Add media device change_source handler. Using the change_source handler,
driver can disable current source and enable new one in one step when
user selects a new input.

Signed-off-by: Shuah Khan <shua...@osg.samsung.com>
---
 drivers/media/usb/au0828/au0828-core.c | 64 ++++++++++++++++++++++++----------
 1 file changed, 46 insertions(+), 18 deletions(-)

diff --git a/drivers/media/usb/au0828/au0828-core.c 
b/drivers/media/usb/au0828/au0828-core.c
index 5dc82e8..01dba5a 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -258,8 +258,8 @@ create_link:
        }
 }
 
-static int au0828_enable_source(struct media_entity *entity,
-                               struct media_pipeline *pipe)
+static int __au0828_enable_source(struct media_entity *entity,
+                                 struct media_pipeline *pipe)
 {
        struct media_entity  *source, *find_source;
        struct media_entity *sink;
@@ -268,11 +268,6 @@ static int au0828_enable_source(struct media_entity 
*entity,
        struct media_device *mdev = entity->graph_obj.mdev;
        struct au0828_dev *dev;
 
-       if (!mdev)
-               return -ENODEV;
-
-       mutex_lock(&mdev->graph_mutex);
-
        dev = mdev->source_priv;
 
        /*
@@ -399,28 +394,36 @@ static int au0828_enable_source(struct media_entity 
*entity,
                 dev->active_source->name, dev->active_sink->name,
                 dev->active_link_owner->name, ret);
 end:
-       mutex_unlock(&mdev->graph_mutex);
        pr_debug("au0828_enable_source() end %s %d %d\n",
                 entity->name, entity->function, ret);
        return ret;
 }
 
-static void au0828_disable_source(struct media_entity *entity)
+static int au0828_enable_source(struct media_entity *entity,
+                               struct media_pipeline *pipe)
 {
-       int ret = 0;
        struct media_device *mdev = entity->graph_obj.mdev;
-       struct au0828_dev *dev;
+       int ret;
 
        if (!mdev)
-               return;
+               return -ENODEV;
 
        mutex_lock(&mdev->graph_mutex);
+       ret = __au0828_enable_source(entity, pipe);
+       mutex_unlock(&mdev->graph_mutex);
+       return ret;
+}
+
+static void __au0828_disable_source(struct media_entity *entity)
+{
+       int ret = 0;
+       struct media_device *mdev = entity->graph_obj.mdev;
+       struct au0828_dev *dev;
+
        dev = mdev->source_priv;
 
-       if (!dev->active_link) {
-               ret = -ENODEV;
-               goto end;
-       }
+       if (!dev->active_link)
+               return;
 
        /* link is active - stop pipeline from source (tuner) */
        if (dev->active_link->sink->entity == dev->active_sink &&
@@ -430,7 +433,7 @@ static void au0828_disable_source(struct media_entity 
*entity)
                 * has active pipeline
                */
                if (dev->active_link_owner != entity)
-                       goto end;
+                       return;
                __media_entity_pipeline_stop(entity);
                ret = __media_entity_setup_link(dev->active_link, 0);
                if (ret)
@@ -445,10 +448,34 @@ static void au0828_disable_source(struct media_entity 
*entity)
                dev->active_source = NULL;
                dev->active_sink = NULL;
        }
+}
 
-end:
+static void au0828_disable_source(struct media_entity *entity)
+{
+       struct media_device *mdev = entity->graph_obj.mdev;
+
+       if (!mdev)
+               return;
+
+       mutex_lock(&mdev->graph_mutex);
+       __au0828_disable_source(entity);
        mutex_unlock(&mdev->graph_mutex);
 }
+static int au0828_change_source(struct media_entity *entity,
+                               struct media_pipeline *pipe)
+{
+       struct media_device *mdev = entity->graph_obj.mdev;
+       int ret;
+
+       if (!mdev)
+               return -ENODEV;
+
+       mutex_lock(&mdev->graph_mutex);
+       __au0828_disable_source(entity);
+       ret = __au0828_enable_source(entity, pipe);
+       mutex_unlock(&mdev->graph_mutex);
+       return ret;
+}
 #endif
 
 static int au0828_media_device_register(struct au0828_dev *dev,
@@ -520,6 +547,7 @@ static int au0828_media_device_register(struct au0828_dev 
*dev,
        dev->media_dev->source_priv = (void *) dev;
        dev->media_dev->enable_source = au0828_enable_source;
        dev->media_dev->disable_source = au0828_disable_source;
+       dev->media_dev->change_source = au0828_change_source;
 #endif
        return 0;
 }
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to