diff options
Diffstat (limited to 'drivers/media')
370 files changed, 14510 insertions, 4927 deletions
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index 49cd30870e0d..3ef0f90b128f 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig | |||
@@ -87,13 +87,21 @@ config MEDIA_RC_SUPPORT | |||
87 | 87 | ||
88 | config MEDIA_CONTROLLER | 88 | config MEDIA_CONTROLLER |
89 | bool "Media Controller API" | 89 | bool "Media Controller API" |
90 | depends on MEDIA_CAMERA_SUPPORT | 90 | depends on MEDIA_CAMERA_SUPPORT || MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT |
91 | ---help--- | 91 | ---help--- |
92 | Enable the media controller API used to query media devices internal | 92 | Enable the media controller API used to query media devices internal |
93 | topology and configure it dynamically. | 93 | topology and configure it dynamically. |
94 | 94 | ||
95 | This API is mostly used by camera interfaces in embedded platforms. | 95 | This API is mostly used by camera interfaces in embedded platforms. |
96 | 96 | ||
97 | config MEDIA_CONTROLLER_DVB | ||
98 | bool "Enable Media controller for DVB" | ||
99 | depends on MEDIA_CONTROLLER | ||
100 | ---help--- | ||
101 | Enable the media controller API support for DVB. | ||
102 | |||
103 | This is currently experimental. | ||
104 | |||
97 | # | 105 | # |
98 | # Video4Linux support | 106 | # Video4Linux support |
99 | # Only enables if one of the V4L2 types (ATV, webcam, radio) is selected | 107 | # Only enables if one of the V4L2 types (ATV, webcam, radio) is selected |
diff --git a/drivers/media/common/saa7146/saa7146_fops.c b/drivers/media/common/saa7146/saa7146_fops.c index b7d63933dae6..df1e8c975cd8 100644 --- a/drivers/media/common/saa7146/saa7146_fops.c +++ b/drivers/media/common/saa7146/saa7146_fops.c | |||
@@ -587,26 +587,20 @@ int saa7146_vv_release(struct saa7146_dev* dev) | |||
587 | } | 587 | } |
588 | EXPORT_SYMBOL_GPL(saa7146_vv_release); | 588 | EXPORT_SYMBOL_GPL(saa7146_vv_release); |
589 | 589 | ||
590 | int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev, | 590 | int saa7146_register_device(struct video_device *vfd, struct saa7146_dev *dev, |
591 | char *name, int type) | 591 | char *name, int type) |
592 | { | 592 | { |
593 | struct video_device *vfd; | ||
594 | int err; | 593 | int err; |
595 | int i; | 594 | int i; |
596 | 595 | ||
597 | DEB_EE("dev:%p, name:'%s', type:%d\n", dev, name, type); | 596 | DEB_EE("dev:%p, name:'%s', type:%d\n", dev, name, type); |
598 | 597 | ||
599 | // released by vfd->release | ||
600 | vfd = video_device_alloc(); | ||
601 | if (vfd == NULL) | ||
602 | return -ENOMEM; | ||
603 | |||
604 | vfd->fops = &video_fops; | 598 | vfd->fops = &video_fops; |
605 | if (type == VFL_TYPE_GRABBER) | 599 | if (type == VFL_TYPE_GRABBER) |
606 | vfd->ioctl_ops = &dev->ext_vv_data->vid_ops; | 600 | vfd->ioctl_ops = &dev->ext_vv_data->vid_ops; |
607 | else | 601 | else |
608 | vfd->ioctl_ops = &dev->ext_vv_data->vbi_ops; | 602 | vfd->ioctl_ops = &dev->ext_vv_data->vbi_ops; |
609 | vfd->release = video_device_release; | 603 | vfd->release = video_device_release_empty; |
610 | vfd->lock = &dev->v4l2_lock; | 604 | vfd->lock = &dev->v4l2_lock; |
611 | vfd->v4l2_dev = &dev->v4l2_dev; | 605 | vfd->v4l2_dev = &dev->v4l2_dev; |
612 | vfd->tvnorms = 0; | 606 | vfd->tvnorms = 0; |
@@ -618,25 +612,20 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev, | |||
618 | err = video_register_device(vfd, type, -1); | 612 | err = video_register_device(vfd, type, -1); |
619 | if (err < 0) { | 613 | if (err < 0) { |
620 | ERR("cannot register v4l2 device. skipping.\n"); | 614 | ERR("cannot register v4l2 device. skipping.\n"); |
621 | video_device_release(vfd); | ||
622 | return err; | 615 | return err; |
623 | } | 616 | } |
624 | 617 | ||
625 | pr_info("%s: registered device %s [v4l2]\n", | 618 | pr_info("%s: registered device %s [v4l2]\n", |
626 | dev->name, video_device_node_name(vfd)); | 619 | dev->name, video_device_node_name(vfd)); |
627 | |||
628 | *vid = vfd; | ||
629 | return 0; | 620 | return 0; |
630 | } | 621 | } |
631 | EXPORT_SYMBOL_GPL(saa7146_register_device); | 622 | EXPORT_SYMBOL_GPL(saa7146_register_device); |
632 | 623 | ||
633 | int saa7146_unregister_device(struct video_device **vid, struct saa7146_dev* dev) | 624 | int saa7146_unregister_device(struct video_device *vfd, struct saa7146_dev *dev) |
634 | { | 625 | { |
635 | DEB_EE("dev:%p\n", dev); | 626 | DEB_EE("dev:%p\n", dev); |
636 | 627 | ||
637 | video_unregister_device(*vid); | 628 | video_unregister_device(vfd); |
638 | *vid = NULL; | ||
639 | |||
640 | return 0; | 629 | return 0; |
641 | } | 630 | } |
642 | EXPORT_SYMBOL_GPL(saa7146_unregister_device); | 631 | EXPORT_SYMBOL_GPL(saa7146_unregister_device); |
diff --git a/drivers/media/common/saa7146/saa7146_vbi.c b/drivers/media/common/saa7146/saa7146_vbi.c index 1e71e374bbfe..2da995758778 100644 --- a/drivers/media/common/saa7146/saa7146_vbi.c +++ b/drivers/media/common/saa7146/saa7146_vbi.c | |||
@@ -95,7 +95,7 @@ static int vbi_workaround(struct saa7146_dev *dev) | |||
95 | 95 | ||
96 | /* prepare to wait to be woken up by the irq-handler */ | 96 | /* prepare to wait to be woken up by the irq-handler */ |
97 | add_wait_queue(&vv->vbi_wq, &wait); | 97 | add_wait_queue(&vv->vbi_wq, &wait); |
98 | current->state = TASK_INTERRUPTIBLE; | 98 | set_current_state(TASK_INTERRUPTIBLE); |
99 | 99 | ||
100 | /* start rps1 to enable workaround */ | 100 | /* start rps1 to enable workaround */ |
101 | saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle); | 101 | saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle); |
@@ -106,7 +106,7 @@ static int vbi_workaround(struct saa7146_dev *dev) | |||
106 | DEB_VBI("brs bug workaround %d/1\n", i); | 106 | DEB_VBI("brs bug workaround %d/1\n", i); |
107 | 107 | ||
108 | remove_wait_queue(&vv->vbi_wq, &wait); | 108 | remove_wait_queue(&vv->vbi_wq, &wait); |
109 | current->state = TASK_RUNNING; | 109 | __set_current_state(TASK_RUNNING); |
110 | 110 | ||
111 | /* disable rps1 irqs */ | 111 | /* disable rps1 irqs */ |
112 | SAA7146_IER_DISABLE(dev,MASK_28); | 112 | SAA7146_IER_DISABLE(dev,MASK_28); |
diff --git a/drivers/media/common/siano/sms-cards.c b/drivers/media/common/siano/sms-cards.c index 82c7a1289f05..ca2f80c7740c 100644 --- a/drivers/media/common/siano/sms-cards.c +++ b/drivers/media/common/siano/sms-cards.c | |||
@@ -21,10 +21,6 @@ | |||
21 | #include "smsir.h" | 21 | #include "smsir.h" |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | 23 | ||
24 | static int sms_dbg; | ||
25 | module_param_named(cards_dbg, sms_dbg, int, 0644); | ||
26 | MODULE_PARM_DESC(cards_dbg, "set debug level (info=1, adv=2 (or-able))"); | ||
27 | |||
28 | static struct sms_board sms_boards[] = { | 24 | static struct sms_board sms_boards[] = { |
29 | [SMS_BOARD_UNKNOWN] = { | 25 | [SMS_BOARD_UNKNOWN] = { |
30 | .name = "Unknown board", | 26 | .name = "Unknown board", |
@@ -232,7 +228,7 @@ int sms_board_event(struct smscore_device_t *coredev, | |||
232 | break; /* BOARD_EVENT_MULTIPLEX_ERRORS */ | 228 | break; /* BOARD_EVENT_MULTIPLEX_ERRORS */ |
233 | 229 | ||
234 | default: | 230 | default: |
235 | sms_err("Unknown SMS board event"); | 231 | pr_err("Unknown SMS board event\n"); |
236 | break; | 232 | break; |
237 | } | 233 | } |
238 | return 0; | 234 | return 0; |
@@ -342,7 +338,7 @@ int sms_board_lna_control(struct smscore_device_t *coredev, int onoff) | |||
342 | int board_id = smscore_get_board_id(coredev); | 338 | int board_id = smscore_get_board_id(coredev); |
343 | struct sms_board *board = sms_get_board(board_id); | 339 | struct sms_board *board = sms_get_board(board_id); |
344 | 340 | ||
345 | sms_debug("%s: LNA %s", __func__, onoff ? "enabled" : "disabled"); | 341 | pr_debug("%s: LNA %s\n", __func__, onoff ? "enabled" : "disabled"); |
346 | 342 | ||
347 | switch (board_id) { | 343 | switch (board_id) { |
348 | case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2: | 344 | case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2: |
diff --git a/drivers/media/common/siano/sms-cards.h b/drivers/media/common/siano/sms-cards.h index 4c4caddf9869..bb3d733f092b 100644 --- a/drivers/media/common/siano/sms-cards.h +++ b/drivers/media/common/siano/sms-cards.h | |||
@@ -20,8 +20,9 @@ | |||
20 | #ifndef __SMS_CARDS_H__ | 20 | #ifndef __SMS_CARDS_H__ |
21 | #define __SMS_CARDS_H__ | 21 | #define __SMS_CARDS_H__ |
22 | 22 | ||
23 | #include <linux/usb.h> | ||
24 | #include "smscoreapi.h" | 23 | #include "smscoreapi.h" |
24 | |||
25 | #include <linux/usb.h> | ||
25 | #include "smsir.h" | 26 | #include "smsir.h" |
26 | 27 | ||
27 | #define SMS_BOARD_UNKNOWN 0 | 28 | #define SMS_BOARD_UNKNOWN 0 |
diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c index a3677438205e..2a8d9a36d6f0 100644 --- a/drivers/media/common/siano/smscoreapi.c +++ b/drivers/media/common/siano/smscoreapi.c | |||
@@ -21,6 +21,8 @@ | |||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include "smscoreapi.h" | ||
25 | |||
24 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
25 | #include <linux/init.h> | 27 | #include <linux/init.h> |
26 | #include <linux/module.h> | 28 | #include <linux/module.h> |
@@ -34,14 +36,9 @@ | |||
34 | #include <linux/wait.h> | 36 | #include <linux/wait.h> |
35 | #include <asm/byteorder.h> | 37 | #include <asm/byteorder.h> |
36 | 38 | ||
37 | #include "smscoreapi.h" | ||
38 | #include "sms-cards.h" | 39 | #include "sms-cards.h" |
39 | #include "smsir.h" | 40 | #include "smsir.h" |
40 | 41 | ||
41 | static int sms_dbg; | ||
42 | module_param_named(debug, sms_dbg, int, 0644); | ||
43 | MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); | ||
44 | |||
45 | struct smscore_device_notifyee_t { | 42 | struct smscore_device_notifyee_t { |
46 | struct list_head entry; | 43 | struct list_head entry; |
47 | hotplug_t hotplug; | 44 | hotplug_t hotplug; |
@@ -460,7 +457,7 @@ static struct smscore_registry_entry_t *smscore_find_registry(char *devpath) | |||
460 | strcpy(entry->devpath, devpath); | 457 | strcpy(entry->devpath, devpath); |
461 | list_add(&entry->entry, &g_smscore_registry); | 458 | list_add(&entry->entry, &g_smscore_registry); |
462 | } else | 459 | } else |
463 | sms_err("failed to create smscore_registry."); | 460 | pr_err("failed to create smscore_registry.\n"); |
464 | kmutex_unlock(&g_smscore_registrylock); | 461 | kmutex_unlock(&g_smscore_registrylock); |
465 | return entry; | 462 | return entry; |
466 | } | 463 | } |
@@ -473,7 +470,7 @@ int smscore_registry_getmode(char *devpath) | |||
473 | if (entry) | 470 | if (entry) |
474 | return entry->mode; | 471 | return entry->mode; |
475 | else | 472 | else |
476 | sms_err("No registry found."); | 473 | pr_err("No registry found.\n"); |
477 | 474 | ||
478 | return default_mode; | 475 | return default_mode; |
479 | } | 476 | } |
@@ -487,7 +484,7 @@ static enum sms_device_type_st smscore_registry_gettype(char *devpath) | |||
487 | if (entry) | 484 | if (entry) |
488 | return entry->type; | 485 | return entry->type; |
489 | else | 486 | else |
490 | sms_err("No registry found."); | 487 | pr_err("No registry found.\n"); |
491 | 488 | ||
492 | return -EINVAL; | 489 | return -EINVAL; |
493 | } | 490 | } |
@@ -500,7 +497,7 @@ static void smscore_registry_setmode(char *devpath, int mode) | |||
500 | if (entry) | 497 | if (entry) |
501 | entry->mode = mode; | 498 | entry->mode = mode; |
502 | else | 499 | else |
503 | sms_err("No registry found."); | 500 | pr_err("No registry found.\n"); |
504 | } | 501 | } |
505 | 502 | ||
506 | static void smscore_registry_settype(char *devpath, | 503 | static void smscore_registry_settype(char *devpath, |
@@ -512,7 +509,7 @@ static void smscore_registry_settype(char *devpath, | |||
512 | if (entry) | 509 | if (entry) |
513 | entry->type = type; | 510 | entry->type = type; |
514 | else | 511 | else |
515 | sms_err("No registry found."); | 512 | pr_err("No registry found.\n"); |
516 | } | 513 | } |
517 | 514 | ||
518 | 515 | ||
@@ -635,10 +632,8 @@ smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer, | |||
635 | struct smscore_buffer_t *cb; | 632 | struct smscore_buffer_t *cb; |
636 | 633 | ||
637 | cb = kzalloc(sizeof(struct smscore_buffer_t), GFP_KERNEL); | 634 | cb = kzalloc(sizeof(struct smscore_buffer_t), GFP_KERNEL); |
638 | if (!cb) { | 635 | if (!cb) |
639 | sms_info("kzalloc(...) failed"); | ||
640 | return NULL; | 636 | return NULL; |
641 | } | ||
642 | 637 | ||
643 | cb->p = buffer; | 638 | cb->p = buffer; |
644 | cb->offset_in_common = buffer - (u8 *) common_buffer; | 639 | cb->offset_in_common = buffer - (u8 *) common_buffer; |
@@ -658,16 +653,19 @@ smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer, | |||
658 | * @return 0 on success, <0 on error. | 653 | * @return 0 on success, <0 on error. |
659 | */ | 654 | */ |
660 | int smscore_register_device(struct smsdevice_params_t *params, | 655 | int smscore_register_device(struct smsdevice_params_t *params, |
661 | struct smscore_device_t **coredev) | 656 | struct smscore_device_t **coredev, |
657 | void *mdev) | ||
662 | { | 658 | { |
663 | struct smscore_device_t *dev; | 659 | struct smscore_device_t *dev; |
664 | u8 *buffer; | 660 | u8 *buffer; |
665 | 661 | ||
666 | dev = kzalloc(sizeof(struct smscore_device_t), GFP_KERNEL); | 662 | dev = kzalloc(sizeof(struct smscore_device_t), GFP_KERNEL); |
667 | if (!dev) { | 663 | if (!dev) |
668 | sms_info("kzalloc(...) failed"); | ||
669 | return -ENOMEM; | 664 | return -ENOMEM; |
670 | } | 665 | |
666 | #ifdef CONFIG_MEDIA_CONTROLLER_DVB | ||
667 | dev->media_dev = mdev; | ||
668 | #endif | ||
671 | 669 | ||
672 | /* init list entry so it could be safe in smscore_unregister_device */ | 670 | /* init list entry so it could be safe in smscore_unregister_device */ |
673 | INIT_LIST_HEAD(&dev->entry); | 671 | INIT_LIST_HEAD(&dev->entry); |
@@ -722,7 +720,7 @@ int smscore_register_device(struct smsdevice_params_t *params, | |||
722 | smscore_putbuffer(dev, cb); | 720 | smscore_putbuffer(dev, cb); |
723 | } | 721 | } |
724 | 722 | ||
725 | sms_info("allocated %d buffers", dev->num_buffers); | 723 | pr_debug("allocated %d buffers\n", dev->num_buffers); |
726 | 724 | ||
727 | dev->mode = DEVICE_MODE_NONE; | 725 | dev->mode = DEVICE_MODE_NONE; |
728 | dev->board_id = SMS_BOARD_UNKNOWN; | 726 | dev->board_id = SMS_BOARD_UNKNOWN; |
@@ -746,7 +744,7 @@ int smscore_register_device(struct smsdevice_params_t *params, | |||
746 | 744 | ||
747 | *coredev = dev; | 745 | *coredev = dev; |
748 | 746 | ||
749 | sms_info("device %p created", dev); | 747 | pr_debug("device %p created\n", dev); |
750 | 748 | ||
751 | return 0; | 749 | return 0; |
752 | } | 750 | } |
@@ -763,7 +761,7 @@ static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev, | |||
763 | 761 | ||
764 | rc = coredev->sendrequest_handler(coredev->context, buffer, size); | 762 | rc = coredev->sendrequest_handler(coredev->context, buffer, size); |
765 | if (rc < 0) { | 763 | if (rc < 0) { |
766 | sms_info("sendrequest returned error %d", rc); | 764 | pr_info("sendrequest returned error %d\n", rc); |
767 | return rc; | 765 | return rc; |
768 | } | 766 | } |
769 | 767 | ||
@@ -786,11 +784,11 @@ static int smscore_init_ir(struct smscore_device_t *coredev) | |||
786 | coredev->ir.dev = NULL; | 784 | coredev->ir.dev = NULL; |
787 | ir_io = sms_get_board(smscore_get_board_id(coredev))->board_cfg.ir; | 785 | ir_io = sms_get_board(smscore_get_board_id(coredev))->board_cfg.ir; |
788 | if (ir_io) {/* only if IR port exist we use IR sub-module */ | 786 | if (ir_io) {/* only if IR port exist we use IR sub-module */ |
789 | sms_info("IR loading"); | 787 | pr_debug("IR loading\n"); |
790 | rc = sms_ir_init(coredev); | 788 | rc = sms_ir_init(coredev); |
791 | 789 | ||
792 | if (rc != 0) | 790 | if (rc != 0) |
793 | sms_err("Error initialization DTV IR sub-module"); | 791 | pr_err("Error initialization DTV IR sub-module\n"); |
794 | else { | 792 | else { |
795 | buffer = kmalloc(sizeof(struct sms_msg_data2) + | 793 | buffer = kmalloc(sizeof(struct sms_msg_data2) + |
796 | SMS_DMA_ALIGNMENT, | 794 | SMS_DMA_ALIGNMENT, |
@@ -812,11 +810,10 @@ static int smscore_init_ir(struct smscore_device_t *coredev) | |||
812 | 810 | ||
813 | kfree(buffer); | 811 | kfree(buffer); |
814 | } else | 812 | } else |
815 | sms_err | 813 | pr_err("Sending IR initialization message failed\n"); |
816 | ("Sending IR initialization message failed"); | ||
817 | } | 814 | } |
818 | } else | 815 | } else |
819 | sms_info("IR port has not been detected"); | 816 | pr_info("IR port has not been detected\n"); |
820 | 817 | ||
821 | return 0; | 818 | return 0; |
822 | } | 819 | } |
@@ -835,13 +832,13 @@ static int smscore_configure_board(struct smscore_device_t *coredev) | |||
835 | 832 | ||
836 | board = sms_get_board(coredev->board_id); | 833 | board = sms_get_board(coredev->board_id); |
837 | if (!board) { | 834 | if (!board) { |
838 | sms_err("no board configuration exist."); | 835 | pr_err("no board configuration exist.\n"); |
839 | return -EINVAL; | 836 | return -EINVAL; |
840 | } | 837 | } |
841 | 838 | ||
842 | if (board->mtu) { | 839 | if (board->mtu) { |
843 | struct sms_msg_data mtu_msg; | 840 | struct sms_msg_data mtu_msg; |
844 | sms_debug("set max transmit unit %d", board->mtu); | 841 | pr_debug("set max transmit unit %d\n", board->mtu); |
845 | 842 | ||
846 | mtu_msg.x_msg_header.msg_src_id = 0; | 843 | mtu_msg.x_msg_header.msg_src_id = 0; |
847 | mtu_msg.x_msg_header.msg_dst_id = HIF_TASK; | 844 | mtu_msg.x_msg_header.msg_dst_id = HIF_TASK; |
@@ -856,7 +853,7 @@ static int smscore_configure_board(struct smscore_device_t *coredev) | |||
856 | 853 | ||
857 | if (board->crystal) { | 854 | if (board->crystal) { |
858 | struct sms_msg_data crys_msg; | 855 | struct sms_msg_data crys_msg; |
859 | sms_debug("set crystal value %d", board->crystal); | 856 | pr_debug("set crystal value %d\n", board->crystal); |
860 | 857 | ||
861 | SMS_INIT_MSG(&crys_msg.x_msg_header, | 858 | SMS_INIT_MSG(&crys_msg.x_msg_header, |
862 | MSG_SMS_NEW_CRYSTAL_REQ, | 859 | MSG_SMS_NEW_CRYSTAL_REQ, |
@@ -890,12 +887,12 @@ int smscore_start_device(struct smscore_device_t *coredev) | |||
890 | 887 | ||
891 | rc = smscore_set_device_mode(coredev, mode); | 888 | rc = smscore_set_device_mode(coredev, mode); |
892 | if (rc < 0) { | 889 | if (rc < 0) { |
893 | sms_info("set device mode faile , rc %d", rc); | 890 | pr_info("set device mode failed , rc %d\n", rc); |
894 | return rc; | 891 | return rc; |
895 | } | 892 | } |
896 | rc = smscore_configure_board(coredev); | 893 | rc = smscore_configure_board(coredev); |
897 | if (rc < 0) { | 894 | if (rc < 0) { |
898 | sms_info("configure board failed , rc %d", rc); | 895 | pr_info("configure board failed , rc %d\n", rc); |
899 | return rc; | 896 | return rc; |
900 | } | 897 | } |
901 | 898 | ||
@@ -904,7 +901,7 @@ int smscore_start_device(struct smscore_device_t *coredev) | |||
904 | rc = smscore_notify_callbacks(coredev, coredev->device, 1); | 901 | rc = smscore_notify_callbacks(coredev, coredev->device, 1); |
905 | smscore_init_ir(coredev); | 902 | smscore_init_ir(coredev); |
906 | 903 | ||
907 | sms_info("device %p started, rc %d", coredev, rc); | 904 | pr_debug("device %p started, rc %d\n", coredev, rc); |
908 | 905 | ||
909 | kmutex_unlock(&g_smscore_deviceslock); | 906 | kmutex_unlock(&g_smscore_deviceslock); |
910 | 907 | ||
@@ -927,7 +924,7 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev, | |||
927 | 924 | ||
928 | mem_address = firmware->start_address; | 925 | mem_address = firmware->start_address; |
929 | 926 | ||
930 | sms_info("loading FW to addr 0x%x size %d", | 927 | pr_debug("loading FW to addr 0x%x size %d\n", |
931 | mem_address, firmware->length); | 928 | mem_address, firmware->length); |
932 | if (coredev->preload_handler) { | 929 | if (coredev->preload_handler) { |
933 | rc = coredev->preload_handler(coredev->context); | 930 | rc = coredev->preload_handler(coredev->context); |
@@ -941,14 +938,14 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev, | |||
941 | return -ENOMEM; | 938 | return -ENOMEM; |
942 | 939 | ||
943 | if (coredev->mode != DEVICE_MODE_NONE) { | 940 | if (coredev->mode != DEVICE_MODE_NONE) { |
944 | sms_debug("sending reload command."); | 941 | pr_debug("sending reload command.\n"); |
945 | SMS_INIT_MSG(&msg->x_msg_header, MSG_SW_RELOAD_START_REQ, | 942 | SMS_INIT_MSG(&msg->x_msg_header, MSG_SW_RELOAD_START_REQ, |
946 | sizeof(struct sms_msg_hdr)); | 943 | sizeof(struct sms_msg_hdr)); |
947 | rc = smscore_sendrequest_and_wait(coredev, msg, | 944 | rc = smscore_sendrequest_and_wait(coredev, msg, |
948 | msg->x_msg_header.msg_length, | 945 | msg->x_msg_header.msg_length, |
949 | &coredev->reload_start_done); | 946 | &coredev->reload_start_done); |
950 | if (rc < 0) { | 947 | if (rc < 0) { |
951 | sms_err("device reload failed, rc %d", rc); | 948 | pr_err("device reload failed, rc %d\n", rc); |
952 | goto exit_fw_download; | 949 | goto exit_fw_download; |
953 | } | 950 | } |
954 | mem_address = *(u32 *) &payload[20]; | 951 | mem_address = *(u32 *) &payload[20]; |
@@ -982,7 +979,7 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev, | |||
982 | if (rc < 0) | 979 | if (rc < 0) |
983 | goto exit_fw_download; | 980 | goto exit_fw_download; |
984 | 981 | ||
985 | sms_debug("sending MSG_SMS_DATA_VALIDITY_REQ expecting 0x%x", | 982 | pr_debug("sending MSG_SMS_DATA_VALIDITY_REQ expecting 0x%x\n", |
986 | calc_checksum); | 983 | calc_checksum); |
987 | SMS_INIT_MSG(&msg->x_msg_header, MSG_SMS_DATA_VALIDITY_REQ, | 984 | SMS_INIT_MSG(&msg->x_msg_header, MSG_SMS_DATA_VALIDITY_REQ, |
988 | sizeof(msg->x_msg_header) + | 985 | sizeof(msg->x_msg_header) + |
@@ -1001,7 +998,7 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev, | |||
1001 | struct sms_msg_data *trigger_msg = | 998 | struct sms_msg_data *trigger_msg = |
1002 | (struct sms_msg_data *) msg; | 999 | (struct sms_msg_data *) msg; |
1003 | 1000 | ||
1004 | sms_debug("sending MSG_SMS_SWDOWNLOAD_TRIGGER_REQ"); | 1001 | pr_debug("sending MSG_SMS_SWDOWNLOAD_TRIGGER_REQ\n"); |
1005 | SMS_INIT_MSG(&msg->x_msg_header, | 1002 | SMS_INIT_MSG(&msg->x_msg_header, |
1006 | MSG_SMS_SWDOWNLOAD_TRIGGER_REQ, | 1003 | MSG_SMS_SWDOWNLOAD_TRIGGER_REQ, |
1007 | sizeof(struct sms_msg_hdr) + | 1004 | sizeof(struct sms_msg_hdr) + |
@@ -1037,12 +1034,13 @@ exit_fw_download: | |||
1037 | kfree(msg); | 1034 | kfree(msg); |
1038 | 1035 | ||
1039 | if (coredev->postload_handler) { | 1036 | if (coredev->postload_handler) { |
1040 | sms_debug("rc=%d, postload=0x%p", rc, coredev->postload_handler); | 1037 | pr_debug("rc=%d, postload=0x%p\n", |
1038 | rc, coredev->postload_handler); | ||
1041 | if (rc >= 0) | 1039 | if (rc >= 0) |
1042 | return coredev->postload_handler(coredev->context); | 1040 | return coredev->postload_handler(coredev->context); |
1043 | } | 1041 | } |
1044 | 1042 | ||
1045 | sms_debug("rc=%d", rc); | 1043 | pr_debug("rc=%d\n", rc); |
1046 | return rc; | 1044 | return rc; |
1047 | } | 1045 | } |
1048 | 1046 | ||
@@ -1121,11 +1119,11 @@ static char *smscore_get_fw_filename(struct smscore_device_t *coredev, | |||
1121 | if (mode <= DEVICE_MODE_NONE || mode >= DEVICE_MODE_MAX) | 1119 | if (mode <= DEVICE_MODE_NONE || mode >= DEVICE_MODE_MAX) |
1122 | return NULL; | 1120 | return NULL; |
1123 | 1121 | ||
1124 | sms_debug("trying to get fw name from sms_boards board_id %d mode %d", | 1122 | pr_debug("trying to get fw name from sms_boards board_id %d mode %d\n", |
1125 | board_id, mode); | 1123 | board_id, mode); |
1126 | fw = sms_get_board(board_id)->fw; | 1124 | fw = sms_get_board(board_id)->fw; |
1127 | if (!fw || !fw[mode]) { | 1125 | if (!fw || !fw[mode]) { |
1128 | sms_debug("cannot find fw name in sms_boards, getting from lookup table mode %d type %d", | 1126 | pr_debug("cannot find fw name in sms_boards, getting from lookup table mode %d type %d\n", |
1129 | mode, type); | 1127 | mode, type); |
1130 | return smscore_fw_lkup[type][mode]; | 1128 | return smscore_fw_lkup[type][mode]; |
1131 | } | 1129 | } |
@@ -1154,10 +1152,10 @@ static int smscore_load_firmware_from_file(struct smscore_device_t *coredev, | |||
1154 | 1152 | ||
1155 | char *fw_filename = smscore_get_fw_filename(coredev, mode); | 1153 | char *fw_filename = smscore_get_fw_filename(coredev, mode); |
1156 | if (!fw_filename) { | 1154 | if (!fw_filename) { |
1157 | sms_err("mode %d not supported on this device", mode); | 1155 | pr_err("mode %d not supported on this device\n", mode); |
1158 | return -ENOENT; | 1156 | return -ENOENT; |
1159 | } | 1157 | } |
1160 | sms_debug("Firmware name: %s", fw_filename); | 1158 | pr_debug("Firmware name: %s\n", fw_filename); |
1161 | 1159 | ||
1162 | if (loadfirmware_handler == NULL && !(coredev->device_flags | 1160 | if (loadfirmware_handler == NULL && !(coredev->device_flags |
1163 | & SMS_DEVICE_FAMILY2)) | 1161 | & SMS_DEVICE_FAMILY2)) |
@@ -1165,14 +1163,14 @@ static int smscore_load_firmware_from_file(struct smscore_device_t *coredev, | |||
1165 | 1163 | ||
1166 | rc = request_firmware(&fw, fw_filename, coredev->device); | 1164 | rc = request_firmware(&fw, fw_filename, coredev->device); |
1167 | if (rc < 0) { | 1165 | if (rc < 0) { |
1168 | sms_err("failed to open firmware file \"%s\"", fw_filename); | 1166 | pr_err("failed to open firmware file '%s'\n", fw_filename); |
1169 | return rc; | 1167 | return rc; |
1170 | } | 1168 | } |
1171 | sms_info("read fw %s, buffer size=0x%zx", fw_filename, fw->size); | 1169 | pr_debug("read fw %s, buffer size=0x%zx\n", fw_filename, fw->size); |
1172 | fw_buf = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT), | 1170 | fw_buf = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT), |
1173 | GFP_KERNEL | GFP_DMA); | 1171 | GFP_KERNEL | GFP_DMA); |
1174 | if (!fw_buf) { | 1172 | if (!fw_buf) { |
1175 | sms_err("failed to allocate firmware buffer"); | 1173 | pr_err("failed to allocate firmware buffer\n"); |
1176 | rc = -ENOMEM; | 1174 | rc = -ENOMEM; |
1177 | } else { | 1175 | } else { |
1178 | memcpy(fw_buf, fw->data, fw->size); | 1176 | memcpy(fw_buf, fw->data, fw->size); |
@@ -1226,18 +1224,18 @@ void smscore_unregister_device(struct smscore_device_t *coredev) | |||
1226 | if (num_buffers == coredev->num_buffers) | 1224 | if (num_buffers == coredev->num_buffers) |
1227 | break; | 1225 | break; |
1228 | if (++retry > 10) { | 1226 | if (++retry > 10) { |
1229 | sms_info("exiting although not all buffers released."); | 1227 | pr_info("exiting although not all buffers released.\n"); |
1230 | break; | 1228 | break; |
1231 | } | 1229 | } |
1232 | 1230 | ||
1233 | sms_info("waiting for %d buffer(s)", | 1231 | pr_debug("waiting for %d buffer(s)\n", |
1234 | coredev->num_buffers - num_buffers); | 1232 | coredev->num_buffers - num_buffers); |
1235 | kmutex_unlock(&g_smscore_deviceslock); | 1233 | kmutex_unlock(&g_smscore_deviceslock); |
1236 | msleep(100); | 1234 | msleep(100); |
1237 | kmutex_lock(&g_smscore_deviceslock); | 1235 | kmutex_lock(&g_smscore_deviceslock); |
1238 | } | 1236 | } |
1239 | 1237 | ||
1240 | sms_info("freed %d buffers", num_buffers); | 1238 | pr_debug("freed %d buffers\n", num_buffers); |
1241 | 1239 | ||
1242 | if (coredev->common_buffer) | 1240 | if (coredev->common_buffer) |
1243 | dma_free_coherent(NULL, coredev->common_buffer_size, | 1241 | dma_free_coherent(NULL, coredev->common_buffer_size, |
@@ -1250,7 +1248,7 @@ void smscore_unregister_device(struct smscore_device_t *coredev) | |||
1250 | 1248 | ||
1251 | kmutex_unlock(&g_smscore_deviceslock); | 1249 | kmutex_unlock(&g_smscore_deviceslock); |
1252 | 1250 | ||
1253 | sms_info("device %p destroyed", coredev); | 1251 | pr_debug("device %p destroyed\n", coredev); |
1254 | } | 1252 | } |
1255 | EXPORT_SYMBOL_GPL(smscore_unregister_device); | 1253 | EXPORT_SYMBOL_GPL(smscore_unregister_device); |
1256 | 1254 | ||
@@ -1271,7 +1269,7 @@ static int smscore_detect_mode(struct smscore_device_t *coredev) | |||
1271 | rc = smscore_sendrequest_and_wait(coredev, msg, msg->msg_length, | 1269 | rc = smscore_sendrequest_and_wait(coredev, msg, msg->msg_length, |
1272 | &coredev->version_ex_done); | 1270 | &coredev->version_ex_done); |
1273 | if (rc == -ETIME) { | 1271 | if (rc == -ETIME) { |
1274 | sms_err("MSG_SMS_GET_VERSION_EX_REQ failed first try"); | 1272 | pr_err("MSG_SMS_GET_VERSION_EX_REQ failed first try\n"); |
1275 | 1273 | ||
1276 | if (wait_for_completion_timeout(&coredev->resume_done, | 1274 | if (wait_for_completion_timeout(&coredev->resume_done, |
1277 | msecs_to_jiffies(5000))) { | 1275 | msecs_to_jiffies(5000))) { |
@@ -1279,7 +1277,7 @@ static int smscore_detect_mode(struct smscore_device_t *coredev) | |||
1279 | coredev, msg, msg->msg_length, | 1277 | coredev, msg, msg->msg_length, |
1280 | &coredev->version_ex_done); | 1278 | &coredev->version_ex_done); |
1281 | if (rc < 0) | 1279 | if (rc < 0) |
1282 | sms_err("MSG_SMS_GET_VERSION_EX_REQ failed second try, rc %d", | 1280 | pr_err("MSG_SMS_GET_VERSION_EX_REQ failed second try, rc %d\n", |
1283 | rc); | 1281 | rc); |
1284 | } else | 1282 | } else |
1285 | rc = -ETIME; | 1283 | rc = -ETIME; |
@@ -1308,7 +1306,7 @@ static int smscore_init_device(struct smscore_device_t *coredev, int mode) | |||
1308 | buffer = kmalloc(sizeof(struct sms_msg_data) + | 1306 | buffer = kmalloc(sizeof(struct sms_msg_data) + |
1309 | SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA); | 1307 | SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA); |
1310 | if (!buffer) { | 1308 | if (!buffer) { |
1311 | sms_err("Could not allocate buffer for init device message."); | 1309 | pr_err("Could not allocate buffer for init device message.\n"); |
1312 | return -ENOMEM; | 1310 | return -ENOMEM; |
1313 | } | 1311 | } |
1314 | 1312 | ||
@@ -1339,10 +1337,10 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) | |||
1339 | { | 1337 | { |
1340 | int rc = 0; | 1338 | int rc = 0; |
1341 | 1339 | ||
1342 | sms_debug("set device mode to %d", mode); | 1340 | pr_debug("set device mode to %d\n", mode); |
1343 | if (coredev->device_flags & SMS_DEVICE_FAMILY2) { | 1341 | if (coredev->device_flags & SMS_DEVICE_FAMILY2) { |
1344 | if (mode <= DEVICE_MODE_NONE || mode >= DEVICE_MODE_MAX) { | 1342 | if (mode <= DEVICE_MODE_NONE || mode >= DEVICE_MODE_MAX) { |
1345 | sms_err("invalid mode specified %d", mode); | 1343 | pr_err("invalid mode specified %d\n", mode); |
1346 | return -EINVAL; | 1344 | return -EINVAL; |
1347 | } | 1345 | } |
1348 | 1346 | ||
@@ -1351,13 +1349,13 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) | |||
1351 | if (!(coredev->device_flags & SMS_DEVICE_NOT_READY)) { | 1349 | if (!(coredev->device_flags & SMS_DEVICE_NOT_READY)) { |
1352 | rc = smscore_detect_mode(coredev); | 1350 | rc = smscore_detect_mode(coredev); |
1353 | if (rc < 0) { | 1351 | if (rc < 0) { |
1354 | sms_err("mode detect failed %d", rc); | 1352 | pr_err("mode detect failed %d\n", rc); |
1355 | return rc; | 1353 | return rc; |
1356 | } | 1354 | } |
1357 | } | 1355 | } |
1358 | 1356 | ||
1359 | if (coredev->mode == mode) { | 1357 | if (coredev->mode == mode) { |
1360 | sms_info("device mode %d already set", mode); | 1358 | pr_debug("device mode %d already set\n", mode); |
1361 | return 0; | 1359 | return 0; |
1362 | } | 1360 | } |
1363 | 1361 | ||
@@ -1365,19 +1363,19 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) | |||
1365 | rc = smscore_load_firmware_from_file(coredev, | 1363 | rc = smscore_load_firmware_from_file(coredev, |
1366 | mode, NULL); | 1364 | mode, NULL); |
1367 | if (rc >= 0) | 1365 | if (rc >= 0) |
1368 | sms_info("firmware download success"); | 1366 | pr_debug("firmware download success\n"); |
1369 | } else { | 1367 | } else { |
1370 | sms_info("mode %d is already supported by running firmware", | 1368 | pr_debug("mode %d is already supported by running firmware\n", |
1371 | mode); | 1369 | mode); |
1372 | } | 1370 | } |
1373 | if (coredev->fw_version >= 0x800) { | 1371 | if (coredev->fw_version >= 0x800) { |
1374 | rc = smscore_init_device(coredev, mode); | 1372 | rc = smscore_init_device(coredev, mode); |
1375 | if (rc < 0) | 1373 | if (rc < 0) |
1376 | sms_err("device init failed, rc %d.", rc); | 1374 | pr_err("device init failed, rc %d.\n", rc); |
1377 | } | 1375 | } |
1378 | } else { | 1376 | } else { |
1379 | if (mode <= DEVICE_MODE_NONE || mode >= DEVICE_MODE_MAX) { | 1377 | if (mode <= DEVICE_MODE_NONE || mode >= DEVICE_MODE_MAX) { |
1380 | sms_err("invalid mode specified %d", mode); | 1378 | pr_err("invalid mode specified %d\n", mode); |
1381 | return -EINVAL; | 1379 | return -EINVAL; |
1382 | } | 1380 | } |
1383 | 1381 | ||
@@ -1414,9 +1412,9 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) | |||
1414 | } | 1412 | } |
1415 | 1413 | ||
1416 | if (rc < 0) | 1414 | if (rc < 0) |
1417 | sms_err("return error code %d.", rc); | 1415 | pr_err("return error code %d.\n", rc); |
1418 | else | 1416 | else |
1419 | sms_debug("Success setting device mode."); | 1417 | pr_debug("Success setting device mode.\n"); |
1420 | 1418 | ||
1421 | return rc; | 1419 | return rc; |
1422 | } | 1420 | } |
@@ -1495,7 +1493,7 @@ void smscore_onresponse(struct smscore_device_t *coredev, | |||
1495 | last_sample_time = time_now; | 1493 | last_sample_time = time_now; |
1496 | 1494 | ||
1497 | if (time_now - last_sample_time > 10000) { | 1495 | if (time_now - last_sample_time > 10000) { |
1498 | sms_debug("data rate %d bytes/secs", | 1496 | pr_debug("data rate %d bytes/secs\n", |
1499 | (int)((data_total * 1000) / | 1497 | (int)((data_total * 1000) / |
1500 | (time_now - last_sample_time))); | 1498 | (time_now - last_sample_time))); |
1501 | 1499 | ||
@@ -1539,7 +1537,7 @@ void smscore_onresponse(struct smscore_device_t *coredev, | |||
1539 | { | 1537 | { |
1540 | struct sms_version_res *ver = | 1538 | struct sms_version_res *ver = |
1541 | (struct sms_version_res *) phdr; | 1539 | (struct sms_version_res *) phdr; |
1542 | sms_debug("Firmware id %d prots 0x%x ver %d.%d", | 1540 | pr_debug("Firmware id %d prots 0x%x ver %d.%d\n", |
1543 | ver->firmware_id, ver->supported_protocols, | 1541 | ver->firmware_id, ver->supported_protocols, |
1544 | ver->rom_ver_major, ver->rom_ver_minor); | 1542 | ver->rom_ver_major, ver->rom_ver_minor); |
1545 | 1543 | ||
@@ -1562,7 +1560,7 @@ void smscore_onresponse(struct smscore_device_t *coredev, | |||
1562 | { | 1560 | { |
1563 | struct sms_msg_data *validity = (struct sms_msg_data *) phdr; | 1561 | struct sms_msg_data *validity = (struct sms_msg_data *) phdr; |
1564 | 1562 | ||
1565 | sms_debug("MSG_SMS_DATA_VALIDITY_RES, checksum = 0x%x", | 1563 | pr_debug("MSG_SMS_DATA_VALIDITY_RES, checksum = 0x%x\n", |
1566 | validity->msg_data[0]); | 1564 | validity->msg_data[0]); |
1567 | complete(&coredev->data_validity_done); | 1565 | complete(&coredev->data_validity_done); |
1568 | break; | 1566 | break; |
@@ -1588,7 +1586,7 @@ void smscore_onresponse(struct smscore_device_t *coredev, | |||
1588 | { | 1586 | { |
1589 | u32 *msgdata = (u32 *) phdr; | 1587 | u32 *msgdata = (u32 *) phdr; |
1590 | coredev->gpio_get_res = msgdata[1]; | 1588 | coredev->gpio_get_res = msgdata[1]; |
1591 | sms_debug("gpio level %d", | 1589 | pr_debug("gpio level %d\n", |
1592 | coredev->gpio_get_res); | 1590 | coredev->gpio_get_res); |
1593 | complete(&coredev->gpio_get_level_done); | 1591 | complete(&coredev->gpio_get_level_done); |
1594 | break; | 1592 | break; |
@@ -1615,7 +1613,7 @@ void smscore_onresponse(struct smscore_device_t *coredev, | |||
1615 | break; | 1613 | break; |
1616 | 1614 | ||
1617 | default: | 1615 | default: |
1618 | sms_debug("message %s(%d) not handled.", | 1616 | pr_debug("message %s(%d) not handled.\n", |
1619 | smscore_translate_msg(phdr->msg_type), | 1617 | smscore_translate_msg(phdr->msg_type), |
1620 | phdr->msg_type); | 1618 | phdr->msg_type); |
1621 | break; | 1619 | break; |
@@ -1681,7 +1679,7 @@ static int smscore_validate_client(struct smscore_device_t *coredev, | |||
1681 | struct smscore_client_t *registered_client; | 1679 | struct smscore_client_t *registered_client; |
1682 | 1680 | ||
1683 | if (!client) { | 1681 | if (!client) { |
1684 | sms_err("bad parameter."); | 1682 | pr_err("bad parameter.\n"); |
1685 | return -EINVAL; | 1683 | return -EINVAL; |
1686 | } | 1684 | } |
1687 | registered_client = smscore_find_client(coredev, data_type, id); | 1685 | registered_client = smscore_find_client(coredev, data_type, id); |
@@ -1689,12 +1687,12 @@ static int smscore_validate_client(struct smscore_device_t *coredev, | |||
1689 | return 0; | 1687 | return 0; |
1690 | 1688 | ||
1691 | if (registered_client) { | 1689 | if (registered_client) { |
1692 | sms_err("The msg ID already registered to another client."); | 1690 | pr_err("The msg ID already registered to another client.\n"); |
1693 | return -EEXIST; | 1691 | return -EEXIST; |
1694 | } | 1692 | } |
1695 | listentry = kzalloc(sizeof(struct smscore_idlist_t), GFP_KERNEL); | 1693 | listentry = kzalloc(sizeof(struct smscore_idlist_t), GFP_KERNEL); |
1696 | if (!listentry) { | 1694 | if (!listentry) { |
1697 | sms_err("Can't allocate memory for client id."); | 1695 | pr_err("Can't allocate memory for client id.\n"); |
1698 | return -ENOMEM; | 1696 | return -ENOMEM; |
1699 | } | 1697 | } |
1700 | listentry->id = id; | 1698 | listentry->id = id; |
@@ -1726,13 +1724,13 @@ int smscore_register_client(struct smscore_device_t *coredev, | |||
1726 | /* check that no other channel with same parameters exists */ | 1724 | /* check that no other channel with same parameters exists */ |
1727 | if (smscore_find_client(coredev, params->data_type, | 1725 | if (smscore_find_client(coredev, params->data_type, |
1728 | params->initial_id)) { | 1726 | params->initial_id)) { |
1729 | sms_err("Client already exist."); | 1727 | pr_err("Client already exist.\n"); |
1730 | return -EEXIST; | 1728 | return -EEXIST; |
1731 | } | 1729 | } |
1732 | 1730 | ||
1733 | newclient = kzalloc(sizeof(struct smscore_client_t), GFP_KERNEL); | 1731 | newclient = kzalloc(sizeof(struct smscore_client_t), GFP_KERNEL); |
1734 | if (!newclient) { | 1732 | if (!newclient) { |
1735 | sms_err("Failed to allocate memory for client."); | 1733 | pr_err("Failed to allocate memory for client.\n"); |
1736 | return -ENOMEM; | 1734 | return -ENOMEM; |
1737 | } | 1735 | } |
1738 | 1736 | ||
@@ -1746,7 +1744,7 @@ int smscore_register_client(struct smscore_device_t *coredev, | |||
1746 | smscore_validate_client(coredev, newclient, params->data_type, | 1744 | smscore_validate_client(coredev, newclient, params->data_type, |
1747 | params->initial_id); | 1745 | params->initial_id); |
1748 | *client = newclient; | 1746 | *client = newclient; |
1749 | sms_debug("%p %d %d", params->context, params->data_type, | 1747 | pr_debug("%p %d %d\n", params->context, params->data_type, |
1750 | params->initial_id); | 1748 | params->initial_id); |
1751 | 1749 | ||
1752 | return 0; | 1750 | return 0; |
@@ -1775,7 +1773,7 @@ void smscore_unregister_client(struct smscore_client_t *client) | |||
1775 | kfree(identry); | 1773 | kfree(identry); |
1776 | } | 1774 | } |
1777 | 1775 | ||
1778 | sms_info("%p", client->context); | 1776 | pr_debug("%p\n", client->context); |
1779 | 1777 | ||
1780 | list_del(&client->entry); | 1778 | list_del(&client->entry); |
1781 | kfree(client); | 1779 | kfree(client); |
@@ -1803,7 +1801,7 @@ int smsclient_sendrequest(struct smscore_client_t *client, | |||
1803 | int rc; | 1801 | int rc; |
1804 | 1802 | ||
1805 | if (client == NULL) { | 1803 | if (client == NULL) { |
1806 | sms_err("Got NULL client"); | 1804 | pr_err("Got NULL client\n"); |
1807 | return -EINVAL; | 1805 | return -EINVAL; |
1808 | } | 1806 | } |
1809 | 1807 | ||
@@ -1811,7 +1809,7 @@ int smsclient_sendrequest(struct smscore_client_t *client, | |||
1811 | 1809 | ||
1812 | /* check that no other channel with same id exists */ | 1810 | /* check that no other channel with same id exists */ |
1813 | if (coredev == NULL) { | 1811 | if (coredev == NULL) { |
1814 | sms_err("Got NULL coredev"); | 1812 | pr_err("Got NULL coredev\n"); |
1815 | return -EINVAL; | 1813 | return -EINVAL; |
1816 | } | 1814 | } |
1817 | 1815 | ||
@@ -2016,9 +2014,9 @@ int smscore_gpio_configure(struct smscore_device_t *coredev, u8 pin_num, | |||
2016 | 2014 | ||
2017 | if (rc != 0) { | 2015 | if (rc != 0) { |
2018 | if (rc == -ETIME) | 2016 | if (rc == -ETIME) |
2019 | sms_err("smscore_gpio_configure timeout"); | 2017 | pr_err("smscore_gpio_configure timeout\n"); |
2020 | else | 2018 | else |
2021 | sms_err("smscore_gpio_configure error"); | 2019 | pr_err("smscore_gpio_configure error\n"); |
2022 | } | 2020 | } |
2023 | free: | 2021 | free: |
2024 | kfree(buffer); | 2022 | kfree(buffer); |
@@ -2065,9 +2063,9 @@ int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 pin_num, | |||
2065 | 2063 | ||
2066 | if (rc != 0) { | 2064 | if (rc != 0) { |
2067 | if (rc == -ETIME) | 2065 | if (rc == -ETIME) |
2068 | sms_err("smscore_gpio_set_level timeout"); | 2066 | pr_err("smscore_gpio_set_level timeout\n"); |
2069 | else | 2067 | else |
2070 | sms_err("smscore_gpio_set_level error"); | 2068 | pr_err("smscore_gpio_set_level error\n"); |
2071 | } | 2069 | } |
2072 | kfree(buffer); | 2070 | kfree(buffer); |
2073 | 2071 | ||
@@ -2113,9 +2111,9 @@ int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 pin_num, | |||
2113 | 2111 | ||
2114 | if (rc != 0) { | 2112 | if (rc != 0) { |
2115 | if (rc == -ETIME) | 2113 | if (rc == -ETIME) |
2116 | sms_err("smscore_gpio_get_level timeout"); | 2114 | pr_err("smscore_gpio_get_level timeout\n"); |
2117 | else | 2115 | else |
2118 | sms_err("smscore_gpio_get_level error"); | 2116 | pr_err("smscore_gpio_get_level error\n"); |
2119 | } | 2117 | } |
2120 | kfree(buffer); | 2118 | kfree(buffer); |
2121 | 2119 | ||
@@ -2163,7 +2161,7 @@ static void __exit smscore_module_exit(void) | |||
2163 | } | 2161 | } |
2164 | kmutex_unlock(&g_smscore_registrylock); | 2162 | kmutex_unlock(&g_smscore_registrylock); |
2165 | 2163 | ||
2166 | sms_debug(""); | 2164 | pr_debug("\n"); |
2167 | } | 2165 | } |
2168 | 2166 | ||
2169 | module_init(smscore_module_init); | 2167 | module_init(smscore_module_init); |
diff --git a/drivers/media/common/siano/smscoreapi.h b/drivers/media/common/siano/smscoreapi.h index 9c9063cd3208..eb8bd689b936 100644 --- a/drivers/media/common/siano/smscoreapi.h +++ b/drivers/media/common/siano/smscoreapi.h | |||
@@ -22,6 +22,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
22 | #ifndef __SMS_CORE_API_H__ | 22 | #ifndef __SMS_CORE_API_H__ |
23 | #define __SMS_CORE_API_H__ | 23 | #define __SMS_CORE_API_H__ |
24 | 24 | ||
25 | #define pr_fmt(fmt) "%s:%s: " fmt, KBUILD_MODNAME, __func__ | ||
26 | |||
25 | #include <linux/device.h> | 27 | #include <linux/device.h> |
26 | #include <linux/list.h> | 28 | #include <linux/list.h> |
27 | #include <linux/mm.h> | 29 | #include <linux/mm.h> |
@@ -31,6 +33,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
31 | #include <linux/wait.h> | 33 | #include <linux/wait.h> |
32 | #include <linux/timer.h> | 34 | #include <linux/timer.h> |
33 | 35 | ||
36 | #include <media/media-device.h> | ||
37 | |||
34 | #include <asm/page.h> | 38 | #include <asm/page.h> |
35 | 39 | ||
36 | #include "smsir.h" | 40 | #include "smsir.h" |
@@ -215,6 +219,10 @@ struct smscore_device_t { | |||
215 | bool is_usb_device; | 219 | bool is_usb_device; |
216 | 220 | ||
217 | int led_state; | 221 | int led_state; |
222 | |||
223 | #if defined(CONFIG_MEDIA_CONTROLLER_DVB) | ||
224 | struct media_device *media_dev; | ||
225 | #endif | ||
218 | }; | 226 | }; |
219 | 227 | ||
220 | /* GPIO definitions for antenna frequency domain control (SMS8021) */ | 228 | /* GPIO definitions for antenna frequency domain control (SMS8021) */ |
@@ -1115,7 +1123,8 @@ extern int smscore_register_hotplug(hotplug_t hotplug); | |||
1115 | extern void smscore_unregister_hotplug(hotplug_t hotplug); | 1123 | extern void smscore_unregister_hotplug(hotplug_t hotplug); |
1116 | 1124 | ||
1117 | extern int smscore_register_device(struct smsdevice_params_t *params, | 1125 | extern int smscore_register_device(struct smsdevice_params_t *params, |
1118 | struct smscore_device_t **coredev); | 1126 | struct smscore_device_t **coredev, |
1127 | void *mdev); | ||
1119 | extern void smscore_unregister_device(struct smscore_device_t *coredev); | 1128 | extern void smscore_unregister_device(struct smscore_device_t *coredev); |
1120 | 1129 | ||
1121 | extern int smscore_start_device(struct smscore_device_t *coredev); | 1130 | extern int smscore_start_device(struct smscore_device_t *coredev); |
@@ -1168,25 +1177,4 @@ int smscore_led_state(struct smscore_device_t *core, int led); | |||
1168 | 1177 | ||
1169 | /* ------------------------------------------------------------------------ */ | 1178 | /* ------------------------------------------------------------------------ */ |
1170 | 1179 | ||
1171 | #define DBG_INFO 1 | ||
1172 | #define DBG_ADV 2 | ||
1173 | |||
1174 | #define sms_printk(kern, fmt, arg...) \ | ||
1175 | printk(kern "%s: " fmt "\n", __func__, ##arg) | ||
1176 | |||
1177 | #define dprintk(kern, lvl, fmt, arg...) do {\ | ||
1178 | if (sms_dbg & lvl) \ | ||
1179 | sms_printk(kern, fmt, ##arg); \ | ||
1180 | } while (0) | ||
1181 | |||
1182 | #define sms_log(fmt, arg...) sms_printk(KERN_INFO, fmt, ##arg) | ||
1183 | #define sms_err(fmt, arg...) \ | ||
1184 | sms_printk(KERN_ERR, "line: %d: " fmt, __LINE__, ##arg) | ||
1185 | #define sms_warn(fmt, arg...) sms_printk(KERN_WARNING, fmt, ##arg) | ||
1186 | #define sms_info(fmt, arg...) \ | ||
1187 | dprintk(KERN_INFO, DBG_INFO, fmt, ##arg) | ||
1188 | #define sms_debug(fmt, arg...) \ | ||
1189 | dprintk(KERN_DEBUG, DBG_ADV, fmt, ##arg) | ||
1190 | |||
1191 | |||
1192 | #endif /* __SMS_CORE_API_H__ */ | 1180 | #endif /* __SMS_CORE_API_H__ */ |
diff --git a/drivers/media/common/siano/smsdvb-debugfs.c b/drivers/media/common/siano/smsdvb-debugfs.c index 2408d7e9451e..1a8677ade391 100644 --- a/drivers/media/common/siano/smsdvb-debugfs.c +++ b/drivers/media/common/siano/smsdvb-debugfs.c | |||
@@ -17,7 +17,7 @@ | |||
17 | * | 17 | * |
18 | ***********************************************************************/ | 18 | ***********************************************************************/ |
19 | 19 | ||
20 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 20 | #include "smscoreapi.h" |
21 | 21 | ||
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
@@ -31,8 +31,6 @@ | |||
31 | #include "dvb_demux.h" | 31 | #include "dvb_demux.h" |
32 | #include "dvb_frontend.h" | 32 | #include "dvb_frontend.h" |
33 | 33 | ||
34 | #include "smscoreapi.h" | ||
35 | |||
36 | #include "smsdvb.h" | 34 | #include "smsdvb.h" |
37 | 35 | ||
38 | static struct dentry *smsdvb_debugfs_usb_root; | 36 | static struct dentry *smsdvb_debugfs_usb_root; |
@@ -536,7 +534,7 @@ int smsdvb_debugfs_register(void) | |||
536 | */ | 534 | */ |
537 | d = debugfs_create_dir("smsdvb", usb_debug_root); | 535 | d = debugfs_create_dir("smsdvb", usb_debug_root); |
538 | if (IS_ERR_OR_NULL(d)) { | 536 | if (IS_ERR_OR_NULL(d)) { |
539 | sms_err("Couldn't create sysfs node for smsdvb"); | 537 | pr_err("Couldn't create sysfs node for smsdvb\n"); |
540 | return PTR_ERR(d); | 538 | return PTR_ERR(d); |
541 | } else { | 539 | } else { |
542 | smsdvb_debugfs_usb_root = d; | 540 | smsdvb_debugfs_usb_root = d; |
diff --git a/drivers/media/common/siano/smsdvb-main.c b/drivers/media/common/siano/smsdvb-main.c index 85151efdd94c..367b8e77feb8 100644 --- a/drivers/media/common/siano/smsdvb-main.c +++ b/drivers/media/common/siano/smsdvb-main.c | |||
@@ -19,6 +19,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
19 | 19 | ||
20 | ****************************************************************/ | 20 | ****************************************************************/ |
21 | 21 | ||
22 | #include "smscoreapi.h" | ||
23 | |||
22 | #include <linux/module.h> | 24 | #include <linux/module.h> |
23 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
24 | #include <linux/init.h> | 26 | #include <linux/init.h> |
@@ -29,7 +31,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
29 | #include "dvb_demux.h" | 31 | #include "dvb_demux.h" |
30 | #include "dvb_frontend.h" | 32 | #include "dvb_frontend.h" |
31 | 33 | ||
32 | #include "smscoreapi.h" | ||
33 | #include "sms-cards.h" | 34 | #include "sms-cards.h" |
34 | 35 | ||
35 | #include "smsdvb.h" | 36 | #include "smsdvb.h" |
@@ -39,11 +40,6 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | |||
39 | static struct list_head g_smsdvb_clients; | 40 | static struct list_head g_smsdvb_clients; |
40 | static struct mutex g_smsdvb_clientslock; | 41 | static struct mutex g_smsdvb_clientslock; |
41 | 42 | ||
42 | static int sms_dbg; | ||
43 | module_param_named(debug, sms_dbg, int, 0644); | ||
44 | MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); | ||
45 | |||
46 | |||
47 | static u32 sms_to_guard_interval_table[] = { | 43 | static u32 sms_to_guard_interval_table[] = { |
48 | [0] = GUARD_INTERVAL_1_32, | 44 | [0] = GUARD_INTERVAL_1_32, |
49 | [1] = GUARD_INTERVAL_1_16, | 45 | [1] = GUARD_INTERVAL_1_16, |
@@ -82,48 +78,48 @@ static void sms_board_dvb3_event(struct smsdvb_client_t *client, | |||
82 | struct smscore_device_t *coredev = client->coredev; | 78 | struct smscore_device_t *coredev = client->coredev; |
83 | switch (event) { | 79 | switch (event) { |
84 | case DVB3_EVENT_INIT: | 80 | case DVB3_EVENT_INIT: |
85 | sms_debug("DVB3_EVENT_INIT"); | 81 | pr_debug("DVB3_EVENT_INIT\n"); |
86 | sms_board_event(coredev, BOARD_EVENT_BIND); | 82 | sms_board_event(coredev, BOARD_EVENT_BIND); |
87 | break; | 83 | break; |
88 | case DVB3_EVENT_SLEEP: | 84 | case DVB3_EVENT_SLEEP: |
89 | sms_debug("DVB3_EVENT_SLEEP"); | 85 | pr_debug("DVB3_EVENT_SLEEP\n"); |
90 | sms_board_event(coredev, BOARD_EVENT_POWER_SUSPEND); | 86 | sms_board_event(coredev, BOARD_EVENT_POWER_SUSPEND); |
91 | break; | 87 | break; |
92 | case DVB3_EVENT_HOTPLUG: | 88 | case DVB3_EVENT_HOTPLUG: |
93 | sms_debug("DVB3_EVENT_HOTPLUG"); | 89 | pr_debug("DVB3_EVENT_HOTPLUG\n"); |
94 | sms_board_event(coredev, BOARD_EVENT_POWER_INIT); | 90 | sms_board_event(coredev, BOARD_EVENT_POWER_INIT); |
95 | break; | 91 | break; |
96 | case DVB3_EVENT_FE_LOCK: | 92 | case DVB3_EVENT_FE_LOCK: |
97 | if (client->event_fe_state != DVB3_EVENT_FE_LOCK) { | 93 | if (client->event_fe_state != DVB3_EVENT_FE_LOCK) { |
98 | client->event_fe_state = DVB3_EVENT_FE_LOCK; | 94 | client->event_fe_state = DVB3_EVENT_FE_LOCK; |
99 | sms_debug("DVB3_EVENT_FE_LOCK"); | 95 | pr_debug("DVB3_EVENT_FE_LOCK\n"); |
100 | sms_board_event(coredev, BOARD_EVENT_FE_LOCK); | 96 | sms_board_event(coredev, BOARD_EVENT_FE_LOCK); |
101 | } | 97 | } |
102 | break; | 98 | break; |
103 | case DVB3_EVENT_FE_UNLOCK: | 99 | case DVB3_EVENT_FE_UNLOCK: |
104 | if (client->event_fe_state != DVB3_EVENT_FE_UNLOCK) { | 100 | if (client->event_fe_state != DVB3_EVENT_FE_UNLOCK) { |
105 | client->event_fe_state = DVB3_EVENT_FE_UNLOCK; | 101 | client->event_fe_state = DVB3_EVENT_FE_UNLOCK; |
106 | sms_debug("DVB3_EVENT_FE_UNLOCK"); | 102 | pr_debug("DVB3_EVENT_FE_UNLOCK\n"); |
107 | sms_board_event(coredev, BOARD_EVENT_FE_UNLOCK); | 103 | sms_board_event(coredev, BOARD_EVENT_FE_UNLOCK); |
108 | } | 104 | } |
109 | break; | 105 | break; |
110 | case DVB3_EVENT_UNC_OK: | 106 | case DVB3_EVENT_UNC_OK: |
111 | if (client->event_unc_state != DVB3_EVENT_UNC_OK) { | 107 | if (client->event_unc_state != DVB3_EVENT_UNC_OK) { |
112 | client->event_unc_state = DVB3_EVENT_UNC_OK; | 108 | client->event_unc_state = DVB3_EVENT_UNC_OK; |
113 | sms_debug("DVB3_EVENT_UNC_OK"); | 109 | pr_debug("DVB3_EVENT_UNC_OK\n"); |
114 | sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_OK); | 110 | sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_OK); |
115 | } | 111 | } |
116 | break; | 112 | break; |
117 | case DVB3_EVENT_UNC_ERR: | 113 | case DVB3_EVENT_UNC_ERR: |
118 | if (client->event_unc_state != DVB3_EVENT_UNC_ERR) { | 114 | if (client->event_unc_state != DVB3_EVENT_UNC_ERR) { |
119 | client->event_unc_state = DVB3_EVENT_UNC_ERR; | 115 | client->event_unc_state = DVB3_EVENT_UNC_ERR; |
120 | sms_debug("DVB3_EVENT_UNC_ERR"); | 116 | pr_debug("DVB3_EVENT_UNC_ERR\n"); |
121 | sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_ERRORS); | 117 | sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_ERRORS); |
122 | } | 118 | } |
123 | break; | 119 | break; |
124 | 120 | ||
125 | default: | 121 | default: |
126 | sms_err("Unknown dvb3 api event"); | 122 | pr_err("Unknown dvb3 api event\n"); |
127 | break; | 123 | break; |
128 | } | 124 | } |
129 | } | 125 | } |
@@ -590,7 +586,7 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) | |||
590 | is_status_update = true; | 586 | is_status_update = true; |
591 | break; | 587 | break; |
592 | default: | 588 | default: |
593 | sms_info("message not handled"); | 589 | pr_debug("message not handled\n"); |
594 | } | 590 | } |
595 | smscore_putbuffer(client->coredev, cb); | 591 | smscore_putbuffer(client->coredev, cb); |
596 | 592 | ||
@@ -613,6 +609,19 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) | |||
613 | return 0; | 609 | return 0; |
614 | } | 610 | } |
615 | 611 | ||
612 | static void smsdvb_media_device_unregister(struct smsdvb_client_t *client) | ||
613 | { | ||
614 | #ifdef CONFIG_MEDIA_CONTROLLER_DVB | ||
615 | struct smscore_device_t *coredev = client->coredev; | ||
616 | |||
617 | if (!coredev->media_dev) | ||
618 | return; | ||
619 | media_device_unregister(coredev->media_dev); | ||
620 | kfree(coredev->media_dev); | ||
621 | coredev->media_dev = NULL; | ||
622 | #endif | ||
623 | } | ||
624 | |||
616 | static void smsdvb_unregister_client(struct smsdvb_client_t *client) | 625 | static void smsdvb_unregister_client(struct smsdvb_client_t *client) |
617 | { | 626 | { |
618 | /* must be called under clientslock */ | 627 | /* must be called under clientslock */ |
@@ -624,6 +633,7 @@ static void smsdvb_unregister_client(struct smsdvb_client_t *client) | |||
624 | dvb_unregister_frontend(&client->frontend); | 633 | dvb_unregister_frontend(&client->frontend); |
625 | dvb_dmxdev_release(&client->dmxdev); | 634 | dvb_dmxdev_release(&client->dmxdev); |
626 | dvb_dmx_release(&client->demux); | 635 | dvb_dmx_release(&client->demux); |
636 | smsdvb_media_device_unregister(client); | ||
627 | dvb_unregister_adapter(&client->adapter); | 637 | dvb_unregister_adapter(&client->adapter); |
628 | kfree(client); | 638 | kfree(client); |
629 | } | 639 | } |
@@ -643,7 +653,7 @@ static int smsdvb_start_feed(struct dvb_demux_feed *feed) | |||
643 | container_of(feed->demux, struct smsdvb_client_t, demux); | 653 | container_of(feed->demux, struct smsdvb_client_t, demux); |
644 | struct sms_msg_data pid_msg; | 654 | struct sms_msg_data pid_msg; |
645 | 655 | ||
646 | sms_debug("add pid %d(%x)", | 656 | pr_debug("add pid %d(%x)\n", |
647 | feed->pid, feed->pid); | 657 | feed->pid, feed->pid); |
648 | 658 | ||
649 | client->feed_users++; | 659 | client->feed_users++; |
@@ -665,7 +675,7 @@ static int smsdvb_stop_feed(struct dvb_demux_feed *feed) | |||
665 | container_of(feed->demux, struct smsdvb_client_t, demux); | 675 | container_of(feed->demux, struct smsdvb_client_t, demux); |
666 | struct sms_msg_data pid_msg; | 676 | struct sms_msg_data pid_msg; |
667 | 677 | ||
668 | sms_debug("remove pid %d(%x)", | 678 | pr_debug("remove pid %d(%x)\n", |
669 | feed->pid, feed->pid); | 679 | feed->pid, feed->pid); |
670 | 680 | ||
671 | client->feed_users--; | 681 | client->feed_users--; |
@@ -835,7 +845,7 @@ static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) | |||
835 | static int smsdvb_get_tune_settings(struct dvb_frontend *fe, | 845 | static int smsdvb_get_tune_settings(struct dvb_frontend *fe, |
836 | struct dvb_frontend_tune_settings *tune) | 846 | struct dvb_frontend_tune_settings *tune) |
837 | { | 847 | { |
838 | sms_debug(""); | 848 | pr_debug("\n"); |
839 | 849 | ||
840 | tune->min_delay_ms = 400; | 850 | tune->min_delay_ms = 400; |
841 | tune->step_size = 250000; | 851 | tune->step_size = 250000; |
@@ -869,7 +879,7 @@ static int smsdvb_dvbt_set_frontend(struct dvb_frontend *fe) | |||
869 | msg.Data[0] = c->frequency; | 879 | msg.Data[0] = c->frequency; |
870 | msg.Data[2] = 12000000; | 880 | msg.Data[2] = 12000000; |
871 | 881 | ||
872 | sms_info("%s: freq %d band %d", __func__, c->frequency, | 882 | pr_debug("%s: freq %d band %d\n", __func__, c->frequency, |
873 | c->bandwidth_hz); | 883 | c->bandwidth_hz); |
874 | 884 | ||
875 | switch (c->bandwidth_hz / 1000000) { | 885 | switch (c->bandwidth_hz / 1000000) { |
@@ -954,7 +964,7 @@ static int smsdvb_isdbt_set_frontend(struct dvb_frontend *fe) | |||
954 | 964 | ||
955 | c->bandwidth_hz = 6000000; | 965 | c->bandwidth_hz = 6000000; |
956 | 966 | ||
957 | sms_info("%s: freq %d segwidth %d segindex %d", __func__, | 967 | pr_debug("freq %d segwidth %d segindex %d\n", |
958 | c->frequency, c->isdbt_sb_segment_count, | 968 | c->frequency, c->isdbt_sb_segment_count, |
959 | c->isdbt_sb_segment_idx); | 969 | c->isdbt_sb_segment_idx); |
960 | 970 | ||
@@ -1082,10 +1092,8 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, | |||
1082 | if (!arrival) | 1092 | if (!arrival) |
1083 | return 0; | 1093 | return 0; |
1084 | client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL); | 1094 | client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL); |
1085 | if (!client) { | 1095 | if (!client) |
1086 | sms_err("kmalloc() failed"); | ||
1087 | return -ENOMEM; | 1096 | return -ENOMEM; |
1088 | } | ||
1089 | 1097 | ||
1090 | /* register dvb adapter */ | 1098 | /* register dvb adapter */ |
1091 | rc = dvb_register_adapter(&client->adapter, | 1099 | rc = dvb_register_adapter(&client->adapter, |
@@ -1093,9 +1101,10 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, | |||
1093 | smscore_get_board_id(coredev))->name, | 1101 | smscore_get_board_id(coredev))->name, |
1094 | THIS_MODULE, device, adapter_nr); | 1102 | THIS_MODULE, device, adapter_nr); |
1095 | if (rc < 0) { | 1103 | if (rc < 0) { |
1096 | sms_err("dvb_register_adapter() failed %d", rc); | 1104 | pr_err("dvb_register_adapter() failed %d\n", rc); |
1097 | goto adapter_error; | 1105 | goto adapter_error; |
1098 | } | 1106 | } |
1107 | dvb_register_media_controller(&client->adapter, coredev->media_dev); | ||
1099 | 1108 | ||
1100 | /* init dvb demux */ | 1109 | /* init dvb demux */ |
1101 | client->demux.dmx.capabilities = DMX_TS_FILTERING; | 1110 | client->demux.dmx.capabilities = DMX_TS_FILTERING; |
@@ -1106,7 +1115,7 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, | |||
1106 | 1115 | ||
1107 | rc = dvb_dmx_init(&client->demux); | 1116 | rc = dvb_dmx_init(&client->demux); |
1108 | if (rc < 0) { | 1117 | if (rc < 0) { |
1109 | sms_err("dvb_dmx_init failed %d", rc); | 1118 | pr_err("dvb_dmx_init failed %d\n", rc); |
1110 | goto dvbdmx_error; | 1119 | goto dvbdmx_error; |
1111 | } | 1120 | } |
1112 | 1121 | ||
@@ -1117,7 +1126,7 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, | |||
1117 | 1126 | ||
1118 | rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter); | 1127 | rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter); |
1119 | if (rc < 0) { | 1128 | if (rc < 0) { |
1120 | sms_err("dvb_dmxdev_init failed %d", rc); | 1129 | pr_err("dvb_dmxdev_init failed %d\n", rc); |
1121 | goto dmxdev_error; | 1130 | goto dmxdev_error; |
1122 | } | 1131 | } |
1123 | 1132 | ||
@@ -1138,7 +1147,7 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, | |||
1138 | 1147 | ||
1139 | rc = dvb_register_frontend(&client->adapter, &client->frontend); | 1148 | rc = dvb_register_frontend(&client->adapter, &client->frontend); |
1140 | if (rc < 0) { | 1149 | if (rc < 0) { |
1141 | sms_err("frontend registration failed %d", rc); | 1150 | pr_err("frontend registration failed %d\n", rc); |
1142 | goto frontend_error; | 1151 | goto frontend_error; |
1143 | } | 1152 | } |
1144 | 1153 | ||
@@ -1150,7 +1159,7 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, | |||
1150 | 1159 | ||
1151 | rc = smscore_register_client(coredev, ¶ms, &client->smsclient); | 1160 | rc = smscore_register_client(coredev, ¶ms, &client->smsclient); |
1152 | if (rc < 0) { | 1161 | if (rc < 0) { |
1153 | sms_err("smscore_register_client() failed %d", rc); | 1162 | pr_err("smscore_register_client() failed %d\n", rc); |
1154 | goto client_error; | 1163 | goto client_error; |
1155 | } | 1164 | } |
1156 | 1165 | ||
@@ -1169,12 +1178,14 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, | |||
1169 | client->event_unc_state = -1; | 1178 | client->event_unc_state = -1; |
1170 | sms_board_dvb3_event(client, DVB3_EVENT_HOTPLUG); | 1179 | sms_board_dvb3_event(client, DVB3_EVENT_HOTPLUG); |
1171 | 1180 | ||
1172 | sms_info("success"); | ||
1173 | sms_board_setup(coredev); | 1181 | sms_board_setup(coredev); |
1174 | 1182 | ||
1175 | if (smsdvb_debugfs_create(client) < 0) | 1183 | if (smsdvb_debugfs_create(client) < 0) |
1176 | sms_info("failed to create debugfs node"); | 1184 | pr_info("failed to create debugfs node\n"); |
1185 | |||
1186 | dvb_create_media_graph(&client->adapter); | ||
1177 | 1187 | ||
1188 | pr_info("DVB interface registered.\n"); | ||
1178 | return 0; | 1189 | return 0; |
1179 | 1190 | ||
1180 | client_error: | 1191 | client_error: |
@@ -1187,6 +1198,7 @@ dmxdev_error: | |||
1187 | dvb_dmx_release(&client->demux); | 1198 | dvb_dmx_release(&client->demux); |
1188 | 1199 | ||
1189 | dvbdmx_error: | 1200 | dvbdmx_error: |
1201 | smsdvb_media_device_unregister(client); | ||
1190 | dvb_unregister_adapter(&client->adapter); | 1202 | dvb_unregister_adapter(&client->adapter); |
1191 | 1203 | ||
1192 | adapter_error: | 1204 | adapter_error: |
@@ -1205,7 +1217,7 @@ static int __init smsdvb_module_init(void) | |||
1205 | 1217 | ||
1206 | rc = smscore_register_hotplug(smsdvb_hotplug); | 1218 | rc = smscore_register_hotplug(smsdvb_hotplug); |
1207 | 1219 | ||
1208 | sms_debug(""); | 1220 | pr_debug("\n"); |
1209 | 1221 | ||
1210 | return rc; | 1222 | return rc; |
1211 | } | 1223 | } |
diff --git a/drivers/media/common/siano/smsir.c b/drivers/media/common/siano/smsir.c index 35d0e887bd65..1d60d200d9ab 100644 --- a/drivers/media/common/siano/smsir.c +++ b/drivers/media/common/siano/smsir.c | |||
@@ -25,10 +25,11 @@ | |||
25 | ****************************************************************/ | 25 | ****************************************************************/ |
26 | 26 | ||
27 | 27 | ||
28 | #include "smscoreapi.h" | ||
29 | |||
28 | #include <linux/types.h> | 30 | #include <linux/types.h> |
29 | #include <linux/input.h> | 31 | #include <linux/input.h> |
30 | 32 | ||
31 | #include "smscoreapi.h" | ||
32 | #include "smsir.h" | 33 | #include "smsir.h" |
33 | #include "sms-cards.h" | 34 | #include "sms-cards.h" |
34 | 35 | ||
@@ -56,16 +57,14 @@ int sms_ir_init(struct smscore_device_t *coredev) | |||
56 | int board_id = smscore_get_board_id(coredev); | 57 | int board_id = smscore_get_board_id(coredev); |
57 | struct rc_dev *dev; | 58 | struct rc_dev *dev; |
58 | 59 | ||
59 | sms_log("Allocating rc device"); | 60 | pr_debug("Allocating rc device\n"); |
60 | dev = rc_allocate_device(); | 61 | dev = rc_allocate_device(); |
61 | if (!dev) { | 62 | if (!dev) |
62 | sms_err("Not enough memory"); | ||
63 | return -ENOMEM; | 63 | return -ENOMEM; |
64 | } | ||
65 | 64 | ||
66 | coredev->ir.controller = 0; /* Todo: vega/nova SPI number */ | 65 | coredev->ir.controller = 0; /* Todo: vega/nova SPI number */ |
67 | coredev->ir.timeout = IR_DEFAULT_TIMEOUT; | 66 | coredev->ir.timeout = IR_DEFAULT_TIMEOUT; |
68 | sms_log("IR port %d, timeout %d ms", | 67 | pr_debug("IR port %d, timeout %d ms\n", |
69 | coredev->ir.controller, coredev->ir.timeout); | 68 | coredev->ir.controller, coredev->ir.timeout); |
70 | 69 | ||
71 | snprintf(coredev->ir.name, sizeof(coredev->ir.name), | 70 | snprintf(coredev->ir.name, sizeof(coredev->ir.name), |
@@ -92,11 +91,12 @@ int sms_ir_init(struct smscore_device_t *coredev) | |||
92 | dev->map_name = sms_get_board(board_id)->rc_codes; | 91 | dev->map_name = sms_get_board(board_id)->rc_codes; |
93 | dev->driver_name = MODULE_NAME; | 92 | dev->driver_name = MODULE_NAME; |
94 | 93 | ||
95 | sms_log("Input device (IR) %s is set for key events", dev->input_name); | 94 | pr_debug("Input device (IR) %s is set for key events\n", |
95 | dev->input_name); | ||
96 | 96 | ||
97 | err = rc_register_device(dev); | 97 | err = rc_register_device(dev); |
98 | if (err < 0) { | 98 | if (err < 0) { |
99 | sms_err("Failed to register device"); | 99 | pr_err("Failed to register device\n"); |
100 | rc_free_device(dev); | 100 | rc_free_device(dev); |
101 | return err; | 101 | return err; |
102 | } | 102 | } |
@@ -109,5 +109,5 @@ void sms_ir_exit(struct smscore_device_t *coredev) | |||
109 | { | 109 | { |
110 | rc_unregister_device(coredev->ir.dev); | 110 | rc_unregister_device(coredev->ir.dev); |
111 | 111 | ||
112 | sms_log(""); | 112 | pr_debug("\n"); |
113 | } | 113 | } |
diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c index abff803ad69a..d0e3f9d85f34 100644 --- a/drivers/media/dvb-core/dmxdev.c +++ b/drivers/media/dvb-core/dmxdev.c | |||
@@ -1136,10 +1136,13 @@ static const struct file_operations dvb_demux_fops = { | |||
1136 | .llseek = default_llseek, | 1136 | .llseek = default_llseek, |
1137 | }; | 1137 | }; |
1138 | 1138 | ||
1139 | static struct dvb_device dvbdev_demux = { | 1139 | static const struct dvb_device dvbdev_demux = { |
1140 | .priv = NULL, | 1140 | .priv = NULL, |
1141 | .users = 1, | 1141 | .users = 1, |
1142 | .writers = 1, | 1142 | .writers = 1, |
1143 | #if defined(CONFIG_MEDIA_CONTROLLER_DVB) | ||
1144 | .name = "dvb-demux", | ||
1145 | #endif | ||
1143 | .fops = &dvb_demux_fops | 1146 | .fops = &dvb_demux_fops |
1144 | }; | 1147 | }; |
1145 | 1148 | ||
@@ -1209,13 +1212,15 @@ static const struct file_operations dvb_dvr_fops = { | |||
1209 | .llseek = default_llseek, | 1212 | .llseek = default_llseek, |
1210 | }; | 1213 | }; |
1211 | 1214 | ||
1212 | static struct dvb_device dvbdev_dvr = { | 1215 | static const struct dvb_device dvbdev_dvr = { |
1213 | .priv = NULL, | 1216 | .priv = NULL, |
1214 | .readers = 1, | 1217 | .readers = 1, |
1215 | .users = 1, | 1218 | .users = 1, |
1219 | #if defined(CONFIG_MEDIA_CONTROLLER_DVB) | ||
1220 | .name = "dvb-dvr", | ||
1221 | #endif | ||
1216 | .fops = &dvb_dvr_fops | 1222 | .fops = &dvb_dvr_fops |
1217 | }; | 1223 | }; |
1218 | |||
1219 | int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter) | 1224 | int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter) |
1220 | { | 1225 | { |
1221 | int i; | 1226 | int i; |
diff --git a/drivers/media/dvb-core/dvb-usb-ids.h b/drivers/media/dvb-core/dvb-usb-ids.h index 80ab8d0ff6e0..c117fb3b4aff 100644 --- a/drivers/media/dvb-core/dvb-usb-ids.h +++ b/drivers/media/dvb-core/dvb-usb-ids.h | |||
@@ -245,6 +245,7 @@ | |||
245 | #define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006 | 245 | #define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006 |
246 | #define USB_PID_TECHNOTREND_CONNECT_S2400_8KEEPROM 0x3009 | 246 | #define USB_PID_TECHNOTREND_CONNECT_S2400_8KEEPROM 0x3009 |
247 | #define USB_PID_TECHNOTREND_CONNECT_CT3650 0x300d | 247 | #define USB_PID_TECHNOTREND_CONNECT_CT3650 0x300d |
248 | #define USB_PID_TECHNOTREND_CONNECT_S2_4600 0x3011 | ||
248 | #define USB_PID_TECHNOTREND_CONNECT_CT2_4650_CI 0x3012 | 249 | #define USB_PID_TECHNOTREND_CONNECT_CT2_4650_CI 0x3012 |
249 | #define USB_PID_TECHNOTREND_TVSTICK_CT2_4400 0x3014 | 250 | #define USB_PID_TECHNOTREND_TVSTICK_CT2_4400 0x3014 |
250 | #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a | 251 | #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a |
@@ -318,6 +319,7 @@ | |||
318 | #define USB_PID_GRANDTEC_DVBT_USB2_COLD 0x0bc6 | 319 | #define USB_PID_GRANDTEC_DVBT_USB2_COLD 0x0bc6 |
319 | #define USB_PID_GRANDTEC_DVBT_USB2_WARM 0x0bc7 | 320 | #define USB_PID_GRANDTEC_DVBT_USB2_WARM 0x0bc7 |
320 | #define USB_PID_WINFAST_DTV2000DS 0x6a04 | 321 | #define USB_PID_WINFAST_DTV2000DS 0x6a04 |
322 | #define USB_PID_WINFAST_DTV2000DS_PLUS 0x6f12 | ||
321 | #define USB_PID_WINFAST_DTV_DONGLE_COLD 0x6025 | 323 | #define USB_PID_WINFAST_DTV_DONGLE_COLD 0x6025 |
322 | #define USB_PID_WINFAST_DTV_DONGLE_WARM 0x6026 | 324 | #define USB_PID_WINFAST_DTV_DONGLE_WARM 0x6026 |
323 | #define USB_PID_WINFAST_DTV_DONGLE_STK7700P 0x6f00 | 325 | #define USB_PID_WINFAST_DTV_DONGLE_STK7700P 0x6f00 |
@@ -385,4 +387,5 @@ | |||
385 | #define USB_PID_PCTV_2002E 0x025c | 387 | #define USB_PID_PCTV_2002E 0x025c |
386 | #define USB_PID_PCTV_2002E_SE 0x025d | 388 | #define USB_PID_PCTV_2002E_SE 0x025d |
387 | #define USB_PID_SVEON_STV27 0xd3af | 389 | #define USB_PID_SVEON_STV27 0xd3af |
390 | #define USB_PID_TURBOX_DTT_2000 0xd3a4 | ||
388 | #endif | 391 | #endif |
diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c index 0aac3096728e..72937756f60c 100644 --- a/drivers/media/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb-core/dvb_ca_en50221.c | |||
@@ -1638,15 +1638,17 @@ static const struct file_operations dvb_ca_fops = { | |||
1638 | .llseek = noop_llseek, | 1638 | .llseek = noop_llseek, |
1639 | }; | 1639 | }; |
1640 | 1640 | ||
1641 | static struct dvb_device dvbdev_ca = { | 1641 | static const struct dvb_device dvbdev_ca = { |
1642 | .priv = NULL, | 1642 | .priv = NULL, |
1643 | .users = 1, | 1643 | .users = 1, |
1644 | .readers = 1, | 1644 | .readers = 1, |
1645 | .writers = 1, | 1645 | .writers = 1, |
1646 | #if defined(CONFIG_MEDIA_CONTROLLER_DVB) | ||
1647 | .name = "dvb-ca-en50221", | ||
1648 | #endif | ||
1646 | .fops = &dvb_ca_fops, | 1649 | .fops = &dvb_ca_fops, |
1647 | }; | 1650 | }; |
1648 | 1651 | ||
1649 | |||
1650 | /* ******************************************************************************** */ | 1652 | /* ******************************************************************************** */ |
1651 | /* Initialisation/shutdown functions */ | 1653 | /* Initialisation/shutdown functions */ |
1652 | 1654 | ||
@@ -1676,14 +1678,14 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, | |||
1676 | /* initialise the system data */ | 1678 | /* initialise the system data */ |
1677 | if ((ca = kzalloc(sizeof(struct dvb_ca_private), GFP_KERNEL)) == NULL) { | 1679 | if ((ca = kzalloc(sizeof(struct dvb_ca_private), GFP_KERNEL)) == NULL) { |
1678 | ret = -ENOMEM; | 1680 | ret = -ENOMEM; |
1679 | goto error; | 1681 | goto exit; |
1680 | } | 1682 | } |
1681 | ca->pub = pubca; | 1683 | ca->pub = pubca; |
1682 | ca->flags = flags; | 1684 | ca->flags = flags; |
1683 | ca->slot_count = slot_count; | 1685 | ca->slot_count = slot_count; |
1684 | if ((ca->slot_info = kcalloc(slot_count, sizeof(struct dvb_ca_slot), GFP_KERNEL)) == NULL) { | 1686 | if ((ca->slot_info = kcalloc(slot_count, sizeof(struct dvb_ca_slot), GFP_KERNEL)) == NULL) { |
1685 | ret = -ENOMEM; | 1687 | ret = -ENOMEM; |
1686 | goto error; | 1688 | goto free_ca; |
1687 | } | 1689 | } |
1688 | init_waitqueue_head(&ca->wait_queue); | 1690 | init_waitqueue_head(&ca->wait_queue); |
1689 | ca->open = 0; | 1691 | ca->open = 0; |
@@ -1694,7 +1696,7 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, | |||
1694 | /* register the DVB device */ | 1696 | /* register the DVB device */ |
1695 | ret = dvb_register_device(dvb_adapter, &ca->dvbdev, &dvbdev_ca, ca, DVB_DEVICE_CA); | 1697 | ret = dvb_register_device(dvb_adapter, &ca->dvbdev, &dvbdev_ca, ca, DVB_DEVICE_CA); |
1696 | if (ret) | 1698 | if (ret) |
1697 | goto error; | 1699 | goto free_slot_info; |
1698 | 1700 | ||
1699 | /* now initialise each slot */ | 1701 | /* now initialise each slot */ |
1700 | for (i = 0; i < slot_count; i++) { | 1702 | for (i = 0; i < slot_count; i++) { |
@@ -1709,7 +1711,7 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, | |||
1709 | 1711 | ||
1710 | if (signal_pending(current)) { | 1712 | if (signal_pending(current)) { |
1711 | ret = -EINTR; | 1713 | ret = -EINTR; |
1712 | goto error; | 1714 | goto unregister_device; |
1713 | } | 1715 | } |
1714 | mb(); | 1716 | mb(); |
1715 | 1717 | ||
@@ -1720,17 +1722,17 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, | |||
1720 | ret = PTR_ERR(ca->thread); | 1722 | ret = PTR_ERR(ca->thread); |
1721 | printk("dvb_ca_init: failed to start kernel_thread (%d)\n", | 1723 | printk("dvb_ca_init: failed to start kernel_thread (%d)\n", |
1722 | ret); | 1724 | ret); |
1723 | goto error; | 1725 | goto unregister_device; |
1724 | } | 1726 | } |
1725 | return 0; | 1727 | return 0; |
1726 | 1728 | ||
1727 | error: | 1729 | unregister_device: |
1728 | if (ca != NULL) { | 1730 | dvb_unregister_device(ca->dvbdev); |
1729 | if (ca->dvbdev != NULL) | 1731 | free_slot_info: |
1730 | dvb_unregister_device(ca->dvbdev); | 1732 | kfree(ca->slot_info); |
1731 | kfree(ca->slot_info); | 1733 | free_ca: |
1732 | kfree(ca); | 1734 | kfree(ca); |
1733 | } | 1735 | exit: |
1734 | pubca->private = NULL; | 1736 | pubca->private = NULL; |
1735 | return ret; | 1737 | return ret; |
1736 | } | 1738 | } |
diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index 2cf30576bf39..882ca417f328 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c | |||
@@ -131,6 +131,11 @@ struct dvb_frontend_private { | |||
131 | int quality; | 131 | int quality; |
132 | unsigned int check_wrapped; | 132 | unsigned int check_wrapped; |
133 | enum dvbfe_search algo_status; | 133 | enum dvbfe_search algo_status; |
134 | |||
135 | #if defined(CONFIG_MEDIA_CONTROLLER_DVB) | ||
136 | struct media_pipeline pipe; | ||
137 | struct media_entity *pipe_start_entity; | ||
138 | #endif | ||
134 | }; | 139 | }; |
135 | 140 | ||
136 | static void dvb_frontend_wakeup(struct dvb_frontend *fe); | 141 | static void dvb_frontend_wakeup(struct dvb_frontend *fe); |
@@ -590,12 +595,106 @@ static void dvb_frontend_wakeup(struct dvb_frontend *fe) | |||
590 | wake_up_interruptible(&fepriv->wait_queue); | 595 | wake_up_interruptible(&fepriv->wait_queue); |
591 | } | 596 | } |
592 | 597 | ||
598 | /** | ||
599 | * dvb_enable_media_tuner() - tries to enable the DVB tuner | ||
600 | * | ||
601 | * @fe: struct dvb_frontend pointer | ||
602 | * | ||
603 | * This function ensures that just one media tuner is enabled for a given | ||
604 | * frontend. It has two different behaviors: | ||
605 | * - For trivial devices with just one tuner: | ||
606 | * it just enables the existing tuner->fe link | ||
607 | * - For devices with more than one tuner: | ||
608 | * It is up to the driver to implement the logic that will enable one tuner | ||
609 | * and disable the other ones. However, if more than one tuner is enabled for | ||
610 | * the same frontend, it will print an error message and return -EINVAL. | ||
611 | * | ||
612 | * At return, it will return the error code returned by media_entity_setup_link, | ||
613 | * or 0 if everything is OK, if no tuner is linked to the frontend or if the | ||
614 | * mdev is NULL. | ||
615 | */ | ||
616 | #ifdef CONFIG_MEDIA_CONTROLLER_DVB | ||
617 | static int dvb_enable_media_tuner(struct dvb_frontend *fe) | ||
618 | { | ||
619 | struct dvb_frontend_private *fepriv = fe->frontend_priv; | ||
620 | struct dvb_adapter *adapter = fe->dvb; | ||
621 | struct media_device *mdev = adapter->mdev; | ||
622 | struct media_entity *entity, *source; | ||
623 | struct media_link *link, *found_link = NULL; | ||
624 | int i, ret, n_links = 0, active_links = 0; | ||
625 | |||
626 | fepriv->pipe_start_entity = NULL; | ||
627 | |||
628 | if (!mdev) | ||
629 | return 0; | ||
630 | |||
631 | entity = fepriv->dvbdev->entity; | ||
632 | fepriv->pipe_start_entity = entity; | ||
633 | |||
634 | for (i = 0; i < entity->num_links; i++) { | ||
635 | link = &entity->links[i]; | ||
636 | if (link->sink->entity == entity) { | ||
637 | found_link = link; | ||
638 | n_links++; | ||
639 | if (link->flags & MEDIA_LNK_FL_ENABLED) | ||
640 | active_links++; | ||
641 | } | ||
642 | } | ||
643 | |||
644 | if (!n_links || active_links == 1 || !found_link) | ||
645 | return 0; | ||
646 | |||
647 | /* | ||
648 | * If a frontend has more than one tuner linked, it is up to the driver | ||
649 | * to select with one will be the active one, as the frontend core can't | ||
650 | * guess. If the driver doesn't do that, it is a bug. | ||
651 | */ | ||
652 | if (n_links > 1 && active_links != 1) { | ||
653 | dev_err(fe->dvb->device, | ||
654 | "WARNING: there are %d active links among %d tuners. This is a driver's bug!\n", | ||
655 | active_links, n_links); | ||
656 | return -EINVAL; | ||
657 | } | ||
658 | |||
659 | source = found_link->source->entity; | ||
660 | fepriv->pipe_start_entity = source; | ||
661 | for (i = 0; i < source->num_links; i++) { | ||
662 | struct media_entity *sink; | ||
663 | int flags = 0; | ||
664 | |||
665 | link = &source->links[i]; | ||
666 | sink = link->sink->entity; | ||
667 | |||
668 | if (sink == entity) | ||
669 | flags = MEDIA_LNK_FL_ENABLED; | ||
670 | |||
671 | ret = media_entity_setup_link(link, flags); | ||
672 | if (ret) { | ||
673 | dev_err(fe->dvb->device, | ||
674 | "Couldn't change link %s->%s to %s. Error %d\n", | ||
675 | source->name, sink->name, | ||
676 | flags ? "enabled" : "disabled", | ||
677 | ret); | ||
678 | return ret; | ||
679 | } else | ||
680 | dev_dbg(fe->dvb->device, | ||
681 | "link %s->%s was %s\n", | ||
682 | source->name, sink->name, | ||
683 | flags ? "ENABLED" : "disabled"); | ||
684 | } | ||
685 | return 0; | ||
686 | } | ||
687 | #endif | ||
688 | |||
593 | static int dvb_frontend_thread(void *data) | 689 | static int dvb_frontend_thread(void *data) |
594 | { | 690 | { |
595 | struct dvb_frontend *fe = data; | 691 | struct dvb_frontend *fe = data; |
596 | struct dvb_frontend_private *fepriv = fe->frontend_priv; | 692 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
597 | fe_status_t s; | 693 | fe_status_t s; |
598 | enum dvbfe_algo algo; | 694 | enum dvbfe_algo algo; |
695 | #ifdef CONFIG_MEDIA_CONTROLLER_DVB | ||
696 | int ret; | ||
697 | #endif | ||
599 | 698 | ||
600 | bool re_tune = false; | 699 | bool re_tune = false; |
601 | bool semheld = false; | 700 | bool semheld = false; |
@@ -609,6 +708,20 @@ static int dvb_frontend_thread(void *data) | |||
609 | fepriv->wakeup = 0; | 708 | fepriv->wakeup = 0; |
610 | fepriv->reinitialise = 0; | 709 | fepriv->reinitialise = 0; |
611 | 710 | ||
711 | #ifdef CONFIG_MEDIA_CONTROLLER_DVB | ||
712 | ret = dvb_enable_media_tuner(fe); | ||
713 | if (ret) { | ||
714 | /* FIXME: return an error if it fails */ | ||
715 | dev_info(fe->dvb->device, | ||
716 | "proceeding with FE task\n"); | ||
717 | } else if (fepriv->pipe_start_entity) { | ||
718 | ret = media_entity_pipeline_start(fepriv->pipe_start_entity, | ||
719 | &fepriv->pipe); | ||
720 | if (ret) | ||
721 | return ret; | ||
722 | } | ||
723 | #endif | ||
724 | |||
612 | dvb_frontend_init(fe); | 725 | dvb_frontend_init(fe); |
613 | 726 | ||
614 | set_freezable(); | 727 | set_freezable(); |
@@ -718,6 +831,12 @@ restart: | |||
718 | } | 831 | } |
719 | } | 832 | } |
720 | 833 | ||
834 | #ifdef CONFIG_MEDIA_CONTROLLER_DVB | ||
835 | if (fepriv->pipe_start_entity) | ||
836 | media_entity_pipeline_stop(fepriv->pipe_start_entity); | ||
837 | fepriv->pipe_start_entity = NULL; | ||
838 | #endif | ||
839 | |||
721 | if (dvb_powerdown_on_sleep) { | 840 | if (dvb_powerdown_on_sleep) { |
722 | if (fe->ops.set_voltage) | 841 | if (fe->ops.set_voltage) |
723 | fe->ops.set_voltage(fe, SEC_VOLTAGE_OFF); | 842 | fe->ops.set_voltage(fe, SEC_VOLTAGE_OFF); |
@@ -2612,11 +2731,14 @@ int dvb_register_frontend(struct dvb_adapter* dvb, | |||
2612 | struct dvb_frontend* fe) | 2731 | struct dvb_frontend* fe) |
2613 | { | 2732 | { |
2614 | struct dvb_frontend_private *fepriv; | 2733 | struct dvb_frontend_private *fepriv; |
2615 | static const struct dvb_device dvbdev_template = { | 2734 | const struct dvb_device dvbdev_template = { |
2616 | .users = ~0, | 2735 | .users = ~0, |
2617 | .writers = 1, | 2736 | .writers = 1, |
2618 | .readers = (~0)-1, | 2737 | .readers = (~0)-1, |
2619 | .fops = &dvb_frontend_fops, | 2738 | .fops = &dvb_frontend_fops, |
2739 | #if defined(CONFIG_MEDIA_CONTROLLER_DVB) | ||
2740 | .name = fe->ops.info.name, | ||
2741 | #endif | ||
2620 | .kernel_ioctl = dvb_frontend_ioctl | 2742 | .kernel_ioctl = dvb_frontend_ioctl |
2621 | }; | 2743 | }; |
2622 | 2744 | ||
diff --git a/drivers/media/dvb-core/dvb_net.c b/drivers/media/dvb-core/dvb_net.c index 4a77cb02dffc..a694fb1ea228 100644 --- a/drivers/media/dvb-core/dvb_net.c +++ b/drivers/media/dvb-core/dvb_net.c | |||
@@ -1461,14 +1461,16 @@ static const struct file_operations dvb_net_fops = { | |||
1461 | .llseek = noop_llseek, | 1461 | .llseek = noop_llseek, |
1462 | }; | 1462 | }; |
1463 | 1463 | ||
1464 | static struct dvb_device dvbdev_net = { | 1464 | static const struct dvb_device dvbdev_net = { |
1465 | .priv = NULL, | 1465 | .priv = NULL, |
1466 | .users = 1, | 1466 | .users = 1, |
1467 | .writers = 1, | 1467 | .writers = 1, |
1468 | #if defined(CONFIG_MEDIA_CONTROLLER_DVB) | ||
1469 | .name = "dvb-net", | ||
1470 | #endif | ||
1468 | .fops = &dvb_net_fops, | 1471 | .fops = &dvb_net_fops, |
1469 | }; | 1472 | }; |
1470 | 1473 | ||
1471 | |||
1472 | void dvb_net_release (struct dvb_net *dvbnet) | 1474 | void dvb_net_release (struct dvb_net *dvbnet) |
1473 | { | 1475 | { |
1474 | int i; | 1476 | int i; |
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 983db75de350..13bb57f0457f 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c | |||
@@ -180,6 +180,93 @@ skip: | |||
180 | return -ENFILE; | 180 | return -ENFILE; |
181 | } | 181 | } |
182 | 182 | ||
183 | static void dvb_register_media_device(struct dvb_device *dvbdev, | ||
184 | int type, int minor) | ||
185 | { | ||
186 | #if defined(CONFIG_MEDIA_CONTROLLER_DVB) | ||
187 | int ret = 0, npads; | ||
188 | |||
189 | if (!dvbdev->adapter->mdev) | ||
190 | return; | ||
191 | |||
192 | dvbdev->entity = kzalloc(sizeof(*dvbdev->entity), GFP_KERNEL); | ||
193 | if (!dvbdev->entity) | ||
194 | return; | ||
195 | |||
196 | dvbdev->entity->info.dev.major = DVB_MAJOR; | ||
197 | dvbdev->entity->info.dev.minor = minor; | ||
198 | dvbdev->entity->name = dvbdev->name; | ||
199 | |||
200 | switch (type) { | ||
201 | case DVB_DEVICE_CA: | ||
202 | case DVB_DEVICE_DEMUX: | ||
203 | case DVB_DEVICE_FRONTEND: | ||
204 | npads = 2; | ||
205 | break; | ||
206 | case DVB_DEVICE_NET: | ||
207 | npads = 0; | ||
208 | break; | ||
209 | default: | ||
210 | npads = 1; | ||
211 | } | ||
212 | |||
213 | if (npads) { | ||
214 | dvbdev->pads = kcalloc(npads, sizeof(*dvbdev->pads), | ||
215 | GFP_KERNEL); | ||
216 | if (!dvbdev->pads) { | ||
217 | kfree(dvbdev->entity); | ||
218 | return; | ||
219 | } | ||
220 | } | ||
221 | |||
222 | switch (type) { | ||
223 | case DVB_DEVICE_FRONTEND: | ||
224 | dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_FE; | ||
225 | dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK; | ||
226 | dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE; | ||
227 | break; | ||
228 | case DVB_DEVICE_DEMUX: | ||
229 | dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_DEMUX; | ||
230 | dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK; | ||
231 | dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE; | ||
232 | break; | ||
233 | case DVB_DEVICE_DVR: | ||
234 | dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_DVR; | ||
235 | dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK; | ||
236 | break; | ||
237 | case DVB_DEVICE_CA: | ||
238 | dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_CA; | ||
239 | dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK; | ||
240 | dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE; | ||
241 | break; | ||
242 | case DVB_DEVICE_NET: | ||
243 | dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_NET; | ||
244 | break; | ||
245 | default: | ||
246 | kfree(dvbdev->entity); | ||
247 | dvbdev->entity = NULL; | ||
248 | return; | ||
249 | } | ||
250 | |||
251 | if (npads) | ||
252 | ret = media_entity_init(dvbdev->entity, npads, dvbdev->pads, 0); | ||
253 | if (!ret) | ||
254 | ret = media_device_register_entity(dvbdev->adapter->mdev, | ||
255 | dvbdev->entity); | ||
256 | if (ret < 0) { | ||
257 | printk(KERN_ERR | ||
258 | "%s: media_device_register_entity failed for %s\n", | ||
259 | __func__, dvbdev->entity->name); | ||
260 | kfree(dvbdev->pads); | ||
261 | kfree(dvbdev->entity); | ||
262 | dvbdev->entity = NULL; | ||
263 | return; | ||
264 | } | ||
265 | |||
266 | printk(KERN_DEBUG "%s: media device '%s' registered.\n", | ||
267 | __func__, dvbdev->entity->name); | ||
268 | #endif | ||
269 | } | ||
183 | 270 | ||
184 | int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, | 271 | int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, |
185 | const struct dvb_device *template, void *priv, int type) | 272 | const struct dvb_device *template, void *priv, int type) |
@@ -258,10 +345,11 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, | |||
258 | __func__, adap->num, dnames[type], id, PTR_ERR(clsdev)); | 345 | __func__, adap->num, dnames[type], id, PTR_ERR(clsdev)); |
259 | return PTR_ERR(clsdev); | 346 | return PTR_ERR(clsdev); |
260 | } | 347 | } |
261 | |||
262 | dprintk(KERN_DEBUG "DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n", | 348 | dprintk(KERN_DEBUG "DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n", |
263 | adap->num, dnames[type], id, minor, minor); | 349 | adap->num, dnames[type], id, minor, minor); |
264 | 350 | ||
351 | dvb_register_media_device(dvbdev, type, minor); | ||
352 | |||
265 | return 0; | 353 | return 0; |
266 | } | 354 | } |
267 | EXPORT_SYMBOL(dvb_register_device); | 355 | EXPORT_SYMBOL(dvb_register_device); |
@@ -278,12 +366,66 @@ void dvb_unregister_device(struct dvb_device *dvbdev) | |||
278 | 366 | ||
279 | device_destroy(dvb_class, MKDEV(DVB_MAJOR, dvbdev->minor)); | 367 | device_destroy(dvb_class, MKDEV(DVB_MAJOR, dvbdev->minor)); |
280 | 368 | ||
369 | #if defined(CONFIG_MEDIA_CONTROLLER_DVB) | ||
370 | if (dvbdev->entity) { | ||
371 | media_device_unregister_entity(dvbdev->entity); | ||
372 | kfree(dvbdev->entity); | ||
373 | kfree(dvbdev->pads); | ||
374 | } | ||
375 | #endif | ||
376 | |||
281 | list_del (&dvbdev->list_head); | 377 | list_del (&dvbdev->list_head); |
282 | kfree (dvbdev->fops); | 378 | kfree (dvbdev->fops); |
283 | kfree (dvbdev); | 379 | kfree (dvbdev); |
284 | } | 380 | } |
285 | EXPORT_SYMBOL(dvb_unregister_device); | 381 | EXPORT_SYMBOL(dvb_unregister_device); |
286 | 382 | ||
383 | |||
384 | #ifdef CONFIG_MEDIA_CONTROLLER_DVB | ||
385 | void dvb_create_media_graph(struct dvb_adapter *adap) | ||
386 | { | ||
387 | struct media_device *mdev = adap->mdev; | ||
388 | struct media_entity *entity, *tuner = NULL, *fe = NULL; | ||
389 | struct media_entity *demux = NULL, *dvr = NULL, *ca = NULL; | ||
390 | |||
391 | if (!mdev) | ||
392 | return; | ||
393 | |||
394 | media_device_for_each_entity(entity, mdev) { | ||
395 | switch (entity->type) { | ||
396 | case MEDIA_ENT_T_V4L2_SUBDEV_TUNER: | ||
397 | tuner = entity; | ||
398 | break; | ||
399 | case MEDIA_ENT_T_DEVNODE_DVB_FE: | ||
400 | fe = entity; | ||
401 | break; | ||
402 | case MEDIA_ENT_T_DEVNODE_DVB_DEMUX: | ||
403 | demux = entity; | ||
404 | break; | ||
405 | case MEDIA_ENT_T_DEVNODE_DVB_DVR: | ||
406 | dvr = entity; | ||
407 | break; | ||
408 | case MEDIA_ENT_T_DEVNODE_DVB_CA: | ||
409 | ca = entity; | ||
410 | break; | ||
411 | } | ||
412 | } | ||
413 | |||
414 | if (tuner && fe) | ||
415 | media_entity_create_link(tuner, 0, fe, 0, 0); | ||
416 | |||
417 | if (fe && demux) | ||
418 | media_entity_create_link(fe, 1, demux, 0, MEDIA_LNK_FL_ENABLED); | ||
419 | |||
420 | if (demux && dvr) | ||
421 | media_entity_create_link(demux, 1, dvr, 0, MEDIA_LNK_FL_ENABLED); | ||
422 | |||
423 | if (demux && ca) | ||
424 | media_entity_create_link(demux, 1, ca, 0, MEDIA_LNK_FL_ENABLED); | ||
425 | } | ||
426 | EXPORT_SYMBOL_GPL(dvb_create_media_graph); | ||
427 | #endif | ||
428 | |||
287 | static int dvbdev_check_free_adapter_num(int num) | 429 | static int dvbdev_check_free_adapter_num(int num) |
288 | { | 430 | { |
289 | struct list_head *entry; | 431 | struct list_head *entry; |
diff --git a/drivers/media/dvb-core/dvbdev.h b/drivers/media/dvb-core/dvbdev.h index f96b28e7fc95..12629b8ecb0c 100644 --- a/drivers/media/dvb-core/dvbdev.h +++ b/drivers/media/dvb-core/dvbdev.h | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/poll.h> | 27 | #include <linux/poll.h> |
28 | #include <linux/fs.h> | 28 | #include <linux/fs.h> |
29 | #include <linux/list.h> | 29 | #include <linux/list.h> |
30 | #include <media/media-device.h> | ||
30 | 31 | ||
31 | #define DVB_MAJOR 212 | 32 | #define DVB_MAJOR 212 |
32 | 33 | ||
@@ -71,6 +72,10 @@ struct dvb_adapter { | |||
71 | int mfe_shared; /* indicates mutually exclusive frontends */ | 72 | int mfe_shared; /* indicates mutually exclusive frontends */ |
72 | struct dvb_device *mfe_dvbdev; /* frontend device in use */ | 73 | struct dvb_device *mfe_dvbdev; /* frontend device in use */ |
73 | struct mutex mfe_lock; /* access lock for thread creation */ | 74 | struct mutex mfe_lock; /* access lock for thread creation */ |
75 | |||
76 | #if defined(CONFIG_MEDIA_CONTROLLER_DVB) | ||
77 | struct media_device *mdev; | ||
78 | #endif | ||
74 | }; | 79 | }; |
75 | 80 | ||
76 | 81 | ||
@@ -92,6 +97,15 @@ struct dvb_device { | |||
92 | /* don't really need those !? -- FIXME: use video_usercopy */ | 97 | /* don't really need those !? -- FIXME: use video_usercopy */ |
93 | int (*kernel_ioctl)(struct file *file, unsigned int cmd, void *arg); | 98 | int (*kernel_ioctl)(struct file *file, unsigned int cmd, void *arg); |
94 | 99 | ||
100 | /* Needed for media controller register/unregister */ | ||
101 | #if defined(CONFIG_MEDIA_CONTROLLER_DVB) | ||
102 | const char *name; | ||
103 | |||
104 | /* Allocated and filled inside dvbdev.c */ | ||
105 | struct media_entity *entity; | ||
106 | struct media_pad *pads; | ||
107 | #endif | ||
108 | |||
95 | void *priv; | 109 | void *priv; |
96 | }; | 110 | }; |
97 | 111 | ||
@@ -109,6 +123,19 @@ extern int dvb_register_device (struct dvb_adapter *adap, | |||
109 | 123 | ||
110 | extern void dvb_unregister_device (struct dvb_device *dvbdev); | 124 | extern void dvb_unregister_device (struct dvb_device *dvbdev); |
111 | 125 | ||
126 | #ifdef CONFIG_MEDIA_CONTROLLER_DVB | ||
127 | void dvb_create_media_graph(struct dvb_adapter *adap); | ||
128 | static inline void dvb_register_media_controller(struct dvb_adapter *adap, | ||
129 | struct media_device *mdev) | ||
130 | { | ||
131 | adap->mdev = mdev; | ||
132 | } | ||
133 | |||
134 | #else | ||
135 | static inline void dvb_create_media_graph(struct dvb_adapter *adap) {} | ||
136 | #define dvb_register_media_controller(a, b) {} | ||
137 | #endif | ||
138 | |||
112 | extern int dvb_generic_open (struct inode *inode, struct file *file); | 139 | extern int dvb_generic_open (struct inode *inode, struct file *file); |
113 | extern int dvb_generic_release (struct inode *inode, struct file *file); | 140 | extern int dvb_generic_release (struct inode *inode, struct file *file); |
114 | extern long dvb_generic_ioctl (struct file *file, | 141 | extern long dvb_generic_ioctl (struct file *file, |
diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig index bb76727d924e..97c151d5b2e1 100644 --- a/drivers/media/dvb-frontends/Kconfig +++ b/drivers/media/dvb-frontends/Kconfig | |||
@@ -577,6 +577,14 @@ config DVB_LGDT3305 | |||
577 | An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want | 577 | An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want |
578 | to support this frontend. | 578 | to support this frontend. |
579 | 579 | ||
580 | config DVB_LGDT3306A | ||
581 | tristate "LG Electronics LGDT3306A based" | ||
582 | depends on DVB_CORE && I2C | ||
583 | default m if !MEDIA_SUBDRV_AUTOSELECT | ||
584 | help | ||
585 | An ATSC 8VSB and QAM-B 64/256 demodulator module. Say Y when you want | ||
586 | to support this frontend. | ||
587 | |||
580 | config DVB_LG2160 | 588 | config DVB_LG2160 |
581 | tristate "LG Electronics LG216x based" | 589 | tristate "LG Electronics LG216x based" |
582 | depends on DVB_CORE && I2C | 590 | depends on DVB_CORE && I2C |
diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile index ba59df63d050..23d399bec804 100644 --- a/drivers/media/dvb-frontends/Makefile +++ b/drivers/media/dvb-frontends/Makefile | |||
@@ -54,6 +54,7 @@ obj-$(CONFIG_DVB_BCM3510) += bcm3510.o | |||
54 | obj-$(CONFIG_DVB_S5H1420) += s5h1420.o | 54 | obj-$(CONFIG_DVB_S5H1420) += s5h1420.o |
55 | obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o | 55 | obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o |
56 | obj-$(CONFIG_DVB_LGDT3305) += lgdt3305.o | 56 | obj-$(CONFIG_DVB_LGDT3305) += lgdt3305.o |
57 | obj-$(CONFIG_DVB_LGDT3306A) += lgdt3306a.o | ||
57 | obj-$(CONFIG_DVB_LG2160) += lg2160.o | 58 | obj-$(CONFIG_DVB_LG2160) += lg2160.o |
58 | obj-$(CONFIG_DVB_CX24123) += cx24123.o | 59 | obj-$(CONFIG_DVB_CX24123) += cx24123.o |
59 | obj-$(CONFIG_DVB_LNBP21) += lnbp21.o | 60 | obj-$(CONFIG_DVB_LNBP21) += lnbp21.o |
diff --git a/drivers/media/dvb-frontends/a8293.h b/drivers/media/dvb-frontends/a8293.h index b6ef6427cfa5..5f0411939ffc 100644 --- a/drivers/media/dvb-frontends/a8293.h +++ b/drivers/media/dvb-frontends/a8293.h | |||
@@ -27,7 +27,7 @@ struct a8293_config { | |||
27 | u8 i2c_addr; | 27 | u8 i2c_addr; |
28 | }; | 28 | }; |
29 | 29 | ||
30 | #if IS_ENABLED(CONFIG_DVB_A8293) | 30 | #if IS_REACHABLE(CONFIG_DVB_A8293) |
31 | extern struct dvb_frontend *a8293_attach(struct dvb_frontend *fe, | 31 | extern struct dvb_frontend *a8293_attach(struct dvb_frontend *fe, |
32 | struct i2c_adapter *i2c, const struct a8293_config *cfg); | 32 | struct i2c_adapter *i2c, const struct a8293_config *cfg); |
33 | #else | 33 | #else |
diff --git a/drivers/media/dvb-frontends/af9013.h b/drivers/media/dvb-frontends/af9013.h index 09273b2cd310..1dcc936e1661 100644 --- a/drivers/media/dvb-frontends/af9013.h +++ b/drivers/media/dvb-frontends/af9013.h | |||
@@ -103,7 +103,7 @@ struct af9013_config { | |||
103 | u8 gpio[4]; | 103 | u8 gpio[4]; |
104 | }; | 104 | }; |
105 | 105 | ||
106 | #if IS_ENABLED(CONFIG_DVB_AF9013) | 106 | #if IS_REACHABLE(CONFIG_DVB_AF9013) |
107 | extern struct dvb_frontend *af9013_attach(const struct af9013_config *config, | 107 | extern struct dvb_frontend *af9013_attach(const struct af9013_config *config, |
108 | struct i2c_adapter *i2c); | 108 | struct i2c_adapter *i2c); |
109 | #else | 109 | #else |
diff --git a/drivers/media/dvb-frontends/atbm8830.h b/drivers/media/dvb-frontends/atbm8830.h index 8e0ac98f8d08..5446d13fdfe8 100644 --- a/drivers/media/dvb-frontends/atbm8830.h +++ b/drivers/media/dvb-frontends/atbm8830.h | |||
@@ -61,7 +61,7 @@ struct atbm8830_config { | |||
61 | u8 agc_hold_loop; | 61 | u8 agc_hold_loop; |
62 | }; | 62 | }; |
63 | 63 | ||
64 | #if IS_ENABLED(CONFIG_DVB_ATBM8830) | 64 | #if IS_REACHABLE(CONFIG_DVB_ATBM8830) |
65 | extern struct dvb_frontend *atbm8830_attach(const struct atbm8830_config *config, | 65 | extern struct dvb_frontend *atbm8830_attach(const struct atbm8830_config *config, |
66 | struct i2c_adapter *i2c); | 66 | struct i2c_adapter *i2c); |
67 | #else | 67 | #else |
diff --git a/drivers/media/dvb-frontends/au8522.h b/drivers/media/dvb-frontends/au8522.h index 612251958855..dde61582c158 100644 --- a/drivers/media/dvb-frontends/au8522.h +++ b/drivers/media/dvb-frontends/au8522.h | |||
@@ -61,7 +61,7 @@ struct au8522_config { | |||
61 | enum au8522_if_freq qam_if; | 61 | enum au8522_if_freq qam_if; |
62 | }; | 62 | }; |
63 | 63 | ||
64 | #if IS_ENABLED(CONFIG_DVB_AU8522_DTV) | 64 | #if IS_REACHABLE(CONFIG_DVB_AU8522_DTV) |
65 | extern struct dvb_frontend *au8522_attach(const struct au8522_config *config, | 65 | extern struct dvb_frontend *au8522_attach(const struct au8522_config *config, |
66 | struct i2c_adapter *i2c); | 66 | struct i2c_adapter *i2c); |
67 | #else | 67 | #else |
diff --git a/drivers/media/dvb-frontends/bcm3510.h b/drivers/media/dvb-frontends/bcm3510.h index 5bd56b1623bf..ff66492fb940 100644 --- a/drivers/media/dvb-frontends/bcm3510.h +++ b/drivers/media/dvb-frontends/bcm3510.h | |||
@@ -34,7 +34,7 @@ struct bcm3510_config | |||
34 | int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); | 34 | int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); |
35 | }; | 35 | }; |
36 | 36 | ||
37 | #if IS_ENABLED(CONFIG_DVB_BCM3510) | 37 | #if IS_REACHABLE(CONFIG_DVB_BCM3510) |
38 | extern struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config, | 38 | extern struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config, |
39 | struct i2c_adapter* i2c); | 39 | struct i2c_adapter* i2c); |
40 | #else | 40 | #else |
diff --git a/drivers/media/dvb-frontends/cx22700.h b/drivers/media/dvb-frontends/cx22700.h index 382a7b1f3618..e0a764868e6f 100644 --- a/drivers/media/dvb-frontends/cx22700.h +++ b/drivers/media/dvb-frontends/cx22700.h | |||
@@ -31,7 +31,7 @@ struct cx22700_config | |||
31 | u8 demod_address; | 31 | u8 demod_address; |
32 | }; | 32 | }; |
33 | 33 | ||
34 | #if IS_ENABLED(CONFIG_DVB_CX22700) | 34 | #if IS_REACHABLE(CONFIG_DVB_CX22700) |
35 | extern struct dvb_frontend* cx22700_attach(const struct cx22700_config* config, | 35 | extern struct dvb_frontend* cx22700_attach(const struct cx22700_config* config, |
36 | struct i2c_adapter* i2c); | 36 | struct i2c_adapter* i2c); |
37 | #else | 37 | #else |
diff --git a/drivers/media/dvb-frontends/cx22702.h b/drivers/media/dvb-frontends/cx22702.h index 0b1a6c2f9d5f..68b69a7660d2 100644 --- a/drivers/media/dvb-frontends/cx22702.h +++ b/drivers/media/dvb-frontends/cx22702.h | |||
@@ -41,7 +41,7 @@ struct cx22702_config { | |||
41 | u8 output_mode; | 41 | u8 output_mode; |
42 | }; | 42 | }; |
43 | 43 | ||
44 | #if IS_ENABLED(CONFIG_DVB_CX22702) | 44 | #if IS_REACHABLE(CONFIG_DVB_CX22702) |
45 | extern struct dvb_frontend *cx22702_attach( | 45 | extern struct dvb_frontend *cx22702_attach( |
46 | const struct cx22702_config *config, | 46 | const struct cx22702_config *config, |
47 | struct i2c_adapter *i2c); | 47 | struct i2c_adapter *i2c); |
diff --git a/drivers/media/dvb-frontends/cx24110.h b/drivers/media/dvb-frontends/cx24110.h index 527aff1f2723..d5453ed20b28 100644 --- a/drivers/media/dvb-frontends/cx24110.h +++ b/drivers/media/dvb-frontends/cx24110.h | |||
@@ -46,7 +46,7 @@ static inline int cx24110_pll_write(struct dvb_frontend *fe, u32 val) | |||
46 | return 0; | 46 | return 0; |
47 | } | 47 | } |
48 | 48 | ||
49 | #if IS_ENABLED(CONFIG_DVB_CX24110) | 49 | #if IS_REACHABLE(CONFIG_DVB_CX24110) |
50 | extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, | 50 | extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, |
51 | struct i2c_adapter* i2c); | 51 | struct i2c_adapter* i2c); |
52 | #else | 52 | #else |
diff --git a/drivers/media/dvb-frontends/cx24113.h b/drivers/media/dvb-frontends/cx24113.h index 782711ba1a32..962919b9b6e6 100644 --- a/drivers/media/dvb-frontends/cx24113.h +++ b/drivers/media/dvb-frontends/cx24113.h | |||
@@ -32,7 +32,7 @@ struct cx24113_config { | |||
32 | u32 xtal_khz; | 32 | u32 xtal_khz; |
33 | }; | 33 | }; |
34 | 34 | ||
35 | #if IS_ENABLED(CONFIG_DVB_TUNER_CX24113) | 35 | #if IS_REACHABLE(CONFIG_DVB_TUNER_CX24113) |
36 | extern struct dvb_frontend *cx24113_attach(struct dvb_frontend *, | 36 | extern struct dvb_frontend *cx24113_attach(struct dvb_frontend *, |
37 | const struct cx24113_config *config, struct i2c_adapter *i2c); | 37 | const struct cx24113_config *config, struct i2c_adapter *i2c); |
38 | 38 | ||
diff --git a/drivers/media/dvb-frontends/cx24116.h b/drivers/media/dvb-frontends/cx24116.h index 2ec84fae3f9f..f6dbabc1d62b 100644 --- a/drivers/media/dvb-frontends/cx24116.h +++ b/drivers/media/dvb-frontends/cx24116.h | |||
@@ -41,7 +41,7 @@ struct cx24116_config { | |||
41 | u16 i2c_wr_max; | 41 | u16 i2c_wr_max; |
42 | }; | 42 | }; |
43 | 43 | ||
44 | #if IS_ENABLED(CONFIG_DVB_CX24116) | 44 | #if IS_REACHABLE(CONFIG_DVB_CX24116) |
45 | extern struct dvb_frontend *cx24116_attach( | 45 | extern struct dvb_frontend *cx24116_attach( |
46 | const struct cx24116_config *config, | 46 | const struct cx24116_config *config, |
47 | struct i2c_adapter *i2c); | 47 | struct i2c_adapter *i2c); |
diff --git a/drivers/media/dvb-frontends/cx24117.h b/drivers/media/dvb-frontends/cx24117.h index 4e59e9574fa7..1648ab432168 100644 --- a/drivers/media/dvb-frontends/cx24117.h +++ b/drivers/media/dvb-frontends/cx24117.h | |||
@@ -30,7 +30,7 @@ struct cx24117_config { | |||
30 | u8 demod_address; | 30 | u8 demod_address; |
31 | }; | 31 | }; |
32 | 32 | ||
33 | #if IS_ENABLED(CONFIG_DVB_CX24117) | 33 | #if IS_REACHABLE(CONFIG_DVB_CX24117) |
34 | extern struct dvb_frontend *cx24117_attach( | 34 | extern struct dvb_frontend *cx24117_attach( |
35 | const struct cx24117_config *config, | 35 | const struct cx24117_config *config, |
36 | struct i2c_adapter *i2c); | 36 | struct i2c_adapter *i2c); |
diff --git a/drivers/media/dvb-frontends/cx24123.h b/drivers/media/dvb-frontends/cx24123.h index 102e70d17c43..758aee5a072f 100644 --- a/drivers/media/dvb-frontends/cx24123.h +++ b/drivers/media/dvb-frontends/cx24123.h | |||
@@ -39,7 +39,7 @@ struct cx24123_config { | |||
39 | void (*agc_callback) (struct dvb_frontend *); | 39 | void (*agc_callback) (struct dvb_frontend *); |
40 | }; | 40 | }; |
41 | 41 | ||
42 | #if IS_ENABLED(CONFIG_DVB_CX24123) | 42 | #if IS_REACHABLE(CONFIG_DVB_CX24123) |
43 | extern struct dvb_frontend *cx24123_attach(const struct cx24123_config *config, | 43 | extern struct dvb_frontend *cx24123_attach(const struct cx24123_config *config, |
44 | struct i2c_adapter *i2c); | 44 | struct i2c_adapter *i2c); |
45 | extern struct i2c_adapter *cx24123_get_tuner_i2c_adapter(struct dvb_frontend *); | 45 | extern struct i2c_adapter *cx24123_get_tuner_i2c_adapter(struct dvb_frontend *); |
diff --git a/drivers/media/dvb-frontends/cxd2820r.h b/drivers/media/dvb-frontends/cxd2820r.h index 6095dbcf7850..56d42760263d 100644 --- a/drivers/media/dvb-frontends/cxd2820r.h +++ b/drivers/media/dvb-frontends/cxd2820r.h | |||
@@ -72,7 +72,7 @@ struct cxd2820r_config { | |||
72 | }; | 72 | }; |
73 | 73 | ||
74 | 74 | ||
75 | #if IS_ENABLED(CONFIG_DVB_CXD2820R) | 75 | #if IS_REACHABLE(CONFIG_DVB_CXD2820R) |
76 | extern struct dvb_frontend *cxd2820r_attach( | 76 | extern struct dvb_frontend *cxd2820r_attach( |
77 | const struct cxd2820r_config *config, | 77 | const struct cxd2820r_config *config, |
78 | struct i2c_adapter *i2c, | 78 | struct i2c_adapter *i2c, |
diff --git a/drivers/media/dvb-frontends/dib0070.h b/drivers/media/dvb-frontends/dib0070.h index 0c6befcc9143..6c0b6672b1d9 100644 --- a/drivers/media/dvb-frontends/dib0070.h +++ b/drivers/media/dvb-frontends/dib0070.h | |||
@@ -48,7 +48,7 @@ struct dib0070_config { | |||
48 | u8 vga_filter; | 48 | u8 vga_filter; |
49 | }; | 49 | }; |
50 | 50 | ||
51 | #if IS_ENABLED(CONFIG_DVB_TUNER_DIB0070) | 51 | #if IS_REACHABLE(CONFIG_DVB_TUNER_DIB0070) |
52 | extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg); | 52 | extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg); |
53 | extern u16 dib0070_wbd_offset(struct dvb_frontend *); | 53 | extern u16 dib0070_wbd_offset(struct dvb_frontend *); |
54 | extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, u8 open); | 54 | extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, u8 open); |
diff --git a/drivers/media/dvb-frontends/dib0090.h b/drivers/media/dvb-frontends/dib0090.h index 6a090954fa10..ad74bc823f08 100644 --- a/drivers/media/dvb-frontends/dib0090.h +++ b/drivers/media/dvb-frontends/dib0090.h | |||
@@ -75,7 +75,7 @@ struct dib0090_config { | |||
75 | u8 force_crystal_mode; | 75 | u8 force_crystal_mode; |
76 | }; | 76 | }; |
77 | 77 | ||
78 | #if IS_ENABLED(CONFIG_DVB_TUNER_DIB0090) | 78 | #if IS_REACHABLE(CONFIG_DVB_TUNER_DIB0090) |
79 | extern struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config); | 79 | extern struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config); |
80 | extern struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config); | 80 | extern struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config); |
81 | extern void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast); | 81 | extern void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast); |
diff --git a/drivers/media/dvb-frontends/dib3000.h b/drivers/media/dvb-frontends/dib3000.h index 9b6c3bbc983a..6ae9899b5b45 100644 --- a/drivers/media/dvb-frontends/dib3000.h +++ b/drivers/media/dvb-frontends/dib3000.h | |||
@@ -41,7 +41,7 @@ struct dib_fe_xfer_ops | |||
41 | int (*tuner_pass_ctrl)(struct dvb_frontend *fe, int onoff, u8 pll_ctrl); | 41 | int (*tuner_pass_ctrl)(struct dvb_frontend *fe, int onoff, u8 pll_ctrl); |
42 | }; | 42 | }; |
43 | 43 | ||
44 | #if IS_ENABLED(CONFIG_DVB_DIB3000MB) | 44 | #if IS_REACHABLE(CONFIG_DVB_DIB3000MB) |
45 | extern struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config, | 45 | extern struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config, |
46 | struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops); | 46 | struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops); |
47 | #else | 47 | #else |
diff --git a/drivers/media/dvb-frontends/dib3000mc.h b/drivers/media/dvb-frontends/dib3000mc.h index 129d1425516a..74816f793611 100644 --- a/drivers/media/dvb-frontends/dib3000mc.h +++ b/drivers/media/dvb-frontends/dib3000mc.h | |||
@@ -41,7 +41,7 @@ struct dib3000mc_config { | |||
41 | #define DEFAULT_DIB3000MC_I2C_ADDRESS 16 | 41 | #define DEFAULT_DIB3000MC_I2C_ADDRESS 16 |
42 | #define DEFAULT_DIB3000P_I2C_ADDRESS 24 | 42 | #define DEFAULT_DIB3000P_I2C_ADDRESS 24 |
43 | 43 | ||
44 | #if IS_ENABLED(CONFIG_DVB_DIB3000MC) | 44 | #if IS_REACHABLE(CONFIG_DVB_DIB3000MC) |
45 | extern struct dvb_frontend *dib3000mc_attach(struct i2c_adapter *i2c_adap, | 45 | extern struct dvb_frontend *dib3000mc_attach(struct i2c_adapter *i2c_adap, |
46 | u8 i2c_addr, | 46 | u8 i2c_addr, |
47 | struct dib3000mc_config *cfg); | 47 | struct dib3000mc_config *cfg); |
diff --git a/drivers/media/dvb-frontends/dib7000m.h b/drivers/media/dvb-frontends/dib7000m.h index b585413f9a29..6468c278cc4d 100644 --- a/drivers/media/dvb-frontends/dib7000m.h +++ b/drivers/media/dvb-frontends/dib7000m.h | |||
@@ -40,7 +40,7 @@ struct dib7000m_config { | |||
40 | 40 | ||
41 | #define DEFAULT_DIB7000M_I2C_ADDRESS 18 | 41 | #define DEFAULT_DIB7000M_I2C_ADDRESS 18 |
42 | 42 | ||
43 | #if IS_ENABLED(CONFIG_DVB_DIB7000M) | 43 | #if IS_REACHABLE(CONFIG_DVB_DIB7000M) |
44 | extern struct dvb_frontend *dib7000m_attach(struct i2c_adapter *i2c_adap, | 44 | extern struct dvb_frontend *dib7000m_attach(struct i2c_adapter *i2c_adap, |
45 | u8 i2c_addr, | 45 | u8 i2c_addr, |
46 | struct dib7000m_config *cfg); | 46 | struct dib7000m_config *cfg); |
diff --git a/drivers/media/dvb-frontends/dib7000p.h b/drivers/media/dvb-frontends/dib7000p.h index 1fea0e972654..baa278928cf3 100644 --- a/drivers/media/dvb-frontends/dib7000p.h +++ b/drivers/media/dvb-frontends/dib7000p.h | |||
@@ -66,7 +66,7 @@ struct dib7000p_ops { | |||
66 | struct dvb_frontend *(*init)(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg); | 66 | struct dvb_frontend *(*init)(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg); |
67 | }; | 67 | }; |
68 | 68 | ||
69 | #if IS_ENABLED(CONFIG_DVB_DIB7000P) | 69 | #if IS_REACHABLE(CONFIG_DVB_DIB7000P) |
70 | void *dib7000p_attach(struct dib7000p_ops *ops); | 70 | void *dib7000p_attach(struct dib7000p_ops *ops); |
71 | #else | 71 | #else |
72 | static inline void *dib7000p_attach(struct dib7000p_ops *ops) | 72 | static inline void *dib7000p_attach(struct dib7000p_ops *ops) |
diff --git a/drivers/media/dvb-frontends/dib8000.h b/drivers/media/dvb-frontends/dib8000.h index 84cc10383dcd..780c37bdcb72 100644 --- a/drivers/media/dvb-frontends/dib8000.h +++ b/drivers/media/dvb-frontends/dib8000.h | |||
@@ -63,7 +63,7 @@ struct dib8000_ops { | |||
63 | struct dvb_frontend *(*init)(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg); | 63 | struct dvb_frontend *(*init)(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg); |
64 | }; | 64 | }; |
65 | 65 | ||
66 | #if IS_ENABLED(CONFIG_DVB_DIB8000) | 66 | #if IS_REACHABLE(CONFIG_DVB_DIB8000) |
67 | void *dib8000_attach(struct dib8000_ops *ops); | 67 | void *dib8000_attach(struct dib8000_ops *ops); |
68 | #else | 68 | #else |
69 | static inline int dib8000_attach(struct dib8000_ops *ops) | 69 | static inline int dib8000_attach(struct dib8000_ops *ops) |
diff --git a/drivers/media/dvb-frontends/dib9000.h b/drivers/media/dvb-frontends/dib9000.h index f3639f045ff0..b10a70aa7c9f 100644 --- a/drivers/media/dvb-frontends/dib9000.h +++ b/drivers/media/dvb-frontends/dib9000.h | |||
@@ -27,7 +27,7 @@ struct dib9000_config { | |||
27 | 27 | ||
28 | #define DEFAULT_DIB9000_I2C_ADDRESS 18 | 28 | #define DEFAULT_DIB9000_I2C_ADDRESS 18 |
29 | 29 | ||
30 | #if IS_ENABLED(CONFIG_DVB_DIB9000) | 30 | #if IS_REACHABLE(CONFIG_DVB_DIB9000) |
31 | extern struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, const struct dib9000_config *cfg); | 31 | extern struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, const struct dib9000_config *cfg); |
32 | extern int dib9000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr); | 32 | extern int dib9000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr); |
33 | extern struct i2c_adapter *dib9000_get_tuner_interface(struct dvb_frontend *fe); | 33 | extern struct i2c_adapter *dib9000_get_tuner_interface(struct dvb_frontend *fe); |
diff --git a/drivers/media/dvb-frontends/drx39xyj/drx39xxj.h b/drivers/media/dvb-frontends/drx39xyj/drx39xxj.h index cfd0b96b6939..8188062953af 100644 --- a/drivers/media/dvb-frontends/drx39xyj/drx39xxj.h +++ b/drivers/media/dvb-frontends/drx39xyj/drx39xxj.h | |||
@@ -34,7 +34,7 @@ struct drx39xxj_state { | |||
34 | const struct firmware *fw; | 34 | const struct firmware *fw; |
35 | }; | 35 | }; |
36 | 36 | ||
37 | #if IS_ENABLED(CONFIG_DVB_DRX39XYJ) | 37 | #if IS_REACHABLE(CONFIG_DVB_DRX39XYJ) |
38 | struct dvb_frontend *drx39xxj_attach(struct i2c_adapter *i2c); | 38 | struct dvb_frontend *drx39xxj_attach(struct i2c_adapter *i2c); |
39 | #else | 39 | #else |
40 | static inline struct dvb_frontend *drx39xxj_attach(struct i2c_adapter *i2c) { | 40 | static inline struct dvb_frontend *drx39xxj_attach(struct i2c_adapter *i2c) { |
diff --git a/drivers/media/dvb-frontends/drxd.h b/drivers/media/dvb-frontends/drxd.h index d998e4d5a7fc..a47c22d6667e 100644 --- a/drivers/media/dvb-frontends/drxd.h +++ b/drivers/media/dvb-frontends/drxd.h | |||
@@ -52,7 +52,7 @@ struct drxd_config { | |||
52 | s16(*osc_deviation) (void *priv, s16 dev, int flag); | 52 | s16(*osc_deviation) (void *priv, s16 dev, int flag); |
53 | }; | 53 | }; |
54 | 54 | ||
55 | #if IS_ENABLED(CONFIG_DVB_DRXD) | 55 | #if IS_REACHABLE(CONFIG_DVB_DRXD) |
56 | extern | 56 | extern |
57 | struct dvb_frontend *drxd_attach(const struct drxd_config *config, | 57 | struct dvb_frontend *drxd_attach(const struct drxd_config *config, |
58 | void *priv, struct i2c_adapter *i2c, | 58 | void *priv, struct i2c_adapter *i2c, |
diff --git a/drivers/media/dvb-frontends/drxk.h b/drivers/media/dvb-frontends/drxk.h index f6cb34660327..8f0b9eec528f 100644 --- a/drivers/media/dvb-frontends/drxk.h +++ b/drivers/media/dvb-frontends/drxk.h | |||
@@ -51,7 +51,7 @@ struct drxk_config { | |||
51 | int qam_demod_parameter_count; | 51 | int qam_demod_parameter_count; |
52 | }; | 52 | }; |
53 | 53 | ||
54 | #if IS_ENABLED(CONFIG_DVB_DRXK) | 54 | #if IS_REACHABLE(CONFIG_DVB_DRXK) |
55 | extern struct dvb_frontend *drxk_attach(const struct drxk_config *config, | 55 | extern struct dvb_frontend *drxk_attach(const struct drxk_config *config, |
56 | struct i2c_adapter *i2c); | 56 | struct i2c_adapter *i2c); |
57 | #else | 57 | #else |
diff --git a/drivers/media/dvb-frontends/ds3000.h b/drivers/media/dvb-frontends/ds3000.h index f9c21fb7af13..153169da9017 100644 --- a/drivers/media/dvb-frontends/ds3000.h +++ b/drivers/media/dvb-frontends/ds3000.h | |||
@@ -35,7 +35,7 @@ struct ds3000_config { | |||
35 | void (*set_lock_led)(struct dvb_frontend *fe, int offon); | 35 | void (*set_lock_led)(struct dvb_frontend *fe, int offon); |
36 | }; | 36 | }; |
37 | 37 | ||
38 | #if IS_ENABLED(CONFIG_DVB_DS3000) | 38 | #if IS_REACHABLE(CONFIG_DVB_DS3000) |
39 | extern struct dvb_frontend *ds3000_attach(const struct ds3000_config *config, | 39 | extern struct dvb_frontend *ds3000_attach(const struct ds3000_config *config, |
40 | struct i2c_adapter *i2c); | 40 | struct i2c_adapter *i2c); |
41 | #else | 41 | #else |
diff --git a/drivers/media/dvb-frontends/dvb-pll.h b/drivers/media/dvb-frontends/dvb-pll.h index f4b5a0601c3a..bf9602a88b6c 100644 --- a/drivers/media/dvb-frontends/dvb-pll.h +++ b/drivers/media/dvb-frontends/dvb-pll.h | |||
@@ -38,7 +38,7 @@ | |||
38 | * @param pll_desc_id dvb_pll_desc to use. | 38 | * @param pll_desc_id dvb_pll_desc to use. |
39 | * @return Frontend pointer on success, NULL on failure | 39 | * @return Frontend pointer on success, NULL on failure |
40 | */ | 40 | */ |
41 | #if IS_ENABLED(CONFIG_DVB_PLL) | 41 | #if IS_REACHABLE(CONFIG_DVB_PLL) |
42 | extern struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, | 42 | extern struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, |
43 | int pll_addr, | 43 | int pll_addr, |
44 | struct i2c_adapter *i2c, | 44 | struct i2c_adapter *i2c, |
diff --git a/drivers/media/dvb-frontends/dvb_dummy_fe.h b/drivers/media/dvb-frontends/dvb_dummy_fe.h index 0cbf96105631..15e4ceab869a 100644 --- a/drivers/media/dvb-frontends/dvb_dummy_fe.h +++ b/drivers/media/dvb-frontends/dvb_dummy_fe.h | |||
@@ -26,7 +26,7 @@ | |||
26 | #include <linux/dvb/frontend.h> | 26 | #include <linux/dvb/frontend.h> |
27 | #include "dvb_frontend.h" | 27 | #include "dvb_frontend.h" |
28 | 28 | ||
29 | #if IS_ENABLED(CONFIG_DVB_DUMMY_FE) | 29 | #if IS_REACHABLE(CONFIG_DVB_DUMMY_FE) |
30 | extern struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void); | 30 | extern struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void); |
31 | extern struct dvb_frontend* dvb_dummy_fe_qpsk_attach(void); | 31 | extern struct dvb_frontend* dvb_dummy_fe_qpsk_attach(void); |
32 | extern struct dvb_frontend* dvb_dummy_fe_qam_attach(void); | 32 | extern struct dvb_frontend* dvb_dummy_fe_qam_attach(void); |
diff --git a/drivers/media/dvb-frontends/ec100.h b/drivers/media/dvb-frontends/ec100.h index 37558403068d..9544bab5cd1d 100644 --- a/drivers/media/dvb-frontends/ec100.h +++ b/drivers/media/dvb-frontends/ec100.h | |||
@@ -31,7 +31,7 @@ struct ec100_config { | |||
31 | }; | 31 | }; |
32 | 32 | ||
33 | 33 | ||
34 | #if IS_ENABLED(CONFIG_DVB_EC100) | 34 | #if IS_REACHABLE(CONFIG_DVB_EC100) |
35 | extern struct dvb_frontend *ec100_attach(const struct ec100_config *config, | 35 | extern struct dvb_frontend *ec100_attach(const struct ec100_config *config, |
36 | struct i2c_adapter *i2c); | 36 | struct i2c_adapter *i2c); |
37 | #else | 37 | #else |
diff --git a/drivers/media/dvb-frontends/hd29l2.h b/drivers/media/dvb-frontends/hd29l2.h index 05cd13028a91..48e9ab74c883 100644 --- a/drivers/media/dvb-frontends/hd29l2.h +++ b/drivers/media/dvb-frontends/hd29l2.h | |||
@@ -51,7 +51,7 @@ struct hd29l2_config { | |||
51 | }; | 51 | }; |
52 | 52 | ||
53 | 53 | ||
54 | #if IS_ENABLED(CONFIG_DVB_HD29L2) | 54 | #if IS_REACHABLE(CONFIG_DVB_HD29L2) |
55 | extern struct dvb_frontend *hd29l2_attach(const struct hd29l2_config *config, | 55 | extern struct dvb_frontend *hd29l2_attach(const struct hd29l2_config *config, |
56 | struct i2c_adapter *i2c); | 56 | struct i2c_adapter *i2c); |
57 | #else | 57 | #else |
diff --git a/drivers/media/dvb-frontends/isl6405.h b/drivers/media/dvb-frontends/isl6405.h index 8abb70c26fd9..3c148b830bd1 100644 --- a/drivers/media/dvb-frontends/isl6405.h +++ b/drivers/media/dvb-frontends/isl6405.h | |||
@@ -55,7 +55,7 @@ | |||
55 | #define ISL6405_ENT2 0x20 | 55 | #define ISL6405_ENT2 0x20 |
56 | #define ISL6405_ISEL2 0x40 | 56 | #define ISL6405_ISEL2 0x40 |
57 | 57 | ||
58 | #if IS_ENABLED(CONFIG_DVB_ISL6405) | 58 | #if IS_REACHABLE(CONFIG_DVB_ISL6405) |
59 | /* override_set and override_clear control which system register bits (above) | 59 | /* override_set and override_clear control which system register bits (above) |
60 | * to always set & clear | 60 | * to always set & clear |
61 | */ | 61 | */ |
diff --git a/drivers/media/dvb-frontends/isl6421.h b/drivers/media/dvb-frontends/isl6421.h index 630e7f8a150e..3273597833fd 100644 --- a/drivers/media/dvb-frontends/isl6421.h +++ b/drivers/media/dvb-frontends/isl6421.h | |||
@@ -39,7 +39,7 @@ | |||
39 | #define ISL6421_ISEL1 0x20 | 39 | #define ISL6421_ISEL1 0x20 |
40 | #define ISL6421_DCL 0x40 | 40 | #define ISL6421_DCL 0x40 |
41 | 41 | ||
42 | #if IS_ENABLED(CONFIG_DVB_ISL6421) | 42 | #if IS_REACHABLE(CONFIG_DVB_ISL6421) |
43 | /* override_set and override_clear control which system register bits (above) to always set & clear */ | 43 | /* override_set and override_clear control which system register bits (above) to always set & clear */ |
44 | extern struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr, | 44 | extern struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr, |
45 | u8 override_set, u8 override_clear, bool override_tone); | 45 | u8 override_set, u8 override_clear, bool override_tone); |
diff --git a/drivers/media/dvb-frontends/isl6423.h b/drivers/media/dvb-frontends/isl6423.h index 80dfd9cc4f41..a64df0ee256b 100644 --- a/drivers/media/dvb-frontends/isl6423.h +++ b/drivers/media/dvb-frontends/isl6423.h | |||
@@ -42,7 +42,7 @@ struct isl6423_config { | |||
42 | u8 mod_extern; | 42 | u8 mod_extern; |
43 | }; | 43 | }; |
44 | 44 | ||
45 | #if IS_ENABLED(CONFIG_DVB_ISL6423) | 45 | #if IS_REACHABLE(CONFIG_DVB_ISL6423) |
46 | 46 | ||
47 | 47 | ||
48 | extern struct dvb_frontend *isl6423_attach(struct dvb_frontend *fe, | 48 | extern struct dvb_frontend *isl6423_attach(struct dvb_frontend *fe, |
diff --git a/drivers/media/dvb-frontends/itd1000.h b/drivers/media/dvb-frontends/itd1000.h index edae0902f4fd..a691bb6f26de 100644 --- a/drivers/media/dvb-frontends/itd1000.h +++ b/drivers/media/dvb-frontends/itd1000.h | |||
@@ -29,7 +29,7 @@ struct itd1000_config { | |||
29 | u8 i2c_address; | 29 | u8 i2c_address; |
30 | }; | 30 | }; |
31 | 31 | ||
32 | #if IS_ENABLED(CONFIG_DVB_TUNER_ITD1000) | 32 | #if IS_REACHABLE(CONFIG_DVB_TUNER_ITD1000) |
33 | extern struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct itd1000_config *cfg); | 33 | extern struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct itd1000_config *cfg); |
34 | #else | 34 | #else |
35 | static inline struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct itd1000_config *cfg) | 35 | static inline struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct itd1000_config *cfg) |
diff --git a/drivers/media/dvb-frontends/ix2505v.h b/drivers/media/dvb-frontends/ix2505v.h index 1a735a75aa98..af107a2dd357 100644 --- a/drivers/media/dvb-frontends/ix2505v.h +++ b/drivers/media/dvb-frontends/ix2505v.h | |||
@@ -49,7 +49,7 @@ struct ix2505v_config { | |||
49 | 49 | ||
50 | }; | 50 | }; |
51 | 51 | ||
52 | #if IS_ENABLED(CONFIG_DVB_IX2505V) | 52 | #if IS_REACHABLE(CONFIG_DVB_IX2505V) |
53 | extern struct dvb_frontend *ix2505v_attach(struct dvb_frontend *fe, | 53 | extern struct dvb_frontend *ix2505v_attach(struct dvb_frontend *fe, |
54 | const struct ix2505v_config *config, struct i2c_adapter *i2c); | 54 | const struct ix2505v_config *config, struct i2c_adapter *i2c); |
55 | #else | 55 | #else |
diff --git a/drivers/media/dvb-frontends/l64781.h b/drivers/media/dvb-frontends/l64781.h index 6813b08a774d..8697e2c2ba36 100644 --- a/drivers/media/dvb-frontends/l64781.h +++ b/drivers/media/dvb-frontends/l64781.h | |||
@@ -31,7 +31,7 @@ struct l64781_config | |||
31 | u8 demod_address; | 31 | u8 demod_address; |
32 | }; | 32 | }; |
33 | 33 | ||
34 | #if IS_ENABLED(CONFIG_DVB_L64781) | 34 | #if IS_REACHABLE(CONFIG_DVB_L64781) |
35 | extern struct dvb_frontend* l64781_attach(const struct l64781_config* config, | 35 | extern struct dvb_frontend* l64781_attach(const struct l64781_config* config, |
36 | struct i2c_adapter* i2c); | 36 | struct i2c_adapter* i2c); |
37 | #else | 37 | #else |
diff --git a/drivers/media/dvb-frontends/lg2160.h b/drivers/media/dvb-frontends/lg2160.h index 194a07a78dc1..d20bd909de39 100644 --- a/drivers/media/dvb-frontends/lg2160.h +++ b/drivers/media/dvb-frontends/lg2160.h | |||
@@ -67,7 +67,7 @@ struct lg2160_config { | |||
67 | enum lg_chip_type lg_chip; | 67 | enum lg_chip_type lg_chip; |
68 | }; | 68 | }; |
69 | 69 | ||
70 | #if IS_ENABLED(CONFIG_DVB_LG2160) | 70 | #if IS_REACHABLE(CONFIG_DVB_LG2160) |
71 | extern | 71 | extern |
72 | struct dvb_frontend *lg2160_attach(const struct lg2160_config *config, | 72 | struct dvb_frontend *lg2160_attach(const struct lg2160_config *config, |
73 | struct i2c_adapter *i2c_adap); | 73 | struct i2c_adapter *i2c_adap); |
diff --git a/drivers/media/dvb-frontends/lgdt3305.h b/drivers/media/dvb-frontends/lgdt3305.h index 9c03e530e01b..f91a1b49ce2f 100644 --- a/drivers/media/dvb-frontends/lgdt3305.h +++ b/drivers/media/dvb-frontends/lgdt3305.h | |||
@@ -80,7 +80,7 @@ struct lgdt3305_config { | |||
80 | enum lgdt_demod_chip_type demod_chip; | 80 | enum lgdt_demod_chip_type demod_chip; |
81 | }; | 81 | }; |
82 | 82 | ||
83 | #if IS_ENABLED(CONFIG_DVB_LGDT3305) | 83 | #if IS_REACHABLE(CONFIG_DVB_LGDT3305) |
84 | extern | 84 | extern |
85 | struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config, | 85 | struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config, |
86 | struct i2c_adapter *i2c_adap); | 86 | struct i2c_adapter *i2c_adap); |
diff --git a/drivers/media/dvb-frontends/lgdt3306a.c b/drivers/media/dvb-frontends/lgdt3306a.c new file mode 100644 index 000000000000..d9a2b0e768e0 --- /dev/null +++ b/drivers/media/dvb-frontends/lgdt3306a.c | |||
@@ -0,0 +1,2144 @@ | |||
1 | /* | ||
2 | * Support for LGDT3306A - 8VSB/QAM-B | ||
3 | * | ||
4 | * Copyright (C) 2013 Fred Richter <frichter@hauppauge.com> | ||
5 | * - driver structure based on lgdt3305.[ch] by Michael Krufky | ||
6 | * - code based on LG3306_V0.35 API by LG Electronics Inc. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | */ | ||
18 | |||
19 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
20 | |||
21 | #include <asm/div64.h> | ||
22 | #include <linux/dvb/frontend.h> | ||
23 | #include "dvb_math.h" | ||
24 | #include "lgdt3306a.h" | ||
25 | |||
26 | |||
27 | static int debug; | ||
28 | module_param(debug, int, 0644); | ||
29 | MODULE_PARM_DESC(debug, "set debug level (info=1, reg=2 (or-able))"); | ||
30 | |||
31 | #define DBG_INFO 1 | ||
32 | #define DBG_REG 2 | ||
33 | #define DBG_DUMP 4 /* FGR - comment out to remove dump code */ | ||
34 | |||
35 | #define lg_debug(fmt, arg...) \ | ||
36 | printk(KERN_DEBUG pr_fmt(fmt), ## arg) | ||
37 | |||
38 | #define dbg_info(fmt, arg...) \ | ||
39 | do { \ | ||
40 | if (debug & DBG_INFO) \ | ||
41 | lg_debug(fmt, ## arg); \ | ||
42 | } while (0) | ||
43 | |||
44 | #define dbg_reg(fmt, arg...) \ | ||
45 | do { \ | ||
46 | if (debug & DBG_REG) \ | ||
47 | lg_debug(fmt, ## arg); \ | ||
48 | } while (0) | ||
49 | |||
50 | #define lg_chkerr(ret) \ | ||
51 | ({ \ | ||
52 | int __ret; \ | ||
53 | __ret = (ret < 0); \ | ||
54 | if (__ret) \ | ||
55 | pr_err("error %d on line %d\n", ret, __LINE__); \ | ||
56 | __ret; \ | ||
57 | }) | ||
58 | |||
59 | struct lgdt3306a_state { | ||
60 | struct i2c_adapter *i2c_adap; | ||
61 | const struct lgdt3306a_config *cfg; | ||
62 | |||
63 | struct dvb_frontend frontend; | ||
64 | |||
65 | fe_modulation_t current_modulation; | ||
66 | u32 current_frequency; | ||
67 | u32 snr; | ||
68 | }; | ||
69 | |||
70 | /* | ||
71 | * LG3306A Register Usage | ||
72 | * (LG does not really name the registers, so this code does not either) | ||
73 | * | ||
74 | * 0000 -> 00FF Common control and status | ||
75 | * 1000 -> 10FF Synchronizer control and status | ||
76 | * 1F00 -> 1FFF Smart Antenna control and status | ||
77 | * 2100 -> 21FF VSB Equalizer control and status | ||
78 | * 2800 -> 28FF QAM Equalizer control and status | ||
79 | * 3000 -> 30FF FEC control and status | ||
80 | */ | ||
81 | |||
82 | enum lgdt3306a_lock_status { | ||
83 | LG3306_UNLOCK = 0x00, | ||
84 | LG3306_LOCK = 0x01, | ||
85 | LG3306_UNKNOWN_LOCK = 0xff | ||
86 | }; | ||
87 | |||
88 | enum lgdt3306a_neverlock_status { | ||
89 | LG3306_NL_INIT = 0x00, | ||
90 | LG3306_NL_PROCESS = 0x01, | ||
91 | LG3306_NL_LOCK = 0x02, | ||
92 | LG3306_NL_FAIL = 0x03, | ||
93 | LG3306_NL_UNKNOWN = 0xff | ||
94 | }; | ||
95 | |||
96 | enum lgdt3306a_modulation { | ||
97 | LG3306_VSB = 0x00, | ||
98 | LG3306_QAM64 = 0x01, | ||
99 | LG3306_QAM256 = 0x02, | ||
100 | LG3306_UNKNOWN_MODE = 0xff | ||
101 | }; | ||
102 | |||
103 | enum lgdt3306a_lock_check { | ||
104 | LG3306_SYNC_LOCK, | ||
105 | LG3306_FEC_LOCK, | ||
106 | LG3306_TR_LOCK, | ||
107 | LG3306_AGC_LOCK, | ||
108 | }; | ||
109 | |||
110 | |||
111 | #ifdef DBG_DUMP | ||
112 | static void lgdt3306a_DumpAllRegs(struct lgdt3306a_state *state); | ||
113 | static void lgdt3306a_DumpRegs(struct lgdt3306a_state *state); | ||
114 | #endif | ||
115 | |||
116 | |||
117 | static int lgdt3306a_write_reg(struct lgdt3306a_state *state, u16 reg, u8 val) | ||
118 | { | ||
119 | int ret; | ||
120 | u8 buf[] = { reg >> 8, reg & 0xff, val }; | ||
121 | struct i2c_msg msg = { | ||
122 | .addr = state->cfg->i2c_addr, .flags = 0, | ||
123 | .buf = buf, .len = 3, | ||
124 | }; | ||
125 | |||
126 | dbg_reg("reg: 0x%04x, val: 0x%02x\n", reg, val); | ||
127 | |||
128 | ret = i2c_transfer(state->i2c_adap, &msg, 1); | ||
129 | |||
130 | if (ret != 1) { | ||
131 | pr_err("error (addr %02x %02x <- %02x, err = %i)\n", | ||
132 | msg.buf[0], msg.buf[1], msg.buf[2], ret); | ||
133 | if (ret < 0) | ||
134 | return ret; | ||
135 | else | ||
136 | return -EREMOTEIO; | ||
137 | } | ||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | static int lgdt3306a_read_reg(struct lgdt3306a_state *state, u16 reg, u8 *val) | ||
142 | { | ||
143 | int ret; | ||
144 | u8 reg_buf[] = { reg >> 8, reg & 0xff }; | ||
145 | struct i2c_msg msg[] = { | ||
146 | { .addr = state->cfg->i2c_addr, | ||
147 | .flags = 0, .buf = reg_buf, .len = 2 }, | ||
148 | { .addr = state->cfg->i2c_addr, | ||
149 | .flags = I2C_M_RD, .buf = val, .len = 1 }, | ||
150 | }; | ||
151 | |||
152 | ret = i2c_transfer(state->i2c_adap, msg, 2); | ||
153 | |||
154 | if (ret != 2) { | ||
155 | pr_err("error (addr %02x reg %04x error (ret == %i)\n", | ||
156 | state->cfg->i2c_addr, reg, ret); | ||
157 | if (ret < 0) | ||
158 | return ret; | ||
159 | else | ||
160 | return -EREMOTEIO; | ||
161 | } | ||
162 | dbg_reg("reg: 0x%04x, val: 0x%02x\n", reg, *val); | ||
163 | |||
164 | return 0; | ||
165 | } | ||
166 | |||
167 | #define read_reg(state, reg) \ | ||
168 | ({ \ | ||
169 | u8 __val; \ | ||
170 | int ret = lgdt3306a_read_reg(state, reg, &__val); \ | ||
171 | if (lg_chkerr(ret)) \ | ||
172 | __val = 0; \ | ||
173 | __val; \ | ||
174 | }) | ||
175 | |||
176 | static int lgdt3306a_set_reg_bit(struct lgdt3306a_state *state, | ||
177 | u16 reg, int bit, int onoff) | ||
178 | { | ||
179 | u8 val; | ||
180 | int ret; | ||
181 | |||
182 | dbg_reg("reg: 0x%04x, bit: %d, level: %d\n", reg, bit, onoff); | ||
183 | |||
184 | ret = lgdt3306a_read_reg(state, reg, &val); | ||
185 | if (lg_chkerr(ret)) | ||
186 | goto fail; | ||
187 | |||
188 | val &= ~(1 << bit); | ||
189 | val |= (onoff & 1) << bit; | ||
190 | |||
191 | ret = lgdt3306a_write_reg(state, reg, val); | ||
192 | lg_chkerr(ret); | ||
193 | fail: | ||
194 | return ret; | ||
195 | } | ||
196 | |||
197 | /* ------------------------------------------------------------------------ */ | ||
198 | |||
199 | static int lgdt3306a_soft_reset(struct lgdt3306a_state *state) | ||
200 | { | ||
201 | int ret; | ||
202 | |||
203 | dbg_info("\n"); | ||
204 | |||
205 | ret = lgdt3306a_set_reg_bit(state, 0x0000, 7, 0); | ||
206 | if (lg_chkerr(ret)) | ||
207 | goto fail; | ||
208 | |||
209 | msleep(20); | ||
210 | ret = lgdt3306a_set_reg_bit(state, 0x0000, 7, 1); | ||
211 | lg_chkerr(ret); | ||
212 | |||
213 | fail: | ||
214 | return ret; | ||
215 | } | ||
216 | |||
217 | static int lgdt3306a_mpeg_mode(struct lgdt3306a_state *state, | ||
218 | enum lgdt3306a_mpeg_mode mode) | ||
219 | { | ||
220 | u8 val; | ||
221 | int ret; | ||
222 | |||
223 | dbg_info("(%d)\n", mode); | ||
224 | /* transport packet format - TPSENB=0x80 */ | ||
225 | ret = lgdt3306a_set_reg_bit(state, 0x0071, 7, | ||
226 | mode == LGDT3306A_MPEG_PARALLEL ? 1 : 0); | ||
227 | if (lg_chkerr(ret)) | ||
228 | goto fail; | ||
229 | |||
230 | /* | ||
231 | * start of packet signal duration | ||
232 | * TPSSOPBITEN=0x40; 0=byte duration, 1=bit duration | ||
233 | */ | ||
234 | ret = lgdt3306a_set_reg_bit(state, 0x0071, 6, 0); | ||
235 | if (lg_chkerr(ret)) | ||
236 | goto fail; | ||
237 | |||
238 | ret = lgdt3306a_read_reg(state, 0x0070, &val); | ||
239 | if (lg_chkerr(ret)) | ||
240 | goto fail; | ||
241 | |||
242 | val |= 0x10; /* TPCLKSUPB=0x10 */ | ||
243 | |||
244 | if (mode == LGDT3306A_MPEG_PARALLEL) | ||
245 | val &= ~0x10; | ||
246 | |||
247 | ret = lgdt3306a_write_reg(state, 0x0070, val); | ||
248 | lg_chkerr(ret); | ||
249 | |||
250 | fail: | ||
251 | return ret; | ||
252 | } | ||
253 | |||
254 | static int lgdt3306a_mpeg_mode_polarity(struct lgdt3306a_state *state, | ||
255 | enum lgdt3306a_tp_clock_edge edge, | ||
256 | enum lgdt3306a_tp_valid_polarity valid) | ||
257 | { | ||
258 | u8 val; | ||
259 | int ret; | ||
260 | |||
261 | dbg_info("edge=%d, valid=%d\n", edge, valid); | ||
262 | |||
263 | ret = lgdt3306a_read_reg(state, 0x0070, &val); | ||
264 | if (lg_chkerr(ret)) | ||
265 | goto fail; | ||
266 | |||
267 | val &= ~0x06; /* TPCLKPOL=0x04, TPVALPOL=0x02 */ | ||
268 | |||
269 | if (edge == LGDT3306A_TPCLK_RISING_EDGE) | ||
270 | val |= 0x04; | ||
271 | if (valid == LGDT3306A_TP_VALID_HIGH) | ||
272 | val |= 0x02; | ||
273 | |||
274 | ret = lgdt3306a_write_reg(state, 0x0070, val); | ||
275 | lg_chkerr(ret); | ||
276 | |||
277 | fail: | ||
278 | return ret; | ||
279 | } | ||
280 | |||
281 | static int lgdt3306a_mpeg_tristate(struct lgdt3306a_state *state, | ||
282 | int mode) | ||
283 | { | ||
284 | u8 val; | ||
285 | int ret; | ||
286 | |||
287 | dbg_info("(%d)\n", mode); | ||
288 | |||
289 | if (mode) { | ||
290 | ret = lgdt3306a_read_reg(state, 0x0070, &val); | ||
291 | if (lg_chkerr(ret)) | ||
292 | goto fail; | ||
293 | /* | ||
294 | * Tristate bus; TPOUTEN=0x80, TPCLKOUTEN=0x20, | ||
295 | * TPDATAOUTEN=0x08 | ||
296 | */ | ||
297 | val &= ~0xa8; | ||
298 | ret = lgdt3306a_write_reg(state, 0x0070, val); | ||
299 | if (lg_chkerr(ret)) | ||
300 | goto fail; | ||
301 | |||
302 | /* AGCIFOUTENB=0x40; 1=Disable IFAGC pin */ | ||
303 | ret = lgdt3306a_set_reg_bit(state, 0x0003, 6, 1); | ||
304 | if (lg_chkerr(ret)) | ||
305 | goto fail; | ||
306 | |||
307 | } else { | ||
308 | /* enable IFAGC pin */ | ||
309 | ret = lgdt3306a_set_reg_bit(state, 0x0003, 6, 0); | ||
310 | if (lg_chkerr(ret)) | ||
311 | goto fail; | ||
312 | |||
313 | ret = lgdt3306a_read_reg(state, 0x0070, &val); | ||
314 | if (lg_chkerr(ret)) | ||
315 | goto fail; | ||
316 | |||
317 | val |= 0xa8; /* enable bus */ | ||
318 | ret = lgdt3306a_write_reg(state, 0x0070, val); | ||
319 | if (lg_chkerr(ret)) | ||
320 | goto fail; | ||
321 | } | ||
322 | |||
323 | fail: | ||
324 | return ret; | ||
325 | } | ||
326 | |||
327 | static int lgdt3306a_ts_bus_ctrl(struct dvb_frontend *fe, int acquire) | ||
328 | { | ||
329 | struct lgdt3306a_state *state = fe->demodulator_priv; | ||
330 | |||
331 | dbg_info("acquire=%d\n", acquire); | ||
332 | |||
333 | return lgdt3306a_mpeg_tristate(state, acquire ? 0 : 1); | ||
334 | |||
335 | } | ||
336 | |||
337 | static int lgdt3306a_power(struct lgdt3306a_state *state, | ||
338 | int mode) | ||
339 | { | ||
340 | int ret; | ||
341 | |||
342 | dbg_info("(%d)\n", mode); | ||
343 | |||
344 | if (mode == 0) { | ||
345 | /* into reset */ | ||
346 | ret = lgdt3306a_set_reg_bit(state, 0x0000, 7, 0); | ||
347 | if (lg_chkerr(ret)) | ||
348 | goto fail; | ||
349 | |||
350 | /* power down */ | ||
351 | ret = lgdt3306a_set_reg_bit(state, 0x0000, 0, 0); | ||
352 | if (lg_chkerr(ret)) | ||
353 | goto fail; | ||
354 | |||
355 | } else { | ||
356 | /* out of reset */ | ||
357 | ret = lgdt3306a_set_reg_bit(state, 0x0000, 7, 1); | ||
358 | if (lg_chkerr(ret)) | ||
359 | goto fail; | ||
360 | |||
361 | /* power up */ | ||
362 | ret = lgdt3306a_set_reg_bit(state, 0x0000, 0, 1); | ||
363 | if (lg_chkerr(ret)) | ||
364 | goto fail; | ||
365 | } | ||
366 | |||
367 | #ifdef DBG_DUMP | ||
368 | lgdt3306a_DumpAllRegs(state); | ||
369 | #endif | ||
370 | fail: | ||
371 | return ret; | ||
372 | } | ||
373 | |||
374 | |||
375 | static int lgdt3306a_set_vsb(struct lgdt3306a_state *state) | ||
376 | { | ||
377 | u8 val; | ||
378 | int ret; | ||
379 | |||
380 | dbg_info("\n"); | ||
381 | |||
382 | /* 0. Spectrum inversion detection manual; spectrum inverted */ | ||
383 | ret = lgdt3306a_read_reg(state, 0x0002, &val); | ||
384 | val &= 0xf7; /* SPECINVAUTO Off */ | ||
385 | val |= 0x04; /* SPECINV On */ | ||
386 | ret = lgdt3306a_write_reg(state, 0x0002, val); | ||
387 | if (lg_chkerr(ret)) | ||
388 | goto fail; | ||
389 | |||
390 | /* 1. Selection of standard mode(0x08=QAM, 0x80=VSB) */ | ||
391 | ret = lgdt3306a_write_reg(state, 0x0008, 0x80); | ||
392 | if (lg_chkerr(ret)) | ||
393 | goto fail; | ||
394 | |||
395 | /* 2. Bandwidth mode for VSB(6MHz) */ | ||
396 | ret = lgdt3306a_read_reg(state, 0x0009, &val); | ||
397 | val &= 0xe3; | ||
398 | val |= 0x0c; /* STDOPDETTMODE[2:0]=3 */ | ||
399 | ret = lgdt3306a_write_reg(state, 0x0009, val); | ||
400 | if (lg_chkerr(ret)) | ||
401 | goto fail; | ||
402 | |||
403 | /* 3. QAM mode detection mode(None) */ | ||
404 | ret = lgdt3306a_read_reg(state, 0x0009, &val); | ||
405 | val &= 0xfc; /* STDOPDETCMODE[1:0]=0 */ | ||
406 | ret = lgdt3306a_write_reg(state, 0x0009, val); | ||
407 | if (lg_chkerr(ret)) | ||
408 | goto fail; | ||
409 | |||
410 | /* 4. ADC sampling frequency rate(2x sampling) */ | ||
411 | ret = lgdt3306a_read_reg(state, 0x000d, &val); | ||
412 | val &= 0xbf; /* SAMPLING4XFEN=0 */ | ||
413 | ret = lgdt3306a_write_reg(state, 0x000d, val); | ||
414 | if (lg_chkerr(ret)) | ||
415 | goto fail; | ||
416 | |||
417 | #if 0 | ||
418 | /* FGR - disable any AICC filtering, testing only */ | ||
419 | |||
420 | ret = lgdt3306a_write_reg(state, 0x0024, 0x00); | ||
421 | if (lg_chkerr(ret)) | ||
422 | goto fail; | ||
423 | |||
424 | /* AICCFIXFREQ0 NT N-1(Video rejection) */ | ||
425 | ret = lgdt3306a_write_reg(state, 0x002e, 0x00); | ||
426 | ret = lgdt3306a_write_reg(state, 0x002f, 0x00); | ||
427 | ret = lgdt3306a_write_reg(state, 0x0030, 0x00); | ||
428 | |||
429 | /* AICCFIXFREQ1 NT N-1(Audio rejection) */ | ||
430 | ret = lgdt3306a_write_reg(state, 0x002b, 0x00); | ||
431 | ret = lgdt3306a_write_reg(state, 0x002c, 0x00); | ||
432 | ret = lgdt3306a_write_reg(state, 0x002d, 0x00); | ||
433 | |||
434 | /* AICCFIXFREQ2 NT Co-Channel(Video rejection) */ | ||
435 | ret = lgdt3306a_write_reg(state, 0x0028, 0x00); | ||
436 | ret = lgdt3306a_write_reg(state, 0x0029, 0x00); | ||
437 | ret = lgdt3306a_write_reg(state, 0x002a, 0x00); | ||
438 | |||
439 | /* AICCFIXFREQ3 NT Co-Channel(Audio rejection) */ | ||
440 | ret = lgdt3306a_write_reg(state, 0x0025, 0x00); | ||
441 | ret = lgdt3306a_write_reg(state, 0x0026, 0x00); | ||
442 | ret = lgdt3306a_write_reg(state, 0x0027, 0x00); | ||
443 | |||
444 | #else | ||
445 | /* FGR - this works well for HVR-1955,1975 */ | ||
446 | |||
447 | /* 5. AICCOPMODE NT N-1 Adj. */ | ||
448 | ret = lgdt3306a_write_reg(state, 0x0024, 0x5A); | ||
449 | if (lg_chkerr(ret)) | ||
450 | goto fail; | ||
451 | |||
452 | /* AICCFIXFREQ0 NT N-1(Video rejection) */ | ||
453 | ret = lgdt3306a_write_reg(state, 0x002e, 0x5A); | ||
454 | ret = lgdt3306a_write_reg(state, 0x002f, 0x00); | ||
455 | ret = lgdt3306a_write_reg(state, 0x0030, 0x00); | ||
456 | |||
457 | /* AICCFIXFREQ1 NT N-1(Audio rejection) */ | ||
458 | ret = lgdt3306a_write_reg(state, 0x002b, 0x36); | ||
459 | ret = lgdt3306a_write_reg(state, 0x002c, 0x00); | ||
460 | ret = lgdt3306a_write_reg(state, 0x002d, 0x00); | ||
461 | |||
462 | /* AICCFIXFREQ2 NT Co-Channel(Video rejection) */ | ||
463 | ret = lgdt3306a_write_reg(state, 0x0028, 0x2A); | ||
464 | ret = lgdt3306a_write_reg(state, 0x0029, 0x00); | ||
465 | ret = lgdt3306a_write_reg(state, 0x002a, 0x00); | ||
466 | |||
467 | /* AICCFIXFREQ3 NT Co-Channel(Audio rejection) */ | ||
468 | ret = lgdt3306a_write_reg(state, 0x0025, 0x06); | ||
469 | ret = lgdt3306a_write_reg(state, 0x0026, 0x00); | ||
470 | ret = lgdt3306a_write_reg(state, 0x0027, 0x00); | ||
471 | #endif | ||
472 | |||
473 | ret = lgdt3306a_read_reg(state, 0x001e, &val); | ||
474 | val &= 0x0f; | ||
475 | val |= 0xa0; | ||
476 | ret = lgdt3306a_write_reg(state, 0x001e, val); | ||
477 | |||
478 | ret = lgdt3306a_write_reg(state, 0x0022, 0x08); | ||
479 | |||
480 | ret = lgdt3306a_write_reg(state, 0x0023, 0xFF); | ||
481 | |||
482 | ret = lgdt3306a_read_reg(state, 0x211f, &val); | ||
483 | val &= 0xef; | ||
484 | ret = lgdt3306a_write_reg(state, 0x211f, val); | ||
485 | |||
486 | ret = lgdt3306a_write_reg(state, 0x2173, 0x01); | ||
487 | |||
488 | ret = lgdt3306a_read_reg(state, 0x1061, &val); | ||
489 | val &= 0xf8; | ||
490 | val |= 0x04; | ||
491 | ret = lgdt3306a_write_reg(state, 0x1061, val); | ||
492 | |||
493 | ret = lgdt3306a_read_reg(state, 0x103d, &val); | ||
494 | val &= 0xcf; | ||
495 | ret = lgdt3306a_write_reg(state, 0x103d, val); | ||
496 | |||
497 | ret = lgdt3306a_write_reg(state, 0x2122, 0x40); | ||
498 | |||
499 | ret = lgdt3306a_read_reg(state, 0x2141, &val); | ||
500 | val &= 0x3f; | ||
501 | ret = lgdt3306a_write_reg(state, 0x2141, val); | ||
502 | |||
503 | ret = lgdt3306a_read_reg(state, 0x2135, &val); | ||
504 | val &= 0x0f; | ||
505 | val |= 0x70; | ||
506 | ret = lgdt3306a_write_reg(state, 0x2135, val); | ||
507 | |||
508 | ret = lgdt3306a_read_reg(state, 0x0003, &val); | ||
509 | val &= 0xf7; | ||
510 | ret = lgdt3306a_write_reg(state, 0x0003, val); | ||
511 | |||
512 | ret = lgdt3306a_read_reg(state, 0x001c, &val); | ||
513 | val &= 0x7f; | ||
514 | ret = lgdt3306a_write_reg(state, 0x001c, val); | ||
515 | |||
516 | /* 6. EQ step size */ | ||
517 | ret = lgdt3306a_read_reg(state, 0x2179, &val); | ||
518 | val &= 0xf8; | ||
519 | ret = lgdt3306a_write_reg(state, 0x2179, val); | ||
520 | |||
521 | ret = lgdt3306a_read_reg(state, 0x217a, &val); | ||
522 | val &= 0xf8; | ||
523 | ret = lgdt3306a_write_reg(state, 0x217a, val); | ||
524 | |||
525 | /* 7. Reset */ | ||
526 | ret = lgdt3306a_soft_reset(state); | ||
527 | if (lg_chkerr(ret)) | ||
528 | goto fail; | ||
529 | |||
530 | dbg_info("complete\n"); | ||
531 | fail: | ||
532 | return ret; | ||
533 | } | ||
534 | |||
535 | static int lgdt3306a_set_qam(struct lgdt3306a_state *state, int modulation) | ||
536 | { | ||
537 | u8 val; | ||
538 | int ret; | ||
539 | |||
540 | dbg_info("modulation=%d\n", modulation); | ||
541 | |||
542 | /* 1. Selection of standard mode(0x08=QAM, 0x80=VSB) */ | ||
543 | ret = lgdt3306a_write_reg(state, 0x0008, 0x08); | ||
544 | if (lg_chkerr(ret)) | ||
545 | goto fail; | ||
546 | |||
547 | /* 1a. Spectrum inversion detection to Auto */ | ||
548 | ret = lgdt3306a_read_reg(state, 0x0002, &val); | ||
549 | val &= 0xfb; /* SPECINV Off */ | ||
550 | val |= 0x08; /* SPECINVAUTO On */ | ||
551 | ret = lgdt3306a_write_reg(state, 0x0002, val); | ||
552 | if (lg_chkerr(ret)) | ||
553 | goto fail; | ||
554 | |||
555 | /* 2. Bandwidth mode for QAM */ | ||
556 | ret = lgdt3306a_read_reg(state, 0x0009, &val); | ||
557 | val &= 0xe3; /* STDOPDETTMODE[2:0]=0 VSB Off */ | ||
558 | ret = lgdt3306a_write_reg(state, 0x0009, val); | ||
559 | if (lg_chkerr(ret)) | ||
560 | goto fail; | ||
561 | |||
562 | /* 3. : 64QAM/256QAM detection(manual, auto) */ | ||
563 | ret = lgdt3306a_read_reg(state, 0x0009, &val); | ||
564 | val &= 0xfc; | ||
565 | val |= 0x02; /* STDOPDETCMODE[1:0]=1=Manual 2=Auto */ | ||
566 | ret = lgdt3306a_write_reg(state, 0x0009, val); | ||
567 | if (lg_chkerr(ret)) | ||
568 | goto fail; | ||
569 | |||
570 | /* 3a. : 64QAM/256QAM selection for manual */ | ||
571 | ret = lgdt3306a_read_reg(state, 0x101a, &val); | ||
572 | val &= 0xf8; | ||
573 | if (modulation == QAM_64) | ||
574 | val |= 0x02; /* QMDQMODE[2:0]=2=QAM64 */ | ||
575 | else | ||
576 | val |= 0x04; /* QMDQMODE[2:0]=4=QAM256 */ | ||
577 | |||
578 | ret = lgdt3306a_write_reg(state, 0x101a, val); | ||
579 | if (lg_chkerr(ret)) | ||
580 | goto fail; | ||
581 | |||
582 | /* 4. ADC sampling frequency rate(4x sampling) */ | ||
583 | ret = lgdt3306a_read_reg(state, 0x000d, &val); | ||
584 | val &= 0xbf; | ||
585 | val |= 0x40; /* SAMPLING4XFEN=1 */ | ||
586 | ret = lgdt3306a_write_reg(state, 0x000d, val); | ||
587 | if (lg_chkerr(ret)) | ||
588 | goto fail; | ||
589 | |||
590 | /* 5. No AICC operation in QAM mode */ | ||
591 | ret = lgdt3306a_read_reg(state, 0x0024, &val); | ||
592 | val &= 0x00; | ||
593 | ret = lgdt3306a_write_reg(state, 0x0024, val); | ||
594 | if (lg_chkerr(ret)) | ||
595 | goto fail; | ||
596 | |||
597 | /* 6. Reset */ | ||
598 | ret = lgdt3306a_soft_reset(state); | ||
599 | if (lg_chkerr(ret)) | ||
600 | goto fail; | ||
601 | |||
602 | dbg_info("complete\n"); | ||
603 | fail: | ||
604 | return ret; | ||
605 | } | ||
606 | |||
607 | static int lgdt3306a_set_modulation(struct lgdt3306a_state *state, | ||
608 | struct dtv_frontend_properties *p) | ||
609 | { | ||
610 | int ret; | ||
611 | |||
612 | dbg_info("\n"); | ||
613 | |||
614 | switch (p->modulation) { | ||
615 | case VSB_8: | ||
616 | ret = lgdt3306a_set_vsb(state); | ||
617 | break; | ||
618 | case QAM_64: | ||
619 | ret = lgdt3306a_set_qam(state, QAM_64); | ||
620 | break; | ||
621 | case QAM_256: | ||
622 | ret = lgdt3306a_set_qam(state, QAM_256); | ||
623 | break; | ||
624 | default: | ||
625 | return -EINVAL; | ||
626 | } | ||
627 | if (lg_chkerr(ret)) | ||
628 | goto fail; | ||
629 | |||
630 | state->current_modulation = p->modulation; | ||
631 | |||
632 | fail: | ||
633 | return ret; | ||
634 | } | ||
635 | |||
636 | /* ------------------------------------------------------------------------ */ | ||
637 | |||
638 | static int lgdt3306a_agc_setup(struct lgdt3306a_state *state, | ||
639 | struct dtv_frontend_properties *p) | ||
640 | { | ||
641 | /* TODO: anything we want to do here??? */ | ||
642 | dbg_info("\n"); | ||
643 | |||
644 | switch (p->modulation) { | ||
645 | case VSB_8: | ||
646 | break; | ||
647 | case QAM_64: | ||
648 | case QAM_256: | ||
649 | break; | ||
650 | default: | ||
651 | return -EINVAL; | ||
652 | } | ||
653 | return 0; | ||
654 | } | ||
655 | |||
656 | /* ------------------------------------------------------------------------ */ | ||
657 | |||
658 | static int lgdt3306a_set_inversion(struct lgdt3306a_state *state, | ||
659 | int inversion) | ||
660 | { | ||
661 | int ret; | ||
662 | |||
663 | dbg_info("(%d)\n", inversion); | ||
664 | |||
665 | ret = lgdt3306a_set_reg_bit(state, 0x0002, 2, inversion ? 1 : 0); | ||
666 | return ret; | ||
667 | } | ||
668 | |||
669 | static int lgdt3306a_set_inversion_auto(struct lgdt3306a_state *state, | ||
670 | int enabled) | ||
671 | { | ||
672 | int ret; | ||
673 | |||
674 | dbg_info("(%d)\n", enabled); | ||
675 | |||
676 | /* 0=Manual 1=Auto(QAM only) - SPECINVAUTO=0x04 */ | ||
677 | ret = lgdt3306a_set_reg_bit(state, 0x0002, 3, enabled); | ||
678 | return ret; | ||
679 | } | ||
680 | |||
681 | static int lgdt3306a_spectral_inversion(struct lgdt3306a_state *state, | ||
682 | struct dtv_frontend_properties *p, | ||
683 | int inversion) | ||
684 | { | ||
685 | int ret = 0; | ||
686 | |||
687 | dbg_info("(%d)\n", inversion); | ||
688 | #if 0 | ||
689 | /* | ||
690 | * FGR - spectral_inversion defaults already set for VSB and QAM; | ||
691 | * can enable later if desired | ||
692 | */ | ||
693 | |||
694 | ret = lgdt3306a_set_inversion(state, inversion); | ||
695 | |||
696 | switch (p->modulation) { | ||
697 | case VSB_8: | ||
698 | /* Manual only for VSB */ | ||
699 | ret = lgdt3306a_set_inversion_auto(state, 0); | ||
700 | break; | ||
701 | case QAM_64: | ||
702 | case QAM_256: | ||
703 | /* Auto ok for QAM */ | ||
704 | ret = lgdt3306a_set_inversion_auto(state, 1); | ||
705 | break; | ||
706 | default: | ||
707 | ret = -EINVAL; | ||
708 | } | ||
709 | #endif | ||
710 | return ret; | ||
711 | } | ||
712 | |||
713 | static int lgdt3306a_set_if(struct lgdt3306a_state *state, | ||
714 | struct dtv_frontend_properties *p) | ||
715 | { | ||
716 | int ret; | ||
717 | u16 if_freq_khz; | ||
718 | u8 nco1, nco2; | ||
719 | |||
720 | switch (p->modulation) { | ||
721 | case VSB_8: | ||
722 | if_freq_khz = state->cfg->vsb_if_khz; | ||
723 | break; | ||
724 | case QAM_64: | ||
725 | case QAM_256: | ||
726 | if_freq_khz = state->cfg->qam_if_khz; | ||
727 | break; | ||
728 | default: | ||
729 | return -EINVAL; | ||
730 | } | ||
731 | |||
732 | switch (if_freq_khz) { | ||
733 | default: | ||
734 | pr_warn("IF=%d KHz is not supportted, 3250 assumed\n", | ||
735 | if_freq_khz); | ||
736 | /* fallthrough */ | ||
737 | case 3250: /* 3.25Mhz */ | ||
738 | nco1 = 0x34; | ||
739 | nco2 = 0x00; | ||
740 | break; | ||
741 | case 3500: /* 3.50Mhz */ | ||
742 | nco1 = 0x38; | ||
743 | nco2 = 0x00; | ||
744 | break; | ||
745 | case 4000: /* 4.00Mhz */ | ||
746 | nco1 = 0x40; | ||
747 | nco2 = 0x00; | ||
748 | break; | ||
749 | case 5000: /* 5.00Mhz */ | ||
750 | nco1 = 0x50; | ||
751 | nco2 = 0x00; | ||
752 | break; | ||
753 | case 5380: /* 5.38Mhz */ | ||
754 | nco1 = 0x56; | ||
755 | nco2 = 0x14; | ||
756 | break; | ||
757 | } | ||
758 | ret = lgdt3306a_write_reg(state, 0x0010, nco1); | ||
759 | if (ret) | ||
760 | return ret; | ||
761 | ret = lgdt3306a_write_reg(state, 0x0011, nco2); | ||
762 | if (ret) | ||
763 | return ret; | ||
764 | |||
765 | dbg_info("if_freq=%d KHz->[%04x]\n", if_freq_khz, nco1<<8 | nco2); | ||
766 | |||
767 | return 0; | ||
768 | } | ||
769 | |||
770 | /* ------------------------------------------------------------------------ */ | ||
771 | |||
772 | static int lgdt3306a_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) | ||
773 | { | ||
774 | struct lgdt3306a_state *state = fe->demodulator_priv; | ||
775 | |||
776 | if (state->cfg->deny_i2c_rptr) { | ||
777 | dbg_info("deny_i2c_rptr=%d\n", state->cfg->deny_i2c_rptr); | ||
778 | return 0; | ||
779 | } | ||
780 | dbg_info("(%d)\n", enable); | ||
781 | |||
782 | /* NI2CRPTEN=0x80 */ | ||
783 | return lgdt3306a_set_reg_bit(state, 0x0002, 7, enable ? 0 : 1); | ||
784 | } | ||
785 | |||
786 | static int lgdt3306a_sleep(struct lgdt3306a_state *state) | ||
787 | { | ||
788 | int ret; | ||
789 | |||
790 | dbg_info("\n"); | ||
791 | state->current_frequency = -1; /* force re-tune, when we wake */ | ||
792 | |||
793 | ret = lgdt3306a_mpeg_tristate(state, 1); /* disable data bus */ | ||
794 | if (lg_chkerr(ret)) | ||
795 | goto fail; | ||
796 | |||
797 | ret = lgdt3306a_power(state, 0); /* power down */ | ||
798 | lg_chkerr(ret); | ||
799 | |||
800 | fail: | ||
801 | return 0; | ||
802 | } | ||
803 | |||
804 | static int lgdt3306a_fe_sleep(struct dvb_frontend *fe) | ||
805 | { | ||
806 | struct lgdt3306a_state *state = fe->demodulator_priv; | ||
807 | |||
808 | return lgdt3306a_sleep(state); | ||
809 | } | ||
810 | |||
811 | static int lgdt3306a_init(struct dvb_frontend *fe) | ||
812 | { | ||
813 | struct lgdt3306a_state *state = fe->demodulator_priv; | ||
814 | u8 val; | ||
815 | int ret; | ||
816 | |||
817 | dbg_info("\n"); | ||
818 | |||
819 | /* 1. Normal operation mode */ | ||
820 | ret = lgdt3306a_set_reg_bit(state, 0x0001, 0, 1); /* SIMFASTENB=0x01 */ | ||
821 | if (lg_chkerr(ret)) | ||
822 | goto fail; | ||
823 | |||
824 | /* 2. Spectrum inversion auto detection (Not valid for VSB) */ | ||
825 | ret = lgdt3306a_set_inversion_auto(state, 0); | ||
826 | if (lg_chkerr(ret)) | ||
827 | goto fail; | ||
828 | |||
829 | /* 3. Spectrum inversion(According to the tuner configuration) */ | ||
830 | ret = lgdt3306a_set_inversion(state, 1); | ||
831 | if (lg_chkerr(ret)) | ||
832 | goto fail; | ||
833 | |||
834 | /* 4. Peak-to-peak voltage of ADC input signal */ | ||
835 | |||
836 | /* ADCSEL1V=0x80=1Vpp; 0x00=2Vpp */ | ||
837 | ret = lgdt3306a_set_reg_bit(state, 0x0004, 7, 1); | ||
838 | if (lg_chkerr(ret)) | ||
839 | goto fail; | ||
840 | |||
841 | /* 5. ADC output data capture clock phase */ | ||
842 | |||
843 | /* 0=same phase as ADC clock */ | ||
844 | ret = lgdt3306a_set_reg_bit(state, 0x0004, 2, 0); | ||
845 | if (lg_chkerr(ret)) | ||
846 | goto fail; | ||
847 | |||
848 | /* 5a. ADC sampling clock source */ | ||
849 | |||
850 | /* ADCCLKPLLSEL=0x08; 0=use ext clock, not PLL */ | ||
851 | ret = lgdt3306a_set_reg_bit(state, 0x0004, 3, 0); | ||
852 | if (lg_chkerr(ret)) | ||
853 | goto fail; | ||
854 | |||
855 | /* 6. Automatic PLL set */ | ||
856 | |||
857 | /* PLLSETAUTO=0x40; 0=off */ | ||
858 | ret = lgdt3306a_set_reg_bit(state, 0x0005, 6, 0); | ||
859 | if (lg_chkerr(ret)) | ||
860 | goto fail; | ||
861 | |||
862 | if (state->cfg->xtalMHz == 24) { /* 24MHz */ | ||
863 | /* 7. Frequency for PLL output(0x2564 for 192MHz for 24MHz) */ | ||
864 | ret = lgdt3306a_read_reg(state, 0x0005, &val); | ||
865 | if (lg_chkerr(ret)) | ||
866 | goto fail; | ||
867 | val &= 0xc0; | ||
868 | val |= 0x25; | ||
869 | ret = lgdt3306a_write_reg(state, 0x0005, val); | ||
870 | if (lg_chkerr(ret)) | ||
871 | goto fail; | ||
872 | ret = lgdt3306a_write_reg(state, 0x0006, 0x64); | ||
873 | if (lg_chkerr(ret)) | ||
874 | goto fail; | ||
875 | |||
876 | /* 8. ADC sampling frequency(0x180000 for 24MHz sampling) */ | ||
877 | ret = lgdt3306a_read_reg(state, 0x000d, &val); | ||
878 | if (lg_chkerr(ret)) | ||
879 | goto fail; | ||
880 | val &= 0xc0; | ||
881 | val |= 0x18; | ||
882 | ret = lgdt3306a_write_reg(state, 0x000d, val); | ||
883 | if (lg_chkerr(ret)) | ||
884 | goto fail; | ||
885 | |||
886 | } else if (state->cfg->xtalMHz == 25) { /* 25MHz */ | ||
887 | /* 7. Frequency for PLL output */ | ||
888 | ret = lgdt3306a_read_reg(state, 0x0005, &val); | ||
889 | if (lg_chkerr(ret)) | ||
890 | goto fail; | ||
891 | val &= 0xc0; | ||
892 | val |= 0x25; | ||
893 | ret = lgdt3306a_write_reg(state, 0x0005, val); | ||
894 | if (lg_chkerr(ret)) | ||
895 | goto fail; | ||
896 | ret = lgdt3306a_write_reg(state, 0x0006, 0x64); | ||
897 | if (lg_chkerr(ret)) | ||
898 | goto fail; | ||
899 | |||
900 | /* 8. ADC sampling frequency(0x190000 for 25MHz sampling) */ | ||
901 | ret = lgdt3306a_read_reg(state, 0x000d, &val); | ||
902 | if (lg_chkerr(ret)) | ||
903 | goto fail; | ||
904 | val &= 0xc0; | ||
905 | val |= 0x19; | ||
906 | ret = lgdt3306a_write_reg(state, 0x000d, val); | ||
907 | if (lg_chkerr(ret)) | ||
908 | goto fail; | ||
909 | } else { | ||
910 | pr_err("Bad xtalMHz=%d\n", state->cfg->xtalMHz); | ||
911 | } | ||
912 | #if 0 | ||
913 | ret = lgdt3306a_write_reg(state, 0x000e, 0x00); | ||
914 | ret = lgdt3306a_write_reg(state, 0x000f, 0x00); | ||
915 | #endif | ||
916 | |||
917 | /* 9. Center frequency of input signal of ADC */ | ||
918 | ret = lgdt3306a_write_reg(state, 0x0010, 0x34); /* 3.25MHz */ | ||
919 | ret = lgdt3306a_write_reg(state, 0x0011, 0x00); | ||
920 | |||
921 | /* 10. Fixed gain error value */ | ||
922 | ret = lgdt3306a_write_reg(state, 0x0014, 0); /* gain error=0 */ | ||
923 | |||
924 | /* 10a. VSB TR BW gear shift initial step */ | ||
925 | ret = lgdt3306a_read_reg(state, 0x103c, &val); | ||
926 | val &= 0x0f; | ||
927 | val |= 0x20; /* SAMGSAUTOSTL_V[3:0] = 2 */ | ||
928 | ret = lgdt3306a_write_reg(state, 0x103c, val); | ||
929 | |||
930 | /* 10b. Timing offset calibration in low temperature for VSB */ | ||
931 | ret = lgdt3306a_read_reg(state, 0x103d, &val); | ||
932 | val &= 0xfc; | ||
933 | val |= 0x03; | ||
934 | ret = lgdt3306a_write_reg(state, 0x103d, val); | ||
935 | |||
936 | /* 10c. Timing offset calibration in low temperature for QAM */ | ||
937 | ret = lgdt3306a_read_reg(state, 0x1036, &val); | ||
938 | val &= 0xf0; | ||
939 | val |= 0x0c; | ||
940 | ret = lgdt3306a_write_reg(state, 0x1036, val); | ||
941 | |||
942 | /* 11. Using the imaginary part of CIR in CIR loading */ | ||
943 | ret = lgdt3306a_read_reg(state, 0x211f, &val); | ||
944 | val &= 0xef; /* do not use imaginary of CIR */ | ||
945 | ret = lgdt3306a_write_reg(state, 0x211f, val); | ||
946 | |||
947 | /* 12. Control of no signal detector function */ | ||
948 | ret = lgdt3306a_read_reg(state, 0x2849, &val); | ||
949 | val &= 0xef; /* NOUSENOSIGDET=0, enable no signal detector */ | ||
950 | ret = lgdt3306a_write_reg(state, 0x2849, val); | ||
951 | |||
952 | /* FGR - put demod in some known mode */ | ||
953 | ret = lgdt3306a_set_vsb(state); | ||
954 | |||
955 | /* 13. TP stream format */ | ||
956 | ret = lgdt3306a_mpeg_mode(state, state->cfg->mpeg_mode); | ||
957 | |||
958 | /* 14. disable output buses */ | ||
959 | ret = lgdt3306a_mpeg_tristate(state, 1); | ||
960 | |||
961 | /* 15. Sleep (in reset) */ | ||
962 | ret = lgdt3306a_sleep(state); | ||
963 | lg_chkerr(ret); | ||
964 | |||
965 | fail: | ||
966 | return ret; | ||
967 | } | ||
968 | |||
969 | static int lgdt3306a_set_parameters(struct dvb_frontend *fe) | ||
970 | { | ||
971 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||
972 | struct lgdt3306a_state *state = fe->demodulator_priv; | ||
973 | int ret; | ||
974 | |||
975 | dbg_info("(%d, %d)\n", p->frequency, p->modulation); | ||
976 | |||
977 | if (state->current_frequency == p->frequency && | ||
978 | state->current_modulation == p->modulation) { | ||
979 | dbg_info(" (already set, skipping ...)\n"); | ||
980 | return 0; | ||
981 | } | ||
982 | state->current_frequency = -1; | ||
983 | state->current_modulation = -1; | ||
984 | |||
985 | ret = lgdt3306a_power(state, 1); /* power up */ | ||
986 | if (lg_chkerr(ret)) | ||
987 | goto fail; | ||
988 | |||
989 | if (fe->ops.tuner_ops.set_params) { | ||
990 | ret = fe->ops.tuner_ops.set_params(fe); | ||
991 | if (fe->ops.i2c_gate_ctrl) | ||
992 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
993 | #if 0 | ||
994 | if (lg_chkerr(ret)) | ||
995 | goto fail; | ||
996 | state->current_frequency = p->frequency; | ||
997 | #endif | ||
998 | } | ||
999 | |||
1000 | ret = lgdt3306a_set_modulation(state, p); | ||
1001 | if (lg_chkerr(ret)) | ||
1002 | goto fail; | ||
1003 | |||
1004 | ret = lgdt3306a_agc_setup(state, p); | ||
1005 | if (lg_chkerr(ret)) | ||
1006 | goto fail; | ||
1007 | |||
1008 | ret = lgdt3306a_set_if(state, p); | ||
1009 | if (lg_chkerr(ret)) | ||
1010 | goto fail; | ||
1011 | |||
1012 | ret = lgdt3306a_spectral_inversion(state, p, | ||
1013 | state->cfg->spectral_inversion ? 1 : 0); | ||
1014 | if (lg_chkerr(ret)) | ||
1015 | goto fail; | ||
1016 | |||
1017 | ret = lgdt3306a_mpeg_mode(state, state->cfg->mpeg_mode); | ||
1018 | if (lg_chkerr(ret)) | ||
1019 | goto fail; | ||
1020 | |||
1021 | ret = lgdt3306a_mpeg_mode_polarity(state, | ||
1022 | state->cfg->tpclk_edge, | ||
1023 | state->cfg->tpvalid_polarity); | ||
1024 | if (lg_chkerr(ret)) | ||
1025 | goto fail; | ||
1026 | |||
1027 | ret = lgdt3306a_mpeg_tristate(state, 0); /* enable data bus */ | ||
1028 | if (lg_chkerr(ret)) | ||
1029 | goto fail; | ||
1030 | |||
1031 | ret = lgdt3306a_soft_reset(state); | ||
1032 | if (lg_chkerr(ret)) | ||
1033 | goto fail; | ||
1034 | |||
1035 | #ifdef DBG_DUMP | ||
1036 | lgdt3306a_DumpAllRegs(state); | ||
1037 | #endif | ||
1038 | state->current_frequency = p->frequency; | ||
1039 | fail: | ||
1040 | return ret; | ||
1041 | } | ||
1042 | |||
1043 | static int lgdt3306a_get_frontend(struct dvb_frontend *fe) | ||
1044 | { | ||
1045 | struct lgdt3306a_state *state = fe->demodulator_priv; | ||
1046 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||
1047 | |||
1048 | dbg_info("(%u, %d)\n", | ||
1049 | state->current_frequency, state->current_modulation); | ||
1050 | |||
1051 | p->modulation = state->current_modulation; | ||
1052 | p->frequency = state->current_frequency; | ||
1053 | return 0; | ||
1054 | } | ||
1055 | |||
1056 | static enum dvbfe_algo lgdt3306a_get_frontend_algo(struct dvb_frontend *fe) | ||
1057 | { | ||
1058 | #if 1 | ||
1059 | return DVBFE_ALGO_CUSTOM; | ||
1060 | #else | ||
1061 | return DVBFE_ALGO_HW; | ||
1062 | #endif | ||
1063 | } | ||
1064 | |||
1065 | /* ------------------------------------------------------------------------ */ | ||
1066 | static int lgdt3306a_monitor_vsb(struct lgdt3306a_state *state) | ||
1067 | { | ||
1068 | u8 val; | ||
1069 | int ret; | ||
1070 | u8 snrRef, maxPowerMan, nCombDet; | ||
1071 | u16 fbDlyCir; | ||
1072 | |||
1073 | ret = lgdt3306a_read_reg(state, 0x21a1, &val); | ||
1074 | if (ret) | ||
1075 | return ret; | ||
1076 | snrRef = val & 0x3f; | ||
1077 | |||
1078 | ret = lgdt3306a_read_reg(state, 0x2185, &maxPowerMan); | ||
1079 | if (ret) | ||
1080 | return ret; | ||
1081 | |||
1082 | ret = lgdt3306a_read_reg(state, 0x2191, &val); | ||
1083 | if (ret) | ||
1084 | return ret; | ||
1085 | nCombDet = (val & 0x80) >> 7; | ||
1086 | |||
1087 | ret = lgdt3306a_read_reg(state, 0x2180, &val); | ||
1088 | if (ret) | ||
1089 | return ret; | ||
1090 | fbDlyCir = (val & 0x03) << 8; | ||
1091 | |||
1092 | ret = lgdt3306a_read_reg(state, 0x2181, &val); | ||
1093 | if (ret) | ||
1094 | return ret; | ||
1095 | fbDlyCir |= val; | ||
1096 | |||
1097 | dbg_info("snrRef=%d maxPowerMan=0x%x nCombDet=%d fbDlyCir=0x%x\n", | ||
1098 | snrRef, maxPowerMan, nCombDet, fbDlyCir); | ||
1099 | |||
1100 | /* Carrier offset sub loop bandwidth */ | ||
1101 | ret = lgdt3306a_read_reg(state, 0x1061, &val); | ||
1102 | if (ret) | ||
1103 | return ret; | ||
1104 | val &= 0xf8; | ||
1105 | if ((snrRef > 18) && (maxPowerMan > 0x68) | ||
1106 | && (nCombDet == 0x01) | ||
1107 | && ((fbDlyCir == 0x03FF) || (fbDlyCir < 0x6C))) { | ||
1108 | /* SNR is over 18dB and no ghosting */ | ||
1109 | val |= 0x00; /* final bandwidth = 0 */ | ||
1110 | } else { | ||
1111 | val |= 0x04; /* final bandwidth = 4 */ | ||
1112 | } | ||
1113 | ret = lgdt3306a_write_reg(state, 0x1061, val); | ||
1114 | if (ret) | ||
1115 | return ret; | ||
1116 | |||
1117 | /* Adjust Notch Filter */ | ||
1118 | ret = lgdt3306a_read_reg(state, 0x0024, &val); | ||
1119 | if (ret) | ||
1120 | return ret; | ||
1121 | val &= 0x0f; | ||
1122 | if (nCombDet == 0) { /* Turn on the Notch Filter */ | ||
1123 | val |= 0x50; | ||
1124 | } | ||
1125 | ret = lgdt3306a_write_reg(state, 0x0024, val); | ||
1126 | if (ret) | ||
1127 | return ret; | ||
1128 | |||
1129 | /* VSB Timing Recovery output normalization */ | ||
1130 | ret = lgdt3306a_read_reg(state, 0x103d, &val); | ||
1131 | if (ret) | ||
1132 | return ret; | ||
1133 | val &= 0xcf; | ||
1134 | val |= 0x20; | ||
1135 | ret = lgdt3306a_write_reg(state, 0x103d, val); | ||
1136 | |||
1137 | return ret; | ||
1138 | } | ||
1139 | |||
1140 | static enum lgdt3306a_modulation | ||
1141 | lgdt3306a_check_oper_mode(struct lgdt3306a_state *state) | ||
1142 | { | ||
1143 | u8 val = 0; | ||
1144 | int ret; | ||
1145 | |||
1146 | ret = lgdt3306a_read_reg(state, 0x0081, &val); | ||
1147 | if (ret) | ||
1148 | goto err; | ||
1149 | |||
1150 | if (val & 0x80) { | ||
1151 | dbg_info("VSB\n"); | ||
1152 | return LG3306_VSB; | ||
1153 | } | ||
1154 | if (val & 0x08) { | ||
1155 | ret = lgdt3306a_read_reg(state, 0x00a6, &val); | ||
1156 | if (ret) | ||
1157 | goto err; | ||
1158 | val = val >> 2; | ||
1159 | if (val & 0x01) { | ||
1160 | dbg_info("QAM256\n"); | ||
1161 | return LG3306_QAM256; | ||
1162 | } | ||
1163 | dbg_info("QAM64\n"); | ||
1164 | return LG3306_QAM64; | ||
1165 | } | ||
1166 | err: | ||
1167 | pr_warn("UNKNOWN\n"); | ||
1168 | return LG3306_UNKNOWN_MODE; | ||
1169 | } | ||
1170 | |||
1171 | static enum lgdt3306a_lock_status | ||
1172 | lgdt3306a_check_lock_status(struct lgdt3306a_state *state, | ||
1173 | enum lgdt3306a_lock_check whatLock) | ||
1174 | { | ||
1175 | u8 val = 0; | ||
1176 | int ret; | ||
1177 | enum lgdt3306a_modulation modeOper; | ||
1178 | enum lgdt3306a_lock_status lockStatus; | ||
1179 | |||
1180 | modeOper = LG3306_UNKNOWN_MODE; | ||
1181 | |||
1182 | switch (whatLock) { | ||
1183 | case LG3306_SYNC_LOCK: | ||
1184 | { | ||
1185 | ret = lgdt3306a_read_reg(state, 0x00a6, &val); | ||
1186 | if (ret) | ||
1187 | return ret; | ||
1188 | |||
1189 | if ((val & 0x80) == 0x80) | ||
1190 | lockStatus = LG3306_LOCK; | ||
1191 | else | ||
1192 | lockStatus = LG3306_UNLOCK; | ||
1193 | |||
1194 | dbg_info("SYNC_LOCK=%x\n", lockStatus); | ||
1195 | break; | ||
1196 | } | ||
1197 | case LG3306_AGC_LOCK: | ||
1198 | { | ||
1199 | ret = lgdt3306a_read_reg(state, 0x0080, &val); | ||
1200 | if (ret) | ||
1201 | return ret; | ||
1202 | |||
1203 | if ((val & 0x40) == 0x40) | ||
1204 | lockStatus = LG3306_LOCK; | ||
1205 | else | ||
1206 | lockStatus = LG3306_UNLOCK; | ||
1207 | |||
1208 | dbg_info("AGC_LOCK=%x\n", lockStatus); | ||
1209 | break; | ||
1210 | } | ||
1211 | case LG3306_TR_LOCK: | ||
1212 | { | ||
1213 | modeOper = lgdt3306a_check_oper_mode(state); | ||
1214 | if ((modeOper == LG3306_QAM64) || (modeOper == LG3306_QAM256)) { | ||
1215 | ret = lgdt3306a_read_reg(state, 0x1094, &val); | ||
1216 | if (ret) | ||
1217 | return ret; | ||
1218 | |||
1219 | if ((val & 0x80) == 0x80) | ||
1220 | lockStatus = LG3306_LOCK; | ||
1221 | else | ||
1222 | lockStatus = LG3306_UNLOCK; | ||
1223 | } else | ||
1224 | lockStatus = LG3306_UNKNOWN_LOCK; | ||
1225 | |||
1226 | dbg_info("TR_LOCK=%x\n", lockStatus); | ||
1227 | break; | ||
1228 | } | ||
1229 | case LG3306_FEC_LOCK: | ||
1230 | { | ||
1231 | modeOper = lgdt3306a_check_oper_mode(state); | ||
1232 | if ((modeOper == LG3306_QAM64) || (modeOper == LG3306_QAM256)) { | ||
1233 | ret = lgdt3306a_read_reg(state, 0x0080, &val); | ||
1234 | if (ret) | ||
1235 | return ret; | ||
1236 | |||
1237 | if ((val & 0x10) == 0x10) | ||
1238 | lockStatus = LG3306_LOCK; | ||
1239 | else | ||
1240 | lockStatus = LG3306_UNLOCK; | ||
1241 | } else | ||
1242 | lockStatus = LG3306_UNKNOWN_LOCK; | ||
1243 | |||
1244 | dbg_info("FEC_LOCK=%x\n", lockStatus); | ||
1245 | break; | ||
1246 | } | ||
1247 | |||
1248 | default: | ||
1249 | lockStatus = LG3306_UNKNOWN_LOCK; | ||
1250 | pr_warn("UNKNOWN whatLock=%d\n", whatLock); | ||
1251 | break; | ||
1252 | } | ||
1253 | |||
1254 | return lockStatus; | ||
1255 | } | ||
1256 | |||
1257 | static enum lgdt3306a_neverlock_status | ||
1258 | lgdt3306a_check_neverlock_status(struct lgdt3306a_state *state) | ||
1259 | { | ||
1260 | u8 val = 0; | ||
1261 | int ret; | ||
1262 | enum lgdt3306a_neverlock_status lockStatus; | ||
1263 | |||
1264 | ret = lgdt3306a_read_reg(state, 0x0080, &val); | ||
1265 | if (ret) | ||
1266 | return ret; | ||
1267 | lockStatus = (enum lgdt3306a_neverlock_status)(val & 0x03); | ||
1268 | |||
1269 | dbg_info("NeverLock=%d", lockStatus); | ||
1270 | |||
1271 | return lockStatus; | ||
1272 | } | ||
1273 | |||
1274 | static int lgdt3306a_pre_monitoring(struct lgdt3306a_state *state) | ||
1275 | { | ||
1276 | u8 val = 0; | ||
1277 | int ret; | ||
1278 | u8 currChDiffACQ, snrRef, mainStrong, aiccrejStatus; | ||
1279 | |||
1280 | /* Channel variation */ | ||
1281 | ret = lgdt3306a_read_reg(state, 0x21bc, &currChDiffACQ); | ||
1282 | if (ret) | ||
1283 | return ret; | ||
1284 | |||
1285 | /* SNR of Frame sync */ | ||
1286 | ret = lgdt3306a_read_reg(state, 0x21a1, &val); | ||
1287 | if (ret) | ||
1288 | return ret; | ||
1289 | snrRef = val & 0x3f; | ||
1290 | |||
1291 | /* Strong Main CIR */ | ||
1292 | ret = lgdt3306a_read_reg(state, 0x2199, &val); | ||
1293 | if (ret) | ||
1294 | return ret; | ||
1295 | mainStrong = (val & 0x40) >> 6; | ||
1296 | |||
1297 | ret = lgdt3306a_read_reg(state, 0x0090, &val); | ||
1298 | if (ret) | ||
1299 | return ret; | ||
1300 | aiccrejStatus = (val & 0xf0) >> 4; | ||
1301 | |||
1302 | dbg_info("snrRef=%d mainStrong=%d aiccrejStatus=%d currChDiffACQ=0x%x\n", | ||
1303 | snrRef, mainStrong, aiccrejStatus, currChDiffACQ); | ||
1304 | |||
1305 | #if 0 | ||
1306 | /* Dynamic ghost exists */ | ||
1307 | if ((mainStrong == 0) && (currChDiffACQ > 0x70)) | ||
1308 | #endif | ||
1309 | if (mainStrong == 0) { | ||
1310 | ret = lgdt3306a_read_reg(state, 0x2135, &val); | ||
1311 | if (ret) | ||
1312 | return ret; | ||
1313 | val &= 0x0f; | ||
1314 | val |= 0xa0; | ||
1315 | ret = lgdt3306a_write_reg(state, 0x2135, val); | ||
1316 | if (ret) | ||
1317 | return ret; | ||
1318 | |||
1319 | ret = lgdt3306a_read_reg(state, 0x2141, &val); | ||
1320 | if (ret) | ||
1321 | return ret; | ||
1322 | val &= 0x3f; | ||
1323 | val |= 0x80; | ||
1324 | ret = lgdt3306a_write_reg(state, 0x2141, val); | ||
1325 | if (ret) | ||
1326 | return ret; | ||
1327 | |||
1328 | ret = lgdt3306a_write_reg(state, 0x2122, 0x70); | ||
1329 | if (ret) | ||
1330 | return ret; | ||
1331 | } else { /* Weak ghost or static channel */ | ||
1332 | ret = lgdt3306a_read_reg(state, 0x2135, &val); | ||
1333 | if (ret) | ||
1334 | return ret; | ||
1335 | val &= 0x0f; | ||
1336 | val |= 0x70; | ||
1337 | ret = lgdt3306a_write_reg(state, 0x2135, val); | ||
1338 | if (ret) | ||
1339 | return ret; | ||
1340 | |||
1341 | ret = lgdt3306a_read_reg(state, 0x2141, &val); | ||
1342 | if (ret) | ||
1343 | return ret; | ||
1344 | val &= 0x3f; | ||
1345 | val |= 0x40; | ||
1346 | ret = lgdt3306a_write_reg(state, 0x2141, val); | ||
1347 | if (ret) | ||
1348 | return ret; | ||
1349 | |||
1350 | ret = lgdt3306a_write_reg(state, 0x2122, 0x40); | ||
1351 | if (ret) | ||
1352 | return ret; | ||
1353 | } | ||
1354 | return 0; | ||
1355 | } | ||
1356 | |||
1357 | static enum lgdt3306a_lock_status | ||
1358 | lgdt3306a_sync_lock_poll(struct lgdt3306a_state *state) | ||
1359 | { | ||
1360 | enum lgdt3306a_lock_status syncLockStatus = LG3306_UNLOCK; | ||
1361 | int i; | ||
1362 | |||
1363 | for (i = 0; i < 2; i++) { | ||
1364 | msleep(30); | ||
1365 | |||
1366 | syncLockStatus = lgdt3306a_check_lock_status(state, | ||
1367 | LG3306_SYNC_LOCK); | ||
1368 | |||
1369 | if (syncLockStatus == LG3306_LOCK) { | ||
1370 | dbg_info("locked(%d)\n", i); | ||
1371 | return LG3306_LOCK; | ||
1372 | } | ||
1373 | } | ||
1374 | dbg_info("not locked\n"); | ||
1375 | return LG3306_UNLOCK; | ||
1376 | } | ||
1377 | |||
1378 | static enum lgdt3306a_lock_status | ||
1379 | lgdt3306a_fec_lock_poll(struct lgdt3306a_state *state) | ||
1380 | { | ||
1381 | enum lgdt3306a_lock_status FECLockStatus = LG3306_UNLOCK; | ||
1382 | int i; | ||
1383 | |||
1384 | for (i = 0; i < 2; i++) { | ||
1385 | msleep(30); | ||
1386 | |||
1387 | FECLockStatus = lgdt3306a_check_lock_status(state, | ||
1388 | LG3306_FEC_LOCK); | ||
1389 | |||
1390 | if (FECLockStatus == LG3306_LOCK) { | ||
1391 | dbg_info("locked(%d)\n", i); | ||
1392 | return FECLockStatus; | ||
1393 | } | ||
1394 | } | ||
1395 | dbg_info("not locked\n"); | ||
1396 | return FECLockStatus; | ||
1397 | } | ||
1398 | |||
1399 | static enum lgdt3306a_neverlock_status | ||
1400 | lgdt3306a_neverlock_poll(struct lgdt3306a_state *state) | ||
1401 | { | ||
1402 | enum lgdt3306a_neverlock_status NLLockStatus = LG3306_NL_FAIL; | ||
1403 | int i; | ||
1404 | |||
1405 | for (i = 0; i < 5; i++) { | ||
1406 | msleep(30); | ||
1407 | |||
1408 | NLLockStatus = lgdt3306a_check_neverlock_status(state); | ||
1409 | |||
1410 | if (NLLockStatus == LG3306_NL_LOCK) { | ||
1411 | dbg_info("NL_LOCK(%d)\n", i); | ||
1412 | return NLLockStatus; | ||
1413 | } | ||
1414 | } | ||
1415 | dbg_info("NLLockStatus=%d\n", NLLockStatus); | ||
1416 | return NLLockStatus; | ||
1417 | } | ||
1418 | |||
1419 | static u8 lgdt3306a_get_packet_error(struct lgdt3306a_state *state) | ||
1420 | { | ||
1421 | u8 val; | ||
1422 | int ret; | ||
1423 | |||
1424 | ret = lgdt3306a_read_reg(state, 0x00fa, &val); | ||
1425 | if (ret) | ||
1426 | return ret; | ||
1427 | |||
1428 | return val; | ||
1429 | } | ||
1430 | |||
1431 | static const u32 valx_x10[] = { | ||
1432 | 10, 11, 13, 15, 17, 20, 25, 33, 41, 50, 59, 73, 87, 100 | ||
1433 | }; | ||
1434 | static const u32 log10x_x1000[] = { | ||
1435 | 0, 41, 114, 176, 230, 301, 398, 518, 613, 699, 771, 863, 939, 1000 | ||
1436 | }; | ||
1437 | |||
1438 | static u32 log10_x1000(u32 x) | ||
1439 | { | ||
1440 | u32 diff_val, step_val, step_log10; | ||
1441 | u32 log_val = 0; | ||
1442 | u32 i; | ||
1443 | |||
1444 | if (x <= 0) | ||
1445 | return -1000000; /* signal error */ | ||
1446 | |||
1447 | if (x == 10) | ||
1448 | return 0; /* log(1)=0 */ | ||
1449 | |||
1450 | if (x < 10) { | ||
1451 | while (x < 10) { | ||
1452 | x = x * 10; | ||
1453 | log_val--; | ||
1454 | } | ||
1455 | } else { /* x > 10 */ | ||
1456 | while (x >= 100) { | ||
1457 | x = x / 10; | ||
1458 | log_val++; | ||
1459 | } | ||
1460 | } | ||
1461 | log_val *= 1000; | ||
1462 | |||
1463 | if (x == 10) /* was our input an exact multiple of 10 */ | ||
1464 | return log_val; /* don't need to interpolate */ | ||
1465 | |||
1466 | /* find our place on the log curve */ | ||
1467 | for (i = 1; i < ARRAY_SIZE(valx_x10); i++) { | ||
1468 | if (valx_x10[i] >= x) | ||
1469 | break; | ||
1470 | } | ||
1471 | if (i == ARRAY_SIZE(valx_x10)) | ||
1472 | return log_val + log10x_x1000[i - 1]; | ||
1473 | |||
1474 | diff_val = x - valx_x10[i-1]; | ||
1475 | step_val = valx_x10[i] - valx_x10[i - 1]; | ||
1476 | step_log10 = log10x_x1000[i] - log10x_x1000[i - 1]; | ||
1477 | |||
1478 | /* do a linear interpolation to get in-between values */ | ||
1479 | return log_val + log10x_x1000[i - 1] + | ||
1480 | ((diff_val*step_log10) / step_val); | ||
1481 | } | ||
1482 | |||
1483 | static u32 lgdt3306a_calculate_snr_x100(struct lgdt3306a_state *state) | ||
1484 | { | ||
1485 | u32 mse; /* Mean-Square Error */ | ||
1486 | u32 pwr; /* Constelation power */ | ||
1487 | u32 snr_x100; | ||
1488 | |||
1489 | mse = (read_reg(state, 0x00ec) << 8) | | ||
1490 | (read_reg(state, 0x00ed)); | ||
1491 | pwr = (read_reg(state, 0x00e8) << 8) | | ||
1492 | (read_reg(state, 0x00e9)); | ||
1493 | |||
1494 | if (mse == 0) /* no signal */ | ||
1495 | return 0; | ||
1496 | |||
1497 | snr_x100 = log10_x1000((pwr * 10000) / mse) - 3000; | ||
1498 | dbg_info("mse=%u, pwr=%u, snr_x100=%d\n", mse, pwr, snr_x100); | ||
1499 | |||
1500 | return snr_x100; | ||
1501 | } | ||
1502 | |||
1503 | static enum lgdt3306a_lock_status | ||
1504 | lgdt3306a_vsb_lock_poll(struct lgdt3306a_state *state) | ||
1505 | { | ||
1506 | int ret; | ||
1507 | u8 cnt = 0; | ||
1508 | u8 packet_error; | ||
1509 | u32 snr; | ||
1510 | |||
1511 | for (cnt = 0; cnt < 10; cnt++) { | ||
1512 | if (lgdt3306a_sync_lock_poll(state) == LG3306_UNLOCK) { | ||
1513 | dbg_info("no sync lock!\n"); | ||
1514 | return LG3306_UNLOCK; | ||
1515 | } | ||
1516 | |||
1517 | msleep(20); | ||
1518 | ret = lgdt3306a_pre_monitoring(state); | ||
1519 | if (ret) | ||
1520 | break; | ||
1521 | |||
1522 | packet_error = lgdt3306a_get_packet_error(state); | ||
1523 | snr = lgdt3306a_calculate_snr_x100(state); | ||
1524 | dbg_info("cnt=%d errors=%d snr=%d\n", cnt, packet_error, snr); | ||
1525 | |||
1526 | if ((snr >= 1500) && (packet_error < 0xff)) | ||
1527 | return LG3306_LOCK; | ||
1528 | } | ||
1529 | |||
1530 | dbg_info("not locked!\n"); | ||
1531 | return LG3306_UNLOCK; | ||
1532 | } | ||
1533 | |||
1534 | static enum lgdt3306a_lock_status | ||
1535 | lgdt3306a_qam_lock_poll(struct lgdt3306a_state *state) | ||
1536 | { | ||
1537 | u8 cnt; | ||
1538 | u8 packet_error; | ||
1539 | u32 snr; | ||
1540 | |||
1541 | for (cnt = 0; cnt < 10; cnt++) { | ||
1542 | if (lgdt3306a_fec_lock_poll(state) == LG3306_UNLOCK) { | ||
1543 | dbg_info("no fec lock!\n"); | ||
1544 | return LG3306_UNLOCK; | ||
1545 | } | ||
1546 | |||
1547 | msleep(20); | ||
1548 | |||
1549 | packet_error = lgdt3306a_get_packet_error(state); | ||
1550 | snr = lgdt3306a_calculate_snr_x100(state); | ||
1551 | dbg_info("cnt=%d errors=%d snr=%d\n", cnt, packet_error, snr); | ||
1552 | |||
1553 | if ((snr >= 1500) && (packet_error < 0xff)) | ||
1554 | return LG3306_LOCK; | ||
1555 | } | ||
1556 | |||
1557 | dbg_info("not locked!\n"); | ||
1558 | return LG3306_UNLOCK; | ||
1559 | } | ||
1560 | |||
1561 | static int lgdt3306a_read_status(struct dvb_frontend *fe, fe_status_t *status) | ||
1562 | { | ||
1563 | struct lgdt3306a_state *state = fe->demodulator_priv; | ||
1564 | u16 strength = 0; | ||
1565 | int ret = 0; | ||
1566 | |||
1567 | if (fe->ops.tuner_ops.get_rf_strength) { | ||
1568 | ret = fe->ops.tuner_ops.get_rf_strength(fe, &strength); | ||
1569 | if (ret == 0) | ||
1570 | dbg_info("strength=%d\n", strength); | ||
1571 | else | ||
1572 | dbg_info("fe->ops.tuner_ops.get_rf_strength() failed\n"); | ||
1573 | } | ||
1574 | |||
1575 | *status = 0; | ||
1576 | if (lgdt3306a_neverlock_poll(state) == LG3306_NL_LOCK) { | ||
1577 | *status |= FE_HAS_SIGNAL; | ||
1578 | *status |= FE_HAS_CARRIER; | ||
1579 | |||
1580 | switch (state->current_modulation) { | ||
1581 | case QAM_256: | ||
1582 | case QAM_64: | ||
1583 | if (lgdt3306a_qam_lock_poll(state) == LG3306_LOCK) { | ||
1584 | *status |= FE_HAS_VITERBI; | ||
1585 | *status |= FE_HAS_SYNC; | ||
1586 | |||
1587 | *status |= FE_HAS_LOCK; | ||
1588 | } | ||
1589 | break; | ||
1590 | case VSB_8: | ||
1591 | if (lgdt3306a_vsb_lock_poll(state) == LG3306_LOCK) { | ||
1592 | *status |= FE_HAS_VITERBI; | ||
1593 | *status |= FE_HAS_SYNC; | ||
1594 | |||
1595 | *status |= FE_HAS_LOCK; | ||
1596 | |||
1597 | ret = lgdt3306a_monitor_vsb(state); | ||
1598 | } | ||
1599 | break; | ||
1600 | default: | ||
1601 | ret = -EINVAL; | ||
1602 | } | ||
1603 | } | ||
1604 | return ret; | ||
1605 | } | ||
1606 | |||
1607 | |||
1608 | static int lgdt3306a_read_snr(struct dvb_frontend *fe, u16 *snr) | ||
1609 | { | ||
1610 | struct lgdt3306a_state *state = fe->demodulator_priv; | ||
1611 | |||
1612 | state->snr = lgdt3306a_calculate_snr_x100(state); | ||
1613 | /* report SNR in dB * 10 */ | ||
1614 | *snr = state->snr/10; | ||
1615 | |||
1616 | return 0; | ||
1617 | } | ||
1618 | |||
1619 | static int lgdt3306a_read_signal_strength(struct dvb_frontend *fe, | ||
1620 | u16 *strength) | ||
1621 | { | ||
1622 | /* | ||
1623 | * Calculate some sort of "strength" from SNR | ||
1624 | */ | ||
1625 | struct lgdt3306a_state *state = fe->demodulator_priv; | ||
1626 | u16 snr; /* snr_x10 */ | ||
1627 | int ret; | ||
1628 | u32 ref_snr; /* snr*100 */ | ||
1629 | u32 str; | ||
1630 | |||
1631 | *strength = 0; | ||
1632 | |||
1633 | switch (state->current_modulation) { | ||
1634 | case VSB_8: | ||
1635 | ref_snr = 1600; /* 16dB */ | ||
1636 | break; | ||
1637 | case QAM_64: | ||
1638 | ref_snr = 2200; /* 22dB */ | ||
1639 | break; | ||
1640 | case QAM_256: | ||
1641 | ref_snr = 2800; /* 28dB */ | ||
1642 | break; | ||
1643 | default: | ||
1644 | return -EINVAL; | ||
1645 | } | ||
1646 | |||
1647 | ret = fe->ops.read_snr(fe, &snr); | ||
1648 | if (lg_chkerr(ret)) | ||
1649 | goto fail; | ||
1650 | |||
1651 | if (state->snr <= (ref_snr - 100)) | ||
1652 | str = 0; | ||
1653 | else if (state->snr <= ref_snr) | ||
1654 | str = (0xffff * 65) / 100; /* 65% */ | ||
1655 | else { | ||
1656 | str = state->snr - ref_snr; | ||
1657 | str /= 50; | ||
1658 | str += 78; /* 78%-100% */ | ||
1659 | if (str > 100) | ||
1660 | str = 100; | ||
1661 | str = (0xffff * str) / 100; | ||
1662 | } | ||
1663 | *strength = (u16)str; | ||
1664 | dbg_info("strength=%u\n", *strength); | ||
1665 | |||
1666 | fail: | ||
1667 | return ret; | ||
1668 | } | ||
1669 | |||
1670 | /* ------------------------------------------------------------------------ */ | ||
1671 | |||
1672 | static int lgdt3306a_read_ber(struct dvb_frontend *fe, u32 *ber) | ||
1673 | { | ||
1674 | struct lgdt3306a_state *state = fe->demodulator_priv; | ||
1675 | u32 tmp; | ||
1676 | |||
1677 | *ber = 0; | ||
1678 | #if 1 | ||
1679 | /* FGR - FIXME - I don't know what value is expected by dvb_core | ||
1680 | * what is the scale of the value?? */ | ||
1681 | tmp = read_reg(state, 0x00fc); /* NBERVALUE[24-31] */ | ||
1682 | tmp = (tmp << 8) | read_reg(state, 0x00fd); /* NBERVALUE[16-23] */ | ||
1683 | tmp = (tmp << 8) | read_reg(state, 0x00fe); /* NBERVALUE[8-15] */ | ||
1684 | tmp = (tmp << 8) | read_reg(state, 0x00ff); /* NBERVALUE[0-7] */ | ||
1685 | *ber = tmp; | ||
1686 | dbg_info("ber=%u\n", tmp); | ||
1687 | #endif | ||
1688 | return 0; | ||
1689 | } | ||
1690 | |||
1691 | static int lgdt3306a_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) | ||
1692 | { | ||
1693 | struct lgdt3306a_state *state = fe->demodulator_priv; | ||
1694 | |||
1695 | *ucblocks = 0; | ||
1696 | #if 1 | ||
1697 | /* FGR - FIXME - I don't know what value is expected by dvb_core | ||
1698 | * what happens when value wraps? */ | ||
1699 | *ucblocks = read_reg(state, 0x00f4); /* TPIFTPERRCNT[0-7] */ | ||
1700 | dbg_info("ucblocks=%u\n", *ucblocks); | ||
1701 | #endif | ||
1702 | |||
1703 | return 0; | ||
1704 | } | ||
1705 | |||
1706 | static int lgdt3306a_tune(struct dvb_frontend *fe, bool re_tune, | ||
1707 | unsigned int mode_flags, unsigned int *delay, | ||
1708 | fe_status_t *status) | ||
1709 | { | ||
1710 | int ret = 0; | ||
1711 | struct lgdt3306a_state *state = fe->demodulator_priv; | ||
1712 | |||
1713 | dbg_info("re_tune=%u\n", re_tune); | ||
1714 | |||
1715 | if (re_tune) { | ||
1716 | state->current_frequency = -1; /* force re-tune */ | ||
1717 | ret = lgdt3306a_set_parameters(fe); | ||
1718 | if (ret != 0) | ||
1719 | return ret; | ||
1720 | } | ||
1721 | *delay = 125; | ||
1722 | ret = lgdt3306a_read_status(fe, status); | ||
1723 | |||
1724 | return ret; | ||
1725 | } | ||
1726 | |||
1727 | static int lgdt3306a_get_tune_settings(struct dvb_frontend *fe, | ||
1728 | struct dvb_frontend_tune_settings | ||
1729 | *fe_tune_settings) | ||
1730 | { | ||
1731 | fe_tune_settings->min_delay_ms = 100; | ||
1732 | dbg_info("\n"); | ||
1733 | return 0; | ||
1734 | } | ||
1735 | |||
1736 | static int lgdt3306a_search(struct dvb_frontend *fe) | ||
1737 | { | ||
1738 | fe_status_t status = 0; | ||
1739 | int i, ret; | ||
1740 | |||
1741 | /* set frontend */ | ||
1742 | ret = lgdt3306a_set_parameters(fe); | ||
1743 | if (ret) | ||
1744 | goto error; | ||
1745 | |||
1746 | /* wait frontend lock */ | ||
1747 | for (i = 20; i > 0; i--) { | ||
1748 | dbg_info(": loop=%d\n", i); | ||
1749 | msleep(50); | ||
1750 | ret = lgdt3306a_read_status(fe, &status); | ||
1751 | if (ret) | ||
1752 | goto error; | ||
1753 | |||
1754 | if (status & FE_HAS_LOCK) | ||
1755 | break; | ||
1756 | } | ||
1757 | |||
1758 | /* check if we have a valid signal */ | ||
1759 | if (status & FE_HAS_LOCK) | ||
1760 | return DVBFE_ALGO_SEARCH_SUCCESS; | ||
1761 | else | ||
1762 | return DVBFE_ALGO_SEARCH_AGAIN; | ||
1763 | |||
1764 | error: | ||
1765 | dbg_info("failed (%d)\n", ret); | ||
1766 | return DVBFE_ALGO_SEARCH_ERROR; | ||
1767 | } | ||
1768 | |||
1769 | static void lgdt3306a_release(struct dvb_frontend *fe) | ||
1770 | { | ||
1771 | struct lgdt3306a_state *state = fe->demodulator_priv; | ||
1772 | |||
1773 | dbg_info("\n"); | ||
1774 | kfree(state); | ||
1775 | } | ||
1776 | |||
1777 | static struct dvb_frontend_ops lgdt3306a_ops; | ||
1778 | |||
1779 | struct dvb_frontend *lgdt3306a_attach(const struct lgdt3306a_config *config, | ||
1780 | struct i2c_adapter *i2c_adap) | ||
1781 | { | ||
1782 | struct lgdt3306a_state *state = NULL; | ||
1783 | int ret; | ||
1784 | u8 val; | ||
1785 | |||
1786 | dbg_info("(%d-%04x)\n", | ||
1787 | i2c_adap ? i2c_adapter_id(i2c_adap) : 0, | ||
1788 | config ? config->i2c_addr : 0); | ||
1789 | |||
1790 | state = kzalloc(sizeof(struct lgdt3306a_state), GFP_KERNEL); | ||
1791 | if (state == NULL) | ||
1792 | goto fail; | ||
1793 | |||
1794 | state->cfg = config; | ||
1795 | state->i2c_adap = i2c_adap; | ||
1796 | |||
1797 | memcpy(&state->frontend.ops, &lgdt3306a_ops, | ||
1798 | sizeof(struct dvb_frontend_ops)); | ||
1799 | state->frontend.demodulator_priv = state; | ||
1800 | |||
1801 | /* verify that we're talking to a lg3306a */ | ||
1802 | /* FGR - NOTE - there is no obvious ChipId to check; we check | ||
1803 | * some "known" bits after reset, but it's still just a guess */ | ||
1804 | ret = lgdt3306a_read_reg(state, 0x0000, &val); | ||
1805 | if (lg_chkerr(ret)) | ||
1806 | goto fail; | ||
1807 | if ((val & 0x74) != 0x74) { | ||
1808 | pr_warn("expected 0x74, got 0x%x\n", (val & 0x74)); | ||
1809 | #if 0 | ||
1810 | /* FIXME - re-enable when we know this is right */ | ||
1811 | goto fail; | ||
1812 | #endif | ||
1813 | } | ||
1814 | ret = lgdt3306a_read_reg(state, 0x0001, &val); | ||
1815 | if (lg_chkerr(ret)) | ||
1816 | goto fail; | ||
1817 | if ((val & 0xf6) != 0xc6) { | ||
1818 | pr_warn("expected 0xc6, got 0x%x\n", (val & 0xf6)); | ||
1819 | #if 0 | ||
1820 | /* FIXME - re-enable when we know this is right */ | ||
1821 | goto fail; | ||
1822 | #endif | ||
1823 | } | ||
1824 | ret = lgdt3306a_read_reg(state, 0x0002, &val); | ||
1825 | if (lg_chkerr(ret)) | ||
1826 | goto fail; | ||
1827 | if ((val & 0x73) != 0x03) { | ||
1828 | pr_warn("expected 0x03, got 0x%x\n", (val & 0x73)); | ||
1829 | #if 0 | ||
1830 | /* FIXME - re-enable when we know this is right */ | ||
1831 | goto fail; | ||
1832 | #endif | ||
1833 | } | ||
1834 | |||
1835 | state->current_frequency = -1; | ||
1836 | state->current_modulation = -1; | ||
1837 | |||
1838 | lgdt3306a_sleep(state); | ||
1839 | |||
1840 | return &state->frontend; | ||
1841 | |||
1842 | fail: | ||
1843 | pr_warn("unable to detect LGDT3306A hardware\n"); | ||
1844 | kfree(state); | ||
1845 | return NULL; | ||
1846 | } | ||
1847 | EXPORT_SYMBOL(lgdt3306a_attach); | ||
1848 | |||
1849 | #ifdef DBG_DUMP | ||
1850 | |||
1851 | static const short regtab[] = { | ||
1852 | 0x0000, /* SOFTRSTB 1'b1 1'b1 1'b1 ADCPDB 1'b1 PLLPDB GBBPDB 11111111 */ | ||
1853 | 0x0001, /* 1'b1 1'b1 1'b0 1'b0 AUTORPTRS */ | ||
1854 | 0x0002, /* NI2CRPTEN 1'b0 1'b0 1'b0 SPECINVAUT */ | ||
1855 | 0x0003, /* AGCRFOUT */ | ||
1856 | 0x0004, /* ADCSEL1V ADCCNT ADCCNF ADCCNS ADCCLKPLL */ | ||
1857 | 0x0005, /* PLLINDIVSE */ | ||
1858 | 0x0006, /* PLLCTRL[7:0] 11100001 */ | ||
1859 | 0x0007, /* SYSINITWAITTIME[7:0] (msec) 00001000 */ | ||
1860 | 0x0008, /* STDOPMODE[7:0] 10000000 */ | ||
1861 | 0x0009, /* 1'b0 1'b0 1'b0 STDOPDETTMODE[2:0] STDOPDETCMODE[1:0] 00011110 */ | ||
1862 | 0x000a, /* DAFTEN 1'b1 x x SCSYSLOCK */ | ||
1863 | 0x000b, /* SCSYSLOCKCHKTIME[7:0] (10msec) 01100100 */ | ||
1864 | 0x000d, /* x SAMPLING4 */ | ||
1865 | 0x000e, /* SAMFREQ[15:8] 00000000 */ | ||
1866 | 0x000f, /* SAMFREQ[7:0] 00000000 */ | ||
1867 | 0x0010, /* IFFREQ[15:8] 01100000 */ | ||
1868 | 0x0011, /* IFFREQ[7:0] 00000000 */ | ||
1869 | 0x0012, /* AGCEN AGCREFMO */ | ||
1870 | 0x0013, /* AGCRFFIXB AGCIFFIXB AGCLOCKDETRNGSEL[1:0] 1'b1 1'b0 1'b0 1'b0 11101000 */ | ||
1871 | 0x0014, /* AGCFIXVALUE[7:0] 01111111 */ | ||
1872 | 0x0015, /* AGCREF[15:8] 00001010 */ | ||
1873 | 0x0016, /* AGCREF[7:0] 11100100 */ | ||
1874 | 0x0017, /* AGCDELAY[7:0] 00100000 */ | ||
1875 | 0x0018, /* AGCRFBW[3:0] AGCIFBW[3:0] 10001000 */ | ||
1876 | 0x0019, /* AGCUDOUTMODE[1:0] AGCUDCTRLLEN[1:0] AGCUDCTRL */ | ||
1877 | 0x001c, /* 1'b1 PFEN MFEN AICCVSYNC */ | ||
1878 | 0x001d, /* 1'b0 1'b1 1'b0 1'b1 AICCVSYNC */ | ||
1879 | 0x001e, /* AICCALPHA[3:0] 1'b1 1'b0 1'b1 1'b0 01111010 */ | ||
1880 | 0x001f, /* AICCDETTH[19:16] AICCOFFTH[19:16] 00000000 */ | ||
1881 | 0x0020, /* AICCDETTH[15:8] 01111100 */ | ||
1882 | 0x0021, /* AICCDETTH[7:0] 00000000 */ | ||
1883 | 0x0022, /* AICCOFFTH[15:8] 00000101 */ | ||
1884 | 0x0023, /* AICCOFFTH[7:0] 11100000 */ | ||
1885 | 0x0024, /* AICCOPMODE3[1:0] AICCOPMODE2[1:0] AICCOPMODE1[1:0] AICCOPMODE0[1:0] 00000000 */ | ||
1886 | 0x0025, /* AICCFIXFREQ3[23:16] 00000000 */ | ||
1887 | 0x0026, /* AICCFIXFREQ3[15:8] 00000000 */ | ||
1888 | 0x0027, /* AICCFIXFREQ3[7:0] 00000000 */ | ||
1889 | 0x0028, /* AICCFIXFREQ2[23:16] 00000000 */ | ||
1890 | 0x0029, /* AICCFIXFREQ2[15:8] 00000000 */ | ||
1891 | 0x002a, /* AICCFIXFREQ2[7:0] 00000000 */ | ||
1892 | 0x002b, /* AICCFIXFREQ1[23:16] 00000000 */ | ||
1893 | 0x002c, /* AICCFIXFREQ1[15:8] 00000000 */ | ||
1894 | 0x002d, /* AICCFIXFREQ1[7:0] 00000000 */ | ||
1895 | 0x002e, /* AICCFIXFREQ0[23:16] 00000000 */ | ||
1896 | 0x002f, /* AICCFIXFREQ0[15:8] 00000000 */ | ||
1897 | 0x0030, /* AICCFIXFREQ0[7:0] 00000000 */ | ||
1898 | 0x0031, /* 1'b0 1'b1 1'b0 1'b0 x DAGC1STER */ | ||
1899 | 0x0032, /* DAGC1STEN DAGC1STER */ | ||
1900 | 0x0033, /* DAGC1STREF[15:8] 00001010 */ | ||
1901 | 0x0034, /* DAGC1STREF[7:0] 11100100 */ | ||
1902 | 0x0035, /* DAGC2NDE */ | ||
1903 | 0x0036, /* DAGC2NDREF[15:8] 00001010 */ | ||
1904 | 0x0037, /* DAGC2NDREF[7:0] 10000000 */ | ||
1905 | 0x0038, /* DAGC2NDLOCKDETRNGSEL[1:0] */ | ||
1906 | 0x003d, /* 1'b1 SAMGEARS */ | ||
1907 | 0x0040, /* SAMLFGMA */ | ||
1908 | 0x0041, /* SAMLFBWM */ | ||
1909 | 0x0044, /* 1'b1 CRGEARSHE */ | ||
1910 | 0x0045, /* CRLFGMAN */ | ||
1911 | 0x0046, /* CFLFBWMA */ | ||
1912 | 0x0047, /* CRLFGMAN */ | ||
1913 | 0x0048, /* x x x x CRLFGSTEP_VS[3:0] xxxx1001 */ | ||
1914 | 0x0049, /* CRLFBWMA */ | ||
1915 | 0x004a, /* CRLFBWMA */ | ||
1916 | 0x0050, /* 1'b0 1'b1 1'b1 1'b0 MSECALCDA */ | ||
1917 | 0x0070, /* TPOUTEN TPIFEN TPCLKOUTE */ | ||
1918 | 0x0071, /* TPSENB TPSSOPBITE */ | ||
1919 | 0x0073, /* TP47HINS x x CHBERINT PERMODE[1:0] PERINT[1:0] 1xx11100 */ | ||
1920 | 0x0075, /* x x x x x IQSWAPCTRL[2:0] xxxxx000 */ | ||
1921 | 0x0076, /* NBERCON NBERST NBERPOL NBERWSYN */ | ||
1922 | 0x0077, /* x NBERLOSTTH[2:0] NBERACQTH[3:0] x0000000 */ | ||
1923 | 0x0078, /* NBERPOLY[31:24] 00000000 */ | ||
1924 | 0x0079, /* NBERPOLY[23:16] 00000000 */ | ||
1925 | 0x007a, /* NBERPOLY[15:8] 00000000 */ | ||
1926 | 0x007b, /* NBERPOLY[7:0] 00000000 */ | ||
1927 | 0x007c, /* NBERPED[31:24] 00000000 */ | ||
1928 | 0x007d, /* NBERPED[23:16] 00000000 */ | ||
1929 | 0x007e, /* NBERPED[15:8] 00000000 */ | ||
1930 | 0x007f, /* NBERPED[7:0] 00000000 */ | ||
1931 | 0x0080, /* x AGCLOCK DAGCLOCK SYSLOCK x x NEVERLOCK[1:0] */ | ||
1932 | 0x0085, /* SPECINVST */ | ||
1933 | 0x0088, /* SYSLOCKTIME[15:8] */ | ||
1934 | 0x0089, /* SYSLOCKTIME[7:0] */ | ||
1935 | 0x008c, /* FECLOCKTIME[15:8] */ | ||
1936 | 0x008d, /* FECLOCKTIME[7:0] */ | ||
1937 | 0x008e, /* AGCACCOUT[15:8] */ | ||
1938 | 0x008f, /* AGCACCOUT[7:0] */ | ||
1939 | 0x0090, /* AICCREJSTATUS[3:0] AICCREJBUSY[3:0] */ | ||
1940 | 0x0091, /* AICCVSYNC */ | ||
1941 | 0x009c, /* CARRFREQOFFSET[15:8] */ | ||
1942 | 0x009d, /* CARRFREQOFFSET[7:0] */ | ||
1943 | 0x00a1, /* SAMFREQOFFSET[23:16] */ | ||
1944 | 0x00a2, /* SAMFREQOFFSET[15:8] */ | ||
1945 | 0x00a3, /* SAMFREQOFFSET[7:0] */ | ||
1946 | 0x00a6, /* SYNCLOCK SYNCLOCKH */ | ||
1947 | #if 0 /* covered elsewhere */ | ||
1948 | 0x00e8, /* CONSTPWR[15:8] */ | ||
1949 | 0x00e9, /* CONSTPWR[7:0] */ | ||
1950 | 0x00ea, /* BMSE[15:8] */ | ||
1951 | 0x00eb, /* BMSE[7:0] */ | ||
1952 | 0x00ec, /* MSE[15:8] */ | ||
1953 | 0x00ed, /* MSE[7:0] */ | ||
1954 | 0x00ee, /* CONSTI[7:0] */ | ||
1955 | 0x00ef, /* CONSTQ[7:0] */ | ||
1956 | #endif | ||
1957 | 0x00f4, /* TPIFTPERRCNT[7:0] */ | ||
1958 | 0x00f5, /* TPCORREC */ | ||
1959 | 0x00f6, /* VBBER[15:8] */ | ||
1960 | 0x00f7, /* VBBER[7:0] */ | ||
1961 | 0x00f8, /* VABER[15:8] */ | ||
1962 | 0x00f9, /* VABER[7:0] */ | ||
1963 | 0x00fa, /* TPERRCNT[7:0] */ | ||
1964 | 0x00fb, /* NBERLOCK x x x x x x x */ | ||
1965 | 0x00fc, /* NBERVALUE[31:24] */ | ||
1966 | 0x00fd, /* NBERVALUE[23:16] */ | ||
1967 | 0x00fe, /* NBERVALUE[15:8] */ | ||
1968 | 0x00ff, /* NBERVALUE[7:0] */ | ||
1969 | 0x1000, /* 1'b0 WODAGCOU */ | ||
1970 | 0x1005, /* x x 1'b1 1'b1 x SRD_Q_QM */ | ||
1971 | 0x1009, /* SRDWAITTIME[7:0] (10msec) 00100011 */ | ||
1972 | 0x100a, /* SRDWAITTIME_CQS[7:0] (msec) 01100100 */ | ||
1973 | 0x101a, /* x 1'b1 1'b0 1'b0 x QMDQAMMODE[2:0] x100x010 */ | ||
1974 | 0x1036, /* 1'b0 1'b1 1'b0 1'b0 SAMGSEND_CQS[3:0] 01001110 */ | ||
1975 | 0x103c, /* SAMGSAUTOSTL_V[3:0] SAMGSAUTOEDL_V[3:0] 01000110 */ | ||
1976 | 0x103d, /* 1'b1 1'b1 SAMCNORMBP_V[1:0] 1'b0 1'b0 SAMMODESEL_V[1:0] 11100001 */ | ||
1977 | 0x103f, /* SAMZTEDSE */ | ||
1978 | 0x105d, /* EQSTATUSE */ | ||
1979 | 0x105f, /* x PMAPG2_V[2:0] x DMAPG2_V[2:0] x001x011 */ | ||
1980 | 0x1060, /* 1'b1 EQSTATUSE */ | ||
1981 | 0x1061, /* CRMAPBWSTL_V[3:0] CRMAPBWEDL_V[3:0] 00000100 */ | ||
1982 | 0x1065, /* 1'b0 x CRMODE_V[1:0] 1'b1 x 1'b1 x 0x111x1x */ | ||
1983 | 0x1066, /* 1'b0 1'b0 1'b1 1'b0 1'b1 PNBOOSTSE */ | ||
1984 | 0x1068, /* CREPHNGAIN2_V[3:0] CREPHNPBW_V[3:0] 10010001 */ | ||
1985 | 0x106e, /* x x x x x CREPHNEN_ */ | ||
1986 | 0x106f, /* CREPHNTH_V[7:0] 00010101 */ | ||
1987 | 0x1072, /* CRSWEEPN */ | ||
1988 | 0x1073, /* CRPGAIN_V[3:0] x x 1'b1 1'b1 1001xx11 */ | ||
1989 | 0x1074, /* CRPBW_V[3:0] x x 1'b1 1'b1 0001xx11 */ | ||
1990 | 0x1080, /* DAFTSTATUS[1:0] x x x x x x */ | ||
1991 | 0x1081, /* SRDSTATUS[1:0] x x x x x SRDLOCK */ | ||
1992 | 0x10a9, /* EQSTATUS_CQS[1:0] x x x x x x */ | ||
1993 | 0x10b7, /* EQSTATUS_V[1:0] x x x x x x */ | ||
1994 | #if 0 /* SMART_ANT */ | ||
1995 | 0x1f00, /* MODEDETE */ | ||
1996 | 0x1f01, /* x x x x x x x SFNRST xxxxxxx0 */ | ||
1997 | 0x1f03, /* NUMOFANT[7:0] 10000000 */ | ||
1998 | 0x1f04, /* x SELMASK[6:0] x0000000 */ | ||
1999 | 0x1f05, /* x SETMASK[6:0] x0000000 */ | ||
2000 | 0x1f06, /* x TXDATA[6:0] x0000000 */ | ||
2001 | 0x1f07, /* x CHNUMBER[6:0] x0000000 */ | ||
2002 | 0x1f09, /* AGCTIME[23:16] 10011000 */ | ||
2003 | 0x1f0a, /* AGCTIME[15:8] 10010110 */ | ||
2004 | 0x1f0b, /* AGCTIME[7:0] 10000000 */ | ||
2005 | 0x1f0c, /* ANTTIME[31:24] 00000000 */ | ||
2006 | 0x1f0d, /* ANTTIME[23:16] 00000011 */ | ||
2007 | 0x1f0e, /* ANTTIME[15:8] 10010000 */ | ||
2008 | 0x1f0f, /* ANTTIME[7:0] 10010000 */ | ||
2009 | 0x1f11, /* SYNCTIME[23:16] 10011000 */ | ||
2010 | 0x1f12, /* SYNCTIME[15:8] 10010110 */ | ||
2011 | 0x1f13, /* SYNCTIME[7:0] 10000000 */ | ||
2012 | 0x1f14, /* SNRTIME[31:24] 00000001 */ | ||
2013 | 0x1f15, /* SNRTIME[23:16] 01111101 */ | ||
2014 | 0x1f16, /* SNRTIME[15:8] 01111000 */ | ||
2015 | 0x1f17, /* SNRTIME[7:0] 01000000 */ | ||
2016 | 0x1f19, /* FECTIME[23:16] 00000000 */ | ||
2017 | 0x1f1a, /* FECTIME[15:8] 01110010 */ | ||
2018 | 0x1f1b, /* FECTIME[7:0] 01110000 */ | ||
2019 | 0x1f1d, /* FECTHD[7:0] 00000011 */ | ||
2020 | 0x1f1f, /* SNRTHD[23:16] 00001000 */ | ||
2021 | 0x1f20, /* SNRTHD[15:8] 01111111 */ | ||
2022 | 0x1f21, /* SNRTHD[7:0] 10000101 */ | ||
2023 | 0x1f80, /* IRQFLG x x SFSDRFLG MODEBFLG SAVEFLG SCANFLG TRACKFLG */ | ||
2024 | 0x1f81, /* x SYNCCON SNRCON FECCON x STDBUSY SYNCRST AGCFZCO */ | ||
2025 | 0x1f82, /* x x x SCANOPCD[4:0] */ | ||
2026 | 0x1f83, /* x x x x MAINOPCD[3:0] */ | ||
2027 | 0x1f84, /* x x RXDATA[13:8] */ | ||
2028 | 0x1f85, /* RXDATA[7:0] */ | ||
2029 | 0x1f86, /* x x SDTDATA[13:8] */ | ||
2030 | 0x1f87, /* SDTDATA[7:0] */ | ||
2031 | 0x1f89, /* ANTSNR[23:16] */ | ||
2032 | 0x1f8a, /* ANTSNR[15:8] */ | ||
2033 | 0x1f8b, /* ANTSNR[7:0] */ | ||
2034 | 0x1f8c, /* x x x x ANTFEC[13:8] */ | ||
2035 | 0x1f8d, /* ANTFEC[7:0] */ | ||
2036 | 0x1f8e, /* MAXCNT[7:0] */ | ||
2037 | 0x1f8f, /* SCANCNT[7:0] */ | ||
2038 | 0x1f91, /* MAXPW[23:16] */ | ||
2039 | 0x1f92, /* MAXPW[15:8] */ | ||
2040 | 0x1f93, /* MAXPW[7:0] */ | ||
2041 | 0x1f95, /* CURPWMSE[23:16] */ | ||
2042 | 0x1f96, /* CURPWMSE[15:8] */ | ||
2043 | 0x1f97, /* CURPWMSE[7:0] */ | ||
2044 | #endif /* SMART_ANT */ | ||
2045 | 0x211f, /* 1'b1 1'b1 1'b1 CIRQEN x x 1'b0 1'b0 1111xx00 */ | ||
2046 | 0x212a, /* EQAUTOST */ | ||
2047 | 0x2122, /* CHFAST[7:0] 01100000 */ | ||
2048 | 0x212b, /* FFFSTEP_V[3:0] x FBFSTEP_V[2:0] 0001x001 */ | ||
2049 | 0x212c, /* PHDEROTBWSEL[3:0] 1'b1 1'b1 1'b1 1'b0 10001110 */ | ||
2050 | 0x212d, /* 1'b1 1'b1 1'b1 1'b1 x x TPIFLOCKS */ | ||
2051 | 0x2135, /* DYNTRACKFDEQ[3:0] x 1'b0 1'b0 1'b0 1010x000 */ | ||
2052 | 0x2141, /* TRMODE[1:0] 1'b1 1'b1 1'b0 1'b1 1'b1 1'b1 01110111 */ | ||
2053 | 0x2162, /* AICCCTRLE */ | ||
2054 | 0x2173, /* PHNCNFCNT[7:0] 00000100 */ | ||
2055 | 0x2179, /* 1'b0 1'b0 1'b0 1'b1 x BADSINGLEDYNTRACKFBF[2:0] 0001x001 */ | ||
2056 | 0x217a, /* 1'b0 1'b0 1'b0 1'b1 x BADSLOWSINGLEDYNTRACKFBF[2:0] 0001x001 */ | ||
2057 | 0x217e, /* CNFCNTTPIF[7:0] 00001000 */ | ||
2058 | 0x217f, /* TPERRCNTTPIF[7:0] 00000001 */ | ||
2059 | 0x2180, /* x x x x x x FBDLYCIR[9:8] */ | ||
2060 | 0x2181, /* FBDLYCIR[7:0] */ | ||
2061 | 0x2185, /* MAXPWRMAIN[7:0] */ | ||
2062 | 0x2191, /* NCOMBDET x x x x x x x */ | ||
2063 | 0x2199, /* x MAINSTRON */ | ||
2064 | 0x219a, /* FFFEQSTEPOUT_V[3:0] FBFSTEPOUT_V[2:0] */ | ||
2065 | 0x21a1, /* x x SNRREF[5:0] */ | ||
2066 | 0x2845, /* 1'b0 1'b1 x x FFFSTEP_CQS[1:0] FFFCENTERTAP[1:0] 01xx1110 */ | ||
2067 | 0x2846, /* 1'b0 x 1'b0 1'b1 FBFSTEP_CQS[1:0] 1'b1 1'b0 0x011110 */ | ||
2068 | 0x2847, /* ENNOSIGDE */ | ||
2069 | 0x2849, /* 1'b1 1'b1 NOUSENOSI */ | ||
2070 | 0x284a, /* EQINITWAITTIME[7:0] 01100100 */ | ||
2071 | 0x3000, /* 1'b1 1'b1 1'b1 x x x 1'b0 RPTRSTM */ | ||
2072 | 0x3001, /* RPTRSTWAITTIME[7:0] (100msec) 00110010 */ | ||
2073 | 0x3031, /* FRAMELOC */ | ||
2074 | 0x3032, /* 1'b1 1'b0 1'b0 1'b0 x x FRAMELOCKMODE_CQS[1:0] 1000xx11 */ | ||
2075 | 0x30a9, /* VDLOCK_Q FRAMELOCK */ | ||
2076 | 0x30aa, /* MPEGLOCK */ | ||
2077 | }; | ||
2078 | |||
2079 | #define numDumpRegs (sizeof(regtab)/sizeof(regtab[0])) | ||
2080 | static u8 regval1[numDumpRegs] = {0, }; | ||
2081 | static u8 regval2[numDumpRegs] = {0, }; | ||
2082 | |||
2083 | static void lgdt3306a_DumpAllRegs(struct lgdt3306a_state *state) | ||
2084 | { | ||
2085 | memset(regval2, 0xff, sizeof(regval2)); | ||
2086 | lgdt3306a_DumpRegs(state); | ||
2087 | } | ||
2088 | |||
2089 | static void lgdt3306a_DumpRegs(struct lgdt3306a_state *state) | ||
2090 | { | ||
2091 | int i; | ||
2092 | int sav_debug = debug; | ||
2093 | |||
2094 | if ((debug & DBG_DUMP) == 0) | ||
2095 | return; | ||
2096 | debug &= ~DBG_REG; /* suppress DBG_REG during reg dump */ | ||
2097 | |||
2098 | lg_debug("\n"); | ||
2099 | |||
2100 | for (i = 0; i < numDumpRegs; i++) { | ||
2101 | lgdt3306a_read_reg(state, regtab[i], ®val1[i]); | ||
2102 | if (regval1[i] != regval2[i]) { | ||
2103 | lg_debug(" %04X = %02X\n", regtab[i], regval1[i]); | ||
2104 | regval2[i] = regval1[i]; | ||
2105 | } | ||
2106 | } | ||
2107 | debug = sav_debug; | ||
2108 | } | ||
2109 | #endif /* DBG_DUMP */ | ||
2110 | |||
2111 | |||
2112 | |||
2113 | static struct dvb_frontend_ops lgdt3306a_ops = { | ||
2114 | .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, | ||
2115 | .info = { | ||
2116 | .name = "LG Electronics LGDT3306A VSB/QAM Frontend", | ||
2117 | .frequency_min = 54000000, | ||
2118 | .frequency_max = 858000000, | ||
2119 | .frequency_stepsize = 62500, | ||
2120 | .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB | ||
2121 | }, | ||
2122 | .i2c_gate_ctrl = lgdt3306a_i2c_gate_ctrl, | ||
2123 | .init = lgdt3306a_init, | ||
2124 | .sleep = lgdt3306a_fe_sleep, | ||
2125 | /* if this is set, it overrides the default swzigzag */ | ||
2126 | .tune = lgdt3306a_tune, | ||
2127 | .set_frontend = lgdt3306a_set_parameters, | ||
2128 | .get_frontend = lgdt3306a_get_frontend, | ||
2129 | .get_frontend_algo = lgdt3306a_get_frontend_algo, | ||
2130 | .get_tune_settings = lgdt3306a_get_tune_settings, | ||
2131 | .read_status = lgdt3306a_read_status, | ||
2132 | .read_ber = lgdt3306a_read_ber, | ||
2133 | .read_signal_strength = lgdt3306a_read_signal_strength, | ||
2134 | .read_snr = lgdt3306a_read_snr, | ||
2135 | .read_ucblocks = lgdt3306a_read_ucblocks, | ||
2136 | .release = lgdt3306a_release, | ||
2137 | .ts_bus_ctrl = lgdt3306a_ts_bus_ctrl, | ||
2138 | .search = lgdt3306a_search, | ||
2139 | }; | ||
2140 | |||
2141 | MODULE_DESCRIPTION("LG Electronics LGDT3306A ATSC/QAM-B Demodulator Driver"); | ||
2142 | MODULE_AUTHOR("Fred Richter <frichter@hauppauge.com>"); | ||
2143 | MODULE_LICENSE("GPL"); | ||
2144 | MODULE_VERSION("0.2"); | ||
diff --git a/drivers/media/dvb-frontends/lgdt3306a.h b/drivers/media/dvb-frontends/lgdt3306a.h new file mode 100644 index 000000000000..9dbb2dced1fe --- /dev/null +++ b/drivers/media/dvb-frontends/lgdt3306a.h | |||
@@ -0,0 +1,74 @@ | |||
1 | /* | ||
2 | * Support for LGDT3306A - 8VSB/QAM-B | ||
3 | * | ||
4 | * Copyright (C) 2013,2014 Fred Richter <frichter@hauppauge.com> | ||
5 | * based on lgdt3305.[ch] by Michael Krufky | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #ifndef _LGDT3306A_H_ | ||
19 | #define _LGDT3306A_H_ | ||
20 | |||
21 | #include <linux/i2c.h> | ||
22 | #include "dvb_frontend.h" | ||
23 | |||
24 | |||
25 | enum lgdt3306a_mpeg_mode { | ||
26 | LGDT3306A_MPEG_PARALLEL = 0, | ||
27 | LGDT3306A_MPEG_SERIAL = 1, | ||
28 | }; | ||
29 | |||
30 | enum lgdt3306a_tp_clock_edge { | ||
31 | LGDT3306A_TPCLK_RISING_EDGE = 0, | ||
32 | LGDT3306A_TPCLK_FALLING_EDGE = 1, | ||
33 | }; | ||
34 | |||
35 | enum lgdt3306a_tp_valid_polarity { | ||
36 | LGDT3306A_TP_VALID_LOW = 0, | ||
37 | LGDT3306A_TP_VALID_HIGH = 1, | ||
38 | }; | ||
39 | |||
40 | struct lgdt3306a_config { | ||
41 | u8 i2c_addr; | ||
42 | |||
43 | /* user defined IF frequency in KHz */ | ||
44 | u16 qam_if_khz; | ||
45 | u16 vsb_if_khz; | ||
46 | |||
47 | /* disable i2c repeater - 0:repeater enabled 1:repeater disabled */ | ||
48 | unsigned int deny_i2c_rptr:1; | ||
49 | |||
50 | /* spectral inversion - 0:disabled 1:enabled */ | ||
51 | unsigned int spectral_inversion:1; | ||
52 | |||
53 | enum lgdt3306a_mpeg_mode mpeg_mode; | ||
54 | enum lgdt3306a_tp_clock_edge tpclk_edge; | ||
55 | enum lgdt3306a_tp_valid_polarity tpvalid_polarity; | ||
56 | |||
57 | /* demod clock freq in MHz; 24 or 25 supported */ | ||
58 | int xtalMHz; | ||
59 | }; | ||
60 | |||
61 | #if IS_REACHABLE(CONFIG_DVB_LGDT3306A) | ||
62 | struct dvb_frontend *lgdt3306a_attach(const struct lgdt3306a_config *config, | ||
63 | struct i2c_adapter *i2c_adap); | ||
64 | #else | ||
65 | static inline | ||
66 | struct dvb_frontend *lgdt3306a_attach(const struct lgdt3306a_config *config, | ||
67 | struct i2c_adapter *i2c_adap) | ||
68 | { | ||
69 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
70 | return NULL; | ||
71 | } | ||
72 | #endif /* CONFIG_DVB_LGDT3306A */ | ||
73 | |||
74 | #endif /* _LGDT3306A_H_ */ | ||
diff --git a/drivers/media/dvb-frontends/lgdt330x.h b/drivers/media/dvb-frontends/lgdt330x.h index 8bb332219fc4..c73eeb45e330 100644 --- a/drivers/media/dvb-frontends/lgdt330x.h +++ b/drivers/media/dvb-frontends/lgdt330x.h | |||
@@ -52,7 +52,7 @@ struct lgdt330x_config | |||
52 | int clock_polarity_flip; | 52 | int clock_polarity_flip; |
53 | }; | 53 | }; |
54 | 54 | ||
55 | #if IS_ENABLED(CONFIG_DVB_LGDT330X) | 55 | #if IS_REACHABLE(CONFIG_DVB_LGDT330X) |
56 | extern struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config, | 56 | extern struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config, |
57 | struct i2c_adapter* i2c); | 57 | struct i2c_adapter* i2c); |
58 | #else | 58 | #else |
diff --git a/drivers/media/dvb-frontends/lgs8gl5.h b/drivers/media/dvb-frontends/lgs8gl5.h index c2da59614727..a5b3faf121f0 100644 --- a/drivers/media/dvb-frontends/lgs8gl5.h +++ b/drivers/media/dvb-frontends/lgs8gl5.h | |||
@@ -31,7 +31,7 @@ struct lgs8gl5_config { | |||
31 | u8 demod_address; | 31 | u8 demod_address; |
32 | }; | 32 | }; |
33 | 33 | ||
34 | #if IS_ENABLED(CONFIG_DVB_LGS8GL5) | 34 | #if IS_REACHABLE(CONFIG_DVB_LGS8GL5) |
35 | extern struct dvb_frontend *lgs8gl5_attach( | 35 | extern struct dvb_frontend *lgs8gl5_attach( |
36 | const struct lgs8gl5_config *config, struct i2c_adapter *i2c); | 36 | const struct lgs8gl5_config *config, struct i2c_adapter *i2c); |
37 | #else | 37 | #else |
diff --git a/drivers/media/dvb-frontends/lgs8gxx.h b/drivers/media/dvb-frontends/lgs8gxx.h index dadb78bf61a9..368c9928ef7f 100644 --- a/drivers/media/dvb-frontends/lgs8gxx.h +++ b/drivers/media/dvb-frontends/lgs8gxx.h | |||
@@ -80,7 +80,7 @@ struct lgs8gxx_config { | |||
80 | u8 tuner_address; | 80 | u8 tuner_address; |
81 | }; | 81 | }; |
82 | 82 | ||
83 | #if IS_ENABLED(CONFIG_DVB_LGS8GXX) | 83 | #if IS_REACHABLE(CONFIG_DVB_LGS8GXX) |
84 | extern struct dvb_frontend *lgs8gxx_attach(const struct lgs8gxx_config *config, | 84 | extern struct dvb_frontend *lgs8gxx_attach(const struct lgs8gxx_config *config, |
85 | struct i2c_adapter *i2c); | 85 | struct i2c_adapter *i2c); |
86 | #else | 86 | #else |
diff --git a/drivers/media/dvb-frontends/lnbh24.h b/drivers/media/dvb-frontends/lnbh24.h index b327a4f31d16..a088b8ec1e53 100644 --- a/drivers/media/dvb-frontends/lnbh24.h +++ b/drivers/media/dvb-frontends/lnbh24.h | |||
@@ -37,7 +37,7 @@ | |||
37 | 37 | ||
38 | #include <linux/dvb/frontend.h> | 38 | #include <linux/dvb/frontend.h> |
39 | 39 | ||
40 | #if IS_ENABLED(CONFIG_DVB_LNBP21) | 40 | #if IS_REACHABLE(CONFIG_DVB_LNBP21) |
41 | /* override_set and override_clear control which | 41 | /* override_set and override_clear control which |
42 | system register bits (above) to always set & clear */ | 42 | system register bits (above) to always set & clear */ |
43 | extern struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe, | 43 | extern struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe, |
diff --git a/drivers/media/dvb-frontends/lnbp21.h b/drivers/media/dvb-frontends/lnbp21.h index dbcbcc2f20a3..a9b530de62a6 100644 --- a/drivers/media/dvb-frontends/lnbp21.h +++ b/drivers/media/dvb-frontends/lnbp21.h | |||
@@ -57,7 +57,7 @@ | |||
57 | 57 | ||
58 | #include <linux/dvb/frontend.h> | 58 | #include <linux/dvb/frontend.h> |
59 | 59 | ||
60 | #if IS_ENABLED(CONFIG_DVB_LNBP21) | 60 | #if IS_REACHABLE(CONFIG_DVB_LNBP21) |
61 | /* override_set and override_clear control which | 61 | /* override_set and override_clear control which |
62 | system register bits (above) to always set & clear */ | 62 | system register bits (above) to always set & clear */ |
63 | extern struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, | 63 | extern struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, |
diff --git a/drivers/media/dvb-frontends/lnbp22.h b/drivers/media/dvb-frontends/lnbp22.h index 63861b311dd8..628148385182 100644 --- a/drivers/media/dvb-frontends/lnbp22.h +++ b/drivers/media/dvb-frontends/lnbp22.h | |||
@@ -39,7 +39,7 @@ | |||
39 | 39 | ||
40 | #include <linux/dvb/frontend.h> | 40 | #include <linux/dvb/frontend.h> |
41 | 41 | ||
42 | #if IS_ENABLED(CONFIG_DVB_LNBP22) | 42 | #if IS_REACHABLE(CONFIG_DVB_LNBP22) |
43 | /* | 43 | /* |
44 | * override_set and override_clear control which system register bits (above) | 44 | * override_set and override_clear control which system register bits (above) |
45 | * to always set & clear | 45 | * to always set & clear |
diff --git a/drivers/media/dvb-frontends/m88rs2000.h b/drivers/media/dvb-frontends/m88rs2000.h index 0a50ea90736b..de7430178e9e 100644 --- a/drivers/media/dvb-frontends/m88rs2000.h +++ b/drivers/media/dvb-frontends/m88rs2000.h | |||
@@ -41,7 +41,7 @@ enum { | |||
41 | CALL_IS_READ, | 41 | CALL_IS_READ, |
42 | }; | 42 | }; |
43 | 43 | ||
44 | #if IS_ENABLED(CONFIG_DVB_M88RS2000) | 44 | #if IS_REACHABLE(CONFIG_DVB_M88RS2000) |
45 | extern struct dvb_frontend *m88rs2000_attach( | 45 | extern struct dvb_frontend *m88rs2000_attach( |
46 | const struct m88rs2000_config *config, struct i2c_adapter *i2c); | 46 | const struct m88rs2000_config *config, struct i2c_adapter *i2c); |
47 | #else | 47 | #else |
diff --git a/drivers/media/dvb-frontends/mb86a16.h b/drivers/media/dvb-frontends/mb86a16.h index 277ce061acf9..e486dc0d8e60 100644 --- a/drivers/media/dvb-frontends/mb86a16.h +++ b/drivers/media/dvb-frontends/mb86a16.h | |||
@@ -33,7 +33,7 @@ struct mb86a16_config { | |||
33 | 33 | ||
34 | 34 | ||
35 | 35 | ||
36 | #if IS_ENABLED(CONFIG_DVB_MB86A16) | 36 | #if IS_REACHABLE(CONFIG_DVB_MB86A16) |
37 | 37 | ||
38 | extern struct dvb_frontend *mb86a16_attach(const struct mb86a16_config *config, | 38 | extern struct dvb_frontend *mb86a16_attach(const struct mb86a16_config *config, |
39 | struct i2c_adapter *i2c_adap); | 39 | struct i2c_adapter *i2c_adap); |
diff --git a/drivers/media/dvb-frontends/mb86a20s.h b/drivers/media/dvb-frontends/mb86a20s.h index cbeb941fba7c..f749c8ac5f39 100644 --- a/drivers/media/dvb-frontends/mb86a20s.h +++ b/drivers/media/dvb-frontends/mb86a20s.h | |||
@@ -34,7 +34,7 @@ struct mb86a20s_config { | |||
34 | bool is_serial; | 34 | bool is_serial; |
35 | }; | 35 | }; |
36 | 36 | ||
37 | #if IS_ENABLED(CONFIG_DVB_MB86A20S) | 37 | #if IS_REACHABLE(CONFIG_DVB_MB86A20S) |
38 | extern struct dvb_frontend *mb86a20s_attach(const struct mb86a20s_config *config, | 38 | extern struct dvb_frontend *mb86a20s_attach(const struct mb86a20s_config *config, |
39 | struct i2c_adapter *i2c); | 39 | struct i2c_adapter *i2c); |
40 | extern struct i2c_adapter *mb86a20s_get_tuner_i2c_adapter(struct dvb_frontend *); | 40 | extern struct i2c_adapter *mb86a20s_get_tuner_i2c_adapter(struct dvb_frontend *); |
diff --git a/drivers/media/dvb-frontends/mn88472.h b/drivers/media/dvb-frontends/mn88472.h index e4e0b80d3091..095294d292f3 100644 --- a/drivers/media/dvb-frontends/mn88472.h +++ b/drivers/media/dvb-frontends/mn88472.h | |||
@@ -19,6 +19,16 @@ | |||
19 | 19 | ||
20 | #include <linux/dvb/frontend.h> | 20 | #include <linux/dvb/frontend.h> |
21 | 21 | ||
22 | enum ts_clock { | ||
23 | VARIABLE_TS_CLOCK, | ||
24 | FIXED_TS_CLOCK, | ||
25 | }; | ||
26 | |||
27 | enum ts_mode { | ||
28 | SERIAL_TS_MODE, | ||
29 | PARALLEL_TS_MODE, | ||
30 | }; | ||
31 | |||
22 | struct mn88472_config { | 32 | struct mn88472_config { |
23 | /* | 33 | /* |
24 | * Max num of bytes given I2C adapter could write at once. | 34 | * Max num of bytes given I2C adapter could write at once. |
@@ -39,6 +49,8 @@ struct mn88472_config { | |||
39 | * Hz | 49 | * Hz |
40 | */ | 50 | */ |
41 | u32 xtal; | 51 | u32 xtal; |
52 | int ts_mode; | ||
53 | int ts_clock; | ||
42 | }; | 54 | }; |
43 | 55 | ||
44 | #endif | 56 | #endif |
diff --git a/drivers/media/dvb-frontends/mn88473.h b/drivers/media/dvb-frontends/mn88473.h index a373ec93cbe0..c717ebed0e03 100644 --- a/drivers/media/dvb-frontends/mn88473.h +++ b/drivers/media/dvb-frontends/mn88473.h | |||
@@ -33,6 +33,12 @@ struct mn88473_config { | |||
33 | * DVB frontend. | 33 | * DVB frontend. |
34 | */ | 34 | */ |
35 | struct dvb_frontend **fe; | 35 | struct dvb_frontend **fe; |
36 | |||
37 | /* | ||
38 | * Xtal frequency. | ||
39 | * Hz | ||
40 | */ | ||
41 | u32 xtal; | ||
36 | }; | 42 | }; |
37 | 43 | ||
38 | #endif | 44 | #endif |
diff --git a/drivers/media/dvb-frontends/mt312.h b/drivers/media/dvb-frontends/mt312.h index 5706621ad79d..386939a90555 100644 --- a/drivers/media/dvb-frontends/mt312.h +++ b/drivers/media/dvb-frontends/mt312.h | |||
@@ -36,7 +36,7 @@ struct mt312_config { | |||
36 | unsigned int voltage_inverted:1; | 36 | unsigned int voltage_inverted:1; |
37 | }; | 37 | }; |
38 | 38 | ||
39 | #if IS_ENABLED(CONFIG_DVB_MT312) | 39 | #if IS_REACHABLE(CONFIG_DVB_MT312) |
40 | struct dvb_frontend *mt312_attach(const struct mt312_config *config, | 40 | struct dvb_frontend *mt312_attach(const struct mt312_config *config, |
41 | struct i2c_adapter *i2c); | 41 | struct i2c_adapter *i2c); |
42 | #else | 42 | #else |
diff --git a/drivers/media/dvb-frontends/mt352.h b/drivers/media/dvb-frontends/mt352.h index 451d904e1500..5873263bd1af 100644 --- a/drivers/media/dvb-frontends/mt352.h +++ b/drivers/media/dvb-frontends/mt352.h | |||
@@ -51,7 +51,7 @@ struct mt352_config | |||
51 | int (*demod_init)(struct dvb_frontend* fe); | 51 | int (*demod_init)(struct dvb_frontend* fe); |
52 | }; | 52 | }; |
53 | 53 | ||
54 | #if IS_ENABLED(CONFIG_DVB_MT352) | 54 | #if IS_REACHABLE(CONFIG_DVB_MT352) |
55 | extern struct dvb_frontend* mt352_attach(const struct mt352_config* config, | 55 | extern struct dvb_frontend* mt352_attach(const struct mt352_config* config, |
56 | struct i2c_adapter* i2c); | 56 | struct i2c_adapter* i2c); |
57 | #else | 57 | #else |
diff --git a/drivers/media/dvb-frontends/nxt200x.h b/drivers/media/dvb-frontends/nxt200x.h index e38d01fb6c2b..825b928ef542 100644 --- a/drivers/media/dvb-frontends/nxt200x.h +++ b/drivers/media/dvb-frontends/nxt200x.h | |||
@@ -42,7 +42,7 @@ struct nxt200x_config | |||
42 | int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); | 42 | int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); |
43 | }; | 43 | }; |
44 | 44 | ||
45 | #if IS_ENABLED(CONFIG_DVB_NXT200X) | 45 | #if IS_REACHABLE(CONFIG_DVB_NXT200X) |
46 | extern struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config, | 46 | extern struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config, |
47 | struct i2c_adapter* i2c); | 47 | struct i2c_adapter* i2c); |
48 | #else | 48 | #else |
diff --git a/drivers/media/dvb-frontends/nxt6000.h b/drivers/media/dvb-frontends/nxt6000.h index b5867c2ae681..a94cefcc6dfd 100644 --- a/drivers/media/dvb-frontends/nxt6000.h +++ b/drivers/media/dvb-frontends/nxt6000.h | |||
@@ -33,7 +33,7 @@ struct nxt6000_config | |||
33 | u8 clock_inversion:1; | 33 | u8 clock_inversion:1; |
34 | }; | 34 | }; |
35 | 35 | ||
36 | #if IS_ENABLED(CONFIG_DVB_NXT6000) | 36 | #if IS_REACHABLE(CONFIG_DVB_NXT6000) |
37 | extern struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, | 37 | extern struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, |
38 | struct i2c_adapter* i2c); | 38 | struct i2c_adapter* i2c); |
39 | #else | 39 | #else |
diff --git a/drivers/media/dvb-frontends/or51132.h b/drivers/media/dvb-frontends/or51132.h index cdb5be3c65d6..9acf8dc87413 100644 --- a/drivers/media/dvb-frontends/or51132.h +++ b/drivers/media/dvb-frontends/or51132.h | |||
@@ -34,7 +34,7 @@ struct or51132_config | |||
34 | int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); | 34 | int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); |
35 | }; | 35 | }; |
36 | 36 | ||
37 | #if IS_ENABLED(CONFIG_DVB_OR51132) | 37 | #if IS_REACHABLE(CONFIG_DVB_OR51132) |
38 | extern struct dvb_frontend* or51132_attach(const struct or51132_config* config, | 38 | extern struct dvb_frontend* or51132_attach(const struct or51132_config* config, |
39 | struct i2c_adapter* i2c); | 39 | struct i2c_adapter* i2c); |
40 | #else | 40 | #else |
diff --git a/drivers/media/dvb-frontends/or51211.h b/drivers/media/dvb-frontends/or51211.h index 9a8ae936b62d..cc6adab63249 100644 --- a/drivers/media/dvb-frontends/or51211.h +++ b/drivers/media/dvb-frontends/or51211.h | |||
@@ -37,7 +37,7 @@ struct or51211_config | |||
37 | void (*sleep)(struct dvb_frontend * fe); | 37 | void (*sleep)(struct dvb_frontend * fe); |
38 | }; | 38 | }; |
39 | 39 | ||
40 | #if IS_ENABLED(CONFIG_DVB_OR51211) | 40 | #if IS_REACHABLE(CONFIG_DVB_OR51211) |
41 | extern struct dvb_frontend* or51211_attach(const struct or51211_config* config, | 41 | extern struct dvb_frontend* or51211_attach(const struct or51211_config* config, |
42 | struct i2c_adapter* i2c); | 42 | struct i2c_adapter* i2c); |
43 | #else | 43 | #else |
diff --git a/drivers/media/dvb-frontends/rtl2832.c b/drivers/media/dvb-frontends/rtl2832.c index 67faa8d6950e..b400f7b3c2e7 100644 --- a/drivers/media/dvb-frontends/rtl2832.c +++ b/drivers/media/dvb-frontends/rtl2832.c | |||
@@ -685,7 +685,7 @@ static int rtl2832_read_status(struct dvb_frontend *fe, fe_status_t *status) | |||
685 | struct rtl2832_dev *dev = fe->demodulator_priv; | 685 | struct rtl2832_dev *dev = fe->demodulator_priv; |
686 | struct i2c_client *client = dev->client; | 686 | struct i2c_client *client = dev->client; |
687 | int ret; | 687 | int ret; |
688 | u32 tmp; | 688 | u32 uninitialized_var(tmp); |
689 | 689 | ||
690 | dev_dbg(&client->dev, "\n"); | 690 | dev_dbg(&client->dev, "\n"); |
691 | 691 | ||
diff --git a/drivers/media/dvb-frontends/s5h1409.h b/drivers/media/dvb-frontends/s5h1409.h index 9e143f5c8107..f58b9ca5557a 100644 --- a/drivers/media/dvb-frontends/s5h1409.h +++ b/drivers/media/dvb-frontends/s5h1409.h | |||
@@ -67,7 +67,7 @@ struct s5h1409_config { | |||
67 | u8 hvr1600_opt; | 67 | u8 hvr1600_opt; |
68 | }; | 68 | }; |
69 | 69 | ||
70 | #if IS_ENABLED(CONFIG_DVB_S5H1409) | 70 | #if IS_REACHABLE(CONFIG_DVB_S5H1409) |
71 | extern struct dvb_frontend *s5h1409_attach(const struct s5h1409_config *config, | 71 | extern struct dvb_frontend *s5h1409_attach(const struct s5h1409_config *config, |
72 | struct i2c_adapter *i2c); | 72 | struct i2c_adapter *i2c); |
73 | #else | 73 | #else |
diff --git a/drivers/media/dvb-frontends/s5h1411.h b/drivers/media/dvb-frontends/s5h1411.h index 1d7deb615674..f3a87f7ec360 100644 --- a/drivers/media/dvb-frontends/s5h1411.h +++ b/drivers/media/dvb-frontends/s5h1411.h | |||
@@ -69,7 +69,7 @@ struct s5h1411_config { | |||
69 | u8 status_mode; | 69 | u8 status_mode; |
70 | }; | 70 | }; |
71 | 71 | ||
72 | #if IS_ENABLED(CONFIG_DVB_S5H1411) | 72 | #if IS_REACHABLE(CONFIG_DVB_S5H1411) |
73 | extern struct dvb_frontend *s5h1411_attach(const struct s5h1411_config *config, | 73 | extern struct dvb_frontend *s5h1411_attach(const struct s5h1411_config *config, |
74 | struct i2c_adapter *i2c); | 74 | struct i2c_adapter *i2c); |
75 | #else | 75 | #else |
diff --git a/drivers/media/dvb-frontends/s5h1420.h b/drivers/media/dvb-frontends/s5h1420.h index 210049b5cf30..142d93e7d02b 100644 --- a/drivers/media/dvb-frontends/s5h1420.h +++ b/drivers/media/dvb-frontends/s5h1420.h | |||
@@ -40,7 +40,7 @@ struct s5h1420_config | |||
40 | u8 serial_mpeg:1; | 40 | u8 serial_mpeg:1; |
41 | }; | 41 | }; |
42 | 42 | ||
43 | #if IS_ENABLED(CONFIG_DVB_S5H1420) | 43 | #if IS_REACHABLE(CONFIG_DVB_S5H1420) |
44 | extern struct dvb_frontend *s5h1420_attach(const struct s5h1420_config *config, | 44 | extern struct dvb_frontend *s5h1420_attach(const struct s5h1420_config *config, |
45 | struct i2c_adapter *i2c); | 45 | struct i2c_adapter *i2c); |
46 | extern struct i2c_adapter *s5h1420_get_tuner_i2c_adapter(struct dvb_frontend *fe); | 46 | extern struct i2c_adapter *s5h1420_get_tuner_i2c_adapter(struct dvb_frontend *fe); |
diff --git a/drivers/media/dvb-frontends/s5h1432.h b/drivers/media/dvb-frontends/s5h1432.h index 70917dd2533a..f490c5ee5801 100644 --- a/drivers/media/dvb-frontends/s5h1432.h +++ b/drivers/media/dvb-frontends/s5h1432.h | |||
@@ -75,7 +75,7 @@ struct s5h1432_config { | |||
75 | u8 status_mode; | 75 | u8 status_mode; |
76 | }; | 76 | }; |
77 | 77 | ||
78 | #if IS_ENABLED(CONFIG_DVB_S5H1432) | 78 | #if IS_REACHABLE(CONFIG_DVB_S5H1432) |
79 | extern struct dvb_frontend *s5h1432_attach(const struct s5h1432_config *config, | 79 | extern struct dvb_frontend *s5h1432_attach(const struct s5h1432_config *config, |
80 | struct i2c_adapter *i2c); | 80 | struct i2c_adapter *i2c); |
81 | #else | 81 | #else |
diff --git a/drivers/media/dvb-frontends/s921.h b/drivers/media/dvb-frontends/s921.h index 9b20c9e0eb88..7d3999a4e974 100644 --- a/drivers/media/dvb-frontends/s921.h +++ b/drivers/media/dvb-frontends/s921.h | |||
@@ -25,7 +25,7 @@ struct s921_config { | |||
25 | u8 demod_address; | 25 | u8 demod_address; |
26 | }; | 26 | }; |
27 | 27 | ||
28 | #if IS_ENABLED(CONFIG_DVB_S921) | 28 | #if IS_REACHABLE(CONFIG_DVB_S921) |
29 | extern struct dvb_frontend *s921_attach(const struct s921_config *config, | 29 | extern struct dvb_frontend *s921_attach(const struct s921_config *config, |
30 | struct i2c_adapter *i2c); | 30 | struct i2c_adapter *i2c); |
31 | extern struct i2c_adapter *s921_get_tuner_i2c_adapter(struct dvb_frontend *); | 31 | extern struct i2c_adapter *s921_get_tuner_i2c_adapter(struct dvb_frontend *); |
diff --git a/drivers/media/dvb-frontends/si2165.c b/drivers/media/dvb-frontends/si2165.c index 98ddb49ad52b..4cc5d10ed0d4 100644 --- a/drivers/media/dvb-frontends/si2165.c +++ b/drivers/media/dvb-frontends/si2165.c | |||
@@ -505,7 +505,7 @@ static int si2165_upload_firmware(struct si2165_state *state) | |||
505 | /* reset crc */ | 505 | /* reset crc */ |
506 | ret = si2165_writereg8(state, 0x0379, 0x01); | 506 | ret = si2165_writereg8(state, 0x0379, 0x01); |
507 | if (ret) | 507 | if (ret) |
508 | return ret; | 508 | goto error; |
509 | 509 | ||
510 | ret = si2165_upload_firmware_block(state, data, len, | 510 | ret = si2165_upload_firmware_block(state, data, len, |
511 | &offset, block_count); | 511 | &offset, block_count); |
diff --git a/drivers/media/dvb-frontends/si2165.h b/drivers/media/dvb-frontends/si2165.h index efaa08123b92..8a15d6a9c552 100644 --- a/drivers/media/dvb-frontends/si2165.h +++ b/drivers/media/dvb-frontends/si2165.h | |||
@@ -45,7 +45,7 @@ struct si2165_config { | |||
45 | bool inversion; | 45 | bool inversion; |
46 | }; | 46 | }; |
47 | 47 | ||
48 | #if IS_ENABLED(CONFIG_DVB_SI2165) | 48 | #if IS_REACHABLE(CONFIG_DVB_SI2165) |
49 | struct dvb_frontend *si2165_attach( | 49 | struct dvb_frontend *si2165_attach( |
50 | const struct si2165_config *config, | 50 | const struct si2165_config *config, |
51 | struct i2c_adapter *i2c); | 51 | struct i2c_adapter *i2c); |
diff --git a/drivers/media/dvb-frontends/si21xx.h b/drivers/media/dvb-frontends/si21xx.h index 1509fed44a3a..ef5f351ca68e 100644 --- a/drivers/media/dvb-frontends/si21xx.h +++ b/drivers/media/dvb-frontends/si21xx.h | |||
@@ -13,7 +13,7 @@ struct si21xx_config { | |||
13 | int min_delay_ms; | 13 | int min_delay_ms; |
14 | }; | 14 | }; |
15 | 15 | ||
16 | #if IS_ENABLED(CONFIG_DVB_SI21XX) | 16 | #if IS_REACHABLE(CONFIG_DVB_SI21XX) |
17 | extern struct dvb_frontend *si21xx_attach(const struct si21xx_config *config, | 17 | extern struct dvb_frontend *si21xx_attach(const struct si21xx_config *config, |
18 | struct i2c_adapter *i2c); | 18 | struct i2c_adapter *i2c); |
19 | #else | 19 | #else |
diff --git a/drivers/media/dvb-frontends/sp2.c b/drivers/media/dvb-frontends/sp2.c index cc1ef966f99f..8fd42767e263 100644 --- a/drivers/media/dvb-frontends/sp2.c +++ b/drivers/media/dvb-frontends/sp2.c | |||
@@ -413,11 +413,8 @@ static int sp2_remove(struct i2c_client *client) | |||
413 | struct sp2 *s = i2c_get_clientdata(client); | 413 | struct sp2 *s = i2c_get_clientdata(client); |
414 | 414 | ||
415 | dev_dbg(&client->dev, "\n"); | 415 | dev_dbg(&client->dev, "\n"); |
416 | |||
417 | sp2_exit(client); | 416 | sp2_exit(client); |
418 | if (s != NULL) | 417 | kfree(s); |
419 | kfree(s); | ||
420 | |||
421 | return 0; | 418 | return 0; |
422 | } | 419 | } |
423 | 420 | ||
diff --git a/drivers/media/dvb-frontends/sp8870.h b/drivers/media/dvb-frontends/sp8870.h index 065ec67d4e30..f507b9fd707b 100644 --- a/drivers/media/dvb-frontends/sp8870.h +++ b/drivers/media/dvb-frontends/sp8870.h | |||
@@ -35,7 +35,7 @@ struct sp8870_config | |||
35 | int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); | 35 | int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); |
36 | }; | 36 | }; |
37 | 37 | ||
38 | #if IS_ENABLED(CONFIG_DVB_SP8870) | 38 | #if IS_REACHABLE(CONFIG_DVB_SP8870) |
39 | extern struct dvb_frontend* sp8870_attach(const struct sp8870_config* config, | 39 | extern struct dvb_frontend* sp8870_attach(const struct sp8870_config* config, |
40 | struct i2c_adapter* i2c); | 40 | struct i2c_adapter* i2c); |
41 | #else | 41 | #else |
diff --git a/drivers/media/dvb-frontends/sp887x.h b/drivers/media/dvb-frontends/sp887x.h index 2cdc4e8bc9cd..412f011e6dfd 100644 --- a/drivers/media/dvb-frontends/sp887x.h +++ b/drivers/media/dvb-frontends/sp887x.h | |||
@@ -17,7 +17,7 @@ struct sp887x_config | |||
17 | int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); | 17 | int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); |
18 | }; | 18 | }; |
19 | 19 | ||
20 | #if IS_ENABLED(CONFIG_DVB_SP887X) | 20 | #if IS_REACHABLE(CONFIG_DVB_SP887X) |
21 | extern struct dvb_frontend* sp887x_attach(const struct sp887x_config* config, | 21 | extern struct dvb_frontend* sp887x_attach(const struct sp887x_config* config, |
22 | struct i2c_adapter* i2c); | 22 | struct i2c_adapter* i2c); |
23 | #else | 23 | #else |
diff --git a/drivers/media/dvb-frontends/stb0899_drv.h b/drivers/media/dvb-frontends/stb0899_drv.h index 139264d19263..0a72131a57db 100644 --- a/drivers/media/dvb-frontends/stb0899_drv.h +++ b/drivers/media/dvb-frontends/stb0899_drv.h | |||
@@ -141,7 +141,7 @@ struct stb0899_config { | |||
141 | int (*tuner_set_rfsiggain)(struct dvb_frontend *fe, u32 rf_gain); | 141 | int (*tuner_set_rfsiggain)(struct dvb_frontend *fe, u32 rf_gain); |
142 | }; | 142 | }; |
143 | 143 | ||
144 | #if IS_ENABLED(CONFIG_DVB_STB0899) | 144 | #if IS_REACHABLE(CONFIG_DVB_STB0899) |
145 | 145 | ||
146 | extern struct dvb_frontend *stb0899_attach(struct stb0899_config *config, | 146 | extern struct dvb_frontend *stb0899_attach(struct stb0899_config *config, |
147 | struct i2c_adapter *i2c); | 147 | struct i2c_adapter *i2c); |
diff --git a/drivers/media/dvb-frontends/stb6000.h b/drivers/media/dvb-frontends/stb6000.h index a768189bfaad..da581b652cb9 100644 --- a/drivers/media/dvb-frontends/stb6000.h +++ b/drivers/media/dvb-frontends/stb6000.h | |||
@@ -35,7 +35,7 @@ | |||
35 | * @param i2c i2c adapter to use. | 35 | * @param i2c i2c adapter to use. |
36 | * @return FE pointer on success, NULL on failure. | 36 | * @return FE pointer on success, NULL on failure. |
37 | */ | 37 | */ |
38 | #if IS_ENABLED(CONFIG_DVB_STB6000) | 38 | #if IS_REACHABLE(CONFIG_DVB_STB6000) |
39 | extern struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe, int addr, | 39 | extern struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe, int addr, |
40 | struct i2c_adapter *i2c); | 40 | struct i2c_adapter *i2c); |
41 | #else | 41 | #else |
diff --git a/drivers/media/dvb-frontends/stb6100.h b/drivers/media/dvb-frontends/stb6100.h index 3a1e40f3b8be..218c8188865d 100644 --- a/drivers/media/dvb-frontends/stb6100.h +++ b/drivers/media/dvb-frontends/stb6100.h | |||
@@ -94,7 +94,7 @@ struct stb6100_state { | |||
94 | u32 reference; | 94 | u32 reference; |
95 | }; | 95 | }; |
96 | 96 | ||
97 | #if IS_ENABLED(CONFIG_DVB_STB6100) | 97 | #if IS_REACHABLE(CONFIG_DVB_STB6100) |
98 | 98 | ||
99 | extern struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe, | 99 | extern struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe, |
100 | const struct stb6100_config *config, | 100 | const struct stb6100_config *config, |
diff --git a/drivers/media/dvb-frontends/stv0288.h b/drivers/media/dvb-frontends/stv0288.h index a0bd93107154..b58603c00c80 100644 --- a/drivers/media/dvb-frontends/stv0288.h +++ b/drivers/media/dvb-frontends/stv0288.h | |||
@@ -43,7 +43,7 @@ struct stv0288_config { | |||
43 | int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured); | 43 | int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured); |
44 | }; | 44 | }; |
45 | 45 | ||
46 | #if IS_ENABLED(CONFIG_DVB_STV0288) | 46 | #if IS_REACHABLE(CONFIG_DVB_STV0288) |
47 | extern struct dvb_frontend *stv0288_attach(const struct stv0288_config *config, | 47 | extern struct dvb_frontend *stv0288_attach(const struct stv0288_config *config, |
48 | struct i2c_adapter *i2c); | 48 | struct i2c_adapter *i2c); |
49 | #else | 49 | #else |
diff --git a/drivers/media/dvb-frontends/stv0297.h b/drivers/media/dvb-frontends/stv0297.h index c8ff3639ce00..b30632a67333 100644 --- a/drivers/media/dvb-frontends/stv0297.h +++ b/drivers/media/dvb-frontends/stv0297.h | |||
@@ -42,7 +42,7 @@ struct stv0297_config | |||
42 | u8 stop_during_read:1; | 42 | u8 stop_during_read:1; |
43 | }; | 43 | }; |
44 | 44 | ||
45 | #if IS_ENABLED(CONFIG_DVB_STV0297) | 45 | #if IS_REACHABLE(CONFIG_DVB_STV0297) |
46 | extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config, | 46 | extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config, |
47 | struct i2c_adapter* i2c); | 47 | struct i2c_adapter* i2c); |
48 | #else | 48 | #else |
diff --git a/drivers/media/dvb-frontends/stv0299.h b/drivers/media/dvb-frontends/stv0299.h index 06f70fc8327b..0aca30a8ec25 100644 --- a/drivers/media/dvb-frontends/stv0299.h +++ b/drivers/media/dvb-frontends/stv0299.h | |||
@@ -95,7 +95,7 @@ struct stv0299_config | |||
95 | int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured); | 95 | int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured); |
96 | }; | 96 | }; |
97 | 97 | ||
98 | #if IS_ENABLED(CONFIG_DVB_STV0299) | 98 | #if IS_REACHABLE(CONFIG_DVB_STV0299) |
99 | extern struct dvb_frontend *stv0299_attach(const struct stv0299_config *config, | 99 | extern struct dvb_frontend *stv0299_attach(const struct stv0299_config *config, |
100 | struct i2c_adapter *i2c); | 100 | struct i2c_adapter *i2c); |
101 | #else | 101 | #else |
diff --git a/drivers/media/dvb-frontends/stv0367.h b/drivers/media/dvb-frontends/stv0367.h index ea80b341f094..92b3e85fb818 100644 --- a/drivers/media/dvb-frontends/stv0367.h +++ b/drivers/media/dvb-frontends/stv0367.h | |||
@@ -39,7 +39,7 @@ struct stv0367_config { | |||
39 | int clk_pol; | 39 | int clk_pol; |
40 | }; | 40 | }; |
41 | 41 | ||
42 | #if IS_ENABLED(CONFIG_DVB_STV0367) | 42 | #if IS_REACHABLE(CONFIG_DVB_STV0367) |
43 | extern struct | 43 | extern struct |
44 | dvb_frontend *stv0367ter_attach(const struct stv0367_config *config, | 44 | dvb_frontend *stv0367ter_attach(const struct stv0367_config *config, |
45 | struct i2c_adapter *i2c); | 45 | struct i2c_adapter *i2c); |
diff --git a/drivers/media/dvb-frontends/stv0900.h b/drivers/media/dvb-frontends/stv0900.h index e2a6dc69ecb4..c90bf00ea9ce 100644 --- a/drivers/media/dvb-frontends/stv0900.h +++ b/drivers/media/dvb-frontends/stv0900.h | |||
@@ -58,7 +58,7 @@ struct stv0900_config { | |||
58 | void (*set_lock_led)(struct dvb_frontend *fe, int offon); | 58 | void (*set_lock_led)(struct dvb_frontend *fe, int offon); |
59 | }; | 59 | }; |
60 | 60 | ||
61 | #if IS_ENABLED(CONFIG_DVB_STV0900) | 61 | #if IS_REACHABLE(CONFIG_DVB_STV0900) |
62 | extern struct dvb_frontend *stv0900_attach(const struct stv0900_config *config, | 62 | extern struct dvb_frontend *stv0900_attach(const struct stv0900_config *config, |
63 | struct i2c_adapter *i2c, int demod); | 63 | struct i2c_adapter *i2c, int demod); |
64 | #else | 64 | #else |
diff --git a/drivers/media/dvb-frontends/stv090x.h b/drivers/media/dvb-frontends/stv090x.h index 742eeda99000..012e55e5032e 100644 --- a/drivers/media/dvb-frontends/stv090x.h +++ b/drivers/media/dvb-frontends/stv090x.h | |||
@@ -107,7 +107,7 @@ struct stv090x_config { | |||
107 | u8 xor_value); | 107 | u8 xor_value); |
108 | }; | 108 | }; |
109 | 109 | ||
110 | #if IS_ENABLED(CONFIG_DVB_STV090x) | 110 | #if IS_REACHABLE(CONFIG_DVB_STV090x) |
111 | 111 | ||
112 | struct dvb_frontend *stv090x_attach(struct stv090x_config *config, | 112 | struct dvb_frontend *stv090x_attach(struct stv090x_config *config, |
113 | struct i2c_adapter *i2c, | 113 | struct i2c_adapter *i2c, |
diff --git a/drivers/media/dvb-frontends/stv6110.h b/drivers/media/dvb-frontends/stv6110.h index 8fa07e6a6745..f3c8a5c6b77d 100644 --- a/drivers/media/dvb-frontends/stv6110.h +++ b/drivers/media/dvb-frontends/stv6110.h | |||
@@ -46,7 +46,7 @@ struct stv6110_config { | |||
46 | u8 clk_div; /* divisor value for the output clock */ | 46 | u8 clk_div; /* divisor value for the output clock */ |
47 | }; | 47 | }; |
48 | 48 | ||
49 | #if IS_ENABLED(CONFIG_DVB_STV6110) | 49 | #if IS_REACHABLE(CONFIG_DVB_STV6110) |
50 | extern struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe, | 50 | extern struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe, |
51 | const struct stv6110_config *config, | 51 | const struct stv6110_config *config, |
52 | struct i2c_adapter *i2c); | 52 | struct i2c_adapter *i2c); |
diff --git a/drivers/media/dvb-frontends/stv6110x.h b/drivers/media/dvb-frontends/stv6110x.h index bc4766db29c5..9f7eb251aec3 100644 --- a/drivers/media/dvb-frontends/stv6110x.h +++ b/drivers/media/dvb-frontends/stv6110x.h | |||
@@ -53,7 +53,7 @@ struct stv6110x_devctl { | |||
53 | }; | 53 | }; |
54 | 54 | ||
55 | 55 | ||
56 | #if IS_ENABLED(CONFIG_DVB_STV6110x) | 56 | #if IS_REACHABLE(CONFIG_DVB_STV6110x) |
57 | 57 | ||
58 | extern struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe, | 58 | extern struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe, |
59 | const struct stv6110x_config *config, | 59 | const struct stv6110x_config *config, |
diff --git a/drivers/media/dvb-frontends/tda1002x.h b/drivers/media/dvb-frontends/tda1002x.h index e404b6e44802..0d334613de1b 100644 --- a/drivers/media/dvb-frontends/tda1002x.h +++ b/drivers/media/dvb-frontends/tda1002x.h | |||
@@ -57,7 +57,7 @@ struct tda10023_config { | |||
57 | u16 deltaf; | 57 | u16 deltaf; |
58 | }; | 58 | }; |
59 | 59 | ||
60 | #if IS_ENABLED(CONFIG_DVB_TDA10021) | 60 | #if IS_REACHABLE(CONFIG_DVB_TDA10021) |
61 | extern struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config, | 61 | extern struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config, |
62 | struct i2c_adapter* i2c, u8 pwm); | 62 | struct i2c_adapter* i2c, u8 pwm); |
63 | #else | 63 | #else |
@@ -69,7 +69,7 @@ static inline struct dvb_frontend* tda10021_attach(const struct tda1002x_config* | |||
69 | } | 69 | } |
70 | #endif // CONFIG_DVB_TDA10021 | 70 | #endif // CONFIG_DVB_TDA10021 |
71 | 71 | ||
72 | #if IS_ENABLED(CONFIG_DVB_TDA10023) | 72 | #if IS_REACHABLE(CONFIG_DVB_TDA10023) |
73 | extern struct dvb_frontend *tda10023_attach( | 73 | extern struct dvb_frontend *tda10023_attach( |
74 | const struct tda10023_config *config, | 74 | const struct tda10023_config *config, |
75 | struct i2c_adapter *i2c, u8 pwm); | 75 | struct i2c_adapter *i2c, u8 pwm); |
diff --git a/drivers/media/dvb-frontends/tda10048.h b/drivers/media/dvb-frontends/tda10048.h index 5e7bf4e47cb3..bc77a7311de1 100644 --- a/drivers/media/dvb-frontends/tda10048.h +++ b/drivers/media/dvb-frontends/tda10048.h | |||
@@ -73,7 +73,7 @@ struct tda10048_config { | |||
73 | u8 pll_n; | 73 | u8 pll_n; |
74 | }; | 74 | }; |
75 | 75 | ||
76 | #if IS_ENABLED(CONFIG_DVB_TDA10048) | 76 | #if IS_REACHABLE(CONFIG_DVB_TDA10048) |
77 | extern struct dvb_frontend *tda10048_attach( | 77 | extern struct dvb_frontend *tda10048_attach( |
78 | const struct tda10048_config *config, | 78 | const struct tda10048_config *config, |
79 | struct i2c_adapter *i2c); | 79 | struct i2c_adapter *i2c); |
diff --git a/drivers/media/dvb-frontends/tda1004x.h b/drivers/media/dvb-frontends/tda1004x.h index dd283fbb61c0..efd7659dace9 100644 --- a/drivers/media/dvb-frontends/tda1004x.h +++ b/drivers/media/dvb-frontends/tda1004x.h | |||
@@ -117,7 +117,7 @@ struct tda1004x_state { | |||
117 | enum tda1004x_demod demod_type; | 117 | enum tda1004x_demod demod_type; |
118 | }; | 118 | }; |
119 | 119 | ||
120 | #if IS_ENABLED(CONFIG_DVB_TDA1004X) | 120 | #if IS_REACHABLE(CONFIG_DVB_TDA1004X) |
121 | extern struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, | 121 | extern struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, |
122 | struct i2c_adapter* i2c); | 122 | struct i2c_adapter* i2c); |
123 | 123 | ||
diff --git a/drivers/media/dvb-frontends/tda10071.h b/drivers/media/dvb-frontends/tda10071.h index 331b5a819383..da89f4249846 100644 --- a/drivers/media/dvb-frontends/tda10071.h +++ b/drivers/media/dvb-frontends/tda10071.h | |||
@@ -72,7 +72,7 @@ struct tda10071_config { | |||
72 | }; | 72 | }; |
73 | 73 | ||
74 | 74 | ||
75 | #if IS_ENABLED(CONFIG_DVB_TDA10071) | 75 | #if IS_REACHABLE(CONFIG_DVB_TDA10071) |
76 | extern struct dvb_frontend *tda10071_attach( | 76 | extern struct dvb_frontend *tda10071_attach( |
77 | const struct tda10071_config *config, struct i2c_adapter *i2c); | 77 | const struct tda10071_config *config, struct i2c_adapter *i2c); |
78 | #else | 78 | #else |
diff --git a/drivers/media/dvb-frontends/tda10086.h b/drivers/media/dvb-frontends/tda10086.h index 458fe91c1b88..690e469995b6 100644 --- a/drivers/media/dvb-frontends/tda10086.h +++ b/drivers/media/dvb-frontends/tda10086.h | |||
@@ -46,7 +46,7 @@ struct tda10086_config | |||
46 | enum tda10086_xtal xtal_freq; | 46 | enum tda10086_xtal xtal_freq; |
47 | }; | 47 | }; |
48 | 48 | ||
49 | #if IS_ENABLED(CONFIG_DVB_TDA10086) | 49 | #if IS_REACHABLE(CONFIG_DVB_TDA10086) |
50 | extern struct dvb_frontend* tda10086_attach(const struct tda10086_config* config, | 50 | extern struct dvb_frontend* tda10086_attach(const struct tda10086_config* config, |
51 | struct i2c_adapter* i2c); | 51 | struct i2c_adapter* i2c); |
52 | #else | 52 | #else |
diff --git a/drivers/media/dvb-frontends/tda18271c2dd.h b/drivers/media/dvb-frontends/tda18271c2dd.h index dd84f7b69bec..7ebd8eaff4eb 100644 --- a/drivers/media/dvb-frontends/tda18271c2dd.h +++ b/drivers/media/dvb-frontends/tda18271c2dd.h | |||
@@ -3,7 +3,7 @@ | |||
3 | 3 | ||
4 | #include <linux/kconfig.h> | 4 | #include <linux/kconfig.h> |
5 | 5 | ||
6 | #if IS_ENABLED(CONFIG_DVB_TDA18271C2DD) | 6 | #if IS_REACHABLE(CONFIG_DVB_TDA18271C2DD) |
7 | struct dvb_frontend *tda18271c2dd_attach(struct dvb_frontend *fe, | 7 | struct dvb_frontend *tda18271c2dd_attach(struct dvb_frontend *fe, |
8 | struct i2c_adapter *i2c, u8 adr); | 8 | struct i2c_adapter *i2c, u8 adr); |
9 | #else | 9 | #else |
diff --git a/drivers/media/dvb-frontends/tda665x.h b/drivers/media/dvb-frontends/tda665x.h index 03a0da6d5cf2..baf520baa42e 100644 --- a/drivers/media/dvb-frontends/tda665x.h +++ b/drivers/media/dvb-frontends/tda665x.h | |||
@@ -31,7 +31,7 @@ struct tda665x_config { | |||
31 | u32 ref_divider; | 31 | u32 ref_divider; |
32 | }; | 32 | }; |
33 | 33 | ||
34 | #if IS_ENABLED(CONFIG_DVB_TDA665x) | 34 | #if IS_REACHABLE(CONFIG_DVB_TDA665x) |
35 | 35 | ||
36 | extern struct dvb_frontend *tda665x_attach(struct dvb_frontend *fe, | 36 | extern struct dvb_frontend *tda665x_attach(struct dvb_frontend *fe, |
37 | const struct tda665x_config *config, | 37 | const struct tda665x_config *config, |
diff --git a/drivers/media/dvb-frontends/tda8083.h b/drivers/media/dvb-frontends/tda8083.h index de6b1860dfdd..46be06fa7e0d 100644 --- a/drivers/media/dvb-frontends/tda8083.h +++ b/drivers/media/dvb-frontends/tda8083.h | |||
@@ -35,7 +35,7 @@ struct tda8083_config | |||
35 | u8 demod_address; | 35 | u8 demod_address; |
36 | }; | 36 | }; |
37 | 37 | ||
38 | #if IS_ENABLED(CONFIG_DVB_TDA8083) | 38 | #if IS_REACHABLE(CONFIG_DVB_TDA8083) |
39 | extern struct dvb_frontend* tda8083_attach(const struct tda8083_config* config, | 39 | extern struct dvb_frontend* tda8083_attach(const struct tda8083_config* config, |
40 | struct i2c_adapter* i2c); | 40 | struct i2c_adapter* i2c); |
41 | #else | 41 | #else |
diff --git a/drivers/media/dvb-frontends/tda8261.h b/drivers/media/dvb-frontends/tda8261.h index 55cf4ffcbfdf..9fa5b3076d5b 100644 --- a/drivers/media/dvb-frontends/tda8261.h +++ b/drivers/media/dvb-frontends/tda8261.h | |||
@@ -34,7 +34,7 @@ struct tda8261_config { | |||
34 | enum tda8261_step step_size; | 34 | enum tda8261_step step_size; |
35 | }; | 35 | }; |
36 | 36 | ||
37 | #if IS_ENABLED(CONFIG_DVB_TDA8261) | 37 | #if IS_REACHABLE(CONFIG_DVB_TDA8261) |
38 | 38 | ||
39 | extern struct dvb_frontend *tda8261_attach(struct dvb_frontend *fe, | 39 | extern struct dvb_frontend *tda8261_attach(struct dvb_frontend *fe, |
40 | const struct tda8261_config *config, | 40 | const struct tda8261_config *config, |
diff --git a/drivers/media/dvb-frontends/tda826x.h b/drivers/media/dvb-frontends/tda826x.h index 5f0f20e7e4f8..81abe1aebe9f 100644 --- a/drivers/media/dvb-frontends/tda826x.h +++ b/drivers/media/dvb-frontends/tda826x.h | |||
@@ -35,7 +35,7 @@ | |||
35 | * @param has_loopthrough Set to 1 if the card has a loopthrough RF connector. | 35 | * @param has_loopthrough Set to 1 if the card has a loopthrough RF connector. |
36 | * @return FE pointer on success, NULL on failure. | 36 | * @return FE pointer on success, NULL on failure. |
37 | */ | 37 | */ |
38 | #if IS_ENABLED(CONFIG_DVB_TDA826X) | 38 | #if IS_REACHABLE(CONFIG_DVB_TDA826X) |
39 | extern struct dvb_frontend* tda826x_attach(struct dvb_frontend *fe, int addr, | 39 | extern struct dvb_frontend* tda826x_attach(struct dvb_frontend *fe, int addr, |
40 | struct i2c_adapter *i2c, | 40 | struct i2c_adapter *i2c, |
41 | int has_loopthrough); | 41 | int has_loopthrough); |
diff --git a/drivers/media/dvb-frontends/ts2020.c b/drivers/media/dvb-frontends/ts2020.c index 9aba044dabed..90164a38cd36 100644 --- a/drivers/media/dvb-frontends/ts2020.c +++ b/drivers/media/dvb-frontends/ts2020.c | |||
@@ -26,12 +26,23 @@ | |||
26 | #define FREQ_OFFSET_LOW_SYM_RATE 3000 | 26 | #define FREQ_OFFSET_LOW_SYM_RATE 3000 |
27 | 27 | ||
28 | struct ts2020_priv { | 28 | struct ts2020_priv { |
29 | struct dvb_frontend *fe; | ||
29 | /* i2c details */ | 30 | /* i2c details */ |
30 | int i2c_address; | 31 | int i2c_address; |
31 | struct i2c_adapter *i2c; | 32 | struct i2c_adapter *i2c; |
32 | u8 clk_out_div; | 33 | u8 clk_out:2; |
34 | u8 clk_out_div:5; | ||
33 | u32 frequency; | 35 | u32 frequency; |
34 | u32 frequency_div; | 36 | u32 frequency_div; |
37 | #define TS2020_M88TS2020 0 | ||
38 | #define TS2020_M88TS2022 1 | ||
39 | u8 tuner; | ||
40 | u8 loop_through:1; | ||
41 | }; | ||
42 | |||
43 | struct ts2020_reg_val { | ||
44 | u8 reg; | ||
45 | u8 val; | ||
35 | }; | 46 | }; |
36 | 47 | ||
37 | static int ts2020_release(struct dvb_frontend *fe) | 48 | static int ts2020_release(struct dvb_frontend *fe) |
@@ -112,40 +123,77 @@ static int ts2020_readreg(struct dvb_frontend *fe, u8 reg) | |||
112 | static int ts2020_sleep(struct dvb_frontend *fe) | 123 | static int ts2020_sleep(struct dvb_frontend *fe) |
113 | { | 124 | { |
114 | struct ts2020_priv *priv = fe->tuner_priv; | 125 | struct ts2020_priv *priv = fe->tuner_priv; |
115 | int ret; | 126 | u8 u8tmp; |
116 | u8 buf[] = { 10, 0 }; | ||
117 | struct i2c_msg msg = { | ||
118 | .addr = priv->i2c_address, | ||
119 | .flags = 0, | ||
120 | .buf = buf, | ||
121 | .len = 2 | ||
122 | }; | ||
123 | 127 | ||
124 | if (fe->ops.i2c_gate_ctrl) | 128 | if (priv->tuner == TS2020_M88TS2020) |
125 | fe->ops.i2c_gate_ctrl(fe, 1); | 129 | u8tmp = 0x0a; /* XXX: probably wrong */ |
126 | 130 | else | |
127 | ret = i2c_transfer(priv->i2c, &msg, 1); | 131 | u8tmp = 0x00; |
128 | if (ret != 1) | ||
129 | printk(KERN_ERR "%s: i2c error\n", __func__); | ||
130 | |||
131 | if (fe->ops.i2c_gate_ctrl) | ||
132 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
133 | 132 | ||
134 | return (ret == 1) ? 0 : ret; | 133 | return ts2020_writereg(fe, u8tmp, 0x00); |
135 | } | 134 | } |
136 | 135 | ||
137 | static int ts2020_init(struct dvb_frontend *fe) | 136 | static int ts2020_init(struct dvb_frontend *fe) |
138 | { | 137 | { |
139 | struct ts2020_priv *priv = fe->tuner_priv; | 138 | struct ts2020_priv *priv = fe->tuner_priv; |
139 | int i; | ||
140 | u8 u8tmp; | ||
141 | |||
142 | if (priv->tuner == TS2020_M88TS2020) { | ||
143 | ts2020_writereg(fe, 0x42, 0x73); | ||
144 | ts2020_writereg(fe, 0x05, priv->clk_out_div); | ||
145 | ts2020_writereg(fe, 0x20, 0x27); | ||
146 | ts2020_writereg(fe, 0x07, 0x02); | ||
147 | ts2020_writereg(fe, 0x11, 0xff); | ||
148 | ts2020_writereg(fe, 0x60, 0xf9); | ||
149 | ts2020_writereg(fe, 0x08, 0x01); | ||
150 | ts2020_writereg(fe, 0x00, 0x41); | ||
151 | } else { | ||
152 | static const struct ts2020_reg_val reg_vals[] = { | ||
153 | {0x7d, 0x9d}, | ||
154 | {0x7c, 0x9a}, | ||
155 | {0x7a, 0x76}, | ||
156 | {0x3b, 0x01}, | ||
157 | {0x63, 0x88}, | ||
158 | {0x61, 0x85}, | ||
159 | {0x22, 0x30}, | ||
160 | {0x30, 0x40}, | ||
161 | {0x20, 0x23}, | ||
162 | {0x24, 0x02}, | ||
163 | {0x12, 0xa0}, | ||
164 | }; | ||
165 | |||
166 | ts2020_writereg(fe, 0x00, 0x01); | ||
167 | ts2020_writereg(fe, 0x00, 0x03); | ||
168 | |||
169 | switch (priv->clk_out) { | ||
170 | case TS2020_CLK_OUT_DISABLED: | ||
171 | u8tmp = 0x60; | ||
172 | break; | ||
173 | case TS2020_CLK_OUT_ENABLED: | ||
174 | u8tmp = 0x70; | ||
175 | ts2020_writereg(fe, 0x05, priv->clk_out_div); | ||
176 | break; | ||
177 | case TS2020_CLK_OUT_ENABLED_XTALOUT: | ||
178 | u8tmp = 0x6c; | ||
179 | break; | ||
180 | default: | ||
181 | u8tmp = 0x60; | ||
182 | break; | ||
183 | } | ||
140 | 184 | ||
141 | ts2020_writereg(fe, 0x42, 0x73); | 185 | ts2020_writereg(fe, 0x42, u8tmp); |
142 | ts2020_writereg(fe, 0x05, priv->clk_out_div); | 186 | |
143 | ts2020_writereg(fe, 0x20, 0x27); | 187 | if (priv->loop_through) |
144 | ts2020_writereg(fe, 0x07, 0x02); | 188 | u8tmp = 0xec; |
145 | ts2020_writereg(fe, 0x11, 0xff); | 189 | else |
146 | ts2020_writereg(fe, 0x60, 0xf9); | 190 | u8tmp = 0x6c; |
147 | ts2020_writereg(fe, 0x08, 0x01); | 191 | |
148 | ts2020_writereg(fe, 0x00, 0x41); | 192 | ts2020_writereg(fe, 0x62, u8tmp); |
193 | |||
194 | for (i = 0; i < ARRAY_SIZE(reg_vals); i++) | ||
195 | ts2020_writereg(fe, reg_vals[i].reg, reg_vals[i].val); | ||
196 | } | ||
149 | 197 | ||
150 | return 0; | 198 | return 0; |
151 | } | 199 | } |
@@ -203,7 +251,14 @@ static int ts2020_set_params(struct dvb_frontend *fe) | |||
203 | ndiv = ndiv + ndiv % 2; | 251 | ndiv = ndiv + ndiv % 2; |
204 | ndiv = ndiv - 1024; | 252 | ndiv = ndiv - 1024; |
205 | 253 | ||
206 | ret = ts2020_writereg(fe, 0x10, 0x80 | lo); | 254 | if (priv->tuner == TS2020_M88TS2020) { |
255 | lpf_coeff = 2766; | ||
256 | ret = ts2020_writereg(fe, 0x10, 0x80 | lo); | ||
257 | } else { | ||
258 | lpf_coeff = 3200; | ||
259 | ret = ts2020_writereg(fe, 0x10, 0x0b); | ||
260 | ret |= ts2020_writereg(fe, 0x11, 0x40); | ||
261 | } | ||
207 | 262 | ||
208 | /* Set frequency divider */ | 263 | /* Set frequency divider */ |
209 | ret |= ts2020_writereg(fe, 0x01, (ndiv >> 8) & 0xf); | 264 | ret |= ts2020_writereg(fe, 0x01, (ndiv >> 8) & 0xf); |
@@ -220,7 +275,8 @@ static int ts2020_set_params(struct dvb_frontend *fe) | |||
220 | ret |= ts2020_tuner_gate_ctrl(fe, 0x08); | 275 | ret |= ts2020_tuner_gate_ctrl(fe, 0x08); |
221 | 276 | ||
222 | /* Tuner RF */ | 277 | /* Tuner RF */ |
223 | ret |= ts2020_set_tuner_rf(fe); | 278 | if (priv->tuner == TS2020_M88TS2020) |
279 | ret |= ts2020_set_tuner_rf(fe); | ||
224 | 280 | ||
225 | gdiv28 = (TS2020_XTAL_FREQ / 1000 * 1694 + 500) / 1000; | 281 | gdiv28 = (TS2020_XTAL_FREQ / 1000 * 1694 + 500) / 1000; |
226 | ret |= ts2020_writereg(fe, 0x04, gdiv28 & 0xff); | 282 | ret |= ts2020_writereg(fe, 0x04, gdiv28 & 0xff); |
@@ -228,6 +284,15 @@ static int ts2020_set_params(struct dvb_frontend *fe) | |||
228 | if (ret < 0) | 284 | if (ret < 0) |
229 | return -ENODEV; | 285 | return -ENODEV; |
230 | 286 | ||
287 | if (priv->tuner == TS2020_M88TS2022) { | ||
288 | ret = ts2020_writereg(fe, 0x25, 0x00); | ||
289 | ret |= ts2020_writereg(fe, 0x27, 0x70); | ||
290 | ret |= ts2020_writereg(fe, 0x41, 0x09); | ||
291 | ret |= ts2020_writereg(fe, 0x08, 0x0b); | ||
292 | if (ret < 0) | ||
293 | return -ENODEV; | ||
294 | } | ||
295 | |||
231 | value = ts2020_readreg(fe, 0x26); | 296 | value = ts2020_readreg(fe, 0x26); |
232 | 297 | ||
233 | f3db = (symbol_rate * 135) / 200 + 2000; | 298 | f3db = (symbol_rate * 135) / 200 + 2000; |
@@ -243,8 +308,6 @@ static int ts2020_set_params(struct dvb_frontend *fe) | |||
243 | if (mlpf_max > 63) | 308 | if (mlpf_max > 63) |
244 | mlpf_max = 63; | 309 | mlpf_max = 63; |
245 | 310 | ||
246 | lpf_coeff = 2766; | ||
247 | |||
248 | nlpf = (f3db * gdiv28 * 2 / lpf_coeff / | 311 | nlpf = (f3db * gdiv28 * 2 / lpf_coeff / |
249 | (TS2020_XTAL_FREQ / 1000) + 1) / 2; | 312 | (TS2020_XTAL_FREQ / 1000) + 1) / 2; |
250 | if (nlpf > 23) | 313 | if (nlpf > 23) |
@@ -285,6 +348,13 @@ static int ts2020_get_frequency(struct dvb_frontend *fe, u32 *frequency) | |||
285 | { | 348 | { |
286 | struct ts2020_priv *priv = fe->tuner_priv; | 349 | struct ts2020_priv *priv = fe->tuner_priv; |
287 | *frequency = priv->frequency; | 350 | *frequency = priv->frequency; |
351 | |||
352 | return 0; | ||
353 | } | ||
354 | |||
355 | static int ts2020_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) | ||
356 | { | ||
357 | *frequency = 0; /* Zero-IF */ | ||
288 | return 0; | 358 | return 0; |
289 | } | 359 | } |
290 | 360 | ||
@@ -324,6 +394,7 @@ static struct dvb_tuner_ops ts2020_tuner_ops = { | |||
324 | .sleep = ts2020_sleep, | 394 | .sleep = ts2020_sleep, |
325 | .set_params = ts2020_set_params, | 395 | .set_params = ts2020_set_params, |
326 | .get_frequency = ts2020_get_frequency, | 396 | .get_frequency = ts2020_get_frequency, |
397 | .get_if_frequency = ts2020_get_if_frequency, | ||
327 | .get_rf_strength = ts2020_read_signal_strength, | 398 | .get_rf_strength = ts2020_read_signal_strength, |
328 | }; | 399 | }; |
329 | 400 | ||
@@ -340,8 +411,10 @@ struct dvb_frontend *ts2020_attach(struct dvb_frontend *fe, | |||
340 | 411 | ||
341 | priv->i2c_address = config->tuner_address; | 412 | priv->i2c_address = config->tuner_address; |
342 | priv->i2c = i2c; | 413 | priv->i2c = i2c; |
414 | priv->clk_out = config->clk_out; | ||
343 | priv->clk_out_div = config->clk_out_div; | 415 | priv->clk_out_div = config->clk_out_div; |
344 | priv->frequency_div = config->frequency_div; | 416 | priv->frequency_div = config->frequency_div; |
417 | priv->fe = fe; | ||
345 | fe->tuner_priv = priv; | 418 | fe->tuner_priv = priv; |
346 | 419 | ||
347 | if (!priv->frequency_div) | 420 | if (!priv->frequency_div) |
@@ -358,9 +431,13 @@ struct dvb_frontend *ts2020_attach(struct dvb_frontend *fe, | |||
358 | 431 | ||
359 | /* Check the tuner version */ | 432 | /* Check the tuner version */ |
360 | buf = ts2020_readreg(fe, 0x00); | 433 | buf = ts2020_readreg(fe, 0x00); |
361 | if ((buf == 0x01) || (buf == 0x41) || (buf == 0x81)) | 434 | if ((buf == 0x01) || (buf == 0x41) || (buf == 0x81)) { |
362 | printk(KERN_INFO "%s: Find tuner TS2020!\n", __func__); | 435 | printk(KERN_INFO "%s: Find tuner TS2020!\n", __func__); |
363 | else { | 436 | priv->tuner = TS2020_M88TS2020; |
437 | } else if ((buf == 0x83) || (buf == 0xc3)) { | ||
438 | printk(KERN_INFO "%s: Find tuner TS2022!\n", __func__); | ||
439 | priv->tuner = TS2020_M88TS2022; | ||
440 | } else { | ||
364 | printk(KERN_ERR "%s: Read tuner reg[0] = %d\n", __func__, buf); | 441 | printk(KERN_ERR "%s: Read tuner reg[0] = %d\n", __func__, buf); |
365 | kfree(priv); | 442 | kfree(priv); |
366 | return NULL; | 443 | return NULL; |
@@ -373,6 +450,165 @@ struct dvb_frontend *ts2020_attach(struct dvb_frontend *fe, | |||
373 | } | 450 | } |
374 | EXPORT_SYMBOL(ts2020_attach); | 451 | EXPORT_SYMBOL(ts2020_attach); |
375 | 452 | ||
453 | static int ts2020_probe(struct i2c_client *client, | ||
454 | const struct i2c_device_id *id) | ||
455 | { | ||
456 | struct ts2020_config *pdata = client->dev.platform_data; | ||
457 | struct dvb_frontend *fe = pdata->fe; | ||
458 | struct ts2020_priv *dev; | ||
459 | int ret; | ||
460 | u8 u8tmp; | ||
461 | unsigned int utmp; | ||
462 | char *chip_str; | ||
463 | |||
464 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
465 | if (!dev) { | ||
466 | ret = -ENOMEM; | ||
467 | goto err; | ||
468 | } | ||
469 | |||
470 | dev->i2c = client->adapter; | ||
471 | dev->i2c_address = client->addr; | ||
472 | dev->clk_out = pdata->clk_out; | ||
473 | dev->clk_out_div = pdata->clk_out_div; | ||
474 | dev->frequency_div = pdata->frequency_div; | ||
475 | dev->fe = fe; | ||
476 | fe->tuner_priv = dev; | ||
477 | |||
478 | /* check if the tuner is there */ | ||
479 | ret = ts2020_readreg(fe, 0x00); | ||
480 | if (ret < 0) | ||
481 | goto err; | ||
482 | utmp = ret; | ||
483 | |||
484 | if ((utmp & 0x03) == 0x00) { | ||
485 | ret = ts2020_writereg(fe, 0x00, 0x01); | ||
486 | if (ret) | ||
487 | goto err; | ||
488 | |||
489 | usleep_range(2000, 50000); | ||
490 | } | ||
491 | |||
492 | ret = ts2020_writereg(fe, 0x00, 0x03); | ||
493 | if (ret) | ||
494 | goto err; | ||
495 | |||
496 | usleep_range(2000, 50000); | ||
497 | |||
498 | ret = ts2020_readreg(fe, 0x00); | ||
499 | if (ret < 0) | ||
500 | goto err; | ||
501 | utmp = ret; | ||
502 | |||
503 | dev_dbg(&client->dev, "chip_id=%02x\n", utmp); | ||
504 | |||
505 | switch (utmp) { | ||
506 | case 0x01: | ||
507 | case 0x41: | ||
508 | case 0x81: | ||
509 | dev->tuner = TS2020_M88TS2020; | ||
510 | chip_str = "TS2020"; | ||
511 | if (!dev->frequency_div) | ||
512 | dev->frequency_div = 1060000; | ||
513 | break; | ||
514 | case 0xc3: | ||
515 | case 0x83: | ||
516 | dev->tuner = TS2020_M88TS2022; | ||
517 | chip_str = "TS2022"; | ||
518 | if (!dev->frequency_div) | ||
519 | dev->frequency_div = 1103000; | ||
520 | break; | ||
521 | default: | ||
522 | ret = -ENODEV; | ||
523 | goto err; | ||
524 | } | ||
525 | |||
526 | if (dev->tuner == TS2020_M88TS2022) { | ||
527 | switch (dev->clk_out) { | ||
528 | case TS2020_CLK_OUT_DISABLED: | ||
529 | u8tmp = 0x60; | ||
530 | break; | ||
531 | case TS2020_CLK_OUT_ENABLED: | ||
532 | u8tmp = 0x70; | ||
533 | ret = ts2020_writereg(fe, 0x05, dev->clk_out_div); | ||
534 | if (ret) | ||
535 | goto err; | ||
536 | break; | ||
537 | case TS2020_CLK_OUT_ENABLED_XTALOUT: | ||
538 | u8tmp = 0x6c; | ||
539 | break; | ||
540 | default: | ||
541 | ret = -EINVAL; | ||
542 | goto err; | ||
543 | } | ||
544 | |||
545 | ret = ts2020_writereg(fe, 0x42, u8tmp); | ||
546 | if (ret) | ||
547 | goto err; | ||
548 | |||
549 | if (dev->loop_through) | ||
550 | u8tmp = 0xec; | ||
551 | else | ||
552 | u8tmp = 0x6c; | ||
553 | |||
554 | ret = ts2020_writereg(fe, 0x62, u8tmp); | ||
555 | if (ret) | ||
556 | goto err; | ||
557 | } | ||
558 | |||
559 | /* sleep */ | ||
560 | ret = ts2020_writereg(fe, 0x00, 0x00); | ||
561 | if (ret) | ||
562 | goto err; | ||
563 | |||
564 | dev_info(&client->dev, | ||
565 | "Montage Technology %s successfully identified\n", chip_str); | ||
566 | |||
567 | memcpy(&fe->ops.tuner_ops, &ts2020_tuner_ops, | ||
568 | sizeof(struct dvb_tuner_ops)); | ||
569 | fe->ops.tuner_ops.release = NULL; | ||
570 | |||
571 | i2c_set_clientdata(client, dev); | ||
572 | return 0; | ||
573 | err: | ||
574 | dev_dbg(&client->dev, "failed=%d\n", ret); | ||
575 | kfree(dev); | ||
576 | return ret; | ||
577 | } | ||
578 | |||
579 | static int ts2020_remove(struct i2c_client *client) | ||
580 | { | ||
581 | struct ts2020_priv *dev = i2c_get_clientdata(client); | ||
582 | struct dvb_frontend *fe = dev->fe; | ||
583 | |||
584 | dev_dbg(&client->dev, "\n"); | ||
585 | |||
586 | memset(&fe->ops.tuner_ops, 0, sizeof(struct dvb_tuner_ops)); | ||
587 | fe->tuner_priv = NULL; | ||
588 | kfree(dev); | ||
589 | |||
590 | return 0; | ||
591 | } | ||
592 | |||
593 | static const struct i2c_device_id ts2020_id_table[] = { | ||
594 | {"ts2020", 0}, | ||
595 | {"ts2022", 0}, | ||
596 | {} | ||
597 | }; | ||
598 | MODULE_DEVICE_TABLE(i2c, ts2020_id_table); | ||
599 | |||
600 | static struct i2c_driver ts2020_driver = { | ||
601 | .driver = { | ||
602 | .owner = THIS_MODULE, | ||
603 | .name = "ts2020", | ||
604 | }, | ||
605 | .probe = ts2020_probe, | ||
606 | .remove = ts2020_remove, | ||
607 | .id_table = ts2020_id_table, | ||
608 | }; | ||
609 | |||
610 | module_i2c_driver(ts2020_driver); | ||
611 | |||
376 | MODULE_AUTHOR("Konstantin Dimitrov <kosio.dimitrov@gmail.com>"); | 612 | MODULE_AUTHOR("Konstantin Dimitrov <kosio.dimitrov@gmail.com>"); |
377 | MODULE_DESCRIPTION("Montage Technology TS2020 - Silicon tuner driver module"); | 613 | MODULE_DESCRIPTION("Montage Technology TS2020 - Silicon tuner driver module"); |
378 | MODULE_LICENSE("GPL"); | 614 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/media/dvb-frontends/ts2020.h b/drivers/media/dvb-frontends/ts2020.h index b2fe6bb3a38b..1714af94eca2 100644 --- a/drivers/media/dvb-frontends/ts2020.h +++ b/drivers/media/dvb-frontends/ts2020.h | |||
@@ -27,11 +27,34 @@ | |||
27 | 27 | ||
28 | struct ts2020_config { | 28 | struct ts2020_config { |
29 | u8 tuner_address; | 29 | u8 tuner_address; |
30 | u8 clk_out_div; | ||
31 | u32 frequency_div; | 30 | u32 frequency_div; |
31 | |||
32 | /* | ||
33 | * RF loop-through | ||
34 | */ | ||
35 | u8 loop_through:1; | ||
36 | |||
37 | /* | ||
38 | * clock output | ||
39 | */ | ||
40 | #define TS2020_CLK_OUT_DISABLED 0 | ||
41 | #define TS2020_CLK_OUT_ENABLED 1 | ||
42 | #define TS2020_CLK_OUT_ENABLED_XTALOUT 2 | ||
43 | u8 clk_out:2; | ||
44 | |||
45 | /* | ||
46 | * clock output divider | ||
47 | * 1 - 31 | ||
48 | */ | ||
49 | u8 clk_out_div:5; | ||
50 | |||
51 | /* | ||
52 | * pointer to DVB frontend | ||
53 | */ | ||
54 | struct dvb_frontend *fe; | ||
32 | }; | 55 | }; |
33 | 56 | ||
34 | #if IS_ENABLED(CONFIG_DVB_TS2020) | 57 | #if IS_REACHABLE(CONFIG_DVB_TS2020) |
35 | 58 | ||
36 | extern struct dvb_frontend *ts2020_attach( | 59 | extern struct dvb_frontend *ts2020_attach( |
37 | struct dvb_frontend *fe, | 60 | struct dvb_frontend *fe, |
diff --git a/drivers/media/dvb-frontends/tua6100.h b/drivers/media/dvb-frontends/tua6100.h index 83a9c30e67ca..52919e04e258 100644 --- a/drivers/media/dvb-frontends/tua6100.h +++ b/drivers/media/dvb-frontends/tua6100.h | |||
@@ -34,7 +34,7 @@ | |||
34 | #include <linux/i2c.h> | 34 | #include <linux/i2c.h> |
35 | #include "dvb_frontend.h" | 35 | #include "dvb_frontend.h" |
36 | 36 | ||
37 | #if IS_ENABLED(CONFIG_DVB_TUA6100) | 37 | #if IS_REACHABLE(CONFIG_DVB_TUA6100) |
38 | extern struct dvb_frontend *tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c); | 38 | extern struct dvb_frontend *tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c); |
39 | #else | 39 | #else |
40 | static inline struct dvb_frontend* tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c) | 40 | static inline struct dvb_frontend* tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c) |
diff --git a/drivers/media/dvb-frontends/ves1820.h b/drivers/media/dvb-frontends/ves1820.h index c073f353ac38..ece46fdcd714 100644 --- a/drivers/media/dvb-frontends/ves1820.h +++ b/drivers/media/dvb-frontends/ves1820.h | |||
@@ -41,7 +41,7 @@ struct ves1820_config | |||
41 | u8 selagc:1; | 41 | u8 selagc:1; |
42 | }; | 42 | }; |
43 | 43 | ||
44 | #if IS_ENABLED(CONFIG_DVB_VES1820) | 44 | #if IS_REACHABLE(CONFIG_DVB_VES1820) |
45 | extern struct dvb_frontend* ves1820_attach(const struct ves1820_config* config, | 45 | extern struct dvb_frontend* ves1820_attach(const struct ves1820_config* config, |
46 | struct i2c_adapter* i2c, u8 pwm); | 46 | struct i2c_adapter* i2c, u8 pwm); |
47 | #else | 47 | #else |
diff --git a/drivers/media/dvb-frontends/ves1x93.h b/drivers/media/dvb-frontends/ves1x93.h index 2307caea6aec..4510fe2f6676 100644 --- a/drivers/media/dvb-frontends/ves1x93.h +++ b/drivers/media/dvb-frontends/ves1x93.h | |||
@@ -40,7 +40,7 @@ struct ves1x93_config | |||
40 | u8 invert_pwm:1; | 40 | u8 invert_pwm:1; |
41 | }; | 41 | }; |
42 | 42 | ||
43 | #if IS_ENABLED(CONFIG_DVB_VES1X93) | 43 | #if IS_REACHABLE(CONFIG_DVB_VES1X93) |
44 | extern struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, | 44 | extern struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, |
45 | struct i2c_adapter* i2c); | 45 | struct i2c_adapter* i2c); |
46 | #else | 46 | #else |
diff --git a/drivers/media/dvb-frontends/zl10036.h b/drivers/media/dvb-frontends/zl10036.h index 5f1e8217eeb6..670e76a654ee 100644 --- a/drivers/media/dvb-frontends/zl10036.h +++ b/drivers/media/dvb-frontends/zl10036.h | |||
@@ -38,7 +38,7 @@ struct zl10036_config { | |||
38 | int rf_loop_enable; | 38 | int rf_loop_enable; |
39 | }; | 39 | }; |
40 | 40 | ||
41 | #if IS_ENABLED(CONFIG_DVB_ZL10036) | 41 | #if IS_REACHABLE(CONFIG_DVB_ZL10036) |
42 | extern struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe, | 42 | extern struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe, |
43 | const struct zl10036_config *config, struct i2c_adapter *i2c); | 43 | const struct zl10036_config *config, struct i2c_adapter *i2c); |
44 | #else | 44 | #else |
diff --git a/drivers/media/dvb-frontends/zl10039.h b/drivers/media/dvb-frontends/zl10039.h index 750b9bca9d02..070929444e71 100644 --- a/drivers/media/dvb-frontends/zl10039.h +++ b/drivers/media/dvb-frontends/zl10039.h | |||
@@ -24,7 +24,7 @@ | |||
24 | 24 | ||
25 | #include <linux/kconfig.h> | 25 | #include <linux/kconfig.h> |
26 | 26 | ||
27 | #if IS_ENABLED(CONFIG_DVB_ZL10039) | 27 | #if IS_REACHABLE(CONFIG_DVB_ZL10039) |
28 | struct dvb_frontend *zl10039_attach(struct dvb_frontend *fe, | 28 | struct dvb_frontend *zl10039_attach(struct dvb_frontend *fe, |
29 | u8 i2c_addr, | 29 | u8 i2c_addr, |
30 | struct i2c_adapter *i2c); | 30 | struct i2c_adapter *i2c); |
diff --git a/drivers/media/dvb-frontends/zl10353.h b/drivers/media/dvb-frontends/zl10353.h index 50c1004aef36..37aa6e8f454a 100644 --- a/drivers/media/dvb-frontends/zl10353.h +++ b/drivers/media/dvb-frontends/zl10353.h | |||
@@ -47,7 +47,7 @@ struct zl10353_config | |||
47 | u8 pll_0; /* default: 0x15 */ | 47 | u8 pll_0; /* default: 0x15 */ |
48 | }; | 48 | }; |
49 | 49 | ||
50 | #if IS_ENABLED(CONFIG_DVB_ZL10353) | 50 | #if IS_REACHABLE(CONFIG_DVB_ZL10353) |
51 | extern struct dvb_frontend* zl10353_attach(const struct zl10353_config *config, | 51 | extern struct dvb_frontend* zl10353_attach(const struct zl10353_config *config, |
52 | struct i2c_adapter *i2c); | 52 | struct i2c_adapter *i2c); |
53 | #else | 53 | #else |
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index da58c9bb67c2..6f30ea76151a 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig | |||
@@ -466,6 +466,17 @@ config VIDEO_APTINA_PLL | |||
466 | config VIDEO_SMIAPP_PLL | 466 | config VIDEO_SMIAPP_PLL |
467 | tristate | 467 | tristate |
468 | 468 | ||
469 | config VIDEO_OV2659 | ||
470 | tristate "OmniVision OV2659 sensor support" | ||
471 | depends on VIDEO_V4L2 && I2C | ||
472 | depends on MEDIA_CAMERA_SUPPORT | ||
473 | ---help--- | ||
474 | This is a Video4Linux2 sensor-level driver for the OmniVision | ||
475 | OV2659 camera. | ||
476 | |||
477 | To compile this driver as a module, choose M here: the | ||
478 | module will be called ov2659. | ||
479 | |||
469 | config VIDEO_OV7640 | 480 | config VIDEO_OV7640 |
470 | tristate "OmniVision OV7640 sensor support" | 481 | tristate "OmniVision OV7640 sensor support" |
471 | depends on I2C && VIDEO_V4L2 | 482 | depends on I2C && VIDEO_V4L2 |
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index 9858900168bf..f165faea5b3f 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile | |||
@@ -77,3 +77,4 @@ obj-$(CONFIG_VIDEO_SMIAPP_PLL) += smiapp-pll.o | |||
77 | obj-$(CONFIG_VIDEO_AK881X) += ak881x.o | 77 | obj-$(CONFIG_VIDEO_AK881X) += ak881x.o |
78 | obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o | 78 | obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o |
79 | obj-$(CONFIG_VIDEO_ML86V7667) += ml86v7667.o | 79 | obj-$(CONFIG_VIDEO_ML86V7667) += ml86v7667.o |
80 | obj-$(CONFIG_VIDEO_OV2659) += ov2659.o | ||
diff --git a/drivers/media/i2c/ad9389b.c b/drivers/media/i2c/ad9389b.c index fada17566205..69094ab047b1 100644 --- a/drivers/media/i2c/ad9389b.c +++ b/drivers/media/i2c/ad9389b.c | |||
@@ -239,8 +239,8 @@ static void ad9389b_set_IT_content_AVI_InfoFrame(struct v4l2_subdev *sd) | |||
239 | { | 239 | { |
240 | struct ad9389b_state *state = get_ad9389b_state(sd); | 240 | struct ad9389b_state *state = get_ad9389b_state(sd); |
241 | 241 | ||
242 | if (state->dv_timings.bt.standards & V4L2_DV_BT_STD_CEA861) { | 242 | if (state->dv_timings.bt.flags & V4L2_DV_FL_IS_CE_VIDEO) { |
243 | /* CEA format, not IT */ | 243 | /* CE format, not IT */ |
244 | ad9389b_wr_and_or(sd, 0xcd, 0xbf, 0x00); | 244 | ad9389b_wr_and_or(sd, 0xcd, 0xbf, 0x00); |
245 | } else { | 245 | } else { |
246 | /* IT format */ | 246 | /* IT format */ |
@@ -255,11 +255,11 @@ static int ad9389b_set_rgb_quantization_mode(struct v4l2_subdev *sd, struct v4l2 | |||
255 | switch (ctrl->val) { | 255 | switch (ctrl->val) { |
256 | case V4L2_DV_RGB_RANGE_AUTO: | 256 | case V4L2_DV_RGB_RANGE_AUTO: |
257 | /* automatic */ | 257 | /* automatic */ |
258 | if (state->dv_timings.bt.standards & V4L2_DV_BT_STD_CEA861) { | 258 | if (state->dv_timings.bt.flags & V4L2_DV_FL_IS_CE_VIDEO) { |
259 | /* cea format, RGB limited range (16-235) */ | 259 | /* CE format, RGB limited range (16-235) */ |
260 | ad9389b_csc_rgb_full2limit(sd, true); | 260 | ad9389b_csc_rgb_full2limit(sd, true); |
261 | } else { | 261 | } else { |
262 | /* not cea format, RGB full range (0-255) */ | 262 | /* not CE format, RGB full range (0-255) */ |
263 | ad9389b_csc_rgb_full2limit(sd, false); | 263 | ad9389b_csc_rgb_full2limit(sd, false); |
264 | } | 264 | } |
265 | break; | 265 | break; |
diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c index b75878c27c2a..a493c0b0b5fe 100644 --- a/drivers/media/i2c/adv7180.c +++ b/drivers/media/i2c/adv7180.c | |||
@@ -582,7 +582,7 @@ static void adv7180_exit_controls(struct adv7180_state *state) | |||
582 | } | 582 | } |
583 | 583 | ||
584 | static int adv7180_enum_mbus_code(struct v4l2_subdev *sd, | 584 | static int adv7180_enum_mbus_code(struct v4l2_subdev *sd, |
585 | struct v4l2_subdev_fh *fh, | 585 | struct v4l2_subdev_pad_config *cfg, |
586 | struct v4l2_subdev_mbus_code_enum *code) | 586 | struct v4l2_subdev_mbus_code_enum *code) |
587 | { | 587 | { |
588 | if (code->index != 0) | 588 | if (code->index != 0) |
@@ -645,13 +645,13 @@ static int adv7180_set_field_mode(struct adv7180_state *state) | |||
645 | } | 645 | } |
646 | 646 | ||
647 | static int adv7180_get_pad_format(struct v4l2_subdev *sd, | 647 | static int adv7180_get_pad_format(struct v4l2_subdev *sd, |
648 | struct v4l2_subdev_fh *fh, | 648 | struct v4l2_subdev_pad_config *cfg, |
649 | struct v4l2_subdev_format *format) | 649 | struct v4l2_subdev_format *format) |
650 | { | 650 | { |
651 | struct adv7180_state *state = to_state(sd); | 651 | struct adv7180_state *state = to_state(sd); |
652 | 652 | ||
653 | if (format->which == V4L2_SUBDEV_FORMAT_TRY) { | 653 | if (format->which == V4L2_SUBDEV_FORMAT_TRY) { |
654 | format->format = *v4l2_subdev_get_try_format(fh, 0); | 654 | format->format = *v4l2_subdev_get_try_format(sd, cfg, 0); |
655 | } else { | 655 | } else { |
656 | adv7180_mbus_fmt(sd, &format->format); | 656 | adv7180_mbus_fmt(sd, &format->format); |
657 | format->format.field = state->field; | 657 | format->format.field = state->field; |
@@ -661,7 +661,7 @@ static int adv7180_get_pad_format(struct v4l2_subdev *sd, | |||
661 | } | 661 | } |
662 | 662 | ||
663 | static int adv7180_set_pad_format(struct v4l2_subdev *sd, | 663 | static int adv7180_set_pad_format(struct v4l2_subdev *sd, |
664 | struct v4l2_subdev_fh *fh, | 664 | struct v4l2_subdev_pad_config *cfg, |
665 | struct v4l2_subdev_format *format) | 665 | struct v4l2_subdev_format *format) |
666 | { | 666 | { |
667 | struct adv7180_state *state = to_state(sd); | 667 | struct adv7180_state *state = to_state(sd); |
@@ -686,7 +686,7 @@ static int adv7180_set_pad_format(struct v4l2_subdev *sd, | |||
686 | adv7180_set_power(state, true); | 686 | adv7180_set_power(state, true); |
687 | } | 687 | } |
688 | } else { | 688 | } else { |
689 | framefmt = v4l2_subdev_get_try_format(fh, 0); | 689 | framefmt = v4l2_subdev_get_try_format(sd, cfg, 0); |
690 | *framefmt = format->format; | 690 | *framefmt = format->format; |
691 | } | 691 | } |
692 | 692 | ||
diff --git a/drivers/media/i2c/adv7343.c b/drivers/media/i2c/adv7343.c index 9d38f7b36cd1..7c50833e7d17 100644 --- a/drivers/media/i2c/adv7343.c +++ b/drivers/media/i2c/adv7343.c | |||
@@ -506,7 +506,6 @@ static int adv7343_remove(struct i2c_client *client) | |||
506 | struct adv7343_state *state = to_state(sd); | 506 | struct adv7343_state *state = to_state(sd); |
507 | 507 | ||
508 | v4l2_async_unregister_subdev(&state->sd); | 508 | v4l2_async_unregister_subdev(&state->sd); |
509 | v4l2_device_unregister_subdev(sd); | ||
510 | v4l2_ctrl_handler_free(&state->hdl); | 509 | v4l2_ctrl_handler_free(&state->hdl); |
511 | 510 | ||
512 | return 0; | 511 | return 0; |
diff --git a/drivers/media/i2c/adv7511.c b/drivers/media/i2c/adv7511.c index 81736aaf0f31..12d93203d405 100644 --- a/drivers/media/i2c/adv7511.c +++ b/drivers/media/i2c/adv7511.c | |||
@@ -312,8 +312,8 @@ static void adv7511_csc_rgb_full2limit(struct v4l2_subdev *sd, bool enable) | |||
312 | static void adv7511_set_IT_content_AVI_InfoFrame(struct v4l2_subdev *sd) | 312 | static void adv7511_set_IT_content_AVI_InfoFrame(struct v4l2_subdev *sd) |
313 | { | 313 | { |
314 | struct adv7511_state *state = get_adv7511_state(sd); | 314 | struct adv7511_state *state = get_adv7511_state(sd); |
315 | if (state->dv_timings.bt.standards & V4L2_DV_BT_STD_CEA861) { | 315 | if (state->dv_timings.bt.flags & V4L2_DV_FL_IS_CE_VIDEO) { |
316 | /* CEA format, not IT */ | 316 | /* CE format, not IT */ |
317 | adv7511_wr_and_or(sd, 0x57, 0x7f, 0x00); | 317 | adv7511_wr_and_or(sd, 0x57, 0x7f, 0x00); |
318 | } else { | 318 | } else { |
319 | /* IT format */ | 319 | /* IT format */ |
@@ -331,11 +331,11 @@ static int adv7511_set_rgb_quantization_mode(struct v4l2_subdev *sd, struct v4l2 | |||
331 | /* automatic */ | 331 | /* automatic */ |
332 | struct adv7511_state *state = get_adv7511_state(sd); | 332 | struct adv7511_state *state = get_adv7511_state(sd); |
333 | 333 | ||
334 | if (state->dv_timings.bt.standards & V4L2_DV_BT_STD_CEA861) { | 334 | if (state->dv_timings.bt.flags & V4L2_DV_FL_IS_CE_VIDEO) { |
335 | /* cea format, RGB limited range (16-235) */ | 335 | /* CE format, RGB limited range (16-235) */ |
336 | adv7511_csc_rgb_full2limit(sd, true); | 336 | adv7511_csc_rgb_full2limit(sd, true); |
337 | } else { | 337 | } else { |
338 | /* not cea format, RGB full range (0-255) */ | 338 | /* not CE format, RGB full range (0-255) */ |
339 | adv7511_csc_rgb_full2limit(sd, false); | 339 | adv7511_csc_rgb_full2limit(sd, false); |
340 | } | 340 | } |
341 | } | 341 | } |
@@ -810,7 +810,7 @@ static int adv7511_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) | |||
810 | } | 810 | } |
811 | 811 | ||
812 | static int adv7511_enum_mbus_code(struct v4l2_subdev *sd, | 812 | static int adv7511_enum_mbus_code(struct v4l2_subdev *sd, |
813 | struct v4l2_subdev_fh *fh, | 813 | struct v4l2_subdev_pad_config *cfg, |
814 | struct v4l2_subdev_mbus_code_enum *code) | 814 | struct v4l2_subdev_mbus_code_enum *code) |
815 | { | 815 | { |
816 | if (code->pad != 0) | 816 | if (code->pad != 0) |
@@ -842,8 +842,9 @@ static void adv7511_fill_format(struct adv7511_state *state, | |||
842 | format->field = V4L2_FIELD_NONE; | 842 | format->field = V4L2_FIELD_NONE; |
843 | } | 843 | } |
844 | 844 | ||
845 | static int adv7511_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | 845 | static int adv7511_get_fmt(struct v4l2_subdev *sd, |
846 | struct v4l2_subdev_format *format) | 846 | struct v4l2_subdev_pad_config *cfg, |
847 | struct v4l2_subdev_format *format) | ||
847 | { | 848 | { |
848 | struct adv7511_state *state = get_adv7511_state(sd); | 849 | struct adv7511_state *state = get_adv7511_state(sd); |
849 | 850 | ||
@@ -855,7 +856,7 @@ static int adv7511_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
855 | if (format->which == V4L2_SUBDEV_FORMAT_TRY) { | 856 | if (format->which == V4L2_SUBDEV_FORMAT_TRY) { |
856 | struct v4l2_mbus_framefmt *fmt; | 857 | struct v4l2_mbus_framefmt *fmt; |
857 | 858 | ||
858 | fmt = v4l2_subdev_get_try_format(fh, format->pad); | 859 | fmt = v4l2_subdev_get_try_format(sd, cfg, format->pad); |
859 | format->format.code = fmt->code; | 860 | format->format.code = fmt->code; |
860 | format->format.colorspace = fmt->colorspace; | 861 | format->format.colorspace = fmt->colorspace; |
861 | format->format.ycbcr_enc = fmt->ycbcr_enc; | 862 | format->format.ycbcr_enc = fmt->ycbcr_enc; |
@@ -870,8 +871,9 @@ static int adv7511_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
870 | return 0; | 871 | return 0; |
871 | } | 872 | } |
872 | 873 | ||
873 | static int adv7511_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | 874 | static int adv7511_set_fmt(struct v4l2_subdev *sd, |
874 | struct v4l2_subdev_format *format) | 875 | struct v4l2_subdev_pad_config *cfg, |
876 | struct v4l2_subdev_format *format) | ||
875 | { | 877 | { |
876 | struct adv7511_state *state = get_adv7511_state(sd); | 878 | struct adv7511_state *state = get_adv7511_state(sd); |
877 | /* | 879 | /* |
@@ -905,7 +907,7 @@ static int adv7511_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
905 | if (format->which == V4L2_SUBDEV_FORMAT_TRY) { | 907 | if (format->which == V4L2_SUBDEV_FORMAT_TRY) { |
906 | struct v4l2_mbus_framefmt *fmt; | 908 | struct v4l2_mbus_framefmt *fmt; |
907 | 909 | ||
908 | fmt = v4l2_subdev_get_try_format(fh, format->pad); | 910 | fmt = v4l2_subdev_get_try_format(sd, cfg, format->pad); |
909 | fmt->code = format->format.code; | 911 | fmt->code = format->format.code; |
910 | fmt->colorspace = format->format.colorspace; | 912 | fmt->colorspace = format->format.colorspace; |
911 | fmt->ycbcr_enc = format->format.ycbcr_enc; | 913 | fmt->ycbcr_enc = format->format.ycbcr_enc; |
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index d228b7c82310..60ffcf098bef 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c | |||
@@ -53,41 +53,41 @@ MODULE_AUTHOR("Mats Randgaard <mats.randgaard@cisco.com>"); | |||
53 | MODULE_LICENSE("GPL"); | 53 | MODULE_LICENSE("GPL"); |
54 | 54 | ||
55 | /* ADV7604 system clock frequency */ | 55 | /* ADV7604 system clock frequency */ |
56 | #define ADV7604_fsc (28636360) | 56 | #define ADV76XX_FSC (28636360) |
57 | 57 | ||
58 | #define ADV7604_RGB_OUT (1 << 1) | 58 | #define ADV76XX_RGB_OUT (1 << 1) |
59 | 59 | ||
60 | #define ADV7604_OP_FORMAT_SEL_8BIT (0 << 0) | 60 | #define ADV76XX_OP_FORMAT_SEL_8BIT (0 << 0) |
61 | #define ADV7604_OP_FORMAT_SEL_10BIT (1 << 0) | 61 | #define ADV7604_OP_FORMAT_SEL_10BIT (1 << 0) |
62 | #define ADV7604_OP_FORMAT_SEL_12BIT (2 << 0) | 62 | #define ADV76XX_OP_FORMAT_SEL_12BIT (2 << 0) |
63 | 63 | ||
64 | #define ADV7604_OP_MODE_SEL_SDR_422 (0 << 5) | 64 | #define ADV76XX_OP_MODE_SEL_SDR_422 (0 << 5) |
65 | #define ADV7604_OP_MODE_SEL_DDR_422 (1 << 5) | 65 | #define ADV7604_OP_MODE_SEL_DDR_422 (1 << 5) |
66 | #define ADV7604_OP_MODE_SEL_SDR_444 (2 << 5) | 66 | #define ADV76XX_OP_MODE_SEL_SDR_444 (2 << 5) |
67 | #define ADV7604_OP_MODE_SEL_DDR_444 (3 << 5) | 67 | #define ADV7604_OP_MODE_SEL_DDR_444 (3 << 5) |
68 | #define ADV7604_OP_MODE_SEL_SDR_422_2X (4 << 5) | 68 | #define ADV76XX_OP_MODE_SEL_SDR_422_2X (4 << 5) |
69 | #define ADV7604_OP_MODE_SEL_ADI_CM (5 << 5) | 69 | #define ADV7604_OP_MODE_SEL_ADI_CM (5 << 5) |
70 | 70 | ||
71 | #define ADV7604_OP_CH_SEL_GBR (0 << 5) | 71 | #define ADV76XX_OP_CH_SEL_GBR (0 << 5) |
72 | #define ADV7604_OP_CH_SEL_GRB (1 << 5) | 72 | #define ADV76XX_OP_CH_SEL_GRB (1 << 5) |
73 | #define ADV7604_OP_CH_SEL_BGR (2 << 5) | 73 | #define ADV76XX_OP_CH_SEL_BGR (2 << 5) |
74 | #define ADV7604_OP_CH_SEL_RGB (3 << 5) | 74 | #define ADV76XX_OP_CH_SEL_RGB (3 << 5) |
75 | #define ADV7604_OP_CH_SEL_BRG (4 << 5) | 75 | #define ADV76XX_OP_CH_SEL_BRG (4 << 5) |
76 | #define ADV7604_OP_CH_SEL_RBG (5 << 5) | 76 | #define ADV76XX_OP_CH_SEL_RBG (5 << 5) |
77 | 77 | ||
78 | #define ADV7604_OP_SWAP_CB_CR (1 << 0) | 78 | #define ADV76XX_OP_SWAP_CB_CR (1 << 0) |
79 | 79 | ||
80 | enum adv7604_type { | 80 | enum adv76xx_type { |
81 | ADV7604, | 81 | ADV7604, |
82 | ADV7611, | 82 | ADV7611, |
83 | }; | 83 | }; |
84 | 84 | ||
85 | struct adv7604_reg_seq { | 85 | struct adv76xx_reg_seq { |
86 | unsigned int reg; | 86 | unsigned int reg; |
87 | u8 val; | 87 | u8 val; |
88 | }; | 88 | }; |
89 | 89 | ||
90 | struct adv7604_format_info { | 90 | struct adv76xx_format_info { |
91 | u32 code; | 91 | u32 code; |
92 | u8 op_ch_sel; | 92 | u8 op_ch_sel; |
93 | bool rgb_out; | 93 | bool rgb_out; |
@@ -95,8 +95,8 @@ struct adv7604_format_info { | |||
95 | u8 op_format_sel; | 95 | u8 op_format_sel; |
96 | }; | 96 | }; |
97 | 97 | ||
98 | struct adv7604_chip_info { | 98 | struct adv76xx_chip_info { |
99 | enum adv7604_type type; | 99 | enum adv76xx_type type; |
100 | 100 | ||
101 | bool has_afe; | 101 | bool has_afe; |
102 | unsigned int max_port; | 102 | unsigned int max_port; |
@@ -109,8 +109,9 @@ struct adv7604_chip_info { | |||
109 | unsigned int cable_det_mask; | 109 | unsigned int cable_det_mask; |
110 | unsigned int tdms_lock_mask; | 110 | unsigned int tdms_lock_mask; |
111 | unsigned int fmt_change_digital_mask; | 111 | unsigned int fmt_change_digital_mask; |
112 | unsigned int cp_csc; | ||
112 | 113 | ||
113 | const struct adv7604_format_info *formats; | 114 | const struct adv76xx_format_info *formats; |
114 | unsigned int nformats; | 115 | unsigned int nformats; |
115 | 116 | ||
116 | void (*set_termination)(struct v4l2_subdev *sd, bool enable); | 117 | void (*set_termination)(struct v4l2_subdev *sd, bool enable); |
@@ -119,7 +120,7 @@ struct adv7604_chip_info { | |||
119 | unsigned int (*read_cable_det)(struct v4l2_subdev *sd); | 120 | unsigned int (*read_cable_det)(struct v4l2_subdev *sd); |
120 | 121 | ||
121 | /* 0 = AFE, 1 = HDMI */ | 122 | /* 0 = AFE, 1 = HDMI */ |
122 | const struct adv7604_reg_seq *recommended_settings[2]; | 123 | const struct adv76xx_reg_seq *recommended_settings[2]; |
123 | unsigned int num_recommended_settings[2]; | 124 | unsigned int num_recommended_settings[2]; |
124 | 125 | ||
125 | unsigned long page_mask; | 126 | unsigned long page_mask; |
@@ -133,22 +134,22 @@ struct adv7604_chip_info { | |||
133 | ********************************************************************** | 134 | ********************************************************************** |
134 | */ | 135 | */ |
135 | 136 | ||
136 | struct adv7604_state { | 137 | struct adv76xx_state { |
137 | const struct adv7604_chip_info *info; | 138 | const struct adv76xx_chip_info *info; |
138 | struct adv7604_platform_data pdata; | 139 | struct adv76xx_platform_data pdata; |
139 | 140 | ||
140 | struct gpio_desc *hpd_gpio[4]; | 141 | struct gpio_desc *hpd_gpio[4]; |
141 | 142 | ||
142 | struct v4l2_subdev sd; | 143 | struct v4l2_subdev sd; |
143 | struct media_pad pads[ADV7604_PAD_MAX]; | 144 | struct media_pad pads[ADV76XX_PAD_MAX]; |
144 | unsigned int source_pad; | 145 | unsigned int source_pad; |
145 | 146 | ||
146 | struct v4l2_ctrl_handler hdl; | 147 | struct v4l2_ctrl_handler hdl; |
147 | 148 | ||
148 | enum adv7604_pad selected_input; | 149 | enum adv76xx_pad selected_input; |
149 | 150 | ||
150 | struct v4l2_dv_timings timings; | 151 | struct v4l2_dv_timings timings; |
151 | const struct adv7604_format_info *format; | 152 | const struct adv76xx_format_info *format; |
152 | 153 | ||
153 | struct { | 154 | struct { |
154 | u8 edid[256]; | 155 | u8 edid[256]; |
@@ -163,7 +164,7 @@ struct adv7604_state { | |||
163 | bool restart_stdi_once; | 164 | bool restart_stdi_once; |
164 | 165 | ||
165 | /* i2c clients */ | 166 | /* i2c clients */ |
166 | struct i2c_client *i2c_clients[ADV7604_PAGE_MAX]; | 167 | struct i2c_client *i2c_clients[ADV76XX_PAGE_MAX]; |
167 | 168 | ||
168 | /* controls */ | 169 | /* controls */ |
169 | struct v4l2_ctrl *detect_tx_5v_ctrl; | 170 | struct v4l2_ctrl *detect_tx_5v_ctrl; |
@@ -173,13 +174,13 @@ struct adv7604_state { | |||
173 | struct v4l2_ctrl *rgb_quantization_range_ctrl; | 174 | struct v4l2_ctrl *rgb_quantization_range_ctrl; |
174 | }; | 175 | }; |
175 | 176 | ||
176 | static bool adv7604_has_afe(struct adv7604_state *state) | 177 | static bool adv76xx_has_afe(struct adv76xx_state *state) |
177 | { | 178 | { |
178 | return state->info->has_afe; | 179 | return state->info->has_afe; |
179 | } | 180 | } |
180 | 181 | ||
181 | /* Supported CEA and DMT timings */ | 182 | /* Supported CEA and DMT timings */ |
182 | static const struct v4l2_dv_timings adv7604_timings[] = { | 183 | static const struct v4l2_dv_timings adv76xx_timings[] = { |
183 | V4L2_DV_BT_CEA_720X480P59_94, | 184 | V4L2_DV_BT_CEA_720X480P59_94, |
184 | V4L2_DV_BT_CEA_720X576P50, | 185 | V4L2_DV_BT_CEA_720X576P50, |
185 | V4L2_DV_BT_CEA_1280X720P24, | 186 | V4L2_DV_BT_CEA_1280X720P24, |
@@ -243,14 +244,14 @@ static const struct v4l2_dv_timings adv7604_timings[] = { | |||
243 | { }, | 244 | { }, |
244 | }; | 245 | }; |
245 | 246 | ||
246 | struct adv7604_video_standards { | 247 | struct adv76xx_video_standards { |
247 | struct v4l2_dv_timings timings; | 248 | struct v4l2_dv_timings timings; |
248 | u8 vid_std; | 249 | u8 vid_std; |
249 | u8 v_freq; | 250 | u8 v_freq; |
250 | }; | 251 | }; |
251 | 252 | ||
252 | /* sorted by number of lines */ | 253 | /* sorted by number of lines */ |
253 | static const struct adv7604_video_standards adv7604_prim_mode_comp[] = { | 254 | static const struct adv76xx_video_standards adv7604_prim_mode_comp[] = { |
254 | /* { V4L2_DV_BT_CEA_720X480P59_94, 0x0a, 0x00 }, TODO flickering */ | 255 | /* { V4L2_DV_BT_CEA_720X480P59_94, 0x0a, 0x00 }, TODO flickering */ |
255 | { V4L2_DV_BT_CEA_720X576P50, 0x0b, 0x00 }, | 256 | { V4L2_DV_BT_CEA_720X576P50, 0x0b, 0x00 }, |
256 | { V4L2_DV_BT_CEA_1280X720P50, 0x19, 0x01 }, | 257 | { V4L2_DV_BT_CEA_1280X720P50, 0x19, 0x01 }, |
@@ -265,7 +266,7 @@ static const struct adv7604_video_standards adv7604_prim_mode_comp[] = { | |||
265 | }; | 266 | }; |
266 | 267 | ||
267 | /* sorted by number of lines */ | 268 | /* sorted by number of lines */ |
268 | static const struct adv7604_video_standards adv7604_prim_mode_gr[] = { | 269 | static const struct adv76xx_video_standards adv7604_prim_mode_gr[] = { |
269 | { V4L2_DV_BT_DMT_640X480P60, 0x08, 0x00 }, | 270 | { V4L2_DV_BT_DMT_640X480P60, 0x08, 0x00 }, |
270 | { V4L2_DV_BT_DMT_640X480P72, 0x09, 0x00 }, | 271 | { V4L2_DV_BT_DMT_640X480P72, 0x09, 0x00 }, |
271 | { V4L2_DV_BT_DMT_640X480P75, 0x0a, 0x00 }, | 272 | { V4L2_DV_BT_DMT_640X480P75, 0x0a, 0x00 }, |
@@ -293,7 +294,7 @@ static const struct adv7604_video_standards adv7604_prim_mode_gr[] = { | |||
293 | }; | 294 | }; |
294 | 295 | ||
295 | /* sorted by number of lines */ | 296 | /* sorted by number of lines */ |
296 | static const struct adv7604_video_standards adv7604_prim_mode_hdmi_comp[] = { | 297 | static const struct adv76xx_video_standards adv76xx_prim_mode_hdmi_comp[] = { |
297 | { V4L2_DV_BT_CEA_720X480P59_94, 0x0a, 0x00 }, | 298 | { V4L2_DV_BT_CEA_720X480P59_94, 0x0a, 0x00 }, |
298 | { V4L2_DV_BT_CEA_720X576P50, 0x0b, 0x00 }, | 299 | { V4L2_DV_BT_CEA_720X576P50, 0x0b, 0x00 }, |
299 | { V4L2_DV_BT_CEA_1280X720P50, 0x13, 0x01 }, | 300 | { V4L2_DV_BT_CEA_1280X720P50, 0x13, 0x01 }, |
@@ -307,7 +308,7 @@ static const struct adv7604_video_standards adv7604_prim_mode_hdmi_comp[] = { | |||
307 | }; | 308 | }; |
308 | 309 | ||
309 | /* sorted by number of lines */ | 310 | /* sorted by number of lines */ |
310 | static const struct adv7604_video_standards adv7604_prim_mode_hdmi_gr[] = { | 311 | static const struct adv76xx_video_standards adv76xx_prim_mode_hdmi_gr[] = { |
311 | { V4L2_DV_BT_DMT_640X480P60, 0x08, 0x00 }, | 312 | { V4L2_DV_BT_DMT_640X480P60, 0x08, 0x00 }, |
312 | { V4L2_DV_BT_DMT_640X480P72, 0x09, 0x00 }, | 313 | { V4L2_DV_BT_DMT_640X480P72, 0x09, 0x00 }, |
313 | { V4L2_DV_BT_DMT_640X480P75, 0x0a, 0x00 }, | 314 | { V4L2_DV_BT_DMT_640X480P75, 0x0a, 0x00 }, |
@@ -328,9 +329,9 @@ static const struct adv7604_video_standards adv7604_prim_mode_hdmi_gr[] = { | |||
328 | 329 | ||
329 | /* ----------------------------------------------------------------------- */ | 330 | /* ----------------------------------------------------------------------- */ |
330 | 331 | ||
331 | static inline struct adv7604_state *to_state(struct v4l2_subdev *sd) | 332 | static inline struct adv76xx_state *to_state(struct v4l2_subdev *sd) |
332 | { | 333 | { |
333 | return container_of(sd, struct adv7604_state, sd); | 334 | return container_of(sd, struct adv76xx_state, sd); |
334 | } | 335 | } |
335 | 336 | ||
336 | static inline unsigned htotal(const struct v4l2_bt_timings *t) | 337 | static inline unsigned htotal(const struct v4l2_bt_timings *t) |
@@ -360,15 +361,15 @@ static s32 adv_smbus_read_byte_data_check(struct i2c_client *client, | |||
360 | return -EIO; | 361 | return -EIO; |
361 | } | 362 | } |
362 | 363 | ||
363 | static s32 adv_smbus_read_byte_data(struct adv7604_state *state, | 364 | static s32 adv_smbus_read_byte_data(struct adv76xx_state *state, |
364 | enum adv7604_page page, u8 command) | 365 | enum adv76xx_page page, u8 command) |
365 | { | 366 | { |
366 | return adv_smbus_read_byte_data_check(state->i2c_clients[page], | 367 | return adv_smbus_read_byte_data_check(state->i2c_clients[page], |
367 | command, true); | 368 | command, true); |
368 | } | 369 | } |
369 | 370 | ||
370 | static s32 adv_smbus_write_byte_data(struct adv7604_state *state, | 371 | static s32 adv_smbus_write_byte_data(struct adv76xx_state *state, |
371 | enum adv7604_page page, u8 command, | 372 | enum adv76xx_page page, u8 command, |
372 | u8 value) | 373 | u8 value) |
373 | { | 374 | { |
374 | struct i2c_client *client = state->i2c_clients[page]; | 375 | struct i2c_client *client = state->i2c_clients[page]; |
@@ -391,8 +392,8 @@ static s32 adv_smbus_write_byte_data(struct adv7604_state *state, | |||
391 | return err; | 392 | return err; |
392 | } | 393 | } |
393 | 394 | ||
394 | static s32 adv_smbus_write_i2c_block_data(struct adv7604_state *state, | 395 | static s32 adv_smbus_write_i2c_block_data(struct adv76xx_state *state, |
395 | enum adv7604_page page, u8 command, | 396 | enum adv76xx_page page, u8 command, |
396 | unsigned length, const u8 *values) | 397 | unsigned length, const u8 *values) |
397 | { | 398 | { |
398 | struct i2c_client *client = state->i2c_clients[page]; | 399 | struct i2c_client *client = state->i2c_clients[page]; |
@@ -411,16 +412,16 @@ static s32 adv_smbus_write_i2c_block_data(struct adv7604_state *state, | |||
411 | 412 | ||
412 | static inline int io_read(struct v4l2_subdev *sd, u8 reg) | 413 | static inline int io_read(struct v4l2_subdev *sd, u8 reg) |
413 | { | 414 | { |
414 | struct adv7604_state *state = to_state(sd); | 415 | struct adv76xx_state *state = to_state(sd); |
415 | 416 | ||
416 | return adv_smbus_read_byte_data(state, ADV7604_PAGE_IO, reg); | 417 | return adv_smbus_read_byte_data(state, ADV76XX_PAGE_IO, reg); |
417 | } | 418 | } |
418 | 419 | ||
419 | static inline int io_write(struct v4l2_subdev *sd, u8 reg, u8 val) | 420 | static inline int io_write(struct v4l2_subdev *sd, u8 reg, u8 val) |
420 | { | 421 | { |
421 | struct adv7604_state *state = to_state(sd); | 422 | struct adv76xx_state *state = to_state(sd); |
422 | 423 | ||
423 | return adv_smbus_write_byte_data(state, ADV7604_PAGE_IO, reg, val); | 424 | return adv_smbus_write_byte_data(state, ADV76XX_PAGE_IO, reg, val); |
424 | } | 425 | } |
425 | 426 | ||
426 | static inline int io_write_clr_set(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val) | 427 | static inline int io_write_clr_set(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val) |
@@ -430,73 +431,73 @@ static inline int io_write_clr_set(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 v | |||
430 | 431 | ||
431 | static inline int avlink_read(struct v4l2_subdev *sd, u8 reg) | 432 | static inline int avlink_read(struct v4l2_subdev *sd, u8 reg) |
432 | { | 433 | { |
433 | struct adv7604_state *state = to_state(sd); | 434 | struct adv76xx_state *state = to_state(sd); |
434 | 435 | ||
435 | return adv_smbus_read_byte_data(state, ADV7604_PAGE_AVLINK, reg); | 436 | return adv_smbus_read_byte_data(state, ADV7604_PAGE_AVLINK, reg); |
436 | } | 437 | } |
437 | 438 | ||
438 | static inline int avlink_write(struct v4l2_subdev *sd, u8 reg, u8 val) | 439 | static inline int avlink_write(struct v4l2_subdev *sd, u8 reg, u8 val) |
439 | { | 440 | { |
440 | struct adv7604_state *state = to_state(sd); | 441 | struct adv76xx_state *state = to_state(sd); |
441 | 442 | ||
442 | return adv_smbus_write_byte_data(state, ADV7604_PAGE_AVLINK, reg, val); | 443 | return adv_smbus_write_byte_data(state, ADV7604_PAGE_AVLINK, reg, val); |
443 | } | 444 | } |
444 | 445 | ||
445 | static inline int cec_read(struct v4l2_subdev *sd, u8 reg) | 446 | static inline int cec_read(struct v4l2_subdev *sd, u8 reg) |
446 | { | 447 | { |
447 | struct adv7604_state *state = to_state(sd); | 448 | struct adv76xx_state *state = to_state(sd); |
448 | 449 | ||
449 | return adv_smbus_read_byte_data(state, ADV7604_PAGE_CEC, reg); | 450 | return adv_smbus_read_byte_data(state, ADV76XX_PAGE_CEC, reg); |
450 | } | 451 | } |
451 | 452 | ||
452 | static inline int cec_write(struct v4l2_subdev *sd, u8 reg, u8 val) | 453 | static inline int cec_write(struct v4l2_subdev *sd, u8 reg, u8 val) |
453 | { | 454 | { |
454 | struct adv7604_state *state = to_state(sd); | 455 | struct adv76xx_state *state = to_state(sd); |
455 | 456 | ||
456 | return adv_smbus_write_byte_data(state, ADV7604_PAGE_CEC, reg, val); | 457 | return adv_smbus_write_byte_data(state, ADV76XX_PAGE_CEC, reg, val); |
457 | } | 458 | } |
458 | 459 | ||
459 | static inline int infoframe_read(struct v4l2_subdev *sd, u8 reg) | 460 | static inline int infoframe_read(struct v4l2_subdev *sd, u8 reg) |
460 | { | 461 | { |
461 | struct adv7604_state *state = to_state(sd); | 462 | struct adv76xx_state *state = to_state(sd); |
462 | 463 | ||
463 | return adv_smbus_read_byte_data(state, ADV7604_PAGE_INFOFRAME, reg); | 464 | return adv_smbus_read_byte_data(state, ADV76XX_PAGE_INFOFRAME, reg); |
464 | } | 465 | } |
465 | 466 | ||
466 | static inline int infoframe_write(struct v4l2_subdev *sd, u8 reg, u8 val) | 467 | static inline int infoframe_write(struct v4l2_subdev *sd, u8 reg, u8 val) |
467 | { | 468 | { |
468 | struct adv7604_state *state = to_state(sd); | 469 | struct adv76xx_state *state = to_state(sd); |
469 | 470 | ||
470 | return adv_smbus_write_byte_data(state, ADV7604_PAGE_INFOFRAME, | 471 | return adv_smbus_write_byte_data(state, ADV76XX_PAGE_INFOFRAME, |
471 | reg, val); | 472 | reg, val); |
472 | } | 473 | } |
473 | 474 | ||
474 | static inline int afe_read(struct v4l2_subdev *sd, u8 reg) | 475 | static inline int afe_read(struct v4l2_subdev *sd, u8 reg) |
475 | { | 476 | { |
476 | struct adv7604_state *state = to_state(sd); | 477 | struct adv76xx_state *state = to_state(sd); |
477 | 478 | ||
478 | return adv_smbus_read_byte_data(state, ADV7604_PAGE_AFE, reg); | 479 | return adv_smbus_read_byte_data(state, ADV76XX_PAGE_AFE, reg); |
479 | } | 480 | } |
480 | 481 | ||
481 | static inline int afe_write(struct v4l2_subdev *sd, u8 reg, u8 val) | 482 | static inline int afe_write(struct v4l2_subdev *sd, u8 reg, u8 val) |
482 | { | 483 | { |
483 | struct adv7604_state *state = to_state(sd); | 484 | struct adv76xx_state *state = to_state(sd); |
484 | 485 | ||
485 | return adv_smbus_write_byte_data(state, ADV7604_PAGE_AFE, reg, val); | 486 | return adv_smbus_write_byte_data(state, ADV76XX_PAGE_AFE, reg, val); |
486 | } | 487 | } |
487 | 488 | ||
488 | static inline int rep_read(struct v4l2_subdev *sd, u8 reg) | 489 | static inline int rep_read(struct v4l2_subdev *sd, u8 reg) |
489 | { | 490 | { |
490 | struct adv7604_state *state = to_state(sd); | 491 | struct adv76xx_state *state = to_state(sd); |
491 | 492 | ||
492 | return adv_smbus_read_byte_data(state, ADV7604_PAGE_REP, reg); | 493 | return adv_smbus_read_byte_data(state, ADV76XX_PAGE_REP, reg); |
493 | } | 494 | } |
494 | 495 | ||
495 | static inline int rep_write(struct v4l2_subdev *sd, u8 reg, u8 val) | 496 | static inline int rep_write(struct v4l2_subdev *sd, u8 reg, u8 val) |
496 | { | 497 | { |
497 | struct adv7604_state *state = to_state(sd); | 498 | struct adv76xx_state *state = to_state(sd); |
498 | 499 | ||
499 | return adv_smbus_write_byte_data(state, ADV7604_PAGE_REP, reg, val); | 500 | return adv_smbus_write_byte_data(state, ADV76XX_PAGE_REP, reg, val); |
500 | } | 501 | } |
501 | 502 | ||
502 | static inline int rep_write_clr_set(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val) | 503 | static inline int rep_write_clr_set(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val) |
@@ -506,64 +507,60 @@ static inline int rep_write_clr_set(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 | |||
506 | 507 | ||
507 | static inline int edid_read(struct v4l2_subdev *sd, u8 reg) | 508 | static inline int edid_read(struct v4l2_subdev *sd, u8 reg) |
508 | { | 509 | { |
509 | struct adv7604_state *state = to_state(sd); | 510 | struct adv76xx_state *state = to_state(sd); |
510 | 511 | ||
511 | return adv_smbus_read_byte_data(state, ADV7604_PAGE_EDID, reg); | 512 | return adv_smbus_read_byte_data(state, ADV76XX_PAGE_EDID, reg); |
512 | } | 513 | } |
513 | 514 | ||
514 | static inline int edid_write(struct v4l2_subdev *sd, u8 reg, u8 val) | 515 | static inline int edid_write(struct v4l2_subdev *sd, u8 reg, u8 val) |
515 | { | 516 | { |
516 | struct adv7604_state *state = to_state(sd); | 517 | struct adv76xx_state *state = to_state(sd); |
517 | 518 | ||
518 | return adv_smbus_write_byte_data(state, ADV7604_PAGE_EDID, reg, val); | 519 | return adv_smbus_write_byte_data(state, ADV76XX_PAGE_EDID, reg, val); |
519 | } | 520 | } |
520 | 521 | ||
521 | static inline int edid_write_block(struct v4l2_subdev *sd, | 522 | static inline int edid_write_block(struct v4l2_subdev *sd, |
522 | unsigned len, const u8 *val) | 523 | unsigned len, const u8 *val) |
523 | { | 524 | { |
524 | struct adv7604_state *state = to_state(sd); | 525 | struct adv76xx_state *state = to_state(sd); |
525 | int err = 0; | 526 | int err = 0; |
526 | int i; | 527 | int i; |
527 | 528 | ||
528 | v4l2_dbg(2, debug, sd, "%s: write EDID block (%d byte)\n", __func__, len); | 529 | v4l2_dbg(2, debug, sd, "%s: write EDID block (%d byte)\n", __func__, len); |
529 | 530 | ||
530 | for (i = 0; !err && i < len; i += I2C_SMBUS_BLOCK_MAX) | 531 | for (i = 0; !err && i < len; i += I2C_SMBUS_BLOCK_MAX) |
531 | err = adv_smbus_write_i2c_block_data(state, ADV7604_PAGE_EDID, | 532 | err = adv_smbus_write_i2c_block_data(state, ADV76XX_PAGE_EDID, |
532 | i, I2C_SMBUS_BLOCK_MAX, val + i); | 533 | i, I2C_SMBUS_BLOCK_MAX, val + i); |
533 | return err; | 534 | return err; |
534 | } | 535 | } |
535 | 536 | ||
536 | static void adv7604_set_hpd(struct adv7604_state *state, unsigned int hpd) | 537 | static void adv76xx_set_hpd(struct adv76xx_state *state, unsigned int hpd) |
537 | { | 538 | { |
538 | unsigned int i; | 539 | unsigned int i; |
539 | 540 | ||
540 | for (i = 0; i < state->info->num_dv_ports; ++i) { | 541 | for (i = 0; i < state->info->num_dv_ports; ++i) |
541 | if (IS_ERR(state->hpd_gpio[i])) | ||
542 | continue; | ||
543 | |||
544 | gpiod_set_value_cansleep(state->hpd_gpio[i], hpd & BIT(i)); | 542 | gpiod_set_value_cansleep(state->hpd_gpio[i], hpd & BIT(i)); |
545 | } | ||
546 | 543 | ||
547 | v4l2_subdev_notify(&state->sd, ADV7604_HOTPLUG, &hpd); | 544 | v4l2_subdev_notify(&state->sd, ADV76XX_HOTPLUG, &hpd); |
548 | } | 545 | } |
549 | 546 | ||
550 | static void adv7604_delayed_work_enable_hotplug(struct work_struct *work) | 547 | static void adv76xx_delayed_work_enable_hotplug(struct work_struct *work) |
551 | { | 548 | { |
552 | struct delayed_work *dwork = to_delayed_work(work); | 549 | struct delayed_work *dwork = to_delayed_work(work); |
553 | struct adv7604_state *state = container_of(dwork, struct adv7604_state, | 550 | struct adv76xx_state *state = container_of(dwork, struct adv76xx_state, |
554 | delayed_work_enable_hotplug); | 551 | delayed_work_enable_hotplug); |
555 | struct v4l2_subdev *sd = &state->sd; | 552 | struct v4l2_subdev *sd = &state->sd; |
556 | 553 | ||
557 | v4l2_dbg(2, debug, sd, "%s: enable hotplug\n", __func__); | 554 | v4l2_dbg(2, debug, sd, "%s: enable hotplug\n", __func__); |
558 | 555 | ||
559 | adv7604_set_hpd(state, state->edid.present); | 556 | adv76xx_set_hpd(state, state->edid.present); |
560 | } | 557 | } |
561 | 558 | ||
562 | static inline int hdmi_read(struct v4l2_subdev *sd, u8 reg) | 559 | static inline int hdmi_read(struct v4l2_subdev *sd, u8 reg) |
563 | { | 560 | { |
564 | struct adv7604_state *state = to_state(sd); | 561 | struct adv76xx_state *state = to_state(sd); |
565 | 562 | ||
566 | return adv_smbus_read_byte_data(state, ADV7604_PAGE_HDMI, reg); | 563 | return adv_smbus_read_byte_data(state, ADV76XX_PAGE_HDMI, reg); |
567 | } | 564 | } |
568 | 565 | ||
569 | static u16 hdmi_read16(struct v4l2_subdev *sd, u8 reg, u16 mask) | 566 | static u16 hdmi_read16(struct v4l2_subdev *sd, u8 reg, u16 mask) |
@@ -573,9 +570,9 @@ static u16 hdmi_read16(struct v4l2_subdev *sd, u8 reg, u16 mask) | |||
573 | 570 | ||
574 | static inline int hdmi_write(struct v4l2_subdev *sd, u8 reg, u8 val) | 571 | static inline int hdmi_write(struct v4l2_subdev *sd, u8 reg, u8 val) |
575 | { | 572 | { |
576 | struct adv7604_state *state = to_state(sd); | 573 | struct adv76xx_state *state = to_state(sd); |
577 | 574 | ||
578 | return adv_smbus_write_byte_data(state, ADV7604_PAGE_HDMI, reg, val); | 575 | return adv_smbus_write_byte_data(state, ADV76XX_PAGE_HDMI, reg, val); |
579 | } | 576 | } |
580 | 577 | ||
581 | static inline int hdmi_write_clr_set(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val) | 578 | static inline int hdmi_write_clr_set(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val) |
@@ -585,16 +582,16 @@ static inline int hdmi_write_clr_set(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 | |||
585 | 582 | ||
586 | static inline int test_write(struct v4l2_subdev *sd, u8 reg, u8 val) | 583 | static inline int test_write(struct v4l2_subdev *sd, u8 reg, u8 val) |
587 | { | 584 | { |
588 | struct adv7604_state *state = to_state(sd); | 585 | struct adv76xx_state *state = to_state(sd); |
589 | 586 | ||
590 | return adv_smbus_write_byte_data(state, ADV7604_PAGE_TEST, reg, val); | 587 | return adv_smbus_write_byte_data(state, ADV76XX_PAGE_TEST, reg, val); |
591 | } | 588 | } |
592 | 589 | ||
593 | static inline int cp_read(struct v4l2_subdev *sd, u8 reg) | 590 | static inline int cp_read(struct v4l2_subdev *sd, u8 reg) |
594 | { | 591 | { |
595 | struct adv7604_state *state = to_state(sd); | 592 | struct adv76xx_state *state = to_state(sd); |
596 | 593 | ||
597 | return adv_smbus_read_byte_data(state, ADV7604_PAGE_CP, reg); | 594 | return adv_smbus_read_byte_data(state, ADV76XX_PAGE_CP, reg); |
598 | } | 595 | } |
599 | 596 | ||
600 | static u16 cp_read16(struct v4l2_subdev *sd, u8 reg, u16 mask) | 597 | static u16 cp_read16(struct v4l2_subdev *sd, u8 reg, u16 mask) |
@@ -604,9 +601,9 @@ static u16 cp_read16(struct v4l2_subdev *sd, u8 reg, u16 mask) | |||
604 | 601 | ||
605 | static inline int cp_write(struct v4l2_subdev *sd, u8 reg, u8 val) | 602 | static inline int cp_write(struct v4l2_subdev *sd, u8 reg, u8 val) |
606 | { | 603 | { |
607 | struct adv7604_state *state = to_state(sd); | 604 | struct adv76xx_state *state = to_state(sd); |
608 | 605 | ||
609 | return adv_smbus_write_byte_data(state, ADV7604_PAGE_CP, reg, val); | 606 | return adv_smbus_write_byte_data(state, ADV76XX_PAGE_CP, reg, val); |
610 | } | 607 | } |
611 | 608 | ||
612 | static inline int cp_write_clr_set(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val) | 609 | static inline int cp_write_clr_set(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val) |
@@ -616,25 +613,25 @@ static inline int cp_write_clr_set(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 v | |||
616 | 613 | ||
617 | static inline int vdp_read(struct v4l2_subdev *sd, u8 reg) | 614 | static inline int vdp_read(struct v4l2_subdev *sd, u8 reg) |
618 | { | 615 | { |
619 | struct adv7604_state *state = to_state(sd); | 616 | struct adv76xx_state *state = to_state(sd); |
620 | 617 | ||
621 | return adv_smbus_read_byte_data(state, ADV7604_PAGE_VDP, reg); | 618 | return adv_smbus_read_byte_data(state, ADV7604_PAGE_VDP, reg); |
622 | } | 619 | } |
623 | 620 | ||
624 | static inline int vdp_write(struct v4l2_subdev *sd, u8 reg, u8 val) | 621 | static inline int vdp_write(struct v4l2_subdev *sd, u8 reg, u8 val) |
625 | { | 622 | { |
626 | struct adv7604_state *state = to_state(sd); | 623 | struct adv76xx_state *state = to_state(sd); |
627 | 624 | ||
628 | return adv_smbus_write_byte_data(state, ADV7604_PAGE_VDP, reg, val); | 625 | return adv_smbus_write_byte_data(state, ADV7604_PAGE_VDP, reg, val); |
629 | } | 626 | } |
630 | 627 | ||
631 | #define ADV7604_REG(page, offset) (((page) << 8) | (offset)) | 628 | #define ADV76XX_REG(page, offset) (((page) << 8) | (offset)) |
632 | #define ADV7604_REG_SEQ_TERM 0xffff | 629 | #define ADV76XX_REG_SEQ_TERM 0xffff |
633 | 630 | ||
634 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 631 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
635 | static int adv7604_read_reg(struct v4l2_subdev *sd, unsigned int reg) | 632 | static int adv76xx_read_reg(struct v4l2_subdev *sd, unsigned int reg) |
636 | { | 633 | { |
637 | struct adv7604_state *state = to_state(sd); | 634 | struct adv76xx_state *state = to_state(sd); |
638 | unsigned int page = reg >> 8; | 635 | unsigned int page = reg >> 8; |
639 | 636 | ||
640 | if (!(BIT(page) & state->info->page_mask)) | 637 | if (!(BIT(page) & state->info->page_mask)) |
@@ -646,9 +643,9 @@ static int adv7604_read_reg(struct v4l2_subdev *sd, unsigned int reg) | |||
646 | } | 643 | } |
647 | #endif | 644 | #endif |
648 | 645 | ||
649 | static int adv7604_write_reg(struct v4l2_subdev *sd, unsigned int reg, u8 val) | 646 | static int adv76xx_write_reg(struct v4l2_subdev *sd, unsigned int reg, u8 val) |
650 | { | 647 | { |
651 | struct adv7604_state *state = to_state(sd); | 648 | struct adv76xx_state *state = to_state(sd); |
652 | unsigned int page = reg >> 8; | 649 | unsigned int page = reg >> 8; |
653 | 650 | ||
654 | if (!(BIT(page) & state->info->page_mask)) | 651 | if (!(BIT(page) & state->info->page_mask)) |
@@ -659,91 +656,91 @@ static int adv7604_write_reg(struct v4l2_subdev *sd, unsigned int reg, u8 val) | |||
659 | return adv_smbus_write_byte_data(state, page, reg, val); | 656 | return adv_smbus_write_byte_data(state, page, reg, val); |
660 | } | 657 | } |
661 | 658 | ||
662 | static void adv7604_write_reg_seq(struct v4l2_subdev *sd, | 659 | static void adv76xx_write_reg_seq(struct v4l2_subdev *sd, |
663 | const struct adv7604_reg_seq *reg_seq) | 660 | const struct adv76xx_reg_seq *reg_seq) |
664 | { | 661 | { |
665 | unsigned int i; | 662 | unsigned int i; |
666 | 663 | ||
667 | for (i = 0; reg_seq[i].reg != ADV7604_REG_SEQ_TERM; i++) | 664 | for (i = 0; reg_seq[i].reg != ADV76XX_REG_SEQ_TERM; i++) |
668 | adv7604_write_reg(sd, reg_seq[i].reg, reg_seq[i].val); | 665 | adv76xx_write_reg(sd, reg_seq[i].reg, reg_seq[i].val); |
669 | } | 666 | } |
670 | 667 | ||
671 | /* ----------------------------------------------------------------------------- | 668 | /* ----------------------------------------------------------------------------- |
672 | * Format helpers | 669 | * Format helpers |
673 | */ | 670 | */ |
674 | 671 | ||
675 | static const struct adv7604_format_info adv7604_formats[] = { | 672 | static const struct adv76xx_format_info adv7604_formats[] = { |
676 | { MEDIA_BUS_FMT_RGB888_1X24, ADV7604_OP_CH_SEL_RGB, true, false, | 673 | { MEDIA_BUS_FMT_RGB888_1X24, ADV76XX_OP_CH_SEL_RGB, true, false, |
677 | ADV7604_OP_MODE_SEL_SDR_444 | ADV7604_OP_FORMAT_SEL_8BIT }, | 674 | ADV76XX_OP_MODE_SEL_SDR_444 | ADV76XX_OP_FORMAT_SEL_8BIT }, |
678 | { MEDIA_BUS_FMT_YUYV8_2X8, ADV7604_OP_CH_SEL_RGB, false, false, | 675 | { MEDIA_BUS_FMT_YUYV8_2X8, ADV76XX_OP_CH_SEL_RGB, false, false, |
679 | ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_8BIT }, | 676 | ADV76XX_OP_MODE_SEL_SDR_422 | ADV76XX_OP_FORMAT_SEL_8BIT }, |
680 | { MEDIA_BUS_FMT_YVYU8_2X8, ADV7604_OP_CH_SEL_RGB, false, true, | 677 | { MEDIA_BUS_FMT_YVYU8_2X8, ADV76XX_OP_CH_SEL_RGB, false, true, |
681 | ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_8BIT }, | 678 | ADV76XX_OP_MODE_SEL_SDR_422 | ADV76XX_OP_FORMAT_SEL_8BIT }, |
682 | { MEDIA_BUS_FMT_YUYV10_2X10, ADV7604_OP_CH_SEL_RGB, false, false, | 679 | { MEDIA_BUS_FMT_YUYV10_2X10, ADV76XX_OP_CH_SEL_RGB, false, false, |
683 | ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_10BIT }, | 680 | ADV76XX_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_10BIT }, |
684 | { MEDIA_BUS_FMT_YVYU10_2X10, ADV7604_OP_CH_SEL_RGB, false, true, | 681 | { MEDIA_BUS_FMT_YVYU10_2X10, ADV76XX_OP_CH_SEL_RGB, false, true, |
685 | ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_10BIT }, | 682 | ADV76XX_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_10BIT }, |
686 | { MEDIA_BUS_FMT_YUYV12_2X12, ADV7604_OP_CH_SEL_RGB, false, false, | 683 | { MEDIA_BUS_FMT_YUYV12_2X12, ADV76XX_OP_CH_SEL_RGB, false, false, |
687 | ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_12BIT }, | 684 | ADV76XX_OP_MODE_SEL_SDR_422 | ADV76XX_OP_FORMAT_SEL_12BIT }, |
688 | { MEDIA_BUS_FMT_YVYU12_2X12, ADV7604_OP_CH_SEL_RGB, false, true, | 685 | { MEDIA_BUS_FMT_YVYU12_2X12, ADV76XX_OP_CH_SEL_RGB, false, true, |
689 | ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_12BIT }, | 686 | ADV76XX_OP_MODE_SEL_SDR_422 | ADV76XX_OP_FORMAT_SEL_12BIT }, |
690 | { MEDIA_BUS_FMT_UYVY8_1X16, ADV7604_OP_CH_SEL_RBG, false, false, | 687 | { MEDIA_BUS_FMT_UYVY8_1X16, ADV76XX_OP_CH_SEL_RBG, false, false, |
691 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT }, | 688 | ADV76XX_OP_MODE_SEL_SDR_422_2X | ADV76XX_OP_FORMAT_SEL_8BIT }, |
692 | { MEDIA_BUS_FMT_VYUY8_1X16, ADV7604_OP_CH_SEL_RBG, false, true, | 689 | { MEDIA_BUS_FMT_VYUY8_1X16, ADV76XX_OP_CH_SEL_RBG, false, true, |
693 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT }, | 690 | ADV76XX_OP_MODE_SEL_SDR_422_2X | ADV76XX_OP_FORMAT_SEL_8BIT }, |
694 | { MEDIA_BUS_FMT_YUYV8_1X16, ADV7604_OP_CH_SEL_RGB, false, false, | 691 | { MEDIA_BUS_FMT_YUYV8_1X16, ADV76XX_OP_CH_SEL_RGB, false, false, |
695 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT }, | 692 | ADV76XX_OP_MODE_SEL_SDR_422_2X | ADV76XX_OP_FORMAT_SEL_8BIT }, |
696 | { MEDIA_BUS_FMT_YVYU8_1X16, ADV7604_OP_CH_SEL_RGB, false, true, | 693 | { MEDIA_BUS_FMT_YVYU8_1X16, ADV76XX_OP_CH_SEL_RGB, false, true, |
697 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT }, | 694 | ADV76XX_OP_MODE_SEL_SDR_422_2X | ADV76XX_OP_FORMAT_SEL_8BIT }, |
698 | { MEDIA_BUS_FMT_UYVY10_1X20, ADV7604_OP_CH_SEL_RBG, false, false, | 695 | { MEDIA_BUS_FMT_UYVY10_1X20, ADV76XX_OP_CH_SEL_RBG, false, false, |
699 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_10BIT }, | 696 | ADV76XX_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_10BIT }, |
700 | { MEDIA_BUS_FMT_VYUY10_1X20, ADV7604_OP_CH_SEL_RBG, false, true, | 697 | { MEDIA_BUS_FMT_VYUY10_1X20, ADV76XX_OP_CH_SEL_RBG, false, true, |
701 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_10BIT }, | 698 | ADV76XX_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_10BIT }, |
702 | { MEDIA_BUS_FMT_YUYV10_1X20, ADV7604_OP_CH_SEL_RGB, false, false, | 699 | { MEDIA_BUS_FMT_YUYV10_1X20, ADV76XX_OP_CH_SEL_RGB, false, false, |
703 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_10BIT }, | 700 | ADV76XX_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_10BIT }, |
704 | { MEDIA_BUS_FMT_YVYU10_1X20, ADV7604_OP_CH_SEL_RGB, false, true, | 701 | { MEDIA_BUS_FMT_YVYU10_1X20, ADV76XX_OP_CH_SEL_RGB, false, true, |
705 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_10BIT }, | 702 | ADV76XX_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_10BIT }, |
706 | { MEDIA_BUS_FMT_UYVY12_1X24, ADV7604_OP_CH_SEL_RBG, false, false, | 703 | { MEDIA_BUS_FMT_UYVY12_1X24, ADV76XX_OP_CH_SEL_RBG, false, false, |
707 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT }, | 704 | ADV76XX_OP_MODE_SEL_SDR_422_2X | ADV76XX_OP_FORMAT_SEL_12BIT }, |
708 | { MEDIA_BUS_FMT_VYUY12_1X24, ADV7604_OP_CH_SEL_RBG, false, true, | 705 | { MEDIA_BUS_FMT_VYUY12_1X24, ADV76XX_OP_CH_SEL_RBG, false, true, |
709 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT }, | 706 | ADV76XX_OP_MODE_SEL_SDR_422_2X | ADV76XX_OP_FORMAT_SEL_12BIT }, |
710 | { MEDIA_BUS_FMT_YUYV12_1X24, ADV7604_OP_CH_SEL_RGB, false, false, | 707 | { MEDIA_BUS_FMT_YUYV12_1X24, ADV76XX_OP_CH_SEL_RGB, false, false, |
711 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT }, | 708 | ADV76XX_OP_MODE_SEL_SDR_422_2X | ADV76XX_OP_FORMAT_SEL_12BIT }, |
712 | { MEDIA_BUS_FMT_YVYU12_1X24, ADV7604_OP_CH_SEL_RGB, false, true, | 709 | { MEDIA_BUS_FMT_YVYU12_1X24, ADV76XX_OP_CH_SEL_RGB, false, true, |
713 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT }, | 710 | ADV76XX_OP_MODE_SEL_SDR_422_2X | ADV76XX_OP_FORMAT_SEL_12BIT }, |
714 | }; | 711 | }; |
715 | 712 | ||
716 | static const struct adv7604_format_info adv7611_formats[] = { | 713 | static const struct adv76xx_format_info adv7611_formats[] = { |
717 | { MEDIA_BUS_FMT_RGB888_1X24, ADV7604_OP_CH_SEL_RGB, true, false, | 714 | { MEDIA_BUS_FMT_RGB888_1X24, ADV76XX_OP_CH_SEL_RGB, true, false, |
718 | ADV7604_OP_MODE_SEL_SDR_444 | ADV7604_OP_FORMAT_SEL_8BIT }, | 715 | ADV76XX_OP_MODE_SEL_SDR_444 | ADV76XX_OP_FORMAT_SEL_8BIT }, |
719 | { MEDIA_BUS_FMT_YUYV8_2X8, ADV7604_OP_CH_SEL_RGB, false, false, | 716 | { MEDIA_BUS_FMT_YUYV8_2X8, ADV76XX_OP_CH_SEL_RGB, false, false, |
720 | ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_8BIT }, | 717 | ADV76XX_OP_MODE_SEL_SDR_422 | ADV76XX_OP_FORMAT_SEL_8BIT }, |
721 | { MEDIA_BUS_FMT_YVYU8_2X8, ADV7604_OP_CH_SEL_RGB, false, true, | 718 | { MEDIA_BUS_FMT_YVYU8_2X8, ADV76XX_OP_CH_SEL_RGB, false, true, |
722 | ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_8BIT }, | 719 | ADV76XX_OP_MODE_SEL_SDR_422 | ADV76XX_OP_FORMAT_SEL_8BIT }, |
723 | { MEDIA_BUS_FMT_YUYV12_2X12, ADV7604_OP_CH_SEL_RGB, false, false, | 720 | { MEDIA_BUS_FMT_YUYV12_2X12, ADV76XX_OP_CH_SEL_RGB, false, false, |
724 | ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_12BIT }, | 721 | ADV76XX_OP_MODE_SEL_SDR_422 | ADV76XX_OP_FORMAT_SEL_12BIT }, |
725 | { MEDIA_BUS_FMT_YVYU12_2X12, ADV7604_OP_CH_SEL_RGB, false, true, | 722 | { MEDIA_BUS_FMT_YVYU12_2X12, ADV76XX_OP_CH_SEL_RGB, false, true, |
726 | ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_12BIT }, | 723 | ADV76XX_OP_MODE_SEL_SDR_422 | ADV76XX_OP_FORMAT_SEL_12BIT }, |
727 | { MEDIA_BUS_FMT_UYVY8_1X16, ADV7604_OP_CH_SEL_RBG, false, false, | 724 | { MEDIA_BUS_FMT_UYVY8_1X16, ADV76XX_OP_CH_SEL_RBG, false, false, |
728 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT }, | 725 | ADV76XX_OP_MODE_SEL_SDR_422_2X | ADV76XX_OP_FORMAT_SEL_8BIT }, |
729 | { MEDIA_BUS_FMT_VYUY8_1X16, ADV7604_OP_CH_SEL_RBG, false, true, | 726 | { MEDIA_BUS_FMT_VYUY8_1X16, ADV76XX_OP_CH_SEL_RBG, false, true, |
730 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT }, | 727 | ADV76XX_OP_MODE_SEL_SDR_422_2X | ADV76XX_OP_FORMAT_SEL_8BIT }, |
731 | { MEDIA_BUS_FMT_YUYV8_1X16, ADV7604_OP_CH_SEL_RGB, false, false, | 728 | { MEDIA_BUS_FMT_YUYV8_1X16, ADV76XX_OP_CH_SEL_RGB, false, false, |
732 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT }, | 729 | ADV76XX_OP_MODE_SEL_SDR_422_2X | ADV76XX_OP_FORMAT_SEL_8BIT }, |
733 | { MEDIA_BUS_FMT_YVYU8_1X16, ADV7604_OP_CH_SEL_RGB, false, true, | 730 | { MEDIA_BUS_FMT_YVYU8_1X16, ADV76XX_OP_CH_SEL_RGB, false, true, |
734 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT }, | 731 | ADV76XX_OP_MODE_SEL_SDR_422_2X | ADV76XX_OP_FORMAT_SEL_8BIT }, |
735 | { MEDIA_BUS_FMT_UYVY12_1X24, ADV7604_OP_CH_SEL_RBG, false, false, | 732 | { MEDIA_BUS_FMT_UYVY12_1X24, ADV76XX_OP_CH_SEL_RBG, false, false, |
736 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT }, | 733 | ADV76XX_OP_MODE_SEL_SDR_422_2X | ADV76XX_OP_FORMAT_SEL_12BIT }, |
737 | { MEDIA_BUS_FMT_VYUY12_1X24, ADV7604_OP_CH_SEL_RBG, false, true, | 734 | { MEDIA_BUS_FMT_VYUY12_1X24, ADV76XX_OP_CH_SEL_RBG, false, true, |
738 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT }, | 735 | ADV76XX_OP_MODE_SEL_SDR_422_2X | ADV76XX_OP_FORMAT_SEL_12BIT }, |
739 | { MEDIA_BUS_FMT_YUYV12_1X24, ADV7604_OP_CH_SEL_RGB, false, false, | 736 | { MEDIA_BUS_FMT_YUYV12_1X24, ADV76XX_OP_CH_SEL_RGB, false, false, |
740 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT }, | 737 | ADV76XX_OP_MODE_SEL_SDR_422_2X | ADV76XX_OP_FORMAT_SEL_12BIT }, |
741 | { MEDIA_BUS_FMT_YVYU12_1X24, ADV7604_OP_CH_SEL_RGB, false, true, | 738 | { MEDIA_BUS_FMT_YVYU12_1X24, ADV76XX_OP_CH_SEL_RGB, false, true, |
742 | ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT }, | 739 | ADV76XX_OP_MODE_SEL_SDR_422_2X | ADV76XX_OP_FORMAT_SEL_12BIT }, |
743 | }; | 740 | }; |
744 | 741 | ||
745 | static const struct adv7604_format_info * | 742 | static const struct adv76xx_format_info * |
746 | adv7604_format_info(struct adv7604_state *state, u32 code) | 743 | adv76xx_format_info(struct adv76xx_state *state, u32 code) |
747 | { | 744 | { |
748 | unsigned int i; | 745 | unsigned int i; |
749 | 746 | ||
@@ -759,7 +756,7 @@ adv7604_format_info(struct adv7604_state *state, u32 code) | |||
759 | 756 | ||
760 | static inline bool is_analog_input(struct v4l2_subdev *sd) | 757 | static inline bool is_analog_input(struct v4l2_subdev *sd) |
761 | { | 758 | { |
762 | struct adv7604_state *state = to_state(sd); | 759 | struct adv76xx_state *state = to_state(sd); |
763 | 760 | ||
764 | return state->selected_input == ADV7604_PAD_VGA_RGB || | 761 | return state->selected_input == ADV7604_PAD_VGA_RGB || |
765 | state->selected_input == ADV7604_PAD_VGA_COMP; | 762 | state->selected_input == ADV7604_PAD_VGA_COMP; |
@@ -767,9 +764,9 @@ static inline bool is_analog_input(struct v4l2_subdev *sd) | |||
767 | 764 | ||
768 | static inline bool is_digital_input(struct v4l2_subdev *sd) | 765 | static inline bool is_digital_input(struct v4l2_subdev *sd) |
769 | { | 766 | { |
770 | struct adv7604_state *state = to_state(sd); | 767 | struct adv76xx_state *state = to_state(sd); |
771 | 768 | ||
772 | return state->selected_input == ADV7604_PAD_HDMI_PORT_A || | 769 | return state->selected_input == ADV76XX_PAD_HDMI_PORT_A || |
773 | state->selected_input == ADV7604_PAD_HDMI_PORT_B || | 770 | state->selected_input == ADV7604_PAD_HDMI_PORT_B || |
774 | state->selected_input == ADV7604_PAD_HDMI_PORT_C || | 771 | state->selected_input == ADV7604_PAD_HDMI_PORT_C || |
775 | state->selected_input == ADV7604_PAD_HDMI_PORT_D; | 772 | state->selected_input == ADV7604_PAD_HDMI_PORT_D; |
@@ -778,7 +775,7 @@ static inline bool is_digital_input(struct v4l2_subdev *sd) | |||
778 | /* ----------------------------------------------------------------------- */ | 775 | /* ----------------------------------------------------------------------- */ |
779 | 776 | ||
780 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 777 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
781 | static void adv7604_inv_register(struct v4l2_subdev *sd) | 778 | static void adv76xx_inv_register(struct v4l2_subdev *sd) |
782 | { | 779 | { |
783 | v4l2_info(sd, "0x000-0x0ff: IO Map\n"); | 780 | v4l2_info(sd, "0x000-0x0ff: IO Map\n"); |
784 | v4l2_info(sd, "0x100-0x1ff: AVLink Map\n"); | 781 | v4l2_info(sd, "0x100-0x1ff: AVLink Map\n"); |
@@ -795,15 +792,15 @@ static void adv7604_inv_register(struct v4l2_subdev *sd) | |||
795 | v4l2_info(sd, "0xc00-0xcff: VDP Map\n"); | 792 | v4l2_info(sd, "0xc00-0xcff: VDP Map\n"); |
796 | } | 793 | } |
797 | 794 | ||
798 | static int adv7604_g_register(struct v4l2_subdev *sd, | 795 | static int adv76xx_g_register(struct v4l2_subdev *sd, |
799 | struct v4l2_dbg_register *reg) | 796 | struct v4l2_dbg_register *reg) |
800 | { | 797 | { |
801 | int ret; | 798 | int ret; |
802 | 799 | ||
803 | ret = adv7604_read_reg(sd, reg->reg); | 800 | ret = adv76xx_read_reg(sd, reg->reg); |
804 | if (ret < 0) { | 801 | if (ret < 0) { |
805 | v4l2_info(sd, "Register %03llx not supported\n", reg->reg); | 802 | v4l2_info(sd, "Register %03llx not supported\n", reg->reg); |
806 | adv7604_inv_register(sd); | 803 | adv76xx_inv_register(sd); |
807 | return ret; | 804 | return ret; |
808 | } | 805 | } |
809 | 806 | ||
@@ -813,15 +810,15 @@ static int adv7604_g_register(struct v4l2_subdev *sd, | |||
813 | return 0; | 810 | return 0; |
814 | } | 811 | } |
815 | 812 | ||
816 | static int adv7604_s_register(struct v4l2_subdev *sd, | 813 | static int adv76xx_s_register(struct v4l2_subdev *sd, |
817 | const struct v4l2_dbg_register *reg) | 814 | const struct v4l2_dbg_register *reg) |
818 | { | 815 | { |
819 | int ret; | 816 | int ret; |
820 | 817 | ||
821 | ret = adv7604_write_reg(sd, reg->reg, reg->val); | 818 | ret = adv76xx_write_reg(sd, reg->reg, reg->val); |
822 | if (ret < 0) { | 819 | if (ret < 0) { |
823 | v4l2_info(sd, "Register %03llx not supported\n", reg->reg); | 820 | v4l2_info(sd, "Register %03llx not supported\n", reg->reg); |
824 | adv7604_inv_register(sd); | 821 | adv76xx_inv_register(sd); |
825 | return ret; | 822 | return ret; |
826 | } | 823 | } |
827 | 824 | ||
@@ -846,10 +843,10 @@ static unsigned int adv7611_read_cable_det(struct v4l2_subdev *sd) | |||
846 | return value & 1; | 843 | return value & 1; |
847 | } | 844 | } |
848 | 845 | ||
849 | static int adv7604_s_detect_tx_5v_ctrl(struct v4l2_subdev *sd) | 846 | static int adv76xx_s_detect_tx_5v_ctrl(struct v4l2_subdev *sd) |
850 | { | 847 | { |
851 | struct adv7604_state *state = to_state(sd); | 848 | struct adv76xx_state *state = to_state(sd); |
852 | const struct adv7604_chip_info *info = state->info; | 849 | const struct adv76xx_chip_info *info = state->info; |
853 | 850 | ||
854 | return v4l2_ctrl_s_ctrl(state->detect_tx_5v_ctrl, | 851 | return v4l2_ctrl_s_ctrl(state->detect_tx_5v_ctrl, |
855 | info->read_cable_det(sd)); | 852 | info->read_cable_det(sd)); |
@@ -857,7 +854,7 @@ static int adv7604_s_detect_tx_5v_ctrl(struct v4l2_subdev *sd) | |||
857 | 854 | ||
858 | static int find_and_set_predefined_video_timings(struct v4l2_subdev *sd, | 855 | static int find_and_set_predefined_video_timings(struct v4l2_subdev *sd, |
859 | u8 prim_mode, | 856 | u8 prim_mode, |
860 | const struct adv7604_video_standards *predef_vid_timings, | 857 | const struct adv76xx_video_standards *predef_vid_timings, |
861 | const struct v4l2_dv_timings *timings) | 858 | const struct v4l2_dv_timings *timings) |
862 | { | 859 | { |
863 | int i; | 860 | int i; |
@@ -878,12 +875,12 @@ static int find_and_set_predefined_video_timings(struct v4l2_subdev *sd, | |||
878 | static int configure_predefined_video_timings(struct v4l2_subdev *sd, | 875 | static int configure_predefined_video_timings(struct v4l2_subdev *sd, |
879 | struct v4l2_dv_timings *timings) | 876 | struct v4l2_dv_timings *timings) |
880 | { | 877 | { |
881 | struct adv7604_state *state = to_state(sd); | 878 | struct adv76xx_state *state = to_state(sd); |
882 | int err; | 879 | int err; |
883 | 880 | ||
884 | v4l2_dbg(1, debug, sd, "%s", __func__); | 881 | v4l2_dbg(1, debug, sd, "%s", __func__); |
885 | 882 | ||
886 | if (adv7604_has_afe(state)) { | 883 | if (adv76xx_has_afe(state)) { |
887 | /* reset to default values */ | 884 | /* reset to default values */ |
888 | io_write(sd, 0x16, 0x43); | 885 | io_write(sd, 0x16, 0x43); |
889 | io_write(sd, 0x17, 0x5a); | 886 | io_write(sd, 0x17, 0x5a); |
@@ -909,10 +906,10 @@ static int configure_predefined_video_timings(struct v4l2_subdev *sd, | |||
909 | 0x02, adv7604_prim_mode_gr, timings); | 906 | 0x02, adv7604_prim_mode_gr, timings); |
910 | } else if (is_digital_input(sd)) { | 907 | } else if (is_digital_input(sd)) { |
911 | err = find_and_set_predefined_video_timings(sd, | 908 | err = find_and_set_predefined_video_timings(sd, |
912 | 0x05, adv7604_prim_mode_hdmi_comp, timings); | 909 | 0x05, adv76xx_prim_mode_hdmi_comp, timings); |
913 | if (err) | 910 | if (err) |
914 | err = find_and_set_predefined_video_timings(sd, | 911 | err = find_and_set_predefined_video_timings(sd, |
915 | 0x06, adv7604_prim_mode_hdmi_gr, timings); | 912 | 0x06, adv76xx_prim_mode_hdmi_gr, timings); |
916 | } else { | 913 | } else { |
917 | v4l2_dbg(2, debug, sd, "%s: Unknown port %d selected\n", | 914 | v4l2_dbg(2, debug, sd, "%s: Unknown port %d selected\n", |
918 | __func__, state->selected_input); | 915 | __func__, state->selected_input); |
@@ -926,7 +923,7 @@ static int configure_predefined_video_timings(struct v4l2_subdev *sd, | |||
926 | static void configure_custom_video_timings(struct v4l2_subdev *sd, | 923 | static void configure_custom_video_timings(struct v4l2_subdev *sd, |
927 | const struct v4l2_bt_timings *bt) | 924 | const struct v4l2_bt_timings *bt) |
928 | { | 925 | { |
929 | struct adv7604_state *state = to_state(sd); | 926 | struct adv76xx_state *state = to_state(sd); |
930 | u32 width = htotal(bt); | 927 | u32 width = htotal(bt); |
931 | u32 height = vtotal(bt); | 928 | u32 height = vtotal(bt); |
932 | u16 cp_start_sav = bt->hsync + bt->hbackporch - 4; | 929 | u16 cp_start_sav = bt->hsync + bt->hbackporch - 4; |
@@ -934,7 +931,7 @@ static void configure_custom_video_timings(struct v4l2_subdev *sd, | |||
934 | u16 cp_start_vbi = height - bt->vfrontporch; | 931 | u16 cp_start_vbi = height - bt->vfrontporch; |
935 | u16 cp_end_vbi = bt->vsync + bt->vbackporch; | 932 | u16 cp_end_vbi = bt->vsync + bt->vbackporch; |
936 | u16 ch1_fr_ll = (((u32)bt->pixelclock / 100) > 0) ? | 933 | u16 ch1_fr_ll = (((u32)bt->pixelclock / 100) > 0) ? |
937 | ((width * (ADV7604_fsc / 100)) / ((u32)bt->pixelclock / 100)) : 0; | 934 | ((width * (ADV76XX_FSC / 100)) / ((u32)bt->pixelclock / 100)) : 0; |
938 | const u8 pll[2] = { | 935 | const u8 pll[2] = { |
939 | 0xc0 | ((width >> 8) & 0x1f), | 936 | 0xc0 | ((width >> 8) & 0x1f), |
940 | width & 0xff | 937 | width & 0xff |
@@ -952,7 +949,7 @@ static void configure_custom_video_timings(struct v4l2_subdev *sd, | |||
952 | /* Should only be set in auto-graphics mode [REF_02, p. 91-92] */ | 949 | /* Should only be set in auto-graphics mode [REF_02, p. 91-92] */ |
953 | /* setup PLL_DIV_MAN_EN and PLL_DIV_RATIO */ | 950 | /* setup PLL_DIV_MAN_EN and PLL_DIV_RATIO */ |
954 | /* IO-map reg. 0x16 and 0x17 should be written in sequence */ | 951 | /* IO-map reg. 0x16 and 0x17 should be written in sequence */ |
955 | if (adv_smbus_write_i2c_block_data(state, ADV7604_PAGE_IO, | 952 | if (adv_smbus_write_i2c_block_data(state, ADV76XX_PAGE_IO, |
956 | 0x16, 2, pll)) | 953 | 0x16, 2, pll)) |
957 | v4l2_err(sd, "writing to reg 0x16 and 0x17 failed\n"); | 954 | v4l2_err(sd, "writing to reg 0x16 and 0x17 failed\n"); |
958 | 955 | ||
@@ -983,9 +980,9 @@ static void configure_custom_video_timings(struct v4l2_subdev *sd, | |||
983 | cp_write(sd, 0xac, (height & 0x0f) << 4); | 980 | cp_write(sd, 0xac, (height & 0x0f) << 4); |
984 | } | 981 | } |
985 | 982 | ||
986 | static void adv7604_set_offset(struct v4l2_subdev *sd, bool auto_offset, u16 offset_a, u16 offset_b, u16 offset_c) | 983 | static void adv76xx_set_offset(struct v4l2_subdev *sd, bool auto_offset, u16 offset_a, u16 offset_b, u16 offset_c) |
987 | { | 984 | { |
988 | struct adv7604_state *state = to_state(sd); | 985 | struct adv76xx_state *state = to_state(sd); |
989 | u8 offset_buf[4]; | 986 | u8 offset_buf[4]; |
990 | 987 | ||
991 | if (auto_offset) { | 988 | if (auto_offset) { |
@@ -1004,14 +1001,14 @@ static void adv7604_set_offset(struct v4l2_subdev *sd, bool auto_offset, u16 off | |||
1004 | offset_buf[3] = offset_c & 0x0ff; | 1001 | offset_buf[3] = offset_c & 0x0ff; |
1005 | 1002 | ||
1006 | /* Registers must be written in this order with no i2c access in between */ | 1003 | /* Registers must be written in this order with no i2c access in between */ |
1007 | if (adv_smbus_write_i2c_block_data(state, ADV7604_PAGE_CP, | 1004 | if (adv_smbus_write_i2c_block_data(state, ADV76XX_PAGE_CP, |
1008 | 0x77, 4, offset_buf)) | 1005 | 0x77, 4, offset_buf)) |
1009 | v4l2_err(sd, "%s: i2c error writing to CP reg 0x77, 0x78, 0x79, 0x7a\n", __func__); | 1006 | v4l2_err(sd, "%s: i2c error writing to CP reg 0x77, 0x78, 0x79, 0x7a\n", __func__); |
1010 | } | 1007 | } |
1011 | 1008 | ||
1012 | static void adv7604_set_gain(struct v4l2_subdev *sd, bool auto_gain, u16 gain_a, u16 gain_b, u16 gain_c) | 1009 | static void adv76xx_set_gain(struct v4l2_subdev *sd, bool auto_gain, u16 gain_a, u16 gain_b, u16 gain_c) |
1013 | { | 1010 | { |
1014 | struct adv7604_state *state = to_state(sd); | 1011 | struct adv76xx_state *state = to_state(sd); |
1015 | u8 gain_buf[4]; | 1012 | u8 gain_buf[4]; |
1016 | u8 gain_man = 1; | 1013 | u8 gain_man = 1; |
1017 | u8 agc_mode_man = 1; | 1014 | u8 agc_mode_man = 1; |
@@ -1034,14 +1031,14 @@ static void adv7604_set_gain(struct v4l2_subdev *sd, bool auto_gain, u16 gain_a, | |||
1034 | gain_buf[3] = ((gain_c & 0x0ff)); | 1031 | gain_buf[3] = ((gain_c & 0x0ff)); |
1035 | 1032 | ||
1036 | /* Registers must be written in this order with no i2c access in between */ | 1033 | /* Registers must be written in this order with no i2c access in between */ |
1037 | if (adv_smbus_write_i2c_block_data(state, ADV7604_PAGE_CP, | 1034 | if (adv_smbus_write_i2c_block_data(state, ADV76XX_PAGE_CP, |
1038 | 0x73, 4, gain_buf)) | 1035 | 0x73, 4, gain_buf)) |
1039 | v4l2_err(sd, "%s: i2c error writing to CP reg 0x73, 0x74, 0x75, 0x76\n", __func__); | 1036 | v4l2_err(sd, "%s: i2c error writing to CP reg 0x73, 0x74, 0x75, 0x76\n", __func__); |
1040 | } | 1037 | } |
1041 | 1038 | ||
1042 | static void set_rgb_quantization_range(struct v4l2_subdev *sd) | 1039 | static void set_rgb_quantization_range(struct v4l2_subdev *sd) |
1043 | { | 1040 | { |
1044 | struct adv7604_state *state = to_state(sd); | 1041 | struct adv76xx_state *state = to_state(sd); |
1045 | bool rgb_output = io_read(sd, 0x02) & 0x02; | 1042 | bool rgb_output = io_read(sd, 0x02) & 0x02; |
1046 | bool hdmi_signal = hdmi_read(sd, 0x05) & 0x80; | 1043 | bool hdmi_signal = hdmi_read(sd, 0x05) & 0x80; |
1047 | 1044 | ||
@@ -1049,8 +1046,8 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd) | |||
1049 | __func__, state->rgb_quantization_range, | 1046 | __func__, state->rgb_quantization_range, |
1050 | rgb_output, hdmi_signal); | 1047 | rgb_output, hdmi_signal); |
1051 | 1048 | ||
1052 | adv7604_set_gain(sd, true, 0x0, 0x0, 0x0); | 1049 | adv76xx_set_gain(sd, true, 0x0, 0x0, 0x0); |
1053 | adv7604_set_offset(sd, true, 0x0, 0x0, 0x0); | 1050 | adv76xx_set_offset(sd, true, 0x0, 0x0, 0x0); |
1054 | 1051 | ||
1055 | switch (state->rgb_quantization_range) { | 1052 | switch (state->rgb_quantization_range) { |
1056 | case V4L2_DV_RGB_RANGE_AUTO: | 1053 | case V4L2_DV_RGB_RANGE_AUTO: |
@@ -1078,7 +1075,7 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd) | |||
1078 | /* Receiving DVI-D signal | 1075 | /* Receiving DVI-D signal |
1079 | * ADV7604 selects RGB limited range regardless of | 1076 | * ADV7604 selects RGB limited range regardless of |
1080 | * input format (CE/IT) in automatic mode */ | 1077 | * input format (CE/IT) in automatic mode */ |
1081 | if (state->timings.bt.standards & V4L2_DV_BT_STD_CEA861) { | 1078 | if (state->timings.bt.flags & V4L2_DV_FL_IS_CE_VIDEO) { |
1082 | /* RGB limited range (16-235) */ | 1079 | /* RGB limited range (16-235) */ |
1083 | io_write_clr_set(sd, 0x02, 0xf0, 0x00); | 1080 | io_write_clr_set(sd, 0x02, 0xf0, 0x00); |
1084 | } else { | 1081 | } else { |
@@ -1086,10 +1083,10 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd) | |||
1086 | io_write_clr_set(sd, 0x02, 0xf0, 0x10); | 1083 | io_write_clr_set(sd, 0x02, 0xf0, 0x10); |
1087 | 1084 | ||
1088 | if (is_digital_input(sd) && rgb_output) { | 1085 | if (is_digital_input(sd) && rgb_output) { |
1089 | adv7604_set_offset(sd, false, 0x40, 0x40, 0x40); | 1086 | adv76xx_set_offset(sd, false, 0x40, 0x40, 0x40); |
1090 | } else { | 1087 | } else { |
1091 | adv7604_set_gain(sd, false, 0xe0, 0xe0, 0xe0); | 1088 | adv76xx_set_gain(sd, false, 0xe0, 0xe0, 0xe0); |
1092 | adv7604_set_offset(sd, false, 0x70, 0x70, 0x70); | 1089 | adv76xx_set_offset(sd, false, 0x70, 0x70, 0x70); |
1093 | } | 1090 | } |
1094 | } | 1091 | } |
1095 | break; | 1092 | break; |
@@ -1119,21 +1116,21 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd) | |||
1119 | 1116 | ||
1120 | /* Adjust gain/offset for DVI-D signals only */ | 1117 | /* Adjust gain/offset for DVI-D signals only */ |
1121 | if (rgb_output) { | 1118 | if (rgb_output) { |
1122 | adv7604_set_offset(sd, false, 0x40, 0x40, 0x40); | 1119 | adv76xx_set_offset(sd, false, 0x40, 0x40, 0x40); |
1123 | } else { | 1120 | } else { |
1124 | adv7604_set_gain(sd, false, 0xe0, 0xe0, 0xe0); | 1121 | adv76xx_set_gain(sd, false, 0xe0, 0xe0, 0xe0); |
1125 | adv7604_set_offset(sd, false, 0x70, 0x70, 0x70); | 1122 | adv76xx_set_offset(sd, false, 0x70, 0x70, 0x70); |
1126 | } | 1123 | } |
1127 | break; | 1124 | break; |
1128 | } | 1125 | } |
1129 | } | 1126 | } |
1130 | 1127 | ||
1131 | static int adv7604_s_ctrl(struct v4l2_ctrl *ctrl) | 1128 | static int adv76xx_s_ctrl(struct v4l2_ctrl *ctrl) |
1132 | { | 1129 | { |
1133 | struct v4l2_subdev *sd = | 1130 | struct v4l2_subdev *sd = |
1134 | &container_of(ctrl->handler, struct adv7604_state, hdl)->sd; | 1131 | &container_of(ctrl->handler, struct adv76xx_state, hdl)->sd; |
1135 | 1132 | ||
1136 | struct adv7604_state *state = to_state(sd); | 1133 | struct adv76xx_state *state = to_state(sd); |
1137 | 1134 | ||
1138 | switch (ctrl->id) { | 1135 | switch (ctrl->id) { |
1139 | case V4L2_CID_BRIGHTNESS: | 1136 | case V4L2_CID_BRIGHTNESS: |
@@ -1153,7 +1150,7 @@ static int adv7604_s_ctrl(struct v4l2_ctrl *ctrl) | |||
1153 | set_rgb_quantization_range(sd); | 1150 | set_rgb_quantization_range(sd); |
1154 | return 0; | 1151 | return 0; |
1155 | case V4L2_CID_ADV_RX_ANALOG_SAMPLING_PHASE: | 1152 | case V4L2_CID_ADV_RX_ANALOG_SAMPLING_PHASE: |
1156 | if (!adv7604_has_afe(state)) | 1153 | if (!adv76xx_has_afe(state)) |
1157 | return -EINVAL; | 1154 | return -EINVAL; |
1158 | /* Set the analog sampling phase. This is needed to find the | 1155 | /* Set the analog sampling phase. This is needed to find the |
1159 | best sampling phase for analog video: an application or | 1156 | best sampling phase for analog video: an application or |
@@ -1185,15 +1182,15 @@ static inline bool no_power(struct v4l2_subdev *sd) | |||
1185 | 1182 | ||
1186 | static inline bool no_signal_tmds(struct v4l2_subdev *sd) | 1183 | static inline bool no_signal_tmds(struct v4l2_subdev *sd) |
1187 | { | 1184 | { |
1188 | struct adv7604_state *state = to_state(sd); | 1185 | struct adv76xx_state *state = to_state(sd); |
1189 | 1186 | ||
1190 | return !(io_read(sd, 0x6a) & (0x10 >> state->selected_input)); | 1187 | return !(io_read(sd, 0x6a) & (0x10 >> state->selected_input)); |
1191 | } | 1188 | } |
1192 | 1189 | ||
1193 | static inline bool no_lock_tmds(struct v4l2_subdev *sd) | 1190 | static inline bool no_lock_tmds(struct v4l2_subdev *sd) |
1194 | { | 1191 | { |
1195 | struct adv7604_state *state = to_state(sd); | 1192 | struct adv76xx_state *state = to_state(sd); |
1196 | const struct adv7604_chip_info *info = state->info; | 1193 | const struct adv76xx_chip_info *info = state->info; |
1197 | 1194 | ||
1198 | return (io_read(sd, 0x6a) & info->tdms_lock_mask) != info->tdms_lock_mask; | 1195 | return (io_read(sd, 0x6a) & info->tdms_lock_mask) != info->tdms_lock_mask; |
1199 | } | 1196 | } |
@@ -1205,13 +1202,13 @@ static inline bool is_hdmi(struct v4l2_subdev *sd) | |||
1205 | 1202 | ||
1206 | static inline bool no_lock_sspd(struct v4l2_subdev *sd) | 1203 | static inline bool no_lock_sspd(struct v4l2_subdev *sd) |
1207 | { | 1204 | { |
1208 | struct adv7604_state *state = to_state(sd); | 1205 | struct adv76xx_state *state = to_state(sd); |
1209 | 1206 | ||
1210 | /* | 1207 | /* |
1211 | * Chips without a AFE don't expose registers for the SSPD, so just assume | 1208 | * Chips without a AFE don't expose registers for the SSPD, so just assume |
1212 | * that we have a lock. | 1209 | * that we have a lock. |
1213 | */ | 1210 | */ |
1214 | if (adv7604_has_afe(state)) | 1211 | if (adv76xx_has_afe(state)) |
1215 | return false; | 1212 | return false; |
1216 | 1213 | ||
1217 | /* TODO channel 2 */ | 1214 | /* TODO channel 2 */ |
@@ -1243,9 +1240,9 @@ static inline bool no_signal(struct v4l2_subdev *sd) | |||
1243 | 1240 | ||
1244 | static inline bool no_lock_cp(struct v4l2_subdev *sd) | 1241 | static inline bool no_lock_cp(struct v4l2_subdev *sd) |
1245 | { | 1242 | { |
1246 | struct adv7604_state *state = to_state(sd); | 1243 | struct adv76xx_state *state = to_state(sd); |
1247 | 1244 | ||
1248 | if (!adv7604_has_afe(state)) | 1245 | if (!adv76xx_has_afe(state)) |
1249 | return false; | 1246 | return false; |
1250 | 1247 | ||
1251 | /* CP has detected a non standard number of lines on the incoming | 1248 | /* CP has detected a non standard number of lines on the incoming |
@@ -1253,13 +1250,19 @@ static inline bool no_lock_cp(struct v4l2_subdev *sd) | |||
1253 | return io_read(sd, 0x12) & 0x01; | 1250 | return io_read(sd, 0x12) & 0x01; |
1254 | } | 1251 | } |
1255 | 1252 | ||
1256 | static int adv7604_g_input_status(struct v4l2_subdev *sd, u32 *status) | 1253 | static inline bool in_free_run(struct v4l2_subdev *sd) |
1254 | { | ||
1255 | return cp_read(sd, 0xff) & 0x10; | ||
1256 | } | ||
1257 | |||
1258 | static int adv76xx_g_input_status(struct v4l2_subdev *sd, u32 *status) | ||
1257 | { | 1259 | { |
1258 | *status = 0; | 1260 | *status = 0; |
1259 | *status |= no_power(sd) ? V4L2_IN_ST_NO_POWER : 0; | 1261 | *status |= no_power(sd) ? V4L2_IN_ST_NO_POWER : 0; |
1260 | *status |= no_signal(sd) ? V4L2_IN_ST_NO_SIGNAL : 0; | 1262 | *status |= no_signal(sd) ? V4L2_IN_ST_NO_SIGNAL : 0; |
1261 | if (no_lock_cp(sd)) | 1263 | if (!in_free_run(sd) && no_lock_cp(sd)) |
1262 | *status |= is_digital_input(sd) ? V4L2_IN_ST_NO_SYNC : V4L2_IN_ST_NO_H_LOCK; | 1264 | *status |= is_digital_input(sd) ? |
1265 | V4L2_IN_ST_NO_SYNC : V4L2_IN_ST_NO_H_LOCK; | ||
1263 | 1266 | ||
1264 | v4l2_dbg(1, debug, sd, "%s: status = 0x%x\n", __func__, *status); | 1267 | v4l2_dbg(1, debug, sd, "%s: status = 0x%x\n", __func__, *status); |
1265 | 1268 | ||
@@ -1278,22 +1281,22 @@ static int stdi2dv_timings(struct v4l2_subdev *sd, | |||
1278 | struct stdi_readback *stdi, | 1281 | struct stdi_readback *stdi, |
1279 | struct v4l2_dv_timings *timings) | 1282 | struct v4l2_dv_timings *timings) |
1280 | { | 1283 | { |
1281 | struct adv7604_state *state = to_state(sd); | 1284 | struct adv76xx_state *state = to_state(sd); |
1282 | u32 hfreq = (ADV7604_fsc * 8) / stdi->bl; | 1285 | u32 hfreq = (ADV76XX_FSC * 8) / stdi->bl; |
1283 | u32 pix_clk; | 1286 | u32 pix_clk; |
1284 | int i; | 1287 | int i; |
1285 | 1288 | ||
1286 | for (i = 0; adv7604_timings[i].bt.height; i++) { | 1289 | for (i = 0; adv76xx_timings[i].bt.height; i++) { |
1287 | if (vtotal(&adv7604_timings[i].bt) != stdi->lcf + 1) | 1290 | if (vtotal(&adv76xx_timings[i].bt) != stdi->lcf + 1) |
1288 | continue; | 1291 | continue; |
1289 | if (adv7604_timings[i].bt.vsync != stdi->lcvs) | 1292 | if (adv76xx_timings[i].bt.vsync != stdi->lcvs) |
1290 | continue; | 1293 | continue; |
1291 | 1294 | ||
1292 | pix_clk = hfreq * htotal(&adv7604_timings[i].bt); | 1295 | pix_clk = hfreq * htotal(&adv76xx_timings[i].bt); |
1293 | 1296 | ||
1294 | if ((pix_clk < adv7604_timings[i].bt.pixelclock + 1000000) && | 1297 | if ((pix_clk < adv76xx_timings[i].bt.pixelclock + 1000000) && |
1295 | (pix_clk > adv7604_timings[i].bt.pixelclock - 1000000)) { | 1298 | (pix_clk > adv76xx_timings[i].bt.pixelclock - 1000000)) { |
1296 | *timings = adv7604_timings[i]; | 1299 | *timings = adv76xx_timings[i]; |
1297 | return 0; | 1300 | return 0; |
1298 | } | 1301 | } |
1299 | } | 1302 | } |
@@ -1319,8 +1322,8 @@ static int stdi2dv_timings(struct v4l2_subdev *sd, | |||
1319 | 1322 | ||
1320 | static int read_stdi(struct v4l2_subdev *sd, struct stdi_readback *stdi) | 1323 | static int read_stdi(struct v4l2_subdev *sd, struct stdi_readback *stdi) |
1321 | { | 1324 | { |
1322 | struct adv7604_state *state = to_state(sd); | 1325 | struct adv76xx_state *state = to_state(sd); |
1323 | const struct adv7604_chip_info *info = state->info; | 1326 | const struct adv76xx_chip_info *info = state->info; |
1324 | u8 polarity; | 1327 | u8 polarity; |
1325 | 1328 | ||
1326 | if (no_lock_stdi(sd) || no_lock_sspd(sd)) { | 1329 | if (no_lock_stdi(sd) || no_lock_sspd(sd)) { |
@@ -1334,7 +1337,7 @@ static int read_stdi(struct v4l2_subdev *sd, struct stdi_readback *stdi) | |||
1334 | stdi->lcvs = cp_read(sd, 0xb3) >> 3; | 1337 | stdi->lcvs = cp_read(sd, 0xb3) >> 3; |
1335 | stdi->interlaced = io_read(sd, 0x12) & 0x10; | 1338 | stdi->interlaced = io_read(sd, 0x12) & 0x10; |
1336 | 1339 | ||
1337 | if (adv7604_has_afe(state)) { | 1340 | if (adv76xx_has_afe(state)) { |
1338 | /* read SSPD */ | 1341 | /* read SSPD */ |
1339 | polarity = cp_read(sd, 0xb5); | 1342 | polarity = cp_read(sd, 0xb5); |
1340 | if ((polarity & 0x03) == 0x01) { | 1343 | if ((polarity & 0x03) == 0x01) { |
@@ -1373,26 +1376,26 @@ static int read_stdi(struct v4l2_subdev *sd, struct stdi_readback *stdi) | |||
1373 | return 0; | 1376 | return 0; |
1374 | } | 1377 | } |
1375 | 1378 | ||
1376 | static int adv7604_enum_dv_timings(struct v4l2_subdev *sd, | 1379 | static int adv76xx_enum_dv_timings(struct v4l2_subdev *sd, |
1377 | struct v4l2_enum_dv_timings *timings) | 1380 | struct v4l2_enum_dv_timings *timings) |
1378 | { | 1381 | { |
1379 | struct adv7604_state *state = to_state(sd); | 1382 | struct adv76xx_state *state = to_state(sd); |
1380 | 1383 | ||
1381 | if (timings->index >= ARRAY_SIZE(adv7604_timings) - 1) | 1384 | if (timings->index >= ARRAY_SIZE(adv76xx_timings) - 1) |
1382 | return -EINVAL; | 1385 | return -EINVAL; |
1383 | 1386 | ||
1384 | if (timings->pad >= state->source_pad) | 1387 | if (timings->pad >= state->source_pad) |
1385 | return -EINVAL; | 1388 | return -EINVAL; |
1386 | 1389 | ||
1387 | memset(timings->reserved, 0, sizeof(timings->reserved)); | 1390 | memset(timings->reserved, 0, sizeof(timings->reserved)); |
1388 | timings->timings = adv7604_timings[timings->index]; | 1391 | timings->timings = adv76xx_timings[timings->index]; |
1389 | return 0; | 1392 | return 0; |
1390 | } | 1393 | } |
1391 | 1394 | ||
1392 | static int adv7604_dv_timings_cap(struct v4l2_subdev *sd, | 1395 | static int adv76xx_dv_timings_cap(struct v4l2_subdev *sd, |
1393 | struct v4l2_dv_timings_cap *cap) | 1396 | struct v4l2_dv_timings_cap *cap) |
1394 | { | 1397 | { |
1395 | struct adv7604_state *state = to_state(sd); | 1398 | struct adv76xx_state *state = to_state(sd); |
1396 | 1399 | ||
1397 | if (cap->pad >= state->source_pad) | 1400 | if (cap->pad >= state->source_pad) |
1398 | return -EINVAL; | 1401 | return -EINVAL; |
@@ -1403,7 +1406,7 @@ static int adv7604_dv_timings_cap(struct v4l2_subdev *sd, | |||
1403 | cap->bt.min_pixelclock = 25000000; | 1406 | cap->bt.min_pixelclock = 25000000; |
1404 | 1407 | ||
1405 | switch (cap->pad) { | 1408 | switch (cap->pad) { |
1406 | case ADV7604_PAD_HDMI_PORT_A: | 1409 | case ADV76XX_PAD_HDMI_PORT_A: |
1407 | case ADV7604_PAD_HDMI_PORT_B: | 1410 | case ADV7604_PAD_HDMI_PORT_B: |
1408 | case ADV7604_PAD_HDMI_PORT_C: | 1411 | case ADV7604_PAD_HDMI_PORT_C: |
1409 | case ADV7604_PAD_HDMI_PORT_D: | 1412 | case ADV7604_PAD_HDMI_PORT_D: |
@@ -1424,16 +1427,16 @@ static int adv7604_dv_timings_cap(struct v4l2_subdev *sd, | |||
1424 | } | 1427 | } |
1425 | 1428 | ||
1426 | /* Fill the optional fields .standards and .flags in struct v4l2_dv_timings | 1429 | /* Fill the optional fields .standards and .flags in struct v4l2_dv_timings |
1427 | if the format is listed in adv7604_timings[] */ | 1430 | if the format is listed in adv76xx_timings[] */ |
1428 | static void adv7604_fill_optional_dv_timings_fields(struct v4l2_subdev *sd, | 1431 | static void adv76xx_fill_optional_dv_timings_fields(struct v4l2_subdev *sd, |
1429 | struct v4l2_dv_timings *timings) | 1432 | struct v4l2_dv_timings *timings) |
1430 | { | 1433 | { |
1431 | int i; | 1434 | int i; |
1432 | 1435 | ||
1433 | for (i = 0; adv7604_timings[i].bt.width; i++) { | 1436 | for (i = 0; adv76xx_timings[i].bt.width; i++) { |
1434 | if (v4l2_match_dv_timings(timings, &adv7604_timings[i], | 1437 | if (v4l2_match_dv_timings(timings, &adv76xx_timings[i], |
1435 | is_digital_input(sd) ? 250000 : 1000000)) { | 1438 | is_digital_input(sd) ? 250000 : 1000000)) { |
1436 | *timings = adv7604_timings[i]; | 1439 | *timings = adv76xx_timings[i]; |
1437 | break; | 1440 | break; |
1438 | } | 1441 | } |
1439 | } | 1442 | } |
@@ -1471,11 +1474,11 @@ static unsigned int adv7611_read_hdmi_pixelclock(struct v4l2_subdev *sd) | |||
1471 | return ((a << 1) | (b >> 7)) * 1000000 + (b & 0x7f) * 1000000 / 128; | 1474 | return ((a << 1) | (b >> 7)) * 1000000 + (b & 0x7f) * 1000000 / 128; |
1472 | } | 1475 | } |
1473 | 1476 | ||
1474 | static int adv7604_query_dv_timings(struct v4l2_subdev *sd, | 1477 | static int adv76xx_query_dv_timings(struct v4l2_subdev *sd, |
1475 | struct v4l2_dv_timings *timings) | 1478 | struct v4l2_dv_timings *timings) |
1476 | { | 1479 | { |
1477 | struct adv7604_state *state = to_state(sd); | 1480 | struct adv76xx_state *state = to_state(sd); |
1478 | const struct adv7604_chip_info *info = state->info; | 1481 | const struct adv76xx_chip_info *info = state->info; |
1479 | struct v4l2_bt_timings *bt = &timings->bt; | 1482 | struct v4l2_bt_timings *bt = &timings->bt; |
1480 | struct stdi_readback stdi; | 1483 | struct stdi_readback stdi; |
1481 | 1484 | ||
@@ -1519,7 +1522,7 @@ static int adv7604_query_dv_timings(struct v4l2_subdev *sd, | |||
1519 | bt->il_vsync = hdmi_read16(sd, 0x30, 0x1fff) / 2; | 1522 | bt->il_vsync = hdmi_read16(sd, 0x30, 0x1fff) / 2; |
1520 | bt->il_vbackporch = hdmi_read16(sd, 0x34, 0x1fff) / 2; | 1523 | bt->il_vbackporch = hdmi_read16(sd, 0x34, 0x1fff) / 2; |
1521 | } | 1524 | } |
1522 | adv7604_fill_optional_dv_timings_fields(sd, timings); | 1525 | adv76xx_fill_optional_dv_timings_fields(sd, timings); |
1523 | } else { | 1526 | } else { |
1524 | /* find format | 1527 | /* find format |
1525 | * Since LCVS values are inaccurate [REF_03, p. 275-276], | 1528 | * Since LCVS values are inaccurate [REF_03, p. 275-276], |
@@ -1576,16 +1579,16 @@ found: | |||
1576 | } | 1579 | } |
1577 | 1580 | ||
1578 | if (debug > 1) | 1581 | if (debug > 1) |
1579 | v4l2_print_dv_timings(sd->name, "adv7604_query_dv_timings: ", | 1582 | v4l2_print_dv_timings(sd->name, "adv76xx_query_dv_timings: ", |
1580 | timings, true); | 1583 | timings, true); |
1581 | 1584 | ||
1582 | return 0; | 1585 | return 0; |
1583 | } | 1586 | } |
1584 | 1587 | ||
1585 | static int adv7604_s_dv_timings(struct v4l2_subdev *sd, | 1588 | static int adv76xx_s_dv_timings(struct v4l2_subdev *sd, |
1586 | struct v4l2_dv_timings *timings) | 1589 | struct v4l2_dv_timings *timings) |
1587 | { | 1590 | { |
1588 | struct adv7604_state *state = to_state(sd); | 1591 | struct adv76xx_state *state = to_state(sd); |
1589 | struct v4l2_bt_timings *bt; | 1592 | struct v4l2_bt_timings *bt; |
1590 | int err; | 1593 | int err; |
1591 | 1594 | ||
@@ -1606,7 +1609,7 @@ static int adv7604_s_dv_timings(struct v4l2_subdev *sd, | |||
1606 | return -ERANGE; | 1609 | return -ERANGE; |
1607 | } | 1610 | } |
1608 | 1611 | ||
1609 | adv7604_fill_optional_dv_timings_fields(sd, timings); | 1612 | adv76xx_fill_optional_dv_timings_fields(sd, timings); |
1610 | 1613 | ||
1611 | state->timings = *timings; | 1614 | state->timings = *timings; |
1612 | 1615 | ||
@@ -1623,15 +1626,15 @@ static int adv7604_s_dv_timings(struct v4l2_subdev *sd, | |||
1623 | set_rgb_quantization_range(sd); | 1626 | set_rgb_quantization_range(sd); |
1624 | 1627 | ||
1625 | if (debug > 1) | 1628 | if (debug > 1) |
1626 | v4l2_print_dv_timings(sd->name, "adv7604_s_dv_timings: ", | 1629 | v4l2_print_dv_timings(sd->name, "adv76xx_s_dv_timings: ", |
1627 | timings, true); | 1630 | timings, true); |
1628 | return 0; | 1631 | return 0; |
1629 | } | 1632 | } |
1630 | 1633 | ||
1631 | static int adv7604_g_dv_timings(struct v4l2_subdev *sd, | 1634 | static int adv76xx_g_dv_timings(struct v4l2_subdev *sd, |
1632 | struct v4l2_dv_timings *timings) | 1635 | struct v4l2_dv_timings *timings) |
1633 | { | 1636 | { |
1634 | struct adv7604_state *state = to_state(sd); | 1637 | struct adv76xx_state *state = to_state(sd); |
1635 | 1638 | ||
1636 | *timings = state->timings; | 1639 | *timings = state->timings; |
1637 | return 0; | 1640 | return 0; |
@@ -1649,7 +1652,7 @@ static void adv7611_set_termination(struct v4l2_subdev *sd, bool enable) | |||
1649 | 1652 | ||
1650 | static void enable_input(struct v4l2_subdev *sd) | 1653 | static void enable_input(struct v4l2_subdev *sd) |
1651 | { | 1654 | { |
1652 | struct adv7604_state *state = to_state(sd); | 1655 | struct adv76xx_state *state = to_state(sd); |
1653 | 1656 | ||
1654 | if (is_analog_input(sd)) { | 1657 | if (is_analog_input(sd)) { |
1655 | io_write(sd, 0x15, 0xb0); /* Disable Tristate of Pins (no audio) */ | 1658 | io_write(sd, 0x15, 0xb0); /* Disable Tristate of Pins (no audio) */ |
@@ -1666,7 +1669,7 @@ static void enable_input(struct v4l2_subdev *sd) | |||
1666 | 1669 | ||
1667 | static void disable_input(struct v4l2_subdev *sd) | 1670 | static void disable_input(struct v4l2_subdev *sd) |
1668 | { | 1671 | { |
1669 | struct adv7604_state *state = to_state(sd); | 1672 | struct adv76xx_state *state = to_state(sd); |
1670 | 1673 | ||
1671 | hdmi_write_clr_set(sd, 0x1a, 0x10, 0x10); /* Mute audio */ | 1674 | hdmi_write_clr_set(sd, 0x1a, 0x10, 0x10); /* Mute audio */ |
1672 | msleep(16); /* 512 samples with >= 32 kHz sample rate [REF_03, c. 7.16.10] */ | 1675 | msleep(16); /* 512 samples with >= 32 kHz sample rate [REF_03, c. 7.16.10] */ |
@@ -1676,11 +1679,11 @@ static void disable_input(struct v4l2_subdev *sd) | |||
1676 | 1679 | ||
1677 | static void select_input(struct v4l2_subdev *sd) | 1680 | static void select_input(struct v4l2_subdev *sd) |
1678 | { | 1681 | { |
1679 | struct adv7604_state *state = to_state(sd); | 1682 | struct adv76xx_state *state = to_state(sd); |
1680 | const struct adv7604_chip_info *info = state->info; | 1683 | const struct adv76xx_chip_info *info = state->info; |
1681 | 1684 | ||
1682 | if (is_analog_input(sd)) { | 1685 | if (is_analog_input(sd)) { |
1683 | adv7604_write_reg_seq(sd, info->recommended_settings[0]); | 1686 | adv76xx_write_reg_seq(sd, info->recommended_settings[0]); |
1684 | 1687 | ||
1685 | afe_write(sd, 0x00, 0x08); /* power up ADC */ | 1688 | afe_write(sd, 0x00, 0x08); /* power up ADC */ |
1686 | afe_write(sd, 0x01, 0x06); /* power up Analog Front End */ | 1689 | afe_write(sd, 0x01, 0x06); /* power up Analog Front End */ |
@@ -1688,9 +1691,9 @@ static void select_input(struct v4l2_subdev *sd) | |||
1688 | } else if (is_digital_input(sd)) { | 1691 | } else if (is_digital_input(sd)) { |
1689 | hdmi_write(sd, 0x00, state->selected_input & 0x03); | 1692 | hdmi_write(sd, 0x00, state->selected_input & 0x03); |
1690 | 1693 | ||
1691 | adv7604_write_reg_seq(sd, info->recommended_settings[1]); | 1694 | adv76xx_write_reg_seq(sd, info->recommended_settings[1]); |
1692 | 1695 | ||
1693 | if (adv7604_has_afe(state)) { | 1696 | if (adv76xx_has_afe(state)) { |
1694 | afe_write(sd, 0x00, 0xff); /* power down ADC */ | 1697 | afe_write(sd, 0x00, 0xff); /* power down ADC */ |
1695 | afe_write(sd, 0x01, 0xfe); /* power down Analog Front End */ | 1698 | afe_write(sd, 0x01, 0xfe); /* power down Analog Front End */ |
1696 | afe_write(sd, 0xc8, 0x40); /* phase control */ | 1699 | afe_write(sd, 0xc8, 0x40); /* phase control */ |
@@ -1705,10 +1708,10 @@ static void select_input(struct v4l2_subdev *sd) | |||
1705 | } | 1708 | } |
1706 | } | 1709 | } |
1707 | 1710 | ||
1708 | static int adv7604_s_routing(struct v4l2_subdev *sd, | 1711 | static int adv76xx_s_routing(struct v4l2_subdev *sd, |
1709 | u32 input, u32 output, u32 config) | 1712 | u32 input, u32 output, u32 config) |
1710 | { | 1713 | { |
1711 | struct adv7604_state *state = to_state(sd); | 1714 | struct adv76xx_state *state = to_state(sd); |
1712 | 1715 | ||
1713 | v4l2_dbg(2, debug, sd, "%s: input %d, selected input %d", | 1716 | v4l2_dbg(2, debug, sd, "%s: input %d, selected input %d", |
1714 | __func__, input, state->selected_input); | 1717 | __func__, input, state->selected_input); |
@@ -1730,11 +1733,11 @@ static int adv7604_s_routing(struct v4l2_subdev *sd, | |||
1730 | return 0; | 1733 | return 0; |
1731 | } | 1734 | } |
1732 | 1735 | ||
1733 | static int adv7604_enum_mbus_code(struct v4l2_subdev *sd, | 1736 | static int adv76xx_enum_mbus_code(struct v4l2_subdev *sd, |
1734 | struct v4l2_subdev_fh *fh, | 1737 | struct v4l2_subdev_pad_config *cfg, |
1735 | struct v4l2_subdev_mbus_code_enum *code) | 1738 | struct v4l2_subdev_mbus_code_enum *code) |
1736 | { | 1739 | { |
1737 | struct adv7604_state *state = to_state(sd); | 1740 | struct adv76xx_state *state = to_state(sd); |
1738 | 1741 | ||
1739 | if (code->index >= state->info->nformats) | 1742 | if (code->index >= state->info->nformats) |
1740 | return -EINVAL; | 1743 | return -EINVAL; |
@@ -1744,7 +1747,7 @@ static int adv7604_enum_mbus_code(struct v4l2_subdev *sd, | |||
1744 | return 0; | 1747 | return 0; |
1745 | } | 1748 | } |
1746 | 1749 | ||
1747 | static void adv7604_fill_format(struct adv7604_state *state, | 1750 | static void adv76xx_fill_format(struct adv76xx_state *state, |
1748 | struct v4l2_mbus_framefmt *format) | 1751 | struct v4l2_mbus_framefmt *format) |
1749 | { | 1752 | { |
1750 | memset(format, 0, sizeof(*format)); | 1753 | memset(format, 0, sizeof(*format)); |
@@ -1752,8 +1755,9 @@ static void adv7604_fill_format(struct adv7604_state *state, | |||
1752 | format->width = state->timings.bt.width; | 1755 | format->width = state->timings.bt.width; |
1753 | format->height = state->timings.bt.height; | 1756 | format->height = state->timings.bt.height; |
1754 | format->field = V4L2_FIELD_NONE; | 1757 | format->field = V4L2_FIELD_NONE; |
1758 | format->colorspace = V4L2_COLORSPACE_SRGB; | ||
1755 | 1759 | ||
1756 | if (state->timings.bt.standards & V4L2_DV_BT_STD_CEA861) | 1760 | if (state->timings.bt.flags & V4L2_DV_FL_IS_CE_VIDEO) |
1757 | format->colorspace = (state->timings.bt.height <= 576) ? | 1761 | format->colorspace = (state->timings.bt.height <= 576) ? |
1758 | V4L2_COLORSPACE_SMPTE170M : V4L2_COLORSPACE_REC709; | 1762 | V4L2_COLORSPACE_SMPTE170M : V4L2_COLORSPACE_REC709; |
1759 | } | 1763 | } |
@@ -1765,7 +1769,7 @@ static void adv7604_fill_format(struct adv7604_state *state, | |||
1765 | * | 1769 | * |
1766 | * The following table gives the op_ch_value from the format component order | 1770 | * The following table gives the op_ch_value from the format component order |
1767 | * (expressed as op_ch_sel value in column) and the bus reordering (expressed as | 1771 | * (expressed as op_ch_sel value in column) and the bus reordering (expressed as |
1768 | * adv7604_bus_order value in row). | 1772 | * adv76xx_bus_order value in row). |
1769 | * | 1773 | * |
1770 | * | GBR(0) GRB(1) BGR(2) RGB(3) BRG(4) RBG(5) | 1774 | * | GBR(0) GRB(1) BGR(2) RGB(3) BRG(4) RBG(5) |
1771 | * ----------+------------------------------------------------- | 1775 | * ----------+------------------------------------------------- |
@@ -1776,11 +1780,11 @@ static void adv7604_fill_format(struct adv7604_state *state, | |||
1776 | * BRG (ROR) | BRG RBG GRB GBR RGB BGR | 1780 | * BRG (ROR) | BRG RBG GRB GBR RGB BGR |
1777 | * GBR (ROL) | RGB BGR RBG BRG GBR GRB | 1781 | * GBR (ROL) | RGB BGR RBG BRG GBR GRB |
1778 | */ | 1782 | */ |
1779 | static unsigned int adv7604_op_ch_sel(struct adv7604_state *state) | 1783 | static unsigned int adv76xx_op_ch_sel(struct adv76xx_state *state) |
1780 | { | 1784 | { |
1781 | #define _SEL(a,b,c,d,e,f) { \ | 1785 | #define _SEL(a,b,c,d,e,f) { \ |
1782 | ADV7604_OP_CH_SEL_##a, ADV7604_OP_CH_SEL_##b, ADV7604_OP_CH_SEL_##c, \ | 1786 | ADV76XX_OP_CH_SEL_##a, ADV76XX_OP_CH_SEL_##b, ADV76XX_OP_CH_SEL_##c, \ |
1783 | ADV7604_OP_CH_SEL_##d, ADV7604_OP_CH_SEL_##e, ADV7604_OP_CH_SEL_##f } | 1787 | ADV76XX_OP_CH_SEL_##d, ADV76XX_OP_CH_SEL_##e, ADV76XX_OP_CH_SEL_##f } |
1784 | #define _BUS(x) [ADV7604_BUS_ORDER_##x] | 1788 | #define _BUS(x) [ADV7604_BUS_ORDER_##x] |
1785 | 1789 | ||
1786 | static const unsigned int op_ch_sel[6][6] = { | 1790 | static const unsigned int op_ch_sel[6][6] = { |
@@ -1795,33 +1799,34 @@ static unsigned int adv7604_op_ch_sel(struct adv7604_state *state) | |||
1795 | return op_ch_sel[state->pdata.bus_order][state->format->op_ch_sel >> 5]; | 1799 | return op_ch_sel[state->pdata.bus_order][state->format->op_ch_sel >> 5]; |
1796 | } | 1800 | } |
1797 | 1801 | ||
1798 | static void adv7604_setup_format(struct adv7604_state *state) | 1802 | static void adv76xx_setup_format(struct adv76xx_state *state) |
1799 | { | 1803 | { |
1800 | struct v4l2_subdev *sd = &state->sd; | 1804 | struct v4l2_subdev *sd = &state->sd; |
1801 | 1805 | ||
1802 | io_write_clr_set(sd, 0x02, 0x02, | 1806 | io_write_clr_set(sd, 0x02, 0x02, |
1803 | state->format->rgb_out ? ADV7604_RGB_OUT : 0); | 1807 | state->format->rgb_out ? ADV76XX_RGB_OUT : 0); |
1804 | io_write(sd, 0x03, state->format->op_format_sel | | 1808 | io_write(sd, 0x03, state->format->op_format_sel | |
1805 | state->pdata.op_format_mode_sel); | 1809 | state->pdata.op_format_mode_sel); |
1806 | io_write_clr_set(sd, 0x04, 0xe0, adv7604_op_ch_sel(state)); | 1810 | io_write_clr_set(sd, 0x04, 0xe0, adv76xx_op_ch_sel(state)); |
1807 | io_write_clr_set(sd, 0x05, 0x01, | 1811 | io_write_clr_set(sd, 0x05, 0x01, |
1808 | state->format->swap_cb_cr ? ADV7604_OP_SWAP_CB_CR : 0); | 1812 | state->format->swap_cb_cr ? ADV76XX_OP_SWAP_CB_CR : 0); |
1809 | } | 1813 | } |
1810 | 1814 | ||
1811 | static int adv7604_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | 1815 | static int adv76xx_get_format(struct v4l2_subdev *sd, |
1816 | struct v4l2_subdev_pad_config *cfg, | ||
1812 | struct v4l2_subdev_format *format) | 1817 | struct v4l2_subdev_format *format) |
1813 | { | 1818 | { |
1814 | struct adv7604_state *state = to_state(sd); | 1819 | struct adv76xx_state *state = to_state(sd); |
1815 | 1820 | ||
1816 | if (format->pad != state->source_pad) | 1821 | if (format->pad != state->source_pad) |
1817 | return -EINVAL; | 1822 | return -EINVAL; |
1818 | 1823 | ||
1819 | adv7604_fill_format(state, &format->format); | 1824 | adv76xx_fill_format(state, &format->format); |
1820 | 1825 | ||
1821 | if (format->which == V4L2_SUBDEV_FORMAT_TRY) { | 1826 | if (format->which == V4L2_SUBDEV_FORMAT_TRY) { |
1822 | struct v4l2_mbus_framefmt *fmt; | 1827 | struct v4l2_mbus_framefmt *fmt; |
1823 | 1828 | ||
1824 | fmt = v4l2_subdev_get_try_format(fh, format->pad); | 1829 | fmt = v4l2_subdev_get_try_format(sd, cfg, format->pad); |
1825 | format->format.code = fmt->code; | 1830 | format->format.code = fmt->code; |
1826 | } else { | 1831 | } else { |
1827 | format->format.code = state->format->code; | 1832 | format->format.code = state->format->code; |
@@ -1830,39 +1835,40 @@ static int adv7604_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
1830 | return 0; | 1835 | return 0; |
1831 | } | 1836 | } |
1832 | 1837 | ||
1833 | static int adv7604_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | 1838 | static int adv76xx_set_format(struct v4l2_subdev *sd, |
1839 | struct v4l2_subdev_pad_config *cfg, | ||
1834 | struct v4l2_subdev_format *format) | 1840 | struct v4l2_subdev_format *format) |
1835 | { | 1841 | { |
1836 | struct adv7604_state *state = to_state(sd); | 1842 | struct adv76xx_state *state = to_state(sd); |
1837 | const struct adv7604_format_info *info; | 1843 | const struct adv76xx_format_info *info; |
1838 | 1844 | ||
1839 | if (format->pad != state->source_pad) | 1845 | if (format->pad != state->source_pad) |
1840 | return -EINVAL; | 1846 | return -EINVAL; |
1841 | 1847 | ||
1842 | info = adv7604_format_info(state, format->format.code); | 1848 | info = adv76xx_format_info(state, format->format.code); |
1843 | if (info == NULL) | 1849 | if (info == NULL) |
1844 | info = adv7604_format_info(state, MEDIA_BUS_FMT_YUYV8_2X8); | 1850 | info = adv76xx_format_info(state, MEDIA_BUS_FMT_YUYV8_2X8); |
1845 | 1851 | ||
1846 | adv7604_fill_format(state, &format->format); | 1852 | adv76xx_fill_format(state, &format->format); |
1847 | format->format.code = info->code; | 1853 | format->format.code = info->code; |
1848 | 1854 | ||
1849 | if (format->which == V4L2_SUBDEV_FORMAT_TRY) { | 1855 | if (format->which == V4L2_SUBDEV_FORMAT_TRY) { |
1850 | struct v4l2_mbus_framefmt *fmt; | 1856 | struct v4l2_mbus_framefmt *fmt; |
1851 | 1857 | ||
1852 | fmt = v4l2_subdev_get_try_format(fh, format->pad); | 1858 | fmt = v4l2_subdev_get_try_format(sd, cfg, format->pad); |
1853 | fmt->code = format->format.code; | 1859 | fmt->code = format->format.code; |
1854 | } else { | 1860 | } else { |
1855 | state->format = info; | 1861 | state->format = info; |
1856 | adv7604_setup_format(state); | 1862 | adv76xx_setup_format(state); |
1857 | } | 1863 | } |
1858 | 1864 | ||
1859 | return 0; | 1865 | return 0; |
1860 | } | 1866 | } |
1861 | 1867 | ||
1862 | static int adv7604_isr(struct v4l2_subdev *sd, u32 status, bool *handled) | 1868 | static int adv76xx_isr(struct v4l2_subdev *sd, u32 status, bool *handled) |
1863 | { | 1869 | { |
1864 | struct adv7604_state *state = to_state(sd); | 1870 | struct adv76xx_state *state = to_state(sd); |
1865 | const struct adv7604_chip_info *info = state->info; | 1871 | const struct adv76xx_chip_info *info = state->info; |
1866 | const u8 irq_reg_0x43 = io_read(sd, 0x43); | 1872 | const u8 irq_reg_0x43 = io_read(sd, 0x43); |
1867 | const u8 irq_reg_0x6b = io_read(sd, 0x6b); | 1873 | const u8 irq_reg_0x6b = io_read(sd, 0x6b); |
1868 | const u8 irq_reg_0x70 = io_read(sd, 0x70); | 1874 | const u8 irq_reg_0x70 = io_read(sd, 0x70); |
@@ -1890,7 +1896,7 @@ static int adv7604_isr(struct v4l2_subdev *sd, u32 status, bool *handled) | |||
1890 | "%s: fmt_change = 0x%x, fmt_change_digital = 0x%x\n", | 1896 | "%s: fmt_change = 0x%x, fmt_change_digital = 0x%x\n", |
1891 | __func__, fmt_change, fmt_change_digital); | 1897 | __func__, fmt_change, fmt_change_digital); |
1892 | 1898 | ||
1893 | v4l2_subdev_notify(sd, ADV7604_FMT_CHANGE, NULL); | 1899 | v4l2_subdev_notify(sd, ADV76XX_FMT_CHANGE, NULL); |
1894 | 1900 | ||
1895 | if (handled) | 1901 | if (handled) |
1896 | *handled = true; | 1902 | *handled = true; |
@@ -1909,22 +1915,22 @@ static int adv7604_isr(struct v4l2_subdev *sd, u32 status, bool *handled) | |||
1909 | if (tx_5v) { | 1915 | if (tx_5v) { |
1910 | v4l2_dbg(1, debug, sd, "%s: tx_5v: 0x%x\n", __func__, tx_5v); | 1916 | v4l2_dbg(1, debug, sd, "%s: tx_5v: 0x%x\n", __func__, tx_5v); |
1911 | io_write(sd, 0x71, tx_5v); | 1917 | io_write(sd, 0x71, tx_5v); |
1912 | adv7604_s_detect_tx_5v_ctrl(sd); | 1918 | adv76xx_s_detect_tx_5v_ctrl(sd); |
1913 | if (handled) | 1919 | if (handled) |
1914 | *handled = true; | 1920 | *handled = true; |
1915 | } | 1921 | } |
1916 | return 0; | 1922 | return 0; |
1917 | } | 1923 | } |
1918 | 1924 | ||
1919 | static int adv7604_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) | 1925 | static int adv76xx_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) |
1920 | { | 1926 | { |
1921 | struct adv7604_state *state = to_state(sd); | 1927 | struct adv76xx_state *state = to_state(sd); |
1922 | u8 *data = NULL; | 1928 | u8 *data = NULL; |
1923 | 1929 | ||
1924 | memset(edid->reserved, 0, sizeof(edid->reserved)); | 1930 | memset(edid->reserved, 0, sizeof(edid->reserved)); |
1925 | 1931 | ||
1926 | switch (edid->pad) { | 1932 | switch (edid->pad) { |
1927 | case ADV7604_PAD_HDMI_PORT_A: | 1933 | case ADV76XX_PAD_HDMI_PORT_A: |
1928 | case ADV7604_PAD_HDMI_PORT_B: | 1934 | case ADV7604_PAD_HDMI_PORT_B: |
1929 | case ADV7604_PAD_HDMI_PORT_C: | 1935 | case ADV7604_PAD_HDMI_PORT_C: |
1930 | case ADV7604_PAD_HDMI_PORT_D: | 1936 | case ADV7604_PAD_HDMI_PORT_D: |
@@ -1982,10 +1988,10 @@ static int get_edid_spa_location(const u8 *edid) | |||
1982 | return -1; | 1988 | return -1; |
1983 | } | 1989 | } |
1984 | 1990 | ||
1985 | static int adv7604_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) | 1991 | static int adv76xx_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) |
1986 | { | 1992 | { |
1987 | struct adv7604_state *state = to_state(sd); | 1993 | struct adv76xx_state *state = to_state(sd); |
1988 | const struct adv7604_chip_info *info = state->info; | 1994 | const struct adv76xx_chip_info *info = state->info; |
1989 | int spa_loc; | 1995 | int spa_loc; |
1990 | int err; | 1996 | int err; |
1991 | int i; | 1997 | int i; |
@@ -1999,7 +2005,7 @@ static int adv7604_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) | |||
1999 | if (edid->blocks == 0) { | 2005 | if (edid->blocks == 0) { |
2000 | /* Disable hotplug and I2C access to EDID RAM from DDC port */ | 2006 | /* Disable hotplug and I2C access to EDID RAM from DDC port */ |
2001 | state->edid.present &= ~(1 << edid->pad); | 2007 | state->edid.present &= ~(1 << edid->pad); |
2002 | adv7604_set_hpd(state, state->edid.present); | 2008 | adv76xx_set_hpd(state, state->edid.present); |
2003 | rep_write_clr_set(sd, info->edid_enable_reg, 0x0f, state->edid.present); | 2009 | rep_write_clr_set(sd, info->edid_enable_reg, 0x0f, state->edid.present); |
2004 | 2010 | ||
2005 | /* Fall back to a 16:9 aspect ratio */ | 2011 | /* Fall back to a 16:9 aspect ratio */ |
@@ -2023,7 +2029,7 @@ static int adv7604_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) | |||
2023 | 2029 | ||
2024 | /* Disable hotplug and I2C access to EDID RAM from DDC port */ | 2030 | /* Disable hotplug and I2C access to EDID RAM from DDC port */ |
2025 | cancel_delayed_work_sync(&state->delayed_work_enable_hotplug); | 2031 | cancel_delayed_work_sync(&state->delayed_work_enable_hotplug); |
2026 | adv7604_set_hpd(state, 0); | 2032 | adv76xx_set_hpd(state, 0); |
2027 | rep_write_clr_set(sd, info->edid_enable_reg, 0x0f, 0x00); | 2033 | rep_write_clr_set(sd, info->edid_enable_reg, 0x0f, 0x00); |
2028 | 2034 | ||
2029 | spa_loc = get_edid_spa_location(edid->edid); | 2035 | spa_loc = get_edid_spa_location(edid->edid); |
@@ -2031,7 +2037,7 @@ static int adv7604_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) | |||
2031 | spa_loc = 0xc0; /* Default value [REF_02, p. 116] */ | 2037 | spa_loc = 0xc0; /* Default value [REF_02, p. 116] */ |
2032 | 2038 | ||
2033 | switch (edid->pad) { | 2039 | switch (edid->pad) { |
2034 | case ADV7604_PAD_HDMI_PORT_A: | 2040 | case ADV76XX_PAD_HDMI_PORT_A: |
2035 | state->spa_port_a[0] = edid->edid[spa_loc]; | 2041 | state->spa_port_a[0] = edid->edid[spa_loc]; |
2036 | state->spa_port_a[1] = edid->edid[spa_loc + 1]; | 2042 | state->spa_port_a[1] = edid->edid[spa_loc + 1]; |
2037 | break; | 2043 | break; |
@@ -2074,7 +2080,7 @@ static int adv7604_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) | |||
2074 | return err; | 2080 | return err; |
2075 | } | 2081 | } |
2076 | 2082 | ||
2077 | /* adv7604 calculates the checksums and enables I2C access to internal | 2083 | /* adv76xx calculates the checksums and enables I2C access to internal |
2078 | EDID RAM from DDC port. */ | 2084 | EDID RAM from DDC port. */ |
2079 | rep_write_clr_set(sd, info->edid_enable_reg, 0x0f, state->edid.present); | 2085 | rep_write_clr_set(sd, info->edid_enable_reg, 0x0f, state->edid.present); |
2080 | 2086 | ||
@@ -2138,10 +2144,10 @@ static void print_avi_infoframe(struct v4l2_subdev *sd) | |||
2138 | buf[8], buf[9], buf[10], buf[11], buf[12], buf[13]); | 2144 | buf[8], buf[9], buf[10], buf[11], buf[12], buf[13]); |
2139 | } | 2145 | } |
2140 | 2146 | ||
2141 | static int adv7604_log_status(struct v4l2_subdev *sd) | 2147 | static int adv76xx_log_status(struct v4l2_subdev *sd) |
2142 | { | 2148 | { |
2143 | struct adv7604_state *state = to_state(sd); | 2149 | struct adv76xx_state *state = to_state(sd); |
2144 | const struct adv7604_chip_info *info = state->info; | 2150 | const struct adv76xx_chip_info *info = state->info; |
2145 | struct v4l2_dv_timings timings; | 2151 | struct v4l2_dv_timings timings; |
2146 | struct stdi_readback stdi; | 2152 | struct stdi_readback stdi; |
2147 | u8 reg_io_0x02 = io_read(sd, 0x02); | 2153 | u8 reg_io_0x02 = io_read(sd, 0x02); |
@@ -2200,7 +2206,7 @@ static int adv7604_log_status(struct v4l2_subdev *sd) | |||
2200 | v4l2_info(sd, "STDI locked: %s\n", no_lock_stdi(sd) ? "false" : "true"); | 2206 | v4l2_info(sd, "STDI locked: %s\n", no_lock_stdi(sd) ? "false" : "true"); |
2201 | v4l2_info(sd, "CP locked: %s\n", no_lock_cp(sd) ? "false" : "true"); | 2207 | v4l2_info(sd, "CP locked: %s\n", no_lock_cp(sd) ? "false" : "true"); |
2202 | v4l2_info(sd, "CP free run: %s\n", | 2208 | v4l2_info(sd, "CP free run: %s\n", |
2203 | (!!(cp_read(sd, 0xff) & 0x10) ? "on" : "off")); | 2209 | (in_free_run(sd)) ? "on" : "off"); |
2204 | v4l2_info(sd, "Prim-mode = 0x%x, video std = 0x%x, v_freq = 0x%x\n", | 2210 | v4l2_info(sd, "Prim-mode = 0x%x, video std = 0x%x, v_freq = 0x%x\n", |
2205 | io_read(sd, 0x01) & 0x0f, io_read(sd, 0x00) & 0x3f, | 2211 | io_read(sd, 0x01) & 0x0f, io_read(sd, 0x00) & 0x3f, |
2206 | (io_read(sd, 0x01) & 0x70) >> 4); | 2212 | (io_read(sd, 0x01) & 0x70) >> 4); |
@@ -2213,7 +2219,7 @@ static int adv7604_log_status(struct v4l2_subdev *sd) | |||
2213 | stdi.lcf, stdi.bl, stdi.lcvs, | 2219 | stdi.lcf, stdi.bl, stdi.lcvs, |
2214 | stdi.interlaced ? "interlaced" : "progressive", | 2220 | stdi.interlaced ? "interlaced" : "progressive", |
2215 | stdi.hs_pol, stdi.vs_pol); | 2221 | stdi.hs_pol, stdi.vs_pol); |
2216 | if (adv7604_query_dv_timings(sd, &timings)) | 2222 | if (adv76xx_query_dv_timings(sd, &timings)) |
2217 | v4l2_info(sd, "No video detected\n"); | 2223 | v4l2_info(sd, "No video detected\n"); |
2218 | else | 2224 | else |
2219 | v4l2_print_dv_timings(sd->name, "Detected format: ", | 2225 | v4l2_print_dv_timings(sd->name, "Detected format: ", |
@@ -2235,7 +2241,7 @@ static int adv7604_log_status(struct v4l2_subdev *sd) | |||
2235 | ((reg_io_0x02 & 0x04) ^ (reg_io_0x02 & 0x01)) ? | 2241 | ((reg_io_0x02 & 0x04) ^ (reg_io_0x02 & 0x01)) ? |
2236 | "enabled" : "disabled"); | 2242 | "enabled" : "disabled"); |
2237 | v4l2_info(sd, "Color space conversion: %s\n", | 2243 | v4l2_info(sd, "Color space conversion: %s\n", |
2238 | csc_coeff_sel_rb[cp_read(sd, 0xfc) >> 4]); | 2244 | csc_coeff_sel_rb[cp_read(sd, info->cp_csc) >> 4]); |
2239 | 2245 | ||
2240 | if (!is_digital_input(sd)) | 2246 | if (!is_digital_input(sd)) |
2241 | return 0; | 2247 | return 0; |
@@ -2279,47 +2285,47 @@ static int adv7604_log_status(struct v4l2_subdev *sd) | |||
2279 | 2285 | ||
2280 | /* ----------------------------------------------------------------------- */ | 2286 | /* ----------------------------------------------------------------------- */ |
2281 | 2287 | ||
2282 | static const struct v4l2_ctrl_ops adv7604_ctrl_ops = { | 2288 | static const struct v4l2_ctrl_ops adv76xx_ctrl_ops = { |
2283 | .s_ctrl = adv7604_s_ctrl, | 2289 | .s_ctrl = adv76xx_s_ctrl, |
2284 | }; | 2290 | }; |
2285 | 2291 | ||
2286 | static const struct v4l2_subdev_core_ops adv7604_core_ops = { | 2292 | static const struct v4l2_subdev_core_ops adv76xx_core_ops = { |
2287 | .log_status = adv7604_log_status, | 2293 | .log_status = adv76xx_log_status, |
2288 | .interrupt_service_routine = adv7604_isr, | 2294 | .interrupt_service_routine = adv76xx_isr, |
2289 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 2295 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
2290 | .g_register = adv7604_g_register, | 2296 | .g_register = adv76xx_g_register, |
2291 | .s_register = adv7604_s_register, | 2297 | .s_register = adv76xx_s_register, |
2292 | #endif | 2298 | #endif |
2293 | }; | 2299 | }; |
2294 | 2300 | ||
2295 | static const struct v4l2_subdev_video_ops adv7604_video_ops = { | 2301 | static const struct v4l2_subdev_video_ops adv76xx_video_ops = { |
2296 | .s_routing = adv7604_s_routing, | 2302 | .s_routing = adv76xx_s_routing, |
2297 | .g_input_status = adv7604_g_input_status, | 2303 | .g_input_status = adv76xx_g_input_status, |
2298 | .s_dv_timings = adv7604_s_dv_timings, | 2304 | .s_dv_timings = adv76xx_s_dv_timings, |
2299 | .g_dv_timings = adv7604_g_dv_timings, | 2305 | .g_dv_timings = adv76xx_g_dv_timings, |
2300 | .query_dv_timings = adv7604_query_dv_timings, | 2306 | .query_dv_timings = adv76xx_query_dv_timings, |
2301 | }; | 2307 | }; |
2302 | 2308 | ||
2303 | static const struct v4l2_subdev_pad_ops adv7604_pad_ops = { | 2309 | static const struct v4l2_subdev_pad_ops adv76xx_pad_ops = { |
2304 | .enum_mbus_code = adv7604_enum_mbus_code, | 2310 | .enum_mbus_code = adv76xx_enum_mbus_code, |
2305 | .get_fmt = adv7604_get_format, | 2311 | .get_fmt = adv76xx_get_format, |
2306 | .set_fmt = adv7604_set_format, | 2312 | .set_fmt = adv76xx_set_format, |
2307 | .get_edid = adv7604_get_edid, | 2313 | .get_edid = adv76xx_get_edid, |
2308 | .set_edid = adv7604_set_edid, | 2314 | .set_edid = adv76xx_set_edid, |
2309 | .dv_timings_cap = adv7604_dv_timings_cap, | 2315 | .dv_timings_cap = adv76xx_dv_timings_cap, |
2310 | .enum_dv_timings = adv7604_enum_dv_timings, | 2316 | .enum_dv_timings = adv76xx_enum_dv_timings, |
2311 | }; | 2317 | }; |
2312 | 2318 | ||
2313 | static const struct v4l2_subdev_ops adv7604_ops = { | 2319 | static const struct v4l2_subdev_ops adv76xx_ops = { |
2314 | .core = &adv7604_core_ops, | 2320 | .core = &adv76xx_core_ops, |
2315 | .video = &adv7604_video_ops, | 2321 | .video = &adv76xx_video_ops, |
2316 | .pad = &adv7604_pad_ops, | 2322 | .pad = &adv76xx_pad_ops, |
2317 | }; | 2323 | }; |
2318 | 2324 | ||
2319 | /* -------------------------- custom ctrls ---------------------------------- */ | 2325 | /* -------------------------- custom ctrls ---------------------------------- */ |
2320 | 2326 | ||
2321 | static const struct v4l2_ctrl_config adv7604_ctrl_analog_sampling_phase = { | 2327 | static const struct v4l2_ctrl_config adv7604_ctrl_analog_sampling_phase = { |
2322 | .ops = &adv7604_ctrl_ops, | 2328 | .ops = &adv76xx_ctrl_ops, |
2323 | .id = V4L2_CID_ADV_RX_ANALOG_SAMPLING_PHASE, | 2329 | .id = V4L2_CID_ADV_RX_ANALOG_SAMPLING_PHASE, |
2324 | .name = "Analog Sampling Phase", | 2330 | .name = "Analog Sampling Phase", |
2325 | .type = V4L2_CTRL_TYPE_INTEGER, | 2331 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -2329,8 +2335,8 @@ static const struct v4l2_ctrl_config adv7604_ctrl_analog_sampling_phase = { | |||
2329 | .def = 0, | 2335 | .def = 0, |
2330 | }; | 2336 | }; |
2331 | 2337 | ||
2332 | static const struct v4l2_ctrl_config adv7604_ctrl_free_run_color_manual = { | 2338 | static const struct v4l2_ctrl_config adv76xx_ctrl_free_run_color_manual = { |
2333 | .ops = &adv7604_ctrl_ops, | 2339 | .ops = &adv76xx_ctrl_ops, |
2334 | .id = V4L2_CID_ADV_RX_FREE_RUN_COLOR_MANUAL, | 2340 | .id = V4L2_CID_ADV_RX_FREE_RUN_COLOR_MANUAL, |
2335 | .name = "Free Running Color, Manual", | 2341 | .name = "Free Running Color, Manual", |
2336 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 2342 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -2340,8 +2346,8 @@ static const struct v4l2_ctrl_config adv7604_ctrl_free_run_color_manual = { | |||
2340 | .def = false, | 2346 | .def = false, |
2341 | }; | 2347 | }; |
2342 | 2348 | ||
2343 | static const struct v4l2_ctrl_config adv7604_ctrl_free_run_color = { | 2349 | static const struct v4l2_ctrl_config adv76xx_ctrl_free_run_color = { |
2344 | .ops = &adv7604_ctrl_ops, | 2350 | .ops = &adv76xx_ctrl_ops, |
2345 | .id = V4L2_CID_ADV_RX_FREE_RUN_COLOR, | 2351 | .id = V4L2_CID_ADV_RX_FREE_RUN_COLOR, |
2346 | .name = "Free Running Color", | 2352 | .name = "Free Running Color", |
2347 | .type = V4L2_CTRL_TYPE_INTEGER, | 2353 | .type = V4L2_CTRL_TYPE_INTEGER, |
@@ -2353,11 +2359,11 @@ static const struct v4l2_ctrl_config adv7604_ctrl_free_run_color = { | |||
2353 | 2359 | ||
2354 | /* ----------------------------------------------------------------------- */ | 2360 | /* ----------------------------------------------------------------------- */ |
2355 | 2361 | ||
2356 | static int adv7604_core_init(struct v4l2_subdev *sd) | 2362 | static int adv76xx_core_init(struct v4l2_subdev *sd) |
2357 | { | 2363 | { |
2358 | struct adv7604_state *state = to_state(sd); | 2364 | struct adv76xx_state *state = to_state(sd); |
2359 | const struct adv7604_chip_info *info = state->info; | 2365 | const struct adv76xx_chip_info *info = state->info; |
2360 | struct adv7604_platform_data *pdata = &state->pdata; | 2366 | struct adv76xx_platform_data *pdata = &state->pdata; |
2361 | 2367 | ||
2362 | hdmi_write(sd, 0x48, | 2368 | hdmi_write(sd, 0x48, |
2363 | (pdata->disable_pwrdnb ? 0x80 : 0) | | 2369 | (pdata->disable_pwrdnb ? 0x80 : 0) | |
@@ -2385,7 +2391,7 @@ static int adv7604_core_init(struct v4l2_subdev *sd) | |||
2385 | io_write_clr_set(sd, 0x05, 0x0e, pdata->blank_data << 3 | | 2391 | io_write_clr_set(sd, 0x05, 0x0e, pdata->blank_data << 3 | |
2386 | pdata->insert_av_codes << 2 | | 2392 | pdata->insert_av_codes << 2 | |
2387 | pdata->replicate_av_codes << 1); | 2393 | pdata->replicate_av_codes << 1); |
2388 | adv7604_setup_format(state); | 2394 | adv76xx_setup_format(state); |
2389 | 2395 | ||
2390 | cp_write(sd, 0x69, 0x30); /* Enable CP CSC */ | 2396 | cp_write(sd, 0x69, 0x30); /* Enable CP CSC */ |
2391 | 2397 | ||
@@ -2415,7 +2421,7 @@ static int adv7604_core_init(struct v4l2_subdev *sd) | |||
2415 | /* TODO from platform data */ | 2421 | /* TODO from platform data */ |
2416 | afe_write(sd, 0xb5, 0x01); /* Setting MCLK to 256Fs */ | 2422 | afe_write(sd, 0xb5, 0x01); /* Setting MCLK to 256Fs */ |
2417 | 2423 | ||
2418 | if (adv7604_has_afe(state)) { | 2424 | if (adv76xx_has_afe(state)) { |
2419 | afe_write(sd, 0x02, pdata->ain_sel); /* Select analog input muxing mode */ | 2425 | afe_write(sd, 0x02, pdata->ain_sel); /* Select analog input muxing mode */ |
2420 | io_write_clr_set(sd, 0x30, 1 << 4, pdata->output_bus_lsb_to_msb << 4); | 2426 | io_write_clr_set(sd, 0x30, 1 << 4, pdata->output_bus_lsb_to_msb << 4); |
2421 | } | 2427 | } |
@@ -2440,7 +2446,7 @@ static void adv7611_setup_irqs(struct v4l2_subdev *sd) | |||
2440 | io_write(sd, 0x41, 0xd0); /* STDI irq for any change, disable INT2 */ | 2446 | io_write(sd, 0x41, 0xd0); /* STDI irq for any change, disable INT2 */ |
2441 | } | 2447 | } |
2442 | 2448 | ||
2443 | static void adv7604_unregister_clients(struct adv7604_state *state) | 2449 | static void adv76xx_unregister_clients(struct adv76xx_state *state) |
2444 | { | 2450 | { |
2445 | unsigned int i; | 2451 | unsigned int i; |
2446 | 2452 | ||
@@ -2450,7 +2456,7 @@ static void adv7604_unregister_clients(struct adv7604_state *state) | |||
2450 | } | 2456 | } |
2451 | } | 2457 | } |
2452 | 2458 | ||
2453 | static struct i2c_client *adv7604_dummy_client(struct v4l2_subdev *sd, | 2459 | static struct i2c_client *adv76xx_dummy_client(struct v4l2_subdev *sd, |
2454 | u8 addr, u8 io_reg) | 2460 | u8 addr, u8 io_reg) |
2455 | { | 2461 | { |
2456 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 2462 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
@@ -2460,74 +2466,74 @@ static struct i2c_client *adv7604_dummy_client(struct v4l2_subdev *sd, | |||
2460 | return i2c_new_dummy(client->adapter, io_read(sd, io_reg) >> 1); | 2466 | return i2c_new_dummy(client->adapter, io_read(sd, io_reg) >> 1); |
2461 | } | 2467 | } |
2462 | 2468 | ||
2463 | static const struct adv7604_reg_seq adv7604_recommended_settings_afe[] = { | 2469 | static const struct adv76xx_reg_seq adv7604_recommended_settings_afe[] = { |
2464 | /* reset ADI recommended settings for HDMI: */ | 2470 | /* reset ADI recommended settings for HDMI: */ |
2465 | /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 4. */ | 2471 | /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 4. */ |
2466 | { ADV7604_REG(ADV7604_PAGE_HDMI, 0x0d), 0x04 }, /* HDMI filter optimization */ | 2472 | { ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x0d), 0x04 }, /* HDMI filter optimization */ |
2467 | { ADV7604_REG(ADV7604_PAGE_HDMI, 0x0d), 0x04 }, /* HDMI filter optimization */ | 2473 | { ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x0d), 0x04 }, /* HDMI filter optimization */ |
2468 | { ADV7604_REG(ADV7604_PAGE_HDMI, 0x3d), 0x00 }, /* DDC bus active pull-up control */ | 2474 | { ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x3d), 0x00 }, /* DDC bus active pull-up control */ |
2469 | { ADV7604_REG(ADV7604_PAGE_HDMI, 0x3e), 0x74 }, /* TMDS PLL optimization */ | 2475 | { ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x3e), 0x74 }, /* TMDS PLL optimization */ |
2470 | { ADV7604_REG(ADV7604_PAGE_HDMI, 0x4e), 0x3b }, /* TMDS PLL optimization */ | 2476 | { ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x4e), 0x3b }, /* TMDS PLL optimization */ |
2471 | { ADV7604_REG(ADV7604_PAGE_HDMI, 0x57), 0x74 }, /* TMDS PLL optimization */ | 2477 | { ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x57), 0x74 }, /* TMDS PLL optimization */ |
2472 | { ADV7604_REG(ADV7604_PAGE_HDMI, 0x58), 0x63 }, /* TMDS PLL optimization */ | 2478 | { ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x58), 0x63 }, /* TMDS PLL optimization */ |
2473 | { ADV7604_REG(ADV7604_PAGE_HDMI, 0x8d), 0x18 }, /* equaliser */ | 2479 | { ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x8d), 0x18 }, /* equaliser */ |
2474 | { ADV7604_REG(ADV7604_PAGE_HDMI, 0x8e), 0x34 }, /* equaliser */ | 2480 | { ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x8e), 0x34 }, /* equaliser */ |
2475 | { ADV7604_REG(ADV7604_PAGE_HDMI, 0x93), 0x88 }, /* equaliser */ | 2481 | { ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x93), 0x88 }, /* equaliser */ |
2476 | { ADV7604_REG(ADV7604_PAGE_HDMI, 0x94), 0x2e }, /* equaliser */ | 2482 | { ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x94), 0x2e }, /* equaliser */ |
2477 | { ADV7604_REG(ADV7604_PAGE_HDMI, 0x96), 0x00 }, /* enable automatic EQ changing */ | 2483 | { ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x96), 0x00 }, /* enable automatic EQ changing */ |
2478 | 2484 | ||
2479 | /* set ADI recommended settings for digitizer */ | 2485 | /* set ADI recommended settings for digitizer */ |
2480 | /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 17. */ | 2486 | /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 17. */ |
2481 | { ADV7604_REG(ADV7604_PAGE_AFE, 0x12), 0x7b }, /* ADC noise shaping filter controls */ | 2487 | { ADV76XX_REG(ADV76XX_PAGE_AFE, 0x12), 0x7b }, /* ADC noise shaping filter controls */ |
2482 | { ADV7604_REG(ADV7604_PAGE_AFE, 0x0c), 0x1f }, /* CP core gain controls */ | 2488 | { ADV76XX_REG(ADV76XX_PAGE_AFE, 0x0c), 0x1f }, /* CP core gain controls */ |
2483 | { ADV7604_REG(ADV7604_PAGE_CP, 0x3e), 0x04 }, /* CP core pre-gain control */ | 2489 | { ADV76XX_REG(ADV76XX_PAGE_CP, 0x3e), 0x04 }, /* CP core pre-gain control */ |
2484 | { ADV7604_REG(ADV7604_PAGE_CP, 0xc3), 0x39 }, /* CP coast control. Graphics mode */ | 2490 | { ADV76XX_REG(ADV76XX_PAGE_CP, 0xc3), 0x39 }, /* CP coast control. Graphics mode */ |
2485 | { ADV7604_REG(ADV7604_PAGE_CP, 0x40), 0x5c }, /* CP core pre-gain control. Graphics mode */ | 2491 | { ADV76XX_REG(ADV76XX_PAGE_CP, 0x40), 0x5c }, /* CP core pre-gain control. Graphics mode */ |
2486 | 2492 | ||
2487 | { ADV7604_REG_SEQ_TERM, 0 }, | 2493 | { ADV76XX_REG_SEQ_TERM, 0 }, |
2488 | }; | 2494 | }; |
2489 | 2495 | ||
2490 | static const struct adv7604_reg_seq adv7604_recommended_settings_hdmi[] = { | 2496 | static const struct adv76xx_reg_seq adv7604_recommended_settings_hdmi[] = { |
2491 | /* set ADI recommended settings for HDMI: */ | 2497 | /* set ADI recommended settings for HDMI: */ |
2492 | /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 4. */ | 2498 | /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 4. */ |
2493 | { ADV7604_REG(ADV7604_PAGE_HDMI, 0x0d), 0x84 }, /* HDMI filter optimization */ | 2499 | { ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x0d), 0x84 }, /* HDMI filter optimization */ |
2494 | { ADV7604_REG(ADV7604_PAGE_HDMI, 0x3d), 0x10 }, /* DDC bus active pull-up control */ | 2500 | { ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x3d), 0x10 }, /* DDC bus active pull-up control */ |
2495 | { ADV7604_REG(ADV7604_PAGE_HDMI, 0x3e), 0x39 }, /* TMDS PLL optimization */ | 2501 | { ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x3e), 0x39 }, /* TMDS PLL optimization */ |
2496 | { ADV7604_REG(ADV7604_PAGE_HDMI, 0x4e), 0x3b }, /* TMDS PLL optimization */ | 2502 | { ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x4e), 0x3b }, /* TMDS PLL optimization */ |
2497 | { ADV7604_REG(ADV7604_PAGE_HDMI, 0x57), 0xb6 }, /* TMDS PLL optimization */ | 2503 | { ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x57), 0xb6 }, /* TMDS PLL optimization */ |
2498 | { ADV7604_REG(ADV7604_PAGE_HDMI, 0x58), 0x03 }, /* TMDS PLL optimization */ | 2504 | { ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x58), 0x03 }, /* TMDS PLL optimization */ |
2499 | { ADV7604_REG(ADV7604_PAGE_HDMI, 0x8d), 0x18 }, /* equaliser */ | 2505 | { ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x8d), 0x18 }, /* equaliser */ |
2500 | { ADV7604_REG(ADV7604_PAGE_HDMI, 0x8e), 0x34 }, /* equaliser */ | 2506 | { ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x8e), 0x34 }, /* equaliser */ |
2501 | { ADV7604_REG(ADV7604_PAGE_HDMI, 0x93), 0x8b }, /* equaliser */ | 2507 | { ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x93), 0x8b }, /* equaliser */ |
2502 | { ADV7604_REG(ADV7604_PAGE_HDMI, 0x94), 0x2d }, /* equaliser */ | 2508 | { ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x94), 0x2d }, /* equaliser */ |
2503 | { ADV7604_REG(ADV7604_PAGE_HDMI, 0x96), 0x01 }, /* enable automatic EQ changing */ | 2509 | { ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x96), 0x01 }, /* enable automatic EQ changing */ |
2504 | 2510 | ||
2505 | /* reset ADI recommended settings for digitizer */ | 2511 | /* reset ADI recommended settings for digitizer */ |
2506 | /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 17. */ | 2512 | /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 17. */ |
2507 | { ADV7604_REG(ADV7604_PAGE_AFE, 0x12), 0xfb }, /* ADC noise shaping filter controls */ | 2513 | { ADV76XX_REG(ADV76XX_PAGE_AFE, 0x12), 0xfb }, /* ADC noise shaping filter controls */ |
2508 | { ADV7604_REG(ADV7604_PAGE_AFE, 0x0c), 0x0d }, /* CP core gain controls */ | 2514 | { ADV76XX_REG(ADV76XX_PAGE_AFE, 0x0c), 0x0d }, /* CP core gain controls */ |
2509 | 2515 | ||
2510 | { ADV7604_REG_SEQ_TERM, 0 }, | 2516 | { ADV76XX_REG_SEQ_TERM, 0 }, |
2511 | }; | 2517 | }; |
2512 | 2518 | ||
2513 | static const struct adv7604_reg_seq adv7611_recommended_settings_hdmi[] = { | 2519 | static const struct adv76xx_reg_seq adv7611_recommended_settings_hdmi[] = { |
2514 | /* ADV7611 Register Settings Recommendations Rev 1.5, May 2014 */ | 2520 | /* ADV7611 Register Settings Recommendations Rev 1.5, May 2014 */ |
2515 | { ADV7604_REG(ADV7604_PAGE_CP, 0x6c), 0x00 }, | 2521 | { ADV76XX_REG(ADV76XX_PAGE_CP, 0x6c), 0x00 }, |
2516 | { ADV7604_REG(ADV7604_PAGE_HDMI, 0x9b), 0x03 }, | 2522 | { ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x9b), 0x03 }, |
2517 | { ADV7604_REG(ADV7604_PAGE_HDMI, 0x6f), 0x08 }, | 2523 | { ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x6f), 0x08 }, |
2518 | { ADV7604_REG(ADV7604_PAGE_HDMI, 0x85), 0x1f }, | 2524 | { ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x85), 0x1f }, |
2519 | { ADV7604_REG(ADV7604_PAGE_HDMI, 0x87), 0x70 }, | 2525 | { ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x87), 0x70 }, |
2520 | { ADV7604_REG(ADV7604_PAGE_HDMI, 0x57), 0xda }, | 2526 | { ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x57), 0xda }, |
2521 | { ADV7604_REG(ADV7604_PAGE_HDMI, 0x58), 0x01 }, | 2527 | { ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x58), 0x01 }, |
2522 | { ADV7604_REG(ADV7604_PAGE_HDMI, 0x03), 0x98 }, | 2528 | { ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x03), 0x98 }, |
2523 | { ADV7604_REG(ADV7604_PAGE_HDMI, 0x4c), 0x44 }, | 2529 | { ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x4c), 0x44 }, |
2524 | { ADV7604_REG(ADV7604_PAGE_HDMI, 0x8d), 0x04 }, | 2530 | { ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x8d), 0x04 }, |
2525 | { ADV7604_REG(ADV7604_PAGE_HDMI, 0x8e), 0x1e }, | 2531 | { ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x8e), 0x1e }, |
2526 | 2532 | ||
2527 | { ADV7604_REG_SEQ_TERM, 0 }, | 2533 | { ADV76XX_REG_SEQ_TERM, 0 }, |
2528 | }; | 2534 | }; |
2529 | 2535 | ||
2530 | static const struct adv7604_chip_info adv7604_chip_info[] = { | 2536 | static const struct adv76xx_chip_info adv76xx_chip_info[] = { |
2531 | [ADV7604] = { | 2537 | [ADV7604] = { |
2532 | .type = ADV7604, | 2538 | .type = ADV7604, |
2533 | .has_afe = true, | 2539 | .has_afe = true, |
@@ -2539,6 +2545,7 @@ static const struct adv7604_chip_info adv7604_chip_info[] = { | |||
2539 | .tdms_lock_mask = 0xe0, | 2545 | .tdms_lock_mask = 0xe0, |
2540 | .cable_det_mask = 0x1e, | 2546 | .cable_det_mask = 0x1e, |
2541 | .fmt_change_digital_mask = 0xc1, | 2547 | .fmt_change_digital_mask = 0xc1, |
2548 | .cp_csc = 0xfc, | ||
2542 | .formats = adv7604_formats, | 2549 | .formats = adv7604_formats, |
2543 | .nformats = ARRAY_SIZE(adv7604_formats), | 2550 | .nformats = ARRAY_SIZE(adv7604_formats), |
2544 | .set_termination = adv7604_set_termination, | 2551 | .set_termination = adv7604_set_termination, |
@@ -2553,18 +2560,18 @@ static const struct adv7604_chip_info adv7604_chip_info[] = { | |||
2553 | [0] = ARRAY_SIZE(adv7604_recommended_settings_afe), | 2560 | [0] = ARRAY_SIZE(adv7604_recommended_settings_afe), |
2554 | [1] = ARRAY_SIZE(adv7604_recommended_settings_hdmi), | 2561 | [1] = ARRAY_SIZE(adv7604_recommended_settings_hdmi), |
2555 | }, | 2562 | }, |
2556 | .page_mask = BIT(ADV7604_PAGE_IO) | BIT(ADV7604_PAGE_AVLINK) | | 2563 | .page_mask = BIT(ADV76XX_PAGE_IO) | BIT(ADV7604_PAGE_AVLINK) | |
2557 | BIT(ADV7604_PAGE_CEC) | BIT(ADV7604_PAGE_INFOFRAME) | | 2564 | BIT(ADV76XX_PAGE_CEC) | BIT(ADV76XX_PAGE_INFOFRAME) | |
2558 | BIT(ADV7604_PAGE_ESDP) | BIT(ADV7604_PAGE_DPP) | | 2565 | BIT(ADV7604_PAGE_ESDP) | BIT(ADV7604_PAGE_DPP) | |
2559 | BIT(ADV7604_PAGE_AFE) | BIT(ADV7604_PAGE_REP) | | 2566 | BIT(ADV76XX_PAGE_AFE) | BIT(ADV76XX_PAGE_REP) | |
2560 | BIT(ADV7604_PAGE_EDID) | BIT(ADV7604_PAGE_HDMI) | | 2567 | BIT(ADV76XX_PAGE_EDID) | BIT(ADV76XX_PAGE_HDMI) | |
2561 | BIT(ADV7604_PAGE_TEST) | BIT(ADV7604_PAGE_CP) | | 2568 | BIT(ADV76XX_PAGE_TEST) | BIT(ADV76XX_PAGE_CP) | |
2562 | BIT(ADV7604_PAGE_VDP), | 2569 | BIT(ADV7604_PAGE_VDP), |
2563 | }, | 2570 | }, |
2564 | [ADV7611] = { | 2571 | [ADV7611] = { |
2565 | .type = ADV7611, | 2572 | .type = ADV7611, |
2566 | .has_afe = false, | 2573 | .has_afe = false, |
2567 | .max_port = ADV7604_PAD_HDMI_PORT_A, | 2574 | .max_port = ADV76XX_PAD_HDMI_PORT_A, |
2568 | .num_dv_ports = 1, | 2575 | .num_dv_ports = 1, |
2569 | .edid_enable_reg = 0x74, | 2576 | .edid_enable_reg = 0x74, |
2570 | .edid_status_reg = 0x76, | 2577 | .edid_status_reg = 0x76, |
@@ -2572,6 +2579,7 @@ static const struct adv7604_chip_info adv7604_chip_info[] = { | |||
2572 | .tdms_lock_mask = 0x43, | 2579 | .tdms_lock_mask = 0x43, |
2573 | .cable_det_mask = 0x01, | 2580 | .cable_det_mask = 0x01, |
2574 | .fmt_change_digital_mask = 0x03, | 2581 | .fmt_change_digital_mask = 0x03, |
2582 | .cp_csc = 0xf4, | ||
2575 | .formats = adv7611_formats, | 2583 | .formats = adv7611_formats, |
2576 | .nformats = ARRAY_SIZE(adv7611_formats), | 2584 | .nformats = ARRAY_SIZE(adv7611_formats), |
2577 | .set_termination = adv7611_set_termination, | 2585 | .set_termination = adv7611_set_termination, |
@@ -2584,34 +2592,34 @@ static const struct adv7604_chip_info adv7604_chip_info[] = { | |||
2584 | .num_recommended_settings = { | 2592 | .num_recommended_settings = { |
2585 | [1] = ARRAY_SIZE(adv7611_recommended_settings_hdmi), | 2593 | [1] = ARRAY_SIZE(adv7611_recommended_settings_hdmi), |
2586 | }, | 2594 | }, |
2587 | .page_mask = BIT(ADV7604_PAGE_IO) | BIT(ADV7604_PAGE_CEC) | | 2595 | .page_mask = BIT(ADV76XX_PAGE_IO) | BIT(ADV76XX_PAGE_CEC) | |
2588 | BIT(ADV7604_PAGE_INFOFRAME) | BIT(ADV7604_PAGE_AFE) | | 2596 | BIT(ADV76XX_PAGE_INFOFRAME) | BIT(ADV76XX_PAGE_AFE) | |
2589 | BIT(ADV7604_PAGE_REP) | BIT(ADV7604_PAGE_EDID) | | 2597 | BIT(ADV76XX_PAGE_REP) | BIT(ADV76XX_PAGE_EDID) | |
2590 | BIT(ADV7604_PAGE_HDMI) | BIT(ADV7604_PAGE_CP), | 2598 | BIT(ADV76XX_PAGE_HDMI) | BIT(ADV76XX_PAGE_CP), |
2591 | }, | 2599 | }, |
2592 | }; | 2600 | }; |
2593 | 2601 | ||
2594 | static struct i2c_device_id adv7604_i2c_id[] = { | 2602 | static struct i2c_device_id adv76xx_i2c_id[] = { |
2595 | { "adv7604", (kernel_ulong_t)&adv7604_chip_info[ADV7604] }, | 2603 | { "adv7604", (kernel_ulong_t)&adv76xx_chip_info[ADV7604] }, |
2596 | { "adv7611", (kernel_ulong_t)&adv7604_chip_info[ADV7611] }, | 2604 | { "adv7611", (kernel_ulong_t)&adv76xx_chip_info[ADV7611] }, |
2597 | { } | 2605 | { } |
2598 | }; | 2606 | }; |
2599 | MODULE_DEVICE_TABLE(i2c, adv7604_i2c_id); | 2607 | MODULE_DEVICE_TABLE(i2c, adv76xx_i2c_id); |
2600 | 2608 | ||
2601 | static struct of_device_id adv7604_of_id[] __maybe_unused = { | 2609 | static struct of_device_id adv76xx_of_id[] __maybe_unused = { |
2602 | { .compatible = "adi,adv7611", .data = &adv7604_chip_info[ADV7611] }, | 2610 | { .compatible = "adi,adv7611", .data = &adv76xx_chip_info[ADV7611] }, |
2603 | { } | 2611 | { } |
2604 | }; | 2612 | }; |
2605 | MODULE_DEVICE_TABLE(of, adv7604_of_id); | 2613 | MODULE_DEVICE_TABLE(of, adv76xx_of_id); |
2606 | 2614 | ||
2607 | static int adv7604_parse_dt(struct adv7604_state *state) | 2615 | static int adv76xx_parse_dt(struct adv76xx_state *state) |
2608 | { | 2616 | { |
2609 | struct v4l2_of_endpoint bus_cfg; | 2617 | struct v4l2_of_endpoint bus_cfg; |
2610 | struct device_node *endpoint; | 2618 | struct device_node *endpoint; |
2611 | struct device_node *np; | 2619 | struct device_node *np; |
2612 | unsigned int flags; | 2620 | unsigned int flags; |
2613 | 2621 | ||
2614 | np = state->i2c_clients[ADV7604_PAGE_IO]->dev.of_node; | 2622 | np = state->i2c_clients[ADV76XX_PAGE_IO]->dev.of_node; |
2615 | 2623 | ||
2616 | /* Parse the endpoint. */ | 2624 | /* Parse the endpoint. */ |
2617 | endpoint = of_graph_get_next_endpoint(np, NULL); | 2625 | endpoint = of_graph_get_next_endpoint(np, NULL); |
@@ -2638,20 +2646,20 @@ static int adv7604_parse_dt(struct adv7604_state *state) | |||
2638 | } | 2646 | } |
2639 | 2647 | ||
2640 | /* Disable the interrupt for now as no DT-based board uses it. */ | 2648 | /* Disable the interrupt for now as no DT-based board uses it. */ |
2641 | state->pdata.int1_config = ADV7604_INT1_CONFIG_DISABLED; | 2649 | state->pdata.int1_config = ADV76XX_INT1_CONFIG_DISABLED; |
2642 | 2650 | ||
2643 | /* Use the default I2C addresses. */ | 2651 | /* Use the default I2C addresses. */ |
2644 | state->pdata.i2c_addresses[ADV7604_PAGE_AVLINK] = 0x42; | 2652 | state->pdata.i2c_addresses[ADV7604_PAGE_AVLINK] = 0x42; |
2645 | state->pdata.i2c_addresses[ADV7604_PAGE_CEC] = 0x40; | 2653 | state->pdata.i2c_addresses[ADV76XX_PAGE_CEC] = 0x40; |
2646 | state->pdata.i2c_addresses[ADV7604_PAGE_INFOFRAME] = 0x3e; | 2654 | state->pdata.i2c_addresses[ADV76XX_PAGE_INFOFRAME] = 0x3e; |
2647 | state->pdata.i2c_addresses[ADV7604_PAGE_ESDP] = 0x38; | 2655 | state->pdata.i2c_addresses[ADV7604_PAGE_ESDP] = 0x38; |
2648 | state->pdata.i2c_addresses[ADV7604_PAGE_DPP] = 0x3c; | 2656 | state->pdata.i2c_addresses[ADV7604_PAGE_DPP] = 0x3c; |
2649 | state->pdata.i2c_addresses[ADV7604_PAGE_AFE] = 0x26; | 2657 | state->pdata.i2c_addresses[ADV76XX_PAGE_AFE] = 0x26; |
2650 | state->pdata.i2c_addresses[ADV7604_PAGE_REP] = 0x32; | 2658 | state->pdata.i2c_addresses[ADV76XX_PAGE_REP] = 0x32; |
2651 | state->pdata.i2c_addresses[ADV7604_PAGE_EDID] = 0x36; | 2659 | state->pdata.i2c_addresses[ADV76XX_PAGE_EDID] = 0x36; |
2652 | state->pdata.i2c_addresses[ADV7604_PAGE_HDMI] = 0x34; | 2660 | state->pdata.i2c_addresses[ADV76XX_PAGE_HDMI] = 0x34; |
2653 | state->pdata.i2c_addresses[ADV7604_PAGE_TEST] = 0x30; | 2661 | state->pdata.i2c_addresses[ADV76XX_PAGE_TEST] = 0x30; |
2654 | state->pdata.i2c_addresses[ADV7604_PAGE_CP] = 0x22; | 2662 | state->pdata.i2c_addresses[ADV76XX_PAGE_CP] = 0x22; |
2655 | state->pdata.i2c_addresses[ADV7604_PAGE_VDP] = 0x24; | 2663 | state->pdata.i2c_addresses[ADV7604_PAGE_VDP] = 0x24; |
2656 | 2664 | ||
2657 | /* Hardcode the remaining platform data fields. */ | 2665 | /* Hardcode the remaining platform data fields. */ |
@@ -2666,12 +2674,12 @@ static int adv7604_parse_dt(struct adv7604_state *state) | |||
2666 | return 0; | 2674 | return 0; |
2667 | } | 2675 | } |
2668 | 2676 | ||
2669 | static int adv7604_probe(struct i2c_client *client, | 2677 | static int adv76xx_probe(struct i2c_client *client, |
2670 | const struct i2c_device_id *id) | 2678 | const struct i2c_device_id *id) |
2671 | { | 2679 | { |
2672 | static const struct v4l2_dv_timings cea640x480 = | 2680 | static const struct v4l2_dv_timings cea640x480 = |
2673 | V4L2_DV_BT_CEA_640X480P59_94; | 2681 | V4L2_DV_BT_CEA_640X480P59_94; |
2674 | struct adv7604_state *state; | 2682 | struct adv76xx_state *state; |
2675 | struct v4l2_ctrl_handler *hdl; | 2683 | struct v4l2_ctrl_handler *hdl; |
2676 | struct v4l2_subdev *sd; | 2684 | struct v4l2_subdev *sd; |
2677 | unsigned int i; | 2685 | unsigned int i; |
@@ -2681,16 +2689,16 @@ static int adv7604_probe(struct i2c_client *client, | |||
2681 | /* Check if the adapter supports the needed features */ | 2689 | /* Check if the adapter supports the needed features */ |
2682 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 2690 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
2683 | return -EIO; | 2691 | return -EIO; |
2684 | v4l_dbg(1, debug, client, "detecting adv7604 client on address 0x%x\n", | 2692 | v4l_dbg(1, debug, client, "detecting adv76xx client on address 0x%x\n", |
2685 | client->addr << 1); | 2693 | client->addr << 1); |
2686 | 2694 | ||
2687 | state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL); | 2695 | state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL); |
2688 | if (!state) { | 2696 | if (!state) { |
2689 | v4l_err(client, "Could not allocate adv7604_state memory!\n"); | 2697 | v4l_err(client, "Could not allocate adv76xx_state memory!\n"); |
2690 | return -ENOMEM; | 2698 | return -ENOMEM; |
2691 | } | 2699 | } |
2692 | 2700 | ||
2693 | state->i2c_clients[ADV7604_PAGE_IO] = client; | 2701 | state->i2c_clients[ADV76XX_PAGE_IO] = client; |
2694 | 2702 | ||
2695 | /* initialize variables */ | 2703 | /* initialize variables */ |
2696 | state->restart_stdi_once = true; | 2704 | state->restart_stdi_once = true; |
@@ -2699,18 +2707,18 @@ static int adv7604_probe(struct i2c_client *client, | |||
2699 | if (IS_ENABLED(CONFIG_OF) && client->dev.of_node) { | 2707 | if (IS_ENABLED(CONFIG_OF) && client->dev.of_node) { |
2700 | const struct of_device_id *oid; | 2708 | const struct of_device_id *oid; |
2701 | 2709 | ||
2702 | oid = of_match_node(adv7604_of_id, client->dev.of_node); | 2710 | oid = of_match_node(adv76xx_of_id, client->dev.of_node); |
2703 | state->info = oid->data; | 2711 | state->info = oid->data; |
2704 | 2712 | ||
2705 | err = adv7604_parse_dt(state); | 2713 | err = adv76xx_parse_dt(state); |
2706 | if (err < 0) { | 2714 | if (err < 0) { |
2707 | v4l_err(client, "DT parsing error\n"); | 2715 | v4l_err(client, "DT parsing error\n"); |
2708 | return err; | 2716 | return err; |
2709 | } | 2717 | } |
2710 | } else if (client->dev.platform_data) { | 2718 | } else if (client->dev.platform_data) { |
2711 | struct adv7604_platform_data *pdata = client->dev.platform_data; | 2719 | struct adv76xx_platform_data *pdata = client->dev.platform_data; |
2712 | 2720 | ||
2713 | state->info = (const struct adv7604_chip_info *)id->driver_data; | 2721 | state->info = (const struct adv76xx_chip_info *)id->driver_data; |
2714 | state->pdata = *pdata; | 2722 | state->pdata = *pdata; |
2715 | } else { | 2723 | } else { |
2716 | v4l_err(client, "No platform data!\n"); | 2724 | v4l_err(client, "No platform data!\n"); |
@@ -2720,20 +2728,20 @@ static int adv7604_probe(struct i2c_client *client, | |||
2720 | /* Request GPIOs. */ | 2728 | /* Request GPIOs. */ |
2721 | for (i = 0; i < state->info->num_dv_ports; ++i) { | 2729 | for (i = 0; i < state->info->num_dv_ports; ++i) { |
2722 | state->hpd_gpio[i] = | 2730 | state->hpd_gpio[i] = |
2723 | devm_gpiod_get_index(&client->dev, "hpd", i); | 2731 | devm_gpiod_get_index_optional(&client->dev, "hpd", i, |
2732 | GPIOD_OUT_LOW); | ||
2724 | if (IS_ERR(state->hpd_gpio[i])) | 2733 | if (IS_ERR(state->hpd_gpio[i])) |
2725 | continue; | 2734 | return PTR_ERR(state->hpd_gpio[i]); |
2726 | |||
2727 | gpiod_direction_output(state->hpd_gpio[i], 0); | ||
2728 | 2735 | ||
2729 | v4l_info(client, "Handling HPD %u GPIO\n", i); | 2736 | if (state->hpd_gpio[i]) |
2737 | v4l_info(client, "Handling HPD %u GPIO\n", i); | ||
2730 | } | 2738 | } |
2731 | 2739 | ||
2732 | state->timings = cea640x480; | 2740 | state->timings = cea640x480; |
2733 | state->format = adv7604_format_info(state, MEDIA_BUS_FMT_YUYV8_2X8); | 2741 | state->format = adv76xx_format_info(state, MEDIA_BUS_FMT_YUYV8_2X8); |
2734 | 2742 | ||
2735 | sd = &state->sd; | 2743 | sd = &state->sd; |
2736 | v4l2_i2c_subdev_init(sd, client, &adv7604_ops); | 2744 | v4l2_i2c_subdev_init(sd, client, &adv76xx_ops); |
2737 | snprintf(sd->name, sizeof(sd->name), "%s %d-%04x", | 2745 | snprintf(sd->name, sizeof(sd->name), "%s %d-%04x", |
2738 | id->name, i2c_adapter_id(client->adapter), | 2746 | id->name, i2c_adapter_id(client->adapter), |
2739 | client->addr); | 2747 | client->addr); |
@@ -2763,15 +2771,15 @@ static int adv7604_probe(struct i2c_client *client, | |||
2763 | 2771 | ||
2764 | /* control handlers */ | 2772 | /* control handlers */ |
2765 | hdl = &state->hdl; | 2773 | hdl = &state->hdl; |
2766 | v4l2_ctrl_handler_init(hdl, adv7604_has_afe(state) ? 9 : 8); | 2774 | v4l2_ctrl_handler_init(hdl, adv76xx_has_afe(state) ? 9 : 8); |
2767 | 2775 | ||
2768 | v4l2_ctrl_new_std(hdl, &adv7604_ctrl_ops, | 2776 | v4l2_ctrl_new_std(hdl, &adv76xx_ctrl_ops, |
2769 | V4L2_CID_BRIGHTNESS, -128, 127, 1, 0); | 2777 | V4L2_CID_BRIGHTNESS, -128, 127, 1, 0); |
2770 | v4l2_ctrl_new_std(hdl, &adv7604_ctrl_ops, | 2778 | v4l2_ctrl_new_std(hdl, &adv76xx_ctrl_ops, |
2771 | V4L2_CID_CONTRAST, 0, 255, 1, 128); | 2779 | V4L2_CID_CONTRAST, 0, 255, 1, 128); |
2772 | v4l2_ctrl_new_std(hdl, &adv7604_ctrl_ops, | 2780 | v4l2_ctrl_new_std(hdl, &adv76xx_ctrl_ops, |
2773 | V4L2_CID_SATURATION, 0, 255, 1, 128); | 2781 | V4L2_CID_SATURATION, 0, 255, 1, 128); |
2774 | v4l2_ctrl_new_std(hdl, &adv7604_ctrl_ops, | 2782 | v4l2_ctrl_new_std(hdl, &adv76xx_ctrl_ops, |
2775 | V4L2_CID_HUE, 0, 128, 1, 0); | 2783 | V4L2_CID_HUE, 0, 128, 1, 0); |
2776 | 2784 | ||
2777 | /* private controls */ | 2785 | /* private controls */ |
@@ -2779,18 +2787,18 @@ static int adv7604_probe(struct i2c_client *client, | |||
2779 | V4L2_CID_DV_RX_POWER_PRESENT, 0, | 2787 | V4L2_CID_DV_RX_POWER_PRESENT, 0, |
2780 | (1 << state->info->num_dv_ports) - 1, 0, 0); | 2788 | (1 << state->info->num_dv_ports) - 1, 0, 0); |
2781 | state->rgb_quantization_range_ctrl = | 2789 | state->rgb_quantization_range_ctrl = |
2782 | v4l2_ctrl_new_std_menu(hdl, &adv7604_ctrl_ops, | 2790 | v4l2_ctrl_new_std_menu(hdl, &adv76xx_ctrl_ops, |
2783 | V4L2_CID_DV_RX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL, | 2791 | V4L2_CID_DV_RX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL, |
2784 | 0, V4L2_DV_RGB_RANGE_AUTO); | 2792 | 0, V4L2_DV_RGB_RANGE_AUTO); |
2785 | 2793 | ||
2786 | /* custom controls */ | 2794 | /* custom controls */ |
2787 | if (adv7604_has_afe(state)) | 2795 | if (adv76xx_has_afe(state)) |
2788 | state->analog_sampling_phase_ctrl = | 2796 | state->analog_sampling_phase_ctrl = |
2789 | v4l2_ctrl_new_custom(hdl, &adv7604_ctrl_analog_sampling_phase, NULL); | 2797 | v4l2_ctrl_new_custom(hdl, &adv7604_ctrl_analog_sampling_phase, NULL); |
2790 | state->free_run_color_manual_ctrl = | 2798 | state->free_run_color_manual_ctrl = |
2791 | v4l2_ctrl_new_custom(hdl, &adv7604_ctrl_free_run_color_manual, NULL); | 2799 | v4l2_ctrl_new_custom(hdl, &adv76xx_ctrl_free_run_color_manual, NULL); |
2792 | state->free_run_color_ctrl = | 2800 | state->free_run_color_ctrl = |
2793 | v4l2_ctrl_new_custom(hdl, &adv7604_ctrl_free_run_color, NULL); | 2801 | v4l2_ctrl_new_custom(hdl, &adv76xx_ctrl_free_run_color, NULL); |
2794 | 2802 | ||
2795 | sd->ctrl_handler = hdl; | 2803 | sd->ctrl_handler = hdl; |
2796 | if (hdl->error) { | 2804 | if (hdl->error) { |
@@ -2799,22 +2807,22 @@ static int adv7604_probe(struct i2c_client *client, | |||
2799 | } | 2807 | } |
2800 | state->detect_tx_5v_ctrl->is_private = true; | 2808 | state->detect_tx_5v_ctrl->is_private = true; |
2801 | state->rgb_quantization_range_ctrl->is_private = true; | 2809 | state->rgb_quantization_range_ctrl->is_private = true; |
2802 | if (adv7604_has_afe(state)) | 2810 | if (adv76xx_has_afe(state)) |
2803 | state->analog_sampling_phase_ctrl->is_private = true; | 2811 | state->analog_sampling_phase_ctrl->is_private = true; |
2804 | state->free_run_color_manual_ctrl->is_private = true; | 2812 | state->free_run_color_manual_ctrl->is_private = true; |
2805 | state->free_run_color_ctrl->is_private = true; | 2813 | state->free_run_color_ctrl->is_private = true; |
2806 | 2814 | ||
2807 | if (adv7604_s_detect_tx_5v_ctrl(sd)) { | 2815 | if (adv76xx_s_detect_tx_5v_ctrl(sd)) { |
2808 | err = -ENODEV; | 2816 | err = -ENODEV; |
2809 | goto err_hdl; | 2817 | goto err_hdl; |
2810 | } | 2818 | } |
2811 | 2819 | ||
2812 | for (i = 1; i < ADV7604_PAGE_MAX; ++i) { | 2820 | for (i = 1; i < ADV76XX_PAGE_MAX; ++i) { |
2813 | if (!(BIT(i) & state->info->page_mask)) | 2821 | if (!(BIT(i) & state->info->page_mask)) |
2814 | continue; | 2822 | continue; |
2815 | 2823 | ||
2816 | state->i2c_clients[i] = | 2824 | state->i2c_clients[i] = |
2817 | adv7604_dummy_client(sd, state->pdata.i2c_addresses[i], | 2825 | adv76xx_dummy_client(sd, state->pdata.i2c_addresses[i], |
2818 | 0xf2 + i); | 2826 | 0xf2 + i); |
2819 | if (state->i2c_clients[i] == NULL) { | 2827 | if (state->i2c_clients[i] == NULL) { |
2820 | err = -ENOMEM; | 2828 | err = -ENOMEM; |
@@ -2832,7 +2840,7 @@ static int adv7604_probe(struct i2c_client *client, | |||
2832 | } | 2840 | } |
2833 | 2841 | ||
2834 | INIT_DELAYED_WORK(&state->delayed_work_enable_hotplug, | 2842 | INIT_DELAYED_WORK(&state->delayed_work_enable_hotplug, |
2835 | adv7604_delayed_work_enable_hotplug); | 2843 | adv76xx_delayed_work_enable_hotplug); |
2836 | 2844 | ||
2837 | state->source_pad = state->info->num_dv_ports | 2845 | state->source_pad = state->info->num_dv_ports |
2838 | + (state->info->has_afe ? 2 : 0); | 2846 | + (state->info->has_afe ? 2 : 0); |
@@ -2845,7 +2853,7 @@ static int adv7604_probe(struct i2c_client *client, | |||
2845 | if (err) | 2853 | if (err) |
2846 | goto err_work_queues; | 2854 | goto err_work_queues; |
2847 | 2855 | ||
2848 | err = adv7604_core_init(sd); | 2856 | err = adv76xx_core_init(sd); |
2849 | if (err) | 2857 | if (err) |
2850 | goto err_entity; | 2858 | goto err_entity; |
2851 | v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name, | 2859 | v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name, |
@@ -2863,7 +2871,7 @@ err_work_queues: | |||
2863 | cancel_delayed_work(&state->delayed_work_enable_hotplug); | 2871 | cancel_delayed_work(&state->delayed_work_enable_hotplug); |
2864 | destroy_workqueue(state->work_queues); | 2872 | destroy_workqueue(state->work_queues); |
2865 | err_i2c: | 2873 | err_i2c: |
2866 | adv7604_unregister_clients(state); | 2874 | adv76xx_unregister_clients(state); |
2867 | err_hdl: | 2875 | err_hdl: |
2868 | v4l2_ctrl_handler_free(hdl); | 2876 | v4l2_ctrl_handler_free(hdl); |
2869 | return err; | 2877 | return err; |
@@ -2871,32 +2879,31 @@ err_hdl: | |||
2871 | 2879 | ||
2872 | /* ----------------------------------------------------------------------- */ | 2880 | /* ----------------------------------------------------------------------- */ |
2873 | 2881 | ||
2874 | static int adv7604_remove(struct i2c_client *client) | 2882 | static int adv76xx_remove(struct i2c_client *client) |
2875 | { | 2883 | { |
2876 | struct v4l2_subdev *sd = i2c_get_clientdata(client); | 2884 | struct v4l2_subdev *sd = i2c_get_clientdata(client); |
2877 | struct adv7604_state *state = to_state(sd); | 2885 | struct adv76xx_state *state = to_state(sd); |
2878 | 2886 | ||
2879 | cancel_delayed_work(&state->delayed_work_enable_hotplug); | 2887 | cancel_delayed_work(&state->delayed_work_enable_hotplug); |
2880 | destroy_workqueue(state->work_queues); | 2888 | destroy_workqueue(state->work_queues); |
2881 | v4l2_async_unregister_subdev(sd); | 2889 | v4l2_async_unregister_subdev(sd); |
2882 | v4l2_device_unregister_subdev(sd); | ||
2883 | media_entity_cleanup(&sd->entity); | 2890 | media_entity_cleanup(&sd->entity); |
2884 | adv7604_unregister_clients(to_state(sd)); | 2891 | adv76xx_unregister_clients(to_state(sd)); |
2885 | v4l2_ctrl_handler_free(sd->ctrl_handler); | 2892 | v4l2_ctrl_handler_free(sd->ctrl_handler); |
2886 | return 0; | 2893 | return 0; |
2887 | } | 2894 | } |
2888 | 2895 | ||
2889 | /* ----------------------------------------------------------------------- */ | 2896 | /* ----------------------------------------------------------------------- */ |
2890 | 2897 | ||
2891 | static struct i2c_driver adv7604_driver = { | 2898 | static struct i2c_driver adv76xx_driver = { |
2892 | .driver = { | 2899 | .driver = { |
2893 | .owner = THIS_MODULE, | 2900 | .owner = THIS_MODULE, |
2894 | .name = "adv7604", | 2901 | .name = "adv7604", |
2895 | .of_match_table = of_match_ptr(adv7604_of_id), | 2902 | .of_match_table = of_match_ptr(adv76xx_of_id), |
2896 | }, | 2903 | }, |
2897 | .probe = adv7604_probe, | 2904 | .probe = adv76xx_probe, |
2898 | .remove = adv7604_remove, | 2905 | .remove = adv76xx_remove, |
2899 | .id_table = adv7604_i2c_id, | 2906 | .id_table = adv76xx_i2c_id, |
2900 | }; | 2907 | }; |
2901 | 2908 | ||
2902 | module_i2c_driver(adv7604_driver); | 2909 | module_i2c_driver(adv76xx_driver); |
diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c index 7c215ee142c4..b5a37fe10a6a 100644 --- a/drivers/media/i2c/adv7842.c +++ b/drivers/media/i2c/adv7842.c | |||
@@ -1119,7 +1119,7 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd) | |||
1119 | /* Receiving DVI-D signal | 1119 | /* Receiving DVI-D signal |
1120 | * ADV7842 selects RGB limited range regardless of | 1120 | * ADV7842 selects RGB limited range regardless of |
1121 | * input format (CE/IT) in automatic mode */ | 1121 | * input format (CE/IT) in automatic mode */ |
1122 | if (state->timings.bt.standards & V4L2_DV_BT_STD_CEA861) { | 1122 | if (state->timings.bt.flags & V4L2_DV_FL_IS_CE_VIDEO) { |
1123 | /* RGB limited range (16-235) */ | 1123 | /* RGB limited range (16-235) */ |
1124 | io_write_and_or(sd, 0x02, 0x0f, 0x00); | 1124 | io_write_and_or(sd, 0x02, 0x0f, 0x00); |
1125 | } else { | 1125 | } else { |
@@ -1901,7 +1901,8 @@ static int adv7842_g_mbus_fmt(struct v4l2_subdev *sd, | |||
1901 | return 0; | 1901 | return 0; |
1902 | } | 1902 | } |
1903 | 1903 | ||
1904 | if (state->timings.bt.standards & V4L2_DV_BT_STD_CEA861) { | 1904 | fmt->colorspace = V4L2_COLORSPACE_SRGB; |
1905 | if (state->timings.bt.flags & V4L2_DV_FL_IS_CE_VIDEO) { | ||
1905 | fmt->colorspace = (state->timings.bt.height <= 576) ? | 1906 | fmt->colorspace = (state->timings.bt.height <= 576) ? |
1906 | V4L2_COLORSPACE_SMPTE170M : V4L2_COLORSPACE_REC709; | 1907 | V4L2_COLORSPACE_SMPTE170M : V4L2_COLORSPACE_REC709; |
1907 | } | 1908 | } |
diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c index 573e08826b9b..bd496447749a 100644 --- a/drivers/media/i2c/cx25840/cx25840-core.c +++ b/drivers/media/i2c/cx25840/cx25840-core.c | |||
@@ -5137,6 +5137,9 @@ static int cx25840_probe(struct i2c_client *client, | |||
5137 | int default_volume; | 5137 | int default_volume; |
5138 | u32 id; | 5138 | u32 id; |
5139 | u16 device_id; | 5139 | u16 device_id; |
5140 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
5141 | int ret; | ||
5142 | #endif | ||
5140 | 5143 | ||
5141 | /* Check if the adapter supports the needed features */ | 5144 | /* Check if the adapter supports the needed features */ |
5142 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 5145 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
@@ -5178,6 +5181,33 @@ static int cx25840_probe(struct i2c_client *client, | |||
5178 | 5181 | ||
5179 | sd = &state->sd; | 5182 | sd = &state->sd; |
5180 | v4l2_i2c_subdev_init(sd, client, &cx25840_ops); | 5183 | v4l2_i2c_subdev_init(sd, client, &cx25840_ops); |
5184 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
5185 | /* | ||
5186 | * TODO: add media controller support for analog video inputs like | ||
5187 | * composite, svideo, etc. | ||
5188 | * A real input pad for this analog demod would be like: | ||
5189 | * ___________ | ||
5190 | * TUNER --------> | | | ||
5191 | * | | | ||
5192 | * SVIDEO .......> | cx25840 | | ||
5193 | * | | | ||
5194 | * COMPOSITE1 ...> |_________| | ||
5195 | * | ||
5196 | * However, at least for now, there's no much gain on modelling | ||
5197 | * those extra inputs. So, let's add it only when needed. | ||
5198 | */ | ||
5199 | state->pads[CX25840_PAD_INPUT].flags = MEDIA_PAD_FL_SINK; | ||
5200 | state->pads[CX25840_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE; | ||
5201 | state->pads[CX25840_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE; | ||
5202 | sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_DECODER; | ||
5203 | |||
5204 | ret = media_entity_init(&sd->entity, ARRAY_SIZE(state->pads), | ||
5205 | state->pads, 0); | ||
5206 | if (ret < 0) { | ||
5207 | v4l_info(client, "failed to initialize media entity!\n"); | ||
5208 | return ret; | ||
5209 | } | ||
5210 | #endif | ||
5181 | 5211 | ||
5182 | switch (id) { | 5212 | switch (id) { |
5183 | case CX23885_AV: | 5213 | case CX23885_AV: |
diff --git a/drivers/media/i2c/cx25840/cx25840-core.h b/drivers/media/i2c/cx25840/cx25840-core.h index 37bc04217c44..fdea48ce0c03 100644 --- a/drivers/media/i2c/cx25840/cx25840-core.h +++ b/drivers/media/i2c/cx25840/cx25840-core.h | |||
@@ -41,6 +41,14 @@ enum cx25840_model { | |||
41 | CX25837, | 41 | CX25837, |
42 | }; | 42 | }; |
43 | 43 | ||
44 | enum cx25840_media_pads { | ||
45 | CX25840_PAD_INPUT, | ||
46 | CX25840_PAD_VID_OUT, | ||
47 | CX25840_PAD_VBI_OUT, | ||
48 | |||
49 | CX25840_NUM_PADS | ||
50 | }; | ||
51 | |||
44 | struct cx25840_state { | 52 | struct cx25840_state { |
45 | struct i2c_client *c; | 53 | struct i2c_client *c; |
46 | struct v4l2_subdev sd; | 54 | struct v4l2_subdev sd; |
@@ -64,6 +72,9 @@ struct cx25840_state { | |||
64 | wait_queue_head_t fw_wait; /* wake up when the fw load is finished */ | 72 | wait_queue_head_t fw_wait; /* wake up when the fw load is finished */ |
65 | struct work_struct fw_work; /* work entry for fw load */ | 73 | struct work_struct fw_work; /* work entry for fw load */ |
66 | struct cx25840_ir_state *ir_state; | 74 | struct cx25840_ir_state *ir_state; |
75 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
76 | struct media_pad pads[CX25840_NUM_PADS]; | ||
77 | #endif | ||
67 | }; | 78 | }; |
68 | 79 | ||
69 | static inline struct cx25840_state *to_state(struct v4l2_subdev *sd) | 80 | static inline struct cx25840_state *to_state(struct v4l2_subdev *sd) |
diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c index 6ed16e569bbf..6404c0d93e7a 100644 --- a/drivers/media/i2c/m5mols/m5mols_core.c +++ b/drivers/media/i2c/m5mols/m5mols_core.c | |||
@@ -531,17 +531,17 @@ static int __find_resolution(struct v4l2_subdev *sd, | |||
531 | } | 531 | } |
532 | 532 | ||
533 | static struct v4l2_mbus_framefmt *__find_format(struct m5mols_info *info, | 533 | static struct v4l2_mbus_framefmt *__find_format(struct m5mols_info *info, |
534 | struct v4l2_subdev_fh *fh, | 534 | struct v4l2_subdev_pad_config *cfg, |
535 | enum v4l2_subdev_format_whence which, | 535 | enum v4l2_subdev_format_whence which, |
536 | enum m5mols_restype type) | 536 | enum m5mols_restype type) |
537 | { | 537 | { |
538 | if (which == V4L2_SUBDEV_FORMAT_TRY) | 538 | if (which == V4L2_SUBDEV_FORMAT_TRY) |
539 | return fh ? v4l2_subdev_get_try_format(fh, 0) : NULL; | 539 | return cfg ? v4l2_subdev_get_try_format(&info->sd, cfg, 0) : NULL; |
540 | 540 | ||
541 | return &info->ffmt[type]; | 541 | return &info->ffmt[type]; |
542 | } | 542 | } |
543 | 543 | ||
544 | static int m5mols_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | 544 | static int m5mols_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, |
545 | struct v4l2_subdev_format *fmt) | 545 | struct v4l2_subdev_format *fmt) |
546 | { | 546 | { |
547 | struct m5mols_info *info = to_m5mols(sd); | 547 | struct m5mols_info *info = to_m5mols(sd); |
@@ -550,7 +550,7 @@ static int m5mols_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
550 | 550 | ||
551 | mutex_lock(&info->lock); | 551 | mutex_lock(&info->lock); |
552 | 552 | ||
553 | format = __find_format(info, fh, fmt->which, info->res_type); | 553 | format = __find_format(info, cfg, fmt->which, info->res_type); |
554 | if (format) | 554 | if (format) |
555 | fmt->format = *format; | 555 | fmt->format = *format; |
556 | else | 556 | else |
@@ -560,7 +560,7 @@ static int m5mols_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
560 | return ret; | 560 | return ret; |
561 | } | 561 | } |
562 | 562 | ||
563 | static int m5mols_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | 563 | static int m5mols_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, |
564 | struct v4l2_subdev_format *fmt) | 564 | struct v4l2_subdev_format *fmt) |
565 | { | 565 | { |
566 | struct m5mols_info *info = to_m5mols(sd); | 566 | struct m5mols_info *info = to_m5mols(sd); |
@@ -574,7 +574,7 @@ static int m5mols_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
574 | if (ret < 0) | 574 | if (ret < 0) |
575 | return ret; | 575 | return ret; |
576 | 576 | ||
577 | sfmt = __find_format(info, fh, fmt->which, type); | 577 | sfmt = __find_format(info, cfg, fmt->which, type); |
578 | if (!sfmt) | 578 | if (!sfmt) |
579 | return 0; | 579 | return 0; |
580 | 580 | ||
@@ -640,7 +640,7 @@ static int m5mols_set_frame_desc(struct v4l2_subdev *sd, unsigned int pad, | |||
640 | 640 | ||
641 | 641 | ||
642 | static int m5mols_enum_mbus_code(struct v4l2_subdev *sd, | 642 | static int m5mols_enum_mbus_code(struct v4l2_subdev *sd, |
643 | struct v4l2_subdev_fh *fh, | 643 | struct v4l2_subdev_pad_config *cfg, |
644 | struct v4l2_subdev_mbus_code_enum *code) | 644 | struct v4l2_subdev_mbus_code_enum *code) |
645 | { | 645 | { |
646 | if (!code || code->index >= SIZE_DEFAULT_FFMT) | 646 | if (!code || code->index >= SIZE_DEFAULT_FFMT) |
@@ -895,7 +895,7 @@ static const struct v4l2_subdev_core_ops m5mols_core_ops = { | |||
895 | */ | 895 | */ |
896 | static int m5mols_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) | 896 | static int m5mols_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) |
897 | { | 897 | { |
898 | struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(fh, 0); | 898 | struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(sd, fh->pad, 0); |
899 | 899 | ||
900 | *format = m5mols_default_ffmt[0]; | 900 | *format = m5mols_default_ffmt[0]; |
901 | return 0; | 901 | return 0; |
diff --git a/drivers/media/i2c/mt9m032.c b/drivers/media/i2c/mt9m032.c index 76431223f0ff..c7747bd0cabb 100644 --- a/drivers/media/i2c/mt9m032.c +++ b/drivers/media/i2c/mt9m032.c | |||
@@ -317,7 +317,7 @@ static int mt9m032_setup_pll(struct mt9m032 *sensor) | |||
317 | */ | 317 | */ |
318 | 318 | ||
319 | static int mt9m032_enum_mbus_code(struct v4l2_subdev *subdev, | 319 | static int mt9m032_enum_mbus_code(struct v4l2_subdev *subdev, |
320 | struct v4l2_subdev_fh *fh, | 320 | struct v4l2_subdev_pad_config *cfg, |
321 | struct v4l2_subdev_mbus_code_enum *code) | 321 | struct v4l2_subdev_mbus_code_enum *code) |
322 | { | 322 | { |
323 | if (code->index != 0) | 323 | if (code->index != 0) |
@@ -328,7 +328,7 @@ static int mt9m032_enum_mbus_code(struct v4l2_subdev *subdev, | |||
328 | } | 328 | } |
329 | 329 | ||
330 | static int mt9m032_enum_frame_size(struct v4l2_subdev *subdev, | 330 | static int mt9m032_enum_frame_size(struct v4l2_subdev *subdev, |
331 | struct v4l2_subdev_fh *fh, | 331 | struct v4l2_subdev_pad_config *cfg, |
332 | struct v4l2_subdev_frame_size_enum *fse) | 332 | struct v4l2_subdev_frame_size_enum *fse) |
333 | { | 333 | { |
334 | if (fse->index != 0 || fse->code != MEDIA_BUS_FMT_Y8_1X8) | 334 | if (fse->index != 0 || fse->code != MEDIA_BUS_FMT_Y8_1X8) |
@@ -345,18 +345,18 @@ static int mt9m032_enum_frame_size(struct v4l2_subdev *subdev, | |||
345 | /** | 345 | /** |
346 | * __mt9m032_get_pad_crop() - get crop rect | 346 | * __mt9m032_get_pad_crop() - get crop rect |
347 | * @sensor: pointer to the sensor struct | 347 | * @sensor: pointer to the sensor struct |
348 | * @fh: file handle for getting the try crop rect from | 348 | * @cfg: v4l2_subdev_pad_config for getting the try crop rect from |
349 | * @which: select try or active crop rect | 349 | * @which: select try or active crop rect |
350 | * | 350 | * |
351 | * Returns a pointer the current active or fh relative try crop rect | 351 | * Returns a pointer the current active or fh relative try crop rect |
352 | */ | 352 | */ |
353 | static struct v4l2_rect * | 353 | static struct v4l2_rect * |
354 | __mt9m032_get_pad_crop(struct mt9m032 *sensor, struct v4l2_subdev_fh *fh, | 354 | __mt9m032_get_pad_crop(struct mt9m032 *sensor, struct v4l2_subdev_pad_config *cfg, |
355 | enum v4l2_subdev_format_whence which) | 355 | enum v4l2_subdev_format_whence which) |
356 | { | 356 | { |
357 | switch (which) { | 357 | switch (which) { |
358 | case V4L2_SUBDEV_FORMAT_TRY: | 358 | case V4L2_SUBDEV_FORMAT_TRY: |
359 | return v4l2_subdev_get_try_crop(fh, 0); | 359 | return v4l2_subdev_get_try_crop(&sensor->subdev, cfg, 0); |
360 | case V4L2_SUBDEV_FORMAT_ACTIVE: | 360 | case V4L2_SUBDEV_FORMAT_ACTIVE: |
361 | return &sensor->crop; | 361 | return &sensor->crop; |
362 | default: | 362 | default: |
@@ -367,18 +367,18 @@ __mt9m032_get_pad_crop(struct mt9m032 *sensor, struct v4l2_subdev_fh *fh, | |||
367 | /** | 367 | /** |
368 | * __mt9m032_get_pad_format() - get format | 368 | * __mt9m032_get_pad_format() - get format |
369 | * @sensor: pointer to the sensor struct | 369 | * @sensor: pointer to the sensor struct |
370 | * @fh: file handle for getting the try format from | 370 | * @cfg: v4l2_subdev_pad_config for getting the try format from |
371 | * @which: select try or active format | 371 | * @which: select try or active format |
372 | * | 372 | * |
373 | * Returns a pointer the current active or fh relative try format | 373 | * Returns a pointer the current active or fh relative try format |
374 | */ | 374 | */ |
375 | static struct v4l2_mbus_framefmt * | 375 | static struct v4l2_mbus_framefmt * |
376 | __mt9m032_get_pad_format(struct mt9m032 *sensor, struct v4l2_subdev_fh *fh, | 376 | __mt9m032_get_pad_format(struct mt9m032 *sensor, struct v4l2_subdev_pad_config *cfg, |
377 | enum v4l2_subdev_format_whence which) | 377 | enum v4l2_subdev_format_whence which) |
378 | { | 378 | { |
379 | switch (which) { | 379 | switch (which) { |
380 | case V4L2_SUBDEV_FORMAT_TRY: | 380 | case V4L2_SUBDEV_FORMAT_TRY: |
381 | return v4l2_subdev_get_try_format(fh, 0); | 381 | return v4l2_subdev_get_try_format(&sensor->subdev, cfg, 0); |
382 | case V4L2_SUBDEV_FORMAT_ACTIVE: | 382 | case V4L2_SUBDEV_FORMAT_ACTIVE: |
383 | return &sensor->format; | 383 | return &sensor->format; |
384 | default: | 384 | default: |
@@ -387,20 +387,20 @@ __mt9m032_get_pad_format(struct mt9m032 *sensor, struct v4l2_subdev_fh *fh, | |||
387 | } | 387 | } |
388 | 388 | ||
389 | static int mt9m032_get_pad_format(struct v4l2_subdev *subdev, | 389 | static int mt9m032_get_pad_format(struct v4l2_subdev *subdev, |
390 | struct v4l2_subdev_fh *fh, | 390 | struct v4l2_subdev_pad_config *cfg, |
391 | struct v4l2_subdev_format *fmt) | 391 | struct v4l2_subdev_format *fmt) |
392 | { | 392 | { |
393 | struct mt9m032 *sensor = to_mt9m032(subdev); | 393 | struct mt9m032 *sensor = to_mt9m032(subdev); |
394 | 394 | ||
395 | mutex_lock(&sensor->lock); | 395 | mutex_lock(&sensor->lock); |
396 | fmt->format = *__mt9m032_get_pad_format(sensor, fh, fmt->which); | 396 | fmt->format = *__mt9m032_get_pad_format(sensor, cfg, fmt->which); |
397 | mutex_unlock(&sensor->lock); | 397 | mutex_unlock(&sensor->lock); |
398 | 398 | ||
399 | return 0; | 399 | return 0; |
400 | } | 400 | } |
401 | 401 | ||
402 | static int mt9m032_set_pad_format(struct v4l2_subdev *subdev, | 402 | static int mt9m032_set_pad_format(struct v4l2_subdev *subdev, |
403 | struct v4l2_subdev_fh *fh, | 403 | struct v4l2_subdev_pad_config *cfg, |
404 | struct v4l2_subdev_format *fmt) | 404 | struct v4l2_subdev_format *fmt) |
405 | { | 405 | { |
406 | struct mt9m032 *sensor = to_mt9m032(subdev); | 406 | struct mt9m032 *sensor = to_mt9m032(subdev); |
@@ -414,7 +414,7 @@ static int mt9m032_set_pad_format(struct v4l2_subdev *subdev, | |||
414 | } | 414 | } |
415 | 415 | ||
416 | /* Scaling is not supported, the format is thus fixed. */ | 416 | /* Scaling is not supported, the format is thus fixed. */ |
417 | fmt->format = *__mt9m032_get_pad_format(sensor, fh, fmt->which); | 417 | fmt->format = *__mt9m032_get_pad_format(sensor, cfg, fmt->which); |
418 | ret = 0; | 418 | ret = 0; |
419 | 419 | ||
420 | done: | 420 | done: |
@@ -423,7 +423,7 @@ done: | |||
423 | } | 423 | } |
424 | 424 | ||
425 | static int mt9m032_get_pad_selection(struct v4l2_subdev *subdev, | 425 | static int mt9m032_get_pad_selection(struct v4l2_subdev *subdev, |
426 | struct v4l2_subdev_fh *fh, | 426 | struct v4l2_subdev_pad_config *cfg, |
427 | struct v4l2_subdev_selection *sel) | 427 | struct v4l2_subdev_selection *sel) |
428 | { | 428 | { |
429 | struct mt9m032 *sensor = to_mt9m032(subdev); | 429 | struct mt9m032 *sensor = to_mt9m032(subdev); |
@@ -432,14 +432,14 @@ static int mt9m032_get_pad_selection(struct v4l2_subdev *subdev, | |||
432 | return -EINVAL; | 432 | return -EINVAL; |
433 | 433 | ||
434 | mutex_lock(&sensor->lock); | 434 | mutex_lock(&sensor->lock); |
435 | sel->r = *__mt9m032_get_pad_crop(sensor, fh, sel->which); | 435 | sel->r = *__mt9m032_get_pad_crop(sensor, cfg, sel->which); |
436 | mutex_unlock(&sensor->lock); | 436 | mutex_unlock(&sensor->lock); |
437 | 437 | ||
438 | return 0; | 438 | return 0; |
439 | } | 439 | } |
440 | 440 | ||
441 | static int mt9m032_set_pad_selection(struct v4l2_subdev *subdev, | 441 | static int mt9m032_set_pad_selection(struct v4l2_subdev *subdev, |
442 | struct v4l2_subdev_fh *fh, | 442 | struct v4l2_subdev_pad_config *cfg, |
443 | struct v4l2_subdev_selection *sel) | 443 | struct v4l2_subdev_selection *sel) |
444 | { | 444 | { |
445 | struct mt9m032 *sensor = to_mt9m032(subdev); | 445 | struct mt9m032 *sensor = to_mt9m032(subdev); |
@@ -475,13 +475,13 @@ static int mt9m032_set_pad_selection(struct v4l2_subdev *subdev, | |||
475 | rect.height = min_t(unsigned int, rect.height, | 475 | rect.height = min_t(unsigned int, rect.height, |
476 | MT9M032_PIXEL_ARRAY_HEIGHT - rect.top); | 476 | MT9M032_PIXEL_ARRAY_HEIGHT - rect.top); |
477 | 477 | ||
478 | __crop = __mt9m032_get_pad_crop(sensor, fh, sel->which); | 478 | __crop = __mt9m032_get_pad_crop(sensor, cfg, sel->which); |
479 | 479 | ||
480 | if (rect.width != __crop->width || rect.height != __crop->height) { | 480 | if (rect.width != __crop->width || rect.height != __crop->height) { |
481 | /* Reset the output image size if the crop rectangle size has | 481 | /* Reset the output image size if the crop rectangle size has |
482 | * been modified. | 482 | * been modified. |
483 | */ | 483 | */ |
484 | format = __mt9m032_get_pad_format(sensor, fh, sel->which); | 484 | format = __mt9m032_get_pad_format(sensor, cfg, sel->which); |
485 | format->width = rect.width; | 485 | format->width = rect.width; |
486 | format->height = rect.height; | 486 | format->height = rect.height; |
487 | } | 487 | } |
diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c index e3acae9a2ec3..0db15f528ac1 100644 --- a/drivers/media/i2c/mt9p031.c +++ b/drivers/media/i2c/mt9p031.c | |||
@@ -15,12 +15,11 @@ | |||
15 | #include <linux/clk.h> | 15 | #include <linux/clk.h> |
16 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
17 | #include <linux/device.h> | 17 | #include <linux/device.h> |
18 | #include <linux/gpio.h> | 18 | #include <linux/gpio/consumer.h> |
19 | #include <linux/i2c.h> | 19 | #include <linux/i2c.h> |
20 | #include <linux/log2.h> | 20 | #include <linux/log2.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/of.h> | 22 | #include <linux/of.h> |
23 | #include <linux/of_gpio.h> | ||
24 | #include <linux/of_graph.h> | 23 | #include <linux/of_graph.h> |
25 | #include <linux/pm.h> | 24 | #include <linux/pm.h> |
26 | #include <linux/regulator/consumer.h> | 25 | #include <linux/regulator/consumer.h> |
@@ -28,6 +27,7 @@ | |||
28 | #include <linux/videodev2.h> | 27 | #include <linux/videodev2.h> |
29 | 28 | ||
30 | #include <media/mt9p031.h> | 29 | #include <media/mt9p031.h> |
30 | #include <media/v4l2-async.h> | ||
31 | #include <media/v4l2-ctrls.h> | 31 | #include <media/v4l2-ctrls.h> |
32 | #include <media/v4l2-device.h> | 32 | #include <media/v4l2-device.h> |
33 | #include <media/v4l2-subdev.h> | 33 | #include <media/v4l2-subdev.h> |
@@ -135,7 +135,7 @@ struct mt9p031 { | |||
135 | struct aptina_pll pll; | 135 | struct aptina_pll pll; |
136 | unsigned int clk_div; | 136 | unsigned int clk_div; |
137 | bool use_pll; | 137 | bool use_pll; |
138 | int reset; | 138 | struct gpio_desc *reset; |
139 | 139 | ||
140 | struct v4l2_ctrl_handler ctrls; | 140 | struct v4l2_ctrl_handler ctrls; |
141 | struct v4l2_ctrl *blc_auto; | 141 | struct v4l2_ctrl *blc_auto; |
@@ -251,7 +251,7 @@ static int mt9p031_clk_setup(struct mt9p031 *mt9p031) | |||
251 | div = DIV_ROUND_UP(pdata->ext_freq, pdata->target_freq); | 251 | div = DIV_ROUND_UP(pdata->ext_freq, pdata->target_freq); |
252 | div = roundup_pow_of_two(div) / 2; | 252 | div = roundup_pow_of_two(div) / 2; |
253 | 253 | ||
254 | mt9p031->clk_div = max_t(unsigned int, div, 64); | 254 | mt9p031->clk_div = min_t(unsigned int, div, 64); |
255 | mt9p031->use_pll = false; | 255 | mt9p031->use_pll = false; |
256 | 256 | ||
257 | return 0; | 257 | return 0; |
@@ -308,9 +308,9 @@ static int mt9p031_power_on(struct mt9p031 *mt9p031) | |||
308 | { | 308 | { |
309 | int ret; | 309 | int ret; |
310 | 310 | ||
311 | /* Ensure RESET_BAR is low */ | 311 | /* Ensure RESET_BAR is active */ |
312 | if (gpio_is_valid(mt9p031->reset)) { | 312 | if (mt9p031->reset) { |
313 | gpio_set_value(mt9p031->reset, 0); | 313 | gpiod_set_value(mt9p031->reset, 1); |
314 | usleep_range(1000, 2000); | 314 | usleep_range(1000, 2000); |
315 | } | 315 | } |
316 | 316 | ||
@@ -331,8 +331,8 @@ static int mt9p031_power_on(struct mt9p031 *mt9p031) | |||
331 | } | 331 | } |
332 | 332 | ||
333 | /* Now RESET_BAR must be high */ | 333 | /* Now RESET_BAR must be high */ |
334 | if (gpio_is_valid(mt9p031->reset)) { | 334 | if (mt9p031->reset) { |
335 | gpio_set_value(mt9p031->reset, 1); | 335 | gpiod_set_value(mt9p031->reset, 0); |
336 | usleep_range(1000, 2000); | 336 | usleep_range(1000, 2000); |
337 | } | 337 | } |
338 | 338 | ||
@@ -341,8 +341,8 @@ static int mt9p031_power_on(struct mt9p031 *mt9p031) | |||
341 | 341 | ||
342 | static void mt9p031_power_off(struct mt9p031 *mt9p031) | 342 | static void mt9p031_power_off(struct mt9p031 *mt9p031) |
343 | { | 343 | { |
344 | if (gpio_is_valid(mt9p031->reset)) { | 344 | if (mt9p031->reset) { |
345 | gpio_set_value(mt9p031->reset, 0); | 345 | gpiod_set_value(mt9p031->reset, 1); |
346 | usleep_range(1000, 2000); | 346 | usleep_range(1000, 2000); |
347 | } | 347 | } |
348 | 348 | ||
@@ -474,7 +474,7 @@ static int mt9p031_s_stream(struct v4l2_subdev *subdev, int enable) | |||
474 | } | 474 | } |
475 | 475 | ||
476 | static int mt9p031_enum_mbus_code(struct v4l2_subdev *subdev, | 476 | static int mt9p031_enum_mbus_code(struct v4l2_subdev *subdev, |
477 | struct v4l2_subdev_fh *fh, | 477 | struct v4l2_subdev_pad_config *cfg, |
478 | struct v4l2_subdev_mbus_code_enum *code) | 478 | struct v4l2_subdev_mbus_code_enum *code) |
479 | { | 479 | { |
480 | struct mt9p031 *mt9p031 = to_mt9p031(subdev); | 480 | struct mt9p031 *mt9p031 = to_mt9p031(subdev); |
@@ -487,7 +487,7 @@ static int mt9p031_enum_mbus_code(struct v4l2_subdev *subdev, | |||
487 | } | 487 | } |
488 | 488 | ||
489 | static int mt9p031_enum_frame_size(struct v4l2_subdev *subdev, | 489 | static int mt9p031_enum_frame_size(struct v4l2_subdev *subdev, |
490 | struct v4l2_subdev_fh *fh, | 490 | struct v4l2_subdev_pad_config *cfg, |
491 | struct v4l2_subdev_frame_size_enum *fse) | 491 | struct v4l2_subdev_frame_size_enum *fse) |
492 | { | 492 | { |
493 | struct mt9p031 *mt9p031 = to_mt9p031(subdev); | 493 | struct mt9p031 *mt9p031 = to_mt9p031(subdev); |
@@ -505,12 +505,12 @@ static int mt9p031_enum_frame_size(struct v4l2_subdev *subdev, | |||
505 | } | 505 | } |
506 | 506 | ||
507 | static struct v4l2_mbus_framefmt * | 507 | static struct v4l2_mbus_framefmt * |
508 | __mt9p031_get_pad_format(struct mt9p031 *mt9p031, struct v4l2_subdev_fh *fh, | 508 | __mt9p031_get_pad_format(struct mt9p031 *mt9p031, struct v4l2_subdev_pad_config *cfg, |
509 | unsigned int pad, u32 which) | 509 | unsigned int pad, u32 which) |
510 | { | 510 | { |
511 | switch (which) { | 511 | switch (which) { |
512 | case V4L2_SUBDEV_FORMAT_TRY: | 512 | case V4L2_SUBDEV_FORMAT_TRY: |
513 | return v4l2_subdev_get_try_format(fh, pad); | 513 | return v4l2_subdev_get_try_format(&mt9p031->subdev, cfg, pad); |
514 | case V4L2_SUBDEV_FORMAT_ACTIVE: | 514 | case V4L2_SUBDEV_FORMAT_ACTIVE: |
515 | return &mt9p031->format; | 515 | return &mt9p031->format; |
516 | default: | 516 | default: |
@@ -519,12 +519,12 @@ __mt9p031_get_pad_format(struct mt9p031 *mt9p031, struct v4l2_subdev_fh *fh, | |||
519 | } | 519 | } |
520 | 520 | ||
521 | static struct v4l2_rect * | 521 | static struct v4l2_rect * |
522 | __mt9p031_get_pad_crop(struct mt9p031 *mt9p031, struct v4l2_subdev_fh *fh, | 522 | __mt9p031_get_pad_crop(struct mt9p031 *mt9p031, struct v4l2_subdev_pad_config *cfg, |
523 | unsigned int pad, u32 which) | 523 | unsigned int pad, u32 which) |
524 | { | 524 | { |
525 | switch (which) { | 525 | switch (which) { |
526 | case V4L2_SUBDEV_FORMAT_TRY: | 526 | case V4L2_SUBDEV_FORMAT_TRY: |
527 | return v4l2_subdev_get_try_crop(fh, pad); | 527 | return v4l2_subdev_get_try_crop(&mt9p031->subdev, cfg, pad); |
528 | case V4L2_SUBDEV_FORMAT_ACTIVE: | 528 | case V4L2_SUBDEV_FORMAT_ACTIVE: |
529 | return &mt9p031->crop; | 529 | return &mt9p031->crop; |
530 | default: | 530 | default: |
@@ -533,18 +533,18 @@ __mt9p031_get_pad_crop(struct mt9p031 *mt9p031, struct v4l2_subdev_fh *fh, | |||
533 | } | 533 | } |
534 | 534 | ||
535 | static int mt9p031_get_format(struct v4l2_subdev *subdev, | 535 | static int mt9p031_get_format(struct v4l2_subdev *subdev, |
536 | struct v4l2_subdev_fh *fh, | 536 | struct v4l2_subdev_pad_config *cfg, |
537 | struct v4l2_subdev_format *fmt) | 537 | struct v4l2_subdev_format *fmt) |
538 | { | 538 | { |
539 | struct mt9p031 *mt9p031 = to_mt9p031(subdev); | 539 | struct mt9p031 *mt9p031 = to_mt9p031(subdev); |
540 | 540 | ||
541 | fmt->format = *__mt9p031_get_pad_format(mt9p031, fh, fmt->pad, | 541 | fmt->format = *__mt9p031_get_pad_format(mt9p031, cfg, fmt->pad, |
542 | fmt->which); | 542 | fmt->which); |
543 | return 0; | 543 | return 0; |
544 | } | 544 | } |
545 | 545 | ||
546 | static int mt9p031_set_format(struct v4l2_subdev *subdev, | 546 | static int mt9p031_set_format(struct v4l2_subdev *subdev, |
547 | struct v4l2_subdev_fh *fh, | 547 | struct v4l2_subdev_pad_config *cfg, |
548 | struct v4l2_subdev_format *format) | 548 | struct v4l2_subdev_format *format) |
549 | { | 549 | { |
550 | struct mt9p031 *mt9p031 = to_mt9p031(subdev); | 550 | struct mt9p031 *mt9p031 = to_mt9p031(subdev); |
@@ -555,7 +555,7 @@ static int mt9p031_set_format(struct v4l2_subdev *subdev, | |||
555 | unsigned int hratio; | 555 | unsigned int hratio; |
556 | unsigned int vratio; | 556 | unsigned int vratio; |
557 | 557 | ||
558 | __crop = __mt9p031_get_pad_crop(mt9p031, fh, format->pad, | 558 | __crop = __mt9p031_get_pad_crop(mt9p031, cfg, format->pad, |
559 | format->which); | 559 | format->which); |
560 | 560 | ||
561 | /* Clamp the width and height to avoid dividing by zero. */ | 561 | /* Clamp the width and height to avoid dividing by zero. */ |
@@ -571,7 +571,7 @@ static int mt9p031_set_format(struct v4l2_subdev *subdev, | |||
571 | hratio = DIV_ROUND_CLOSEST(__crop->width, width); | 571 | hratio = DIV_ROUND_CLOSEST(__crop->width, width); |
572 | vratio = DIV_ROUND_CLOSEST(__crop->height, height); | 572 | vratio = DIV_ROUND_CLOSEST(__crop->height, height); |
573 | 573 | ||
574 | __format = __mt9p031_get_pad_format(mt9p031, fh, format->pad, | 574 | __format = __mt9p031_get_pad_format(mt9p031, cfg, format->pad, |
575 | format->which); | 575 | format->which); |
576 | __format->width = __crop->width / hratio; | 576 | __format->width = __crop->width / hratio; |
577 | __format->height = __crop->height / vratio; | 577 | __format->height = __crop->height / vratio; |
@@ -582,7 +582,7 @@ static int mt9p031_set_format(struct v4l2_subdev *subdev, | |||
582 | } | 582 | } |
583 | 583 | ||
584 | static int mt9p031_get_selection(struct v4l2_subdev *subdev, | 584 | static int mt9p031_get_selection(struct v4l2_subdev *subdev, |
585 | struct v4l2_subdev_fh *fh, | 585 | struct v4l2_subdev_pad_config *cfg, |
586 | struct v4l2_subdev_selection *sel) | 586 | struct v4l2_subdev_selection *sel) |
587 | { | 587 | { |
588 | struct mt9p031 *mt9p031 = to_mt9p031(subdev); | 588 | struct mt9p031 *mt9p031 = to_mt9p031(subdev); |
@@ -590,12 +590,12 @@ static int mt9p031_get_selection(struct v4l2_subdev *subdev, | |||
590 | if (sel->target != V4L2_SEL_TGT_CROP) | 590 | if (sel->target != V4L2_SEL_TGT_CROP) |
591 | return -EINVAL; | 591 | return -EINVAL; |
592 | 592 | ||
593 | sel->r = *__mt9p031_get_pad_crop(mt9p031, fh, sel->pad, sel->which); | 593 | sel->r = *__mt9p031_get_pad_crop(mt9p031, cfg, sel->pad, sel->which); |
594 | return 0; | 594 | return 0; |
595 | } | 595 | } |
596 | 596 | ||
597 | static int mt9p031_set_selection(struct v4l2_subdev *subdev, | 597 | static int mt9p031_set_selection(struct v4l2_subdev *subdev, |
598 | struct v4l2_subdev_fh *fh, | 598 | struct v4l2_subdev_pad_config *cfg, |
599 | struct v4l2_subdev_selection *sel) | 599 | struct v4l2_subdev_selection *sel) |
600 | { | 600 | { |
601 | struct mt9p031 *mt9p031 = to_mt9p031(subdev); | 601 | struct mt9p031 *mt9p031 = to_mt9p031(subdev); |
@@ -625,13 +625,13 @@ static int mt9p031_set_selection(struct v4l2_subdev *subdev, | |||
625 | rect.height = min_t(unsigned int, rect.height, | 625 | rect.height = min_t(unsigned int, rect.height, |
626 | MT9P031_PIXEL_ARRAY_HEIGHT - rect.top); | 626 | MT9P031_PIXEL_ARRAY_HEIGHT - rect.top); |
627 | 627 | ||
628 | __crop = __mt9p031_get_pad_crop(mt9p031, fh, sel->pad, sel->which); | 628 | __crop = __mt9p031_get_pad_crop(mt9p031, cfg, sel->pad, sel->which); |
629 | 629 | ||
630 | if (rect.width != __crop->width || rect.height != __crop->height) { | 630 | if (rect.width != __crop->width || rect.height != __crop->height) { |
631 | /* Reset the output image size if the crop rectangle size has | 631 | /* Reset the output image size if the crop rectangle size has |
632 | * been modified. | 632 | * been modified. |
633 | */ | 633 | */ |
634 | __format = __mt9p031_get_pad_format(mt9p031, fh, sel->pad, | 634 | __format = __mt9p031_get_pad_format(mt9p031, cfg, sel->pad, |
635 | sel->which); | 635 | sel->which); |
636 | __format->width = rect.width; | 636 | __format->width = rect.width; |
637 | __format->height = rect.height; | 637 | __format->height = rect.height; |
@@ -946,13 +946,13 @@ static int mt9p031_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh) | |||
946 | struct v4l2_mbus_framefmt *format; | 946 | struct v4l2_mbus_framefmt *format; |
947 | struct v4l2_rect *crop; | 947 | struct v4l2_rect *crop; |
948 | 948 | ||
949 | crop = v4l2_subdev_get_try_crop(fh, 0); | 949 | crop = v4l2_subdev_get_try_crop(subdev, fh->pad, 0); |
950 | crop->left = MT9P031_COLUMN_START_DEF; | 950 | crop->left = MT9P031_COLUMN_START_DEF; |
951 | crop->top = MT9P031_ROW_START_DEF; | 951 | crop->top = MT9P031_ROW_START_DEF; |
952 | crop->width = MT9P031_WINDOW_WIDTH_DEF; | 952 | crop->width = MT9P031_WINDOW_WIDTH_DEF; |
953 | crop->height = MT9P031_WINDOW_HEIGHT_DEF; | 953 | crop->height = MT9P031_WINDOW_HEIGHT_DEF; |
954 | 954 | ||
955 | format = v4l2_subdev_get_try_format(fh, 0); | 955 | format = v4l2_subdev_get_try_format(subdev, fh->pad, 0); |
956 | 956 | ||
957 | if (mt9p031->model == MT9P031_MODEL_MONOCHROME) | 957 | if (mt9p031->model == MT9P031_MODEL_MONOCHROME) |
958 | format->code = MEDIA_BUS_FMT_Y12_1X12; | 958 | format->code = MEDIA_BUS_FMT_Y12_1X12; |
@@ -1022,7 +1022,6 @@ mt9p031_get_pdata(struct i2c_client *client) | |||
1022 | if (!pdata) | 1022 | if (!pdata) |
1023 | goto done; | 1023 | goto done; |
1024 | 1024 | ||
1025 | pdata->reset = of_get_named_gpio(client->dev.of_node, "reset-gpios", 0); | ||
1026 | of_property_read_u32(np, "input-clock-frequency", &pdata->ext_freq); | 1025 | of_property_read_u32(np, "input-clock-frequency", &pdata->ext_freq); |
1027 | of_property_read_u32(np, "pixel-clock-frequency", &pdata->target_freq); | 1026 | of_property_read_u32(np, "pixel-clock-frequency", &pdata->target_freq); |
1028 | 1027 | ||
@@ -1059,7 +1058,6 @@ static int mt9p031_probe(struct i2c_client *client, | |||
1059 | mt9p031->output_control = MT9P031_OUTPUT_CONTROL_DEF; | 1058 | mt9p031->output_control = MT9P031_OUTPUT_CONTROL_DEF; |
1060 | mt9p031->mode2 = MT9P031_READ_MODE_2_ROW_BLC; | 1059 | mt9p031->mode2 = MT9P031_READ_MODE_2_ROW_BLC; |
1061 | mt9p031->model = did->driver_data; | 1060 | mt9p031->model = did->driver_data; |
1062 | mt9p031->reset = -1; | ||
1063 | 1061 | ||
1064 | mt9p031->regulators[0].supply = "vdd"; | 1062 | mt9p031->regulators[0].supply = "vdd"; |
1065 | mt9p031->regulators[1].supply = "vdd_io"; | 1063 | mt9p031->regulators[1].supply = "vdd_io"; |
@@ -1071,6 +1069,8 @@ static int mt9p031_probe(struct i2c_client *client, | |||
1071 | return ret; | 1069 | return ret; |
1072 | } | 1070 | } |
1073 | 1071 | ||
1072 | mutex_init(&mt9p031->power_lock); | ||
1073 | |||
1074 | v4l2_ctrl_handler_init(&mt9p031->ctrls, ARRAY_SIZE(mt9p031_ctrls) + 6); | 1074 | v4l2_ctrl_handler_init(&mt9p031->ctrls, ARRAY_SIZE(mt9p031_ctrls) + 6); |
1075 | 1075 | ||
1076 | v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops, | 1076 | v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops, |
@@ -1108,7 +1108,6 @@ static int mt9p031_probe(struct i2c_client *client, | |||
1108 | mt9p031->blc_offset = v4l2_ctrl_find(&mt9p031->ctrls, | 1108 | mt9p031->blc_offset = v4l2_ctrl_find(&mt9p031->ctrls, |
1109 | V4L2_CID_BLC_DIGITAL_OFFSET); | 1109 | V4L2_CID_BLC_DIGITAL_OFFSET); |
1110 | 1110 | ||
1111 | mutex_init(&mt9p031->power_lock); | ||
1112 | v4l2_i2c_subdev_init(&mt9p031->subdev, client, &mt9p031_subdev_ops); | 1111 | v4l2_i2c_subdev_init(&mt9p031->subdev, client, &mt9p031_subdev_ops); |
1113 | mt9p031->subdev.internal_ops = &mt9p031_subdev_internal_ops; | 1112 | mt9p031->subdev.internal_ops = &mt9p031_subdev_internal_ops; |
1114 | 1113 | ||
@@ -1134,21 +1133,20 @@ static int mt9p031_probe(struct i2c_client *client, | |||
1134 | mt9p031->format.field = V4L2_FIELD_NONE; | 1133 | mt9p031->format.field = V4L2_FIELD_NONE; |
1135 | mt9p031->format.colorspace = V4L2_COLORSPACE_SRGB; | 1134 | mt9p031->format.colorspace = V4L2_COLORSPACE_SRGB; |
1136 | 1135 | ||
1137 | if (gpio_is_valid(pdata->reset)) { | 1136 | mt9p031->reset = devm_gpiod_get_optional(&client->dev, "reset", |
1138 | ret = devm_gpio_request_one(&client->dev, pdata->reset, | 1137 | GPIOD_OUT_HIGH); |
1139 | GPIOF_OUT_INIT_LOW, "mt9p031_rst"); | ||
1140 | if (ret < 0) | ||
1141 | goto done; | ||
1142 | |||
1143 | mt9p031->reset = pdata->reset; | ||
1144 | } | ||
1145 | 1138 | ||
1146 | ret = mt9p031_clk_setup(mt9p031); | 1139 | ret = mt9p031_clk_setup(mt9p031); |
1140 | if (ret) | ||
1141 | goto done; | ||
1142 | |||
1143 | ret = v4l2_async_register_subdev(&mt9p031->subdev); | ||
1147 | 1144 | ||
1148 | done: | 1145 | done: |
1149 | if (ret < 0) { | 1146 | if (ret < 0) { |
1150 | v4l2_ctrl_handler_free(&mt9p031->ctrls); | 1147 | v4l2_ctrl_handler_free(&mt9p031->ctrls); |
1151 | media_entity_cleanup(&mt9p031->subdev.entity); | 1148 | media_entity_cleanup(&mt9p031->subdev.entity); |
1149 | mutex_destroy(&mt9p031->power_lock); | ||
1152 | } | 1150 | } |
1153 | 1151 | ||
1154 | return ret; | 1152 | return ret; |
@@ -1160,8 +1158,9 @@ static int mt9p031_remove(struct i2c_client *client) | |||
1160 | struct mt9p031 *mt9p031 = to_mt9p031(subdev); | 1158 | struct mt9p031 *mt9p031 = to_mt9p031(subdev); |
1161 | 1159 | ||
1162 | v4l2_ctrl_handler_free(&mt9p031->ctrls); | 1160 | v4l2_ctrl_handler_free(&mt9p031->ctrls); |
1163 | v4l2_device_unregister_subdev(subdev); | 1161 | v4l2_async_unregister_subdev(subdev); |
1164 | media_entity_cleanup(&subdev->entity); | 1162 | media_entity_cleanup(&subdev->entity); |
1163 | mutex_destroy(&mt9p031->power_lock); | ||
1165 | 1164 | ||
1166 | return 0; | 1165 | return 0; |
1167 | } | 1166 | } |
diff --git a/drivers/media/i2c/mt9t001.c b/drivers/media/i2c/mt9t001.c index f6ca636b538d..8ae99f7f254c 100644 --- a/drivers/media/i2c/mt9t001.c +++ b/drivers/media/i2c/mt9t001.c | |||
@@ -244,12 +244,12 @@ static int __mt9t001_set_power(struct mt9t001 *mt9t001, bool on) | |||
244 | */ | 244 | */ |
245 | 245 | ||
246 | static struct v4l2_mbus_framefmt * | 246 | static struct v4l2_mbus_framefmt * |
247 | __mt9t001_get_pad_format(struct mt9t001 *mt9t001, struct v4l2_subdev_fh *fh, | 247 | __mt9t001_get_pad_format(struct mt9t001 *mt9t001, struct v4l2_subdev_pad_config *cfg, |
248 | unsigned int pad, enum v4l2_subdev_format_whence which) | 248 | unsigned int pad, enum v4l2_subdev_format_whence which) |
249 | { | 249 | { |
250 | switch (which) { | 250 | switch (which) { |
251 | case V4L2_SUBDEV_FORMAT_TRY: | 251 | case V4L2_SUBDEV_FORMAT_TRY: |
252 | return v4l2_subdev_get_try_format(fh, pad); | 252 | return v4l2_subdev_get_try_format(&mt9t001->subdev, cfg, pad); |
253 | case V4L2_SUBDEV_FORMAT_ACTIVE: | 253 | case V4L2_SUBDEV_FORMAT_ACTIVE: |
254 | return &mt9t001->format; | 254 | return &mt9t001->format; |
255 | default: | 255 | default: |
@@ -258,12 +258,12 @@ __mt9t001_get_pad_format(struct mt9t001 *mt9t001, struct v4l2_subdev_fh *fh, | |||
258 | } | 258 | } |
259 | 259 | ||
260 | static struct v4l2_rect * | 260 | static struct v4l2_rect * |
261 | __mt9t001_get_pad_crop(struct mt9t001 *mt9t001, struct v4l2_subdev_fh *fh, | 261 | __mt9t001_get_pad_crop(struct mt9t001 *mt9t001, struct v4l2_subdev_pad_config *cfg, |
262 | unsigned int pad, enum v4l2_subdev_format_whence which) | 262 | unsigned int pad, enum v4l2_subdev_format_whence which) |
263 | { | 263 | { |
264 | switch (which) { | 264 | switch (which) { |
265 | case V4L2_SUBDEV_FORMAT_TRY: | 265 | case V4L2_SUBDEV_FORMAT_TRY: |
266 | return v4l2_subdev_get_try_crop(fh, pad); | 266 | return v4l2_subdev_get_try_crop(&mt9t001->subdev, cfg, pad); |
267 | case V4L2_SUBDEV_FORMAT_ACTIVE: | 267 | case V4L2_SUBDEV_FORMAT_ACTIVE: |
268 | return &mt9t001->crop; | 268 | return &mt9t001->crop; |
269 | default: | 269 | default: |
@@ -327,7 +327,7 @@ static int mt9t001_s_stream(struct v4l2_subdev *subdev, int enable) | |||
327 | } | 327 | } |
328 | 328 | ||
329 | static int mt9t001_enum_mbus_code(struct v4l2_subdev *subdev, | 329 | static int mt9t001_enum_mbus_code(struct v4l2_subdev *subdev, |
330 | struct v4l2_subdev_fh *fh, | 330 | struct v4l2_subdev_pad_config *cfg, |
331 | struct v4l2_subdev_mbus_code_enum *code) | 331 | struct v4l2_subdev_mbus_code_enum *code) |
332 | { | 332 | { |
333 | if (code->index > 0) | 333 | if (code->index > 0) |
@@ -338,7 +338,7 @@ static int mt9t001_enum_mbus_code(struct v4l2_subdev *subdev, | |||
338 | } | 338 | } |
339 | 339 | ||
340 | static int mt9t001_enum_frame_size(struct v4l2_subdev *subdev, | 340 | static int mt9t001_enum_frame_size(struct v4l2_subdev *subdev, |
341 | struct v4l2_subdev_fh *fh, | 341 | struct v4l2_subdev_pad_config *cfg, |
342 | struct v4l2_subdev_frame_size_enum *fse) | 342 | struct v4l2_subdev_frame_size_enum *fse) |
343 | { | 343 | { |
344 | if (fse->index >= 8 || fse->code != MEDIA_BUS_FMT_SGRBG10_1X10) | 344 | if (fse->index >= 8 || fse->code != MEDIA_BUS_FMT_SGRBG10_1X10) |
@@ -353,18 +353,18 @@ static int mt9t001_enum_frame_size(struct v4l2_subdev *subdev, | |||
353 | } | 353 | } |
354 | 354 | ||
355 | static int mt9t001_get_format(struct v4l2_subdev *subdev, | 355 | static int mt9t001_get_format(struct v4l2_subdev *subdev, |
356 | struct v4l2_subdev_fh *fh, | 356 | struct v4l2_subdev_pad_config *cfg, |
357 | struct v4l2_subdev_format *format) | 357 | struct v4l2_subdev_format *format) |
358 | { | 358 | { |
359 | struct mt9t001 *mt9t001 = to_mt9t001(subdev); | 359 | struct mt9t001 *mt9t001 = to_mt9t001(subdev); |
360 | 360 | ||
361 | format->format = *__mt9t001_get_pad_format(mt9t001, fh, format->pad, | 361 | format->format = *__mt9t001_get_pad_format(mt9t001, cfg, format->pad, |
362 | format->which); | 362 | format->which); |
363 | return 0; | 363 | return 0; |
364 | } | 364 | } |
365 | 365 | ||
366 | static int mt9t001_set_format(struct v4l2_subdev *subdev, | 366 | static int mt9t001_set_format(struct v4l2_subdev *subdev, |
367 | struct v4l2_subdev_fh *fh, | 367 | struct v4l2_subdev_pad_config *cfg, |
368 | struct v4l2_subdev_format *format) | 368 | struct v4l2_subdev_format *format) |
369 | { | 369 | { |
370 | struct mt9t001 *mt9t001 = to_mt9t001(subdev); | 370 | struct mt9t001 *mt9t001 = to_mt9t001(subdev); |
@@ -375,7 +375,7 @@ static int mt9t001_set_format(struct v4l2_subdev *subdev, | |||
375 | unsigned int hratio; | 375 | unsigned int hratio; |
376 | unsigned int vratio; | 376 | unsigned int vratio; |
377 | 377 | ||
378 | __crop = __mt9t001_get_pad_crop(mt9t001, fh, format->pad, | 378 | __crop = __mt9t001_get_pad_crop(mt9t001, cfg, format->pad, |
379 | format->which); | 379 | format->which); |
380 | 380 | ||
381 | /* Clamp the width and height to avoid dividing by zero. */ | 381 | /* Clamp the width and height to avoid dividing by zero. */ |
@@ -391,7 +391,7 @@ static int mt9t001_set_format(struct v4l2_subdev *subdev, | |||
391 | hratio = DIV_ROUND_CLOSEST(__crop->width, width); | 391 | hratio = DIV_ROUND_CLOSEST(__crop->width, width); |
392 | vratio = DIV_ROUND_CLOSEST(__crop->height, height); | 392 | vratio = DIV_ROUND_CLOSEST(__crop->height, height); |
393 | 393 | ||
394 | __format = __mt9t001_get_pad_format(mt9t001, fh, format->pad, | 394 | __format = __mt9t001_get_pad_format(mt9t001, cfg, format->pad, |
395 | format->which); | 395 | format->which); |
396 | __format->width = __crop->width / hratio; | 396 | __format->width = __crop->width / hratio; |
397 | __format->height = __crop->height / vratio; | 397 | __format->height = __crop->height / vratio; |
@@ -402,7 +402,7 @@ static int mt9t001_set_format(struct v4l2_subdev *subdev, | |||
402 | } | 402 | } |
403 | 403 | ||
404 | static int mt9t001_get_selection(struct v4l2_subdev *subdev, | 404 | static int mt9t001_get_selection(struct v4l2_subdev *subdev, |
405 | struct v4l2_subdev_fh *fh, | 405 | struct v4l2_subdev_pad_config *cfg, |
406 | struct v4l2_subdev_selection *sel) | 406 | struct v4l2_subdev_selection *sel) |
407 | { | 407 | { |
408 | struct mt9t001 *mt9t001 = to_mt9t001(subdev); | 408 | struct mt9t001 *mt9t001 = to_mt9t001(subdev); |
@@ -410,12 +410,12 @@ static int mt9t001_get_selection(struct v4l2_subdev *subdev, | |||
410 | if (sel->target != V4L2_SEL_TGT_CROP) | 410 | if (sel->target != V4L2_SEL_TGT_CROP) |
411 | return -EINVAL; | 411 | return -EINVAL; |
412 | 412 | ||
413 | sel->r = *__mt9t001_get_pad_crop(mt9t001, fh, sel->pad, sel->which); | 413 | sel->r = *__mt9t001_get_pad_crop(mt9t001, cfg, sel->pad, sel->which); |
414 | return 0; | 414 | return 0; |
415 | } | 415 | } |
416 | 416 | ||
417 | static int mt9t001_set_selection(struct v4l2_subdev *subdev, | 417 | static int mt9t001_set_selection(struct v4l2_subdev *subdev, |
418 | struct v4l2_subdev_fh *fh, | 418 | struct v4l2_subdev_pad_config *cfg, |
419 | struct v4l2_subdev_selection *sel) | 419 | struct v4l2_subdev_selection *sel) |
420 | { | 420 | { |
421 | struct mt9t001 *mt9t001 = to_mt9t001(subdev); | 421 | struct mt9t001 *mt9t001 = to_mt9t001(subdev); |
@@ -447,13 +447,13 @@ static int mt9t001_set_selection(struct v4l2_subdev *subdev, | |||
447 | rect.height = min_t(unsigned int, rect.height, | 447 | rect.height = min_t(unsigned int, rect.height, |
448 | MT9T001_PIXEL_ARRAY_HEIGHT - rect.top); | 448 | MT9T001_PIXEL_ARRAY_HEIGHT - rect.top); |
449 | 449 | ||
450 | __crop = __mt9t001_get_pad_crop(mt9t001, fh, sel->pad, sel->which); | 450 | __crop = __mt9t001_get_pad_crop(mt9t001, cfg, sel->pad, sel->which); |
451 | 451 | ||
452 | if (rect.width != __crop->width || rect.height != __crop->height) { | 452 | if (rect.width != __crop->width || rect.height != __crop->height) { |
453 | /* Reset the output image size if the crop rectangle size has | 453 | /* Reset the output image size if the crop rectangle size has |
454 | * been modified. | 454 | * been modified. |
455 | */ | 455 | */ |
456 | __format = __mt9t001_get_pad_format(mt9t001, fh, sel->pad, | 456 | __format = __mt9t001_get_pad_format(mt9t001, cfg, sel->pad, |
457 | sel->which); | 457 | sel->which); |
458 | __format->width = rect.width; | 458 | __format->width = rect.width; |
459 | __format->height = rect.height; | 459 | __format->height = rect.height; |
@@ -790,13 +790,13 @@ static int mt9t001_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh) | |||
790 | struct v4l2_mbus_framefmt *format; | 790 | struct v4l2_mbus_framefmt *format; |
791 | struct v4l2_rect *crop; | 791 | struct v4l2_rect *crop; |
792 | 792 | ||
793 | crop = v4l2_subdev_get_try_crop(fh, 0); | 793 | crop = v4l2_subdev_get_try_crop(subdev, fh->pad, 0); |
794 | crop->left = MT9T001_COLUMN_START_DEF; | 794 | crop->left = MT9T001_COLUMN_START_DEF; |
795 | crop->top = MT9T001_ROW_START_DEF; | 795 | crop->top = MT9T001_ROW_START_DEF; |
796 | crop->width = MT9T001_WINDOW_WIDTH_DEF + 1; | 796 | crop->width = MT9T001_WINDOW_WIDTH_DEF + 1; |
797 | crop->height = MT9T001_WINDOW_HEIGHT_DEF + 1; | 797 | crop->height = MT9T001_WINDOW_HEIGHT_DEF + 1; |
798 | 798 | ||
799 | format = v4l2_subdev_get_try_format(fh, 0); | 799 | format = v4l2_subdev_get_try_format(subdev, fh->pad, 0); |
800 | format->code = MEDIA_BUS_FMT_SGRBG10_1X10; | 800 | format->code = MEDIA_BUS_FMT_SGRBG10_1X10; |
801 | format->width = MT9T001_WINDOW_WIDTH_DEF + 1; | 801 | format->width = MT9T001_WINDOW_WIDTH_DEF + 1; |
802 | format->height = MT9T001_WINDOW_HEIGHT_DEF + 1; | 802 | format->height = MT9T001_WINDOW_HEIGHT_DEF + 1; |
diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c index bd3f979a4d49..977f4006edbd 100644 --- a/drivers/media/i2c/mt9v032.c +++ b/drivers/media/i2c/mt9v032.c | |||
@@ -17,6 +17,8 @@ | |||
17 | #include <linux/i2c.h> | 17 | #include <linux/i2c.h> |
18 | #include <linux/log2.h> | 18 | #include <linux/log2.h> |
19 | #include <linux/mutex.h> | 19 | #include <linux/mutex.h> |
20 | #include <linux/of.h> | ||
21 | #include <linux/of_gpio.h> | ||
20 | #include <linux/regmap.h> | 22 | #include <linux/regmap.h> |
21 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
22 | #include <linux/videodev2.h> | 24 | #include <linux/videodev2.h> |
@@ -26,6 +28,7 @@ | |||
26 | #include <media/mt9v032.h> | 28 | #include <media/mt9v032.h> |
27 | #include <media/v4l2-ctrls.h> | 29 | #include <media/v4l2-ctrls.h> |
28 | #include <media/v4l2-device.h> | 30 | #include <media/v4l2-device.h> |
31 | #include <media/v4l2-of.h> | ||
29 | #include <media/v4l2-subdev.h> | 32 | #include <media/v4l2-subdev.h> |
30 | 33 | ||
31 | /* The first four rows are black rows. The active area spans 753x481 pixels. */ | 34 | /* The first four rows are black rows. The active area spans 753x481 pixels. */ |
@@ -371,12 +374,12 @@ static int __mt9v032_set_power(struct mt9v032 *mt9v032, bool on) | |||
371 | */ | 374 | */ |
372 | 375 | ||
373 | static struct v4l2_mbus_framefmt * | 376 | static struct v4l2_mbus_framefmt * |
374 | __mt9v032_get_pad_format(struct mt9v032 *mt9v032, struct v4l2_subdev_fh *fh, | 377 | __mt9v032_get_pad_format(struct mt9v032 *mt9v032, struct v4l2_subdev_pad_config *cfg, |
375 | unsigned int pad, enum v4l2_subdev_format_whence which) | 378 | unsigned int pad, enum v4l2_subdev_format_whence which) |
376 | { | 379 | { |
377 | switch (which) { | 380 | switch (which) { |
378 | case V4L2_SUBDEV_FORMAT_TRY: | 381 | case V4L2_SUBDEV_FORMAT_TRY: |
379 | return v4l2_subdev_get_try_format(fh, pad); | 382 | return v4l2_subdev_get_try_format(&mt9v032->subdev, cfg, pad); |
380 | case V4L2_SUBDEV_FORMAT_ACTIVE: | 383 | case V4L2_SUBDEV_FORMAT_ACTIVE: |
381 | return &mt9v032->format; | 384 | return &mt9v032->format; |
382 | default: | 385 | default: |
@@ -385,12 +388,12 @@ __mt9v032_get_pad_format(struct mt9v032 *mt9v032, struct v4l2_subdev_fh *fh, | |||
385 | } | 388 | } |
386 | 389 | ||
387 | static struct v4l2_rect * | 390 | static struct v4l2_rect * |
388 | __mt9v032_get_pad_crop(struct mt9v032 *mt9v032, struct v4l2_subdev_fh *fh, | 391 | __mt9v032_get_pad_crop(struct mt9v032 *mt9v032, struct v4l2_subdev_pad_config *cfg, |
389 | unsigned int pad, enum v4l2_subdev_format_whence which) | 392 | unsigned int pad, enum v4l2_subdev_format_whence which) |
390 | { | 393 | { |
391 | switch (which) { | 394 | switch (which) { |
392 | case V4L2_SUBDEV_FORMAT_TRY: | 395 | case V4L2_SUBDEV_FORMAT_TRY: |
393 | return v4l2_subdev_get_try_crop(fh, pad); | 396 | return v4l2_subdev_get_try_crop(&mt9v032->subdev, cfg, pad); |
394 | case V4L2_SUBDEV_FORMAT_ACTIVE: | 397 | case V4L2_SUBDEV_FORMAT_ACTIVE: |
395 | return &mt9v032->crop; | 398 | return &mt9v032->crop; |
396 | default: | 399 | default: |
@@ -448,7 +451,7 @@ static int mt9v032_s_stream(struct v4l2_subdev *subdev, int enable) | |||
448 | } | 451 | } |
449 | 452 | ||
450 | static int mt9v032_enum_mbus_code(struct v4l2_subdev *subdev, | 453 | static int mt9v032_enum_mbus_code(struct v4l2_subdev *subdev, |
451 | struct v4l2_subdev_fh *fh, | 454 | struct v4l2_subdev_pad_config *cfg, |
452 | struct v4l2_subdev_mbus_code_enum *code) | 455 | struct v4l2_subdev_mbus_code_enum *code) |
453 | { | 456 | { |
454 | if (code->index > 0) | 457 | if (code->index > 0) |
@@ -459,7 +462,7 @@ static int mt9v032_enum_mbus_code(struct v4l2_subdev *subdev, | |||
459 | } | 462 | } |
460 | 463 | ||
461 | static int mt9v032_enum_frame_size(struct v4l2_subdev *subdev, | 464 | static int mt9v032_enum_frame_size(struct v4l2_subdev *subdev, |
462 | struct v4l2_subdev_fh *fh, | 465 | struct v4l2_subdev_pad_config *cfg, |
463 | struct v4l2_subdev_frame_size_enum *fse) | 466 | struct v4l2_subdev_frame_size_enum *fse) |
464 | { | 467 | { |
465 | if (fse->index >= 3 || fse->code != MEDIA_BUS_FMT_SGRBG10_1X10) | 468 | if (fse->index >= 3 || fse->code != MEDIA_BUS_FMT_SGRBG10_1X10) |
@@ -474,12 +477,12 @@ static int mt9v032_enum_frame_size(struct v4l2_subdev *subdev, | |||
474 | } | 477 | } |
475 | 478 | ||
476 | static int mt9v032_get_format(struct v4l2_subdev *subdev, | 479 | static int mt9v032_get_format(struct v4l2_subdev *subdev, |
477 | struct v4l2_subdev_fh *fh, | 480 | struct v4l2_subdev_pad_config *cfg, |
478 | struct v4l2_subdev_format *format) | 481 | struct v4l2_subdev_format *format) |
479 | { | 482 | { |
480 | struct mt9v032 *mt9v032 = to_mt9v032(subdev); | 483 | struct mt9v032 *mt9v032 = to_mt9v032(subdev); |
481 | 484 | ||
482 | format->format = *__mt9v032_get_pad_format(mt9v032, fh, format->pad, | 485 | format->format = *__mt9v032_get_pad_format(mt9v032, cfg, format->pad, |
483 | format->which); | 486 | format->which); |
484 | return 0; | 487 | return 0; |
485 | } | 488 | } |
@@ -509,7 +512,7 @@ static unsigned int mt9v032_calc_ratio(unsigned int input, unsigned int output) | |||
509 | } | 512 | } |
510 | 513 | ||
511 | static int mt9v032_set_format(struct v4l2_subdev *subdev, | 514 | static int mt9v032_set_format(struct v4l2_subdev *subdev, |
512 | struct v4l2_subdev_fh *fh, | 515 | struct v4l2_subdev_pad_config *cfg, |
513 | struct v4l2_subdev_format *format) | 516 | struct v4l2_subdev_format *format) |
514 | { | 517 | { |
515 | struct mt9v032 *mt9v032 = to_mt9v032(subdev); | 518 | struct mt9v032 *mt9v032 = to_mt9v032(subdev); |
@@ -520,7 +523,7 @@ static int mt9v032_set_format(struct v4l2_subdev *subdev, | |||
520 | unsigned int hratio; | 523 | unsigned int hratio; |
521 | unsigned int vratio; | 524 | unsigned int vratio; |
522 | 525 | ||
523 | __crop = __mt9v032_get_pad_crop(mt9v032, fh, format->pad, | 526 | __crop = __mt9v032_get_pad_crop(mt9v032, cfg, format->pad, |
524 | format->which); | 527 | format->which); |
525 | 528 | ||
526 | /* Clamp the width and height to avoid dividing by zero. */ | 529 | /* Clamp the width and height to avoid dividing by zero. */ |
@@ -536,7 +539,7 @@ static int mt9v032_set_format(struct v4l2_subdev *subdev, | |||
536 | hratio = mt9v032_calc_ratio(__crop->width, width); | 539 | hratio = mt9v032_calc_ratio(__crop->width, width); |
537 | vratio = mt9v032_calc_ratio(__crop->height, height); | 540 | vratio = mt9v032_calc_ratio(__crop->height, height); |
538 | 541 | ||
539 | __format = __mt9v032_get_pad_format(mt9v032, fh, format->pad, | 542 | __format = __mt9v032_get_pad_format(mt9v032, cfg, format->pad, |
540 | format->which); | 543 | format->which); |
541 | __format->width = __crop->width / hratio; | 544 | __format->width = __crop->width / hratio; |
542 | __format->height = __crop->height / vratio; | 545 | __format->height = __crop->height / vratio; |
@@ -553,7 +556,7 @@ static int mt9v032_set_format(struct v4l2_subdev *subdev, | |||
553 | } | 556 | } |
554 | 557 | ||
555 | static int mt9v032_get_selection(struct v4l2_subdev *subdev, | 558 | static int mt9v032_get_selection(struct v4l2_subdev *subdev, |
556 | struct v4l2_subdev_fh *fh, | 559 | struct v4l2_subdev_pad_config *cfg, |
557 | struct v4l2_subdev_selection *sel) | 560 | struct v4l2_subdev_selection *sel) |
558 | { | 561 | { |
559 | struct mt9v032 *mt9v032 = to_mt9v032(subdev); | 562 | struct mt9v032 *mt9v032 = to_mt9v032(subdev); |
@@ -561,12 +564,12 @@ static int mt9v032_get_selection(struct v4l2_subdev *subdev, | |||
561 | if (sel->target != V4L2_SEL_TGT_CROP) | 564 | if (sel->target != V4L2_SEL_TGT_CROP) |
562 | return -EINVAL; | 565 | return -EINVAL; |
563 | 566 | ||
564 | sel->r = *__mt9v032_get_pad_crop(mt9v032, fh, sel->pad, sel->which); | 567 | sel->r = *__mt9v032_get_pad_crop(mt9v032, cfg, sel->pad, sel->which); |
565 | return 0; | 568 | return 0; |
566 | } | 569 | } |
567 | 570 | ||
568 | static int mt9v032_set_selection(struct v4l2_subdev *subdev, | 571 | static int mt9v032_set_selection(struct v4l2_subdev *subdev, |
569 | struct v4l2_subdev_fh *fh, | 572 | struct v4l2_subdev_pad_config *cfg, |
570 | struct v4l2_subdev_selection *sel) | 573 | struct v4l2_subdev_selection *sel) |
571 | { | 574 | { |
572 | struct mt9v032 *mt9v032 = to_mt9v032(subdev); | 575 | struct mt9v032 *mt9v032 = to_mt9v032(subdev); |
@@ -598,13 +601,13 @@ static int mt9v032_set_selection(struct v4l2_subdev *subdev, | |||
598 | rect.height = min_t(unsigned int, | 601 | rect.height = min_t(unsigned int, |
599 | rect.height, MT9V032_PIXEL_ARRAY_HEIGHT - rect.top); | 602 | rect.height, MT9V032_PIXEL_ARRAY_HEIGHT - rect.top); |
600 | 603 | ||
601 | __crop = __mt9v032_get_pad_crop(mt9v032, fh, sel->pad, sel->which); | 604 | __crop = __mt9v032_get_pad_crop(mt9v032, cfg, sel->pad, sel->which); |
602 | 605 | ||
603 | if (rect.width != __crop->width || rect.height != __crop->height) { | 606 | if (rect.width != __crop->width || rect.height != __crop->height) { |
604 | /* Reset the output image size if the crop rectangle size has | 607 | /* Reset the output image size if the crop rectangle size has |
605 | * been modified. | 608 | * been modified. |
606 | */ | 609 | */ |
607 | __format = __mt9v032_get_pad_format(mt9v032, fh, sel->pad, | 610 | __format = __mt9v032_get_pad_format(mt9v032, cfg, sel->pad, |
608 | sel->which); | 611 | sel->which); |
609 | __format->width = rect.width; | 612 | __format->width = rect.width; |
610 | __format->height = rect.height; | 613 | __format->height = rect.height; |
@@ -810,13 +813,13 @@ static int mt9v032_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh) | |||
810 | struct v4l2_mbus_framefmt *format; | 813 | struct v4l2_mbus_framefmt *format; |
811 | struct v4l2_rect *crop; | 814 | struct v4l2_rect *crop; |
812 | 815 | ||
813 | crop = v4l2_subdev_get_try_crop(fh, 0); | 816 | crop = v4l2_subdev_get_try_crop(subdev, fh->pad, 0); |
814 | crop->left = MT9V032_COLUMN_START_DEF; | 817 | crop->left = MT9V032_COLUMN_START_DEF; |
815 | crop->top = MT9V032_ROW_START_DEF; | 818 | crop->top = MT9V032_ROW_START_DEF; |
816 | crop->width = MT9V032_WINDOW_WIDTH_DEF; | 819 | crop->width = MT9V032_WINDOW_WIDTH_DEF; |
817 | crop->height = MT9V032_WINDOW_HEIGHT_DEF; | 820 | crop->height = MT9V032_WINDOW_HEIGHT_DEF; |
818 | 821 | ||
819 | format = v4l2_subdev_get_try_format(fh, 0); | 822 | format = v4l2_subdev_get_try_format(subdev, fh->pad, 0); |
820 | 823 | ||
821 | if (mt9v032->model->color) | 824 | if (mt9v032->model->color) |
822 | format->code = MEDIA_BUS_FMT_SGRBG10_1X10; | 825 | format->code = MEDIA_BUS_FMT_SGRBG10_1X10; |
@@ -876,10 +879,58 @@ static const struct regmap_config mt9v032_regmap_config = { | |||
876 | * Driver initialization and probing | 879 | * Driver initialization and probing |
877 | */ | 880 | */ |
878 | 881 | ||
882 | static struct mt9v032_platform_data * | ||
883 | mt9v032_get_pdata(struct i2c_client *client) | ||
884 | { | ||
885 | struct mt9v032_platform_data *pdata; | ||
886 | struct v4l2_of_endpoint endpoint; | ||
887 | struct device_node *np; | ||
888 | struct property *prop; | ||
889 | |||
890 | if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node) | ||
891 | return client->dev.platform_data; | ||
892 | |||
893 | np = of_graph_get_next_endpoint(client->dev.of_node, NULL); | ||
894 | if (!np) | ||
895 | return NULL; | ||
896 | |||
897 | if (v4l2_of_parse_endpoint(np, &endpoint) < 0) | ||
898 | goto done; | ||
899 | |||
900 | pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); | ||
901 | if (!pdata) | ||
902 | goto done; | ||
903 | |||
904 | prop = of_find_property(np, "link-frequencies", NULL); | ||
905 | if (prop) { | ||
906 | u64 *link_freqs; | ||
907 | size_t size = prop->length / sizeof(*link_freqs); | ||
908 | |||
909 | link_freqs = devm_kcalloc(&client->dev, size, | ||
910 | sizeof(*link_freqs), GFP_KERNEL); | ||
911 | if (!link_freqs) | ||
912 | goto done; | ||
913 | |||
914 | if (of_property_read_u64_array(np, "link-frequencies", | ||
915 | link_freqs, size) < 0) | ||
916 | goto done; | ||
917 | |||
918 | pdata->link_freqs = link_freqs; | ||
919 | pdata->link_def_freq = link_freqs[0]; | ||
920 | } | ||
921 | |||
922 | pdata->clk_pol = !!(endpoint.bus.parallel.flags & | ||
923 | V4L2_MBUS_PCLK_SAMPLE_RISING); | ||
924 | |||
925 | done: | ||
926 | of_node_put(np); | ||
927 | return pdata; | ||
928 | } | ||
929 | |||
879 | static int mt9v032_probe(struct i2c_client *client, | 930 | static int mt9v032_probe(struct i2c_client *client, |
880 | const struct i2c_device_id *did) | 931 | const struct i2c_device_id *did) |
881 | { | 932 | { |
882 | struct mt9v032_platform_data *pdata = client->dev.platform_data; | 933 | struct mt9v032_platform_data *pdata = mt9v032_get_pdata(client); |
883 | struct mt9v032 *mt9v032; | 934 | struct mt9v032 *mt9v032; |
884 | unsigned int i; | 935 | unsigned int i; |
885 | int ret; | 936 | int ret; |
@@ -961,9 +1012,12 @@ static int mt9v032_probe(struct i2c_client *client, | |||
961 | 1012 | ||
962 | mt9v032->subdev.ctrl_handler = &mt9v032->ctrls; | 1013 | mt9v032->subdev.ctrl_handler = &mt9v032->ctrls; |
963 | 1014 | ||
964 | if (mt9v032->ctrls.error) | 1015 | if (mt9v032->ctrls.error) { |
965 | printk(KERN_INFO "%s: control initialization error %d\n", | 1016 | dev_err(&client->dev, "control initialization error %d\n", |
966 | __func__, mt9v032->ctrls.error); | 1017 | mt9v032->ctrls.error); |
1018 | ret = mt9v032->ctrls.error; | ||
1019 | goto err; | ||
1020 | } | ||
967 | 1021 | ||
968 | mt9v032->crop.left = MT9V032_COLUMN_START_DEF; | 1022 | mt9v032->crop.left = MT9V032_COLUMN_START_DEF; |
969 | mt9v032->crop.top = MT9V032_ROW_START_DEF; | 1023 | mt9v032->crop.top = MT9V032_ROW_START_DEF; |
@@ -1016,7 +1070,6 @@ static int mt9v032_remove(struct i2c_client *client) | |||
1016 | 1070 | ||
1017 | v4l2_async_unregister_subdev(subdev); | 1071 | v4l2_async_unregister_subdev(subdev); |
1018 | v4l2_ctrl_handler_free(&mt9v032->ctrls); | 1072 | v4l2_ctrl_handler_free(&mt9v032->ctrls); |
1019 | v4l2_device_unregister_subdev(subdev); | ||
1020 | media_entity_cleanup(&subdev->entity); | 1073 | media_entity_cleanup(&subdev->entity); |
1021 | 1074 | ||
1022 | return 0; | 1075 | return 0; |
@@ -1035,9 +1088,25 @@ static const struct i2c_device_id mt9v032_id[] = { | |||
1035 | }; | 1088 | }; |
1036 | MODULE_DEVICE_TABLE(i2c, mt9v032_id); | 1089 | MODULE_DEVICE_TABLE(i2c, mt9v032_id); |
1037 | 1090 | ||
1091 | #if IS_ENABLED(CONFIG_OF) | ||
1092 | static const struct of_device_id mt9v032_of_match[] = { | ||
1093 | { .compatible = "aptina,mt9v022" }, | ||
1094 | { .compatible = "aptina,mt9v022m" }, | ||
1095 | { .compatible = "aptina,mt9v024" }, | ||
1096 | { .compatible = "aptina,mt9v024m" }, | ||
1097 | { .compatible = "aptina,mt9v032" }, | ||
1098 | { .compatible = "aptina,mt9v032m" }, | ||
1099 | { .compatible = "aptina,mt9v034" }, | ||
1100 | { .compatible = "aptina,mt9v034m" }, | ||
1101 | { /* Sentinel */ } | ||
1102 | }; | ||
1103 | MODULE_DEVICE_TABLE(of, mt9v032_of_match); | ||
1104 | #endif | ||
1105 | |||
1038 | static struct i2c_driver mt9v032_driver = { | 1106 | static struct i2c_driver mt9v032_driver = { |
1039 | .driver = { | 1107 | .driver = { |
1040 | .name = "mt9v032", | 1108 | .name = "mt9v032", |
1109 | .of_match_table = of_match_ptr(mt9v032_of_match), | ||
1041 | }, | 1110 | }, |
1042 | .probe = mt9v032_probe, | 1111 | .probe = mt9v032_probe, |
1043 | .remove = mt9v032_remove, | 1112 | .remove = mt9v032_remove, |
diff --git a/drivers/media/i2c/noon010pc30.c b/drivers/media/i2c/noon010pc30.c index 00c7b26f4823..f197b6cbd407 100644 --- a/drivers/media/i2c/noon010pc30.c +++ b/drivers/media/i2c/noon010pc30.c | |||
@@ -492,7 +492,7 @@ unlock: | |||
492 | } | 492 | } |
493 | 493 | ||
494 | static int noon010_enum_mbus_code(struct v4l2_subdev *sd, | 494 | static int noon010_enum_mbus_code(struct v4l2_subdev *sd, |
495 | struct v4l2_subdev_fh *fh, | 495 | struct v4l2_subdev_pad_config *cfg, |
496 | struct v4l2_subdev_mbus_code_enum *code) | 496 | struct v4l2_subdev_mbus_code_enum *code) |
497 | { | 497 | { |
498 | if (code->index >= ARRAY_SIZE(noon010_formats)) | 498 | if (code->index >= ARRAY_SIZE(noon010_formats)) |
@@ -502,15 +502,16 @@ static int noon010_enum_mbus_code(struct v4l2_subdev *sd, | |||
502 | return 0; | 502 | return 0; |
503 | } | 503 | } |
504 | 504 | ||
505 | static int noon010_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | 505 | static int noon010_get_fmt(struct v4l2_subdev *sd, |
506 | struct v4l2_subdev_pad_config *cfg, | ||
506 | struct v4l2_subdev_format *fmt) | 507 | struct v4l2_subdev_format *fmt) |
507 | { | 508 | { |
508 | struct noon010_info *info = to_noon010(sd); | 509 | struct noon010_info *info = to_noon010(sd); |
509 | struct v4l2_mbus_framefmt *mf; | 510 | struct v4l2_mbus_framefmt *mf; |
510 | 511 | ||
511 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { | 512 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { |
512 | if (fh) { | 513 | if (cfg) { |
513 | mf = v4l2_subdev_get_try_format(fh, 0); | 514 | mf = v4l2_subdev_get_try_format(sd, cfg, 0); |
514 | fmt->format = *mf; | 515 | fmt->format = *mf; |
515 | } | 516 | } |
516 | return 0; | 517 | return 0; |
@@ -542,7 +543,7 @@ static const struct noon010_format *noon010_try_fmt(struct v4l2_subdev *sd, | |||
542 | return &noon010_formats[i]; | 543 | return &noon010_formats[i]; |
543 | } | 544 | } |
544 | 545 | ||
545 | static int noon010_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | 546 | static int noon010_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, |
546 | struct v4l2_subdev_format *fmt) | 547 | struct v4l2_subdev_format *fmt) |
547 | { | 548 | { |
548 | struct noon010_info *info = to_noon010(sd); | 549 | struct noon010_info *info = to_noon010(sd); |
@@ -557,8 +558,8 @@ static int noon010_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
557 | fmt->format.field = V4L2_FIELD_NONE; | 558 | fmt->format.field = V4L2_FIELD_NONE; |
558 | 559 | ||
559 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { | 560 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { |
560 | if (fh) { | 561 | if (cfg) { |
561 | mf = v4l2_subdev_get_try_format(fh, 0); | 562 | mf = v4l2_subdev_get_try_format(sd, cfg, 0); |
562 | *mf = fmt->format; | 563 | *mf = fmt->format; |
563 | } | 564 | } |
564 | return 0; | 565 | return 0; |
@@ -640,7 +641,7 @@ static int noon010_log_status(struct v4l2_subdev *sd) | |||
640 | 641 | ||
641 | static int noon010_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) | 642 | static int noon010_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) |
642 | { | 643 | { |
643 | struct v4l2_mbus_framefmt *mf = v4l2_subdev_get_try_format(fh, 0); | 644 | struct v4l2_mbus_framefmt *mf = v4l2_subdev_get_try_format(sd, fh->pad, 0); |
644 | 645 | ||
645 | mf->width = noon010_sizes[0].width; | 646 | mf->width = noon010_sizes[0].width; |
646 | mf->height = noon010_sizes[0].height; | 647 | mf->height = noon010_sizes[0].height; |
diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c new file mode 100644 index 000000000000..edebd114279d --- /dev/null +++ b/drivers/media/i2c/ov2659.c | |||
@@ -0,0 +1,1509 @@ | |||
1 | /* | ||
2 | * Omnivision OV2659 CMOS Image Sensor driver | ||
3 | * | ||
4 | * Copyright (C) 2015 Texas Instruments, Inc. | ||
5 | * | ||
6 | * Benoit Parrot <bparrot@ti.com> | ||
7 | * Lad, Prabhakar <prabhakar.csengg@gmail.com> | ||
8 | * | ||
9 | * This program is free software; you may redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; version 2 of the License. | ||
12 | * | ||
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
14 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
15 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
16 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
17 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
18 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
19 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
20 | * SOFTWARE. | ||
21 | */ | ||
22 | |||
23 | #include <linux/clk.h> | ||
24 | #include <linux/delay.h> | ||
25 | #include <linux/err.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | #include <linux/io.h> | ||
29 | #include <linux/i2c.h> | ||
30 | #include <linux/kernel.h> | ||
31 | #include <linux/media.h> | ||
32 | #include <linux/module.h> | ||
33 | #include <linux/of.h> | ||
34 | #include <linux/of_graph.h> | ||
35 | #include <linux/slab.h> | ||
36 | #include <linux/uaccess.h> | ||
37 | #include <linux/videodev2.h> | ||
38 | |||
39 | #include <media/media-entity.h> | ||
40 | #include <media/ov2659.h> | ||
41 | #include <media/v4l2-common.h> | ||
42 | #include <media/v4l2-ctrls.h> | ||
43 | #include <media/v4l2-device.h> | ||
44 | #include <media/v4l2-event.h> | ||
45 | #include <media/v4l2-image-sizes.h> | ||
46 | #include <media/v4l2-mediabus.h> | ||
47 | #include <media/v4l2-of.h> | ||
48 | #include <media/v4l2-subdev.h> | ||
49 | |||
50 | #define DRIVER_NAME "ov2659" | ||
51 | |||
52 | /* | ||
53 | * OV2659 register definitions | ||
54 | */ | ||
55 | #define REG_SOFTWARE_STANDBY 0x0100 | ||
56 | #define REG_SOFTWARE_RESET 0x0103 | ||
57 | #define REG_IO_CTRL00 0x3000 | ||
58 | #define REG_IO_CTRL01 0x3001 | ||
59 | #define REG_IO_CTRL02 0x3002 | ||
60 | #define REG_OUTPUT_VALUE00 0x3008 | ||
61 | #define REG_OUTPUT_VALUE01 0x3009 | ||
62 | #define REG_OUTPUT_VALUE02 0x300d | ||
63 | #define REG_OUTPUT_SELECT00 0x300e | ||
64 | #define REG_OUTPUT_SELECT01 0x300f | ||
65 | #define REG_OUTPUT_SELECT02 0x3010 | ||
66 | #define REG_OUTPUT_DRIVE 0x3011 | ||
67 | #define REG_INPUT_READOUT00 0x302d | ||
68 | #define REG_INPUT_READOUT01 0x302e | ||
69 | #define REG_INPUT_READOUT02 0x302f | ||
70 | |||
71 | #define REG_SC_PLL_CTRL0 0x3003 | ||
72 | #define REG_SC_PLL_CTRL1 0x3004 | ||
73 | #define REG_SC_PLL_CTRL2 0x3005 | ||
74 | #define REG_SC_PLL_CTRL3 0x3006 | ||
75 | #define REG_SC_CHIP_ID_H 0x300a | ||
76 | #define REG_SC_CHIP_ID_L 0x300b | ||
77 | #define REG_SC_PWC 0x3014 | ||
78 | #define REG_SC_CLKRST0 0x301a | ||
79 | #define REG_SC_CLKRST1 0x301b | ||
80 | #define REG_SC_CLKRST2 0x301c | ||
81 | #define REG_SC_CLKRST3 0x301d | ||
82 | #define REG_SC_SUB_ID 0x302a | ||
83 | #define REG_SC_SCCB_ID 0x302b | ||
84 | |||
85 | #define REG_GROUP_ADDRESS_00 0x3200 | ||
86 | #define REG_GROUP_ADDRESS_01 0x3201 | ||
87 | #define REG_GROUP_ADDRESS_02 0x3202 | ||
88 | #define REG_GROUP_ADDRESS_03 0x3203 | ||
89 | #define REG_GROUP_ACCESS 0x3208 | ||
90 | |||
91 | #define REG_AWB_R_GAIN_H 0x3400 | ||
92 | #define REG_AWB_R_GAIN_L 0x3401 | ||
93 | #define REG_AWB_G_GAIN_H 0x3402 | ||
94 | #define REG_AWB_G_GAIN_L 0x3403 | ||
95 | #define REG_AWB_B_GAIN_H 0x3404 | ||
96 | #define REG_AWB_B_GAIN_L 0x3405 | ||
97 | #define REG_AWB_MANUAL_CONTROL 0x3406 | ||
98 | |||
99 | #define REG_TIMING_HS_H 0x3800 | ||
100 | #define REG_TIMING_HS_L 0x3801 | ||
101 | #define REG_TIMING_VS_H 0x3802 | ||
102 | #define REG_TIMING_VS_L 0x3803 | ||
103 | #define REG_TIMING_HW_H 0x3804 | ||
104 | #define REG_TIMING_HW_L 0x3805 | ||
105 | #define REG_TIMING_VH_H 0x3806 | ||
106 | #define REG_TIMING_VH_L 0x3807 | ||
107 | #define REG_TIMING_DVPHO_H 0x3808 | ||
108 | #define REG_TIMING_DVPHO_L 0x3809 | ||
109 | #define REG_TIMING_DVPVO_H 0x380a | ||
110 | #define REG_TIMING_DVPVO_L 0x380b | ||
111 | #define REG_TIMING_HTS_H 0x380c | ||
112 | #define REG_TIMING_HTS_L 0x380d | ||
113 | #define REG_TIMING_VTS_H 0x380e | ||
114 | #define REG_TIMING_VTS_L 0x380f | ||
115 | #define REG_TIMING_HOFFS_H 0x3810 | ||
116 | #define REG_TIMING_HOFFS_L 0x3811 | ||
117 | #define REG_TIMING_VOFFS_H 0x3812 | ||
118 | #define REG_TIMING_VOFFS_L 0x3813 | ||
119 | #define REG_TIMING_XINC 0x3814 | ||
120 | #define REG_TIMING_YINC 0x3815 | ||
121 | #define REG_TIMING_VERT_FORMAT 0x3820 | ||
122 | #define REG_TIMING_HORIZ_FORMAT 0x3821 | ||
123 | |||
124 | #define REG_FORMAT_CTRL00 0x4300 | ||
125 | |||
126 | #define REG_VFIFO_READ_START_H 0x4608 | ||
127 | #define REG_VFIFO_READ_START_L 0x4609 | ||
128 | |||
129 | #define REG_DVP_CTRL02 0x4708 | ||
130 | |||
131 | #define REG_ISP_CTRL00 0x5000 | ||
132 | #define REG_ISP_CTRL01 0x5001 | ||
133 | #define REG_ISP_CTRL02 0x5002 | ||
134 | |||
135 | #define REG_LENC_RED_X0_H 0x500c | ||
136 | #define REG_LENC_RED_X0_L 0x500d | ||
137 | #define REG_LENC_RED_Y0_H 0x500e | ||
138 | #define REG_LENC_RED_Y0_L 0x500f | ||
139 | #define REG_LENC_RED_A1 0x5010 | ||
140 | #define REG_LENC_RED_B1 0x5011 | ||
141 | #define REG_LENC_RED_A2_B2 0x5012 | ||
142 | #define REG_LENC_GREEN_X0_H 0x5013 | ||
143 | #define REG_LENC_GREEN_X0_L 0x5014 | ||
144 | #define REG_LENC_GREEN_Y0_H 0x5015 | ||
145 | #define REG_LENC_GREEN_Y0_L 0x5016 | ||
146 | #define REG_LENC_GREEN_A1 0x5017 | ||
147 | #define REG_LENC_GREEN_B1 0x5018 | ||
148 | #define REG_LENC_GREEN_A2_B2 0x5019 | ||
149 | #define REG_LENC_BLUE_X0_H 0x501a | ||
150 | #define REG_LENC_BLUE_X0_L 0x501b | ||
151 | #define REG_LENC_BLUE_Y0_H 0x501c | ||
152 | #define REG_LENC_BLUE_Y0_L 0x501d | ||
153 | #define REG_LENC_BLUE_A1 0x501e | ||
154 | #define REG_LENC_BLUE_B1 0x501f | ||
155 | #define REG_LENC_BLUE_A2_B2 0x5020 | ||
156 | |||
157 | #define REG_AWB_CTRL00 0x5035 | ||
158 | #define REG_AWB_CTRL01 0x5036 | ||
159 | #define REG_AWB_CTRL02 0x5037 | ||
160 | #define REG_AWB_CTRL03 0x5038 | ||
161 | #define REG_AWB_CTRL04 0x5039 | ||
162 | #define REG_AWB_LOCAL_LIMIT 0x503a | ||
163 | #define REG_AWB_CTRL12 0x5049 | ||
164 | #define REG_AWB_CTRL13 0x504a | ||
165 | #define REG_AWB_CTRL14 0x504b | ||
166 | |||
167 | #define REG_SHARPENMT_THRESH1 0x5064 | ||
168 | #define REG_SHARPENMT_THRESH2 0x5065 | ||
169 | #define REG_SHARPENMT_OFFSET1 0x5066 | ||
170 | #define REG_SHARPENMT_OFFSET2 0x5067 | ||
171 | #define REG_DENOISE_THRESH1 0x5068 | ||
172 | #define REG_DENOISE_THRESH2 0x5069 | ||
173 | #define REG_DENOISE_OFFSET1 0x506a | ||
174 | #define REG_DENOISE_OFFSET2 0x506b | ||
175 | #define REG_SHARPEN_THRESH1 0x506c | ||
176 | #define REG_SHARPEN_THRESH2 0x506d | ||
177 | #define REG_CIP_CTRL00 0x506e | ||
178 | #define REG_CIP_CTRL01 0x506f | ||
179 | |||
180 | #define REG_CMX_SIGN 0x5079 | ||
181 | #define REG_CMX_MISC_CTRL 0x507a | ||
182 | |||
183 | #define REG_PRE_ISP_CTRL00 0x50a0 | ||
184 | #define TEST_PATTERN_ENABLE BIT(7) | ||
185 | #define VERTICAL_COLOR_BAR_MASK 0x53 | ||
186 | |||
187 | #define REG_NULL 0x0000 /* Array end token */ | ||
188 | |||
189 | #define OV265X_ID(_msb, _lsb) ((_msb) << 8 | (_lsb)) | ||
190 | #define OV2659_ID 0x2656 | ||
191 | |||
192 | struct sensor_register { | ||
193 | u16 addr; | ||
194 | u8 value; | ||
195 | }; | ||
196 | |||
197 | struct ov2659_framesize { | ||
198 | u16 width; | ||
199 | u16 height; | ||
200 | u16 max_exp_lines; | ||
201 | const struct sensor_register *regs; | ||
202 | }; | ||
203 | |||
204 | struct ov2659_pll_ctrl { | ||
205 | u8 ctrl1; | ||
206 | u8 ctrl2; | ||
207 | u8 ctrl3; | ||
208 | }; | ||
209 | |||
210 | struct ov2659_pixfmt { | ||
211 | u32 code; | ||
212 | /* Output format Register Value (REG_FORMAT_CTRL00) */ | ||
213 | struct sensor_register *format_ctrl_regs; | ||
214 | }; | ||
215 | |||
216 | struct pll_ctrl_reg { | ||
217 | unsigned int div; | ||
218 | unsigned char reg; | ||
219 | }; | ||
220 | |||
221 | struct ov2659 { | ||
222 | struct v4l2_subdev sd; | ||
223 | struct media_pad pad; | ||
224 | struct v4l2_mbus_framefmt format; | ||
225 | unsigned int xvclk_frequency; | ||
226 | const struct ov2659_platform_data *pdata; | ||
227 | struct mutex lock; | ||
228 | struct i2c_client *client; | ||
229 | struct v4l2_ctrl_handler ctrls; | ||
230 | struct v4l2_ctrl *link_frequency; | ||
231 | const struct ov2659_framesize *frame_size; | ||
232 | struct sensor_register *format_ctrl_regs; | ||
233 | struct ov2659_pll_ctrl pll; | ||
234 | int streaming; | ||
235 | }; | ||
236 | |||
237 | static const struct sensor_register ov2659_init_regs[] = { | ||
238 | { REG_IO_CTRL00, 0x03 }, | ||
239 | { REG_IO_CTRL01, 0xff }, | ||
240 | { REG_IO_CTRL02, 0xe0 }, | ||
241 | { 0x3633, 0x3d }, | ||
242 | { 0x3620, 0x02 }, | ||
243 | { 0x3631, 0x11 }, | ||
244 | { 0x3612, 0x04 }, | ||
245 | { 0x3630, 0x20 }, | ||
246 | { 0x4702, 0x02 }, | ||
247 | { 0x370c, 0x34 }, | ||
248 | { REG_TIMING_HS_H, 0x00 }, | ||
249 | { REG_TIMING_HS_L, 0x00 }, | ||
250 | { REG_TIMING_VS_H, 0x00 }, | ||
251 | { REG_TIMING_VS_L, 0x00 }, | ||
252 | { REG_TIMING_HW_H, 0x06 }, | ||
253 | { REG_TIMING_HW_L, 0x5f }, | ||
254 | { REG_TIMING_VH_H, 0x04 }, | ||
255 | { REG_TIMING_VH_L, 0xb7 }, | ||
256 | { REG_TIMING_DVPHO_H, 0x03 }, | ||
257 | { REG_TIMING_DVPHO_L, 0x20 }, | ||
258 | { REG_TIMING_DVPVO_H, 0x02 }, | ||
259 | { REG_TIMING_DVPVO_L, 0x58 }, | ||
260 | { REG_TIMING_HTS_H, 0x05 }, | ||
261 | { REG_TIMING_HTS_L, 0x14 }, | ||
262 | { REG_TIMING_VTS_H, 0x02 }, | ||
263 | { REG_TIMING_VTS_L, 0x68 }, | ||
264 | { REG_TIMING_HOFFS_L, 0x08 }, | ||
265 | { REG_TIMING_VOFFS_L, 0x02 }, | ||
266 | { REG_TIMING_XINC, 0x31 }, | ||
267 | { REG_TIMING_YINC, 0x31 }, | ||
268 | { 0x3a02, 0x02 }, | ||
269 | { 0x3a03, 0x68 }, | ||
270 | { 0x3a08, 0x00 }, | ||
271 | { 0x3a09, 0x5c }, | ||
272 | { 0x3a0a, 0x00 }, | ||
273 | { 0x3a0b, 0x4d }, | ||
274 | { 0x3a0d, 0x08 }, | ||
275 | { 0x3a0e, 0x06 }, | ||
276 | { 0x3a14, 0x02 }, | ||
277 | { 0x3a15, 0x28 }, | ||
278 | { REG_DVP_CTRL02, 0x01 }, | ||
279 | { 0x3623, 0x00 }, | ||
280 | { 0x3634, 0x76 }, | ||
281 | { 0x3701, 0x44 }, | ||
282 | { 0x3702, 0x18 }, | ||
283 | { 0x3703, 0x24 }, | ||
284 | { 0x3704, 0x24 }, | ||
285 | { 0x3705, 0x0c }, | ||
286 | { REG_TIMING_VERT_FORMAT, 0x81 }, | ||
287 | { REG_TIMING_HORIZ_FORMAT, 0x01 }, | ||
288 | { 0x370a, 0x52 }, | ||
289 | { REG_VFIFO_READ_START_H, 0x00 }, | ||
290 | { REG_VFIFO_READ_START_L, 0x80 }, | ||
291 | { REG_FORMAT_CTRL00, 0x30 }, | ||
292 | { 0x5086, 0x02 }, | ||
293 | { REG_ISP_CTRL00, 0xfb }, | ||
294 | { REG_ISP_CTRL01, 0x1f }, | ||
295 | { REG_ISP_CTRL02, 0x00 }, | ||
296 | { 0x5025, 0x0e }, | ||
297 | { 0x5026, 0x18 }, | ||
298 | { 0x5027, 0x34 }, | ||
299 | { 0x5028, 0x4c }, | ||
300 | { 0x5029, 0x62 }, | ||
301 | { 0x502a, 0x74 }, | ||
302 | { 0x502b, 0x85 }, | ||
303 | { 0x502c, 0x92 }, | ||
304 | { 0x502d, 0x9e }, | ||
305 | { 0x502e, 0xb2 }, | ||
306 | { 0x502f, 0xc0 }, | ||
307 | { 0x5030, 0xcc }, | ||
308 | { 0x5031, 0xe0 }, | ||
309 | { 0x5032, 0xee }, | ||
310 | { 0x5033, 0xf6 }, | ||
311 | { 0x5034, 0x11 }, | ||
312 | { 0x5070, 0x1c }, | ||
313 | { 0x5071, 0x5b }, | ||
314 | { 0x5072, 0x05 }, | ||
315 | { 0x5073, 0x20 }, | ||
316 | { 0x5074, 0x94 }, | ||
317 | { 0x5075, 0xb4 }, | ||
318 | { 0x5076, 0xb4 }, | ||
319 | { 0x5077, 0xaf }, | ||
320 | { 0x5078, 0x05 }, | ||
321 | { REG_CMX_SIGN, 0x98 }, | ||
322 | { REG_CMX_MISC_CTRL, 0x21 }, | ||
323 | { REG_AWB_CTRL00, 0x6a }, | ||
324 | { REG_AWB_CTRL01, 0x11 }, | ||
325 | { REG_AWB_CTRL02, 0x92 }, | ||
326 | { REG_AWB_CTRL03, 0x21 }, | ||
327 | { REG_AWB_CTRL04, 0xe1 }, | ||
328 | { REG_AWB_LOCAL_LIMIT, 0x01 }, | ||
329 | { 0x503c, 0x05 }, | ||
330 | { 0x503d, 0x08 }, | ||
331 | { 0x503e, 0x08 }, | ||
332 | { 0x503f, 0x64 }, | ||
333 | { 0x5040, 0x58 }, | ||
334 | { 0x5041, 0x2a }, | ||
335 | { 0x5042, 0xc5 }, | ||
336 | { 0x5043, 0x2e }, | ||
337 | { 0x5044, 0x3a }, | ||
338 | { 0x5045, 0x3c }, | ||
339 | { 0x5046, 0x44 }, | ||
340 | { 0x5047, 0xf8 }, | ||
341 | { 0x5048, 0x08 }, | ||
342 | { REG_AWB_CTRL12, 0x70 }, | ||
343 | { REG_AWB_CTRL13, 0xf0 }, | ||
344 | { REG_AWB_CTRL14, 0xf0 }, | ||
345 | { REG_LENC_RED_X0_H, 0x03 }, | ||
346 | { REG_LENC_RED_X0_L, 0x20 }, | ||
347 | { REG_LENC_RED_Y0_H, 0x02 }, | ||
348 | { REG_LENC_RED_Y0_L, 0x5c }, | ||
349 | { REG_LENC_RED_A1, 0x48 }, | ||
350 | { REG_LENC_RED_B1, 0x00 }, | ||
351 | { REG_LENC_RED_A2_B2, 0x66 }, | ||
352 | { REG_LENC_GREEN_X0_H, 0x03 }, | ||
353 | { REG_LENC_GREEN_X0_L, 0x30 }, | ||
354 | { REG_LENC_GREEN_Y0_H, 0x02 }, | ||
355 | { REG_LENC_GREEN_Y0_L, 0x7c }, | ||
356 | { REG_LENC_GREEN_A1, 0x40 }, | ||
357 | { REG_LENC_GREEN_B1, 0x00 }, | ||
358 | { REG_LENC_GREEN_A2_B2, 0x66 }, | ||
359 | { REG_LENC_BLUE_X0_H, 0x03 }, | ||
360 | { REG_LENC_BLUE_X0_L, 0x10 }, | ||
361 | { REG_LENC_BLUE_Y0_H, 0x02 }, | ||
362 | { REG_LENC_BLUE_Y0_L, 0x7c }, | ||
363 | { REG_LENC_BLUE_A1, 0x3a }, | ||
364 | { REG_LENC_BLUE_B1, 0x00 }, | ||
365 | { REG_LENC_BLUE_A2_B2, 0x66 }, | ||
366 | { REG_CIP_CTRL00, 0x44 }, | ||
367 | { REG_SHARPENMT_THRESH1, 0x08 }, | ||
368 | { REG_SHARPENMT_THRESH2, 0x10 }, | ||
369 | { REG_SHARPENMT_OFFSET1, 0x12 }, | ||
370 | { REG_SHARPENMT_OFFSET2, 0x02 }, | ||
371 | { REG_SHARPEN_THRESH1, 0x08 }, | ||
372 | { REG_SHARPEN_THRESH2, 0x10 }, | ||
373 | { REG_CIP_CTRL01, 0xa6 }, | ||
374 | { REG_DENOISE_THRESH1, 0x08 }, | ||
375 | { REG_DENOISE_THRESH2, 0x10 }, | ||
376 | { REG_DENOISE_OFFSET1, 0x04 }, | ||
377 | { REG_DENOISE_OFFSET2, 0x12 }, | ||
378 | { 0x507e, 0x40 }, | ||
379 | { 0x507f, 0x20 }, | ||
380 | { 0x507b, 0x02 }, | ||
381 | { REG_CMX_MISC_CTRL, 0x01 }, | ||
382 | { 0x5084, 0x0c }, | ||
383 | { 0x5085, 0x3e }, | ||
384 | { 0x5005, 0x80 }, | ||
385 | { 0x3a0f, 0x30 }, | ||
386 | { 0x3a10, 0x28 }, | ||
387 | { 0x3a1b, 0x32 }, | ||
388 | { 0x3a1e, 0x26 }, | ||
389 | { 0x3a11, 0x60 }, | ||
390 | { 0x3a1f, 0x14 }, | ||
391 | { 0x5060, 0x69 }, | ||
392 | { 0x5061, 0x7d }, | ||
393 | { 0x5062, 0x7d }, | ||
394 | { 0x5063, 0x69 }, | ||
395 | { REG_NULL, 0x00 }, | ||
396 | }; | ||
397 | |||
398 | /* 1280X720 720p */ | ||
399 | static struct sensor_register ov2659_720p[] = { | ||
400 | { REG_TIMING_HS_H, 0x00 }, | ||
401 | { REG_TIMING_HS_L, 0xa0 }, | ||
402 | { REG_TIMING_VS_H, 0x00 }, | ||
403 | { REG_TIMING_VS_L, 0xf0 }, | ||
404 | { REG_TIMING_HW_H, 0x05 }, | ||
405 | { REG_TIMING_HW_L, 0xbf }, | ||
406 | { REG_TIMING_VH_H, 0x03 }, | ||
407 | { REG_TIMING_VH_L, 0xcb }, | ||
408 | { REG_TIMING_DVPHO_H, 0x05 }, | ||
409 | { REG_TIMING_DVPHO_L, 0x00 }, | ||
410 | { REG_TIMING_DVPVO_H, 0x02 }, | ||
411 | { REG_TIMING_DVPVO_L, 0xd0 }, | ||
412 | { REG_TIMING_HTS_H, 0x06 }, | ||
413 | { REG_TIMING_HTS_L, 0x4c }, | ||
414 | { REG_TIMING_VTS_H, 0x02 }, | ||
415 | { REG_TIMING_VTS_L, 0xe8 }, | ||
416 | { REG_TIMING_HOFFS_L, 0x10 }, | ||
417 | { REG_TIMING_VOFFS_L, 0x06 }, | ||
418 | { REG_TIMING_XINC, 0x11 }, | ||
419 | { REG_TIMING_YINC, 0x11 }, | ||
420 | { REG_TIMING_VERT_FORMAT, 0x80 }, | ||
421 | { REG_TIMING_HORIZ_FORMAT, 0x00 }, | ||
422 | { 0x3a03, 0xe8 }, | ||
423 | { 0x3a09, 0x6f }, | ||
424 | { 0x3a0b, 0x5d }, | ||
425 | { 0x3a15, 0x9a }, | ||
426 | { REG_NULL, 0x00 }, | ||
427 | }; | ||
428 | |||
429 | /* 1600X1200 UXGA */ | ||
430 | static struct sensor_register ov2659_uxga[] = { | ||
431 | { REG_TIMING_HS_H, 0x00 }, | ||
432 | { REG_TIMING_HS_L, 0x00 }, | ||
433 | { REG_TIMING_VS_H, 0x00 }, | ||
434 | { REG_TIMING_VS_L, 0x00 }, | ||
435 | { REG_TIMING_HW_H, 0x06 }, | ||
436 | { REG_TIMING_HW_L, 0x5f }, | ||
437 | { REG_TIMING_VH_H, 0x04 }, | ||
438 | { REG_TIMING_VH_L, 0xbb }, | ||
439 | { REG_TIMING_DVPHO_H, 0x06 }, | ||
440 | { REG_TIMING_DVPHO_L, 0x40 }, | ||
441 | { REG_TIMING_DVPVO_H, 0x04 }, | ||
442 | { REG_TIMING_DVPVO_L, 0xb0 }, | ||
443 | { REG_TIMING_HTS_H, 0x07 }, | ||
444 | { REG_TIMING_HTS_L, 0x9f }, | ||
445 | { REG_TIMING_VTS_H, 0x04 }, | ||
446 | { REG_TIMING_VTS_L, 0xd0 }, | ||
447 | { REG_TIMING_HOFFS_L, 0x10 }, | ||
448 | { REG_TIMING_VOFFS_L, 0x06 }, | ||
449 | { REG_TIMING_XINC, 0x11 }, | ||
450 | { REG_TIMING_YINC, 0x11 }, | ||
451 | { 0x3a02, 0x04 }, | ||
452 | { 0x3a03, 0xd0 }, | ||
453 | { 0x3a08, 0x00 }, | ||
454 | { 0x3a09, 0xb8 }, | ||
455 | { 0x3a0a, 0x00 }, | ||
456 | { 0x3a0b, 0x9a }, | ||
457 | { 0x3a0d, 0x08 }, | ||
458 | { 0x3a0e, 0x06 }, | ||
459 | { 0x3a14, 0x04 }, | ||
460 | { 0x3a15, 0x50 }, | ||
461 | { 0x3623, 0x00 }, | ||
462 | { 0x3634, 0x44 }, | ||
463 | { 0x3701, 0x44 }, | ||
464 | { 0x3702, 0x30 }, | ||
465 | { 0x3703, 0x48 }, | ||
466 | { 0x3704, 0x48 }, | ||
467 | { 0x3705, 0x18 }, | ||
468 | { REG_TIMING_VERT_FORMAT, 0x80 }, | ||
469 | { REG_TIMING_HORIZ_FORMAT, 0x00 }, | ||
470 | { 0x370a, 0x12 }, | ||
471 | { REG_VFIFO_READ_START_H, 0x00 }, | ||
472 | { REG_VFIFO_READ_START_L, 0x80 }, | ||
473 | { REG_ISP_CTRL02, 0x00 }, | ||
474 | { REG_NULL, 0x00 }, | ||
475 | }; | ||
476 | |||
477 | /* 1280X1024 SXGA */ | ||
478 | static struct sensor_register ov2659_sxga[] = { | ||
479 | { REG_TIMING_HS_H, 0x00 }, | ||
480 | { REG_TIMING_HS_L, 0x00 }, | ||
481 | { REG_TIMING_VS_H, 0x00 }, | ||
482 | { REG_TIMING_VS_L, 0x00 }, | ||
483 | { REG_TIMING_HW_H, 0x06 }, | ||
484 | { REG_TIMING_HW_L, 0x5f }, | ||
485 | { REG_TIMING_VH_H, 0x04 }, | ||
486 | { REG_TIMING_VH_L, 0xb7 }, | ||
487 | { REG_TIMING_DVPHO_H, 0x05 }, | ||
488 | { REG_TIMING_DVPHO_L, 0x00 }, | ||
489 | { REG_TIMING_DVPVO_H, 0x04 }, | ||
490 | { REG_TIMING_DVPVO_L, 0x00 }, | ||
491 | { REG_TIMING_HTS_H, 0x07 }, | ||
492 | { REG_TIMING_HTS_L, 0x9c }, | ||
493 | { REG_TIMING_VTS_H, 0x04 }, | ||
494 | { REG_TIMING_VTS_L, 0xd0 }, | ||
495 | { REG_TIMING_HOFFS_L, 0x10 }, | ||
496 | { REG_TIMING_VOFFS_L, 0x06 }, | ||
497 | { REG_TIMING_XINC, 0x11 }, | ||
498 | { REG_TIMING_YINC, 0x11 }, | ||
499 | { 0x3a02, 0x02 }, | ||
500 | { 0x3a03, 0x68 }, | ||
501 | { 0x3a08, 0x00 }, | ||
502 | { 0x3a09, 0x5c }, | ||
503 | { 0x3a0a, 0x00 }, | ||
504 | { 0x3a0b, 0x4d }, | ||
505 | { 0x3a0d, 0x08 }, | ||
506 | { 0x3a0e, 0x06 }, | ||
507 | { 0x3a14, 0x02 }, | ||
508 | { 0x3a15, 0x28 }, | ||
509 | { 0x3623, 0x00 }, | ||
510 | { 0x3634, 0x76 }, | ||
511 | { 0x3701, 0x44 }, | ||
512 | { 0x3702, 0x18 }, | ||
513 | { 0x3703, 0x24 }, | ||
514 | { 0x3704, 0x24 }, | ||
515 | { 0x3705, 0x0c }, | ||
516 | { REG_TIMING_VERT_FORMAT, 0x80 }, | ||
517 | { REG_TIMING_HORIZ_FORMAT, 0x00 }, | ||
518 | { 0x370a, 0x52 }, | ||
519 | { REG_VFIFO_READ_START_H, 0x00 }, | ||
520 | { REG_VFIFO_READ_START_L, 0x80 }, | ||
521 | { REG_ISP_CTRL02, 0x00 }, | ||
522 | { REG_NULL, 0x00 }, | ||
523 | }; | ||
524 | |||
525 | /* 1024X768 SXGA */ | ||
526 | static struct sensor_register ov2659_xga[] = { | ||
527 | { REG_TIMING_HS_H, 0x00 }, | ||
528 | { REG_TIMING_HS_L, 0x00 }, | ||
529 | { REG_TIMING_VS_H, 0x00 }, | ||
530 | { REG_TIMING_VS_L, 0x00 }, | ||
531 | { REG_TIMING_HW_H, 0x06 }, | ||
532 | { REG_TIMING_HW_L, 0x5f }, | ||
533 | { REG_TIMING_VH_H, 0x04 }, | ||
534 | { REG_TIMING_VH_L, 0xb7 }, | ||
535 | { REG_TIMING_DVPHO_H, 0x04 }, | ||
536 | { REG_TIMING_DVPHO_L, 0x00 }, | ||
537 | { REG_TIMING_DVPVO_H, 0x03 }, | ||
538 | { REG_TIMING_DVPVO_L, 0x00 }, | ||
539 | { REG_TIMING_HTS_H, 0x07 }, | ||
540 | { REG_TIMING_HTS_L, 0x9c }, | ||
541 | { REG_TIMING_VTS_H, 0x04 }, | ||
542 | { REG_TIMING_VTS_L, 0xd0 }, | ||
543 | { REG_TIMING_HOFFS_L, 0x10 }, | ||
544 | { REG_TIMING_VOFFS_L, 0x06 }, | ||
545 | { REG_TIMING_XINC, 0x11 }, | ||
546 | { REG_TIMING_YINC, 0x11 }, | ||
547 | { 0x3a02, 0x02 }, | ||
548 | { 0x3a03, 0x68 }, | ||
549 | { 0x3a08, 0x00 }, | ||
550 | { 0x3a09, 0x5c }, | ||
551 | { 0x3a0a, 0x00 }, | ||
552 | { 0x3a0b, 0x4d }, | ||
553 | { 0x3a0d, 0x08 }, | ||
554 | { 0x3a0e, 0x06 }, | ||
555 | { 0x3a14, 0x02 }, | ||
556 | { 0x3a15, 0x28 }, | ||
557 | { 0x3623, 0x00 }, | ||
558 | { 0x3634, 0x76 }, | ||
559 | { 0x3701, 0x44 }, | ||
560 | { 0x3702, 0x18 }, | ||
561 | { 0x3703, 0x24 }, | ||
562 | { 0x3704, 0x24 }, | ||
563 | { 0x3705, 0x0c }, | ||
564 | { REG_TIMING_VERT_FORMAT, 0x80 }, | ||
565 | { REG_TIMING_HORIZ_FORMAT, 0x00 }, | ||
566 | { 0x370a, 0x52 }, | ||
567 | { REG_VFIFO_READ_START_H, 0x00 }, | ||
568 | { REG_VFIFO_READ_START_L, 0x80 }, | ||
569 | { REG_ISP_CTRL02, 0x00 }, | ||
570 | { REG_NULL, 0x00 }, | ||
571 | }; | ||
572 | |||
573 | /* 800X600 SVGA */ | ||
574 | static struct sensor_register ov2659_svga[] = { | ||
575 | { REG_TIMING_HS_H, 0x00 }, | ||
576 | { REG_TIMING_HS_L, 0x00 }, | ||
577 | { REG_TIMING_VS_H, 0x00 }, | ||
578 | { REG_TIMING_VS_L, 0x00 }, | ||
579 | { REG_TIMING_HW_H, 0x06 }, | ||
580 | { REG_TIMING_HW_L, 0x5f }, | ||
581 | { REG_TIMING_VH_H, 0x04 }, | ||
582 | { REG_TIMING_VH_L, 0xb7 }, | ||
583 | { REG_TIMING_DVPHO_H, 0x03 }, | ||
584 | { REG_TIMING_DVPHO_L, 0x20 }, | ||
585 | { REG_TIMING_DVPVO_H, 0x02 }, | ||
586 | { REG_TIMING_DVPVO_L, 0x58 }, | ||
587 | { REG_TIMING_HTS_H, 0x05 }, | ||
588 | { REG_TIMING_HTS_L, 0x14 }, | ||
589 | { REG_TIMING_VTS_H, 0x02 }, | ||
590 | { REG_TIMING_VTS_L, 0x68 }, | ||
591 | { REG_TIMING_HOFFS_L, 0x08 }, | ||
592 | { REG_TIMING_VOFFS_L, 0x02 }, | ||
593 | { REG_TIMING_XINC, 0x31 }, | ||
594 | { REG_TIMING_YINC, 0x31 }, | ||
595 | { 0x3a02, 0x02 }, | ||
596 | { 0x3a03, 0x68 }, | ||
597 | { 0x3a08, 0x00 }, | ||
598 | { 0x3a09, 0x5c }, | ||
599 | { 0x3a0a, 0x00 }, | ||
600 | { 0x3a0b, 0x4d }, | ||
601 | { 0x3a0d, 0x08 }, | ||
602 | { 0x3a0e, 0x06 }, | ||
603 | { 0x3a14, 0x02 }, | ||
604 | { 0x3a15, 0x28 }, | ||
605 | { 0x3623, 0x00 }, | ||
606 | { 0x3634, 0x76 }, | ||
607 | { 0x3701, 0x44 }, | ||
608 | { 0x3702, 0x18 }, | ||
609 | { 0x3703, 0x24 }, | ||
610 | { 0x3704, 0x24 }, | ||
611 | { 0x3705, 0x0c }, | ||
612 | { REG_TIMING_VERT_FORMAT, 0x81 }, | ||
613 | { REG_TIMING_HORIZ_FORMAT, 0x01 }, | ||
614 | { 0x370a, 0x52 }, | ||
615 | { REG_VFIFO_READ_START_H, 0x00 }, | ||
616 | { REG_VFIFO_READ_START_L, 0x80 }, | ||
617 | { REG_ISP_CTRL02, 0x00 }, | ||
618 | { REG_NULL, 0x00 }, | ||
619 | }; | ||
620 | |||
621 | /* 640X480 VGA */ | ||
622 | static struct sensor_register ov2659_vga[] = { | ||
623 | { REG_TIMING_HS_H, 0x00 }, | ||
624 | { REG_TIMING_HS_L, 0x00 }, | ||
625 | { REG_TIMING_VS_H, 0x00 }, | ||
626 | { REG_TIMING_VS_L, 0x00 }, | ||
627 | { REG_TIMING_HW_H, 0x06 }, | ||
628 | { REG_TIMING_HW_L, 0x5f }, | ||
629 | { REG_TIMING_VH_H, 0x04 }, | ||
630 | { REG_TIMING_VH_L, 0xb7 }, | ||
631 | { REG_TIMING_DVPHO_H, 0x02 }, | ||
632 | { REG_TIMING_DVPHO_L, 0x80 }, | ||
633 | { REG_TIMING_DVPVO_H, 0x01 }, | ||
634 | { REG_TIMING_DVPVO_L, 0xe0 }, | ||
635 | { REG_TIMING_HTS_H, 0x05 }, | ||
636 | { REG_TIMING_HTS_L, 0x14 }, | ||
637 | { REG_TIMING_VTS_H, 0x02 }, | ||
638 | { REG_TIMING_VTS_L, 0x68 }, | ||
639 | { REG_TIMING_HOFFS_L, 0x08 }, | ||
640 | { REG_TIMING_VOFFS_L, 0x02 }, | ||
641 | { REG_TIMING_XINC, 0x31 }, | ||
642 | { REG_TIMING_YINC, 0x31 }, | ||
643 | { 0x3a02, 0x02 }, | ||
644 | { 0x3a03, 0x68 }, | ||
645 | { 0x3a08, 0x00 }, | ||
646 | { 0x3a09, 0x5c }, | ||
647 | { 0x3a0a, 0x00 }, | ||
648 | { 0x3a0b, 0x4d }, | ||
649 | { 0x3a0d, 0x08 }, | ||
650 | { 0x3a0e, 0x06 }, | ||
651 | { 0x3a14, 0x02 }, | ||
652 | { 0x3a15, 0x28 }, | ||
653 | { 0x3623, 0x00 }, | ||
654 | { 0x3634, 0x76 }, | ||
655 | { 0x3701, 0x44 }, | ||
656 | { 0x3702, 0x18 }, | ||
657 | { 0x3703, 0x24 }, | ||
658 | { 0x3704, 0x24 }, | ||
659 | { 0x3705, 0x0c }, | ||
660 | { REG_TIMING_VERT_FORMAT, 0x81 }, | ||
661 | { REG_TIMING_HORIZ_FORMAT, 0x01 }, | ||
662 | { 0x370a, 0x52 }, | ||
663 | { REG_VFIFO_READ_START_H, 0x00 }, | ||
664 | { REG_VFIFO_READ_START_L, 0x80 }, | ||
665 | { REG_ISP_CTRL02, 0x10 }, | ||
666 | { REG_NULL, 0x00 }, | ||
667 | }; | ||
668 | |||
669 | /* 320X240 QVGA */ | ||
670 | static struct sensor_register ov2659_qvga[] = { | ||
671 | { REG_TIMING_HS_H, 0x00 }, | ||
672 | { REG_TIMING_HS_L, 0x00 }, | ||
673 | { REG_TIMING_VS_H, 0x00 }, | ||
674 | { REG_TIMING_VS_L, 0x00 }, | ||
675 | { REG_TIMING_HW_H, 0x06 }, | ||
676 | { REG_TIMING_HW_L, 0x5f }, | ||
677 | { REG_TIMING_VH_H, 0x04 }, | ||
678 | { REG_TIMING_VH_L, 0xb7 }, | ||
679 | { REG_TIMING_DVPHO_H, 0x01 }, | ||
680 | { REG_TIMING_DVPHO_L, 0x40 }, | ||
681 | { REG_TIMING_DVPVO_H, 0x00 }, | ||
682 | { REG_TIMING_DVPVO_L, 0xf0 }, | ||
683 | { REG_TIMING_HTS_H, 0x05 }, | ||
684 | { REG_TIMING_HTS_L, 0x14 }, | ||
685 | { REG_TIMING_VTS_H, 0x02 }, | ||
686 | { REG_TIMING_VTS_L, 0x68 }, | ||
687 | { REG_TIMING_HOFFS_L, 0x08 }, | ||
688 | { REG_TIMING_VOFFS_L, 0x02 }, | ||
689 | { REG_TIMING_XINC, 0x31 }, | ||
690 | { REG_TIMING_YINC, 0x31 }, | ||
691 | { 0x3a02, 0x02 }, | ||
692 | { 0x3a03, 0x68 }, | ||
693 | { 0x3a08, 0x00 }, | ||
694 | { 0x3a09, 0x5c }, | ||
695 | { 0x3a0a, 0x00 }, | ||
696 | { 0x3a0b, 0x4d }, | ||
697 | { 0x3a0d, 0x08 }, | ||
698 | { 0x3a0e, 0x06 }, | ||
699 | { 0x3a14, 0x02 }, | ||
700 | { 0x3a15, 0x28 }, | ||
701 | { 0x3623, 0x00 }, | ||
702 | { 0x3634, 0x76 }, | ||
703 | { 0x3701, 0x44 }, | ||
704 | { 0x3702, 0x18 }, | ||
705 | { 0x3703, 0x24 }, | ||
706 | { 0x3704, 0x24 }, | ||
707 | { 0x3705, 0x0c }, | ||
708 | { REG_TIMING_VERT_FORMAT, 0x81 }, | ||
709 | { REG_TIMING_HORIZ_FORMAT, 0x01 }, | ||
710 | { 0x370a, 0x52 }, | ||
711 | { REG_VFIFO_READ_START_H, 0x00 }, | ||
712 | { REG_VFIFO_READ_START_L, 0x80 }, | ||
713 | { REG_ISP_CTRL02, 0x10 }, | ||
714 | { REG_NULL, 0x00 }, | ||
715 | }; | ||
716 | |||
717 | static const struct pll_ctrl_reg ctrl3[] = { | ||
718 | { 1, 0x00 }, | ||
719 | { 2, 0x02 }, | ||
720 | { 3, 0x03 }, | ||
721 | { 4, 0x06 }, | ||
722 | { 6, 0x0d }, | ||
723 | { 8, 0x0e }, | ||
724 | { 12, 0x0f }, | ||
725 | { 16, 0x12 }, | ||
726 | { 24, 0x13 }, | ||
727 | { 32, 0x16 }, | ||
728 | { 48, 0x1b }, | ||
729 | { 64, 0x1e }, | ||
730 | { 96, 0x1f }, | ||
731 | { 0, 0x00 }, | ||
732 | }; | ||
733 | |||
734 | static const struct pll_ctrl_reg ctrl1[] = { | ||
735 | { 2, 0x10 }, | ||
736 | { 4, 0x20 }, | ||
737 | { 6, 0x30 }, | ||
738 | { 8, 0x40 }, | ||
739 | { 10, 0x50 }, | ||
740 | { 12, 0x60 }, | ||
741 | { 14, 0x70 }, | ||
742 | { 16, 0x80 }, | ||
743 | { 18, 0x90 }, | ||
744 | { 20, 0xa0 }, | ||
745 | { 22, 0xb0 }, | ||
746 | { 24, 0xc0 }, | ||
747 | { 26, 0xd0 }, | ||
748 | { 28, 0xe0 }, | ||
749 | { 30, 0xf0 }, | ||
750 | { 0, 0x00 }, | ||
751 | }; | ||
752 | |||
753 | static const struct ov2659_framesize ov2659_framesizes[] = { | ||
754 | { /* QVGA */ | ||
755 | .width = 320, | ||
756 | .height = 240, | ||
757 | .regs = ov2659_qvga, | ||
758 | .max_exp_lines = 248, | ||
759 | }, { /* VGA */ | ||
760 | .width = 640, | ||
761 | .height = 480, | ||
762 | .regs = ov2659_vga, | ||
763 | .max_exp_lines = 498, | ||
764 | }, { /* SVGA */ | ||
765 | .width = 800, | ||
766 | .height = 600, | ||
767 | .regs = ov2659_svga, | ||
768 | .max_exp_lines = 498, | ||
769 | }, { /* XGA */ | ||
770 | .width = 1024, | ||
771 | .height = 768, | ||
772 | .regs = ov2659_xga, | ||
773 | .max_exp_lines = 498, | ||
774 | }, { /* 720P */ | ||
775 | .width = 1280, | ||
776 | .height = 720, | ||
777 | .regs = ov2659_720p, | ||
778 | .max_exp_lines = 498, | ||
779 | }, { /* SXGA */ | ||
780 | .width = 1280, | ||
781 | .height = 1024, | ||
782 | .regs = ov2659_sxga, | ||
783 | .max_exp_lines = 1048, | ||
784 | }, { /* UXGA */ | ||
785 | .width = 1600, | ||
786 | .height = 1200, | ||
787 | .regs = ov2659_uxga, | ||
788 | .max_exp_lines = 498, | ||
789 | }, | ||
790 | }; | ||
791 | |||
792 | /* YUV422 YUYV*/ | ||
793 | static struct sensor_register ov2659_format_yuyv[] = { | ||
794 | { REG_FORMAT_CTRL00, 0x30 }, | ||
795 | { REG_NULL, 0x0 }, | ||
796 | }; | ||
797 | |||
798 | /* YUV422 UYVY */ | ||
799 | static struct sensor_register ov2659_format_uyvy[] = { | ||
800 | { REG_FORMAT_CTRL00, 0x32 }, | ||
801 | { REG_NULL, 0x0 }, | ||
802 | }; | ||
803 | |||
804 | /* Raw Bayer BGGR */ | ||
805 | static struct sensor_register ov2659_format_bggr[] = { | ||
806 | { REG_FORMAT_CTRL00, 0x00 }, | ||
807 | { REG_NULL, 0x0 }, | ||
808 | }; | ||
809 | |||
810 | /* RGB565 */ | ||
811 | static struct sensor_register ov2659_format_rgb565[] = { | ||
812 | { REG_FORMAT_CTRL00, 0x60 }, | ||
813 | { REG_NULL, 0x0 }, | ||
814 | }; | ||
815 | |||
816 | static const struct ov2659_pixfmt ov2659_formats[] = { | ||
817 | { | ||
818 | .code = MEDIA_BUS_FMT_YUYV8_2X8, | ||
819 | .format_ctrl_regs = ov2659_format_yuyv, | ||
820 | }, { | ||
821 | .code = MEDIA_BUS_FMT_UYVY8_2X8, | ||
822 | .format_ctrl_regs = ov2659_format_uyvy, | ||
823 | }, { | ||
824 | .code = MEDIA_BUS_FMT_RGB565_2X8_BE, | ||
825 | .format_ctrl_regs = ov2659_format_rgb565, | ||
826 | }, { | ||
827 | .code = MEDIA_BUS_FMT_SBGGR8_1X8, | ||
828 | .format_ctrl_regs = ov2659_format_bggr, | ||
829 | }, | ||
830 | }; | ||
831 | |||
832 | static inline struct ov2659 *to_ov2659(struct v4l2_subdev *sd) | ||
833 | { | ||
834 | return container_of(sd, struct ov2659, sd); | ||
835 | } | ||
836 | |||
837 | /* sensor register write */ | ||
838 | static int ov2659_write(struct i2c_client *client, u16 reg, u8 val) | ||
839 | { | ||
840 | struct i2c_msg msg; | ||
841 | u8 buf[3]; | ||
842 | int ret; | ||
843 | |||
844 | buf[0] = reg >> 8; | ||
845 | buf[1] = reg & 0xFF; | ||
846 | buf[2] = val; | ||
847 | |||
848 | msg.addr = client->addr; | ||
849 | msg.flags = client->flags; | ||
850 | msg.buf = buf; | ||
851 | msg.len = sizeof(buf); | ||
852 | |||
853 | ret = i2c_transfer(client->adapter, &msg, 1); | ||
854 | if (ret >= 0) | ||
855 | return 0; | ||
856 | |||
857 | dev_dbg(&client->dev, | ||
858 | "ov2659 write reg(0x%x val:0x%x) failed !\n", reg, val); | ||
859 | |||
860 | return ret; | ||
861 | } | ||
862 | |||
863 | /* sensor register read */ | ||
864 | static int ov2659_read(struct i2c_client *client, u16 reg, u8 *val) | ||
865 | { | ||
866 | struct i2c_msg msg[2]; | ||
867 | u8 buf[2]; | ||
868 | int ret; | ||
869 | |||
870 | buf[0] = reg >> 8; | ||
871 | buf[1] = reg & 0xFF; | ||
872 | |||
873 | msg[0].addr = client->addr; | ||
874 | msg[0].flags = client->flags; | ||
875 | msg[0].buf = buf; | ||
876 | msg[0].len = sizeof(buf); | ||
877 | |||
878 | msg[1].addr = client->addr; | ||
879 | msg[1].flags = client->flags | I2C_M_RD; | ||
880 | msg[1].buf = buf; | ||
881 | msg[1].len = 1; | ||
882 | |||
883 | ret = i2c_transfer(client->adapter, msg, 2); | ||
884 | if (ret >= 0) { | ||
885 | *val = buf[0]; | ||
886 | return 0; | ||
887 | } | ||
888 | |||
889 | dev_dbg(&client->dev, | ||
890 | "ov2659 read reg(0x%x val:0x%x) failed !\n", reg, *val); | ||
891 | |||
892 | return ret; | ||
893 | } | ||
894 | |||
895 | static int ov2659_write_array(struct i2c_client *client, | ||
896 | const struct sensor_register *regs) | ||
897 | { | ||
898 | int i, ret = 0; | ||
899 | |||
900 | for (i = 0; ret == 0 && regs[i].addr; i++) | ||
901 | ret = ov2659_write(client, regs[i].addr, regs[i].value); | ||
902 | |||
903 | return ret; | ||
904 | } | ||
905 | |||
906 | static void ov2659_pll_calc_params(struct ov2659 *ov2659) | ||
907 | { | ||
908 | const struct ov2659_platform_data *pdata = ov2659->pdata; | ||
909 | u8 ctrl1_reg = 0, ctrl2_reg = 0, ctrl3_reg = 0; | ||
910 | struct i2c_client *client = ov2659->client; | ||
911 | unsigned int desired = pdata->link_frequency; | ||
912 | u32 s_prediv = 1, s_postdiv = 1, s_mult = 1; | ||
913 | u32 prediv, postdiv, mult; | ||
914 | u32 bestdelta = -1; | ||
915 | u32 delta, actual; | ||
916 | int i, j; | ||
917 | |||
918 | for (i = 0; ctrl1[i].div != 0; i++) { | ||
919 | postdiv = ctrl1[i].div; | ||
920 | for (j = 0; ctrl3[j].div != 0; j++) { | ||
921 | prediv = ctrl3[j].div; | ||
922 | for (mult = 1; mult <= 63; mult++) { | ||
923 | actual = ov2659->xvclk_frequency; | ||
924 | actual *= mult; | ||
925 | actual /= prediv; | ||
926 | actual /= postdiv; | ||
927 | delta = actual - desired; | ||
928 | delta = abs(delta); | ||
929 | |||
930 | if ((delta < bestdelta) || (bestdelta == -1)) { | ||
931 | bestdelta = delta; | ||
932 | s_mult = mult; | ||
933 | s_prediv = prediv; | ||
934 | s_postdiv = postdiv; | ||
935 | ctrl1_reg = ctrl1[i].reg; | ||
936 | ctrl2_reg = mult; | ||
937 | ctrl3_reg = ctrl3[j].reg; | ||
938 | } | ||
939 | } | ||
940 | } | ||
941 | } | ||
942 | |||
943 | ov2659->pll.ctrl1 = ctrl1_reg; | ||
944 | ov2659->pll.ctrl2 = ctrl2_reg; | ||
945 | ov2659->pll.ctrl3 = ctrl3_reg; | ||
946 | |||
947 | dev_dbg(&client->dev, | ||
948 | "Actual reg config: ctrl1_reg: %02x ctrl2_reg: %02x ctrl3_reg: %02x\n", | ||
949 | ctrl1_reg, ctrl2_reg, ctrl3_reg); | ||
950 | } | ||
951 | |||
952 | static int ov2659_set_pixel_clock(struct ov2659 *ov2659) | ||
953 | { | ||
954 | struct i2c_client *client = ov2659->client; | ||
955 | struct sensor_register pll_regs[] = { | ||
956 | {REG_SC_PLL_CTRL1, ov2659->pll.ctrl1}, | ||
957 | {REG_SC_PLL_CTRL2, ov2659->pll.ctrl2}, | ||
958 | {REG_SC_PLL_CTRL3, ov2659->pll.ctrl3}, | ||
959 | {REG_NULL, 0x00}, | ||
960 | }; | ||
961 | |||
962 | dev_dbg(&client->dev, "%s\n", __func__); | ||
963 | |||
964 | return ov2659_write_array(client, pll_regs); | ||
965 | }; | ||
966 | |||
967 | static void ov2659_get_default_format(struct v4l2_mbus_framefmt *format) | ||
968 | { | ||
969 | format->width = ov2659_framesizes[2].width; | ||
970 | format->height = ov2659_framesizes[2].height; | ||
971 | format->colorspace = V4L2_COLORSPACE_SRGB; | ||
972 | format->code = ov2659_formats[0].code; | ||
973 | format->field = V4L2_FIELD_NONE; | ||
974 | } | ||
975 | |||
976 | static void ov2659_set_streaming(struct ov2659 *ov2659, int on) | ||
977 | { | ||
978 | struct i2c_client *client = ov2659->client; | ||
979 | int ret; | ||
980 | |||
981 | on = !!on; | ||
982 | |||
983 | dev_dbg(&client->dev, "%s: on: %d\n", __func__, on); | ||
984 | |||
985 | ret = ov2659_write(client, REG_SOFTWARE_STANDBY, on); | ||
986 | if (ret) | ||
987 | dev_err(&client->dev, "ov2659 soft standby failed\n"); | ||
988 | } | ||
989 | |||
990 | static int ov2659_init(struct v4l2_subdev *sd, u32 val) | ||
991 | { | ||
992 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
993 | |||
994 | return ov2659_write_array(client, ov2659_init_regs); | ||
995 | } | ||
996 | |||
997 | /* | ||
998 | * V4L2 subdev video and pad level operations | ||
999 | */ | ||
1000 | |||
1001 | static int ov2659_enum_mbus_code(struct v4l2_subdev *sd, | ||
1002 | struct v4l2_subdev_pad_config *cfg, | ||
1003 | struct v4l2_subdev_mbus_code_enum *code) | ||
1004 | { | ||
1005 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1006 | |||
1007 | dev_dbg(&client->dev, "%s:\n", __func__); | ||
1008 | |||
1009 | if (code->index >= ARRAY_SIZE(ov2659_formats)) | ||
1010 | return -EINVAL; | ||
1011 | |||
1012 | code->code = ov2659_formats[code->index].code; | ||
1013 | |||
1014 | return 0; | ||
1015 | } | ||
1016 | |||
1017 | static int ov2659_enum_frame_sizes(struct v4l2_subdev *sd, | ||
1018 | struct v4l2_subdev_pad_config *cfg, | ||
1019 | struct v4l2_subdev_frame_size_enum *fse) | ||
1020 | { | ||
1021 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1022 | int i = ARRAY_SIZE(ov2659_formats); | ||
1023 | |||
1024 | dev_dbg(&client->dev, "%s:\n", __func__); | ||
1025 | |||
1026 | if (fse->index >= ARRAY_SIZE(ov2659_framesizes)) | ||
1027 | return -EINVAL; | ||
1028 | |||
1029 | while (--i) | ||
1030 | if (fse->code == ov2659_formats[i].code) | ||
1031 | break; | ||
1032 | |||
1033 | fse->code = ov2659_formats[i].code; | ||
1034 | |||
1035 | fse->min_width = ov2659_framesizes[fse->index].width; | ||
1036 | fse->max_width = fse->min_width; | ||
1037 | fse->max_height = ov2659_framesizes[fse->index].height; | ||
1038 | fse->min_height = fse->max_height; | ||
1039 | |||
1040 | return 0; | ||
1041 | } | ||
1042 | |||
1043 | static int ov2659_get_fmt(struct v4l2_subdev *sd, | ||
1044 | struct v4l2_subdev_pad_config *cfg, | ||
1045 | struct v4l2_subdev_format *fmt) | ||
1046 | { | ||
1047 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1048 | struct ov2659 *ov2659 = to_ov2659(sd); | ||
1049 | struct v4l2_mbus_framefmt *mf; | ||
1050 | |||
1051 | dev_dbg(&client->dev, "ov2659_get_fmt\n"); | ||
1052 | |||
1053 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { | ||
1054 | mf = v4l2_subdev_get_try_format(sd, cfg, 0); | ||
1055 | mutex_lock(&ov2659->lock); | ||
1056 | fmt->format = *mf; | ||
1057 | mutex_unlock(&ov2659->lock); | ||
1058 | return 0; | ||
1059 | } | ||
1060 | |||
1061 | mutex_lock(&ov2659->lock); | ||
1062 | fmt->format = ov2659->format; | ||
1063 | mutex_unlock(&ov2659->lock); | ||
1064 | |||
1065 | dev_dbg(&client->dev, "ov2659_get_fmt: %x %dx%d\n", | ||
1066 | ov2659->format.code, ov2659->format.width, | ||
1067 | ov2659->format.height); | ||
1068 | |||
1069 | return 0; | ||
1070 | } | ||
1071 | |||
1072 | static void __ov2659_try_frame_size(struct v4l2_mbus_framefmt *mf, | ||
1073 | const struct ov2659_framesize **size) | ||
1074 | { | ||
1075 | const struct ov2659_framesize *fsize = &ov2659_framesizes[0]; | ||
1076 | const struct ov2659_framesize *match = NULL; | ||
1077 | int i = ARRAY_SIZE(ov2659_framesizes); | ||
1078 | unsigned int min_err = UINT_MAX; | ||
1079 | |||
1080 | while (i--) { | ||
1081 | int err = abs(fsize->width - mf->width) | ||
1082 | + abs(fsize->height - mf->height); | ||
1083 | if ((err < min_err) && (fsize->regs[0].addr)) { | ||
1084 | min_err = err; | ||
1085 | match = fsize; | ||
1086 | } | ||
1087 | fsize++; | ||
1088 | } | ||
1089 | |||
1090 | if (!match) | ||
1091 | match = &ov2659_framesizes[2]; | ||
1092 | |||
1093 | mf->width = match->width; | ||
1094 | mf->height = match->height; | ||
1095 | |||
1096 | if (size) | ||
1097 | *size = match; | ||
1098 | } | ||
1099 | |||
1100 | static int ov2659_set_fmt(struct v4l2_subdev *sd, | ||
1101 | struct v4l2_subdev_pad_config *cfg, | ||
1102 | struct v4l2_subdev_format *fmt) | ||
1103 | { | ||
1104 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1105 | unsigned int index = ARRAY_SIZE(ov2659_formats); | ||
1106 | struct v4l2_mbus_framefmt *mf = &fmt->format; | ||
1107 | const struct ov2659_framesize *size = NULL; | ||
1108 | struct ov2659 *ov2659 = to_ov2659(sd); | ||
1109 | int ret = 0; | ||
1110 | |||
1111 | dev_dbg(&client->dev, "ov2659_set_fmt\n"); | ||
1112 | |||
1113 | __ov2659_try_frame_size(mf, &size); | ||
1114 | |||
1115 | while (--index >= 0) | ||
1116 | if (ov2659_formats[index].code == mf->code) | ||
1117 | break; | ||
1118 | |||
1119 | if (index < 0) | ||
1120 | return -EINVAL; | ||
1121 | |||
1122 | mf->colorspace = V4L2_COLORSPACE_SRGB; | ||
1123 | mf->code = ov2659_formats[index].code; | ||
1124 | mf->field = V4L2_FIELD_NONE; | ||
1125 | |||
1126 | mutex_lock(&ov2659->lock); | ||
1127 | |||
1128 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { | ||
1129 | mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); | ||
1130 | *mf = fmt->format; | ||
1131 | } else { | ||
1132 | s64 val; | ||
1133 | |||
1134 | if (ov2659->streaming) { | ||
1135 | mutex_unlock(&ov2659->lock); | ||
1136 | return -EBUSY; | ||
1137 | } | ||
1138 | |||
1139 | ov2659->frame_size = size; | ||
1140 | ov2659->format = fmt->format; | ||
1141 | ov2659->format_ctrl_regs = | ||
1142 | ov2659_formats[index].format_ctrl_regs; | ||
1143 | |||
1144 | if (ov2659->format.code != MEDIA_BUS_FMT_SBGGR8_1X8) | ||
1145 | val = ov2659->pdata->link_frequency / 2; | ||
1146 | else | ||
1147 | val = ov2659->pdata->link_frequency; | ||
1148 | |||
1149 | ret = v4l2_ctrl_s_ctrl_int64(ov2659->link_frequency, val); | ||
1150 | if (ret < 0) | ||
1151 | dev_warn(&client->dev, | ||
1152 | "failed to set link_frequency rate (%d)\n", | ||
1153 | ret); | ||
1154 | } | ||
1155 | |||
1156 | mutex_unlock(&ov2659->lock); | ||
1157 | return ret; | ||
1158 | } | ||
1159 | |||
1160 | static int ov2659_set_frame_size(struct ov2659 *ov2659) | ||
1161 | { | ||
1162 | struct i2c_client *client = ov2659->client; | ||
1163 | |||
1164 | dev_dbg(&client->dev, "%s\n", __func__); | ||
1165 | |||
1166 | return ov2659_write_array(ov2659->client, ov2659->frame_size->regs); | ||
1167 | } | ||
1168 | |||
1169 | static int ov2659_set_format(struct ov2659 *ov2659) | ||
1170 | { | ||
1171 | struct i2c_client *client = ov2659->client; | ||
1172 | |||
1173 | dev_dbg(&client->dev, "%s\n", __func__); | ||
1174 | |||
1175 | return ov2659_write_array(ov2659->client, ov2659->format_ctrl_regs); | ||
1176 | } | ||
1177 | |||
1178 | static int ov2659_s_stream(struct v4l2_subdev *sd, int on) | ||
1179 | { | ||
1180 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1181 | struct ov2659 *ov2659 = to_ov2659(sd); | ||
1182 | int ret = 0; | ||
1183 | |||
1184 | dev_dbg(&client->dev, "%s: on: %d\n", __func__, on); | ||
1185 | |||
1186 | mutex_lock(&ov2659->lock); | ||
1187 | |||
1188 | on = !!on; | ||
1189 | |||
1190 | if (ov2659->streaming == on) | ||
1191 | goto unlock; | ||
1192 | |||
1193 | if (!on) { | ||
1194 | /* Stop Streaming Sequence */ | ||
1195 | ov2659_set_streaming(ov2659, 0); | ||
1196 | ov2659->streaming = on; | ||
1197 | goto unlock; | ||
1198 | } | ||
1199 | |||
1200 | ov2659_set_pixel_clock(ov2659); | ||
1201 | ov2659_set_frame_size(ov2659); | ||
1202 | ov2659_set_format(ov2659); | ||
1203 | ov2659_set_streaming(ov2659, 1); | ||
1204 | ov2659->streaming = on; | ||
1205 | |||
1206 | unlock: | ||
1207 | mutex_unlock(&ov2659->lock); | ||
1208 | return ret; | ||
1209 | } | ||
1210 | |||
1211 | static int ov2659_set_test_pattern(struct ov2659 *ov2659, int value) | ||
1212 | { | ||
1213 | struct i2c_client *client = v4l2_get_subdevdata(&ov2659->sd); | ||
1214 | int ret; | ||
1215 | u8 val; | ||
1216 | |||
1217 | ret = ov2659_read(client, REG_PRE_ISP_CTRL00, &val); | ||
1218 | if (ret < 0) | ||
1219 | return ret; | ||
1220 | |||
1221 | switch (value) { | ||
1222 | case 0: | ||
1223 | val &= ~TEST_PATTERN_ENABLE; | ||
1224 | break; | ||
1225 | case 1: | ||
1226 | val &= VERTICAL_COLOR_BAR_MASK; | ||
1227 | val |= TEST_PATTERN_ENABLE; | ||
1228 | break; | ||
1229 | } | ||
1230 | |||
1231 | return ov2659_write(client, REG_PRE_ISP_CTRL00, val); | ||
1232 | } | ||
1233 | |||
1234 | static int ov2659_s_ctrl(struct v4l2_ctrl *ctrl) | ||
1235 | { | ||
1236 | struct ov2659 *ov2659 = | ||
1237 | container_of(ctrl->handler, struct ov2659, ctrls); | ||
1238 | |||
1239 | switch (ctrl->id) { | ||
1240 | case V4L2_CID_TEST_PATTERN: | ||
1241 | return ov2659_set_test_pattern(ov2659, ctrl->val); | ||
1242 | } | ||
1243 | |||
1244 | return 0; | ||
1245 | } | ||
1246 | |||
1247 | static struct v4l2_ctrl_ops ov2659_ctrl_ops = { | ||
1248 | .s_ctrl = ov2659_s_ctrl, | ||
1249 | }; | ||
1250 | |||
1251 | static const char * const ov2659_test_pattern_menu[] = { | ||
1252 | "Disabled", | ||
1253 | "Vertical Color Bars", | ||
1254 | }; | ||
1255 | |||
1256 | /* ----------------------------------------------------------------------------- | ||
1257 | * V4L2 subdev internal operations | ||
1258 | */ | ||
1259 | |||
1260 | static int ov2659_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) | ||
1261 | { | ||
1262 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1263 | struct v4l2_mbus_framefmt *format = | ||
1264 | v4l2_subdev_get_try_format(sd, fh->pad, 0); | ||
1265 | |||
1266 | dev_dbg(&client->dev, "%s:\n", __func__); | ||
1267 | |||
1268 | ov2659_get_default_format(format); | ||
1269 | |||
1270 | return 0; | ||
1271 | } | ||
1272 | |||
1273 | static const struct v4l2_subdev_core_ops ov2659_subdev_core_ops = { | ||
1274 | .log_status = v4l2_ctrl_subdev_log_status, | ||
1275 | .subscribe_event = v4l2_ctrl_subdev_subscribe_event, | ||
1276 | .unsubscribe_event = v4l2_event_subdev_unsubscribe, | ||
1277 | }; | ||
1278 | |||
1279 | static const struct v4l2_subdev_video_ops ov2659_subdev_video_ops = { | ||
1280 | .s_stream = ov2659_s_stream, | ||
1281 | }; | ||
1282 | |||
1283 | static const struct v4l2_subdev_pad_ops ov2659_subdev_pad_ops = { | ||
1284 | .enum_mbus_code = ov2659_enum_mbus_code, | ||
1285 | .enum_frame_size = ov2659_enum_frame_sizes, | ||
1286 | .get_fmt = ov2659_get_fmt, | ||
1287 | .set_fmt = ov2659_set_fmt, | ||
1288 | }; | ||
1289 | |||
1290 | static const struct v4l2_subdev_ops ov2659_subdev_ops = { | ||
1291 | .core = &ov2659_subdev_core_ops, | ||
1292 | .video = &ov2659_subdev_video_ops, | ||
1293 | .pad = &ov2659_subdev_pad_ops, | ||
1294 | }; | ||
1295 | |||
1296 | static const struct v4l2_subdev_internal_ops ov2659_subdev_internal_ops = { | ||
1297 | .open = ov2659_open, | ||
1298 | }; | ||
1299 | |||
1300 | static int ov2659_detect(struct v4l2_subdev *sd) | ||
1301 | { | ||
1302 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1303 | u8 pid, ver; | ||
1304 | int ret; | ||
1305 | |||
1306 | dev_dbg(&client->dev, "%s:\n", __func__); | ||
1307 | |||
1308 | ret = ov2659_write(client, REG_SOFTWARE_RESET, 0x01); | ||
1309 | if (ret != 0) { | ||
1310 | dev_err(&client->dev, "Sensor soft reset failed\n"); | ||
1311 | return -ENODEV; | ||
1312 | } | ||
1313 | usleep_range(1000, 2000); | ||
1314 | |||
1315 | ret = ov2659_init(sd, 0); | ||
1316 | if (ret < 0) | ||
1317 | return ret; | ||
1318 | |||
1319 | /* Check sensor revision */ | ||
1320 | ret = ov2659_read(client, REG_SC_CHIP_ID_H, &pid); | ||
1321 | if (!ret) | ||
1322 | ret = ov2659_read(client, REG_SC_CHIP_ID_L, &ver); | ||
1323 | |||
1324 | if (!ret) { | ||
1325 | unsigned short id; | ||
1326 | |||
1327 | id = OV265X_ID(pid, ver); | ||
1328 | if (id != OV2659_ID) | ||
1329 | dev_err(&client->dev, | ||
1330 | "Sensor detection failed (%04X, %d)\n", | ||
1331 | id, ret); | ||
1332 | else | ||
1333 | dev_info(&client->dev, "Found OV%04X sensor\n", id); | ||
1334 | } | ||
1335 | |||
1336 | return ret; | ||
1337 | } | ||
1338 | |||
1339 | static struct ov2659_platform_data * | ||
1340 | ov2659_get_pdata(struct i2c_client *client) | ||
1341 | { | ||
1342 | struct ov2659_platform_data *pdata; | ||
1343 | struct device_node *endpoint; | ||
1344 | int ret; | ||
1345 | |||
1346 | if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node) | ||
1347 | return client->dev.platform_data; | ||
1348 | |||
1349 | endpoint = of_graph_get_next_endpoint(client->dev.of_node, NULL); | ||
1350 | if (!endpoint) | ||
1351 | return NULL; | ||
1352 | |||
1353 | pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); | ||
1354 | if (!pdata) | ||
1355 | goto done; | ||
1356 | |||
1357 | ret = of_property_read_u64(endpoint, "link-frequencies", | ||
1358 | &pdata->link_frequency); | ||
1359 | if (ret) { | ||
1360 | dev_err(&client->dev, "link-frequencies property not found\n"); | ||
1361 | pdata = NULL; | ||
1362 | } | ||
1363 | |||
1364 | done: | ||
1365 | of_node_put(endpoint); | ||
1366 | return pdata; | ||
1367 | } | ||
1368 | |||
1369 | static int ov2659_probe(struct i2c_client *client, | ||
1370 | const struct i2c_device_id *id) | ||
1371 | { | ||
1372 | const struct ov2659_platform_data *pdata = ov2659_get_pdata(client); | ||
1373 | struct v4l2_subdev *sd; | ||
1374 | struct ov2659 *ov2659; | ||
1375 | struct clk *clk; | ||
1376 | int ret; | ||
1377 | |||
1378 | if (!pdata) { | ||
1379 | dev_err(&client->dev, "platform data not specified\n"); | ||
1380 | return -EINVAL; | ||
1381 | } | ||
1382 | |||
1383 | ov2659 = devm_kzalloc(&client->dev, sizeof(*ov2659), GFP_KERNEL); | ||
1384 | if (!ov2659) | ||
1385 | return -ENOMEM; | ||
1386 | |||
1387 | ov2659->pdata = pdata; | ||
1388 | ov2659->client = client; | ||
1389 | |||
1390 | clk = devm_clk_get(&client->dev, "xvclk"); | ||
1391 | if (IS_ERR(clk)) | ||
1392 | return PTR_ERR(clk); | ||
1393 | |||
1394 | ov2659->xvclk_frequency = clk_get_rate(clk); | ||
1395 | if (ov2659->xvclk_frequency < 6000000 || | ||
1396 | ov2659->xvclk_frequency > 27000000) | ||
1397 | return -EINVAL; | ||
1398 | |||
1399 | v4l2_ctrl_handler_init(&ov2659->ctrls, 2); | ||
1400 | ov2659->link_frequency = | ||
1401 | v4l2_ctrl_new_std(&ov2659->ctrls, &ov2659_ctrl_ops, | ||
1402 | V4L2_CID_PIXEL_RATE, | ||
1403 | pdata->link_frequency / 2, | ||
1404 | pdata->link_frequency, 1, | ||
1405 | pdata->link_frequency); | ||
1406 | v4l2_ctrl_new_std_menu_items(&ov2659->ctrls, &ov2659_ctrl_ops, | ||
1407 | V4L2_CID_TEST_PATTERN, | ||
1408 | ARRAY_SIZE(ov2659_test_pattern_menu) - 1, | ||
1409 | 0, 0, ov2659_test_pattern_menu); | ||
1410 | ov2659->sd.ctrl_handler = &ov2659->ctrls; | ||
1411 | |||
1412 | if (ov2659->ctrls.error) { | ||
1413 | dev_err(&client->dev, "%s: control initialization error %d\n", | ||
1414 | __func__, ov2659->ctrls.error); | ||
1415 | return ov2659->ctrls.error; | ||
1416 | } | ||
1417 | |||
1418 | sd = &ov2659->sd; | ||
1419 | client->flags |= I2C_CLIENT_SCCB; | ||
1420 | v4l2_i2c_subdev_init(sd, client, &ov2659_subdev_ops); | ||
1421 | |||
1422 | sd->internal_ops = &ov2659_subdev_internal_ops; | ||
1423 | sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | | ||
1424 | V4L2_SUBDEV_FL_HAS_EVENTS; | ||
1425 | |||
1426 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
1427 | ov2659->pad.flags = MEDIA_PAD_FL_SOURCE; | ||
1428 | sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; | ||
1429 | ret = media_entity_init(&sd->entity, 1, &ov2659->pad, 0); | ||
1430 | if (ret < 0) { | ||
1431 | v4l2_ctrl_handler_free(&ov2659->ctrls); | ||
1432 | return ret; | ||
1433 | } | ||
1434 | #endif | ||
1435 | |||
1436 | mutex_init(&ov2659->lock); | ||
1437 | |||
1438 | ov2659_get_default_format(&ov2659->format); | ||
1439 | ov2659->frame_size = &ov2659_framesizes[2]; | ||
1440 | ov2659->format_ctrl_regs = ov2659_formats[0].format_ctrl_regs; | ||
1441 | |||
1442 | ret = ov2659_detect(sd); | ||
1443 | if (ret < 0) | ||
1444 | goto error; | ||
1445 | |||
1446 | /* Calculate the PLL register value needed */ | ||
1447 | ov2659_pll_calc_params(ov2659); | ||
1448 | |||
1449 | ret = v4l2_async_register_subdev(&ov2659->sd); | ||
1450 | if (ret) | ||
1451 | goto error; | ||
1452 | |||
1453 | dev_info(&client->dev, "%s sensor driver registered !!\n", sd->name); | ||
1454 | |||
1455 | return 0; | ||
1456 | |||
1457 | error: | ||
1458 | v4l2_ctrl_handler_free(&ov2659->ctrls); | ||
1459 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
1460 | media_entity_cleanup(&sd->entity); | ||
1461 | #endif | ||
1462 | mutex_destroy(&ov2659->lock); | ||
1463 | return ret; | ||
1464 | } | ||
1465 | |||
1466 | static int ov2659_remove(struct i2c_client *client) | ||
1467 | { | ||
1468 | struct v4l2_subdev *sd = i2c_get_clientdata(client); | ||
1469 | struct ov2659 *ov2659 = to_ov2659(sd); | ||
1470 | |||
1471 | v4l2_ctrl_handler_free(&ov2659->ctrls); | ||
1472 | v4l2_async_unregister_subdev(sd); | ||
1473 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
1474 | media_entity_cleanup(&sd->entity); | ||
1475 | #endif | ||
1476 | mutex_destroy(&ov2659->lock); | ||
1477 | |||
1478 | return 0; | ||
1479 | } | ||
1480 | |||
1481 | static const struct i2c_device_id ov2659_id[] = { | ||
1482 | { "ov2659", 0 }, | ||
1483 | { /* sentinel */ }, | ||
1484 | }; | ||
1485 | MODULE_DEVICE_TABLE(i2c, ov2659_id); | ||
1486 | |||
1487 | #if IS_ENABLED(CONFIG_OF) | ||
1488 | static const struct of_device_id ov2659_of_match[] = { | ||
1489 | { .compatible = "ovti,ov2659", }, | ||
1490 | { /* sentinel */ }, | ||
1491 | }; | ||
1492 | MODULE_DEVICE_TABLE(of, ov2659_of_match); | ||
1493 | #endif | ||
1494 | |||
1495 | static struct i2c_driver ov2659_i2c_driver = { | ||
1496 | .driver = { | ||
1497 | .name = DRIVER_NAME, | ||
1498 | .of_match_table = of_match_ptr(ov2659_of_match), | ||
1499 | }, | ||
1500 | .probe = ov2659_probe, | ||
1501 | .remove = ov2659_remove, | ||
1502 | .id_table = ov2659_id, | ||
1503 | }; | ||
1504 | |||
1505 | module_i2c_driver(ov2659_i2c_driver); | ||
1506 | |||
1507 | MODULE_AUTHOR("Benoit Parrot <bparrot@ti.com>"); | ||
1508 | MODULE_DESCRIPTION("OV2659 CMOS Image Sensor driver"); | ||
1509 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c index 957927f7a353..b9847527eb5a 100644 --- a/drivers/media/i2c/ov7670.c +++ b/drivers/media/i2c/ov7670.c | |||
@@ -1069,29 +1069,35 @@ static int ov7670_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) | |||
1069 | 1069 | ||
1070 | static int ov7670_frame_rates[] = { 30, 15, 10, 5, 1 }; | 1070 | static int ov7670_frame_rates[] = { 30, 15, 10, 5, 1 }; |
1071 | 1071 | ||
1072 | static int ov7670_enum_frameintervals(struct v4l2_subdev *sd, | 1072 | static int ov7670_enum_frame_interval(struct v4l2_subdev *sd, |
1073 | struct v4l2_frmivalenum *interval) | 1073 | struct v4l2_subdev_pad_config *cfg, |
1074 | struct v4l2_subdev_frame_interval_enum *fie) | ||
1074 | { | 1075 | { |
1075 | if (interval->index >= ARRAY_SIZE(ov7670_frame_rates)) | 1076 | if (fie->pad) |
1076 | return -EINVAL; | 1077 | return -EINVAL; |
1077 | interval->type = V4L2_FRMIVAL_TYPE_DISCRETE; | 1078 | if (fie->index >= ARRAY_SIZE(ov7670_frame_rates)) |
1078 | interval->discrete.numerator = 1; | 1079 | return -EINVAL; |
1079 | interval->discrete.denominator = ov7670_frame_rates[interval->index]; | 1080 | fie->interval.numerator = 1; |
1081 | fie->interval.denominator = ov7670_frame_rates[fie->index]; | ||
1080 | return 0; | 1082 | return 0; |
1081 | } | 1083 | } |
1082 | 1084 | ||
1083 | /* | 1085 | /* |
1084 | * Frame size enumeration | 1086 | * Frame size enumeration |
1085 | */ | 1087 | */ |
1086 | static int ov7670_enum_framesizes(struct v4l2_subdev *sd, | 1088 | static int ov7670_enum_frame_size(struct v4l2_subdev *sd, |
1087 | struct v4l2_frmsizeenum *fsize) | 1089 | struct v4l2_subdev_pad_config *cfg, |
1090 | struct v4l2_subdev_frame_size_enum *fse) | ||
1088 | { | 1091 | { |
1089 | struct ov7670_info *info = to_state(sd); | 1092 | struct ov7670_info *info = to_state(sd); |
1090 | int i; | 1093 | int i; |
1091 | int num_valid = -1; | 1094 | int num_valid = -1; |
1092 | __u32 index = fsize->index; | 1095 | __u32 index = fse->index; |
1093 | unsigned int n_win_sizes = info->devtype->n_win_sizes; | 1096 | unsigned int n_win_sizes = info->devtype->n_win_sizes; |
1094 | 1097 | ||
1098 | if (fse->pad) | ||
1099 | return -EINVAL; | ||
1100 | |||
1095 | /* | 1101 | /* |
1096 | * If a minimum width/height was requested, filter out the capture | 1102 | * If a minimum width/height was requested, filter out the capture |
1097 | * windows that fall outside that. | 1103 | * windows that fall outside that. |
@@ -1103,9 +1109,8 @@ static int ov7670_enum_framesizes(struct v4l2_subdev *sd, | |||
1103 | if (info->min_height && win->height < info->min_height) | 1109 | if (info->min_height && win->height < info->min_height) |
1104 | continue; | 1110 | continue; |
1105 | if (index == ++num_valid) { | 1111 | if (index == ++num_valid) { |
1106 | fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; | 1112 | fse->min_width = fse->max_width = win->width; |
1107 | fsize->discrete.width = win->width; | 1113 | fse->min_height = fse->max_height = win->height; |
1108 | fsize->discrete.height = win->height; | ||
1109 | return 0; | 1114 | return 0; |
1110 | } | 1115 | } |
1111 | } | 1116 | } |
@@ -1485,13 +1490,17 @@ static const struct v4l2_subdev_video_ops ov7670_video_ops = { | |||
1485 | .s_mbus_fmt = ov7670_s_mbus_fmt, | 1490 | .s_mbus_fmt = ov7670_s_mbus_fmt, |
1486 | .s_parm = ov7670_s_parm, | 1491 | .s_parm = ov7670_s_parm, |
1487 | .g_parm = ov7670_g_parm, | 1492 | .g_parm = ov7670_g_parm, |
1488 | .enum_frameintervals = ov7670_enum_frameintervals, | 1493 | }; |
1489 | .enum_framesizes = ov7670_enum_framesizes, | 1494 | |
1495 | static const struct v4l2_subdev_pad_ops ov7670_pad_ops = { | ||
1496 | .enum_frame_interval = ov7670_enum_frame_interval, | ||
1497 | .enum_frame_size = ov7670_enum_frame_size, | ||
1490 | }; | 1498 | }; |
1491 | 1499 | ||
1492 | static const struct v4l2_subdev_ops ov7670_ops = { | 1500 | static const struct v4l2_subdev_ops ov7670_ops = { |
1493 | .core = &ov7670_core_ops, | 1501 | .core = &ov7670_core_ops, |
1494 | .video = &ov7670_video_ops, | 1502 | .video = &ov7670_video_ops, |
1503 | .pad = &ov7670_pad_ops, | ||
1495 | }; | 1504 | }; |
1496 | 1505 | ||
1497 | /* ----------------------------------------------------------------------- */ | 1506 | /* ----------------------------------------------------------------------- */ |
diff --git a/drivers/media/i2c/ov9650.c b/drivers/media/i2c/ov9650.c index 2246bd5436ad..2bc473385c91 100644 --- a/drivers/media/i2c/ov9650.c +++ b/drivers/media/i2c/ov9650.c | |||
@@ -1067,7 +1067,7 @@ static void ov965x_get_default_format(struct v4l2_mbus_framefmt *mf) | |||
1067 | } | 1067 | } |
1068 | 1068 | ||
1069 | static int ov965x_enum_mbus_code(struct v4l2_subdev *sd, | 1069 | static int ov965x_enum_mbus_code(struct v4l2_subdev *sd, |
1070 | struct v4l2_subdev_fh *fh, | 1070 | struct v4l2_subdev_pad_config *cfg, |
1071 | struct v4l2_subdev_mbus_code_enum *code) | 1071 | struct v4l2_subdev_mbus_code_enum *code) |
1072 | { | 1072 | { |
1073 | if (code->index >= ARRAY_SIZE(ov965x_formats)) | 1073 | if (code->index >= ARRAY_SIZE(ov965x_formats)) |
@@ -1078,7 +1078,7 @@ static int ov965x_enum_mbus_code(struct v4l2_subdev *sd, | |||
1078 | } | 1078 | } |
1079 | 1079 | ||
1080 | static int ov965x_enum_frame_sizes(struct v4l2_subdev *sd, | 1080 | static int ov965x_enum_frame_sizes(struct v4l2_subdev *sd, |
1081 | struct v4l2_subdev_fh *fh, | 1081 | struct v4l2_subdev_pad_config *cfg, |
1082 | struct v4l2_subdev_frame_size_enum *fse) | 1082 | struct v4l2_subdev_frame_size_enum *fse) |
1083 | { | 1083 | { |
1084 | int i = ARRAY_SIZE(ov965x_formats); | 1084 | int i = ARRAY_SIZE(ov965x_formats); |
@@ -1164,14 +1164,14 @@ static int ov965x_s_frame_interval(struct v4l2_subdev *sd, | |||
1164 | return ret; | 1164 | return ret; |
1165 | } | 1165 | } |
1166 | 1166 | ||
1167 | static int ov965x_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | 1167 | static int ov965x_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, |
1168 | struct v4l2_subdev_format *fmt) | 1168 | struct v4l2_subdev_format *fmt) |
1169 | { | 1169 | { |
1170 | struct ov965x *ov965x = to_ov965x(sd); | 1170 | struct ov965x *ov965x = to_ov965x(sd); |
1171 | struct v4l2_mbus_framefmt *mf; | 1171 | struct v4l2_mbus_framefmt *mf; |
1172 | 1172 | ||
1173 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { | 1173 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { |
1174 | mf = v4l2_subdev_get_try_format(fh, 0); | 1174 | mf = v4l2_subdev_get_try_format(sd, cfg, 0); |
1175 | fmt->format = *mf; | 1175 | fmt->format = *mf; |
1176 | return 0; | 1176 | return 0; |
1177 | } | 1177 | } |
@@ -1208,7 +1208,7 @@ static void __ov965x_try_frame_size(struct v4l2_mbus_framefmt *mf, | |||
1208 | *size = match; | 1208 | *size = match; |
1209 | } | 1209 | } |
1210 | 1210 | ||
1211 | static int ov965x_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | 1211 | static int ov965x_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, |
1212 | struct v4l2_subdev_format *fmt) | 1212 | struct v4l2_subdev_format *fmt) |
1213 | { | 1213 | { |
1214 | unsigned int index = ARRAY_SIZE(ov965x_formats); | 1214 | unsigned int index = ARRAY_SIZE(ov965x_formats); |
@@ -1230,8 +1230,8 @@ static int ov965x_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
1230 | mutex_lock(&ov965x->lock); | 1230 | mutex_lock(&ov965x->lock); |
1231 | 1231 | ||
1232 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { | 1232 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { |
1233 | if (fh != NULL) { | 1233 | if (cfg != NULL) { |
1234 | mf = v4l2_subdev_get_try_format(fh, fmt->pad); | 1234 | mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); |
1235 | *mf = fmt->format; | 1235 | *mf = fmt->format; |
1236 | } | 1236 | } |
1237 | } else { | 1237 | } else { |
@@ -1361,7 +1361,7 @@ static int ov965x_s_stream(struct v4l2_subdev *sd, int on) | |||
1361 | */ | 1361 | */ |
1362 | static int ov965x_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) | 1362 | static int ov965x_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) |
1363 | { | 1363 | { |
1364 | struct v4l2_mbus_framefmt *mf = v4l2_subdev_get_try_format(fh, 0); | 1364 | struct v4l2_mbus_framefmt *mf = v4l2_subdev_get_try_format(sd, fh->pad, 0); |
1365 | 1365 | ||
1366 | ov965x_get_default_format(mf); | 1366 | ov965x_get_default_format(mf); |
1367 | return 0; | 1367 | return 0; |
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c index ee0f57e01b56..08b234bd2962 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c +++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c | |||
@@ -824,10 +824,11 @@ static const struct s5c73m3_frame_size *s5c73m3_find_frame_size( | |||
824 | } | 824 | } |
825 | 825 | ||
826 | static void s5c73m3_oif_try_format(struct s5c73m3 *state, | 826 | static void s5c73m3_oif_try_format(struct s5c73m3 *state, |
827 | struct v4l2_subdev_fh *fh, | 827 | struct v4l2_subdev_pad_config *cfg, |
828 | struct v4l2_subdev_format *fmt, | 828 | struct v4l2_subdev_format *fmt, |
829 | const struct s5c73m3_frame_size **fs) | 829 | const struct s5c73m3_frame_size **fs) |
830 | { | 830 | { |
831 | struct v4l2_subdev *sd = &state->sensor_sd; | ||
831 | u32 code; | 832 | u32 code; |
832 | 833 | ||
833 | switch (fmt->pad) { | 834 | switch (fmt->pad) { |
@@ -850,7 +851,7 @@ static void s5c73m3_oif_try_format(struct s5c73m3 *state, | |||
850 | *fs = state->oif_pix_size[RES_ISP]; | 851 | *fs = state->oif_pix_size[RES_ISP]; |
851 | else | 852 | else |
852 | *fs = s5c73m3_find_frame_size( | 853 | *fs = s5c73m3_find_frame_size( |
853 | v4l2_subdev_get_try_format(fh, | 854 | v4l2_subdev_get_try_format(sd, cfg, |
854 | OIF_ISP_PAD), | 855 | OIF_ISP_PAD), |
855 | RES_ISP); | 856 | RES_ISP); |
856 | break; | 857 | break; |
@@ -860,7 +861,7 @@ static void s5c73m3_oif_try_format(struct s5c73m3 *state, | |||
860 | } | 861 | } |
861 | 862 | ||
862 | static void s5c73m3_try_format(struct s5c73m3 *state, | 863 | static void s5c73m3_try_format(struct s5c73m3 *state, |
863 | struct v4l2_subdev_fh *fh, | 864 | struct v4l2_subdev_pad_config *cfg, |
864 | struct v4l2_subdev_format *fmt, | 865 | struct v4l2_subdev_format *fmt, |
865 | const struct s5c73m3_frame_size **fs) | 866 | const struct s5c73m3_frame_size **fs) |
866 | { | 867 | { |
@@ -952,7 +953,7 @@ static int s5c73m3_oif_s_frame_interval(struct v4l2_subdev *sd, | |||
952 | } | 953 | } |
953 | 954 | ||
954 | static int s5c73m3_oif_enum_frame_interval(struct v4l2_subdev *sd, | 955 | static int s5c73m3_oif_enum_frame_interval(struct v4l2_subdev *sd, |
955 | struct v4l2_subdev_fh *fh, | 956 | struct v4l2_subdev_pad_config *cfg, |
956 | struct v4l2_subdev_frame_interval_enum *fie) | 957 | struct v4l2_subdev_frame_interval_enum *fie) |
957 | { | 958 | { |
958 | struct s5c73m3 *state = oif_sd_to_s5c73m3(sd); | 959 | struct s5c73m3 *state = oif_sd_to_s5c73m3(sd); |
@@ -990,7 +991,7 @@ static int s5c73m3_oif_get_pad_code(int pad, int index) | |||
990 | } | 991 | } |
991 | 992 | ||
992 | static int s5c73m3_get_fmt(struct v4l2_subdev *sd, | 993 | static int s5c73m3_get_fmt(struct v4l2_subdev *sd, |
993 | struct v4l2_subdev_fh *fh, | 994 | struct v4l2_subdev_pad_config *cfg, |
994 | struct v4l2_subdev_format *fmt) | 995 | struct v4l2_subdev_format *fmt) |
995 | { | 996 | { |
996 | struct s5c73m3 *state = sensor_sd_to_s5c73m3(sd); | 997 | struct s5c73m3 *state = sensor_sd_to_s5c73m3(sd); |
@@ -998,7 +999,7 @@ static int s5c73m3_get_fmt(struct v4l2_subdev *sd, | |||
998 | u32 code; | 999 | u32 code; |
999 | 1000 | ||
1000 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { | 1001 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { |
1001 | fmt->format = *v4l2_subdev_get_try_format(fh, fmt->pad); | 1002 | fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad); |
1002 | return 0; | 1003 | return 0; |
1003 | } | 1004 | } |
1004 | 1005 | ||
@@ -1024,7 +1025,7 @@ static int s5c73m3_get_fmt(struct v4l2_subdev *sd, | |||
1024 | } | 1025 | } |
1025 | 1026 | ||
1026 | static int s5c73m3_oif_get_fmt(struct v4l2_subdev *sd, | 1027 | static int s5c73m3_oif_get_fmt(struct v4l2_subdev *sd, |
1027 | struct v4l2_subdev_fh *fh, | 1028 | struct v4l2_subdev_pad_config *cfg, |
1028 | struct v4l2_subdev_format *fmt) | 1029 | struct v4l2_subdev_format *fmt) |
1029 | { | 1030 | { |
1030 | struct s5c73m3 *state = oif_sd_to_s5c73m3(sd); | 1031 | struct s5c73m3 *state = oif_sd_to_s5c73m3(sd); |
@@ -1032,7 +1033,7 @@ static int s5c73m3_oif_get_fmt(struct v4l2_subdev *sd, | |||
1032 | u32 code; | 1033 | u32 code; |
1033 | 1034 | ||
1034 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { | 1035 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { |
1035 | fmt->format = *v4l2_subdev_get_try_format(fh, fmt->pad); | 1036 | fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad); |
1036 | return 0; | 1037 | return 0; |
1037 | } | 1038 | } |
1038 | 1039 | ||
@@ -1062,7 +1063,7 @@ static int s5c73m3_oif_get_fmt(struct v4l2_subdev *sd, | |||
1062 | } | 1063 | } |
1063 | 1064 | ||
1064 | static int s5c73m3_set_fmt(struct v4l2_subdev *sd, | 1065 | static int s5c73m3_set_fmt(struct v4l2_subdev *sd, |
1065 | struct v4l2_subdev_fh *fh, | 1066 | struct v4l2_subdev_pad_config *cfg, |
1066 | struct v4l2_subdev_format *fmt) | 1067 | struct v4l2_subdev_format *fmt) |
1067 | { | 1068 | { |
1068 | const struct s5c73m3_frame_size *frame_size = NULL; | 1069 | const struct s5c73m3_frame_size *frame_size = NULL; |
@@ -1072,10 +1073,10 @@ static int s5c73m3_set_fmt(struct v4l2_subdev *sd, | |||
1072 | 1073 | ||
1073 | mutex_lock(&state->lock); | 1074 | mutex_lock(&state->lock); |
1074 | 1075 | ||
1075 | s5c73m3_try_format(state, fh, fmt, &frame_size); | 1076 | s5c73m3_try_format(state, cfg, fmt, &frame_size); |
1076 | 1077 | ||
1077 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { | 1078 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { |
1078 | mf = v4l2_subdev_get_try_format(fh, fmt->pad); | 1079 | mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); |
1079 | *mf = fmt->format; | 1080 | *mf = fmt->format; |
1080 | } else { | 1081 | } else { |
1081 | switch (fmt->pad) { | 1082 | switch (fmt->pad) { |
@@ -1101,7 +1102,7 @@ static int s5c73m3_set_fmt(struct v4l2_subdev *sd, | |||
1101 | } | 1102 | } |
1102 | 1103 | ||
1103 | static int s5c73m3_oif_set_fmt(struct v4l2_subdev *sd, | 1104 | static int s5c73m3_oif_set_fmt(struct v4l2_subdev *sd, |
1104 | struct v4l2_subdev_fh *fh, | 1105 | struct v4l2_subdev_pad_config *cfg, |
1105 | struct v4l2_subdev_format *fmt) | 1106 | struct v4l2_subdev_format *fmt) |
1106 | { | 1107 | { |
1107 | const struct s5c73m3_frame_size *frame_size = NULL; | 1108 | const struct s5c73m3_frame_size *frame_size = NULL; |
@@ -1111,13 +1112,13 @@ static int s5c73m3_oif_set_fmt(struct v4l2_subdev *sd, | |||
1111 | 1112 | ||
1112 | mutex_lock(&state->lock); | 1113 | mutex_lock(&state->lock); |
1113 | 1114 | ||
1114 | s5c73m3_oif_try_format(state, fh, fmt, &frame_size); | 1115 | s5c73m3_oif_try_format(state, cfg, fmt, &frame_size); |
1115 | 1116 | ||
1116 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { | 1117 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { |
1117 | mf = v4l2_subdev_get_try_format(fh, fmt->pad); | 1118 | mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); |
1118 | *mf = fmt->format; | 1119 | *mf = fmt->format; |
1119 | if (fmt->pad == OIF_ISP_PAD) { | 1120 | if (fmt->pad == OIF_ISP_PAD) { |
1120 | mf = v4l2_subdev_get_try_format(fh, OIF_SOURCE_PAD); | 1121 | mf = v4l2_subdev_get_try_format(sd, cfg, OIF_SOURCE_PAD); |
1121 | mf->width = fmt->format.width; | 1122 | mf->width = fmt->format.width; |
1122 | mf->height = fmt->format.height; | 1123 | mf->height = fmt->format.height; |
1123 | } | 1124 | } |
@@ -1189,7 +1190,7 @@ static int s5c73m3_oif_set_frame_desc(struct v4l2_subdev *sd, unsigned int pad, | |||
1189 | } | 1190 | } |
1190 | 1191 | ||
1191 | static int s5c73m3_enum_mbus_code(struct v4l2_subdev *sd, | 1192 | static int s5c73m3_enum_mbus_code(struct v4l2_subdev *sd, |
1192 | struct v4l2_subdev_fh *fh, | 1193 | struct v4l2_subdev_pad_config *cfg, |
1193 | struct v4l2_subdev_mbus_code_enum *code) | 1194 | struct v4l2_subdev_mbus_code_enum *code) |
1194 | { | 1195 | { |
1195 | static const int codes[] = { | 1196 | static const int codes[] = { |
@@ -1205,7 +1206,7 @@ static int s5c73m3_enum_mbus_code(struct v4l2_subdev *sd, | |||
1205 | } | 1206 | } |
1206 | 1207 | ||
1207 | static int s5c73m3_oif_enum_mbus_code(struct v4l2_subdev *sd, | 1208 | static int s5c73m3_oif_enum_mbus_code(struct v4l2_subdev *sd, |
1208 | struct v4l2_subdev_fh *fh, | 1209 | struct v4l2_subdev_pad_config *cfg, |
1209 | struct v4l2_subdev_mbus_code_enum *code) | 1210 | struct v4l2_subdev_mbus_code_enum *code) |
1210 | { | 1211 | { |
1211 | int ret; | 1212 | int ret; |
@@ -1220,7 +1221,7 @@ static int s5c73m3_oif_enum_mbus_code(struct v4l2_subdev *sd, | |||
1220 | } | 1221 | } |
1221 | 1222 | ||
1222 | static int s5c73m3_enum_frame_size(struct v4l2_subdev *sd, | 1223 | static int s5c73m3_enum_frame_size(struct v4l2_subdev *sd, |
1223 | struct v4l2_subdev_fh *fh, | 1224 | struct v4l2_subdev_pad_config *cfg, |
1224 | struct v4l2_subdev_frame_size_enum *fse) | 1225 | struct v4l2_subdev_frame_size_enum *fse) |
1225 | { | 1226 | { |
1226 | int idx; | 1227 | int idx; |
@@ -1247,9 +1248,10 @@ static int s5c73m3_enum_frame_size(struct v4l2_subdev *sd, | |||
1247 | } | 1248 | } |
1248 | 1249 | ||
1249 | static int s5c73m3_oif_enum_frame_size(struct v4l2_subdev *sd, | 1250 | static int s5c73m3_oif_enum_frame_size(struct v4l2_subdev *sd, |
1250 | struct v4l2_subdev_fh *fh, | 1251 | struct v4l2_subdev_pad_config *cfg, |
1251 | struct v4l2_subdev_frame_size_enum *fse) | 1252 | struct v4l2_subdev_frame_size_enum *fse) |
1252 | { | 1253 | { |
1254 | struct s5c73m3 *state = oif_sd_to_s5c73m3(sd); | ||
1253 | int idx; | 1255 | int idx; |
1254 | 1256 | ||
1255 | if (fse->pad == OIF_SOURCE_PAD) { | 1257 | if (fse->pad == OIF_SOURCE_PAD) { |
@@ -1259,11 +1261,25 @@ static int s5c73m3_oif_enum_frame_size(struct v4l2_subdev *sd, | |||
1259 | switch (fse->code) { | 1261 | switch (fse->code) { |
1260 | case S5C73M3_JPEG_FMT: | 1262 | case S5C73M3_JPEG_FMT: |
1261 | case S5C73M3_ISP_FMT: { | 1263 | case S5C73M3_ISP_FMT: { |
1262 | struct v4l2_mbus_framefmt *mf = | 1264 | unsigned w, h; |
1263 | v4l2_subdev_get_try_format(fh, OIF_ISP_PAD); | 1265 | |
1266 | if (fse->which == V4L2_SUBDEV_FORMAT_TRY) { | ||
1267 | struct v4l2_mbus_framefmt *mf; | ||
1268 | |||
1269 | mf = v4l2_subdev_get_try_format(sd, cfg, | ||
1270 | OIF_ISP_PAD); | ||
1271 | |||
1272 | w = mf->width; | ||
1273 | h = mf->height; | ||
1274 | } else { | ||
1275 | const struct s5c73m3_frame_size *fs; | ||
1264 | 1276 | ||
1265 | fse->max_width = fse->min_width = mf->width; | 1277 | fs = state->oif_pix_size[RES_ISP]; |
1266 | fse->max_height = fse->min_height = mf->height; | 1278 | w = fs->width; |
1279 | h = fs->height; | ||
1280 | } | ||
1281 | fse->max_width = fse->min_width = w; | ||
1282 | fse->max_height = fse->min_height = h; | ||
1267 | return 0; | 1283 | return 0; |
1268 | } | 1284 | } |
1269 | default: | 1285 | default: |
@@ -1306,11 +1322,11 @@ static int s5c73m3_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) | |||
1306 | { | 1322 | { |
1307 | struct v4l2_mbus_framefmt *mf; | 1323 | struct v4l2_mbus_framefmt *mf; |
1308 | 1324 | ||
1309 | mf = v4l2_subdev_get_try_format(fh, S5C73M3_ISP_PAD); | 1325 | mf = v4l2_subdev_get_try_format(sd, fh->pad, S5C73M3_ISP_PAD); |
1310 | s5c73m3_fill_mbus_fmt(mf, &s5c73m3_isp_resolutions[1], | 1326 | s5c73m3_fill_mbus_fmt(mf, &s5c73m3_isp_resolutions[1], |
1311 | S5C73M3_ISP_FMT); | 1327 | S5C73M3_ISP_FMT); |
1312 | 1328 | ||
1313 | mf = v4l2_subdev_get_try_format(fh, S5C73M3_JPEG_PAD); | 1329 | mf = v4l2_subdev_get_try_format(sd, fh->pad, S5C73M3_JPEG_PAD); |
1314 | s5c73m3_fill_mbus_fmt(mf, &s5c73m3_jpeg_resolutions[1], | 1330 | s5c73m3_fill_mbus_fmt(mf, &s5c73m3_jpeg_resolutions[1], |
1315 | S5C73M3_JPEG_FMT); | 1331 | S5C73M3_JPEG_FMT); |
1316 | 1332 | ||
@@ -1321,15 +1337,15 @@ static int s5c73m3_oif_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) | |||
1321 | { | 1337 | { |
1322 | struct v4l2_mbus_framefmt *mf; | 1338 | struct v4l2_mbus_framefmt *mf; |
1323 | 1339 | ||
1324 | mf = v4l2_subdev_get_try_format(fh, OIF_ISP_PAD); | 1340 | mf = v4l2_subdev_get_try_format(sd, fh->pad, OIF_ISP_PAD); |
1325 | s5c73m3_fill_mbus_fmt(mf, &s5c73m3_isp_resolutions[1], | 1341 | s5c73m3_fill_mbus_fmt(mf, &s5c73m3_isp_resolutions[1], |
1326 | S5C73M3_ISP_FMT); | 1342 | S5C73M3_ISP_FMT); |
1327 | 1343 | ||
1328 | mf = v4l2_subdev_get_try_format(fh, OIF_JPEG_PAD); | 1344 | mf = v4l2_subdev_get_try_format(sd, fh->pad, OIF_JPEG_PAD); |
1329 | s5c73m3_fill_mbus_fmt(mf, &s5c73m3_jpeg_resolutions[1], | 1345 | s5c73m3_fill_mbus_fmt(mf, &s5c73m3_jpeg_resolutions[1], |
1330 | S5C73M3_JPEG_FMT); | 1346 | S5C73M3_JPEG_FMT); |
1331 | 1347 | ||
1332 | mf = v4l2_subdev_get_try_format(fh, OIF_SOURCE_PAD); | 1348 | mf = v4l2_subdev_get_try_format(sd, fh->pad, OIF_SOURCE_PAD); |
1333 | s5c73m3_fill_mbus_fmt(mf, &s5c73m3_isp_resolutions[1], | 1349 | s5c73m3_fill_mbus_fmt(mf, &s5c73m3_isp_resolutions[1], |
1334 | S5C73M3_ISP_FMT); | 1350 | S5C73M3_ISP_FMT); |
1335 | return 0; | 1351 | return 0; |
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-spi.c b/drivers/media/i2c/s5c73m3/s5c73m3-spi.c index f60b265b4da1..63eb19093381 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3-spi.c +++ b/drivers/media/i2c/s5c73m3/s5c73m3-spi.c | |||
@@ -52,7 +52,7 @@ static int spi_xmit(struct spi_device *spi_dev, void *addr, const int len, | |||
52 | xfer.rx_buf = addr; | 52 | xfer.rx_buf = addr; |
53 | 53 | ||
54 | if (spi_dev == NULL) { | 54 | if (spi_dev == NULL) { |
55 | dev_err(&spi_dev->dev, "SPI device is uninitialized\n"); | 55 | pr_err("SPI device is uninitialized\n"); |
56 | return -ENODEV; | 56 | return -ENODEV; |
57 | } | 57 | } |
58 | 58 | ||
diff --git a/drivers/media/i2c/s5k4ecgx.c b/drivers/media/i2c/s5k4ecgx.c index 70071314789e..97084237275d 100644 --- a/drivers/media/i2c/s5k4ecgx.c +++ b/drivers/media/i2c/s5k4ecgx.c | |||
@@ -531,7 +531,7 @@ static int s5k4ecgx_try_frame_size(struct v4l2_mbus_framefmt *mf, | |||
531 | } | 531 | } |
532 | 532 | ||
533 | static int s5k4ecgx_enum_mbus_code(struct v4l2_subdev *sd, | 533 | static int s5k4ecgx_enum_mbus_code(struct v4l2_subdev *sd, |
534 | struct v4l2_subdev_fh *fh, | 534 | struct v4l2_subdev_pad_config *cfg, |
535 | struct v4l2_subdev_mbus_code_enum *code) | 535 | struct v4l2_subdev_mbus_code_enum *code) |
536 | { | 536 | { |
537 | if (code->index >= ARRAY_SIZE(s5k4ecgx_formats)) | 537 | if (code->index >= ARRAY_SIZE(s5k4ecgx_formats)) |
@@ -541,15 +541,15 @@ static int s5k4ecgx_enum_mbus_code(struct v4l2_subdev *sd, | |||
541 | return 0; | 541 | return 0; |
542 | } | 542 | } |
543 | 543 | ||
544 | static int s5k4ecgx_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | 544 | static int s5k4ecgx_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, |
545 | struct v4l2_subdev_format *fmt) | 545 | struct v4l2_subdev_format *fmt) |
546 | { | 546 | { |
547 | struct s5k4ecgx *priv = to_s5k4ecgx(sd); | 547 | struct s5k4ecgx *priv = to_s5k4ecgx(sd); |
548 | struct v4l2_mbus_framefmt *mf; | 548 | struct v4l2_mbus_framefmt *mf; |
549 | 549 | ||
550 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { | 550 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { |
551 | if (fh) { | 551 | if (cfg) { |
552 | mf = v4l2_subdev_get_try_format(fh, 0); | 552 | mf = v4l2_subdev_get_try_format(sd, cfg, 0); |
553 | fmt->format = *mf; | 553 | fmt->format = *mf; |
554 | } | 554 | } |
555 | return 0; | 555 | return 0; |
@@ -581,7 +581,7 @@ static const struct s5k4ecgx_pixfmt *s5k4ecgx_try_fmt(struct v4l2_subdev *sd, | |||
581 | return &s5k4ecgx_formats[i]; | 581 | return &s5k4ecgx_formats[i]; |
582 | } | 582 | } |
583 | 583 | ||
584 | static int s5k4ecgx_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | 584 | static int s5k4ecgx_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, |
585 | struct v4l2_subdev_format *fmt) | 585 | struct v4l2_subdev_format *fmt) |
586 | { | 586 | { |
587 | struct s5k4ecgx *priv = to_s5k4ecgx(sd); | 587 | struct s5k4ecgx *priv = to_s5k4ecgx(sd); |
@@ -596,8 +596,8 @@ static int s5k4ecgx_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
596 | fmt->format.field = V4L2_FIELD_NONE; | 596 | fmt->format.field = V4L2_FIELD_NONE; |
597 | 597 | ||
598 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { | 598 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { |
599 | if (fh) { | 599 | if (cfg) { |
600 | mf = v4l2_subdev_get_try_format(fh, 0); | 600 | mf = v4l2_subdev_get_try_format(sd, cfg, 0); |
601 | *mf = fmt->format; | 601 | *mf = fmt->format; |
602 | } | 602 | } |
603 | return 0; | 603 | return 0; |
@@ -692,7 +692,7 @@ static int s5k4ecgx_registered(struct v4l2_subdev *sd) | |||
692 | */ | 692 | */ |
693 | static int s5k4ecgx_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) | 693 | static int s5k4ecgx_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) |
694 | { | 694 | { |
695 | struct v4l2_mbus_framefmt *mf = v4l2_subdev_get_try_format(fh, 0); | 695 | struct v4l2_mbus_framefmt *mf = v4l2_subdev_get_try_format(sd, fh->pad, 0); |
696 | 696 | ||
697 | mf->width = s5k4ecgx_prev_sizes[0].size.width; | 697 | mf->width = s5k4ecgx_prev_sizes[0].size.width; |
698 | mf->height = s5k4ecgx_prev_sizes[0].size.height; | 698 | mf->height = s5k4ecgx_prev_sizes[0].size.height; |
diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c index a3d7d0391302..297ef04e146a 100644 --- a/drivers/media/i2c/s5k5baf.c +++ b/drivers/media/i2c/s5k5baf.c | |||
@@ -374,6 +374,8 @@ static int s5k5baf_fw_parse(struct device *dev, struct s5k5baf_fw **fw, | |||
374 | count -= S5K5BAG_FW_TAG_LEN; | 374 | count -= S5K5BAG_FW_TAG_LEN; |
375 | 375 | ||
376 | d = devm_kzalloc(dev, count * sizeof(u16), GFP_KERNEL); | 376 | d = devm_kzalloc(dev, count * sizeof(u16), GFP_KERNEL); |
377 | if (!d) | ||
378 | return -ENOMEM; | ||
377 | 379 | ||
378 | for (i = 0; i < count; ++i) | 380 | for (i = 0; i < count; ++i) |
379 | d[i] = le16_to_cpu(data[i]); | 381 | d[i] = le16_to_cpu(data[i]); |
@@ -1182,7 +1184,7 @@ static int s5k5baf_s_frame_interval(struct v4l2_subdev *sd, | |||
1182 | * V4L2 subdev pad level and video operations | 1184 | * V4L2 subdev pad level and video operations |
1183 | */ | 1185 | */ |
1184 | static int s5k5baf_enum_frame_interval(struct v4l2_subdev *sd, | 1186 | static int s5k5baf_enum_frame_interval(struct v4l2_subdev *sd, |
1185 | struct v4l2_subdev_fh *fh, | 1187 | struct v4l2_subdev_pad_config *cfg, |
1186 | struct v4l2_subdev_frame_interval_enum *fie) | 1188 | struct v4l2_subdev_frame_interval_enum *fie) |
1187 | { | 1189 | { |
1188 | if (fie->index > S5K5BAF_MAX_FR_TIME - S5K5BAF_MIN_FR_TIME || | 1190 | if (fie->index > S5K5BAF_MAX_FR_TIME - S5K5BAF_MIN_FR_TIME || |
@@ -1201,7 +1203,7 @@ static int s5k5baf_enum_frame_interval(struct v4l2_subdev *sd, | |||
1201 | } | 1203 | } |
1202 | 1204 | ||
1203 | static int s5k5baf_enum_mbus_code(struct v4l2_subdev *sd, | 1205 | static int s5k5baf_enum_mbus_code(struct v4l2_subdev *sd, |
1204 | struct v4l2_subdev_fh *fh, | 1206 | struct v4l2_subdev_pad_config *cfg, |
1205 | struct v4l2_subdev_mbus_code_enum *code) | 1207 | struct v4l2_subdev_mbus_code_enum *code) |
1206 | { | 1208 | { |
1207 | if (code->pad == PAD_CIS) { | 1209 | if (code->pad == PAD_CIS) { |
@@ -1219,7 +1221,7 @@ static int s5k5baf_enum_mbus_code(struct v4l2_subdev *sd, | |||
1219 | } | 1221 | } |
1220 | 1222 | ||
1221 | static int s5k5baf_enum_frame_size(struct v4l2_subdev *sd, | 1223 | static int s5k5baf_enum_frame_size(struct v4l2_subdev *sd, |
1222 | struct v4l2_subdev_fh *fh, | 1224 | struct v4l2_subdev_pad_config *cfg, |
1223 | struct v4l2_subdev_frame_size_enum *fse) | 1225 | struct v4l2_subdev_frame_size_enum *fse) |
1224 | { | 1226 | { |
1225 | int i; | 1227 | int i; |
@@ -1276,7 +1278,7 @@ static int s5k5baf_try_isp_format(struct v4l2_mbus_framefmt *mf) | |||
1276 | return pixfmt; | 1278 | return pixfmt; |
1277 | } | 1279 | } |
1278 | 1280 | ||
1279 | static int s5k5baf_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | 1281 | static int s5k5baf_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, |
1280 | struct v4l2_subdev_format *fmt) | 1282 | struct v4l2_subdev_format *fmt) |
1281 | { | 1283 | { |
1282 | struct s5k5baf *state = to_s5k5baf(sd); | 1284 | struct s5k5baf *state = to_s5k5baf(sd); |
@@ -1284,7 +1286,7 @@ static int s5k5baf_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
1284 | struct v4l2_mbus_framefmt *mf; | 1286 | struct v4l2_mbus_framefmt *mf; |
1285 | 1287 | ||
1286 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { | 1288 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { |
1287 | mf = v4l2_subdev_get_try_format(fh, fmt->pad); | 1289 | mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); |
1288 | fmt->format = *mf; | 1290 | fmt->format = *mf; |
1289 | return 0; | 1291 | return 0; |
1290 | } | 1292 | } |
@@ -1306,7 +1308,7 @@ static int s5k5baf_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
1306 | return 0; | 1308 | return 0; |
1307 | } | 1309 | } |
1308 | 1310 | ||
1309 | static int s5k5baf_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | 1311 | static int s5k5baf_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, |
1310 | struct v4l2_subdev_format *fmt) | 1312 | struct v4l2_subdev_format *fmt) |
1311 | { | 1313 | { |
1312 | struct v4l2_mbus_framefmt *mf = &fmt->format; | 1314 | struct v4l2_mbus_framefmt *mf = &fmt->format; |
@@ -1317,7 +1319,7 @@ static int s5k5baf_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
1317 | mf->field = V4L2_FIELD_NONE; | 1319 | mf->field = V4L2_FIELD_NONE; |
1318 | 1320 | ||
1319 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { | 1321 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { |
1320 | *v4l2_subdev_get_try_format(fh, fmt->pad) = *mf; | 1322 | *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = *mf; |
1321 | return 0; | 1323 | return 0; |
1322 | } | 1324 | } |
1323 | 1325 | ||
@@ -1369,7 +1371,7 @@ static int s5k5baf_is_bound_target(u32 target) | |||
1369 | } | 1371 | } |
1370 | 1372 | ||
1371 | static int s5k5baf_get_selection(struct v4l2_subdev *sd, | 1373 | static int s5k5baf_get_selection(struct v4l2_subdev *sd, |
1372 | struct v4l2_subdev_fh *fh, | 1374 | struct v4l2_subdev_pad_config *cfg, |
1373 | struct v4l2_subdev_selection *sel) | 1375 | struct v4l2_subdev_selection *sel) |
1374 | { | 1376 | { |
1375 | static enum selection_rect rtype; | 1377 | static enum selection_rect rtype; |
@@ -1389,9 +1391,9 @@ static int s5k5baf_get_selection(struct v4l2_subdev *sd, | |||
1389 | 1391 | ||
1390 | if (sel->which == V4L2_SUBDEV_FORMAT_TRY) { | 1392 | if (sel->which == V4L2_SUBDEV_FORMAT_TRY) { |
1391 | if (rtype == R_COMPOSE) | 1393 | if (rtype == R_COMPOSE) |
1392 | sel->r = *v4l2_subdev_get_try_compose(fh, sel->pad); | 1394 | sel->r = *v4l2_subdev_get_try_compose(sd, cfg, sel->pad); |
1393 | else | 1395 | else |
1394 | sel->r = *v4l2_subdev_get_try_crop(fh, sel->pad); | 1396 | sel->r = *v4l2_subdev_get_try_crop(sd, cfg, sel->pad); |
1395 | return 0; | 1397 | return 0; |
1396 | } | 1398 | } |
1397 | 1399 | ||
@@ -1460,7 +1462,7 @@ static bool s5k5baf_cmp_rect(const struct v4l2_rect *r1, | |||
1460 | } | 1462 | } |
1461 | 1463 | ||
1462 | static int s5k5baf_set_selection(struct v4l2_subdev *sd, | 1464 | static int s5k5baf_set_selection(struct v4l2_subdev *sd, |
1463 | struct v4l2_subdev_fh *fh, | 1465 | struct v4l2_subdev_pad_config *cfg, |
1464 | struct v4l2_subdev_selection *sel) | 1466 | struct v4l2_subdev_selection *sel) |
1465 | { | 1467 | { |
1466 | static enum selection_rect rtype; | 1468 | static enum selection_rect rtype; |
@@ -1481,9 +1483,9 @@ static int s5k5baf_set_selection(struct v4l2_subdev *sd, | |||
1481 | if (sel->which == V4L2_SUBDEV_FORMAT_TRY) { | 1483 | if (sel->which == V4L2_SUBDEV_FORMAT_TRY) { |
1482 | rects = (struct v4l2_rect * []) { | 1484 | rects = (struct v4l2_rect * []) { |
1483 | &s5k5baf_cis_rect, | 1485 | &s5k5baf_cis_rect, |
1484 | v4l2_subdev_get_try_crop(fh, PAD_CIS), | 1486 | v4l2_subdev_get_try_crop(sd, cfg, PAD_CIS), |
1485 | v4l2_subdev_get_try_compose(fh, PAD_CIS), | 1487 | v4l2_subdev_get_try_compose(sd, cfg, PAD_CIS), |
1486 | v4l2_subdev_get_try_crop(fh, PAD_OUT) | 1488 | v4l2_subdev_get_try_crop(sd, cfg, PAD_OUT) |
1487 | }; | 1489 | }; |
1488 | s5k5baf_set_rect_and_adjust(rects, rtype, &sel->r); | 1490 | s5k5baf_set_rect_and_adjust(rects, rtype, &sel->r); |
1489 | return 0; | 1491 | return 0; |
@@ -1701,22 +1703,22 @@ static int s5k5baf_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) | |||
1701 | { | 1703 | { |
1702 | struct v4l2_mbus_framefmt *mf; | 1704 | struct v4l2_mbus_framefmt *mf; |
1703 | 1705 | ||
1704 | mf = v4l2_subdev_get_try_format(fh, PAD_CIS); | 1706 | mf = v4l2_subdev_get_try_format(sd, fh->pad, PAD_CIS); |
1705 | s5k5baf_try_cis_format(mf); | 1707 | s5k5baf_try_cis_format(mf); |
1706 | 1708 | ||
1707 | if (s5k5baf_is_cis_subdev(sd)) | 1709 | if (s5k5baf_is_cis_subdev(sd)) |
1708 | return 0; | 1710 | return 0; |
1709 | 1711 | ||
1710 | mf = v4l2_subdev_get_try_format(fh, PAD_OUT); | 1712 | mf = v4l2_subdev_get_try_format(sd, fh->pad, PAD_OUT); |
1711 | mf->colorspace = s5k5baf_formats[0].colorspace; | 1713 | mf->colorspace = s5k5baf_formats[0].colorspace; |
1712 | mf->code = s5k5baf_formats[0].code; | 1714 | mf->code = s5k5baf_formats[0].code; |
1713 | mf->width = s5k5baf_cis_rect.width; | 1715 | mf->width = s5k5baf_cis_rect.width; |
1714 | mf->height = s5k5baf_cis_rect.height; | 1716 | mf->height = s5k5baf_cis_rect.height; |
1715 | mf->field = V4L2_FIELD_NONE; | 1717 | mf->field = V4L2_FIELD_NONE; |
1716 | 1718 | ||
1717 | *v4l2_subdev_get_try_crop(fh, PAD_CIS) = s5k5baf_cis_rect; | 1719 | *v4l2_subdev_get_try_crop(sd, fh->pad, PAD_CIS) = s5k5baf_cis_rect; |
1718 | *v4l2_subdev_get_try_compose(fh, PAD_CIS) = s5k5baf_cis_rect; | 1720 | *v4l2_subdev_get_try_compose(sd, fh->pad, PAD_CIS) = s5k5baf_cis_rect; |
1719 | *v4l2_subdev_get_try_crop(fh, PAD_OUT) = s5k5baf_cis_rect; | 1721 | *v4l2_subdev_get_try_crop(sd, fh->pad, PAD_OUT) = s5k5baf_cis_rect; |
1720 | 1722 | ||
1721 | return 0; | 1723 | return 0; |
1722 | } | 1724 | } |
diff --git a/drivers/media/i2c/s5k6a3.c b/drivers/media/i2c/s5k6a3.c index 91b841a1b850..bc389d5e42ae 100644 --- a/drivers/media/i2c/s5k6a3.c +++ b/drivers/media/i2c/s5k6a3.c | |||
@@ -99,7 +99,7 @@ static const struct v4l2_mbus_framefmt *find_sensor_format( | |||
99 | } | 99 | } |
100 | 100 | ||
101 | static int s5k6a3_enum_mbus_code(struct v4l2_subdev *sd, | 101 | static int s5k6a3_enum_mbus_code(struct v4l2_subdev *sd, |
102 | struct v4l2_subdev_fh *fh, | 102 | struct v4l2_subdev_pad_config *cfg, |
103 | struct v4l2_subdev_mbus_code_enum *code) | 103 | struct v4l2_subdev_mbus_code_enum *code) |
104 | { | 104 | { |
105 | if (code->index >= ARRAY_SIZE(s5k6a3_formats)) | 105 | if (code->index >= ARRAY_SIZE(s5k6a3_formats)) |
@@ -123,17 +123,17 @@ static void s5k6a3_try_format(struct v4l2_mbus_framefmt *mf) | |||
123 | } | 123 | } |
124 | 124 | ||
125 | static struct v4l2_mbus_framefmt *__s5k6a3_get_format( | 125 | static struct v4l2_mbus_framefmt *__s5k6a3_get_format( |
126 | struct s5k6a3 *sensor, struct v4l2_subdev_fh *fh, | 126 | struct s5k6a3 *sensor, struct v4l2_subdev_pad_config *cfg, |
127 | u32 pad, enum v4l2_subdev_format_whence which) | 127 | u32 pad, enum v4l2_subdev_format_whence which) |
128 | { | 128 | { |
129 | if (which == V4L2_SUBDEV_FORMAT_TRY) | 129 | if (which == V4L2_SUBDEV_FORMAT_TRY) |
130 | return fh ? v4l2_subdev_get_try_format(fh, pad) : NULL; | 130 | return cfg ? v4l2_subdev_get_try_format(&sensor->subdev, cfg, pad) : NULL; |
131 | 131 | ||
132 | return &sensor->format; | 132 | return &sensor->format; |
133 | } | 133 | } |
134 | 134 | ||
135 | static int s5k6a3_set_fmt(struct v4l2_subdev *sd, | 135 | static int s5k6a3_set_fmt(struct v4l2_subdev *sd, |
136 | struct v4l2_subdev_fh *fh, | 136 | struct v4l2_subdev_pad_config *cfg, |
137 | struct v4l2_subdev_format *fmt) | 137 | struct v4l2_subdev_format *fmt) |
138 | { | 138 | { |
139 | struct s5k6a3 *sensor = sd_to_s5k6a3(sd); | 139 | struct s5k6a3 *sensor = sd_to_s5k6a3(sd); |
@@ -141,7 +141,7 @@ static int s5k6a3_set_fmt(struct v4l2_subdev *sd, | |||
141 | 141 | ||
142 | s5k6a3_try_format(&fmt->format); | 142 | s5k6a3_try_format(&fmt->format); |
143 | 143 | ||
144 | mf = __s5k6a3_get_format(sensor, fh, fmt->pad, fmt->which); | 144 | mf = __s5k6a3_get_format(sensor, cfg, fmt->pad, fmt->which); |
145 | if (mf) { | 145 | if (mf) { |
146 | mutex_lock(&sensor->lock); | 146 | mutex_lock(&sensor->lock); |
147 | if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) | 147 | if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) |
@@ -152,13 +152,13 @@ static int s5k6a3_set_fmt(struct v4l2_subdev *sd, | |||
152 | } | 152 | } |
153 | 153 | ||
154 | static int s5k6a3_get_fmt(struct v4l2_subdev *sd, | 154 | static int s5k6a3_get_fmt(struct v4l2_subdev *sd, |
155 | struct v4l2_subdev_fh *fh, | 155 | struct v4l2_subdev_pad_config *cfg, |
156 | struct v4l2_subdev_format *fmt) | 156 | struct v4l2_subdev_format *fmt) |
157 | { | 157 | { |
158 | struct s5k6a3 *sensor = sd_to_s5k6a3(sd); | 158 | struct s5k6a3 *sensor = sd_to_s5k6a3(sd); |
159 | struct v4l2_mbus_framefmt *mf; | 159 | struct v4l2_mbus_framefmt *mf; |
160 | 160 | ||
161 | mf = __s5k6a3_get_format(sensor, fh, fmt->pad, fmt->which); | 161 | mf = __s5k6a3_get_format(sensor, cfg, fmt->pad, fmt->which); |
162 | 162 | ||
163 | mutex_lock(&sensor->lock); | 163 | mutex_lock(&sensor->lock); |
164 | fmt->format = *mf; | 164 | fmt->format = *mf; |
@@ -174,7 +174,7 @@ static struct v4l2_subdev_pad_ops s5k6a3_pad_ops = { | |||
174 | 174 | ||
175 | static int s5k6a3_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) | 175 | static int s5k6a3_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) |
176 | { | 176 | { |
177 | struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(fh, 0); | 177 | struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(sd, fh->pad, 0); |
178 | 178 | ||
179 | *format = s5k6a3_formats[0]; | 179 | *format = s5k6a3_formats[0]; |
180 | format->width = S5K6A3_DEFAULT_WIDTH; | 180 | format->width = S5K6A3_DEFAULT_WIDTH; |
diff --git a/drivers/media/i2c/s5k6aa.c b/drivers/media/i2c/s5k6aa.c index b1c583239dab..de803a11efb4 100644 --- a/drivers/media/i2c/s5k6aa.c +++ b/drivers/media/i2c/s5k6aa.c | |||
@@ -996,7 +996,7 @@ static int s5k6aa_s_frame_interval(struct v4l2_subdev *sd, | |||
996 | * V4L2 subdev pad level and video operations | 996 | * V4L2 subdev pad level and video operations |
997 | */ | 997 | */ |
998 | static int s5k6aa_enum_frame_interval(struct v4l2_subdev *sd, | 998 | static int s5k6aa_enum_frame_interval(struct v4l2_subdev *sd, |
999 | struct v4l2_subdev_fh *fh, | 999 | struct v4l2_subdev_pad_config *cfg, |
1000 | struct v4l2_subdev_frame_interval_enum *fie) | 1000 | struct v4l2_subdev_frame_interval_enum *fie) |
1001 | { | 1001 | { |
1002 | struct s5k6aa *s5k6aa = to_s5k6aa(sd); | 1002 | struct s5k6aa *s5k6aa = to_s5k6aa(sd); |
@@ -1023,7 +1023,7 @@ static int s5k6aa_enum_frame_interval(struct v4l2_subdev *sd, | |||
1023 | } | 1023 | } |
1024 | 1024 | ||
1025 | static int s5k6aa_enum_mbus_code(struct v4l2_subdev *sd, | 1025 | static int s5k6aa_enum_mbus_code(struct v4l2_subdev *sd, |
1026 | struct v4l2_subdev_fh *fh, | 1026 | struct v4l2_subdev_pad_config *cfg, |
1027 | struct v4l2_subdev_mbus_code_enum *code) | 1027 | struct v4l2_subdev_mbus_code_enum *code) |
1028 | { | 1028 | { |
1029 | if (code->index >= ARRAY_SIZE(s5k6aa_formats)) | 1029 | if (code->index >= ARRAY_SIZE(s5k6aa_formats)) |
@@ -1034,7 +1034,7 @@ static int s5k6aa_enum_mbus_code(struct v4l2_subdev *sd, | |||
1034 | } | 1034 | } |
1035 | 1035 | ||
1036 | static int s5k6aa_enum_frame_size(struct v4l2_subdev *sd, | 1036 | static int s5k6aa_enum_frame_size(struct v4l2_subdev *sd, |
1037 | struct v4l2_subdev_fh *fh, | 1037 | struct v4l2_subdev_pad_config *cfg, |
1038 | struct v4l2_subdev_frame_size_enum *fse) | 1038 | struct v4l2_subdev_frame_size_enum *fse) |
1039 | { | 1039 | { |
1040 | int i = ARRAY_SIZE(s5k6aa_formats); | 1040 | int i = ARRAY_SIZE(s5k6aa_formats); |
@@ -1056,14 +1056,14 @@ static int s5k6aa_enum_frame_size(struct v4l2_subdev *sd, | |||
1056 | } | 1056 | } |
1057 | 1057 | ||
1058 | static struct v4l2_rect * | 1058 | static struct v4l2_rect * |
1059 | __s5k6aa_get_crop_rect(struct s5k6aa *s5k6aa, struct v4l2_subdev_fh *fh, | 1059 | __s5k6aa_get_crop_rect(struct s5k6aa *s5k6aa, struct v4l2_subdev_pad_config *cfg, |
1060 | enum v4l2_subdev_format_whence which) | 1060 | enum v4l2_subdev_format_whence which) |
1061 | { | 1061 | { |
1062 | if (which == V4L2_SUBDEV_FORMAT_ACTIVE) | 1062 | if (which == V4L2_SUBDEV_FORMAT_ACTIVE) |
1063 | return &s5k6aa->ccd_rect; | 1063 | return &s5k6aa->ccd_rect; |
1064 | 1064 | ||
1065 | WARN_ON(which != V4L2_SUBDEV_FORMAT_TRY); | 1065 | WARN_ON(which != V4L2_SUBDEV_FORMAT_TRY); |
1066 | return v4l2_subdev_get_try_crop(fh, 0); | 1066 | return v4l2_subdev_get_try_crop(&s5k6aa->sd, cfg, 0); |
1067 | } | 1067 | } |
1068 | 1068 | ||
1069 | static void s5k6aa_try_format(struct s5k6aa *s5k6aa, | 1069 | static void s5k6aa_try_format(struct s5k6aa *s5k6aa, |
@@ -1087,7 +1087,7 @@ static void s5k6aa_try_format(struct s5k6aa *s5k6aa, | |||
1087 | mf->field = V4L2_FIELD_NONE; | 1087 | mf->field = V4L2_FIELD_NONE; |
1088 | } | 1088 | } |
1089 | 1089 | ||
1090 | static int s5k6aa_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | 1090 | static int s5k6aa_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, |
1091 | struct v4l2_subdev_format *fmt) | 1091 | struct v4l2_subdev_format *fmt) |
1092 | { | 1092 | { |
1093 | struct s5k6aa *s5k6aa = to_s5k6aa(sd); | 1093 | struct s5k6aa *s5k6aa = to_s5k6aa(sd); |
@@ -1096,7 +1096,7 @@ static int s5k6aa_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
1096 | memset(fmt->reserved, 0, sizeof(fmt->reserved)); | 1096 | memset(fmt->reserved, 0, sizeof(fmt->reserved)); |
1097 | 1097 | ||
1098 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { | 1098 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { |
1099 | mf = v4l2_subdev_get_try_format(fh, 0); | 1099 | mf = v4l2_subdev_get_try_format(sd, cfg, 0); |
1100 | fmt->format = *mf; | 1100 | fmt->format = *mf; |
1101 | return 0; | 1101 | return 0; |
1102 | } | 1102 | } |
@@ -1108,7 +1108,7 @@ static int s5k6aa_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
1108 | return 0; | 1108 | return 0; |
1109 | } | 1109 | } |
1110 | 1110 | ||
1111 | static int s5k6aa_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | 1111 | static int s5k6aa_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, |
1112 | struct v4l2_subdev_format *fmt) | 1112 | struct v4l2_subdev_format *fmt) |
1113 | { | 1113 | { |
1114 | struct s5k6aa *s5k6aa = to_s5k6aa(sd); | 1114 | struct s5k6aa *s5k6aa = to_s5k6aa(sd); |
@@ -1121,8 +1121,8 @@ static int s5k6aa_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
1121 | s5k6aa_try_format(s5k6aa, &fmt->format); | 1121 | s5k6aa_try_format(s5k6aa, &fmt->format); |
1122 | 1122 | ||
1123 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { | 1123 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { |
1124 | mf = v4l2_subdev_get_try_format(fh, fmt->pad); | 1124 | mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); |
1125 | crop = v4l2_subdev_get_try_crop(fh, 0); | 1125 | crop = v4l2_subdev_get_try_crop(sd, cfg, 0); |
1126 | } else { | 1126 | } else { |
1127 | if (s5k6aa->streaming) { | 1127 | if (s5k6aa->streaming) { |
1128 | ret = -EBUSY; | 1128 | ret = -EBUSY; |
@@ -1162,7 +1162,7 @@ static int s5k6aa_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
1162 | } | 1162 | } |
1163 | 1163 | ||
1164 | static int s5k6aa_get_selection(struct v4l2_subdev *sd, | 1164 | static int s5k6aa_get_selection(struct v4l2_subdev *sd, |
1165 | struct v4l2_subdev_fh *fh, | 1165 | struct v4l2_subdev_pad_config *cfg, |
1166 | struct v4l2_subdev_selection *sel) | 1166 | struct v4l2_subdev_selection *sel) |
1167 | { | 1167 | { |
1168 | struct s5k6aa *s5k6aa = to_s5k6aa(sd); | 1168 | struct s5k6aa *s5k6aa = to_s5k6aa(sd); |
@@ -1174,7 +1174,7 @@ static int s5k6aa_get_selection(struct v4l2_subdev *sd, | |||
1174 | memset(sel->reserved, 0, sizeof(sel->reserved)); | 1174 | memset(sel->reserved, 0, sizeof(sel->reserved)); |
1175 | 1175 | ||
1176 | mutex_lock(&s5k6aa->lock); | 1176 | mutex_lock(&s5k6aa->lock); |
1177 | rect = __s5k6aa_get_crop_rect(s5k6aa, fh, sel->which); | 1177 | rect = __s5k6aa_get_crop_rect(s5k6aa, cfg, sel->which); |
1178 | sel->r = *rect; | 1178 | sel->r = *rect; |
1179 | mutex_unlock(&s5k6aa->lock); | 1179 | mutex_unlock(&s5k6aa->lock); |
1180 | 1180 | ||
@@ -1185,7 +1185,7 @@ static int s5k6aa_get_selection(struct v4l2_subdev *sd, | |||
1185 | } | 1185 | } |
1186 | 1186 | ||
1187 | static int s5k6aa_set_selection(struct v4l2_subdev *sd, | 1187 | static int s5k6aa_set_selection(struct v4l2_subdev *sd, |
1188 | struct v4l2_subdev_fh *fh, | 1188 | struct v4l2_subdev_pad_config *cfg, |
1189 | struct v4l2_subdev_selection *sel) | 1189 | struct v4l2_subdev_selection *sel) |
1190 | { | 1190 | { |
1191 | struct s5k6aa *s5k6aa = to_s5k6aa(sd); | 1191 | struct s5k6aa *s5k6aa = to_s5k6aa(sd); |
@@ -1197,13 +1197,13 @@ static int s5k6aa_set_selection(struct v4l2_subdev *sd, | |||
1197 | return -EINVAL; | 1197 | return -EINVAL; |
1198 | 1198 | ||
1199 | mutex_lock(&s5k6aa->lock); | 1199 | mutex_lock(&s5k6aa->lock); |
1200 | crop_r = __s5k6aa_get_crop_rect(s5k6aa, fh, sel->which); | 1200 | crop_r = __s5k6aa_get_crop_rect(s5k6aa, cfg, sel->which); |
1201 | 1201 | ||
1202 | if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) { | 1202 | if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) { |
1203 | mf = &s5k6aa->preset->mbus_fmt; | 1203 | mf = &s5k6aa->preset->mbus_fmt; |
1204 | s5k6aa->apply_crop = 1; | 1204 | s5k6aa->apply_crop = 1; |
1205 | } else { | 1205 | } else { |
1206 | mf = v4l2_subdev_get_try_format(fh, 0); | 1206 | mf = v4l2_subdev_get_try_format(sd, cfg, 0); |
1207 | } | 1207 | } |
1208 | v4l_bound_align_image(&sel->r.width, mf->width, | 1208 | v4l_bound_align_image(&sel->r.width, mf->width, |
1209 | S5K6AA_WIN_WIDTH_MAX, 1, | 1209 | S5K6AA_WIN_WIDTH_MAX, 1, |
@@ -1424,8 +1424,8 @@ static int s5k6aa_initialize_ctrls(struct s5k6aa *s5k6aa) | |||
1424 | */ | 1424 | */ |
1425 | static int s5k6aa_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) | 1425 | static int s5k6aa_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) |
1426 | { | 1426 | { |
1427 | struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(fh, 0); | 1427 | struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(sd, fh->pad, 0); |
1428 | struct v4l2_rect *crop = v4l2_subdev_get_try_crop(fh, 0); | 1428 | struct v4l2_rect *crop = v4l2_subdev_get_try_crop(sd, fh->pad, 0); |
1429 | 1429 | ||
1430 | format->colorspace = s5k6aa_formats[0].colorspace; | 1430 | format->colorspace = s5k6aa_formats[0].colorspace; |
1431 | format->code = s5k6aa_formats[0].code; | 1431 | format->code = s5k6aa_formats[0].code; |
diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index d47eff5d3101..557f25def3a0 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c | |||
@@ -344,7 +344,7 @@ static const struct smiapp_csi_data_format smiapp_csi_data_formats[] = { | |||
344 | { MEDIA_BUS_FMT_SGBRG8_1X8, 8, 8, SMIAPP_PIXEL_ORDER_GBRG, }, | 344 | { MEDIA_BUS_FMT_SGBRG8_1X8, 8, 8, SMIAPP_PIXEL_ORDER_GBRG, }, |
345 | }; | 345 | }; |
346 | 346 | ||
347 | const char *pixel_order_str[] = { "GRBG", "RGGB", "BGGR", "GBRG" }; | 347 | static const char *pixel_order_str[] = { "GRBG", "RGGB", "BGGR", "GBRG" }; |
348 | 348 | ||
349 | #define to_csi_format_idx(fmt) (((unsigned long)(fmt) \ | 349 | #define to_csi_format_idx(fmt) (((unsigned long)(fmt) \ |
350 | - (unsigned long)smiapp_csi_data_formats) \ | 350 | - (unsigned long)smiapp_csi_data_formats) \ |
@@ -1557,7 +1557,7 @@ static int smiapp_set_stream(struct v4l2_subdev *subdev, int enable) | |||
1557 | } | 1557 | } |
1558 | 1558 | ||
1559 | static int smiapp_enum_mbus_code(struct v4l2_subdev *subdev, | 1559 | static int smiapp_enum_mbus_code(struct v4l2_subdev *subdev, |
1560 | struct v4l2_subdev_fh *fh, | 1560 | struct v4l2_subdev_pad_config *cfg, |
1561 | struct v4l2_subdev_mbus_code_enum *code) | 1561 | struct v4l2_subdev_mbus_code_enum *code) |
1562 | { | 1562 | { |
1563 | struct i2c_client *client = v4l2_get_subdevdata(subdev); | 1563 | struct i2c_client *client = v4l2_get_subdevdata(subdev); |
@@ -1611,13 +1611,13 @@ static u32 __smiapp_get_mbus_code(struct v4l2_subdev *subdev, | |||
1611 | } | 1611 | } |
1612 | 1612 | ||
1613 | static int __smiapp_get_format(struct v4l2_subdev *subdev, | 1613 | static int __smiapp_get_format(struct v4l2_subdev *subdev, |
1614 | struct v4l2_subdev_fh *fh, | 1614 | struct v4l2_subdev_pad_config *cfg, |
1615 | struct v4l2_subdev_format *fmt) | 1615 | struct v4l2_subdev_format *fmt) |
1616 | { | 1616 | { |
1617 | struct smiapp_subdev *ssd = to_smiapp_subdev(subdev); | 1617 | struct smiapp_subdev *ssd = to_smiapp_subdev(subdev); |
1618 | 1618 | ||
1619 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { | 1619 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { |
1620 | fmt->format = *v4l2_subdev_get_try_format(fh, fmt->pad); | 1620 | fmt->format = *v4l2_subdev_get_try_format(subdev, cfg, fmt->pad); |
1621 | } else { | 1621 | } else { |
1622 | struct v4l2_rect *r; | 1622 | struct v4l2_rect *r; |
1623 | 1623 | ||
@@ -1636,21 +1636,21 @@ static int __smiapp_get_format(struct v4l2_subdev *subdev, | |||
1636 | } | 1636 | } |
1637 | 1637 | ||
1638 | static int smiapp_get_format(struct v4l2_subdev *subdev, | 1638 | static int smiapp_get_format(struct v4l2_subdev *subdev, |
1639 | struct v4l2_subdev_fh *fh, | 1639 | struct v4l2_subdev_pad_config *cfg, |
1640 | struct v4l2_subdev_format *fmt) | 1640 | struct v4l2_subdev_format *fmt) |
1641 | { | 1641 | { |
1642 | struct smiapp_sensor *sensor = to_smiapp_sensor(subdev); | 1642 | struct smiapp_sensor *sensor = to_smiapp_sensor(subdev); |
1643 | int rval; | 1643 | int rval; |
1644 | 1644 | ||
1645 | mutex_lock(&sensor->mutex); | 1645 | mutex_lock(&sensor->mutex); |
1646 | rval = __smiapp_get_format(subdev, fh, fmt); | 1646 | rval = __smiapp_get_format(subdev, cfg, fmt); |
1647 | mutex_unlock(&sensor->mutex); | 1647 | mutex_unlock(&sensor->mutex); |
1648 | 1648 | ||
1649 | return rval; | 1649 | return rval; |
1650 | } | 1650 | } |
1651 | 1651 | ||
1652 | static void smiapp_get_crop_compose(struct v4l2_subdev *subdev, | 1652 | static void smiapp_get_crop_compose(struct v4l2_subdev *subdev, |
1653 | struct v4l2_subdev_fh *fh, | 1653 | struct v4l2_subdev_pad_config *cfg, |
1654 | struct v4l2_rect **crops, | 1654 | struct v4l2_rect **crops, |
1655 | struct v4l2_rect **comps, int which) | 1655 | struct v4l2_rect **comps, int which) |
1656 | { | 1656 | { |
@@ -1666,12 +1666,12 @@ static void smiapp_get_crop_compose(struct v4l2_subdev *subdev, | |||
1666 | } else { | 1666 | } else { |
1667 | if (crops) { | 1667 | if (crops) { |
1668 | for (i = 0; i < subdev->entity.num_pads; i++) { | 1668 | for (i = 0; i < subdev->entity.num_pads; i++) { |
1669 | crops[i] = v4l2_subdev_get_try_crop(fh, i); | 1669 | crops[i] = v4l2_subdev_get_try_crop(subdev, cfg, i); |
1670 | BUG_ON(!crops[i]); | 1670 | BUG_ON(!crops[i]); |
1671 | } | 1671 | } |
1672 | } | 1672 | } |
1673 | if (comps) { | 1673 | if (comps) { |
1674 | *comps = v4l2_subdev_get_try_compose(fh, | 1674 | *comps = v4l2_subdev_get_try_compose(subdev, cfg, |
1675 | SMIAPP_PAD_SINK); | 1675 | SMIAPP_PAD_SINK); |
1676 | BUG_ON(!*comps); | 1676 | BUG_ON(!*comps); |
1677 | } | 1677 | } |
@@ -1680,14 +1680,14 @@ static void smiapp_get_crop_compose(struct v4l2_subdev *subdev, | |||
1680 | 1680 | ||
1681 | /* Changes require propagation only on sink pad. */ | 1681 | /* Changes require propagation only on sink pad. */ |
1682 | static void smiapp_propagate(struct v4l2_subdev *subdev, | 1682 | static void smiapp_propagate(struct v4l2_subdev *subdev, |
1683 | struct v4l2_subdev_fh *fh, int which, | 1683 | struct v4l2_subdev_pad_config *cfg, int which, |
1684 | int target) | 1684 | int target) |
1685 | { | 1685 | { |
1686 | struct smiapp_sensor *sensor = to_smiapp_sensor(subdev); | 1686 | struct smiapp_sensor *sensor = to_smiapp_sensor(subdev); |
1687 | struct smiapp_subdev *ssd = to_smiapp_subdev(subdev); | 1687 | struct smiapp_subdev *ssd = to_smiapp_subdev(subdev); |
1688 | struct v4l2_rect *comp, *crops[SMIAPP_PADS]; | 1688 | struct v4l2_rect *comp, *crops[SMIAPP_PADS]; |
1689 | 1689 | ||
1690 | smiapp_get_crop_compose(subdev, fh, crops, &comp, which); | 1690 | smiapp_get_crop_compose(subdev, cfg, crops, &comp, which); |
1691 | 1691 | ||
1692 | switch (target) { | 1692 | switch (target) { |
1693 | case V4L2_SEL_TGT_CROP: | 1693 | case V4L2_SEL_TGT_CROP: |
@@ -1730,7 +1730,7 @@ static const struct smiapp_csi_data_format | |||
1730 | } | 1730 | } |
1731 | 1731 | ||
1732 | static int smiapp_set_format_source(struct v4l2_subdev *subdev, | 1732 | static int smiapp_set_format_source(struct v4l2_subdev *subdev, |
1733 | struct v4l2_subdev_fh *fh, | 1733 | struct v4l2_subdev_pad_config *cfg, |
1734 | struct v4l2_subdev_format *fmt) | 1734 | struct v4l2_subdev_format *fmt) |
1735 | { | 1735 | { |
1736 | struct smiapp_sensor *sensor = to_smiapp_sensor(subdev); | 1736 | struct smiapp_sensor *sensor = to_smiapp_sensor(subdev); |
@@ -1741,7 +1741,7 @@ static int smiapp_set_format_source(struct v4l2_subdev *subdev, | |||
1741 | unsigned int i; | 1741 | unsigned int i; |
1742 | int rval; | 1742 | int rval; |
1743 | 1743 | ||
1744 | rval = __smiapp_get_format(subdev, fh, fmt); | 1744 | rval = __smiapp_get_format(subdev, cfg, fmt); |
1745 | if (rval) | 1745 | if (rval) |
1746 | return rval; | 1746 | return rval; |
1747 | 1747 | ||
@@ -1783,7 +1783,7 @@ static int smiapp_set_format_source(struct v4l2_subdev *subdev, | |||
1783 | } | 1783 | } |
1784 | 1784 | ||
1785 | static int smiapp_set_format(struct v4l2_subdev *subdev, | 1785 | static int smiapp_set_format(struct v4l2_subdev *subdev, |
1786 | struct v4l2_subdev_fh *fh, | 1786 | struct v4l2_subdev_pad_config *cfg, |
1787 | struct v4l2_subdev_format *fmt) | 1787 | struct v4l2_subdev_format *fmt) |
1788 | { | 1788 | { |
1789 | struct smiapp_sensor *sensor = to_smiapp_sensor(subdev); | 1789 | struct smiapp_sensor *sensor = to_smiapp_sensor(subdev); |
@@ -1795,7 +1795,7 @@ static int smiapp_set_format(struct v4l2_subdev *subdev, | |||
1795 | if (fmt->pad == ssd->source_pad) { | 1795 | if (fmt->pad == ssd->source_pad) { |
1796 | int rval; | 1796 | int rval; |
1797 | 1797 | ||
1798 | rval = smiapp_set_format_source(subdev, fh, fmt); | 1798 | rval = smiapp_set_format_source(subdev, cfg, fmt); |
1799 | 1799 | ||
1800 | mutex_unlock(&sensor->mutex); | 1800 | mutex_unlock(&sensor->mutex); |
1801 | 1801 | ||
@@ -1817,7 +1817,7 @@ static int smiapp_set_format(struct v4l2_subdev *subdev, | |||
1817 | sensor->limits[SMIAPP_LIMIT_MIN_Y_OUTPUT_SIZE], | 1817 | sensor->limits[SMIAPP_LIMIT_MIN_Y_OUTPUT_SIZE], |
1818 | sensor->limits[SMIAPP_LIMIT_MAX_Y_OUTPUT_SIZE]); | 1818 | sensor->limits[SMIAPP_LIMIT_MAX_Y_OUTPUT_SIZE]); |
1819 | 1819 | ||
1820 | smiapp_get_crop_compose(subdev, fh, crops, NULL, fmt->which); | 1820 | smiapp_get_crop_compose(subdev, cfg, crops, NULL, fmt->which); |
1821 | 1821 | ||
1822 | crops[ssd->sink_pad]->left = 0; | 1822 | crops[ssd->sink_pad]->left = 0; |
1823 | crops[ssd->sink_pad]->top = 0; | 1823 | crops[ssd->sink_pad]->top = 0; |
@@ -1825,7 +1825,7 @@ static int smiapp_set_format(struct v4l2_subdev *subdev, | |||
1825 | crops[ssd->sink_pad]->height = fmt->format.height; | 1825 | crops[ssd->sink_pad]->height = fmt->format.height; |
1826 | if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) | 1826 | if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) |
1827 | ssd->sink_fmt = *crops[ssd->sink_pad]; | 1827 | ssd->sink_fmt = *crops[ssd->sink_pad]; |
1828 | smiapp_propagate(subdev, fh, fmt->which, | 1828 | smiapp_propagate(subdev, cfg, fmt->which, |
1829 | V4L2_SEL_TGT_CROP); | 1829 | V4L2_SEL_TGT_CROP); |
1830 | 1830 | ||
1831 | mutex_unlock(&sensor->mutex); | 1831 | mutex_unlock(&sensor->mutex); |
@@ -1878,7 +1878,7 @@ static int scaling_goodness(struct v4l2_subdev *subdev, int w, int ask_w, | |||
1878 | } | 1878 | } |
1879 | 1879 | ||
1880 | static void smiapp_set_compose_binner(struct v4l2_subdev *subdev, | 1880 | static void smiapp_set_compose_binner(struct v4l2_subdev *subdev, |
1881 | struct v4l2_subdev_fh *fh, | 1881 | struct v4l2_subdev_pad_config *cfg, |
1882 | struct v4l2_subdev_selection *sel, | 1882 | struct v4l2_subdev_selection *sel, |
1883 | struct v4l2_rect **crops, | 1883 | struct v4l2_rect **crops, |
1884 | struct v4l2_rect *comp) | 1884 | struct v4l2_rect *comp) |
@@ -1926,7 +1926,7 @@ static void smiapp_set_compose_binner(struct v4l2_subdev *subdev, | |||
1926 | * result. | 1926 | * result. |
1927 | */ | 1927 | */ |
1928 | static void smiapp_set_compose_scaler(struct v4l2_subdev *subdev, | 1928 | static void smiapp_set_compose_scaler(struct v4l2_subdev *subdev, |
1929 | struct v4l2_subdev_fh *fh, | 1929 | struct v4l2_subdev_pad_config *cfg, |
1930 | struct v4l2_subdev_selection *sel, | 1930 | struct v4l2_subdev_selection *sel, |
1931 | struct v4l2_rect **crops, | 1931 | struct v4l2_rect **crops, |
1932 | struct v4l2_rect *comp) | 1932 | struct v4l2_rect *comp) |
@@ -2042,25 +2042,25 @@ static void smiapp_set_compose_scaler(struct v4l2_subdev *subdev, | |||
2042 | } | 2042 | } |
2043 | /* We're only called on source pads. This function sets scaling. */ | 2043 | /* We're only called on source pads. This function sets scaling. */ |
2044 | static int smiapp_set_compose(struct v4l2_subdev *subdev, | 2044 | static int smiapp_set_compose(struct v4l2_subdev *subdev, |
2045 | struct v4l2_subdev_fh *fh, | 2045 | struct v4l2_subdev_pad_config *cfg, |
2046 | struct v4l2_subdev_selection *sel) | 2046 | struct v4l2_subdev_selection *sel) |
2047 | { | 2047 | { |
2048 | struct smiapp_sensor *sensor = to_smiapp_sensor(subdev); | 2048 | struct smiapp_sensor *sensor = to_smiapp_sensor(subdev); |
2049 | struct smiapp_subdev *ssd = to_smiapp_subdev(subdev); | 2049 | struct smiapp_subdev *ssd = to_smiapp_subdev(subdev); |
2050 | struct v4l2_rect *comp, *crops[SMIAPP_PADS]; | 2050 | struct v4l2_rect *comp, *crops[SMIAPP_PADS]; |
2051 | 2051 | ||
2052 | smiapp_get_crop_compose(subdev, fh, crops, &comp, sel->which); | 2052 | smiapp_get_crop_compose(subdev, cfg, crops, &comp, sel->which); |
2053 | 2053 | ||
2054 | sel->r.top = 0; | 2054 | sel->r.top = 0; |
2055 | sel->r.left = 0; | 2055 | sel->r.left = 0; |
2056 | 2056 | ||
2057 | if (ssd == sensor->binner) | 2057 | if (ssd == sensor->binner) |
2058 | smiapp_set_compose_binner(subdev, fh, sel, crops, comp); | 2058 | smiapp_set_compose_binner(subdev, cfg, sel, crops, comp); |
2059 | else | 2059 | else |
2060 | smiapp_set_compose_scaler(subdev, fh, sel, crops, comp); | 2060 | smiapp_set_compose_scaler(subdev, cfg, sel, crops, comp); |
2061 | 2061 | ||
2062 | *comp = sel->r; | 2062 | *comp = sel->r; |
2063 | smiapp_propagate(subdev, fh, sel->which, | 2063 | smiapp_propagate(subdev, cfg, sel->which, |
2064 | V4L2_SEL_TGT_COMPOSE); | 2064 | V4L2_SEL_TGT_COMPOSE); |
2065 | 2065 | ||
2066 | if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) | 2066 | if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) |
@@ -2113,7 +2113,7 @@ static int __smiapp_sel_supported(struct v4l2_subdev *subdev, | |||
2113 | } | 2113 | } |
2114 | 2114 | ||
2115 | static int smiapp_set_crop(struct v4l2_subdev *subdev, | 2115 | static int smiapp_set_crop(struct v4l2_subdev *subdev, |
2116 | struct v4l2_subdev_fh *fh, | 2116 | struct v4l2_subdev_pad_config *cfg, |
2117 | struct v4l2_subdev_selection *sel) | 2117 | struct v4l2_subdev_selection *sel) |
2118 | { | 2118 | { |
2119 | struct smiapp_sensor *sensor = to_smiapp_sensor(subdev); | 2119 | struct smiapp_sensor *sensor = to_smiapp_sensor(subdev); |
@@ -2121,7 +2121,7 @@ static int smiapp_set_crop(struct v4l2_subdev *subdev, | |||
2121 | struct v4l2_rect *src_size, *crops[SMIAPP_PADS]; | 2121 | struct v4l2_rect *src_size, *crops[SMIAPP_PADS]; |
2122 | struct v4l2_rect _r; | 2122 | struct v4l2_rect _r; |
2123 | 2123 | ||
2124 | smiapp_get_crop_compose(subdev, fh, crops, NULL, sel->which); | 2124 | smiapp_get_crop_compose(subdev, cfg, crops, NULL, sel->which); |
2125 | 2125 | ||
2126 | if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) { | 2126 | if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) { |
2127 | if (sel->pad == ssd->sink_pad) | 2127 | if (sel->pad == ssd->sink_pad) |
@@ -2132,15 +2132,15 @@ static int smiapp_set_crop(struct v4l2_subdev *subdev, | |||
2132 | if (sel->pad == ssd->sink_pad) { | 2132 | if (sel->pad == ssd->sink_pad) { |
2133 | _r.left = 0; | 2133 | _r.left = 0; |
2134 | _r.top = 0; | 2134 | _r.top = 0; |
2135 | _r.width = v4l2_subdev_get_try_format(fh, sel->pad) | 2135 | _r.width = v4l2_subdev_get_try_format(subdev, cfg, sel->pad) |
2136 | ->width; | 2136 | ->width; |
2137 | _r.height = v4l2_subdev_get_try_format(fh, sel->pad) | 2137 | _r.height = v4l2_subdev_get_try_format(subdev, cfg, sel->pad) |
2138 | ->height; | 2138 | ->height; |
2139 | src_size = &_r; | 2139 | src_size = &_r; |
2140 | } else { | 2140 | } else { |
2141 | src_size = | 2141 | src_size = |
2142 | v4l2_subdev_get_try_compose( | 2142 | v4l2_subdev_get_try_compose( |
2143 | fh, ssd->sink_pad); | 2143 | subdev, cfg, ssd->sink_pad); |
2144 | } | 2144 | } |
2145 | } | 2145 | } |
2146 | 2146 | ||
@@ -2158,14 +2158,14 @@ static int smiapp_set_crop(struct v4l2_subdev *subdev, | |||
2158 | *crops[sel->pad] = sel->r; | 2158 | *crops[sel->pad] = sel->r; |
2159 | 2159 | ||
2160 | if (ssd != sensor->pixel_array && sel->pad == SMIAPP_PAD_SINK) | 2160 | if (ssd != sensor->pixel_array && sel->pad == SMIAPP_PAD_SINK) |
2161 | smiapp_propagate(subdev, fh, sel->which, | 2161 | smiapp_propagate(subdev, cfg, sel->which, |
2162 | V4L2_SEL_TGT_CROP); | 2162 | V4L2_SEL_TGT_CROP); |
2163 | 2163 | ||
2164 | return 0; | 2164 | return 0; |
2165 | } | 2165 | } |
2166 | 2166 | ||
2167 | static int __smiapp_get_selection(struct v4l2_subdev *subdev, | 2167 | static int __smiapp_get_selection(struct v4l2_subdev *subdev, |
2168 | struct v4l2_subdev_fh *fh, | 2168 | struct v4l2_subdev_pad_config *cfg, |
2169 | struct v4l2_subdev_selection *sel) | 2169 | struct v4l2_subdev_selection *sel) |
2170 | { | 2170 | { |
2171 | struct smiapp_sensor *sensor = to_smiapp_sensor(subdev); | 2171 | struct smiapp_sensor *sensor = to_smiapp_sensor(subdev); |
@@ -2178,13 +2178,13 @@ static int __smiapp_get_selection(struct v4l2_subdev *subdev, | |||
2178 | if (ret) | 2178 | if (ret) |
2179 | return ret; | 2179 | return ret; |
2180 | 2180 | ||
2181 | smiapp_get_crop_compose(subdev, fh, crops, &comp, sel->which); | 2181 | smiapp_get_crop_compose(subdev, cfg, crops, &comp, sel->which); |
2182 | 2182 | ||
2183 | if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) { | 2183 | if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) { |
2184 | sink_fmt = ssd->sink_fmt; | 2184 | sink_fmt = ssd->sink_fmt; |
2185 | } else { | 2185 | } else { |
2186 | struct v4l2_mbus_framefmt *fmt = | 2186 | struct v4l2_mbus_framefmt *fmt = |
2187 | v4l2_subdev_get_try_format(fh, ssd->sink_pad); | 2187 | v4l2_subdev_get_try_format(subdev, cfg, ssd->sink_pad); |
2188 | 2188 | ||
2189 | sink_fmt.left = 0; | 2189 | sink_fmt.left = 0; |
2190 | sink_fmt.top = 0; | 2190 | sink_fmt.top = 0; |
@@ -2220,20 +2220,20 @@ static int __smiapp_get_selection(struct v4l2_subdev *subdev, | |||
2220 | } | 2220 | } |
2221 | 2221 | ||
2222 | static int smiapp_get_selection(struct v4l2_subdev *subdev, | 2222 | static int smiapp_get_selection(struct v4l2_subdev *subdev, |
2223 | struct v4l2_subdev_fh *fh, | 2223 | struct v4l2_subdev_pad_config *cfg, |
2224 | struct v4l2_subdev_selection *sel) | 2224 | struct v4l2_subdev_selection *sel) |
2225 | { | 2225 | { |
2226 | struct smiapp_sensor *sensor = to_smiapp_sensor(subdev); | 2226 | struct smiapp_sensor *sensor = to_smiapp_sensor(subdev); |
2227 | int rval; | 2227 | int rval; |
2228 | 2228 | ||
2229 | mutex_lock(&sensor->mutex); | 2229 | mutex_lock(&sensor->mutex); |
2230 | rval = __smiapp_get_selection(subdev, fh, sel); | 2230 | rval = __smiapp_get_selection(subdev, cfg, sel); |
2231 | mutex_unlock(&sensor->mutex); | 2231 | mutex_unlock(&sensor->mutex); |
2232 | 2232 | ||
2233 | return rval; | 2233 | return rval; |
2234 | } | 2234 | } |
2235 | static int smiapp_set_selection(struct v4l2_subdev *subdev, | 2235 | static int smiapp_set_selection(struct v4l2_subdev *subdev, |
2236 | struct v4l2_subdev_fh *fh, | 2236 | struct v4l2_subdev_pad_config *cfg, |
2237 | struct v4l2_subdev_selection *sel) | 2237 | struct v4l2_subdev_selection *sel) |
2238 | { | 2238 | { |
2239 | struct smiapp_sensor *sensor = to_smiapp_sensor(subdev); | 2239 | struct smiapp_sensor *sensor = to_smiapp_sensor(subdev); |
@@ -2259,10 +2259,10 @@ static int smiapp_set_selection(struct v4l2_subdev *subdev, | |||
2259 | 2259 | ||
2260 | switch (sel->target) { | 2260 | switch (sel->target) { |
2261 | case V4L2_SEL_TGT_CROP: | 2261 | case V4L2_SEL_TGT_CROP: |
2262 | ret = smiapp_set_crop(subdev, fh, sel); | 2262 | ret = smiapp_set_crop(subdev, cfg, sel); |
2263 | break; | 2263 | break; |
2264 | case V4L2_SEL_TGT_COMPOSE: | 2264 | case V4L2_SEL_TGT_COMPOSE: |
2265 | ret = smiapp_set_compose(subdev, fh, sel); | 2265 | ret = smiapp_set_compose(subdev, cfg, sel); |
2266 | break; | 2266 | break; |
2267 | default: | 2267 | default: |
2268 | ret = -EINVAL; | 2268 | ret = -EINVAL; |
@@ -2841,8 +2841,8 @@ static int smiapp_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) | |||
2841 | 2841 | ||
2842 | for (i = 0; i < ssd->npads; i++) { | 2842 | for (i = 0; i < ssd->npads; i++) { |
2843 | struct v4l2_mbus_framefmt *try_fmt = | 2843 | struct v4l2_mbus_framefmt *try_fmt = |
2844 | v4l2_subdev_get_try_format(fh, i); | 2844 | v4l2_subdev_get_try_format(sd, fh->pad, i); |
2845 | struct v4l2_rect *try_crop = v4l2_subdev_get_try_crop(fh, i); | 2845 | struct v4l2_rect *try_crop = v4l2_subdev_get_try_crop(sd, fh->pad, i); |
2846 | struct v4l2_rect *try_comp; | 2846 | struct v4l2_rect *try_comp; |
2847 | 2847 | ||
2848 | try_fmt->width = sensor->limits[SMIAPP_LIMIT_X_ADDR_MAX] + 1; | 2848 | try_fmt->width = sensor->limits[SMIAPP_LIMIT_X_ADDR_MAX] + 1; |
@@ -2858,7 +2858,7 @@ static int smiapp_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) | |||
2858 | if (ssd != sensor->pixel_array) | 2858 | if (ssd != sensor->pixel_array) |
2859 | continue; | 2859 | continue; |
2860 | 2860 | ||
2861 | try_comp = v4l2_subdev_get_try_compose(fh, i); | 2861 | try_comp = v4l2_subdev_get_try_compose(sd, fh->pad, i); |
2862 | *try_comp = *try_crop; | 2862 | *try_comp = *try_crop; |
2863 | } | 2863 | } |
2864 | 2864 | ||
@@ -2977,12 +2977,7 @@ static struct smiapp_platform_data *smiapp_get_pdata(struct device *dev) | |||
2977 | struct smiapp_platform_data *pdata; | 2977 | struct smiapp_platform_data *pdata; |
2978 | struct v4l2_of_endpoint bus_cfg; | 2978 | struct v4l2_of_endpoint bus_cfg; |
2979 | struct device_node *ep; | 2979 | struct device_node *ep; |
2980 | struct property *prop; | ||
2981 | __be32 *val; | ||
2982 | uint32_t asize; | 2980 | uint32_t asize; |
2983 | #ifdef CONFIG_OF | ||
2984 | unsigned int i; | ||
2985 | #endif | ||
2986 | int rval; | 2981 | int rval; |
2987 | 2982 | ||
2988 | if (!dev->of_node) | 2983 | if (!dev->of_node) |
@@ -2993,10 +2988,8 @@ static struct smiapp_platform_data *smiapp_get_pdata(struct device *dev) | |||
2993 | return NULL; | 2988 | return NULL; |
2994 | 2989 | ||
2995 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | 2990 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); |
2996 | if (!pdata) { | 2991 | if (!pdata) |
2997 | rval = -ENOMEM; | ||
2998 | goto out_err; | 2992 | goto out_err; |
2999 | } | ||
3000 | 2993 | ||
3001 | v4l2_of_parse_endpoint(ep, &bus_cfg); | 2994 | v4l2_of_parse_endpoint(ep, &bus_cfg); |
3002 | 2995 | ||
@@ -3006,7 +2999,6 @@ static struct smiapp_platform_data *smiapp_get_pdata(struct device *dev) | |||
3006 | break; | 2999 | break; |
3007 | /* FIXME: add CCP2 support. */ | 3000 | /* FIXME: add CCP2 support. */ |
3008 | default: | 3001 | default: |
3009 | rval = -EINVAL; | ||
3010 | goto out_err; | 3002 | goto out_err; |
3011 | } | 3003 | } |
3012 | 3004 | ||
@@ -3030,8 +3022,7 @@ static struct smiapp_platform_data *smiapp_get_pdata(struct device *dev) | |||
3030 | dev_dbg(dev, "reset %d, nvm %d, clk %d, csi %d\n", pdata->xshutdown, | 3022 | dev_dbg(dev, "reset %d, nvm %d, clk %d, csi %d\n", pdata->xshutdown, |
3031 | pdata->nvm_size, pdata->ext_clk, pdata->csi_signalling_mode); | 3023 | pdata->nvm_size, pdata->ext_clk, pdata->csi_signalling_mode); |
3032 | 3024 | ||
3033 | rval = of_get_property( | 3025 | rval = of_get_property(ep, "link-frequencies", &asize) ? 0 : -ENOENT; |
3034 | dev->of_node, "link-frequencies", &asize) ? 0 : -ENOENT; | ||
3035 | if (rval) { | 3026 | if (rval) { |
3036 | dev_warn(dev, "can't get link-frequencies array size\n"); | 3027 | dev_warn(dev, "can't get link-frequencies array size\n"); |
3037 | goto out_err; | 3028 | goto out_err; |
@@ -3044,25 +3035,12 @@ static struct smiapp_platform_data *smiapp_get_pdata(struct device *dev) | |||
3044 | } | 3035 | } |
3045 | 3036 | ||
3046 | asize /= sizeof(*pdata->op_sys_clock); | 3037 | asize /= sizeof(*pdata->op_sys_clock); |
3047 | /* | 3038 | rval = of_property_read_u64_array( |
3048 | * Read a 64-bit array --- this will be replaced with a | 3039 | ep, "link-frequencies", pdata->op_sys_clock, asize); |
3049 | * of_property_read_u64_array() once it's merged. | 3040 | if (rval) { |
3050 | */ | 3041 | dev_warn(dev, "can't get link-frequencies\n"); |
3051 | prop = of_find_property(dev->of_node, "link-frequencies", NULL); | ||
3052 | if (!prop) | ||
3053 | goto out_err; | ||
3054 | if (!prop->value) | ||
3055 | goto out_err; | ||
3056 | if (asize * sizeof(*pdata->op_sys_clock) > prop->length) | ||
3057 | goto out_err; | ||
3058 | val = prop->value; | ||
3059 | if (IS_ERR(val)) | ||
3060 | goto out_err; | 3042 | goto out_err; |
3061 | 3043 | } | |
3062 | #ifdef CONFIG_OF | ||
3063 | for (i = 0; i < asize; i++) | ||
3064 | pdata->op_sys_clock[i] = of_read_number(val + i * 2, 2); | ||
3065 | #endif | ||
3066 | 3044 | ||
3067 | for (; asize > 0; asize--) | 3045 | for (; asize > 0; asize--) |
3068 | dev_dbg(dev, "freq %d: %lld\n", asize - 1, | 3046 | dev_dbg(dev, "freq %d: %lld\n", asize - 1, |
diff --git a/drivers/media/i2c/soc_camera/mt9m111.c b/drivers/media/i2c/soc_camera/mt9m111.c index 5992ea93257a..441e0fda24fe 100644 --- a/drivers/media/i2c/soc_camera/mt9m111.c +++ b/drivers/media/i2c/soc_camera/mt9m111.c | |||
@@ -1016,7 +1016,6 @@ static int mt9m111_remove(struct i2c_client *client) | |||
1016 | 1016 | ||
1017 | v4l2_async_unregister_subdev(&mt9m111->subdev); | 1017 | v4l2_async_unregister_subdev(&mt9m111->subdev); |
1018 | v4l2_clk_put(mt9m111->clk); | 1018 | v4l2_clk_put(mt9m111->clk); |
1019 | v4l2_device_unregister_subdev(&mt9m111->subdev); | ||
1020 | v4l2_ctrl_handler_free(&mt9m111->hdl); | 1019 | v4l2_ctrl_handler_free(&mt9m111->hdl); |
1021 | 1020 | ||
1022 | return 0; | 1021 | return 0; |
diff --git a/drivers/media/i2c/soc_camera/ov2640.c b/drivers/media/i2c/soc_camera/ov2640.c index 1fdce2f6f880..e3c907a97765 100644 --- a/drivers/media/i2c/soc_camera/ov2640.c +++ b/drivers/media/i2c/soc_camera/ov2640.c | |||
@@ -18,6 +18,9 @@ | |||
18 | #include <linux/i2c.h> | 18 | #include <linux/i2c.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
21 | #include <linux/gpio.h> | ||
22 | #include <linux/gpio/consumer.h> | ||
23 | #include <linux/of_gpio.h> | ||
21 | #include <linux/v4l2-mediabus.h> | 24 | #include <linux/v4l2-mediabus.h> |
22 | #include <linux/videodev2.h> | 25 | #include <linux/videodev2.h> |
23 | 26 | ||
@@ -283,6 +286,10 @@ struct ov2640_priv { | |||
283 | u32 cfmt_code; | 286 | u32 cfmt_code; |
284 | struct v4l2_clk *clk; | 287 | struct v4l2_clk *clk; |
285 | const struct ov2640_win_size *win; | 288 | const struct ov2640_win_size *win; |
289 | |||
290 | struct soc_camera_subdev_desc ssdd_dt; | ||
291 | struct gpio_desc *resetb_gpio; | ||
292 | struct gpio_desc *pwdn_gpio; | ||
286 | }; | 293 | }; |
287 | 294 | ||
288 | /* | 295 | /* |
@@ -1038,6 +1045,63 @@ static struct v4l2_subdev_ops ov2640_subdev_ops = { | |||
1038 | .video = &ov2640_subdev_video_ops, | 1045 | .video = &ov2640_subdev_video_ops, |
1039 | }; | 1046 | }; |
1040 | 1047 | ||
1048 | /* OF probe functions */ | ||
1049 | static int ov2640_hw_power(struct device *dev, int on) | ||
1050 | { | ||
1051 | struct i2c_client *client = to_i2c_client(dev); | ||
1052 | struct ov2640_priv *priv = to_ov2640(client); | ||
1053 | |||
1054 | dev_dbg(&client->dev, "%s: %s the camera\n", | ||
1055 | __func__, on ? "ENABLE" : "DISABLE"); | ||
1056 | |||
1057 | if (priv->pwdn_gpio) | ||
1058 | gpiod_direction_output(priv->pwdn_gpio, !on); | ||
1059 | |||
1060 | return 0; | ||
1061 | } | ||
1062 | |||
1063 | static int ov2640_hw_reset(struct device *dev) | ||
1064 | { | ||
1065 | struct i2c_client *client = to_i2c_client(dev); | ||
1066 | struct ov2640_priv *priv = to_ov2640(client); | ||
1067 | |||
1068 | if (priv->resetb_gpio) { | ||
1069 | /* Active the resetb pin to perform a reset pulse */ | ||
1070 | gpiod_direction_output(priv->resetb_gpio, 1); | ||
1071 | usleep_range(3000, 5000); | ||
1072 | gpiod_direction_output(priv->resetb_gpio, 0); | ||
1073 | } | ||
1074 | |||
1075 | return 0; | ||
1076 | } | ||
1077 | |||
1078 | static int ov2640_probe_dt(struct i2c_client *client, | ||
1079 | struct ov2640_priv *priv) | ||
1080 | { | ||
1081 | /* Request the reset GPIO deasserted */ | ||
1082 | priv->resetb_gpio = devm_gpiod_get_optional(&client->dev, "resetb", | ||
1083 | GPIOD_OUT_LOW); | ||
1084 | if (!priv->resetb_gpio) | ||
1085 | dev_dbg(&client->dev, "resetb gpio is not assigned!\n"); | ||
1086 | else if (IS_ERR(priv->resetb_gpio)) | ||
1087 | return PTR_ERR(priv->resetb_gpio); | ||
1088 | |||
1089 | /* Request the power down GPIO asserted */ | ||
1090 | priv->pwdn_gpio = devm_gpiod_get_optional(&client->dev, "pwdn", | ||
1091 | GPIOD_OUT_HIGH); | ||
1092 | if (!priv->pwdn_gpio) | ||
1093 | dev_dbg(&client->dev, "pwdn gpio is not assigned!\n"); | ||
1094 | else if (IS_ERR(priv->pwdn_gpio)) | ||
1095 | return PTR_ERR(priv->pwdn_gpio); | ||
1096 | |||
1097 | /* Initialize the soc_camera_subdev_desc */ | ||
1098 | priv->ssdd_dt.power = ov2640_hw_power; | ||
1099 | priv->ssdd_dt.reset = ov2640_hw_reset; | ||
1100 | client->dev.platform_data = &priv->ssdd_dt; | ||
1101 | |||
1102 | return 0; | ||
1103 | } | ||
1104 | |||
1041 | /* | 1105 | /* |
1042 | * i2c_driver functions | 1106 | * i2c_driver functions |
1043 | */ | 1107 | */ |
@@ -1049,12 +1113,6 @@ static int ov2640_probe(struct i2c_client *client, | |||
1049 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | 1113 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); |
1050 | int ret; | 1114 | int ret; |
1051 | 1115 | ||
1052 | if (!ssdd) { | ||
1053 | dev_err(&adapter->dev, | ||
1054 | "OV2640: Missing platform_data for driver\n"); | ||
1055 | return -EINVAL; | ||
1056 | } | ||
1057 | |||
1058 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { | 1116 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { |
1059 | dev_err(&adapter->dev, | 1117 | dev_err(&adapter->dev, |
1060 | "OV2640: I2C-Adapter doesn't support SMBUS\n"); | 1118 | "OV2640: I2C-Adapter doesn't support SMBUS\n"); |
@@ -1068,6 +1126,22 @@ static int ov2640_probe(struct i2c_client *client, | |||
1068 | return -ENOMEM; | 1126 | return -ENOMEM; |
1069 | } | 1127 | } |
1070 | 1128 | ||
1129 | priv->clk = v4l2_clk_get(&client->dev, "xvclk"); | ||
1130 | if (IS_ERR(priv->clk)) | ||
1131 | return -EPROBE_DEFER; | ||
1132 | |||
1133 | if (!ssdd && !client->dev.of_node) { | ||
1134 | dev_err(&client->dev, "Missing platform_data for driver\n"); | ||
1135 | ret = -EINVAL; | ||
1136 | goto err_clk; | ||
1137 | } | ||
1138 | |||
1139 | if (!ssdd) { | ||
1140 | ret = ov2640_probe_dt(client, priv); | ||
1141 | if (ret) | ||
1142 | goto err_clk; | ||
1143 | } | ||
1144 | |||
1071 | v4l2_i2c_subdev_init(&priv->subdev, client, &ov2640_subdev_ops); | 1145 | v4l2_i2c_subdev_init(&priv->subdev, client, &ov2640_subdev_ops); |
1072 | v4l2_ctrl_handler_init(&priv->hdl, 2); | 1146 | v4l2_ctrl_handler_init(&priv->hdl, 2); |
1073 | v4l2_ctrl_new_std(&priv->hdl, &ov2640_ctrl_ops, | 1147 | v4l2_ctrl_new_std(&priv->hdl, &ov2640_ctrl_ops, |
@@ -1075,24 +1149,27 @@ static int ov2640_probe(struct i2c_client *client, | |||
1075 | v4l2_ctrl_new_std(&priv->hdl, &ov2640_ctrl_ops, | 1149 | v4l2_ctrl_new_std(&priv->hdl, &ov2640_ctrl_ops, |
1076 | V4L2_CID_HFLIP, 0, 1, 1, 0); | 1150 | V4L2_CID_HFLIP, 0, 1, 1, 0); |
1077 | priv->subdev.ctrl_handler = &priv->hdl; | 1151 | priv->subdev.ctrl_handler = &priv->hdl; |
1078 | if (priv->hdl.error) | 1152 | if (priv->hdl.error) { |
1079 | return priv->hdl.error; | 1153 | ret = priv->hdl.error; |
1080 | 1154 | goto err_clk; | |
1081 | priv->clk = v4l2_clk_get(&client->dev, "mclk"); | ||
1082 | if (IS_ERR(priv->clk)) { | ||
1083 | ret = PTR_ERR(priv->clk); | ||
1084 | goto eclkget; | ||
1085 | } | 1155 | } |
1086 | 1156 | ||
1087 | ret = ov2640_video_probe(client); | 1157 | ret = ov2640_video_probe(client); |
1088 | if (ret) { | 1158 | if (ret < 0) |
1089 | v4l2_clk_put(priv->clk); | 1159 | goto err_videoprobe; |
1090 | eclkget: | 1160 | |
1091 | v4l2_ctrl_handler_free(&priv->hdl); | 1161 | ret = v4l2_async_register_subdev(&priv->subdev); |
1092 | } else { | 1162 | if (ret < 0) |
1093 | dev_info(&adapter->dev, "OV2640 Probed\n"); | 1163 | goto err_videoprobe; |
1094 | } | 1164 | |
1165 | dev_info(&adapter->dev, "OV2640 Probed\n"); | ||
1095 | 1166 | ||
1167 | return 0; | ||
1168 | |||
1169 | err_videoprobe: | ||
1170 | v4l2_ctrl_handler_free(&priv->hdl); | ||
1171 | err_clk: | ||
1172 | v4l2_clk_put(priv->clk); | ||
1096 | return ret; | 1173 | return ret; |
1097 | } | 1174 | } |
1098 | 1175 | ||
@@ -1100,6 +1177,7 @@ static int ov2640_remove(struct i2c_client *client) | |||
1100 | { | 1177 | { |
1101 | struct ov2640_priv *priv = to_ov2640(client); | 1178 | struct ov2640_priv *priv = to_ov2640(client); |
1102 | 1179 | ||
1180 | v4l2_async_unregister_subdev(&priv->subdev); | ||
1103 | v4l2_clk_put(priv->clk); | 1181 | v4l2_clk_put(priv->clk); |
1104 | v4l2_device_unregister_subdev(&priv->subdev); | 1182 | v4l2_device_unregister_subdev(&priv->subdev); |
1105 | v4l2_ctrl_handler_free(&priv->hdl); | 1183 | v4l2_ctrl_handler_free(&priv->hdl); |
@@ -1112,9 +1190,16 @@ static const struct i2c_device_id ov2640_id[] = { | |||
1112 | }; | 1190 | }; |
1113 | MODULE_DEVICE_TABLE(i2c, ov2640_id); | 1191 | MODULE_DEVICE_TABLE(i2c, ov2640_id); |
1114 | 1192 | ||
1193 | static const struct of_device_id ov2640_of_match[] = { | ||
1194 | {.compatible = "ovti,ov2640", }, | ||
1195 | {}, | ||
1196 | }; | ||
1197 | MODULE_DEVICE_TABLE(of, ov2640_of_match); | ||
1198 | |||
1115 | static struct i2c_driver ov2640_i2c_driver = { | 1199 | static struct i2c_driver ov2640_i2c_driver = { |
1116 | .driver = { | 1200 | .driver = { |
1117 | .name = "ov2640", | 1201 | .name = "ov2640", |
1202 | .of_match_table = of_match_ptr(ov2640_of_match), | ||
1118 | }, | 1203 | }, |
1119 | .probe = ov2640_probe, | 1204 | .probe = ov2640_probe, |
1120 | .remove = ov2640_remove, | 1205 | .remove = ov2640_remove, |
diff --git a/drivers/media/i2c/ths7303.c b/drivers/media/i2c/ths7303.c index ed9ae8875348..9f7fdb6b61ca 100644 --- a/drivers/media/i2c/ths7303.c +++ b/drivers/media/i2c/ths7303.c | |||
@@ -52,10 +52,6 @@ MODULE_DESCRIPTION("TI THS7303 video amplifier driver"); | |||
52 | MODULE_AUTHOR("Chaithrika U S"); | 52 | MODULE_AUTHOR("Chaithrika U S"); |
53 | MODULE_LICENSE("GPL"); | 53 | MODULE_LICENSE("GPL"); |
54 | 54 | ||
55 | static int debug; | ||
56 | module_param(debug, int, 0644); | ||
57 | MODULE_PARM_DESC(debug, "Debug level 0-1"); | ||
58 | |||
59 | static inline struct ths7303_state *to_state(struct v4l2_subdev *sd) | 55 | static inline struct ths7303_state *to_state(struct v4l2_subdev *sd) |
60 | { | 56 | { |
61 | return container_of(sd, struct ths7303_state, sd); | 57 | return container_of(sd, struct ths7303_state, sd); |
diff --git a/drivers/media/i2c/ths8200.c b/drivers/media/i2c/ths8200.c index 4ebd329d7b42..73fc42bc2de6 100644 --- a/drivers/media/i2c/ths8200.c +++ b/drivers/media/i2c/ths8200.c | |||
@@ -479,7 +479,6 @@ static int ths8200_remove(struct i2c_client *client) | |||
479 | 479 | ||
480 | ths8200_s_power(sd, false); | 480 | ths8200_s_power(sd, false); |
481 | v4l2_async_unregister_subdev(&decoder->sd); | 481 | v4l2_async_unregister_subdev(&decoder->sd); |
482 | v4l2_device_unregister_subdev(sd); | ||
483 | 482 | ||
484 | return 0; | 483 | return 0; |
485 | } | 484 | } |
diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c index 204204259ac6..1c6bc306ecdc 100644 --- a/drivers/media/i2c/tvp514x.c +++ b/drivers/media/i2c/tvp514x.c | |||
@@ -923,13 +923,13 @@ static const struct v4l2_ctrl_ops tvp514x_ctrl_ops = { | |||
923 | /** | 923 | /** |
924 | * tvp514x_enum_mbus_code() - V4L2 decoder interface handler for enum_mbus_code | 924 | * tvp514x_enum_mbus_code() - V4L2 decoder interface handler for enum_mbus_code |
925 | * @sd: pointer to standard V4L2 sub-device structure | 925 | * @sd: pointer to standard V4L2 sub-device structure |
926 | * @fh: file handle | 926 | * @cfg: pad configuration |
927 | * @code: pointer to v4l2_subdev_mbus_code_enum structure | 927 | * @code: pointer to v4l2_subdev_mbus_code_enum structure |
928 | * | 928 | * |
929 | * Enumertaes mbus codes supported | 929 | * Enumertaes mbus codes supported |
930 | */ | 930 | */ |
931 | static int tvp514x_enum_mbus_code(struct v4l2_subdev *sd, | 931 | static int tvp514x_enum_mbus_code(struct v4l2_subdev *sd, |
932 | struct v4l2_subdev_fh *fh, | 932 | struct v4l2_subdev_pad_config *cfg, |
933 | struct v4l2_subdev_mbus_code_enum *code) | 933 | struct v4l2_subdev_mbus_code_enum *code) |
934 | { | 934 | { |
935 | u32 pad = code->pad; | 935 | u32 pad = code->pad; |
@@ -950,13 +950,13 @@ static int tvp514x_enum_mbus_code(struct v4l2_subdev *sd, | |||
950 | /** | 950 | /** |
951 | * tvp514x_get_pad_format() - V4L2 decoder interface handler for get pad format | 951 | * tvp514x_get_pad_format() - V4L2 decoder interface handler for get pad format |
952 | * @sd: pointer to standard V4L2 sub-device structure | 952 | * @sd: pointer to standard V4L2 sub-device structure |
953 | * @fh: file handle | 953 | * @cfg: pad configuration |
954 | * @format: pointer to v4l2_subdev_format structure | 954 | * @format: pointer to v4l2_subdev_format structure |
955 | * | 955 | * |
956 | * Retrieves pad format which is active or tried based on requirement | 956 | * Retrieves pad format which is active or tried based on requirement |
957 | */ | 957 | */ |
958 | static int tvp514x_get_pad_format(struct v4l2_subdev *sd, | 958 | static int tvp514x_get_pad_format(struct v4l2_subdev *sd, |
959 | struct v4l2_subdev_fh *fh, | 959 | struct v4l2_subdev_pad_config *cfg, |
960 | struct v4l2_subdev_format *format) | 960 | struct v4l2_subdev_format *format) |
961 | { | 961 | { |
962 | struct tvp514x_decoder *decoder = to_decoder(sd); | 962 | struct tvp514x_decoder *decoder = to_decoder(sd); |
@@ -979,13 +979,13 @@ static int tvp514x_get_pad_format(struct v4l2_subdev *sd, | |||
979 | /** | 979 | /** |
980 | * tvp514x_set_pad_format() - V4L2 decoder interface handler for set pad format | 980 | * tvp514x_set_pad_format() - V4L2 decoder interface handler for set pad format |
981 | * @sd: pointer to standard V4L2 sub-device structure | 981 | * @sd: pointer to standard V4L2 sub-device structure |
982 | * @fh: file handle | 982 | * @cfg: pad configuration |
983 | * @format: pointer to v4l2_subdev_format structure | 983 | * @format: pointer to v4l2_subdev_format structure |
984 | * | 984 | * |
985 | * Set pad format for the output pad | 985 | * Set pad format for the output pad |
986 | */ | 986 | */ |
987 | static int tvp514x_set_pad_format(struct v4l2_subdev *sd, | 987 | static int tvp514x_set_pad_format(struct v4l2_subdev *sd, |
988 | struct v4l2_subdev_fh *fh, | 988 | struct v4l2_subdev_pad_config *cfg, |
989 | struct v4l2_subdev_format *fmt) | 989 | struct v4l2_subdev_format *fmt) |
990 | { | 990 | { |
991 | struct tvp514x_decoder *decoder = to_decoder(sd); | 991 | struct tvp514x_decoder *decoder = to_decoder(sd); |
@@ -1209,7 +1209,6 @@ static int tvp514x_remove(struct i2c_client *client) | |||
1209 | struct tvp514x_decoder *decoder = to_decoder(sd); | 1209 | struct tvp514x_decoder *decoder = to_decoder(sd); |
1210 | 1210 | ||
1211 | v4l2_async_unregister_subdev(&decoder->sd); | 1211 | v4l2_async_unregister_subdev(&decoder->sd); |
1212 | v4l2_device_unregister_subdev(sd); | ||
1213 | #if defined(CONFIG_MEDIA_CONTROLLER) | 1212 | #if defined(CONFIG_MEDIA_CONTROLLER) |
1214 | media_entity_cleanup(&decoder->sd.entity); | 1213 | media_entity_cleanup(&decoder->sd.entity); |
1215 | #endif | 1214 | #endif |
diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c index fe4870e22cfe..787cdfb08749 100644 --- a/drivers/media/i2c/tvp7002.c +++ b/drivers/media/i2c/tvp7002.c | |||
@@ -846,13 +846,13 @@ static const struct v4l2_ctrl_ops tvp7002_ctrl_ops = { | |||
846 | /* | 846 | /* |
847 | * tvp7002_enum_mbus_code() - Enum supported digital video format on pad | 847 | * tvp7002_enum_mbus_code() - Enum supported digital video format on pad |
848 | * @sd: pointer to standard V4L2 sub-device structure | 848 | * @sd: pointer to standard V4L2 sub-device structure |
849 | * @fh: file handle for the subdev | 849 | * @cfg: pad configuration |
850 | * @code: pointer to subdev enum mbus code struct | 850 | * @code: pointer to subdev enum mbus code struct |
851 | * | 851 | * |
852 | * Enumerate supported digital video formats for pad. | 852 | * Enumerate supported digital video formats for pad. |
853 | */ | 853 | */ |
854 | static int | 854 | static int |
855 | tvp7002_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | 855 | tvp7002_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, |
856 | struct v4l2_subdev_mbus_code_enum *code) | 856 | struct v4l2_subdev_mbus_code_enum *code) |
857 | { | 857 | { |
858 | /* Check requested format index is within range */ | 858 | /* Check requested format index is within range */ |
@@ -867,13 +867,13 @@ tvp7002_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
867 | /* | 867 | /* |
868 | * tvp7002_get_pad_format() - get video format on pad | 868 | * tvp7002_get_pad_format() - get video format on pad |
869 | * @sd: pointer to standard V4L2 sub-device structure | 869 | * @sd: pointer to standard V4L2 sub-device structure |
870 | * @fh: file handle for the subdev | 870 | * @cfg: pad configuration |
871 | * @fmt: pointer to subdev format struct | 871 | * @fmt: pointer to subdev format struct |
872 | * | 872 | * |
873 | * get video format for pad. | 873 | * get video format for pad. |
874 | */ | 874 | */ |
875 | static int | 875 | static int |
876 | tvp7002_get_pad_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | 876 | tvp7002_get_pad_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, |
877 | struct v4l2_subdev_format *fmt) | 877 | struct v4l2_subdev_format *fmt) |
878 | { | 878 | { |
879 | struct tvp7002 *tvp7002 = to_tvp7002(sd); | 879 | struct tvp7002 *tvp7002 = to_tvp7002(sd); |
@@ -890,16 +890,16 @@ tvp7002_get_pad_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
890 | /* | 890 | /* |
891 | * tvp7002_set_pad_format() - set video format on pad | 891 | * tvp7002_set_pad_format() - set video format on pad |
892 | * @sd: pointer to standard V4L2 sub-device structure | 892 | * @sd: pointer to standard V4L2 sub-device structure |
893 | * @fh: file handle for the subdev | 893 | * @cfg: pad configuration |
894 | * @fmt: pointer to subdev format struct | 894 | * @fmt: pointer to subdev format struct |
895 | * | 895 | * |
896 | * set video format for pad. | 896 | * set video format for pad. |
897 | */ | 897 | */ |
898 | static int | 898 | static int |
899 | tvp7002_set_pad_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | 899 | tvp7002_set_pad_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, |
900 | struct v4l2_subdev_format *fmt) | 900 | struct v4l2_subdev_format *fmt) |
901 | { | 901 | { |
902 | return tvp7002_get_pad_format(sd, fh, fmt); | 902 | return tvp7002_get_pad_format(sd, cfg, fmt); |
903 | } | 903 | } |
904 | 904 | ||
905 | /* V4L2 core operation handlers */ | 905 | /* V4L2 core operation handlers */ |
@@ -1116,7 +1116,6 @@ static int tvp7002_remove(struct i2c_client *c) | |||
1116 | #if defined(CONFIG_MEDIA_CONTROLLER) | 1116 | #if defined(CONFIG_MEDIA_CONTROLLER) |
1117 | media_entity_cleanup(&device->sd.entity); | 1117 | media_entity_cleanup(&device->sd.entity); |
1118 | #endif | 1118 | #endif |
1119 | v4l2_device_unregister_subdev(sd); | ||
1120 | v4l2_ctrl_handler_free(&device->hdl); | 1119 | v4l2_ctrl_handler_free(&device->hdl); |
1121 | return 0; | 1120 | return 0; |
1122 | } | 1121 | } |
diff --git a/drivers/media/mmc/siano/smssdio.c b/drivers/media/mmc/siano/smssdio.c index 912c2814c6cf..fee2d710bbf8 100644 --- a/drivers/media/mmc/siano/smssdio.c +++ b/drivers/media/mmc/siano/smssdio.c | |||
@@ -32,6 +32,8 @@ | |||
32 | * Fix stop command | 32 | * Fix stop command |
33 | */ | 33 | */ |
34 | 34 | ||
35 | #include "smscoreapi.h" | ||
36 | |||
35 | #include <linux/moduleparam.h> | 37 | #include <linux/moduleparam.h> |
36 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
37 | #include <linux/firmware.h> | 39 | #include <linux/firmware.h> |
@@ -41,7 +43,6 @@ | |||
41 | #include <linux/mmc/sdio_ids.h> | 43 | #include <linux/mmc/sdio_ids.h> |
42 | #include <linux/module.h> | 44 | #include <linux/module.h> |
43 | 45 | ||
44 | #include "smscoreapi.h" | ||
45 | #include "sms-cards.h" | 46 | #include "sms-cards.h" |
46 | #include "smsendian.h" | 47 | #include "smsendian.h" |
47 | 48 | ||
@@ -141,14 +142,14 @@ static void smssdio_interrupt(struct sdio_func *func) | |||
141 | */ | 142 | */ |
142 | (void)sdio_readb(func, SMSSDIO_INT, &ret); | 143 | (void)sdio_readb(func, SMSSDIO_INT, &ret); |
143 | if (ret) { | 144 | if (ret) { |
144 | sms_err("Unable to read interrupt register!\n"); | 145 | pr_err("Unable to read interrupt register!\n"); |
145 | return; | 146 | return; |
146 | } | 147 | } |
147 | 148 | ||
148 | if (smsdev->split_cb == NULL) { | 149 | if (smsdev->split_cb == NULL) { |
149 | cb = smscore_getbuffer(smsdev->coredev); | 150 | cb = smscore_getbuffer(smsdev->coredev); |
150 | if (!cb) { | 151 | if (!cb) { |
151 | sms_err("Unable to allocate data buffer!\n"); | 152 | pr_err("Unable to allocate data buffer!\n"); |
152 | return; | 153 | return; |
153 | } | 154 | } |
154 | 155 | ||
@@ -157,7 +158,7 @@ static void smssdio_interrupt(struct sdio_func *func) | |||
157 | SMSSDIO_DATA, | 158 | SMSSDIO_DATA, |
158 | SMSSDIO_BLOCK_SIZE); | 159 | SMSSDIO_BLOCK_SIZE); |
159 | if (ret) { | 160 | if (ret) { |
160 | sms_err("Error %d reading initial block!\n", ret); | 161 | pr_err("Error %d reading initial block!\n", ret); |
161 | return; | 162 | return; |
162 | } | 163 | } |
163 | 164 | ||
@@ -198,7 +199,7 @@ static void smssdio_interrupt(struct sdio_func *func) | |||
198 | size); | 199 | size); |
199 | if (ret && ret != -EINVAL) { | 200 | if (ret && ret != -EINVAL) { |
200 | smscore_putbuffer(smsdev->coredev, cb); | 201 | smscore_putbuffer(smsdev->coredev, cb); |
201 | sms_err("Error %d reading data from card!\n", ret); | 202 | pr_err("Error %d reading data from card!\n", ret); |
202 | return; | 203 | return; |
203 | } | 204 | } |
204 | 205 | ||
@@ -216,8 +217,8 @@ static void smssdio_interrupt(struct sdio_func *func) | |||
216 | smsdev->func->cur_blksize); | 217 | smsdev->func->cur_blksize); |
217 | if (ret) { | 218 | if (ret) { |
218 | smscore_putbuffer(smsdev->coredev, cb); | 219 | smscore_putbuffer(smsdev->coredev, cb); |
219 | sms_err("Error %d reading " | 220 | pr_err("Error %d reading data from card!\n", |
220 | "data from card!\n", ret); | 221 | ret); |
221 | return; | 222 | return; |
222 | } | 223 | } |
223 | 224 | ||
@@ -278,7 +279,7 @@ static int smssdio_probe(struct sdio_func *func, | |||
278 | goto free; | 279 | goto free; |
279 | } | 280 | } |
280 | 281 | ||
281 | ret = smscore_register_device(¶ms, &smsdev->coredev); | 282 | ret = smscore_register_device(¶ms, &smsdev->coredev, NULL); |
282 | if (ret < 0) | 283 | if (ret < 0) |
283 | goto free; | 284 | goto free; |
284 | 285 | ||
diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index 4ec2a3c3f23c..bc12060e0882 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c | |||
@@ -2474,7 +2474,7 @@ static int bttv_querycap(struct file *file, void *priv, | |||
2474 | return -EINVAL; | 2474 | return -EINVAL; |
2475 | 2475 | ||
2476 | strlcpy(cap->driver, "bttv", sizeof(cap->driver)); | 2476 | strlcpy(cap->driver, "bttv", sizeof(cap->driver)); |
2477 | strlcpy(cap->card, btv->video_dev->name, sizeof(cap->card)); | 2477 | strlcpy(cap->card, btv->video_dev.name, sizeof(cap->card)); |
2478 | snprintf(cap->bus_info, sizeof(cap->bus_info), | 2478 | snprintf(cap->bus_info, sizeof(cap->bus_info), |
2479 | "PCI:%s", pci_name(btv->c.pci)); | 2479 | "PCI:%s", pci_name(btv->c.pci)); |
2480 | cap->capabilities = | 2480 | cap->capabilities = |
@@ -2484,9 +2484,9 @@ static int bttv_querycap(struct file *file, void *priv, | |||
2484 | V4L2_CAP_DEVICE_CAPS; | 2484 | V4L2_CAP_DEVICE_CAPS; |
2485 | if (no_overlay <= 0) | 2485 | if (no_overlay <= 0) |
2486 | cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY; | 2486 | cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY; |
2487 | if (btv->vbi_dev) | 2487 | if (video_is_registered(&btv->vbi_dev)) |
2488 | cap->capabilities |= V4L2_CAP_VBI_CAPTURE; | 2488 | cap->capabilities |= V4L2_CAP_VBI_CAPTURE; |
2489 | if (btv->radio_dev) | 2489 | if (video_is_registered(&btv->radio_dev)) |
2490 | cap->capabilities |= V4L2_CAP_RADIO; | 2490 | cap->capabilities |= V4L2_CAP_RADIO; |
2491 | 2491 | ||
2492 | /* | 2492 | /* |
@@ -3905,18 +3905,14 @@ static irqreturn_t bttv_irq(int irq, void *dev_id) | |||
3905 | /* ----------------------------------------------------------------------- */ | 3905 | /* ----------------------------------------------------------------------- */ |
3906 | /* initialization */ | 3906 | /* initialization */ |
3907 | 3907 | ||
3908 | static struct video_device *vdev_init(struct bttv *btv, | 3908 | static void vdev_init(struct bttv *btv, |
3909 | const struct video_device *template, | 3909 | struct video_device *vfd, |
3910 | const char *type_name) | 3910 | const struct video_device *template, |
3911 | const char *type_name) | ||
3911 | { | 3912 | { |
3912 | struct video_device *vfd; | ||
3913 | |||
3914 | vfd = video_device_alloc(); | ||
3915 | if (NULL == vfd) | ||
3916 | return NULL; | ||
3917 | *vfd = *template; | 3913 | *vfd = *template; |
3918 | vfd->v4l2_dev = &btv->c.v4l2_dev; | 3914 | vfd->v4l2_dev = &btv->c.v4l2_dev; |
3919 | vfd->release = video_device_release; | 3915 | vfd->release = video_device_release_empty; |
3920 | video_set_drvdata(vfd, btv); | 3916 | video_set_drvdata(vfd, btv); |
3921 | snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)", | 3917 | snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)", |
3922 | btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "", | 3918 | btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "", |
@@ -3927,32 +3923,13 @@ static struct video_device *vdev_init(struct bttv *btv, | |||
3927 | v4l2_disable_ioctl(vfd, VIDIOC_G_TUNER); | 3923 | v4l2_disable_ioctl(vfd, VIDIOC_G_TUNER); |
3928 | v4l2_disable_ioctl(vfd, VIDIOC_S_TUNER); | 3924 | v4l2_disable_ioctl(vfd, VIDIOC_S_TUNER); |
3929 | } | 3925 | } |
3930 | return vfd; | ||
3931 | } | 3926 | } |
3932 | 3927 | ||
3933 | static void bttv_unregister_video(struct bttv *btv) | 3928 | static void bttv_unregister_video(struct bttv *btv) |
3934 | { | 3929 | { |
3935 | if (btv->video_dev) { | 3930 | video_unregister_device(&btv->video_dev); |
3936 | if (video_is_registered(btv->video_dev)) | 3931 | video_unregister_device(&btv->vbi_dev); |
3937 | video_unregister_device(btv->video_dev); | 3932 | video_unregister_device(&btv->radio_dev); |
3938 | else | ||
3939 | video_device_release(btv->video_dev); | ||
3940 | btv->video_dev = NULL; | ||
3941 | } | ||
3942 | if (btv->vbi_dev) { | ||
3943 | if (video_is_registered(btv->vbi_dev)) | ||
3944 | video_unregister_device(btv->vbi_dev); | ||
3945 | else | ||
3946 | video_device_release(btv->vbi_dev); | ||
3947 | btv->vbi_dev = NULL; | ||
3948 | } | ||
3949 | if (btv->radio_dev) { | ||
3950 | if (video_is_registered(btv->radio_dev)) | ||
3951 | video_unregister_device(btv->radio_dev); | ||
3952 | else | ||
3953 | video_device_release(btv->radio_dev); | ||
3954 | btv->radio_dev = NULL; | ||
3955 | } | ||
3956 | } | 3933 | } |
3957 | 3934 | ||
3958 | /* register video4linux devices */ | 3935 | /* register video4linux devices */ |
@@ -3962,44 +3939,38 @@ static int bttv_register_video(struct bttv *btv) | |||
3962 | pr_notice("Overlay support disabled\n"); | 3939 | pr_notice("Overlay support disabled\n"); |
3963 | 3940 | ||
3964 | /* video */ | 3941 | /* video */ |
3965 | btv->video_dev = vdev_init(btv, &bttv_video_template, "video"); | 3942 | vdev_init(btv, &btv->video_dev, &bttv_video_template, "video"); |
3966 | 3943 | ||
3967 | if (NULL == btv->video_dev) | 3944 | if (video_register_device(&btv->video_dev, VFL_TYPE_GRABBER, |
3968 | goto err; | ||
3969 | if (video_register_device(btv->video_dev, VFL_TYPE_GRABBER, | ||
3970 | video_nr[btv->c.nr]) < 0) | 3945 | video_nr[btv->c.nr]) < 0) |
3971 | goto err; | 3946 | goto err; |
3972 | pr_info("%d: registered device %s\n", | 3947 | pr_info("%d: registered device %s\n", |
3973 | btv->c.nr, video_device_node_name(btv->video_dev)); | 3948 | btv->c.nr, video_device_node_name(&btv->video_dev)); |
3974 | if (device_create_file(&btv->video_dev->dev, | 3949 | if (device_create_file(&btv->video_dev.dev, |
3975 | &dev_attr_card)<0) { | 3950 | &dev_attr_card)<0) { |
3976 | pr_err("%d: device_create_file 'card' failed\n", btv->c.nr); | 3951 | pr_err("%d: device_create_file 'card' failed\n", btv->c.nr); |
3977 | goto err; | 3952 | goto err; |
3978 | } | 3953 | } |
3979 | 3954 | ||
3980 | /* vbi */ | 3955 | /* vbi */ |
3981 | btv->vbi_dev = vdev_init(btv, &bttv_video_template, "vbi"); | 3956 | vdev_init(btv, &btv->vbi_dev, &bttv_video_template, "vbi"); |
3982 | 3957 | ||
3983 | if (NULL == btv->vbi_dev) | 3958 | if (video_register_device(&btv->vbi_dev, VFL_TYPE_VBI, |
3984 | goto err; | ||
3985 | if (video_register_device(btv->vbi_dev, VFL_TYPE_VBI, | ||
3986 | vbi_nr[btv->c.nr]) < 0) | 3959 | vbi_nr[btv->c.nr]) < 0) |
3987 | goto err; | 3960 | goto err; |
3988 | pr_info("%d: registered device %s\n", | 3961 | pr_info("%d: registered device %s\n", |
3989 | btv->c.nr, video_device_node_name(btv->vbi_dev)); | 3962 | btv->c.nr, video_device_node_name(&btv->vbi_dev)); |
3990 | 3963 | ||
3991 | if (!btv->has_radio) | 3964 | if (!btv->has_radio) |
3992 | return 0; | 3965 | return 0; |
3993 | /* radio */ | 3966 | /* radio */ |
3994 | btv->radio_dev = vdev_init(btv, &radio_template, "radio"); | 3967 | vdev_init(btv, &btv->radio_dev, &radio_template, "radio"); |
3995 | if (NULL == btv->radio_dev) | 3968 | btv->radio_dev.ctrl_handler = &btv->radio_ctrl_handler; |
3996 | goto err; | 3969 | if (video_register_device(&btv->radio_dev, VFL_TYPE_RADIO, |
3997 | btv->radio_dev->ctrl_handler = &btv->radio_ctrl_handler; | ||
3998 | if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO, | ||
3999 | radio_nr[btv->c.nr]) < 0) | 3970 | radio_nr[btv->c.nr]) < 0) |
4000 | goto err; | 3971 | goto err; |
4001 | pr_info("%d: registered device %s\n", | 3972 | pr_info("%d: registered device %s\n", |
4002 | btv->c.nr, video_device_node_name(btv->radio_dev)); | 3973 | btv->c.nr, video_device_node_name(&btv->radio_dev)); |
4003 | 3974 | ||
4004 | /* all done */ | 3975 | /* all done */ |
4005 | return 0; | 3976 | return 0; |
diff --git a/drivers/media/pci/bt8xx/bttvp.h b/drivers/media/pci/bt8xx/bttvp.h index bc048c586b1f..a444cfb35c0b 100644 --- a/drivers/media/pci/bt8xx/bttvp.h +++ b/drivers/media/pci/bt8xx/bttvp.h | |||
@@ -404,9 +404,9 @@ struct bttv { | |||
404 | struct v4l2_subdev *sd_tda7432; | 404 | struct v4l2_subdev *sd_tda7432; |
405 | 405 | ||
406 | /* video4linux (1) */ | 406 | /* video4linux (1) */ |
407 | struct video_device *video_dev; | 407 | struct video_device video_dev; |
408 | struct video_device *radio_dev; | 408 | struct video_device radio_dev; |
409 | struct video_device *vbi_dev; | 409 | struct video_device vbi_dev; |
410 | 410 | ||
411 | /* controls */ | 411 | /* controls */ |
412 | struct v4l2_ctrl_handler ctrl_handler; | 412 | struct v4l2_ctrl_handler ctrl_handler; |
diff --git a/drivers/media/pci/cx18/cx18-alsa-main.c b/drivers/media/pci/cx18/cx18-alsa-main.c index ea272bcb38df..0b0e8015ad34 100644 --- a/drivers/media/pci/cx18/cx18-alsa-main.c +++ b/drivers/media/pci/cx18/cx18-alsa-main.c | |||
@@ -216,7 +216,7 @@ static int cx18_alsa_load(struct cx18 *cx) | |||
216 | } | 216 | } |
217 | 217 | ||
218 | s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM]; | 218 | s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM]; |
219 | if (s->video_dev == NULL) { | 219 | if (s->video_dev.v4l2_dev == NULL) { |
220 | CX18_DEBUG_ALSA_INFO("%s: PCM stream for card is disabled - " | 220 | CX18_DEBUG_ALSA_INFO("%s: PCM stream for card is disabled - " |
221 | "skipping\n", __func__); | 221 | "skipping\n", __func__); |
222 | return 0; | 222 | return 0; |
diff --git a/drivers/media/pci/cx18/cx18-driver.h b/drivers/media/pci/cx18/cx18-driver.h index 207d6e82403b..b15beed2dc14 100644 --- a/drivers/media/pci/cx18/cx18-driver.h +++ b/drivers/media/pci/cx18/cx18-driver.h | |||
@@ -373,7 +373,7 @@ struct cx18_in_work_order { | |||
373 | struct cx18_stream { | 373 | struct cx18_stream { |
374 | /* These first five fields are always set, even if the stream | 374 | /* These first five fields are always set, even if the stream |
375 | is not actually created. */ | 375 | is not actually created. */ |
376 | struct video_device *video_dev; /* NULL when stream not created */ | 376 | struct video_device video_dev; /* v4l2_dev is NULL when stream not created */ |
377 | struct cx18_dvb *dvb; /* DVB / Digital Transport */ | 377 | struct cx18_dvb *dvb; /* DVB / Digital Transport */ |
378 | struct cx18 *cx; /* for ease of use */ | 378 | struct cx18 *cx; /* for ease of use */ |
379 | const char *name; /* name of the stream */ | 379 | const char *name; /* name of the stream */ |
@@ -409,6 +409,7 @@ struct cx18_stream { | |||
409 | /* Videobuf for YUV video */ | 409 | /* Videobuf for YUV video */ |
410 | u32 pixelformat; | 410 | u32 pixelformat; |
411 | u32 vb_bytes_per_frame; | 411 | u32 vb_bytes_per_frame; |
412 | u32 vb_bytes_per_line; | ||
412 | struct list_head vb_capture; /* video capture queue */ | 413 | struct list_head vb_capture; /* video capture queue */ |
413 | spinlock_t vb_lock; | 414 | spinlock_t vb_lock; |
414 | struct timer_list vb_timeout; | 415 | struct timer_list vb_timeout; |
diff --git a/drivers/media/pci/cx18/cx18-fileops.c b/drivers/media/pci/cx18/cx18-fileops.c index 76a3b4ac541e..df837408efd5 100644 --- a/drivers/media/pci/cx18/cx18-fileops.c +++ b/drivers/media/pci/cx18/cx18-fileops.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include "cx18-controls.h" | 34 | #include "cx18-controls.h" |
35 | #include "cx18-ioctl.h" | 35 | #include "cx18-ioctl.h" |
36 | #include "cx18-cards.h" | 36 | #include "cx18-cards.h" |
37 | #include <media/v4l2-event.h> | ||
37 | 38 | ||
38 | /* This function tries to claim the stream for a specific file descriptor. | 39 | /* This function tries to claim the stream for a specific file descriptor. |
39 | If no one else is using this stream then the stream is claimed and | 40 | If no one else is using this stream then the stream is claimed and |
@@ -609,13 +610,16 @@ ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count, | |||
609 | 610 | ||
610 | unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait) | 611 | unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait) |
611 | { | 612 | { |
613 | unsigned long req_events = poll_requested_events(wait); | ||
612 | struct cx18_open_id *id = file2id(filp); | 614 | struct cx18_open_id *id = file2id(filp); |
613 | struct cx18 *cx = id->cx; | 615 | struct cx18 *cx = id->cx; |
614 | struct cx18_stream *s = &cx->streams[id->type]; | 616 | struct cx18_stream *s = &cx->streams[id->type]; |
615 | int eof = test_bit(CX18_F_S_STREAMOFF, &s->s_flags); | 617 | int eof = test_bit(CX18_F_S_STREAMOFF, &s->s_flags); |
618 | unsigned res = 0; | ||
616 | 619 | ||
617 | /* Start a capture if there is none */ | 620 | /* Start a capture if there is none */ |
618 | if (!eof && !test_bit(CX18_F_S_STREAMING, &s->s_flags)) { | 621 | if (!eof && !test_bit(CX18_F_S_STREAMING, &s->s_flags) && |
622 | (req_events & (POLLIN | POLLRDNORM))) { | ||
619 | int rc; | 623 | int rc; |
620 | 624 | ||
621 | mutex_lock(&cx->serialize_lock); | 625 | mutex_lock(&cx->serialize_lock); |
@@ -632,21 +636,26 @@ unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait) | |||
632 | if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) && | 636 | if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) && |
633 | (id->type == CX18_ENC_STREAM_TYPE_YUV)) { | 637 | (id->type == CX18_ENC_STREAM_TYPE_YUV)) { |
634 | int videobuf_poll = videobuf_poll_stream(filp, &s->vbuf_q, wait); | 638 | int videobuf_poll = videobuf_poll_stream(filp, &s->vbuf_q, wait); |
639 | |||
640 | if (v4l2_event_pending(&id->fh)) | ||
641 | res |= POLLPRI; | ||
635 | if (eof && videobuf_poll == POLLERR) | 642 | if (eof && videobuf_poll == POLLERR) |
636 | return POLLHUP; | 643 | return res | POLLHUP; |
637 | else | 644 | return res | videobuf_poll; |
638 | return videobuf_poll; | ||
639 | } | 645 | } |
640 | 646 | ||
641 | /* add stream's waitq to the poll list */ | 647 | /* add stream's waitq to the poll list */ |
642 | CX18_DEBUG_HI_FILE("Encoder poll\n"); | 648 | CX18_DEBUG_HI_FILE("Encoder poll\n"); |
643 | poll_wait(filp, &s->waitq, wait); | 649 | if (v4l2_event_pending(&id->fh)) |
650 | res |= POLLPRI; | ||
651 | else | ||
652 | poll_wait(filp, &s->waitq, wait); | ||
644 | 653 | ||
645 | if (atomic_read(&s->q_full.depth)) | 654 | if (atomic_read(&s->q_full.depth)) |
646 | return POLLIN | POLLRDNORM; | 655 | return res | POLLIN | POLLRDNORM; |
647 | if (eof) | 656 | if (eof) |
648 | return POLLHUP; | 657 | return res | POLLHUP; |
649 | return 0; | 658 | return res; |
650 | } | 659 | } |
651 | 660 | ||
652 | int cx18_v4l2_mmap(struct file *file, struct vm_area_struct *vma) | 661 | int cx18_v4l2_mmap(struct file *file, struct vm_area_struct *vma) |
@@ -797,7 +806,7 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp) | |||
797 | CX18_DEBUG_WARN("nomem on v4l2 open\n"); | 806 | CX18_DEBUG_WARN("nomem on v4l2 open\n"); |
798 | return -ENOMEM; | 807 | return -ENOMEM; |
799 | } | 808 | } |
800 | v4l2_fh_init(&item->fh, s->video_dev); | 809 | v4l2_fh_init(&item->fh, &s->video_dev); |
801 | 810 | ||
802 | item->cx = cx; | 811 | item->cx = cx; |
803 | item->type = s->type; | 812 | item->type = s->type; |
diff --git a/drivers/media/pci/cx18/cx18-ioctl.c b/drivers/media/pci/cx18/cx18-ioctl.c index b8e4b68a9196..79aee30d5fd8 100644 --- a/drivers/media/pci/cx18/cx18-ioctl.c +++ b/drivers/media/pci/cx18/cx18-ioctl.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include "cx18-cards.h" | 39 | #include "cx18-cards.h" |
40 | #include "cx18-av-core.h" | 40 | #include "cx18-av-core.h" |
41 | #include <media/tveeprom.h> | 41 | #include <media/tveeprom.h> |
42 | #include <media/v4l2-event.h> | ||
42 | 43 | ||
43 | u16 cx18_service2vbi(int type) | 44 | u16 cx18_service2vbi(int type) |
44 | { | 45 | { |
@@ -159,7 +160,7 @@ static int cx18_g_fmt_vid_cap(struct file *file, void *fh, | |||
159 | if (id->type == CX18_ENC_STREAM_TYPE_YUV) { | 160 | if (id->type == CX18_ENC_STREAM_TYPE_YUV) { |
160 | pixfmt->pixelformat = s->pixelformat; | 161 | pixfmt->pixelformat = s->pixelformat; |
161 | pixfmt->sizeimage = s->vb_bytes_per_frame; | 162 | pixfmt->sizeimage = s->vb_bytes_per_frame; |
162 | pixfmt->bytesperline = 720; | 163 | pixfmt->bytesperline = s->vb_bytes_per_line; |
163 | } else { | 164 | } else { |
164 | pixfmt->pixelformat = V4L2_PIX_FMT_MPEG; | 165 | pixfmt->pixelformat = V4L2_PIX_FMT_MPEG; |
165 | pixfmt->sizeimage = 128 * 1024; | 166 | pixfmt->sizeimage = 128 * 1024; |
@@ -287,10 +288,13 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh, | |||
287 | s->pixelformat = fmt->fmt.pix.pixelformat; | 288 | s->pixelformat = fmt->fmt.pix.pixelformat; |
288 | /* HM12 YUV size is (Y=(h*720) + UV=(h*(720/2))) | 289 | /* HM12 YUV size is (Y=(h*720) + UV=(h*(720/2))) |
289 | UYUV YUV size is (Y=(h*720) + UV=(h*(720))) */ | 290 | UYUV YUV size is (Y=(h*720) + UV=(h*(720))) */ |
290 | if (s->pixelformat == V4L2_PIX_FMT_HM12) | 291 | if (s->pixelformat == V4L2_PIX_FMT_HM12) { |
291 | s->vb_bytes_per_frame = h * 720 * 3 / 2; | 292 | s->vb_bytes_per_frame = h * 720 * 3 / 2; |
292 | else | 293 | s->vb_bytes_per_line = 720; /* First plane */ |
294 | } else { | ||
293 | s->vb_bytes_per_frame = h * 720 * 2; | 295 | s->vb_bytes_per_frame = h * 720 * 2; |
296 | s->vb_bytes_per_line = 1440; /* Packed */ | ||
297 | } | ||
294 | 298 | ||
295 | mbus_fmt.width = cx->cxhdl.width = w; | 299 | mbus_fmt.width = cx->cxhdl.width = w; |
296 | mbus_fmt.height = cx->cxhdl.height = h; | 300 | mbus_fmt.height = cx->cxhdl.height = h; |
@@ -447,34 +451,29 @@ static int cx18_cropcap(struct file *file, void *fh, | |||
447 | 451 | ||
448 | if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 452 | if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
449 | return -EINVAL; | 453 | return -EINVAL; |
450 | cropcap->bounds.top = cropcap->bounds.left = 0; | ||
451 | cropcap->bounds.width = 720; | ||
452 | cropcap->bounds.height = cx->is_50hz ? 576 : 480; | ||
453 | cropcap->pixelaspect.numerator = cx->is_50hz ? 59 : 10; | 454 | cropcap->pixelaspect.numerator = cx->is_50hz ? 59 : 10; |
454 | cropcap->pixelaspect.denominator = cx->is_50hz ? 54 : 11; | 455 | cropcap->pixelaspect.denominator = cx->is_50hz ? 54 : 11; |
455 | cropcap->defrect = cropcap->bounds; | ||
456 | return 0; | 456 | return 0; |
457 | } | 457 | } |
458 | 458 | ||
459 | static int cx18_s_crop(struct file *file, void *fh, const struct v4l2_crop *crop) | 459 | static int cx18_g_selection(struct file *file, void *fh, |
460 | { | 460 | struct v4l2_selection *sel) |
461 | struct cx18_open_id *id = fh2id(fh); | ||
462 | struct cx18 *cx = id->cx; | ||
463 | |||
464 | if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
465 | return -EINVAL; | ||
466 | CX18_DEBUG_WARN("VIDIOC_S_CROP not implemented\n"); | ||
467 | return -EINVAL; | ||
468 | } | ||
469 | |||
470 | static int cx18_g_crop(struct file *file, void *fh, struct v4l2_crop *crop) | ||
471 | { | 461 | { |
472 | struct cx18 *cx = fh2id(fh)->cx; | 462 | struct cx18 *cx = fh2id(fh)->cx; |
473 | 463 | ||
474 | if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 464 | if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
475 | return -EINVAL; | 465 | return -EINVAL; |
476 | CX18_DEBUG_WARN("VIDIOC_G_CROP not implemented\n"); | 466 | switch (sel->target) { |
477 | return -EINVAL; | 467 | case V4L2_SEL_TGT_CROP_BOUNDS: |
468 | case V4L2_SEL_TGT_CROP_DEFAULT: | ||
469 | sel->r.top = sel->r.left = 0; | ||
470 | sel->r.width = 720; | ||
471 | sel->r.height = cx->is_50hz ? 576 : 480; | ||
472 | break; | ||
473 | default: | ||
474 | return -EINVAL; | ||
475 | } | ||
476 | return 0; | ||
478 | } | 477 | } |
479 | 478 | ||
480 | static int cx18_enum_fmt_vid_cap(struct file *file, void *fh, | 479 | static int cx18_enum_fmt_vid_cap(struct file *file, void *fh, |
@@ -510,6 +509,9 @@ int cx18_s_input(struct file *file, void *fh, unsigned int inp) | |||
510 | { | 509 | { |
511 | struct cx18_open_id *id = fh2id(fh); | 510 | struct cx18_open_id *id = fh2id(fh); |
512 | struct cx18 *cx = id->cx; | 511 | struct cx18 *cx = id->cx; |
512 | v4l2_std_id std = V4L2_STD_ALL; | ||
513 | const struct cx18_card_video_input *card_input = | ||
514 | cx->card->video_inputs + inp; | ||
513 | 515 | ||
514 | if (inp >= cx->nof_inputs) | 516 | if (inp >= cx->nof_inputs) |
515 | return -EINVAL; | 517 | return -EINVAL; |
@@ -525,6 +527,11 @@ int cx18_s_input(struct file *file, void *fh, unsigned int inp) | |||
525 | cx->active_input = inp; | 527 | cx->active_input = inp; |
526 | /* Set the audio input to whatever is appropriate for the input type. */ | 528 | /* Set the audio input to whatever is appropriate for the input type. */ |
527 | cx->audio_input = cx->card->video_inputs[inp].audio_index; | 529 | cx->audio_input = cx->card->video_inputs[inp].audio_index; |
530 | if (card_input->video_type == V4L2_INPUT_TYPE_TUNER) | ||
531 | std = cx->tuner_std; | ||
532 | cx->streams[CX18_ENC_STREAM_TYPE_MPG].video_dev.tvnorms = std; | ||
533 | cx->streams[CX18_ENC_STREAM_TYPE_YUV].video_dev.tvnorms = std; | ||
534 | cx->streams[CX18_ENC_STREAM_TYPE_VBI].video_dev.tvnorms = std; | ||
528 | 535 | ||
529 | /* prevent others from messing with the streams until | 536 | /* prevent others from messing with the streams until |
530 | we're finished changing inputs. */ | 537 | we're finished changing inputs. */ |
@@ -1036,7 +1043,7 @@ static int cx18_log_status(struct file *file, void *fh) | |||
1036 | for (i = 0; i < CX18_MAX_STREAMS; i++) { | 1043 | for (i = 0; i < CX18_MAX_STREAMS; i++) { |
1037 | struct cx18_stream *s = &cx->streams[i]; | 1044 | struct cx18_stream *s = &cx->streams[i]; |
1038 | 1045 | ||
1039 | if (s->video_dev == NULL || s->buffers == 0) | 1046 | if (s->video_dev.v4l2_dev == NULL || s->buffers == 0) |
1040 | continue; | 1047 | continue; |
1041 | CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", | 1048 | CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", |
1042 | s->name, s->s_flags, | 1049 | s->name, s->s_flags, |
@@ -1078,8 +1085,7 @@ static const struct v4l2_ioctl_ops cx18_ioctl_ops = { | |||
1078 | .vidioc_enumaudio = cx18_enumaudio, | 1085 | .vidioc_enumaudio = cx18_enumaudio, |
1079 | .vidioc_enum_input = cx18_enum_input, | 1086 | .vidioc_enum_input = cx18_enum_input, |
1080 | .vidioc_cropcap = cx18_cropcap, | 1087 | .vidioc_cropcap = cx18_cropcap, |
1081 | .vidioc_s_crop = cx18_s_crop, | 1088 | .vidioc_g_selection = cx18_g_selection, |
1082 | .vidioc_g_crop = cx18_g_crop, | ||
1083 | .vidioc_g_input = cx18_g_input, | 1089 | .vidioc_g_input = cx18_g_input, |
1084 | .vidioc_s_input = cx18_s_input, | 1090 | .vidioc_s_input = cx18_s_input, |
1085 | .vidioc_g_frequency = cx18_g_frequency, | 1091 | .vidioc_g_frequency = cx18_g_frequency, |
@@ -1114,6 +1120,8 @@ static const struct v4l2_ioctl_ops cx18_ioctl_ops = { | |||
1114 | .vidioc_querybuf = cx18_querybuf, | 1120 | .vidioc_querybuf = cx18_querybuf, |
1115 | .vidioc_qbuf = cx18_qbuf, | 1121 | .vidioc_qbuf = cx18_qbuf, |
1116 | .vidioc_dqbuf = cx18_dqbuf, | 1122 | .vidioc_dqbuf = cx18_dqbuf, |
1123 | .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, | ||
1124 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, | ||
1117 | }; | 1125 | }; |
1118 | 1126 | ||
1119 | void cx18_set_funcs(struct video_device *vdev) | 1127 | void cx18_set_funcs(struct video_device *vdev) |
diff --git a/drivers/media/pci/cx18/cx18-streams.c b/drivers/media/pci/cx18/cx18-streams.c index 369445fcf3e5..c82d25d53341 100644 --- a/drivers/media/pci/cx18/cx18-streams.c +++ b/drivers/media/pci/cx18/cx18-streams.c | |||
@@ -254,11 +254,8 @@ static struct videobuf_queue_ops cx18_videobuf_qops = { | |||
254 | static void cx18_stream_init(struct cx18 *cx, int type) | 254 | static void cx18_stream_init(struct cx18 *cx, int type) |
255 | { | 255 | { |
256 | struct cx18_stream *s = &cx->streams[type]; | 256 | struct cx18_stream *s = &cx->streams[type]; |
257 | struct video_device *video_dev = s->video_dev; | ||
258 | 257 | ||
259 | /* we need to keep video_dev, so restore it afterwards */ | ||
260 | memset(s, 0, sizeof(*s)); | 258 | memset(s, 0, sizeof(*s)); |
261 | s->video_dev = video_dev; | ||
262 | 259 | ||
263 | /* initialize cx18_stream fields */ | 260 | /* initialize cx18_stream fields */ |
264 | s->dvb = NULL; | 261 | s->dvb = NULL; |
@@ -307,6 +304,7 @@ static void cx18_stream_init(struct cx18 *cx, int type) | |||
307 | /* Assume the previous pixel default */ | 304 | /* Assume the previous pixel default */ |
308 | s->pixelformat = V4L2_PIX_FMT_HM12; | 305 | s->pixelformat = V4L2_PIX_FMT_HM12; |
309 | s->vb_bytes_per_frame = cx->cxhdl.height * 720 * 3 / 2; | 306 | s->vb_bytes_per_frame = cx->cxhdl.height * 720 * 3 / 2; |
307 | s->vb_bytes_per_line = 720; | ||
310 | } | 308 | } |
311 | } | 309 | } |
312 | 310 | ||
@@ -319,12 +317,12 @@ static int cx18_prep_dev(struct cx18 *cx, int type) | |||
319 | 317 | ||
320 | /* | 318 | /* |
321 | * These five fields are always initialized. | 319 | * These five fields are always initialized. |
322 | * For analog capture related streams, if video_dev == NULL then the | 320 | * For analog capture related streams, if video_dev.v4l2_dev == NULL then the |
323 | * stream is not in use. | 321 | * stream is not in use. |
324 | * For the TS stream, if dvb == NULL then the stream is not in use. | 322 | * For the TS stream, if dvb == NULL then the stream is not in use. |
325 | * In those cases no other fields but these four can be used. | 323 | * In those cases no other fields but these four can be used. |
326 | */ | 324 | */ |
327 | s->video_dev = NULL; | 325 | s->video_dev.v4l2_dev = NULL; |
328 | s->dvb = NULL; | 326 | s->dvb = NULL; |
329 | s->cx = cx; | 327 | s->cx = cx; |
330 | s->type = type; | 328 | s->type = type; |
@@ -367,24 +365,20 @@ static int cx18_prep_dev(struct cx18 *cx, int type) | |||
367 | if (num_offset == -1) | 365 | if (num_offset == -1) |
368 | return 0; | 366 | return 0; |
369 | 367 | ||
370 | /* allocate and initialize the v4l2 video device structure */ | 368 | /* initialize the v4l2 video device structure */ |
371 | s->video_dev = video_device_alloc(); | 369 | snprintf(s->video_dev.name, sizeof(s->video_dev.name), "%s %s", |
372 | if (s->video_dev == NULL) { | ||
373 | CX18_ERR("Couldn't allocate v4l2 video_device for %s\n", | ||
374 | s->name); | ||
375 | return -ENOMEM; | ||
376 | } | ||
377 | |||
378 | snprintf(s->video_dev->name, sizeof(s->video_dev->name), "%s %s", | ||
379 | cx->v4l2_dev.name, s->name); | 370 | cx->v4l2_dev.name, s->name); |
380 | 371 | ||
381 | s->video_dev->num = num; | 372 | s->video_dev.num = num; |
382 | s->video_dev->v4l2_dev = &cx->v4l2_dev; | 373 | s->video_dev.v4l2_dev = &cx->v4l2_dev; |
383 | s->video_dev->fops = &cx18_v4l2_enc_fops; | 374 | s->video_dev.fops = &cx18_v4l2_enc_fops; |
384 | s->video_dev->release = video_device_release; | 375 | s->video_dev.release = video_device_release_empty; |
385 | s->video_dev->tvnorms = V4L2_STD_ALL; | 376 | if (cx->card->video_inputs->video_type == CX18_CARD_INPUT_VID_TUNER) |
386 | s->video_dev->lock = &cx->serialize_lock; | 377 | s->video_dev.tvnorms = cx->tuner_std; |
387 | cx18_set_funcs(s->video_dev); | 378 | else |
379 | s->video_dev.tvnorms = V4L2_STD_ALL; | ||
380 | s->video_dev.lock = &cx->serialize_lock; | ||
381 | cx18_set_funcs(&s->video_dev); | ||
388 | return 0; | 382 | return 0; |
389 | } | 383 | } |
390 | 384 | ||
@@ -428,31 +422,30 @@ static int cx18_reg_dev(struct cx18 *cx, int type) | |||
428 | } | 422 | } |
429 | } | 423 | } |
430 | 424 | ||
431 | if (s->video_dev == NULL) | 425 | if (s->video_dev.v4l2_dev == NULL) |
432 | return 0; | 426 | return 0; |
433 | 427 | ||
434 | num = s->video_dev->num; | 428 | num = s->video_dev.num; |
435 | /* card number + user defined offset + device offset */ | 429 | /* card number + user defined offset + device offset */ |
436 | if (type != CX18_ENC_STREAM_TYPE_MPG) { | 430 | if (type != CX18_ENC_STREAM_TYPE_MPG) { |
437 | struct cx18_stream *s_mpg = &cx->streams[CX18_ENC_STREAM_TYPE_MPG]; | 431 | struct cx18_stream *s_mpg = &cx->streams[CX18_ENC_STREAM_TYPE_MPG]; |
438 | 432 | ||
439 | if (s_mpg->video_dev) | 433 | if (s_mpg->video_dev.v4l2_dev) |
440 | num = s_mpg->video_dev->num | 434 | num = s_mpg->video_dev.num |
441 | + cx18_stream_info[type].num_offset; | 435 | + cx18_stream_info[type].num_offset; |
442 | } | 436 | } |
443 | video_set_drvdata(s->video_dev, s); | 437 | video_set_drvdata(&s->video_dev, s); |
444 | 438 | ||
445 | /* Register device. First try the desired minor, then any free one. */ | 439 | /* Register device. First try the desired minor, then any free one. */ |
446 | ret = video_register_device_no_warn(s->video_dev, vfl_type, num); | 440 | ret = video_register_device_no_warn(&s->video_dev, vfl_type, num); |
447 | if (ret < 0) { | 441 | if (ret < 0) { |
448 | CX18_ERR("Couldn't register v4l2 device for %s (device node number %d)\n", | 442 | CX18_ERR("Couldn't register v4l2 device for %s (device node number %d)\n", |
449 | s->name, num); | 443 | s->name, num); |
450 | video_device_release(s->video_dev); | 444 | s->video_dev.v4l2_dev = NULL; |
451 | s->video_dev = NULL; | ||
452 | return ret; | 445 | return ret; |
453 | } | 446 | } |
454 | 447 | ||
455 | name = video_device_node_name(s->video_dev); | 448 | name = video_device_node_name(&s->video_dev); |
456 | 449 | ||
457 | switch (vfl_type) { | 450 | switch (vfl_type) { |
458 | case VFL_TYPE_GRABBER: | 451 | case VFL_TYPE_GRABBER: |
@@ -542,10 +535,9 @@ void cx18_streams_cleanup(struct cx18 *cx, int unregister) | |||
542 | } | 535 | } |
543 | 536 | ||
544 | /* If struct video_device exists, can have buffers allocated */ | 537 | /* If struct video_device exists, can have buffers allocated */ |
545 | vdev = cx->streams[type].video_dev; | 538 | vdev = &cx->streams[type].video_dev; |
546 | 539 | ||
547 | cx->streams[type].video_dev = NULL; | 540 | if (vdev->v4l2_dev == NULL) |
548 | if (vdev == NULL) | ||
549 | continue; | 541 | continue; |
550 | 542 | ||
551 | if (type == CX18_ENC_STREAM_TYPE_YUV) | 543 | if (type == CX18_ENC_STREAM_TYPE_YUV) |
@@ -553,11 +545,7 @@ void cx18_streams_cleanup(struct cx18 *cx, int unregister) | |||
553 | 545 | ||
554 | cx18_stream_free(&cx->streams[type]); | 546 | cx18_stream_free(&cx->streams[type]); |
555 | 547 | ||
556 | /* Unregister or release device */ | 548 | video_unregister_device(vdev); |
557 | if (unregister) | ||
558 | video_unregister_device(vdev); | ||
559 | else | ||
560 | video_device_release(vdev); | ||
561 | } | 549 | } |
562 | } | 550 | } |
563 | 551 | ||
@@ -1042,7 +1030,7 @@ u32 cx18_find_handle(struct cx18 *cx) | |||
1042 | for (i = 0; i < CX18_MAX_STREAMS; i++) { | 1030 | for (i = 0; i < CX18_MAX_STREAMS; i++) { |
1043 | struct cx18_stream *s = &cx->streams[i]; | 1031 | struct cx18_stream *s = &cx->streams[i]; |
1044 | 1032 | ||
1045 | if (s->video_dev && (s->handle != CX18_INVALID_TASK_HANDLE)) | 1033 | if (s->video_dev.v4l2_dev && (s->handle != CX18_INVALID_TASK_HANDLE)) |
1046 | return s->handle; | 1034 | return s->handle; |
1047 | } | 1035 | } |
1048 | return CX18_INVALID_TASK_HANDLE; | 1036 | return CX18_INVALID_TASK_HANDLE; |
diff --git a/drivers/media/pci/cx18/cx18-streams.h b/drivers/media/pci/cx18/cx18-streams.h index 713b0e61536d..27f8af9b11cd 100644 --- a/drivers/media/pci/cx18/cx18-streams.h +++ b/drivers/media/pci/cx18/cx18-streams.h | |||
@@ -33,7 +33,7 @@ void cx18_stream_rotate_idx_mdls(struct cx18 *cx); | |||
33 | 33 | ||
34 | static inline bool cx18_stream_enabled(struct cx18_stream *s) | 34 | static inline bool cx18_stream_enabled(struct cx18_stream *s) |
35 | { | 35 | { |
36 | return s->video_dev || | 36 | return s->video_dev.v4l2_dev || |
37 | (s->dvb && s->dvb->enabled) || | 37 | (s->dvb && s->dvb->enabled) || |
38 | (s->type == CX18_ENC_STREAM_TYPE_IDX && | 38 | (s->type == CX18_ENC_STREAM_TYPE_IDX && |
39 | s->cx->stream_buffers[CX18_ENC_STREAM_TYPE_IDX] != 0); | 39 | s->cx->stream_buffers[CX18_ENC_STREAM_TYPE_IDX] != 0); |
diff --git a/drivers/media/pci/cx23885/Kconfig b/drivers/media/pci/cx23885/Kconfig index 74d774e5227b..2e1b88ccdbf2 100644 --- a/drivers/media/pci/cx23885/Kconfig +++ b/drivers/media/pci/cx23885/Kconfig | |||
@@ -40,7 +40,6 @@ config VIDEO_CX23885 | |||
40 | select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT | 40 | select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT |
41 | select MEDIA_TUNER_XC5000 if MEDIA_SUBDRV_AUTOSELECT | 41 | select MEDIA_TUNER_XC5000 if MEDIA_SUBDRV_AUTOSELECT |
42 | select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT | 42 | select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT |
43 | select MEDIA_TUNER_M88TS2022 if MEDIA_SUBDRV_AUTOSELECT | ||
44 | select MEDIA_TUNER_M88RS6000T if MEDIA_SUBDRV_AUTOSELECT | 43 | select MEDIA_TUNER_M88RS6000T if MEDIA_SUBDRV_AUTOSELECT |
45 | select DVB_TUNER_DIB0070 if MEDIA_SUBDRV_AUTOSELECT | 44 | select DVB_TUNER_DIB0070 if MEDIA_SUBDRV_AUTOSELECT |
46 | ---help--- | 45 | ---help--- |
diff --git a/drivers/media/pci/cx23885/altera-ci.c b/drivers/media/pci/cx23885/altera-ci.c index 2bbbf545b042..0a91df2c9f08 100644 --- a/drivers/media/pci/cx23885/altera-ci.c +++ b/drivers/media/pci/cx23885/altera-ci.c | |||
@@ -483,7 +483,6 @@ static void altera_hw_filt_release(void *main_dev, int filt_nr) | |||
483 | } | 483 | } |
484 | 484 | ||
485 | } | 485 | } |
486 | EXPORT_SYMBOL(altera_hw_filt_release); | ||
487 | 486 | ||
488 | void altera_ci_release(void *dev, int ci_nr) | 487 | void altera_ci_release(void *dev, int ci_nr) |
489 | { | 488 | { |
@@ -598,7 +597,6 @@ static int altera_pid_feed_control(void *demux_dev, int filt_nr, | |||
598 | 597 | ||
599 | return 0; | 598 | return 0; |
600 | } | 599 | } |
601 | EXPORT_SYMBOL(altera_pid_feed_control); | ||
602 | 600 | ||
603 | static int altera_ci_start_feed(struct dvb_demux_feed *feed, int num) | 601 | static int altera_ci_start_feed(struct dvb_demux_feed *feed, int num) |
604 | { | 602 | { |
@@ -699,7 +697,6 @@ err: | |||
699 | 697 | ||
700 | return ret; | 698 | return ret; |
701 | } | 699 | } |
702 | EXPORT_SYMBOL(altera_hw_filt_init); | ||
703 | 700 | ||
704 | int altera_ci_init(struct altera_ci_config *config, int ci_nr) | 701 | int altera_ci_init(struct altera_ci_config *config, int ci_nr) |
705 | { | 702 | { |
diff --git a/drivers/media/pci/cx23885/altera-ci.h b/drivers/media/pci/cx23885/altera-ci.h index 5028f0cf83f4..6c511723fd1b 100644 --- a/drivers/media/pci/cx23885/altera-ci.h +++ b/drivers/media/pci/cx23885/altera-ci.h | |||
@@ -39,7 +39,7 @@ struct altera_ci_config { | |||
39 | int (*fpga_rw) (void *dev, int ad_rg, int val, int rw); | 39 | int (*fpga_rw) (void *dev, int ad_rg, int val, int rw); |
40 | }; | 40 | }; |
41 | 41 | ||
42 | #if IS_ENABLED(CONFIG_MEDIA_ALTERA_CI) | 42 | #if IS_REACHABLE(CONFIG_MEDIA_ALTERA_CI) |
43 | 43 | ||
44 | extern int altera_ci_init(struct altera_ci_config *config, int ci_nr); | 44 | extern int altera_ci_init(struct altera_ci_config *config, int ci_nr); |
45 | extern void altera_ci_release(void *dev, int ci_nr); | 45 | extern void altera_ci_release(void *dev, int ci_nr); |
diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c index 1ad49946d7fa..7aee76af7a85 100644 --- a/drivers/media/pci/cx23885/cx23885-core.c +++ b/drivers/media/pci/cx23885/cx23885-core.c | |||
@@ -825,6 +825,7 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) | |||
825 | int i; | 825 | int i; |
826 | 826 | ||
827 | spin_lock_init(&dev->pci_irqmask_lock); | 827 | spin_lock_init(&dev->pci_irqmask_lock); |
828 | spin_lock_init(&dev->slock); | ||
828 | 829 | ||
829 | mutex_init(&dev->lock); | 830 | mutex_init(&dev->lock); |
830 | mutex_init(&dev->gpio_lock); | 831 | mutex_init(&dev->gpio_lock); |
diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index 45fbe1e4d2d0..745caabe3397 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c | |||
@@ -73,7 +73,6 @@ | |||
73 | #include "si2157.h" | 73 | #include "si2157.h" |
74 | #include "sp2.h" | 74 | #include "sp2.h" |
75 | #include "m88ds3103.h" | 75 | #include "m88ds3103.h" |
76 | #include "m88ts2022.h" | ||
77 | #include "m88rs6000t.h" | 76 | #include "m88rs6000t.h" |
78 | 77 | ||
79 | static unsigned int debug; | 78 | static unsigned int debug; |
@@ -1187,7 +1186,7 @@ static int dvb_register(struct cx23885_tsport *port) | |||
1187 | struct vb2_dvb_frontend *fe0, *fe1 = NULL; | 1186 | struct vb2_dvb_frontend *fe0, *fe1 = NULL; |
1188 | struct si2168_config si2168_config; | 1187 | struct si2168_config si2168_config; |
1189 | struct si2157_config si2157_config; | 1188 | struct si2157_config si2157_config; |
1190 | struct m88ts2022_config m88ts2022_config; | 1189 | struct ts2020_config ts2020_config; |
1191 | struct i2c_board_info info; | 1190 | struct i2c_board_info info; |
1192 | struct i2c_adapter *adapter; | 1191 | struct i2c_adapter *adapter; |
1193 | struct i2c_client *client_demod = NULL, *client_tuner = NULL; | 1192 | struct i2c_client *client_demod = NULL, *client_tuner = NULL; |
@@ -1856,13 +1855,12 @@ static int dvb_register(struct cx23885_tsport *port) | |||
1856 | break; | 1855 | break; |
1857 | 1856 | ||
1858 | /* attach tuner */ | 1857 | /* attach tuner */ |
1859 | memset(&m88ts2022_config, 0, sizeof(m88ts2022_config)); | 1858 | memset(&ts2020_config, 0, sizeof(ts2020_config)); |
1860 | m88ts2022_config.fe = fe0->dvb.frontend; | 1859 | ts2020_config.fe = fe0->dvb.frontend; |
1861 | m88ts2022_config.clock = 27000000; | ||
1862 | memset(&info, 0, sizeof(struct i2c_board_info)); | 1860 | memset(&info, 0, sizeof(struct i2c_board_info)); |
1863 | strlcpy(info.type, "m88ts2022", I2C_NAME_SIZE); | 1861 | strlcpy(info.type, "ts2020", I2C_NAME_SIZE); |
1864 | info.addr = 0x60; | 1862 | info.addr = 0x60; |
1865 | info.platform_data = &m88ts2022_config; | 1863 | info.platform_data = &ts2020_config; |
1866 | request_module(info.type); | 1864 | request_module(info.type); |
1867 | client_tuner = i2c_new_device(adapter, &info); | 1865 | client_tuner = i2c_new_device(adapter, &info); |
1868 | if (client_tuner == NULL || | 1866 | if (client_tuner == NULL || |
@@ -1986,13 +1984,12 @@ static int dvb_register(struct cx23885_tsport *port) | |||
1986 | break; | 1984 | break; |
1987 | 1985 | ||
1988 | /* attach tuner */ | 1986 | /* attach tuner */ |
1989 | memset(&m88ts2022_config, 0, sizeof(m88ts2022_config)); | 1987 | memset(&ts2020_config, 0, sizeof(ts2020_config)); |
1990 | m88ts2022_config.fe = fe0->dvb.frontend; | 1988 | ts2020_config.fe = fe0->dvb.frontend; |
1991 | m88ts2022_config.clock = 27000000; | ||
1992 | memset(&info, 0, sizeof(struct i2c_board_info)); | 1989 | memset(&info, 0, sizeof(struct i2c_board_info)); |
1993 | strlcpy(info.type, "m88ts2022", I2C_NAME_SIZE); | 1990 | strlcpy(info.type, "ts2020", I2C_NAME_SIZE); |
1994 | info.addr = 0x60; | 1991 | info.addr = 0x60; |
1995 | info.platform_data = &m88ts2022_config; | 1992 | info.platform_data = &ts2020_config; |
1996 | request_module(info.type); | 1993 | request_module(info.type); |
1997 | client_tuner = i2c_new_device(adapter, &info); | 1994 | client_tuner = i2c_new_device(adapter, &info); |
1998 | if (client_tuner == NULL || client_tuner->dev.driver == NULL) | 1995 | if (client_tuner == NULL || client_tuner->dev.driver == NULL) |
@@ -2032,13 +2029,12 @@ static int dvb_register(struct cx23885_tsport *port) | |||
2032 | break; | 2029 | break; |
2033 | 2030 | ||
2034 | /* attach tuner */ | 2031 | /* attach tuner */ |
2035 | memset(&m88ts2022_config, 0, sizeof(m88ts2022_config)); | 2032 | memset(&ts2020_config, 0, sizeof(ts2020_config)); |
2036 | m88ts2022_config.fe = fe0->dvb.frontend; | 2033 | ts2020_config.fe = fe0->dvb.frontend; |
2037 | m88ts2022_config.clock = 27000000; | ||
2038 | memset(&info, 0, sizeof(struct i2c_board_info)); | 2034 | memset(&info, 0, sizeof(struct i2c_board_info)); |
2039 | strlcpy(info.type, "m88ts2022", I2C_NAME_SIZE); | 2035 | strlcpy(info.type, "ts2020", I2C_NAME_SIZE); |
2040 | info.addr = 0x60; | 2036 | info.addr = 0x60; |
2041 | info.platform_data = &m88ts2022_config; | 2037 | info.platform_data = &ts2020_config; |
2042 | request_module(info.type); | 2038 | request_module(info.type); |
2043 | client_tuner = i2c_new_device(adapter, &info); | 2039 | client_tuner = i2c_new_device(adapter, &info); |
2044 | if (client_tuner == NULL || client_tuner->dev.driver == NULL) | 2040 | if (client_tuner == NULL || client_tuner->dev.driver == NULL) |
diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c index 5e93c682a3f5..2232b389c441 100644 --- a/drivers/media/pci/cx23885/cx23885-video.c +++ b/drivers/media/pci/cx23885/cx23885-video.c | |||
@@ -1137,7 +1137,6 @@ int cx23885_video_register(struct cx23885_dev *dev) | |||
1137 | int err; | 1137 | int err; |
1138 | 1138 | ||
1139 | dprintk(1, "%s()\n", __func__); | 1139 | dprintk(1, "%s()\n", __func__); |
1140 | spin_lock_init(&dev->slock); | ||
1141 | 1140 | ||
1142 | /* Initialize VBI template */ | 1141 | /* Initialize VBI template */ |
1143 | cx23885_vbi_template = cx23885_video_template; | 1142 | cx23885_vbi_template = cx23885_video_template; |
diff --git a/drivers/media/pci/cx88/cx88-blackbird.c b/drivers/media/pci/cx88/cx88-blackbird.c index b6be46e94289..24216efa56e7 100644 --- a/drivers/media/pci/cx88/cx88-blackbird.c +++ b/drivers/media/pci/cx88/cx88-blackbird.c | |||
@@ -1102,32 +1102,26 @@ static int cx8802_blackbird_advise_release(struct cx8802_driver *drv) | |||
1102 | 1102 | ||
1103 | static void blackbird_unregister_video(struct cx8802_dev *dev) | 1103 | static void blackbird_unregister_video(struct cx8802_dev *dev) |
1104 | { | 1104 | { |
1105 | if (dev->mpeg_dev) { | 1105 | video_unregister_device(&dev->mpeg_dev); |
1106 | if (video_is_registered(dev->mpeg_dev)) | ||
1107 | video_unregister_device(dev->mpeg_dev); | ||
1108 | else | ||
1109 | video_device_release(dev->mpeg_dev); | ||
1110 | dev->mpeg_dev = NULL; | ||
1111 | } | ||
1112 | } | 1106 | } |
1113 | 1107 | ||
1114 | static int blackbird_register_video(struct cx8802_dev *dev) | 1108 | static int blackbird_register_video(struct cx8802_dev *dev) |
1115 | { | 1109 | { |
1116 | int err; | 1110 | int err; |
1117 | 1111 | ||
1118 | dev->mpeg_dev = cx88_vdev_init(dev->core, dev->pci, | 1112 | cx88_vdev_init(dev->core, dev->pci, &dev->mpeg_dev, |
1119 | &cx8802_mpeg_template, "mpeg"); | 1113 | &cx8802_mpeg_template, "mpeg"); |
1120 | dev->mpeg_dev->ctrl_handler = &dev->cxhdl.hdl; | 1114 | dev->mpeg_dev.ctrl_handler = &dev->cxhdl.hdl; |
1121 | video_set_drvdata(dev->mpeg_dev, dev); | 1115 | video_set_drvdata(&dev->mpeg_dev, dev); |
1122 | dev->mpeg_dev->queue = &dev->vb2_mpegq; | 1116 | dev->mpeg_dev.queue = &dev->vb2_mpegq; |
1123 | err = video_register_device(dev->mpeg_dev, VFL_TYPE_GRABBER, -1); | 1117 | err = video_register_device(&dev->mpeg_dev, VFL_TYPE_GRABBER, -1); |
1124 | if (err < 0) { | 1118 | if (err < 0) { |
1125 | printk(KERN_INFO "%s/2: can't register mpeg device\n", | 1119 | printk(KERN_INFO "%s/2: can't register mpeg device\n", |
1126 | dev->core->name); | 1120 | dev->core->name); |
1127 | return err; | 1121 | return err; |
1128 | } | 1122 | } |
1129 | printk(KERN_INFO "%s/2: registered device %s [mpeg]\n", | 1123 | printk(KERN_INFO "%s/2: registered device %s [mpeg]\n", |
1130 | dev->core->name, video_device_node_name(dev->mpeg_dev)); | 1124 | dev->core->name, video_device_node_name(&dev->mpeg_dev)); |
1131 | return 0; | 1125 | return 0; |
1132 | } | 1126 | } |
1133 | 1127 | ||
diff --git a/drivers/media/pci/cx88/cx88-core.c b/drivers/media/pci/cx88/cx88-core.c index c38d5a12e277..3501be9f19d8 100644 --- a/drivers/media/pci/cx88/cx88-core.c +++ b/drivers/media/pci/cx88/cx88-core.c | |||
@@ -985,17 +985,14 @@ int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm) | |||
985 | 985 | ||
986 | /* ------------------------------------------------------------------ */ | 986 | /* ------------------------------------------------------------------ */ |
987 | 987 | ||
988 | struct video_device *cx88_vdev_init(struct cx88_core *core, | 988 | void cx88_vdev_init(struct cx88_core *core, |
989 | struct pci_dev *pci, | 989 | struct pci_dev *pci, |
990 | const struct video_device *template_, | 990 | struct video_device *vfd, |
991 | const char *type) | 991 | const struct video_device *template_, |
992 | const char *type) | ||
992 | { | 993 | { |
993 | struct video_device *vfd; | ||
994 | |||
995 | vfd = video_device_alloc(); | ||
996 | if (NULL == vfd) | ||
997 | return NULL; | ||
998 | *vfd = *template_; | 994 | *vfd = *template_; |
995 | |||
999 | /* | 996 | /* |
1000 | * The dev pointer of v4l2_device is NULL, instead we set the | 997 | * The dev pointer of v4l2_device is NULL, instead we set the |
1001 | * video_device dev_parent pointer to the correct PCI bus device. | 998 | * video_device dev_parent pointer to the correct PCI bus device. |
@@ -1004,11 +1001,10 @@ struct video_device *cx88_vdev_init(struct cx88_core *core, | |||
1004 | */ | 1001 | */ |
1005 | vfd->v4l2_dev = &core->v4l2_dev; | 1002 | vfd->v4l2_dev = &core->v4l2_dev; |
1006 | vfd->dev_parent = &pci->dev; | 1003 | vfd->dev_parent = &pci->dev; |
1007 | vfd->release = video_device_release; | 1004 | vfd->release = video_device_release_empty; |
1008 | vfd->lock = &core->lock; | 1005 | vfd->lock = &core->lock; |
1009 | snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", | 1006 | snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", |
1010 | core->name, type, core->board.name); | 1007 | core->name, type, core->board.name); |
1011 | return vfd; | ||
1012 | } | 1008 | } |
1013 | 1009 | ||
1014 | struct cx88_core* cx88_core_get(struct pci_dev *pci) | 1010 | struct cx88_core* cx88_core_get(struct pci_dev *pci) |
diff --git a/drivers/media/pci/cx88/cx88-mpeg.c b/drivers/media/pci/cx88/cx88-mpeg.c index a369b0840acf..98344540c51f 100644 --- a/drivers/media/pci/cx88/cx88-mpeg.c +++ b/drivers/media/pci/cx88/cx88-mpeg.c | |||
@@ -732,7 +732,7 @@ static int cx8802_probe(struct pci_dev *pci_dev, | |||
732 | dev->alloc_ctx = vb2_dma_sg_init_ctx(&pci_dev->dev); | 732 | dev->alloc_ctx = vb2_dma_sg_init_ctx(&pci_dev->dev); |
733 | if (IS_ERR(dev->alloc_ctx)) { | 733 | if (IS_ERR(dev->alloc_ctx)) { |
734 | err = PTR_ERR(dev->alloc_ctx); | 734 | err = PTR_ERR(dev->alloc_ctx); |
735 | goto fail_core; | 735 | goto fail_dev; |
736 | } | 736 | } |
737 | dev->core = core; | 737 | dev->core = core; |
738 | 738 | ||
@@ -754,6 +754,7 @@ static int cx8802_probe(struct pci_dev *pci_dev, | |||
754 | 754 | ||
755 | fail_free: | 755 | fail_free: |
756 | vb2_dma_sg_cleanup_ctx(dev->alloc_ctx); | 756 | vb2_dma_sg_cleanup_ctx(dev->alloc_ctx); |
757 | fail_dev: | ||
757 | kfree(dev); | 758 | kfree(dev); |
758 | fail_core: | 759 | fail_core: |
759 | core->dvbdev = NULL; | 760 | core->dvbdev = NULL; |
diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c index 860c98fc72c7..c9decd80bf61 100644 --- a/drivers/media/pci/cx88/cx88-video.c +++ b/drivers/media/pci/cx88/cx88-video.c | |||
@@ -1274,27 +1274,9 @@ static const struct v4l2_ctrl_ops cx8800_ctrl_aud_ops = { | |||
1274 | 1274 | ||
1275 | static void cx8800_unregister_video(struct cx8800_dev *dev) | 1275 | static void cx8800_unregister_video(struct cx8800_dev *dev) |
1276 | { | 1276 | { |
1277 | if (dev->radio_dev) { | 1277 | video_unregister_device(&dev->radio_dev); |
1278 | if (video_is_registered(dev->radio_dev)) | 1278 | video_unregister_device(&dev->vbi_dev); |
1279 | video_unregister_device(dev->radio_dev); | 1279 | video_unregister_device(&dev->video_dev); |
1280 | else | ||
1281 | video_device_release(dev->radio_dev); | ||
1282 | dev->radio_dev = NULL; | ||
1283 | } | ||
1284 | if (dev->vbi_dev) { | ||
1285 | if (video_is_registered(dev->vbi_dev)) | ||
1286 | video_unregister_device(dev->vbi_dev); | ||
1287 | else | ||
1288 | video_device_release(dev->vbi_dev); | ||
1289 | dev->vbi_dev = NULL; | ||
1290 | } | ||
1291 | if (dev->video_dev) { | ||
1292 | if (video_is_registered(dev->video_dev)) | ||
1293 | video_unregister_device(dev->video_dev); | ||
1294 | else | ||
1295 | video_device_release(dev->video_dev); | ||
1296 | dev->video_dev = NULL; | ||
1297 | } | ||
1298 | } | 1280 | } |
1299 | 1281 | ||
1300 | static int cx8800_initdev(struct pci_dev *pci_dev, | 1282 | static int cx8800_initdev(struct pci_dev *pci_dev, |
@@ -1485,12 +1467,12 @@ static int cx8800_initdev(struct pci_dev *pci_dev, | |||
1485 | goto fail_unreg; | 1467 | goto fail_unreg; |
1486 | 1468 | ||
1487 | /* register v4l devices */ | 1469 | /* register v4l devices */ |
1488 | dev->video_dev = cx88_vdev_init(core,dev->pci, | 1470 | cx88_vdev_init(core, dev->pci, &dev->video_dev, |
1489 | &cx8800_video_template,"video"); | 1471 | &cx8800_video_template, "video"); |
1490 | video_set_drvdata(dev->video_dev, dev); | 1472 | video_set_drvdata(&dev->video_dev, dev); |
1491 | dev->video_dev->ctrl_handler = &core->video_hdl; | 1473 | dev->video_dev.ctrl_handler = &core->video_hdl; |
1492 | dev->video_dev->queue = &dev->vb2_vidq; | 1474 | dev->video_dev.queue = &dev->vb2_vidq; |
1493 | err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER, | 1475 | err = video_register_device(&dev->video_dev, VFL_TYPE_GRABBER, |
1494 | video_nr[core->nr]); | 1476 | video_nr[core->nr]); |
1495 | if (err < 0) { | 1477 | if (err < 0) { |
1496 | printk(KERN_ERR "%s/0: can't register video device\n", | 1478 | printk(KERN_ERR "%s/0: can't register video device\n", |
@@ -1498,12 +1480,13 @@ static int cx8800_initdev(struct pci_dev *pci_dev, | |||
1498 | goto fail_unreg; | 1480 | goto fail_unreg; |
1499 | } | 1481 | } |
1500 | printk(KERN_INFO "%s/0: registered device %s [v4l2]\n", | 1482 | printk(KERN_INFO "%s/0: registered device %s [v4l2]\n", |
1501 | core->name, video_device_node_name(dev->video_dev)); | 1483 | core->name, video_device_node_name(&dev->video_dev)); |
1502 | 1484 | ||
1503 | dev->vbi_dev = cx88_vdev_init(core,dev->pci,&cx8800_vbi_template,"vbi"); | 1485 | cx88_vdev_init(core, dev->pci, &dev->vbi_dev, |
1504 | video_set_drvdata(dev->vbi_dev, dev); | 1486 | &cx8800_vbi_template, "vbi"); |
1505 | dev->vbi_dev->queue = &dev->vb2_vbiq; | 1487 | video_set_drvdata(&dev->vbi_dev, dev); |
1506 | err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI, | 1488 | dev->vbi_dev.queue = &dev->vb2_vbiq; |
1489 | err = video_register_device(&dev->vbi_dev, VFL_TYPE_VBI, | ||
1507 | vbi_nr[core->nr]); | 1490 | vbi_nr[core->nr]); |
1508 | if (err < 0) { | 1491 | if (err < 0) { |
1509 | printk(KERN_ERR "%s/0: can't register vbi device\n", | 1492 | printk(KERN_ERR "%s/0: can't register vbi device\n", |
@@ -1511,14 +1494,14 @@ static int cx8800_initdev(struct pci_dev *pci_dev, | |||
1511 | goto fail_unreg; | 1494 | goto fail_unreg; |
1512 | } | 1495 | } |
1513 | printk(KERN_INFO "%s/0: registered device %s\n", | 1496 | printk(KERN_INFO "%s/0: registered device %s\n", |
1514 | core->name, video_device_node_name(dev->vbi_dev)); | 1497 | core->name, video_device_node_name(&dev->vbi_dev)); |
1515 | 1498 | ||
1516 | if (core->board.radio.type == CX88_RADIO) { | 1499 | if (core->board.radio.type == CX88_RADIO) { |
1517 | dev->radio_dev = cx88_vdev_init(core,dev->pci, | 1500 | cx88_vdev_init(core, dev->pci, &dev->radio_dev, |
1518 | &cx8800_radio_template,"radio"); | 1501 | &cx8800_radio_template, "radio"); |
1519 | video_set_drvdata(dev->radio_dev, dev); | 1502 | video_set_drvdata(&dev->radio_dev, dev); |
1520 | dev->radio_dev->ctrl_handler = &core->audio_hdl; | 1503 | dev->radio_dev.ctrl_handler = &core->audio_hdl; |
1521 | err = video_register_device(dev->radio_dev,VFL_TYPE_RADIO, | 1504 | err = video_register_device(&dev->radio_dev, VFL_TYPE_RADIO, |
1522 | radio_nr[core->nr]); | 1505 | radio_nr[core->nr]); |
1523 | if (err < 0) { | 1506 | if (err < 0) { |
1524 | printk(KERN_ERR "%s/0: can't register radio device\n", | 1507 | printk(KERN_ERR "%s/0: can't register radio device\n", |
@@ -1526,7 +1509,7 @@ static int cx8800_initdev(struct pci_dev *pci_dev, | |||
1526 | goto fail_unreg; | 1509 | goto fail_unreg; |
1527 | } | 1510 | } |
1528 | printk(KERN_INFO "%s/0: registered device %s\n", | 1511 | printk(KERN_INFO "%s/0: registered device %s\n", |
1529 | core->name, video_device_node_name(dev->radio_dev)); | 1512 | core->name, video_device_node_name(&dev->radio_dev)); |
1530 | } | 1513 | } |
1531 | 1514 | ||
1532 | /* start tvaudio thread */ | 1515 | /* start tvaudio thread */ |
diff --git a/drivers/media/pci/cx88/cx88.h b/drivers/media/pci/cx88/cx88.h index 7748ca9abb09..b9fe1ac24803 100644 --- a/drivers/media/pci/cx88/cx88.h +++ b/drivers/media/pci/cx88/cx88.h | |||
@@ -478,9 +478,9 @@ struct cx8800_dev { | |||
478 | 478 | ||
479 | /* various device info */ | 479 | /* various device info */ |
480 | unsigned int resources; | 480 | unsigned int resources; |
481 | struct video_device *video_dev; | 481 | struct video_device video_dev; |
482 | struct video_device *vbi_dev; | 482 | struct video_device vbi_dev; |
483 | struct video_device *radio_dev; | 483 | struct video_device radio_dev; |
484 | 484 | ||
485 | /* pci i/o */ | 485 | /* pci i/o */ |
486 | struct pci_dev *pci; | 486 | struct pci_dev *pci; |
@@ -563,7 +563,7 @@ struct cx8802_dev { | |||
563 | /* for blackbird only */ | 563 | /* for blackbird only */ |
564 | struct list_head devlist; | 564 | struct list_head devlist; |
565 | #if IS_ENABLED(CONFIG_VIDEO_CX88_BLACKBIRD) | 565 | #if IS_ENABLED(CONFIG_VIDEO_CX88_BLACKBIRD) |
566 | struct video_device *mpeg_dev; | 566 | struct video_device mpeg_dev; |
567 | u32 mailbox; | 567 | u32 mailbox; |
568 | 568 | ||
569 | /* mpeg params */ | 569 | /* mpeg params */ |
@@ -647,10 +647,11 @@ extern int cx88_set_scale(struct cx88_core *core, unsigned int width, | |||
647 | unsigned int height, enum v4l2_field field); | 647 | unsigned int height, enum v4l2_field field); |
648 | extern int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm); | 648 | extern int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm); |
649 | 649 | ||
650 | extern struct video_device *cx88_vdev_init(struct cx88_core *core, | 650 | extern void cx88_vdev_init(struct cx88_core *core, |
651 | struct pci_dev *pci, | 651 | struct pci_dev *pci, |
652 | const struct video_device *template_, | 652 | struct video_device *vfd, |
653 | const char *type); | 653 | const struct video_device *template_, |
654 | const char *type); | ||
654 | extern struct cx88_core *cx88_core_get(struct pci_dev *pci); | 655 | extern struct cx88_core *cx88_core_get(struct pci_dev *pci); |
655 | extern void cx88_core_put(struct cx88_core *core, | 656 | extern void cx88_core_put(struct cx88_core *core, |
656 | struct pci_dev *pci); | 657 | struct pci_dev *pci); |
diff --git a/drivers/media/pci/ivtv/ivtv-alsa-main.c b/drivers/media/pci/ivtv/ivtv-alsa-main.c index 39b52929755a..41fa21534edf 100644 --- a/drivers/media/pci/ivtv/ivtv-alsa-main.c +++ b/drivers/media/pci/ivtv/ivtv-alsa-main.c | |||
@@ -224,7 +224,7 @@ static int ivtv_alsa_load(struct ivtv *itv) | |||
224 | } | 224 | } |
225 | 225 | ||
226 | s = &itv->streams[IVTV_ENC_STREAM_TYPE_PCM]; | 226 | s = &itv->streams[IVTV_ENC_STREAM_TYPE_PCM]; |
227 | if (s->vdev == NULL) { | 227 | if (s->vdev.v4l2_dev == NULL) { |
228 | IVTV_DEBUG_ALSA_INFO("%s: PCM stream for card is disabled - " | 228 | IVTV_DEBUG_ALSA_INFO("%s: PCM stream for card is disabled - " |
229 | "skipping\n", __func__); | 229 | "skipping\n", __func__); |
230 | return 0; | 230 | return 0; |
diff --git a/drivers/media/pci/ivtv/ivtv-alsa-pcm.c b/drivers/media/pci/ivtv/ivtv-alsa-pcm.c index 7bf9cbca4fa6..f198b9826ed8 100644 --- a/drivers/media/pci/ivtv/ivtv-alsa-pcm.c +++ b/drivers/media/pci/ivtv/ivtv-alsa-pcm.c | |||
@@ -167,7 +167,7 @@ static int snd_ivtv_pcm_capture_open(struct snd_pcm_substream *substream) | |||
167 | 167 | ||
168 | s = &itv->streams[IVTV_ENC_STREAM_TYPE_PCM]; | 168 | s = &itv->streams[IVTV_ENC_STREAM_TYPE_PCM]; |
169 | 169 | ||
170 | v4l2_fh_init(&item.fh, s->vdev); | 170 | v4l2_fh_init(&item.fh, &s->vdev); |
171 | item.itv = itv; | 171 | item.itv = itv; |
172 | item.type = s->type; | 172 | item.type = s->type; |
173 | 173 | ||
diff --git a/drivers/media/pci/ivtv/ivtv-driver.c b/drivers/media/pci/ivtv/ivtv-driver.c index 802642d26643..c2e60b4f292d 100644 --- a/drivers/media/pci/ivtv/ivtv-driver.c +++ b/drivers/media/pci/ivtv/ivtv-driver.c | |||
@@ -1284,7 +1284,7 @@ static int ivtv_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) | |||
1284 | return 0; | 1284 | return 0; |
1285 | 1285 | ||
1286 | free_streams: | 1286 | free_streams: |
1287 | ivtv_streams_cleanup(itv, 1); | 1287 | ivtv_streams_cleanup(itv); |
1288 | free_irq: | 1288 | free_irq: |
1289 | free_irq(itv->pdev->irq, (void *)itv); | 1289 | free_irq(itv->pdev->irq, (void *)itv); |
1290 | free_i2c: | 1290 | free_i2c: |
@@ -1444,7 +1444,7 @@ static void ivtv_remove(struct pci_dev *pdev) | |||
1444 | flush_kthread_worker(&itv->irq_worker); | 1444 | flush_kthread_worker(&itv->irq_worker); |
1445 | kthread_stop(itv->irq_worker_task); | 1445 | kthread_stop(itv->irq_worker_task); |
1446 | 1446 | ||
1447 | ivtv_streams_cleanup(itv, 1); | 1447 | ivtv_streams_cleanup(itv); |
1448 | ivtv_udma_free(itv); | 1448 | ivtv_udma_free(itv); |
1449 | 1449 | ||
1450 | v4l2_ctrl_handler_free(&itv->cxhdl.hdl); | 1450 | v4l2_ctrl_handler_free(&itv->cxhdl.hdl); |
diff --git a/drivers/media/pci/ivtv/ivtv-driver.h b/drivers/media/pci/ivtv/ivtv-driver.h index bc309f42c8ed..e8b6c7ad2ba9 100644 --- a/drivers/media/pci/ivtv/ivtv-driver.h +++ b/drivers/media/pci/ivtv/ivtv-driver.h | |||
@@ -327,7 +327,7 @@ struct ivtv; /* forward reference */ | |||
327 | struct ivtv_stream { | 327 | struct ivtv_stream { |
328 | /* These first four fields are always set, even if the stream | 328 | /* These first four fields are always set, even if the stream |
329 | is not actually created. */ | 329 | is not actually created. */ |
330 | struct video_device *vdev; /* NULL when stream not created */ | 330 | struct video_device vdev; /* vdev.v4l2_dev is NULL if there is no device */ |
331 | struct ivtv *itv; /* for ease of use */ | 331 | struct ivtv *itv; /* for ease of use */ |
332 | const char *name; /* name of the stream */ | 332 | const char *name; /* name of the stream */ |
333 | int type; /* stream type */ | 333 | int type; /* stream type */ |
diff --git a/drivers/media/pci/ivtv/ivtv-fileops.c b/drivers/media/pci/ivtv/ivtv-fileops.c index e5ff6277ca85..605d280d8a5f 100644 --- a/drivers/media/pci/ivtv/ivtv-fileops.c +++ b/drivers/media/pci/ivtv/ivtv-fileops.c | |||
@@ -995,7 +995,7 @@ static int ivtv_open(struct file *filp) | |||
995 | IVTV_DEBUG_WARN("nomem on v4l2 open\n"); | 995 | IVTV_DEBUG_WARN("nomem on v4l2 open\n"); |
996 | return -ENOMEM; | 996 | return -ENOMEM; |
997 | } | 997 | } |
998 | v4l2_fh_init(&item->fh, s->vdev); | 998 | v4l2_fh_init(&item->fh, &s->vdev); |
999 | item->itv = itv; | 999 | item->itv = itv; |
1000 | item->type = s->type; | 1000 | item->type = s->type; |
1001 | 1001 | ||
diff --git a/drivers/media/pci/ivtv/ivtv-ioctl.c b/drivers/media/pci/ivtv/ivtv-ioctl.c index 4d8ee18c3feb..6fe6c4a0e858 100644 --- a/drivers/media/pci/ivtv/ivtv-ioctl.c +++ b/drivers/media/pci/ivtv/ivtv-ioctl.c | |||
@@ -448,9 +448,12 @@ static int ivtv_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *f | |||
448 | static int ivtv_g_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt) | 448 | static int ivtv_g_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt) |
449 | { | 449 | { |
450 | struct ivtv *itv = fh2id(fh)->itv; | 450 | struct ivtv *itv = fh2id(fh)->itv; |
451 | struct ivtv_stream *s = &itv->streams[fh2id(fh)->type]; | ||
451 | struct v4l2_window *winfmt = &fmt->fmt.win; | 452 | struct v4l2_window *winfmt = &fmt->fmt.win; |
452 | 453 | ||
453 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | 454 | if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) |
455 | return -EINVAL; | ||
456 | if (!itv->osd_video_pbase) | ||
454 | return -EINVAL; | 457 | return -EINVAL; |
455 | winfmt->chromakey = itv->osd_chroma_key; | 458 | winfmt->chromakey = itv->osd_chroma_key; |
456 | winfmt->global_alpha = itv->osd_global_alpha; | 459 | winfmt->global_alpha = itv->osd_global_alpha; |
@@ -555,10 +558,13 @@ static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format | |||
555 | static int ivtv_try_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt) | 558 | static int ivtv_try_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt) |
556 | { | 559 | { |
557 | struct ivtv *itv = fh2id(fh)->itv; | 560 | struct ivtv *itv = fh2id(fh)->itv; |
561 | struct ivtv_stream *s = &itv->streams[fh2id(fh)->type]; | ||
558 | u32 chromakey = fmt->fmt.win.chromakey; | 562 | u32 chromakey = fmt->fmt.win.chromakey; |
559 | u8 global_alpha = fmt->fmt.win.global_alpha; | 563 | u8 global_alpha = fmt->fmt.win.global_alpha; |
560 | 564 | ||
561 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | 565 | if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) |
566 | return -EINVAL; | ||
567 | if (!itv->osd_video_pbase) | ||
562 | return -EINVAL; | 568 | return -EINVAL; |
563 | ivtv_g_fmt_vid_out_overlay(file, fh, fmt); | 569 | ivtv_g_fmt_vid_out_overlay(file, fh, fmt); |
564 | fmt->fmt.win.chromakey = chromakey; | 570 | fmt->fmt.win.chromakey = chromakey; |
@@ -741,6 +747,11 @@ static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vc | |||
741 | snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev)); | 747 | snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev)); |
742 | vcap->capabilities = itv->v4l2_cap | V4L2_CAP_DEVICE_CAPS; | 748 | vcap->capabilities = itv->v4l2_cap | V4L2_CAP_DEVICE_CAPS; |
743 | vcap->device_caps = s->caps; | 749 | vcap->device_caps = s->caps; |
750 | if ((s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY) && | ||
751 | !itv->osd_video_pbase) { | ||
752 | vcap->capabilities &= ~V4L2_CAP_VIDEO_OUTPUT_OVERLAY; | ||
753 | vcap->device_caps &= ~V4L2_CAP_VIDEO_OUTPUT_OVERLAY; | ||
754 | } | ||
744 | return 0; | 755 | return 0; |
745 | } | 756 | } |
746 | 757 | ||
@@ -816,80 +827,103 @@ static int ivtv_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropca | |||
816 | { | 827 | { |
817 | struct ivtv_open_id *id = fh2id(fh); | 828 | struct ivtv_open_id *id = fh2id(fh); |
818 | struct ivtv *itv = id->itv; | 829 | struct ivtv *itv = id->itv; |
819 | struct yuv_playback_info *yi = &itv->yuv_info; | ||
820 | int streamtype; | ||
821 | |||
822 | streamtype = id->type; | ||
823 | 830 | ||
824 | if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) | ||
825 | return -EINVAL; | ||
826 | cropcap->bounds.top = cropcap->bounds.left = 0; | ||
827 | cropcap->bounds.width = 720; | ||
828 | if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { | 831 | if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { |
829 | cropcap->bounds.height = itv->is_50hz ? 576 : 480; | ||
830 | cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10; | 832 | cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10; |
831 | cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11; | 833 | cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11; |
832 | } else if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) { | 834 | } else if (cropcap->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { |
833 | if (yi->track_osd) { | ||
834 | cropcap->bounds.width = yi->osd_full_w; | ||
835 | cropcap->bounds.height = yi->osd_full_h; | ||
836 | } else { | ||
837 | cropcap->bounds.width = 720; | ||
838 | cropcap->bounds.height = | ||
839 | itv->is_out_50hz ? 576 : 480; | ||
840 | } | ||
841 | cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10; | 835 | cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10; |
842 | cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11; | 836 | cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11; |
843 | } else { | 837 | } else { |
844 | cropcap->bounds.height = itv->is_out_50hz ? 576 : 480; | 838 | return -EINVAL; |
845 | cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10; | ||
846 | cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11; | ||
847 | } | 839 | } |
848 | cropcap->defrect = cropcap->bounds; | ||
849 | return 0; | 840 | return 0; |
850 | } | 841 | } |
851 | 842 | ||
852 | static int ivtv_s_crop(struct file *file, void *fh, const struct v4l2_crop *crop) | 843 | static int ivtv_s_selection(struct file *file, void *fh, |
844 | struct v4l2_selection *sel) | ||
853 | { | 845 | { |
854 | struct ivtv_open_id *id = fh2id(fh); | 846 | struct ivtv_open_id *id = fh2id(fh); |
855 | struct ivtv *itv = id->itv; | 847 | struct ivtv *itv = id->itv; |
856 | struct yuv_playback_info *yi = &itv->yuv_info; | 848 | struct yuv_playback_info *yi = &itv->yuv_info; |
857 | int streamtype; | 849 | struct v4l2_rect r = { 0, 0, 720, 0 }; |
850 | int streamtype = id->type; | ||
858 | 851 | ||
859 | streamtype = id->type; | 852 | if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT || |
853 | !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | ||
854 | return -EINVAL; | ||
860 | 855 | ||
861 | if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && | 856 | if (sel->target != V4L2_SEL_TGT_COMPOSE) |
862 | (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { | ||
863 | if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) { | ||
864 | yi->main_rect = crop->c; | ||
865 | return 0; | ||
866 | } else { | ||
867 | if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4, | ||
868 | crop->c.width, crop->c.height, crop->c.left, crop->c.top)) { | ||
869 | itv->main_rect = crop->c; | ||
870 | return 0; | ||
871 | } | ||
872 | } | ||
873 | return -EINVAL; | 857 | return -EINVAL; |
858 | |||
859 | |||
860 | if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT || | ||
861 | !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | ||
862 | return -EINVAL; | ||
863 | |||
864 | r.height = itv->is_out_50hz ? 576 : 480; | ||
865 | if (streamtype == IVTV_DEC_STREAM_TYPE_YUV && yi->track_osd) { | ||
866 | r.width = yi->osd_full_w; | ||
867 | r.height = yi->osd_full_h; | ||
868 | } | ||
869 | sel->r.width = clamp(sel->r.width, 16U, r.width); | ||
870 | sel->r.height = clamp(sel->r.height, 16U, r.height); | ||
871 | sel->r.left = clamp_t(unsigned, sel->r.left, 0, r.width - sel->r.width); | ||
872 | sel->r.top = clamp_t(unsigned, sel->r.top, 0, r.height - sel->r.height); | ||
873 | |||
874 | if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) { | ||
875 | yi->main_rect = sel->r; | ||
876 | return 0; | ||
877 | } | ||
878 | if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4, | ||
879 | sel->r.width, sel->r.height, sel->r.left, sel->r.top)) { | ||
880 | itv->main_rect = sel->r; | ||
881 | return 0; | ||
874 | } | 882 | } |
875 | return -EINVAL; | 883 | return -EINVAL; |
876 | } | 884 | } |
877 | 885 | ||
878 | static int ivtv_g_crop(struct file *file, void *fh, struct v4l2_crop *crop) | 886 | static int ivtv_g_selection(struct file *file, void *fh, |
887 | struct v4l2_selection *sel) | ||
879 | { | 888 | { |
880 | struct ivtv_open_id *id = fh2id(fh); | 889 | struct ivtv_open_id *id = fh2id(fh); |
881 | struct ivtv *itv = id->itv; | 890 | struct ivtv *itv = id->itv; |
882 | struct yuv_playback_info *yi = &itv->yuv_info; | 891 | struct yuv_playback_info *yi = &itv->yuv_info; |
883 | int streamtype; | 892 | struct v4l2_rect r = { 0, 0, 720, 0 }; |
893 | int streamtype = id->type; | ||
894 | |||
895 | if (sel->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
896 | switch (sel->target) { | ||
897 | case V4L2_SEL_TGT_CROP_DEFAULT: | ||
898 | case V4L2_SEL_TGT_CROP_BOUNDS: | ||
899 | sel->r.top = sel->r.left = 0; | ||
900 | sel->r.width = 720; | ||
901 | sel->r.height = itv->is_50hz ? 576 : 480; | ||
902 | return 0; | ||
903 | default: | ||
904 | return -EINVAL; | ||
905 | } | ||
906 | } | ||
884 | 907 | ||
885 | streamtype = id->type; | 908 | if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT || |
909 | !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | ||
910 | return -EINVAL; | ||
886 | 911 | ||
887 | if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && | 912 | switch (sel->target) { |
888 | (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { | 913 | case V4L2_SEL_TGT_COMPOSE: |
889 | if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) | 914 | if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) |
890 | crop->c = yi->main_rect; | 915 | sel->r = yi->main_rect; |
891 | else | 916 | else |
892 | crop->c = itv->main_rect; | 917 | sel->r = itv->main_rect; |
918 | return 0; | ||
919 | case V4L2_SEL_TGT_COMPOSE_DEFAULT: | ||
920 | case V4L2_SEL_TGT_COMPOSE_BOUNDS: | ||
921 | r.height = itv->is_out_50hz ? 576 : 480; | ||
922 | if (streamtype == IVTV_DEC_STREAM_TYPE_YUV && yi->track_osd) { | ||
923 | r.width = yi->osd_full_w; | ||
924 | r.height = yi->osd_full_h; | ||
925 | } | ||
926 | sel->r = r; | ||
893 | return 0; | 927 | return 0; |
894 | } | 928 | } |
895 | return -EINVAL; | 929 | return -EINVAL; |
@@ -987,7 +1021,7 @@ int ivtv_s_input(struct file *file, void *fh, unsigned int inp) | |||
987 | else | 1021 | else |
988 | std = V4L2_STD_ALL; | 1022 | std = V4L2_STD_ALL; |
989 | for (i = 0; i <= IVTV_ENC_STREAM_TYPE_VBI; i++) | 1023 | for (i = 0; i <= IVTV_ENC_STREAM_TYPE_VBI; i++) |
990 | itv->streams[i].vdev->tvnorms = std; | 1024 | itv->streams[i].vdev.tvnorms = std; |
991 | 1025 | ||
992 | /* prevent others from messing with the streams until | 1026 | /* prevent others from messing with the streams until |
993 | we're finished changing inputs. */ | 1027 | we're finished changing inputs. */ |
@@ -1038,7 +1072,7 @@ static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency * | |||
1038 | struct ivtv *itv = fh2id(fh)->itv; | 1072 | struct ivtv *itv = fh2id(fh)->itv; |
1039 | struct ivtv_stream *s = &itv->streams[fh2id(fh)->type]; | 1073 | struct ivtv_stream *s = &itv->streams[fh2id(fh)->type]; |
1040 | 1074 | ||
1041 | if (s->vdev->vfl_dir) | 1075 | if (s->vdev.vfl_dir) |
1042 | return -ENOTTY; | 1076 | return -ENOTTY; |
1043 | if (vf->tuner != 0) | 1077 | if (vf->tuner != 0) |
1044 | return -EINVAL; | 1078 | return -EINVAL; |
@@ -1052,7 +1086,7 @@ int ivtv_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *v | |||
1052 | struct ivtv *itv = fh2id(fh)->itv; | 1086 | struct ivtv *itv = fh2id(fh)->itv; |
1053 | struct ivtv_stream *s = &itv->streams[fh2id(fh)->type]; | 1087 | struct ivtv_stream *s = &itv->streams[fh2id(fh)->type]; |
1054 | 1088 | ||
1055 | if (s->vdev->vfl_dir) | 1089 | if (s->vdev.vfl_dir) |
1056 | return -ENOTTY; | 1090 | return -ENOTTY; |
1057 | if (vf->tuner != 0) | 1091 | if (vf->tuner != 0) |
1058 | return -EINVAL; | 1092 | return -EINVAL; |
@@ -1340,6 +1374,7 @@ static int ivtv_try_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder | |||
1340 | static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) | 1374 | static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) |
1341 | { | 1375 | { |
1342 | struct ivtv *itv = fh2id(fh)->itv; | 1376 | struct ivtv *itv = fh2id(fh)->itv; |
1377 | struct ivtv_stream *s = &itv->streams[fh2id(fh)->type]; | ||
1343 | u32 data[CX2341X_MBOX_MAX_DATA]; | 1378 | u32 data[CX2341X_MBOX_MAX_DATA]; |
1344 | struct yuv_playback_info *yi = &itv->yuv_info; | 1379 | struct yuv_playback_info *yi = &itv->yuv_info; |
1345 | 1380 | ||
@@ -1363,10 +1398,10 @@ static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) | |||
1363 | 0, | 1398 | 0, |
1364 | }; | 1399 | }; |
1365 | 1400 | ||
1366 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) | 1401 | if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) |
1367 | return -EINVAL; | 1402 | return -ENOTTY; |
1368 | if (!itv->osd_video_pbase) | 1403 | if (!itv->osd_video_pbase) |
1369 | return -EINVAL; | 1404 | return -ENOTTY; |
1370 | 1405 | ||
1371 | fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY | | 1406 | fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY | |
1372 | V4L2_FBUF_CAP_GLOBAL_ALPHA; | 1407 | V4L2_FBUF_CAP_GLOBAL_ALPHA; |
@@ -1427,12 +1462,13 @@ static int ivtv_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffe | |||
1427 | { | 1462 | { |
1428 | struct ivtv_open_id *id = fh2id(fh); | 1463 | struct ivtv_open_id *id = fh2id(fh); |
1429 | struct ivtv *itv = id->itv; | 1464 | struct ivtv *itv = id->itv; |
1465 | struct ivtv_stream *s = &itv->streams[fh2id(fh)->type]; | ||
1430 | struct yuv_playback_info *yi = &itv->yuv_info; | 1466 | struct yuv_playback_info *yi = &itv->yuv_info; |
1431 | 1467 | ||
1432 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) | 1468 | if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) |
1433 | return -EINVAL; | 1469 | return -ENOTTY; |
1434 | if (!itv->osd_video_pbase) | 1470 | if (!itv->osd_video_pbase) |
1435 | return -EINVAL; | 1471 | return -ENOTTY; |
1436 | 1472 | ||
1437 | itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0; | 1473 | itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0; |
1438 | itv->osd_local_alpha_state = | 1474 | itv->osd_local_alpha_state = |
@@ -1447,9 +1483,12 @@ static int ivtv_overlay(struct file *file, void *fh, unsigned int on) | |||
1447 | { | 1483 | { |
1448 | struct ivtv_open_id *id = fh2id(fh); | 1484 | struct ivtv_open_id *id = fh2id(fh); |
1449 | struct ivtv *itv = id->itv; | 1485 | struct ivtv *itv = id->itv; |
1486 | struct ivtv_stream *s = &itv->streams[fh2id(fh)->type]; | ||
1450 | 1487 | ||
1451 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) | 1488 | if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) |
1452 | return -EINVAL; | 1489 | return -ENOTTY; |
1490 | if (!itv->osd_video_pbase) | ||
1491 | return -ENOTTY; | ||
1453 | 1492 | ||
1454 | ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, on != 0); | 1493 | ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, on != 0); |
1455 | 1494 | ||
@@ -1547,7 +1586,7 @@ static int ivtv_log_status(struct file *file, void *fh) | |||
1547 | for (i = 0; i < IVTV_MAX_STREAMS; i++) { | 1586 | for (i = 0; i < IVTV_MAX_STREAMS; i++) { |
1548 | struct ivtv_stream *s = &itv->streams[i]; | 1587 | struct ivtv_stream *s = &itv->streams[i]; |
1549 | 1588 | ||
1550 | if (s->vdev == NULL || s->buffers == 0) | 1589 | if (s->vdev.v4l2_dev == NULL || s->buffers == 0) |
1551 | continue; | 1590 | continue; |
1552 | IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags, | 1591 | IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags, |
1553 | (s->buffers - s->q_free.buffers) * 100 / s->buffers, | 1592 | (s->buffers - s->q_free.buffers) * 100 / s->buffers, |
@@ -1837,8 +1876,8 @@ static const struct v4l2_ioctl_ops ivtv_ioctl_ops = { | |||
1837 | .vidioc_enum_output = ivtv_enum_output, | 1876 | .vidioc_enum_output = ivtv_enum_output, |
1838 | .vidioc_enumaudout = ivtv_enumaudout, | 1877 | .vidioc_enumaudout = ivtv_enumaudout, |
1839 | .vidioc_cropcap = ivtv_cropcap, | 1878 | .vidioc_cropcap = ivtv_cropcap, |
1840 | .vidioc_s_crop = ivtv_s_crop, | 1879 | .vidioc_s_selection = ivtv_s_selection, |
1841 | .vidioc_g_crop = ivtv_g_crop, | 1880 | .vidioc_g_selection = ivtv_g_selection, |
1842 | .vidioc_g_input = ivtv_g_input, | 1881 | .vidioc_g_input = ivtv_g_input, |
1843 | .vidioc_s_input = ivtv_s_input, | 1882 | .vidioc_s_input = ivtv_s_input, |
1844 | .vidioc_g_output = ivtv_g_output, | 1883 | .vidioc_g_output = ivtv_g_output, |
diff --git a/drivers/media/pci/ivtv/ivtv-irq.c b/drivers/media/pci/ivtv/ivtv-irq.c index e7d701777e53..36ca2d67c812 100644 --- a/drivers/media/pci/ivtv/ivtv-irq.c +++ b/drivers/media/pci/ivtv/ivtv-irq.c | |||
@@ -75,7 +75,7 @@ static void ivtv_pio_work_handler(struct ivtv *itv) | |||
75 | 75 | ||
76 | IVTV_DEBUG_HI_DMA("ivtv_pio_work_handler\n"); | 76 | IVTV_DEBUG_HI_DMA("ivtv_pio_work_handler\n"); |
77 | if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS || | 77 | if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS || |
78 | s->vdev == NULL || !ivtv_use_pio(s)) { | 78 | s->vdev.v4l2_dev == NULL || !ivtv_use_pio(s)) { |
79 | itv->cur_pio_stream = -1; | 79 | itv->cur_pio_stream = -1; |
80 | /* trigger PIO complete user interrupt */ | 80 | /* trigger PIO complete user interrupt */ |
81 | write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44); | 81 | write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44); |
@@ -132,7 +132,7 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA | |||
132 | int rc; | 132 | int rc; |
133 | 133 | ||
134 | /* sanity checks */ | 134 | /* sanity checks */ |
135 | if (s->vdev == NULL) { | 135 | if (s->vdev.v4l2_dev == NULL) { |
136 | IVTV_DEBUG_WARN("Stream %s not started\n", s->name); | 136 | IVTV_DEBUG_WARN("Stream %s not started\n", s->name); |
137 | return -1; | 137 | return -1; |
138 | } | 138 | } |
@@ -890,8 +890,8 @@ static void ivtv_irq_vsync(struct ivtv *itv) | |||
890 | if (s) | 890 | if (s) |
891 | wake_up(&s->waitq); | 891 | wake_up(&s->waitq); |
892 | } | 892 | } |
893 | if (s && s->vdev) | 893 | if (s && s->vdev.v4l2_dev) |
894 | v4l2_event_queue(s->vdev, frame ? &evtop : &evbottom); | 894 | v4l2_event_queue(&s->vdev, frame ? &evtop : &evbottom); |
895 | wake_up(&itv->vsync_waitq); | 895 | wake_up(&itv->vsync_waitq); |
896 | 896 | ||
897 | /* Send VBI to saa7127 */ | 897 | /* Send VBI to saa7127 */ |
diff --git a/drivers/media/pci/ivtv/ivtv-streams.c b/drivers/media/pci/ivtv/ivtv-streams.c index f0a1cc472313..d27c6df97566 100644 --- a/drivers/media/pci/ivtv/ivtv-streams.c +++ b/drivers/media/pci/ivtv/ivtv-streams.c | |||
@@ -130,7 +130,8 @@ static struct { | |||
130 | "decoder MPG", | 130 | "decoder MPG", |
131 | VFL_TYPE_GRABBER, IVTV_V4L2_DEC_MPG_OFFSET, | 131 | VFL_TYPE_GRABBER, IVTV_V4L2_DEC_MPG_OFFSET, |
132 | PCI_DMA_TODEVICE, 0, | 132 | PCI_DMA_TODEVICE, 0, |
133 | V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, | 133 | V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | |
134 | V4L2_CAP_VIDEO_OUTPUT_OVERLAY, | ||
134 | &ivtv_v4l2_dec_fops | 135 | &ivtv_v4l2_dec_fops |
135 | }, | 136 | }, |
136 | { /* IVTV_DEC_STREAM_TYPE_VBI */ | 137 | { /* IVTV_DEC_STREAM_TYPE_VBI */ |
@@ -151,7 +152,8 @@ static struct { | |||
151 | "decoder YUV", | 152 | "decoder YUV", |
152 | VFL_TYPE_GRABBER, IVTV_V4L2_DEC_YUV_OFFSET, | 153 | VFL_TYPE_GRABBER, IVTV_V4L2_DEC_YUV_OFFSET, |
153 | PCI_DMA_TODEVICE, 0, | 154 | PCI_DMA_TODEVICE, 0, |
154 | V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, | 155 | V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | |
156 | V4L2_CAP_VIDEO_OUTPUT_OVERLAY, | ||
155 | &ivtv_v4l2_dec_fops | 157 | &ivtv_v4l2_dec_fops |
156 | } | 158 | } |
157 | }; | 159 | }; |
@@ -159,11 +161,9 @@ static struct { | |||
159 | static void ivtv_stream_init(struct ivtv *itv, int type) | 161 | static void ivtv_stream_init(struct ivtv *itv, int type) |
160 | { | 162 | { |
161 | struct ivtv_stream *s = &itv->streams[type]; | 163 | struct ivtv_stream *s = &itv->streams[type]; |
162 | struct video_device *vdev = s->vdev; | ||
163 | 164 | ||
164 | /* we need to keep vdev, so restore it afterwards */ | 165 | /* we need to keep vdev, so restore it afterwards */ |
165 | memset(s, 0, sizeof(*s)); | 166 | memset(s, 0, sizeof(*s)); |
166 | s->vdev = vdev; | ||
167 | 167 | ||
168 | /* initialize ivtv_stream fields */ | 168 | /* initialize ivtv_stream fields */ |
169 | s->itv = itv; | 169 | s->itv = itv; |
@@ -194,10 +194,10 @@ static int ivtv_prep_dev(struct ivtv *itv, int type) | |||
194 | int num_offset = ivtv_stream_info[type].num_offset; | 194 | int num_offset = ivtv_stream_info[type].num_offset; |
195 | int num = itv->instance + ivtv_first_minor + num_offset; | 195 | int num = itv->instance + ivtv_first_minor + num_offset; |
196 | 196 | ||
197 | /* These four fields are always initialized. If vdev == NULL, then | 197 | /* These four fields are always initialized. If vdev.v4l2_dev == NULL, then |
198 | this stream is not in use. In that case no other fields but these | 198 | this stream is not in use. In that case no other fields but these |
199 | four can be used. */ | 199 | four can be used. */ |
200 | s->vdev = NULL; | 200 | s->vdev.v4l2_dev = NULL; |
201 | s->itv = itv; | 201 | s->itv = itv; |
202 | s->type = type; | 202 | s->type = type; |
203 | s->name = ivtv_stream_info[type].name; | 203 | s->name = ivtv_stream_info[type].name; |
@@ -218,40 +218,33 @@ static int ivtv_prep_dev(struct ivtv *itv, int type) | |||
218 | 218 | ||
219 | ivtv_stream_init(itv, type); | 219 | ivtv_stream_init(itv, type); |
220 | 220 | ||
221 | /* allocate and initialize the v4l2 video device structure */ | 221 | snprintf(s->vdev.name, sizeof(s->vdev.name), "%s %s", |
222 | s->vdev = video_device_alloc(); | ||
223 | if (s->vdev == NULL) { | ||
224 | IVTV_ERR("Couldn't allocate v4l2 video_device for %s\n", s->name); | ||
225 | return -ENOMEM; | ||
226 | } | ||
227 | |||
228 | snprintf(s->vdev->name, sizeof(s->vdev->name), "%s %s", | ||
229 | itv->v4l2_dev.name, s->name); | 222 | itv->v4l2_dev.name, s->name); |
230 | 223 | ||
231 | s->vdev->num = num; | 224 | s->vdev.num = num; |
232 | s->vdev->v4l2_dev = &itv->v4l2_dev; | 225 | s->vdev.v4l2_dev = &itv->v4l2_dev; |
233 | if (ivtv_stream_info[type].v4l2_caps & | 226 | if (ivtv_stream_info[type].v4l2_caps & |
234 | (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_SLICED_VBI_OUTPUT)) | 227 | (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_SLICED_VBI_OUTPUT)) |
235 | s->vdev->vfl_dir = VFL_DIR_TX; | 228 | s->vdev.vfl_dir = VFL_DIR_TX; |
236 | s->vdev->fops = ivtv_stream_info[type].fops; | 229 | s->vdev.fops = ivtv_stream_info[type].fops; |
237 | s->vdev->ctrl_handler = itv->v4l2_dev.ctrl_handler; | 230 | s->vdev.ctrl_handler = itv->v4l2_dev.ctrl_handler; |
238 | s->vdev->release = video_device_release; | 231 | s->vdev.release = video_device_release_empty; |
239 | s->vdev->tvnorms = V4L2_STD_ALL; | 232 | s->vdev.tvnorms = V4L2_STD_ALL; |
240 | s->vdev->lock = &itv->serialize_lock; | 233 | s->vdev.lock = &itv->serialize_lock; |
241 | if (s->type == IVTV_DEC_STREAM_TYPE_VBI) { | 234 | if (s->type == IVTV_DEC_STREAM_TYPE_VBI) { |
242 | v4l2_disable_ioctl(s->vdev, VIDIOC_S_AUDIO); | 235 | v4l2_disable_ioctl(&s->vdev, VIDIOC_S_AUDIO); |
243 | v4l2_disable_ioctl(s->vdev, VIDIOC_G_AUDIO); | 236 | v4l2_disable_ioctl(&s->vdev, VIDIOC_G_AUDIO); |
244 | v4l2_disable_ioctl(s->vdev, VIDIOC_ENUMAUDIO); | 237 | v4l2_disable_ioctl(&s->vdev, VIDIOC_ENUMAUDIO); |
245 | v4l2_disable_ioctl(s->vdev, VIDIOC_ENUMINPUT); | 238 | v4l2_disable_ioctl(&s->vdev, VIDIOC_ENUMINPUT); |
246 | v4l2_disable_ioctl(s->vdev, VIDIOC_S_INPUT); | 239 | v4l2_disable_ioctl(&s->vdev, VIDIOC_S_INPUT); |
247 | v4l2_disable_ioctl(s->vdev, VIDIOC_G_INPUT); | 240 | v4l2_disable_ioctl(&s->vdev, VIDIOC_G_INPUT); |
248 | v4l2_disable_ioctl(s->vdev, VIDIOC_S_FREQUENCY); | 241 | v4l2_disable_ioctl(&s->vdev, VIDIOC_S_FREQUENCY); |
249 | v4l2_disable_ioctl(s->vdev, VIDIOC_G_FREQUENCY); | 242 | v4l2_disable_ioctl(&s->vdev, VIDIOC_G_FREQUENCY); |
250 | v4l2_disable_ioctl(s->vdev, VIDIOC_S_TUNER); | 243 | v4l2_disable_ioctl(&s->vdev, VIDIOC_S_TUNER); |
251 | v4l2_disable_ioctl(s->vdev, VIDIOC_G_TUNER); | 244 | v4l2_disable_ioctl(&s->vdev, VIDIOC_G_TUNER); |
252 | v4l2_disable_ioctl(s->vdev, VIDIOC_S_STD); | 245 | v4l2_disable_ioctl(&s->vdev, VIDIOC_S_STD); |
253 | } | 246 | } |
254 | ivtv_set_funcs(s->vdev); | 247 | ivtv_set_funcs(&s->vdev); |
255 | return 0; | 248 | return 0; |
256 | } | 249 | } |
257 | 250 | ||
@@ -266,7 +259,7 @@ int ivtv_streams_setup(struct ivtv *itv) | |||
266 | if (ivtv_prep_dev(itv, type)) | 259 | if (ivtv_prep_dev(itv, type)) |
267 | break; | 260 | break; |
268 | 261 | ||
269 | if (itv->streams[type].vdev == NULL) | 262 | if (itv->streams[type].vdev.v4l2_dev == NULL) |
270 | continue; | 263 | continue; |
271 | 264 | ||
272 | /* Allocate Stream */ | 265 | /* Allocate Stream */ |
@@ -277,7 +270,7 @@ int ivtv_streams_setup(struct ivtv *itv) | |||
277 | return 0; | 270 | return 0; |
278 | 271 | ||
279 | /* One or more streams could not be initialized. Clean 'em all up. */ | 272 | /* One or more streams could not be initialized. Clean 'em all up. */ |
280 | ivtv_streams_cleanup(itv, 0); | 273 | ivtv_streams_cleanup(itv); |
281 | return -ENOMEM; | 274 | return -ENOMEM; |
282 | } | 275 | } |
283 | 276 | ||
@@ -288,28 +281,26 @@ static int ivtv_reg_dev(struct ivtv *itv, int type) | |||
288 | const char *name; | 281 | const char *name; |
289 | int num; | 282 | int num; |
290 | 283 | ||
291 | if (s->vdev == NULL) | 284 | if (s->vdev.v4l2_dev == NULL) |
292 | return 0; | 285 | return 0; |
293 | 286 | ||
294 | num = s->vdev->num; | 287 | num = s->vdev.num; |
295 | /* card number + user defined offset + device offset */ | 288 | /* card number + user defined offset + device offset */ |
296 | if (type != IVTV_ENC_STREAM_TYPE_MPG) { | 289 | if (type != IVTV_ENC_STREAM_TYPE_MPG) { |
297 | struct ivtv_stream *s_mpg = &itv->streams[IVTV_ENC_STREAM_TYPE_MPG]; | 290 | struct ivtv_stream *s_mpg = &itv->streams[IVTV_ENC_STREAM_TYPE_MPG]; |
298 | 291 | ||
299 | if (s_mpg->vdev) | 292 | if (s_mpg->vdev.v4l2_dev) |
300 | num = s_mpg->vdev->num + ivtv_stream_info[type].num_offset; | 293 | num = s_mpg->vdev.num + ivtv_stream_info[type].num_offset; |
301 | } | 294 | } |
302 | video_set_drvdata(s->vdev, s); | 295 | video_set_drvdata(&s->vdev, s); |
303 | 296 | ||
304 | /* Register device. First try the desired minor, then any free one. */ | 297 | /* Register device. First try the desired minor, then any free one. */ |
305 | if (video_register_device_no_warn(s->vdev, vfl_type, num)) { | 298 | if (video_register_device_no_warn(&s->vdev, vfl_type, num)) { |
306 | IVTV_ERR("Couldn't register v4l2 device for %s (device node number %d)\n", | 299 | IVTV_ERR("Couldn't register v4l2 device for %s (device node number %d)\n", |
307 | s->name, num); | 300 | s->name, num); |
308 | video_device_release(s->vdev); | ||
309 | s->vdev = NULL; | ||
310 | return -ENOMEM; | 301 | return -ENOMEM; |
311 | } | 302 | } |
312 | name = video_device_node_name(s->vdev); | 303 | name = video_device_node_name(&s->vdev); |
313 | 304 | ||
314 | switch (vfl_type) { | 305 | switch (vfl_type) { |
315 | case VFL_TYPE_GRABBER: | 306 | case VFL_TYPE_GRABBER: |
@@ -346,29 +337,25 @@ int ivtv_streams_register(struct ivtv *itv) | |||
346 | return 0; | 337 | return 0; |
347 | 338 | ||
348 | /* One or more streams could not be initialized. Clean 'em all up. */ | 339 | /* One or more streams could not be initialized. Clean 'em all up. */ |
349 | ivtv_streams_cleanup(itv, 1); | 340 | ivtv_streams_cleanup(itv); |
350 | return -ENOMEM; | 341 | return -ENOMEM; |
351 | } | 342 | } |
352 | 343 | ||
353 | /* Unregister v4l2 devices */ | 344 | /* Unregister v4l2 devices */ |
354 | void ivtv_streams_cleanup(struct ivtv *itv, int unregister) | 345 | void ivtv_streams_cleanup(struct ivtv *itv) |
355 | { | 346 | { |
356 | int type; | 347 | int type; |
357 | 348 | ||
358 | /* Teardown all streams */ | 349 | /* Teardown all streams */ |
359 | for (type = 0; type < IVTV_MAX_STREAMS; type++) { | 350 | for (type = 0; type < IVTV_MAX_STREAMS; type++) { |
360 | struct video_device *vdev = itv->streams[type].vdev; | 351 | struct video_device *vdev = &itv->streams[type].vdev; |
361 | 352 | ||
362 | itv->streams[type].vdev = NULL; | 353 | if (vdev->v4l2_dev == NULL) |
363 | if (vdev == NULL) | ||
364 | continue; | 354 | continue; |
365 | 355 | ||
356 | video_unregister_device(vdev); | ||
366 | ivtv_stream_free(&itv->streams[type]); | 357 | ivtv_stream_free(&itv->streams[type]); |
367 | /* Unregister or release device */ | 358 | itv->streams[type].vdev.v4l2_dev = NULL; |
368 | if (unregister) | ||
369 | video_unregister_device(vdev); | ||
370 | else | ||
371 | video_device_release(vdev); | ||
372 | } | 359 | } |
373 | } | 360 | } |
374 | 361 | ||
@@ -492,7 +479,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s) | |||
492 | int captype = 0, subtype = 0; | 479 | int captype = 0, subtype = 0; |
493 | int enable_passthrough = 0; | 480 | int enable_passthrough = 0; |
494 | 481 | ||
495 | if (s->vdev == NULL) | 482 | if (s->vdev.v4l2_dev == NULL) |
496 | return -EINVAL; | 483 | return -EINVAL; |
497 | 484 | ||
498 | IVTV_DEBUG_INFO("Start encoder stream %s\n", s->name); | 485 | IVTV_DEBUG_INFO("Start encoder stream %s\n", s->name); |
@@ -661,7 +648,7 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s) | |||
661 | u16 width; | 648 | u16 width; |
662 | u16 height; | 649 | u16 height; |
663 | 650 | ||
664 | if (s->vdev == NULL) | 651 | if (s->vdev.v4l2_dev == NULL) |
665 | return -EINVAL; | 652 | return -EINVAL; |
666 | 653 | ||
667 | IVTV_DEBUG_INFO("Setting some initial decoder settings\n"); | 654 | IVTV_DEBUG_INFO("Setting some initial decoder settings\n"); |
@@ -723,7 +710,7 @@ int ivtv_start_v4l2_decode_stream(struct ivtv_stream *s, int gop_offset) | |||
723 | struct ivtv *itv = s->itv; | 710 | struct ivtv *itv = s->itv; |
724 | int rc; | 711 | int rc; |
725 | 712 | ||
726 | if (s->vdev == NULL) | 713 | if (s->vdev.v4l2_dev == NULL) |
727 | return -EINVAL; | 714 | return -EINVAL; |
728 | 715 | ||
729 | if (test_and_set_bit(IVTV_F_S_STREAMING, &s->s_flags)) | 716 | if (test_and_set_bit(IVTV_F_S_STREAMING, &s->s_flags)) |
@@ -778,7 +765,7 @@ void ivtv_stop_all_captures(struct ivtv *itv) | |||
778 | for (i = IVTV_MAX_STREAMS - 1; i >= 0; i--) { | 765 | for (i = IVTV_MAX_STREAMS - 1; i >= 0; i--) { |
779 | struct ivtv_stream *s = &itv->streams[i]; | 766 | struct ivtv_stream *s = &itv->streams[i]; |
780 | 767 | ||
781 | if (s->vdev == NULL) | 768 | if (s->vdev.v4l2_dev == NULL) |
782 | continue; | 769 | continue; |
783 | if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) { | 770 | if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) { |
784 | ivtv_stop_v4l2_encode_stream(s, 0); | 771 | ivtv_stop_v4l2_encode_stream(s, 0); |
@@ -793,7 +780,7 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end) | |||
793 | int cap_type; | 780 | int cap_type; |
794 | int stopmode; | 781 | int stopmode; |
795 | 782 | ||
796 | if (s->vdev == NULL) | 783 | if (s->vdev.v4l2_dev == NULL) |
797 | return -EINVAL; | 784 | return -EINVAL; |
798 | 785 | ||
799 | /* This function assumes that you are allowed to stop the capture | 786 | /* This function assumes that you are allowed to stop the capture |
@@ -917,7 +904,7 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts) | |||
917 | }; | 904 | }; |
918 | struct ivtv *itv = s->itv; | 905 | struct ivtv *itv = s->itv; |
919 | 906 | ||
920 | if (s->vdev == NULL) | 907 | if (s->vdev.v4l2_dev == NULL) |
921 | return -EINVAL; | 908 | return -EINVAL; |
922 | 909 | ||
923 | if (s->type != IVTV_DEC_STREAM_TYPE_YUV && s->type != IVTV_DEC_STREAM_TYPE_MPG) | 910 | if (s->type != IVTV_DEC_STREAM_TYPE_YUV && s->type != IVTV_DEC_STREAM_TYPE_MPG) |
@@ -969,7 +956,7 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts) | |||
969 | 956 | ||
970 | set_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags); | 957 | set_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags); |
971 | wake_up(&itv->event_waitq); | 958 | wake_up(&itv->event_waitq); |
972 | v4l2_event_queue(s->vdev, &ev); | 959 | v4l2_event_queue(&s->vdev, &ev); |
973 | 960 | ||
974 | /* wake up wait queues */ | 961 | /* wake up wait queues */ |
975 | wake_up(&s->waitq); | 962 | wake_up(&s->waitq); |
@@ -982,7 +969,7 @@ int ivtv_passthrough_mode(struct ivtv *itv, int enable) | |||
982 | struct ivtv_stream *yuv_stream = &itv->streams[IVTV_ENC_STREAM_TYPE_YUV]; | 969 | struct ivtv_stream *yuv_stream = &itv->streams[IVTV_ENC_STREAM_TYPE_YUV]; |
983 | struct ivtv_stream *dec_stream = &itv->streams[IVTV_DEC_STREAM_TYPE_YUV]; | 970 | struct ivtv_stream *dec_stream = &itv->streams[IVTV_DEC_STREAM_TYPE_YUV]; |
984 | 971 | ||
985 | if (yuv_stream->vdev == NULL || dec_stream->vdev == NULL) | 972 | if (yuv_stream->vdev.v4l2_dev == NULL || dec_stream->vdev.v4l2_dev == NULL) |
986 | return -EINVAL; | 973 | return -EINVAL; |
987 | 974 | ||
988 | IVTV_DEBUG_INFO("ivtv ioctl: Select passthrough mode\n"); | 975 | IVTV_DEBUG_INFO("ivtv ioctl: Select passthrough mode\n"); |
diff --git a/drivers/media/pci/ivtv/ivtv-streams.h b/drivers/media/pci/ivtv/ivtv-streams.h index a653a5136417..3d76a415fbd8 100644 --- a/drivers/media/pci/ivtv/ivtv-streams.h +++ b/drivers/media/pci/ivtv/ivtv-streams.h | |||
@@ -23,7 +23,7 @@ | |||
23 | 23 | ||
24 | int ivtv_streams_setup(struct ivtv *itv); | 24 | int ivtv_streams_setup(struct ivtv *itv); |
25 | int ivtv_streams_register(struct ivtv *itv); | 25 | int ivtv_streams_register(struct ivtv *itv); |
26 | void ivtv_streams_cleanup(struct ivtv *itv, int unregister); | 26 | void ivtv_streams_cleanup(struct ivtv *itv); |
27 | 27 | ||
28 | /* Capture related */ | 28 | /* Capture related */ |
29 | int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s); | 29 | int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s); |
diff --git a/drivers/media/pci/meye/meye.c b/drivers/media/pci/meye/meye.c index 9d9f90cb7740..ba887e8e1b17 100644 --- a/drivers/media/pci/meye/meye.c +++ b/drivers/media/pci/meye/meye.c | |||
@@ -1546,7 +1546,7 @@ static struct video_device meye_template = { | |||
1546 | .name = "meye", | 1546 | .name = "meye", |
1547 | .fops = &meye_fops, | 1547 | .fops = &meye_fops, |
1548 | .ioctl_ops = &meye_ioctl_ops, | 1548 | .ioctl_ops = &meye_ioctl_ops, |
1549 | .release = video_device_release, | 1549 | .release = video_device_release_empty, |
1550 | }; | 1550 | }; |
1551 | 1551 | ||
1552 | static const struct v4l2_ctrl_ops meye_ctrl_ops = { | 1552 | static const struct v4l2_ctrl_ops meye_ctrl_ops = { |
@@ -1623,7 +1623,7 @@ static int meye_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) | |||
1623 | 1623 | ||
1624 | if (meye.mchip_dev != NULL) { | 1624 | if (meye.mchip_dev != NULL) { |
1625 | printk(KERN_ERR "meye: only one device allowed!\n"); | 1625 | printk(KERN_ERR "meye: only one device allowed!\n"); |
1626 | goto outnotdev; | 1626 | return ret; |
1627 | } | 1627 | } |
1628 | 1628 | ||
1629 | ret = v4l2_device_register(&pcidev->dev, v4l2_dev); | 1629 | ret = v4l2_device_register(&pcidev->dev, v4l2_dev); |
@@ -1633,11 +1633,6 @@ static int meye_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) | |||
1633 | } | 1633 | } |
1634 | ret = -ENOMEM; | 1634 | ret = -ENOMEM; |
1635 | meye.mchip_dev = pcidev; | 1635 | meye.mchip_dev = pcidev; |
1636 | meye.vdev = video_device_alloc(); | ||
1637 | if (!meye.vdev) { | ||
1638 | v4l2_err(v4l2_dev, "video_device_alloc() failed!\n"); | ||
1639 | goto outnotdev; | ||
1640 | } | ||
1641 | 1636 | ||
1642 | meye.grab_temp = vmalloc(MCHIP_NB_PAGES_MJPEG * PAGE_SIZE); | 1637 | meye.grab_temp = vmalloc(MCHIP_NB_PAGES_MJPEG * PAGE_SIZE); |
1643 | if (!meye.grab_temp) { | 1638 | if (!meye.grab_temp) { |
@@ -1658,8 +1653,8 @@ static int meye_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) | |||
1658 | goto outkfifoalloc2; | 1653 | goto outkfifoalloc2; |
1659 | } | 1654 | } |
1660 | 1655 | ||
1661 | memcpy(meye.vdev, &meye_template, sizeof(meye_template)); | 1656 | meye.vdev = meye_template; |
1662 | meye.vdev->v4l2_dev = &meye.v4l2_dev; | 1657 | meye.vdev.v4l2_dev = &meye.v4l2_dev; |
1663 | 1658 | ||
1664 | ret = -EIO; | 1659 | ret = -EIO; |
1665 | if ((ret = sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 1))) { | 1660 | if ((ret = sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 1))) { |
@@ -1743,9 +1738,9 @@ static int meye_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) | |||
1743 | } | 1738 | } |
1744 | 1739 | ||
1745 | v4l2_ctrl_handler_setup(&meye.hdl); | 1740 | v4l2_ctrl_handler_setup(&meye.hdl); |
1746 | meye.vdev->ctrl_handler = &meye.hdl; | 1741 | meye.vdev.ctrl_handler = &meye.hdl; |
1747 | 1742 | ||
1748 | if (video_register_device(meye.vdev, VFL_TYPE_GRABBER, | 1743 | if (video_register_device(&meye.vdev, VFL_TYPE_GRABBER, |
1749 | video_nr) < 0) { | 1744 | video_nr) < 0) { |
1750 | v4l2_err(v4l2_dev, "video_register_device failed\n"); | 1745 | v4l2_err(v4l2_dev, "video_register_device failed\n"); |
1751 | goto outvideoreg; | 1746 | goto outvideoreg; |
@@ -1777,14 +1772,12 @@ outkfifoalloc2: | |||
1777 | outkfifoalloc1: | 1772 | outkfifoalloc1: |
1778 | vfree(meye.grab_temp); | 1773 | vfree(meye.grab_temp); |
1779 | outvmalloc: | 1774 | outvmalloc: |
1780 | video_device_release(meye.vdev); | ||
1781 | outnotdev: | ||
1782 | return ret; | 1775 | return ret; |
1783 | } | 1776 | } |
1784 | 1777 | ||
1785 | static void meye_remove(struct pci_dev *pcidev) | 1778 | static void meye_remove(struct pci_dev *pcidev) |
1786 | { | 1779 | { |
1787 | video_unregister_device(meye.vdev); | 1780 | video_unregister_device(&meye.vdev); |
1788 | 1781 | ||
1789 | mchip_hic_stop(); | 1782 | mchip_hic_stop(); |
1790 | 1783 | ||
diff --git a/drivers/media/pci/meye/meye.h b/drivers/media/pci/meye/meye.h index 6fed9274cfa5..751be5e533c7 100644 --- a/drivers/media/pci/meye/meye.h +++ b/drivers/media/pci/meye/meye.h | |||
@@ -311,7 +311,7 @@ struct meye { | |||
311 | struct kfifo doneq; /* queue for grabbed buffers */ | 311 | struct kfifo doneq; /* queue for grabbed buffers */ |
312 | spinlock_t doneq_lock; /* lock protecting the queue */ | 312 | spinlock_t doneq_lock; /* lock protecting the queue */ |
313 | wait_queue_head_t proc_list; /* wait queue */ | 313 | wait_queue_head_t proc_list; /* wait queue */ |
314 | struct video_device *vdev; /* video device parameters */ | 314 | struct video_device vdev; /* video device parameters */ |
315 | u16 brightness; | 315 | u16 brightness; |
316 | u16 hue; | 316 | u16 hue; |
317 | u16 contrast; | 317 | u16 contrast; |
diff --git a/drivers/media/pci/saa7146/hexium_gemini.c b/drivers/media/pci/saa7146/hexium_gemini.c index 366434f5647e..03cbcd2095c6 100644 --- a/drivers/media/pci/saa7146/hexium_gemini.c +++ b/drivers/media/pci/saa7146/hexium_gemini.c | |||
@@ -66,7 +66,7 @@ struct hexium | |||
66 | { | 66 | { |
67 | int type; | 67 | int type; |
68 | 68 | ||
69 | struct video_device *video_dev; | 69 | struct video_device video_dev; |
70 | struct i2c_adapter i2c_adapter; | 70 | struct i2c_adapter i2c_adapter; |
71 | 71 | ||
72 | int cur_input; /* current input */ | 72 | int cur_input; /* current input */ |
diff --git a/drivers/media/pci/saa7146/hexium_orion.c b/drivers/media/pci/saa7146/hexium_orion.c index a1eb26d11070..15f0d66ff78a 100644 --- a/drivers/media/pci/saa7146/hexium_orion.c +++ b/drivers/media/pci/saa7146/hexium_orion.c | |||
@@ -63,7 +63,7 @@ struct hexium_data | |||
63 | struct hexium | 63 | struct hexium |
64 | { | 64 | { |
65 | int type; | 65 | int type; |
66 | struct video_device *video_dev; | 66 | struct video_device video_dev; |
67 | struct i2c_adapter i2c_adapter; | 67 | struct i2c_adapter i2c_adapter; |
68 | 68 | ||
69 | int cur_input; /* current input */ | 69 | int cur_input; /* current input */ |
diff --git a/drivers/media/pci/saa7146/mxb.c b/drivers/media/pci/saa7146/mxb.c index c4c8fce8f2b4..0ca1e07ae783 100644 --- a/drivers/media/pci/saa7146/mxb.c +++ b/drivers/media/pci/saa7146/mxb.c | |||
@@ -151,8 +151,8 @@ static struct mxb_routing TEA6420_line[MXB_AUDIOS + 1][2] = { | |||
151 | 151 | ||
152 | struct mxb | 152 | struct mxb |
153 | { | 153 | { |
154 | struct video_device *video_dev; | 154 | struct video_device video_dev; |
155 | struct video_device *vbi_dev; | 155 | struct video_device vbi_dev; |
156 | 156 | ||
157 | struct i2c_adapter i2c_adapter; | 157 | struct i2c_adapter i2c_adapter; |
158 | 158 | ||
diff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c index 4b0bec3766ed..9cf3c6cba498 100644 --- a/drivers/media/pci/saa7164/saa7164-core.c +++ b/drivers/media/pci/saa7164/saa7164-core.c | |||
@@ -1436,11 +1436,11 @@ static void saa7164_finidev(struct pci_dev *pci_dev) | |||
1436 | saa7164_i2c_unregister(&dev->i2c_bus[1]); | 1436 | saa7164_i2c_unregister(&dev->i2c_bus[1]); |
1437 | saa7164_i2c_unregister(&dev->i2c_bus[2]); | 1437 | saa7164_i2c_unregister(&dev->i2c_bus[2]); |
1438 | 1438 | ||
1439 | pci_disable_device(pci_dev); | ||
1440 | |||
1441 | /* unregister stuff */ | 1439 | /* unregister stuff */ |
1442 | free_irq(pci_dev->irq, dev); | 1440 | free_irq(pci_dev->irq, dev); |
1443 | 1441 | ||
1442 | pci_disable_device(pci_dev); | ||
1443 | |||
1444 | mutex_lock(&devlist); | 1444 | mutex_lock(&devlist); |
1445 | list_del(&dev->devlist); | 1445 | list_del(&dev->devlist); |
1446 | mutex_unlock(&devlist); | 1446 | mutex_unlock(&devlist); |
diff --git a/drivers/media/pci/smipcie/Kconfig b/drivers/media/pci/smipcie/Kconfig index c8de53f5ea28..21a1583dbd8f 100644 --- a/drivers/media/pci/smipcie/Kconfig +++ b/drivers/media/pci/smipcie/Kconfig | |||
@@ -4,7 +4,7 @@ config DVB_SMIPCIE | |||
4 | select I2C_ALGOBIT | 4 | select I2C_ALGOBIT |
5 | select DVB_M88DS3103 if MEDIA_SUBDRV_AUTOSELECT | 5 | select DVB_M88DS3103 if MEDIA_SUBDRV_AUTOSELECT |
6 | select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT | 6 | select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT |
7 | select MEDIA_TUNER_M88TS2022 if MEDIA_SUBDRV_AUTOSELECT | 7 | select DVB_TS2020 if MEDIA_SUBDRV_AUTOSELECT |
8 | select MEDIA_TUNER_M88RS6000T if MEDIA_SUBDRV_AUTOSELECT | 8 | select MEDIA_TUNER_M88RS6000T if MEDIA_SUBDRV_AUTOSELECT |
9 | select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT | 9 | select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT |
10 | help | 10 | help |
diff --git a/drivers/media/pci/smipcie/smipcie.c b/drivers/media/pci/smipcie/smipcie.c index 36c8ed77309c..411592524c63 100644 --- a/drivers/media/pci/smipcie/smipcie.c +++ b/drivers/media/pci/smipcie/smipcie.c | |||
@@ -16,7 +16,7 @@ | |||
16 | 16 | ||
17 | #include "smipcie.h" | 17 | #include "smipcie.h" |
18 | #include "m88ds3103.h" | 18 | #include "m88ds3103.h" |
19 | #include "m88ts2022.h" | 19 | #include "ts2020.h" |
20 | #include "m88rs6000t.h" | 20 | #include "m88rs6000t.h" |
21 | #include "si2168.h" | 21 | #include "si2168.h" |
22 | #include "si2157.h" | 22 | #include "si2157.h" |
@@ -532,9 +532,7 @@ static int smi_dvbsky_m88ds3103_fe_attach(struct smi_port *port) | |||
532 | struct i2c_adapter *tuner_i2c_adapter; | 532 | struct i2c_adapter *tuner_i2c_adapter; |
533 | struct i2c_client *tuner_client; | 533 | struct i2c_client *tuner_client; |
534 | struct i2c_board_info tuner_info; | 534 | struct i2c_board_info tuner_info; |
535 | struct m88ts2022_config m88ts2022_config = { | 535 | struct ts2020_config ts2020_config = {}; |
536 | .clock = 27000000, | ||
537 | }; | ||
538 | memset(&tuner_info, 0, sizeof(struct i2c_board_info)); | 536 | memset(&tuner_info, 0, sizeof(struct i2c_board_info)); |
539 | i2c = (port->idx == 0) ? &dev->i2c_bus[0] : &dev->i2c_bus[1]; | 537 | i2c = (port->idx == 0) ? &dev->i2c_bus[0] : &dev->i2c_bus[1]; |
540 | 538 | ||
@@ -546,10 +544,10 @@ static int smi_dvbsky_m88ds3103_fe_attach(struct smi_port *port) | |||
546 | return ret; | 544 | return ret; |
547 | } | 545 | } |
548 | /* attach tuner */ | 546 | /* attach tuner */ |
549 | m88ts2022_config.fe = port->fe; | 547 | ts2020_config.fe = port->fe; |
550 | strlcpy(tuner_info.type, "m88ts2022", I2C_NAME_SIZE); | 548 | strlcpy(tuner_info.type, "ts2020", I2C_NAME_SIZE); |
551 | tuner_info.addr = 0x60; | 549 | tuner_info.addr = 0x60; |
552 | tuner_info.platform_data = &m88ts2022_config; | 550 | tuner_info.platform_data = &ts2020_config; |
553 | tuner_client = smi_add_i2c_client(tuner_i2c_adapter, &tuner_info); | 551 | tuner_client = smi_add_i2c_client(tuner_i2c_adapter, &tuner_info); |
554 | if (!tuner_client) { | 552 | if (!tuner_client) { |
555 | ret = -ENODEV; | 553 | ret = -ENODEV; |
diff --git a/drivers/media/pci/sta2x11/sta2x11_vip.c b/drivers/media/pci/sta2x11/sta2x11_vip.c index 22450f583da1..d384a6b0b09f 100644 --- a/drivers/media/pci/sta2x11/sta2x11_vip.c +++ b/drivers/media/pci/sta2x11/sta2x11_vip.c | |||
@@ -127,7 +127,7 @@ static inline struct vip_buffer *to_vip_buffer(struct vb2_buffer *vb2) | |||
127 | */ | 127 | */ |
128 | struct sta2x11_vip { | 128 | struct sta2x11_vip { |
129 | struct v4l2_device v4l2_dev; | 129 | struct v4l2_device v4l2_dev; |
130 | struct video_device *video_dev; | 130 | struct video_device video_dev; |
131 | struct pci_dev *pdev; | 131 | struct pci_dev *pdev; |
132 | struct i2c_adapter *adapter; | 132 | struct i2c_adapter *adapter; |
133 | unsigned int register_save_area[IRQ_COUNT + SAVE_COUNT + AUX_COUNT]; | 133 | unsigned int register_save_area[IRQ_COUNT + SAVE_COUNT + AUX_COUNT]; |
@@ -763,7 +763,7 @@ static const struct v4l2_ioctl_ops vip_ioctl_ops = { | |||
763 | 763 | ||
764 | static struct video_device video_dev_template = { | 764 | static struct video_device video_dev_template = { |
765 | .name = KBUILD_MODNAME, | 765 | .name = KBUILD_MODNAME, |
766 | .release = video_device_release, | 766 | .release = video_device_release_empty, |
767 | .fops = &vip_fops, | 767 | .fops = &vip_fops, |
768 | .ioctl_ops = &vip_ioctl_ops, | 768 | .ioctl_ops = &vip_ioctl_ops, |
769 | .tvnorms = V4L2_STD_ALL, | 769 | .tvnorms = V4L2_STD_ALL, |
@@ -1082,19 +1082,13 @@ static int sta2x11_vip_init_one(struct pci_dev *pdev, | |||
1082 | goto release_buf; | 1082 | goto release_buf; |
1083 | } | 1083 | } |
1084 | 1084 | ||
1085 | /* Alloc, initialize and register video device */ | 1085 | /* Initialize and register video device */ |
1086 | vip->video_dev = video_device_alloc(); | 1086 | vip->video_dev = video_dev_template; |
1087 | if (!vip->video_dev) { | 1087 | vip->video_dev.v4l2_dev = &vip->v4l2_dev; |
1088 | ret = -ENOMEM; | 1088 | vip->video_dev.queue = &vip->vb_vidq; |
1089 | goto release_irq; | 1089 | video_set_drvdata(&vip->video_dev, vip); |
1090 | } | ||
1091 | 1090 | ||
1092 | vip->video_dev = &video_dev_template; | 1091 | ret = video_register_device(&vip->video_dev, VFL_TYPE_GRABBER, -1); |
1093 | vip->video_dev->v4l2_dev = &vip->v4l2_dev; | ||
1094 | vip->video_dev->queue = &vip->vb_vidq; | ||
1095 | video_set_drvdata(vip->video_dev, vip); | ||
1096 | |||
1097 | ret = video_register_device(vip->video_dev, VFL_TYPE_GRABBER, -1); | ||
1098 | if (ret) | 1092 | if (ret) |
1099 | goto vrelease; | 1093 | goto vrelease; |
1100 | 1094 | ||
@@ -1124,13 +1118,9 @@ static int sta2x11_vip_init_one(struct pci_dev *pdev, | |||
1124 | return 0; | 1118 | return 0; |
1125 | 1119 | ||
1126 | vunreg: | 1120 | vunreg: |
1127 | video_set_drvdata(vip->video_dev, NULL); | 1121 | video_set_drvdata(&vip->video_dev, NULL); |
1128 | vrelease: | 1122 | vrelease: |
1129 | if (video_is_registered(vip->video_dev)) | 1123 | video_unregister_device(&vip->video_dev); |
1130 | video_unregister_device(vip->video_dev); | ||
1131 | else | ||
1132 | video_device_release(vip->video_dev); | ||
1133 | release_irq: | ||
1134 | free_irq(pdev->irq, vip); | 1124 | free_irq(pdev->irq, vip); |
1135 | release_buf: | 1125 | release_buf: |
1136 | sta2x11_vip_release_buffer(vip); | 1126 | sta2x11_vip_release_buffer(vip); |
@@ -1175,9 +1165,8 @@ static void sta2x11_vip_remove_one(struct pci_dev *pdev) | |||
1175 | 1165 | ||
1176 | sta2x11_vip_clear_register(vip); | 1166 | sta2x11_vip_clear_register(vip); |
1177 | 1167 | ||
1178 | video_set_drvdata(vip->video_dev, NULL); | 1168 | video_set_drvdata(&vip->video_dev, NULL); |
1179 | video_unregister_device(vip->video_dev); | 1169 | video_unregister_device(&vip->video_dev); |
1180 | /*do not call video_device_release() here, is already done */ | ||
1181 | free_irq(pdev->irq, vip); | 1170 | free_irq(pdev->irq, vip); |
1182 | pci_disable_msi(pdev); | 1171 | pci_disable_msi(pdev); |
1183 | vb2_queue_release(&vip->vb_vidq); | 1172 | vb2_queue_release(&vip->vb_vidq); |
diff --git a/drivers/media/pci/ttpci/av7110.h b/drivers/media/pci/ttpci/av7110.h index ef3d9606b269..835635b0c712 100644 --- a/drivers/media/pci/ttpci/av7110.h +++ b/drivers/media/pci/ttpci/av7110.h | |||
@@ -102,8 +102,8 @@ struct av7110 { | |||
102 | struct dvb_device dvb_dev; | 102 | struct dvb_device dvb_dev; |
103 | struct dvb_net dvb_net; | 103 | struct dvb_net dvb_net; |
104 | 104 | ||
105 | struct video_device *v4l_dev; | 105 | struct video_device v4l_dev; |
106 | struct video_device *vbi_dev; | 106 | struct video_device vbi_dev; |
107 | 107 | ||
108 | struct saa7146_dev *dev; | 108 | struct saa7146_dev *dev; |
109 | 109 | ||
diff --git a/drivers/media/pci/ttpci/budget-av.c b/drivers/media/pci/ttpci/budget-av.c index 0ba3875af22e..54c9910256f8 100644 --- a/drivers/media/pci/ttpci/budget-av.c +++ b/drivers/media/pci/ttpci/budget-av.c | |||
@@ -68,7 +68,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | |||
68 | 68 | ||
69 | struct budget_av { | 69 | struct budget_av { |
70 | struct budget budget; | 70 | struct budget budget; |
71 | struct video_device *vd; | 71 | struct video_device vd; |
72 | int cur_input; | 72 | int cur_input; |
73 | int has_saa7113; | 73 | int has_saa7113; |
74 | struct tasklet_struct ciintf_irq_tasklet; | 74 | struct tasklet_struct ciintf_irq_tasklet; |
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index d9b872b9285a..421f53188c6c 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig | |||
@@ -56,7 +56,7 @@ config VIDEO_VIU | |||
56 | 56 | ||
57 | config VIDEO_TIMBERDALE | 57 | config VIDEO_TIMBERDALE |
58 | tristate "Support for timberdale Video In/LogiWIN" | 58 | tristate "Support for timberdale Video In/LogiWIN" |
59 | depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API | 59 | depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API && HAS_DMA |
60 | depends on (MFD_TIMBERDALE && TIMB_DMA) || COMPILE_TEST | 60 | depends on (MFD_TIMBERDALE && TIMB_DMA) || COMPILE_TEST |
61 | select VIDEO_ADV7180 | 61 | select VIDEO_ADV7180 |
62 | select VIDEOBUF_DMA_CONTIG | 62 | select VIDEOBUF_DMA_CONTIG |
@@ -90,6 +90,7 @@ config VIDEO_OMAP3 | |||
90 | select ARM_DMA_USE_IOMMU | 90 | select ARM_DMA_USE_IOMMU |
91 | select OMAP_IOMMU | 91 | select OMAP_IOMMU |
92 | select VIDEOBUF2_DMA_CONTIG | 92 | select VIDEOBUF2_DMA_CONTIG |
93 | select MFD_SYSCON | ||
93 | ---help--- | 94 | ---help--- |
94 | Driver for an OMAP 3 camera controller. | 95 | Driver for an OMAP 3 camera controller. |
95 | 96 | ||
@@ -117,6 +118,7 @@ source "drivers/media/platform/soc_camera/Kconfig" | |||
117 | source "drivers/media/platform/exynos4-is/Kconfig" | 118 | source "drivers/media/platform/exynos4-is/Kconfig" |
118 | source "drivers/media/platform/s5p-tv/Kconfig" | 119 | source "drivers/media/platform/s5p-tv/Kconfig" |
119 | source "drivers/media/platform/am437x/Kconfig" | 120 | source "drivers/media/platform/am437x/Kconfig" |
121 | source "drivers/media/platform/xilinx/Kconfig" | ||
120 | 122 | ||
121 | endif # V4L_PLATFORM_DRIVERS | 123 | endif # V4L_PLATFORM_DRIVERS |
122 | 124 | ||
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile index 3ec154742083..8f855616c237 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile | |||
@@ -48,4 +48,6 @@ obj-y += omap/ | |||
48 | 48 | ||
49 | obj-$(CONFIG_VIDEO_AM437X_VPFE) += am437x/ | 49 | obj-$(CONFIG_VIDEO_AM437X_VPFE) += am437x/ |
50 | 50 | ||
51 | obj-$(CONFIG_VIDEO_XILINX) += xilinx/ | ||
52 | |||
51 | ccflags-y += -I$(srctree)/drivers/media/i2c | 53 | ccflags-y += -I$(srctree)/drivers/media/i2c |
diff --git a/drivers/media/platform/am437x/Kconfig b/drivers/media/platform/am437x/Kconfig index 7b023a76e32e..42d9c186710a 100644 --- a/drivers/media/platform/am437x/Kconfig +++ b/drivers/media/platform/am437x/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config VIDEO_AM437X_VPFE | 1 | config VIDEO_AM437X_VPFE |
2 | tristate "TI AM437x VPFE video capture driver" | 2 | tristate "TI AM437x VPFE video capture driver" |
3 | depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API | 3 | depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && HAS_DMA |
4 | depends on SOC_AM43XX || COMPILE_TEST | 4 | depends on SOC_AM43XX || COMPILE_TEST |
5 | select VIDEOBUF2_DMA_CONTIG | 5 | select VIDEOBUF2_DMA_CONTIG |
6 | help | 6 | help |
diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c index 0d07fca756fe..a30cc2f7e4f1 100644 --- a/drivers/media/platform/am437x/am437x-vpfe.c +++ b/drivers/media/platform/am437x/am437x-vpfe.c | |||
@@ -1645,6 +1645,7 @@ static int vpfe_enum_size(struct file *file, void *priv, | |||
1645 | fse.index = fsize->index; | 1645 | fse.index = fsize->index; |
1646 | fse.pad = 0; | 1646 | fse.pad = 0; |
1647 | fse.code = mbus.code; | 1647 | fse.code = mbus.code; |
1648 | fse.which = V4L2_SUBDEV_FORMAT_ACTIVE; | ||
1648 | ret = v4l2_subdev_call(sdinfo->sd, pad, enum_frame_size, NULL, &fse); | 1649 | ret = v4l2_subdev_call(sdinfo->sd, pad, enum_frame_size, NULL, &fse); |
1649 | if (ret) | 1650 | if (ret) |
1650 | return -EINVAL; | 1651 | return -EINVAL; |
@@ -1700,11 +1701,16 @@ static int vpfe_get_app_input_index(struct vpfe_device *vpfe, | |||
1700 | { | 1701 | { |
1701 | struct vpfe_config *cfg = vpfe->cfg; | 1702 | struct vpfe_config *cfg = vpfe->cfg; |
1702 | struct vpfe_subdev_info *sdinfo; | 1703 | struct vpfe_subdev_info *sdinfo; |
1704 | struct i2c_client *client; | ||
1705 | struct i2c_client *curr_client; | ||
1703 | int i, j = 0; | 1706 | int i, j = 0; |
1704 | 1707 | ||
1708 | curr_client = v4l2_get_subdevdata(vpfe->current_subdev->sd); | ||
1705 | for (i = 0; i < ARRAY_SIZE(vpfe->cfg->asd); i++) { | 1709 | for (i = 0; i < ARRAY_SIZE(vpfe->cfg->asd); i++) { |
1706 | sdinfo = &cfg->sub_devs[i]; | 1710 | sdinfo = &cfg->sub_devs[i]; |
1707 | if (!strcmp(sdinfo->name, vpfe->current_subdev->name)) { | 1711 | client = v4l2_get_subdevdata(sdinfo->sd); |
1712 | if (client->addr == curr_client->addr && | ||
1713 | client->adapter->nr == client->adapter->nr) { | ||
1708 | if (vpfe->current_input >= 1) | 1714 | if (vpfe->current_input >= 1) |
1709 | return -1; | 1715 | return -1; |
1710 | *app_input_index = j + vpfe->current_input; | 1716 | *app_input_index = j + vpfe->current_input; |
@@ -2296,20 +2302,10 @@ vpfe_async_bound(struct v4l2_async_notifier *notifier, | |||
2296 | vpfe_dbg(1, vpfe, "vpfe_async_bound\n"); | 2302 | vpfe_dbg(1, vpfe, "vpfe_async_bound\n"); |
2297 | 2303 | ||
2298 | for (i = 0; i < ARRAY_SIZE(vpfe->cfg->asd); i++) { | 2304 | for (i = 0; i < ARRAY_SIZE(vpfe->cfg->asd); i++) { |
2299 | sdinfo = &vpfe->cfg->sub_devs[i]; | 2305 | if (vpfe->cfg->asd[i]->match.of.node == asd[i].match.of.node) { |
2300 | 2306 | sdinfo = &vpfe->cfg->sub_devs[i]; | |
2301 | if (!strcmp(sdinfo->name, subdev->name)) { | ||
2302 | vpfe->sd[i] = subdev; | 2307 | vpfe->sd[i] = subdev; |
2303 | vpfe_info(vpfe, | 2308 | vpfe->sd[i]->grp_id = sdinfo->grp_id; |
2304 | "v4l2 sub device %s registered\n", | ||
2305 | subdev->name); | ||
2306 | vpfe->sd[i]->grp_id = | ||
2307 | sdinfo->grp_id; | ||
2308 | /* update tvnorms from the sub devices */ | ||
2309 | for (j = 0; j < 1; j++) | ||
2310 | vpfe->video_dev->tvnorms |= | ||
2311 | sdinfo->inputs[j].std; | ||
2312 | |||
2313 | found = true; | 2309 | found = true; |
2314 | break; | 2310 | break; |
2315 | } | 2311 | } |
@@ -2320,6 +2316,8 @@ vpfe_async_bound(struct v4l2_async_notifier *notifier, | |||
2320 | return -EINVAL; | 2316 | return -EINVAL; |
2321 | } | 2317 | } |
2322 | 2318 | ||
2319 | vpfe->video_dev.tvnorms |= sdinfo->inputs[0].std; | ||
2320 | |||
2323 | /* setup the supported formats & indexes */ | 2321 | /* setup the supported formats & indexes */ |
2324 | for (j = 0, i = 0; ; ++j) { | 2322 | for (j = 0, i = 0; ; ++j) { |
2325 | struct vpfe_fmt *fmt; | 2323 | struct vpfe_fmt *fmt; |
@@ -2327,6 +2325,7 @@ vpfe_async_bound(struct v4l2_async_notifier *notifier, | |||
2327 | 2325 | ||
2328 | memset(&mbus_code, 0, sizeof(mbus_code)); | 2326 | memset(&mbus_code, 0, sizeof(mbus_code)); |
2329 | mbus_code.index = j; | 2327 | mbus_code.index = j; |
2328 | mbus_code.which = V4L2_SUBDEV_FORMAT_ACTIVE; | ||
2330 | ret = v4l2_subdev_call(subdev, pad, enum_mbus_code, | 2329 | ret = v4l2_subdev_call(subdev, pad, enum_mbus_code, |
2331 | NULL, &mbus_code); | 2330 | NULL, &mbus_code); |
2332 | if (ret) | 2331 | if (ret) |
@@ -2390,9 +2389,9 @@ static int vpfe_probe_complete(struct vpfe_device *vpfe) | |||
2390 | 2389 | ||
2391 | INIT_LIST_HEAD(&vpfe->dma_queue); | 2390 | INIT_LIST_HEAD(&vpfe->dma_queue); |
2392 | 2391 | ||
2393 | vdev = vpfe->video_dev; | 2392 | vdev = &vpfe->video_dev; |
2394 | strlcpy(vdev->name, VPFE_MODULE_NAME, sizeof(vdev->name)); | 2393 | strlcpy(vdev->name, VPFE_MODULE_NAME, sizeof(vdev->name)); |
2395 | vdev->release = video_device_release; | 2394 | vdev->release = video_device_release_empty; |
2396 | vdev->fops = &vpfe_fops; | 2395 | vdev->fops = &vpfe_fops; |
2397 | vdev->ioctl_ops = &vpfe_ioctl_ops; | 2396 | vdev->ioctl_ops = &vpfe_ioctl_ops; |
2398 | vdev->v4l2_dev = &vpfe->v4l2_dev; | 2397 | vdev->v4l2_dev = &vpfe->v4l2_dev; |
@@ -2400,7 +2399,7 @@ static int vpfe_probe_complete(struct vpfe_device *vpfe) | |||
2400 | vdev->queue = q; | 2399 | vdev->queue = q; |
2401 | vdev->lock = &vpfe->lock; | 2400 | vdev->lock = &vpfe->lock; |
2402 | video_set_drvdata(vdev, vpfe); | 2401 | video_set_drvdata(vdev, vpfe); |
2403 | err = video_register_device(vpfe->video_dev, VFL_TYPE_GRABBER, -1); | 2402 | err = video_register_device(&vpfe->video_dev, VFL_TYPE_GRABBER, -1); |
2404 | if (err) { | 2403 | if (err) { |
2405 | vpfe_err(vpfe, | 2404 | vpfe_err(vpfe, |
2406 | "Unable to register video device.\n"); | 2405 | "Unable to register video device.\n"); |
@@ -2425,7 +2424,7 @@ static int vpfe_async_complete(struct v4l2_async_notifier *notifier) | |||
2425 | static struct vpfe_config * | 2424 | static struct vpfe_config * |
2426 | vpfe_get_pdata(struct platform_device *pdev) | 2425 | vpfe_get_pdata(struct platform_device *pdev) |
2427 | { | 2426 | { |
2428 | struct device_node *endpoint = NULL, *rem = NULL; | 2427 | struct device_node *endpoint = NULL; |
2429 | struct v4l2_of_endpoint bus_cfg; | 2428 | struct v4l2_of_endpoint bus_cfg; |
2430 | struct vpfe_subdev_info *sdinfo; | 2429 | struct vpfe_subdev_info *sdinfo; |
2431 | struct vpfe_config *pdata; | 2430 | struct vpfe_config *pdata; |
@@ -2443,6 +2442,8 @@ vpfe_get_pdata(struct platform_device *pdev) | |||
2443 | return NULL; | 2442 | return NULL; |
2444 | 2443 | ||
2445 | for (i = 0; ; i++) { | 2444 | for (i = 0; ; i++) { |
2445 | struct device_node *rem; | ||
2446 | |||
2446 | endpoint = of_graph_get_next_endpoint(pdev->dev.of_node, | 2447 | endpoint = of_graph_get_next_endpoint(pdev->dev.of_node, |
2447 | endpoint); | 2448 | endpoint); |
2448 | if (!endpoint) | 2449 | if (!endpoint) |
@@ -2497,11 +2498,15 @@ vpfe_get_pdata(struct platform_device *pdev) | |||
2497 | goto done; | 2498 | goto done; |
2498 | } | 2499 | } |
2499 | 2500 | ||
2500 | strncpy(sdinfo->name, rem->name, sizeof(sdinfo->name)); | ||
2501 | |||
2502 | pdata->asd[i] = devm_kzalloc(&pdev->dev, | 2501 | pdata->asd[i] = devm_kzalloc(&pdev->dev, |
2503 | sizeof(struct v4l2_async_subdev), | 2502 | sizeof(struct v4l2_async_subdev), |
2504 | GFP_KERNEL); | 2503 | GFP_KERNEL); |
2504 | if (!pdata->asd[i]) { | ||
2505 | of_node_put(rem); | ||
2506 | pdata = NULL; | ||
2507 | goto done; | ||
2508 | } | ||
2509 | |||
2505 | pdata->asd[i]->match_type = V4L2_ASYNC_MATCH_OF; | 2510 | pdata->asd[i]->match_type = V4L2_ASYNC_MATCH_OF; |
2506 | pdata->asd[i]->match.of.node = rem; | 2511 | pdata->asd[i]->match.of.node = rem; |
2507 | of_node_put(rem); | 2512 | of_node_put(rem); |
@@ -2512,7 +2517,6 @@ vpfe_get_pdata(struct platform_device *pdev) | |||
2512 | 2517 | ||
2513 | done: | 2518 | done: |
2514 | of_node_put(endpoint); | 2519 | of_node_put(endpoint); |
2515 | of_node_put(rem); | ||
2516 | return NULL; | 2520 | return NULL; |
2517 | } | 2521 | } |
2518 | 2522 | ||
@@ -2560,17 +2564,11 @@ static int vpfe_probe(struct platform_device *pdev) | |||
2560 | return -EINVAL; | 2564 | return -EINVAL; |
2561 | } | 2565 | } |
2562 | 2566 | ||
2563 | vpfe->video_dev = video_device_alloc(); | ||
2564 | if (!vpfe->video_dev) { | ||
2565 | dev_err(&pdev->dev, "Unable to allocate video device\n"); | ||
2566 | return -ENOMEM; | ||
2567 | } | ||
2568 | |||
2569 | ret = v4l2_device_register(&pdev->dev, &vpfe->v4l2_dev); | 2567 | ret = v4l2_device_register(&pdev->dev, &vpfe->v4l2_dev); |
2570 | if (ret) { | 2568 | if (ret) { |
2571 | vpfe_err(vpfe, | 2569 | vpfe_err(vpfe, |
2572 | "Unable to register v4l2 device.\n"); | 2570 | "Unable to register v4l2 device.\n"); |
2573 | goto probe_out_video_release; | 2571 | return ret; |
2574 | } | 2572 | } |
2575 | 2573 | ||
2576 | /* set the driver data in platform device */ | 2574 | /* set the driver data in platform device */ |
@@ -2608,9 +2606,6 @@ static int vpfe_probe(struct platform_device *pdev) | |||
2608 | 2606 | ||
2609 | probe_out_v4l2_unregister: | 2607 | probe_out_v4l2_unregister: |
2610 | v4l2_device_unregister(&vpfe->v4l2_dev); | 2608 | v4l2_device_unregister(&vpfe->v4l2_dev); |
2611 | probe_out_video_release: | ||
2612 | if (!video_is_registered(vpfe->video_dev)) | ||
2613 | video_device_release(vpfe->video_dev); | ||
2614 | return ret; | 2609 | return ret; |
2615 | } | 2610 | } |
2616 | 2611 | ||
@@ -2627,7 +2622,7 @@ static int vpfe_remove(struct platform_device *pdev) | |||
2627 | 2622 | ||
2628 | v4l2_async_notifier_unregister(&vpfe->notifier); | 2623 | v4l2_async_notifier_unregister(&vpfe->notifier); |
2629 | v4l2_device_unregister(&vpfe->v4l2_dev); | 2624 | v4l2_device_unregister(&vpfe->v4l2_dev); |
2630 | video_unregister_device(vpfe->video_dev); | 2625 | video_unregister_device(&vpfe->video_dev); |
2631 | 2626 | ||
2632 | return 0; | 2627 | return 0; |
2633 | } | 2628 | } |
diff --git a/drivers/media/platform/am437x/am437x-vpfe.h b/drivers/media/platform/am437x/am437x-vpfe.h index 0f557352313d..5bfb35649a39 100644 --- a/drivers/media/platform/am437x/am437x-vpfe.h +++ b/drivers/media/platform/am437x/am437x-vpfe.h | |||
@@ -83,7 +83,6 @@ struct vpfe_route { | |||
83 | }; | 83 | }; |
84 | 84 | ||
85 | struct vpfe_subdev_info { | 85 | struct vpfe_subdev_info { |
86 | char name[32]; | ||
87 | /* Sub device group id */ | 86 | /* Sub device group id */ |
88 | int grp_id; | 87 | int grp_id; |
89 | /* inputs available at the sub device */ | 88 | /* inputs available at the sub device */ |
@@ -223,7 +222,7 @@ struct vpfe_ccdc { | |||
223 | struct vpfe_device { | 222 | struct vpfe_device { |
224 | /* V4l2 specific parameters */ | 223 | /* V4l2 specific parameters */ |
225 | /* Identifies video device for this channel */ | 224 | /* Identifies video device for this channel */ |
226 | struct video_device *video_dev; | 225 | struct video_device video_dev; |
227 | /* sub devices */ | 226 | /* sub devices */ |
228 | struct v4l2_subdev **sd; | 227 | struct v4l2_subdev **sd; |
229 | /* vpfe cfg */ | 228 | /* vpfe cfg */ |
diff --git a/drivers/media/platform/blackfin/bfin_capture.c b/drivers/media/platform/blackfin/bfin_capture.c index 8f6698668ecf..6a437f86dcdc 100644 --- a/drivers/media/platform/blackfin/bfin_capture.c +++ b/drivers/media/platform/blackfin/bfin_capture.c | |||
@@ -44,7 +44,6 @@ | |||
44 | #include <media/blackfin/ppi.h> | 44 | #include <media/blackfin/ppi.h> |
45 | 45 | ||
46 | #define CAPTURE_DRV_NAME "bfin_capture" | 46 | #define CAPTURE_DRV_NAME "bfin_capture" |
47 | #define BCAP_MIN_NUM_BUF 2 | ||
48 | 47 | ||
49 | struct bcap_format { | 48 | struct bcap_format { |
50 | char *desc; | 49 | char *desc; |
@@ -65,7 +64,7 @@ struct bcap_device { | |||
65 | /* v4l2 control handler */ | 64 | /* v4l2 control handler */ |
66 | struct v4l2_ctrl_handler ctrl_handler; | 65 | struct v4l2_ctrl_handler ctrl_handler; |
67 | /* device node data */ | 66 | /* device node data */ |
68 | struct video_device *video_dev; | 67 | struct video_device video_dev; |
69 | /* sub device instance */ | 68 | /* sub device instance */ |
70 | struct v4l2_subdev *sd; | 69 | struct v4l2_subdev *sd; |
71 | /* capture config */ | 70 | /* capture config */ |
@@ -104,12 +103,8 @@ struct bcap_device { | |||
104 | struct completion comp; | 103 | struct completion comp; |
105 | /* prepare to stop */ | 104 | /* prepare to stop */ |
106 | bool stop; | 105 | bool stop; |
107 | }; | 106 | /* vb2 buffer sequence counter */ |
108 | 107 | unsigned sequence; | |
109 | struct bcap_fh { | ||
110 | struct v4l2_fh fh; | ||
111 | /* indicates whether this file handle is doing IO */ | ||
112 | bool io_allowed; | ||
113 | }; | 108 | }; |
114 | 109 | ||
115 | static const struct bcap_format bcap_formats[] = { | 110 | static const struct bcap_format bcap_formats[] = { |
@@ -201,90 +196,6 @@ static void bcap_free_sensor_formats(struct bcap_device *bcap_dev) | |||
201 | bcap_dev->sensor_formats = NULL; | 196 | bcap_dev->sensor_formats = NULL; |
202 | } | 197 | } |
203 | 198 | ||
204 | static int bcap_open(struct file *file) | ||
205 | { | ||
206 | struct bcap_device *bcap_dev = video_drvdata(file); | ||
207 | struct video_device *vfd = bcap_dev->video_dev; | ||
208 | struct bcap_fh *bcap_fh; | ||
209 | |||
210 | if (!bcap_dev->sd) { | ||
211 | v4l2_err(&bcap_dev->v4l2_dev, "No sub device registered\n"); | ||
212 | return -ENODEV; | ||
213 | } | ||
214 | |||
215 | bcap_fh = kzalloc(sizeof(*bcap_fh), GFP_KERNEL); | ||
216 | if (!bcap_fh) { | ||
217 | v4l2_err(&bcap_dev->v4l2_dev, | ||
218 | "unable to allocate memory for file handle object\n"); | ||
219 | return -ENOMEM; | ||
220 | } | ||
221 | |||
222 | v4l2_fh_init(&bcap_fh->fh, vfd); | ||
223 | |||
224 | /* store pointer to v4l2_fh in private_data member of file */ | ||
225 | file->private_data = &bcap_fh->fh; | ||
226 | v4l2_fh_add(&bcap_fh->fh); | ||
227 | bcap_fh->io_allowed = false; | ||
228 | return 0; | ||
229 | } | ||
230 | |||
231 | static int bcap_release(struct file *file) | ||
232 | { | ||
233 | struct bcap_device *bcap_dev = video_drvdata(file); | ||
234 | struct v4l2_fh *fh = file->private_data; | ||
235 | struct bcap_fh *bcap_fh = container_of(fh, struct bcap_fh, fh); | ||
236 | |||
237 | /* if this instance is doing IO */ | ||
238 | if (bcap_fh->io_allowed) | ||
239 | vb2_queue_release(&bcap_dev->buffer_queue); | ||
240 | |||
241 | file->private_data = NULL; | ||
242 | v4l2_fh_del(&bcap_fh->fh); | ||
243 | v4l2_fh_exit(&bcap_fh->fh); | ||
244 | kfree(bcap_fh); | ||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | static int bcap_mmap(struct file *file, struct vm_area_struct *vma) | ||
249 | { | ||
250 | struct bcap_device *bcap_dev = video_drvdata(file); | ||
251 | int ret; | ||
252 | |||
253 | if (mutex_lock_interruptible(&bcap_dev->mutex)) | ||
254 | return -ERESTARTSYS; | ||
255 | ret = vb2_mmap(&bcap_dev->buffer_queue, vma); | ||
256 | mutex_unlock(&bcap_dev->mutex); | ||
257 | return ret; | ||
258 | } | ||
259 | |||
260 | #ifndef CONFIG_MMU | ||
261 | static unsigned long bcap_get_unmapped_area(struct file *file, | ||
262 | unsigned long addr, | ||
263 | unsigned long len, | ||
264 | unsigned long pgoff, | ||
265 | unsigned long flags) | ||
266 | { | ||
267 | struct bcap_device *bcap_dev = video_drvdata(file); | ||
268 | |||
269 | return vb2_get_unmapped_area(&bcap_dev->buffer_queue, | ||
270 | addr, | ||
271 | len, | ||
272 | pgoff, | ||
273 | flags); | ||
274 | } | ||
275 | #endif | ||
276 | |||
277 | static unsigned int bcap_poll(struct file *file, poll_table *wait) | ||
278 | { | ||
279 | struct bcap_device *bcap_dev = video_drvdata(file); | ||
280 | unsigned int res; | ||
281 | |||
282 | mutex_lock(&bcap_dev->mutex); | ||
283 | res = vb2_poll(&bcap_dev->buffer_queue, file, wait); | ||
284 | mutex_unlock(&bcap_dev->mutex); | ||
285 | return res; | ||
286 | } | ||
287 | |||
288 | static int bcap_queue_setup(struct vb2_queue *vq, | 199 | static int bcap_queue_setup(struct vb2_queue *vq, |
289 | const struct v4l2_format *fmt, | 200 | const struct v4l2_format *fmt, |
290 | unsigned int *nbuffers, unsigned int *nplanes, | 201 | unsigned int *nbuffers, unsigned int *nplanes, |
@@ -292,37 +203,32 @@ static int bcap_queue_setup(struct vb2_queue *vq, | |||
292 | { | 203 | { |
293 | struct bcap_device *bcap_dev = vb2_get_drv_priv(vq); | 204 | struct bcap_device *bcap_dev = vb2_get_drv_priv(vq); |
294 | 205 | ||
295 | if (*nbuffers < BCAP_MIN_NUM_BUF) | 206 | if (fmt && fmt->fmt.pix.sizeimage < bcap_dev->fmt.sizeimage) |
296 | *nbuffers = BCAP_MIN_NUM_BUF; | 207 | return -EINVAL; |
208 | |||
209 | if (vq->num_buffers + *nbuffers < 2) | ||
210 | *nbuffers = 2; | ||
297 | 211 | ||
298 | *nplanes = 1; | 212 | *nplanes = 1; |
299 | sizes[0] = bcap_dev->fmt.sizeimage; | 213 | sizes[0] = fmt ? fmt->fmt.pix.sizeimage : bcap_dev->fmt.sizeimage; |
300 | alloc_ctxs[0] = bcap_dev->alloc_ctx; | 214 | alloc_ctxs[0] = bcap_dev->alloc_ctx; |
301 | 215 | ||
302 | return 0; | 216 | return 0; |
303 | } | 217 | } |
304 | 218 | ||
305 | static int bcap_buffer_init(struct vb2_buffer *vb) | ||
306 | { | ||
307 | struct bcap_buffer *buf = to_bcap_vb(vb); | ||
308 | |||
309 | INIT_LIST_HEAD(&buf->list); | ||
310 | return 0; | ||
311 | } | ||
312 | |||
313 | static int bcap_buffer_prepare(struct vb2_buffer *vb) | 219 | static int bcap_buffer_prepare(struct vb2_buffer *vb) |
314 | { | 220 | { |
315 | struct bcap_device *bcap_dev = vb2_get_drv_priv(vb->vb2_queue); | 221 | struct bcap_device *bcap_dev = vb2_get_drv_priv(vb->vb2_queue); |
316 | struct bcap_buffer *buf = to_bcap_vb(vb); | 222 | unsigned long size = bcap_dev->fmt.sizeimage; |
317 | unsigned long size; | ||
318 | 223 | ||
319 | size = bcap_dev->fmt.sizeimage; | ||
320 | if (vb2_plane_size(vb, 0) < size) { | 224 | if (vb2_plane_size(vb, 0) < size) { |
321 | v4l2_err(&bcap_dev->v4l2_dev, "buffer too small (%lu < %lu)\n", | 225 | v4l2_err(&bcap_dev->v4l2_dev, "buffer too small (%lu < %lu)\n", |
322 | vb2_plane_size(vb, 0), size); | 226 | vb2_plane_size(vb, 0), size); |
323 | return -EINVAL; | 227 | return -EINVAL; |
324 | } | 228 | } |
325 | vb2_set_plane_payload(&buf->vb, 0, size); | 229 | vb2_set_plane_payload(vb, 0, size); |
230 | |||
231 | vb->v4l2_buf.field = bcap_dev->fmt.field; | ||
326 | 232 | ||
327 | return 0; | 233 | return 0; |
328 | } | 234 | } |
@@ -353,14 +259,16 @@ static int bcap_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
353 | { | 259 | { |
354 | struct bcap_device *bcap_dev = vb2_get_drv_priv(vq); | 260 | struct bcap_device *bcap_dev = vb2_get_drv_priv(vq); |
355 | struct ppi_if *ppi = bcap_dev->ppi; | 261 | struct ppi_if *ppi = bcap_dev->ppi; |
262 | struct bcap_buffer *buf, *tmp; | ||
356 | struct ppi_params params; | 263 | struct ppi_params params; |
264 | dma_addr_t addr; | ||
357 | int ret; | 265 | int ret; |
358 | 266 | ||
359 | /* enable streamon on the sub device */ | 267 | /* enable streamon on the sub device */ |
360 | ret = v4l2_subdev_call(bcap_dev->sd, video, s_stream, 1); | 268 | ret = v4l2_subdev_call(bcap_dev->sd, video, s_stream, 1); |
361 | if (ret && (ret != -ENOIOCTLCMD)) { | 269 | if (ret && (ret != -ENOIOCTLCMD)) { |
362 | v4l2_err(&bcap_dev->v4l2_dev, "stream on failed in subdev\n"); | 270 | v4l2_err(&bcap_dev->v4l2_dev, "stream on failed in subdev\n"); |
363 | return ret; | 271 | goto err; |
364 | } | 272 | } |
365 | 273 | ||
366 | /* set ppi params */ | 274 | /* set ppi params */ |
@@ -399,7 +307,7 @@ static int bcap_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
399 | if (ret < 0) { | 307 | if (ret < 0) { |
400 | v4l2_err(&bcap_dev->v4l2_dev, | 308 | v4l2_err(&bcap_dev->v4l2_dev, |
401 | "Error in setting ppi params\n"); | 309 | "Error in setting ppi params\n"); |
402 | return ret; | 310 | goto err; |
403 | } | 311 | } |
404 | 312 | ||
405 | /* attach ppi DMA irq handler */ | 313 | /* attach ppi DMA irq handler */ |
@@ -407,12 +315,34 @@ static int bcap_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
407 | if (ret < 0) { | 315 | if (ret < 0) { |
408 | v4l2_err(&bcap_dev->v4l2_dev, | 316 | v4l2_err(&bcap_dev->v4l2_dev, |
409 | "Error in attaching interrupt handler\n"); | 317 | "Error in attaching interrupt handler\n"); |
410 | return ret; | 318 | goto err; |
411 | } | 319 | } |
412 | 320 | ||
321 | bcap_dev->sequence = 0; | ||
322 | |||
413 | reinit_completion(&bcap_dev->comp); | 323 | reinit_completion(&bcap_dev->comp); |
414 | bcap_dev->stop = false; | 324 | bcap_dev->stop = false; |
325 | |||
326 | /* get the next frame from the dma queue */ | ||
327 | bcap_dev->cur_frm = list_entry(bcap_dev->dma_queue.next, | ||
328 | struct bcap_buffer, list); | ||
329 | /* remove buffer from the dma queue */ | ||
330 | list_del_init(&bcap_dev->cur_frm->list); | ||
331 | addr = vb2_dma_contig_plane_dma_addr(&bcap_dev->cur_frm->vb, 0); | ||
332 | /* update DMA address */ | ||
333 | ppi->ops->update_addr(ppi, (unsigned long)addr); | ||
334 | /* enable ppi */ | ||
335 | ppi->ops->start(ppi); | ||
336 | |||
415 | return 0; | 337 | return 0; |
338 | |||
339 | err: | ||
340 | list_for_each_entry_safe(buf, tmp, &bcap_dev->dma_queue, list) { | ||
341 | list_del(&buf->list); | ||
342 | vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED); | ||
343 | } | ||
344 | |||
345 | return ret; | ||
416 | } | 346 | } |
417 | 347 | ||
418 | static void bcap_stop_streaming(struct vb2_queue *vq) | 348 | static void bcap_stop_streaming(struct vb2_queue *vq) |
@@ -431,6 +361,9 @@ static void bcap_stop_streaming(struct vb2_queue *vq) | |||
431 | "stream off failed in subdev\n"); | 361 | "stream off failed in subdev\n"); |
432 | 362 | ||
433 | /* release all active buffers */ | 363 | /* release all active buffers */ |
364 | if (bcap_dev->cur_frm) | ||
365 | vb2_buffer_done(&bcap_dev->cur_frm->vb, VB2_BUF_STATE_ERROR); | ||
366 | |||
434 | while (!list_empty(&bcap_dev->dma_queue)) { | 367 | while (!list_empty(&bcap_dev->dma_queue)) { |
435 | bcap_dev->cur_frm = list_entry(bcap_dev->dma_queue.next, | 368 | bcap_dev->cur_frm = list_entry(bcap_dev->dma_queue.next, |
436 | struct bcap_buffer, list); | 369 | struct bcap_buffer, list); |
@@ -441,7 +374,6 @@ static void bcap_stop_streaming(struct vb2_queue *vq) | |||
441 | 374 | ||
442 | static struct vb2_ops bcap_video_qops = { | 375 | static struct vb2_ops bcap_video_qops = { |
443 | .queue_setup = bcap_queue_setup, | 376 | .queue_setup = bcap_queue_setup, |
444 | .buf_init = bcap_buffer_init, | ||
445 | .buf_prepare = bcap_buffer_prepare, | 377 | .buf_prepare = bcap_buffer_prepare, |
446 | .buf_cleanup = bcap_buffer_cleanup, | 378 | .buf_cleanup = bcap_buffer_cleanup, |
447 | .buf_queue = bcap_buffer_queue, | 379 | .buf_queue = bcap_buffer_queue, |
@@ -451,57 +383,6 @@ static struct vb2_ops bcap_video_qops = { | |||
451 | .stop_streaming = bcap_stop_streaming, | 383 | .stop_streaming = bcap_stop_streaming, |
452 | }; | 384 | }; |
453 | 385 | ||
454 | static int bcap_reqbufs(struct file *file, void *priv, | ||
455 | struct v4l2_requestbuffers *req_buf) | ||
456 | { | ||
457 | struct bcap_device *bcap_dev = video_drvdata(file); | ||
458 | struct vb2_queue *vq = &bcap_dev->buffer_queue; | ||
459 | struct v4l2_fh *fh = file->private_data; | ||
460 | struct bcap_fh *bcap_fh = container_of(fh, struct bcap_fh, fh); | ||
461 | |||
462 | if (vb2_is_busy(vq)) | ||
463 | return -EBUSY; | ||
464 | |||
465 | bcap_fh->io_allowed = true; | ||
466 | |||
467 | return vb2_reqbufs(vq, req_buf); | ||
468 | } | ||
469 | |||
470 | static int bcap_querybuf(struct file *file, void *priv, | ||
471 | struct v4l2_buffer *buf) | ||
472 | { | ||
473 | struct bcap_device *bcap_dev = video_drvdata(file); | ||
474 | |||
475 | return vb2_querybuf(&bcap_dev->buffer_queue, buf); | ||
476 | } | ||
477 | |||
478 | static int bcap_qbuf(struct file *file, void *priv, | ||
479 | struct v4l2_buffer *buf) | ||
480 | { | ||
481 | struct bcap_device *bcap_dev = video_drvdata(file); | ||
482 | struct v4l2_fh *fh = file->private_data; | ||
483 | struct bcap_fh *bcap_fh = container_of(fh, struct bcap_fh, fh); | ||
484 | |||
485 | if (!bcap_fh->io_allowed) | ||
486 | return -EBUSY; | ||
487 | |||
488 | return vb2_qbuf(&bcap_dev->buffer_queue, buf); | ||
489 | } | ||
490 | |||
491 | static int bcap_dqbuf(struct file *file, void *priv, | ||
492 | struct v4l2_buffer *buf) | ||
493 | { | ||
494 | struct bcap_device *bcap_dev = video_drvdata(file); | ||
495 | struct v4l2_fh *fh = file->private_data; | ||
496 | struct bcap_fh *bcap_fh = container_of(fh, struct bcap_fh, fh); | ||
497 | |||
498 | if (!bcap_fh->io_allowed) | ||
499 | return -EBUSY; | ||
500 | |||
501 | return vb2_dqbuf(&bcap_dev->buffer_queue, | ||
502 | buf, file->f_flags & O_NONBLOCK); | ||
503 | } | ||
504 | |||
505 | static irqreturn_t bcap_isr(int irq, void *dev_id) | 386 | static irqreturn_t bcap_isr(int irq, void *dev_id) |
506 | { | 387 | { |
507 | struct ppi_if *ppi = dev_id; | 388 | struct ppi_if *ppi = dev_id; |
@@ -517,6 +398,7 @@ static irqreturn_t bcap_isr(int irq, void *dev_id) | |||
517 | vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); | 398 | vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); |
518 | ppi->err = false; | 399 | ppi->err = false; |
519 | } else { | 400 | } else { |
401 | vb->v4l2_buf.sequence = bcap_dev->sequence++; | ||
520 | vb2_buffer_done(vb, VB2_BUF_STATE_DONE); | 402 | vb2_buffer_done(vb, VB2_BUF_STATE_DONE); |
521 | } | 403 | } |
522 | bcap_dev->cur_frm = list_entry(bcap_dev->dma_queue.next, | 404 | bcap_dev->cur_frm = list_entry(bcap_dev->dma_queue.next, |
@@ -543,62 +425,14 @@ static irqreturn_t bcap_isr(int irq, void *dev_id) | |||
543 | return IRQ_HANDLED; | 425 | return IRQ_HANDLED; |
544 | } | 426 | } |
545 | 427 | ||
546 | static int bcap_streamon(struct file *file, void *priv, | ||
547 | enum v4l2_buf_type buf_type) | ||
548 | { | ||
549 | struct bcap_device *bcap_dev = video_drvdata(file); | ||
550 | struct bcap_fh *fh = file->private_data; | ||
551 | struct ppi_if *ppi = bcap_dev->ppi; | ||
552 | dma_addr_t addr; | ||
553 | int ret; | ||
554 | |||
555 | if (!fh->io_allowed) | ||
556 | return -EBUSY; | ||
557 | |||
558 | /* call streamon to start streaming in videobuf */ | ||
559 | ret = vb2_streamon(&bcap_dev->buffer_queue, buf_type); | ||
560 | if (ret) | ||
561 | return ret; | ||
562 | |||
563 | /* if dma queue is empty, return error */ | ||
564 | if (list_empty(&bcap_dev->dma_queue)) { | ||
565 | v4l2_err(&bcap_dev->v4l2_dev, "dma queue is empty\n"); | ||
566 | ret = -EINVAL; | ||
567 | goto err; | ||
568 | } | ||
569 | |||
570 | /* get the next frame from the dma queue */ | ||
571 | bcap_dev->cur_frm = list_entry(bcap_dev->dma_queue.next, | ||
572 | struct bcap_buffer, list); | ||
573 | /* remove buffer from the dma queue */ | ||
574 | list_del_init(&bcap_dev->cur_frm->list); | ||
575 | addr = vb2_dma_contig_plane_dma_addr(&bcap_dev->cur_frm->vb, 0); | ||
576 | /* update DMA address */ | ||
577 | ppi->ops->update_addr(ppi, (unsigned long)addr); | ||
578 | /* enable ppi */ | ||
579 | ppi->ops->start(ppi); | ||
580 | |||
581 | return 0; | ||
582 | err: | ||
583 | vb2_streamoff(&bcap_dev->buffer_queue, buf_type); | ||
584 | return ret; | ||
585 | } | ||
586 | |||
587 | static int bcap_streamoff(struct file *file, void *priv, | ||
588 | enum v4l2_buf_type buf_type) | ||
589 | { | ||
590 | struct bcap_device *bcap_dev = video_drvdata(file); | ||
591 | struct bcap_fh *fh = file->private_data; | ||
592 | |||
593 | if (!fh->io_allowed) | ||
594 | return -EBUSY; | ||
595 | |||
596 | return vb2_streamoff(&bcap_dev->buffer_queue, buf_type); | ||
597 | } | ||
598 | |||
599 | static int bcap_querystd(struct file *file, void *priv, v4l2_std_id *std) | 428 | static int bcap_querystd(struct file *file, void *priv, v4l2_std_id *std) |
600 | { | 429 | { |
601 | struct bcap_device *bcap_dev = video_drvdata(file); | 430 | struct bcap_device *bcap_dev = video_drvdata(file); |
431 | struct v4l2_input input; | ||
432 | |||
433 | input = bcap_dev->cfg->inputs[bcap_dev->cur_input]; | ||
434 | if (!(input.capabilities & V4L2_IN_CAP_STD)) | ||
435 | return -ENODATA; | ||
602 | 436 | ||
603 | return v4l2_subdev_call(bcap_dev->sd, video, querystd, std); | 437 | return v4l2_subdev_call(bcap_dev->sd, video, querystd, std); |
604 | } | 438 | } |
@@ -606,6 +440,11 @@ static int bcap_querystd(struct file *file, void *priv, v4l2_std_id *std) | |||
606 | static int bcap_g_std(struct file *file, void *priv, v4l2_std_id *std) | 440 | static int bcap_g_std(struct file *file, void *priv, v4l2_std_id *std) |
607 | { | 441 | { |
608 | struct bcap_device *bcap_dev = video_drvdata(file); | 442 | struct bcap_device *bcap_dev = video_drvdata(file); |
443 | struct v4l2_input input; | ||
444 | |||
445 | input = bcap_dev->cfg->inputs[bcap_dev->cur_input]; | ||
446 | if (!(input.capabilities & V4L2_IN_CAP_STD)) | ||
447 | return -ENODATA; | ||
609 | 448 | ||
610 | *std = bcap_dev->std; | 449 | *std = bcap_dev->std; |
611 | return 0; | 450 | return 0; |
@@ -614,8 +453,13 @@ static int bcap_g_std(struct file *file, void *priv, v4l2_std_id *std) | |||
614 | static int bcap_s_std(struct file *file, void *priv, v4l2_std_id std) | 453 | static int bcap_s_std(struct file *file, void *priv, v4l2_std_id std) |
615 | { | 454 | { |
616 | struct bcap_device *bcap_dev = video_drvdata(file); | 455 | struct bcap_device *bcap_dev = video_drvdata(file); |
456 | struct v4l2_input input; | ||
617 | int ret; | 457 | int ret; |
618 | 458 | ||
459 | input = bcap_dev->cfg->inputs[bcap_dev->cur_input]; | ||
460 | if (!(input.capabilities & V4L2_IN_CAP_STD)) | ||
461 | return -ENODATA; | ||
462 | |||
619 | if (vb2_is_busy(&bcap_dev->buffer_queue)) | 463 | if (vb2_is_busy(&bcap_dev->buffer_queue)) |
620 | return -EBUSY; | 464 | return -EBUSY; |
621 | 465 | ||
@@ -631,6 +475,11 @@ static int bcap_enum_dv_timings(struct file *file, void *priv, | |||
631 | struct v4l2_enum_dv_timings *timings) | 475 | struct v4l2_enum_dv_timings *timings) |
632 | { | 476 | { |
633 | struct bcap_device *bcap_dev = video_drvdata(file); | 477 | struct bcap_device *bcap_dev = video_drvdata(file); |
478 | struct v4l2_input input; | ||
479 | |||
480 | input = bcap_dev->cfg->inputs[bcap_dev->cur_input]; | ||
481 | if (!(input.capabilities & V4L2_IN_CAP_DV_TIMINGS)) | ||
482 | return -ENODATA; | ||
634 | 483 | ||
635 | timings->pad = 0; | 484 | timings->pad = 0; |
636 | 485 | ||
@@ -642,6 +491,11 @@ static int bcap_query_dv_timings(struct file *file, void *priv, | |||
642 | struct v4l2_dv_timings *timings) | 491 | struct v4l2_dv_timings *timings) |
643 | { | 492 | { |
644 | struct bcap_device *bcap_dev = video_drvdata(file); | 493 | struct bcap_device *bcap_dev = video_drvdata(file); |
494 | struct v4l2_input input; | ||
495 | |||
496 | input = bcap_dev->cfg->inputs[bcap_dev->cur_input]; | ||
497 | if (!(input.capabilities & V4L2_IN_CAP_DV_TIMINGS)) | ||
498 | return -ENODATA; | ||
645 | 499 | ||
646 | return v4l2_subdev_call(bcap_dev->sd, video, | 500 | return v4l2_subdev_call(bcap_dev->sd, video, |
647 | query_dv_timings, timings); | 501 | query_dv_timings, timings); |
@@ -651,6 +505,11 @@ static int bcap_g_dv_timings(struct file *file, void *priv, | |||
651 | struct v4l2_dv_timings *timings) | 505 | struct v4l2_dv_timings *timings) |
652 | { | 506 | { |
653 | struct bcap_device *bcap_dev = video_drvdata(file); | 507 | struct bcap_device *bcap_dev = video_drvdata(file); |
508 | struct v4l2_input input; | ||
509 | |||
510 | input = bcap_dev->cfg->inputs[bcap_dev->cur_input]; | ||
511 | if (!(input.capabilities & V4L2_IN_CAP_DV_TIMINGS)) | ||
512 | return -ENODATA; | ||
654 | 513 | ||
655 | *timings = bcap_dev->dv_timings; | 514 | *timings = bcap_dev->dv_timings; |
656 | return 0; | 515 | return 0; |
@@ -660,7 +519,13 @@ static int bcap_s_dv_timings(struct file *file, void *priv, | |||
660 | struct v4l2_dv_timings *timings) | 519 | struct v4l2_dv_timings *timings) |
661 | { | 520 | { |
662 | struct bcap_device *bcap_dev = video_drvdata(file); | 521 | struct bcap_device *bcap_dev = video_drvdata(file); |
522 | struct v4l2_input input; | ||
663 | int ret; | 523 | int ret; |
524 | |||
525 | input = bcap_dev->cfg->inputs[bcap_dev->cur_input]; | ||
526 | if (!(input.capabilities & V4L2_IN_CAP_DV_TIMINGS)) | ||
527 | return -ENODATA; | ||
528 | |||
664 | if (vb2_is_busy(&bcap_dev->buffer_queue)) | 529 | if (vb2_is_busy(&bcap_dev->buffer_queue)) |
665 | return -EBUSY; | 530 | return -EBUSY; |
666 | 531 | ||
@@ -881,12 +746,14 @@ static const struct v4l2_ioctl_ops bcap_ioctl_ops = { | |||
881 | .vidioc_g_dv_timings = bcap_g_dv_timings, | 746 | .vidioc_g_dv_timings = bcap_g_dv_timings, |
882 | .vidioc_query_dv_timings = bcap_query_dv_timings, | 747 | .vidioc_query_dv_timings = bcap_query_dv_timings, |
883 | .vidioc_enum_dv_timings = bcap_enum_dv_timings, | 748 | .vidioc_enum_dv_timings = bcap_enum_dv_timings, |
884 | .vidioc_reqbufs = bcap_reqbufs, | 749 | .vidioc_reqbufs = vb2_ioctl_reqbufs, |
885 | .vidioc_querybuf = bcap_querybuf, | 750 | .vidioc_create_bufs = vb2_ioctl_create_bufs, |
886 | .vidioc_qbuf = bcap_qbuf, | 751 | .vidioc_querybuf = vb2_ioctl_querybuf, |
887 | .vidioc_dqbuf = bcap_dqbuf, | 752 | .vidioc_qbuf = vb2_ioctl_qbuf, |
888 | .vidioc_streamon = bcap_streamon, | 753 | .vidioc_dqbuf = vb2_ioctl_dqbuf, |
889 | .vidioc_streamoff = bcap_streamoff, | 754 | .vidioc_expbuf = vb2_ioctl_expbuf, |
755 | .vidioc_streamon = vb2_ioctl_streamon, | ||
756 | .vidioc_streamoff = vb2_ioctl_streamoff, | ||
890 | .vidioc_g_parm = bcap_g_parm, | 757 | .vidioc_g_parm = bcap_g_parm, |
891 | .vidioc_s_parm = bcap_s_parm, | 758 | .vidioc_s_parm = bcap_s_parm, |
892 | .vidioc_log_status = bcap_log_status, | 759 | .vidioc_log_status = bcap_log_status, |
@@ -894,14 +761,14 @@ static const struct v4l2_ioctl_ops bcap_ioctl_ops = { | |||
894 | 761 | ||
895 | static struct v4l2_file_operations bcap_fops = { | 762 | static struct v4l2_file_operations bcap_fops = { |
896 | .owner = THIS_MODULE, | 763 | .owner = THIS_MODULE, |
897 | .open = bcap_open, | 764 | .open = v4l2_fh_open, |
898 | .release = bcap_release, | 765 | .release = vb2_fop_release, |
899 | .unlocked_ioctl = video_ioctl2, | 766 | .unlocked_ioctl = video_ioctl2, |
900 | .mmap = bcap_mmap, | 767 | .mmap = vb2_fop_mmap, |
901 | #ifndef CONFIG_MMU | 768 | #ifndef CONFIG_MMU |
902 | .get_unmapped_area = bcap_get_unmapped_area, | 769 | .get_unmapped_area = vb2_fop_get_unmapped_area, |
903 | #endif | 770 | #endif |
904 | .poll = bcap_poll | 771 | .poll = vb2_fop_poll |
905 | }; | 772 | }; |
906 | 773 | ||
907 | static int bcap_probe(struct platform_device *pdev) | 774 | static int bcap_probe(struct platform_device *pdev) |
@@ -942,27 +809,20 @@ static int bcap_probe(struct platform_device *pdev) | |||
942 | goto err_free_ppi; | 809 | goto err_free_ppi; |
943 | } | 810 | } |
944 | 811 | ||
945 | vfd = video_device_alloc(); | 812 | vfd = &bcap_dev->video_dev; |
946 | if (!vfd) { | ||
947 | ret = -ENOMEM; | ||
948 | v4l2_err(pdev->dev.driver, "Unable to alloc video device\n"); | ||
949 | goto err_cleanup_ctx; | ||
950 | } | ||
951 | |||
952 | /* initialize field of video device */ | 813 | /* initialize field of video device */ |
953 | vfd->release = video_device_release; | 814 | vfd->release = video_device_release_empty; |
954 | vfd->fops = &bcap_fops; | 815 | vfd->fops = &bcap_fops; |
955 | vfd->ioctl_ops = &bcap_ioctl_ops; | 816 | vfd->ioctl_ops = &bcap_ioctl_ops; |
956 | vfd->tvnorms = 0; | 817 | vfd->tvnorms = 0; |
957 | vfd->v4l2_dev = &bcap_dev->v4l2_dev; | 818 | vfd->v4l2_dev = &bcap_dev->v4l2_dev; |
958 | strncpy(vfd->name, CAPTURE_DRV_NAME, sizeof(vfd->name)); | 819 | strncpy(vfd->name, CAPTURE_DRV_NAME, sizeof(vfd->name)); |
959 | bcap_dev->video_dev = vfd; | ||
960 | 820 | ||
961 | ret = v4l2_device_register(&pdev->dev, &bcap_dev->v4l2_dev); | 821 | ret = v4l2_device_register(&pdev->dev, &bcap_dev->v4l2_dev); |
962 | if (ret) { | 822 | if (ret) { |
963 | v4l2_err(pdev->dev.driver, | 823 | v4l2_err(pdev->dev.driver, |
964 | "Unable to register v4l2 device\n"); | 824 | "Unable to register v4l2 device\n"); |
965 | goto err_release_vdev; | 825 | goto err_cleanup_ctx; |
966 | } | 826 | } |
967 | v4l2_info(&bcap_dev->v4l2_dev, "v4l2 device registered\n"); | 827 | v4l2_info(&bcap_dev->v4l2_dev, "v4l2 device registered\n"); |
968 | 828 | ||
@@ -978,13 +838,14 @@ static int bcap_probe(struct platform_device *pdev) | |||
978 | /* initialize queue */ | 838 | /* initialize queue */ |
979 | q = &bcap_dev->buffer_queue; | 839 | q = &bcap_dev->buffer_queue; |
980 | q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 840 | q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
981 | q->io_modes = VB2_MMAP; | 841 | q->io_modes = VB2_MMAP | VB2_DMABUF; |
982 | q->drv_priv = bcap_dev; | 842 | q->drv_priv = bcap_dev; |
983 | q->buf_struct_size = sizeof(struct bcap_buffer); | 843 | q->buf_struct_size = sizeof(struct bcap_buffer); |
984 | q->ops = &bcap_video_qops; | 844 | q->ops = &bcap_video_qops; |
985 | q->mem_ops = &vb2_dma_contig_memops; | 845 | q->mem_ops = &vb2_dma_contig_memops; |
986 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; | 846 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; |
987 | q->lock = &bcap_dev->mutex; | 847 | q->lock = &bcap_dev->mutex; |
848 | q->min_buffers_needed = 1; | ||
988 | 849 | ||
989 | ret = vb2_queue_init(q); | 850 | ret = vb2_queue_init(q); |
990 | if (ret) | 851 | if (ret) |
@@ -997,15 +858,16 @@ static int bcap_probe(struct platform_device *pdev) | |||
997 | INIT_LIST_HEAD(&bcap_dev->dma_queue); | 858 | INIT_LIST_HEAD(&bcap_dev->dma_queue); |
998 | 859 | ||
999 | vfd->lock = &bcap_dev->mutex; | 860 | vfd->lock = &bcap_dev->mutex; |
861 | vfd->queue = q; | ||
1000 | 862 | ||
1001 | /* register video device */ | 863 | /* register video device */ |
1002 | ret = video_register_device(bcap_dev->video_dev, VFL_TYPE_GRABBER, -1); | 864 | ret = video_register_device(&bcap_dev->video_dev, VFL_TYPE_GRABBER, -1); |
1003 | if (ret) { | 865 | if (ret) { |
1004 | v4l2_err(&bcap_dev->v4l2_dev, | 866 | v4l2_err(&bcap_dev->v4l2_dev, |
1005 | "Unable to register video device\n"); | 867 | "Unable to register video device\n"); |
1006 | goto err_free_handler; | 868 | goto err_free_handler; |
1007 | } | 869 | } |
1008 | video_set_drvdata(bcap_dev->video_dev, bcap_dev); | 870 | video_set_drvdata(&bcap_dev->video_dev, bcap_dev); |
1009 | v4l2_info(&bcap_dev->v4l2_dev, "video device registered as: %s\n", | 871 | v4l2_info(&bcap_dev->v4l2_dev, "video device registered as: %s\n", |
1010 | video_device_node_name(vfd)); | 872 | video_device_node_name(vfd)); |
1011 | 873 | ||
@@ -1083,15 +945,11 @@ static int bcap_probe(struct platform_device *pdev) | |||
1083 | } | 945 | } |
1084 | return 0; | 946 | return 0; |
1085 | err_unreg_vdev: | 947 | err_unreg_vdev: |
1086 | video_unregister_device(bcap_dev->video_dev); | 948 | video_unregister_device(&bcap_dev->video_dev); |
1087 | bcap_dev->video_dev = NULL; | ||
1088 | err_free_handler: | 949 | err_free_handler: |
1089 | v4l2_ctrl_handler_free(&bcap_dev->ctrl_handler); | 950 | v4l2_ctrl_handler_free(&bcap_dev->ctrl_handler); |
1090 | err_unreg_v4l2: | 951 | err_unreg_v4l2: |
1091 | v4l2_device_unregister(&bcap_dev->v4l2_dev); | 952 | v4l2_device_unregister(&bcap_dev->v4l2_dev); |
1092 | err_release_vdev: | ||
1093 | if (bcap_dev->video_dev) | ||
1094 | video_device_release(bcap_dev->video_dev); | ||
1095 | err_cleanup_ctx: | 953 | err_cleanup_ctx: |
1096 | vb2_dma_contig_cleanup_ctx(bcap_dev->alloc_ctx); | 954 | vb2_dma_contig_cleanup_ctx(bcap_dev->alloc_ctx); |
1097 | err_free_ppi: | 955 | err_free_ppi: |
@@ -1108,7 +966,7 @@ static int bcap_remove(struct platform_device *pdev) | |||
1108 | struct bcap_device, v4l2_dev); | 966 | struct bcap_device, v4l2_dev); |
1109 | 967 | ||
1110 | bcap_free_sensor_formats(bcap_dev); | 968 | bcap_free_sensor_formats(bcap_dev); |
1111 | video_unregister_device(bcap_dev->video_dev); | 969 | video_unregister_device(&bcap_dev->video_dev); |
1112 | v4l2_ctrl_handler_free(&bcap_dev->ctrl_handler); | 970 | v4l2_ctrl_handler_free(&bcap_dev->ctrl_handler); |
1113 | v4l2_device_unregister(v4l2_dev); | 971 | v4l2_device_unregister(v4l2_dev); |
1114 | vb2_dma_contig_cleanup_ctx(bcap_dev->alloc_ctx); | 972 | vb2_dma_contig_cleanup_ctx(bcap_dev->alloc_ctx); |
diff --git a/drivers/media/platform/coda/Makefile b/drivers/media/platform/coda/Makefile index 25ce15561695..834e504bf085 100644 --- a/drivers/media/platform/coda/Makefile +++ b/drivers/media/platform/coda/Makefile | |||
@@ -1,3 +1,5 @@ | |||
1 | ccflags-y += -I$(src) | ||
2 | |||
1 | coda-objs := coda-common.o coda-bit.o coda-h264.o coda-jpeg.o | 3 | coda-objs := coda-common.o coda-bit.o coda-h264.o coda-jpeg.o |
2 | 4 | ||
3 | obj-$(CONFIG_VIDEO_CODA) += coda.o | 5 | obj-$(CONFIG_VIDEO_CODA) += coda.o |
diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c index 856b542b35b9..d0430071d2ee 100644 --- a/drivers/media/platform/coda/coda-bit.c +++ b/drivers/media/platform/coda/coda-bit.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/clk.h> | 15 | #include <linux/clk.h> |
16 | #include <linux/irqreturn.h> | 16 | #include <linux/irqreturn.h> |
17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | #include <linux/log2.h> | ||
18 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
19 | #include <linux/reset.h> | 20 | #include <linux/reset.h> |
20 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
@@ -29,13 +30,18 @@ | |||
29 | #include <media/videobuf2-vmalloc.h> | 30 | #include <media/videobuf2-vmalloc.h> |
30 | 31 | ||
31 | #include "coda.h" | 32 | #include "coda.h" |
33 | #define CREATE_TRACE_POINTS | ||
34 | #include "trace.h" | ||
32 | 35 | ||
36 | #define CODA_PARA_BUF_SIZE (10 * 1024) | ||
33 | #define CODA7_PS_BUF_SIZE 0x28000 | 37 | #define CODA7_PS_BUF_SIZE 0x28000 |
34 | #define CODA9_PS_SAVE_SIZE (512 * 1024) | 38 | #define CODA9_PS_SAVE_SIZE (512 * 1024) |
35 | 39 | ||
36 | #define CODA_DEFAULT_GAMMA 4096 | 40 | #define CODA_DEFAULT_GAMMA 4096 |
37 | #define CODA9_DEFAULT_GAMMA 24576 /* 0.75 * 32768 */ | 41 | #define CODA9_DEFAULT_GAMMA 24576 /* 0.75 * 32768 */ |
38 | 42 | ||
43 | static void coda_free_bitstream_buffer(struct coda_ctx *ctx); | ||
44 | |||
39 | static inline int coda_is_initialized(struct coda_dev *dev) | 45 | static inline int coda_is_initialized(struct coda_dev *dev) |
40 | { | 46 | { |
41 | return coda_read(dev, CODA_REG_BIT_CUR_PC) != 0; | 47 | return coda_read(dev, CODA_REG_BIT_CUR_PC) != 0; |
@@ -84,15 +90,21 @@ static void coda_command_async(struct coda_ctx *ctx, int cmd) | |||
84 | coda_write(dev, ctx->params.codec_mode, CODA_REG_BIT_RUN_COD_STD); | 90 | coda_write(dev, ctx->params.codec_mode, CODA_REG_BIT_RUN_COD_STD); |
85 | coda_write(dev, ctx->params.codec_mode_aux, CODA7_REG_BIT_RUN_AUX_STD); | 91 | coda_write(dev, ctx->params.codec_mode_aux, CODA7_REG_BIT_RUN_AUX_STD); |
86 | 92 | ||
93 | trace_coda_bit_run(ctx, cmd); | ||
94 | |||
87 | coda_write(dev, cmd, CODA_REG_BIT_RUN_COMMAND); | 95 | coda_write(dev, cmd, CODA_REG_BIT_RUN_COMMAND); |
88 | } | 96 | } |
89 | 97 | ||
90 | static int coda_command_sync(struct coda_ctx *ctx, int cmd) | 98 | static int coda_command_sync(struct coda_ctx *ctx, int cmd) |
91 | { | 99 | { |
92 | struct coda_dev *dev = ctx->dev; | 100 | struct coda_dev *dev = ctx->dev; |
101 | int ret; | ||
93 | 102 | ||
94 | coda_command_async(ctx, cmd); | 103 | coda_command_async(ctx, cmd); |
95 | return coda_wait_timeout(dev); | 104 | ret = coda_wait_timeout(dev); |
105 | trace_coda_bit_done(ctx); | ||
106 | |||
107 | return ret; | ||
96 | } | 108 | } |
97 | 109 | ||
98 | int coda_hw_reset(struct coda_ctx *ctx) | 110 | int coda_hw_reset(struct coda_ctx *ctx) |
@@ -177,10 +189,6 @@ static int coda_bitstream_queue(struct coda_ctx *ctx, | |||
177 | if (n < src_size) | 189 | if (n < src_size) |
178 | return -ENOSPC; | 190 | return -ENOSPC; |
179 | 191 | ||
180 | dma_sync_single_for_device(&ctx->dev->plat_dev->dev, | ||
181 | ctx->bitstream.paddr, ctx->bitstream.size, | ||
182 | DMA_TO_DEVICE); | ||
183 | |||
184 | src_buf->v4l2_buf.sequence = ctx->qsequence++; | 192 | src_buf->v4l2_buf.sequence = ctx->qsequence++; |
185 | 193 | ||
186 | return 0; | 194 | return 0; |
@@ -214,7 +222,7 @@ static bool coda_bitstream_try_queue(struct coda_ctx *ctx, | |||
214 | return true; | 222 | return true; |
215 | } | 223 | } |
216 | 224 | ||
217 | void coda_fill_bitstream(struct coda_ctx *ctx) | 225 | void coda_fill_bitstream(struct coda_ctx *ctx, bool streaming) |
218 | { | 226 | { |
219 | struct vb2_buffer *src_buf; | 227 | struct vb2_buffer *src_buf; |
220 | struct coda_buffer_meta *meta; | 228 | struct coda_buffer_meta *meta; |
@@ -235,9 +243,12 @@ void coda_fill_bitstream(struct coda_ctx *ctx) | |||
235 | if (ctx->codec->src_fourcc == V4L2_PIX_FMT_JPEG && | 243 | if (ctx->codec->src_fourcc == V4L2_PIX_FMT_JPEG && |
236 | !coda_jpeg_check_buffer(ctx, src_buf)) { | 244 | !coda_jpeg_check_buffer(ctx, src_buf)) { |
237 | v4l2_err(&ctx->dev->v4l2_dev, | 245 | v4l2_err(&ctx->dev->v4l2_dev, |
238 | "dropping invalid JPEG frame\n"); | 246 | "dropping invalid JPEG frame %d\n", |
247 | ctx->qsequence); | ||
239 | src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); | 248 | src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); |
240 | v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR); | 249 | v4l2_m2m_buf_done(src_buf, streaming ? |
250 | VB2_BUF_STATE_ERROR : | ||
251 | VB2_BUF_STATE_QUEUED); | ||
241 | continue; | 252 | continue; |
242 | } | 253 | } |
243 | 254 | ||
@@ -262,6 +273,8 @@ void coda_fill_bitstream(struct coda_ctx *ctx) | |||
262 | ctx->bitstream_fifo.kfifo.mask; | 273 | ctx->bitstream_fifo.kfifo.mask; |
263 | list_add_tail(&meta->list, | 274 | list_add_tail(&meta->list, |
264 | &ctx->buffer_meta_list); | 275 | &ctx->buffer_meta_list); |
276 | |||
277 | trace_coda_bit_queue(ctx, src_buf, meta); | ||
265 | } | 278 | } |
266 | 279 | ||
267 | v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE); | 280 | v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE); |
@@ -297,6 +310,14 @@ static void coda_parabuf_write(struct coda_ctx *ctx, int index, u32 value) | |||
297 | p[index ^ 1] = value; | 310 | p[index ^ 1] = value; |
298 | } | 311 | } |
299 | 312 | ||
313 | static inline int coda_alloc_context_buf(struct coda_ctx *ctx, | ||
314 | struct coda_aux_buf *buf, size_t size, | ||
315 | const char *name) | ||
316 | { | ||
317 | return coda_alloc_aux_buf(ctx->dev, buf, size, name, ctx->debugfs_entry); | ||
318 | } | ||
319 | |||
320 | |||
300 | static void coda_free_framebuffers(struct coda_ctx *ctx) | 321 | static void coda_free_framebuffers(struct coda_ctx *ctx) |
301 | { | 322 | { |
302 | int i; | 323 | int i; |
@@ -377,6 +398,7 @@ static void coda_free_context_buffers(struct coda_ctx *ctx) | |||
377 | coda_free_aux_buf(dev, &ctx->psbuf); | 398 | coda_free_aux_buf(dev, &ctx->psbuf); |
378 | if (dev->devtype->product != CODA_DX6) | 399 | if (dev->devtype->product != CODA_DX6) |
379 | coda_free_aux_buf(dev, &ctx->workbuf); | 400 | coda_free_aux_buf(dev, &ctx->workbuf); |
401 | coda_free_aux_buf(dev, &ctx->parabuf); | ||
380 | } | 402 | } |
381 | 403 | ||
382 | static int coda_alloc_context_buffers(struct coda_ctx *ctx, | 404 | static int coda_alloc_context_buffers(struct coda_ctx *ctx, |
@@ -386,57 +408,42 @@ static int coda_alloc_context_buffers(struct coda_ctx *ctx, | |||
386 | size_t size; | 408 | size_t size; |
387 | int ret; | 409 | int ret; |
388 | 410 | ||
411 | if (!ctx->parabuf.vaddr) { | ||
412 | ret = coda_alloc_context_buf(ctx, &ctx->parabuf, | ||
413 | CODA_PARA_BUF_SIZE, "parabuf"); | ||
414 | if (ret < 0) | ||
415 | return ret; | ||
416 | } | ||
417 | |||
389 | if (dev->devtype->product == CODA_DX6) | 418 | if (dev->devtype->product == CODA_DX6) |
390 | return 0; | 419 | return 0; |
391 | 420 | ||
392 | if (ctx->psbuf.vaddr) { | 421 | if (!ctx->slicebuf.vaddr && q_data->fourcc == V4L2_PIX_FMT_H264) { |
393 | v4l2_err(&dev->v4l2_dev, "psmembuf still allocated\n"); | ||
394 | return -EBUSY; | ||
395 | } | ||
396 | if (ctx->slicebuf.vaddr) { | ||
397 | v4l2_err(&dev->v4l2_dev, "slicebuf still allocated\n"); | ||
398 | return -EBUSY; | ||
399 | } | ||
400 | if (ctx->workbuf.vaddr) { | ||
401 | v4l2_err(&dev->v4l2_dev, "context buffer still allocated\n"); | ||
402 | ret = -EBUSY; | ||
403 | return -ENOMEM; | ||
404 | } | ||
405 | |||
406 | if (q_data->fourcc == V4L2_PIX_FMT_H264) { | ||
407 | /* worst case slice size */ | 422 | /* worst case slice size */ |
408 | size = (DIV_ROUND_UP(q_data->width, 16) * | 423 | size = (DIV_ROUND_UP(q_data->width, 16) * |
409 | DIV_ROUND_UP(q_data->height, 16)) * 3200 / 8 + 512; | 424 | DIV_ROUND_UP(q_data->height, 16)) * 3200 / 8 + 512; |
410 | ret = coda_alloc_context_buf(ctx, &ctx->slicebuf, size, | 425 | ret = coda_alloc_context_buf(ctx, &ctx->slicebuf, size, |
411 | "slicebuf"); | 426 | "slicebuf"); |
412 | if (ret < 0) { | 427 | if (ret < 0) |
413 | v4l2_err(&dev->v4l2_dev, | 428 | goto err; |
414 | "failed to allocate %d byte slice buffer", | ||
415 | ctx->slicebuf.size); | ||
416 | return ret; | ||
417 | } | ||
418 | } | 429 | } |
419 | 430 | ||
420 | if (dev->devtype->product == CODA_7541) { | 431 | if (!ctx->psbuf.vaddr && dev->devtype->product == CODA_7541) { |
421 | ret = coda_alloc_context_buf(ctx, &ctx->psbuf, | 432 | ret = coda_alloc_context_buf(ctx, &ctx->psbuf, |
422 | CODA7_PS_BUF_SIZE, "psbuf"); | 433 | CODA7_PS_BUF_SIZE, "psbuf"); |
423 | if (ret < 0) { | 434 | if (ret < 0) |
424 | v4l2_err(&dev->v4l2_dev, | ||
425 | "failed to allocate psmem buffer"); | ||
426 | goto err; | 435 | goto err; |
427 | } | ||
428 | } | 436 | } |
429 | 437 | ||
430 | size = dev->devtype->workbuf_size; | 438 | if (!ctx->workbuf.vaddr) { |
431 | if (dev->devtype->product == CODA_960 && | 439 | size = dev->devtype->workbuf_size; |
432 | q_data->fourcc == V4L2_PIX_FMT_H264) | 440 | if (dev->devtype->product == CODA_960 && |
433 | size += CODA9_PS_SAVE_SIZE; | 441 | q_data->fourcc == V4L2_PIX_FMT_H264) |
434 | ret = coda_alloc_context_buf(ctx, &ctx->workbuf, size, "workbuf"); | 442 | size += CODA9_PS_SAVE_SIZE; |
435 | if (ret < 0) { | 443 | ret = coda_alloc_context_buf(ctx, &ctx->workbuf, size, |
436 | v4l2_err(&dev->v4l2_dev, | 444 | "workbuf"); |
437 | "failed to allocate %d byte context buffer", | 445 | if (ret < 0) |
438 | ctx->workbuf.size); | 446 | goto err; |
439 | goto err; | ||
440 | } | 447 | } |
441 | 448 | ||
442 | return 0; | 449 | return 0; |
@@ -709,6 +716,27 @@ err_clk_per: | |||
709 | * Encoder context operations | 716 | * Encoder context operations |
710 | */ | 717 | */ |
711 | 718 | ||
719 | static int coda_encoder_reqbufs(struct coda_ctx *ctx, | ||
720 | struct v4l2_requestbuffers *rb) | ||
721 | { | ||
722 | struct coda_q_data *q_data_src; | ||
723 | int ret; | ||
724 | |||
725 | if (rb->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) | ||
726 | return 0; | ||
727 | |||
728 | if (rb->count) { | ||
729 | q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); | ||
730 | ret = coda_alloc_context_buffers(ctx, q_data_src); | ||
731 | if (ret < 0) | ||
732 | return ret; | ||
733 | } else { | ||
734 | coda_free_context_buffers(ctx); | ||
735 | } | ||
736 | |||
737 | return 0; | ||
738 | } | ||
739 | |||
712 | static int coda_start_encoding(struct coda_ctx *ctx) | 740 | static int coda_start_encoding(struct coda_ctx *ctx) |
713 | { | 741 | { |
714 | struct coda_dev *dev = ctx->dev; | 742 | struct coda_dev *dev = ctx->dev; |
@@ -725,11 +753,6 @@ static int coda_start_encoding(struct coda_ctx *ctx) | |||
725 | q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); | 753 | q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); |
726 | dst_fourcc = q_data_dst->fourcc; | 754 | dst_fourcc = q_data_dst->fourcc; |
727 | 755 | ||
728 | /* Allocate per-instance buffers */ | ||
729 | ret = coda_alloc_context_buffers(ctx, q_data_src); | ||
730 | if (ret < 0) | ||
731 | return ret; | ||
732 | |||
733 | buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); | 756 | buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); |
734 | bitstream_buf = vb2_dma_contig_plane_dma_addr(buf, 0); | 757 | bitstream_buf = vb2_dma_contig_plane_dma_addr(buf, 0); |
735 | bitstream_size = q_data_dst->sizeimage; | 758 | bitstream_size = q_data_dst->sizeimage; |
@@ -1227,6 +1250,8 @@ static int coda_prepare_encode(struct coda_ctx *ctx) | |||
1227 | coda_write(dev, ctx->iram_info.axi_sram_use, | 1250 | coda_write(dev, ctx->iram_info.axi_sram_use, |
1228 | CODA7_REG_BIT_AXI_SRAM_USE); | 1251 | CODA7_REG_BIT_AXI_SRAM_USE); |
1229 | 1252 | ||
1253 | trace_coda_enc_pic_run(ctx, src_buf); | ||
1254 | |||
1230 | coda_command_async(ctx, CODA_COMMAND_PIC_RUN); | 1255 | coda_command_async(ctx, CODA_COMMAND_PIC_RUN); |
1231 | 1256 | ||
1232 | return 0; | 1257 | return 0; |
@@ -1241,6 +1266,8 @@ static void coda_finish_encode(struct coda_ctx *ctx) | |||
1241 | src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); | 1266 | src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); |
1242 | dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); | 1267 | dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); |
1243 | 1268 | ||
1269 | trace_coda_enc_pic_done(ctx, dst_buf); | ||
1270 | |||
1244 | /* Get results from the coda */ | 1271 | /* Get results from the coda */ |
1245 | start_ptr = coda_read(dev, CODA_CMD_ENC_PIC_BB_START); | 1272 | start_ptr = coda_read(dev, CODA_CMD_ENC_PIC_BB_START); |
1246 | wr_ptr = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->reg_idx)); | 1273 | wr_ptr = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->reg_idx)); |
@@ -1311,7 +1338,6 @@ static void coda_seq_end_work(struct work_struct *work) | |||
1311 | ctx->bitstream.vaddr, ctx->bitstream.size); | 1338 | ctx->bitstream.vaddr, ctx->bitstream.size); |
1312 | 1339 | ||
1313 | coda_free_framebuffers(ctx); | 1340 | coda_free_framebuffers(ctx); |
1314 | coda_free_context_buffers(ctx); | ||
1315 | 1341 | ||
1316 | mutex_unlock(&dev->coda_mutex); | 1342 | mutex_unlock(&dev->coda_mutex); |
1317 | mutex_unlock(&ctx->buffer_mutex); | 1343 | mutex_unlock(&ctx->buffer_mutex); |
@@ -1322,11 +1348,13 @@ static void coda_bit_release(struct coda_ctx *ctx) | |||
1322 | mutex_lock(&ctx->buffer_mutex); | 1348 | mutex_lock(&ctx->buffer_mutex); |
1323 | coda_free_framebuffers(ctx); | 1349 | coda_free_framebuffers(ctx); |
1324 | coda_free_context_buffers(ctx); | 1350 | coda_free_context_buffers(ctx); |
1351 | coda_free_bitstream_buffer(ctx); | ||
1325 | mutex_unlock(&ctx->buffer_mutex); | 1352 | mutex_unlock(&ctx->buffer_mutex); |
1326 | } | 1353 | } |
1327 | 1354 | ||
1328 | const struct coda_context_ops coda_bit_encode_ops = { | 1355 | const struct coda_context_ops coda_bit_encode_ops = { |
1329 | .queue_init = coda_encoder_queue_init, | 1356 | .queue_init = coda_encoder_queue_init, |
1357 | .reqbufs = coda_encoder_reqbufs, | ||
1330 | .start_streaming = coda_start_encoding, | 1358 | .start_streaming = coda_start_encoding, |
1331 | .prepare_run = coda_prepare_encode, | 1359 | .prepare_run = coda_prepare_encode, |
1332 | .finish_run = coda_finish_encode, | 1360 | .finish_run = coda_finish_encode, |
@@ -1338,6 +1366,65 @@ const struct coda_context_ops coda_bit_encode_ops = { | |||
1338 | * Decoder context operations | 1366 | * Decoder context operations |
1339 | */ | 1367 | */ |
1340 | 1368 | ||
1369 | static int coda_alloc_bitstream_buffer(struct coda_ctx *ctx, | ||
1370 | struct coda_q_data *q_data) | ||
1371 | { | ||
1372 | if (ctx->bitstream.vaddr) | ||
1373 | return 0; | ||
1374 | |||
1375 | ctx->bitstream.size = roundup_pow_of_two(q_data->sizeimage * 2); | ||
1376 | ctx->bitstream.vaddr = dma_alloc_writecombine( | ||
1377 | &ctx->dev->plat_dev->dev, ctx->bitstream.size, | ||
1378 | &ctx->bitstream.paddr, GFP_KERNEL); | ||
1379 | if (!ctx->bitstream.vaddr) { | ||
1380 | v4l2_err(&ctx->dev->v4l2_dev, | ||
1381 | "failed to allocate bitstream ringbuffer"); | ||
1382 | return -ENOMEM; | ||
1383 | } | ||
1384 | kfifo_init(&ctx->bitstream_fifo, | ||
1385 | ctx->bitstream.vaddr, ctx->bitstream.size); | ||
1386 | |||
1387 | return 0; | ||
1388 | } | ||
1389 | |||
1390 | static void coda_free_bitstream_buffer(struct coda_ctx *ctx) | ||
1391 | { | ||
1392 | if (ctx->bitstream.vaddr == NULL) | ||
1393 | return; | ||
1394 | |||
1395 | dma_free_writecombine(&ctx->dev->plat_dev->dev, ctx->bitstream.size, | ||
1396 | ctx->bitstream.vaddr, ctx->bitstream.paddr); | ||
1397 | ctx->bitstream.vaddr = NULL; | ||
1398 | kfifo_init(&ctx->bitstream_fifo, NULL, 0); | ||
1399 | } | ||
1400 | |||
1401 | static int coda_decoder_reqbufs(struct coda_ctx *ctx, | ||
1402 | struct v4l2_requestbuffers *rb) | ||
1403 | { | ||
1404 | struct coda_q_data *q_data_src; | ||
1405 | int ret; | ||
1406 | |||
1407 | if (rb->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) | ||
1408 | return 0; | ||
1409 | |||
1410 | if (rb->count) { | ||
1411 | q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); | ||
1412 | ret = coda_alloc_context_buffers(ctx, q_data_src); | ||
1413 | if (ret < 0) | ||
1414 | return ret; | ||
1415 | ret = coda_alloc_bitstream_buffer(ctx, q_data_src); | ||
1416 | if (ret < 0) { | ||
1417 | coda_free_context_buffers(ctx); | ||
1418 | return ret; | ||
1419 | } | ||
1420 | } else { | ||
1421 | coda_free_bitstream_buffer(ctx); | ||
1422 | coda_free_context_buffers(ctx); | ||
1423 | } | ||
1424 | |||
1425 | return 0; | ||
1426 | } | ||
1427 | |||
1341 | static int __coda_start_decoding(struct coda_ctx *ctx) | 1428 | static int __coda_start_decoding(struct coda_ctx *ctx) |
1342 | { | 1429 | { |
1343 | struct coda_q_data *q_data_src, *q_data_dst; | 1430 | struct coda_q_data *q_data_src, *q_data_dst; |
@@ -1356,11 +1443,6 @@ static int __coda_start_decoding(struct coda_ctx *ctx) | |||
1356 | src_fourcc = q_data_src->fourcc; | 1443 | src_fourcc = q_data_src->fourcc; |
1357 | dst_fourcc = q_data_dst->fourcc; | 1444 | dst_fourcc = q_data_dst->fourcc; |
1358 | 1445 | ||
1359 | /* Allocate per-instance buffers */ | ||
1360 | ret = coda_alloc_context_buffers(ctx, q_data_src); | ||
1361 | if (ret < 0) | ||
1362 | return ret; | ||
1363 | |||
1364 | coda_write(dev, ctx->parabuf.paddr, CODA_REG_BIT_PARA_BUF_ADDR); | 1446 | coda_write(dev, ctx->parabuf.paddr, CODA_REG_BIT_PARA_BUF_ADDR); |
1365 | 1447 | ||
1366 | /* Update coda bitstream read and write pointers from kfifo */ | 1448 | /* Update coda bitstream read and write pointers from kfifo */ |
@@ -1579,7 +1661,7 @@ static int coda_prepare_decode(struct coda_ctx *ctx) | |||
1579 | 1661 | ||
1580 | /* Try to copy source buffer contents into the bitstream ringbuffer */ | 1662 | /* Try to copy source buffer contents into the bitstream ringbuffer */ |
1581 | mutex_lock(&ctx->bitstream_mutex); | 1663 | mutex_lock(&ctx->bitstream_mutex); |
1582 | coda_fill_bitstream(ctx); | 1664 | coda_fill_bitstream(ctx, true); |
1583 | mutex_unlock(&ctx->bitstream_mutex); | 1665 | mutex_unlock(&ctx->bitstream_mutex); |
1584 | 1666 | ||
1585 | if (coda_get_bitstream_payload(ctx) < 512 && | 1667 | if (coda_get_bitstream_payload(ctx) < 512 && |
@@ -1675,6 +1757,8 @@ static int coda_prepare_decode(struct coda_ctx *ctx) | |||
1675 | /* Clear decode success flag */ | 1757 | /* Clear decode success flag */ |
1676 | coda_write(dev, 0, CODA_RET_DEC_PIC_SUCCESS); | 1758 | coda_write(dev, 0, CODA_RET_DEC_PIC_SUCCESS); |
1677 | 1759 | ||
1760 | trace_coda_dec_pic_run(ctx, meta); | ||
1761 | |||
1678 | coda_command_async(ctx, CODA_COMMAND_PIC_RUN); | 1762 | coda_command_async(ctx, CODA_COMMAND_PIC_RUN); |
1679 | 1763 | ||
1680 | return 0; | 1764 | return 0; |
@@ -1704,7 +1788,7 @@ static void coda_finish_decode(struct coda_ctx *ctx) | |||
1704 | * by up to 512 bytes | 1788 | * by up to 512 bytes |
1705 | */ | 1789 | */ |
1706 | if (ctx->bit_stream_param & CODA_BIT_STREAM_END_FLAG) { | 1790 | if (ctx->bit_stream_param & CODA_BIT_STREAM_END_FLAG) { |
1707 | if (coda_get_bitstream_payload(ctx) >= CODA_MAX_FRAME_SIZE - 512) | 1791 | if (coda_get_bitstream_payload(ctx) >= ctx->bitstream.size - 512) |
1708 | kfifo_init(&ctx->bitstream_fifo, | 1792 | kfifo_init(&ctx->bitstream_fifo, |
1709 | ctx->bitstream.vaddr, ctx->bitstream.size); | 1793 | ctx->bitstream.vaddr, ctx->bitstream.size); |
1710 | } | 1794 | } |
@@ -1835,6 +1919,8 @@ static void coda_finish_decode(struct coda_ctx *ctx) | |||
1835 | } | 1919 | } |
1836 | mutex_unlock(&ctx->bitstream_mutex); | 1920 | mutex_unlock(&ctx->bitstream_mutex); |
1837 | 1921 | ||
1922 | trace_coda_dec_pic_done(ctx, &ctx->frame_metas[decoded_idx]); | ||
1923 | |||
1838 | val = coda_read(dev, CODA_RET_DEC_PIC_TYPE) & 0x7; | 1924 | val = coda_read(dev, CODA_RET_DEC_PIC_TYPE) & 0x7; |
1839 | if (val == 0) | 1925 | if (val == 0) |
1840 | ctx->frame_types[decoded_idx] = V4L2_BUF_FLAG_KEYFRAME; | 1926 | ctx->frame_types[decoded_idx] = V4L2_BUF_FLAG_KEYFRAME; |
@@ -1874,6 +1960,8 @@ static void coda_finish_decode(struct coda_ctx *ctx) | |||
1874 | dst_buf->v4l2_buf.timecode = meta->timecode; | 1960 | dst_buf->v4l2_buf.timecode = meta->timecode; |
1875 | dst_buf->v4l2_buf.timestamp = meta->timestamp; | 1961 | dst_buf->v4l2_buf.timestamp = meta->timestamp; |
1876 | 1962 | ||
1963 | trace_coda_dec_rot_done(ctx, meta, dst_buf); | ||
1964 | |||
1877 | switch (q_data_dst->fourcc) { | 1965 | switch (q_data_dst->fourcc) { |
1878 | case V4L2_PIX_FMT_YUV420: | 1966 | case V4L2_PIX_FMT_YUV420: |
1879 | case V4L2_PIX_FMT_YVU420: | 1967 | case V4L2_PIX_FMT_YVU420: |
@@ -1906,6 +1994,7 @@ static void coda_finish_decode(struct coda_ctx *ctx) | |||
1906 | 1994 | ||
1907 | const struct coda_context_ops coda_bit_decode_ops = { | 1995 | const struct coda_context_ops coda_bit_decode_ops = { |
1908 | .queue_init = coda_decoder_queue_init, | 1996 | .queue_init = coda_decoder_queue_init, |
1997 | .reqbufs = coda_decoder_reqbufs, | ||
1909 | .start_streaming = coda_start_decoding, | 1998 | .start_streaming = coda_start_decoding, |
1910 | .prepare_run = coda_prepare_decode, | 1999 | .prepare_run = coda_prepare_decode, |
1911 | .finish_run = coda_finish_decode, | 2000 | .finish_run = coda_finish_decode, |
@@ -1931,6 +2020,8 @@ irqreturn_t coda_irq_handler(int irq, void *data) | |||
1931 | return IRQ_HANDLED; | 2020 | return IRQ_HANDLED; |
1932 | } | 2021 | } |
1933 | 2022 | ||
2023 | trace_coda_bit_done(ctx); | ||
2024 | |||
1934 | if (ctx->aborting) { | 2025 | if (ctx->aborting) { |
1935 | v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev, | 2026 | v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev, |
1936 | "task has been aborted\n"); | 2027 | "task has been aborted\n"); |
diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index 6f32e6d6b156..8e6fe0200117 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c | |||
@@ -46,7 +46,6 @@ | |||
46 | #define CODADX6_MAX_INSTANCES 4 | 46 | #define CODADX6_MAX_INSTANCES 4 |
47 | #define CODA_MAX_FORMATS 4 | 47 | #define CODA_MAX_FORMATS 4 |
48 | 48 | ||
49 | #define CODA_PARA_BUF_SIZE (10 * 1024) | ||
50 | #define CODA_ISRAM_SIZE (2048 * 2) | 49 | #define CODA_ISRAM_SIZE (2048 * 2) |
51 | 50 | ||
52 | #define MIN_W 176 | 51 | #define MIN_W 176 |
@@ -696,6 +695,26 @@ static int coda_s_fmt_vid_out(struct file *file, void *priv, | |||
696 | return coda_s_fmt(ctx, &f_cap); | 695 | return coda_s_fmt(ctx, &f_cap); |
697 | } | 696 | } |
698 | 697 | ||
698 | static int coda_reqbufs(struct file *file, void *priv, | ||
699 | struct v4l2_requestbuffers *rb) | ||
700 | { | ||
701 | struct coda_ctx *ctx = fh_to_ctx(priv); | ||
702 | int ret; | ||
703 | |||
704 | ret = v4l2_m2m_reqbufs(file, ctx->fh.m2m_ctx, rb); | ||
705 | if (ret) | ||
706 | return ret; | ||
707 | |||
708 | /* | ||
709 | * Allow to allocate instance specific per-context buffers, such as | ||
710 | * bitstream ringbuffer, slice buffer, work buffer, etc. if needed. | ||
711 | */ | ||
712 | if (rb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && ctx->ops->reqbufs) | ||
713 | return ctx->ops->reqbufs(ctx, rb); | ||
714 | |||
715 | return 0; | ||
716 | } | ||
717 | |||
699 | static int coda_qbuf(struct file *file, void *priv, | 718 | static int coda_qbuf(struct file *file, void *priv, |
700 | struct v4l2_buffer *buf) | 719 | struct v4l2_buffer *buf) |
701 | { | 720 | { |
@@ -841,7 +860,7 @@ static const struct v4l2_ioctl_ops coda_ioctl_ops = { | |||
841 | .vidioc_try_fmt_vid_out = coda_try_fmt_vid_out, | 860 | .vidioc_try_fmt_vid_out = coda_try_fmt_vid_out, |
842 | .vidioc_s_fmt_vid_out = coda_s_fmt_vid_out, | 861 | .vidioc_s_fmt_vid_out = coda_s_fmt_vid_out, |
843 | 862 | ||
844 | .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, | 863 | .vidioc_reqbufs = coda_reqbufs, |
845 | .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, | 864 | .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, |
846 | 865 | ||
847 | .vidioc_qbuf = coda_qbuf, | 866 | .vidioc_qbuf = coda_qbuf, |
@@ -1173,7 +1192,7 @@ static void coda_buf_queue(struct vb2_buffer *vb) | |||
1173 | mutex_lock(&ctx->bitstream_mutex); | 1192 | mutex_lock(&ctx->bitstream_mutex); |
1174 | v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb); | 1193 | v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb); |
1175 | if (vb2_is_streaming(vb->vb2_queue)) | 1194 | if (vb2_is_streaming(vb->vb2_queue)) |
1176 | coda_fill_bitstream(ctx); | 1195 | coda_fill_bitstream(ctx, true); |
1177 | mutex_unlock(&ctx->bitstream_mutex); | 1196 | mutex_unlock(&ctx->bitstream_mutex); |
1178 | } else { | 1197 | } else { |
1179 | v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb); | 1198 | v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb); |
@@ -1215,8 +1234,9 @@ void coda_free_aux_buf(struct coda_dev *dev, | |||
1215 | buf->vaddr, buf->paddr); | 1234 | buf->vaddr, buf->paddr); |
1216 | buf->vaddr = NULL; | 1235 | buf->vaddr = NULL; |
1217 | buf->size = 0; | 1236 | buf->size = 0; |
1237 | debugfs_remove(buf->dentry); | ||
1238 | buf->dentry = NULL; | ||
1218 | } | 1239 | } |
1219 | debugfs_remove(buf->dentry); | ||
1220 | } | 1240 | } |
1221 | 1241 | ||
1222 | static int coda_start_streaming(struct vb2_queue *q, unsigned int count) | 1242 | static int coda_start_streaming(struct vb2_queue *q, unsigned int count) |
@@ -1232,9 +1252,9 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count) | |||
1232 | if (q_data_src->fourcc == V4L2_PIX_FMT_H264 || | 1252 | if (q_data_src->fourcc == V4L2_PIX_FMT_H264 || |
1233 | (q_data_src->fourcc == V4L2_PIX_FMT_JPEG && | 1253 | (q_data_src->fourcc == V4L2_PIX_FMT_JPEG && |
1234 | ctx->dev->devtype->product == CODA_7541)) { | 1254 | ctx->dev->devtype->product == CODA_7541)) { |
1235 | /* copy the buffers that where queued before streamon */ | 1255 | /* copy the buffers that were queued before streamon */ |
1236 | mutex_lock(&ctx->bitstream_mutex); | 1256 | mutex_lock(&ctx->bitstream_mutex); |
1237 | coda_fill_bitstream(ctx); | 1257 | coda_fill_bitstream(ctx, false); |
1238 | mutex_unlock(&ctx->bitstream_mutex); | 1258 | mutex_unlock(&ctx->bitstream_mutex); |
1239 | 1259 | ||
1240 | if (coda_get_bitstream_payload(ctx) < 512) { | 1260 | if (coda_get_bitstream_payload(ctx) < 512) { |
@@ -1262,12 +1282,23 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count) | |||
1262 | if (!(ctx->streamon_out & ctx->streamon_cap)) | 1282 | if (!(ctx->streamon_out & ctx->streamon_cap)) |
1263 | return 0; | 1283 | return 0; |
1264 | 1284 | ||
1285 | q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); | ||
1286 | if ((q_data_src->width != q_data_dst->width && | ||
1287 | round_up(q_data_src->width, 16) != q_data_dst->width) || | ||
1288 | (q_data_src->height != q_data_dst->height && | ||
1289 | round_up(q_data_src->height, 16) != q_data_dst->height)) { | ||
1290 | v4l2_err(v4l2_dev, "can't convert %dx%d to %dx%d\n", | ||
1291 | q_data_src->width, q_data_src->height, | ||
1292 | q_data_dst->width, q_data_dst->height); | ||
1293 | ret = -EINVAL; | ||
1294 | goto err; | ||
1295 | } | ||
1296 | |||
1265 | /* Allow BIT decoder device_run with no new buffers queued */ | 1297 | /* Allow BIT decoder device_run with no new buffers queued */ |
1266 | if (ctx->inst_type == CODA_INST_DECODER && ctx->use_bit) | 1298 | if (ctx->inst_type == CODA_INST_DECODER && ctx->use_bit) |
1267 | v4l2_m2m_set_src_buffered(ctx->fh.m2m_ctx, true); | 1299 | v4l2_m2m_set_src_buffered(ctx->fh.m2m_ctx, true); |
1268 | 1300 | ||
1269 | ctx->gopcounter = ctx->params.gop_size - 1; | 1301 | ctx->gopcounter = ctx->params.gop_size - 1; |
1270 | q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); | ||
1271 | 1302 | ||
1272 | ctx->codec = coda_find_codec(ctx->dev, q_data_src->fourcc, | 1303 | ctx->codec = coda_find_codec(ctx->dev, q_data_src->fourcc, |
1273 | q_data_dst->fourcc); | 1304 | q_data_dst->fourcc); |
@@ -1308,6 +1339,9 @@ static void coda_stop_streaming(struct vb2_queue *q) | |||
1308 | struct coda_ctx *ctx = vb2_get_drv_priv(q); | 1339 | struct coda_ctx *ctx = vb2_get_drv_priv(q); |
1309 | struct coda_dev *dev = ctx->dev; | 1340 | struct coda_dev *dev = ctx->dev; |
1310 | struct vb2_buffer *buf; | 1341 | struct vb2_buffer *buf; |
1342 | bool stop; | ||
1343 | |||
1344 | stop = ctx->streamon_out && ctx->streamon_cap; | ||
1311 | 1345 | ||
1312 | if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { | 1346 | if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { |
1313 | v4l2_dbg(1, coda_debug, &dev->v4l2_dev, | 1347 | v4l2_dbg(1, coda_debug, &dev->v4l2_dev, |
@@ -1332,7 +1366,7 @@ static void coda_stop_streaming(struct vb2_queue *q) | |||
1332 | v4l2_m2m_buf_done(buf, VB2_BUF_STATE_ERROR); | 1366 | v4l2_m2m_buf_done(buf, VB2_BUF_STATE_ERROR); |
1333 | } | 1367 | } |
1334 | 1368 | ||
1335 | if (!ctx->streamon_out && !ctx->streamon_cap) { | 1369 | if (stop) { |
1336 | struct coda_buffer_meta *meta; | 1370 | struct coda_buffer_meta *meta; |
1337 | 1371 | ||
1338 | if (ctx->ops->seq_end_work) { | 1372 | if (ctx->ops->seq_end_work) { |
@@ -1457,7 +1491,7 @@ static const struct v4l2_ctrl_ops coda_ctrl_ops = { | |||
1457 | static void coda_encode_ctrls(struct coda_ctx *ctx) | 1491 | static void coda_encode_ctrls(struct coda_ctx *ctx) |
1458 | { | 1492 | { |
1459 | v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, | 1493 | v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, |
1460 | V4L2_CID_MPEG_VIDEO_BITRATE, 0, 32767000, 1, 0); | 1494 | V4L2_CID_MPEG_VIDEO_BITRATE, 0, 32767000, 1000, 0); |
1461 | v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, | 1495 | v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, |
1462 | V4L2_CID_MPEG_VIDEO_GOP_SIZE, 1, 60, 1, 16); | 1496 | V4L2_CID_MPEG_VIDEO_GOP_SIZE, 1, 60, 1, 16); |
1463 | v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, | 1497 | v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, |
@@ -1541,6 +1575,13 @@ static int coda_queue_init(struct coda_ctx *ctx, struct vb2_queue *vq) | |||
1541 | vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); | 1575 | vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); |
1542 | vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; | 1576 | vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; |
1543 | vq->lock = &ctx->dev->dev_mutex; | 1577 | vq->lock = &ctx->dev->dev_mutex; |
1578 | /* One way to indicate end-of-stream for coda is to set the | ||
1579 | * bytesused == 0. However by default videobuf2 handles bytesused | ||
1580 | * equal to 0 as a special case and changes its value to the size | ||
1581 | * of the buffer. Set the allow_zero_bytesused flag, so | ||
1582 | * that videobuf2 will keep the value of bytesused intact. | ||
1583 | */ | ||
1584 | vq->allow_zero_bytesused = 1; | ||
1544 | 1585 | ||
1545 | return vb2_queue_init(vq); | 1586 | return vb2_queue_init(vq); |
1546 | } | 1587 | } |
@@ -1621,6 +1662,11 @@ static int coda_open(struct file *file) | |||
1621 | set_bit(idx, &dev->instance_mask); | 1662 | set_bit(idx, &dev->instance_mask); |
1622 | 1663 | ||
1623 | name = kasprintf(GFP_KERNEL, "context%d", idx); | 1664 | name = kasprintf(GFP_KERNEL, "context%d", idx); |
1665 | if (!name) { | ||
1666 | ret = -ENOMEM; | ||
1667 | goto err_coda_name_init; | ||
1668 | } | ||
1669 | |||
1624 | ctx->debugfs_entry = debugfs_create_dir(name, dev->debugfs_root); | 1670 | ctx->debugfs_entry = debugfs_create_dir(name, dev->debugfs_root); |
1625 | kfree(name); | 1671 | kfree(name); |
1626 | 1672 | ||
@@ -1682,28 +1728,6 @@ static int coda_open(struct file *file) | |||
1682 | 1728 | ||
1683 | ctx->fh.ctrl_handler = &ctx->ctrls; | 1729 | ctx->fh.ctrl_handler = &ctx->ctrls; |
1684 | 1730 | ||
1685 | if (ctx->use_bit) { | ||
1686 | ret = coda_alloc_context_buf(ctx, &ctx->parabuf, | ||
1687 | CODA_PARA_BUF_SIZE, "parabuf"); | ||
1688 | if (ret < 0) { | ||
1689 | v4l2_err(&dev->v4l2_dev, "failed to allocate parabuf"); | ||
1690 | goto err_dma_alloc; | ||
1691 | } | ||
1692 | } | ||
1693 | if (ctx->use_bit && ctx->inst_type == CODA_INST_DECODER) { | ||
1694 | ctx->bitstream.size = CODA_MAX_FRAME_SIZE; | ||
1695 | ctx->bitstream.vaddr = dma_alloc_writecombine( | ||
1696 | &dev->plat_dev->dev, ctx->bitstream.size, | ||
1697 | &ctx->bitstream.paddr, GFP_KERNEL); | ||
1698 | if (!ctx->bitstream.vaddr) { | ||
1699 | v4l2_err(&dev->v4l2_dev, | ||
1700 | "failed to allocate bitstream ringbuffer"); | ||
1701 | ret = -ENOMEM; | ||
1702 | goto err_dma_writecombine; | ||
1703 | } | ||
1704 | } | ||
1705 | kfifo_init(&ctx->bitstream_fifo, | ||
1706 | ctx->bitstream.vaddr, ctx->bitstream.size); | ||
1707 | mutex_init(&ctx->bitstream_mutex); | 1731 | mutex_init(&ctx->bitstream_mutex); |
1708 | mutex_init(&ctx->buffer_mutex); | 1732 | mutex_init(&ctx->buffer_mutex); |
1709 | INIT_LIST_HEAD(&ctx->buffer_meta_list); | 1733 | INIT_LIST_HEAD(&ctx->buffer_meta_list); |
@@ -1717,12 +1741,6 @@ static int coda_open(struct file *file) | |||
1717 | 1741 | ||
1718 | return 0; | 1742 | return 0; |
1719 | 1743 | ||
1720 | err_dma_writecombine: | ||
1721 | if (ctx->dev->devtype->product == CODA_DX6) | ||
1722 | coda_free_aux_buf(dev, &ctx->workbuf); | ||
1723 | coda_free_aux_buf(dev, &ctx->parabuf); | ||
1724 | err_dma_alloc: | ||
1725 | v4l2_ctrl_handler_free(&ctx->ctrls); | ||
1726 | err_ctrls_setup: | 1744 | err_ctrls_setup: |
1727 | v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); | 1745 | v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); |
1728 | err_ctx_init: | 1746 | err_ctx_init: |
@@ -1735,6 +1753,7 @@ err_pm_get: | |||
1735 | v4l2_fh_del(&ctx->fh); | 1753 | v4l2_fh_del(&ctx->fh); |
1736 | v4l2_fh_exit(&ctx->fh); | 1754 | v4l2_fh_exit(&ctx->fh); |
1737 | clear_bit(ctx->idx, &dev->instance_mask); | 1755 | clear_bit(ctx->idx, &dev->instance_mask); |
1756 | err_coda_name_init: | ||
1738 | err_coda_max: | 1757 | err_coda_max: |
1739 | kfree(ctx); | 1758 | kfree(ctx); |
1740 | return ret; | 1759 | return ret; |
@@ -1764,14 +1783,9 @@ static int coda_release(struct file *file) | |||
1764 | list_del(&ctx->list); | 1783 | list_del(&ctx->list); |
1765 | coda_unlock(ctx); | 1784 | coda_unlock(ctx); |
1766 | 1785 | ||
1767 | if (ctx->bitstream.vaddr) { | ||
1768 | dma_free_writecombine(&dev->plat_dev->dev, ctx->bitstream.size, | ||
1769 | ctx->bitstream.vaddr, ctx->bitstream.paddr); | ||
1770 | } | ||
1771 | if (ctx->dev->devtype->product == CODA_DX6) | 1786 | if (ctx->dev->devtype->product == CODA_DX6) |
1772 | coda_free_aux_buf(dev, &ctx->workbuf); | 1787 | coda_free_aux_buf(dev, &ctx->workbuf); |
1773 | 1788 | ||
1774 | coda_free_aux_buf(dev, &ctx->parabuf); | ||
1775 | v4l2_ctrl_handler_free(&ctx->ctrls); | 1789 | v4l2_ctrl_handler_free(&ctx->ctrls); |
1776 | clk_disable_unprepare(dev->clk_ahb); | 1790 | clk_disable_unprepare(dev->clk_ahb); |
1777 | clk_disable_unprepare(dev->clk_per); | 1791 | clk_disable_unprepare(dev->clk_per); |
@@ -1901,8 +1915,7 @@ static int coda_register_device(struct coda_dev *dev, int i) | |||
1901 | if (i >= dev->devtype->num_vdevs) | 1915 | if (i >= dev->devtype->num_vdevs) |
1902 | return -EINVAL; | 1916 | return -EINVAL; |
1903 | 1917 | ||
1904 | snprintf(vfd->name, sizeof(vfd->name), "%s", | 1918 | strlcpy(vfd->name, dev->devtype->vdevs[i]->name, sizeof(vfd->name)); |
1905 | dev->devtype->vdevs[i]->name); | ||
1906 | vfd->fops = &coda_fops; | 1919 | vfd->fops = &coda_fops; |
1907 | vfd->ioctl_ops = &coda_ioctl_ops; | 1920 | vfd->ioctl_ops = &coda_ioctl_ops; |
1908 | vfd->release = video_device_release_empty, | 1921 | vfd->release = video_device_release_empty, |
@@ -1933,10 +1946,8 @@ static void coda_fw_callback(const struct firmware *fw, void *context) | |||
1933 | /* allocate auxiliary per-device code buffer for the BIT processor */ | 1946 | /* allocate auxiliary per-device code buffer for the BIT processor */ |
1934 | ret = coda_alloc_aux_buf(dev, &dev->codebuf, fw->size, "codebuf", | 1947 | ret = coda_alloc_aux_buf(dev, &dev->codebuf, fw->size, "codebuf", |
1935 | dev->debugfs_root); | 1948 | dev->debugfs_root); |
1936 | if (ret < 0) { | 1949 | if (ret < 0) |
1937 | dev_err(&pdev->dev, "failed to allocate code buffer\n"); | ||
1938 | goto put_pm; | 1950 | goto put_pm; |
1939 | } | ||
1940 | 1951 | ||
1941 | /* Copy the whole firmware image to the code buffer */ | 1952 | /* Copy the whole firmware image to the code buffer */ |
1942 | memcpy(dev->codebuf.vaddr, fw->data, fw->size); | 1953 | memcpy(dev->codebuf.vaddr, fw->data, fw->size); |
@@ -2174,20 +2185,16 @@ static int coda_probe(struct platform_device *pdev) | |||
2174 | ret = coda_alloc_aux_buf(dev, &dev->workbuf, | 2185 | ret = coda_alloc_aux_buf(dev, &dev->workbuf, |
2175 | dev->devtype->workbuf_size, "workbuf", | 2186 | dev->devtype->workbuf_size, "workbuf", |
2176 | dev->debugfs_root); | 2187 | dev->debugfs_root); |
2177 | if (ret < 0) { | 2188 | if (ret < 0) |
2178 | dev_err(&pdev->dev, "failed to allocate work buffer\n"); | ||
2179 | goto err_v4l2_register; | 2189 | goto err_v4l2_register; |
2180 | } | ||
2181 | } | 2190 | } |
2182 | 2191 | ||
2183 | if (dev->devtype->tempbuf_size) { | 2192 | if (dev->devtype->tempbuf_size) { |
2184 | ret = coda_alloc_aux_buf(dev, &dev->tempbuf, | 2193 | ret = coda_alloc_aux_buf(dev, &dev->tempbuf, |
2185 | dev->devtype->tempbuf_size, "tempbuf", | 2194 | dev->devtype->tempbuf_size, "tempbuf", |
2186 | dev->debugfs_root); | 2195 | dev->debugfs_root); |
2187 | if (ret < 0) { | 2196 | if (ret < 0) |
2188 | dev_err(&pdev->dev, "failed to allocate temp buffer\n"); | ||
2189 | goto err_v4l2_register; | 2197 | goto err_v4l2_register; |
2190 | } | ||
2191 | } | 2198 | } |
2192 | 2199 | ||
2193 | dev->iram.size = dev->devtype->iram_size; | 2200 | dev->iram.size = dev->devtype->iram_size; |
diff --git a/drivers/media/platform/coda/coda-jpeg.c b/drivers/media/platform/coda/coda-jpeg.c index 8fa3e353f9e2..11e734bc2cbd 100644 --- a/drivers/media/platform/coda/coda-jpeg.c +++ b/drivers/media/platform/coda/coda-jpeg.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/swab.h> | 13 | #include <linux/swab.h> |
14 | 14 | ||
15 | #include "coda.h" | 15 | #include "coda.h" |
16 | #include "trace.h" | ||
16 | 17 | ||
17 | #define SOI_MARKER 0xffd8 | 18 | #define SOI_MARKER 0xffd8 |
18 | #define EOI_MARKER 0xffd9 | 19 | #define EOI_MARKER 0xffd9 |
diff --git a/drivers/media/platform/coda/coda.h b/drivers/media/platform/coda/coda.h index 0c35cd5032ff..6a5c8f6c688e 100644 --- a/drivers/media/platform/coda/coda.h +++ b/drivers/media/platform/coda/coda.h | |||
@@ -12,6 +12,9 @@ | |||
12 | * (at your option) any later version. | 12 | * (at your option) any later version. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #ifndef __CODA_H__ | ||
16 | #define __CODA_H__ | ||
17 | |||
15 | #include <linux/debugfs.h> | 18 | #include <linux/debugfs.h> |
16 | #include <linux/irqreturn.h> | 19 | #include <linux/irqreturn.h> |
17 | #include <linux/mutex.h> | 20 | #include <linux/mutex.h> |
@@ -26,7 +29,6 @@ | |||
26 | #include "coda_regs.h" | 29 | #include "coda_regs.h" |
27 | 30 | ||
28 | #define CODA_MAX_FRAMEBUFFERS 8 | 31 | #define CODA_MAX_FRAMEBUFFERS 8 |
29 | #define CODA_MAX_FRAME_SIZE 0x100000 | ||
30 | #define FMO_SLICE_SAVE_BUF_SIZE (32) | 32 | #define FMO_SLICE_SAVE_BUF_SIZE (32) |
31 | 33 | ||
32 | enum { | 34 | enum { |
@@ -178,6 +180,7 @@ struct coda_ctx; | |||
178 | struct coda_context_ops { | 180 | struct coda_context_ops { |
179 | int (*queue_init)(void *priv, struct vb2_queue *src_vq, | 181 | int (*queue_init)(void *priv, struct vb2_queue *src_vq, |
180 | struct vb2_queue *dst_vq); | 182 | struct vb2_queue *dst_vq); |
183 | int (*reqbufs)(struct coda_ctx *ctx, struct v4l2_requestbuffers *rb); | ||
181 | int (*start_streaming)(struct coda_ctx *ctx); | 184 | int (*start_streaming)(struct coda_ctx *ctx); |
182 | int (*prepare_run)(struct coda_ctx *ctx); | 185 | int (*prepare_run)(struct coda_ctx *ctx); |
183 | void (*finish_run)(struct coda_ctx *ctx); | 186 | void (*finish_run)(struct coda_ctx *ctx); |
@@ -249,13 +252,6 @@ int coda_alloc_aux_buf(struct coda_dev *dev, struct coda_aux_buf *buf, | |||
249 | size_t size, const char *name, struct dentry *parent); | 252 | size_t size, const char *name, struct dentry *parent); |
250 | void coda_free_aux_buf(struct coda_dev *dev, struct coda_aux_buf *buf); | 253 | void coda_free_aux_buf(struct coda_dev *dev, struct coda_aux_buf *buf); |
251 | 254 | ||
252 | static inline int coda_alloc_context_buf(struct coda_ctx *ctx, | ||
253 | struct coda_aux_buf *buf, size_t size, | ||
254 | const char *name) | ||
255 | { | ||
256 | return coda_alloc_aux_buf(ctx->dev, buf, size, name, ctx->debugfs_entry); | ||
257 | } | ||
258 | |||
259 | int coda_encoder_queue_init(void *priv, struct vb2_queue *src_vq, | 255 | int coda_encoder_queue_init(void *priv, struct vb2_queue *src_vq, |
260 | struct vb2_queue *dst_vq); | 256 | struct vb2_queue *dst_vq); |
261 | int coda_decoder_queue_init(void *priv, struct vb2_queue *src_vq, | 257 | int coda_decoder_queue_init(void *priv, struct vb2_queue *src_vq, |
@@ -263,7 +259,7 @@ int coda_decoder_queue_init(void *priv, struct vb2_queue *src_vq, | |||
263 | 259 | ||
264 | int coda_hw_reset(struct coda_ctx *ctx); | 260 | int coda_hw_reset(struct coda_ctx *ctx); |
265 | 261 | ||
266 | void coda_fill_bitstream(struct coda_ctx *ctx); | 262 | void coda_fill_bitstream(struct coda_ctx *ctx, bool streaming); |
267 | 263 | ||
268 | void coda_set_gdi_regs(struct coda_ctx *ctx); | 264 | void coda_set_gdi_regs(struct coda_ctx *ctx); |
269 | 265 | ||
@@ -284,7 +280,7 @@ const char *coda_product_name(int product); | |||
284 | 280 | ||
285 | int coda_check_firmware(struct coda_dev *dev); | 281 | int coda_check_firmware(struct coda_dev *dev); |
286 | 282 | ||
287 | static inline int coda_get_bitstream_payload(struct coda_ctx *ctx) | 283 | static inline unsigned int coda_get_bitstream_payload(struct coda_ctx *ctx) |
288 | { | 284 | { |
289 | return kfifo_len(&ctx->bitstream_fifo); | 285 | return kfifo_len(&ctx->bitstream_fifo); |
290 | } | 286 | } |
@@ -301,3 +297,5 @@ extern const struct coda_context_ops coda_bit_encode_ops; | |||
301 | extern const struct coda_context_ops coda_bit_decode_ops; | 297 | extern const struct coda_context_ops coda_bit_decode_ops; |
302 | 298 | ||
303 | irqreturn_t coda_irq_handler(int irq, void *data); | 299 | irqreturn_t coda_irq_handler(int irq, void *data); |
300 | |||
301 | #endif /* __CODA_H__ */ | ||
diff --git a/drivers/media/platform/coda/trace.h b/drivers/media/platform/coda/trace.h new file mode 100644 index 000000000000..d1d06cbd1f6a --- /dev/null +++ b/drivers/media/platform/coda/trace.h | |||
@@ -0,0 +1,203 @@ | |||
1 | #undef TRACE_SYSTEM | ||
2 | #define TRACE_SYSTEM coda | ||
3 | |||
4 | #if !defined(__CODA_TRACE_H__) || defined(TRACE_HEADER_MULTI_READ) | ||
5 | #define __CODA_TRACE_H__ | ||
6 | |||
7 | #include <linux/tracepoint.h> | ||
8 | #include <media/videobuf2-core.h> | ||
9 | |||
10 | #include "coda.h" | ||
11 | |||
12 | #define TRACE_SYSTEM_STRING __stringify(TRACE_SYSTEM) | ||
13 | |||
14 | TRACE_EVENT(coda_bit_run, | ||
15 | TP_PROTO(struct coda_ctx *ctx, int cmd), | ||
16 | |||
17 | TP_ARGS(ctx, cmd), | ||
18 | |||
19 | TP_STRUCT__entry( | ||
20 | __field(int, minor) | ||
21 | __field(int, ctx) | ||
22 | __field(int, cmd) | ||
23 | ), | ||
24 | |||
25 | TP_fast_assign( | ||
26 | __entry->minor = ctx->fh.vdev->minor; | ||
27 | __entry->ctx = ctx->idx; | ||
28 | __entry->cmd = cmd; | ||
29 | ), | ||
30 | |||
31 | TP_printk("minor = %d, ctx = %d, cmd = %d", | ||
32 | __entry->minor, __entry->ctx, __entry->cmd) | ||
33 | ); | ||
34 | |||
35 | TRACE_EVENT(coda_bit_done, | ||
36 | TP_PROTO(struct coda_ctx *ctx), | ||
37 | |||
38 | TP_ARGS(ctx), | ||
39 | |||
40 | TP_STRUCT__entry( | ||
41 | __field(int, minor) | ||
42 | __field(int, ctx) | ||
43 | ), | ||
44 | |||
45 | TP_fast_assign( | ||
46 | __entry->minor = ctx->fh.vdev->minor; | ||
47 | __entry->ctx = ctx->idx; | ||
48 | ), | ||
49 | |||
50 | TP_printk("minor = %d, ctx = %d", __entry->minor, __entry->ctx) | ||
51 | ); | ||
52 | |||
53 | TRACE_EVENT(coda_enc_pic_run, | ||
54 | TP_PROTO(struct coda_ctx *ctx, struct vb2_buffer *buf), | ||
55 | |||
56 | TP_ARGS(ctx, buf), | ||
57 | |||
58 | TP_STRUCT__entry( | ||
59 | __field(int, minor) | ||
60 | __field(int, index) | ||
61 | __field(int, ctx) | ||
62 | ), | ||
63 | |||
64 | TP_fast_assign( | ||
65 | __entry->minor = ctx->fh.vdev->minor; | ||
66 | __entry->index = buf->v4l2_buf.index; | ||
67 | __entry->ctx = ctx->idx; | ||
68 | ), | ||
69 | |||
70 | TP_printk("minor = %d, index = %d, ctx = %d", | ||
71 | __entry->minor, __entry->index, __entry->ctx) | ||
72 | ); | ||
73 | |||
74 | TRACE_EVENT(coda_enc_pic_done, | ||
75 | TP_PROTO(struct coda_ctx *ctx, struct vb2_buffer *buf), | ||
76 | |||
77 | TP_ARGS(ctx, buf), | ||
78 | |||
79 | TP_STRUCT__entry( | ||
80 | __field(int, minor) | ||
81 | __field(int, index) | ||
82 | __field(int, ctx) | ||
83 | ), | ||
84 | |||
85 | TP_fast_assign( | ||
86 | __entry->minor = ctx->fh.vdev->minor; | ||
87 | __entry->index = buf->v4l2_buf.index; | ||
88 | __entry->ctx = ctx->idx; | ||
89 | ), | ||
90 | |||
91 | TP_printk("minor = %d, index = %d, ctx = %d", | ||
92 | __entry->minor, __entry->index, __entry->ctx) | ||
93 | ); | ||
94 | |||
95 | TRACE_EVENT(coda_bit_queue, | ||
96 | TP_PROTO(struct coda_ctx *ctx, struct vb2_buffer *buf, | ||
97 | struct coda_buffer_meta *meta), | ||
98 | |||
99 | TP_ARGS(ctx, buf, meta), | ||
100 | |||
101 | TP_STRUCT__entry( | ||
102 | __field(int, minor) | ||
103 | __field(int, index) | ||
104 | __field(int, start) | ||
105 | __field(int, end) | ||
106 | __field(int, ctx) | ||
107 | ), | ||
108 | |||
109 | TP_fast_assign( | ||
110 | __entry->minor = ctx->fh.vdev->minor; | ||
111 | __entry->index = buf->v4l2_buf.index; | ||
112 | __entry->start = meta->start; | ||
113 | __entry->end = meta->end; | ||
114 | __entry->ctx = ctx->idx; | ||
115 | ), | ||
116 | |||
117 | TP_printk("minor = %d, index = %d, start = 0x%x, end = 0x%x, ctx = %d", | ||
118 | __entry->minor, __entry->index, __entry->start, __entry->end, | ||
119 | __entry->ctx) | ||
120 | ); | ||
121 | |||
122 | TRACE_EVENT(coda_dec_pic_run, | ||
123 | TP_PROTO(struct coda_ctx *ctx, struct coda_buffer_meta *meta), | ||
124 | |||
125 | TP_ARGS(ctx, meta), | ||
126 | |||
127 | TP_STRUCT__entry( | ||
128 | __field(int, minor) | ||
129 | __field(int, start) | ||
130 | __field(int, end) | ||
131 | __field(int, ctx) | ||
132 | ), | ||
133 | |||
134 | TP_fast_assign( | ||
135 | __entry->minor = ctx->fh.vdev->minor; | ||
136 | __entry->start = meta ? meta->start : 0; | ||
137 | __entry->end = meta ? meta->end : 0; | ||
138 | __entry->ctx = ctx->idx; | ||
139 | ), | ||
140 | |||
141 | TP_printk("minor = %d, start = 0x%x, end = 0x%x, ctx = %d", | ||
142 | __entry->minor, __entry->start, __entry->end, __entry->ctx) | ||
143 | ); | ||
144 | |||
145 | TRACE_EVENT(coda_dec_pic_done, | ||
146 | TP_PROTO(struct coda_ctx *ctx, struct coda_buffer_meta *meta), | ||
147 | |||
148 | TP_ARGS(ctx, meta), | ||
149 | |||
150 | TP_STRUCT__entry( | ||
151 | __field(int, minor) | ||
152 | __field(int, start) | ||
153 | __field(int, end) | ||
154 | __field(int, ctx) | ||
155 | ), | ||
156 | |||
157 | TP_fast_assign( | ||
158 | __entry->minor = ctx->fh.vdev->minor; | ||
159 | __entry->start = meta->start; | ||
160 | __entry->end = meta->end; | ||
161 | __entry->ctx = ctx->idx; | ||
162 | ), | ||
163 | |||
164 | TP_printk("minor = %d, start = 0x%x, end = 0x%x, ctx = %d", | ||
165 | __entry->minor, __entry->start, __entry->end, __entry->ctx) | ||
166 | ); | ||
167 | |||
168 | TRACE_EVENT(coda_dec_rot_done, | ||
169 | TP_PROTO(struct coda_ctx *ctx, struct coda_buffer_meta *meta, | ||
170 | struct vb2_buffer *buf), | ||
171 | |||
172 | TP_ARGS(ctx, meta, buf), | ||
173 | |||
174 | TP_STRUCT__entry( | ||
175 | __field(int, minor) | ||
176 | __field(int, start) | ||
177 | __field(int, end) | ||
178 | __field(int, index) | ||
179 | __field(int, ctx) | ||
180 | ), | ||
181 | |||
182 | TP_fast_assign( | ||
183 | __entry->minor = ctx->fh.vdev->minor; | ||
184 | __entry->start = meta->start; | ||
185 | __entry->end = meta->end; | ||
186 | __entry->index = buf->v4l2_buf.index; | ||
187 | __entry->ctx = ctx->idx; | ||
188 | ), | ||
189 | |||
190 | TP_printk("minor = %d, start = 0x%x, end = 0x%x, index = %d, ctx = %d", | ||
191 | __entry->minor, __entry->start, __entry->end, __entry->index, | ||
192 | __entry->ctx) | ||
193 | ); | ||
194 | |||
195 | #endif /* __CODA_TRACE_H__ */ | ||
196 | |||
197 | #undef TRACE_INCLUDE_PATH | ||
198 | #define TRACE_INCLUDE_PATH . | ||
199 | #undef TRACE_INCLUDE_FILE | ||
200 | #define TRACE_INCLUDE_FILE trace | ||
201 | |||
202 | /* This part must be outside protection */ | ||
203 | #include <trace/define_trace.h> | ||
diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c index b41bf7e822c8..ccfcf3f528d3 100644 --- a/drivers/media/platform/davinci/vpfe_capture.c +++ b/drivers/media/platform/davinci/vpfe_capture.c | |||
@@ -1871,16 +1871,9 @@ static int vpfe_probe(struct platform_device *pdev) | |||
1871 | goto probe_free_ccdc_cfg_mem; | 1871 | goto probe_free_ccdc_cfg_mem; |
1872 | } | 1872 | } |
1873 | 1873 | ||
1874 | /* Allocate memory for video device */ | 1874 | vfd = &vpfe_dev->video_dev; |
1875 | vfd = video_device_alloc(); | ||
1876 | if (NULL == vfd) { | ||
1877 | ret = -ENOMEM; | ||
1878 | v4l2_err(pdev->dev.driver, "Unable to alloc video device\n"); | ||
1879 | goto probe_out_release_irq; | ||
1880 | } | ||
1881 | |||
1882 | /* Initialize field of video device */ | 1875 | /* Initialize field of video device */ |
1883 | vfd->release = video_device_release; | 1876 | vfd->release = video_device_release_empty; |
1884 | vfd->fops = &vpfe_fops; | 1877 | vfd->fops = &vpfe_fops; |
1885 | vfd->ioctl_ops = &vpfe_ioctl_ops; | 1878 | vfd->ioctl_ops = &vpfe_ioctl_ops; |
1886 | vfd->tvnorms = 0; | 1879 | vfd->tvnorms = 0; |
@@ -1891,14 +1884,12 @@ static int vpfe_probe(struct platform_device *pdev) | |||
1891 | (VPFE_CAPTURE_VERSION_CODE >> 16) & 0xff, | 1884 | (VPFE_CAPTURE_VERSION_CODE >> 16) & 0xff, |
1892 | (VPFE_CAPTURE_VERSION_CODE >> 8) & 0xff, | 1885 | (VPFE_CAPTURE_VERSION_CODE >> 8) & 0xff, |
1893 | (VPFE_CAPTURE_VERSION_CODE) & 0xff); | 1886 | (VPFE_CAPTURE_VERSION_CODE) & 0xff); |
1894 | /* Set video_dev to the video device */ | ||
1895 | vpfe_dev->video_dev = vfd; | ||
1896 | 1887 | ||
1897 | ret = v4l2_device_register(&pdev->dev, &vpfe_dev->v4l2_dev); | 1888 | ret = v4l2_device_register(&pdev->dev, &vpfe_dev->v4l2_dev); |
1898 | if (ret) { | 1889 | if (ret) { |
1899 | v4l2_err(pdev->dev.driver, | 1890 | v4l2_err(pdev->dev.driver, |
1900 | "Unable to register v4l2 device.\n"); | 1891 | "Unable to register v4l2 device.\n"); |
1901 | goto probe_out_video_release; | 1892 | goto probe_out_release_irq; |
1902 | } | 1893 | } |
1903 | v4l2_info(&vpfe_dev->v4l2_dev, "v4l2 device registered\n"); | 1894 | v4l2_info(&vpfe_dev->v4l2_dev, "v4l2 device registered\n"); |
1904 | spin_lock_init(&vpfe_dev->irqlock); | 1895 | spin_lock_init(&vpfe_dev->irqlock); |
@@ -1914,7 +1905,7 @@ static int vpfe_probe(struct platform_device *pdev) | |||
1914 | v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, | 1905 | v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, |
1915 | "video_dev=%p\n", &vpfe_dev->video_dev); | 1906 | "video_dev=%p\n", &vpfe_dev->video_dev); |
1916 | vpfe_dev->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1907 | vpfe_dev->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
1917 | ret = video_register_device(vpfe_dev->video_dev, | 1908 | ret = video_register_device(&vpfe_dev->video_dev, |
1918 | VFL_TYPE_GRABBER, -1); | 1909 | VFL_TYPE_GRABBER, -1); |
1919 | 1910 | ||
1920 | if (ret) { | 1911 | if (ret) { |
@@ -1927,7 +1918,7 @@ static int vpfe_probe(struct platform_device *pdev) | |||
1927 | /* set the driver data in platform device */ | 1918 | /* set the driver data in platform device */ |
1928 | platform_set_drvdata(pdev, vpfe_dev); | 1919 | platform_set_drvdata(pdev, vpfe_dev); |
1929 | /* set driver private data */ | 1920 | /* set driver private data */ |
1930 | video_set_drvdata(vpfe_dev->video_dev, vpfe_dev); | 1921 | video_set_drvdata(&vpfe_dev->video_dev, vpfe_dev); |
1931 | i2c_adap = i2c_get_adapter(vpfe_cfg->i2c_adapter_id); | 1922 | i2c_adap = i2c_get_adapter(vpfe_cfg->i2c_adapter_id); |
1932 | num_subdevs = vpfe_cfg->num_subdevs; | 1923 | num_subdevs = vpfe_cfg->num_subdevs; |
1933 | vpfe_dev->sd = kmalloc(sizeof(struct v4l2_subdev *) * num_subdevs, | 1924 | vpfe_dev->sd = kmalloc(sizeof(struct v4l2_subdev *) * num_subdevs, |
@@ -1979,12 +1970,9 @@ static int vpfe_probe(struct platform_device *pdev) | |||
1979 | probe_sd_out: | 1970 | probe_sd_out: |
1980 | kfree(vpfe_dev->sd); | 1971 | kfree(vpfe_dev->sd); |
1981 | probe_out_video_unregister: | 1972 | probe_out_video_unregister: |
1982 | video_unregister_device(vpfe_dev->video_dev); | 1973 | video_unregister_device(&vpfe_dev->video_dev); |
1983 | probe_out_v4l2_unregister: | 1974 | probe_out_v4l2_unregister: |
1984 | v4l2_device_unregister(&vpfe_dev->v4l2_dev); | 1975 | v4l2_device_unregister(&vpfe_dev->v4l2_dev); |
1985 | probe_out_video_release: | ||
1986 | if (!video_is_registered(vpfe_dev->video_dev)) | ||
1987 | video_device_release(vpfe_dev->video_dev); | ||
1988 | probe_out_release_irq: | 1976 | probe_out_release_irq: |
1989 | free_irq(vpfe_dev->ccdc_irq0, vpfe_dev); | 1977 | free_irq(vpfe_dev->ccdc_irq0, vpfe_dev); |
1990 | probe_free_ccdc_cfg_mem: | 1978 | probe_free_ccdc_cfg_mem: |
@@ -2007,7 +1995,7 @@ static int vpfe_remove(struct platform_device *pdev) | |||
2007 | free_irq(vpfe_dev->ccdc_irq0, vpfe_dev); | 1995 | free_irq(vpfe_dev->ccdc_irq0, vpfe_dev); |
2008 | kfree(vpfe_dev->sd); | 1996 | kfree(vpfe_dev->sd); |
2009 | v4l2_device_unregister(&vpfe_dev->v4l2_dev); | 1997 | v4l2_device_unregister(&vpfe_dev->v4l2_dev); |
2010 | video_unregister_device(vpfe_dev->video_dev); | 1998 | video_unregister_device(&vpfe_dev->video_dev); |
2011 | kfree(vpfe_dev); | 1999 | kfree(vpfe_dev); |
2012 | kfree(ccdc_cfg); | 2000 | kfree(ccdc_cfg); |
2013 | return 0; | 2001 | return 0; |
diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c index fa0a51521772..a5f548138b91 100644 --- a/drivers/media/platform/davinci/vpif_capture.c +++ b/drivers/media/platform/davinci/vpif_capture.c | |||
@@ -712,7 +712,7 @@ static int vpif_set_input( | |||
712 | ch->vpifparams.iface = chan_cfg->vpif_if; | 712 | ch->vpifparams.iface = chan_cfg->vpif_if; |
713 | 713 | ||
714 | /* update tvnorms from the sub device input info */ | 714 | /* update tvnorms from the sub device input info */ |
715 | ch->video_dev->tvnorms = chan_cfg->inputs[index].input.std; | 715 | ch->video_dev.tvnorms = chan_cfg->inputs[index].input.std; |
716 | return 0; | 716 | return 0; |
717 | } | 717 | } |
718 | 718 | ||
@@ -1337,7 +1337,7 @@ static int vpif_probe_complete(void) | |||
1337 | struct video_device *vdev; | 1337 | struct video_device *vdev; |
1338 | struct channel_obj *ch; | 1338 | struct channel_obj *ch; |
1339 | struct vb2_queue *q; | 1339 | struct vb2_queue *q; |
1340 | int i, j, err, k; | 1340 | int j, err, k; |
1341 | 1341 | ||
1342 | for (j = 0; j < VPIF_CAPTURE_MAX_DEVICES; j++) { | 1342 | for (j = 0; j < VPIF_CAPTURE_MAX_DEVICES; j++) { |
1343 | ch = vpif_obj.dev[j]; | 1343 | ch = vpif_obj.dev[j]; |
@@ -1384,16 +1384,16 @@ static int vpif_probe_complete(void) | |||
1384 | INIT_LIST_HEAD(&common->dma_queue); | 1384 | INIT_LIST_HEAD(&common->dma_queue); |
1385 | 1385 | ||
1386 | /* Initialize the video_device structure */ | 1386 | /* Initialize the video_device structure */ |
1387 | vdev = ch->video_dev; | 1387 | vdev = &ch->video_dev; |
1388 | strlcpy(vdev->name, VPIF_DRIVER_NAME, sizeof(vdev->name)); | 1388 | strlcpy(vdev->name, VPIF_DRIVER_NAME, sizeof(vdev->name)); |
1389 | vdev->release = video_device_release; | 1389 | vdev->release = video_device_release_empty; |
1390 | vdev->fops = &vpif_fops; | 1390 | vdev->fops = &vpif_fops; |
1391 | vdev->ioctl_ops = &vpif_ioctl_ops; | 1391 | vdev->ioctl_ops = &vpif_ioctl_ops; |
1392 | vdev->v4l2_dev = &vpif_obj.v4l2_dev; | 1392 | vdev->v4l2_dev = &vpif_obj.v4l2_dev; |
1393 | vdev->vfl_dir = VFL_DIR_RX; | 1393 | vdev->vfl_dir = VFL_DIR_RX; |
1394 | vdev->queue = q; | 1394 | vdev->queue = q; |
1395 | vdev->lock = &common->lock; | 1395 | vdev->lock = &common->lock; |
1396 | video_set_drvdata(ch->video_dev, ch); | 1396 | video_set_drvdata(&ch->video_dev, ch); |
1397 | err = video_register_device(vdev, | 1397 | err = video_register_device(vdev, |
1398 | VFL_TYPE_GRABBER, (j ? 1 : 0)); | 1398 | VFL_TYPE_GRABBER, (j ? 1 : 0)); |
1399 | if (err) | 1399 | if (err) |
@@ -1410,14 +1410,9 @@ probe_out: | |||
1410 | common = &ch->common[k]; | 1410 | common = &ch->common[k]; |
1411 | vb2_dma_contig_cleanup_ctx(common->alloc_ctx); | 1411 | vb2_dma_contig_cleanup_ctx(common->alloc_ctx); |
1412 | /* Unregister video device */ | 1412 | /* Unregister video device */ |
1413 | video_unregister_device(ch->video_dev); | 1413 | video_unregister_device(&ch->video_dev); |
1414 | } | 1414 | } |
1415 | kfree(vpif_obj.sd); | 1415 | kfree(vpif_obj.sd); |
1416 | for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) { | ||
1417 | ch = vpif_obj.dev[i]; | ||
1418 | /* Note: does nothing if ch->video_dev == NULL */ | ||
1419 | video_device_release(ch->video_dev); | ||
1420 | } | ||
1421 | v4l2_device_unregister(&vpif_obj.v4l2_dev); | 1416 | v4l2_device_unregister(&vpif_obj.v4l2_dev); |
1422 | 1417 | ||
1423 | return err; | 1418 | return err; |
@@ -1438,13 +1433,11 @@ static int vpif_async_complete(struct v4l2_async_notifier *notifier) | |||
1438 | static __init int vpif_probe(struct platform_device *pdev) | 1433 | static __init int vpif_probe(struct platform_device *pdev) |
1439 | { | 1434 | { |
1440 | struct vpif_subdev_info *subdevdata; | 1435 | struct vpif_subdev_info *subdevdata; |
1441 | int i, j, err; | ||
1442 | int res_idx = 0; | ||
1443 | struct i2c_adapter *i2c_adap; | 1436 | struct i2c_adapter *i2c_adap; |
1444 | struct channel_obj *ch; | ||
1445 | struct video_device *vfd; | ||
1446 | struct resource *res; | 1437 | struct resource *res; |
1447 | int subdev_count; | 1438 | int subdev_count; |
1439 | int res_idx = 0; | ||
1440 | int i, err; | ||
1448 | 1441 | ||
1449 | vpif_dev = &pdev->dev; | 1442 | vpif_dev = &pdev->dev; |
1450 | 1443 | ||
@@ -1472,24 +1465,6 @@ static __init int vpif_probe(struct platform_device *pdev) | |||
1472 | res_idx++; | 1465 | res_idx++; |
1473 | } | 1466 | } |
1474 | 1467 | ||
1475 | for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) { | ||
1476 | /* Get the pointer to the channel object */ | ||
1477 | ch = vpif_obj.dev[i]; | ||
1478 | /* Allocate memory for video device */ | ||
1479 | vfd = video_device_alloc(); | ||
1480 | if (NULL == vfd) { | ||
1481 | for (j = 0; j < i; j++) { | ||
1482 | ch = vpif_obj.dev[j]; | ||
1483 | video_device_release(ch->video_dev); | ||
1484 | } | ||
1485 | err = -ENOMEM; | ||
1486 | goto vpif_unregister; | ||
1487 | } | ||
1488 | |||
1489 | /* Set video_dev to the video device */ | ||
1490 | ch->video_dev = vfd; | ||
1491 | } | ||
1492 | |||
1493 | vpif_obj.config = pdev->dev.platform_data; | 1468 | vpif_obj.config = pdev->dev.platform_data; |
1494 | 1469 | ||
1495 | subdev_count = vpif_obj.config->subdev_count; | 1470 | subdev_count = vpif_obj.config->subdev_count; |
@@ -1498,7 +1473,7 @@ static __init int vpif_probe(struct platform_device *pdev) | |||
1498 | if (vpif_obj.sd == NULL) { | 1473 | if (vpif_obj.sd == NULL) { |
1499 | vpif_err("unable to allocate memory for subdevice pointers\n"); | 1474 | vpif_err("unable to allocate memory for subdevice pointers\n"); |
1500 | err = -ENOMEM; | 1475 | err = -ENOMEM; |
1501 | goto vpif_sd_error; | 1476 | goto vpif_unregister; |
1502 | } | 1477 | } |
1503 | 1478 | ||
1504 | if (!vpif_obj.config->asd_sizes) { | 1479 | if (!vpif_obj.config->asd_sizes) { |
@@ -1541,13 +1516,6 @@ static __init int vpif_probe(struct platform_device *pdev) | |||
1541 | probe_subdev_out: | 1516 | probe_subdev_out: |
1542 | /* free sub devices memory */ | 1517 | /* free sub devices memory */ |
1543 | kfree(vpif_obj.sd); | 1518 | kfree(vpif_obj.sd); |
1544 | |||
1545 | vpif_sd_error: | ||
1546 | for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) { | ||
1547 | ch = vpif_obj.dev[i]; | ||
1548 | /* Note: does nothing if ch->video_dev == NULL */ | ||
1549 | video_device_release(ch->video_dev); | ||
1550 | } | ||
1551 | vpif_unregister: | 1519 | vpif_unregister: |
1552 | v4l2_device_unregister(&vpif_obj.v4l2_dev); | 1520 | v4l2_device_unregister(&vpif_obj.v4l2_dev); |
1553 | 1521 | ||
@@ -1576,7 +1544,7 @@ static int vpif_remove(struct platform_device *device) | |||
1576 | common = &ch->common[VPIF_VIDEO_INDEX]; | 1544 | common = &ch->common[VPIF_VIDEO_INDEX]; |
1577 | vb2_dma_contig_cleanup_ctx(common->alloc_ctx); | 1545 | vb2_dma_contig_cleanup_ctx(common->alloc_ctx); |
1578 | /* Unregister video device */ | 1546 | /* Unregister video device */ |
1579 | video_unregister_device(ch->video_dev); | 1547 | video_unregister_device(&ch->video_dev); |
1580 | kfree(vpif_obj.dev[i]); | 1548 | kfree(vpif_obj.dev[i]); |
1581 | } | 1549 | } |
1582 | return 0; | 1550 | return 0; |
diff --git a/drivers/media/platform/davinci/vpif_capture.h b/drivers/media/platform/davinci/vpif_capture.h index f65d28d38e66..8b8a663f6b22 100644 --- a/drivers/media/platform/davinci/vpif_capture.h +++ b/drivers/media/platform/davinci/vpif_capture.h | |||
@@ -92,7 +92,7 @@ struct common_obj { | |||
92 | 92 | ||
93 | struct channel_obj { | 93 | struct channel_obj { |
94 | /* Identifies video device for this channel */ | 94 | /* Identifies video device for this channel */ |
95 | struct video_device *video_dev; | 95 | struct video_device video_dev; |
96 | /* Indicates id of the field which is being displayed */ | 96 | /* Indicates id of the field which is being displayed */ |
97 | u32 field_id; | 97 | u32 field_id; |
98 | /* flag to indicate whether decoder is initialized */ | 98 | /* flag to indicate whether decoder is initialized */ |
diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c index 839c24de1fd8..682e5d578bf7 100644 --- a/drivers/media/platform/davinci/vpif_display.c +++ b/drivers/media/platform/davinci/vpif_display.c | |||
@@ -829,7 +829,7 @@ static int vpif_set_output(struct vpif_display_config *vpif_cfg, | |||
829 | ch->sd = sd; | 829 | ch->sd = sd; |
830 | if (chan_cfg->outputs != NULL) | 830 | if (chan_cfg->outputs != NULL) |
831 | /* update tvnorms from the sub device output info */ | 831 | /* update tvnorms from the sub device output info */ |
832 | ch->video_dev->tvnorms = chan_cfg->outputs[index].output.std; | 832 | ch->video_dev.tvnorms = chan_cfg->outputs[index].output.std; |
833 | return 0; | 833 | return 0; |
834 | } | 834 | } |
835 | 835 | ||
@@ -1204,16 +1204,16 @@ static int vpif_probe_complete(void) | |||
1204 | ch, &ch->video_dev); | 1204 | ch, &ch->video_dev); |
1205 | 1205 | ||
1206 | /* Initialize the video_device structure */ | 1206 | /* Initialize the video_device structure */ |
1207 | vdev = ch->video_dev; | 1207 | vdev = &ch->video_dev; |
1208 | strlcpy(vdev->name, VPIF_DRIVER_NAME, sizeof(vdev->name)); | 1208 | strlcpy(vdev->name, VPIF_DRIVER_NAME, sizeof(vdev->name)); |
1209 | vdev->release = video_device_release; | 1209 | vdev->release = video_device_release_empty; |
1210 | vdev->fops = &vpif_fops; | 1210 | vdev->fops = &vpif_fops; |
1211 | vdev->ioctl_ops = &vpif_ioctl_ops; | 1211 | vdev->ioctl_ops = &vpif_ioctl_ops; |
1212 | vdev->v4l2_dev = &vpif_obj.v4l2_dev; | 1212 | vdev->v4l2_dev = &vpif_obj.v4l2_dev; |
1213 | vdev->vfl_dir = VFL_DIR_TX; | 1213 | vdev->vfl_dir = VFL_DIR_TX; |
1214 | vdev->queue = q; | 1214 | vdev->queue = q; |
1215 | vdev->lock = &common->lock; | 1215 | vdev->lock = &common->lock; |
1216 | video_set_drvdata(ch->video_dev, ch); | 1216 | video_set_drvdata(&ch->video_dev, ch); |
1217 | err = video_register_device(vdev, VFL_TYPE_GRABBER, | 1217 | err = video_register_device(vdev, VFL_TYPE_GRABBER, |
1218 | (j ? 3 : 2)); | 1218 | (j ? 3 : 2)); |
1219 | if (err < 0) | 1219 | if (err < 0) |
@@ -1227,9 +1227,7 @@ probe_out: | |||
1227 | ch = vpif_obj.dev[k]; | 1227 | ch = vpif_obj.dev[k]; |
1228 | common = &ch->common[k]; | 1228 | common = &ch->common[k]; |
1229 | vb2_dma_contig_cleanup_ctx(common->alloc_ctx); | 1229 | vb2_dma_contig_cleanup_ctx(common->alloc_ctx); |
1230 | video_unregister_device(ch->video_dev); | 1230 | video_unregister_device(&ch->video_dev); |
1231 | video_device_release(ch->video_dev); | ||
1232 | ch->video_dev = NULL; | ||
1233 | } | 1231 | } |
1234 | return err; | 1232 | return err; |
1235 | } | 1233 | } |
@@ -1246,13 +1244,11 @@ static int vpif_async_complete(struct v4l2_async_notifier *notifier) | |||
1246 | static __init int vpif_probe(struct platform_device *pdev) | 1244 | static __init int vpif_probe(struct platform_device *pdev) |
1247 | { | 1245 | { |
1248 | struct vpif_subdev_info *subdevdata; | 1246 | struct vpif_subdev_info *subdevdata; |
1249 | int i, j = 0, err = 0; | ||
1250 | int res_idx = 0; | ||
1251 | struct i2c_adapter *i2c_adap; | 1247 | struct i2c_adapter *i2c_adap; |
1252 | struct channel_obj *ch; | ||
1253 | struct video_device *vfd; | ||
1254 | struct resource *res; | 1248 | struct resource *res; |
1255 | int subdev_count; | 1249 | int subdev_count; |
1250 | int res_idx = 0; | ||
1251 | int i, err; | ||
1256 | 1252 | ||
1257 | vpif_dev = &pdev->dev; | 1253 | vpif_dev = &pdev->dev; |
1258 | err = initialize_vpif(); | 1254 | err = initialize_vpif(); |
@@ -1281,25 +1277,6 @@ static __init int vpif_probe(struct platform_device *pdev) | |||
1281 | res_idx++; | 1277 | res_idx++; |
1282 | } | 1278 | } |
1283 | 1279 | ||
1284 | for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) { | ||
1285 | /* Get the pointer to the channel object */ | ||
1286 | ch = vpif_obj.dev[i]; | ||
1287 | |||
1288 | /* Allocate memory for video device */ | ||
1289 | vfd = video_device_alloc(); | ||
1290 | if (vfd == NULL) { | ||
1291 | for (j = 0; j < i; j++) { | ||
1292 | ch = vpif_obj.dev[j]; | ||
1293 | video_device_release(ch->video_dev); | ||
1294 | } | ||
1295 | err = -ENOMEM; | ||
1296 | goto vpif_unregister; | ||
1297 | } | ||
1298 | |||
1299 | /* Set video_dev to the video device */ | ||
1300 | ch->video_dev = vfd; | ||
1301 | } | ||
1302 | |||
1303 | vpif_obj.config = pdev->dev.platform_data; | 1280 | vpif_obj.config = pdev->dev.platform_data; |
1304 | subdev_count = vpif_obj.config->subdev_count; | 1281 | subdev_count = vpif_obj.config->subdev_count; |
1305 | subdevdata = vpif_obj.config->subdevinfo; | 1282 | subdevdata = vpif_obj.config->subdevinfo; |
@@ -1308,7 +1285,7 @@ static __init int vpif_probe(struct platform_device *pdev) | |||
1308 | if (vpif_obj.sd == NULL) { | 1285 | if (vpif_obj.sd == NULL) { |
1309 | vpif_err("unable to allocate memory for subdevice pointers\n"); | 1286 | vpif_err("unable to allocate memory for subdevice pointers\n"); |
1310 | err = -ENOMEM; | 1287 | err = -ENOMEM; |
1311 | goto vpif_sd_error; | 1288 | goto vpif_unregister; |
1312 | } | 1289 | } |
1313 | 1290 | ||
1314 | if (!vpif_obj.config->asd_sizes) { | 1291 | if (!vpif_obj.config->asd_sizes) { |
@@ -1348,12 +1325,6 @@ static __init int vpif_probe(struct platform_device *pdev) | |||
1348 | 1325 | ||
1349 | probe_subdev_out: | 1326 | probe_subdev_out: |
1350 | kfree(vpif_obj.sd); | 1327 | kfree(vpif_obj.sd); |
1351 | vpif_sd_error: | ||
1352 | for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) { | ||
1353 | ch = vpif_obj.dev[i]; | ||
1354 | /* Note: does nothing if ch->video_dev == NULL */ | ||
1355 | video_device_release(ch->video_dev); | ||
1356 | } | ||
1357 | vpif_unregister: | 1328 | vpif_unregister: |
1358 | v4l2_device_unregister(&vpif_obj.v4l2_dev); | 1329 | v4l2_device_unregister(&vpif_obj.v4l2_dev); |
1359 | 1330 | ||
@@ -1379,9 +1350,7 @@ static int vpif_remove(struct platform_device *device) | |||
1379 | common = &ch->common[VPIF_VIDEO_INDEX]; | 1350 | common = &ch->common[VPIF_VIDEO_INDEX]; |
1380 | vb2_dma_contig_cleanup_ctx(common->alloc_ctx); | 1351 | vb2_dma_contig_cleanup_ctx(common->alloc_ctx); |
1381 | /* Unregister video device */ | 1352 | /* Unregister video device */ |
1382 | video_unregister_device(ch->video_dev); | 1353 | video_unregister_device(&ch->video_dev); |
1383 | |||
1384 | ch->video_dev = NULL; | ||
1385 | kfree(vpif_obj.dev[i]); | 1354 | kfree(vpif_obj.dev[i]); |
1386 | } | 1355 | } |
1387 | 1356 | ||
diff --git a/drivers/media/platform/davinci/vpif_display.h b/drivers/media/platform/davinci/vpif_display.h index 7b21a7607674..849e0e385f18 100644 --- a/drivers/media/platform/davinci/vpif_display.h +++ b/drivers/media/platform/davinci/vpif_display.h | |||
@@ -100,7 +100,7 @@ struct common_obj { | |||
100 | 100 | ||
101 | struct channel_obj { | 101 | struct channel_obj { |
102 | /* V4l2 specific parameters */ | 102 | /* V4l2 specific parameters */ |
103 | struct video_device *video_dev; /* Identifies video device for | 103 | struct video_device video_dev; /* Identifies video device for |
104 | * this channel */ | 104 | * this channel */ |
105 | u32 field_id; /* Indicates id of the field | 105 | u32 field_id; /* Indicates id of the field |
106 | * which is being displayed */ | 106 | * which is being displayed */ |
diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c index 8a2fd8c33d42..cfebf292e15a 100644 --- a/drivers/media/platform/exynos4-is/fimc-capture.c +++ b/drivers/media/platform/exynos4-is/fimc-capture.c | |||
@@ -1482,7 +1482,7 @@ void fimc_sensor_notify(struct v4l2_subdev *sd, unsigned int notification, | |||
1482 | } | 1482 | } |
1483 | 1483 | ||
1484 | static int fimc_subdev_enum_mbus_code(struct v4l2_subdev *sd, | 1484 | static int fimc_subdev_enum_mbus_code(struct v4l2_subdev *sd, |
1485 | struct v4l2_subdev_fh *fh, | 1485 | struct v4l2_subdev_pad_config *cfg, |
1486 | struct v4l2_subdev_mbus_code_enum *code) | 1486 | struct v4l2_subdev_mbus_code_enum *code) |
1487 | { | 1487 | { |
1488 | struct fimc_fmt *fmt; | 1488 | struct fimc_fmt *fmt; |
@@ -1495,7 +1495,7 @@ static int fimc_subdev_enum_mbus_code(struct v4l2_subdev *sd, | |||
1495 | } | 1495 | } |
1496 | 1496 | ||
1497 | static int fimc_subdev_get_fmt(struct v4l2_subdev *sd, | 1497 | static int fimc_subdev_get_fmt(struct v4l2_subdev *sd, |
1498 | struct v4l2_subdev_fh *fh, | 1498 | struct v4l2_subdev_pad_config *cfg, |
1499 | struct v4l2_subdev_format *fmt) | 1499 | struct v4l2_subdev_format *fmt) |
1500 | { | 1500 | { |
1501 | struct fimc_dev *fimc = v4l2_get_subdevdata(sd); | 1501 | struct fimc_dev *fimc = v4l2_get_subdevdata(sd); |
@@ -1504,7 +1504,7 @@ static int fimc_subdev_get_fmt(struct v4l2_subdev *sd, | |||
1504 | struct v4l2_mbus_framefmt *mf; | 1504 | struct v4l2_mbus_framefmt *mf; |
1505 | 1505 | ||
1506 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { | 1506 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { |
1507 | mf = v4l2_subdev_get_try_format(fh, fmt->pad); | 1507 | mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); |
1508 | fmt->format = *mf; | 1508 | fmt->format = *mf; |
1509 | return 0; | 1509 | return 0; |
1510 | } | 1510 | } |
@@ -1536,7 +1536,7 @@ static int fimc_subdev_get_fmt(struct v4l2_subdev *sd, | |||
1536 | } | 1536 | } |
1537 | 1537 | ||
1538 | static int fimc_subdev_set_fmt(struct v4l2_subdev *sd, | 1538 | static int fimc_subdev_set_fmt(struct v4l2_subdev *sd, |
1539 | struct v4l2_subdev_fh *fh, | 1539 | struct v4l2_subdev_pad_config *cfg, |
1540 | struct v4l2_subdev_format *fmt) | 1540 | struct v4l2_subdev_format *fmt) |
1541 | { | 1541 | { |
1542 | struct fimc_dev *fimc = v4l2_get_subdevdata(sd); | 1542 | struct fimc_dev *fimc = v4l2_get_subdevdata(sd); |
@@ -1559,7 +1559,7 @@ static int fimc_subdev_set_fmt(struct v4l2_subdev *sd, | |||
1559 | mf->colorspace = V4L2_COLORSPACE_JPEG; | 1559 | mf->colorspace = V4L2_COLORSPACE_JPEG; |
1560 | 1560 | ||
1561 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { | 1561 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { |
1562 | mf = v4l2_subdev_get_try_format(fh, fmt->pad); | 1562 | mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); |
1563 | *mf = fmt->format; | 1563 | *mf = fmt->format; |
1564 | return 0; | 1564 | return 0; |
1565 | } | 1565 | } |
@@ -1602,7 +1602,7 @@ static int fimc_subdev_set_fmt(struct v4l2_subdev *sd, | |||
1602 | } | 1602 | } |
1603 | 1603 | ||
1604 | static int fimc_subdev_get_selection(struct v4l2_subdev *sd, | 1604 | static int fimc_subdev_get_selection(struct v4l2_subdev *sd, |
1605 | struct v4l2_subdev_fh *fh, | 1605 | struct v4l2_subdev_pad_config *cfg, |
1606 | struct v4l2_subdev_selection *sel) | 1606 | struct v4l2_subdev_selection *sel) |
1607 | { | 1607 | { |
1608 | struct fimc_dev *fimc = v4l2_get_subdevdata(sd); | 1608 | struct fimc_dev *fimc = v4l2_get_subdevdata(sd); |
@@ -1628,10 +1628,10 @@ static int fimc_subdev_get_selection(struct v4l2_subdev *sd, | |||
1628 | return 0; | 1628 | return 0; |
1629 | 1629 | ||
1630 | case V4L2_SEL_TGT_CROP: | 1630 | case V4L2_SEL_TGT_CROP: |
1631 | try_sel = v4l2_subdev_get_try_crop(fh, sel->pad); | 1631 | try_sel = v4l2_subdev_get_try_crop(sd, cfg, sel->pad); |
1632 | break; | 1632 | break; |
1633 | case V4L2_SEL_TGT_COMPOSE: | 1633 | case V4L2_SEL_TGT_COMPOSE: |
1634 | try_sel = v4l2_subdev_get_try_compose(fh, sel->pad); | 1634 | try_sel = v4l2_subdev_get_try_compose(sd, cfg, sel->pad); |
1635 | f = &ctx->d_frame; | 1635 | f = &ctx->d_frame; |
1636 | break; | 1636 | break; |
1637 | default: | 1637 | default: |
@@ -1657,7 +1657,7 @@ static int fimc_subdev_get_selection(struct v4l2_subdev *sd, | |||
1657 | } | 1657 | } |
1658 | 1658 | ||
1659 | static int fimc_subdev_set_selection(struct v4l2_subdev *sd, | 1659 | static int fimc_subdev_set_selection(struct v4l2_subdev *sd, |
1660 | struct v4l2_subdev_fh *fh, | 1660 | struct v4l2_subdev_pad_config *cfg, |
1661 | struct v4l2_subdev_selection *sel) | 1661 | struct v4l2_subdev_selection *sel) |
1662 | { | 1662 | { |
1663 | struct fimc_dev *fimc = v4l2_get_subdevdata(sd); | 1663 | struct fimc_dev *fimc = v4l2_get_subdevdata(sd); |
@@ -1675,10 +1675,10 @@ static int fimc_subdev_set_selection(struct v4l2_subdev *sd, | |||
1675 | 1675 | ||
1676 | switch (sel->target) { | 1676 | switch (sel->target) { |
1677 | case V4L2_SEL_TGT_CROP: | 1677 | case V4L2_SEL_TGT_CROP: |
1678 | try_sel = v4l2_subdev_get_try_crop(fh, sel->pad); | 1678 | try_sel = v4l2_subdev_get_try_crop(sd, cfg, sel->pad); |
1679 | break; | 1679 | break; |
1680 | case V4L2_SEL_TGT_COMPOSE: | 1680 | case V4L2_SEL_TGT_COMPOSE: |
1681 | try_sel = v4l2_subdev_get_try_compose(fh, sel->pad); | 1681 | try_sel = v4l2_subdev_get_try_compose(sd, cfg, sel->pad); |
1682 | f = &ctx->d_frame; | 1682 | f = &ctx->d_frame; |
1683 | break; | 1683 | break; |
1684 | default: | 1684 | default: |
diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c index 60c744915549..5d78f5716f3b 100644 --- a/drivers/media/platform/exynos4-is/fimc-isp.c +++ b/drivers/media/platform/exynos4-is/fimc-isp.c | |||
@@ -112,7 +112,7 @@ static const struct media_entity_operations fimc_is_subdev_media_ops = { | |||
112 | }; | 112 | }; |
113 | 113 | ||
114 | static int fimc_is_subdev_enum_mbus_code(struct v4l2_subdev *sd, | 114 | static int fimc_is_subdev_enum_mbus_code(struct v4l2_subdev *sd, |
115 | struct v4l2_subdev_fh *fh, | 115 | struct v4l2_subdev_pad_config *cfg, |
116 | struct v4l2_subdev_mbus_code_enum *code) | 116 | struct v4l2_subdev_mbus_code_enum *code) |
117 | { | 117 | { |
118 | const struct fimc_fmt *fmt; | 118 | const struct fimc_fmt *fmt; |
@@ -125,14 +125,14 @@ static int fimc_is_subdev_enum_mbus_code(struct v4l2_subdev *sd, | |||
125 | } | 125 | } |
126 | 126 | ||
127 | static int fimc_isp_subdev_get_fmt(struct v4l2_subdev *sd, | 127 | static int fimc_isp_subdev_get_fmt(struct v4l2_subdev *sd, |
128 | struct v4l2_subdev_fh *fh, | 128 | struct v4l2_subdev_pad_config *cfg, |
129 | struct v4l2_subdev_format *fmt) | 129 | struct v4l2_subdev_format *fmt) |
130 | { | 130 | { |
131 | struct fimc_isp *isp = v4l2_get_subdevdata(sd); | 131 | struct fimc_isp *isp = v4l2_get_subdevdata(sd); |
132 | struct v4l2_mbus_framefmt *mf = &fmt->format; | 132 | struct v4l2_mbus_framefmt *mf = &fmt->format; |
133 | 133 | ||
134 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { | 134 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { |
135 | *mf = *v4l2_subdev_get_try_format(fh, fmt->pad); | 135 | *mf = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad); |
136 | return 0; | 136 | return 0; |
137 | } | 137 | } |
138 | 138 | ||
@@ -162,7 +162,7 @@ static int fimc_isp_subdev_get_fmt(struct v4l2_subdev *sd, | |||
162 | } | 162 | } |
163 | 163 | ||
164 | static void __isp_subdev_try_format(struct fimc_isp *isp, | 164 | static void __isp_subdev_try_format(struct fimc_isp *isp, |
165 | struct v4l2_subdev_fh *fh, | 165 | struct v4l2_subdev_pad_config *cfg, |
166 | struct v4l2_subdev_format *fmt) | 166 | struct v4l2_subdev_format *fmt) |
167 | { | 167 | { |
168 | struct v4l2_mbus_framefmt *mf = &fmt->format; | 168 | struct v4l2_mbus_framefmt *mf = &fmt->format; |
@@ -178,7 +178,7 @@ static void __isp_subdev_try_format(struct fimc_isp *isp, | |||
178 | mf->code = MEDIA_BUS_FMT_SGRBG10_1X10; | 178 | mf->code = MEDIA_BUS_FMT_SGRBG10_1X10; |
179 | } else { | 179 | } else { |
180 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) | 180 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) |
181 | format = v4l2_subdev_get_try_format(fh, | 181 | format = v4l2_subdev_get_try_format(&isp->subdev, cfg, |
182 | FIMC_ISP_SD_PAD_SINK); | 182 | FIMC_ISP_SD_PAD_SINK); |
183 | else | 183 | else |
184 | format = &isp->sink_fmt; | 184 | format = &isp->sink_fmt; |
@@ -197,7 +197,7 @@ static void __isp_subdev_try_format(struct fimc_isp *isp, | |||
197 | } | 197 | } |
198 | 198 | ||
199 | static int fimc_isp_subdev_set_fmt(struct v4l2_subdev *sd, | 199 | static int fimc_isp_subdev_set_fmt(struct v4l2_subdev *sd, |
200 | struct v4l2_subdev_fh *fh, | 200 | struct v4l2_subdev_pad_config *cfg, |
201 | struct v4l2_subdev_format *fmt) | 201 | struct v4l2_subdev_format *fmt) |
202 | { | 202 | { |
203 | struct fimc_isp *isp = v4l2_get_subdevdata(sd); | 203 | struct fimc_isp *isp = v4l2_get_subdevdata(sd); |
@@ -209,10 +209,10 @@ static int fimc_isp_subdev_set_fmt(struct v4l2_subdev *sd, | |||
209 | __func__, fmt->pad, mf->code, mf->width, mf->height); | 209 | __func__, fmt->pad, mf->code, mf->width, mf->height); |
210 | 210 | ||
211 | mutex_lock(&isp->subdev_lock); | 211 | mutex_lock(&isp->subdev_lock); |
212 | __isp_subdev_try_format(isp, fh, fmt); | 212 | __isp_subdev_try_format(isp, cfg, fmt); |
213 | 213 | ||
214 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { | 214 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { |
215 | mf = v4l2_subdev_get_try_format(fh, fmt->pad); | 215 | mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); |
216 | *mf = fmt->format; | 216 | *mf = fmt->format; |
217 | 217 | ||
218 | /* Propagate format to the source pads */ | 218 | /* Propagate format to the source pads */ |
@@ -223,8 +223,8 @@ static int fimc_isp_subdev_set_fmt(struct v4l2_subdev *sd, | |||
223 | for (pad = FIMC_ISP_SD_PAD_SRC_FIFO; | 223 | for (pad = FIMC_ISP_SD_PAD_SRC_FIFO; |
224 | pad < FIMC_ISP_SD_PADS_NUM; pad++) { | 224 | pad < FIMC_ISP_SD_PADS_NUM; pad++) { |
225 | format.pad = pad; | 225 | format.pad = pad; |
226 | __isp_subdev_try_format(isp, fh, &format); | 226 | __isp_subdev_try_format(isp, cfg, &format); |
227 | mf = v4l2_subdev_get_try_format(fh, pad); | 227 | mf = v4l2_subdev_get_try_format(sd, cfg, pad); |
228 | *mf = format.format; | 228 | *mf = format.format; |
229 | } | 229 | } |
230 | } | 230 | } |
@@ -236,7 +236,7 @@ static int fimc_isp_subdev_set_fmt(struct v4l2_subdev *sd, | |||
236 | isp->sink_fmt = *mf; | 236 | isp->sink_fmt = *mf; |
237 | 237 | ||
238 | format.pad = FIMC_ISP_SD_PAD_SRC_DMA; | 238 | format.pad = FIMC_ISP_SD_PAD_SRC_DMA; |
239 | __isp_subdev_try_format(isp, fh, &format); | 239 | __isp_subdev_try_format(isp, cfg, &format); |
240 | 240 | ||
241 | isp->src_fmt = format.format; | 241 | isp->src_fmt = format.format; |
242 | __is_set_frame_size(is, &isp->src_fmt); | 242 | __is_set_frame_size(is, &isp->src_fmt); |
@@ -369,7 +369,7 @@ static int fimc_isp_subdev_open(struct v4l2_subdev *sd, | |||
369 | struct v4l2_mbus_framefmt fmt; | 369 | struct v4l2_mbus_framefmt fmt; |
370 | struct v4l2_mbus_framefmt *format; | 370 | struct v4l2_mbus_framefmt *format; |
371 | 371 | ||
372 | format = v4l2_subdev_get_try_format(fh, FIMC_ISP_SD_PAD_SINK); | 372 | format = v4l2_subdev_get_try_format(sd, fh->pad, FIMC_ISP_SD_PAD_SINK); |
373 | 373 | ||
374 | fmt.colorspace = V4L2_COLORSPACE_SRGB; | 374 | fmt.colorspace = V4L2_COLORSPACE_SRGB; |
375 | fmt.code = fimc_isp_formats[0].mbus_code; | 375 | fmt.code = fimc_isp_formats[0].mbus_code; |
@@ -378,12 +378,12 @@ static int fimc_isp_subdev_open(struct v4l2_subdev *sd, | |||
378 | fmt.field = V4L2_FIELD_NONE; | 378 | fmt.field = V4L2_FIELD_NONE; |
379 | *format = fmt; | 379 | *format = fmt; |
380 | 380 | ||
381 | format = v4l2_subdev_get_try_format(fh, FIMC_ISP_SD_PAD_SRC_FIFO); | 381 | format = v4l2_subdev_get_try_format(sd, fh->pad, FIMC_ISP_SD_PAD_SRC_FIFO); |
382 | fmt.width = DEFAULT_PREVIEW_STILL_WIDTH; | 382 | fmt.width = DEFAULT_PREVIEW_STILL_WIDTH; |
383 | fmt.height = DEFAULT_PREVIEW_STILL_HEIGHT; | 383 | fmt.height = DEFAULT_PREVIEW_STILL_HEIGHT; |
384 | *format = fmt; | 384 | *format = fmt; |
385 | 385 | ||
386 | format = v4l2_subdev_get_try_format(fh, FIMC_ISP_SD_PAD_SRC_DMA); | 386 | format = v4l2_subdev_get_try_format(sd, fh->pad, FIMC_ISP_SD_PAD_SRC_DMA); |
387 | *format = fmt; | 387 | *format = fmt; |
388 | 388 | ||
389 | return 0; | 389 | return 0; |
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c index 2510f189e242..ca6261a86a5f 100644 --- a/drivers/media/platform/exynos4-is/fimc-lite.c +++ b/drivers/media/platform/exynos4-is/fimc-lite.c | |||
@@ -568,7 +568,7 @@ static const struct v4l2_file_operations fimc_lite_fops = { | |||
568 | */ | 568 | */ |
569 | 569 | ||
570 | static const struct fimc_fmt *fimc_lite_subdev_try_fmt(struct fimc_lite *fimc, | 570 | static const struct fimc_fmt *fimc_lite_subdev_try_fmt(struct fimc_lite *fimc, |
571 | struct v4l2_subdev_fh *fh, | 571 | struct v4l2_subdev_pad_config *cfg, |
572 | struct v4l2_subdev_format *format) | 572 | struct v4l2_subdev_format *format) |
573 | { | 573 | { |
574 | struct flite_drvdata *dd = fimc->dd; | 574 | struct flite_drvdata *dd = fimc->dd; |
@@ -592,13 +592,13 @@ static const struct fimc_fmt *fimc_lite_subdev_try_fmt(struct fimc_lite *fimc, | |||
592 | struct v4l2_rect *rect; | 592 | struct v4l2_rect *rect; |
593 | 593 | ||
594 | if (format->which == V4L2_SUBDEV_FORMAT_TRY) { | 594 | if (format->which == V4L2_SUBDEV_FORMAT_TRY) { |
595 | sink_fmt = v4l2_subdev_get_try_format(fh, | 595 | sink_fmt = v4l2_subdev_get_try_format(&fimc->subdev, cfg, |
596 | FLITE_SD_PAD_SINK); | 596 | FLITE_SD_PAD_SINK); |
597 | 597 | ||
598 | mf->code = sink_fmt->code; | 598 | mf->code = sink_fmt->code; |
599 | mf->colorspace = sink_fmt->colorspace; | 599 | mf->colorspace = sink_fmt->colorspace; |
600 | 600 | ||
601 | rect = v4l2_subdev_get_try_crop(fh, | 601 | rect = v4l2_subdev_get_try_crop(&fimc->subdev, cfg, |
602 | FLITE_SD_PAD_SINK); | 602 | FLITE_SD_PAD_SINK); |
603 | } else { | 603 | } else { |
604 | mf->code = sink->fmt->mbus_code; | 604 | mf->code = sink->fmt->mbus_code; |
@@ -1047,7 +1047,7 @@ static const struct media_entity_operations fimc_lite_subdev_media_ops = { | |||
1047 | }; | 1047 | }; |
1048 | 1048 | ||
1049 | static int fimc_lite_subdev_enum_mbus_code(struct v4l2_subdev *sd, | 1049 | static int fimc_lite_subdev_enum_mbus_code(struct v4l2_subdev *sd, |
1050 | struct v4l2_subdev_fh *fh, | 1050 | struct v4l2_subdev_pad_config *cfg, |
1051 | struct v4l2_subdev_mbus_code_enum *code) | 1051 | struct v4l2_subdev_mbus_code_enum *code) |
1052 | { | 1052 | { |
1053 | const struct fimc_fmt *fmt; | 1053 | const struct fimc_fmt *fmt; |
@@ -1060,16 +1060,17 @@ static int fimc_lite_subdev_enum_mbus_code(struct v4l2_subdev *sd, | |||
1060 | } | 1060 | } |
1061 | 1061 | ||
1062 | static struct v4l2_mbus_framefmt *__fimc_lite_subdev_get_try_fmt( | 1062 | static struct v4l2_mbus_framefmt *__fimc_lite_subdev_get_try_fmt( |
1063 | struct v4l2_subdev_fh *fh, unsigned int pad) | 1063 | struct v4l2_subdev *sd, |
1064 | struct v4l2_subdev_pad_config *cfg, unsigned int pad) | ||
1064 | { | 1065 | { |
1065 | if (pad != FLITE_SD_PAD_SINK) | 1066 | if (pad != FLITE_SD_PAD_SINK) |
1066 | pad = FLITE_SD_PAD_SOURCE_DMA; | 1067 | pad = FLITE_SD_PAD_SOURCE_DMA; |
1067 | 1068 | ||
1068 | return v4l2_subdev_get_try_format(fh, pad); | 1069 | return v4l2_subdev_get_try_format(sd, cfg, pad); |
1069 | } | 1070 | } |
1070 | 1071 | ||
1071 | static int fimc_lite_subdev_get_fmt(struct v4l2_subdev *sd, | 1072 | static int fimc_lite_subdev_get_fmt(struct v4l2_subdev *sd, |
1072 | struct v4l2_subdev_fh *fh, | 1073 | struct v4l2_subdev_pad_config *cfg, |
1073 | struct v4l2_subdev_format *fmt) | 1074 | struct v4l2_subdev_format *fmt) |
1074 | { | 1075 | { |
1075 | struct fimc_lite *fimc = v4l2_get_subdevdata(sd); | 1076 | struct fimc_lite *fimc = v4l2_get_subdevdata(sd); |
@@ -1077,7 +1078,7 @@ static int fimc_lite_subdev_get_fmt(struct v4l2_subdev *sd, | |||
1077 | struct flite_frame *f = &fimc->inp_frame; | 1078 | struct flite_frame *f = &fimc->inp_frame; |
1078 | 1079 | ||
1079 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { | 1080 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { |
1080 | mf = __fimc_lite_subdev_get_try_fmt(fh, fmt->pad); | 1081 | mf = __fimc_lite_subdev_get_try_fmt(sd, cfg, fmt->pad); |
1081 | fmt->format = *mf; | 1082 | fmt->format = *mf; |
1082 | return 0; | 1083 | return 0; |
1083 | } | 1084 | } |
@@ -1100,7 +1101,7 @@ static int fimc_lite_subdev_get_fmt(struct v4l2_subdev *sd, | |||
1100 | } | 1101 | } |
1101 | 1102 | ||
1102 | static int fimc_lite_subdev_set_fmt(struct v4l2_subdev *sd, | 1103 | static int fimc_lite_subdev_set_fmt(struct v4l2_subdev *sd, |
1103 | struct v4l2_subdev_fh *fh, | 1104 | struct v4l2_subdev_pad_config *cfg, |
1104 | struct v4l2_subdev_format *fmt) | 1105 | struct v4l2_subdev_format *fmt) |
1105 | { | 1106 | { |
1106 | struct fimc_lite *fimc = v4l2_get_subdevdata(sd); | 1107 | struct fimc_lite *fimc = v4l2_get_subdevdata(sd); |
@@ -1122,17 +1123,17 @@ static int fimc_lite_subdev_set_fmt(struct v4l2_subdev *sd, | |||
1122 | return -EBUSY; | 1123 | return -EBUSY; |
1123 | } | 1124 | } |
1124 | 1125 | ||
1125 | ffmt = fimc_lite_subdev_try_fmt(fimc, fh, fmt); | 1126 | ffmt = fimc_lite_subdev_try_fmt(fimc, cfg, fmt); |
1126 | 1127 | ||
1127 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { | 1128 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { |
1128 | struct v4l2_mbus_framefmt *src_fmt; | 1129 | struct v4l2_mbus_framefmt *src_fmt; |
1129 | 1130 | ||
1130 | mf = __fimc_lite_subdev_get_try_fmt(fh, fmt->pad); | 1131 | mf = __fimc_lite_subdev_get_try_fmt(sd, cfg, fmt->pad); |
1131 | *mf = fmt->format; | 1132 | *mf = fmt->format; |
1132 | 1133 | ||
1133 | if (fmt->pad == FLITE_SD_PAD_SINK) { | 1134 | if (fmt->pad == FLITE_SD_PAD_SINK) { |
1134 | unsigned int pad = FLITE_SD_PAD_SOURCE_DMA; | 1135 | unsigned int pad = FLITE_SD_PAD_SOURCE_DMA; |
1135 | src_fmt = __fimc_lite_subdev_get_try_fmt(fh, pad); | 1136 | src_fmt = __fimc_lite_subdev_get_try_fmt(sd, cfg, pad); |
1136 | *src_fmt = *mf; | 1137 | *src_fmt = *mf; |
1137 | } | 1138 | } |
1138 | 1139 | ||
@@ -1160,7 +1161,7 @@ static int fimc_lite_subdev_set_fmt(struct v4l2_subdev *sd, | |||
1160 | } | 1161 | } |
1161 | 1162 | ||
1162 | static int fimc_lite_subdev_get_selection(struct v4l2_subdev *sd, | 1163 | static int fimc_lite_subdev_get_selection(struct v4l2_subdev *sd, |
1163 | struct v4l2_subdev_fh *fh, | 1164 | struct v4l2_subdev_pad_config *cfg, |
1164 | struct v4l2_subdev_selection *sel) | 1165 | struct v4l2_subdev_selection *sel) |
1165 | { | 1166 | { |
1166 | struct fimc_lite *fimc = v4l2_get_subdevdata(sd); | 1167 | struct fimc_lite *fimc = v4l2_get_subdevdata(sd); |
@@ -1172,7 +1173,7 @@ static int fimc_lite_subdev_get_selection(struct v4l2_subdev *sd, | |||
1172 | return -EINVAL; | 1173 | return -EINVAL; |
1173 | 1174 | ||
1174 | if (sel->which == V4L2_SUBDEV_FORMAT_TRY) { | 1175 | if (sel->which == V4L2_SUBDEV_FORMAT_TRY) { |
1175 | sel->r = *v4l2_subdev_get_try_crop(fh, sel->pad); | 1176 | sel->r = *v4l2_subdev_get_try_crop(sd, cfg, sel->pad); |
1176 | return 0; | 1177 | return 0; |
1177 | } | 1178 | } |
1178 | 1179 | ||
@@ -1195,7 +1196,7 @@ static int fimc_lite_subdev_get_selection(struct v4l2_subdev *sd, | |||
1195 | } | 1196 | } |
1196 | 1197 | ||
1197 | static int fimc_lite_subdev_set_selection(struct v4l2_subdev *sd, | 1198 | static int fimc_lite_subdev_set_selection(struct v4l2_subdev *sd, |
1198 | struct v4l2_subdev_fh *fh, | 1199 | struct v4l2_subdev_pad_config *cfg, |
1199 | struct v4l2_subdev_selection *sel) | 1200 | struct v4l2_subdev_selection *sel) |
1200 | { | 1201 | { |
1201 | struct fimc_lite *fimc = v4l2_get_subdevdata(sd); | 1202 | struct fimc_lite *fimc = v4l2_get_subdevdata(sd); |
@@ -1209,7 +1210,7 @@ static int fimc_lite_subdev_set_selection(struct v4l2_subdev *sd, | |||
1209 | fimc_lite_try_crop(fimc, &sel->r); | 1210 | fimc_lite_try_crop(fimc, &sel->r); |
1210 | 1211 | ||
1211 | if (sel->which == V4L2_SUBDEV_FORMAT_TRY) { | 1212 | if (sel->which == V4L2_SUBDEV_FORMAT_TRY) { |
1212 | *v4l2_subdev_get_try_crop(fh, sel->pad) = sel->r; | 1213 | *v4l2_subdev_get_try_crop(sd, cfg, sel->pad) = sel->r; |
1213 | } else { | 1214 | } else { |
1214 | unsigned long flags; | 1215 | unsigned long flags; |
1215 | spin_lock_irqsave(&fimc->slock, flags); | 1216 | spin_lock_irqsave(&fimc->slock, flags); |
diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c index 2504aa89a6f4..d74e1bec3d86 100644 --- a/drivers/media/platform/exynos4-is/mipi-csis.c +++ b/drivers/media/platform/exynos4-is/mipi-csis.c | |||
@@ -540,7 +540,7 @@ unlock: | |||
540 | } | 540 | } |
541 | 541 | ||
542 | static int s5pcsis_enum_mbus_code(struct v4l2_subdev *sd, | 542 | static int s5pcsis_enum_mbus_code(struct v4l2_subdev *sd, |
543 | struct v4l2_subdev_fh *fh, | 543 | struct v4l2_subdev_pad_config *cfg, |
544 | struct v4l2_subdev_mbus_code_enum *code) | 544 | struct v4l2_subdev_mbus_code_enum *code) |
545 | { | 545 | { |
546 | if (code->index >= ARRAY_SIZE(s5pcsis_formats)) | 546 | if (code->index >= ARRAY_SIZE(s5pcsis_formats)) |
@@ -568,23 +568,23 @@ static struct csis_pix_format const *s5pcsis_try_format( | |||
568 | } | 568 | } |
569 | 569 | ||
570 | static struct v4l2_mbus_framefmt *__s5pcsis_get_format( | 570 | static struct v4l2_mbus_framefmt *__s5pcsis_get_format( |
571 | struct csis_state *state, struct v4l2_subdev_fh *fh, | 571 | struct csis_state *state, struct v4l2_subdev_pad_config *cfg, |
572 | enum v4l2_subdev_format_whence which) | 572 | enum v4l2_subdev_format_whence which) |
573 | { | 573 | { |
574 | if (which == V4L2_SUBDEV_FORMAT_TRY) | 574 | if (which == V4L2_SUBDEV_FORMAT_TRY) |
575 | return fh ? v4l2_subdev_get_try_format(fh, 0) : NULL; | 575 | return cfg ? v4l2_subdev_get_try_format(&state->sd, cfg, 0) : NULL; |
576 | 576 | ||
577 | return &state->format; | 577 | return &state->format; |
578 | } | 578 | } |
579 | 579 | ||
580 | static int s5pcsis_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | 580 | static int s5pcsis_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, |
581 | struct v4l2_subdev_format *fmt) | 581 | struct v4l2_subdev_format *fmt) |
582 | { | 582 | { |
583 | struct csis_state *state = sd_to_csis_state(sd); | 583 | struct csis_state *state = sd_to_csis_state(sd); |
584 | struct csis_pix_format const *csis_fmt; | 584 | struct csis_pix_format const *csis_fmt; |
585 | struct v4l2_mbus_framefmt *mf; | 585 | struct v4l2_mbus_framefmt *mf; |
586 | 586 | ||
587 | mf = __s5pcsis_get_format(state, fh, fmt->which); | 587 | mf = __s5pcsis_get_format(state, cfg, fmt->which); |
588 | 588 | ||
589 | if (fmt->pad == CSIS_PAD_SOURCE) { | 589 | if (fmt->pad == CSIS_PAD_SOURCE) { |
590 | if (mf) { | 590 | if (mf) { |
@@ -605,13 +605,13 @@ static int s5pcsis_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
605 | return 0; | 605 | return 0; |
606 | } | 606 | } |
607 | 607 | ||
608 | static int s5pcsis_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | 608 | static int s5pcsis_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, |
609 | struct v4l2_subdev_format *fmt) | 609 | struct v4l2_subdev_format *fmt) |
610 | { | 610 | { |
611 | struct csis_state *state = sd_to_csis_state(sd); | 611 | struct csis_state *state = sd_to_csis_state(sd); |
612 | struct v4l2_mbus_framefmt *mf; | 612 | struct v4l2_mbus_framefmt *mf; |
613 | 613 | ||
614 | mf = __s5pcsis_get_format(state, fh, fmt->which); | 614 | mf = __s5pcsis_get_format(state, cfg, fmt->which); |
615 | if (!mf) | 615 | if (!mf) |
616 | return -EINVAL; | 616 | return -EINVAL; |
617 | 617 | ||
@@ -651,7 +651,7 @@ static int s5pcsis_log_status(struct v4l2_subdev *sd) | |||
651 | 651 | ||
652 | static int s5pcsis_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) | 652 | static int s5pcsis_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) |
653 | { | 653 | { |
654 | struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(fh, 0); | 654 | struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(sd, fh->pad, 0); |
655 | 655 | ||
656 | format->colorspace = V4L2_COLORSPACE_JPEG; | 656 | format->colorspace = V4L2_COLORSPACE_JPEG; |
657 | format->code = s5pcsis_formats[0].code; | 657 | format->code = s5pcsis_formats[0].code; |
diff --git a/drivers/media/platform/m2m-deinterlace.c b/drivers/media/platform/m2m-deinterlace.c index b70c1aecca37..92d954973ccf 100644 --- a/drivers/media/platform/m2m-deinterlace.c +++ b/drivers/media/platform/m2m-deinterlace.c | |||
@@ -127,7 +127,7 @@ static struct deinterlace_fmt *find_format(struct v4l2_format *f) | |||
127 | 127 | ||
128 | struct deinterlace_dev { | 128 | struct deinterlace_dev { |
129 | struct v4l2_device v4l2_dev; | 129 | struct v4l2_device v4l2_dev; |
130 | struct video_device *vfd; | 130 | struct video_device vfd; |
131 | 131 | ||
132 | atomic_t busy; | 132 | atomic_t busy; |
133 | struct mutex dev_mutex; | 133 | struct mutex dev_mutex; |
@@ -983,7 +983,7 @@ static struct video_device deinterlace_videodev = { | |||
983 | .fops = &deinterlace_fops, | 983 | .fops = &deinterlace_fops, |
984 | .ioctl_ops = &deinterlace_ioctl_ops, | 984 | .ioctl_ops = &deinterlace_ioctl_ops, |
985 | .minor = -1, | 985 | .minor = -1, |
986 | .release = video_device_release, | 986 | .release = video_device_release_empty, |
987 | .vfl_dir = VFL_DIR_M2M, | 987 | .vfl_dir = VFL_DIR_M2M, |
988 | }; | 988 | }; |
989 | 989 | ||
@@ -1026,13 +1026,7 @@ static int deinterlace_probe(struct platform_device *pdev) | |||
1026 | atomic_set(&pcdev->busy, 0); | 1026 | atomic_set(&pcdev->busy, 0); |
1027 | mutex_init(&pcdev->dev_mutex); | 1027 | mutex_init(&pcdev->dev_mutex); |
1028 | 1028 | ||
1029 | vfd = video_device_alloc(); | 1029 | vfd = &pcdev->vfd; |
1030 | if (!vfd) { | ||
1031 | v4l2_err(&pcdev->v4l2_dev, "Failed to allocate video device\n"); | ||
1032 | ret = -ENOMEM; | ||
1033 | goto unreg_dev; | ||
1034 | } | ||
1035 | |||
1036 | *vfd = deinterlace_videodev; | 1030 | *vfd = deinterlace_videodev; |
1037 | vfd->lock = &pcdev->dev_mutex; | 1031 | vfd->lock = &pcdev->dev_mutex; |
1038 | vfd->v4l2_dev = &pcdev->v4l2_dev; | 1032 | vfd->v4l2_dev = &pcdev->v4l2_dev; |
@@ -1040,12 +1034,11 @@ static int deinterlace_probe(struct platform_device *pdev) | |||
1040 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); | 1034 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); |
1041 | if (ret) { | 1035 | if (ret) { |
1042 | v4l2_err(&pcdev->v4l2_dev, "Failed to register video device\n"); | 1036 | v4l2_err(&pcdev->v4l2_dev, "Failed to register video device\n"); |
1043 | goto rel_vdev; | 1037 | goto unreg_dev; |
1044 | } | 1038 | } |
1045 | 1039 | ||
1046 | video_set_drvdata(vfd, pcdev); | 1040 | video_set_drvdata(vfd, pcdev); |
1047 | snprintf(vfd->name, sizeof(vfd->name), "%s", deinterlace_videodev.name); | 1041 | snprintf(vfd->name, sizeof(vfd->name), "%s", deinterlace_videodev.name); |
1048 | pcdev->vfd = vfd; | ||
1049 | v4l2_info(&pcdev->v4l2_dev, MEM2MEM_TEST_MODULE_NAME | 1042 | v4l2_info(&pcdev->v4l2_dev, MEM2MEM_TEST_MODULE_NAME |
1050 | " Device registered as /dev/video%d\n", vfd->num); | 1043 | " Device registered as /dev/video%d\n", vfd->num); |
1051 | 1044 | ||
@@ -1069,11 +1062,9 @@ static int deinterlace_probe(struct platform_device *pdev) | |||
1069 | 1062 | ||
1070 | v4l2_m2m_release(pcdev->m2m_dev); | 1063 | v4l2_m2m_release(pcdev->m2m_dev); |
1071 | err_m2m: | 1064 | err_m2m: |
1072 | video_unregister_device(pcdev->vfd); | 1065 | video_unregister_device(&pcdev->vfd); |
1073 | err_ctx: | 1066 | err_ctx: |
1074 | vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx); | 1067 | vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx); |
1075 | rel_vdev: | ||
1076 | video_device_release(vfd); | ||
1077 | unreg_dev: | 1068 | unreg_dev: |
1078 | v4l2_device_unregister(&pcdev->v4l2_dev); | 1069 | v4l2_device_unregister(&pcdev->v4l2_dev); |
1079 | rel_dma: | 1070 | rel_dma: |
@@ -1088,7 +1079,7 @@ static int deinterlace_remove(struct platform_device *pdev) | |||
1088 | 1079 | ||
1089 | v4l2_info(&pcdev->v4l2_dev, "Removing " MEM2MEM_TEST_MODULE_NAME); | 1080 | v4l2_info(&pcdev->v4l2_dev, "Removing " MEM2MEM_TEST_MODULE_NAME); |
1090 | v4l2_m2m_release(pcdev->m2m_dev); | 1081 | v4l2_m2m_release(pcdev->m2m_dev); |
1091 | video_unregister_device(pcdev->vfd); | 1082 | video_unregister_device(&pcdev->vfd); |
1092 | v4l2_device_unregister(&pcdev->v4l2_dev); | 1083 | v4l2_device_unregister(&pcdev->v4l2_dev); |
1093 | vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx); | 1084 | vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx); |
1094 | dma_release_channel(pcdev->dma_chan); | 1085 | dma_release_channel(pcdev->dma_chan); |
diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index dd5b1415f974..9c64b5d01c6a 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c | |||
@@ -1568,24 +1568,64 @@ static int mcam_vidioc_enum_framesizes(struct file *filp, void *priv, | |||
1568 | struct v4l2_frmsizeenum *sizes) | 1568 | struct v4l2_frmsizeenum *sizes) |
1569 | { | 1569 | { |
1570 | struct mcam_camera *cam = priv; | 1570 | struct mcam_camera *cam = priv; |
1571 | struct mcam_format_struct *f; | ||
1572 | struct v4l2_subdev_frame_size_enum fse = { | ||
1573 | .index = sizes->index, | ||
1574 | .which = V4L2_SUBDEV_FORMAT_ACTIVE, | ||
1575 | }; | ||
1571 | int ret; | 1576 | int ret; |
1572 | 1577 | ||
1578 | f = mcam_find_format(sizes->pixel_format); | ||
1579 | if (f->pixelformat != sizes->pixel_format) | ||
1580 | return -EINVAL; | ||
1581 | fse.code = f->mbus_code; | ||
1573 | mutex_lock(&cam->s_mutex); | 1582 | mutex_lock(&cam->s_mutex); |
1574 | ret = sensor_call(cam, video, enum_framesizes, sizes); | 1583 | ret = sensor_call(cam, pad, enum_frame_size, NULL, &fse); |
1575 | mutex_unlock(&cam->s_mutex); | 1584 | mutex_unlock(&cam->s_mutex); |
1576 | return ret; | 1585 | if (ret) |
1586 | return ret; | ||
1587 | if (fse.min_width == fse.max_width && | ||
1588 | fse.min_height == fse.max_height) { | ||
1589 | sizes->type = V4L2_FRMSIZE_TYPE_DISCRETE; | ||
1590 | sizes->discrete.width = fse.min_width; | ||
1591 | sizes->discrete.height = fse.min_height; | ||
1592 | return 0; | ||
1593 | } | ||
1594 | sizes->type = V4L2_FRMSIZE_TYPE_CONTINUOUS; | ||
1595 | sizes->stepwise.min_width = fse.min_width; | ||
1596 | sizes->stepwise.max_width = fse.max_width; | ||
1597 | sizes->stepwise.min_height = fse.min_height; | ||
1598 | sizes->stepwise.max_height = fse.max_height; | ||
1599 | sizes->stepwise.step_width = 1; | ||
1600 | sizes->stepwise.step_height = 1; | ||
1601 | return 0; | ||
1577 | } | 1602 | } |
1578 | 1603 | ||
1579 | static int mcam_vidioc_enum_frameintervals(struct file *filp, void *priv, | 1604 | static int mcam_vidioc_enum_frameintervals(struct file *filp, void *priv, |
1580 | struct v4l2_frmivalenum *interval) | 1605 | struct v4l2_frmivalenum *interval) |
1581 | { | 1606 | { |
1582 | struct mcam_camera *cam = priv; | 1607 | struct mcam_camera *cam = priv; |
1608 | struct mcam_format_struct *f; | ||
1609 | struct v4l2_subdev_frame_interval_enum fie = { | ||
1610 | .index = interval->index, | ||
1611 | .width = interval->width, | ||
1612 | .height = interval->height, | ||
1613 | .which = V4L2_SUBDEV_FORMAT_ACTIVE, | ||
1614 | }; | ||
1583 | int ret; | 1615 | int ret; |
1584 | 1616 | ||
1617 | f = mcam_find_format(interval->pixel_format); | ||
1618 | if (f->pixelformat != interval->pixel_format) | ||
1619 | return -EINVAL; | ||
1620 | fie.code = f->mbus_code; | ||
1585 | mutex_lock(&cam->s_mutex); | 1621 | mutex_lock(&cam->s_mutex); |
1586 | ret = sensor_call(cam, video, enum_frameintervals, interval); | 1622 | ret = sensor_call(cam, pad, enum_frame_interval, NULL, &fie); |
1587 | mutex_unlock(&cam->s_mutex); | 1623 | mutex_unlock(&cam->s_mutex); |
1588 | return ret; | 1624 | if (ret) |
1625 | return ret; | ||
1626 | interval->type = V4L2_FRMIVAL_TYPE_DISCRETE; | ||
1627 | interval->discrete = fie.interval; | ||
1628 | return 0; | ||
1589 | } | 1629 | } |
1590 | 1630 | ||
1591 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1631 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c index ba2d8f973d58..17b189a81ec5 100644 --- a/drivers/media/platform/omap/omap_vout.c +++ b/drivers/media/platform/omap/omap_vout.c | |||
@@ -1978,7 +1978,7 @@ static int __init omap_vout_setup_video_bufs(struct platform_device *pdev, | |||
1978 | vout->cropped_offset = 0; | 1978 | vout->cropped_offset = 0; |
1979 | 1979 | ||
1980 | if (ovid->rotation_type == VOUT_ROT_VRFB) { | 1980 | if (ovid->rotation_type == VOUT_ROT_VRFB) { |
1981 | int static_vrfb_allocation = (vid_num == 0) ? | 1981 | bool static_vrfb_allocation = (vid_num == 0) ? |
1982 | vid1_static_vrfb_alloc : vid2_static_vrfb_alloc; | 1982 | vid1_static_vrfb_alloc : vid2_static_vrfb_alloc; |
1983 | ret = omap_vout_setup_vrfb_bufs(pdev, vid_num, | 1983 | ret = omap_vout_setup_vrfb_bufs(pdev, vid_num, |
1984 | static_vrfb_allocation); | 1984 | static_vrfb_allocation); |
diff --git a/drivers/media/platform/omap/omap_vout_vrfb.c b/drivers/media/platform/omap/omap_vout_vrfb.c index aa39306afc73..c6e252760c62 100644 --- a/drivers/media/platform/omap/omap_vout_vrfb.c +++ b/drivers/media/platform/omap/omap_vout_vrfb.c | |||
@@ -21,6 +21,7 @@ | |||
21 | 21 | ||
22 | #include "omap_voutdef.h" | 22 | #include "omap_voutdef.h" |
23 | #include "omap_voutlib.h" | 23 | #include "omap_voutlib.h" |
24 | #include "omap_vout_vrfb.h" | ||
24 | 25 | ||
25 | #define OMAP_DMA_NO_DEVICE 0 | 26 | #define OMAP_DMA_NO_DEVICE 0 |
26 | 27 | ||
diff --git a/drivers/media/platform/omap/omap_vout_vrfb.h b/drivers/media/platform/omap/omap_vout_vrfb.h index 4c2314839b48..c976975024df 100644 --- a/drivers/media/platform/omap/omap_vout_vrfb.h +++ b/drivers/media/platform/omap/omap_vout_vrfb.h | |||
@@ -15,7 +15,7 @@ | |||
15 | #ifdef CONFIG_VIDEO_OMAP2_VOUT_VRFB | 15 | #ifdef CONFIG_VIDEO_OMAP2_VOUT_VRFB |
16 | void omap_vout_free_vrfb_buffers(struct omap_vout_device *vout); | 16 | void omap_vout_free_vrfb_buffers(struct omap_vout_device *vout); |
17 | int omap_vout_setup_vrfb_bufs(struct platform_device *pdev, int vid_num, | 17 | int omap_vout_setup_vrfb_bufs(struct platform_device *pdev, int vid_num, |
18 | u32 static_vrfb_allocation); | 18 | bool static_vrfb_allocation); |
19 | void omap_vout_release_vrfb(struct omap_vout_device *vout); | 19 | void omap_vout_release_vrfb(struct omap_vout_device *vout); |
20 | int omap_vout_vrfb_buffer_setup(struct omap_vout_device *vout, | 20 | int omap_vout_vrfb_buffer_setup(struct omap_vout_device *vout, |
21 | unsigned int *count, unsigned int startindex); | 21 | unsigned int *count, unsigned int startindex); |
@@ -25,7 +25,7 @@ void omap_vout_calculate_vrfb_offset(struct omap_vout_device *vout); | |||
25 | #else | 25 | #else |
26 | static inline void omap_vout_free_vrfb_buffers(struct omap_vout_device *vout) { }; | 26 | static inline void omap_vout_free_vrfb_buffers(struct omap_vout_device *vout) { }; |
27 | static inline int omap_vout_setup_vrfb_bufs(struct platform_device *pdev, int vid_num, | 27 | static inline int omap_vout_setup_vrfb_bufs(struct platform_device *pdev, int vid_num, |
28 | u32 static_vrfb_allocation) | 28 | bool static_vrfb_allocation) |
29 | { return 0; }; | 29 | { return 0; }; |
30 | static inline void omap_vout_release_vrfb(struct omap_vout_device *vout) { }; | 30 | static inline void omap_vout_release_vrfb(struct omap_vout_device *vout) { }; |
31 | static inline int omap_vout_vrfb_buffer_setup(struct omap_vout_device *vout, | 31 | static inline int omap_vout_vrfb_buffer_setup(struct omap_vout_device *vout, |
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index deca80903c3a..18d0a871747f 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #include <linux/dma-mapping.h> | 51 | #include <linux/dma-mapping.h> |
52 | #include <linux/i2c.h> | 52 | #include <linux/i2c.h> |
53 | #include <linux/interrupt.h> | 53 | #include <linux/interrupt.h> |
54 | #include <linux/mfd/syscon.h> | ||
54 | #include <linux/module.h> | 55 | #include <linux/module.h> |
55 | #include <linux/omap-iommu.h> | 56 | #include <linux/omap-iommu.h> |
56 | #include <linux/platform_device.h> | 57 | #include <linux/platform_device.h> |
@@ -63,6 +64,7 @@ | |||
63 | 64 | ||
64 | #include <media/v4l2-common.h> | 65 | #include <media/v4l2-common.h> |
65 | #include <media/v4l2-device.h> | 66 | #include <media/v4l2-device.h> |
67 | #include <media/v4l2-of.h> | ||
66 | 68 | ||
67 | #include "isp.h" | 69 | #include "isp.h" |
68 | #include "ispreg.h" | 70 | #include "ispreg.h" |
@@ -85,35 +87,45 @@ static void isp_restore_ctx(struct isp_device *isp); | |||
85 | static const struct isp_res_mapping isp_res_maps[] = { | 87 | static const struct isp_res_mapping isp_res_maps[] = { |
86 | { | 88 | { |
87 | .isp_rev = ISP_REVISION_2_0, | 89 | .isp_rev = ISP_REVISION_2_0, |
88 | .map = 1 << OMAP3_ISP_IOMEM_MAIN | | 90 | .offset = { |
89 | 1 << OMAP3_ISP_IOMEM_CCP2 | | 91 | /* first MMIO area */ |
90 | 1 << OMAP3_ISP_IOMEM_CCDC | | 92 | 0x0000, /* base, len 0x0070 */ |
91 | 1 << OMAP3_ISP_IOMEM_HIST | | 93 | 0x0400, /* ccp2, len 0x01f0 */ |
92 | 1 << OMAP3_ISP_IOMEM_H3A | | 94 | 0x0600, /* ccdc, len 0x00a8 */ |
93 | 1 << OMAP3_ISP_IOMEM_PREV | | 95 | 0x0a00, /* hist, len 0x0048 */ |
94 | 1 << OMAP3_ISP_IOMEM_RESZ | | 96 | 0x0c00, /* h3a, len 0x0060 */ |
95 | 1 << OMAP3_ISP_IOMEM_SBL | | 97 | 0x0e00, /* preview, len 0x00a0 */ |
96 | 1 << OMAP3_ISP_IOMEM_CSI2A_REGS1 | | 98 | 0x1000, /* resizer, len 0x00ac */ |
97 | 1 << OMAP3_ISP_IOMEM_CSIPHY2 | | 99 | 0x1200, /* sbl, len 0x00fc */ |
98 | 1 << OMAP3_ISP_IOMEM_343X_CONTROL_CSIRXFE, | 100 | /* second MMIO area */ |
101 | 0x0000, /* csi2a, len 0x0170 */ | ||
102 | 0x0170, /* csiphy2, len 0x000c */ | ||
103 | }, | ||
104 | .syscon_offset = 0xdc, | ||
105 | .phy_type = ISP_PHY_TYPE_3430, | ||
99 | }, | 106 | }, |
100 | { | 107 | { |
101 | .isp_rev = ISP_REVISION_15_0, | 108 | .isp_rev = ISP_REVISION_15_0, |
102 | .map = 1 << OMAP3_ISP_IOMEM_MAIN | | 109 | .offset = { |
103 | 1 << OMAP3_ISP_IOMEM_CCP2 | | 110 | /* first MMIO area */ |
104 | 1 << OMAP3_ISP_IOMEM_CCDC | | 111 | 0x0000, /* base, len 0x0070 */ |
105 | 1 << OMAP3_ISP_IOMEM_HIST | | 112 | 0x0400, /* ccp2, len 0x01f0 */ |
106 | 1 << OMAP3_ISP_IOMEM_H3A | | 113 | 0x0600, /* ccdc, len 0x00a8 */ |
107 | 1 << OMAP3_ISP_IOMEM_PREV | | 114 | 0x0a00, /* hist, len 0x0048 */ |
108 | 1 << OMAP3_ISP_IOMEM_RESZ | | 115 | 0x0c00, /* h3a, len 0x0060 */ |
109 | 1 << OMAP3_ISP_IOMEM_SBL | | 116 | 0x0e00, /* preview, len 0x00a0 */ |
110 | 1 << OMAP3_ISP_IOMEM_CSI2A_REGS1 | | 117 | 0x1000, /* resizer, len 0x00ac */ |
111 | 1 << OMAP3_ISP_IOMEM_CSIPHY2 | | 118 | 0x1200, /* sbl, len 0x00fc */ |
112 | 1 << OMAP3_ISP_IOMEM_CSI2A_REGS2 | | 119 | /* second MMIO area */ |
113 | 1 << OMAP3_ISP_IOMEM_CSI2C_REGS1 | | 120 | 0x0000, /* csi2a, len 0x0170 (1st area) */ |
114 | 1 << OMAP3_ISP_IOMEM_CSIPHY1 | | 121 | 0x0170, /* csiphy2, len 0x000c */ |
115 | 1 << OMAP3_ISP_IOMEM_CSI2C_REGS2 | | 122 | 0x01c0, /* csi2a, len 0x0040 (2nd area) */ |
116 | 1 << OMAP3_ISP_IOMEM_3630_CONTROL_CAMERA_PHY_CTRL, | 123 | 0x0400, /* csi2c, len 0x0170 (1st area) */ |
124 | 0x0570, /* csiphy1, len 0x000c */ | ||
125 | 0x05c0, /* csi2c, len 0x0040 (2nd area) */ | ||
126 | }, | ||
127 | .syscon_offset = 0x2f0, | ||
128 | .phy_type = ISP_PHY_TYPE_3630, | ||
117 | }, | 129 | }, |
118 | }; | 130 | }; |
119 | 131 | ||
@@ -279,9 +291,20 @@ static const struct clk_init_data isp_xclk_init_data = { | |||
279 | .num_parents = 1, | 291 | .num_parents = 1, |
280 | }; | 292 | }; |
281 | 293 | ||
294 | static struct clk *isp_xclk_src_get(struct of_phandle_args *clkspec, void *data) | ||
295 | { | ||
296 | unsigned int idx = clkspec->args[0]; | ||
297 | struct isp_device *isp = data; | ||
298 | |||
299 | if (idx >= ARRAY_SIZE(isp->xclks)) | ||
300 | return ERR_PTR(-ENOENT); | ||
301 | |||
302 | return isp->xclks[idx].clk; | ||
303 | } | ||
304 | |||
282 | static int isp_xclk_init(struct isp_device *isp) | 305 | static int isp_xclk_init(struct isp_device *isp) |
283 | { | 306 | { |
284 | struct isp_platform_data *pdata = isp->pdata; | 307 | struct device_node *np = isp->dev->of_node; |
285 | struct clk_init_data init; | 308 | struct clk_init_data init; |
286 | unsigned int i; | 309 | unsigned int i; |
287 | 310 | ||
@@ -311,37 +334,27 @@ static int isp_xclk_init(struct isp_device *isp) | |||
311 | xclk->clk = clk_register(NULL, &xclk->hw); | 334 | xclk->clk = clk_register(NULL, &xclk->hw); |
312 | if (IS_ERR(xclk->clk)) | 335 | if (IS_ERR(xclk->clk)) |
313 | return PTR_ERR(xclk->clk); | 336 | return PTR_ERR(xclk->clk); |
314 | |||
315 | if (pdata->xclks[i].con_id == NULL && | ||
316 | pdata->xclks[i].dev_id == NULL) | ||
317 | continue; | ||
318 | |||
319 | xclk->lookup = kzalloc(sizeof(*xclk->lookup), GFP_KERNEL); | ||
320 | if (xclk->lookup == NULL) | ||
321 | return -ENOMEM; | ||
322 | |||
323 | xclk->lookup->con_id = pdata->xclks[i].con_id; | ||
324 | xclk->lookup->dev_id = pdata->xclks[i].dev_id; | ||
325 | xclk->lookup->clk = xclk->clk; | ||
326 | |||
327 | clkdev_add(xclk->lookup); | ||
328 | } | 337 | } |
329 | 338 | ||
339 | if (np) | ||
340 | of_clk_add_provider(np, isp_xclk_src_get, isp); | ||
341 | |||
330 | return 0; | 342 | return 0; |
331 | } | 343 | } |
332 | 344 | ||
333 | static void isp_xclk_cleanup(struct isp_device *isp) | 345 | static void isp_xclk_cleanup(struct isp_device *isp) |
334 | { | 346 | { |
347 | struct device_node *np = isp->dev->of_node; | ||
335 | unsigned int i; | 348 | unsigned int i; |
336 | 349 | ||
350 | if (np) | ||
351 | of_clk_del_provider(np); | ||
352 | |||
337 | for (i = 0; i < ARRAY_SIZE(isp->xclks); ++i) { | 353 | for (i = 0; i < ARRAY_SIZE(isp->xclks); ++i) { |
338 | struct isp_xclk *xclk = &isp->xclks[i]; | 354 | struct isp_xclk *xclk = &isp->xclks[i]; |
339 | 355 | ||
340 | if (!IS_ERR(xclk->clk)) | 356 | if (!IS_ERR(xclk->clk)) |
341 | clk_unregister(xclk->clk); | 357 | clk_unregister(xclk->clk); |
342 | |||
343 | if (xclk->lookup) | ||
344 | clkdev_drop(xclk->lookup); | ||
345 | } | 358 | } |
346 | } | 359 | } |
347 | 360 | ||
@@ -422,7 +435,7 @@ static void isp_core_init(struct isp_device *isp, int idle) | |||
422 | */ | 435 | */ |
423 | void omap3isp_configure_bridge(struct isp_device *isp, | 436 | void omap3isp_configure_bridge(struct isp_device *isp, |
424 | enum ccdc_input_entity input, | 437 | enum ccdc_input_entity input, |
425 | const struct isp_parallel_platform_data *pdata, | 438 | const struct isp_parallel_cfg *parcfg, |
426 | unsigned int shift, unsigned int bridge) | 439 | unsigned int shift, unsigned int bridge) |
427 | { | 440 | { |
428 | u32 ispctrl_val; | 441 | u32 ispctrl_val; |
@@ -437,8 +450,8 @@ void omap3isp_configure_bridge(struct isp_device *isp, | |||
437 | switch (input) { | 450 | switch (input) { |
438 | case CCDC_INPUT_PARALLEL: | 451 | case CCDC_INPUT_PARALLEL: |
439 | ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_PARALLEL; | 452 | ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_PARALLEL; |
440 | ispctrl_val |= pdata->clk_pol << ISPCTRL_PAR_CLK_POL_SHIFT; | 453 | ispctrl_val |= parcfg->clk_pol << ISPCTRL_PAR_CLK_POL_SHIFT; |
441 | shift += pdata->data_lane_shift * 2; | 454 | shift += parcfg->data_lane_shift * 2; |
442 | break; | 455 | break; |
443 | 456 | ||
444 | case CCDC_INPUT_CSI2A: | 457 | case CCDC_INPUT_CSI2A: |
@@ -1784,58 +1797,121 @@ static void isp_unregister_entities(struct isp_device *isp) | |||
1784 | } | 1797 | } |
1785 | 1798 | ||
1786 | /* | 1799 | /* |
1787 | * isp_register_subdev_group - Register a group of subdevices | 1800 | * isp_register_subdev - Register a sub-device |
1788 | * @isp: OMAP3 ISP device | 1801 | * @isp: OMAP3 ISP device |
1789 | * @board_info: I2C subdevs board information array | 1802 | * @isp_subdev: platform data related to a sub-device |
1790 | * | 1803 | * |
1791 | * Register all I2C subdevices in the board_info array. The array must be | 1804 | * Register an I2C sub-device which has not been registered by other |
1792 | * terminated by a NULL entry, and the first entry must be the sensor. | 1805 | * means (such as the Device Tree). |
1793 | * | 1806 | * |
1794 | * Return a pointer to the sensor media entity if it has been successfully | 1807 | * Return a pointer to the sub-device if it has been successfully |
1795 | * registered, or NULL otherwise. | 1808 | * registered, or NULL otherwise. |
1796 | */ | 1809 | */ |
1797 | static struct v4l2_subdev * | 1810 | static struct v4l2_subdev * |
1798 | isp_register_subdev_group(struct isp_device *isp, | 1811 | isp_register_subdev(struct isp_device *isp, |
1799 | struct isp_subdev_i2c_board_info *board_info) | 1812 | struct isp_platform_subdev *isp_subdev) |
1800 | { | 1813 | { |
1801 | struct v4l2_subdev *sensor = NULL; | 1814 | struct i2c_adapter *adapter; |
1802 | unsigned int first; | 1815 | struct v4l2_subdev *sd; |
1803 | 1816 | ||
1804 | if (board_info->board_info == NULL) | 1817 | if (isp_subdev->board_info == NULL) |
1805 | return NULL; | 1818 | return NULL; |
1806 | 1819 | ||
1807 | for (first = 1; board_info->board_info; ++board_info, first = 0) { | 1820 | adapter = i2c_get_adapter(isp_subdev->i2c_adapter_id); |
1808 | struct v4l2_subdev *subdev; | 1821 | if (adapter == NULL) { |
1809 | struct i2c_adapter *adapter; | 1822 | dev_err(isp->dev, |
1823 | "%s: Unable to get I2C adapter %d for device %s\n", | ||
1824 | __func__, isp_subdev->i2c_adapter_id, | ||
1825 | isp_subdev->board_info->type); | ||
1826 | return NULL; | ||
1827 | } | ||
1810 | 1828 | ||
1811 | adapter = i2c_get_adapter(board_info->i2c_adapter_id); | 1829 | sd = v4l2_i2c_new_subdev_board(&isp->v4l2_dev, adapter, |
1812 | if (adapter == NULL) { | 1830 | isp_subdev->board_info, NULL); |
1813 | dev_err(isp->dev, "%s: Unable to get I2C adapter %d for " | 1831 | if (sd == NULL) { |
1814 | "device %s\n", __func__, | 1832 | dev_err(isp->dev, "%s: Unable to register subdev %s\n", |
1815 | board_info->i2c_adapter_id, | 1833 | __func__, isp_subdev->board_info->type); |
1816 | board_info->board_info->type); | 1834 | return NULL; |
1817 | continue; | 1835 | } |
1818 | } | ||
1819 | 1836 | ||
1820 | subdev = v4l2_i2c_new_subdev_board(&isp->v4l2_dev, adapter, | 1837 | return sd; |
1821 | board_info->board_info, NULL); | 1838 | } |
1822 | if (subdev == NULL) { | 1839 | |
1823 | dev_err(isp->dev, "%s: Unable to register subdev %s\n", | 1840 | static int isp_link_entity( |
1824 | __func__, board_info->board_info->type); | 1841 | struct isp_device *isp, struct media_entity *entity, |
1825 | continue; | 1842 | enum isp_interface_type interface) |
1826 | } | 1843 | { |
1844 | struct media_entity *input; | ||
1845 | unsigned int flags; | ||
1846 | unsigned int pad; | ||
1847 | unsigned int i; | ||
1848 | |||
1849 | /* Connect the sensor to the correct interface module. | ||
1850 | * Parallel sensors are connected directly to the CCDC, while | ||
1851 | * serial sensors are connected to the CSI2a, CCP2b or CSI2c | ||
1852 | * receiver through CSIPHY1 or CSIPHY2. | ||
1853 | */ | ||
1854 | switch (interface) { | ||
1855 | case ISP_INTERFACE_PARALLEL: | ||
1856 | input = &isp->isp_ccdc.subdev.entity; | ||
1857 | pad = CCDC_PAD_SINK; | ||
1858 | flags = 0; | ||
1859 | break; | ||
1860 | |||
1861 | case ISP_INTERFACE_CSI2A_PHY2: | ||
1862 | input = &isp->isp_csi2a.subdev.entity; | ||
1863 | pad = CSI2_PAD_SINK; | ||
1864 | flags = MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED; | ||
1865 | break; | ||
1866 | |||
1867 | case ISP_INTERFACE_CCP2B_PHY1: | ||
1868 | case ISP_INTERFACE_CCP2B_PHY2: | ||
1869 | input = &isp->isp_ccp2.subdev.entity; | ||
1870 | pad = CCP2_PAD_SINK; | ||
1871 | flags = 0; | ||
1872 | break; | ||
1873 | |||
1874 | case ISP_INTERFACE_CSI2C_PHY1: | ||
1875 | input = &isp->isp_csi2c.subdev.entity; | ||
1876 | pad = CSI2_PAD_SINK; | ||
1877 | flags = MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED; | ||
1878 | break; | ||
1827 | 1879 | ||
1828 | if (first) | 1880 | default: |
1829 | sensor = subdev; | 1881 | dev_err(isp->dev, "%s: invalid interface type %u\n", __func__, |
1882 | interface); | ||
1883 | return -EINVAL; | ||
1884 | } | ||
1885 | |||
1886 | /* | ||
1887 | * Not all interfaces are available on all revisions of the | ||
1888 | * ISP. The sub-devices of those interfaces aren't initialised | ||
1889 | * in such a case. Check this by ensuring the num_pads is | ||
1890 | * non-zero. | ||
1891 | */ | ||
1892 | if (!input->num_pads) { | ||
1893 | dev_err(isp->dev, "%s: invalid input %u\n", entity->name, | ||
1894 | interface); | ||
1895 | return -EINVAL; | ||
1896 | } | ||
1897 | |||
1898 | for (i = 0; i < entity->num_pads; i++) { | ||
1899 | if (entity->pads[i].flags & MEDIA_PAD_FL_SOURCE) | ||
1900 | break; | ||
1901 | } | ||
1902 | if (i == entity->num_pads) { | ||
1903 | dev_err(isp->dev, "%s: no source pad in external entity\n", | ||
1904 | __func__); | ||
1905 | return -EINVAL; | ||
1830 | } | 1906 | } |
1831 | 1907 | ||
1832 | return sensor; | 1908 | return media_entity_create_link(entity, i, input, pad, flags); |
1833 | } | 1909 | } |
1834 | 1910 | ||
1835 | static int isp_register_entities(struct isp_device *isp) | 1911 | static int isp_register_entities(struct isp_device *isp) |
1836 | { | 1912 | { |
1837 | struct isp_platform_data *pdata = isp->pdata; | 1913 | struct isp_platform_data *pdata = isp->pdata; |
1838 | struct isp_v4l2_subdevs_group *subdevs; | 1914 | struct isp_platform_subdev *isp_subdev; |
1839 | int ret; | 1915 | int ret; |
1840 | 1916 | ||
1841 | isp->media_dev.dev = isp->dev; | 1917 | isp->media_dev.dev = isp->dev; |
@@ -1892,74 +1968,31 @@ static int isp_register_entities(struct isp_device *isp) | |||
1892 | if (ret < 0) | 1968 | if (ret < 0) |
1893 | goto done; | 1969 | goto done; |
1894 | 1970 | ||
1971 | /* | ||
1972 | * Device Tree --- the external sub-devices will be registered | ||
1973 | * later. The same goes for the sub-device node registration. | ||
1974 | */ | ||
1975 | if (isp->dev->of_node) | ||
1976 | return 0; | ||
1977 | |||
1895 | /* Register external entities */ | 1978 | /* Register external entities */ |
1896 | for (subdevs = pdata->subdevs; subdevs && subdevs->subdevs; ++subdevs) { | 1979 | for (isp_subdev = pdata ? pdata->subdevs : NULL; |
1897 | struct v4l2_subdev *sensor; | 1980 | isp_subdev && isp_subdev->board_info; isp_subdev++) { |
1898 | struct media_entity *input; | 1981 | struct v4l2_subdev *sd; |
1899 | unsigned int flags; | ||
1900 | unsigned int pad; | ||
1901 | unsigned int i; | ||
1902 | |||
1903 | sensor = isp_register_subdev_group(isp, subdevs->subdevs); | ||
1904 | if (sensor == NULL) | ||
1905 | continue; | ||
1906 | 1982 | ||
1907 | sensor->host_priv = subdevs; | 1983 | sd = isp_register_subdev(isp, isp_subdev); |
1908 | 1984 | ||
1909 | /* Connect the sensor to the correct interface module. Parallel | 1985 | /* |
1910 | * sensors are connected directly to the CCDC, while serial | 1986 | * No bus information --- this is either a flash or a |
1911 | * sensors are connected to the CSI2a, CCP2b or CSI2c receiver | 1987 | * lens subdev. |
1912 | * through CSIPHY1 or CSIPHY2. | ||
1913 | */ | 1988 | */ |
1914 | switch (subdevs->interface) { | 1989 | if (!sd || !isp_subdev->bus) |
1915 | case ISP_INTERFACE_PARALLEL: | 1990 | continue; |
1916 | input = &isp->isp_ccdc.subdev.entity; | ||
1917 | pad = CCDC_PAD_SINK; | ||
1918 | flags = 0; | ||
1919 | break; | ||
1920 | |||
1921 | case ISP_INTERFACE_CSI2A_PHY2: | ||
1922 | input = &isp->isp_csi2a.subdev.entity; | ||
1923 | pad = CSI2_PAD_SINK; | ||
1924 | flags = MEDIA_LNK_FL_IMMUTABLE | ||
1925 | | MEDIA_LNK_FL_ENABLED; | ||
1926 | break; | ||
1927 | |||
1928 | case ISP_INTERFACE_CCP2B_PHY1: | ||
1929 | case ISP_INTERFACE_CCP2B_PHY2: | ||
1930 | input = &isp->isp_ccp2.subdev.entity; | ||
1931 | pad = CCP2_PAD_SINK; | ||
1932 | flags = 0; | ||
1933 | break; | ||
1934 | |||
1935 | case ISP_INTERFACE_CSI2C_PHY1: | ||
1936 | input = &isp->isp_csi2c.subdev.entity; | ||
1937 | pad = CSI2_PAD_SINK; | ||
1938 | flags = MEDIA_LNK_FL_IMMUTABLE | ||
1939 | | MEDIA_LNK_FL_ENABLED; | ||
1940 | break; | ||
1941 | |||
1942 | default: | ||
1943 | dev_err(isp->dev, "%s: invalid interface type %u\n", | ||
1944 | __func__, subdevs->interface); | ||
1945 | ret = -EINVAL; | ||
1946 | goto done; | ||
1947 | } | ||
1948 | 1991 | ||
1949 | for (i = 0; i < sensor->entity.num_pads; i++) { | 1992 | sd->host_priv = isp_subdev->bus; |
1950 | if (sensor->entity.pads[i].flags & MEDIA_PAD_FL_SOURCE) | ||
1951 | break; | ||
1952 | } | ||
1953 | if (i == sensor->entity.num_pads) { | ||
1954 | dev_err(isp->dev, | ||
1955 | "%s: no source pad in external entity\n", | ||
1956 | __func__); | ||
1957 | ret = -EINVAL; | ||
1958 | goto done; | ||
1959 | } | ||
1960 | 1993 | ||
1961 | ret = media_entity_create_link(&sensor->entity, i, input, pad, | 1994 | ret = isp_link_entity(isp, &sd->entity, |
1962 | flags); | 1995 | isp_subdev->bus->interface); |
1963 | if (ret < 0) | 1996 | if (ret < 0) |
1964 | goto done; | 1997 | goto done; |
1965 | } | 1998 | } |
@@ -1967,8 +2000,10 @@ static int isp_register_entities(struct isp_device *isp) | |||
1967 | ret = v4l2_device_register_subdev_nodes(&isp->v4l2_dev); | 2000 | ret = v4l2_device_register_subdev_nodes(&isp->v4l2_dev); |
1968 | 2001 | ||
1969 | done: | 2002 | done: |
1970 | if (ret < 0) | 2003 | if (ret < 0) { |
1971 | isp_unregister_entities(isp); | 2004 | isp_unregister_entities(isp); |
2005 | v4l2_async_notifier_unregister(&isp->notifier); | ||
2006 | } | ||
1972 | 2007 | ||
1973 | return ret; | 2008 | return ret; |
1974 | } | 2009 | } |
@@ -2183,6 +2218,7 @@ static int isp_remove(struct platform_device *pdev) | |||
2183 | { | 2218 | { |
2184 | struct isp_device *isp = platform_get_drvdata(pdev); | 2219 | struct isp_device *isp = platform_get_drvdata(pdev); |
2185 | 2220 | ||
2221 | v4l2_async_notifier_unregister(&isp->notifier); | ||
2186 | isp_unregister_entities(isp); | 2222 | isp_unregister_entities(isp); |
2187 | isp_cleanup_modules(isp); | 2223 | isp_cleanup_modules(isp); |
2188 | isp_xclk_cleanup(isp); | 2224 | isp_xclk_cleanup(isp); |
@@ -2194,26 +2230,156 @@ static int isp_remove(struct platform_device *pdev) | |||
2194 | return 0; | 2230 | return 0; |
2195 | } | 2231 | } |
2196 | 2232 | ||
2197 | static int isp_map_mem_resource(struct platform_device *pdev, | 2233 | enum isp_of_phy { |
2198 | struct isp_device *isp, | 2234 | ISP_OF_PHY_PARALLEL = 0, |
2199 | enum isp_mem_resources res) | 2235 | ISP_OF_PHY_CSIPHY1, |
2236 | ISP_OF_PHY_CSIPHY2, | ||
2237 | }; | ||
2238 | |||
2239 | static int isp_of_parse_node(struct device *dev, struct device_node *node, | ||
2240 | struct isp_async_subdev *isd) | ||
2200 | { | 2241 | { |
2201 | struct resource *mem; | 2242 | struct isp_bus_cfg *buscfg = &isd->bus; |
2243 | struct v4l2_of_endpoint vep; | ||
2244 | unsigned int i; | ||
2202 | 2245 | ||
2203 | /* request the mem region for the camera registers */ | 2246 | v4l2_of_parse_endpoint(node, &vep); |
2247 | |||
2248 | dev_dbg(dev, "parsing endpoint %s, interface %u\n", node->full_name, | ||
2249 | vep.base.port); | ||
2250 | |||
2251 | switch (vep.base.port) { | ||
2252 | case ISP_OF_PHY_PARALLEL: | ||
2253 | buscfg->interface = ISP_INTERFACE_PARALLEL; | ||
2254 | buscfg->bus.parallel.data_lane_shift = | ||
2255 | vep.bus.parallel.data_shift; | ||
2256 | buscfg->bus.parallel.clk_pol = | ||
2257 | !!(vep.bus.parallel.flags | ||
2258 | & V4L2_MBUS_PCLK_SAMPLE_FALLING); | ||
2259 | buscfg->bus.parallel.hs_pol = | ||
2260 | !!(vep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW); | ||
2261 | buscfg->bus.parallel.vs_pol = | ||
2262 | !!(vep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW); | ||
2263 | buscfg->bus.parallel.fld_pol = | ||
2264 | !!(vep.bus.parallel.flags & V4L2_MBUS_FIELD_EVEN_LOW); | ||
2265 | buscfg->bus.parallel.data_pol = | ||
2266 | !!(vep.bus.parallel.flags & V4L2_MBUS_DATA_ACTIVE_LOW); | ||
2267 | break; | ||
2204 | 2268 | ||
2205 | mem = platform_get_resource(pdev, IORESOURCE_MEM, res); | 2269 | case ISP_OF_PHY_CSIPHY1: |
2270 | case ISP_OF_PHY_CSIPHY2: | ||
2271 | /* FIXME: always assume CSI-2 for now. */ | ||
2272 | switch (vep.base.port) { | ||
2273 | case ISP_OF_PHY_CSIPHY1: | ||
2274 | buscfg->interface = ISP_INTERFACE_CSI2C_PHY1; | ||
2275 | break; | ||
2276 | case ISP_OF_PHY_CSIPHY2: | ||
2277 | buscfg->interface = ISP_INTERFACE_CSI2A_PHY2; | ||
2278 | break; | ||
2279 | } | ||
2280 | buscfg->bus.csi2.lanecfg.clk.pos = vep.bus.mipi_csi2.clock_lane; | ||
2281 | buscfg->bus.csi2.lanecfg.clk.pol = | ||
2282 | vep.bus.mipi_csi2.lane_polarities[0]; | ||
2283 | dev_dbg(dev, "clock lane polarity %u, pos %u\n", | ||
2284 | buscfg->bus.csi2.lanecfg.clk.pol, | ||
2285 | buscfg->bus.csi2.lanecfg.clk.pos); | ||
2286 | |||
2287 | for (i = 0; i < ISP_CSIPHY2_NUM_DATA_LANES; i++) { | ||
2288 | buscfg->bus.csi2.lanecfg.data[i].pos = | ||
2289 | vep.bus.mipi_csi2.data_lanes[i]; | ||
2290 | buscfg->bus.csi2.lanecfg.data[i].pol = | ||
2291 | vep.bus.mipi_csi2.lane_polarities[i + 1]; | ||
2292 | dev_dbg(dev, "data lane %u polarity %u, pos %u\n", i, | ||
2293 | buscfg->bus.csi2.lanecfg.data[i].pol, | ||
2294 | buscfg->bus.csi2.lanecfg.data[i].pos); | ||
2295 | } | ||
2206 | 2296 | ||
2207 | /* map the region */ | 2297 | /* |
2208 | isp->mmio_base[res] = devm_ioremap_resource(isp->dev, mem); | 2298 | * FIXME: now we assume the CRC is always there. |
2209 | if (IS_ERR(isp->mmio_base[res])) | 2299 | * Implement a way to obtain this information from the |
2210 | return PTR_ERR(isp->mmio_base[res]); | 2300 | * sensor. Frame descriptors, perhaps? |
2301 | */ | ||
2302 | buscfg->bus.csi2.crc = 1; | ||
2303 | break; | ||
2211 | 2304 | ||
2212 | isp->mmio_base_phys[res] = mem->start; | 2305 | default: |
2306 | dev_warn(dev, "%s: invalid interface %u\n", node->full_name, | ||
2307 | vep.base.port); | ||
2308 | break; | ||
2309 | } | ||
2213 | 2310 | ||
2214 | return 0; | 2311 | return 0; |
2215 | } | 2312 | } |
2216 | 2313 | ||
2314 | static int isp_of_parse_nodes(struct device *dev, | ||
2315 | struct v4l2_async_notifier *notifier) | ||
2316 | { | ||
2317 | struct device_node *node = NULL; | ||
2318 | |||
2319 | notifier->subdevs = devm_kcalloc( | ||
2320 | dev, ISP_MAX_SUBDEVS, sizeof(*notifier->subdevs), GFP_KERNEL); | ||
2321 | if (!notifier->subdevs) | ||
2322 | return -ENOMEM; | ||
2323 | |||
2324 | while (notifier->num_subdevs < ISP_MAX_SUBDEVS && | ||
2325 | (node = of_graph_get_next_endpoint(dev->of_node, node))) { | ||
2326 | struct isp_async_subdev *isd; | ||
2327 | |||
2328 | isd = devm_kzalloc(dev, sizeof(*isd), GFP_KERNEL); | ||
2329 | if (!isd) { | ||
2330 | of_node_put(node); | ||
2331 | return -ENOMEM; | ||
2332 | } | ||
2333 | |||
2334 | notifier->subdevs[notifier->num_subdevs] = &isd->asd; | ||
2335 | |||
2336 | if (isp_of_parse_node(dev, node, isd)) { | ||
2337 | of_node_put(node); | ||
2338 | return -EINVAL; | ||
2339 | } | ||
2340 | |||
2341 | isd->asd.match.of.node = of_graph_get_remote_port_parent(node); | ||
2342 | of_node_put(node); | ||
2343 | if (!isd->asd.match.of.node) { | ||
2344 | dev_warn(dev, "bad remote port parent\n"); | ||
2345 | return -EINVAL; | ||
2346 | } | ||
2347 | |||
2348 | isd->asd.match_type = V4L2_ASYNC_MATCH_OF; | ||
2349 | notifier->num_subdevs++; | ||
2350 | } | ||
2351 | |||
2352 | return notifier->num_subdevs; | ||
2353 | } | ||
2354 | |||
2355 | static int isp_subdev_notifier_bound(struct v4l2_async_notifier *async, | ||
2356 | struct v4l2_subdev *subdev, | ||
2357 | struct v4l2_async_subdev *asd) | ||
2358 | { | ||
2359 | struct isp_device *isp = container_of(async, struct isp_device, | ||
2360 | notifier); | ||
2361 | struct isp_async_subdev *isd = | ||
2362 | container_of(asd, struct isp_async_subdev, asd); | ||
2363 | int ret; | ||
2364 | |||
2365 | ret = isp_link_entity(isp, &subdev->entity, isd->bus.interface); | ||
2366 | if (ret < 0) | ||
2367 | return ret; | ||
2368 | |||
2369 | isd->sd = subdev; | ||
2370 | isd->sd->host_priv = &isd->bus; | ||
2371 | |||
2372 | return ret; | ||
2373 | } | ||
2374 | |||
2375 | static int isp_subdev_notifier_complete(struct v4l2_async_notifier *async) | ||
2376 | { | ||
2377 | struct isp_device *isp = container_of(async, struct isp_device, | ||
2378 | notifier); | ||
2379 | |||
2380 | return v4l2_device_register_subdev_nodes(&isp->v4l2_dev); | ||
2381 | } | ||
2382 | |||
2217 | /* | 2383 | /* |
2218 | * isp_probe - Probe ISP platform device | 2384 | * isp_probe - Probe ISP platform device |
2219 | * @pdev: Pointer to ISP platform device | 2385 | * @pdev: Pointer to ISP platform device |
@@ -2227,47 +2393,86 @@ static int isp_map_mem_resource(struct platform_device *pdev, | |||
2227 | */ | 2393 | */ |
2228 | static int isp_probe(struct platform_device *pdev) | 2394 | static int isp_probe(struct platform_device *pdev) |
2229 | { | 2395 | { |
2230 | struct isp_platform_data *pdata = pdev->dev.platform_data; | ||
2231 | struct isp_device *isp; | 2396 | struct isp_device *isp; |
2397 | struct resource *mem; | ||
2232 | int ret; | 2398 | int ret; |
2233 | int i, m; | 2399 | int i, m; |
2234 | 2400 | ||
2235 | if (pdata == NULL) | ||
2236 | return -EINVAL; | ||
2237 | |||
2238 | isp = devm_kzalloc(&pdev->dev, sizeof(*isp), GFP_KERNEL); | 2401 | isp = devm_kzalloc(&pdev->dev, sizeof(*isp), GFP_KERNEL); |
2239 | if (!isp) { | 2402 | if (!isp) { |
2240 | dev_err(&pdev->dev, "could not allocate memory\n"); | 2403 | dev_err(&pdev->dev, "could not allocate memory\n"); |
2241 | return -ENOMEM; | 2404 | return -ENOMEM; |
2242 | } | 2405 | } |
2243 | 2406 | ||
2407 | if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) { | ||
2408 | ret = of_property_read_u32(pdev->dev.of_node, "ti,phy-type", | ||
2409 | &isp->phy_type); | ||
2410 | if (ret) | ||
2411 | return ret; | ||
2412 | |||
2413 | isp->syscon = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, | ||
2414 | "syscon"); | ||
2415 | if (IS_ERR(isp->syscon)) | ||
2416 | return PTR_ERR(isp->syscon); | ||
2417 | |||
2418 | ret = of_property_read_u32_index(pdev->dev.of_node, "syscon", 1, | ||
2419 | &isp->syscon_offset); | ||
2420 | if (ret) | ||
2421 | return ret; | ||
2422 | |||
2423 | ret = isp_of_parse_nodes(&pdev->dev, &isp->notifier); | ||
2424 | if (ret < 0) | ||
2425 | return ret; | ||
2426 | ret = v4l2_async_notifier_register(&isp->v4l2_dev, | ||
2427 | &isp->notifier); | ||
2428 | if (ret) | ||
2429 | return ret; | ||
2430 | } else { | ||
2431 | isp->pdata = pdev->dev.platform_data; | ||
2432 | isp->syscon = syscon_regmap_lookup_by_pdevname("syscon.0"); | ||
2433 | if (IS_ERR(isp->syscon)) | ||
2434 | return PTR_ERR(isp->syscon); | ||
2435 | dev_warn(&pdev->dev, | ||
2436 | "Platform data support is deprecated! Please move to DT now!\n"); | ||
2437 | } | ||
2438 | |||
2244 | isp->autoidle = autoidle; | 2439 | isp->autoidle = autoidle; |
2245 | 2440 | ||
2246 | mutex_init(&isp->isp_mutex); | 2441 | mutex_init(&isp->isp_mutex); |
2247 | spin_lock_init(&isp->stat_lock); | 2442 | spin_lock_init(&isp->stat_lock); |
2248 | 2443 | ||
2249 | isp->dev = &pdev->dev; | 2444 | isp->dev = &pdev->dev; |
2250 | isp->pdata = pdata; | ||
2251 | isp->ref_count = 0; | 2445 | isp->ref_count = 0; |
2252 | 2446 | ||
2253 | ret = dma_coerce_mask_and_coherent(isp->dev, DMA_BIT_MASK(32)); | 2447 | ret = dma_coerce_mask_and_coherent(isp->dev, DMA_BIT_MASK(32)); |
2254 | if (ret) | 2448 | if (ret) |
2255 | return ret; | 2449 | goto error; |
2256 | 2450 | ||
2257 | platform_set_drvdata(pdev, isp); | 2451 | platform_set_drvdata(pdev, isp); |
2258 | 2452 | ||
2259 | /* Regulators */ | 2453 | /* Regulators */ |
2260 | isp->isp_csiphy1.vdd = devm_regulator_get(&pdev->dev, "VDD_CSIPHY1"); | 2454 | isp->isp_csiphy1.vdd = devm_regulator_get(&pdev->dev, "vdd-csiphy1"); |
2261 | isp->isp_csiphy2.vdd = devm_regulator_get(&pdev->dev, "VDD_CSIPHY2"); | 2455 | isp->isp_csiphy2.vdd = devm_regulator_get(&pdev->dev, "vdd-csiphy2"); |
2262 | 2456 | ||
2263 | /* Clocks | 2457 | /* Clocks |
2264 | * | 2458 | * |
2265 | * The ISP clock tree is revision-dependent. We thus need to enable ICLK | 2459 | * The ISP clock tree is revision-dependent. We thus need to enable ICLK |
2266 | * manually to read the revision before calling __omap3isp_get(). | 2460 | * manually to read the revision before calling __omap3isp_get(). |
2461 | * | ||
2462 | * Start by mapping the ISP MMIO area, which is in two pieces. | ||
2463 | * The ISP IOMMU is in between. Map both now, and fill in the | ||
2464 | * ISP revision specific portions a little later in the | ||
2465 | * function. | ||
2267 | */ | 2466 | */ |
2268 | ret = isp_map_mem_resource(pdev, isp, OMAP3_ISP_IOMEM_MAIN); | 2467 | for (i = 0; i < 2; i++) { |
2269 | if (ret < 0) | 2468 | unsigned int map_idx = i ? OMAP3_ISP_IOMEM_CSI2A_REGS1 : 0; |
2270 | goto error; | 2469 | |
2470 | mem = platform_get_resource(pdev, IORESOURCE_MEM, i); | ||
2471 | isp->mmio_base[map_idx] = | ||
2472 | devm_ioremap_resource(isp->dev, mem); | ||
2473 | if (IS_ERR(isp->mmio_base[map_idx])) | ||
2474 | return PTR_ERR(isp->mmio_base[map_idx]); | ||
2475 | } | ||
2271 | 2476 | ||
2272 | ret = isp_get_clocks(isp); | 2477 | ret = isp_get_clocks(isp); |
2273 | if (ret < 0) | 2478 | if (ret < 0) |
@@ -2308,14 +2513,23 @@ static int isp_probe(struct platform_device *pdev) | |||
2308 | goto error_isp; | 2513 | goto error_isp; |
2309 | } | 2514 | } |
2310 | 2515 | ||
2311 | for (i = 1; i < OMAP3_ISP_IOMEM_LAST; i++) { | 2516 | if (!IS_ENABLED(CONFIG_OF) || !pdev->dev.of_node) { |
2312 | if (isp_res_maps[m].map & 1 << i) { | 2517 | isp->syscon_offset = isp_res_maps[m].syscon_offset; |
2313 | ret = isp_map_mem_resource(pdev, isp, i); | 2518 | isp->phy_type = isp_res_maps[m].phy_type; |
2314 | if (ret) | ||
2315 | goto error_isp; | ||
2316 | } | ||
2317 | } | 2519 | } |
2318 | 2520 | ||
2521 | for (i = 1; i < OMAP3_ISP_IOMEM_CSI2A_REGS1; i++) | ||
2522 | isp->mmio_base[i] = | ||
2523 | isp->mmio_base[0] + isp_res_maps[m].offset[i]; | ||
2524 | |||
2525 | for (i = OMAP3_ISP_IOMEM_CSIPHY2; i < OMAP3_ISP_IOMEM_LAST; i++) | ||
2526 | isp->mmio_base[i] = | ||
2527 | isp->mmio_base[OMAP3_ISP_IOMEM_CSI2A_REGS1] | ||
2528 | + isp_res_maps[m].offset[i]; | ||
2529 | |||
2530 | isp->mmio_hist_base_phys = | ||
2531 | mem->start + isp_res_maps[m].offset[OMAP3_ISP_IOMEM_HIST]; | ||
2532 | |||
2319 | /* IOMMU */ | 2533 | /* IOMMU */ |
2320 | ret = isp_attach_iommu(isp); | 2534 | ret = isp_attach_iommu(isp); |
2321 | if (ret < 0) { | 2535 | if (ret < 0) { |
@@ -2343,6 +2557,9 @@ static int isp_probe(struct platform_device *pdev) | |||
2343 | if (ret < 0) | 2557 | if (ret < 0) |
2344 | goto error_iommu; | 2558 | goto error_iommu; |
2345 | 2559 | ||
2560 | isp->notifier.bound = isp_subdev_notifier_bound; | ||
2561 | isp->notifier.complete = isp_subdev_notifier_complete; | ||
2562 | |||
2346 | ret = isp_register_entities(isp); | 2563 | ret = isp_register_entities(isp); |
2347 | if (ret < 0) | 2564 | if (ret < 0) |
2348 | goto error_modules; | 2565 | goto error_modules; |
@@ -2378,6 +2595,11 @@ static struct platform_device_id omap3isp_id_table[] = { | |||
2378 | }; | 2595 | }; |
2379 | MODULE_DEVICE_TABLE(platform, omap3isp_id_table); | 2596 | MODULE_DEVICE_TABLE(platform, omap3isp_id_table); |
2380 | 2597 | ||
2598 | static const struct of_device_id omap3isp_of_table[] = { | ||
2599 | { .compatible = "ti,omap3-isp" }, | ||
2600 | { }, | ||
2601 | }; | ||
2602 | |||
2381 | static struct platform_driver omap3isp_driver = { | 2603 | static struct platform_driver omap3isp_driver = { |
2382 | .probe = isp_probe, | 2604 | .probe = isp_probe, |
2383 | .remove = isp_remove, | 2605 | .remove = isp_remove, |
@@ -2385,6 +2607,7 @@ static struct platform_driver omap3isp_driver = { | |||
2385 | .driver = { | 2607 | .driver = { |
2386 | .name = "omap3isp", | 2608 | .name = "omap3isp", |
2387 | .pm = &omap3isp_pm_ops, | 2609 | .pm = &omap3isp_pm_ops, |
2610 | .of_match_table = omap3isp_of_table, | ||
2388 | }, | 2611 | }, |
2389 | }; | 2612 | }; |
2390 | 2613 | ||
diff --git a/drivers/media/platform/omap3isp/isp.h b/drivers/media/platform/omap3isp/isp.h index cfdfc8714b6b..e579943175c4 100644 --- a/drivers/media/platform/omap3isp/isp.h +++ b/drivers/media/platform/omap3isp/isp.h | |||
@@ -18,6 +18,7 @@ | |||
18 | #define OMAP3_ISP_CORE_H | 18 | #define OMAP3_ISP_CORE_H |
19 | 19 | ||
20 | #include <media/omap3isp.h> | 20 | #include <media/omap3isp.h> |
21 | #include <media/v4l2-async.h> | ||
21 | #include <media/v4l2-device.h> | 22 | #include <media/v4l2-device.h> |
22 | #include <linux/clk-provider.h> | 23 | #include <linux/clk-provider.h> |
23 | #include <linux/device.h> | 24 | #include <linux/device.h> |
@@ -59,8 +60,6 @@ enum isp_mem_resources { | |||
59 | OMAP3_ISP_IOMEM_CSI2C_REGS1, | 60 | OMAP3_ISP_IOMEM_CSI2C_REGS1, |
60 | OMAP3_ISP_IOMEM_CSIPHY1, | 61 | OMAP3_ISP_IOMEM_CSIPHY1, |
61 | OMAP3_ISP_IOMEM_CSI2C_REGS2, | 62 | OMAP3_ISP_IOMEM_CSI2C_REGS2, |
62 | OMAP3_ISP_IOMEM_343X_CONTROL_CSIRXFE, | ||
63 | OMAP3_ISP_IOMEM_3630_CONTROL_CAMERA_PHY_CTRL, | ||
64 | OMAP3_ISP_IOMEM_LAST | 63 | OMAP3_ISP_IOMEM_LAST |
65 | }; | 64 | }; |
66 | 65 | ||
@@ -93,14 +92,25 @@ enum isp_subclk_resource { | |||
93 | /* ISP2P: OMAP 36xx */ | 92 | /* ISP2P: OMAP 36xx */ |
94 | #define ISP_REVISION_15_0 0xF0 | 93 | #define ISP_REVISION_15_0 0xF0 |
95 | 94 | ||
95 | #define ISP_PHY_TYPE_3430 0 | ||
96 | #define ISP_PHY_TYPE_3630 1 | ||
97 | |||
98 | struct regmap; | ||
99 | |||
96 | /* | 100 | /* |
97 | * struct isp_res_mapping - Map ISP io resources to ISP revision. | 101 | * struct isp_res_mapping - Map ISP io resources to ISP revision. |
98 | * @isp_rev: ISP_REVISION_x_x | 102 | * @isp_rev: ISP_REVISION_x_x |
99 | * @map: bitmap for enum isp_mem_resources | 103 | * @offset: register offsets of various ISP sub-blocks |
104 | * @syscon_offset: offset of the syscon register for 343x / 3630 | ||
105 | * (CONTROL_CSIRXFE / CONTROL_CAMERA_PHY_CTRL, respectively) | ||
106 | * from the syscon base address | ||
107 | * @phy_type: ISP_PHY_TYPE_{3430,3630} | ||
100 | */ | 108 | */ |
101 | struct isp_res_mapping { | 109 | struct isp_res_mapping { |
102 | u32 isp_rev; | 110 | u32 isp_rev; |
103 | u32 map; | 111 | u32 offset[OMAP3_ISP_IOMEM_LAST]; |
112 | u32 syscon_offset; | ||
113 | u32 phy_type; | ||
104 | }; | 114 | }; |
105 | 115 | ||
106 | /* | 116 | /* |
@@ -122,7 +132,6 @@ enum isp_xclk_id { | |||
122 | struct isp_xclk { | 132 | struct isp_xclk { |
123 | struct isp_device *isp; | 133 | struct isp_device *isp; |
124 | struct clk_hw hw; | 134 | struct clk_hw hw; |
125 | struct clk_lookup *lookup; | ||
126 | struct clk *clk; | 135 | struct clk *clk; |
127 | enum isp_xclk_id id; | 136 | enum isp_xclk_id id; |
128 | 137 | ||
@@ -138,8 +147,11 @@ struct isp_xclk { | |||
138 | * @irq_num: Currently used IRQ number. | 147 | * @irq_num: Currently used IRQ number. |
139 | * @mmio_base: Array with kernel base addresses for ioremapped ISP register | 148 | * @mmio_base: Array with kernel base addresses for ioremapped ISP register |
140 | * regions. | 149 | * regions. |
141 | * @mmio_base_phys: Array with physical L4 bus addresses for ISP register | 150 | * @mmio_hist_base_phys: Physical L4 bus address for ISP hist block register |
142 | * regions. | 151 | * region. |
152 | * @syscon: Regmap for the syscon register space | ||
153 | * @syscon_offset: Offset of the CSIPHY control register in syscon | ||
154 | * @phy_type: ISP_PHY_TYPE_{3430,3630} | ||
143 | * @mapping: IOMMU mapping | 155 | * @mapping: IOMMU mapping |
144 | * @stat_lock: Spinlock for handling statistics | 156 | * @stat_lock: Spinlock for handling statistics |
145 | * @isp_mutex: Mutex for serializing requests to ISP. | 157 | * @isp_mutex: Mutex for serializing requests to ISP. |
@@ -166,6 +178,7 @@ struct isp_xclk { | |||
166 | */ | 178 | */ |
167 | struct isp_device { | 179 | struct isp_device { |
168 | struct v4l2_device v4l2_dev; | 180 | struct v4l2_device v4l2_dev; |
181 | struct v4l2_async_notifier notifier; | ||
169 | struct media_device media_dev; | 182 | struct media_device media_dev; |
170 | struct device *dev; | 183 | struct device *dev; |
171 | u32 revision; | 184 | u32 revision; |
@@ -175,7 +188,10 @@ struct isp_device { | |||
175 | unsigned int irq_num; | 188 | unsigned int irq_num; |
176 | 189 | ||
177 | void __iomem *mmio_base[OMAP3_ISP_IOMEM_LAST]; | 190 | void __iomem *mmio_base[OMAP3_ISP_IOMEM_LAST]; |
178 | unsigned long mmio_base_phys[OMAP3_ISP_IOMEM_LAST]; | 191 | unsigned long mmio_hist_base_phys; |
192 | struct regmap *syscon; | ||
193 | u32 syscon_offset; | ||
194 | u32 phy_type; | ||
179 | 195 | ||
180 | struct dma_iommu_mapping *mapping; | 196 | struct dma_iommu_mapping *mapping; |
181 | 197 | ||
@@ -209,6 +225,15 @@ struct isp_device { | |||
209 | 225 | ||
210 | unsigned int sbl_resources; | 226 | unsigned int sbl_resources; |
211 | unsigned int subclk_resources; | 227 | unsigned int subclk_resources; |
228 | |||
229 | #define ISP_MAX_SUBDEVS 8 | ||
230 | struct v4l2_subdev *subdevs[ISP_MAX_SUBDEVS]; | ||
231 | }; | ||
232 | |||
233 | struct isp_async_subdev { | ||
234 | struct v4l2_subdev *sd; | ||
235 | struct isp_bus_cfg bus; | ||
236 | struct v4l2_async_subdev asd; | ||
212 | }; | 237 | }; |
213 | 238 | ||
214 | #define v4l2_dev_to_isp_device(dev) \ | 239 | #define v4l2_dev_to_isp_device(dev) \ |
@@ -229,7 +254,7 @@ int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe, | |||
229 | void omap3isp_pipeline_cancel_stream(struct isp_pipeline *pipe); | 254 | void omap3isp_pipeline_cancel_stream(struct isp_pipeline *pipe); |
230 | void omap3isp_configure_bridge(struct isp_device *isp, | 255 | void omap3isp_configure_bridge(struct isp_device *isp, |
231 | enum ccdc_input_entity input, | 256 | enum ccdc_input_entity input, |
232 | const struct isp_parallel_platform_data *pdata, | 257 | const struct isp_parallel_cfg *buscfg, |
233 | unsigned int shift, unsigned int bridge); | 258 | unsigned int shift, unsigned int bridge); |
234 | 259 | ||
235 | struct isp_device *omap3isp_get(struct isp_device *isp); | 260 | struct isp_device *omap3isp_get(struct isp_device *isp); |
diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c index 587489a072d5..a6a61cce43dd 100644 --- a/drivers/media/platform/omap3isp/ispccdc.c +++ b/drivers/media/platform/omap3isp/ispccdc.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #define CCDC_MIN_HEIGHT 32 | 32 | #define CCDC_MIN_HEIGHT 32 |
33 | 33 | ||
34 | static struct v4l2_mbus_framefmt * | 34 | static struct v4l2_mbus_framefmt * |
35 | __ccdc_get_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh, | 35 | __ccdc_get_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_pad_config *cfg, |
36 | unsigned int pad, enum v4l2_subdev_format_whence which); | 36 | unsigned int pad, enum v4l2_subdev_format_whence which); |
37 | 37 | ||
38 | static const unsigned int ccdc_fmts[] = { | 38 | static const unsigned int ccdc_fmts[] = { |
@@ -958,11 +958,11 @@ void omap3isp_ccdc_max_rate(struct isp_ccdc_device *ccdc, | |||
958 | /* | 958 | /* |
959 | * ccdc_config_sync_if - Set CCDC sync interface configuration | 959 | * ccdc_config_sync_if - Set CCDC sync interface configuration |
960 | * @ccdc: Pointer to ISP CCDC device. | 960 | * @ccdc: Pointer to ISP CCDC device. |
961 | * @pdata: Parallel interface platform data (may be NULL) | 961 | * @parcfg: Parallel interface platform data (may be NULL) |
962 | * @data_size: Data size | 962 | * @data_size: Data size |
963 | */ | 963 | */ |
964 | static void ccdc_config_sync_if(struct isp_ccdc_device *ccdc, | 964 | static void ccdc_config_sync_if(struct isp_ccdc_device *ccdc, |
965 | struct isp_parallel_platform_data *pdata, | 965 | struct isp_parallel_cfg *parcfg, |
966 | unsigned int data_size) | 966 | unsigned int data_size) |
967 | { | 967 | { |
968 | struct isp_device *isp = to_isp_device(ccdc); | 968 | struct isp_device *isp = to_isp_device(ccdc); |
@@ -1000,19 +1000,19 @@ static void ccdc_config_sync_if(struct isp_ccdc_device *ccdc, | |||
1000 | break; | 1000 | break; |
1001 | } | 1001 | } |
1002 | 1002 | ||
1003 | if (pdata && pdata->data_pol) | 1003 | if (parcfg && parcfg->data_pol) |
1004 | syn_mode |= ISPCCDC_SYN_MODE_DATAPOL; | 1004 | syn_mode |= ISPCCDC_SYN_MODE_DATAPOL; |
1005 | 1005 | ||
1006 | if (pdata && pdata->hs_pol) | 1006 | if (parcfg && parcfg->hs_pol) |
1007 | syn_mode |= ISPCCDC_SYN_MODE_HDPOL; | 1007 | syn_mode |= ISPCCDC_SYN_MODE_HDPOL; |
1008 | 1008 | ||
1009 | /* The polarity of the vertical sync signal output by the BT.656 | 1009 | /* The polarity of the vertical sync signal output by the BT.656 |
1010 | * decoder is not documented and seems to be active low. | 1010 | * decoder is not documented and seems to be active low. |
1011 | */ | 1011 | */ |
1012 | if ((pdata && pdata->vs_pol) || ccdc->bt656) | 1012 | if ((parcfg && parcfg->vs_pol) || ccdc->bt656) |
1013 | syn_mode |= ISPCCDC_SYN_MODE_VDPOL; | 1013 | syn_mode |= ISPCCDC_SYN_MODE_VDPOL; |
1014 | 1014 | ||
1015 | if (pdata && pdata->fld_pol) | 1015 | if (parcfg && parcfg->fld_pol) |
1016 | syn_mode |= ISPCCDC_SYN_MODE_FLDPOL; | 1016 | syn_mode |= ISPCCDC_SYN_MODE_FLDPOL; |
1017 | 1017 | ||
1018 | isp_reg_writel(isp, syn_mode, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE); | 1018 | isp_reg_writel(isp, syn_mode, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE); |
@@ -1115,7 +1115,7 @@ static const u32 ccdc_sgbrg_pattern = | |||
1115 | static void ccdc_configure(struct isp_ccdc_device *ccdc) | 1115 | static void ccdc_configure(struct isp_ccdc_device *ccdc) |
1116 | { | 1116 | { |
1117 | struct isp_device *isp = to_isp_device(ccdc); | 1117 | struct isp_device *isp = to_isp_device(ccdc); |
1118 | struct isp_parallel_platform_data *pdata = NULL; | 1118 | struct isp_parallel_cfg *parcfg = NULL; |
1119 | struct v4l2_subdev *sensor; | 1119 | struct v4l2_subdev *sensor; |
1120 | struct v4l2_mbus_framefmt *format; | 1120 | struct v4l2_mbus_framefmt *format; |
1121 | const struct v4l2_rect *crop; | 1121 | const struct v4l2_rect *crop; |
@@ -1145,7 +1145,7 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc) | |||
1145 | if (!ret) | 1145 | if (!ret) |
1146 | ccdc->bt656 = cfg.type == V4L2_MBUS_BT656; | 1146 | ccdc->bt656 = cfg.type == V4L2_MBUS_BT656; |
1147 | 1147 | ||
1148 | pdata = &((struct isp_v4l2_subdevs_group *)sensor->host_priv) | 1148 | parcfg = &((struct isp_bus_cfg *)sensor->host_priv) |
1149 | ->bus.parallel; | 1149 | ->bus.parallel; |
1150 | } | 1150 | } |
1151 | 1151 | ||
@@ -1175,10 +1175,10 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc) | |||
1175 | else | 1175 | else |
1176 | bridge = ISPCTRL_PAR_BRIDGE_DISABLE; | 1176 | bridge = ISPCTRL_PAR_BRIDGE_DISABLE; |
1177 | 1177 | ||
1178 | omap3isp_configure_bridge(isp, ccdc->input, pdata, shift, bridge); | 1178 | omap3isp_configure_bridge(isp, ccdc->input, parcfg, shift, bridge); |
1179 | 1179 | ||
1180 | /* Configure the sync interface. */ | 1180 | /* Configure the sync interface. */ |
1181 | ccdc_config_sync_if(ccdc, pdata, depth_out); | 1181 | ccdc_config_sync_if(ccdc, parcfg, depth_out); |
1182 | 1182 | ||
1183 | syn_mode = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE); | 1183 | syn_mode = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE); |
1184 | 1184 | ||
@@ -1935,21 +1935,21 @@ static int ccdc_set_stream(struct v4l2_subdev *sd, int enable) | |||
1935 | } | 1935 | } |
1936 | 1936 | ||
1937 | static struct v4l2_mbus_framefmt * | 1937 | static struct v4l2_mbus_framefmt * |
1938 | __ccdc_get_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh, | 1938 | __ccdc_get_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_pad_config *cfg, |
1939 | unsigned int pad, enum v4l2_subdev_format_whence which) | 1939 | unsigned int pad, enum v4l2_subdev_format_whence which) |
1940 | { | 1940 | { |
1941 | if (which == V4L2_SUBDEV_FORMAT_TRY) | 1941 | if (which == V4L2_SUBDEV_FORMAT_TRY) |
1942 | return v4l2_subdev_get_try_format(fh, pad); | 1942 | return v4l2_subdev_get_try_format(&ccdc->subdev, cfg, pad); |
1943 | else | 1943 | else |
1944 | return &ccdc->formats[pad]; | 1944 | return &ccdc->formats[pad]; |
1945 | } | 1945 | } |
1946 | 1946 | ||
1947 | static struct v4l2_rect * | 1947 | static struct v4l2_rect * |
1948 | __ccdc_get_crop(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh, | 1948 | __ccdc_get_crop(struct isp_ccdc_device *ccdc, struct v4l2_subdev_pad_config *cfg, |
1949 | enum v4l2_subdev_format_whence which) | 1949 | enum v4l2_subdev_format_whence which) |
1950 | { | 1950 | { |
1951 | if (which == V4L2_SUBDEV_FORMAT_TRY) | 1951 | if (which == V4L2_SUBDEV_FORMAT_TRY) |
1952 | return v4l2_subdev_get_try_crop(fh, CCDC_PAD_SOURCE_OF); | 1952 | return v4l2_subdev_get_try_crop(&ccdc->subdev, cfg, CCDC_PAD_SOURCE_OF); |
1953 | else | 1953 | else |
1954 | return &ccdc->crop; | 1954 | return &ccdc->crop; |
1955 | } | 1955 | } |
@@ -1957,12 +1957,12 @@ __ccdc_get_crop(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh, | |||
1957 | /* | 1957 | /* |
1958 | * ccdc_try_format - Try video format on a pad | 1958 | * ccdc_try_format - Try video format on a pad |
1959 | * @ccdc: ISP CCDC device | 1959 | * @ccdc: ISP CCDC device |
1960 | * @fh : V4L2 subdev file handle | 1960 | * @cfg : V4L2 subdev pad configuration |
1961 | * @pad: Pad number | 1961 | * @pad: Pad number |
1962 | * @fmt: Format | 1962 | * @fmt: Format |
1963 | */ | 1963 | */ |
1964 | static void | 1964 | static void |
1965 | ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh, | 1965 | ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_pad_config *cfg, |
1966 | unsigned int pad, struct v4l2_mbus_framefmt *fmt, | 1966 | unsigned int pad, struct v4l2_mbus_framefmt *fmt, |
1967 | enum v4l2_subdev_format_whence which) | 1967 | enum v4l2_subdev_format_whence which) |
1968 | { | 1968 | { |
@@ -1998,7 +1998,7 @@ ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh, | |||
1998 | case CCDC_PAD_SOURCE_OF: | 1998 | case CCDC_PAD_SOURCE_OF: |
1999 | pixelcode = fmt->code; | 1999 | pixelcode = fmt->code; |
2000 | field = fmt->field; | 2000 | field = fmt->field; |
2001 | *fmt = *__ccdc_get_format(ccdc, fh, CCDC_PAD_SINK, which); | 2001 | *fmt = *__ccdc_get_format(ccdc, cfg, CCDC_PAD_SINK, which); |
2002 | 2002 | ||
2003 | /* In SYNC mode the bridge converts YUV formats from 2X8 to | 2003 | /* In SYNC mode the bridge converts YUV formats from 2X8 to |
2004 | * 1X16. In BT.656 no such conversion occurs. As we don't know | 2004 | * 1X16. In BT.656 no such conversion occurs. As we don't know |
@@ -2023,7 +2023,7 @@ ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh, | |||
2023 | } | 2023 | } |
2024 | 2024 | ||
2025 | /* Hardcode the output size to the crop rectangle size. */ | 2025 | /* Hardcode the output size to the crop rectangle size. */ |
2026 | crop = __ccdc_get_crop(ccdc, fh, which); | 2026 | crop = __ccdc_get_crop(ccdc, cfg, which); |
2027 | fmt->width = crop->width; | 2027 | fmt->width = crop->width; |
2028 | fmt->height = crop->height; | 2028 | fmt->height = crop->height; |
2029 | 2029 | ||
@@ -2040,7 +2040,7 @@ ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh, | |||
2040 | break; | 2040 | break; |
2041 | 2041 | ||
2042 | case CCDC_PAD_SOURCE_VP: | 2042 | case CCDC_PAD_SOURCE_VP: |
2043 | *fmt = *__ccdc_get_format(ccdc, fh, CCDC_PAD_SINK, which); | 2043 | *fmt = *__ccdc_get_format(ccdc, cfg, CCDC_PAD_SINK, which); |
2044 | 2044 | ||
2045 | /* The video port interface truncates the data to 10 bits. */ | 2045 | /* The video port interface truncates the data to 10 bits. */ |
2046 | info = omap3isp_video_format_info(fmt->code); | 2046 | info = omap3isp_video_format_info(fmt->code); |
@@ -2112,12 +2112,12 @@ static void ccdc_try_crop(struct isp_ccdc_device *ccdc, | |||
2112 | /* | 2112 | /* |
2113 | * ccdc_enum_mbus_code - Handle pixel format enumeration | 2113 | * ccdc_enum_mbus_code - Handle pixel format enumeration |
2114 | * @sd : pointer to v4l2 subdev structure | 2114 | * @sd : pointer to v4l2 subdev structure |
2115 | * @fh : V4L2 subdev file handle | 2115 | * @cfg : V4L2 subdev pad configuration |
2116 | * @code : pointer to v4l2_subdev_mbus_code_enum structure | 2116 | * @code : pointer to v4l2_subdev_mbus_code_enum structure |
2117 | * return -EINVAL or zero on success | 2117 | * return -EINVAL or zero on success |
2118 | */ | 2118 | */ |
2119 | static int ccdc_enum_mbus_code(struct v4l2_subdev *sd, | 2119 | static int ccdc_enum_mbus_code(struct v4l2_subdev *sd, |
2120 | struct v4l2_subdev_fh *fh, | 2120 | struct v4l2_subdev_pad_config *cfg, |
2121 | struct v4l2_subdev_mbus_code_enum *code) | 2121 | struct v4l2_subdev_mbus_code_enum *code) |
2122 | { | 2122 | { |
2123 | struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd); | 2123 | struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd); |
@@ -2132,8 +2132,8 @@ static int ccdc_enum_mbus_code(struct v4l2_subdev *sd, | |||
2132 | break; | 2132 | break; |
2133 | 2133 | ||
2134 | case CCDC_PAD_SOURCE_OF: | 2134 | case CCDC_PAD_SOURCE_OF: |
2135 | format = __ccdc_get_format(ccdc, fh, code->pad, | 2135 | format = __ccdc_get_format(ccdc, cfg, code->pad, |
2136 | V4L2_SUBDEV_FORMAT_TRY); | 2136 | code->which); |
2137 | 2137 | ||
2138 | if (format->code == MEDIA_BUS_FMT_YUYV8_2X8 || | 2138 | if (format->code == MEDIA_BUS_FMT_YUYV8_2X8 || |
2139 | format->code == MEDIA_BUS_FMT_UYVY8_2X8) { | 2139 | format->code == MEDIA_BUS_FMT_UYVY8_2X8) { |
@@ -2163,8 +2163,8 @@ static int ccdc_enum_mbus_code(struct v4l2_subdev *sd, | |||
2163 | if (code->index != 0) | 2163 | if (code->index != 0) |
2164 | return -EINVAL; | 2164 | return -EINVAL; |
2165 | 2165 | ||
2166 | format = __ccdc_get_format(ccdc, fh, code->pad, | 2166 | format = __ccdc_get_format(ccdc, cfg, code->pad, |
2167 | V4L2_SUBDEV_FORMAT_TRY); | 2167 | code->which); |
2168 | 2168 | ||
2169 | /* A pixel code equal to 0 means that the video port doesn't | 2169 | /* A pixel code equal to 0 means that the video port doesn't |
2170 | * support the input format. Don't enumerate any pixel code. | 2170 | * support the input format. Don't enumerate any pixel code. |
@@ -2183,7 +2183,7 @@ static int ccdc_enum_mbus_code(struct v4l2_subdev *sd, | |||
2183 | } | 2183 | } |
2184 | 2184 | ||
2185 | static int ccdc_enum_frame_size(struct v4l2_subdev *sd, | 2185 | static int ccdc_enum_frame_size(struct v4l2_subdev *sd, |
2186 | struct v4l2_subdev_fh *fh, | 2186 | struct v4l2_subdev_pad_config *cfg, |
2187 | struct v4l2_subdev_frame_size_enum *fse) | 2187 | struct v4l2_subdev_frame_size_enum *fse) |
2188 | { | 2188 | { |
2189 | struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd); | 2189 | struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd); |
@@ -2195,7 +2195,7 @@ static int ccdc_enum_frame_size(struct v4l2_subdev *sd, | |||
2195 | format.code = fse->code; | 2195 | format.code = fse->code; |
2196 | format.width = 1; | 2196 | format.width = 1; |
2197 | format.height = 1; | 2197 | format.height = 1; |
2198 | ccdc_try_format(ccdc, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY); | 2198 | ccdc_try_format(ccdc, cfg, fse->pad, &format, fse->which); |
2199 | fse->min_width = format.width; | 2199 | fse->min_width = format.width; |
2200 | fse->min_height = format.height; | 2200 | fse->min_height = format.height; |
2201 | 2201 | ||
@@ -2205,7 +2205,7 @@ static int ccdc_enum_frame_size(struct v4l2_subdev *sd, | |||
2205 | format.code = fse->code; | 2205 | format.code = fse->code; |
2206 | format.width = -1; | 2206 | format.width = -1; |
2207 | format.height = -1; | 2207 | format.height = -1; |
2208 | ccdc_try_format(ccdc, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY); | 2208 | ccdc_try_format(ccdc, cfg, fse->pad, &format, fse->which); |
2209 | fse->max_width = format.width; | 2209 | fse->max_width = format.width; |
2210 | fse->max_height = format.height; | 2210 | fse->max_height = format.height; |
2211 | 2211 | ||
@@ -2215,7 +2215,7 @@ static int ccdc_enum_frame_size(struct v4l2_subdev *sd, | |||
2215 | /* | 2215 | /* |
2216 | * ccdc_get_selection - Retrieve a selection rectangle on a pad | 2216 | * ccdc_get_selection - Retrieve a selection rectangle on a pad |
2217 | * @sd: ISP CCDC V4L2 subdevice | 2217 | * @sd: ISP CCDC V4L2 subdevice |
2218 | * @fh: V4L2 subdev file handle | 2218 | * @cfg: V4L2 subdev pad configuration |
2219 | * @sel: Selection rectangle | 2219 | * @sel: Selection rectangle |
2220 | * | 2220 | * |
2221 | * The only supported rectangles are the crop rectangles on the output formatter | 2221 | * The only supported rectangles are the crop rectangles on the output formatter |
@@ -2223,7 +2223,7 @@ static int ccdc_enum_frame_size(struct v4l2_subdev *sd, | |||
2223 | * | 2223 | * |
2224 | * Return 0 on success or a negative error code otherwise. | 2224 | * Return 0 on success or a negative error code otherwise. |
2225 | */ | 2225 | */ |
2226 | static int ccdc_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | 2226 | static int ccdc_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, |
2227 | struct v4l2_subdev_selection *sel) | 2227 | struct v4l2_subdev_selection *sel) |
2228 | { | 2228 | { |
2229 | struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd); | 2229 | struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd); |
@@ -2239,12 +2239,12 @@ static int ccdc_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
2239 | sel->r.width = INT_MAX; | 2239 | sel->r.width = INT_MAX; |
2240 | sel->r.height = INT_MAX; | 2240 | sel->r.height = INT_MAX; |
2241 | 2241 | ||
2242 | format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SINK, sel->which); | 2242 | format = __ccdc_get_format(ccdc, cfg, CCDC_PAD_SINK, sel->which); |
2243 | ccdc_try_crop(ccdc, format, &sel->r); | 2243 | ccdc_try_crop(ccdc, format, &sel->r); |
2244 | break; | 2244 | break; |
2245 | 2245 | ||
2246 | case V4L2_SEL_TGT_CROP: | 2246 | case V4L2_SEL_TGT_CROP: |
2247 | sel->r = *__ccdc_get_crop(ccdc, fh, sel->which); | 2247 | sel->r = *__ccdc_get_crop(ccdc, cfg, sel->which); |
2248 | break; | 2248 | break; |
2249 | 2249 | ||
2250 | default: | 2250 | default: |
@@ -2257,7 +2257,7 @@ static int ccdc_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
2257 | /* | 2257 | /* |
2258 | * ccdc_set_selection - Set a selection rectangle on a pad | 2258 | * ccdc_set_selection - Set a selection rectangle on a pad |
2259 | * @sd: ISP CCDC V4L2 subdevice | 2259 | * @sd: ISP CCDC V4L2 subdevice |
2260 | * @fh: V4L2 subdev file handle | 2260 | * @cfg: V4L2 subdev pad configuration |
2261 | * @sel: Selection rectangle | 2261 | * @sel: Selection rectangle |
2262 | * | 2262 | * |
2263 | * The only supported rectangle is the actual crop rectangle on the output | 2263 | * The only supported rectangle is the actual crop rectangle on the output |
@@ -2265,7 +2265,7 @@ static int ccdc_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
2265 | * | 2265 | * |
2266 | * Return 0 on success or a negative error code otherwise. | 2266 | * Return 0 on success or a negative error code otherwise. |
2267 | */ | 2267 | */ |
2268 | static int ccdc_set_selection(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | 2268 | static int ccdc_set_selection(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, |
2269 | struct v4l2_subdev_selection *sel) | 2269 | struct v4l2_subdev_selection *sel) |
2270 | { | 2270 | { |
2271 | struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd); | 2271 | struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd); |
@@ -2284,17 +2284,17 @@ static int ccdc_set_selection(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
2284 | * rectangle. | 2284 | * rectangle. |
2285 | */ | 2285 | */ |
2286 | if (sel->flags & V4L2_SEL_FLAG_KEEP_CONFIG) { | 2286 | if (sel->flags & V4L2_SEL_FLAG_KEEP_CONFIG) { |
2287 | sel->r = *__ccdc_get_crop(ccdc, fh, sel->which); | 2287 | sel->r = *__ccdc_get_crop(ccdc, cfg, sel->which); |
2288 | return 0; | 2288 | return 0; |
2289 | } | 2289 | } |
2290 | 2290 | ||
2291 | format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SINK, sel->which); | 2291 | format = __ccdc_get_format(ccdc, cfg, CCDC_PAD_SINK, sel->which); |
2292 | ccdc_try_crop(ccdc, format, &sel->r); | 2292 | ccdc_try_crop(ccdc, format, &sel->r); |
2293 | *__ccdc_get_crop(ccdc, fh, sel->which) = sel->r; | 2293 | *__ccdc_get_crop(ccdc, cfg, sel->which) = sel->r; |
2294 | 2294 | ||
2295 | /* Update the source format. */ | 2295 | /* Update the source format. */ |
2296 | format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SOURCE_OF, sel->which); | 2296 | format = __ccdc_get_format(ccdc, cfg, CCDC_PAD_SOURCE_OF, sel->which); |
2297 | ccdc_try_format(ccdc, fh, CCDC_PAD_SOURCE_OF, format, sel->which); | 2297 | ccdc_try_format(ccdc, cfg, CCDC_PAD_SOURCE_OF, format, sel->which); |
2298 | 2298 | ||
2299 | return 0; | 2299 | return 0; |
2300 | } | 2300 | } |
@@ -2302,19 +2302,19 @@ static int ccdc_set_selection(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
2302 | /* | 2302 | /* |
2303 | * ccdc_get_format - Retrieve the video format on a pad | 2303 | * ccdc_get_format - Retrieve the video format on a pad |
2304 | * @sd : ISP CCDC V4L2 subdevice | 2304 | * @sd : ISP CCDC V4L2 subdevice |
2305 | * @fh : V4L2 subdev file handle | 2305 | * @cfg: V4L2 subdev pad configuration |
2306 | * @fmt: Format | 2306 | * @fmt: Format |
2307 | * | 2307 | * |
2308 | * Return 0 on success or -EINVAL if the pad is invalid or doesn't correspond | 2308 | * Return 0 on success or -EINVAL if the pad is invalid or doesn't correspond |
2309 | * to the format type. | 2309 | * to the format type. |
2310 | */ | 2310 | */ |
2311 | static int ccdc_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | 2311 | static int ccdc_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, |
2312 | struct v4l2_subdev_format *fmt) | 2312 | struct v4l2_subdev_format *fmt) |
2313 | { | 2313 | { |
2314 | struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd); | 2314 | struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd); |
2315 | struct v4l2_mbus_framefmt *format; | 2315 | struct v4l2_mbus_framefmt *format; |
2316 | 2316 | ||
2317 | format = __ccdc_get_format(ccdc, fh, fmt->pad, fmt->which); | 2317 | format = __ccdc_get_format(ccdc, cfg, fmt->pad, fmt->which); |
2318 | if (format == NULL) | 2318 | if (format == NULL) |
2319 | return -EINVAL; | 2319 | return -EINVAL; |
2320 | 2320 | ||
@@ -2325,30 +2325,30 @@ static int ccdc_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
2325 | /* | 2325 | /* |
2326 | * ccdc_set_format - Set the video format on a pad | 2326 | * ccdc_set_format - Set the video format on a pad |
2327 | * @sd : ISP CCDC V4L2 subdevice | 2327 | * @sd : ISP CCDC V4L2 subdevice |
2328 | * @fh : V4L2 subdev file handle | 2328 | * @cfg: V4L2 subdev pad configuration |
2329 | * @fmt: Format | 2329 | * @fmt: Format |
2330 | * | 2330 | * |
2331 | * Return 0 on success or -EINVAL if the pad is invalid or doesn't correspond | 2331 | * Return 0 on success or -EINVAL if the pad is invalid or doesn't correspond |
2332 | * to the format type. | 2332 | * to the format type. |
2333 | */ | 2333 | */ |
2334 | static int ccdc_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | 2334 | static int ccdc_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, |
2335 | struct v4l2_subdev_format *fmt) | 2335 | struct v4l2_subdev_format *fmt) |
2336 | { | 2336 | { |
2337 | struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd); | 2337 | struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd); |
2338 | struct v4l2_mbus_framefmt *format; | 2338 | struct v4l2_mbus_framefmt *format; |
2339 | struct v4l2_rect *crop; | 2339 | struct v4l2_rect *crop; |
2340 | 2340 | ||
2341 | format = __ccdc_get_format(ccdc, fh, fmt->pad, fmt->which); | 2341 | format = __ccdc_get_format(ccdc, cfg, fmt->pad, fmt->which); |
2342 | if (format == NULL) | 2342 | if (format == NULL) |
2343 | return -EINVAL; | 2343 | return -EINVAL; |
2344 | 2344 | ||
2345 | ccdc_try_format(ccdc, fh, fmt->pad, &fmt->format, fmt->which); | 2345 | ccdc_try_format(ccdc, cfg, fmt->pad, &fmt->format, fmt->which); |
2346 | *format = fmt->format; | 2346 | *format = fmt->format; |
2347 | 2347 | ||
2348 | /* Propagate the format from sink to source */ | 2348 | /* Propagate the format from sink to source */ |
2349 | if (fmt->pad == CCDC_PAD_SINK) { | 2349 | if (fmt->pad == CCDC_PAD_SINK) { |
2350 | /* Reset the crop rectangle. */ | 2350 | /* Reset the crop rectangle. */ |
2351 | crop = __ccdc_get_crop(ccdc, fh, fmt->which); | 2351 | crop = __ccdc_get_crop(ccdc, cfg, fmt->which); |
2352 | crop->left = 0; | 2352 | crop->left = 0; |
2353 | crop->top = 0; | 2353 | crop->top = 0; |
2354 | crop->width = fmt->format.width; | 2354 | crop->width = fmt->format.width; |
@@ -2357,16 +2357,16 @@ static int ccdc_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
2357 | ccdc_try_crop(ccdc, &fmt->format, crop); | 2357 | ccdc_try_crop(ccdc, &fmt->format, crop); |
2358 | 2358 | ||
2359 | /* Update the source formats. */ | 2359 | /* Update the source formats. */ |
2360 | format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SOURCE_OF, | 2360 | format = __ccdc_get_format(ccdc, cfg, CCDC_PAD_SOURCE_OF, |
2361 | fmt->which); | 2361 | fmt->which); |
2362 | *format = fmt->format; | 2362 | *format = fmt->format; |
2363 | ccdc_try_format(ccdc, fh, CCDC_PAD_SOURCE_OF, format, | 2363 | ccdc_try_format(ccdc, cfg, CCDC_PAD_SOURCE_OF, format, |
2364 | fmt->which); | 2364 | fmt->which); |
2365 | 2365 | ||
2366 | format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SOURCE_VP, | 2366 | format = __ccdc_get_format(ccdc, cfg, CCDC_PAD_SOURCE_VP, |
2367 | fmt->which); | 2367 | fmt->which); |
2368 | *format = fmt->format; | 2368 | *format = fmt->format; |
2369 | ccdc_try_format(ccdc, fh, CCDC_PAD_SOURCE_VP, format, | 2369 | ccdc_try_format(ccdc, cfg, CCDC_PAD_SOURCE_VP, format, |
2370 | fmt->which); | 2370 | fmt->which); |
2371 | } | 2371 | } |
2372 | 2372 | ||
@@ -2417,11 +2417,11 @@ static int ccdc_link_validate(struct v4l2_subdev *sd, | |||
2417 | 2417 | ||
2418 | /* We've got a parallel sensor here. */ | 2418 | /* We've got a parallel sensor here. */ |
2419 | if (ccdc->input == CCDC_INPUT_PARALLEL) { | 2419 | if (ccdc->input == CCDC_INPUT_PARALLEL) { |
2420 | struct isp_parallel_platform_data *pdata = | 2420 | struct isp_parallel_cfg *parcfg = |
2421 | &((struct isp_v4l2_subdevs_group *) | 2421 | &((struct isp_bus_cfg *) |
2422 | media_entity_to_v4l2_subdev(link->source->entity) | 2422 | media_entity_to_v4l2_subdev(link->source->entity) |
2423 | ->host_priv)->bus.parallel; | 2423 | ->host_priv)->bus.parallel; |
2424 | parallel_shift = pdata->data_lane_shift * 2; | 2424 | parallel_shift = parcfg->data_lane_shift * 2; |
2425 | } else { | 2425 | } else { |
2426 | parallel_shift = 0; | 2426 | parallel_shift = 0; |
2427 | } | 2427 | } |
@@ -2453,7 +2453,7 @@ static int ccdc_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) | |||
2453 | format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10; | 2453 | format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10; |
2454 | format.format.width = 4096; | 2454 | format.format.width = 4096; |
2455 | format.format.height = 4096; | 2455 | format.format.height = 4096; |
2456 | ccdc_set_format(sd, fh, &format); | 2456 | ccdc_set_format(sd, fh ? fh->pad : NULL, &format); |
2457 | 2457 | ||
2458 | return 0; | 2458 | return 0; |
2459 | } | 2459 | } |
diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c index f4aedb37e41e..38e6a974c5b1 100644 --- a/drivers/media/platform/omap3isp/ispccp2.c +++ b/drivers/media/platform/omap3isp/ispccp2.c | |||
@@ -201,14 +201,14 @@ static void ccp2_mem_enable(struct isp_ccp2_device *ccp2, u8 enable) | |||
201 | /* | 201 | /* |
202 | * ccp2_phyif_config - Initialize CCP2 phy interface config | 202 | * ccp2_phyif_config - Initialize CCP2 phy interface config |
203 | * @ccp2: Pointer to ISP CCP2 device | 203 | * @ccp2: Pointer to ISP CCP2 device |
204 | * @pdata: CCP2 platform data | 204 | * @buscfg: CCP2 platform data |
205 | * | 205 | * |
206 | * Configure the CCP2 physical interface module from platform data. | 206 | * Configure the CCP2 physical interface module from platform data. |
207 | * | 207 | * |
208 | * Returns -EIO if strobe is chosen in CSI1 mode, or 0 on success. | 208 | * Returns -EIO if strobe is chosen in CSI1 mode, or 0 on success. |
209 | */ | 209 | */ |
210 | static int ccp2_phyif_config(struct isp_ccp2_device *ccp2, | 210 | static int ccp2_phyif_config(struct isp_ccp2_device *ccp2, |
211 | const struct isp_ccp2_platform_data *pdata) | 211 | const struct isp_ccp2_cfg *buscfg) |
212 | { | 212 | { |
213 | struct isp_device *isp = to_isp_device(ccp2); | 213 | struct isp_device *isp = to_isp_device(ccp2); |
214 | u32 val; | 214 | u32 val; |
@@ -218,16 +218,16 @@ static int ccp2_phyif_config(struct isp_ccp2_device *ccp2, | |||
218 | ISPCCP2_CTRL_IO_OUT_SEL | ISPCCP2_CTRL_MODE; | 218 | ISPCCP2_CTRL_IO_OUT_SEL | ISPCCP2_CTRL_MODE; |
219 | /* Data/strobe physical layer */ | 219 | /* Data/strobe physical layer */ |
220 | BIT_SET(val, ISPCCP2_CTRL_PHY_SEL_SHIFT, ISPCCP2_CTRL_PHY_SEL_MASK, | 220 | BIT_SET(val, ISPCCP2_CTRL_PHY_SEL_SHIFT, ISPCCP2_CTRL_PHY_SEL_MASK, |
221 | pdata->phy_layer); | 221 | buscfg->phy_layer); |
222 | BIT_SET(val, ISPCCP2_CTRL_INV_SHIFT, ISPCCP2_CTRL_INV_MASK, | 222 | BIT_SET(val, ISPCCP2_CTRL_INV_SHIFT, ISPCCP2_CTRL_INV_MASK, |
223 | pdata->strobe_clk_pol); | 223 | buscfg->strobe_clk_pol); |
224 | isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL); | 224 | isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL); |
225 | 225 | ||
226 | val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL); | 226 | val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL); |
227 | if (!(val & ISPCCP2_CTRL_MODE)) { | 227 | if (!(val & ISPCCP2_CTRL_MODE)) { |
228 | if (pdata->ccp2_mode == ISP_CCP2_MODE_CCP2) | 228 | if (buscfg->ccp2_mode == ISP_CCP2_MODE_CCP2) |
229 | dev_warn(isp->dev, "OMAP3 CCP2 bus not available\n"); | 229 | dev_warn(isp->dev, "OMAP3 CCP2 bus not available\n"); |
230 | if (pdata->phy_layer == ISP_CCP2_PHY_DATA_STROBE) | 230 | if (buscfg->phy_layer == ISP_CCP2_PHY_DATA_STROBE) |
231 | /* Strobe mode requires CCP2 */ | 231 | /* Strobe mode requires CCP2 */ |
232 | return -EIO; | 232 | return -EIO; |
233 | } | 233 | } |
@@ -347,7 +347,7 @@ static void ccp2_lcx_config(struct isp_ccp2_device *ccp2, | |||
347 | */ | 347 | */ |
348 | static int ccp2_if_configure(struct isp_ccp2_device *ccp2) | 348 | static int ccp2_if_configure(struct isp_ccp2_device *ccp2) |
349 | { | 349 | { |
350 | const struct isp_v4l2_subdevs_group *pdata; | 350 | const struct isp_bus_cfg *buscfg; |
351 | struct v4l2_mbus_framefmt *format; | 351 | struct v4l2_mbus_framefmt *format; |
352 | struct media_pad *pad; | 352 | struct media_pad *pad; |
353 | struct v4l2_subdev *sensor; | 353 | struct v4l2_subdev *sensor; |
@@ -358,20 +358,20 @@ static int ccp2_if_configure(struct isp_ccp2_device *ccp2) | |||
358 | 358 | ||
359 | pad = media_entity_remote_pad(&ccp2->pads[CCP2_PAD_SINK]); | 359 | pad = media_entity_remote_pad(&ccp2->pads[CCP2_PAD_SINK]); |
360 | sensor = media_entity_to_v4l2_subdev(pad->entity); | 360 | sensor = media_entity_to_v4l2_subdev(pad->entity); |
361 | pdata = sensor->host_priv; | 361 | buscfg = sensor->host_priv; |
362 | 362 | ||
363 | ret = ccp2_phyif_config(ccp2, &pdata->bus.ccp2); | 363 | ret = ccp2_phyif_config(ccp2, &buscfg->bus.ccp2); |
364 | if (ret < 0) | 364 | if (ret < 0) |
365 | return ret; | 365 | return ret; |
366 | 366 | ||
367 | ccp2_vp_config(ccp2, pdata->bus.ccp2.vpclk_div + 1); | 367 | ccp2_vp_config(ccp2, buscfg->bus.ccp2.vpclk_div + 1); |
368 | 368 | ||
369 | v4l2_subdev_call(sensor, sensor, g_skip_top_lines, &lines); | 369 | v4l2_subdev_call(sensor, sensor, g_skip_top_lines, &lines); |
370 | 370 | ||
371 | format = &ccp2->formats[CCP2_PAD_SINK]; | 371 | format = &ccp2->formats[CCP2_PAD_SINK]; |
372 | 372 | ||
373 | ccp2->if_cfg.data_start = lines; | 373 | ccp2->if_cfg.data_start = lines; |
374 | ccp2->if_cfg.crc = pdata->bus.ccp2.crc; | 374 | ccp2->if_cfg.crc = buscfg->bus.ccp2.crc; |
375 | ccp2->if_cfg.format = format->code; | 375 | ccp2->if_cfg.format = format->code; |
376 | ccp2->if_cfg.data_size = format->height; | 376 | ccp2->if_cfg.data_size = format->height; |
377 | 377 | ||
@@ -611,17 +611,17 @@ static const unsigned int ccp2_fmts[] = { | |||
611 | /* | 611 | /* |
612 | * __ccp2_get_format - helper function for getting ccp2 format | 612 | * __ccp2_get_format - helper function for getting ccp2 format |
613 | * @ccp2 : Pointer to ISP CCP2 device | 613 | * @ccp2 : Pointer to ISP CCP2 device |
614 | * @fh : V4L2 subdev file handle | 614 | * @cfg: V4L2 subdev pad configuration |
615 | * @pad : pad number | 615 | * @pad : pad number |
616 | * @which : wanted subdev format | 616 | * @which : wanted subdev format |
617 | * return format structure or NULL on error | 617 | * return format structure or NULL on error |
618 | */ | 618 | */ |
619 | static struct v4l2_mbus_framefmt * | 619 | static struct v4l2_mbus_framefmt * |
620 | __ccp2_get_format(struct isp_ccp2_device *ccp2, struct v4l2_subdev_fh *fh, | 620 | __ccp2_get_format(struct isp_ccp2_device *ccp2, struct v4l2_subdev_pad_config *cfg, |
621 | unsigned int pad, enum v4l2_subdev_format_whence which) | 621 | unsigned int pad, enum v4l2_subdev_format_whence which) |
622 | { | 622 | { |
623 | if (which == V4L2_SUBDEV_FORMAT_TRY) | 623 | if (which == V4L2_SUBDEV_FORMAT_TRY) |
624 | return v4l2_subdev_get_try_format(fh, pad); | 624 | return v4l2_subdev_get_try_format(&ccp2->subdev, cfg, pad); |
625 | else | 625 | else |
626 | return &ccp2->formats[pad]; | 626 | return &ccp2->formats[pad]; |
627 | } | 627 | } |
@@ -629,13 +629,13 @@ __ccp2_get_format(struct isp_ccp2_device *ccp2, struct v4l2_subdev_fh *fh, | |||
629 | /* | 629 | /* |
630 | * ccp2_try_format - Handle try format by pad subdev method | 630 | * ccp2_try_format - Handle try format by pad subdev method |
631 | * @ccp2 : Pointer to ISP CCP2 device | 631 | * @ccp2 : Pointer to ISP CCP2 device |
632 | * @fh : V4L2 subdev file handle | 632 | * @cfg: V4L2 subdev pad configuration |
633 | * @pad : pad num | 633 | * @pad : pad num |
634 | * @fmt : pointer to v4l2 mbus format structure | 634 | * @fmt : pointer to v4l2 mbus format structure |
635 | * @which : wanted subdev format | 635 | * @which : wanted subdev format |
636 | */ | 636 | */ |
637 | static void ccp2_try_format(struct isp_ccp2_device *ccp2, | 637 | static void ccp2_try_format(struct isp_ccp2_device *ccp2, |
638 | struct v4l2_subdev_fh *fh, unsigned int pad, | 638 | struct v4l2_subdev_pad_config *cfg, unsigned int pad, |
639 | struct v4l2_mbus_framefmt *fmt, | 639 | struct v4l2_mbus_framefmt *fmt, |
640 | enum v4l2_subdev_format_whence which) | 640 | enum v4l2_subdev_format_whence which) |
641 | { | 641 | { |
@@ -669,7 +669,7 @@ static void ccp2_try_format(struct isp_ccp2_device *ccp2, | |||
669 | * When CCP2 write to memory feature will be added this | 669 | * When CCP2 write to memory feature will be added this |
670 | * should be changed properly. | 670 | * should be changed properly. |
671 | */ | 671 | */ |
672 | format = __ccp2_get_format(ccp2, fh, CCP2_PAD_SINK, which); | 672 | format = __ccp2_get_format(ccp2, cfg, CCP2_PAD_SINK, which); |
673 | memcpy(fmt, format, sizeof(*fmt)); | 673 | memcpy(fmt, format, sizeof(*fmt)); |
674 | fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; | 674 | fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; |
675 | break; | 675 | break; |
@@ -682,12 +682,12 @@ static void ccp2_try_format(struct isp_ccp2_device *ccp2, | |||
682 | /* | 682 | /* |
683 | * ccp2_enum_mbus_code - Handle pixel format enumeration | 683 | * ccp2_enum_mbus_code - Handle pixel format enumeration |
684 | * @sd : pointer to v4l2 subdev structure | 684 | * @sd : pointer to v4l2 subdev structure |
685 | * @fh : V4L2 subdev file handle | 685 | * @cfg: V4L2 subdev pad configuration |
686 | * @code : pointer to v4l2_subdev_mbus_code_enum structure | 686 | * @code : pointer to v4l2_subdev_mbus_code_enum structure |
687 | * return -EINVAL or zero on success | 687 | * return -EINVAL or zero on success |
688 | */ | 688 | */ |
689 | static int ccp2_enum_mbus_code(struct v4l2_subdev *sd, | 689 | static int ccp2_enum_mbus_code(struct v4l2_subdev *sd, |
690 | struct v4l2_subdev_fh *fh, | 690 | struct v4l2_subdev_pad_config *cfg, |
691 | struct v4l2_subdev_mbus_code_enum *code) | 691 | struct v4l2_subdev_mbus_code_enum *code) |
692 | { | 692 | { |
693 | struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd); | 693 | struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd); |
@@ -702,8 +702,8 @@ static int ccp2_enum_mbus_code(struct v4l2_subdev *sd, | |||
702 | if (code->index != 0) | 702 | if (code->index != 0) |
703 | return -EINVAL; | 703 | return -EINVAL; |
704 | 704 | ||
705 | format = __ccp2_get_format(ccp2, fh, CCP2_PAD_SINK, | 705 | format = __ccp2_get_format(ccp2, cfg, CCP2_PAD_SINK, |
706 | V4L2_SUBDEV_FORMAT_TRY); | 706 | code->which); |
707 | code->code = format->code; | 707 | code->code = format->code; |
708 | } | 708 | } |
709 | 709 | ||
@@ -711,7 +711,7 @@ static int ccp2_enum_mbus_code(struct v4l2_subdev *sd, | |||
711 | } | 711 | } |
712 | 712 | ||
713 | static int ccp2_enum_frame_size(struct v4l2_subdev *sd, | 713 | static int ccp2_enum_frame_size(struct v4l2_subdev *sd, |
714 | struct v4l2_subdev_fh *fh, | 714 | struct v4l2_subdev_pad_config *cfg, |
715 | struct v4l2_subdev_frame_size_enum *fse) | 715 | struct v4l2_subdev_frame_size_enum *fse) |
716 | { | 716 | { |
717 | struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd); | 717 | struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd); |
@@ -723,7 +723,7 @@ static int ccp2_enum_frame_size(struct v4l2_subdev *sd, | |||
723 | format.code = fse->code; | 723 | format.code = fse->code; |
724 | format.width = 1; | 724 | format.width = 1; |
725 | format.height = 1; | 725 | format.height = 1; |
726 | ccp2_try_format(ccp2, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY); | 726 | ccp2_try_format(ccp2, cfg, fse->pad, &format, fse->which); |
727 | fse->min_width = format.width; | 727 | fse->min_width = format.width; |
728 | fse->min_height = format.height; | 728 | fse->min_height = format.height; |
729 | 729 | ||
@@ -733,7 +733,7 @@ static int ccp2_enum_frame_size(struct v4l2_subdev *sd, | |||
733 | format.code = fse->code; | 733 | format.code = fse->code; |
734 | format.width = -1; | 734 | format.width = -1; |
735 | format.height = -1; | 735 | format.height = -1; |
736 | ccp2_try_format(ccp2, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY); | 736 | ccp2_try_format(ccp2, cfg, fse->pad, &format, fse->which); |
737 | fse->max_width = format.width; | 737 | fse->max_width = format.width; |
738 | fse->max_height = format.height; | 738 | fse->max_height = format.height; |
739 | 739 | ||
@@ -743,17 +743,17 @@ static int ccp2_enum_frame_size(struct v4l2_subdev *sd, | |||
743 | /* | 743 | /* |
744 | * ccp2_get_format - Handle get format by pads subdev method | 744 | * ccp2_get_format - Handle get format by pads subdev method |
745 | * @sd : pointer to v4l2 subdev structure | 745 | * @sd : pointer to v4l2 subdev structure |
746 | * @fh : V4L2 subdev file handle | 746 | * @cfg: V4L2 subdev pad configuration |
747 | * @fmt : pointer to v4l2 subdev format structure | 747 | * @fmt : pointer to v4l2 subdev format structure |
748 | * return -EINVAL or zero on success | 748 | * return -EINVAL or zero on success |
749 | */ | 749 | */ |
750 | static int ccp2_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | 750 | static int ccp2_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, |
751 | struct v4l2_subdev_format *fmt) | 751 | struct v4l2_subdev_format *fmt) |
752 | { | 752 | { |
753 | struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd); | 753 | struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd); |
754 | struct v4l2_mbus_framefmt *format; | 754 | struct v4l2_mbus_framefmt *format; |
755 | 755 | ||
756 | format = __ccp2_get_format(ccp2, fh, fmt->pad, fmt->which); | 756 | format = __ccp2_get_format(ccp2, cfg, fmt->pad, fmt->which); |
757 | if (format == NULL) | 757 | if (format == NULL) |
758 | return -EINVAL; | 758 | return -EINVAL; |
759 | 759 | ||
@@ -764,29 +764,29 @@ static int ccp2_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
764 | /* | 764 | /* |
765 | * ccp2_set_format - Handle set format by pads subdev method | 765 | * ccp2_set_format - Handle set format by pads subdev method |
766 | * @sd : pointer to v4l2 subdev structure | 766 | * @sd : pointer to v4l2 subdev structure |
767 | * @fh : V4L2 subdev file handle | 767 | * @cfg: V4L2 subdev pad configuration |
768 | * @fmt : pointer to v4l2 subdev format structure | 768 | * @fmt : pointer to v4l2 subdev format structure |
769 | * returns zero | 769 | * returns zero |
770 | */ | 770 | */ |
771 | static int ccp2_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | 771 | static int ccp2_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, |
772 | struct v4l2_subdev_format *fmt) | 772 | struct v4l2_subdev_format *fmt) |
773 | { | 773 | { |
774 | struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd); | 774 | struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd); |
775 | struct v4l2_mbus_framefmt *format; | 775 | struct v4l2_mbus_framefmt *format; |
776 | 776 | ||
777 | format = __ccp2_get_format(ccp2, fh, fmt->pad, fmt->which); | 777 | format = __ccp2_get_format(ccp2, cfg, fmt->pad, fmt->which); |
778 | if (format == NULL) | 778 | if (format == NULL) |
779 | return -EINVAL; | 779 | return -EINVAL; |
780 | 780 | ||
781 | ccp2_try_format(ccp2, fh, fmt->pad, &fmt->format, fmt->which); | 781 | ccp2_try_format(ccp2, cfg, fmt->pad, &fmt->format, fmt->which); |
782 | *format = fmt->format; | 782 | *format = fmt->format; |
783 | 783 | ||
784 | /* Propagate the format from sink to source */ | 784 | /* Propagate the format from sink to source */ |
785 | if (fmt->pad == CCP2_PAD_SINK) { | 785 | if (fmt->pad == CCP2_PAD_SINK) { |
786 | format = __ccp2_get_format(ccp2, fh, CCP2_PAD_SOURCE, | 786 | format = __ccp2_get_format(ccp2, cfg, CCP2_PAD_SOURCE, |
787 | fmt->which); | 787 | fmt->which); |
788 | *format = fmt->format; | 788 | *format = fmt->format; |
789 | ccp2_try_format(ccp2, fh, CCP2_PAD_SOURCE, format, fmt->which); | 789 | ccp2_try_format(ccp2, cfg, CCP2_PAD_SOURCE, format, fmt->which); |
790 | } | 790 | } |
791 | 791 | ||
792 | return 0; | 792 | return 0; |
@@ -811,7 +811,7 @@ static int ccp2_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) | |||
811 | format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10; | 811 | format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10; |
812 | format.format.width = 4096; | 812 | format.format.width = 4096; |
813 | format.format.height = 4096; | 813 | format.format.height = 4096; |
814 | ccp2_set_format(sd, fh, &format); | 814 | ccp2_set_format(sd, fh ? fh->pad : NULL, &format); |
815 | 815 | ||
816 | return 0; | 816 | return 0; |
817 | } | 817 | } |
diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c index 09c686d96ae8..a78338d012b4 100644 --- a/drivers/media/platform/omap3isp/ispcsi2.c +++ b/drivers/media/platform/omap3isp/ispcsi2.c | |||
@@ -548,7 +548,8 @@ int omap3isp_csi2_reset(struct isp_csi2_device *csi2) | |||
548 | 548 | ||
549 | static int csi2_configure(struct isp_csi2_device *csi2) | 549 | static int csi2_configure(struct isp_csi2_device *csi2) |
550 | { | 550 | { |
551 | const struct isp_v4l2_subdevs_group *pdata; | 551 | struct isp_pipeline *pipe = to_isp_pipeline(&csi2->subdev.entity); |
552 | const struct isp_bus_cfg *buscfg; | ||
552 | struct isp_device *isp = csi2->isp; | 553 | struct isp_device *isp = csi2->isp; |
553 | struct isp_csi2_timing_cfg *timing = &csi2->timing[0]; | 554 | struct isp_csi2_timing_cfg *timing = &csi2->timing[0]; |
554 | struct v4l2_subdev *sensor; | 555 | struct v4l2_subdev *sensor; |
@@ -565,14 +566,19 @@ static int csi2_configure(struct isp_csi2_device *csi2) | |||
565 | 566 | ||
566 | pad = media_entity_remote_pad(&csi2->pads[CSI2_PAD_SINK]); | 567 | pad = media_entity_remote_pad(&csi2->pads[CSI2_PAD_SINK]); |
567 | sensor = media_entity_to_v4l2_subdev(pad->entity); | 568 | sensor = media_entity_to_v4l2_subdev(pad->entity); |
568 | pdata = sensor->host_priv; | 569 | buscfg = sensor->host_priv; |
569 | 570 | ||
570 | csi2->frame_skip = 0; | 571 | csi2->frame_skip = 0; |
571 | v4l2_subdev_call(sensor, sensor, g_skip_frames, &csi2->frame_skip); | 572 | v4l2_subdev_call(sensor, sensor, g_skip_frames, &csi2->frame_skip); |
572 | 573 | ||
573 | csi2->ctrl.vp_out_ctrl = pdata->bus.csi2.vpclk_div; | 574 | csi2->ctrl.vp_out_ctrl = |
575 | clamp_t(unsigned int, pipe->l3_ick / pipe->external_rate - 1, | ||
576 | 1, 3); | ||
577 | dev_dbg(isp->dev, "%s: l3_ick %lu, external_rate %u, vp_out_ctrl %u\n", | ||
578 | __func__, pipe->l3_ick, pipe->external_rate, | ||
579 | csi2->ctrl.vp_out_ctrl); | ||
574 | csi2->ctrl.frame_mode = ISP_CSI2_FRAME_IMMEDIATE; | 580 | csi2->ctrl.frame_mode = ISP_CSI2_FRAME_IMMEDIATE; |
575 | csi2->ctrl.ecc_enable = pdata->bus.csi2.crc; | 581 | csi2->ctrl.ecc_enable = buscfg->bus.csi2.crc; |
576 | 582 | ||
577 | timing->ionum = 1; | 583 | timing->ionum = 1; |
578 | timing->force_rx_mode = 1; | 584 | timing->force_rx_mode = 1; |
@@ -829,17 +835,17 @@ static const struct isp_video_operations csi2_ispvideo_ops = { | |||
829 | */ | 835 | */ |
830 | 836 | ||
831 | static struct v4l2_mbus_framefmt * | 837 | static struct v4l2_mbus_framefmt * |
832 | __csi2_get_format(struct isp_csi2_device *csi2, struct v4l2_subdev_fh *fh, | 838 | __csi2_get_format(struct isp_csi2_device *csi2, struct v4l2_subdev_pad_config *cfg, |
833 | unsigned int pad, enum v4l2_subdev_format_whence which) | 839 | unsigned int pad, enum v4l2_subdev_format_whence which) |
834 | { | 840 | { |
835 | if (which == V4L2_SUBDEV_FORMAT_TRY) | 841 | if (which == V4L2_SUBDEV_FORMAT_TRY) |
836 | return v4l2_subdev_get_try_format(fh, pad); | 842 | return v4l2_subdev_get_try_format(&csi2->subdev, cfg, pad); |
837 | else | 843 | else |
838 | return &csi2->formats[pad]; | 844 | return &csi2->formats[pad]; |
839 | } | 845 | } |
840 | 846 | ||
841 | static void | 847 | static void |
842 | csi2_try_format(struct isp_csi2_device *csi2, struct v4l2_subdev_fh *fh, | 848 | csi2_try_format(struct isp_csi2_device *csi2, struct v4l2_subdev_pad_config *cfg, |
843 | unsigned int pad, struct v4l2_mbus_framefmt *fmt, | 849 | unsigned int pad, struct v4l2_mbus_framefmt *fmt, |
844 | enum v4l2_subdev_format_whence which) | 850 | enum v4l2_subdev_format_whence which) |
845 | { | 851 | { |
@@ -869,7 +875,7 @@ csi2_try_format(struct isp_csi2_device *csi2, struct v4l2_subdev_fh *fh, | |||
869 | * compression. | 875 | * compression. |
870 | */ | 876 | */ |
871 | pixelcode = fmt->code; | 877 | pixelcode = fmt->code; |
872 | format = __csi2_get_format(csi2, fh, CSI2_PAD_SINK, which); | 878 | format = __csi2_get_format(csi2, cfg, CSI2_PAD_SINK, which); |
873 | memcpy(fmt, format, sizeof(*fmt)); | 879 | memcpy(fmt, format, sizeof(*fmt)); |
874 | 880 | ||
875 | /* | 881 | /* |
@@ -890,12 +896,12 @@ csi2_try_format(struct isp_csi2_device *csi2, struct v4l2_subdev_fh *fh, | |||
890 | /* | 896 | /* |
891 | * csi2_enum_mbus_code - Handle pixel format enumeration | 897 | * csi2_enum_mbus_code - Handle pixel format enumeration |
892 | * @sd : pointer to v4l2 subdev structure | 898 | * @sd : pointer to v4l2 subdev structure |
893 | * @fh : V4L2 subdev file handle | 899 | * @cfg: V4L2 subdev pad configuration |
894 | * @code : pointer to v4l2_subdev_mbus_code_enum structure | 900 | * @code : pointer to v4l2_subdev_mbus_code_enum structure |
895 | * return -EINVAL or zero on success | 901 | * return -EINVAL or zero on success |
896 | */ | 902 | */ |
897 | static int csi2_enum_mbus_code(struct v4l2_subdev *sd, | 903 | static int csi2_enum_mbus_code(struct v4l2_subdev *sd, |
898 | struct v4l2_subdev_fh *fh, | 904 | struct v4l2_subdev_pad_config *cfg, |
899 | struct v4l2_subdev_mbus_code_enum *code) | 905 | struct v4l2_subdev_mbus_code_enum *code) |
900 | { | 906 | { |
901 | struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd); | 907 | struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd); |
@@ -908,8 +914,8 @@ static int csi2_enum_mbus_code(struct v4l2_subdev *sd, | |||
908 | 914 | ||
909 | code->code = csi2_input_fmts[code->index]; | 915 | code->code = csi2_input_fmts[code->index]; |
910 | } else { | 916 | } else { |
911 | format = __csi2_get_format(csi2, fh, CSI2_PAD_SINK, | 917 | format = __csi2_get_format(csi2, cfg, CSI2_PAD_SINK, |
912 | V4L2_SUBDEV_FORMAT_TRY); | 918 | code->which); |
913 | switch (code->index) { | 919 | switch (code->index) { |
914 | case 0: | 920 | case 0: |
915 | /* Passthrough sink pad code */ | 921 | /* Passthrough sink pad code */ |
@@ -932,7 +938,7 @@ static int csi2_enum_mbus_code(struct v4l2_subdev *sd, | |||
932 | } | 938 | } |
933 | 939 | ||
934 | static int csi2_enum_frame_size(struct v4l2_subdev *sd, | 940 | static int csi2_enum_frame_size(struct v4l2_subdev *sd, |
935 | struct v4l2_subdev_fh *fh, | 941 | struct v4l2_subdev_pad_config *cfg, |
936 | struct v4l2_subdev_frame_size_enum *fse) | 942 | struct v4l2_subdev_frame_size_enum *fse) |
937 | { | 943 | { |
938 | struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd); | 944 | struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd); |
@@ -944,7 +950,7 @@ static int csi2_enum_frame_size(struct v4l2_subdev *sd, | |||
944 | format.code = fse->code; | 950 | format.code = fse->code; |
945 | format.width = 1; | 951 | format.width = 1; |
946 | format.height = 1; | 952 | format.height = 1; |
947 | csi2_try_format(csi2, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY); | 953 | csi2_try_format(csi2, cfg, fse->pad, &format, fse->which); |
948 | fse->min_width = format.width; | 954 | fse->min_width = format.width; |
949 | fse->min_height = format.height; | 955 | fse->min_height = format.height; |
950 | 956 | ||
@@ -954,7 +960,7 @@ static int csi2_enum_frame_size(struct v4l2_subdev *sd, | |||
954 | format.code = fse->code; | 960 | format.code = fse->code; |
955 | format.width = -1; | 961 | format.width = -1; |
956 | format.height = -1; | 962 | format.height = -1; |
957 | csi2_try_format(csi2, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY); | 963 | csi2_try_format(csi2, cfg, fse->pad, &format, fse->which); |
958 | fse->max_width = format.width; | 964 | fse->max_width = format.width; |
959 | fse->max_height = format.height; | 965 | fse->max_height = format.height; |
960 | 966 | ||
@@ -964,17 +970,17 @@ static int csi2_enum_frame_size(struct v4l2_subdev *sd, | |||
964 | /* | 970 | /* |
965 | * csi2_get_format - Handle get format by pads subdev method | 971 | * csi2_get_format - Handle get format by pads subdev method |
966 | * @sd : pointer to v4l2 subdev structure | 972 | * @sd : pointer to v4l2 subdev structure |
967 | * @fh : V4L2 subdev file handle | 973 | * @cfg: V4L2 subdev pad configuration |
968 | * @fmt: pointer to v4l2 subdev format structure | 974 | * @fmt: pointer to v4l2 subdev format structure |
969 | * return -EINVAL or zero on success | 975 | * return -EINVAL or zero on success |
970 | */ | 976 | */ |
971 | static int csi2_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | 977 | static int csi2_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, |
972 | struct v4l2_subdev_format *fmt) | 978 | struct v4l2_subdev_format *fmt) |
973 | { | 979 | { |
974 | struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd); | 980 | struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd); |
975 | struct v4l2_mbus_framefmt *format; | 981 | struct v4l2_mbus_framefmt *format; |
976 | 982 | ||
977 | format = __csi2_get_format(csi2, fh, fmt->pad, fmt->which); | 983 | format = __csi2_get_format(csi2, cfg, fmt->pad, fmt->which); |
978 | if (format == NULL) | 984 | if (format == NULL) |
979 | return -EINVAL; | 985 | return -EINVAL; |
980 | 986 | ||
@@ -985,29 +991,29 @@ static int csi2_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
985 | /* | 991 | /* |
986 | * csi2_set_format - Handle set format by pads subdev method | 992 | * csi2_set_format - Handle set format by pads subdev method |
987 | * @sd : pointer to v4l2 subdev structure | 993 | * @sd : pointer to v4l2 subdev structure |
988 | * @fh : V4L2 subdev file handle | 994 | * @cfg: V4L2 subdev pad configuration |
989 | * @fmt: pointer to v4l2 subdev format structure | 995 | * @fmt: pointer to v4l2 subdev format structure |
990 | * return -EINVAL or zero on success | 996 | * return -EINVAL or zero on success |
991 | */ | 997 | */ |
992 | static int csi2_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | 998 | static int csi2_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, |
993 | struct v4l2_subdev_format *fmt) | 999 | struct v4l2_subdev_format *fmt) |
994 | { | 1000 | { |
995 | struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd); | 1001 | struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd); |
996 | struct v4l2_mbus_framefmt *format; | 1002 | struct v4l2_mbus_framefmt *format; |
997 | 1003 | ||
998 | format = __csi2_get_format(csi2, fh, fmt->pad, fmt->which); | 1004 | format = __csi2_get_format(csi2, cfg, fmt->pad, fmt->which); |
999 | if (format == NULL) | 1005 | if (format == NULL) |
1000 | return -EINVAL; | 1006 | return -EINVAL; |
1001 | 1007 | ||
1002 | csi2_try_format(csi2, fh, fmt->pad, &fmt->format, fmt->which); | 1008 | csi2_try_format(csi2, cfg, fmt->pad, &fmt->format, fmt->which); |
1003 | *format = fmt->format; | 1009 | *format = fmt->format; |
1004 | 1010 | ||
1005 | /* Propagate the format from sink to source */ | 1011 | /* Propagate the format from sink to source */ |
1006 | if (fmt->pad == CSI2_PAD_SINK) { | 1012 | if (fmt->pad == CSI2_PAD_SINK) { |
1007 | format = __csi2_get_format(csi2, fh, CSI2_PAD_SOURCE, | 1013 | format = __csi2_get_format(csi2, cfg, CSI2_PAD_SOURCE, |
1008 | fmt->which); | 1014 | fmt->which); |
1009 | *format = fmt->format; | 1015 | *format = fmt->format; |
1010 | csi2_try_format(csi2, fh, CSI2_PAD_SOURCE, format, fmt->which); | 1016 | csi2_try_format(csi2, cfg, CSI2_PAD_SOURCE, format, fmt->which); |
1011 | } | 1017 | } |
1012 | 1018 | ||
1013 | return 0; | 1019 | return 0; |
@@ -1032,7 +1038,7 @@ static int csi2_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) | |||
1032 | format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10; | 1038 | format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10; |
1033 | format.format.width = 4096; | 1039 | format.format.width = 4096; |
1034 | format.format.height = 4096; | 1040 | format.format.height = 4096; |
1035 | csi2_set_format(sd, fh, &format); | 1041 | csi2_set_format(sd, fh ? fh->pad : NULL, &format); |
1036 | 1042 | ||
1037 | return 0; | 1043 | return 0; |
1038 | } | 1044 | } |
diff --git a/drivers/media/platform/omap3isp/ispcsiphy.c b/drivers/media/platform/omap3isp/ispcsiphy.c index e033f2237a72..495447d66cfd 100644 --- a/drivers/media/platform/omap3isp/ispcsiphy.c +++ b/drivers/media/platform/omap3isp/ispcsiphy.c | |||
@@ -16,6 +16,7 @@ | |||
16 | 16 | ||
17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
18 | #include <linux/device.h> | 18 | #include <linux/device.h> |
19 | #include <linux/regmap.h> | ||
19 | #include <linux/regulator/consumer.h> | 20 | #include <linux/regulator/consumer.h> |
20 | 21 | ||
21 | #include "isp.h" | 22 | #include "isp.h" |
@@ -26,10 +27,11 @@ static void csiphy_routing_cfg_3630(struct isp_csiphy *phy, | |||
26 | enum isp_interface_type iface, | 27 | enum isp_interface_type iface, |
27 | bool ccp2_strobe) | 28 | bool ccp2_strobe) |
28 | { | 29 | { |
29 | u32 reg = isp_reg_readl( | 30 | u32 reg; |
30 | phy->isp, OMAP3_ISP_IOMEM_3630_CONTROL_CAMERA_PHY_CTRL, 0); | ||
31 | u32 shift, mode; | 31 | u32 shift, mode; |
32 | 32 | ||
33 | regmap_read(phy->isp->syscon, phy->isp->syscon_offset, ®); | ||
34 | |||
33 | switch (iface) { | 35 | switch (iface) { |
34 | default: | 36 | default: |
35 | /* Should not happen in practice, but let's keep the compiler happy. */ | 37 | /* Should not happen in practice, but let's keep the compiler happy. */ |
@@ -63,8 +65,7 @@ static void csiphy_routing_cfg_3630(struct isp_csiphy *phy, | |||
63 | reg &= ~(OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_MASK << shift); | 65 | reg &= ~(OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_MASK << shift); |
64 | reg |= mode << shift; | 66 | reg |= mode << shift; |
65 | 67 | ||
66 | isp_reg_writel(phy->isp, reg, | 68 | regmap_write(phy->isp->syscon, phy->isp->syscon_offset, reg); |
67 | OMAP3_ISP_IOMEM_3630_CONTROL_CAMERA_PHY_CTRL, 0); | ||
68 | } | 69 | } |
69 | 70 | ||
70 | static void csiphy_routing_cfg_3430(struct isp_csiphy *phy, u32 iface, bool on, | 71 | static void csiphy_routing_cfg_3430(struct isp_csiphy *phy, u32 iface, bool on, |
@@ -78,16 +79,14 @@ static void csiphy_routing_cfg_3430(struct isp_csiphy *phy, u32 iface, bool on, | |||
78 | return; | 79 | return; |
79 | 80 | ||
80 | if (!on) { | 81 | if (!on) { |
81 | isp_reg_writel(phy->isp, 0, | 82 | regmap_write(phy->isp->syscon, phy->isp->syscon_offset, 0); |
82 | OMAP3_ISP_IOMEM_343X_CONTROL_CSIRXFE, 0); | ||
83 | return; | 83 | return; |
84 | } | 84 | } |
85 | 85 | ||
86 | if (ccp2_strobe) | 86 | if (ccp2_strobe) |
87 | csirxfe |= OMAP343X_CONTROL_CSIRXFE_SELFORM; | 87 | csirxfe |= OMAP343X_CONTROL_CSIRXFE_SELFORM; |
88 | 88 | ||
89 | isp_reg_writel(phy->isp, csirxfe, | 89 | regmap_write(phy->isp->syscon, phy->isp->syscon_offset, csirxfe); |
90 | OMAP3_ISP_IOMEM_343X_CONTROL_CSIRXFE, 0); | ||
91 | } | 90 | } |
92 | 91 | ||
93 | /* | 92 | /* |
@@ -106,10 +105,9 @@ static void csiphy_routing_cfg(struct isp_csiphy *phy, | |||
106 | enum isp_interface_type iface, bool on, | 105 | enum isp_interface_type iface, bool on, |
107 | bool ccp2_strobe) | 106 | bool ccp2_strobe) |
108 | { | 107 | { |
109 | if (phy->isp->mmio_base[OMAP3_ISP_IOMEM_3630_CONTROL_CAMERA_PHY_CTRL] | 108 | if (phy->isp->phy_type == ISP_PHY_TYPE_3630 && on) |
110 | && on) | ||
111 | return csiphy_routing_cfg_3630(phy, iface, ccp2_strobe); | 109 | return csiphy_routing_cfg_3630(phy, iface, ccp2_strobe); |
112 | if (phy->isp->mmio_base[OMAP3_ISP_IOMEM_343X_CONTROL_CSIRXFE]) | 110 | if (phy->isp->phy_type == ISP_PHY_TYPE_3430) |
113 | return csiphy_routing_cfg_3430(phy, iface, on, ccp2_strobe); | 111 | return csiphy_routing_cfg_3430(phy, iface, on, ccp2_strobe); |
114 | } | 112 | } |
115 | 113 | ||
@@ -168,18 +166,25 @@ static int omap3isp_csiphy_config(struct isp_csiphy *phy) | |||
168 | { | 166 | { |
169 | struct isp_csi2_device *csi2 = phy->csi2; | 167 | struct isp_csi2_device *csi2 = phy->csi2; |
170 | struct isp_pipeline *pipe = to_isp_pipeline(&csi2->subdev.entity); | 168 | struct isp_pipeline *pipe = to_isp_pipeline(&csi2->subdev.entity); |
171 | struct isp_v4l2_subdevs_group *subdevs = pipe->external->host_priv; | 169 | struct isp_bus_cfg *buscfg = pipe->external->host_priv; |
172 | struct isp_csiphy_lanes_cfg *lanes; | 170 | struct isp_csiphy_lanes_cfg *lanes; |
173 | int csi2_ddrclk_khz; | 171 | int csi2_ddrclk_khz; |
174 | unsigned int used_lanes = 0; | 172 | unsigned int used_lanes = 0; |
175 | unsigned int i; | 173 | unsigned int i; |
176 | u32 reg; | 174 | u32 reg; |
177 | 175 | ||
178 | if (subdevs->interface == ISP_INTERFACE_CCP2B_PHY1 | 176 | if (!buscfg) { |
179 | || subdevs->interface == ISP_INTERFACE_CCP2B_PHY2) | 177 | struct isp_async_subdev *isd = |
180 | lanes = &subdevs->bus.ccp2.lanecfg; | 178 | container_of(pipe->external->asd, |
179 | struct isp_async_subdev, asd); | ||
180 | buscfg = &isd->bus; | ||
181 | } | ||
182 | |||
183 | if (buscfg->interface == ISP_INTERFACE_CCP2B_PHY1 | ||
184 | || buscfg->interface == ISP_INTERFACE_CCP2B_PHY2) | ||
185 | lanes = &buscfg->bus.ccp2.lanecfg; | ||
181 | else | 186 | else |
182 | lanes = &subdevs->bus.csi2.lanecfg; | 187 | lanes = &buscfg->bus.csi2.lanecfg; |
183 | 188 | ||
184 | /* Clock and data lanes verification */ | 189 | /* Clock and data lanes verification */ |
185 | for (i = 0; i < phy->num_data_lanes; i++) { | 190 | for (i = 0; i < phy->num_data_lanes; i++) { |
@@ -203,8 +208,8 @@ static int omap3isp_csiphy_config(struct isp_csiphy *phy) | |||
203 | * issue since the MPU power domain is forced on whilst the | 208 | * issue since the MPU power domain is forced on whilst the |
204 | * ISP is in use. | 209 | * ISP is in use. |
205 | */ | 210 | */ |
206 | csiphy_routing_cfg(phy, subdevs->interface, true, | 211 | csiphy_routing_cfg(phy, buscfg->interface, true, |
207 | subdevs->bus.ccp2.phy_layer); | 212 | buscfg->bus.ccp2.phy_layer); |
208 | 213 | ||
209 | /* DPHY timing configuration */ | 214 | /* DPHY timing configuration */ |
210 | /* CSI-2 is DDR and we only count used lanes. */ | 215 | /* CSI-2 is DDR and we only count used lanes. */ |
@@ -302,11 +307,10 @@ void omap3isp_csiphy_release(struct isp_csiphy *phy) | |||
302 | struct isp_csi2_device *csi2 = phy->csi2; | 307 | struct isp_csi2_device *csi2 = phy->csi2; |
303 | struct isp_pipeline *pipe = | 308 | struct isp_pipeline *pipe = |
304 | to_isp_pipeline(&csi2->subdev.entity); | 309 | to_isp_pipeline(&csi2->subdev.entity); |
305 | struct isp_v4l2_subdevs_group *subdevs = | 310 | struct isp_bus_cfg *buscfg = pipe->external->host_priv; |
306 | pipe->external->host_priv; | ||
307 | 311 | ||
308 | csiphy_routing_cfg(phy, subdevs->interface, false, | 312 | csiphy_routing_cfg(phy, buscfg->interface, false, |
309 | subdevs->bus.ccp2.phy_layer); | 313 | buscfg->bus.ccp2.phy_layer); |
310 | csiphy_power_autoswitch_enable(phy, false); | 314 | csiphy_power_autoswitch_enable(phy, false); |
311 | csiphy_set_power(phy, ISPCSI2_PHY_CFG_PWR_CMD_OFF); | 315 | csiphy_set_power(phy, ISPCSI2_PHY_CFG_PWR_CMD_OFF); |
312 | regulator_disable(phy->vdd); | 316 | regulator_disable(phy->vdd); |
diff --git a/drivers/media/platform/omap3isp/isph3a_aewb.c b/drivers/media/platform/omap3isp/isph3a_aewb.c index b208c5417146..ccaf92f39236 100644 --- a/drivers/media/platform/omap3isp/isph3a_aewb.c +++ b/drivers/media/platform/omap3isp/isph3a_aewb.c | |||
@@ -297,7 +297,6 @@ int omap3isp_h3a_aewb_init(struct isp_device *isp) | |||
297 | 297 | ||
298 | aewb->ops = &h3a_aewb_ops; | 298 | aewb->ops = &h3a_aewb_ops; |
299 | aewb->priv = aewb_cfg; | 299 | aewb->priv = aewb_cfg; |
300 | aewb->dma_ch = -1; | ||
301 | aewb->event_type = V4L2_EVENT_OMAP3ISP_AEWB; | 300 | aewb->event_type = V4L2_EVENT_OMAP3ISP_AEWB; |
302 | aewb->isp = isp; | 301 | aewb->isp = isp; |
303 | 302 | ||
diff --git a/drivers/media/platform/omap3isp/isph3a_af.c b/drivers/media/platform/omap3isp/isph3a_af.c index 8a83e195f3e3..92937f7eecef 100644 --- a/drivers/media/platform/omap3isp/isph3a_af.c +++ b/drivers/media/platform/omap3isp/isph3a_af.c | |||
@@ -360,7 +360,6 @@ int omap3isp_h3a_af_init(struct isp_device *isp) | |||
360 | 360 | ||
361 | af->ops = &h3a_af_ops; | 361 | af->ops = &h3a_af_ops; |
362 | af->priv = af_cfg; | 362 | af->priv = af_cfg; |
363 | af->dma_ch = -1; | ||
364 | af->event_type = V4L2_EVENT_OMAP3ISP_AF; | 363 | af->event_type = V4L2_EVENT_OMAP3ISP_AF; |
365 | af->isp = isp; | 364 | af->isp = isp; |
366 | 365 | ||
diff --git a/drivers/media/platform/omap3isp/isphist.c b/drivers/media/platform/omap3isp/isphist.c index ce822c34c843..7138b043a4aa 100644 --- a/drivers/media/platform/omap3isp/isphist.c +++ b/drivers/media/platform/omap3isp/isphist.c | |||
@@ -16,20 +16,18 @@ | |||
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
19 | #include <linux/device.h> | ||
20 | #include <linux/dmaengine.h> | ||
21 | #include <linux/omap-dmaengine.h> | ||
19 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
20 | #include <linux/uaccess.h> | 23 | #include <linux/uaccess.h> |
21 | #include <linux/device.h> | ||
22 | 24 | ||
23 | #include "isp.h" | 25 | #include "isp.h" |
24 | #include "ispreg.h" | 26 | #include "ispreg.h" |
25 | #include "isphist.h" | 27 | #include "isphist.h" |
26 | 28 | ||
27 | #define OMAP24XX_DMA_NO_DEVICE 0 | ||
28 | |||
29 | #define HIST_CONFIG_DMA 1 | 29 | #define HIST_CONFIG_DMA 1 |
30 | 30 | ||
31 | #define HIST_USING_DMA(hist) ((hist)->dma_ch >= 0) | ||
32 | |||
33 | /* | 31 | /* |
34 | * hist_reset_mem - clear Histogram memory before start stats engine. | 32 | * hist_reset_mem - clear Histogram memory before start stats engine. |
35 | */ | 33 | */ |
@@ -62,20 +60,6 @@ static void hist_reset_mem(struct ispstat *hist) | |||
62 | hist->wait_acc_frames = conf->num_acc_frames; | 60 | hist->wait_acc_frames = conf->num_acc_frames; |
63 | } | 61 | } |
64 | 62 | ||
65 | static void hist_dma_config(struct ispstat *hist) | ||
66 | { | ||
67 | struct isp_device *isp = hist->isp; | ||
68 | |||
69 | hist->dma_config.data_type = OMAP_DMA_DATA_TYPE_S32; | ||
70 | hist->dma_config.sync_mode = OMAP_DMA_SYNC_ELEMENT; | ||
71 | hist->dma_config.frame_count = 1; | ||
72 | hist->dma_config.src_amode = OMAP_DMA_AMODE_CONSTANT; | ||
73 | hist->dma_config.src_start = isp->mmio_base_phys[OMAP3_ISP_IOMEM_HIST] | ||
74 | + ISPHIST_DATA; | ||
75 | hist->dma_config.dst_amode = OMAP_DMA_AMODE_POST_INC; | ||
76 | hist->dma_config.src_or_dst_synch = OMAP_DMA_SRC_SYNC; | ||
77 | } | ||
78 | |||
79 | /* | 63 | /* |
80 | * hist_setup_regs - Helper function to update Histogram registers. | 64 | * hist_setup_regs - Helper function to update Histogram registers. |
81 | */ | 65 | */ |
@@ -176,17 +160,12 @@ static int hist_busy(struct ispstat *hist) | |||
176 | & ISPHIST_PCR_BUSY; | 160 | & ISPHIST_PCR_BUSY; |
177 | } | 161 | } |
178 | 162 | ||
179 | static void hist_dma_cb(int lch, u16 ch_status, void *data) | 163 | static void hist_dma_cb(void *data) |
180 | { | 164 | { |
181 | struct ispstat *hist = data; | 165 | struct ispstat *hist = data; |
182 | 166 | ||
183 | if (ch_status & ~OMAP_DMA_BLOCK_IRQ) { | 167 | /* FIXME: The DMA engine API can't report transfer errors :-/ */ |
184 | dev_dbg(hist->isp->dev, "hist: DMA error. status = 0x%04x\n", | 168 | |
185 | ch_status); | ||
186 | omap_stop_dma(lch); | ||
187 | hist_reset_mem(hist); | ||
188 | atomic_set(&hist->buf_err, 1); | ||
189 | } | ||
190 | isp_reg_clr(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, | 169 | isp_reg_clr(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, |
191 | ISPHIST_CNT_CLEAR); | 170 | ISPHIST_CNT_CLEAR); |
192 | 171 | ||
@@ -198,24 +177,57 @@ static void hist_dma_cb(int lch, u16 ch_status, void *data) | |||
198 | static int hist_buf_dma(struct ispstat *hist) | 177 | static int hist_buf_dma(struct ispstat *hist) |
199 | { | 178 | { |
200 | dma_addr_t dma_addr = hist->active_buf->dma_addr; | 179 | dma_addr_t dma_addr = hist->active_buf->dma_addr; |
180 | struct dma_async_tx_descriptor *tx; | ||
181 | struct dma_slave_config cfg; | ||
182 | dma_cookie_t cookie; | ||
183 | int ret; | ||
201 | 184 | ||
202 | if (unlikely(!dma_addr)) { | 185 | if (unlikely(!dma_addr)) { |
203 | dev_dbg(hist->isp->dev, "hist: invalid DMA buffer address\n"); | 186 | dev_dbg(hist->isp->dev, "hist: invalid DMA buffer address\n"); |
204 | hist_reset_mem(hist); | 187 | goto error; |
205 | return STAT_NO_BUF; | ||
206 | } | 188 | } |
207 | 189 | ||
208 | isp_reg_writel(hist->isp, 0, OMAP3_ISP_IOMEM_HIST, ISPHIST_ADDR); | 190 | isp_reg_writel(hist->isp, 0, OMAP3_ISP_IOMEM_HIST, ISPHIST_ADDR); |
209 | isp_reg_set(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, | 191 | isp_reg_set(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, |
210 | ISPHIST_CNT_CLEAR); | 192 | ISPHIST_CNT_CLEAR); |
211 | omap3isp_flush(hist->isp); | 193 | omap3isp_flush(hist->isp); |
212 | hist->dma_config.dst_start = dma_addr; | ||
213 | hist->dma_config.elem_count = hist->buf_size / sizeof(u32); | ||
214 | omap_set_dma_params(hist->dma_ch, &hist->dma_config); | ||
215 | 194 | ||
216 | omap_start_dma(hist->dma_ch); | 195 | memset(&cfg, 0, sizeof(cfg)); |
196 | cfg.src_addr = hist->isp->mmio_hist_base_phys + ISPHIST_DATA; | ||
197 | cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
198 | cfg.src_maxburst = hist->buf_size / 4; | ||
199 | |||
200 | ret = dmaengine_slave_config(hist->dma_ch, &cfg); | ||
201 | if (ret < 0) { | ||
202 | dev_dbg(hist->isp->dev, | ||
203 | "hist: DMA slave configuration failed\n"); | ||
204 | goto error; | ||
205 | } | ||
206 | |||
207 | tx = dmaengine_prep_slave_single(hist->dma_ch, dma_addr, | ||
208 | hist->buf_size, DMA_DEV_TO_MEM, | ||
209 | DMA_CTRL_ACK); | ||
210 | if (tx == NULL) { | ||
211 | dev_dbg(hist->isp->dev, | ||
212 | "hist: DMA slave preparation failed\n"); | ||
213 | goto error; | ||
214 | } | ||
215 | |||
216 | tx->callback = hist_dma_cb; | ||
217 | tx->callback_param = hist; | ||
218 | cookie = tx->tx_submit(tx); | ||
219 | if (dma_submit_error(cookie)) { | ||
220 | dev_dbg(hist->isp->dev, "hist: DMA submission failed\n"); | ||
221 | goto error; | ||
222 | } | ||
223 | |||
224 | dma_async_issue_pending(hist->dma_ch); | ||
217 | 225 | ||
218 | return STAT_BUF_WAITING_DMA; | 226 | return STAT_BUF_WAITING_DMA; |
227 | |||
228 | error: | ||
229 | hist_reset_mem(hist); | ||
230 | return STAT_NO_BUF; | ||
219 | } | 231 | } |
220 | 232 | ||
221 | static int hist_buf_pio(struct ispstat *hist) | 233 | static int hist_buf_pio(struct ispstat *hist) |
@@ -272,7 +284,7 @@ static int hist_buf_process(struct ispstat *hist) | |||
272 | if (--(hist->wait_acc_frames)) | 284 | if (--(hist->wait_acc_frames)) |
273 | return STAT_NO_BUF; | 285 | return STAT_NO_BUF; |
274 | 286 | ||
275 | if (HIST_USING_DMA(hist)) | 287 | if (hist->dma_ch) |
276 | ret = hist_buf_dma(hist); | 288 | ret = hist_buf_dma(hist); |
277 | else | 289 | else |
278 | ret = hist_buf_pio(hist); | 290 | ret = hist_buf_pio(hist); |
@@ -473,18 +485,28 @@ int omap3isp_hist_init(struct isp_device *isp) | |||
473 | 485 | ||
474 | hist->isp = isp; | 486 | hist->isp = isp; |
475 | 487 | ||
476 | if (HIST_CONFIG_DMA) | 488 | if (HIST_CONFIG_DMA) { |
477 | ret = omap_request_dma(OMAP24XX_DMA_NO_DEVICE, "DMA_ISP_HIST", | 489 | struct platform_device *pdev = to_platform_device(isp->dev); |
478 | hist_dma_cb, hist, &hist->dma_ch); | 490 | struct resource *res; |
479 | if (ret) { | 491 | unsigned int sig = 0; |
480 | if (HIST_CONFIG_DMA) | 492 | dma_cap_mask_t mask; |
481 | dev_warn(isp->dev, "hist: DMA request channel failed. " | 493 | |
482 | "Using PIO only.\n"); | 494 | dma_cap_zero(mask); |
483 | hist->dma_ch = -1; | 495 | dma_cap_set(DMA_SLAVE, mask); |
484 | } else { | 496 | |
485 | dev_dbg(isp->dev, "hist: DMA channel = %d\n", hist->dma_ch); | 497 | res = platform_get_resource_byname(pdev, IORESOURCE_DMA, |
486 | hist_dma_config(hist); | 498 | "hist"); |
487 | omap_enable_dma_irq(hist->dma_ch, OMAP_DMA_BLOCK_IRQ); | 499 | if (res) |
500 | sig = res->start; | ||
501 | |||
502 | hist->dma_ch = dma_request_slave_channel_compat(mask, | ||
503 | omap_dma_filter_fn, &sig, isp->dev, "hist"); | ||
504 | if (!hist->dma_ch) | ||
505 | dev_warn(isp->dev, | ||
506 | "hist: DMA channel request failed, using PIO\n"); | ||
507 | else | ||
508 | dev_dbg(isp->dev, "hist: using DMA channel %s\n", | ||
509 | dma_chan_name(hist->dma_ch)); | ||
488 | } | 510 | } |
489 | 511 | ||
490 | hist->ops = &hist_ops; | 512 | hist->ops = &hist_ops; |
@@ -493,8 +515,8 @@ int omap3isp_hist_init(struct isp_device *isp) | |||
493 | 515 | ||
494 | ret = omap3isp_stat_init(hist, "histogram", &hist_subdev_ops); | 516 | ret = omap3isp_stat_init(hist, "histogram", &hist_subdev_ops); |
495 | if (ret) { | 517 | if (ret) { |
496 | if (HIST_USING_DMA(hist)) | 518 | if (hist->dma_ch) |
497 | omap_free_dma(hist->dma_ch); | 519 | dma_release_channel(hist->dma_ch); |
498 | } | 520 | } |
499 | 521 | ||
500 | return ret; | 522 | return ret; |
@@ -505,7 +527,10 @@ int omap3isp_hist_init(struct isp_device *isp) | |||
505 | */ | 527 | */ |
506 | void omap3isp_hist_cleanup(struct isp_device *isp) | 528 | void omap3isp_hist_cleanup(struct isp_device *isp) |
507 | { | 529 | { |
508 | if (HIST_USING_DMA(&isp->isp_hist)) | 530 | struct ispstat *hist = &isp->isp_hist; |
509 | omap_free_dma(isp->isp_hist.dma_ch); | 531 | |
510 | omap3isp_stat_cleanup(&isp->isp_hist); | 532 | if (hist->dma_ch) |
533 | dma_release_channel(hist->dma_ch); | ||
534 | |||
535 | omap3isp_stat_cleanup(hist); | ||
511 | } | 536 | } |
diff --git a/drivers/media/platform/omap3isp/isppreview.c b/drivers/media/platform/omap3isp/isppreview.c index dd9eed45d853..15cb254ccc39 100644 --- a/drivers/media/platform/omap3isp/isppreview.c +++ b/drivers/media/platform/omap3isp/isppreview.c | |||
@@ -1686,21 +1686,21 @@ static int preview_set_stream(struct v4l2_subdev *sd, int enable) | |||
1686 | } | 1686 | } |
1687 | 1687 | ||
1688 | static struct v4l2_mbus_framefmt * | 1688 | static struct v4l2_mbus_framefmt * |
1689 | __preview_get_format(struct isp_prev_device *prev, struct v4l2_subdev_fh *fh, | 1689 | __preview_get_format(struct isp_prev_device *prev, struct v4l2_subdev_pad_config *cfg, |
1690 | unsigned int pad, enum v4l2_subdev_format_whence which) | 1690 | unsigned int pad, enum v4l2_subdev_format_whence which) |
1691 | { | 1691 | { |
1692 | if (which == V4L2_SUBDEV_FORMAT_TRY) | 1692 | if (which == V4L2_SUBDEV_FORMAT_TRY) |
1693 | return v4l2_subdev_get_try_format(fh, pad); | 1693 | return v4l2_subdev_get_try_format(&prev->subdev, cfg, pad); |
1694 | else | 1694 | else |
1695 | return &prev->formats[pad]; | 1695 | return &prev->formats[pad]; |
1696 | } | 1696 | } |
1697 | 1697 | ||
1698 | static struct v4l2_rect * | 1698 | static struct v4l2_rect * |
1699 | __preview_get_crop(struct isp_prev_device *prev, struct v4l2_subdev_fh *fh, | 1699 | __preview_get_crop(struct isp_prev_device *prev, struct v4l2_subdev_pad_config *cfg, |
1700 | enum v4l2_subdev_format_whence which) | 1700 | enum v4l2_subdev_format_whence which) |
1701 | { | 1701 | { |
1702 | if (which == V4L2_SUBDEV_FORMAT_TRY) | 1702 | if (which == V4L2_SUBDEV_FORMAT_TRY) |
1703 | return v4l2_subdev_get_try_crop(fh, PREV_PAD_SINK); | 1703 | return v4l2_subdev_get_try_crop(&prev->subdev, cfg, PREV_PAD_SINK); |
1704 | else | 1704 | else |
1705 | return &prev->crop; | 1705 | return &prev->crop; |
1706 | } | 1706 | } |
@@ -1727,7 +1727,7 @@ static const unsigned int preview_output_fmts[] = { | |||
1727 | /* | 1727 | /* |
1728 | * preview_try_format - Validate a format | 1728 | * preview_try_format - Validate a format |
1729 | * @prev: ISP preview engine | 1729 | * @prev: ISP preview engine |
1730 | * @fh: V4L2 subdev file handle | 1730 | * @cfg: V4L2 subdev pad configuration |
1731 | * @pad: pad number | 1731 | * @pad: pad number |
1732 | * @fmt: format to be validated | 1732 | * @fmt: format to be validated |
1733 | * @which: try/active format selector | 1733 | * @which: try/active format selector |
@@ -1736,7 +1736,7 @@ static const unsigned int preview_output_fmts[] = { | |||
1736 | * engine limits and the format and crop rectangles on other pads. | 1736 | * engine limits and the format and crop rectangles on other pads. |
1737 | */ | 1737 | */ |
1738 | static void preview_try_format(struct isp_prev_device *prev, | 1738 | static void preview_try_format(struct isp_prev_device *prev, |
1739 | struct v4l2_subdev_fh *fh, unsigned int pad, | 1739 | struct v4l2_subdev_pad_config *cfg, unsigned int pad, |
1740 | struct v4l2_mbus_framefmt *fmt, | 1740 | struct v4l2_mbus_framefmt *fmt, |
1741 | enum v4l2_subdev_format_whence which) | 1741 | enum v4l2_subdev_format_whence which) |
1742 | { | 1742 | { |
@@ -1777,7 +1777,7 @@ static void preview_try_format(struct isp_prev_device *prev, | |||
1777 | 1777 | ||
1778 | case PREV_PAD_SOURCE: | 1778 | case PREV_PAD_SOURCE: |
1779 | pixelcode = fmt->code; | 1779 | pixelcode = fmt->code; |
1780 | *fmt = *__preview_get_format(prev, fh, PREV_PAD_SINK, which); | 1780 | *fmt = *__preview_get_format(prev, cfg, PREV_PAD_SINK, which); |
1781 | 1781 | ||
1782 | switch (pixelcode) { | 1782 | switch (pixelcode) { |
1783 | case MEDIA_BUS_FMT_YUYV8_1X16: | 1783 | case MEDIA_BUS_FMT_YUYV8_1X16: |
@@ -1795,7 +1795,7 @@ static void preview_try_format(struct isp_prev_device *prev, | |||
1795 | * is not supported yet, hardcode the output size to the crop | 1795 | * is not supported yet, hardcode the output size to the crop |
1796 | * rectangle size. | 1796 | * rectangle size. |
1797 | */ | 1797 | */ |
1798 | crop = __preview_get_crop(prev, fh, which); | 1798 | crop = __preview_get_crop(prev, cfg, which); |
1799 | fmt->width = crop->width; | 1799 | fmt->width = crop->width; |
1800 | fmt->height = crop->height; | 1800 | fmt->height = crop->height; |
1801 | 1801 | ||
@@ -1864,12 +1864,12 @@ static void preview_try_crop(struct isp_prev_device *prev, | |||
1864 | /* | 1864 | /* |
1865 | * preview_enum_mbus_code - Handle pixel format enumeration | 1865 | * preview_enum_mbus_code - Handle pixel format enumeration |
1866 | * @sd : pointer to v4l2 subdev structure | 1866 | * @sd : pointer to v4l2 subdev structure |
1867 | * @fh : V4L2 subdev file handle | 1867 | * @cfg: V4L2 subdev pad configuration |
1868 | * @code : pointer to v4l2_subdev_mbus_code_enum structure | 1868 | * @code : pointer to v4l2_subdev_mbus_code_enum structure |
1869 | * return -EINVAL or zero on success | 1869 | * return -EINVAL or zero on success |
1870 | */ | 1870 | */ |
1871 | static int preview_enum_mbus_code(struct v4l2_subdev *sd, | 1871 | static int preview_enum_mbus_code(struct v4l2_subdev *sd, |
1872 | struct v4l2_subdev_fh *fh, | 1872 | struct v4l2_subdev_pad_config *cfg, |
1873 | struct v4l2_subdev_mbus_code_enum *code) | 1873 | struct v4l2_subdev_mbus_code_enum *code) |
1874 | { | 1874 | { |
1875 | switch (code->pad) { | 1875 | switch (code->pad) { |
@@ -1893,7 +1893,7 @@ static int preview_enum_mbus_code(struct v4l2_subdev *sd, | |||
1893 | } | 1893 | } |
1894 | 1894 | ||
1895 | static int preview_enum_frame_size(struct v4l2_subdev *sd, | 1895 | static int preview_enum_frame_size(struct v4l2_subdev *sd, |
1896 | struct v4l2_subdev_fh *fh, | 1896 | struct v4l2_subdev_pad_config *cfg, |
1897 | struct v4l2_subdev_frame_size_enum *fse) | 1897 | struct v4l2_subdev_frame_size_enum *fse) |
1898 | { | 1898 | { |
1899 | struct isp_prev_device *prev = v4l2_get_subdevdata(sd); | 1899 | struct isp_prev_device *prev = v4l2_get_subdevdata(sd); |
@@ -1905,7 +1905,7 @@ static int preview_enum_frame_size(struct v4l2_subdev *sd, | |||
1905 | format.code = fse->code; | 1905 | format.code = fse->code; |
1906 | format.width = 1; | 1906 | format.width = 1; |
1907 | format.height = 1; | 1907 | format.height = 1; |
1908 | preview_try_format(prev, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY); | 1908 | preview_try_format(prev, cfg, fse->pad, &format, fse->which); |
1909 | fse->min_width = format.width; | 1909 | fse->min_width = format.width; |
1910 | fse->min_height = format.height; | 1910 | fse->min_height = format.height; |
1911 | 1911 | ||
@@ -1915,7 +1915,7 @@ static int preview_enum_frame_size(struct v4l2_subdev *sd, | |||
1915 | format.code = fse->code; | 1915 | format.code = fse->code; |
1916 | format.width = -1; | 1916 | format.width = -1; |
1917 | format.height = -1; | 1917 | format.height = -1; |
1918 | preview_try_format(prev, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY); | 1918 | preview_try_format(prev, cfg, fse->pad, &format, fse->which); |
1919 | fse->max_width = format.width; | 1919 | fse->max_width = format.width; |
1920 | fse->max_height = format.height; | 1920 | fse->max_height = format.height; |
1921 | 1921 | ||
@@ -1925,7 +1925,7 @@ static int preview_enum_frame_size(struct v4l2_subdev *sd, | |||
1925 | /* | 1925 | /* |
1926 | * preview_get_selection - Retrieve a selection rectangle on a pad | 1926 | * preview_get_selection - Retrieve a selection rectangle on a pad |
1927 | * @sd: ISP preview V4L2 subdevice | 1927 | * @sd: ISP preview V4L2 subdevice |
1928 | * @fh: V4L2 subdev file handle | 1928 | * @cfg: V4L2 subdev pad configuration |
1929 | * @sel: Selection rectangle | 1929 | * @sel: Selection rectangle |
1930 | * | 1930 | * |
1931 | * The only supported rectangles are the crop rectangles on the sink pad. | 1931 | * The only supported rectangles are the crop rectangles on the sink pad. |
@@ -1933,7 +1933,7 @@ static int preview_enum_frame_size(struct v4l2_subdev *sd, | |||
1933 | * Return 0 on success or a negative error code otherwise. | 1933 | * Return 0 on success or a negative error code otherwise. |
1934 | */ | 1934 | */ |
1935 | static int preview_get_selection(struct v4l2_subdev *sd, | 1935 | static int preview_get_selection(struct v4l2_subdev *sd, |
1936 | struct v4l2_subdev_fh *fh, | 1936 | struct v4l2_subdev_pad_config *cfg, |
1937 | struct v4l2_subdev_selection *sel) | 1937 | struct v4l2_subdev_selection *sel) |
1938 | { | 1938 | { |
1939 | struct isp_prev_device *prev = v4l2_get_subdevdata(sd); | 1939 | struct isp_prev_device *prev = v4l2_get_subdevdata(sd); |
@@ -1949,13 +1949,13 @@ static int preview_get_selection(struct v4l2_subdev *sd, | |||
1949 | sel->r.width = INT_MAX; | 1949 | sel->r.width = INT_MAX; |
1950 | sel->r.height = INT_MAX; | 1950 | sel->r.height = INT_MAX; |
1951 | 1951 | ||
1952 | format = __preview_get_format(prev, fh, PREV_PAD_SINK, | 1952 | format = __preview_get_format(prev, cfg, PREV_PAD_SINK, |
1953 | sel->which); | 1953 | sel->which); |
1954 | preview_try_crop(prev, format, &sel->r); | 1954 | preview_try_crop(prev, format, &sel->r); |
1955 | break; | 1955 | break; |
1956 | 1956 | ||
1957 | case V4L2_SEL_TGT_CROP: | 1957 | case V4L2_SEL_TGT_CROP: |
1958 | sel->r = *__preview_get_crop(prev, fh, sel->which); | 1958 | sel->r = *__preview_get_crop(prev, cfg, sel->which); |
1959 | break; | 1959 | break; |
1960 | 1960 | ||
1961 | default: | 1961 | default: |
@@ -1968,7 +1968,7 @@ static int preview_get_selection(struct v4l2_subdev *sd, | |||
1968 | /* | 1968 | /* |
1969 | * preview_set_selection - Set a selection rectangle on a pad | 1969 | * preview_set_selection - Set a selection rectangle on a pad |
1970 | * @sd: ISP preview V4L2 subdevice | 1970 | * @sd: ISP preview V4L2 subdevice |
1971 | * @fh: V4L2 subdev file handle | 1971 | * @cfg: V4L2 subdev pad configuration |
1972 | * @sel: Selection rectangle | 1972 | * @sel: Selection rectangle |
1973 | * | 1973 | * |
1974 | * The only supported rectangle is the actual crop rectangle on the sink pad. | 1974 | * The only supported rectangle is the actual crop rectangle on the sink pad. |
@@ -1976,7 +1976,7 @@ static int preview_get_selection(struct v4l2_subdev *sd, | |||
1976 | * Return 0 on success or a negative error code otherwise. | 1976 | * Return 0 on success or a negative error code otherwise. |
1977 | */ | 1977 | */ |
1978 | static int preview_set_selection(struct v4l2_subdev *sd, | 1978 | static int preview_set_selection(struct v4l2_subdev *sd, |
1979 | struct v4l2_subdev_fh *fh, | 1979 | struct v4l2_subdev_pad_config *cfg, |
1980 | struct v4l2_subdev_selection *sel) | 1980 | struct v4l2_subdev_selection *sel) |
1981 | { | 1981 | { |
1982 | struct isp_prev_device *prev = v4l2_get_subdevdata(sd); | 1982 | struct isp_prev_device *prev = v4l2_get_subdevdata(sd); |
@@ -1995,17 +1995,17 @@ static int preview_set_selection(struct v4l2_subdev *sd, | |||
1995 | * rectangle. | 1995 | * rectangle. |
1996 | */ | 1996 | */ |
1997 | if (sel->flags & V4L2_SEL_FLAG_KEEP_CONFIG) { | 1997 | if (sel->flags & V4L2_SEL_FLAG_KEEP_CONFIG) { |
1998 | sel->r = *__preview_get_crop(prev, fh, sel->which); | 1998 | sel->r = *__preview_get_crop(prev, cfg, sel->which); |
1999 | return 0; | 1999 | return 0; |
2000 | } | 2000 | } |
2001 | 2001 | ||
2002 | format = __preview_get_format(prev, fh, PREV_PAD_SINK, sel->which); | 2002 | format = __preview_get_format(prev, cfg, PREV_PAD_SINK, sel->which); |
2003 | preview_try_crop(prev, format, &sel->r); | 2003 | preview_try_crop(prev, format, &sel->r); |
2004 | *__preview_get_crop(prev, fh, sel->which) = sel->r; | 2004 | *__preview_get_crop(prev, cfg, sel->which) = sel->r; |
2005 | 2005 | ||
2006 | /* Update the source format. */ | 2006 | /* Update the source format. */ |
2007 | format = __preview_get_format(prev, fh, PREV_PAD_SOURCE, sel->which); | 2007 | format = __preview_get_format(prev, cfg, PREV_PAD_SOURCE, sel->which); |
2008 | preview_try_format(prev, fh, PREV_PAD_SOURCE, format, sel->which); | 2008 | preview_try_format(prev, cfg, PREV_PAD_SOURCE, format, sel->which); |
2009 | 2009 | ||
2010 | return 0; | 2010 | return 0; |
2011 | } | 2011 | } |
@@ -2013,17 +2013,17 @@ static int preview_set_selection(struct v4l2_subdev *sd, | |||
2013 | /* | 2013 | /* |
2014 | * preview_get_format - Handle get format by pads subdev method | 2014 | * preview_get_format - Handle get format by pads subdev method |
2015 | * @sd : pointer to v4l2 subdev structure | 2015 | * @sd : pointer to v4l2 subdev structure |
2016 | * @fh : V4L2 subdev file handle | 2016 | * @cfg: V4L2 subdev pad configuration |
2017 | * @fmt: pointer to v4l2 subdev format structure | 2017 | * @fmt: pointer to v4l2 subdev format structure |
2018 | * return -EINVAL or zero on success | 2018 | * return -EINVAL or zero on success |
2019 | */ | 2019 | */ |
2020 | static int preview_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | 2020 | static int preview_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, |
2021 | struct v4l2_subdev_format *fmt) | 2021 | struct v4l2_subdev_format *fmt) |
2022 | { | 2022 | { |
2023 | struct isp_prev_device *prev = v4l2_get_subdevdata(sd); | 2023 | struct isp_prev_device *prev = v4l2_get_subdevdata(sd); |
2024 | struct v4l2_mbus_framefmt *format; | 2024 | struct v4l2_mbus_framefmt *format; |
2025 | 2025 | ||
2026 | format = __preview_get_format(prev, fh, fmt->pad, fmt->which); | 2026 | format = __preview_get_format(prev, cfg, fmt->pad, fmt->which); |
2027 | if (format == NULL) | 2027 | if (format == NULL) |
2028 | return -EINVAL; | 2028 | return -EINVAL; |
2029 | 2029 | ||
@@ -2034,28 +2034,28 @@ static int preview_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
2034 | /* | 2034 | /* |
2035 | * preview_set_format - Handle set format by pads subdev method | 2035 | * preview_set_format - Handle set format by pads subdev method |
2036 | * @sd : pointer to v4l2 subdev structure | 2036 | * @sd : pointer to v4l2 subdev structure |
2037 | * @fh : V4L2 subdev file handle | 2037 | * @cfg: V4L2 subdev pad configuration |
2038 | * @fmt: pointer to v4l2 subdev format structure | 2038 | * @fmt: pointer to v4l2 subdev format structure |
2039 | * return -EINVAL or zero on success | 2039 | * return -EINVAL or zero on success |
2040 | */ | 2040 | */ |
2041 | static int preview_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | 2041 | static int preview_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, |
2042 | struct v4l2_subdev_format *fmt) | 2042 | struct v4l2_subdev_format *fmt) |
2043 | { | 2043 | { |
2044 | struct isp_prev_device *prev = v4l2_get_subdevdata(sd); | 2044 | struct isp_prev_device *prev = v4l2_get_subdevdata(sd); |
2045 | struct v4l2_mbus_framefmt *format; | 2045 | struct v4l2_mbus_framefmt *format; |
2046 | struct v4l2_rect *crop; | 2046 | struct v4l2_rect *crop; |
2047 | 2047 | ||
2048 | format = __preview_get_format(prev, fh, fmt->pad, fmt->which); | 2048 | format = __preview_get_format(prev, cfg, fmt->pad, fmt->which); |
2049 | if (format == NULL) | 2049 | if (format == NULL) |
2050 | return -EINVAL; | 2050 | return -EINVAL; |
2051 | 2051 | ||
2052 | preview_try_format(prev, fh, fmt->pad, &fmt->format, fmt->which); | 2052 | preview_try_format(prev, cfg, fmt->pad, &fmt->format, fmt->which); |
2053 | *format = fmt->format; | 2053 | *format = fmt->format; |
2054 | 2054 | ||
2055 | /* Propagate the format from sink to source */ | 2055 | /* Propagate the format from sink to source */ |
2056 | if (fmt->pad == PREV_PAD_SINK) { | 2056 | if (fmt->pad == PREV_PAD_SINK) { |
2057 | /* Reset the crop rectangle. */ | 2057 | /* Reset the crop rectangle. */ |
2058 | crop = __preview_get_crop(prev, fh, fmt->which); | 2058 | crop = __preview_get_crop(prev, cfg, fmt->which); |
2059 | crop->left = 0; | 2059 | crop->left = 0; |
2060 | crop->top = 0; | 2060 | crop->top = 0; |
2061 | crop->width = fmt->format.width; | 2061 | crop->width = fmt->format.width; |
@@ -2064,9 +2064,9 @@ static int preview_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
2064 | preview_try_crop(prev, &fmt->format, crop); | 2064 | preview_try_crop(prev, &fmt->format, crop); |
2065 | 2065 | ||
2066 | /* Update the source format. */ | 2066 | /* Update the source format. */ |
2067 | format = __preview_get_format(prev, fh, PREV_PAD_SOURCE, | 2067 | format = __preview_get_format(prev, cfg, PREV_PAD_SOURCE, |
2068 | fmt->which); | 2068 | fmt->which); |
2069 | preview_try_format(prev, fh, PREV_PAD_SOURCE, format, | 2069 | preview_try_format(prev, cfg, PREV_PAD_SOURCE, format, |
2070 | fmt->which); | 2070 | fmt->which); |
2071 | } | 2071 | } |
2072 | 2072 | ||
@@ -2093,7 +2093,7 @@ static int preview_init_formats(struct v4l2_subdev *sd, | |||
2093 | format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10; | 2093 | format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10; |
2094 | format.format.width = 4096; | 2094 | format.format.width = 4096; |
2095 | format.format.height = 4096; | 2095 | format.format.height = 4096; |
2096 | preview_set_format(sd, fh, &format); | 2096 | preview_set_format(sd, fh ? fh->pad : NULL, &format); |
2097 | 2097 | ||
2098 | return 0; | 2098 | return 0; |
2099 | } | 2099 | } |
diff --git a/drivers/media/platform/omap3isp/ispresizer.c b/drivers/media/platform/omap3isp/ispresizer.c index 2b9bc4839876..7cfb43dc0ffd 100644 --- a/drivers/media/platform/omap3isp/ispresizer.c +++ b/drivers/media/platform/omap3isp/ispresizer.c | |||
@@ -112,16 +112,16 @@ static const struct isprsz_coef filter_coefs = { | |||
112 | * __resizer_get_format - helper function for getting resizer format | 112 | * __resizer_get_format - helper function for getting resizer format |
113 | * @res : pointer to resizer private structure | 113 | * @res : pointer to resizer private structure |
114 | * @pad : pad number | 114 | * @pad : pad number |
115 | * @fh : V4L2 subdev file handle | 115 | * @cfg: V4L2 subdev pad configuration |
116 | * @which : wanted subdev format | 116 | * @which : wanted subdev format |
117 | * return zero | 117 | * return zero |
118 | */ | 118 | */ |
119 | static struct v4l2_mbus_framefmt * | 119 | static struct v4l2_mbus_framefmt * |
120 | __resizer_get_format(struct isp_res_device *res, struct v4l2_subdev_fh *fh, | 120 | __resizer_get_format(struct isp_res_device *res, struct v4l2_subdev_pad_config *cfg, |
121 | unsigned int pad, enum v4l2_subdev_format_whence which) | 121 | unsigned int pad, enum v4l2_subdev_format_whence which) |
122 | { | 122 | { |
123 | if (which == V4L2_SUBDEV_FORMAT_TRY) | 123 | if (which == V4L2_SUBDEV_FORMAT_TRY) |
124 | return v4l2_subdev_get_try_format(fh, pad); | 124 | return v4l2_subdev_get_try_format(&res->subdev, cfg, pad); |
125 | else | 125 | else |
126 | return &res->formats[pad]; | 126 | return &res->formats[pad]; |
127 | } | 127 | } |
@@ -129,15 +129,15 @@ __resizer_get_format(struct isp_res_device *res, struct v4l2_subdev_fh *fh, | |||
129 | /* | 129 | /* |
130 | * __resizer_get_crop - helper function for getting resizer crop rectangle | 130 | * __resizer_get_crop - helper function for getting resizer crop rectangle |
131 | * @res : pointer to resizer private structure | 131 | * @res : pointer to resizer private structure |
132 | * @fh : V4L2 subdev file handle | 132 | * @cfg: V4L2 subdev pad configuration |
133 | * @which : wanted subdev crop rectangle | 133 | * @which : wanted subdev crop rectangle |
134 | */ | 134 | */ |
135 | static struct v4l2_rect * | 135 | static struct v4l2_rect * |
136 | __resizer_get_crop(struct isp_res_device *res, struct v4l2_subdev_fh *fh, | 136 | __resizer_get_crop(struct isp_res_device *res, struct v4l2_subdev_pad_config *cfg, |
137 | enum v4l2_subdev_format_whence which) | 137 | enum v4l2_subdev_format_whence which) |
138 | { | 138 | { |
139 | if (which == V4L2_SUBDEV_FORMAT_TRY) | 139 | if (which == V4L2_SUBDEV_FORMAT_TRY) |
140 | return v4l2_subdev_get_try_crop(fh, RESZ_PAD_SINK); | 140 | return v4l2_subdev_get_try_crop(&res->subdev, cfg, RESZ_PAD_SINK); |
141 | else | 141 | else |
142 | return &res->crop.request; | 142 | return &res->crop.request; |
143 | } | 143 | } |
@@ -1215,7 +1215,7 @@ static void resizer_try_crop(const struct v4l2_mbus_framefmt *sink, | |||
1215 | /* | 1215 | /* |
1216 | * resizer_get_selection - Retrieve a selection rectangle on a pad | 1216 | * resizer_get_selection - Retrieve a selection rectangle on a pad |
1217 | * @sd: ISP resizer V4L2 subdevice | 1217 | * @sd: ISP resizer V4L2 subdevice |
1218 | * @fh: V4L2 subdev file handle | 1218 | * @cfg: V4L2 subdev pad configuration |
1219 | * @sel: Selection rectangle | 1219 | * @sel: Selection rectangle |
1220 | * | 1220 | * |
1221 | * The only supported rectangles are the crop rectangles on the sink pad. | 1221 | * The only supported rectangles are the crop rectangles on the sink pad. |
@@ -1223,7 +1223,7 @@ static void resizer_try_crop(const struct v4l2_mbus_framefmt *sink, | |||
1223 | * Return 0 on success or a negative error code otherwise. | 1223 | * Return 0 on success or a negative error code otherwise. |
1224 | */ | 1224 | */ |
1225 | static int resizer_get_selection(struct v4l2_subdev *sd, | 1225 | static int resizer_get_selection(struct v4l2_subdev *sd, |
1226 | struct v4l2_subdev_fh *fh, | 1226 | struct v4l2_subdev_pad_config *cfg, |
1227 | struct v4l2_subdev_selection *sel) | 1227 | struct v4l2_subdev_selection *sel) |
1228 | { | 1228 | { |
1229 | struct isp_res_device *res = v4l2_get_subdevdata(sd); | 1229 | struct isp_res_device *res = v4l2_get_subdevdata(sd); |
@@ -1234,9 +1234,9 @@ static int resizer_get_selection(struct v4l2_subdev *sd, | |||
1234 | if (sel->pad != RESZ_PAD_SINK) | 1234 | if (sel->pad != RESZ_PAD_SINK) |
1235 | return -EINVAL; | 1235 | return -EINVAL; |
1236 | 1236 | ||
1237 | format_sink = __resizer_get_format(res, fh, RESZ_PAD_SINK, | 1237 | format_sink = __resizer_get_format(res, cfg, RESZ_PAD_SINK, |
1238 | sel->which); | 1238 | sel->which); |
1239 | format_source = __resizer_get_format(res, fh, RESZ_PAD_SOURCE, | 1239 | format_source = __resizer_get_format(res, cfg, RESZ_PAD_SOURCE, |
1240 | sel->which); | 1240 | sel->which); |
1241 | 1241 | ||
1242 | switch (sel->target) { | 1242 | switch (sel->target) { |
@@ -1251,7 +1251,7 @@ static int resizer_get_selection(struct v4l2_subdev *sd, | |||
1251 | break; | 1251 | break; |
1252 | 1252 | ||
1253 | case V4L2_SEL_TGT_CROP: | 1253 | case V4L2_SEL_TGT_CROP: |
1254 | sel->r = *__resizer_get_crop(res, fh, sel->which); | 1254 | sel->r = *__resizer_get_crop(res, cfg, sel->which); |
1255 | resizer_calc_ratios(res, &sel->r, format_source, &ratio); | 1255 | resizer_calc_ratios(res, &sel->r, format_source, &ratio); |
1256 | break; | 1256 | break; |
1257 | 1257 | ||
@@ -1265,7 +1265,7 @@ static int resizer_get_selection(struct v4l2_subdev *sd, | |||
1265 | /* | 1265 | /* |
1266 | * resizer_set_selection - Set a selection rectangle on a pad | 1266 | * resizer_set_selection - Set a selection rectangle on a pad |
1267 | * @sd: ISP resizer V4L2 subdevice | 1267 | * @sd: ISP resizer V4L2 subdevice |
1268 | * @fh: V4L2 subdev file handle | 1268 | * @cfg: V4L2 subdev pad configuration |
1269 | * @sel: Selection rectangle | 1269 | * @sel: Selection rectangle |
1270 | * | 1270 | * |
1271 | * The only supported rectangle is the actual crop rectangle on the sink pad. | 1271 | * The only supported rectangle is the actual crop rectangle on the sink pad. |
@@ -1276,7 +1276,7 @@ static int resizer_get_selection(struct v4l2_subdev *sd, | |||
1276 | * Return 0 on success or a negative error code otherwise. | 1276 | * Return 0 on success or a negative error code otherwise. |
1277 | */ | 1277 | */ |
1278 | static int resizer_set_selection(struct v4l2_subdev *sd, | 1278 | static int resizer_set_selection(struct v4l2_subdev *sd, |
1279 | struct v4l2_subdev_fh *fh, | 1279 | struct v4l2_subdev_pad_config *cfg, |
1280 | struct v4l2_subdev_selection *sel) | 1280 | struct v4l2_subdev_selection *sel) |
1281 | { | 1281 | { |
1282 | struct isp_res_device *res = v4l2_get_subdevdata(sd); | 1282 | struct isp_res_device *res = v4l2_get_subdevdata(sd); |
@@ -1290,9 +1290,9 @@ static int resizer_set_selection(struct v4l2_subdev *sd, | |||
1290 | sel->pad != RESZ_PAD_SINK) | 1290 | sel->pad != RESZ_PAD_SINK) |
1291 | return -EINVAL; | 1291 | return -EINVAL; |
1292 | 1292 | ||
1293 | format_sink = __resizer_get_format(res, fh, RESZ_PAD_SINK, | 1293 | format_sink = __resizer_get_format(res, cfg, RESZ_PAD_SINK, |
1294 | sel->which); | 1294 | sel->which); |
1295 | format_source = *__resizer_get_format(res, fh, RESZ_PAD_SOURCE, | 1295 | format_source = *__resizer_get_format(res, cfg, RESZ_PAD_SOURCE, |
1296 | sel->which); | 1296 | sel->which); |
1297 | 1297 | ||
1298 | dev_dbg(isp->dev, "%s(%s): req %ux%u -> (%d,%d)/%ux%u -> %ux%u\n", | 1298 | dev_dbg(isp->dev, "%s(%s): req %ux%u -> (%d,%d)/%ux%u -> %ux%u\n", |
@@ -1310,7 +1310,7 @@ static int resizer_set_selection(struct v4l2_subdev *sd, | |||
1310 | * stored the mangled rectangle. | 1310 | * stored the mangled rectangle. |
1311 | */ | 1311 | */ |
1312 | resizer_try_crop(format_sink, &format_source, &sel->r); | 1312 | resizer_try_crop(format_sink, &format_source, &sel->r); |
1313 | *__resizer_get_crop(res, fh, sel->which) = sel->r; | 1313 | *__resizer_get_crop(res, cfg, sel->which) = sel->r; |
1314 | resizer_calc_ratios(res, &sel->r, &format_source, &ratio); | 1314 | resizer_calc_ratios(res, &sel->r, &format_source, &ratio); |
1315 | 1315 | ||
1316 | dev_dbg(isp->dev, "%s(%s): got %ux%u -> (%d,%d)/%ux%u -> %ux%u\n", | 1316 | dev_dbg(isp->dev, "%s(%s): got %ux%u -> (%d,%d)/%ux%u -> %ux%u\n", |
@@ -1320,7 +1320,7 @@ static int resizer_set_selection(struct v4l2_subdev *sd, | |||
1320 | format_source.width, format_source.height); | 1320 | format_source.width, format_source.height); |
1321 | 1321 | ||
1322 | if (sel->which == V4L2_SUBDEV_FORMAT_TRY) { | 1322 | if (sel->which == V4L2_SUBDEV_FORMAT_TRY) { |
1323 | *__resizer_get_format(res, fh, RESZ_PAD_SOURCE, sel->which) = | 1323 | *__resizer_get_format(res, cfg, RESZ_PAD_SOURCE, sel->which) = |
1324 | format_source; | 1324 | format_source; |
1325 | return 0; | 1325 | return 0; |
1326 | } | 1326 | } |
@@ -1331,7 +1331,7 @@ static int resizer_set_selection(struct v4l2_subdev *sd, | |||
1331 | */ | 1331 | */ |
1332 | spin_lock_irqsave(&res->lock, flags); | 1332 | spin_lock_irqsave(&res->lock, flags); |
1333 | 1333 | ||
1334 | *__resizer_get_format(res, fh, RESZ_PAD_SOURCE, sel->which) = | 1334 | *__resizer_get_format(res, cfg, RESZ_PAD_SOURCE, sel->which) = |
1335 | format_source; | 1335 | format_source; |
1336 | 1336 | ||
1337 | res->ratio = ratio; | 1337 | res->ratio = ratio; |
@@ -1368,13 +1368,13 @@ static unsigned int resizer_max_in_width(struct isp_res_device *res) | |||
1368 | /* | 1368 | /* |
1369 | * resizer_try_format - Handle try format by pad subdev method | 1369 | * resizer_try_format - Handle try format by pad subdev method |
1370 | * @res : ISP resizer device | 1370 | * @res : ISP resizer device |
1371 | * @fh : V4L2 subdev file handle | 1371 | * @cfg: V4L2 subdev pad configuration |
1372 | * @pad : pad num | 1372 | * @pad : pad num |
1373 | * @fmt : pointer to v4l2 format structure | 1373 | * @fmt : pointer to v4l2 format structure |
1374 | * @which : wanted subdev format | 1374 | * @which : wanted subdev format |
1375 | */ | 1375 | */ |
1376 | static void resizer_try_format(struct isp_res_device *res, | 1376 | static void resizer_try_format(struct isp_res_device *res, |
1377 | struct v4l2_subdev_fh *fh, unsigned int pad, | 1377 | struct v4l2_subdev_pad_config *cfg, unsigned int pad, |
1378 | struct v4l2_mbus_framefmt *fmt, | 1378 | struct v4l2_mbus_framefmt *fmt, |
1379 | enum v4l2_subdev_format_whence which) | 1379 | enum v4l2_subdev_format_whence which) |
1380 | { | 1380 | { |
@@ -1395,10 +1395,10 @@ static void resizer_try_format(struct isp_res_device *res, | |||
1395 | break; | 1395 | break; |
1396 | 1396 | ||
1397 | case RESZ_PAD_SOURCE: | 1397 | case RESZ_PAD_SOURCE: |
1398 | format = __resizer_get_format(res, fh, RESZ_PAD_SINK, which); | 1398 | format = __resizer_get_format(res, cfg, RESZ_PAD_SINK, which); |
1399 | fmt->code = format->code; | 1399 | fmt->code = format->code; |
1400 | 1400 | ||
1401 | crop = *__resizer_get_crop(res, fh, which); | 1401 | crop = *__resizer_get_crop(res, cfg, which); |
1402 | resizer_calc_ratios(res, &crop, fmt, &ratio); | 1402 | resizer_calc_ratios(res, &crop, fmt, &ratio); |
1403 | break; | 1403 | break; |
1404 | } | 1404 | } |
@@ -1410,12 +1410,12 @@ static void resizer_try_format(struct isp_res_device *res, | |||
1410 | /* | 1410 | /* |
1411 | * resizer_enum_mbus_code - Handle pixel format enumeration | 1411 | * resizer_enum_mbus_code - Handle pixel format enumeration |
1412 | * @sd : pointer to v4l2 subdev structure | 1412 | * @sd : pointer to v4l2 subdev structure |
1413 | * @fh : V4L2 subdev file handle | 1413 | * @cfg: V4L2 subdev pad configuration |
1414 | * @code : pointer to v4l2_subdev_mbus_code_enum structure | 1414 | * @code : pointer to v4l2_subdev_mbus_code_enum structure |
1415 | * return -EINVAL or zero on success | 1415 | * return -EINVAL or zero on success |
1416 | */ | 1416 | */ |
1417 | static int resizer_enum_mbus_code(struct v4l2_subdev *sd, | 1417 | static int resizer_enum_mbus_code(struct v4l2_subdev *sd, |
1418 | struct v4l2_subdev_fh *fh, | 1418 | struct v4l2_subdev_pad_config *cfg, |
1419 | struct v4l2_subdev_mbus_code_enum *code) | 1419 | struct v4l2_subdev_mbus_code_enum *code) |
1420 | { | 1420 | { |
1421 | struct isp_res_device *res = v4l2_get_subdevdata(sd); | 1421 | struct isp_res_device *res = v4l2_get_subdevdata(sd); |
@@ -1430,8 +1430,8 @@ static int resizer_enum_mbus_code(struct v4l2_subdev *sd, | |||
1430 | if (code->index != 0) | 1430 | if (code->index != 0) |
1431 | return -EINVAL; | 1431 | return -EINVAL; |
1432 | 1432 | ||
1433 | format = __resizer_get_format(res, fh, RESZ_PAD_SINK, | 1433 | format = __resizer_get_format(res, cfg, RESZ_PAD_SINK, |
1434 | V4L2_SUBDEV_FORMAT_TRY); | 1434 | code->which); |
1435 | code->code = format->code; | 1435 | code->code = format->code; |
1436 | } | 1436 | } |
1437 | 1437 | ||
@@ -1439,7 +1439,7 @@ static int resizer_enum_mbus_code(struct v4l2_subdev *sd, | |||
1439 | } | 1439 | } |
1440 | 1440 | ||
1441 | static int resizer_enum_frame_size(struct v4l2_subdev *sd, | 1441 | static int resizer_enum_frame_size(struct v4l2_subdev *sd, |
1442 | struct v4l2_subdev_fh *fh, | 1442 | struct v4l2_subdev_pad_config *cfg, |
1443 | struct v4l2_subdev_frame_size_enum *fse) | 1443 | struct v4l2_subdev_frame_size_enum *fse) |
1444 | { | 1444 | { |
1445 | struct isp_res_device *res = v4l2_get_subdevdata(sd); | 1445 | struct isp_res_device *res = v4l2_get_subdevdata(sd); |
@@ -1451,7 +1451,7 @@ static int resizer_enum_frame_size(struct v4l2_subdev *sd, | |||
1451 | format.code = fse->code; | 1451 | format.code = fse->code; |
1452 | format.width = 1; | 1452 | format.width = 1; |
1453 | format.height = 1; | 1453 | format.height = 1; |
1454 | resizer_try_format(res, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY); | 1454 | resizer_try_format(res, cfg, fse->pad, &format, fse->which); |
1455 | fse->min_width = format.width; | 1455 | fse->min_width = format.width; |
1456 | fse->min_height = format.height; | 1456 | fse->min_height = format.height; |
1457 | 1457 | ||
@@ -1461,7 +1461,7 @@ static int resizer_enum_frame_size(struct v4l2_subdev *sd, | |||
1461 | format.code = fse->code; | 1461 | format.code = fse->code; |
1462 | format.width = -1; | 1462 | format.width = -1; |
1463 | format.height = -1; | 1463 | format.height = -1; |
1464 | resizer_try_format(res, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY); | 1464 | resizer_try_format(res, cfg, fse->pad, &format, fse->which); |
1465 | fse->max_width = format.width; | 1465 | fse->max_width = format.width; |
1466 | fse->max_height = format.height; | 1466 | fse->max_height = format.height; |
1467 | 1467 | ||
@@ -1471,17 +1471,17 @@ static int resizer_enum_frame_size(struct v4l2_subdev *sd, | |||
1471 | /* | 1471 | /* |
1472 | * resizer_get_format - Handle get format by pads subdev method | 1472 | * resizer_get_format - Handle get format by pads subdev method |
1473 | * @sd : pointer to v4l2 subdev structure | 1473 | * @sd : pointer to v4l2 subdev structure |
1474 | * @fh : V4L2 subdev file handle | 1474 | * @cfg: V4L2 subdev pad configuration |
1475 | * @fmt : pointer to v4l2 subdev format structure | 1475 | * @fmt : pointer to v4l2 subdev format structure |
1476 | * return -EINVAL or zero on success | 1476 | * return -EINVAL or zero on success |
1477 | */ | 1477 | */ |
1478 | static int resizer_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | 1478 | static int resizer_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, |
1479 | struct v4l2_subdev_format *fmt) | 1479 | struct v4l2_subdev_format *fmt) |
1480 | { | 1480 | { |
1481 | struct isp_res_device *res = v4l2_get_subdevdata(sd); | 1481 | struct isp_res_device *res = v4l2_get_subdevdata(sd); |
1482 | struct v4l2_mbus_framefmt *format; | 1482 | struct v4l2_mbus_framefmt *format; |
1483 | 1483 | ||
1484 | format = __resizer_get_format(res, fh, fmt->pad, fmt->which); | 1484 | format = __resizer_get_format(res, cfg, fmt->pad, fmt->which); |
1485 | if (format == NULL) | 1485 | if (format == NULL) |
1486 | return -EINVAL; | 1486 | return -EINVAL; |
1487 | 1487 | ||
@@ -1492,37 +1492,37 @@ static int resizer_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
1492 | /* | 1492 | /* |
1493 | * resizer_set_format - Handle set format by pads subdev method | 1493 | * resizer_set_format - Handle set format by pads subdev method |
1494 | * @sd : pointer to v4l2 subdev structure | 1494 | * @sd : pointer to v4l2 subdev structure |
1495 | * @fh : V4L2 subdev file handle | 1495 | * @cfg: V4L2 subdev pad configuration |
1496 | * @fmt : pointer to v4l2 subdev format structure | 1496 | * @fmt : pointer to v4l2 subdev format structure |
1497 | * return -EINVAL or zero on success | 1497 | * return -EINVAL or zero on success |
1498 | */ | 1498 | */ |
1499 | static int resizer_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | 1499 | static int resizer_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, |
1500 | struct v4l2_subdev_format *fmt) | 1500 | struct v4l2_subdev_format *fmt) |
1501 | { | 1501 | { |
1502 | struct isp_res_device *res = v4l2_get_subdevdata(sd); | 1502 | struct isp_res_device *res = v4l2_get_subdevdata(sd); |
1503 | struct v4l2_mbus_framefmt *format; | 1503 | struct v4l2_mbus_framefmt *format; |
1504 | struct v4l2_rect *crop; | 1504 | struct v4l2_rect *crop; |
1505 | 1505 | ||
1506 | format = __resizer_get_format(res, fh, fmt->pad, fmt->which); | 1506 | format = __resizer_get_format(res, cfg, fmt->pad, fmt->which); |
1507 | if (format == NULL) | 1507 | if (format == NULL) |
1508 | return -EINVAL; | 1508 | return -EINVAL; |
1509 | 1509 | ||
1510 | resizer_try_format(res, fh, fmt->pad, &fmt->format, fmt->which); | 1510 | resizer_try_format(res, cfg, fmt->pad, &fmt->format, fmt->which); |
1511 | *format = fmt->format; | 1511 | *format = fmt->format; |
1512 | 1512 | ||
1513 | if (fmt->pad == RESZ_PAD_SINK) { | 1513 | if (fmt->pad == RESZ_PAD_SINK) { |
1514 | /* reset crop rectangle */ | 1514 | /* reset crop rectangle */ |
1515 | crop = __resizer_get_crop(res, fh, fmt->which); | 1515 | crop = __resizer_get_crop(res, cfg, fmt->which); |
1516 | crop->left = 0; | 1516 | crop->left = 0; |
1517 | crop->top = 0; | 1517 | crop->top = 0; |
1518 | crop->width = fmt->format.width; | 1518 | crop->width = fmt->format.width; |
1519 | crop->height = fmt->format.height; | 1519 | crop->height = fmt->format.height; |
1520 | 1520 | ||
1521 | /* Propagate the format from sink to source */ | 1521 | /* Propagate the format from sink to source */ |
1522 | format = __resizer_get_format(res, fh, RESZ_PAD_SOURCE, | 1522 | format = __resizer_get_format(res, cfg, RESZ_PAD_SOURCE, |
1523 | fmt->which); | 1523 | fmt->which); |
1524 | *format = fmt->format; | 1524 | *format = fmt->format; |
1525 | resizer_try_format(res, fh, RESZ_PAD_SOURCE, format, | 1525 | resizer_try_format(res, cfg, RESZ_PAD_SOURCE, format, |
1526 | fmt->which); | 1526 | fmt->which); |
1527 | } | 1527 | } |
1528 | 1528 | ||
@@ -1573,7 +1573,7 @@ static int resizer_init_formats(struct v4l2_subdev *sd, | |||
1573 | format.format.code = MEDIA_BUS_FMT_YUYV8_1X16; | 1573 | format.format.code = MEDIA_BUS_FMT_YUYV8_1X16; |
1574 | format.format.width = 4096; | 1574 | format.format.width = 4096; |
1575 | format.format.height = 4096; | 1575 | format.format.height = 4096; |
1576 | resizer_set_format(sd, fh, &format); | 1576 | resizer_set_format(sd, fh ? fh->pad : NULL, &format); |
1577 | 1577 | ||
1578 | return 0; | 1578 | return 0; |
1579 | } | 1579 | } |
diff --git a/drivers/media/platform/omap3isp/ispstat.c b/drivers/media/platform/omap3isp/ispstat.c index a94e8340508f..20434e83e801 100644 --- a/drivers/media/platform/omap3isp/ispstat.c +++ b/drivers/media/platform/omap3isp/ispstat.c | |||
@@ -21,7 +21,7 @@ | |||
21 | 21 | ||
22 | #include "isp.h" | 22 | #include "isp.h" |
23 | 23 | ||
24 | #define ISP_STAT_USES_DMAENGINE(stat) ((stat)->dma_ch >= 0) | 24 | #define ISP_STAT_USES_DMAENGINE(stat) ((stat)->dma_ch != NULL) |
25 | 25 | ||
26 | /* | 26 | /* |
27 | * MAGIC_SIZE must always be the greatest common divisor of | 27 | * MAGIC_SIZE must always be the greatest common divisor of |
diff --git a/drivers/media/platform/omap3isp/ispstat.h b/drivers/media/platform/omap3isp/ispstat.h index b32b29677e2c..b79380d83fcf 100644 --- a/drivers/media/platform/omap3isp/ispstat.h +++ b/drivers/media/platform/omap3isp/ispstat.h | |||
@@ -20,7 +20,6 @@ | |||
20 | 20 | ||
21 | #include <linux/types.h> | 21 | #include <linux/types.h> |
22 | #include <linux/omap3isp.h> | 22 | #include <linux/omap3isp.h> |
23 | #include <linux/omap-dma.h> | ||
24 | #include <media/v4l2-event.h> | 23 | #include <media/v4l2-event.h> |
25 | 24 | ||
26 | #include "isp.h" | 25 | #include "isp.h" |
@@ -33,6 +32,7 @@ | |||
33 | #define STAT_NO_BUF 1 /* An error has occurred */ | 32 | #define STAT_NO_BUF 1 /* An error has occurred */ |
34 | #define STAT_BUF_WAITING_DMA 2 /* Histogram only: DMA is running */ | 33 | #define STAT_BUF_WAITING_DMA 2 /* Histogram only: DMA is running */ |
35 | 34 | ||
35 | struct dma_chan; | ||
36 | struct ispstat; | 36 | struct ispstat; |
37 | 37 | ||
38 | struct ispstat_buffer { | 38 | struct ispstat_buffer { |
@@ -96,7 +96,6 @@ struct ispstat { | |||
96 | u8 inc_config; | 96 | u8 inc_config; |
97 | atomic_t buf_err; | 97 | atomic_t buf_err; |
98 | enum ispstat_state_t state; /* enabling/disabling state */ | 98 | enum ispstat_state_t state; /* enabling/disabling state */ |
99 | struct omap_dma_channel_params dma_config; | ||
100 | struct isp_device *isp; | 99 | struct isp_device *isp; |
101 | void *priv; /* pointer to priv config struct */ | 100 | void *priv; /* pointer to priv config struct */ |
102 | void *recover_priv; /* pointer to recover priv configuration */ | 101 | void *recover_priv; /* pointer to recover priv configuration */ |
@@ -110,7 +109,7 @@ struct ispstat { | |||
110 | u32 frame_number; | 109 | u32 frame_number; |
111 | u32 buf_size; | 110 | u32 buf_size; |
112 | u32 buf_alloc_size; | 111 | u32 buf_alloc_size; |
113 | int dma_ch; | 112 | struct dma_chan *dma_ch; |
114 | unsigned long event_type; | 113 | unsigned long event_type; |
115 | struct ispstat_buffer *buf; | 114 | struct ispstat_buffer *buf; |
116 | struct ispstat_buffer *active_buf; | 115 | struct ispstat_buffer *active_buf; |
diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c index 3fe9047ef466..d285af18df7f 100644 --- a/drivers/media/platform/omap3isp/ispvideo.c +++ b/drivers/media/platform/omap3isp/ispvideo.c | |||
@@ -452,7 +452,6 @@ struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video) | |||
452 | enum isp_pipeline_state state; | 452 | enum isp_pipeline_state state; |
453 | struct isp_buffer *buf; | 453 | struct isp_buffer *buf; |
454 | unsigned long flags; | 454 | unsigned long flags; |
455 | struct timespec ts; | ||
456 | 455 | ||
457 | spin_lock_irqsave(&video->irqlock, flags); | 456 | spin_lock_irqsave(&video->irqlock, flags); |
458 | if (WARN_ON(list_empty(&video->dmaqueue))) { | 457 | if (WARN_ON(list_empty(&video->dmaqueue))) { |
@@ -465,9 +464,7 @@ struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video) | |||
465 | list_del(&buf->irqlist); | 464 | list_del(&buf->irqlist); |
466 | spin_unlock_irqrestore(&video->irqlock, flags); | 465 | spin_unlock_irqrestore(&video->irqlock, flags); |
467 | 466 | ||
468 | ktime_get_ts(&ts); | 467 | v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp); |
469 | buf->vb.v4l2_buf.timestamp.tv_sec = ts.tv_sec; | ||
470 | buf->vb.v4l2_buf.timestamp.tv_usec = ts.tv_nsec / NSEC_PER_USEC; | ||
471 | 468 | ||
472 | /* Do frame number propagation only if this is the output video node. | 469 | /* Do frame number propagation only if this is the output video node. |
473 | * Frame number either comes from the CSI receivers or it gets | 470 | * Frame number either comes from the CSI receivers or it gets |
@@ -524,7 +521,6 @@ struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video) | |||
524 | 521 | ||
525 | buf = list_first_entry(&video->dmaqueue, struct isp_buffer, | 522 | buf = list_first_entry(&video->dmaqueue, struct isp_buffer, |
526 | irqlist); | 523 | irqlist); |
527 | buf->vb.state = VB2_BUF_STATE_ACTIVE; | ||
528 | 524 | ||
529 | spin_unlock_irqrestore(&video->irqlock, flags); | 525 | spin_unlock_irqrestore(&video->irqlock, flags); |
530 | 526 | ||
@@ -1022,7 +1018,7 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) | |||
1022 | 1018 | ||
1023 | pipe->entities = 0; | 1019 | pipe->entities = 0; |
1024 | 1020 | ||
1025 | if (video->isp->pdata->set_constraints) | 1021 | if (video->isp->pdata && video->isp->pdata->set_constraints) |
1026 | video->isp->pdata->set_constraints(video->isp, true); | 1022 | video->isp->pdata->set_constraints(video->isp, true); |
1027 | pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]); | 1023 | pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]); |
1028 | pipe->max_rate = pipe->l3_ick; | 1024 | pipe->max_rate = pipe->l3_ick; |
@@ -1104,7 +1100,7 @@ err_set_stream: | |||
1104 | err_check_format: | 1100 | err_check_format: |
1105 | media_entity_pipeline_stop(&video->video.entity); | 1101 | media_entity_pipeline_stop(&video->video.entity); |
1106 | err_pipeline_start: | 1102 | err_pipeline_start: |
1107 | if (video->isp->pdata->set_constraints) | 1103 | if (video->isp->pdata && video->isp->pdata->set_constraints) |
1108 | video->isp->pdata->set_constraints(video->isp, false); | 1104 | video->isp->pdata->set_constraints(video->isp, false); |
1109 | /* The DMA queue must be emptied here, otherwise CCDC interrupts that | 1105 | /* The DMA queue must be emptied here, otherwise CCDC interrupts that |
1110 | * will get triggered the next time the CCDC is powered up will try to | 1106 | * will get triggered the next time the CCDC is powered up will try to |
@@ -1165,7 +1161,7 @@ isp_video_streamoff(struct file *file, void *fh, enum v4l2_buf_type type) | |||
1165 | video->queue = NULL; | 1161 | video->queue = NULL; |
1166 | video->error = false; | 1162 | video->error = false; |
1167 | 1163 | ||
1168 | if (video->isp->pdata->set_constraints) | 1164 | if (video->isp->pdata && video->isp->pdata->set_constraints) |
1169 | video->isp->pdata->set_constraints(video->isp, false); | 1165 | video->isp->pdata->set_constraints(video->isp, false); |
1170 | media_entity_pipeline_stop(&video->video.entity); | 1166 | media_entity_pipeline_stop(&video->video.entity); |
1171 | 1167 | ||
@@ -1326,14 +1322,8 @@ static unsigned int isp_video_poll(struct file *file, poll_table *wait) | |||
1326 | static int isp_video_mmap(struct file *file, struct vm_area_struct *vma) | 1322 | static int isp_video_mmap(struct file *file, struct vm_area_struct *vma) |
1327 | { | 1323 | { |
1328 | struct isp_video_fh *vfh = to_isp_video_fh(file->private_data); | 1324 | struct isp_video_fh *vfh = to_isp_video_fh(file->private_data); |
1329 | struct isp_video *video = video_drvdata(file); | ||
1330 | int ret; | ||
1331 | |||
1332 | mutex_lock(&video->queue_lock); | ||
1333 | ret = vb2_mmap(&vfh->queue, vma); | ||
1334 | mutex_unlock(&video->queue_lock); | ||
1335 | 1325 | ||
1336 | return ret; | 1326 | return vb2_mmap(&vfh->queue, vma); |
1337 | } | 1327 | } |
1338 | 1328 | ||
1339 | static struct v4l2_file_operations isp_video_fops = { | 1329 | static struct v4l2_file_operations isp_video_fops = { |
diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c index 54479d60cc0d..f6a61b9ceff4 100644 --- a/drivers/media/platform/s3c-camif/camif-capture.c +++ b/drivers/media/platform/s3c-camif/camif-capture.c | |||
@@ -1219,7 +1219,7 @@ static const u32 camif_mbus_formats[] = { | |||
1219 | */ | 1219 | */ |
1220 | 1220 | ||
1221 | static int s3c_camif_subdev_enum_mbus_code(struct v4l2_subdev *sd, | 1221 | static int s3c_camif_subdev_enum_mbus_code(struct v4l2_subdev *sd, |
1222 | struct v4l2_subdev_fh *fh, | 1222 | struct v4l2_subdev_pad_config *cfg, |
1223 | struct v4l2_subdev_mbus_code_enum *code) | 1223 | struct v4l2_subdev_mbus_code_enum *code) |
1224 | { | 1224 | { |
1225 | if (code->index >= ARRAY_SIZE(camif_mbus_formats)) | 1225 | if (code->index >= ARRAY_SIZE(camif_mbus_formats)) |
@@ -1230,14 +1230,14 @@ static int s3c_camif_subdev_enum_mbus_code(struct v4l2_subdev *sd, | |||
1230 | } | 1230 | } |
1231 | 1231 | ||
1232 | static int s3c_camif_subdev_get_fmt(struct v4l2_subdev *sd, | 1232 | static int s3c_camif_subdev_get_fmt(struct v4l2_subdev *sd, |
1233 | struct v4l2_subdev_fh *fh, | 1233 | struct v4l2_subdev_pad_config *cfg, |
1234 | struct v4l2_subdev_format *fmt) | 1234 | struct v4l2_subdev_format *fmt) |
1235 | { | 1235 | { |
1236 | struct camif_dev *camif = v4l2_get_subdevdata(sd); | 1236 | struct camif_dev *camif = v4l2_get_subdevdata(sd); |
1237 | struct v4l2_mbus_framefmt *mf = &fmt->format; | 1237 | struct v4l2_mbus_framefmt *mf = &fmt->format; |
1238 | 1238 | ||
1239 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { | 1239 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { |
1240 | mf = v4l2_subdev_get_try_format(fh, fmt->pad); | 1240 | mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); |
1241 | fmt->format = *mf; | 1241 | fmt->format = *mf; |
1242 | return 0; | 1242 | return 0; |
1243 | } | 1243 | } |
@@ -1297,7 +1297,7 @@ static void __camif_subdev_try_format(struct camif_dev *camif, | |||
1297 | } | 1297 | } |
1298 | 1298 | ||
1299 | static int s3c_camif_subdev_set_fmt(struct v4l2_subdev *sd, | 1299 | static int s3c_camif_subdev_set_fmt(struct v4l2_subdev *sd, |
1300 | struct v4l2_subdev_fh *fh, | 1300 | struct v4l2_subdev_pad_config *cfg, |
1301 | struct v4l2_subdev_format *fmt) | 1301 | struct v4l2_subdev_format *fmt) |
1302 | { | 1302 | { |
1303 | struct camif_dev *camif = v4l2_get_subdevdata(sd); | 1303 | struct camif_dev *camif = v4l2_get_subdevdata(sd); |
@@ -1325,7 +1325,7 @@ static int s3c_camif_subdev_set_fmt(struct v4l2_subdev *sd, | |||
1325 | __camif_subdev_try_format(camif, mf, fmt->pad); | 1325 | __camif_subdev_try_format(camif, mf, fmt->pad); |
1326 | 1326 | ||
1327 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { | 1327 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { |
1328 | mf = v4l2_subdev_get_try_format(fh, fmt->pad); | 1328 | mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); |
1329 | *mf = fmt->format; | 1329 | *mf = fmt->format; |
1330 | mutex_unlock(&camif->lock); | 1330 | mutex_unlock(&camif->lock); |
1331 | return 0; | 1331 | return 0; |
@@ -1364,7 +1364,7 @@ static int s3c_camif_subdev_set_fmt(struct v4l2_subdev *sd, | |||
1364 | } | 1364 | } |
1365 | 1365 | ||
1366 | static int s3c_camif_subdev_get_selection(struct v4l2_subdev *sd, | 1366 | static int s3c_camif_subdev_get_selection(struct v4l2_subdev *sd, |
1367 | struct v4l2_subdev_fh *fh, | 1367 | struct v4l2_subdev_pad_config *cfg, |
1368 | struct v4l2_subdev_selection *sel) | 1368 | struct v4l2_subdev_selection *sel) |
1369 | { | 1369 | { |
1370 | struct camif_dev *camif = v4l2_get_subdevdata(sd); | 1370 | struct camif_dev *camif = v4l2_get_subdevdata(sd); |
@@ -1377,7 +1377,7 @@ static int s3c_camif_subdev_get_selection(struct v4l2_subdev *sd, | |||
1377 | return -EINVAL; | 1377 | return -EINVAL; |
1378 | 1378 | ||
1379 | if (sel->which == V4L2_SUBDEV_FORMAT_TRY) { | 1379 | if (sel->which == V4L2_SUBDEV_FORMAT_TRY) { |
1380 | sel->r = *v4l2_subdev_get_try_crop(fh, sel->pad); | 1380 | sel->r = *v4l2_subdev_get_try_crop(sd, cfg, sel->pad); |
1381 | return 0; | 1381 | return 0; |
1382 | } | 1382 | } |
1383 | 1383 | ||
@@ -1451,7 +1451,7 @@ static void __camif_try_crop(struct camif_dev *camif, struct v4l2_rect *r) | |||
1451 | } | 1451 | } |
1452 | 1452 | ||
1453 | static int s3c_camif_subdev_set_selection(struct v4l2_subdev *sd, | 1453 | static int s3c_camif_subdev_set_selection(struct v4l2_subdev *sd, |
1454 | struct v4l2_subdev_fh *fh, | 1454 | struct v4l2_subdev_pad_config *cfg, |
1455 | struct v4l2_subdev_selection *sel) | 1455 | struct v4l2_subdev_selection *sel) |
1456 | { | 1456 | { |
1457 | struct camif_dev *camif = v4l2_get_subdevdata(sd); | 1457 | struct camif_dev *camif = v4l2_get_subdevdata(sd); |
@@ -1465,7 +1465,7 @@ static int s3c_camif_subdev_set_selection(struct v4l2_subdev *sd, | |||
1465 | __camif_try_crop(camif, &sel->r); | 1465 | __camif_try_crop(camif, &sel->r); |
1466 | 1466 | ||
1467 | if (sel->which == V4L2_SUBDEV_FORMAT_TRY) { | 1467 | if (sel->which == V4L2_SUBDEV_FORMAT_TRY) { |
1468 | *v4l2_subdev_get_try_crop(fh, sel->pad) = sel->r; | 1468 | *v4l2_subdev_get_try_crop(sd, cfg, sel->pad) = sel->r; |
1469 | } else { | 1469 | } else { |
1470 | unsigned long flags; | 1470 | unsigned long flags; |
1471 | unsigned int i; | 1471 | unsigned int i; |
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index a92ff4249d10..bfbf1575677c 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c | |||
@@ -621,6 +621,7 @@ static int s5p_jpeg_to_user_subsampling(struct s5p_jpeg_ctx *ctx) | |||
621 | return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY; | 621 | return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY; |
622 | return ctx->subsampling; | 622 | return ctx->subsampling; |
623 | case SJPEG_EXYNOS3250: | 623 | case SJPEG_EXYNOS3250: |
624 | case SJPEG_EXYNOS5420: | ||
624 | if (ctx->subsampling > 3) | 625 | if (ctx->subsampling > 3) |
625 | return V4L2_JPEG_CHROMA_SUBSAMPLING_411; | 626 | return V4L2_JPEG_CHROMA_SUBSAMPLING_411; |
626 | return exynos3250_decoded_subsampling[ctx->subsampling]; | 627 | return exynos3250_decoded_subsampling[ctx->subsampling]; |
@@ -1142,13 +1143,13 @@ static void jpeg_bound_align_image(struct s5p_jpeg_ctx *ctx, | |||
1142 | w_step = 1 << walign; | 1143 | w_step = 1 << walign; |
1143 | h_step = 1 << halign; | 1144 | h_step = 1 << halign; |
1144 | 1145 | ||
1145 | if (ctx->jpeg->variant->version == SJPEG_EXYNOS3250) { | 1146 | if (ctx->jpeg->variant->hw3250_compat) { |
1146 | /* | 1147 | /* |
1147 | * Rightmost and bottommost pixels are cropped by the | 1148 | * Rightmost and bottommost pixels are cropped by the |
1148 | * Exynos3250 JPEG IP for RGB formats, for the specific | 1149 | * Exynos3250/compatible JPEG IP for RGB formats, for the |
1149 | * width and height values respectively. This assignment | 1150 | * specific width and height values respectively. This |
1150 | * will result in v4l_bound_align_image returning dimensions | 1151 | * assignment will result in v4l_bound_align_image returning |
1151 | * reduced by 1 for the aforementioned cases. | 1152 | * dimensions reduced by 1 for the aforementioned cases. |
1152 | */ | 1153 | */ |
1153 | if (w_step == 4 && ((width & 3) == 1)) { | 1154 | if (w_step == 4 && ((width & 3) == 1)) { |
1154 | wmax = width; | 1155 | wmax = width; |
@@ -1384,12 +1385,12 @@ static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f) | |||
1384 | 1385 | ||
1385 | /* | 1386 | /* |
1386 | * Prevent downscaling to YUV420 format by more than 2 | 1387 | * Prevent downscaling to YUV420 format by more than 2 |
1387 | * for Exynos3250 SoC as it produces broken raw image | 1388 | * for Exynos3250/compatible SoC as it produces broken raw image |
1388 | * in such cases. | 1389 | * in such cases. |
1389 | */ | 1390 | */ |
1390 | if (ct->mode == S5P_JPEG_DECODE && | 1391 | if (ct->mode == S5P_JPEG_DECODE && |
1391 | f_type == FMT_TYPE_CAPTURE && | 1392 | f_type == FMT_TYPE_CAPTURE && |
1392 | ct->jpeg->variant->version == SJPEG_EXYNOS3250 && | 1393 | ct->jpeg->variant->hw3250_compat && |
1393 | pix->pixelformat == V4L2_PIX_FMT_YUV420 && | 1394 | pix->pixelformat == V4L2_PIX_FMT_YUV420 && |
1394 | ct->scale_factor > 2) { | 1395 | ct->scale_factor > 2) { |
1395 | scale_rect.width = ct->out_q.w / 2; | 1396 | scale_rect.width = ct->out_q.w / 2; |
@@ -1569,12 +1570,12 @@ static int s5p_jpeg_s_selection(struct file *file, void *fh, | |||
1569 | if (s->target == V4L2_SEL_TGT_COMPOSE) { | 1570 | if (s->target == V4L2_SEL_TGT_COMPOSE) { |
1570 | if (ctx->mode != S5P_JPEG_DECODE) | 1571 | if (ctx->mode != S5P_JPEG_DECODE) |
1571 | return -EINVAL; | 1572 | return -EINVAL; |
1572 | if (ctx->jpeg->variant->version == SJPEG_EXYNOS3250) | 1573 | if (ctx->jpeg->variant->hw3250_compat) |
1573 | ret = exynos3250_jpeg_try_downscale(ctx, rect); | 1574 | ret = exynos3250_jpeg_try_downscale(ctx, rect); |
1574 | } else if (s->target == V4L2_SEL_TGT_CROP) { | 1575 | } else if (s->target == V4L2_SEL_TGT_CROP) { |
1575 | if (ctx->mode != S5P_JPEG_ENCODE) | 1576 | if (ctx->mode != S5P_JPEG_ENCODE) |
1576 | return -EINVAL; | 1577 | return -EINVAL; |
1577 | if (ctx->jpeg->variant->version == SJPEG_EXYNOS3250) | 1578 | if (ctx->jpeg->variant->hw3250_compat) |
1578 | ret = exynos3250_jpeg_try_crop(ctx, rect); | 1579 | ret = exynos3250_jpeg_try_crop(ctx, rect); |
1579 | } | 1580 | } |
1580 | 1581 | ||
@@ -1604,8 +1605,9 @@ static int s5p_jpeg_adjust_subs_ctrl(struct s5p_jpeg_ctx *ctx, int *ctrl_val) | |||
1604 | case SJPEG_S5P: | 1605 | case SJPEG_S5P: |
1605 | return 0; | 1606 | return 0; |
1606 | case SJPEG_EXYNOS3250: | 1607 | case SJPEG_EXYNOS3250: |
1608 | case SJPEG_EXYNOS5420: | ||
1607 | /* | 1609 | /* |
1608 | * The exynos3250 device can produce JPEG image only | 1610 | * The exynos3250/compatible device can produce JPEG image only |
1609 | * of 4:4:4 subsampling when given RGB32 source image. | 1611 | * of 4:4:4 subsampling when given RGB32 source image. |
1610 | */ | 1612 | */ |
1611 | if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB32) | 1613 | if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB32) |
@@ -1624,7 +1626,7 @@ static int s5p_jpeg_adjust_subs_ctrl(struct s5p_jpeg_ctx *ctx, int *ctrl_val) | |||
1624 | } | 1626 | } |
1625 | 1627 | ||
1626 | /* | 1628 | /* |
1627 | * The exynos4x12 and exynos3250 devices require resulting | 1629 | * The exynos4x12 and exynos3250/compatible devices require resulting |
1628 | * jpeg subsampling not to be lower than the input raw image | 1630 | * jpeg subsampling not to be lower than the input raw image |
1629 | * subsampling. | 1631 | * subsampling. |
1630 | */ | 1632 | */ |
@@ -1842,7 +1844,7 @@ static void exynos4_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx) | |||
1842 | struct s5p_jpeg *jpeg = ctx->jpeg; | 1844 | struct s5p_jpeg *jpeg = ctx->jpeg; |
1843 | struct s5p_jpeg_fmt *fmt; | 1845 | struct s5p_jpeg_fmt *fmt; |
1844 | struct vb2_buffer *vb; | 1846 | struct vb2_buffer *vb; |
1845 | struct s5p_jpeg_addr jpeg_addr; | 1847 | struct s5p_jpeg_addr jpeg_addr = {}; |
1846 | u32 pix_size, padding_bytes = 0; | 1848 | u32 pix_size, padding_bytes = 0; |
1847 | 1849 | ||
1848 | jpeg_addr.cb = 0; | 1850 | jpeg_addr.cb = 0; |
@@ -1946,7 +1948,7 @@ static void exynos3250_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx) | |||
1946 | struct s5p_jpeg *jpeg = ctx->jpeg; | 1948 | struct s5p_jpeg *jpeg = ctx->jpeg; |
1947 | struct s5p_jpeg_fmt *fmt; | 1949 | struct s5p_jpeg_fmt *fmt; |
1948 | struct vb2_buffer *vb; | 1950 | struct vb2_buffer *vb; |
1949 | struct s5p_jpeg_addr jpeg_addr; | 1951 | struct s5p_jpeg_addr jpeg_addr = {}; |
1950 | u32 pix_size; | 1952 | u32 pix_size; |
1951 | 1953 | ||
1952 | pix_size = ctx->cap_q.w * ctx->cap_q.h; | 1954 | pix_size = ctx->cap_q.w * ctx->cap_q.h; |
@@ -2020,6 +2022,16 @@ static void exynos3250_jpeg_device_run(void *priv) | |||
2020 | exynos3250_jpeg_qtbl(jpeg->regs, 2, 1); | 2022 | exynos3250_jpeg_qtbl(jpeg->regs, 2, 1); |
2021 | exynos3250_jpeg_qtbl(jpeg->regs, 3, 1); | 2023 | exynos3250_jpeg_qtbl(jpeg->regs, 3, 1); |
2022 | 2024 | ||
2025 | /* | ||
2026 | * Some SoCs require setting Huffman tables before each run | ||
2027 | */ | ||
2028 | if (jpeg->variant->htbl_reinit) { | ||
2029 | s5p_jpeg_set_hdctbl(jpeg->regs); | ||
2030 | s5p_jpeg_set_hdctblg(jpeg->regs); | ||
2031 | s5p_jpeg_set_hactbl(jpeg->regs); | ||
2032 | s5p_jpeg_set_hactblg(jpeg->regs); | ||
2033 | } | ||
2034 | |||
2023 | /* Y, Cb, Cr use Huffman table 0 */ | 2035 | /* Y, Cb, Cr use Huffman table 0 */ |
2024 | exynos3250_jpeg_htbl_ac(jpeg->regs, 1); | 2036 | exynos3250_jpeg_htbl_ac(jpeg->regs, 1); |
2025 | exynos3250_jpeg_htbl_dc(jpeg->regs, 1); | 2037 | exynos3250_jpeg_htbl_dc(jpeg->regs, 1); |
@@ -2663,13 +2675,12 @@ static int s5p_jpeg_runtime_resume(struct device *dev) | |||
2663 | /* | 2675 | /* |
2664 | * JPEG IP allows storing two Huffman tables for each component. | 2676 | * JPEG IP allows storing two Huffman tables for each component. |
2665 | * We fill table 0 for each component and do this here only | 2677 | * We fill table 0 for each component and do this here only |
2666 | * for S5PC210 and Exynos3250 SoCs. Exynos4x12 SoC requires | 2678 | * for S5PC210 and Exynos3250 SoCs. Exynos4x12 and Exynos542x SoC |
2667 | * programming its Huffman tables each time the encoding process | 2679 | * require programming their Huffman tables each time the encoding |
2668 | * is initialized, and thus it is accomplished in the device_run | 2680 | * process is initialized, and thus it is accomplished in the |
2669 | * callback of m2m_ops. | 2681 | * device_run callback of m2m_ops. |
2670 | */ | 2682 | */ |
2671 | if (jpeg->variant->version == SJPEG_S5P || | 2683 | if (!jpeg->variant->htbl_reinit) { |
2672 | jpeg->variant->version == SJPEG_EXYNOS3250) { | ||
2673 | s5p_jpeg_set_hdctbl(jpeg->regs); | 2684 | s5p_jpeg_set_hdctbl(jpeg->regs); |
2674 | s5p_jpeg_set_hdctblg(jpeg->regs); | 2685 | s5p_jpeg_set_hdctblg(jpeg->regs); |
2675 | s5p_jpeg_set_hactbl(jpeg->regs); | 2686 | s5p_jpeg_set_hactbl(jpeg->regs); |
@@ -2717,6 +2728,7 @@ static struct s5p_jpeg_variant exynos3250_jpeg_drvdata = { | |||
2717 | .jpeg_irq = exynos3250_jpeg_irq, | 2728 | .jpeg_irq = exynos3250_jpeg_irq, |
2718 | .m2m_ops = &exynos3250_jpeg_m2m_ops, | 2729 | .m2m_ops = &exynos3250_jpeg_m2m_ops, |
2719 | .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS3250, | 2730 | .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS3250, |
2731 | .hw3250_compat = 1, | ||
2720 | }; | 2732 | }; |
2721 | 2733 | ||
2722 | static struct s5p_jpeg_variant exynos4_jpeg_drvdata = { | 2734 | static struct s5p_jpeg_variant exynos4_jpeg_drvdata = { |
@@ -2724,6 +2736,16 @@ static struct s5p_jpeg_variant exynos4_jpeg_drvdata = { | |||
2724 | .jpeg_irq = exynos4_jpeg_irq, | 2736 | .jpeg_irq = exynos4_jpeg_irq, |
2725 | .m2m_ops = &exynos4_jpeg_m2m_ops, | 2737 | .m2m_ops = &exynos4_jpeg_m2m_ops, |
2726 | .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS4, | 2738 | .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS4, |
2739 | .htbl_reinit = 1, | ||
2740 | }; | ||
2741 | |||
2742 | static struct s5p_jpeg_variant exynos5420_jpeg_drvdata = { | ||
2743 | .version = SJPEG_EXYNOS5420, | ||
2744 | .jpeg_irq = exynos3250_jpeg_irq, /* intentionally 3250 */ | ||
2745 | .m2m_ops = &exynos3250_jpeg_m2m_ops, /* intentionally 3250 */ | ||
2746 | .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS3250, /* intentionally 3250 */ | ||
2747 | .hw3250_compat = 1, | ||
2748 | .htbl_reinit = 1, | ||
2727 | }; | 2749 | }; |
2728 | 2750 | ||
2729 | static const struct of_device_id samsung_jpeg_match[] = { | 2751 | static const struct of_device_id samsung_jpeg_match[] = { |
@@ -2739,6 +2761,9 @@ static const struct of_device_id samsung_jpeg_match[] = { | |||
2739 | }, { | 2761 | }, { |
2740 | .compatible = "samsung,exynos4212-jpeg", | 2762 | .compatible = "samsung,exynos4212-jpeg", |
2741 | .data = &exynos4_jpeg_drvdata, | 2763 | .data = &exynos4_jpeg_drvdata, |
2764 | }, { | ||
2765 | .compatible = "samsung,exynos5420-jpeg", | ||
2766 | .data = &exynos5420_jpeg_drvdata, | ||
2742 | }, | 2767 | }, |
2743 | {}, | 2768 | {}, |
2744 | }; | 2769 | }; |
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.h b/drivers/media/platform/s5p-jpeg/jpeg-core.h index 764b32de326b..7d9a9ed19cea 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.h +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.h | |||
@@ -67,10 +67,12 @@ | |||
67 | #define SJPEG_SUBSAMPLING_420 0x22 | 67 | #define SJPEG_SUBSAMPLING_420 0x22 |
68 | 68 | ||
69 | /* Version numbers */ | 69 | /* Version numbers */ |
70 | 70 | enum sjpeg_version { | |
71 | #define SJPEG_S5P 1 | 71 | SJPEG_S5P, |
72 | #define SJPEG_EXYNOS3250 2 | 72 | SJPEG_EXYNOS3250, |
73 | #define SJPEG_EXYNOS4 3 | 73 | SJPEG_EXYNOS4, |
74 | SJPEG_EXYNOS5420, | ||
75 | }; | ||
74 | 76 | ||
75 | enum exynos4_jpeg_result { | 77 | enum exynos4_jpeg_result { |
76 | OK_ENC_OR_DEC, | 78 | OK_ENC_OR_DEC, |
@@ -130,6 +132,8 @@ struct s5p_jpeg { | |||
130 | struct s5p_jpeg_variant { | 132 | struct s5p_jpeg_variant { |
131 | unsigned int version; | 133 | unsigned int version; |
132 | unsigned int fmt_ver_flag; | 134 | unsigned int fmt_ver_flag; |
135 | unsigned int hw3250_compat:1; | ||
136 | unsigned int htbl_reinit:1; | ||
133 | struct v4l2_m2m_ops *m2m_ops; | 137 | struct v4l2_m2m_ops *m2m_ops; |
134 | irqreturn_t (*jpeg_irq)(int irq, void *priv); | 138 | irqreturn_t (*jpeg_irq)(int irq, void *priv); |
135 | }; | 139 | }; |
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.c b/drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.c index e3b8e67e005f..b5f20e722b63 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.c | |||
@@ -51,18 +51,6 @@ void s5p_jpeg_input_raw_mode(void __iomem *regs, unsigned long mode) | |||
51 | writel(reg, regs + S5P_JPGCMOD); | 51 | writel(reg, regs + S5P_JPGCMOD); |
52 | } | 52 | } |
53 | 53 | ||
54 | void s5p_jpeg_input_raw_y16(void __iomem *regs, bool y16) | ||
55 | { | ||
56 | unsigned long reg; | ||
57 | |||
58 | reg = readl(regs + S5P_JPGCMOD); | ||
59 | if (y16) | ||
60 | reg |= S5P_MODE_Y16; | ||
61 | else | ||
62 | reg &= ~S5P_MODE_Y16_MASK; | ||
63 | writel(reg, regs + S5P_JPGCMOD); | ||
64 | } | ||
65 | |||
66 | void s5p_jpeg_proc_mode(void __iomem *regs, unsigned long mode) | 54 | void s5p_jpeg_proc_mode(void __iomem *regs, unsigned long mode) |
67 | { | 55 | { |
68 | unsigned long reg, m; | 56 | unsigned long reg, m; |
@@ -208,26 +196,6 @@ void s5p_jpeg_final_mcu_num_int_enable(void __iomem *regs, bool enbl) | |||
208 | writel(reg, regs + S5P_JPGINTSE); | 196 | writel(reg, regs + S5P_JPGINTSE); |
209 | } | 197 | } |
210 | 198 | ||
211 | void s5p_jpeg_timer_enable(void __iomem *regs, unsigned long val) | ||
212 | { | ||
213 | unsigned long reg; | ||
214 | |||
215 | reg = readl(regs + S5P_JPG_TIMER_SE); | ||
216 | reg |= S5P_TIMER_INT_EN; | ||
217 | reg &= ~S5P_TIMER_INIT_MASK; | ||
218 | reg |= val & S5P_TIMER_INIT_MASK; | ||
219 | writel(reg, regs + S5P_JPG_TIMER_SE); | ||
220 | } | ||
221 | |||
222 | void s5p_jpeg_timer_disable(void __iomem *regs) | ||
223 | { | ||
224 | unsigned long reg; | ||
225 | |||
226 | reg = readl(regs + S5P_JPG_TIMER_SE); | ||
227 | reg &= ~S5P_TIMER_INT_EN_MASK; | ||
228 | writel(reg, regs + S5P_JPG_TIMER_SE); | ||
229 | } | ||
230 | |||
231 | int s5p_jpeg_timer_stat(void __iomem *regs) | 199 | int s5p_jpeg_timer_stat(void __iomem *regs) |
232 | { | 200 | { |
233 | return (int)((readl(regs + S5P_JPG_TIMER_ST) & S5P_TIMER_INT_STAT_MASK) | 201 | return (int)((readl(regs + S5P_JPG_TIMER_ST) & S5P_TIMER_INT_STAT_MASK) |
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.h b/drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.h index c11ebe86b9c9..f208fa3ed738 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.h +++ b/drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.h | |||
@@ -29,7 +29,6 @@ | |||
29 | void s5p_jpeg_reset(void __iomem *regs); | 29 | void s5p_jpeg_reset(void __iomem *regs); |
30 | void s5p_jpeg_poweron(void __iomem *regs); | 30 | void s5p_jpeg_poweron(void __iomem *regs); |
31 | void s5p_jpeg_input_raw_mode(void __iomem *regs, unsigned long mode); | 31 | void s5p_jpeg_input_raw_mode(void __iomem *regs, unsigned long mode); |
32 | void s5p_jpeg_input_raw_y16(void __iomem *regs, bool y16); | ||
33 | void s5p_jpeg_proc_mode(void __iomem *regs, unsigned long mode); | 32 | void s5p_jpeg_proc_mode(void __iomem *regs, unsigned long mode); |
34 | void s5p_jpeg_subsampling_mode(void __iomem *regs, unsigned int mode); | 33 | void s5p_jpeg_subsampling_mode(void __iomem *regs, unsigned int mode); |
35 | unsigned int s5p_jpeg_get_subsampling_mode(void __iomem *regs); | 34 | unsigned int s5p_jpeg_get_subsampling_mode(void __iomem *regs); |
@@ -42,8 +41,6 @@ void s5p_jpeg_x(void __iomem *regs, unsigned int x); | |||
42 | void s5p_jpeg_rst_int_enable(void __iomem *regs, bool enable); | 41 | void s5p_jpeg_rst_int_enable(void __iomem *regs, bool enable); |
43 | void s5p_jpeg_data_num_int_enable(void __iomem *regs, bool enable); | 42 | void s5p_jpeg_data_num_int_enable(void __iomem *regs, bool enable); |
44 | void s5p_jpeg_final_mcu_num_int_enable(void __iomem *regs, bool enbl); | 43 | void s5p_jpeg_final_mcu_num_int_enable(void __iomem *regs, bool enbl); |
45 | void s5p_jpeg_timer_enable(void __iomem *regs, unsigned long val); | ||
46 | void s5p_jpeg_timer_disable(void __iomem *regs); | ||
47 | int s5p_jpeg_timer_stat(void __iomem *regs); | 44 | int s5p_jpeg_timer_stat(void __iomem *regs); |
48 | void s5p_jpeg_clear_timer_stat(void __iomem *regs); | 45 | void s5p_jpeg_clear_timer_stat(void __iomem *regs); |
49 | void s5p_jpeg_enc_stream_int(void __iomem *regs, unsigned long size); | 46 | void s5p_jpeg_enc_stream_int(void __iomem *regs, unsigned long size); |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index 98374e8bad3e..8333fbc2fe96 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c | |||
@@ -844,6 +844,13 @@ static int s5p_mfc_open(struct file *file) | |||
844 | ret = -ENOENT; | 844 | ret = -ENOENT; |
845 | goto err_queue_init; | 845 | goto err_queue_init; |
846 | } | 846 | } |
847 | /* One way to indicate end-of-stream for MFC is to set the | ||
848 | * bytesused == 0. However by default videobuf2 handles bytesused | ||
849 | * equal to 0 as a special case and changes its value to the size | ||
850 | * of the buffer. Set the allow_zero_bytesused flag so that videobuf2 | ||
851 | * will keep the value of bytesused intact. | ||
852 | */ | ||
853 | q->allow_zero_bytesused = 1; | ||
847 | q->mem_ops = &vb2_dma_contig_memops; | 854 | q->mem_ops = &vb2_dma_contig_memops; |
848 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; | 855 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; |
849 | ret = vb2_queue_init(q); | 856 | ret = vb2_queue_init(q); |
diff --git a/drivers/media/platform/s5p-tv/mixer_video.c b/drivers/media/platform/s5p-tv/mixer_video.c index 72d4f2e1efc0..751f3b618337 100644 --- a/drivers/media/platform/s5p-tv/mixer_video.c +++ b/drivers/media/platform/s5p-tv/mixer_video.c | |||
@@ -287,7 +287,7 @@ static void mxr_mplane_fill(struct v4l2_plane_pix_format *planes, | |||
287 | u32 bl_width = divup(width, blk->width); | 287 | u32 bl_width = divup(width, blk->width); |
288 | u32 bl_height = divup(height, blk->height); | 288 | u32 bl_height = divup(height, blk->height); |
289 | u32 sizeimage = bl_width * bl_height * blk->size; | 289 | u32 sizeimage = bl_width * bl_height * blk->size; |
290 | u16 bytesperline = bl_width * blk->size / blk->height; | 290 | u32 bytesperline = bl_width * blk->size / blk->height; |
291 | 291 | ||
292 | plane->sizeimage += sizeimage; | 292 | plane->sizeimage += sizeimage; |
293 | plane->bytesperline = max(plane->bytesperline, bytesperline); | 293 | plane->bytesperline = max(plane->bytesperline, bytesperline); |
diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c index 261f1195b49f..dde1ccc730be 100644 --- a/drivers/media/platform/sh_vou.c +++ b/drivers/media/platform/sh_vou.c | |||
@@ -62,7 +62,7 @@ enum sh_vou_status { | |||
62 | 62 | ||
63 | struct sh_vou_device { | 63 | struct sh_vou_device { |
64 | struct v4l2_device v4l2_dev; | 64 | struct v4l2_device v4l2_dev; |
65 | struct video_device *vdev; | 65 | struct video_device vdev; |
66 | atomic_t use_count; | 66 | atomic_t use_count; |
67 | struct sh_vou_pdata *pdata; | 67 | struct sh_vou_pdata *pdata; |
68 | spinlock_t lock; | 68 | spinlock_t lock; |
@@ -890,7 +890,7 @@ static int sh_vou_s_std(struct file *file, void *priv, v4l2_std_id std_id) | |||
890 | 890 | ||
891 | dev_dbg(vou_dev->v4l2_dev.dev, "%s(): 0x%llx\n", __func__, std_id); | 891 | dev_dbg(vou_dev->v4l2_dev.dev, "%s(): 0x%llx\n", __func__, std_id); |
892 | 892 | ||
893 | if (std_id & ~vou_dev->vdev->tvnorms) | 893 | if (std_id & ~vou_dev->vdev.tvnorms) |
894 | return -EINVAL; | 894 | return -EINVAL; |
895 | 895 | ||
896 | ret = v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, video, | 896 | ret = v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, video, |
@@ -1168,10 +1168,10 @@ static int sh_vou_open(struct file *file) | |||
1168 | 1168 | ||
1169 | dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__); | 1169 | dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__); |
1170 | 1170 | ||
1171 | file->private_data = vou_file; | 1171 | if (mutex_lock_interruptible(&vou_dev->fop_lock)) { |
1172 | 1172 | kfree(vou_file); | |
1173 | if (mutex_lock_interruptible(&vou_dev->fop_lock)) | ||
1174 | return -ERESTARTSYS; | 1173 | return -ERESTARTSYS; |
1174 | } | ||
1175 | if (atomic_inc_return(&vou_dev->use_count) == 1) { | 1175 | if (atomic_inc_return(&vou_dev->use_count) == 1) { |
1176 | int ret; | 1176 | int ret; |
1177 | /* First open */ | 1177 | /* First open */ |
@@ -1183,6 +1183,7 @@ static int sh_vou_open(struct file *file) | |||
1183 | pm_runtime_put(vou_dev->v4l2_dev.dev); | 1183 | pm_runtime_put(vou_dev->v4l2_dev.dev); |
1184 | vou_dev->status = SH_VOU_IDLE; | 1184 | vou_dev->status = SH_VOU_IDLE; |
1185 | mutex_unlock(&vou_dev->fop_lock); | 1185 | mutex_unlock(&vou_dev->fop_lock); |
1186 | kfree(vou_file); | ||
1186 | return ret; | 1187 | return ret; |
1187 | } | 1188 | } |
1188 | } | 1189 | } |
@@ -1192,9 +1193,11 @@ static int sh_vou_open(struct file *file) | |||
1192 | V4L2_BUF_TYPE_VIDEO_OUTPUT, | 1193 | V4L2_BUF_TYPE_VIDEO_OUTPUT, |
1193 | V4L2_FIELD_NONE, | 1194 | V4L2_FIELD_NONE, |
1194 | sizeof(struct videobuf_buffer), | 1195 | sizeof(struct videobuf_buffer), |
1195 | vou_dev->vdev, &vou_dev->fop_lock); | 1196 | &vou_dev->vdev, &vou_dev->fop_lock); |
1196 | mutex_unlock(&vou_dev->fop_lock); | 1197 | mutex_unlock(&vou_dev->fop_lock); |
1197 | 1198 | ||
1199 | file->private_data = vou_file; | ||
1200 | |||
1198 | return 0; | 1201 | return 0; |
1199 | } | 1202 | } |
1200 | 1203 | ||
@@ -1358,21 +1361,14 @@ static int sh_vou_probe(struct platform_device *pdev) | |||
1358 | goto ev4l2devreg; | 1361 | goto ev4l2devreg; |
1359 | } | 1362 | } |
1360 | 1363 | ||
1361 | /* Allocate memory for video device */ | 1364 | vdev = &vou_dev->vdev; |
1362 | vdev = video_device_alloc(); | ||
1363 | if (vdev == NULL) { | ||
1364 | ret = -ENOMEM; | ||
1365 | goto evdevalloc; | ||
1366 | } | ||
1367 | |||
1368 | *vdev = sh_vou_video_template; | 1365 | *vdev = sh_vou_video_template; |
1369 | if (vou_pdata->bus_fmt == SH_VOU_BUS_8BIT) | 1366 | if (vou_pdata->bus_fmt == SH_VOU_BUS_8BIT) |
1370 | vdev->tvnorms |= V4L2_STD_PAL; | 1367 | vdev->tvnorms |= V4L2_STD_PAL; |
1371 | vdev->v4l2_dev = &vou_dev->v4l2_dev; | 1368 | vdev->v4l2_dev = &vou_dev->v4l2_dev; |
1372 | vdev->release = video_device_release; | 1369 | vdev->release = video_device_release_empty; |
1373 | vdev->lock = &vou_dev->fop_lock; | 1370 | vdev->lock = &vou_dev->fop_lock; |
1374 | 1371 | ||
1375 | vou_dev->vdev = vdev; | ||
1376 | video_set_drvdata(vdev, vou_dev); | 1372 | video_set_drvdata(vdev, vou_dev); |
1377 | 1373 | ||
1378 | pm_runtime_enable(&pdev->dev); | 1374 | pm_runtime_enable(&pdev->dev); |
@@ -1406,9 +1402,7 @@ ei2cnd: | |||
1406 | ereset: | 1402 | ereset: |
1407 | i2c_put_adapter(i2c_adap); | 1403 | i2c_put_adapter(i2c_adap); |
1408 | ei2cgadap: | 1404 | ei2cgadap: |
1409 | video_device_release(vdev); | ||
1410 | pm_runtime_disable(&pdev->dev); | 1405 | pm_runtime_disable(&pdev->dev); |
1411 | evdevalloc: | ||
1412 | v4l2_device_unregister(&vou_dev->v4l2_dev); | 1406 | v4l2_device_unregister(&vou_dev->v4l2_dev); |
1413 | ev4l2devreg: | 1407 | ev4l2devreg: |
1414 | free_irq(irq, vou_dev); | 1408 | free_irq(irq, vou_dev); |
@@ -1435,7 +1429,7 @@ static int sh_vou_remove(struct platform_device *pdev) | |||
1435 | if (irq > 0) | 1429 | if (irq > 0) |
1436 | free_irq(irq, vou_dev); | 1430 | free_irq(irq, vou_dev); |
1437 | pm_runtime_disable(&pdev->dev); | 1431 | pm_runtime_disable(&pdev->dev); |
1438 | video_unregister_device(vou_dev->vdev); | 1432 | video_unregister_device(&vou_dev->vdev); |
1439 | i2c_put_adapter(client->adapter); | 1433 | i2c_put_adapter(client->adapter); |
1440 | v4l2_device_unregister(&vou_dev->v4l2_dev); | 1434 | v4l2_device_unregister(&vou_dev->v4l2_dev); |
1441 | iounmap(vou_dev->base); | 1435 | iounmap(vou_dev->base); |
diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c index 279ab9f6ae38..9351f64dee7b 100644 --- a/drivers/media/platform/soc_camera/rcar_vin.c +++ b/drivers/media/platform/soc_camera/rcar_vin.c | |||
@@ -977,19 +977,6 @@ static void rcar_vin_remove_device(struct soc_camera_device *icd) | |||
977 | icd->devnum); | 977 | icd->devnum); |
978 | } | 978 | } |
979 | 979 | ||
980 | /* Called with .host_lock held */ | ||
981 | static int rcar_vin_clock_start(struct soc_camera_host *ici) | ||
982 | { | ||
983 | /* VIN does not have "mclk" */ | ||
984 | return 0; | ||
985 | } | ||
986 | |||
987 | /* Called with .host_lock held */ | ||
988 | static void rcar_vin_clock_stop(struct soc_camera_host *ici) | ||
989 | { | ||
990 | /* VIN does not have "mclk" */ | ||
991 | } | ||
992 | |||
993 | static void set_coeff(struct rcar_vin_priv *priv, unsigned short xs) | 980 | static void set_coeff(struct rcar_vin_priv *priv, unsigned short xs) |
994 | { | 981 | { |
995 | int i; | 982 | int i; |
@@ -1803,8 +1790,6 @@ static struct soc_camera_host_ops rcar_vin_host_ops = { | |||
1803 | .owner = THIS_MODULE, | 1790 | .owner = THIS_MODULE, |
1804 | .add = rcar_vin_add_device, | 1791 | .add = rcar_vin_add_device, |
1805 | .remove = rcar_vin_remove_device, | 1792 | .remove = rcar_vin_remove_device, |
1806 | .clock_start = rcar_vin_clock_start, | ||
1807 | .clock_stop = rcar_vin_clock_stop, | ||
1808 | .get_formats = rcar_vin_get_formats, | 1793 | .get_formats = rcar_vin_get_formats, |
1809 | .put_formats = rcar_vin_put_formats, | 1794 | .put_formats = rcar_vin_put_formats, |
1810 | .get_crop = rcar_vin_get_crop, | 1795 | .get_crop = rcar_vin_get_crop, |
diff --git a/drivers/media/platform/soc_camera/sh_mobile_csi2.c b/drivers/media/platform/soc_camera/sh_mobile_csi2.c index c4e7aa0ee7e1..cd93241eb497 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_csi2.c +++ b/drivers/media/platform/soc_camera/sh_mobile_csi2.c | |||
@@ -380,7 +380,6 @@ static int sh_csi2_remove(struct platform_device *pdev) | |||
380 | struct sh_csi2 *priv = container_of(subdev, struct sh_csi2, subdev); | 380 | struct sh_csi2 *priv = container_of(subdev, struct sh_csi2, subdev); |
381 | 381 | ||
382 | v4l2_async_unregister_subdev(&priv->subdev); | 382 | v4l2_async_unregister_subdev(&priv->subdev); |
383 | v4l2_device_unregister_subdev(subdev); | ||
384 | pm_runtime_disable(&pdev->dev); | 383 | pm_runtime_disable(&pdev->dev); |
385 | 384 | ||
386 | return 0; | 385 | return 0; |
diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index 9039d989c01c..7bfe7665687f 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c | |||
@@ -177,6 +177,30 @@ static int __soc_camera_power_off(struct soc_camera_device *icd) | |||
177 | return 0; | 177 | return 0; |
178 | } | 178 | } |
179 | 179 | ||
180 | static int soc_camera_clock_start(struct soc_camera_host *ici) | ||
181 | { | ||
182 | int ret; | ||
183 | |||
184 | if (!ici->ops->clock_start) | ||
185 | return 0; | ||
186 | |||
187 | mutex_lock(&ici->clk_lock); | ||
188 | ret = ici->ops->clock_start(ici); | ||
189 | mutex_unlock(&ici->clk_lock); | ||
190 | |||
191 | return ret; | ||
192 | } | ||
193 | |||
194 | static void soc_camera_clock_stop(struct soc_camera_host *ici) | ||
195 | { | ||
196 | if (!ici->ops->clock_stop) | ||
197 | return; | ||
198 | |||
199 | mutex_lock(&ici->clk_lock); | ||
200 | ici->ops->clock_stop(ici); | ||
201 | mutex_unlock(&ici->clk_lock); | ||
202 | } | ||
203 | |||
180 | const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc( | 204 | const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc( |
181 | struct soc_camera_device *icd, unsigned int fourcc) | 205 | struct soc_camera_device *icd, unsigned int fourcc) |
182 | { | 206 | { |
@@ -584,9 +608,7 @@ static int soc_camera_add_device(struct soc_camera_device *icd) | |||
584 | return -EBUSY; | 608 | return -EBUSY; |
585 | 609 | ||
586 | if (!icd->clk) { | 610 | if (!icd->clk) { |
587 | mutex_lock(&ici->clk_lock); | 611 | ret = soc_camera_clock_start(ici); |
588 | ret = ici->ops->clock_start(ici); | ||
589 | mutex_unlock(&ici->clk_lock); | ||
590 | if (ret < 0) | 612 | if (ret < 0) |
591 | return ret; | 613 | return ret; |
592 | } | 614 | } |
@@ -602,11 +624,8 @@ static int soc_camera_add_device(struct soc_camera_device *icd) | |||
602 | return 0; | 624 | return 0; |
603 | 625 | ||
604 | eadd: | 626 | eadd: |
605 | if (!icd->clk) { | 627 | if (!icd->clk) |
606 | mutex_lock(&ici->clk_lock); | 628 | soc_camera_clock_stop(ici); |
607 | ici->ops->clock_stop(ici); | ||
608 | mutex_unlock(&ici->clk_lock); | ||
609 | } | ||
610 | return ret; | 629 | return ret; |
611 | } | 630 | } |
612 | 631 | ||
@@ -619,11 +638,8 @@ static void soc_camera_remove_device(struct soc_camera_device *icd) | |||
619 | 638 | ||
620 | if (ici->ops->remove) | 639 | if (ici->ops->remove) |
621 | ici->ops->remove(icd); | 640 | ici->ops->remove(icd); |
622 | if (!icd->clk) { | 641 | if (!icd->clk) |
623 | mutex_lock(&ici->clk_lock); | 642 | soc_camera_clock_stop(ici); |
624 | ici->ops->clock_stop(ici); | ||
625 | mutex_unlock(&ici->clk_lock); | ||
626 | } | ||
627 | ici->icd = NULL; | 643 | ici->icd = NULL; |
628 | } | 644 | } |
629 | 645 | ||
@@ -688,7 +704,8 @@ static int soc_camera_open(struct file *file) | |||
688 | 704 | ||
689 | /* The camera could have been already on, try to reset */ | 705 | /* The camera could have been already on, try to reset */ |
690 | if (sdesc->subdev_desc.reset) | 706 | if (sdesc->subdev_desc.reset) |
691 | sdesc->subdev_desc.reset(icd->pdev); | 707 | if (icd->control) |
708 | sdesc->subdev_desc.reset(icd->control); | ||
692 | 709 | ||
693 | ret = soc_camera_add_device(icd); | 710 | ret = soc_camera_add_device(icd); |
694 | if (ret < 0) { | 711 | if (ret < 0) { |
@@ -1159,7 +1176,8 @@ static void scan_add_host(struct soc_camera_host *ici) | |||
1159 | 1176 | ||
1160 | /* The camera could have been already on, try to reset */ | 1177 | /* The camera could have been already on, try to reset */ |
1161 | if (ssdd->reset) | 1178 | if (ssdd->reset) |
1162 | ssdd->reset(icd->pdev); | 1179 | if (icd->control) |
1180 | ssdd->reset(icd->control); | ||
1163 | 1181 | ||
1164 | icd->parent = ici->v4l2_dev.dev; | 1182 | icd->parent = ici->v4l2_dev.dev; |
1165 | 1183 | ||
@@ -1178,7 +1196,6 @@ static int soc_camera_clk_enable(struct v4l2_clk *clk) | |||
1178 | { | 1196 | { |
1179 | struct soc_camera_device *icd = clk->priv; | 1197 | struct soc_camera_device *icd = clk->priv; |
1180 | struct soc_camera_host *ici; | 1198 | struct soc_camera_host *ici; |
1181 | int ret; | ||
1182 | 1199 | ||
1183 | if (!icd || !icd->parent) | 1200 | if (!icd || !icd->parent) |
1184 | return -ENODEV; | 1201 | return -ENODEV; |
@@ -1192,10 +1209,7 @@ static int soc_camera_clk_enable(struct v4l2_clk *clk) | |||
1192 | * If a different client is currently being probed, the host will tell | 1209 | * If a different client is currently being probed, the host will tell |
1193 | * you to go | 1210 | * you to go |
1194 | */ | 1211 | */ |
1195 | mutex_lock(&ici->clk_lock); | 1212 | return soc_camera_clock_start(ici); |
1196 | ret = ici->ops->clock_start(ici); | ||
1197 | mutex_unlock(&ici->clk_lock); | ||
1198 | return ret; | ||
1199 | } | 1213 | } |
1200 | 1214 | ||
1201 | static void soc_camera_clk_disable(struct v4l2_clk *clk) | 1215 | static void soc_camera_clk_disable(struct v4l2_clk *clk) |
@@ -1208,9 +1222,7 @@ static void soc_camera_clk_disable(struct v4l2_clk *clk) | |||
1208 | 1222 | ||
1209 | ici = to_soc_camera_host(icd->parent); | 1223 | ici = to_soc_camera_host(icd->parent); |
1210 | 1224 | ||
1211 | mutex_lock(&ici->clk_lock); | 1225 | soc_camera_clock_stop(ici); |
1212 | ici->ops->clock_stop(ici); | ||
1213 | mutex_unlock(&ici->clk_lock); | ||
1214 | 1226 | ||
1215 | module_put(ici->ops->owner); | 1227 | module_put(ici->ops->owner); |
1216 | } | 1228 | } |
@@ -1364,7 +1376,7 @@ static int soc_camera_i2c_init(struct soc_camera_device *icd, | |||
1364 | snprintf(clk_name, sizeof(clk_name), "%d-%04x", | 1376 | snprintf(clk_name, sizeof(clk_name), "%d-%04x", |
1365 | shd->i2c_adapter_id, shd->board_info->addr); | 1377 | shd->i2c_adapter_id, shd->board_info->addr); |
1366 | 1378 | ||
1367 | icd->clk = v4l2_clk_register(&soc_camera_clk_ops, clk_name, "mclk", icd); | 1379 | icd->clk = v4l2_clk_register(&soc_camera_clk_ops, clk_name, icd); |
1368 | if (IS_ERR(icd->clk)) { | 1380 | if (IS_ERR(icd->clk)) { |
1369 | ret = PTR_ERR(icd->clk); | 1381 | ret = PTR_ERR(icd->clk); |
1370 | goto eclkreg; | 1382 | goto eclkreg; |
@@ -1445,7 +1457,7 @@ static int soc_camera_async_bound(struct v4l2_async_notifier *notifier, | |||
1445 | memcpy(&sdesc->subdev_desc, ssdd, | 1457 | memcpy(&sdesc->subdev_desc, ssdd, |
1446 | sizeof(sdesc->subdev_desc)); | 1458 | sizeof(sdesc->subdev_desc)); |
1447 | if (ssdd->reset) | 1459 | if (ssdd->reset) |
1448 | ssdd->reset(icd->pdev); | 1460 | ssdd->reset(&client->dev); |
1449 | } | 1461 | } |
1450 | 1462 | ||
1451 | icd->control = &client->dev; | 1463 | icd->control = &client->dev; |
@@ -1545,7 +1557,7 @@ static int scan_async_group(struct soc_camera_host *ici, | |||
1545 | snprintf(clk_name, sizeof(clk_name), "%d-%04x", | 1557 | snprintf(clk_name, sizeof(clk_name), "%d-%04x", |
1546 | sasd->asd.match.i2c.adapter_id, sasd->asd.match.i2c.address); | 1558 | sasd->asd.match.i2c.adapter_id, sasd->asd.match.i2c.address); |
1547 | 1559 | ||
1548 | icd->clk = v4l2_clk_register(&soc_camera_clk_ops, clk_name, "mclk", icd); | 1560 | icd->clk = v4l2_clk_register(&soc_camera_clk_ops, clk_name, icd); |
1549 | if (IS_ERR(icd->clk)) { | 1561 | if (IS_ERR(icd->clk)) { |
1550 | ret = PTR_ERR(icd->clk); | 1562 | ret = PTR_ERR(icd->clk); |
1551 | goto eclkreg; | 1563 | goto eclkreg; |
@@ -1650,7 +1662,7 @@ static int soc_of_bind(struct soc_camera_host *ici, | |||
1650 | snprintf(clk_name, sizeof(clk_name), "of-%s", | 1662 | snprintf(clk_name, sizeof(clk_name), "of-%s", |
1651 | of_node_full_name(remote)); | 1663 | of_node_full_name(remote)); |
1652 | 1664 | ||
1653 | icd->clk = v4l2_clk_register(&soc_camera_clk_ops, clk_name, "mclk", icd); | 1665 | icd->clk = v4l2_clk_register(&soc_camera_clk_ops, clk_name, icd); |
1654 | if (IS_ERR(icd->clk)) { | 1666 | if (IS_ERR(icd->clk)) { |
1655 | ret = PTR_ERR(icd->clk); | 1667 | ret = PTR_ERR(icd->clk); |
1656 | goto eclkreg; | 1668 | goto eclkreg; |
@@ -1659,6 +1671,8 @@ static int soc_of_bind(struct soc_camera_host *ici, | |||
1659 | ret = v4l2_async_notifier_register(&ici->v4l2_dev, &sasc->notifier); | 1671 | ret = v4l2_async_notifier_register(&ici->v4l2_dev, &sasc->notifier); |
1660 | if (!ret) | 1672 | if (!ret) |
1661 | return 0; | 1673 | return 0; |
1674 | |||
1675 | v4l2_clk_unregister(icd->clk); | ||
1662 | eclkreg: | 1676 | eclkreg: |
1663 | icd->clk = NULL; | 1677 | icd->clk = NULL; |
1664 | platform_device_del(sasc->pdev); | 1678 | platform_device_del(sasc->pdev); |
@@ -1751,9 +1765,7 @@ static int soc_camera_probe(struct soc_camera_host *ici, | |||
1751 | ret = -EINVAL; | 1765 | ret = -EINVAL; |
1752 | goto eadd; | 1766 | goto eadd; |
1753 | } else { | 1767 | } else { |
1754 | mutex_lock(&ici->clk_lock); | 1768 | ret = soc_camera_clock_start(ici); |
1755 | ret = ici->ops->clock_start(ici); | ||
1756 | mutex_unlock(&ici->clk_lock); | ||
1757 | if (ret < 0) | 1769 | if (ret < 0) |
1758 | goto eadd; | 1770 | goto eadd; |
1759 | 1771 | ||
@@ -1793,9 +1805,7 @@ efinish: | |||
1793 | module_put(control->driver->owner); | 1805 | module_put(control->driver->owner); |
1794 | enodrv: | 1806 | enodrv: |
1795 | eadddev: | 1807 | eadddev: |
1796 | mutex_lock(&ici->clk_lock); | 1808 | soc_camera_clock_stop(ici); |
1797 | ici->ops->clock_stop(ici); | ||
1798 | mutex_unlock(&ici->clk_lock); | ||
1799 | } | 1809 | } |
1800 | eadd: | 1810 | eadd: |
1801 | if (icd->vdev) { | 1811 | if (icd->vdev) { |
@@ -1889,22 +1899,34 @@ static int default_enum_framesizes(struct soc_camera_device *icd, | |||
1889 | int ret; | 1899 | int ret; |
1890 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | 1900 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
1891 | const struct soc_camera_format_xlate *xlate; | 1901 | const struct soc_camera_format_xlate *xlate; |
1892 | __u32 pixfmt = fsize->pixel_format; | 1902 | struct v4l2_subdev_frame_size_enum fse = { |
1893 | struct v4l2_frmsizeenum fsize_mbus = *fsize; | 1903 | .index = fsize->index, |
1904 | .which = V4L2_SUBDEV_FORMAT_ACTIVE, | ||
1905 | }; | ||
1894 | 1906 | ||
1895 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); | 1907 | xlate = soc_camera_xlate_by_fourcc(icd, fsize->pixel_format); |
1896 | if (!xlate) | 1908 | if (!xlate) |
1897 | return -EINVAL; | 1909 | return -EINVAL; |
1898 | /* map xlate-code to pixel_format, sensor only handle xlate-code*/ | 1910 | fse.code = xlate->code; |
1899 | fsize_mbus.pixel_format = xlate->code; | ||
1900 | 1911 | ||
1901 | ret = v4l2_subdev_call(sd, video, enum_framesizes, &fsize_mbus); | 1912 | ret = v4l2_subdev_call(sd, pad, enum_frame_size, NULL, &fse); |
1902 | if (ret < 0) | 1913 | if (ret < 0) |
1903 | return ret; | 1914 | return ret; |
1904 | 1915 | ||
1905 | *fsize = fsize_mbus; | 1916 | if (fse.min_width == fse.max_width && |
1906 | fsize->pixel_format = pixfmt; | 1917 | fse.min_height == fse.max_height) { |
1907 | 1918 | fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; | |
1919 | fsize->discrete.width = fse.min_width; | ||
1920 | fsize->discrete.height = fse.min_height; | ||
1921 | return 0; | ||
1922 | } | ||
1923 | fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS; | ||
1924 | fsize->stepwise.min_width = fse.min_width; | ||
1925 | fsize->stepwise.max_width = fse.max_width; | ||
1926 | fsize->stepwise.min_height = fse.min_height; | ||
1927 | fsize->stepwise.max_height = fse.max_height; | ||
1928 | fsize->stepwise.step_width = 1; | ||
1929 | fsize->stepwise.step_height = 1; | ||
1908 | return 0; | 1930 | return 0; |
1909 | } | 1931 | } |
1910 | 1932 | ||
@@ -1921,8 +1943,6 @@ int soc_camera_host_register(struct soc_camera_host *ici) | |||
1921 | ((!ici->ops->init_videobuf || | 1943 | ((!ici->ops->init_videobuf || |
1922 | !ici->ops->reqbufs) && | 1944 | !ici->ops->reqbufs) && |
1923 | !ici->ops->init_videobuf2) || | 1945 | !ici->ops->init_videobuf2) || |
1924 | !ici->ops->clock_start || | ||
1925 | !ici->ops->clock_stop || | ||
1926 | !ici->ops->poll || | 1946 | !ici->ops->poll || |
1927 | !ici->v4l2_dev.dev) | 1947 | !ici->v4l2_dev.dev) |
1928 | return -EINVAL; | 1948 | return -EINVAL; |
diff --git a/drivers/media/platform/via-camera.c b/drivers/media/platform/via-camera.c index 86989d86abfa..678ed9f353cb 100644 --- a/drivers/media/platform/via-camera.c +++ b/drivers/media/platform/via-camera.c | |||
@@ -1147,12 +1147,23 @@ static int viacam_enum_frameintervals(struct file *filp, void *priv, | |||
1147 | struct v4l2_frmivalenum *interval) | 1147 | struct v4l2_frmivalenum *interval) |
1148 | { | 1148 | { |
1149 | struct via_camera *cam = priv; | 1149 | struct via_camera *cam = priv; |
1150 | struct v4l2_subdev_frame_interval_enum fie = { | ||
1151 | .index = interval->index, | ||
1152 | .code = cam->mbus_code, | ||
1153 | .width = cam->sensor_format.width, | ||
1154 | .height = cam->sensor_format.height, | ||
1155 | .which = V4L2_SUBDEV_FORMAT_ACTIVE, | ||
1156 | }; | ||
1150 | int ret; | 1157 | int ret; |
1151 | 1158 | ||
1152 | mutex_lock(&cam->lock); | 1159 | mutex_lock(&cam->lock); |
1153 | ret = sensor_call(cam, video, enum_frameintervals, interval); | 1160 | ret = sensor_call(cam, pad, enum_frame_interval, NULL, &fie); |
1154 | mutex_unlock(&cam->lock); | 1161 | mutex_unlock(&cam->lock); |
1155 | return ret; | 1162 | if (ret) |
1163 | return ret; | ||
1164 | interval->type = V4L2_FRMIVAL_TYPE_DISCRETE; | ||
1165 | interval->discrete = fie.interval; | ||
1166 | return 0; | ||
1156 | } | 1167 | } |
1157 | 1168 | ||
1158 | 1169 | ||
diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c index d9d844aab39b..4d6b4cc57c57 100644 --- a/drivers/media/platform/vim2m.c +++ b/drivers/media/platform/vim2m.c | |||
@@ -142,7 +142,7 @@ static struct vim2m_fmt *find_format(struct v4l2_format *f) | |||
142 | 142 | ||
143 | struct vim2m_dev { | 143 | struct vim2m_dev { |
144 | struct v4l2_device v4l2_dev; | 144 | struct v4l2_device v4l2_dev; |
145 | struct video_device *vfd; | 145 | struct video_device vfd; |
146 | 146 | ||
147 | atomic_t num_inst; | 147 | atomic_t num_inst; |
148 | struct mutex dev_mutex; | 148 | struct mutex dev_mutex; |
@@ -968,7 +968,7 @@ static struct video_device vim2m_videodev = { | |||
968 | .fops = &vim2m_fops, | 968 | .fops = &vim2m_fops, |
969 | .ioctl_ops = &vim2m_ioctl_ops, | 969 | .ioctl_ops = &vim2m_ioctl_ops, |
970 | .minor = -1, | 970 | .minor = -1, |
971 | .release = video_device_release, | 971 | .release = video_device_release_empty, |
972 | }; | 972 | }; |
973 | 973 | ||
974 | static struct v4l2_m2m_ops m2m_ops = { | 974 | static struct v4l2_m2m_ops m2m_ops = { |
@@ -996,26 +996,19 @@ static int vim2m_probe(struct platform_device *pdev) | |||
996 | atomic_set(&dev->num_inst, 0); | 996 | atomic_set(&dev->num_inst, 0); |
997 | mutex_init(&dev->dev_mutex); | 997 | mutex_init(&dev->dev_mutex); |
998 | 998 | ||
999 | vfd = video_device_alloc(); | 999 | dev->vfd = vim2m_videodev; |
1000 | if (!vfd) { | 1000 | vfd = &dev->vfd; |
1001 | v4l2_err(&dev->v4l2_dev, "Failed to allocate video device\n"); | ||
1002 | ret = -ENOMEM; | ||
1003 | goto unreg_dev; | ||
1004 | } | ||
1005 | |||
1006 | *vfd = vim2m_videodev; | ||
1007 | vfd->lock = &dev->dev_mutex; | 1001 | vfd->lock = &dev->dev_mutex; |
1008 | vfd->v4l2_dev = &dev->v4l2_dev; | 1002 | vfd->v4l2_dev = &dev->v4l2_dev; |
1009 | 1003 | ||
1010 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); | 1004 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); |
1011 | if (ret) { | 1005 | if (ret) { |
1012 | v4l2_err(&dev->v4l2_dev, "Failed to register video device\n"); | 1006 | v4l2_err(&dev->v4l2_dev, "Failed to register video device\n"); |
1013 | goto rel_vdev; | 1007 | goto unreg_dev; |
1014 | } | 1008 | } |
1015 | 1009 | ||
1016 | video_set_drvdata(vfd, dev); | 1010 | video_set_drvdata(vfd, dev); |
1017 | snprintf(vfd->name, sizeof(vfd->name), "%s", vim2m_videodev.name); | 1011 | snprintf(vfd->name, sizeof(vfd->name), "%s", vim2m_videodev.name); |
1018 | dev->vfd = vfd; | ||
1019 | v4l2_info(&dev->v4l2_dev, | 1012 | v4l2_info(&dev->v4l2_dev, |
1020 | "Device registered as /dev/video%d\n", vfd->num); | 1013 | "Device registered as /dev/video%d\n", vfd->num); |
1021 | 1014 | ||
@@ -1033,9 +1026,7 @@ static int vim2m_probe(struct platform_device *pdev) | |||
1033 | 1026 | ||
1034 | err_m2m: | 1027 | err_m2m: |
1035 | v4l2_m2m_release(dev->m2m_dev); | 1028 | v4l2_m2m_release(dev->m2m_dev); |
1036 | video_unregister_device(dev->vfd); | 1029 | video_unregister_device(&dev->vfd); |
1037 | rel_vdev: | ||
1038 | video_device_release(vfd); | ||
1039 | unreg_dev: | 1030 | unreg_dev: |
1040 | v4l2_device_unregister(&dev->v4l2_dev); | 1031 | v4l2_device_unregister(&dev->v4l2_dev); |
1041 | 1032 | ||
@@ -1049,7 +1040,7 @@ static int vim2m_remove(struct platform_device *pdev) | |||
1049 | v4l2_info(&dev->v4l2_dev, "Removing " MEM2MEM_NAME); | 1040 | v4l2_info(&dev->v4l2_dev, "Removing " MEM2MEM_NAME); |
1050 | v4l2_m2m_release(dev->m2m_dev); | 1041 | v4l2_m2m_release(dev->m2m_dev); |
1051 | del_timer_sync(&dev->timer); | 1042 | del_timer_sync(&dev->timer); |
1052 | video_unregister_device(dev->vfd); | 1043 | video_unregister_device(&dev->vfd); |
1053 | v4l2_device_unregister(&dev->v4l2_dev); | 1044 | v4l2_device_unregister(&dev->v4l2_dev); |
1054 | 1045 | ||
1055 | return 0; | 1046 | return 0; |
diff --git a/drivers/media/platform/vivid/vivid-core.c b/drivers/media/platform/vivid/vivid-core.c index a7e033a5d291..d33f16495dbc 100644 --- a/drivers/media/platform/vivid/vivid-core.c +++ b/drivers/media/platform/vivid/vivid-core.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/vmalloc.h> | 26 | #include <linux/vmalloc.h> |
27 | #include <linux/font.h> | 27 | #include <linux/font.h> |
28 | #include <linux/mutex.h> | 28 | #include <linux/mutex.h> |
29 | #include <linux/platform_device.h> | ||
29 | #include <linux/videodev2.h> | 30 | #include <linux/videodev2.h> |
30 | #include <linux/v4l2-dv-timings.h> | 31 | #include <linux/v4l2-dv-timings.h> |
31 | #include <media/videobuf2-vmalloc.h> | 32 | #include <media/videobuf2-vmalloc.h> |
@@ -618,7 +619,23 @@ static const struct v4l2_ioctl_ops vivid_ioctl_ops = { | |||
618 | Initialization and module stuff | 619 | Initialization and module stuff |
619 | ------------------------------------------------------------------*/ | 620 | ------------------------------------------------------------------*/ |
620 | 621 | ||
621 | static int __init vivid_create_instance(int inst) | 622 | static void vivid_dev_release(struct v4l2_device *v4l2_dev) |
623 | { | ||
624 | struct vivid_dev *dev = container_of(v4l2_dev, struct vivid_dev, v4l2_dev); | ||
625 | |||
626 | vivid_free_controls(dev); | ||
627 | v4l2_device_unregister(&dev->v4l2_dev); | ||
628 | vfree(dev->scaled_line); | ||
629 | vfree(dev->blended_line); | ||
630 | vfree(dev->edid); | ||
631 | vfree(dev->bitmap_cap); | ||
632 | vfree(dev->bitmap_out); | ||
633 | tpg_free(&dev->tpg); | ||
634 | kfree(dev->query_dv_timings_qmenu); | ||
635 | kfree(dev); | ||
636 | } | ||
637 | |||
638 | static int vivid_create_instance(struct platform_device *pdev, int inst) | ||
622 | { | 639 | { |
623 | static const struct v4l2_dv_timings def_dv_timings = | 640 | static const struct v4l2_dv_timings def_dv_timings = |
624 | V4L2_DV_BT_CEA_1280X720P60; | 641 | V4L2_DV_BT_CEA_1280X720P60; |
@@ -646,9 +663,12 @@ static int __init vivid_create_instance(int inst) | |||
646 | /* register v4l2_device */ | 663 | /* register v4l2_device */ |
647 | snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), | 664 | snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), |
648 | "%s-%03d", VIVID_MODULE_NAME, inst); | 665 | "%s-%03d", VIVID_MODULE_NAME, inst); |
649 | ret = v4l2_device_register(NULL, &dev->v4l2_dev); | 666 | ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); |
650 | if (ret) | 667 | if (ret) { |
651 | goto free_dev; | 668 | kfree(dev); |
669 | return ret; | ||
670 | } | ||
671 | dev->v4l2_dev.release = vivid_dev_release; | ||
652 | 672 | ||
653 | /* start detecting feature set */ | 673 | /* start detecting feature set */ |
654 | 674 | ||
@@ -1256,15 +1276,8 @@ unreg_dev: | |||
1256 | video_unregister_device(&dev->vbi_cap_dev); | 1276 | video_unregister_device(&dev->vbi_cap_dev); |
1257 | video_unregister_device(&dev->vid_out_dev); | 1277 | video_unregister_device(&dev->vid_out_dev); |
1258 | video_unregister_device(&dev->vid_cap_dev); | 1278 | video_unregister_device(&dev->vid_cap_dev); |
1259 | vivid_free_controls(dev); | ||
1260 | v4l2_device_unregister(&dev->v4l2_dev); | ||
1261 | free_dev: | 1279 | free_dev: |
1262 | vfree(dev->scaled_line); | 1280 | v4l2_device_put(&dev->v4l2_dev); |
1263 | vfree(dev->blended_line); | ||
1264 | vfree(dev->edid); | ||
1265 | tpg_free(&dev->tpg); | ||
1266 | kfree(dev->query_dv_timings_qmenu); | ||
1267 | kfree(dev); | ||
1268 | return ret; | 1281 | return ret; |
1269 | } | 1282 | } |
1270 | 1283 | ||
@@ -1274,7 +1287,7 @@ free_dev: | |||
1274 | will succeed. This is limited to the maximum number of devices that | 1287 | will succeed. This is limited to the maximum number of devices that |
1275 | videodev supports, which is equal to VIDEO_NUM_DEVICES. | 1288 | videodev supports, which is equal to VIDEO_NUM_DEVICES. |
1276 | */ | 1289 | */ |
1277 | static int __init vivid_init(void) | 1290 | static int vivid_probe(struct platform_device *pdev) |
1278 | { | 1291 | { |
1279 | const struct font_desc *font = find_font("VGA8x16"); | 1292 | const struct font_desc *font = find_font("VGA8x16"); |
1280 | int ret = 0, i; | 1293 | int ret = 0, i; |
@@ -1289,7 +1302,7 @@ static int __init vivid_init(void) | |||
1289 | n_devs = clamp_t(unsigned, n_devs, 1, VIVID_MAX_DEVS); | 1302 | n_devs = clamp_t(unsigned, n_devs, 1, VIVID_MAX_DEVS); |
1290 | 1303 | ||
1291 | for (i = 0; i < n_devs; i++) { | 1304 | for (i = 0; i < n_devs; i++) { |
1292 | ret = vivid_create_instance(i); | 1305 | ret = vivid_create_instance(pdev, i); |
1293 | if (ret) { | 1306 | if (ret) { |
1294 | /* If some instantiations succeeded, keep driver */ | 1307 | /* If some instantiations succeeded, keep driver */ |
1295 | if (i) | 1308 | if (i) |
@@ -1309,7 +1322,7 @@ static int __init vivid_init(void) | |||
1309 | return ret; | 1322 | return ret; |
1310 | } | 1323 | } |
1311 | 1324 | ||
1312 | static void __exit vivid_exit(void) | 1325 | static int vivid_remove(struct platform_device *pdev) |
1313 | { | 1326 | { |
1314 | struct vivid_dev *dev; | 1327 | struct vivid_dev *dev; |
1315 | unsigned i; | 1328 | unsigned i; |
@@ -1358,18 +1371,48 @@ static void __exit vivid_exit(void) | |||
1358 | unregister_framebuffer(&dev->fb_info); | 1371 | unregister_framebuffer(&dev->fb_info); |
1359 | vivid_fb_release_buffers(dev); | 1372 | vivid_fb_release_buffers(dev); |
1360 | } | 1373 | } |
1361 | v4l2_device_unregister(&dev->v4l2_dev); | 1374 | v4l2_device_put(&dev->v4l2_dev); |
1362 | vivid_free_controls(dev); | ||
1363 | vfree(dev->scaled_line); | ||
1364 | vfree(dev->blended_line); | ||
1365 | vfree(dev->edid); | ||
1366 | vfree(dev->bitmap_cap); | ||
1367 | vfree(dev->bitmap_out); | ||
1368 | tpg_free(&dev->tpg); | ||
1369 | kfree(dev->query_dv_timings_qmenu); | ||
1370 | kfree(dev); | ||
1371 | vivid_devs[i] = NULL; | 1375 | vivid_devs[i] = NULL; |
1372 | } | 1376 | } |
1377 | return 0; | ||
1378 | } | ||
1379 | |||
1380 | static void vivid_pdev_release(struct device *dev) | ||
1381 | { | ||
1382 | } | ||
1383 | |||
1384 | static struct platform_device vivid_pdev = { | ||
1385 | .name = "vivid", | ||
1386 | .dev.release = vivid_pdev_release, | ||
1387 | }; | ||
1388 | |||
1389 | static struct platform_driver vivid_pdrv = { | ||
1390 | .probe = vivid_probe, | ||
1391 | .remove = vivid_remove, | ||
1392 | .driver = { | ||
1393 | .name = "vivid", | ||
1394 | }, | ||
1395 | }; | ||
1396 | |||
1397 | static int __init vivid_init(void) | ||
1398 | { | ||
1399 | int ret; | ||
1400 | |||
1401 | ret = platform_device_register(&vivid_pdev); | ||
1402 | if (ret) | ||
1403 | return ret; | ||
1404 | |||
1405 | ret = platform_driver_register(&vivid_pdrv); | ||
1406 | if (ret) | ||
1407 | platform_device_unregister(&vivid_pdev); | ||
1408 | |||
1409 | return ret; | ||
1410 | } | ||
1411 | |||
1412 | static void __exit vivid_exit(void) | ||
1413 | { | ||
1414 | platform_driver_unregister(&vivid_pdrv); | ||
1415 | platform_device_unregister(&vivid_pdev); | ||
1373 | } | 1416 | } |
1374 | 1417 | ||
1375 | module_init(vivid_init); | 1418 | module_init(vivid_init); |
diff --git a/drivers/media/platform/vivid/vivid-core.h b/drivers/media/platform/vivid/vivid-core.h index 4b497df4b6a4..9e15aee9a52e 100644 --- a/drivers/media/platform/vivid/vivid-core.h +++ b/drivers/media/platform/vivid/vivid-core.h | |||
@@ -79,12 +79,14 @@ extern unsigned vivid_debug; | |||
79 | struct vivid_fmt { | 79 | struct vivid_fmt { |
80 | const char *name; | 80 | const char *name; |
81 | u32 fourcc; /* v4l2 format id */ | 81 | u32 fourcc; /* v4l2 format id */ |
82 | u8 depth; | ||
83 | bool is_yuv; | 82 | bool is_yuv; |
84 | bool can_do_overlay; | 83 | bool can_do_overlay; |
84 | u8 vdownsampling[TPG_MAX_PLANES]; | ||
85 | u32 alpha_mask; | 85 | u32 alpha_mask; |
86 | u8 planes; | 86 | u8 planes; |
87 | u32 data_offset[2]; | 87 | u8 buffers; |
88 | u32 data_offset[TPG_MAX_PLANES]; | ||
89 | u32 bit_depth[TPG_MAX_PLANES]; | ||
88 | }; | 90 | }; |
89 | 91 | ||
90 | extern struct vivid_fmt vivid_formats[]; | 92 | extern struct vivid_fmt vivid_formats[]; |
@@ -332,7 +334,7 @@ struct vivid_dev { | |||
332 | u32 ycbcr_enc_out; | 334 | u32 ycbcr_enc_out; |
333 | u32 quantization_out; | 335 | u32 quantization_out; |
334 | u32 service_set_out; | 336 | u32 service_set_out; |
335 | u32 bytesperline_out[2]; | 337 | unsigned bytesperline_out[TPG_MAX_PLANES]; |
336 | unsigned tv_field_out; | 338 | unsigned tv_field_out; |
337 | unsigned tv_audio_output; | 339 | unsigned tv_audio_output; |
338 | bool vbi_out_have_wss; | 340 | bool vbi_out_have_wss; |
diff --git a/drivers/media/platform/vivid/vivid-ctrls.c b/drivers/media/platform/vivid/vivid-ctrls.c index 32a798f2d953..2b9070098b08 100644 --- a/drivers/media/platform/vivid/vivid-ctrls.c +++ b/drivers/media/platform/vivid/vivid-ctrls.c | |||
@@ -818,7 +818,7 @@ static int vivid_vid_out_s_ctrl(struct v4l2_ctrl *ctrl) | |||
818 | dev->dvi_d_out = ctrl->val == V4L2_DV_TX_MODE_DVI_D; | 818 | dev->dvi_d_out = ctrl->val == V4L2_DV_TX_MODE_DVI_D; |
819 | if (!vivid_is_hdmi_out(dev)) | 819 | if (!vivid_is_hdmi_out(dev)) |
820 | break; | 820 | break; |
821 | if (!dev->dvi_d_out && (bt->standards & V4L2_DV_BT_STD_CEA861)) { | 821 | if (!dev->dvi_d_out && (bt->flags & V4L2_DV_FL_IS_CE_VIDEO)) { |
822 | if (bt->width == 720 && bt->height <= 576) | 822 | if (bt->width == 720 && bt->height <= 576) |
823 | dev->colorspace_out = V4L2_COLORSPACE_SMPTE170M; | 823 | dev->colorspace_out = V4L2_COLORSPACE_SMPTE170M; |
824 | else | 824 | else |
diff --git a/drivers/media/platform/vivid/vivid-kthread-cap.c b/drivers/media/platform/vivid/vivid-kthread-cap.c index 39a67cfae120..1727f5453f0b 100644 --- a/drivers/media/platform/vivid/vivid-kthread-cap.c +++ b/drivers/media/platform/vivid/vivid-kthread-cap.c | |||
@@ -229,14 +229,29 @@ static void vivid_precalc_copy_rects(struct vivid_dev *dev) | |||
229 | dev->loop_vid_overlay_cap.left, dev->loop_vid_overlay_cap.top); | 229 | dev->loop_vid_overlay_cap.left, dev->loop_vid_overlay_cap.top); |
230 | } | 230 | } |
231 | 231 | ||
232 | static void *plane_vaddr(struct tpg_data *tpg, struct vivid_buffer *buf, | ||
233 | unsigned p, unsigned bpl[TPG_MAX_PLANES], unsigned h) | ||
234 | { | ||
235 | unsigned i; | ||
236 | void *vbuf; | ||
237 | |||
238 | if (p == 0 || tpg_g_buffers(tpg) > 1) | ||
239 | return vb2_plane_vaddr(&buf->vb, p); | ||
240 | vbuf = vb2_plane_vaddr(&buf->vb, 0); | ||
241 | for (i = 0; i < p; i++) | ||
242 | vbuf += bpl[i] * h / tpg->vdownsampling[i]; | ||
243 | return vbuf; | ||
244 | } | ||
245 | |||
232 | static int vivid_copy_buffer(struct vivid_dev *dev, unsigned p, u8 *vcapbuf, | 246 | static int vivid_copy_buffer(struct vivid_dev *dev, unsigned p, u8 *vcapbuf, |
233 | struct vivid_buffer *vid_cap_buf) | 247 | struct vivid_buffer *vid_cap_buf) |
234 | { | 248 | { |
235 | bool blank = dev->must_blank[vid_cap_buf->vb.v4l2_buf.index]; | 249 | bool blank = dev->must_blank[vid_cap_buf->vb.v4l2_buf.index]; |
236 | struct tpg_data *tpg = &dev->tpg; | 250 | struct tpg_data *tpg = &dev->tpg; |
237 | struct vivid_buffer *vid_out_buf = NULL; | 251 | struct vivid_buffer *vid_out_buf = NULL; |
238 | unsigned pixsize = tpg_g_twopixelsize(tpg, p) / 2; | 252 | unsigned vdiv = dev->fmt_out->vdownsampling[p]; |
239 | unsigned img_width = dev->compose_cap.width; | 253 | unsigned twopixsize = tpg_g_twopixelsize(tpg, p); |
254 | unsigned img_width = tpg_hdiv(tpg, p, dev->compose_cap.width); | ||
240 | unsigned img_height = dev->compose_cap.height; | 255 | unsigned img_height = dev->compose_cap.height; |
241 | unsigned stride_cap = tpg->bytesperline[p]; | 256 | unsigned stride_cap = tpg->bytesperline[p]; |
242 | unsigned stride_out = dev->bytesperline_out[p]; | 257 | unsigned stride_out = dev->bytesperline_out[p]; |
@@ -255,6 +270,7 @@ static int vivid_copy_buffer(struct vivid_dev *dev, unsigned p, u8 *vcapbuf, | |||
255 | unsigned vid_overlay_fract_part = 0; | 270 | unsigned vid_overlay_fract_part = 0; |
256 | unsigned vid_overlay_y = 0; | 271 | unsigned vid_overlay_y = 0; |
257 | unsigned vid_overlay_error = 0; | 272 | unsigned vid_overlay_error = 0; |
273 | unsigned vid_cap_left = tpg_hdiv(tpg, p, dev->loop_vid_cap.left); | ||
258 | unsigned vid_cap_right; | 274 | unsigned vid_cap_right; |
259 | bool quick; | 275 | bool quick; |
260 | 276 | ||
@@ -269,25 +285,29 @@ static int vivid_copy_buffer(struct vivid_dev *dev, unsigned p, u8 *vcapbuf, | |||
269 | 285 | ||
270 | vid_cap_buf->vb.v4l2_buf.field = vid_out_buf->vb.v4l2_buf.field; | 286 | vid_cap_buf->vb.v4l2_buf.field = vid_out_buf->vb.v4l2_buf.field; |
271 | 287 | ||
272 | voutbuf = vb2_plane_vaddr(&vid_out_buf->vb, p) + | 288 | voutbuf = plane_vaddr(tpg, vid_out_buf, p, |
273 | vid_out_buf->vb.v4l2_planes[p].data_offset; | 289 | dev->bytesperline_out, dev->fmt_out_rect.height); |
274 | voutbuf += dev->loop_vid_out.left * pixsize + dev->loop_vid_out.top * stride_out; | 290 | if (p < dev->fmt_out->buffers) |
275 | vcapbuf += dev->compose_cap.left * pixsize + dev->compose_cap.top * stride_cap; | 291 | voutbuf += vid_out_buf->vb.v4l2_planes[p].data_offset; |
292 | voutbuf += tpg_hdiv(tpg, p, dev->loop_vid_out.left) + | ||
293 | (dev->loop_vid_out.top / vdiv) * stride_out; | ||
294 | vcapbuf += tpg_hdiv(tpg, p, dev->compose_cap.left) + | ||
295 | (dev->compose_cap.top / vdiv) * stride_cap; | ||
276 | 296 | ||
277 | if (dev->loop_vid_copy.width == 0 || dev->loop_vid_copy.height == 0) { | 297 | if (dev->loop_vid_copy.width == 0 || dev->loop_vid_copy.height == 0) { |
278 | /* | 298 | /* |
279 | * If there is nothing to copy, then just fill the capture window | 299 | * If there is nothing to copy, then just fill the capture window |
280 | * with black. | 300 | * with black. |
281 | */ | 301 | */ |
282 | for (y = 0; y < hmax; y++, vcapbuf += stride_cap) | 302 | for (y = 0; y < hmax / vdiv; y++, vcapbuf += stride_cap) |
283 | memcpy(vcapbuf, tpg->black_line[p], img_width * pixsize); | 303 | memcpy(vcapbuf, tpg->black_line[p], img_width); |
284 | return 0; | 304 | return 0; |
285 | } | 305 | } |
286 | 306 | ||
287 | if (dev->overlay_out_enabled && | 307 | if (dev->overlay_out_enabled && |
288 | dev->loop_vid_overlay.width && dev->loop_vid_overlay.height) { | 308 | dev->loop_vid_overlay.width && dev->loop_vid_overlay.height) { |
289 | vosdbuf = dev->video_vbase; | 309 | vosdbuf = dev->video_vbase; |
290 | vosdbuf += dev->loop_fb_copy.left * pixsize + | 310 | vosdbuf += (dev->loop_fb_copy.left * twopixsize) / 2 + |
291 | dev->loop_fb_copy.top * stride_osd; | 311 | dev->loop_fb_copy.top * stride_osd; |
292 | vid_overlay_int_part = dev->loop_vid_overlay.height / | 312 | vid_overlay_int_part = dev->loop_vid_overlay.height / |
293 | dev->loop_vid_overlay_cap.height; | 313 | dev->loop_vid_overlay_cap.height; |
@@ -295,12 +315,12 @@ static int vivid_copy_buffer(struct vivid_dev *dev, unsigned p, u8 *vcapbuf, | |||
295 | dev->loop_vid_overlay_cap.height; | 315 | dev->loop_vid_overlay_cap.height; |
296 | } | 316 | } |
297 | 317 | ||
298 | vid_cap_right = dev->loop_vid_cap.left + dev->loop_vid_cap.width; | 318 | vid_cap_right = tpg_hdiv(tpg, p, dev->loop_vid_cap.left + dev->loop_vid_cap.width); |
299 | /* quick is true if no video scaling is needed */ | 319 | /* quick is true if no video scaling is needed */ |
300 | quick = dev->loop_vid_out.width == dev->loop_vid_cap.width; | 320 | quick = dev->loop_vid_out.width == dev->loop_vid_cap.width; |
301 | 321 | ||
302 | dev->cur_scaled_line = dev->loop_vid_out.height; | 322 | dev->cur_scaled_line = dev->loop_vid_out.height; |
303 | for (y = 0; y < hmax; y++, vcapbuf += stride_cap) { | 323 | for (y = 0; y < hmax; y += vdiv, vcapbuf += stride_cap) { |
304 | /* osdline is true if this line requires overlay blending */ | 324 | /* osdline is true if this line requires overlay blending */ |
305 | bool osdline = vosdbuf && y >= dev->loop_vid_overlay_cap.top && | 325 | bool osdline = vosdbuf && y >= dev->loop_vid_overlay_cap.top && |
306 | y < dev->loop_vid_overlay_cap.top + dev->loop_vid_overlay_cap.height; | 326 | y < dev->loop_vid_overlay_cap.top + dev->loop_vid_overlay_cap.height; |
@@ -311,34 +331,34 @@ static int vivid_copy_buffer(struct vivid_dev *dev, unsigned p, u8 *vcapbuf, | |||
311 | */ | 331 | */ |
312 | if (y < dev->loop_vid_cap.top || | 332 | if (y < dev->loop_vid_cap.top || |
313 | y >= dev->loop_vid_cap.top + dev->loop_vid_cap.height) { | 333 | y >= dev->loop_vid_cap.top + dev->loop_vid_cap.height) { |
314 | memcpy(vcapbuf, tpg->black_line[p], img_width * pixsize); | 334 | memcpy(vcapbuf, tpg->black_line[p], img_width); |
315 | continue; | 335 | continue; |
316 | } | 336 | } |
317 | 337 | ||
318 | /* fill the left border with black */ | 338 | /* fill the left border with black */ |
319 | if (dev->loop_vid_cap.left) | 339 | if (dev->loop_vid_cap.left) |
320 | memcpy(vcapbuf, tpg->black_line[p], dev->loop_vid_cap.left * pixsize); | 340 | memcpy(vcapbuf, tpg->black_line[p], vid_cap_left); |
321 | 341 | ||
322 | /* fill the right border with black */ | 342 | /* fill the right border with black */ |
323 | if (vid_cap_right < img_width) | 343 | if (vid_cap_right < img_width) |
324 | memcpy(vcapbuf + vid_cap_right * pixsize, | 344 | memcpy(vcapbuf + vid_cap_right, tpg->black_line[p], |
325 | tpg->black_line[p], (img_width - vid_cap_right) * pixsize); | 345 | img_width - vid_cap_right); |
326 | 346 | ||
327 | if (quick && !osdline) { | 347 | if (quick && !osdline) { |
328 | memcpy(vcapbuf + dev->loop_vid_cap.left * pixsize, | 348 | memcpy(vcapbuf + vid_cap_left, |
329 | voutbuf + vid_out_y * stride_out, | 349 | voutbuf + vid_out_y * stride_out, |
330 | dev->loop_vid_cap.width * pixsize); | 350 | tpg_hdiv(tpg, p, dev->loop_vid_cap.width)); |
331 | goto update_vid_out_y; | 351 | goto update_vid_out_y; |
332 | } | 352 | } |
333 | if (dev->cur_scaled_line == vid_out_y) { | 353 | if (dev->cur_scaled_line == vid_out_y) { |
334 | memcpy(vcapbuf + dev->loop_vid_cap.left * pixsize, | 354 | memcpy(vcapbuf + vid_cap_left, dev->scaled_line, |
335 | dev->scaled_line, | 355 | tpg_hdiv(tpg, p, dev->loop_vid_cap.width)); |
336 | dev->loop_vid_cap.width * pixsize); | ||
337 | goto update_vid_out_y; | 356 | goto update_vid_out_y; |
338 | } | 357 | } |
339 | if (!osdline) { | 358 | if (!osdline) { |
340 | scale_line(voutbuf + vid_out_y * stride_out, dev->scaled_line, | 359 | scale_line(voutbuf + vid_out_y * stride_out, dev->scaled_line, |
341 | dev->loop_vid_out.width, dev->loop_vid_cap.width, | 360 | tpg_hdiv(tpg, p, dev->loop_vid_out.width), |
361 | tpg_hdiv(tpg, p, dev->loop_vid_cap.width), | ||
342 | tpg_g_twopixelsize(tpg, p)); | 362 | tpg_g_twopixelsize(tpg, p)); |
343 | } else { | 363 | } else { |
344 | /* | 364 | /* |
@@ -346,7 +366,8 @@ static int vivid_copy_buffer(struct vivid_dev *dev, unsigned p, u8 *vcapbuf, | |||
346 | * loop_vid_overlay rectangle. | 366 | * loop_vid_overlay rectangle. |
347 | */ | 367 | */ |
348 | unsigned offset = | 368 | unsigned offset = |
349 | (dev->loop_vid_overlay.left - dev->loop_vid_copy.left) * pixsize; | 369 | ((dev->loop_vid_overlay.left - dev->loop_vid_copy.left) * |
370 | twopixsize) / 2; | ||
350 | u8 *osd = vosdbuf + vid_overlay_y * stride_osd; | 371 | u8 *osd = vosdbuf + vid_overlay_y * stride_osd; |
351 | 372 | ||
352 | scale_line(voutbuf + vid_out_y * stride_out, dev->blended_line, | 373 | scale_line(voutbuf + vid_out_y * stride_out, dev->blended_line, |
@@ -356,18 +377,17 @@ static int vivid_copy_buffer(struct vivid_dev *dev, unsigned p, u8 *vcapbuf, | |||
356 | blend_line(dev, vid_overlay_y + dev->loop_vid_overlay.top, | 377 | blend_line(dev, vid_overlay_y + dev->loop_vid_overlay.top, |
357 | dev->loop_vid_overlay.left, | 378 | dev->loop_vid_overlay.left, |
358 | dev->blended_line + offset, osd, | 379 | dev->blended_line + offset, osd, |
359 | dev->loop_vid_overlay.width, pixsize); | 380 | dev->loop_vid_overlay.width, twopixsize / 2); |
360 | else | 381 | else |
361 | memcpy(dev->blended_line + offset, | 382 | memcpy(dev->blended_line + offset, |
362 | osd, dev->loop_vid_overlay.width * pixsize); | 383 | osd, (dev->loop_vid_overlay.width * twopixsize) / 2); |
363 | scale_line(dev->blended_line, dev->scaled_line, | 384 | scale_line(dev->blended_line, dev->scaled_line, |
364 | dev->loop_vid_copy.width, dev->loop_vid_cap.width, | 385 | dev->loop_vid_copy.width, dev->loop_vid_cap.width, |
365 | tpg_g_twopixelsize(tpg, p)); | 386 | tpg_g_twopixelsize(tpg, p)); |
366 | } | 387 | } |
367 | dev->cur_scaled_line = vid_out_y; | 388 | dev->cur_scaled_line = vid_out_y; |
368 | memcpy(vcapbuf + dev->loop_vid_cap.left * pixsize, | 389 | memcpy(vcapbuf + vid_cap_left, dev->scaled_line, |
369 | dev->scaled_line, | 390 | tpg_hdiv(tpg, p, dev->loop_vid_cap.width)); |
370 | dev->loop_vid_cap.width * pixsize); | ||
371 | 391 | ||
372 | update_vid_out_y: | 392 | update_vid_out_y: |
373 | if (osdline) { | 393 | if (osdline) { |
@@ -380,21 +400,22 @@ update_vid_out_y: | |||
380 | } | 400 | } |
381 | vid_out_y += vid_out_int_part; | 401 | vid_out_y += vid_out_int_part; |
382 | vid_out_error += vid_out_fract_part; | 402 | vid_out_error += vid_out_fract_part; |
383 | if (vid_out_error >= dev->loop_vid_cap.height) { | 403 | if (vid_out_error >= dev->loop_vid_cap.height / vdiv) { |
384 | vid_out_error -= dev->loop_vid_cap.height; | 404 | vid_out_error -= dev->loop_vid_cap.height / vdiv; |
385 | vid_out_y++; | 405 | vid_out_y++; |
386 | } | 406 | } |
387 | } | 407 | } |
388 | 408 | ||
389 | if (!blank) | 409 | if (!blank) |
390 | return 0; | 410 | return 0; |
391 | for (; y < img_height; y++, vcapbuf += stride_cap) | 411 | for (; y < img_height; y += vdiv, vcapbuf += stride_cap) |
392 | memcpy(vcapbuf, tpg->contrast_line[p], img_width * pixsize); | 412 | memcpy(vcapbuf, tpg->contrast_line[p], img_width); |
393 | return 0; | 413 | return 0; |
394 | } | 414 | } |
395 | 415 | ||
396 | static void vivid_fillbuff(struct vivid_dev *dev, struct vivid_buffer *buf) | 416 | static void vivid_fillbuff(struct vivid_dev *dev, struct vivid_buffer *buf) |
397 | { | 417 | { |
418 | struct tpg_data *tpg = &dev->tpg; | ||
398 | unsigned factor = V4L2_FIELD_HAS_T_OR_B(dev->field_cap) ? 2 : 1; | 419 | unsigned factor = V4L2_FIELD_HAS_T_OR_B(dev->field_cap) ? 2 : 1; |
399 | unsigned line_height = 16 / factor; | 420 | unsigned line_height = 16 / factor; |
400 | bool is_tv = vivid_is_sdtv_cap(dev); | 421 | bool is_tv = vivid_is_sdtv_cap(dev); |
@@ -427,7 +448,7 @@ static void vivid_fillbuff(struct vivid_dev *dev, struct vivid_buffer *buf) | |||
427 | * standards. | 448 | * standards. |
428 | */ | 449 | */ |
429 | buf->vb.v4l2_buf.field = ((dev->vid_cap_seq_count & 1) ^ is_60hz) ? | 450 | buf->vb.v4l2_buf.field = ((dev->vid_cap_seq_count & 1) ^ is_60hz) ? |
430 | V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM; | 451 | V4L2_FIELD_BOTTOM : V4L2_FIELD_TOP; |
431 | /* | 452 | /* |
432 | * The sequence counter counts frames, not fields. So divide | 453 | * The sequence counter counts frames, not fields. So divide |
433 | * by two. | 454 | * by two. |
@@ -436,27 +457,29 @@ static void vivid_fillbuff(struct vivid_dev *dev, struct vivid_buffer *buf) | |||
436 | } else { | 457 | } else { |
437 | buf->vb.v4l2_buf.field = dev->field_cap; | 458 | buf->vb.v4l2_buf.field = dev->field_cap; |
438 | } | 459 | } |
439 | tpg_s_field(&dev->tpg, buf->vb.v4l2_buf.field); | 460 | tpg_s_field(tpg, buf->vb.v4l2_buf.field, |
440 | tpg_s_perc_fill_blank(&dev->tpg, dev->must_blank[buf->vb.v4l2_buf.index]); | 461 | dev->field_cap == V4L2_FIELD_ALTERNATE); |
462 | tpg_s_perc_fill_blank(tpg, dev->must_blank[buf->vb.v4l2_buf.index]); | ||
441 | 463 | ||
442 | vivid_precalc_copy_rects(dev); | 464 | vivid_precalc_copy_rects(dev); |
443 | 465 | ||
444 | for (p = 0; p < tpg_g_planes(&dev->tpg); p++) { | 466 | for (p = 0; p < tpg_g_planes(tpg); p++) { |
445 | void *vbuf = vb2_plane_vaddr(&buf->vb, p); | 467 | void *vbuf = plane_vaddr(tpg, buf, p, |
468 | tpg->bytesperline, tpg->buf_height); | ||
446 | 469 | ||
447 | /* | 470 | /* |
448 | * The first plane of a multiplanar format has a non-zero | 471 | * The first plane of a multiplanar format has a non-zero |
449 | * data_offset. This helps testing whether the application | 472 | * data_offset. This helps testing whether the application |
450 | * correctly supports non-zero data offsets. | 473 | * correctly supports non-zero data offsets. |
451 | */ | 474 | */ |
452 | if (dev->fmt_cap->data_offset[p]) { | 475 | if (p < tpg_g_buffers(tpg) && dev->fmt_cap->data_offset[p]) { |
453 | memset(vbuf, dev->fmt_cap->data_offset[p] & 0xff, | 476 | memset(vbuf, dev->fmt_cap->data_offset[p] & 0xff, |
454 | dev->fmt_cap->data_offset[p]); | 477 | dev->fmt_cap->data_offset[p]); |
455 | vbuf += dev->fmt_cap->data_offset[p]; | 478 | vbuf += dev->fmt_cap->data_offset[p]; |
456 | } | 479 | } |
457 | tpg_calc_text_basep(&dev->tpg, basep, p, vbuf); | 480 | tpg_calc_text_basep(tpg, basep, p, vbuf); |
458 | if (!is_loop || vivid_copy_buffer(dev, p, vbuf, buf)) | 481 | if (!is_loop || vivid_copy_buffer(dev, p, vbuf, buf)) |
459 | tpg_fillbuffer(&dev->tpg, vivid_get_std_cap(dev), p, vbuf); | 482 | tpg_fill_plane_buffer(tpg, vivid_get_std_cap(dev), p, vbuf); |
460 | } | 483 | } |
461 | dev->must_blank[buf->vb.v4l2_buf.index] = false; | 484 | dev->must_blank[buf->vb.v4l2_buf.index] = false; |
462 | 485 | ||
@@ -475,12 +498,12 @@ static void vivid_fillbuff(struct vivid_dev *dev, struct vivid_buffer *buf) | |||
475 | (dev->field_cap == V4L2_FIELD_ALTERNATE) ? | 498 | (dev->field_cap == V4L2_FIELD_ALTERNATE) ? |
476 | (buf->vb.v4l2_buf.field == V4L2_FIELD_TOP ? | 499 | (buf->vb.v4l2_buf.field == V4L2_FIELD_TOP ? |
477 | " top" : " bottom") : ""); | 500 | " top" : " bottom") : ""); |
478 | tpg_gen_text(&dev->tpg, basep, line++ * line_height, 16, str); | 501 | tpg_gen_text(tpg, basep, line++ * line_height, 16, str); |
479 | } | 502 | } |
480 | if (dev->osd_mode == 0) { | 503 | if (dev->osd_mode == 0) { |
481 | snprintf(str, sizeof(str), " %dx%d, input %d ", | 504 | snprintf(str, sizeof(str), " %dx%d, input %d ", |
482 | dev->src_rect.width, dev->src_rect.height, dev->input); | 505 | dev->src_rect.width, dev->src_rect.height, dev->input); |
483 | tpg_gen_text(&dev->tpg, basep, line++ * line_height, 16, str); | 506 | tpg_gen_text(tpg, basep, line++ * line_height, 16, str); |
484 | 507 | ||
485 | gain = v4l2_ctrl_g_ctrl(dev->gain); | 508 | gain = v4l2_ctrl_g_ctrl(dev->gain); |
486 | mutex_lock(dev->ctrl_hdl_user_vid.lock); | 509 | mutex_lock(dev->ctrl_hdl_user_vid.lock); |
@@ -490,38 +513,38 @@ static void vivid_fillbuff(struct vivid_dev *dev, struct vivid_buffer *buf) | |||
490 | dev->contrast->cur.val, | 513 | dev->contrast->cur.val, |
491 | dev->saturation->cur.val, | 514 | dev->saturation->cur.val, |
492 | dev->hue->cur.val); | 515 | dev->hue->cur.val); |
493 | tpg_gen_text(&dev->tpg, basep, line++ * line_height, 16, str); | 516 | tpg_gen_text(tpg, basep, line++ * line_height, 16, str); |
494 | snprintf(str, sizeof(str), | 517 | snprintf(str, sizeof(str), |
495 | " autogain %d, gain %3d, alpha 0x%02x ", | 518 | " autogain %d, gain %3d, alpha 0x%02x ", |
496 | dev->autogain->cur.val, gain, dev->alpha->cur.val); | 519 | dev->autogain->cur.val, gain, dev->alpha->cur.val); |
497 | mutex_unlock(dev->ctrl_hdl_user_vid.lock); | 520 | mutex_unlock(dev->ctrl_hdl_user_vid.lock); |
498 | tpg_gen_text(&dev->tpg, basep, line++ * line_height, 16, str); | 521 | tpg_gen_text(tpg, basep, line++ * line_height, 16, str); |
499 | mutex_lock(dev->ctrl_hdl_user_aud.lock); | 522 | mutex_lock(dev->ctrl_hdl_user_aud.lock); |
500 | snprintf(str, sizeof(str), | 523 | snprintf(str, sizeof(str), |
501 | " volume %3d, mute %d ", | 524 | " volume %3d, mute %d ", |
502 | dev->volume->cur.val, dev->mute->cur.val); | 525 | dev->volume->cur.val, dev->mute->cur.val); |
503 | mutex_unlock(dev->ctrl_hdl_user_aud.lock); | 526 | mutex_unlock(dev->ctrl_hdl_user_aud.lock); |
504 | tpg_gen_text(&dev->tpg, basep, line++ * line_height, 16, str); | 527 | tpg_gen_text(tpg, basep, line++ * line_height, 16, str); |
505 | mutex_lock(dev->ctrl_hdl_user_gen.lock); | 528 | mutex_lock(dev->ctrl_hdl_user_gen.lock); |
506 | snprintf(str, sizeof(str), " int32 %d, int64 %lld, bitmask %08x ", | 529 | snprintf(str, sizeof(str), " int32 %d, int64 %lld, bitmask %08x ", |
507 | dev->int32->cur.val, | 530 | dev->int32->cur.val, |
508 | *dev->int64->p_cur.p_s64, | 531 | *dev->int64->p_cur.p_s64, |
509 | dev->bitmask->cur.val); | 532 | dev->bitmask->cur.val); |
510 | tpg_gen_text(&dev->tpg, basep, line++ * line_height, 16, str); | 533 | tpg_gen_text(tpg, basep, line++ * line_height, 16, str); |
511 | snprintf(str, sizeof(str), " boolean %d, menu %s, string \"%s\" ", | 534 | snprintf(str, sizeof(str), " boolean %d, menu %s, string \"%s\" ", |
512 | dev->boolean->cur.val, | 535 | dev->boolean->cur.val, |
513 | dev->menu->qmenu[dev->menu->cur.val], | 536 | dev->menu->qmenu[dev->menu->cur.val], |
514 | dev->string->p_cur.p_char); | 537 | dev->string->p_cur.p_char); |
515 | tpg_gen_text(&dev->tpg, basep, line++ * line_height, 16, str); | 538 | tpg_gen_text(tpg, basep, line++ * line_height, 16, str); |
516 | snprintf(str, sizeof(str), " integer_menu %lld, value %d ", | 539 | snprintf(str, sizeof(str), " integer_menu %lld, value %d ", |
517 | dev->int_menu->qmenu_int[dev->int_menu->cur.val], | 540 | dev->int_menu->qmenu_int[dev->int_menu->cur.val], |
518 | dev->int_menu->cur.val); | 541 | dev->int_menu->cur.val); |
519 | mutex_unlock(dev->ctrl_hdl_user_gen.lock); | 542 | mutex_unlock(dev->ctrl_hdl_user_gen.lock); |
520 | tpg_gen_text(&dev->tpg, basep, line++ * line_height, 16, str); | 543 | tpg_gen_text(tpg, basep, line++ * line_height, 16, str); |
521 | if (dev->button_pressed) { | 544 | if (dev->button_pressed) { |
522 | dev->button_pressed--; | 545 | dev->button_pressed--; |
523 | snprintf(str, sizeof(str), " button pressed!"); | 546 | snprintf(str, sizeof(str), " button pressed!"); |
524 | tpg_gen_text(&dev->tpg, basep, line++ * line_height, 16, str); | 547 | tpg_gen_text(tpg, basep, line++ * line_height, 16, str); |
525 | } | 548 | } |
526 | } | 549 | } |
527 | 550 | ||
@@ -585,6 +608,12 @@ static void vivid_overlay(struct vivid_dev *dev, struct vivid_buffer *buf) | |||
585 | bool quick = dev->bitmap_cap == NULL && dev->clipcount_cap == 0; | 608 | bool quick = dev->bitmap_cap == NULL && dev->clipcount_cap == 0; |
586 | int x, y, w, out_x = 0; | 609 | int x, y, w, out_x = 0; |
587 | 610 | ||
611 | /* | ||
612 | * Overlay support is only supported for formats that have a twopixelsize | ||
613 | * that's >= 2. Warn and bail out if that's not the case. | ||
614 | */ | ||
615 | if (WARN_ON(pixsize == 0)) | ||
616 | return; | ||
588 | if ((dev->overlay_cap_field == V4L2_FIELD_TOP || | 617 | if ((dev->overlay_cap_field == V4L2_FIELD_TOP || |
589 | dev->overlay_cap_field == V4L2_FIELD_BOTTOM) && | 618 | dev->overlay_cap_field == V4L2_FIELD_BOTTOM) && |
590 | dev->overlay_cap_field != buf->vb.v4l2_buf.field) | 619 | dev->overlay_cap_field != buf->vb.v4l2_buf.field) |
diff --git a/drivers/media/platform/vivid/vivid-sdr-cap.c b/drivers/media/platform/vivid/vivid-sdr-cap.c index 4af55f18829f..caf131666e37 100644 --- a/drivers/media/platform/vivid/vivid-sdr-cap.c +++ b/drivers/media/platform/vivid/vivid-sdr-cap.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <media/v4l2-common.h> | 27 | #include <media/v4l2-common.h> |
28 | #include <media/v4l2-event.h> | 28 | #include <media/v4l2-event.h> |
29 | #include <media/v4l2-dv-timings.h> | 29 | #include <media/v4l2-dv-timings.h> |
30 | #include <linux/fixp-arith.h> | ||
30 | 31 | ||
31 | #include "vivid-core.h" | 32 | #include "vivid-core.h" |
32 | #include "vivid-ctrls.h" | 33 | #include "vivid-ctrls.h" |
@@ -423,40 +424,19 @@ int vidioc_g_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f) | |||
423 | return 0; | 424 | return 0; |
424 | } | 425 | } |
425 | 426 | ||
426 | #define FIXP_FRAC (1 << 15) | 427 | #define FIXP_N (15) |
427 | #define FIXP_PI ((int)(FIXP_FRAC * 3.141592653589)) | 428 | #define FIXP_FRAC (1 << FIXP_N) |
428 | 429 | #define FIXP_2PI ((int)(2 * 3.141592653589 * FIXP_FRAC)) | |
429 | /* cos() from cx88 driver: cx88-dsp.c */ | ||
430 | static s32 fixp_cos(unsigned int x) | ||
431 | { | ||
432 | u32 t2, t4, t6, t8; | ||
433 | u16 period = x / FIXP_PI; | ||
434 | |||
435 | if (period % 2) | ||
436 | return -fixp_cos(x - FIXP_PI); | ||
437 | x = x % FIXP_PI; | ||
438 | if (x > FIXP_PI/2) | ||
439 | return -fixp_cos(FIXP_PI/2 - (x % (FIXP_PI/2))); | ||
440 | /* Now x is between 0 and FIXP_PI/2. | ||
441 | * To calculate cos(x) we use it's Taylor polinom. */ | ||
442 | t2 = x*x/FIXP_FRAC/2; | ||
443 | t4 = t2*x/FIXP_FRAC*x/FIXP_FRAC/3/4; | ||
444 | t6 = t4*x/FIXP_FRAC*x/FIXP_FRAC/5/6; | ||
445 | t8 = t6*x/FIXP_FRAC*x/FIXP_FRAC/7/8; | ||
446 | return FIXP_FRAC-t2+t4-t6+t8; | ||
447 | } | ||
448 | |||
449 | static inline s32 fixp_sin(unsigned int x) | ||
450 | { | ||
451 | return -fixp_cos(x + (FIXP_PI / 2)); | ||
452 | } | ||
453 | 430 | ||
454 | void vivid_sdr_cap_process(struct vivid_dev *dev, struct vivid_buffer *buf) | 431 | void vivid_sdr_cap_process(struct vivid_dev *dev, struct vivid_buffer *buf) |
455 | { | 432 | { |
456 | u8 *vbuf = vb2_plane_vaddr(&buf->vb, 0); | 433 | u8 *vbuf = vb2_plane_vaddr(&buf->vb, 0); |
457 | unsigned long i; | 434 | unsigned long i; |
458 | unsigned long plane_size = vb2_plane_size(&buf->vb, 0); | 435 | unsigned long plane_size = vb2_plane_size(&buf->vb, 0); |
459 | int fixp_src_phase_step, fixp_i, fixp_q; | 436 | s32 src_phase_step; |
437 | s32 mod_phase_step; | ||
438 | s32 fixp_i; | ||
439 | s32 fixp_q; | ||
460 | 440 | ||
461 | /* | 441 | /* |
462 | * TODO: Generated beep tone goes very crackly when sample rate is | 442 | * TODO: Generated beep tone goes very crackly when sample rate is |
@@ -466,28 +446,36 @@ void vivid_sdr_cap_process(struct vivid_dev *dev, struct vivid_buffer *buf) | |||
466 | 446 | ||
467 | /* calculate phase step */ | 447 | /* calculate phase step */ |
468 | #define BEEP_FREQ 1000 /* 1kHz beep */ | 448 | #define BEEP_FREQ 1000 /* 1kHz beep */ |
469 | fixp_src_phase_step = DIV_ROUND_CLOSEST(2 * FIXP_PI * BEEP_FREQ, | 449 | src_phase_step = DIV_ROUND_CLOSEST(FIXP_2PI * BEEP_FREQ, |
470 | dev->sdr_adc_freq); | 450 | dev->sdr_adc_freq); |
471 | 451 | ||
472 | for (i = 0; i < plane_size; i += 2) { | 452 | for (i = 0; i < plane_size; i += 2) { |
473 | dev->sdr_fixp_mod_phase += fixp_cos(dev->sdr_fixp_src_phase); | 453 | mod_phase_step = fixp_cos32_rad(dev->sdr_fixp_src_phase, |
474 | dev->sdr_fixp_src_phase += fixp_src_phase_step; | 454 | FIXP_2PI) >> (31 - FIXP_N); |
455 | |||
456 | dev->sdr_fixp_src_phase += src_phase_step; | ||
457 | dev->sdr_fixp_mod_phase += mod_phase_step / 4; | ||
475 | 458 | ||
476 | /* | 459 | /* |
477 | * Transfer phases to [0 / 2xPI] in order to avoid variable | 460 | * Transfer phases to [0 / 2xPI] in order to avoid variable |
478 | * overflow and make it suitable for cosine implementation | 461 | * overflow and make it suitable for cosine implementation |
479 | * used, which does not support negative angles. | 462 | * used, which does not support negative angles. |
480 | */ | 463 | */ |
481 | while (dev->sdr_fixp_mod_phase < (0 * FIXP_PI)) | 464 | while (dev->sdr_fixp_mod_phase < FIXP_2PI) |
482 | dev->sdr_fixp_mod_phase += (2 * FIXP_PI); | 465 | dev->sdr_fixp_mod_phase += FIXP_2PI; |
483 | while (dev->sdr_fixp_mod_phase > (2 * FIXP_PI)) | 466 | while (dev->sdr_fixp_mod_phase > FIXP_2PI) |
484 | dev->sdr_fixp_mod_phase -= (2 * FIXP_PI); | 467 | dev->sdr_fixp_mod_phase -= FIXP_2PI; |
468 | |||
469 | while (dev->sdr_fixp_src_phase > FIXP_2PI) | ||
470 | dev->sdr_fixp_src_phase -= FIXP_2PI; | ||
485 | 471 | ||
486 | while (dev->sdr_fixp_src_phase > (2 * FIXP_PI)) | 472 | fixp_i = fixp_cos32_rad(dev->sdr_fixp_mod_phase, FIXP_2PI); |
487 | dev->sdr_fixp_src_phase -= (2 * FIXP_PI); | 473 | fixp_q = fixp_sin32_rad(dev->sdr_fixp_mod_phase, FIXP_2PI); |
488 | 474 | ||
489 | fixp_i = fixp_cos(dev->sdr_fixp_mod_phase); | 475 | /* Normalize fraction values represented with 32 bit precision |
490 | fixp_q = fixp_sin(dev->sdr_fixp_mod_phase); | 476 | * to fixed point representation with FIXP_N bits */ |
477 | fixp_i >>= (31 - FIXP_N); | ||
478 | fixp_q >>= (31 - FIXP_N); | ||
491 | 479 | ||
492 | /* convert 'fixp float' to u8 */ | 480 | /* convert 'fixp float' to u8 */ |
493 | /* u8 = X * 127.5f + 127.5f; where X is float [-1.0 / +1.0] */ | 481 | /* u8 = X * 127.5f + 127.5f; where X is float [-1.0 / +1.0] */ |
diff --git a/drivers/media/platform/vivid/vivid-tpg.c b/drivers/media/platform/vivid/vivid-tpg.c index 34493f435d5a..cb766eb154e7 100644 --- a/drivers/media/platform/vivid/vivid-tpg.c +++ b/drivers/media/platform/vivid/vivid-tpg.c | |||
@@ -35,7 +35,10 @@ const char * const tpg_pattern_strings[] = { | |||
35 | "100% Green", | 35 | "100% Green", |
36 | "100% Blue", | 36 | "100% Blue", |
37 | "16x16 Checkers", | 37 | "16x16 Checkers", |
38 | "2x2 Checkers", | ||
38 | "1x1 Checkers", | 39 | "1x1 Checkers", |
40 | "2x2 Red/Green Checkers", | ||
41 | "1x1 Red/Green Checkers", | ||
39 | "Alternating Hor Lines", | 42 | "Alternating Hor Lines", |
40 | "Alternating Vert Lines", | 43 | "Alternating Vert Lines", |
41 | "One Pixel Wide Cross", | 44 | "One Pixel Wide Cross", |
@@ -120,15 +123,20 @@ int tpg_alloc(struct tpg_data *tpg, unsigned max_w) | |||
120 | tpg->max_line_width = max_w; | 123 | tpg->max_line_width = max_w; |
121 | for (pat = 0; pat < TPG_MAX_PAT_LINES; pat++) { | 124 | for (pat = 0; pat < TPG_MAX_PAT_LINES; pat++) { |
122 | for (plane = 0; plane < TPG_MAX_PLANES; plane++) { | 125 | for (plane = 0; plane < TPG_MAX_PLANES; plane++) { |
123 | unsigned pixelsz = plane ? 1 : 4; | 126 | unsigned pixelsz = plane ? 2 : 4; |
124 | 127 | ||
125 | tpg->lines[pat][plane] = vzalloc(max_w * 2 * pixelsz); | 128 | tpg->lines[pat][plane] = vzalloc(max_w * 2 * pixelsz); |
126 | if (!tpg->lines[pat][plane]) | 129 | if (!tpg->lines[pat][plane]) |
127 | return -ENOMEM; | 130 | return -ENOMEM; |
131 | if (plane == 0) | ||
132 | continue; | ||
133 | tpg->downsampled_lines[pat][plane] = vzalloc(max_w * 2 * pixelsz); | ||
134 | if (!tpg->downsampled_lines[pat][plane]) | ||
135 | return -ENOMEM; | ||
128 | } | 136 | } |
129 | } | 137 | } |
130 | for (plane = 0; plane < TPG_MAX_PLANES; plane++) { | 138 | for (plane = 0; plane < TPG_MAX_PLANES; plane++) { |
131 | unsigned pixelsz = plane ? 1 : 4; | 139 | unsigned pixelsz = plane ? 2 : 4; |
132 | 140 | ||
133 | tpg->contrast_line[plane] = vzalloc(max_w * pixelsz); | 141 | tpg->contrast_line[plane] = vzalloc(max_w * pixelsz); |
134 | if (!tpg->contrast_line[plane]) | 142 | if (!tpg->contrast_line[plane]) |
@@ -152,6 +160,10 @@ void tpg_free(struct tpg_data *tpg) | |||
152 | for (plane = 0; plane < TPG_MAX_PLANES; plane++) { | 160 | for (plane = 0; plane < TPG_MAX_PLANES; plane++) { |
153 | vfree(tpg->lines[pat][plane]); | 161 | vfree(tpg->lines[pat][plane]); |
154 | tpg->lines[pat][plane] = NULL; | 162 | tpg->lines[pat][plane] = NULL; |
163 | if (plane == 0) | ||
164 | continue; | ||
165 | vfree(tpg->downsampled_lines[pat][plane]); | ||
166 | tpg->downsampled_lines[pat][plane] = NULL; | ||
155 | } | 167 | } |
156 | for (plane = 0; plane < TPG_MAX_PLANES; plane++) { | 168 | for (plane = 0; plane < TPG_MAX_PLANES; plane++) { |
157 | vfree(tpg->contrast_line[plane]); | 169 | vfree(tpg->contrast_line[plane]); |
@@ -167,14 +179,38 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc) | |||
167 | { | 179 | { |
168 | tpg->fourcc = fourcc; | 180 | tpg->fourcc = fourcc; |
169 | tpg->planes = 1; | 181 | tpg->planes = 1; |
182 | tpg->buffers = 1; | ||
170 | tpg->recalc_colors = true; | 183 | tpg->recalc_colors = true; |
184 | tpg->interleaved = false; | ||
185 | tpg->vdownsampling[0] = 1; | ||
186 | tpg->hdownsampling[0] = 1; | ||
187 | tpg->hmask[0] = ~0; | ||
188 | tpg->hmask[1] = ~0; | ||
189 | tpg->hmask[2] = ~0; | ||
190 | |||
171 | switch (fourcc) { | 191 | switch (fourcc) { |
192 | case V4L2_PIX_FMT_SBGGR8: | ||
193 | case V4L2_PIX_FMT_SGBRG8: | ||
194 | case V4L2_PIX_FMT_SGRBG8: | ||
195 | case V4L2_PIX_FMT_SRGGB8: | ||
196 | tpg->interleaved = true; | ||
197 | tpg->vdownsampling[1] = 1; | ||
198 | tpg->hdownsampling[1] = 1; | ||
199 | tpg->planes = 2; | ||
200 | /* fall through */ | ||
201 | case V4L2_PIX_FMT_RGB332: | ||
172 | case V4L2_PIX_FMT_RGB565: | 202 | case V4L2_PIX_FMT_RGB565: |
173 | case V4L2_PIX_FMT_RGB565X: | 203 | case V4L2_PIX_FMT_RGB565X: |
204 | case V4L2_PIX_FMT_RGB444: | ||
205 | case V4L2_PIX_FMT_XRGB444: | ||
206 | case V4L2_PIX_FMT_ARGB444: | ||
174 | case V4L2_PIX_FMT_RGB555: | 207 | case V4L2_PIX_FMT_RGB555: |
175 | case V4L2_PIX_FMT_XRGB555: | 208 | case V4L2_PIX_FMT_XRGB555: |
176 | case V4L2_PIX_FMT_ARGB555: | 209 | case V4L2_PIX_FMT_ARGB555: |
177 | case V4L2_PIX_FMT_RGB555X: | 210 | case V4L2_PIX_FMT_RGB555X: |
211 | case V4L2_PIX_FMT_XRGB555X: | ||
212 | case V4L2_PIX_FMT_ARGB555X: | ||
213 | case V4L2_PIX_FMT_BGR666: | ||
178 | case V4L2_PIX_FMT_RGB24: | 214 | case V4L2_PIX_FMT_RGB24: |
179 | case V4L2_PIX_FMT_BGR24: | 215 | case V4L2_PIX_FMT_BGR24: |
180 | case V4L2_PIX_FMT_RGB32: | 216 | case V4L2_PIX_FMT_RGB32: |
@@ -183,16 +219,72 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc) | |||
183 | case V4L2_PIX_FMT_XBGR32: | 219 | case V4L2_PIX_FMT_XBGR32: |
184 | case V4L2_PIX_FMT_ARGB32: | 220 | case V4L2_PIX_FMT_ARGB32: |
185 | case V4L2_PIX_FMT_ABGR32: | 221 | case V4L2_PIX_FMT_ABGR32: |
222 | case V4L2_PIX_FMT_GREY: | ||
186 | tpg->is_yuv = false; | 223 | tpg->is_yuv = false; |
187 | break; | 224 | break; |
225 | case V4L2_PIX_FMT_YUV444: | ||
226 | case V4L2_PIX_FMT_YUV555: | ||
227 | case V4L2_PIX_FMT_YUV565: | ||
228 | case V4L2_PIX_FMT_YUV32: | ||
229 | tpg->is_yuv = true; | ||
230 | break; | ||
231 | case V4L2_PIX_FMT_YUV420M: | ||
232 | case V4L2_PIX_FMT_YVU420M: | ||
233 | tpg->buffers = 3; | ||
234 | /* fall through */ | ||
235 | case V4L2_PIX_FMT_YUV420: | ||
236 | case V4L2_PIX_FMT_YVU420: | ||
237 | tpg->vdownsampling[1] = 2; | ||
238 | tpg->vdownsampling[2] = 2; | ||
239 | tpg->hdownsampling[1] = 2; | ||
240 | tpg->hdownsampling[2] = 2; | ||
241 | tpg->planes = 3; | ||
242 | tpg->is_yuv = true; | ||
243 | break; | ||
244 | case V4L2_PIX_FMT_YUV422P: | ||
245 | tpg->vdownsampling[1] = 1; | ||
246 | tpg->vdownsampling[2] = 1; | ||
247 | tpg->hdownsampling[1] = 2; | ||
248 | tpg->hdownsampling[2] = 2; | ||
249 | tpg->planes = 3; | ||
250 | tpg->is_yuv = true; | ||
251 | break; | ||
188 | case V4L2_PIX_FMT_NV16M: | 252 | case V4L2_PIX_FMT_NV16M: |
189 | case V4L2_PIX_FMT_NV61M: | 253 | case V4L2_PIX_FMT_NV61M: |
254 | tpg->buffers = 2; | ||
255 | /* fall through */ | ||
256 | case V4L2_PIX_FMT_NV16: | ||
257 | case V4L2_PIX_FMT_NV61: | ||
258 | tpg->vdownsampling[1] = 1; | ||
259 | tpg->hdownsampling[1] = 1; | ||
260 | tpg->hmask[1] = ~1; | ||
190 | tpg->planes = 2; | 261 | tpg->planes = 2; |
191 | /* fall-through */ | 262 | tpg->is_yuv = true; |
263 | break; | ||
264 | case V4L2_PIX_FMT_NV12M: | ||
265 | case V4L2_PIX_FMT_NV21M: | ||
266 | tpg->buffers = 2; | ||
267 | /* fall through */ | ||
268 | case V4L2_PIX_FMT_NV12: | ||
269 | case V4L2_PIX_FMT_NV21: | ||
270 | tpg->vdownsampling[1] = 2; | ||
271 | tpg->hdownsampling[1] = 1; | ||
272 | tpg->hmask[1] = ~1; | ||
273 | tpg->planes = 2; | ||
274 | tpg->is_yuv = true; | ||
275 | break; | ||
276 | case V4L2_PIX_FMT_NV24: | ||
277 | case V4L2_PIX_FMT_NV42: | ||
278 | tpg->vdownsampling[1] = 1; | ||
279 | tpg->hdownsampling[1] = 1; | ||
280 | tpg->planes = 2; | ||
281 | tpg->is_yuv = true; | ||
282 | break; | ||
192 | case V4L2_PIX_FMT_YUYV: | 283 | case V4L2_PIX_FMT_YUYV: |
193 | case V4L2_PIX_FMT_UYVY: | 284 | case V4L2_PIX_FMT_UYVY: |
194 | case V4L2_PIX_FMT_YVYU: | 285 | case V4L2_PIX_FMT_YVYU: |
195 | case V4L2_PIX_FMT_VYUY: | 286 | case V4L2_PIX_FMT_VYUY: |
287 | tpg->hmask[0] = ~1; | ||
196 | tpg->is_yuv = true; | 288 | tpg->is_yuv = true; |
197 | break; | 289 | break; |
198 | default: | 290 | default: |
@@ -200,35 +292,75 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc) | |||
200 | } | 292 | } |
201 | 293 | ||
202 | switch (fourcc) { | 294 | switch (fourcc) { |
295 | case V4L2_PIX_FMT_RGB332: | ||
296 | tpg->twopixelsize[0] = 2; | ||
297 | break; | ||
203 | case V4L2_PIX_FMT_RGB565: | 298 | case V4L2_PIX_FMT_RGB565: |
204 | case V4L2_PIX_FMT_RGB565X: | 299 | case V4L2_PIX_FMT_RGB565X: |
300 | case V4L2_PIX_FMT_RGB444: | ||
301 | case V4L2_PIX_FMT_XRGB444: | ||
302 | case V4L2_PIX_FMT_ARGB444: | ||
205 | case V4L2_PIX_FMT_RGB555: | 303 | case V4L2_PIX_FMT_RGB555: |
206 | case V4L2_PIX_FMT_XRGB555: | 304 | case V4L2_PIX_FMT_XRGB555: |
207 | case V4L2_PIX_FMT_ARGB555: | 305 | case V4L2_PIX_FMT_ARGB555: |
208 | case V4L2_PIX_FMT_RGB555X: | 306 | case V4L2_PIX_FMT_RGB555X: |
307 | case V4L2_PIX_FMT_XRGB555X: | ||
308 | case V4L2_PIX_FMT_ARGB555X: | ||
209 | case V4L2_PIX_FMT_YUYV: | 309 | case V4L2_PIX_FMT_YUYV: |
210 | case V4L2_PIX_FMT_UYVY: | 310 | case V4L2_PIX_FMT_UYVY: |
211 | case V4L2_PIX_FMT_YVYU: | 311 | case V4L2_PIX_FMT_YVYU: |
212 | case V4L2_PIX_FMT_VYUY: | 312 | case V4L2_PIX_FMT_VYUY: |
313 | case V4L2_PIX_FMT_YUV444: | ||
314 | case V4L2_PIX_FMT_YUV555: | ||
315 | case V4L2_PIX_FMT_YUV565: | ||
213 | tpg->twopixelsize[0] = 2 * 2; | 316 | tpg->twopixelsize[0] = 2 * 2; |
214 | break; | 317 | break; |
215 | case V4L2_PIX_FMT_RGB24: | 318 | case V4L2_PIX_FMT_RGB24: |
216 | case V4L2_PIX_FMT_BGR24: | 319 | case V4L2_PIX_FMT_BGR24: |
217 | tpg->twopixelsize[0] = 2 * 3; | 320 | tpg->twopixelsize[0] = 2 * 3; |
218 | break; | 321 | break; |
322 | case V4L2_PIX_FMT_BGR666: | ||
219 | case V4L2_PIX_FMT_RGB32: | 323 | case V4L2_PIX_FMT_RGB32: |
220 | case V4L2_PIX_FMT_BGR32: | 324 | case V4L2_PIX_FMT_BGR32: |
221 | case V4L2_PIX_FMT_XRGB32: | 325 | case V4L2_PIX_FMT_XRGB32: |
222 | case V4L2_PIX_FMT_XBGR32: | 326 | case V4L2_PIX_FMT_XBGR32: |
223 | case V4L2_PIX_FMT_ARGB32: | 327 | case V4L2_PIX_FMT_ARGB32: |
224 | case V4L2_PIX_FMT_ABGR32: | 328 | case V4L2_PIX_FMT_ABGR32: |
329 | case V4L2_PIX_FMT_YUV32: | ||
225 | tpg->twopixelsize[0] = 2 * 4; | 330 | tpg->twopixelsize[0] = 2 * 4; |
226 | break; | 331 | break; |
332 | case V4L2_PIX_FMT_GREY: | ||
333 | tpg->twopixelsize[0] = 2; | ||
334 | break; | ||
335 | case V4L2_PIX_FMT_NV12: | ||
336 | case V4L2_PIX_FMT_NV21: | ||
337 | case V4L2_PIX_FMT_NV12M: | ||
338 | case V4L2_PIX_FMT_NV21M: | ||
339 | case V4L2_PIX_FMT_NV16: | ||
340 | case V4L2_PIX_FMT_NV61: | ||
227 | case V4L2_PIX_FMT_NV16M: | 341 | case V4L2_PIX_FMT_NV16M: |
228 | case V4L2_PIX_FMT_NV61M: | 342 | case V4L2_PIX_FMT_NV61M: |
343 | case V4L2_PIX_FMT_SBGGR8: | ||
344 | case V4L2_PIX_FMT_SGBRG8: | ||
345 | case V4L2_PIX_FMT_SGRBG8: | ||
346 | case V4L2_PIX_FMT_SRGGB8: | ||
229 | tpg->twopixelsize[0] = 2; | 347 | tpg->twopixelsize[0] = 2; |
230 | tpg->twopixelsize[1] = 2; | 348 | tpg->twopixelsize[1] = 2; |
231 | break; | 349 | break; |
350 | case V4L2_PIX_FMT_YUV422P: | ||
351 | case V4L2_PIX_FMT_YUV420: | ||
352 | case V4L2_PIX_FMT_YVU420: | ||
353 | case V4L2_PIX_FMT_YUV420M: | ||
354 | case V4L2_PIX_FMT_YVU420M: | ||
355 | tpg->twopixelsize[0] = 2; | ||
356 | tpg->twopixelsize[1] = 2; | ||
357 | tpg->twopixelsize[2] = 2; | ||
358 | break; | ||
359 | case V4L2_PIX_FMT_NV24: | ||
360 | case V4L2_PIX_FMT_NV42: | ||
361 | tpg->twopixelsize[0] = 2; | ||
362 | tpg->twopixelsize[1] = 4; | ||
363 | break; | ||
232 | } | 364 | } |
233 | return true; | 365 | return true; |
234 | } | 366 | } |
@@ -267,7 +399,8 @@ void tpg_reset_source(struct tpg_data *tpg, unsigned width, unsigned height, | |||
267 | tpg->compose.width = width; | 399 | tpg->compose.width = width; |
268 | tpg->compose.height = tpg->buf_height; | 400 | tpg->compose.height = tpg->buf_height; |
269 | for (p = 0; p < tpg->planes; p++) | 401 | for (p = 0; p < tpg->planes; p++) |
270 | tpg->bytesperline[p] = width * tpg->twopixelsize[p] / 2; | 402 | tpg->bytesperline[p] = (width * tpg->twopixelsize[p]) / |
403 | (2 * tpg->hdownsampling[p]); | ||
271 | tpg->recalc_square_border = true; | 404 | tpg->recalc_square_border = true; |
272 | } | 405 | } |
273 | 406 | ||
@@ -347,9 +480,9 @@ static void color_to_ycbcr(struct tpg_data *tpg, int r, int g, int b, | |||
347 | { COEFF(0.5, 224), COEFF(-0.445, 224), COEFF(-0.055, 224) }, | 480 | { COEFF(0.5, 224), COEFF(-0.445, 224), COEFF(-0.055, 224) }, |
348 | }; | 481 | }; |
349 | static const int bt2020[3][3] = { | 482 | static const int bt2020[3][3] = { |
350 | { COEFF(0.2726, 219), COEFF(0.6780, 219), COEFF(0.0593, 219) }, | 483 | { COEFF(0.2627, 219), COEFF(0.6780, 219), COEFF(0.0593, 219) }, |
351 | { COEFF(-0.1396, 224), COEFF(-0.3604, 224), COEFF(0.5, 224) }, | 484 | { COEFF(-0.1396, 224), COEFF(-0.3604, 224), COEFF(0.5, 224) }, |
352 | { COEFF(0.5, 224), COEFF(-0.4629, 224), COEFF(-0.0405, 224) }, | 485 | { COEFF(0.5, 224), COEFF(-0.4598, 224), COEFF(-0.0402, 224) }, |
353 | }; | 486 | }; |
354 | bool full = tpg->real_quantization == V4L2_QUANTIZATION_FULL_RANGE; | 487 | bool full = tpg->real_quantization == V4L2_QUANTIZATION_FULL_RANGE; |
355 | unsigned y_offset = full ? 0 : 16; | 488 | unsigned y_offset = full ? 0 : 16; |
@@ -524,10 +657,10 @@ static void precalculate_color(struct tpg_data *tpg, int k) | |||
524 | g <<= 4; | 657 | g <<= 4; |
525 | b <<= 4; | 658 | b <<= 4; |
526 | } | 659 | } |
527 | if (tpg->qual == TPG_QUAL_GRAY) { | 660 | if (tpg->qual == TPG_QUAL_GRAY || tpg->fourcc == V4L2_PIX_FMT_GREY) { |
528 | /* Rec. 709 Luma function */ | 661 | /* Rec. 709 Luma function */ |
529 | /* (0.2126, 0.7152, 0.0722) * (255 * 256) */ | 662 | /* (0.2126, 0.7152, 0.0722) * (255 * 256) */ |
530 | r = g = b = ((13879 * r + 46688 * g + 4713 * b) >> 16) + (16 << 4); | 663 | r = g = b = (13879 * r + 46688 * g + 4713 * b) >> 16; |
531 | } | 664 | } |
532 | 665 | ||
533 | /* | 666 | /* |
@@ -601,9 +734,29 @@ static void precalculate_color(struct tpg_data *tpg, int k) | |||
601 | cb = clamp(cb, 16 << 4, 240 << 4); | 734 | cb = clamp(cb, 16 << 4, 240 << 4); |
602 | cr = clamp(cr, 16 << 4, 240 << 4); | 735 | cr = clamp(cr, 16 << 4, 240 << 4); |
603 | } | 736 | } |
604 | tpg->colors[k][0] = clamp(y >> 4, 1, 254); | 737 | y = clamp(y >> 4, 1, 254); |
605 | tpg->colors[k][1] = clamp(cb >> 4, 1, 254); | 738 | cb = clamp(cb >> 4, 1, 254); |
606 | tpg->colors[k][2] = clamp(cr >> 4, 1, 254); | 739 | cr = clamp(cr >> 4, 1, 254); |
740 | switch (tpg->fourcc) { | ||
741 | case V4L2_PIX_FMT_YUV444: | ||
742 | y >>= 4; | ||
743 | cb >>= 4; | ||
744 | cr >>= 4; | ||
745 | break; | ||
746 | case V4L2_PIX_FMT_YUV555: | ||
747 | y >>= 3; | ||
748 | cb >>= 3; | ||
749 | cr >>= 3; | ||
750 | break; | ||
751 | case V4L2_PIX_FMT_YUV565: | ||
752 | y >>= 3; | ||
753 | cb >>= 2; | ||
754 | cr >>= 3; | ||
755 | break; | ||
756 | } | ||
757 | tpg->colors[k][0] = y; | ||
758 | tpg->colors[k][1] = cb; | ||
759 | tpg->colors[k][2] = cr; | ||
607 | } else { | 760 | } else { |
608 | if (tpg->real_quantization == V4L2_QUANTIZATION_LIM_RANGE) { | 761 | if (tpg->real_quantization == V4L2_QUANTIZATION_LIM_RANGE) { |
609 | r = (r * 219) / 255 + (16 << 4); | 762 | r = (r * 219) / 255 + (16 << 4); |
@@ -611,20 +764,39 @@ static void precalculate_color(struct tpg_data *tpg, int k) | |||
611 | b = (b * 219) / 255 + (16 << 4); | 764 | b = (b * 219) / 255 + (16 << 4); |
612 | } | 765 | } |
613 | switch (tpg->fourcc) { | 766 | switch (tpg->fourcc) { |
767 | case V4L2_PIX_FMT_RGB332: | ||
768 | r >>= 9; | ||
769 | g >>= 9; | ||
770 | b >>= 10; | ||
771 | break; | ||
614 | case V4L2_PIX_FMT_RGB565: | 772 | case V4L2_PIX_FMT_RGB565: |
615 | case V4L2_PIX_FMT_RGB565X: | 773 | case V4L2_PIX_FMT_RGB565X: |
616 | r >>= 7; | 774 | r >>= 7; |
617 | g >>= 6; | 775 | g >>= 6; |
618 | b >>= 7; | 776 | b >>= 7; |
619 | break; | 777 | break; |
778 | case V4L2_PIX_FMT_RGB444: | ||
779 | case V4L2_PIX_FMT_XRGB444: | ||
780 | case V4L2_PIX_FMT_ARGB444: | ||
781 | r >>= 8; | ||
782 | g >>= 8; | ||
783 | b >>= 8; | ||
784 | break; | ||
620 | case V4L2_PIX_FMT_RGB555: | 785 | case V4L2_PIX_FMT_RGB555: |
621 | case V4L2_PIX_FMT_XRGB555: | 786 | case V4L2_PIX_FMT_XRGB555: |
622 | case V4L2_PIX_FMT_ARGB555: | 787 | case V4L2_PIX_FMT_ARGB555: |
623 | case V4L2_PIX_FMT_RGB555X: | 788 | case V4L2_PIX_FMT_RGB555X: |
789 | case V4L2_PIX_FMT_XRGB555X: | ||
790 | case V4L2_PIX_FMT_ARGB555X: | ||
624 | r >>= 7; | 791 | r >>= 7; |
625 | g >>= 7; | 792 | g >>= 7; |
626 | b >>= 7; | 793 | b >>= 7; |
627 | break; | 794 | break; |
795 | case V4L2_PIX_FMT_BGR666: | ||
796 | r >>= 6; | ||
797 | g >>= 6; | ||
798 | b >>= 6; | ||
799 | break; | ||
628 | default: | 800 | default: |
629 | r >>= 4; | 801 | r >>= 4; |
630 | g >>= 4; | 802 | g >>= 4; |
@@ -665,31 +837,120 @@ static void gen_twopix(struct tpg_data *tpg, | |||
665 | b_v = tpg->colors[color][2]; /* B or precalculated V */ | 837 | b_v = tpg->colors[color][2]; /* B or precalculated V */ |
666 | 838 | ||
667 | switch (tpg->fourcc) { | 839 | switch (tpg->fourcc) { |
840 | case V4L2_PIX_FMT_GREY: | ||
841 | buf[0][offset] = r_y; | ||
842 | break; | ||
843 | case V4L2_PIX_FMT_YUV422P: | ||
844 | case V4L2_PIX_FMT_YUV420: | ||
845 | case V4L2_PIX_FMT_YUV420M: | ||
846 | buf[0][offset] = r_y; | ||
847 | if (odd) { | ||
848 | buf[1][0] = (buf[1][0] + g_u) / 2; | ||
849 | buf[2][0] = (buf[2][0] + b_v) / 2; | ||
850 | buf[1][1] = buf[1][0]; | ||
851 | buf[2][1] = buf[2][0]; | ||
852 | break; | ||
853 | } | ||
854 | buf[1][0] = g_u; | ||
855 | buf[2][0] = b_v; | ||
856 | break; | ||
857 | case V4L2_PIX_FMT_YVU420: | ||
858 | case V4L2_PIX_FMT_YVU420M: | ||
859 | buf[0][offset] = r_y; | ||
860 | if (odd) { | ||
861 | buf[1][0] = (buf[1][0] + b_v) / 2; | ||
862 | buf[2][0] = (buf[2][0] + g_u) / 2; | ||
863 | buf[1][1] = buf[1][0]; | ||
864 | buf[2][1] = buf[2][0]; | ||
865 | break; | ||
866 | } | ||
867 | buf[1][0] = b_v; | ||
868 | buf[2][0] = g_u; | ||
869 | break; | ||
870 | |||
871 | case V4L2_PIX_FMT_NV12: | ||
872 | case V4L2_PIX_FMT_NV12M: | ||
873 | case V4L2_PIX_FMT_NV16: | ||
668 | case V4L2_PIX_FMT_NV16M: | 874 | case V4L2_PIX_FMT_NV16M: |
669 | buf[0][offset] = r_y; | 875 | buf[0][offset] = r_y; |
670 | buf[1][offset] = odd ? b_v : g_u; | 876 | if (odd) { |
877 | buf[1][0] = (buf[1][0] + g_u) / 2; | ||
878 | buf[1][1] = (buf[1][1] + b_v) / 2; | ||
879 | break; | ||
880 | } | ||
881 | buf[1][0] = g_u; | ||
882 | buf[1][1] = b_v; | ||
671 | break; | 883 | break; |
884 | case V4L2_PIX_FMT_NV21: | ||
885 | case V4L2_PIX_FMT_NV21M: | ||
886 | case V4L2_PIX_FMT_NV61: | ||
672 | case V4L2_PIX_FMT_NV61M: | 887 | case V4L2_PIX_FMT_NV61M: |
673 | buf[0][offset] = r_y; | 888 | buf[0][offset] = r_y; |
674 | buf[1][offset] = odd ? g_u : b_v; | 889 | if (odd) { |
890 | buf[1][0] = (buf[1][0] + b_v) / 2; | ||
891 | buf[1][1] = (buf[1][1] + g_u) / 2; | ||
892 | break; | ||
893 | } | ||
894 | buf[1][0] = b_v; | ||
895 | buf[1][1] = g_u; | ||
896 | break; | ||
897 | |||
898 | case V4L2_PIX_FMT_NV24: | ||
899 | buf[0][offset] = r_y; | ||
900 | buf[1][2 * offset] = g_u; | ||
901 | buf[1][2 * offset + 1] = b_v; | ||
902 | break; | ||
903 | |||
904 | case V4L2_PIX_FMT_NV42: | ||
905 | buf[0][offset] = r_y; | ||
906 | buf[1][2 * offset] = b_v; | ||
907 | buf[1][2 * offset + 1] = g_u; | ||
675 | break; | 908 | break; |
676 | 909 | ||
677 | case V4L2_PIX_FMT_YUYV: | 910 | case V4L2_PIX_FMT_YUYV: |
678 | buf[0][offset] = r_y; | 911 | buf[0][offset] = r_y; |
679 | buf[0][offset + 1] = odd ? b_v : g_u; | 912 | if (odd) { |
913 | buf[0][1] = (buf[0][1] + g_u) / 2; | ||
914 | buf[0][3] = (buf[0][3] + b_v) / 2; | ||
915 | break; | ||
916 | } | ||
917 | buf[0][1] = g_u; | ||
918 | buf[0][3] = b_v; | ||
680 | break; | 919 | break; |
681 | case V4L2_PIX_FMT_UYVY: | 920 | case V4L2_PIX_FMT_UYVY: |
682 | buf[0][offset] = odd ? b_v : g_u; | ||
683 | buf[0][offset + 1] = r_y; | 921 | buf[0][offset + 1] = r_y; |
922 | if (odd) { | ||
923 | buf[0][0] = (buf[0][0] + g_u) / 2; | ||
924 | buf[0][2] = (buf[0][2] + b_v) / 2; | ||
925 | break; | ||
926 | } | ||
927 | buf[0][0] = g_u; | ||
928 | buf[0][2] = b_v; | ||
684 | break; | 929 | break; |
685 | case V4L2_PIX_FMT_YVYU: | 930 | case V4L2_PIX_FMT_YVYU: |
686 | buf[0][offset] = r_y; | 931 | buf[0][offset] = r_y; |
687 | buf[0][offset + 1] = odd ? g_u : b_v; | 932 | if (odd) { |
933 | buf[0][1] = (buf[0][1] + b_v) / 2; | ||
934 | buf[0][3] = (buf[0][3] + g_u) / 2; | ||
935 | break; | ||
936 | } | ||
937 | buf[0][1] = b_v; | ||
938 | buf[0][3] = g_u; | ||
688 | break; | 939 | break; |
689 | case V4L2_PIX_FMT_VYUY: | 940 | case V4L2_PIX_FMT_VYUY: |
690 | buf[0][offset] = odd ? g_u : b_v; | ||
691 | buf[0][offset + 1] = r_y; | 941 | buf[0][offset + 1] = r_y; |
942 | if (odd) { | ||
943 | buf[0][0] = (buf[0][0] + b_v) / 2; | ||
944 | buf[0][2] = (buf[0][2] + g_u) / 2; | ||
945 | break; | ||
946 | } | ||
947 | buf[0][0] = b_v; | ||
948 | buf[0][2] = g_u; | ||
949 | break; | ||
950 | case V4L2_PIX_FMT_RGB332: | ||
951 | buf[0][offset] = (r_y << 5) | (g_u << 2) | b_v; | ||
692 | break; | 952 | break; |
953 | case V4L2_PIX_FMT_YUV565: | ||
693 | case V4L2_PIX_FMT_RGB565: | 954 | case V4L2_PIX_FMT_RGB565: |
694 | buf[0][offset] = (g_u << 5) | b_v; | 955 | buf[0][offset] = (g_u << 5) | b_v; |
695 | buf[0][offset + 1] = (r_y << 3) | (g_u >> 3); | 956 | buf[0][offset + 1] = (r_y << 3) | (g_u >> 3); |
@@ -698,15 +959,29 @@ static void gen_twopix(struct tpg_data *tpg, | |||
698 | buf[0][offset] = (r_y << 3) | (g_u >> 3); | 959 | buf[0][offset] = (r_y << 3) | (g_u >> 3); |
699 | buf[0][offset + 1] = (g_u << 5) | b_v; | 960 | buf[0][offset + 1] = (g_u << 5) | b_v; |
700 | break; | 961 | break; |
962 | case V4L2_PIX_FMT_RGB444: | ||
963 | case V4L2_PIX_FMT_XRGB444: | ||
964 | alpha = 0; | ||
965 | /* fall through */ | ||
966 | case V4L2_PIX_FMT_YUV444: | ||
967 | case V4L2_PIX_FMT_ARGB444: | ||
968 | buf[0][offset] = (g_u << 4) | b_v; | ||
969 | buf[0][offset + 1] = (alpha & 0xf0) | r_y; | ||
970 | break; | ||
701 | case V4L2_PIX_FMT_RGB555: | 971 | case V4L2_PIX_FMT_RGB555: |
702 | case V4L2_PIX_FMT_XRGB555: | 972 | case V4L2_PIX_FMT_XRGB555: |
703 | alpha = 0; | 973 | alpha = 0; |
704 | /* fall through */ | 974 | /* fall through */ |
975 | case V4L2_PIX_FMT_YUV555: | ||
705 | case V4L2_PIX_FMT_ARGB555: | 976 | case V4L2_PIX_FMT_ARGB555: |
706 | buf[0][offset] = (g_u << 5) | b_v; | 977 | buf[0][offset] = (g_u << 5) | b_v; |
707 | buf[0][offset + 1] = (alpha & 0x80) | (r_y << 2) | (g_u >> 3); | 978 | buf[0][offset + 1] = (alpha & 0x80) | (r_y << 2) | (g_u >> 3); |
708 | break; | 979 | break; |
709 | case V4L2_PIX_FMT_RGB555X: | 980 | case V4L2_PIX_FMT_RGB555X: |
981 | case V4L2_PIX_FMT_XRGB555X: | ||
982 | alpha = 0; | ||
983 | /* fall through */ | ||
984 | case V4L2_PIX_FMT_ARGB555X: | ||
710 | buf[0][offset] = (alpha & 0x80) | (r_y << 2) | (g_u >> 3); | 985 | buf[0][offset] = (alpha & 0x80) | (r_y << 2) | (g_u >> 3); |
711 | buf[0][offset + 1] = (g_u << 5) | b_v; | 986 | buf[0][offset + 1] = (g_u << 5) | b_v; |
712 | break; | 987 | break; |
@@ -720,10 +995,17 @@ static void gen_twopix(struct tpg_data *tpg, | |||
720 | buf[0][offset + 1] = g_u; | 995 | buf[0][offset + 1] = g_u; |
721 | buf[0][offset + 2] = r_y; | 996 | buf[0][offset + 2] = r_y; |
722 | break; | 997 | break; |
998 | case V4L2_PIX_FMT_BGR666: | ||
999 | buf[0][offset] = (b_v << 2) | (g_u >> 4); | ||
1000 | buf[0][offset + 1] = (g_u << 4) | (r_y >> 2); | ||
1001 | buf[0][offset + 2] = r_y << 6; | ||
1002 | buf[0][offset + 3] = 0; | ||
1003 | break; | ||
723 | case V4L2_PIX_FMT_RGB32: | 1004 | case V4L2_PIX_FMT_RGB32: |
724 | case V4L2_PIX_FMT_XRGB32: | 1005 | case V4L2_PIX_FMT_XRGB32: |
725 | alpha = 0; | 1006 | alpha = 0; |
726 | /* fall through */ | 1007 | /* fall through */ |
1008 | case V4L2_PIX_FMT_YUV32: | ||
727 | case V4L2_PIX_FMT_ARGB32: | 1009 | case V4L2_PIX_FMT_ARGB32: |
728 | buf[0][offset] = alpha; | 1010 | buf[0][offset] = alpha; |
729 | buf[0][offset + 1] = r_y; | 1011 | buf[0][offset + 1] = r_y; |
@@ -740,15 +1022,47 @@ static void gen_twopix(struct tpg_data *tpg, | |||
740 | buf[0][offset + 2] = r_y; | 1022 | buf[0][offset + 2] = r_y; |
741 | buf[0][offset + 3] = alpha; | 1023 | buf[0][offset + 3] = alpha; |
742 | break; | 1024 | break; |
1025 | case V4L2_PIX_FMT_SBGGR8: | ||
1026 | buf[0][offset] = odd ? g_u : b_v; | ||
1027 | buf[1][offset] = odd ? r_y : g_u; | ||
1028 | break; | ||
1029 | case V4L2_PIX_FMT_SGBRG8: | ||
1030 | buf[0][offset] = odd ? b_v : g_u; | ||
1031 | buf[1][offset] = odd ? g_u : r_y; | ||
1032 | break; | ||
1033 | case V4L2_PIX_FMT_SGRBG8: | ||
1034 | buf[0][offset] = odd ? r_y : g_u; | ||
1035 | buf[1][offset] = odd ? g_u : b_v; | ||
1036 | break; | ||
1037 | case V4L2_PIX_FMT_SRGGB8: | ||
1038 | buf[0][offset] = odd ? g_u : r_y; | ||
1039 | buf[1][offset] = odd ? b_v : g_u; | ||
1040 | break; | ||
1041 | } | ||
1042 | } | ||
1043 | |||
1044 | unsigned tpg_g_interleaved_plane(const struct tpg_data *tpg, unsigned buf_line) | ||
1045 | { | ||
1046 | switch (tpg->fourcc) { | ||
1047 | case V4L2_PIX_FMT_SBGGR8: | ||
1048 | case V4L2_PIX_FMT_SGBRG8: | ||
1049 | case V4L2_PIX_FMT_SGRBG8: | ||
1050 | case V4L2_PIX_FMT_SRGGB8: | ||
1051 | return buf_line & 1; | ||
1052 | default: | ||
1053 | return 0; | ||
743 | } | 1054 | } |
744 | } | 1055 | } |
745 | 1056 | ||
746 | /* Return how many pattern lines are used by the current pattern. */ | 1057 | /* Return how many pattern lines are used by the current pattern. */ |
747 | static unsigned tpg_get_pat_lines(struct tpg_data *tpg) | 1058 | static unsigned tpg_get_pat_lines(const struct tpg_data *tpg) |
748 | { | 1059 | { |
749 | switch (tpg->pattern) { | 1060 | switch (tpg->pattern) { |
750 | case TPG_PAT_CHECKERS_16X16: | 1061 | case TPG_PAT_CHECKERS_16X16: |
1062 | case TPG_PAT_CHECKERS_2X2: | ||
751 | case TPG_PAT_CHECKERS_1X1: | 1063 | case TPG_PAT_CHECKERS_1X1: |
1064 | case TPG_PAT_COLOR_CHECKERS_2X2: | ||
1065 | case TPG_PAT_COLOR_CHECKERS_1X1: | ||
752 | case TPG_PAT_ALTERNATING_HLINES: | 1066 | case TPG_PAT_ALTERNATING_HLINES: |
753 | case TPG_PAT_CROSS_1_PIXEL: | 1067 | case TPG_PAT_CROSS_1_PIXEL: |
754 | case TPG_PAT_CROSS_2_PIXELS: | 1068 | case TPG_PAT_CROSS_2_PIXELS: |
@@ -763,14 +1077,18 @@ static unsigned tpg_get_pat_lines(struct tpg_data *tpg) | |||
763 | } | 1077 | } |
764 | 1078 | ||
765 | /* Which pattern line should be used for the given frame line. */ | 1079 | /* Which pattern line should be used for the given frame line. */ |
766 | static unsigned tpg_get_pat_line(struct tpg_data *tpg, unsigned line) | 1080 | static unsigned tpg_get_pat_line(const struct tpg_data *tpg, unsigned line) |
767 | { | 1081 | { |
768 | switch (tpg->pattern) { | 1082 | switch (tpg->pattern) { |
769 | case TPG_PAT_CHECKERS_16X16: | 1083 | case TPG_PAT_CHECKERS_16X16: |
770 | return (line >> 4) & 1; | 1084 | return (line >> 4) & 1; |
771 | case TPG_PAT_CHECKERS_1X1: | 1085 | case TPG_PAT_CHECKERS_1X1: |
1086 | case TPG_PAT_COLOR_CHECKERS_1X1: | ||
772 | case TPG_PAT_ALTERNATING_HLINES: | 1087 | case TPG_PAT_ALTERNATING_HLINES: |
773 | return line & 1; | 1088 | return line & 1; |
1089 | case TPG_PAT_CHECKERS_2X2: | ||
1090 | case TPG_PAT_COLOR_CHECKERS_2X2: | ||
1091 | return (line & 2) >> 1; | ||
774 | case TPG_PAT_100_COLORSQUARES: | 1092 | case TPG_PAT_100_COLORSQUARES: |
775 | case TPG_PAT_100_HCOLORBAR: | 1093 | case TPG_PAT_100_HCOLORBAR: |
776 | return (line * 8) / tpg->src_height; | 1094 | return (line * 8) / tpg->src_height; |
@@ -789,7 +1107,8 @@ static unsigned tpg_get_pat_line(struct tpg_data *tpg, unsigned line) | |||
789 | * Which color should be used for the given pattern line and X coordinate. | 1107 | * Which color should be used for the given pattern line and X coordinate. |
790 | * Note: x is in the range 0 to 2 * tpg->src_width. | 1108 | * Note: x is in the range 0 to 2 * tpg->src_width. |
791 | */ | 1109 | */ |
792 | static enum tpg_color tpg_get_color(struct tpg_data *tpg, unsigned pat_line, unsigned x) | 1110 | static enum tpg_color tpg_get_color(const struct tpg_data *tpg, |
1111 | unsigned pat_line, unsigned x) | ||
793 | { | 1112 | { |
794 | /* Maximum number of bars are TPG_COLOR_MAX - otherwise, the input print code | 1113 | /* Maximum number of bars are TPG_COLOR_MAX - otherwise, the input print code |
795 | should be modified */ | 1114 | should be modified */ |
@@ -836,6 +1155,15 @@ static enum tpg_color tpg_get_color(struct tpg_data *tpg, unsigned pat_line, uns | |||
836 | case TPG_PAT_CHECKERS_1X1: | 1155 | case TPG_PAT_CHECKERS_1X1: |
837 | return ((x & 1) ^ (pat_line & 1)) ? | 1156 | return ((x & 1) ^ (pat_line & 1)) ? |
838 | TPG_COLOR_100_WHITE : TPG_COLOR_100_BLACK; | 1157 | TPG_COLOR_100_WHITE : TPG_COLOR_100_BLACK; |
1158 | case TPG_PAT_COLOR_CHECKERS_1X1: | ||
1159 | return ((x & 1) ^ (pat_line & 1)) ? | ||
1160 | TPG_COLOR_100_RED : TPG_COLOR_100_BLUE; | ||
1161 | case TPG_PAT_CHECKERS_2X2: | ||
1162 | return (((x >> 1) & 1) ^ (pat_line & 1)) ? | ||
1163 | TPG_COLOR_100_WHITE : TPG_COLOR_100_BLACK; | ||
1164 | case TPG_PAT_COLOR_CHECKERS_2X2: | ||
1165 | return (((x >> 1) & 1) ^ (pat_line & 1)) ? | ||
1166 | TPG_COLOR_100_RED : TPG_COLOR_100_BLUE; | ||
839 | case TPG_PAT_ALTERNATING_HLINES: | 1167 | case TPG_PAT_ALTERNATING_HLINES: |
840 | return pat_line ? TPG_COLOR_100_WHITE : TPG_COLOR_100_BLACK; | 1168 | return pat_line ? TPG_COLOR_100_WHITE : TPG_COLOR_100_BLACK; |
841 | case TPG_PAT_ALTERNATING_VLINES: | 1169 | case TPG_PAT_ALTERNATING_VLINES: |
@@ -948,6 +1276,7 @@ static void tpg_calculate_square_border(struct tpg_data *tpg) | |||
948 | static void tpg_precalculate_line(struct tpg_data *tpg) | 1276 | static void tpg_precalculate_line(struct tpg_data *tpg) |
949 | { | 1277 | { |
950 | enum tpg_color contrast; | 1278 | enum tpg_color contrast; |
1279 | u8 pix[TPG_MAX_PLANES][8]; | ||
951 | unsigned pat; | 1280 | unsigned pat; |
952 | unsigned p; | 1281 | unsigned p; |
953 | unsigned x; | 1282 | unsigned x; |
@@ -974,7 +1303,6 @@ static void tpg_precalculate_line(struct tpg_data *tpg) | |||
974 | for (x = 0; x < tpg->scaled_width * 2; x += 2) { | 1303 | for (x = 0; x < tpg->scaled_width * 2; x += 2) { |
975 | unsigned real_x = src_x; | 1304 | unsigned real_x = src_x; |
976 | enum tpg_color color1, color2; | 1305 | enum tpg_color color1, color2; |
977 | u8 pix[TPG_MAX_PLANES][8]; | ||
978 | 1306 | ||
979 | real_x = tpg->hflip ? tpg->src_width * 2 - real_x - 2 : real_x; | 1307 | real_x = tpg->hflip ? tpg->src_width * 2 - real_x - 2 : real_x; |
980 | color1 = tpg_get_color(tpg, pat, real_x); | 1308 | color1 = tpg_get_color(tpg, pat, real_x); |
@@ -1001,39 +1329,53 @@ static void tpg_precalculate_line(struct tpg_data *tpg) | |||
1001 | gen_twopix(tpg, pix, tpg->hflip ? color1 : color2, 1); | 1329 | gen_twopix(tpg, pix, tpg->hflip ? color1 : color2, 1); |
1002 | for (p = 0; p < tpg->planes; p++) { | 1330 | for (p = 0; p < tpg->planes; p++) { |
1003 | unsigned twopixsize = tpg->twopixelsize[p]; | 1331 | unsigned twopixsize = tpg->twopixelsize[p]; |
1004 | u8 *pos = tpg->lines[pat][p] + x * twopixsize / 2; | 1332 | unsigned hdiv = tpg->hdownsampling[p]; |
1333 | u8 *pos = tpg->lines[pat][p] + tpg_hdiv(tpg, p, x); | ||
1005 | 1334 | ||
1006 | memcpy(pos, pix[p], twopixsize); | 1335 | memcpy(pos, pix[p], twopixsize / hdiv); |
1007 | } | 1336 | } |
1008 | } | 1337 | } |
1009 | } | 1338 | } |
1010 | for (x = 0; x < tpg->scaled_width; x += 2) { | ||
1011 | u8 pix[TPG_MAX_PLANES][8]; | ||
1012 | 1339 | ||
1013 | gen_twopix(tpg, pix, contrast, 0); | 1340 | if (tpg->vdownsampling[tpg->planes - 1] > 1) { |
1014 | gen_twopix(tpg, pix, contrast, 1); | 1341 | unsigned pat_lines = tpg_get_pat_lines(tpg); |
1015 | for (p = 0; p < tpg->planes; p++) { | ||
1016 | unsigned twopixsize = tpg->twopixelsize[p]; | ||
1017 | u8 *pos = tpg->contrast_line[p] + x * twopixsize / 2; | ||
1018 | 1342 | ||
1019 | memcpy(pos, pix[p], twopixsize); | 1343 | for (pat = 0; pat < pat_lines; pat++) { |
1344 | unsigned next_pat = (pat + 1) % pat_lines; | ||
1345 | |||
1346 | for (p = 1; p < tpg->planes; p++) { | ||
1347 | unsigned w = tpg_hdiv(tpg, p, tpg->scaled_width * 2); | ||
1348 | u8 *pos1 = tpg->lines[pat][p]; | ||
1349 | u8 *pos2 = tpg->lines[next_pat][p]; | ||
1350 | u8 *dest = tpg->downsampled_lines[pat][p]; | ||
1351 | |||
1352 | for (x = 0; x < w; x++, pos1++, pos2++, dest++) | ||
1353 | *dest = ((u16)*pos1 + (u16)*pos2) / 2; | ||
1354 | } | ||
1020 | } | 1355 | } |
1021 | } | 1356 | } |
1022 | for (x = 0; x < tpg->scaled_width; x += 2) { | ||
1023 | u8 pix[TPG_MAX_PLANES][8]; | ||
1024 | 1357 | ||
1025 | gen_twopix(tpg, pix, TPG_COLOR_100_BLACK, 0); | 1358 | gen_twopix(tpg, pix, contrast, 0); |
1026 | gen_twopix(tpg, pix, TPG_COLOR_100_BLACK, 1); | 1359 | gen_twopix(tpg, pix, contrast, 1); |
1027 | for (p = 0; p < tpg->planes; p++) { | 1360 | for (p = 0; p < tpg->planes; p++) { |
1028 | unsigned twopixsize = tpg->twopixelsize[p]; | 1361 | unsigned twopixsize = tpg->twopixelsize[p]; |
1029 | u8 *pos = tpg->black_line[p] + x * twopixsize / 2; | 1362 | u8 *pos = tpg->contrast_line[p]; |
1030 | 1363 | ||
1364 | for (x = 0; x < tpg->scaled_width; x += 2, pos += twopixsize) | ||
1365 | memcpy(pos, pix[p], twopixsize); | ||
1366 | } | ||
1367 | |||
1368 | gen_twopix(tpg, pix, TPG_COLOR_100_BLACK, 0); | ||
1369 | gen_twopix(tpg, pix, TPG_COLOR_100_BLACK, 1); | ||
1370 | for (p = 0; p < tpg->planes; p++) { | ||
1371 | unsigned twopixsize = tpg->twopixelsize[p]; | ||
1372 | u8 *pos = tpg->black_line[p]; | ||
1373 | |||
1374 | for (x = 0; x < tpg->scaled_width; x += 2, pos += twopixsize) | ||
1031 | memcpy(pos, pix[p], twopixsize); | 1375 | memcpy(pos, pix[p], twopixsize); |
1032 | } | ||
1033 | } | 1376 | } |
1034 | for (x = 0; x < tpg->scaled_width * 2; x += 2) { | ||
1035 | u8 pix[TPG_MAX_PLANES][8]; | ||
1036 | 1377 | ||
1378 | for (x = 0; x < tpg->scaled_width * 2; x += 2) { | ||
1037 | gen_twopix(tpg, pix, TPG_COLOR_RANDOM, 0); | 1379 | gen_twopix(tpg, pix, TPG_COLOR_RANDOM, 0); |
1038 | gen_twopix(tpg, pix, TPG_COLOR_RANDOM, 1); | 1380 | gen_twopix(tpg, pix, TPG_COLOR_RANDOM, 1); |
1039 | for (p = 0; p < tpg->planes; p++) { | 1381 | for (p = 0; p < tpg->planes; p++) { |
@@ -1043,6 +1385,7 @@ static void tpg_precalculate_line(struct tpg_data *tpg) | |||
1043 | memcpy(pos, pix[p], twopixsize); | 1385 | memcpy(pos, pix[p], twopixsize); |
1044 | } | 1386 | } |
1045 | } | 1387 | } |
1388 | |||
1046 | gen_twopix(tpg, tpg->textbg, TPG_COLOR_TEXTBG, 0); | 1389 | gen_twopix(tpg, tpg->textbg, TPG_COLOR_TEXTBG, 0); |
1047 | gen_twopix(tpg, tpg->textbg, TPG_COLOR_TEXTBG, 1); | 1390 | gen_twopix(tpg, tpg->textbg, TPG_COLOR_TEXTBG, 1); |
1048 | gen_twopix(tpg, tpg->textfg, TPG_COLOR_TEXTFG, 0); | 1391 | gen_twopix(tpg, tpg->textfg, TPG_COLOR_TEXTFG, 0); |
@@ -1052,8 +1395,8 @@ static void tpg_precalculate_line(struct tpg_data *tpg) | |||
1052 | /* need this to do rgb24 rendering */ | 1395 | /* need this to do rgb24 rendering */ |
1053 | typedef struct { u16 __; u8 _; } __packed x24; | 1396 | typedef struct { u16 __; u8 _; } __packed x24; |
1054 | 1397 | ||
1055 | void tpg_gen_text(struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2], | 1398 | void tpg_gen_text(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2], |
1056 | int y, int x, char *text) | 1399 | int y, int x, char *text) |
1057 | { | 1400 | { |
1058 | int line; | 1401 | int line; |
1059 | unsigned step = V4L2_FIELD_HAS_T_OR_B(tpg->field) ? 2 : 1; | 1402 | unsigned step = V4L2_FIELD_HAS_T_OR_B(tpg->field) ? 2 : 1; |
@@ -1083,24 +1426,37 @@ void tpg_gen_text(struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2], | |||
1083 | div = 2; | 1426 | div = 2; |
1084 | 1427 | ||
1085 | for (p = 0; p < tpg->planes; p++) { | 1428 | for (p = 0; p < tpg->planes; p++) { |
1086 | /* Print stream time */ | 1429 | unsigned vdiv = tpg->vdownsampling[p]; |
1430 | unsigned hdiv = tpg->hdownsampling[p]; | ||
1431 | |||
1432 | /* Print text */ | ||
1087 | #define PRINTSTR(PIXTYPE) do { \ | 1433 | #define PRINTSTR(PIXTYPE) do { \ |
1088 | PIXTYPE fg; \ | 1434 | PIXTYPE fg; \ |
1089 | PIXTYPE bg; \ | 1435 | PIXTYPE bg; \ |
1090 | memcpy(&fg, tpg->textfg[p], sizeof(PIXTYPE)); \ | 1436 | memcpy(&fg, tpg->textfg[p], sizeof(PIXTYPE)); \ |
1091 | memcpy(&bg, tpg->textbg[p], sizeof(PIXTYPE)); \ | 1437 | memcpy(&bg, tpg->textbg[p], sizeof(PIXTYPE)); \ |
1092 | \ | 1438 | \ |
1093 | for (line = first; line < 16; line += step) { \ | 1439 | for (line = first; line < 16; line += vdiv * step) { \ |
1094 | int l = tpg->vflip ? 15 - line : line; \ | 1440 | int l = tpg->vflip ? 15 - line : line; \ |
1095 | PIXTYPE *pos = (PIXTYPE *)(basep[p][line & 1] + \ | 1441 | PIXTYPE *pos = (PIXTYPE *)(basep[p][(line / vdiv) & 1] + \ |
1096 | ((y * step + l) / div) * tpg->bytesperline[p] + \ | 1442 | ((y * step + l) / (vdiv * div)) * tpg->bytesperline[p] + \ |
1097 | x * sizeof(PIXTYPE)); \ | 1443 | (x / hdiv) * sizeof(PIXTYPE)); \ |
1098 | unsigned s; \ | 1444 | unsigned s; \ |
1099 | \ | 1445 | \ |
1100 | for (s = 0; s < len; s++) { \ | 1446 | for (s = 0; s < len; s++) { \ |
1101 | u8 chr = font8x16[text[s] * 16 + line]; \ | 1447 | u8 chr = font8x16[text[s] * 16 + line]; \ |
1102 | \ | 1448 | \ |
1103 | if (tpg->hflip) { \ | 1449 | if (hdiv == 2 && tpg->hflip) { \ |
1450 | pos[3] = (chr & (0x01 << 6) ? fg : bg); \ | ||
1451 | pos[2] = (chr & (0x01 << 4) ? fg : bg); \ | ||
1452 | pos[1] = (chr & (0x01 << 2) ? fg : bg); \ | ||
1453 | pos[0] = (chr & (0x01 << 0) ? fg : bg); \ | ||
1454 | } else if (hdiv == 2) { \ | ||
1455 | pos[0] = (chr & (0x01 << 7) ? fg : bg); \ | ||
1456 | pos[1] = (chr & (0x01 << 5) ? fg : bg); \ | ||
1457 | pos[2] = (chr & (0x01 << 3) ? fg : bg); \ | ||
1458 | pos[3] = (chr & (0x01 << 1) ? fg : bg); \ | ||
1459 | } else if (tpg->hflip) { \ | ||
1104 | pos[7] = (chr & (0x01 << 7) ? fg : bg); \ | 1460 | pos[7] = (chr & (0x01 << 7) ? fg : bg); \ |
1105 | pos[6] = (chr & (0x01 << 6) ? fg : bg); \ | 1461 | pos[6] = (chr & (0x01 << 6) ? fg : bg); \ |
1106 | pos[5] = (chr & (0x01 << 5) ? fg : bg); \ | 1462 | pos[5] = (chr & (0x01 << 5) ? fg : bg); \ |
@@ -1120,7 +1476,7 @@ void tpg_gen_text(struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2], | |||
1120 | pos[7] = (chr & (0x01 << 0) ? fg : bg); \ | 1476 | pos[7] = (chr & (0x01 << 0) ? fg : bg); \ |
1121 | } \ | 1477 | } \ |
1122 | \ | 1478 | \ |
1123 | pos += tpg->hflip ? -8 : 8; \ | 1479 | pos += (tpg->hflip ? -8 : 8) / hdiv; \ |
1124 | } \ | 1480 | } \ |
1125 | } \ | 1481 | } \ |
1126 | } while (0) | 1482 | } while (0) |
@@ -1187,7 +1543,7 @@ void tpg_update_mv_step(struct tpg_data *tpg) | |||
1187 | } | 1543 | } |
1188 | 1544 | ||
1189 | /* Map the line number relative to the crop rectangle to a frame line number */ | 1545 | /* Map the line number relative to the crop rectangle to a frame line number */ |
1190 | static unsigned tpg_calc_frameline(struct tpg_data *tpg, unsigned src_y, | 1546 | static unsigned tpg_calc_frameline(const struct tpg_data *tpg, unsigned src_y, |
1191 | unsigned field) | 1547 | unsigned field) |
1192 | { | 1548 | { |
1193 | switch (field) { | 1549 | switch (field) { |
@@ -1204,7 +1560,7 @@ static unsigned tpg_calc_frameline(struct tpg_data *tpg, unsigned src_y, | |||
1204 | * Map the line number relative to the compose rectangle to a destination | 1560 | * Map the line number relative to the compose rectangle to a destination |
1205 | * buffer line number. | 1561 | * buffer line number. |
1206 | */ | 1562 | */ |
1207 | static unsigned tpg_calc_buffer_line(struct tpg_data *tpg, unsigned y, | 1563 | static unsigned tpg_calc_buffer_line(const struct tpg_data *tpg, unsigned y, |
1208 | unsigned field) | 1564 | unsigned field) |
1209 | { | 1565 | { |
1210 | y += tpg->compose.top; | 1566 | y += tpg->compose.top; |
@@ -1265,6 +1621,10 @@ static void tpg_recalc(struct tpg_data *tpg) | |||
1265 | V4L2_QUANTIZATION_LIM_RANGE; | 1621 | V4L2_QUANTIZATION_LIM_RANGE; |
1266 | break; | 1622 | break; |
1267 | } | 1623 | } |
1624 | } else if (tpg->colorspace == V4L2_COLORSPACE_BT2020) { | ||
1625 | /* R'G'B' BT.2020 is limited range */ | ||
1626 | tpg->real_quantization = | ||
1627 | V4L2_QUANTIZATION_LIM_RANGE; | ||
1268 | } | 1628 | } |
1269 | } | 1629 | } |
1270 | tpg_precalculate_colors(tpg); | 1630 | tpg_precalculate_colors(tpg); |
@@ -1283,191 +1643,388 @@ void tpg_calc_text_basep(struct tpg_data *tpg, | |||
1283 | u8 *basep[TPG_MAX_PLANES][2], unsigned p, u8 *vbuf) | 1643 | u8 *basep[TPG_MAX_PLANES][2], unsigned p, u8 *vbuf) |
1284 | { | 1644 | { |
1285 | unsigned stride = tpg->bytesperline[p]; | 1645 | unsigned stride = tpg->bytesperline[p]; |
1646 | unsigned h = tpg->buf_height; | ||
1286 | 1647 | ||
1287 | tpg_recalc(tpg); | 1648 | tpg_recalc(tpg); |
1288 | 1649 | ||
1289 | basep[p][0] = vbuf; | 1650 | basep[p][0] = vbuf; |
1290 | basep[p][1] = vbuf; | 1651 | basep[p][1] = vbuf; |
1652 | h /= tpg->vdownsampling[p]; | ||
1291 | if (tpg->field == V4L2_FIELD_SEQ_TB) | 1653 | if (tpg->field == V4L2_FIELD_SEQ_TB) |
1292 | basep[p][1] += tpg->buf_height * stride / 2; | 1654 | basep[p][1] += h * stride / 2; |
1293 | else if (tpg->field == V4L2_FIELD_SEQ_BT) | 1655 | else if (tpg->field == V4L2_FIELD_SEQ_BT) |
1294 | basep[p][0] += tpg->buf_height * stride / 2; | 1656 | basep[p][0] += h * stride / 2; |
1657 | if (p == 0 && tpg->interleaved) | ||
1658 | tpg_calc_text_basep(tpg, basep, 1, vbuf); | ||
1295 | } | 1659 | } |
1296 | 1660 | ||
1297 | void tpg_fillbuffer(struct tpg_data *tpg, v4l2_std_id std, unsigned p, u8 *vbuf) | 1661 | static int tpg_pattern_avg(const struct tpg_data *tpg, |
1662 | unsigned pat1, unsigned pat2) | ||
1298 | { | 1663 | { |
1299 | bool is_tv = std; | 1664 | unsigned pat_lines = tpg_get_pat_lines(tpg); |
1300 | bool is_60hz = is_tv && (std & V4L2_STD_525_60); | 1665 | |
1301 | unsigned mv_hor_old = tpg->mv_hor_count % tpg->src_width; | 1666 | if (pat1 == (pat2 + 1) % pat_lines) |
1302 | unsigned mv_hor_new = (tpg->mv_hor_count + tpg->mv_hor_step) % tpg->src_width; | 1667 | return pat2; |
1303 | unsigned mv_vert_old = tpg->mv_vert_count % tpg->src_height; | 1668 | if (pat2 == (pat1 + 1) % pat_lines) |
1304 | unsigned mv_vert_new = (tpg->mv_vert_count + tpg->mv_vert_step) % tpg->src_height; | 1669 | return pat1; |
1670 | return -1; | ||
1671 | } | ||
1672 | |||
1673 | /* | ||
1674 | * This struct contains common parameters used by both the drawing of the | ||
1675 | * test pattern and the drawing of the extras (borders, square, etc.) | ||
1676 | */ | ||
1677 | struct tpg_draw_params { | ||
1678 | /* common data */ | ||
1679 | bool is_tv; | ||
1680 | bool is_60hz; | ||
1681 | unsigned twopixsize; | ||
1682 | unsigned img_width; | ||
1683 | unsigned stride; | ||
1684 | unsigned hmax; | ||
1685 | unsigned frame_line; | ||
1686 | unsigned frame_line_next; | ||
1687 | |||
1688 | /* test pattern */ | ||
1689 | unsigned mv_hor_old; | ||
1690 | unsigned mv_hor_new; | ||
1691 | unsigned mv_vert_old; | ||
1692 | unsigned mv_vert_new; | ||
1693 | |||
1694 | /* extras */ | ||
1305 | unsigned wss_width; | 1695 | unsigned wss_width; |
1306 | unsigned f; | 1696 | unsigned wss_random_offset; |
1307 | int hmax = (tpg->compose.height * tpg->perc_fill) / 100; | 1697 | unsigned sav_eav_f; |
1308 | int h; | 1698 | unsigned left_pillar_width; |
1309 | unsigned twopixsize = tpg->twopixelsize[p]; | 1699 | unsigned right_pillar_start; |
1310 | unsigned img_width = tpg->compose.width * twopixsize / 2; | 1700 | }; |
1311 | unsigned line_offset; | ||
1312 | unsigned left_pillar_width = 0; | ||
1313 | unsigned right_pillar_start = img_width; | ||
1314 | unsigned stride = tpg->bytesperline[p]; | ||
1315 | unsigned factor = V4L2_FIELD_HAS_T_OR_B(tpg->field) ? 2 : 1; | ||
1316 | u8 *orig_vbuf = vbuf; | ||
1317 | 1701 | ||
1318 | /* Coarse scaling with Bresenham */ | 1702 | static void tpg_fill_params_pattern(const struct tpg_data *tpg, unsigned p, |
1319 | unsigned int_part = (tpg->crop.height / factor) / tpg->compose.height; | 1703 | struct tpg_draw_params *params) |
1320 | unsigned fract_part = (tpg->crop.height / factor) % tpg->compose.height; | 1704 | { |
1321 | unsigned src_y = 0; | 1705 | params->mv_hor_old = |
1322 | unsigned error = 0; | 1706 | tpg_hscale_div(tpg, p, tpg->mv_hor_count % tpg->src_width); |
1707 | params->mv_hor_new = | ||
1708 | tpg_hscale_div(tpg, p, (tpg->mv_hor_count + tpg->mv_hor_step) % | ||
1709 | tpg->src_width); | ||
1710 | params->mv_vert_old = tpg->mv_vert_count % tpg->src_height; | ||
1711 | params->mv_vert_new = | ||
1712 | (tpg->mv_vert_count + tpg->mv_vert_step) % tpg->src_height; | ||
1713 | } | ||
1323 | 1714 | ||
1324 | tpg_recalc(tpg); | 1715 | static void tpg_fill_params_extras(const struct tpg_data *tpg, |
1716 | unsigned p, | ||
1717 | struct tpg_draw_params *params) | ||
1718 | { | ||
1719 | unsigned left_pillar_width = 0; | ||
1720 | unsigned right_pillar_start = params->img_width; | ||
1721 | |||
1722 | params->wss_width = tpg->crop.left < tpg->src_width / 2 ? | ||
1723 | tpg->src_width / 2 - tpg->crop.left : 0; | ||
1724 | if (params->wss_width > tpg->crop.width) | ||
1725 | params->wss_width = tpg->crop.width; | ||
1726 | params->wss_width = tpg_hscale_div(tpg, p, params->wss_width); | ||
1727 | params->wss_random_offset = | ||
1728 | params->twopixsize * prandom_u32_max(tpg->src_width / 2); | ||
1325 | 1729 | ||
1326 | mv_hor_old = (mv_hor_old * tpg->scaled_width / tpg->src_width) & ~1; | ||
1327 | mv_hor_new = (mv_hor_new * tpg->scaled_width / tpg->src_width) & ~1; | ||
1328 | wss_width = tpg->crop.left < tpg->src_width / 2 ? | ||
1329 | tpg->src_width / 2 - tpg->crop.left : 0; | ||
1330 | if (wss_width > tpg->crop.width) | ||
1331 | wss_width = tpg->crop.width; | ||
1332 | wss_width = wss_width * tpg->scaled_width / tpg->src_width; | ||
1333 | |||
1334 | vbuf += tpg->compose.left * twopixsize / 2; | ||
1335 | line_offset = tpg->crop.left * tpg->scaled_width / tpg->src_width; | ||
1336 | line_offset = (line_offset & ~1) * twopixsize / 2; | ||
1337 | if (tpg->crop.left < tpg->border.left) { | 1730 | if (tpg->crop.left < tpg->border.left) { |
1338 | left_pillar_width = tpg->border.left - tpg->crop.left; | 1731 | left_pillar_width = tpg->border.left - tpg->crop.left; |
1339 | if (left_pillar_width > tpg->crop.width) | 1732 | if (left_pillar_width > tpg->crop.width) |
1340 | left_pillar_width = tpg->crop.width; | 1733 | left_pillar_width = tpg->crop.width; |
1341 | left_pillar_width = (left_pillar_width * tpg->scaled_width) / tpg->src_width; | 1734 | left_pillar_width = tpg_hscale_div(tpg, p, left_pillar_width); |
1342 | left_pillar_width = (left_pillar_width & ~1) * twopixsize / 2; | ||
1343 | } | 1735 | } |
1344 | if (tpg->crop.left + tpg->crop.width > tpg->border.left + tpg->border.width) { | 1736 | params->left_pillar_width = left_pillar_width; |
1345 | right_pillar_start = tpg->border.left + tpg->border.width - tpg->crop.left; | 1737 | |
1346 | right_pillar_start = (right_pillar_start * tpg->scaled_width) / tpg->src_width; | 1738 | if (tpg->crop.left + tpg->crop.width > |
1347 | right_pillar_start = (right_pillar_start & ~1) * twopixsize / 2; | 1739 | tpg->border.left + tpg->border.width) { |
1348 | if (right_pillar_start > img_width) | 1740 | right_pillar_start = |
1349 | right_pillar_start = img_width; | 1741 | tpg->border.left + tpg->border.width - tpg->crop.left; |
1742 | right_pillar_start = | ||
1743 | tpg_hscale_div(tpg, p, right_pillar_start); | ||
1744 | if (right_pillar_start > params->img_width) | ||
1745 | right_pillar_start = params->img_width; | ||
1350 | } | 1746 | } |
1747 | params->right_pillar_start = right_pillar_start; | ||
1351 | 1748 | ||
1352 | f = tpg->field == (is_60hz ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM); | 1749 | params->sav_eav_f = tpg->field == |
1750 | (params->is_60hz ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM); | ||
1751 | } | ||
1353 | 1752 | ||
1354 | for (h = 0; h < tpg->compose.height; h++) { | 1753 | static void tpg_fill_plane_extras(const struct tpg_data *tpg, |
1355 | bool even; | 1754 | const struct tpg_draw_params *params, |
1356 | bool fill_blank = false; | 1755 | unsigned p, unsigned h, u8 *vbuf) |
1357 | unsigned frame_line; | 1756 | { |
1358 | unsigned buf_line; | 1757 | unsigned twopixsize = params->twopixsize; |
1359 | unsigned pat_line_old; | 1758 | unsigned img_width = params->img_width; |
1360 | unsigned pat_line_new; | 1759 | unsigned frame_line = params->frame_line; |
1361 | u8 *linestart_older; | 1760 | const struct v4l2_rect *sq = &tpg->square; |
1362 | u8 *linestart_newer; | 1761 | const struct v4l2_rect *b = &tpg->border; |
1363 | u8 *linestart_top; | 1762 | const struct v4l2_rect *c = &tpg->crop; |
1364 | u8 *linestart_bottom; | 1763 | |
1365 | 1764 | if (params->is_tv && !params->is_60hz && | |
1366 | frame_line = tpg_calc_frameline(tpg, src_y, tpg->field); | 1765 | frame_line == 0 && params->wss_width) { |
1367 | even = !(frame_line & 1); | 1766 | /* |
1368 | buf_line = tpg_calc_buffer_line(tpg, h, tpg->field); | 1767 | * Replace the first half of the top line of a 50 Hz frame |
1369 | src_y += int_part; | 1768 | * with random data to simulate a WSS signal. |
1370 | error += fract_part; | 1769 | */ |
1371 | if (error >= tpg->compose.height) { | 1770 | u8 *wss = tpg->random_line[p] + params->wss_random_offset; |
1372 | error -= tpg->compose.height; | ||
1373 | src_y++; | ||
1374 | } | ||
1375 | 1771 | ||
1376 | if (h >= hmax) { | 1772 | memcpy(vbuf, wss, params->wss_width); |
1377 | if (hmax == tpg->compose.height) | 1773 | } |
1378 | continue; | 1774 | |
1379 | if (!tpg->perc_fill_blank) | 1775 | if (tpg->show_border && frame_line >= b->top && |
1380 | continue; | 1776 | frame_line < b->top + b->height) { |
1381 | fill_blank = true; | 1777 | unsigned bottom = b->top + b->height - 1; |
1382 | } | 1778 | unsigned left = params->left_pillar_width; |
1779 | unsigned right = params->right_pillar_start; | ||
1383 | 1780 | ||
1384 | if (tpg->vflip) | 1781 | if (frame_line == b->top || frame_line == b->top + 1 || |
1385 | frame_line = tpg->src_height - frame_line - 1; | 1782 | frame_line == bottom || frame_line == bottom - 1) { |
1386 | 1783 | memcpy(vbuf + left, tpg->contrast_line[p], | |
1387 | if (fill_blank) { | 1784 | right - left); |
1388 | linestart_older = tpg->contrast_line[p]; | ||
1389 | linestart_newer = tpg->contrast_line[p]; | ||
1390 | } else if (tpg->qual != TPG_QUAL_NOISE && | ||
1391 | (frame_line < tpg->border.top || | ||
1392 | frame_line >= tpg->border.top + tpg->border.height)) { | ||
1393 | linestart_older = tpg->black_line[p]; | ||
1394 | linestart_newer = tpg->black_line[p]; | ||
1395 | } else if (tpg->pattern == TPG_PAT_NOISE || tpg->qual == TPG_QUAL_NOISE) { | ||
1396 | linestart_older = tpg->random_line[p] + | ||
1397 | twopixsize * prandom_u32_max(tpg->src_width / 2); | ||
1398 | linestart_newer = tpg->random_line[p] + | ||
1399 | twopixsize * prandom_u32_max(tpg->src_width / 2); | ||
1400 | } else { | 1785 | } else { |
1401 | pat_line_old = tpg_get_pat_line(tpg, | 1786 | if (b->left >= c->left && |
1402 | (frame_line + mv_vert_old) % tpg->src_height); | 1787 | b->left < c->left + c->width) |
1403 | pat_line_new = tpg_get_pat_line(tpg, | 1788 | memcpy(vbuf + left, |
1404 | (frame_line + mv_vert_new) % tpg->src_height); | 1789 | tpg->contrast_line[p], twopixsize); |
1405 | linestart_older = tpg->lines[pat_line_old][p] + | 1790 | if (b->left + b->width > c->left && |
1406 | mv_hor_old * twopixsize / 2; | 1791 | b->left + b->width <= c->left + c->width) |
1407 | linestart_newer = tpg->lines[pat_line_new][p] + | 1792 | memcpy(vbuf + right - twopixsize, |
1408 | mv_hor_new * twopixsize / 2; | 1793 | tpg->contrast_line[p], twopixsize); |
1409 | linestart_older += line_offset; | ||
1410 | linestart_newer += line_offset; | ||
1411 | } | 1794 | } |
1412 | if (is_60hz) { | 1795 | } |
1413 | linestart_top = linestart_newer; | 1796 | if (tpg->qual != TPG_QUAL_NOISE && frame_line >= b->top && |
1414 | linestart_bottom = linestart_older; | 1797 | frame_line < b->top + b->height) { |
1415 | } else { | 1798 | memcpy(vbuf, tpg->black_line[p], params->left_pillar_width); |
1416 | linestart_top = linestart_older; | 1799 | memcpy(vbuf + params->right_pillar_start, tpg->black_line[p], |
1417 | linestart_bottom = linestart_newer; | 1800 | img_width - params->right_pillar_start); |
1801 | } | ||
1802 | if (tpg->show_square && frame_line >= sq->top && | ||
1803 | frame_line < sq->top + sq->height && | ||
1804 | sq->left < c->left + c->width && | ||
1805 | sq->left + sq->width >= c->left) { | ||
1806 | unsigned left = sq->left; | ||
1807 | unsigned width = sq->width; | ||
1808 | |||
1809 | if (c->left > left) { | ||
1810 | width -= c->left - left; | ||
1811 | left = c->left; | ||
1418 | } | 1812 | } |
1813 | if (c->left + c->width < left + width) | ||
1814 | width -= left + width - c->left - c->width; | ||
1815 | left -= c->left; | ||
1816 | left = tpg_hscale_div(tpg, p, left); | ||
1817 | width = tpg_hscale_div(tpg, p, width); | ||
1818 | memcpy(vbuf + left, tpg->contrast_line[p], width); | ||
1819 | } | ||
1820 | if (tpg->insert_sav) { | ||
1821 | unsigned offset = tpg_hdiv(tpg, p, tpg->compose.width / 3); | ||
1822 | u8 *p = vbuf + offset; | ||
1823 | unsigned vact = 0, hact = 0; | ||
1824 | |||
1825 | p[0] = 0xff; | ||
1826 | p[1] = 0; | ||
1827 | p[2] = 0; | ||
1828 | p[3] = 0x80 | (params->sav_eav_f << 6) | | ||
1829 | (vact << 5) | (hact << 4) | | ||
1830 | ((hact ^ vact) << 3) | | ||
1831 | ((hact ^ params->sav_eav_f) << 2) | | ||
1832 | ((params->sav_eav_f ^ vact) << 1) | | ||
1833 | (hact ^ vact ^ params->sav_eav_f); | ||
1834 | } | ||
1835 | if (tpg->insert_eav) { | ||
1836 | unsigned offset = tpg_hdiv(tpg, p, tpg->compose.width * 2 / 3); | ||
1837 | u8 *p = vbuf + offset; | ||
1838 | unsigned vact = 0, hact = 1; | ||
1839 | |||
1840 | p[0] = 0xff; | ||
1841 | p[1] = 0; | ||
1842 | p[2] = 0; | ||
1843 | p[3] = 0x80 | (params->sav_eav_f << 6) | | ||
1844 | (vact << 5) | (hact << 4) | | ||
1845 | ((hact ^ vact) << 3) | | ||
1846 | ((hact ^ params->sav_eav_f) << 2) | | ||
1847 | ((params->sav_eav_f ^ vact) << 1) | | ||
1848 | (hact ^ vact ^ params->sav_eav_f); | ||
1849 | } | ||
1850 | } | ||
1419 | 1851 | ||
1420 | switch (tpg->field) { | 1852 | static void tpg_fill_plane_pattern(const struct tpg_data *tpg, |
1421 | case V4L2_FIELD_INTERLACED: | 1853 | const struct tpg_draw_params *params, |
1422 | case V4L2_FIELD_INTERLACED_TB: | 1854 | unsigned p, unsigned h, u8 *vbuf) |
1423 | case V4L2_FIELD_SEQ_TB: | 1855 | { |
1424 | case V4L2_FIELD_SEQ_BT: | 1856 | unsigned twopixsize = params->twopixsize; |
1425 | if (even) | 1857 | unsigned img_width = params->img_width; |
1426 | memcpy(vbuf + buf_line * stride, linestart_top, img_width); | 1858 | unsigned mv_hor_old = params->mv_hor_old; |
1427 | else | 1859 | unsigned mv_hor_new = params->mv_hor_new; |
1428 | memcpy(vbuf + buf_line * stride, linestart_bottom, img_width); | 1860 | unsigned mv_vert_old = params->mv_vert_old; |
1429 | break; | 1861 | unsigned mv_vert_new = params->mv_vert_new; |
1430 | case V4L2_FIELD_INTERLACED_BT: | 1862 | unsigned frame_line = params->frame_line; |
1431 | if (even) | 1863 | unsigned frame_line_next = params->frame_line_next; |
1432 | memcpy(vbuf + buf_line * stride, linestart_bottom, img_width); | 1864 | unsigned line_offset = tpg_hscale_div(tpg, p, tpg->crop.left); |
1433 | else | 1865 | bool even; |
1434 | memcpy(vbuf + buf_line * stride, linestart_top, img_width); | 1866 | bool fill_blank = false; |
1435 | break; | 1867 | unsigned pat_line_old; |
1436 | case V4L2_FIELD_TOP: | 1868 | unsigned pat_line_new; |
1437 | memcpy(vbuf + buf_line * stride, linestart_top, img_width); | 1869 | u8 *linestart_older; |
1438 | break; | 1870 | u8 *linestart_newer; |
1439 | case V4L2_FIELD_BOTTOM: | 1871 | u8 *linestart_top; |
1440 | memcpy(vbuf + buf_line * stride, linestart_bottom, img_width); | 1872 | u8 *linestart_bottom; |
1441 | break; | 1873 | |
1442 | case V4L2_FIELD_NONE: | 1874 | even = !(frame_line & 1); |
1443 | default: | 1875 | |
1444 | memcpy(vbuf + buf_line * stride, linestart_older, img_width); | 1876 | if (h >= params->hmax) { |
1445 | break; | 1877 | if (params->hmax == tpg->compose.height) |
1446 | } | 1878 | return; |
1879 | if (!tpg->perc_fill_blank) | ||
1880 | return; | ||
1881 | fill_blank = true; | ||
1882 | } | ||
1447 | 1883 | ||
1448 | if (is_tv && !is_60hz && frame_line == 0 && wss_width) { | 1884 | if (tpg->vflip) { |
1449 | /* | 1885 | frame_line = tpg->src_height - frame_line - 1; |
1450 | * Replace the first half of the top line of a 50 Hz frame | 1886 | frame_line_next = tpg->src_height - frame_line_next - 1; |
1451 | * with random data to simulate a WSS signal. | 1887 | } |
1452 | */ | 1888 | |
1453 | u8 *wss = tpg->random_line[p] + | 1889 | if (fill_blank) { |
1890 | linestart_older = tpg->contrast_line[p]; | ||
1891 | linestart_newer = tpg->contrast_line[p]; | ||
1892 | } else if (tpg->qual != TPG_QUAL_NOISE && | ||
1893 | (frame_line < tpg->border.top || | ||
1894 | frame_line >= tpg->border.top + tpg->border.height)) { | ||
1895 | linestart_older = tpg->black_line[p]; | ||
1896 | linestart_newer = tpg->black_line[p]; | ||
1897 | } else if (tpg->pattern == TPG_PAT_NOISE || tpg->qual == TPG_QUAL_NOISE) { | ||
1898 | linestart_older = tpg->random_line[p] + | ||
1899 | twopixsize * prandom_u32_max(tpg->src_width / 2); | ||
1900 | linestart_newer = tpg->random_line[p] + | ||
1454 | twopixsize * prandom_u32_max(tpg->src_width / 2); | 1901 | twopixsize * prandom_u32_max(tpg->src_width / 2); |
1902 | } else { | ||
1903 | unsigned frame_line_old = | ||
1904 | (frame_line + mv_vert_old) % tpg->src_height; | ||
1905 | unsigned frame_line_new = | ||
1906 | (frame_line + mv_vert_new) % tpg->src_height; | ||
1907 | unsigned pat_line_next_old; | ||
1908 | unsigned pat_line_next_new; | ||
1455 | 1909 | ||
1456 | memcpy(vbuf + buf_line * stride, wss, wss_width * twopixsize / 2); | 1910 | pat_line_old = tpg_get_pat_line(tpg, frame_line_old); |
1911 | pat_line_new = tpg_get_pat_line(tpg, frame_line_new); | ||
1912 | linestart_older = tpg->lines[pat_line_old][p] + mv_hor_old; | ||
1913 | linestart_newer = tpg->lines[pat_line_new][p] + mv_hor_new; | ||
1914 | |||
1915 | if (tpg->vdownsampling[p] > 1 && frame_line != frame_line_next) { | ||
1916 | int avg_pat; | ||
1917 | |||
1918 | /* | ||
1919 | * Now decide whether we need to use downsampled_lines[]. | ||
1920 | * That's necessary if the two lines use different patterns. | ||
1921 | */ | ||
1922 | pat_line_next_old = tpg_get_pat_line(tpg, | ||
1923 | (frame_line_next + mv_vert_old) % tpg->src_height); | ||
1924 | pat_line_next_new = tpg_get_pat_line(tpg, | ||
1925 | (frame_line_next + mv_vert_new) % tpg->src_height); | ||
1926 | |||
1927 | switch (tpg->field) { | ||
1928 | case V4L2_FIELD_INTERLACED: | ||
1929 | case V4L2_FIELD_INTERLACED_BT: | ||
1930 | case V4L2_FIELD_INTERLACED_TB: | ||
1931 | avg_pat = tpg_pattern_avg(tpg, pat_line_old, pat_line_new); | ||
1932 | if (avg_pat < 0) | ||
1933 | break; | ||
1934 | linestart_older = tpg->downsampled_lines[avg_pat][p] + mv_hor_old; | ||
1935 | linestart_newer = linestart_older; | ||
1936 | break; | ||
1937 | case V4L2_FIELD_NONE: | ||
1938 | case V4L2_FIELD_TOP: | ||
1939 | case V4L2_FIELD_BOTTOM: | ||
1940 | case V4L2_FIELD_SEQ_BT: | ||
1941 | case V4L2_FIELD_SEQ_TB: | ||
1942 | avg_pat = tpg_pattern_avg(tpg, pat_line_old, pat_line_next_old); | ||
1943 | if (avg_pat >= 0) | ||
1944 | linestart_older = tpg->downsampled_lines[avg_pat][p] + | ||
1945 | mv_hor_old; | ||
1946 | avg_pat = tpg_pattern_avg(tpg, pat_line_new, pat_line_next_new); | ||
1947 | if (avg_pat >= 0) | ||
1948 | linestart_newer = tpg->downsampled_lines[avg_pat][p] + | ||
1949 | mv_hor_new; | ||
1950 | break; | ||
1951 | } | ||
1457 | } | 1952 | } |
1953 | linestart_older += line_offset; | ||
1954 | linestart_newer += line_offset; | ||
1955 | } | ||
1956 | if (tpg->field_alternate) { | ||
1957 | linestart_top = linestart_bottom = linestart_older; | ||
1958 | } else if (params->is_60hz) { | ||
1959 | linestart_top = linestart_newer; | ||
1960 | linestart_bottom = linestart_older; | ||
1961 | } else { | ||
1962 | linestart_top = linestart_older; | ||
1963 | linestart_bottom = linestart_newer; | ||
1964 | } | ||
1965 | |||
1966 | switch (tpg->field) { | ||
1967 | case V4L2_FIELD_INTERLACED: | ||
1968 | case V4L2_FIELD_INTERLACED_TB: | ||
1969 | case V4L2_FIELD_SEQ_TB: | ||
1970 | case V4L2_FIELD_SEQ_BT: | ||
1971 | if (even) | ||
1972 | memcpy(vbuf, linestart_top, img_width); | ||
1973 | else | ||
1974 | memcpy(vbuf, linestart_bottom, img_width); | ||
1975 | break; | ||
1976 | case V4L2_FIELD_INTERLACED_BT: | ||
1977 | if (even) | ||
1978 | memcpy(vbuf, linestart_bottom, img_width); | ||
1979 | else | ||
1980 | memcpy(vbuf, linestart_top, img_width); | ||
1981 | break; | ||
1982 | case V4L2_FIELD_TOP: | ||
1983 | memcpy(vbuf, linestart_top, img_width); | ||
1984 | break; | ||
1985 | case V4L2_FIELD_BOTTOM: | ||
1986 | memcpy(vbuf, linestart_bottom, img_width); | ||
1987 | break; | ||
1988 | case V4L2_FIELD_NONE: | ||
1989 | default: | ||
1990 | memcpy(vbuf, linestart_older, img_width); | ||
1991 | break; | ||
1458 | } | 1992 | } |
1993 | } | ||
1994 | |||
1995 | void tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std, | ||
1996 | unsigned p, u8 *vbuf) | ||
1997 | { | ||
1998 | struct tpg_draw_params params; | ||
1999 | unsigned factor = V4L2_FIELD_HAS_T_OR_B(tpg->field) ? 2 : 1; | ||
2000 | |||
2001 | /* Coarse scaling with Bresenham */ | ||
2002 | unsigned int_part = (tpg->crop.height / factor) / tpg->compose.height; | ||
2003 | unsigned fract_part = (tpg->crop.height / factor) % tpg->compose.height; | ||
2004 | unsigned src_y = 0; | ||
2005 | unsigned error = 0; | ||
2006 | unsigned h; | ||
2007 | |||
2008 | tpg_recalc(tpg); | ||
2009 | |||
2010 | params.is_tv = std; | ||
2011 | params.is_60hz = std & V4L2_STD_525_60; | ||
2012 | params.twopixsize = tpg->twopixelsize[p]; | ||
2013 | params.img_width = tpg_hdiv(tpg, p, tpg->compose.width); | ||
2014 | params.stride = tpg->bytesperline[p]; | ||
2015 | params.hmax = (tpg->compose.height * tpg->perc_fill) / 100; | ||
2016 | |||
2017 | tpg_fill_params_pattern(tpg, p, ¶ms); | ||
2018 | tpg_fill_params_extras(tpg, p, ¶ms); | ||
2019 | |||
2020 | vbuf += tpg_hdiv(tpg, p, tpg->compose.left); | ||
1459 | 2021 | ||
1460 | vbuf = orig_vbuf; | ||
1461 | vbuf += tpg->compose.left * twopixsize / 2; | ||
1462 | src_y = 0; | ||
1463 | error = 0; | ||
1464 | for (h = 0; h < tpg->compose.height; h++) { | 2022 | for (h = 0; h < tpg->compose.height; h++) { |
1465 | unsigned frame_line = tpg_calc_frameline(tpg, src_y, tpg->field); | 2023 | unsigned buf_line; |
1466 | unsigned buf_line = tpg_calc_buffer_line(tpg, h, tpg->field); | ||
1467 | const struct v4l2_rect *sq = &tpg->square; | ||
1468 | const struct v4l2_rect *b = &tpg->border; | ||
1469 | const struct v4l2_rect *c = &tpg->crop; | ||
1470 | 2024 | ||
2025 | params.frame_line = tpg_calc_frameline(tpg, src_y, tpg->field); | ||
2026 | params.frame_line_next = params.frame_line; | ||
2027 | buf_line = tpg_calc_buffer_line(tpg, h, tpg->field); | ||
1471 | src_y += int_part; | 2028 | src_y += int_part; |
1472 | error += fract_part; | 2029 | error += fract_part; |
1473 | if (error >= tpg->compose.height) { | 2030 | if (error >= tpg->compose.height) { |
@@ -1475,80 +2032,61 @@ void tpg_fillbuffer(struct tpg_data *tpg, v4l2_std_id std, unsigned p, u8 *vbuf) | |||
1475 | src_y++; | 2032 | src_y++; |
1476 | } | 2033 | } |
1477 | 2034 | ||
1478 | if (tpg->show_border && frame_line >= b->top && | 2035 | /* |
1479 | frame_line < b->top + b->height) { | 2036 | * For line-interleaved formats determine the 'plane' |
1480 | unsigned bottom = b->top + b->height - 1; | 2037 | * based on the buffer line. |
1481 | unsigned left = left_pillar_width; | 2038 | */ |
1482 | unsigned right = right_pillar_start; | 2039 | if (tpg_g_interleaved(tpg)) |
2040 | p = tpg_g_interleaved_plane(tpg, buf_line); | ||
1483 | 2041 | ||
1484 | if (frame_line == b->top || frame_line == b->top + 1 || | 2042 | if (tpg->vdownsampling[p] > 1) { |
1485 | frame_line == bottom || frame_line == bottom - 1) { | 2043 | /* |
1486 | memcpy(vbuf + buf_line * stride + left, tpg->contrast_line[p], | 2044 | * When doing vertical downsampling the field setting |
1487 | right - left); | 2045 | * matters: for SEQ_BT/TB we downsample each field |
2046 | * separately (i.e. lines 0+2 are combined, as are | ||
2047 | * lines 1+3), for the other field settings we combine | ||
2048 | * odd and even lines. Doing that for SEQ_BT/TB would | ||
2049 | * be really weird. | ||
2050 | */ | ||
2051 | if (tpg->field == V4L2_FIELD_SEQ_BT || | ||
2052 | tpg->field == V4L2_FIELD_SEQ_TB) { | ||
2053 | unsigned next_src_y = src_y; | ||
2054 | |||
2055 | if ((h & 3) >= 2) | ||
2056 | continue; | ||
2057 | next_src_y += int_part; | ||
2058 | if (error + fract_part >= tpg->compose.height) | ||
2059 | next_src_y++; | ||
2060 | params.frame_line_next = | ||
2061 | tpg_calc_frameline(tpg, next_src_y, tpg->field); | ||
1488 | } else { | 2062 | } else { |
1489 | if (b->left >= c->left && | 2063 | if (h & 1) |
1490 | b->left < c->left + c->width) | 2064 | continue; |
1491 | memcpy(vbuf + buf_line * stride + left, | 2065 | params.frame_line_next = |
1492 | tpg->contrast_line[p], twopixsize); | 2066 | tpg_calc_frameline(tpg, src_y, tpg->field); |
1493 | if (b->left + b->width > c->left && | ||
1494 | b->left + b->width <= c->left + c->width) | ||
1495 | memcpy(vbuf + buf_line * stride + right - twopixsize, | ||
1496 | tpg->contrast_line[p], twopixsize); | ||
1497 | } | 2067 | } |
2068 | |||
2069 | buf_line /= tpg->vdownsampling[p]; | ||
1498 | } | 2070 | } |
1499 | if (tpg->qual != TPG_QUAL_NOISE && frame_line >= b->top && | 2071 | tpg_fill_plane_pattern(tpg, ¶ms, p, h, |
1500 | frame_line < b->top + b->height) { | 2072 | vbuf + buf_line * params.stride); |
1501 | memcpy(vbuf + buf_line * stride, tpg->black_line[p], left_pillar_width); | 2073 | tpg_fill_plane_extras(tpg, ¶ms, p, h, |
1502 | memcpy(vbuf + buf_line * stride + right_pillar_start, tpg->black_line[p], | 2074 | vbuf + buf_line * params.stride); |
1503 | img_width - right_pillar_start); | 2075 | } |
1504 | } | 2076 | } |
1505 | if (tpg->show_square && frame_line >= sq->top && | 2077 | |
1506 | frame_line < sq->top + sq->height && | 2078 | void tpg_fillbuffer(struct tpg_data *tpg, v4l2_std_id std, unsigned p, u8 *vbuf) |
1507 | sq->left < c->left + c->width && | 2079 | { |
1508 | sq->left + sq->width >= c->left) { | 2080 | unsigned offset = 0; |
1509 | unsigned left = sq->left; | 2081 | unsigned i; |
1510 | unsigned width = sq->width; | 2082 | |
1511 | 2083 | if (tpg->buffers > 1) { | |
1512 | if (c->left > left) { | 2084 | tpg_fill_plane_buffer(tpg, std, p, vbuf); |
1513 | width -= c->left - left; | 2085 | return; |
1514 | left = c->left; | 2086 | } |
1515 | } | 2087 | |
1516 | if (c->left + c->width < left + width) | 2088 | for (i = 0; i < tpg_g_planes(tpg); i++) { |
1517 | width -= left + width - c->left - c->width; | 2089 | tpg_fill_plane_buffer(tpg, std, i, vbuf + offset); |
1518 | left -= c->left; | 2090 | offset += tpg_calc_plane_size(tpg, i); |
1519 | left = (left * tpg->scaled_width) / tpg->src_width; | ||
1520 | left = (left & ~1) * twopixsize / 2; | ||
1521 | width = (width * tpg->scaled_width) / tpg->src_width; | ||
1522 | width = (width & ~1) * twopixsize / 2; | ||
1523 | memcpy(vbuf + buf_line * stride + left, tpg->contrast_line[p], width); | ||
1524 | } | ||
1525 | if (tpg->insert_sav) { | ||
1526 | unsigned offset = (tpg->compose.width / 6) * twopixsize; | ||
1527 | u8 *p = vbuf + buf_line * stride + offset; | ||
1528 | unsigned vact = 0, hact = 0; | ||
1529 | |||
1530 | p[0] = 0xff; | ||
1531 | p[1] = 0; | ||
1532 | p[2] = 0; | ||
1533 | p[3] = 0x80 | (f << 6) | (vact << 5) | (hact << 4) | | ||
1534 | ((hact ^ vact) << 3) | | ||
1535 | ((hact ^ f) << 2) | | ||
1536 | ((f ^ vact) << 1) | | ||
1537 | (hact ^ vact ^ f); | ||
1538 | } | ||
1539 | if (tpg->insert_eav) { | ||
1540 | unsigned offset = (tpg->compose.width / 6) * 2 * twopixsize; | ||
1541 | u8 *p = vbuf + buf_line * stride + offset; | ||
1542 | unsigned vact = 0, hact = 1; | ||
1543 | |||
1544 | p[0] = 0xff; | ||
1545 | p[1] = 0; | ||
1546 | p[2] = 0; | ||
1547 | p[3] = 0x80 | (f << 6) | (vact << 5) | (hact << 4) | | ||
1548 | ((hact ^ vact) << 3) | | ||
1549 | ((hact ^ f) << 2) | | ||
1550 | ((f ^ vact) << 1) | | ||
1551 | (hact ^ vact ^ f); | ||
1552 | } | ||
1553 | } | 2091 | } |
1554 | } | 2092 | } |
diff --git a/drivers/media/platform/vivid/vivid-tpg.h b/drivers/media/platform/vivid/vivid-tpg.h index bd8b1c760b3f..a50cd2e2535b 100644 --- a/drivers/media/platform/vivid/vivid-tpg.h +++ b/drivers/media/platform/vivid/vivid-tpg.h | |||
@@ -41,7 +41,10 @@ enum tpg_pattern { | |||
41 | TPG_PAT_GREEN, | 41 | TPG_PAT_GREEN, |
42 | TPG_PAT_BLUE, | 42 | TPG_PAT_BLUE, |
43 | TPG_PAT_CHECKERS_16X16, | 43 | TPG_PAT_CHECKERS_16X16, |
44 | TPG_PAT_CHECKERS_2X2, | ||
44 | TPG_PAT_CHECKERS_1X1, | 45 | TPG_PAT_CHECKERS_1X1, |
46 | TPG_PAT_COLOR_CHECKERS_2X2, | ||
47 | TPG_PAT_COLOR_CHECKERS_1X1, | ||
45 | TPG_PAT_ALTERNATING_HLINES, | 48 | TPG_PAT_ALTERNATING_HLINES, |
46 | TPG_PAT_ALTERNATING_VLINES, | 49 | TPG_PAT_ALTERNATING_VLINES, |
47 | TPG_PAT_CROSS_1_PIXEL, | 50 | TPG_PAT_CROSS_1_PIXEL, |
@@ -87,7 +90,7 @@ enum tpg_move_mode { | |||
87 | 90 | ||
88 | extern const char * const tpg_aspect_strings[]; | 91 | extern const char * const tpg_aspect_strings[]; |
89 | 92 | ||
90 | #define TPG_MAX_PLANES 2 | 93 | #define TPG_MAX_PLANES 3 |
91 | #define TPG_MAX_PAT_LINES 8 | 94 | #define TPG_MAX_PAT_LINES 8 |
92 | 95 | ||
93 | struct tpg_data { | 96 | struct tpg_data { |
@@ -98,6 +101,7 @@ struct tpg_data { | |||
98 | /* Scaled output frame size */ | 101 | /* Scaled output frame size */ |
99 | unsigned scaled_width; | 102 | unsigned scaled_width; |
100 | u32 field; | 103 | u32 field; |
104 | bool field_alternate; | ||
101 | /* crop coordinates are frame-based */ | 105 | /* crop coordinates are frame-based */ |
102 | struct v4l2_rect crop; | 106 | struct v4l2_rect crop; |
103 | /* compose coordinates are format-based */ | 107 | /* compose coordinates are format-based */ |
@@ -134,7 +138,16 @@ struct tpg_data { | |||
134 | enum tpg_pixel_aspect pix_aspect; | 138 | enum tpg_pixel_aspect pix_aspect; |
135 | unsigned rgb_range; | 139 | unsigned rgb_range; |
136 | unsigned real_rgb_range; | 140 | unsigned real_rgb_range; |
141 | unsigned buffers; | ||
137 | unsigned planes; | 142 | unsigned planes; |
143 | bool interleaved; | ||
144 | u8 vdownsampling[TPG_MAX_PLANES]; | ||
145 | u8 hdownsampling[TPG_MAX_PLANES]; | ||
146 | /* | ||
147 | * horizontal positions must be ANDed with this value to enforce | ||
148 | * correct boundaries for packed YUYV values. | ||
149 | */ | ||
150 | unsigned hmask[TPG_MAX_PLANES]; | ||
138 | /* Used to store the colors in native format, either RGB or YUV */ | 151 | /* Used to store the colors in native format, either RGB or YUV */ |
139 | u8 colors[TPG_COLOR_MAX][3]; | 152 | u8 colors[TPG_COLOR_MAX][3]; |
140 | u8 textfg[TPG_MAX_PLANES][8], textbg[TPG_MAX_PLANES][8]; | 153 | u8 textfg[TPG_MAX_PLANES][8], textbg[TPG_MAX_PLANES][8]; |
@@ -168,6 +181,7 @@ struct tpg_data { | |||
168 | /* Used to store TPG_MAX_PAT_LINES lines, each with up to two planes */ | 181 | /* Used to store TPG_MAX_PAT_LINES lines, each with up to two planes */ |
169 | unsigned max_line_width; | 182 | unsigned max_line_width; |
170 | u8 *lines[TPG_MAX_PAT_LINES][TPG_MAX_PLANES]; | 183 | u8 *lines[TPG_MAX_PAT_LINES][TPG_MAX_PLANES]; |
184 | u8 *downsampled_lines[TPG_MAX_PAT_LINES][TPG_MAX_PLANES]; | ||
171 | u8 *random_line[TPG_MAX_PLANES]; | 185 | u8 *random_line[TPG_MAX_PLANES]; |
172 | u8 *contrast_line[TPG_MAX_PLANES]; | 186 | u8 *contrast_line[TPG_MAX_PLANES]; |
173 | u8 *black_line[TPG_MAX_PLANES]; | 187 | u8 *black_line[TPG_MAX_PLANES]; |
@@ -180,11 +194,15 @@ void tpg_reset_source(struct tpg_data *tpg, unsigned width, unsigned height, | |||
180 | u32 field); | 194 | u32 field); |
181 | 195 | ||
182 | void tpg_set_font(const u8 *f); | 196 | void tpg_set_font(const u8 *f); |
183 | void tpg_gen_text(struct tpg_data *tpg, | 197 | void tpg_gen_text(const struct tpg_data *tpg, |
184 | u8 *basep[TPG_MAX_PLANES][2], int y, int x, char *text); | 198 | u8 *basep[TPG_MAX_PLANES][2], int y, int x, char *text); |
185 | void tpg_calc_text_basep(struct tpg_data *tpg, | 199 | void tpg_calc_text_basep(struct tpg_data *tpg, |
186 | u8 *basep[TPG_MAX_PLANES][2], unsigned p, u8 *vbuf); | 200 | u8 *basep[TPG_MAX_PLANES][2], unsigned p, u8 *vbuf); |
187 | void tpg_fillbuffer(struct tpg_data *tpg, v4l2_std_id std, unsigned p, u8 *vbuf); | 201 | unsigned tpg_g_interleaved_plane(const struct tpg_data *tpg, unsigned buf_line); |
202 | void tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std, | ||
203 | unsigned p, u8 *vbuf); | ||
204 | void tpg_fillbuffer(struct tpg_data *tpg, v4l2_std_id std, | ||
205 | unsigned p, u8 *vbuf); | ||
188 | bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc); | 206 | bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc); |
189 | void tpg_s_crop_compose(struct tpg_data *tpg, const struct v4l2_rect *crop, | 207 | void tpg_s_crop_compose(struct tpg_data *tpg, const struct v4l2_rect *crop, |
190 | const struct v4l2_rect *compose); | 208 | const struct v4l2_rect *compose); |
@@ -323,9 +341,19 @@ static inline u32 tpg_g_quantization(const struct tpg_data *tpg) | |||
323 | return tpg->quantization; | 341 | return tpg->quantization; |
324 | } | 342 | } |
325 | 343 | ||
344 | static inline unsigned tpg_g_buffers(const struct tpg_data *tpg) | ||
345 | { | ||
346 | return tpg->buffers; | ||
347 | } | ||
348 | |||
326 | static inline unsigned tpg_g_planes(const struct tpg_data *tpg) | 349 | static inline unsigned tpg_g_planes(const struct tpg_data *tpg) |
327 | { | 350 | { |
328 | return tpg->planes; | 351 | return tpg->interleaved ? 1 : tpg->planes; |
352 | } | ||
353 | |||
354 | static inline bool tpg_g_interleaved(const struct tpg_data *tpg) | ||
355 | { | ||
356 | return tpg->interleaved; | ||
329 | } | 357 | } |
330 | 358 | ||
331 | static inline unsigned tpg_g_twopixelsize(const struct tpg_data *tpg, unsigned plane) | 359 | static inline unsigned tpg_g_twopixelsize(const struct tpg_data *tpg, unsigned plane) |
@@ -333,6 +361,24 @@ static inline unsigned tpg_g_twopixelsize(const struct tpg_data *tpg, unsigned p | |||
333 | return tpg->twopixelsize[plane]; | 361 | return tpg->twopixelsize[plane]; |
334 | } | 362 | } |
335 | 363 | ||
364 | static inline unsigned tpg_hdiv(const struct tpg_data *tpg, | ||
365 | unsigned plane, unsigned x) | ||
366 | { | ||
367 | return ((x / tpg->hdownsampling[plane]) & tpg->hmask[plane]) * | ||
368 | tpg->twopixelsize[plane] / 2; | ||
369 | } | ||
370 | |||
371 | static inline unsigned tpg_hscale(const struct tpg_data *tpg, unsigned x) | ||
372 | { | ||
373 | return (x * tpg->scaled_width) / tpg->src_width; | ||
374 | } | ||
375 | |||
376 | static inline unsigned tpg_hscale_div(const struct tpg_data *tpg, | ||
377 | unsigned plane, unsigned x) | ||
378 | { | ||
379 | return tpg_hdiv(tpg, plane, tpg_hscale(tpg, x)); | ||
380 | } | ||
381 | |||
336 | static inline unsigned tpg_g_bytesperline(const struct tpg_data *tpg, unsigned plane) | 382 | static inline unsigned tpg_g_bytesperline(const struct tpg_data *tpg, unsigned plane) |
337 | { | 383 | { |
338 | return tpg->bytesperline[plane]; | 384 | return tpg->bytesperline[plane]; |
@@ -340,7 +386,60 @@ static inline unsigned tpg_g_bytesperline(const struct tpg_data *tpg, unsigned p | |||
340 | 386 | ||
341 | static inline void tpg_s_bytesperline(struct tpg_data *tpg, unsigned plane, unsigned bpl) | 387 | static inline void tpg_s_bytesperline(struct tpg_data *tpg, unsigned plane, unsigned bpl) |
342 | { | 388 | { |
343 | tpg->bytesperline[plane] = bpl; | 389 | unsigned p; |
390 | |||
391 | if (tpg->buffers > 1) { | ||
392 | tpg->bytesperline[plane] = bpl; | ||
393 | return; | ||
394 | } | ||
395 | |||
396 | for (p = 0; p < tpg_g_planes(tpg); p++) { | ||
397 | unsigned plane_w = bpl * tpg->twopixelsize[p] / tpg->twopixelsize[0]; | ||
398 | |||
399 | tpg->bytesperline[p] = plane_w / tpg->hdownsampling[p]; | ||
400 | } | ||
401 | } | ||
402 | |||
403 | |||
404 | static inline unsigned tpg_g_line_width(const struct tpg_data *tpg, unsigned plane) | ||
405 | { | ||
406 | unsigned w = 0; | ||
407 | unsigned p; | ||
408 | |||
409 | if (tpg->buffers > 1) | ||
410 | return tpg_g_bytesperline(tpg, plane); | ||
411 | for (p = 0; p < tpg_g_planes(tpg); p++) { | ||
412 | unsigned plane_w = tpg_g_bytesperline(tpg, p); | ||
413 | |||
414 | w += plane_w / tpg->vdownsampling[p]; | ||
415 | } | ||
416 | return w; | ||
417 | } | ||
418 | |||
419 | static inline unsigned tpg_calc_line_width(const struct tpg_data *tpg, | ||
420 | unsigned plane, unsigned bpl) | ||
421 | { | ||
422 | unsigned w = 0; | ||
423 | unsigned p; | ||
424 | |||
425 | if (tpg->buffers > 1) | ||
426 | return bpl; | ||
427 | for (p = 0; p < tpg_g_planes(tpg); p++) { | ||
428 | unsigned plane_w = bpl * tpg->twopixelsize[p] / tpg->twopixelsize[0]; | ||
429 | |||
430 | plane_w /= tpg->hdownsampling[p]; | ||
431 | w += plane_w / tpg->vdownsampling[p]; | ||
432 | } | ||
433 | return w; | ||
434 | } | ||
435 | |||
436 | static inline unsigned tpg_calc_plane_size(const struct tpg_data *tpg, unsigned plane) | ||
437 | { | ||
438 | if (plane >= tpg_g_planes(tpg)) | ||
439 | return 0; | ||
440 | |||
441 | return tpg_g_bytesperline(tpg, plane) * tpg->buf_height / | ||
442 | tpg->vdownsampling[plane]; | ||
344 | } | 443 | } |
345 | 444 | ||
346 | static inline void tpg_s_buf_height(struct tpg_data *tpg, unsigned h) | 445 | static inline void tpg_s_buf_height(struct tpg_data *tpg, unsigned h) |
@@ -348,9 +447,10 @@ static inline void tpg_s_buf_height(struct tpg_data *tpg, unsigned h) | |||
348 | tpg->buf_height = h; | 447 | tpg->buf_height = h; |
349 | } | 448 | } |
350 | 449 | ||
351 | static inline void tpg_s_field(struct tpg_data *tpg, unsigned field) | 450 | static inline void tpg_s_field(struct tpg_data *tpg, unsigned field, bool alternate) |
352 | { | 451 | { |
353 | tpg->field = field; | 452 | tpg->field = field; |
453 | tpg->field_alternate = alternate; | ||
354 | } | 454 | } |
355 | 455 | ||
356 | static inline void tpg_s_perc_fill(struct tpg_data *tpg, | 456 | static inline void tpg_s_perc_fill(struct tpg_data *tpg, |
diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c b/drivers/media/platform/vivid/vivid-vid-cap.c index 867a29a6d18f..dab5990f45a0 100644 --- a/drivers/media/platform/vivid/vivid-vid-cap.c +++ b/drivers/media/platform/vivid/vivid-vid-cap.c | |||
@@ -42,20 +42,26 @@ static const struct vivid_fmt formats_ovl[] = { | |||
42 | { | 42 | { |
43 | .name = "RGB565 (LE)", | 43 | .name = "RGB565 (LE)", |
44 | .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */ | 44 | .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */ |
45 | .depth = 16, | 45 | .vdownsampling = { 1 }, |
46 | .bit_depth = { 16 }, | ||
46 | .planes = 1, | 47 | .planes = 1, |
48 | .buffers = 1, | ||
47 | }, | 49 | }, |
48 | { | 50 | { |
49 | .name = "XRGB555 (LE)", | 51 | .name = "XRGB555 (LE)", |
50 | .fourcc = V4L2_PIX_FMT_XRGB555, /* gggbbbbb arrrrrgg */ | 52 | .fourcc = V4L2_PIX_FMT_XRGB555, /* gggbbbbb arrrrrgg */ |
51 | .depth = 16, | 53 | .vdownsampling = { 1 }, |
54 | .bit_depth = { 16 }, | ||
52 | .planes = 1, | 55 | .planes = 1, |
56 | .buffers = 1, | ||
53 | }, | 57 | }, |
54 | { | 58 | { |
55 | .name = "ARGB555 (LE)", | 59 | .name = "ARGB555 (LE)", |
56 | .fourcc = V4L2_PIX_FMT_ARGB555, /* gggbbbbb arrrrrgg */ | 60 | .fourcc = V4L2_PIX_FMT_ARGB555, /* gggbbbbb arrrrrgg */ |
57 | .depth = 16, | 61 | .vdownsampling = { 1 }, |
62 | .bit_depth = { 16 }, | ||
58 | .planes = 1, | 63 | .planes = 1, |
64 | .buffers = 1, | ||
59 | }, | 65 | }, |
60 | }; | 66 | }; |
61 | 67 | ||
@@ -94,7 +100,7 @@ static int vid_cap_queue_setup(struct vb2_queue *vq, const struct v4l2_format *f | |||
94 | unsigned sizes[], void *alloc_ctxs[]) | 100 | unsigned sizes[], void *alloc_ctxs[]) |
95 | { | 101 | { |
96 | struct vivid_dev *dev = vb2_get_drv_priv(vq); | 102 | struct vivid_dev *dev = vb2_get_drv_priv(vq); |
97 | unsigned planes = tpg_g_planes(&dev->tpg); | 103 | unsigned buffers = tpg_g_buffers(&dev->tpg); |
98 | unsigned h = dev->fmt_cap_rect.height; | 104 | unsigned h = dev->fmt_cap_rect.height; |
99 | unsigned p; | 105 | unsigned p; |
100 | 106 | ||
@@ -127,39 +133,36 @@ static int vid_cap_queue_setup(struct vb2_queue *vq, const struct v4l2_format *f | |||
127 | mp = &fmt->fmt.pix_mp; | 133 | mp = &fmt->fmt.pix_mp; |
128 | /* | 134 | /* |
129 | * Check if the number of planes in the specified format match | 135 | * Check if the number of planes in the specified format match |
130 | * the number of planes in the current format. You can't mix that. | 136 | * the number of buffers in the current format. You can't mix that. |
131 | */ | 137 | */ |
132 | if (mp->num_planes != planes) | 138 | if (mp->num_planes != buffers) |
133 | return -EINVAL; | 139 | return -EINVAL; |
134 | vfmt = vivid_get_format(dev, mp->pixelformat); | 140 | vfmt = vivid_get_format(dev, mp->pixelformat); |
135 | for (p = 0; p < planes; p++) { | 141 | for (p = 0; p < buffers; p++) { |
136 | sizes[p] = mp->plane_fmt[p].sizeimage; | 142 | sizes[p] = mp->plane_fmt[p].sizeimage; |
137 | if (sizes[0] < tpg_g_bytesperline(&dev->tpg, 0) * h + | 143 | if (sizes[p] < tpg_g_line_width(&dev->tpg, p) * h + |
138 | vfmt->data_offset[p]) | 144 | vfmt->data_offset[p]) |
139 | return -EINVAL; | 145 | return -EINVAL; |
140 | } | 146 | } |
141 | } else { | 147 | } else { |
142 | for (p = 0; p < planes; p++) | 148 | for (p = 0; p < buffers; p++) |
143 | sizes[p] = tpg_g_bytesperline(&dev->tpg, p) * h + | 149 | sizes[p] = tpg_g_line_width(&dev->tpg, p) * h + |
144 | dev->fmt_cap->data_offset[p]; | 150 | dev->fmt_cap->data_offset[p]; |
145 | } | 151 | } |
146 | 152 | ||
147 | if (vq->num_buffers + *nbuffers < 2) | 153 | if (vq->num_buffers + *nbuffers < 2) |
148 | *nbuffers = 2 - vq->num_buffers; | 154 | *nbuffers = 2 - vq->num_buffers; |
149 | 155 | ||
150 | *nplanes = planes; | 156 | *nplanes = buffers; |
151 | 157 | ||
152 | /* | 158 | /* |
153 | * videobuf2-vmalloc allocator is context-less so no need to set | 159 | * videobuf2-vmalloc allocator is context-less so no need to set |
154 | * alloc_ctxs array. | 160 | * alloc_ctxs array. |
155 | */ | 161 | */ |
156 | 162 | ||
157 | if (planes == 2) | 163 | dprintk(dev, 1, "%s: count=%d\n", __func__, *nbuffers); |
158 | dprintk(dev, 1, "%s, count=%d, sizes=%u, %u\n", __func__, | 164 | for (p = 0; p < buffers; p++) |
159 | *nbuffers, sizes[0], sizes[1]); | 165 | dprintk(dev, 1, "%s: size[%u]=%u\n", __func__, p, sizes[p]); |
160 | else | ||
161 | dprintk(dev, 1, "%s, count=%d, size=%u\n", __func__, | ||
162 | *nbuffers, sizes[0]); | ||
163 | 166 | ||
164 | return 0; | 167 | return 0; |
165 | } | 168 | } |
@@ -168,7 +171,7 @@ static int vid_cap_buf_prepare(struct vb2_buffer *vb) | |||
168 | { | 171 | { |
169 | struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue); | 172 | struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue); |
170 | unsigned long size; | 173 | unsigned long size; |
171 | unsigned planes = tpg_g_planes(&dev->tpg); | 174 | unsigned buffers = tpg_g_buffers(&dev->tpg); |
172 | unsigned p; | 175 | unsigned p; |
173 | 176 | ||
174 | dprintk(dev, 1, "%s\n", __func__); | 177 | dprintk(dev, 1, "%s\n", __func__); |
@@ -184,13 +187,13 @@ static int vid_cap_buf_prepare(struct vb2_buffer *vb) | |||
184 | dev->buf_prepare_error = false; | 187 | dev->buf_prepare_error = false; |
185 | return -EINVAL; | 188 | return -EINVAL; |
186 | } | 189 | } |
187 | for (p = 0; p < planes; p++) { | 190 | for (p = 0; p < buffers; p++) { |
188 | size = tpg_g_bytesperline(&dev->tpg, p) * dev->fmt_cap_rect.height + | 191 | size = tpg_g_line_width(&dev->tpg, p) * dev->fmt_cap_rect.height + |
189 | dev->fmt_cap->data_offset[p]; | 192 | dev->fmt_cap->data_offset[p]; |
190 | 193 | ||
191 | if (vb2_plane_size(vb, 0) < size) { | 194 | if (vb2_plane_size(vb, p) < size) { |
192 | dprintk(dev, 1, "%s data will not fit into plane %u (%lu < %lu)\n", | 195 | dprintk(dev, 1, "%s data will not fit into plane %u (%lu < %lu)\n", |
193 | __func__, p, vb2_plane_size(vb, 0), size); | 196 | __func__, p, vb2_plane_size(vb, p), size); |
194 | return -EINVAL; | 197 | return -EINVAL; |
195 | } | 198 | } |
196 | 199 | ||
@@ -441,7 +444,7 @@ void vivid_update_format_cap(struct vivid_dev *dev, bool keep_controls) | |||
441 | */ | 444 | */ |
442 | if (keep_controls || !dev->colorspace) | 445 | if (keep_controls || !dev->colorspace) |
443 | break; | 446 | break; |
444 | if (bt->standards & V4L2_DV_BT_STD_CEA861) { | 447 | if (bt->flags & V4L2_DV_FL_IS_CE_VIDEO) { |
445 | if (bt->width == 720 && bt->height <= 576) | 448 | if (bt->width == 720 && bt->height <= 576) |
446 | v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_170M); | 449 | v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_170M); |
447 | else | 450 | else |
@@ -526,11 +529,11 @@ int vivid_g_fmt_vid_cap(struct file *file, void *priv, | |||
526 | mp->colorspace = vivid_colorspace_cap(dev); | 529 | mp->colorspace = vivid_colorspace_cap(dev); |
527 | mp->ycbcr_enc = vivid_ycbcr_enc_cap(dev); | 530 | mp->ycbcr_enc = vivid_ycbcr_enc_cap(dev); |
528 | mp->quantization = vivid_quantization_cap(dev); | 531 | mp->quantization = vivid_quantization_cap(dev); |
529 | mp->num_planes = dev->fmt_cap->planes; | 532 | mp->num_planes = dev->fmt_cap->buffers; |
530 | for (p = 0; p < mp->num_planes; p++) { | 533 | for (p = 0; p < mp->num_planes; p++) { |
531 | mp->plane_fmt[p].bytesperline = tpg_g_bytesperline(&dev->tpg, p); | 534 | mp->plane_fmt[p].bytesperline = tpg_g_bytesperline(&dev->tpg, p); |
532 | mp->plane_fmt[p].sizeimage = | 535 | mp->plane_fmt[p].sizeimage = |
533 | mp->plane_fmt[p].bytesperline * mp->height + | 536 | tpg_g_line_width(&dev->tpg, p) * mp->height + |
534 | dev->fmt_cap->data_offset[p]; | 537 | dev->fmt_cap->data_offset[p]; |
535 | } | 538 | } |
536 | return 0; | 539 | return 0; |
@@ -596,18 +599,19 @@ int vivid_try_fmt_vid_cap(struct file *file, void *priv, | |||
596 | 599 | ||
597 | /* This driver supports custom bytesperline values */ | 600 | /* This driver supports custom bytesperline values */ |
598 | 601 | ||
599 | /* Calculate the minimum supported bytesperline value */ | 602 | mp->num_planes = fmt->buffers; |
600 | bytesperline = (mp->width * fmt->depth) >> 3; | ||
601 | /* Calculate the maximum supported bytesperline value */ | ||
602 | max_bpl = (MAX_ZOOM * MAX_WIDTH * fmt->depth) >> 3; | ||
603 | mp->num_planes = fmt->planes; | ||
604 | for (p = 0; p < mp->num_planes; p++) { | 603 | for (p = 0; p < mp->num_planes; p++) { |
604 | /* Calculate the minimum supported bytesperline value */ | ||
605 | bytesperline = (mp->width * fmt->bit_depth[p]) >> 3; | ||
606 | /* Calculate the maximum supported bytesperline value */ | ||
607 | max_bpl = (MAX_ZOOM * MAX_WIDTH * fmt->bit_depth[p]) >> 3; | ||
608 | |||
605 | if (pfmt[p].bytesperline > max_bpl) | 609 | if (pfmt[p].bytesperline > max_bpl) |
606 | pfmt[p].bytesperline = max_bpl; | 610 | pfmt[p].bytesperline = max_bpl; |
607 | if (pfmt[p].bytesperline < bytesperline) | 611 | if (pfmt[p].bytesperline < bytesperline) |
608 | pfmt[p].bytesperline = bytesperline; | 612 | pfmt[p].bytesperline = bytesperline; |
609 | pfmt[p].sizeimage = pfmt[p].bytesperline * mp->height + | 613 | pfmt[p].sizeimage = tpg_calc_line_width(&dev->tpg, p, pfmt[p].bytesperline) * |
610 | fmt->data_offset[p]; | 614 | mp->height + fmt->data_offset[p]; |
611 | memset(pfmt[p].reserved, 0, sizeof(pfmt[p].reserved)); | 615 | memset(pfmt[p].reserved, 0, sizeof(pfmt[p].reserved)); |
612 | } | 616 | } |
613 | mp->colorspace = vivid_colorspace_cap(dev); | 617 | mp->colorspace = vivid_colorspace_cap(dev); |
@@ -627,6 +631,7 @@ int vivid_s_fmt_vid_cap(struct file *file, void *priv, | |||
627 | struct vb2_queue *q = &dev->vb_vid_cap_q; | 631 | struct vb2_queue *q = &dev->vb_vid_cap_q; |
628 | int ret = vivid_try_fmt_vid_cap(file, priv, f); | 632 | int ret = vivid_try_fmt_vid_cap(file, priv, f); |
629 | unsigned factor = 1; | 633 | unsigned factor = 1; |
634 | unsigned p; | ||
630 | unsigned i; | 635 | unsigned i; |
631 | 636 | ||
632 | if (ret < 0) | 637 | if (ret < 0) |
@@ -729,13 +734,15 @@ int vivid_s_fmt_vid_cap(struct file *file, void *priv, | |||
729 | dev->fmt_cap_rect.width = mp->width; | 734 | dev->fmt_cap_rect.width = mp->width; |
730 | dev->fmt_cap_rect.height = mp->height; | 735 | dev->fmt_cap_rect.height = mp->height; |
731 | tpg_s_buf_height(&dev->tpg, mp->height); | 736 | tpg_s_buf_height(&dev->tpg, mp->height); |
732 | tpg_s_bytesperline(&dev->tpg, 0, mp->plane_fmt[0].bytesperline); | 737 | tpg_s_fourcc(&dev->tpg, dev->fmt_cap->fourcc); |
733 | if (tpg_g_planes(&dev->tpg) > 1) | 738 | for (p = 0; p < tpg_g_buffers(&dev->tpg); p++) |
734 | tpg_s_bytesperline(&dev->tpg, 1, mp->plane_fmt[1].bytesperline); | 739 | tpg_s_bytesperline(&dev->tpg, p, mp->plane_fmt[p].bytesperline); |
735 | dev->field_cap = mp->field; | 740 | dev->field_cap = mp->field; |
736 | tpg_s_field(&dev->tpg, dev->field_cap); | 741 | if (dev->field_cap == V4L2_FIELD_ALTERNATE) |
742 | tpg_s_field(&dev->tpg, V4L2_FIELD_TOP, true); | ||
743 | else | ||
744 | tpg_s_field(&dev->tpg, dev->field_cap, false); | ||
737 | tpg_s_crop_compose(&dev->tpg, &dev->crop_cap, &dev->compose_cap); | 745 | tpg_s_crop_compose(&dev->tpg, &dev->crop_cap, &dev->compose_cap); |
738 | tpg_s_fourcc(&dev->tpg, dev->fmt_cap->fourcc); | ||
739 | if (vivid_is_sdtv_cap(dev)) | 746 | if (vivid_is_sdtv_cap(dev)) |
740 | dev->tv_field_cap = mp->field; | 747 | dev->tv_field_cap = mp->field; |
741 | tpg_update_mv_step(&dev->tpg); | 748 | tpg_update_mv_step(&dev->tpg); |
@@ -1012,8 +1019,12 @@ int vivid_vid_cap_cropcap(struct file *file, void *priv, | |||
1012 | int vidioc_enum_fmt_vid_overlay(struct file *file, void *priv, | 1019 | int vidioc_enum_fmt_vid_overlay(struct file *file, void *priv, |
1013 | struct v4l2_fmtdesc *f) | 1020 | struct v4l2_fmtdesc *f) |
1014 | { | 1021 | { |
1022 | struct vivid_dev *dev = video_drvdata(file); | ||
1015 | const struct vivid_fmt *fmt; | 1023 | const struct vivid_fmt *fmt; |
1016 | 1024 | ||
1025 | if (dev->multiplanar) | ||
1026 | return -ENOTTY; | ||
1027 | |||
1017 | if (f->index >= ARRAY_SIZE(formats_ovl)) | 1028 | if (f->index >= ARRAY_SIZE(formats_ovl)) |
1018 | return -EINVAL; | 1029 | return -EINVAL; |
1019 | 1030 | ||
@@ -1032,6 +1043,9 @@ int vidioc_g_fmt_vid_overlay(struct file *file, void *priv, | |||
1032 | struct v4l2_window *win = &f->fmt.win; | 1043 | struct v4l2_window *win = &f->fmt.win; |
1033 | unsigned clipcount = win->clipcount; | 1044 | unsigned clipcount = win->clipcount; |
1034 | 1045 | ||
1046 | if (dev->multiplanar) | ||
1047 | return -ENOTTY; | ||
1048 | |||
1035 | win->w.top = dev->overlay_cap_top; | 1049 | win->w.top = dev->overlay_cap_top; |
1036 | win->w.left = dev->overlay_cap_left; | 1050 | win->w.left = dev->overlay_cap_left; |
1037 | win->w.width = compose->width; | 1051 | win->w.width = compose->width; |
@@ -1063,6 +1077,9 @@ int vidioc_try_fmt_vid_overlay(struct file *file, void *priv, | |||
1063 | struct v4l2_window *win = &f->fmt.win; | 1077 | struct v4l2_window *win = &f->fmt.win; |
1064 | int i, j; | 1078 | int i, j; |
1065 | 1079 | ||
1080 | if (dev->multiplanar) | ||
1081 | return -ENOTTY; | ||
1082 | |||
1066 | win->w.left = clamp_t(int, win->w.left, | 1083 | win->w.left = clamp_t(int, win->w.left, |
1067 | -dev->fb_cap.fmt.width, dev->fb_cap.fmt.width); | 1084 | -dev->fb_cap.fmt.width, dev->fb_cap.fmt.width); |
1068 | win->w.top = clamp_t(int, win->w.top, | 1085 | win->w.top = clamp_t(int, win->w.top, |
@@ -1150,6 +1167,9 @@ int vivid_vid_cap_overlay(struct file *file, void *fh, unsigned i) | |||
1150 | { | 1167 | { |
1151 | struct vivid_dev *dev = video_drvdata(file); | 1168 | struct vivid_dev *dev = video_drvdata(file); |
1152 | 1169 | ||
1170 | if (dev->multiplanar) | ||
1171 | return -ENOTTY; | ||
1172 | |||
1153 | if (i && dev->fb_vbase_cap == NULL) | 1173 | if (i && dev->fb_vbase_cap == NULL) |
1154 | return -EINVAL; | 1174 | return -EINVAL; |
1155 | 1175 | ||
@@ -1169,6 +1189,9 @@ int vivid_vid_cap_g_fbuf(struct file *file, void *fh, | |||
1169 | { | 1189 | { |
1170 | struct vivid_dev *dev = video_drvdata(file); | 1190 | struct vivid_dev *dev = video_drvdata(file); |
1171 | 1191 | ||
1192 | if (dev->multiplanar) | ||
1193 | return -ENOTTY; | ||
1194 | |||
1172 | *a = dev->fb_cap; | 1195 | *a = dev->fb_cap; |
1173 | a->capability = V4L2_FBUF_CAP_BITMAP_CLIPPING | | 1196 | a->capability = V4L2_FBUF_CAP_BITMAP_CLIPPING | |
1174 | V4L2_FBUF_CAP_LIST_CLIPPING; | 1197 | V4L2_FBUF_CAP_LIST_CLIPPING; |
@@ -1185,6 +1208,9 @@ int vivid_vid_cap_s_fbuf(struct file *file, void *fh, | |||
1185 | struct vivid_dev *dev = video_drvdata(file); | 1208 | struct vivid_dev *dev = video_drvdata(file); |
1186 | const struct vivid_fmt *fmt; | 1209 | const struct vivid_fmt *fmt; |
1187 | 1210 | ||
1211 | if (dev->multiplanar) | ||
1212 | return -ENOTTY; | ||
1213 | |||
1188 | if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO)) | 1214 | if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO)) |
1189 | return -EPERM; | 1215 | return -EPERM; |
1190 | 1216 | ||
@@ -1202,7 +1228,7 @@ int vivid_vid_cap_s_fbuf(struct file *file, void *fh, | |||
1202 | fmt = vivid_get_format(dev, a->fmt.pixelformat); | 1228 | fmt = vivid_get_format(dev, a->fmt.pixelformat); |
1203 | if (!fmt || !fmt->can_do_overlay) | 1229 | if (!fmt || !fmt->can_do_overlay) |
1204 | return -EINVAL; | 1230 | return -EINVAL; |
1205 | if (a->fmt.bytesperline < (a->fmt.width * fmt->depth) / 8) | 1231 | if (a->fmt.bytesperline < (a->fmt.width * fmt->bit_depth[0]) / 8) |
1206 | return -EINVAL; | 1232 | return -EINVAL; |
1207 | if (a->fmt.height * a->fmt.bytesperline < a->fmt.sizeimage) | 1233 | if (a->fmt.height * a->fmt.bytesperline < a->fmt.sizeimage) |
1208 | return -EINVAL; | 1234 | return -EINVAL; |
@@ -1332,7 +1358,7 @@ int vidioc_s_input(struct file *file, void *priv, unsigned i) | |||
1332 | v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_170M); | 1358 | v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_170M); |
1333 | break; | 1359 | break; |
1334 | case HDMI: | 1360 | case HDMI: |
1335 | if (bt->standards & V4L2_DV_BT_STD_CEA861) { | 1361 | if (bt->flags & V4L2_DV_FL_IS_CE_VIDEO) { |
1336 | if (dev->src_rect.width == 720 && dev->src_rect.height <= 576) | 1362 | if (dev->src_rect.width == 720 && dev->src_rect.height <= 576) |
1337 | v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_170M); | 1363 | v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_170M); |
1338 | else | 1364 | else |
@@ -1552,6 +1578,65 @@ int vivid_vid_cap_s_std(struct file *file, void *priv, v4l2_std_id id) | |||
1552 | return 0; | 1578 | return 0; |
1553 | } | 1579 | } |
1554 | 1580 | ||
1581 | static void find_aspect_ratio(u32 width, u32 height, | ||
1582 | u32 *num, u32 *denom) | ||
1583 | { | ||
1584 | if (!(height % 3) && ((height * 4 / 3) == width)) { | ||
1585 | *num = 4; | ||
1586 | *denom = 3; | ||
1587 | } else if (!(height % 9) && ((height * 16 / 9) == width)) { | ||
1588 | *num = 16; | ||
1589 | *denom = 9; | ||
1590 | } else if (!(height % 10) && ((height * 16 / 10) == width)) { | ||
1591 | *num = 16; | ||
1592 | *denom = 10; | ||
1593 | } else if (!(height % 4) && ((height * 5 / 4) == width)) { | ||
1594 | *num = 5; | ||
1595 | *denom = 4; | ||
1596 | } else if (!(height % 9) && ((height * 15 / 9) == width)) { | ||
1597 | *num = 15; | ||
1598 | *denom = 9; | ||
1599 | } else { /* default to 16:9 */ | ||
1600 | *num = 16; | ||
1601 | *denom = 9; | ||
1602 | } | ||
1603 | } | ||
1604 | |||
1605 | static bool valid_cvt_gtf_timings(struct v4l2_dv_timings *timings) | ||
1606 | { | ||
1607 | struct v4l2_bt_timings *bt = &timings->bt; | ||
1608 | u32 total_h_pixel; | ||
1609 | u32 total_v_lines; | ||
1610 | u32 h_freq; | ||
1611 | |||
1612 | if (!v4l2_valid_dv_timings(timings, &vivid_dv_timings_cap, | ||
1613 | NULL, NULL)) | ||
1614 | return false; | ||
1615 | |||
1616 | total_h_pixel = V4L2_DV_BT_FRAME_WIDTH(bt); | ||
1617 | total_v_lines = V4L2_DV_BT_FRAME_HEIGHT(bt); | ||
1618 | |||
1619 | h_freq = (u32)bt->pixelclock / total_h_pixel; | ||
1620 | |||
1621 | if (bt->standards == 0 || (bt->standards & V4L2_DV_BT_STD_CVT)) { | ||
1622 | if (v4l2_detect_cvt(total_v_lines, h_freq, bt->vsync, | ||
1623 | bt->polarities, timings)) | ||
1624 | return true; | ||
1625 | } | ||
1626 | |||
1627 | if (bt->standards == 0 || (bt->standards & V4L2_DV_BT_STD_GTF)) { | ||
1628 | struct v4l2_fract aspect_ratio; | ||
1629 | |||
1630 | find_aspect_ratio(bt->width, bt->height, | ||
1631 | &aspect_ratio.numerator, | ||
1632 | &aspect_ratio.denominator); | ||
1633 | if (v4l2_detect_gtf(total_v_lines, h_freq, bt->vsync, | ||
1634 | bt->polarities, aspect_ratio, timings)) | ||
1635 | return true; | ||
1636 | } | ||
1637 | return false; | ||
1638 | } | ||
1639 | |||
1555 | int vivid_vid_cap_s_dv_timings(struct file *file, void *_fh, | 1640 | int vivid_vid_cap_s_dv_timings(struct file *file, void *_fh, |
1556 | struct v4l2_dv_timings *timings) | 1641 | struct v4l2_dv_timings *timings) |
1557 | { | 1642 | { |
@@ -1559,13 +1644,16 @@ int vivid_vid_cap_s_dv_timings(struct file *file, void *_fh, | |||
1559 | 1644 | ||
1560 | if (!vivid_is_hdmi_cap(dev)) | 1645 | if (!vivid_is_hdmi_cap(dev)) |
1561 | return -ENODATA; | 1646 | return -ENODATA; |
1562 | if (vb2_is_busy(&dev->vb_vid_cap_q)) | ||
1563 | return -EBUSY; | ||
1564 | if (!v4l2_find_dv_timings_cap(timings, &vivid_dv_timings_cap, | 1647 | if (!v4l2_find_dv_timings_cap(timings, &vivid_dv_timings_cap, |
1565 | 0, NULL, NULL)) | 1648 | 0, NULL, NULL) && |
1649 | !valid_cvt_gtf_timings(timings)) | ||
1566 | return -EINVAL; | 1650 | return -EINVAL; |
1651 | |||
1567 | if (v4l2_match_dv_timings(timings, &dev->dv_timings_cap, 0)) | 1652 | if (v4l2_match_dv_timings(timings, &dev->dv_timings_cap, 0)) |
1568 | return 0; | 1653 | return 0; |
1654 | if (vb2_is_busy(&dev->vb_vid_cap_q)) | ||
1655 | return -EBUSY; | ||
1656 | |||
1569 | dev->dv_timings_cap = *timings; | 1657 | dev->dv_timings_cap = *timings; |
1570 | vivid_update_format_cap(dev, false); | 1658 | vivid_update_format_cap(dev, false); |
1571 | return 0; | 1659 | return 0; |
@@ -1663,18 +1751,14 @@ int vidioc_enum_frameintervals(struct file *file, void *priv, | |||
1663 | return -EINVAL; | 1751 | return -EINVAL; |
1664 | 1752 | ||
1665 | if (!vivid_is_webcam(dev)) { | 1753 | if (!vivid_is_webcam(dev)) { |
1666 | static const struct v4l2_fract step = { 1, 1 }; | ||
1667 | |||
1668 | if (fival->index) | 1754 | if (fival->index) |
1669 | return -EINVAL; | 1755 | return -EINVAL; |
1670 | if (fival->width < MIN_WIDTH || fival->width > MAX_WIDTH * MAX_ZOOM) | 1756 | if (fival->width < MIN_WIDTH || fival->width > MAX_WIDTH * MAX_ZOOM) |
1671 | return -EINVAL; | 1757 | return -EINVAL; |
1672 | if (fival->height < MIN_HEIGHT || fival->height > MAX_HEIGHT * MAX_ZOOM) | 1758 | if (fival->height < MIN_HEIGHT || fival->height > MAX_HEIGHT * MAX_ZOOM) |
1673 | return -EINVAL; | 1759 | return -EINVAL; |
1674 | fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS; | 1760 | fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; |
1675 | fival->stepwise.min = tpf_min; | 1761 | fival->discrete = dev->timeperframe_vid_cap; |
1676 | fival->stepwise.max = tpf_max; | ||
1677 | fival->stepwise.step = step; | ||
1678 | return 0; | 1762 | return 0; |
1679 | } | 1763 | } |
1680 | 1764 | ||
diff --git a/drivers/media/platform/vivid/vivid-vid-common.c b/drivers/media/platform/vivid/vivid-vid-common.c index 6bef1e6d6788..aa446271ad34 100644 --- a/drivers/media/platform/vivid/vivid-vid-common.c +++ b/drivers/media/platform/vivid/vivid-vid-common.c | |||
@@ -33,8 +33,9 @@ const struct v4l2_dv_timings_cap vivid_dv_timings_cap = { | |||
33 | .type = V4L2_DV_BT_656_1120, | 33 | .type = V4L2_DV_BT_656_1120, |
34 | /* keep this initialization for compatibility with GCC < 4.4.6 */ | 34 | /* keep this initialization for compatibility with GCC < 4.4.6 */ |
35 | .reserved = { 0 }, | 35 | .reserved = { 0 }, |
36 | V4L2_INIT_BT_TIMINGS(0, MAX_WIDTH, 0, MAX_HEIGHT, 25000000, 600000000, | 36 | V4L2_INIT_BT_TIMINGS(0, MAX_WIDTH, 0, MAX_HEIGHT, 14000000, 775000000, |
37 | V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT, | 37 | V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT | |
38 | V4L2_DV_BT_STD_CVT | V4L2_DV_BT_STD_GTF, | ||
38 | V4L2_DV_BT_CAP_PROGRESSIVE | V4L2_DV_BT_CAP_INTERLACED) | 39 | V4L2_DV_BT_CAP_PROGRESSIVE | V4L2_DV_BT_CAP_INTERLACED) |
39 | }; | 40 | }; |
40 | 41 | ||
@@ -46,145 +47,435 @@ struct vivid_fmt vivid_formats[] = { | |||
46 | { | 47 | { |
47 | .name = "4:2:2, packed, YUYV", | 48 | .name = "4:2:2, packed, YUYV", |
48 | .fourcc = V4L2_PIX_FMT_YUYV, | 49 | .fourcc = V4L2_PIX_FMT_YUYV, |
49 | .depth = 16, | 50 | .vdownsampling = { 1 }, |
51 | .bit_depth = { 16 }, | ||
50 | .is_yuv = true, | 52 | .is_yuv = true, |
51 | .planes = 1, | 53 | .planes = 1, |
52 | .data_offset = { PLANE0_DATA_OFFSET, 0 }, | 54 | .buffers = 1, |
55 | .data_offset = { PLANE0_DATA_OFFSET }, | ||
53 | }, | 56 | }, |
54 | { | 57 | { |
55 | .name = "4:2:2, packed, UYVY", | 58 | .name = "4:2:2, packed, UYVY", |
56 | .fourcc = V4L2_PIX_FMT_UYVY, | 59 | .fourcc = V4L2_PIX_FMT_UYVY, |
57 | .depth = 16, | 60 | .vdownsampling = { 1 }, |
61 | .bit_depth = { 16 }, | ||
58 | .is_yuv = true, | 62 | .is_yuv = true, |
59 | .planes = 1, | 63 | .planes = 1, |
64 | .buffers = 1, | ||
60 | }, | 65 | }, |
61 | { | 66 | { |
62 | .name = "4:2:2, packed, YVYU", | 67 | .name = "4:2:2, packed, YVYU", |
63 | .fourcc = V4L2_PIX_FMT_YVYU, | 68 | .fourcc = V4L2_PIX_FMT_YVYU, |
64 | .depth = 16, | 69 | .vdownsampling = { 1 }, |
70 | .bit_depth = { 16 }, | ||
65 | .is_yuv = true, | 71 | .is_yuv = true, |
66 | .planes = 1, | 72 | .planes = 1, |
73 | .buffers = 1, | ||
67 | }, | 74 | }, |
68 | { | 75 | { |
69 | .name = "4:2:2, packed, VYUY", | 76 | .name = "4:2:2, packed, VYUY", |
70 | .fourcc = V4L2_PIX_FMT_VYUY, | 77 | .fourcc = V4L2_PIX_FMT_VYUY, |
71 | .depth = 16, | 78 | .vdownsampling = { 1 }, |
79 | .bit_depth = { 16 }, | ||
80 | .is_yuv = true, | ||
81 | .planes = 1, | ||
82 | .buffers = 1, | ||
83 | }, | ||
84 | { | ||
85 | .name = "YUV 4:2:2 triplanar", | ||
86 | .fourcc = V4L2_PIX_FMT_YUV422P, | ||
87 | .vdownsampling = { 1, 1, 1 }, | ||
88 | .bit_depth = { 8, 4, 4 }, | ||
89 | .is_yuv = true, | ||
90 | .planes = 3, | ||
91 | .buffers = 1, | ||
92 | }, | ||
93 | { | ||
94 | .name = "YUV 4:2:0 triplanar", | ||
95 | .fourcc = V4L2_PIX_FMT_YUV420, | ||
96 | .vdownsampling = { 1, 2, 2 }, | ||
97 | .bit_depth = { 8, 4, 4 }, | ||
98 | .is_yuv = true, | ||
99 | .planes = 3, | ||
100 | .buffers = 1, | ||
101 | }, | ||
102 | { | ||
103 | .name = "YVU 4:2:0 triplanar", | ||
104 | .fourcc = V4L2_PIX_FMT_YVU420, | ||
105 | .vdownsampling = { 1, 2, 2 }, | ||
106 | .bit_depth = { 8, 4, 4 }, | ||
107 | .is_yuv = true, | ||
108 | .planes = 3, | ||
109 | .buffers = 1, | ||
110 | }, | ||
111 | { | ||
112 | .name = "YUV 4:2:0 biplanar", | ||
113 | .fourcc = V4L2_PIX_FMT_NV12, | ||
114 | .vdownsampling = { 1, 2 }, | ||
115 | .bit_depth = { 8, 8 }, | ||
116 | .is_yuv = true, | ||
117 | .planes = 2, | ||
118 | .buffers = 1, | ||
119 | }, | ||
120 | { | ||
121 | .name = "YVU 4:2:0 biplanar", | ||
122 | .fourcc = V4L2_PIX_FMT_NV21, | ||
123 | .vdownsampling = { 1, 2 }, | ||
124 | .bit_depth = { 8, 8 }, | ||
125 | .is_yuv = true, | ||
126 | .planes = 2, | ||
127 | .buffers = 1, | ||
128 | }, | ||
129 | { | ||
130 | .name = "YUV 4:2:2 biplanar", | ||
131 | .fourcc = V4L2_PIX_FMT_NV16, | ||
132 | .vdownsampling = { 1, 1 }, | ||
133 | .bit_depth = { 8, 8 }, | ||
134 | .is_yuv = true, | ||
135 | .planes = 2, | ||
136 | .buffers = 1, | ||
137 | }, | ||
138 | { | ||
139 | .name = "YVU 4:2:2 biplanar", | ||
140 | .fourcc = V4L2_PIX_FMT_NV61, | ||
141 | .vdownsampling = { 1, 1 }, | ||
142 | .bit_depth = { 8, 8 }, | ||
143 | .is_yuv = true, | ||
144 | .planes = 2, | ||
145 | .buffers = 1, | ||
146 | }, | ||
147 | { | ||
148 | .name = "YUV 4:4:4 biplanar", | ||
149 | .fourcc = V4L2_PIX_FMT_NV24, | ||
150 | .vdownsampling = { 1, 1 }, | ||
151 | .bit_depth = { 8, 16 }, | ||
152 | .is_yuv = true, | ||
153 | .planes = 2, | ||
154 | .buffers = 1, | ||
155 | }, | ||
156 | { | ||
157 | .name = "YVU 4:4:4 biplanar", | ||
158 | .fourcc = V4L2_PIX_FMT_NV42, | ||
159 | .vdownsampling = { 1, 1 }, | ||
160 | .bit_depth = { 8, 16 }, | ||
161 | .is_yuv = true, | ||
162 | .planes = 2, | ||
163 | .buffers = 1, | ||
164 | }, | ||
165 | { | ||
166 | .name = "YUV555 (LE)", | ||
167 | .fourcc = V4L2_PIX_FMT_YUV555, /* uuuvvvvv ayyyyyuu */ | ||
168 | .vdownsampling = { 1 }, | ||
169 | .bit_depth = { 16 }, | ||
170 | .planes = 1, | ||
171 | .buffers = 1, | ||
172 | .alpha_mask = 0x8000, | ||
173 | }, | ||
174 | { | ||
175 | .name = "YUV565 (LE)", | ||
176 | .fourcc = V4L2_PIX_FMT_YUV565, /* uuuvvvvv yyyyyuuu */ | ||
177 | .vdownsampling = { 1 }, | ||
178 | .bit_depth = { 16 }, | ||
179 | .planes = 1, | ||
180 | .buffers = 1, | ||
181 | }, | ||
182 | { | ||
183 | .name = "YUV444", | ||
184 | .fourcc = V4L2_PIX_FMT_YUV444, /* uuuuvvvv aaaayyyy */ | ||
185 | .vdownsampling = { 1 }, | ||
186 | .bit_depth = { 16 }, | ||
187 | .planes = 1, | ||
188 | .buffers = 1, | ||
189 | .alpha_mask = 0xf000, | ||
190 | }, | ||
191 | { | ||
192 | .name = "YUV32 (LE)", | ||
193 | .fourcc = V4L2_PIX_FMT_YUV32, /* ayuv */ | ||
194 | .vdownsampling = { 1 }, | ||
195 | .bit_depth = { 32 }, | ||
196 | .planes = 1, | ||
197 | .buffers = 1, | ||
198 | .alpha_mask = 0x000000ff, | ||
199 | }, | ||
200 | { | ||
201 | .name = "Monochrome", | ||
202 | .fourcc = V4L2_PIX_FMT_GREY, | ||
203 | .vdownsampling = { 1 }, | ||
204 | .bit_depth = { 8 }, | ||
72 | .is_yuv = true, | 205 | .is_yuv = true, |
73 | .planes = 1, | 206 | .planes = 1, |
207 | .buffers = 1, | ||
208 | }, | ||
209 | { | ||
210 | .name = "RGB332", | ||
211 | .fourcc = V4L2_PIX_FMT_RGB332, /* rrrgggbb */ | ||
212 | .vdownsampling = { 1 }, | ||
213 | .bit_depth = { 8 }, | ||
214 | .planes = 1, | ||
215 | .buffers = 1, | ||
74 | }, | 216 | }, |
75 | { | 217 | { |
76 | .name = "RGB565 (LE)", | 218 | .name = "RGB565 (LE)", |
77 | .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */ | 219 | .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */ |
78 | .depth = 16, | 220 | .vdownsampling = { 1 }, |
221 | .bit_depth = { 16 }, | ||
79 | .planes = 1, | 222 | .planes = 1, |
223 | .buffers = 1, | ||
80 | .can_do_overlay = true, | 224 | .can_do_overlay = true, |
81 | }, | 225 | }, |
82 | { | 226 | { |
83 | .name = "RGB565 (BE)", | 227 | .name = "RGB565 (BE)", |
84 | .fourcc = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */ | 228 | .fourcc = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */ |
85 | .depth = 16, | 229 | .vdownsampling = { 1 }, |
230 | .bit_depth = { 16 }, | ||
86 | .planes = 1, | 231 | .planes = 1, |
232 | .buffers = 1, | ||
87 | .can_do_overlay = true, | 233 | .can_do_overlay = true, |
88 | }, | 234 | }, |
89 | { | 235 | { |
236 | .name = "RGB444", | ||
237 | .fourcc = V4L2_PIX_FMT_RGB444, /* xxxxrrrr ggggbbbb */ | ||
238 | .vdownsampling = { 1 }, | ||
239 | .bit_depth = { 16 }, | ||
240 | .planes = 1, | ||
241 | .buffers = 1, | ||
242 | }, | ||
243 | { | ||
244 | .name = "XRGB444", | ||
245 | .fourcc = V4L2_PIX_FMT_XRGB444, /* xxxxrrrr ggggbbbb */ | ||
246 | .vdownsampling = { 1 }, | ||
247 | .bit_depth = { 16 }, | ||
248 | .planes = 1, | ||
249 | .buffers = 1, | ||
250 | }, | ||
251 | { | ||
252 | .name = "ARGB444", | ||
253 | .fourcc = V4L2_PIX_FMT_ARGB444, /* aaaarrrr ggggbbbb */ | ||
254 | .vdownsampling = { 1 }, | ||
255 | .bit_depth = { 16 }, | ||
256 | .planes = 1, | ||
257 | .buffers = 1, | ||
258 | .alpha_mask = 0x00f0, | ||
259 | }, | ||
260 | { | ||
90 | .name = "RGB555 (LE)", | 261 | .name = "RGB555 (LE)", |
91 | .fourcc = V4L2_PIX_FMT_RGB555, /* gggbbbbb arrrrrgg */ | 262 | .fourcc = V4L2_PIX_FMT_RGB555, /* gggbbbbb xrrrrrgg */ |
92 | .depth = 16, | 263 | .vdownsampling = { 1 }, |
264 | .bit_depth = { 16 }, | ||
93 | .planes = 1, | 265 | .planes = 1, |
266 | .buffers = 1, | ||
94 | .can_do_overlay = true, | 267 | .can_do_overlay = true, |
95 | }, | 268 | }, |
96 | { | 269 | { |
97 | .name = "XRGB555 (LE)", | 270 | .name = "XRGB555 (LE)", |
98 | .fourcc = V4L2_PIX_FMT_XRGB555, /* gggbbbbb arrrrrgg */ | 271 | .fourcc = V4L2_PIX_FMT_XRGB555, /* gggbbbbb xrrrrrgg */ |
99 | .depth = 16, | 272 | .vdownsampling = { 1 }, |
273 | .bit_depth = { 16 }, | ||
100 | .planes = 1, | 274 | .planes = 1, |
275 | .buffers = 1, | ||
101 | .can_do_overlay = true, | 276 | .can_do_overlay = true, |
102 | }, | 277 | }, |
103 | { | 278 | { |
104 | .name = "ARGB555 (LE)", | 279 | .name = "ARGB555 (LE)", |
105 | .fourcc = V4L2_PIX_FMT_ARGB555, /* gggbbbbb arrrrrgg */ | 280 | .fourcc = V4L2_PIX_FMT_ARGB555, /* gggbbbbb arrrrrgg */ |
106 | .depth = 16, | 281 | .vdownsampling = { 1 }, |
282 | .bit_depth = { 16 }, | ||
107 | .planes = 1, | 283 | .planes = 1, |
284 | .buffers = 1, | ||
108 | .can_do_overlay = true, | 285 | .can_do_overlay = true, |
109 | .alpha_mask = 0x8000, | 286 | .alpha_mask = 0x8000, |
110 | }, | 287 | }, |
111 | { | 288 | { |
112 | .name = "RGB555 (BE)", | 289 | .name = "RGB555 (BE)", |
113 | .fourcc = V4L2_PIX_FMT_RGB555X, /* arrrrrgg gggbbbbb */ | 290 | .fourcc = V4L2_PIX_FMT_RGB555X, /* xrrrrrgg gggbbbbb */ |
114 | .depth = 16, | 291 | .vdownsampling = { 1 }, |
292 | .bit_depth = { 16 }, | ||
115 | .planes = 1, | 293 | .planes = 1, |
116 | .can_do_overlay = true, | 294 | .buffers = 1, |
295 | }, | ||
296 | { | ||
297 | .name = "XRGB555 (BE)", | ||
298 | .fourcc = V4L2_PIX_FMT_XRGB555X, /* xrrrrrgg gggbbbbb */ | ||
299 | .vdownsampling = { 1 }, | ||
300 | .bit_depth = { 16 }, | ||
301 | .planes = 1, | ||
302 | .buffers = 1, | ||
303 | }, | ||
304 | { | ||
305 | .name = "ARGB555 (BE)", | ||
306 | .fourcc = V4L2_PIX_FMT_ARGB555X, /* arrrrrgg gggbbbbb */ | ||
307 | .vdownsampling = { 1 }, | ||
308 | .bit_depth = { 16 }, | ||
309 | .planes = 1, | ||
310 | .buffers = 1, | ||
311 | .alpha_mask = 0x0080, | ||
117 | }, | 312 | }, |
118 | { | 313 | { |
119 | .name = "RGB24 (LE)", | 314 | .name = "RGB24 (LE)", |
120 | .fourcc = V4L2_PIX_FMT_RGB24, /* rgb */ | 315 | .fourcc = V4L2_PIX_FMT_RGB24, /* rgb */ |
121 | .depth = 24, | 316 | .vdownsampling = { 1 }, |
317 | .bit_depth = { 24 }, | ||
122 | .planes = 1, | 318 | .planes = 1, |
319 | .buffers = 1, | ||
123 | }, | 320 | }, |
124 | { | 321 | { |
125 | .name = "RGB24 (BE)", | 322 | .name = "RGB24 (BE)", |
126 | .fourcc = V4L2_PIX_FMT_BGR24, /* bgr */ | 323 | .fourcc = V4L2_PIX_FMT_BGR24, /* bgr */ |
127 | .depth = 24, | 324 | .vdownsampling = { 1 }, |
325 | .bit_depth = { 24 }, | ||
128 | .planes = 1, | 326 | .planes = 1, |
327 | .buffers = 1, | ||
328 | }, | ||
329 | { | ||
330 | .name = "BGR666", | ||
331 | .fourcc = V4L2_PIX_FMT_BGR666, /* bbbbbbgg ggggrrrr rrxxxxxx */ | ||
332 | .vdownsampling = { 1 }, | ||
333 | .bit_depth = { 32 }, | ||
334 | .planes = 1, | ||
335 | .buffers = 1, | ||
129 | }, | 336 | }, |
130 | { | 337 | { |
131 | .name = "RGB32 (LE)", | 338 | .name = "RGB32 (LE)", |
132 | .fourcc = V4L2_PIX_FMT_RGB32, /* argb */ | 339 | .fourcc = V4L2_PIX_FMT_RGB32, /* xrgb */ |
133 | .depth = 32, | 340 | .vdownsampling = { 1 }, |
341 | .bit_depth = { 32 }, | ||
134 | .planes = 1, | 342 | .planes = 1, |
343 | .buffers = 1, | ||
135 | }, | 344 | }, |
136 | { | 345 | { |
137 | .name = "RGB32 (BE)", | 346 | .name = "RGB32 (BE)", |
138 | .fourcc = V4L2_PIX_FMT_BGR32, /* bgra */ | 347 | .fourcc = V4L2_PIX_FMT_BGR32, /* bgrx */ |
139 | .depth = 32, | 348 | .vdownsampling = { 1 }, |
349 | .bit_depth = { 32 }, | ||
140 | .planes = 1, | 350 | .planes = 1, |
351 | .buffers = 1, | ||
141 | }, | 352 | }, |
142 | { | 353 | { |
143 | .name = "XRGB32 (LE)", | 354 | .name = "XRGB32 (LE)", |
144 | .fourcc = V4L2_PIX_FMT_XRGB32, /* argb */ | 355 | .fourcc = V4L2_PIX_FMT_XRGB32, /* xrgb */ |
145 | .depth = 32, | 356 | .vdownsampling = { 1 }, |
357 | .bit_depth = { 32 }, | ||
146 | .planes = 1, | 358 | .planes = 1, |
359 | .buffers = 1, | ||
147 | }, | 360 | }, |
148 | { | 361 | { |
149 | .name = "XRGB32 (BE)", | 362 | .name = "XRGB32 (BE)", |
150 | .fourcc = V4L2_PIX_FMT_XBGR32, /* bgra */ | 363 | .fourcc = V4L2_PIX_FMT_XBGR32, /* bgrx */ |
151 | .depth = 32, | 364 | .vdownsampling = { 1 }, |
365 | .bit_depth = { 32 }, | ||
152 | .planes = 1, | 366 | .planes = 1, |
367 | .buffers = 1, | ||
153 | }, | 368 | }, |
154 | { | 369 | { |
155 | .name = "ARGB32 (LE)", | 370 | .name = "ARGB32 (LE)", |
156 | .fourcc = V4L2_PIX_FMT_ARGB32, /* argb */ | 371 | .fourcc = V4L2_PIX_FMT_ARGB32, /* argb */ |
157 | .depth = 32, | 372 | .vdownsampling = { 1 }, |
373 | .bit_depth = { 32 }, | ||
158 | .planes = 1, | 374 | .planes = 1, |
375 | .buffers = 1, | ||
159 | .alpha_mask = 0x000000ff, | 376 | .alpha_mask = 0x000000ff, |
160 | }, | 377 | }, |
161 | { | 378 | { |
162 | .name = "ARGB32 (BE)", | 379 | .name = "ARGB32 (BE)", |
163 | .fourcc = V4L2_PIX_FMT_ABGR32, /* bgra */ | 380 | .fourcc = V4L2_PIX_FMT_ABGR32, /* bgra */ |
164 | .depth = 32, | 381 | .vdownsampling = { 1 }, |
382 | .bit_depth = { 32 }, | ||
165 | .planes = 1, | 383 | .planes = 1, |
384 | .buffers = 1, | ||
166 | .alpha_mask = 0xff000000, | 385 | .alpha_mask = 0xff000000, |
167 | }, | 386 | }, |
168 | { | 387 | { |
169 | .name = "4:2:2, planar, YUV", | 388 | .name = "Bayer BG/GR", |
389 | .fourcc = V4L2_PIX_FMT_SBGGR8, /* Bayer BG/GR */ | ||
390 | .vdownsampling = { 1 }, | ||
391 | .bit_depth = { 8 }, | ||
392 | .planes = 1, | ||
393 | .buffers = 1, | ||
394 | }, | ||
395 | { | ||
396 | .name = "Bayer GB/RG", | ||
397 | .fourcc = V4L2_PIX_FMT_SGBRG8, /* Bayer GB/RG */ | ||
398 | .vdownsampling = { 1 }, | ||
399 | .bit_depth = { 8 }, | ||
400 | .planes = 1, | ||
401 | .buffers = 1, | ||
402 | }, | ||
403 | { | ||
404 | .name = "Bayer GR/BG", | ||
405 | .fourcc = V4L2_PIX_FMT_SGRBG8, /* Bayer GR/BG */ | ||
406 | .vdownsampling = { 1 }, | ||
407 | .bit_depth = { 8 }, | ||
408 | .planes = 1, | ||
409 | .buffers = 1, | ||
410 | }, | ||
411 | { | ||
412 | .name = "Bayer RG/GB", | ||
413 | .fourcc = V4L2_PIX_FMT_SRGGB8, /* Bayer RG/GB */ | ||
414 | .vdownsampling = { 1 }, | ||
415 | .bit_depth = { 8 }, | ||
416 | .planes = 1, | ||
417 | .buffers = 1, | ||
418 | }, | ||
419 | { | ||
420 | .name = "4:2:2, biplanar, YUV", | ||
170 | .fourcc = V4L2_PIX_FMT_NV16M, | 421 | .fourcc = V4L2_PIX_FMT_NV16M, |
171 | .depth = 8, | 422 | .vdownsampling = { 1, 1 }, |
423 | .bit_depth = { 8, 8 }, | ||
172 | .is_yuv = true, | 424 | .is_yuv = true, |
173 | .planes = 2, | 425 | .planes = 2, |
426 | .buffers = 2, | ||
174 | .data_offset = { PLANE0_DATA_OFFSET, 0 }, | 427 | .data_offset = { PLANE0_DATA_OFFSET, 0 }, |
175 | }, | 428 | }, |
176 | { | 429 | { |
177 | .name = "4:2:2, planar, YVU", | 430 | .name = "4:2:2, biplanar, YVU", |
178 | .fourcc = V4L2_PIX_FMT_NV61M, | 431 | .fourcc = V4L2_PIX_FMT_NV61M, |
179 | .depth = 8, | 432 | .vdownsampling = { 1, 1 }, |
433 | .bit_depth = { 8, 8 }, | ||
180 | .is_yuv = true, | 434 | .is_yuv = true, |
181 | .planes = 2, | 435 | .planes = 2, |
436 | .buffers = 2, | ||
182 | .data_offset = { 0, PLANE0_DATA_OFFSET }, | 437 | .data_offset = { 0, PLANE0_DATA_OFFSET }, |
183 | }, | 438 | }, |
439 | { | ||
440 | .name = "4:2:0, triplanar, YUV", | ||
441 | .fourcc = V4L2_PIX_FMT_YUV420M, | ||
442 | .vdownsampling = { 1, 2, 2 }, | ||
443 | .bit_depth = { 8, 4, 4 }, | ||
444 | .is_yuv = true, | ||
445 | .planes = 3, | ||
446 | .buffers = 3, | ||
447 | }, | ||
448 | { | ||
449 | .name = "4:2:0, triplanar, YVU", | ||
450 | .fourcc = V4L2_PIX_FMT_YVU420M, | ||
451 | .vdownsampling = { 1, 2, 2 }, | ||
452 | .bit_depth = { 8, 4, 4 }, | ||
453 | .is_yuv = true, | ||
454 | .planes = 3, | ||
455 | .buffers = 3, | ||
456 | }, | ||
457 | { | ||
458 | .name = "4:2:0, biplanar, YUV", | ||
459 | .fourcc = V4L2_PIX_FMT_NV12M, | ||
460 | .vdownsampling = { 1, 2 }, | ||
461 | .bit_depth = { 8, 8 }, | ||
462 | .is_yuv = true, | ||
463 | .planes = 2, | ||
464 | .buffers = 2, | ||
465 | }, | ||
466 | { | ||
467 | .name = "4:2:0, biplanar, YVU", | ||
468 | .fourcc = V4L2_PIX_FMT_NV21M, | ||
469 | .vdownsampling = { 1, 2 }, | ||
470 | .bit_depth = { 8, 8 }, | ||
471 | .is_yuv = true, | ||
472 | .planes = 2, | ||
473 | .buffers = 2, | ||
474 | }, | ||
184 | }; | 475 | }; |
185 | 476 | ||
186 | /* There are 2 multiplanar formats in the list */ | 477 | /* There are 6 multiplanar formats in the list */ |
187 | #define VIVID_MPLANAR_FORMATS 2 | 478 | #define VIVID_MPLANAR_FORMATS 6 |
188 | 479 | ||
189 | const struct vivid_fmt *vivid_get_format(struct vivid_dev *dev, u32 pixelformat) | 480 | const struct vivid_fmt *vivid_get_format(struct vivid_dev *dev, u32 pixelformat) |
190 | { | 481 | { |
@@ -194,7 +485,7 @@ const struct vivid_fmt *vivid_get_format(struct vivid_dev *dev, u32 pixelformat) | |||
194 | for (k = 0; k < ARRAY_SIZE(vivid_formats); k++) { | 485 | for (k = 0; k < ARRAY_SIZE(vivid_formats); k++) { |
195 | fmt = &vivid_formats[k]; | 486 | fmt = &vivid_formats[k]; |
196 | if (fmt->fourcc == pixelformat) | 487 | if (fmt->fourcc == pixelformat) |
197 | if (fmt->planes == 1 || dev->multiplanar) | 488 | if (fmt->buffers == 1 || dev->multiplanar) |
198 | return fmt; | 489 | return fmt; |
199 | } | 490 | } |
200 | 491 | ||
@@ -210,6 +501,13 @@ bool vivid_vid_can_loop(struct vivid_dev *dev) | |||
210 | return false; | 501 | return false; |
211 | if (dev->field_cap != dev->field_out) | 502 | if (dev->field_cap != dev->field_out) |
212 | return false; | 503 | return false; |
504 | /* | ||
505 | * While this can be supported, it is just too much work | ||
506 | * to actually implement. | ||
507 | */ | ||
508 | if (dev->field_cap == V4L2_FIELD_SEQ_TB || | ||
509 | dev->field_cap == V4L2_FIELD_SEQ_BT) | ||
510 | return false; | ||
213 | if (vivid_is_svid_cap(dev) && vivid_is_svid_out(dev)) { | 511 | if (vivid_is_svid_cap(dev) && vivid_is_svid_out(dev)) { |
214 | if (!(dev->std_cap & V4L2_STD_525_60) != | 512 | if (!(dev->std_cap & V4L2_STD_525_60) != |
215 | !(dev->std_out & V4L2_STD_525_60)) | 513 | !(dev->std_out & V4L2_STD_525_60)) |
@@ -397,6 +695,9 @@ int vivid_vid_adjust_sel(unsigned flags, struct v4l2_rect *r) | |||
397 | unsigned w = r->width; | 695 | unsigned w = r->width; |
398 | unsigned h = r->height; | 696 | unsigned h = r->height; |
399 | 697 | ||
698 | /* sanitize w and h in case someone passes ~0 as the value */ | ||
699 | w &= 0xffff; | ||
700 | h &= 0xffff; | ||
400 | if (!(flags & V4L2_SEL_FLAG_LE)) { | 701 | if (!(flags & V4L2_SEL_FLAG_LE)) { |
401 | w++; | 702 | w++; |
402 | h++; | 703 | h++; |
@@ -421,8 +722,9 @@ int vivid_vid_adjust_sel(unsigned flags, struct v4l2_rect *r) | |||
421 | r->top = 0; | 722 | r->top = 0; |
422 | if (r->left < 0) | 723 | if (r->left < 0) |
423 | r->left = 0; | 724 | r->left = 0; |
424 | r->left &= ~1; | 725 | /* sanitize left and top in case someone passes ~0 as the value */ |
425 | r->top &= ~1; | 726 | r->left &= 0xfffe; |
727 | r->top &= 0xfffe; | ||
426 | if (r->left + w > MAX_WIDTH) | 728 | if (r->left + w > MAX_WIDTH) |
427 | r->left = MAX_WIDTH - w; | 729 | r->left = MAX_WIDTH - w; |
428 | if (r->top + h > MAX_HEIGHT) | 730 | if (r->top + h > MAX_HEIGHT) |
diff --git a/drivers/media/platform/vivid/vivid-vid-out.c b/drivers/media/platform/vivid/vivid-vid-out.c index 39ff79f6aa67..0af43dc7715c 100644 --- a/drivers/media/platform/vivid/vivid-vid-out.c +++ b/drivers/media/platform/vivid/vivid-vid-out.c | |||
@@ -36,9 +36,14 @@ static int vid_out_queue_setup(struct vb2_queue *vq, const struct v4l2_format *f | |||
36 | unsigned sizes[], void *alloc_ctxs[]) | 36 | unsigned sizes[], void *alloc_ctxs[]) |
37 | { | 37 | { |
38 | struct vivid_dev *dev = vb2_get_drv_priv(vq); | 38 | struct vivid_dev *dev = vb2_get_drv_priv(vq); |
39 | unsigned planes = dev->fmt_out->planes; | 39 | const struct vivid_fmt *vfmt = dev->fmt_out; |
40 | unsigned planes = vfmt->buffers; | ||
40 | unsigned h = dev->fmt_out_rect.height; | 41 | unsigned h = dev->fmt_out_rect.height; |
41 | unsigned size = dev->bytesperline_out[0] * h; | 42 | unsigned size = dev->bytesperline_out[0] * h; |
43 | unsigned p; | ||
44 | |||
45 | for (p = vfmt->buffers; p < vfmt->planes; p++) | ||
46 | size += dev->bytesperline_out[p] * h / vfmt->vdownsampling[p]; | ||
42 | 47 | ||
43 | if (dev->field_out == V4L2_FIELD_ALTERNATE) { | 48 | if (dev->field_out == V4L2_FIELD_ALTERNATE) { |
44 | /* | 49 | /* |
@@ -74,21 +79,16 @@ static int vid_out_queue_setup(struct vb2_queue *vq, const struct v4l2_format *f | |||
74 | if (mp->num_planes != planes) | 79 | if (mp->num_planes != planes) |
75 | return -EINVAL; | 80 | return -EINVAL; |
76 | sizes[0] = mp->plane_fmt[0].sizeimage; | 81 | sizes[0] = mp->plane_fmt[0].sizeimage; |
77 | if (planes == 2) { | 82 | if (sizes[0] < size) |
78 | sizes[1] = mp->plane_fmt[1].sizeimage; | ||
79 | if (sizes[0] < dev->bytesperline_out[0] * h || | ||
80 | sizes[1] < dev->bytesperline_out[1] * h) | ||
81 | return -EINVAL; | ||
82 | } else if (sizes[0] < size) { | ||
83 | return -EINVAL; | 83 | return -EINVAL; |
84 | for (p = 1; p < planes; p++) { | ||
85 | sizes[p] = mp->plane_fmt[p].sizeimage; | ||
86 | if (sizes[p] < dev->bytesperline_out[p] * h) | ||
87 | return -EINVAL; | ||
84 | } | 88 | } |
85 | } else { | 89 | } else { |
86 | if (planes == 2) { | 90 | for (p = 0; p < planes; p++) |
87 | sizes[0] = dev->bytesperline_out[0] * h; | 91 | sizes[p] = p ? dev->bytesperline_out[p] * h : size; |
88 | sizes[1] = dev->bytesperline_out[1] * h; | ||
89 | } else { | ||
90 | sizes[0] = size; | ||
91 | } | ||
92 | } | 92 | } |
93 | 93 | ||
94 | if (vq->num_buffers + *nbuffers < 2) | 94 | if (vq->num_buffers + *nbuffers < 2) |
@@ -101,12 +101,9 @@ static int vid_out_queue_setup(struct vb2_queue *vq, const struct v4l2_format *f | |||
101 | * alloc_ctxs array. | 101 | * alloc_ctxs array. |
102 | */ | 102 | */ |
103 | 103 | ||
104 | if (planes == 2) | 104 | dprintk(dev, 1, "%s: count=%d\n", __func__, *nbuffers); |
105 | dprintk(dev, 1, "%s, count=%d, sizes=%u, %u\n", __func__, | 105 | for (p = 0; p < planes; p++) |
106 | *nbuffers, sizes[0], sizes[1]); | 106 | dprintk(dev, 1, "%s: size[%u]=%u\n", __func__, p, sizes[p]); |
107 | else | ||
108 | dprintk(dev, 1, "%s, count=%d, size=%u\n", __func__, | ||
109 | *nbuffers, sizes[0]); | ||
110 | return 0; | 107 | return 0; |
111 | } | 108 | } |
112 | 109 | ||
@@ -114,7 +111,7 @@ static int vid_out_buf_prepare(struct vb2_buffer *vb) | |||
114 | { | 111 | { |
115 | struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue); | 112 | struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue); |
116 | unsigned long size; | 113 | unsigned long size; |
117 | unsigned planes = dev->fmt_out->planes; | 114 | unsigned planes; |
118 | unsigned p; | 115 | unsigned p; |
119 | 116 | ||
120 | dprintk(dev, 1, "%s\n", __func__); | 117 | dprintk(dev, 1, "%s\n", __func__); |
@@ -122,6 +119,8 @@ static int vid_out_buf_prepare(struct vb2_buffer *vb) | |||
122 | if (WARN_ON(NULL == dev->fmt_out)) | 119 | if (WARN_ON(NULL == dev->fmt_out)) |
123 | return -EINVAL; | 120 | return -EINVAL; |
124 | 121 | ||
122 | planes = dev->fmt_out->planes; | ||
123 | |||
125 | if (dev->buf_prepare_error) { | 124 | if (dev->buf_prepare_error) { |
126 | /* | 125 | /* |
127 | * Error injection: test what happens if buf_prepare() returns | 126 | * Error injection: test what happens if buf_prepare() returns |
@@ -220,7 +219,7 @@ const struct vb2_ops vivid_vid_out_qops = { | |||
220 | void vivid_update_format_out(struct vivid_dev *dev) | 219 | void vivid_update_format_out(struct vivid_dev *dev) |
221 | { | 220 | { |
222 | struct v4l2_bt_timings *bt = &dev->dv_timings_out.bt; | 221 | struct v4l2_bt_timings *bt = &dev->dv_timings_out.bt; |
223 | unsigned size; | 222 | unsigned size, p; |
224 | 223 | ||
225 | switch (dev->output_type[dev->output]) { | 224 | switch (dev->output_type[dev->output]) { |
226 | case SVID: | 225 | case SVID: |
@@ -249,7 +248,7 @@ void vivid_update_format_out(struct vivid_dev *dev) | |||
249 | dev->field_out = V4L2_FIELD_ALTERNATE; | 248 | dev->field_out = V4L2_FIELD_ALTERNATE; |
250 | else | 249 | else |
251 | dev->field_out = V4L2_FIELD_NONE; | 250 | dev->field_out = V4L2_FIELD_NONE; |
252 | if (!dev->dvi_d_out && (bt->standards & V4L2_DV_BT_STD_CEA861)) { | 251 | if (!dev->dvi_d_out && (bt->flags & V4L2_DV_FL_IS_CE_VIDEO)) { |
253 | if (bt->width == 720 && bt->height <= 576) | 252 | if (bt->width == 720 && bt->height <= 576) |
254 | dev->colorspace_out = V4L2_COLORSPACE_SMPTE170M; | 253 | dev->colorspace_out = V4L2_COLORSPACE_SMPTE170M; |
255 | else | 254 | else |
@@ -267,9 +266,9 @@ void vivid_update_format_out(struct vivid_dev *dev) | |||
267 | if (V4L2_FIELD_HAS_T_OR_B(dev->field_out)) | 266 | if (V4L2_FIELD_HAS_T_OR_B(dev->field_out)) |
268 | dev->crop_out.height /= 2; | 267 | dev->crop_out.height /= 2; |
269 | dev->fmt_out_rect = dev->crop_out; | 268 | dev->fmt_out_rect = dev->crop_out; |
270 | dev->bytesperline_out[0] = (dev->sink_rect.width * dev->fmt_out->depth) / 8; | 269 | for (p = 0; p < dev->fmt_out->planes; p++) |
271 | if (dev->fmt_out->planes == 2) | 270 | dev->bytesperline_out[p] = |
272 | dev->bytesperline_out[1] = (dev->sink_rect.width * dev->fmt_out->depth) / 8; | 271 | (dev->sink_rect.width * dev->fmt_out->bit_depth[p]) / 8; |
273 | } | 272 | } |
274 | 273 | ||
275 | /* Map the field to something that is valid for the current output */ | 274 | /* Map the field to something that is valid for the current output */ |
@@ -313,21 +312,28 @@ int vivid_g_fmt_vid_out(struct file *file, void *priv, | |||
313 | { | 312 | { |
314 | struct vivid_dev *dev = video_drvdata(file); | 313 | struct vivid_dev *dev = video_drvdata(file); |
315 | struct v4l2_pix_format_mplane *mp = &f->fmt.pix_mp; | 314 | struct v4l2_pix_format_mplane *mp = &f->fmt.pix_mp; |
315 | const struct vivid_fmt *fmt = dev->fmt_out; | ||
316 | unsigned p; | 316 | unsigned p; |
317 | 317 | ||
318 | mp->width = dev->fmt_out_rect.width; | 318 | mp->width = dev->fmt_out_rect.width; |
319 | mp->height = dev->fmt_out_rect.height; | 319 | mp->height = dev->fmt_out_rect.height; |
320 | mp->field = dev->field_out; | 320 | mp->field = dev->field_out; |
321 | mp->pixelformat = dev->fmt_out->fourcc; | 321 | mp->pixelformat = fmt->fourcc; |
322 | mp->colorspace = dev->colorspace_out; | 322 | mp->colorspace = dev->colorspace_out; |
323 | mp->ycbcr_enc = dev->ycbcr_enc_out; | 323 | mp->ycbcr_enc = dev->ycbcr_enc_out; |
324 | mp->quantization = dev->quantization_out; | 324 | mp->quantization = dev->quantization_out; |
325 | mp->num_planes = dev->fmt_out->planes; | 325 | mp->num_planes = fmt->buffers; |
326 | for (p = 0; p < mp->num_planes; p++) { | 326 | for (p = 0; p < mp->num_planes; p++) { |
327 | mp->plane_fmt[p].bytesperline = dev->bytesperline_out[p]; | 327 | mp->plane_fmt[p].bytesperline = dev->bytesperline_out[p]; |
328 | mp->plane_fmt[p].sizeimage = | 328 | mp->plane_fmt[p].sizeimage = |
329 | mp->plane_fmt[p].bytesperline * mp->height; | 329 | mp->plane_fmt[p].bytesperline * mp->height; |
330 | } | 330 | } |
331 | for (p = fmt->buffers; p < fmt->planes; p++) { | ||
332 | unsigned stride = dev->bytesperline_out[p]; | ||
333 | |||
334 | mp->plane_fmt[0].sizeimage += | ||
335 | (stride * mp->height) / fmt->vdownsampling[p]; | ||
336 | } | ||
331 | return 0; | 337 | return 0; |
332 | } | 338 | } |
333 | 339 | ||
@@ -386,10 +392,10 @@ int vivid_try_fmt_vid_out(struct file *file, void *priv, | |||
386 | /* This driver supports custom bytesperline values */ | 392 | /* This driver supports custom bytesperline values */ |
387 | 393 | ||
388 | /* Calculate the minimum supported bytesperline value */ | 394 | /* Calculate the minimum supported bytesperline value */ |
389 | bytesperline = (mp->width * fmt->depth) >> 3; | 395 | bytesperline = (mp->width * fmt->bit_depth[0]) >> 3; |
390 | /* Calculate the maximum supported bytesperline value */ | 396 | /* Calculate the maximum supported bytesperline value */ |
391 | max_bpl = (MAX_ZOOM * MAX_WIDTH * fmt->depth) >> 3; | 397 | max_bpl = (MAX_ZOOM * MAX_WIDTH * fmt->bit_depth[0]) >> 3; |
392 | mp->num_planes = fmt->planes; | 398 | mp->num_planes = fmt->buffers; |
393 | for (p = 0; p < mp->num_planes; p++) { | 399 | for (p = 0; p < mp->num_planes; p++) { |
394 | if (pfmt[p].bytesperline > max_bpl) | 400 | if (pfmt[p].bytesperline > max_bpl) |
395 | pfmt[p].bytesperline = max_bpl; | 401 | pfmt[p].bytesperline = max_bpl; |
@@ -398,11 +404,14 @@ int vivid_try_fmt_vid_out(struct file *file, void *priv, | |||
398 | pfmt[p].sizeimage = pfmt[p].bytesperline * mp->height; | 404 | pfmt[p].sizeimage = pfmt[p].bytesperline * mp->height; |
399 | memset(pfmt[p].reserved, 0, sizeof(pfmt[p].reserved)); | 405 | memset(pfmt[p].reserved, 0, sizeof(pfmt[p].reserved)); |
400 | } | 406 | } |
407 | for (p = fmt->buffers; p < fmt->planes; p++) | ||
408 | pfmt[0].sizeimage += (pfmt[0].bytesperline * fmt->bit_depth[p]) / | ||
409 | (fmt->bit_depth[0] * fmt->vdownsampling[p]); | ||
401 | mp->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; | 410 | mp->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; |
402 | mp->quantization = V4L2_QUANTIZATION_DEFAULT; | 411 | mp->quantization = V4L2_QUANTIZATION_DEFAULT; |
403 | if (vivid_is_svid_out(dev)) { | 412 | if (vivid_is_svid_out(dev)) { |
404 | mp->colorspace = V4L2_COLORSPACE_SMPTE170M; | 413 | mp->colorspace = V4L2_COLORSPACE_SMPTE170M; |
405 | } else if (dev->dvi_d_out || !(bt->standards & V4L2_DV_BT_STD_CEA861)) { | 414 | } else if (dev->dvi_d_out || !(bt->flags & V4L2_DV_FL_IS_CE_VIDEO)) { |
406 | mp->colorspace = V4L2_COLORSPACE_SRGB; | 415 | mp->colorspace = V4L2_COLORSPACE_SRGB; |
407 | if (dev->dvi_d_out) | 416 | if (dev->dvi_d_out) |
408 | mp->quantization = V4L2_QUANTIZATION_LIM_RANGE; | 417 | mp->quantization = V4L2_QUANTIZATION_LIM_RANGE; |
@@ -429,6 +438,7 @@ int vivid_s_fmt_vid_out(struct file *file, void *priv, | |||
429 | struct vb2_queue *q = &dev->vb_vid_out_q; | 438 | struct vb2_queue *q = &dev->vb_vid_out_q; |
430 | int ret = vivid_try_fmt_vid_out(file, priv, f); | 439 | int ret = vivid_try_fmt_vid_out(file, priv, f); |
431 | unsigned factor = 1; | 440 | unsigned factor = 1; |
441 | unsigned p; | ||
432 | 442 | ||
433 | if (ret < 0) | 443 | if (ret < 0) |
434 | return ret; | 444 | return ret; |
@@ -524,9 +534,12 @@ int vivid_s_fmt_vid_out(struct file *file, void *priv, | |||
524 | 534 | ||
525 | dev->fmt_out_rect.width = mp->width; | 535 | dev->fmt_out_rect.width = mp->width; |
526 | dev->fmt_out_rect.height = mp->height; | 536 | dev->fmt_out_rect.height = mp->height; |
527 | dev->bytesperline_out[0] = mp->plane_fmt[0].bytesperline; | 537 | for (p = 0; p < mp->num_planes; p++) |
528 | if (mp->num_planes > 1) | 538 | dev->bytesperline_out[p] = mp->plane_fmt[p].bytesperline; |
529 | dev->bytesperline_out[1] = mp->plane_fmt[1].bytesperline; | 539 | for (p = dev->fmt_out->buffers; p < dev->fmt_out->planes; p++) |
540 | dev->bytesperline_out[p] = | ||
541 | (dev->bytesperline_out[0] * dev->fmt_out->bit_depth[p]) / | ||
542 | dev->fmt_out->bit_depth[0]; | ||
530 | dev->field_out = mp->field; | 543 | dev->field_out = mp->field; |
531 | if (vivid_is_svid_out(dev)) | 544 | if (vivid_is_svid_out(dev)) |
532 | dev->tv_field_out = mp->field; | 545 | dev->tv_field_out = mp->field; |
@@ -1114,13 +1127,13 @@ int vivid_vid_out_s_dv_timings(struct file *file, void *_fh, | |||
1114 | 1127 | ||
1115 | if (!vivid_is_hdmi_out(dev)) | 1128 | if (!vivid_is_hdmi_out(dev)) |
1116 | return -ENODATA; | 1129 | return -ENODATA; |
1117 | if (vb2_is_busy(&dev->vb_vid_out_q)) | ||
1118 | return -EBUSY; | ||
1119 | if (!v4l2_find_dv_timings_cap(timings, &vivid_dv_timings_cap, | 1130 | if (!v4l2_find_dv_timings_cap(timings, &vivid_dv_timings_cap, |
1120 | 0, NULL, NULL)) | 1131 | 0, NULL, NULL)) |
1121 | return -EINVAL; | 1132 | return -EINVAL; |
1122 | if (v4l2_match_dv_timings(timings, &dev->dv_timings_out, 0)) | 1133 | if (v4l2_match_dv_timings(timings, &dev->dv_timings_out, 0)) |
1123 | return 0; | 1134 | return 0; |
1135 | if (vb2_is_busy(&dev->vb_vid_out_q)) | ||
1136 | return -EBUSY; | ||
1124 | dev->dv_timings_out = *timings; | 1137 | dev->dv_timings_out = *timings; |
1125 | vivid_update_format_out(dev); | 1138 | vivid_update_format_out(dev); |
1126 | return 0; | 1139 | return 0; |
diff --git a/drivers/media/platform/vsp1/vsp1_bru.c b/drivers/media/platform/vsp1/vsp1_bru.c index 401e2b77a0b6..7dd763311c0f 100644 --- a/drivers/media/platform/vsp1/vsp1_bru.c +++ b/drivers/media/platform/vsp1/vsp1_bru.c | |||
@@ -183,13 +183,14 @@ static int bru_s_stream(struct v4l2_subdev *subdev, int enable) | |||
183 | */ | 183 | */ |
184 | 184 | ||
185 | static int bru_enum_mbus_code(struct v4l2_subdev *subdev, | 185 | static int bru_enum_mbus_code(struct v4l2_subdev *subdev, |
186 | struct v4l2_subdev_fh *fh, | 186 | struct v4l2_subdev_pad_config *cfg, |
187 | struct v4l2_subdev_mbus_code_enum *code) | 187 | struct v4l2_subdev_mbus_code_enum *code) |
188 | { | 188 | { |
189 | static const unsigned int codes[] = { | 189 | static const unsigned int codes[] = { |
190 | MEDIA_BUS_FMT_ARGB8888_1X32, | 190 | MEDIA_BUS_FMT_ARGB8888_1X32, |
191 | MEDIA_BUS_FMT_AYUV8_1X32, | 191 | MEDIA_BUS_FMT_AYUV8_1X32, |
192 | }; | 192 | }; |
193 | struct vsp1_bru *bru = to_bru(subdev); | ||
193 | struct v4l2_mbus_framefmt *format; | 194 | struct v4l2_mbus_framefmt *format; |
194 | 195 | ||
195 | if (code->pad == BRU_PAD_SINK(0)) { | 196 | if (code->pad == BRU_PAD_SINK(0)) { |
@@ -201,7 +202,8 @@ static int bru_enum_mbus_code(struct v4l2_subdev *subdev, | |||
201 | if (code->index) | 202 | if (code->index) |
202 | return -EINVAL; | 203 | return -EINVAL; |
203 | 204 | ||
204 | format = v4l2_subdev_get_try_format(fh, BRU_PAD_SINK(0)); | 205 | format = vsp1_entity_get_pad_format(&bru->entity, cfg, |
206 | BRU_PAD_SINK(0), code->which); | ||
205 | code->code = format->code; | 207 | code->code = format->code; |
206 | } | 208 | } |
207 | 209 | ||
@@ -209,7 +211,7 @@ static int bru_enum_mbus_code(struct v4l2_subdev *subdev, | |||
209 | } | 211 | } |
210 | 212 | ||
211 | static int bru_enum_frame_size(struct v4l2_subdev *subdev, | 213 | static int bru_enum_frame_size(struct v4l2_subdev *subdev, |
212 | struct v4l2_subdev_fh *fh, | 214 | struct v4l2_subdev_pad_config *cfg, |
213 | struct v4l2_subdev_frame_size_enum *fse) | 215 | struct v4l2_subdev_frame_size_enum *fse) |
214 | { | 216 | { |
215 | if (fse->index) | 217 | if (fse->index) |
@@ -228,12 +230,12 @@ static int bru_enum_frame_size(struct v4l2_subdev *subdev, | |||
228 | } | 230 | } |
229 | 231 | ||
230 | static struct v4l2_rect *bru_get_compose(struct vsp1_bru *bru, | 232 | static struct v4l2_rect *bru_get_compose(struct vsp1_bru *bru, |
231 | struct v4l2_subdev_fh *fh, | 233 | struct v4l2_subdev_pad_config *cfg, |
232 | unsigned int pad, u32 which) | 234 | unsigned int pad, u32 which) |
233 | { | 235 | { |
234 | switch (which) { | 236 | switch (which) { |
235 | case V4L2_SUBDEV_FORMAT_TRY: | 237 | case V4L2_SUBDEV_FORMAT_TRY: |
236 | return v4l2_subdev_get_try_crop(fh, pad); | 238 | return v4l2_subdev_get_try_crop(&bru->entity.subdev, cfg, pad); |
237 | case V4L2_SUBDEV_FORMAT_ACTIVE: | 239 | case V4L2_SUBDEV_FORMAT_ACTIVE: |
238 | return &bru->inputs[pad].compose; | 240 | return &bru->inputs[pad].compose; |
239 | default: | 241 | default: |
@@ -241,18 +243,18 @@ static struct v4l2_rect *bru_get_compose(struct vsp1_bru *bru, | |||
241 | } | 243 | } |
242 | } | 244 | } |
243 | 245 | ||
244 | static int bru_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, | 246 | static int bru_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg, |
245 | struct v4l2_subdev_format *fmt) | 247 | struct v4l2_subdev_format *fmt) |
246 | { | 248 | { |
247 | struct vsp1_bru *bru = to_bru(subdev); | 249 | struct vsp1_bru *bru = to_bru(subdev); |
248 | 250 | ||
249 | fmt->format = *vsp1_entity_get_pad_format(&bru->entity, fh, fmt->pad, | 251 | fmt->format = *vsp1_entity_get_pad_format(&bru->entity, cfg, fmt->pad, |
250 | fmt->which); | 252 | fmt->which); |
251 | 253 | ||
252 | return 0; | 254 | return 0; |
253 | } | 255 | } |
254 | 256 | ||
255 | static void bru_try_format(struct vsp1_bru *bru, struct v4l2_subdev_fh *fh, | 257 | static void bru_try_format(struct vsp1_bru *bru, struct v4l2_subdev_pad_config *cfg, |
256 | unsigned int pad, struct v4l2_mbus_framefmt *fmt, | 258 | unsigned int pad, struct v4l2_mbus_framefmt *fmt, |
257 | enum v4l2_subdev_format_whence which) | 259 | enum v4l2_subdev_format_whence which) |
258 | { | 260 | { |
@@ -268,7 +270,7 @@ static void bru_try_format(struct vsp1_bru *bru, struct v4l2_subdev_fh *fh, | |||
268 | 270 | ||
269 | default: | 271 | default: |
270 | /* The BRU can't perform format conversion. */ | 272 | /* The BRU can't perform format conversion. */ |
271 | format = vsp1_entity_get_pad_format(&bru->entity, fh, | 273 | format = vsp1_entity_get_pad_format(&bru->entity, cfg, |
272 | BRU_PAD_SINK(0), which); | 274 | BRU_PAD_SINK(0), which); |
273 | fmt->code = format->code; | 275 | fmt->code = format->code; |
274 | break; | 276 | break; |
@@ -280,15 +282,15 @@ static void bru_try_format(struct vsp1_bru *bru, struct v4l2_subdev_fh *fh, | |||
280 | fmt->colorspace = V4L2_COLORSPACE_SRGB; | 282 | fmt->colorspace = V4L2_COLORSPACE_SRGB; |
281 | } | 283 | } |
282 | 284 | ||
283 | static int bru_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, | 285 | static int bru_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg, |
284 | struct v4l2_subdev_format *fmt) | 286 | struct v4l2_subdev_format *fmt) |
285 | { | 287 | { |
286 | struct vsp1_bru *bru = to_bru(subdev); | 288 | struct vsp1_bru *bru = to_bru(subdev); |
287 | struct v4l2_mbus_framefmt *format; | 289 | struct v4l2_mbus_framefmt *format; |
288 | 290 | ||
289 | bru_try_format(bru, fh, fmt->pad, &fmt->format, fmt->which); | 291 | bru_try_format(bru, cfg, fmt->pad, &fmt->format, fmt->which); |
290 | 292 | ||
291 | format = vsp1_entity_get_pad_format(&bru->entity, fh, fmt->pad, | 293 | format = vsp1_entity_get_pad_format(&bru->entity, cfg, fmt->pad, |
292 | fmt->which); | 294 | fmt->which); |
293 | *format = fmt->format; | 295 | *format = fmt->format; |
294 | 296 | ||
@@ -296,7 +298,7 @@ static int bru_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, | |||
296 | if (fmt->pad != BRU_PAD_SOURCE) { | 298 | if (fmt->pad != BRU_PAD_SOURCE) { |
297 | struct v4l2_rect *compose; | 299 | struct v4l2_rect *compose; |
298 | 300 | ||
299 | compose = bru_get_compose(bru, fh, fmt->pad, fmt->which); | 301 | compose = bru_get_compose(bru, cfg, fmt->pad, fmt->which); |
300 | compose->left = 0; | 302 | compose->left = 0; |
301 | compose->top = 0; | 303 | compose->top = 0; |
302 | compose->width = format->width; | 304 | compose->width = format->width; |
@@ -308,7 +310,7 @@ static int bru_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, | |||
308 | unsigned int i; | 310 | unsigned int i; |
309 | 311 | ||
310 | for (i = 0; i <= BRU_PAD_SOURCE; ++i) { | 312 | for (i = 0; i <= BRU_PAD_SOURCE; ++i) { |
311 | format = vsp1_entity_get_pad_format(&bru->entity, fh, | 313 | format = vsp1_entity_get_pad_format(&bru->entity, cfg, |
312 | i, fmt->which); | 314 | i, fmt->which); |
313 | format->code = fmt->format.code; | 315 | format->code = fmt->format.code; |
314 | } | 316 | } |
@@ -318,7 +320,7 @@ static int bru_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, | |||
318 | } | 320 | } |
319 | 321 | ||
320 | static int bru_get_selection(struct v4l2_subdev *subdev, | 322 | static int bru_get_selection(struct v4l2_subdev *subdev, |
321 | struct v4l2_subdev_fh *fh, | 323 | struct v4l2_subdev_pad_config *cfg, |
322 | struct v4l2_subdev_selection *sel) | 324 | struct v4l2_subdev_selection *sel) |
323 | { | 325 | { |
324 | struct vsp1_bru *bru = to_bru(subdev); | 326 | struct vsp1_bru *bru = to_bru(subdev); |
@@ -335,7 +337,7 @@ static int bru_get_selection(struct v4l2_subdev *subdev, | |||
335 | return 0; | 337 | return 0; |
336 | 338 | ||
337 | case V4L2_SEL_TGT_COMPOSE: | 339 | case V4L2_SEL_TGT_COMPOSE: |
338 | sel->r = *bru_get_compose(bru, fh, sel->pad, sel->which); | 340 | sel->r = *bru_get_compose(bru, cfg, sel->pad, sel->which); |
339 | return 0; | 341 | return 0; |
340 | 342 | ||
341 | default: | 343 | default: |
@@ -344,7 +346,7 @@ static int bru_get_selection(struct v4l2_subdev *subdev, | |||
344 | } | 346 | } |
345 | 347 | ||
346 | static int bru_set_selection(struct v4l2_subdev *subdev, | 348 | static int bru_set_selection(struct v4l2_subdev *subdev, |
347 | struct v4l2_subdev_fh *fh, | 349 | struct v4l2_subdev_pad_config *cfg, |
348 | struct v4l2_subdev_selection *sel) | 350 | struct v4l2_subdev_selection *sel) |
349 | { | 351 | { |
350 | struct vsp1_bru *bru = to_bru(subdev); | 352 | struct vsp1_bru *bru = to_bru(subdev); |
@@ -360,7 +362,7 @@ static int bru_set_selection(struct v4l2_subdev *subdev, | |||
360 | /* The compose rectangle top left corner must be inside the output | 362 | /* The compose rectangle top left corner must be inside the output |
361 | * frame. | 363 | * frame. |
362 | */ | 364 | */ |
363 | format = vsp1_entity_get_pad_format(&bru->entity, fh, BRU_PAD_SOURCE, | 365 | format = vsp1_entity_get_pad_format(&bru->entity, cfg, BRU_PAD_SOURCE, |
364 | sel->which); | 366 | sel->which); |
365 | sel->r.left = clamp_t(unsigned int, sel->r.left, 0, format->width - 1); | 367 | sel->r.left = clamp_t(unsigned int, sel->r.left, 0, format->width - 1); |
366 | sel->r.top = clamp_t(unsigned int, sel->r.top, 0, format->height - 1); | 368 | sel->r.top = clamp_t(unsigned int, sel->r.top, 0, format->height - 1); |
@@ -368,12 +370,12 @@ static int bru_set_selection(struct v4l2_subdev *subdev, | |||
368 | /* Scaling isn't supported, the compose rectangle size must be identical | 370 | /* Scaling isn't supported, the compose rectangle size must be identical |
369 | * to the sink format size. | 371 | * to the sink format size. |
370 | */ | 372 | */ |
371 | format = vsp1_entity_get_pad_format(&bru->entity, fh, sel->pad, | 373 | format = vsp1_entity_get_pad_format(&bru->entity, cfg, sel->pad, |
372 | sel->which); | 374 | sel->which); |
373 | sel->r.width = format->width; | 375 | sel->r.width = format->width; |
374 | sel->r.height = format->height; | 376 | sel->r.height = format->height; |
375 | 377 | ||
376 | compose = bru_get_compose(bru, fh, sel->pad, sel->which); | 378 | compose = bru_get_compose(bru, cfg, sel->pad, sel->which); |
377 | *compose = sel->r; | 379 | *compose = sel->r; |
378 | 380 | ||
379 | return 0; | 381 | return 0; |
diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c index 79af71d5e270..a453bb4ddd37 100644 --- a/drivers/media/platform/vsp1/vsp1_entity.c +++ b/drivers/media/platform/vsp1/vsp1_entity.c | |||
@@ -63,12 +63,12 @@ int vsp1_entity_set_streaming(struct vsp1_entity *entity, bool streaming) | |||
63 | 63 | ||
64 | struct v4l2_mbus_framefmt * | 64 | struct v4l2_mbus_framefmt * |
65 | vsp1_entity_get_pad_format(struct vsp1_entity *entity, | 65 | vsp1_entity_get_pad_format(struct vsp1_entity *entity, |
66 | struct v4l2_subdev_fh *fh, | 66 | struct v4l2_subdev_pad_config *cfg, |
67 | unsigned int pad, u32 which) | 67 | unsigned int pad, u32 which) |
68 | { | 68 | { |
69 | switch (which) { | 69 | switch (which) { |
70 | case V4L2_SUBDEV_FORMAT_TRY: | 70 | case V4L2_SUBDEV_FORMAT_TRY: |
71 | return v4l2_subdev_get_try_format(fh, pad); | 71 | return v4l2_subdev_get_try_format(&entity->subdev, cfg, pad); |
72 | case V4L2_SUBDEV_FORMAT_ACTIVE: | 72 | case V4L2_SUBDEV_FORMAT_ACTIVE: |
73 | return &entity->formats[pad]; | 73 | return &entity->formats[pad]; |
74 | default: | 74 | default: |
@@ -79,14 +79,14 @@ vsp1_entity_get_pad_format(struct vsp1_entity *entity, | |||
79 | /* | 79 | /* |
80 | * vsp1_entity_init_formats - Initialize formats on all pads | 80 | * vsp1_entity_init_formats - Initialize formats on all pads |
81 | * @subdev: V4L2 subdevice | 81 | * @subdev: V4L2 subdevice |
82 | * @fh: V4L2 subdev file handle | 82 | * @cfg: V4L2 subdev pad configuration |
83 | * | 83 | * |
84 | * Initialize all pad formats with default values. If fh is not NULL, try | 84 | * Initialize all pad formats with default values. If cfg is not NULL, try |
85 | * formats are initialized on the file handle. Otherwise active formats are | 85 | * formats are initialized on the file handle. Otherwise active formats are |
86 | * initialized on the device. | 86 | * initialized on the device. |
87 | */ | 87 | */ |
88 | void vsp1_entity_init_formats(struct v4l2_subdev *subdev, | 88 | void vsp1_entity_init_formats(struct v4l2_subdev *subdev, |
89 | struct v4l2_subdev_fh *fh) | 89 | struct v4l2_subdev_pad_config *cfg) |
90 | { | 90 | { |
91 | struct v4l2_subdev_format format; | 91 | struct v4l2_subdev_format format; |
92 | unsigned int pad; | 92 | unsigned int pad; |
@@ -95,17 +95,17 @@ void vsp1_entity_init_formats(struct v4l2_subdev *subdev, | |||
95 | memset(&format, 0, sizeof(format)); | 95 | memset(&format, 0, sizeof(format)); |
96 | 96 | ||
97 | format.pad = pad; | 97 | format.pad = pad; |
98 | format.which = fh ? V4L2_SUBDEV_FORMAT_TRY | 98 | format.which = cfg ? V4L2_SUBDEV_FORMAT_TRY |
99 | : V4L2_SUBDEV_FORMAT_ACTIVE; | 99 | : V4L2_SUBDEV_FORMAT_ACTIVE; |
100 | 100 | ||
101 | v4l2_subdev_call(subdev, pad, set_fmt, fh, &format); | 101 | v4l2_subdev_call(subdev, pad, set_fmt, cfg, &format); |
102 | } | 102 | } |
103 | } | 103 | } |
104 | 104 | ||
105 | static int vsp1_entity_open(struct v4l2_subdev *subdev, | 105 | static int vsp1_entity_open(struct v4l2_subdev *subdev, |
106 | struct v4l2_subdev_fh *fh) | 106 | struct v4l2_subdev_fh *fh) |
107 | { | 107 | { |
108 | vsp1_entity_init_formats(subdev, fh); | 108 | vsp1_entity_init_formats(subdev, fh->pad); |
109 | 109 | ||
110 | return 0; | 110 | return 0; |
111 | } | 111 | } |
diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h index aa20aaa58208..62c768d1c6aa 100644 --- a/drivers/media/platform/vsp1/vsp1_entity.h +++ b/drivers/media/platform/vsp1/vsp1_entity.h | |||
@@ -91,10 +91,10 @@ extern const struct media_entity_operations vsp1_media_ops; | |||
91 | 91 | ||
92 | struct v4l2_mbus_framefmt * | 92 | struct v4l2_mbus_framefmt * |
93 | vsp1_entity_get_pad_format(struct vsp1_entity *entity, | 93 | vsp1_entity_get_pad_format(struct vsp1_entity *entity, |
94 | struct v4l2_subdev_fh *fh, | 94 | struct v4l2_subdev_pad_config *cfg, |
95 | unsigned int pad, u32 which); | 95 | unsigned int pad, u32 which); |
96 | void vsp1_entity_init_formats(struct v4l2_subdev *subdev, | 96 | void vsp1_entity_init_formats(struct v4l2_subdev *subdev, |
97 | struct v4l2_subdev_fh *fh); | 97 | struct v4l2_subdev_pad_config *cfg); |
98 | 98 | ||
99 | bool vsp1_entity_is_streaming(struct vsp1_entity *entity); | 99 | bool vsp1_entity_is_streaming(struct vsp1_entity *entity); |
100 | int vsp1_entity_set_streaming(struct vsp1_entity *entity, bool streaming); | 100 | int vsp1_entity_set_streaming(struct vsp1_entity *entity, bool streaming); |
diff --git a/drivers/media/platform/vsp1/vsp1_hsit.c b/drivers/media/platform/vsp1/vsp1_hsit.c index 0bc0471746c9..8ffb817ae525 100644 --- a/drivers/media/platform/vsp1/vsp1_hsit.c +++ b/drivers/media/platform/vsp1/vsp1_hsit.c | |||
@@ -55,7 +55,7 @@ static int hsit_s_stream(struct v4l2_subdev *subdev, int enable) | |||
55 | */ | 55 | */ |
56 | 56 | ||
57 | static int hsit_enum_mbus_code(struct v4l2_subdev *subdev, | 57 | static int hsit_enum_mbus_code(struct v4l2_subdev *subdev, |
58 | struct v4l2_subdev_fh *fh, | 58 | struct v4l2_subdev_pad_config *cfg, |
59 | struct v4l2_subdev_mbus_code_enum *code) | 59 | struct v4l2_subdev_mbus_code_enum *code) |
60 | { | 60 | { |
61 | struct vsp1_hsit *hsit = to_hsit(subdev); | 61 | struct vsp1_hsit *hsit = to_hsit(subdev); |
@@ -73,12 +73,14 @@ static int hsit_enum_mbus_code(struct v4l2_subdev *subdev, | |||
73 | } | 73 | } |
74 | 74 | ||
75 | static int hsit_enum_frame_size(struct v4l2_subdev *subdev, | 75 | static int hsit_enum_frame_size(struct v4l2_subdev *subdev, |
76 | struct v4l2_subdev_fh *fh, | 76 | struct v4l2_subdev_pad_config *cfg, |
77 | struct v4l2_subdev_frame_size_enum *fse) | 77 | struct v4l2_subdev_frame_size_enum *fse) |
78 | { | 78 | { |
79 | struct vsp1_hsit *hsit = to_hsit(subdev); | ||
79 | struct v4l2_mbus_framefmt *format; | 80 | struct v4l2_mbus_framefmt *format; |
80 | 81 | ||
81 | format = v4l2_subdev_get_try_format(fh, fse->pad); | 82 | format = vsp1_entity_get_pad_format(&hsit->entity, cfg, fse->pad, |
83 | fse->which); | ||
82 | 84 | ||
83 | if (fse->index || fse->code != format->code) | 85 | if (fse->index || fse->code != format->code) |
84 | return -EINVAL; | 86 | return -EINVAL; |
@@ -102,25 +104,25 @@ static int hsit_enum_frame_size(struct v4l2_subdev *subdev, | |||
102 | } | 104 | } |
103 | 105 | ||
104 | static int hsit_get_format(struct v4l2_subdev *subdev, | 106 | static int hsit_get_format(struct v4l2_subdev *subdev, |
105 | struct v4l2_subdev_fh *fh, | 107 | struct v4l2_subdev_pad_config *cfg, |
106 | struct v4l2_subdev_format *fmt) | 108 | struct v4l2_subdev_format *fmt) |
107 | { | 109 | { |
108 | struct vsp1_hsit *hsit = to_hsit(subdev); | 110 | struct vsp1_hsit *hsit = to_hsit(subdev); |
109 | 111 | ||
110 | fmt->format = *vsp1_entity_get_pad_format(&hsit->entity, fh, fmt->pad, | 112 | fmt->format = *vsp1_entity_get_pad_format(&hsit->entity, cfg, fmt->pad, |
111 | fmt->which); | 113 | fmt->which); |
112 | 114 | ||
113 | return 0; | 115 | return 0; |
114 | } | 116 | } |
115 | 117 | ||
116 | static int hsit_set_format(struct v4l2_subdev *subdev, | 118 | static int hsit_set_format(struct v4l2_subdev *subdev, |
117 | struct v4l2_subdev_fh *fh, | 119 | struct v4l2_subdev_pad_config *cfg, |
118 | struct v4l2_subdev_format *fmt) | 120 | struct v4l2_subdev_format *fmt) |
119 | { | 121 | { |
120 | struct vsp1_hsit *hsit = to_hsit(subdev); | 122 | struct vsp1_hsit *hsit = to_hsit(subdev); |
121 | struct v4l2_mbus_framefmt *format; | 123 | struct v4l2_mbus_framefmt *format; |
122 | 124 | ||
123 | format = vsp1_entity_get_pad_format(&hsit->entity, fh, fmt->pad, | 125 | format = vsp1_entity_get_pad_format(&hsit->entity, cfg, fmt->pad, |
124 | fmt->which); | 126 | fmt->which); |
125 | 127 | ||
126 | if (fmt->pad == HSIT_PAD_SOURCE) { | 128 | if (fmt->pad == HSIT_PAD_SOURCE) { |
@@ -143,7 +145,7 @@ static int hsit_set_format(struct v4l2_subdev *subdev, | |||
143 | fmt->format = *format; | 145 | fmt->format = *format; |
144 | 146 | ||
145 | /* Propagate the format to the source pad. */ | 147 | /* Propagate the format to the source pad. */ |
146 | format = vsp1_entity_get_pad_format(&hsit->entity, fh, HSIT_PAD_SOURCE, | 148 | format = vsp1_entity_get_pad_format(&hsit->entity, cfg, HSIT_PAD_SOURCE, |
147 | fmt->which); | 149 | fmt->which); |
148 | *format = fmt->format; | 150 | *format = fmt->format; |
149 | format->code = hsit->inverse ? MEDIA_BUS_FMT_ARGB8888_1X32 | 151 | format->code = hsit->inverse ? MEDIA_BUS_FMT_ARGB8888_1X32 |
diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c index 17a6ca7dafe6..39fa5ef20fbb 100644 --- a/drivers/media/platform/vsp1/vsp1_lif.c +++ b/drivers/media/platform/vsp1/vsp1_lif.c | |||
@@ -74,13 +74,14 @@ static int lif_s_stream(struct v4l2_subdev *subdev, int enable) | |||
74 | */ | 74 | */ |
75 | 75 | ||
76 | static int lif_enum_mbus_code(struct v4l2_subdev *subdev, | 76 | static int lif_enum_mbus_code(struct v4l2_subdev *subdev, |
77 | struct v4l2_subdev_fh *fh, | 77 | struct v4l2_subdev_pad_config *cfg, |
78 | struct v4l2_subdev_mbus_code_enum *code) | 78 | struct v4l2_subdev_mbus_code_enum *code) |
79 | { | 79 | { |
80 | static const unsigned int codes[] = { | 80 | static const unsigned int codes[] = { |
81 | MEDIA_BUS_FMT_ARGB8888_1X32, | 81 | MEDIA_BUS_FMT_ARGB8888_1X32, |
82 | MEDIA_BUS_FMT_AYUV8_1X32, | 82 | MEDIA_BUS_FMT_AYUV8_1X32, |
83 | }; | 83 | }; |
84 | struct vsp1_lif *lif = to_lif(subdev); | ||
84 | 85 | ||
85 | if (code->pad == LIF_PAD_SINK) { | 86 | if (code->pad == LIF_PAD_SINK) { |
86 | if (code->index >= ARRAY_SIZE(codes)) | 87 | if (code->index >= ARRAY_SIZE(codes)) |
@@ -96,7 +97,8 @@ static int lif_enum_mbus_code(struct v4l2_subdev *subdev, | |||
96 | if (code->index) | 97 | if (code->index) |
97 | return -EINVAL; | 98 | return -EINVAL; |
98 | 99 | ||
99 | format = v4l2_subdev_get_try_format(fh, LIF_PAD_SINK); | 100 | format = vsp1_entity_get_pad_format(&lif->entity, cfg, |
101 | LIF_PAD_SINK, code->which); | ||
100 | code->code = format->code; | 102 | code->code = format->code; |
101 | } | 103 | } |
102 | 104 | ||
@@ -104,12 +106,14 @@ static int lif_enum_mbus_code(struct v4l2_subdev *subdev, | |||
104 | } | 106 | } |
105 | 107 | ||
106 | static int lif_enum_frame_size(struct v4l2_subdev *subdev, | 108 | static int lif_enum_frame_size(struct v4l2_subdev *subdev, |
107 | struct v4l2_subdev_fh *fh, | 109 | struct v4l2_subdev_pad_config *cfg, |
108 | struct v4l2_subdev_frame_size_enum *fse) | 110 | struct v4l2_subdev_frame_size_enum *fse) |
109 | { | 111 | { |
112 | struct vsp1_lif *lif = to_lif(subdev); | ||
110 | struct v4l2_mbus_framefmt *format; | 113 | struct v4l2_mbus_framefmt *format; |
111 | 114 | ||
112 | format = v4l2_subdev_get_try_format(fh, LIF_PAD_SINK); | 115 | format = vsp1_entity_get_pad_format(&lif->entity, cfg, LIF_PAD_SINK, |
116 | fse->which); | ||
113 | 117 | ||
114 | if (fse->index || fse->code != format->code) | 118 | if (fse->index || fse->code != format->code) |
115 | return -EINVAL; | 119 | return -EINVAL; |
@@ -129,18 +133,18 @@ static int lif_enum_frame_size(struct v4l2_subdev *subdev, | |||
129 | return 0; | 133 | return 0; |
130 | } | 134 | } |
131 | 135 | ||
132 | static int lif_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, | 136 | static int lif_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg, |
133 | struct v4l2_subdev_format *fmt) | 137 | struct v4l2_subdev_format *fmt) |
134 | { | 138 | { |
135 | struct vsp1_lif *lif = to_lif(subdev); | 139 | struct vsp1_lif *lif = to_lif(subdev); |
136 | 140 | ||
137 | fmt->format = *vsp1_entity_get_pad_format(&lif->entity, fh, fmt->pad, | 141 | fmt->format = *vsp1_entity_get_pad_format(&lif->entity, cfg, fmt->pad, |
138 | fmt->which); | 142 | fmt->which); |
139 | 143 | ||
140 | return 0; | 144 | return 0; |
141 | } | 145 | } |
142 | 146 | ||
143 | static int lif_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, | 147 | static int lif_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg, |
144 | struct v4l2_subdev_format *fmt) | 148 | struct v4l2_subdev_format *fmt) |
145 | { | 149 | { |
146 | struct vsp1_lif *lif = to_lif(subdev); | 150 | struct vsp1_lif *lif = to_lif(subdev); |
@@ -151,7 +155,7 @@ static int lif_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, | |||
151 | fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32) | 155 | fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32) |
152 | fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32; | 156 | fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32; |
153 | 157 | ||
154 | format = vsp1_entity_get_pad_format(&lif->entity, fh, fmt->pad, | 158 | format = vsp1_entity_get_pad_format(&lif->entity, cfg, fmt->pad, |
155 | fmt->which); | 159 | fmt->which); |
156 | 160 | ||
157 | if (fmt->pad == LIF_PAD_SOURCE) { | 161 | if (fmt->pad == LIF_PAD_SOURCE) { |
@@ -173,7 +177,7 @@ static int lif_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, | |||
173 | fmt->format = *format; | 177 | fmt->format = *format; |
174 | 178 | ||
175 | /* Propagate the format to the source pad. */ | 179 | /* Propagate the format to the source pad. */ |
176 | format = vsp1_entity_get_pad_format(&lif->entity, fh, LIF_PAD_SOURCE, | 180 | format = vsp1_entity_get_pad_format(&lif->entity, cfg, LIF_PAD_SOURCE, |
177 | fmt->which); | 181 | fmt->which); |
178 | *format = fmt->format; | 182 | *format = fmt->format; |
179 | 183 | ||
diff --git a/drivers/media/platform/vsp1/vsp1_lut.c b/drivers/media/platform/vsp1/vsp1_lut.c index 6f185c3621fe..656ec272a414 100644 --- a/drivers/media/platform/vsp1/vsp1_lut.c +++ b/drivers/media/platform/vsp1/vsp1_lut.c | |||
@@ -82,7 +82,7 @@ static int lut_s_stream(struct v4l2_subdev *subdev, int enable) | |||
82 | */ | 82 | */ |
83 | 83 | ||
84 | static int lut_enum_mbus_code(struct v4l2_subdev *subdev, | 84 | static int lut_enum_mbus_code(struct v4l2_subdev *subdev, |
85 | struct v4l2_subdev_fh *fh, | 85 | struct v4l2_subdev_pad_config *cfg, |
86 | struct v4l2_subdev_mbus_code_enum *code) | 86 | struct v4l2_subdev_mbus_code_enum *code) |
87 | { | 87 | { |
88 | static const unsigned int codes[] = { | 88 | static const unsigned int codes[] = { |
@@ -90,6 +90,7 @@ static int lut_enum_mbus_code(struct v4l2_subdev *subdev, | |||
90 | MEDIA_BUS_FMT_AHSV8888_1X32, | 90 | MEDIA_BUS_FMT_AHSV8888_1X32, |
91 | MEDIA_BUS_FMT_AYUV8_1X32, | 91 | MEDIA_BUS_FMT_AYUV8_1X32, |
92 | }; | 92 | }; |
93 | struct vsp1_lut *lut = to_lut(subdev); | ||
93 | struct v4l2_mbus_framefmt *format; | 94 | struct v4l2_mbus_framefmt *format; |
94 | 95 | ||
95 | if (code->pad == LUT_PAD_SINK) { | 96 | if (code->pad == LUT_PAD_SINK) { |
@@ -104,7 +105,8 @@ static int lut_enum_mbus_code(struct v4l2_subdev *subdev, | |||
104 | if (code->index) | 105 | if (code->index) |
105 | return -EINVAL; | 106 | return -EINVAL; |
106 | 107 | ||
107 | format = v4l2_subdev_get_try_format(fh, LUT_PAD_SINK); | 108 | format = vsp1_entity_get_pad_format(&lut->entity, cfg, |
109 | LUT_PAD_SINK, code->which); | ||
108 | code->code = format->code; | 110 | code->code = format->code; |
109 | } | 111 | } |
110 | 112 | ||
@@ -112,12 +114,14 @@ static int lut_enum_mbus_code(struct v4l2_subdev *subdev, | |||
112 | } | 114 | } |
113 | 115 | ||
114 | static int lut_enum_frame_size(struct v4l2_subdev *subdev, | 116 | static int lut_enum_frame_size(struct v4l2_subdev *subdev, |
115 | struct v4l2_subdev_fh *fh, | 117 | struct v4l2_subdev_pad_config *cfg, |
116 | struct v4l2_subdev_frame_size_enum *fse) | 118 | struct v4l2_subdev_frame_size_enum *fse) |
117 | { | 119 | { |
120 | struct vsp1_lut *lut = to_lut(subdev); | ||
118 | struct v4l2_mbus_framefmt *format; | 121 | struct v4l2_mbus_framefmt *format; |
119 | 122 | ||
120 | format = v4l2_subdev_get_try_format(fh, fse->pad); | 123 | format = vsp1_entity_get_pad_format(&lut->entity, cfg, |
124 | fse->pad, fse->which); | ||
121 | 125 | ||
122 | if (fse->index || fse->code != format->code) | 126 | if (fse->index || fse->code != format->code) |
123 | return -EINVAL; | 127 | return -EINVAL; |
@@ -140,18 +144,18 @@ static int lut_enum_frame_size(struct v4l2_subdev *subdev, | |||
140 | return 0; | 144 | return 0; |
141 | } | 145 | } |
142 | 146 | ||
143 | static int lut_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, | 147 | static int lut_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg, |
144 | struct v4l2_subdev_format *fmt) | 148 | struct v4l2_subdev_format *fmt) |
145 | { | 149 | { |
146 | struct vsp1_lut *lut = to_lut(subdev); | 150 | struct vsp1_lut *lut = to_lut(subdev); |
147 | 151 | ||
148 | fmt->format = *vsp1_entity_get_pad_format(&lut->entity, fh, fmt->pad, | 152 | fmt->format = *vsp1_entity_get_pad_format(&lut->entity, cfg, fmt->pad, |
149 | fmt->which); | 153 | fmt->which); |
150 | 154 | ||
151 | return 0; | 155 | return 0; |
152 | } | 156 | } |
153 | 157 | ||
154 | static int lut_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, | 158 | static int lut_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg, |
155 | struct v4l2_subdev_format *fmt) | 159 | struct v4l2_subdev_format *fmt) |
156 | { | 160 | { |
157 | struct vsp1_lut *lut = to_lut(subdev); | 161 | struct vsp1_lut *lut = to_lut(subdev); |
@@ -163,7 +167,7 @@ static int lut_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, | |||
163 | fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32) | 167 | fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32) |
164 | fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32; | 168 | fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32; |
165 | 169 | ||
166 | format = vsp1_entity_get_pad_format(&lut->entity, fh, fmt->pad, | 170 | format = vsp1_entity_get_pad_format(&lut->entity, cfg, fmt->pad, |
167 | fmt->which); | 171 | fmt->which); |
168 | 172 | ||
169 | if (fmt->pad == LUT_PAD_SOURCE) { | 173 | if (fmt->pad == LUT_PAD_SOURCE) { |
@@ -182,7 +186,7 @@ static int lut_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, | |||
182 | fmt->format = *format; | 186 | fmt->format = *format; |
183 | 187 | ||
184 | /* Propagate the format to the source pad. */ | 188 | /* Propagate the format to the source pad. */ |
185 | format = vsp1_entity_get_pad_format(&lut->entity, fh, LUT_PAD_SOURCE, | 189 | format = vsp1_entity_get_pad_format(&lut->entity, cfg, LUT_PAD_SOURCE, |
186 | fmt->which); | 190 | fmt->which); |
187 | *format = fmt->format; | 191 | *format = fmt->format; |
188 | 192 | ||
diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.c b/drivers/media/platform/vsp1/vsp1_rwpf.c index 1f1ba26a834a..fa71f4695e16 100644 --- a/drivers/media/platform/vsp1/vsp1_rwpf.c +++ b/drivers/media/platform/vsp1/vsp1_rwpf.c | |||
@@ -25,7 +25,7 @@ | |||
25 | */ | 25 | */ |
26 | 26 | ||
27 | int vsp1_rwpf_enum_mbus_code(struct v4l2_subdev *subdev, | 27 | int vsp1_rwpf_enum_mbus_code(struct v4l2_subdev *subdev, |
28 | struct v4l2_subdev_fh *fh, | 28 | struct v4l2_subdev_pad_config *cfg, |
29 | struct v4l2_subdev_mbus_code_enum *code) | 29 | struct v4l2_subdev_mbus_code_enum *code) |
30 | { | 30 | { |
31 | static const unsigned int codes[] = { | 31 | static const unsigned int codes[] = { |
@@ -42,13 +42,14 @@ int vsp1_rwpf_enum_mbus_code(struct v4l2_subdev *subdev, | |||
42 | } | 42 | } |
43 | 43 | ||
44 | int vsp1_rwpf_enum_frame_size(struct v4l2_subdev *subdev, | 44 | int vsp1_rwpf_enum_frame_size(struct v4l2_subdev *subdev, |
45 | struct v4l2_subdev_fh *fh, | 45 | struct v4l2_subdev_pad_config *cfg, |
46 | struct v4l2_subdev_frame_size_enum *fse) | 46 | struct v4l2_subdev_frame_size_enum *fse) |
47 | { | 47 | { |
48 | struct vsp1_rwpf *rwpf = to_rwpf(subdev); | 48 | struct vsp1_rwpf *rwpf = to_rwpf(subdev); |
49 | struct v4l2_mbus_framefmt *format; | 49 | struct v4l2_mbus_framefmt *format; |
50 | 50 | ||
51 | format = v4l2_subdev_get_try_format(fh, fse->pad); | 51 | format = vsp1_entity_get_pad_format(&rwpf->entity, cfg, fse->pad, |
52 | fse->which); | ||
52 | 53 | ||
53 | if (fse->index || fse->code != format->code) | 54 | if (fse->index || fse->code != format->code) |
54 | return -EINVAL; | 55 | return -EINVAL; |
@@ -72,11 +73,11 @@ int vsp1_rwpf_enum_frame_size(struct v4l2_subdev *subdev, | |||
72 | } | 73 | } |
73 | 74 | ||
74 | static struct v4l2_rect * | 75 | static struct v4l2_rect * |
75 | vsp1_rwpf_get_crop(struct vsp1_rwpf *rwpf, struct v4l2_subdev_fh *fh, u32 which) | 76 | vsp1_rwpf_get_crop(struct vsp1_rwpf *rwpf, struct v4l2_subdev_pad_config *cfg, u32 which) |
76 | { | 77 | { |
77 | switch (which) { | 78 | switch (which) { |
78 | case V4L2_SUBDEV_FORMAT_TRY: | 79 | case V4L2_SUBDEV_FORMAT_TRY: |
79 | return v4l2_subdev_get_try_crop(fh, RWPF_PAD_SINK); | 80 | return v4l2_subdev_get_try_crop(&rwpf->entity.subdev, cfg, RWPF_PAD_SINK); |
80 | case V4L2_SUBDEV_FORMAT_ACTIVE: | 81 | case V4L2_SUBDEV_FORMAT_ACTIVE: |
81 | return &rwpf->crop; | 82 | return &rwpf->crop; |
82 | default: | 83 | default: |
@@ -84,18 +85,18 @@ vsp1_rwpf_get_crop(struct vsp1_rwpf *rwpf, struct v4l2_subdev_fh *fh, u32 which) | |||
84 | } | 85 | } |
85 | } | 86 | } |
86 | 87 | ||
87 | int vsp1_rwpf_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, | 88 | int vsp1_rwpf_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg, |
88 | struct v4l2_subdev_format *fmt) | 89 | struct v4l2_subdev_format *fmt) |
89 | { | 90 | { |
90 | struct vsp1_rwpf *rwpf = to_rwpf(subdev); | 91 | struct vsp1_rwpf *rwpf = to_rwpf(subdev); |
91 | 92 | ||
92 | fmt->format = *vsp1_entity_get_pad_format(&rwpf->entity, fh, fmt->pad, | 93 | fmt->format = *vsp1_entity_get_pad_format(&rwpf->entity, cfg, fmt->pad, |
93 | fmt->which); | 94 | fmt->which); |
94 | 95 | ||
95 | return 0; | 96 | return 0; |
96 | } | 97 | } |
97 | 98 | ||
98 | int vsp1_rwpf_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, | 99 | int vsp1_rwpf_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg, |
99 | struct v4l2_subdev_format *fmt) | 100 | struct v4l2_subdev_format *fmt) |
100 | { | 101 | { |
101 | struct vsp1_rwpf *rwpf = to_rwpf(subdev); | 102 | struct vsp1_rwpf *rwpf = to_rwpf(subdev); |
@@ -107,7 +108,7 @@ int vsp1_rwpf_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, | |||
107 | fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32) | 108 | fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32) |
108 | fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32; | 109 | fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32; |
109 | 110 | ||
110 | format = vsp1_entity_get_pad_format(&rwpf->entity, fh, fmt->pad, | 111 | format = vsp1_entity_get_pad_format(&rwpf->entity, cfg, fmt->pad, |
111 | fmt->which); | 112 | fmt->which); |
112 | 113 | ||
113 | if (fmt->pad == RWPF_PAD_SOURCE) { | 114 | if (fmt->pad == RWPF_PAD_SOURCE) { |
@@ -130,14 +131,14 @@ int vsp1_rwpf_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, | |||
130 | fmt->format = *format; | 131 | fmt->format = *format; |
131 | 132 | ||
132 | /* Update the sink crop rectangle. */ | 133 | /* Update the sink crop rectangle. */ |
133 | crop = vsp1_rwpf_get_crop(rwpf, fh, fmt->which); | 134 | crop = vsp1_rwpf_get_crop(rwpf, cfg, fmt->which); |
134 | crop->left = 0; | 135 | crop->left = 0; |
135 | crop->top = 0; | 136 | crop->top = 0; |
136 | crop->width = fmt->format.width; | 137 | crop->width = fmt->format.width; |
137 | crop->height = fmt->format.height; | 138 | crop->height = fmt->format.height; |
138 | 139 | ||
139 | /* Propagate the format to the source pad. */ | 140 | /* Propagate the format to the source pad. */ |
140 | format = vsp1_entity_get_pad_format(&rwpf->entity, fh, RWPF_PAD_SOURCE, | 141 | format = vsp1_entity_get_pad_format(&rwpf->entity, cfg, RWPF_PAD_SOURCE, |
141 | fmt->which); | 142 | fmt->which); |
142 | *format = fmt->format; | 143 | *format = fmt->format; |
143 | 144 | ||
@@ -145,7 +146,7 @@ int vsp1_rwpf_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, | |||
145 | } | 146 | } |
146 | 147 | ||
147 | int vsp1_rwpf_get_selection(struct v4l2_subdev *subdev, | 148 | int vsp1_rwpf_get_selection(struct v4l2_subdev *subdev, |
148 | struct v4l2_subdev_fh *fh, | 149 | struct v4l2_subdev_pad_config *cfg, |
149 | struct v4l2_subdev_selection *sel) | 150 | struct v4l2_subdev_selection *sel) |
150 | { | 151 | { |
151 | struct vsp1_rwpf *rwpf = to_rwpf(subdev); | 152 | struct vsp1_rwpf *rwpf = to_rwpf(subdev); |
@@ -157,11 +158,11 @@ int vsp1_rwpf_get_selection(struct v4l2_subdev *subdev, | |||
157 | 158 | ||
158 | switch (sel->target) { | 159 | switch (sel->target) { |
159 | case V4L2_SEL_TGT_CROP: | 160 | case V4L2_SEL_TGT_CROP: |
160 | sel->r = *vsp1_rwpf_get_crop(rwpf, fh, sel->which); | 161 | sel->r = *vsp1_rwpf_get_crop(rwpf, cfg, sel->which); |
161 | break; | 162 | break; |
162 | 163 | ||
163 | case V4L2_SEL_TGT_CROP_BOUNDS: | 164 | case V4L2_SEL_TGT_CROP_BOUNDS: |
164 | format = vsp1_entity_get_pad_format(&rwpf->entity, fh, | 165 | format = vsp1_entity_get_pad_format(&rwpf->entity, cfg, |
165 | RWPF_PAD_SINK, sel->which); | 166 | RWPF_PAD_SINK, sel->which); |
166 | sel->r.left = 0; | 167 | sel->r.left = 0; |
167 | sel->r.top = 0; | 168 | sel->r.top = 0; |
@@ -177,7 +178,7 @@ int vsp1_rwpf_get_selection(struct v4l2_subdev *subdev, | |||
177 | } | 178 | } |
178 | 179 | ||
179 | int vsp1_rwpf_set_selection(struct v4l2_subdev *subdev, | 180 | int vsp1_rwpf_set_selection(struct v4l2_subdev *subdev, |
180 | struct v4l2_subdev_fh *fh, | 181 | struct v4l2_subdev_pad_config *cfg, |
181 | struct v4l2_subdev_selection *sel) | 182 | struct v4l2_subdev_selection *sel) |
182 | { | 183 | { |
183 | struct vsp1_rwpf *rwpf = to_rwpf(subdev); | 184 | struct vsp1_rwpf *rwpf = to_rwpf(subdev); |
@@ -194,7 +195,7 @@ int vsp1_rwpf_set_selection(struct v4l2_subdev *subdev, | |||
194 | /* Make sure the crop rectangle is entirely contained in the image. The | 195 | /* Make sure the crop rectangle is entirely contained in the image. The |
195 | * WPF top and left offsets are limited to 255. | 196 | * WPF top and left offsets are limited to 255. |
196 | */ | 197 | */ |
197 | format = vsp1_entity_get_pad_format(&rwpf->entity, fh, RWPF_PAD_SINK, | 198 | format = vsp1_entity_get_pad_format(&rwpf->entity, cfg, RWPF_PAD_SINK, |
198 | sel->which); | 199 | sel->which); |
199 | sel->r.left = min_t(unsigned int, sel->r.left, format->width - 2); | 200 | sel->r.left = min_t(unsigned int, sel->r.left, format->width - 2); |
200 | sel->r.top = min_t(unsigned int, sel->r.top, format->height - 2); | 201 | sel->r.top = min_t(unsigned int, sel->r.top, format->height - 2); |
@@ -207,11 +208,11 @@ int vsp1_rwpf_set_selection(struct v4l2_subdev *subdev, | |||
207 | sel->r.height = min_t(unsigned int, sel->r.height, | 208 | sel->r.height = min_t(unsigned int, sel->r.height, |
208 | format->height - sel->r.top); | 209 | format->height - sel->r.top); |
209 | 210 | ||
210 | crop = vsp1_rwpf_get_crop(rwpf, fh, sel->which); | 211 | crop = vsp1_rwpf_get_crop(rwpf, cfg, sel->which); |
211 | *crop = sel->r; | 212 | *crop = sel->r; |
212 | 213 | ||
213 | /* Propagate the format to the source pad. */ | 214 | /* Propagate the format to the source pad. */ |
214 | format = vsp1_entity_get_pad_format(&rwpf->entity, fh, RWPF_PAD_SOURCE, | 215 | format = vsp1_entity_get_pad_format(&rwpf->entity, cfg, RWPF_PAD_SOURCE, |
215 | sel->which); | 216 | sel->which); |
216 | format->width = crop->width; | 217 | format->width = crop->width; |
217 | format->height = crop->height; | 218 | format->height = crop->height; |
diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h index 2cf1f13d3bf9..f452dce1a931 100644 --- a/drivers/media/platform/vsp1/vsp1_rwpf.h +++ b/drivers/media/platform/vsp1/vsp1_rwpf.h | |||
@@ -51,20 +51,20 @@ struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index); | |||
51 | struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index); | 51 | struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index); |
52 | 52 | ||
53 | int vsp1_rwpf_enum_mbus_code(struct v4l2_subdev *subdev, | 53 | int vsp1_rwpf_enum_mbus_code(struct v4l2_subdev *subdev, |
54 | struct v4l2_subdev_fh *fh, | 54 | struct v4l2_subdev_pad_config *cfg, |
55 | struct v4l2_subdev_mbus_code_enum *code); | 55 | struct v4l2_subdev_mbus_code_enum *code); |
56 | int vsp1_rwpf_enum_frame_size(struct v4l2_subdev *subdev, | 56 | int vsp1_rwpf_enum_frame_size(struct v4l2_subdev *subdev, |
57 | struct v4l2_subdev_fh *fh, | 57 | struct v4l2_subdev_pad_config *cfg, |
58 | struct v4l2_subdev_frame_size_enum *fse); | 58 | struct v4l2_subdev_frame_size_enum *fse); |
59 | int vsp1_rwpf_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, | 59 | int vsp1_rwpf_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg, |
60 | struct v4l2_subdev_format *fmt); | 60 | struct v4l2_subdev_format *fmt); |
61 | int vsp1_rwpf_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, | 61 | int vsp1_rwpf_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg, |
62 | struct v4l2_subdev_format *fmt); | 62 | struct v4l2_subdev_format *fmt); |
63 | int vsp1_rwpf_get_selection(struct v4l2_subdev *subdev, | 63 | int vsp1_rwpf_get_selection(struct v4l2_subdev *subdev, |
64 | struct v4l2_subdev_fh *fh, | 64 | struct v4l2_subdev_pad_config *cfg, |
65 | struct v4l2_subdev_selection *sel); | 65 | struct v4l2_subdev_selection *sel); |
66 | int vsp1_rwpf_set_selection(struct v4l2_subdev *subdev, | 66 | int vsp1_rwpf_set_selection(struct v4l2_subdev *subdev, |
67 | struct v4l2_subdev_fh *fh, | 67 | struct v4l2_subdev_pad_config *cfg, |
68 | struct v4l2_subdev_selection *sel); | 68 | struct v4l2_subdev_selection *sel); |
69 | 69 | ||
70 | #endif /* __VSP1_RWPF_H__ */ | 70 | #endif /* __VSP1_RWPF_H__ */ |
diff --git a/drivers/media/platform/vsp1/vsp1_sru.c b/drivers/media/platform/vsp1/vsp1_sru.c index 1129494c7cfc..6310acab60e7 100644 --- a/drivers/media/platform/vsp1/vsp1_sru.c +++ b/drivers/media/platform/vsp1/vsp1_sru.c | |||
@@ -166,13 +166,14 @@ static int sru_s_stream(struct v4l2_subdev *subdev, int enable) | |||
166 | */ | 166 | */ |
167 | 167 | ||
168 | static int sru_enum_mbus_code(struct v4l2_subdev *subdev, | 168 | static int sru_enum_mbus_code(struct v4l2_subdev *subdev, |
169 | struct v4l2_subdev_fh *fh, | 169 | struct v4l2_subdev_pad_config *cfg, |
170 | struct v4l2_subdev_mbus_code_enum *code) | 170 | struct v4l2_subdev_mbus_code_enum *code) |
171 | { | 171 | { |
172 | static const unsigned int codes[] = { | 172 | static const unsigned int codes[] = { |
173 | MEDIA_BUS_FMT_ARGB8888_1X32, | 173 | MEDIA_BUS_FMT_ARGB8888_1X32, |
174 | MEDIA_BUS_FMT_AYUV8_1X32, | 174 | MEDIA_BUS_FMT_AYUV8_1X32, |
175 | }; | 175 | }; |
176 | struct vsp1_sru *sru = to_sru(subdev); | ||
176 | struct v4l2_mbus_framefmt *format; | 177 | struct v4l2_mbus_framefmt *format; |
177 | 178 | ||
178 | if (code->pad == SRU_PAD_SINK) { | 179 | if (code->pad == SRU_PAD_SINK) { |
@@ -187,7 +188,8 @@ static int sru_enum_mbus_code(struct v4l2_subdev *subdev, | |||
187 | if (code->index) | 188 | if (code->index) |
188 | return -EINVAL; | 189 | return -EINVAL; |
189 | 190 | ||
190 | format = v4l2_subdev_get_try_format(fh, SRU_PAD_SINK); | 191 | format = vsp1_entity_get_pad_format(&sru->entity, cfg, |
192 | SRU_PAD_SINK, code->which); | ||
191 | code->code = format->code; | 193 | code->code = format->code; |
192 | } | 194 | } |
193 | 195 | ||
@@ -195,12 +197,14 @@ static int sru_enum_mbus_code(struct v4l2_subdev *subdev, | |||
195 | } | 197 | } |
196 | 198 | ||
197 | static int sru_enum_frame_size(struct v4l2_subdev *subdev, | 199 | static int sru_enum_frame_size(struct v4l2_subdev *subdev, |
198 | struct v4l2_subdev_fh *fh, | 200 | struct v4l2_subdev_pad_config *cfg, |
199 | struct v4l2_subdev_frame_size_enum *fse) | 201 | struct v4l2_subdev_frame_size_enum *fse) |
200 | { | 202 | { |
203 | struct vsp1_sru *sru = to_sru(subdev); | ||
201 | struct v4l2_mbus_framefmt *format; | 204 | struct v4l2_mbus_framefmt *format; |
202 | 205 | ||
203 | format = v4l2_subdev_get_try_format(fh, SRU_PAD_SINK); | 206 | format = vsp1_entity_get_pad_format(&sru->entity, cfg, |
207 | SRU_PAD_SINK, fse->which); | ||
204 | 208 | ||
205 | if (fse->index || fse->code != format->code) | 209 | if (fse->index || fse->code != format->code) |
206 | return -EINVAL; | 210 | return -EINVAL; |
@@ -226,18 +230,18 @@ static int sru_enum_frame_size(struct v4l2_subdev *subdev, | |||
226 | return 0; | 230 | return 0; |
227 | } | 231 | } |
228 | 232 | ||
229 | static int sru_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, | 233 | static int sru_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg, |
230 | struct v4l2_subdev_format *fmt) | 234 | struct v4l2_subdev_format *fmt) |
231 | { | 235 | { |
232 | struct vsp1_sru *sru = to_sru(subdev); | 236 | struct vsp1_sru *sru = to_sru(subdev); |
233 | 237 | ||
234 | fmt->format = *vsp1_entity_get_pad_format(&sru->entity, fh, fmt->pad, | 238 | fmt->format = *vsp1_entity_get_pad_format(&sru->entity, cfg, fmt->pad, |
235 | fmt->which); | 239 | fmt->which); |
236 | 240 | ||
237 | return 0; | 241 | return 0; |
238 | } | 242 | } |
239 | 243 | ||
240 | static void sru_try_format(struct vsp1_sru *sru, struct v4l2_subdev_fh *fh, | 244 | static void sru_try_format(struct vsp1_sru *sru, struct v4l2_subdev_pad_config *cfg, |
241 | unsigned int pad, struct v4l2_mbus_framefmt *fmt, | 245 | unsigned int pad, struct v4l2_mbus_framefmt *fmt, |
242 | enum v4l2_subdev_format_whence which) | 246 | enum v4l2_subdev_format_whence which) |
243 | { | 247 | { |
@@ -258,7 +262,7 @@ static void sru_try_format(struct vsp1_sru *sru, struct v4l2_subdev_fh *fh, | |||
258 | 262 | ||
259 | case SRU_PAD_SOURCE: | 263 | case SRU_PAD_SOURCE: |
260 | /* The SRU can't perform format conversion. */ | 264 | /* The SRU can't perform format conversion. */ |
261 | format = vsp1_entity_get_pad_format(&sru->entity, fh, | 265 | format = vsp1_entity_get_pad_format(&sru->entity, cfg, |
262 | SRU_PAD_SINK, which); | 266 | SRU_PAD_SINK, which); |
263 | fmt->code = format->code; | 267 | fmt->code = format->code; |
264 | 268 | ||
@@ -288,25 +292,25 @@ static void sru_try_format(struct vsp1_sru *sru, struct v4l2_subdev_fh *fh, | |||
288 | fmt->colorspace = V4L2_COLORSPACE_SRGB; | 292 | fmt->colorspace = V4L2_COLORSPACE_SRGB; |
289 | } | 293 | } |
290 | 294 | ||
291 | static int sru_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, | 295 | static int sru_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg, |
292 | struct v4l2_subdev_format *fmt) | 296 | struct v4l2_subdev_format *fmt) |
293 | { | 297 | { |
294 | struct vsp1_sru *sru = to_sru(subdev); | 298 | struct vsp1_sru *sru = to_sru(subdev); |
295 | struct v4l2_mbus_framefmt *format; | 299 | struct v4l2_mbus_framefmt *format; |
296 | 300 | ||
297 | sru_try_format(sru, fh, fmt->pad, &fmt->format, fmt->which); | 301 | sru_try_format(sru, cfg, fmt->pad, &fmt->format, fmt->which); |
298 | 302 | ||
299 | format = vsp1_entity_get_pad_format(&sru->entity, fh, fmt->pad, | 303 | format = vsp1_entity_get_pad_format(&sru->entity, cfg, fmt->pad, |
300 | fmt->which); | 304 | fmt->which); |
301 | *format = fmt->format; | 305 | *format = fmt->format; |
302 | 306 | ||
303 | if (fmt->pad == SRU_PAD_SINK) { | 307 | if (fmt->pad == SRU_PAD_SINK) { |
304 | /* Propagate the format to the source pad. */ | 308 | /* Propagate the format to the source pad. */ |
305 | format = vsp1_entity_get_pad_format(&sru->entity, fh, | 309 | format = vsp1_entity_get_pad_format(&sru->entity, cfg, |
306 | SRU_PAD_SOURCE, fmt->which); | 310 | SRU_PAD_SOURCE, fmt->which); |
307 | *format = fmt->format; | 311 | *format = fmt->format; |
308 | 312 | ||
309 | sru_try_format(sru, fh, SRU_PAD_SOURCE, format, fmt->which); | 313 | sru_try_format(sru, cfg, SRU_PAD_SOURCE, format, fmt->which); |
310 | } | 314 | } |
311 | 315 | ||
312 | return 0; | 316 | return 0; |
diff --git a/drivers/media/platform/vsp1/vsp1_uds.c b/drivers/media/platform/vsp1/vsp1_uds.c index a4afec133800..ccc8243e3493 100644 --- a/drivers/media/platform/vsp1/vsp1_uds.c +++ b/drivers/media/platform/vsp1/vsp1_uds.c | |||
@@ -169,13 +169,14 @@ static int uds_s_stream(struct v4l2_subdev *subdev, int enable) | |||
169 | */ | 169 | */ |
170 | 170 | ||
171 | static int uds_enum_mbus_code(struct v4l2_subdev *subdev, | 171 | static int uds_enum_mbus_code(struct v4l2_subdev *subdev, |
172 | struct v4l2_subdev_fh *fh, | 172 | struct v4l2_subdev_pad_config *cfg, |
173 | struct v4l2_subdev_mbus_code_enum *code) | 173 | struct v4l2_subdev_mbus_code_enum *code) |
174 | { | 174 | { |
175 | static const unsigned int codes[] = { | 175 | static const unsigned int codes[] = { |
176 | MEDIA_BUS_FMT_ARGB8888_1X32, | 176 | MEDIA_BUS_FMT_ARGB8888_1X32, |
177 | MEDIA_BUS_FMT_AYUV8_1X32, | 177 | MEDIA_BUS_FMT_AYUV8_1X32, |
178 | }; | 178 | }; |
179 | struct vsp1_uds *uds = to_uds(subdev); | ||
179 | 180 | ||
180 | if (code->pad == UDS_PAD_SINK) { | 181 | if (code->pad == UDS_PAD_SINK) { |
181 | if (code->index >= ARRAY_SIZE(codes)) | 182 | if (code->index >= ARRAY_SIZE(codes)) |
@@ -191,7 +192,8 @@ static int uds_enum_mbus_code(struct v4l2_subdev *subdev, | |||
191 | if (code->index) | 192 | if (code->index) |
192 | return -EINVAL; | 193 | return -EINVAL; |
193 | 194 | ||
194 | format = v4l2_subdev_get_try_format(fh, UDS_PAD_SINK); | 195 | format = vsp1_entity_get_pad_format(&uds->entity, cfg, |
196 | UDS_PAD_SINK, code->which); | ||
195 | code->code = format->code; | 197 | code->code = format->code; |
196 | } | 198 | } |
197 | 199 | ||
@@ -199,12 +201,14 @@ static int uds_enum_mbus_code(struct v4l2_subdev *subdev, | |||
199 | } | 201 | } |
200 | 202 | ||
201 | static int uds_enum_frame_size(struct v4l2_subdev *subdev, | 203 | static int uds_enum_frame_size(struct v4l2_subdev *subdev, |
202 | struct v4l2_subdev_fh *fh, | 204 | struct v4l2_subdev_pad_config *cfg, |
203 | struct v4l2_subdev_frame_size_enum *fse) | 205 | struct v4l2_subdev_frame_size_enum *fse) |
204 | { | 206 | { |
207 | struct vsp1_uds *uds = to_uds(subdev); | ||
205 | struct v4l2_mbus_framefmt *format; | 208 | struct v4l2_mbus_framefmt *format; |
206 | 209 | ||
207 | format = v4l2_subdev_get_try_format(fh, UDS_PAD_SINK); | 210 | format = vsp1_entity_get_pad_format(&uds->entity, cfg, |
211 | UDS_PAD_SINK, fse->which); | ||
208 | 212 | ||
209 | if (fse->index || fse->code != format->code) | 213 | if (fse->index || fse->code != format->code) |
210 | return -EINVAL; | 214 | return -EINVAL; |
@@ -224,18 +228,18 @@ static int uds_enum_frame_size(struct v4l2_subdev *subdev, | |||
224 | return 0; | 228 | return 0; |
225 | } | 229 | } |
226 | 230 | ||
227 | static int uds_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, | 231 | static int uds_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg, |
228 | struct v4l2_subdev_format *fmt) | 232 | struct v4l2_subdev_format *fmt) |
229 | { | 233 | { |
230 | struct vsp1_uds *uds = to_uds(subdev); | 234 | struct vsp1_uds *uds = to_uds(subdev); |
231 | 235 | ||
232 | fmt->format = *vsp1_entity_get_pad_format(&uds->entity, fh, fmt->pad, | 236 | fmt->format = *vsp1_entity_get_pad_format(&uds->entity, cfg, fmt->pad, |
233 | fmt->which); | 237 | fmt->which); |
234 | 238 | ||
235 | return 0; | 239 | return 0; |
236 | } | 240 | } |
237 | 241 | ||
238 | static void uds_try_format(struct vsp1_uds *uds, struct v4l2_subdev_fh *fh, | 242 | static void uds_try_format(struct vsp1_uds *uds, struct v4l2_subdev_pad_config *cfg, |
239 | unsigned int pad, struct v4l2_mbus_framefmt *fmt, | 243 | unsigned int pad, struct v4l2_mbus_framefmt *fmt, |
240 | enum v4l2_subdev_format_whence which) | 244 | enum v4l2_subdev_format_whence which) |
241 | { | 245 | { |
@@ -256,7 +260,7 @@ static void uds_try_format(struct vsp1_uds *uds, struct v4l2_subdev_fh *fh, | |||
256 | 260 | ||
257 | case UDS_PAD_SOURCE: | 261 | case UDS_PAD_SOURCE: |
258 | /* The UDS scales but can't perform format conversion. */ | 262 | /* The UDS scales but can't perform format conversion. */ |
259 | format = vsp1_entity_get_pad_format(&uds->entity, fh, | 263 | format = vsp1_entity_get_pad_format(&uds->entity, cfg, |
260 | UDS_PAD_SINK, which); | 264 | UDS_PAD_SINK, which); |
261 | fmt->code = format->code; | 265 | fmt->code = format->code; |
262 | 266 | ||
@@ -271,25 +275,25 @@ static void uds_try_format(struct vsp1_uds *uds, struct v4l2_subdev_fh *fh, | |||
271 | fmt->colorspace = V4L2_COLORSPACE_SRGB; | 275 | fmt->colorspace = V4L2_COLORSPACE_SRGB; |
272 | } | 276 | } |
273 | 277 | ||
274 | static int uds_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, | 278 | static int uds_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg, |
275 | struct v4l2_subdev_format *fmt) | 279 | struct v4l2_subdev_format *fmt) |
276 | { | 280 | { |
277 | struct vsp1_uds *uds = to_uds(subdev); | 281 | struct vsp1_uds *uds = to_uds(subdev); |
278 | struct v4l2_mbus_framefmt *format; | 282 | struct v4l2_mbus_framefmt *format; |
279 | 283 | ||
280 | uds_try_format(uds, fh, fmt->pad, &fmt->format, fmt->which); | 284 | uds_try_format(uds, cfg, fmt->pad, &fmt->format, fmt->which); |
281 | 285 | ||
282 | format = vsp1_entity_get_pad_format(&uds->entity, fh, fmt->pad, | 286 | format = vsp1_entity_get_pad_format(&uds->entity, cfg, fmt->pad, |
283 | fmt->which); | 287 | fmt->which); |
284 | *format = fmt->format; | 288 | *format = fmt->format; |
285 | 289 | ||
286 | if (fmt->pad == UDS_PAD_SINK) { | 290 | if (fmt->pad == UDS_PAD_SINK) { |
287 | /* Propagate the format to the source pad. */ | 291 | /* Propagate the format to the source pad. */ |
288 | format = vsp1_entity_get_pad_format(&uds->entity, fh, | 292 | format = vsp1_entity_get_pad_format(&uds->entity, cfg, |
289 | UDS_PAD_SOURCE, fmt->which); | 293 | UDS_PAD_SOURCE, fmt->which); |
290 | *format = fmt->format; | 294 | *format = fmt->format; |
291 | 295 | ||
292 | uds_try_format(uds, fh, UDS_PAD_SOURCE, format, fmt->which); | 296 | uds_try_format(uds, cfg, UDS_PAD_SOURCE, format, fmt->which); |
293 | } | 297 | } |
294 | 298 | ||
295 | return 0; | 299 | return 0; |
diff --git a/drivers/media/platform/xilinx/Kconfig b/drivers/media/platform/xilinx/Kconfig new file mode 100644 index 000000000000..d7324c726fc2 --- /dev/null +++ b/drivers/media/platform/xilinx/Kconfig | |||
@@ -0,0 +1,23 @@ | |||
1 | config VIDEO_XILINX | ||
2 | tristate "Xilinx Video IP (EXPERIMENTAL)" | ||
3 | depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF | ||
4 | select VIDEOBUF2_DMA_CONTIG | ||
5 | ---help--- | ||
6 | Driver for Xilinx Video IP Pipelines | ||
7 | |||
8 | if VIDEO_XILINX | ||
9 | |||
10 | config VIDEO_XILINX_TPG | ||
11 | tristate "Xilinx Video Test Pattern Generator" | ||
12 | depends on VIDEO_XILINX | ||
13 | select VIDEO_XILINX_VTC | ||
14 | ---help--- | ||
15 | Driver for the Xilinx Video Test Pattern Generator | ||
16 | |||
17 | config VIDEO_XILINX_VTC | ||
18 | tristate "Xilinx Video Timing Controller" | ||
19 | depends on VIDEO_XILINX | ||
20 | ---help--- | ||
21 | Driver for the Xilinx Video Timing Controller | ||
22 | |||
23 | endif #VIDEO_XILINX | ||
diff --git a/drivers/media/platform/xilinx/Makefile b/drivers/media/platform/xilinx/Makefile new file mode 100644 index 000000000000..e8a0f2a9f733 --- /dev/null +++ b/drivers/media/platform/xilinx/Makefile | |||
@@ -0,0 +1,5 @@ | |||
1 | xilinx-video-objs += xilinx-dma.o xilinx-vip.o xilinx-vipp.o | ||
2 | |||
3 | obj-$(CONFIG_VIDEO_XILINX) += xilinx-video.o | ||
4 | obj-$(CONFIG_VIDEO_XILINX_TPG) += xilinx-tpg.o | ||
5 | obj-$(CONFIG_VIDEO_XILINX_VTC) += xilinx-vtc.o | ||
diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c new file mode 100644 index 000000000000..10209c294168 --- /dev/null +++ b/drivers/media/platform/xilinx/xilinx-dma.c | |||
@@ -0,0 +1,766 @@ | |||
1 | /* | ||
2 | * Xilinx Video DMA | ||
3 | * | ||
4 | * Copyright (C) 2013-2015 Ideas on Board | ||
5 | * Copyright (C) 2013-2015 Xilinx, Inc. | ||
6 | * | ||
7 | * Contacts: Hyun Kwon <hyun.kwon@xilinx.com> | ||
8 | * Laurent Pinchart <laurent.pinchart@ideasonboard.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include <linux/amba/xilinx_dma.h> | ||
16 | #include <linux/lcm.h> | ||
17 | #include <linux/list.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/of.h> | ||
20 | #include <linux/slab.h> | ||
21 | |||
22 | #include <media/v4l2-dev.h> | ||
23 | #include <media/v4l2-fh.h> | ||
24 | #include <media/v4l2-ioctl.h> | ||
25 | #include <media/videobuf2-core.h> | ||
26 | #include <media/videobuf2-dma-contig.h> | ||
27 | |||
28 | #include "xilinx-dma.h" | ||
29 | #include "xilinx-vip.h" | ||
30 | #include "xilinx-vipp.h" | ||
31 | |||
32 | #define XVIP_DMA_DEF_FORMAT V4L2_PIX_FMT_YUYV | ||
33 | #define XVIP_DMA_DEF_WIDTH 1920 | ||
34 | #define XVIP_DMA_DEF_HEIGHT 1080 | ||
35 | |||
36 | /* Minimum and maximum widths are expressed in bytes */ | ||
37 | #define XVIP_DMA_MIN_WIDTH 1U | ||
38 | #define XVIP_DMA_MAX_WIDTH 65535U | ||
39 | #define XVIP_DMA_MIN_HEIGHT 1U | ||
40 | #define XVIP_DMA_MAX_HEIGHT 8191U | ||
41 | |||
42 | /* ----------------------------------------------------------------------------- | ||
43 | * Helper functions | ||
44 | */ | ||
45 | |||
46 | static struct v4l2_subdev * | ||
47 | xvip_dma_remote_subdev(struct media_pad *local, u32 *pad) | ||
48 | { | ||
49 | struct media_pad *remote; | ||
50 | |||
51 | remote = media_entity_remote_pad(local); | ||
52 | if (remote == NULL || | ||
53 | media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV) | ||
54 | return NULL; | ||
55 | |||
56 | if (pad) | ||
57 | *pad = remote->index; | ||
58 | |||
59 | return media_entity_to_v4l2_subdev(remote->entity); | ||
60 | } | ||
61 | |||
62 | static int xvip_dma_verify_format(struct xvip_dma *dma) | ||
63 | { | ||
64 | struct v4l2_subdev_format fmt; | ||
65 | struct v4l2_subdev *subdev; | ||
66 | int ret; | ||
67 | |||
68 | subdev = xvip_dma_remote_subdev(&dma->pad, &fmt.pad); | ||
69 | if (subdev == NULL) | ||
70 | return -EPIPE; | ||
71 | |||
72 | fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; | ||
73 | ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt); | ||
74 | if (ret < 0) | ||
75 | return ret == -ENOIOCTLCMD ? -EINVAL : ret; | ||
76 | |||
77 | if (dma->fmtinfo->code != fmt.format.code || | ||
78 | dma->format.height != fmt.format.height || | ||
79 | dma->format.width != fmt.format.width || | ||
80 | dma->format.colorspace != fmt.format.colorspace) | ||
81 | return -EINVAL; | ||
82 | |||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | /* ----------------------------------------------------------------------------- | ||
87 | * Pipeline Stream Management | ||
88 | */ | ||
89 | |||
90 | /** | ||
91 | * xvip_pipeline_start_stop - Start ot stop streaming on a pipeline | ||
92 | * @pipe: The pipeline | ||
93 | * @start: Start (when true) or stop (when false) the pipeline | ||
94 | * | ||
95 | * Walk the entities chain starting at the pipeline output video node and start | ||
96 | * or stop all of them. | ||
97 | * | ||
98 | * Return: 0 if successful, or the return value of the failed video::s_stream | ||
99 | * operation otherwise. | ||
100 | */ | ||
101 | static int xvip_pipeline_start_stop(struct xvip_pipeline *pipe, bool start) | ||
102 | { | ||
103 | struct xvip_dma *dma = pipe->output; | ||
104 | struct media_entity *entity; | ||
105 | struct media_pad *pad; | ||
106 | struct v4l2_subdev *subdev; | ||
107 | int ret; | ||
108 | |||
109 | entity = &dma->video.entity; | ||
110 | while (1) { | ||
111 | pad = &entity->pads[0]; | ||
112 | if (!(pad->flags & MEDIA_PAD_FL_SINK)) | ||
113 | break; | ||
114 | |||
115 | pad = media_entity_remote_pad(pad); | ||
116 | if (pad == NULL || | ||
117 | media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV) | ||
118 | break; | ||
119 | |||
120 | entity = pad->entity; | ||
121 | subdev = media_entity_to_v4l2_subdev(entity); | ||
122 | |||
123 | ret = v4l2_subdev_call(subdev, video, s_stream, start); | ||
124 | if (start && ret < 0 && ret != -ENOIOCTLCMD) | ||
125 | return ret; | ||
126 | } | ||
127 | |||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | /** | ||
132 | * xvip_pipeline_set_stream - Enable/disable streaming on a pipeline | ||
133 | * @pipe: The pipeline | ||
134 | * @on: Turn the stream on when true or off when false | ||
135 | * | ||
136 | * The pipeline is shared between all DMA engines connect at its input and | ||
137 | * output. While the stream state of DMA engines can be controlled | ||
138 | * independently, pipelines have a shared stream state that enable or disable | ||
139 | * all entities in the pipeline. For this reason the pipeline uses a streaming | ||
140 | * counter that tracks the number of DMA engines that have requested the stream | ||
141 | * to be enabled. | ||
142 | * | ||
143 | * When called with the @on argument set to true, this function will increment | ||
144 | * the pipeline streaming count. If the streaming count reaches the number of | ||
145 | * DMA engines in the pipeline it will enable all entities that belong to the | ||
146 | * pipeline. | ||
147 | * | ||
148 | * Similarly, when called with the @on argument set to false, this function will | ||
149 | * decrement the pipeline streaming count and disable all entities in the | ||
150 | * pipeline when the streaming count reaches zero. | ||
151 | * | ||
152 | * Return: 0 if successful, or the return value of the failed video::s_stream | ||
153 | * operation otherwise. Stopping the pipeline never fails. The pipeline state is | ||
154 | * not updated when the operation fails. | ||
155 | */ | ||
156 | static int xvip_pipeline_set_stream(struct xvip_pipeline *pipe, bool on) | ||
157 | { | ||
158 | int ret = 0; | ||
159 | |||
160 | mutex_lock(&pipe->lock); | ||
161 | |||
162 | if (on) { | ||
163 | if (pipe->stream_count == pipe->num_dmas - 1) { | ||
164 | ret = xvip_pipeline_start_stop(pipe, true); | ||
165 | if (ret < 0) | ||
166 | goto done; | ||
167 | } | ||
168 | pipe->stream_count++; | ||
169 | } else { | ||
170 | if (--pipe->stream_count == 0) | ||
171 | xvip_pipeline_start_stop(pipe, false); | ||
172 | } | ||
173 | |||
174 | done: | ||
175 | mutex_unlock(&pipe->lock); | ||
176 | return ret; | ||
177 | } | ||
178 | |||
179 | static int xvip_pipeline_validate(struct xvip_pipeline *pipe, | ||
180 | struct xvip_dma *start) | ||
181 | { | ||
182 | struct media_entity_graph graph; | ||
183 | struct media_entity *entity = &start->video.entity; | ||
184 | struct media_device *mdev = entity->parent; | ||
185 | unsigned int num_inputs = 0; | ||
186 | unsigned int num_outputs = 0; | ||
187 | |||
188 | mutex_lock(&mdev->graph_mutex); | ||
189 | |||
190 | /* Walk the graph to locate the video nodes. */ | ||
191 | media_entity_graph_walk_start(&graph, entity); | ||
192 | |||
193 | while ((entity = media_entity_graph_walk_next(&graph))) { | ||
194 | struct xvip_dma *dma; | ||
195 | |||
196 | if (entity->type != MEDIA_ENT_T_DEVNODE_V4L) | ||
197 | continue; | ||
198 | |||
199 | dma = to_xvip_dma(media_entity_to_video_device(entity)); | ||
200 | |||
201 | if (dma->pad.flags & MEDIA_PAD_FL_SINK) { | ||
202 | pipe->output = dma; | ||
203 | num_outputs++; | ||
204 | } else { | ||
205 | num_inputs++; | ||
206 | } | ||
207 | } | ||
208 | |||
209 | mutex_unlock(&mdev->graph_mutex); | ||
210 | |||
211 | /* We need exactly one output and zero or one input. */ | ||
212 | if (num_outputs != 1 || num_inputs > 1) | ||
213 | return -EPIPE; | ||
214 | |||
215 | pipe->num_dmas = num_inputs + num_outputs; | ||
216 | |||
217 | return 0; | ||
218 | } | ||
219 | |||
220 | static void __xvip_pipeline_cleanup(struct xvip_pipeline *pipe) | ||
221 | { | ||
222 | pipe->num_dmas = 0; | ||
223 | pipe->output = NULL; | ||
224 | } | ||
225 | |||
226 | /** | ||
227 | * xvip_pipeline_cleanup - Cleanup the pipeline after streaming | ||
228 | * @pipe: the pipeline | ||
229 | * | ||
230 | * Decrease the pipeline use count and clean it up if we were the last user. | ||
231 | */ | ||
232 | static void xvip_pipeline_cleanup(struct xvip_pipeline *pipe) | ||
233 | { | ||
234 | mutex_lock(&pipe->lock); | ||
235 | |||
236 | /* If we're the last user clean up the pipeline. */ | ||
237 | if (--pipe->use_count == 0) | ||
238 | __xvip_pipeline_cleanup(pipe); | ||
239 | |||
240 | mutex_unlock(&pipe->lock); | ||
241 | } | ||
242 | |||
243 | /** | ||
244 | * xvip_pipeline_prepare - Prepare the pipeline for streaming | ||
245 | * @pipe: the pipeline | ||
246 | * @dma: DMA engine at one end of the pipeline | ||
247 | * | ||
248 | * Validate the pipeline if no user exists yet, otherwise just increase the use | ||
249 | * count. | ||
250 | * | ||
251 | * Return: 0 if successful or -EPIPE if the pipeline is not valid. | ||
252 | */ | ||
253 | static int xvip_pipeline_prepare(struct xvip_pipeline *pipe, | ||
254 | struct xvip_dma *dma) | ||
255 | { | ||
256 | int ret; | ||
257 | |||
258 | mutex_lock(&pipe->lock); | ||
259 | |||
260 | /* If we're the first user validate and initialize the pipeline. */ | ||
261 | if (pipe->use_count == 0) { | ||
262 | ret = xvip_pipeline_validate(pipe, dma); | ||
263 | if (ret < 0) { | ||
264 | __xvip_pipeline_cleanup(pipe); | ||
265 | goto done; | ||
266 | } | ||
267 | } | ||
268 | |||
269 | pipe->use_count++; | ||
270 | ret = 0; | ||
271 | |||
272 | done: | ||
273 | mutex_unlock(&pipe->lock); | ||
274 | return ret; | ||
275 | } | ||
276 | |||
277 | /* ----------------------------------------------------------------------------- | ||
278 | * videobuf2 queue operations | ||
279 | */ | ||
280 | |||
281 | /** | ||
282 | * struct xvip_dma_buffer - Video DMA buffer | ||
283 | * @buf: vb2 buffer base object | ||
284 | * @queue: buffer list entry in the DMA engine queued buffers list | ||
285 | * @dma: DMA channel that uses the buffer | ||
286 | */ | ||
287 | struct xvip_dma_buffer { | ||
288 | struct vb2_buffer buf; | ||
289 | struct list_head queue; | ||
290 | struct xvip_dma *dma; | ||
291 | }; | ||
292 | |||
293 | #define to_xvip_dma_buffer(vb) container_of(vb, struct xvip_dma_buffer, buf) | ||
294 | |||
295 | static void xvip_dma_complete(void *param) | ||
296 | { | ||
297 | struct xvip_dma_buffer *buf = param; | ||
298 | struct xvip_dma *dma = buf->dma; | ||
299 | |||
300 | spin_lock(&dma->queued_lock); | ||
301 | list_del(&buf->queue); | ||
302 | spin_unlock(&dma->queued_lock); | ||
303 | |||
304 | buf->buf.v4l2_buf.field = V4L2_FIELD_NONE; | ||
305 | buf->buf.v4l2_buf.sequence = dma->sequence++; | ||
306 | v4l2_get_timestamp(&buf->buf.v4l2_buf.timestamp); | ||
307 | vb2_set_plane_payload(&buf->buf, 0, dma->format.sizeimage); | ||
308 | vb2_buffer_done(&buf->buf, VB2_BUF_STATE_DONE); | ||
309 | } | ||
310 | |||
311 | static int | ||
312 | xvip_dma_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, | ||
313 | unsigned int *nbuffers, unsigned int *nplanes, | ||
314 | unsigned int sizes[], void *alloc_ctxs[]) | ||
315 | { | ||
316 | struct xvip_dma *dma = vb2_get_drv_priv(vq); | ||
317 | |||
318 | /* Make sure the image size is large enough. */ | ||
319 | if (fmt && fmt->fmt.pix.sizeimage < dma->format.sizeimage) | ||
320 | return -EINVAL; | ||
321 | |||
322 | *nplanes = 1; | ||
323 | |||
324 | sizes[0] = fmt ? fmt->fmt.pix.sizeimage : dma->format.sizeimage; | ||
325 | alloc_ctxs[0] = dma->alloc_ctx; | ||
326 | |||
327 | return 0; | ||
328 | } | ||
329 | |||
330 | static int xvip_dma_buffer_prepare(struct vb2_buffer *vb) | ||
331 | { | ||
332 | struct xvip_dma *dma = vb2_get_drv_priv(vb->vb2_queue); | ||
333 | struct xvip_dma_buffer *buf = to_xvip_dma_buffer(vb); | ||
334 | |||
335 | buf->dma = dma; | ||
336 | |||
337 | return 0; | ||
338 | } | ||
339 | |||
340 | static void xvip_dma_buffer_queue(struct vb2_buffer *vb) | ||
341 | { | ||
342 | struct xvip_dma *dma = vb2_get_drv_priv(vb->vb2_queue); | ||
343 | struct xvip_dma_buffer *buf = to_xvip_dma_buffer(vb); | ||
344 | struct dma_async_tx_descriptor *desc; | ||
345 | dma_addr_t addr = vb2_dma_contig_plane_dma_addr(vb, 0); | ||
346 | u32 flags; | ||
347 | |||
348 | if (dma->queue.type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
349 | flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK; | ||
350 | dma->xt.dir = DMA_DEV_TO_MEM; | ||
351 | dma->xt.src_sgl = false; | ||
352 | dma->xt.dst_sgl = true; | ||
353 | dma->xt.dst_start = addr; | ||
354 | } else { | ||
355 | flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK; | ||
356 | dma->xt.dir = DMA_MEM_TO_DEV; | ||
357 | dma->xt.src_sgl = true; | ||
358 | dma->xt.dst_sgl = false; | ||
359 | dma->xt.src_start = addr; | ||
360 | } | ||
361 | |||
362 | dma->xt.frame_size = 1; | ||
363 | dma->sgl[0].size = dma->format.width * dma->fmtinfo->bpp; | ||
364 | dma->sgl[0].icg = dma->format.bytesperline - dma->sgl[0].size; | ||
365 | dma->xt.numf = dma->format.height; | ||
366 | |||
367 | desc = dmaengine_prep_interleaved_dma(dma->dma, &dma->xt, flags); | ||
368 | if (!desc) { | ||
369 | dev_err(dma->xdev->dev, "Failed to prepare DMA transfer\n"); | ||
370 | vb2_buffer_done(&buf->buf, VB2_BUF_STATE_ERROR); | ||
371 | return; | ||
372 | } | ||
373 | desc->callback = xvip_dma_complete; | ||
374 | desc->callback_param = buf; | ||
375 | |||
376 | spin_lock_irq(&dma->queued_lock); | ||
377 | list_add_tail(&buf->queue, &dma->queued_bufs); | ||
378 | spin_unlock_irq(&dma->queued_lock); | ||
379 | |||
380 | dmaengine_submit(desc); | ||
381 | |||
382 | if (vb2_is_streaming(&dma->queue)) | ||
383 | dma_async_issue_pending(dma->dma); | ||
384 | } | ||
385 | |||
386 | static int xvip_dma_start_streaming(struct vb2_queue *vq, unsigned int count) | ||
387 | { | ||
388 | struct xvip_dma *dma = vb2_get_drv_priv(vq); | ||
389 | struct xvip_dma_buffer *buf, *nbuf; | ||
390 | struct xvip_pipeline *pipe; | ||
391 | int ret; | ||
392 | |||
393 | dma->sequence = 0; | ||
394 | |||
395 | /* | ||
396 | * Start streaming on the pipeline. No link touching an entity in the | ||
397 | * pipeline can be activated or deactivated once streaming is started. | ||
398 | * | ||
399 | * Use the pipeline object embedded in the first DMA object that starts | ||
400 | * streaming. | ||
401 | */ | ||
402 | pipe = dma->video.entity.pipe | ||
403 | ? to_xvip_pipeline(&dma->video.entity) : &dma->pipe; | ||
404 | |||
405 | ret = media_entity_pipeline_start(&dma->video.entity, &pipe->pipe); | ||
406 | if (ret < 0) | ||
407 | goto error; | ||
408 | |||
409 | /* Verify that the configured format matches the output of the | ||
410 | * connected subdev. | ||
411 | */ | ||
412 | ret = xvip_dma_verify_format(dma); | ||
413 | if (ret < 0) | ||
414 | goto error_stop; | ||
415 | |||
416 | ret = xvip_pipeline_prepare(pipe, dma); | ||
417 | if (ret < 0) | ||
418 | goto error_stop; | ||
419 | |||
420 | /* Start the DMA engine. This must be done before starting the blocks | ||
421 | * in the pipeline to avoid DMA synchronization issues. | ||
422 | */ | ||
423 | dma_async_issue_pending(dma->dma); | ||
424 | |||
425 | /* Start the pipeline. */ | ||
426 | xvip_pipeline_set_stream(pipe, true); | ||
427 | |||
428 | return 0; | ||
429 | |||
430 | error_stop: | ||
431 | media_entity_pipeline_stop(&dma->video.entity); | ||
432 | |||
433 | error: | ||
434 | /* Give back all queued buffers to videobuf2. */ | ||
435 | spin_lock_irq(&dma->queued_lock); | ||
436 | list_for_each_entry_safe(buf, nbuf, &dma->queued_bufs, queue) { | ||
437 | vb2_buffer_done(&buf->buf, VB2_BUF_STATE_QUEUED); | ||
438 | list_del(&buf->queue); | ||
439 | } | ||
440 | spin_unlock_irq(&dma->queued_lock); | ||
441 | |||
442 | return ret; | ||
443 | } | ||
444 | |||
445 | static void xvip_dma_stop_streaming(struct vb2_queue *vq) | ||
446 | { | ||
447 | struct xvip_dma *dma = vb2_get_drv_priv(vq); | ||
448 | struct xvip_pipeline *pipe = to_xvip_pipeline(&dma->video.entity); | ||
449 | struct xvip_dma_buffer *buf, *nbuf; | ||
450 | |||
451 | /* Stop the pipeline. */ | ||
452 | xvip_pipeline_set_stream(pipe, false); | ||
453 | |||
454 | /* Stop and reset the DMA engine. */ | ||
455 | dmaengine_terminate_all(dma->dma); | ||
456 | |||
457 | /* Cleanup the pipeline and mark it as being stopped. */ | ||
458 | xvip_pipeline_cleanup(pipe); | ||
459 | media_entity_pipeline_stop(&dma->video.entity); | ||
460 | |||
461 | /* Give back all queued buffers to videobuf2. */ | ||
462 | spin_lock_irq(&dma->queued_lock); | ||
463 | list_for_each_entry_safe(buf, nbuf, &dma->queued_bufs, queue) { | ||
464 | vb2_buffer_done(&buf->buf, VB2_BUF_STATE_ERROR); | ||
465 | list_del(&buf->queue); | ||
466 | } | ||
467 | spin_unlock_irq(&dma->queued_lock); | ||
468 | } | ||
469 | |||
470 | static struct vb2_ops xvip_dma_queue_qops = { | ||
471 | .queue_setup = xvip_dma_queue_setup, | ||
472 | .buf_prepare = xvip_dma_buffer_prepare, | ||
473 | .buf_queue = xvip_dma_buffer_queue, | ||
474 | .wait_prepare = vb2_ops_wait_prepare, | ||
475 | .wait_finish = vb2_ops_wait_finish, | ||
476 | .start_streaming = xvip_dma_start_streaming, | ||
477 | .stop_streaming = xvip_dma_stop_streaming, | ||
478 | }; | ||
479 | |||
480 | /* ----------------------------------------------------------------------------- | ||
481 | * V4L2 ioctls | ||
482 | */ | ||
483 | |||
484 | static int | ||
485 | xvip_dma_querycap(struct file *file, void *fh, struct v4l2_capability *cap) | ||
486 | { | ||
487 | struct v4l2_fh *vfh = file->private_data; | ||
488 | struct xvip_dma *dma = to_xvip_dma(vfh->vdev); | ||
489 | |||
490 | cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING | ||
491 | | dma->xdev->v4l2_caps; | ||
492 | |||
493 | if (dma->queue.type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
494 | cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; | ||
495 | else | ||
496 | cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; | ||
497 | |||
498 | strlcpy(cap->driver, "xilinx-vipp", sizeof(cap->driver)); | ||
499 | strlcpy(cap->card, dma->video.name, sizeof(cap->card)); | ||
500 | snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s:%u", | ||
501 | dma->xdev->dev->of_node->name, dma->port); | ||
502 | |||
503 | return 0; | ||
504 | } | ||
505 | |||
506 | /* FIXME: without this callback function, some applications are not configured | ||
507 | * with correct formats, and it results in frames in wrong format. Whether this | ||
508 | * callback needs to be required is not clearly defined, so it should be | ||
509 | * clarified through the mailing list. | ||
510 | */ | ||
511 | static int | ||
512 | xvip_dma_enum_format(struct file *file, void *fh, struct v4l2_fmtdesc *f) | ||
513 | { | ||
514 | struct v4l2_fh *vfh = file->private_data; | ||
515 | struct xvip_dma *dma = to_xvip_dma(vfh->vdev); | ||
516 | |||
517 | if (f->index > 0) | ||
518 | return -EINVAL; | ||
519 | |||
520 | f->pixelformat = dma->format.pixelformat; | ||
521 | strlcpy(f->description, dma->fmtinfo->description, | ||
522 | sizeof(f->description)); | ||
523 | |||
524 | return 0; | ||
525 | } | ||
526 | |||
527 | static int | ||
528 | xvip_dma_get_format(struct file *file, void *fh, struct v4l2_format *format) | ||
529 | { | ||
530 | struct v4l2_fh *vfh = file->private_data; | ||
531 | struct xvip_dma *dma = to_xvip_dma(vfh->vdev); | ||
532 | |||
533 | format->fmt.pix = dma->format; | ||
534 | |||
535 | return 0; | ||
536 | } | ||
537 | |||
538 | static void | ||
539 | __xvip_dma_try_format(struct xvip_dma *dma, struct v4l2_pix_format *pix, | ||
540 | const struct xvip_video_format **fmtinfo) | ||
541 | { | ||
542 | const struct xvip_video_format *info; | ||
543 | unsigned int min_width; | ||
544 | unsigned int max_width; | ||
545 | unsigned int min_bpl; | ||
546 | unsigned int max_bpl; | ||
547 | unsigned int width; | ||
548 | unsigned int align; | ||
549 | unsigned int bpl; | ||
550 | |||
551 | /* Retrieve format information and select the default format if the | ||
552 | * requested format isn't supported. | ||
553 | */ | ||
554 | info = xvip_get_format_by_fourcc(pix->pixelformat); | ||
555 | if (IS_ERR(info)) | ||
556 | info = xvip_get_format_by_fourcc(XVIP_DMA_DEF_FORMAT); | ||
557 | |||
558 | pix->pixelformat = info->fourcc; | ||
559 | pix->field = V4L2_FIELD_NONE; | ||
560 | |||
561 | /* The transfer alignment requirements are expressed in bytes. Compute | ||
562 | * the minimum and maximum values, clamp the requested width and convert | ||
563 | * it back to pixels. | ||
564 | */ | ||
565 | align = lcm(dma->align, info->bpp); | ||
566 | min_width = roundup(XVIP_DMA_MIN_WIDTH, align); | ||
567 | max_width = rounddown(XVIP_DMA_MAX_WIDTH, align); | ||
568 | width = rounddown(pix->width * info->bpp, align); | ||
569 | |||
570 | pix->width = clamp(width, min_width, max_width) / info->bpp; | ||
571 | pix->height = clamp(pix->height, XVIP_DMA_MIN_HEIGHT, | ||
572 | XVIP_DMA_MAX_HEIGHT); | ||
573 | |||
574 | /* Clamp the requested bytes per line value. If the maximum bytes per | ||
575 | * line value is zero, the module doesn't support user configurable line | ||
576 | * sizes. Override the requested value with the minimum in that case. | ||
577 | */ | ||
578 | min_bpl = pix->width * info->bpp; | ||
579 | max_bpl = rounddown(XVIP_DMA_MAX_WIDTH, dma->align); | ||
580 | bpl = rounddown(pix->bytesperline, dma->align); | ||
581 | |||
582 | pix->bytesperline = clamp(bpl, min_bpl, max_bpl); | ||
583 | pix->sizeimage = pix->bytesperline * pix->height; | ||
584 | |||
585 | if (fmtinfo) | ||
586 | *fmtinfo = info; | ||
587 | } | ||
588 | |||
589 | static int | ||
590 | xvip_dma_try_format(struct file *file, void *fh, struct v4l2_format *format) | ||
591 | { | ||
592 | struct v4l2_fh *vfh = file->private_data; | ||
593 | struct xvip_dma *dma = to_xvip_dma(vfh->vdev); | ||
594 | |||
595 | __xvip_dma_try_format(dma, &format->fmt.pix, NULL); | ||
596 | return 0; | ||
597 | } | ||
598 | |||
599 | static int | ||
600 | xvip_dma_set_format(struct file *file, void *fh, struct v4l2_format *format) | ||
601 | { | ||
602 | struct v4l2_fh *vfh = file->private_data; | ||
603 | struct xvip_dma *dma = to_xvip_dma(vfh->vdev); | ||
604 | const struct xvip_video_format *info; | ||
605 | |||
606 | __xvip_dma_try_format(dma, &format->fmt.pix, &info); | ||
607 | |||
608 | if (vb2_is_busy(&dma->queue)) | ||
609 | return -EBUSY; | ||
610 | |||
611 | dma->format = format->fmt.pix; | ||
612 | dma->fmtinfo = info; | ||
613 | |||
614 | return 0; | ||
615 | } | ||
616 | |||
617 | static const struct v4l2_ioctl_ops xvip_dma_ioctl_ops = { | ||
618 | .vidioc_querycap = xvip_dma_querycap, | ||
619 | .vidioc_enum_fmt_vid_cap = xvip_dma_enum_format, | ||
620 | .vidioc_g_fmt_vid_cap = xvip_dma_get_format, | ||
621 | .vidioc_g_fmt_vid_out = xvip_dma_get_format, | ||
622 | .vidioc_s_fmt_vid_cap = xvip_dma_set_format, | ||
623 | .vidioc_s_fmt_vid_out = xvip_dma_set_format, | ||
624 | .vidioc_try_fmt_vid_cap = xvip_dma_try_format, | ||
625 | .vidioc_try_fmt_vid_out = xvip_dma_try_format, | ||
626 | .vidioc_reqbufs = vb2_ioctl_reqbufs, | ||
627 | .vidioc_querybuf = vb2_ioctl_querybuf, | ||
628 | .vidioc_qbuf = vb2_ioctl_qbuf, | ||
629 | .vidioc_dqbuf = vb2_ioctl_dqbuf, | ||
630 | .vidioc_create_bufs = vb2_ioctl_create_bufs, | ||
631 | .vidioc_expbuf = vb2_ioctl_expbuf, | ||
632 | .vidioc_streamon = vb2_ioctl_streamon, | ||
633 | .vidioc_streamoff = vb2_ioctl_streamoff, | ||
634 | }; | ||
635 | |||
636 | /* ----------------------------------------------------------------------------- | ||
637 | * V4L2 file operations | ||
638 | */ | ||
639 | |||
640 | static const struct v4l2_file_operations xvip_dma_fops = { | ||
641 | .owner = THIS_MODULE, | ||
642 | .unlocked_ioctl = video_ioctl2, | ||
643 | .open = v4l2_fh_open, | ||
644 | .release = vb2_fop_release, | ||
645 | .poll = vb2_fop_poll, | ||
646 | .mmap = vb2_fop_mmap, | ||
647 | }; | ||
648 | |||
649 | /* ----------------------------------------------------------------------------- | ||
650 | * Xilinx Video DMA Core | ||
651 | */ | ||
652 | |||
653 | int xvip_dma_init(struct xvip_composite_device *xdev, struct xvip_dma *dma, | ||
654 | enum v4l2_buf_type type, unsigned int port) | ||
655 | { | ||
656 | char name[14]; | ||
657 | int ret; | ||
658 | |||
659 | dma->xdev = xdev; | ||
660 | dma->port = port; | ||
661 | mutex_init(&dma->lock); | ||
662 | mutex_init(&dma->pipe.lock); | ||
663 | INIT_LIST_HEAD(&dma->queued_bufs); | ||
664 | spin_lock_init(&dma->queued_lock); | ||
665 | |||
666 | dma->fmtinfo = xvip_get_format_by_fourcc(XVIP_DMA_DEF_FORMAT); | ||
667 | dma->format.pixelformat = dma->fmtinfo->fourcc; | ||
668 | dma->format.colorspace = V4L2_COLORSPACE_SRGB; | ||
669 | dma->format.field = V4L2_FIELD_NONE; | ||
670 | dma->format.width = XVIP_DMA_DEF_WIDTH; | ||
671 | dma->format.height = XVIP_DMA_DEF_HEIGHT; | ||
672 | dma->format.bytesperline = dma->format.width * dma->fmtinfo->bpp; | ||
673 | dma->format.sizeimage = dma->format.bytesperline * dma->format.height; | ||
674 | |||
675 | /* Initialize the media entity... */ | ||
676 | dma->pad.flags = type == V4L2_BUF_TYPE_VIDEO_CAPTURE | ||
677 | ? MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE; | ||
678 | |||
679 | ret = media_entity_init(&dma->video.entity, 1, &dma->pad, 0); | ||
680 | if (ret < 0) | ||
681 | goto error; | ||
682 | |||
683 | /* ... and the video node... */ | ||
684 | dma->video.fops = &xvip_dma_fops; | ||
685 | dma->video.v4l2_dev = &xdev->v4l2_dev; | ||
686 | dma->video.queue = &dma->queue; | ||
687 | snprintf(dma->video.name, sizeof(dma->video.name), "%s %s %u", | ||
688 | xdev->dev->of_node->name, | ||
689 | type == V4L2_BUF_TYPE_VIDEO_CAPTURE ? "output" : "input", | ||
690 | port); | ||
691 | dma->video.vfl_type = VFL_TYPE_GRABBER; | ||
692 | dma->video.vfl_dir = type == V4L2_BUF_TYPE_VIDEO_CAPTURE | ||
693 | ? VFL_DIR_RX : VFL_DIR_TX; | ||
694 | dma->video.release = video_device_release_empty; | ||
695 | dma->video.ioctl_ops = &xvip_dma_ioctl_ops; | ||
696 | dma->video.lock = &dma->lock; | ||
697 | |||
698 | video_set_drvdata(&dma->video, dma); | ||
699 | |||
700 | /* ... and the buffers queue... */ | ||
701 | dma->alloc_ctx = vb2_dma_contig_init_ctx(dma->xdev->dev); | ||
702 | if (IS_ERR(dma->alloc_ctx)) | ||
703 | goto error; | ||
704 | |||
705 | /* Don't enable VB2_READ and VB2_WRITE, as using the read() and write() | ||
706 | * V4L2 APIs would be inefficient. Testing on the command line with a | ||
707 | * 'cat /dev/video?' thus won't be possible, but given that the driver | ||
708 | * anyway requires a test tool to setup the pipeline before any video | ||
709 | * stream can be started, requiring a specific V4L2 test tool as well | ||
710 | * instead of 'cat' isn't really a drawback. | ||
711 | */ | ||
712 | dma->queue.type = type; | ||
713 | dma->queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; | ||
714 | dma->queue.lock = &dma->lock; | ||
715 | dma->queue.drv_priv = dma; | ||
716 | dma->queue.buf_struct_size = sizeof(struct xvip_dma_buffer); | ||
717 | dma->queue.ops = &xvip_dma_queue_qops; | ||
718 | dma->queue.mem_ops = &vb2_dma_contig_memops; | ||
719 | dma->queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC | ||
720 | | V4L2_BUF_FLAG_TSTAMP_SRC_EOF; | ||
721 | ret = vb2_queue_init(&dma->queue); | ||
722 | if (ret < 0) { | ||
723 | dev_err(dma->xdev->dev, "failed to initialize VB2 queue\n"); | ||
724 | goto error; | ||
725 | } | ||
726 | |||
727 | /* ... and the DMA channel. */ | ||
728 | sprintf(name, "port%u", port); | ||
729 | dma->dma = dma_request_slave_channel(dma->xdev->dev, name); | ||
730 | if (dma->dma == NULL) { | ||
731 | dev_err(dma->xdev->dev, "no VDMA channel found\n"); | ||
732 | ret = -ENODEV; | ||
733 | goto error; | ||
734 | } | ||
735 | |||
736 | dma->align = 1 << dma->dma->device->copy_align; | ||
737 | |||
738 | ret = video_register_device(&dma->video, VFL_TYPE_GRABBER, -1); | ||
739 | if (ret < 0) { | ||
740 | dev_err(dma->xdev->dev, "failed to register video device\n"); | ||
741 | goto error; | ||
742 | } | ||
743 | |||
744 | return 0; | ||
745 | |||
746 | error: | ||
747 | xvip_dma_cleanup(dma); | ||
748 | return ret; | ||
749 | } | ||
750 | |||
751 | void xvip_dma_cleanup(struct xvip_dma *dma) | ||
752 | { | ||
753 | if (video_is_registered(&dma->video)) | ||
754 | video_unregister_device(&dma->video); | ||
755 | |||
756 | if (dma->dma) | ||
757 | dma_release_channel(dma->dma); | ||
758 | |||
759 | if (!IS_ERR_OR_NULL(dma->alloc_ctx)) | ||
760 | vb2_dma_contig_cleanup_ctx(dma->alloc_ctx); | ||
761 | |||
762 | media_entity_cleanup(&dma->video.entity); | ||
763 | |||
764 | mutex_destroy(&dma->lock); | ||
765 | mutex_destroy(&dma->pipe.lock); | ||
766 | } | ||
diff --git a/drivers/media/platform/xilinx/xilinx-dma.h b/drivers/media/platform/xilinx/xilinx-dma.h new file mode 100644 index 000000000000..a540111f8d3d --- /dev/null +++ b/drivers/media/platform/xilinx/xilinx-dma.h | |||
@@ -0,0 +1,109 @@ | |||
1 | /* | ||
2 | * Xilinx Video DMA | ||
3 | * | ||
4 | * Copyright (C) 2013-2015 Ideas on Board | ||
5 | * Copyright (C) 2013-2015 Xilinx, Inc. | ||
6 | * | ||
7 | * Contacts: Hyun Kwon <hyun.kwon@xilinx.com> | ||
8 | * Laurent Pinchart <laurent.pinchart@ideasonboard.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #ifndef __XILINX_VIP_DMA_H__ | ||
16 | #define __XILINX_VIP_DMA_H__ | ||
17 | |||
18 | #include <linux/dmaengine.h> | ||
19 | #include <linux/mutex.h> | ||
20 | #include <linux/spinlock.h> | ||
21 | #include <linux/videodev2.h> | ||
22 | |||
23 | #include <media/media-entity.h> | ||
24 | #include <media/v4l2-dev.h> | ||
25 | #include <media/videobuf2-core.h> | ||
26 | |||
27 | struct dma_chan; | ||
28 | struct xvip_composite_device; | ||
29 | struct xvip_video_format; | ||
30 | |||
31 | /** | ||
32 | * struct xvip_pipeline - Xilinx Video IP pipeline structure | ||
33 | * @pipe: media pipeline | ||
34 | * @lock: protects the pipeline @stream_count | ||
35 | * @use_count: number of DMA engines using the pipeline | ||
36 | * @stream_count: number of DMA engines currently streaming | ||
37 | * @num_dmas: number of DMA engines in the pipeline | ||
38 | * @output: DMA engine at the output of the pipeline | ||
39 | */ | ||
40 | struct xvip_pipeline { | ||
41 | struct media_pipeline pipe; | ||
42 | |||
43 | struct mutex lock; | ||
44 | unsigned int use_count; | ||
45 | unsigned int stream_count; | ||
46 | |||
47 | unsigned int num_dmas; | ||
48 | struct xvip_dma *output; | ||
49 | }; | ||
50 | |||
51 | static inline struct xvip_pipeline *to_xvip_pipeline(struct media_entity *e) | ||
52 | { | ||
53 | return container_of(e->pipe, struct xvip_pipeline, pipe); | ||
54 | } | ||
55 | |||
56 | /** | ||
57 | * struct xvip_dma - Video DMA channel | ||
58 | * @list: list entry in a composite device dmas list | ||
59 | * @video: V4L2 video device associated with the DMA channel | ||
60 | * @pad: media pad for the video device entity | ||
61 | * @xdev: composite device the DMA channel belongs to | ||
62 | * @pipe: pipeline belonging to the DMA channel | ||
63 | * @port: composite device DT node port number for the DMA channel | ||
64 | * @lock: protects the @format, @fmtinfo and @queue fields | ||
65 | * @format: active V4L2 pixel format | ||
66 | * @fmtinfo: format information corresponding to the active @format | ||
67 | * @queue: vb2 buffers queue | ||
68 | * @alloc_ctx: allocation context for the vb2 @queue | ||
69 | * @sequence: V4L2 buffers sequence number | ||
70 | * @queued_bufs: list of queued buffers | ||
71 | * @queued_lock: protects the buf_queued list | ||
72 | * @dma: DMA engine channel | ||
73 | * @align: transfer alignment required by the DMA channel (in bytes) | ||
74 | * @xt: dma interleaved template for dma configuration | ||
75 | * @sgl: data chunk structure for dma_interleaved_template | ||
76 | */ | ||
77 | struct xvip_dma { | ||
78 | struct list_head list; | ||
79 | struct video_device video; | ||
80 | struct media_pad pad; | ||
81 | |||
82 | struct xvip_composite_device *xdev; | ||
83 | struct xvip_pipeline pipe; | ||
84 | unsigned int port; | ||
85 | |||
86 | struct mutex lock; | ||
87 | struct v4l2_pix_format format; | ||
88 | const struct xvip_video_format *fmtinfo; | ||
89 | |||
90 | struct vb2_queue queue; | ||
91 | void *alloc_ctx; | ||
92 | unsigned int sequence; | ||
93 | |||
94 | struct list_head queued_bufs; | ||
95 | spinlock_t queued_lock; | ||
96 | |||
97 | struct dma_chan *dma; | ||
98 | unsigned int align; | ||
99 | struct dma_interleaved_template xt; | ||
100 | struct data_chunk sgl[1]; | ||
101 | }; | ||
102 | |||
103 | #define to_xvip_dma(vdev) container_of(vdev, struct xvip_dma, video) | ||
104 | |||
105 | int xvip_dma_init(struct xvip_composite_device *xdev, struct xvip_dma *dma, | ||
106 | enum v4l2_buf_type type, unsigned int port); | ||
107 | void xvip_dma_cleanup(struct xvip_dma *dma); | ||
108 | |||
109 | #endif /* __XILINX_VIP_DMA_H__ */ | ||
diff --git a/drivers/media/platform/xilinx/xilinx-tpg.c b/drivers/media/platform/xilinx/xilinx-tpg.c new file mode 100644 index 000000000000..b5f7d5ecb7f6 --- /dev/null +++ b/drivers/media/platform/xilinx/xilinx-tpg.c | |||
@@ -0,0 +1,931 @@ | |||
1 | /* | ||
2 | * Xilinx Test Pattern Generator | ||
3 | * | ||
4 | * Copyright (C) 2013-2015 Ideas on Board | ||
5 | * Copyright (C) 2013-2015 Xilinx, Inc. | ||
6 | * | ||
7 | * Contacts: Hyun Kwon <hyun.kwon@xilinx.com> | ||
8 | * Laurent Pinchart <laurent.pinchart@ideasonboard.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include <linux/device.h> | ||
16 | #include <linux/gpio/consumer.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/of.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/xilinx-v4l2-controls.h> | ||
21 | |||
22 | #include <media/v4l2-async.h> | ||
23 | #include <media/v4l2-ctrls.h> | ||
24 | #include <media/v4l2-subdev.h> | ||
25 | |||
26 | #include "xilinx-vip.h" | ||
27 | #include "xilinx-vtc.h" | ||
28 | |||
29 | #define XTPG_CTRL_STATUS_SLAVE_ERROR (1 << 16) | ||
30 | #define XTPG_CTRL_IRQ_SLAVE_ERROR (1 << 16) | ||
31 | |||
32 | #define XTPG_PATTERN_CONTROL 0x0100 | ||
33 | #define XTPG_PATTERN_MASK (0xf << 0) | ||
34 | #define XTPG_PATTERN_CONTROL_CROSS_HAIRS (1 << 4) | ||
35 | #define XTPG_PATTERN_CONTROL_MOVING_BOX (1 << 5) | ||
36 | #define XTPG_PATTERN_CONTROL_COLOR_MASK_SHIFT 6 | ||
37 | #define XTPG_PATTERN_CONTROL_COLOR_MASK_MASK (0xf << 6) | ||
38 | #define XTPG_PATTERN_CONTROL_STUCK_PIXEL (1 << 9) | ||
39 | #define XTPG_PATTERN_CONTROL_NOISE (1 << 10) | ||
40 | #define XTPG_PATTERN_CONTROL_MOTION (1 << 12) | ||
41 | #define XTPG_MOTION_SPEED 0x0104 | ||
42 | #define XTPG_CROSS_HAIRS 0x0108 | ||
43 | #define XTPG_CROSS_HAIRS_ROW_SHIFT 0 | ||
44 | #define XTPG_CROSS_HAIRS_ROW_MASK (0xfff << 0) | ||
45 | #define XTPG_CROSS_HAIRS_COLUMN_SHIFT 16 | ||
46 | #define XTPG_CROSS_HAIRS_COLUMN_MASK (0xfff << 16) | ||
47 | #define XTPG_ZPLATE_HOR_CONTROL 0x010c | ||
48 | #define XTPG_ZPLATE_VER_CONTROL 0x0110 | ||
49 | #define XTPG_ZPLATE_START_SHIFT 0 | ||
50 | #define XTPG_ZPLATE_START_MASK (0xffff << 0) | ||
51 | #define XTPG_ZPLATE_SPEED_SHIFT 16 | ||
52 | #define XTPG_ZPLATE_SPEED_MASK (0xffff << 16) | ||
53 | #define XTPG_BOX_SIZE 0x0114 | ||
54 | #define XTPG_BOX_COLOR 0x0118 | ||
55 | #define XTPG_STUCK_PIXEL_THRESH 0x011c | ||
56 | #define XTPG_NOISE_GAIN 0x0120 | ||
57 | #define XTPG_BAYER_PHASE 0x0124 | ||
58 | #define XTPG_BAYER_PHASE_RGGB 0 | ||
59 | #define XTPG_BAYER_PHASE_GRBG 1 | ||
60 | #define XTPG_BAYER_PHASE_GBRG 2 | ||
61 | #define XTPG_BAYER_PHASE_BGGR 3 | ||
62 | #define XTPG_BAYER_PHASE_OFF 4 | ||
63 | |||
64 | /* | ||
65 | * The minimum blanking value is one clock cycle for the front porch, one clock | ||
66 | * cycle for the sync pulse and one clock cycle for the back porch. | ||
67 | */ | ||
68 | #define XTPG_MIN_HBLANK 3 | ||
69 | #define XTPG_MAX_HBLANK (XVTC_MAX_HSIZE - XVIP_MIN_WIDTH) | ||
70 | #define XTPG_MIN_VBLANK 3 | ||
71 | #define XTPG_MAX_VBLANK (XVTC_MAX_VSIZE - XVIP_MIN_HEIGHT) | ||
72 | |||
73 | /** | ||
74 | * struct xtpg_device - Xilinx Test Pattern Generator device structure | ||
75 | * @xvip: Xilinx Video IP device | ||
76 | * @pads: media pads | ||
77 | * @npads: number of pads (1 or 2) | ||
78 | * @has_input: whether an input is connected to the sink pad | ||
79 | * @formats: active V4L2 media bus format for each pad | ||
80 | * @default_format: default V4L2 media bus format | ||
81 | * @vip_format: format information corresponding to the active format | ||
82 | * @bayer: boolean flag if TPG is set to any bayer format | ||
83 | * @ctrl_handler: control handler | ||
84 | * @hblank: horizontal blanking control | ||
85 | * @vblank: vertical blanking control | ||
86 | * @pattern: test pattern control | ||
87 | * @streaming: is the video stream active | ||
88 | * @vtc: video timing controller | ||
89 | * @vtmux_gpio: video timing mux GPIO | ||
90 | */ | ||
91 | struct xtpg_device { | ||
92 | struct xvip_device xvip; | ||
93 | |||
94 | struct media_pad pads[2]; | ||
95 | unsigned int npads; | ||
96 | bool has_input; | ||
97 | |||
98 | struct v4l2_mbus_framefmt formats[2]; | ||
99 | struct v4l2_mbus_framefmt default_format; | ||
100 | const struct xvip_video_format *vip_format; | ||
101 | bool bayer; | ||
102 | |||
103 | struct v4l2_ctrl_handler ctrl_handler; | ||
104 | struct v4l2_ctrl *hblank; | ||
105 | struct v4l2_ctrl *vblank; | ||
106 | struct v4l2_ctrl *pattern; | ||
107 | bool streaming; | ||
108 | |||
109 | struct xvtc_device *vtc; | ||
110 | struct gpio_desc *vtmux_gpio; | ||
111 | }; | ||
112 | |||
113 | static inline struct xtpg_device *to_tpg(struct v4l2_subdev *subdev) | ||
114 | { | ||
115 | return container_of(subdev, struct xtpg_device, xvip.subdev); | ||
116 | } | ||
117 | |||
118 | static u32 xtpg_get_bayer_phase(unsigned int code) | ||
119 | { | ||
120 | switch (code) { | ||
121 | case MEDIA_BUS_FMT_SRGGB8_1X8: | ||
122 | return XTPG_BAYER_PHASE_RGGB; | ||
123 | case MEDIA_BUS_FMT_SGRBG8_1X8: | ||
124 | return XTPG_BAYER_PHASE_GRBG; | ||
125 | case MEDIA_BUS_FMT_SGBRG8_1X8: | ||
126 | return XTPG_BAYER_PHASE_GBRG; | ||
127 | case MEDIA_BUS_FMT_SBGGR8_1X8: | ||
128 | return XTPG_BAYER_PHASE_BGGR; | ||
129 | default: | ||
130 | return XTPG_BAYER_PHASE_OFF; | ||
131 | } | ||
132 | } | ||
133 | |||
134 | static void __xtpg_update_pattern_control(struct xtpg_device *xtpg, | ||
135 | bool passthrough, bool pattern) | ||
136 | { | ||
137 | u32 pattern_mask = (1 << (xtpg->pattern->maximum + 1)) - 1; | ||
138 | |||
139 | /* | ||
140 | * If the TPG has no sink pad or no input connected to its sink pad | ||
141 | * passthrough mode can't be enabled. | ||
142 | */ | ||
143 | if (xtpg->npads == 1 || !xtpg->has_input) | ||
144 | passthrough = false; | ||
145 | |||
146 | /* If passthrough mode is allowed unmask bit 0. */ | ||
147 | if (passthrough) | ||
148 | pattern_mask &= ~1; | ||
149 | |||
150 | /* If test pattern mode is allowed unmask all other bits. */ | ||
151 | if (pattern) | ||
152 | pattern_mask &= 1; | ||
153 | |||
154 | __v4l2_ctrl_modify_range(xtpg->pattern, 0, xtpg->pattern->maximum, | ||
155 | pattern_mask, pattern ? 9 : 0); | ||
156 | } | ||
157 | |||
158 | static void xtpg_update_pattern_control(struct xtpg_device *xtpg, | ||
159 | bool passthrough, bool pattern) | ||
160 | { | ||
161 | mutex_lock(xtpg->ctrl_handler.lock); | ||
162 | __xtpg_update_pattern_control(xtpg, passthrough, pattern); | ||
163 | mutex_unlock(xtpg->ctrl_handler.lock); | ||
164 | } | ||
165 | |||
166 | /* ----------------------------------------------------------------------------- | ||
167 | * V4L2 Subdevice Video Operations | ||
168 | */ | ||
169 | |||
170 | static int xtpg_s_stream(struct v4l2_subdev *subdev, int enable) | ||
171 | { | ||
172 | struct xtpg_device *xtpg = to_tpg(subdev); | ||
173 | unsigned int width = xtpg->formats[0].width; | ||
174 | unsigned int height = xtpg->formats[0].height; | ||
175 | bool passthrough; | ||
176 | u32 bayer_phase; | ||
177 | |||
178 | if (!enable) { | ||
179 | xvip_stop(&xtpg->xvip); | ||
180 | if (xtpg->vtc) | ||
181 | xvtc_generator_stop(xtpg->vtc); | ||
182 | |||
183 | xtpg_update_pattern_control(xtpg, true, true); | ||
184 | xtpg->streaming = false; | ||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | xvip_set_frame_size(&xtpg->xvip, &xtpg->formats[0]); | ||
189 | |||
190 | if (xtpg->vtc) { | ||
191 | struct xvtc_config config = { | ||
192 | .hblank_start = width, | ||
193 | .hsync_start = width + 1, | ||
194 | .vblank_start = height, | ||
195 | .vsync_start = height + 1, | ||
196 | }; | ||
197 | unsigned int htotal; | ||
198 | unsigned int vtotal; | ||
199 | |||
200 | htotal = min_t(unsigned int, XVTC_MAX_HSIZE, | ||
201 | v4l2_ctrl_g_ctrl(xtpg->hblank) + width); | ||
202 | vtotal = min_t(unsigned int, XVTC_MAX_VSIZE, | ||
203 | v4l2_ctrl_g_ctrl(xtpg->vblank) + height); | ||
204 | |||
205 | config.hsync_end = htotal - 1; | ||
206 | config.hsize = htotal; | ||
207 | config.vsync_end = vtotal - 1; | ||
208 | config.vsize = vtotal; | ||
209 | |||
210 | xvtc_generator_start(xtpg->vtc, &config); | ||
211 | } | ||
212 | |||
213 | /* | ||
214 | * Configure the bayer phase and video timing mux based on the | ||
215 | * operation mode (passthrough or test pattern generation). The test | ||
216 | * pattern can be modified by the control set handler, we thus need to | ||
217 | * take the control lock here to avoid races. | ||
218 | */ | ||
219 | mutex_lock(xtpg->ctrl_handler.lock); | ||
220 | |||
221 | xvip_clr_and_set(&xtpg->xvip, XTPG_PATTERN_CONTROL, | ||
222 | XTPG_PATTERN_MASK, xtpg->pattern->cur.val); | ||
223 | |||
224 | /* | ||
225 | * Switching between passthrough and test pattern generation modes isn't | ||
226 | * allowed during streaming, update the control range accordingly. | ||
227 | */ | ||
228 | passthrough = xtpg->pattern->cur.val == 0; | ||
229 | __xtpg_update_pattern_control(xtpg, passthrough, !passthrough); | ||
230 | |||
231 | xtpg->streaming = true; | ||
232 | |||
233 | mutex_unlock(xtpg->ctrl_handler.lock); | ||
234 | |||
235 | /* | ||
236 | * For TPG v5.0, the bayer phase needs to be off for the pass through | ||
237 | * mode, otherwise the external input would be subsampled. | ||
238 | */ | ||
239 | bayer_phase = passthrough ? XTPG_BAYER_PHASE_OFF | ||
240 | : xtpg_get_bayer_phase(xtpg->formats[0].code); | ||
241 | xvip_write(&xtpg->xvip, XTPG_BAYER_PHASE, bayer_phase); | ||
242 | |||
243 | if (xtpg->vtmux_gpio) | ||
244 | gpiod_set_value_cansleep(xtpg->vtmux_gpio, !passthrough); | ||
245 | |||
246 | xvip_start(&xtpg->xvip); | ||
247 | |||
248 | return 0; | ||
249 | } | ||
250 | |||
251 | /* ----------------------------------------------------------------------------- | ||
252 | * V4L2 Subdevice Pad Operations | ||
253 | */ | ||
254 | |||
255 | static struct v4l2_mbus_framefmt * | ||
256 | __xtpg_get_pad_format(struct xtpg_device *xtpg, | ||
257 | struct v4l2_subdev_pad_config *cfg, | ||
258 | unsigned int pad, u32 which) | ||
259 | { | ||
260 | switch (which) { | ||
261 | case V4L2_SUBDEV_FORMAT_TRY: | ||
262 | return v4l2_subdev_get_try_format(&xtpg->xvip.subdev, cfg, pad); | ||
263 | case V4L2_SUBDEV_FORMAT_ACTIVE: | ||
264 | return &xtpg->formats[pad]; | ||
265 | default: | ||
266 | return NULL; | ||
267 | } | ||
268 | } | ||
269 | |||
270 | static int xtpg_get_format(struct v4l2_subdev *subdev, | ||
271 | struct v4l2_subdev_pad_config *cfg, | ||
272 | struct v4l2_subdev_format *fmt) | ||
273 | { | ||
274 | struct xtpg_device *xtpg = to_tpg(subdev); | ||
275 | |||
276 | fmt->format = *__xtpg_get_pad_format(xtpg, cfg, fmt->pad, fmt->which); | ||
277 | |||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | static int xtpg_set_format(struct v4l2_subdev *subdev, | ||
282 | struct v4l2_subdev_pad_config *cfg, | ||
283 | struct v4l2_subdev_format *fmt) | ||
284 | { | ||
285 | struct xtpg_device *xtpg = to_tpg(subdev); | ||
286 | struct v4l2_mbus_framefmt *__format; | ||
287 | u32 bayer_phase; | ||
288 | |||
289 | __format = __xtpg_get_pad_format(xtpg, cfg, fmt->pad, fmt->which); | ||
290 | |||
291 | /* In two pads mode the source pad format is always identical to the | ||
292 | * sink pad format. | ||
293 | */ | ||
294 | if (xtpg->npads == 2 && fmt->pad == 1) { | ||
295 | fmt->format = *__format; | ||
296 | return 0; | ||
297 | } | ||
298 | |||
299 | /* Bayer phase is configurable at runtime */ | ||
300 | if (xtpg->bayer) { | ||
301 | bayer_phase = xtpg_get_bayer_phase(fmt->format.code); | ||
302 | if (bayer_phase != XTPG_BAYER_PHASE_OFF) | ||
303 | __format->code = fmt->format.code; | ||
304 | } | ||
305 | |||
306 | xvip_set_format_size(__format, fmt); | ||
307 | |||
308 | fmt->format = *__format; | ||
309 | |||
310 | /* Propagate the format to the source pad. */ | ||
311 | if (xtpg->npads == 2) { | ||
312 | __format = __xtpg_get_pad_format(xtpg, cfg, 1, fmt->which); | ||
313 | *__format = fmt->format; | ||
314 | } | ||
315 | |||
316 | return 0; | ||
317 | } | ||
318 | |||
319 | /* ----------------------------------------------------------------------------- | ||
320 | * V4L2 Subdevice Operations | ||
321 | */ | ||
322 | |||
323 | static int xtpg_enum_frame_size(struct v4l2_subdev *subdev, | ||
324 | struct v4l2_subdev_pad_config *cfg, | ||
325 | struct v4l2_subdev_frame_size_enum *fse) | ||
326 | { | ||
327 | struct v4l2_mbus_framefmt *format; | ||
328 | |||
329 | format = v4l2_subdev_get_try_format(subdev, cfg, fse->pad); | ||
330 | |||
331 | if (fse->index || fse->code != format->code) | ||
332 | return -EINVAL; | ||
333 | |||
334 | /* Min / max values for pad 0 is always fixed in both one and two pads | ||
335 | * modes. In two pads mode, the source pad(= 1) size is identical to | ||
336 | * the sink pad size */ | ||
337 | if (fse->pad == 0) { | ||
338 | fse->min_width = XVIP_MIN_WIDTH; | ||
339 | fse->max_width = XVIP_MAX_WIDTH; | ||
340 | fse->min_height = XVIP_MIN_HEIGHT; | ||
341 | fse->max_height = XVIP_MAX_HEIGHT; | ||
342 | } else { | ||
343 | fse->min_width = format->width; | ||
344 | fse->max_width = format->width; | ||
345 | fse->min_height = format->height; | ||
346 | fse->max_height = format->height; | ||
347 | } | ||
348 | |||
349 | return 0; | ||
350 | } | ||
351 | |||
352 | static int xtpg_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh) | ||
353 | { | ||
354 | struct xtpg_device *xtpg = to_tpg(subdev); | ||
355 | struct v4l2_mbus_framefmt *format; | ||
356 | |||
357 | format = v4l2_subdev_get_try_format(subdev, fh->pad, 0); | ||
358 | *format = xtpg->default_format; | ||
359 | |||
360 | if (xtpg->npads == 2) { | ||
361 | format = v4l2_subdev_get_try_format(subdev, fh->pad, 1); | ||
362 | *format = xtpg->default_format; | ||
363 | } | ||
364 | |||
365 | return 0; | ||
366 | } | ||
367 | |||
368 | static int xtpg_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh) | ||
369 | { | ||
370 | return 0; | ||
371 | } | ||
372 | |||
373 | static int xtpg_s_ctrl(struct v4l2_ctrl *ctrl) | ||
374 | { | ||
375 | struct xtpg_device *xtpg = container_of(ctrl->handler, | ||
376 | struct xtpg_device, | ||
377 | ctrl_handler); | ||
378 | switch (ctrl->id) { | ||
379 | case V4L2_CID_TEST_PATTERN: | ||
380 | xvip_clr_and_set(&xtpg->xvip, XTPG_PATTERN_CONTROL, | ||
381 | XTPG_PATTERN_MASK, ctrl->val); | ||
382 | return 0; | ||
383 | case V4L2_CID_XILINX_TPG_CROSS_HAIRS: | ||
384 | xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL, | ||
385 | XTPG_PATTERN_CONTROL_CROSS_HAIRS, ctrl->val); | ||
386 | return 0; | ||
387 | case V4L2_CID_XILINX_TPG_MOVING_BOX: | ||
388 | xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL, | ||
389 | XTPG_PATTERN_CONTROL_MOVING_BOX, ctrl->val); | ||
390 | return 0; | ||
391 | case V4L2_CID_XILINX_TPG_COLOR_MASK: | ||
392 | xvip_clr_and_set(&xtpg->xvip, XTPG_PATTERN_CONTROL, | ||
393 | XTPG_PATTERN_CONTROL_COLOR_MASK_MASK, | ||
394 | ctrl->val << | ||
395 | XTPG_PATTERN_CONTROL_COLOR_MASK_SHIFT); | ||
396 | return 0; | ||
397 | case V4L2_CID_XILINX_TPG_STUCK_PIXEL: | ||
398 | xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL, | ||
399 | XTPG_PATTERN_CONTROL_STUCK_PIXEL, ctrl->val); | ||
400 | return 0; | ||
401 | case V4L2_CID_XILINX_TPG_NOISE: | ||
402 | xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL, | ||
403 | XTPG_PATTERN_CONTROL_NOISE, ctrl->val); | ||
404 | return 0; | ||
405 | case V4L2_CID_XILINX_TPG_MOTION: | ||
406 | xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL, | ||
407 | XTPG_PATTERN_CONTROL_MOTION, ctrl->val); | ||
408 | return 0; | ||
409 | case V4L2_CID_XILINX_TPG_MOTION_SPEED: | ||
410 | xvip_write(&xtpg->xvip, XTPG_MOTION_SPEED, ctrl->val); | ||
411 | return 0; | ||
412 | case V4L2_CID_XILINX_TPG_CROSS_HAIR_ROW: | ||
413 | xvip_clr_and_set(&xtpg->xvip, XTPG_CROSS_HAIRS, | ||
414 | XTPG_CROSS_HAIRS_ROW_MASK, | ||
415 | ctrl->val << XTPG_CROSS_HAIRS_ROW_SHIFT); | ||
416 | return 0; | ||
417 | case V4L2_CID_XILINX_TPG_CROSS_HAIR_COLUMN: | ||
418 | xvip_clr_and_set(&xtpg->xvip, XTPG_CROSS_HAIRS, | ||
419 | XTPG_CROSS_HAIRS_COLUMN_MASK, | ||
420 | ctrl->val << XTPG_CROSS_HAIRS_COLUMN_SHIFT); | ||
421 | return 0; | ||
422 | case V4L2_CID_XILINX_TPG_ZPLATE_HOR_START: | ||
423 | xvip_clr_and_set(&xtpg->xvip, XTPG_ZPLATE_HOR_CONTROL, | ||
424 | XTPG_ZPLATE_START_MASK, | ||
425 | ctrl->val << XTPG_ZPLATE_START_SHIFT); | ||
426 | return 0; | ||
427 | case V4L2_CID_XILINX_TPG_ZPLATE_HOR_SPEED: | ||
428 | xvip_clr_and_set(&xtpg->xvip, XTPG_ZPLATE_HOR_CONTROL, | ||
429 | XTPG_ZPLATE_SPEED_MASK, | ||
430 | ctrl->val << XTPG_ZPLATE_SPEED_SHIFT); | ||
431 | return 0; | ||
432 | case V4L2_CID_XILINX_TPG_ZPLATE_VER_START: | ||
433 | xvip_clr_and_set(&xtpg->xvip, XTPG_ZPLATE_VER_CONTROL, | ||
434 | XTPG_ZPLATE_START_MASK, | ||
435 | ctrl->val << XTPG_ZPLATE_START_SHIFT); | ||
436 | return 0; | ||
437 | case V4L2_CID_XILINX_TPG_ZPLATE_VER_SPEED: | ||
438 | xvip_clr_and_set(&xtpg->xvip, XTPG_ZPLATE_VER_CONTROL, | ||
439 | XTPG_ZPLATE_SPEED_MASK, | ||
440 | ctrl->val << XTPG_ZPLATE_SPEED_SHIFT); | ||
441 | return 0; | ||
442 | case V4L2_CID_XILINX_TPG_BOX_SIZE: | ||
443 | xvip_write(&xtpg->xvip, XTPG_BOX_SIZE, ctrl->val); | ||
444 | return 0; | ||
445 | case V4L2_CID_XILINX_TPG_BOX_COLOR: | ||
446 | xvip_write(&xtpg->xvip, XTPG_BOX_COLOR, ctrl->val); | ||
447 | return 0; | ||
448 | case V4L2_CID_XILINX_TPG_STUCK_PIXEL_THRESH: | ||
449 | xvip_write(&xtpg->xvip, XTPG_STUCK_PIXEL_THRESH, ctrl->val); | ||
450 | return 0; | ||
451 | case V4L2_CID_XILINX_TPG_NOISE_GAIN: | ||
452 | xvip_write(&xtpg->xvip, XTPG_NOISE_GAIN, ctrl->val); | ||
453 | return 0; | ||
454 | } | ||
455 | |||
456 | return 0; | ||
457 | } | ||
458 | |||
459 | static const struct v4l2_ctrl_ops xtpg_ctrl_ops = { | ||
460 | .s_ctrl = xtpg_s_ctrl, | ||
461 | }; | ||
462 | |||
463 | static struct v4l2_subdev_core_ops xtpg_core_ops = { | ||
464 | }; | ||
465 | |||
466 | static struct v4l2_subdev_video_ops xtpg_video_ops = { | ||
467 | .s_stream = xtpg_s_stream, | ||
468 | }; | ||
469 | |||
470 | static struct v4l2_subdev_pad_ops xtpg_pad_ops = { | ||
471 | .enum_mbus_code = xvip_enum_mbus_code, | ||
472 | .enum_frame_size = xtpg_enum_frame_size, | ||
473 | .get_fmt = xtpg_get_format, | ||
474 | .set_fmt = xtpg_set_format, | ||
475 | }; | ||
476 | |||
477 | static struct v4l2_subdev_ops xtpg_ops = { | ||
478 | .core = &xtpg_core_ops, | ||
479 | .video = &xtpg_video_ops, | ||
480 | .pad = &xtpg_pad_ops, | ||
481 | }; | ||
482 | |||
483 | static const struct v4l2_subdev_internal_ops xtpg_internal_ops = { | ||
484 | .open = xtpg_open, | ||
485 | .close = xtpg_close, | ||
486 | }; | ||
487 | |||
488 | /* | ||
489 | * Control Config | ||
490 | */ | ||
491 | |||
492 | static const char *const xtpg_pattern_strings[] = { | ||
493 | "Passthrough", | ||
494 | "Horizontal Ramp", | ||
495 | "Vertical Ramp", | ||
496 | "Temporal Ramp", | ||
497 | "Solid Red", | ||
498 | "Solid Green", | ||
499 | "Solid Blue", | ||
500 | "Solid Black", | ||
501 | "Solid White", | ||
502 | "Color Bars", | ||
503 | "Zone Plate", | ||
504 | "Tartan Color Bars", | ||
505 | "Cross Hatch", | ||
506 | "None", | ||
507 | "Vertical/Horizontal Ramps", | ||
508 | "Black/White Checker Board", | ||
509 | }; | ||
510 | |||
511 | static struct v4l2_ctrl_config xtpg_ctrls[] = { | ||
512 | { | ||
513 | .ops = &xtpg_ctrl_ops, | ||
514 | .id = V4L2_CID_XILINX_TPG_CROSS_HAIRS, | ||
515 | .name = "Test Pattern: Cross Hairs", | ||
516 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
517 | .min = false, | ||
518 | .max = true, | ||
519 | .step = 1, | ||
520 | .def = 0, | ||
521 | }, { | ||
522 | .ops = &xtpg_ctrl_ops, | ||
523 | .id = V4L2_CID_XILINX_TPG_MOVING_BOX, | ||
524 | .name = "Test Pattern: Moving Box", | ||
525 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
526 | .min = false, | ||
527 | .max = true, | ||
528 | .step = 1, | ||
529 | .def = 0, | ||
530 | }, { | ||
531 | .ops = &xtpg_ctrl_ops, | ||
532 | .id = V4L2_CID_XILINX_TPG_COLOR_MASK, | ||
533 | .name = "Test Pattern: Color Mask", | ||
534 | .type = V4L2_CTRL_TYPE_BITMASK, | ||
535 | .min = 0, | ||
536 | .max = 0xf, | ||
537 | .def = 0, | ||
538 | }, { | ||
539 | .ops = &xtpg_ctrl_ops, | ||
540 | .id = V4L2_CID_XILINX_TPG_STUCK_PIXEL, | ||
541 | .name = "Test Pattern: Stuck Pixel", | ||
542 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
543 | .min = false, | ||
544 | .max = true, | ||
545 | .step = 1, | ||
546 | .def = 0, | ||
547 | }, { | ||
548 | .ops = &xtpg_ctrl_ops, | ||
549 | .id = V4L2_CID_XILINX_TPG_NOISE, | ||
550 | .name = "Test Pattern: Noise", | ||
551 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
552 | .min = false, | ||
553 | .max = true, | ||
554 | .step = 1, | ||
555 | .def = 0, | ||
556 | }, { | ||
557 | .ops = &xtpg_ctrl_ops, | ||
558 | .id = V4L2_CID_XILINX_TPG_MOTION, | ||
559 | .name = "Test Pattern: Motion", | ||
560 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
561 | .min = false, | ||
562 | .max = true, | ||
563 | .step = 1, | ||
564 | .def = 0, | ||
565 | }, { | ||
566 | .ops = &xtpg_ctrl_ops, | ||
567 | .id = V4L2_CID_XILINX_TPG_MOTION_SPEED, | ||
568 | .name = "Test Pattern: Motion Speed", | ||
569 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
570 | .min = 0, | ||
571 | .max = (1 << 8) - 1, | ||
572 | .step = 1, | ||
573 | .def = 4, | ||
574 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
575 | }, { | ||
576 | .ops = &xtpg_ctrl_ops, | ||
577 | .id = V4L2_CID_XILINX_TPG_CROSS_HAIR_ROW, | ||
578 | .name = "Test Pattern: Cross Hairs Row", | ||
579 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
580 | .min = 0, | ||
581 | .max = (1 << 12) - 1, | ||
582 | .step = 1, | ||
583 | .def = 0x64, | ||
584 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
585 | }, { | ||
586 | .ops = &xtpg_ctrl_ops, | ||
587 | .id = V4L2_CID_XILINX_TPG_CROSS_HAIR_COLUMN, | ||
588 | .name = "Test Pattern: Cross Hairs Column", | ||
589 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
590 | .min = 0, | ||
591 | .max = (1 << 12) - 1, | ||
592 | .step = 1, | ||
593 | .def = 0x64, | ||
594 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
595 | }, { | ||
596 | .ops = &xtpg_ctrl_ops, | ||
597 | .id = V4L2_CID_XILINX_TPG_ZPLATE_HOR_START, | ||
598 | .name = "Test Pattern: Zplate Horizontal Start Pos", | ||
599 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
600 | .min = 0, | ||
601 | .max = (1 << 16) - 1, | ||
602 | .step = 1, | ||
603 | .def = 0x1e, | ||
604 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
605 | }, { | ||
606 | .ops = &xtpg_ctrl_ops, | ||
607 | .id = V4L2_CID_XILINX_TPG_ZPLATE_HOR_SPEED, | ||
608 | .name = "Test Pattern: Zplate Horizontal Speed", | ||
609 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
610 | .min = 0, | ||
611 | .max = (1 << 16) - 1, | ||
612 | .step = 1, | ||
613 | .def = 0, | ||
614 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
615 | }, { | ||
616 | .ops = &xtpg_ctrl_ops, | ||
617 | .id = V4L2_CID_XILINX_TPG_ZPLATE_VER_START, | ||
618 | .name = "Test Pattern: Zplate Vertical Start Pos", | ||
619 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
620 | .min = 0, | ||
621 | .max = (1 << 16) - 1, | ||
622 | .step = 1, | ||
623 | .def = 1, | ||
624 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
625 | }, { | ||
626 | .ops = &xtpg_ctrl_ops, | ||
627 | .id = V4L2_CID_XILINX_TPG_ZPLATE_VER_SPEED, | ||
628 | .name = "Test Pattern: Zplate Vertical Speed", | ||
629 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
630 | .min = 0, | ||
631 | .max = (1 << 16) - 1, | ||
632 | .step = 1, | ||
633 | .def = 0, | ||
634 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
635 | }, { | ||
636 | .ops = &xtpg_ctrl_ops, | ||
637 | .id = V4L2_CID_XILINX_TPG_BOX_SIZE, | ||
638 | .name = "Test Pattern: Box Size", | ||
639 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
640 | .min = 0, | ||
641 | .max = (1 << 12) - 1, | ||
642 | .step = 1, | ||
643 | .def = 0x32, | ||
644 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
645 | }, { | ||
646 | .ops = &xtpg_ctrl_ops, | ||
647 | .id = V4L2_CID_XILINX_TPG_BOX_COLOR, | ||
648 | .name = "Test Pattern: Box Color(RGB)", | ||
649 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
650 | .min = 0, | ||
651 | .max = (1 << 24) - 1, | ||
652 | .step = 1, | ||
653 | .def = 0, | ||
654 | }, { | ||
655 | .ops = &xtpg_ctrl_ops, | ||
656 | .id = V4L2_CID_XILINX_TPG_STUCK_PIXEL_THRESH, | ||
657 | .name = "Test Pattern: Stuck Pixel threshold", | ||
658 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
659 | .min = 0, | ||
660 | .max = (1 << 16) - 1, | ||
661 | .step = 1, | ||
662 | .def = 0, | ||
663 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
664 | }, { | ||
665 | .ops = &xtpg_ctrl_ops, | ||
666 | .id = V4L2_CID_XILINX_TPG_NOISE_GAIN, | ||
667 | .name = "Test Pattern: Noise Gain", | ||
668 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
669 | .min = 0, | ||
670 | .max = (1 << 8) - 1, | ||
671 | .step = 1, | ||
672 | .def = 0, | ||
673 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
674 | }, | ||
675 | }; | ||
676 | |||
677 | /* ----------------------------------------------------------------------------- | ||
678 | * Media Operations | ||
679 | */ | ||
680 | |||
681 | static const struct media_entity_operations xtpg_media_ops = { | ||
682 | .link_validate = v4l2_subdev_link_validate, | ||
683 | }; | ||
684 | |||
685 | /* ----------------------------------------------------------------------------- | ||
686 | * Power Management | ||
687 | */ | ||
688 | |||
689 | static int __maybe_unused xtpg_pm_suspend(struct device *dev) | ||
690 | { | ||
691 | struct xtpg_device *xtpg = dev_get_drvdata(dev); | ||
692 | |||
693 | xvip_suspend(&xtpg->xvip); | ||
694 | |||
695 | return 0; | ||
696 | } | ||
697 | |||
698 | static int __maybe_unused xtpg_pm_resume(struct device *dev) | ||
699 | { | ||
700 | struct xtpg_device *xtpg = dev_get_drvdata(dev); | ||
701 | |||
702 | xvip_resume(&xtpg->xvip); | ||
703 | |||
704 | return 0; | ||
705 | } | ||
706 | |||
707 | /* ----------------------------------------------------------------------------- | ||
708 | * Platform Device Driver | ||
709 | */ | ||
710 | |||
711 | static int xtpg_parse_of(struct xtpg_device *xtpg) | ||
712 | { | ||
713 | struct device *dev = xtpg->xvip.dev; | ||
714 | struct device_node *node = xtpg->xvip.dev->of_node; | ||
715 | struct device_node *ports; | ||
716 | struct device_node *port; | ||
717 | unsigned int nports = 0; | ||
718 | bool has_endpoint = false; | ||
719 | |||
720 | ports = of_get_child_by_name(node, "ports"); | ||
721 | if (ports == NULL) | ||
722 | ports = node; | ||
723 | |||
724 | for_each_child_of_node(ports, port) { | ||
725 | const struct xvip_video_format *format; | ||
726 | struct device_node *endpoint; | ||
727 | |||
728 | if (!port->name || of_node_cmp(port->name, "port")) | ||
729 | continue; | ||
730 | |||
731 | format = xvip_of_get_format(port); | ||
732 | if (IS_ERR(format)) { | ||
733 | dev_err(dev, "invalid format in DT"); | ||
734 | return PTR_ERR(format); | ||
735 | } | ||
736 | |||
737 | /* Get and check the format description */ | ||
738 | if (!xtpg->vip_format) { | ||
739 | xtpg->vip_format = format; | ||
740 | } else if (xtpg->vip_format != format) { | ||
741 | dev_err(dev, "in/out format mismatch in DT"); | ||
742 | return -EINVAL; | ||
743 | } | ||
744 | |||
745 | if (nports == 0) { | ||
746 | endpoint = of_get_next_child(port, NULL); | ||
747 | if (endpoint) | ||
748 | has_endpoint = true; | ||
749 | of_node_put(endpoint); | ||
750 | } | ||
751 | |||
752 | /* Count the number of ports. */ | ||
753 | nports++; | ||
754 | } | ||
755 | |||
756 | if (nports != 1 && nports != 2) { | ||
757 | dev_err(dev, "invalid number of ports %u\n", nports); | ||
758 | return -EINVAL; | ||
759 | } | ||
760 | |||
761 | xtpg->npads = nports; | ||
762 | if (nports == 2 && has_endpoint) | ||
763 | xtpg->has_input = true; | ||
764 | |||
765 | return 0; | ||
766 | } | ||
767 | |||
768 | static int xtpg_probe(struct platform_device *pdev) | ||
769 | { | ||
770 | struct v4l2_subdev *subdev; | ||
771 | struct xtpg_device *xtpg; | ||
772 | u32 i, bayer_phase; | ||
773 | int ret; | ||
774 | |||
775 | xtpg = devm_kzalloc(&pdev->dev, sizeof(*xtpg), GFP_KERNEL); | ||
776 | if (!xtpg) | ||
777 | return -ENOMEM; | ||
778 | |||
779 | xtpg->xvip.dev = &pdev->dev; | ||
780 | |||
781 | ret = xtpg_parse_of(xtpg); | ||
782 | if (ret < 0) | ||
783 | return ret; | ||
784 | |||
785 | ret = xvip_init_resources(&xtpg->xvip); | ||
786 | if (ret < 0) | ||
787 | return ret; | ||
788 | |||
789 | xtpg->vtmux_gpio = devm_gpiod_get_optional(&pdev->dev, "timing", | ||
790 | GPIOD_OUT_HIGH); | ||
791 | if (IS_ERR(xtpg->vtmux_gpio)) { | ||
792 | ret = PTR_ERR(xtpg->vtmux_gpio); | ||
793 | goto error_resource; | ||
794 | } | ||
795 | |||
796 | xtpg->vtc = xvtc_of_get(pdev->dev.of_node); | ||
797 | if (IS_ERR(xtpg->vtc)) { | ||
798 | ret = PTR_ERR(xtpg->vtc); | ||
799 | goto error_resource; | ||
800 | } | ||
801 | |||
802 | /* Reset and initialize the core */ | ||
803 | xvip_reset(&xtpg->xvip); | ||
804 | |||
805 | /* Initialize V4L2 subdevice and media entity. Pad numbers depend on the | ||
806 | * number of pads. | ||
807 | */ | ||
808 | if (xtpg->npads == 2) { | ||
809 | xtpg->pads[0].flags = MEDIA_PAD_FL_SINK; | ||
810 | xtpg->pads[1].flags = MEDIA_PAD_FL_SOURCE; | ||
811 | } else { | ||
812 | xtpg->pads[0].flags = MEDIA_PAD_FL_SOURCE; | ||
813 | } | ||
814 | |||
815 | /* Initialize the default format */ | ||
816 | xtpg->default_format.code = xtpg->vip_format->code; | ||
817 | xtpg->default_format.field = V4L2_FIELD_NONE; | ||
818 | xtpg->default_format.colorspace = V4L2_COLORSPACE_SRGB; | ||
819 | xvip_get_frame_size(&xtpg->xvip, &xtpg->default_format); | ||
820 | |||
821 | bayer_phase = xtpg_get_bayer_phase(xtpg->vip_format->code); | ||
822 | if (bayer_phase != XTPG_BAYER_PHASE_OFF) | ||
823 | xtpg->bayer = true; | ||
824 | |||
825 | xtpg->formats[0] = xtpg->default_format; | ||
826 | if (xtpg->npads == 2) | ||
827 | xtpg->formats[1] = xtpg->default_format; | ||
828 | |||
829 | /* Initialize V4L2 subdevice and media entity */ | ||
830 | subdev = &xtpg->xvip.subdev; | ||
831 | v4l2_subdev_init(subdev, &xtpg_ops); | ||
832 | subdev->dev = &pdev->dev; | ||
833 | subdev->internal_ops = &xtpg_internal_ops; | ||
834 | strlcpy(subdev->name, dev_name(&pdev->dev), sizeof(subdev->name)); | ||
835 | v4l2_set_subdevdata(subdev, xtpg); | ||
836 | subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; | ||
837 | subdev->entity.ops = &xtpg_media_ops; | ||
838 | |||
839 | ret = media_entity_init(&subdev->entity, xtpg->npads, xtpg->pads, 0); | ||
840 | if (ret < 0) | ||
841 | goto error; | ||
842 | |||
843 | v4l2_ctrl_handler_init(&xtpg->ctrl_handler, 3 + ARRAY_SIZE(xtpg_ctrls)); | ||
844 | |||
845 | xtpg->vblank = v4l2_ctrl_new_std(&xtpg->ctrl_handler, &xtpg_ctrl_ops, | ||
846 | V4L2_CID_VBLANK, XTPG_MIN_VBLANK, | ||
847 | XTPG_MAX_VBLANK, 1, 100); | ||
848 | xtpg->hblank = v4l2_ctrl_new_std(&xtpg->ctrl_handler, &xtpg_ctrl_ops, | ||
849 | V4L2_CID_HBLANK, XTPG_MIN_HBLANK, | ||
850 | XTPG_MAX_HBLANK, 1, 100); | ||
851 | xtpg->pattern = v4l2_ctrl_new_std_menu_items(&xtpg->ctrl_handler, | ||
852 | &xtpg_ctrl_ops, V4L2_CID_TEST_PATTERN, | ||
853 | ARRAY_SIZE(xtpg_pattern_strings) - 1, | ||
854 | 1, 9, xtpg_pattern_strings); | ||
855 | |||
856 | for (i = 0; i < ARRAY_SIZE(xtpg_ctrls); i++) | ||
857 | v4l2_ctrl_new_custom(&xtpg->ctrl_handler, &xtpg_ctrls[i], NULL); | ||
858 | |||
859 | if (xtpg->ctrl_handler.error) { | ||
860 | dev_err(&pdev->dev, "failed to add controls\n"); | ||
861 | ret = xtpg->ctrl_handler.error; | ||
862 | goto error; | ||
863 | } | ||
864 | subdev->ctrl_handler = &xtpg->ctrl_handler; | ||
865 | |||
866 | xtpg_update_pattern_control(xtpg, true, true); | ||
867 | |||
868 | ret = v4l2_ctrl_handler_setup(&xtpg->ctrl_handler); | ||
869 | if (ret < 0) { | ||
870 | dev_err(&pdev->dev, "failed to set controls\n"); | ||
871 | goto error; | ||
872 | } | ||
873 | |||
874 | platform_set_drvdata(pdev, xtpg); | ||
875 | |||
876 | xvip_print_version(&xtpg->xvip); | ||
877 | |||
878 | ret = v4l2_async_register_subdev(subdev); | ||
879 | if (ret < 0) { | ||
880 | dev_err(&pdev->dev, "failed to register subdev\n"); | ||
881 | goto error; | ||
882 | } | ||
883 | |||
884 | return 0; | ||
885 | |||
886 | error: | ||
887 | v4l2_ctrl_handler_free(&xtpg->ctrl_handler); | ||
888 | media_entity_cleanup(&subdev->entity); | ||
889 | xvtc_put(xtpg->vtc); | ||
890 | error_resource: | ||
891 | xvip_cleanup_resources(&xtpg->xvip); | ||
892 | return ret; | ||
893 | } | ||
894 | |||
895 | static int xtpg_remove(struct platform_device *pdev) | ||
896 | { | ||
897 | struct xtpg_device *xtpg = platform_get_drvdata(pdev); | ||
898 | struct v4l2_subdev *subdev = &xtpg->xvip.subdev; | ||
899 | |||
900 | v4l2_async_unregister_subdev(subdev); | ||
901 | v4l2_ctrl_handler_free(&xtpg->ctrl_handler); | ||
902 | media_entity_cleanup(&subdev->entity); | ||
903 | |||
904 | xvip_cleanup_resources(&xtpg->xvip); | ||
905 | |||
906 | return 0; | ||
907 | } | ||
908 | |||
909 | static SIMPLE_DEV_PM_OPS(xtpg_pm_ops, xtpg_pm_suspend, xtpg_pm_resume); | ||
910 | |||
911 | static const struct of_device_id xtpg_of_id_table[] = { | ||
912 | { .compatible = "xlnx,v-tpg-5.0" }, | ||
913 | { } | ||
914 | }; | ||
915 | MODULE_DEVICE_TABLE(of, xtpg_of_id_table); | ||
916 | |||
917 | static struct platform_driver xtpg_driver = { | ||
918 | .driver = { | ||
919 | .name = "xilinx-tpg", | ||
920 | .pm = &xtpg_pm_ops, | ||
921 | .of_match_table = xtpg_of_id_table, | ||
922 | }, | ||
923 | .probe = xtpg_probe, | ||
924 | .remove = xtpg_remove, | ||
925 | }; | ||
926 | |||
927 | module_platform_driver(xtpg_driver); | ||
928 | |||
929 | MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>"); | ||
930 | MODULE_DESCRIPTION("Xilinx Test Pattern Generator Driver"); | ||
931 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/media/platform/xilinx/xilinx-vip.c b/drivers/media/platform/xilinx/xilinx-vip.c new file mode 100644 index 000000000000..311259129504 --- /dev/null +++ b/drivers/media/platform/xilinx/xilinx-vip.c | |||
@@ -0,0 +1,323 @@ | |||
1 | /* | ||
2 | * Xilinx Video IP Core | ||
3 | * | ||
4 | * Copyright (C) 2013-2015 Ideas on Board | ||
5 | * Copyright (C) 2013-2015 Xilinx, Inc. | ||
6 | * | ||
7 | * Contacts: Hyun Kwon <hyun.kwon@xilinx.com> | ||
8 | * Laurent Pinchart <laurent.pinchart@ideasonboard.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include <linux/clk.h> | ||
16 | #include <linux/export.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/of.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | |||
21 | #include <dt-bindings/media/xilinx-vip.h> | ||
22 | |||
23 | #include "xilinx-vip.h" | ||
24 | |||
25 | /* ----------------------------------------------------------------------------- | ||
26 | * Helper functions | ||
27 | */ | ||
28 | |||
29 | static const struct xvip_video_format xvip_video_formats[] = { | ||
30 | { XVIP_VF_YUV_422, 8, NULL, MEDIA_BUS_FMT_UYVY8_1X16, | ||
31 | 2, V4L2_PIX_FMT_YUYV, "4:2:2, packed, YUYV" }, | ||
32 | { XVIP_VF_YUV_444, 8, NULL, MEDIA_BUS_FMT_VUY8_1X24, | ||
33 | 3, V4L2_PIX_FMT_YUV444, "4:4:4, packed, YUYV" }, | ||
34 | { XVIP_VF_RBG, 8, NULL, MEDIA_BUS_FMT_RBG888_1X24, | ||
35 | 3, 0, NULL }, | ||
36 | { XVIP_VF_MONO_SENSOR, 8, "mono", MEDIA_BUS_FMT_Y8_1X8, | ||
37 | 1, V4L2_PIX_FMT_GREY, "Greyscale 8-bit" }, | ||
38 | { XVIP_VF_MONO_SENSOR, 8, "rggb", MEDIA_BUS_FMT_SRGGB8_1X8, | ||
39 | 1, V4L2_PIX_FMT_SGRBG8, "Bayer 8-bit RGGB" }, | ||
40 | { XVIP_VF_MONO_SENSOR, 8, "grbg", MEDIA_BUS_FMT_SGRBG8_1X8, | ||
41 | 1, V4L2_PIX_FMT_SGRBG8, "Bayer 8-bit GRBG" }, | ||
42 | { XVIP_VF_MONO_SENSOR, 8, "gbrg", MEDIA_BUS_FMT_SGBRG8_1X8, | ||
43 | 1, V4L2_PIX_FMT_SGBRG8, "Bayer 8-bit GBRG" }, | ||
44 | { XVIP_VF_MONO_SENSOR, 8, "bggr", MEDIA_BUS_FMT_SBGGR8_1X8, | ||
45 | 1, V4L2_PIX_FMT_SBGGR8, "Bayer 8-bit BGGR" }, | ||
46 | }; | ||
47 | |||
48 | /** | ||
49 | * xvip_get_format_by_code - Retrieve format information for a media bus code | ||
50 | * @code: the format media bus code | ||
51 | * | ||
52 | * Return: a pointer to the format information structure corresponding to the | ||
53 | * given V4L2 media bus format @code, or ERR_PTR if no corresponding format can | ||
54 | * be found. | ||
55 | */ | ||
56 | const struct xvip_video_format *xvip_get_format_by_code(unsigned int code) | ||
57 | { | ||
58 | unsigned int i; | ||
59 | |||
60 | for (i = 0; i < ARRAY_SIZE(xvip_video_formats); ++i) { | ||
61 | const struct xvip_video_format *format = &xvip_video_formats[i]; | ||
62 | |||
63 | if (format->code == code) | ||
64 | return format; | ||
65 | } | ||
66 | |||
67 | return ERR_PTR(-EINVAL); | ||
68 | } | ||
69 | EXPORT_SYMBOL_GPL(xvip_get_format_by_code); | ||
70 | |||
71 | /** | ||
72 | * xvip_get_format_by_fourcc - Retrieve format information for a 4CC | ||
73 | * @fourcc: the format 4CC | ||
74 | * | ||
75 | * Return: a pointer to the format information structure corresponding to the | ||
76 | * given V4L2 format @fourcc, or ERR_PTR if no corresponding format can be | ||
77 | * found. | ||
78 | */ | ||
79 | const struct xvip_video_format *xvip_get_format_by_fourcc(u32 fourcc) | ||
80 | { | ||
81 | unsigned int i; | ||
82 | |||
83 | for (i = 0; i < ARRAY_SIZE(xvip_video_formats); ++i) { | ||
84 | const struct xvip_video_format *format = &xvip_video_formats[i]; | ||
85 | |||
86 | if (format->fourcc == fourcc) | ||
87 | return format; | ||
88 | } | ||
89 | |||
90 | return ERR_PTR(-EINVAL); | ||
91 | } | ||
92 | EXPORT_SYMBOL_GPL(xvip_get_format_by_fourcc); | ||
93 | |||
94 | /** | ||
95 | * xvip_of_get_format - Parse a device tree node and return format information | ||
96 | * @node: the device tree node | ||
97 | * | ||
98 | * Read the xlnx,video-format, xlnx,video-width and xlnx,cfa-pattern properties | ||
99 | * from the device tree @node passed as an argument and return the corresponding | ||
100 | * format information. | ||
101 | * | ||
102 | * Return: a pointer to the format information structure corresponding to the | ||
103 | * format name and width, or ERR_PTR if no corresponding format can be found. | ||
104 | */ | ||
105 | const struct xvip_video_format *xvip_of_get_format(struct device_node *node) | ||
106 | { | ||
107 | const char *pattern = "mono"; | ||
108 | unsigned int vf_code; | ||
109 | unsigned int i; | ||
110 | u32 width; | ||
111 | int ret; | ||
112 | |||
113 | ret = of_property_read_u32(node, "xlnx,video-format", &vf_code); | ||
114 | if (ret < 0) | ||
115 | return ERR_PTR(ret); | ||
116 | |||
117 | ret = of_property_read_u32(node, "xlnx,video-width", &width); | ||
118 | if (ret < 0) | ||
119 | return ERR_PTR(ret); | ||
120 | |||
121 | if (vf_code == XVIP_VF_MONO_SENSOR) | ||
122 | of_property_read_string(node, "xlnx,cfa-pattern", &pattern); | ||
123 | |||
124 | for (i = 0; i < ARRAY_SIZE(xvip_video_formats); ++i) { | ||
125 | const struct xvip_video_format *format = &xvip_video_formats[i]; | ||
126 | |||
127 | if (format->vf_code != vf_code || format->width != width) | ||
128 | continue; | ||
129 | |||
130 | if (vf_code == XVIP_VF_MONO_SENSOR && | ||
131 | strcmp(pattern, format->pattern)) | ||
132 | continue; | ||
133 | |||
134 | return format; | ||
135 | } | ||
136 | |||
137 | return ERR_PTR(-EINVAL); | ||
138 | } | ||
139 | EXPORT_SYMBOL_GPL(xvip_of_get_format); | ||
140 | |||
141 | /** | ||
142 | * xvip_set_format_size - Set the media bus frame format size | ||
143 | * @format: V4L2 frame format on media bus | ||
144 | * @fmt: media bus format | ||
145 | * | ||
146 | * Set the media bus frame format size. The width / height from the subdevice | ||
147 | * format are set to the given media bus format. The new format size is stored | ||
148 | * in @format. The width and height are clamped using default min / max values. | ||
149 | */ | ||
150 | void xvip_set_format_size(struct v4l2_mbus_framefmt *format, | ||
151 | const struct v4l2_subdev_format *fmt) | ||
152 | { | ||
153 | format->width = clamp_t(unsigned int, fmt->format.width, | ||
154 | XVIP_MIN_WIDTH, XVIP_MAX_WIDTH); | ||
155 | format->height = clamp_t(unsigned int, fmt->format.height, | ||
156 | XVIP_MIN_HEIGHT, XVIP_MAX_HEIGHT); | ||
157 | } | ||
158 | EXPORT_SYMBOL_GPL(xvip_set_format_size); | ||
159 | |||
160 | /** | ||
161 | * xvip_clr_or_set - Clear or set the register with a bitmask | ||
162 | * @xvip: Xilinx Video IP device | ||
163 | * @addr: address of register | ||
164 | * @mask: bitmask to be set or cleared | ||
165 | * @set: boolean flag indicating whether to set or clear | ||
166 | * | ||
167 | * Clear or set the register at address @addr with a bitmask @mask depending on | ||
168 | * the boolean flag @set. When the flag @set is true, the bitmask is set in | ||
169 | * the register, otherwise the bitmask is cleared from the register | ||
170 | * when the flag @set is false. | ||
171 | * | ||
172 | * Fox eample, this function can be used to set a control with a boolean value | ||
173 | * requested by users. If the caller knows whether to set or clear in the first | ||
174 | * place, the caller should call xvip_clr() or xvip_set() directly instead of | ||
175 | * using this function. | ||
176 | */ | ||
177 | void xvip_clr_or_set(struct xvip_device *xvip, u32 addr, u32 mask, bool set) | ||
178 | { | ||
179 | u32 reg; | ||
180 | |||
181 | reg = xvip_read(xvip, addr); | ||
182 | reg = set ? reg | mask : reg & ~mask; | ||
183 | xvip_write(xvip, addr, reg); | ||
184 | } | ||
185 | EXPORT_SYMBOL_GPL(xvip_clr_or_set); | ||
186 | |||
187 | /** | ||
188 | * xvip_clr_and_set - Clear and set the register with a bitmask | ||
189 | * @xvip: Xilinx Video IP device | ||
190 | * @addr: address of register | ||
191 | * @clr: bitmask to be cleared | ||
192 | * @set: bitmask to be set | ||
193 | * | ||
194 | * Clear a bit(s) of mask @clr in the register at address @addr, then set | ||
195 | * a bit(s) of mask @set in the register after. | ||
196 | */ | ||
197 | void xvip_clr_and_set(struct xvip_device *xvip, u32 addr, u32 clr, u32 set) | ||
198 | { | ||
199 | u32 reg; | ||
200 | |||
201 | reg = xvip_read(xvip, addr); | ||
202 | reg &= ~clr; | ||
203 | reg |= set; | ||
204 | xvip_write(xvip, addr, reg); | ||
205 | } | ||
206 | EXPORT_SYMBOL_GPL(xvip_clr_and_set); | ||
207 | |||
208 | int xvip_init_resources(struct xvip_device *xvip) | ||
209 | { | ||
210 | struct platform_device *pdev = to_platform_device(xvip->dev); | ||
211 | struct resource *res; | ||
212 | |||
213 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
214 | xvip->iomem = devm_ioremap_resource(xvip->dev, res); | ||
215 | if (IS_ERR(xvip->iomem)) | ||
216 | return PTR_ERR(xvip->iomem); | ||
217 | |||
218 | xvip->clk = devm_clk_get(xvip->dev, NULL); | ||
219 | if (IS_ERR(xvip->clk)) | ||
220 | return PTR_ERR(xvip->clk); | ||
221 | |||
222 | clk_prepare_enable(xvip->clk); | ||
223 | return 0; | ||
224 | } | ||
225 | EXPORT_SYMBOL_GPL(xvip_init_resources); | ||
226 | |||
227 | void xvip_cleanup_resources(struct xvip_device *xvip) | ||
228 | { | ||
229 | clk_disable_unprepare(xvip->clk); | ||
230 | } | ||
231 | EXPORT_SYMBOL_GPL(xvip_cleanup_resources); | ||
232 | |||
233 | /* ----------------------------------------------------------------------------- | ||
234 | * Subdev operations handlers | ||
235 | */ | ||
236 | |||
237 | /** | ||
238 | * xvip_enum_mbus_code - Enumerate the media format code | ||
239 | * @subdev: V4L2 subdevice | ||
240 | * @cfg: V4L2 subdev pad configuration | ||
241 | * @code: returning media bus code | ||
242 | * | ||
243 | * Enumerate the media bus code of the subdevice. Return the corresponding | ||
244 | * pad format code. This function only works for subdevices with fixed format | ||
245 | * on all pads. Subdevices with multiple format should have their own | ||
246 | * function to enumerate mbus codes. | ||
247 | * | ||
248 | * Return: 0 if the media bus code is found, or -EINVAL if the format index | ||
249 | * is not valid. | ||
250 | */ | ||
251 | int xvip_enum_mbus_code(struct v4l2_subdev *subdev, | ||
252 | struct v4l2_subdev_pad_config *cfg, | ||
253 | struct v4l2_subdev_mbus_code_enum *code) | ||
254 | { | ||
255 | struct v4l2_mbus_framefmt *format; | ||
256 | |||
257 | /* Enumerating frame sizes based on the active configuration isn't | ||
258 | * supported yet. | ||
259 | */ | ||
260 | if (code->which == V4L2_SUBDEV_FORMAT_ACTIVE) | ||
261 | return -EINVAL; | ||
262 | |||
263 | if (code->index) | ||
264 | return -EINVAL; | ||
265 | |||
266 | format = v4l2_subdev_get_try_format(subdev, cfg, code->pad); | ||
267 | |||
268 | code->code = format->code; | ||
269 | |||
270 | return 0; | ||
271 | } | ||
272 | EXPORT_SYMBOL_GPL(xvip_enum_mbus_code); | ||
273 | |||
274 | /** | ||
275 | * xvip_enum_frame_size - Enumerate the media bus frame size | ||
276 | * @subdev: V4L2 subdevice | ||
277 | * @cfg: V4L2 subdev pad configuration | ||
278 | * @fse: returning media bus frame size | ||
279 | * | ||
280 | * This function is a drop-in implementation of the subdev enum_frame_size pad | ||
281 | * operation. It assumes that the subdevice has one sink pad and one source | ||
282 | * pad, and that the format on the source pad is always identical to the | ||
283 | * format on the sink pad. Entities with different requirements need to | ||
284 | * implement their own enum_frame_size handlers. | ||
285 | * | ||
286 | * Return: 0 if the media bus frame size is found, or -EINVAL | ||
287 | * if the index or the code is not valid. | ||
288 | */ | ||
289 | int xvip_enum_frame_size(struct v4l2_subdev *subdev, | ||
290 | struct v4l2_subdev_pad_config *cfg, | ||
291 | struct v4l2_subdev_frame_size_enum *fse) | ||
292 | { | ||
293 | struct v4l2_mbus_framefmt *format; | ||
294 | |||
295 | /* Enumerating frame sizes based on the active configuration isn't | ||
296 | * supported yet. | ||
297 | */ | ||
298 | if (fse->which == V4L2_SUBDEV_FORMAT_ACTIVE) | ||
299 | return -EINVAL; | ||
300 | |||
301 | format = v4l2_subdev_get_try_format(subdev, cfg, fse->pad); | ||
302 | |||
303 | if (fse->index || fse->code != format->code) | ||
304 | return -EINVAL; | ||
305 | |||
306 | if (fse->pad == XVIP_PAD_SINK) { | ||
307 | fse->min_width = XVIP_MIN_WIDTH; | ||
308 | fse->max_width = XVIP_MAX_WIDTH; | ||
309 | fse->min_height = XVIP_MIN_HEIGHT; | ||
310 | fse->max_height = XVIP_MAX_HEIGHT; | ||
311 | } else { | ||
312 | /* The size on the source pad is fixed and always identical to | ||
313 | * the size on the sink pad. | ||
314 | */ | ||
315 | fse->min_width = format->width; | ||
316 | fse->max_width = format->width; | ||
317 | fse->min_height = format->height; | ||
318 | fse->max_height = format->height; | ||
319 | } | ||
320 | |||
321 | return 0; | ||
322 | } | ||
323 | EXPORT_SYMBOL_GPL(xvip_enum_frame_size); | ||
diff --git a/drivers/media/platform/xilinx/xilinx-vip.h b/drivers/media/platform/xilinx/xilinx-vip.h new file mode 100644 index 000000000000..42fee2026815 --- /dev/null +++ b/drivers/media/platform/xilinx/xilinx-vip.h | |||
@@ -0,0 +1,238 @@ | |||
1 | /* | ||
2 | * Xilinx Video IP Core | ||
3 | * | ||
4 | * Copyright (C) 2013-2015 Ideas on Board | ||
5 | * Copyright (C) 2013-2015 Xilinx, Inc. | ||
6 | * | ||
7 | * Contacts: Hyun Kwon <hyun.kwon@xilinx.com> | ||
8 | * Laurent Pinchart <laurent.pinchart@ideasonboard.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #ifndef __XILINX_VIP_H__ | ||
16 | #define __XILINX_VIP_H__ | ||
17 | |||
18 | #include <linux/io.h> | ||
19 | #include <media/v4l2-subdev.h> | ||
20 | |||
21 | struct clk; | ||
22 | |||
23 | /* | ||
24 | * Minimum and maximum width and height common to most video IP cores. IP | ||
25 | * cores with different requirements must define their own values. | ||
26 | */ | ||
27 | #define XVIP_MIN_WIDTH 32 | ||
28 | #define XVIP_MAX_WIDTH 7680 | ||
29 | #define XVIP_MIN_HEIGHT 32 | ||
30 | #define XVIP_MAX_HEIGHT 7680 | ||
31 | |||
32 | /* | ||
33 | * Pad IDs. IP cores with with multiple inputs or outputs should define | ||
34 | * their own values. | ||
35 | */ | ||
36 | #define XVIP_PAD_SINK 0 | ||
37 | #define XVIP_PAD_SOURCE 1 | ||
38 | |||
39 | /* Xilinx Video IP Control Registers */ | ||
40 | #define XVIP_CTRL_CONTROL 0x0000 | ||
41 | #define XVIP_CTRL_CONTROL_SW_ENABLE (1 << 0) | ||
42 | #define XVIP_CTRL_CONTROL_REG_UPDATE (1 << 1) | ||
43 | #define XVIP_CTRL_CONTROL_BYPASS (1 << 4) | ||
44 | #define XVIP_CTRL_CONTROL_TEST_PATTERN (1 << 5) | ||
45 | #define XVIP_CTRL_CONTROL_FRAME_SYNC_RESET (1 << 30) | ||
46 | #define XVIP_CTRL_CONTROL_SW_RESET (1 << 31) | ||
47 | #define XVIP_CTRL_STATUS 0x0004 | ||
48 | #define XVIP_CTRL_STATUS_PROC_STARTED (1 << 0) | ||
49 | #define XVIP_CTRL_STATUS_EOF (1 << 1) | ||
50 | #define XVIP_CTRL_ERROR 0x0008 | ||
51 | #define XVIP_CTRL_ERROR_SLAVE_EOL_EARLY (1 << 0) | ||
52 | #define XVIP_CTRL_ERROR_SLAVE_EOL_LATE (1 << 1) | ||
53 | #define XVIP_CTRL_ERROR_SLAVE_SOF_EARLY (1 << 2) | ||
54 | #define XVIP_CTRL_ERROR_SLAVE_SOF_LATE (1 << 3) | ||
55 | #define XVIP_CTRL_IRQ_ENABLE 0x000c | ||
56 | #define XVIP_CTRL_IRQ_ENABLE_PROC_STARTED (1 << 0) | ||
57 | #define XVIP_CTRL_IRQ_EOF (1 << 1) | ||
58 | #define XVIP_CTRL_VERSION 0x0010 | ||
59 | #define XVIP_CTRL_VERSION_MAJOR_MASK (0xff << 24) | ||
60 | #define XVIP_CTRL_VERSION_MAJOR_SHIFT 24 | ||
61 | #define XVIP_CTRL_VERSION_MINOR_MASK (0xff << 16) | ||
62 | #define XVIP_CTRL_VERSION_MINOR_SHIFT 16 | ||
63 | #define XVIP_CTRL_VERSION_REVISION_MASK (0xf << 12) | ||
64 | #define XVIP_CTRL_VERSION_REVISION_SHIFT 12 | ||
65 | #define XVIP_CTRL_VERSION_PATCH_MASK (0xf << 8) | ||
66 | #define XVIP_CTRL_VERSION_PATCH_SHIFT 8 | ||
67 | #define XVIP_CTRL_VERSION_INTERNAL_MASK (0xff << 0) | ||
68 | #define XVIP_CTRL_VERSION_INTERNAL_SHIFT 0 | ||
69 | |||
70 | /* Xilinx Video IP Timing Registers */ | ||
71 | #define XVIP_ACTIVE_SIZE 0x0020 | ||
72 | #define XVIP_ACTIVE_VSIZE_MASK (0x7ff << 16) | ||
73 | #define XVIP_ACTIVE_VSIZE_SHIFT 16 | ||
74 | #define XVIP_ACTIVE_HSIZE_MASK (0x7ff << 0) | ||
75 | #define XVIP_ACTIVE_HSIZE_SHIFT 0 | ||
76 | #define XVIP_ENCODING 0x0028 | ||
77 | #define XVIP_ENCODING_NBITS_8 (0 << 4) | ||
78 | #define XVIP_ENCODING_NBITS_10 (1 << 4) | ||
79 | #define XVIP_ENCODING_NBITS_12 (2 << 4) | ||
80 | #define XVIP_ENCODING_NBITS_16 (3 << 4) | ||
81 | #define XVIP_ENCODING_NBITS_MASK (3 << 4) | ||
82 | #define XVIP_ENCODING_NBITS_SHIFT 4 | ||
83 | #define XVIP_ENCODING_VIDEO_FORMAT_YUV422 (0 << 0) | ||
84 | #define XVIP_ENCODING_VIDEO_FORMAT_YUV444 (1 << 0) | ||
85 | #define XVIP_ENCODING_VIDEO_FORMAT_RGB (2 << 0) | ||
86 | #define XVIP_ENCODING_VIDEO_FORMAT_YUV420 (3 << 0) | ||
87 | #define XVIP_ENCODING_VIDEO_FORMAT_MASK (3 << 0) | ||
88 | #define XVIP_ENCODING_VIDEO_FORMAT_SHIFT 0 | ||
89 | |||
90 | /** | ||
91 | * struct xvip_device - Xilinx Video IP device structure | ||
92 | * @subdev: V4L2 subdevice | ||
93 | * @dev: (OF) device | ||
94 | * @iomem: device I/O register space remapped to kernel virtual memory | ||
95 | * @clk: video core clock | ||
96 | * @saved_ctrl: saved control register for resume / suspend | ||
97 | */ | ||
98 | struct xvip_device { | ||
99 | struct v4l2_subdev subdev; | ||
100 | struct device *dev; | ||
101 | void __iomem *iomem; | ||
102 | struct clk *clk; | ||
103 | u32 saved_ctrl; | ||
104 | }; | ||
105 | |||
106 | /** | ||
107 | * struct xvip_video_format - Xilinx Video IP video format description | ||
108 | * @vf_code: AXI4 video format code | ||
109 | * @width: AXI4 format width in bits per component | ||
110 | * @pattern: CFA pattern for Mono/Sensor formats | ||
111 | * @code: media bus format code | ||
112 | * @bpp: bytes per pixel (when stored in memory) | ||
113 | * @fourcc: V4L2 pixel format FCC identifier | ||
114 | * @description: format description, suitable for userspace | ||
115 | */ | ||
116 | struct xvip_video_format { | ||
117 | unsigned int vf_code; | ||
118 | unsigned int width; | ||
119 | const char *pattern; | ||
120 | unsigned int code; | ||
121 | unsigned int bpp; | ||
122 | u32 fourcc; | ||
123 | const char *description; | ||
124 | }; | ||
125 | |||
126 | const struct xvip_video_format *xvip_get_format_by_code(unsigned int code); | ||
127 | const struct xvip_video_format *xvip_get_format_by_fourcc(u32 fourcc); | ||
128 | const struct xvip_video_format *xvip_of_get_format(struct device_node *node); | ||
129 | void xvip_set_format_size(struct v4l2_mbus_framefmt *format, | ||
130 | const struct v4l2_subdev_format *fmt); | ||
131 | int xvip_enum_mbus_code(struct v4l2_subdev *subdev, | ||
132 | struct v4l2_subdev_pad_config *cfg, | ||
133 | struct v4l2_subdev_mbus_code_enum *code); | ||
134 | int xvip_enum_frame_size(struct v4l2_subdev *subdev, | ||
135 | struct v4l2_subdev_pad_config *cfg, | ||
136 | struct v4l2_subdev_frame_size_enum *fse); | ||
137 | |||
138 | static inline u32 xvip_read(struct xvip_device *xvip, u32 addr) | ||
139 | { | ||
140 | return ioread32(xvip->iomem + addr); | ||
141 | } | ||
142 | |||
143 | static inline void xvip_write(struct xvip_device *xvip, u32 addr, u32 value) | ||
144 | { | ||
145 | iowrite32(value, xvip->iomem + addr); | ||
146 | } | ||
147 | |||
148 | static inline void xvip_clr(struct xvip_device *xvip, u32 addr, u32 clr) | ||
149 | { | ||
150 | xvip_write(xvip, addr, xvip_read(xvip, addr) & ~clr); | ||
151 | } | ||
152 | |||
153 | static inline void xvip_set(struct xvip_device *xvip, u32 addr, u32 set) | ||
154 | { | ||
155 | xvip_write(xvip, addr, xvip_read(xvip, addr) | set); | ||
156 | } | ||
157 | |||
158 | void xvip_clr_or_set(struct xvip_device *xvip, u32 addr, u32 mask, bool set); | ||
159 | void xvip_clr_and_set(struct xvip_device *xvip, u32 addr, u32 clr, u32 set); | ||
160 | |||
161 | int xvip_init_resources(struct xvip_device *xvip); | ||
162 | void xvip_cleanup_resources(struct xvip_device *xvip); | ||
163 | |||
164 | static inline void xvip_reset(struct xvip_device *xvip) | ||
165 | { | ||
166 | xvip_write(xvip, XVIP_CTRL_CONTROL, XVIP_CTRL_CONTROL_SW_RESET); | ||
167 | } | ||
168 | |||
169 | static inline void xvip_start(struct xvip_device *xvip) | ||
170 | { | ||
171 | xvip_set(xvip, XVIP_CTRL_CONTROL, | ||
172 | XVIP_CTRL_CONTROL_SW_ENABLE | XVIP_CTRL_CONTROL_REG_UPDATE); | ||
173 | } | ||
174 | |||
175 | static inline void xvip_stop(struct xvip_device *xvip) | ||
176 | { | ||
177 | xvip_clr(xvip, XVIP_CTRL_CONTROL, XVIP_CTRL_CONTROL_SW_ENABLE); | ||
178 | } | ||
179 | |||
180 | static inline void xvip_resume(struct xvip_device *xvip) | ||
181 | { | ||
182 | xvip_write(xvip, XVIP_CTRL_CONTROL, | ||
183 | xvip->saved_ctrl | XVIP_CTRL_CONTROL_SW_ENABLE); | ||
184 | } | ||
185 | |||
186 | static inline void xvip_suspend(struct xvip_device *xvip) | ||
187 | { | ||
188 | xvip->saved_ctrl = xvip_read(xvip, XVIP_CTRL_CONTROL); | ||
189 | xvip_write(xvip, XVIP_CTRL_CONTROL, | ||
190 | xvip->saved_ctrl & ~XVIP_CTRL_CONTROL_SW_ENABLE); | ||
191 | } | ||
192 | |||
193 | static inline void xvip_set_frame_size(struct xvip_device *xvip, | ||
194 | const struct v4l2_mbus_framefmt *format) | ||
195 | { | ||
196 | xvip_write(xvip, XVIP_ACTIVE_SIZE, | ||
197 | (format->height << XVIP_ACTIVE_VSIZE_SHIFT) | | ||
198 | (format->width << XVIP_ACTIVE_HSIZE_SHIFT)); | ||
199 | } | ||
200 | |||
201 | static inline void xvip_get_frame_size(struct xvip_device *xvip, | ||
202 | struct v4l2_mbus_framefmt *format) | ||
203 | { | ||
204 | u32 reg; | ||
205 | |||
206 | reg = xvip_read(xvip, XVIP_ACTIVE_SIZE); | ||
207 | format->width = (reg & XVIP_ACTIVE_HSIZE_MASK) >> | ||
208 | XVIP_ACTIVE_HSIZE_SHIFT; | ||
209 | format->height = (reg & XVIP_ACTIVE_VSIZE_MASK) >> | ||
210 | XVIP_ACTIVE_VSIZE_SHIFT; | ||
211 | } | ||
212 | |||
213 | static inline void xvip_enable_reg_update(struct xvip_device *xvip) | ||
214 | { | ||
215 | xvip_set(xvip, XVIP_CTRL_CONTROL, XVIP_CTRL_CONTROL_REG_UPDATE); | ||
216 | } | ||
217 | |||
218 | static inline void xvip_disable_reg_update(struct xvip_device *xvip) | ||
219 | { | ||
220 | xvip_clr(xvip, XVIP_CTRL_CONTROL, XVIP_CTRL_CONTROL_REG_UPDATE); | ||
221 | } | ||
222 | |||
223 | static inline void xvip_print_version(struct xvip_device *xvip) | ||
224 | { | ||
225 | u32 version; | ||
226 | |||
227 | version = xvip_read(xvip, XVIP_CTRL_VERSION); | ||
228 | |||
229 | dev_info(xvip->dev, "device found, version %u.%02x%x\n", | ||
230 | ((version & XVIP_CTRL_VERSION_MAJOR_MASK) >> | ||
231 | XVIP_CTRL_VERSION_MAJOR_SHIFT), | ||
232 | ((version & XVIP_CTRL_VERSION_MINOR_MASK) >> | ||
233 | XVIP_CTRL_VERSION_MINOR_SHIFT), | ||
234 | ((version & XVIP_CTRL_VERSION_REVISION_MASK) >> | ||
235 | XVIP_CTRL_VERSION_REVISION_SHIFT)); | ||
236 | } | ||
237 | |||
238 | #endif /* __XILINX_VIP_H__ */ | ||
diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c new file mode 100644 index 000000000000..7b7cb9c28d2c --- /dev/null +++ b/drivers/media/platform/xilinx/xilinx-vipp.c | |||
@@ -0,0 +1,669 @@ | |||
1 | /* | ||
2 | * Xilinx Video IP Composite Device | ||
3 | * | ||
4 | * Copyright (C) 2013-2015 Ideas on Board | ||
5 | * Copyright (C) 2013-2015 Xilinx, Inc. | ||
6 | * | ||
7 | * Contacts: Hyun Kwon <hyun.kwon@xilinx.com> | ||
8 | * Laurent Pinchart <laurent.pinchart@ideasonboard.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include <linux/list.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/of.h> | ||
18 | #include <linux/of_graph.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/slab.h> | ||
21 | |||
22 | #include <media/v4l2-async.h> | ||
23 | #include <media/v4l2-common.h> | ||
24 | #include <media/v4l2-device.h> | ||
25 | #include <media/v4l2-of.h> | ||
26 | |||
27 | #include "xilinx-dma.h" | ||
28 | #include "xilinx-vipp.h" | ||
29 | |||
30 | #define XVIPP_DMA_S2MM 0 | ||
31 | #define XVIPP_DMA_MM2S 1 | ||
32 | |||
33 | /** | ||
34 | * struct xvip_graph_entity - Entity in the video graph | ||
35 | * @list: list entry in a graph entities list | ||
36 | * @node: the entity's DT node | ||
37 | * @entity: media entity, from the corresponding V4L2 subdev | ||
38 | * @asd: subdev asynchronous registration information | ||
39 | * @subdev: V4L2 subdev | ||
40 | */ | ||
41 | struct xvip_graph_entity { | ||
42 | struct list_head list; | ||
43 | struct device_node *node; | ||
44 | struct media_entity *entity; | ||
45 | |||
46 | struct v4l2_async_subdev asd; | ||
47 | struct v4l2_subdev *subdev; | ||
48 | }; | ||
49 | |||
50 | /* ----------------------------------------------------------------------------- | ||
51 | * Graph Management | ||
52 | */ | ||
53 | |||
54 | static struct xvip_graph_entity * | ||
55 | xvip_graph_find_entity(struct xvip_composite_device *xdev, | ||
56 | const struct device_node *node) | ||
57 | { | ||
58 | struct xvip_graph_entity *entity; | ||
59 | |||
60 | list_for_each_entry(entity, &xdev->entities, list) { | ||
61 | if (entity->node == node) | ||
62 | return entity; | ||
63 | } | ||
64 | |||
65 | return NULL; | ||
66 | } | ||
67 | |||
68 | static int xvip_graph_build_one(struct xvip_composite_device *xdev, | ||
69 | struct xvip_graph_entity *entity) | ||
70 | { | ||
71 | u32 link_flags = MEDIA_LNK_FL_ENABLED; | ||
72 | struct media_entity *local = entity->entity; | ||
73 | struct media_entity *remote; | ||
74 | struct media_pad *local_pad; | ||
75 | struct media_pad *remote_pad; | ||
76 | struct xvip_graph_entity *ent; | ||
77 | struct v4l2_of_link link; | ||
78 | struct device_node *ep = NULL; | ||
79 | struct device_node *next; | ||
80 | int ret = 0; | ||
81 | |||
82 | dev_dbg(xdev->dev, "creating links for entity %s\n", local->name); | ||
83 | |||
84 | while (1) { | ||
85 | /* Get the next endpoint and parse its link. */ | ||
86 | next = of_graph_get_next_endpoint(entity->node, ep); | ||
87 | if (next == NULL) | ||
88 | break; | ||
89 | |||
90 | of_node_put(ep); | ||
91 | ep = next; | ||
92 | |||
93 | dev_dbg(xdev->dev, "processing endpoint %s\n", ep->full_name); | ||
94 | |||
95 | ret = v4l2_of_parse_link(ep, &link); | ||
96 | if (ret < 0) { | ||
97 | dev_err(xdev->dev, "failed to parse link for %s\n", | ||
98 | ep->full_name); | ||
99 | continue; | ||
100 | } | ||
101 | |||
102 | /* Skip sink ports, they will be processed from the other end of | ||
103 | * the link. | ||
104 | */ | ||
105 | if (link.local_port >= local->num_pads) { | ||
106 | dev_err(xdev->dev, "invalid port number %u on %s\n", | ||
107 | link.local_port, link.local_node->full_name); | ||
108 | v4l2_of_put_link(&link); | ||
109 | ret = -EINVAL; | ||
110 | break; | ||
111 | } | ||
112 | |||
113 | local_pad = &local->pads[link.local_port]; | ||
114 | |||
115 | if (local_pad->flags & MEDIA_PAD_FL_SINK) { | ||
116 | dev_dbg(xdev->dev, "skipping sink port %s:%u\n", | ||
117 | link.local_node->full_name, link.local_port); | ||
118 | v4l2_of_put_link(&link); | ||
119 | continue; | ||
120 | } | ||
121 | |||
122 | /* Skip DMA engines, they will be processed separately. */ | ||
123 | if (link.remote_node == xdev->dev->of_node) { | ||
124 | dev_dbg(xdev->dev, "skipping DMA port %s:%u\n", | ||
125 | link.local_node->full_name, link.local_port); | ||
126 | v4l2_of_put_link(&link); | ||
127 | continue; | ||
128 | } | ||
129 | |||
130 | /* Find the remote entity. */ | ||
131 | ent = xvip_graph_find_entity(xdev, link.remote_node); | ||
132 | if (ent == NULL) { | ||
133 | dev_err(xdev->dev, "no entity found for %s\n", | ||
134 | link.remote_node->full_name); | ||
135 | v4l2_of_put_link(&link); | ||
136 | ret = -ENODEV; | ||
137 | break; | ||
138 | } | ||
139 | |||
140 | remote = ent->entity; | ||
141 | |||
142 | if (link.remote_port >= remote->num_pads) { | ||
143 | dev_err(xdev->dev, "invalid port number %u on %s\n", | ||
144 | link.remote_port, link.remote_node->full_name); | ||
145 | v4l2_of_put_link(&link); | ||
146 | ret = -EINVAL; | ||
147 | break; | ||
148 | } | ||
149 | |||
150 | remote_pad = &remote->pads[link.remote_port]; | ||
151 | |||
152 | v4l2_of_put_link(&link); | ||
153 | |||
154 | /* Create the media link. */ | ||
155 | dev_dbg(xdev->dev, "creating %s:%u -> %s:%u link\n", | ||
156 | local->name, local_pad->index, | ||
157 | remote->name, remote_pad->index); | ||
158 | |||
159 | ret = media_entity_create_link(local, local_pad->index, | ||
160 | remote, remote_pad->index, | ||
161 | link_flags); | ||
162 | if (ret < 0) { | ||
163 | dev_err(xdev->dev, | ||
164 | "failed to create %s:%u -> %s:%u link\n", | ||
165 | local->name, local_pad->index, | ||
166 | remote->name, remote_pad->index); | ||
167 | break; | ||
168 | } | ||
169 | } | ||
170 | |||
171 | of_node_put(ep); | ||
172 | return ret; | ||
173 | } | ||
174 | |||
175 | static struct xvip_dma * | ||
176 | xvip_graph_find_dma(struct xvip_composite_device *xdev, unsigned int port) | ||
177 | { | ||
178 | struct xvip_dma *dma; | ||
179 | |||
180 | list_for_each_entry(dma, &xdev->dmas, list) { | ||
181 | if (dma->port == port) | ||
182 | return dma; | ||
183 | } | ||
184 | |||
185 | return NULL; | ||
186 | } | ||
187 | |||
188 | static int xvip_graph_build_dma(struct xvip_composite_device *xdev) | ||
189 | { | ||
190 | u32 link_flags = MEDIA_LNK_FL_ENABLED; | ||
191 | struct device_node *node = xdev->dev->of_node; | ||
192 | struct media_entity *source; | ||
193 | struct media_entity *sink; | ||
194 | struct media_pad *source_pad; | ||
195 | struct media_pad *sink_pad; | ||
196 | struct xvip_graph_entity *ent; | ||
197 | struct v4l2_of_link link; | ||
198 | struct device_node *ep = NULL; | ||
199 | struct device_node *next; | ||
200 | struct xvip_dma *dma; | ||
201 | int ret = 0; | ||
202 | |||
203 | dev_dbg(xdev->dev, "creating links for DMA engines\n"); | ||
204 | |||
205 | while (1) { | ||
206 | /* Get the next endpoint and parse its link. */ | ||
207 | next = of_graph_get_next_endpoint(node, ep); | ||
208 | if (next == NULL) | ||
209 | break; | ||
210 | |||
211 | of_node_put(ep); | ||
212 | ep = next; | ||
213 | |||
214 | dev_dbg(xdev->dev, "processing endpoint %s\n", ep->full_name); | ||
215 | |||
216 | ret = v4l2_of_parse_link(ep, &link); | ||
217 | if (ret < 0) { | ||
218 | dev_err(xdev->dev, "failed to parse link for %s\n", | ||
219 | ep->full_name); | ||
220 | continue; | ||
221 | } | ||
222 | |||
223 | /* Find the DMA engine. */ | ||
224 | dma = xvip_graph_find_dma(xdev, link.local_port); | ||
225 | if (dma == NULL) { | ||
226 | dev_err(xdev->dev, "no DMA engine found for port %u\n", | ||
227 | link.local_port); | ||
228 | v4l2_of_put_link(&link); | ||
229 | ret = -EINVAL; | ||
230 | break; | ||
231 | } | ||
232 | |||
233 | dev_dbg(xdev->dev, "creating link for DMA engine %s\n", | ||
234 | dma->video.name); | ||
235 | |||
236 | /* Find the remote entity. */ | ||
237 | ent = xvip_graph_find_entity(xdev, link.remote_node); | ||
238 | if (ent == NULL) { | ||
239 | dev_err(xdev->dev, "no entity found for %s\n", | ||
240 | link.remote_node->full_name); | ||
241 | v4l2_of_put_link(&link); | ||
242 | ret = -ENODEV; | ||
243 | break; | ||
244 | } | ||
245 | |||
246 | if (link.remote_port >= ent->entity->num_pads) { | ||
247 | dev_err(xdev->dev, "invalid port number %u on %s\n", | ||
248 | link.remote_port, link.remote_node->full_name); | ||
249 | v4l2_of_put_link(&link); | ||
250 | ret = -EINVAL; | ||
251 | break; | ||
252 | } | ||
253 | |||
254 | if (dma->pad.flags & MEDIA_PAD_FL_SOURCE) { | ||
255 | source = &dma->video.entity; | ||
256 | source_pad = &dma->pad; | ||
257 | sink = ent->entity; | ||
258 | sink_pad = &sink->pads[link.remote_port]; | ||
259 | } else { | ||
260 | source = ent->entity; | ||
261 | source_pad = &source->pads[link.remote_port]; | ||
262 | sink = &dma->video.entity; | ||
263 | sink_pad = &dma->pad; | ||
264 | } | ||
265 | |||
266 | v4l2_of_put_link(&link); | ||
267 | |||
268 | /* Create the media link. */ | ||
269 | dev_dbg(xdev->dev, "creating %s:%u -> %s:%u link\n", | ||
270 | source->name, source_pad->index, | ||
271 | sink->name, sink_pad->index); | ||
272 | |||
273 | ret = media_entity_create_link(source, source_pad->index, | ||
274 | sink, sink_pad->index, | ||
275 | link_flags); | ||
276 | if (ret < 0) { | ||
277 | dev_err(xdev->dev, | ||
278 | "failed to create %s:%u -> %s:%u link\n", | ||
279 | source->name, source_pad->index, | ||
280 | sink->name, sink_pad->index); | ||
281 | break; | ||
282 | } | ||
283 | } | ||
284 | |||
285 | of_node_put(ep); | ||
286 | return ret; | ||
287 | } | ||
288 | |||
289 | static int xvip_graph_notify_complete(struct v4l2_async_notifier *notifier) | ||
290 | { | ||
291 | struct xvip_composite_device *xdev = | ||
292 | container_of(notifier, struct xvip_composite_device, notifier); | ||
293 | struct xvip_graph_entity *entity; | ||
294 | int ret; | ||
295 | |||
296 | dev_dbg(xdev->dev, "notify complete, all subdevs registered\n"); | ||
297 | |||
298 | /* Create links for every entity. */ | ||
299 | list_for_each_entry(entity, &xdev->entities, list) { | ||
300 | ret = xvip_graph_build_one(xdev, entity); | ||
301 | if (ret < 0) | ||
302 | return ret; | ||
303 | } | ||
304 | |||
305 | /* Create links for DMA channels. */ | ||
306 | ret = xvip_graph_build_dma(xdev); | ||
307 | if (ret < 0) | ||
308 | return ret; | ||
309 | |||
310 | ret = v4l2_device_register_subdev_nodes(&xdev->v4l2_dev); | ||
311 | if (ret < 0) | ||
312 | dev_err(xdev->dev, "failed to register subdev nodes\n"); | ||
313 | |||
314 | return ret; | ||
315 | } | ||
316 | |||
317 | static int xvip_graph_notify_bound(struct v4l2_async_notifier *notifier, | ||
318 | struct v4l2_subdev *subdev, | ||
319 | struct v4l2_async_subdev *asd) | ||
320 | { | ||
321 | struct xvip_composite_device *xdev = | ||
322 | container_of(notifier, struct xvip_composite_device, notifier); | ||
323 | struct xvip_graph_entity *entity; | ||
324 | |||
325 | /* Locate the entity corresponding to the bound subdev and store the | ||
326 | * subdev pointer. | ||
327 | */ | ||
328 | list_for_each_entry(entity, &xdev->entities, list) { | ||
329 | if (entity->node != subdev->dev->of_node) | ||
330 | continue; | ||
331 | |||
332 | if (entity->subdev) { | ||
333 | dev_err(xdev->dev, "duplicate subdev for node %s\n", | ||
334 | entity->node->full_name); | ||
335 | return -EINVAL; | ||
336 | } | ||
337 | |||
338 | dev_dbg(xdev->dev, "subdev %s bound\n", subdev->name); | ||
339 | entity->entity = &subdev->entity; | ||
340 | entity->subdev = subdev; | ||
341 | return 0; | ||
342 | } | ||
343 | |||
344 | dev_err(xdev->dev, "no entity for subdev %s\n", subdev->name); | ||
345 | return -EINVAL; | ||
346 | } | ||
347 | |||
348 | static int xvip_graph_parse_one(struct xvip_composite_device *xdev, | ||
349 | struct device_node *node) | ||
350 | { | ||
351 | struct xvip_graph_entity *entity; | ||
352 | struct device_node *remote; | ||
353 | struct device_node *ep = NULL; | ||
354 | struct device_node *next; | ||
355 | int ret = 0; | ||
356 | |||
357 | dev_dbg(xdev->dev, "parsing node %s\n", node->full_name); | ||
358 | |||
359 | while (1) { | ||
360 | next = of_graph_get_next_endpoint(node, ep); | ||
361 | if (next == NULL) | ||
362 | break; | ||
363 | |||
364 | of_node_put(ep); | ||
365 | ep = next; | ||
366 | |||
367 | dev_dbg(xdev->dev, "handling endpoint %s\n", ep->full_name); | ||
368 | |||
369 | remote = of_graph_get_remote_port_parent(ep); | ||
370 | if (remote == NULL) { | ||
371 | ret = -EINVAL; | ||
372 | break; | ||
373 | } | ||
374 | |||
375 | /* Skip entities that we have already processed. */ | ||
376 | if (remote == xdev->dev->of_node || | ||
377 | xvip_graph_find_entity(xdev, remote)) { | ||
378 | of_node_put(remote); | ||
379 | continue; | ||
380 | } | ||
381 | |||
382 | entity = devm_kzalloc(xdev->dev, sizeof(*entity), GFP_KERNEL); | ||
383 | if (entity == NULL) { | ||
384 | of_node_put(remote); | ||
385 | ret = -ENOMEM; | ||
386 | break; | ||
387 | } | ||
388 | |||
389 | entity->node = remote; | ||
390 | entity->asd.match_type = V4L2_ASYNC_MATCH_OF; | ||
391 | entity->asd.match.of.node = remote; | ||
392 | list_add_tail(&entity->list, &xdev->entities); | ||
393 | xdev->num_subdevs++; | ||
394 | } | ||
395 | |||
396 | of_node_put(ep); | ||
397 | return ret; | ||
398 | } | ||
399 | |||
400 | static int xvip_graph_parse(struct xvip_composite_device *xdev) | ||
401 | { | ||
402 | struct xvip_graph_entity *entity; | ||
403 | int ret; | ||
404 | |||
405 | /* | ||
406 | * Walk the links to parse the full graph. Start by parsing the | ||
407 | * composite node and then parse entities in turn. The list_for_each | ||
408 | * loop will handle entities added at the end of the list while walking | ||
409 | * the links. | ||
410 | */ | ||
411 | ret = xvip_graph_parse_one(xdev, xdev->dev->of_node); | ||
412 | if (ret < 0) | ||
413 | return 0; | ||
414 | |||
415 | list_for_each_entry(entity, &xdev->entities, list) { | ||
416 | ret = xvip_graph_parse_one(xdev, entity->node); | ||
417 | if (ret < 0) | ||
418 | break; | ||
419 | } | ||
420 | |||
421 | return ret; | ||
422 | } | ||
423 | |||
424 | static int xvip_graph_dma_init_one(struct xvip_composite_device *xdev, | ||
425 | struct device_node *node) | ||
426 | { | ||
427 | struct xvip_dma *dma; | ||
428 | enum v4l2_buf_type type; | ||
429 | const char *direction; | ||
430 | unsigned int index; | ||
431 | int ret; | ||
432 | |||
433 | ret = of_property_read_string(node, "direction", &direction); | ||
434 | if (ret < 0) | ||
435 | return ret; | ||
436 | |||
437 | if (strcmp(direction, "input") == 0) | ||
438 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
439 | else if (strcmp(direction, "output") == 0) | ||
440 | type = V4L2_BUF_TYPE_VIDEO_OUTPUT; | ||
441 | else | ||
442 | return -EINVAL; | ||
443 | |||
444 | of_property_read_u32(node, "reg", &index); | ||
445 | |||
446 | dma = devm_kzalloc(xdev->dev, sizeof(*dma), GFP_KERNEL); | ||
447 | if (dma == NULL) | ||
448 | return -ENOMEM; | ||
449 | |||
450 | ret = xvip_dma_init(xdev, dma, type, index); | ||
451 | if (ret < 0) { | ||
452 | dev_err(xdev->dev, "%s initialization failed\n", | ||
453 | node->full_name); | ||
454 | return ret; | ||
455 | } | ||
456 | |||
457 | list_add_tail(&dma->list, &xdev->dmas); | ||
458 | |||
459 | xdev->v4l2_caps |= type == V4L2_BUF_TYPE_VIDEO_CAPTURE | ||
460 | ? V4L2_CAP_VIDEO_CAPTURE : V4L2_CAP_VIDEO_OUTPUT; | ||
461 | |||
462 | return 0; | ||
463 | } | ||
464 | |||
465 | static int xvip_graph_dma_init(struct xvip_composite_device *xdev) | ||
466 | { | ||
467 | struct device_node *ports; | ||
468 | struct device_node *port; | ||
469 | int ret; | ||
470 | |||
471 | ports = of_get_child_by_name(xdev->dev->of_node, "ports"); | ||
472 | if (ports == NULL) { | ||
473 | dev_err(xdev->dev, "ports node not present\n"); | ||
474 | return -EINVAL; | ||
475 | } | ||
476 | |||
477 | for_each_child_of_node(ports, port) { | ||
478 | ret = xvip_graph_dma_init_one(xdev, port); | ||
479 | if (ret < 0) | ||
480 | return ret; | ||
481 | } | ||
482 | |||
483 | return 0; | ||
484 | } | ||
485 | |||
486 | static void xvip_graph_cleanup(struct xvip_composite_device *xdev) | ||
487 | { | ||
488 | struct xvip_graph_entity *entityp; | ||
489 | struct xvip_graph_entity *entity; | ||
490 | struct xvip_dma *dmap; | ||
491 | struct xvip_dma *dma; | ||
492 | |||
493 | v4l2_async_notifier_unregister(&xdev->notifier); | ||
494 | |||
495 | list_for_each_entry_safe(entity, entityp, &xdev->entities, list) { | ||
496 | of_node_put(entity->node); | ||
497 | list_del(&entity->list); | ||
498 | } | ||
499 | |||
500 | list_for_each_entry_safe(dma, dmap, &xdev->dmas, list) { | ||
501 | xvip_dma_cleanup(dma); | ||
502 | list_del(&dma->list); | ||
503 | } | ||
504 | } | ||
505 | |||
506 | static int xvip_graph_init(struct xvip_composite_device *xdev) | ||
507 | { | ||
508 | struct xvip_graph_entity *entity; | ||
509 | struct v4l2_async_subdev **subdevs = NULL; | ||
510 | unsigned int num_subdevs; | ||
511 | unsigned int i; | ||
512 | int ret; | ||
513 | |||
514 | /* Init the DMA channels. */ | ||
515 | ret = xvip_graph_dma_init(xdev); | ||
516 | if (ret < 0) { | ||
517 | dev_err(xdev->dev, "DMA initialization failed\n"); | ||
518 | goto done; | ||
519 | } | ||
520 | |||
521 | /* Parse the graph to extract a list of subdevice DT nodes. */ | ||
522 | ret = xvip_graph_parse(xdev); | ||
523 | if (ret < 0) { | ||
524 | dev_err(xdev->dev, "graph parsing failed\n"); | ||
525 | goto done; | ||
526 | } | ||
527 | |||
528 | if (!xdev->num_subdevs) { | ||
529 | dev_err(xdev->dev, "no subdev found in graph\n"); | ||
530 | goto done; | ||
531 | } | ||
532 | |||
533 | /* Register the subdevices notifier. */ | ||
534 | num_subdevs = xdev->num_subdevs; | ||
535 | subdevs = devm_kzalloc(xdev->dev, sizeof(*subdevs) * num_subdevs, | ||
536 | GFP_KERNEL); | ||
537 | if (subdevs == NULL) { | ||
538 | ret = -ENOMEM; | ||
539 | goto done; | ||
540 | } | ||
541 | |||
542 | i = 0; | ||
543 | list_for_each_entry(entity, &xdev->entities, list) | ||
544 | subdevs[i++] = &entity->asd; | ||
545 | |||
546 | xdev->notifier.subdevs = subdevs; | ||
547 | xdev->notifier.num_subdevs = num_subdevs; | ||
548 | xdev->notifier.bound = xvip_graph_notify_bound; | ||
549 | xdev->notifier.complete = xvip_graph_notify_complete; | ||
550 | |||
551 | ret = v4l2_async_notifier_register(&xdev->v4l2_dev, &xdev->notifier); | ||
552 | if (ret < 0) { | ||
553 | dev_err(xdev->dev, "notifier registration failed\n"); | ||
554 | goto done; | ||
555 | } | ||
556 | |||
557 | ret = 0; | ||
558 | |||
559 | done: | ||
560 | if (ret < 0) | ||
561 | xvip_graph_cleanup(xdev); | ||
562 | |||
563 | return ret; | ||
564 | } | ||
565 | |||
566 | /* ----------------------------------------------------------------------------- | ||
567 | * Media Controller and V4L2 | ||
568 | */ | ||
569 | |||
570 | static void xvip_composite_v4l2_cleanup(struct xvip_composite_device *xdev) | ||
571 | { | ||
572 | v4l2_device_unregister(&xdev->v4l2_dev); | ||
573 | media_device_unregister(&xdev->media_dev); | ||
574 | } | ||
575 | |||
576 | static int xvip_composite_v4l2_init(struct xvip_composite_device *xdev) | ||
577 | { | ||
578 | int ret; | ||
579 | |||
580 | xdev->media_dev.dev = xdev->dev; | ||
581 | strlcpy(xdev->media_dev.model, "Xilinx Video Composite Device", | ||
582 | sizeof(xdev->media_dev.model)); | ||
583 | xdev->media_dev.hw_revision = 0; | ||
584 | |||
585 | ret = media_device_register(&xdev->media_dev); | ||
586 | if (ret < 0) { | ||
587 | dev_err(xdev->dev, "media device registration failed (%d)\n", | ||
588 | ret); | ||
589 | return ret; | ||
590 | } | ||
591 | |||
592 | xdev->v4l2_dev.mdev = &xdev->media_dev; | ||
593 | ret = v4l2_device_register(xdev->dev, &xdev->v4l2_dev); | ||
594 | if (ret < 0) { | ||
595 | dev_err(xdev->dev, "V4L2 device registration failed (%d)\n", | ||
596 | ret); | ||
597 | media_device_unregister(&xdev->media_dev); | ||
598 | return ret; | ||
599 | } | ||
600 | |||
601 | return 0; | ||
602 | } | ||
603 | |||
604 | /* ----------------------------------------------------------------------------- | ||
605 | * Platform Device Driver | ||
606 | */ | ||
607 | |||
608 | static int xvip_composite_probe(struct platform_device *pdev) | ||
609 | { | ||
610 | struct xvip_composite_device *xdev; | ||
611 | int ret; | ||
612 | |||
613 | xdev = devm_kzalloc(&pdev->dev, sizeof(*xdev), GFP_KERNEL); | ||
614 | if (!xdev) | ||
615 | return -ENOMEM; | ||
616 | |||
617 | xdev->dev = &pdev->dev; | ||
618 | INIT_LIST_HEAD(&xdev->entities); | ||
619 | INIT_LIST_HEAD(&xdev->dmas); | ||
620 | |||
621 | ret = xvip_composite_v4l2_init(xdev); | ||
622 | if (ret < 0) | ||
623 | return ret; | ||
624 | |||
625 | ret = xvip_graph_init(xdev); | ||
626 | if (ret < 0) | ||
627 | goto error; | ||
628 | |||
629 | platform_set_drvdata(pdev, xdev); | ||
630 | |||
631 | dev_info(xdev->dev, "device registered\n"); | ||
632 | |||
633 | return 0; | ||
634 | |||
635 | error: | ||
636 | xvip_composite_v4l2_cleanup(xdev); | ||
637 | return ret; | ||
638 | } | ||
639 | |||
640 | static int xvip_composite_remove(struct platform_device *pdev) | ||
641 | { | ||
642 | struct xvip_composite_device *xdev = platform_get_drvdata(pdev); | ||
643 | |||
644 | xvip_graph_cleanup(xdev); | ||
645 | xvip_composite_v4l2_cleanup(xdev); | ||
646 | |||
647 | return 0; | ||
648 | } | ||
649 | |||
650 | static const struct of_device_id xvip_composite_of_id_table[] = { | ||
651 | { .compatible = "xlnx,video" }, | ||
652 | { } | ||
653 | }; | ||
654 | MODULE_DEVICE_TABLE(of, xvip_composite_of_id_table); | ||
655 | |||
656 | static struct platform_driver xvip_composite_driver = { | ||
657 | .driver = { | ||
658 | .name = "xilinx-video", | ||
659 | .of_match_table = xvip_composite_of_id_table, | ||
660 | }, | ||
661 | .probe = xvip_composite_probe, | ||
662 | .remove = xvip_composite_remove, | ||
663 | }; | ||
664 | |||
665 | module_platform_driver(xvip_composite_driver); | ||
666 | |||
667 | MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>"); | ||
668 | MODULE_DESCRIPTION("Xilinx Video IP Composite Driver"); | ||
669 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/media/platform/xilinx/xilinx-vipp.h b/drivers/media/platform/xilinx/xilinx-vipp.h new file mode 100644 index 000000000000..faf6b6e80b3b --- /dev/null +++ b/drivers/media/platform/xilinx/xilinx-vipp.h | |||
@@ -0,0 +1,49 @@ | |||
1 | /* | ||
2 | * Xilinx Video IP Composite Device | ||
3 | * | ||
4 | * Copyright (C) 2013-2015 Ideas on Board | ||
5 | * Copyright (C) 2013-2015 Xilinx, Inc. | ||
6 | * | ||
7 | * Contacts: Hyun Kwon <hyun.kwon@xilinx.com> | ||
8 | * Laurent Pinchart <laurent.pinchart@ideasonboard.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #ifndef __XILINX_VIPP_H__ | ||
16 | #define __XILINX_VIPP_H__ | ||
17 | |||
18 | #include <linux/list.h> | ||
19 | #include <linux/mutex.h> | ||
20 | #include <media/media-device.h> | ||
21 | #include <media/v4l2-async.h> | ||
22 | #include <media/v4l2-ctrls.h> | ||
23 | #include <media/v4l2-device.h> | ||
24 | |||
25 | /** | ||
26 | * struct xvip_composite_device - Xilinx Video IP device structure | ||
27 | * @v4l2_dev: V4L2 device | ||
28 | * @media_dev: media device | ||
29 | * @dev: (OF) device | ||
30 | * @notifier: V4L2 asynchronous subdevs notifier | ||
31 | * @entities: entities in the graph as a list of xvip_graph_entity | ||
32 | * @num_subdevs: number of subdevs in the pipeline | ||
33 | * @dmas: list of DMA channels at the pipeline output and input | ||
34 | * @v4l2_caps: V4L2 capabilities of the whole device (see VIDIOC_QUERYCAP) | ||
35 | */ | ||
36 | struct xvip_composite_device { | ||
37 | struct v4l2_device v4l2_dev; | ||
38 | struct media_device media_dev; | ||
39 | struct device *dev; | ||
40 | |||
41 | struct v4l2_async_notifier notifier; | ||
42 | struct list_head entities; | ||
43 | unsigned int num_subdevs; | ||
44 | |||
45 | struct list_head dmas; | ||
46 | u32 v4l2_caps; | ||
47 | }; | ||
48 | |||
49 | #endif /* __XILINX_VIPP_H__ */ | ||
diff --git a/drivers/media/platform/xilinx/xilinx-vtc.c b/drivers/media/platform/xilinx/xilinx-vtc.c new file mode 100644 index 000000000000..01c750edcac5 --- /dev/null +++ b/drivers/media/platform/xilinx/xilinx-vtc.c | |||
@@ -0,0 +1,380 @@ | |||
1 | /* | ||
2 | * Xilinx Video Timing Controller | ||
3 | * | ||
4 | * Copyright (C) 2013-2015 Ideas on Board | ||
5 | * Copyright (C) 2013-2015 Xilinx, Inc. | ||
6 | * | ||
7 | * Contacts: Hyun Kwon <hyun.kwon@xilinx.com> | ||
8 | * Laurent Pinchart <laurent.pinchart@ideasonboard.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include <linux/clk.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/of.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/slab.h> | ||
20 | |||
21 | #include "xilinx-vip.h" | ||
22 | #include "xilinx-vtc.h" | ||
23 | |||
24 | #define XVTC_CONTROL_FIELD_ID_POL_SRC (1 << 26) | ||
25 | #define XVTC_CONTROL_ACTIVE_CHROMA_POL_SRC (1 << 25) | ||
26 | #define XVTC_CONTROL_ACTIVE_VIDEO_POL_SRC (1 << 24) | ||
27 | #define XVTC_CONTROL_HSYNC_POL_SRC (1 << 23) | ||
28 | #define XVTC_CONTROL_VSYNC_POL_SRC (1 << 22) | ||
29 | #define XVTC_CONTROL_HBLANK_POL_SRC (1 << 21) | ||
30 | #define XVTC_CONTROL_VBLANK_POL_SRC (1 << 20) | ||
31 | #define XVTC_CONTROL_CHROMA_SRC (1 << 18) | ||
32 | #define XVTC_CONTROL_VBLANK_HOFF_SRC (1 << 17) | ||
33 | #define XVTC_CONTROL_VSYNC_END_SRC (1 << 16) | ||
34 | #define XVTC_CONTROL_VSYNC_START_SRC (1 << 15) | ||
35 | #define XVTC_CONTROL_ACTIVE_VSIZE_SRC (1 << 14) | ||
36 | #define XVTC_CONTROL_FRAME_VSIZE_SRC (1 << 13) | ||
37 | #define XVTC_CONTROL_HSYNC_END_SRC (1 << 11) | ||
38 | #define XVTC_CONTROL_HSYNC_START_SRC (1 << 10) | ||
39 | #define XVTC_CONTROL_ACTIVE_HSIZE_SRC (1 << 9) | ||
40 | #define XVTC_CONTROL_FRAME_HSIZE_SRC (1 << 8) | ||
41 | #define XVTC_CONTROL_SYNC_ENABLE (1 << 5) | ||
42 | #define XVTC_CONTROL_DET_ENABLE (1 << 3) | ||
43 | #define XVTC_CONTROL_GEN_ENABLE (1 << 2) | ||
44 | |||
45 | #define XVTC_STATUS_FSYNC(n) ((n) << 16) | ||
46 | #define XVTC_STATUS_GEN_ACTIVE_VIDEO (1 << 13) | ||
47 | #define XVTC_STATUS_GEN_VBLANK (1 << 12) | ||
48 | #define XVTC_STATUS_DET_ACTIVE_VIDEO (1 << 11) | ||
49 | #define XVTC_STATUS_DET_VBLANK (1 << 10) | ||
50 | #define XVTC_STATUS_LOCK_LOSS (1 << 9) | ||
51 | #define XVTC_STATUS_LOCK (1 << 8) | ||
52 | |||
53 | #define XVTC_ERROR_ACTIVE_CHROMA_LOCK (1 << 21) | ||
54 | #define XVTC_ERROR_ACTIVE_VIDEO_LOCK (1 << 20) | ||
55 | #define XVTC_ERROR_HSYNC_LOCK (1 << 19) | ||
56 | #define XVTC_ERROR_VSYNC_LOCK (1 << 18) | ||
57 | #define XVTC_ERROR_HBLANK_LOCK (1 << 17) | ||
58 | #define XVTC_ERROR_VBLANK_LOCK (1 << 16) | ||
59 | |||
60 | #define XVTC_IRQ_ENABLE_FSYNC(n) ((n) << 16) | ||
61 | #define XVTC_IRQ_ENABLE_GEN_ACTIVE_VIDEO (1 << 13) | ||
62 | #define XVTC_IRQ_ENABLE_GEN_VBLANK (1 << 12) | ||
63 | #define XVTC_IRQ_ENABLE_DET_ACTIVE_VIDEO (1 << 11) | ||
64 | #define XVTC_IRQ_ENABLE_DET_VBLANK (1 << 10) | ||
65 | #define XVTC_IRQ_ENABLE_LOCK_LOSS (1 << 9) | ||
66 | #define XVTC_IRQ_ENABLE_LOCK (1 << 8) | ||
67 | |||
68 | /* | ||
69 | * The following registers exist in two blocks, one at 0x0020 for the detector | ||
70 | * and one at 0x0060 for the generator. | ||
71 | */ | ||
72 | |||
73 | #define XVTC_DETECTOR_OFFSET 0x0020 | ||
74 | #define XVTC_GENERATOR_OFFSET 0x0060 | ||
75 | |||
76 | #define XVTC_ACTIVE_SIZE 0x0000 | ||
77 | #define XVTC_ACTIVE_VSIZE_SHIFT 16 | ||
78 | #define XVTC_ACTIVE_VSIZE_MASK (0x1fff << 16) | ||
79 | #define XVTC_ACTIVE_HSIZE_SHIFT 0 | ||
80 | #define XVTC_ACTIVE_HSIZE_MASK (0x1fff << 0) | ||
81 | |||
82 | #define XVTC_TIMING_STATUS 0x0004 | ||
83 | #define XVTC_TIMING_STATUS_ACTIVE_VIDEO (1 << 2) | ||
84 | #define XVTC_TIMING_STATUS_VBLANK (1 << 1) | ||
85 | #define XVTC_TIMING_STATUS_LOCKED (1 << 0) | ||
86 | |||
87 | #define XVTC_ENCODING 0x0008 | ||
88 | #define XVTC_ENCODING_CHROMA_PARITY_SHIFT 8 | ||
89 | #define XVTC_ENCODING_CHROMA_PARITY_MASK (3 << 8) | ||
90 | #define XVTC_ENCODING_CHROMA_PARITY_EVEN_ALL (0 << 8) | ||
91 | #define XVTC_ENCODING_CHROMA_PARITY_ODD_ALL (1 << 8) | ||
92 | #define XVTC_ENCODING_CHROMA_PARITY_EVEN_EVEN (2 << 8) | ||
93 | #define XVTC_ENCODING_CHROMA_PARITY_ODD_EVEN (3 << 8) | ||
94 | #define XVTC_ENCODING_VIDEO_FORMAT_SHIFT 0 | ||
95 | #define XVTC_ENCODING_VIDEO_FORMAT_MASK (0xf << 0) | ||
96 | #define XVTC_ENCODING_VIDEO_FORMAT_YUV422 (0 << 0) | ||
97 | #define XVTC_ENCODING_VIDEO_FORMAT_YUV444 (1 << 0) | ||
98 | #define XVTC_ENCODING_VIDEO_FORMAT_RGB (2 << 0) | ||
99 | #define XVTC_ENCODING_VIDEO_FORMAT_YUV420 (3 << 0) | ||
100 | |||
101 | #define XVTC_POLARITY 0x000c | ||
102 | #define XVTC_POLARITY_ACTIVE_CHROMA_POL (1 << 5) | ||
103 | #define XVTC_POLARITY_ACTIVE_VIDEO_POL (1 << 4) | ||
104 | #define XVTC_POLARITY_HSYNC_POL (1 << 3) | ||
105 | #define XVTC_POLARITY_VSYNC_POL (1 << 2) | ||
106 | #define XVTC_POLARITY_HBLANK_POL (1 << 1) | ||
107 | #define XVTC_POLARITY_VBLANK_POL (1 << 0) | ||
108 | |||
109 | #define XVTC_HSIZE 0x0010 | ||
110 | #define XVTC_HSIZE_MASK (0x1fff << 0) | ||
111 | |||
112 | #define XVTC_VSIZE 0x0014 | ||
113 | #define XVTC_VSIZE_MASK (0x1fff << 0) | ||
114 | |||
115 | #define XVTC_HSYNC 0x0018 | ||
116 | #define XVTC_HSYNC_END_SHIFT 16 | ||
117 | #define XVTC_HSYNC_END_MASK (0x1fff << 16) | ||
118 | #define XVTC_HSYNC_START_SHIFT 0 | ||
119 | #define XVTC_HSYNC_START_MASK (0x1fff << 0) | ||
120 | |||
121 | #define XVTC_F0_VBLANK_H 0x001c | ||
122 | #define XVTC_F0_VBLANK_HEND_SHIFT 16 | ||
123 | #define XVTC_F0_VBLANK_HEND_MASK (0x1fff << 16) | ||
124 | #define XVTC_F0_VBLANK_HSTART_SHIFT 0 | ||
125 | #define XVTC_F0_VBLANK_HSTART_MASK (0x1fff << 0) | ||
126 | |||
127 | #define XVTC_F0_VSYNC_V 0x0020 | ||
128 | #define XVTC_F0_VSYNC_VEND_SHIFT 16 | ||
129 | #define XVTC_F0_VSYNC_VEND_MASK (0x1fff << 16) | ||
130 | #define XVTC_F0_VSYNC_VSTART_SHIFT 0 | ||
131 | #define XVTC_F0_VSYNC_VSTART_MASK (0x1fff << 0) | ||
132 | |||
133 | #define XVTC_F0_VSYNC_H 0x0024 | ||
134 | #define XVTC_F0_VSYNC_HEND_SHIFT 16 | ||
135 | #define XVTC_F0_VSYNC_HEND_MASK (0x1fff << 16) | ||
136 | #define XVTC_F0_VSYNC_HSTART_SHIFT 0 | ||
137 | #define XVTC_F0_VSYNC_HSTART_MASK (0x1fff << 0) | ||
138 | |||
139 | #define XVTC_FRAME_SYNC_CONFIG(n) (0x0100 + 4 * (n)) | ||
140 | #define XVTC_FRAME_SYNC_V_START_SHIFT 16 | ||
141 | #define XVTC_FRAME_SYNC_V_START_MASK (0x1fff << 16) | ||
142 | #define XVTC_FRAME_SYNC_H_START_SHIFT 0 | ||
143 | #define XVTC_FRAME_SYNC_H_START_MASK (0x1fff << 0) | ||
144 | |||
145 | #define XVTC_GENERATOR_GLOBAL_DELAY 0x0104 | ||
146 | |||
147 | /** | ||
148 | * struct xvtc_device - Xilinx Video Timing Controller device structure | ||
149 | * @xvip: Xilinx Video IP device | ||
150 | * @list: entry in the global VTC list | ||
151 | * @has_detector: the VTC has a timing detector | ||
152 | * @has_generator: the VTC has a timing generator | ||
153 | * @config: generator timings configuration | ||
154 | */ | ||
155 | struct xvtc_device { | ||
156 | struct xvip_device xvip; | ||
157 | struct list_head list; | ||
158 | |||
159 | bool has_detector; | ||
160 | bool has_generator; | ||
161 | |||
162 | struct xvtc_config config; | ||
163 | }; | ||
164 | |||
165 | static LIST_HEAD(xvtc_list); | ||
166 | static DEFINE_MUTEX(xvtc_lock); | ||
167 | |||
168 | static inline void xvtc_gen_write(struct xvtc_device *xvtc, u32 addr, u32 value) | ||
169 | { | ||
170 | xvip_write(&xvtc->xvip, XVTC_GENERATOR_OFFSET + addr, value); | ||
171 | } | ||
172 | |||
173 | /* ----------------------------------------------------------------------------- | ||
174 | * Generator Operations | ||
175 | */ | ||
176 | |||
177 | int xvtc_generator_start(struct xvtc_device *xvtc, | ||
178 | const struct xvtc_config *config) | ||
179 | { | ||
180 | int ret; | ||
181 | |||
182 | if (!xvtc->has_generator) | ||
183 | return -ENXIO; | ||
184 | |||
185 | ret = clk_prepare_enable(xvtc->xvip.clk); | ||
186 | if (ret < 0) | ||
187 | return ret; | ||
188 | |||
189 | /* We don't care about the chroma active signal, encoding parameters are | ||
190 | * not important for now. | ||
191 | */ | ||
192 | xvtc_gen_write(xvtc, XVTC_POLARITY, | ||
193 | XVTC_POLARITY_ACTIVE_CHROMA_POL | | ||
194 | XVTC_POLARITY_ACTIVE_VIDEO_POL | | ||
195 | XVTC_POLARITY_HSYNC_POL | XVTC_POLARITY_VSYNC_POL | | ||
196 | XVTC_POLARITY_HBLANK_POL | XVTC_POLARITY_VBLANK_POL); | ||
197 | |||
198 | /* Hardcode the polarity to active high, as required by the video in to | ||
199 | * AXI4-stream core. | ||
200 | */ | ||
201 | xvtc_gen_write(xvtc, XVTC_ENCODING, 0); | ||
202 | |||
203 | /* Configure the timings. The VBLANK and VSYNC signals assertion and | ||
204 | * deassertion are hardcoded to the first pixel of the line. | ||
205 | */ | ||
206 | xvtc_gen_write(xvtc, XVTC_ACTIVE_SIZE, | ||
207 | (config->vblank_start << XVTC_ACTIVE_VSIZE_SHIFT) | | ||
208 | (config->hblank_start << XVTC_ACTIVE_HSIZE_SHIFT)); | ||
209 | xvtc_gen_write(xvtc, XVTC_HSIZE, config->hsize); | ||
210 | xvtc_gen_write(xvtc, XVTC_VSIZE, config->vsize); | ||
211 | xvtc_gen_write(xvtc, XVTC_HSYNC, | ||
212 | (config->hsync_end << XVTC_HSYNC_END_SHIFT) | | ||
213 | (config->hsync_start << XVTC_HSYNC_START_SHIFT)); | ||
214 | xvtc_gen_write(xvtc, XVTC_F0_VBLANK_H, 0); | ||
215 | xvtc_gen_write(xvtc, XVTC_F0_VSYNC_V, | ||
216 | (config->vsync_end << XVTC_F0_VSYNC_VEND_SHIFT) | | ||
217 | (config->vsync_start << XVTC_F0_VSYNC_VSTART_SHIFT)); | ||
218 | xvtc_gen_write(xvtc, XVTC_F0_VSYNC_H, 0); | ||
219 | |||
220 | /* Enable the generator. Set the source of all generator parameters to | ||
221 | * generator registers. | ||
222 | */ | ||
223 | xvip_write(&xvtc->xvip, XVIP_CTRL_CONTROL, | ||
224 | XVTC_CONTROL_ACTIVE_CHROMA_POL_SRC | | ||
225 | XVTC_CONTROL_ACTIVE_VIDEO_POL_SRC | | ||
226 | XVTC_CONTROL_HSYNC_POL_SRC | XVTC_CONTROL_VSYNC_POL_SRC | | ||
227 | XVTC_CONTROL_HBLANK_POL_SRC | XVTC_CONTROL_VBLANK_POL_SRC | | ||
228 | XVTC_CONTROL_CHROMA_SRC | XVTC_CONTROL_VBLANK_HOFF_SRC | | ||
229 | XVTC_CONTROL_VSYNC_END_SRC | XVTC_CONTROL_VSYNC_START_SRC | | ||
230 | XVTC_CONTROL_ACTIVE_VSIZE_SRC | | ||
231 | XVTC_CONTROL_FRAME_VSIZE_SRC | XVTC_CONTROL_HSYNC_END_SRC | | ||
232 | XVTC_CONTROL_HSYNC_START_SRC | | ||
233 | XVTC_CONTROL_ACTIVE_HSIZE_SRC | | ||
234 | XVTC_CONTROL_FRAME_HSIZE_SRC | XVTC_CONTROL_GEN_ENABLE | | ||
235 | XVIP_CTRL_CONTROL_REG_UPDATE); | ||
236 | |||
237 | return 0; | ||
238 | } | ||
239 | EXPORT_SYMBOL_GPL(xvtc_generator_start); | ||
240 | |||
241 | int xvtc_generator_stop(struct xvtc_device *xvtc) | ||
242 | { | ||
243 | if (!xvtc->has_generator) | ||
244 | return -ENXIO; | ||
245 | |||
246 | xvip_write(&xvtc->xvip, XVIP_CTRL_CONTROL, 0); | ||
247 | |||
248 | clk_disable_unprepare(xvtc->xvip.clk); | ||
249 | |||
250 | return 0; | ||
251 | } | ||
252 | EXPORT_SYMBOL_GPL(xvtc_generator_stop); | ||
253 | |||
254 | struct xvtc_device *xvtc_of_get(struct device_node *np) | ||
255 | { | ||
256 | struct device_node *xvtc_node; | ||
257 | struct xvtc_device *found = NULL; | ||
258 | struct xvtc_device *xvtc; | ||
259 | |||
260 | if (!of_find_property(np, "xlnx,vtc", NULL)) | ||
261 | return NULL; | ||
262 | |||
263 | xvtc_node = of_parse_phandle(np, "xlnx,vtc", 0); | ||
264 | if (xvtc_node == NULL) | ||
265 | return ERR_PTR(-EINVAL); | ||
266 | |||
267 | mutex_lock(&xvtc_lock); | ||
268 | list_for_each_entry(xvtc, &xvtc_list, list) { | ||
269 | if (xvtc->xvip.dev->of_node == xvtc_node) { | ||
270 | found = xvtc; | ||
271 | break; | ||
272 | } | ||
273 | } | ||
274 | mutex_unlock(&xvtc_lock); | ||
275 | |||
276 | of_node_put(xvtc_node); | ||
277 | |||
278 | if (!found) | ||
279 | return ERR_PTR(-EPROBE_DEFER); | ||
280 | |||
281 | return found; | ||
282 | } | ||
283 | EXPORT_SYMBOL_GPL(xvtc_of_get); | ||
284 | |||
285 | void xvtc_put(struct xvtc_device *xvtc) | ||
286 | { | ||
287 | } | ||
288 | EXPORT_SYMBOL_GPL(xvtc_put); | ||
289 | |||
290 | /* ----------------------------------------------------------------------------- | ||
291 | * Registration and Unregistration | ||
292 | */ | ||
293 | |||
294 | static void xvtc_register_device(struct xvtc_device *xvtc) | ||
295 | { | ||
296 | mutex_lock(&xvtc_lock); | ||
297 | list_add_tail(&xvtc->list, &xvtc_list); | ||
298 | mutex_unlock(&xvtc_lock); | ||
299 | } | ||
300 | |||
301 | static void xvtc_unregister_device(struct xvtc_device *xvtc) | ||
302 | { | ||
303 | mutex_lock(&xvtc_lock); | ||
304 | list_del(&xvtc->list); | ||
305 | mutex_unlock(&xvtc_lock); | ||
306 | } | ||
307 | |||
308 | /* ----------------------------------------------------------------------------- | ||
309 | * Platform Device Driver | ||
310 | */ | ||
311 | |||
312 | static int xvtc_parse_of(struct xvtc_device *xvtc) | ||
313 | { | ||
314 | struct device_node *node = xvtc->xvip.dev->of_node; | ||
315 | |||
316 | xvtc->has_detector = of_property_read_bool(node, "xlnx,detector"); | ||
317 | xvtc->has_generator = of_property_read_bool(node, "xlnx,generator"); | ||
318 | |||
319 | return 0; | ||
320 | } | ||
321 | |||
322 | static int xvtc_probe(struct platform_device *pdev) | ||
323 | { | ||
324 | struct xvtc_device *xvtc; | ||
325 | int ret; | ||
326 | |||
327 | xvtc = devm_kzalloc(&pdev->dev, sizeof(*xvtc), GFP_KERNEL); | ||
328 | if (!xvtc) | ||
329 | return -ENOMEM; | ||
330 | |||
331 | xvtc->xvip.dev = &pdev->dev; | ||
332 | |||
333 | ret = xvtc_parse_of(xvtc); | ||
334 | if (ret < 0) | ||
335 | return ret; | ||
336 | |||
337 | ret = xvip_init_resources(&xvtc->xvip); | ||
338 | if (ret < 0) | ||
339 | return ret; | ||
340 | |||
341 | platform_set_drvdata(pdev, xvtc); | ||
342 | |||
343 | xvip_print_version(&xvtc->xvip); | ||
344 | |||
345 | xvtc_register_device(xvtc); | ||
346 | |||
347 | return 0; | ||
348 | } | ||
349 | |||
350 | static int xvtc_remove(struct platform_device *pdev) | ||
351 | { | ||
352 | struct xvtc_device *xvtc = platform_get_drvdata(pdev); | ||
353 | |||
354 | xvtc_unregister_device(xvtc); | ||
355 | |||
356 | xvip_cleanup_resources(&xvtc->xvip); | ||
357 | |||
358 | return 0; | ||
359 | } | ||
360 | |||
361 | static const struct of_device_id xvtc_of_id_table[] = { | ||
362 | { .compatible = "xlnx,v-tc-6.1" }, | ||
363 | { } | ||
364 | }; | ||
365 | MODULE_DEVICE_TABLE(of, xvtc_of_id_table); | ||
366 | |||
367 | static struct platform_driver xvtc_driver = { | ||
368 | .driver = { | ||
369 | .name = "xilinx-vtc", | ||
370 | .of_match_table = xvtc_of_id_table, | ||
371 | }, | ||
372 | .probe = xvtc_probe, | ||
373 | .remove = xvtc_remove, | ||
374 | }; | ||
375 | |||
376 | module_platform_driver(xvtc_driver); | ||
377 | |||
378 | MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>"); | ||
379 | MODULE_DESCRIPTION("Xilinx Video Timing Controller Driver"); | ||
380 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/media/platform/xilinx/xilinx-vtc.h b/drivers/media/platform/xilinx/xilinx-vtc.h new file mode 100644 index 000000000000..e1bb2cfcf428 --- /dev/null +++ b/drivers/media/platform/xilinx/xilinx-vtc.h | |||
@@ -0,0 +1,42 @@ | |||
1 | /* | ||
2 | * Xilinx Video Timing Controller | ||
3 | * | ||
4 | * Copyright (C) 2013-2015 Ideas on Board | ||
5 | * Copyright (C) 2013-2015 Xilinx, Inc. | ||
6 | * | ||
7 | * Contacts: Hyun Kwon <hyun.kwon@xilinx.com> | ||
8 | * Laurent Pinchart <laurent.pinchart@ideasonboard.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #ifndef __XILINX_VTC_H__ | ||
16 | #define __XILINX_VTC_H__ | ||
17 | |||
18 | struct device_node; | ||
19 | struct xvtc_device; | ||
20 | |||
21 | #define XVTC_MAX_HSIZE 8191 | ||
22 | #define XVTC_MAX_VSIZE 8191 | ||
23 | |||
24 | struct xvtc_config { | ||
25 | unsigned int hblank_start; | ||
26 | unsigned int hsync_start; | ||
27 | unsigned int hsync_end; | ||
28 | unsigned int hsize; | ||
29 | unsigned int vblank_start; | ||
30 | unsigned int vsync_start; | ||
31 | unsigned int vsync_end; | ||
32 | unsigned int vsize; | ||
33 | }; | ||
34 | |||
35 | struct xvtc_device *xvtc_of_get(struct device_node *np); | ||
36 | void xvtc_put(struct xvtc_device *xvtc); | ||
37 | |||
38 | int xvtc_generator_start(struct xvtc_device *xvtc, | ||
39 | const struct xvtc_config *config); | ||
40 | int xvtc_generator_stop(struct xvtc_device *xvtc); | ||
41 | |||
42 | #endif /* __XILINX_VTC_H__ */ | ||
diff --git a/drivers/media/radio/radio-wl1273.c b/drivers/media/radio/radio-wl1273.c index b8f36445516b..a93f681aa9d6 100644 --- a/drivers/media/radio/radio-wl1273.c +++ b/drivers/media/radio/radio-wl1273.c | |||
@@ -347,6 +347,7 @@ static int wl1273_fm_set_tx_freq(struct wl1273_device *radio, unsigned int freq) | |||
347 | { | 347 | { |
348 | struct wl1273_core *core = radio->core; | 348 | struct wl1273_core *core = radio->core; |
349 | int r = 0; | 349 | int r = 0; |
350 | unsigned long t; | ||
350 | 351 | ||
351 | if (freq < WL1273_BAND_TX_LOW) { | 352 | if (freq < WL1273_BAND_TX_LOW) { |
352 | dev_err(radio->dev, | 353 | dev_err(radio->dev, |
@@ -378,11 +379,11 @@ static int wl1273_fm_set_tx_freq(struct wl1273_device *radio, unsigned int freq) | |||
378 | reinit_completion(&radio->busy); | 379 | reinit_completion(&radio->busy); |
379 | 380 | ||
380 | /* wait for the FR IRQ */ | 381 | /* wait for the FR IRQ */ |
381 | r = wait_for_completion_timeout(&radio->busy, msecs_to_jiffies(2000)); | 382 | t = wait_for_completion_timeout(&radio->busy, msecs_to_jiffies(2000)); |
382 | if (!r) | 383 | if (!t) |
383 | return -ETIMEDOUT; | 384 | return -ETIMEDOUT; |
384 | 385 | ||
385 | dev_dbg(radio->dev, "WL1273_CHANL_SET: %d\n", r); | 386 | dev_dbg(radio->dev, "WL1273_CHANL_SET: %lu\n", t); |
386 | 387 | ||
387 | /* Enable the output power */ | 388 | /* Enable the output power */ |
388 | r = core->write(core, WL1273_POWER_ENB_SET, 1); | 389 | r = core->write(core, WL1273_POWER_ENB_SET, 1); |
@@ -392,12 +393,12 @@ static int wl1273_fm_set_tx_freq(struct wl1273_device *radio, unsigned int freq) | |||
392 | reinit_completion(&radio->busy); | 393 | reinit_completion(&radio->busy); |
393 | 394 | ||
394 | /* wait for the POWER_ENB IRQ */ | 395 | /* wait for the POWER_ENB IRQ */ |
395 | r = wait_for_completion_timeout(&radio->busy, msecs_to_jiffies(1000)); | 396 | t = wait_for_completion_timeout(&radio->busy, msecs_to_jiffies(1000)); |
396 | if (!r) | 397 | if (!t) |
397 | return -ETIMEDOUT; | 398 | return -ETIMEDOUT; |
398 | 399 | ||
399 | radio->tx_frequency = freq; | 400 | radio->tx_frequency = freq; |
400 | dev_dbg(radio->dev, "WL1273_POWER_ENB_SET: %d\n", r); | 401 | dev_dbg(radio->dev, "WL1273_POWER_ENB_SET: %lu\n", t); |
401 | 402 | ||
402 | return 0; | 403 | return 0; |
403 | } | 404 | } |
@@ -406,6 +407,7 @@ static int wl1273_fm_set_rx_freq(struct wl1273_device *radio, unsigned int freq) | |||
406 | { | 407 | { |
407 | struct wl1273_core *core = radio->core; | 408 | struct wl1273_core *core = radio->core; |
408 | int r, f; | 409 | int r, f; |
410 | unsigned long t; | ||
409 | 411 | ||
410 | if (freq < radio->rangelow) { | 412 | if (freq < radio->rangelow) { |
411 | dev_err(radio->dev, | 413 | dev_err(radio->dev, |
@@ -446,8 +448,8 @@ static int wl1273_fm_set_rx_freq(struct wl1273_device *radio, unsigned int freq) | |||
446 | 448 | ||
447 | reinit_completion(&radio->busy); | 449 | reinit_completion(&radio->busy); |
448 | 450 | ||
449 | r = wait_for_completion_timeout(&radio->busy, msecs_to_jiffies(2000)); | 451 | t = wait_for_completion_timeout(&radio->busy, msecs_to_jiffies(2000)); |
450 | if (!r) { | 452 | if (!t) { |
451 | dev_err(radio->dev, "%s: TIMEOUT\n", __func__); | 453 | dev_err(radio->dev, "%s: TIMEOUT\n", __func__); |
452 | return -ETIMEDOUT; | 454 | return -ETIMEDOUT; |
453 | } | 455 | } |
@@ -826,9 +828,12 @@ static int wl1273_fm_set_seek(struct wl1273_device *radio, | |||
826 | if (r) | 828 | if (r) |
827 | goto out; | 829 | goto out; |
828 | 830 | ||
831 | /* wait for the FR IRQ */ | ||
829 | wait_for_completion_timeout(&radio->busy, msecs_to_jiffies(1000)); | 832 | wait_for_completion_timeout(&radio->busy, msecs_to_jiffies(1000)); |
830 | if (!(radio->irq_received & WL1273_BL_EVENT)) | 833 | if (!(radio->irq_received & WL1273_BL_EVENT)) { |
834 | r = -ETIMEDOUT; | ||
831 | goto out; | 835 | goto out; |
836 | } | ||
832 | 837 | ||
833 | radio->irq_received &= ~WL1273_BL_EVENT; | 838 | radio->irq_received &= ~WL1273_BL_EVENT; |
834 | 839 | ||
@@ -854,7 +859,9 @@ static int wl1273_fm_set_seek(struct wl1273_device *radio, | |||
854 | if (r) | 859 | if (r) |
855 | goto out; | 860 | goto out; |
856 | 861 | ||
857 | wait_for_completion_timeout(&radio->busy, msecs_to_jiffies(1000)); | 862 | /* wait for the FR IRQ */ |
863 | if (!wait_for_completion_timeout(&radio->busy, msecs_to_jiffies(1000))) | ||
864 | r = -ETIMEDOUT; | ||
858 | out: | 865 | out: |
859 | dev_dbg(radio->dev, "%s: Err: %d\n", __func__, r); | 866 | dev_dbg(radio->dev, "%s: Err: %d\n", __func__, r); |
860 | return r; | 867 | return r; |
diff --git a/drivers/media/radio/si470x/radio-si470x-common.c b/drivers/media/radio/si470x/radio-si470x-common.c index 909c3f92d839..1d827adab7eb 100644 --- a/drivers/media/radio/si470x/radio-si470x-common.c +++ b/drivers/media/radio/si470x/radio-si470x-common.c | |||
@@ -208,6 +208,7 @@ static int si470x_set_band(struct si470x_device *radio, int band) | |||
208 | static int si470x_set_chan(struct si470x_device *radio, unsigned short chan) | 208 | static int si470x_set_chan(struct si470x_device *radio, unsigned short chan) |
209 | { | 209 | { |
210 | int retval; | 210 | int retval; |
211 | unsigned long time_left; | ||
211 | bool timed_out = false; | 212 | bool timed_out = false; |
212 | 213 | ||
213 | /* start tuning */ | 214 | /* start tuning */ |
@@ -219,9 +220,9 @@ static int si470x_set_chan(struct si470x_device *radio, unsigned short chan) | |||
219 | 220 | ||
220 | /* wait till tune operation has completed */ | 221 | /* wait till tune operation has completed */ |
221 | reinit_completion(&radio->completion); | 222 | reinit_completion(&radio->completion); |
222 | retval = wait_for_completion_timeout(&radio->completion, | 223 | time_left = wait_for_completion_timeout(&radio->completion, |
223 | msecs_to_jiffies(tune_timeout)); | 224 | msecs_to_jiffies(tune_timeout)); |
224 | if (!retval) | 225 | if (time_left == 0) |
225 | timed_out = true; | 226 | timed_out = true; |
226 | 227 | ||
227 | if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) | 228 | if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) |
@@ -301,6 +302,7 @@ static int si470x_set_seek(struct si470x_device *radio, | |||
301 | int band, retval; | 302 | int band, retval; |
302 | unsigned int freq; | 303 | unsigned int freq; |
303 | bool timed_out = false; | 304 | bool timed_out = false; |
305 | unsigned long time_left; | ||
304 | 306 | ||
305 | /* set band */ | 307 | /* set band */ |
306 | if (seek->rangelow || seek->rangehigh) { | 308 | if (seek->rangelow || seek->rangehigh) { |
@@ -342,9 +344,9 @@ static int si470x_set_seek(struct si470x_device *radio, | |||
342 | 344 | ||
343 | /* wait till tune operation has completed */ | 345 | /* wait till tune operation has completed */ |
344 | reinit_completion(&radio->completion); | 346 | reinit_completion(&radio->completion); |
345 | retval = wait_for_completion_timeout(&radio->completion, | 347 | time_left = wait_for_completion_timeout(&radio->completion, |
346 | msecs_to_jiffies(seek_timeout)); | 348 | msecs_to_jiffies(seek_timeout)); |
347 | if (!retval) | 349 | if (time_left == 0) |
348 | timed_out = true; | 350 | timed_out = true; |
349 | 351 | ||
350 | if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) | 352 | if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) |
diff --git a/drivers/media/radio/si4713/si4713.c b/drivers/media/radio/si4713/si4713.c index c90004dac170..e9d03ac69a27 100644 --- a/drivers/media/radio/si4713/si4713.c +++ b/drivers/media/radio/si4713/si4713.c | |||
@@ -383,7 +383,7 @@ static int si4713_powerup(struct si4713_device *sdev) | |||
383 | } | 383 | } |
384 | } | 384 | } |
385 | 385 | ||
386 | if (!IS_ERR(sdev->gpio_reset)) { | 386 | if (sdev->gpio_reset) { |
387 | udelay(50); | 387 | udelay(50); |
388 | gpiod_set_value(sdev->gpio_reset, 1); | 388 | gpiod_set_value(sdev->gpio_reset, 1); |
389 | } | 389 | } |
@@ -407,8 +407,7 @@ static int si4713_powerup(struct si4713_device *sdev) | |||
407 | SI4713_STC_INT | SI4713_CTS); | 407 | SI4713_STC_INT | SI4713_CTS); |
408 | return err; | 408 | return err; |
409 | } | 409 | } |
410 | if (!IS_ERR(sdev->gpio_reset)) | 410 | gpiod_set_value(sdev->gpio_reset, 0); |
411 | gpiod_set_value(sdev->gpio_reset, 0); | ||
412 | 411 | ||
413 | 412 | ||
414 | if (sdev->vdd) { | 413 | if (sdev->vdd) { |
@@ -447,7 +446,7 @@ static int si4713_powerdown(struct si4713_device *sdev) | |||
447 | v4l2_dbg(1, debug, &sdev->sd, "Power down response: 0x%02x\n", | 446 | v4l2_dbg(1, debug, &sdev->sd, "Power down response: 0x%02x\n", |
448 | resp[0]); | 447 | resp[0]); |
449 | v4l2_dbg(1, debug, &sdev->sd, "Device in reset mode\n"); | 448 | v4l2_dbg(1, debug, &sdev->sd, "Device in reset mode\n"); |
450 | if (!IS_ERR(sdev->gpio_reset)) | 449 | if (sdev->gpio_reset) |
451 | gpiod_set_value(sdev->gpio_reset, 0); | 450 | gpiod_set_value(sdev->gpio_reset, 0); |
452 | 451 | ||
453 | if (sdev->vdd) { | 452 | if (sdev->vdd) { |
@@ -1460,14 +1459,9 @@ static int si4713_probe(struct i2c_client *client, | |||
1460 | goto exit; | 1459 | goto exit; |
1461 | } | 1460 | } |
1462 | 1461 | ||
1463 | sdev->gpio_reset = devm_gpiod_get(&client->dev, "reset"); | 1462 | sdev->gpio_reset = devm_gpiod_get_optional(&client->dev, "reset", |
1464 | if (!IS_ERR(sdev->gpio_reset)) { | 1463 | GPIOD_OUT_LOW); |
1465 | gpiod_direction_output(sdev->gpio_reset, 0); | 1464 | if (IS_ERR(sdev->gpio_reset)) { |
1466 | } else if (PTR_ERR(sdev->gpio_reset) == -ENOENT) { | ||
1467 | dev_dbg(&client->dev, "No reset GPIO assigned\n"); | ||
1468 | } else if (PTR_ERR(sdev->gpio_reset) == -ENOSYS) { | ||
1469 | dev_dbg(&client->dev, "No reset GPIO support\n"); | ||
1470 | } else { | ||
1471 | rval = PTR_ERR(sdev->gpio_reset); | 1465 | rval = PTR_ERR(sdev->gpio_reset); |
1472 | dev_err(&client->dev, "Failed to request gpio: %d\n", rval); | 1466 | dev_err(&client->dev, "Failed to request gpio: %d\n", rval); |
1473 | goto exit; | 1467 | goto exit; |
diff --git a/drivers/media/radio/wl128x/Kconfig b/drivers/media/radio/wl128x/Kconfig index f359be7e9dd9..9d6574bebf78 100644 --- a/drivers/media/radio/wl128x/Kconfig +++ b/drivers/media/radio/wl128x/Kconfig | |||
@@ -5,7 +5,7 @@ menu "Texas Instruments WL128x FM driver (ST based)" | |||
5 | config RADIO_WL128X | 5 | config RADIO_WL128X |
6 | tristate "Texas Instruments WL128x FM Radio" | 6 | tristate "Texas Instruments WL128x FM Radio" |
7 | depends on VIDEO_V4L2 && RFKILL && GPIOLIB && TTY | 7 | depends on VIDEO_V4L2 && RFKILL && GPIOLIB && TTY |
8 | select TI_ST if NET | 8 | depends on TI_ST |
9 | help | 9 | help |
10 | Choose Y here if you have this FM radio chip. | 10 | Choose Y here if you have this FM radio chip. |
11 | 11 | ||
diff --git a/drivers/media/radio/wl128x/fmdrv_v4l2.c b/drivers/media/radio/wl128x/fmdrv_v4l2.c index a5bd3f674bbd..fb42f0fd0c1f 100644 --- a/drivers/media/radio/wl128x/fmdrv_v4l2.c +++ b/drivers/media/radio/wl128x/fmdrv_v4l2.c | |||
@@ -36,7 +36,7 @@ | |||
36 | #include "fmdrv_rx.h" | 36 | #include "fmdrv_rx.h" |
37 | #include "fmdrv_tx.h" | 37 | #include "fmdrv_tx.h" |
38 | 38 | ||
39 | static struct video_device *gradio_dev; | 39 | static struct video_device gradio_dev; |
40 | static u8 radio_disconnected; | 40 | static u8 radio_disconnected; |
41 | 41 | ||
42 | /* -- V4L2 RADIO (/dev/radioX) device file operation interfaces --- */ | 42 | /* -- V4L2 RADIO (/dev/radioX) device file operation interfaces --- */ |
@@ -517,7 +517,7 @@ static struct video_device fm_viddev_template = { | |||
517 | .fops = &fm_drv_fops, | 517 | .fops = &fm_drv_fops, |
518 | .ioctl_ops = &fm_drv_ioctl_ops, | 518 | .ioctl_ops = &fm_drv_ioctl_ops, |
519 | .name = FM_DRV_NAME, | 519 | .name = FM_DRV_NAME, |
520 | .release = video_device_release, | 520 | .release = video_device_release_empty, |
521 | /* | 521 | /* |
522 | * To ensure both the tuner and modulator ioctls are accessible we | 522 | * To ensure both the tuner and modulator ioctls are accessible we |
523 | * set the vfl_dir to M2M to indicate this. | 523 | * set the vfl_dir to M2M to indicate this. |
@@ -543,29 +543,21 @@ int fm_v4l2_init_video_device(struct fmdev *fmdev, int radio_nr) | |||
543 | /* Init mutex for core locking */ | 543 | /* Init mutex for core locking */ |
544 | mutex_init(&fmdev->mutex); | 544 | mutex_init(&fmdev->mutex); |
545 | 545 | ||
546 | /* Allocate new video device */ | ||
547 | gradio_dev = video_device_alloc(); | ||
548 | if (NULL == gradio_dev) { | ||
549 | fmerr("Can't allocate video device\n"); | ||
550 | return -ENOMEM; | ||
551 | } | ||
552 | |||
553 | /* Setup FM driver's V4L2 properties */ | 546 | /* Setup FM driver's V4L2 properties */ |
554 | memcpy(gradio_dev, &fm_viddev_template, sizeof(fm_viddev_template)); | 547 | gradio_dev = fm_viddev_template; |
555 | 548 | ||
556 | video_set_drvdata(gradio_dev, fmdev); | 549 | video_set_drvdata(&gradio_dev, fmdev); |
557 | 550 | ||
558 | gradio_dev->lock = &fmdev->mutex; | 551 | gradio_dev.lock = &fmdev->mutex; |
559 | gradio_dev->v4l2_dev = &fmdev->v4l2_dev; | 552 | gradio_dev.v4l2_dev = &fmdev->v4l2_dev; |
560 | 553 | ||
561 | /* Register with V4L2 subsystem as RADIO device */ | 554 | /* Register with V4L2 subsystem as RADIO device */ |
562 | if (video_register_device(gradio_dev, VFL_TYPE_RADIO, radio_nr)) { | 555 | if (video_register_device(&gradio_dev, VFL_TYPE_RADIO, radio_nr)) { |
563 | video_device_release(gradio_dev); | ||
564 | fmerr("Could not register video device\n"); | 556 | fmerr("Could not register video device\n"); |
565 | return -ENOMEM; | 557 | return -ENOMEM; |
566 | } | 558 | } |
567 | 559 | ||
568 | fmdev->radio_dev = gradio_dev; | 560 | fmdev->radio_dev = &gradio_dev; |
569 | 561 | ||
570 | /* Register to v4l2 ctrl handler framework */ | 562 | /* Register to v4l2 ctrl handler framework */ |
571 | fmdev->radio_dev->ctrl_handler = &fmdev->ctrl_handler; | 563 | fmdev->radio_dev->ctrl_handler = &fmdev->ctrl_handler; |
@@ -611,13 +603,13 @@ void *fm_v4l2_deinit_video_device(void) | |||
611 | struct fmdev *fmdev; | 603 | struct fmdev *fmdev; |
612 | 604 | ||
613 | 605 | ||
614 | fmdev = video_get_drvdata(gradio_dev); | 606 | fmdev = video_get_drvdata(&gradio_dev); |
615 | 607 | ||
616 | /* Unregister to v4l2 ctrl handler framework*/ | 608 | /* Unregister to v4l2 ctrl handler framework*/ |
617 | v4l2_ctrl_handler_free(&fmdev->ctrl_handler); | 609 | v4l2_ctrl_handler_free(&fmdev->ctrl_handler); |
618 | 610 | ||
619 | /* Unregister RADIO device from V4L2 subsystem */ | 611 | /* Unregister RADIO device from V4L2 subsystem */ |
620 | video_unregister_device(gradio_dev); | 612 | video_unregister_device(&gradio_dev); |
621 | 613 | ||
622 | v4l2_device_unregister(&fmdev->v4l2_dev); | 614 | v4l2_device_unregister(&fmdev->v4l2_dev); |
623 | 615 | ||
diff --git a/drivers/media/rc/img-ir/img-ir-core.c b/drivers/media/rc/img-ir/img-ir-core.c index 77c78de4f5bf..03fe080278df 100644 --- a/drivers/media/rc/img-ir/img-ir-core.c +++ b/drivers/media/rc/img-ir/img-ir-core.c | |||
@@ -110,16 +110,32 @@ static int img_ir_probe(struct platform_device *pdev) | |||
110 | priv->clk = devm_clk_get(&pdev->dev, "core"); | 110 | priv->clk = devm_clk_get(&pdev->dev, "core"); |
111 | if (IS_ERR(priv->clk)) | 111 | if (IS_ERR(priv->clk)) |
112 | dev_warn(&pdev->dev, "cannot get core clock resource\n"); | 112 | dev_warn(&pdev->dev, "cannot get core clock resource\n"); |
113 | |||
114 | /* Get sys clock */ | ||
115 | priv->sys_clk = devm_clk_get(&pdev->dev, "sys"); | ||
116 | if (IS_ERR(priv->sys_clk)) | ||
117 | dev_warn(&pdev->dev, "cannot get sys clock resource\n"); | ||
113 | /* | 118 | /* |
114 | * The driver doesn't need to know about the system ("sys") or power | 119 | * Enabling the system clock before the register interface is |
115 | * modulation ("mod") clocks yet | 120 | * accessed. ISR shouldn't get called with Sys Clock disabled, |
121 | * hence exiting probe with an error. | ||
116 | */ | 122 | */ |
123 | if (!IS_ERR(priv->sys_clk)) { | ||
124 | error = clk_prepare_enable(priv->sys_clk); | ||
125 | if (error) { | ||
126 | dev_err(&pdev->dev, "cannot enable sys clock\n"); | ||
127 | return error; | ||
128 | } | ||
129 | } | ||
117 | 130 | ||
118 | /* Set up raw & hw decoder */ | 131 | /* Set up raw & hw decoder */ |
119 | error = img_ir_probe_raw(priv); | 132 | error = img_ir_probe_raw(priv); |
120 | error2 = img_ir_probe_hw(priv); | 133 | error2 = img_ir_probe_hw(priv); |
121 | if (error && error2) | 134 | if (error && error2) { |
122 | return (error == -ENODEV) ? error2 : error; | 135 | if (error == -ENODEV) |
136 | error = error2; | ||
137 | goto err_probe; | ||
138 | } | ||
123 | 139 | ||
124 | /* Get the IRQ */ | 140 | /* Get the IRQ */ |
125 | priv->irq = irq; | 141 | priv->irq = irq; |
@@ -139,6 +155,9 @@ static int img_ir_probe(struct platform_device *pdev) | |||
139 | err_irq: | 155 | err_irq: |
140 | img_ir_remove_hw(priv); | 156 | img_ir_remove_hw(priv); |
141 | img_ir_remove_raw(priv); | 157 | img_ir_remove_raw(priv); |
158 | err_probe: | ||
159 | if (!IS_ERR(priv->sys_clk)) | ||
160 | clk_disable_unprepare(priv->sys_clk); | ||
142 | return error; | 161 | return error; |
143 | } | 162 | } |
144 | 163 | ||
@@ -146,12 +165,14 @@ static int img_ir_remove(struct platform_device *pdev) | |||
146 | { | 165 | { |
147 | struct img_ir_priv *priv = platform_get_drvdata(pdev); | 166 | struct img_ir_priv *priv = platform_get_drvdata(pdev); |
148 | 167 | ||
149 | free_irq(priv->irq, img_ir_isr); | 168 | free_irq(priv->irq, priv); |
150 | img_ir_remove_hw(priv); | 169 | img_ir_remove_hw(priv); |
151 | img_ir_remove_raw(priv); | 170 | img_ir_remove_raw(priv); |
152 | 171 | ||
153 | if (!IS_ERR(priv->clk)) | 172 | if (!IS_ERR(priv->clk)) |
154 | clk_disable_unprepare(priv->clk); | 173 | clk_disable_unprepare(priv->clk); |
174 | if (!IS_ERR(priv->sys_clk)) | ||
175 | clk_disable_unprepare(priv->sys_clk); | ||
155 | return 0; | 176 | return 0; |
156 | } | 177 | } |
157 | 178 | ||
diff --git a/drivers/media/rc/img-ir/img-ir.h b/drivers/media/rc/img-ir/img-ir.h index 2ddf56083182..f1387c016d3d 100644 --- a/drivers/media/rc/img-ir/img-ir.h +++ b/drivers/media/rc/img-ir/img-ir.h | |||
@@ -138,6 +138,7 @@ struct clk; | |||
138 | * @dev: Platform device. | 138 | * @dev: Platform device. |
139 | * @irq: IRQ number. | 139 | * @irq: IRQ number. |
140 | * @clk: Input clock. | 140 | * @clk: Input clock. |
141 | * @sys_clk: System clock. | ||
141 | * @reg_base: Iomem base address of IR register block. | 142 | * @reg_base: Iomem base address of IR register block. |
142 | * @lock: Protects IR registers and variables in this struct. | 143 | * @lock: Protects IR registers and variables in this struct. |
143 | * @raw: Driver data for raw decoder. | 144 | * @raw: Driver data for raw decoder. |
@@ -147,6 +148,7 @@ struct img_ir_priv { | |||
147 | struct device *dev; | 148 | struct device *dev; |
148 | int irq; | 149 | int irq; |
149 | struct clk *clk; | 150 | struct clk *clk; |
151 | struct clk *sys_clk; | ||
150 | void __iomem *reg_base; | 152 | void __iomem *reg_base; |
151 | spinlock_t lock; | 153 | spinlock_t lock; |
152 | 154 | ||
diff --git a/drivers/media/rc/ir-hix5hd2.c b/drivers/media/rc/ir-hix5hd2.c index b0df62961c14..58ec5986274e 100644 --- a/drivers/media/rc/ir-hix5hd2.c +++ b/drivers/media/rc/ir-hix5hd2.c | |||
@@ -16,14 +16,6 @@ | |||
16 | #include <linux/regmap.h> | 16 | #include <linux/regmap.h> |
17 | #include <media/rc-core.h> | 17 | #include <media/rc-core.h> |
18 | 18 | ||
19 | /* Allow the driver to compile on all architectures */ | ||
20 | #ifndef writel_relaxed | ||
21 | # define writel_relaxed writel | ||
22 | #endif | ||
23 | #ifndef readl_relaxed | ||
24 | # define readl_relaxed readl | ||
25 | #endif | ||
26 | |||
27 | #define IR_ENABLE 0x00 | 19 | #define IR_ENABLE 0x00 |
28 | #define IR_CONFIG 0x04 | 20 | #define IR_CONFIG 0x04 |
29 | #define CNT_LEADS 0x08 | 21 | #define CNT_LEADS 0x08 |
diff --git a/drivers/media/tuners/Kconfig b/drivers/media/tuners/Kconfig index 42e5a01b9192..983510d282f6 100644 --- a/drivers/media/tuners/Kconfig +++ b/drivers/media/tuners/Kconfig | |||
@@ -224,14 +224,6 @@ config MEDIA_TUNER_FC2580 | |||
224 | help | 224 | help |
225 | FCI FC2580 silicon tuner driver. | 225 | FCI FC2580 silicon tuner driver. |
226 | 226 | ||
227 | config MEDIA_TUNER_M88TS2022 | ||
228 | tristate "Montage M88TS2022 silicon tuner" | ||
229 | depends on MEDIA_SUPPORT && I2C | ||
230 | select REGMAP_I2C | ||
231 | default m if !MEDIA_SUBDRV_AUTOSELECT | ||
232 | help | ||
233 | Montage M88TS2022 silicon tuner driver. | ||
234 | |||
235 | config MEDIA_TUNER_M88RS6000T | 227 | config MEDIA_TUNER_M88RS6000T |
236 | tristate "Montage M88RS6000 internal tuner" | 228 | tristate "Montage M88RS6000 internal tuner" |
237 | depends on MEDIA_SUPPORT && I2C | 229 | depends on MEDIA_SUPPORT && I2C |
diff --git a/drivers/media/tuners/Makefile b/drivers/media/tuners/Makefile index da4fe6ef73e7..06a9ab65e5fa 100644 --- a/drivers/media/tuners/Makefile +++ b/drivers/media/tuners/Makefile | |||
@@ -33,7 +33,6 @@ obj-$(CONFIG_MEDIA_TUNER_E4000) += e4000.o | |||
33 | obj-$(CONFIG_MEDIA_TUNER_FC2580) += fc2580.o | 33 | obj-$(CONFIG_MEDIA_TUNER_FC2580) += fc2580.o |
34 | obj-$(CONFIG_MEDIA_TUNER_TUA9001) += tua9001.o | 34 | obj-$(CONFIG_MEDIA_TUNER_TUA9001) += tua9001.o |
35 | obj-$(CONFIG_MEDIA_TUNER_SI2157) += si2157.o | 35 | obj-$(CONFIG_MEDIA_TUNER_SI2157) += si2157.o |
36 | obj-$(CONFIG_MEDIA_TUNER_M88TS2022) += m88ts2022.o | ||
37 | obj-$(CONFIG_MEDIA_TUNER_FC0011) += fc0011.o | 36 | obj-$(CONFIG_MEDIA_TUNER_FC0011) += fc0011.o |
38 | obj-$(CONFIG_MEDIA_TUNER_FC0012) += fc0012.o | 37 | obj-$(CONFIG_MEDIA_TUNER_FC0012) += fc0012.o |
39 | obj-$(CONFIG_MEDIA_TUNER_FC0013) += fc0013.o | 38 | obj-$(CONFIG_MEDIA_TUNER_FC0013) += fc0013.o |
diff --git a/drivers/media/tuners/fc0011.h b/drivers/media/tuners/fc0011.h index 43ec893a6877..81bb568d6943 100644 --- a/drivers/media/tuners/fc0011.h +++ b/drivers/media/tuners/fc0011.h | |||
@@ -23,7 +23,7 @@ enum fc0011_fe_callback_commands { | |||
23 | FC0011_FE_CALLBACK_RESET, | 23 | FC0011_FE_CALLBACK_RESET, |
24 | }; | 24 | }; |
25 | 25 | ||
26 | #if IS_ENABLED(CONFIG_MEDIA_TUNER_FC0011) | 26 | #if IS_REACHABLE(CONFIG_MEDIA_TUNER_FC0011) |
27 | struct dvb_frontend *fc0011_attach(struct dvb_frontend *fe, | 27 | struct dvb_frontend *fc0011_attach(struct dvb_frontend *fe, |
28 | struct i2c_adapter *i2c, | 28 | struct i2c_adapter *i2c, |
29 | const struct fc0011_config *config); | 29 | const struct fc0011_config *config); |
diff --git a/drivers/media/tuners/fc0012.h b/drivers/media/tuners/fc0012.h index 1d08057e3275..9ad32859bab0 100644 --- a/drivers/media/tuners/fc0012.h +++ b/drivers/media/tuners/fc0012.h | |||
@@ -49,7 +49,7 @@ struct fc0012_config { | |||
49 | bool clock_out; | 49 | bool clock_out; |
50 | }; | 50 | }; |
51 | 51 | ||
52 | #if IS_ENABLED(CONFIG_MEDIA_TUNER_FC0012) | 52 | #if IS_REACHABLE(CONFIG_MEDIA_TUNER_FC0012) |
53 | extern struct dvb_frontend *fc0012_attach(struct dvb_frontend *fe, | 53 | extern struct dvb_frontend *fc0012_attach(struct dvb_frontend *fe, |
54 | struct i2c_adapter *i2c, | 54 | struct i2c_adapter *i2c, |
55 | const struct fc0012_config *cfg); | 55 | const struct fc0012_config *cfg); |
diff --git a/drivers/media/tuners/fc0013.h b/drivers/media/tuners/fc0013.h index d65d5b37f56e..e130bd7a3230 100644 --- a/drivers/media/tuners/fc0013.h +++ b/drivers/media/tuners/fc0013.h | |||
@@ -26,7 +26,7 @@ | |||
26 | #include "dvb_frontend.h" | 26 | #include "dvb_frontend.h" |
27 | #include "fc001x-common.h" | 27 | #include "fc001x-common.h" |
28 | 28 | ||
29 | #if IS_ENABLED(CONFIG_MEDIA_TUNER_FC0013) | 29 | #if IS_REACHABLE(CONFIG_MEDIA_TUNER_FC0013) |
30 | extern struct dvb_frontend *fc0013_attach(struct dvb_frontend *fe, | 30 | extern struct dvb_frontend *fc0013_attach(struct dvb_frontend *fe, |
31 | struct i2c_adapter *i2c, | 31 | struct i2c_adapter *i2c, |
32 | u8 i2c_address, int dual_master, | 32 | u8 i2c_address, int dual_master, |
diff --git a/drivers/media/tuners/fc2580.h b/drivers/media/tuners/fc2580.h index 9c43c1cc82d9..b1ce6770f88e 100644 --- a/drivers/media/tuners/fc2580.h +++ b/drivers/media/tuners/fc2580.h | |||
@@ -37,7 +37,7 @@ struct fc2580_config { | |||
37 | u32 clock; | 37 | u32 clock; |
38 | }; | 38 | }; |
39 | 39 | ||
40 | #if IS_ENABLED(CONFIG_MEDIA_TUNER_FC2580) | 40 | #if IS_REACHABLE(CONFIG_MEDIA_TUNER_FC2580) |
41 | extern struct dvb_frontend *fc2580_attach(struct dvb_frontend *fe, | 41 | extern struct dvb_frontend *fc2580_attach(struct dvb_frontend *fe, |
42 | struct i2c_adapter *i2c, const struct fc2580_config *cfg); | 42 | struct i2c_adapter *i2c, const struct fc2580_config *cfg); |
43 | #else | 43 | #else |
diff --git a/drivers/media/tuners/m88ts2022.c b/drivers/media/tuners/m88ts2022.c deleted file mode 100644 index 066e5431da93..000000000000 --- a/drivers/media/tuners/m88ts2022.c +++ /dev/null | |||
@@ -1,579 +0,0 @@ | |||
1 | /* | ||
2 | * Montage M88TS2022 silicon tuner driver | ||
3 | * | ||
4 | * Copyright (C) 2013 Antti Palosaari <crope@iki.fi> | ||
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 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * Some calculations are taken from existing TS2020 driver. | ||
17 | */ | ||
18 | |||
19 | #include "m88ts2022_priv.h" | ||
20 | |||
21 | static int m88ts2022_cmd(struct m88ts2022_dev *dev, int op, int sleep, u8 reg, | ||
22 | u8 mask, u8 val, u8 *reg_val) | ||
23 | { | ||
24 | int ret, i; | ||
25 | unsigned int utmp; | ||
26 | struct m88ts2022_reg_val reg_vals[] = { | ||
27 | {0x51, 0x1f - op}, | ||
28 | {0x51, 0x1f}, | ||
29 | {0x50, 0x00 + op}, | ||
30 | {0x50, 0x00}, | ||
31 | }; | ||
32 | |||
33 | for (i = 0; i < 2; i++) { | ||
34 | dev_dbg(&dev->client->dev, | ||
35 | "i=%d op=%02x reg=%02x mask=%02x val=%02x\n", | ||
36 | i, op, reg, mask, val); | ||
37 | |||
38 | for (i = 0; i < ARRAY_SIZE(reg_vals); i++) { | ||
39 | ret = regmap_write(dev->regmap, reg_vals[i].reg, | ||
40 | reg_vals[i].val); | ||
41 | if (ret) | ||
42 | goto err; | ||
43 | } | ||
44 | |||
45 | usleep_range(sleep * 1000, sleep * 10000); | ||
46 | |||
47 | ret = regmap_read(dev->regmap, reg, &utmp); | ||
48 | if (ret) | ||
49 | goto err; | ||
50 | |||
51 | if ((utmp & mask) != val) | ||
52 | break; | ||
53 | } | ||
54 | |||
55 | if (reg_val) | ||
56 | *reg_val = utmp; | ||
57 | err: | ||
58 | return ret; | ||
59 | } | ||
60 | |||
61 | static int m88ts2022_set_params(struct dvb_frontend *fe) | ||
62 | { | ||
63 | struct m88ts2022_dev *dev = fe->tuner_priv; | ||
64 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
65 | int ret; | ||
66 | unsigned int utmp, frequency_khz, frequency_offset_khz, f_3db_hz; | ||
67 | unsigned int f_ref_khz, f_vco_khz, div_ref, div_out, pll_n, gdiv28; | ||
68 | u8 buf[3], u8tmp, cap_code, lpf_gm, lpf_mxdiv, div_max, div_min; | ||
69 | u16 u16tmp; | ||
70 | |||
71 | dev_dbg(&dev->client->dev, | ||
72 | "frequency=%d symbol_rate=%d rolloff=%d\n", | ||
73 | c->frequency, c->symbol_rate, c->rolloff); | ||
74 | /* | ||
75 | * Integer-N PLL synthesizer | ||
76 | * kHz is used for all calculations to keep calculations within 32-bit | ||
77 | */ | ||
78 | f_ref_khz = DIV_ROUND_CLOSEST(dev->cfg.clock, 1000); | ||
79 | div_ref = DIV_ROUND_CLOSEST(f_ref_khz, 2000); | ||
80 | |||
81 | if (c->symbol_rate < 5000000) | ||
82 | frequency_offset_khz = 3000; /* 3 MHz */ | ||
83 | else | ||
84 | frequency_offset_khz = 0; | ||
85 | |||
86 | frequency_khz = c->frequency + frequency_offset_khz; | ||
87 | |||
88 | if (frequency_khz < 1103000) { | ||
89 | div_out = 4; | ||
90 | u8tmp = 0x1b; | ||
91 | } else { | ||
92 | div_out = 2; | ||
93 | u8tmp = 0x0b; | ||
94 | } | ||
95 | |||
96 | buf[0] = u8tmp; | ||
97 | buf[1] = 0x40; | ||
98 | ret = regmap_bulk_write(dev->regmap, 0x10, buf, 2); | ||
99 | if (ret) | ||
100 | goto err; | ||
101 | |||
102 | f_vco_khz = frequency_khz * div_out; | ||
103 | pll_n = f_vco_khz * div_ref / f_ref_khz; | ||
104 | pll_n += pll_n % 2; | ||
105 | dev->frequency_khz = pll_n * f_ref_khz / div_ref / div_out; | ||
106 | |||
107 | if (pll_n < 4095) | ||
108 | u16tmp = pll_n - 1024; | ||
109 | else if (pll_n < 6143) | ||
110 | u16tmp = pll_n + 1024; | ||
111 | else | ||
112 | u16tmp = pll_n + 3072; | ||
113 | |||
114 | buf[0] = (u16tmp >> 8) & 0x3f; | ||
115 | buf[1] = (u16tmp >> 0) & 0xff; | ||
116 | buf[2] = div_ref - 8; | ||
117 | ret = regmap_bulk_write(dev->regmap, 0x01, buf, 3); | ||
118 | if (ret) | ||
119 | goto err; | ||
120 | |||
121 | dev_dbg(&dev->client->dev, | ||
122 | "frequency=%u offset=%d f_vco_khz=%u pll_n=%u div_ref=%u div_out=%u\n", | ||
123 | dev->frequency_khz, dev->frequency_khz - c->frequency, | ||
124 | f_vco_khz, pll_n, div_ref, div_out); | ||
125 | |||
126 | ret = m88ts2022_cmd(dev, 0x10, 5, 0x15, 0x40, 0x00, NULL); | ||
127 | if (ret) | ||
128 | goto err; | ||
129 | |||
130 | ret = regmap_read(dev->regmap, 0x14, &utmp); | ||
131 | if (ret) | ||
132 | goto err; | ||
133 | |||
134 | utmp &= 0x7f; | ||
135 | if (utmp < 64) { | ||
136 | ret = regmap_update_bits(dev->regmap, 0x10, 0x80, 0x80); | ||
137 | if (ret) | ||
138 | goto err; | ||
139 | |||
140 | ret = regmap_write(dev->regmap, 0x11, 0x6f); | ||
141 | if (ret) | ||
142 | goto err; | ||
143 | |||
144 | ret = m88ts2022_cmd(dev, 0x10, 5, 0x15, 0x40, 0x00, NULL); | ||
145 | if (ret) | ||
146 | goto err; | ||
147 | } | ||
148 | |||
149 | ret = regmap_read(dev->regmap, 0x14, &utmp); | ||
150 | if (ret) | ||
151 | goto err; | ||
152 | |||
153 | utmp &= 0x1f; | ||
154 | if (utmp > 19) { | ||
155 | ret = regmap_update_bits(dev->regmap, 0x10, 0x02, 0x00); | ||
156 | if (ret) | ||
157 | goto err; | ||
158 | } | ||
159 | |||
160 | ret = m88ts2022_cmd(dev, 0x08, 5, 0x3c, 0xff, 0x00, NULL); | ||
161 | if (ret) | ||
162 | goto err; | ||
163 | |||
164 | ret = regmap_write(dev->regmap, 0x25, 0x00); | ||
165 | if (ret) | ||
166 | goto err; | ||
167 | |||
168 | ret = regmap_write(dev->regmap, 0x27, 0x70); | ||
169 | if (ret) | ||
170 | goto err; | ||
171 | |||
172 | ret = regmap_write(dev->regmap, 0x41, 0x09); | ||
173 | if (ret) | ||
174 | goto err; | ||
175 | |||
176 | ret = regmap_write(dev->regmap, 0x08, 0x0b); | ||
177 | if (ret) | ||
178 | goto err; | ||
179 | |||
180 | /* filters */ | ||
181 | gdiv28 = DIV_ROUND_CLOSEST(f_ref_khz * 1694U, 1000000U); | ||
182 | |||
183 | ret = regmap_write(dev->regmap, 0x04, gdiv28); | ||
184 | if (ret) | ||
185 | goto err; | ||
186 | |||
187 | ret = m88ts2022_cmd(dev, 0x04, 2, 0x26, 0xff, 0x00, &u8tmp); | ||
188 | if (ret) | ||
189 | goto err; | ||
190 | |||
191 | cap_code = u8tmp & 0x3f; | ||
192 | |||
193 | ret = regmap_write(dev->regmap, 0x41, 0x0d); | ||
194 | if (ret) | ||
195 | goto err; | ||
196 | |||
197 | ret = m88ts2022_cmd(dev, 0x04, 2, 0x26, 0xff, 0x00, &u8tmp); | ||
198 | if (ret) | ||
199 | goto err; | ||
200 | |||
201 | u8tmp &= 0x3f; | ||
202 | cap_code = (cap_code + u8tmp) / 2; | ||
203 | gdiv28 = gdiv28 * 207 / (cap_code * 2 + 151); | ||
204 | div_max = gdiv28 * 135 / 100; | ||
205 | div_min = gdiv28 * 78 / 100; | ||
206 | div_max = clamp_val(div_max, 0U, 63U); | ||
207 | |||
208 | f_3db_hz = mult_frac(c->symbol_rate, 135, 200); | ||
209 | f_3db_hz += 2000000U + (frequency_offset_khz * 1000U); | ||
210 | f_3db_hz = clamp(f_3db_hz, 7000000U, 40000000U); | ||
211 | |||
212 | #define LPF_COEFF 3200U | ||
213 | lpf_gm = DIV_ROUND_CLOSEST(f_3db_hz * gdiv28, LPF_COEFF * f_ref_khz); | ||
214 | lpf_gm = clamp_val(lpf_gm, 1U, 23U); | ||
215 | |||
216 | lpf_mxdiv = DIV_ROUND_CLOSEST(lpf_gm * LPF_COEFF * f_ref_khz, f_3db_hz); | ||
217 | if (lpf_mxdiv < div_min) | ||
218 | lpf_mxdiv = DIV_ROUND_CLOSEST(++lpf_gm * LPF_COEFF * f_ref_khz, f_3db_hz); | ||
219 | lpf_mxdiv = clamp_val(lpf_mxdiv, 0U, div_max); | ||
220 | |||
221 | ret = regmap_write(dev->regmap, 0x04, lpf_mxdiv); | ||
222 | if (ret) | ||
223 | goto err; | ||
224 | |||
225 | ret = regmap_write(dev->regmap, 0x06, lpf_gm); | ||
226 | if (ret) | ||
227 | goto err; | ||
228 | |||
229 | ret = m88ts2022_cmd(dev, 0x04, 2, 0x26, 0xff, 0x00, &u8tmp); | ||
230 | if (ret) | ||
231 | goto err; | ||
232 | |||
233 | cap_code = u8tmp & 0x3f; | ||
234 | |||
235 | ret = regmap_write(dev->regmap, 0x41, 0x09); | ||
236 | if (ret) | ||
237 | goto err; | ||
238 | |||
239 | ret = m88ts2022_cmd(dev, 0x04, 2, 0x26, 0xff, 0x00, &u8tmp); | ||
240 | if (ret) | ||
241 | goto err; | ||
242 | |||
243 | u8tmp &= 0x3f; | ||
244 | cap_code = (cap_code + u8tmp) / 2; | ||
245 | |||
246 | u8tmp = cap_code | 0x80; | ||
247 | ret = regmap_write(dev->regmap, 0x25, u8tmp); | ||
248 | if (ret) | ||
249 | goto err; | ||
250 | |||
251 | ret = regmap_write(dev->regmap, 0x27, 0x30); | ||
252 | if (ret) | ||
253 | goto err; | ||
254 | |||
255 | ret = regmap_write(dev->regmap, 0x08, 0x09); | ||
256 | if (ret) | ||
257 | goto err; | ||
258 | |||
259 | ret = m88ts2022_cmd(dev, 0x01, 20, 0x21, 0xff, 0x00, NULL); | ||
260 | if (ret) | ||
261 | goto err; | ||
262 | err: | ||
263 | if (ret) | ||
264 | dev_dbg(&dev->client->dev, "failed=%d\n", ret); | ||
265 | |||
266 | return ret; | ||
267 | } | ||
268 | |||
269 | static int m88ts2022_init(struct dvb_frontend *fe) | ||
270 | { | ||
271 | struct m88ts2022_dev *dev = fe->tuner_priv; | ||
272 | int ret, i; | ||
273 | u8 u8tmp; | ||
274 | static const struct m88ts2022_reg_val reg_vals[] = { | ||
275 | {0x7d, 0x9d}, | ||
276 | {0x7c, 0x9a}, | ||
277 | {0x7a, 0x76}, | ||
278 | {0x3b, 0x01}, | ||
279 | {0x63, 0x88}, | ||
280 | {0x61, 0x85}, | ||
281 | {0x22, 0x30}, | ||
282 | {0x30, 0x40}, | ||
283 | {0x20, 0x23}, | ||
284 | {0x24, 0x02}, | ||
285 | {0x12, 0xa0}, | ||
286 | }; | ||
287 | |||
288 | dev_dbg(&dev->client->dev, "\n"); | ||
289 | |||
290 | ret = regmap_write(dev->regmap, 0x00, 0x01); | ||
291 | if (ret) | ||
292 | goto err; | ||
293 | |||
294 | ret = regmap_write(dev->regmap, 0x00, 0x03); | ||
295 | if (ret) | ||
296 | goto err; | ||
297 | |||
298 | switch (dev->cfg.clock_out) { | ||
299 | case M88TS2022_CLOCK_OUT_DISABLED: | ||
300 | u8tmp = 0x60; | ||
301 | break; | ||
302 | case M88TS2022_CLOCK_OUT_ENABLED: | ||
303 | u8tmp = 0x70; | ||
304 | ret = regmap_write(dev->regmap, 0x05, dev->cfg.clock_out_div); | ||
305 | if (ret) | ||
306 | goto err; | ||
307 | break; | ||
308 | case M88TS2022_CLOCK_OUT_ENABLED_XTALOUT: | ||
309 | u8tmp = 0x6c; | ||
310 | break; | ||
311 | default: | ||
312 | goto err; | ||
313 | } | ||
314 | |||
315 | ret = regmap_write(dev->regmap, 0x42, u8tmp); | ||
316 | if (ret) | ||
317 | goto err; | ||
318 | |||
319 | if (dev->cfg.loop_through) | ||
320 | u8tmp = 0xec; | ||
321 | else | ||
322 | u8tmp = 0x6c; | ||
323 | |||
324 | ret = regmap_write(dev->regmap, 0x62, u8tmp); | ||
325 | if (ret) | ||
326 | goto err; | ||
327 | |||
328 | for (i = 0; i < ARRAY_SIZE(reg_vals); i++) { | ||
329 | ret = regmap_write(dev->regmap, reg_vals[i].reg, reg_vals[i].val); | ||
330 | if (ret) | ||
331 | goto err; | ||
332 | } | ||
333 | err: | ||
334 | if (ret) | ||
335 | dev_dbg(&dev->client->dev, "failed=%d\n", ret); | ||
336 | return ret; | ||
337 | } | ||
338 | |||
339 | static int m88ts2022_sleep(struct dvb_frontend *fe) | ||
340 | { | ||
341 | struct m88ts2022_dev *dev = fe->tuner_priv; | ||
342 | int ret; | ||
343 | |||
344 | dev_dbg(&dev->client->dev, "\n"); | ||
345 | |||
346 | ret = regmap_write(dev->regmap, 0x00, 0x00); | ||
347 | if (ret) | ||
348 | goto err; | ||
349 | err: | ||
350 | if (ret) | ||
351 | dev_dbg(&dev->client->dev, "failed=%d\n", ret); | ||
352 | return ret; | ||
353 | } | ||
354 | |||
355 | static int m88ts2022_get_frequency(struct dvb_frontend *fe, u32 *frequency) | ||
356 | { | ||
357 | struct m88ts2022_dev *dev = fe->tuner_priv; | ||
358 | |||
359 | dev_dbg(&dev->client->dev, "\n"); | ||
360 | |||
361 | *frequency = dev->frequency_khz; | ||
362 | return 0; | ||
363 | } | ||
364 | |||
365 | static int m88ts2022_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) | ||
366 | { | ||
367 | struct m88ts2022_dev *dev = fe->tuner_priv; | ||
368 | |||
369 | dev_dbg(&dev->client->dev, "\n"); | ||
370 | |||
371 | *frequency = 0; /* Zero-IF */ | ||
372 | return 0; | ||
373 | } | ||
374 | |||
375 | static int m88ts2022_get_rf_strength(struct dvb_frontend *fe, u16 *strength) | ||
376 | { | ||
377 | struct m88ts2022_dev *dev = fe->tuner_priv; | ||
378 | int ret; | ||
379 | u16 gain, u16tmp; | ||
380 | unsigned int utmp, gain1, gain2, gain3; | ||
381 | |||
382 | ret = regmap_read(dev->regmap, 0x3d, &utmp); | ||
383 | if (ret) | ||
384 | goto err; | ||
385 | |||
386 | gain1 = (utmp >> 0) & 0x1f; | ||
387 | gain1 = clamp(gain1, 0U, 15U); | ||
388 | |||
389 | ret = regmap_read(dev->regmap, 0x21, &utmp); | ||
390 | if (ret) | ||
391 | goto err; | ||
392 | |||
393 | gain2 = (utmp >> 0) & 0x1f; | ||
394 | gain2 = clamp(gain2, 2U, 16U); | ||
395 | |||
396 | ret = regmap_read(dev->regmap, 0x66, &utmp); | ||
397 | if (ret) | ||
398 | goto err; | ||
399 | |||
400 | gain3 = (utmp >> 3) & 0x07; | ||
401 | gain3 = clamp(gain3, 0U, 6U); | ||
402 | |||
403 | gain = gain1 * 265 + gain2 * 338 + gain3 * 285; | ||
404 | |||
405 | /* scale value to 0x0000-0xffff */ | ||
406 | u16tmp = (0xffff - gain); | ||
407 | u16tmp = clamp_val(u16tmp, 59000U, 61500U); | ||
408 | |||
409 | *strength = (u16tmp - 59000) * 0xffff / (61500 - 59000); | ||
410 | err: | ||
411 | if (ret) | ||
412 | dev_dbg(&dev->client->dev, "failed=%d\n", ret); | ||
413 | return ret; | ||
414 | } | ||
415 | |||
416 | static const struct dvb_tuner_ops m88ts2022_tuner_ops = { | ||
417 | .info = { | ||
418 | .name = "Montage M88TS2022", | ||
419 | .frequency_min = 950000, | ||
420 | .frequency_max = 2150000, | ||
421 | }, | ||
422 | |||
423 | .init = m88ts2022_init, | ||
424 | .sleep = m88ts2022_sleep, | ||
425 | .set_params = m88ts2022_set_params, | ||
426 | |||
427 | .get_frequency = m88ts2022_get_frequency, | ||
428 | .get_if_frequency = m88ts2022_get_if_frequency, | ||
429 | .get_rf_strength = m88ts2022_get_rf_strength, | ||
430 | }; | ||
431 | |||
432 | static int m88ts2022_probe(struct i2c_client *client, | ||
433 | const struct i2c_device_id *id) | ||
434 | { | ||
435 | struct m88ts2022_config *cfg = client->dev.platform_data; | ||
436 | struct dvb_frontend *fe = cfg->fe; | ||
437 | struct m88ts2022_dev *dev; | ||
438 | int ret; | ||
439 | u8 u8tmp; | ||
440 | unsigned int utmp; | ||
441 | static const struct regmap_config regmap_config = { | ||
442 | .reg_bits = 8, | ||
443 | .val_bits = 8, | ||
444 | }; | ||
445 | |||
446 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
447 | if (!dev) { | ||
448 | ret = -ENOMEM; | ||
449 | dev_err(&client->dev, "kzalloc() failed\n"); | ||
450 | goto err; | ||
451 | } | ||
452 | |||
453 | memcpy(&dev->cfg, cfg, sizeof(struct m88ts2022_config)); | ||
454 | dev->client = client; | ||
455 | dev->regmap = devm_regmap_init_i2c(client, ®map_config); | ||
456 | if (IS_ERR(dev->regmap)) { | ||
457 | ret = PTR_ERR(dev->regmap); | ||
458 | goto err; | ||
459 | } | ||
460 | |||
461 | /* check if the tuner is there */ | ||
462 | ret = regmap_read(dev->regmap, 0x00, &utmp); | ||
463 | if (ret) | ||
464 | goto err; | ||
465 | |||
466 | if ((utmp & 0x03) == 0x00) { | ||
467 | ret = regmap_write(dev->regmap, 0x00, 0x01); | ||
468 | if (ret) | ||
469 | goto err; | ||
470 | |||
471 | usleep_range(2000, 50000); | ||
472 | } | ||
473 | |||
474 | ret = regmap_write(dev->regmap, 0x00, 0x03); | ||
475 | if (ret) | ||
476 | goto err; | ||
477 | |||
478 | usleep_range(2000, 50000); | ||
479 | |||
480 | ret = regmap_read(dev->regmap, 0x00, &utmp); | ||
481 | if (ret) | ||
482 | goto err; | ||
483 | |||
484 | dev_dbg(&dev->client->dev, "chip_id=%02x\n", utmp); | ||
485 | |||
486 | switch (utmp) { | ||
487 | case 0xc3: | ||
488 | case 0x83: | ||
489 | break; | ||
490 | default: | ||
491 | ret = -ENODEV; | ||
492 | goto err; | ||
493 | } | ||
494 | |||
495 | switch (dev->cfg.clock_out) { | ||
496 | case M88TS2022_CLOCK_OUT_DISABLED: | ||
497 | u8tmp = 0x60; | ||
498 | break; | ||
499 | case M88TS2022_CLOCK_OUT_ENABLED: | ||
500 | u8tmp = 0x70; | ||
501 | ret = regmap_write(dev->regmap, 0x05, dev->cfg.clock_out_div); | ||
502 | if (ret) | ||
503 | goto err; | ||
504 | break; | ||
505 | case M88TS2022_CLOCK_OUT_ENABLED_XTALOUT: | ||
506 | u8tmp = 0x6c; | ||
507 | break; | ||
508 | default: | ||
509 | ret = -EINVAL; | ||
510 | goto err; | ||
511 | } | ||
512 | |||
513 | ret = regmap_write(dev->regmap, 0x42, u8tmp); | ||
514 | if (ret) | ||
515 | goto err; | ||
516 | |||
517 | if (dev->cfg.loop_through) | ||
518 | u8tmp = 0xec; | ||
519 | else | ||
520 | u8tmp = 0x6c; | ||
521 | |||
522 | ret = regmap_write(dev->regmap, 0x62, u8tmp); | ||
523 | if (ret) | ||
524 | goto err; | ||
525 | |||
526 | /* sleep */ | ||
527 | ret = regmap_write(dev->regmap, 0x00, 0x00); | ||
528 | if (ret) | ||
529 | goto err; | ||
530 | |||
531 | dev_info(&dev->client->dev, "Montage M88TS2022 successfully identified\n"); | ||
532 | |||
533 | fe->tuner_priv = dev; | ||
534 | memcpy(&fe->ops.tuner_ops, &m88ts2022_tuner_ops, | ||
535 | sizeof(struct dvb_tuner_ops)); | ||
536 | |||
537 | i2c_set_clientdata(client, dev); | ||
538 | return 0; | ||
539 | err: | ||
540 | dev_dbg(&client->dev, "failed=%d\n", ret); | ||
541 | kfree(dev); | ||
542 | return ret; | ||
543 | } | ||
544 | |||
545 | static int m88ts2022_remove(struct i2c_client *client) | ||
546 | { | ||
547 | struct m88ts2022_dev *dev = i2c_get_clientdata(client); | ||
548 | struct dvb_frontend *fe = dev->cfg.fe; | ||
549 | |||
550 | dev_dbg(&client->dev, "\n"); | ||
551 | |||
552 | memset(&fe->ops.tuner_ops, 0, sizeof(struct dvb_tuner_ops)); | ||
553 | fe->tuner_priv = NULL; | ||
554 | kfree(dev); | ||
555 | |||
556 | return 0; | ||
557 | } | ||
558 | |||
559 | static const struct i2c_device_id m88ts2022_id[] = { | ||
560 | {"m88ts2022", 0}, | ||
561 | {} | ||
562 | }; | ||
563 | MODULE_DEVICE_TABLE(i2c, m88ts2022_id); | ||
564 | |||
565 | static struct i2c_driver m88ts2022_driver = { | ||
566 | .driver = { | ||
567 | .owner = THIS_MODULE, | ||
568 | .name = "m88ts2022", | ||
569 | }, | ||
570 | .probe = m88ts2022_probe, | ||
571 | .remove = m88ts2022_remove, | ||
572 | .id_table = m88ts2022_id, | ||
573 | }; | ||
574 | |||
575 | module_i2c_driver(m88ts2022_driver); | ||
576 | |||
577 | MODULE_DESCRIPTION("Montage M88TS2022 silicon tuner driver"); | ||
578 | MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); | ||
579 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/tuners/m88ts2022.h b/drivers/media/tuners/m88ts2022.h deleted file mode 100644 index 659fa1b1633a..000000000000 --- a/drivers/media/tuners/m88ts2022.h +++ /dev/null | |||
@@ -1,54 +0,0 @@ | |||
1 | /* | ||
2 | * Montage M88TS2022 silicon tuner driver | ||
3 | * | ||
4 | * Copyright (C) 2013 Antti Palosaari <crope@iki.fi> | ||
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 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #ifndef M88TS2022_H | ||
18 | #define M88TS2022_H | ||
19 | |||
20 | #include "dvb_frontend.h" | ||
21 | |||
22 | struct m88ts2022_config { | ||
23 | /* | ||
24 | * clock | ||
25 | * 16000000 - 32000000 | ||
26 | */ | ||
27 | u32 clock; | ||
28 | |||
29 | /* | ||
30 | * RF loop-through | ||
31 | */ | ||
32 | u8 loop_through:1; | ||
33 | |||
34 | /* | ||
35 | * clock output | ||
36 | */ | ||
37 | #define M88TS2022_CLOCK_OUT_DISABLED 0 | ||
38 | #define M88TS2022_CLOCK_OUT_ENABLED 1 | ||
39 | #define M88TS2022_CLOCK_OUT_ENABLED_XTALOUT 2 | ||
40 | u8 clock_out:2; | ||
41 | |||
42 | /* | ||
43 | * clock output divider | ||
44 | * 1 - 31 | ||
45 | */ | ||
46 | u8 clock_out_div:5; | ||
47 | |||
48 | /* | ||
49 | * pointer to DVB frontend | ||
50 | */ | ||
51 | struct dvb_frontend *fe; | ||
52 | }; | ||
53 | |||
54 | #endif | ||
diff --git a/drivers/media/tuners/m88ts2022_priv.h b/drivers/media/tuners/m88ts2022_priv.h deleted file mode 100644 index feeb5ad6beef..000000000000 --- a/drivers/media/tuners/m88ts2022_priv.h +++ /dev/null | |||
@@ -1,35 +0,0 @@ | |||
1 | /* | ||
2 | * Montage M88TS2022 silicon tuner driver | ||
3 | * | ||
4 | * Copyright (C) 2013 Antti Palosaari <crope@iki.fi> | ||
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 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #ifndef M88TS2022_PRIV_H | ||
18 | #define M88TS2022_PRIV_H | ||
19 | |||
20 | #include "m88ts2022.h" | ||
21 | #include <linux/regmap.h> | ||
22 | |||
23 | struct m88ts2022_dev { | ||
24 | struct m88ts2022_config cfg; | ||
25 | struct i2c_client *client; | ||
26 | struct regmap *regmap; | ||
27 | u32 frequency_khz; | ||
28 | }; | ||
29 | |||
30 | struct m88ts2022_reg_val { | ||
31 | u8 reg; | ||
32 | u8 val; | ||
33 | }; | ||
34 | |||
35 | #endif | ||
diff --git a/drivers/media/tuners/max2165.h b/drivers/media/tuners/max2165.h index 26e1dc64bb67..5054f01a78fb 100644 --- a/drivers/media/tuners/max2165.h +++ b/drivers/media/tuners/max2165.h | |||
@@ -32,7 +32,7 @@ struct max2165_config { | |||
32 | u8 osc_clk; /* in MHz, selectable values: 4,16,18,20,22,24,26,28 */ | 32 | u8 osc_clk; /* in MHz, selectable values: 4,16,18,20,22,24,26,28 */ |
33 | }; | 33 | }; |
34 | 34 | ||
35 | #if IS_ENABLED(CONFIG_MEDIA_TUNER_MAX2165) | 35 | #if IS_REACHABLE(CONFIG_MEDIA_TUNER_MAX2165) |
36 | extern struct dvb_frontend *max2165_attach(struct dvb_frontend *fe, | 36 | extern struct dvb_frontend *max2165_attach(struct dvb_frontend *fe, |
37 | struct i2c_adapter *i2c, | 37 | struct i2c_adapter *i2c, |
38 | struct max2165_config *cfg); | 38 | struct max2165_config *cfg); |
diff --git a/drivers/media/tuners/mc44s803.h b/drivers/media/tuners/mc44s803.h index 9aae50aca2b7..b3e614be657d 100644 --- a/drivers/media/tuners/mc44s803.h +++ b/drivers/media/tuners/mc44s803.h | |||
@@ -32,7 +32,7 @@ struct mc44s803_config { | |||
32 | u8 dig_out; | 32 | u8 dig_out; |
33 | }; | 33 | }; |
34 | 34 | ||
35 | #if IS_ENABLED(CONFIG_MEDIA_TUNER_MC44S803) | 35 | #if IS_REACHABLE(CONFIG_MEDIA_TUNER_MC44S803) |
36 | extern struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe, | 36 | extern struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe, |
37 | struct i2c_adapter *i2c, struct mc44s803_config *cfg); | 37 | struct i2c_adapter *i2c, struct mc44s803_config *cfg); |
38 | #else | 38 | #else |
diff --git a/drivers/media/tuners/mt2060.h b/drivers/media/tuners/mt2060.h index c64fc19cb278..6efed359a24f 100644 --- a/drivers/media/tuners/mt2060.h +++ b/drivers/media/tuners/mt2060.h | |||
@@ -30,7 +30,7 @@ struct mt2060_config { | |||
30 | u8 clock_out; /* 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1 */ | 30 | u8 clock_out; /* 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1 */ |
31 | }; | 31 | }; |
32 | 32 | ||
33 | #if IS_ENABLED(CONFIG_MEDIA_TUNER_MT2060) | 33 | #if IS_REACHABLE(CONFIG_MEDIA_TUNER_MT2060) |
34 | extern struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1); | 34 | extern struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1); |
35 | #else | 35 | #else |
36 | static inline struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1) | 36 | static inline struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1) |
diff --git a/drivers/media/tuners/mt2063.h b/drivers/media/tuners/mt2063.h index e1acfc8e7ae3..e55e0a6dd1be 100644 --- a/drivers/media/tuners/mt2063.h +++ b/drivers/media/tuners/mt2063.h | |||
@@ -8,7 +8,7 @@ struct mt2063_config { | |||
8 | u32 refclock; | 8 | u32 refclock; |
9 | }; | 9 | }; |
10 | 10 | ||
11 | #if IS_ENABLED(CONFIG_MEDIA_TUNER_MT2063) | 11 | #if IS_REACHABLE(CONFIG_MEDIA_TUNER_MT2063) |
12 | struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe, | 12 | struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe, |
13 | struct mt2063_config *config, | 13 | struct mt2063_config *config, |
14 | struct i2c_adapter *i2c); | 14 | struct i2c_adapter *i2c); |
diff --git a/drivers/media/tuners/mt20xx.h b/drivers/media/tuners/mt20xx.h index f56241ccaa00..9912362b415e 100644 --- a/drivers/media/tuners/mt20xx.h +++ b/drivers/media/tuners/mt20xx.h | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
21 | #include "dvb_frontend.h" | 21 | #include "dvb_frontend.h" |
22 | 22 | ||
23 | #if IS_ENABLED(CONFIG_MEDIA_TUNER_MT20XX) | 23 | #if IS_REACHABLE(CONFIG_MEDIA_TUNER_MT20XX) |
24 | extern struct dvb_frontend *microtune_attach(struct dvb_frontend *fe, | 24 | extern struct dvb_frontend *microtune_attach(struct dvb_frontend *fe, |
25 | struct i2c_adapter* i2c_adap, | 25 | struct i2c_adapter* i2c_adap, |
26 | u8 i2c_addr); | 26 | u8 i2c_addr); |
diff --git a/drivers/media/tuners/mt2131.h b/drivers/media/tuners/mt2131.h index 837c854b9c65..8267a6ae5d84 100644 --- a/drivers/media/tuners/mt2131.h +++ b/drivers/media/tuners/mt2131.h | |||
@@ -30,7 +30,7 @@ struct mt2131_config { | |||
30 | u8 clock_out; /* 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1 */ | 30 | u8 clock_out; /* 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1 */ |
31 | }; | 31 | }; |
32 | 32 | ||
33 | #if IS_ENABLED(CONFIG_MEDIA_TUNER_MT2131) | 33 | #if IS_REACHABLE(CONFIG_MEDIA_TUNER_MT2131) |
34 | extern struct dvb_frontend* mt2131_attach(struct dvb_frontend *fe, | 34 | extern struct dvb_frontend* mt2131_attach(struct dvb_frontend *fe, |
35 | struct i2c_adapter *i2c, | 35 | struct i2c_adapter *i2c, |
36 | struct mt2131_config *cfg, | 36 | struct mt2131_config *cfg, |
diff --git a/drivers/media/tuners/mt2266.h b/drivers/media/tuners/mt2266.h index fad6dd657d77..69abefa18c37 100644 --- a/drivers/media/tuners/mt2266.h +++ b/drivers/media/tuners/mt2266.h | |||
@@ -24,7 +24,7 @@ struct mt2266_config { | |||
24 | u8 i2c_address; | 24 | u8 i2c_address; |
25 | }; | 25 | }; |
26 | 26 | ||
27 | #if IS_ENABLED(CONFIG_MEDIA_TUNER_MT2266) | 27 | #if IS_REACHABLE(CONFIG_MEDIA_TUNER_MT2266) |
28 | extern struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg); | 28 | extern struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg); |
29 | #else | 29 | #else |
30 | static inline struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg) | 30 | static inline struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg) |
diff --git a/drivers/media/tuners/mxl5005s.h b/drivers/media/tuners/mxl5005s.h index ae8db885ad87..5764b12c5c7c 100644 --- a/drivers/media/tuners/mxl5005s.h +++ b/drivers/media/tuners/mxl5005s.h | |||
@@ -118,7 +118,7 @@ struct mxl5005s_config { | |||
118 | u8 AgcMasterByte; | 118 | u8 AgcMasterByte; |
119 | }; | 119 | }; |
120 | 120 | ||
121 | #if IS_ENABLED(CONFIG_MEDIA_TUNER_MXL5005S) | 121 | #if IS_REACHABLE(CONFIG_MEDIA_TUNER_MXL5005S) |
122 | extern struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe, | 122 | extern struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe, |
123 | struct i2c_adapter *i2c, | 123 | struct i2c_adapter *i2c, |
124 | struct mxl5005s_config *config); | 124 | struct mxl5005s_config *config); |
diff --git a/drivers/media/tuners/mxl5007t.h b/drivers/media/tuners/mxl5007t.h index ae7037d681c5..e786d1f23ff1 100644 --- a/drivers/media/tuners/mxl5007t.h +++ b/drivers/media/tuners/mxl5007t.h | |||
@@ -77,7 +77,7 @@ struct mxl5007t_config { | |||
77 | unsigned int clk_out_enable:1; | 77 | unsigned int clk_out_enable:1; |
78 | }; | 78 | }; |
79 | 79 | ||
80 | #if IS_ENABLED(CONFIG_MEDIA_TUNER_MXL5007T) | 80 | #if IS_REACHABLE(CONFIG_MEDIA_TUNER_MXL5007T) |
81 | extern struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe, | 81 | extern struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe, |
82 | struct i2c_adapter *i2c, u8 addr, | 82 | struct i2c_adapter *i2c, u8 addr, |
83 | struct mxl5007t_config *cfg); | 83 | struct mxl5007t_config *cfg); |
diff --git a/drivers/media/tuners/qt1010.h b/drivers/media/tuners/qt1010.h index 8ab5d479749f..e3198f23437c 100644 --- a/drivers/media/tuners/qt1010.h +++ b/drivers/media/tuners/qt1010.h | |||
@@ -36,7 +36,7 @@ struct qt1010_config { | |||
36 | * @param cfg tuner hw based configuration | 36 | * @param cfg tuner hw based configuration |
37 | * @return fe pointer on success, NULL on failure | 37 | * @return fe pointer on success, NULL on failure |
38 | */ | 38 | */ |
39 | #if IS_ENABLED(CONFIG_MEDIA_TUNER_QT1010) | 39 | #if IS_REACHABLE(CONFIG_MEDIA_TUNER_QT1010) |
40 | extern struct dvb_frontend *qt1010_attach(struct dvb_frontend *fe, | 40 | extern struct dvb_frontend *qt1010_attach(struct dvb_frontend *fe, |
41 | struct i2c_adapter *i2c, | 41 | struct i2c_adapter *i2c, |
42 | struct qt1010_config *cfg); | 42 | struct qt1010_config *cfg); |
diff --git a/drivers/media/tuners/r820t.c b/drivers/media/tuners/r820t.c index 8e040cf9cf13..71159a58860f 100644 --- a/drivers/media/tuners/r820t.c +++ b/drivers/media/tuners/r820t.c | |||
@@ -775,6 +775,19 @@ static int r820t_sysfreq_sel(struct r820t_priv *priv, u32 freq, | |||
775 | div_buf_cur = 0x30; /* 11, 150u */ | 775 | div_buf_cur = 0x30; /* 11, 150u */ |
776 | filter_cur = 0x40; /* 10, low */ | 776 | filter_cur = 0x40; /* 10, low */ |
777 | break; | 777 | break; |
778 | case SYS_DVBC_ANNEX_A: | ||
779 | mixer_top = 0x24; /* mixer top:13 , top-1, low-discharge */ | ||
780 | lna_top = 0xe5; | ||
781 | lna_vth_l = 0x62; | ||
782 | mixer_vth_l = 0x75; | ||
783 | air_cable1_in = 0x60; | ||
784 | cable2_in = 0x00; | ||
785 | pre_dect = 0x40; | ||
786 | lna_discharge = 14; | ||
787 | cp_cur = 0x38; /* 111, auto */ | ||
788 | div_buf_cur = 0x30; /* 11, 150u */ | ||
789 | filter_cur = 0x40; /* 10, low */ | ||
790 | break; | ||
778 | default: /* DVB-T 8M */ | 791 | default: /* DVB-T 8M */ |
779 | mixer_top = 0x24; /* mixer top:13 , top-1, low-discharge */ | 792 | mixer_top = 0x24; /* mixer top:13 , top-1, low-discharge */ |
780 | lna_top = 0xe5; /* detect bw 3, lna top:4, predet top:2 */ | 793 | lna_top = 0xe5; /* detect bw 3, lna top:4, predet top:2 */ |
@@ -957,7 +970,7 @@ static int r820t_set_tv_standard(struct r820t_priv *priv, | |||
957 | ext_enable = 0x40; /* r30[6], ext enable; r30[5]:0 ext at lna max */ | 970 | ext_enable = 0x40; /* r30[6], ext enable; r30[5]:0 ext at lna max */ |
958 | loop_through = 0x00; /* r5[7], lt on */ | 971 | loop_through = 0x00; /* r5[7], lt on */ |
959 | lt_att = 0x00; /* r31[7], lt att enable */ | 972 | lt_att = 0x00; /* r31[7], lt att enable */ |
960 | flt_ext_widest = 0x00; /* r15[7]: flt_ext_wide off */ | 973 | flt_ext_widest = 0x80; /* r15[7]: flt_ext_wide on */ |
961 | polyfil_cur = 0x60; /* r25[6:5]:min */ | 974 | polyfil_cur = 0x60; /* r25[6:5]:min */ |
962 | } else if (delsys == SYS_DVBC_ANNEX_A) { | 975 | } else if (delsys == SYS_DVBC_ANNEX_A) { |
963 | if_khz = 5070; | 976 | if_khz = 5070; |
@@ -971,6 +984,18 @@ static int r820t_set_tv_standard(struct r820t_priv *priv, | |||
971 | lt_att = 0x00; /* r31[7], lt att enable */ | 984 | lt_att = 0x00; /* r31[7], lt att enable */ |
972 | flt_ext_widest = 0x00; /* r15[7]: flt_ext_wide off */ | 985 | flt_ext_widest = 0x00; /* r15[7]: flt_ext_wide off */ |
973 | polyfil_cur = 0x60; /* r25[6:5]:min */ | 986 | polyfil_cur = 0x60; /* r25[6:5]:min */ |
987 | } else if (delsys == SYS_DVBC_ANNEX_C) { | ||
988 | if_khz = 4063; | ||
989 | filt_cal_lo = 55000; | ||
990 | filt_gain = 0x10; /* +3db, 6mhz on */ | ||
991 | img_r = 0x00; /* image negative */ | ||
992 | filt_q = 0x10; /* r10[4]:low q(1'b1) */ | ||
993 | hp_cor = 0x6a; /* 1.7m disable, +0cap, 1.0mhz */ | ||
994 | ext_enable = 0x40; /* r30[6]=1 ext enable; r30[5]:1 ext at lna max-1 */ | ||
995 | loop_through = 0x00; /* r5[7], lt on */ | ||
996 | lt_att = 0x00; /* r31[7], lt att enable */ | ||
997 | flt_ext_widest = 0x80; /* r15[7]: flt_ext_wide on */ | ||
998 | polyfil_cur = 0x60; /* r25[6:5]:min */ | ||
974 | } else { | 999 | } else { |
975 | if (bw <= 6) { | 1000 | if (bw <= 6) { |
976 | if_khz = 3570; | 1001 | if_khz = 3570; |
@@ -1186,7 +1211,7 @@ static int r820t_read_gain(struct r820t_priv *priv) | |||
1186 | if (rc < 0) | 1211 | if (rc < 0) |
1187 | return rc; | 1212 | return rc; |
1188 | 1213 | ||
1189 | return ((data[3] & 0x0f) << 1) + ((data[3] & 0xf0) >> 4); | 1214 | return ((data[3] & 0x08) << 1) + ((data[3] & 0xf0) >> 4); |
1190 | } | 1215 | } |
1191 | 1216 | ||
1192 | #if 0 | 1217 | #if 0 |
diff --git a/drivers/media/tuners/r820t.h b/drivers/media/tuners/r820t.h index 48af3548027d..b1e5661af1c7 100644 --- a/drivers/media/tuners/r820t.h +++ b/drivers/media/tuners/r820t.h | |||
@@ -42,7 +42,7 @@ struct r820t_config { | |||
42 | bool use_predetect; | 42 | bool use_predetect; |
43 | }; | 43 | }; |
44 | 44 | ||
45 | #if IS_ENABLED(CONFIG_MEDIA_TUNER_R820T) | 45 | #if IS_REACHABLE(CONFIG_MEDIA_TUNER_R820T) |
46 | struct dvb_frontend *r820t_attach(struct dvb_frontend *fe, | 46 | struct dvb_frontend *r820t_attach(struct dvb_frontend *fe, |
47 | struct i2c_adapter *i2c, | 47 | struct i2c_adapter *i2c, |
48 | const struct r820t_config *cfg); | 48 | const struct r820t_config *cfg); |
diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c index fcf139dfdec6..d74ae26621ca 100644 --- a/drivers/media/tuners/si2157.c +++ b/drivers/media/tuners/si2157.c | |||
@@ -244,6 +244,7 @@ static int si2157_set_params(struct dvb_frontend *fe) | |||
244 | int ret; | 244 | int ret; |
245 | struct si2157_cmd cmd; | 245 | struct si2157_cmd cmd; |
246 | u8 bandwidth, delivery_system; | 246 | u8 bandwidth, delivery_system; |
247 | u32 if_frequency = 5000000; | ||
247 | 248 | ||
248 | dev_dbg(&client->dev, | 249 | dev_dbg(&client->dev, |
249 | "delivery_system=%d frequency=%u bandwidth_hz=%u\n", | 250 | "delivery_system=%d frequency=%u bandwidth_hz=%u\n", |
@@ -266,9 +267,11 @@ static int si2157_set_params(struct dvb_frontend *fe) | |||
266 | switch (c->delivery_system) { | 267 | switch (c->delivery_system) { |
267 | case SYS_ATSC: | 268 | case SYS_ATSC: |
268 | delivery_system = 0x00; | 269 | delivery_system = 0x00; |
270 | if_frequency = 3250000; | ||
269 | break; | 271 | break; |
270 | case SYS_DVBC_ANNEX_B: | 272 | case SYS_DVBC_ANNEX_B: |
271 | delivery_system = 0x10; | 273 | delivery_system = 0x10; |
274 | if_frequency = 4000000; | ||
272 | break; | 275 | break; |
273 | case SYS_DVBT: | 276 | case SYS_DVBT: |
274 | case SYS_DVBT2: /* it seems DVB-T and DVB-T2 both are 0x20 here */ | 277 | case SYS_DVBT2: /* it seems DVB-T and DVB-T2 both are 0x20 here */ |
@@ -302,6 +305,20 @@ static int si2157_set_params(struct dvb_frontend *fe) | |||
302 | if (ret) | 305 | if (ret) |
303 | goto err; | 306 | goto err; |
304 | 307 | ||
308 | /* set if frequency if needed */ | ||
309 | if (if_frequency != dev->if_frequency) { | ||
310 | memcpy(cmd.args, "\x14\x00\x06\x07", 4); | ||
311 | cmd.args[4] = (if_frequency / 1000) & 0xff; | ||
312 | cmd.args[5] = ((if_frequency / 1000) >> 8) & 0xff; | ||
313 | cmd.wlen = 6; | ||
314 | cmd.rlen = 4; | ||
315 | ret = si2157_cmd_execute(client, &cmd); | ||
316 | if (ret) | ||
317 | goto err; | ||
318 | |||
319 | dev->if_frequency = if_frequency; | ||
320 | } | ||
321 | |||
305 | /* set frequency */ | 322 | /* set frequency */ |
306 | memcpy(cmd.args, "\x41\x00\x00\x00\x00\x00\x00\x00", 8); | 323 | memcpy(cmd.args, "\x41\x00\x00\x00\x00\x00\x00\x00", 8); |
307 | cmd.args[4] = (c->frequency >> 0) & 0xff; | 324 | cmd.args[4] = (c->frequency >> 0) & 0xff; |
@@ -322,14 +339,17 @@ err: | |||
322 | 339 | ||
323 | static int si2157_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) | 340 | static int si2157_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) |
324 | { | 341 | { |
325 | *frequency = 5000000; /* default value of property 0x0706 */ | 342 | struct i2c_client *client = fe->tuner_priv; |
343 | struct si2157_dev *dev = i2c_get_clientdata(client); | ||
344 | |||
345 | *frequency = dev->if_frequency; | ||
326 | return 0; | 346 | return 0; |
327 | } | 347 | } |
328 | 348 | ||
329 | static const struct dvb_tuner_ops si2157_ops = { | 349 | static const struct dvb_tuner_ops si2157_ops = { |
330 | .info = { | 350 | .info = { |
331 | .name = "Silicon Labs Si2146/2147/2148/2157/2158", | 351 | .name = "Silicon Labs Si2146/2147/2148/2157/2158", |
332 | .frequency_min = 110000000, | 352 | .frequency_min = 55000000, |
333 | .frequency_max = 862000000, | 353 | .frequency_max = 862000000, |
334 | }, | 354 | }, |
335 | 355 | ||
@@ -360,6 +380,7 @@ static int si2157_probe(struct i2c_client *client, | |||
360 | dev->inversion = cfg->inversion; | 380 | dev->inversion = cfg->inversion; |
361 | dev->fw_loaded = false; | 381 | dev->fw_loaded = false; |
362 | dev->chiptype = (u8)id->driver_data; | 382 | dev->chiptype = (u8)id->driver_data; |
383 | dev->if_frequency = 5000000; /* default value of property 0x0706 */ | ||
363 | mutex_init(&dev->i2c_mutex); | 384 | mutex_init(&dev->i2c_mutex); |
364 | 385 | ||
365 | /* check if the tuner is there */ | 386 | /* check if the tuner is there */ |
diff --git a/drivers/media/tuners/si2157_priv.h b/drivers/media/tuners/si2157_priv.h index 7aa53bce5593..cd8fa5b25304 100644 --- a/drivers/media/tuners/si2157_priv.h +++ b/drivers/media/tuners/si2157_priv.h | |||
@@ -28,6 +28,7 @@ struct si2157_dev { | |||
28 | bool fw_loaded; | 28 | bool fw_loaded; |
29 | bool inversion; | 29 | bool inversion; |
30 | u8 chiptype; | 30 | u8 chiptype; |
31 | u32 if_frequency; | ||
31 | }; | 32 | }; |
32 | 33 | ||
33 | #define SI2157_CHIPTYPE_SI2157 0 | 34 | #define SI2157_CHIPTYPE_SI2157 0 |
diff --git a/drivers/media/tuners/tda18218.h b/drivers/media/tuners/tda18218.h index 366410e0cc9a..1eacb4f84e93 100644 --- a/drivers/media/tuners/tda18218.h +++ b/drivers/media/tuners/tda18218.h | |||
@@ -30,7 +30,7 @@ struct tda18218_config { | |||
30 | u8 loop_through:1; | 30 | u8 loop_through:1; |
31 | }; | 31 | }; |
32 | 32 | ||
33 | #if IS_ENABLED(CONFIG_MEDIA_TUNER_TDA18218) | 33 | #if IS_REACHABLE(CONFIG_MEDIA_TUNER_TDA18218) |
34 | extern struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe, | 34 | extern struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe, |
35 | struct i2c_adapter *i2c, struct tda18218_config *cfg); | 35 | struct i2c_adapter *i2c, struct tda18218_config *cfg); |
36 | #else | 36 | #else |
diff --git a/drivers/media/tuners/tda18271.h b/drivers/media/tuners/tda18271.h index 4c418d63f540..0a846333ce57 100644 --- a/drivers/media/tuners/tda18271.h +++ b/drivers/media/tuners/tda18271.h | |||
@@ -121,7 +121,7 @@ enum tda18271_mode { | |||
121 | TDA18271_DIGITAL, | 121 | TDA18271_DIGITAL, |
122 | }; | 122 | }; |
123 | 123 | ||
124 | #if IS_ENABLED(CONFIG_MEDIA_TUNER_TDA18271) | 124 | #if IS_REACHABLE(CONFIG_MEDIA_TUNER_TDA18271) |
125 | extern struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, | 125 | extern struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, |
126 | struct i2c_adapter *i2c, | 126 | struct i2c_adapter *i2c, |
127 | struct tda18271_config *cfg); | 127 | struct tda18271_config *cfg); |
diff --git a/drivers/media/tuners/tda827x.h b/drivers/media/tuners/tda827x.h index b64292152baf..abf2e2fe5350 100644 --- a/drivers/media/tuners/tda827x.h +++ b/drivers/media/tuners/tda827x.h | |||
@@ -51,7 +51,7 @@ struct tda827x_config | |||
51 | * @param cfg optional callback function pointers. | 51 | * @param cfg optional callback function pointers. |
52 | * @return FE pointer on success, NULL on failure. | 52 | * @return FE pointer on success, NULL on failure. |
53 | */ | 53 | */ |
54 | #if IS_ENABLED(CONFIG_MEDIA_TUNER_TDA827X) | 54 | #if IS_REACHABLE(CONFIG_MEDIA_TUNER_TDA827X) |
55 | extern struct dvb_frontend* tda827x_attach(struct dvb_frontend *fe, int addr, | 55 | extern struct dvb_frontend* tda827x_attach(struct dvb_frontend *fe, int addr, |
56 | struct i2c_adapter *i2c, | 56 | struct i2c_adapter *i2c, |
57 | struct tda827x_config *cfg); | 57 | struct tda827x_config *cfg); |
diff --git a/drivers/media/tuners/tda8290.h b/drivers/media/tuners/tda8290.h index cf96e585785e..901b8cac7105 100644 --- a/drivers/media/tuners/tda8290.h +++ b/drivers/media/tuners/tda8290.h | |||
@@ -38,7 +38,7 @@ struct tda829x_config { | |||
38 | struct tda18271_std_map *tda18271_std_map; | 38 | struct tda18271_std_map *tda18271_std_map; |
39 | }; | 39 | }; |
40 | 40 | ||
41 | #if IS_ENABLED(CONFIG_MEDIA_TUNER_TDA8290) | 41 | #if IS_REACHABLE(CONFIG_MEDIA_TUNER_TDA8290) |
42 | extern int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr); | 42 | extern int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr); |
43 | 43 | ||
44 | extern struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe, | 44 | extern struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe, |
diff --git a/drivers/media/tuners/tda9887.h b/drivers/media/tuners/tda9887.h index 37a4a1123e0c..95070eca02ca 100644 --- a/drivers/media/tuners/tda9887.h +++ b/drivers/media/tuners/tda9887.h | |||
@@ -21,7 +21,7 @@ | |||
21 | #include "dvb_frontend.h" | 21 | #include "dvb_frontend.h" |
22 | 22 | ||
23 | /* ------------------------------------------------------------------------ */ | 23 | /* ------------------------------------------------------------------------ */ |
24 | #if IS_ENABLED(CONFIG_MEDIA_TUNER_TDA9887) | 24 | #if IS_REACHABLE(CONFIG_MEDIA_TUNER_TDA9887) |
25 | extern struct dvb_frontend *tda9887_attach(struct dvb_frontend *fe, | 25 | extern struct dvb_frontend *tda9887_attach(struct dvb_frontend *fe, |
26 | struct i2c_adapter *i2c_adap, | 26 | struct i2c_adapter *i2c_adap, |
27 | u8 i2c_addr); | 27 | u8 i2c_addr); |
diff --git a/drivers/media/tuners/tea5761.h b/drivers/media/tuners/tea5761.h index 933228ffb509..2d624d9919e3 100644 --- a/drivers/media/tuners/tea5761.h +++ b/drivers/media/tuners/tea5761.h | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
21 | #include "dvb_frontend.h" | 21 | #include "dvb_frontend.h" |
22 | 22 | ||
23 | #if IS_ENABLED(CONFIG_MEDIA_TUNER_TEA5761) | 23 | #if IS_REACHABLE(CONFIG_MEDIA_TUNER_TEA5761) |
24 | extern int tea5761_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr); | 24 | extern int tea5761_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr); |
25 | 25 | ||
26 | extern struct dvb_frontend *tea5761_attach(struct dvb_frontend *fe, | 26 | extern struct dvb_frontend *tea5761_attach(struct dvb_frontend *fe, |
diff --git a/drivers/media/tuners/tea5767.h b/drivers/media/tuners/tea5767.h index c39101199383..4f6f6c92db78 100644 --- a/drivers/media/tuners/tea5767.h +++ b/drivers/media/tuners/tea5767.h | |||
@@ -39,7 +39,7 @@ struct tea5767_ctrl { | |||
39 | enum tea5767_xtal xtal_freq; | 39 | enum tea5767_xtal xtal_freq; |
40 | }; | 40 | }; |
41 | 41 | ||
42 | #if IS_ENABLED(CONFIG_MEDIA_TUNER_TEA5767) | 42 | #if IS_REACHABLE(CONFIG_MEDIA_TUNER_TEA5767) |
43 | extern int tea5767_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr); | 43 | extern int tea5767_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr); |
44 | 44 | ||
45 | extern struct dvb_frontend *tea5767_attach(struct dvb_frontend *fe, | 45 | extern struct dvb_frontend *tea5767_attach(struct dvb_frontend *fe, |
diff --git a/drivers/media/tuners/tua9001.h b/drivers/media/tuners/tua9001.h index 26358da1c100..2c3375c7aeb9 100644 --- a/drivers/media/tuners/tua9001.h +++ b/drivers/media/tuners/tua9001.h | |||
@@ -51,7 +51,7 @@ struct tua9001_config { | |||
51 | #define TUA9001_CMD_RESETN 1 | 51 | #define TUA9001_CMD_RESETN 1 |
52 | #define TUA9001_CMD_RXEN 2 | 52 | #define TUA9001_CMD_RXEN 2 |
53 | 53 | ||
54 | #if IS_ENABLED(CONFIG_MEDIA_TUNER_TUA9001) | 54 | #if IS_REACHABLE(CONFIG_MEDIA_TUNER_TUA9001) |
55 | extern struct dvb_frontend *tua9001_attach(struct dvb_frontend *fe, | 55 | extern struct dvb_frontend *tua9001_attach(struct dvb_frontend *fe, |
56 | struct i2c_adapter *i2c, struct tua9001_config *cfg); | 56 | struct i2c_adapter *i2c, struct tua9001_config *cfg); |
57 | #else | 57 | #else |
diff --git a/drivers/media/tuners/tuner-simple.h b/drivers/media/tuners/tuner-simple.h index ffd12cfe650b..6399b45b0590 100644 --- a/drivers/media/tuners/tuner-simple.h +++ b/drivers/media/tuners/tuner-simple.h | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
21 | #include "dvb_frontend.h" | 21 | #include "dvb_frontend.h" |
22 | 22 | ||
23 | #if IS_ENABLED(CONFIG_MEDIA_TUNER_SIMPLE) | 23 | #if IS_REACHABLE(CONFIG_MEDIA_TUNER_SIMPLE) |
24 | extern struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe, | 24 | extern struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe, |
25 | struct i2c_adapter *i2c_adap, | 25 | struct i2c_adapter *i2c_adap, |
26 | u8 i2c_addr, | 26 | u8 i2c_addr, |
diff --git a/drivers/media/tuners/tuner-xc2028.h b/drivers/media/tuners/tuner-xc2028.h index 181d087faec4..98e4effca896 100644 --- a/drivers/media/tuners/tuner-xc2028.h +++ b/drivers/media/tuners/tuner-xc2028.h | |||
@@ -56,7 +56,7 @@ struct xc2028_config { | |||
56 | #define XC2028_RESET_CLK 1 | 56 | #define XC2028_RESET_CLK 1 |
57 | #define XC2028_I2C_FLUSH 2 | 57 | #define XC2028_I2C_FLUSH 2 |
58 | 58 | ||
59 | #if IS_ENABLED(CONFIG_MEDIA_TUNER_XC2028) | 59 | #if IS_REACHABLE(CONFIG_MEDIA_TUNER_XC2028) |
60 | extern struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe, | 60 | extern struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe, |
61 | struct xc2028_config *cfg); | 61 | struct xc2028_config *cfg); |
62 | #else | 62 | #else |
diff --git a/drivers/media/tuners/xc4000.h b/drivers/media/tuners/xc4000.h index 97c23de5296c..40517860cf67 100644 --- a/drivers/media/tuners/xc4000.h +++ b/drivers/media/tuners/xc4000.h | |||
@@ -50,7 +50,7 @@ struct xc4000_config { | |||
50 | * it's passed back to a bridge during tuner_callback(). | 50 | * it's passed back to a bridge during tuner_callback(). |
51 | */ | 51 | */ |
52 | 52 | ||
53 | #if IS_ENABLED(CONFIG_MEDIA_TUNER_XC4000) | 53 | #if IS_REACHABLE(CONFIG_MEDIA_TUNER_XC4000) |
54 | extern struct dvb_frontend *xc4000_attach(struct dvb_frontend *fe, | 54 | extern struct dvb_frontend *xc4000_attach(struct dvb_frontend *fe, |
55 | struct i2c_adapter *i2c, | 55 | struct i2c_adapter *i2c, |
56 | struct xc4000_config *cfg); | 56 | struct xc4000_config *cfg); |
diff --git a/drivers/media/tuners/xc5000.c b/drivers/media/tuners/xc5000.c index 2a039de8ab9a..e6e5e90d8d95 100644 --- a/drivers/media/tuners/xc5000.c +++ b/drivers/media/tuners/xc5000.c | |||
@@ -1336,7 +1336,10 @@ static int xc5000_release(struct dvb_frontend *fe) | |||
1336 | 1336 | ||
1337 | if (priv) { | 1337 | if (priv) { |
1338 | cancel_delayed_work(&priv->timer_sleep); | 1338 | cancel_delayed_work(&priv->timer_sleep); |
1339 | release_firmware(priv->firmware); | 1339 | if (priv->firmware) { |
1340 | release_firmware(priv->firmware); | ||
1341 | priv->firmware = NULL; | ||
1342 | } | ||
1340 | hybrid_tuner_release_state(priv); | 1343 | hybrid_tuner_release_state(priv); |
1341 | } | 1344 | } |
1342 | 1345 | ||
diff --git a/drivers/media/tuners/xc5000.h b/drivers/media/tuners/xc5000.h index 6aa534f17a30..00ba29e21fb9 100644 --- a/drivers/media/tuners/xc5000.h +++ b/drivers/media/tuners/xc5000.h | |||
@@ -58,7 +58,7 @@ struct xc5000_config { | |||
58 | * it's passed back to a bridge during tuner_callback(). | 58 | * it's passed back to a bridge during tuner_callback(). |
59 | */ | 59 | */ |
60 | 60 | ||
61 | #if IS_ENABLED(CONFIG_MEDIA_TUNER_XC5000) | 61 | #if IS_REACHABLE(CONFIG_MEDIA_TUNER_XC5000) |
62 | extern struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, | 62 | extern struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, |
63 | struct i2c_adapter *i2c, | 63 | struct i2c_adapter *i2c, |
64 | const struct xc5000_config *cfg); | 64 | const struct xc5000_config *cfg); |
diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index a27cb5fcdef8..1a362a041ab3 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c | |||
@@ -299,29 +299,23 @@ static int au0828_init_isoc(struct au0828_dev *dev, int max_packets, | |||
299 | * Announces that a buffer were filled and request the next | 299 | * Announces that a buffer were filled and request the next |
300 | */ | 300 | */ |
301 | static inline void buffer_filled(struct au0828_dev *dev, | 301 | static inline void buffer_filled(struct au0828_dev *dev, |
302 | struct au0828_dmaqueue *dma_q, | 302 | struct au0828_dmaqueue *dma_q, |
303 | struct au0828_buffer *buf) | 303 | struct au0828_buffer *buf) |
304 | { | 304 | { |
305 | /* Advice that buffer was filled */ | 305 | struct vb2_buffer *vb = &buf->vb; |
306 | au0828_isocdbg("[%p/%d] wakeup\n", buf, buf->top_field); | 306 | struct vb2_queue *q = vb->vb2_queue; |
307 | 307 | ||
308 | buf->vb.v4l2_buf.sequence = dev->frame_count++; | ||
309 | buf->vb.v4l2_buf.field = V4L2_FIELD_INTERLACED; | ||
310 | v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp); | ||
311 | vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE); | ||
312 | } | ||
313 | |||
314 | static inline void vbi_buffer_filled(struct au0828_dev *dev, | ||
315 | struct au0828_dmaqueue *dma_q, | ||
316 | struct au0828_buffer *buf) | ||
317 | { | ||
318 | /* Advice that buffer was filled */ | 308 | /* Advice that buffer was filled */ |
319 | au0828_isocdbg("[%p/%d] wakeup\n", buf, buf->top_field); | 309 | au0828_isocdbg("[%p/%d] wakeup\n", buf, buf->top_field); |
320 | 310 | ||
321 | buf->vb.v4l2_buf.sequence = dev->vbi_frame_count++; | 311 | if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) |
322 | buf->vb.v4l2_buf.field = V4L2_FIELD_INTERLACED; | 312 | vb->v4l2_buf.sequence = dev->frame_count++; |
323 | v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp); | 313 | else |
324 | vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE); | 314 | vb->v4l2_buf.sequence = dev->vbi_frame_count++; |
315 | |||
316 | vb->v4l2_buf.field = V4L2_FIELD_INTERLACED; | ||
317 | v4l2_get_timestamp(&vb->v4l2_buf.timestamp); | ||
318 | vb2_buffer_done(vb, VB2_BUF_STATE_DONE); | ||
325 | } | 319 | } |
326 | 320 | ||
327 | /* | 321 | /* |
@@ -574,9 +568,7 @@ static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb) | |||
574 | if (fbyte & 0x40) { | 568 | if (fbyte & 0x40) { |
575 | /* VBI */ | 569 | /* VBI */ |
576 | if (vbi_buf != NULL) | 570 | if (vbi_buf != NULL) |
577 | vbi_buffer_filled(dev, | 571 | buffer_filled(dev, vbi_dma_q, vbi_buf); |
578 | vbi_dma_q, | ||
579 | vbi_buf); | ||
580 | vbi_get_next_buf(vbi_dma_q, &vbi_buf); | 572 | vbi_get_next_buf(vbi_dma_q, &vbi_buf); |
581 | if (vbi_buf == NULL) | 573 | if (vbi_buf == NULL) |
582 | vbioutp = NULL; | 574 | vbioutp = NULL; |
@@ -899,12 +891,8 @@ void au0828_analog_unregister(struct au0828_dev *dev) | |||
899 | { | 891 | { |
900 | dprintk(1, "au0828_analog_unregister called\n"); | 892 | dprintk(1, "au0828_analog_unregister called\n"); |
901 | mutex_lock(&au0828_sysfs_lock); | 893 | mutex_lock(&au0828_sysfs_lock); |
902 | 894 | video_unregister_device(&dev->vdev); | |
903 | if (dev->vdev) | 895 | video_unregister_device(&dev->vbi_dev); |
904 | video_unregister_device(dev->vdev); | ||
905 | if (dev->vbi_dev) | ||
906 | video_unregister_device(dev->vbi_dev); | ||
907 | |||
908 | mutex_unlock(&au0828_sysfs_lock); | 896 | mutex_unlock(&au0828_sysfs_lock); |
909 | } | 897 | } |
910 | 898 | ||
@@ -949,7 +937,7 @@ static void au0828_vbi_buffer_timeout(unsigned long data) | |||
949 | if (buf != NULL) { | 937 | if (buf != NULL) { |
950 | vbi_data = vb2_plane_vaddr(&buf->vb, 0); | 938 | vbi_data = vb2_plane_vaddr(&buf->vb, 0); |
951 | memset(vbi_data, 0x00, buf->length); | 939 | memset(vbi_data, 0x00, buf->length); |
952 | vbi_buffer_filled(dev, dma_q, buf); | 940 | buffer_filled(dev, dma_q, buf); |
953 | } | 941 | } |
954 | vbi_get_next_buf(dma_q, &buf); | 942 | vbi_get_next_buf(dma_q, &buf); |
955 | 943 | ||
@@ -1286,7 +1274,7 @@ static int vidioc_enum_input(struct file *file, void *priv, | |||
1286 | input->audioset = 2; | 1274 | input->audioset = 2; |
1287 | } | 1275 | } |
1288 | 1276 | ||
1289 | input->std = dev->vdev->tvnorms; | 1277 | input->std = dev->vdev.tvnorms; |
1290 | 1278 | ||
1291 | return 0; | 1279 | return 0; |
1292 | } | 1280 | } |
@@ -1704,7 +1692,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
1704 | 1692 | ||
1705 | static const struct video_device au0828_video_template = { | 1693 | static const struct video_device au0828_video_template = { |
1706 | .fops = &au0828_v4l_fops, | 1694 | .fops = &au0828_v4l_fops, |
1707 | .release = video_device_release, | 1695 | .release = video_device_release_empty, |
1708 | .ioctl_ops = &video_ioctl_ops, | 1696 | .ioctl_ops = &video_ioctl_ops, |
1709 | .tvnorms = V4L2_STD_NTSC_M | V4L2_STD_PAL_M, | 1697 | .tvnorms = V4L2_STD_NTSC_M | V4L2_STD_PAL_M, |
1710 | }; | 1698 | }; |
@@ -1814,52 +1802,36 @@ int au0828_analog_register(struct au0828_dev *dev, | |||
1814 | dev->std = V4L2_STD_NTSC_M; | 1802 | dev->std = V4L2_STD_NTSC_M; |
1815 | au0828_s_input(dev, 0); | 1803 | au0828_s_input(dev, 0); |
1816 | 1804 | ||
1817 | /* allocate and fill v4l2 video struct */ | ||
1818 | dev->vdev = video_device_alloc(); | ||
1819 | if (NULL == dev->vdev) { | ||
1820 | dprintk(1, "Can't allocate video_device.\n"); | ||
1821 | return -ENOMEM; | ||
1822 | } | ||
1823 | |||
1824 | /* allocate the VBI struct */ | ||
1825 | dev->vbi_dev = video_device_alloc(); | ||
1826 | if (NULL == dev->vbi_dev) { | ||
1827 | dprintk(1, "Can't allocate vbi_device.\n"); | ||
1828 | ret = -ENOMEM; | ||
1829 | goto err_vdev; | ||
1830 | } | ||
1831 | |||
1832 | mutex_init(&dev->vb_queue_lock); | 1805 | mutex_init(&dev->vb_queue_lock); |
1833 | mutex_init(&dev->vb_vbi_queue_lock); | 1806 | mutex_init(&dev->vb_vbi_queue_lock); |
1834 | 1807 | ||
1835 | /* Fill the video capture device struct */ | 1808 | /* Fill the video capture device struct */ |
1836 | *dev->vdev = au0828_video_template; | 1809 | dev->vdev = au0828_video_template; |
1837 | dev->vdev->v4l2_dev = &dev->v4l2_dev; | 1810 | dev->vdev.v4l2_dev = &dev->v4l2_dev; |
1838 | dev->vdev->lock = &dev->lock; | 1811 | dev->vdev.lock = &dev->lock; |
1839 | dev->vdev->queue = &dev->vb_vidq; | 1812 | dev->vdev.queue = &dev->vb_vidq; |
1840 | dev->vdev->queue->lock = &dev->vb_queue_lock; | 1813 | dev->vdev.queue->lock = &dev->vb_queue_lock; |
1841 | strcpy(dev->vdev->name, "au0828a video"); | 1814 | strcpy(dev->vdev.name, "au0828a video"); |
1842 | 1815 | ||
1843 | /* Setup the VBI device */ | 1816 | /* Setup the VBI device */ |
1844 | *dev->vbi_dev = au0828_video_template; | 1817 | dev->vbi_dev = au0828_video_template; |
1845 | dev->vbi_dev->v4l2_dev = &dev->v4l2_dev; | 1818 | dev->vbi_dev.v4l2_dev = &dev->v4l2_dev; |
1846 | dev->vbi_dev->lock = &dev->lock; | 1819 | dev->vbi_dev.lock = &dev->lock; |
1847 | dev->vbi_dev->queue = &dev->vb_vbiq; | 1820 | dev->vbi_dev.queue = &dev->vb_vbiq; |
1848 | dev->vbi_dev->queue->lock = &dev->vb_vbi_queue_lock; | 1821 | dev->vbi_dev.queue->lock = &dev->vb_vbi_queue_lock; |
1849 | strcpy(dev->vbi_dev->name, "au0828a vbi"); | 1822 | strcpy(dev->vbi_dev.name, "au0828a vbi"); |
1850 | 1823 | ||
1851 | /* initialize videobuf2 stuff */ | 1824 | /* initialize videobuf2 stuff */ |
1852 | retval = au0828_vb2_setup(dev); | 1825 | retval = au0828_vb2_setup(dev); |
1853 | if (retval != 0) { | 1826 | if (retval != 0) { |
1854 | dprintk(1, "unable to setup videobuf2 queues (error = %d).\n", | 1827 | dprintk(1, "unable to setup videobuf2 queues (error = %d).\n", |
1855 | retval); | 1828 | retval); |
1856 | ret = -ENODEV; | 1829 | return -ENODEV; |
1857 | goto err_vbi_dev; | ||
1858 | } | 1830 | } |
1859 | 1831 | ||
1860 | /* Register the v4l2 device */ | 1832 | /* Register the v4l2 device */ |
1861 | video_set_drvdata(dev->vdev, dev); | 1833 | video_set_drvdata(&dev->vdev, dev); |
1862 | retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, -1); | 1834 | retval = video_register_device(&dev->vdev, VFL_TYPE_GRABBER, -1); |
1863 | if (retval != 0) { | 1835 | if (retval != 0) { |
1864 | dprintk(1, "unable to register video device (error = %d).\n", | 1836 | dprintk(1, "unable to register video device (error = %d).\n", |
1865 | retval); | 1837 | retval); |
@@ -1868,8 +1840,8 @@ int au0828_analog_register(struct au0828_dev *dev, | |||
1868 | } | 1840 | } |
1869 | 1841 | ||
1870 | /* Register the vbi device */ | 1842 | /* Register the vbi device */ |
1871 | video_set_drvdata(dev->vbi_dev, dev); | 1843 | video_set_drvdata(&dev->vbi_dev, dev); |
1872 | retval = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, -1); | 1844 | retval = video_register_device(&dev->vbi_dev, VFL_TYPE_VBI, -1); |
1873 | if (retval != 0) { | 1845 | if (retval != 0) { |
1874 | dprintk(1, "unable to register vbi device (error = %d).\n", | 1846 | dprintk(1, "unable to register vbi device (error = %d).\n", |
1875 | retval); | 1847 | retval); |
@@ -1882,14 +1854,10 @@ int au0828_analog_register(struct au0828_dev *dev, | |||
1882 | return 0; | 1854 | return 0; |
1883 | 1855 | ||
1884 | err_reg_vbi_dev: | 1856 | err_reg_vbi_dev: |
1885 | video_unregister_device(dev->vdev); | 1857 | video_unregister_device(&dev->vdev); |
1886 | err_reg_vdev: | 1858 | err_reg_vdev: |
1887 | vb2_queue_release(&dev->vb_vidq); | 1859 | vb2_queue_release(&dev->vb_vidq); |
1888 | vb2_queue_release(&dev->vb_vbiq); | 1860 | vb2_queue_release(&dev->vb_vbiq); |
1889 | err_vbi_dev: | ||
1890 | video_device_release(dev->vbi_dev); | ||
1891 | err_vdev: | ||
1892 | video_device_release(dev->vdev); | ||
1893 | return ret; | 1861 | return ret; |
1894 | } | 1862 | } |
1895 | 1863 | ||
diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h index eb1518742ae6..3b480005ce3b 100644 --- a/drivers/media/usb/au0828/au0828.h +++ b/drivers/media/usb/au0828/au0828.h | |||
@@ -209,8 +209,8 @@ struct au0828_dev { | |||
209 | struct au0828_rc *ir; | 209 | struct au0828_rc *ir; |
210 | #endif | 210 | #endif |
211 | 211 | ||
212 | struct video_device *vdev; | 212 | struct video_device vdev; |
213 | struct video_device *vbi_dev; | 213 | struct video_device vbi_dev; |
214 | 214 | ||
215 | /* Videobuf2 */ | 215 | /* Videobuf2 */ |
216 | struct vb2_queue vb_vidq; | 216 | struct vb2_queue vb_vidq; |
diff --git a/drivers/media/usb/cx231xx/Kconfig b/drivers/media/usb/cx231xx/Kconfig index 173c0e287a08..0cced3e5b040 100644 --- a/drivers/media/usb/cx231xx/Kconfig +++ b/drivers/media/usb/cx231xx/Kconfig | |||
@@ -47,6 +47,7 @@ config VIDEO_CX231XX_DVB | |||
47 | select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT | 47 | select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT |
48 | select DVB_MB86A20S if MEDIA_SUBDRV_AUTOSELECT | 48 | select DVB_MB86A20S if MEDIA_SUBDRV_AUTOSELECT |
49 | select DVB_LGDT3305 if MEDIA_SUBDRV_AUTOSELECT | 49 | select DVB_LGDT3305 if MEDIA_SUBDRV_AUTOSELECT |
50 | select DVB_LGDT3306A if MEDIA_SUBDRV_AUTOSELECT | ||
50 | select DVB_TDA18271C2DD if MEDIA_SUBDRV_AUTOSELECT | 51 | select DVB_TDA18271C2DD if MEDIA_SUBDRV_AUTOSELECT |
51 | select DVB_SI2165 if MEDIA_SUBDRV_AUTOSELECT | 52 | select DVB_SI2165 if MEDIA_SUBDRV_AUTOSELECT |
52 | select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT | 53 | select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT |
diff --git a/drivers/media/usb/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c index 3f295b4d1a3d..983ea8339154 100644 --- a/drivers/media/usb/cx231xx/cx231xx-417.c +++ b/drivers/media/usb/cx231xx/cx231xx-417.c | |||
@@ -1868,13 +1868,9 @@ void cx231xx_417_unregister(struct cx231xx *dev) | |||
1868 | dprintk(1, "%s()\n", __func__); | 1868 | dprintk(1, "%s()\n", __func__); |
1869 | dprintk(3, "%s()\n", __func__); | 1869 | dprintk(3, "%s()\n", __func__); |
1870 | 1870 | ||
1871 | if (dev->v4l_device) { | 1871 | if (video_is_registered(&dev->v4l_device)) { |
1872 | if (-1 != dev->v4l_device->minor) | 1872 | video_unregister_device(&dev->v4l_device); |
1873 | video_unregister_device(dev->v4l_device); | ||
1874 | else | ||
1875 | video_device_release(dev->v4l_device); | ||
1876 | v4l2_ctrl_handler_free(&dev->mpeg_ctrl_handler.hdl); | 1873 | v4l2_ctrl_handler_free(&dev->mpeg_ctrl_handler.hdl); |
1877 | dev->v4l_device = NULL; | ||
1878 | } | 1874 | } |
1879 | } | 1875 | } |
1880 | 1876 | ||
@@ -1911,25 +1907,21 @@ static struct cx2341x_handler_ops cx231xx_ops = { | |||
1911 | .s_video_encoding = cx231xx_s_video_encoding, | 1907 | .s_video_encoding = cx231xx_s_video_encoding, |
1912 | }; | 1908 | }; |
1913 | 1909 | ||
1914 | static struct video_device *cx231xx_video_dev_alloc( | 1910 | static void cx231xx_video_dev_init( |
1915 | struct cx231xx *dev, | 1911 | struct cx231xx *dev, |
1916 | struct usb_device *usbdev, | 1912 | struct usb_device *usbdev, |
1917 | struct video_device *template, | 1913 | struct video_device *vfd, |
1918 | char *type) | 1914 | const struct video_device *template, |
1915 | const char *type) | ||
1919 | { | 1916 | { |
1920 | struct video_device *vfd; | ||
1921 | |||
1922 | dprintk(1, "%s()\n", __func__); | 1917 | dprintk(1, "%s()\n", __func__); |
1923 | vfd = video_device_alloc(); | ||
1924 | if (NULL == vfd) | ||
1925 | return NULL; | ||
1926 | *vfd = *template; | 1918 | *vfd = *template; |
1927 | snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, | 1919 | snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, |
1928 | type, cx231xx_boards[dev->model].name); | 1920 | type, cx231xx_boards[dev->model].name); |
1929 | 1921 | ||
1930 | vfd->v4l2_dev = &dev->v4l2_dev; | 1922 | vfd->v4l2_dev = &dev->v4l2_dev; |
1931 | vfd->lock = &dev->lock; | 1923 | vfd->lock = &dev->lock; |
1932 | vfd->release = video_device_release; | 1924 | vfd->release = video_device_release_empty; |
1933 | vfd->ctrl_handler = &dev->mpeg_ctrl_handler.hdl; | 1925 | vfd->ctrl_handler = &dev->mpeg_ctrl_handler.hdl; |
1934 | video_set_drvdata(vfd, dev); | 1926 | video_set_drvdata(vfd, dev); |
1935 | if (dev->tuner_type == TUNER_ABSENT) { | 1927 | if (dev->tuner_type == TUNER_ABSENT) { |
@@ -1938,9 +1930,6 @@ static struct video_device *cx231xx_video_dev_alloc( | |||
1938 | v4l2_disable_ioctl(vfd, VIDIOC_G_TUNER); | 1930 | v4l2_disable_ioctl(vfd, VIDIOC_G_TUNER); |
1939 | v4l2_disable_ioctl(vfd, VIDIOC_S_TUNER); | 1931 | v4l2_disable_ioctl(vfd, VIDIOC_S_TUNER); |
1940 | } | 1932 | } |
1941 | |||
1942 | return vfd; | ||
1943 | |||
1944 | } | 1933 | } |
1945 | 1934 | ||
1946 | int cx231xx_417_register(struct cx231xx *dev) | 1935 | int cx231xx_417_register(struct cx231xx *dev) |
@@ -1983,9 +1972,9 @@ int cx231xx_417_register(struct cx231xx *dev) | |||
1983 | cx2341x_handler_set_50hz(&dev->mpeg_ctrl_handler, false); | 1972 | cx2341x_handler_set_50hz(&dev->mpeg_ctrl_handler, false); |
1984 | 1973 | ||
1985 | /* Allocate and initialize V4L video device */ | 1974 | /* Allocate and initialize V4L video device */ |
1986 | dev->v4l_device = cx231xx_video_dev_alloc(dev, | 1975 | cx231xx_video_dev_init(dev, dev->udev, |
1987 | dev->udev, &cx231xx_mpeg_template, "mpeg"); | 1976 | &dev->v4l_device, &cx231xx_mpeg_template, "mpeg"); |
1988 | err = video_register_device(dev->v4l_device, | 1977 | err = video_register_device(&dev->v4l_device, |
1989 | VFL_TYPE_GRABBER, -1); | 1978 | VFL_TYPE_GRABBER, -1); |
1990 | if (err < 0) { | 1979 | if (err < 0) { |
1991 | dprintk(3, "%s: can't register mpeg device\n", dev->name); | 1980 | dprintk(3, "%s: can't register mpeg device\n", dev->name); |
@@ -1994,7 +1983,7 @@ int cx231xx_417_register(struct cx231xx *dev) | |||
1994 | } | 1983 | } |
1995 | 1984 | ||
1996 | dprintk(3, "%s: registered device video%d [mpeg]\n", | 1985 | dprintk(3, "%s: registered device video%d [mpeg]\n", |
1997 | dev->name, dev->v4l_device->num); | 1986 | dev->name, dev->v4l_device.num); |
1998 | 1987 | ||
1999 | return 0; | 1988 | return 0; |
2000 | } | 1989 | } |
diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index da03733690bd..fe00da105e77 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c | |||
@@ -776,6 +776,45 @@ struct cx231xx_board cx231xx_boards[] = { | |||
776 | .gpio = NULL, | 776 | .gpio = NULL, |
777 | } }, | 777 | } }, |
778 | }, | 778 | }, |
779 | [CX231XX_BOARD_HAUPPAUGE_955Q] = { | ||
780 | .name = "Hauppauge WinTV-HVR-955Q (111401)", | ||
781 | .tuner_type = TUNER_ABSENT, | ||
782 | .tuner_addr = 0x60, | ||
783 | .tuner_gpio = RDE250_XCV_TUNER, | ||
784 | .tuner_sif_gpio = 0x05, | ||
785 | .tuner_scl_gpio = 0x1a, | ||
786 | .tuner_sda_gpio = 0x1b, | ||
787 | .decoder = CX231XX_AVDECODER, | ||
788 | .output_mode = OUT_MODE_VIP11, | ||
789 | .demod_xfer_mode = 0, | ||
790 | .ctl_pin_status_mask = 0xFFFFFFC4, | ||
791 | .agc_analog_digital_select_gpio = 0x0c, | ||
792 | .gpio_pin_status_mask = 0x4001000, | ||
793 | .tuner_i2c_master = I2C_1_MUX_3, | ||
794 | .demod_i2c_master = I2C_2, | ||
795 | .has_dvb = 1, | ||
796 | .demod_addr = 0x0e, | ||
797 | .norm = V4L2_STD_NTSC, | ||
798 | |||
799 | .input = {{ | ||
800 | .type = CX231XX_VMUX_TELEVISION, | ||
801 | .vmux = CX231XX_VIN_3_1, | ||
802 | .amux = CX231XX_AMUX_VIDEO, | ||
803 | .gpio = NULL, | ||
804 | }, { | ||
805 | .type = CX231XX_VMUX_COMPOSITE1, | ||
806 | .vmux = CX231XX_VIN_2_1, | ||
807 | .amux = CX231XX_AMUX_LINE_IN, | ||
808 | .gpio = NULL, | ||
809 | }, { | ||
810 | .type = CX231XX_VMUX_SVIDEO, | ||
811 | .vmux = CX231XX_VIN_1_1 | | ||
812 | (CX231XX_VIN_1_2 << 8) | | ||
813 | CX25840_SVIDEO_ON, | ||
814 | .amux = CX231XX_AMUX_LINE_IN, | ||
815 | .gpio = NULL, | ||
816 | } }, | ||
817 | }, | ||
779 | }; | 818 | }; |
780 | const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards); | 819 | const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards); |
781 | 820 | ||
@@ -805,6 +844,8 @@ struct usb_device_id cx231xx_id_table[] = { | |||
805 | .driver_info = CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC}, | 844 | .driver_info = CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC}, |
806 | {USB_DEVICE(0x2040, 0xb120), | 845 | {USB_DEVICE(0x2040, 0xb120), |
807 | .driver_info = CX231XX_BOARD_HAUPPAUGE_EXETER}, | 846 | .driver_info = CX231XX_BOARD_HAUPPAUGE_EXETER}, |
847 | {USB_DEVICE(0x2040, 0xb123), | ||
848 | .driver_info = CX231XX_BOARD_HAUPPAUGE_955Q}, | ||
808 | {USB_DEVICE(0x2040, 0xb130), | 849 | {USB_DEVICE(0x2040, 0xb130), |
809 | .driver_info = CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx}, | 850 | .driver_info = CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx}, |
810 | {USB_DEVICE(0x2040, 0xb131), | 851 | {USB_DEVICE(0x2040, 0xb131), |
@@ -912,9 +953,6 @@ static inline void cx231xx_set_model(struct cx231xx *dev) | |||
912 | */ | 953 | */ |
913 | void cx231xx_pre_card_setup(struct cx231xx *dev) | 954 | void cx231xx_pre_card_setup(struct cx231xx *dev) |
914 | { | 955 | { |
915 | |||
916 | cx231xx_set_model(dev); | ||
917 | |||
918 | dev_info(dev->dev, "Identified as %s (card=%d)\n", | 956 | dev_info(dev->dev, "Identified as %s (card=%d)\n", |
919 | dev->board.name, dev->model); | 957 | dev->board.name, dev->model); |
920 | 958 | ||
@@ -1052,6 +1090,7 @@ void cx231xx_card_setup(struct cx231xx *dev) | |||
1052 | switch (dev->model) { | 1090 | switch (dev->model) { |
1053 | case CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx: | 1091 | case CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx: |
1054 | case CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx: | 1092 | case CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx: |
1093 | case CX231XX_BOARD_HAUPPAUGE_955Q: | ||
1055 | { | 1094 | { |
1056 | struct tveeprom tvee; | 1095 | struct tveeprom tvee; |
1057 | static u8 eeprom[256]; | 1096 | static u8 eeprom[256]; |
@@ -1092,6 +1131,17 @@ void cx231xx_config_i2c(struct cx231xx *dev) | |||
1092 | call_all(dev, video, s_stream, 1); | 1131 | call_all(dev, video, s_stream, 1); |
1093 | } | 1132 | } |
1094 | 1133 | ||
1134 | static void cx231xx_unregister_media_device(struct cx231xx *dev) | ||
1135 | { | ||
1136 | #ifdef CONFIG_MEDIA_CONTROLLER | ||
1137 | if (dev->media_dev) { | ||
1138 | media_device_unregister(dev->media_dev); | ||
1139 | kfree(dev->media_dev); | ||
1140 | dev->media_dev = NULL; | ||
1141 | } | ||
1142 | #endif | ||
1143 | } | ||
1144 | |||
1095 | /* | 1145 | /* |
1096 | * cx231xx_realease_resources() | 1146 | * cx231xx_realease_resources() |
1097 | * unregisters the v4l2,i2c and usb devices | 1147 | * unregisters the v4l2,i2c and usb devices |
@@ -1099,6 +1149,8 @@ void cx231xx_config_i2c(struct cx231xx *dev) | |||
1099 | */ | 1149 | */ |
1100 | void cx231xx_release_resources(struct cx231xx *dev) | 1150 | void cx231xx_release_resources(struct cx231xx *dev) |
1101 | { | 1151 | { |
1152 | cx231xx_unregister_media_device(dev); | ||
1153 | |||
1102 | cx231xx_release_analog_resources(dev); | 1154 | cx231xx_release_analog_resources(dev); |
1103 | 1155 | ||
1104 | cx231xx_remove_from_devlist(dev); | 1156 | cx231xx_remove_from_devlist(dev); |
@@ -1117,6 +1169,74 @@ void cx231xx_release_resources(struct cx231xx *dev) | |||
1117 | clear_bit(dev->devno, &cx231xx_devused); | 1169 | clear_bit(dev->devno, &cx231xx_devused); |
1118 | } | 1170 | } |
1119 | 1171 | ||
1172 | static void cx231xx_media_device_register(struct cx231xx *dev, | ||
1173 | struct usb_device *udev) | ||
1174 | { | ||
1175 | #ifdef CONFIG_MEDIA_CONTROLLER | ||
1176 | struct media_device *mdev; | ||
1177 | int ret; | ||
1178 | |||
1179 | mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); | ||
1180 | if (!mdev) | ||
1181 | return; | ||
1182 | |||
1183 | mdev->dev = dev->dev; | ||
1184 | strlcpy(mdev->model, dev->board.name, sizeof(mdev->model)); | ||
1185 | if (udev->serial) | ||
1186 | strlcpy(mdev->serial, udev->serial, sizeof(mdev->serial)); | ||
1187 | strcpy(mdev->bus_info, udev->devpath); | ||
1188 | mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice); | ||
1189 | mdev->driver_version = LINUX_VERSION_CODE; | ||
1190 | |||
1191 | ret = media_device_register(mdev); | ||
1192 | if (ret) { | ||
1193 | dev_err(dev->dev, | ||
1194 | "Couldn't create a media device. Error: %d\n", | ||
1195 | ret); | ||
1196 | kfree(mdev); | ||
1197 | return; | ||
1198 | } | ||
1199 | |||
1200 | dev->media_dev = mdev; | ||
1201 | #endif | ||
1202 | } | ||
1203 | |||
1204 | static void cx231xx_create_media_graph(struct cx231xx *dev) | ||
1205 | { | ||
1206 | #ifdef CONFIG_MEDIA_CONTROLLER | ||
1207 | struct media_device *mdev = dev->media_dev; | ||
1208 | struct media_entity *entity; | ||
1209 | struct media_entity *tuner = NULL, *decoder = NULL; | ||
1210 | |||
1211 | if (!mdev) | ||
1212 | return; | ||
1213 | |||
1214 | media_device_for_each_entity(entity, mdev) { | ||
1215 | switch (entity->type) { | ||
1216 | case MEDIA_ENT_T_V4L2_SUBDEV_TUNER: | ||
1217 | tuner = entity; | ||
1218 | break; | ||
1219 | case MEDIA_ENT_T_V4L2_SUBDEV_DECODER: | ||
1220 | decoder = entity; | ||
1221 | break; | ||
1222 | } | ||
1223 | } | ||
1224 | |||
1225 | /* Analog setup, using tuner as a link */ | ||
1226 | |||
1227 | if (!decoder) | ||
1228 | return; | ||
1229 | |||
1230 | if (tuner) | ||
1231 | media_entity_create_link(tuner, 0, decoder, 0, | ||
1232 | MEDIA_LNK_FL_ENABLED); | ||
1233 | media_entity_create_link(decoder, 1, &dev->vdev.entity, 0, | ||
1234 | MEDIA_LNK_FL_ENABLED); | ||
1235 | media_entity_create_link(decoder, 2, &dev->vbi_dev.entity, 0, | ||
1236 | MEDIA_LNK_FL_ENABLED); | ||
1237 | #endif | ||
1238 | } | ||
1239 | |||
1120 | /* | 1240 | /* |
1121 | * cx231xx_init_dev() | 1241 | * cx231xx_init_dev() |
1122 | * allocates and inits the device structs, registers i2c bus and v4l device | 1242 | * allocates and inits the device structs, registers i2c bus and v4l device |
@@ -1225,10 +1345,8 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, | |||
1225 | } | 1345 | } |
1226 | 1346 | ||
1227 | retval = cx231xx_register_analog_devices(dev); | 1347 | retval = cx231xx_register_analog_devices(dev); |
1228 | if (retval) { | 1348 | if (retval) |
1229 | cx231xx_release_analog_resources(dev); | ||
1230 | goto err_analog; | 1349 | goto err_analog; |
1231 | } | ||
1232 | 1350 | ||
1233 | cx231xx_ir_init(dev); | 1351 | cx231xx_ir_init(dev); |
1234 | 1352 | ||
@@ -1236,6 +1354,8 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, | |||
1236 | 1354 | ||
1237 | return 0; | 1355 | return 0; |
1238 | err_analog: | 1356 | err_analog: |
1357 | cx231xx_unregister_media_device(dev); | ||
1358 | cx231xx_release_analog_resources(dev); | ||
1239 | cx231xx_remove_from_devlist(dev); | 1359 | cx231xx_remove_from_devlist(dev); |
1240 | err_dev_init: | 1360 | err_dev_init: |
1241 | cx231xx_dev_uninit(dev); | 1361 | cx231xx_dev_uninit(dev); |
@@ -1438,6 +1558,8 @@ static int cx231xx_usb_probe(struct usb_interface *interface, | |||
1438 | dev->video_mode.alt = -1; | 1558 | dev->video_mode.alt = -1; |
1439 | dev->dev = d; | 1559 | dev->dev = d; |
1440 | 1560 | ||
1561 | cx231xx_set_model(dev); | ||
1562 | |||
1441 | dev->interface_count++; | 1563 | dev->interface_count++; |
1442 | /* reset gpio dir and value */ | 1564 | /* reset gpio dir and value */ |
1443 | dev->gpio_dir = 0; | 1565 | dev->gpio_dir = 0; |
@@ -1502,7 +1624,13 @@ static int cx231xx_usb_probe(struct usb_interface *interface, | |||
1502 | /* save our data pointer in this interface device */ | 1624 | /* save our data pointer in this interface device */ |
1503 | usb_set_intfdata(interface, dev); | 1625 | usb_set_intfdata(interface, dev); |
1504 | 1626 | ||
1627 | /* Register the media controller */ | ||
1628 | cx231xx_media_device_register(dev, udev); | ||
1629 | |||
1505 | /* Create v4l2 device */ | 1630 | /* Create v4l2 device */ |
1631 | #ifdef CONFIG_MEDIA_CONTROLLER | ||
1632 | dev->v4l2_dev.mdev = dev->media_dev; | ||
1633 | #endif | ||
1506 | retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev); | 1634 | retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev); |
1507 | if (retval) { | 1635 | if (retval) { |
1508 | dev_err(d, "v4l2_device_register failed\n"); | 1636 | dev_err(d, "v4l2_device_register failed\n"); |
@@ -1568,6 +1696,8 @@ static int cx231xx_usb_probe(struct usb_interface *interface, | |||
1568 | /* load other modules required */ | 1696 | /* load other modules required */ |
1569 | request_modules(dev); | 1697 | request_modules(dev); |
1570 | 1698 | ||
1699 | cx231xx_create_media_graph(dev); | ||
1700 | |||
1571 | return 0; | 1701 | return 0; |
1572 | err_video_alt: | 1702 | err_video_alt: |
1573 | /* cx231xx_uninit_dev: */ | 1703 | /* cx231xx_uninit_dev: */ |
@@ -1618,7 +1748,7 @@ static void cx231xx_usb_disconnect(struct usb_interface *interface) | |||
1618 | if (dev->users) { | 1748 | if (dev->users) { |
1619 | dev_warn(dev->dev, | 1749 | dev_warn(dev->dev, |
1620 | "device %s is open! Deregistration and memory deallocation are deferred on close.\n", | 1750 | "device %s is open! Deregistration and memory deallocation are deferred on close.\n", |
1621 | video_device_node_name(dev->vdev)); | 1751 | video_device_node_name(&dev->vdev)); |
1622 | 1752 | ||
1623 | /* Even having users, it is safe to remove the RC i2c driver */ | 1753 | /* Even having users, it is safe to remove the RC i2c driver */ |
1624 | cx231xx_ir_exit(dev); | 1754 | cx231xx_ir_exit(dev); |
diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c index 4a3f28c4e8d3..e42bde081cd7 100644 --- a/drivers/media/usb/cx231xx/cx231xx-core.c +++ b/drivers/media/usb/cx231xx/cx231xx-core.c | |||
@@ -176,16 +176,9 @@ int cx231xx_send_usb_command(struct cx231xx_i2c *i2c_bus, | |||
176 | saddr_len = req_data->saddr_len; | 176 | saddr_len = req_data->saddr_len; |
177 | 177 | ||
178 | /* Set wValue */ | 178 | /* Set wValue */ |
179 | if (saddr_len == 1) /* need check saddr_len == 0 */ | 179 | ven_req.wValue = (req_data->dev_addr << 9 | _i2c_period << 4 | |
180 | ven_req.wValue = | 180 | saddr_len << 2 | _i2c_nostop << 1 | I2C_SYNC | |
181 | req_data-> | 181 | _i2c_reserve << 6); |
182 | dev_addr << 9 | _i2c_period << 4 | saddr_len << 2 | | ||
183 | _i2c_nostop << 1 | I2C_SYNC | _i2c_reserve << 6; | ||
184 | else | ||
185 | ven_req.wValue = | ||
186 | req_data-> | ||
187 | dev_addr << 9 | _i2c_period << 4 | saddr_len << 2 | | ||
188 | _i2c_nostop << 1 | I2C_SYNC | _i2c_reserve << 6; | ||
189 | 182 | ||
190 | /* set channel number */ | 183 | /* set channel number */ |
191 | if (req_data->direction & I2C_M_RD) { | 184 | if (req_data->direction & I2C_M_RD) { |
diff --git a/drivers/media/usb/cx231xx/cx231xx-dvb.c b/drivers/media/usb/cx231xx/cx231xx-dvb.c index dd600b994e69..610d5675bde6 100644 --- a/drivers/media/usb/cx231xx/cx231xx-dvb.c +++ b/drivers/media/usb/cx231xx/cx231xx-dvb.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include "si2165.h" | 34 | #include "si2165.h" |
35 | #include "mb86a20s.h" | 35 | #include "mb86a20s.h" |
36 | #include "si2157.h" | 36 | #include "si2157.h" |
37 | #include "lgdt3306a.h" | ||
37 | 38 | ||
38 | MODULE_DESCRIPTION("driver for cx231xx based DVB cards"); | 39 | MODULE_DESCRIPTION("driver for cx231xx based DVB cards"); |
39 | MODULE_AUTHOR("Srinivasa Deevi <srinivasa.deevi@conexant.com>"); | 40 | MODULE_AUTHOR("Srinivasa Deevi <srinivasa.deevi@conexant.com>"); |
@@ -160,6 +161,18 @@ static const struct si2165_config pctv_quatro_stick_1114xx_si2165_config = { | |||
160 | .ref_freq_Hz = 24000000, | 161 | .ref_freq_Hz = 24000000, |
161 | }; | 162 | }; |
162 | 163 | ||
164 | static struct lgdt3306a_config hauppauge_955q_lgdt3306a_config = { | ||
165 | .i2c_addr = 0x59, | ||
166 | .qam_if_khz = 4000, | ||
167 | .vsb_if_khz = 3250, | ||
168 | .deny_i2c_rptr = 1, | ||
169 | .spectral_inversion = 1, | ||
170 | .mpeg_mode = LGDT3306A_MPEG_SERIAL, | ||
171 | .tpclk_edge = LGDT3306A_TPCLK_RISING_EDGE, | ||
172 | .tpvalid_polarity = LGDT3306A_TP_VALID_HIGH, | ||
173 | .xtalMHz = 25, | ||
174 | }; | ||
175 | |||
163 | static inline void print_err_status(struct cx231xx *dev, int packet, int status) | 176 | static inline void print_err_status(struct cx231xx *dev, int packet, int status) |
164 | { | 177 | { |
165 | char *errmsg = "Unknown"; | 178 | char *errmsg = "Unknown"; |
@@ -455,6 +468,7 @@ static int register_dvb(struct cx231xx_dvb *dvb, | |||
455 | 468 | ||
456 | mutex_init(&dvb->lock); | 469 | mutex_init(&dvb->lock); |
457 | 470 | ||
471 | |||
458 | /* register adapter */ | 472 | /* register adapter */ |
459 | result = dvb_register_adapter(&dvb->adapter, dev->name, module, device, | 473 | result = dvb_register_adapter(&dvb->adapter, dev->name, module, device, |
460 | adapter_nr); | 474 | adapter_nr); |
@@ -464,6 +478,7 @@ static int register_dvb(struct cx231xx_dvb *dvb, | |||
464 | dev->name, result); | 478 | dev->name, result); |
465 | goto fail_adapter; | 479 | goto fail_adapter; |
466 | } | 480 | } |
481 | dvb_register_media_controller(&dvb->adapter, dev->media_dev); | ||
467 | 482 | ||
468 | /* Ensure all frontends negotiate bus access */ | 483 | /* Ensure all frontends negotiate bus access */ |
469 | dvb->frontend->ops.ts_bus_ctrl = cx231xx_dvb_bus_ctrl; | 484 | dvb->frontend->ops.ts_bus_ctrl = cx231xx_dvb_bus_ctrl; |
@@ -536,6 +551,8 @@ static int register_dvb(struct cx231xx_dvb *dvb, | |||
536 | 551 | ||
537 | /* register network adapter */ | 552 | /* register network adapter */ |
538 | dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx); | 553 | dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx); |
554 | dvb_create_media_graph(&dvb->adapter); | ||
555 | |||
539 | return 0; | 556 | return 0; |
540 | 557 | ||
541 | fail_fe_conn: | 558 | fail_fe_conn: |
@@ -807,7 +824,61 @@ static int dvb_init(struct cx231xx *dev) | |||
807 | dev->dvb->i2c_client_tuner = client; | 824 | dev->dvb->i2c_client_tuner = client; |
808 | break; | 825 | break; |
809 | } | 826 | } |
827 | case CX231XX_BOARD_HAUPPAUGE_955Q: | ||
828 | { | ||
829 | struct i2c_client *client; | ||
830 | struct i2c_board_info info; | ||
831 | struct si2157_config si2157_config; | ||
832 | |||
833 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
834 | |||
835 | dev->dvb->frontend = dvb_attach(lgdt3306a_attach, | ||
836 | &hauppauge_955q_lgdt3306a_config, | ||
837 | tuner_i2c | ||
838 | ); | ||
839 | |||
840 | if (dev->dvb->frontend == NULL) { | ||
841 | dev_err(dev->dev, | ||
842 | "Failed to attach LGDT3306A frontend.\n"); | ||
843 | result = -EINVAL; | ||
844 | goto out_free; | ||
845 | } | ||
846 | |||
847 | dev->dvb->frontend->ops.i2c_gate_ctrl = NULL; | ||
848 | |||
849 | /* define general-purpose callback pointer */ | ||
850 | dvb->frontend->callback = cx231xx_tuner_callback; | ||
851 | |||
852 | /* attach tuner */ | ||
853 | memset(&si2157_config, 0, sizeof(si2157_config)); | ||
854 | si2157_config.fe = dev->dvb->frontend; | ||
855 | si2157_config.inversion = true; | ||
856 | strlcpy(info.type, "si2157", I2C_NAME_SIZE); | ||
857 | info.addr = 0x60; | ||
858 | info.platform_data = &si2157_config; | ||
859 | request_module("si2157"); | ||
810 | 860 | ||
861 | client = i2c_new_device( | ||
862 | tuner_i2c, | ||
863 | &info); | ||
864 | if (client == NULL || client->dev.driver == NULL) { | ||
865 | dvb_frontend_detach(dev->dvb->frontend); | ||
866 | result = -ENODEV; | ||
867 | goto out_free; | ||
868 | } | ||
869 | |||
870 | if (!try_module_get(client->dev.driver->owner)) { | ||
871 | i2c_unregister_device(client); | ||
872 | dvb_frontend_detach(dev->dvb->frontend); | ||
873 | result = -ENODEV; | ||
874 | goto out_free; | ||
875 | } | ||
876 | |||
877 | dev->cx231xx_reset_analog_tuner = NULL; | ||
878 | |||
879 | dev->dvb->i2c_client_tuner = client; | ||
880 | break; | ||
881 | } | ||
811 | case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID: | 882 | case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID: |
812 | case CX231XX_BOARD_KWORLD_UB430_USB_HYBRID: | 883 | case CX231XX_BOARD_KWORLD_UB430_USB_HYBRID: |
813 | 884 | ||
diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index ecea76fe07f6..c261e160c158 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c | |||
@@ -100,6 +100,75 @@ static struct cx231xx_fmt format[] = { | |||
100 | }; | 100 | }; |
101 | 101 | ||
102 | 102 | ||
103 | static int cx231xx_enable_analog_tuner(struct cx231xx *dev) | ||
104 | { | ||
105 | #ifdef CONFIG_MEDIA_CONTROLLER | ||
106 | struct media_device *mdev = dev->media_dev; | ||
107 | struct media_entity *entity, *decoder = NULL, *source; | ||
108 | struct media_link *link, *found_link = NULL; | ||
109 | int i, ret, active_links = 0; | ||
110 | |||
111 | if (!mdev) | ||
112 | return 0; | ||
113 | |||
114 | /* | ||
115 | * This will find the tuner that is connected into the decoder. | ||
116 | * Technically, this is not 100% correct, as the device may be | ||
117 | * using an analog input instead of the tuner. However, as we can't | ||
118 | * do DVB streaming while the DMA engine is being used for V4L2, | ||
119 | * this should be enough for the actual needs. | ||
120 | */ | ||
121 | media_device_for_each_entity(entity, mdev) { | ||
122 | if (entity->type == MEDIA_ENT_T_V4L2_SUBDEV_DECODER) { | ||
123 | decoder = entity; | ||
124 | break; | ||
125 | } | ||
126 | } | ||
127 | if (!decoder) | ||
128 | return 0; | ||
129 | |||
130 | for (i = 0; i < decoder->num_links; i++) { | ||
131 | link = &decoder->links[i]; | ||
132 | if (link->sink->entity == decoder) { | ||
133 | found_link = link; | ||
134 | if (link->flags & MEDIA_LNK_FL_ENABLED) | ||
135 | active_links++; | ||
136 | break; | ||
137 | } | ||
138 | } | ||
139 | |||
140 | if (active_links == 1 || !found_link) | ||
141 | return 0; | ||
142 | |||
143 | source = found_link->source->entity; | ||
144 | for (i = 0; i < source->num_links; i++) { | ||
145 | struct media_entity *sink; | ||
146 | int flags = 0; | ||
147 | |||
148 | link = &source->links[i]; | ||
149 | sink = link->sink->entity; | ||
150 | |||
151 | if (sink == entity) | ||
152 | flags = MEDIA_LNK_FL_ENABLED; | ||
153 | |||
154 | ret = media_entity_setup_link(link, flags); | ||
155 | if (ret) { | ||
156 | dev_err(dev->dev, | ||
157 | "Couldn't change link %s->%s to %s. Error %d\n", | ||
158 | source->name, sink->name, | ||
159 | flags ? "enabled" : "disabled", | ||
160 | ret); | ||
161 | return ret; | ||
162 | } else | ||
163 | dev_dbg(dev->dev, | ||
164 | "link %s->%s was %s\n", | ||
165 | source->name, sink->name, | ||
166 | flags ? "ENABLED" : "disabled"); | ||
167 | } | ||
168 | #endif | ||
169 | return 0; | ||
170 | } | ||
171 | |||
103 | /* ------------------------------------------------------------------ | 172 | /* ------------------------------------------------------------------ |
104 | Video buffer and parser functions | 173 | Video buffer and parser functions |
105 | ------------------------------------------------------------------*/ | 174 | ------------------------------------------------------------------*/ |
@@ -667,6 +736,9 @@ buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) | |||
667 | if (*count < CX231XX_MIN_BUF) | 736 | if (*count < CX231XX_MIN_BUF) |
668 | *count = CX231XX_MIN_BUF; | 737 | *count = CX231XX_MIN_BUF; |
669 | 738 | ||
739 | |||
740 | cx231xx_enable_analog_tuner(dev); | ||
741 | |||
670 | return 0; | 742 | return 0; |
671 | } | 743 | } |
672 | 744 | ||
@@ -756,6 +828,7 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, | |||
756 | } | 828 | } |
757 | 829 | ||
758 | buf->vb.state = VIDEOBUF_PREPARED; | 830 | buf->vb.state = VIDEOBUF_PREPARED; |
831 | |||
759 | return 0; | 832 | return 0; |
760 | 833 | ||
761 | fail: | 834 | fail: |
@@ -1056,7 +1129,7 @@ int cx231xx_enum_input(struct file *file, void *priv, | |||
1056 | (CX231XX_VMUX_CABLE == INPUT(n)->type)) | 1129 | (CX231XX_VMUX_CABLE == INPUT(n)->type)) |
1057 | i->type = V4L2_INPUT_TYPE_TUNER; | 1130 | i->type = V4L2_INPUT_TYPE_TUNER; |
1058 | 1131 | ||
1059 | i->std = dev->vdev->tvnorms; | 1132 | i->std = dev->vdev.tvnorms; |
1060 | 1133 | ||
1061 | /* If they are asking about the active input, read signal status */ | 1134 | /* If they are asking about the active input, read signal status */ |
1062 | if (n == dev->video_input) { | 1135 | if (n == dev->video_input) { |
@@ -1451,7 +1524,7 @@ int cx231xx_querycap(struct file *file, void *priv, | |||
1451 | cap->capabilities = cap->device_caps | V4L2_CAP_READWRITE | | 1524 | cap->capabilities = cap->device_caps | V4L2_CAP_READWRITE | |
1452 | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_VIDEO_CAPTURE | | 1525 | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_VIDEO_CAPTURE | |
1453 | V4L2_CAP_STREAMING | V4L2_CAP_DEVICE_CAPS; | 1526 | V4L2_CAP_STREAMING | V4L2_CAP_DEVICE_CAPS; |
1454 | if (dev->radio_dev) | 1527 | if (video_is_registered(&dev->radio_dev)) |
1455 | cap->capabilities |= V4L2_CAP_RADIO; | 1528 | cap->capabilities |= V4L2_CAP_RADIO; |
1456 | 1529 | ||
1457 | return 0; | 1530 | return 0; |
@@ -1729,34 +1802,21 @@ void cx231xx_release_analog_resources(struct cx231xx *dev) | |||
1729 | 1802 | ||
1730 | /*FIXME: I2C IR should be disconnected */ | 1803 | /*FIXME: I2C IR should be disconnected */ |
1731 | 1804 | ||
1732 | if (dev->radio_dev) { | 1805 | if (video_is_registered(&dev->radio_dev)) |
1733 | if (video_is_registered(dev->radio_dev)) | 1806 | video_unregister_device(&dev->radio_dev); |
1734 | video_unregister_device(dev->radio_dev); | 1807 | if (video_is_registered(&dev->vbi_dev)) { |
1735 | else | ||
1736 | video_device_release(dev->radio_dev); | ||
1737 | dev->radio_dev = NULL; | ||
1738 | } | ||
1739 | if (dev->vbi_dev) { | ||
1740 | dev_info(dev->dev, "V4L2 device %s deregistered\n", | 1808 | dev_info(dev->dev, "V4L2 device %s deregistered\n", |
1741 | video_device_node_name(dev->vbi_dev)); | 1809 | video_device_node_name(&dev->vbi_dev)); |
1742 | if (video_is_registered(dev->vbi_dev)) | 1810 | video_unregister_device(&dev->vbi_dev); |
1743 | video_unregister_device(dev->vbi_dev); | ||
1744 | else | ||
1745 | video_device_release(dev->vbi_dev); | ||
1746 | dev->vbi_dev = NULL; | ||
1747 | } | 1811 | } |
1748 | if (dev->vdev) { | 1812 | if (video_is_registered(&dev->vdev)) { |
1749 | dev_info(dev->dev, "V4L2 device %s deregistered\n", | 1813 | dev_info(dev->dev, "V4L2 device %s deregistered\n", |
1750 | video_device_node_name(dev->vdev)); | 1814 | video_device_node_name(&dev->vdev)); |
1751 | 1815 | ||
1752 | if (dev->board.has_417) | 1816 | if (dev->board.has_417) |
1753 | cx231xx_417_unregister(dev); | 1817 | cx231xx_417_unregister(dev); |
1754 | 1818 | ||
1755 | if (video_is_registered(dev->vdev)) | 1819 | video_unregister_device(&dev->vdev); |
1756 | video_unregister_device(dev->vdev); | ||
1757 | else | ||
1758 | video_device_release(dev->vdev); | ||
1759 | dev->vdev = NULL; | ||
1760 | } | 1820 | } |
1761 | v4l2_ctrl_handler_free(&dev->ctrl_handler); | 1821 | v4l2_ctrl_handler_free(&dev->ctrl_handler); |
1762 | v4l2_ctrl_handler_free(&dev->radio_ctrl_handler); | 1822 | v4l2_ctrl_handler_free(&dev->radio_ctrl_handler); |
@@ -2013,7 +2073,7 @@ static struct video_device cx231xx_vbi_template; | |||
2013 | 2073 | ||
2014 | static const struct video_device cx231xx_video_template = { | 2074 | static const struct video_device cx231xx_video_template = { |
2015 | .fops = &cx231xx_v4l_fops, | 2075 | .fops = &cx231xx_v4l_fops, |
2016 | .release = video_device_release, | 2076 | .release = video_device_release_empty, |
2017 | .ioctl_ops = &video_ioctl_ops, | 2077 | .ioctl_ops = &video_ioctl_ops, |
2018 | .tvnorms = V4L2_STD_ALL, | 2078 | .tvnorms = V4L2_STD_ALL, |
2019 | }; | 2079 | }; |
@@ -2049,19 +2109,14 @@ static struct video_device cx231xx_radio_template = { | |||
2049 | 2109 | ||
2050 | /******************************** usb interface ******************************/ | 2110 | /******************************** usb interface ******************************/ |
2051 | 2111 | ||
2052 | static struct video_device *cx231xx_vdev_init(struct cx231xx *dev, | 2112 | static void cx231xx_vdev_init(struct cx231xx *dev, |
2053 | const struct video_device | 2113 | struct video_device *vfd, |
2054 | *template, const char *type_name) | 2114 | const struct video_device *template, |
2115 | const char *type_name) | ||
2055 | { | 2116 | { |
2056 | struct video_device *vfd; | ||
2057 | |||
2058 | vfd = video_device_alloc(); | ||
2059 | if (NULL == vfd) | ||
2060 | return NULL; | ||
2061 | |||
2062 | *vfd = *template; | 2117 | *vfd = *template; |
2063 | vfd->v4l2_dev = &dev->v4l2_dev; | 2118 | vfd->v4l2_dev = &dev->v4l2_dev; |
2064 | vfd->release = video_device_release; | 2119 | vfd->release = video_device_release_empty; |
2065 | vfd->lock = &dev->lock; | 2120 | vfd->lock = &dev->lock; |
2066 | 2121 | ||
2067 | snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name); | 2122 | snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name); |
@@ -2073,7 +2128,6 @@ static struct video_device *cx231xx_vdev_init(struct cx231xx *dev, | |||
2073 | v4l2_disable_ioctl(vfd, VIDIOC_G_TUNER); | 2128 | v4l2_disable_ioctl(vfd, VIDIOC_G_TUNER); |
2074 | v4l2_disable_ioctl(vfd, VIDIOC_S_TUNER); | 2129 | v4l2_disable_ioctl(vfd, VIDIOC_S_TUNER); |
2075 | } | 2130 | } |
2076 | return vfd; | ||
2077 | } | 2131 | } |
2078 | 2132 | ||
2079 | int cx231xx_register_analog_devices(struct cx231xx *dev) | 2133 | int cx231xx_register_analog_devices(struct cx231xx *dev) |
@@ -2116,15 +2170,16 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) | |||
2116 | /* write code here... */ | 2170 | /* write code here... */ |
2117 | 2171 | ||
2118 | /* allocate and fill video video_device struct */ | 2172 | /* allocate and fill video video_device struct */ |
2119 | dev->vdev = cx231xx_vdev_init(dev, &cx231xx_video_template, "video"); | 2173 | cx231xx_vdev_init(dev, &dev->vdev, &cx231xx_video_template, "video"); |
2120 | if (!dev->vdev) { | 2174 | #if defined(CONFIG_MEDIA_CONTROLLER) |
2121 | dev_err(dev->dev, "cannot allocate video_device.\n"); | 2175 | dev->video_pad.flags = MEDIA_PAD_FL_SINK; |
2122 | return -ENODEV; | 2176 | ret = media_entity_init(&dev->vdev.entity, 1, &dev->video_pad, 0); |
2123 | } | 2177 | if (ret < 0) |
2124 | 2178 | dev_err(dev->dev, "failed to initialize video media entity!\n"); | |
2125 | dev->vdev->ctrl_handler = &dev->ctrl_handler; | 2179 | #endif |
2180 | dev->vdev.ctrl_handler = &dev->ctrl_handler; | ||
2126 | /* register v4l2 video video_device */ | 2181 | /* register v4l2 video video_device */ |
2127 | ret = video_register_device(dev->vdev, VFL_TYPE_GRABBER, | 2182 | ret = video_register_device(&dev->vdev, VFL_TYPE_GRABBER, |
2128 | video_nr[dev->devno]); | 2183 | video_nr[dev->devno]); |
2129 | if (ret) { | 2184 | if (ret) { |
2130 | dev_err(dev->dev, | 2185 | dev_err(dev->dev, |
@@ -2134,22 +2189,24 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) | |||
2134 | } | 2189 | } |
2135 | 2190 | ||
2136 | dev_info(dev->dev, "Registered video device %s [v4l2]\n", | 2191 | dev_info(dev->dev, "Registered video device %s [v4l2]\n", |
2137 | video_device_node_name(dev->vdev)); | 2192 | video_device_node_name(&dev->vdev)); |
2138 | 2193 | ||
2139 | /* Initialize VBI template */ | 2194 | /* Initialize VBI template */ |
2140 | cx231xx_vbi_template = cx231xx_video_template; | 2195 | cx231xx_vbi_template = cx231xx_video_template; |
2141 | strcpy(cx231xx_vbi_template.name, "cx231xx-vbi"); | 2196 | strcpy(cx231xx_vbi_template.name, "cx231xx-vbi"); |
2142 | 2197 | ||
2143 | /* Allocate and fill vbi video_device struct */ | 2198 | /* Allocate and fill vbi video_device struct */ |
2144 | dev->vbi_dev = cx231xx_vdev_init(dev, &cx231xx_vbi_template, "vbi"); | 2199 | cx231xx_vdev_init(dev, &dev->vbi_dev, &cx231xx_vbi_template, "vbi"); |
2145 | 2200 | ||
2146 | if (!dev->vbi_dev) { | 2201 | #if defined(CONFIG_MEDIA_CONTROLLER) |
2147 | dev_err(dev->dev, "cannot allocate video_device.\n"); | 2202 | dev->vbi_pad.flags = MEDIA_PAD_FL_SINK; |
2148 | return -ENODEV; | 2203 | ret = media_entity_init(&dev->vbi_dev.entity, 1, &dev->vbi_pad, 0); |
2149 | } | 2204 | if (ret < 0) |
2150 | dev->vbi_dev->ctrl_handler = &dev->ctrl_handler; | 2205 | dev_err(dev->dev, "failed to initialize vbi media entity!\n"); |
2206 | #endif | ||
2207 | dev->vbi_dev.ctrl_handler = &dev->ctrl_handler; | ||
2151 | /* register v4l2 vbi video_device */ | 2208 | /* register v4l2 vbi video_device */ |
2152 | ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, | 2209 | ret = video_register_device(&dev->vbi_dev, VFL_TYPE_VBI, |
2153 | vbi_nr[dev->devno]); | 2210 | vbi_nr[dev->devno]); |
2154 | if (ret < 0) { | 2211 | if (ret < 0) { |
2155 | dev_err(dev->dev, "unable to register vbi device\n"); | 2212 | dev_err(dev->dev, "unable to register vbi device\n"); |
@@ -2157,18 +2214,13 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) | |||
2157 | } | 2214 | } |
2158 | 2215 | ||
2159 | dev_info(dev->dev, "Registered VBI device %s\n", | 2216 | dev_info(dev->dev, "Registered VBI device %s\n", |
2160 | video_device_node_name(dev->vbi_dev)); | 2217 | video_device_node_name(&dev->vbi_dev)); |
2161 | 2218 | ||
2162 | if (cx231xx_boards[dev->model].radio.type == CX231XX_RADIO) { | 2219 | if (cx231xx_boards[dev->model].radio.type == CX231XX_RADIO) { |
2163 | dev->radio_dev = cx231xx_vdev_init(dev, &cx231xx_radio_template, | 2220 | cx231xx_vdev_init(dev, &dev->radio_dev, |
2164 | "radio"); | 2221 | &cx231xx_radio_template, "radio"); |
2165 | if (!dev->radio_dev) { | 2222 | dev->radio_dev.ctrl_handler = &dev->radio_ctrl_handler; |
2166 | dev_err(dev->dev, | 2223 | ret = video_register_device(&dev->radio_dev, VFL_TYPE_RADIO, |
2167 | "cannot allocate video_device.\n"); | ||
2168 | return -ENODEV; | ||
2169 | } | ||
2170 | dev->radio_dev->ctrl_handler = &dev->radio_ctrl_handler; | ||
2171 | ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO, | ||
2172 | radio_nr[dev->devno]); | 2224 | radio_nr[dev->devno]); |
2173 | if (ret < 0) { | 2225 | if (ret < 0) { |
2174 | dev_err(dev->dev, | 2226 | dev_err(dev->dev, |
@@ -2176,7 +2228,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) | |||
2176 | return ret; | 2228 | return ret; |
2177 | } | 2229 | } |
2178 | dev_info(dev->dev, "Registered radio device as %s\n", | 2230 | dev_info(dev->dev, "Registered radio device as %s\n", |
2179 | video_device_node_name(dev->radio_dev)); | 2231 | video_device_node_name(&dev->radio_dev)); |
2180 | } | 2232 | } |
2181 | 2233 | ||
2182 | return 0; | 2234 | return 0; |
diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h index 6d6f3ee812f6..00d3bce9a690 100644 --- a/drivers/media/usb/cx231xx/cx231xx.h +++ b/drivers/media/usb/cx231xx/cx231xx.h | |||
@@ -76,6 +76,7 @@ | |||
76 | #define CX231XX_BOARD_KWORLD_UB445_USB_HYBRID 18 | 76 | #define CX231XX_BOARD_KWORLD_UB445_USB_HYBRID 18 |
77 | #define CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx 19 | 77 | #define CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx 19 |
78 | #define CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx 20 | 78 | #define CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx 20 |
79 | #define CX231XX_BOARD_HAUPPAUGE_955Q 21 | ||
79 | 80 | ||
80 | /* Limits minimum and default number of buffers */ | 81 | /* Limits minimum and default number of buffers */ |
81 | #define CX231XX_MIN_BUF 4 | 82 | #define CX231XX_MIN_BUF 4 |
@@ -633,7 +634,7 @@ struct cx231xx { | |||
633 | 634 | ||
634 | /* video for linux */ | 635 | /* video for linux */ |
635 | int users; /* user count for exclusive use */ | 636 | int users; /* user count for exclusive use */ |
636 | struct video_device *vdev; /* video for linux device struct */ | 637 | struct video_device vdev; /* video for linux device struct */ |
637 | v4l2_std_id norm; /* selected tv norm */ | 638 | v4l2_std_id norm; /* selected tv norm */ |
638 | int ctl_freq; /* selected frequency */ | 639 | int ctl_freq; /* selected frequency */ |
639 | unsigned int ctl_ainput; /* selected audio input */ | 640 | unsigned int ctl_ainput; /* selected audio input */ |
@@ -655,8 +656,13 @@ struct cx231xx { | |||
655 | struct mutex ctrl_urb_lock; /* protects urb_buf */ | 656 | struct mutex ctrl_urb_lock; /* protects urb_buf */ |
656 | struct list_head inqueue, outqueue; | 657 | struct list_head inqueue, outqueue; |
657 | wait_queue_head_t open, wait_frame, wait_stream; | 658 | wait_queue_head_t open, wait_frame, wait_stream; |
658 | struct video_device *vbi_dev; | 659 | struct video_device vbi_dev; |
659 | struct video_device *radio_dev; | 660 | struct video_device radio_dev; |
661 | |||
662 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
663 | struct media_device *media_dev; | ||
664 | struct media_pad video_pad, vbi_pad; | ||
665 | #endif | ||
660 | 666 | ||
661 | unsigned char eedata[256]; | 667 | unsigned char eedata[256]; |
662 | 668 | ||
@@ -718,7 +724,7 @@ struct cx231xx { | |||
718 | u8 USE_ISO; | 724 | u8 USE_ISO; |
719 | struct cx231xx_tvnorm encodernorm; | 725 | struct cx231xx_tvnorm encodernorm; |
720 | struct cx231xx_tsport ts1, ts2; | 726 | struct cx231xx_tsport ts1, ts2; |
721 | struct video_device *v4l_device; | 727 | struct video_device v4l_device; |
722 | atomic_t v4l_reader_count; | 728 | atomic_t v4l_reader_count; |
723 | u32 freq; | 729 | u32 freq; |
724 | unsigned int input; | 730 | unsigned int input; |
@@ -972,8 +978,11 @@ extern void cx231xx_417_unregister(struct cx231xx *dev); | |||
972 | int cx231xx_ir_init(struct cx231xx *dev); | 978 | int cx231xx_ir_init(struct cx231xx *dev); |
973 | void cx231xx_ir_exit(struct cx231xx *dev); | 979 | void cx231xx_ir_exit(struct cx231xx *dev); |
974 | #else | 980 | #else |
975 | #define cx231xx_ir_init(dev) (0) | 981 | static inline int cx231xx_ir_init(struct cx231xx *dev) |
976 | #define cx231xx_ir_exit(dev) (0) | 982 | { |
983 | return 0; | ||
984 | } | ||
985 | static inline void cx231xx_ir_exit(struct cx231xx *dev) {} | ||
977 | #endif | 986 | #endif |
978 | 987 | ||
979 | static inline unsigned int norm_maxw(struct cx231xx *dev) | 988 | static inline unsigned int norm_maxw(struct cx231xx *dev) |
diff --git a/drivers/media/usb/dvb-usb-v2/Kconfig b/drivers/media/usb/dvb-usb-v2/Kconfig index 0982e734fab5..9facc92c8dea 100644 --- a/drivers/media/usb/dvb-usb-v2/Kconfig +++ b/drivers/media/usb/dvb-usb-v2/Kconfig | |||
@@ -146,7 +146,7 @@ config DVB_USB_DVBSKY | |||
146 | depends on DVB_USB_V2 | 146 | depends on DVB_USB_V2 |
147 | select DVB_M88DS3103 if MEDIA_SUBDRV_AUTOSELECT | 147 | select DVB_M88DS3103 if MEDIA_SUBDRV_AUTOSELECT |
148 | select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT | 148 | select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT |
149 | select MEDIA_TUNER_M88TS2022 if MEDIA_SUBDRV_AUTOSELECT | 149 | select DVB_TS2020 if MEDIA_SUBDRV_AUTOSELECT |
150 | select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT | 150 | select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT |
151 | select DVB_SP2 if MEDIA_SUBDRV_AUTOSELECT | 151 | select DVB_SP2 if MEDIA_SUBDRV_AUTOSELECT |
152 | help | 152 | help |
diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb.h b/drivers/media/usb/dvb-usb-v2/dvb_usb.h index 41c6363dff08..023d91f7e654 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb.h +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb.h | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/usb/input.h> | 25 | #include <linux/usb/input.h> |
26 | #include <linux/firmware.h> | 26 | #include <linux/firmware.h> |
27 | #include <media/rc-core.h> | 27 | #include <media/rc-core.h> |
28 | #include <media/media-device.h> | ||
28 | 29 | ||
29 | #include "dvb_frontend.h" | 30 | #include "dvb_frontend.h" |
30 | #include "dvb_demux.h" | 31 | #include "dvb_demux.h" |
diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c index 9913e0f59485..f5df9eaba04f 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c | |||
@@ -400,10 +400,61 @@ skip_feed_stop: | |||
400 | return ret; | 400 | return ret; |
401 | } | 401 | } |
402 | 402 | ||
403 | static void dvb_usbv2_media_device_register(struct dvb_usb_adapter *adap) | ||
404 | { | ||
405 | #ifdef CONFIG_MEDIA_CONTROLLER_DVB | ||
406 | struct media_device *mdev; | ||
407 | struct dvb_usb_device *d = adap_to_d(adap); | ||
408 | struct usb_device *udev = d->udev; | ||
409 | int ret; | ||
410 | |||
411 | mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); | ||
412 | if (!mdev) | ||
413 | return; | ||
414 | |||
415 | mdev->dev = &udev->dev; | ||
416 | strlcpy(mdev->model, d->name, sizeof(mdev->model)); | ||
417 | if (udev->serial) | ||
418 | strlcpy(mdev->serial, udev->serial, sizeof(mdev->serial)); | ||
419 | strcpy(mdev->bus_info, udev->devpath); | ||
420 | mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice); | ||
421 | mdev->driver_version = LINUX_VERSION_CODE; | ||
422 | |||
423 | ret = media_device_register(mdev); | ||
424 | if (ret) { | ||
425 | dev_err(&d->udev->dev, | ||
426 | "Couldn't create a media device. Error: %d\n", | ||
427 | ret); | ||
428 | kfree(mdev); | ||
429 | return; | ||
430 | } | ||
431 | |||
432 | dvb_register_media_controller(&adap->dvb_adap, mdev); | ||
433 | |||
434 | dev_info(&d->udev->dev, "media controller created\n"); | ||
435 | |||
436 | #endif | ||
437 | } | ||
438 | |||
439 | static void dvb_usbv2_media_device_unregister(struct dvb_usb_adapter *adap) | ||
440 | { | ||
441 | #ifdef CONFIG_MEDIA_CONTROLLER_DVB | ||
442 | |||
443 | if (!adap->dvb_adap.mdev) | ||
444 | return; | ||
445 | |||
446 | media_device_unregister(adap->dvb_adap.mdev); | ||
447 | kfree(adap->dvb_adap.mdev); | ||
448 | adap->dvb_adap.mdev = NULL; | ||
449 | |||
450 | #endif | ||
451 | } | ||
452 | |||
403 | static int dvb_usbv2_adapter_dvb_init(struct dvb_usb_adapter *adap) | 453 | static int dvb_usbv2_adapter_dvb_init(struct dvb_usb_adapter *adap) |
404 | { | 454 | { |
405 | int ret; | 455 | int ret; |
406 | struct dvb_usb_device *d = adap_to_d(adap); | 456 | struct dvb_usb_device *d = adap_to_d(adap); |
457 | |||
407 | dev_dbg(&d->udev->dev, "%s: adap=%d\n", __func__, adap->id); | 458 | dev_dbg(&d->udev->dev, "%s: adap=%d\n", __func__, adap->id); |
408 | 459 | ||
409 | ret = dvb_register_adapter(&adap->dvb_adap, d->name, d->props->owner, | 460 | ret = dvb_register_adapter(&adap->dvb_adap, d->name, d->props->owner, |
@@ -416,6 +467,8 @@ static int dvb_usbv2_adapter_dvb_init(struct dvb_usb_adapter *adap) | |||
416 | 467 | ||
417 | adap->dvb_adap.priv = adap; | 468 | adap->dvb_adap.priv = adap; |
418 | 469 | ||
470 | dvb_usbv2_media_device_register(adap); | ||
471 | |||
419 | if (d->props->read_mac_address) { | 472 | if (d->props->read_mac_address) { |
420 | ret = d->props->read_mac_address(adap, | 473 | ret = d->props->read_mac_address(adap, |
421 | adap->dvb_adap.proposed_mac); | 474 | adap->dvb_adap.proposed_mac); |
@@ -464,6 +517,7 @@ err_dvb_net_init: | |||
464 | err_dvb_dmxdev_init: | 517 | err_dvb_dmxdev_init: |
465 | dvb_dmx_release(&adap->demux); | 518 | dvb_dmx_release(&adap->demux); |
466 | err_dvb_dmx_init: | 519 | err_dvb_dmx_init: |
520 | dvb_usbv2_media_device_unregister(adap); | ||
467 | dvb_unregister_adapter(&adap->dvb_adap); | 521 | dvb_unregister_adapter(&adap->dvb_adap); |
468 | err_dvb_register_adapter: | 522 | err_dvb_register_adapter: |
469 | adap->dvb_adap.priv = NULL; | 523 | adap->dvb_adap.priv = NULL; |
@@ -480,6 +534,7 @@ static int dvb_usbv2_adapter_dvb_exit(struct dvb_usb_adapter *adap) | |||
480 | adap->demux.dmx.close(&adap->demux.dmx); | 534 | adap->demux.dmx.close(&adap->demux.dmx); |
481 | dvb_dmxdev_release(&adap->dmxdev); | 535 | dvb_dmxdev_release(&adap->dmxdev); |
482 | dvb_dmx_release(&adap->demux); | 536 | dvb_dmx_release(&adap->demux); |
537 | dvb_usbv2_media_device_unregister(adap); | ||
483 | dvb_unregister_adapter(&adap->dvb_adap); | 538 | dvb_unregister_adapter(&adap->dvb_adap); |
484 | } | 539 | } |
485 | 540 | ||
@@ -643,6 +698,8 @@ static int dvb_usbv2_adapter_frontend_init(struct dvb_usb_adapter *adap) | |||
643 | } | 698 | } |
644 | } | 699 | } |
645 | 700 | ||
701 | dvb_create_media_graph(&adap->dvb_adap); | ||
702 | |||
646 | return 0; | 703 | return 0; |
647 | 704 | ||
648 | err_dvb_unregister_frontend: | 705 | err_dvb_unregister_frontend: |
@@ -955,6 +1012,7 @@ void dvb_usbv2_disconnect(struct usb_interface *intf) | |||
955 | struct dvb_usb_device *d = usb_get_intfdata(intf); | 1012 | struct dvb_usb_device *d = usb_get_intfdata(intf); |
956 | const char *name = d->name; | 1013 | const char *name = d->name; |
957 | struct device dev = d->udev->dev; | 1014 | struct device dev = d->udev->dev; |
1015 | |||
958 | dev_dbg(&d->udev->dev, "%s: bInterfaceNumber=%d\n", __func__, | 1016 | dev_dbg(&d->udev->dev, "%s: bInterfaceNumber=%d\n", __func__, |
959 | intf->cur_altsetting->desc.bInterfaceNumber); | 1017 | intf->cur_altsetting->desc.bInterfaceNumber); |
960 | 1018 | ||
diff --git a/drivers/media/usb/dvb-usb-v2/dvbsky.c b/drivers/media/usb/dvb-usb-v2/dvbsky.c index 9b5add4499e3..cdf59bcd760c 100644 --- a/drivers/media/usb/dvb-usb-v2/dvbsky.c +++ b/drivers/media/usb/dvb-usb-v2/dvbsky.c | |||
@@ -20,7 +20,7 @@ | |||
20 | 20 | ||
21 | #include "dvb_usb.h" | 21 | #include "dvb_usb.h" |
22 | #include "m88ds3103.h" | 22 | #include "m88ds3103.h" |
23 | #include "m88ts2022.h" | 23 | #include "ts2020.h" |
24 | #include "sp2.h" | 24 | #include "sp2.h" |
25 | #include "si2168.h" | 25 | #include "si2168.h" |
26 | #include "si2157.h" | 26 | #include "si2157.h" |
@@ -315,9 +315,7 @@ static int dvbsky_s960_attach(struct dvb_usb_adapter *adap) | |||
315 | struct i2c_adapter *i2c_adapter; | 315 | struct i2c_adapter *i2c_adapter; |
316 | struct i2c_client *client; | 316 | struct i2c_client *client; |
317 | struct i2c_board_info info; | 317 | struct i2c_board_info info; |
318 | struct m88ts2022_config m88ts2022_config = { | 318 | struct ts2020_config ts2020_config = {}; |
319 | .clock = 27000000, | ||
320 | }; | ||
321 | memset(&info, 0, sizeof(struct i2c_board_info)); | 319 | memset(&info, 0, sizeof(struct i2c_board_info)); |
322 | 320 | ||
323 | /* attach demod */ | 321 | /* attach demod */ |
@@ -332,11 +330,11 @@ static int dvbsky_s960_attach(struct dvb_usb_adapter *adap) | |||
332 | } | 330 | } |
333 | 331 | ||
334 | /* attach tuner */ | 332 | /* attach tuner */ |
335 | m88ts2022_config.fe = adap->fe[0]; | 333 | ts2020_config.fe = adap->fe[0]; |
336 | strlcpy(info.type, "m88ts2022", I2C_NAME_SIZE); | 334 | strlcpy(info.type, "ts2020", I2C_NAME_SIZE); |
337 | info.addr = 0x60; | 335 | info.addr = 0x60; |
338 | info.platform_data = &m88ts2022_config; | 336 | info.platform_data = &ts2020_config; |
339 | request_module("m88ts2022"); | 337 | request_module("ts2020"); |
340 | client = i2c_new_device(i2c_adapter, &info); | 338 | client = i2c_new_device(i2c_adapter, &info); |
341 | if (client == NULL || client->dev.driver == NULL) { | 339 | if (client == NULL || client->dev.driver == NULL) { |
342 | dvb_frontend_detach(adap->fe[0]); | 340 | dvb_frontend_detach(adap->fe[0]); |
@@ -439,9 +437,7 @@ static int dvbsky_s960c_attach(struct dvb_usb_adapter *adap) | |||
439 | struct i2c_client *client_tuner, *client_ci; | 437 | struct i2c_client *client_tuner, *client_ci; |
440 | struct i2c_board_info info; | 438 | struct i2c_board_info info; |
441 | struct sp2_config sp2_config; | 439 | struct sp2_config sp2_config; |
442 | struct m88ts2022_config m88ts2022_config = { | 440 | struct ts2020_config ts2020_config = {}; |
443 | .clock = 27000000, | ||
444 | }; | ||
445 | memset(&info, 0, sizeof(struct i2c_board_info)); | 441 | memset(&info, 0, sizeof(struct i2c_board_info)); |
446 | 442 | ||
447 | /* attach demod */ | 443 | /* attach demod */ |
@@ -456,11 +452,11 @@ static int dvbsky_s960c_attach(struct dvb_usb_adapter *adap) | |||
456 | } | 452 | } |
457 | 453 | ||
458 | /* attach tuner */ | 454 | /* attach tuner */ |
459 | m88ts2022_config.fe = adap->fe[0]; | 455 | ts2020_config.fe = adap->fe[0]; |
460 | strlcpy(info.type, "m88ts2022", I2C_NAME_SIZE); | 456 | strlcpy(info.type, "ts2020", I2C_NAME_SIZE); |
461 | info.addr = 0x60; | 457 | info.addr = 0x60; |
462 | info.platform_data = &m88ts2022_config; | 458 | info.platform_data = &ts2020_config; |
463 | request_module("m88ts2022"); | 459 | request_module("ts2020"); |
464 | client_tuner = i2c_new_device(i2c_adapter, &info); | 460 | client_tuner = i2c_new_device(i2c_adapter, &info); |
465 | if (client_tuner == NULL || client_tuner->dev.driver == NULL) { | 461 | if (client_tuner == NULL || client_tuner->dev.driver == NULL) { |
466 | ret = -ENODEV; | 462 | ret = -ENODEV; |
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index 87fc0fe29ebd..895441fe90f7 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c | |||
@@ -866,6 +866,8 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap) | |||
866 | mn88472_config.i2c_wr_max = 22, | 866 | mn88472_config.i2c_wr_max = 22, |
867 | strlcpy(info.type, "mn88472", I2C_NAME_SIZE); | 867 | strlcpy(info.type, "mn88472", I2C_NAME_SIZE); |
868 | mn88472_config.xtal = 20500000; | 868 | mn88472_config.xtal = 20500000; |
869 | mn88472_config.ts_mode = SERIAL_TS_MODE; | ||
870 | mn88472_config.ts_clock = VARIABLE_TS_CLOCK; | ||
869 | info.addr = 0x18; | 871 | info.addr = 0x18; |
870 | info.platform_data = &mn88472_config; | 872 | info.platform_data = &mn88472_config; |
871 | request_module(info.type); | 873 | request_module(info.type); |
@@ -1609,7 +1611,7 @@ static int rtl2832u_get_rc_config(struct dvb_usb_device *d, | |||
1609 | rc->allowed_protos = RC_BIT_ALL; | 1611 | rc->allowed_protos = RC_BIT_ALL; |
1610 | rc->driver_type = RC_DRIVER_IR_RAW; | 1612 | rc->driver_type = RC_DRIVER_IR_RAW; |
1611 | rc->query = rtl2832u_rc_query; | 1613 | rc->query = rtl2832u_rc_query; |
1612 | rc->interval = 400; | 1614 | rc->interval = 200; |
1613 | 1615 | ||
1614 | return 0; | 1616 | return 0; |
1615 | } | 1617 | } |
@@ -1724,6 +1726,8 @@ static const struct usb_device_id rtl28xxu_id_table[] = { | |||
1724 | &rtl28xxu_props, "DigitalNow Quad DVB-T Receiver", NULL) }, | 1726 | &rtl28xxu_props, "DigitalNow Quad DVB-T Receiver", NULL) }, |
1725 | { DVB_USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_MINID, | 1727 | { DVB_USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_MINID, |
1726 | &rtl28xxu_props, "Leadtek Winfast DTV Dongle Mini D", NULL) }, | 1728 | &rtl28xxu_props, "Leadtek Winfast DTV Dongle Mini D", NULL) }, |
1729 | { DVB_USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV2000DS_PLUS, | ||
1730 | &rtl28xxu_props, "Leadtek WinFast DTV2000DS Plus", RC_MAP_LEADTEK_Y04G0051) }, | ||
1727 | { DVB_USB_DEVICE(USB_VID_TERRATEC, 0x00d3, | 1731 | { DVB_USB_DEVICE(USB_VID_TERRATEC, 0x00d3, |
1728 | &rtl28xxu_props, "TerraTec Cinergy T Stick RC (Rev. 3)", NULL) }, | 1732 | &rtl28xxu_props, "TerraTec Cinergy T Stick RC (Rev. 3)", NULL) }, |
1729 | { DVB_USB_DEVICE(USB_VID_DEXATEK, 0x1102, | 1733 | { DVB_USB_DEVICE(USB_VID_DEXATEK, 0x1102, |
@@ -1754,6 +1758,8 @@ static const struct usb_device_id rtl28xxu_id_table[] = { | |||
1754 | &rtl28xxu_props, "Sveon STV21", NULL) }, | 1758 | &rtl28xxu_props, "Sveon STV21", NULL) }, |
1755 | { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV27, | 1759 | { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV27, |
1756 | &rtl28xxu_props, "Sveon STV27", NULL) }, | 1760 | &rtl28xxu_props, "Sveon STV27", NULL) }, |
1761 | { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_TURBOX_DTT_2000, | ||
1762 | &rtl28xxu_props, "TURBO-X Pure TV Tuner DTT-2000", NULL) }, | ||
1757 | 1763 | ||
1758 | /* RTL2832P devices: */ | 1764 | /* RTL2832P devices: */ |
1759 | { DVB_USB_DEVICE(USB_VID_HANFTEK, 0x0131, | 1765 | { DVB_USB_DEVICE(USB_VID_HANFTEK, 0x0131, |
diff --git a/drivers/media/usb/dvb-usb/Kconfig b/drivers/media/usb/dvb-usb/Kconfig index 3364200db093..128eee61570d 100644 --- a/drivers/media/usb/dvb-usb/Kconfig +++ b/drivers/media/usb/dvb-usb/Kconfig | |||
@@ -278,9 +278,10 @@ config DVB_USB_DW2102 | |||
278 | select DVB_STV6110 if MEDIA_SUBDRV_AUTOSELECT | 278 | select DVB_STV6110 if MEDIA_SUBDRV_AUTOSELECT |
279 | select DVB_STV0900 if MEDIA_SUBDRV_AUTOSELECT | 279 | select DVB_STV0900 if MEDIA_SUBDRV_AUTOSELECT |
280 | select DVB_M88RS2000 if MEDIA_SUBDRV_AUTOSELECT | 280 | select DVB_M88RS2000 if MEDIA_SUBDRV_AUTOSELECT |
281 | select DVB_M88DS3103 if MEDIA_SUBDRV_AUTOSELECT | ||
281 | help | 282 | help |
282 | Say Y here to support the DvbWorld, TeVii, Prof DVB-S/S2 USB2.0 | 283 | Say Y here to support the DvbWorld, TeVii, Prof, TechnoTrend |
283 | receivers. | 284 | DVB-S/S2 USB2.0 receivers. |
284 | 285 | ||
285 | config DVB_USB_CINERGY_T2 | 286 | config DVB_USB_CINERGY_T2 |
286 | tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver" | 287 | tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver" |
diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c index f327c49d7e09..ffc3704abded 100644 --- a/drivers/media/usb/dvb-usb/cxusb.c +++ b/drivers/media/usb/dvb-usb/cxusb.c | |||
@@ -1516,28 +1516,95 @@ static void cxusb_disconnect(struct usb_interface *intf) | |||
1516 | dvb_usb_device_exit(intf); | 1516 | dvb_usb_device_exit(intf); |
1517 | } | 1517 | } |
1518 | 1518 | ||
1519 | static struct usb_device_id cxusb_table [] = { | 1519 | enum cxusb_table_index { |
1520 | { USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) }, | 1520 | MEDION_MD95700, |
1521 | { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD) }, | 1521 | DVICO_BLUEBIRD_LG064F_COLD, |
1522 | { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_WARM) }, | 1522 | DVICO_BLUEBIRD_LG064F_WARM, |
1523 | { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_COLD) }, | 1523 | DVICO_BLUEBIRD_DUAL_1_COLD, |
1524 | { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_WARM) }, | 1524 | DVICO_BLUEBIRD_DUAL_1_WARM, |
1525 | { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_COLD) }, | 1525 | DVICO_BLUEBIRD_LGZ201_COLD, |
1526 | { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_WARM) }, | 1526 | DVICO_BLUEBIRD_LGZ201_WARM, |
1527 | { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_COLD) }, | 1527 | DVICO_BLUEBIRD_TH7579_COLD, |
1528 | { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_WARM) }, | 1528 | DVICO_BLUEBIRD_TH7579_WARM, |
1529 | { USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD) }, | 1529 | DIGITALNOW_BLUEBIRD_DUAL_1_COLD, |
1530 | { USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM) }, | 1530 | DIGITALNOW_BLUEBIRD_DUAL_1_WARM, |
1531 | { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD) }, | 1531 | DVICO_BLUEBIRD_DUAL_2_COLD, |
1532 | { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM) }, | 1532 | DVICO_BLUEBIRD_DUAL_2_WARM, |
1533 | { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4) }, | 1533 | DVICO_BLUEBIRD_DUAL_4, |
1534 | { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) }, | 1534 | DVICO_BLUEBIRD_DVB_T_NANO_2, |
1535 | { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) }, | 1535 | DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM, |
1536 | { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) }, | 1536 | AVERMEDIA_VOLAR_A868R, |
1537 | { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2) }, | 1537 | DVICO_BLUEBIRD_DUAL_4_REV_2, |
1538 | { USB_DEVICE(USB_VID_CONEXANT, USB_PID_CONEXANT_D680_DMB) }, | 1538 | CONEXANT_D680_DMB, |
1539 | { USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_D689) }, | 1539 | MYGICA_D689, |
1540 | { USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230) }, | 1540 | MYGICA_T230, |
1541 | NR__cxusb_table_index | ||
1542 | }; | ||
1543 | |||
1544 | static struct usb_device_id cxusb_table[NR__cxusb_table_index + 1] = { | ||
1545 | [MEDION_MD95700] = { | ||
1546 | USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) | ||
1547 | }, | ||
1548 | [DVICO_BLUEBIRD_LG064F_COLD] = { | ||
1549 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD) | ||
1550 | }, | ||
1551 | [DVICO_BLUEBIRD_LG064F_WARM] = { | ||
1552 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_WARM) | ||
1553 | }, | ||
1554 | [DVICO_BLUEBIRD_DUAL_1_COLD] = { | ||
1555 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_COLD) | ||
1556 | }, | ||
1557 | [DVICO_BLUEBIRD_DUAL_1_WARM] = { | ||
1558 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_WARM) | ||
1559 | }, | ||
1560 | [DVICO_BLUEBIRD_LGZ201_COLD] = { | ||
1561 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_COLD) | ||
1562 | }, | ||
1563 | [DVICO_BLUEBIRD_LGZ201_WARM] = { | ||
1564 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_WARM) | ||
1565 | }, | ||
1566 | [DVICO_BLUEBIRD_TH7579_COLD] = { | ||
1567 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_COLD) | ||
1568 | }, | ||
1569 | [DVICO_BLUEBIRD_TH7579_WARM] = { | ||
1570 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_WARM) | ||
1571 | }, | ||
1572 | [DIGITALNOW_BLUEBIRD_DUAL_1_COLD] = { | ||
1573 | USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD) | ||
1574 | }, | ||
1575 | [DIGITALNOW_BLUEBIRD_DUAL_1_WARM] = { | ||
1576 | USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM) | ||
1577 | }, | ||
1578 | [DVICO_BLUEBIRD_DUAL_2_COLD] = { | ||
1579 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD) | ||
1580 | }, | ||
1581 | [DVICO_BLUEBIRD_DUAL_2_WARM] = { | ||
1582 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM) | ||
1583 | }, | ||
1584 | [DVICO_BLUEBIRD_DUAL_4] = { | ||
1585 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4) | ||
1586 | }, | ||
1587 | [DVICO_BLUEBIRD_DVB_T_NANO_2] = { | ||
1588 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) | ||
1589 | }, | ||
1590 | [DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM] = { | ||
1591 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) | ||
1592 | }, | ||
1593 | [AVERMEDIA_VOLAR_A868R] = { | ||
1594 | USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) | ||
1595 | }, | ||
1596 | [DVICO_BLUEBIRD_DUAL_4_REV_2] = { | ||
1597 | USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2) | ||
1598 | }, | ||
1599 | [CONEXANT_D680_DMB] = { | ||
1600 | USB_DEVICE(USB_VID_CONEXANT, USB_PID_CONEXANT_D680_DMB) | ||
1601 | }, | ||
1602 | [MYGICA_D689] = { | ||
1603 | USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_D689) | ||
1604 | }, | ||
1605 | [MYGICA_T230] = { | ||
1606 | USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230) | ||
1607 | }, | ||
1541 | {} /* Terminating entry */ | 1608 | {} /* Terminating entry */ |
1542 | }; | 1609 | }; |
1543 | MODULE_DEVICE_TABLE (usb, cxusb_table); | 1610 | MODULE_DEVICE_TABLE (usb, cxusb_table); |
@@ -1581,7 +1648,7 @@ static struct dvb_usb_device_properties cxusb_medion_properties = { | |||
1581 | .devices = { | 1648 | .devices = { |
1582 | { "Medion MD95700 (MDUSBTV-HYBRID)", | 1649 | { "Medion MD95700 (MDUSBTV-HYBRID)", |
1583 | { NULL }, | 1650 | { NULL }, |
1584 | { &cxusb_table[0], NULL }, | 1651 | { &cxusb_table[MEDION_MD95700], NULL }, |
1585 | }, | 1652 | }, |
1586 | } | 1653 | } |
1587 | }; | 1654 | }; |
@@ -1637,8 +1704,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties = { | |||
1637 | .num_device_descs = 1, | 1704 | .num_device_descs = 1, |
1638 | .devices = { | 1705 | .devices = { |
1639 | { "DViCO FusionHDTV5 USB Gold", | 1706 | { "DViCO FusionHDTV5 USB Gold", |
1640 | { &cxusb_table[1], NULL }, | 1707 | { &cxusb_table[DVICO_BLUEBIRD_LG064F_COLD], NULL }, |
1641 | { &cxusb_table[2], NULL }, | 1708 | { &cxusb_table[DVICO_BLUEBIRD_LG064F_WARM], NULL }, |
1642 | }, | 1709 | }, |
1643 | } | 1710 | } |
1644 | }; | 1711 | }; |
@@ -1693,16 +1760,16 @@ static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties = { | |||
1693 | .num_device_descs = 3, | 1760 | .num_device_descs = 3, |
1694 | .devices = { | 1761 | .devices = { |
1695 | { "DViCO FusionHDTV DVB-T Dual USB", | 1762 | { "DViCO FusionHDTV DVB-T Dual USB", |
1696 | { &cxusb_table[3], NULL }, | 1763 | { &cxusb_table[DVICO_BLUEBIRD_DUAL_1_COLD], NULL }, |
1697 | { &cxusb_table[4], NULL }, | 1764 | { &cxusb_table[DVICO_BLUEBIRD_DUAL_1_WARM], NULL }, |
1698 | }, | 1765 | }, |
1699 | { "DigitalNow DVB-T Dual USB", | 1766 | { "DigitalNow DVB-T Dual USB", |
1700 | { &cxusb_table[9], NULL }, | 1767 | { &cxusb_table[DIGITALNOW_BLUEBIRD_DUAL_1_COLD], NULL }, |
1701 | { &cxusb_table[10], NULL }, | 1768 | { &cxusb_table[DIGITALNOW_BLUEBIRD_DUAL_1_WARM], NULL }, |
1702 | }, | 1769 | }, |
1703 | { "DViCO FusionHDTV DVB-T Dual Digital 2", | 1770 | { "DViCO FusionHDTV DVB-T Dual Digital 2", |
1704 | { &cxusb_table[11], NULL }, | 1771 | { &cxusb_table[DVICO_BLUEBIRD_DUAL_2_COLD], NULL }, |
1705 | { &cxusb_table[12], NULL }, | 1772 | { &cxusb_table[DVICO_BLUEBIRD_DUAL_2_WARM], NULL }, |
1706 | }, | 1773 | }, |
1707 | } | 1774 | } |
1708 | }; | 1775 | }; |
@@ -1756,8 +1823,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = { | |||
1756 | .num_device_descs = 1, | 1823 | .num_device_descs = 1, |
1757 | .devices = { | 1824 | .devices = { |
1758 | { "DViCO FusionHDTV DVB-T USB (LGZ201)", | 1825 | { "DViCO FusionHDTV DVB-T USB (LGZ201)", |
1759 | { &cxusb_table[5], NULL }, | 1826 | { &cxusb_table[DVICO_BLUEBIRD_LGZ201_COLD], NULL }, |
1760 | { &cxusb_table[6], NULL }, | 1827 | { &cxusb_table[DVICO_BLUEBIRD_LGZ201_WARM], NULL }, |
1761 | }, | 1828 | }, |
1762 | } | 1829 | } |
1763 | }; | 1830 | }; |
@@ -1812,8 +1879,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties = { | |||
1812 | .num_device_descs = 1, | 1879 | .num_device_descs = 1, |
1813 | .devices = { | 1880 | .devices = { |
1814 | { "DViCO FusionHDTV DVB-T USB (TH7579)", | 1881 | { "DViCO FusionHDTV DVB-T USB (TH7579)", |
1815 | { &cxusb_table[7], NULL }, | 1882 | { &cxusb_table[DVICO_BLUEBIRD_TH7579_COLD], NULL }, |
1816 | { &cxusb_table[8], NULL }, | 1883 | { &cxusb_table[DVICO_BLUEBIRD_TH7579_WARM], NULL }, |
1817 | }, | 1884 | }, |
1818 | } | 1885 | } |
1819 | }; | 1886 | }; |
@@ -1865,7 +1932,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties = { | |||
1865 | .devices = { | 1932 | .devices = { |
1866 | { "DViCO FusionHDTV DVB-T Dual Digital 4", | 1933 | { "DViCO FusionHDTV DVB-T Dual Digital 4", |
1867 | { NULL }, | 1934 | { NULL }, |
1868 | { &cxusb_table[13], NULL }, | 1935 | { &cxusb_table[DVICO_BLUEBIRD_DUAL_4], NULL }, |
1869 | }, | 1936 | }, |
1870 | } | 1937 | } |
1871 | }; | 1938 | }; |
@@ -1918,7 +1985,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties = { | |||
1918 | .devices = { | 1985 | .devices = { |
1919 | { "DViCO FusionHDTV DVB-T NANO2", | 1986 | { "DViCO FusionHDTV DVB-T NANO2", |
1920 | { NULL }, | 1987 | { NULL }, |
1921 | { &cxusb_table[14], NULL }, | 1988 | { &cxusb_table[DVICO_BLUEBIRD_DVB_T_NANO_2], NULL }, |
1922 | }, | 1989 | }, |
1923 | } | 1990 | } |
1924 | }; | 1991 | }; |
@@ -1972,8 +2039,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_prope | |||
1972 | .num_device_descs = 1, | 2039 | .num_device_descs = 1, |
1973 | .devices = { | 2040 | .devices = { |
1974 | { "DViCO FusionHDTV DVB-T NANO2 w/o firmware", | 2041 | { "DViCO FusionHDTV DVB-T NANO2 w/o firmware", |
1975 | { &cxusb_table[14], NULL }, | 2042 | { &cxusb_table[DVICO_BLUEBIRD_DVB_T_NANO_2], NULL }, |
1976 | { &cxusb_table[15], NULL }, | 2043 | { &cxusb_table[DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM], NULL }, |
1977 | }, | 2044 | }, |
1978 | } | 2045 | } |
1979 | }; | 2046 | }; |
@@ -2017,7 +2084,7 @@ static struct dvb_usb_device_properties cxusb_aver_a868r_properties = { | |||
2017 | .devices = { | 2084 | .devices = { |
2018 | { "AVerMedia AVerTVHD Volar (A868R)", | 2085 | { "AVerMedia AVerTVHD Volar (A868R)", |
2019 | { NULL }, | 2086 | { NULL }, |
2020 | { &cxusb_table[16], NULL }, | 2087 | { &cxusb_table[AVERMEDIA_VOLAR_A868R], NULL }, |
2021 | }, | 2088 | }, |
2022 | } | 2089 | } |
2023 | }; | 2090 | }; |
@@ -2071,7 +2138,7 @@ struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties = { | |||
2071 | .devices = { | 2138 | .devices = { |
2072 | { "DViCO FusionHDTV DVB-T Dual Digital 4 (rev 2)", | 2139 | { "DViCO FusionHDTV DVB-T Dual Digital 4 (rev 2)", |
2073 | { NULL }, | 2140 | { NULL }, |
2074 | { &cxusb_table[17], NULL }, | 2141 | { &cxusb_table[DVICO_BLUEBIRD_DUAL_4_REV_2], NULL }, |
2075 | }, | 2142 | }, |
2076 | } | 2143 | } |
2077 | }; | 2144 | }; |
@@ -2125,7 +2192,7 @@ static struct dvb_usb_device_properties cxusb_d680_dmb_properties = { | |||
2125 | { | 2192 | { |
2126 | "Conexant DMB-TH Stick", | 2193 | "Conexant DMB-TH Stick", |
2127 | { NULL }, | 2194 | { NULL }, |
2128 | { &cxusb_table[18], NULL }, | 2195 | { &cxusb_table[CONEXANT_D680_DMB], NULL }, |
2129 | }, | 2196 | }, |
2130 | } | 2197 | } |
2131 | }; | 2198 | }; |
@@ -2179,7 +2246,7 @@ static struct dvb_usb_device_properties cxusb_mygica_d689_properties = { | |||
2179 | { | 2246 | { |
2180 | "Mygica D689 DMB-TH", | 2247 | "Mygica D689 DMB-TH", |
2181 | { NULL }, | 2248 | { NULL }, |
2182 | { &cxusb_table[19], NULL }, | 2249 | { &cxusb_table[MYGICA_D689], NULL }, |
2183 | }, | 2250 | }, |
2184 | } | 2251 | } |
2185 | }; | 2252 | }; |
@@ -2232,7 +2299,7 @@ static struct dvb_usb_device_properties cxusb_mygica_t230_properties = { | |||
2232 | { | 2299 | { |
2233 | "Mygica T230 DVB-T/T2/C", | 2300 | "Mygica T230 DVB-T/T2/C", |
2234 | { NULL }, | 2301 | { NULL }, |
2235 | { &cxusb_table[20], NULL }, | 2302 | { &cxusb_table[MYGICA_T230], NULL }, |
2236 | }, | 2303 | }, |
2237 | } | 2304 | } |
2238 | }; | 2305 | }; |
diff --git a/drivers/media/usb/dvb-usb/dib0700_core.c b/drivers/media/usb/dvb-usb/dib0700_core.c index 50856dbf5496..2b40393836ff 100644 --- a/drivers/media/usb/dvb-usb/dib0700_core.c +++ b/drivers/media/usb/dvb-usb/dib0700_core.c | |||
@@ -651,9 +651,6 @@ out: | |||
651 | return ret; | 651 | return ret; |
652 | } | 652 | } |
653 | 653 | ||
654 | /* Number of keypresses to ignore before start repeating */ | ||
655 | #define RC_REPEAT_DELAY_V1_20 10 | ||
656 | |||
657 | /* This is the structure of the RC response packet starting in firmware 1.20 */ | 654 | /* This is the structure of the RC response packet starting in firmware 1.20 */ |
658 | struct dib0700_rc_response { | 655 | struct dib0700_rc_response { |
659 | u8 report_id; | 656 | u8 report_id; |
diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c index e1757b8f5f5d..d7d55a20e959 100644 --- a/drivers/media/usb/dvb-usb/dib0700_devices.c +++ b/drivers/media/usb/dvb-usb/dib0700_devices.c | |||
@@ -510,9 +510,6 @@ static int stk7700ph_tuner_attach(struct dvb_usb_adapter *adap) | |||
510 | 510 | ||
511 | static u8 rc_request[] = { REQUEST_POLL_RC, 0 }; | 511 | static u8 rc_request[] = { REQUEST_POLL_RC, 0 }; |
512 | 512 | ||
513 | /* Number of keypresses to ignore before start repeating */ | ||
514 | #define RC_REPEAT_DELAY 6 | ||
515 | |||
516 | /* | 513 | /* |
517 | * This function is used only when firmware is < 1.20 version. Newer | 514 | * This function is used only when firmware is < 1.20 version. Newer |
518 | * firmwares use bulk mode, with functions implemented at dib0700_core, | 515 | * firmwares use bulk mode, with functions implemented at dib0700_core, |
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-dvb.c b/drivers/media/usb/dvb-usb/dvb-usb-dvb.c index 719413b15f20..8a260c854653 100644 --- a/drivers/media/usb/dvb-usb/dvb-usb-dvb.c +++ b/drivers/media/usb/dvb-usb/dvb-usb-dvb.c | |||
@@ -84,14 +84,61 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff) | |||
84 | 84 | ||
85 | static int dvb_usb_start_feed(struct dvb_demux_feed *dvbdmxfeed) | 85 | static int dvb_usb_start_feed(struct dvb_demux_feed *dvbdmxfeed) |
86 | { | 86 | { |
87 | deb_ts("start pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid,dvbdmxfeed->type); | 87 | deb_ts("start pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid, |
88 | return dvb_usb_ctrl_feed(dvbdmxfeed,1); | 88 | dvbdmxfeed->type); |
89 | return dvb_usb_ctrl_feed(dvbdmxfeed, 1); | ||
89 | } | 90 | } |
90 | 91 | ||
91 | static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) | 92 | static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) |
92 | { | 93 | { |
93 | deb_ts("stop pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid, dvbdmxfeed->type); | 94 | deb_ts("stop pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid, dvbdmxfeed->type); |
94 | return dvb_usb_ctrl_feed(dvbdmxfeed,0); | 95 | return dvb_usb_ctrl_feed(dvbdmxfeed, 0); |
96 | } | ||
97 | |||
98 | static void dvb_usb_media_device_register(struct dvb_usb_adapter *adap) | ||
99 | { | ||
100 | #ifdef CONFIG_MEDIA_CONTROLLER_DVB | ||
101 | struct media_device *mdev; | ||
102 | struct dvb_usb_device *d = adap->dev; | ||
103 | struct usb_device *udev = d->udev; | ||
104 | int ret; | ||
105 | |||
106 | mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); | ||
107 | if (!mdev) | ||
108 | return; | ||
109 | |||
110 | mdev->dev = &udev->dev; | ||
111 | strlcpy(mdev->model, d->desc->name, sizeof(mdev->model)); | ||
112 | if (udev->serial) | ||
113 | strlcpy(mdev->serial, udev->serial, sizeof(mdev->serial)); | ||
114 | strcpy(mdev->bus_info, udev->devpath); | ||
115 | mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice); | ||
116 | mdev->driver_version = LINUX_VERSION_CODE; | ||
117 | |||
118 | ret = media_device_register(mdev); | ||
119 | if (ret) { | ||
120 | dev_err(&d->udev->dev, | ||
121 | "Couldn't create a media device. Error: %d\n", | ||
122 | ret); | ||
123 | kfree(mdev); | ||
124 | return; | ||
125 | } | ||
126 | dvb_register_media_controller(&adap->dvb_adap, mdev); | ||
127 | |||
128 | dev_info(&d->udev->dev, "media controller created\n"); | ||
129 | #endif | ||
130 | } | ||
131 | |||
132 | static void dvb_usb_media_device_unregister(struct dvb_usb_adapter *adap) | ||
133 | { | ||
134 | #ifdef CONFIG_MEDIA_CONTROLLER_DVB | ||
135 | if (!adap->dvb_adap.mdev) | ||
136 | return; | ||
137 | |||
138 | media_device_unregister(adap->dvb_adap.mdev); | ||
139 | kfree(adap->dvb_adap.mdev); | ||
140 | adap->dvb_adap.mdev = NULL; | ||
141 | #endif | ||
95 | } | 142 | } |
96 | 143 | ||
97 | int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap, short *adapter_nums) | 144 | int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap, short *adapter_nums) |
@@ -107,9 +154,11 @@ int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap, short *adapter_nums) | |||
107 | } | 154 | } |
108 | adap->dvb_adap.priv = adap; | 155 | adap->dvb_adap.priv = adap; |
109 | 156 | ||
157 | dvb_usb_media_device_register(adap); | ||
158 | |||
110 | if (adap->dev->props.read_mac_address) { | 159 | if (adap->dev->props.read_mac_address) { |
111 | if (adap->dev->props.read_mac_address(adap->dev,adap->dvb_adap.proposed_mac) == 0) | 160 | if (adap->dev->props.read_mac_address(adap->dev, adap->dvb_adap.proposed_mac) == 0) |
112 | info("MAC address: %pM",adap->dvb_adap.proposed_mac); | 161 | info("MAC address: %pM", adap->dvb_adap.proposed_mac); |
113 | else | 162 | else |
114 | err("MAC address reading failed."); | 163 | err("MAC address reading failed."); |
115 | } | 164 | } |
@@ -128,7 +177,7 @@ int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap, short *adapter_nums) | |||
128 | adap->demux.stop_feed = dvb_usb_stop_feed; | 177 | adap->demux.stop_feed = dvb_usb_stop_feed; |
129 | adap->demux.write_to_decoder = NULL; | 178 | adap->demux.write_to_decoder = NULL; |
130 | if ((ret = dvb_dmx_init(&adap->demux)) < 0) { | 179 | if ((ret = dvb_dmx_init(&adap->demux)) < 0) { |
131 | err("dvb_dmx_init failed: error %d",ret); | 180 | err("dvb_dmx_init failed: error %d", ret); |
132 | goto err_dmx; | 181 | goto err_dmx; |
133 | } | 182 | } |
134 | 183 | ||
@@ -136,13 +185,13 @@ int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap, short *adapter_nums) | |||
136 | adap->dmxdev.demux = &adap->demux.dmx; | 185 | adap->dmxdev.demux = &adap->demux.dmx; |
137 | adap->dmxdev.capabilities = 0; | 186 | adap->dmxdev.capabilities = 0; |
138 | if ((ret = dvb_dmxdev_init(&adap->dmxdev, &adap->dvb_adap)) < 0) { | 187 | if ((ret = dvb_dmxdev_init(&adap->dmxdev, &adap->dvb_adap)) < 0) { |
139 | err("dvb_dmxdev_init failed: error %d",ret); | 188 | err("dvb_dmxdev_init failed: error %d", ret); |
140 | goto err_dmx_dev; | 189 | goto err_dmx_dev; |
141 | } | 190 | } |
142 | 191 | ||
143 | if ((ret = dvb_net_init(&adap->dvb_adap, &adap->dvb_net, | 192 | if ((ret = dvb_net_init(&adap->dvb_adap, &adap->dvb_net, |
144 | &adap->demux.dmx)) < 0) { | 193 | &adap->demux.dmx)) < 0) { |
145 | err("dvb_net_init failed: error %d",ret); | 194 | err("dvb_net_init failed: error %d", ret); |
146 | goto err_net_init; | 195 | goto err_net_init; |
147 | } | 196 | } |
148 | 197 | ||
@@ -154,6 +203,7 @@ err_net_init: | |||
154 | err_dmx_dev: | 203 | err_dmx_dev: |
155 | dvb_dmx_release(&adap->demux); | 204 | dvb_dmx_release(&adap->demux); |
156 | err_dmx: | 205 | err_dmx: |
206 | dvb_usb_media_device_unregister(adap); | ||
157 | dvb_unregister_adapter(&adap->dvb_adap); | 207 | dvb_unregister_adapter(&adap->dvb_adap); |
158 | err: | 208 | err: |
159 | return ret; | 209 | return ret; |
@@ -167,6 +217,7 @@ int dvb_usb_adapter_dvb_exit(struct dvb_usb_adapter *adap) | |||
167 | adap->demux.dmx.close(&adap->demux.dmx); | 217 | adap->demux.dmx.close(&adap->demux.dmx); |
168 | dvb_dmxdev_release(&adap->dmxdev); | 218 | dvb_dmxdev_release(&adap->dmxdev); |
169 | dvb_dmx_release(&adap->demux); | 219 | dvb_dmx_release(&adap->demux); |
220 | dvb_usb_media_device_unregister(adap); | ||
170 | dvb_unregister_adapter(&adap->dvb_adap); | 221 | dvb_unregister_adapter(&adap->dvb_adap); |
171 | adap->state &= ~DVB_USB_ADAP_STATE_DVB; | 222 | adap->state &= ~DVB_USB_ADAP_STATE_DVB; |
172 | } | 223 | } |
@@ -268,6 +319,8 @@ int dvb_usb_adapter_frontend_init(struct dvb_usb_adapter *adap) | |||
268 | adap->num_frontends_initialized++; | 319 | adap->num_frontends_initialized++; |
269 | } | 320 | } |
270 | 321 | ||
322 | dvb_create_media_graph(&adap->dvb_adap); | ||
323 | |||
271 | return 0; | 324 | return 0; |
272 | } | 325 | } |
273 | 326 | ||
diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c index 1a3df10d6bad..f1f357f43ff0 100644 --- a/drivers/media/usb/dvb-usb/dw2102.c +++ b/drivers/media/usb/dvb-usb/dw2102.c | |||
@@ -2,7 +2,8 @@ | |||
2 | * DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101, | 2 | * DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101, |
3 | * TeVii S600, S630, S650, S660, S480, S421, S632 | 3 | * TeVii S600, S630, S650, S660, S480, S421, S632 |
4 | * Prof 1100, 7500, | 4 | * Prof 1100, 7500, |
5 | * Geniatech SU3000, T220 Cards | 5 | * Geniatech SU3000, T220, |
6 | * TechnoTrend S2-4600 Cards | ||
6 | * Copyright (C) 2008-2012 Igor M. Liplianin (liplianin@me.by) | 7 | * Copyright (C) 2008-2012 Igor M. Liplianin (liplianin@me.by) |
7 | * | 8 | * |
8 | * This program is free software; you can redistribute it and/or modify it | 9 | * This program is free software; you can redistribute it and/or modify it |
@@ -31,6 +32,8 @@ | |||
31 | #include "m88rs2000.h" | 32 | #include "m88rs2000.h" |
32 | #include "tda18271.h" | 33 | #include "tda18271.h" |
33 | #include "cxd2820r.h" | 34 | #include "cxd2820r.h" |
35 | #include "m88ds3103.h" | ||
36 | #include "ts2020.h" | ||
34 | 37 | ||
35 | /* Max transfer size done by I2C transfer functions */ | 38 | /* Max transfer size done by I2C transfer functions */ |
36 | #define MAX_XFER_SIZE 64 | 39 | #define MAX_XFER_SIZE 64 |
@@ -112,11 +115,9 @@ | |||
112 | "Please see linux/Documentation/dvb/ for more details " \ | 115 | "Please see linux/Documentation/dvb/ for more details " \ |
113 | "on firmware-problems." | 116 | "on firmware-problems." |
114 | 117 | ||
115 | struct su3000_state { | 118 | struct dw2102_state { |
116 | u8 initialized; | 119 | u8 initialized; |
117 | }; | 120 | struct i2c_client *i2c_client_tuner; |
118 | |||
119 | struct s6x0_state { | ||
120 | int (*old_set_voltage)(struct dvb_frontend *f, fe_sec_voltage_t v); | 121 | int (*old_set_voltage)(struct dvb_frontend *f, fe_sec_voltage_t v); |
121 | }; | 122 | }; |
122 | 123 | ||
@@ -887,7 +888,7 @@ static int su3000_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) | |||
887 | 888 | ||
888 | static int su3000_power_ctrl(struct dvb_usb_device *d, int i) | 889 | static int su3000_power_ctrl(struct dvb_usb_device *d, int i) |
889 | { | 890 | { |
890 | struct su3000_state *state = (struct su3000_state *)d->priv; | 891 | struct dw2102_state *state = (struct dw2102_state *)d->priv; |
891 | u8 obuf[] = {0xde, 0}; | 892 | u8 obuf[] = {0xde, 0}; |
892 | 893 | ||
893 | info("%s: %d, initialized %d\n", __func__, i, state->initialized); | 894 | info("%s: %d, initialized %d\n", __func__, i, state->initialized); |
@@ -973,7 +974,7 @@ static int s660_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | |||
973 | { | 974 | { |
974 | struct dvb_usb_adapter *d = | 975 | struct dvb_usb_adapter *d = |
975 | (struct dvb_usb_adapter *)(fe->dvb->priv); | 976 | (struct dvb_usb_adapter *)(fe->dvb->priv); |
976 | struct s6x0_state *st = (struct s6x0_state *)d->dev->priv; | 977 | struct dw2102_state *st = (struct dw2102_state *)d->dev->priv; |
977 | 978 | ||
978 | dw210x_set_voltage(fe, voltage); | 979 | dw210x_set_voltage(fe, voltage); |
979 | if (st->old_set_voltage) | 980 | if (st->old_set_voltage) |
@@ -1117,6 +1118,22 @@ static struct tda18271_config tda18271_config = { | |||
1117 | .gate = TDA18271_GATE_DIGITAL, | 1118 | .gate = TDA18271_GATE_DIGITAL, |
1118 | }; | 1119 | }; |
1119 | 1120 | ||
1121 | static const struct m88ds3103_config tt_s2_4600_m88ds3103_config = { | ||
1122 | .i2c_addr = 0x68, | ||
1123 | .clock = 27000000, | ||
1124 | .i2c_wr_max = 33, | ||
1125 | .ts_mode = M88DS3103_TS_CI, | ||
1126 | .ts_clk = 16000, | ||
1127 | .ts_clk_pol = 0, | ||
1128 | .spec_inv = 0, | ||
1129 | .agc_inv = 0, | ||
1130 | .clock_out = M88DS3103_CLOCK_OUT_ENABLED, | ||
1131 | .envelope_mode = 0, | ||
1132 | .agc = 0x99, | ||
1133 | .lnb_hv_pol = 1, | ||
1134 | .lnb_en_pol = 0, | ||
1135 | }; | ||
1136 | |||
1120 | static u8 m88rs2000_inittab[] = { | 1137 | static u8 m88rs2000_inittab[] = { |
1121 | DEMOD_WRITE, 0x9a, 0x30, | 1138 | DEMOD_WRITE, 0x9a, 0x30, |
1122 | DEMOD_WRITE, 0x00, 0x01, | 1139 | DEMOD_WRITE, 0x00, 0x01, |
@@ -1295,7 +1312,7 @@ static int stv0288_frontend_attach(struct dvb_usb_adapter *d) | |||
1295 | 1312 | ||
1296 | static int ds3000_frontend_attach(struct dvb_usb_adapter *d) | 1313 | static int ds3000_frontend_attach(struct dvb_usb_adapter *d) |
1297 | { | 1314 | { |
1298 | struct s6x0_state *st = (struct s6x0_state *)d->dev->priv; | 1315 | struct dw2102_state *st = d->dev->priv; |
1299 | u8 obuf[] = {7, 1}; | 1316 | u8 obuf[] = {7, 1}; |
1300 | 1317 | ||
1301 | d->fe_adap[0].fe = dvb_attach(ds3000_attach, &s660_ds3000_config, | 1318 | d->fe_adap[0].fe = dvb_attach(ds3000_attach, &s660_ds3000_config, |
@@ -1461,6 +1478,84 @@ static int m88rs2000_frontend_attach(struct dvb_usb_adapter *d) | |||
1461 | return -EIO; | 1478 | return -EIO; |
1462 | } | 1479 | } |
1463 | 1480 | ||
1481 | static int tt_s2_4600_frontend_attach(struct dvb_usb_adapter *adap) | ||
1482 | { | ||
1483 | struct dvb_usb_device *d = adap->dev; | ||
1484 | struct dw2102_state *state = d->priv; | ||
1485 | u8 obuf[3] = { 0xe, 0x80, 0 }; | ||
1486 | u8 ibuf[] = { 0 }; | ||
1487 | struct i2c_adapter *i2c_adapter; | ||
1488 | struct i2c_client *client; | ||
1489 | struct i2c_board_info info; | ||
1490 | struct ts2020_config ts2020_config = {}; | ||
1491 | |||
1492 | if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 1, 0) < 0) | ||
1493 | err("command 0x0e transfer failed."); | ||
1494 | |||
1495 | obuf[0] = 0xe; | ||
1496 | obuf[1] = 0x02; | ||
1497 | obuf[2] = 1; | ||
1498 | |||
1499 | if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 1, 0) < 0) | ||
1500 | err("command 0x0e transfer failed."); | ||
1501 | msleep(300); | ||
1502 | |||
1503 | obuf[0] = 0xe; | ||
1504 | obuf[1] = 0x83; | ||
1505 | obuf[2] = 0; | ||
1506 | |||
1507 | if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 1, 0) < 0) | ||
1508 | err("command 0x0e transfer failed."); | ||
1509 | |||
1510 | obuf[0] = 0xe; | ||
1511 | obuf[1] = 0x83; | ||
1512 | obuf[2] = 1; | ||
1513 | |||
1514 | if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 1, 0) < 0) | ||
1515 | err("command 0x0e transfer failed."); | ||
1516 | |||
1517 | obuf[0] = 0x51; | ||
1518 | |||
1519 | if (dvb_usb_generic_rw(d, obuf, 1, ibuf, 1, 0) < 0) | ||
1520 | err("command 0x51 transfer failed."); | ||
1521 | |||
1522 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
1523 | |||
1524 | adap->fe_adap[0].fe = dvb_attach(m88ds3103_attach, | ||
1525 | &tt_s2_4600_m88ds3103_config, | ||
1526 | &d->i2c_adap, | ||
1527 | &i2c_adapter); | ||
1528 | if (adap->fe_adap[0].fe == NULL) | ||
1529 | return -ENODEV; | ||
1530 | |||
1531 | /* attach tuner */ | ||
1532 | ts2020_config.fe = adap->fe_adap[0].fe; | ||
1533 | strlcpy(info.type, "ts2022", I2C_NAME_SIZE); | ||
1534 | info.addr = 0x60; | ||
1535 | info.platform_data = &ts2020_config; | ||
1536 | request_module("ts2020"); | ||
1537 | client = i2c_new_device(i2c_adapter, &info); | ||
1538 | |||
1539 | if (client == NULL || client->dev.driver == NULL) { | ||
1540 | dvb_frontend_detach(adap->fe_adap[0].fe); | ||
1541 | return -ENODEV; | ||
1542 | } | ||
1543 | |||
1544 | if (!try_module_get(client->dev.driver->owner)) { | ||
1545 | i2c_unregister_device(client); | ||
1546 | dvb_frontend_detach(adap->fe_adap[0].fe); | ||
1547 | return -ENODEV; | ||
1548 | } | ||
1549 | |||
1550 | /* delegate signal strength measurement to tuner */ | ||
1551 | adap->fe_adap[0].fe->ops.read_signal_strength = | ||
1552 | adap->fe_adap[0].fe->ops.tuner_ops.get_rf_strength; | ||
1553 | |||
1554 | state->i2c_client_tuner = client; | ||
1555 | |||
1556 | return 0; | ||
1557 | } | ||
1558 | |||
1464 | static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) | 1559 | static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) |
1465 | { | 1560 | { |
1466 | dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60, | 1561 | dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60, |
@@ -1561,6 +1656,7 @@ enum dw2102_table_entry { | |||
1561 | TERRATEC_CINERGY_S2_R2, | 1656 | TERRATEC_CINERGY_S2_R2, |
1562 | GOTVIEW_SAT_HD, | 1657 | GOTVIEW_SAT_HD, |
1563 | GENIATECH_T220, | 1658 | GENIATECH_T220, |
1659 | TECHNOTREND_S2_4600, | ||
1564 | }; | 1660 | }; |
1565 | 1661 | ||
1566 | static struct usb_device_id dw2102_table[] = { | 1662 | static struct usb_device_id dw2102_table[] = { |
@@ -1584,6 +1680,8 @@ static struct usb_device_id dw2102_table[] = { | |||
1584 | [TERRATEC_CINERGY_S2_R2] = {USB_DEVICE(USB_VID_TERRATEC, 0x00b0)}, | 1680 | [TERRATEC_CINERGY_S2_R2] = {USB_DEVICE(USB_VID_TERRATEC, 0x00b0)}, |
1585 | [GOTVIEW_SAT_HD] = {USB_DEVICE(0x1FE1, USB_PID_GOTVIEW_SAT_HD)}, | 1681 | [GOTVIEW_SAT_HD] = {USB_DEVICE(0x1FE1, USB_PID_GOTVIEW_SAT_HD)}, |
1586 | [GENIATECH_T220] = {USB_DEVICE(0x1f4d, 0xD220)}, | 1682 | [GENIATECH_T220] = {USB_DEVICE(0x1f4d, 0xD220)}, |
1683 | [TECHNOTREND_S2_4600] = {USB_DEVICE(USB_VID_TECHNOTREND, | ||
1684 | USB_PID_TECHNOTREND_CONNECT_S2_4600)}, | ||
1587 | { } | 1685 | { } |
1588 | }; | 1686 | }; |
1589 | 1687 | ||
@@ -1857,7 +1955,7 @@ static struct dvb_usb_device_properties dw3101_properties = { | |||
1857 | static struct dvb_usb_device_properties s6x0_properties = { | 1955 | static struct dvb_usb_device_properties s6x0_properties = { |
1858 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | 1956 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
1859 | .usb_ctrl = DEVICE_SPECIFIC, | 1957 | .usb_ctrl = DEVICE_SPECIFIC, |
1860 | .size_of_priv = sizeof(struct s6x0_state), | 1958 | .size_of_priv = sizeof(struct dw2102_state), |
1861 | .firmware = S630_FIRMWARE, | 1959 | .firmware = S630_FIRMWARE, |
1862 | .no_reconnect = 1, | 1960 | .no_reconnect = 1, |
1863 | 1961 | ||
@@ -1950,7 +2048,7 @@ static struct dvb_usb_device_description d632 = { | |||
1950 | static struct dvb_usb_device_properties su3000_properties = { | 2048 | static struct dvb_usb_device_properties su3000_properties = { |
1951 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | 2049 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
1952 | .usb_ctrl = DEVICE_SPECIFIC, | 2050 | .usb_ctrl = DEVICE_SPECIFIC, |
1953 | .size_of_priv = sizeof(struct su3000_state), | 2051 | .size_of_priv = sizeof(struct dw2102_state), |
1954 | .power_ctrl = su3000_power_ctrl, | 2052 | .power_ctrl = su3000_power_ctrl, |
1955 | .num_adapters = 1, | 2053 | .num_adapters = 1, |
1956 | .identify_state = su3000_identify_state, | 2054 | .identify_state = su3000_identify_state, |
@@ -2015,7 +2113,7 @@ static struct dvb_usb_device_properties su3000_properties = { | |||
2015 | static struct dvb_usb_device_properties t220_properties = { | 2113 | static struct dvb_usb_device_properties t220_properties = { |
2016 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | 2114 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
2017 | .usb_ctrl = DEVICE_SPECIFIC, | 2115 | .usb_ctrl = DEVICE_SPECIFIC, |
2018 | .size_of_priv = sizeof(struct su3000_state), | 2116 | .size_of_priv = sizeof(struct dw2102_state), |
2019 | .power_ctrl = su3000_power_ctrl, | 2117 | .power_ctrl = su3000_power_ctrl, |
2020 | .num_adapters = 1, | 2118 | .num_adapters = 1, |
2021 | .identify_state = su3000_identify_state, | 2119 | .identify_state = su3000_identify_state, |
@@ -2061,6 +2159,55 @@ static struct dvb_usb_device_properties t220_properties = { | |||
2061 | } | 2159 | } |
2062 | }; | 2160 | }; |
2063 | 2161 | ||
2162 | static struct dvb_usb_device_properties tt_s2_4600_properties = { | ||
2163 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | ||
2164 | .usb_ctrl = DEVICE_SPECIFIC, | ||
2165 | .size_of_priv = sizeof(struct dw2102_state), | ||
2166 | .power_ctrl = su3000_power_ctrl, | ||
2167 | .num_adapters = 1, | ||
2168 | .identify_state = su3000_identify_state, | ||
2169 | .i2c_algo = &su3000_i2c_algo, | ||
2170 | |||
2171 | .rc.core = { | ||
2172 | .rc_interval = 250, | ||
2173 | .rc_codes = RC_MAP_TT_1500, | ||
2174 | .module_name = "dw2102", | ||
2175 | .allowed_protos = RC_BIT_RC5, | ||
2176 | .rc_query = su3000_rc_query, | ||
2177 | }, | ||
2178 | |||
2179 | .read_mac_address = su3000_read_mac_address, | ||
2180 | |||
2181 | .generic_bulk_ctrl_endpoint = 0x01, | ||
2182 | |||
2183 | .adapter = { | ||
2184 | { | ||
2185 | .num_frontends = 1, | ||
2186 | .fe = {{ | ||
2187 | .streaming_ctrl = su3000_streaming_ctrl, | ||
2188 | .frontend_attach = tt_s2_4600_frontend_attach, | ||
2189 | .stream = { | ||
2190 | .type = USB_BULK, | ||
2191 | .count = 8, | ||
2192 | .endpoint = 0x82, | ||
2193 | .u = { | ||
2194 | .bulk = { | ||
2195 | .buffersize = 4096, | ||
2196 | } | ||
2197 | } | ||
2198 | } | ||
2199 | } }, | ||
2200 | } | ||
2201 | }, | ||
2202 | .num_device_descs = 1, | ||
2203 | .devices = { | ||
2204 | { "TechnoTrend TT-connect S2-4600", | ||
2205 | { &dw2102_table[TECHNOTREND_S2_4600], NULL }, | ||
2206 | { NULL }, | ||
2207 | }, | ||
2208 | } | ||
2209 | }; | ||
2210 | |||
2064 | static int dw2102_probe(struct usb_interface *intf, | 2211 | static int dw2102_probe(struct usb_interface *intf, |
2065 | const struct usb_device_id *id) | 2212 | const struct usb_device_id *id) |
2066 | { | 2213 | { |
@@ -2135,16 +2282,34 @@ static int dw2102_probe(struct usb_interface *intf, | |||
2135 | 0 == dvb_usb_device_init(intf, &su3000_properties, | 2282 | 0 == dvb_usb_device_init(intf, &su3000_properties, |
2136 | THIS_MODULE, NULL, adapter_nr) || | 2283 | THIS_MODULE, NULL, adapter_nr) || |
2137 | 0 == dvb_usb_device_init(intf, &t220_properties, | 2284 | 0 == dvb_usb_device_init(intf, &t220_properties, |
2285 | THIS_MODULE, NULL, adapter_nr) || | ||
2286 | 0 == dvb_usb_device_init(intf, &tt_s2_4600_properties, | ||
2138 | THIS_MODULE, NULL, adapter_nr)) | 2287 | THIS_MODULE, NULL, adapter_nr)) |
2139 | return 0; | 2288 | return 0; |
2140 | 2289 | ||
2141 | return -ENODEV; | 2290 | return -ENODEV; |
2142 | } | 2291 | } |
2143 | 2292 | ||
2293 | static void dw2102_disconnect(struct usb_interface *intf) | ||
2294 | { | ||
2295 | struct dvb_usb_device *d = usb_get_intfdata(intf); | ||
2296 | struct dw2102_state *st = (struct dw2102_state *)d->priv; | ||
2297 | struct i2c_client *client; | ||
2298 | |||
2299 | /* remove I2C client for tuner */ | ||
2300 | client = st->i2c_client_tuner; | ||
2301 | if (client) { | ||
2302 | module_put(client->dev.driver->owner); | ||
2303 | i2c_unregister_device(client); | ||
2304 | } | ||
2305 | |||
2306 | dvb_usb_device_exit(intf); | ||
2307 | } | ||
2308 | |||
2144 | static struct usb_driver dw2102_driver = { | 2309 | static struct usb_driver dw2102_driver = { |
2145 | .name = "dw2102", | 2310 | .name = "dw2102", |
2146 | .probe = dw2102_probe, | 2311 | .probe = dw2102_probe, |
2147 | .disconnect = dvb_usb_device_exit, | 2312 | .disconnect = dw2102_disconnect, |
2148 | .id_table = dw2102_table, | 2313 | .id_table = dw2102_table, |
2149 | }; | 2314 | }; |
2150 | 2315 | ||
@@ -2155,7 +2320,8 @@ MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104," | |||
2155 | " DVB-C 3101 USB2.0," | 2320 | " DVB-C 3101 USB2.0," |
2156 | " TeVii S600, S630, S650, S660, S480, S421, S632" | 2321 | " TeVii S600, S630, S650, S660, S480, S421, S632" |
2157 | " Prof 1100, 7500 USB2.0," | 2322 | " Prof 1100, 7500 USB2.0," |
2158 | " Geniatech SU3000, T220 devices"); | 2323 | " Geniatech SU3000, T220," |
2324 | " TechnoTrend S2-4600 devices"); | ||
2159 | MODULE_VERSION("0.1"); | 2325 | MODULE_VERSION("0.1"); |
2160 | MODULE_LICENSE("GPL"); | 2326 | MODULE_LICENSE("GPL"); |
2161 | MODULE_FIRMWARE(DW2101_FIRMWARE); | 2327 | MODULE_FIRMWARE(DW2101_FIRMWARE); |
diff --git a/drivers/media/usb/em28xx/Kconfig b/drivers/media/usb/em28xx/Kconfig index f5d7198753c7..e382210c4ada 100644 --- a/drivers/media/usb/em28xx/Kconfig +++ b/drivers/media/usb/em28xx/Kconfig | |||
@@ -55,7 +55,7 @@ config VIDEO_EM28XX_DVB | |||
55 | select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT | 55 | select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT |
56 | select MEDIA_TUNER_TDA18212 if MEDIA_SUBDRV_AUTOSELECT | 56 | select MEDIA_TUNER_TDA18212 if MEDIA_SUBDRV_AUTOSELECT |
57 | select DVB_M88DS3103 if MEDIA_SUBDRV_AUTOSELECT | 57 | select DVB_M88DS3103 if MEDIA_SUBDRV_AUTOSELECT |
58 | select MEDIA_TUNER_M88TS2022 if MEDIA_SUBDRV_AUTOSELECT | 58 | select DVB_TS2020 if MEDIA_SUBDRV_AUTOSELECT |
59 | select DVB_DRX39XYJ if MEDIA_SUBDRV_AUTOSELECT | 59 | select DVB_DRX39XYJ if MEDIA_SUBDRV_AUTOSELECT |
60 | select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT | 60 | select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT |
61 | select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT | 61 | select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT |
diff --git a/drivers/media/usb/em28xx/em28xx-camera.c b/drivers/media/usb/em28xx/em28xx-camera.c index 7be661f73930..a4b22c2c3ba7 100644 --- a/drivers/media/usb/em28xx/em28xx-camera.c +++ b/drivers/media/usb/em28xx/em28xx-camera.c | |||
@@ -330,7 +330,7 @@ int em28xx_init_camera(struct em28xx *dev) | |||
330 | 330 | ||
331 | v4l2_clk_name_i2c(clk_name, sizeof(clk_name), | 331 | v4l2_clk_name_i2c(clk_name, sizeof(clk_name), |
332 | i2c_adapter_id(adap), client->addr); | 332 | i2c_adapter_id(adap), client->addr); |
333 | v4l2->clk = v4l2_clk_register_fixed(clk_name, "mclk", -EINVAL); | 333 | v4l2->clk = v4l2_clk_register_fixed(clk_name, -EINVAL); |
334 | if (IS_ERR(v4l2->clk)) | 334 | if (IS_ERR(v4l2->clk)) |
335 | return PTR_ERR(v4l2->clk); | 335 | return PTR_ERR(v4l2->clk); |
336 | 336 | ||
diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index d9704e66b8c9..394004607059 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c | |||
@@ -1157,6 +1157,15 @@ struct em28xx_board em28xx_boards[] = { | |||
1157 | .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | | 1157 | .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | |
1158 | EM28XX_I2C_FREQ_400_KHZ, | 1158 | EM28XX_I2C_FREQ_400_KHZ, |
1159 | }, | 1159 | }, |
1160 | [EM2884_BOARD_ELGATO_EYETV_HYBRID_2008] = { | ||
1161 | .name = "Elgato EyeTV Hybrid 2008 INT", | ||
1162 | .has_dvb = 1, | ||
1163 | .ir_codes = RC_MAP_NEC_TERRATEC_CINERGY_XS, | ||
1164 | .tuner_type = TUNER_ABSENT, | ||
1165 | .def_i2c_bus = 1, | ||
1166 | .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | | ||
1167 | EM28XX_I2C_FREQ_400_KHZ, | ||
1168 | }, | ||
1160 | [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900] = { | 1169 | [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900] = { |
1161 | .name = "Hauppauge WinTV HVR 900", | 1170 | .name = "Hauppauge WinTV HVR 900", |
1162 | .tda9887_conf = TDA9887_PRESENT, | 1171 | .tda9887_conf = TDA9887_PRESENT, |
@@ -2378,8 +2387,10 @@ struct usb_device_id em28xx_id_table[] = { | |||
2378 | .driver_info = EM2860_BOARD_TERRATEC_GRABBY }, | 2387 | .driver_info = EM2860_BOARD_TERRATEC_GRABBY }, |
2379 | { USB_DEVICE(0x0ccd, 0x00b2), | 2388 | { USB_DEVICE(0x0ccd, 0x00b2), |
2380 | .driver_info = EM2884_BOARD_CINERGY_HTC_STICK }, | 2389 | .driver_info = EM2884_BOARD_CINERGY_HTC_STICK }, |
2390 | { USB_DEVICE(0x0fd9, 0x0018), | ||
2391 | .driver_info = EM2884_BOARD_ELGATO_EYETV_HYBRID_2008 }, | ||
2381 | { USB_DEVICE(0x0fd9, 0x0033), | 2392 | { USB_DEVICE(0x0fd9, 0x0033), |
2382 | .driver_info = EM2860_BOARD_ELGATO_VIDEO_CAPTURE}, | 2393 | .driver_info = EM2860_BOARD_ELGATO_VIDEO_CAPTURE }, |
2383 | { USB_DEVICE(0x185b, 0x2870), | 2394 | { USB_DEVICE(0x185b, 0x2870), |
2384 | .driver_info = EM2870_BOARD_COMPRO_VIDEOMATE }, | 2395 | .driver_info = EM2870_BOARD_COMPRO_VIDEOMATE }, |
2385 | { USB_DEVICE(0x185b, 0x2041), | 2396 | { USB_DEVICE(0x185b, 0x2041), |
diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c index aee70d483264..a5b22c5a240c 100644 --- a/drivers/media/usb/em28xx/em28xx-dvb.c +++ b/drivers/media/usb/em28xx/em28xx-dvb.c | |||
@@ -54,7 +54,7 @@ | |||
54 | #include "qt1010.h" | 54 | #include "qt1010.h" |
55 | #include "mb86a20s.h" | 55 | #include "mb86a20s.h" |
56 | #include "m88ds3103.h" | 56 | #include "m88ds3103.h" |
57 | #include "m88ts2022.h" | 57 | #include "ts2020.h" |
58 | #include "si2168.h" | 58 | #include "si2168.h" |
59 | #include "si2157.h" | 59 | #include "si2157.h" |
60 | 60 | ||
@@ -1380,6 +1380,7 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
1380 | } | 1380 | } |
1381 | } | 1381 | } |
1382 | break; | 1382 | break; |
1383 | case EM2884_BOARD_ELGATO_EYETV_HYBRID_2008: | ||
1383 | case EM2884_BOARD_CINERGY_HTC_STICK: | 1384 | case EM2884_BOARD_CINERGY_HTC_STICK: |
1384 | terratec_htc_stick_init(dev); | 1385 | terratec_htc_stick_init(dev); |
1385 | 1386 | ||
@@ -1491,8 +1492,7 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
1491 | struct i2c_adapter *i2c_adapter; | 1492 | struct i2c_adapter *i2c_adapter; |
1492 | struct i2c_client *client; | 1493 | struct i2c_client *client; |
1493 | struct i2c_board_info info; | 1494 | struct i2c_board_info info; |
1494 | struct m88ts2022_config m88ts2022_config = { | 1495 | struct ts2020_config ts2020_config = { |
1495 | .clock = 27000000, | ||
1496 | }; | 1496 | }; |
1497 | memset(&info, 0, sizeof(struct i2c_board_info)); | 1497 | memset(&info, 0, sizeof(struct i2c_board_info)); |
1498 | 1498 | ||
@@ -1507,11 +1507,11 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
1507 | } | 1507 | } |
1508 | 1508 | ||
1509 | /* attach tuner */ | 1509 | /* attach tuner */ |
1510 | m88ts2022_config.fe = dvb->fe[0]; | 1510 | ts2020_config.fe = dvb->fe[0]; |
1511 | strlcpy(info.type, "m88ts2022", I2C_NAME_SIZE); | 1511 | strlcpy(info.type, "ts2022", I2C_NAME_SIZE); |
1512 | info.addr = 0x60; | 1512 | info.addr = 0x60; |
1513 | info.platform_data = &m88ts2022_config; | 1513 | info.platform_data = &ts2020_config; |
1514 | request_module("m88ts2022"); | 1514 | request_module("ts2020"); |
1515 | client = i2c_new_device(i2c_adapter, &info); | 1515 | client = i2c_new_device(i2c_adapter, &info); |
1516 | if (client == NULL || client->dev.driver == NULL) { | 1516 | if (client == NULL || client->dev.driver == NULL) { |
1517 | dvb_frontend_detach(dvb->fe[0]); | 1517 | dvb_frontend_detach(dvb->fe[0]); |
diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 9ecf65629b3d..14eba9c65de3 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c | |||
@@ -1472,7 +1472,7 @@ static int vidioc_enum_input(struct file *file, void *priv, | |||
1472 | (EM28XX_VMUX_CABLE == INPUT(n)->type)) | 1472 | (EM28XX_VMUX_CABLE == INPUT(n)->type)) |
1473 | i->type = V4L2_INPUT_TYPE_TUNER; | 1473 | i->type = V4L2_INPUT_TYPE_TUNER; |
1474 | 1474 | ||
1475 | i->std = dev->v4l2->vdev->tvnorms; | 1475 | i->std = dev->v4l2->vdev.tvnorms; |
1476 | /* webcams do not have the STD API */ | 1476 | /* webcams do not have the STD API */ |
1477 | if (dev->board.is_webcam) | 1477 | if (dev->board.is_webcam) |
1478 | i->capabilities = 0; | 1478 | i->capabilities = 0; |
@@ -1730,9 +1730,9 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
1730 | 1730 | ||
1731 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS | | 1731 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS | |
1732 | V4L2_CAP_READWRITE | V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; | 1732 | V4L2_CAP_READWRITE | V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; |
1733 | if (v4l2->vbi_dev) | 1733 | if (video_is_registered(&v4l2->vbi_dev)) |
1734 | cap->capabilities |= V4L2_CAP_VBI_CAPTURE; | 1734 | cap->capabilities |= V4L2_CAP_VBI_CAPTURE; |
1735 | if (v4l2->radio_dev) | 1735 | if (video_is_registered(&v4l2->radio_dev)) |
1736 | cap->capabilities |= V4L2_CAP_RADIO; | 1736 | cap->capabilities |= V4L2_CAP_RADIO; |
1737 | return 0; | 1737 | return 0; |
1738 | } | 1738 | } |
@@ -1966,20 +1966,20 @@ static int em28xx_v4l2_fini(struct em28xx *dev) | |||
1966 | 1966 | ||
1967 | em28xx_uninit_usb_xfer(dev, EM28XX_ANALOG_MODE); | 1967 | em28xx_uninit_usb_xfer(dev, EM28XX_ANALOG_MODE); |
1968 | 1968 | ||
1969 | if (v4l2->radio_dev) { | 1969 | if (video_is_registered(&v4l2->radio_dev)) { |
1970 | em28xx_info("V4L2 device %s deregistered\n", | 1970 | em28xx_info("V4L2 device %s deregistered\n", |
1971 | video_device_node_name(v4l2->radio_dev)); | 1971 | video_device_node_name(&v4l2->radio_dev)); |
1972 | video_unregister_device(v4l2->radio_dev); | 1972 | video_unregister_device(&v4l2->radio_dev); |
1973 | } | 1973 | } |
1974 | if (v4l2->vbi_dev) { | 1974 | if (video_is_registered(&v4l2->vbi_dev)) { |
1975 | em28xx_info("V4L2 device %s deregistered\n", | 1975 | em28xx_info("V4L2 device %s deregistered\n", |
1976 | video_device_node_name(v4l2->vbi_dev)); | 1976 | video_device_node_name(&v4l2->vbi_dev)); |
1977 | video_unregister_device(v4l2->vbi_dev); | 1977 | video_unregister_device(&v4l2->vbi_dev); |
1978 | } | 1978 | } |
1979 | if (v4l2->vdev) { | 1979 | if (video_is_registered(&v4l2->vdev)) { |
1980 | em28xx_info("V4L2 device %s deregistered\n", | 1980 | em28xx_info("V4L2 device %s deregistered\n", |
1981 | video_device_node_name(v4l2->vdev)); | 1981 | video_device_node_name(&v4l2->vdev)); |
1982 | video_unregister_device(v4l2->vdev); | 1982 | video_unregister_device(&v4l2->vdev); |
1983 | } | 1983 | } |
1984 | 1984 | ||
1985 | v4l2_ctrl_handler_free(&v4l2->ctrl_handler); | 1985 | v4l2_ctrl_handler_free(&v4l2->ctrl_handler); |
@@ -2127,7 +2127,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
2127 | static const struct video_device em28xx_video_template = { | 2127 | static const struct video_device em28xx_video_template = { |
2128 | .fops = &em28xx_v4l_fops, | 2128 | .fops = &em28xx_v4l_fops, |
2129 | .ioctl_ops = &video_ioctl_ops, | 2129 | .ioctl_ops = &video_ioctl_ops, |
2130 | .release = video_device_release, | 2130 | .release = video_device_release_empty, |
2131 | .tvnorms = V4L2_STD_ALL, | 2131 | .tvnorms = V4L2_STD_ALL, |
2132 | }; | 2132 | }; |
2133 | 2133 | ||
@@ -2156,7 +2156,7 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = { | |||
2156 | static struct video_device em28xx_radio_template = { | 2156 | static struct video_device em28xx_radio_template = { |
2157 | .fops = &radio_fops, | 2157 | .fops = &radio_fops, |
2158 | .ioctl_ops = &radio_ioctl_ops, | 2158 | .ioctl_ops = &radio_ioctl_ops, |
2159 | .release = video_device_release, | 2159 | .release = video_device_release_empty, |
2160 | }; | 2160 | }; |
2161 | 2161 | ||
2162 | /* I2C possible address to saa7115, tvp5150, msp3400, tvaudio */ | 2162 | /* I2C possible address to saa7115, tvp5150, msp3400, tvaudio */ |
@@ -2179,17 +2179,11 @@ static unsigned short msp3400_addrs[] = { | |||
2179 | 2179 | ||
2180 | /******************************** usb interface ******************************/ | 2180 | /******************************** usb interface ******************************/ |
2181 | 2181 | ||
2182 | static struct video_device | 2182 | static void em28xx_vdev_init(struct em28xx *dev, |
2183 | *em28xx_vdev_init(struct em28xx *dev, | 2183 | struct video_device *vfd, |
2184 | const struct video_device *template, | 2184 | const struct video_device *template, |
2185 | const char *type_name) | 2185 | const char *type_name) |
2186 | { | 2186 | { |
2187 | struct video_device *vfd; | ||
2188 | |||
2189 | vfd = video_device_alloc(); | ||
2190 | if (NULL == vfd) | ||
2191 | return NULL; | ||
2192 | |||
2193 | *vfd = *template; | 2187 | *vfd = *template; |
2194 | vfd->v4l2_dev = &dev->v4l2->v4l2_dev; | 2188 | vfd->v4l2_dev = &dev->v4l2->v4l2_dev; |
2195 | vfd->lock = &dev->lock; | 2189 | vfd->lock = &dev->lock; |
@@ -2200,7 +2194,6 @@ static struct video_device | |||
2200 | dev->name, type_name); | 2194 | dev->name, type_name); |
2201 | 2195 | ||
2202 | video_set_drvdata(vfd, dev); | 2196 | video_set_drvdata(vfd, dev); |
2203 | return vfd; | ||
2204 | } | 2197 | } |
2205 | 2198 | ||
2206 | static void em28xx_tuner_setup(struct em28xx *dev, unsigned short tuner_addr) | 2199 | static void em28xx_tuner_setup(struct em28xx *dev, unsigned short tuner_addr) |
@@ -2491,38 +2484,33 @@ static int em28xx_v4l2_init(struct em28xx *dev) | |||
2491 | goto unregister_dev; | 2484 | goto unregister_dev; |
2492 | 2485 | ||
2493 | /* allocate and fill video video_device struct */ | 2486 | /* allocate and fill video video_device struct */ |
2494 | v4l2->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video"); | 2487 | em28xx_vdev_init(dev, &v4l2->vdev, &em28xx_video_template, "video"); |
2495 | if (!v4l2->vdev) { | ||
2496 | em28xx_errdev("cannot allocate video_device.\n"); | ||
2497 | ret = -ENODEV; | ||
2498 | goto unregister_dev; | ||
2499 | } | ||
2500 | mutex_init(&v4l2->vb_queue_lock); | 2488 | mutex_init(&v4l2->vb_queue_lock); |
2501 | mutex_init(&v4l2->vb_vbi_queue_lock); | 2489 | mutex_init(&v4l2->vb_vbi_queue_lock); |
2502 | v4l2->vdev->queue = &v4l2->vb_vidq; | 2490 | v4l2->vdev.queue = &v4l2->vb_vidq; |
2503 | v4l2->vdev->queue->lock = &v4l2->vb_queue_lock; | 2491 | v4l2->vdev.queue->lock = &v4l2->vb_queue_lock; |
2504 | 2492 | ||
2505 | /* disable inapplicable ioctls */ | 2493 | /* disable inapplicable ioctls */ |
2506 | if (dev->board.is_webcam) { | 2494 | if (dev->board.is_webcam) { |
2507 | v4l2_disable_ioctl(v4l2->vdev, VIDIOC_QUERYSTD); | 2495 | v4l2_disable_ioctl(&v4l2->vdev, VIDIOC_QUERYSTD); |
2508 | v4l2_disable_ioctl(v4l2->vdev, VIDIOC_G_STD); | 2496 | v4l2_disable_ioctl(&v4l2->vdev, VIDIOC_G_STD); |
2509 | v4l2_disable_ioctl(v4l2->vdev, VIDIOC_S_STD); | 2497 | v4l2_disable_ioctl(&v4l2->vdev, VIDIOC_S_STD); |
2510 | } else { | 2498 | } else { |
2511 | v4l2_disable_ioctl(v4l2->vdev, VIDIOC_S_PARM); | 2499 | v4l2_disable_ioctl(&v4l2->vdev, VIDIOC_S_PARM); |
2512 | } | 2500 | } |
2513 | if (dev->tuner_type == TUNER_ABSENT) { | 2501 | if (dev->tuner_type == TUNER_ABSENT) { |
2514 | v4l2_disable_ioctl(v4l2->vdev, VIDIOC_G_TUNER); | 2502 | v4l2_disable_ioctl(&v4l2->vdev, VIDIOC_G_TUNER); |
2515 | v4l2_disable_ioctl(v4l2->vdev, VIDIOC_S_TUNER); | 2503 | v4l2_disable_ioctl(&v4l2->vdev, VIDIOC_S_TUNER); |
2516 | v4l2_disable_ioctl(v4l2->vdev, VIDIOC_G_FREQUENCY); | 2504 | v4l2_disable_ioctl(&v4l2->vdev, VIDIOC_G_FREQUENCY); |
2517 | v4l2_disable_ioctl(v4l2->vdev, VIDIOC_S_FREQUENCY); | 2505 | v4l2_disable_ioctl(&v4l2->vdev, VIDIOC_S_FREQUENCY); |
2518 | } | 2506 | } |
2519 | if (dev->int_audio_type == EM28XX_INT_AUDIO_NONE) { | 2507 | if (dev->int_audio_type == EM28XX_INT_AUDIO_NONE) { |
2520 | v4l2_disable_ioctl(v4l2->vdev, VIDIOC_G_AUDIO); | 2508 | v4l2_disable_ioctl(&v4l2->vdev, VIDIOC_G_AUDIO); |
2521 | v4l2_disable_ioctl(v4l2->vdev, VIDIOC_S_AUDIO); | 2509 | v4l2_disable_ioctl(&v4l2->vdev, VIDIOC_S_AUDIO); |
2522 | } | 2510 | } |
2523 | 2511 | ||
2524 | /* register v4l2 video video_device */ | 2512 | /* register v4l2 video video_device */ |
2525 | ret = video_register_device(v4l2->vdev, VFL_TYPE_GRABBER, | 2513 | ret = video_register_device(&v4l2->vdev, VFL_TYPE_GRABBER, |
2526 | video_nr[dev->devno]); | 2514 | video_nr[dev->devno]); |
2527 | if (ret) { | 2515 | if (ret) { |
2528 | em28xx_errdev("unable to register video device (error=%i).\n", | 2516 | em28xx_errdev("unable to register video device (error=%i).\n", |
@@ -2532,27 +2520,27 @@ static int em28xx_v4l2_init(struct em28xx *dev) | |||
2532 | 2520 | ||
2533 | /* Allocate and fill vbi video_device struct */ | 2521 | /* Allocate and fill vbi video_device struct */ |
2534 | if (em28xx_vbi_supported(dev) == 1) { | 2522 | if (em28xx_vbi_supported(dev) == 1) { |
2535 | v4l2->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template, | 2523 | em28xx_vdev_init(dev, &v4l2->vbi_dev, &em28xx_video_template, |
2536 | "vbi"); | 2524 | "vbi"); |
2537 | 2525 | ||
2538 | v4l2->vbi_dev->queue = &v4l2->vb_vbiq; | 2526 | v4l2->vbi_dev.queue = &v4l2->vb_vbiq; |
2539 | v4l2->vbi_dev->queue->lock = &v4l2->vb_vbi_queue_lock; | 2527 | v4l2->vbi_dev.queue->lock = &v4l2->vb_vbi_queue_lock; |
2540 | 2528 | ||
2541 | /* disable inapplicable ioctls */ | 2529 | /* disable inapplicable ioctls */ |
2542 | v4l2_disable_ioctl(v4l2->vbi_dev, VIDIOC_S_PARM); | 2530 | v4l2_disable_ioctl(&v4l2->vbi_dev, VIDIOC_S_PARM); |
2543 | if (dev->tuner_type == TUNER_ABSENT) { | 2531 | if (dev->tuner_type == TUNER_ABSENT) { |
2544 | v4l2_disable_ioctl(v4l2->vbi_dev, VIDIOC_G_TUNER); | 2532 | v4l2_disable_ioctl(&v4l2->vbi_dev, VIDIOC_G_TUNER); |
2545 | v4l2_disable_ioctl(v4l2->vbi_dev, VIDIOC_S_TUNER); | 2533 | v4l2_disable_ioctl(&v4l2->vbi_dev, VIDIOC_S_TUNER); |
2546 | v4l2_disable_ioctl(v4l2->vbi_dev, VIDIOC_G_FREQUENCY); | 2534 | v4l2_disable_ioctl(&v4l2->vbi_dev, VIDIOC_G_FREQUENCY); |
2547 | v4l2_disable_ioctl(v4l2->vbi_dev, VIDIOC_S_FREQUENCY); | 2535 | v4l2_disable_ioctl(&v4l2->vbi_dev, VIDIOC_S_FREQUENCY); |
2548 | } | 2536 | } |
2549 | if (dev->int_audio_type == EM28XX_INT_AUDIO_NONE) { | 2537 | if (dev->int_audio_type == EM28XX_INT_AUDIO_NONE) { |
2550 | v4l2_disable_ioctl(v4l2->vbi_dev, VIDIOC_G_AUDIO); | 2538 | v4l2_disable_ioctl(&v4l2->vbi_dev, VIDIOC_G_AUDIO); |
2551 | v4l2_disable_ioctl(v4l2->vbi_dev, VIDIOC_S_AUDIO); | 2539 | v4l2_disable_ioctl(&v4l2->vbi_dev, VIDIOC_S_AUDIO); |
2552 | } | 2540 | } |
2553 | 2541 | ||
2554 | /* register v4l2 vbi video_device */ | 2542 | /* register v4l2 vbi video_device */ |
2555 | ret = video_register_device(v4l2->vbi_dev, VFL_TYPE_VBI, | 2543 | ret = video_register_device(&v4l2->vbi_dev, VFL_TYPE_VBI, |
2556 | vbi_nr[dev->devno]); | 2544 | vbi_nr[dev->devno]); |
2557 | if (ret < 0) { | 2545 | if (ret < 0) { |
2558 | em28xx_errdev("unable to register vbi device\n"); | 2546 | em28xx_errdev("unable to register vbi device\n"); |
@@ -2561,29 +2549,24 @@ static int em28xx_v4l2_init(struct em28xx *dev) | |||
2561 | } | 2549 | } |
2562 | 2550 | ||
2563 | if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) { | 2551 | if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) { |
2564 | v4l2->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template, | 2552 | em28xx_vdev_init(dev, &v4l2->radio_dev, &em28xx_radio_template, |
2565 | "radio"); | 2553 | "radio"); |
2566 | if (!v4l2->radio_dev) { | 2554 | ret = video_register_device(&v4l2->radio_dev, VFL_TYPE_RADIO, |
2567 | em28xx_errdev("cannot allocate video_device.\n"); | ||
2568 | ret = -ENODEV; | ||
2569 | goto unregister_dev; | ||
2570 | } | ||
2571 | ret = video_register_device(v4l2->radio_dev, VFL_TYPE_RADIO, | ||
2572 | radio_nr[dev->devno]); | 2555 | radio_nr[dev->devno]); |
2573 | if (ret < 0) { | 2556 | if (ret < 0) { |
2574 | em28xx_errdev("can't register radio device\n"); | 2557 | em28xx_errdev("can't register radio device\n"); |
2575 | goto unregister_dev; | 2558 | goto unregister_dev; |
2576 | } | 2559 | } |
2577 | em28xx_info("Registered radio device as %s\n", | 2560 | em28xx_info("Registered radio device as %s\n", |
2578 | video_device_node_name(v4l2->radio_dev)); | 2561 | video_device_node_name(&v4l2->radio_dev)); |
2579 | } | 2562 | } |
2580 | 2563 | ||
2581 | em28xx_info("V4L2 video device registered as %s\n", | 2564 | em28xx_info("V4L2 video device registered as %s\n", |
2582 | video_device_node_name(v4l2->vdev)); | 2565 | video_device_node_name(&v4l2->vdev)); |
2583 | 2566 | ||
2584 | if (v4l2->vbi_dev) | 2567 | if (video_is_registered(&v4l2->vbi_dev)) |
2585 | em28xx_info("V4L2 VBI device registered as %s\n", | 2568 | em28xx_info("V4L2 VBI device registered as %s\n", |
2586 | video_device_node_name(v4l2->vbi_dev)); | 2569 | video_device_node_name(&v4l2->vbi_dev)); |
2587 | 2570 | ||
2588 | /* Save some power by putting tuner to sleep */ | 2571 | /* Save some power by putting tuner to sleep */ |
2589 | v4l2_device_call_all(&v4l2->v4l2_dev, 0, core, s_power, 0); | 2572 | v4l2_device_call_all(&v4l2->v4l2_dev, 0, core, s_power, 0); |
diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index 9c7075344109..e6559c6f143c 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h | |||
@@ -143,6 +143,7 @@ | |||
143 | #define EM28178_BOARD_PCTV_292E 94 | 143 | #define EM28178_BOARD_PCTV_292E 94 |
144 | #define EM2861_BOARD_LEADTEK_VC100 95 | 144 | #define EM2861_BOARD_LEADTEK_VC100 95 |
145 | #define EM28178_BOARD_TERRATEC_T2_STICK_HD 96 | 145 | #define EM28178_BOARD_TERRATEC_T2_STICK_HD 96 |
146 | #define EM2884_BOARD_ELGATO_EYETV_HYBRID_2008 97 | ||
146 | 147 | ||
147 | /* Limits minimum and default number of buffers */ | 148 | /* Limits minimum and default number of buffers */ |
148 | #define EM28XX_MIN_BUF 4 | 149 | #define EM28XX_MIN_BUF 4 |
@@ -512,9 +513,9 @@ struct em28xx_v4l2 { | |||
512 | struct v4l2_ctrl_handler ctrl_handler; | 513 | struct v4l2_ctrl_handler ctrl_handler; |
513 | struct v4l2_clk *clk; | 514 | struct v4l2_clk *clk; |
514 | 515 | ||
515 | struct video_device *vdev; | 516 | struct video_device vdev; |
516 | struct video_device *vbi_dev; | 517 | struct video_device vbi_dev; |
517 | struct video_device *radio_dev; | 518 | struct video_device radio_dev; |
518 | 519 | ||
519 | /* Videobuf2 */ | 520 | /* Videobuf2 */ |
520 | struct vb2_queue vb_vidq; | 521 | struct vb2_queue vb_vidq; |
diff --git a/drivers/media/usb/gspca/ov534.c b/drivers/media/usb/gspca/ov534.c index a9c866d6d82d..146071b8e116 100644 --- a/drivers/media/usb/gspca/ov534.c +++ b/drivers/media/usb/gspca/ov534.c | |||
@@ -816,21 +816,16 @@ static void sethue(struct gspca_dev *gspca_dev, s32 val) | |||
816 | s16 huesin; | 816 | s16 huesin; |
817 | s16 huecos; | 817 | s16 huecos; |
818 | 818 | ||
819 | /* fixp_sin and fixp_cos accept only positive values, while | ||
820 | * our val is between -90 and 90 | ||
821 | */ | ||
822 | val += 360; | ||
823 | |||
824 | /* According to the datasheet the registers expect HUESIN and | 819 | /* According to the datasheet the registers expect HUESIN and |
825 | * HUECOS to be the result of the trigonometric functions, | 820 | * HUECOS to be the result of the trigonometric functions, |
826 | * scaled by 0x80. | 821 | * scaled by 0x80. |
827 | * | 822 | * |
828 | * The 0x100 here represents the maximun absolute value | 823 | * The 0x7fff here represents the maximum absolute value |
829 | * returned byt fixp_sin and fixp_cos, so the scaling will | 824 | * returned byt fixp_sin and fixp_cos, so the scaling will |
830 | * consider the result like in the interval [-1.0, 1.0]. | 825 | * consider the result like in the interval [-1.0, 1.0]. |
831 | */ | 826 | */ |
832 | huesin = fixp_sin(val) * 0x80 / 0x100; | 827 | huesin = fixp_sin16(val) * 0x80 / 0x7fff; |
833 | huecos = fixp_cos(val) * 0x80 / 0x100; | 828 | huecos = fixp_cos16(val) * 0x80 / 0x7fff; |
834 | 829 | ||
835 | if (huesin < 0) { | 830 | if (huesin < 0) { |
836 | sccb_reg_write(gspca_dev, 0xab, | 831 | sccb_reg_write(gspca_dev, 0xab, |
diff --git a/drivers/media/usb/gspca/topro.c b/drivers/media/usb/gspca/topro.c index 5fcd1eec2004..c70ff406b07a 100644 --- a/drivers/media/usb/gspca/topro.c +++ b/drivers/media/usb/gspca/topro.c | |||
@@ -969,7 +969,9 @@ static void jpeg_set_qual(u8 *jpeg_hdr, | |||
969 | { | 969 | { |
970 | int i, sc; | 970 | int i, sc; |
971 | 971 | ||
972 | if (quality < 50) | 972 | if (quality <= 0) |
973 | sc = 5000; | ||
974 | else if (quality < 50) | ||
973 | sc = 5000 / quality; | 975 | sc = 5000 / quality; |
974 | else | 976 | else |
975 | sc = 200 - quality * 2; | 977 | sc = 200 - quality * 2; |
diff --git a/drivers/media/usb/hdpvr/hdpvr-core.c b/drivers/media/usb/hdpvr/hdpvr-core.c index 42b4cdf28cfd..3fc64197b4e6 100644 --- a/drivers/media/usb/hdpvr/hdpvr-core.c +++ b/drivers/media/usb/hdpvr/hdpvr-core.c | |||
@@ -69,10 +69,6 @@ MODULE_DEVICE_TABLE(usb, hdpvr_table); | |||
69 | void hdpvr_delete(struct hdpvr_device *dev) | 69 | void hdpvr_delete(struct hdpvr_device *dev) |
70 | { | 70 | { |
71 | hdpvr_free_buffers(dev); | 71 | hdpvr_free_buffers(dev); |
72 | |||
73 | if (dev->video_dev) | ||
74 | video_device_release(dev->video_dev); | ||
75 | |||
76 | usb_put_dev(dev->udev); | 72 | usb_put_dev(dev->udev); |
77 | } | 73 | } |
78 | 74 | ||
@@ -397,7 +393,7 @@ static int hdpvr_probe(struct usb_interface *interface, | |||
397 | 393 | ||
398 | /* let the user know what node this device is now attached to */ | 394 | /* let the user know what node this device is now attached to */ |
399 | v4l2_info(&dev->v4l2_dev, "device now attached to %s\n", | 395 | v4l2_info(&dev->v4l2_dev, "device now attached to %s\n", |
400 | video_device_node_name(dev->video_dev)); | 396 | video_device_node_name(&dev->video_dev)); |
401 | return 0; | 397 | return 0; |
402 | 398 | ||
403 | reg_fail: | 399 | reg_fail: |
@@ -420,7 +416,7 @@ static void hdpvr_disconnect(struct usb_interface *interface) | |||
420 | struct hdpvr_device *dev = to_hdpvr_dev(usb_get_intfdata(interface)); | 416 | struct hdpvr_device *dev = to_hdpvr_dev(usb_get_intfdata(interface)); |
421 | 417 | ||
422 | v4l2_info(&dev->v4l2_dev, "device %s disconnected\n", | 418 | v4l2_info(&dev->v4l2_dev, "device %s disconnected\n", |
423 | video_device_node_name(dev->video_dev)); | 419 | video_device_node_name(&dev->video_dev)); |
424 | /* prevent more I/O from starting and stop any ongoing */ | 420 | /* prevent more I/O from starting and stop any ongoing */ |
425 | mutex_lock(&dev->io_mutex); | 421 | mutex_lock(&dev->io_mutex); |
426 | dev->status = STATUS_DISCONNECTED; | 422 | dev->status = STATUS_DISCONNECTED; |
@@ -436,7 +432,7 @@ static void hdpvr_disconnect(struct usb_interface *interface) | |||
436 | #if IS_ENABLED(CONFIG_I2C) | 432 | #if IS_ENABLED(CONFIG_I2C) |
437 | i2c_del_adapter(&dev->i2c_adapter); | 433 | i2c_del_adapter(&dev->i2c_adapter); |
438 | #endif | 434 | #endif |
439 | video_unregister_device(dev->video_dev); | 435 | video_unregister_device(&dev->video_dev); |
440 | atomic_dec(&dev_nr); | 436 | atomic_dec(&dev_nr); |
441 | } | 437 | } |
442 | 438 | ||
diff --git a/drivers/media/usb/hdpvr/hdpvr-video.c b/drivers/media/usb/hdpvr/hdpvr-video.c index 59d15fd242ba..d8d8c0f519fc 100644 --- a/drivers/media/usb/hdpvr/hdpvr-video.c +++ b/drivers/media/usb/hdpvr/hdpvr-video.c | |||
@@ -797,7 +797,7 @@ static int vidioc_s_input(struct file *file, void *_fh, | |||
797 | * Comment this out for now, but if the legacy mode can be | 797 | * Comment this out for now, but if the legacy mode can be |
798 | * removed in the future, then this code should be enabled | 798 | * removed in the future, then this code should be enabled |
799 | * again. | 799 | * again. |
800 | dev->video_dev->tvnorms = | 800 | dev->video_dev.tvnorms = |
801 | (index != HDPVR_COMPONENT) ? V4L2_STD_ALL : 0; | 801 | (index != HDPVR_COMPONENT) ? V4L2_STD_ALL : 0; |
802 | */ | 802 | */ |
803 | } | 803 | } |
@@ -1228,19 +1228,12 @@ int hdpvr_register_videodev(struct hdpvr_device *dev, struct device *parent, | |||
1228 | } | 1228 | } |
1229 | 1229 | ||
1230 | /* setup and register video device */ | 1230 | /* setup and register video device */ |
1231 | dev->video_dev = video_device_alloc(); | 1231 | dev->video_dev = hdpvr_video_template; |
1232 | if (!dev->video_dev) { | 1232 | strcpy(dev->video_dev.name, "Hauppauge HD PVR"); |
1233 | v4l2_err(&dev->v4l2_dev, "video_device_alloc() failed\n"); | 1233 | dev->video_dev.v4l2_dev = &dev->v4l2_dev; |
1234 | res = -ENOMEM; | 1234 | video_set_drvdata(&dev->video_dev, dev); |
1235 | goto error; | ||
1236 | } | ||
1237 | |||
1238 | *dev->video_dev = hdpvr_video_template; | ||
1239 | strcpy(dev->video_dev->name, "Hauppauge HD PVR"); | ||
1240 | dev->video_dev->v4l2_dev = &dev->v4l2_dev; | ||
1241 | video_set_drvdata(dev->video_dev, dev); | ||
1242 | 1235 | ||
1243 | res = video_register_device(dev->video_dev, VFL_TYPE_GRABBER, devnum); | 1236 | res = video_register_device(&dev->video_dev, VFL_TYPE_GRABBER, devnum); |
1244 | if (res < 0) { | 1237 | if (res < 0) { |
1245 | v4l2_err(&dev->v4l2_dev, "video_device registration failed\n"); | 1238 | v4l2_err(&dev->v4l2_dev, "video_device registration failed\n"); |
1246 | goto error; | 1239 | goto error; |
diff --git a/drivers/media/usb/hdpvr/hdpvr.h b/drivers/media/usb/hdpvr/hdpvr.h index dc685d44cb3e..a3194304182d 100644 --- a/drivers/media/usb/hdpvr/hdpvr.h +++ b/drivers/media/usb/hdpvr/hdpvr.h | |||
@@ -66,7 +66,7 @@ struct hdpvr_options { | |||
66 | /* Structure to hold all of our device specific stuff */ | 66 | /* Structure to hold all of our device specific stuff */ |
67 | struct hdpvr_device { | 67 | struct hdpvr_device { |
68 | /* the v4l device for this device */ | 68 | /* the v4l device for this device */ |
69 | struct video_device *video_dev; | 69 | struct video_device video_dev; |
70 | /* the control handler for this device */ | 70 | /* the control handler for this device */ |
71 | struct v4l2_ctrl_handler hdl; | 71 | struct v4l2_ctrl_handler hdl; |
72 | /* the usb device for this device */ | 72 | /* the usb device for this device */ |
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c index 35e4ea530494..1c5f85bf7ed4 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c | |||
@@ -21,7 +21,6 @@ | |||
21 | 21 | ||
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | #include <linux/version.h> | ||
25 | #include "pvrusb2-context.h" | 24 | #include "pvrusb2-context.h" |
26 | #include "pvrusb2-hdw.h" | 25 | #include "pvrusb2-hdw.h" |
27 | #include "pvrusb2.h" | 26 | #include "pvrusb2.h" |
@@ -32,6 +31,7 @@ | |||
32 | #include <linux/module.h> | 31 | #include <linux/module.h> |
33 | #include <media/v4l2-dev.h> | 32 | #include <media/v4l2-dev.h> |
34 | #include <media/v4l2-device.h> | 33 | #include <media/v4l2-device.h> |
34 | #include <media/v4l2-fh.h> | ||
35 | #include <media/v4l2-common.h> | 35 | #include <media/v4l2-common.h> |
36 | #include <media/v4l2-ioctl.h> | 36 | #include <media/v4l2-ioctl.h> |
37 | 37 | ||
@@ -50,14 +50,11 @@ struct pvr2_v4l2_dev { | |||
50 | }; | 50 | }; |
51 | 51 | ||
52 | struct pvr2_v4l2_fh { | 52 | struct pvr2_v4l2_fh { |
53 | struct v4l2_fh fh; | ||
53 | struct pvr2_channel channel; | 54 | struct pvr2_channel channel; |
54 | struct pvr2_v4l2_dev *pdi; | 55 | struct pvr2_v4l2_dev *pdi; |
55 | enum v4l2_priority prio; | ||
56 | struct pvr2_ioread *rhp; | 56 | struct pvr2_ioread *rhp; |
57 | struct file *file; | 57 | struct file *file; |
58 | struct pvr2_v4l2 *vhead; | ||
59 | struct pvr2_v4l2_fh *vnext; | ||
60 | struct pvr2_v4l2_fh *vprev; | ||
61 | wait_queue_head_t wait_data; | 58 | wait_queue_head_t wait_data; |
62 | int fw_mode_flag; | 59 | int fw_mode_flag; |
63 | /* Map contiguous ordinal value to input id */ | 60 | /* Map contiguous ordinal value to input id */ |
@@ -67,10 +64,6 @@ struct pvr2_v4l2_fh { | |||
67 | 64 | ||
68 | struct pvr2_v4l2 { | 65 | struct pvr2_v4l2 { |
69 | struct pvr2_channel channel; | 66 | struct pvr2_channel channel; |
70 | struct pvr2_v4l2_fh *vfirst; | ||
71 | struct pvr2_v4l2_fh *vlast; | ||
72 | |||
73 | struct v4l2_prio_state prio; | ||
74 | 67 | ||
75 | /* streams - Note that these must be separately, individually, | 68 | /* streams - Note that these must be separately, individually, |
76 | * allocated pointers. This is because the v4l core is going to | 69 | * allocated pointers. This is because the v4l core is going to |
@@ -169,23 +162,6 @@ static int pvr2_querycap(struct file *file, void *priv, struct v4l2_capability * | |||
169 | return 0; | 162 | return 0; |
170 | } | 163 | } |
171 | 164 | ||
172 | static int pvr2_g_priority(struct file *file, void *priv, enum v4l2_priority *p) | ||
173 | { | ||
174 | struct pvr2_v4l2_fh *fh = file->private_data; | ||
175 | struct pvr2_v4l2 *vp = fh->vhead; | ||
176 | |||
177 | *p = v4l2_prio_max(&vp->prio); | ||
178 | return 0; | ||
179 | } | ||
180 | |||
181 | static int pvr2_s_priority(struct file *file, void *priv, enum v4l2_priority prio) | ||
182 | { | ||
183 | struct pvr2_v4l2_fh *fh = file->private_data; | ||
184 | struct pvr2_v4l2 *vp = fh->vhead; | ||
185 | |||
186 | return v4l2_prio_change(&vp->prio, &fh->prio, prio); | ||
187 | } | ||
188 | |||
189 | static int pvr2_g_std(struct file *file, void *priv, v4l2_std_id *std) | 165 | static int pvr2_g_std(struct file *file, void *priv, v4l2_std_id *std) |
190 | { | 166 | { |
191 | struct pvr2_v4l2_fh *fh = file->private_data; | 167 | struct pvr2_v4l2_fh *fh = file->private_data; |
@@ -805,8 +781,6 @@ static int pvr2_log_status(struct file *file, void *priv) | |||
805 | 781 | ||
806 | static const struct v4l2_ioctl_ops pvr2_ioctl_ops = { | 782 | static const struct v4l2_ioctl_ops pvr2_ioctl_ops = { |
807 | .vidioc_querycap = pvr2_querycap, | 783 | .vidioc_querycap = pvr2_querycap, |
808 | .vidioc_g_priority = pvr2_g_priority, | ||
809 | .vidioc_s_priority = pvr2_s_priority, | ||
810 | .vidioc_s_audio = pvr2_s_audio, | 784 | .vidioc_s_audio = pvr2_s_audio, |
811 | .vidioc_g_audio = pvr2_g_audio, | 785 | .vidioc_g_audio = pvr2_g_audio, |
812 | .vidioc_enumaudio = pvr2_enumaudio, | 786 | .vidioc_enumaudio = pvr2_enumaudio, |
@@ -911,7 +885,9 @@ static void pvr2_v4l2_internal_check(struct pvr2_channel *chp) | |||
911 | if (!vp->channel.mc_head->disconnect_flag) return; | 885 | if (!vp->channel.mc_head->disconnect_flag) return; |
912 | pvr2_v4l2_dev_disassociate_parent(vp->dev_video); | 886 | pvr2_v4l2_dev_disassociate_parent(vp->dev_video); |
913 | pvr2_v4l2_dev_disassociate_parent(vp->dev_radio); | 887 | pvr2_v4l2_dev_disassociate_parent(vp->dev_radio); |
914 | if (vp->vfirst) return; | 888 | if (!list_empty(&vp->dev_video->devbase.fh_list) || |
889 | !list_empty(&vp->dev_radio->devbase.fh_list)) | ||
890 | return; | ||
915 | pvr2_v4l2_destroy_no_lock(vp); | 891 | pvr2_v4l2_destroy_no_lock(vp); |
916 | } | 892 | } |
917 | 893 | ||
@@ -921,7 +897,6 @@ static long pvr2_v4l2_ioctl(struct file *file, | |||
921 | { | 897 | { |
922 | 898 | ||
923 | struct pvr2_v4l2_fh *fh = file->private_data; | 899 | struct pvr2_v4l2_fh *fh = file->private_data; |
924 | struct pvr2_v4l2 *vp = fh->vhead; | ||
925 | struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; | 900 | struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; |
926 | long ret = -EINVAL; | 901 | long ret = -EINVAL; |
927 | 902 | ||
@@ -934,18 +909,6 @@ static long pvr2_v4l2_ioctl(struct file *file, | |||
934 | return -EFAULT; | 909 | return -EFAULT; |
935 | } | 910 | } |
936 | 911 | ||
937 | /* check priority */ | ||
938 | switch (cmd) { | ||
939 | case VIDIOC_S_CTRL: | ||
940 | case VIDIOC_S_STD: | ||
941 | case VIDIOC_S_INPUT: | ||
942 | case VIDIOC_S_TUNER: | ||
943 | case VIDIOC_S_FREQUENCY: | ||
944 | ret = v4l2_prio_check(&vp->prio, fh->prio); | ||
945 | if (ret) | ||
946 | return ret; | ||
947 | } | ||
948 | |||
949 | ret = video_ioctl2(file, cmd, arg); | 912 | ret = video_ioctl2(file, cmd, arg); |
950 | 913 | ||
951 | pvr2_hdw_commit_ctl(hdw); | 914 | pvr2_hdw_commit_ctl(hdw); |
@@ -970,7 +933,7 @@ static long pvr2_v4l2_ioctl(struct file *file, | |||
970 | static int pvr2_v4l2_release(struct file *file) | 933 | static int pvr2_v4l2_release(struct file *file) |
971 | { | 934 | { |
972 | struct pvr2_v4l2_fh *fhp = file->private_data; | 935 | struct pvr2_v4l2_fh *fhp = file->private_data; |
973 | struct pvr2_v4l2 *vp = fhp->vhead; | 936 | struct pvr2_v4l2 *vp = fhp->pdi->v4lp; |
974 | struct pvr2_hdw *hdw = fhp->channel.mc_head->hdw; | 937 | struct pvr2_hdw *hdw = fhp->channel.mc_head->hdw; |
975 | 938 | ||
976 | pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_release"); | 939 | pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_release"); |
@@ -984,22 +947,10 @@ static int pvr2_v4l2_release(struct file *file) | |||
984 | fhp->rhp = NULL; | 947 | fhp->rhp = NULL; |
985 | } | 948 | } |
986 | 949 | ||
987 | v4l2_prio_close(&vp->prio, fhp->prio); | 950 | v4l2_fh_del(&fhp->fh); |
951 | v4l2_fh_exit(&fhp->fh); | ||
988 | file->private_data = NULL; | 952 | file->private_data = NULL; |
989 | 953 | ||
990 | if (fhp->vnext) { | ||
991 | fhp->vnext->vprev = fhp->vprev; | ||
992 | } else { | ||
993 | vp->vlast = fhp->vprev; | ||
994 | } | ||
995 | if (fhp->vprev) { | ||
996 | fhp->vprev->vnext = fhp->vnext; | ||
997 | } else { | ||
998 | vp->vfirst = fhp->vnext; | ||
999 | } | ||
1000 | fhp->vnext = NULL; | ||
1001 | fhp->vprev = NULL; | ||
1002 | fhp->vhead = NULL; | ||
1003 | pvr2_channel_done(&fhp->channel); | 954 | pvr2_channel_done(&fhp->channel); |
1004 | pvr2_trace(PVR2_TRACE_STRUCT, | 955 | pvr2_trace(PVR2_TRACE_STRUCT, |
1005 | "Destroying pvr_v4l2_fh id=%p",fhp); | 956 | "Destroying pvr_v4l2_fh id=%p",fhp); |
@@ -1008,7 +959,9 @@ static int pvr2_v4l2_release(struct file *file) | |||
1008 | fhp->input_map = NULL; | 959 | fhp->input_map = NULL; |
1009 | } | 960 | } |
1010 | kfree(fhp); | 961 | kfree(fhp); |
1011 | if (vp->channel.mc_head->disconnect_flag && !vp->vfirst) { | 962 | if (vp->channel.mc_head->disconnect_flag && |
963 | list_empty(&vp->dev_video->devbase.fh_list) && | ||
964 | list_empty(&vp->dev_radio->devbase.fh_list)) { | ||
1012 | pvr2_v4l2_destroy_no_lock(vp); | 965 | pvr2_v4l2_destroy_no_lock(vp); |
1013 | } | 966 | } |
1014 | return 0; | 967 | return 0; |
@@ -1043,6 +996,7 @@ static int pvr2_v4l2_open(struct file *file) | |||
1043 | return -ENOMEM; | 996 | return -ENOMEM; |
1044 | } | 997 | } |
1045 | 998 | ||
999 | v4l2_fh_init(&fhp->fh, &dip->devbase); | ||
1046 | init_waitqueue_head(&fhp->wait_data); | 1000 | init_waitqueue_head(&fhp->wait_data); |
1047 | fhp->pdi = dip; | 1001 | fhp->pdi = dip; |
1048 | 1002 | ||
@@ -1093,21 +1047,11 @@ static int pvr2_v4l2_open(struct file *file) | |||
1093 | fhp->input_map[input_cnt++] = idx; | 1047 | fhp->input_map[input_cnt++] = idx; |
1094 | } | 1048 | } |
1095 | 1049 | ||
1096 | fhp->vnext = NULL; | ||
1097 | fhp->vprev = vp->vlast; | ||
1098 | if (vp->vlast) { | ||
1099 | vp->vlast->vnext = fhp; | ||
1100 | } else { | ||
1101 | vp->vfirst = fhp; | ||
1102 | } | ||
1103 | vp->vlast = fhp; | ||
1104 | fhp->vhead = vp; | ||
1105 | |||
1106 | fhp->file = file; | 1050 | fhp->file = file; |
1107 | file->private_data = fhp; | 1051 | file->private_data = fhp; |
1108 | v4l2_prio_open(&vp->prio, &fhp->prio); | ||
1109 | 1052 | ||
1110 | fhp->fw_mode_flag = pvr2_hdw_cpufw_get_enabled(hdw); | 1053 | fhp->fw_mode_flag = pvr2_hdw_cpufw_get_enabled(hdw); |
1054 | v4l2_fh_add(&fhp->fh); | ||
1111 | 1055 | ||
1112 | return 0; | 1056 | return 0; |
1113 | } | 1057 | } |
@@ -1247,7 +1191,7 @@ static const struct v4l2_file_operations vdev_fops = { | |||
1247 | .open = pvr2_v4l2_open, | 1191 | .open = pvr2_v4l2_open, |
1248 | .release = pvr2_v4l2_release, | 1192 | .release = pvr2_v4l2_release, |
1249 | .read = pvr2_v4l2_read, | 1193 | .read = pvr2_v4l2_read, |
1250 | .ioctl = pvr2_v4l2_ioctl, | 1194 | .unlocked_ioctl = pvr2_v4l2_ioctl, |
1251 | .poll = pvr2_v4l2_poll, | 1195 | .poll = pvr2_v4l2_poll, |
1252 | }; | 1196 | }; |
1253 | 1197 | ||
diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c index 94e10b10b66e..c945e4c2fbd4 100644 --- a/drivers/media/usb/siano/smsusb.c +++ b/drivers/media/usb/siano/smsusb.c | |||
@@ -19,6 +19,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
19 | 19 | ||
20 | ****************************************************************/ | 20 | ****************************************************************/ |
21 | 21 | ||
22 | #include "smscoreapi.h" | ||
23 | |||
22 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
23 | #include <linux/init.h> | 25 | #include <linux/init.h> |
24 | #include <linux/usb.h> | 26 | #include <linux/usb.h> |
@@ -26,14 +28,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
26 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
27 | #include <linux/module.h> | 29 | #include <linux/module.h> |
28 | 30 | ||
29 | #include "smscoreapi.h" | ||
30 | #include "sms-cards.h" | 31 | #include "sms-cards.h" |
31 | #include "smsendian.h" | 32 | #include "smsendian.h" |
32 | 33 | ||
33 | static int sms_dbg; | ||
34 | module_param_named(debug, sms_dbg, int, 0644); | ||
35 | MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); | ||
36 | |||
37 | #define USB1_BUFFER_SIZE 0x1000 | 34 | #define USB1_BUFFER_SIZE 0x1000 |
38 | #define USB2_BUFFER_SIZE 0x2000 | 35 | #define USB2_BUFFER_SIZE 0x2000 |
39 | 36 | ||
@@ -87,7 +84,7 @@ static void smsusb_onresponse(struct urb *urb) | |||
87 | struct smsusb_device_t *dev = surb->dev; | 84 | struct smsusb_device_t *dev = surb->dev; |
88 | 85 | ||
89 | if (urb->status == -ESHUTDOWN) { | 86 | if (urb->status == -ESHUTDOWN) { |
90 | sms_err("error, urb status %d (-ESHUTDOWN), %d bytes", | 87 | pr_err("error, urb status %d (-ESHUTDOWN), %d bytes\n", |
91 | urb->status, urb->actual_length); | 88 | urb->status, urb->actual_length); |
92 | return; | 89 | return; |
93 | } | 90 | } |
@@ -109,9 +106,7 @@ static void smsusb_onresponse(struct urb *urb) | |||
109 | /* sanity check */ | 106 | /* sanity check */ |
110 | if (((int) phdr->msg_length + | 107 | if (((int) phdr->msg_length + |
111 | surb->cb->offset) > urb->actual_length) { | 108 | surb->cb->offset) > urb->actual_length) { |
112 | sms_err("invalid response " | 109 | pr_err("invalid response msglen %d offset %d size %d\n", |
113 | "msglen %d offset %d " | ||
114 | "size %d", | ||
115 | phdr->msg_length, | 110 | phdr->msg_length, |
116 | surb->cb->offset, | 111 | surb->cb->offset, |
117 | urb->actual_length); | 112 | urb->actual_length); |
@@ -125,7 +120,7 @@ static void smsusb_onresponse(struct urb *urb) | |||
125 | } else | 120 | } else |
126 | surb->cb->offset = 0; | 121 | surb->cb->offset = 0; |
127 | 122 | ||
128 | sms_debug("received %s(%d) size: %d", | 123 | pr_debug("received %s(%d) size: %d\n", |
129 | smscore_translate_msg(phdr->msg_type), | 124 | smscore_translate_msg(phdr->msg_type), |
130 | phdr->msg_type, phdr->msg_length); | 125 | phdr->msg_type, phdr->msg_length); |
131 | 126 | ||
@@ -134,12 +129,11 @@ static void smsusb_onresponse(struct urb *urb) | |||
134 | smscore_onresponse(dev->coredev, surb->cb); | 129 | smscore_onresponse(dev->coredev, surb->cb); |
135 | surb->cb = NULL; | 130 | surb->cb = NULL; |
136 | } else { | 131 | } else { |
137 | sms_err("invalid response " | 132 | pr_err("invalid response msglen %d actual %d\n", |
138 | "msglen %d actual %d", | ||
139 | phdr->msg_length, urb->actual_length); | 133 | phdr->msg_length, urb->actual_length); |
140 | } | 134 | } |
141 | } else | 135 | } else |
142 | sms_err("error, urb status %d, %d bytes", | 136 | pr_err("error, urb status %d, %d bytes\n", |
143 | urb->status, urb->actual_length); | 137 | urb->status, urb->actual_length); |
144 | 138 | ||
145 | 139 | ||
@@ -153,7 +147,7 @@ static int smsusb_submit_urb(struct smsusb_device_t *dev, | |||
153 | if (!surb->cb) { | 147 | if (!surb->cb) { |
154 | surb->cb = smscore_getbuffer(dev->coredev); | 148 | surb->cb = smscore_getbuffer(dev->coredev); |
155 | if (!surb->cb) { | 149 | if (!surb->cb) { |
156 | sms_err("smscore_getbuffer(...) returned NULL"); | 150 | pr_err("smscore_getbuffer(...) returned NULL\n"); |
157 | return -ENOMEM; | 151 | return -ENOMEM; |
158 | } | 152 | } |
159 | } | 153 | } |
@@ -194,7 +188,7 @@ static int smsusb_start_streaming(struct smsusb_device_t *dev) | |||
194 | for (i = 0; i < MAX_URBS; i++) { | 188 | for (i = 0; i < MAX_URBS; i++) { |
195 | rc = smsusb_submit_urb(dev, &dev->surbs[i]); | 189 | rc = smsusb_submit_urb(dev, &dev->surbs[i]); |
196 | if (rc < 0) { | 190 | if (rc < 0) { |
197 | sms_err("smsusb_submit_urb(...) failed"); | 191 | pr_err("smsusb_submit_urb(...) failed\n"); |
198 | smsusb_stop_streaming(dev); | 192 | smsusb_stop_streaming(dev); |
199 | break; | 193 | break; |
200 | } | 194 | } |
@@ -210,11 +204,11 @@ static int smsusb_sendrequest(void *context, void *buffer, size_t size) | |||
210 | int dummy; | 204 | int dummy; |
211 | 205 | ||
212 | if (dev->state != SMSUSB_ACTIVE) { | 206 | if (dev->state != SMSUSB_ACTIVE) { |
213 | sms_debug("Device not active yet"); | 207 | pr_debug("Device not active yet\n"); |
214 | return -ENOENT; | 208 | return -ENOENT; |
215 | } | 209 | } |
216 | 210 | ||
217 | sms_debug("sending %s(%d) size: %d", | 211 | pr_debug("sending %s(%d) size: %d\n", |
218 | smscore_translate_msg(phdr->msg_type), phdr->msg_type, | 212 | smscore_translate_msg(phdr->msg_type), phdr->msg_type, |
219 | phdr->msg_length); | 213 | phdr->msg_length); |
220 | 214 | ||
@@ -249,7 +243,7 @@ static int smsusb1_load_firmware(struct usb_device *udev, int id, int board_id) | |||
249 | id = sms_get_board(board_id)->default_mode; | 243 | id = sms_get_board(board_id)->default_mode; |
250 | 244 | ||
251 | if (id < DEVICE_MODE_DVBT || id > DEVICE_MODE_DVBT_BDA) { | 245 | if (id < DEVICE_MODE_DVBT || id > DEVICE_MODE_DVBT_BDA) { |
252 | sms_err("invalid firmware id specified %d", id); | 246 | pr_err("invalid firmware id specified %d\n", id); |
253 | return -EINVAL; | 247 | return -EINVAL; |
254 | } | 248 | } |
255 | 249 | ||
@@ -257,13 +251,13 @@ static int smsusb1_load_firmware(struct usb_device *udev, int id, int board_id) | |||
257 | 251 | ||
258 | rc = request_firmware(&fw, fw_filename, &udev->dev); | 252 | rc = request_firmware(&fw, fw_filename, &udev->dev); |
259 | if (rc < 0) { | 253 | if (rc < 0) { |
260 | sms_warn("failed to open \"%s\" mode %d, " | 254 | pr_warn("failed to open '%s' mode %d, trying again with default firmware\n", |
261 | "trying again with default firmware", fw_filename, id); | 255 | fw_filename, id); |
262 | 256 | ||
263 | fw_filename = smsusb1_fw_lkup[id]; | 257 | fw_filename = smsusb1_fw_lkup[id]; |
264 | rc = request_firmware(&fw, fw_filename, &udev->dev); | 258 | rc = request_firmware(&fw, fw_filename, &udev->dev); |
265 | if (rc < 0) { | 259 | if (rc < 0) { |
266 | sms_warn("failed to open \"%s\" mode %d", | 260 | pr_warn("failed to open '%s' mode %d\n", |
267 | fw_filename, id); | 261 | fw_filename, id); |
268 | 262 | ||
269 | return rc; | 263 | return rc; |
@@ -277,14 +271,14 @@ static int smsusb1_load_firmware(struct usb_device *udev, int id, int board_id) | |||
277 | rc = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 2), | 271 | rc = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 2), |
278 | fw_buffer, fw->size, &dummy, 1000); | 272 | fw_buffer, fw->size, &dummy, 1000); |
279 | 273 | ||
280 | sms_info("sent %zu(%d) bytes, rc %d", fw->size, dummy, rc); | 274 | pr_debug("sent %zu(%d) bytes, rc %d\n", fw->size, dummy, rc); |
281 | 275 | ||
282 | kfree(fw_buffer); | 276 | kfree(fw_buffer); |
283 | } else { | 277 | } else { |
284 | sms_err("failed to allocate firmware buffer"); | 278 | pr_err("failed to allocate firmware buffer\n"); |
285 | rc = -ENOMEM; | 279 | rc = -ENOMEM; |
286 | } | 280 | } |
287 | sms_info("read FW %s, size=%zu", fw_filename, fw->size); | 281 | pr_debug("read FW %s, size=%zu\n", fw_filename, fw->size); |
288 | 282 | ||
289 | release_firmware(fw); | 283 | release_firmware(fw); |
290 | 284 | ||
@@ -300,7 +294,7 @@ static void smsusb1_detectmode(void *context, int *mode) | |||
300 | 294 | ||
301 | if (!product_string) { | 295 | if (!product_string) { |
302 | product_string = "none"; | 296 | product_string = "none"; |
303 | sms_err("product string not found"); | 297 | pr_err("product string not found\n"); |
304 | } else if (strstr(product_string, "DVBH")) | 298 | } else if (strstr(product_string, "DVBH")) |
305 | *mode = 1; | 299 | *mode = 1; |
306 | else if (strstr(product_string, "BDA")) | 300 | else if (strstr(product_string, "BDA")) |
@@ -310,7 +304,7 @@ static void smsusb1_detectmode(void *context, int *mode) | |||
310 | else if (strstr(product_string, "TDMB")) | 304 | else if (strstr(product_string, "TDMB")) |
311 | *mode = 2; | 305 | *mode = 2; |
312 | 306 | ||
313 | sms_info("%d \"%s\"", *mode, product_string); | 307 | pr_debug("%d \"%s\"\n", *mode, product_string); |
314 | } | 308 | } |
315 | 309 | ||
316 | static int smsusb1_setmode(void *context, int mode) | 310 | static int smsusb1_setmode(void *context, int mode) |
@@ -319,7 +313,7 @@ static int smsusb1_setmode(void *context, int mode) | |||
319 | sizeof(struct sms_msg_hdr), 0 }; | 313 | sizeof(struct sms_msg_hdr), 0 }; |
320 | 314 | ||
321 | if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) { | 315 | if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) { |
322 | sms_err("invalid firmware id specified %d", mode); | 316 | pr_err("invalid firmware id specified %d\n", mode); |
323 | return -EINVAL; | 317 | return -EINVAL; |
324 | } | 318 | } |
325 | 319 | ||
@@ -339,25 +333,61 @@ static void smsusb_term_device(struct usb_interface *intf) | |||
339 | if (dev->coredev) | 333 | if (dev->coredev) |
340 | smscore_unregister_device(dev->coredev); | 334 | smscore_unregister_device(dev->coredev); |
341 | 335 | ||
342 | sms_info("device 0x%p destroyed", dev); | 336 | pr_debug("device 0x%p destroyed\n", dev); |
343 | kfree(dev); | 337 | kfree(dev); |
344 | } | 338 | } |
345 | 339 | ||
346 | usb_set_intfdata(intf, NULL); | 340 | usb_set_intfdata(intf, NULL); |
347 | } | 341 | } |
348 | 342 | ||
343 | static void *siano_media_device_register(struct smsusb_device_t *dev, | ||
344 | int board_id) | ||
345 | { | ||
346 | #ifdef CONFIG_MEDIA_CONTROLLER_DVB | ||
347 | struct media_device *mdev; | ||
348 | struct usb_device *udev = dev->udev; | ||
349 | struct sms_board *board = sms_get_board(board_id); | ||
350 | int ret; | ||
351 | |||
352 | mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); | ||
353 | if (!mdev) | ||
354 | return NULL; | ||
355 | |||
356 | mdev->dev = &udev->dev; | ||
357 | strlcpy(mdev->model, board->name, sizeof(mdev->model)); | ||
358 | if (udev->serial) | ||
359 | strlcpy(mdev->serial, udev->serial, sizeof(mdev->serial)); | ||
360 | strcpy(mdev->bus_info, udev->devpath); | ||
361 | mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice); | ||
362 | mdev->driver_version = LINUX_VERSION_CODE; | ||
363 | |||
364 | ret = media_device_register(mdev); | ||
365 | if (ret) { | ||
366 | pr_err("Couldn't create a media device. Error: %d\n", | ||
367 | ret); | ||
368 | kfree(mdev); | ||
369 | return NULL; | ||
370 | } | ||
371 | |||
372 | pr_info("media controller created\n"); | ||
373 | |||
374 | return mdev; | ||
375 | #else | ||
376 | return NULL; | ||
377 | #endif | ||
378 | } | ||
379 | |||
349 | static int smsusb_init_device(struct usb_interface *intf, int board_id) | 380 | static int smsusb_init_device(struct usb_interface *intf, int board_id) |
350 | { | 381 | { |
351 | struct smsdevice_params_t params; | 382 | struct smsdevice_params_t params; |
352 | struct smsusb_device_t *dev; | 383 | struct smsusb_device_t *dev; |
384 | void *mdev; | ||
353 | int i, rc; | 385 | int i, rc; |
354 | 386 | ||
355 | /* create device object */ | 387 | /* create device object */ |
356 | dev = kzalloc(sizeof(struct smsusb_device_t), GFP_KERNEL); | 388 | dev = kzalloc(sizeof(struct smsusb_device_t), GFP_KERNEL); |
357 | if (!dev) { | 389 | if (!dev) |
358 | sms_err("kzalloc(sizeof(struct smsusb_device_t) failed"); | ||
359 | return -ENOMEM; | 390 | return -ENOMEM; |
360 | } | ||
361 | 391 | ||
362 | memset(¶ms, 0, sizeof(params)); | 392 | memset(¶ms, 0, sizeof(params)); |
363 | usb_set_intfdata(intf, dev); | 393 | usb_set_intfdata(intf, dev); |
@@ -374,7 +404,7 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id) | |||
374 | params.detectmode_handler = smsusb1_detectmode; | 404 | params.detectmode_handler = smsusb1_detectmode; |
375 | break; | 405 | break; |
376 | case SMS_UNKNOWN_TYPE: | 406 | case SMS_UNKNOWN_TYPE: |
377 | sms_err("Unspecified sms device type!"); | 407 | pr_err("Unspecified sms device type!\n"); |
378 | /* fall-thru */ | 408 | /* fall-thru */ |
379 | default: | 409 | default: |
380 | dev->buffer_size = USB2_BUFFER_SIZE; | 410 | dev->buffer_size = USB2_BUFFER_SIZE; |
@@ -393,7 +423,7 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id) | |||
393 | dev->out_ep = intf->cur_altsetting->endpoint[i].desc.bEndpointAddress; | 423 | dev->out_ep = intf->cur_altsetting->endpoint[i].desc.bEndpointAddress; |
394 | } | 424 | } |
395 | 425 | ||
396 | sms_info("in_ep = %02x, out_ep = %02x", | 426 | pr_debug("in_ep = %02x, out_ep = %02x\n", |
397 | dev->in_ep, dev->out_ep); | 427 | dev->in_ep, dev->out_ep); |
398 | 428 | ||
399 | params.device = &dev->udev->dev; | 429 | params.device = &dev->udev->dev; |
@@ -403,11 +433,17 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id) | |||
403 | params.context = dev; | 433 | params.context = dev; |
404 | usb_make_path(dev->udev, params.devpath, sizeof(params.devpath)); | 434 | usb_make_path(dev->udev, params.devpath, sizeof(params.devpath)); |
405 | 435 | ||
436 | mdev = siano_media_device_register(dev, board_id); | ||
437 | |||
406 | /* register in smscore */ | 438 | /* register in smscore */ |
407 | rc = smscore_register_device(¶ms, &dev->coredev); | 439 | rc = smscore_register_device(¶ms, &dev->coredev, mdev); |
408 | if (rc < 0) { | 440 | if (rc < 0) { |
409 | sms_err("smscore_register_device(...) failed, rc %d", rc); | 441 | pr_err("smscore_register_device(...) failed, rc %d\n", rc); |
410 | smsusb_term_device(intf); | 442 | smsusb_term_device(intf); |
443 | #ifdef CONFIG_MEDIA_CONTROLLER_DVB | ||
444 | media_device_unregister(mdev); | ||
445 | #endif | ||
446 | kfree(mdev); | ||
411 | return rc; | 447 | return rc; |
412 | } | 448 | } |
413 | 449 | ||
@@ -421,10 +457,10 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id) | |||
421 | usb_init_urb(&dev->surbs[i].urb); | 457 | usb_init_urb(&dev->surbs[i].urb); |
422 | } | 458 | } |
423 | 459 | ||
424 | sms_info("smsusb_start_streaming(...)."); | 460 | pr_debug("smsusb_start_streaming(...).\n"); |
425 | rc = smsusb_start_streaming(dev); | 461 | rc = smsusb_start_streaming(dev); |
426 | if (rc < 0) { | 462 | if (rc < 0) { |
427 | sms_err("smsusb_start_streaming(...) failed"); | 463 | pr_err("smsusb_start_streaming(...) failed\n"); |
428 | smsusb_term_device(intf); | 464 | smsusb_term_device(intf); |
429 | return rc; | 465 | return rc; |
430 | } | 466 | } |
@@ -433,12 +469,12 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id) | |||
433 | 469 | ||
434 | rc = smscore_start_device(dev->coredev); | 470 | rc = smscore_start_device(dev->coredev); |
435 | if (rc < 0) { | 471 | if (rc < 0) { |
436 | sms_err("smscore_start_device(...) failed"); | 472 | pr_err("smscore_start_device(...) failed\n"); |
437 | smsusb_term_device(intf); | 473 | smsusb_term_device(intf); |
438 | return rc; | 474 | return rc; |
439 | } | 475 | } |
440 | 476 | ||
441 | sms_info("device 0x%p created", dev); | 477 | pr_debug("device 0x%p created\n", dev); |
442 | 478 | ||
443 | return rc; | 479 | return rc; |
444 | } | 480 | } |
@@ -450,13 +486,13 @@ static int smsusb_probe(struct usb_interface *intf, | |||
450 | char devpath[32]; | 486 | char devpath[32]; |
451 | int i, rc; | 487 | int i, rc; |
452 | 488 | ||
453 | sms_info("board id=%lu, interface number %d", | 489 | pr_info("board id=%lu, interface number %d\n", |
454 | id->driver_info, | 490 | id->driver_info, |
455 | intf->cur_altsetting->desc.bInterfaceNumber); | 491 | intf->cur_altsetting->desc.bInterfaceNumber); |
456 | 492 | ||
457 | if (sms_get_board(id->driver_info)->intf_num != | 493 | if (sms_get_board(id->driver_info)->intf_num != |
458 | intf->cur_altsetting->desc.bInterfaceNumber) { | 494 | intf->cur_altsetting->desc.bInterfaceNumber) { |
459 | sms_debug("interface %d won't be used. Expecting interface %d to popup", | 495 | pr_debug("interface %d won't be used. Expecting interface %d to popup\n", |
460 | intf->cur_altsetting->desc.bInterfaceNumber, | 496 | intf->cur_altsetting->desc.bInterfaceNumber, |
461 | sms_get_board(id->driver_info)->intf_num); | 497 | sms_get_board(id->driver_info)->intf_num); |
462 | return -ENODEV; | 498 | return -ENODEV; |
@@ -467,15 +503,15 @@ static int smsusb_probe(struct usb_interface *intf, | |||
467 | intf->cur_altsetting->desc.bInterfaceNumber, | 503 | intf->cur_altsetting->desc.bInterfaceNumber, |
468 | 0); | 504 | 0); |
469 | if (rc < 0) { | 505 | if (rc < 0) { |
470 | sms_err("usb_set_interface failed, rc %d", rc); | 506 | pr_err("usb_set_interface failed, rc %d\n", rc); |
471 | return rc; | 507 | return rc; |
472 | } | 508 | } |
473 | } | 509 | } |
474 | 510 | ||
475 | sms_info("smsusb_probe %d", | 511 | pr_debug("smsusb_probe %d\n", |
476 | intf->cur_altsetting->desc.bInterfaceNumber); | 512 | intf->cur_altsetting->desc.bInterfaceNumber); |
477 | for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) { | 513 | for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) { |
478 | sms_info("endpoint %d %02x %02x %d", i, | 514 | pr_debug("endpoint %d %02x %02x %d\n", i, |
479 | intf->cur_altsetting->endpoint[i].desc.bEndpointAddress, | 515 | intf->cur_altsetting->endpoint[i].desc.bEndpointAddress, |
480 | intf->cur_altsetting->endpoint[i].desc.bmAttributes, | 516 | intf->cur_altsetting->endpoint[i].desc.bmAttributes, |
481 | intf->cur_altsetting->endpoint[i].desc.wMaxPacketSize); | 517 | intf->cur_altsetting->endpoint[i].desc.wMaxPacketSize); |
@@ -489,7 +525,7 @@ static int smsusb_probe(struct usb_interface *intf, | |||
489 | } | 525 | } |
490 | if ((udev->actconfig->desc.bNumInterfaces == 2) && | 526 | if ((udev->actconfig->desc.bNumInterfaces == 2) && |
491 | (intf->cur_altsetting->desc.bInterfaceNumber == 0)) { | 527 | (intf->cur_altsetting->desc.bInterfaceNumber == 0)) { |
492 | sms_debug("rom interface 0 is not used"); | 528 | pr_debug("rom interface 0 is not used\n"); |
493 | return -ENODEV; | 529 | return -ENODEV; |
494 | } | 530 | } |
495 | 531 | ||
@@ -498,23 +534,25 @@ static int smsusb_probe(struct usb_interface *intf, | |||
498 | 534 | ||
499 | snprintf(devpath, sizeof(devpath), "usb\\%d-%s", | 535 | snprintf(devpath, sizeof(devpath), "usb\\%d-%s", |
500 | udev->bus->busnum, udev->devpath); | 536 | udev->bus->busnum, udev->devpath); |
501 | sms_info("stellar device in cold state was found at %s.", devpath); | 537 | pr_info("stellar device in cold state was found at %s.\n", |
538 | devpath); | ||
502 | rc = smsusb1_load_firmware( | 539 | rc = smsusb1_load_firmware( |
503 | udev, smscore_registry_getmode(devpath), | 540 | udev, smscore_registry_getmode(devpath), |
504 | id->driver_info); | 541 | id->driver_info); |
505 | 542 | ||
506 | /* This device will reset and gain another USB ID */ | 543 | /* This device will reset and gain another USB ID */ |
507 | if (!rc) | 544 | if (!rc) |
508 | sms_info("stellar device now in warm state"); | 545 | pr_info("stellar device now in warm state\n"); |
509 | else | 546 | else |
510 | sms_err("Failed to put stellar in warm state. Error: %d", rc); | 547 | pr_err("Failed to put stellar in warm state. Error: %d\n", |
548 | rc); | ||
511 | 549 | ||
512 | return rc; | 550 | return rc; |
513 | } else { | 551 | } else { |
514 | rc = smsusb_init_device(intf, id->driver_info); | 552 | rc = smsusb_init_device(intf, id->driver_info); |
515 | } | 553 | } |
516 | 554 | ||
517 | sms_info("Device initialized with return code %d", rc); | 555 | pr_info("Device initialized with return code %d\n", rc); |
518 | sms_board_load_modules(id->driver_info); | 556 | sms_board_load_modules(id->driver_info); |
519 | return rc; | 557 | return rc; |
520 | } | 558 | } |
diff --git a/drivers/media/usb/stk1160/stk1160-v4l.c b/drivers/media/usb/stk1160/stk1160-v4l.c index 65a326c5128f..749ad5603c9e 100644 --- a/drivers/media/usb/stk1160/stk1160-v4l.c +++ b/drivers/media/usb/stk1160/stk1160-v4l.c | |||
@@ -240,6 +240,11 @@ static int stk1160_stop_streaming(struct stk1160 *dev) | |||
240 | if (mutex_lock_interruptible(&dev->v4l_lock)) | 240 | if (mutex_lock_interruptible(&dev->v4l_lock)) |
241 | return -ERESTARTSYS; | 241 | return -ERESTARTSYS; |
242 | 242 | ||
243 | /* | ||
244 | * Once URBs are cancelled, the URB complete handler | ||
245 | * won't be running. This is required to safely release the | ||
246 | * current buffer (dev->isoc_ctl.buf). | ||
247 | */ | ||
243 | stk1160_cancel_isoc(dev); | 248 | stk1160_cancel_isoc(dev); |
244 | 249 | ||
245 | /* | 250 | /* |
@@ -620,8 +625,16 @@ void stk1160_clear_queue(struct stk1160 *dev) | |||
620 | stk1160_info("buffer [%p/%d] aborted\n", | 625 | stk1160_info("buffer [%p/%d] aborted\n", |
621 | buf, buf->vb.v4l2_buf.index); | 626 | buf, buf->vb.v4l2_buf.index); |
622 | } | 627 | } |
623 | /* It's important to clear current buffer */ | 628 | |
624 | dev->isoc_ctl.buf = NULL; | 629 | /* It's important to release the current buffer */ |
630 | if (dev->isoc_ctl.buf) { | ||
631 | buf = dev->isoc_ctl.buf; | ||
632 | dev->isoc_ctl.buf = NULL; | ||
633 | |||
634 | vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); | ||
635 | stk1160_info("buffer [%p/%d] aborted\n", | ||
636 | buf, buf->vb.v4l2_buf.index); | ||
637 | } | ||
625 | spin_unlock_irqrestore(&dev->buf_lock, flags); | 638 | spin_unlock_irqrestore(&dev->buf_lock, flags); |
626 | } | 639 | } |
627 | 640 | ||
diff --git a/drivers/media/usb/stkwebcam/stk-webcam.c b/drivers/media/usb/stkwebcam/stk-webcam.c index e08fa587332f..c21c4c004f97 100644 --- a/drivers/media/usb/stkwebcam/stk-webcam.c +++ b/drivers/media/usb/stkwebcam/stk-webcam.c | |||
@@ -556,10 +556,8 @@ static int stk_free_sio_buffers(struct stk_camera *dev) | |||
556 | nbufs = dev->n_sbufs; | 556 | nbufs = dev->n_sbufs; |
557 | dev->n_sbufs = 0; | 557 | dev->n_sbufs = 0; |
558 | spin_unlock_irqrestore(&dev->spinlock, flags); | 558 | spin_unlock_irqrestore(&dev->spinlock, flags); |
559 | for (i = 0; i < nbufs; i++) { | 559 | for (i = 0; i < nbufs; i++) |
560 | if (dev->sio_bufs[i].buffer != NULL) | 560 | vfree(dev->sio_bufs[i].buffer); |
561 | vfree(dev->sio_bufs[i].buffer); | ||
562 | } | ||
563 | kfree(dev->sio_bufs); | 561 | kfree(dev->sio_bufs); |
564 | dev->sio_bufs = NULL; | 562 | dev->sio_bufs = NULL; |
565 | return 0; | 563 | return 0; |
diff --git a/drivers/media/usb/tm6000/tm6000-video.c b/drivers/media/usb/tm6000/tm6000-video.c index 0f14d3ccc7b4..77ce9efe1f24 100644 --- a/drivers/media/usb/tm6000/tm6000-video.c +++ b/drivers/media/usb/tm6000/tm6000-video.c | |||
@@ -1576,7 +1576,7 @@ static struct video_device tm6000_template = { | |||
1576 | .name = "tm6000", | 1576 | .name = "tm6000", |
1577 | .fops = &tm6000_fops, | 1577 | .fops = &tm6000_fops, |
1578 | .ioctl_ops = &video_ioctl_ops, | 1578 | .ioctl_ops = &video_ioctl_ops, |
1579 | .release = video_device_release, | 1579 | .release = video_device_release_empty, |
1580 | .tvnorms = TM6000_STD, | 1580 | .tvnorms = TM6000_STD, |
1581 | }; | 1581 | }; |
1582 | 1582 | ||
@@ -1609,25 +1609,19 @@ static struct video_device tm6000_radio_template = { | |||
1609 | * ------------------------------------------------------------------ | 1609 | * ------------------------------------------------------------------ |
1610 | */ | 1610 | */ |
1611 | 1611 | ||
1612 | static struct video_device *vdev_init(struct tm6000_core *dev, | 1612 | static void vdev_init(struct tm6000_core *dev, |
1613 | struct video_device *vfd, | ||
1613 | const struct video_device | 1614 | const struct video_device |
1614 | *template, const char *type_name) | 1615 | *template, const char *type_name) |
1615 | { | 1616 | { |
1616 | struct video_device *vfd; | ||
1617 | |||
1618 | vfd = video_device_alloc(); | ||
1619 | if (NULL == vfd) | ||
1620 | return NULL; | ||
1621 | |||
1622 | *vfd = *template; | 1617 | *vfd = *template; |
1623 | vfd->v4l2_dev = &dev->v4l2_dev; | 1618 | vfd->v4l2_dev = &dev->v4l2_dev; |
1624 | vfd->release = video_device_release; | 1619 | vfd->release = video_device_release_empty; |
1625 | vfd->lock = &dev->lock; | 1620 | vfd->lock = &dev->lock; |
1626 | 1621 | ||
1627 | snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name); | 1622 | snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name); |
1628 | 1623 | ||
1629 | video_set_drvdata(vfd, dev); | 1624 | video_set_drvdata(vfd, dev); |
1630 | return vfd; | ||
1631 | } | 1625 | } |
1632 | 1626 | ||
1633 | int tm6000_v4l2_register(struct tm6000_core *dev) | 1627 | int tm6000_v4l2_register(struct tm6000_core *dev) |
@@ -1658,62 +1652,46 @@ int tm6000_v4l2_register(struct tm6000_core *dev) | |||
1658 | if (ret) | 1652 | if (ret) |
1659 | goto free_ctrl; | 1653 | goto free_ctrl; |
1660 | 1654 | ||
1661 | dev->vfd = vdev_init(dev, &tm6000_template, "video"); | 1655 | vdev_init(dev, &dev->vfd, &tm6000_template, "video"); |
1662 | 1656 | ||
1663 | if (!dev->vfd) { | 1657 | dev->vfd.ctrl_handler = &dev->ctrl_handler; |
1664 | printk(KERN_INFO "%s: can't register video device\n", | ||
1665 | dev->name); | ||
1666 | ret = -ENOMEM; | ||
1667 | goto free_ctrl; | ||
1668 | } | ||
1669 | dev->vfd->ctrl_handler = &dev->ctrl_handler; | ||
1670 | 1658 | ||
1671 | /* init video dma queues */ | 1659 | /* init video dma queues */ |
1672 | INIT_LIST_HEAD(&dev->vidq.active); | 1660 | INIT_LIST_HEAD(&dev->vidq.active); |
1673 | INIT_LIST_HEAD(&dev->vidq.queued); | 1661 | INIT_LIST_HEAD(&dev->vidq.queued); |
1674 | 1662 | ||
1675 | ret = video_register_device(dev->vfd, VFL_TYPE_GRABBER, video_nr); | 1663 | ret = video_register_device(&dev->vfd, VFL_TYPE_GRABBER, video_nr); |
1676 | 1664 | ||
1677 | if (ret < 0) { | 1665 | if (ret < 0) { |
1678 | printk(KERN_INFO "%s: can't register video device\n", | 1666 | printk(KERN_INFO "%s: can't register video device\n", |
1679 | dev->name); | 1667 | dev->name); |
1680 | video_device_release(dev->vfd); | ||
1681 | dev->vfd = NULL; | ||
1682 | goto free_ctrl; | 1668 | goto free_ctrl; |
1683 | } | 1669 | } |
1684 | 1670 | ||
1685 | printk(KERN_INFO "%s: registered device %s\n", | 1671 | printk(KERN_INFO "%s: registered device %s\n", |
1686 | dev->name, video_device_node_name(dev->vfd)); | 1672 | dev->name, video_device_node_name(&dev->vfd)); |
1687 | 1673 | ||
1688 | if (dev->caps.has_radio) { | 1674 | if (dev->caps.has_radio) { |
1689 | dev->radio_dev = vdev_init(dev, &tm6000_radio_template, | 1675 | vdev_init(dev, &dev->radio_dev, &tm6000_radio_template, |
1690 | "radio"); | 1676 | "radio"); |
1691 | if (!dev->radio_dev) { | 1677 | dev->radio_dev.ctrl_handler = &dev->radio_ctrl_handler; |
1692 | printk(KERN_INFO "%s: can't register radio device\n", | 1678 | ret = video_register_device(&dev->radio_dev, VFL_TYPE_RADIO, |
1693 | dev->name); | ||
1694 | ret = -ENXIO; | ||
1695 | goto unreg_video; | ||
1696 | } | ||
1697 | |||
1698 | dev->radio_dev->ctrl_handler = &dev->radio_ctrl_handler; | ||
1699 | ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO, | ||
1700 | radio_nr); | 1679 | radio_nr); |
1701 | if (ret < 0) { | 1680 | if (ret < 0) { |
1702 | printk(KERN_INFO "%s: can't register radio device\n", | 1681 | printk(KERN_INFO "%s: can't register radio device\n", |
1703 | dev->name); | 1682 | dev->name); |
1704 | video_device_release(dev->radio_dev); | ||
1705 | goto unreg_video; | 1683 | goto unreg_video; |
1706 | } | 1684 | } |
1707 | 1685 | ||
1708 | printk(KERN_INFO "%s: registered device %s\n", | 1686 | printk(KERN_INFO "%s: registered device %s\n", |
1709 | dev->name, video_device_node_name(dev->radio_dev)); | 1687 | dev->name, video_device_node_name(&dev->radio_dev)); |
1710 | } | 1688 | } |
1711 | 1689 | ||
1712 | printk(KERN_INFO "Trident TVMaster TM5600/TM6000/TM6010 USB2 board (Load status: %d)\n", ret); | 1690 | printk(KERN_INFO "Trident TVMaster TM5600/TM6000/TM6010 USB2 board (Load status: %d)\n", ret); |
1713 | return ret; | 1691 | return ret; |
1714 | 1692 | ||
1715 | unreg_video: | 1693 | unreg_video: |
1716 | video_unregister_device(dev->vfd); | 1694 | video_unregister_device(&dev->vfd); |
1717 | free_ctrl: | 1695 | free_ctrl: |
1718 | v4l2_ctrl_handler_free(&dev->ctrl_handler); | 1696 | v4l2_ctrl_handler_free(&dev->ctrl_handler); |
1719 | v4l2_ctrl_handler_free(&dev->radio_ctrl_handler); | 1697 | v4l2_ctrl_handler_free(&dev->radio_ctrl_handler); |
@@ -1722,19 +1700,12 @@ free_ctrl: | |||
1722 | 1700 | ||
1723 | int tm6000_v4l2_unregister(struct tm6000_core *dev) | 1701 | int tm6000_v4l2_unregister(struct tm6000_core *dev) |
1724 | { | 1702 | { |
1725 | video_unregister_device(dev->vfd); | 1703 | video_unregister_device(&dev->vfd); |
1726 | 1704 | ||
1727 | /* if URB buffers are still allocated free them now */ | 1705 | /* if URB buffers are still allocated free them now */ |
1728 | tm6000_free_urb_buffers(dev); | 1706 | tm6000_free_urb_buffers(dev); |
1729 | 1707 | ||
1730 | if (dev->radio_dev) { | 1708 | video_unregister_device(&dev->radio_dev); |
1731 | if (video_is_registered(dev->radio_dev)) | ||
1732 | video_unregister_device(dev->radio_dev); | ||
1733 | else | ||
1734 | video_device_release(dev->radio_dev); | ||
1735 | dev->radio_dev = NULL; | ||
1736 | } | ||
1737 | |||
1738 | return 0; | 1709 | return 0; |
1739 | } | 1710 | } |
1740 | 1711 | ||
diff --git a/drivers/media/usb/tm6000/tm6000.h b/drivers/media/usb/tm6000/tm6000.h index 08bd0740dd23..f2127944776f 100644 --- a/drivers/media/usb/tm6000/tm6000.h +++ b/drivers/media/usb/tm6000/tm6000.h | |||
@@ -220,8 +220,8 @@ struct tm6000_core { | |||
220 | struct tm6000_fh *resources; /* Points to fh that is streaming */ | 220 | struct tm6000_fh *resources; /* Points to fh that is streaming */ |
221 | bool is_res_read; | 221 | bool is_res_read; |
222 | 222 | ||
223 | struct video_device *vfd; | 223 | struct video_device vfd; |
224 | struct video_device *radio_dev; | 224 | struct video_device radio_dev; |
225 | struct tm6000_dmaqueue vidq; | 225 | struct tm6000_dmaqueue vidq; |
226 | struct v4l2_device v4l2_dev; | 226 | struct v4l2_device v4l2_dev; |
227 | struct v4l2_ctrl_handler ctrl_handler; | 227 | struct v4l2_ctrl_handler ctrl_handler; |
diff --git a/drivers/media/usb/usbvision/usbvision-video.c b/drivers/media/usb/usbvision/usbvision-video.c index cd2fbf11e3b4..12b403e78d52 100644 --- a/drivers/media/usb/usbvision/usbvision-video.c +++ b/drivers/media/usb/usbvision/usbvision-video.c | |||
@@ -471,7 +471,7 @@ static int vidioc_g_register(struct file *file, void *priv, | |||
471 | /* NT100x has a 8-bit register space */ | 471 | /* NT100x has a 8-bit register space */ |
472 | err_code = usbvision_read_reg(usbvision, reg->reg&0xff); | 472 | err_code = usbvision_read_reg(usbvision, reg->reg&0xff); |
473 | if (err_code < 0) { | 473 | if (err_code < 0) { |
474 | dev_err(&usbvision->vdev->dev, | 474 | dev_err(&usbvision->vdev.dev, |
475 | "%s: VIDIOC_DBG_G_REGISTER failed: error %d\n", | 475 | "%s: VIDIOC_DBG_G_REGISTER failed: error %d\n", |
476 | __func__, err_code); | 476 | __func__, err_code); |
477 | return err_code; | 477 | return err_code; |
@@ -490,7 +490,7 @@ static int vidioc_s_register(struct file *file, void *priv, | |||
490 | /* NT100x has a 8-bit register space */ | 490 | /* NT100x has a 8-bit register space */ |
491 | err_code = usbvision_write_reg(usbvision, reg->reg & 0xff, reg->val); | 491 | err_code = usbvision_write_reg(usbvision, reg->reg & 0xff, reg->val); |
492 | if (err_code < 0) { | 492 | if (err_code < 0) { |
493 | dev_err(&usbvision->vdev->dev, | 493 | dev_err(&usbvision->vdev.dev, |
494 | "%s: VIDIOC_DBG_S_REGISTER failed: error %d\n", | 494 | "%s: VIDIOC_DBG_S_REGISTER failed: error %d\n", |
495 | __func__, err_code); | 495 | __func__, err_code); |
496 | return err_code; | 496 | return err_code; |
@@ -1157,7 +1157,7 @@ static int usbvision_radio_open(struct file *file) | |||
1157 | if (mutex_lock_interruptible(&usbvision->v4l2_lock)) | 1157 | if (mutex_lock_interruptible(&usbvision->v4l2_lock)) |
1158 | return -ERESTARTSYS; | 1158 | return -ERESTARTSYS; |
1159 | if (usbvision->user) { | 1159 | if (usbvision->user) { |
1160 | dev_err(&usbvision->rdev->dev, | 1160 | dev_err(&usbvision->rdev.dev, |
1161 | "%s: Someone tried to open an already opened USBVision Radio!\n", | 1161 | "%s: Someone tried to open an already opened USBVision Radio!\n", |
1162 | __func__); | 1162 | __func__); |
1163 | err_code = -EBUSY; | 1163 | err_code = -EBUSY; |
@@ -1280,7 +1280,7 @@ static struct video_device usbvision_video_template = { | |||
1280 | .fops = &usbvision_fops, | 1280 | .fops = &usbvision_fops, |
1281 | .ioctl_ops = &usbvision_ioctl_ops, | 1281 | .ioctl_ops = &usbvision_ioctl_ops, |
1282 | .name = "usbvision-video", | 1282 | .name = "usbvision-video", |
1283 | .release = video_device_release, | 1283 | .release = video_device_release_empty, |
1284 | .tvnorms = USBVISION_NORMS, | 1284 | .tvnorms = USBVISION_NORMS, |
1285 | }; | 1285 | }; |
1286 | 1286 | ||
@@ -1312,58 +1312,46 @@ static const struct v4l2_ioctl_ops usbvision_radio_ioctl_ops = { | |||
1312 | static struct video_device usbvision_radio_template = { | 1312 | static struct video_device usbvision_radio_template = { |
1313 | .fops = &usbvision_radio_fops, | 1313 | .fops = &usbvision_radio_fops, |
1314 | .name = "usbvision-radio", | 1314 | .name = "usbvision-radio", |
1315 | .release = video_device_release, | 1315 | .release = video_device_release_empty, |
1316 | .ioctl_ops = &usbvision_radio_ioctl_ops, | 1316 | .ioctl_ops = &usbvision_radio_ioctl_ops, |
1317 | }; | 1317 | }; |
1318 | 1318 | ||
1319 | 1319 | ||
1320 | static struct video_device *usbvision_vdev_init(struct usb_usbvision *usbvision, | 1320 | static void usbvision_vdev_init(struct usb_usbvision *usbvision, |
1321 | struct video_device *vdev_template, | 1321 | struct video_device *vdev, |
1322 | char *name) | 1322 | const struct video_device *vdev_template, |
1323 | const char *name) | ||
1323 | { | 1324 | { |
1324 | struct usb_device *usb_dev = usbvision->dev; | 1325 | struct usb_device *usb_dev = usbvision->dev; |
1325 | struct video_device *vdev; | ||
1326 | 1326 | ||
1327 | if (usb_dev == NULL) { | 1327 | if (usb_dev == NULL) { |
1328 | dev_err(&usbvision->dev->dev, | 1328 | dev_err(&usbvision->dev->dev, |
1329 | "%s: usbvision->dev is not set\n", __func__); | 1329 | "%s: usbvision->dev is not set\n", __func__); |
1330 | return NULL; | 1330 | return; |
1331 | } | 1331 | } |
1332 | 1332 | ||
1333 | vdev = video_device_alloc(); | ||
1334 | if (NULL == vdev) | ||
1335 | return NULL; | ||
1336 | *vdev = *vdev_template; | 1333 | *vdev = *vdev_template; |
1337 | vdev->lock = &usbvision->v4l2_lock; | 1334 | vdev->lock = &usbvision->v4l2_lock; |
1338 | vdev->v4l2_dev = &usbvision->v4l2_dev; | 1335 | vdev->v4l2_dev = &usbvision->v4l2_dev; |
1339 | snprintf(vdev->name, sizeof(vdev->name), "%s", name); | 1336 | snprintf(vdev->name, sizeof(vdev->name), "%s", name); |
1340 | video_set_drvdata(vdev, usbvision); | 1337 | video_set_drvdata(vdev, usbvision); |
1341 | return vdev; | ||
1342 | } | 1338 | } |
1343 | 1339 | ||
1344 | /* unregister video4linux devices */ | 1340 | /* unregister video4linux devices */ |
1345 | static void usbvision_unregister_video(struct usb_usbvision *usbvision) | 1341 | static void usbvision_unregister_video(struct usb_usbvision *usbvision) |
1346 | { | 1342 | { |
1347 | /* Radio Device: */ | 1343 | /* Radio Device: */ |
1348 | if (usbvision->rdev) { | 1344 | if (video_is_registered(&usbvision->rdev)) { |
1349 | PDEBUG(DBG_PROBE, "unregister %s [v4l2]", | 1345 | PDEBUG(DBG_PROBE, "unregister %s [v4l2]", |
1350 | video_device_node_name(usbvision->rdev)); | 1346 | video_device_node_name(&usbvision->rdev)); |
1351 | if (video_is_registered(usbvision->rdev)) | 1347 | video_unregister_device(&usbvision->rdev); |
1352 | video_unregister_device(usbvision->rdev); | ||
1353 | else | ||
1354 | video_device_release(usbvision->rdev); | ||
1355 | usbvision->rdev = NULL; | ||
1356 | } | 1348 | } |
1357 | 1349 | ||
1358 | /* Video Device: */ | 1350 | /* Video Device: */ |
1359 | if (usbvision->vdev) { | 1351 | if (video_is_registered(&usbvision->vdev)) { |
1360 | PDEBUG(DBG_PROBE, "unregister %s [v4l2]", | 1352 | PDEBUG(DBG_PROBE, "unregister %s [v4l2]", |
1361 | video_device_node_name(usbvision->vdev)); | 1353 | video_device_node_name(&usbvision->vdev)); |
1362 | if (video_is_registered(usbvision->vdev)) | 1354 | video_unregister_device(&usbvision->vdev); |
1363 | video_unregister_device(usbvision->vdev); | ||
1364 | else | ||
1365 | video_device_release(usbvision->vdev); | ||
1366 | usbvision->vdev = NULL; | ||
1367 | } | 1355 | } |
1368 | } | 1356 | } |
1369 | 1357 | ||
@@ -1371,28 +1359,22 @@ static void usbvision_unregister_video(struct usb_usbvision *usbvision) | |||
1371 | static int usbvision_register_video(struct usb_usbvision *usbvision) | 1359 | static int usbvision_register_video(struct usb_usbvision *usbvision) |
1372 | { | 1360 | { |
1373 | /* Video Device: */ | 1361 | /* Video Device: */ |
1374 | usbvision->vdev = usbvision_vdev_init(usbvision, | 1362 | usbvision_vdev_init(usbvision, &usbvision->vdev, |
1375 | &usbvision_video_template, | 1363 | &usbvision_video_template, "USBVision Video"); |
1376 | "USBVision Video"); | 1364 | if (video_register_device(&usbvision->vdev, VFL_TYPE_GRABBER, video_nr) < 0) |
1377 | if (usbvision->vdev == NULL) | ||
1378 | goto err_exit; | ||
1379 | if (video_register_device(usbvision->vdev, VFL_TYPE_GRABBER, video_nr) < 0) | ||
1380 | goto err_exit; | 1365 | goto err_exit; |
1381 | printk(KERN_INFO "USBVision[%d]: registered USBVision Video device %s [v4l2]\n", | 1366 | printk(KERN_INFO "USBVision[%d]: registered USBVision Video device %s [v4l2]\n", |
1382 | usbvision->nr, video_device_node_name(usbvision->vdev)); | 1367 | usbvision->nr, video_device_node_name(&usbvision->vdev)); |
1383 | 1368 | ||
1384 | /* Radio Device: */ | 1369 | /* Radio Device: */ |
1385 | if (usbvision_device_data[usbvision->dev_model].radio) { | 1370 | if (usbvision_device_data[usbvision->dev_model].radio) { |
1386 | /* usbvision has radio */ | 1371 | /* usbvision has radio */ |
1387 | usbvision->rdev = usbvision_vdev_init(usbvision, | 1372 | usbvision_vdev_init(usbvision, &usbvision->rdev, |
1388 | &usbvision_radio_template, | 1373 | &usbvision_radio_template, "USBVision Radio"); |
1389 | "USBVision Radio"); | 1374 | if (video_register_device(&usbvision->rdev, VFL_TYPE_RADIO, radio_nr) < 0) |
1390 | if (usbvision->rdev == NULL) | ||
1391 | goto err_exit; | ||
1392 | if (video_register_device(usbvision->rdev, VFL_TYPE_RADIO, radio_nr) < 0) | ||
1393 | goto err_exit; | 1375 | goto err_exit; |
1394 | printk(KERN_INFO "USBVision[%d]: registered USBVision Radio device %s [v4l2]\n", | 1376 | printk(KERN_INFO "USBVision[%d]: registered USBVision Radio device %s [v4l2]\n", |
1395 | usbvision->nr, video_device_node_name(usbvision->rdev)); | 1377 | usbvision->nr, video_device_node_name(&usbvision->rdev)); |
1396 | } | 1378 | } |
1397 | /* all done */ | 1379 | /* all done */ |
1398 | return 0; | 1380 | return 0; |
@@ -1461,7 +1443,7 @@ static void usbvision_release(struct usb_usbvision *usbvision) | |||
1461 | 1443 | ||
1462 | usbvision->initialized = 0; | 1444 | usbvision->initialized = 0; |
1463 | 1445 | ||
1464 | usbvision_remove_sysfs(usbvision->vdev); | 1446 | usbvision_remove_sysfs(&usbvision->vdev); |
1465 | usbvision_unregister_video(usbvision); | 1447 | usbvision_unregister_video(usbvision); |
1466 | kfree(usbvision->alt_max_pkt_size); | 1448 | kfree(usbvision->alt_max_pkt_size); |
1467 | 1449 | ||
@@ -1525,7 +1507,7 @@ static int usbvision_probe(struct usb_interface *intf, | |||
1525 | const struct usb_host_interface *interface; | 1507 | const struct usb_host_interface *interface; |
1526 | struct usb_usbvision *usbvision = NULL; | 1508 | struct usb_usbvision *usbvision = NULL; |
1527 | const struct usb_endpoint_descriptor *endpoint; | 1509 | const struct usb_endpoint_descriptor *endpoint; |
1528 | int model, i; | 1510 | int model, i, ret; |
1529 | 1511 | ||
1530 | PDEBUG(DBG_PROBE, "VID=%#04x, PID=%#04x, ifnum=%u", | 1512 | PDEBUG(DBG_PROBE, "VID=%#04x, PID=%#04x, ifnum=%u", |
1531 | dev->descriptor.idVendor, | 1513 | dev->descriptor.idVendor, |
@@ -1534,7 +1516,8 @@ static int usbvision_probe(struct usb_interface *intf, | |||
1534 | model = devid->driver_info; | 1516 | model = devid->driver_info; |
1535 | if (model < 0 || model >= usbvision_device_data_size) { | 1517 | if (model < 0 || model >= usbvision_device_data_size) { |
1536 | PDEBUG(DBG_PROBE, "model out of bounds %d", model); | 1518 | PDEBUG(DBG_PROBE, "model out of bounds %d", model); |
1537 | return -ENODEV; | 1519 | ret = -ENODEV; |
1520 | goto err_usb; | ||
1538 | } | 1521 | } |
1539 | printk(KERN_INFO "%s: %s found\n", __func__, | 1522 | printk(KERN_INFO "%s: %s found\n", __func__, |
1540 | usbvision_device_data[model].model_string); | 1523 | usbvision_device_data[model].model_string); |
@@ -1549,18 +1532,21 @@ static int usbvision_probe(struct usb_interface *intf, | |||
1549 | __func__, ifnum); | 1532 | __func__, ifnum); |
1550 | dev_err(&intf->dev, "%s: Endpoint attributes %d", | 1533 | dev_err(&intf->dev, "%s: Endpoint attributes %d", |
1551 | __func__, endpoint->bmAttributes); | 1534 | __func__, endpoint->bmAttributes); |
1552 | return -ENODEV; | 1535 | ret = -ENODEV; |
1536 | goto err_usb; | ||
1553 | } | 1537 | } |
1554 | if (usb_endpoint_dir_out(endpoint)) { | 1538 | if (usb_endpoint_dir_out(endpoint)) { |
1555 | dev_err(&intf->dev, "%s: interface %d. has ISO OUT endpoint!\n", | 1539 | dev_err(&intf->dev, "%s: interface %d. has ISO OUT endpoint!\n", |
1556 | __func__, ifnum); | 1540 | __func__, ifnum); |
1557 | return -ENODEV; | 1541 | ret = -ENODEV; |
1542 | goto err_usb; | ||
1558 | } | 1543 | } |
1559 | 1544 | ||
1560 | usbvision = usbvision_alloc(dev, intf); | 1545 | usbvision = usbvision_alloc(dev, intf); |
1561 | if (usbvision == NULL) { | 1546 | if (usbvision == NULL) { |
1562 | dev_err(&intf->dev, "%s: couldn't allocate USBVision struct\n", __func__); | 1547 | dev_err(&intf->dev, "%s: couldn't allocate USBVision struct\n", __func__); |
1563 | return -ENOMEM; | 1548 | ret = -ENOMEM; |
1549 | goto err_usb; | ||
1564 | } | 1550 | } |
1565 | 1551 | ||
1566 | if (dev->descriptor.bNumConfigurations > 1) | 1552 | if (dev->descriptor.bNumConfigurations > 1) |
@@ -1579,8 +1565,8 @@ static int usbvision_probe(struct usb_interface *intf, | |||
1579 | usbvision->alt_max_pkt_size = kmalloc(32 * usbvision->num_alt, GFP_KERNEL); | 1565 | usbvision->alt_max_pkt_size = kmalloc(32 * usbvision->num_alt, GFP_KERNEL); |
1580 | if (usbvision->alt_max_pkt_size == NULL) { | 1566 | if (usbvision->alt_max_pkt_size == NULL) { |
1581 | dev_err(&intf->dev, "usbvision: out of memory!\n"); | 1567 | dev_err(&intf->dev, "usbvision: out of memory!\n"); |
1582 | usbvision_release(usbvision); | 1568 | ret = -ENOMEM; |
1583 | return -ENOMEM; | 1569 | goto err_pkt; |
1584 | } | 1570 | } |
1585 | 1571 | ||
1586 | for (i = 0; i < usbvision->num_alt; i++) { | 1572 | for (i = 0; i < usbvision->num_alt; i++) { |
@@ -1611,10 +1597,16 @@ static int usbvision_probe(struct usb_interface *intf, | |||
1611 | usbvision_configure_video(usbvision); | 1597 | usbvision_configure_video(usbvision); |
1612 | usbvision_register_video(usbvision); | 1598 | usbvision_register_video(usbvision); |
1613 | 1599 | ||
1614 | usbvision_create_sysfs(usbvision->vdev); | 1600 | usbvision_create_sysfs(&usbvision->vdev); |
1615 | 1601 | ||
1616 | PDEBUG(DBG_PROBE, "success"); | 1602 | PDEBUG(DBG_PROBE, "success"); |
1617 | return 0; | 1603 | return 0; |
1604 | |||
1605 | err_pkt: | ||
1606 | usbvision_release(usbvision); | ||
1607 | err_usb: | ||
1608 | usb_put_dev(dev); | ||
1609 | return ret; | ||
1618 | } | 1610 | } |
1619 | 1611 | ||
1620 | 1612 | ||
diff --git a/drivers/media/usb/usbvision/usbvision.h b/drivers/media/usb/usbvision/usbvision.h index 77aeb1ed9a81..140a1f67566e 100644 --- a/drivers/media/usb/usbvision/usbvision.h +++ b/drivers/media/usb/usbvision/usbvision.h | |||
@@ -357,8 +357,8 @@ extern struct usb_device_id usbvision_table[]; | |||
357 | 357 | ||
358 | struct usb_usbvision { | 358 | struct usb_usbvision { |
359 | struct v4l2_device v4l2_dev; | 359 | struct v4l2_device v4l2_dev; |
360 | struct video_device *vdev; /* Video Device */ | 360 | struct video_device vdev; /* Video Device */ |
361 | struct video_device *rdev; /* Radio Device */ | 361 | struct video_device rdev; /* Radio Device */ |
362 | 362 | ||
363 | /* i2c Declaration Section*/ | 363 | /* i2c Declaration Section*/ |
364 | struct i2c_adapter i2c_adap; | 364 | struct i2c_adapter i2c_adap; |
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index cf27006c29dc..5970dd6a1c1c 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c | |||
@@ -1669,10 +1669,6 @@ static void uvc_delete(struct uvc_device *dev) | |||
1669 | #ifdef CONFIG_MEDIA_CONTROLLER | 1669 | #ifdef CONFIG_MEDIA_CONTROLLER |
1670 | uvc_mc_cleanup_entity(entity); | 1670 | uvc_mc_cleanup_entity(entity); |
1671 | #endif | 1671 | #endif |
1672 | if (entity->vdev) { | ||
1673 | video_device_release(entity->vdev); | ||
1674 | entity->vdev = NULL; | ||
1675 | } | ||
1676 | kfree(entity); | 1672 | kfree(entity); |
1677 | } | 1673 | } |
1678 | 1674 | ||
@@ -1717,11 +1713,10 @@ static void uvc_unregister_video(struct uvc_device *dev) | |||
1717 | atomic_inc(&dev->nstreams); | 1713 | atomic_inc(&dev->nstreams); |
1718 | 1714 | ||
1719 | list_for_each_entry(stream, &dev->streams, list) { | 1715 | list_for_each_entry(stream, &dev->streams, list) { |
1720 | if (stream->vdev == NULL) | 1716 | if (!video_is_registered(&stream->vdev)) |
1721 | continue; | 1717 | continue; |
1722 | 1718 | ||
1723 | video_unregister_device(stream->vdev); | 1719 | video_unregister_device(&stream->vdev); |
1724 | stream->vdev = NULL; | ||
1725 | 1720 | ||
1726 | uvc_debugfs_cleanup_stream(stream); | 1721 | uvc_debugfs_cleanup_stream(stream); |
1727 | } | 1722 | } |
@@ -1736,7 +1731,7 @@ static void uvc_unregister_video(struct uvc_device *dev) | |||
1736 | static int uvc_register_video(struct uvc_device *dev, | 1731 | static int uvc_register_video(struct uvc_device *dev, |
1737 | struct uvc_streaming *stream) | 1732 | struct uvc_streaming *stream) |
1738 | { | 1733 | { |
1739 | struct video_device *vdev; | 1734 | struct video_device *vdev = &stream->vdev; |
1740 | int ret; | 1735 | int ret; |
1741 | 1736 | ||
1742 | /* Initialize the video buffers queue. */ | 1737 | /* Initialize the video buffers queue. */ |
@@ -1757,12 +1752,6 @@ static int uvc_register_video(struct uvc_device *dev, | |||
1757 | uvc_debugfs_init_stream(stream); | 1752 | uvc_debugfs_init_stream(stream); |
1758 | 1753 | ||
1759 | /* Register the device with V4L. */ | 1754 | /* Register the device with V4L. */ |
1760 | vdev = video_device_alloc(); | ||
1761 | if (vdev == NULL) { | ||
1762 | uvc_printk(KERN_ERR, "Failed to allocate video device (%d).\n", | ||
1763 | ret); | ||
1764 | return -ENOMEM; | ||
1765 | } | ||
1766 | 1755 | ||
1767 | /* We already hold a reference to dev->udev. The video device will be | 1756 | /* We already hold a reference to dev->udev. The video device will be |
1768 | * unregistered before the reference is released, so we don't need to | 1757 | * unregistered before the reference is released, so we don't need to |
@@ -1780,15 +1769,12 @@ static int uvc_register_video(struct uvc_device *dev, | |||
1780 | /* Set the driver data before calling video_register_device, otherwise | 1769 | /* Set the driver data before calling video_register_device, otherwise |
1781 | * uvc_v4l2_open might race us. | 1770 | * uvc_v4l2_open might race us. |
1782 | */ | 1771 | */ |
1783 | stream->vdev = vdev; | ||
1784 | video_set_drvdata(vdev, stream); | 1772 | video_set_drvdata(vdev, stream); |
1785 | 1773 | ||
1786 | ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); | 1774 | ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); |
1787 | if (ret < 0) { | 1775 | if (ret < 0) { |
1788 | uvc_printk(KERN_ERR, "Failed to register video device (%d).\n", | 1776 | uvc_printk(KERN_ERR, "Failed to register video device (%d).\n", |
1789 | ret); | 1777 | ret); |
1790 | stream->vdev = NULL; | ||
1791 | video_device_release(vdev); | ||
1792 | return ret; | 1778 | return ret; |
1793 | } | 1779 | } |
1794 | 1780 | ||
@@ -1827,7 +1813,7 @@ static int uvc_register_terms(struct uvc_device *dev, | |||
1827 | if (ret < 0) | 1813 | if (ret < 0) |
1828 | return ret; | 1814 | return ret; |
1829 | 1815 | ||
1830 | term->vdev = stream->vdev; | 1816 | term->vdev = &stream->vdev; |
1831 | } | 1817 | } |
1832 | 1818 | ||
1833 | return 0; | 1819 | return 0; |
@@ -2461,6 +2447,14 @@ static struct usb_device_id uvc_ids[] = { | |||
2461 | .bInterfaceProtocol = 0, | 2447 | .bInterfaceProtocol = 0, |
2462 | .driver_info = UVC_QUIRK_PROBE_MINMAX | 2448 | .driver_info = UVC_QUIRK_PROBE_MINMAX |
2463 | | UVC_QUIRK_PROBE_EXTRAFIELDS }, | 2449 | | UVC_QUIRK_PROBE_EXTRAFIELDS }, |
2450 | /* Aveo Technology USB 2.0 Camera (Tasco USB Microscope) */ | ||
2451 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | ||
2452 | | USB_DEVICE_ID_MATCH_INT_INFO, | ||
2453 | .idVendor = 0x1871, | ||
2454 | .idProduct = 0x0516, | ||
2455 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC, | ||
2456 | .bInterfaceSubClass = 1, | ||
2457 | .bInterfaceProtocol = 0 }, | ||
2464 | /* Ecamm Pico iMage */ | 2458 | /* Ecamm Pico iMage */ |
2465 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 2459 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
2466 | | USB_DEVICE_ID_MATCH_INT_INFO, | 2460 | | USB_DEVICE_ID_MATCH_INT_INFO, |
diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c index 10c554e7655c..87a19f33e460 100644 --- a/drivers/media/usb/uvc/uvc_queue.c +++ b/drivers/media/usb/uvc/uvc_queue.c | |||
@@ -306,25 +306,14 @@ int uvc_queue_streamoff(struct uvc_video_queue *queue, enum v4l2_buf_type type) | |||
306 | 306 | ||
307 | int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma) | 307 | int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma) |
308 | { | 308 | { |
309 | int ret; | 309 | return vb2_mmap(&queue->queue, vma); |
310 | |||
311 | mutex_lock(&queue->mutex); | ||
312 | ret = vb2_mmap(&queue->queue, vma); | ||
313 | mutex_unlock(&queue->mutex); | ||
314 | |||
315 | return ret; | ||
316 | } | 310 | } |
317 | 311 | ||
318 | #ifndef CONFIG_MMU | 312 | #ifndef CONFIG_MMU |
319 | unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue, | 313 | unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue, |
320 | unsigned long pgoff) | 314 | unsigned long pgoff) |
321 | { | 315 | { |
322 | unsigned long ret; | 316 | return vb2_get_unmapped_area(&queue->queue, 0, 0, pgoff, 0); |
323 | |||
324 | mutex_lock(&queue->mutex); | ||
325 | ret = vb2_get_unmapped_area(&queue->queue, 0, 0, pgoff, 0); | ||
326 | mutex_unlock(&queue->mutex); | ||
327 | return ret; | ||
328 | } | 317 | } |
329 | #endif | 318 | #endif |
330 | 319 | ||
diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index 43e953f73e02..c4b1ac6750d8 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c | |||
@@ -511,7 +511,7 @@ static int uvc_v4l2_open(struct file *file) | |||
511 | stream->dev->users++; | 511 | stream->dev->users++; |
512 | mutex_unlock(&stream->dev->lock); | 512 | mutex_unlock(&stream->dev->lock); |
513 | 513 | ||
514 | v4l2_fh_init(&handle->vfh, stream->vdev); | 514 | v4l2_fh_init(&handle->vfh, &stream->vdev); |
515 | v4l2_fh_add(&handle->vfh); | 515 | v4l2_fh_add(&handle->vfh); |
516 | handle->chain = stream->chain; | 516 | handle->chain = stream->chain; |
517 | handle->stream = stream; | 517 | handle->stream = stream; |
@@ -882,6 +882,35 @@ static int uvc_ioctl_queryctrl(struct file *file, void *fh, | |||
882 | return uvc_query_v4l2_ctrl(chain, qc); | 882 | return uvc_query_v4l2_ctrl(chain, qc); |
883 | } | 883 | } |
884 | 884 | ||
885 | static int uvc_ioctl_query_ext_ctrl(struct file *file, void *fh, | ||
886 | struct v4l2_query_ext_ctrl *qec) | ||
887 | { | ||
888 | struct uvc_fh *handle = fh; | ||
889 | struct uvc_video_chain *chain = handle->chain; | ||
890 | struct v4l2_queryctrl qc = { qec->id }; | ||
891 | int ret; | ||
892 | |||
893 | ret = uvc_query_v4l2_ctrl(chain, &qc); | ||
894 | if (ret) | ||
895 | return ret; | ||
896 | |||
897 | qec->id = qc.id; | ||
898 | qec->type = qc.type; | ||
899 | strlcpy(qec->name, qc.name, sizeof(qec->name)); | ||
900 | qec->minimum = qc.minimum; | ||
901 | qec->maximum = qc.maximum; | ||
902 | qec->step = qc.step; | ||
903 | qec->default_value = qc.default_value; | ||
904 | qec->flags = qc.flags; | ||
905 | qec->elem_size = 4; | ||
906 | qec->elems = 1; | ||
907 | qec->nr_of_dims = 0; | ||
908 | memset(qec->dims, 0, sizeof(qec->dims)); | ||
909 | memset(qec->reserved, 0, sizeof(qec->reserved)); | ||
910 | |||
911 | return 0; | ||
912 | } | ||
913 | |||
885 | static int uvc_ioctl_g_ctrl(struct file *file, void *fh, | 914 | static int uvc_ioctl_g_ctrl(struct file *file, void *fh, |
886 | struct v4l2_control *ctrl) | 915 | struct v4l2_control *ctrl) |
887 | { | 916 | { |
@@ -1018,26 +1047,37 @@ static int uvc_ioctl_querymenu(struct file *file, void *fh, | |||
1018 | return uvc_query_v4l2_menu(chain, qm); | 1047 | return uvc_query_v4l2_menu(chain, qm); |
1019 | } | 1048 | } |
1020 | 1049 | ||
1021 | static int uvc_ioctl_cropcap(struct file *file, void *fh, | 1050 | static int uvc_ioctl_g_selection(struct file *file, void *fh, |
1022 | struct v4l2_cropcap *ccap) | 1051 | struct v4l2_selection *sel) |
1023 | { | 1052 | { |
1024 | struct uvc_fh *handle = fh; | 1053 | struct uvc_fh *handle = fh; |
1025 | struct uvc_streaming *stream = handle->stream; | 1054 | struct uvc_streaming *stream = handle->stream; |
1026 | 1055 | ||
1027 | if (ccap->type != stream->type) | 1056 | if (sel->type != stream->type) |
1028 | return -EINVAL; | 1057 | return -EINVAL; |
1029 | 1058 | ||
1030 | ccap->bounds.left = 0; | 1059 | switch (sel->target) { |
1031 | ccap->bounds.top = 0; | 1060 | case V4L2_SEL_TGT_CROP_DEFAULT: |
1061 | case V4L2_SEL_TGT_CROP_BOUNDS: | ||
1062 | if (stream->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1063 | return -EINVAL; | ||
1064 | break; | ||
1065 | case V4L2_SEL_TGT_COMPOSE_DEFAULT: | ||
1066 | case V4L2_SEL_TGT_COMPOSE_BOUNDS: | ||
1067 | if (stream->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) | ||
1068 | return -EINVAL; | ||
1069 | break; | ||
1070 | default: | ||
1071 | return -EINVAL; | ||
1072 | } | ||
1073 | |||
1074 | sel->r.left = 0; | ||
1075 | sel->r.top = 0; | ||
1032 | mutex_lock(&stream->mutex); | 1076 | mutex_lock(&stream->mutex); |
1033 | ccap->bounds.width = stream->cur_frame->wWidth; | 1077 | sel->r.width = stream->cur_frame->wWidth; |
1034 | ccap->bounds.height = stream->cur_frame->wHeight; | 1078 | sel->r.height = stream->cur_frame->wHeight; |
1035 | mutex_unlock(&stream->mutex); | 1079 | mutex_unlock(&stream->mutex); |
1036 | 1080 | ||
1037 | ccap->defrect = ccap->bounds; | ||
1038 | |||
1039 | ccap->pixelaspect.numerator = 1; | ||
1040 | ccap->pixelaspect.denominator = 1; | ||
1041 | return 0; | 1081 | return 0; |
1042 | } | 1082 | } |
1043 | 1083 | ||
@@ -1133,6 +1173,9 @@ static int uvc_ioctl_enum_frameintervals(struct file *file, void *fh, | |||
1133 | uvc_simplify_fraction(&fival->discrete.numerator, | 1173 | uvc_simplify_fraction(&fival->discrete.numerator, |
1134 | &fival->discrete.denominator, 8, 333); | 1174 | &fival->discrete.denominator, 8, 333); |
1135 | } else { | 1175 | } else { |
1176 | if (fival->index) | ||
1177 | return -EINVAL; | ||
1178 | |||
1136 | fival->type = V4L2_FRMIVAL_TYPE_STEPWISE; | 1179 | fival->type = V4L2_FRMIVAL_TYPE_STEPWISE; |
1137 | fival->stepwise.min.numerator = frame->dwFrameInterval[0]; | 1180 | fival->stepwise.min.numerator = frame->dwFrameInterval[0]; |
1138 | fival->stepwise.min.denominator = 10000000; | 1181 | fival->stepwise.min.denominator = 10000000; |
@@ -1443,13 +1486,14 @@ const struct v4l2_ioctl_ops uvc_ioctl_ops = { | |||
1443 | .vidioc_g_input = uvc_ioctl_g_input, | 1486 | .vidioc_g_input = uvc_ioctl_g_input, |
1444 | .vidioc_s_input = uvc_ioctl_s_input, | 1487 | .vidioc_s_input = uvc_ioctl_s_input, |
1445 | .vidioc_queryctrl = uvc_ioctl_queryctrl, | 1488 | .vidioc_queryctrl = uvc_ioctl_queryctrl, |
1489 | .vidioc_query_ext_ctrl = uvc_ioctl_query_ext_ctrl, | ||
1446 | .vidioc_g_ctrl = uvc_ioctl_g_ctrl, | 1490 | .vidioc_g_ctrl = uvc_ioctl_g_ctrl, |
1447 | .vidioc_s_ctrl = uvc_ioctl_s_ctrl, | 1491 | .vidioc_s_ctrl = uvc_ioctl_s_ctrl, |
1448 | .vidioc_g_ext_ctrls = uvc_ioctl_g_ext_ctrls, | 1492 | .vidioc_g_ext_ctrls = uvc_ioctl_g_ext_ctrls, |
1449 | .vidioc_s_ext_ctrls = uvc_ioctl_s_ext_ctrls, | 1493 | .vidioc_s_ext_ctrls = uvc_ioctl_s_ext_ctrls, |
1450 | .vidioc_try_ext_ctrls = uvc_ioctl_try_ext_ctrls, | 1494 | .vidioc_try_ext_ctrls = uvc_ioctl_try_ext_ctrls, |
1451 | .vidioc_querymenu = uvc_ioctl_querymenu, | 1495 | .vidioc_querymenu = uvc_ioctl_querymenu, |
1452 | .vidioc_cropcap = uvc_ioctl_cropcap, | 1496 | .vidioc_g_selection = uvc_ioctl_g_selection, |
1453 | .vidioc_g_parm = uvc_ioctl_g_parm, | 1497 | .vidioc_g_parm = uvc_ioctl_g_parm, |
1454 | .vidioc_s_parm = uvc_ioctl_s_parm, | 1498 | .vidioc_s_parm = uvc_ioctl_s_parm, |
1455 | .vidioc_enum_framesizes = uvc_ioctl_enum_framesizes, | 1499 | .vidioc_enum_framesizes = uvc_ioctl_enum_framesizes, |
diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index c63e5b55e143..1b594c203992 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h | |||
@@ -443,7 +443,7 @@ struct uvc_stats_stream { | |||
443 | struct uvc_streaming { | 443 | struct uvc_streaming { |
444 | struct list_head list; | 444 | struct list_head list; |
445 | struct uvc_device *dev; | 445 | struct uvc_device *dev; |
446 | struct video_device *vdev; | 446 | struct video_device vdev; |
447 | struct uvc_video_chain *chain; | 447 | struct uvc_video_chain *chain; |
448 | atomic_t active; | 448 | atomic_t active; |
449 | 449 | ||
diff --git a/drivers/media/v4l2-core/tuner-core.c b/drivers/media/v4l2-core/tuner-core.c index 559f8372e2eb..abdcffabcb59 100644 --- a/drivers/media/v4l2-core/tuner-core.c +++ b/drivers/media/v4l2-core/tuner-core.c | |||
@@ -134,6 +134,9 @@ struct tuner { | |||
134 | unsigned int type; /* chip type id */ | 134 | unsigned int type; /* chip type id */ |
135 | void *config; | 135 | void *config; |
136 | const char *name; | 136 | const char *name; |
137 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
138 | struct media_pad pad; | ||
139 | #endif | ||
137 | }; | 140 | }; |
138 | 141 | ||
139 | /* | 142 | /* |
@@ -434,6 +437,10 @@ static void set_type(struct i2c_client *c, unsigned int type, | |||
434 | t->name = analog_ops->info.name; | 437 | t->name = analog_ops->info.name; |
435 | } | 438 | } |
436 | 439 | ||
440 | #ifdef CONFIG_MEDIA_CONTROLLER | ||
441 | t->sd.entity.name = t->name; | ||
442 | #endif | ||
443 | |||
437 | tuner_dbg("type set to %s\n", t->name); | 444 | tuner_dbg("type set to %s\n", t->name); |
438 | 445 | ||
439 | t->mode_mask = new_mode_mask; | 446 | t->mode_mask = new_mode_mask; |
@@ -592,6 +599,9 @@ static int tuner_probe(struct i2c_client *client, | |||
592 | struct tuner *t; | 599 | struct tuner *t; |
593 | struct tuner *radio; | 600 | struct tuner *radio; |
594 | struct tuner *tv; | 601 | struct tuner *tv; |
602 | #ifdef CONFIG_MEDIA_CONTROLLER | ||
603 | int ret; | ||
604 | #endif | ||
595 | 605 | ||
596 | t = kzalloc(sizeof(struct tuner), GFP_KERNEL); | 606 | t = kzalloc(sizeof(struct tuner), GFP_KERNEL); |
597 | if (NULL == t) | 607 | if (NULL == t) |
@@ -684,6 +694,18 @@ static int tuner_probe(struct i2c_client *client, | |||
684 | 694 | ||
685 | /* Should be just before return */ | 695 | /* Should be just before return */ |
686 | register_client: | 696 | register_client: |
697 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
698 | t->pad.flags = MEDIA_PAD_FL_SOURCE; | ||
699 | t->sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_TUNER; | ||
700 | t->sd.entity.name = t->name; | ||
701 | |||
702 | ret = media_entity_init(&t->sd.entity, 1, &t->pad, 0); | ||
703 | if (ret < 0) { | ||
704 | tuner_err("failed to initialize media entity!\n"); | ||
705 | kfree(t); | ||
706 | return -ENODEV; | ||
707 | } | ||
708 | #endif | ||
687 | /* Sets a default mode */ | 709 | /* Sets a default mode */ |
688 | if (t->mode_mask & T_ANALOG_TV) | 710 | if (t->mode_mask & T_ANALOG_TV) |
689 | t->mode = V4L2_TUNER_ANALOG_TV; | 711 | t->mode = V4L2_TUNER_ANALOG_TV; |
diff --git a/drivers/media/v4l2-core/v4l2-clk.c b/drivers/media/v4l2-core/v4l2-clk.c index e18cc0469cf8..34e416a554f6 100644 --- a/drivers/media/v4l2-core/v4l2-clk.c +++ b/drivers/media/v4l2-core/v4l2-clk.c | |||
@@ -9,6 +9,7 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/atomic.h> | 11 | #include <linux/atomic.h> |
12 | #include <linux/clk.h> | ||
12 | #include <linux/device.h> | 13 | #include <linux/device.h> |
13 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
14 | #include <linux/list.h> | 15 | #include <linux/list.h> |
@@ -23,17 +24,13 @@ | |||
23 | static DEFINE_MUTEX(clk_lock); | 24 | static DEFINE_MUTEX(clk_lock); |
24 | static LIST_HEAD(clk_list); | 25 | static LIST_HEAD(clk_list); |
25 | 26 | ||
26 | static struct v4l2_clk *v4l2_clk_find(const char *dev_id, const char *id) | 27 | static struct v4l2_clk *v4l2_clk_find(const char *dev_id) |
27 | { | 28 | { |
28 | struct v4l2_clk *clk; | 29 | struct v4l2_clk *clk; |
29 | 30 | ||
30 | list_for_each_entry(clk, &clk_list, list) { | 31 | list_for_each_entry(clk, &clk_list, list) |
31 | if (strcmp(dev_id, clk->dev_id)) | 32 | if (!strcmp(dev_id, clk->dev_id)) |
32 | continue; | ||
33 | |||
34 | if (!id || !clk->id || !strcmp(clk->id, id)) | ||
35 | return clk; | 33 | return clk; |
36 | } | ||
37 | 34 | ||
38 | return ERR_PTR(-ENODEV); | 35 | return ERR_PTR(-ENODEV); |
39 | } | 36 | } |
@@ -41,9 +38,24 @@ static struct v4l2_clk *v4l2_clk_find(const char *dev_id, const char *id) | |||
41 | struct v4l2_clk *v4l2_clk_get(struct device *dev, const char *id) | 38 | struct v4l2_clk *v4l2_clk_get(struct device *dev, const char *id) |
42 | { | 39 | { |
43 | struct v4l2_clk *clk; | 40 | struct v4l2_clk *clk; |
41 | struct clk *ccf_clk = clk_get(dev, id); | ||
42 | |||
43 | if (PTR_ERR(ccf_clk) == -EPROBE_DEFER) | ||
44 | return ERR_PTR(-EPROBE_DEFER); | ||
45 | |||
46 | if (!IS_ERR_OR_NULL(ccf_clk)) { | ||
47 | clk = kzalloc(sizeof(*clk), GFP_KERNEL); | ||
48 | if (!clk) { | ||
49 | clk_put(ccf_clk); | ||
50 | return ERR_PTR(-ENOMEM); | ||
51 | } | ||
52 | clk->clk = ccf_clk; | ||
53 | |||
54 | return clk; | ||
55 | } | ||
44 | 56 | ||
45 | mutex_lock(&clk_lock); | 57 | mutex_lock(&clk_lock); |
46 | clk = v4l2_clk_find(dev_name(dev), id); | 58 | clk = v4l2_clk_find(dev_name(dev)); |
47 | 59 | ||
48 | if (!IS_ERR(clk)) | 60 | if (!IS_ERR(clk)) |
49 | atomic_inc(&clk->use_count); | 61 | atomic_inc(&clk->use_count); |
@@ -60,6 +72,12 @@ void v4l2_clk_put(struct v4l2_clk *clk) | |||
60 | if (IS_ERR(clk)) | 72 | if (IS_ERR(clk)) |
61 | return; | 73 | return; |
62 | 74 | ||
75 | if (clk->clk) { | ||
76 | clk_put(clk->clk); | ||
77 | kfree(clk); | ||
78 | return; | ||
79 | } | ||
80 | |||
63 | mutex_lock(&clk_lock); | 81 | mutex_lock(&clk_lock); |
64 | 82 | ||
65 | list_for_each_entry(tmp, &clk_list, list) | 83 | list_for_each_entry(tmp, &clk_list, list) |
@@ -97,8 +115,12 @@ static void v4l2_clk_unlock_driver(struct v4l2_clk *clk) | |||
97 | 115 | ||
98 | int v4l2_clk_enable(struct v4l2_clk *clk) | 116 | int v4l2_clk_enable(struct v4l2_clk *clk) |
99 | { | 117 | { |
100 | int ret = v4l2_clk_lock_driver(clk); | 118 | int ret; |
119 | |||
120 | if (clk->clk) | ||
121 | return clk_prepare_enable(clk->clk); | ||
101 | 122 | ||
123 | ret = v4l2_clk_lock_driver(clk); | ||
102 | if (ret < 0) | 124 | if (ret < 0) |
103 | return ret; | 125 | return ret; |
104 | 126 | ||
@@ -124,11 +146,14 @@ void v4l2_clk_disable(struct v4l2_clk *clk) | |||
124 | { | 146 | { |
125 | int enable; | 147 | int enable; |
126 | 148 | ||
149 | if (clk->clk) | ||
150 | return clk_disable_unprepare(clk->clk); | ||
151 | |||
127 | mutex_lock(&clk->lock); | 152 | mutex_lock(&clk->lock); |
128 | 153 | ||
129 | enable = --clk->enable; | 154 | enable = --clk->enable; |
130 | if (WARN(enable < 0, "Unbalanced %s() on %s:%s!\n", __func__, | 155 | if (WARN(enable < 0, "Unbalanced %s() on %s!\n", __func__, |
131 | clk->dev_id, clk->id)) | 156 | clk->dev_id)) |
132 | clk->enable++; | 157 | clk->enable++; |
133 | else if (!enable && clk->ops->disable) | 158 | else if (!enable && clk->ops->disable) |
134 | clk->ops->disable(clk); | 159 | clk->ops->disable(clk); |
@@ -141,8 +166,12 @@ EXPORT_SYMBOL(v4l2_clk_disable); | |||
141 | 166 | ||
142 | unsigned long v4l2_clk_get_rate(struct v4l2_clk *clk) | 167 | unsigned long v4l2_clk_get_rate(struct v4l2_clk *clk) |
143 | { | 168 | { |
144 | int ret = v4l2_clk_lock_driver(clk); | 169 | int ret; |
170 | |||
171 | if (clk->clk) | ||
172 | return clk_get_rate(clk->clk); | ||
145 | 173 | ||
174 | ret = v4l2_clk_lock_driver(clk); | ||
146 | if (ret < 0) | 175 | if (ret < 0) |
147 | return ret; | 176 | return ret; |
148 | 177 | ||
@@ -161,7 +190,16 @@ EXPORT_SYMBOL(v4l2_clk_get_rate); | |||
161 | 190 | ||
162 | int v4l2_clk_set_rate(struct v4l2_clk *clk, unsigned long rate) | 191 | int v4l2_clk_set_rate(struct v4l2_clk *clk, unsigned long rate) |
163 | { | 192 | { |
164 | int ret = v4l2_clk_lock_driver(clk); | 193 | int ret; |
194 | |||
195 | if (clk->clk) { | ||
196 | long r = clk_round_rate(clk->clk, rate); | ||
197 | if (r < 0) | ||
198 | return r; | ||
199 | return clk_set_rate(clk->clk, r); | ||
200 | } | ||
201 | |||
202 | ret = v4l2_clk_lock_driver(clk); | ||
165 | 203 | ||
166 | if (ret < 0) | 204 | if (ret < 0) |
167 | return ret; | 205 | return ret; |
@@ -181,7 +219,7 @@ EXPORT_SYMBOL(v4l2_clk_set_rate); | |||
181 | 219 | ||
182 | struct v4l2_clk *v4l2_clk_register(const struct v4l2_clk_ops *ops, | 220 | struct v4l2_clk *v4l2_clk_register(const struct v4l2_clk_ops *ops, |
183 | const char *dev_id, | 221 | const char *dev_id, |
184 | const char *id, void *priv) | 222 | void *priv) |
185 | { | 223 | { |
186 | struct v4l2_clk *clk; | 224 | struct v4l2_clk *clk; |
187 | int ret; | 225 | int ret; |
@@ -193,9 +231,8 @@ struct v4l2_clk *v4l2_clk_register(const struct v4l2_clk_ops *ops, | |||
193 | if (!clk) | 231 | if (!clk) |
194 | return ERR_PTR(-ENOMEM); | 232 | return ERR_PTR(-ENOMEM); |
195 | 233 | ||
196 | clk->id = kstrdup(id, GFP_KERNEL); | ||
197 | clk->dev_id = kstrdup(dev_id, GFP_KERNEL); | 234 | clk->dev_id = kstrdup(dev_id, GFP_KERNEL); |
198 | if ((id && !clk->id) || !clk->dev_id) { | 235 | if (!clk->dev_id) { |
199 | ret = -ENOMEM; | 236 | ret = -ENOMEM; |
200 | goto ealloc; | 237 | goto ealloc; |
201 | } | 238 | } |
@@ -205,7 +242,7 @@ struct v4l2_clk *v4l2_clk_register(const struct v4l2_clk_ops *ops, | |||
205 | mutex_init(&clk->lock); | 242 | mutex_init(&clk->lock); |
206 | 243 | ||
207 | mutex_lock(&clk_lock); | 244 | mutex_lock(&clk_lock); |
208 | if (!IS_ERR(v4l2_clk_find(dev_id, id))) { | 245 | if (!IS_ERR(v4l2_clk_find(dev_id))) { |
209 | mutex_unlock(&clk_lock); | 246 | mutex_unlock(&clk_lock); |
210 | ret = -EEXIST; | 247 | ret = -EEXIST; |
211 | goto eexist; | 248 | goto eexist; |
@@ -217,7 +254,6 @@ struct v4l2_clk *v4l2_clk_register(const struct v4l2_clk_ops *ops, | |||
217 | 254 | ||
218 | eexist: | 255 | eexist: |
219 | ealloc: | 256 | ealloc: |
220 | kfree(clk->id); | ||
221 | kfree(clk->dev_id); | 257 | kfree(clk->dev_id); |
222 | kfree(clk); | 258 | kfree(clk); |
223 | return ERR_PTR(ret); | 259 | return ERR_PTR(ret); |
@@ -227,15 +263,14 @@ EXPORT_SYMBOL(v4l2_clk_register); | |||
227 | void v4l2_clk_unregister(struct v4l2_clk *clk) | 263 | void v4l2_clk_unregister(struct v4l2_clk *clk) |
228 | { | 264 | { |
229 | if (WARN(atomic_read(&clk->use_count), | 265 | if (WARN(atomic_read(&clk->use_count), |
230 | "%s(): Refusing to unregister ref-counted %s:%s clock!\n", | 266 | "%s(): Refusing to unregister ref-counted %s clock!\n", |
231 | __func__, clk->dev_id, clk->id)) | 267 | __func__, clk->dev_id)) |
232 | return; | 268 | return; |
233 | 269 | ||
234 | mutex_lock(&clk_lock); | 270 | mutex_lock(&clk_lock); |
235 | list_del(&clk->list); | 271 | list_del(&clk->list); |
236 | mutex_unlock(&clk_lock); | 272 | mutex_unlock(&clk_lock); |
237 | 273 | ||
238 | kfree(clk->id); | ||
239 | kfree(clk->dev_id); | 274 | kfree(clk->dev_id); |
240 | kfree(clk); | 275 | kfree(clk); |
241 | } | 276 | } |
@@ -253,7 +288,7 @@ static unsigned long fixed_get_rate(struct v4l2_clk *clk) | |||
253 | } | 288 | } |
254 | 289 | ||
255 | struct v4l2_clk *__v4l2_clk_register_fixed(const char *dev_id, | 290 | struct v4l2_clk *__v4l2_clk_register_fixed(const char *dev_id, |
256 | const char *id, unsigned long rate, struct module *owner) | 291 | unsigned long rate, struct module *owner) |
257 | { | 292 | { |
258 | struct v4l2_clk *clk; | 293 | struct v4l2_clk *clk; |
259 | struct v4l2_clk_fixed *priv = kzalloc(sizeof(*priv), GFP_KERNEL); | 294 | struct v4l2_clk_fixed *priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
@@ -265,7 +300,7 @@ struct v4l2_clk *__v4l2_clk_register_fixed(const char *dev_id, | |||
265 | priv->ops.get_rate = fixed_get_rate; | 300 | priv->ops.get_rate = fixed_get_rate; |
266 | priv->ops.owner = owner; | 301 | priv->ops.owner = owner; |
267 | 302 | ||
268 | clk = v4l2_clk_register(&priv->ops, dev_id, id, priv); | 303 | clk = v4l2_clk_register(&priv->ops, dev_id, priv); |
269 | if (IS_ERR(clk)) | 304 | if (IS_ERR(clk)) |
270 | kfree(priv); | 305 | kfree(priv); |
271 | 306 | ||
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index 45c5b4710601..e3a3468002e6 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c | |||
@@ -991,7 +991,8 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, | |||
991 | case V4L2_CID_AUTO_FOCUS_START: | 991 | case V4L2_CID_AUTO_FOCUS_START: |
992 | case V4L2_CID_AUTO_FOCUS_STOP: | 992 | case V4L2_CID_AUTO_FOCUS_STOP: |
993 | *type = V4L2_CTRL_TYPE_BUTTON; | 993 | *type = V4L2_CTRL_TYPE_BUTTON; |
994 | *flags |= V4L2_CTRL_FLAG_WRITE_ONLY; | 994 | *flags |= V4L2_CTRL_FLAG_WRITE_ONLY | |
995 | V4L2_CTRL_FLAG_EXECUTE_ON_WRITE; | ||
995 | *min = *max = *step = *def = 0; | 996 | *min = *max = *step = *def = 0; |
996 | break; | 997 | break; |
997 | case V4L2_CID_POWER_LINE_FREQUENCY: | 998 | case V4L2_CID_POWER_LINE_FREQUENCY: |
@@ -1172,7 +1173,8 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, | |||
1172 | case V4L2_CID_FOCUS_RELATIVE: | 1173 | case V4L2_CID_FOCUS_RELATIVE: |
1173 | case V4L2_CID_IRIS_RELATIVE: | 1174 | case V4L2_CID_IRIS_RELATIVE: |
1174 | case V4L2_CID_ZOOM_RELATIVE: | 1175 | case V4L2_CID_ZOOM_RELATIVE: |
1175 | *flags |= V4L2_CTRL_FLAG_WRITE_ONLY; | 1176 | *flags |= V4L2_CTRL_FLAG_WRITE_ONLY | |
1177 | V4L2_CTRL_FLAG_EXECUTE_ON_WRITE; | ||
1176 | break; | 1178 | break; |
1177 | case V4L2_CID_FLASH_STROBE_STATUS: | 1179 | case V4L2_CID_FLASH_STROBE_STATUS: |
1178 | case V4L2_CID_AUTO_FOCUS_STATUS: | 1180 | case V4L2_CID_AUTO_FOCUS_STATUS: |
@@ -1609,6 +1611,19 @@ static int cluster_changed(struct v4l2_ctrl *master) | |||
1609 | 1611 | ||
1610 | if (ctrl == NULL) | 1612 | if (ctrl == NULL) |
1611 | continue; | 1613 | continue; |
1614 | |||
1615 | if (ctrl->flags & V4L2_CTRL_FLAG_EXECUTE_ON_WRITE) | ||
1616 | changed = ctrl_changed = true; | ||
1617 | |||
1618 | /* | ||
1619 | * Set has_changed to false to avoid generating | ||
1620 | * the event V4L2_EVENT_CTRL_CH_VALUE | ||
1621 | */ | ||
1622 | if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) { | ||
1623 | ctrl->has_changed = false; | ||
1624 | continue; | ||
1625 | } | ||
1626 | |||
1612 | for (idx = 0; !ctrl_changed && idx < ctrl->elems; idx++) | 1627 | for (idx = 0; !ctrl_changed && idx < ctrl->elems; idx++) |
1613 | ctrl_changed = !ctrl->type_ops->equal(ctrl, idx, | 1628 | ctrl_changed = !ctrl->type_ops->equal(ctrl, idx, |
1614 | ctrl->p_cur, ctrl->p_new); | 1629 | ctrl->p_cur, ctrl->p_new); |
@@ -1974,7 +1989,8 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, | |||
1974 | 1989 | ||
1975 | sz_extra = 0; | 1990 | sz_extra = 0; |
1976 | if (type == V4L2_CTRL_TYPE_BUTTON) | 1991 | if (type == V4L2_CTRL_TYPE_BUTTON) |
1977 | flags |= V4L2_CTRL_FLAG_WRITE_ONLY; | 1992 | flags |= V4L2_CTRL_FLAG_WRITE_ONLY | |
1993 | V4L2_CTRL_FLAG_EXECUTE_ON_WRITE; | ||
1978 | else if (type == V4L2_CTRL_TYPE_CTRL_CLASS) | 1994 | else if (type == V4L2_CTRL_TYPE_CTRL_CLASS) |
1979 | flags |= V4L2_CTRL_FLAG_READ_ONLY; | 1995 | flags |= V4L2_CTRL_FLAG_READ_ONLY; |
1980 | else if (type == V4L2_CTRL_TYPE_INTEGER64 || | 1996 | else if (type == V4L2_CTRL_TYPE_INTEGER64 || |
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index 86bb93fd7db8..71a1b93b0790 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c | |||
@@ -357,34 +357,6 @@ static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
357 | ret = vdev->fops->unlocked_ioctl(filp, cmd, arg); | 357 | ret = vdev->fops->unlocked_ioctl(filp, cmd, arg); |
358 | if (lock) | 358 | if (lock) |
359 | mutex_unlock(lock); | 359 | mutex_unlock(lock); |
360 | } else if (vdev->fops->ioctl) { | ||
361 | /* This code path is a replacement for the BKL. It is a major | ||
362 | * hack but it will have to do for those drivers that are not | ||
363 | * yet converted to use unlocked_ioctl. | ||
364 | * | ||
365 | * All drivers implement struct v4l2_device, so we use the | ||
366 | * lock defined there to serialize the ioctls. | ||
367 | * | ||
368 | * However, if the driver sleeps, then it blocks all ioctls | ||
369 | * since the lock is still held. This is very common for | ||
370 | * VIDIOC_DQBUF since that normally waits for a frame to arrive. | ||
371 | * As a result any other ioctl calls will proceed very, very | ||
372 | * slowly since each call will have to wait for the VIDIOC_QBUF | ||
373 | * to finish. Things that should take 0.01s may now take 10-20 | ||
374 | * seconds. | ||
375 | * | ||
376 | * The workaround is to *not* take the lock for VIDIOC_DQBUF. | ||
377 | * This actually works OK for videobuf-based drivers, since | ||
378 | * videobuf will take its own internal lock. | ||
379 | */ | ||
380 | struct mutex *m = &vdev->v4l2_dev->ioctl_lock; | ||
381 | |||
382 | if (cmd != VIDIOC_DQBUF && mutex_lock_interruptible(m)) | ||
383 | return -ERESTARTSYS; | ||
384 | if (video_is_registered(vdev)) | ||
385 | ret = vdev->fops->ioctl(filp, cmd, arg); | ||
386 | if (cmd != VIDIOC_DQBUF) | ||
387 | mutex_unlock(m); | ||
388 | } else | 360 | } else |
389 | ret = -ENOTTY; | 361 | ret = -ENOTTY; |
390 | 362 | ||
@@ -560,10 +532,9 @@ static void determine_valid_ioctls(struct video_device *vdev) | |||
560 | /* vfl_type and vfl_dir independent ioctls */ | 532 | /* vfl_type and vfl_dir independent ioctls */ |
561 | 533 | ||
562 | SET_VALID_IOCTL(ops, VIDIOC_QUERYCAP, vidioc_querycap); | 534 | SET_VALID_IOCTL(ops, VIDIOC_QUERYCAP, vidioc_querycap); |
563 | if (ops->vidioc_g_priority) | 535 | set_bit(_IOC_NR(VIDIOC_G_PRIORITY), valid_ioctls); |
564 | set_bit(_IOC_NR(VIDIOC_G_PRIORITY), valid_ioctls); | 536 | set_bit(_IOC_NR(VIDIOC_S_PRIORITY), valid_ioctls); |
565 | if (ops->vidioc_s_priority) | 537 | |
566 | set_bit(_IOC_NR(VIDIOC_S_PRIORITY), valid_ioctls); | ||
567 | /* Note: the control handler can also be passed through the filehandle, | 538 | /* Note: the control handler can also be passed through the filehandle, |
568 | and that can't be tested here. If the bit for these control ioctls | 539 | and that can't be tested here. If the bit for these control ioctls |
569 | is set, then the ioctl is valid. But if it is 0, then it can still | 540 | is set, then the ioctl is valid. But if it is 0, then it can still |
@@ -640,6 +611,14 @@ static void determine_valid_ioctls(struct video_device *vdev) | |||
640 | SET_VALID_IOCTL(ops, VIDIOC_TRY_DECODER_CMD, vidioc_try_decoder_cmd); | 611 | SET_VALID_IOCTL(ops, VIDIOC_TRY_DECODER_CMD, vidioc_try_decoder_cmd); |
641 | SET_VALID_IOCTL(ops, VIDIOC_ENUM_FRAMESIZES, vidioc_enum_framesizes); | 612 | SET_VALID_IOCTL(ops, VIDIOC_ENUM_FRAMESIZES, vidioc_enum_framesizes); |
642 | SET_VALID_IOCTL(ops, VIDIOC_ENUM_FRAMEINTERVALS, vidioc_enum_frameintervals); | 613 | SET_VALID_IOCTL(ops, VIDIOC_ENUM_FRAMEINTERVALS, vidioc_enum_frameintervals); |
614 | if (ops->vidioc_g_crop || ops->vidioc_g_selection) | ||
615 | set_bit(_IOC_NR(VIDIOC_G_CROP), valid_ioctls); | ||
616 | if (ops->vidioc_s_crop || ops->vidioc_s_selection) | ||
617 | set_bit(_IOC_NR(VIDIOC_S_CROP), valid_ioctls); | ||
618 | SET_VALID_IOCTL(ops, VIDIOC_G_SELECTION, vidioc_g_selection); | ||
619 | SET_VALID_IOCTL(ops, VIDIOC_S_SELECTION, vidioc_s_selection); | ||
620 | if (ops->vidioc_cropcap || ops->vidioc_g_selection) | ||
621 | set_bit(_IOC_NR(VIDIOC_CROPCAP), valid_ioctls); | ||
643 | } else if (is_vbi) { | 622 | } else if (is_vbi) { |
644 | /* vbi specific ioctls */ | 623 | /* vbi specific ioctls */ |
645 | if ((is_rx && (ops->vidioc_g_fmt_vbi_cap || | 624 | if ((is_rx && (ops->vidioc_g_fmt_vbi_cap || |
@@ -708,14 +687,6 @@ static void determine_valid_ioctls(struct video_device *vdev) | |||
708 | SET_VALID_IOCTL(ops, VIDIOC_G_AUDOUT, vidioc_g_audout); | 687 | SET_VALID_IOCTL(ops, VIDIOC_G_AUDOUT, vidioc_g_audout); |
709 | SET_VALID_IOCTL(ops, VIDIOC_S_AUDOUT, vidioc_s_audout); | 688 | SET_VALID_IOCTL(ops, VIDIOC_S_AUDOUT, vidioc_s_audout); |
710 | } | 689 | } |
711 | if (ops->vidioc_g_crop || ops->vidioc_g_selection) | ||
712 | set_bit(_IOC_NR(VIDIOC_G_CROP), valid_ioctls); | ||
713 | if (ops->vidioc_s_crop || ops->vidioc_s_selection) | ||
714 | set_bit(_IOC_NR(VIDIOC_S_CROP), valid_ioctls); | ||
715 | SET_VALID_IOCTL(ops, VIDIOC_G_SELECTION, vidioc_g_selection); | ||
716 | SET_VALID_IOCTL(ops, VIDIOC_S_SELECTION, vidioc_s_selection); | ||
717 | if (ops->vidioc_cropcap || ops->vidioc_g_selection) | ||
718 | set_bit(_IOC_NR(VIDIOC_CROPCAP), valid_ioctls); | ||
719 | if (ops->vidioc_g_parm || (vdev->vfl_type == VFL_TYPE_GRABBER && | 690 | if (ops->vidioc_g_parm || (vdev->vfl_type == VFL_TYPE_GRABBER && |
720 | ops->vidioc_g_std)) | 691 | ops->vidioc_g_std)) |
721 | set_bit(_IOC_NR(VIDIOC_G_PARM), valid_ioctls); | 692 | set_bit(_IOC_NR(VIDIOC_G_PARM), valid_ioctls); |
@@ -943,8 +914,8 @@ int __video_register_device(struct video_device *vdev, int type, int nr, | |||
943 | vdev->vfl_type != VFL_TYPE_SUBDEV) { | 914 | vdev->vfl_type != VFL_TYPE_SUBDEV) { |
944 | vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L; | 915 | vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L; |
945 | vdev->entity.name = vdev->name; | 916 | vdev->entity.name = vdev->name; |
946 | vdev->entity.info.v4l.major = VIDEO_MAJOR; | 917 | vdev->entity.info.dev.major = VIDEO_MAJOR; |
947 | vdev->entity.info.v4l.minor = vdev->minor; | 918 | vdev->entity.info.dev.minor = vdev->minor; |
948 | ret = media_device_register_entity(vdev->v4l2_dev->mdev, | 919 | ret = media_device_register_entity(vdev->v4l2_dev->mdev, |
949 | &vdev->entity); | 920 | &vdev->entity); |
950 | if (ret < 0) | 921 | if (ret < 0) |
diff --git a/drivers/media/v4l2-core/v4l2-device.c b/drivers/media/v4l2-core/v4l2-device.c index 015f92aab44a..5b0a30b9252b 100644 --- a/drivers/media/v4l2-core/v4l2-device.c +++ b/drivers/media/v4l2-core/v4l2-device.c | |||
@@ -37,7 +37,6 @@ int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev) | |||
37 | 37 | ||
38 | INIT_LIST_HEAD(&v4l2_dev->subdevs); | 38 | INIT_LIST_HEAD(&v4l2_dev->subdevs); |
39 | spin_lock_init(&v4l2_dev->lock); | 39 | spin_lock_init(&v4l2_dev->lock); |
40 | mutex_init(&v4l2_dev->ioctl_lock); | ||
41 | v4l2_prio_init(&v4l2_dev->prio); | 40 | v4l2_prio_init(&v4l2_dev->prio); |
42 | kref_init(&v4l2_dev->ref); | 41 | kref_init(&v4l2_dev->ref); |
43 | get_device(dev); | 42 | get_device(dev); |
@@ -248,8 +247,8 @@ int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev) | |||
248 | goto clean_up; | 247 | goto clean_up; |
249 | } | 248 | } |
250 | #if defined(CONFIG_MEDIA_CONTROLLER) | 249 | #if defined(CONFIG_MEDIA_CONTROLLER) |
251 | sd->entity.info.v4l.major = VIDEO_MAJOR; | 250 | sd->entity.info.dev.major = VIDEO_MAJOR; |
252 | sd->entity.info.v4l.minor = vdev->minor; | 251 | sd->entity.info.dev.minor = vdev->minor; |
253 | #endif | 252 | #endif |
254 | sd->devnode = vdev; | 253 | sd->devnode = vdev; |
255 | } | 254 | } |
diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c index b1d8dbb39665..c0e96382feba 100644 --- a/drivers/media/v4l2-core/v4l2-dv-timings.c +++ b/drivers/media/v4l2-core/v4l2-dv-timings.c | |||
@@ -282,7 +282,7 @@ void v4l2_print_dv_timings(const char *dev_prefix, const char *prefix, | |||
282 | (bt->polarities & V4L2_DV_VSYNC_POS_POL) ? "+" : "-", | 282 | (bt->polarities & V4L2_DV_VSYNC_POS_POL) ? "+" : "-", |
283 | bt->vsync, bt->vbackporch); | 283 | bt->vsync, bt->vbackporch); |
284 | pr_info("%s: pixelclock: %llu\n", dev_prefix, bt->pixelclock); | 284 | pr_info("%s: pixelclock: %llu\n", dev_prefix, bt->pixelclock); |
285 | pr_info("%s: flags (0x%x):%s%s%s%s\n", dev_prefix, bt->flags, | 285 | pr_info("%s: flags (0x%x):%s%s%s%s%s\n", dev_prefix, bt->flags, |
286 | (bt->flags & V4L2_DV_FL_REDUCED_BLANKING) ? | 286 | (bt->flags & V4L2_DV_FL_REDUCED_BLANKING) ? |
287 | " REDUCED_BLANKING" : "", | 287 | " REDUCED_BLANKING" : "", |
288 | (bt->flags & V4L2_DV_FL_CAN_REDUCE_FPS) ? | 288 | (bt->flags & V4L2_DV_FL_CAN_REDUCE_FPS) ? |
@@ -290,7 +290,9 @@ void v4l2_print_dv_timings(const char *dev_prefix, const char *prefix, | |||
290 | (bt->flags & V4L2_DV_FL_REDUCED_FPS) ? | 290 | (bt->flags & V4L2_DV_FL_REDUCED_FPS) ? |
291 | " REDUCED_FPS" : "", | 291 | " REDUCED_FPS" : "", |
292 | (bt->flags & V4L2_DV_FL_HALF_LINE) ? | 292 | (bt->flags & V4L2_DV_FL_HALF_LINE) ? |
293 | " HALF_LINE" : ""); | 293 | " HALF_LINE" : "", |
294 | (bt->flags & V4L2_DV_FL_IS_CE_VIDEO) ? | ||
295 | " CE_VIDEO" : ""); | ||
294 | pr_info("%s: standards (0x%x):%s%s%s%s\n", dev_prefix, bt->standards, | 296 | pr_info("%s: standards (0x%x):%s%s%s%s\n", dev_prefix, bt->standards, |
295 | (bt->standards & V4L2_DV_BT_STD_CEA861) ? " CEA" : "", | 297 | (bt->standards & V4L2_DV_BT_STD_CEA861) ? " CEA" : "", |
296 | (bt->standards & V4L2_DV_BT_STD_DMT) ? " DMT" : "", | 298 | (bt->standards & V4L2_DV_BT_STD_DMT) ? " DMT" : "", |
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index b08407225db1..aa407cb5f830 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c | |||
@@ -257,7 +257,7 @@ static void v4l_print_format(const void *arg, bool write_only) | |||
257 | pr_cont(", width=%u, height=%u, " | 257 | pr_cont(", width=%u, height=%u, " |
258 | "pixelformat=%c%c%c%c, field=%s, " | 258 | "pixelformat=%c%c%c%c, field=%s, " |
259 | "bytesperline=%u, sizeimage=%u, colorspace=%d, " | 259 | "bytesperline=%u, sizeimage=%u, colorspace=%d, " |
260 | "flags %x, ycbcr_enc=%u, quantization=%u\n", | 260 | "flags=0x%x, ycbcr_enc=%u, quantization=%u\n", |
261 | pix->width, pix->height, | 261 | pix->width, pix->height, |
262 | (pix->pixelformat & 0xff), | 262 | (pix->pixelformat & 0xff), |
263 | (pix->pixelformat >> 8) & 0xff, | 263 | (pix->pixelformat >> 8) & 0xff, |
@@ -273,7 +273,7 @@ static void v4l_print_format(const void *arg, bool write_only) | |||
273 | mp = &p->fmt.pix_mp; | 273 | mp = &p->fmt.pix_mp; |
274 | pr_cont(", width=%u, height=%u, " | 274 | pr_cont(", width=%u, height=%u, " |
275 | "format=%c%c%c%c, field=%s, " | 275 | "format=%c%c%c%c, field=%s, " |
276 | "colorspace=%d, num_planes=%u, flags=%x, " | 276 | "colorspace=%d, num_planes=%u, flags=0x%x, " |
277 | "ycbcr_enc=%u, quantization=%u\n", | 277 | "ycbcr_enc=%u, quantization=%u\n", |
278 | mp->width, mp->height, | 278 | mp->width, mp->height, |
279 | (mp->pixelformat & 0xff), | 279 | (mp->pixelformat & 0xff), |
@@ -901,6 +901,8 @@ static int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv) | |||
901 | */ | 901 | */ |
902 | if (!allow_priv && c->ctrl_class == V4L2_CID_PRIVATE_BASE) | 902 | if (!allow_priv && c->ctrl_class == V4L2_CID_PRIVATE_BASE) |
903 | return 0; | 903 | return 0; |
904 | if (c->ctrl_class == 0) | ||
905 | return 1; | ||
904 | /* Check that all controls are from the same control class. */ | 906 | /* Check that all controls are from the same control class. */ |
905 | for (i = 0; i < c->count; i++) { | 907 | for (i = 0; i < c->count; i++) { |
906 | if (V4L2_CTRL_ID2CLASS(c->controls[i].id) != c->ctrl_class) { | 908 | if (V4L2_CTRL_ID2CLASS(c->controls[i].id) != c->ctrl_class) { |
@@ -1046,8 +1048,6 @@ static int v4l_g_priority(const struct v4l2_ioctl_ops *ops, | |||
1046 | struct video_device *vfd; | 1048 | struct video_device *vfd; |
1047 | u32 *p = arg; | 1049 | u32 *p = arg; |
1048 | 1050 | ||
1049 | if (ops->vidioc_g_priority) | ||
1050 | return ops->vidioc_g_priority(file, fh, arg); | ||
1051 | vfd = video_devdata(file); | 1051 | vfd = video_devdata(file); |
1052 | *p = v4l2_prio_max(vfd->prio); | 1052 | *p = v4l2_prio_max(vfd->prio); |
1053 | return 0; | 1053 | return 0; |
@@ -1060,9 +1060,9 @@ static int v4l_s_priority(const struct v4l2_ioctl_ops *ops, | |||
1060 | struct v4l2_fh *vfh; | 1060 | struct v4l2_fh *vfh; |
1061 | u32 *p = arg; | 1061 | u32 *p = arg; |
1062 | 1062 | ||
1063 | if (ops->vidioc_s_priority) | ||
1064 | return ops->vidioc_s_priority(file, fh, *p); | ||
1065 | vfd = video_devdata(file); | 1063 | vfd = video_devdata(file); |
1064 | if (!test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) | ||
1065 | return -ENOTTY; | ||
1066 | vfh = file->private_data; | 1066 | vfh = file->private_data; |
1067 | return v4l2_prio_change(vfd->prio, &vfh->prio, *p); | 1067 | return v4l2_prio_change(vfd->prio, &vfh->prio, *p); |
1068 | } | 1068 | } |
diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c index 80c588f4e429..73824a5ada83 100644 --- a/drivers/media/v4l2-core/v4l2-mem2mem.c +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c | |||
@@ -97,7 +97,7 @@ EXPORT_SYMBOL(v4l2_m2m_get_vq); | |||
97 | */ | 97 | */ |
98 | void *v4l2_m2m_next_buf(struct v4l2_m2m_queue_ctx *q_ctx) | 98 | void *v4l2_m2m_next_buf(struct v4l2_m2m_queue_ctx *q_ctx) |
99 | { | 99 | { |
100 | struct v4l2_m2m_buffer *b = NULL; | 100 | struct v4l2_m2m_buffer *b; |
101 | unsigned long flags; | 101 | unsigned long flags; |
102 | 102 | ||
103 | spin_lock_irqsave(&q_ctx->rdy_spinlock, flags); | 103 | spin_lock_irqsave(&q_ctx->rdy_spinlock, flags); |
@@ -119,7 +119,7 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_next_buf); | |||
119 | */ | 119 | */ |
120 | void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx) | 120 | void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx) |
121 | { | 121 | { |
122 | struct v4l2_m2m_buffer *b = NULL; | 122 | struct v4l2_m2m_buffer *b; |
123 | unsigned long flags; | 123 | unsigned long flags; |
124 | 124 | ||
125 | spin_lock_irqsave(&q_ctx->rdy_spinlock, flags); | 125 | spin_lock_irqsave(&q_ctx->rdy_spinlock, flags); |
diff --git a/drivers/media/v4l2-core/v4l2-of.c b/drivers/media/v4l2-core/v4l2-of.c index b4ed9a955fbe..83143d39dea7 100644 --- a/drivers/media/v4l2-core/v4l2-of.c +++ b/drivers/media/v4l2-core/v4l2-of.c | |||
@@ -19,11 +19,10 @@ | |||
19 | 19 | ||
20 | #include <media/v4l2-of.h> | 20 | #include <media/v4l2-of.h> |
21 | 21 | ||
22 | static void v4l2_of_parse_csi_bus(const struct device_node *node, | 22 | static int v4l2_of_parse_csi_bus(const struct device_node *node, |
23 | struct v4l2_of_endpoint *endpoint) | 23 | struct v4l2_of_endpoint *endpoint) |
24 | { | 24 | { |
25 | struct v4l2_of_bus_mipi_csi2 *bus = &endpoint->bus.mipi_csi2; | 25 | struct v4l2_of_bus_mipi_csi2 *bus = &endpoint->bus.mipi_csi2; |
26 | u32 data_lanes[ARRAY_SIZE(bus->data_lanes)]; | ||
27 | struct property *prop; | 26 | struct property *prop; |
28 | bool have_clk_lane = false; | 27 | bool have_clk_lane = false; |
29 | unsigned int flags = 0; | 28 | unsigned int flags = 0; |
@@ -32,16 +31,34 @@ static void v4l2_of_parse_csi_bus(const struct device_node *node, | |||
32 | prop = of_find_property(node, "data-lanes", NULL); | 31 | prop = of_find_property(node, "data-lanes", NULL); |
33 | if (prop) { | 32 | if (prop) { |
34 | const __be32 *lane = NULL; | 33 | const __be32 *lane = NULL; |
35 | int i; | 34 | unsigned int i; |
36 | 35 | ||
37 | for (i = 0; i < ARRAY_SIZE(data_lanes); i++) { | 36 | for (i = 0; i < ARRAY_SIZE(bus->data_lanes); i++) { |
38 | lane = of_prop_next_u32(prop, lane, &data_lanes[i]); | 37 | lane = of_prop_next_u32(prop, lane, &v); |
39 | if (!lane) | 38 | if (!lane) |
40 | break; | 39 | break; |
40 | bus->data_lanes[i] = v; | ||
41 | } | 41 | } |
42 | bus->num_data_lanes = i; | 42 | bus->num_data_lanes = i; |
43 | while (i--) | 43 | } |
44 | bus->data_lanes[i] = data_lanes[i]; | 44 | |
45 | prop = of_find_property(node, "lane-polarities", NULL); | ||
46 | if (prop) { | ||
47 | const __be32 *polarity = NULL; | ||
48 | unsigned int i; | ||
49 | |||
50 | for (i = 0; i < ARRAY_SIZE(bus->lane_polarities); i++) { | ||
51 | polarity = of_prop_next_u32(prop, polarity, &v); | ||
52 | if (!polarity) | ||
53 | break; | ||
54 | bus->lane_polarities[i] = v; | ||
55 | } | ||
56 | |||
57 | if (i < 1 + bus->num_data_lanes /* clock + data */) { | ||
58 | pr_warn("%s: too few lane-polarities entries (need %u, got %u)\n", | ||
59 | node->full_name, 1 + bus->num_data_lanes, i); | ||
60 | return -EINVAL; | ||
61 | } | ||
45 | } | 62 | } |
46 | 63 | ||
47 | if (!of_property_read_u32(node, "clock-lanes", &v)) { | 64 | if (!of_property_read_u32(node, "clock-lanes", &v)) { |
@@ -56,6 +73,8 @@ static void v4l2_of_parse_csi_bus(const struct device_node *node, | |||
56 | 73 | ||
57 | bus->flags = flags; | 74 | bus->flags = flags; |
58 | endpoint->bus_type = V4L2_MBUS_CSI2; | 75 | endpoint->bus_type = V4L2_MBUS_CSI2; |
76 | |||
77 | return 0; | ||
59 | } | 78 | } |
60 | 79 | ||
61 | static void v4l2_of_parse_parallel_bus(const struct device_node *node, | 80 | static void v4l2_of_parse_parallel_bus(const struct device_node *node, |
@@ -127,11 +146,15 @@ static void v4l2_of_parse_parallel_bus(const struct device_node *node, | |||
127 | int v4l2_of_parse_endpoint(const struct device_node *node, | 146 | int v4l2_of_parse_endpoint(const struct device_node *node, |
128 | struct v4l2_of_endpoint *endpoint) | 147 | struct v4l2_of_endpoint *endpoint) |
129 | { | 148 | { |
149 | int rval; | ||
150 | |||
130 | of_graph_parse_endpoint(node, &endpoint->base); | 151 | of_graph_parse_endpoint(node, &endpoint->base); |
131 | endpoint->bus_type = 0; | 152 | endpoint->bus_type = 0; |
132 | memset(&endpoint->bus, 0, sizeof(endpoint->bus)); | 153 | memset(&endpoint->bus, 0, sizeof(endpoint->bus)); |
133 | 154 | ||
134 | v4l2_of_parse_csi_bus(node, endpoint); | 155 | rval = v4l2_of_parse_csi_bus(node, endpoint); |
156 | if (rval) | ||
157 | return rval; | ||
135 | /* | 158 | /* |
136 | * Parse the parallel video bus properties only if none | 159 | * Parse the parallel video bus properties only if none |
137 | * of the MIPI CSI-2 specific properties were found. | 160 | * of the MIPI CSI-2 specific properties were found. |
@@ -142,3 +165,64 @@ int v4l2_of_parse_endpoint(const struct device_node *node, | |||
142 | return 0; | 165 | return 0; |
143 | } | 166 | } |
144 | EXPORT_SYMBOL(v4l2_of_parse_endpoint); | 167 | EXPORT_SYMBOL(v4l2_of_parse_endpoint); |
168 | |||
169 | /** | ||
170 | * v4l2_of_parse_link() - parse a link between two endpoints | ||
171 | * @node: pointer to the endpoint at the local end of the link | ||
172 | * @link: pointer to the V4L2 OF link data structure | ||
173 | * | ||
174 | * Fill the link structure with the local and remote nodes and port numbers. | ||
175 | * The local_node and remote_node fields are set to point to the local and | ||
176 | * remote port's parent nodes respectively (the port parent node being the | ||
177 | * parent node of the port node if that node isn't a 'ports' node, or the | ||
178 | * grand-parent node of the port node otherwise). | ||
179 | * | ||
180 | * A reference is taken to both the local and remote nodes, the caller must use | ||
181 | * v4l2_of_put_link() to drop the references when done with the link. | ||
182 | * | ||
183 | * Return: 0 on success, or -ENOLINK if the remote endpoint can't be found. | ||
184 | */ | ||
185 | int v4l2_of_parse_link(const struct device_node *node, | ||
186 | struct v4l2_of_link *link) | ||
187 | { | ||
188 | struct device_node *np; | ||
189 | |||
190 | memset(link, 0, sizeof(*link)); | ||
191 | |||
192 | np = of_get_parent(node); | ||
193 | of_property_read_u32(np, "reg", &link->local_port); | ||
194 | np = of_get_next_parent(np); | ||
195 | if (of_node_cmp(np->name, "ports") == 0) | ||
196 | np = of_get_next_parent(np); | ||
197 | link->local_node = np; | ||
198 | |||
199 | np = of_parse_phandle(node, "remote-endpoint", 0); | ||
200 | if (!np) { | ||
201 | of_node_put(link->local_node); | ||
202 | return -ENOLINK; | ||
203 | } | ||
204 | |||
205 | np = of_get_parent(np); | ||
206 | of_property_read_u32(np, "reg", &link->remote_port); | ||
207 | np = of_get_next_parent(np); | ||
208 | if (of_node_cmp(np->name, "ports") == 0) | ||
209 | np = of_get_next_parent(np); | ||
210 | link->remote_node = np; | ||
211 | |||
212 | return 0; | ||
213 | } | ||
214 | EXPORT_SYMBOL(v4l2_of_parse_link); | ||
215 | |||
216 | /** | ||
217 | * v4l2_of_put_link() - drop references to nodes in a link | ||
218 | * @link: pointer to the V4L2 OF link data structure | ||
219 | * | ||
220 | * Drop references to the local and remote nodes in the link. This function must | ||
221 | * be called on every link parsed with v4l2_of_parse_link(). | ||
222 | */ | ||
223 | void v4l2_of_put_link(struct v4l2_of_link *link) | ||
224 | { | ||
225 | of_node_put(link->local_node); | ||
226 | of_node_put(link->remote_node); | ||
227 | } | ||
228 | EXPORT_SYMBOL(v4l2_of_put_link); | ||
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index 19a034e79be4..63596063b213 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c | |||
@@ -93,8 +93,7 @@ static int subdev_open(struct file *file) | |||
93 | 93 | ||
94 | err: | 94 | err: |
95 | #if defined(CONFIG_MEDIA_CONTROLLER) | 95 | #if defined(CONFIG_MEDIA_CONTROLLER) |
96 | if (entity) | 96 | media_entity_put(entity); |
97 | media_entity_put(entity); | ||
98 | #endif | 97 | #endif |
99 | v4l2_fh_del(&subdev_fh->vfh); | 98 | v4l2_fh_del(&subdev_fh->vfh); |
100 | v4l2_fh_exit(&subdev_fh->vfh); | 99 | v4l2_fh_exit(&subdev_fh->vfh); |
@@ -262,7 +261,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
262 | if (rval) | 261 | if (rval) |
263 | return rval; | 262 | return rval; |
264 | 263 | ||
265 | return v4l2_subdev_call(sd, pad, get_fmt, subdev_fh, format); | 264 | return v4l2_subdev_call(sd, pad, get_fmt, subdev_fh->pad, format); |
266 | } | 265 | } |
267 | 266 | ||
268 | case VIDIOC_SUBDEV_S_FMT: { | 267 | case VIDIOC_SUBDEV_S_FMT: { |
@@ -272,7 +271,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
272 | if (rval) | 271 | if (rval) |
273 | return rval; | 272 | return rval; |
274 | 273 | ||
275 | return v4l2_subdev_call(sd, pad, set_fmt, subdev_fh, format); | 274 | return v4l2_subdev_call(sd, pad, set_fmt, subdev_fh->pad, format); |
276 | } | 275 | } |
277 | 276 | ||
278 | case VIDIOC_SUBDEV_G_CROP: { | 277 | case VIDIOC_SUBDEV_G_CROP: { |
@@ -289,7 +288,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
289 | sel.target = V4L2_SEL_TGT_CROP; | 288 | sel.target = V4L2_SEL_TGT_CROP; |
290 | 289 | ||
291 | rval = v4l2_subdev_call( | 290 | rval = v4l2_subdev_call( |
292 | sd, pad, get_selection, subdev_fh, &sel); | 291 | sd, pad, get_selection, subdev_fh->pad, &sel); |
293 | 292 | ||
294 | crop->rect = sel.r; | 293 | crop->rect = sel.r; |
295 | 294 | ||
@@ -311,7 +310,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
311 | sel.r = crop->rect; | 310 | sel.r = crop->rect; |
312 | 311 | ||
313 | rval = v4l2_subdev_call( | 312 | rval = v4l2_subdev_call( |
314 | sd, pad, set_selection, subdev_fh, &sel); | 313 | sd, pad, set_selection, subdev_fh->pad, &sel); |
315 | 314 | ||
316 | crop->rect = sel.r; | 315 | crop->rect = sel.r; |
317 | 316 | ||
@@ -321,20 +320,28 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
321 | case VIDIOC_SUBDEV_ENUM_MBUS_CODE: { | 320 | case VIDIOC_SUBDEV_ENUM_MBUS_CODE: { |
322 | struct v4l2_subdev_mbus_code_enum *code = arg; | 321 | struct v4l2_subdev_mbus_code_enum *code = arg; |
323 | 322 | ||
323 | if (code->which != V4L2_SUBDEV_FORMAT_TRY && | ||
324 | code->which != V4L2_SUBDEV_FORMAT_ACTIVE) | ||
325 | return -EINVAL; | ||
326 | |||
324 | if (code->pad >= sd->entity.num_pads) | 327 | if (code->pad >= sd->entity.num_pads) |
325 | return -EINVAL; | 328 | return -EINVAL; |
326 | 329 | ||
327 | return v4l2_subdev_call(sd, pad, enum_mbus_code, subdev_fh, | 330 | return v4l2_subdev_call(sd, pad, enum_mbus_code, subdev_fh->pad, |
328 | code); | 331 | code); |
329 | } | 332 | } |
330 | 333 | ||
331 | case VIDIOC_SUBDEV_ENUM_FRAME_SIZE: { | 334 | case VIDIOC_SUBDEV_ENUM_FRAME_SIZE: { |
332 | struct v4l2_subdev_frame_size_enum *fse = arg; | 335 | struct v4l2_subdev_frame_size_enum *fse = arg; |
333 | 336 | ||
337 | if (fse->which != V4L2_SUBDEV_FORMAT_TRY && | ||
338 | fse->which != V4L2_SUBDEV_FORMAT_ACTIVE) | ||
339 | return -EINVAL; | ||
340 | |||
334 | if (fse->pad >= sd->entity.num_pads) | 341 | if (fse->pad >= sd->entity.num_pads) |
335 | return -EINVAL; | 342 | return -EINVAL; |
336 | 343 | ||
337 | return v4l2_subdev_call(sd, pad, enum_frame_size, subdev_fh, | 344 | return v4l2_subdev_call(sd, pad, enum_frame_size, subdev_fh->pad, |
338 | fse); | 345 | fse); |
339 | } | 346 | } |
340 | 347 | ||
@@ -359,10 +366,14 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
359 | case VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL: { | 366 | case VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL: { |
360 | struct v4l2_subdev_frame_interval_enum *fie = arg; | 367 | struct v4l2_subdev_frame_interval_enum *fie = arg; |
361 | 368 | ||
369 | if (fie->which != V4L2_SUBDEV_FORMAT_TRY && | ||
370 | fie->which != V4L2_SUBDEV_FORMAT_ACTIVE) | ||
371 | return -EINVAL; | ||
372 | |||
362 | if (fie->pad >= sd->entity.num_pads) | 373 | if (fie->pad >= sd->entity.num_pads) |
363 | return -EINVAL; | 374 | return -EINVAL; |
364 | 375 | ||
365 | return v4l2_subdev_call(sd, pad, enum_frame_interval, subdev_fh, | 376 | return v4l2_subdev_call(sd, pad, enum_frame_interval, subdev_fh->pad, |
366 | fie); | 377 | fie); |
367 | } | 378 | } |
368 | 379 | ||
@@ -374,7 +385,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
374 | return rval; | 385 | return rval; |
375 | 386 | ||
376 | return v4l2_subdev_call( | 387 | return v4l2_subdev_call( |
377 | sd, pad, get_selection, subdev_fh, sel); | 388 | sd, pad, get_selection, subdev_fh->pad, sel); |
378 | } | 389 | } |
379 | 390 | ||
380 | case VIDIOC_SUBDEV_S_SELECTION: { | 391 | case VIDIOC_SUBDEV_S_SELECTION: { |
@@ -385,7 +396,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
385 | return rval; | 396 | return rval; |
386 | 397 | ||
387 | return v4l2_subdev_call( | 398 | return v4l2_subdev_call( |
388 | sd, pad, set_selection, subdev_fh, sel); | 399 | sd, pad, set_selection, subdev_fh->pad, sel); |
389 | } | 400 | } |
390 | 401 | ||
391 | case VIDIOC_G_EDID: { | 402 | case VIDIOC_G_EDID: { |
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index cc16e76a2493..0931eaa75768 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c | |||
@@ -1247,6 +1247,16 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b | |||
1247 | { | 1247 | { |
1248 | unsigned int plane; | 1248 | unsigned int plane; |
1249 | 1249 | ||
1250 | if (V4L2_TYPE_IS_OUTPUT(b->type)) { | ||
1251 | if (WARN_ON_ONCE(b->bytesused == 0)) { | ||
1252 | pr_warn_once("use of bytesused == 0 is deprecated and will be removed in the future,\n"); | ||
1253 | if (vb->vb2_queue->allow_zero_bytesused) | ||
1254 | pr_warn_once("use VIDIOC_DECODER_CMD(V4L2_DEC_CMD_STOP) instead.\n"); | ||
1255 | else | ||
1256 | pr_warn_once("use the actual size instead.\n"); | ||
1257 | } | ||
1258 | } | ||
1259 | |||
1250 | if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) { | 1260 | if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) { |
1251 | if (b->memory == V4L2_MEMORY_USERPTR) { | 1261 | if (b->memory == V4L2_MEMORY_USERPTR) { |
1252 | for (plane = 0; plane < vb->num_planes; ++plane) { | 1262 | for (plane = 0; plane < vb->num_planes; ++plane) { |
@@ -1276,13 +1286,22 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b | |||
1276 | * userspace clearly never bothered to set it and | 1286 | * userspace clearly never bothered to set it and |
1277 | * it's a safe assumption that they really meant to | 1287 | * it's a safe assumption that they really meant to |
1278 | * use the full plane sizes. | 1288 | * use the full plane sizes. |
1289 | * | ||
1290 | * Some drivers, e.g. old codec drivers, use bytesused == 0 | ||
1291 | * as a way to indicate that streaming is finished. | ||
1292 | * In that case, the driver should use the | ||
1293 | * allow_zero_bytesused flag to keep old userspace | ||
1294 | * applications working. | ||
1279 | */ | 1295 | */ |
1280 | for (plane = 0; plane < vb->num_planes; ++plane) { | 1296 | for (plane = 0; plane < vb->num_planes; ++plane) { |
1281 | struct v4l2_plane *pdst = &v4l2_planes[plane]; | 1297 | struct v4l2_plane *pdst = &v4l2_planes[plane]; |
1282 | struct v4l2_plane *psrc = &b->m.planes[plane]; | 1298 | struct v4l2_plane *psrc = &b->m.planes[plane]; |
1283 | 1299 | ||
1284 | pdst->bytesused = psrc->bytesused ? | 1300 | if (vb->vb2_queue->allow_zero_bytesused) |
1285 | psrc->bytesused : pdst->length; | 1301 | pdst->bytesused = psrc->bytesused; |
1302 | else | ||
1303 | pdst->bytesused = psrc->bytesused ? | ||
1304 | psrc->bytesused : pdst->length; | ||
1286 | pdst->data_offset = psrc->data_offset; | 1305 | pdst->data_offset = psrc->data_offset; |
1287 | } | 1306 | } |
1288 | } | 1307 | } |
@@ -1295,6 +1314,11 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b | |||
1295 | * | 1314 | * |
1296 | * If bytesused == 0 for the output buffer, then fall back | 1315 | * If bytesused == 0 for the output buffer, then fall back |
1297 | * to the full buffer size as that's a sensible default. | 1316 | * to the full buffer size as that's a sensible default. |
1317 | * | ||
1318 | * Some drivers, e.g. old codec drivers, use bytesused == 0 as | ||
1319 | * a way to indicate that streaming is finished. In that case, | ||
1320 | * the driver should use the allow_zero_bytesused flag to keep | ||
1321 | * old userspace applications working. | ||
1298 | */ | 1322 | */ |
1299 | if (b->memory == V4L2_MEMORY_USERPTR) { | 1323 | if (b->memory == V4L2_MEMORY_USERPTR) { |
1300 | v4l2_planes[0].m.userptr = b->m.userptr; | 1324 | v4l2_planes[0].m.userptr = b->m.userptr; |
@@ -1306,10 +1330,13 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b | |||
1306 | v4l2_planes[0].length = b->length; | 1330 | v4l2_planes[0].length = b->length; |
1307 | } | 1331 | } |
1308 | 1332 | ||
1309 | if (V4L2_TYPE_IS_OUTPUT(b->type)) | 1333 | if (V4L2_TYPE_IS_OUTPUT(b->type)) { |
1310 | v4l2_planes[0].bytesused = b->bytesused ? | 1334 | if (vb->vb2_queue->allow_zero_bytesused) |
1311 | b->bytesused : v4l2_planes[0].length; | 1335 | v4l2_planes[0].bytesused = b->bytesused; |
1312 | else | 1336 | else |
1337 | v4l2_planes[0].bytesused = b->bytesused ? | ||
1338 | b->bytesused : v4l2_planes[0].length; | ||
1339 | } else | ||
1313 | v4l2_planes[0].bytesused = 0; | 1340 | v4l2_planes[0].bytesused = 0; |
1314 | 1341 | ||
1315 | } | 1342 | } |
@@ -2760,7 +2787,8 @@ struct vb2_fileio_data { | |||
2760 | unsigned int initial_index; | 2787 | unsigned int initial_index; |
2761 | unsigned int q_count; | 2788 | unsigned int q_count; |
2762 | unsigned int dq_count; | 2789 | unsigned int dq_count; |
2763 | unsigned int flags; | 2790 | unsigned read_once:1; |
2791 | unsigned write_immediately:1; | ||
2764 | }; | 2792 | }; |
2765 | 2793 | ||
2766 | /** | 2794 | /** |
@@ -2798,14 +2826,16 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read) | |||
2798 | */ | 2826 | */ |
2799 | count = 1; | 2827 | count = 1; |
2800 | 2828 | ||
2801 | dprintk(3, "setting up file io: mode %s, count %d, flags %08x\n", | 2829 | dprintk(3, "setting up file io: mode %s, count %d, read_once %d, write_immediately %d\n", |
2802 | (read) ? "read" : "write", count, q->io_flags); | 2830 | (read) ? "read" : "write", count, q->fileio_read_once, |
2831 | q->fileio_write_immediately); | ||
2803 | 2832 | ||
2804 | fileio = kzalloc(sizeof(struct vb2_fileio_data), GFP_KERNEL); | 2833 | fileio = kzalloc(sizeof(struct vb2_fileio_data), GFP_KERNEL); |
2805 | if (fileio == NULL) | 2834 | if (fileio == NULL) |
2806 | return -ENOMEM; | 2835 | return -ENOMEM; |
2807 | 2836 | ||
2808 | fileio->flags = q->io_flags; | 2837 | fileio->read_once = q->fileio_read_once; |
2838 | fileio->write_immediately = q->fileio_write_immediately; | ||
2809 | 2839 | ||
2810 | /* | 2840 | /* |
2811 | * Request buffers and use MMAP type to force driver | 2841 | * Request buffers and use MMAP type to force driver |
@@ -3028,13 +3058,11 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_ | |||
3028 | /* | 3058 | /* |
3029 | * Queue next buffer if required. | 3059 | * Queue next buffer if required. |
3030 | */ | 3060 | */ |
3031 | if (buf->pos == buf->size || | 3061 | if (buf->pos == buf->size || (!read && fileio->write_immediately)) { |
3032 | (!read && (fileio->flags & VB2_FILEIO_WRITE_IMMEDIATELY))) { | ||
3033 | /* | 3062 | /* |
3034 | * Check if this is the last buffer to read. | 3063 | * Check if this is the last buffer to read. |
3035 | */ | 3064 | */ |
3036 | if (read && (fileio->flags & VB2_FILEIO_READ_ONCE) && | 3065 | if (read && fileio->read_once && fileio->dq_count == 1) { |
3037 | fileio->dq_count == 1) { | ||
3038 | dprintk(3, "read limit reached\n"); | 3066 | dprintk(3, "read limit reached\n"); |
3039 | return __vb2_cleanup_fileio(q); | 3067 | return __vb2_cleanup_fileio(q); |
3040 | } | 3068 | } |
@@ -3411,6 +3439,8 @@ ssize_t vb2_fop_write(struct file *file, const char __user *buf, | |||
3411 | struct mutex *lock = vdev->queue->lock ? vdev->queue->lock : vdev->lock; | 3439 | struct mutex *lock = vdev->queue->lock ? vdev->queue->lock : vdev->lock; |
3412 | int err = -EBUSY; | 3440 | int err = -EBUSY; |
3413 | 3441 | ||
3442 | if (!(vdev->queue->io_modes & VB2_WRITE)) | ||
3443 | return -EINVAL; | ||
3414 | if (lock && mutex_lock_interruptible(lock)) | 3444 | if (lock && mutex_lock_interruptible(lock)) |
3415 | return -ERESTARTSYS; | 3445 | return -ERESTARTSYS; |
3416 | if (vb2_queue_is_busy(vdev, file)) | 3446 | if (vb2_queue_is_busy(vdev, file)) |
@@ -3433,6 +3463,8 @@ ssize_t vb2_fop_read(struct file *file, char __user *buf, | |||
3433 | struct mutex *lock = vdev->queue->lock ? vdev->queue->lock : vdev->lock; | 3463 | struct mutex *lock = vdev->queue->lock ? vdev->queue->lock : vdev->lock; |
3434 | int err = -EBUSY; | 3464 | int err = -EBUSY; |
3435 | 3465 | ||
3466 | if (!(vdev->queue->io_modes & VB2_READ)) | ||
3467 | return -EINVAL; | ||
3436 | if (lock && mutex_lock_interruptible(lock)) | 3468 | if (lock && mutex_lock_interruptible(lock)) |
3437 | return -ERESTARTSYS; | 3469 | return -ERESTARTSYS; |
3438 | if (vb2_queue_is_busy(vdev, file)) | 3470 | if (vb2_queue_is_busy(vdev, file)) |