linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 00/21] Update ALSA, and au0828 drivers to use Managed Media Controller API
@ 2015-09-22 17:19 Shuah Khan
  2015-09-22 17:19 ` [PATCH v3 01/21] Revert "[media] media: media controller entity framework enhancements for ALSA" Shuah Khan
                   ` (20 more replies)
  0 siblings, 21 replies; 22+ messages in thread
From: Shuah Khan @ 2015-09-22 17:19 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, sakari.ailus, tiwai,
	pawel, m.szyprowski, kyungmin.park, perex, stefanr, crope,
	dan.carpenter, tskd08, ruchandani.tina, arnd, chehabrafael,
	prabhakar.csengg, Julia.Lawall, elfring, ricardo.ribalda,
	chris.j.arges, pierre-louis.bossart, gtmkramer, clemens,
	misterpib, takamichiho, pmatilai, damien, daniel, vladcatoi,
	normalperson, joe, bugzilla.frnkcg, jussi
  Cc: Shuah Khan, linux-media, alsa-devel

This patch series updates ALSA driver, and au0828 core driver to
use Managed Media controller API to share tuner. Please note that
Managed Media Controller API and DVB and V4L2 drivers updates to
use Media Controller API have been added in a prior patch series.

Media Controller API is enhanced with two new interfaces to
register and unregister entity_notify hooks to allow drivers
to take appropriate actions when as new entities get added to
the shared media device.

Tested exclusion between digital, analog, and audio to ensure
when tuner has an active link to DVB FE, analog, and audio will
detect and honor the tuner busy conditions and vice versa.

Changes since v2:
http://www.spinics.net/lists/linux-media/msg91926.html

1. An important change in this patch series is made to ALSA
   to check for resources and hold in snd_usb_hw_params(),
   and release from snd_usb_hw_free(). This change fixed the
   lockdep warnings seen when resources were held in
   TRIGGER_START and released from TRIGGER_STOP which could
   run in IRQ context. I acknowledge Clemens Ladisch for
   suggesting the correct places to hold/free resources to
   avoid IRQ path complications.
2. With the above change, the patch series is simpler without
   the need to change the graph_mutex into a spinlock.
3. I split the patches up differently for easy reviews - no code
   bloat from v2.
4. A second important change is now the Bridge driver (au0828)
   owns and drives the graph creation as well as enabling and
   disabling tuner. It also keeps state information to avoid
   graph walks in enable_source and disable_source handler.
   I acknowledge Hans Verkuil for his suggestions and ideas
   for this change.

History:
This patch series has been updated to address comments from
3 previous versions of this series. Links to v3 version
for reference are:

https://www.mail-archive.com/linux-media%40vger.kernel.org/msg89491.html
https://www.mail-archive.com/linux-media@vger.kernel.org/msg89492.html
https://www.mail-archive.com/linux-media%40vger.kernel.org/msg89493.html

Shuah Khan (21):
  Revert "[media] media: media controller entity framework enhancements
    for ALSA"
  media: Media Controller register/unregister entity_notify API
  media: Add ALSA Media Controller devnodes
  media: Media Controller enable/disable source handler API
  media: Media Controller fix to not let stream_count go negative
  media: Media Controller export non locking __media_entity_setup_link()
  media: Media Controller non-locking
    __media_entity_pipeline_start/stop()
  media: v4l-core add v4l_enable/disable_media_tuner() helper functions
  media: Move au8522_media_pads enum to au8522.h from au8522_priv.h
  media: au8522 change to create MC pad for ALSA Audio Out
  media: au0828 Use au8522_media_pads enum for pad defines
  media: au0828 fix au0828_create_media_graph() entity checks
  media: Change v4l-core to check for tuner availability
  media: dvb-frontend invoke enable/disable_source handlers
  media: au0828 video remove au0828_enable_analog_tuner()
  media: au0828 video change to use v4l_enable_media_tuner()
  media: au0828 change to use Managed Media Controller API
  media: au0828 change to register/unregister entity_notify hook
  media: au0828 implement enable_source and disable_source handlers
  media: media: dvb-frontend fix enable_source error legs
  sound/usb: Update ALSA driver to use Managed Media Controller API

 drivers/media/dvb-core/dvb_frontend.c        | 142 ++-----------
 drivers/media/dvb-core/dvb_frontend.h        |   3 +
 drivers/media/dvb-frontends/au8522.h         |   8 +
 drivers/media/dvb-frontends/au8522_decoder.c |   1 +
 drivers/media/dvb-frontends/au8522_priv.h    |   8 -
 drivers/media/media-device.c                 |  46 +++-
 drivers/media/media-entity.c                 |  64 ++++--
 drivers/media/usb/au0828/au0828-core.c       | 305 ++++++++++++++++++++++-----
 drivers/media/usb/au0828/au0828-video.c      |  76 ++-----
 drivers/media/usb/au0828/au0828.h            |   8 +
 drivers/media/v4l2-core/v4l2-dev.c           |  27 +++
 drivers/media/v4l2-core/v4l2-fh.c            |   1 +
 drivers/media/v4l2-core/v4l2-ioctl.c         |  29 +++
 drivers/media/v4l2-core/videobuf2-core.c     |   3 +
 include/media/media-device.h                 |  41 ++++
 include/media/media-entity.h                 |   7 +-
 include/media/v4l2-dev.h                     |   4 +
 include/uapi/linux/media.h                   |   5 +
 sound/usb/Makefile                           |  15 +-
 sound/usb/card.c                             |   5 +
 sound/usb/card.h                             |   1 +
 sound/usb/media.c                            | 178 ++++++++++++++++
 sound/usb/media.h                            |  51 +++++
 sound/usb/pcm.c                              |  29 ++-
 sound/usb/quirks-table.h                     |   1 +
 sound/usb/quirks.c                           |   9 +-
 sound/usb/stream.c                           |   2 +
 sound/usb/usbaudio.h                         |   1 +
 28 files changed, 790 insertions(+), 280 deletions(-)
 create mode 100644 sound/usb/media.c
 create mode 100644 sound/usb/media.h

-- 
2.1.4


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v3 01/21] Revert "[media] media: media controller entity framework enhancements for ALSA"
  2015-09-22 17:19 [PATCH v3 00/21] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
@ 2015-09-22 17:19 ` Shuah Khan
  2015-09-22 17:19 ` [PATCH v3 02/21] media: Media Controller register/unregister entity_notify API Shuah Khan
                   ` (19 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Shuah Khan @ 2015-09-22 17:19 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, sakari.ailus, tiwai,
	pawel, m.szyprowski, kyungmin.park, perex, stefanr, crope,
	dan.carpenter, tskd08, ruchandani.tina, arnd, chehabrafael,
	prabhakar.csengg, Julia.Lawall, elfring, ricardo.ribalda,
	chris.j.arges, pierre-louis.bossart, gtmkramer, clemens,
	misterpib, takamichiho, pmatilai, damien, daniel, vladcatoi,
	normalperson, joe, bugzilla.frnkcg, jussi
  Cc: Shuah Khan, linux-media, alsa-devel

This reverts commit ed64cf1e182fb30fe67652386c0880fcf3302f97.
This patch is no longer necessary as the entity register
callback is implemented at media_device level.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/media-device.c | 7 -------
 include/media/media-entity.h | 4 ----
 2 files changed, 11 deletions(-)

diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index 76590ba..c55ab50 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -428,8 +428,6 @@ EXPORT_SYMBOL_GPL(media_device_unregister);
 int __must_check media_device_register_entity(struct media_device *mdev,
 					      struct media_entity *entity)
 {
-	struct media_entity *eptr;
-
 	/* Warn if we apparently re-register an entity */
 	WARN_ON(entity->parent != NULL);
 	entity->parent = mdev;
@@ -442,11 +440,6 @@ int __must_check media_device_register_entity(struct media_device *mdev,
 	list_add_tail(&entity->list, &mdev->entities);
 	spin_unlock(&mdev->lock);
 
-	media_device_for_each_entity(eptr, mdev) {
-		if (eptr != entity)
-			media_entity_call(eptr, register_notify);
-	}
-
 	return 0;
 }
 EXPORT_SYMBOL_GPL(media_device_register_entity);
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index 0bc4c2f..0c003d8 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -46,7 +46,6 @@ struct media_pad {
 
 /**
  * struct media_entity_operations - Media entity operations
- * @register_notify	Notify entity of newly registered entity
  * @link_setup:		Notify the entity of link changes. The operation can
  *			return an error, in which case link setup will be
  *			cancelled. Optional.
@@ -55,7 +54,6 @@ struct media_pad {
  *			validates all links by calling this operation. Optional.
  */
 struct media_entity_operations {
-	int (*register_notify)(struct media_entity *entity);
 	int (*link_setup)(struct media_entity *entity,
 			  const struct media_pad *local,
 			  const struct media_pad *remote, u32 flags);
@@ -103,8 +101,6 @@ struct media_entity {
 		/* Sub-device specifications */
 		/* Nothing needed yet */
 	} info;
-
-	void *private;			/* private data for the entity */
 };
 
 static inline u32 media_entity_type(struct media_entity *entity)
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v3 02/21] media: Media Controller register/unregister entity_notify API
  2015-09-22 17:19 [PATCH v3 00/21] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
  2015-09-22 17:19 ` [PATCH v3 01/21] Revert "[media] media: media controller entity framework enhancements for ALSA" Shuah Khan
@ 2015-09-22 17:19 ` Shuah Khan
  2015-09-22 17:19 ` [PATCH v3 03/21] media: Add ALSA Media Controller devnodes Shuah Khan
                   ` (18 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Shuah Khan @ 2015-09-22 17:19 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, sakari.ailus, tiwai,
	pawel, m.szyprowski, kyungmin.park, perex, stefanr, crope,
	dan.carpenter, tskd08, ruchandani.tina, arnd, chehabrafael,
	prabhakar.csengg, Julia.Lawall, elfring, ricardo.ribalda,
	chris.j.arges, pierre-louis.bossart, gtmkramer, clemens,
	misterpib, takamichiho, pmatilai, damien, daniel, vladcatoi,
	normalperson, joe, bugzilla.frnkcg, jussi
  Cc: Shuah Khan, linux-media, alsa-devel

Add new interfaces to register and unregister entity_notify
hook to media device to allow drivers to take appropriate
actions when as new entities get added to the shared media
device.When a new entity is registered, all registered
entity_notify hooks are invoked to allow drivers or modules
that registered hook to take appropriate action. For example,
ALSA driver registers an entity_notify hook to parse the list
of registered entities to determine if decoder has been linked
to ALSA entity. au0828 bridge driver registers an entity_notify
hook to create media graph for the device.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/media-device.c | 45 ++++++++++++++++++++++++++++++++++++++++++++
 include/media/media-device.h | 23 ++++++++++++++++++++++
 2 files changed, 68 insertions(+)

diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index c55ab50..22565a8 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -381,6 +381,7 @@ int __must_check __media_device_register(struct media_device *mdev,
 
 	mdev->entity_id = 1;
 	INIT_LIST_HEAD(&mdev->entities);
+	INIT_LIST_HEAD(&mdev->entity_notify);
 	spin_lock_init(&mdev->lock);
 	mutex_init(&mdev->graph_mutex);
 
@@ -411,9 +412,12 @@ void media_device_unregister(struct media_device *mdev)
 {
 	struct media_entity *entity;
 	struct media_entity *next;
+	struct media_entity_notify *notify, *nextp;
 
 	list_for_each_entry_safe(entity, next, &mdev->entities, list)
 		media_device_unregister_entity(entity);
+	list_for_each_entry_safe(notify, nextp, &mdev->entity_notify, list)
+		media_device_unregister_entity_notify(mdev, notify);
 
 	device_remove_file(&mdev->devnode.dev, &dev_attr_model);
 	media_devnode_unregister(&mdev->devnode);
@@ -421,6 +425,39 @@ void media_device_unregister(struct media_device *mdev)
 EXPORT_SYMBOL_GPL(media_device_unregister);
 
 /**
+ * media_device_register_entity_notify - Register a media entity notify
+ * callback with a media device. When a new entity is registered, all
+ * the registered media_entity_notify callbacks are invoked.
+ * @mdev:	The media device
+ * @nptr:	The media_entity_notify
+ */
+int __must_check media_device_register_entity_notify(struct media_device *mdev,
+					struct media_entity_notify *nptr)
+{
+	spin_lock(&mdev->lock);
+	list_add_tail(&nptr->list, &mdev->entity_notify);
+	spin_unlock(&mdev->lock);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(media_device_register_entity_notify);
+
+/**
+ * media_device_unregister_entity_notify - Unregister a media entity notify
+ * callback with a media device. When a new entity is registered, all
+ * the registered media_entity_notify callbacks are invoked.
+ * @mdev:	The media device
+ * @nptr:	The media_entity_notify
+ */
+void media_device_unregister_entity_notify(struct media_device *mdev,
+					struct media_entity_notify *nptr)
+{
+	spin_lock(&mdev->lock);
+	list_del(&nptr->list);
+	spin_unlock(&mdev->lock);
+}
+EXPORT_SYMBOL_GPL(media_device_unregister_entity_notify);
+
+/**
  * media_device_register_entity - Register an entity with a media device
  * @mdev:	The media device
  * @entity:	The entity
@@ -428,6 +465,8 @@ EXPORT_SYMBOL_GPL(media_device_unregister);
 int __must_check media_device_register_entity(struct media_device *mdev,
 					      struct media_entity *entity)
 {
+	struct media_entity_notify *notify, *next;
+
 	/* Warn if we apparently re-register an entity */
 	WARN_ON(entity->parent != NULL);
 	entity->parent = mdev;
@@ -440,6 +479,11 @@ int __must_check media_device_register_entity(struct media_device *mdev,
 	list_add_tail(&entity->list, &mdev->entities);
 	spin_unlock(&mdev->lock);
 
+	/* invoke entity_notify callbacks */
+	list_for_each_entry_safe(notify, next, &mdev->entity_notify, list) {
+		(notify)->notify(entity, notify->notify_data);
+	}
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(media_device_register_entity);
@@ -462,6 +506,7 @@ void media_device_unregister_entity(struct media_entity *entity)
 	list_del(&entity->list);
 	spin_unlock(&mdev->lock);
 	entity->parent = NULL;
+	/* invoke entity_notify callbacks to handle entity removal?? */
 }
 EXPORT_SYMBOL_GPL(media_device_unregister_entity);
 
diff --git a/include/media/media-device.h b/include/media/media-device.h
index a44f18f..a3854f6 100644
--- a/include/media/media-device.h
+++ b/include/media/media-device.h
@@ -32,6 +32,12 @@
 
 struct device;
 
+struct media_entity_notify {
+	struct list_head list;
+	void *notify_data;
+	void (*notify)(struct media_entity *entity, void *notify_data);
+};
+
 /**
  * struct media_device - Media device
  * @dev:	Parent device
@@ -70,6 +76,8 @@ struct media_device {
 
 	u32 entity_id;
 	struct list_head entities;
+	/* notify callback list invoked when a new entity is registered */
+	struct list_head entity_notify;
 
 	/* Protects the entities list */
 	spinlock_t lock;
@@ -94,6 +102,10 @@ int __must_check __media_device_register(struct media_device *mdev,
 #define media_device_register(mdev) __media_device_register(mdev, THIS_MODULE)
 void media_device_unregister(struct media_device *mdev);
 
+int __must_check media_device_register_entity_notify(struct media_device *mdev,
+					struct media_entity_notify *nptr);
+void media_device_unregister_entity_notify(struct media_device *mdev,
+					struct media_entity_notify *nptr);
 int __must_check media_device_register_entity(struct media_device *mdev,
 					      struct media_entity *entity);
 void media_device_unregister_entity(struct media_entity *entity);
@@ -112,6 +124,17 @@ static inline int media_device_register(struct media_device *mdev)
 static inline void media_device_unregister(struct media_device *mdev)
 {
 }
+static inline int media_device_register_entity_notify(
+					struct media_device *mdev,
+					struct media_entity_notify *nptr)
+{
+	return 0;
+}
+static inline void media_device_unregister_entity_notify(
+					struct media_device *mdev,
+					struct media_entity_notify *nptr)
+{
+}
 static inline int media_device_register_entity(struct media_device *mdev,
 						struct media_entity *entity)
 {
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v3 03/21] media: Add ALSA Media Controller devnodes
  2015-09-22 17:19 [PATCH v3 00/21] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
  2015-09-22 17:19 ` [PATCH v3 01/21] Revert "[media] media: media controller entity framework enhancements for ALSA" Shuah Khan
  2015-09-22 17:19 ` [PATCH v3 02/21] media: Media Controller register/unregister entity_notify API Shuah Khan
@ 2015-09-22 17:19 ` Shuah Khan
  2015-09-22 17:19 ` [PATCH v3 04/21] media: Media Controller enable/disable source handler API Shuah Khan
                   ` (17 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Shuah Khan @ 2015-09-22 17:19 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, sakari.ailus, tiwai,
	pawel, m.szyprowski, kyungmin.park, perex, stefanr, crope,
	dan.carpenter, tskd08, ruchandani.tina, arnd, chehabrafael,
	prabhakar.csengg, Julia.Lawall, elfring, ricardo.ribalda,
	chris.j.arges, pierre-louis.bossart, gtmkramer, clemens,
	misterpib, takamichiho, pmatilai, damien, daniel, vladcatoi,
	normalperson, joe, bugzilla.frnkcg, jussi
  Cc: Shuah Khan, linux-media, alsa-devel

Add ALSA Media Controller capture, playback, and mixer
devnode defines.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 include/uapi/linux/media.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h
index 4e816be..4a30ea3 100644
--- a/include/uapi/linux/media.h
+++ b/include/uapi/linux/media.h
@@ -49,12 +49,17 @@ struct media_device_info {
 #define MEDIA_ENT_T_DEVNODE		(1 << MEDIA_ENT_TYPE_SHIFT)
 #define MEDIA_ENT_T_DEVNODE_V4L		(MEDIA_ENT_T_DEVNODE + 1)
 #define MEDIA_ENT_T_DEVNODE_FB		(MEDIA_ENT_T_DEVNODE + 2)
+/* Legacy ALSA symbol. Keep it to avoid userspace compilation breakages */
 #define MEDIA_ENT_T_DEVNODE_ALSA	(MEDIA_ENT_T_DEVNODE + 3)
 #define MEDIA_ENT_T_DEVNODE_DVB_FE	(MEDIA_ENT_T_DEVNODE + 4)
 #define MEDIA_ENT_T_DEVNODE_DVB_DEMUX	(MEDIA_ENT_T_DEVNODE + 5)
 #define MEDIA_ENT_T_DEVNODE_DVB_DVR	(MEDIA_ENT_T_DEVNODE + 6)
 #define MEDIA_ENT_T_DEVNODE_DVB_CA	(MEDIA_ENT_T_DEVNODE + 7)
 #define MEDIA_ENT_T_DEVNODE_DVB_NET	(MEDIA_ENT_T_DEVNODE + 8)
+/* ALSA devnodes */
+#define MEDIA_ENT_T_DEVNODE_ALSA_CAPTURE	(MEDIA_ENT_T_DEVNODE + 9)
+#define MEDIA_ENT_T_DEVNODE_ALSA_PLAYBACK	(MEDIA_ENT_T_DEVNODE + 10)
+#define MEDIA_ENT_T_DEVNODE_ALSA_MIXER		(MEDIA_ENT_T_DEVNODE + 11)
 
 /* Legacy symbol. Use it to avoid userspace compilation breakages */
 #define MEDIA_ENT_T_DEVNODE_DVB		MEDIA_ENT_T_DEVNODE_DVB_FE
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v3 04/21] media: Media Controller enable/disable source handler API
  2015-09-22 17:19 [PATCH v3 00/21] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (2 preceding siblings ...)
  2015-09-22 17:19 ` [PATCH v3 03/21] media: Add ALSA Media Controller devnodes Shuah Khan
@ 2015-09-22 17:19 ` Shuah Khan
  2015-09-22 17:19 ` [PATCH v3 05/21] media: Media Controller fix to not let stream_count go negative Shuah Khan
                   ` (16 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Shuah Khan @ 2015-09-22 17:19 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, sakari.ailus, tiwai,
	pawel, m.szyprowski, kyungmin.park, perex, stefanr, crope,
	dan.carpenter, tskd08, ruchandani.tina, arnd, chehabrafael,
	prabhakar.csengg, Julia.Lawall, elfring, ricardo.ribalda,
	chris.j.arges, pierre-louis.bossart, gtmkramer, clemens,
	misterpib, takamichiho, pmatilai, damien, daniel, vladcatoi,
	normalperson, joe, bugzilla.frnkcg, jussi
  Cc: Shuah Khan, linux-media, alsa-devel

Add new fields to struct media_device to add enable_source, and
disable_source handlers, and source_priv to stash driver private
data that is need to run these handlers. The enable_source handler
finds source entity for the passed in entity and check if it is
available, and activate the link using __media_entity_setup_link()
interface. Bridge driver is expected to implement and set these
handlers and private data when media_device is registered or when
bridge driver finds the media_device during probe. This is to enable
the use-case to find tuner entity connected to the decoder entity and
check if it is available, and activate it and start pipeline between
the source and the entity. The disable_source handler deactivates the
link and stops the pipeline. This handler can be invoked from the
media core (v4l-core, dvb-core) as well as other drivers such as ALSA
that control the media device.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 include/media/media-device.h | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/include/media/media-device.h b/include/media/media-device.h
index a3854f6..117c169 100644
--- a/include/media/media-device.h
+++ b/include/media/media-device.h
@@ -84,6 +84,24 @@ struct media_device {
 	/* Serializes graph operations. */
 	struct mutex graph_mutex;
 
+	/* Handlers to find source entity for the sink entity and
+	 * check if it is available, and activate the link using
+	 * media_entity_setup_link() interface and start pipeline
+	 * from the source to the entity.
+	 * Bridge driver is expected to implement and set the
+	 * handler when media_device is registered or when
+	 * bridge driver finds the media_device during probe.
+	 * Bridge driver sets source_priv with information
+	 * necessary to run enable/disable source handlers.
+	 *
+	 * Use-case: find tuner entity connected to the decoder
+	 * entity and check if it is available, and activate the
+	 * using media_entity_setup_link() if it is available.
+	*/
+	void *source_priv;
+	int (*enable_source)(struct media_entity *entity,
+			     struct media_pipeline *pipe);
+	void (*disable_source)(struct media_entity *entity);
 	int (*link_notify)(struct media_link *link, u32 flags,
 			   unsigned int notification);
 };
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v3 05/21] media: Media Controller fix to not let stream_count go negative
  2015-09-22 17:19 [PATCH v3 00/21] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (3 preceding siblings ...)
  2015-09-22 17:19 ` [PATCH v3 04/21] media: Media Controller enable/disable source handler API Shuah Khan
@ 2015-09-22 17:19 ` Shuah Khan
  2015-09-22 17:19 ` [PATCH v3 06/21] media: Media Controller export non locking __media_entity_setup_link() Shuah Khan
                   ` (15 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Shuah Khan @ 2015-09-22 17:19 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, sakari.ailus, tiwai,
	pawel, m.szyprowski, kyungmin.park, perex, stefanr, crope,
	dan.carpenter, tskd08, ruchandani.tina, arnd, chehabrafael,
	prabhakar.csengg, Julia.Lawall, elfring, ricardo.ribalda,
	chris.j.arges, pierre-louis.bossart, gtmkramer, clemens,
	misterpib, takamichiho, pmatilai, damien, daniel, vladcatoi,
	normalperson, joe, bugzilla.frnkcg, jussi
  Cc: Shuah Khan, linux-media, alsa-devel

Add a range check to not let the stream_count become negative.
Wthout this check, calls to stop pipeline when there is no active
pipeline will result in stream_count < 0 condition and lock and
preventing link state (activate/deactivate) changes. This will
happen from error leg in start pipeline interface.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/media-entity.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index 4d8e01c..68d5ec2 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -315,9 +315,12 @@ error:
 	media_entity_graph_walk_start(&graph, entity_err);
 
 	while ((entity_err = media_entity_graph_walk_next(&graph))) {
-		entity_err->stream_count--;
-		if (entity_err->stream_count == 0)
-			entity_err->pipe = NULL;
+		/* don't let the stream_count go negative */
+		if (entity->stream_count > 0) {
+			entity_err->stream_count--;
+			if (entity_err->stream_count == 0)
+				entity_err->pipe = NULL;
+		}
 
 		/*
 		 * We haven't increased stream_count further than this
@@ -355,9 +358,12 @@ void media_entity_pipeline_stop(struct media_entity *entity)
 	media_entity_graph_walk_start(&graph, entity);
 
 	while ((entity = media_entity_graph_walk_next(&graph))) {
-		entity->stream_count--;
-		if (entity->stream_count == 0)
-			entity->pipe = NULL;
+		/* don't let the stream_count go negative */
+		if (entity->stream_count > 0) {
+			entity->stream_count--;
+			if (entity->stream_count == 0)
+				entity->pipe = NULL;
+		}
 	}
 
 	mutex_unlock(&mdev->graph_mutex);
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v3 06/21] media: Media Controller export non locking __media_entity_setup_link()
  2015-09-22 17:19 [PATCH v3 00/21] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (4 preceding siblings ...)
  2015-09-22 17:19 ` [PATCH v3 05/21] media: Media Controller fix to not let stream_count go negative Shuah Khan
@ 2015-09-22 17:19 ` Shuah Khan
  2015-09-22 17:19 ` [PATCH v3 07/21] media: Media Controller non-locking __media_entity_pipeline_start/stop() Shuah Khan
                   ` (14 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Shuah Khan @ 2015-09-22 17:19 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, sakari.ailus, tiwai,
	pawel, m.szyprowski, kyungmin.park, perex, stefanr, crope,
	dan.carpenter, tskd08, ruchandani.tina, arnd, chehabrafael,
	prabhakar.csengg, Julia.Lawall, elfring, ricardo.ribalda,
	chris.j.arges, pierre-louis.bossart, gtmkramer, clemens,
	misterpib, takamichiho, pmatilai, damien, daniel, vladcatoi,
	normalperson, joe, bugzilla.frnkcg, jussi
  Cc: Shuah Khan, linux-media, alsa-devel

Export __media_entity_setup_link() to be used from code paths that hold
the graph_mutex.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/media-entity.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index 68d5ec2..03b3836 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -612,6 +612,7 @@ int __media_entity_setup_link(struct media_link *link, u32 flags)
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(__media_entity_setup_link);
 
 int media_entity_setup_link(struct media_link *link, u32 flags)
 {
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v3 07/21] media: Media Controller non-locking __media_entity_pipeline_start/stop()
  2015-09-22 17:19 [PATCH v3 00/21] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (5 preceding siblings ...)
  2015-09-22 17:19 ` [PATCH v3 06/21] media: Media Controller export non locking __media_entity_setup_link() Shuah Khan
@ 2015-09-22 17:19 ` Shuah Khan
  2015-09-22 17:19 ` [PATCH v3 08/21] media: v4l-core add v4l_enable/disable_media_tuner() helper functions Shuah Khan
                   ` (13 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Shuah Khan @ 2015-09-22 17:19 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, sakari.ailus, tiwai,
	pawel, m.szyprowski, kyungmin.park, perex, stefanr, crope,
	dan.carpenter, tskd08, ruchandani.tina, arnd, chehabrafael,
	prabhakar.csengg, Julia.Lawall, elfring, ricardo.ribalda,
	chris.j.arges, pierre-louis.bossart, gtmkramer, clemens,
	misterpib, takamichiho, pmatilai, damien, daniel, vladcatoi,
	normalperson, joe, bugzilla.frnkcg, jussi
  Cc: Shuah Khan, linux-media, alsa-devel

Add non-locking __media_entity_pipeline_start/stop() interfaces
to be called from code paths that hold the graph_mutex. For this
change, the media_entity_pipeline_start() routine is renamed to
__media_entity_pipeline_start() minus the graph_mutex lock and
unlock. media_entity_pipeline_start() now calls the non-locking
__media_entity_pipeline_start() holding the graph_lock. The stop
interface, media_entity_pipeline_stop() routine is renamed to
__media_entity_pipeline_stop() minus the graph_mutex lock and
unlock. media_entity_pipeline_stop() now calls the non-locking
__media_entity_pipeline_stop() holding the graph_lock.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/media-entity.c | 45 ++++++++++++++++++++++++++++++--------------
 include/media/media-entity.h |  3 +++
 2 files changed, 34 insertions(+), 14 deletions(-)

diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index 03b3836..b87e773 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -210,6 +210,7 @@ EXPORT_SYMBOL_GPL(media_entity_graph_walk_next);
 
 /**
  * media_entity_pipeline_start - Mark a pipeline as streaming
+ * __media_entity_pipeline_start - Mark a pipeline as streaming
  * @entity: Starting entity
  * @pipe: Media pipeline to be assigned to all entities in the pipeline.
  *
@@ -220,18 +221,17 @@ EXPORT_SYMBOL_GPL(media_entity_graph_walk_next);
  * Calls to this function can be nested, in which case the same number of
  * media_entity_pipeline_stop() calls will be required to stop streaming. The
  * pipeline pointer must be identical for all nested calls to
- * media_entity_pipeline_start().
+ * __media_entity_pipeline_start().
+ * User is expected to hold the graph_mutex. If not user can call
+ * media_entity_pipeline_start()
  */
-__must_check int media_entity_pipeline_start(struct media_entity *entity,
-					     struct media_pipeline *pipe)
+__must_check int __media_entity_pipeline_start(struct media_entity *entity,
+					       struct media_pipeline *pipe)
 {
-	struct media_device *mdev = entity->parent;
 	struct media_entity_graph graph;
 	struct media_entity *entity_err = entity;
 	int ret;
 
-	mutex_lock(&mdev->graph_mutex);
-
 	media_entity_graph_walk_start(&graph, entity);
 
 	while ((entity = media_entity_graph_walk_next(&graph))) {
@@ -303,8 +303,6 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity,
 		}
 	}
 
-	mutex_unlock(&mdev->graph_mutex);
-
 	return 0;
 
 error:
@@ -330,14 +328,25 @@ error:
 			break;
 	}
 
-	mutex_unlock(&mdev->graph_mutex);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(__media_entity_pipeline_start);
 
+__must_check int media_entity_pipeline_start(struct media_entity *entity,
+					     struct media_pipeline *pipe)
+{
+	struct media_device *mdev = entity->parent;
+	int ret;
+
+	mutex_lock(&mdev->graph_mutex);
+	ret = __media_entity_pipeline_start(entity, pipe);
+	mutex_unlock(&mdev->graph_mutex);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(media_entity_pipeline_start);
 
 /**
- * media_entity_pipeline_stop - Mark a pipeline as not streaming
+ * __media_entity_pipeline_stop - Mark a pipeline as not streaming
  * @entity: Starting entity
  *
  * Mark all entities connected to a given entity through enabled links, either
@@ -347,14 +356,13 @@ EXPORT_SYMBOL_GPL(media_entity_pipeline_start);
  * If multiple calls to media_entity_pipeline_start() have been made, the same
  * number of calls to this function are required to mark the pipeline as not
  * streaming.
+ * User is expected to hold the graph_mutex. If not user can call
+ * media_entity_pipeline_stop()
  */
-void media_entity_pipeline_stop(struct media_entity *entity)
+void __media_entity_pipeline_stop(struct media_entity *entity)
 {
-	struct media_device *mdev = entity->parent;
 	struct media_entity_graph graph;
 
-	mutex_lock(&mdev->graph_mutex);
-
 	media_entity_graph_walk_start(&graph, entity);
 
 	while ((entity = media_entity_graph_walk_next(&graph))) {
@@ -366,6 +374,15 @@ void media_entity_pipeline_stop(struct media_entity *entity)
 		}
 	}
 
+}
+EXPORT_SYMBOL_GPL(__media_entity_pipeline_stop);
+
+void media_entity_pipeline_stop(struct media_entity *entity)
+{
+	struct media_device *mdev = entity->parent;
+
+	mutex_lock(&mdev->graph_mutex);
+	__media_entity_pipeline_stop(entity);
 	mutex_unlock(&mdev->graph_mutex);
 }
 EXPORT_SYMBOL_GPL(media_entity_pipeline_stop);
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index 0c003d8..cc0bbd0 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -148,8 +148,11 @@ void media_entity_graph_walk_start(struct media_entity_graph *graph,
 		struct media_entity *entity);
 struct media_entity *
 media_entity_graph_walk_next(struct media_entity_graph *graph);
+__must_check int __media_entity_pipeline_start(struct media_entity *entity,
+					       struct media_pipeline *pipe);
 __must_check int media_entity_pipeline_start(struct media_entity *entity,
 					     struct media_pipeline *pipe);
+void __media_entity_pipeline_stop(struct media_entity *entity);
 void media_entity_pipeline_stop(struct media_entity *entity);
 
 #define media_entity_call(entity, operation, args...)			\
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v3 08/21] media: v4l-core add v4l_enable/disable_media_tuner() helper functions
  2015-09-22 17:19 [PATCH v3 00/21] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (6 preceding siblings ...)
  2015-09-22 17:19 ` [PATCH v3 07/21] media: Media Controller non-locking __media_entity_pipeline_start/stop() Shuah Khan
@ 2015-09-22 17:19 ` Shuah Khan
  2015-09-22 17:19 ` [PATCH v3 09/21] media: Move au8522_media_pads enum to au8522.h from au8522_priv.h Shuah Khan
                   ` (12 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Shuah Khan @ 2015-09-22 17:19 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, sakari.ailus, tiwai,
	pawel, m.szyprowski, kyungmin.park, perex, stefanr, crope,
	dan.carpenter, tskd08, ruchandani.tina, arnd, chehabrafael,
	prabhakar.csengg, Julia.Lawall, elfring, ricardo.ribalda,
	chris.j.arges, pierre-louis.bossart, gtmkramer, clemens,
	misterpib, takamichiho, pmatilai, damien, daniel, vladcatoi,
	normalperson, joe, bugzilla.frnkcg, jussi
  Cc: Shuah Khan, linux-media, alsa-devel

Add a new interfaces to be used by v4l-core to invoke enable
source and disable_source handlers in the media_device. The
enable_source helper function invokes the enable_source handler
to find tuner entity connected to the decoder and check is it
is available or busy. If tuner is available, link is activated
and pipeline is started. The disable_source helper function
invokes the disable_source handler to deactivate and stop the
pipeline.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/v4l2-core/v4l2-dev.c | 27 +++++++++++++++++++++++++++
 include/media/v4l2-dev.h           |  4 ++++
 2 files changed, 31 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index 71a1b93..8e93c99 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -230,6 +230,33 @@ struct video_device *video_devdata(struct file *file)
 }
 EXPORT_SYMBOL(video_devdata);
 
+int v4l_enable_media_tuner(struct video_device *vdev)
+{
+#ifdef CONFIG_MEDIA_CONTROLLER
+	struct media_device *mdev = vdev->entity.parent;
+	int ret;
+
+	if (!mdev || !mdev->enable_source)
+			return 0;
+	ret = mdev->enable_source(&vdev->entity, &vdev->pipe);
+	if (ret)
+		return -EBUSY;
+	return 0;
+#endif /* CONFIG_MEDIA_CONTROLLER */
+	return 0;
+}
+EXPORT_SYMBOL_GPL(v4l_enable_media_tuner);
+
+void v4l_disable_media_tuner(struct video_device *vdev)
+{
+#ifdef CONFIG_MEDIA_CONTROLLER
+	struct media_device *mdev = vdev->entity.parent;
+
+	if (mdev && mdev->disable_source)
+		mdev->disable_source(&vdev->entity);
+#endif /* CONFIG_MEDIA_CONTROLLER */
+}
+EXPORT_SYMBOL_GPL(v4l_disable_media_tuner);
 
 /* Priority handling */
 
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index acbcd2f..8f1884f 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -86,6 +86,7 @@ struct video_device
 {
 #if defined(CONFIG_MEDIA_CONTROLLER)
 	struct media_entity entity;
+	struct media_pipeline pipe;
 #endif
 	/* device ops */
 	const struct v4l2_file_operations *fops;
@@ -178,6 +179,9 @@ struct video_device * __must_check video_device_alloc(void);
 /* this release function frees the vdev pointer */
 void video_device_release(struct video_device *vdev);
 
+int v4l_enable_media_tuner(struct video_device *vdev);
+void v4l_disable_media_tuner(struct video_device *vdev);
+
 /* this release function does nothing, use when the video_device is a
    static global struct. Note that having a static video_device is
    a dubious construction at best. */
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v3 09/21] media: Move au8522_media_pads enum to au8522.h from au8522_priv.h
  2015-09-22 17:19 [PATCH v3 00/21] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (7 preceding siblings ...)
  2015-09-22 17:19 ` [PATCH v3 08/21] media: v4l-core add v4l_enable/disable_media_tuner() helper functions Shuah Khan
@ 2015-09-22 17:19 ` Shuah Khan
  2015-09-22 17:19 ` [PATCH v3 10/21] media: au8522 change to create MC pad for ALSA Audio Out Shuah Khan
                   ` (11 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Shuah Khan @ 2015-09-22 17:19 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, sakari.ailus, tiwai,
	pawel, m.szyprowski, kyungmin.park, perex, stefanr, crope,
	dan.carpenter, tskd08, ruchandani.tina, arnd, chehabrafael,
	prabhakar.csengg, Julia.Lawall, elfring, ricardo.ribalda,
	chris.j.arges, pierre-louis.bossart, gtmkramer, clemens,
	misterpib, takamichiho, pmatilai, damien, daniel, vladcatoi,
	normalperson, joe, bugzilla.frnkcg, jussi
  Cc: Shuah Khan, linux-media, alsa-devel

Move the au8522_media_pads enum to au8522.h from au8522_priv.h.
This will allow au0828-core to use these defines instead of
hard-coding the pad values when it creates media graph linking
decode pads to other entities.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/dvb-frontends/au8522.h      | 7 +++++++
 drivers/media/dvb-frontends/au8522_priv.h | 8 --------
 2 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/media/dvb-frontends/au8522.h b/drivers/media/dvb-frontends/au8522.h
index dde6158..3c72f40 100644
--- a/drivers/media/dvb-frontends/au8522.h
+++ b/drivers/media/dvb-frontends/au8522.h
@@ -90,4 +90,11 @@ enum au8522_audio_input {
 	AU8522_AUDIO_SIF,
 };
 
+enum au8522_media_pads {
+	AU8522_PAD_INPUT,
+	AU8522_PAD_VID_OUT,
+	AU8522_PAD_VBI_OUT,
+
+	AU8522_NUM_PADS
+};
 #endif /* __AU8522_H__ */
diff --git a/drivers/media/dvb-frontends/au8522_priv.h b/drivers/media/dvb-frontends/au8522_priv.h
index d6209d9..4c2a6ed 100644
--- a/drivers/media/dvb-frontends/au8522_priv.h
+++ b/drivers/media/dvb-frontends/au8522_priv.h
@@ -39,14 +39,6 @@
 #define AU8522_DIGITAL_MODE 1
 #define AU8522_SUSPEND_MODE 2
 
-enum au8522_media_pads {
-	AU8522_PAD_INPUT,
-	AU8522_PAD_VID_OUT,
-	AU8522_PAD_VBI_OUT,
-
-	AU8522_NUM_PADS
-};
-
 struct au8522_state {
 	struct i2c_client *c;
 	struct i2c_adapter *i2c;
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v3 10/21] media: au8522 change to create MC pad for ALSA Audio Out
  2015-09-22 17:19 [PATCH v3 00/21] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (8 preceding siblings ...)
  2015-09-22 17:19 ` [PATCH v3 09/21] media: Move au8522_media_pads enum to au8522.h from au8522_priv.h Shuah Khan
@ 2015-09-22 17:19 ` Shuah Khan
  2015-09-22 17:19 ` [PATCH v3 11/21] media: au0828 Use au8522_media_pads enum for pad defines Shuah Khan
                   ` (10 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Shuah Khan @ 2015-09-22 17:19 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, sakari.ailus, tiwai,
	pawel, m.szyprowski, kyungmin.park, perex, stefanr, crope,
	dan.carpenter, tskd08, ruchandani.tina, arnd, chehabrafael,
	prabhakar.csengg, Julia.Lawall, elfring, ricardo.ribalda,
	chris.j.arges, pierre-louis.bossart, gtmkramer, clemens,
	misterpib, takamichiho, pmatilai, damien, daniel, vladcatoi,
	normalperson, joe, bugzilla.frnkcg, jussi
  Cc: Shuah Khan, linux-media, alsa-devel

Add new pad for ALSA Audio Out to au8522_media_pads.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/dvb-frontends/au8522.h         | 1 +
 drivers/media/dvb-frontends/au8522_decoder.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/media/dvb-frontends/au8522.h b/drivers/media/dvb-frontends/au8522.h
index 3c72f40..d7a997f 100644
--- a/drivers/media/dvb-frontends/au8522.h
+++ b/drivers/media/dvb-frontends/au8522.h
@@ -94,6 +94,7 @@ enum au8522_media_pads {
 	AU8522_PAD_INPUT,
 	AU8522_PAD_VID_OUT,
 	AU8522_PAD_VBI_OUT,
+	AU8522_PAD_AUDIO_OUT,
 
 	AU8522_NUM_PADS
 };
diff --git a/drivers/media/dvb-frontends/au8522_decoder.c b/drivers/media/dvb-frontends/au8522_decoder.c
index 24990db..5fc9a39 100644
--- a/drivers/media/dvb-frontends/au8522_decoder.c
+++ b/drivers/media/dvb-frontends/au8522_decoder.c
@@ -775,6 +775,7 @@ static int au8522_probe(struct i2c_client *client,
 	state->pads[AU8522_PAD_INPUT].flags = MEDIA_PAD_FL_SINK;
 	state->pads[AU8522_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE;
 	state->pads[AU8522_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE;
+	state->pads[AU8522_PAD_AUDIO_OUT].flags = MEDIA_PAD_FL_SOURCE;
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
 
 	ret = media_entity_init(&sd->entity, ARRAY_SIZE(state->pads),
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v3 11/21] media: au0828 Use au8522_media_pads enum for pad defines
  2015-09-22 17:19 [PATCH v3 00/21] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (9 preceding siblings ...)
  2015-09-22 17:19 ` [PATCH v3 10/21] media: au8522 change to create MC pad for ALSA Audio Out Shuah Khan
@ 2015-09-22 17:19 ` Shuah Khan
  2015-09-22 17:19 ` [PATCH v3 12/21] media: au0828 fix au0828_create_media_graph() entity checks Shuah Khan
                   ` (9 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Shuah Khan @ 2015-09-22 17:19 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, sakari.ailus, tiwai,
	pawel, m.szyprowski, kyungmin.park, perex, stefanr, crope,
	dan.carpenter, tskd08, ruchandani.tina, arnd, chehabrafael,
	prabhakar.csengg, Julia.Lawall, elfring, ricardo.ribalda,
	chris.j.arges, pierre-louis.bossart, gtmkramer, clemens,
	misterpib, takamichiho, pmatilai, damien, daniel, vladcatoi,
	normalperson, joe, bugzilla.frnkcg, jussi
  Cc: Shuah Khan, linux-media, alsa-devel

Change au0828-core to use au8522_media_pads enum defines
instead of hard-coding the pad values when it creates
media graph linking decode pads to other entities.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/usb/au0828/au0828-core.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index 0378a2c..276598b 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -20,6 +20,7 @@
  */
 
 #include "au0828.h"
+#include "au8522.h"
 
 #include <linux/module.h>
 #include <linux/slab.h>
@@ -263,11 +264,13 @@ static void au0828_create_media_graph(struct au0828_dev *dev)
 		media_entity_create_link(tuner, 0, decoder, 0,
 					 MEDIA_LNK_FL_ENABLED);
 	if (dev->vdev.entity.links)
-		media_entity_create_link(decoder, 1, &dev->vdev.entity, 0,
-				 MEDIA_LNK_FL_ENABLED);
+		media_entity_create_link(decoder, AU8522_PAD_VID_OUT,
+					 &dev->vdev.entity, 0,
+					 MEDIA_LNK_FL_ENABLED);
 	if (dev->vbi_dev.entity.links)
-		media_entity_create_link(decoder, 2, &dev->vbi_dev.entity, 0,
-				 MEDIA_LNK_FL_ENABLED);
+		media_entity_create_link(decoder, AU8522_PAD_VBI_OUT,
+					 &dev->vbi_dev.entity, 0,
+					 MEDIA_LNK_FL_ENABLED);
 #endif
 }
 
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v3 12/21] media: au0828 fix au0828_create_media_graph() entity checks
  2015-09-22 17:19 [PATCH v3 00/21] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (10 preceding siblings ...)
  2015-09-22 17:19 ` [PATCH v3 11/21] media: au0828 Use au8522_media_pads enum for pad defines Shuah Khan
@ 2015-09-22 17:19 ` Shuah Khan
  2015-09-22 17:19 ` [PATCH v3 13/21] media: Change v4l-core to check for tuner availability Shuah Khan
                   ` (8 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Shuah Khan @ 2015-09-22 17:19 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, sakari.ailus, tiwai,
	pawel, m.szyprowski, kyungmin.park, perex, stefanr, crope,
	dan.carpenter, tskd08, ruchandani.tina, arnd, chehabrafael,
	prabhakar.csengg, Julia.Lawall, elfring, ricardo.ribalda,
	chris.j.arges, pierre-louis.bossart, gtmkramer, clemens,
	misterpib, takamichiho, pmatilai, damien, daniel, vladcatoi,
	normalperson, joe, bugzilla.frnkcg, jussi
  Cc: Shuah Khan, linux-media, alsa-devel

au0828_create_media_graph() checks if entity.links is null
or not to determine, if vbi_dev and vdev entities have been
registered. Checking entity.parent field is right way, as
parent field gets initialized when entity is registered. Fix
it to check entity.parent field.

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

diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index 276598b..0b8dc49 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -263,11 +263,11 @@ static void au0828_create_media_graph(struct au0828_dev *dev)
 	if (tuner)
 		media_entity_create_link(tuner, 0, decoder, 0,
 					 MEDIA_LNK_FL_ENABLED);
-	if (dev->vdev.entity.links)
+	if (dev->vdev.entity.parent)
 		media_entity_create_link(decoder, AU8522_PAD_VID_OUT,
 					 &dev->vdev.entity, 0,
 					 MEDIA_LNK_FL_ENABLED);
-	if (dev->vbi_dev.entity.links)
+	if (dev->vbi_dev.entity.parent)
 		media_entity_create_link(decoder, AU8522_PAD_VBI_OUT,
 					 &dev->vbi_dev.entity, 0,
 					 MEDIA_LNK_FL_ENABLED);
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v3 13/21] media: Change v4l-core to check for tuner availability
  2015-09-22 17:19 [PATCH v3 00/21] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (11 preceding siblings ...)
  2015-09-22 17:19 ` [PATCH v3 12/21] media: au0828 fix au0828_create_media_graph() entity checks Shuah Khan
@ 2015-09-22 17:19 ` Shuah Khan
  2015-09-22 17:19 ` [PATCH v3 14/21] media: dvb-frontend invoke enable/disable_source handlers Shuah Khan
                   ` (7 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Shuah Khan @ 2015-09-22 17:19 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, sakari.ailus, tiwai,
	pawel, m.szyprowski, kyungmin.park, perex, stefanr, crope,
	dan.carpenter, tskd08, ruchandani.tina, arnd, chehabrafael,
	prabhakar.csengg, Julia.Lawall, elfring, ricardo.ribalda,
	chris.j.arges, pierre-louis.bossart, gtmkramer, clemens,
	misterpib, takamichiho, pmatilai, damien, daniel, vladcatoi,
	normalperson, joe, bugzilla.frnkcg, jussi
  Cc: Shuah Khan, linux-media, alsa-devel

Change s_input, s_fmt, s_tuner, s_frequency, querystd,
s_hw_freq_seek, and vb2_internal_streamon interfaces that
alter the tuner configuration to check for tuner availability
by calling v4l_enable_media_tuner(). If tuner isn't free,
return -EBUSY. v4l_disable_media_tuner() is called from
v4l2_fh_exit() to release the tuner.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/v4l2-core/v4l2-fh.c        |  1 +
 drivers/media/v4l2-core/v4l2-ioctl.c     | 29 +++++++++++++++++++++++++++++
 drivers/media/v4l2-core/videobuf2-core.c |  3 +++
 3 files changed, 33 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-fh.c b/drivers/media/v4l2-core/v4l2-fh.c
index c97067a..538db62 100644
--- a/drivers/media/v4l2-core/v4l2-fh.c
+++ b/drivers/media/v4l2-core/v4l2-fh.c
@@ -92,6 +92,7 @@ void v4l2_fh_exit(struct v4l2_fh *fh)
 {
 	if (fh->vdev == NULL)
 		return;
+	v4l_disable_media_tuner(fh->vdev);
 	v4l2_event_unsubscribe_all(fh);
 	fh->vdev = NULL;
 }
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index 85de455..deffc1b 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -1035,6 +1035,12 @@ static int v4l_querycap(const struct v4l2_ioctl_ops *ops,
 static int v4l_s_input(const struct v4l2_ioctl_ops *ops,
 				struct file *file, void *fh, void *arg)
 {
+	struct video_device *vfd = video_devdata(file);
+	int ret;
+
+	ret = v4l_enable_media_tuner(vfd);
+	if (ret)
+		return ret;
 	return ops->vidioc_s_input(file, fh, *(unsigned int *)arg);
 }
 
@@ -1433,6 +1439,9 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
 	bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
 	int ret;
 
+	ret = v4l_enable_media_tuner(vfd);
+	if (ret)
+		return ret;
 	v4l_sanitize_format(p);
 
 	switch (p->type) {
@@ -1612,7 +1621,11 @@ static int v4l_s_tuner(const struct v4l2_ioctl_ops *ops,
 {
 	struct video_device *vfd = video_devdata(file);
 	struct v4l2_tuner *p = arg;
+	int ret;
 
+	ret = v4l_enable_media_tuner(vfd);
+	if (ret)
+		return ret;
 	p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
 			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
 	return ops->vidioc_s_tuner(file, fh, p);
@@ -1650,7 +1663,11 @@ static int v4l_s_frequency(const struct v4l2_ioctl_ops *ops,
 	struct video_device *vfd = video_devdata(file);
 	const struct v4l2_frequency *p = arg;
 	enum v4l2_tuner_type type;
+	int ret;
 
+	ret = v4l_enable_media_tuner(vfd);
+	if (ret)
+		return ret;
 	if (vfd->vfl_type == VFL_TYPE_SDR) {
 		if (p->type != V4L2_TUNER_ADC && p->type != V4L2_TUNER_RF)
 			return -EINVAL;
@@ -1705,7 +1722,11 @@ static int v4l_s_std(const struct v4l2_ioctl_ops *ops,
 {
 	struct video_device *vfd = video_devdata(file);
 	v4l2_std_id id = *(v4l2_std_id *)arg, norm;
+	int ret;
 
+	ret = v4l_enable_media_tuner(vfd);
+	if (ret)
+		return ret;
 	norm = id & vfd->tvnorms;
 	if (vfd->tvnorms && !norm)	/* Check if std is supported */
 		return -EINVAL;
@@ -1719,7 +1740,11 @@ static int v4l_querystd(const struct v4l2_ioctl_ops *ops,
 {
 	struct video_device *vfd = video_devdata(file);
 	v4l2_std_id *p = arg;
+	int ret;
 
+	ret = v4l_enable_media_tuner(vfd);
+	if (ret)
+		return ret;
 	/*
 	 * If no signal is detected, then the driver should return
 	 * V4L2_STD_UNKNOWN. Otherwise it should return tvnorms with
@@ -1738,7 +1763,11 @@ static int v4l_s_hw_freq_seek(const struct v4l2_ioctl_ops *ops,
 	struct video_device *vfd = video_devdata(file);
 	struct v4l2_hw_freq_seek *p = arg;
 	enum v4l2_tuner_type type;
+	int ret;
 
+	ret = v4l_enable_media_tuner(vfd);
+	if (ret)
+		return ret;
 	/* s_hw_freq_seek is not supported for SDR for now */
 	if (vfd->vfl_type == VFL_TYPE_SDR)
 		return -EINVAL;
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
index d835814..f7304d8 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -2251,6 +2251,9 @@ static int vb2_internal_streamon(struct vb2_queue *q, enum v4l2_buf_type type)
 	 * are available.
 	 */
 	if (q->queued_count >= q->min_buffers_needed) {
+		ret = v4l_enable_media_tuner(q->owner->vdev);
+		if (ret)
+			return ret;
 		ret = vb2_start_streaming(q);
 		if (ret) {
 			__vb2_queue_cancel(q);
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v3 14/21] media: dvb-frontend invoke enable/disable_source handlers
  2015-09-22 17:19 [PATCH v3 00/21] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (12 preceding siblings ...)
  2015-09-22 17:19 ` [PATCH v3 13/21] media: Change v4l-core to check for tuner availability Shuah Khan
@ 2015-09-22 17:19 ` Shuah Khan
  2015-09-22 17:19 ` [PATCH v3 15/21] media: au0828 video remove au0828_enable_analog_tuner() Shuah Khan
                   ` (6 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Shuah Khan @ 2015-09-22 17:19 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, sakari.ailus, tiwai,
	pawel, m.szyprowski, kyungmin.park, perex, stefanr, crope,
	dan.carpenter, tskd08, ruchandani.tina, arnd, chehabrafael,
	prabhakar.csengg, Julia.Lawall, elfring, ricardo.ribalda,
	chris.j.arges, pierre-louis.bossart, gtmkramer, clemens,
	misterpib, takamichiho, pmatilai, damien, daniel, vladcatoi,
	normalperson, joe, bugzilla.frnkcg, jussi
  Cc: Shuah Khan, linux-media, alsa-devel

Checking for tuner availability from frontend thread start
disrupts video stream. Change to check for tuner and start
pipeline from frontend open instead and stop pipeline from
frontend release. In addition, make a change to invoke
enable_source and disable_source handlers to check for
tuner availability. The enable_source handler finds tuner
entity connected to the decoder and check is it is available
or busy. If tuner is available, link is activated and pipeline
is started. The disable_source handler to deactivate and stop
the pipeline. dvb_enable_media_tuner() is removed as it is no
longer necessary with dvb invoking enable_source and
disable_source handlers. pipe_start_entity field is removed
and pipe field is moved to dvb_frontend from dvb_frontend_private.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/dvb-core/dvb_frontend.c | 135 ++++------------------------------
 drivers/media/dvb-core/dvb_frontend.h |   3 +
 2 files changed, 18 insertions(+), 120 deletions(-)

diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index 842b9c8..c06dd61 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -132,11 +132,6 @@ struct dvb_frontend_private {
 	int quality;
 	unsigned int check_wrapped;
 	enum dvbfe_search algo_status;
-
-#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
-	struct media_pipeline pipe;
-	struct media_entity *pipe_start_entity;
-#endif
 };
 
 static void dvb_frontend_wakeup(struct dvb_frontend *fe);
@@ -597,107 +592,12 @@ static void dvb_frontend_wakeup(struct dvb_frontend *fe)
 	wake_up_interruptible(&fepriv->wait_queue);
 }
 
-/**
- * dvb_enable_media_tuner() - tries to enable the DVB tuner
- *
- * @fe:		struct dvb_frontend pointer
- *
- * This function ensures that just one media tuner is enabled for a given
- * frontend. It has two different behaviors:
- * - For trivial devices with just one tuner:
- *   it just enables the existing tuner->fe link
- * - For devices with more than one tuner:
- *   It is up to the driver to implement the logic that will enable one tuner
- *   and disable the other ones. However, if more than one tuner is enabled for
- *   the same frontend, it will print an error message and return -EINVAL.
- *
- * At return, it will return the error code returned by media_entity_setup_link,
- * or 0 if everything is OK, if no tuner is linked to the frontend or if the
- * mdev is NULL.
- */
-#ifdef CONFIG_MEDIA_CONTROLLER_DVB
-static int dvb_enable_media_tuner(struct dvb_frontend *fe)
-{
-	struct dvb_frontend_private *fepriv = fe->frontend_priv;
-	struct dvb_adapter *adapter = fe->dvb;
-	struct media_device *mdev = adapter->mdev;
-	struct media_entity  *entity, *source;
-	struct media_link *link, *found_link = NULL;
-	int i, ret, n_links = 0, active_links = 0;
-
-	fepriv->pipe_start_entity = NULL;
-
-	if (!mdev)
-		return 0;
-
-	entity = fepriv->dvbdev->entity;
-	fepriv->pipe_start_entity = entity;
-
-	for (i = 0; i < entity->num_links; i++) {
-		link = &entity->links[i];
-		if (link->sink->entity == entity) {
-			found_link = link;
-			n_links++;
-			if (link->flags & MEDIA_LNK_FL_ENABLED)
-				active_links++;
-		}
-	}
-
-	if (!n_links || active_links == 1 || !found_link)
-		return 0;
-
-	/*
-	 * If a frontend has more than one tuner linked, it is up to the driver
-	 * to select with one will be the active one, as the frontend core can't
-	 * guess. If the driver doesn't do that, it is a bug.
-	 */
-	if (n_links > 1 && active_links != 1) {
-		dev_err(fe->dvb->device,
-			"WARNING: there are %d active links among %d tuners. This is a driver's bug!\n",
-			active_links, n_links);
-		return -EINVAL;
-	}
-
-	source = found_link->source->entity;
-	fepriv->pipe_start_entity = source;
-	for (i = 0; i < source->num_links; i++) {
-		struct media_entity *sink;
-		int flags = 0;
-
-		link = &source->links[i];
-		sink = link->sink->entity;
-
-		if (sink == entity)
-			flags = MEDIA_LNK_FL_ENABLED;
-
-		ret = media_entity_setup_link(link, flags);
-		if (ret) {
-			dev_err(fe->dvb->device,
-				"Couldn't change link %s->%s to %s. Error %d\n",
-				source->name, sink->name,
-				flags ? "enabled" : "disabled",
-				ret);
-			return ret;
-		} else
-			dev_dbg(fe->dvb->device,
-				"link %s->%s was %s\n",
-				source->name, sink->name,
-				flags ? "ENABLED" : "disabled");
-	}
-	return 0;
-}
-#endif
-
 static int dvb_frontend_thread(void *data)
 {
 	struct dvb_frontend *fe = data;
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
 	enum fe_status s;
 	enum dvbfe_algo algo;
-#ifdef CONFIG_MEDIA_CONTROLLER_DVB
-	int ret;
-#endif
-
 	bool re_tune = false;
 	bool semheld = false;
 
@@ -710,20 +610,6 @@ static int dvb_frontend_thread(void *data)
 	fepriv->wakeup = 0;
 	fepriv->reinitialise = 0;
 
-#ifdef CONFIG_MEDIA_CONTROLLER_DVB
-	ret = dvb_enable_media_tuner(fe);
-	if (ret) {
-		/* FIXME: return an error if it fails */
-		dev_info(fe->dvb->device,
-			"proceeding with FE task\n");
-	} else if (fepriv->pipe_start_entity) {
-		ret = media_entity_pipeline_start(fepriv->pipe_start_entity,
-						  &fepriv->pipe);
-		if (ret)
-			return ret;
-	}
-#endif
-
 	dvb_frontend_init(fe);
 
 	set_freezable();
@@ -833,12 +719,6 @@ restart:
 		}
 	}
 
-#ifdef CONFIG_MEDIA_CONTROLLER_DVB
-	if (fepriv->pipe_start_entity)
-		media_entity_pipeline_stop(fepriv->pipe_start_entity);
-	fepriv->pipe_start_entity = NULL;
-#endif
-
 	if (dvb_powerdown_on_sleep) {
 		if (fe->ops.set_voltage)
 			fe->ops.set_voltage(fe, SEC_VOLTAGE_OFF);
@@ -2616,6 +2496,17 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
 		fepriv->tone = -1;
 		fepriv->voltage = -1;
 
+#ifdef CONFIG_MEDIA_CONTROLLER_DVB
+		if (fe->dvb->mdev && fe->dvb->mdev->enable_source) {
+			ret = fe->dvb->mdev->enable_source(dvbdev->entity,
+						  &fe->pipe);
+			if (ret) {
+				dev_err(fe->dvb->device,
+					"Tuner is busy. Error %d\n", ret);
+				goto err1;
+			}
+		}
+#endif
 		ret = dvb_frontend_start (fe);
 		if (ret)
 			goto err2;
@@ -2659,6 +2550,10 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
 		wake_up(&fepriv->wait_queue);
 		if (fe->exit != DVB_FE_NO_EXIT)
 			wake_up(&dvbdev->wait_queue);
+#ifdef CONFIG_MEDIA_CONTROLLER_DVB
+		if (fe->dvb->mdev && fe->dvb->mdev->disable_source)
+			fe->dvb->mdev->disable_source(dvbdev->entity);
+#endif
 		if (fe->ops.ts_bus_ctrl)
 			fe->ops.ts_bus_ctrl(fe, 0);
 	}
diff --git a/drivers/media/dvb-core/dvb_frontend.h b/drivers/media/dvb-core/dvb_frontend.h
index 4816947..03d328e 100644
--- a/drivers/media/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb-core/dvb_frontend.h
@@ -428,6 +428,9 @@ struct dvb_frontend {
 	int (*callback)(void *adapter_priv, int component, int cmd, int arg);
 	int id;
 	unsigned int exit;
+#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
+	struct media_pipeline pipe;
+#endif
 };
 
 extern int dvb_register_frontend(struct dvb_adapter *dvb,
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v3 15/21] media: au0828 video remove au0828_enable_analog_tuner()
  2015-09-22 17:19 [PATCH v3 00/21] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (13 preceding siblings ...)
  2015-09-22 17:19 ` [PATCH v3 14/21] media: dvb-frontend invoke enable/disable_source handlers Shuah Khan
@ 2015-09-22 17:19 ` Shuah Khan
  2015-09-22 17:19 ` [PATCH v3 16/21] media: au0828 video change to use v4l_enable_media_tuner() Shuah Khan
                   ` (5 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Shuah Khan @ 2015-09-22 17:19 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, sakari.ailus, tiwai,
	pawel, m.szyprowski, kyungmin.park, perex, stefanr, crope,
	dan.carpenter, tskd08, ruchandani.tina, arnd, chehabrafael,
	prabhakar.csengg, Julia.Lawall, elfring, ricardo.ribalda,
	chris.j.arges, pierre-louis.bossart, gtmkramer, clemens,
	misterpib, takamichiho, pmatilai, damien, daniel, vladcatoi,
	normalperson, joe, bugzilla.frnkcg, jussi
  Cc: Shuah Khan, linux-media, alsa-devel

au0828_enable_analog_tuner() is no longer needed with
v4l2-core and au0828-video invoking enable_source and
disable_source handlers. In addition, it is unnecessary
to check for tuner availability in queue_setup() as
v4l2-core handles the tuner availability checks.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/usb/au0828/au0828-video.c | 62 ---------------------------------
 1 file changed, 62 deletions(-)

diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c
index 939b2ad..b63ae78 100644
--- a/drivers/media/usb/au0828/au0828-video.c
+++ b/drivers/media/usb/au0828/au0828-video.c
@@ -637,66 +637,6 @@ static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb)
 	return rc;
 }
 
-static int au0828_enable_analog_tuner(struct au0828_dev *dev)
-{
-#ifdef CONFIG_MEDIA_CONTROLLER
-	struct media_device *mdev = dev->media_dev;
-	struct media_entity  *entity, *source;
-	struct media_link *link, *found_link = NULL;
-	int i, ret, active_links = 0;
-
-	if (!mdev || !dev->decoder)
-		return 0;
-
-	/*
-	 * This will find the tuner that is connected into the decoder.
-	 * Technically, this is not 100% correct, as the device may be
-	 * using an analog input instead of the tuner. However, as we can't
-	 * do DVB streaming while the DMA engine is being used for V4L2,
-	 * this should be enough for the actual needs.
-	 */
-	for (i = 0; i < dev->decoder->num_links; i++) {
-		link = &dev->decoder->links[i];
-		if (link->sink->entity == dev->decoder) {
-			found_link = link;
-			if (link->flags & MEDIA_LNK_FL_ENABLED)
-				active_links++;
-			break;
-		}
-	}
-
-	if (active_links == 1 || !found_link)
-		return 0;
-
-	source = found_link->source->entity;
-	for (i = 0; i < source->num_links; i++) {
-		struct media_entity *sink;
-		int flags = 0;
-
-		link = &source->links[i];
-		sink = link->sink->entity;
-
-		if (sink == entity)
-			flags = MEDIA_LNK_FL_ENABLED;
-
-		ret = media_entity_setup_link(link, flags);
-		if (ret) {
-			pr_err(
-				"Couldn't change link %s->%s to %s. Error %d\n",
-				source->name, sink->name,
-				flags ? "enabled" : "disabled",
-				ret);
-			return ret;
-		} else
-			au0828_isocdbg(
-				"link %s->%s was %s\n",
-				source->name, sink->name,
-				flags ? "ENABLED" : "disabled");
-	}
-#endif
-	return 0;
-}
-
 static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
 		       unsigned int *nbuffers, unsigned int *nplanes,
 		       unsigned int sizes[], void *alloc_ctxs[])
@@ -712,8 +652,6 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
 	*nplanes = 1;
 	sizes[0] = size;
 
-	au0828_enable_analog_tuner(dev);
-
 	return 0;
 }
 
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v3 16/21] media: au0828 video change to use v4l_enable_media_tuner()
  2015-09-22 17:19 [PATCH v3 00/21] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (14 preceding siblings ...)
  2015-09-22 17:19 ` [PATCH v3 15/21] media: au0828 video remove au0828_enable_analog_tuner() Shuah Khan
@ 2015-09-22 17:19 ` Shuah Khan
  2015-09-22 17:19 ` [PATCH v3 17/21] media: au0828 change to use Managed Media Controller API Shuah Khan
                   ` (4 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Shuah Khan @ 2015-09-22 17:19 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, sakari.ailus, tiwai,
	pawel, m.szyprowski, kyungmin.park, perex, stefanr, crope,
	dan.carpenter, tskd08, ruchandani.tina, arnd, chehabrafael,
	prabhakar.csengg, Julia.Lawall, elfring, ricardo.ribalda,
	chris.j.arges, pierre-louis.bossart, gtmkramer, clemens,
	misterpib, takamichiho, pmatilai, damien, daniel, vladcatoi,
	normalperson, joe, bugzilla.frnkcg, jussi
  Cc: Shuah Khan, linux-media, alsa-devel

au0828 is changed to use v4l_enable_media_tuner() to check for
tuner availability from vidioc_g_tuner(), and au0828_v4l2_close(),
before changing tuner settings. If tuner isn't free, return busy
condition from vidioc_g_tuner() and in au0828_v4l2_close() tuner
is left untouched without powering down to save energy.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/usb/au0828/au0828-video.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c
index b63ae78..6680aeb 100644
--- a/drivers/media/usb/au0828/au0828-video.c
+++ b/drivers/media/usb/au0828/au0828-video.c
@@ -1005,8 +1005,12 @@ static int au0828_v4l2_close(struct file *filp)
 		goto end;
 
 	if (dev->users == 1) {
-		/* Save some power by putting tuner to sleep */
-		v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0);
+		/* Save some power by putting tuner to sleep, if it is free */
+		/* What happens when radio is using tuner?? */
+		ret = v4l_enable_media_tuner(vdev);
+		if (ret == 0)
+			v4l2_device_call_all(&dev->v4l2_dev, 0, core,
+					     s_power, 0);
 		dev->std_set_in_tuner_core = 0;
 
 		/* When close the device, set the usb intf0 into alt0 to free
@@ -1407,10 +1411,16 @@ static int vidioc_s_audio(struct file *file, void *priv, const struct v4l2_audio
 static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
 {
 	struct au0828_dev *dev = video_drvdata(file);
+	struct video_device *vfd = video_devdata(file);
+	int ret;
 
 	if (t->index != 0)
 		return -EINVAL;
 
+	ret = v4l_enable_media_tuner(vfd);
+	if (ret)
+		return ret;
+
 	dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
 		dev->std_set_in_tuner_core, dev->dev_state);
 
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v3 17/21] media: au0828 change to use Managed Media Controller API
  2015-09-22 17:19 [PATCH v3 00/21] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (15 preceding siblings ...)
  2015-09-22 17:19 ` [PATCH v3 16/21] media: au0828 video change to use v4l_enable_media_tuner() Shuah Khan
@ 2015-09-22 17:19 ` Shuah Khan
  2015-09-22 17:19 ` [PATCH v3 18/21] media: au0828 change to register/unregister entity_notify hook Shuah Khan
                   ` (3 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Shuah Khan @ 2015-09-22 17:19 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, sakari.ailus, tiwai,
	pawel, m.szyprowski, kyungmin.park, perex, stefanr, crope,
	dan.carpenter, tskd08, ruchandani.tina, arnd, chehabrafael,
	prabhakar.csengg, Julia.Lawall, elfring, ricardo.ribalda,
	chris.j.arges, pierre-louis.bossart, gtmkramer, clemens,
	misterpib, takamichiho, pmatilai, damien, daniel, vladcatoi,
	normalperson, joe, bugzilla.frnkcg, jussi
  Cc: Shuah Khan, linux-media, alsa-devel

Change au0828 to use Managed Media Controller API to coordinate
creating/deleting media device on parent usb device it shares
with the snd-usb-audio driver. With this change, au0828 uses
media_device_get_devres() to allocate a new media device devres
or return an existing one, if it finds one.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/usb/au0828/au0828-core.c | 45 +++++++++++++++++-----------------
 1 file changed, 22 insertions(+), 23 deletions(-)

diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index 0b8dc49..63e31e2 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -132,9 +132,9 @@ static void au0828_unregister_media_device(struct au0828_dev *dev)
 {
 
 #ifdef CONFIG_MEDIA_CONTROLLER
-	if (dev->media_dev) {
+	if (dev->media_dev &&
+	    media_devnode_is_registered(&dev->media_dev->devnode)) {
 		media_device_unregister(dev->media_dev);
-		kfree(dev->media_dev);
 		dev->media_dev = NULL;
 	}
 #endif
@@ -204,31 +204,30 @@ static void au0828_media_device_register(struct au0828_dev *dev,
 	struct media_device *mdev;
 	int ret;
 
-	mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
+	mdev = media_device_get_devres(&udev->dev);
 	if (!mdev)
 		return;
 
-	mdev->dev = &udev->dev;
-
-	if (!dev->board.name)
-		strlcpy(mdev->model, "unknown au0828", sizeof(mdev->model));
-	else
-		strlcpy(mdev->model, dev->board.name, sizeof(mdev->model));
-	if (udev->serial)
-		strlcpy(mdev->serial, udev->serial, sizeof(mdev->serial));
-	strcpy(mdev->bus_info, udev->devpath);
-	mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice);
-	mdev->driver_version = LINUX_VERSION_CODE;
-
-	ret = media_device_register(mdev);
-	if (ret) {
-		pr_err(
-			"Couldn't create a media device. Error: %d\n",
-			ret);
-		kfree(mdev);
-		return;
+	if (!media_devnode_is_registered(&mdev->devnode)) {
+		/* register media device */
+		mdev->dev = &udev->dev;
+
+		if (udev->product)
+			strlcpy(mdev->model, udev->product,
+				sizeof(mdev->model));
+		if (udev->serial)
+			strlcpy(mdev->serial, udev->serial,
+				sizeof(mdev->serial));
+		strcpy(mdev->bus_info, udev->devpath);
+		mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice);
+		ret = media_device_register(mdev);
+		if (ret) {
+			dev_err(&udev->dev,
+				"Couldn't create a media device. Error: %d\n",
+				ret);
+			return;
+		}
 	}
-
 	dev->media_dev = mdev;
 #endif
 }
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v3 18/21] media: au0828 change to register/unregister entity_notify hook
  2015-09-22 17:19 [PATCH v3 00/21] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (16 preceding siblings ...)
  2015-09-22 17:19 ` [PATCH v3 17/21] media: au0828 change to use Managed Media Controller API Shuah Khan
@ 2015-09-22 17:19 ` Shuah Khan
  2015-09-22 17:19 ` [PATCH v3 19/21] media: au0828 implement enable_source and disable_source handlers Shuah Khan
                   ` (2 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Shuah Khan @ 2015-09-22 17:19 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, sakari.ailus, tiwai,
	pawel, m.szyprowski, kyungmin.park, perex, stefanr, crope,
	dan.carpenter, tskd08, ruchandani.tina, arnd, chehabrafael,
	prabhakar.csengg, Julia.Lawall, elfring, ricardo.ribalda,
	chris.j.arges, pierre-louis.bossart, gtmkramer, clemens,
	misterpib, takamichiho, pmatilai, damien, daniel, vladcatoi,
	normalperson, joe, bugzilla.frnkcg, jussi
  Cc: Shuah Khan, linux-media, alsa-devel

au0828 registers entity_notify hook to create media graph for
the device. This handler runs whenvere a new entity gets added
to the media device. It creates necessary links from video, vbi,
and ALSA entities to decoder and links tuner and decoder entities.
As this handler runs as entities get added, it has to maintain
state on the links it already created. New fields are added to
au0828_dev to keep this state information. entity_notify gets
unregistered before media_device unregister.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/usb/au0828/au0828-core.c | 118 +++++++++++++++++++++------------
 drivers/media/usb/au0828/au0828.h      |   6 ++
 2 files changed, 81 insertions(+), 43 deletions(-)

diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index 63e31e2..fcff2e2 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -134,6 +134,8 @@ static void au0828_unregister_media_device(struct au0828_dev *dev)
 #ifdef CONFIG_MEDIA_CONTROLLER
 	if (dev->media_dev &&
 	    media_devnode_is_registered(&dev->media_dev->devnode)) {
+		media_device_unregister_entity_notify(dev->media_dev,
+						      &dev->entity_notify);
 		media_device_unregister(dev->media_dev);
 		dev->media_dev = NULL;
 	}
@@ -197,6 +199,75 @@ static void au0828_usb_disconnect(struct usb_interface *interface)
 	au0828_usb_release(dev);
 }
 
+static void au0828_create_media_graph(struct media_entity *new,
+				      void *notify_data)
+{
+#ifdef CONFIG_MEDIA_CONTROLLER
+	struct au0828_dev *dev = (struct au0828_dev *) notify_data;
+	struct media_device *mdev = dev->media_dev;
+	struct media_entity *entity, *tuner = NULL, *decoder = NULL;
+	struct media_entity *alsa_capture = NULL;
+	int ret;
+
+	if (!mdev)
+		return;
+
+	if (dev->tuner_linked && dev->vdev_linked && dev->vbi_linked &&
+	    dev->alsa_capture_linked)
+		return;
+
+	media_device_for_each_entity(entity, mdev) {
+		switch (entity->type) {
+		case MEDIA_ENT_T_V4L2_SUBDEV_TUNER:
+			tuner = entity;
+			break;
+		case MEDIA_ENT_T_V4L2_SUBDEV_DECODER:
+			decoder = entity;
+			break;
+		case MEDIA_ENT_T_DEVNODE_ALSA_CAPTURE:
+			alsa_capture = entity;
+			break;
+		}
+	}
+
+	if (!decoder)
+		return;
+
+	/* save tuner for using in enable_source disable_source handlers
+	 * avoid graph walk in those handlers. Note that decoder is
+	 * saved during v4l2_dev registration */
+
+	if (tuner && !dev->tuner_linked) {
+		dev->tuner = tuner;
+		ret = media_entity_create_link(tuner, 0, decoder, 0,
+					       MEDIA_LNK_FL_ENABLED);
+		if (ret == 0)
+			dev->tuner_linked = 1;
+	}
+	if (dev->vdev.entity.parent && !dev->vdev_linked) {
+		ret = media_entity_create_link(decoder, AU8522_PAD_VID_OUT,
+					       &dev->vdev.entity, 0,
+					       MEDIA_LNK_FL_ENABLED);
+		if (ret == 0)
+			dev->vdev_linked = 1;
+	}
+	if (dev->vbi_dev.entity.parent && !dev->vbi_linked) {
+		ret = media_entity_create_link(decoder, AU8522_PAD_VBI_OUT,
+					       &dev->vbi_dev.entity, 0,
+					       MEDIA_LNK_FL_ENABLED);
+		if (ret == 0)
+			dev->vbi_linked = 1;
+	}
+	if (alsa_capture && !dev->alsa_capture_linked) {
+		ret = media_entity_create_link(decoder, AU8522_PAD_AUDIO_OUT,
+					       alsa_capture, 0,
+					       MEDIA_LNK_FL_ENABLED);
+		if (ret == 0)
+			dev->alsa_capture_linked = 1;
+	}
+#endif
+}
+
 static void au0828_media_device_register(struct au0828_dev *dev,
 					  struct usb_device *udev)
 {
@@ -227,52 +298,15 @@ static void au0828_media_device_register(struct au0828_dev *dev,
 				ret);
 			return;
 		}
+		/* register entity_notify callback */
+		dev->entity_notify.notify_data = (void *) dev;
+		dev->entity_notify.notify = au0828_create_media_graph;
+		media_device_register_entity_notify(mdev, &dev->entity_notify);
 	}
 	dev->media_dev = mdev;
 #endif
 }
 
-
-static void au0828_create_media_graph(struct au0828_dev *dev)
-{
-#ifdef CONFIG_MEDIA_CONTROLLER
-	struct media_device *mdev = dev->media_dev;
-	struct media_entity *entity;
-	struct media_entity *tuner = NULL, *decoder = NULL;
-
-	if (!mdev)
-		return;
-
-	media_device_for_each_entity(entity, mdev) {
-		switch (entity->type) {
-		case MEDIA_ENT_T_V4L2_SUBDEV_TUNER:
-			tuner = entity;
-			break;
-		case MEDIA_ENT_T_V4L2_SUBDEV_DECODER:
-			decoder = entity;
-			break;
-		}
-	}
-
-	/* Analog setup, using tuner as a link */
-
-	if (!decoder)
-		return;
-
-	if (tuner)
-		media_entity_create_link(tuner, 0, decoder, 0,
-					 MEDIA_LNK_FL_ENABLED);
-	if (dev->vdev.entity.parent)
-		media_entity_create_link(decoder, AU8522_PAD_VID_OUT,
-					 &dev->vdev.entity, 0,
-					 MEDIA_LNK_FL_ENABLED);
-	if (dev->vbi_dev.entity.parent)
-		media_entity_create_link(decoder, AU8522_PAD_VBI_OUT,
-					 &dev->vbi_dev.entity, 0,
-					 MEDIA_LNK_FL_ENABLED);
-#endif
-}
-
 static int au0828_usb_probe(struct usb_interface *interface,
 	const struct usb_device_id *id)
 {
@@ -385,8 +419,6 @@ static int au0828_usb_probe(struct usb_interface *interface,
 
 	mutex_unlock(&dev->lock);
 
-	au0828_create_media_graph(dev);
-
 	return retval;
 }
 
diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h
index d3644b3..08cc7b8 100644
--- a/drivers/media/usb/au0828/au0828.h
+++ b/drivers/media/usb/au0828/au0828.h
@@ -281,6 +281,12 @@ struct au0828_dev {
 	struct media_device *media_dev;
 	struct media_pad video_pad, vbi_pad;
 	struct media_entity *decoder;
+	struct media_entity *tuner;
+	struct media_entity_notify entity_notify;
+	bool tuner_linked;
+	bool vdev_linked;
+	bool vbi_linked;
+	bool alsa_capture_linked;
 #endif
 };
 
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v3 19/21] media: au0828 implement enable_source and disable_source handlers
  2015-09-22 17:19 [PATCH v3 00/21] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (17 preceding siblings ...)
  2015-09-22 17:19 ` [PATCH v3 18/21] media: au0828 change to register/unregister entity_notify hook Shuah Khan
@ 2015-09-22 17:19 ` Shuah Khan
  2015-09-22 17:19 ` [PATCH v3 20/21] media: media: dvb-frontend fix enable_source error legs Shuah Khan
  2015-09-22 17:19 ` [PATCH v3 21/21] sound/usb: Update ALSA driver to use Managed Media Controller API Shuah Khan
  20 siblings, 0 replies; 22+ messages in thread
From: Shuah Khan @ 2015-09-22 17:19 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, sakari.ailus, tiwai,
	pawel, m.szyprowski, kyungmin.park, perex, stefanr, crope,
	dan.carpenter, tskd08, ruchandani.tina, arnd, chehabrafael,
	prabhakar.csengg, Julia.Lawall, elfring, ricardo.ribalda,
	chris.j.arges, pierre-louis.bossart, gtmkramer, clemens,
	misterpib, takamichiho, pmatilai, damien, daniel, vladcatoi,
	normalperson, joe, bugzilla.frnkcg, jussi
  Cc: Shuah Khan, linux-media, alsa-devel

Implements enable_source and disable_source handlers for other
drivers (v4l2-core, dvb-core, and ALSA) to use to check for
tuner connected to the decoder and activate the link if tuner
is free, and deactivate and free the tuner when it is no longer
needed.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/usb/au0828/au0828-core.c | 169 +++++++++++++++++++++++++++++++++
 drivers/media/usb/au0828/au0828.h      |   2 +
 2 files changed, 171 insertions(+)

diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index fcff2e2..ce9d5d4 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -268,6 +268,164 @@ static void au0828_create_media_graph(struct media_entity *new,
 #endif
 }
 
+static int au0828_enable_source(struct media_entity *entity,
+				struct media_pipeline *pipe)
+{
+#ifdef CONFIG_MEDIA_CONTROLLER
+	struct media_entity  *source;
+	struct media_entity *sink;
+	struct media_link *link, *found_link = NULL;
+	int i, ret = 0;
+	struct media_device *mdev = entity->parent;
+	struct au0828_dev *dev;
+
+	if (!mdev)
+		return -ENODEV;
+
+	/* for ALSA and Video entities, source is the decoder */
+	mutex_lock(&mdev->graph_mutex);
+
+	dev = mdev->source_priv;
+	if (!dev->tuner || !dev->decoder) {
+		ret = -ENODEV;
+		goto end;
+	}
+
+	/*
+	 * For ALSA and V4L2 entity, find the link to which decoder
+	 * is the sink. Look for an active link between decoder and
+	 * tuner, if one exists, nothing to do. If not, look for any
+	 * active links between tuner and any other entity. If one
+	 * exists, tuner is busy. If tuner is free, setup link and
+	 * start pipeline from source (tuner).
+	 * For DVB FE entity, the source for the link is the tuner.
+	 * Check if tuner is available and setup link and start
+	 * pipeline.
+	*/
+	if (entity->type != MEDIA_ENT_T_DEVNODE_DVB_FE)
+		sink = dev->decoder;
+	else
+		sink = entity;
+
+	/* Is an active link between sink and tuner */
+	if (dev->active_link) {
+		if (dev->active_link->sink->entity == sink &&
+		    dev->active_link->source->entity == dev->tuner) {
+			ret = 0;
+			goto end;
+		} else {
+			ret = -EBUSY;
+			goto end;
+		}
+	}
+
+	for (i = 0; i < sink->num_links; i++) {
+		link = &sink->links[i];
+		/* Used to check just the sink, check source too - works?? */
+		if (link->sink->entity == sink &&
+		    link->source->entity == dev->tuner) {
+			found_link = link;
+			break;
+		}
+	}
+
+	if (!found_link) {
+		ret = -ENODEV;
+		goto end;
+	}
+
+	source = found_link->source->entity;
+	for (i = 0; i < source->num_links; i++) {
+		struct media_entity *find_sink;
+		int flags = 0;
+
+		link = &source->links[i];
+		find_sink = link->sink->entity;
+
+		if (find_sink == sink)
+			flags = MEDIA_LNK_FL_ENABLED;
+
+		ret = __media_entity_setup_link(link, flags);
+		if (ret) {
+			pr_err(
+				"Change tuner link %s->%s to %s. Error %d\n",
+				source->name, find_sink->name,
+				flags ? "enabled" : "disabled",
+				ret);
+			goto end;
+		}
+		/* start pipeline */
+		if (find_sink == sink) {
+			dev->active_link = link;
+			ret = __media_entity_pipeline_start(entity, pipe);
+			if (ret) {
+				pr_err("Start Pipeline: %s->%s Error %d\n",
+					source->name, entity->name, ret);
+				goto end;
+			}
+			/* save link owner to avoid audio deactivating
+			   video owned link from disable_source and
+			   vice versa */
+			dev->active_link_owner = entity;
+			pr_info("Started Pipeline: %s->%s ret %d\n",
+				source->name, entity->name, ret);
+		}
+	}
+end:
+	mutex_unlock(&mdev->graph_mutex);
+	return ret;
+#endif
+	return 0;
+}
+
+static void au0828_disable_source(struct media_entity *entity)
+{
+#ifdef CONFIG_MEDIA_CONTROLLER
+	struct media_entity *sink;
+	int ret = 0;
+	struct media_device *mdev = entity->parent;
+	struct au0828_dev *dev;
+
+	if (!mdev)
+		return;
+
+	mutex_lock(&mdev->graph_mutex);
+
+	dev = mdev->source_priv;
+	if (!dev->tuner || !dev->decoder || !dev->active_link) {
+		ret = -ENODEV;
+		goto end;
+	}
+
+	if (entity->type != MEDIA_ENT_T_DEVNODE_DVB_FE)
+		sink = dev->decoder;
+	else
+		sink = entity;
+
+	/* link is active - stop pipeline from source (tuner) */
+	if (dev->active_link && dev->active_link->sink->entity == sink &&
+	    dev->active_link->source->entity == dev->tuner) {
+		/* prevent video from deactivating link when audio
+		   has active pipeline */
+		if (dev->active_link_owner != entity)
+			goto end;
+		__media_entity_pipeline_stop(entity);
+		pr_info("Stopped Pipeline: %s->%s entity %s\n",
+			dev->active_link->source->entity->name,
+			dev->active_link->sink->entity->name,
+			entity->name);
+		ret = __media_entity_setup_link(dev->active_link, 0);
+		if (ret)
+			pr_err("Deactive link Error %d\n", ret);
+		dev->active_link = NULL;
+		dev->active_link_owner = NULL;
+	}
+
+end:
+	mutex_unlock(&mdev->graph_mutex);
+#endif
+}
+
 static void au0828_media_device_register(struct au0828_dev *dev,
 					  struct usb_device *udev)
 {
@@ -291,6 +449,10 @@ static void au0828_media_device_register(struct au0828_dev *dev,
 				sizeof(mdev->serial));
 		strcpy(mdev->bus_info, udev->devpath);
 		mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice);
+		/* Set enable_source and disable_source handlers and data */
+		mdev->source_priv = (void *) dev;
+		mdev->enable_source = au0828_enable_source;
+		mdev->disable_source = au0828_disable_source;
 		ret = media_device_register(mdev);
 		if (ret) {
 			dev_err(&udev->dev,
@@ -303,6 +465,13 @@ static void au0828_media_device_register(struct au0828_dev *dev,
 		dev->entity_notify.notify = au0828_create_media_graph;
 		media_device_register_entity_notify(mdev, &dev->entity_notify);
 	}
+	/* If ALSA registered the media device - set enable_source */
+	if (!mdev->enable_source) {
+		/* Set enable_source and disable_source handlers and data */
+		mdev->source_priv = (void *) dev;
+		mdev->enable_source = au0828_enable_source;
+		mdev->disable_source = au0828_disable_source;
+	}
 	dev->media_dev = mdev;
 #endif
 }
diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h
index 08cc7b8..f64dbbb 100644
--- a/drivers/media/usb/au0828/au0828.h
+++ b/drivers/media/usb/au0828/au0828.h
@@ -287,6 +287,8 @@ struct au0828_dev {
 	bool vdev_linked;
 	bool vbi_linked;
 	bool alsa_capture_linked;
+	struct media_link *active_link;
+	struct media_entity *active_link_owner;
 #endif
 };
 
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v3 20/21] media: media: dvb-frontend fix enable_source error legs
  2015-09-22 17:19 [PATCH v3 00/21] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (18 preceding siblings ...)
  2015-09-22 17:19 ` [PATCH v3 19/21] media: au0828 implement enable_source and disable_source handlers Shuah Khan
@ 2015-09-22 17:19 ` Shuah Khan
  2015-09-22 17:19 ` [PATCH v3 21/21] sound/usb: Update ALSA driver to use Managed Media Controller API Shuah Khan
  20 siblings, 0 replies; 22+ messages in thread
From: Shuah Khan @ 2015-09-22 17:19 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, sakari.ailus, tiwai,
	pawel, m.szyprowski, kyungmin.park, perex, stefanr, crope,
	dan.carpenter, tskd08, ruchandani.tina, arnd, chehabrafael,
	prabhakar.csengg, Julia.Lawall, elfring, ricardo.ribalda,
	chris.j.arges, pierre-louis.bossart, gtmkramer, clemens,
	misterpib, takamichiho, pmatilai, damien, daniel, vladcatoi,
	normalperson, joe, bugzilla.frnkcg, jussi
  Cc: Shuah Khan, linux-media, alsa-devel

When enable_source finds the tuner busy, do dvb_generic_release().
In addition, when dvb_frontend_start() fails, call disable_source
to release tuner.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 drivers/media/dvb-core/dvb_frontend.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index c06dd61..67e30ae 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -2503,13 +2503,13 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
 			if (ret) {
 				dev_err(fe->dvb->device,
 					"Tuner is busy. Error %d\n", ret);
-				goto err1;
+				goto err2;
 			}
 		}
 #endif
 		ret = dvb_frontend_start (fe);
 		if (ret)
-			goto err2;
+			goto err3;
 
 		/*  empty event queue */
 		fepriv->events.eventr = fepriv->events.eventw = 0;
@@ -2519,6 +2519,11 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
 		mutex_unlock (&adapter->mfe_lock);
 	return ret;
 
+err3:
+#ifdef CONFIG_MEDIA_CONTROLLER_DVB
+	if (fe->dvb->mdev && fe->dvb->mdev->disable_source)
+		fe->dvb->mdev->disable_source(dvbdev->entity);
+#endif
 err2:
 	dvb_generic_release(inode, file);
 err1:
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v3 21/21] sound/usb: Update ALSA driver to use Managed Media Controller API
  2015-09-22 17:19 [PATCH v3 00/21] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
                   ` (19 preceding siblings ...)
  2015-09-22 17:19 ` [PATCH v3 20/21] media: media: dvb-frontend fix enable_source error legs Shuah Khan
@ 2015-09-22 17:19 ` Shuah Khan
  20 siblings, 0 replies; 22+ messages in thread
From: Shuah Khan @ 2015-09-22 17:19 UTC (permalink / raw)
  To: mchehab, hans.verkuil, laurent.pinchart, sakari.ailus, tiwai,
	pawel, m.szyprowski, kyungmin.park, perex, stefanr, crope,
	dan.carpenter, tskd08, ruchandani.tina, arnd, chehabrafael,
	prabhakar.csengg, Julia.Lawall, elfring, ricardo.ribalda,
	chris.j.arges, pierre-louis.bossart, gtmkramer, clemens,
	misterpib, takamichiho, pmatilai, damien, daniel, vladcatoi,
	normalperson, joe, bugzilla.frnkcg, jussi
  Cc: Shuah Khan, linux-media, alsa-devel

Change ALSA driver to use Managed ~media Managed Controller
API to share tuner with DVB and V4L2 drivers that control
AU0828 media device.  Media device is created based on a
newly added field value in the struct snd_usb_audio_quirk.
Using this approach, the media controller API usage can be
added for a specific device. In this patch, Media Controller
API is enabled for AU0828 hw. snd_usb_create_quirk() will
check this new field, if set will create a media device using
media_device_get_devres() interface.

media_device_get_devres() will allocate a new media device
devres or return an existing one, if it finds one.

During probe, media usb driver could have created the media
device devres. It will then register the media device if it
isn't already registered. Media device unregister is done from
usb_audio_disconnect().

During probe, media usb driver could have created the
media device devres. It will then register the media
device if it isn't already registered. Media device
unregister is done from usb_audio_disconnect().

New structure media_ctl is added to group the new
fields to support media entity and links. This new
structure is added to struct snd_usb_substream.

A new entity_notify hook and a new ALSA capture media
entity are registered from snd_usb_pcm_open() after
setting up hardware information for the PCM device.

When a new entity is registered, Media Controller API
interface media_device_register_entity() invokes all
registered entity_notify hooks for the media device.
ALSA entity_notify hook parses all the entity list to
find a link from decoder it ALSA entity. This indicates
that the bridge driver created a link from decoder to
ALSA capture entity.

ALSA will attempt to enable the tuner to link the tuner
to the decoder calling enable_source handler if one is
provided by the bridge driver prior to starting Media
pipeline from snd_usb_hw_params(). If enable_source returns
with tuner busy condition, then snd_usb_hw_params() will fail
with -EBUSY. Media pipeline is stopped from snd_usb_hw_free().

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
---
 sound/usb/Makefile       |  15 +++-
 sound/usb/card.c         |   5 ++
 sound/usb/card.h         |   1 +
 sound/usb/media.c        | 178 +++++++++++++++++++++++++++++++++++++++++++++++
 sound/usb/media.h        |  51 ++++++++++++++
 sound/usb/pcm.c          |  29 ++++++--
 sound/usb/quirks-table.h |   1 +
 sound/usb/quirks.c       |   9 ++-
 sound/usb/stream.c       |   2 +
 sound/usb/usbaudio.h     |   1 +
 10 files changed, 284 insertions(+), 8 deletions(-)
 create mode 100644 sound/usb/media.c
 create mode 100644 sound/usb/media.h

diff --git a/sound/usb/Makefile b/sound/usb/Makefile
index 2d2d122..665fdd9 100644
--- a/sound/usb/Makefile
+++ b/sound/usb/Makefile
@@ -2,6 +2,18 @@
 # Makefile for ALSA
 #
 
+# Media Controller
+ifeq ($(CONFIG_MEDIA_CONTROLLER),y)
+  ifeq ($(CONFIG_MEDIA_SUPPORT),y)
+        KBUILD_CFLAGS += -DUSE_MEDIA_CONTROLLER
+  endif
+  ifeq ($(CONFIG_MEDIA_SUPPORT_MODULE),y)
+    ifeq ($(MODULE),y)
+          KBUILD_CFLAGS += -DUSE_MEDIA_CONTROLLER
+    endif
+  endif
+endif
+
 snd-usb-audio-objs := 	card.o \
 			clock.o \
 			endpoint.o \
@@ -13,7 +25,8 @@ snd-usb-audio-objs := 	card.o \
 			pcm.o \
 			proc.o \
 			quirks.o \
-			stream.o
+			stream.o \
+			media.o
 
 snd-usbmidi-lib-objs := midi.o
 
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 1fab977..469d2bf 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -66,6 +66,7 @@
 #include "format.h"
 #include "power.h"
 #include "stream.h"
+#include "media.h"
 
 MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
 MODULE_DESCRIPTION("USB Audio");
@@ -619,6 +620,10 @@ static void usb_audio_disconnect(struct usb_interface *intf)
 		list_for_each_entry(mixer, &chip->mixer_list, list) {
 			snd_usb_mixer_disconnect(mixer);
 		}
+		/* Nice to check quirk && quirk->media_device
+		 * need some special handlings. Doesn't look like
+		 * we have access to quirk here */
+		media_device_delete(intf);
 	}
 
 	chip->num_interfaces--;
diff --git a/sound/usb/card.h b/sound/usb/card.h
index ef580b4..235a85f 100644
--- a/sound/usb/card.h
+++ b/sound/usb/card.h
@@ -155,6 +155,7 @@ struct snd_usb_substream {
 	} dsd_dop;
 
 	bool trigger_tstamp_pending_update; /* trigger timestamp being updated from initial estimate */
+	void *media_ctl;
 };
 
 struct snd_usb_stream {
diff --git a/sound/usb/media.c b/sound/usb/media.c
new file mode 100644
index 0000000..97c3b2d
--- /dev/null
+++ b/sound/usb/media.c
@@ -0,0 +1,178 @@
+/*
+ * media.c - Media Controller specific ALSA driver code
+ *
+ * Copyright (c) 2015 Shuah Khan <shuahkh@osg.samsung.com>
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * This file is released under the GPLv2.
+ */
+
+/*
+ * This file adds Media Controller support to ALSA driver
+ * to use the Media Controller API to share tuner with DVB
+ * and V4L2 drivers that control media device. Media device
+ * is created based on existing quirks framework. Using this
+ * approach, the media controller API usage can be added for
+ * a specific device.
+*/
+
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/usb.h>
+#include <linux/moduleparam.h>
+#include <linux/mutex.h>
+#include <linux/usb/audio.h>
+#include <linux/usb/audio-v2.h>
+#include <linux/module.h>
+
+#include <sound/control.h>
+#include <sound/core.h>
+#include <sound/info.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/initval.h>
+
+#include "usbaudio.h"
+#include "card.h"
+#include "midi.h"
+#include "mixer.h"
+#include "proc.h"
+#include "quirks.h"
+#include "endpoint.h"
+#include "helper.h"
+#include "debug.h"
+#include "pcm.h"
+#include "format.h"
+#include "power.h"
+#include "stream.h"
+#include "media.h"
+
+#ifdef USE_MEDIA_CONTROLLER
+int media_device_init(struct snd_usb_audio *chip, struct usb_interface *iface)
+{
+	struct media_device *mdev;
+	struct usb_device *usbdev = interface_to_usbdev(iface);
+	int ret;
+
+	mdev = media_device_get_devres(&usbdev->dev);
+	if (!mdev)
+		return -ENOMEM;
+	if (!media_devnode_is_registered(&mdev->devnode)) {
+		/* register media device */
+		mdev->dev = &usbdev->dev;
+		if (usbdev->product)
+			strlcpy(mdev->model, usbdev->product,
+				sizeof(mdev->model));
+		if (usbdev->serial)
+			strlcpy(mdev->serial, usbdev->serial,
+				sizeof(mdev->serial));
+		strcpy(mdev->bus_info, usbdev->devpath);
+		mdev->hw_revision = le16_to_cpu(usbdev->descriptor.bcdDevice);
+		ret = media_device_register(mdev);
+		if (ret) {
+			dev_err(&usbdev->dev,
+				"Couldn't create a media device. Error: %d\n",
+				ret);
+			return ret;
+		}
+	}
+	return 0;
+}
+
+void media_device_delete(struct usb_interface *iface)
+{
+	struct media_device *mdev;
+	struct usb_device *usbdev = interface_to_usbdev(iface);
+
+	mdev = media_device_find_devres(&usbdev->dev);
+	if (mdev && media_devnode_is_registered(&mdev->devnode))
+		media_device_unregister(mdev);
+}
+
+static int media_enable_source(struct media_ctl *mctl)
+{
+	if (mctl && mctl->media_dev->enable_source)
+		return mctl->media_dev->enable_source(&mctl->media_entity,
+							&mctl->media_pipe);
+	return 0;
+}
+
+static void media_disable_source(struct media_ctl *mctl)
+{
+	if (mctl && mctl->media_dev->disable_source)
+		mctl->media_dev->disable_source(&mctl->media_entity);
+}
+
+int media_stream_init(struct snd_usb_substream *subs, struct snd_pcm *pcm,
+			int stream)
+{
+	struct media_device *mdev;
+	struct media_ctl *mctl;
+	struct device *pcm_dev = &pcm->streams[stream].dev;
+
+	mdev = media_device_find_devres(&subs->dev->dev);
+	if (!mdev)
+		return -ENODEV;
+
+	if (subs->media_ctl)
+		return 0;
+
+	/* allocate media_ctl */
+	mctl = kzalloc(sizeof(struct media_ctl), GFP_KERNEL);
+	if (!mctl)
+		return -ENOMEM;
+
+	subs->media_ctl = (void *) mctl;
+	mctl->media_dev = mdev;
+	if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+		mctl->media_entity.type = MEDIA_ENT_T_DEVNODE_ALSA_PLAYBACK;
+	else
+		mctl->media_entity.type = MEDIA_ENT_T_DEVNODE_ALSA_CAPTURE;
+	mctl->media_entity.name = pcm->name;
+	mctl->media_entity.info.dev.major = MAJOR(pcm_dev->devt);
+	mctl->media_entity.info.dev.minor = MINOR(pcm_dev->devt);
+	mctl->media_pad.flags = MEDIA_PAD_FL_SINK;
+	media_entity_init(&mctl->media_entity, 1, &mctl->media_pad, 0);
+	return media_device_register_entity(mctl->media_dev,
+						&mctl->media_entity);
+}
+
+void media_stream_delete(struct snd_usb_substream *subs)
+{
+	struct media_ctl *mctl = (struct media_ctl *) subs->media_ctl;
+
+	if (mctl && mctl->media_dev) {
+		struct media_device *mdev;
+
+		mdev = media_device_find_devres(&subs->dev->dev);
+		if (mdev) {
+			media_entity_remove_links(&mctl->media_entity);
+			media_device_unregister_entity(&mctl->media_entity);
+			media_entity_cleanup(&mctl->media_entity);
+		}
+		mctl->media_dev = NULL;
+		kfree(mctl);
+		subs->media_ctl = NULL;
+	}
+}
+
+int media_start_pipeline(struct snd_usb_substream *subs)
+{
+	struct media_ctl *mctl = (struct media_ctl *) subs->media_ctl;
+
+	if (mctl)
+		return media_enable_source(mctl);
+	return 0;
+}
+
+void media_stop_pipeline(struct snd_usb_substream *subs)
+{
+	struct media_ctl *mctl = (struct media_ctl *) subs->media_ctl;
+
+	if (mctl)
+		media_disable_source(mctl);
+}
+#endif
diff --git a/sound/usb/media.h b/sound/usb/media.h
new file mode 100644
index 0000000..90587aa
--- /dev/null
+++ b/sound/usb/media.h
@@ -0,0 +1,51 @@
+/*
+ * media.h - Media Controller specific ALSA driver code
+ *
+ * Copyright (c) 2015 Shuah Khan <shuahkh@osg.samsung.com>
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * This file is released under the GPLv2.
+ */
+
+/*
+ * This file adds Media Controller support to ALSA driver
+ * to use the Media Controller API to share tuner with DVB
+ * and V4L2 drivers that control media device. Media device
+ * is created based on existing quirks framework. Using this
+ * approach, the media controller API usage can be added for
+ * a specific device.
+*/
+#ifndef __MEDIA_H
+
+#ifdef USE_MEDIA_CONTROLLER
+#include <media/media-device.h>
+#include <media/media-entity.h>
+
+struct media_ctl {
+	struct media_device *media_dev;
+	struct media_entity media_entity;
+	struct media_pad media_pad;
+	struct media_pipeline media_pipe;
+};
+
+int media_device_init(struct snd_usb_audio *chip, struct usb_interface *iface);
+void media_device_delete(struct usb_interface *iface);
+int media_stream_init(struct snd_usb_substream *subs, struct snd_pcm *pcm,
+			int stream);
+void media_stream_delete(struct snd_usb_substream *subs);
+int media_start_pipeline(struct snd_usb_substream *subs);
+void media_stop_pipeline(struct snd_usb_substream *subs);
+#else
+static inline int media_device_init(struct snd_usb_audio *chip,
+					struct usb_interface *iface)
+						{ return 0; }
+static inline void media_device_delete(struct usb_interface *iface) { }
+static inline int media_stream_init(struct snd_usb_substream *subs,
+					struct snd_pcm *pcm, int stream)
+						{ return 0; }
+static inline void media_stream_delete(struct snd_usb_substream *subs) { }
+static inline int media_start_pipeline(struct snd_usb_substream *subs)
+					{ return 0; }
+static inline void media_stop_pipeline(struct snd_usb_substream *subs) { }
+#endif
+#endif /* __MEDIA_H */
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index b4ef410..0cba02e 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -35,6 +35,7 @@
 #include "pcm.h"
 #include "clock.h"
 #include "power.h"
+#include "media.h"
 
 #define SUBSTREAM_FLAG_DATA_EP_STARTED	0
 #define SUBSTREAM_FLAG_SYNC_EP_STARTED	1
@@ -687,10 +688,14 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream,
 	struct audioformat *fmt;
 	int ret;
 
+	ret = media_start_pipeline(subs);
+	if (ret)
+		return ret;
+
 	ret = snd_pcm_lib_alloc_vmalloc_buffer(substream,
 					       params_buffer_bytes(hw_params));
 	if (ret < 0)
-		return ret;
+		goto err_ret;
 
 	subs->pcm_format = params_format(hw_params);
 	subs->period_bytes = params_period_bytes(hw_params);
@@ -704,23 +709,29 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream,
 		dev_dbg(&subs->dev->dev,
 			"cannot set format: format = %#x, rate = %d, channels = %d\n",
 			   subs->pcm_format, subs->cur_rate, subs->channels);
-		return -EINVAL;
+		ret = -EINVAL;
+		goto err_ret;
 	}
 
 	down_read(&subs->stream->chip->shutdown_rwsem);
-	if (subs->stream->chip->shutdown)
+	if (subs->stream->chip->shutdown) {
 		ret = -ENODEV;
-	else
+		goto err_ret;
+	} else
 		ret = set_format(subs, fmt);
 	up_read(&subs->stream->chip->shutdown_rwsem);
 	if (ret < 0)
-		return ret;
+		goto err_ret;
 
 	subs->interface = fmt->iface;
 	subs->altset_idx = fmt->altset_idx;
 	subs->need_setup_ep = true;
 
 	return 0;
+
+err_ret:
+	media_stop_pipeline(subs);
+	return ret;
 }
 
 /*
@@ -732,6 +743,7 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream)
 {
 	struct snd_usb_substream *subs = substream->runtime->private_data;
 
+	media_stop_pipeline(subs);
 	subs->cur_audiofmt = NULL;
 	subs->cur_rate = 0;
 	subs->period_bytes = 0;
@@ -1195,6 +1207,7 @@ static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction)
 	struct snd_usb_stream *as = snd_pcm_substream_chip(substream);
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_usb_substream *subs = &as->substream[direction];
+	int ret;
 
 	subs->interface = -1;
 	subs->altset_idx = 0;
@@ -1208,7 +1221,10 @@ static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction)
 	subs->dsd_dop.channel = 0;
 	subs->dsd_dop.marker = 1;
 
-	return setup_hw_info(runtime, subs);
+	ret = setup_hw_info(runtime, subs);
+	if (ret == 0)
+		ret = media_stream_init(subs, as->pcm, direction);
+	return ret;
 }
 
 static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction)
@@ -1217,6 +1233,7 @@ static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction)
 	struct snd_usb_substream *subs = &as->substream[direction];
 
 	stop_endpoints(subs, true);
+	media_stop_pipeline(subs);
 
 	if (!as->chip->shutdown && subs->interface >= 0) {
 		usb_set_interface(subs->dev, subs->interface, 0);
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index 2f6d3e9..51c544f 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -2798,6 +2798,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
 		.product_name = pname, \
 		.ifnum = QUIRK_ANY_INTERFACE, \
 		.type = QUIRK_AUDIO_ALIGN_TRANSFER, \
+		.media_device = 1, \
 	} \
 }
 
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 7c5a701..8190069 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -36,6 +36,7 @@
 #include "pcm.h"
 #include "clock.h"
 #include "stream.h"
+#include "media.h"
 
 /*
  * handle the quirks for the contained interfaces
@@ -541,13 +542,19 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip,
 		[QUIRK_AUDIO_ALIGN_TRANSFER] = create_align_transfer_quirk,
 		[QUIRK_AUDIO_STANDARD_MIXER] = create_standard_mixer_quirk,
 	};
+	int ret;
 
+	if (quirk->media_device) {
+		/* don't want to fail when media_device_init() doesn't work */
+		media_device_init(chip, iface);
+	}
 	if (quirk->type < QUIRK_TYPE_COUNT) {
-		return quirk_funcs[quirk->type](chip, iface, driver, quirk);
+		ret = quirk_funcs[quirk->type](chip, iface, driver, quirk);
 	} else {
 		usb_audio_err(chip, "invalid quirk type %d\n", quirk->type);
 		return -ENXIO;
 	}
+	return ret;
 }
 
 /*
diff --git a/sound/usb/stream.c b/sound/usb/stream.c
index 310a382..6d01c47 100644
--- a/sound/usb/stream.c
+++ b/sound/usb/stream.c
@@ -36,6 +36,7 @@
 #include "format.h"
 #include "clock.h"
 #include "stream.h"
+#include "media.h"
 
 /*
  * free a substream
@@ -52,6 +53,7 @@ static void free_substream(struct snd_usb_substream *subs)
 		kfree(fp);
 	}
 	kfree(subs->rate_list.list);
+	media_stream_delete(subs);
 }
 
 
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index 91d0380..c2dbf1d 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -108,6 +108,7 @@ struct snd_usb_audio_quirk {
 	const char *product_name;
 	int16_t ifnum;
 	uint16_t type;
+	bool media_device;
 	const void *data;
 };
 
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2015-09-22 17:28 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-22 17:19 [PATCH v3 00/21] Update ALSA, and au0828 drivers to use Managed Media Controller API Shuah Khan
2015-09-22 17:19 ` [PATCH v3 01/21] Revert "[media] media: media controller entity framework enhancements for ALSA" Shuah Khan
2015-09-22 17:19 ` [PATCH v3 02/21] media: Media Controller register/unregister entity_notify API Shuah Khan
2015-09-22 17:19 ` [PATCH v3 03/21] media: Add ALSA Media Controller devnodes Shuah Khan
2015-09-22 17:19 ` [PATCH v3 04/21] media: Media Controller enable/disable source handler API Shuah Khan
2015-09-22 17:19 ` [PATCH v3 05/21] media: Media Controller fix to not let stream_count go negative Shuah Khan
2015-09-22 17:19 ` [PATCH v3 06/21] media: Media Controller export non locking __media_entity_setup_link() Shuah Khan
2015-09-22 17:19 ` [PATCH v3 07/21] media: Media Controller non-locking __media_entity_pipeline_start/stop() Shuah Khan
2015-09-22 17:19 ` [PATCH v3 08/21] media: v4l-core add v4l_enable/disable_media_tuner() helper functions Shuah Khan
2015-09-22 17:19 ` [PATCH v3 09/21] media: Move au8522_media_pads enum to au8522.h from au8522_priv.h Shuah Khan
2015-09-22 17:19 ` [PATCH v3 10/21] media: au8522 change to create MC pad for ALSA Audio Out Shuah Khan
2015-09-22 17:19 ` [PATCH v3 11/21] media: au0828 Use au8522_media_pads enum for pad defines Shuah Khan
2015-09-22 17:19 ` [PATCH v3 12/21] media: au0828 fix au0828_create_media_graph() entity checks Shuah Khan
2015-09-22 17:19 ` [PATCH v3 13/21] media: Change v4l-core to check for tuner availability Shuah Khan
2015-09-22 17:19 ` [PATCH v3 14/21] media: dvb-frontend invoke enable/disable_source handlers Shuah Khan
2015-09-22 17:19 ` [PATCH v3 15/21] media: au0828 video remove au0828_enable_analog_tuner() Shuah Khan
2015-09-22 17:19 ` [PATCH v3 16/21] media: au0828 video change to use v4l_enable_media_tuner() Shuah Khan
2015-09-22 17:19 ` [PATCH v3 17/21] media: au0828 change to use Managed Media Controller API Shuah Khan
2015-09-22 17:19 ` [PATCH v3 18/21] media: au0828 change to register/unregister entity_notify hook Shuah Khan
2015-09-22 17:19 ` [PATCH v3 19/21] media: au0828 implement enable_source and disable_source handlers Shuah Khan
2015-09-22 17:19 ` [PATCH v3 20/21] media: media: dvb-frontend fix enable_source error legs Shuah Khan
2015-09-22 17:19 ` [PATCH v3 21/21] sound/usb: Update ALSA driver to use Managed Media Controller API Shuah Khan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).