Commit a0246e02 authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab

[media] dvbdev: add support for media controller

Provide a way to register media controller device nodes
at the DVB core.

Please notice that the dvbdev callers also require changes
for the devices to be registered via the media controller.
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent 0b6ffd45
...@@ -87,13 +87,21 @@ config MEDIA_RC_SUPPORT ...@@ -87,13 +87,21 @@ config MEDIA_RC_SUPPORT
config MEDIA_CONTROLLER config MEDIA_CONTROLLER
bool "Media Controller API" bool "Media Controller API"
depends on MEDIA_CAMERA_SUPPORT depends on MEDIA_CAMERA_SUPPORT || MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT
---help--- ---help---
Enable the media controller API used to query media devices internal Enable the media controller API used to query media devices internal
topology and configure it dynamically. topology and configure it dynamically.
This API is mostly used by camera interfaces in embedded platforms. This API is mostly used by camera interfaces in embedded platforms.
config MEDIA_CONTROLLER_DVB
bool "Enable Media controller for DVB"
depends on MEDIA_CONTROLLER
---help---
Enable the media controller API support for DVB.
This is currently experimental.
# #
# Video4Linux support # Video4Linux support
# Only enables if one of the V4L2 types (ATV, webcam, radio) is selected # Only enables if one of the V4L2 types (ATV, webcam, radio) is selected
......
...@@ -180,6 +180,59 @@ static int dvbdev_get_free_id (struct dvb_adapter *adap, int type) ...@@ -180,6 +180,59 @@ static int dvbdev_get_free_id (struct dvb_adapter *adap, int type)
return -ENFILE; return -ENFILE;
} }
static void dvb_register_media_device(struct dvb_device *dvbdev,
int type, int minor)
{
#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
int ret;
if (!dvbdev->adapter->mdev)
return;
dvbdev->entity = kzalloc(sizeof(*dvbdev->entity), GFP_KERNEL);
if (!dvbdev->entity)
return;
dvbdev->entity->info.dev.major = DVB_MAJOR;
dvbdev->entity->info.dev.minor = minor;
dvbdev->entity->name = dvbdev->name;
switch (type) {
case DVB_DEVICE_FRONTEND:
dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_FE;
break;
case DVB_DEVICE_DEMUX:
dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_DEMUX;
break;
case DVB_DEVICE_DVR:
dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_DVR;
break;
case DVB_DEVICE_CA:
dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_CA;
break;
case DVB_DEVICE_NET:
dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_NET;
break;
default:
kfree(dvbdev->entity);
dvbdev->entity = NULL;
return;
}
ret = media_device_register_entity(dvbdev->adapter->mdev,
dvbdev->entity);
if (ret < 0) {
printk(KERN_ERR
"%s: media_device_register_entity failed for %s\n",
__func__, dvbdev->entity->name);
kfree(dvbdev->entity);
dvbdev->entity = NULL;
return;
}
printk(KERN_DEBUG "%s: media device '%s' registered.\n",
__func__, dvbdev->entity->name);
#endif
}
int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
const struct dvb_device *template, void *priv, int type) const struct dvb_device *template, void *priv, int type)
...@@ -258,10 +311,11 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, ...@@ -258,10 +311,11 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
__func__, adap->num, dnames[type], id, PTR_ERR(clsdev)); __func__, adap->num, dnames[type], id, PTR_ERR(clsdev));
return PTR_ERR(clsdev); return PTR_ERR(clsdev);
} }
dprintk(KERN_DEBUG "DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n", dprintk(KERN_DEBUG "DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
adap->num, dnames[type], id, minor, minor); adap->num, dnames[type], id, minor, minor);
dvb_register_media_device(dvbdev, type, minor);
return 0; return 0;
} }
EXPORT_SYMBOL(dvb_register_device); EXPORT_SYMBOL(dvb_register_device);
...@@ -278,6 +332,13 @@ void dvb_unregister_device(struct dvb_device *dvbdev) ...@@ -278,6 +332,13 @@ void dvb_unregister_device(struct dvb_device *dvbdev)
device_destroy(dvb_class, MKDEV(DVB_MAJOR, dvbdev->minor)); device_destroy(dvb_class, MKDEV(DVB_MAJOR, dvbdev->minor));
#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
if (dvbdev->entity) {
media_device_unregister_entity(dvbdev->entity);
kfree(dvbdev->entity);
}
#endif
list_del (&dvbdev->list_head); list_del (&dvbdev->list_head);
kfree (dvbdev->fops); kfree (dvbdev->fops);
kfree (dvbdev); kfree (dvbdev);
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/poll.h> #include <linux/poll.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/list.h> #include <linux/list.h>
#include <media/media-device.h>
#define DVB_MAJOR 212 #define DVB_MAJOR 212
...@@ -71,6 +72,10 @@ struct dvb_adapter { ...@@ -71,6 +72,10 @@ struct dvb_adapter {
int mfe_shared; /* indicates mutually exclusive frontends */ int mfe_shared; /* indicates mutually exclusive frontends */
struct dvb_device *mfe_dvbdev; /* frontend device in use */ struct dvb_device *mfe_dvbdev; /* frontend device in use */
struct mutex mfe_lock; /* access lock for thread creation */ struct mutex mfe_lock; /* access lock for thread creation */
#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
struct media_device *mdev;
#endif
}; };
...@@ -92,6 +97,14 @@ struct dvb_device { ...@@ -92,6 +97,14 @@ struct dvb_device {
/* don't really need those !? -- FIXME: use video_usercopy */ /* don't really need those !? -- FIXME: use video_usercopy */
int (*kernel_ioctl)(struct file *file, unsigned int cmd, void *arg); int (*kernel_ioctl)(struct file *file, unsigned int cmd, void *arg);
/* Needed for media controller register/unregister */
#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
const char *name;
/* Filled inside dvbdev.c */
struct media_entity *entity;
#endif
void *priv; void *priv;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment