diff options
| author | Helen Fornazier <helen.koike@collabora.com> | 2017-06-19 20:00:18 +0300 | 
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab@s-opensource.com> | 2017-06-23 15:12:07 +0300 | 
| commit | 4a29b70907496aa9da79112ec31cf9cf2b972c3f (patch) | |
| tree | 9be42df7b467e369899f96e2e4d2e25869bf42f8 /drivers/media/platform/vimc/vimc-sensor.c | |
| parent | 535d296f4841ffbd7f773ff2a559daa6e117f315 (diff) | |
| download | linux-4a29b70907496aa9da79112ec31cf9cf2b972c3f.tar.xz | |
[media] vimc: Subdevices as modules
Change the core structure for adding subdevices in the topology.
Instead of calling the specific create function for each subdevice,
inject a child platform_device with the driver's name.
Each type of node in the topology (sensor, capture, debayer, scaler)
will register a platform_driver with the corresponding name through the
component subsystem.
Implementing a new subdevice type doesn't require vimc-core to be altered.
This facilitates future implementation of dynamic entities, where
hotpluging an entity in the topology is just a matter of
registering/unregistering a platform_device in the system.
It also facilitates other implementations of different nodes without
touching the core code and remove the need of a header file for each
type of node.
Signed-off-by: Helen Koike <helen.koike@collabora.com>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Diffstat (limited to 'drivers/media/platform/vimc/vimc-sensor.c')
| -rw-r--r-- | drivers/media/platform/vimc/vimc-sensor.c | 93 | 
1 files changed, 68 insertions, 25 deletions
diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c index d4f97050b544..5ea7b0853936 100644 --- a/drivers/media/platform/vimc/vimc-sensor.c +++ b/drivers/media/platform/vimc/vimc-sensor.c @@ -15,18 +15,24 @@   *   */ +#include <linux/component.h>  #include <linux/freezer.h>  #include <linux/kthread.h> +#include <linux/module.h> +#include <linux/platform_device.h>  #include <linux/v4l2-mediabus.h>  #include <linux/vmalloc.h>  #include <media/v4l2-subdev.h>  #include <media/v4l2-tpg.h> -#include "vimc-sensor.h" +#include "vimc-common.h" + +#define VIMC_SEN_DRV_NAME "vimc-sensor"  struct vimc_sen_device {  	struct vimc_ent_device ved;  	struct v4l2_subdev sd; +	struct device *dev;  	struct tpg_data tpg;  	struct task_struct *kthread_sen;  	u8 *frame; @@ -166,7 +172,7 @@ static int vimc_sen_set_fmt(struct v4l2_subdev *sd,  	/* Set the new format */  	vimc_sen_adjust_fmt(&fmt->format); -	dev_dbg(vsen->sd.v4l2_dev->mdev->dev, "%s: format update: " +	dev_dbg(vsen->dev, "%s: format update: "  		"old:%dx%d (0x%x, %d, %d, %d, %d) "  		"new:%dx%d (0x%x, %d, %d, %d, %d)\n", vsen->sd.name,  		/* old */ @@ -252,8 +258,8 @@ static int vimc_sen_s_stream(struct v4l2_subdev *sd, int enable)  		vsen->kthread_sen = kthread_run(vimc_sen_tpg_thread, vsen,  					"%s-sen", vsen->sd.v4l2_dev->name);  		if (IS_ERR(vsen->kthread_sen)) { -			dev_err(vsen->sd.v4l2_dev->dev, -				"%s: kernel_thread() failed\n",	vsen->sd.name); +			dev_err(vsen->dev, "%s: kernel_thread() failed\n", +				vsen->sd.name);  			vfree(vsen->frame);  			vsen->frame = NULL;  			return PTR_ERR(vsen->kthread_sen); @@ -285,8 +291,10 @@ static const struct v4l2_subdev_ops vimc_sen_ops = {  	.video = &vimc_sen_video_ops,  }; -static void vimc_sen_destroy(struct vimc_ent_device *ved) +static void vimc_sen_comp_unbind(struct device *comp, struct device *master, +				 void *master_data)  { +	struct vimc_ent_device *ved = dev_get_drvdata(comp);  	struct vimc_sen_device *vsen =  				container_of(ved, struct vimc_sen_device, ved); @@ -295,36 +303,31 @@ static void vimc_sen_destroy(struct vimc_ent_device *ved)  	kfree(vsen);  } -struct vimc_ent_device *vimc_sen_create(struct v4l2_device *v4l2_dev, -					const char *const name, -					u16 num_pads, -					const unsigned long *pads_flag) +static int vimc_sen_comp_bind(struct device *comp, struct device *master, +			      void *master_data)  { +	struct v4l2_device *v4l2_dev = master_data; +	struct vimc_platform_data *pdata = comp->platform_data;  	struct vimc_sen_device *vsen; -	unsigned int i;  	int ret; -	/* NOTE: a sensor node may be created with more then one pad */ -	if (!name || !num_pads || !pads_flag) -		return ERR_PTR(-EINVAL); - -	/* check if all pads are sources */ -	for (i = 0; i < num_pads; i++) -		if (!(pads_flag[i] & MEDIA_PAD_FL_SOURCE)) -			return ERR_PTR(-EINVAL); -  	/* Allocate the vsen struct */  	vsen = kzalloc(sizeof(*vsen), GFP_KERNEL);  	if (!vsen) -		return ERR_PTR(-ENOMEM); +		return -ENOMEM;  	/* Initialize ved and sd */ -	ret = vimc_ent_sd_register(&vsen->ved, &vsen->sd, v4l2_dev, name, -				   MEDIA_ENT_F_CAM_SENSOR, num_pads, pads_flag, -				   &vimc_sen_ops, vimc_sen_destroy); +	ret = vimc_ent_sd_register(&vsen->ved, &vsen->sd, v4l2_dev, +				   pdata->entity_name, +				   MEDIA_ENT_F_ATV_DECODER, 1, +				   (const unsigned long[1]) {MEDIA_PAD_FL_SOURCE}, +				   &vimc_sen_ops);  	if (ret)  		goto err_free_vsen; +	dev_set_drvdata(comp, &vsen->ved); +	vsen->dev = comp; +  	/* Initialize the frame format */  	vsen->mbus_format = fmt_default; @@ -335,12 +338,52 @@ struct vimc_ent_device *vimc_sen_create(struct v4l2_device *v4l2_dev,  	if (ret)  		goto err_unregister_ent_sd; -	return &vsen->ved; +	return 0;  err_unregister_ent_sd:  	vimc_ent_sd_unregister(&vsen->ved,  &vsen->sd);  err_free_vsen:  	kfree(vsen); -	return ERR_PTR(ret); +	return ret;  } + +static const struct component_ops vimc_sen_comp_ops = { +	.bind = vimc_sen_comp_bind, +	.unbind = vimc_sen_comp_unbind, +}; + +static int vimc_sen_probe(struct platform_device *pdev) +{ +	return component_add(&pdev->dev, &vimc_sen_comp_ops); +} + +static int vimc_sen_remove(struct platform_device *pdev) +{ +	component_del(&pdev->dev, &vimc_sen_comp_ops); + +	return 0; +} + +static struct platform_driver vimc_sen_pdrv = { +	.probe		= vimc_sen_probe, +	.remove		= vimc_sen_remove, +	.driver		= { +		.name	= VIMC_SEN_DRV_NAME, +	}, +}; + +static const struct platform_device_id vimc_sen_driver_ids[] = { +	{ +		.name           = VIMC_SEN_DRV_NAME, +	}, +	{ } +}; + +module_platform_driver(vimc_sen_pdrv); + +MODULE_DEVICE_TABLE(platform, vimc_sen_driver_ids); + +MODULE_DESCRIPTION("Virtual Media Controller Driver (VIMC) Sensor"); +MODULE_AUTHOR("Helen Mae Koike Fornazier <helen.fornazier@gmail.com>"); +MODULE_LICENSE("GPL");  | 
