diff options
author | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2015-02-18 10:22:27 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2015-02-26 06:45:25 -0500 |
commit | 3d263114c4b75d06253f0ed8059164dbc70c9f0c (patch) | |
tree | 6f859fd9932aeb075fae1b655c1ed8a5265be325 | |
parent | 7e2b41e9127e4e4ceeb2d4e86405846974cc4cec (diff) |
[media] cx231xx: enable the analog tuner at buffer setup
buf_prepare callback is called for every queued buffer. This is
an overkill. Call it at buf_setup, as this should be enough.
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
-rw-r--r-- | drivers/media/usb/cx231xx/cx231xx-video.c | 143 |
1 files changed, 72 insertions, 71 deletions
diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index 86ad746cc4cb..acc1b68c408e 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 | ||
@@ -703,75 +775,6 @@ static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf) | |||
703 | buf->vb.state = VIDEOBUF_NEEDS_INIT; | 775 | buf->vb.state = VIDEOBUF_NEEDS_INIT; |
704 | } | 776 | } |
705 | 777 | ||
706 | static int cx231xx_enable_analog_tuner(struct cx231xx *dev) | ||
707 | { | ||
708 | #ifdef CONFIG_MEDIA_CONTROLLER | ||
709 | struct media_device *mdev = dev->media_dev; | ||
710 | struct media_entity *entity, *decoder = NULL, *source; | ||
711 | struct media_link *link, *found_link = NULL; | ||
712 | int i, ret, active_links = 0; | ||
713 | |||
714 | if (!mdev) | ||
715 | return 0; | ||
716 | |||
717 | /* | ||
718 | * This will find the tuner that is connected into the decoder. | ||
719 | * Technically, this is not 100% correct, as the device may be | ||
720 | * using an analog input instead of the tuner. However, as we can't | ||
721 | * do DVB streaming while the DMA engine is being used for V4L2, | ||
722 | * this should be enough for the actual needs. | ||
723 | */ | ||
724 | media_device_for_each_entity(entity, mdev) { | ||
725 | if (entity->type == MEDIA_ENT_T_V4L2_SUBDEV_DECODER) { | ||
726 | decoder = entity; | ||
727 | break; | ||
728 | } | ||
729 | } | ||
730 | if (!decoder) | ||
731 | return 0; | ||
732 | |||
733 | for (i = 0; i < decoder->num_links; i++) { | ||
734 | link = &decoder->links[i]; | ||
735 | if (link->sink->entity == decoder) { | ||
736 | found_link = link; | ||
737 | if (link->flags & MEDIA_LNK_FL_ENABLED) | ||
738 | active_links++; | ||
739 | break; | ||
740 | } | ||
741 | } | ||
742 | |||
743 | if (active_links == 1 || !found_link) | ||
744 | return 0; | ||
745 | |||
746 | source = found_link->source->entity; | ||
747 | for (i = 0; i < source->num_links; i++) { | ||
748 | struct media_entity *sink; | ||
749 | int flags = 0; | ||
750 | |||
751 | link = &source->links[i]; | ||
752 | sink = link->sink->entity; | ||
753 | |||
754 | if (sink == entity) | ||
755 | flags = MEDIA_LNK_FL_ENABLED; | ||
756 | |||
757 | ret = media_entity_setup_link(link, flags); | ||
758 | if (ret) { | ||
759 | dev_err(dev->dev, | ||
760 | "Couldn't change link %s->%s to %s. Error %d\n", | ||
761 | source->name, sink->name, | ||
762 | flags ? "enabled" : "disabled", | ||
763 | ret); | ||
764 | return ret; | ||
765 | } else | ||
766 | dev_dbg(dev->dev, | ||
767 | "link %s->%s was %s\n", | ||
768 | source->name, sink->name, | ||
769 | flags ? "ENABLED" : "disabled"); | ||
770 | } | ||
771 | #endif | ||
772 | return 0; | ||
773 | } | ||
774 | |||
775 | static int | 778 | static int |
776 | buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, | 779 | buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, |
777 | enum v4l2_field field) | 780 | enum v4l2_field field) |
@@ -826,8 +829,6 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, | |||
826 | 829 | ||
827 | buf->vb.state = VIDEOBUF_PREPARED; | 830 | buf->vb.state = VIDEOBUF_PREPARED; |
828 | 831 | ||
829 | cx231xx_enable_analog_tuner(dev); | ||
830 | |||
831 | return 0; | 832 | return 0; |
832 | 833 | ||
833 | fail: | 834 | fail: |