diff options
Diffstat (limited to 'drivers/media/platform/vimc')
| -rw-r--r-- | drivers/media/platform/vimc/vimc-common.h | 5 | ||||
| -rw-r--r-- | drivers/media/platform/vimc/vimc-sensor.c | 65 | 
2 files changed, 68 insertions, 2 deletions
| diff --git a/drivers/media/platform/vimc/vimc-common.h b/drivers/media/platform/vimc/vimc-common.h index dca528a316e7..2e9981b18166 100644 --- a/drivers/media/platform/vimc/vimc-common.h +++ b/drivers/media/platform/vimc/vimc-common.h @@ -22,6 +22,11 @@  #include <media/media-device.h>  #include <media/v4l2-device.h> +/* VIMC-specific controls */ +#define VIMC_CID_VIMC_BASE		(0x00f00000 | 0xf000) +#define VIMC_CID_VIMC_CLASS		(0x00f00000 | 1) +#define VIMC_CID_TEST_PATTERN		(VIMC_CID_VIMC_BASE + 0) +  #define VIMC_FRAME_MAX_WIDTH 4096  #define VIMC_FRAME_MAX_HEIGHT 2160  #define VIMC_FRAME_MIN_WIDTH 16 diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c index 02e68c8fc02b..457e211514c6 100644 --- a/drivers/media/platform/vimc/vimc-sensor.c +++ b/drivers/media/platform/vimc/vimc-sensor.c @@ -22,8 +22,9 @@  #include <linux/platform_device.h>  #include <linux/v4l2-mediabus.h>  #include <linux/vmalloc.h> +#include <media/v4l2-ctrls.h>  #include <media/v4l2-subdev.h> -#include <media/v4l2-tpg.h> +#include <media/tpg/v4l2-tpg.h>  #include "vimc-common.h" @@ -38,6 +39,7 @@ struct vimc_sen_device {  	u8 *frame;  	/* The active format */  	struct v4l2_mbus_framefmt mbus_format; +	struct v4l2_ctrl_handler hdl;  };  static const struct v4l2_mbus_framefmt fmt_default = { @@ -291,6 +293,31 @@ static const struct v4l2_subdev_ops vimc_sen_ops = {  	.video = &vimc_sen_video_ops,  }; +static int vimc_sen_s_ctrl(struct v4l2_ctrl *ctrl) +{ +	struct vimc_sen_device *vsen = +		container_of(ctrl->handler, struct vimc_sen_device, hdl); + +	switch (ctrl->id) { +	case VIMC_CID_TEST_PATTERN: +		tpg_s_pattern(&vsen->tpg, ctrl->val); +		break; +	case V4L2_CID_HFLIP: +		tpg_s_hflip(&vsen->tpg, ctrl->val); +		break; +	case V4L2_CID_VFLIP: +		tpg_s_vflip(&vsen->tpg, ctrl->val); +		break; +	default: +		return -EINVAL; +	} +	return 0; +} + +static const struct v4l2_ctrl_ops vimc_sen_ctrl_ops = { +	.s_ctrl = vimc_sen_s_ctrl, +}; +  static void vimc_sen_comp_unbind(struct device *comp, struct device *master,  				 void *master_data)  { @@ -299,10 +326,28 @@ static void vimc_sen_comp_unbind(struct device *comp, struct device *master,  				container_of(ved, struct vimc_sen_device, ved);  	vimc_ent_sd_unregister(ved, &vsen->sd); +	v4l2_ctrl_handler_free(&vsen->hdl);  	tpg_free(&vsen->tpg);  	kfree(vsen);  } +/* Image Processing Controls */ +static const struct v4l2_ctrl_config vimc_sen_ctrl_class = { +	.flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY, +	.id = VIMC_CID_VIMC_CLASS, +	.name = "VIMC Controls", +	.type = V4L2_CTRL_TYPE_CTRL_CLASS, +}; + +static const struct v4l2_ctrl_config vimc_sen_ctrl_test_pattern = { +	.ops = &vimc_sen_ctrl_ops, +	.id = VIMC_CID_TEST_PATTERN, +	.name = "Test Pattern", +	.type = V4L2_CTRL_TYPE_MENU, +	.max = TPG_PAT_NOISE, +	.qmenu = tpg_pattern_strings, +}; +  static int vimc_sen_comp_bind(struct device *comp, struct device *master,  			      void *master_data)  { @@ -316,6 +361,20 @@ static int vimc_sen_comp_bind(struct device *comp, struct device *master,  	if (!vsen)  		return -ENOMEM; +	v4l2_ctrl_handler_init(&vsen->hdl, 4); + +	v4l2_ctrl_new_custom(&vsen->hdl, &vimc_sen_ctrl_class, NULL); +	v4l2_ctrl_new_custom(&vsen->hdl, &vimc_sen_ctrl_test_pattern, NULL); +	v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops, +			  V4L2_CID_VFLIP, 0, 1, 1, 0); +	v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops, +			  V4L2_CID_HFLIP, 0, 1, 1, 0); +	vsen->sd.ctrl_handler = &vsen->hdl; +	if (vsen->hdl.error) { +		ret = vsen->hdl.error; +		goto err_free_vsen; +	} +  	/* Initialize ved and sd */  	ret = vimc_ent_sd_register(&vsen->ved, &vsen->sd, v4l2_dev,  				   pdata->entity_name, @@ -323,7 +382,7 @@ static int vimc_sen_comp_bind(struct device *comp, struct device *master,  				   (const unsigned long[1]) {MEDIA_PAD_FL_SOURCE},  				   &vimc_sen_ops);  	if (ret) -		goto err_free_vsen; +		goto err_free_hdl;  	dev_set_drvdata(comp, &vsen->ved);  	vsen->dev = comp; @@ -342,6 +401,8 @@ static int vimc_sen_comp_bind(struct device *comp, struct device *master,  err_unregister_ent_sd:  	vimc_ent_sd_unregister(&vsen->ved,  &vsen->sd); +err_free_hdl: +	v4l2_ctrl_handler_free(&vsen->hdl);  err_free_vsen:  	kfree(vsen); |