From fd911e7221a8a47c4f4303197931b16c401d0f04 Mon Sep 17 00:00:00 2001 From: Xu Hongfei Date: Thu, 6 Jun 2019 11:24:34 +0800 Subject: [PATCH] media: i2c: nvp6324: support media controller in driver Change-Id: I982b626c22303487a5fa3d64391a37685ef4d7e1 Signed-off-by: Xu Hongfei --- drivers/media/i2c/jaguar1_drv/jaguar1_drv.c | 12 ++++ drivers/media/i2c/jaguar1_drv/jaguar1_drv.h | 5 ++ drivers/media/i2c/jaguar1_drv/jaguar1_v4l2.c | 74 +++++++++++++++++++- 3 files changed, 88 insertions(+), 3 deletions(-) diff --git a/drivers/media/i2c/jaguar1_drv/jaguar1_drv.c b/drivers/media/i2c/jaguar1_drv/jaguar1_drv.c index 28838572ada6..324a8f577bd3 100644 --- a/drivers/media/i2c/jaguar1_drv/jaguar1_drv.c +++ b/drivers/media/i2c/jaguar1_drv/jaguar1_drv.c @@ -692,6 +692,18 @@ static long jaguar1_ioctl(struct file *file, unsigned int cmd, unsigned long arg return 0; } +/* + * mclk + * default: 756MHZ + * 1: 378MHZ + * 2: 594MHZ + * 3: 1242MHZ + */ +void jaguar1_set_mclk(unsigned int mclk) +{ + jaguar1_mclk = mclk; +} + void jaguar1_start(video_init_all *video_init) { down(&jaguar1_lock); diff --git a/drivers/media/i2c/jaguar1_drv/jaguar1_drv.h b/drivers/media/i2c/jaguar1_drv/jaguar1_drv.h index 1a3b01a38c1d..da1db92870e0 100644 --- a/drivers/media/i2c/jaguar1_drv/jaguar1_drv.h +++ b/drivers/media/i2c/jaguar1_drv/jaguar1_drv.h @@ -18,6 +18,11 @@ #include "jaguar1_video.h" +#define JAGUAR1_MCLK_594MHZ 0x01 +#define JAGUAR1_MCLK_378MHZ 0x02 +#define JAGUAR1_MCLK_1242MHZ 0x03 + +void jaguar1_set_mclk(unsigned int mclk); void jaguar1_start(video_init_all *video_init); void jaguar1_stop(void); int jaguar1_init(int i2c_bus); diff --git a/drivers/media/i2c/jaguar1_drv/jaguar1_v4l2.c b/drivers/media/i2c/jaguar1_drv/jaguar1_v4l2.c index 20ca13c1b4c5..cee6c3ddae09 100644 --- a/drivers/media/i2c/jaguar1_drv/jaguar1_v4l2.c +++ b/drivers/media/i2c/jaguar1_drv/jaguar1_v4l2.c @@ -45,6 +45,7 @@ #endif #define JAGUAR1_XVCLK_FREQ 24000000 +#define JAGUAR1_LINK_FREQ 320000000 #define OF_CAMERA_PINCTRL_STATE_DEFAULT "rockchip,camera_default" #define OF_CAMERA_PINCTRL_STATE_SLEEP "rockchip,camera_sleep" @@ -54,7 +55,7 @@ #define JAGUAR1_NAME "jaguar1" -#define FORCE_720P +/* #define FORCE_720P */ struct jaguar1_gpio { int pltfrm_gpio; @@ -99,6 +100,7 @@ struct jaguar1 { struct v4l2_subdev subdev; struct media_pad pad; + struct v4l2_ctrl_handler ctrl_handler; struct mutex mutex; bool power_on; struct jaguar1_regulators regulators; @@ -139,9 +141,12 @@ static const struct jaguar1_framesize jaguar1_framesizes[] = { static const struct jaguar1_pixfmt jaguar1_formats[] = { { .code = MEDIA_BUS_FMT_UYVY8_2X8, - } + }, }; +static const s64 link_freq_menu_items[] = { + JAGUAR1_LINK_FREQ +}; static int __jaguar1_power_on(struct jaguar1 *jaguar1) { u32 i; @@ -294,6 +299,39 @@ exit: return ret; } +static int jaguar1_initialize_controls(struct jaguar1 *jaguar1) +{ + struct v4l2_ctrl_handler *handler; + struct v4l2_ctrl *ctrl; + int ret; + + handler = &jaguar1->ctrl_handler; + ret = v4l2_ctrl_handler_init(handler, 1); + if (ret) + return ret; + handler->lock = &jaguar1->mutex; + + ctrl = v4l2_ctrl_new_int_menu(handler, NULL, V4L2_CID_LINK_FREQ, + 0, 0, link_freq_menu_items); + if (ctrl) + ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; + + if (handler->error) { + ret = handler->error; + dev_err(&jaguar1->client->dev, + "Failed to init controls(%d)\n", ret); + goto err_free_handler; + } + + jaguar1->subdev.ctrl_handler = handler; + + return 0; + +err_free_handler: + v4l2_ctrl_handler_free(handler); + + return ret; +} static void jaguar1_get_default_format(struct v4l2_mbus_framefmt *format) { format->width = jaguar1_framesizes[0].width; @@ -319,6 +357,7 @@ static int jaguar1_stream(struct v4l2_subdev *sd, int on) goto unlock; if (on) { + jaguar1_set_mclk(JAGUAR1_MCLK_1242MHZ); fmt_idx = jaguar1->frame_size->fmt_idx; for (ch = 0; ch < 4; ch++) { video_init.ch_param[ch].ch = ch; @@ -408,7 +447,7 @@ static int jaguar1_get_fmt(struct v4l2_subdev *sd, fmt->format = jaguar1->format; mutex_unlock(&jaguar1->mutex); - dev_info(&client->dev, "%s: %x %dx%d\n", __func__, + dev_dbg(&client->dev, "%s: %x %dx%d\n", __func__, jaguar1->format.code, jaguar1->format.width, jaguar1->format.height); @@ -774,6 +813,7 @@ static int jaguar1_probe(struct i2c_client *client, sd = &jaguar1->subdev; v4l2_i2c_subdev_init(sd, client, &jaguar1_subdev_ops); + ret = jaguar1_initialize_controls(jaguar1); __jaguar1_power_on(jaguar1); ret = jaguar1_init(i2c_adapter_id(client->adapter)); @@ -785,11 +825,38 @@ static int jaguar1_probe(struct i2c_client *client, return ret; } +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API + sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; +#endif +#if defined(CONFIG_MEDIA_CONTROLLER) + jaguar1->pad.flags = MEDIA_PAD_FL_SOURCE; + sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + ret = media_entity_init(&sd->entity, 1, &jaguar1->pad, 0); + if (ret < 0) + goto err_power_off; +#endif + + ret = v4l2_async_register_subdev_sensor_common(sd); + if (ret) { + dev_err(dev, "v4l2 async register subdev failed\n"); + goto err_clean_entity; + } + pm_runtime_set_active(dev); pm_runtime_enable(dev); pm_runtime_idle(dev); return 0; + +err_power_off: + __jaguar1_power_off(jaguar1); +err_clean_entity: +#if defined(CONFIG_MEDIA_CONTROLLER) + media_entity_cleanup(&sd->entity); +#endif + mutex_destroy(&jaguar1->mutex); + + return ret; } static int jaguar1_remove(struct i2c_client *client) @@ -798,6 +865,7 @@ static int jaguar1_remove(struct i2c_client *client) struct jaguar1 *jaguar1 = to_jaguar1(sd); jaguar1_exit(); + v4l2_ctrl_handler_free(&jaguar1->ctrl_handler); mutex_destroy(&jaguar1->mutex); pm_runtime_disable(&client->dev);