aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@osg.samsung.com>2015-02-18 10:22:27 -0500
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2015-02-26 06:45:25 -0500
commit3d263114c4b75d06253f0ed8059164dbc70c9f0c (patch)
tree6f859fd9932aeb075fae1b655c1ed8a5265be325
parent7e2b41e9127e4e4ceeb2d4e86405846974cc4cec (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.c143
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
103static 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
706static 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
775static int 778static int
776buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, 779buffer_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
833fail: 834fail: