From e90812c47b958407b54d05780dc483fdc1b57a93 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:11 +0200 Subject: [PATCH 001/394] staging: media: rkvdec: fix pm_runtime_get_sync() usage count The pm_runtime_get_sync() internally increments the dev->power.usage_count without decrementing it, even on errors. Replace it by the new pm_runtime_resume_and_get(), introduced by: commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") in order to properly decrement the usage counter, avoiding a potential PM usage counter leak. Reviewed-by: Ezequiel Garcia Reviewed-by: Jonathan Cameron Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/rkvdec/rkvdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c index d821661d30f3..8c17615f3a7a 100644 --- a/drivers/staging/media/rkvdec/rkvdec.c +++ b/drivers/staging/media/rkvdec/rkvdec.c @@ -658,7 +658,7 @@ static void rkvdec_device_run(void *priv) if (WARN_ON(!desc)) return; - ret = pm_runtime_get_sync(rkvdec->dev); + ret = pm_runtime_resume_and_get(rkvdec->dev); if (ret < 0) { rkvdec_job_finish_no_pm(ctx, VB2_BUF_STATE_ERROR); return; From 4cba5473c5ce0f1389d316c5dc6f83a0259df5eb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 27 Apr 2021 10:39:47 +0200 Subject: [PATCH 002/394] media: venus: Rework error fail recover logic The Venus code has a sort of watchdog that attempts to recover from IP errors, implemented as a delayed work job, which calls venus_sys_error_handler(). Right now, it has several issues: 1. It assumes that PM runtime resume never fails 2. It internally runs two while() loops that also assume that PM runtime will never fail to go idle: while (pm_runtime_active(core->dev_dec) || pm_runtime_active(core->dev_enc)) msleep(10); ... while (core->pmdomains[0] && pm_runtime_active(core->pmdomains[0])) usleep_range(1000, 1500); 3. It uses an OR to merge all return codes and then report to the user 4. If the hardware never recovers, it keeps running on every 10ms, flooding the syslog with 2 messages (so, up to 200 messages per second). Rework the code, in order to prevent that, by: 1. check the return code from PM runtime resume; 2. don't let the while() loops run forever; 3. store the failed event; 4. use warn ratelimited when it fails to recover. Fixes: af2c3834c8ca ("[media] media: venus: adding core part and helper functions") Reviewed-by: Jonathan Cameron Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/venus/core.c | 58 +++++++++++++++++++----- 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c index 54bac7ec14c5..91b15842c555 100644 --- a/drivers/media/platform/qcom/venus/core.c +++ b/drivers/media/platform/qcom/venus/core.c @@ -78,22 +78,32 @@ static const struct hfi_core_ops venus_core_ops = { .event_notify = venus_event_notify, }; +#define RPM_WAIT_FOR_IDLE_MAX_ATTEMPTS 10 + static void venus_sys_error_handler(struct work_struct *work) { struct venus_core *core = container_of(work, struct venus_core, work.work); - int ret = 0; + int ret, i, max_attempts = RPM_WAIT_FOR_IDLE_MAX_ATTEMPTS; + const char *err_msg = ""; + bool failed = false; - pm_runtime_get_sync(core->dev); + ret = pm_runtime_get_sync(core->dev); + if (ret < 0) { + err_msg = "resume runtime PM"; + max_attempts = 0; + failed = true; + } hfi_core_deinit(core, true); - dev_warn(core->dev, "system error has occurred, starting recovery!\n"); - mutex_lock(&core->lock); - while (pm_runtime_active(core->dev_dec) || pm_runtime_active(core->dev_enc)) + for (i = 0; i < max_attempts; i++) { + if (!pm_runtime_active(core->dev_dec) && !pm_runtime_active(core->dev_enc)) + break; msleep(10); + } venus_shutdown(core); @@ -101,31 +111,55 @@ static void venus_sys_error_handler(struct work_struct *work) pm_runtime_put_sync(core->dev); - while (core->pmdomains[0] && pm_runtime_active(core->pmdomains[0])) + for (i = 0; i < max_attempts; i++) { + if (!core->pmdomains[0] || !pm_runtime_active(core->pmdomains[0])) + break; usleep_range(1000, 1500); + } hfi_reinit(core); - pm_runtime_get_sync(core->dev); + ret = pm_runtime_get_sync(core->dev); + if (ret < 0) { + err_msg = "resume runtime PM"; + failed = true; + } - ret |= venus_boot(core); - ret |= hfi_core_resume(core, true); + ret = venus_boot(core); + if (ret && !failed) { + err_msg = "boot Venus"; + failed = true; + } + + ret = hfi_core_resume(core, true); + if (ret && !failed) { + err_msg = "resume HFI"; + failed = true; + } enable_irq(core->irq); mutex_unlock(&core->lock); - ret |= hfi_core_init(core); + ret = hfi_core_init(core); + if (ret && !failed) { + err_msg = "init HFI"; + failed = true; + } pm_runtime_put_sync(core->dev); - if (ret) { + if (failed) { disable_irq_nosync(core->irq); - dev_warn(core->dev, "recovery failed (%d)\n", ret); + dev_warn_ratelimited(core->dev, + "System error has occurred, recovery failed to %s\n", + err_msg); schedule_delayed_work(&core->work, msecs_to_jiffies(10)); return; } + dev_warn(core->dev, "system error has occurred (recovered)\n"); + mutex_lock(&core->lock); core->sys_error = false; mutex_unlock(&core->lock); From 747bad54a677d8633ec14b39dfbeb859c821d7f2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 28 Apr 2021 09:38:56 +0200 Subject: [PATCH 003/394] media: s5p_cec: decrement usage count if disabled There's a bug at s5p_cec_adap_enable(): if called to disable the device, it should call pm_runtime_put() instead of pm_runtime_disable(), as the goal here is to decrement the usage_count and not to disable PM runtime. Reported-by: Sylwester Nawrocki Reviewed-by: Jonathan Cameron Fixes: 1bcbf6f4b6b0 ("[media] cec: s5p-cec: Add s5p-cec driver") Signed-off-by: Mauro Carvalho Chehab --- drivers/media/cec/platform/s5p/s5p_cec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/cec/platform/s5p/s5p_cec.c b/drivers/media/cec/platform/s5p/s5p_cec.c index 2a3e7ffefe0a..3c7c4c3c798c 100644 --- a/drivers/media/cec/platform/s5p/s5p_cec.c +++ b/drivers/media/cec/platform/s5p/s5p_cec.c @@ -51,7 +51,7 @@ static int s5p_cec_adap_enable(struct cec_adapter *adap, bool enable) } else { s5p_cec_mask_tx_interrupts(cec); s5p_cec_mask_rx_interrupts(cec); - pm_runtime_disable(cec->dev); + pm_runtime_put(cec->dev); } return 0; From 6005a8e955e4e451e4bf6000affaab566d4cab5e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 27 Apr 2021 08:36:00 +0200 Subject: [PATCH 004/394] media: i2c: ccs-core: return the right error code at suspend If pm_runtime resume logic fails, return the error code provided by it, instead of -EAGAIN, as, depending on what caused it to fail, it may not be something that would be recovered. Fixes: cbba45d43631 ("[media] smiapp: Use runtime PM") Reviewed-by: Jonathan Cameron Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ccs/ccs-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index 9dc3f45da3dc..b05f409014b2 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -3093,7 +3093,7 @@ static int __maybe_unused ccs_suspend(struct device *dev) if (rval < 0) { pm_runtime_put_noidle(dev); - return -EAGAIN; + return rval; } if (sensor->streaming) From da3a1858c3a37c09446e1470c48352897d59d11b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:11 +0200 Subject: [PATCH 005/394] media: i2c: ccs-core: fix pm_runtime_get_sync() usage count The pm_runtime_get_sync() internally increments the dev->power.usage_count without decrementing it, even on errors. There is a bug at ccs_pm_get_init(): when this function returns an error, the stream is not started, and RPM usage_count should not be incremented. However, if the calls to v4l2_ctrl_handler_setup() return errors, it will be kept incremented. At ccs_suspend() the best is to replace it by the new pm_runtime_resume_and_get(), introduced by: commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") in order to properly decrement the usage counter automatically, in the case of errors. Fixes: 96e3a6b92f23 ("media: smiapp: Avoid maintaining power state information") Cc: stable@vger.kernel.org Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ccs/ccs-core.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index b05f409014b2..4a848ac2d2cd 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -1880,21 +1880,33 @@ static int ccs_pm_get_init(struct ccs_sensor *sensor) struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); int rval; + /* + * It can't use pm_runtime_resume_and_get() here, as the driver + * relies at the returned value to detect if the device was already + * active or not. + */ rval = pm_runtime_get_sync(&client->dev); - if (rval < 0) { - pm_runtime_put_noidle(&client->dev); + if (rval < 0) + goto error; - return rval; - } else if (!rval) { - rval = v4l2_ctrl_handler_setup(&sensor->pixel_array-> - ctrl_handler); - if (rval) - return rval; + /* Device was already active, so don't set controls */ + if (rval == 1) + return 0; - return v4l2_ctrl_handler_setup(&sensor->src->ctrl_handler); - } + /* Restore V4L2 controls to the previously suspended device */ + rval = v4l2_ctrl_handler_setup(&sensor->pixel_array->ctrl_handler); + if (rval) + goto error; + rval = v4l2_ctrl_handler_setup(&sensor->src->ctrl_handler); + if (rval) + goto error; + + /* Keep PM runtime usage_count incremented on success */ return 0; +error: + pm_runtime_put(&client->dev); + return rval; } static int ccs_set_stream(struct v4l2_subdev *subdev, int enable) From 62c90446868b439929cb04395f04a709a64ae04b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:13 +0200 Subject: [PATCH 006/394] media: i2c: imx334: fix the pm runtime get logic The PM runtime get logic is currently broken, as it checks if ret is zero instead of checking if it is an error code, as reported by Dan Carpenter. While here, use the pm_runtime_resume_and_get() as added by: commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. As a bonus, such function always return zero on success. It should also be noticed that a fail of pm_runtime_get_sync() would potentially result in a spurious runtime_suspend(), instead of using pm_runtime_put_noidle(). Reported-by: Dan Carpenter Reviewed-by: Daniele Alessandrelli Reviewed-by: Jonathan Cameron Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/imx334.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/media/i2c/imx334.c b/drivers/media/i2c/imx334.c index 047aa7658d21..23f28606e570 100644 --- a/drivers/media/i2c/imx334.c +++ b/drivers/media/i2c/imx334.c @@ -717,9 +717,9 @@ static int imx334_set_stream(struct v4l2_subdev *sd, int enable) } if (enable) { - ret = pm_runtime_get_sync(imx334->dev); - if (ret) - goto error_power_off; + ret = pm_runtime_resume_and_get(imx334->dev); + if (ret < 0) + goto error_unlock; ret = imx334_start_streaming(imx334); if (ret) @@ -737,6 +737,7 @@ static int imx334_set_stream(struct v4l2_subdev *sd, int enable) error_power_off: pm_runtime_put(imx334->dev); +error_unlock: mutex_unlock(&imx334->mutex); return ret; From e6695c89b3d4595f60c9fe40e0938e085d15dd20 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 27 Apr 2021 11:43:54 +0200 Subject: [PATCH 007/394] media: exynos-gsc: don't resume at remove time Calling pm_runtime_get_sync() at driver's removal time is not needed, as this will resume PM runtime. Also, the PM runtime code at pm_runtime_disable() already calls it, if it detects the need. So, change the logic in order to disable PM runtime earlier. Reviewed-by: Jonathan Cameron Reviewed-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos-gsc/gsc-core.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c index 9f41c2e7097a..f49f3322f835 100644 --- a/drivers/media/platform/exynos-gsc/gsc-core.c +++ b/drivers/media/platform/exynos-gsc/gsc-core.c @@ -1210,18 +1210,19 @@ static int gsc_remove(struct platform_device *pdev) struct gsc_dev *gsc = platform_get_drvdata(pdev); int i; - pm_runtime_get_sync(&pdev->dev); - gsc_unregister_m2m_device(gsc); v4l2_device_unregister(&gsc->v4l2_dev); vb2_dma_contig_clear_max_seg_size(&pdev->dev); - for (i = 0; i < gsc->num_clocks; i++) - clk_disable_unprepare(gsc->clock[i]); - pm_runtime_put_noidle(&pdev->dev); pm_runtime_disable(&pdev->dev); + if (!pm_runtime_status_suspended(&pdev->dev)) + for (i = 0; i < gsc->num_clocks; i++) + clk_disable_unprepare(gsc->clock[i]); + + pm_runtime_set_suspended(&pdev->dev); + dev_dbg(&pdev->dev, "%s driver unloaded\n", pdev->name); return 0; } From dd97908ee35096356fb4111bb77d5f94bcfe337d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 16:47:42 +0200 Subject: [PATCH 008/394] media: atmel: properly get pm_runtime There are several issues in the way the atmel driver handles pm_runtime_get_sync(): - it doesn't check return codes; - it doesn't properly decrement the usage_count on all places; - it starts streaming even if pm_runtime_get_sync() fails. - while it tries to get pm_runtime at the clock enable logic, it doesn't check if the operation was suceeded. Replace all occurrences of it to use the new kAPI: pm_runtime_resume_and_get(), which ensures that, if the return code is not negative, the usage_count was incremented. With that, add additional checks when this is called, in order to ensure that errors will be properly addressed. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/atmel/atmel-isc-base.c | 30 ++++++++++++++----- drivers/media/platform/atmel/atmel-isi.c | 19 +++++++++--- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index fe3ec8d0eaee..ce8e1351fa53 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -294,9 +294,13 @@ static int isc_wait_clk_stable(struct clk_hw *hw) static int isc_clk_prepare(struct clk_hw *hw) { struct isc_clk *isc_clk = to_isc_clk(hw); + int ret; - if (isc_clk->id == ISC_ISPCK) - pm_runtime_get_sync(isc_clk->dev); + if (isc_clk->id == ISC_ISPCK) { + ret = pm_runtime_resume_and_get(isc_clk->dev); + if (ret < 0) + return ret; + } return isc_wait_clk_stable(hw); } @@ -353,9 +357,13 @@ static int isc_clk_is_enabled(struct clk_hw *hw) { struct isc_clk *isc_clk = to_isc_clk(hw); u32 status; + int ret; - if (isc_clk->id == ISC_ISPCK) - pm_runtime_get_sync(isc_clk->dev); + if (isc_clk->id == ISC_ISPCK) { + ret = pm_runtime_resume_and_get(isc_clk->dev); + if (ret < 0) + return 0; + } regmap_read(isc_clk->regmap, ISC_CLKSR, &status); @@ -807,7 +815,12 @@ static int isc_start_streaming(struct vb2_queue *vq, unsigned int count) goto err_start_stream; } - pm_runtime_get_sync(isc->dev); + ret = pm_runtime_resume_and_get(isc->dev); + if (ret < 0) { + v4l2_err(&isc->v4l2_dev, "RPM resume failed in subdev %d\n", + ret); + goto err_pm_get; + } ret = isc_configure(isc); if (unlikely(ret)) @@ -838,7 +851,7 @@ static int isc_start_streaming(struct vb2_queue *vq, unsigned int count) err_configure: pm_runtime_put_sync(isc->dev); - +err_pm_get: v4l2_subdev_call(isc->current_subdev->sd, video, s_stream, 0); err_start_stream: @@ -1809,6 +1822,7 @@ static void isc_awb_work(struct work_struct *w) u32 baysel; unsigned long flags; u32 min, max; + int ret; /* streaming is not active anymore */ if (isc->stop) @@ -1831,7 +1845,9 @@ static void isc_awb_work(struct work_struct *w) ctrls->hist_id = hist_id; baysel = isc->config.sd_format->cfa_baycfg << ISC_HIS_CFG_BAYSEL_SHIFT; - pm_runtime_get_sync(isc->dev); + ret = pm_runtime_resume_and_get(isc->dev); + if (ret < 0) + return; /* * only update if we have all the required histograms and controls diff --git a/drivers/media/platform/atmel/atmel-isi.c b/drivers/media/platform/atmel/atmel-isi.c index e392b3efe363..5b1dd358f2e6 100644 --- a/drivers/media/platform/atmel/atmel-isi.c +++ b/drivers/media/platform/atmel/atmel-isi.c @@ -422,7 +422,9 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) struct frame_buffer *buf, *node; int ret; - pm_runtime_get_sync(isi->dev); + ret = pm_runtime_resume_and_get(isi->dev); + if (ret < 0) + return ret; /* Enable stream on the sub device */ ret = v4l2_subdev_call(isi->entity.subdev, video, s_stream, 1); @@ -782,9 +784,10 @@ static int isi_enum_frameintervals(struct file *file, void *fh, return 0; } -static void isi_camera_set_bus_param(struct atmel_isi *isi) +static int isi_camera_set_bus_param(struct atmel_isi *isi) { u32 cfg1 = 0; + int ret; /* set bus param for ISI */ if (isi->pdata.hsync_act_low) @@ -801,12 +804,16 @@ static void isi_camera_set_bus_param(struct atmel_isi *isi) cfg1 |= ISI_CFG1_THMASK_BEATS_16; /* Enable PM and peripheral clock before operate isi registers */ - pm_runtime_get_sync(isi->dev); + ret = pm_runtime_resume_and_get(isi->dev); + if (ret < 0) + return ret; isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); isi_writel(isi, ISI_CFG1, cfg1); pm_runtime_put(isi->dev); + + return 0; } /* -----------------------------------------------------------------------*/ @@ -1085,7 +1092,11 @@ static int isi_graph_notify_complete(struct v4l2_async_notifier *notifier) dev_err(isi->dev, "No supported mediabus format found\n"); return ret; } - isi_camera_set_bus_param(isi); + ret = isi_camera_set_bus_param(isi); + if (ret) { + dev_err(isi->dev, "Can't wake up device\n"); + return ret; + } ret = isi_set_default_fmt(isi); if (ret) { From 892bb6ecead9b834ba7ad1d07513e9eba1baa3a4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 28 Apr 2021 08:27:55 +0200 Subject: [PATCH 009/394] media: hantro: do a PM resume earlier The device_run() first enables the clock and then tries to resume PM runtime, checking for errors. Well, if for some reason the pm_runtime can not resume, it would be better to detect it beforehand. So, change the order inside device_run(). Reviewed-by: Ezequiel Garcia Fixes: 775fec69008d ("media: add Rockchip VPU JPEG encoder driver") Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/hantro/hantro_drv.c | 33 +++++++++++++++-------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c index 595e82a82728..eea2009fa17b 100644 --- a/drivers/staging/media/hantro/hantro_drv.c +++ b/drivers/staging/media/hantro/hantro_drv.c @@ -56,16 +56,12 @@ dma_addr_t hantro_get_ref(struct hantro_ctx *ctx, u64 ts) return hantro_get_dec_buf_addr(ctx, buf); } -static void hantro_job_finish(struct hantro_dev *vpu, - struct hantro_ctx *ctx, - enum vb2_buffer_state result) +static void hantro_job_finish_no_pm(struct hantro_dev *vpu, + struct hantro_ctx *ctx, + enum vb2_buffer_state result) { struct vb2_v4l2_buffer *src, *dst; - pm_runtime_mark_last_busy(vpu->dev); - pm_runtime_put_autosuspend(vpu->dev); - clk_bulk_disable(vpu->variant->num_clocks, vpu->clocks); - src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); @@ -81,6 +77,18 @@ static void hantro_job_finish(struct hantro_dev *vpu, result); } +static void hantro_job_finish(struct hantro_dev *vpu, + struct hantro_ctx *ctx, + enum vb2_buffer_state result) +{ + pm_runtime_mark_last_busy(vpu->dev); + pm_runtime_put_autosuspend(vpu->dev); + + clk_bulk_disable(vpu->variant->num_clocks, vpu->clocks); + + hantro_job_finish_no_pm(vpu, ctx, result); +} + void hantro_irq_done(struct hantro_dev *vpu, enum vb2_buffer_state result) { @@ -152,12 +160,15 @@ static void device_run(void *priv) src = hantro_get_src_buf(ctx); dst = hantro_get_dst_buf(ctx); + ret = pm_runtime_get_sync(ctx->dev->dev); + if (ret < 0) { + pm_runtime_put_noidle(ctx->dev->dev); + goto err_cancel_job; + } + ret = clk_bulk_enable(ctx->dev->variant->num_clocks, ctx->dev->clocks); if (ret) goto err_cancel_job; - ret = pm_runtime_get_sync(ctx->dev->dev); - if (ret < 0) - goto err_cancel_job; v4l2_m2m_buf_copy_metadata(src, dst, true); @@ -165,7 +176,7 @@ static void device_run(void *priv) return; err_cancel_job: - hantro_job_finish(ctx->dev, ctx, VB2_BUF_STATE_ERROR); + hantro_job_finish_no_pm(ctx->dev, ctx, VB2_BUF_STATE_ERROR); } static struct v4l2_m2m_ops vpu_m2m_ops = { From e7c617cab7a522fba5b20f9033ee98565b6f3546 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 16:54:25 +0200 Subject: [PATCH 010/394] media: marvel-ccic: fix some issues when getting pm_runtime Calling pm_runtime_get_sync() is bad, since even when it returns an error, pm_runtime_put*() should be called. So, use instead pm_runtime_resume_and_get(). While here, ensure that the error condition will be checked during clock enable an media open() calls. Reviewed-by: Jonathan Cameron Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/marvell-ccic/mcam-core.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index 141bf5d97a04..ea87110d9073 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c @@ -918,6 +918,7 @@ static int mclk_enable(struct clk_hw *hw) struct mcam_camera *cam = container_of(hw, struct mcam_camera, mclk_hw); int mclk_src; int mclk_div; + int ret; /* * Clock the sensor appropriately. Controller clock should @@ -931,7 +932,9 @@ static int mclk_enable(struct clk_hw *hw) mclk_div = 2; } - pm_runtime_get_sync(cam->dev); + ret = pm_runtime_resume_and_get(cam->dev); + if (ret < 0) + return ret; clk_enable(cam->clk[0]); mcam_reg_write(cam, REG_CLKCTRL, (mclk_src << 29) | mclk_div); mcam_ctlr_power_up(cam); @@ -1611,7 +1614,9 @@ static int mcam_v4l_open(struct file *filp) ret = sensor_call(cam, core, s_power, 1); if (ret) goto out; - pm_runtime_get_sync(cam->dev); + ret = pm_runtime_resume_and_get(cam->dev); + if (ret < 0) + goto out; __mcam_cam_reset(cam); mcam_set_config_needed(cam, 1); } From d07bb9702cf5f5ccf3fb661e6cab54bbc33cd23f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 16:57:16 +0200 Subject: [PATCH 011/394] media: mdk-mdp: fix pm_runtime_get_sync() usage count The pm_runtime_get_sync() internally increments the dev->power.usage_count without decrementing it, even on errors. Replace it by the new pm_runtime_resume_and_get(), introduced by: commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") in order to properly decrement the usage counter, avoiding a potential PM usage counter leak. While here, fix the return contition of mtk_mdp_m2m_start_streaming(), as it doesn't make any sense to return 0 if the PM runtime failed to resume. Reviewed-by: Jonathan Cameron Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c index ace4528cdc5e..f14779e7596e 100644 --- a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c @@ -391,12 +391,12 @@ static int mtk_mdp_m2m_start_streaming(struct vb2_queue *q, unsigned int count) struct mtk_mdp_ctx *ctx = q->drv_priv; int ret; - ret = pm_runtime_get_sync(&ctx->mdp_dev->pdev->dev); + ret = pm_runtime_resume_and_get(&ctx->mdp_dev->pdev->dev); if (ret < 0) - mtk_mdp_dbg(1, "[%d] pm_runtime_get_sync failed:%d", + mtk_mdp_dbg(1, "[%d] pm_runtime_resume_and_get failed:%d", ctx->id, ret); - return 0; + return ret; } static void *mtk_mdp_m2m_buf_remove(struct mtk_mdp_ctx *ctx, From fa9f443f7c962d072d150472e2bb77de39817a9a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 16:59:34 +0200 Subject: [PATCH 012/394] media: rcar_fdp1: simplify error check logic at fdp_open() Avoid some code duplication by moving the common error path logic at fdp_open(). Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/rcar_fdp1.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/media/platform/rcar_fdp1.c b/drivers/media/platform/rcar_fdp1.c index 01c1fbb97bf6..d26413fa5205 100644 --- a/drivers/media/platform/rcar_fdp1.c +++ b/drivers/media/platform/rcar_fdp1.c @@ -2117,9 +2117,7 @@ static int fdp1_open(struct file *file) if (ctx->hdl.error) { ret = ctx->hdl.error; - v4l2_ctrl_handler_free(&ctx->hdl); - kfree(ctx); - goto done; + goto error_ctx; } ctx->fh.ctrl_handler = &ctx->hdl; @@ -2133,10 +2131,7 @@ static int fdp1_open(struct file *file) if (IS_ERR(ctx->fh.m2m_ctx)) { ret = PTR_ERR(ctx->fh.m2m_ctx); - - v4l2_ctrl_handler_free(&ctx->hdl); - kfree(ctx); - goto done; + goto error_ctx; } /* Perform any power management required */ @@ -2147,6 +2142,12 @@ static int fdp1_open(struct file *file) dprintk(fdp1, "Created instance: %p, m2m_ctx: %p\n", ctx, ctx->fh.m2m_ctx); + mutex_unlock(&fdp1->dev_mutex); + return 0; + +error_ctx: + v4l2_ctrl_handler_free(&ctx->hdl); + kfree(ctx); done: mutex_unlock(&fdp1->dev_mutex); return ret; From 45e75a8c6fa455a5909ac04db76a4b15d6bb8368 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 16:59:34 +0200 Subject: [PATCH 013/394] media: rcar_fdp1: fix pm_runtime_get_sync() usage count The pm_runtime_get_sync() internally increments the dev->power.usage_count without decrementing it, even on errors. Replace it by the new pm_runtime_resume_and_get(), introduced by: commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") in order to properly decrement the usage counter, avoiding a potential PM usage counter leak. Also, right now, the driver is ignoring any troubles when trying to do PM resume. So, add the proper error handling for the code. Reviewed-by: Jonathan Cameron Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/rcar_fdp1.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/rcar_fdp1.c b/drivers/media/platform/rcar_fdp1.c index d26413fa5205..89aac60066d9 100644 --- a/drivers/media/platform/rcar_fdp1.c +++ b/drivers/media/platform/rcar_fdp1.c @@ -2135,7 +2135,9 @@ static int fdp1_open(struct file *file) } /* Perform any power management required */ - pm_runtime_get_sync(fdp1->dev); + ret = pm_runtime_resume_and_get(fdp1->dev); + if (ret < 0) + goto error_pm; v4l2_fh_add(&ctx->fh); @@ -2145,6 +2147,8 @@ static int fdp1_open(struct file *file) mutex_unlock(&fdp1->dev_mutex); return 0; +error_pm: + v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); error_ctx: v4l2_ctrl_handler_free(&ctx->hdl); kfree(ctx); @@ -2352,7 +2356,9 @@ static int fdp1_probe(struct platform_device *pdev) /* Power up the cells to read HW */ pm_runtime_enable(&pdev->dev); - pm_runtime_get_sync(fdp1->dev); + ret = pm_runtime_resume_and_get(fdp1->dev); + if (ret < 0) + goto disable_pm; hw_version = fdp1_read(fdp1, FD1_IP_INTDATA); switch (hw_version) { @@ -2381,6 +2387,9 @@ static int fdp1_probe(struct platform_device *pdev) return 0; +disable_pm: + pm_runtime_disable(fdp1->dev); + release_m2m: v4l2_m2m_release(fdp1->m2m_dev); From 220955ec3c84505ec6a75bea494ec61f5295ef7a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:03:23 +0200 Subject: [PATCH 014/394] media: renesas-ceu: Properly check for PM errors Right now, the driver just assumes that PM runtime resume worked, but it may fail. Well, the pm_runtime_get_sync() internally increments the dev->power.usage_count without decrementing it, even on errors. So, using it is tricky. Let's replace it by the new pm_runtime_resume_and_get(), introduced by: commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") and return an error if something bad happens. This should ensure that the PM runtime usage_count will be properly decremented if an error happens at open time. Reviewed-by: Jonathan Cameron Acked-by: Jacopo Mondi Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/renesas-ceu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/renesas-ceu.c b/drivers/media/platform/renesas-ceu.c index cd137101d41e..17f01b6e3fe0 100644 --- a/drivers/media/platform/renesas-ceu.c +++ b/drivers/media/platform/renesas-ceu.c @@ -1099,10 +1099,10 @@ static int ceu_open(struct file *file) mutex_lock(&ceudev->mlock); /* Causes soft-reset and sensor power on on first open */ - pm_runtime_get_sync(ceudev->dev); + ret = pm_runtime_resume_and_get(ceudev->dev); mutex_unlock(&ceudev->mlock); - return 0; + return ret; } static int ceu_release(struct file *file) From fdc34e82c0f968ac4c157bd3d8c299ebc24c9c63 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:04:23 +0200 Subject: [PATCH 015/394] media: s5p: fix pm_runtime_get_sync() usage count The pm_runtime_get_sync() internally increments the dev->power.usage_count without decrementing it, even on errors. Replace it by the new pm_runtime_resume_and_get(), introduced by: commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") in order to properly decrement the usage counter, avoiding a potential PM usage counter leak. While here, check if the PM runtime error was caught at s5p_cec_adap_enable(). Reviewed-by: Jonathan Cameron Reviewed-by: Sylwester Nawrocki Acked-by: Marek Szyprowski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/cec/platform/s5p/s5p_cec.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/media/cec/platform/s5p/s5p_cec.c b/drivers/media/cec/platform/s5p/s5p_cec.c index 3c7c4c3c798c..028a09a7531e 100644 --- a/drivers/media/cec/platform/s5p/s5p_cec.c +++ b/drivers/media/cec/platform/s5p/s5p_cec.c @@ -35,10 +35,13 @@ MODULE_PARM_DESC(debug, "debug level (0-2)"); static int s5p_cec_adap_enable(struct cec_adapter *adap, bool enable) { + int ret; struct s5p_cec_dev *cec = cec_get_drvdata(adap); if (enable) { - pm_runtime_get_sync(cec->dev); + ret = pm_runtime_resume_and_get(cec->dev); + if (ret < 0) + return ret; s5p_cec_reset(cec); From c41e02493334985cca1a22efd5ca962ce3abb061 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:05:27 +0200 Subject: [PATCH 016/394] media: am437x: fix pm_runtime_get_sync() usage count The pm_runtime_get_sync() internally increments the dev->power.usage_count without decrementing it, even on errors. Replace it by the new pm_runtime_resume_and_get(), introduced by: commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") in order to properly decrement the usage counter, avoiding a potential PM usage counter leak. While here, ensure that the driver will check if PM runtime resumed at vpfe_initialize_device(). Reviewed-by: Jonathan Cameron Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/am437x/am437x-vpfe.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c index 6cdc77dda0e4..1c9cb9e05fdf 100644 --- a/drivers/media/platform/am437x/am437x-vpfe.c +++ b/drivers/media/platform/am437x/am437x-vpfe.c @@ -1021,7 +1021,9 @@ static int vpfe_initialize_device(struct vpfe_device *vpfe) if (ret) return ret; - pm_runtime_get_sync(vpfe->pdev); + ret = pm_runtime_resume_and_get(vpfe->pdev); + if (ret < 0) + return ret; vpfe_config_enable(&vpfe->ccdc, 1); @@ -2443,7 +2445,11 @@ static int vpfe_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); /* for now just enable it here instead of waiting for the open */ - pm_runtime_get_sync(&pdev->dev); + ret = pm_runtime_resume_and_get(&pdev->dev); + if (ret < 0) { + vpfe_err(vpfe, "Unable to resume device.\n"); + goto probe_out_v4l2_unregister; + } vpfe_ccdc_config_defaults(ccdc); @@ -2530,6 +2536,11 @@ static int vpfe_suspend(struct device *dev) /* only do full suspend if streaming has started */ if (vb2_start_streaming_called(&vpfe->buffer_queue)) { + /* + * ignore RPM resume errors here, as it is already too late. + * A check like that should happen earlier, either at + * open() or just before start streaming. + */ pm_runtime_get_sync(dev); vpfe_config_enable(ccdc, 1); From 6e8b1526db164c9d4b9dacfb9bc48e365d7c4860 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:07:41 +0200 Subject: [PATCH 017/394] media: sh_vou: fix pm_runtime_get_sync() usage count The pm_runtime_get_sync() internally increments the dev->power.usage_count without decrementing it, even on errors. Replace it by the new pm_runtime_resume_and_get(), introduced by: commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") in order to properly decrement the usage counter, avoiding a potential PM usage counter leak. While here, check if the PM runtime error was caught at open time. Reviewed-by: Jonathan Cameron Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/sh_vou.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c index 4ac48441f22c..ca4310e26c49 100644 --- a/drivers/media/platform/sh_vou.c +++ b/drivers/media/platform/sh_vou.c @@ -1133,7 +1133,11 @@ static int sh_vou_open(struct file *file) if (v4l2_fh_is_singular_file(file) && vou_dev->status == SH_VOU_INITIALISING) { /* First open */ - pm_runtime_get_sync(vou_dev->v4l2_dev.dev); + err = pm_runtime_resume_and_get(vou_dev->v4l2_dev.dev); + if (err < 0) { + v4l2_fh_release(file); + goto done_open; + } err = sh_vou_hw_init(vou_dev); if (err < 0) { pm_runtime_put(vou_dev->v4l2_dev.dev); From 908711f542c17fe61e5d653da1beb8e5ab5c7b50 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:09 +0200 Subject: [PATCH 018/394] media: mtk-vcodec: fix PM runtime get logic Currently, the driver just assumes that PM runtime logic succeded resuming the device. That may not be the case, as pm_runtime_get_sync() can fail (but keeping the usage count incremented). Replace the code to use pm_runtime_resume_and_get(), and letting it return the error code. This way, if mtk_vcodec_dec_pw_on() fails, the logic under fops_vcodec_open() will do the right thing and return an error, instead of just assuming that the device is ready to be used. Reviewed-by: Jonathan Cameron Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 4 +++- drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c | 8 +++++--- drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c index 147dfef1638d..f87dc47d9e63 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c @@ -126,7 +126,9 @@ static int fops_vcodec_open(struct file *file) mtk_vcodec_dec_set_default_params(ctx); if (v4l2_fh_is_singular(&ctx->fh)) { - mtk_vcodec_dec_pw_on(&dev->pm); + ret = mtk_vcodec_dec_pw_on(&dev->pm); + if (ret < 0) + goto err_load_fw; /* * Does nothing if firmware was already loaded. */ diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c index ddee7046ce42..6038db96f71c 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c @@ -88,13 +88,15 @@ void mtk_vcodec_release_dec_pm(struct mtk_vcodec_dev *dev) put_device(dev->pm.larbvdec); } -void mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm) +int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm) { int ret; - ret = pm_runtime_get_sync(pm->dev); + ret = pm_runtime_resume_and_get(pm->dev); if (ret) - mtk_v4l2_err("pm_runtime_get_sync fail %d", ret); + mtk_v4l2_err("pm_runtime_resume_and_get fail %d", ret); + + return ret; } void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h index 872d8bf8cfaf..280aeaefdb65 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h @@ -12,7 +12,7 @@ int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *dev); void mtk_vcodec_release_dec_pm(struct mtk_vcodec_dev *dev); -void mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm); +int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm); void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm); void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm); void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm); From 10343de268d10cf07b092b8b525e12ad558ead77 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:10 +0200 Subject: [PATCH 019/394] media: s5p-jpeg: fix pm_runtime_get_sync() usage count The pm_runtime_get_sync() internally increments the dev->power.usage_count without decrementing it, even on errors. Replace it by the new pm_runtime_resume_and_get(), introduced by: commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") in order to properly decrement the usage counter, avoiding a potential PM usage counter leak. As a plus, pm_runtime_resume_and_get() doesn't return positive numbers, so the return code validation can be removed. Reviewed-by: Jonathan Cameron Reviewed-by: Sylwester Nawrocki Acked-by: Andrzej Pietrasiewicz Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-jpeg/jpeg-core.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index 026111505f5a..d402e456f27d 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c @@ -2566,11 +2566,8 @@ static void s5p_jpeg_buf_queue(struct vb2_buffer *vb) static int s5p_jpeg_start_streaming(struct vb2_queue *q, unsigned int count) { struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q); - int ret; - ret = pm_runtime_get_sync(ctx->jpeg->dev); - - return ret > 0 ? 0 : ret; + return pm_runtime_resume_and_get(ctx->jpeg->dev); } static void s5p_jpeg_stop_streaming(struct vb2_queue *q) From baa450f08d691a40fcc29ba8ce40e02613736ac7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:10 +0200 Subject: [PATCH 020/394] media: sti/delta: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Reviewed-by: Jonathan Cameron Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/sti/delta/delta-v4l2.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/media/platform/sti/delta/delta-v4l2.c b/drivers/media/platform/sti/delta/delta-v4l2.c index c691b3d81549..064a00a3084a 100644 --- a/drivers/media/platform/sti/delta/delta-v4l2.c +++ b/drivers/media/platform/sti/delta/delta-v4l2.c @@ -954,10 +954,8 @@ static void delta_run_work(struct work_struct *work) /* enable the hardware */ if (!dec->pm) { ret = delta_get_sync(ctx); - if (ret) { - delta_put_autosuspend(ctx); + if (ret) goto err; - } } /* decode this access unit */ @@ -1277,9 +1275,9 @@ int delta_get_sync(struct delta_ctx *ctx) int ret = 0; /* enable the hardware */ - ret = pm_runtime_get_sync(delta->dev); + ret = pm_runtime_resume_and_get(delta->dev); if (ret < 0) { - dev_err(delta->dev, "%s pm_runtime_get_sync failed (%d)\n", + dev_err(delta->dev, "%s pm_runtime_resume_and_get failed (%d)\n", __func__, ret); return ret; } From 9c298f82d8392f799a0595f50076afa1d91e9092 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:10 +0200 Subject: [PATCH 021/394] media: sunxi: fix pm_runtime_get_sync() usage count The pm_runtime_get_sync() internally increments the dev->power.usage_count without decrementing it, even on errors. Replace it by the new pm_runtime_resume_and_get(), introduced by: commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") in order to properly decrement the usage counter, avoiding a potential PM usage counter leak. Reviewed-by: Jonathan Cameron Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c b/drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c index 3f81dd17755c..fbcca59a0517 100644 --- a/drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c +++ b/drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c @@ -494,7 +494,7 @@ static int rotate_start_streaming(struct vb2_queue *vq, unsigned int count) struct device *dev = ctx->dev->dev; int ret; - ret = pm_runtime_get_sync(dev); + ret = pm_runtime_resume_and_get(dev); if (ret < 0) { dev_err(dev, "Failed to enable module\n"); From c44eac5b72e23c31eefc0e10a71d9650036b8341 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:21 +0200 Subject: [PATCH 022/394] media: sti/bdisp: fix pm_runtime_get_sync() usage count The pm_runtime_get_sync() internally increments the dev->power.usage_count without decrementing it, even on errors. The bdisp_start_streaming() doesn't take it into account, which would unbalance PM usage counter at bdisp_stop_streaming(). The logic at bdisp_probe() is correct, but the best is to use the same call along the driver. So, replace it by the new pm_runtime_resume_and_get(), introduced by: commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") in order to properly decrement the usage counter, avoiding a potential PM usage counter leak. Reviewed-by: Jonathan Cameron Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/sti/bdisp/bdisp-v4l2.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c index 060ca85f64d5..85288da9d2ae 100644 --- a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c +++ b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c @@ -499,7 +499,7 @@ static int bdisp_start_streaming(struct vb2_queue *q, unsigned int count) { struct bdisp_ctx *ctx = q->drv_priv; struct vb2_v4l2_buffer *buf; - int ret = pm_runtime_get_sync(ctx->bdisp_dev->dev); + int ret = pm_runtime_resume_and_get(ctx->bdisp_dev->dev); if (ret < 0) { dev_err(ctx->bdisp_dev->dev, "failed to set runtime PM\n"); @@ -1364,10 +1364,10 @@ static int bdisp_probe(struct platform_device *pdev) /* Power management */ pm_runtime_enable(dev); - ret = pm_runtime_get_sync(dev); + ret = pm_runtime_resume_and_get(dev); if (ret < 0) { dev_err(dev, "failed to set PM\n"); - goto err_pm; + goto err_remove; } /* Filters */ @@ -1395,6 +1395,7 @@ err_filter: bdisp_hw_free_filters(bdisp->dev); err_pm: pm_runtime_put(dev); +err_remove: bdisp_debugfs_remove(bdisp); v4l2_device_unregister(&bdisp->v4l2_dev); err_clk: From 59f96244af9403ddf4810ec5c0fbe8920857634e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:17 +0200 Subject: [PATCH 023/394] media: exynos4-is: fix pm_runtime_get_sync() usage count The pm_runtime_get_sync() internally increments the dev->power.usage_count without decrementing it, even on errors. On some places, this is ok, but on others the usage count ended being unbalanced on failures. Replace it by the new pm_runtime_resume_and_get(), introduced by: commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") in order to properly decrement the usage counter, avoiding a potential PM usage counter leak. As a bonus, such function always return zero on success. So, some code can be simplified. Reviewed-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos4-is/fimc-capture.c | 6 ++---- drivers/media/platform/exynos4-is/fimc-is.c | 4 ++-- drivers/media/platform/exynos4-is/fimc-isp-video.c | 3 +-- drivers/media/platform/exynos4-is/fimc-isp.c | 7 +++---- drivers/media/platform/exynos4-is/fimc-lite.c | 5 +++-- drivers/media/platform/exynos4-is/fimc-m2m.c | 5 +---- drivers/media/platform/exynos4-is/media-dev.c | 9 +++------ drivers/media/platform/exynos4-is/mipi-csis.c | 10 ++++------ 8 files changed, 19 insertions(+), 30 deletions(-) diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c index 13c838d3f947..0da36443173c 100644 --- a/drivers/media/platform/exynos4-is/fimc-capture.c +++ b/drivers/media/platform/exynos4-is/fimc-capture.c @@ -478,11 +478,9 @@ static int fimc_capture_open(struct file *file) goto unlock; set_bit(ST_CAPT_BUSY, &fimc->state); - ret = pm_runtime_get_sync(&fimc->pdev->dev); - if (ret < 0) { - pm_runtime_put_sync(&fimc->pdev->dev); + ret = pm_runtime_resume_and_get(&fimc->pdev->dev); + if (ret < 0) goto unlock; - } ret = v4l2_fh_open(file); if (ret) { diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c index 972d9601d236..1b24f5bfc4af 100644 --- a/drivers/media/platform/exynos4-is/fimc-is.c +++ b/drivers/media/platform/exynos4-is/fimc-is.c @@ -828,9 +828,9 @@ static int fimc_is_probe(struct platform_device *pdev) goto err_irq; } - ret = pm_runtime_get_sync(dev); + ret = pm_runtime_resume_and_get(dev); if (ret < 0) - goto err_pm; + goto err_irq; vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32)); diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c index 612b9872afc8..8d9dc597deaa 100644 --- a/drivers/media/platform/exynos4-is/fimc-isp-video.c +++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c @@ -275,7 +275,7 @@ static int isp_video_open(struct file *file) if (ret < 0) goto unlock; - ret = pm_runtime_get_sync(&isp->pdev->dev); + ret = pm_runtime_resume_and_get(&isp->pdev->dev); if (ret < 0) goto rel_fh; @@ -293,7 +293,6 @@ static int isp_video_open(struct file *file) if (!ret) goto unlock; rel_fh: - pm_runtime_put_noidle(&isp->pdev->dev); v4l2_fh_release(file); unlock: mutex_unlock(&isp->video_lock); diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c index a77c49b18511..74b49d30901e 100644 --- a/drivers/media/platform/exynos4-is/fimc-isp.c +++ b/drivers/media/platform/exynos4-is/fimc-isp.c @@ -304,11 +304,10 @@ static int fimc_isp_subdev_s_power(struct v4l2_subdev *sd, int on) pr_debug("on: %d\n", on); if (on) { - ret = pm_runtime_get_sync(&is->pdev->dev); - if (ret < 0) { - pm_runtime_put(&is->pdev->dev); + ret = pm_runtime_resume_and_get(&is->pdev->dev); + if (ret < 0) return ret; - } + set_bit(IS_ST_PWR_ON, &is->state); ret = fimc_is_start_firmware(is); diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c index fe20af3a7178..4d8b18078ff3 100644 --- a/drivers/media/platform/exynos4-is/fimc-lite.c +++ b/drivers/media/platform/exynos4-is/fimc-lite.c @@ -469,9 +469,9 @@ static int fimc_lite_open(struct file *file) } set_bit(ST_FLITE_IN_USE, &fimc->state); - ret = pm_runtime_get_sync(&fimc->pdev->dev); + ret = pm_runtime_resume_and_get(&fimc->pdev->dev); if (ret < 0) - goto err_pm; + goto err_in_use; ret = v4l2_fh_open(file); if (ret < 0) @@ -499,6 +499,7 @@ static int fimc_lite_open(struct file *file) v4l2_fh_release(file); err_pm: pm_runtime_put_sync(&fimc->pdev->dev); +err_in_use: clear_bit(ST_FLITE_IN_USE, &fimc->state); unlock: mutex_unlock(&fimc->lock); diff --git a/drivers/media/platform/exynos4-is/fimc-m2m.c b/drivers/media/platform/exynos4-is/fimc-m2m.c index c9704a147e5c..df8e2aa454d8 100644 --- a/drivers/media/platform/exynos4-is/fimc-m2m.c +++ b/drivers/media/platform/exynos4-is/fimc-m2m.c @@ -73,17 +73,14 @@ static void fimc_m2m_shutdown(struct fimc_ctx *ctx) static int start_streaming(struct vb2_queue *q, unsigned int count) { struct fimc_ctx *ctx = q->drv_priv; - int ret; - ret = pm_runtime_get_sync(&ctx->fimc_dev->pdev->dev); - return ret > 0 ? 0 : ret; + return pm_runtime_resume_and_get(&ctx->fimc_dev->pdev->dev); } static void stop_streaming(struct vb2_queue *q) { struct fimc_ctx *ctx = q->drv_priv; - fimc_m2m_shutdown(ctx); fimc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR); pm_runtime_put(&ctx->fimc_dev->pdev->dev); diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index 13d192ba4aa6..e025178db06c 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c @@ -512,11 +512,9 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd) if (!fmd->pmf) return -ENXIO; - ret = pm_runtime_get_sync(fmd->pmf); - if (ret < 0) { - pm_runtime_put(fmd->pmf); + ret = pm_runtime_resume_and_get(fmd->pmf); + if (ret < 0) return ret; - } fmd->num_sensors = 0; @@ -1291,8 +1289,7 @@ static int cam_clk_prepare(struct clk_hw *hw) if (camclk->fmd->pmf == NULL) return -ENODEV; - ret = pm_runtime_get_sync(camclk->fmd->pmf); - return ret < 0 ? ret : 0; + return pm_runtime_resume_and_get(camclk->fmd->pmf); } static void cam_clk_unprepare(struct clk_hw *hw) diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c index 1aac167abb17..ebf39c856894 100644 --- a/drivers/media/platform/exynos4-is/mipi-csis.c +++ b/drivers/media/platform/exynos4-is/mipi-csis.c @@ -494,7 +494,7 @@ static int s5pcsis_s_power(struct v4l2_subdev *sd, int on) struct device *dev = &state->pdev->dev; if (on) - return pm_runtime_get_sync(dev); + return pm_runtime_resume_and_get(dev); return pm_runtime_put_sync(dev); } @@ -509,11 +509,9 @@ static int s5pcsis_s_stream(struct v4l2_subdev *sd, int enable) if (enable) { s5pcsis_clear_counters(state); - ret = pm_runtime_get_sync(&state->pdev->dev); - if (ret && ret != 1) { - pm_runtime_put_noidle(&state->pdev->dev); + ret = pm_runtime_resume_and_get(&state->pdev->dev); + if (ret < 0) return ret; - } } mutex_lock(&state->lock); @@ -535,7 +533,7 @@ unlock: if (!enable) pm_runtime_put(&state->pdev->dev); - return ret == 1 ? 0 : ret; + return ret; } static int s5pcsis_enum_mbus_code(struct v4l2_subdev *sd, From 59087b66ea6730c130c57d23bd9fd139b78c1ba5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:18 +0200 Subject: [PATCH 024/394] media: exynos-gsc: fix pm_runtime_get_sync() usage count The pm_runtime_get_sync() internally increments the dev->power.usage_count without decrementing it, even on errors. Replace it by the new pm_runtime_resume_and_get(), introduced by: commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") in order to properly decrement the usage counter, avoiding a potential PM usage counter leak. As a bonus, as pm_runtime_get_sync() always return 0 on success, the logic can be simplified. Reviewed-by: Jonathan Cameron Reviewed-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos-gsc/gsc-m2m.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/media/platform/exynos-gsc/gsc-m2m.c b/drivers/media/platform/exynos-gsc/gsc-m2m.c index 27a3c92c73bc..f1cf847d1cc2 100644 --- a/drivers/media/platform/exynos-gsc/gsc-m2m.c +++ b/drivers/media/platform/exynos-gsc/gsc-m2m.c @@ -56,10 +56,8 @@ static void __gsc_m2m_job_abort(struct gsc_ctx *ctx) static int gsc_m2m_start_streaming(struct vb2_queue *q, unsigned int count) { struct gsc_ctx *ctx = q->drv_priv; - int ret; - ret = pm_runtime_get_sync(&ctx->gsc_dev->pdev->dev); - return ret > 0 ? 0 : ret; + return pm_runtime_resume_and_get(&ctx->gsc_dev->pdev->dev); } static void __gsc_m2m_cleanup_queue(struct gsc_ctx *ctx) From 9148cded3a0246d55e62187e219466c0c7986925 Mon Sep 17 00:00:00 2001 From: Aline Santana Cordeiro Date: Fri, 9 Apr 2021 14:24:21 +0200 Subject: [PATCH 025/394] media: staging: media: hantro: Align line break to the open parenthesis in file hantro_hw.h Aligns line break with the remaining function arguments to the open parenthesis. Issue found by checkpatch. Signed-off-by: Aline Santana Cordeiro Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/hantro/hantro_hw.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h index 83b3e42b63a3..0e34ae545f66 100644 --- a/drivers/staging/media/hantro/hantro_hw.h +++ b/drivers/staging/media/hantro/hantro_hw.h @@ -219,7 +219,7 @@ hantro_h264_mv_size(unsigned int width, unsigned int height) void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx); void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx); void hantro_mpeg2_dec_copy_qtable(u8 *qtable, - const struct v4l2_ctrl_mpeg2_quantization *ctrl); + const struct v4l2_ctrl_mpeg2_quantization *ctrl); int hantro_mpeg2_dec_init(struct hantro_ctx *ctx); void hantro_mpeg2_dec_exit(struct hantro_ctx *ctx); From d637c5dbbfee4c0cbd2f507b627e5b29823f49da Mon Sep 17 00:00:00 2001 From: Aline Santana Cordeiro Date: Fri, 9 Apr 2021 14:24:25 +0200 Subject: [PATCH 026/394] media: staging: media: hantro: Align line break to the open parenthesis in file hantro_mpeg2.c Aligns line break with the remaining function arguments to the open parenthesis. Issue found by checkpatch. Signed-off-by: Aline Santana Cordeiro Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/hantro/hantro_mpeg2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/media/hantro/hantro_mpeg2.c b/drivers/staging/media/hantro/hantro_mpeg2.c index 1d334e6fcd06..53a99a9988d5 100644 --- a/drivers/staging/media/hantro/hantro_mpeg2.c +++ b/drivers/staging/media/hantro/hantro_mpeg2.c @@ -19,7 +19,7 @@ static const u8 zigzag[64] = { }; void hantro_mpeg2_dec_copy_qtable(u8 *qtable, - const struct v4l2_ctrl_mpeg2_quantization *ctrl) + const struct v4l2_ctrl_mpeg2_quantization *ctrl) { int i, n; From d58f75de9b958ff9d996da942ccf79d7526bfde8 Mon Sep 17 00:00:00 2001 From: Aline Santana Cordeiro Date: Fri, 9 Apr 2021 21:01:08 +0200 Subject: [PATCH 027/394] media: staging: media: omap4iss: Align line break to the open parenthesis in file iss_video.c Aligns line break with the remaining function arguments to the open parenthesis. Issue found by checkpatch. Signed-off-by: Aline Santana Cordeiro Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/omap4iss/iss_video.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c index 930f638f51eb..d0da083deed5 100644 --- a/drivers/staging/media/omap4iss/iss_video.c +++ b/drivers/staging/media/omap4iss/iss_video.c @@ -399,7 +399,7 @@ static void iss_video_buf_queue(struct vb2_buffer *vb) if (start) omap4iss_pipeline_set_stream(pipe, - ISS_PIPELINE_STREAM_SINGLESHOT); + ISS_PIPELINE_STREAM_SINGLESHOT); } } @@ -960,7 +960,7 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) unsigned long flags; ret = omap4iss_pipeline_set_stream(pipe, - ISS_PIPELINE_STREAM_CONTINUOUS); + ISS_PIPELINE_STREAM_CONTINUOUS); if (ret < 0) goto err_omap4iss_set_stream; spin_lock_irqsave(&video->qlock, flags); From 047d39c4a1bc197ec038008e941fa30d08d1d885 Mon Sep 17 00:00:00 2001 From: Martiros Shakhzadyan Date: Mon, 12 Apr 2021 04:35:56 +0200 Subject: [PATCH 028/394] media: staging: media: atomisp: Removed a superfluous else clause Fixed a coding style issue. Signed-off-by: Martiros Shakhzadyan Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/i2c/atomisp-ov2722.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c index 1209492c1826..912eadaffc44 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c @@ -774,11 +774,11 @@ static int ov2722_s_power(struct v4l2_subdev *sd, int on) if (on == 0) return power_down(sd); - else { - ret = power_up(sd); - if (!ret) - return ov2722_init(sd); - } + + ret = power_up(sd); + if (!ret) + return ov2722_init(sd); + return ret; } From 94dfa800dda45a0849aa493c05800b2a3557a6ee Mon Sep 17 00:00:00 2001 From: Beatriz Martins de Carvalho Date: Mon, 12 Apr 2021 15:43:01 +0200 Subject: [PATCH 029/394] media: staging: media: atomisp: i2c: align line break to match with open parenthesis Aligns line break with the remaining function arguments to the open parenthesis. Issue found by checkpatch in file atomisp-gc2235.c Signed-off-by: Beatriz Martins de Carvalho Acked-by: Sakari Ailus Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/i2c/atomisp-gc2235.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c index 78147ffb6099..6ba4a8adff7c 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c @@ -171,8 +171,8 @@ static int __gc2235_buf_reg_array(struct i2c_client *client, } static int __gc2235_write_reg_is_consecutive(struct i2c_client *client, - struct gc2235_write_ctrl *ctrl, - const struct gc2235_reg *next) + struct gc2235_write_ctrl *ctrl, + const struct gc2235_reg *next) { if (ctrl->index == 0) return 1; From a21baa418c5b6a011f02d18d2214c28d6f3a4a47 Mon Sep 17 00:00:00 2001 From: Mitali Borkar Date: Tue, 13 Apr 2021 07:15:29 +0200 Subject: [PATCH 030/394] media: staging: media: intel-ipu3: remove unnecessary blank line Removed an unnecessary blank line to meet linux kernel coding style. Reported by checkpatch.pl Signed-off-by: Mitali Borkar Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/ipu3/include/intel-ipu3.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/media/ipu3/include/intel-ipu3.h b/drivers/staging/media/ipu3/include/intel-ipu3.h index 9b644fb23dde..3fb7fc547eff 100644 --- a/drivers/staging/media/ipu3/include/intel-ipu3.h +++ b/drivers/staging/media/ipu3/include/intel-ipu3.h @@ -74,7 +74,6 @@ struct ipu3_uapi_grid_config { (IPU3_UAPI_AWB_MAX_SETS * \ (IPU3_UAPI_AWB_SET_SIZE + IPU3_UAPI_AWB_SPARE_FOR_BUBBLES)) - /** * struct ipu3_uapi_awb_raw_buffer - AWB raw buffer * From 25074ea239ac92321e75009e001049886f91d850 Mon Sep 17 00:00:00 2001 From: Mitali Borkar Date: Tue, 13 Apr 2021 07:15:46 +0200 Subject: [PATCH 031/394] media: staging: media: intel-ipu3: reduce length of line Reduced length of line as it was exceeding 100 characters by removing comments from same line and adding it to previous line. This makes code neater, and meets linux kernel coding style. Reported by checkpatch. Signed-off-by: Mitali Borkar Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/ipu3/include/intel-ipu3.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/ipu3/include/intel-ipu3.h b/drivers/staging/media/ipu3/include/intel-ipu3.h index 3fb7fc547eff..ce068b2bea73 100644 --- a/drivers/staging/media/ipu3/include/intel-ipu3.h +++ b/drivers/staging/media/ipu3/include/intel-ipu3.h @@ -9,8 +9,10 @@ /* from /drivers/staging/media/ipu3/include/videodev2.h */ /* Vendor specific - used for IPU3 camera sub-system */ -#define V4L2_META_FMT_IPU3_PARAMS v4l2_fourcc('i', 'p', '3', 'p') /* IPU3 processing parameters */ -#define V4L2_META_FMT_IPU3_STAT_3A v4l2_fourcc('i', 'p', '3', 's') /* IPU3 3A statistics */ +/* IPU3 processing parameters */ +#define V4L2_META_FMT_IPU3_PARAMS v4l2_fourcc('i', 'p', '3', 'p') +/* IPU3 3A statistics */ +#define V4L2_META_FMT_IPU3_STAT_3A v4l2_fourcc('i', 'p', '3', 's') /* from include/uapi/linux/v4l2-controls.h */ #define V4L2_CID_INTEL_IPU3_BASE (V4L2_CID_USER_BASE + 0x10c0) From 17daf473e2a48ca34b434f69c00bd2fd6fa39a4d Mon Sep 17 00:00:00 2001 From: Mitali Borkar Date: Tue, 13 Apr 2021 07:16:22 +0200 Subject: [PATCH 032/394] media: staging: media: intel-ipu3: remove space before tabs Removed unnecessary space before tabs to adhere to linux kernel coding style. Reported by checkpatch. Signed-off-by: Mitali Borkar Acked-by: Sakari Ailus Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/ipu3/include/intel-ipu3.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/media/ipu3/include/intel-ipu3.h b/drivers/staging/media/ipu3/include/intel-ipu3.h index ce068b2bea73..1f4a2fd7c9f5 100644 --- a/drivers/staging/media/ipu3/include/intel-ipu3.h +++ b/drivers/staging/media/ipu3/include/intel-ipu3.h @@ -631,7 +631,7 @@ struct ipu3_uapi_bnr_static_config_wb_gains_thr_config { * @cg: Gain coefficient for threshold calculation, [0, 31], default 8. * @ci: Intensity coefficient for threshold calculation. range [0, 0x1f] * default 6. - * format: u3.2 (3 most significant bits represent whole number, + * format: u3.2 (3 most significant bits represent whole number, * 2 least significant bits represent the fractional part * with each count representing 0.25) * e.g. 6 in binary format is 00110, that translates to 1.5 From 72e03872410842e6c0de27b7243fe90af5254bc0 Mon Sep 17 00:00:00 2001 From: Mitali Borkar Date: Tue, 13 Apr 2021 17:29:17 +0200 Subject: [PATCH 033/394] media: staging: media: intel-ipu3: line should not end with '[' Fixed the issue of line should not end with '[' by moving argument from next line to line ending with '[' and made it under 80 characters. Reported by checkpatch. Signed-off-by: Mitali Borkar Acked-by: Sakari Ailus Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/ipu3/include/intel-ipu3.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/ipu3/include/intel-ipu3.h b/drivers/staging/media/ipu3/include/intel-ipu3.h index 1f4a2fd7c9f5..fa3d6ee5adf2 100644 --- a/drivers/staging/media/ipu3/include/intel-ipu3.h +++ b/drivers/staging/media/ipu3/include/intel-ipu3.h @@ -245,8 +245,8 @@ struct ipu3_uapi_ae_ccm { */ struct ipu3_uapi_ae_config { struct ipu3_uapi_ae_grid_config grid_cfg __attribute__((aligned(32))); - struct ipu3_uapi_ae_weight_elem weights[ - IPU3_UAPI_AE_WEIGHTS] __attribute__((aligned(32))); + struct ipu3_uapi_ae_weight_elem weights[IPU3_UAPI_AE_WEIGHTS] + __attribute__((aligned(32))); struct ipu3_uapi_ae_ccm ae_ccm __attribute__((aligned(32))); } __packed; From 7900bdc25a019159911d5ee38f83b78ac6639589 Mon Sep 17 00:00:00 2001 From: Mitali Borkar Date: Tue, 13 Apr 2021 21:50:16 +0200 Subject: [PATCH 034/394] media: staging: media: zoran: add spaces around '<<' operator Added spaces around '<<' operator to improve readability and meet linux kernel coding style. Reported by checkpatch Signed-off-by: Mitali Borkar Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/zoran/zr36057.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/media/zoran/zr36057.h b/drivers/staging/media/zoran/zr36057.h index 71b651add35a..a2a75fd9f535 100644 --- a/drivers/staging/media/zoran/zr36057.h +++ b/drivers/staging/media/zoran/zr36057.h @@ -30,13 +30,13 @@ #define ZR36057_VFESPFR_HOR_DCM 14 #define ZR36057_VFESPFR_VER_DCM 8 #define ZR36057_VFESPFR_DISP_MODE 6 -#define ZR36057_VFESPFR_YUV422 (0<<3) -#define ZR36057_VFESPFR_RGB888 (1<<3) -#define ZR36057_VFESPFR_RGB565 (2<<3) -#define ZR36057_VFESPFR_RGB555 (3<<3) -#define ZR36057_VFESPFR_ERR_DIF (1<<2) -#define ZR36057_VFESPFR_PACK24 (1<<1) -#define ZR36057_VFESPFR_LITTLE_ENDIAN (1<<0) +#define ZR36057_VFESPFR_YUV422 (0 << 3) +#define ZR36057_VFESPFR_RGB888 (1 << 3) +#define ZR36057_VFESPFR_RGB565 (2 << 3) +#define ZR36057_VFESPFR_RGB555 (3 << 3) +#define ZR36057_VFESPFR_ERR_DIF (1 << 2) +#define ZR36057_VFESPFR_PACK24 (1 << 1) +#define ZR36057_VFESPFR_LITTLE_ENDIAN (1 << 0) #define ZR36057_VDTR 0x00c /* Video Display "Top" Register */ From 451c34dd69b80857fa50e33581db22143afa8890 Mon Sep 17 00:00:00 2001 From: Martiros Shakhzadyan Date: Tue, 13 Apr 2021 20:03:13 +0200 Subject: [PATCH 035/394] media: staging: media: atomisp: Minor code style changes Fixed line continuation and parenthesis alignment issues. Signed-off-by: Martiros Shakhzadyan Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/i2c/atomisp-ov2722.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c index 912eadaffc44..90a985ee25fa 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c @@ -49,8 +49,8 @@ static int ov2722_read_reg(struct i2c_client *client, return -ENODEV; } - if (data_length != OV2722_8BIT && data_length != OV2722_16BIT - && data_length != OV2722_32BIT) { + if (data_length != OV2722_8BIT && data_length != OV2722_16BIT && + data_length != OV2722_32BIT) { dev_err(&client->dev, "%s error, invalid data length\n", __func__); return -EINVAL; @@ -212,8 +212,8 @@ static int __ov2722_buf_reg_array(struct i2c_client *client, } static int __ov2722_write_reg_is_consecutive(struct i2c_client *client, - struct ov2722_write_ctrl *ctrl, - const struct ov2722_reg *next) + struct ov2722_write_ctrl *ctrl, + const struct ov2722_reg *next) { if (ctrl->index == 0) return 1; From d7c89be51d17d629e7c550388a81858af09ad343 Mon Sep 17 00:00:00 2001 From: Aline Santana Cordeiro Date: Wed, 14 Apr 2021 15:25:37 +0200 Subject: [PATCH 036/394] media: staging: media: omap4iss: Remove unused macro function Remove unused macro function "v4l2_dev_to_iss_device(dev)". Signed-off-by: Aline Santana Cordeiro Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/omap4iss/iss.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/media/omap4iss/iss.h b/drivers/staging/media/omap4iss/iss.h index b88f9529683c..3f587e000729 100644 --- a/drivers/staging/media/omap4iss/iss.h +++ b/drivers/staging/media/omap4iss/iss.h @@ -119,9 +119,6 @@ struct iss_device { unsigned int isp_subclk_resources; }; -#define v4l2_dev_to_iss_device(dev) \ - container_of(dev, struct iss_device, v4l2_dev) - int omap4iss_get_external_info(struct iss_pipeline *pipe, struct media_link *link); From bbbcba0267e2faff32c62905219f1d3b81f75d30 Mon Sep 17 00:00:00 2001 From: Aline Santana Cordeiro Date: Wed, 14 Apr 2021 16:06:02 +0200 Subject: [PATCH 037/394] media: staging: media: atomisp: pci: Correct identation in block of conditional statements in file atomisp_v4l2.c Correct identation in block of conditional statements. The function "v4l2_device_unregister_subdev()" depends on the results of the macro function "list_for_each_entry_safe()". Signed-off-by: Aline Santana Cordeiro Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/atomisp_v4l2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c index 0295e2e32d79..6d853f480e1c 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c +++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c @@ -1178,7 +1178,7 @@ static void atomisp_unregister_entities(struct atomisp_device *isp) atomisp_mipi_csi2_unregister_entities(&isp->csi2_port[i]); list_for_each_entry_safe(sd, next, &isp->v4l2_dev.subdevs, list) - v4l2_device_unregister_subdev(sd); + v4l2_device_unregister_subdev(sd); v4l2_device_unregister(&isp->v4l2_dev); media_device_unregister(&isp->media_dev); From 848802da8d0443befd155926ff4184e6ebffb5c0 Mon Sep 17 00:00:00 2001 From: Aline Santana Cordeiro Date: Wed, 14 Apr 2021 16:06:06 +0200 Subject: [PATCH 038/394] media: staging: media: atomisp: pci: Correct identation in block of conditional statements in file atomisp_acc.c Correct identation in block of conditional statements. The conditional statement depends on the results of the macro function "list_for_each_entry()". Signed-off-by: Aline Santana Cordeiro Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/atomisp_acc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/atomisp_acc.c b/drivers/staging/media/atomisp/pci/atomisp_acc.c index f638d0bd09fe..5e5faa4b3445 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_acc.c +++ b/drivers/staging/media/atomisp/pci/atomisp_acc.c @@ -77,8 +77,8 @@ acc_get_fw(struct atomisp_sub_device *asd, unsigned int handle) struct atomisp_acc_fw *acc_fw; list_for_each_entry(acc_fw, &asd->acc.fw, list) - if (acc_fw->handle == handle) - return acc_fw; + if (acc_fw->handle == handle) + return acc_fw; return NULL; } From 14bc5eb80bda1a3e3c8c2a0eab3064eaba949f3a Mon Sep 17 00:00:00 2001 From: Aline Santana Cordeiro Date: Wed, 14 Apr 2021 23:16:45 +0200 Subject: [PATCH 039/394] media: staging: media: atomisp: pci: Format comments according to coding-style in file atomisp_acc.c Format all comments according to the coding-style. Issue detected by checkpatch.pl. Signed-off-by: Aline Santana Cordeiro Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/atomisp_acc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/atomisp_acc.c b/drivers/staging/media/atomisp/pci/atomisp_acc.c index 5e5faa4b3445..9a1751895ab0 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_acc.c +++ b/drivers/staging/media/atomisp/pci/atomisp_acc.c @@ -464,9 +464,11 @@ int atomisp_acc_load_extensions(struct atomisp_sub_device *asd) continue; for (i = 0; i < ARRAY_SIZE(acc_flag_to_pipe); i++) { - /* QoS (ACC pipe) acceleration stages are currently - * allowed only in continuous mode. Skip them for - * all other modes. */ + /* + * QoS (ACC pipe) acceleration stages are + * currently allowed only in continuous mode. + * Skip them for all other modes. + */ if (!continuous && acc_flag_to_pipe[i].flag == ATOMISP_ACC_FW_LOAD_FL_ACC) From 73edc4da40635774100d0eb9ca2e6476e3b2b470 Mon Sep 17 00:00:00 2001 From: Aline Santana Cordeiro Date: Wed, 14 Apr 2021 23:16:48 +0200 Subject: [PATCH 040/394] media: staging: media: atomisp: pci: Format comments according to coding-style in file atomisp_cmd.h Format all comments according to the coding-style. Issue detected by checkpatch.pl. Signed-off-by: Aline Santana Cordeiro Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../staging/media/atomisp/pci/atomisp_cmd.h | 161 +++++------------- 1 file changed, 43 insertions(+), 118 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.h b/drivers/staging/media/atomisp/pci/atomisp_cmd.h index 412baeb91944..e8bdd264d31b 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_cmd.h +++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.h @@ -49,9 +49,7 @@ struct ia_css_frame; /* FIXME: check if can go */ extern int atomisp_punit_hpll_freq; -/* - * Helper function - */ +/* Helper function */ void dump_sp_dmem(struct atomisp_device *isp, unsigned int addr, unsigned int size); struct camera_mipi_info *atomisp_to_sensor_mipi_info(struct v4l2_subdev *sd); @@ -65,9 +63,7 @@ bool atomisp_buffers_queued(struct atomisp_sub_device *asd); /* ISP2401 */ bool atomisp_buffers_queued_pipe(struct atomisp_video_pipe *pipe); -/* - * Interrupt functions - */ +/* Interrupt functions */ void atomisp_msi_irq_init(struct atomisp_device *isp); void atomisp_msi_irq_uninit(struct atomisp_device *isp); void atomisp_wdt_work(struct work_struct *work); @@ -82,15 +78,10 @@ int atomisp_get_frame_pgnr(struct atomisp_device *isp, const struct ia_css_frame *frame, u32 *p_pgnr); void atomisp_delayed_init_work(struct work_struct *work); -/* - * Get internal fmt according to V4L2 fmt - */ - +/* Get internal fmt according to V4L2 fmt */ bool atomisp_is_viewfinder_support(struct atomisp_device *isp); -/* - * ISP features control function - */ +/* ISP features control function */ /* * Function to set sensor runmode by user when @@ -105,9 +96,7 @@ int atomisp_set_sensor_runmode(struct atomisp_sub_device *asd, int atomisp_gdc_cac(struct atomisp_sub_device *asd, int flag, __s32 *value); -/* - * Function to enable/disable low light mode (including ANR) - */ +/* Function to enable/disable low light mode (including ANR) */ int atomisp_low_light(struct atomisp_sub_device *asd, int flag, __s32 *value); @@ -120,91 +109,63 @@ int atomisp_xnr(struct atomisp_sub_device *asd, int flag, int *arg); int atomisp_formats(struct atomisp_sub_device *asd, int flag, struct atomisp_formats_config *config); -/* - * Function to configure noise reduction - */ +/* Function to configure noise reduction */ int atomisp_nr(struct atomisp_sub_device *asd, int flag, struct atomisp_nr_config *config); -/* - * Function to configure temporal noise reduction (TNR) - */ +/* Function to configure temporal noise reduction (TNR) */ int atomisp_tnr(struct atomisp_sub_device *asd, int flag, struct atomisp_tnr_config *config); -/* - * Function to configure black level compensation - */ +/* Function to configure black level compensation */ int atomisp_black_level(struct atomisp_sub_device *asd, int flag, struct atomisp_ob_config *config); -/* - * Function to configure edge enhancement - */ +/* Function to configure edge enhancement */ int atomisp_ee(struct atomisp_sub_device *asd, int flag, struct atomisp_ee_config *config); -/* - * Function to update Gamma table for gamma, brightness and contrast config - */ +/* Function to update Gamma table for gamma, brightness and contrast config */ int atomisp_gamma(struct atomisp_sub_device *asd, int flag, struct atomisp_gamma_table *config); -/* - * Function to update Ctc table for Chroma Enhancement - */ + +/* Function to update Ctc table for Chroma Enhancement */ int atomisp_ctc(struct atomisp_sub_device *asd, int flag, struct atomisp_ctc_table *config); -/* - * Function to update gamma correction parameters - */ +/* Function to update gamma correction parameters */ int atomisp_gamma_correction(struct atomisp_sub_device *asd, int flag, struct atomisp_gc_config *config); -/* - * Function to update Gdc table for gdc - */ +/* Function to update Gdc table for gdc */ int atomisp_gdc_cac_table(struct atomisp_sub_device *asd, int flag, struct atomisp_morph_table *config); -/* - * Function to update table for macc - */ +/* Function to update table for macc */ int atomisp_macc_table(struct atomisp_sub_device *asd, int flag, struct atomisp_macc_config *config); -/* - * Function to get DIS statistics. - */ + +/* Function to get DIS statistics. */ int atomisp_get_dis_stat(struct atomisp_sub_device *asd, struct atomisp_dis_statistics *stats); -/* - * Function to get DVS2 BQ resolution settings - */ +/* Function to get DVS2 BQ resolution settings */ int atomisp_get_dvs2_bq_resolutions(struct atomisp_sub_device *asd, struct atomisp_dvs2_bq_resolutions *bq_res); -/* - * Function to set the DIS coefficients. - */ +/* Function to set the DIS coefficients. */ int atomisp_set_dis_coefs(struct atomisp_sub_device *asd, struct atomisp_dis_coefficients *coefs); -/* - * Function to set the DIS motion vector. - */ +/* Function to set the DIS motion vector. */ int atomisp_set_dis_vector(struct atomisp_sub_device *asd, struct atomisp_dis_vector *vector); -/* - * Function to set/get 3A stat from isp - */ +/* Function to set/get 3A stat from isp */ int atomisp_3a_stat(struct atomisp_sub_device *asd, int flag, struct atomisp_3a_statistics *config); -/* - * Function to get metadata from isp - */ +/* Function to get metadata from isp */ int atomisp_get_metadata(struct atomisp_sub_device *asd, int flag, struct atomisp_metadata *config); @@ -213,84 +174,59 @@ int atomisp_get_metadata_by_type(struct atomisp_sub_device *asd, int flag, int atomisp_set_parameters(struct video_device *vdev, struct atomisp_parameters *arg); -/* - * Function to set/get isp parameters to isp - */ + +/* Function to set/get isp parameters to isp */ int atomisp_param(struct atomisp_sub_device *asd, int flag, struct atomisp_parm *config); -/* - * Function to configure color effect of the image - */ +/* Function to configure color effect of the image */ int atomisp_color_effect(struct atomisp_sub_device *asd, int flag, __s32 *effect); -/* - * Function to configure bad pixel correction - */ +/* Function to configure bad pixel correction */ int atomisp_bad_pixel(struct atomisp_sub_device *asd, int flag, __s32 *value); -/* - * Function to configure bad pixel correction params - */ +/* Function to configure bad pixel correction params */ int atomisp_bad_pixel_param(struct atomisp_sub_device *asd, int flag, struct atomisp_dp_config *config); -/* - * Function to enable/disable video image stablization - */ +/* Function to enable/disable video image stablization */ int atomisp_video_stable(struct atomisp_sub_device *asd, int flag, __s32 *value); -/* - * Function to configure fixed pattern noise - */ +/* Function to configure fixed pattern noise */ int atomisp_fixed_pattern(struct atomisp_sub_device *asd, int flag, __s32 *value); -/* - * Function to configure fixed pattern noise table - */ +/* Function to configure fixed pattern noise table */ int atomisp_fixed_pattern_table(struct atomisp_sub_device *asd, struct v4l2_framebuffer *config); -/* - * Function to configure false color correction - */ +/* Function to configure false color correction */ int atomisp_false_color(struct atomisp_sub_device *asd, int flag, __s32 *value); -/* - * Function to configure false color correction params - */ +/* Function to configure false color correction params */ int atomisp_false_color_param(struct atomisp_sub_device *asd, int flag, struct atomisp_de_config *config); -/* - * Function to configure white balance params - */ +/* Function to configure white balance params */ int atomisp_white_balance_param(struct atomisp_sub_device *asd, int flag, struct atomisp_wb_config *config); int atomisp_3a_config_param(struct atomisp_sub_device *asd, int flag, struct atomisp_3a_config *config); -/* - * Function to setup digital zoom - */ +/* Function to setup digital zoom */ int atomisp_digital_zoom(struct atomisp_sub_device *asd, int flag, __s32 *value); -/* - * Function set camera_prefiles.xml current sensor pixel array size - */ +/* Function set camera_prefiles.xml current sensor pixel array size */ int atomisp_set_array_res(struct atomisp_sub_device *asd, struct atomisp_resolution *config); -/* - * Function to calculate real zoom region for every pipe - */ +/* Function to calculate real zoom region for every pipe */ int atomisp_calculate_real_zoom_region(struct atomisp_sub_device *asd, struct ia_css_dz_config *dz_config, enum ia_css_pipe_id css_pipe_id); @@ -371,9 +307,7 @@ void atomisp_css_flush(struct atomisp_device *isp); int atomisp_source_pad_to_stream_id(struct atomisp_sub_device *asd, uint16_t source_pad); -/* - * Events. Only one event has to be exported for now. - */ +/* Events. Only one event has to be exported for now. */ void atomisp_eof_event(struct atomisp_sub_device *asd, uint8_t exp_id); enum mipi_port_id __get_mipi_port(struct atomisp_device *isp, @@ -389,34 +323,25 @@ void atomisp_free_css_parameters(struct atomisp_css_params *css_param); void atomisp_handle_parameter_and_buffer(struct atomisp_video_pipe *pipe); void atomisp_flush_params_queue(struct atomisp_video_pipe *asd); -/* - * Function to do Raw Buffer related operation, after enable Lock Unlock Raw Buffer - */ + +/* Function to do Raw Buffer related operation, after enable Lock Unlock Raw Buffer */ int atomisp_exp_id_unlock(struct atomisp_sub_device *asd, int *exp_id); int atomisp_exp_id_capture(struct atomisp_sub_device *asd, int *exp_id); -/* - * Function to update Raw Buffer bitmap - */ +/* Function to update Raw Buffer bitmap */ int atomisp_set_raw_buffer_bitmap(struct atomisp_sub_device *asd, int exp_id); void atomisp_init_raw_buffer_bitmap(struct atomisp_sub_device *asd); -/* - * Function to enable/disable zoom for capture pipe - */ +/* Function to enable/disable zoom for capture pipe */ int atomisp_enable_dz_capt_pipe(struct atomisp_sub_device *asd, unsigned int *enable); -/* - * Function to get metadata type bu pipe id - */ +/* Function to get metadata type bu pipe id */ enum atomisp_metadata_type atomisp_get_metadata_type(struct atomisp_sub_device *asd, enum ia_css_pipe_id pipe_id); -/* - * Function for HAL to inject a fake event to wake up poll thread - */ +/* Function for HAL to inject a fake event to wake up poll thread */ int atomisp_inject_a_fake_event(struct atomisp_sub_device *asd, int *event); /* From 29dd19e3ac7b2a8671ebeac02859232ce0e34f58 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 11 May 2021 17:03:21 +0200 Subject: [PATCH 041/394] media: exynos4-is: remove a now unused integer The usage of pm_runtime_resume_and_get() removed the need of a temporary integer. So, drop it. Fixes: 59f96244af94 ("media: exynos4-is: fix pm_runtime_get_sync() usage count") Reported-by: Stephen Rothwell Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos4-is/media-dev.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index e025178db06c..3b8a24bb724c 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c @@ -1284,7 +1284,6 @@ static DEVICE_ATTR(subdev_conf_mode, S_IWUSR | S_IRUGO, static int cam_clk_prepare(struct clk_hw *hw) { struct cam_clk *camclk = to_cam_clk(hw); - int ret; if (camclk->fmd->pmf == NULL) return -ENODEV; From 56c1f0876293888f686e31278d183d4af2cac3c3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 May 2021 11:26:31 +0200 Subject: [PATCH 042/394] media: sti: fix obj-$(config) targets The right thing to do is to add a new object to the building system when a certain config option is selected, and *not* override them. So, fix obj-$(config) logic at sti makefiles, using "+=", instead of ":=". Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/sti/bdisp/Makefile | 2 +- drivers/media/platform/sti/delta/Makefile | 2 +- drivers/media/platform/sti/hva/Makefile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/sti/bdisp/Makefile b/drivers/media/platform/sti/bdisp/Makefile index caf7ccd193ea..39ade0a34723 100644 --- a/drivers/media/platform/sti/bdisp/Makefile +++ b/drivers/media/platform/sti/bdisp/Makefile @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_VIDEO_STI_BDISP) := bdisp.o +obj-$(CONFIG_VIDEO_STI_BDISP) += bdisp.o bdisp-objs := bdisp-v4l2.o bdisp-hw.o bdisp-debug.o diff --git a/drivers/media/platform/sti/delta/Makefile b/drivers/media/platform/sti/delta/Makefile index 92b37e216f00..32412fa4c632 100644 --- a/drivers/media/platform/sti/delta/Makefile +++ b/drivers/media/platform/sti/delta/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_VIDEO_STI_DELTA_DRIVER) := st-delta.o +obj-$(CONFIG_VIDEO_STI_DELTA_DRIVER) += st-delta.o st-delta-y := delta-v4l2.o delta-mem.o delta-ipc.o delta-debug.o # MJPEG support diff --git a/drivers/media/platform/sti/hva/Makefile b/drivers/media/platform/sti/hva/Makefile index 74b41ec52f97..b5a5478bdd01 100644 --- a/drivers/media/platform/sti/hva/Makefile +++ b/drivers/media/platform/sti/hva/Makefile @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_VIDEO_STI_HVA) := st-hva.o +obj-$(CONFIG_VIDEO_STI_HVA) += st-hva.o st-hva-y := hva-v4l2.o hva-hw.o hva-mem.o hva-h264.o st-hva-$(CONFIG_VIDEO_STI_HVA_DEBUGFS) += hva-debugfs.o From 0a016c35a326c6b2f558ede58ff08da7ef1da1a8 Mon Sep 17 00:00:00 2001 From: Aline Santana Cordeiro Date: Thu, 15 Apr 2021 18:54:23 +0200 Subject: [PATCH 043/394] media: staging: media: atomisp: pci: Balance braces around conditional statements in file atomisp_cmd.c Balance braces around conditional statements. Issue detected by checkpatch.pl. It happens in if-else statements where one of the commands uses braces around a block of code and the other command does not since it has just a single line of code. Signed-off-by: Aline Santana Cordeiro Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../staging/media/atomisp/pci/atomisp_cmd.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp_cmd.c index 14abc1ca00e8..24d8eaccb9c6 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c +++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c @@ -1138,9 +1138,10 @@ void atomisp_buf_done(struct atomisp_sub_device *asd, int error, asd->frame_status[vb->i] = ATOMISP_FRAME_STATUS_OK; } - } else + } else { asd->frame_status[vb->i] = ATOMISP_FRAME_STATUS_OK; + } } else { asd->frame_status[vb->i] = ATOMISP_FRAME_STATUS_OK; } @@ -4941,9 +4942,9 @@ atomisp_try_fmt_file(struct atomisp_device *isp, struct v4l2_format *f) depth = get_pixel_depth(pixelformat); - if (field == V4L2_FIELD_ANY) + if (field == V4L2_FIELD_ANY) { field = V4L2_FIELD_NONE; - else if (field != V4L2_FIELD_NONE) { + } else if (field != V4L2_FIELD_NONE) { dev_err(isp->dev, "Wrong output field\n"); return -EINVAL; } @@ -6564,17 +6565,17 @@ static int atomisp_get_pipe_id(struct atomisp_video_pipe *pipe) { struct atomisp_sub_device *asd = pipe->asd; - if (ATOMISP_USE_YUVPP(asd)) + if (ATOMISP_USE_YUVPP(asd)) { return IA_CSS_PIPE_ID_YUVPP; - else if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_SCALER) + } else if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_SCALER) { return IA_CSS_PIPE_ID_VIDEO; - else if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_LOWLAT) + } else if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_LOWLAT) { return IA_CSS_PIPE_ID_CAPTURE; - else if (pipe == &asd->video_out_video_capture) + } else if (pipe == &asd->video_out_video_capture) { return IA_CSS_PIPE_ID_VIDEO; - else if (pipe == &asd->video_out_vf) + } else if (pipe == &asd->video_out_vf) { return IA_CSS_PIPE_ID_CAPTURE; - else if (pipe == &asd->video_out_preview) { + } else if (pipe == &asd->video_out_preview) { if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) return IA_CSS_PIPE_ID_VIDEO; else From b6465b1d74b8ce6dd585ae96877bb74bc6f86f5e Mon Sep 17 00:00:00 2001 From: Aline Santana Cordeiro Date: Thu, 15 Apr 2021 18:54:27 +0200 Subject: [PATCH 044/394] media: staging: media: atomisp: pci: Balance braces around conditional statements in file atomisp_compat_css20.c Balance braces around conditional statements. Issue detected by checkpatch.pl. It happens in if-else statements where one of the commands uses braces around a block of code and the other command does not since it has just a single line of code. Signed-off-by: Aline Santana Cordeiro Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/atomisp_compat_css20.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c b/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c index ce3165291eec..f60198bb8a1a 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c +++ b/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c @@ -2782,9 +2782,9 @@ int atomisp_get_css_frame_info(struct atomisp_sub_device *asd, int stream_index; struct atomisp_device *isp = asd->isp; - if (ATOMISP_SOC_CAMERA(asd)) + if (ATOMISP_SOC_CAMERA(asd)) { stream_index = atomisp_source_pad_to_stream_id(asd, source_pad); - else { + } else { stream_index = (pipe_index == IA_CSS_PIPE_ID_YUVPP) ? ATOMISP_INPUT_STREAM_VIDEO : atomisp_source_pad_to_stream_id(asd, source_pad); From 41d1f1b03909782aa8f0a05db9a15a762679bc17 Mon Sep 17 00:00:00 2001 From: Aline Santana Cordeiro Date: Thu, 15 Apr 2021 18:54:34 +0200 Subject: [PATCH 045/394] media: staging: media: atomisp: pci: Balance braces around conditional statements in file atomisp_subdev.c Balance braces around conditional statements. Issue detected by checkpatch.pl. It happens in if-else statements where one of the commands uses braces around a block of code and the other command does not since it has just a single line of code. Signed-off-by: Aline Santana Cordeiro Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/atomisp_subdev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/atomisp_subdev.c b/drivers/staging/media/atomisp/pci/atomisp_subdev.c index 2ef5f44e4b6b..aeabd07bf518 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_subdev.c +++ b/drivers/staging/media/atomisp/pci/atomisp_subdev.c @@ -472,9 +472,9 @@ int atomisp_subdev_set_selection(struct v4l2_subdev *sd, * when dvs is disabled. */ dvs_w = dvs_h = 12; - } else + } else { dvs_w = dvs_h = 0; - + } atomisp_css_video_set_dis_envelope(isp_sd, dvs_w, dvs_h); atomisp_css_input_set_effective_resolution(isp_sd, stream_id, crop[pad]->width, crop[pad]->height); From d1ca04c476d6dccb6a02248187b8aab1400ed176 Mon Sep 17 00:00:00 2001 From: Aline Santana Cordeiro Date: Thu, 15 Apr 2021 18:54:38 +0200 Subject: [PATCH 046/394] media: staging: media: atomisp: pci: Balance braces around conditional statements in file atomisp_v4l2.c Balance braces around conditional statements. Issue detected by checkpatch.pl. It happens in if-else statements where one of the commands uses braces around a block of code and the other command does not since it has just a single line of code. Signed-off-by: Aline Santana Cordeiro Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/atomisp_v4l2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c index 6d853f480e1c..948769ca6539 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c +++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c @@ -1500,9 +1500,9 @@ static int init_atomisp_wdts(struct atomisp_device *isp) for (i = 0; i < isp->num_of_streams; i++) { struct atomisp_sub_device *asd = &isp->asd[i]; - if (!IS_ISP2401) + if (!IS_ISP2401) { timer_setup(&asd->wdt, atomisp_wdt, 0); - else { + } else { timer_setup(&asd->video_out_capture.wdt, atomisp_wdt, 0); timer_setup(&asd->video_out_preview.wdt, From 049eda0749faa98d074e7f362c3e2d211da2e5ed Mon Sep 17 00:00:00 2001 From: Aline Santana Cordeiro Date: Thu, 15 Apr 2021 19:18:18 +0200 Subject: [PATCH 047/394] media: staging: media: tegra-video: Align line break to match with the open parenthesis in file vi.c Align line break to match with the open parenthesis. Issue detected by checkpatch.pl. Signed-off-by: Aline Santana Cordeiro Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/tegra-video/vi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/tegra-video/vi.c b/drivers/staging/media/tegra-video/vi.c index df5ca3596470..b712063a7c5d 100644 --- a/drivers/staging/media/tegra-video/vi.c +++ b/drivers/staging/media/tegra-video/vi.c @@ -1812,8 +1812,8 @@ static int tegra_vi_graph_parse_one(struct tegra_vi_channel *chan, continue; } - tvge = v4l2_async_notifier_add_fwnode_subdev(&chan->notifier, - remote, struct tegra_vi_graph_entity); + tvge = v4l2_async_notifier_add_fwnode_subdev(&chan->notifier, remote, + struct tegra_vi_graph_entity); if (IS_ERR(tvge)) { ret = PTR_ERR(tvge); dev_err(vi->dev, From 6ceb557604e85c55bce0585216623c21c7a00453 Mon Sep 17 00:00:00 2001 From: Martiros Shakhzadyan Date: Thu, 15 Apr 2021 23:41:41 +0200 Subject: [PATCH 048/394] media: staging: media: atomisp: Fix sh_css.c brace coding style issues Fix brace coding style issues. Signed-off-by: Martiros Shakhzadyan Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/sh_css.c | 224 +++++++++------------ 1 file changed, 90 insertions(+), 134 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/sh_css.c b/drivers/staging/media/atomisp/pci/sh_css.c index 27dd8ce8ba0a..bb752d47457c 100644 --- a/drivers/staging/media/atomisp/pci/sh_css.c +++ b/drivers/staging/media/atomisp/pci/sh_css.c @@ -453,15 +453,15 @@ static enum ia_css_frame_format yuv422_copy_formats[] = { * by the copy binary given the stream format. * */ static int -verify_copy_out_frame_format(struct ia_css_pipe *pipe) { +verify_copy_out_frame_format(struct ia_css_pipe *pipe) +{ enum ia_css_frame_format out_fmt = pipe->output_info[0].format; unsigned int i, found = 0; assert(pipe); assert(pipe->stream); - switch (pipe->stream->config.input_config.format) - { + switch (pipe->stream->config.input_config.format) { case ATOMISP_INPUT_FORMAT_YUV420_8_LEGACY: case ATOMISP_INPUT_FORMAT_YUV420_8: for (i = 0; i < ARRAY_SIZE(yuv420_copy_formats) && !found; i++) @@ -528,7 +528,8 @@ ia_css_stream_input_format_bits_per_pixel(struct ia_css_stream *stream) #if !defined(ISP2401) static int -sh_css_config_input_network(struct ia_css_stream *stream) { +sh_css_config_input_network(struct ia_css_stream *stream) +{ unsigned int fmt_type; struct ia_css_pipe *pipe = stream->last_pipe; struct ia_css_binary *binary = NULL; @@ -554,8 +555,7 @@ sh_css_config_input_network(struct ia_css_stream *stream) { stream->config.mode); if ((binary && (binary->online || stream->config.continuous)) || - pipe->config.mode == IA_CSS_PIPE_MODE_COPY) - { + pipe->config.mode == IA_CSS_PIPE_MODE_COPY) { err = ia_css_ifmtr_configure(&stream->config, binary); if (err) @@ -563,8 +563,7 @@ sh_css_config_input_network(struct ia_css_stream *stream) { } if (stream->config.mode == IA_CSS_INPUT_MODE_TPG || - stream->config.mode == IA_CSS_INPUT_MODE_PRBS) - { + stream->config.mode == IA_CSS_INPUT_MODE_PRBS) { unsigned int hblank_cycles = 100, vblank_lines = 6, width, @@ -723,35 +722,32 @@ static bool sh_css_translate_stream_cfg_to_input_system_input_port_id( switch (stream_cfg->mode) { case IA_CSS_INPUT_MODE_TPG: - if (stream_cfg->source.tpg.id == IA_CSS_TPG_ID0) { + if (stream_cfg->source.tpg.id == IA_CSS_TPG_ID0) isys_stream_descr->input_port_id = INPUT_SYSTEM_PIXELGEN_PORT0_ID; - } else if (stream_cfg->source.tpg.id == IA_CSS_TPG_ID1) { + else if (stream_cfg->source.tpg.id == IA_CSS_TPG_ID1) isys_stream_descr->input_port_id = INPUT_SYSTEM_PIXELGEN_PORT1_ID; - } else if (stream_cfg->source.tpg.id == IA_CSS_TPG_ID2) { + else if (stream_cfg->source.tpg.id == IA_CSS_TPG_ID2) isys_stream_descr->input_port_id = INPUT_SYSTEM_PIXELGEN_PORT2_ID; - } break; case IA_CSS_INPUT_MODE_PRBS: - if (stream_cfg->source.prbs.id == IA_CSS_PRBS_ID0) { + if (stream_cfg->source.prbs.id == IA_CSS_PRBS_ID0) isys_stream_descr->input_port_id = INPUT_SYSTEM_PIXELGEN_PORT0_ID; - } else if (stream_cfg->source.prbs.id == IA_CSS_PRBS_ID1) { + else if (stream_cfg->source.prbs.id == IA_CSS_PRBS_ID1) isys_stream_descr->input_port_id = INPUT_SYSTEM_PIXELGEN_PORT1_ID; - } else if (stream_cfg->source.prbs.id == IA_CSS_PRBS_ID2) { + else if (stream_cfg->source.prbs.id == IA_CSS_PRBS_ID2) isys_stream_descr->input_port_id = INPUT_SYSTEM_PIXELGEN_PORT2_ID; - } break; case IA_CSS_INPUT_MODE_BUFFERED_SENSOR: - if (stream_cfg->source.port.port == MIPI_PORT0_ID) { + if (stream_cfg->source.port.port == MIPI_PORT0_ID) isys_stream_descr->input_port_id = INPUT_SYSTEM_CSI_PORT0_ID; - } else if (stream_cfg->source.port.port == MIPI_PORT1_ID) { + else if (stream_cfg->source.port.port == MIPI_PORT1_ID) isys_stream_descr->input_port_id = INPUT_SYSTEM_CSI_PORT1_ID; - } else if (stream_cfg->source.port.port == MIPI_PORT2_ID) { + else if (stream_cfg->source.port.port == MIPI_PORT2_ID) isys_stream_descr->input_port_id = INPUT_SYSTEM_CSI_PORT2_ID; - } break; default: @@ -804,15 +800,14 @@ static bool sh_css_translate_stream_cfg_to_input_system_input_port_attr( rc = true; switch (stream_cfg->mode) { case IA_CSS_INPUT_MODE_TPG: - if (stream_cfg->source.tpg.mode == IA_CSS_TPG_MODE_RAMP) { + if (stream_cfg->source.tpg.mode == IA_CSS_TPG_MODE_RAMP) isys_stream_descr->tpg_port_attr.mode = PIXELGEN_TPG_MODE_RAMP; - } else if (stream_cfg->source.tpg.mode == IA_CSS_TPG_MODE_CHECKERBOARD) { + else if (stream_cfg->source.tpg.mode == IA_CSS_TPG_MODE_CHECKERBOARD) isys_stream_descr->tpg_port_attr.mode = PIXELGEN_TPG_MODE_CHBO; - } else if (stream_cfg->source.tpg.mode == IA_CSS_TPG_MODE_MONO) { + else if (stream_cfg->source.tpg.mode == IA_CSS_TPG_MODE_MONO) isys_stream_descr->tpg_port_attr.mode = PIXELGEN_TPG_MODE_MONO; - } else { + else rc = false; - } /* * TODO @@ -951,12 +946,12 @@ static bool sh_css_translate_stream_cfg_to_input_system_input_port_resolution( stream_cfg->mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR) && stream_cfg->source.port.compression.type != IA_CSS_CSI2_COMPRESSION_TYPE_NONE) { if (stream_cfg->source.port.compression.uncompressed_bits_per_pixel == - UNCOMPRESSED_BITS_PER_PIXEL_10) { + UNCOMPRESSED_BITS_PER_PIXEL_10) fmt_type = ATOMISP_INPUT_FORMAT_RAW_10; - } else if (stream_cfg->source.port.compression.uncompressed_bits_per_pixel == - UNCOMPRESSED_BITS_PER_PIXEL_12) { + else if (stream_cfg->source.port.compression.uncompressed_bits_per_pixel == + UNCOMPRESSED_BITS_PER_PIXEL_12) fmt_type = ATOMISP_INPUT_FORMAT_RAW_12; - } else + else return false; } @@ -1045,7 +1040,8 @@ static bool sh_css_translate_binary_info_to_input_system_output_port_attr( } static int -sh_css_config_input_network(struct ia_css_stream *stream) { +sh_css_config_input_network(struct ia_css_stream *stream) +{ bool rc; ia_css_isys_descr_t isys_stream_descr; unsigned int sp_thread_id; @@ -1060,19 +1056,16 @@ sh_css_config_input_network(struct ia_css_stream *stream) { ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "sh_css_config_input_network() enter 0x%p:\n", stream); - if (stream->config.continuous) - { - if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_CAPTURE) { + if (stream->config.continuous) { + if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_CAPTURE) pipe = stream->last_pipe; - } else if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_YUVPP) { + else if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_YUVPP) pipe = stream->last_pipe; - } else if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_PREVIEW) { + else if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_PREVIEW) pipe = stream->last_pipe->pipe_settings.preview.copy_pipe; - } else if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_VIDEO) { + else if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_VIDEO) pipe = stream->last_pipe->pipe_settings.video.copy_pipe; - } - } else - { + } else { pipe = stream->last_pipe; if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_CAPTURE) { /* @@ -1095,8 +1088,7 @@ sh_css_config_input_network(struct ia_css_stream *stream) { if (pipe->pipeline.stages->binary) binary = pipe->pipeline.stages->binary; - if (binary) - { + if (binary) { /* this was being done in ifmtr in 2400. * online and cont bypass the init_in_frameinfo_memory_defaults * so need to do it here @@ -1210,11 +1202,10 @@ static inline struct ia_css_pipe *stream_get_target_pipe( struct ia_css_pipe *target_pipe; /* get the pipe that consumes the stream */ - if (stream->config.continuous) { + if (stream->config.continuous) target_pipe = stream_get_copy_pipe(stream); - } else { + else target_pipe = stream_get_last_pipe(stream); - } return target_pipe; } @@ -1388,7 +1379,8 @@ start_binary(struct ia_css_pipe *pipe, /* start the copy function on the SP */ static int start_copy_on_sp(struct ia_css_pipe *pipe, - struct ia_css_frame *out_frame) { + struct ia_css_frame *out_frame) +{ (void)out_frame; assert(pipe); assert(pipe->stream); @@ -1406,8 +1398,7 @@ start_copy_on_sp(struct ia_css_pipe *pipe, sh_css_sp_start_binary_copy(ia_css_pipe_get_pipe_num(pipe), out_frame, pipe->stream->config.pixels_per_clock == 2); #if !defined(ISP2401) - if (pipe->stream->reconfigure_css_rx) - { + if (pipe->stream->reconfigure_css_rx) { ia_css_isys_rx_configure(&pipe->stream->csi_rx_config, pipe->stream->config.mode); pipe->stream->reconfigure_css_rx = false; @@ -1596,7 +1587,8 @@ ia_css_reset_defaults(struct sh_css *css) int ia_css_load_firmware(struct device *dev, const struct ia_css_env *env, - const struct ia_css_fw *fw) { + const struct ia_css_fw *fw) +{ int err; if (!env) @@ -1607,16 +1599,14 @@ ia_css_load_firmware(struct device *dev, const struct ia_css_env *env, ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_load_firmware() enter\n"); /* make sure we initialize my_css */ - if (my_css.flush != env->cpu_mem_env.flush) - { + if (my_css.flush != env->cpu_mem_env.flush) { ia_css_reset_defaults(&my_css); my_css.flush = env->cpu_mem_env.flush; } ia_css_unload_firmware(); /* in case we are called twice */ err = sh_css_load_firmware(dev, fw->data, fw->bytes); - if (!err) - { + if (!err) { err = ia_css_binary_init_infos(); if (!err) fw_explicitly_loaded = true; @@ -1630,7 +1620,8 @@ int ia_css_init(struct device *dev, const struct ia_css_env *env, const struct ia_css_fw *fw, u32 mmu_l1_base, - enum ia_css_irq_type irq_type) { + enum ia_css_irq_type irq_type) +{ int err; ia_css_spctrl_cfg spctrl_cfg; @@ -1704,16 +1695,14 @@ ia_css_init(struct device *dev, const struct ia_css_env *env, my_css.flush = flush_func; err = ia_css_rmgr_init(); - if (err) - { + if (err) { IA_CSS_LEAVE_ERR(err); return err; } IA_CSS_LOG("init: %d", my_css_save_initialized); - if (!my_css_save_initialized) - { + if (!my_css_save_initialized) { my_css_save_initialized = true; my_css_save.mode = sh_css_mode_working; memset(my_css_save.stream_seeds, 0, @@ -1741,19 +1730,16 @@ ia_css_init(struct device *dev, const struct ia_css_env *env, gpio_reg_store(GPIO0_ID, _gpio_block_reg_do_0, 0); err = ia_css_refcount_init(REFCOUNT_SIZE); - if (err) - { + if (err) { IA_CSS_LEAVE_ERR(err); return err; } err = sh_css_params_init(); - if (err) - { + if (err) { IA_CSS_LEAVE_ERR(err); return err; } - if (fw) - { + if (fw) { ia_css_unload_firmware(); /* in case we already had firmware loaded */ err = sh_css_load_firmware(dev, fw->data, fw->bytes); if (err) { @@ -1774,23 +1760,20 @@ ia_css_init(struct device *dev, const struct ia_css_env *env, return -EINVAL; err = ia_css_spctrl_load_fw(SP0_ID, &spctrl_cfg); - if (err) - { + if (err) { IA_CSS_LEAVE_ERR(err); return err; } #if WITH_PC_MONITORING - if (!thread_alive) - { + if (!thread_alive) { thread_alive++; sh_css_print("PC_MONITORING: %s() -- create thread DISABLED\n", __func__); spying_thread_create(); } #endif - if (!sh_css_hrt_system_is_idle()) - { + if (!sh_css_hrt_system_is_idle()) { IA_CSS_LEAVE_ERR(-EBUSY); return -EBUSY; } @@ -1823,7 +1806,8 @@ ia_css_init(struct device *dev, const struct ia_css_env *env, } int -ia_css_enable_isys_event_queue(bool enable) { +ia_css_enable_isys_event_queue(bool enable) +{ if (sh_css_sp_is_running()) return -EBUSY; sh_css_sp_enable_isys_event_queue(enable); @@ -1844,7 +1828,8 @@ sh_css_flush(struct ia_css_acc_fw *fw) * doing it from stream_create since we could run out of sp threads due to * allocation on inactive pipelines. */ static int -map_sp_threads(struct ia_css_stream *stream, bool map) { +map_sp_threads(struct ia_css_stream *stream, bool map) +{ struct ia_css_pipe *main_pipe = NULL; struct ia_css_pipe *copy_pipe = NULL; struct ia_css_pipe *capture_pipe = NULL; @@ -1856,8 +1841,7 @@ map_sp_threads(struct ia_css_stream *stream, bool map) { IA_CSS_ENTER_PRIVATE("stream = %p, map = %s", stream, map ? "true" : "false"); - if (!stream) - { + if (!stream) { IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL); return -EINVAL; } @@ -1867,8 +1851,7 @@ map_sp_threads(struct ia_css_stream *stream, bool map) { ia_css_pipeline_map(main_pipe->pipe_num, map); - switch (pipe_id) - { + switch (pipe_id) { case IA_CSS_PIPE_ID_PREVIEW: copy_pipe = main_pipe->pipe_settings.preview.copy_pipe; capture_pipe = main_pipe->pipe_settings.preview.capture_pipe; @@ -1887,23 +1870,17 @@ map_sp_threads(struct ia_css_stream *stream, bool map) { } if (acc_pipe) - { ia_css_pipeline_map(acc_pipe->pipe_num, map); - } if (capture_pipe) - { ia_css_pipeline_map(capture_pipe->pipe_num, map); - } /* Firmware expects copy pipe to be the last pipe mapped. (if needed) */ if (copy_pipe) - { ia_css_pipeline_map(copy_pipe->pipe_num, map); - } + /* DH regular multi pipe - not continuous mode: map the next pipes too */ - if (!stream->config.continuous) - { + if (!stream->config.continuous) { int i; for (i = 1; i < stream->num_pipes; i++) @@ -1917,7 +1894,8 @@ map_sp_threads(struct ia_css_stream *stream, bool map) { /* creates a host pipeline skeleton for all pipes in a stream. Called during * stream_create. */ static int -create_host_pipeline_structure(struct ia_css_stream *stream) { +create_host_pipeline_structure(struct ia_css_stream *stream) +{ struct ia_css_pipe *copy_pipe = NULL, *capture_pipe = NULL; struct ia_css_pipe *acc_pipe = NULL; enum ia_css_pipe_id pipe_id; @@ -1929,24 +1907,21 @@ create_host_pipeline_structure(struct ia_css_stream *stream) { assert(stream); IA_CSS_ENTER_PRIVATE("stream = %p", stream); - if (!stream) - { + if (!stream) { IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL); return -EINVAL; } main_pipe = stream->last_pipe; assert(main_pipe); - if (!main_pipe) - { + if (!main_pipe) { IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL); return -EINVAL; } pipe_id = main_pipe->mode; - switch (pipe_id) - { + switch (pipe_id) { case IA_CSS_PIPE_ID_PREVIEW: copy_pipe = main_pipe->pipe_settings.preview.copy_pipe; copy_pipe_delay = main_pipe->dvs_frame_delay; @@ -1986,30 +1961,23 @@ create_host_pipeline_structure(struct ia_css_stream *stream) { } if (!(err) && copy_pipe) - { err = ia_css_pipeline_create(©_pipe->pipeline, copy_pipe->mode, copy_pipe->pipe_num, copy_pipe_delay); - } if (!(err) && capture_pipe) - { err = ia_css_pipeline_create(&capture_pipe->pipeline, capture_pipe->mode, capture_pipe->pipe_num, capture_pipe_delay); - } if (!(err) && acc_pipe) - { err = ia_css_pipeline_create(&acc_pipe->pipeline, acc_pipe->mode, acc_pipe->pipe_num, main_pipe->dvs_frame_delay); - } /* DH regular multi pipe - not continuous mode: create the next pipelines too */ - if (!stream->config.continuous) - { + if (!stream->config.continuous) { int i; for (i = 1; i < stream->num_pipes && 0 == err; i++) { @@ -2028,7 +1996,8 @@ create_host_pipeline_structure(struct ia_css_stream *stream) { /* creates a host pipeline for all pipes in a stream. Called during * stream_start. */ static int -create_host_pipeline(struct ia_css_stream *stream) { +create_host_pipeline(struct ia_css_stream *stream) +{ struct ia_css_pipe *copy_pipe = NULL, *capture_pipe = NULL; struct ia_css_pipe *acc_pipe = NULL; enum ia_css_pipe_id pipe_id; @@ -2037,8 +2006,7 @@ create_host_pipeline(struct ia_css_stream *stream) { unsigned int max_input_width = 0; IA_CSS_ENTER_PRIVATE("stream = %p", stream); - if (!stream) - { + if (!stream) { IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL); return -EINVAL; } @@ -2049,8 +2017,7 @@ create_host_pipeline(struct ia_css_stream *stream) { /* No continuous frame allocation for capture pipe. It uses the * "main" pipe's frames. */ if ((pipe_id == IA_CSS_PIPE_ID_PREVIEW) || - (pipe_id == IA_CSS_PIPE_ID_VIDEO)) - { + (pipe_id == IA_CSS_PIPE_ID_VIDEO)) { /* About pipe_id == IA_CSS_PIPE_ID_PREVIEW && stream->config.mode != IA_CSS_INPUT_MODE_MEMORY: * The original condition pipe_id == IA_CSS_PIPE_ID_PREVIEW is too strong. E.g. in SkyCam (with memory * based input frames) there is no continuous mode and thus no need for allocated continuous frames @@ -2068,24 +2035,21 @@ create_host_pipeline(struct ia_css_stream *stream) { #if !defined(ISP2401) /* old isys: need to allocate_mipi_frames() even in IA_CSS_PIPE_MODE_COPY */ - if (pipe_id != IA_CSS_PIPE_ID_ACC) - { + if (pipe_id != IA_CSS_PIPE_ID_ACC) { err = allocate_mipi_frames(main_pipe, &stream->info); if (err) goto ERR; } #elif defined(ISP2401) if ((pipe_id != IA_CSS_PIPE_ID_ACC) && - (main_pipe->config.mode != IA_CSS_PIPE_MODE_COPY)) - { + (main_pipe->config.mode != IA_CSS_PIPE_MODE_COPY)) { err = allocate_mipi_frames(main_pipe, &stream->info); if (err) goto ERR; } #endif - switch (pipe_id) - { + switch (pipe_id) { case IA_CSS_PIPE_ID_PREVIEW: copy_pipe = main_pipe->pipe_settings.preview.copy_pipe; capture_pipe = main_pipe->pipe_settings.preview.capture_pipe; @@ -2135,31 +2099,27 @@ create_host_pipeline(struct ia_css_stream *stream) { if (err) goto ERR; - if (copy_pipe) - { + if (copy_pipe) { err = create_host_copy_pipeline(copy_pipe, max_input_width, main_pipe->continuous_frames[0]); if (err) goto ERR; } - if (capture_pipe) - { + if (capture_pipe) { err = create_host_capture_pipeline(capture_pipe); if (err) goto ERR; } - if (acc_pipe) - { + if (acc_pipe) { err = create_host_acc_pipeline(acc_pipe); if (err) goto ERR; } /* DH regular multi pipe - not continuous mode: create the next pipelines too */ - if (!stream->config.continuous) - { + if (!stream->config.continuous) { int i; for (i = 1; i < stream->num_pipes && 0 == err; i++) { @@ -2201,10 +2161,10 @@ static const struct ia_css_yuvpp_settings yuvpp = IA_CSS_DEFAULT_YUVPP_SETTINGS; static int init_pipe_defaults(enum ia_css_pipe_mode mode, struct ia_css_pipe *pipe, - bool copy_pipe) { + bool copy_pipe) +{ - if (!pipe) - { + if (!pipe) { IA_CSS_ERROR("NULL pipe parameter"); return -EINVAL; } @@ -2213,18 +2173,17 @@ init_pipe_defaults(enum ia_css_pipe_mode mode, memcpy(pipe, &default_pipe, sizeof(default_pipe)); /* TODO: JB should not be needed, but temporary backward reference */ - switch (mode) - { + switch (mode) { case IA_CSS_PIPE_MODE_PREVIEW: pipe->mode = IA_CSS_PIPE_ID_PREVIEW; memcpy(&pipe->pipe_settings.preview, &preview, sizeof(preview)); break; case IA_CSS_PIPE_MODE_CAPTURE: - if (copy_pipe) { + if (copy_pipe) pipe->mode = IA_CSS_PIPE_ID_COPY; - } else { + else pipe->mode = IA_CSS_PIPE_ID_CAPTURE; - } + memcpy(&pipe->pipe_settings.capture, &capture, sizeof(capture)); break; case IA_CSS_PIPE_MODE_VIDEO: @@ -2254,27 +2213,25 @@ pipe_global_init(void) u8 i; my_css.pipe_counter = 0; - for (i = 0; i < IA_CSS_PIPELINE_NUM_MAX; i++) { + for (i = 0; i < IA_CSS_PIPELINE_NUM_MAX; i++) my_css.all_pipes[i] = NULL; - } } static int pipe_generate_pipe_num(const struct ia_css_pipe *pipe, - unsigned int *pipe_number) { + unsigned int *pipe_number) +{ const u8 INVALID_PIPE_NUM = (uint8_t)~(0); u8 pipe_num = INVALID_PIPE_NUM; u8 i; - if (!pipe) - { + if (!pipe) { IA_CSS_ERROR("NULL pipe parameter"); return -EINVAL; } /* Assign a new pipe_num .... search for empty place */ - for (i = 0; i < IA_CSS_PIPELINE_NUM_MAX; i++) - { + for (i = 0; i < IA_CSS_PIPELINE_NUM_MAX; i++) { if (!my_css.all_pipes[i]) { /*position is reserved */ my_css.all_pipes[i] = (struct ia_css_pipe *)pipe; @@ -2282,8 +2239,7 @@ pipe_generate_pipe_num(const struct ia_css_pipe *pipe, break; } } - if (pipe_num == INVALID_PIPE_NUM) - { + if (pipe_num == INVALID_PIPE_NUM) { /* Max number of pipes already allocated */ IA_CSS_ERROR("Max number of pipes already created"); return -ENOSPC; From c0633711b00ae5997925f0b691acb7ec900155c4 Mon Sep 17 00:00:00 2001 From: Martiros Shakhzadyan Date: Thu, 15 Apr 2021 23:41:42 +0200 Subject: [PATCH 049/394] media: staging: media: atomisp: Remove redundant assertions in sh_css.c Remove assert() in places where the condition is already handled. Signed-off-by: Martiros Shakhzadyan Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/sh_css.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/sh_css.c b/drivers/staging/media/atomisp/pci/sh_css.c index bb752d47457c..01ce6005ead4 100644 --- a/drivers/staging/media/atomisp/pci/sh_css.c +++ b/drivers/staging/media/atomisp/pci/sh_css.c @@ -413,7 +413,6 @@ aspect_ratio_crop(struct ia_css_pipe *curr_pipe, static void sh_css_pipe_free_shading_table(struct ia_css_pipe *pipe) { - assert(pipe); if (!pipe) { IA_CSS_ERROR("NULL input parameter"); return; @@ -1080,7 +1079,6 @@ sh_css_config_input_network(struct ia_css_stream *stream) } } - assert(pipe); if (!pipe) return -EINVAL; @@ -1382,8 +1380,6 @@ start_copy_on_sp(struct ia_css_pipe *pipe, struct ia_css_frame *out_frame) { (void)out_frame; - assert(pipe); - assert(pipe->stream); if ((!pipe) || (!pipe->stream)) return -EINVAL; @@ -1837,7 +1833,6 @@ map_sp_threads(struct ia_css_stream *stream, bool map) int err = 0; enum ia_css_pipe_id pipe_id; - assert(stream); IA_CSS_ENTER_PRIVATE("stream = %p, map = %s", stream, map ? "true" : "false"); @@ -1904,7 +1899,6 @@ create_host_pipeline_structure(struct ia_css_stream *stream) unsigned int copy_pipe_delay = 0, capture_pipe_delay = 0; - assert(stream); IA_CSS_ENTER_PRIVATE("stream = %p", stream); if (!stream) { @@ -1913,7 +1907,6 @@ create_host_pipeline_structure(struct ia_css_stream *stream) } main_pipe = stream->last_pipe; - assert(main_pipe); if (!main_pipe) { IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL); return -EINVAL; @@ -2317,7 +2310,6 @@ static void sh_css_pipe_free_acc_binaries( struct ia_css_pipeline *pipeline; struct ia_css_pipeline_stage *stage; - assert(pipe); if (!pipe) { IA_CSS_ERROR("NULL input pointer"); return; From 7394bf6d3c1e8316484fcf3a9d71daaab489f211 Mon Sep 17 00:00:00 2001 From: Martiros Shakhzadyan Date: Mon, 19 Apr 2021 21:25:55 +0200 Subject: [PATCH 050/394] media: staging: media: atomisp: Fix the rest of sh_css.c brace issues Fix the remainder of brace coding style issues. Signed-off-by: Martiros Shakhzadyan Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/sh_css.c | 1134 +++++++++----------- 1 file changed, 498 insertions(+), 636 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/sh_css.c b/drivers/staging/media/atomisp/pci/sh_css.c index 01ce6005ead4..ac748da7a7ef 100644 --- a/drivers/staging/media/atomisp/pci/sh_css.c +++ b/drivers/staging/media/atomisp/pci/sh_css.c @@ -1101,8 +1101,7 @@ sh_css_config_input_network(struct ia_css_stream *stream) /* get the target input terminal */ sp_pipeline_input_terminal = &sh_css_sp_group.pipe_io[sp_thread_id].input; - for (i = 0; i < IA_CSS_STREAM_MAX_ISYS_STREAM_PER_CH; i++) - { + for (i = 0; i < IA_CSS_STREAM_MAX_ISYS_STREAM_PER_CH; i++) { /* initialization */ memset((void *)(&isys_stream_descr), 0, sizeof(ia_css_isys_descr_t)); sp_pipeline_input_terminal->context.virtual_input_system_stream[i].valid = 0; @@ -2156,7 +2155,6 @@ init_pipe_defaults(enum ia_css_pipe_mode mode, struct ia_css_pipe *pipe, bool copy_pipe) { - if (!pipe) { IA_CSS_ERROR("NULL pipe parameter"); return -EINVAL; @@ -2258,12 +2256,12 @@ pipe_release_pipe_num(unsigned int pipe_num) static int create_pipe(enum ia_css_pipe_mode mode, struct ia_css_pipe **pipe, - bool copy_pipe) { + bool copy_pipe) +{ int err = 0; struct ia_css_pipe *me; - if (!pipe) - { + if (!pipe) { IA_CSS_ERROR("NULL pipe parameter"); return -EINVAL; } @@ -2273,15 +2271,13 @@ create_pipe(enum ia_css_pipe_mode mode, return -ENOMEM; err = init_pipe_defaults(mode, me, copy_pipe); - if (err) - { + if (err) { kfree(me); return err; } err = pipe_generate_pipe_num(me, &me->pipe_num); - if (err) - { + if (err) { kfree(me); return err; } @@ -2326,26 +2322,24 @@ static void sh_css_pipe_free_acc_binaries( } int -ia_css_pipe_destroy(struct ia_css_pipe *pipe) { +ia_css_pipe_destroy(struct ia_css_pipe *pipe) +{ int err = 0; IA_CSS_ENTER("pipe = %p", pipe); - if (!pipe) - { + if (!pipe) { IA_CSS_LEAVE_ERR(-EINVAL); return -EINVAL; } - if (pipe->stream) - { + if (pipe->stream) { IA_CSS_LOG("ia_css_stream_destroy not called!"); IA_CSS_LEAVE_ERR(-EINVAL); return -EINVAL; } - switch (pipe->config.mode) - { + switch (pipe->config.mode) { case IA_CSS_PIPE_MODE_PREVIEW: /* need to take into account that this function is also called on the internal copy pipe */ @@ -2409,9 +2403,8 @@ ia_css_pipe_destroy(struct ia_css_pipe *pipe) { /* Temporarily, not every sh_css_pipe has an acc_extension. */ if (pipe->config.acc_extension) - { ia_css_pipe_unload_extension(pipe, pipe->config.acc_extension); - } + kfree(pipe); IA_CSS_LEAVE("err = %d", err); return err; @@ -2441,9 +2434,9 @@ ia_css_uninit(void) ifmtr_set_if_blocking_mode_reset = true; #endif - if (!fw_explicitly_loaded) { + if (!fw_explicitly_loaded) ia_css_unload_firmware(); - } + ia_css_spctrl_unload_fw(SP0_ID); sh_css_sp_set_sp_running(false); /* check and free any remaining mipi frames */ @@ -2630,7 +2623,8 @@ static int load_copy_binary( static int alloc_continuous_frames( - struct ia_css_pipe *pipe, bool init_time) { + struct ia_css_pipe *pipe, bool init_time) +{ int err = 0; struct ia_css_frame_info ref_info; enum ia_css_pipe_id pipe_id; @@ -2640,8 +2634,7 @@ alloc_continuous_frames( IA_CSS_ENTER_PRIVATE("pipe = %p, init_time = %d", pipe, init_time); - if ((!pipe) || (!pipe->stream)) - { + if ((!pipe) || (!pipe->stream)) { IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL); return -EINVAL; } @@ -2649,26 +2642,22 @@ alloc_continuous_frames( pipe_id = pipe->mode; continuous = pipe->stream->config.continuous; - if (continuous) - { + if (continuous) { if (init_time) { num_frames = pipe->stream->config.init_num_cont_raw_buf; pipe->stream->continuous_pipe = pipe; - } else + } else { num_frames = pipe->stream->config.target_num_cont_raw_buf; - } else - { + } + } else { num_frames = NUM_ONLINE_INIT_CONTINUOUS_FRAMES; } - if (pipe_id == IA_CSS_PIPE_ID_PREVIEW) - { + if (pipe_id == IA_CSS_PIPE_ID_PREVIEW) { ref_info = pipe->pipe_settings.preview.preview_binary.in_frame_info; - } else if (pipe_id == IA_CSS_PIPE_ID_VIDEO) - { + } else if (pipe_id == IA_CSS_PIPE_ID_VIDEO) { ref_info = pipe->pipe_settings.video.video_binary.in_frame_info; - } else - { + } else { /* should not happen */ IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL); return -EINVAL; @@ -2684,8 +2673,7 @@ alloc_continuous_frames( #endif #if !defined(HAS_NO_PACKED_RAW_PIXELS) - if (pipe->stream->config.pack_raw_pixels) - { + if (pipe->stream->config.pack_raw_pixels) { ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "alloc_continuous_frames() IA_CSS_FRAME_FORMAT_RAW_PACKED\n"); ref_info.format = IA_CSS_FRAME_FORMAT_RAW_PACKED; @@ -2714,8 +2702,7 @@ alloc_continuous_frames( else idx = pipe->stream->config.init_num_cont_raw_buf; - for (i = idx; i < NUM_CONTINUOUS_FRAMES; i++) - { + for (i = idx; i < NUM_CONTINUOUS_FRAMES; i++) { /* free previous frame */ if (pipe->continuous_frames[i]) { ia_css_frame_free(pipe->continuous_frames[i]); @@ -2745,14 +2732,16 @@ alloc_continuous_frames( } int -ia_css_alloc_continuous_frame_remain(struct ia_css_stream *stream) { +ia_css_alloc_continuous_frame_remain(struct ia_css_stream *stream) +{ if (!stream) return -EINVAL; return alloc_continuous_frames(stream->continuous_pipe, false); } static int -load_preview_binaries(struct ia_css_pipe *pipe) { +load_preview_binaries(struct ia_css_pipe *pipe) +{ struct ia_css_frame_info prev_in_info, prev_bds_out_info, prev_out_info, @@ -2860,8 +2849,7 @@ load_preview_binaries(struct ia_css_pipe *pipe) { * then the preview binary selection is done again. */ if (need_vf_pp && - (mycs->preview_binary.out_frame_info[0].format != IA_CSS_FRAME_FORMAT_YUV_LINE)) - { + (mycs->preview_binary.out_frame_info[0].format != IA_CSS_FRAME_FORMAT_YUV_LINE)) { /* Preview step 2 */ if (pipe->vf_yuv_ds_input_info.res.width) prev_vf_info = pipe->vf_yuv_ds_input_info; @@ -2886,8 +2874,7 @@ load_preview_binaries(struct ia_css_pipe *pipe) { return err; } - if (need_vf_pp) - { + if (need_vf_pp) { struct ia_css_binary_descr vf_pp_descr; /* Viewfinder post-processing */ @@ -2918,8 +2905,7 @@ load_preview_binaries(struct ia_css_pipe *pipe) { #endif /* Copy */ - if (need_isp_copy_binary) - { + if (need_isp_copy_binary) { err = load_copy_binary(pipe, &mycs->copy_binary, &mycs->preview_binary); @@ -2927,8 +2913,7 @@ load_preview_binaries(struct ia_css_pipe *pipe) { return err; } - if (pipe->shading_table) - { + if (pipe->shading_table) { ia_css_shading_table_free(pipe->shading_table); pipe->shading_table = NULL; } @@ -2943,11 +2928,11 @@ ia_css_binary_unload(struct ia_css_binary *binary) } static int -unload_preview_binaries(struct ia_css_pipe *pipe) { +unload_preview_binaries(struct ia_css_pipe *pipe) +{ IA_CSS_ENTER_PRIVATE("pipe = %p", pipe); - if ((!pipe) || (pipe->mode != IA_CSS_PIPE_ID_PREVIEW)) - { + if ((!pipe) || (pipe->mode != IA_CSS_PIPE_ID_PREVIEW)) { IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL); return -EINVAL; } @@ -3000,15 +2985,15 @@ static int add_firmwares( struct ia_css_frame *in = NULL; struct ia_css_frame *vf = NULL; - if ((fw == last_fw) && (fw->info.isp.sp.enable.out_frame != 0)) { + if ((fw == last_fw) && (fw->info.isp.sp.enable.out_frame != 0)) out[0] = out_frame; - } - if (fw->info.isp.sp.enable.in_frame != 0) { + + if (fw->info.isp.sp.enable.in_frame != 0) in = in_frame; - } - if (fw->info.isp.sp.enable.out_frame != 0) { + + if (fw->info.isp.sp.enable.out_frame != 0) vf = vf_frame; - } + ia_css_pipe_get_firmwares_stage_desc(&stage_desc, binary, out, in, vf, fw, binary_mode); err = ia_css_pipeline_create_and_add_stage(me, @@ -3222,7 +3207,8 @@ static void sh_css_setup_queues(void) static int init_vf_frameinfo_defaults(struct ia_css_pipe *pipe, - struct ia_css_frame *vf_frame, unsigned int idx) { + struct ia_css_frame *vf_frame, unsigned int idx) +{ int err = 0; unsigned int thread_id; enum sh_css_queue_id queue_id; @@ -3387,7 +3373,8 @@ ia_css_get_crop_offsets( static int init_in_frameinfo_memory_defaults(struct ia_css_pipe *pipe, - struct ia_css_frame *frame, enum ia_css_frame_format format) { + struct ia_css_frame *frame, enum ia_css_frame_format format) +{ struct ia_css_frame *in_frame; int err = 0; unsigned int thread_id; @@ -3428,7 +3415,8 @@ init_in_frameinfo_memory_defaults(struct ia_css_pipe *pipe, static int init_out_frameinfo_defaults(struct ia_css_pipe *pipe, - struct ia_css_frame *out_frame, unsigned int idx) { + struct ia_css_frame *out_frame, unsigned int idx) +{ int err = 0; unsigned int thread_id; enum sh_css_queue_id queue_id; @@ -3659,14 +3647,14 @@ ERR: } static int -create_host_acc_pipeline(struct ia_css_pipe *pipe) { +create_host_acc_pipeline(struct ia_css_pipe *pipe) +{ int err = 0; const struct ia_css_fw_info *fw; unsigned int i; IA_CSS_ENTER_PRIVATE("pipe = %p", pipe); - if ((!pipe) || (!pipe->stream)) - { + if ((!pipe) || (!pipe->stream)) { IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL); return -EINVAL; } @@ -3677,15 +3665,13 @@ create_host_acc_pipeline(struct ia_css_pipe *pipe) { pipe->pipeline.pipe_qos_config = 0; fw = pipe->vf_stage; - for (i = 0; fw; fw = fw->next) - { + for (i = 0; fw; fw = fw->next) { err = sh_css_pipeline_add_acc_stage(&pipe->pipeline, fw); if (err) goto ERR; } - for (i = 0; i < pipe->config.num_acc_stages; i++) - { + for (i = 0; i < pipe->config.num_acc_stages; i++) { struct ia_css_fw_info *fw = pipe->config.acc_stages[i]; err = sh_css_pipeline_add_acc_stage(&pipe->pipeline, fw); @@ -3702,7 +3688,8 @@ ERR: /* Create stages for preview */ static int -create_host_preview_pipeline(struct ia_css_pipe *pipe) { +create_host_preview_pipeline(struct ia_css_pipe *pipe) +{ struct ia_css_pipeline_stage *copy_stage = NULL; struct ia_css_pipeline_stage *preview_stage = NULL; struct ia_css_pipeline_stage *vf_pp_stage = NULL; @@ -3722,8 +3709,7 @@ create_host_preview_pipeline(struct ia_css_pipe *pipe) { #endif IA_CSS_ENTER_PRIVATE("pipe = %p", pipe); - if ((!pipe) || (!pipe->stream) || (pipe->mode != IA_CSS_PIPE_ID_PREVIEW)) - { + if ((!pipe) || (!pipe->stream) || (pipe->mode != IA_CSS_PIPE_ID_PREVIEW)) { IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL); return -EINVAL; } @@ -3751,16 +3737,14 @@ create_host_preview_pipeline(struct ia_css_pipe *pipe) { /* Construct in_frame info (only in case we have dynamic input */ need_in_frameinfo_memory = pipe->stream->config.mode == IA_CSS_INPUT_MODE_MEMORY; #endif - if (need_in_frameinfo_memory) - { + if (need_in_frameinfo_memory) { err = init_in_frameinfo_memory_defaults(pipe, &me->in_frame, IA_CSS_FRAME_FORMAT_RAW); if (err) goto ERR; in_frame = &me->in_frame; - } else - { + } else { in_frame = NULL; } @@ -3774,8 +3758,7 @@ create_host_preview_pipeline(struct ia_css_pipe *pipe) { if (pipe->pipe_settings.preview.vf_pp_binary.info) vf_pp_binary = &pipe->pipe_settings.preview.vf_pp_binary; - if (pipe->pipe_settings.preview.copy_binary.info) - { + if (pipe->pipe_settings.preview.copy_binary.info) { ia_css_pipe_util_set_output_frames(out_frames, 0, NULL); ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary, out_frames, NULL, NULL); @@ -3790,21 +3773,19 @@ create_host_preview_pipeline(struct ia_css_pipe *pipe) { /* When continuous is enabled, configure in_frame with the * last pipe, which is the copy pipe. */ - if (continuous || !online) { + if (continuous || !online) in_frame = pipe->stream->last_pipe->continuous_frames[0]; - } + #else in_frame = pipe->continuous_frames[0]; #endif } - if (vf_pp_binary) - { + if (vf_pp_binary) { ia_css_pipe_util_set_output_frames(out_frames, 0, NULL); ia_css_pipe_get_generic_stage_desc(&stage_desc, preview_binary, out_frames, in_frame, NULL); - } else - { + } else { ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame); ia_css_pipe_get_generic_stage_desc(&stage_desc, preview_binary, out_frames, in_frame, NULL); @@ -3818,14 +3799,12 @@ create_host_preview_pipeline(struct ia_css_pipe *pipe) { preview_stage->args.copy_vf = preview_binary->info->sp.pipeline.mode == IA_CSS_BINARY_MODE_COPY; preview_stage->args.copy_output = !preview_stage->args.copy_vf; - if (preview_stage->args.copy_vf && !preview_stage->args.out_vf_frame) - { + if (preview_stage->args.copy_vf && !preview_stage->args.out_vf_frame) { /* in case of copy, use the vf frame as output frame */ preview_stage->args.out_vf_frame = preview_stage->args.out_frame[0]; } - if (vf_pp_binary) - { + if (vf_pp_binary) { if (preview_binary->info->sp.pipeline.mode == IA_CSS_BINARY_MODE_COPY) in_frame = preview_stage->args.out_vf_frame; else @@ -3865,7 +3844,8 @@ static void send_raw_frames(struct ia_css_pipe *pipe) } static int -preview_start(struct ia_css_pipe *pipe) { +preview_start(struct ia_css_pipe *pipe) +{ int err = 0; struct ia_css_pipe *copy_pipe, *capture_pipe; struct ia_css_pipe *acc_pipe; @@ -3875,8 +3855,7 @@ preview_start(struct ia_css_pipe *pipe) { const struct ia_css_isp_parameters *params = NULL; IA_CSS_ENTER_PRIVATE("pipe = %p", pipe); - if ((!pipe) || (!pipe->stream) || (pipe->mode != IA_CSS_PIPE_ID_PREVIEW)) - { + if ((!pipe) || (!pipe->stream) || (pipe->mode != IA_CSS_PIPE_ID_PREVIEW)) { IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL); return -EINVAL; } @@ -3903,8 +3882,7 @@ preview_start(struct ia_css_pipe *pipe) { ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id); copy_ovrd = 1 << thread_id; - if (pipe->stream->cont_capt) - { + if (pipe->stream->cont_capt) { ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(capture_pipe), &thread_id); copy_ovrd |= 1 << thread_id; @@ -3917,8 +3895,7 @@ preview_start(struct ia_css_pipe *pipe) { } /* Construct and load the copy pipe */ - if (pipe->stream->config.continuous) - { + if (pipe->stream->config.continuous) { sh_css_sp_init_pipeline(©_pipe->pipeline, IA_CSS_PIPE_ID_COPY, (uint8_t)ia_css_pipe_get_pipe_num(copy_pipe), @@ -3939,8 +3916,7 @@ preview_start(struct ia_css_pipe *pipe) { } /* Construct and load the capture pipe */ - if (pipe->stream->cont_capt) - { + if (pipe->stream->cont_capt) { sh_css_sp_init_pipeline(&capture_pipe->pipeline, IA_CSS_PIPE_ID_CAPTURE, (uint8_t)ia_css_pipe_get_pipe_num(capture_pipe), @@ -3958,8 +3934,7 @@ preview_start(struct ia_css_pipe *pipe) { params); } - if (acc_pipe) - { + if (acc_pipe) { sh_css_sp_init_pipeline(&acc_pipe->pipeline, IA_CSS_PIPE_ID_ACC, (uint8_t)ia_css_pipe_get_pipe_num(acc_pipe), @@ -3985,7 +3960,8 @@ preview_start(struct ia_css_pipe *pipe) { int ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe, - const struct ia_css_buffer *buffer) { + const struct ia_css_buffer *buffer) +{ int return_err = 0; unsigned int thread_id; enum sh_css_queue_id queue_id; @@ -4000,8 +3976,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe, IA_CSS_ENTER("pipe=%p, buffer=%p", pipe, buffer); - if ((!pipe) || (!buffer)) - { + if ((!pipe) || (!buffer)) { IA_CSS_LEAVE_ERR(-EINVAL); return -EINVAL; } @@ -4010,8 +3985,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe, /* following code will be enabled when IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME is removed */ #if 0 - if (buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME) - { + if (buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME) { bool found_pipe = false; for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) { @@ -4025,8 +3999,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe, if (!found_pipe) return -EINVAL; } - if (buf_type == IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME) - { + if (buf_type == IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME) { bool found_pipe = false; for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) { @@ -4049,34 +4022,29 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe, assert(buf_type < IA_CSS_NUM_DYNAMIC_BUFFER_TYPE); if ((buf_type == IA_CSS_BUFFER_TYPE_INVALID) || (buf_type >= IA_CSS_NUM_DYNAMIC_BUFFER_TYPE) || - (pipe_id >= IA_CSS_PIPE_ID_NUM)) - { + (pipe_id >= IA_CSS_PIPE_ID_NUM)) { IA_CSS_LEAVE_ERR(-EINVAL); return -EINVAL; } ret_err = ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id); - if (!ret_err) - { + if (!ret_err) { IA_CSS_LEAVE_ERR(-EINVAL); return -EINVAL; } ret_err = ia_css_query_internal_queue_id(buf_type, thread_id, &queue_id); - if (!ret_err) - { + if (!ret_err) { IA_CSS_LEAVE_ERR(-EINVAL); return -EINVAL; } - if ((queue_id <= SH_CSS_INVALID_QUEUE_ID) || (queue_id >= SH_CSS_MAX_NUM_QUEUES)) - { + if ((queue_id <= SH_CSS_INVALID_QUEUE_ID) || (queue_id >= SH_CSS_MAX_NUM_QUEUES)) { IA_CSS_LEAVE_ERR(-EINVAL); return -EINVAL; } - if (!sh_css_sp_is_running()) - { + if (!sh_css_sp_is_running()) { IA_CSS_LOG("SP is not running!"); IA_CSS_LEAVE_ERR(-EBUSY); /* SP is not running. The queues are not valid */ @@ -4094,24 +4062,21 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe, ddr_buffer.cookie_ptr = buffer->driver_cookie; ddr_buffer.timing_data = buffer->timing_data; - if (buf_type == IA_CSS_BUFFER_TYPE_3A_STATISTICS) - { + if (buf_type == IA_CSS_BUFFER_TYPE_3A_STATISTICS) { if (!buffer->data.stats_3a) { IA_CSS_LEAVE_ERR(-EINVAL); return -EINVAL; } ddr_buffer.kernel_ptr = HOST_ADDRESS(buffer->data.stats_3a); ddr_buffer.payload.s3a = *buffer->data.stats_3a; - } else if (buf_type == IA_CSS_BUFFER_TYPE_DIS_STATISTICS) - { + } else if (buf_type == IA_CSS_BUFFER_TYPE_DIS_STATISTICS) { if (!buffer->data.stats_dvs) { IA_CSS_LEAVE_ERR(-EINVAL); return -EINVAL; } ddr_buffer.kernel_ptr = HOST_ADDRESS(buffer->data.stats_dvs); ddr_buffer.payload.dis = *buffer->data.stats_dvs; - } else if (buf_type == IA_CSS_BUFFER_TYPE_METADATA) - { + } else if (buf_type == IA_CSS_BUFFER_TYPE_METADATA) { if (!buffer->data.metadata) { IA_CSS_LEAVE_ERR(-EINVAL); return -EINVAL; @@ -4122,8 +4087,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe, || (buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME) || (buf_type == IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME) || (buf_type == IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME) - || (buf_type == IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME)) - { + || (buf_type == IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME)) { if (!buffer->data.frame) { IA_CSS_LEAVE_ERR(-EINVAL); return -EINVAL; @@ -4158,8 +4122,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe, assert(h_vbuf); assert(h_vbuf->vptr != 0x0); - if ((!h_vbuf) || (h_vbuf->vptr == 0x0)) - { + if ((!h_vbuf) || (h_vbuf->vptr == 0x0)) { IA_CSS_LEAVE_ERR(-EINVAL); return -EINVAL; } @@ -4169,8 +4132,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe, sizeof(struct sh_css_hmm_buffer)); if ((buf_type == IA_CSS_BUFFER_TYPE_3A_STATISTICS) || (buf_type == IA_CSS_BUFFER_TYPE_DIS_STATISTICS) - || (buf_type == IA_CSS_BUFFER_TYPE_LACE_STATISTICS)) - { + || (buf_type == IA_CSS_BUFFER_TYPE_LACE_STATISTICS)) { if (!pipeline) { ia_css_rmgr_rel_vbuf(hmm_buffer_pool, &h_vbuf); IA_CSS_LOG("pipeline is empty!"); @@ -4193,8 +4155,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe, || (buf_type == IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME) || (buf_type == IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME) || (buf_type == IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME) - || (buf_type == IA_CSS_BUFFER_TYPE_METADATA)) - { + || (buf_type == IA_CSS_BUFFER_TYPE_METADATA)) { return_err = ia_css_bufq_enqueue_buffer(thread_id, queue_id, (uint32_t)h_vbuf->vptr); @@ -4208,8 +4169,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe, #endif } - if (!return_err) - { + if (!return_err) { if (sh_css_hmm_buffer_record_acquire( h_vbuf, buf_type, HOST_ADDRESS(ddr_buffer.kernel_ptr))) { @@ -4224,8 +4184,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe, * Tell the SP which queues are not empty, * by sending the software event. */ - if (!return_err) - { + if (!return_err) { if (!sh_css_sp_is_running()) { /* SP is not running. The queues are not valid */ IA_CSS_LOG("SP is not running!"); @@ -4237,8 +4196,7 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe, (uint8_t)thread_id, queue_id, 0); - } else - { + } else { ia_css_rmgr_rel_vbuf(hmm_buffer_pool, &h_vbuf); IA_CSS_ERROR("buffer not enqueued"); } @@ -4253,7 +4211,8 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe, */ int ia_css_pipe_dequeue_buffer(struct ia_css_pipe *pipe, - struct ia_css_buffer *buffer) { + struct ia_css_buffer *buffer) +{ int return_err; enum sh_css_queue_id queue_id; ia_css_ptr ddr_buffer_addr = (ia_css_ptr)0; @@ -4266,8 +4225,7 @@ ia_css_pipe_dequeue_buffer(struct ia_css_pipe *pipe, IA_CSS_ENTER("pipe=%p, buffer=%p", pipe, buffer); - if ((!pipe) || (!buffer)) - { + if ((!pipe) || (!buffer)) { IA_CSS_LEAVE_ERR(-EINVAL); return -EINVAL; } @@ -4281,27 +4239,23 @@ ia_css_pipe_dequeue_buffer(struct ia_css_pipe *pipe, ddr_buffer.kernel_ptr = 0; ret_err = ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id); - if (!ret_err) - { + if (!ret_err) { IA_CSS_LEAVE_ERR(-EINVAL); return -EINVAL; } ret_err = ia_css_query_internal_queue_id(buf_type, thread_id, &queue_id); - if (!ret_err) - { + if (!ret_err) { IA_CSS_LEAVE_ERR(-EINVAL); return -EINVAL; } - if ((queue_id <= SH_CSS_INVALID_QUEUE_ID) || (queue_id >= SH_CSS_MAX_NUM_QUEUES)) - { + if ((queue_id <= SH_CSS_INVALID_QUEUE_ID) || (queue_id >= SH_CSS_MAX_NUM_QUEUES)) { IA_CSS_LEAVE_ERR(-EINVAL); return -EINVAL; } - if (!sh_css_sp_is_running()) - { + if (!sh_css_sp_is_running()) { IA_CSS_LOG("SP is not running!"); IA_CSS_LEAVE_ERR(-EBUSY); /* SP is not running. The queues are not valid */ @@ -4311,8 +4265,7 @@ ia_css_pipe_dequeue_buffer(struct ia_css_pipe *pipe, return_err = ia_css_bufq_dequeue_buffer(queue_id, (uint32_t *)&ddr_buffer_addr); - if (!return_err) - { + if (!return_err) { struct ia_css_frame *frame; struct sh_css_hmm_buffer_record *hmm_buffer_record = NULL; @@ -4454,8 +4407,7 @@ ia_css_pipe_dequeue_buffer(struct ia_css_pipe *pipe, * Tell the SP which queues are not full, * by sending the software event. */ - if (!return_err) - { + if (!return_err) { if (!sh_css_sp_is_running()) { IA_CSS_LOG("SP is not running!"); IA_CSS_LEAVE_ERR(-EBUSY); @@ -4504,12 +4456,14 @@ static enum ia_css_event_type convert_event_sp_to_host_domain[] = { }; int -ia_css_dequeue_event(struct ia_css_event *event) { +ia_css_dequeue_event(struct ia_css_event *event) +{ return ia_css_dequeue_psys_event(event); } int -ia_css_dequeue_psys_event(struct ia_css_event *event) { +ia_css_dequeue_psys_event(struct ia_css_event *event) +{ enum ia_css_pipe_id pipe_id = 0; u8 payload[4] = {0, 0, 0, 0}; int ret_err; @@ -4524,11 +4478,9 @@ ia_css_dequeue_psys_event(struct ia_css_event *event) { if (!event) return -EINVAL; + /* SP is not running. The queues are not valid */ if (!sh_css_sp_is_running()) - { - /* SP is not running. The queues are not valid */ return -EBUSY; - } /* dequeue the event (if any) from the psys event queue */ ret_err = ia_css_bufq_dequeue_psys_event(payload); @@ -4555,8 +4507,7 @@ ia_css_dequeue_psys_event(struct ia_css_event *event) { event->timer_code = 0; event->timer_subcode = 0; - if (event->type == IA_CSS_EVENT_TYPE_TIMER) - { + if (event->type == IA_CSS_EVENT_TYPE_TIMER) { /* timer event ??? get the 2nd event and decode the data into the event struct */ u32 tmp_data; /* 1st event: LSB 16-bit timer data and code */ @@ -4580,37 +4531,32 @@ ia_css_dequeue_psys_event(struct ia_css_event *event) { tmp_data = ((payload[1] & 0xFF) | ((payload[3] & 0xFF) << 8)); event->timer_data |= (tmp_data << 16); event->timer_subcode = payload[2]; - } + } else { /* It's a non timer event. So clear first half of the timer event data. * If the second part of the TIMER event is not received, we discard * the first half of the timer data and process the non timer event without * affecting the flow. So the non timer event falls through * the code. */ - else { event->timer_data = 0; event->timer_code = 0; event->timer_subcode = 0; IA_CSS_ERROR("Missing 2nd timer event. Timer event discarded"); } } - if (event->type == IA_CSS_EVENT_TYPE_PORT_EOF) - { + if (event->type == IA_CSS_EVENT_TYPE_PORT_EOF) { event->port = (enum mipi_port_id)payload[1]; event->exp_id = payload[3]; - } else if (event->type == IA_CSS_EVENT_TYPE_FW_WARNING) - { + } else if (event->type == IA_CSS_EVENT_TYPE_FW_WARNING) { event->fw_warning = (enum ia_css_fw_warning)payload[1]; /* exp_id is only available in these warning types */ if (event->fw_warning == IA_CSS_FW_WARNING_EXP_ID_LOCKED || event->fw_warning == IA_CSS_FW_WARNING_TAG_EXP_ID_FAILED) event->exp_id = payload[3]; - } else if (event->type == IA_CSS_EVENT_TYPE_FW_ASSERT) - { + } else if (event->type == IA_CSS_EVENT_TYPE_FW_ASSERT) { event->fw_assert_module_id = payload[1]; /* module */ event->fw_assert_line_no = (payload[2] << 8) + payload[3]; /* payload[2] is line_no>>8, payload[3] is line_no&0xff */ - } else if (event->type != IA_CSS_EVENT_TYPE_TIMER) - { + } else if (event->type != IA_CSS_EVENT_TYPE_TIMER) { /* pipe related events. * payload[1] contains the pipe_num, * payload[2] contains the pipe_id. These are different. */ @@ -4660,7 +4606,8 @@ ia_css_dequeue_psys_event(struct ia_css_event *event) { } int -ia_css_dequeue_isys_event(struct ia_css_event *event) { +ia_css_dequeue_isys_event(struct ia_css_event *event) +{ u8 payload[4] = {0, 0, 0, 0}; int err = 0; @@ -4670,11 +4617,9 @@ ia_css_dequeue_isys_event(struct ia_css_event *event) { if (!event) return -EINVAL; + /* SP is not running. The queues are not valid */ if (!sh_css_sp_is_running()) - { - /* SP is not running. The queues are not valid */ return -EBUSY; - } err = ia_css_bufq_dequeue_isys_event(payload); if (err) @@ -4707,7 +4652,8 @@ acc_start(struct ia_css_pipe *pipe) } static int -sh_css_pipe_start(struct ia_css_stream *stream) { +sh_css_pipe_start(struct ia_css_stream *stream) +{ int err = 0; struct ia_css_pipe *pipe; @@ -4716,22 +4662,19 @@ sh_css_pipe_start(struct ia_css_stream *stream) { IA_CSS_ENTER_PRIVATE("stream = %p", stream); - if (!stream) - { + if (!stream) { IA_CSS_LEAVE_ERR(-EINVAL); return -EINVAL; } pipe = stream->last_pipe; - if (!pipe) - { + if (!pipe) { IA_CSS_LEAVE_ERR(-EINVAL); return -EINVAL; } pipe_id = pipe->mode; - if (stream->started) - { + if (stream->started) { IA_CSS_WARNING("Cannot start stream that is already started"); IA_CSS_LEAVE_ERR(err); return err; @@ -4739,8 +4682,7 @@ sh_css_pipe_start(struct ia_css_stream *stream) { pipe->stop_requested = false; - switch (pipe_id) - { + switch (pipe_id) { case IA_CSS_PIPE_ID_PREVIEW: err = preview_start(pipe); break; @@ -4760,8 +4702,7 @@ sh_css_pipe_start(struct ia_css_stream *stream) { err = -EINVAL; } /* DH regular multi pipe - not continuous mode: start the next pipes too */ - if (!stream->config.continuous) - { + if (!stream->config.continuous) { int i; for (i = 1; i < stream->num_pipes && 0 == err ; i++) { @@ -4791,8 +4732,7 @@ sh_css_pipe_start(struct ia_css_stream *stream) { } } } - if (err) - { + if (err) { IA_CSS_LEAVE_ERR_PRIVATE(err); return err; } @@ -4802,8 +4742,7 @@ sh_css_pipe_start(struct ia_css_stream *stream) { * don't use ISP parameters anyway. So this should be okay. * The SP binary (jpeg) copy does not use any parameters. */ - if (!copy_on_sp(pipe)) - { + if (!copy_on_sp(pipe)) { sh_css_invalidate_params(stream); err = sh_css_param_update_isp_params(pipe, stream->isp_params_configs, true, NULL); @@ -4817,8 +4756,7 @@ sh_css_pipe_start(struct ia_css_stream *stream) { ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id); - if (!sh_css_sp_is_running()) - { + if (!sh_css_sp_is_running()) { IA_CSS_LEAVE_ERR_PRIVATE(-EBUSY); /* SP is not running. The queues are not valid */ return -EBUSY; @@ -4827,8 +4765,7 @@ sh_css_pipe_start(struct ia_css_stream *stream) { (uint8_t)thread_id, 0, 0); /* DH regular multi pipe - not continuous mode: enqueue event to the next pipes too */ - if (!stream->config.continuous) - { + if (!stream->config.continuous) { int i; for (i = 1; i < stream->num_pipes; i++) { @@ -4842,8 +4779,7 @@ sh_css_pipe_start(struct ia_css_stream *stream) { } /* in case of continuous capture mode, we also start capture thread and copy thread*/ - if (pipe->stream->config.continuous) - { + if (pipe->stream->config.continuous) { struct ia_css_pipe *copy_pipe = NULL; if (pipe_id == IA_CSS_PIPE_ID_PREVIEW) @@ -4862,8 +4798,7 @@ sh_css_pipe_start(struct ia_css_stream *stream) { IA_CSS_PSYS_SW_EVENT_START_STREAM, (uint8_t)thread_id, 0, 0); } - if (pipe->stream->cont_capt) - { + if (pipe->stream->cont_capt) { struct ia_css_pipe *capture_pipe = NULL; if (pipe_id == IA_CSS_PIPE_ID_PREVIEW) @@ -4884,8 +4819,7 @@ sh_css_pipe_start(struct ia_css_stream *stream) { } /* in case of PREVIEW mode, check whether QOS acc_pipe is available, then start the qos pipe */ - if (pipe_id == IA_CSS_PIPE_ID_PREVIEW) - { + if (pipe_id == IA_CSS_PIPE_ID_PREVIEW) { struct ia_css_pipe *acc_pipe = NULL; acc_pipe = pipe->pipe_settings.preview.acc_pipe; @@ -4936,7 +4870,8 @@ sh_css_continuous_is_enabled(uint8_t pipe_num) /* ISP2400 */ int ia_css_stream_get_max_buffer_depth(struct ia_css_stream *stream, - int *buffer_depth) { + int *buffer_depth) +{ if (!buffer_depth) return -EINVAL; ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_get_max_buffer_depth() enter: void\n"); @@ -4946,7 +4881,8 @@ ia_css_stream_get_max_buffer_depth(struct ia_css_stream *stream, } int -ia_css_stream_set_buffer_depth(struct ia_css_stream *stream, int buffer_depth) { +ia_css_stream_set_buffer_depth(struct ia_css_stream *stream, int buffer_depth) +{ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_set_buffer_depth() enter: num_frames=%d\n", buffer_depth); (void)stream; if (buffer_depth > NUM_CONTINUOUS_FRAMES || buffer_depth < 1) @@ -4960,7 +4896,8 @@ ia_css_stream_set_buffer_depth(struct ia_css_stream *stream, int buffer_depth) { /* ISP2401 */ int ia_css_stream_get_buffer_depth(struct ia_css_stream *stream, - int *buffer_depth) { + int *buffer_depth) +{ if (!buffer_depth) return -EINVAL; ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_get_buffer_depth() enter: void\n"); @@ -4985,8 +4922,7 @@ sh_css_pipes_stop(struct ia_css_stream *stream) int i; assert(stream); - if (!stream) - { + if (!stream) { IA_CSS_LOG("stream does NOT exist!"); err = -EINVAL; goto ERR; @@ -4994,8 +4930,7 @@ sh_css_pipes_stop(struct ia_css_stream *stream) main_pipe = stream->last_pipe; assert(main_pipe); - if (!main_pipe) - { + if (!main_pipe) { IA_CSS_LOG("main_pipe does NOT exist!"); err = -EINVAL; goto ERR; @@ -5008,8 +4943,7 @@ sh_css_pipes_stop(struct ia_css_stream *stream) * Stop all "ia_css_pipe" instances in this target * "ia_css_stream" instance. */ - for (i = 0; i < stream->num_pipes; i++) - { + for (i = 0; i < stream->num_pipes; i++) { /* send the "stop" request to the "ia_css_pipe" instance */ IA_CSS_LOG("Send the stop-request to the pipe: pipe_id=%d", stream->pipes[i]->pipeline.pipe_id); @@ -5043,8 +4977,7 @@ sh_css_pipes_stop(struct ia_css_stream *stream) * * We need to stop this "Copy Pipe", as well. */ - if (main_pipe->stream->config.continuous) - { + if (main_pipe->stream->config.continuous) { struct ia_css_pipe *copy_pipe = NULL; /* get the reference to "Copy Pipe" */ @@ -5220,8 +5153,7 @@ sh_css_pipe_get_shading_info(struct ia_css_pipe *pipe, binary = ia_css_pipe_get_shading_correction_binary(pipe); - if (binary) - { + if (binary) { err = ia_css_binary_get_shading_info(binary, IA_CSS_SHADING_CORRECTION_TYPE_1, pipe->required_bds_factor, @@ -5231,8 +5163,7 @@ sh_css_pipe_get_shading_info(struct ia_css_pipe *pipe, /* Other function calls can be added here when other shading correction types will be added * in the future. */ - } else - { + } else { /* When the pipe does not have a binary which has the shading * correction, this function does not need to fill the shading * information. It is not a error case, and then @@ -5245,7 +5176,8 @@ sh_css_pipe_get_shading_info(struct ia_css_pipe *pipe, static int sh_css_pipe_get_grid_info(struct ia_css_pipe *pipe, - struct ia_css_grid_info *info) { + struct ia_css_grid_info *info) +{ int err = 0; struct ia_css_binary *binary = NULL; @@ -5256,30 +5188,27 @@ sh_css_pipe_get_grid_info(struct ia_css_pipe *pipe, binary = ia_css_pipe_get_s3a_binary(pipe); - if (binary) - { + if (binary) { err = ia_css_binary_3a_grid_info(binary, info, pipe); if (err) goto ERR; - } else + } else { memset(&info->s3a_grid, 0, sizeof(info->s3a_grid)); + } binary = ia_css_pipe_get_sdis_binary(pipe); - if (binary) - { + if (binary) { ia_css_binary_dvs_grid_info(binary, info, pipe); ia_css_binary_dvs_stat_grid_info(binary, info, pipe); - } else - { + } else { memset(&info->dvs_grid.dvs_grid_info, 0, sizeof(info->dvs_grid.dvs_grid_info)); memset(&info->dvs_grid.dvs_stat_grid_info, 0, sizeof(info->dvs_grid.dvs_stat_grid_info)); } - if (binary) - { + if (binary) { /* copy pipe does not have ISP binary*/ info->isp_in_width = binary->internal_frame_info.res.width; info->isp_in_height = binary->internal_frame_info.res.height; @@ -5299,7 +5228,8 @@ ERR : */ static int ia_css_pipe_check_format(struct ia_css_pipe *pipe, - enum ia_css_frame_format format) { + enum ia_css_frame_format format) +{ const enum ia_css_frame_format *supported_formats; int number_of_formats; int found = 0; @@ -5307,8 +5237,7 @@ ia_css_pipe_check_format(struct ia_css_pipe *pipe, IA_CSS_ENTER_PRIVATE(""); - if (NULL == pipe || NULL == pipe->pipe_settings.video.video_binary.info) - { + if (NULL == pipe || NULL == pipe->pipe_settings.video.video_binary.info) { IA_CSS_ERROR("Pipe or binary info is not set"); IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL); return -EINVAL; @@ -5317,15 +5246,13 @@ ia_css_pipe_check_format(struct ia_css_pipe *pipe, supported_formats = pipe->pipe_settings.video.video_binary.info->output_formats; number_of_formats = sizeof(pipe->pipe_settings.video.video_binary.info->output_formats) / sizeof(enum ia_css_frame_format); - for (i = 0; i < number_of_formats && !found; i++) - { + for (i = 0; i < number_of_formats && !found; i++) { if (supported_formats[i] == format) { found = 1; break; } } - if (!found) - { + if (!found) { IA_CSS_ERROR("Requested format is not supported by binary"); IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL); return -EINVAL; @@ -5476,10 +5403,10 @@ static int load_video_binaries(struct ia_css_pipe *pipe) &mycs->video_binary); if (err) { - if (video_vf_info) { - /* This will do another video binary lookup later for YUV_LINE format*/ + /* This will do another video binary lookup later for YUV_LINE format*/ + if (video_vf_info) need_vf_pp = true; - } else + else return err; } else if (video_vf_info) { /* The first video binary lookup is successful, but we may @@ -5642,13 +5569,13 @@ static int load_video_binaries(struct ia_css_pipe *pipe) } static int -unload_video_binaries(struct ia_css_pipe *pipe) { +unload_video_binaries(struct ia_css_pipe *pipe) +{ unsigned int i; IA_CSS_ENTER_PRIVATE("pipe = %p", pipe); - if ((!pipe) || (pipe->mode != IA_CSS_PIPE_ID_VIDEO)) - { + if ((!pipe) || (pipe->mode != IA_CSS_PIPE_ID_VIDEO)) { IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL); return -EINVAL; } @@ -5798,31 +5725,29 @@ static int sh_css_pipe_configure_viewfinder(struct ia_css_pipe *pipe, unsigned int width, unsigned int height, unsigned int min_width, enum ia_css_frame_format format, - unsigned int idx) { + unsigned int idx) +{ int err = 0; IA_CSS_ENTER_PRIVATE("pipe = %p, width = %d, height = %d, min_width = %d, format = %d, idx = %d\n", pipe, width, height, min_width, format, idx); - if (!pipe) - { + if (!pipe) { IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL); return -EINVAL; } err = ia_css_util_check_res(width, height); - if (err) - { + if (err) { IA_CSS_LEAVE_ERR_PRIVATE(err); return err; } if (pipe->vf_output_info[idx].res.width != width || pipe->vf_output_info[idx].res.height != height || pipe->vf_output_info[idx].format != format) - { ia_css_frame_info_init(&pipe->vf_output_info[idx], width, height, format, min_width); - } + IA_CSS_LEAVE_ERR_PRIVATE(0); return 0; } @@ -6202,7 +6127,8 @@ static int load_primary_binaries( } static int -allocate_delay_frames(struct ia_css_pipe *pipe) { +allocate_delay_frames(struct ia_css_pipe *pipe) +{ unsigned int num_delay_frames = 0, i = 0; unsigned int dvs_frame_delay = 0; struct ia_css_frame_info ref_info; @@ -6212,8 +6138,7 @@ allocate_delay_frames(struct ia_css_pipe *pipe) { IA_CSS_ENTER_PRIVATE(""); - if (!pipe) - { + if (!pipe) { IA_CSS_ERROR("Invalid args - pipe %p", pipe); return -EINVAL; } @@ -6224,8 +6149,7 @@ allocate_delay_frames(struct ia_css_pipe *pipe) { if (dvs_frame_delay > 0) num_delay_frames = dvs_frame_delay + 1; - switch (mode) - { + switch (mode) { case IA_CSS_PIPE_ID_CAPTURE: { struct ia_css_capture_settings *mycs_capture = &pipe->pipe_settings.capture; (void)mycs_capture; @@ -6277,8 +6201,7 @@ allocate_delay_frames(struct ia_css_pipe *pipe) { ref_info.raw_bit_depth = SH_CSS_REF_BIT_DEPTH; assert(num_delay_frames <= MAX_NUM_VIDEO_DELAY_FRAMES); - for (i = 0; i < num_delay_frames; i++) - { + for (i = 0; i < num_delay_frames; i++) { err = ia_css_frame_allocate_from_info(&delay_frames[i], &ref_info); if (err) return err; @@ -6288,7 +6211,8 @@ allocate_delay_frames(struct ia_css_pipe *pipe) { } static int load_advanced_binaries( - struct ia_css_pipe *pipe) { + struct ia_css_pipe *pipe) +{ struct ia_css_frame_info pre_in_info, gdc_in_info, post_in_info, post_out_info, vf_info, *vf_pp_in_info, *pipe_out_info, @@ -6405,7 +6329,8 @@ static int load_advanced_binaries( } static int load_bayer_isp_binaries( - struct ia_css_pipe *pipe) { + struct ia_css_pipe *pipe) +{ struct ia_css_frame_info pre_isp_in_info, *pipe_out_info; int err = 0; struct ia_css_binary_descr pre_de_descr; @@ -6434,7 +6359,8 @@ static int load_bayer_isp_binaries( } static int load_low_light_binaries( - struct ia_css_pipe *pipe) { + struct ia_css_pipe *pipe) +{ struct ia_css_frame_info pre_in_info, anr_in_info, post_in_info, post_out_info, vf_info, *pipe_vf_out_info, *pipe_out_info, @@ -6572,7 +6498,8 @@ static bool copy_on_sp(struct ia_css_pipe *pipe) } static int load_capture_binaries( - struct ia_css_pipe *pipe) { + struct ia_css_pipe *pipe) +{ int err = 0; bool must_be_raw; @@ -6640,13 +6567,13 @@ static int load_capture_binaries( } static int -unload_capture_binaries(struct ia_css_pipe *pipe) { +unload_capture_binaries(struct ia_css_pipe *pipe) +{ unsigned int i; IA_CSS_ENTER_PRIVATE("pipe = %p", pipe); - if ((!pipe) || ((pipe->mode != IA_CSS_PIPE_ID_CAPTURE) && (pipe->mode != IA_CSS_PIPE_ID_COPY))) - { + if ((!pipe) || ((pipe->mode != IA_CSS_PIPE_ID_CAPTURE) && (pipe->mode != IA_CSS_PIPE_ID_COPY))) { IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL); return -EINVAL; } @@ -6674,7 +6601,8 @@ unload_capture_binaries(struct ia_css_pipe *pipe) { static bool need_downscaling(const struct ia_css_resolution in_res, - const struct ia_css_resolution out_res) { + const struct ia_css_resolution out_res) +{ if (in_res.width > out_res.width || in_res.height > out_res.height) return true; @@ -6682,7 +6610,8 @@ need_downscaling(const struct ia_css_resolution in_res, } static bool -need_yuv_scaler_stage(const struct ia_css_pipe *pipe) { +need_yuv_scaler_stage(const struct ia_css_pipe *pipe) +{ unsigned int i; struct ia_css_resolution in_res, out_res; @@ -6724,7 +6653,8 @@ static int ia_css_pipe_create_cas_scaler_desc_single_output( struct ia_css_frame_info *cas_scaler_in_info, struct ia_css_frame_info *cas_scaler_out_info, struct ia_css_frame_info *cas_scaler_vf_info, - struct ia_css_cas_binary_descr *descr) { + struct ia_css_cas_binary_descr *descr) +{ unsigned int i; unsigned int hor_ds_factor = 0, ver_ds_factor = 0; int err = 0; @@ -6842,7 +6772,8 @@ ERR: /* FIXME: merge most of this and single output version */ static int ia_css_pipe_create_cas_scaler_desc( struct ia_css_pipe *pipe, - struct ia_css_cas_binary_descr *descr) { + struct ia_css_cas_binary_descr *descr) +{ struct ia_css_frame_info in_info = IA_CSS_BINARY_DEFAULT_FRAME_INFO; struct ia_css_frame_info *out_info[IA_CSS_PIPE_MAX_OUTPUT_STAGE]; struct ia_css_frame_info *vf_out_info[IA_CSS_PIPE_MAX_OUTPUT_STAGE]; @@ -6998,7 +6929,8 @@ ERR: } static void ia_css_pipe_destroy_cas_scaler_desc(struct ia_css_cas_binary_descr - *descr) { + *descr) +{ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_pipe_destroy_cas_scaler_desc() enter:\n"); kfree(descr->in_info); @@ -7016,7 +6948,8 @@ static void ia_css_pipe_destroy_cas_scaler_desc(struct ia_css_cas_binary_descr } static int -load_yuvpp_binaries(struct ia_css_pipe *pipe) { +load_yuvpp_binaries(struct ia_css_pipe *pipe) +{ int err = 0; bool need_scaler = false; struct ia_css_frame_info *vf_pp_in_info[IA_CSS_PIPE_MAX_OUTPUT_STAGE]; @@ -7041,8 +6974,7 @@ load_yuvpp_binaries(struct ia_css_pipe *pipe) { mycs = &pipe->pipe_settings.yuvpp; - for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) - { + for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) { if (pipe->vf_output_info[i].res.width != 0) { err = ia_css_util_check_vf_out_info(&pipe->output_info[i], &pipe->vf_output_info[i]); @@ -7056,8 +6988,7 @@ load_yuvpp_binaries(struct ia_css_pipe *pipe) { /* we build up the pipeline starting at the end */ /* Capture post-processing */ - if (need_scaler) - { + if (need_scaler) { struct ia_css_binary_descr yuv_scaler_descr; err = ia_css_pipe_create_cas_scaler_desc(pipe, @@ -7091,18 +7022,14 @@ load_yuvpp_binaries(struct ia_css_pipe *pipe) { goto ERR; } ia_css_pipe_destroy_cas_scaler_desc(&cas_scaler_descr); - } else - { + } else { mycs->num_output = 1; } if (need_scaler) - { next_binary = &mycs->yuv_scaler_binary[0]; - } else - { + else next_binary = NULL; - } #if defined(ISP2401) /* @@ -7128,8 +7055,7 @@ load_yuvpp_binaries(struct ia_css_pipe *pipe) { need_isp_copy_binary = true; #endif /* ISP2401 */ - if (need_isp_copy_binary) - { + if (need_isp_copy_binary) { err = load_copy_binary(pipe, &mycs->copy_binary, next_binary); @@ -7159,8 +7085,7 @@ load_yuvpp_binaries(struct ia_css_pipe *pipe) { } /* Viewfinder post-processing */ - if (need_scaler) - { + if (need_scaler) { for (i = 0, j = 0; i < mycs->num_yuv_scaler; i++) { if (mycs->is_output_stage[i]) { assert(j < 2); @@ -7170,19 +7095,17 @@ load_yuvpp_binaries(struct ia_css_pipe *pipe) { } } mycs->num_vf_pp = j; - } else - { + } else { vf_pp_in_info[0] = &mycs->copy_binary.vf_frame_info; - for (i = 1; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) { + for (i = 1; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) vf_pp_in_info[i] = NULL; - } + mycs->num_vf_pp = 1; } mycs->vf_pp_binary = kzalloc(mycs->num_vf_pp * sizeof(struct ia_css_binary), GFP_KERNEL); - if (!mycs->vf_pp_binary) - { + if (!mycs->vf_pp_binary) { err = -ENOMEM; goto ERR; } @@ -7190,8 +7113,7 @@ load_yuvpp_binaries(struct ia_css_pipe *pipe) { { struct ia_css_binary_descr vf_pp_descr; - for (i = 0; i < mycs->num_vf_pp; i++) - { + for (i = 0; i < mycs->num_vf_pp; i++) { if (pipe->vf_output_info[i].res.width != 0) { ia_css_pipe_get_vfpp_binarydesc(pipe, &vf_pp_descr, vf_pp_in_info[i], &pipe->vf_output_info[i]); @@ -7207,34 +7129,31 @@ load_yuvpp_binaries(struct ia_css_pipe *pipe) { ERR: if (need_scaler) - { ia_css_pipe_destroy_cas_scaler_desc(&cas_scaler_descr); - } + ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "load_yuvpp_binaries() leave, err=%d\n", err); return err; } static int -unload_yuvpp_binaries(struct ia_css_pipe *pipe) { +unload_yuvpp_binaries(struct ia_css_pipe *pipe) +{ unsigned int i; IA_CSS_ENTER_PRIVATE("pipe = %p", pipe); - if ((!pipe) || (pipe->mode != IA_CSS_PIPE_ID_YUVPP)) - { + if ((!pipe) || (pipe->mode != IA_CSS_PIPE_ID_YUVPP)) { IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL); return -EINVAL; } ia_css_binary_unload(&pipe->pipe_settings.yuvpp.copy_binary); for (i = 0; i < pipe->pipe_settings.yuvpp.num_yuv_scaler; i++) - { ia_css_binary_unload(&pipe->pipe_settings.yuvpp.yuv_scaler_binary[i]); - } + for (i = 0; i < pipe->pipe_settings.yuvpp.num_vf_pp; i++) - { ia_css_binary_unload(&pipe->pipe_settings.yuvpp.vf_pp_binary[i]); - } + kfree(pipe->pipe_settings.yuvpp.is_output_stage); pipe->pipe_settings.yuvpp.is_output_stage = NULL; kfree(pipe->pipe_settings.yuvpp.yuv_scaler_binary); @@ -7284,25 +7203,23 @@ static int yuvpp_start(struct ia_css_pipe *pipe) } static int -sh_css_pipe_unload_binaries(struct ia_css_pipe *pipe) { +sh_css_pipe_unload_binaries(struct ia_css_pipe *pipe) +{ int err = 0; IA_CSS_ENTER_PRIVATE("pipe = %p", pipe); - if (!pipe) - { + if (!pipe) { IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL); return -EINVAL; } /* PIPE_MODE_COPY has no binaries, but has output frames to outside*/ - if (pipe->config.mode == IA_CSS_PIPE_MODE_COPY) - { + if (pipe->config.mode == IA_CSS_PIPE_MODE_COPY) { IA_CSS_LEAVE_ERR_PRIVATE(0); return 0; } - switch (pipe->mode) - { + switch (pipe->mode) { case IA_CSS_PIPE_ID_PREVIEW: err = unload_preview_binaries(pipe); break; @@ -7323,7 +7240,8 @@ sh_css_pipe_unload_binaries(struct ia_css_pipe *pipe) { } static int -sh_css_pipe_load_binaries(struct ia_css_pipe *pipe) { +sh_css_pipe_load_binaries(struct ia_css_pipe *pipe) +{ int err = 0; assert(pipe); @@ -7333,8 +7251,7 @@ sh_css_pipe_load_binaries(struct ia_css_pipe *pipe) { if (pipe->config.mode == IA_CSS_PIPE_MODE_COPY) return err; - switch (pipe->mode) - { + switch (pipe->mode) { case IA_CSS_PIPE_ID_PREVIEW: err = load_preview_binaries(pipe); break; @@ -7353,8 +7270,7 @@ sh_css_pipe_load_binaries(struct ia_css_pipe *pipe) { err = -EINVAL; break; } - if (err) - { + if (err) { if (sh_css_pipe_unload_binaries(pipe)) { /* currently css does not support multiple error returns in a single function, * using -EINVAL in this case */ @@ -7365,7 +7281,8 @@ sh_css_pipe_load_binaries(struct ia_css_pipe *pipe) { } static int -create_host_yuvpp_pipeline(struct ia_css_pipe *pipe) { +create_host_yuvpp_pipeline(struct ia_css_pipe *pipe) +{ struct ia_css_pipeline *me; int err = 0; struct ia_css_pipeline_stage *vf_pp_stage = NULL, @@ -7392,15 +7309,13 @@ create_host_yuvpp_pipeline(struct ia_css_pipe *pipe) { #endif IA_CSS_ENTER_PRIVATE("pipe = %p", pipe); - if ((!pipe) || (!pipe->stream) || (pipe->mode != IA_CSS_PIPE_ID_YUVPP)) - { + if ((!pipe) || (!pipe->stream) || (pipe->mode != IA_CSS_PIPE_ID_YUVPP)) { IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL); return -EINVAL; } me = &pipe->pipeline; ia_css_pipeline_clean(me); - for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) - { + for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) { out_frame[i] = NULL; vf_frame[i] = NULL; } @@ -7428,8 +7343,7 @@ create_host_yuvpp_pipeline(struct ia_css_pipe *pipe) { /* the input frame can come from: * a) memory: connect yuvscaler to me->in_frame * b) sensor, via copy binary: connect yuvscaler to copy binary later on */ - if (need_in_frameinfo_memory) - { + if (need_in_frameinfo_memory) { /* TODO: improve for different input formats. */ /* @@ -7478,13 +7392,11 @@ create_host_yuvpp_pipeline(struct ia_css_pipe *pipe) { } in_frame = &me->in_frame; - } else - { + } else { in_frame = NULL; } - for (i = 0; i < num_output_stage; i++) - { + for (i = 0; i < num_output_stage; i++) { assert(i < IA_CSS_PIPE_MAX_OUTPUT_STAGE); if (pipe->output_info[i].res.width != 0) { err = init_out_frameinfo_defaults(pipe, &me->out_frame[i], i); @@ -7511,8 +7423,7 @@ create_host_yuvpp_pipeline(struct ia_css_pipe *pipe) { yuv_scaler_binary = pipe->pipe_settings.yuvpp.yuv_scaler_binary; need_scaler = need_yuv_scaler_stage(pipe); - if (pipe->pipe_settings.yuvpp.copy_binary.info) - { + if (pipe->pipe_settings.yuvpp.copy_binary.info) { struct ia_css_frame *in_frame_local = NULL; #ifdef ISP2401 @@ -7550,8 +7461,7 @@ create_host_yuvpp_pipeline(struct ia_css_pipe *pipe) { } } - if (need_scaler) - { + if (need_scaler) { struct ia_css_frame *tmp_out_frame = NULL; struct ia_css_frame *tmp_vf_frame = NULL; struct ia_css_frame *tmp_in_frame = in_frame; @@ -7591,8 +7501,7 @@ create_host_yuvpp_pipeline(struct ia_css_pipe *pipe) { j++; } } - } else if (copy_stage) - { + } else if (copy_stage) { if (vf_frame[0] && vf_frame[0]->info.res.width != 0) { in_frame = copy_stage->args.out_vf_frame; err = add_vf_pp_stage(pipe, in_frame, vf_frame[0], &vf_pp_binary[0], @@ -7614,7 +7523,8 @@ create_host_yuvpp_pipeline(struct ia_css_pipe *pipe) { static int create_host_copy_pipeline(struct ia_css_pipe *pipe, unsigned int max_input_width, - struct ia_css_frame *out_frame) { + struct ia_css_frame *out_frame) +{ struct ia_css_pipeline *me; int err = 0; struct ia_css_pipeline_stage_desc stage_desc; @@ -7631,16 +7541,14 @@ create_host_copy_pipeline(struct ia_css_pipe *pipe, out_frame->flash_state = IA_CSS_FRAME_FLASH_STATE_NONE; if (copy_on_sp(pipe) && - pipe->stream->config.input_config.format == ATOMISP_INPUT_FORMAT_BINARY_8) - { + pipe->stream->config.input_config.format == ATOMISP_INPUT_FORMAT_BINARY_8) { ia_css_frame_info_init( &out_frame->info, JPEG_BYTES, 1, IA_CSS_FRAME_FORMAT_BINARY_8, 0); - } else if (out_frame->info.format == IA_CSS_FRAME_FORMAT_RAW) - { + } else if (out_frame->info.format == IA_CSS_FRAME_FORMAT_RAW) { out_frame->info.raw_bit_depth = ia_css_pipe_util_pipe_input_format_bpp(pipe); } @@ -7664,7 +7572,8 @@ create_host_copy_pipeline(struct ia_css_pipe *pipe, } static int -create_host_isyscopy_capture_pipeline(struct ia_css_pipe *pipe) { +create_host_isyscopy_capture_pipeline(struct ia_css_pipe *pipe) +{ struct ia_css_pipeline *me = &pipe->pipeline; int err = 0; struct ia_css_pipeline_stage_desc stage_desc; @@ -7708,7 +7617,8 @@ create_host_isyscopy_capture_pipeline(struct ia_css_pipe *pipe) { } static int -create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) { +create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) +{ struct ia_css_pipeline *me; int err = 0; enum ia_css_capture_mode mode; @@ -7772,8 +7682,7 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) { /* Construct in_frame info (only in case we have dynamic input */ need_in_frameinfo_memory = pipe->stream->config.mode == IA_CSS_INPUT_MODE_MEMORY; #endif - if (need_in_frameinfo_memory) - { + if (need_in_frameinfo_memory) { err = init_in_frameinfo_memory_defaults(pipe, &me->in_frame, IA_CSS_FRAME_FORMAT_RAW); if (err) { @@ -7782,22 +7691,19 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) { } in_frame = &me->in_frame; - } else - { + } else { in_frame = NULL; } err = init_out_frameinfo_defaults(pipe, &me->out_frame[0], 0); - if (err) - { + if (err) { IA_CSS_LEAVE_ERR_PRIVATE(err); return err; } out_frame = &me->out_frame[0]; /* Construct vf_frame info (only in case we have VF) */ - if (pipe->enable_viewfinder[IA_CSS_PIPE_OUTPUT_STAGE_0]) - { + if (pipe->enable_viewfinder[IA_CSS_PIPE_OUTPUT_STAGE_0]) { if (mode == IA_CSS_CAPTURE_MODE_RAW || mode == IA_CSS_CAPTURE_MODE_BAYER) { /* These modes don't support viewfinder output */ vf_frame = NULL; @@ -7805,22 +7711,20 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) { init_vf_frameinfo_defaults(pipe, &me->vf_frame[0], 0); vf_frame = &me->vf_frame[0]; } - } else - { + } else { vf_frame = NULL; } copy_binary = &pipe->pipe_settings.capture.copy_binary; num_primary_stage = pipe->pipe_settings.capture.num_primary_stage; - if ((num_primary_stage == 0) && (mode == IA_CSS_CAPTURE_MODE_PRIMARY)) - { + if ((num_primary_stage == 0) && (mode == IA_CSS_CAPTURE_MODE_PRIMARY)) { IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL); return -EINVAL; } + for (i = 0; i < num_primary_stage; i++) - { primary_binary[i] = &pipe->pipe_settings.capture.primary_binary[i]; - } + vf_pp_binary = &pipe->pipe_settings.capture.vf_pp_binary; pre_isp_binary = &pipe->pipe_settings.capture.pre_isp_binary; anr_gdc_binary = &pipe->pipe_settings.capture.anr_gdc_binary; @@ -7837,8 +7741,7 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) { need_yuv_pp = (yuv_scaler_binary && yuv_scaler_binary->info); need_ldc = (capture_ldc_binary && capture_ldc_binary->info); - if (pipe->pipe_settings.capture.copy_binary.info) - { + if (pipe->pipe_settings.capture.copy_binary.info) { if (raw) { ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame); #if defined(ISP2401) @@ -7867,13 +7770,11 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) { IA_CSS_LEAVE_ERR_PRIVATE(err); return err; } - } else if (pipe->stream->config.continuous) - { + } else if (pipe->stream->config.continuous) { in_frame = pipe->stream->last_pipe->continuous_frames[0]; } - if (mode == IA_CSS_CAPTURE_MODE_PRIMARY) - { + if (mode == IA_CSS_CAPTURE_MODE_PRIMARY) { struct ia_css_frame *local_in_frame = NULL; struct ia_css_frame *local_out_frame = NULL; @@ -7918,8 +7819,7 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) { IA_CSS_BINARY_MODE_COPY; current_stage->args.copy_output = current_stage->args.copy_vf; } else if (mode == IA_CSS_CAPTURE_MODE_ADVANCED || - mode == IA_CSS_CAPTURE_MODE_LOW_LIGHT) - { + mode == IA_CSS_CAPTURE_MODE_LOW_LIGHT) { ia_css_pipe_util_set_output_frames(out_frames, 0, NULL); ia_css_pipe_get_generic_stage_desc(&stage_desc, pre_isp_binary, out_frames, in_frame, NULL); @@ -7955,8 +7855,7 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) { IA_CSS_LEAVE_ERR_PRIVATE(err); return err; } - } else if (mode == IA_CSS_CAPTURE_MODE_BAYER) - { + } else if (mode == IA_CSS_CAPTURE_MODE_BAYER) { ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame); ia_css_pipe_get_generic_stage_desc(&stage_desc, pre_isp_binary, out_frames, in_frame, NULL); @@ -7970,8 +7869,7 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) { } #ifndef ISP2401 - if (need_pp && current_stage) - { + if (need_pp && current_stage) { struct ia_css_frame *local_in_frame = NULL; local_in_frame = current_stage->args.out_frame[0]; @@ -7989,8 +7887,7 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) { need_yuv_pp ? NULL : out_frame, #else /* ldc and capture_pp not supported in same pipeline */ - if (need_ldc && current_stage) - { + if (need_ldc && current_stage) { in_frame = current_stage->args.out_frame[0]; ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame); ia_css_pipe_get_generic_stage_desc(&stage_desc, capture_ldc_binary, @@ -7998,8 +7895,7 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) { err = ia_css_pipeline_create_and_add_stage(me, &stage_desc, NULL); - } else if (need_pp && current_stage) - { + } else if (need_pp && current_stage) { in_frame = current_stage->args.out_frame[0]; err = add_capture_pp_stage(pipe, me, in_frame, need_yuv_pp ? NULL : out_frame, #endif @@ -8011,8 +7907,7 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) { } } - if (need_yuv_pp && current_stage) - { + if (need_yuv_pp && current_stage) { struct ia_css_frame *tmp_in_frame = current_stage->args.out_frame[0]; struct ia_css_frame *tmp_out_frame = NULL; @@ -8044,8 +7939,7 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) { * should not be considered as a clean solution. Proper * investigation should be done to come up with the clean solution. * */ - if (mode != IA_CSS_CAPTURE_MODE_RAW && mode != IA_CSS_CAPTURE_MODE_BAYER && current_stage && vf_frame) - { + if (mode != IA_CSS_CAPTURE_MODE_RAW && mode != IA_CSS_CAPTURE_MODE_BAYER && current_stage && vf_frame) { in_frame = current_stage->args.out_vf_frame; err = add_vf_pp_stage(pipe, in_frame, vf_frame, vf_pp_binary, ¤t_stage); @@ -8063,7 +7957,8 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) { } static int -create_host_capture_pipeline(struct ia_css_pipe *pipe) { +create_host_capture_pipeline(struct ia_css_pipe *pipe) +{ int err = 0; IA_CSS_ENTER_PRIVATE("pipe = %p", pipe); @@ -8072,8 +7967,7 @@ create_host_capture_pipeline(struct ia_css_pipe *pipe) { err = create_host_isyscopy_capture_pipeline(pipe); else err = create_host_regular_capture_pipeline(pipe); - if (err) - { + if (err) { IA_CSS_LEAVE_ERR_PRIVATE(err); return err; } @@ -8084,7 +7978,8 @@ create_host_capture_pipeline(struct ia_css_pipe *pipe) { } static int capture_start( - struct ia_css_pipe *pipe) { + struct ia_css_pipe *pipe) +{ struct ia_css_pipeline *me; int err = 0; @@ -8155,7 +8050,8 @@ static int capture_start( static int sh_css_pipe_get_output_frame_info(struct ia_css_pipe *pipe, struct ia_css_frame_info *info, - unsigned int idx) { + unsigned int idx) +{ assert(pipe); assert(info); @@ -8164,8 +8060,7 @@ sh_css_pipe_get_output_frame_info(struct ia_css_pipe *pipe, *info = pipe->output_info[idx]; if (copy_on_sp(pipe) && - pipe->stream->config.input_config.format == ATOMISP_INPUT_FORMAT_BINARY_8) - { + pipe->stream->config.input_config.format == ATOMISP_INPUT_FORMAT_BINARY_8) { ia_css_frame_info_init( info, JPEG_BYTES, @@ -8173,8 +8068,7 @@ sh_css_pipe_get_output_frame_info(struct ia_css_pipe *pipe, IA_CSS_FRAME_FORMAT_BINARY_8, 0); } else if (info->format == IA_CSS_FRAME_FORMAT_RAW || - info->format == IA_CSS_FRAME_FORMAT_RAW_PACKED) - { + info->format == IA_CSS_FRAME_FORMAT_RAW_PACKED) { info->raw_bit_depth = ia_css_pipe_util_pipe_input_format_bpp(pipe); } @@ -8188,7 +8082,8 @@ void ia_css_stream_send_input_frame(const struct ia_css_stream *stream, const unsigned short *data, unsigned int width, - unsigned int height) { + unsigned int height) +{ assert(stream); ia_css_inputfifo_send_input_frame( @@ -8199,7 +8094,8 @@ ia_css_stream_send_input_frame(const struct ia_css_stream *stream, } void -ia_css_stream_start_input_frame(const struct ia_css_stream *stream) { +ia_css_stream_start_input_frame(const struct ia_css_stream *stream) +{ assert(stream); ia_css_inputfifo_start_frame( @@ -8213,7 +8109,8 @@ ia_css_stream_send_input_line(const struct ia_css_stream *stream, const unsigned short *data, unsigned int width, const unsigned short *data2, - unsigned int width2) { + unsigned int width2) +{ assert(stream); ia_css_inputfifo_send_line(stream->config.channel_id, @@ -8224,7 +8121,8 @@ void ia_css_stream_send_input_embedded_line(const struct ia_css_stream *stream, enum atomisp_input_format format, const unsigned short *data, - unsigned int width) { + unsigned int width) +{ assert(stream); if (!data || width == 0) return; @@ -8233,14 +8131,16 @@ ia_css_stream_send_input_embedded_line(const struct ia_css_stream *stream, } void -ia_css_stream_end_input_frame(const struct ia_css_stream *stream) { +ia_css_stream_end_input_frame(const struct ia_css_stream *stream) +{ assert(stream); ia_css_inputfifo_end_frame(stream->config.channel_id); } static void -append_firmware(struct ia_css_fw_info **l, struct ia_css_fw_info *firmware) { +append_firmware(struct ia_css_fw_info **l, struct ia_css_fw_info *firmware) +{ IA_CSS_ENTER_PRIVATE("l = %p, firmware = %p", l, firmware); if (!l) { IA_CSS_ERROR("NULL fw_info"); @@ -8255,7 +8155,8 @@ append_firmware(struct ia_css_fw_info **l, struct ia_css_fw_info *firmware) { } static void -remove_firmware(struct ia_css_fw_info **l, struct ia_css_fw_info *firmware) { +remove_firmware(struct ia_css_fw_info **l, struct ia_css_fw_info *firmware) +{ assert(*l); assert(firmware); (void)l; @@ -8297,12 +8198,12 @@ static int upload_isp_code(struct ia_css_fw_info *firmware) } static int -acc_load_extension(struct ia_css_fw_info *firmware) { +acc_load_extension(struct ia_css_fw_info *firmware) +{ int err; struct ia_css_fw_info *hd = firmware; - while (hd) - { + while (hd) { err = upload_isp_code(hd); if (err) return err; @@ -8316,7 +8217,8 @@ acc_load_extension(struct ia_css_fw_info *firmware) { } static void -acc_unload_extension(struct ia_css_fw_info *firmware) { +acc_unload_extension(struct ia_css_fw_info *firmware) +{ struct ia_css_fw_info *hd = firmware; struct ia_css_fw_info *hdn = NULL; @@ -8340,13 +8242,13 @@ acc_unload_extension(struct ia_css_fw_info *firmware) { /* Load firmware for extension */ static int ia_css_pipe_load_extension(struct ia_css_pipe *pipe, - struct ia_css_fw_info *firmware) { + struct ia_css_fw_info *firmware) +{ int err = 0; IA_CSS_ENTER_PRIVATE("fw = %p pipe = %p", firmware, pipe); - if ((!firmware) || (!pipe)) - { + if ((!firmware) || (!pipe)) { IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL); return -EINVAL; } @@ -8364,7 +8266,8 @@ ia_css_pipe_load_extension(struct ia_css_pipe *pipe, /* Unload firmware for extension */ static void ia_css_pipe_unload_extension(struct ia_css_pipe *pipe, - struct ia_css_fw_info *firmware) { + struct ia_css_fw_info *firmware) +{ IA_CSS_ENTER_PRIVATE("fw = %p pipe = %p", firmware, pipe); if ((!firmware) || (!pipe)) { @@ -8383,7 +8286,8 @@ ia_css_pipe_unload_extension(struct ia_css_pipe *pipe, } bool -ia_css_pipeline_uses_params(struct ia_css_pipeline *me) { +ia_css_pipeline_uses_params(struct ia_css_pipeline *me) +{ struct ia_css_pipeline_stage *stage; assert(me); @@ -8404,7 +8308,8 @@ ia_css_pipeline_uses_params(struct ia_css_pipeline *me) { static int sh_css_pipeline_add_acc_stage(struct ia_css_pipeline *pipeline, - const void *acc_fw) { + const void *acc_fw) +{ struct ia_css_fw_info *fw = (struct ia_css_fw_info *)acc_fw; /* In QoS case, load_extension already called, so skipping */ int err = 0; @@ -8416,8 +8321,7 @@ sh_css_pipeline_add_acc_stage(struct ia_css_pipeline *pipeline, "sh_css_pipeline_add_acc_stage() enter: pipeline=%p, acc_fw=%p\n", pipeline, acc_fw); - if (!err) - { + if (!err) { struct ia_css_pipeline_stage_desc stage_desc; ia_css_pipe_get_acc_stage_desc(&stage_desc, NULL, fw); @@ -8436,7 +8340,8 @@ sh_css_pipeline_add_acc_stage(struct ia_css_pipeline *pipeline, * Refer to "sh_css_internal.h" for details. */ int ia_css_stream_capture_frame(struct ia_css_stream *stream, - unsigned int exp_id) { + unsigned int exp_id) +{ struct sh_css_tag_descr tag_descr; u32 encoded_tag_descr; int err; @@ -8478,7 +8383,8 @@ int ia_css_stream_capture( struct ia_css_stream *stream, int num_captures, unsigned int skip, - int offset) { + int offset) +{ struct sh_css_tag_descr tag_descr; unsigned int encoded_tag_descr; int return_err; @@ -8541,8 +8447,9 @@ void ia_css_stream_request_flash(struct ia_css_stream *stream) ia_css_debug_dump_sp_sw_debug_info(); ia_css_debug_dump_debug_info(NULL); } - } else + } else { IA_CSS_LOG("SP is not running!"); + } #endif ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, @@ -8550,7 +8457,8 @@ void ia_css_stream_request_flash(struct ia_css_stream *stream) } static void -sh_css_init_host_sp_control_vars(void) { +sh_css_init_host_sp_control_vars(void) +{ const struct ia_css_fw_info *fw; unsigned int HIVE_ADDR_ia_css_ispctrl_sp_isp_started; @@ -8634,7 +8542,8 @@ void ia_css_pipe_config_defaults(struct ia_css_pipe_config *pipe_config) void ia_css_pipe_extra_config_defaults(struct ia_css_pipe_extra_config - *extra_config) { + *extra_config) +{ if (!extra_config) { IA_CSS_ERROR("NULL input parameter"); return; @@ -8664,11 +8573,11 @@ void ia_css_stream_config_defaults(struct ia_css_stream_config *stream_config) } static int -ia_css_acc_pipe_create(struct ia_css_pipe *pipe) { +ia_css_acc_pipe_create(struct ia_css_pipe *pipe) +{ int err = 0; - if (!pipe) - { + if (!pipe) { IA_CSS_ERROR("NULL input parameter"); return -EINVAL; } @@ -8678,9 +8587,7 @@ ia_css_acc_pipe_create(struct ia_css_pipe *pipe) { pipe->config.acc_num_execs = 1; if (pipe->config.acc_extension) - { err = ia_css_pipe_load_extension(pipe, pipe->config.acc_extension); - } return err; } @@ -8699,9 +8606,8 @@ int ia_css_pipe_create(const struct ia_css_pipe_config *config, err = ia_css_pipe_create_extra(config, NULL, pipe); - if (err == 0) { + if (err == 0) IA_CSS_LOG("pipe created successfully = %p", *pipe); - } IA_CSS_LEAVE_ERR_PRIVATE(err); @@ -8711,7 +8617,8 @@ int ia_css_pipe_create(const struct ia_css_pipe_config *config, int ia_css_pipe_create_extra(const struct ia_css_pipe_config *config, const struct ia_css_pipe_extra_config *extra_config, - struct ia_css_pipe **pipe) { + struct ia_css_pipe **pipe) +{ int err = -EINVAL; struct ia_css_pipe *internal_pipe = NULL; unsigned int i; @@ -8719,14 +8626,12 @@ ia_css_pipe_create_extra(const struct ia_css_pipe_config *config, IA_CSS_ENTER_PRIVATE("config = %p, extra_config = %p and pipe = %p", config, extra_config, pipe); /* do not allow to create more than the maximum limit */ - if (my_css.pipe_counter >= IA_CSS_PIPELINE_NUM_MAX) - { + if (my_css.pipe_counter >= IA_CSS_PIPELINE_NUM_MAX) { IA_CSS_LEAVE_ERR_PRIVATE(-ENOSPC); return -EINVAL; } - if ((!pipe) || (!config)) - { + if ((!pipe) || (!config)) { IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL); return -EINVAL; } @@ -8735,8 +8640,7 @@ ia_css_pipe_create_extra(const struct ia_css_pipe_config *config, ia_css_debug_dump_pipe_extra_config(extra_config); err = create_pipe(config->mode, &internal_pipe, false); - if (err) - { + if (err) { IA_CSS_LEAVE_ERR_PRIVATE(err); return err; } @@ -8748,8 +8652,7 @@ ia_css_pipe_create_extra(const struct ia_css_pipe_config *config, else ia_css_pipe_extra_config_defaults(&internal_pipe->extra_config); - if (config->mode == IA_CSS_PIPE_MODE_ACC) - { + if (config->mode == IA_CSS_PIPE_MODE_ACC) { /* Temporary hack to migrate acceleration to CSS 2.0. * In the future the code for all pipe types should be * unified. */ @@ -8776,15 +8679,13 @@ ia_css_pipe_create_extra(const struct ia_css_pipe_config *config, set bayer_ds_out_res equal to IF output resolution(IF may do cropping on sensor output) or use default decimation factor 1. */ if (internal_pipe->extra_config.enable_raw_binning && - internal_pipe->config.bayer_ds_out_res.width) - { + internal_pipe->config.bayer_ds_out_res.width) { /* fill some code here, if no code is needed, please remove it during integration */ } /* YUV downscaling */ if ((internal_pipe->config.vf_pp_in_res.width || - internal_pipe->config.capt_pp_in_res.width)) - { + internal_pipe->config.capt_pp_in_res.width)) { enum ia_css_frame_format format; if (internal_pipe->config.vf_pp_in_res.width) { @@ -8805,8 +8706,7 @@ ia_css_pipe_create_extra(const struct ia_css_pipe_config *config, } } if (internal_pipe->config.vf_pp_in_res.width && - internal_pipe->config.mode == IA_CSS_PIPE_MODE_PREVIEW) - { + internal_pipe->config.mode == IA_CSS_PIPE_MODE_PREVIEW) { ia_css_frame_info_init( &internal_pipe->vf_yuv_ds_input_info, internal_pipe->config.vf_pp_in_res.width, @@ -8814,8 +8714,7 @@ ia_css_pipe_create_extra(const struct ia_css_pipe_config *config, IA_CSS_FRAME_FORMAT_YUV_LINE, 0); } /* handle bayer downscaling output info */ - if (internal_pipe->config.bayer_ds_out_res.width) - { + if (internal_pipe->config.bayer_ds_out_res.width) { ia_css_frame_info_init( &internal_pipe->bds_output_info, internal_pipe->config.bayer_ds_out_res.width, @@ -8824,8 +8723,7 @@ ia_css_pipe_create_extra(const struct ia_css_pipe_config *config, } /* handle output info, assume always needed */ - for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) - { + for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) { if (internal_pipe->config.output_info[i].res.width) { err = sh_css_pipe_configure_output( internal_pipe, @@ -8861,8 +8759,7 @@ ia_css_pipe_create_extra(const struct ia_css_pipe_config *config, } } } - if (internal_pipe->config.acc_extension) - { + if (internal_pipe->config.acc_extension) { err = ia_css_pipe_load_extension(internal_pipe, internal_pipe->config.acc_extension); if (err) { @@ -8882,18 +8779,18 @@ ia_css_pipe_create_extra(const struct ia_css_pipe_config *config, int ia_css_pipe_get_info(const struct ia_css_pipe *pipe, - struct ia_css_pipe_info *pipe_info) { + struct ia_css_pipe_info *pipe_info) +{ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_pipe_get_info()\n"); + assert(pipe_info); - if (!pipe_info) - { + if (!pipe_info) { ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR, "ia_css_pipe_get_info: pipe_info cannot be NULL\n"); return -EINVAL; } - if (!pipe || !pipe->stream) - { + if (!pipe || !pipe->stream) { ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR, "ia_css_pipe_get_info: ia_css_stream_create needs to be called before ia_css_[stream/pipe]_get_info\n"); return -EINVAL; @@ -8921,40 +8818,36 @@ bool ia_css_pipe_has_dvs_stats(struct ia_css_pipe_info *pipe_info) int ia_css_pipe_override_frame_format(struct ia_css_pipe *pipe, int pin_index, - enum ia_css_frame_format new_format) { + enum ia_css_frame_format new_format) +{ int err = 0; IA_CSS_ENTER_PRIVATE("pipe = %p, pin_index = %d, new_formats = %d", pipe, pin_index, new_format); - if (!pipe) - { + if (!pipe) { IA_CSS_ERROR("pipe is not set"); err = -EINVAL; IA_CSS_LEAVE_ERR_PRIVATE(err); return err; } - if (0 != pin_index && 1 != pin_index) - { + if (0 != pin_index && 1 != pin_index) { IA_CSS_ERROR("pin index is not valid"); err = -EINVAL; IA_CSS_LEAVE_ERR_PRIVATE(err); return err; } - if (new_format != IA_CSS_FRAME_FORMAT_NV12_TILEY) - { + if (new_format != IA_CSS_FRAME_FORMAT_NV12_TILEY) { IA_CSS_ERROR("new format is not valid"); err = -EINVAL; IA_CSS_LEAVE_ERR_PRIVATE(err); return err; - } else - { + } else { err = ia_css_pipe_check_format(pipe, new_format); if (!err) { - if (pin_index == 0) { + if (pin_index == 0) pipe->output_info[0].format = new_format; - } else { + else pipe->vf_output_info[0].format = new_format; - } } } IA_CSS_LEAVE_ERR_PRIVATE(err); @@ -8964,7 +8857,8 @@ ia_css_pipe_override_frame_format(struct ia_css_pipe *pipe, #if !defined(ISP2401) /* Configuration of INPUT_SYSTEM_VERSION_2401 is done on SP */ static int -ia_css_stream_configure_rx(struct ia_css_stream *stream) { +ia_css_stream_configure_rx(struct ia_css_stream *stream) +{ struct ia_css_input_port *config; assert(stream); @@ -8993,11 +8887,10 @@ ia_css_stream_configure_rx(struct ia_css_stream *stream) { if (config->compression.type == IA_CSS_CSI2_COMPRESSION_TYPE_NONE) stream->csi_rx_config.comp = MIPI_PREDICTOR_NONE; else - { /* not implemented yet, requires extension of the rx_cfg_t * struct */ return -EINVAL; - } + stream->csi_rx_config.is_two_ppc = (stream->config.pixels_per_clock == 2); stream->reconfigure_css_rx = true; return 0; @@ -9008,7 +8901,8 @@ static struct ia_css_pipe * find_pipe(struct ia_css_pipe *pipes[], unsigned int num_pipes, enum ia_css_pipe_mode mode, - bool copy_pipe) { + bool copy_pipe) +{ unsigned int i; assert(pipes); @@ -9024,21 +8918,20 @@ find_pipe(struct ia_css_pipe *pipes[], } static int -ia_css_acc_stream_create(struct ia_css_stream *stream) { +ia_css_acc_stream_create(struct ia_css_stream *stream) +{ int i; int err = 0; assert(stream); IA_CSS_ENTER_PRIVATE("stream = %p", stream); - if (!stream) - { + if (!stream) { IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL); return -EINVAL; } - for (i = 0; i < stream->num_pipes; i++) - { + for (i = 0; i < stream->num_pipes; i++) { struct ia_css_pipe *pipe = stream->pipes[i]; assert(pipe); @@ -9052,14 +8945,12 @@ ia_css_acc_stream_create(struct ia_css_stream *stream) { /* Map SP threads before doing anything. */ err = map_sp_threads(stream, true); - if (err) - { + if (err) { IA_CSS_LEAVE_ERR_PRIVATE(err); return err; } - for (i = 0; i < stream->num_pipes; i++) - { + for (i = 0; i < stream->num_pipes; i++) { struct ia_css_pipe *pipe = stream->pipes[i]; assert(pipe); @@ -9067,8 +8958,7 @@ ia_css_acc_stream_create(struct ia_css_stream *stream) { } err = create_host_pipeline_structure(stream); - if (err) - { + if (err) { IA_CSS_LEAVE_ERR_PRIVATE(err); return err; } @@ -9082,7 +8972,8 @@ ia_css_acc_stream_create(struct ia_css_stream *stream) { static int metadata_info_init(const struct ia_css_metadata_config *mdc, - struct ia_css_metadata_info *md) { + struct ia_css_metadata_info *md) +{ /* Either both width and height should be set or neither */ if ((mdc->resolution.height > 0) ^ (mdc->resolution.width > 0)) return -EINVAL; @@ -9142,7 +9033,8 @@ int ia_css_stream_create(const struct ia_css_stream_config *stream_config, int num_pipes, struct ia_css_pipe *pipes[], - struct ia_css_stream **stream) { + struct ia_css_stream **stream) +{ struct ia_css_pipe *curr_pipe; struct ia_css_stream *curr_stream = NULL; bool spcopyonly; @@ -9161,8 +9053,7 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config, /* some checks */ if (num_pipes == 0 || !stream || - !pipes) - { + !pipes) { err = -EINVAL; IA_CSS_LEAVE_ERR(err); return err; @@ -9171,8 +9062,7 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config, #if !defined(ISP2401) /* We don't support metadata for JPEG stream, since they both use str2mem */ if (stream_config->input_config.format == ATOMISP_INPUT_FORMAT_BINARY_8 && - stream_config->metadata_config.resolution.height > 0) - { + stream_config->metadata_config.resolution.height > 0) { err = -EINVAL; IA_CSS_LEAVE_ERR(err); return err; @@ -9180,8 +9070,7 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config, #endif #ifdef ISP2401 - if (stream_config->online && stream_config->pack_raw_pixels) - { + if (stream_config->online && stream_config->pack_raw_pixels) { IA_CSS_LOG("online and pack raw is invalid on input system 2401"); err = -EINVAL; IA_CSS_LEAVE_ERR(err); @@ -9236,16 +9125,14 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config, /* Currently we only supported metadata up to a certain size. */ err = metadata_info_init(&stream_config->metadata_config, &md_info); - if (err) - { + if (err) { IA_CSS_LEAVE_ERR(err); return err; } /* allocate the stream instance */ curr_stream = kzalloc(sizeof(struct ia_css_stream), GFP_KERNEL); - if (!curr_stream) - { + if (!curr_stream) { err = -ENOMEM; IA_CSS_LEAVE_ERR(err); return err; @@ -9256,8 +9143,7 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config, /* allocate pipes */ curr_stream->num_pipes = num_pipes; curr_stream->pipes = kcalloc(num_pipes, sizeof(struct ia_css_pipe *), GFP_KERNEL); - if (!curr_stream->pipes) - { + if (!curr_stream->pipes) { curr_stream->num_pipes = 0; kfree(curr_stream); curr_stream = NULL; @@ -9280,8 +9166,7 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config, #endif #ifdef ISP2401 - if (curr_stream->config.online) - { + if (curr_stream->config.online) { curr_stream->config.source.port.num_lanes = stream_config->source.port.num_lanes; curr_stream->config.mode = IA_CSS_INPUT_MODE_BUFFERED_SENSOR; @@ -9299,8 +9184,7 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config, curr_stream->config.lock_all); /* copy mode specific stuff */ - switch (curr_stream->config.mode) - { + switch (curr_stream->config.mode) { case IA_CSS_INPUT_MODE_SENSOR: case IA_CSS_INPUT_MODE_BUFFERED_SENSOR: #if !defined(ISP2401) @@ -9342,14 +9226,12 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config, err = aspect_ratio_crop_init(curr_stream, pipes, &aspect_ratio_crop_enabled); - if (err) - { + if (err) { IA_CSS_LEAVE_ERR(err); goto ERR; } #endif - for (i = 0; i < num_pipes; i++) - { + for (i = 0; i < num_pipes; i++) { struct ia_css_resolution effective_res; curr_pipe = pipes[i]; @@ -9389,9 +9271,8 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config, if (pipes[i]->config.mode != IA_CSS_PIPE_MODE_ACC && pipes[i]->config.mode != IA_CSS_PIPE_MODE_COPY) { err = check_pipe_resolutions(pipes[i]); - if (err) { + if (err) goto ERR; - } } } } @@ -9401,20 +9282,17 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config, goto ERR; IA_CSS_LOG("isp_params_configs: %p", curr_stream->isp_params_configs); - if (num_pipes == 1 && pipes[0]->config.mode == IA_CSS_PIPE_MODE_ACC) - { + if (num_pipes == 1 && pipes[0]->config.mode == IA_CSS_PIPE_MODE_ACC) { *stream = curr_stream; err = ia_css_acc_stream_create(curr_stream); goto ERR; } /* sensor binning */ - if (!spcopyonly) - { + if (!spcopyonly) { sensor_binning_changed = sh_css_params_set_binning_factor(curr_stream, curr_stream->config.sensor_binning_factor); - } else - { + } else { sensor_binning_changed = false; } @@ -9425,8 +9303,7 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config, curr_stream->cont_capt = false; /* Temporary hack: we give the preview pipe a reference to the capture * pipe in continuous capture mode. */ - if (curr_stream->config.continuous) - { + if (curr_stream->config.continuous) { /* Search for the preview pipe and create the copy pipe */ struct ia_css_pipe *preview_pipe; struct ia_css_pipe *video_pipe; @@ -9474,9 +9351,9 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config, preview_pipe->pipe_settings.preview.copy_pipe = copy_pipe; copy_pipe->stream = curr_stream; } - if (preview_pipe && curr_stream->cont_capt) { + if (preview_pipe && curr_stream->cont_capt) preview_pipe->pipe_settings.preview.capture_pipe = capture_pipe; - } + if (video_pipe && !video_pipe->pipe_settings.video.copy_pipe) { err = create_pipe(IA_CSS_PIPE_MODE_CAPTURE, ©_pipe, true); if (err) @@ -9485,15 +9362,13 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config, video_pipe->pipe_settings.video.copy_pipe = copy_pipe; copy_pipe->stream = curr_stream; } - if (video_pipe && curr_stream->cont_capt) { + if (video_pipe && curr_stream->cont_capt) video_pipe->pipe_settings.video.capture_pipe = capture_pipe; - } - if (preview_pipe && acc_pipe) { + + if (preview_pipe && acc_pipe) preview_pipe->pipe_settings.preview.acc_pipe = acc_pipe; - } } - for (i = 0; i < num_pipes; i++) - { + for (i = 0; i < num_pipes; i++) { curr_pipe = pipes[i]; /* set current stream */ curr_pipe->stream = curr_stream; @@ -9514,8 +9389,7 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config, } /* now pipes have been configured, info should be available */ - for (i = 0; i < num_pipes; i++) - { + for (i = 0; i < num_pipes; i++) { struct ia_css_pipe_info *pipe_info = NULL; curr_pipe = pipes[i]; @@ -9565,22 +9439,19 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config, /* Map SP threads before doing anything. */ err = map_sp_threads(curr_stream, true); - if (err) - { + if (err) { IA_CSS_LOG("map_sp_threads: return_err=%d", err); goto ERR; } - for (i = 0; i < num_pipes; i++) - { + for (i = 0; i < num_pipes; i++) { curr_pipe = pipes[i]; ia_css_pipe_map_queue(curr_pipe, true); } /* Create host side pipeline objects without stages */ err = create_host_pipeline_structure(curr_stream); - if (err) - { + if (err) { IA_CSS_LOG("create_host_pipeline_structure: return_err=%d", err); goto ERR; } @@ -9618,13 +9489,13 @@ ERR: } int -ia_css_stream_destroy(struct ia_css_stream *stream) { +ia_css_stream_destroy(struct ia_css_stream *stream) +{ int i; int err = 0; IA_CSS_ENTER_PRIVATE("stream = %p", stream); - if (!stream) - { + if (!stream) { err = -EINVAL; IA_CSS_LEAVE_ERR_PRIVATE(err); return err; @@ -9633,8 +9504,7 @@ ia_css_stream_destroy(struct ia_css_stream *stream) { ia_css_stream_isp_parameters_uninit(stream); if ((stream->last_pipe) && - ia_css_pipeline_is_mapped(stream->last_pipe->pipe_num)) - { + ia_css_pipeline_is_mapped(stream->last_pipe->pipe_num)) { #if defined(ISP2401) bool free_mpi; @@ -9696,8 +9566,7 @@ ia_css_stream_destroy(struct ia_css_stream *stream) { } /* remove references from pipes to stream */ - for (i = 0; i < stream->num_pipes; i++) - { + for (i = 0; i < stream->num_pipes; i++) { struct ia_css_pipe *entry = stream->pipes[i]; assert(entry); @@ -9726,8 +9595,7 @@ ia_css_stream_destroy(struct ia_css_stream *stream) { /* working mode: take out of the seed list */ if (my_css_save.mode == sh_css_mode_working) { for (i = 0; i < MAX_ACTIVE_STREAMS; i++) { - if (my_css_save.stream_seeds[i].stream == stream) - { + if (my_css_save.stream_seeds[i].stream == stream) { IA_CSS_LOG("took out stream %d", i); my_css_save.stream_seeds[i].stream = NULL; break; @@ -9743,7 +9611,8 @@ ia_css_stream_destroy(struct ia_css_stream *stream) { int ia_css_stream_get_info(const struct ia_css_stream *stream, - struct ia_css_stream_info *stream_info) { + struct ia_css_stream_info *stream_info) +{ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_get_info: enter/exit\n"); assert(stream); assert(stream_info); @@ -9759,15 +9628,15 @@ ia_css_stream_get_info(const struct ia_css_stream *stream, * The stream handle is used to identify the correct entry in the css_save struct */ int -ia_css_stream_load(struct ia_css_stream *stream) { +ia_css_stream_load(struct ia_css_stream *stream) +{ if (!IS_ISP2401) { int i; int err; assert(stream); ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_load() enter,\n"); - for (i = 0; i < MAX_ACTIVE_STREAMS; i++) - { + for (i = 0; i < MAX_ACTIVE_STREAMS; i++) { if (my_css_save.stream_seeds[i].stream == stream) { int j; @@ -9806,12 +9675,12 @@ ia_css_stream_load(struct ia_css_stream *stream) { } int -ia_css_stream_start(struct ia_css_stream *stream) { +ia_css_stream_start(struct ia_css_stream *stream) +{ int err = 0; IA_CSS_ENTER("stream = %p", stream); - if ((!stream) || (!stream->last_pipe)) - { + if ((!stream) || (!stream->last_pipe)) { IA_CSS_LEAVE_ERR(-EINVAL); return -EINVAL; } @@ -9821,8 +9690,7 @@ ia_css_stream_start(struct ia_css_stream *stream) { /* Create host side pipeline. */ err = create_host_pipeline(stream); - if (err) - { + if (err) { IA_CSS_LEAVE_ERR(err); return err; } @@ -9835,8 +9703,7 @@ ia_css_stream_start(struct ia_css_stream *stream) { #if !defined(ISP2401) /* Initialize mipi size checks */ - if (stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR) - { + if (stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR) { unsigned int idx; unsigned int port = (unsigned int)(stream->config.source.port.port); @@ -9847,8 +9714,7 @@ ia_css_stream_start(struct ia_css_stream *stream) { } #endif - if (stream->config.mode != IA_CSS_INPUT_MODE_MEMORY) - { + if (stream->config.mode != IA_CSS_INPUT_MODE_MEMORY) { err = sh_css_config_input_network(stream); if (err) return err; @@ -9860,7 +9726,8 @@ ia_css_stream_start(struct ia_css_stream *stream) { } int -ia_css_stream_stop(struct ia_css_stream *stream) { +ia_css_stream_stop(struct ia_css_stream *stream) +{ int err = 0; ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_stop() enter/exit\n"); @@ -9871,22 +9738,19 @@ ia_css_stream_stop(struct ia_css_stream *stream) { #if !defined(ISP2401) /* De-initialize mipi size checks */ - if (stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR) - { + if (stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR) { unsigned int idx; unsigned int port = (unsigned int)(stream->config.source.port.port); - for (idx = 0; idx < IA_CSS_MIPI_SIZE_CHECK_MAX_NOF_ENTRIES_PER_PORT; idx++) { + for (idx = 0; idx < IA_CSS_MIPI_SIZE_CHECK_MAX_NOF_ENTRIES_PER_PORT; idx++) sh_css_sp_group.config.mipi_sizes_for_check[port][idx] = 0; - } } #endif - if (!IS_ISP2401) { + if (!IS_ISP2401) err = ia_css_pipeline_request_stop(&stream->last_pipe->pipeline); - } else { + else err = sh_css_pipes_stop(stream); - } if (err) return err; @@ -9899,16 +9763,16 @@ ia_css_stream_stop(struct ia_css_stream *stream) { } bool -ia_css_stream_has_stopped(struct ia_css_stream *stream) { +ia_css_stream_has_stopped(struct ia_css_stream *stream) +{ bool stopped; assert(stream); - if (!IS_ISP2401) { + if (!IS_ISP2401) stopped = ia_css_pipeline_has_stopped(&stream->last_pipe->pipeline); - } else { + else stopped = sh_css_pipes_have_stopped(stream); - } return stopped; } @@ -9919,7 +9783,8 @@ ia_css_stream_has_stopped(struct ia_css_stream *stream) { * The stream handle is used to identify the correct entry in the css_save struct */ int -ia_css_stream_unload(struct ia_css_stream *stream) { +ia_css_stream_unload(struct ia_css_stream *stream) +{ int i; assert(stream); @@ -9927,8 +9792,7 @@ ia_css_stream_unload(struct ia_css_stream *stream) { /* some checks */ assert(stream); for (i = 0; i < MAX_ACTIVE_STREAMS; i++) - if (my_css_save.stream_seeds[i].stream == stream) - { + if (my_css_save.stream_seeds[i].stream == stream) { int j; ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, @@ -9948,7 +9812,8 @@ ia_css_stream_unload(struct ia_css_stream *stream) { int ia_css_temp_pipe_to_pipe_id(const struct ia_css_pipe *pipe, - enum ia_css_pipe_id *pipe_id) { + enum ia_css_pipe_id *pipe_id) +{ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_temp_pipe_to_pipe_id() enter/exit\n"); if (pipe) *pipe_id = pipe->mode; @@ -9959,18 +9824,21 @@ ia_css_temp_pipe_to_pipe_id(const struct ia_css_pipe *pipe, } enum atomisp_input_format -ia_css_stream_get_format(const struct ia_css_stream *stream) { +ia_css_stream_get_format(const struct ia_css_stream *stream) +{ return stream->config.input_config.format; } bool -ia_css_stream_get_two_pixels_per_clock(const struct ia_css_stream *stream) { +ia_css_stream_get_two_pixels_per_clock(const struct ia_css_stream *stream) +{ return (stream->config.pixels_per_clock == 2); } struct ia_css_binary * ia_css_stream_get_shading_correction_binary(const struct ia_css_stream - *stream) { + *stream) +{ struct ia_css_pipe *pipe; assert(stream); @@ -9988,7 +9856,8 @@ ia_css_stream_get_shading_correction_binary(const struct ia_css_stream } struct ia_css_binary * -ia_css_stream_get_dvs_binary(const struct ia_css_stream *stream) { +ia_css_stream_get_dvs_binary(const struct ia_css_stream *stream) +{ int i; struct ia_css_pipe *video_pipe = NULL; @@ -10007,7 +9876,8 @@ ia_css_stream_get_dvs_binary(const struct ia_css_stream *stream) { } struct ia_css_binary * -ia_css_stream_get_3a_binary(const struct ia_css_stream *stream) { +ia_css_stream_get_3a_binary(const struct ia_css_stream *stream) +{ struct ia_css_pipe *pipe; struct ia_css_binary *s3a_binary = NULL; @@ -10029,7 +9899,8 @@ ia_css_stream_get_3a_binary(const struct ia_css_stream *stream) { int ia_css_stream_set_output_padded_width(struct ia_css_stream *stream, - unsigned int output_padded_width) { + unsigned int output_padded_width) +{ struct ia_css_pipe *pipe; assert(stream); @@ -10046,7 +9917,8 @@ ia_css_stream_set_output_padded_width(struct ia_css_stream *stream, } static struct ia_css_binary * -ia_css_pipe_get_shading_correction_binary(const struct ia_css_pipe *pipe) { +ia_css_pipe_get_shading_correction_binary(const struct ia_css_pipe *pipe) +{ struct ia_css_binary *binary = NULL; assert(pipe); @@ -10091,7 +9963,8 @@ ia_css_pipe_get_shading_correction_binary(const struct ia_css_pipe *pipe) { } static struct ia_css_binary * -ia_css_pipe_get_s3a_binary(const struct ia_css_pipe *pipe) { +ia_css_pipe_get_s3a_binary(const struct ia_css_pipe *pipe) +{ struct ia_css_binary *binary = NULL; assert(pipe); @@ -10114,9 +9987,9 @@ ia_css_pipe_get_s3a_binary(const struct ia_css_pipe *pipe) { } } } else if (pipe->config.default_capture_config.mode == - IA_CSS_CAPTURE_MODE_BAYER) + IA_CSS_CAPTURE_MODE_BAYER) { binary = (struct ia_css_binary *)&pipe->pipe_settings.capture.pre_isp_binary; - else if (pipe->config.default_capture_config.mode == + } else if (pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_ADVANCED || pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_LOW_LIGHT) { if (pipe->config.isp_pipe_version == IA_CSS_PIPE_VERSION_1) @@ -10138,7 +10011,8 @@ ia_css_pipe_get_s3a_binary(const struct ia_css_pipe *pipe) { } static struct ia_css_binary * -ia_css_pipe_get_sdis_binary(const struct ia_css_pipe *pipe) { +ia_css_pipe_get_sdis_binary(const struct ia_css_pipe *pipe) +{ struct ia_css_binary *binary = NULL; assert(pipe); @@ -10158,14 +10032,16 @@ ia_css_pipe_get_sdis_binary(const struct ia_css_pipe *pipe) { } struct ia_css_pipeline * -ia_css_pipe_get_pipeline(const struct ia_css_pipe *pipe) { +ia_css_pipe_get_pipeline(const struct ia_css_pipe *pipe) +{ assert(pipe); return (struct ia_css_pipeline *)&pipe->pipeline; } unsigned int -ia_css_pipe_get_pipe_num(const struct ia_css_pipe *pipe) { +ia_css_pipe_get_pipe_num(const struct ia_css_pipe *pipe) +{ assert(pipe); /* KW was not sure this function was not returning a value @@ -10182,7 +10058,8 @@ ia_css_pipe_get_pipe_num(const struct ia_css_pipe *pipe) { } unsigned int -ia_css_pipe_get_isp_pipe_version(const struct ia_css_pipe *pipe) { +ia_css_pipe_get_isp_pipe_version(const struct ia_css_pipe *pipe) +{ assert(pipe); return (unsigned int)pipe->config.isp_pipe_version; @@ -10191,7 +10068,8 @@ ia_css_pipe_get_isp_pipe_version(const struct ia_css_pipe *pipe) { #define SP_START_TIMEOUT_US 30000000 int -ia_css_start_sp(void) { +ia_css_start_sp(void) +{ unsigned long timeout; int err = 0; @@ -10200,13 +10078,11 @@ ia_css_start_sp(void) { /* waiting for the SP is completely started */ timeout = SP_START_TIMEOUT_US; - while ((ia_css_spctrl_get_state(SP0_ID) != IA_CSS_SP_SW_INITIALIZED) && timeout) - { + while ((ia_css_spctrl_get_state(SP0_ID) != IA_CSS_SP_SW_INITIALIZED) && timeout) { timeout--; udelay(1); } - if (timeout == 0) - { + if (timeout == 0) { IA_CSS_ERROR("timeout during SP initialization"); return -EINVAL; } @@ -10234,14 +10110,14 @@ ia_css_start_sp(void) { #define SP_SHUTDOWN_TIMEOUT_US 200000 int -ia_css_stop_sp(void) { +ia_css_stop_sp(void) +{ unsigned long timeout; int err = 0; IA_CSS_ENTER("void"); - if (!sh_css_sp_is_running()) - { + if (!sh_css_sp_is_running()) { err = -EINVAL; IA_CSS_LEAVE("SP already stopped : return_err=%d", err); @@ -10253,8 +10129,7 @@ ia_css_stop_sp(void) { if (!IS_ISP2401) { sh_css_write_host2sp_command(host2sp_cmd_terminate); } else { - if (!sh_css_write_host2sp_command(host2sp_cmd_terminate)) - { + if (!sh_css_write_host2sp_command(host2sp_cmd_terminate)) { IA_CSS_ERROR("Call to 'sh-css_write_host2sp_command()' failed"); ia_css_debug_dump_sp_sw_debug_info(); ia_css_debug_dump_debug_info(NULL); @@ -10264,27 +10139,23 @@ ia_css_stop_sp(void) { sh_css_sp_set_sp_running(false); timeout = SP_SHUTDOWN_TIMEOUT_US; - while (!ia_css_spctrl_is_idle(SP0_ID) && timeout) - { + while (!ia_css_spctrl_is_idle(SP0_ID) && timeout) { timeout--; udelay(1); } if ((ia_css_spctrl_get_state(SP0_ID) != IA_CSS_SP_SW_TERMINATED)) IA_CSS_WARNING("SP has not terminated (SW)"); - if (timeout == 0) - { + if (timeout == 0) { IA_CSS_WARNING("SP is not idle"); ia_css_debug_dump_sp_sw_debug_info(); } timeout = SP_SHUTDOWN_TIMEOUT_US; - while (!isp_ctrl_getbit(ISP0_ID, ISP_SC_REG, ISP_IDLE_BIT) && timeout) - { + while (!isp_ctrl_getbit(ISP0_ID, ISP_SC_REG, ISP_IDLE_BIT) && timeout) { timeout--; udelay(1); } - if (timeout == 0) - { + if (timeout == 0) { IA_CSS_WARNING("ISP is not idle"); ia_css_debug_dump_sp_sw_debug_info(); } @@ -10299,7 +10170,8 @@ ia_css_stop_sp(void) { } int -ia_css_update_continuous_frames(struct ia_css_stream *stream) { +ia_css_update_continuous_frames(struct ia_css_stream *stream) +{ struct ia_css_pipe *pipe; unsigned int i; @@ -10307,8 +10179,7 @@ ia_css_update_continuous_frames(struct ia_css_stream *stream) { IA_CSS_DEBUG_TRACE, "sh_css_update_continuous_frames() enter:\n"); - if (!stream) - { + if (!stream) { ia_css_debug_dtrace( IA_CSS_DEBUG_TRACE, "sh_css_update_continuous_frames() leave: invalid stream, return_void\n"); @@ -10319,10 +10190,9 @@ ia_css_update_continuous_frames(struct ia_css_stream *stream) { for (i = stream->config.init_num_cont_raw_buf; i < stream->config.target_num_cont_raw_buf; i++) - { sh_css_update_host2sp_offline_frame(i, pipe->continuous_frames[i], pipe->cont_md_buffers[i]); - } + sh_css_update_host2sp_cont_num_raw_frames (stream->config.target_num_cont_raw_buf, true); ia_css_debug_dtrace( @@ -10448,7 +10318,8 @@ void ia_css_pipe_map_queue(struct ia_css_pipe *pipe, bool map) #if CONFIG_ON_FRAME_ENQUEUE() static int set_config_on_frame_enqueue(struct ia_css_frame_info - *info, struct frame_data_wrapper *frame) { + *info, struct frame_data_wrapper *frame) +{ frame->config_on_frame_enqueue.padded_width = 0; /* currently we support configuration on frame enqueue only on YUV formats */ @@ -10456,11 +10327,11 @@ static int set_config_on_frame_enqueue(struct ia_css_frame_info switch (info->format) { case IA_CSS_FRAME_FORMAT_YUV420: case IA_CSS_FRAME_FORMAT_NV12: - if (info->padded_width > info->res.width) { + if (info->padded_width > info->res.width) frame->config_on_frame_enqueue.padded_width = info->padded_width; - } else if ((info->padded_width < info->res.width) && (info->padded_width > 0)) { + else if ((info->padded_width < info->res.width) && (info->padded_width > 0)) return -EINVAL; - } + /* nothing to do if width == padded width or padded width is zeroed (the same) */ break; default: @@ -10472,22 +10343,21 @@ static int set_config_on_frame_enqueue(struct ia_css_frame_info #endif int -ia_css_unlock_raw_frame(struct ia_css_stream *stream, uint32_t exp_id) { +ia_css_unlock_raw_frame(struct ia_css_stream *stream, uint32_t exp_id) +{ int ret; IA_CSS_ENTER(""); /* Only continuous streams have a tagger to which we can send the * unlock message. */ - if (!stream || !stream->config.continuous) - { + if (!stream || !stream->config.continuous) { IA_CSS_ERROR("invalid stream pointer"); return -EINVAL; } if (exp_id > IA_CSS_ISYS_MAX_EXPOSURE_ID || - exp_id < IA_CSS_ISYS_MIN_EXPOSURE_ID) - { + exp_id < IA_CSS_ISYS_MIN_EXPOSURE_ID) { IA_CSS_ERROR("invalid exposure ID: %d\n", exp_id); return -EINVAL; } @@ -10506,7 +10376,8 @@ ia_css_unlock_raw_frame(struct ia_css_stream *stream, uint32_t exp_id) { */ int ia_css_pipe_set_qos_ext_state(struct ia_css_pipe *pipe, uint32_t fw_handle, - bool enable) { + bool enable) +{ unsigned int thread_id; struct ia_css_pipeline_stage *stage; int err = 0; @@ -10514,20 +10385,16 @@ ia_css_pipe_set_qos_ext_state(struct ia_css_pipe *pipe, uint32_t fw_handle, IA_CSS_ENTER(""); /* Parameter Check */ - if (!pipe || !pipe->stream) - { + if (!pipe || !pipe->stream) { IA_CSS_ERROR("Invalid Pipe."); err = -EINVAL; - } else if (!(pipe->config.acc_extension)) - { + } else if (!(pipe->config.acc_extension)) { IA_CSS_ERROR("Invalid Pipe(No Extension Firmware)"); err = -EINVAL; - } else if (!sh_css_sp_is_running()) - { + } else if (!sh_css_sp_is_running()) { IA_CSS_ERROR("Leaving: queue unavailable."); err = -EBUSY; - } else - { + } else { /* Query the threadid and stage_num for the Extension firmware*/ ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id); err = ia_css_pipeline_get_stage_from_fw(&pipe->pipeline, fw_handle, &stage); @@ -10555,7 +10422,8 @@ ia_css_pipe_set_qos_ext_state(struct ia_css_pipe *pipe, uint32_t fw_handle, */ int ia_css_pipe_get_qos_ext_state(struct ia_css_pipe *pipe, uint32_t fw_handle, - bool *enable) { + bool *enable) +{ struct ia_css_pipeline_stage *stage; unsigned int thread_id; int err = 0; @@ -10563,20 +10431,16 @@ ia_css_pipe_get_qos_ext_state(struct ia_css_pipe *pipe, uint32_t fw_handle, IA_CSS_ENTER(""); /* Parameter Check */ - if (!pipe || !pipe->stream) - { + if (!pipe || !pipe->stream) { IA_CSS_ERROR("Invalid Pipe."); err = -EINVAL; - } else if (!(pipe->config.acc_extension)) - { + } else if (!(pipe->config.acc_extension)) { IA_CSS_ERROR("Invalid Pipe (No Extension Firmware)."); err = -EINVAL; - } else if (!sh_css_sp_is_running()) - { + } else if (!sh_css_sp_is_running()) { IA_CSS_ERROR("Leaving: queue unavailable."); err = -EBUSY; - } else - { + } else { /* Query the threadid and stage_num corresponding to the Extension firmware*/ ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id); err = ia_css_pipeline_get_stage_from_fw(&pipe->pipeline, fw_handle, &stage); @@ -10596,7 +10460,8 @@ int ia_css_pipe_update_qos_ext_mapped_arg(struct ia_css_pipe *pipe, u32 fw_handle, struct ia_css_isp_param_css_segments *css_seg, - struct ia_css_isp_param_isp_segments *isp_seg) { + struct ia_css_isp_param_isp_segments *isp_seg) +{ unsigned int HIVE_ADDR_sp_group; static struct sh_css_sp_group sp_group; static struct sh_css_sp_stage sp_stage; @@ -10614,20 +10479,16 @@ ia_css_pipe_update_qos_ext_mapped_arg(struct ia_css_pipe *pipe, fw = &sh_css_sp_fw; /* Parameter Check */ - if (!pipe || !pipe->stream) - { + if (!pipe || !pipe->stream) { IA_CSS_ERROR("Invalid Pipe."); err = -EINVAL; - } else if (!(pipe->config.acc_extension)) - { + } else if (!(pipe->config.acc_extension)) { IA_CSS_ERROR("Invalid Pipe (No Extension Firmware)."); err = -EINVAL; - } else if (!sh_css_sp_is_running()) - { + } else if (!sh_css_sp_is_running()) { IA_CSS_ERROR("Leaving: queue unavailable."); err = -EBUSY; - } else - { + } else { /* Query the thread_id and stage_num corresponding to the Extension firmware */ ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id); err = ia_css_pipeline_get_stage_from_fw(&pipe->pipeline, fw_handle, &stage); @@ -10678,7 +10539,8 @@ ia_css_pipe_update_qos_ext_mapped_arg(struct ia_css_pipe *pipe, static int aspect_ratio_crop_init(struct ia_css_stream *curr_stream, struct ia_css_pipe *pipes[], - bool *do_crop_status) { + bool *do_crop_status) +{ int err = 0; int i; struct ia_css_pipe *curr_pipe; @@ -10687,15 +10549,13 @@ aspect_ratio_crop_init(struct ia_css_stream *curr_stream, if ((!curr_stream) || (curr_stream->num_pipes == 0) || (!pipes) || - (!do_crop_status)) - { + (!do_crop_status)) { err = -EINVAL; IA_CSS_LEAVE_ERR(err); return err; } - for (i = 0; i < curr_stream->num_pipes; i++) - { + for (i = 0; i < curr_stream->num_pipes; i++) { curr_pipe = pipes[i]; pipe_mask |= (1 << curr_pipe->config.mode); } @@ -10709,7 +10569,8 @@ aspect_ratio_crop_init(struct ia_css_stream *curr_stream, } static bool -aspect_ratio_crop_check(bool enabled, struct ia_css_pipe *curr_pipe) { +aspect_ratio_crop_check(bool enabled, struct ia_css_pipe *curr_pipe) +{ bool status = false; if ((curr_pipe) && enabled) { @@ -10724,7 +10585,8 @@ aspect_ratio_crop_check(bool enabled, struct ia_css_pipe *curr_pipe) { static int aspect_ratio_crop(struct ia_css_pipe *curr_pipe, - struct ia_css_resolution *effective_res) { + struct ia_css_resolution *effective_res) +{ int err = 0; struct ia_css_resolution crop_res; struct ia_css_resolution *in_res = NULL; @@ -10734,8 +10596,7 @@ aspect_ratio_crop(struct ia_css_pipe *curr_pipe, bool use_capt_pp_in_res = false; if ((!curr_pipe) || - (!effective_res)) - { + (!effective_res)) { err = -EINVAL; IA_CSS_LEAVE_ERR(err); return err; @@ -10743,8 +10604,7 @@ aspect_ratio_crop(struct ia_css_pipe *curr_pipe, if ((curr_pipe->config.mode != IA_CSS_PIPE_MODE_PREVIEW) && (curr_pipe->config.mode != IA_CSS_PIPE_MODE_VIDEO) && - (curr_pipe->config.mode != IA_CSS_PIPE_MODE_CAPTURE)) - { + (curr_pipe->config.mode != IA_CSS_PIPE_MODE_CAPTURE)) { err = -EINVAL; IA_CSS_LEAVE_ERR(err); return err; @@ -10765,8 +10625,7 @@ aspect_ratio_crop(struct ia_css_pipe *curr_pipe, in_res = &curr_pipe->stream->config.input_config.effective_res; out_res = &curr_pipe->output_info[0].res; - switch (curr_pipe->config.mode) - { + switch (curr_pipe->config.mode) { case IA_CSS_PIPE_MODE_PREVIEW: if (use_bds_output_info) out_res = &curr_pipe->bds_output_info.res; @@ -10793,20 +10652,19 @@ aspect_ratio_crop(struct ia_css_pipe *curr_pipe, err = ia_css_frame_find_crop_resolution(in_res, out_res, &crop_res); if (!err) - { *effective_res = crop_res; - } else - { + else /* in case of error fallback to default * effective resolution from driver. */ IA_CSS_LOG("ia_css_frame_find_crop_resolution() failed with err(%d)", err); - } + return err; } #endif static void -sh_css_hmm_buffer_record_init(void) { +sh_css_hmm_buffer_record_init(void) +{ int i; for (i = 0; i < MAX_HMM_BUFFER_NUM; i++) @@ -10814,7 +10672,8 @@ sh_css_hmm_buffer_record_init(void) { } static void -sh_css_hmm_buffer_record_uninit(void) { +sh_css_hmm_buffer_record_uninit(void) +{ int i; struct sh_css_hmm_buffer_record *buffer_record = NULL; @@ -10830,7 +10689,8 @@ sh_css_hmm_buffer_record_uninit(void) { } static void -sh_css_hmm_buffer_record_reset(struct sh_css_hmm_buffer_record *buffer_record) { +sh_css_hmm_buffer_record_reset(struct sh_css_hmm_buffer_record *buffer_record) +{ assert(buffer_record); buffer_record->in_use = false; buffer_record->type = IA_CSS_BUFFER_TYPE_INVALID; @@ -10841,7 +10701,8 @@ sh_css_hmm_buffer_record_reset(struct sh_css_hmm_buffer_record *buffer_record) { static struct sh_css_hmm_buffer_record *sh_css_hmm_buffer_record_acquire(struct ia_css_rmgr_vbuf_handle *h_vbuf, enum ia_css_buffer_type type, - hrt_address kernel_ptr) { + hrt_address kernel_ptr) +{ int i; struct sh_css_hmm_buffer_record *buffer_record = NULL; struct sh_css_hmm_buffer_record *out_buffer_record = NULL; @@ -10869,7 +10730,8 @@ static struct sh_css_hmm_buffer_record static struct sh_css_hmm_buffer_record *sh_css_hmm_buffer_record_validate(ia_css_ptr ddr_buffer_addr, - enum ia_css_buffer_type type) { + enum ia_css_buffer_type type) +{ int i; struct sh_css_hmm_buffer_record *buffer_record = NULL; bool found_record = false; From dfdd8ceb6f748abe4848fe09dedc4e5fc4c5635b Mon Sep 17 00:00:00 2001 From: Martiros Shakhzadyan Date: Mon, 19 Apr 2021 21:25:56 +0200 Subject: [PATCH 051/394] media: staging: media: atomisp: Remove all redundant assertions in sh_css.c Remove the remainder of assert() in places where the condition is already handled. Signed-off-by: Martiros Shakhzadyan Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/sh_css.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/sh_css.c b/drivers/staging/media/atomisp/pci/sh_css.c index ac748da7a7ef..8484c83ad29f 100644 --- a/drivers/staging/media/atomisp/pci/sh_css.c +++ b/drivers/staging/media/atomisp/pci/sh_css.c @@ -4119,9 +4119,6 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe, /* TODO: change next to correct pool for optimization */ ia_css_rmgr_acq_vbuf(hmm_buffer_pool, &h_vbuf); - assert(h_vbuf); - assert(h_vbuf->vptr != 0x0); - if ((!h_vbuf) || (h_vbuf->vptr == 0x0)) { IA_CSS_LEAVE_ERR(-EINVAL); return -EINVAL; @@ -4921,7 +4918,6 @@ sh_css_pipes_stop(struct ia_css_stream *stream) enum ia_css_pipe_id main_pipe_id; int i; - assert(stream); if (!stream) { IA_CSS_LOG("stream does NOT exist!"); err = -EINVAL; @@ -4929,7 +4925,6 @@ sh_css_pipes_stop(struct ia_css_stream *stream) } main_pipe = stream->last_pipe; - assert(main_pipe); if (!main_pipe) { IA_CSS_LOG("main_pipe does NOT exist!"); err = -EINVAL; @@ -4987,7 +4982,6 @@ sh_css_pipes_stop(struct ia_css_stream *stream) copy_pipe = main_pipe->pipe_settings.video.copy_pipe; /* return the error code if "Copy Pipe" does NOT exist */ - assert(copy_pipe); if (!copy_pipe) { IA_CSS_LOG("Copy Pipe does NOT exist!"); err = -EINVAL; @@ -5022,7 +5016,6 @@ sh_css_pipes_have_stopped(struct ia_css_stream *stream) int i; - assert(stream); if (!stream) { IA_CSS_LOG("stream does NOT exist!"); rval = false; @@ -5030,7 +5023,6 @@ sh_css_pipes_have_stopped(struct ia_css_stream *stream) } main_pipe = stream->last_pipe; - assert(main_pipe); if (!main_pipe) { IA_CSS_LOG("main_pipe does NOT exist!"); @@ -5071,7 +5063,6 @@ sh_css_pipes_have_stopped(struct ia_css_stream *stream) copy_pipe = main_pipe->pipe_settings.video.copy_pipe; /* return if "Copy Pipe" does NOT exist */ - assert(copy_pipe); if (!copy_pipe) { IA_CSS_LOG("Copy Pipe does NOT exist!"); @@ -8783,8 +8774,6 @@ ia_css_pipe_get_info(const struct ia_css_pipe *pipe, { ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_pipe_get_info()\n"); - - assert(pipe_info); if (!pipe_info) { ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR, "ia_css_pipe_get_info: pipe_info cannot be NULL\n"); @@ -8923,7 +8912,6 @@ ia_css_acc_stream_create(struct ia_css_stream *stream) int i; int err = 0; - assert(stream); IA_CSS_ENTER_PRIVATE("stream = %p", stream); if (!stream) { @@ -8934,7 +8922,6 @@ ia_css_acc_stream_create(struct ia_css_stream *stream) for (i = 0; i < stream->num_pipes; i++) { struct ia_css_pipe *pipe = stream->pipes[i]; - assert(pipe); if (!pipe) { IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL); return -EINVAL; From 9d634547323e7cb7dd11c68075e8128ce68544ae Mon Sep 17 00:00:00 2001 From: Martiros Shakhzadyan Date: Mon, 19 Apr 2021 21:25:57 +0200 Subject: [PATCH 052/394] media: staging: media: atomisp: Remove a superfluous else clause in sh_css.c Remove a superfluous else clause in ia_css_pipe_check_format() Signed-off-by: Martiros Shakhzadyan Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/sh_css.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/sh_css.c b/drivers/staging/media/atomisp/pci/sh_css.c index 8484c83ad29f..4d4f030e0fe0 100644 --- a/drivers/staging/media/atomisp/pci/sh_css.c +++ b/drivers/staging/media/atomisp/pci/sh_css.c @@ -5247,11 +5247,9 @@ ia_css_pipe_check_format(struct ia_css_pipe *pipe, IA_CSS_ERROR("Requested format is not supported by binary"); IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL); return -EINVAL; - } else - { - IA_CSS_LEAVE_ERR_PRIVATE(0); - return 0; } + IA_CSS_LEAVE_ERR_PRIVATE(0); + return 0; } static int load_video_binaries(struct ia_css_pipe *pipe) From d4bc34d18201120b247506b4a6ed17af694dfcf7 Mon Sep 17 00:00:00 2001 From: Martiros Shakhzadyan Date: Mon, 19 Apr 2021 21:26:00 +0200 Subject: [PATCH 053/394] media: staging: media: atomisp: Replace if else clause with a ternary Use the ternary operator for conditional variable assignment in create_host_video_pipeline(). Signed-off-by: Martiros Shakhzadyan Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/sh_css.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/sh_css.c b/drivers/staging/media/atomisp/pci/sh_css.c index 4d4f030e0fe0..346f57147d90 100644 --- a/drivers/staging/media/atomisp/pci/sh_css.c +++ b/drivers/staging/media/atomisp/pci/sh_css.c @@ -3617,11 +3617,8 @@ static int create_host_video_pipeline(struct ia_css_pipe *pipe) struct ia_css_frame *tmp_out_frame = NULL; for (i = 0; i < num_yuv_scaler; i++) { - if (is_output_stage[i]) { - tmp_out_frame = out_frame; - } else { - tmp_out_frame = NULL; - } + tmp_out_frame = is_output_stage[i] ? out_frame : NULL; + err = add_yuv_scaler_stage(pipe, me, tmp_in_frame, tmp_out_frame, NULL, &yuv_scaler_binary[i], From 7796e455170efa1823457b17a292b1c65bb8c1e0 Mon Sep 17 00:00:00 2001 From: Martiros Shakhzadyan Date: Fri, 23 Apr 2021 18:13:48 +0200 Subject: [PATCH 054/394] media: staging: media: atomisp: Fix alignment and line length issues Fix alignment style issues and adjacent line length issues in sh_css.c Signed-off-by: Martiros Shakhzadyan Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/sh_css.c | 619 +++++++++++---------- 1 file changed, 333 insertions(+), 286 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/sh_css.c b/drivers/staging/media/atomisp/pci/sh_css.c index 346f57147d90..0482bfa2c490 100644 --- a/drivers/staging/media/atomisp/pci/sh_css.c +++ b/drivers/staging/media/atomisp/pci/sh_css.c @@ -239,8 +239,8 @@ ia_css_reset_defaults(struct sh_css *css); static void sh_css_init_host_sp_control_vars(void); -static int set_num_primary_stages(unsigned int *num, - enum ia_css_pipe_version version); +static int +set_num_primary_stages(unsigned int *num, enum ia_css_pipe_version version); static bool need_capture_pp(const struct ia_css_pipe *pipe); @@ -2996,9 +2996,8 @@ static int add_firmwares( ia_css_pipe_get_firmwares_stage_desc(&stage_desc, binary, out, in, vf, fw, binary_mode); - err = ia_css_pipeline_create_and_add_stage(me, - &stage_desc, - &extra_stage); + err = ia_css_pipeline_create_and_add_stage(me, &stage_desc, + &extra_stage); if (err) return err; if (fw->info.isp.sp.enable.output != 0) @@ -3106,9 +3105,8 @@ static int add_yuv_scaler_stage( ia_css_pipe_get_generic_stage_desc(&stage_desc, yuv_scaler_binary, out_frames, in_frame, vf_frame); } - err = ia_css_pipeline_create_and_add_stage(me, - &stage_desc, - pre_vf_pp_stage); + err = ia_css_pipeline_create_and_add_stage(me, &stage_desc, + pre_vf_pp_stage); if (err) return err; in_frame = (*pre_vf_pp_stage)->args.out_frame[0]; @@ -3166,9 +3164,8 @@ static int add_capture_pp_stage( ia_css_pipe_get_generic_stage_desc(&stage_desc, capture_pp_binary, out_frames, NULL, vf_frame); } - err = ia_css_pipeline_create_and_add_stage(me, - &stage_desc, - capture_pp_stage); + err = ia_css_pipeline_create_and_add_stage(me, &stage_desc, + capture_pp_stage); if (err) return err; err = add_firmwares(me, capture_pp_binary, pipe->output_stage, last_fw, @@ -3523,9 +3520,8 @@ static int create_host_video_pipeline(struct ia_css_pipe *pipe) ia_css_pipe_util_set_output_frames(out_frames, 0, NULL); ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary, out_frames, NULL, NULL); - err = ia_css_pipeline_create_and_add_stage(me, - &stage_desc, - ©_stage); + err = ia_css_pipeline_create_and_add_stage(me, &stage_desc, + ©_stage); if (err) goto ERR; in_frame = me->stages->args.out_frame[0]; @@ -3552,9 +3548,8 @@ static int create_host_video_pipeline(struct ia_css_pipe *pipe) ia_css_pipe_get_generic_stage_desc(&stage_desc, video_binary, out_frames, in_frame, vf_frame); } - err = ia_css_pipeline_create_and_add_stage(me, - &stage_desc, - &video_stage); + err = ia_css_pipeline_create_and_add_stage(me, &stage_desc, + &video_stage); if (err) goto ERR; @@ -3619,8 +3614,8 @@ static int create_host_video_pipeline(struct ia_css_pipe *pipe) for (i = 0; i < num_yuv_scaler; i++) { tmp_out_frame = is_output_stage[i] ? out_frame : NULL; - err = add_yuv_scaler_stage(pipe, me, tmp_in_frame, tmp_out_frame, - NULL, + err = add_yuv_scaler_stage(pipe, me, tmp_in_frame, + tmp_out_frame, NULL, &yuv_scaler_binary[i], &yuv_scaler_stage); @@ -3759,9 +3754,8 @@ create_host_preview_pipeline(struct ia_css_pipe *pipe) ia_css_pipe_util_set_output_frames(out_frames, 0, NULL); ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary, out_frames, NULL, NULL); - err = ia_css_pipeline_create_and_add_stage(me, - &stage_desc, - ©_stage); + err = ia_css_pipeline_create_and_add_stage(me, &stage_desc, + ©_stage); if (err) goto ERR; in_frame = me->stages->args.out_frame[0]; @@ -3787,9 +3781,8 @@ create_host_preview_pipeline(struct ia_css_pipe *pipe) ia_css_pipe_get_generic_stage_desc(&stage_desc, preview_binary, out_frames, in_frame, NULL); } - err = ia_css_pipeline_create_and_add_stage(me, - &stage_desc, - &preview_stage); + err = ia_css_pipeline_create_and_add_stage(me, &stage_desc, + &preview_stage); if (err) goto ERR; /* If we use copy iso preview, the input must be yuv iso raw */ @@ -4122,8 +4115,8 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe, } hmm_store(h_vbuf->vptr, - (void *)(&ddr_buffer), - sizeof(struct sh_css_hmm_buffer)); + (void *)(&ddr_buffer), + sizeof(struct sh_css_hmm_buffer)); if ((buf_type == IA_CSS_BUFFER_TYPE_3A_STATISTICS) || (buf_type == IA_CSS_BUFFER_TYPE_DIS_STATISTICS) || (buf_type == IA_CSS_BUFFER_TYPE_LACE_STATISTICS)) { @@ -4284,8 +4277,8 @@ ia_css_pipe_dequeue_buffer(struct ia_css_pipe *pipe, } hmm_load(ddr_buffer_addr, - &ddr_buffer, - sizeof(struct sh_css_hmm_buffer)); + &ddr_buffer, + sizeof(struct sh_css_hmm_buffer)); /* if the kernel_ptr is 0 or an invalid, return an error. * do not access the buffer via the kernal_ptr. @@ -4938,7 +4931,7 @@ sh_css_pipes_stop(struct ia_css_stream *stream) for (i = 0; i < stream->num_pipes; i++) { /* send the "stop" request to the "ia_css_pipe" instance */ IA_CSS_LOG("Send the stop-request to the pipe: pipe_id=%d", - stream->pipes[i]->pipeline.pipe_id); + stream->pipes[i]->pipeline.pipe_id); err = ia_css_pipeline_request_stop(&stream->pipes[i]->pipeline); /* @@ -4987,7 +4980,7 @@ sh_css_pipes_stop(struct ia_css_stream *stream) /* send the "stop" request to "Copy Pipe" */ IA_CSS_LOG("Send the stop-request to the pipe: pipe_id=%d", - copy_pipe->pipeline.pipe_id); + copy_pipe->pipeline.pipe_id); err = ia_css_pipeline_request_stop(©_pipe->pipeline); } @@ -5814,7 +5807,7 @@ static bool need_capt_ldc( } static int set_num_primary_stages(unsigned int *num, - enum ia_css_pipe_version version) + enum ia_css_pipe_version version) { int err = 0; @@ -6014,10 +6007,13 @@ static int load_primary_binaries( capt_pp_in_info = &prim_out_info; ia_css_pipe_get_capturepp_binarydesc(pipe, - &capture_pp_descr, capt_pp_in_info, - &capt_pp_out_info, &vf_info); + &capture_pp_descr, + capt_pp_in_info, + &capt_pp_out_info, + &vf_info); + err = ia_css_binary_find(&capture_pp_descr, - &mycs->capture_pp_binary); + &mycs->capture_pp_binary); if (err) { IA_CSS_LEAVE_ERR_PRIVATE(err); return err; @@ -6027,11 +6023,12 @@ static int load_primary_binaries( struct ia_css_binary_descr capt_ldc_descr; ia_css_pipe_get_ldc_binarydesc(pipe, - &capt_ldc_descr, &prim_out_info, - &capt_ldc_out_info); + &capt_ldc_descr, + &prim_out_info, + &capt_ldc_out_info); err = ia_css_binary_find(&capt_ldc_descr, - &mycs->capture_ldc_binary); + &mycs->capture_ldc_binary); if (err) { IA_CSS_LEAVE_ERR_PRIVATE(err); return err; @@ -6048,8 +6045,9 @@ static int load_primary_binaries( if (pipe->enable_viewfinder[IA_CSS_PIPE_OUTPUT_STAGE_0] && (i == mycs->num_primary_stage - 1)) local_vf_info = &vf_info; - ia_css_pipe_get_primary_binarydesc(pipe, &prim_descr[i], &prim_in_info, - &prim_out_info, local_vf_info, i); + ia_css_pipe_get_primary_binarydesc(pipe, &prim_descr[i], + &prim_in_info, &prim_out_info, + local_vf_info, i); err = ia_css_binary_find(&prim_descr[i], &mycs->primary_binary[i]); if (err) { IA_CSS_LEAVE_ERR_PRIVATE(err); @@ -6101,8 +6099,8 @@ static int load_primary_binaries( /* ISP Copy */ if (need_isp_copy_binary) { err = load_copy_binary(pipe, - &mycs->copy_binary, - &mycs->primary_binary[0]); + &mycs->copy_binary, + &mycs->primary_binary[0]); if (err) { IA_CSS_LEAVE_ERR_PRIVATE(err); return err; @@ -6211,7 +6209,7 @@ static int load_advanced_binaries( assert(pipe); assert(pipe->mode == IA_CSS_PIPE_ID_CAPTURE || - pipe->mode == IA_CSS_PIPE_ID_COPY); + pipe->mode == IA_CSS_PIPE_ID_COPY); if (pipe->pipe_settings.capture.pre_isp_binary.info) return 0; pipe_out_info = &pipe->output_info[0]; @@ -6224,17 +6222,18 @@ static int load_advanced_binaries( need_pp = need_capture_pp(pipe); ia_css_frame_info_set_format(&vf_info, - IA_CSS_FRAME_FORMAT_YUV_LINE); + IA_CSS_FRAME_FORMAT_YUV_LINE); /* we build up the pipeline starting at the end */ /* Capture post-processing */ if (need_pp) { struct ia_css_binary_descr capture_pp_descr; - ia_css_pipe_get_capturepp_binarydesc(pipe, - &capture_pp_descr, &post_out_info, pipe_out_info, &vf_info); + ia_css_pipe_get_capturepp_binarydesc(pipe, &capture_pp_descr, + &post_out_info, + pipe_out_info, &vf_info); err = ia_css_binary_find(&capture_pp_descr, - &pipe->pipe_settings.capture.capture_pp_binary); + &pipe->pipe_settings.capture.capture_pp_binary); if (err) return err; } else { @@ -6245,10 +6244,11 @@ static int load_advanced_binaries( { struct ia_css_binary_descr post_gdc_descr; - ia_css_pipe_get_post_gdc_binarydesc(pipe, - &post_gdc_descr, &post_in_info, &post_out_info, &vf_info); + ia_css_pipe_get_post_gdc_binarydesc(pipe, &post_gdc_descr, + &post_in_info, + &post_out_info, &vf_info); err = ia_css_binary_find(&post_gdc_descr, - &pipe->pipe_settings.capture.post_isp_binary); + &pipe->pipe_settings.capture.post_isp_binary); if (err) return err; } @@ -6258,9 +6258,9 @@ static int load_advanced_binaries( struct ia_css_binary_descr gdc_descr; ia_css_pipe_get_gdc_binarydesc(pipe, &gdc_descr, &gdc_in_info, - &pipe->pipe_settings.capture.post_isp_binary.in_frame_info); + &pipe->pipe_settings.capture.post_isp_binary.in_frame_info); err = ia_css_binary_find(&gdc_descr, - &pipe->pipe_settings.capture.anr_gdc_binary); + &pipe->pipe_settings.capture.anr_gdc_binary); if (err) return err; } @@ -6272,9 +6272,9 @@ static int load_advanced_binaries( struct ia_css_binary_descr pre_gdc_descr; ia_css_pipe_get_pre_gdc_binarydesc(pipe, &pre_gdc_descr, &pre_in_info, - &pipe->pipe_settings.capture.anr_gdc_binary.in_frame_info); + &pipe->pipe_settings.capture.anr_gdc_binary.in_frame_info); err = ia_css_binary_find(&pre_gdc_descr, - &pipe->pipe_settings.capture.pre_isp_binary); + &pipe->pipe_settings.capture.pre_isp_binary); if (err) return err; } @@ -6296,7 +6296,7 @@ static int load_advanced_binaries( ia_css_pipe_get_vfpp_binarydesc(pipe, &vf_pp_descr, vf_pp_in_info, pipe_vf_out_info); err = ia_css_binary_find(&vf_pp_descr, - &pipe->pipe_settings.capture.vf_pp_binary); + &pipe->pipe_settings.capture.vf_pp_binary); if (err) return err; } @@ -6308,8 +6308,8 @@ static int load_advanced_binaries( #endif if (need_isp_copy) load_copy_binary(pipe, - &pipe->pipe_settings.capture.copy_binary, - &pipe->pipe_settings.capture.pre_isp_binary); + &pipe->pipe_settings.capture.copy_binary, + &pipe->pipe_settings.capture.pre_isp_binary); return err; } @@ -6324,7 +6324,7 @@ static int load_bayer_isp_binaries( IA_CSS_ENTER_PRIVATE(""); assert(pipe); assert(pipe->mode == IA_CSS_PIPE_ID_CAPTURE || - pipe->mode == IA_CSS_PIPE_ID_COPY); + pipe->mode == IA_CSS_PIPE_ID_COPY); pipe_out_info = &pipe->output_info[0]; if (pipe->pipe_settings.capture.pre_isp_binary.info) @@ -6335,11 +6335,11 @@ static int load_bayer_isp_binaries( return err; ia_css_pipe_get_pre_de_binarydesc(pipe, &pre_de_descr, - &pre_isp_in_info, - pipe_out_info); + &pre_isp_in_info, + pipe_out_info); err = ia_css_binary_find(&pre_de_descr, - &pipe->pipe_settings.capture.pre_isp_binary); + &pipe->pipe_settings.capture.pre_isp_binary); return err; } @@ -6358,7 +6358,7 @@ static int load_low_light_binaries( IA_CSS_ENTER_PRIVATE(""); assert(pipe); assert(pipe->mode == IA_CSS_PIPE_ID_CAPTURE || - pipe->mode == IA_CSS_PIPE_ID_COPY); + pipe->mode == IA_CSS_PIPE_ID_COPY); if (pipe->pipe_settings.capture.pre_isp_binary.info) return 0; @@ -6373,17 +6373,18 @@ static int load_low_light_binaries( need_pp = need_capture_pp(pipe); ia_css_frame_info_set_format(&vf_info, - IA_CSS_FRAME_FORMAT_YUV_LINE); + IA_CSS_FRAME_FORMAT_YUV_LINE); /* we build up the pipeline starting at the end */ /* Capture post-processing */ if (need_pp) { struct ia_css_binary_descr capture_pp_descr; - ia_css_pipe_get_capturepp_binarydesc(pipe, - &capture_pp_descr, &post_out_info, pipe_out_info, &vf_info); + ia_css_pipe_get_capturepp_binarydesc(pipe, &capture_pp_descr, + &post_out_info, + pipe_out_info, &vf_info); err = ia_css_binary_find(&capture_pp_descr, - &pipe->pipe_settings.capture.capture_pp_binary); + &pipe->pipe_settings.capture.capture_pp_binary); if (err) return err; } else { @@ -6397,7 +6398,7 @@ static int load_low_light_binaries( ia_css_pipe_get_post_anr_binarydesc(pipe, &post_anr_descr, &post_in_info, &post_out_info, &vf_info); err = ia_css_binary_find(&post_anr_descr, - &pipe->pipe_settings.capture.post_isp_binary); + &pipe->pipe_settings.capture.post_isp_binary); if (err) return err; } @@ -6407,9 +6408,9 @@ static int load_low_light_binaries( struct ia_css_binary_descr anr_descr; ia_css_pipe_get_anr_binarydesc(pipe, &anr_descr, &anr_in_info, - &pipe->pipe_settings.capture.post_isp_binary.in_frame_info); + &pipe->pipe_settings.capture.post_isp_binary.in_frame_info); err = ia_css_binary_find(&anr_descr, - &pipe->pipe_settings.capture.anr_gdc_binary); + &pipe->pipe_settings.capture.anr_gdc_binary); if (err) return err; } @@ -6421,9 +6422,9 @@ static int load_low_light_binaries( struct ia_css_binary_descr pre_anr_descr; ia_css_pipe_get_pre_anr_binarydesc(pipe, &pre_anr_descr, &pre_in_info, - &pipe->pipe_settings.capture.anr_gdc_binary.in_frame_info); + &pipe->pipe_settings.capture.anr_gdc_binary.in_frame_info); err = ia_css_binary_find(&pre_anr_descr, - &pipe->pipe_settings.capture.pre_isp_binary); + &pipe->pipe_settings.capture.pre_isp_binary); if (err) return err; } @@ -6442,10 +6443,10 @@ static int load_low_light_binaries( { struct ia_css_binary_descr vf_pp_descr; - ia_css_pipe_get_vfpp_binarydesc(pipe, - &vf_pp_descr, vf_pp_in_info, pipe_vf_out_info); + ia_css_pipe_get_vfpp_binarydesc(pipe, &vf_pp_descr, + vf_pp_in_info, pipe_vf_out_info); err = ia_css_binary_find(&vf_pp_descr, - &pipe->pipe_settings.capture.vf_pp_binary); + &pipe->pipe_settings.capture.vf_pp_binary); if (err) return err; } @@ -6457,8 +6458,8 @@ static int load_low_light_binaries( #endif if (need_isp_copy) err = load_copy_binary(pipe, - &pipe->pipe_settings.capture.copy_binary, - &pipe->pipe_settings.capture.pre_isp_binary); + &pipe->pipe_settings.capture.copy_binary, + &pipe->pipe_settings.capture.pre_isp_binary); return err; } @@ -6492,7 +6493,7 @@ static int load_capture_binaries( IA_CSS_ENTER_PRIVATE(""); assert(pipe); assert(pipe->mode == IA_CSS_PIPE_ID_CAPTURE || - pipe->mode == IA_CSS_PIPE_ID_COPY); + pipe->mode == IA_CSS_PIPE_ID_COPY); if (pipe->pipe_settings.capture.primary_binary[0].info) { IA_CSS_LEAVE_ERR_PRIVATE(0); @@ -6587,7 +6588,7 @@ unload_capture_binaries(struct ia_css_pipe *pipe) static bool need_downscaling(const struct ia_css_resolution in_res, - const struct ia_css_resolution out_res) + const struct ia_css_resolution out_res) { if (in_res.width > out_res.width || in_res.height > out_res.height) return true; @@ -6658,9 +6659,9 @@ static int ia_css_pipe_create_cas_scaler_desc_single_output( descr->num_output_stage = 1; hor_ds_factor = CEIL_DIV(cas_scaler_in_info->res.width, - cas_scaler_out_info->res.width); + cas_scaler_out_info->res.width); ver_ds_factor = CEIL_DIV(cas_scaler_in_info->res.height, - cas_scaler_out_info->res.height); + cas_scaler_out_info->res.height); /* use the same horizontal and vertical downscaling factor for simplicity */ assert(hor_ds_factor == ver_ds_factor); @@ -6670,31 +6671,36 @@ static int ia_css_pipe_create_cas_scaler_desc_single_output( i *= max_scale_factor_per_stage; } - descr->in_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info), - GFP_KERNEL); + descr->in_info = kmalloc(descr->num_stage * + sizeof(struct ia_css_frame_info), + GFP_KERNEL); if (!descr->in_info) { err = -ENOMEM; goto ERR; } - descr->internal_out_info = kmalloc(descr->num_stage * sizeof( - struct ia_css_frame_info), GFP_KERNEL); + descr->internal_out_info = kmalloc(descr->num_stage * + sizeof(struct ia_css_frame_info), + GFP_KERNEL); if (!descr->internal_out_info) { err = -ENOMEM; goto ERR; } - descr->out_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info), - GFP_KERNEL); + descr->out_info = kmalloc(descr->num_stage * + sizeof(struct ia_css_frame_info), + GFP_KERNEL); if (!descr->out_info) { err = -ENOMEM; goto ERR; } - descr->vf_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info), - GFP_KERNEL); + descr->vf_info = kmalloc(descr->num_stage * + sizeof(struct ia_css_frame_info), + GFP_KERNEL); if (!descr->vf_info) { err = -ENOMEM; goto ERR; } - descr->is_output_stage = kmalloc(descr->num_stage * sizeof(bool), GFP_KERNEL); + descr->is_output_stage = kmalloc(descr->num_stage * sizeof(bool), + GFP_KERNEL); if (!descr->is_output_stage) { err = -ENOMEM; goto ERR; @@ -6738,9 +6744,9 @@ static int ia_css_pipe_create_cas_scaler_desc_single_output( max_scale_factor_per_stage; descr->internal_out_info[i].format = IA_CSS_FRAME_FORMAT_YUV420; ia_css_frame_info_init(&descr->internal_out_info[i], - tmp_in_info.res.width / max_scale_factor_per_stage, - tmp_in_info.res.height / max_scale_factor_per_stage, - IA_CSS_FRAME_FORMAT_YUV420, 0); + tmp_in_info.res.width / max_scale_factor_per_stage, + tmp_in_info.res.height / max_scale_factor_per_stage, + IA_CSS_FRAME_FORMAT_YUV420, 0); descr->out_info[i].res.width = 0; descr->out_info[i].res.height = 0; descr->vf_info[i].res.width = 0; @@ -6816,30 +6822,35 @@ static int ia_css_pipe_create_cas_scaler_desc( descr->num_stage = num_stages; descr->in_info = kmalloc_array(descr->num_stage, - sizeof(struct ia_css_frame_info), GFP_KERNEL); + sizeof(struct ia_css_frame_info), + GFP_KERNEL); if (!descr->in_info) { err = -ENOMEM; goto ERR; } - descr->internal_out_info = kmalloc(descr->num_stage * sizeof( - struct ia_css_frame_info), GFP_KERNEL); + descr->internal_out_info = kmalloc(descr->num_stage * + sizeof(struct ia_css_frame_info), + GFP_KERNEL); if (!descr->internal_out_info) { err = -ENOMEM; goto ERR; } - descr->out_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info), - GFP_KERNEL); + descr->out_info = kmalloc(descr->num_stage * + sizeof(struct ia_css_frame_info), + GFP_KERNEL); if (!descr->out_info) { err = -ENOMEM; goto ERR; } - descr->vf_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info), - GFP_KERNEL); + descr->vf_info = kmalloc(descr->num_stage * + sizeof(struct ia_css_frame_info), + GFP_KERNEL); if (!descr->vf_info) { err = -ENOMEM; goto ERR; } - descr->is_output_stage = kmalloc(descr->num_stage * sizeof(bool), GFP_KERNEL); + descr->is_output_stage = kmalloc(descr->num_stage * sizeof(bool), + GFP_KERNEL); if (!descr->is_output_stage) { err = -ENOMEM; goto ERR; @@ -6849,7 +6860,7 @@ static int ia_css_pipe_create_cas_scaler_desc( if (out_info[i]) { if (i > 0) { assert((out_info[i - 1]->res.width >= out_info[i]->res.width) && - (out_info[i - 1]->res.height >= out_info[i]->res.height)); + (out_info[i - 1]->res.height >= out_info[i]->res.height)); } } } @@ -6897,9 +6908,9 @@ static int ia_css_pipe_create_cas_scaler_desc( max_scale_factor_per_stage; descr->internal_out_info[i].format = IA_CSS_FRAME_FORMAT_YUV420; ia_css_frame_info_init(&descr->internal_out_info[i], - tmp_in_info.res.width / max_scale_factor_per_stage, - tmp_in_info.res.height / max_scale_factor_per_stage, - IA_CSS_FRAME_FORMAT_YUV420, 0); + tmp_in_info.res.width / max_scale_factor_per_stage, + tmp_in_info.res.height / max_scale_factor_per_stage, + IA_CSS_FRAME_FORMAT_YUV420, 0); descr->out_info[i].res.width = 0; descr->out_info[i].res.height = 0; descr->vf_info[i].res.width = 0; @@ -6978,13 +6989,14 @@ load_yuvpp_binaries(struct ia_css_pipe *pipe) struct ia_css_binary_descr yuv_scaler_descr; err = ia_css_pipe_create_cas_scaler_desc(pipe, - &cas_scaler_descr); + &cas_scaler_descr); if (err) goto ERR; mycs->num_output = cas_scaler_descr.num_output_stage; mycs->num_yuv_scaler = cas_scaler_descr.num_stage; mycs->yuv_scaler_binary = kzalloc(cas_scaler_descr.num_stage * - sizeof(struct ia_css_binary), GFP_KERNEL); + sizeof(struct ia_css_binary), + GFP_KERNEL); if (!mycs->yuv_scaler_binary) { err = -ENOMEM; goto ERR; @@ -6998,12 +7010,13 @@ load_yuvpp_binaries(struct ia_css_pipe *pipe) for (i = 0; i < cas_scaler_descr.num_stage; i++) { mycs->is_output_stage[i] = cas_scaler_descr.is_output_stage[i]; ia_css_pipe_get_yuvscaler_binarydesc(pipe, - &yuv_scaler_descr, &cas_scaler_descr.in_info[i], - &cas_scaler_descr.out_info[i], - &cas_scaler_descr.internal_out_info[i], - &cas_scaler_descr.vf_info[i]); + &yuv_scaler_descr, + &cas_scaler_descr.in_info[i], + &cas_scaler_descr.out_info[i], + &cas_scaler_descr.internal_out_info[i], + &cas_scaler_descr.vf_info[i]); err = ia_css_binary_find(&yuv_scaler_descr, - &mycs->yuv_scaler_binary[i]); + &mycs->yuv_scaler_binary[i]); if (err) goto ERR; } @@ -7043,8 +7056,8 @@ load_yuvpp_binaries(struct ia_css_pipe *pipe) if (need_isp_copy_binary) { err = load_copy_binary(pipe, - &mycs->copy_binary, - next_binary); + &mycs->copy_binary, + next_binary); if (err) goto ERR; @@ -7089,8 +7102,9 @@ load_yuvpp_binaries(struct ia_css_pipe *pipe) mycs->num_vf_pp = 1; } - mycs->vf_pp_binary = kzalloc(mycs->num_vf_pp * sizeof(struct ia_css_binary), - GFP_KERNEL); + mycs->vf_pp_binary = kzalloc(mycs->num_vf_pp * + sizeof(struct ia_css_binary), + GFP_KERNEL); if (!mycs->vf_pp_binary) { err = -ENOMEM; goto ERR; @@ -7419,18 +7433,26 @@ create_host_yuvpp_pipeline(struct ia_css_pipe *pipe) #endif if (need_scaler) { - ia_css_pipe_util_set_output_frames(bin_out_frame, 0, NULL); - ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary, - bin_out_frame, in_frame_local, NULL); + ia_css_pipe_util_set_output_frames(bin_out_frame, + 0, NULL); + ia_css_pipe_get_generic_stage_desc(&stage_desc, + copy_binary, + bin_out_frame, + in_frame_local, + NULL); } else { - ia_css_pipe_util_set_output_frames(bin_out_frame, 0, out_frame[0]); - ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary, - bin_out_frame, in_frame_local, NULL); + ia_css_pipe_util_set_output_frames(bin_out_frame, + 0, out_frame[0]); + ia_css_pipe_get_generic_stage_desc(&stage_desc, + copy_binary, + bin_out_frame, + in_frame_local, + NULL); } err = ia_css_pipeline_create_and_add_stage(me, - &stage_desc, - ©_stage); + &stage_desc, + ©_stage); if (err) { IA_CSS_LEAVE_ERR_PRIVATE(err); @@ -7462,10 +7484,11 @@ create_host_yuvpp_pipeline(struct ia_css_pipe *pipe) tmp_vf_frame = NULL; } - err = add_yuv_scaler_stage(pipe, me, tmp_in_frame, tmp_out_frame, - NULL, - &yuv_scaler_binary[i], - &yuv_scaler_stage); + err = add_yuv_scaler_stage(pipe, me, tmp_in_frame, + tmp_out_frame, + NULL, + &yuv_scaler_binary[i], + &yuv_scaler_stage); if (err) { IA_CSS_LEAVE_ERR_PRIVATE(err); @@ -7476,8 +7499,10 @@ create_host_yuvpp_pipeline(struct ia_css_pipe *pipe) if (pipe->pipe_settings.yuvpp.is_output_stage[i]) { if (tmp_vf_frame && (tmp_vf_frame->info.res.width != 0)) { in_frame = yuv_scaler_stage->args.out_vf_frame; - err = add_vf_pp_stage(pipe, in_frame, tmp_vf_frame, &vf_pp_binary[j], - &vf_pp_stage); + err = add_vf_pp_stage(pipe, in_frame, + tmp_vf_frame, + &vf_pp_binary[j], + &vf_pp_stage); if (err) { IA_CSS_LEAVE_ERR_PRIVATE(err); @@ -7490,8 +7515,8 @@ create_host_yuvpp_pipeline(struct ia_css_pipe *pipe) } else if (copy_stage) { if (vf_frame[0] && vf_frame[0]->info.res.width != 0) { in_frame = copy_stage->args.out_vf_frame; - err = add_vf_pp_stage(pipe, in_frame, vf_frame[0], &vf_pp_binary[0], - &vf_pp_stage); + err = add_vf_pp_stage(pipe, in_frame, vf_frame[0], + &vf_pp_binary[0], &vf_pp_stage); } if (err) { IA_CSS_LEAVE_ERR_PRIVATE(err); @@ -7499,7 +7524,8 @@ create_host_yuvpp_pipeline(struct ia_css_pipe *pipe) } } - ia_css_pipeline_finalize_stages(&pipe->pipeline, pipe->stream->config.continuous); + ia_css_pipeline_finalize_stages(&pipe->pipeline, + pipe->stream->config.continuous); IA_CSS_LEAVE_ERR_PRIVATE(0); @@ -7508,8 +7534,8 @@ create_host_yuvpp_pipeline(struct ia_css_pipe *pipe) static int create_host_copy_pipeline(struct ia_css_pipe *pipe, - unsigned int max_input_width, - struct ia_css_frame *out_frame) + unsigned int max_input_width, + struct ia_css_frame *out_frame) { struct ia_css_pipeline *me; int err = 0; @@ -7528,12 +7554,8 @@ create_host_copy_pipeline(struct ia_css_pipe *pipe, if (copy_on_sp(pipe) && pipe->stream->config.input_config.format == ATOMISP_INPUT_FORMAT_BINARY_8) { - ia_css_frame_info_init( - &out_frame->info, - JPEG_BYTES, - 1, - IA_CSS_FRAME_FORMAT_BINARY_8, - 0); + ia_css_frame_info_init(&out_frame->info, JPEG_BYTES, 1, + IA_CSS_FRAME_FORMAT_BINARY_8, 0); } else if (out_frame->info.format == IA_CSS_FRAME_FORMAT_RAW) { out_frame->info.raw_bit_depth = ia_css_pipe_util_pipe_input_format_bpp(pipe); @@ -7544,12 +7566,12 @@ create_host_copy_pipeline(struct ia_css_pipe *pipe, pipe->mode = IA_CSS_PIPE_ID_COPY; ia_css_pipe_get_sp_func_stage_desc(&stage_desc, out_frame, - IA_CSS_PIPELINE_RAW_COPY, max_input_width); - err = ia_css_pipeline_create_and_add_stage(me, - &stage_desc, - NULL); + IA_CSS_PIPELINE_RAW_COPY, + max_input_width); + err = ia_css_pipeline_create_and_add_stage(me, &stage_desc, NULL); - ia_css_pipeline_finalize_stages(&pipe->pipeline, pipe->stream->config.continuous); + ia_css_pipeline_finalize_stages(&pipe->pipeline, + pipe->stream->config.continuous); ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "create_host_copy_pipeline() leave:\n"); @@ -7588,9 +7610,10 @@ create_host_isyscopy_capture_pipeline(struct ia_css_pipe *pipe) me->pipe_id = IA_CSS_PIPE_ID_CAPTURE; pipe->mode = IA_CSS_PIPE_ID_CAPTURE; ia_css_pipe_get_sp_func_stage_desc(&stage_desc, out_frame, - IA_CSS_PIPELINE_ISYS_COPY, max_input_width); + IA_CSS_PIPELINE_ISYS_COPY, + max_input_width); err = ia_css_pipeline_create_and_add_stage(me, - &stage_desc, &out_stage); + &stage_desc, &out_stage); if (err) return err; @@ -7642,7 +7665,8 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) IA_CSS_ENTER_PRIVATE(""); assert(pipe); assert(pipe->stream); - assert(pipe->mode == IA_CSS_PIPE_ID_CAPTURE || pipe->mode == IA_CSS_PIPE_ID_COPY); + assert(pipe->mode == IA_CSS_PIPE_ID_CAPTURE || + pipe->mode == IA_CSS_PIPE_ID_COPY); me = &pipe->pipeline; mode = pipe->config.default_capture_config.mode; @@ -7732,26 +7756,37 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame); #if defined(ISP2401) if (!continuous) { - ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary, - out_frames, in_frame, NULL); + ia_css_pipe_get_generic_stage_desc(&stage_desc, + copy_binary, + out_frames, + in_frame, + NULL); } else { in_frame = pipe->stream->last_pipe->continuous_frames[0]; - ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary, - out_frames, in_frame, NULL); + ia_css_pipe_get_generic_stage_desc(&stage_desc, + copy_binary, + out_frames, + in_frame, + NULL); } #else - ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary, - out_frames, NULL, NULL); + ia_css_pipe_get_generic_stage_desc(&stage_desc, + copy_binary, + out_frames, + NULL, NULL); #endif } else { - ia_css_pipe_util_set_output_frames(out_frames, 0, in_frame); - ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary, - out_frames, NULL, NULL); + ia_css_pipe_util_set_output_frames(out_frames, 0, + in_frame); + ia_css_pipe_get_generic_stage_desc(&stage_desc, + copy_binary, + out_frames, + NULL, NULL); } err = ia_css_pipeline_create_and_add_stage(me, - &stage_desc, - ¤t_stage); + &stage_desc, + ¤t_stage); if (err) { IA_CSS_LEAVE_ERR_PRIVATE(err); return err; @@ -7788,11 +7823,14 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) * Proper investigation should be done to come up with the clean * solution. * */ - ia_css_pipe_get_generic_stage_desc(&stage_desc, primary_binary[i], - out_frames, local_in_frame, NULL); + ia_css_pipe_get_generic_stage_desc(&stage_desc, + primary_binary[i], + out_frames, + local_in_frame, + NULL); err = ia_css_pipeline_create_and_add_stage(me, - &stage_desc, - ¤t_stage); + &stage_desc, + ¤t_stage); if (err) { IA_CSS_LEAVE_ERR_PRIVATE(err); return err; @@ -7808,18 +7846,18 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) mode == IA_CSS_CAPTURE_MODE_LOW_LIGHT) { ia_css_pipe_util_set_output_frames(out_frames, 0, NULL); ia_css_pipe_get_generic_stage_desc(&stage_desc, pre_isp_binary, - out_frames, in_frame, NULL); - err = ia_css_pipeline_create_and_add_stage(me, - &stage_desc, NULL); + out_frames, in_frame, NULL); + err = ia_css_pipeline_create_and_add_stage(me, &stage_desc, + NULL); if (err) { IA_CSS_LEAVE_ERR_PRIVATE(err); return err; } ia_css_pipe_util_set_output_frames(out_frames, 0, NULL); ia_css_pipe_get_generic_stage_desc(&stage_desc, anr_gdc_binary, - out_frames, NULL, NULL); - err = ia_css_pipeline_create_and_add_stage(me, - &stage_desc, NULL); + out_frames, NULL, NULL); + err = ia_css_pipeline_create_and_add_stage(me, &stage_desc, + NULL); if (err) { IA_CSS_LEAVE_ERR_PRIVATE(err); return err; @@ -7827,16 +7865,21 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) if (need_pp) { ia_css_pipe_util_set_output_frames(out_frames, 0, NULL); - ia_css_pipe_get_generic_stage_desc(&stage_desc, post_isp_binary, - out_frames, NULL, NULL); + ia_css_pipe_get_generic_stage_desc(&stage_desc, + post_isp_binary, + out_frames, + NULL, NULL); } else { - ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame); - ia_css_pipe_get_generic_stage_desc(&stage_desc, post_isp_binary, - out_frames, NULL, NULL); + ia_css_pipe_util_set_output_frames(out_frames, 0, + out_frame); + ia_css_pipe_get_generic_stage_desc(&stage_desc, + post_isp_binary, + out_frames, + NULL, NULL); } - err = ia_css_pipeline_create_and_add_stage(me, - &stage_desc, ¤t_stage); + err = ia_css_pipeline_create_and_add_stage(me, &stage_desc, + ¤t_stage); if (err) { IA_CSS_LEAVE_ERR_PRIVATE(err); return err; @@ -7844,10 +7887,9 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) } else if (mode == IA_CSS_CAPTURE_MODE_BAYER) { ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame); ia_css_pipe_get_generic_stage_desc(&stage_desc, pre_isp_binary, - out_frames, in_frame, NULL); - err = ia_css_pipeline_create_and_add_stage(me, - &stage_desc, - NULL); + out_frames, in_frame, NULL); + err = ia_css_pipeline_create_and_add_stage(me, &stage_desc, + NULL); if (err) { IA_CSS_LEAVE_ERR_PRIVATE(err); return err; @@ -7862,31 +7904,34 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) if (need_ldc) { ia_css_pipe_util_set_output_frames(out_frames, 0, NULL); - ia_css_pipe_get_generic_stage_desc(&stage_desc, capture_ldc_binary, - out_frames, local_in_frame, NULL); + ia_css_pipe_get_generic_stage_desc(&stage_desc, + capture_ldc_binary, + out_frames, + local_in_frame, + NULL); err = ia_css_pipeline_create_and_add_stage(me, - &stage_desc, - ¤t_stage); + &stage_desc, + ¤t_stage); local_in_frame = current_stage->args.out_frame[0]; } err = add_capture_pp_stage(pipe, me, local_in_frame, - need_yuv_pp ? NULL : out_frame, + need_yuv_pp ? NULL : out_frame, #else /* ldc and capture_pp not supported in same pipeline */ if (need_ldc && current_stage) { in_frame = current_stage->args.out_frame[0]; ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame); ia_css_pipe_get_generic_stage_desc(&stage_desc, capture_ldc_binary, - out_frames, in_frame, NULL); - err = ia_css_pipeline_create_and_add_stage(me, - &stage_desc, - NULL); + out_frames, in_frame, NULL); + err = ia_css_pipeline_create_and_add_stage(me, &stage_desc, + NULL); } else if (need_pp && current_stage) { in_frame = current_stage->args.out_frame[0]; - err = add_capture_pp_stage(pipe, me, in_frame, need_yuv_pp ? NULL : out_frame, + err = add_capture_pp_stage(pipe, me, in_frame, + need_yuv_pp ? NULL : out_frame, #endif - capture_pp_binary, - ¤t_stage); + capture_pp_binary, + ¤t_stage); if (err) { IA_CSS_LEAVE_ERR_PRIVATE(err); return err; @@ -7903,10 +7948,10 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) else tmp_out_frame = NULL; - err = add_yuv_scaler_stage(pipe, me, tmp_in_frame, tmp_out_frame, - NULL, - &yuv_scaler_binary[i], - &yuv_scaler_stage); + err = add_yuv_scaler_stage(pipe, me, tmp_in_frame, + tmp_out_frame, NULL, + &yuv_scaler_binary[i], + &yuv_scaler_stage); if (err) { IA_CSS_LEAVE_ERR_PRIVATE(err); return err; @@ -7928,7 +7973,7 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) if (mode != IA_CSS_CAPTURE_MODE_RAW && mode != IA_CSS_CAPTURE_MODE_BAYER && current_stage && vf_frame) { in_frame = current_stage->args.out_vf_frame; err = add_vf_pp_stage(pipe, in_frame, vf_frame, vf_pp_binary, - ¤t_stage); + ¤t_stage); if (err) { IA_CSS_LEAVE_ERR_PRIVATE(err); return err; @@ -7980,7 +8025,7 @@ static int capture_start( me = &pipe->pipeline; if ((pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_RAW || - pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_BAYER) && + pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_BAYER) && (pipe->config.mode != IA_CSS_PIPE_MODE_COPY)) { if (copy_on_sp(pipe)) { err = start_copy_on_sp(pipe, &me->out_frame[0]); @@ -8024,7 +8069,7 @@ static int capture_start( if (pipe->config.mode == IA_CSS_PIPE_MODE_COPY && pipe->stream->reconfigure_css_rx) { ia_css_isys_rx_configure(&pipe->stream->csi_rx_config, - pipe->stream->config.mode); + pipe->stream->config.mode); pipe->stream->reconfigure_css_rx = false; } #endif @@ -8035,8 +8080,8 @@ static int capture_start( static int sh_css_pipe_get_output_frame_info(struct ia_css_pipe *pipe, - struct ia_css_frame_info *info, - unsigned int idx) + struct ia_css_frame_info *info, + unsigned int idx) { assert(pipe); assert(info); @@ -8054,7 +8099,7 @@ sh_css_pipe_get_output_frame_info(struct ia_css_pipe *pipe, IA_CSS_FRAME_FORMAT_BINARY_8, 0); } else if (info->format == IA_CSS_FRAME_FORMAT_RAW || - info->format == IA_CSS_FRAME_FORMAT_RAW_PACKED) { + info->format == IA_CSS_FRAME_FORMAT_RAW_PACKED) { info->raw_bit_depth = ia_css_pipe_util_pipe_input_format_bpp(pipe); } @@ -8066,9 +8111,9 @@ sh_css_pipe_get_output_frame_info(struct ia_css_pipe *pipe, void ia_css_stream_send_input_frame(const struct ia_css_stream *stream, - const unsigned short *data, - unsigned int width, - unsigned int height) + const unsigned short *data, + unsigned int width, + unsigned int height) { assert(stream); @@ -8092,22 +8137,22 @@ ia_css_stream_start_input_frame(const struct ia_css_stream *stream) void ia_css_stream_send_input_line(const struct ia_css_stream *stream, - const unsigned short *data, - unsigned int width, - const unsigned short *data2, - unsigned int width2) + const unsigned short *data, + unsigned int width, + const unsigned short *data2, + unsigned int width2) { assert(stream); ia_css_inputfifo_send_line(stream->config.channel_id, - data, width, data2, width2); + data, width, data2, width2); } void ia_css_stream_send_input_embedded_line(const struct ia_css_stream *stream, - enum atomisp_input_format format, - const unsigned short *data, - unsigned int width) + enum atomisp_input_format format, + const unsigned short *data, + unsigned int width) { assert(stream); if (!data || width == 0) @@ -8228,7 +8273,7 @@ acc_unload_extension(struct ia_css_fw_info *firmware) /* Load firmware for extension */ static int ia_css_pipe_load_extension(struct ia_css_pipe *pipe, - struct ia_css_fw_info *firmware) + struct ia_css_fw_info *firmware) { int err = 0; @@ -8252,7 +8297,7 @@ ia_css_pipe_load_extension(struct ia_css_pipe *pipe, /* Unload firmware for extension */ static void ia_css_pipe_unload_extension(struct ia_css_pipe *pipe, - struct ia_css_fw_info *firmware) + struct ia_css_fw_info *firmware) { IA_CSS_ENTER_PRIVATE("fw = %p pipe = %p", firmware, pipe); @@ -8294,7 +8339,7 @@ ia_css_pipeline_uses_params(struct ia_css_pipeline *me) static int sh_css_pipeline_add_acc_stage(struct ia_css_pipeline *pipeline, - const void *acc_fw) + const void *acc_fw) { struct ia_css_fw_info *fw = (struct ia_css_fw_info *)acc_fw; /* In QoS case, load_extension already called, so skipping */ @@ -8312,8 +8357,8 @@ sh_css_pipeline_add_acc_stage(struct ia_css_pipeline *pipeline, ia_css_pipe_get_acc_stage_desc(&stage_desc, NULL, fw); err = ia_css_pipeline_create_and_add_stage(pipeline, - &stage_desc, - NULL); + &stage_desc, + NULL); } ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, @@ -8326,7 +8371,7 @@ sh_css_pipeline_add_acc_stage(struct ia_css_pipeline *pipeline, * Refer to "sh_css_internal.h" for details. */ int ia_css_stream_capture_frame(struct ia_css_stream *stream, - unsigned int exp_id) + unsigned int exp_id) { struct sh_css_tag_descr tag_descr; u32 encoded_tag_descr; @@ -8485,22 +8530,22 @@ sh_css_init_host_sp_control_vars(void) (void)HIVE_ADDR_host_sp_com; sp_dmem_store_uint32(SP0_ID, - (unsigned int)sp_address_of(ia_css_ispctrl_sp_isp_started), - (uint32_t)(0)); + (unsigned int)sp_address_of(ia_css_ispctrl_sp_isp_started), + (uint32_t)(0)); sp_dmem_store_uint32(SP0_ID, - (unsigned int)sp_address_of(host_sp_queues_initialized), - (uint32_t)(0)); + (unsigned int)sp_address_of(host_sp_queues_initialized), + (uint32_t)(0)); sp_dmem_store_uint32(SP0_ID, - (unsigned int)sp_address_of(sp_sleep_mode), - (uint32_t)(0)); + (unsigned int)sp_address_of(sp_sleep_mode), + (uint32_t)(0)); sp_dmem_store_uint32(SP0_ID, - (unsigned int)sp_address_of(ia_css_dmaproxy_sp_invalidate_tlb), - (uint32_t)(false)); + (unsigned int)sp_address_of(ia_css_dmaproxy_sp_invalidate_tlb), + (uint32_t)(false)); #ifndef ISP2401 sp_dmem_store_uint32(SP0_ID, - (unsigned int)sp_address_of(sp_stop_copy_preview), - my_css.stop_copy_preview ? (uint32_t)(1) : (uint32_t)(0)); + (unsigned int)sp_address_of(sp_stop_copy_preview), + my_css.stop_copy_preview ? (uint32_t)(1) : (uint32_t)(0)); #endif store_sp_array_uint(host_sp_com, o, host2sp_cmd_ready); @@ -8527,8 +8572,7 @@ void ia_css_pipe_config_defaults(struct ia_css_pipe_config *pipe_config) } void -ia_css_pipe_extra_config_defaults(struct ia_css_pipe_extra_config - *extra_config) +ia_css_pipe_extra_config_defaults(struct ia_css_pipe_extra_config *extra_config) { if (!extra_config) { IA_CSS_ERROR("NULL input parameter"); @@ -8602,8 +8646,8 @@ int ia_css_pipe_create(const struct ia_css_pipe_config *config, int ia_css_pipe_create_extra(const struct ia_css_pipe_config *config, - const struct ia_css_pipe_extra_config *extra_config, - struct ia_css_pipe **pipe) + const struct ia_css_pipe_extra_config *extra_config, + struct ia_css_pipe **pipe) { int err = -EINVAL; struct ia_css_pipe *internal_pipe = NULL; @@ -8671,7 +8715,7 @@ ia_css_pipe_create_extra(const struct ia_css_pipe_config *config, /* YUV downscaling */ if ((internal_pipe->config.vf_pp_in_res.width || - internal_pipe->config.capt_pp_in_res.width)) { + internal_pipe->config.capt_pp_in_res.width)) { enum ia_css_frame_format format; if (internal_pipe->config.vf_pp_in_res.width) { @@ -8747,7 +8791,7 @@ ia_css_pipe_create_extra(const struct ia_css_pipe_config *config, } if (internal_pipe->config.acc_extension) { err = ia_css_pipe_load_extension(internal_pipe, - internal_pipe->config.acc_extension); + internal_pipe->config.acc_extension); if (err) { IA_CSS_LEAVE_ERR_PRIVATE(err); kvfree(internal_pipe); @@ -8765,7 +8809,7 @@ ia_css_pipe_create_extra(const struct ia_css_pipe_config *config, int ia_css_pipe_get_info(const struct ia_css_pipe *pipe, - struct ia_css_pipe_info *pipe_info) + struct ia_css_pipe_info *pipe_info) { ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_pipe_get_info()\n"); @@ -8801,8 +8845,8 @@ bool ia_css_pipe_has_dvs_stats(struct ia_css_pipe_info *pipe_info) int ia_css_pipe_override_frame_format(struct ia_css_pipe *pipe, - int pin_index, - enum ia_css_frame_format new_format) + int pin_index, + enum ia_css_frame_format new_format) { int err = 0; @@ -8882,10 +8926,8 @@ ia_css_stream_configure_rx(struct ia_css_stream *stream) #endif static struct ia_css_pipe * -find_pipe(struct ia_css_pipe *pipes[], - unsigned int num_pipes, - enum ia_css_pipe_mode mode, - bool copy_pipe) +find_pipe(struct ia_css_pipe *pipes[], unsigned int num_pipes, + enum ia_css_pipe_mode mode, bool copy_pipe) { unsigned int i; @@ -8954,7 +8996,7 @@ ia_css_acc_stream_create(struct ia_css_stream *stream) static int metadata_info_init(const struct ia_css_metadata_config *mdc, - struct ia_css_metadata_info *md) + struct ia_css_metadata_info *md) { /* Either both width and height should be set or neither */ if ((mdc->resolution.height > 0) ^ (mdc->resolution.width > 0)) @@ -8982,7 +9024,7 @@ static int check_pipe_resolutions(const struct ia_css_pipe *pipe) } if (ia_css_util_check_res(pipe->config.input_effective_res.width, - pipe->config.input_effective_res.height) != 0) { + pipe->config.input_effective_res.height) != 0) { IA_CSS_ERROR("effective resolution not supported"); err = -EINVAL; goto EXIT; @@ -8990,7 +9032,7 @@ static int check_pipe_resolutions(const struct ia_css_pipe *pipe) if (!ia_css_util_resolution_is_zero( pipe->stream->config.input_config.input_res)) { if (!ia_css_util_res_leq(pipe->config.input_effective_res, - pipe->stream->config.input_config.input_res)) { + pipe->stream->config.input_config.input_res)) { IA_CSS_ERROR("effective resolution is larger than input resolution"); err = -EINVAL; goto EXIT; @@ -9013,9 +9055,9 @@ EXIT: int ia_css_stream_create(const struct ia_css_stream_config *stream_config, - int num_pipes, - struct ia_css_pipe *pipes[], - struct ia_css_stream **stream) + int num_pipes, + struct ia_css_pipe *pipes[], + struct ia_css_stream **stream) { struct ia_css_pipe *curr_pipe; struct ia_css_stream *curr_stream = NULL; @@ -9176,11 +9218,11 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config, case IA_CSS_INPUT_MODE_TPG: #if !defined(ISP2401) IA_CSS_LOG("tpg_configuration: x_mask=%d, y_mask=%d, x_delta=%d, y_delta=%d, xy_mask=%d", - curr_stream->config.source.tpg.x_mask, - curr_stream->config.source.tpg.y_mask, - curr_stream->config.source.tpg.x_delta, - curr_stream->config.source.tpg.y_delta, - curr_stream->config.source.tpg.xy_mask); + curr_stream->config.source.tpg.x_mask, + curr_stream->config.source.tpg.y_mask, + curr_stream->config.source.tpg.x_delta, + curr_stream->config.source.tpg.y_delta, + curr_stream->config.source.tpg.xy_mask); sh_css_sp_configure_tpg( curr_stream->config.source.tpg.x_mask, @@ -9205,9 +9247,8 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config, } #ifdef ISP2401 - err = aspect_ratio_crop_init(curr_stream, - pipes, - &aspect_ratio_crop_enabled); + err = aspect_ratio_crop_init(curr_stream, pipes, + &aspect_ratio_crop_enabled); if (err) { IA_CSS_LEAVE_ERR(err); goto ERR; @@ -9244,8 +9285,8 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config, curr_pipe->config.input_effective_res = effective_res; } IA_CSS_LOG("effective_res=%dx%d", - effective_res.width, - effective_res.height); + effective_res.width, + effective_res.height); } if (IS_ISP2401) { @@ -9273,13 +9314,13 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config, if (!spcopyonly) { sensor_binning_changed = sh_css_params_set_binning_factor(curr_stream, - curr_stream->config.sensor_binning_factor); + curr_stream->config.sensor_binning_factor); } else { sensor_binning_changed = false; } IA_CSS_LOG("sensor_binning=%d, changed=%d", - curr_stream->config.sensor_binning_factor, sensor_binning_changed); + curr_stream->config.sensor_binning_factor, sensor_binning_changed); /* loop over pipes */ IA_CSS_LOG("num_pipes=%d", num_pipes); curr_stream->cont_capt = false; @@ -9303,17 +9344,18 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config, /* Create copy pipe here, since it may not be exposed to the driver */ preview_pipe = find_pipe(pipes, num_pipes, - IA_CSS_PIPE_MODE_PREVIEW, false); + IA_CSS_PIPE_MODE_PREVIEW, false); video_pipe = find_pipe(pipes, num_pipes, - IA_CSS_PIPE_MODE_VIDEO, false); - acc_pipe = find_pipe(pipes, num_pipes, - IA_CSS_PIPE_MODE_ACC, false); + IA_CSS_PIPE_MODE_VIDEO, false); + acc_pipe = find_pipe(pipes, num_pipes, IA_CSS_PIPE_MODE_ACC, + false); if (acc_pipe && num_pipes == 2 && curr_stream->cont_capt) curr_stream->cont_capt = false; /* preview + QoS case will not need cont_capt switch */ if (curr_stream->cont_capt) { capture_pipe = find_pipe(pipes, num_pipes, - IA_CSS_PIPE_MODE_CAPTURE, false); + IA_CSS_PIPE_MODE_CAPTURE, + false); if (!capture_pipe) { err = -EINVAL; goto ERR; @@ -9395,10 +9437,12 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config, if (!spcopyonly) { if (!IS_ISP2401) err = sh_css_pipe_get_shading_info(curr_pipe, - &pipe_info->shading_info, NULL); + &pipe_info->shading_info, + NULL); else err = sh_css_pipe_get_shading_info(curr_pipe, - &pipe_info->shading_info, &curr_pipe->config); + &pipe_info->shading_info, + &curr_pipe->config); if (err) goto ERR; @@ -9408,7 +9452,8 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config, goto ERR; for (j = 0; j < IA_CSS_PIPE_MAX_OUTPUT_STAGE; j++) { sh_css_pipe_get_viewfinder_frame_info(curr_pipe, - &pipe_info->vf_output_info[j], j); + &pipe_info->vf_output_info[j], + j); if (err) goto ERR; } @@ -9593,7 +9638,7 @@ ia_css_stream_destroy(struct ia_css_stream *stream) int ia_css_stream_get_info(const struct ia_css_stream *stream, - struct ia_css_stream_info *stream_info) + struct ia_css_stream_info *stream_info) { ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_get_info: enter/exit\n"); assert(stream); @@ -9881,7 +9926,7 @@ ia_css_stream_get_3a_binary(const struct ia_css_stream *stream) int ia_css_stream_set_output_padded_width(struct ia_css_stream *stream, - unsigned int output_padded_width) + unsigned int output_padded_width) { struct ia_css_pipe *pipe; @@ -10358,7 +10403,7 @@ ia_css_unlock_raw_frame(struct ia_css_stream *stream, uint32_t exp_id) */ int ia_css_pipe_set_qos_ext_state(struct ia_css_pipe *pipe, uint32_t fw_handle, - bool enable) + bool enable) { unsigned int thread_id; struct ia_css_pipeline_stage *stage; @@ -10404,7 +10449,7 @@ ia_css_pipe_set_qos_ext_state(struct ia_css_pipe *pipe, uint32_t fw_handle, */ int ia_css_pipe_get_qos_ext_state(struct ia_css_pipe *pipe, uint32_t fw_handle, - bool *enable) + bool *enable) { struct ia_css_pipeline_stage *stage; unsigned int thread_id; @@ -10440,9 +10485,9 @@ ia_css_pipe_get_qos_ext_state(struct ia_css_pipe *pipe, uint32_t fw_handle, /* ISP2401 */ int ia_css_pipe_update_qos_ext_mapped_arg(struct ia_css_pipe *pipe, - u32 fw_handle, - struct ia_css_isp_param_css_segments *css_seg, - struct ia_css_isp_param_isp_segments *isp_seg) + u32 fw_handle, + struct ia_css_isp_param_css_segments *css_seg, + struct ia_css_isp_param_isp_segments *isp_seg) { unsigned int HIVE_ADDR_sp_group; static struct sh_css_sp_group sp_group; @@ -10477,7 +10522,7 @@ ia_css_pipe_update_qos_ext_mapped_arg(struct ia_css_pipe *pipe, if (!err) { /* Get the Extension State */ enabled = (SH_CSS_QOS_STAGE_IS_ENABLED(&sh_css_sp_group.pipe[thread_id], - stage->stage_num)) ? true : false; + stage->stage_num)) ? true : false; /* Update mapped arg only when extension stage is not enabled */ if (enabled) { IA_CSS_ERROR("Leaving: cannot update when stage is enabled."); @@ -10487,13 +10532,14 @@ ia_css_pipe_update_qos_ext_mapped_arg(struct ia_css_pipe *pipe, HIVE_ADDR_sp_group = fw->info.sp.group; sp_dmem_load(SP0_ID, - (unsigned int)sp_address_of(sp_group), - &sp_group, sizeof(struct sh_css_sp_group)); + (unsigned int)sp_address_of(sp_group), + &sp_group, + sizeof(struct sh_css_sp_group)); hmm_load(sp_group.pipe[thread_id].sp_stage_addr[stage_num], - &sp_stage, sizeof(struct sh_css_sp_stage)); + &sp_stage, sizeof(struct sh_css_sp_stage)); hmm_load(sp_stage.isp_stage_addr, - &isp_stage, sizeof(struct sh_css_isp_stage)); + &isp_stage, sizeof(struct sh_css_isp_stage)); for (mem = 0; mem < N_IA_CSS_ISP_MEMORIES; mem++) { isp_stage.mem_initializers.params[IA_CSS_PARAM_CLASS_PARAM][mem].address = @@ -10509,7 +10555,8 @@ ia_css_pipe_update_qos_ext_mapped_arg(struct ia_css_pipe *pipe, } hmm_store(sp_stage.isp_stage_addr, - &isp_stage, sizeof(struct sh_css_isp_stage)); + &isp_stage, + sizeof(struct sh_css_isp_stage)); } } } @@ -10520,8 +10567,8 @@ ia_css_pipe_update_qos_ext_mapped_arg(struct ia_css_pipe *pipe, #ifdef ISP2401 static int aspect_ratio_crop_init(struct ia_css_stream *curr_stream, - struct ia_css_pipe *pipes[], - bool *do_crop_status) + struct ia_css_pipe *pipes[], + bool *do_crop_status) { int err = 0; int i; @@ -10567,7 +10614,7 @@ aspect_ratio_crop_check(bool enabled, struct ia_css_pipe *curr_pipe) static int aspect_ratio_crop(struct ia_css_pipe *curr_pipe, - struct ia_css_resolution *effective_res) + struct ia_css_resolution *effective_res) { int err = 0; struct ia_css_resolution crop_res; @@ -10627,7 +10674,7 @@ aspect_ratio_crop(struct ia_css_pipe *curr_pipe, case IA_CSS_PIPE_MODE_YUVPP: default: IA_CSS_ERROR("aspect ratio cropping invalid args: mode[%d]\n", - curr_pipe->config.mode); + curr_pipe->config.mode); assert(0); break; } @@ -10691,7 +10738,7 @@ static struct sh_css_hmm_buffer_record assert(h_vbuf); assert((type > IA_CSS_BUFFER_TYPE_INVALID) && - (type < IA_CSS_NUM_DYNAMIC_BUFFER_TYPE)); + (type < IA_CSS_NUM_DYNAMIC_BUFFER_TYPE)); assert(kernel_ptr != 0); buffer_record = &hmm_buffer_record[0]; From 58a328830e490c5ee512519c2e8172ecc3073445 Mon Sep 17 00:00:00 2001 From: Martiros Shakhzadyan Date: Fri, 23 Apr 2021 18:12:29 +0200 Subject: [PATCH 055/394] media: staging: media: atomisp: Refactor ia_css_stream_load() Move the support check to the beginning of the function. Change the logic to avoid multiple nesting blocks. Move 'err' variable assignment outside of the if statement. Remove an unnecessary check whether 'j' is zero. Signed-off-by: Martiros Shakhzadyan Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/sh_css.c | 73 +++++++++++----------- 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/sh_css.c b/drivers/staging/media/atomisp/pci/sh_css.c index 0482bfa2c490..f1a2ba99f90e 100644 --- a/drivers/staging/media/atomisp/pci/sh_css.c +++ b/drivers/staging/media/atomisp/pci/sh_css.c @@ -9657,48 +9657,47 @@ ia_css_stream_get_info(const struct ia_css_stream *stream, int ia_css_stream_load(struct ia_css_stream *stream) { - if (!IS_ISP2401) { - int i; - int err; + int i, j, err; - assert(stream); - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_load() enter,\n"); - for (i = 0; i < MAX_ACTIVE_STREAMS; i++) { - if (my_css_save.stream_seeds[i].stream == stream) { - int j; - - for (j = 0; j < my_css_save.stream_seeds[i].num_pipes; j++) { - if ((err = ia_css_pipe_create(&my_css_save.stream_seeds[i].pipe_config[j], - &my_css_save.stream_seeds[i].pipes[j])) != 0) { - if (j) { - int k; - - for (k = 0; k < j; k++) - ia_css_pipe_destroy(my_css_save.stream_seeds[i].pipes[k]); - } - return err; - } - } - err = ia_css_stream_create(&my_css_save.stream_seeds[i].stream_config, - my_css_save.stream_seeds[i].num_pipes, - my_css_save.stream_seeds[i].pipes, - &my_css_save.stream_seeds[i].stream); - if (err) { - ia_css_stream_destroy(stream); - for (j = 0; j < my_css_save.stream_seeds[i].num_pipes; j++) - ia_css_pipe_destroy(my_css_save.stream_seeds[i].pipes[j]); - return err; - } - break; - } - } - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_load() exit,\n"); - return 0; - } else { + if (IS_ISP2401) { /* TODO remove function - DEPRECATED */ (void)stream; return -ENOTSUPP; } + + assert(stream); + ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_load() enter,\n"); + for (i = 0; i < MAX_ACTIVE_STREAMS; i++) { + if (my_css_save.stream_seeds[i].stream != stream) + continue; + + for (j = 0; j < my_css_save.stream_seeds[i].num_pipes; j++) { + int k; + + err = ia_css_pipe_create(&my_css_save.stream_seeds[i].pipe_config[j], + &my_css_save.stream_seeds[i].pipes[j]); + if (!err) + continue; + + for (k = 0; k < j; k++) + ia_css_pipe_destroy(my_css_save.stream_seeds[i].pipes[k]); + return err; + } + err = ia_css_stream_create(&my_css_save.stream_seeds[i].stream_config, + my_css_save.stream_seeds[i].num_pipes, + my_css_save.stream_seeds[i].pipes, + &my_css_save.stream_seeds[i].stream); + if (!err) + break; + + ia_css_stream_destroy(stream); + for (j = 0; j < my_css_save.stream_seeds[i].num_pipes; j++) + ia_css_pipe_destroy(my_css_save.stream_seeds[i].pipes[j]); + return err; + } + + ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_load() exit,\n"); + return 0; } int From 684e025c716568496ec63e892f573a26a4db72d9 Mon Sep 17 00:00:00 2001 From: Martiros Shakhzadyan Date: Fri, 23 Apr 2021 18:13:12 +0200 Subject: [PATCH 056/394] media: staging: media: atomisp: Fix line split style issues Fix line split issues and resolve adjacent extra parens. Signed-off-by: Martiros Shakhzadyan Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/sh_css.c | 91 ++++++++++------------ 1 file changed, 42 insertions(+), 49 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/sh_css.c b/drivers/staging/media/atomisp/pci/sh_css.c index f1a2ba99f90e..d26b1301eeb7 100644 --- a/drivers/staging/media/atomisp/pci/sh_css.c +++ b/drivers/staging/media/atomisp/pci/sh_css.c @@ -308,8 +308,7 @@ sh_css_pipeline_add_acc_stage(struct ia_css_pipeline *pipeline, const void *acc_fw); static int -alloc_continuous_frames( - struct ia_css_pipe *pipe, bool init_time); +alloc_continuous_frames(struct ia_css_pipe *pipe, bool init_time); static void pipe_global_init(void); @@ -2622,8 +2621,7 @@ static int load_copy_binary( } static int -alloc_continuous_frames( - struct ia_css_pipe *pipe, bool init_time) +alloc_continuous_frames(struct ia_css_pipe *pipe, bool init_time) { int err = 0; struct ia_css_frame_info ref_info; @@ -4010,9 +4008,9 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe, assert(pipe_id < IA_CSS_PIPE_ID_NUM); assert(buf_type < IA_CSS_NUM_DYNAMIC_BUFFER_TYPE); - if ((buf_type == IA_CSS_BUFFER_TYPE_INVALID) || - (buf_type >= IA_CSS_NUM_DYNAMIC_BUFFER_TYPE) || - (pipe_id >= IA_CSS_PIPE_ID_NUM)) { + if (buf_type == IA_CSS_BUFFER_TYPE_INVALID || + buf_type >= IA_CSS_NUM_DYNAMIC_BUFFER_TYPE || + pipe_id >= IA_CSS_PIPE_ID_NUM) { IA_CSS_LEAVE_ERR(-EINVAL); return -EINVAL; } @@ -4073,11 +4071,11 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe, } ddr_buffer.kernel_ptr = HOST_ADDRESS(buffer->data.metadata); ddr_buffer.payload.metadata = *buffer->data.metadata; - } else if ((buf_type == IA_CSS_BUFFER_TYPE_INPUT_FRAME) - || (buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME) - || (buf_type == IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME) - || (buf_type == IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME) - || (buf_type == IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME)) { + } else if (buf_type == IA_CSS_BUFFER_TYPE_INPUT_FRAME || + buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME || + buf_type == IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME || + buf_type == IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME || + buf_type == IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME) { if (!buffer->data.frame) { IA_CSS_LEAVE_ERR(-EINVAL); return -EINVAL; @@ -4117,9 +4115,9 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe, hmm_store(h_vbuf->vptr, (void *)(&ddr_buffer), sizeof(struct sh_css_hmm_buffer)); - if ((buf_type == IA_CSS_BUFFER_TYPE_3A_STATISTICS) - || (buf_type == IA_CSS_BUFFER_TYPE_DIS_STATISTICS) - || (buf_type == IA_CSS_BUFFER_TYPE_LACE_STATISTICS)) { + if (buf_type == IA_CSS_BUFFER_TYPE_3A_STATISTICS || + buf_type == IA_CSS_BUFFER_TYPE_DIS_STATISTICS || + buf_type == IA_CSS_BUFFER_TYPE_LACE_STATISTICS) { if (!pipeline) { ia_css_rmgr_rel_vbuf(hmm_buffer_pool, &h_vbuf); IA_CSS_LOG("pipeline is empty!"); @@ -4137,18 +4135,18 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe, (uint32_t)h_vbuf->vptr); } } - } else if ((buf_type == IA_CSS_BUFFER_TYPE_INPUT_FRAME) - || (buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME) - || (buf_type == IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME) - || (buf_type == IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME) - || (buf_type == IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME) - || (buf_type == IA_CSS_BUFFER_TYPE_METADATA)) { + } else if (buf_type == IA_CSS_BUFFER_TYPE_INPUT_FRAME || + buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME || + buf_type == IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME || + buf_type == IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME || + buf_type == IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME || + buf_type == IA_CSS_BUFFER_TYPE_METADATA) { return_err = ia_css_bufq_enqueue_buffer(thread_id, queue_id, (uint32_t)h_vbuf->vptr); #if defined(SH_CSS_ENABLE_PER_FRAME_PARAMS) - if (!(return_err) && - (buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME)) { + if (!return_err && + buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME) { IA_CSS_LOG("pfp: enqueued OF %d to q %d thread %d", ddr_buffer.payload.frame.frame_data, queue_id, thread_id); @@ -4300,8 +4298,8 @@ ia_css_pipe_dequeue_buffer(struct ia_css_pipe *pipe, buffer->driver_cookie = ddr_buffer.cookie_ptr; buffer->timing_data = ddr_buffer.timing_data; - if ((buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME) || - (buf_type == IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME)) { + if (buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME || + buf_type == IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME) { buffer->isys_eof_clock_tick.ticks = ddr_buffer.isys_eof_clock_tick; } @@ -6194,8 +6192,7 @@ allocate_delay_frames(struct ia_css_pipe *pipe) return 0; } -static int load_advanced_binaries( - struct ia_css_pipe *pipe) +static int load_advanced_binaries(struct ia_css_pipe *pipe) { struct ia_css_frame_info pre_in_info, gdc_in_info, post_in_info, post_out_info, @@ -6314,8 +6311,7 @@ static int load_advanced_binaries( return err; } -static int load_bayer_isp_binaries( - struct ia_css_pipe *pipe) +static int load_bayer_isp_binaries(struct ia_css_pipe *pipe) { struct ia_css_frame_info pre_isp_in_info, *pipe_out_info; int err = 0; @@ -6344,8 +6340,7 @@ static int load_bayer_isp_binaries( return err; } -static int load_low_light_binaries( - struct ia_css_pipe *pipe) +static int load_low_light_binaries(struct ia_css_pipe *pipe) { struct ia_css_frame_info pre_in_info, anr_in_info, post_in_info, post_out_info, @@ -6484,8 +6479,7 @@ static bool copy_on_sp(struct ia_css_pipe *pipe) return rval; } -static int load_capture_binaries( - struct ia_css_pipe *pipe) +static int load_capture_binaries(struct ia_css_pipe *pipe) { int err = 0; bool must_be_raw; @@ -6560,7 +6554,8 @@ unload_capture_binaries(struct ia_css_pipe *pipe) IA_CSS_ENTER_PRIVATE("pipe = %p", pipe); - if ((!pipe) || ((pipe->mode != IA_CSS_PIPE_ID_CAPTURE) && (pipe->mode != IA_CSS_PIPE_ID_COPY))) { + if (!pipe || (pipe->mode != IA_CSS_PIPE_ID_CAPTURE && + pipe->mode != IA_CSS_PIPE_ID_COPY)) { IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL); return -EINVAL; } @@ -6637,10 +6632,10 @@ need_yuv_scaler_stage(const struct ia_css_pipe *pipe) /* which has some hard-coded knowledge which prevents reuse of the function. */ /* Later, merge this with ia_css_pipe_create_cas_scaler_desc */ static int ia_css_pipe_create_cas_scaler_desc_single_output( - struct ia_css_frame_info *cas_scaler_in_info, - struct ia_css_frame_info *cas_scaler_out_info, - struct ia_css_frame_info *cas_scaler_vf_info, - struct ia_css_cas_binary_descr *descr) + struct ia_css_frame_info *cas_scaler_in_info, + struct ia_css_frame_info *cas_scaler_out_info, + struct ia_css_frame_info *cas_scaler_vf_info, + struct ia_css_cas_binary_descr *descr) { unsigned int i; unsigned int hor_ds_factor = 0, ver_ds_factor = 0; @@ -6762,9 +6757,9 @@ ERR: } /* FIXME: merge most of this and single output version */ -static int ia_css_pipe_create_cas_scaler_desc( - struct ia_css_pipe *pipe, - struct ia_css_cas_binary_descr *descr) +static int +ia_css_pipe_create_cas_scaler_desc(struct ia_css_pipe *pipe, + struct ia_css_cas_binary_descr *descr) { struct ia_css_frame_info in_info = IA_CSS_BINARY_DEFAULT_FRAME_INFO; struct ia_css_frame_info *out_info[IA_CSS_PIPE_MAX_OUTPUT_STAGE]; @@ -7970,7 +7965,9 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) * should not be considered as a clean solution. Proper * investigation should be done to come up with the clean solution. * */ - if (mode != IA_CSS_CAPTURE_MODE_RAW && mode != IA_CSS_CAPTURE_MODE_BAYER && current_stage && vf_frame) { + if (mode != IA_CSS_CAPTURE_MODE_RAW && + mode != IA_CSS_CAPTURE_MODE_BAYER && + current_stage && vf_frame) { in_frame = current_stage->args.out_vf_frame; err = add_vf_pp_stage(pipe, in_frame, vf_frame, vf_pp_binary, ¤t_stage); @@ -8008,8 +8005,7 @@ create_host_capture_pipeline(struct ia_css_pipe *pipe) return err; } -static int capture_start( - struct ia_css_pipe *pipe) +static int capture_start(struct ia_css_pipe *pipe) { struct ia_css_pipeline *me; @@ -8410,11 +8406,8 @@ int ia_css_stream_capture_frame(struct ia_css_stream *stream, * @brief Configure the continuous capture. * Refer to "sh_css_internal.h" for details. */ -int ia_css_stream_capture( - struct ia_css_stream *stream, - int num_captures, - unsigned int skip, - int offset) +int ia_css_stream_capture(struct ia_css_stream *stream, int num_captures, + unsigned int skip, int offset) { struct sh_css_tag_descr tag_descr; unsigned int encoded_tag_descr; From 43692e9e1b8b93d0e26e4a752adc41973863ecb2 Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Wed, 28 Apr 2021 20:05:41 +0200 Subject: [PATCH 057/394] media: staging: media: atomisp: balance braces around if...else block Balance braces around the if else blocks as per the code style guidelines. Add braces to branches where it is missing. Resolves checkpatch script CHECK / WARNING feedback messages. Signed-off-by: Deepak R Varma Signed-off-by: Hans Verkuil Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/i2c/atomisp-gc2235.c | 4 ++-- drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c index 6ba4a8adff7c..e722c639b60d 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c @@ -658,9 +658,9 @@ static int gc2235_s_power(struct v4l2_subdev *sd, int on) { int ret; - if (on == 0) + if (on == 0) { ret = power_down(sd); - else { + } else { ret = power_up(sd); if (!ret) ret = __gc2235_init(sd); diff --git a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c index f5de81132177..465fc4468442 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c @@ -568,9 +568,9 @@ static int power_down(struct v4l2_subdev *sd) static int mt9m114_s_power(struct v4l2_subdev *sd, int power) { - if (power == 0) + if (power == 0) { return power_down(sd); - else { + } else { if (power_up(sd)) return -EINVAL; From 21837c2c27cdc0ab768b64c8f626b6738604e37d Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Wed, 28 Apr 2021 20:06:50 +0200 Subject: [PATCH 058/394] media: staging: media: atomisp: remove unnecessary braces According to the coding style guidelines, if...else blocks with single instructions do not need enclosing braces. This resolves checkpatch WARNING / CHECK complaints. Signed-off-by: Deepak R Varma Signed-off-by: Hans Verkuil Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/i2c/atomisp-ov2680.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c index c90730513438..f167781e258a 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c @@ -461,11 +461,11 @@ static int ov2680_v_flip(struct v4l2_subdev *sd, s32 value) ret = ov2680_read_reg(client, 1, OV2680_FLIP_REG, &val); if (ret) return ret; - if (value) { + if (value) val |= OV2680_FLIP_MIRROR_BIT_ENABLE; - } else { + else val &= ~OV2680_FLIP_MIRROR_BIT_ENABLE; - } + ret = ov2680_write_reg(client, 1, OV2680_FLIP_REG, val); if (ret) From f50559f0c9b43b023476664724e8494fbe9de4fc Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Wed, 28 Apr 2021 20:08:45 +0200 Subject: [PATCH 059/394] media: staging: media: atomisp: reformat code comment blocks Reformat code comment blocks according to the coding style guidelines. This resolves different checkpatch script WARNINGs around block comments. [hverkuil: fixed up one missed '/* text' comment as reported by Fabio] Suggested-by: Fabio Aiuto Signed-off-by: Deepak R Varma Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../media/atomisp/i2c/atomisp-gc2235.c | 19 ++++--- .../atomisp/i2c/atomisp-libmsrlisthelper.c | 6 ++- .../media/atomisp/i2c/atomisp-mt9m114.c | 49 ++++++++++++------- .../media/atomisp/i2c/atomisp-ov2680.c | 20 +++++--- drivers/staging/media/atomisp/i2c/mt9m114.h | 6 ++- drivers/staging/media/atomisp/i2c/ov2680.h | 10 ++-- 6 files changed, 67 insertions(+), 43 deletions(-) diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c index e722c639b60d..38defa0f8151 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c @@ -228,7 +228,7 @@ static int gc2235_g_focal(struct v4l2_subdev *sd, s32 *val) static int gc2235_g_fnumber(struct v4l2_subdev *sd, s32 *val) { - /*const f number for imx*/ + /* const f number for imx */ *val = (GC2235_F_NUMBER_DEFAULT_NUM << 16) | GC2235_F_NUMBER_DEM; return 0; } @@ -427,7 +427,8 @@ static long gc2235_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) return 0; } -/* This returns the exposure time being used. This should only be used +/* + * This returns the exposure time being used. This should only be used * for filling in EXIF data, not for actual image processing. */ static int gc2235_q_exposure(struct v4l2_subdev *sd, s32 *value) @@ -746,11 +747,12 @@ static int startup(struct v4l2_subdev *sd) int ret = 0; if (is_init == 0) { - /* force gc2235 to do a reset in res change, otherwise it - * can not output normal after switching res. and it is not - * necessary for first time run up after power on, for the sack - * of performance - */ + /* + * force gc2235 to do a reset in res change, otherwise it + * can not output normal after switching res. and it is not + * necessary for first time run up after power on, for the sack + * of performance + */ power_down(sd); power_up(sd); gc2235_write_reg_array(client, gc2235_init_settings); @@ -904,7 +906,8 @@ static int gc2235_s_config(struct v4l2_subdev *sd, (struct camera_sensor_platform_data *)platform_data; mutex_lock(&dev->input_lock); - /* power off the module, then power on it in future + /* + * power off the module, then power on it in future * as first power on by board may not fulfill the * power on sequqence needed by the module */ diff --git a/drivers/staging/media/atomisp/i2c/atomisp-libmsrlisthelper.c b/drivers/staging/media/atomisp/i2c/atomisp-libmsrlisthelper.c index b93c80471f22..7a20d918a9d5 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-libmsrlisthelper.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-libmsrlisthelper.c @@ -50,14 +50,16 @@ struct tbd_data_record_header { static int set_msr_configuration(struct i2c_client *client, uint8_t *bufptr, unsigned int size) { - /* The configuration data contains any number of sequences where + /* + * The configuration data contains any number of sequences where * the first byte (that is, uint8_t) that marks the number of bytes * in the sequence to follow, is indeed followed by the indicated * number of bytes of actual data to be written to sensor. * By convention, the first two bytes of actual data should be * understood as an address in the sensor address space (hibyte * followed by lobyte) where the remaining data in the sequence - * will be written. */ + * will be written. + */ u8 *ptr = bufptr; diff --git a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c index 465fc4468442..a5f0b4848ddf 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c @@ -475,10 +475,12 @@ static int gpio_ctrl(struct v4l2_subdev *sd, bool flag) if (!dev || !dev->platform_data) return -ENODEV; - /* Note: current modules wire only one GPIO signal (RESET#), + /* + * Note: current modules wire only one GPIO signal (RESET#), * but the schematic wires up two to the connector. BIOS * versions have been unfortunately inconsistent with which - * ACPI index RESET# is on, so hit both */ + * ACPI index RESET# is on, so hit both + */ if (flag) { ret = dev->platform_data->gpio0_ctrl(sd, 0); @@ -560,7 +562,7 @@ static int power_down(struct v4l2_subdev *sd) if (ret) dev_err(&client->dev, "vprog failed.\n"); - /*according to DS, 20ms is needed after power down*/ + /* according to DS, 20ms is needed after power down */ msleep(20); return ret; @@ -947,7 +949,7 @@ static int mt9m114_g_focal(struct v4l2_subdev *sd, s32 *val) static int mt9m114_g_fnumber(struct v4l2_subdev *sd, s32 *val) { - /*const f number for mt9m114*/ + /* const f number for mt9m114 */ *val = (MT9M114_F_NUMBER_DEFAULT_NUM << 16) | MT9M114_F_NUMBER_DEM; return 0; } @@ -1008,8 +1010,10 @@ static long mt9m114_s_exposure(struct v4l2_subdev *sd, exposure->gain[1]); coarse_integration = exposure->integration_time[0]; - /* fine_integration = ExposureTime.FineIntegrationTime; */ - /* FrameLengthLines = ExposureTime.FrameLengthLines; */ + /* + * fine_integration = ExposureTime.FineIntegrationTime; + * FrameLengthLines = ExposureTime.FrameLengthLines; + */ FLines = mt9m114_res[dev->res].lines_per_frame; AnalogGain = exposure->gain[0]; DigitalGain = exposure->gain[1]; @@ -1019,8 +1023,8 @@ static long mt9m114_s_exposure(struct v4l2_subdev *sd, dev->first_gain = AnalogGain; dev->first_diggain = DigitalGain; } - /* DigitalGain = 0x400 * (((u16) DigitalGain) >> 8) + - ((unsigned int)(0x400 * (((u16) DigitalGain) & 0xFF)) >>8); */ + /* DigitalGain = 0x400 * (((u16) DigitalGain) >> 8) + */ + /* ((unsigned int)(0x400 * (((u16) DigitalGain) & 0xFF)) >>8); */ /* set frame length */ if (FLines < coarse_integration + 6) @@ -1034,8 +1038,10 @@ static long mt9m114_s_exposure(struct v4l2_subdev *sd, } /* set coarse integration */ - /* 3A provide real exposure time. - should not translate to any value here. */ + /* + * 3A provide real exposure time. + * should not translate to any value here. + */ ret = mt9m114_write_reg(client, MISENSOR_16BIT, REG_EXPO_COARSE, (u16)(coarse_integration)); if (ret) { @@ -1044,7 +1050,7 @@ static long mt9m114_s_exposure(struct v4l2_subdev *sd, } /* - // set analog/digital gain + * set analog/digital gain switch(AnalogGain) { case 0: @@ -1069,8 +1075,9 @@ static long mt9m114_s_exposure(struct v4l2_subdev *sd, */ if (DigitalGain >= 16 || DigitalGain <= 1) DigitalGain = 1; - /* AnalogGainToWrite = - (u16)((DigitalGain << 12) | AnalogGainToWrite); */ + /* + * AnalogGainToWrite = (u16)((DigitalGain << 12) | AnalogGainToWrite); + */ AnalogGainToWrite = (u16)((DigitalGain << 12) | (u16)AnalogGain); ret = mt9m114_write_reg(client, MISENSOR_16BIT, REG_GAIN, AnalogGainToWrite); @@ -1095,8 +1102,10 @@ static long mt9m114_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) return 0; } -/* This returns the exposure time being used. This should only be used - for filling in EXIF data, not for actual image processing. */ +/* + * This returns the exposure time being used. This should only be used + * for filling in EXIF data, not for actual image processing. + */ static int mt9m114_g_exposure(struct v4l2_subdev *sd, s32 *value) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -1247,7 +1256,8 @@ static int mt9m114_s_ev(struct v4l2_subdev *sd, s32 val) s32 luma = 0x37; int err; - /* EV value only support -2 to 2 + /* + * EV value only support -2 to 2 * 0: 0x37, 1:0x47, 2:0x57, -1:0x27, -2:0x17 */ if (val < -2 || val > 2) @@ -1295,9 +1305,10 @@ static int mt9m114_g_ev(struct v4l2_subdev *sd, s32 *val) return 0; } -/* Fake interface +/* + * Fake interface * mt9m114 now can not support 3a_lock -*/ + */ static int mt9m114_s_3a_lock(struct v4l2_subdev *sd, s32 val) { aaalock = val; @@ -1843,7 +1854,7 @@ static int mt9m114_probe(struct i2c_client *client) return ret; } - /*TODO add format code here*/ + /* TODO add format code here */ dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; dev->pad.flags = MEDIA_PAD_FL_SOURCE; dev->format.code = MEDIA_BUS_FMT_SGRBG10_1X10; diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c index f167781e258a..eb1ecd198c22 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c @@ -127,7 +127,7 @@ static int ov2680_g_focal(struct v4l2_subdev *sd, s32 *val) static int ov2680_g_fnumber(struct v4l2_subdev *sd, s32 *val) { - /*const f number for ov2680*/ + /* const f number for ov2680 */ *val = (OV2680_F_NUMBER_DEFAULT_NUM << 16) | OV2680_F_NUMBER_DEM; return 0; @@ -399,7 +399,8 @@ static long ov2680_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) return 0; } -/* This returns the exposure time being used. This should only be used +/* + * This returns the exposure time being used. This should only be used * for filling in EXIF data, not for actual image processing. */ static int ov2680_q_exposure(struct v4l2_subdev *sd, s32 *value) @@ -727,11 +728,13 @@ static int gpio_ctrl(struct v4l2_subdev *sd, bool flag) if (!dev || !dev->platform_data) return -ENODEV; - /* The OV2680 documents only one GPIO input (#XSHUTDN), but + /* + * The OV2680 documents only one GPIO input (#XSHUTDN), but * existing integrations often wire two (reset/power_down) * because that is the way other sensors work. There is no * way to tell how it is wired internally, so existing - * firmwares expose both and we drive them symmetrically. */ + * firmwares expose both and we drive them symmetrically. + */ if (flag) { ret = dev->platform_data->gpio0_ctrl(sd, 1); usleep_range(10000, 15000); @@ -977,7 +980,8 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd, goto err; } - /*recall flip functions to avoid flip registers + /* + * recall flip functions to avoid flip registers * were overridden by default setting */ if (h_flag) @@ -987,7 +991,8 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd, v4l2_info(client, "\n%s idx %d\n", __func__, dev->fmt_idx); - /*ret = startup(sd); + /* + * ret = startup(sd); * if (ret) * dev_err(&client->dev, "ov2680 startup err\n"); */ @@ -1096,7 +1101,8 @@ static int ov2680_s_config(struct v4l2_subdev *sd, (struct camera_sensor_platform_data *)platform_data; mutex_lock(&dev->input_lock); - /* power off the module, then power on it in future + /* + * power off the module, then power on it in future * as first power on by board may not fulfill the * power on sequqence needed by the module */ diff --git a/drivers/staging/media/atomisp/i2c/mt9m114.h b/drivers/staging/media/atomisp/i2c/mt9m114.h index 787bbf59e895..bcce18b65fa6 100644 --- a/drivers/staging/media/atomisp/i2c/mt9m114.h +++ b/drivers/staging/media/atomisp/i2c/mt9m114.h @@ -764,8 +764,10 @@ static struct misensor_reg const mt9m114_common[] = { {MISENSOR_8BIT, 0xC85C, 0x03}, /* cam_crop_cropmode = 3 */ {MISENSOR_16BIT, 0xC868, 0x0280}, /* cam_output_width = 952 */ {MISENSOR_16BIT, 0xC86A, 0x01E0}, /* cam_output_height = 538 */ - /* LOAD = Step3-Recommended - * Patch,Errata and Sensor optimization Setting */ + /* + * LOAD = Step3-Recommended + * Patch, Errata and Sensor optimization Setting + */ {MISENSOR_16BIT, 0x316A, 0x8270}, /* DAC_TXLO_ROW */ {MISENSOR_16BIT, 0x316C, 0x8270}, /* DAC_TXLO */ {MISENSOR_16BIT, 0x3ED0, 0x2305}, /* DAC_LD_4_5 */ diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h index 49920245e064..4d43b45915e5 100644 --- a/drivers/staging/media/atomisp/i2c/ov2680.h +++ b/drivers/staging/media/atomisp/i2c/ov2680.h @@ -459,8 +459,8 @@ static struct ov2680_reg const ov2680_656x496_30fps[] = { }; /* -* 800x600 30fps VBlanking 1lane 10Bit (binning) -*/ + * 800x600 30fps VBlanking 1lane 10Bit (binning) + */ static struct ov2680_reg const ov2680_720x592_30fps[] = { {0x3086, 0x01}, {0x3501, 0x26}, @@ -504,8 +504,8 @@ static struct ov2680_reg const ov2680_720x592_30fps[] = { }; /* -* 800x600 30fps VBlanking 1lane 10Bit (binning) -*/ + * 800x600 30fps VBlanking 1lane 10Bit (binning) + */ static struct ov2680_reg const ov2680_800x600_30fps[] = { {0x3086, 0x01}, {0x3501, 0x26}, @@ -634,7 +634,7 @@ static struct ov2680_reg const ov2680_1296x976_30fps[] = { /* * 1456*1096 30fps VBlanking 1lane 10bit(no-scaling) -*/ + */ static struct ov2680_reg const ov2680_1456x1096_30fps[] = { {0x3086, 0x00}, {0x3501, 0x48}, From 4c999ae366e13bdf1f961fdf4c4cefe3d772f275 Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Wed, 28 Apr 2021 20:09:20 +0200 Subject: [PATCH 060/394] media: staging: media: atomisp: fix CamelCase variable naming Mixed case variable names are discouraged and they result in checkpatch script "Avoid CamelCase" warnings. Replace such CamelCase variable names by lower case strings according to the coding style guidelines. Signed-off-by: Deepak R Varma Signed-off-by: Hans Verkuil Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- .../media/atomisp/i2c/atomisp-mt9m114.c | 63 ++++++++++--------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c index a5f0b4848ddf..0a6f8f68b215 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c @@ -1000,10 +1000,10 @@ static long mt9m114_s_exposure(struct v4l2_subdev *sd, struct mt9m114_device *dev = to_mt9m114_sensor(sd); int ret = 0; unsigned int coarse_integration = 0; - unsigned int FLines = 0; - unsigned int FrameLengthLines = 0; /* ExposureTime.FrameLengthLines; */ - unsigned int AnalogGain, DigitalGain; - u32 AnalogGainToWrite = 0; + unsigned int f_lines = 0; + unsigned int frame_len_lines = 0; /* ExposureTime.FrameLengthLines; */ + unsigned int analog_gain, digital_gain; + u32 analog_gain_to_write = 0; dev_dbg(&client->dev, "%s(0x%X 0x%X 0x%X)\n", __func__, exposure->integration_time[0], exposure->gain[0], @@ -1012,28 +1012,28 @@ static long mt9m114_s_exposure(struct v4l2_subdev *sd, coarse_integration = exposure->integration_time[0]; /* * fine_integration = ExposureTime.FineIntegrationTime; - * FrameLengthLines = ExposureTime.FrameLengthLines; + * frame_len_lines = ExposureTime.FrameLengthLines; */ - FLines = mt9m114_res[dev->res].lines_per_frame; - AnalogGain = exposure->gain[0]; - DigitalGain = exposure->gain[1]; + f_lines = mt9m114_res[dev->res].lines_per_frame; + analog_gain = exposure->gain[0]; + digital_gain = exposure->gain[1]; if (!dev->streamon) { /*Save the first exposure values while stream is off*/ dev->first_exp = coarse_integration; - dev->first_gain = AnalogGain; - dev->first_diggain = DigitalGain; + dev->first_gain = analog_gain; + dev->first_diggain = digital_gain; } - /* DigitalGain = 0x400 * (((u16) DigitalGain) >> 8) + */ - /* ((unsigned int)(0x400 * (((u16) DigitalGain) & 0xFF)) >>8); */ + /* digital_gain = 0x400 * (((u16) digital_gain) >> 8) + */ + /* ((unsigned int)(0x400 * (((u16) digital_gain) & 0xFF)) >>8); */ /* set frame length */ - if (FLines < coarse_integration + 6) - FLines = coarse_integration + 6; - if (FLines < FrameLengthLines) - FLines = FrameLengthLines; - ret = mt9m114_write_reg(client, MISENSOR_16BIT, 0x300A, FLines); + if (f_lines < coarse_integration + 6) + f_lines = coarse_integration + 6; + if (f_lines < frame_len_lines) + f_lines = frame_len_lines; + ret = mt9m114_write_reg(client, MISENSOR_16BIT, 0x300A, f_lines); if (ret) { - v4l2_err(client, "%s: fail to set FLines\n", __func__); + v4l2_err(client, "%s: fail to set f_lines\n", __func__); return -EINVAL; } @@ -1051,38 +1051,39 @@ static long mt9m114_s_exposure(struct v4l2_subdev *sd, /* * set analog/digital gain - switch(AnalogGain) + switch(analog_gain) { case 0: - AnalogGainToWrite = 0x0; + analog_gain_to_write = 0x0; break; case 1: - AnalogGainToWrite = 0x20; + analog_gain_to_write = 0x20; break; case 2: - AnalogGainToWrite = 0x60; + analog_gain_to_write = 0x60; break; case 4: - AnalogGainToWrite = 0xA0; + analog_gain_to_write = 0xA0; break; case 8: - AnalogGainToWrite = 0xE0; + analog_gain_to_write = 0xE0; break; default: - AnalogGainToWrite = 0x20; + analog_gain_to_write = 0x20; break; } */ - if (DigitalGain >= 16 || DigitalGain <= 1) - DigitalGain = 1; + if (digital_gain >= 16 || digital_gain <= 1) + digital_gain = 1; /* - * AnalogGainToWrite = (u16)((DigitalGain << 12) | AnalogGainToWrite); + * analog_gain_to_write = (u16)((digital_gain << 12) + * | analog_gain_to_write); */ - AnalogGainToWrite = (u16)((DigitalGain << 12) | (u16)AnalogGain); + analog_gain_to_write = (u16)((digital_gain << 12) | (u16)analog_gain); ret = mt9m114_write_reg(client, MISENSOR_16BIT, - REG_GAIN, AnalogGainToWrite); + REG_GAIN, analog_gain_to_write); if (ret) { - v4l2_err(client, "%s: fail to set AnalogGainToWrite\n", + v4l2_err(client, "%s: fail to set analog_gain_to_write\n", __func__); return -EINVAL; } From 2dfc978ac0f3aaa5de4eb604ef7f35bacd077a03 Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Wed, 28 Apr 2021 20:09:55 +0200 Subject: [PATCH 061/394] media: staging: media: atomisp: replace raw pr_*() by dev_dbg() It is recommended to use driver model diagnostic macros dev_*() instead of raw printk() or pr_*() since the former ensures that the log messages are always associated with the corresponding device and driver. This also addresses the checkpatch complain for not using KERN_ facility in printk() call. Suggested-by: Fabio Aiuto Signed-off-by: Deepak R Varma Signed-off-by: Hans Verkuil Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- .../media/atomisp/i2c/atomisp-gc0310.c | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c index d170d0adfea4..e1de3cf68893 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c @@ -300,7 +300,7 @@ static int gc0310_get_intg_factor(struct i2c_client *client, /* pixel clock calculattion */ dev->vt_pix_clk_freq_mhz = 14400000; // 16.8MHz buf->vt_pix_clk_freq_mhz = dev->vt_pix_clk_freq_mhz; - pr_info("vt_pix_clk_freq_mhz=%d\n", buf->vt_pix_clk_freq_mhz); + dev_dbg(&client->dev, "vt_pix_clk_freq_mhz=%d\n", buf->vt_pix_clk_freq_mhz); /* get integration time */ buf->coarse_integration_time_min = GC0310_COARSE_INTG_TIME_MIN; @@ -326,7 +326,7 @@ static int gc0310_get_intg_factor(struct i2c_client *client, if (ret) return ret; buf->crop_horizontal_start = val | (reg_val & 0xFF); - pr_info("crop_horizontal_start=%d\n", buf->crop_horizontal_start); + dev_dbg(&client->dev, "crop_horizontal_start=%d\n", buf->crop_horizontal_start); /* Getting crop_vertical_start */ ret = gc0310_read_reg(client, GC0310_8BIT, @@ -339,7 +339,7 @@ static int gc0310_get_intg_factor(struct i2c_client *client, if (ret) return ret; buf->crop_vertical_start = val | (reg_val & 0xFF); - pr_info("crop_vertical_start=%d\n", buf->crop_vertical_start); + dev_dbg(&client->dev, "crop_vertical_start=%d\n", buf->crop_vertical_start); /* Getting output_width */ ret = gc0310_read_reg(client, GC0310_8BIT, @@ -352,7 +352,7 @@ static int gc0310_get_intg_factor(struct i2c_client *client, if (ret) return ret; buf->output_width = val | (reg_val & 0xFF); - pr_info("output_width=%d\n", buf->output_width); + dev_dbg(&client->dev, "output_width=%d\n", buf->output_width); /* Getting output_height */ ret = gc0310_read_reg(client, GC0310_8BIT, @@ -365,12 +365,12 @@ static int gc0310_get_intg_factor(struct i2c_client *client, if (ret) return ret; buf->output_height = val | (reg_val & 0xFF); - pr_info("output_height=%d\n", buf->output_height); + dev_dbg(&client->dev, "output_height=%d\n", buf->output_height); buf->crop_horizontal_end = buf->crop_horizontal_start + buf->output_width - 1; buf->crop_vertical_end = buf->crop_vertical_start + buf->output_height - 1; - pr_info("crop_horizontal_end=%d\n", buf->crop_horizontal_end); - pr_info("crop_vertical_end=%d\n", buf->crop_vertical_end); + dev_dbg(&client->dev, "crop_horizontal_end=%d\n", buf->crop_horizontal_end); + dev_dbg(&client->dev, "crop_vertical_end=%d\n", buf->crop_vertical_end); /* Getting line_length_pck */ ret = gc0310_read_reg(client, GC0310_8BIT, @@ -389,7 +389,7 @@ static int gc0310_get_intg_factor(struct i2c_client *client, return ret; sh_delay = reg_val; buf->line_length_pck = buf->output_width + hori_blanking + sh_delay + 4; - pr_info("hori_blanking=%d sh_delay=%d line_length_pck=%d\n", hori_blanking, + dev_dbg(&client->dev, "hori_blanking=%d sh_delay=%d line_length_pck=%d\n", hori_blanking, sh_delay, buf->line_length_pck); /* Getting frame_length_lines */ @@ -404,7 +404,7 @@ static int gc0310_get_intg_factor(struct i2c_client *client, return ret; vert_blanking = val | (reg_val & 0xFF); buf->frame_length_lines = buf->output_height + vert_blanking; - pr_info("vert_blanking=%d frame_length_lines=%d\n", vert_blanking, + dev_dbg(&client->dev, "vert_blanking=%d frame_length_lines=%d\n", vert_blanking, buf->frame_length_lines); buf->binning_factor_x = res->bin_factor_x ? @@ -434,7 +434,7 @@ static int gc0310_set_gain(struct v4l2_subdev *sd, int gain) dgain = gain / 2; } - pr_info("gain=0x%x again=0x%x dgain=0x%x\n", gain, again, dgain); + dev_dbg(&client->dev, "gain=0x%x again=0x%x dgain=0x%x\n", gain, again, dgain); /* set analog gain */ ret = gc0310_write_reg(client, GC0310_8BIT, @@ -458,7 +458,7 @@ static int __gc0310_set_exposure(struct v4l2_subdev *sd, int coarse_itg, struct i2c_client *client = v4l2_get_subdevdata(sd); int ret; - pr_info("coarse_itg=%d gain=%d digitgain=%d\n", coarse_itg, gain, digitgain); + dev_dbg(&client->dev, "coarse_itg=%d gain=%d digitgain=%d\n", coarse_itg, gain, digitgain); /* set exposure */ ret = gc0310_write_reg(client, GC0310_8BIT, @@ -1020,8 +1020,8 @@ static int gc0310_set_fmt(struct v4l2_subdev *sd, return -EINVAL; } - printk("%s: before gc0310_write_reg_array %s\n", __func__, - gc0310_res[dev->fmt_idx].desc); + dev_dbg(&client->dev, "%s: before gc0310_write_reg_array %s\n", + __func__, gc0310_res[dev->fmt_idx].desc); ret = startup(sd); if (ret) { dev_err(&client->dev, "gc0310 startup err\n"); @@ -1085,7 +1085,7 @@ static int gc0310_detect(struct i2c_client *client) return -ENODEV; } id = ((((u16)high) << 8) | (u16)low); - pr_info("sensor ID = 0x%x\n", id); + dev_dbg(&client->dev, "sensor ID = 0x%x\n", id); if (id != GC0310_ID) { dev_err(&client->dev, "sensor ID error, read id = 0x%x, target id = 0x%x\n", id, @@ -1106,7 +1106,7 @@ static int gc0310_s_stream(struct v4l2_subdev *sd, int enable) struct i2c_client *client = v4l2_get_subdevdata(sd); int ret; - pr_info("%s S enable=%d\n", __func__, enable); + dev_dbg(&client->dev, "%s S enable=%d\n", __func__, enable); mutex_lock(&dev->input_lock); if (enable) { From 637959f7e273a83934c9d3c6a50af529fb46cbb6 Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Wed, 28 Apr 2021 20:10:26 +0200 Subject: [PATCH 062/394] media: staging: media: atomisp: remove unnecessary pr_info calls pr_info() messages to log function entry / exit tracing spams the log. Such basic tracing is not necessary and be removed. Signed-off-by: Deepak R Varma Signed-off-by: Hans Verkuil Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- .../staging/media/atomisp/i2c/atomisp-gc0310.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c index e1de3cf68893..6c5a378a2eb5 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c @@ -718,7 +718,6 @@ static int gc0310_init(struct v4l2_subdev *sd) struct i2c_client *client = v4l2_get_subdevdata(sd); struct gc0310_device *dev = to_gc0310_sensor(sd); - pr_info("%s S\n", __func__); mutex_lock(&dev->input_lock); /* set initial registers */ @@ -730,7 +729,6 @@ static int gc0310_init(struct v4l2_subdev *sd) mutex_unlock(&dev->input_lock); - pr_info("%s E\n", __func__); return ret; } @@ -796,7 +794,6 @@ static int power_up(struct v4l2_subdev *sd) struct i2c_client *client = v4l2_get_subdevdata(sd); int ret; - pr_info("%s S\n", __func__); if (!dev->platform_data) { dev_err(&client->dev, "no camera_sensor_platform_data"); @@ -823,7 +820,6 @@ static int power_up(struct v4l2_subdev *sd) msleep(100); - pr_info("%s E\n", __func__); return 0; fail_gpio: @@ -959,15 +955,12 @@ static int startup(struct v4l2_subdev *sd) struct i2c_client *client = v4l2_get_subdevdata(sd); int ret = 0; - pr_info("%s S\n", __func__); - ret = gc0310_write_reg_array(client, gc0310_res[dev->fmt_idx].regs); if (ret) { dev_err(&client->dev, "gc0310 write register err.\n"); return ret; } - pr_info("%s E\n", __func__); return ret; } @@ -982,8 +975,6 @@ static int gc0310_set_fmt(struct v4l2_subdev *sd, int ret = 0; int idx = 0; - pr_info("%s S\n", __func__); - if (format->pad) return -EINVAL; @@ -1035,7 +1026,6 @@ static int gc0310_set_fmt(struct v4l2_subdev *sd, goto err; } - pr_info("%s E\n", __func__); err: mutex_unlock(&dev->input_lock); return ret; @@ -1068,7 +1058,6 @@ static int gc0310_detect(struct i2c_client *client) int ret; u16 id; - pr_info("%s S\n", __func__); if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) return -ENODEV; @@ -1095,8 +1084,6 @@ static int gc0310_detect(struct i2c_client *client) dev_dbg(&client->dev, "detect gc0310 success\n"); - pr_info("%s E\n", __func__); - return 0; } @@ -1142,7 +1129,6 @@ static int gc0310_s_stream(struct v4l2_subdev *sd, int enable) } mutex_unlock(&dev->input_lock); - pr_info("%s E\n", __func__); return ret; } @@ -1153,7 +1139,6 @@ static int gc0310_s_config(struct v4l2_subdev *sd, struct i2c_client *client = v4l2_get_subdevdata(sd); int ret = 0; - pr_info("%s S\n", __func__); if (!platform_data) return -ENODEV; @@ -1196,7 +1181,6 @@ static int gc0310_s_config(struct v4l2_subdev *sd, } mutex_unlock(&dev->input_lock); - pr_info("%s E\n", __func__); return 0; fail_csi_cfg: @@ -1365,7 +1349,6 @@ static int gc0310_probe(struct i2c_client *client) if (ret) gc0310_remove(client); - pr_info("%s E\n", __func__); return ret; out_free: v4l2_device_unregister_subdev(&dev->sd); From 4eb48acac1e9fef09fde3079e4b2e30dc7cf2b35 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 9 Apr 2021 11:15:31 +0200 Subject: [PATCH 063/394] media: s2255drv: remove redundant assignment to variable field The variable 'field' is being assigned a value this is never read, it is being updated in all the following if/else combinations. The assignment is redundant and can be removed. Addresses-Coverity: ("Unused value") Signed-off-by: Colin Ian King Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/s2255/s2255drv.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c index 4af55e2478be..3b0e4ed75d99 100644 --- a/drivers/media/usb/s2255/s2255drv.c +++ b/drivers/media/usb/s2255/s2255drv.c @@ -767,8 +767,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, if (fmt == NULL) return -EINVAL; - field = f->fmt.pix.field; - dprintk(vc->dev, 50, "%s NTSC: %d suggested width: %d, height: %d\n", __func__, is_ntsc, f->fmt.pix.width, f->fmt.pix.height); if (is_ntsc) { From b07006ff9365ddfc184e1836cd1f75355c6bb740 Mon Sep 17 00:00:00 2001 From: Sebastian Fricke Date: Sat, 17 Apr 2021 15:34:38 +0200 Subject: [PATCH 064/394] media: mc: mc-entity.c: Fix typo s/entity in the other end/entity at the other end/ [hverkuil: also remove the spurious space after 'link'] Signed-off-by: Sebastian Fricke Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/mc/mc-entity.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/mc/mc-entity.c b/drivers/media/mc/mc-entity.c index 678b99771cfa..f40f41977142 100644 --- a/drivers/media/mc/mc-entity.c +++ b/drivers/media/mc/mc-entity.c @@ -323,7 +323,7 @@ static void media_graph_walk_iter(struct media_graph *graph) return; } - /* Get the entity in the other end of the link . */ + /* Get the entity at the other end of the link. */ next = media_entity_other(entity, link); /* Has the entity already been visited? */ From 71c41518128414ebb1215a074f94ef8f3e2bf0cc Mon Sep 17 00:00:00 2001 From: Sebastian Fricke Date: Sun, 18 Apr 2021 12:34:25 +0200 Subject: [PATCH 065/394] media: rkisp1: rksip1-capture.c: Improve comments and fix typos Improve the wording of the function description to increase readability. Fix three typos: s/during processing a frame/while processing a frame/ s/it also update/it also updates/ s/there's not buf in shadow/there's no buffer in a shadow register/ Replace the abbreviation 'buf' with the full word buffer, the abbreviation 'config' with the verb configure, and 'regs' with registers. The goal of this change is to ease the reading flow of the comment. Signed-off-by: Sebastian Fricke Reviewed-by: Dafna Hirschfeld Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../platform/rockchip/rkisp1/rkisp1-capture.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c index 5f6c9d1623e4..9643bdd05b7b 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c @@ -830,8 +830,8 @@ static void rkisp1_return_all_buffers(struct rkisp1_capture *cap, } /* - * Most of registers inside rockchip ISP1 have shadow register since - * they must be not be changed during processing a frame. + * Most registers inside the rockchip ISP1 have shadow register since + * they must not be changed while processing a frame. * Usually, each sub-module updates its shadow register after * processing the last pixel of a frame. */ @@ -847,14 +847,14 @@ static void rkisp1_cap_stream_enable(struct rkisp1_capture *cap) spin_lock_irq(&cap->buf.lock); rkisp1_set_next_buf(cap); cap->ops->enable(cap); - /* It's safe to config ACTIVE and SHADOW regs for the + /* It's safe to configure ACTIVE and SHADOW registers for the * first stream. While when the second is starting, do NOT - * force update because it also update the first one. + * force update because it also updates the first one. * - * The latter case would drop one more buf(that is 2) since - * there's not buf in shadow when the second FE received. This's - * also required because the second FE maybe corrupt especially - * when run at 120fps. + * The latter case would drop one more buffer(that is 2) since + * there's no buffer in a shadow register when the second FE received. + * This's also required because the second FE maybe corrupt + * especially when run at 120fps. */ if (!other->is_streaming) { /* force cfg update */ From 27ba44270b5ea3d6ec71e148051becffb51d2324 Mon Sep 17 00:00:00 2001 From: Sebastian Fricke Date: Tue, 20 Apr 2021 19:45:22 +0200 Subject: [PATCH 066/394] media: rkisp1: rkisp1-params.c: Fix typos s/when the camera active/when the camera is active/ s/thus not isr protection/therefore there is no need to acquire a lock/ Signed-off-by: Sebastian Fricke Reviewed-by: Dafna Hirschfeld Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/rockchip/rkisp1/rkisp1-params.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c index b6beddd988d0..529c6e21815f 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c @@ -1258,7 +1258,10 @@ void rkisp1_params_configure(struct rkisp1_params *params, rkisp1_params_config_parameter(params); } -/* Not called when the camera active, thus not isr protection. */ +/* + * Not called when the camera is active, therefore there is no need to acquire + * a lock. + */ void rkisp1_params_disable(struct rkisp1_params *params) { rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DPCC_MODE, From be8656e62e9e791837b606a027802b504a945c97 Mon Sep 17 00:00:00 2001 From: Pavel Skripkin Date: Wed, 21 Apr 2021 21:43:45 +0200 Subject: [PATCH 067/394] media: cpia2: fix memory leak in cpia2_usb_probe syzbot reported leak in cpia2 usb driver. The problem was in invalid error handling. v4l2_device_register() is called in cpia2_init_camera_struct(), but all error cases after cpia2_init_camera_struct() did not call the v4l2_device_unregister() Reported-by: syzbot+d1e69c888f0d3866ead4@syzkaller.appspotmail.com Signed-off-by: Pavel Skripkin Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cpia2/cpia2.h | 1 + drivers/media/usb/cpia2/cpia2_core.c | 12 ++++++++++++ drivers/media/usb/cpia2/cpia2_usb.c | 13 +++++++------ 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/drivers/media/usb/cpia2/cpia2.h b/drivers/media/usb/cpia2/cpia2.h index 50835f5f7512..57b7f1ea68da 100644 --- a/drivers/media/usb/cpia2/cpia2.h +++ b/drivers/media/usb/cpia2/cpia2.h @@ -429,6 +429,7 @@ int cpia2_send_command(struct camera_data *cam, struct cpia2_command *cmd); int cpia2_do_command(struct camera_data *cam, unsigned int command, unsigned char direction, unsigned char param); +void cpia2_deinit_camera_struct(struct camera_data *cam, struct usb_interface *intf); struct camera_data *cpia2_init_camera_struct(struct usb_interface *intf); int cpia2_init_camera(struct camera_data *cam); int cpia2_allocate_buffers(struct camera_data *cam); diff --git a/drivers/media/usb/cpia2/cpia2_core.c b/drivers/media/usb/cpia2/cpia2_core.c index e747548ab286..b5a2d06fb356 100644 --- a/drivers/media/usb/cpia2/cpia2_core.c +++ b/drivers/media/usb/cpia2/cpia2_core.c @@ -2163,6 +2163,18 @@ static void reset_camera_struct(struct camera_data *cam) cam->height = cam->params.roi.height; } +/****************************************************************************** + * + * cpia2_init_camera_struct + * + * Deinitialize camera struct + *****************************************************************************/ +void cpia2_deinit_camera_struct(struct camera_data *cam, struct usb_interface *intf) +{ + v4l2_device_unregister(&cam->v4l2_dev); + kfree(cam); +} + /****************************************************************************** * * cpia2_init_camera_struct diff --git a/drivers/media/usb/cpia2/cpia2_usb.c b/drivers/media/usb/cpia2/cpia2_usb.c index 3ab80a7b4498..76aac06f9fb8 100644 --- a/drivers/media/usb/cpia2/cpia2_usb.c +++ b/drivers/media/usb/cpia2/cpia2_usb.c @@ -844,15 +844,13 @@ static int cpia2_usb_probe(struct usb_interface *intf, ret = set_alternate(cam, USBIF_CMDONLY); if (ret < 0) { ERR("%s: usb_set_interface error (ret = %d)\n", __func__, ret); - kfree(cam); - return ret; + goto alt_err; } if((ret = cpia2_init_camera(cam)) < 0) { ERR("%s: failed to initialize cpia2 camera (ret = %d)\n", __func__, ret); - kfree(cam); - return ret; + goto alt_err; } LOG(" CPiA Version: %d.%02d (%d.%d)\n", cam->params.version.firmware_revision_hi, @@ -872,11 +870,14 @@ static int cpia2_usb_probe(struct usb_interface *intf, ret = cpia2_register_camera(cam); if (ret < 0) { ERR("%s: Failed to register cpia2 camera (ret = %d)\n", __func__, ret); - kfree(cam); - return ret; + goto alt_err; } return 0; + +alt_err: + cpia2_deinit_camera_struct(cam, intf); + return ret; } /****************************************************************************** From b2cd0b31ed896c1a6a423019ed3633e890a7f997 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 22 Apr 2021 10:21:52 +0200 Subject: [PATCH 068/394] media: rtl2832_sdr/vivid/airspy/hackrf/msi2500: drop memset of fmt.sdr.reserved The V4L2 core already zeroes fmt.sdr.reserved, so there is no need for drivers to do the same. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/rtl2832_sdr.c | 4 ---- drivers/media/test-drivers/vivid/vivid-sdr-cap.c | 3 --- drivers/media/usb/airspy/airspy.c | 3 --- drivers/media/usb/hackrf/hackrf.c | 3 --- drivers/media/usb/msi2500/msi2500.c | 3 --- 5 files changed, 16 deletions(-) diff --git a/drivers/media/dvb-frontends/rtl2832_sdr.c b/drivers/media/dvb-frontends/rtl2832_sdr.c index ef6feb299d46..1a2f0d2adadf 100644 --- a/drivers/media/dvb-frontends/rtl2832_sdr.c +++ b/drivers/media/dvb-frontends/rtl2832_sdr.c @@ -1130,8 +1130,6 @@ static int rtl2832_sdr_g_fmt_sdr_cap(struct file *file, void *priv, f->fmt.sdr.pixelformat = dev->pixelformat; f->fmt.sdr.buffersize = dev->buffersize; - memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved)); - return 0; } @@ -1149,7 +1147,6 @@ static int rtl2832_sdr_s_fmt_sdr_cap(struct file *file, void *priv, if (vb2_is_busy(q)) return -EBUSY; - memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved)); for (i = 0; i < dev->num_formats; i++) { if (formats[i].pixelformat == f->fmt.sdr.pixelformat) { dev->pixelformat = formats[i].pixelformat; @@ -1177,7 +1174,6 @@ static int rtl2832_sdr_try_fmt_sdr_cap(struct file *file, void *priv, dev_dbg(&pdev->dev, "pixelformat fourcc %4.4s\n", (char *)&f->fmt.sdr.pixelformat); - memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved)); for (i = 0; i < dev->num_formats; i++) { if (formats[i].pixelformat == f->fmt.sdr.pixelformat) { f->fmt.sdr.buffersize = formats[i].buffersize; diff --git a/drivers/media/test-drivers/vivid/vivid-sdr-cap.c b/drivers/media/test-drivers/vivid/vivid-sdr-cap.c index a1e52708b7ca..265db2114671 100644 --- a/drivers/media/test-drivers/vivid/vivid-sdr-cap.c +++ b/drivers/media/test-drivers/vivid/vivid-sdr-cap.c @@ -455,7 +455,6 @@ int vidioc_g_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f) f->fmt.sdr.pixelformat = dev->sdr_pixelformat; f->fmt.sdr.buffersize = dev->sdr_buffersize; - memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved)); return 0; } @@ -468,7 +467,6 @@ int vidioc_s_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f) if (vb2_is_busy(q)) return -EBUSY; - memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved)); for (i = 0; i < ARRAY_SIZE(formats); i++) { if (formats[i].pixelformat == f->fmt.sdr.pixelformat) { dev->sdr_pixelformat = formats[i].pixelformat; @@ -488,7 +486,6 @@ int vidioc_try_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f) { int i; - memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved)); for (i = 0; i < ARRAY_SIZE(formats); i++) { if (formats[i].pixelformat == f->fmt.sdr.pixelformat) { f->fmt.sdr.buffersize = formats[i].buffersize; diff --git a/drivers/media/usb/airspy/airspy.c b/drivers/media/usb/airspy/airspy.c index 751703db06f5..7a81be7970b2 100644 --- a/drivers/media/usb/airspy/airspy.c +++ b/drivers/media/usb/airspy/airspy.c @@ -632,7 +632,6 @@ static int airspy_g_fmt_sdr_cap(struct file *file, void *priv, f->fmt.sdr.pixelformat = s->pixelformat; f->fmt.sdr.buffersize = s->buffersize; - memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved)); return 0; } @@ -647,7 +646,6 @@ static int airspy_s_fmt_sdr_cap(struct file *file, void *priv, if (vb2_is_busy(q)) return -EBUSY; - memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved)); for (i = 0; i < NUM_FORMATS; i++) { if (formats[i].pixelformat == f->fmt.sdr.pixelformat) { s->pixelformat = formats[i].pixelformat; @@ -670,7 +668,6 @@ static int airspy_try_fmt_sdr_cap(struct file *file, void *priv, { int i; - memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved)); for (i = 0; i < NUM_FORMATS; i++) { if (formats[i].pixelformat == f->fmt.sdr.pixelformat) { f->fmt.sdr.buffersize = formats[i].buffersize; diff --git a/drivers/media/usb/hackrf/hackrf.c b/drivers/media/usb/hackrf/hackrf.c index cec841ad7495..3e535be2c520 100644 --- a/drivers/media/usb/hackrf/hackrf.c +++ b/drivers/media/usb/hackrf/hackrf.c @@ -929,7 +929,6 @@ static int hackrf_s_fmt_sdr(struct file *file, void *priv, if (vb2_is_busy(q)) return -EBUSY; - memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved)); for (i = 0; i < NUM_FORMATS; i++) { if (f->fmt.sdr.pixelformat == formats[i].pixelformat) { dev->pixelformat = formats[i].pixelformat; @@ -955,7 +954,6 @@ static int hackrf_g_fmt_sdr(struct file *file, void *priv, dev_dbg(dev->dev, "pixelformat fourcc %4.4s\n", (char *)&dev->pixelformat); - memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved)); f->fmt.sdr.pixelformat = dev->pixelformat; f->fmt.sdr.buffersize = dev->buffersize; @@ -971,7 +969,6 @@ static int hackrf_try_fmt_sdr(struct file *file, void *priv, dev_dbg(dev->dev, "pixelformat fourcc %4.4s\n", (char *)&f->fmt.sdr.pixelformat); - memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved)); for (i = 0; i < NUM_FORMATS; i++) { if (formats[i].pixelformat == f->fmt.sdr.pixelformat) { f->fmt.sdr.buffersize = formats[i].buffersize; diff --git a/drivers/media/usb/msi2500/msi2500.c b/drivers/media/usb/msi2500/msi2500.c index 63882a5248ae..71de6b4c4e4c 100644 --- a/drivers/media/usb/msi2500/msi2500.c +++ b/drivers/media/usb/msi2500/msi2500.c @@ -912,7 +912,6 @@ static int msi2500_g_fmt_sdr_cap(struct file *file, void *priv, f->fmt.sdr.pixelformat = dev->pixelformat; f->fmt.sdr.buffersize = dev->buffersize; - memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved)); return 0; } @@ -930,7 +929,6 @@ static int msi2500_s_fmt_sdr_cap(struct file *file, void *priv, if (vb2_is_busy(q)) return -EBUSY; - memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved)); for (i = 0; i < dev->num_formats; i++) { if (formats[i].pixelformat == f->fmt.sdr.pixelformat) { dev->pixelformat = formats[i].pixelformat; @@ -957,7 +955,6 @@ static int msi2500_try_fmt_sdr_cap(struct file *file, void *priv, dev_dbg(dev->dev, "pixelformat fourcc %4.4s\n", (char *)&f->fmt.sdr.pixelformat); - memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved)); for (i = 0; i < dev->num_formats; i++) { if (formats[i].pixelformat == f->fmt.sdr.pixelformat) { f->fmt.sdr.buffersize = formats[i].buffersize; From 3d37ef41bed0854805ab9af22c422267510e1344 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 23 Apr 2021 10:00:49 +0200 Subject: [PATCH 069/394] media: cobalt: fix race condition in setting HPD The cobalt_s_bit_sysctrl reads the old register value over PCI, then changes a bit and sets writes the new value to the register. This is used among other things for setting the HPD output pin. But if the HPD is changed for multiple inputs at the same time, then this causes a race condition where a stale value is read. Serialize this function with a mutex. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cobalt/cobalt-driver.c | 1 + drivers/media/pci/cobalt/cobalt-driver.h | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/media/pci/cobalt/cobalt-driver.c b/drivers/media/pci/cobalt/cobalt-driver.c index 839503e654f4..16af58f2f93c 100644 --- a/drivers/media/pci/cobalt/cobalt-driver.c +++ b/drivers/media/pci/cobalt/cobalt-driver.c @@ -667,6 +667,7 @@ static int cobalt_probe(struct pci_dev *pci_dev, return -ENOMEM; cobalt->pci_dev = pci_dev; cobalt->instance = i; + mutex_init(&cobalt->pci_lock); retval = v4l2_device_register(&pci_dev->dev, &cobalt->v4l2_dev); if (retval) { diff --git a/drivers/media/pci/cobalt/cobalt-driver.h b/drivers/media/pci/cobalt/cobalt-driver.h index bca68572b324..12c33e035904 100644 --- a/drivers/media/pci/cobalt/cobalt-driver.h +++ b/drivers/media/pci/cobalt/cobalt-driver.h @@ -251,6 +251,8 @@ struct cobalt { int instance; struct pci_dev *pci_dev; struct v4l2_device v4l2_dev; + /* serialize PCI access in cobalt_s_bit_sysctrl() */ + struct mutex pci_lock; void __iomem *bar0, *bar1; @@ -320,10 +322,13 @@ static inline u32 cobalt_g_sysctrl(struct cobalt *cobalt) static inline void cobalt_s_bit_sysctrl(struct cobalt *cobalt, int bit, int val) { - u32 ctrl = cobalt_read_bar1(cobalt, COBALT_SYS_CTRL_BASE); + u32 ctrl; + mutex_lock(&cobalt->pci_lock); + ctrl = cobalt_read_bar1(cobalt, COBALT_SYS_CTRL_BASE); cobalt_write_bar1(cobalt, COBALT_SYS_CTRL_BASE, (ctrl & ~(1UL << bit)) | (val << bit)); + mutex_unlock(&cobalt->pci_lock); } static inline u32 cobalt_g_sysstat(struct cobalt *cobalt) From 67a7e53d5b21f3a84efc03a4e62db7caf97841ef Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Tue, 27 Apr 2021 09:15:54 +0200 Subject: [PATCH 070/394] media: hevc: Fix dependent slice segment flags Dependent slice segment flag for PPS control is misnamed. It should have "enabled" at the end. It only tells if this flag is present in slice header or not and not the actual value. Fix this by renaming the PPS flag and introduce another flag for slice control which tells actual value. Signed-off-by: Jernej Skrabec Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst | 5 ++++- drivers/staging/media/sunxi/cedrus/cedrus_h265.c | 4 ++-- include/media/hevc-ctrls.h | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst index b0de4e6e7ebd..514b334470ea 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst @@ -3053,7 +3053,7 @@ enum v4l2_mpeg_video_hevc_size_of_length_field - :stub-columns: 0 :widths: 1 1 2 - * - ``V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT`` + * - ``V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT_ENABLED`` - 0x00000001 - * - ``V4L2_HEVC_PPS_FLAG_OUTPUT_FLAG_PRESENT`` @@ -3277,6 +3277,9 @@ enum v4l2_mpeg_video_hevc_size_of_length_field - * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED`` - 0x00000100 - + * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_DEPENDENT_SLICE_SEGMENT`` + - 0x00000200 + - .. raw:: latex diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c index ce497d0197df..10744fab7cea 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c @@ -477,8 +477,8 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx, slice_params->flags); reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_DEPENDENT_SLICE_SEGMENT, - V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT, - pps->flags); + V4L2_HEVC_SLICE_PARAMS_FLAG_DEPENDENT_SLICE_SEGMENT, + slice_params->flags); /* FIXME: For multi-slice support. */ reg |= VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_FIRST_SLICE_SEGMENT_IN_PIC; diff --git a/include/media/hevc-ctrls.h b/include/media/hevc-ctrls.h index b4cb2ef02f17..226fcfa0e026 100644 --- a/include/media/hevc-ctrls.h +++ b/include/media/hevc-ctrls.h @@ -81,7 +81,7 @@ struct v4l2_ctrl_hevc_sps { __u64 flags; }; -#define V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT (1ULL << 0) +#define V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT_ENABLED (1ULL << 0) #define V4L2_HEVC_PPS_FLAG_OUTPUT_FLAG_PRESENT (1ULL << 1) #define V4L2_HEVC_PPS_FLAG_SIGN_DATA_HIDING_ENABLED (1ULL << 2) #define V4L2_HEVC_PPS_FLAG_CABAC_INIT_PRESENT (1ULL << 3) @@ -160,6 +160,7 @@ struct v4l2_hevc_pred_weight_table { #define V4L2_HEVC_SLICE_PARAMS_FLAG_USE_INTEGER_MV (1ULL << 6) #define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_DEBLOCKING_FILTER_DISABLED (1ULL << 7) #define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED (1ULL << 8) +#define V4L2_HEVC_SLICE_PARAMS_FLAG_DEPENDENT_SLICE_SEGMENT (1ULL << 9) struct v4l2_ctrl_hevc_slice_params { __u32 bit_size; From 414e0a6437f96234fe0ba932093b8ff6a187192a Mon Sep 17 00:00:00 2001 From: dingsenjie Date: Fri, 30 Apr 2021 08:18:33 +0200 Subject: [PATCH 071/394] media: qcom/camss: Use devm_platform_ioremap_resource_byname Use the devm_platform_ioremap_resource_byname() helper instead of calling platform_get_resource_byname() and devm_ioremap_resource() separately. Signed-off-by: dingsenjie Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/camss/camss-csid.c | 3 +-- drivers/media/platform/qcom/camss/camss-csiphy.c | 8 +++----- drivers/media/platform/qcom/camss/camss-ispif.c | 6 ++---- drivers/media/platform/qcom/camss/camss-vfe.c | 3 +-- 4 files changed, 7 insertions(+), 13 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c index cc11fbfdae13..0e6b76e83983 100644 --- a/drivers/media/platform/qcom/camss/camss-csid.c +++ b/drivers/media/platform/qcom/camss/camss-csid.c @@ -566,8 +566,7 @@ int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid, /* Memory */ - r = platform_get_resource_byname(pdev, IORESOURCE_MEM, res->reg[0]); - csid->base = devm_ioremap_resource(dev, r); + csid->base = devm_platform_ioremap_resource_byname(pdev, res->reg[0]); if (IS_ERR(csid->base)) return PTR_ERR(csid->base); diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c index b3c3bf19e522..1996541278a2 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c @@ -591,16 +591,14 @@ int msm_csiphy_subdev_init(struct camss *camss, /* Memory */ - r = platform_get_resource_byname(pdev, IORESOURCE_MEM, res->reg[0]); - csiphy->base = devm_ioremap_resource(dev, r); + csiphy->base = devm_platform_ioremap_resource_byname(pdev, res->reg[0]); if (IS_ERR(csiphy->base)) return PTR_ERR(csiphy->base); if (camss->version == CAMSS_8x16 || camss->version == CAMSS_8x96) { - r = platform_get_resource_byname(pdev, IORESOURCE_MEM, - res->reg[1]); - csiphy->base_clk_mux = devm_ioremap_resource(dev, r); + csiphy->base_clk_mux = + devm_platform_ioremap_resource_byname(pdev, res->reg[1]); if (IS_ERR(csiphy->base_clk_mux)) return PTR_ERR(csiphy->base_clk_mux); } else { diff --git a/drivers/media/platform/qcom/camss/camss-ispif.c b/drivers/media/platform/qcom/camss/camss-ispif.c index 37611c8861da..d7942f723fdc 100644 --- a/drivers/media/platform/qcom/camss/camss-ispif.c +++ b/drivers/media/platform/qcom/camss/camss-ispif.c @@ -1143,13 +1143,11 @@ int msm_ispif_subdev_init(struct camss *camss, /* Memory */ - r = platform_get_resource_byname(pdev, IORESOURCE_MEM, res->reg[0]); - ispif->base = devm_ioremap_resource(dev, r); + ispif->base = devm_platform_ioremap_resource_byname(pdev, res->reg[0]); if (IS_ERR(ispif->base)) return PTR_ERR(ispif->base); - r = platform_get_resource_byname(pdev, IORESOURCE_MEM, res->reg[1]); - ispif->base_clk_mux = devm_ioremap_resource(dev, r); + ispif->base_clk_mux = devm_platform_ioremap_resource_byname(pdev, res->reg[1]); if (IS_ERR(ispif->base_clk_mux)) return PTR_ERR(ispif->base_clk_mux); diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c index 15695fd466c4..1584ee77ad00 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe.c +++ b/drivers/media/platform/qcom/camss/camss-vfe.c @@ -1301,8 +1301,7 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe, /* Memory */ - r = platform_get_resource_byname(pdev, IORESOURCE_MEM, res->reg[0]); - vfe->base = devm_ioremap_resource(dev, r); + vfe->base = devm_platform_ioremap_resource_byname(pdev, res->reg[0]); if (IS_ERR(vfe->base)) { dev_err(dev, "could not map memory\n"); return PTR_ERR(vfe->base); From 8edcb5049ac29aa3c8acc5ef15dd4036543d747e Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 30 Apr 2021 22:19:55 +0200 Subject: [PATCH 072/394] media: I2C: change 'RST' to "RSET" to fix multiple build errors The use of an enum named 'RST' conflicts with a #define macro named 'RST' in arch/mips/include/asm/mach-rc32434/rb.h. The MIPS use of RST was there first (AFAICT), so change the media/i2c/ uses of RST to be named 'RSET'. 'git grep -w RSET' does not report any naming conflicts with the new name. This fixes multiple build errors: arch/mips/include/asm/mach-rc32434/rb.h:15:14: error: expected identifier before '(' token 15 | #define RST (1 << 15) | ^ drivers/media/i2c/s5c73m3/s5c73m3.h:356:2: note: in expansion of macro 'RST' 356 | RST, | ^~~ ../arch/mips/include/asm/mach-rc32434/rb.h:15:14: error: expected identifier before '(' token 15 | #define RST (1 << 15) | ^ ../drivers/media/i2c/s5k6aa.c:180:2: note: in expansion of macro 'RST' 180 | RST, | ^~~ ../arch/mips/include/asm/mach-rc32434/rb.h:15:14: error: expected identifier before '(' token 15 | #define RST (1 << 15) | ^ ../drivers/media/i2c/s5k5baf.c:238:2: note: in expansion of macro 'RST' 238 | RST, | ^~~ and some others that I have trimmed. Fixes: cac47f1822fc ("[media] V4L: Add S5C73M3 camera driver") Fixes: 8b99312b7214 ("[media] Add v4l2 subdev driver for S5K4ECGX sensor") Fixes: 7d459937dc09 ("[media] Add driver for Samsung S5K5BAF camera sensor") Fixes: bfa8dd3a0524 ("[media] v4l: Add v4l2 subdev driver for S5K6AAFX sensor") Signed-off-by: Randy Dunlap Reported-by: kernel test robot Cc: Shawn Guo Cc: Sascha Hauer Cc: Pengutronix Kernel Team Cc: Fabio Estevam Cc: NXP Linux Team Cc: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) Cc: Andrzej Hajda Cc: Sylwester Nawrocki Cc: Sangwook Lee Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/s5c73m3/s5c73m3-core.c | 6 +++--- drivers/media/i2c/s5c73m3/s5c73m3.h | 2 +- drivers/media/i2c/s5k4ecgx.c | 10 +++++----- drivers/media/i2c/s5k5baf.c | 6 +++--- drivers/media/i2c/s5k6aa.c | 10 +++++----- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c index 5b4c4a3547c9..71804a70bc6d 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c +++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c @@ -1386,7 +1386,7 @@ static int __s5c73m3_power_on(struct s5c73m3 *state) s5c73m3_gpio_deassert(state, STBY); usleep_range(100, 200); - s5c73m3_gpio_deassert(state, RST); + s5c73m3_gpio_deassert(state, RSET); usleep_range(50, 100); return 0; @@ -1401,7 +1401,7 @@ static int __s5c73m3_power_off(struct s5c73m3 *state) { int i, ret; - if (s5c73m3_gpio_assert(state, RST)) + if (s5c73m3_gpio_assert(state, RSET)) usleep_range(10, 50); if (s5c73m3_gpio_assert(state, STBY)) @@ -1606,7 +1606,7 @@ static int s5c73m3_get_platform_data(struct s5c73m3 *state) state->mclk_frequency = pdata->mclk_frequency; state->gpio[STBY] = pdata->gpio_stby; - state->gpio[RST] = pdata->gpio_reset; + state->gpio[RSET] = pdata->gpio_reset; return 0; } diff --git a/drivers/media/i2c/s5c73m3/s5c73m3.h b/drivers/media/i2c/s5c73m3/s5c73m3.h index ef7e85b34263..c3fcfdd3ea66 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3.h +++ b/drivers/media/i2c/s5c73m3/s5c73m3.h @@ -353,7 +353,7 @@ struct s5c73m3_ctrls { enum s5c73m3_gpio_id { STBY, - RST, + RSET, GPIO_NUM, }; diff --git a/drivers/media/i2c/s5k4ecgx.c b/drivers/media/i2c/s5k4ecgx.c index b2d53417badf..4e97309a67f4 100644 --- a/drivers/media/i2c/s5k4ecgx.c +++ b/drivers/media/i2c/s5k4ecgx.c @@ -173,7 +173,7 @@ static const char * const s5k4ecgx_supply_names[] = { enum s5k4ecgx_gpio_id { STBY, - RST, + RSET, GPIO_NUM, }; @@ -476,7 +476,7 @@ static int __s5k4ecgx_power_on(struct s5k4ecgx *priv) if (s5k4ecgx_gpio_set_value(priv, STBY, priv->gpio[STBY].level)) usleep_range(30, 50); - if (s5k4ecgx_gpio_set_value(priv, RST, priv->gpio[RST].level)) + if (s5k4ecgx_gpio_set_value(priv, RSET, priv->gpio[RSET].level)) usleep_range(30, 50); return 0; @@ -484,7 +484,7 @@ static int __s5k4ecgx_power_on(struct s5k4ecgx *priv) static int __s5k4ecgx_power_off(struct s5k4ecgx *priv) { - if (s5k4ecgx_gpio_set_value(priv, RST, !priv->gpio[RST].level)) + if (s5k4ecgx_gpio_set_value(priv, RSET, !priv->gpio[RSET].level)) usleep_range(30, 50); if (s5k4ecgx_gpio_set_value(priv, STBY, !priv->gpio[STBY].level)) @@ -872,7 +872,7 @@ static int s5k4ecgx_config_gpios(struct s5k4ecgx *priv, int ret; priv->gpio[STBY].gpio = -EINVAL; - priv->gpio[RST].gpio = -EINVAL; + priv->gpio[RSET].gpio = -EINVAL; ret = s5k4ecgx_config_gpio(gpio->gpio, gpio->level, "S5K4ECGX_STBY"); @@ -891,7 +891,7 @@ static int s5k4ecgx_config_gpios(struct s5k4ecgx *priv, s5k4ecgx_free_gpios(priv); return ret; } - priv->gpio[RST] = *gpio; + priv->gpio[RSET] = *gpio; if (gpio_is_valid(gpio->gpio)) gpio_set_value(gpio->gpio, 0); diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c index 6e702b57c37d..bc560817e504 100644 --- a/drivers/media/i2c/s5k5baf.c +++ b/drivers/media/i2c/s5k5baf.c @@ -235,7 +235,7 @@ struct s5k5baf_gpio { enum s5k5baf_gpio_id { STBY, - RST, + RSET, NUM_GPIOS, }; @@ -969,7 +969,7 @@ static int s5k5baf_power_on(struct s5k5baf *state) s5k5baf_gpio_deassert(state, STBY); usleep_range(50, 100); - s5k5baf_gpio_deassert(state, RST); + s5k5baf_gpio_deassert(state, RSET); return 0; err_reg_dis: @@ -987,7 +987,7 @@ static int s5k5baf_power_off(struct s5k5baf *state) state->apply_cfg = 0; state->apply_crop = 0; - s5k5baf_gpio_assert(state, RST); + s5k5baf_gpio_assert(state, RSET); s5k5baf_gpio_assert(state, STBY); if (!IS_ERR(state->clock)) diff --git a/drivers/media/i2c/s5k6aa.c b/drivers/media/i2c/s5k6aa.c index 038e38500760..e9be7323a22e 100644 --- a/drivers/media/i2c/s5k6aa.c +++ b/drivers/media/i2c/s5k6aa.c @@ -177,7 +177,7 @@ static const char * const s5k6aa_supply_names[] = { enum s5k6aa_gpio_id { STBY, - RST, + RSET, GPIO_NUM, }; @@ -841,7 +841,7 @@ static int __s5k6aa_power_on(struct s5k6aa *s5k6aa) ret = s5k6aa->s_power(1); usleep_range(4000, 5000); - if (s5k6aa_gpio_deassert(s5k6aa, RST)) + if (s5k6aa_gpio_deassert(s5k6aa, RSET)) msleep(20); return ret; @@ -851,7 +851,7 @@ static int __s5k6aa_power_off(struct s5k6aa *s5k6aa) { int ret; - if (s5k6aa_gpio_assert(s5k6aa, RST)) + if (s5k6aa_gpio_assert(s5k6aa, RSET)) usleep_range(100, 150); if (s5k6aa->s_power) { @@ -1510,7 +1510,7 @@ static int s5k6aa_configure_gpios(struct s5k6aa *s5k6aa, int ret; s5k6aa->gpio[STBY].gpio = -EINVAL; - s5k6aa->gpio[RST].gpio = -EINVAL; + s5k6aa->gpio[RSET].gpio = -EINVAL; gpio = &pdata->gpio_stby; if (gpio_is_valid(gpio->gpio)) { @@ -1533,7 +1533,7 @@ static int s5k6aa_configure_gpios(struct s5k6aa *s5k6aa, if (ret < 0) return ret; - s5k6aa->gpio[RST] = *gpio; + s5k6aa->gpio[RSET] = *gpio; } return 0; From f8194e5e63fdcb349e8da9eef9e574d5b1d687cb Mon Sep 17 00:00:00 2001 From: Anirudh Rayabharam Date: Tue, 4 May 2021 19:08:58 +0200 Subject: [PATCH 073/394] media: pvrusb2: fix warning in pvr2_i2c_core_done syzbot has reported the following warning in pvr2_i2c_done: sysfs group 'power' not found for kobject '1-0043' When the device is disconnected (pvr_hdw_disconnect), the i2c adapter is not unregistered along with the USB and v4l2 teardown. As part of the USB device disconnect, the sysfs files of the subdevices are also deleted. So, by the time pvr_i2c_core_done is called by pvr_context_destroy, the sysfs files have been deleted. To fix this, unregister the i2c adapter too in pvr_hdw_disconnect. Make the device deregistration code shared by calling pvr_hdw_disconnect from pvr2_hdw_destroy. Reported-by: syzbot+e74a998ca8f1df9cc332@syzkaller.appspotmail.com Tested-by: syzbot+e74a998ca8f1df9cc332@syzkaller.appspotmail.com Reviewed-by: Greg Kroah-Hartman Signed-off-by: Anirudh Rayabharam Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/pvrusb2/pvrusb2-hdw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c index f4a727918e35..d38dee1792e4 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c @@ -2676,9 +2676,8 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw) pvr2_stream_destroy(hdw->vid_stream); hdw->vid_stream = NULL; } - pvr2_i2c_core_done(hdw); v4l2_device_unregister(&hdw->v4l2_dev); - pvr2_hdw_remove_usb_stuff(hdw); + pvr2_hdw_disconnect(hdw); mutex_lock(&pvr2_unit_mtx); do { if ((hdw->unit_number >= 0) && @@ -2705,6 +2704,7 @@ void pvr2_hdw_disconnect(struct pvr2_hdw *hdw) { pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_disconnect(hdw=%p)",hdw); LOCK_TAKE(hdw->big_lock); + pvr2_i2c_core_done(hdw); LOCK_TAKE(hdw->ctl_lock); pvr2_hdw_remove_usb_stuff(hdw); LOCK_GIVE(hdw->ctl_lock); From 09f4310c6bfbc0002ce1cf8fc90db50777d75916 Mon Sep 17 00:00:00 2001 From: Emil Velikov Date: Thu, 1 Apr 2021 16:43:28 +0200 Subject: [PATCH 074/394] media: hantro: use G1_REG_INTERRUPT directly for the mpeg2 Use the register directly over the existing SWREG(). Ideally we'll port the driver away from the local registers, but for now this is enough. For context - I was reading through the IRQ register handling across the variants. Acked-by: Nicolas Ferre Reviewed-by: Ezequiel Garcia Signed-off-by: Emil Velikov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c index 6386a3989bfe..0fd306806f16 100644 --- a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c +++ b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c @@ -10,6 +10,7 @@ #include #include "hantro.h" #include "hantro_hw.h" +#include "hantro_g1_regs.h" #define G1_SWREG(nr) ((nr) * 4) @@ -20,7 +21,6 @@ #define G1_REG_REFER2_BASE G1_SWREG(16) #define G1_REG_REFER3_BASE G1_SWREG(17) #define G1_REG_QTABLE_BASE G1_SWREG(40) -#define G1_REG_DEC_E(v) ((v) ? BIT(0) : 0) #define G1_REG_DEC_AXI_RD_ID(v) (((v) << 24) & GENMASK(31, 24)) #define G1_REG_DEC_TIMEOUT_E(v) ((v) ? BIT(23) : 0) @@ -246,6 +246,5 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx) hantro_end_prepare_run(ctx); - reg = G1_REG_DEC_E(1); - vdpu_write(vpu, reg, G1_SWREG(1)); + vdpu_write(vpu, G1_REG_INTERRUPT_DEC_E, G1_REG_INTERRUPT); } From 3b330849512ef7c617f72111fd958daf6febdf40 Mon Sep 17 00:00:00 2001 From: Emil Velikov Date: Thu, 1 Apr 2021 16:43:29 +0200 Subject: [PATCH 075/394] media: hantro: imx: reuse MB_DIM define Swap the hardcoded 16 with MB_DIM define. Fixes: 8e4aaa687863 ("media: hantro: add initial i.MX8MQ support") Acked-by: Nicolas Ferre Reviewed-by: Ezequiel Garcia Reviewed-by: Philipp Zabel Signed-off-by: Emil Velikov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/hantro/imx8m_vpu_hw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/hantro/imx8m_vpu_hw.c b/drivers/staging/media/hantro/imx8m_vpu_hw.c index c222de075ef4..1f48c1956cd2 100644 --- a/drivers/staging/media/hantro/imx8m_vpu_hw.c +++ b/drivers/staging/media/hantro/imx8m_vpu_hw.c @@ -109,10 +109,10 @@ static const struct hantro_fmt imx8m_vpu_dec_fmts[] = { .frmsize = { .min_width = 48, .max_width = 3840, - .step_width = 16, + .step_width = MB_DIM, .min_height = 48, .max_height = 2160, - .step_height = 16, + .step_height = MB_DIM, }, }, { From c78b22aaaa9055b05a5bd47f6715f0de16487dd4 Mon Sep 17 00:00:00 2001 From: Emil Velikov Date: Thu, 1 Apr 2021 16:43:30 +0200 Subject: [PATCH 076/394] media: hantro: imx: remove duplicate dec_base init The vpu->dec_base is already set by the hantro driver itself. Fixes: 8e4aaa687863 ("media: hantro: add initial i.MX8MQ support") Acked-by: Nicolas Ferre Reviewed-by: Ezequiel Garcia Reviewed-by: Philipp Zabel Signed-off-by: Emil Velikov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/hantro/imx8m_vpu_hw.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/media/hantro/imx8m_vpu_hw.c b/drivers/staging/media/hantro/imx8m_vpu_hw.c index 1f48c1956cd2..cb1ac02c03d2 100644 --- a/drivers/staging/media/hantro/imx8m_vpu_hw.c +++ b/drivers/staging/media/hantro/imx8m_vpu_hw.c @@ -150,7 +150,6 @@ static irqreturn_t imx8m_vpu_g1_irq(int irq, void *dev_id) static int imx8mq_vpu_hw_init(struct hantro_dev *vpu) { - vpu->dec_base = vpu->reg_bases[0]; vpu->ctrl_base = vpu->reg_bases[vpu->variant->num_regs - 1]; return 0; From d72a96b6c053dca29e7b2a94fb700f4960ce9834 Mon Sep 17 00:00:00 2001 From: Emil Velikov Date: Thu, 1 Apr 2021 16:43:31 +0200 Subject: [PATCH 077/394] media: hantro: imx: remove unused include The current imx8 code does not use the jpeg encoder. Remove the unnecessary include. Fixes: 8e4aaa687863 ("media: hantro: add initial i.MX8MQ support") Acked-by: Nicolas Ferre Reviewed-by: Ezequiel Garcia Reviewed-by: Philipp Zabel Signed-off-by: Emil Velikov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/hantro/imx8m_vpu_hw.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/media/hantro/imx8m_vpu_hw.c b/drivers/staging/media/hantro/imx8m_vpu_hw.c index cb1ac02c03d2..f36c1bd681ba 100644 --- a/drivers/staging/media/hantro/imx8m_vpu_hw.c +++ b/drivers/staging/media/hantro/imx8m_vpu_hw.c @@ -9,7 +9,6 @@ #include #include "hantro.h" -#include "hantro_jpeg.h" #include "hantro_g1_regs.h" #define CTRL_SOFT_RESET 0x00 From bbc42ab0da985f538eefe1b470a610624e53829f Mon Sep 17 00:00:00 2001 From: Emil Velikov Date: Thu, 1 Apr 2021 16:43:32 +0200 Subject: [PATCH 078/394] media: hantro: introduce hantro_g1.c for common API The Hantro G1 IRQ and reset handling is pretty standard. I was this close to duplicating it, yet again, before reconsidering and refactoring it to a separate file. Acked-by: Nicolas Ferre Reviewed-by: Ezequiel Garcia Reviewed-by: Philipp Zabel Signed-off-by: Emil Velikov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/hantro/Makefile | 1 + drivers/staging/media/hantro/hantro_g1.c | 39 ++++++++++++++++++++ drivers/staging/media/hantro/hantro_hw.h | 3 ++ drivers/staging/media/hantro/imx8m_vpu_hw.c | 21 +---------- drivers/staging/media/hantro/rk3288_vpu_hw.c | 36 ++---------------- 5 files changed, 48 insertions(+), 52 deletions(-) create mode 100644 drivers/staging/media/hantro/hantro_g1.c diff --git a/drivers/staging/media/hantro/Makefile b/drivers/staging/media/hantro/Makefile index 743ce08eb184..3747a32799b2 100644 --- a/drivers/staging/media/hantro/Makefile +++ b/drivers/staging/media/hantro/Makefile @@ -7,6 +7,7 @@ hantro-vpu-y += \ hantro_v4l2.o \ hantro_postproc.o \ hantro_h1_jpeg_enc.o \ + hantro_g1.o \ hantro_g1_h264_dec.o \ hantro_g1_mpeg2_dec.o \ hantro_g1_vp8_dec.o \ diff --git a/drivers/staging/media/hantro/hantro_g1.c b/drivers/staging/media/hantro/hantro_g1.c new file mode 100644 index 000000000000..0ab1cee62218 --- /dev/null +++ b/drivers/staging/media/hantro/hantro_g1.c @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Hantro VPU codec driver + * + * Copyright (C) 2018 Rockchip Electronics Co., Ltd. + * Jeffy Chen + * Copyright (C) 2019 Pengutronix, Philipp Zabel + * Copyright (C) 2021 Collabora Ltd, Emil Velikov + */ + +#include "hantro.h" +#include "hantro_g1_regs.h" + +irqreturn_t hantro_g1_irq(int irq, void *dev_id) +{ + struct hantro_dev *vpu = dev_id; + enum vb2_buffer_state state; + u32 status; + + status = vdpu_read(vpu, G1_REG_INTERRUPT); + state = (status & G1_REG_INTERRUPT_DEC_RDY_INT) ? + VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR; + + vdpu_write(vpu, 0, G1_REG_INTERRUPT); + vdpu_write(vpu, G1_REG_CONFIG_DEC_CLK_GATE_E, G1_REG_CONFIG); + + hantro_irq_done(vpu, state); + + return IRQ_HANDLED; +} + +void hantro_g1_reset(struct hantro_ctx *ctx) +{ + struct hantro_dev *vpu = ctx->dev; + + vdpu_write(vpu, G1_REG_INTERRUPT_DEC_IRQ_DIS, G1_REG_INTERRUPT); + vdpu_write(vpu, G1_REG_CONFIG_DEC_CLK_GATE_E, G1_REG_CONFIG); + vdpu_write(vpu, 1, G1_REG_SOFT_RESET); +} diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h index 0e34ae545f66..a1008e595808 100644 --- a/drivers/staging/media/hantro/hantro_hw.h +++ b/drivers/staging/media/hantro/hantro_hw.h @@ -176,6 +176,9 @@ void hantro_irq_done(struct hantro_dev *vpu, void hantro_start_prepare_run(struct hantro_ctx *ctx); void hantro_end_prepare_run(struct hantro_ctx *ctx); +irqreturn_t hantro_g1_irq(int irq, void *dev_id); +void hantro_g1_reset(struct hantro_ctx *ctx); + void hantro_h1_jpeg_enc_run(struct hantro_ctx *ctx); void rk3399_vpu_jpeg_enc_run(struct hantro_ctx *ctx); int hantro_jpeg_enc_init(struct hantro_ctx *ctx); diff --git a/drivers/staging/media/hantro/imx8m_vpu_hw.c b/drivers/staging/media/hantro/imx8m_vpu_hw.c index f36c1bd681ba..9eb556460e52 100644 --- a/drivers/staging/media/hantro/imx8m_vpu_hw.c +++ b/drivers/staging/media/hantro/imx8m_vpu_hw.c @@ -9,7 +9,6 @@ #include #include "hantro.h" -#include "hantro_g1_regs.h" #define CTRL_SOFT_RESET 0x00 #define RESET_G1 BIT(1) @@ -129,24 +128,6 @@ static const struct hantro_fmt imx8m_vpu_dec_fmts[] = { }, }; -static irqreturn_t imx8m_vpu_g1_irq(int irq, void *dev_id) -{ - struct hantro_dev *vpu = dev_id; - enum vb2_buffer_state state; - u32 status; - - status = vdpu_read(vpu, G1_REG_INTERRUPT); - state = (status & G1_REG_INTERRUPT_DEC_RDY_INT) ? - VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR; - - vdpu_write(vpu, 0, G1_REG_INTERRUPT); - vdpu_write(vpu, G1_REG_CONFIG_DEC_CLK_GATE_E, G1_REG_CONFIG); - - hantro_irq_done(vpu, state); - - return IRQ_HANDLED; -} - static int imx8mq_vpu_hw_init(struct hantro_dev *vpu) { vpu->ctrl_base = vpu->reg_bases[vpu->variant->num_regs - 1]; @@ -191,7 +172,7 @@ static const struct hantro_codec_ops imx8mq_vpu_codec_ops[] = { */ static const struct hantro_irq imx8mq_irqs[] = { - { "g1", imx8m_vpu_g1_irq }, + { "g1", hantro_g1_irq }, { "g2", NULL /* TODO: imx8m_vpu_g2_irq */ }, }; diff --git a/drivers/staging/media/hantro/rk3288_vpu_hw.c b/drivers/staging/media/hantro/rk3288_vpu_hw.c index 7b299ee3e93d..fefd45269e52 100644 --- a/drivers/staging/media/hantro/rk3288_vpu_hw.c +++ b/drivers/staging/media/hantro/rk3288_vpu_hw.c @@ -10,7 +10,6 @@ #include "hantro.h" #include "hantro_jpeg.h" -#include "hantro_g1_regs.h" #include "hantro_h1_regs.h" #define RK3288_ACLK_MAX_FREQ (400 * 1000 * 1000) @@ -127,24 +126,6 @@ static irqreturn_t rk3288_vepu_irq(int irq, void *dev_id) return IRQ_HANDLED; } -static irqreturn_t rk3288_vdpu_irq(int irq, void *dev_id) -{ - struct hantro_dev *vpu = dev_id; - enum vb2_buffer_state state; - u32 status; - - status = vdpu_read(vpu, G1_REG_INTERRUPT); - state = (status & G1_REG_INTERRUPT_DEC_RDY_INT) ? - VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR; - - vdpu_write(vpu, 0, G1_REG_INTERRUPT); - vdpu_write(vpu, G1_REG_CONFIG_DEC_CLK_GATE_E, G1_REG_CONFIG); - - hantro_irq_done(vpu, state); - - return IRQ_HANDLED; -} - static int rk3288_vpu_hw_init(struct hantro_dev *vpu) { /* Bump ACLK to max. possible freq. to improve performance. */ @@ -161,15 +142,6 @@ static void rk3288_vpu_enc_reset(struct hantro_ctx *ctx) vepu_write(vpu, 0, H1_REG_AXI_CTRL); } -static void rk3288_vpu_dec_reset(struct hantro_ctx *ctx) -{ - struct hantro_dev *vpu = ctx->dev; - - vdpu_write(vpu, G1_REG_INTERRUPT_DEC_IRQ_DIS, G1_REG_INTERRUPT); - vdpu_write(vpu, G1_REG_CONFIG_DEC_CLK_GATE_E, G1_REG_CONFIG); - vdpu_write(vpu, 1, G1_REG_SOFT_RESET); -} - /* * Supported codec ops. */ @@ -184,19 +156,19 @@ static const struct hantro_codec_ops rk3288_vpu_codec_ops[] = { }, [HANTRO_MODE_H264_DEC] = { .run = hantro_g1_h264_dec_run, - .reset = rk3288_vpu_dec_reset, + .reset = hantro_g1_reset, .init = hantro_h264_dec_init, .exit = hantro_h264_dec_exit, }, [HANTRO_MODE_MPEG2_DEC] = { .run = hantro_g1_mpeg2_dec_run, - .reset = rk3288_vpu_dec_reset, + .reset = hantro_g1_reset, .init = hantro_mpeg2_dec_init, .exit = hantro_mpeg2_dec_exit, }, [HANTRO_MODE_VP8_DEC] = { .run = hantro_g1_vp8_dec_run, - .reset = rk3288_vpu_dec_reset, + .reset = hantro_g1_reset, .init = hantro_vp8_dec_init, .exit = hantro_vp8_dec_exit, }, @@ -208,7 +180,7 @@ static const struct hantro_codec_ops rk3288_vpu_codec_ops[] = { static const struct hantro_irq rk3288_irqs[] = { { "vepu", rk3288_vepu_irq }, - { "vdpu", rk3288_vdpu_irq }, + { "vdpu", hantro_g1_irq }, }; static const char * const rk3288_clk_names[] = { From 18d6c8b7b4c94c5e2e5b5807d9484b4d54b8fa1b Mon Sep 17 00:00:00 2001 From: Emil Velikov Date: Thu, 1 Apr 2021 16:43:33 +0200 Subject: [PATCH 079/394] media: hantro: add fallback handling for single irq/clk Currently the driver expects that each irq/clk will have a name specified. A valid point was raised by the DT maintainers - when there is a single interrupt line or clock - the names are not needed. Keep the names within the drivers themselves, but don't use them when only a single entry exists. Instead use: - num_clk == 1 - devm_clk_get(..., NULL) - num_irq == 1 - platform_get_irq(..., 0) Suggested-by: Ezequiel Garcia Signed-off-by: Emil Velikov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/hantro/hantro_drv.c | 37 ++++++++++++++++++----- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c index eea2009fa17b..dd37d87e4c2a 100644 --- a/drivers/staging/media/hantro/hantro_drv.c +++ b/drivers/staging/media/hantro/hantro_drv.c @@ -763,12 +763,23 @@ static int hantro_probe(struct platform_device *pdev) if (!vpu->clocks) return -ENOMEM; - for (i = 0; i < vpu->variant->num_clocks; i++) - vpu->clocks[i].id = vpu->variant->clk_names[i]; - ret = devm_clk_bulk_get(&pdev->dev, vpu->variant->num_clocks, - vpu->clocks); - if (ret) - return ret; + if (vpu->variant->num_clocks > 1) { + for (i = 0; i < vpu->variant->num_clocks; i++) + vpu->clocks[i].id = vpu->variant->clk_names[i]; + + ret = devm_clk_bulk_get(&pdev->dev, vpu->variant->num_clocks, + vpu->clocks); + if (ret) + return ret; + } else { + /* + * If the driver has a single clk, chances are there will be no + * actual name in the DT bindings. + */ + vpu->clocks[0].clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(vpu->clocks)) + return PTR_ERR(vpu->clocks); + } num_bases = vpu->variant->num_regs ?: 1; vpu->reg_bases = devm_kcalloc(&pdev->dev, num_bases, @@ -796,13 +807,23 @@ static int hantro_probe(struct platform_device *pdev) vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32)); for (i = 0; i < vpu->variant->num_irqs; i++) { - const char *irq_name = vpu->variant->irqs[i].name; + const char *irq_name; int irq; if (!vpu->variant->irqs[i].handler) continue; - irq = platform_get_irq_byname(vpu->pdev, irq_name); + if (vpu->variant->num_clocks > 1) { + irq_name = vpu->variant->irqs[i].name; + irq = platform_get_irq_byname(vpu->pdev, irq_name); + } else { + /* + * If the driver has a single IRQ, chances are there + * will be no actual name in the DT bindings. + */ + irq_name = "default"; + irq = platform_get_irq(vpu->pdev, 0); + } if (irq <= 0) return -ENXIO; From 0d705395afa4b4fa7d0fae86b9c04cfe50a03ace Mon Sep 17 00:00:00 2001 From: Emil Velikov Date: Thu, 1 Apr 2021 16:43:34 +0200 Subject: [PATCH 080/394] media: dt-bindings: Document SAMA5D4 VDEC bindings Add devicetree binding documentation for the Hantro G1/G2 VDEC on the Microchip SAMAS5D4 SoC. Acked-by: Nicolas Ferre Signed-off-by: Emil Velikov Reviewed-by: Rob Herring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../media/microchip,sama5d4-vdec.yaml | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/microchip,sama5d4-vdec.yaml diff --git a/Documentation/devicetree/bindings/media/microchip,sama5d4-vdec.yaml b/Documentation/devicetree/bindings/media/microchip,sama5d4-vdec.yaml new file mode 100644 index 000000000000..4b77103ca913 --- /dev/null +++ b/Documentation/devicetree/bindings/media/microchip,sama5d4-vdec.yaml @@ -0,0 +1,47 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) + +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/media/microchip,sama5d4-vdec.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +title: Hantro G1 VPU codec implemented on Microchip SAMA5D4 SoCs + +maintainers: + - Emil Velikov + +description: + Hantro G1 video decode accelerator present on Microchip SAMA5D4 SoCs. + +properties: + compatible: + const: microchip,sama5d4-vdec + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + - clocks + +additionalProperties: false + +examples: + - | + #include + #include + + vdec0: vdec@300000 { + compatible = "microchip,sama5d4-vdec"; + reg = <0x00300000 0x100000>; + interrupts = <19 IRQ_TYPE_LEVEL_HIGH 4>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 19>; + }; From 82ad940c00949965739360f68b90d9a00ccefc81 Mon Sep 17 00:00:00 2001 From: Emil Velikov Date: Thu, 1 Apr 2021 16:43:35 +0200 Subject: [PATCH 081/394] media: hantro: add initial SAMA5D4 support The SoC features a Hantro G1 compatible video decoder, supporting the MPEG-2, VP8 and H264 codecs with resolutions up-to 1280x720. Post-processing core is also available on the SoC. Acked-by: Nicolas Ferre Reviewed-by: Ezequiel Garcia Signed-off-by: Emil Velikov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/hantro/Kconfig | 10 +- drivers/staging/media/hantro/Makefile | 3 + drivers/staging/media/hantro/hantro_drv.c | 3 + drivers/staging/media/hantro/hantro_hw.h | 1 + .../staging/media/hantro/sama5d4_vdec_hw.c | 117 ++++++++++++++++++ 5 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 drivers/staging/media/hantro/sama5d4_vdec_hw.c diff --git a/drivers/staging/media/hantro/Kconfig b/drivers/staging/media/hantro/Kconfig index 5b6cf9f62b1a..20b1f6d7b69c 100644 --- a/drivers/staging/media/hantro/Kconfig +++ b/drivers/staging/media/hantro/Kconfig @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 config VIDEO_HANTRO tristate "Hantro VPU driver" - depends on ARCH_MXC || ARCH_ROCKCHIP || COMPILE_TEST + depends on ARCH_MXC || ARCH_ROCKCHIP || ARCH_AT91 || COMPILE_TEST depends on VIDEO_DEV && VIDEO_V4L2 select MEDIA_CONTROLLER select MEDIA_CONTROLLER_REQUEST_API @@ -24,6 +24,14 @@ config VIDEO_HANTRO_IMX8M help Enable support for i.MX8M SoCs. +config VIDEO_HANTRO_SAMA5D4 + bool "Hantro VDEC SAMA5D4 support" + depends on VIDEO_HANTRO + depends on ARCH_AT91 || COMPILE_TEST + default y + help + Enable support for Microchip SAMA5D4 SoCs. + config VIDEO_HANTRO_ROCKCHIP bool "Hantro VPU Rockchip support" depends on VIDEO_HANTRO diff --git a/drivers/staging/media/hantro/Makefile b/drivers/staging/media/hantro/Makefile index 3747a32799b2..f4b99901eeee 100644 --- a/drivers/staging/media/hantro/Makefile +++ b/drivers/staging/media/hantro/Makefile @@ -22,6 +22,9 @@ hantro-vpu-y += \ hantro-vpu-$(CONFIG_VIDEO_HANTRO_IMX8M) += \ imx8m_vpu_hw.o +hantro-vpu-$(CONFIG_VIDEO_HANTRO_SAMA5D4) += \ + sama5d4_vdec_hw.o + hantro-vpu-$(CONFIG_VIDEO_HANTRO_ROCKCHIP) += \ rk3288_vpu_hw.o \ rk3399_vpu_hw.o diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c index dd37d87e4c2a..85dcb0882afc 100644 --- a/drivers/staging/media/hantro/hantro_drv.c +++ b/drivers/staging/media/hantro/hantro_drv.c @@ -489,6 +489,9 @@ static const struct of_device_id of_hantro_match[] = { #endif #ifdef CONFIG_VIDEO_HANTRO_IMX8M { .compatible = "nxp,imx8mq-vpu", .data = &imx8mq_vpu_variant, }, +#endif +#ifdef CONFIG_VIDEO_HANTRO_SAMA5D4 + { .compatible = "microchip,sama5d4-vdec", .data = &sama5d4_vdec_variant, }, #endif { /* sentinel */ } }; diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h index a1008e595808..0a42df22472e 100644 --- a/drivers/staging/media/hantro/hantro_hw.h +++ b/drivers/staging/media/hantro/hantro_hw.h @@ -164,6 +164,7 @@ extern const struct hantro_variant rk3399_vpu_variant; extern const struct hantro_variant rk3328_vpu_variant; extern const struct hantro_variant rk3288_vpu_variant; extern const struct hantro_variant imx8mq_vpu_variant; +extern const struct hantro_variant sama5d4_vdec_variant; extern const struct hantro_postproc_regs hantro_g1_postproc_regs; diff --git a/drivers/staging/media/hantro/sama5d4_vdec_hw.c b/drivers/staging/media/hantro/sama5d4_vdec_hw.c new file mode 100644 index 000000000000..58ae72c2b723 --- /dev/null +++ b/drivers/staging/media/hantro/sama5d4_vdec_hw.c @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Hantro VDEC driver + * + * Copyright (C) 2021 Collabora Ltd, Emil Velikov + */ + +#include "hantro.h" + +/* + * Supported formats. + */ + +static const struct hantro_fmt sama5d4_vdec_postproc_fmts[] = { + { + .fourcc = V4L2_PIX_FMT_YUYV, + .codec_mode = HANTRO_MODE_NONE, + }, +}; + +static const struct hantro_fmt sama5d4_vdec_fmts[] = { + { + .fourcc = V4L2_PIX_FMT_NV12, + .codec_mode = HANTRO_MODE_NONE, + }, + { + .fourcc = V4L2_PIX_FMT_MPEG2_SLICE, + .codec_mode = HANTRO_MODE_MPEG2_DEC, + .max_depth = 2, + .frmsize = { + .min_width = 48, + .max_width = 1280, + .step_width = MB_DIM, + .min_height = 48, + .max_height = 720, + .step_height = MB_DIM, + }, + }, + { + .fourcc = V4L2_PIX_FMT_VP8_FRAME, + .codec_mode = HANTRO_MODE_VP8_DEC, + .max_depth = 2, + .frmsize = { + .min_width = 48, + .max_width = 1280, + .step_width = MB_DIM, + .min_height = 48, + .max_height = 720, + .step_height = MB_DIM, + }, + }, + { + .fourcc = V4L2_PIX_FMT_H264_SLICE, + .codec_mode = HANTRO_MODE_H264_DEC, + .max_depth = 2, + .frmsize = { + .min_width = 48, + .max_width = 1280, + .step_width = MB_DIM, + .min_height = 48, + .max_height = 720, + .step_height = MB_DIM, + }, + }, +}; + +static int sama5d4_hw_init(struct hantro_dev *vpu) +{ + return 0; +} + +/* + * Supported codec ops. + */ + +static const struct hantro_codec_ops sama5d4_vdec_codec_ops[] = { + [HANTRO_MODE_MPEG2_DEC] = { + .run = hantro_g1_mpeg2_dec_run, + .reset = hantro_g1_reset, + .init = hantro_mpeg2_dec_init, + .exit = hantro_mpeg2_dec_exit, + }, + [HANTRO_MODE_VP8_DEC] = { + .run = hantro_g1_vp8_dec_run, + .reset = hantro_g1_reset, + .init = hantro_vp8_dec_init, + .exit = hantro_vp8_dec_exit, + }, + [HANTRO_MODE_H264_DEC] = { + .run = hantro_g1_h264_dec_run, + .reset = hantro_g1_reset, + .init = hantro_h264_dec_init, + .exit = hantro_h264_dec_exit, + }, +}; + +static const struct hantro_irq sama5d4_irqs[] = { + { "vdec", hantro_g1_irq }, +}; + +static const char * const sama5d4_clk_names[] = { "vdec_clk" }; + +const struct hantro_variant sama5d4_vdec_variant = { + .dec_fmts = sama5d4_vdec_fmts, + .num_dec_fmts = ARRAY_SIZE(sama5d4_vdec_fmts), + .postproc_fmts = sama5d4_vdec_postproc_fmts, + .num_postproc_fmts = ARRAY_SIZE(sama5d4_vdec_postproc_fmts), + .postproc_regs = &hantro_g1_postproc_regs, + .codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER | + HANTRO_H264_DECODER, + .codec_ops = sama5d4_vdec_codec_ops, + .init = sama5d4_hw_init, + .irqs = sama5d4_irqs, + .num_irqs = ARRAY_SIZE(sama5d4_irqs), + .clk_names = sama5d4_clk_names, + .num_clocks = ARRAY_SIZE(sama5d4_clk_names), +}; From bb9212fd971035597d264fc6a7cc4df0db9b5fd0 Mon Sep 17 00:00:00 2001 From: Emil Velikov Date: Thu, 1 Apr 2021 16:43:36 +0200 Subject: [PATCH 082/394] media: ARM: dts: sama5d4: enable Hantro G1 VDEC Add the SAMA5D4 VDEC module which comprises Hantro G1 video decoder core. Cc: Rob Herring Cc: Frank Rowand Cc: devicetree@vger.kernel.org Acked-by: Nicolas Ferre Signed-off-by: Emil Velikov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- arch/arm/boot/dts/sama5d4.dtsi | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi index 05c55875835d..e47e1ca63043 100644 --- a/arch/arm/boot/dts/sama5d4.dtsi +++ b/arch/arm/boot/dts/sama5d4.dtsi @@ -101,6 +101,13 @@ ranges = <0 0x100000 0x2400>; }; + vdec0: vdec@300000 { + compatible = "microchip,sama5d4-vdec"; + reg = <0x00300000 0x100000>; + interrupts = <19 IRQ_TYPE_LEVEL_HIGH 4>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 19>; + }; + usb0: gadget@400000 { compatible = "atmel,sama5d3-udc"; reg = <0x00400000 0x100000 From 401b0e5dcab62196c56aa7c2536b0cacfc506e0e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:11 +0200 Subject: [PATCH 083/394] media: i2c: ak7375: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Reviewed-by: Jonathan Cameron Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ak7375.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/media/i2c/ak7375.c b/drivers/media/i2c/ak7375.c index e1f94ee0f48f..40b1a4aa846c 100644 --- a/drivers/media/i2c/ak7375.c +++ b/drivers/media/i2c/ak7375.c @@ -87,15 +87,7 @@ static const struct v4l2_ctrl_ops ak7375_vcm_ctrl_ops = { static int ak7375_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { - int ret; - - ret = pm_runtime_get_sync(sd->dev); - if (ret < 0) { - pm_runtime_put_noidle(sd->dev); - return ret; - } - - return 0; + return pm_runtime_resume_and_get(sd->dev); } static int ak7375_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) From 7917f27941c3c1289aad2be27bf329844125d13e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:11 +0200 Subject: [PATCH 084/394] media: i2c: dw9714: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/dw9714.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/media/i2c/dw9714.c b/drivers/media/i2c/dw9714.c index 3f0b082f863f..c8b4292512dc 100644 --- a/drivers/media/i2c/dw9714.c +++ b/drivers/media/i2c/dw9714.c @@ -85,15 +85,7 @@ static const struct v4l2_ctrl_ops dw9714_vcm_ctrl_ops = { static int dw9714_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { - int rval; - - rval = pm_runtime_get_sync(sd->dev); - if (rval < 0) { - pm_runtime_put_noidle(sd->dev); - return rval; - } - - return 0; + return pm_runtime_resume_and_get(sd->dev); } static int dw9714_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) From ed8f47b061250ddaadcfe33a54532241a718b59e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:12 +0200 Subject: [PATCH 085/394] media: i2c: dw9768: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/dw9768.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/media/i2c/dw9768.c b/drivers/media/i2c/dw9768.c index 8b8cb4b077b5..c086580efac7 100644 --- a/drivers/media/i2c/dw9768.c +++ b/drivers/media/i2c/dw9768.c @@ -374,15 +374,7 @@ static const struct v4l2_ctrl_ops dw9768_ctrl_ops = { static int dw9768_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { - int ret; - - ret = pm_runtime_get_sync(sd->dev); - if (ret < 0) { - pm_runtime_put_noidle(sd->dev); - return ret; - } - - return 0; + return pm_runtime_resume_and_get(sd->dev); } static int dw9768_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) From d5e75e8b4a24715fddd4adf3a4c0bf90e36546c5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:12 +0200 Subject: [PATCH 086/394] media: i2c: dw9807-vcm: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/dw9807-vcm.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/media/i2c/dw9807-vcm.c b/drivers/media/i2c/dw9807-vcm.c index 438a44b76da8..95e06f13bc9e 100644 --- a/drivers/media/i2c/dw9807-vcm.c +++ b/drivers/media/i2c/dw9807-vcm.c @@ -130,15 +130,7 @@ static const struct v4l2_ctrl_ops dw9807_vcm_ctrl_ops = { static int dw9807_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { - int rval; - - rval = pm_runtime_get_sync(sd->dev); - if (rval < 0) { - pm_runtime_put_noidle(sd->dev); - return rval; - } - - return 0; + return pm_runtime_resume_and_get(sd->dev); } static int dw9807_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) From c36c7d56ad4426ddf6cc598a52562533709a245c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:12 +0200 Subject: [PATCH 087/394] media: i2c: hi556: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/hi556.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/i2c/hi556.c b/drivers/media/i2c/hi556.c index 6f05c1138e3b..627ccfa34835 100644 --- a/drivers/media/i2c/hi556.c +++ b/drivers/media/i2c/hi556.c @@ -813,9 +813,8 @@ static int hi556_set_stream(struct v4l2_subdev *sd, int enable) mutex_lock(&hi556->mutex); if (enable) { - ret = pm_runtime_get_sync(&client->dev); + ret = pm_runtime_resume_and_get(&client->dev); if (ret < 0) { - pm_runtime_put_noidle(&client->dev); mutex_unlock(&hi556->mutex); return ret; } From 3c11dfe3be25940dba2472f4e3114be132a74ba0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:12 +0200 Subject: [PATCH 088/394] media: i2c: imx214: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/imx214.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/imx214.c b/drivers/media/i2c/imx214.c index e8b281e432e8..1a770a530cf5 100644 --- a/drivers/media/i2c/imx214.c +++ b/drivers/media/i2c/imx214.c @@ -776,11 +776,9 @@ static int imx214_s_stream(struct v4l2_subdev *subdev, int enable) return 0; if (enable) { - ret = pm_runtime_get_sync(imx214->dev); - if (ret < 0) { - pm_runtime_put_noidle(imx214->dev); + ret = pm_runtime_resume_and_get(imx214->dev); + if (ret < 0) return ret; - } ret = imx214_start_streaming(imx214); if (ret < 0) From 30ad455912651abb79db379a2a2eaad00509ba87 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:12 +0200 Subject: [PATCH 089/394] media: i2c: imx219: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/imx219.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c index 1054ffedaefd..74a0bf9b088b 100644 --- a/drivers/media/i2c/imx219.c +++ b/drivers/media/i2c/imx219.c @@ -1035,11 +1035,9 @@ static int imx219_start_streaming(struct imx219 *imx219) const struct imx219_reg_list *reg_list; int ret; - ret = pm_runtime_get_sync(&client->dev); - if (ret < 0) { - pm_runtime_put_noidle(&client->dev); + ret = pm_runtime_resume_and_get(&client->dev); + if (ret < 0) return ret; - } /* Apply default values of current mode */ reg_list = &imx219->mode->reg_list; From 018ef43017113afc24d0a1842b7c7cf66a52cfc9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:13 +0200 Subject: [PATCH 090/394] media: i2c: imx258: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/imx258.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/imx258.c b/drivers/media/i2c/imx258.c index a017ec4e0f50..90529424d5b6 100644 --- a/drivers/media/i2c/imx258.c +++ b/drivers/media/i2c/imx258.c @@ -1039,11 +1039,9 @@ static int imx258_set_stream(struct v4l2_subdev *sd, int enable) } if (enable) { - ret = pm_runtime_get_sync(&client->dev); - if (ret < 0) { - pm_runtime_put_noidle(&client->dev); + ret = pm_runtime_resume_and_get(&client->dev); + if (ret < 0) goto err_unlock; - } /* * Apply default & customized values From bb94b8f3a76e76ed24e76fa58892fd8db86c13c2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:13 +0200 Subject: [PATCH 091/394] media: i2c: imx274: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/imx274.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/i2c/imx274.c b/drivers/media/i2c/imx274.c index cdccaab3043a..ee2127436f0b 100644 --- a/drivers/media/i2c/imx274.c +++ b/drivers/media/i2c/imx274.c @@ -1441,9 +1441,8 @@ static int imx274_s_stream(struct v4l2_subdev *sd, int on) mutex_lock(&imx274->lock); if (on) { - ret = pm_runtime_get_sync(&imx274->client->dev); + ret = pm_runtime_resume_and_get(&imx274->client->dev); if (ret < 0) { - pm_runtime_put_noidle(&imx274->client->dev); mutex_unlock(&imx274->lock); return ret; } From 739d9c64150a73dccfa9a8b792de5179fa06e1f7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:13 +0200 Subject: [PATCH 092/394] media: i2c: imx290: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/imx290.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/imx290.c b/drivers/media/i2c/imx290.c index 6319a42057d2..06020e648a97 100644 --- a/drivers/media/i2c/imx290.c +++ b/drivers/media/i2c/imx290.c @@ -764,11 +764,9 @@ static int imx290_set_stream(struct v4l2_subdev *sd, int enable) int ret = 0; if (enable) { - ret = pm_runtime_get_sync(imx290->dev); - if (ret < 0) { - pm_runtime_put_noidle(imx290->dev); + ret = pm_runtime_resume_and_get(imx290->dev); + if (ret < 0) goto unlock_and_return; - } ret = imx290_start_streaming(imx290); if (ret) { From c0f8f1b6a10110fd70c41114214ba1b209d9a910 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:13 +0200 Subject: [PATCH 093/394] media: i2c: imx319: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/imx319.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/imx319.c b/drivers/media/i2c/imx319.c index 38540323a156..4e0a8c9d271f 100644 --- a/drivers/media/i2c/imx319.c +++ b/drivers/media/i2c/imx319.c @@ -2141,11 +2141,9 @@ static int imx319_set_stream(struct v4l2_subdev *sd, int enable) } if (enable) { - ret = pm_runtime_get_sync(&client->dev); - if (ret < 0) { - pm_runtime_put_noidle(&client->dev); + ret = pm_runtime_resume_and_get(&client->dev); + if (ret < 0) goto err_unlock; - } /* * Apply default & customized values From 5f070f4df4fd71230074d154a6fd99c6abe03abb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:14 +0200 Subject: [PATCH 094/394] media: i2c: imx355: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/imx355.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c index ccedcd4c520a..93f13a04439a 100644 --- a/drivers/media/i2c/imx355.c +++ b/drivers/media/i2c/imx355.c @@ -1442,11 +1442,9 @@ static int imx355_set_stream(struct v4l2_subdev *sd, int enable) } if (enable) { - ret = pm_runtime_get_sync(&client->dev); - if (ret < 0) { - pm_runtime_put_noidle(&client->dev); + ret = pm_runtime_resume_and_get(&client->dev); + if (ret < 0) goto err_unlock; - } /* * Apply default & customized values From e7c018a96355fa0d8ce2d4499d300584a92717c2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:14 +0200 Subject: [PATCH 095/394] media: i2c: mt9m001: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/mt9m001.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/mt9m001.c b/drivers/media/i2c/mt9m001.c index 3b0ba8ed5233..58c85a3bccf6 100644 --- a/drivers/media/i2c/mt9m001.c +++ b/drivers/media/i2c/mt9m001.c @@ -217,9 +217,9 @@ static int mt9m001_s_stream(struct v4l2_subdev *sd, int enable) goto done; if (enable) { - ret = pm_runtime_get_sync(&client->dev); + ret = pm_runtime_resume_and_get(&client->dev); if (ret < 0) - goto put_unlock; + goto unlock; ret = mt9m001_apply_selection(sd); if (ret) @@ -247,6 +247,7 @@ done: put_unlock: pm_runtime_put(&client->dev); +unlock: mutex_unlock(&mt9m001->mutex); return ret; @@ -834,6 +835,10 @@ static int mt9m001_remove(struct i2c_client *client) { struct mt9m001 *mt9m001 = to_mt9m001(client); + /* + * As it increments RPM usage_count even on errors, we don't need to + * check the returned code here. + */ pm_runtime_get_sync(&client->dev); v4l2_async_unregister_subdev(&mt9m001->subdev); From 67d44de2f842414d28acc0512311a9dad17ee797 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:14 +0200 Subject: [PATCH 096/394] media: i2c: ov02a10: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov02a10.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/ov02a10.c b/drivers/media/i2c/ov02a10.c index c47b1d45d8fd..a1d7314b20a9 100644 --- a/drivers/media/i2c/ov02a10.c +++ b/drivers/media/i2c/ov02a10.c @@ -540,11 +540,9 @@ static int ov02a10_s_stream(struct v4l2_subdev *sd, int on) } if (on) { - ret = pm_runtime_get_sync(&client->dev); - if (ret < 0) { - pm_runtime_put_noidle(&client->dev); + ret = pm_runtime_resume_and_get(&client->dev); + if (ret < 0) goto unlock_and_return; - } ret = __ov02a10_start_stream(ov02a10); if (ret) { From cc9351ff1055f932e7af637081a411ffeaf82f76 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:14 +0200 Subject: [PATCH 097/394] media: i2c: ov13858: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov13858.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/ov13858.c b/drivers/media/i2c/ov13858.c index 4a2885ff0cbe..9598c0b19603 100644 --- a/drivers/media/i2c/ov13858.c +++ b/drivers/media/i2c/ov13858.c @@ -1472,11 +1472,9 @@ static int ov13858_set_stream(struct v4l2_subdev *sd, int enable) } if (enable) { - ret = pm_runtime_get_sync(&client->dev); - if (ret < 0) { - pm_runtime_put_noidle(&client->dev); + ret = pm_runtime_resume_and_get(&client->dev); + if (ret < 0) goto err_unlock; - } /* * Apply default & customized values From c12ede18c38beb4804bfc9995be05a75e0c1a34a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:14 +0200 Subject: [PATCH 098/394] media: i2c: ov2659: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Acked-by: Lad Prabhakar Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov2659.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c index 42f64175a6df..a3c8eae68486 100644 --- a/drivers/media/i2c/ov2659.c +++ b/drivers/media/i2c/ov2659.c @@ -1186,11 +1186,9 @@ static int ov2659_s_stream(struct v4l2_subdev *sd, int on) goto unlock; } - ret = pm_runtime_get_sync(&client->dev); - if (ret < 0) { - pm_runtime_put_noidle(&client->dev); + ret = pm_runtime_resume_and_get(&client->dev); + if (ret < 0) goto unlock; - } ret = ov2659_init(sd, 0); if (!ret) From c679b2365a9e93f5def3a548bb2917f1968c59a5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:15 +0200 Subject: [PATCH 099/394] media: i2c: ov2685: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov2685.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/ov2685.c b/drivers/media/i2c/ov2685.c index 49a2dcedb347..2f3836dd8eed 100644 --- a/drivers/media/i2c/ov2685.c +++ b/drivers/media/i2c/ov2685.c @@ -456,11 +456,10 @@ static int ov2685_s_stream(struct v4l2_subdev *sd, int on) goto unlock_and_return; if (on) { - ret = pm_runtime_get_sync(&ov2685->client->dev); - if (ret < 0) { - pm_runtime_put_noidle(&client->dev); + ret = pm_runtime_resume_and_get(&ov2685->client->dev); + if (ret < 0) goto unlock_and_return; - } + ret = __v4l2_ctrl_handler_setup(&ov2685->ctrl_handler); if (ret) { pm_runtime_put(&client->dev); From b9be93aa55b4ee1821b2974995640fa769689d94 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:15 +0200 Subject: [PATCH 100/394] media: i2c: ov2740: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Reviewed-by: Jonathan Cameron Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov2740.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c index 0f3f17f3c426..54779f720f9d 100644 --- a/drivers/media/i2c/ov2740.c +++ b/drivers/media/i2c/ov2740.c @@ -751,9 +751,8 @@ static int ov2740_set_stream(struct v4l2_subdev *sd, int enable) mutex_lock(&ov2740->mutex); if (enable) { - ret = pm_runtime_get_sync(&client->dev); + ret = pm_runtime_resume_and_get(&client->dev); if (ret < 0) { - pm_runtime_put_noidle(&client->dev); mutex_unlock(&ov2740->mutex); return ret; } @@ -1049,9 +1048,8 @@ static int ov2740_nvmem_read(void *priv, unsigned int off, void *val, goto exit; } - ret = pm_runtime_get_sync(dev); + ret = pm_runtime_resume_and_get(dev); if (ret < 0) { - pm_runtime_put_noidle(dev); goto exit; } From 5187df40bf3d910d883cfff815812540de951999 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:15 +0200 Subject: [PATCH 101/394] media: i2c: ov5647: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Acked-by: Jacopo Mondi Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov5647.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c index 1cefa15729ce..38faa74755e3 100644 --- a/drivers/media/i2c/ov5647.c +++ b/drivers/media/i2c/ov5647.c @@ -882,20 +882,20 @@ static int ov5647_s_stream(struct v4l2_subdev *sd, int enable) } if (enable) { - ret = pm_runtime_get_sync(&client->dev); + ret = pm_runtime_resume_and_get(&client->dev); if (ret < 0) goto error_unlock; ret = ov5647_stream_on(sd); if (ret < 0) { dev_err(&client->dev, "stream start failed: %d\n", ret); - goto error_unlock; + goto error_pm; } } else { ret = ov5647_stream_off(sd); if (ret < 0) { dev_err(&client->dev, "stream stop failed: %d\n", ret); - goto error_unlock; + goto error_pm; } pm_runtime_put(&client->dev); } @@ -905,8 +905,9 @@ static int ov5647_s_stream(struct v4l2_subdev *sd, int enable) return 0; -error_unlock: +error_pm: pm_runtime_put(&client->dev); +error_unlock: mutex_unlock(&sensor->lock); return ret; From 6b19d297008627ba4296448e760624578b199542 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:15 +0200 Subject: [PATCH 102/394] media: i2c: ov5648: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov5648.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/ov5648.c b/drivers/media/i2c/ov5648.c index 3ecb4a3e8773..07e64ff0be3f 100644 --- a/drivers/media/i2c/ov5648.c +++ b/drivers/media/i2c/ov5648.c @@ -2132,11 +2132,9 @@ static int ov5648_s_stream(struct v4l2_subdev *subdev, int enable) int ret; if (enable) { - ret = pm_runtime_get_sync(sensor->dev); - if (ret < 0) { - pm_runtime_put_noidle(sensor->dev); + ret = pm_runtime_resume_and_get(sensor->dev); + if (ret < 0) return ret; - } } mutex_lock(&sensor->mutex); From f151c230dced061eebeeafae6d6c5958d4a46689 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:15 +0200 Subject: [PATCH 103/394] media: i2c: ov5670: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov5670.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/ov5670.c b/drivers/media/i2c/ov5670.c index dee7df8dd100..182f271f118f 100644 --- a/drivers/media/i2c/ov5670.c +++ b/drivers/media/i2c/ov5670.c @@ -2347,11 +2347,9 @@ static int ov5670_set_stream(struct v4l2_subdev *sd, int enable) goto unlock_and_return; if (enable) { - ret = pm_runtime_get_sync(&client->dev); - if (ret < 0) { - pm_runtime_put_noidle(&client->dev); + ret = pm_runtime_resume_and_get(&client->dev); + if (ret < 0) goto unlock_and_return; - } ret = ov5670_start_streaming(ov5670); if (ret) From f236bb2490b60eea8e2db0251fc9062181762fe5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:16 +0200 Subject: [PATCH 104/394] media: i2c: ov5675: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov5675.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/i2c/ov5675.c b/drivers/media/i2c/ov5675.c index dea32859459a..e7e297a23960 100644 --- a/drivers/media/i2c/ov5675.c +++ b/drivers/media/i2c/ov5675.c @@ -863,9 +863,8 @@ static int ov5675_set_stream(struct v4l2_subdev *sd, int enable) mutex_lock(&ov5675->mutex); if (enable) { - ret = pm_runtime_get_sync(&client->dev); + ret = pm_runtime_resume_and_get(&client->dev); if (ret < 0) { - pm_runtime_put_noidle(&client->dev); mutex_unlock(&ov5675->mutex); return ret; } From 1541ac5ffd4c228242ec4f0af3a73e7bd652ab3f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:16 +0200 Subject: [PATCH 105/394] media: i2c: ov5695: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov5695.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/ov5695.c b/drivers/media/i2c/ov5695.c index 09bee57a241d..469d941813c6 100644 --- a/drivers/media/i2c/ov5695.c +++ b/drivers/media/i2c/ov5695.c @@ -946,11 +946,9 @@ static int ov5695_s_stream(struct v4l2_subdev *sd, int on) goto unlock_and_return; if (on) { - ret = pm_runtime_get_sync(&client->dev); - if (ret < 0) { - pm_runtime_put_noidle(&client->dev); + ret = pm_runtime_resume_and_get(&client->dev); + if (ret < 0) goto unlock_and_return; - } ret = __ov5695_start_stream(ov5695); if (ret) { From 45bbff806cab3bb5b5026386b896d1c6f027556c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:16 +0200 Subject: [PATCH 106/394] media: i2c: ov7740: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov7740.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/ov7740.c b/drivers/media/i2c/ov7740.c index 47a9003d29d6..e0ff6506a543 100644 --- a/drivers/media/i2c/ov7740.c +++ b/drivers/media/i2c/ov7740.c @@ -624,11 +624,9 @@ static int ov7740_set_stream(struct v4l2_subdev *sd, int enable) } if (enable) { - ret = pm_runtime_get_sync(&client->dev); - if (ret < 0) { - pm_runtime_put_noidle(&client->dev); + ret = pm_runtime_resume_and_get(&client->dev); + if (ret < 0) goto err_unlock; - } ret = ov7740_start_streaming(ov7740); if (ret) From 529e78dea6a05750a9ff7bb44bb360546d4a322d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:16 +0200 Subject: [PATCH 107/394] media: i2c: ov8856: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov8856.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/i2c/ov8856.c b/drivers/media/i2c/ov8856.c index e3af3ea277af..2875f8e4ddcb 100644 --- a/drivers/media/i2c/ov8856.c +++ b/drivers/media/i2c/ov8856.c @@ -1340,9 +1340,8 @@ static int ov8856_set_stream(struct v4l2_subdev *sd, int enable) mutex_lock(&ov8856->mutex); if (enable) { - ret = pm_runtime_get_sync(&client->dev); + ret = pm_runtime_resume_and_get(&client->dev); if (ret < 0) { - pm_runtime_put_noidle(&client->dev); mutex_unlock(&ov8856->mutex); return ret; } From 586ee057ba6b014520e3dac232ac25da987f5ac0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:16 +0200 Subject: [PATCH 108/394] media: i2c: ov8865: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov8865.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c index 9ecf180635ee..3bf6ee4898a9 100644 --- a/drivers/media/i2c/ov8865.c +++ b/drivers/media/i2c/ov8865.c @@ -2497,11 +2497,9 @@ static int ov8865_s_stream(struct v4l2_subdev *subdev, int enable) int ret; if (enable) { - ret = pm_runtime_get_sync(sensor->dev); - if (ret < 0) { - pm_runtime_put_noidle(sensor->dev); + ret = pm_runtime_resume_and_get(sensor->dev); + if (ret < 0) return ret; - } } mutex_lock(&sensor->mutex); From 279a085db8c8bcf7d83b06cfe36cf4b80f4d0566 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:16 +0200 Subject: [PATCH 109/394] media: i2c: ov9734: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov9734.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/i2c/ov9734.c b/drivers/media/i2c/ov9734.c index b7309a551cae..ba156683c533 100644 --- a/drivers/media/i2c/ov9734.c +++ b/drivers/media/i2c/ov9734.c @@ -644,9 +644,8 @@ static int ov9734_set_stream(struct v4l2_subdev *sd, int enable) } if (enable) { - ret = pm_runtime_get_sync(&client->dev); + ret = pm_runtime_resume_and_get(&client->dev); if (ret < 0) { - pm_runtime_put_noidle(&client->dev); mutex_unlock(&ov9734->mutex); return ret; } From 81f2fe55d12b3ad26c8203c51967ae531db7ac40 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:17 +0200 Subject: [PATCH 110/394] media: i2c: tvp5150: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/tvp5150.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c index e26e3f544054..374a9da75e4d 100644 --- a/drivers/media/i2c/tvp5150.c +++ b/drivers/media/i2c/tvp5150.c @@ -1448,11 +1448,9 @@ static int tvp5150_s_stream(struct v4l2_subdev *sd, int enable) TVP5150_MISC_CTL_CLOCK_OE; if (enable) { - ret = pm_runtime_get_sync(sd->dev); - if (ret < 0) { - pm_runtime_put_noidle(sd->dev); + ret = pm_runtime_resume_and_get(sd->dev); + if (ret < 0) return ret; - } tvp5150_enable(sd); @@ -1675,15 +1673,7 @@ err: static int tvp5150_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { - int ret; - - ret = pm_runtime_get_sync(sd->dev); - if (ret < 0) { - pm_runtime_put_noidle(sd->dev); - return ret; - } - - return 0; + return pm_runtime_resume_and_get(sd->dev); } static int tvp5150_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) From a959a7bf3b939494adca95b1c53e98b74fd90702 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:17 +0200 Subject: [PATCH 111/394] media: i2c: video-i2c: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/video-i2c.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/media/i2c/video-i2c.c b/drivers/media/i2c/video-i2c.c index 0465832a4090..de12f38f347c 100644 --- a/drivers/media/i2c/video-i2c.c +++ b/drivers/media/i2c/video-i2c.c @@ -286,11 +286,9 @@ static int amg88xx_read(struct device *dev, enum hwmon_sensor_types type, __le16 buf; int tmp; - tmp = pm_runtime_get_sync(regmap_get_device(data->regmap)); - if (tmp < 0) { - pm_runtime_put_noidle(regmap_get_device(data->regmap)); + tmp = pm_runtime_resume_and_get(regmap_get_device(data->regmap)); + if (tmp < 0) return tmp; - } tmp = regmap_bulk_read(data->regmap, AMG88XX_REG_TTHL, &buf, 2); pm_runtime_mark_last_busy(regmap_get_device(data->regmap)); @@ -512,11 +510,9 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) if (data->kthread_vid_cap) return 0; - ret = pm_runtime_get_sync(dev); - if (ret < 0) { - pm_runtime_put_noidle(dev); + ret = pm_runtime_resume_and_get(dev); + if (ret < 0) goto error_del_list; - } ret = data->chip->setup(data); if (ret) From 2450f59d24166c8af60aa075e9dec4466f905c1f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:11 +0200 Subject: [PATCH 112/394] media: i2c: ccs-core: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Reviewed-by: Jonathan Cameron Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ccs/ccs-core.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index 4a848ac2d2cd..a349189a38db 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -3101,12 +3101,9 @@ static int __maybe_unused ccs_suspend(struct device *dev) bool streaming = sensor->streaming; int rval; - rval = pm_runtime_get_sync(dev); - if (rval < 0) { - pm_runtime_put_noidle(dev); - + rval = pm_runtime_resume_and_get(dev); + if (rval < 0) return rval; - } if (sensor->streaming) ccs_stop_streaming(sensor); From 75ecb9c83cf9d29eaa05bbdd0f84356ac22ed972 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:22 +0200 Subject: [PATCH 113/394] staging: media: imx7-mipi-csis: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Acked-by: Rui Miguel Silva Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/imx7-mipi-csis.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c index 025fdc488bd6..1dc680d94a46 100644 --- a/drivers/staging/media/imx/imx7-mipi-csis.c +++ b/drivers/staging/media/imx/imx7-mipi-csis.c @@ -695,11 +695,10 @@ static int mipi_csis_s_stream(struct v4l2_subdev *mipi_sd, int enable) mipi_csis_clear_counters(state); - ret = pm_runtime_get_sync(&state->pdev->dev); - if (ret < 0) { - pm_runtime_put_noidle(&state->pdev->dev); + ret = pm_runtime_resume_and_get(&state->pdev->dev); + if (ret < 0) return ret; - } + ret = v4l2_subdev_call(state->src_sd, core, s_power, 1); if (ret < 0 && ret != -ENOIOCTLCMD) goto done; From deb9119f807abd01d4d78a2dc567b10e2501ec79 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:21 +0200 Subject: [PATCH 114/394] staging: media: atomisp: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Besides that, the de-init order in case of css error was wrong. This change should also fix that. Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/pci/atomisp_fops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/atomisp/pci/atomisp_fops.c b/drivers/staging/media/atomisp/pci/atomisp_fops.c index f1e6b2597853..26d05474a035 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_fops.c +++ b/drivers/staging/media/atomisp/pci/atomisp_fops.c @@ -837,7 +837,7 @@ dev_init: } /* runtime power management, turn on ISP */ - ret = pm_runtime_get_sync(vdev->v4l2_dev->dev); + ret = pm_runtime_resume_and_get(vdev->v4l2_dev->dev); if (ret < 0) { dev_err(isp->dev, "Failed to power on device\n"); goto error; @@ -881,9 +881,9 @@ done: css_error: atomisp_css_uninit(isp); + pm_runtime_put(vdev->v4l2_dev->dev); error: hmm_pool_unregister(HMM_POOL_TYPE_DYNAMIC); - pm_runtime_put(vdev->v4l2_dev->dev); rt_mutex_unlock(&isp->mutex); return ret; } From 7af42f3136d8029f84be743a06c96ba024eabb40 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:22 +0200 Subject: [PATCH 115/394] staging: media: ipu3: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Reviewed-by: Jonathan Cameron Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/ipu3/ipu3.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/media/ipu3/ipu3.c b/drivers/staging/media/ipu3/ipu3.c index ee1bba6bdcac..8e1e9e46e604 100644 --- a/drivers/staging/media/ipu3/ipu3.c +++ b/drivers/staging/media/ipu3/ipu3.c @@ -392,10 +392,9 @@ int imgu_s_stream(struct imgu_device *imgu, int enable) } /* Set Power */ - r = pm_runtime_get_sync(dev); + r = pm_runtime_resume_and_get(dev); if (r < 0) { dev_err(dev, "failed to set imgu power\n"); - pm_runtime_put(dev); return r; } From e21e1e94ce10e7ce09f98184526a237125179155 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:22 +0200 Subject: [PATCH 116/394] staging: media: cedrus_video: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Acked-by: Jonathan Cameron Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/sunxi/cedrus/cedrus_video.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging/media/sunxi/cedrus/cedrus_video.c index b62eb8e84057..9ddd789d0b1f 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c @@ -490,11 +490,9 @@ static int cedrus_start_streaming(struct vb2_queue *vq, unsigned int count) } if (V4L2_TYPE_IS_OUTPUT(vq->type)) { - ret = pm_runtime_get_sync(dev->dev); - if (ret < 0) { - pm_runtime_put_noidle(dev->dev); + ret = pm_runtime_resume_and_get(dev->dev); + if (ret < 0) goto err_cleanup; - } if (dev->dec_ops[ctx->current_codec]->start) { ret = dev->dec_ops[ctx->current_codec]->start(ctx); From dc8276b789174071ca3fbfe887a95718b3f9b888 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:22 +0200 Subject: [PATCH 117/394] staging: media: tegra-vde: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/tegra-vde/vde.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/staging/media/tegra-vde/vde.c b/drivers/staging/media/tegra-vde/vde.c index 28845b5bafaf..e025b69776f2 100644 --- a/drivers/staging/media/tegra-vde/vde.c +++ b/drivers/staging/media/tegra-vde/vde.c @@ -775,9 +775,9 @@ static int tegra_vde_ioctl_decode_h264(struct tegra_vde *vde, if (ret) goto release_dpb_frames; - ret = pm_runtime_get_sync(dev); + ret = pm_runtime_resume_and_get(dev); if (ret < 0) - goto put_runtime_pm; + goto unlock; /* * We rely on the VDE registers reset value, otherwise VDE @@ -843,6 +843,8 @@ static int tegra_vde_ioctl_decode_h264(struct tegra_vde *vde, put_runtime_pm: pm_runtime_mark_last_busy(dev); pm_runtime_put_autosuspend(dev); + +unlock: mutex_unlock(&vde->lock); release_dpb_frames: @@ -1069,11 +1071,19 @@ static int tegra_vde_probe(struct platform_device *pdev) * power-cycle it in order to put hardware into a predictable lower * power state. */ - pm_runtime_get_sync(dev); + if (pm_runtime_resume_and_get(dev) < 0) + goto err_pm_runtime; + pm_runtime_put(dev); return 0; +err_pm_runtime: + misc_deregister(&vde->miscdev); + + pm_runtime_dont_use_autosuspend(dev); + pm_runtime_disable(dev); + err_deinit_iommu: tegra_vde_iommu_deinit(vde); @@ -1089,7 +1099,12 @@ static int tegra_vde_remove(struct platform_device *pdev) struct tegra_vde *vde = platform_get_drvdata(pdev); struct device *dev = &pdev->dev; + /* + * As it increments RPM usage_count even on errors, we don't need to + * check the returned code here. + */ pm_runtime_get_sync(dev); + pm_runtime_dont_use_autosuspend(dev); pm_runtime_disable(dev); From c09ffca53fcd186e140c82ea73e51cb4dd362053 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:23 +0200 Subject: [PATCH 118/394] staging: media: tegra-video: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Reviewed-by: Jonathan Cameron Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/tegra-video/csi.c | 3 +-- drivers/staging/media/tegra-video/vi.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/media/tegra-video/csi.c b/drivers/staging/media/tegra-video/csi.c index 033a6935c26d..e938bf4c48b6 100644 --- a/drivers/staging/media/tegra-video/csi.c +++ b/drivers/staging/media/tegra-video/csi.c @@ -298,10 +298,9 @@ static int tegra_csi_enable_stream(struct v4l2_subdev *subdev) struct tegra_csi *csi = csi_chan->csi; int ret, err; - ret = pm_runtime_get_sync(csi->dev); + ret = pm_runtime_resume_and_get(csi->dev); if (ret < 0) { dev_err(csi->dev, "failed to get runtime PM: %d\n", ret); - pm_runtime_put_noidle(csi->dev); return ret; } diff --git a/drivers/staging/media/tegra-video/vi.c b/drivers/staging/media/tegra-video/vi.c index b712063a7c5d..b76e9110e706 100644 --- a/drivers/staging/media/tegra-video/vi.c +++ b/drivers/staging/media/tegra-video/vi.c @@ -297,10 +297,9 @@ static int tegra_channel_start_streaming(struct vb2_queue *vq, u32 count) struct tegra_vi_channel *chan = vb2_get_drv_priv(vq); int ret; - ret = pm_runtime_get_sync(chan->vi->dev); + ret = pm_runtime_resume_and_get(chan->vi->dev); if (ret < 0) { dev_err(chan->vi->dev, "failed to get runtime PM: %d\n", ret); - pm_runtime_put_noidle(chan->vi->dev); return ret; } From 0314339a0a49f4a128b61e5e1a0af1df6e64a186 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:20 +0200 Subject: [PATCH 119/394] media: rockchip/rga: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Reviewed-by: Ezequiel Garcia Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/rockchip/rga/rga-buf.c | 3 +-- drivers/media/platform/rockchip/rga/rga.c | 4 +++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/rockchip/rga/rga-buf.c b/drivers/media/platform/rockchip/rga/rga-buf.c index bf9a75b75083..81508ed5abf3 100644 --- a/drivers/media/platform/rockchip/rga/rga-buf.c +++ b/drivers/media/platform/rockchip/rga/rga-buf.c @@ -79,9 +79,8 @@ static int rga_buf_start_streaming(struct vb2_queue *q, unsigned int count) struct rockchip_rga *rga = ctx->rga; int ret; - ret = pm_runtime_get_sync(rga->dev); + ret = pm_runtime_resume_and_get(rga->dev); if (ret < 0) { - pm_runtime_put_noidle(rga->dev); rga_buf_return_buffers(q, VB2_BUF_STATE_QUEUED); return ret; } diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c index 9d122429706e..bf3fd71ec3af 100644 --- a/drivers/media/platform/rockchip/rga/rga.c +++ b/drivers/media/platform/rockchip/rga/rga.c @@ -866,7 +866,9 @@ static int rga_probe(struct platform_device *pdev) goto unreg_video_dev; } - pm_runtime_get_sync(rga->dev); + ret = pm_runtime_resume_and_get(rga->dev); + if (ret < 0) + goto unreg_video_dev; rga->version.major = (rga_read(rga, RGA_VERSION_INFO) >> 24) & 0xFF; rga->version.minor = (rga_read(rga, RGA_VERSION_INFO) >> 20) & 0x0F; From bc700a13cd3ffe8bb6ef7274ede74a19639fd6dd Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 15:35:51 +0200 Subject: [PATCH 120/394] media: sti/hva: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. While the hva driver does it right, there are lots of errors on other drivers due to its misusage. So, let's change this driver to also use pm_runtime_resume_and_get(), as we're doing similar changes all over the media subsystem. Reviewed-by: Jonathan Cameron Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/sti/hva/hva-hw.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/sti/hva/hva-hw.c b/drivers/media/platform/sti/hva/hva-hw.c index f59811e27f51..77b8bfa5e0c5 100644 --- a/drivers/media/platform/sti/hva/hva-hw.c +++ b/drivers/media/platform/sti/hva/hva-hw.c @@ -270,9 +270,8 @@ static unsigned long int hva_hw_get_ip_version(struct hva_dev *hva) struct device *dev = hva_to_dev(hva); unsigned long int version; - if (pm_runtime_get_sync(dev) < 0) { + if (pm_runtime_resume_and_get(dev) < 0) { dev_err(dev, "%s failed to get pm_runtime\n", HVA_PREFIX); - pm_runtime_put_noidle(dev); mutex_unlock(&hva->protect_mutex); return -EFAULT; } @@ -386,10 +385,10 @@ int hva_hw_probe(struct platform_device *pdev, struct hva_dev *hva) pm_runtime_set_suspended(dev); pm_runtime_enable(dev); - ret = pm_runtime_get_sync(dev); + ret = pm_runtime_resume_and_get(dev); if (ret < 0) { dev_err(dev, "%s failed to set PM\n", HVA_PREFIX); - goto err_pm; + goto err_clk; } /* check IP hardware version */ @@ -462,6 +461,7 @@ int hva_hw_execute_task(struct hva_ctx *ctx, enum hva_hw_cmd_type cmd, u8 client_id = ctx->id; int ret; u32 reg = 0; + bool got_pm = false; mutex_lock(&hva->protect_mutex); @@ -469,12 +469,13 @@ int hva_hw_execute_task(struct hva_ctx *ctx, enum hva_hw_cmd_type cmd, enable_irq(hva->irq_its); enable_irq(hva->irq_err); - if (pm_runtime_get_sync(dev) < 0) { + if (pm_runtime_resume_and_get(dev) < 0) { dev_err(dev, "%s failed to get pm_runtime\n", ctx->name); ctx->sys_errors++; ret = -EFAULT; goto out; } + got_pm = true; reg = readl_relaxed(hva->regs + HVA_HIF_REG_CLK_GATING); switch (cmd) { @@ -537,7 +538,8 @@ out: dev_dbg(dev, "%s unknown command 0x%x\n", ctx->name, cmd); } - pm_runtime_put_autosuspend(dev); + if (got_pm) + pm_runtime_put_autosuspend(dev); mutex_unlock(&hva->protect_mutex); return ret; @@ -553,9 +555,8 @@ void hva_hw_dump_regs(struct hva_dev *hva, struct seq_file *s) mutex_lock(&hva->protect_mutex); - if (pm_runtime_get_sync(dev) < 0) { + if (pm_runtime_resume_and_get(dev) < 0) { seq_puts(s, "Cannot wake up IP\n"); - pm_runtime_put_noidle(dev); mutex_unlock(&hva->protect_mutex); return; } From 0ccb25b8279cb6f212434322126b4c512f0b306c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:17 +0200 Subject: [PATCH 121/394] media: ipu3: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/intel/ipu3/ipu3-cio2-main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c index fecef85bd62e..ca8040d1a725 100644 --- a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c @@ -975,10 +975,9 @@ static int cio2_vb2_start_streaming(struct vb2_queue *vq, unsigned int count) cio2->cur_queue = q; atomic_set(&q->frame_sequence, 0); - r = pm_runtime_get_sync(&cio2->pci_dev->dev); + r = pm_runtime_resume_and_get(&cio2->pci_dev->dev); if (r < 0) { dev_info(&cio2->pci_dev->dev, "failed to set power %d\n", r); - pm_runtime_put_noidle(&cio2->pci_dev->dev); return r; } From 7295e537bb2b16b500ff55cd6209b3cefd323948 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:17 +0200 Subject: [PATCH 122/394] media: coda: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. While here, as noted by Phillip, the labels at the coda_open() function are currently named after what operation failed, instead of what they do in response. So, change the name of the error label that it is called when clk_enable fails, in order to be consistent. Reviewed-by: Philipp Zabel Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-common.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index bd666c858fa1..2017de85713e 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c @@ -2660,7 +2660,7 @@ static int coda_open(struct file *file) ctx->use_vdoa = false; /* Power up and upload firmware if necessary */ - ret = pm_runtime_get_sync(dev->dev); + ret = pm_runtime_resume_and_get(dev->dev); if (ret < 0) { v4l2_err(&dev->v4l2_dev, "failed to power up: %d\n", ret); goto err_pm_get; @@ -2668,7 +2668,7 @@ static int coda_open(struct file *file) ret = clk_prepare_enable(dev->clk_per); if (ret) - goto err_pm_get; + goto err_clk_enable; ret = clk_prepare_enable(dev->clk_ahb); if (ret) @@ -2707,8 +2707,9 @@ err_ctx_init: clk_disable_unprepare(dev->clk_ahb); err_clk_ahb: clk_disable_unprepare(dev->clk_per); -err_pm_get: +err_clk_enable: pm_runtime_put_sync(dev->dev); +err_pm_get: v4l2_fh_del(&ctx->fh); v4l2_fh_exit(&ctx->fh); err_coda_name_init: From 97df01fae800ff765dbb247ee30c7a438b2ae07b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:18 +0200 Subject: [PATCH 123/394] media: mtk-jpeg: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c index 88a23bce569d..a89c7b206eef 100644 --- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c @@ -920,7 +920,7 @@ static void mtk_jpeg_enc_device_run(void *priv) src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); - ret = pm_runtime_get_sync(jpeg->dev); + ret = pm_runtime_resume_and_get(jpeg->dev); if (ret < 0) goto enc_end; @@ -973,7 +973,7 @@ static void mtk_jpeg_dec_device_run(void *priv) return; } - ret = pm_runtime_get_sync(jpeg->dev); + ret = pm_runtime_resume_and_get(jpeg->dev); if (ret < 0) goto dec_end; From 09dfb36ce250e76322ac8940c10d75e53a9e48d4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:18 +0200 Subject: [PATCH 124/394] media: camss: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Reviewed-by: Robert Foss Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/camss/camss-csid.c | 6 ++---- drivers/media/platform/qcom/camss/camss-csiphy.c | 6 ++---- drivers/media/platform/qcom/camss/camss-ispif.c | 6 ++---- drivers/media/platform/qcom/camss/camss-vfe.c | 5 +++-- 4 files changed, 9 insertions(+), 14 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c index 0e6b76e83983..7e2490ca1ad1 100644 --- a/drivers/media/platform/qcom/camss/camss-csid.c +++ b/drivers/media/platform/qcom/camss/camss-csid.c @@ -156,11 +156,9 @@ static int csid_set_power(struct v4l2_subdev *sd, int on) int ret; if (on) { - ret = pm_runtime_get_sync(dev); - if (ret < 0) { - pm_runtime_put_sync(dev); + ret = pm_runtime_resume_and_get(dev); + if (ret < 0) return ret; - } ret = regulator_enable(csid->vdda); if (ret < 0) { diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c index 1996541278a2..b623e007aec6 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c @@ -197,11 +197,9 @@ static int csiphy_set_power(struct v4l2_subdev *sd, int on) if (on) { int ret; - ret = pm_runtime_get_sync(dev); - if (ret < 0) { - pm_runtime_put_sync(dev); + ret = pm_runtime_resume_and_get(dev); + if (ret < 0) return ret; - } ret = csiphy_set_clock_rates(csiphy); if (ret < 0) { diff --git a/drivers/media/platform/qcom/camss/camss-ispif.c b/drivers/media/platform/qcom/camss/camss-ispif.c index d7942f723fdc..1b716182d35c 100644 --- a/drivers/media/platform/qcom/camss/camss-ispif.c +++ b/drivers/media/platform/qcom/camss/camss-ispif.c @@ -372,11 +372,9 @@ static int ispif_set_power(struct v4l2_subdev *sd, int on) goto exit; } - ret = pm_runtime_get_sync(dev); - if (ret < 0) { - pm_runtime_put_sync(dev); + ret = pm_runtime_resume_and_get(dev); + if (ret < 0) goto exit; - } ret = camss_enable_clocks(ispif->nclocks, ispif->clock, dev); if (ret < 0) { diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c index 1584ee77ad00..27ab20c5b57e 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe.c +++ b/drivers/media/platform/qcom/camss/camss-vfe.c @@ -584,9 +584,9 @@ static int vfe_get(struct vfe_device *vfe) if (ret < 0) goto error_pm_domain; - ret = pm_runtime_get_sync(vfe->camss->dev); + ret = pm_runtime_resume_and_get(vfe->camss->dev); if (ret < 0) - goto error_pm_runtime_get; + goto error_domain_off; ret = vfe_set_clock_rates(vfe); if (ret < 0) @@ -620,6 +620,7 @@ error_reset: error_pm_runtime_get: pm_runtime_put_sync(vfe->camss->dev); +error_domain_off: vfe->ops->pm_domain_off(vfe); error_pm_domain: From f6bf35ee3e4d9353c117bcc5cc4616d1ce2d977f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 5 May 2021 09:45:19 +0200 Subject: [PATCH 125/394] media: venus: core: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/venus/pm_helpers.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/platform/qcom/venus/pm_helpers.c b/drivers/media/platform/qcom/venus/pm_helpers.c index c7e1ebec47ee..d0fddf5e9a69 100644 --- a/drivers/media/platform/qcom/venus/pm_helpers.c +++ b/drivers/media/platform/qcom/venus/pm_helpers.c @@ -990,9 +990,8 @@ static int core_power_v4(struct venus_core *core, int on) if (on == POWER_ON) { if (pmctrl) { - ret = pm_runtime_get_sync(pmctrl); + ret = pm_runtime_resume_and_get(pmctrl); if (ret < 0) { - pm_runtime_put_noidle(pmctrl); return ret; } } From 1938ab0d271ffb6f0c9efa2873a53642167fe57c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:19 +0200 Subject: [PATCH 126/394] media: venus: vdec: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. As a bonus, there's no need to check if ret == 1, as pm_runtime_resume_and_get() always return 0 on success. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/venus/vdec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c index ddb7cd39424e..198e47eb63f4 100644 --- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -568,10 +568,10 @@ static int vdec_pm_get(struct venus_inst *inst) int ret; mutex_lock(&core->pm_lock); - ret = pm_runtime_get_sync(dev); + ret = pm_runtime_resume_and_get(dev); mutex_unlock(&core->pm_lock); - return ret < 0 ? ret : 0; + return ret; } static int vdec_pm_put(struct venus_inst *inst, bool autosuspend) @@ -601,7 +601,7 @@ static int vdec_pm_get_put(struct venus_inst *inst) mutex_lock(&core->pm_lock); if (pm_runtime_suspended(dev)) { - ret = pm_runtime_get_sync(dev); + ret = pm_runtime_resume_and_get(dev); if (ret < 0) goto error; From 85368a213e2dc0f4956e9d23daa39c4a339861e1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:19 +0200 Subject: [PATCH 127/394] media: venus: venc: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/venus/venc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c index 4a7291f934b6..8dd49d4f124c 100644 --- a/drivers/media/platform/qcom/venus/venc.c +++ b/drivers/media/platform/qcom/venus/venc.c @@ -1205,9 +1205,9 @@ static int venc_open(struct file *file) venus_helper_init_instance(inst); - ret = pm_runtime_get_sync(core->dev_enc); + ret = pm_runtime_resume_and_get(core->dev_enc); if (ret < 0) - goto err_put_sync; + goto err_free; ret = venc_ctrl_init(inst); if (ret) @@ -1252,6 +1252,7 @@ err_ctrl_deinit: venc_ctrl_deinit(inst); err_put_sync: pm_runtime_put_sync(core->dev_enc); +err_free: kfree(inst); return ret; } From c311f53362b05a82b47d1ed9dcfeb4637063b8d7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:19 +0200 Subject: [PATCH 128/394] media: rcar-fcp: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. As a bonus, pm_runtime_resume_and_get() always return 0 on success. So, the code can be simplified. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/rcar-fcp.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/media/platform/rcar-fcp.c b/drivers/media/platform/rcar-fcp.c index 5c03318ae07b..eb59a3ba6d0f 100644 --- a/drivers/media/platform/rcar-fcp.c +++ b/drivers/media/platform/rcar-fcp.c @@ -96,18 +96,10 @@ EXPORT_SYMBOL_GPL(rcar_fcp_get_device); */ int rcar_fcp_enable(struct rcar_fcp_device *fcp) { - int ret; - if (!fcp) return 0; - ret = pm_runtime_get_sync(fcp->dev); - if (ret < 0) { - pm_runtime_put_noidle(fcp->dev); - return ret; - } - - return 0; + return pm_runtime_resume_and_get(fcp->dev); } EXPORT_SYMBOL_GPL(rcar_fcp_enable); From 8102cf89ecd594572433ffb9103ce104ae57927e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:20 +0200 Subject: [PATCH 129/394] media: rkisp1: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c index 9643bdd05b7b..60cd2200e7ae 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c @@ -1003,9 +1003,8 @@ rkisp1_vb2_start_streaming(struct vb2_queue *queue, unsigned int count) if (ret) goto err_pipeline_stop; - ret = pm_runtime_get_sync(cap->rkisp1->dev); + ret = pm_runtime_resume_and_get(cap->rkisp1->dev); if (ret < 0) { - pm_runtime_put_noidle(cap->rkisp1->dev); dev_err(cap->rkisp1->dev, "power up failed %d\n", ret); goto err_destroy_dummy; } From a8779c2752f27f045f60bb191e257528374dc45c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:20 +0200 Subject: [PATCH 130/394] media: s3c-camif: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Reviewed-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s3c-camif/camif-capture.c | 2 +- drivers/media/platform/s3c-camif/camif-core.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c index 9ca49af29542..62241ec3b978 100644 --- a/drivers/media/platform/s3c-camif/camif-capture.c +++ b/drivers/media/platform/s3c-camif/camif-capture.c @@ -547,7 +547,7 @@ static int s3c_camif_open(struct file *file) if (ret < 0) goto unlock; - ret = pm_runtime_get_sync(camif->dev); + ret = pm_runtime_resume_and_get(camif->dev); if (ret < 0) goto err_pm; diff --git a/drivers/media/platform/s3c-camif/camif-core.c b/drivers/media/platform/s3c-camif/camif-core.c index 4c3c00d59c92..e1d51fd3e700 100644 --- a/drivers/media/platform/s3c-camif/camif-core.c +++ b/drivers/media/platform/s3c-camif/camif-core.c @@ -460,9 +460,9 @@ static int s3c_camif_probe(struct platform_device *pdev) pm_runtime_enable(dev); - ret = pm_runtime_get_sync(dev); + ret = pm_runtime_resume_and_get(dev); if (ret < 0) - goto err_pm; + goto err_disable; ret = camif_media_dev_init(camif); if (ret < 0) @@ -502,6 +502,7 @@ err_sens: camif_unregister_media_entities(camif); err_pm: pm_runtime_put(dev); +err_disable: pm_runtime_disable(dev); camif_clk_put(camif); err_clk: From 67b92f54186c0bf17038833cc376adaf133a4b6a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:20 +0200 Subject: [PATCH 131/394] media: s5p-mfc: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Reviewed-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc_pm.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c index 62d2320a7218..88b7d33c9197 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c @@ -78,11 +78,9 @@ int s5p_mfc_power_on(void) { int i, ret = 0; - ret = pm_runtime_get_sync(pm->device); - if (ret < 0) { - pm_runtime_put_noidle(pm->device); + ret = pm_runtime_resume_and_get(pm->device); + if (ret < 0) return ret; - } /* clock control */ for (i = 0; i < pm->num_clocks; i++) { From 75c573eb704178051637fdcd980e2850e0932080 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:21 +0200 Subject: [PATCH 132/394] media: stm32: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/stm32/stm32-dcmi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/stm32/stm32-dcmi.c b/drivers/media/platform/stm32/stm32-dcmi.c index d9b4ad0abf0c..b33c6e7ae0a1 100644 --- a/drivers/media/platform/stm32/stm32-dcmi.c +++ b/drivers/media/platform/stm32/stm32-dcmi.c @@ -723,11 +723,11 @@ static int dcmi_start_streaming(struct vb2_queue *vq, unsigned int count) u32 val = 0; int ret; - ret = pm_runtime_get_sync(dcmi->dev); + ret = pm_runtime_resume_and_get(dcmi->dev); if (ret < 0) { dev_err(dcmi->dev, "%s: Failed to start streaming, cannot get sync (%d)\n", __func__, ret); - goto err_pm_put; + goto err_unlocked; } ret = media_pipeline_start(&dcmi->vdev->entity, &dcmi->pipeline); @@ -848,6 +848,7 @@ err_media_pipeline_stop: err_pm_put: pm_runtime_put(dcmi->dev); +err_unlocked: spin_lock_irq(&dcmi->irqlock); /* * Return all buffers to vb2 in QUEUED state. From 79e790ff0bc5192f874cc587c462825556133d1c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:21 +0200 Subject: [PATCH 133/394] media: sunxi: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/sunxi/sun4i-csi/sun4i_v4l2.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/sunxi/sun4i-csi/sun4i_v4l2.c b/drivers/media/platform/sunxi/sun4i-csi/sun4i_v4l2.c index 4785faddf630..54b909987caa 100644 --- a/drivers/media/platform/sunxi/sun4i-csi/sun4i_v4l2.c +++ b/drivers/media/platform/sunxi/sun4i-csi/sun4i_v4l2.c @@ -206,9 +206,9 @@ static int sun4i_csi_open(struct file *file) if (ret) return ret; - ret = pm_runtime_get_sync(csi->dev); + ret = pm_runtime_resume_and_get(csi->dev); if (ret < 0) - goto err_pm_put; + goto err_unlock; ret = v4l2_pipeline_pm_get(&csi->vdev.entity); if (ret) @@ -227,6 +227,8 @@ err_pipeline_pm_put: err_pm_put: pm_runtime_put(csi->dev); + +err_unlock: mutex_unlock(&csi->lock); return ret; From 588bc430133c912f0ff39c375eae9baa81978d1e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:21 +0200 Subject: [PATCH 134/394] media: ti-vpe: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/ti-vpe/cal-video.c | 4 +++- drivers/media/platform/ti-vpe/cal.c | 8 +++++--- drivers/media/platform/ti-vpe/vpe.c | 8 +++----- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/media/platform/ti-vpe/cal-video.c b/drivers/media/platform/ti-vpe/cal-video.c index 7b7436a355ee..15fb5360cf13 100644 --- a/drivers/media/platform/ti-vpe/cal-video.c +++ b/drivers/media/platform/ti-vpe/cal-video.c @@ -700,7 +700,9 @@ static int cal_start_streaming(struct vb2_queue *vq, unsigned int count) addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0); - pm_runtime_get_sync(ctx->cal->dev); + ret = pm_runtime_resume_and_get(ctx->cal->dev); + if (ret < 0) + goto error_pipeline; cal_ctx_set_dma_addr(ctx, addr); cal_ctx_start(ctx); diff --git a/drivers/media/platform/ti-vpe/cal.c b/drivers/media/platform/ti-vpe/cal.c index 2e2bef91b2b0..76fe7a8b33f6 100644 --- a/drivers/media/platform/ti-vpe/cal.c +++ b/drivers/media/platform/ti-vpe/cal.c @@ -1024,7 +1024,7 @@ static int cal_probe(struct platform_device *pdev) /* Read the revision and hardware info to verify hardware access. */ pm_runtime_enable(&pdev->dev); - ret = pm_runtime_get_sync(&pdev->dev); + ret = pm_runtime_resume_and_get(&pdev->dev); if (ret) goto error_pm_runtime; @@ -1098,10 +1098,11 @@ static int cal_remove(struct platform_device *pdev) { struct cal_dev *cal = platform_get_drvdata(pdev); unsigned int i; + int ret; cal_dbg(1, cal, "Removing %s\n", CAL_MODULE_NAME); - pm_runtime_get_sync(&pdev->dev); + ret = pm_runtime_resume_and_get(&pdev->dev); cal_media_unregister(cal); @@ -1115,7 +1116,8 @@ static int cal_remove(struct platform_device *pdev) for (i = 0; i < cal->data->num_csi2_phy; i++) cal_camerarx_destroy(cal->phy[i]); - pm_runtime_put_sync(&pdev->dev); + if (ret >= 0) + pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); return 0; diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c index 10251b787674..5b1c5d96a407 100644 --- a/drivers/media/platform/ti-vpe/vpe.c +++ b/drivers/media/platform/ti-vpe/vpe.c @@ -2471,11 +2471,9 @@ static int vpe_runtime_get(struct platform_device *pdev) dev_dbg(&pdev->dev, "vpe_runtime_get\n"); - r = pm_runtime_get_sync(&pdev->dev); + r = pm_runtime_resume_and_get(&pdev->dev); WARN_ON(r < 0); - if (r) - pm_runtime_put_noidle(&pdev->dev); - return r < 0 ? r : 0; + return r; } static void vpe_runtime_put(struct platform_device *pdev) @@ -2580,7 +2578,7 @@ static int vpe_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); ret = vpe_runtime_get(pdev); - if (ret) + if (ret < 0) goto rel_m2m; /* Perform clk enable followed by reset */ From 71aeaedc968343c644b3c073b715b24b909ef088 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:21 +0200 Subject: [PATCH 135/394] media: vsp1: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. As a bonus, pm_runtime_resume_and_get() always return 0 on success. So, the code can be simplified. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vsp1/vsp1_drv.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c index aa66e4f5f3f3..de442d6c9926 100644 --- a/drivers/media/platform/vsp1/vsp1_drv.c +++ b/drivers/media/platform/vsp1/vsp1_drv.c @@ -559,15 +559,7 @@ static int vsp1_device_init(struct vsp1_device *vsp1) */ int vsp1_device_get(struct vsp1_device *vsp1) { - int ret; - - ret = pm_runtime_get_sync(vsp1->dev); - if (ret < 0) { - pm_runtime_put_noidle(vsp1->dev); - return ret; - } - - return 0; + return pm_runtime_resume_and_get(vsp1->dev); } /* From 334fe327a8b4fdebea14af478f7f6185d45e566b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 23 Apr 2021 17:19:20 +0200 Subject: [PATCH 136/394] media: rcar-vin: use pm_runtime_resume_and_get() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. Use the new API, in order to cleanup the error check logic. Reviewed-by: Niklas Söderlund Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/rcar-vin/rcar-csi2.c | 15 ++++++++++++--- drivers/media/platform/rcar-vin/rcar-dma.c | 6 ++---- drivers/media/platform/rcar-vin/rcar-v4l2.c | 6 ++---- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c b/drivers/media/platform/rcar-vin/rcar-csi2.c index e06cd512aba2..99bf814eb2a7 100644 --- a/drivers/media/platform/rcar-vin/rcar-csi2.c +++ b/drivers/media/platform/rcar-vin/rcar-csi2.c @@ -406,10 +406,17 @@ static void rcsi2_enter_standby(struct rcar_csi2 *priv) pm_runtime_put(priv->dev); } -static void rcsi2_exit_standby(struct rcar_csi2 *priv) +static int rcsi2_exit_standby(struct rcar_csi2 *priv) { - pm_runtime_get_sync(priv->dev); + int ret; + + ret = pm_runtime_resume_and_get(priv->dev); + if (ret < 0) + return ret; + reset_control_deassert(priv->rstc); + + return 0; } static int rcsi2_wait_phy_start(struct rcar_csi2 *priv, @@ -657,7 +664,9 @@ static int rcsi2_start(struct rcar_csi2 *priv) { int ret; - rcsi2_exit_standby(priv); + ret = rcsi2_exit_standby(priv); + if (ret < 0) + return ret; ret = rcsi2_start_receiver(priv); if (ret) { diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index f30dafbdf61c..f5f722ab1d4e 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -1458,11 +1458,9 @@ int rvin_set_channel_routing(struct rvin_dev *vin, u8 chsel) u32 vnmc; int ret; - ret = pm_runtime_get_sync(vin->dev); - if (ret < 0) { - pm_runtime_put_noidle(vin->dev); + ret = pm_runtime_resume_and_get(vin->dev); + if (ret < 0) return ret; - } /* Make register writes take effect immediately. */ vnmc = rvin_read(vin, VNMC_REG); diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index 457a65bf6b66..b1e9f86caa5c 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -870,11 +870,9 @@ static int rvin_open(struct file *file) struct rvin_dev *vin = video_drvdata(file); int ret; - ret = pm_runtime_get_sync(vin->dev); - if (ret < 0) { - pm_runtime_put_noidle(vin->dev); + ret = pm_runtime_resume_and_get(vin->dev); + if (ret < 0) return ret; - } ret = mutex_lock_interruptible(&vin->lock); if (ret) From 10f05966c52052c06ec4303ffc2f8185df713784 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 26 Apr 2021 14:26:43 +0200 Subject: [PATCH 137/394] media: hantro: use pm_runtime_resume_and_get() Commit dd8088d5a896 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter") added pm_runtime_resume_and_get() in order to automatically handle dev->power.usage_count decrement on errors. While there's nothing wrong with the current usage on this driver, as we're getting rid of the pm_runtime_get_sync() call all over the media subsystem, let's remove the last occurrence on this driver. Reviewed-by: Ezequiel Garcia Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/hantro/hantro_drv.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c index 85dcb0882afc..074b9bb30d6d 100644 --- a/drivers/staging/media/hantro/hantro_drv.c +++ b/drivers/staging/media/hantro/hantro_drv.c @@ -160,11 +160,9 @@ static void device_run(void *priv) src = hantro_get_src_buf(ctx); dst = hantro_get_dst_buf(ctx); - ret = pm_runtime_get_sync(ctx->dev->dev); - if (ret < 0) { - pm_runtime_put_noidle(ctx->dev->dev); + ret = pm_runtime_resume_and_get(ctx->dev->dev); + if (ret < 0) goto err_cancel_job; - } ret = clk_bulk_enable(ctx->dev->variant->num_clocks, ctx->dev->clocks); if (ret) From 89cf71e62cd39da12e7a6e36ae6db126391ca9e2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 20 May 2021 16:05:45 +0200 Subject: [PATCH 138/394] media: davinci: fix two kernel-doc comments A typo there is causing two warnings: drivers/media/platform/davinci/vpif_display.c:114: warning: Function parameter or member 'nplanes' not described in 'vpif_buffer_queue_setup' drivers/media/platform/davinci/vpif_capture.c:112: warning: Function parameter or member 'nplanes' not described in 'vpif_buffer_queue_setup' Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpif_capture.c | 2 +- drivers/media/platform/davinci/vpif_display.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c index 8d2e165bf7de..c034e25dd9aa 100644 --- a/drivers/media/platform/davinci/vpif_capture.c +++ b/drivers/media/platform/davinci/vpif_capture.c @@ -99,7 +99,7 @@ static int vpif_buffer_prepare(struct vb2_buffer *vb) * vpif_buffer_queue_setup : Callback function for buffer setup. * @vq: vb2_queue ptr * @nbuffers: ptr to number of buffers requested by application - * @nplanes:: contains number of distinct video planes needed to hold a frame + * @nplanes: contains number of distinct video planes needed to hold a frame * @sizes: contains the size (in bytes) of each plane. * @alloc_devs: ptr to allocation context * diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c index e5f61d9b221d..59f6b782e104 100644 --- a/drivers/media/platform/davinci/vpif_display.c +++ b/drivers/media/platform/davinci/vpif_display.c @@ -101,7 +101,7 @@ static int vpif_buffer_prepare(struct vb2_buffer *vb) * vpif_buffer_queue_setup : Callback function for buffer setup. * @vq: vb2_queue ptr * @nbuffers: ptr to number of buffers requested by application - * @nplanes:: contains number of distinct video planes needed to hold a frame + * @nplanes: contains number of distinct video planes needed to hold a frame * @sizes: contains the size (in bytes) of each plane. * @alloc_devs: ptr to allocation context * From 12ccb76280f8c0c07794fa68f83286b934981ca5 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Tue, 13 Apr 2021 11:40:17 +0200 Subject: [PATCH 139/394] media: lirc: remove out of date comment This file has been updated many times since 2010. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/lirc.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/uapi/linux/lirc.h b/include/uapi/linux/lirc.h index c45a4eaea667..9919f2062b14 100644 --- a/include/uapi/linux/lirc.h +++ b/include/uapi/linux/lirc.h @@ -1,7 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * lirc.h - linux infrared remote control header file - * last modified 2010/07/13 by Jarod Wilson */ #ifndef _LINUX_LIRC_H From 58c08df5751d823332ccdb49f1d5795479097119 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 21 Apr 2021 15:58:40 +0200 Subject: [PATCH 140/394] media: rc: remove tango ir driver and keymap The tango platform was removed, so the driver is no longer needed. Cc: Marc Gonzalez Acked-by: Rob Herring Acked-by: Mans Rullgard Signed-off-by: Arnd Bergmann Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- .../devicetree/bindings/media/rc.yaml | 1 - .../devicetree/bindings/media/tango-ir.txt | 21 -- drivers/media/rc/Kconfig | 10 - drivers/media/rc/Makefile | 1 - drivers/media/rc/keymaps/Makefile | 1 - drivers/media/rc/keymaps/rc-tango.c | 89 ------ drivers/media/rc/tango-ir.c | 267 ------------------ include/media/rc-map.h | 1 - 8 files changed, 391 deletions(-) delete mode 100644 Documentation/devicetree/bindings/media/tango-ir.txt delete mode 100644 drivers/media/rc/keymaps/rc-tango.c delete mode 100644 drivers/media/rc/tango-ir.c diff --git a/Documentation/devicetree/bindings/media/rc.yaml b/Documentation/devicetree/bindings/media/rc.yaml index af9e7e59e5a1..12d838b05632 100644 --- a/Documentation/devicetree/bindings/media/rc.yaml +++ b/Documentation/devicetree/bindings/media/rc.yaml @@ -125,7 +125,6 @@ properties: - rc-snapstream-firefly - rc-streamzap - rc-su3000 - - rc-tango - rc-tanix-tx3mini - rc-tanix-tx5max - rc-tbs-nec diff --git a/Documentation/devicetree/bindings/media/tango-ir.txt b/Documentation/devicetree/bindings/media/tango-ir.txt deleted file mode 100644 index a9f00c2bf897..000000000000 --- a/Documentation/devicetree/bindings/media/tango-ir.txt +++ /dev/null @@ -1,21 +0,0 @@ -Sigma Designs Tango IR NEC/RC-5/RC-6 decoder (SMP86xx and SMP87xx) - -Required properties: - -- compatible: "sigma,smp8642-ir" -- reg: address/size of NEC+RC5 area, address/size of RC6 area -- interrupts: spec for IR IRQ -- clocks: spec for IR clock (typically the crystal oscillator) - -Optional properties: - -- linux,rc-map-name: see Documentation/devicetree/bindings/media/rc.txt - -Example: - - ir@10518 { - compatible = "sigma,smp8642-ir"; - reg = <0x10518 0x18>, <0x105e0 0x1c>; - interrupts = <21 IRQ_TYPE_EDGE_RISING>; - clocks = <&xtal>; - }; diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index f016b35c2b17..ae0025fba21c 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig @@ -499,16 +499,6 @@ config IR_SIR To compile this driver as a module, choose M here: the module will be called sir-ir. -config IR_TANGO - tristate "Sigma Designs SMP86xx IR decoder" - depends on RC_CORE - depends on ARCH_TANGO || COMPILE_TEST - help - Adds support for the HW IR decoder embedded on Sigma Designs - Tango-based systems (SMP86xx, SMP87xx). - The HW decoder supports NEC, RC-5, RC-6 IR protocols. - When compiled as a module, look for tango-ir. - config RC_XBOX_DVD tristate "Xbox DVD Movie Playback Kit" depends on RC_CORE diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile index f31002288f7c..692e9b6b203f 100644 --- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile @@ -48,6 +48,5 @@ obj-$(CONFIG_IR_IMG) += img-ir/ obj-$(CONFIG_IR_SERIAL) += serial_ir.o obj-$(CONFIG_IR_SIR) += sir_ir.o obj-$(CONFIG_IR_MTK) += mtk-cir.o -obj-$(CONFIG_IR_TANGO) += tango-ir.o obj-$(CONFIG_RC_XBOX_DVD) += xbox_remote.o obj-$(CONFIG_IR_TOY) += ir_toy.o diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile index 50b2833dbe4f..f609dfe7fd76 100644 --- a/drivers/media/rc/keymaps/Makefile +++ b/drivers/media/rc/keymaps/Makefile @@ -100,7 +100,6 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ rc-reddo.o \ rc-snapstream-firefly.o \ rc-streamzap.o \ - rc-tango.o \ rc-tanix-tx3mini.o \ rc-tanix-tx5max.o \ rc-tbs-nec.o \ diff --git a/drivers/media/rc/keymaps/rc-tango.c b/drivers/media/rc/keymaps/rc-tango.c deleted file mode 100644 index 2b9cef6ef5b5..000000000000 --- a/drivers/media/rc/keymaps/rc-tango.c +++ /dev/null @@ -1,89 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2017 Sigma Designs - */ - -#include -#include - -static struct rc_map_table tango_table[] = { - { 0x4cb4a, KEY_POWER }, - { 0x4cb48, KEY_FILE }, - { 0x4cb0f, KEY_SETUP }, - { 0x4cb4d, KEY_SUSPEND }, - { 0x4cb4e, KEY_VOLUMEUP }, - { 0x4cb44, KEY_EJECTCD }, - { 0x4cb13, KEY_TV }, - { 0x4cb51, KEY_MUTE }, - { 0x4cb52, KEY_VOLUMEDOWN }, - - { 0x4cb41, KEY_NUMERIC_1 }, - { 0x4cb03, KEY_NUMERIC_2 }, - { 0x4cb42, KEY_NUMERIC_3 }, - { 0x4cb45, KEY_NUMERIC_4 }, - { 0x4cb07, KEY_NUMERIC_5 }, - { 0x4cb46, KEY_NUMERIC_6 }, - { 0x4cb55, KEY_NUMERIC_7 }, - { 0x4cb17, KEY_NUMERIC_8 }, - { 0x4cb56, KEY_NUMERIC_9 }, - { 0x4cb1b, KEY_NUMERIC_0 }, - { 0x4cb59, KEY_DELETE }, - { 0x4cb5a, KEY_CAPSLOCK }, - - { 0x4cb47, KEY_BACK }, - { 0x4cb05, KEY_SWITCHVIDEOMODE }, - { 0x4cb06, KEY_UP }, - { 0x4cb43, KEY_LEFT }, - { 0x4cb01, KEY_RIGHT }, - { 0x4cb0a, KEY_DOWN }, - { 0x4cb02, KEY_ENTER }, - { 0x4cb4b, KEY_INFO }, - { 0x4cb09, KEY_HOME }, - - { 0x4cb53, KEY_MENU }, - { 0x4cb12, KEY_PREVIOUS }, - { 0x4cb50, KEY_PLAY }, - { 0x4cb11, KEY_NEXT }, - { 0x4cb4f, KEY_TITLE }, - { 0x4cb0e, KEY_REWIND }, - { 0x4cb4c, KEY_STOP }, - { 0x4cb0d, KEY_FORWARD }, - { 0x4cb57, KEY_MEDIA_REPEAT }, - { 0x4cb16, KEY_ANGLE }, - { 0x4cb54, KEY_PAUSE }, - { 0x4cb15, KEY_SLOW }, - { 0x4cb5b, KEY_TIME }, - { 0x4cb1a, KEY_AUDIO }, - { 0x4cb58, KEY_SUBTITLE }, - { 0x4cb19, KEY_ZOOM }, - - { 0x4cb5f, KEY_RED }, - { 0x4cb1e, KEY_GREEN }, - { 0x4cb5c, KEY_YELLOW }, - { 0x4cb1d, KEY_BLUE }, -}; - -static struct rc_map_list tango_map = { - .map = { - .scan = tango_table, - .size = ARRAY_SIZE(tango_table), - .rc_proto = RC_PROTO_NECX, - .name = RC_MAP_TANGO, - } -}; - -static int __init init_rc_map_tango(void) -{ - return rc_map_register(&tango_map); -} - -static void __exit exit_rc_map_tango(void) -{ - rc_map_unregister(&tango_map); -} - -module_init(init_rc_map_tango) -module_exit(exit_rc_map_tango) - -MODULE_AUTHOR("Sigma Designs"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/rc/tango-ir.c b/drivers/media/rc/tango-ir.c deleted file mode 100644 index b8eb5bc4d9be..000000000000 --- a/drivers/media/rc/tango-ir.c +++ /dev/null @@ -1,267 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2015 Mans Rullgard - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define DRIVER_NAME "tango-ir" - -#define IR_NEC_CTRL 0x00 -#define IR_NEC_DATA 0x04 -#define IR_CTRL 0x08 -#define IR_RC5_CLK_DIV 0x0c -#define IR_RC5_DATA 0x10 -#define IR_INT 0x14 - -#define NEC_TIME_BASE 560 -#define RC5_TIME_BASE 1778 - -#define RC6_CTRL 0x00 -#define RC6_CLKDIV 0x04 -#define RC6_DATA0 0x08 -#define RC6_DATA1 0x0c -#define RC6_DATA2 0x10 -#define RC6_DATA3 0x14 -#define RC6_DATA4 0x18 - -#define RC6_CARRIER 36000 -#define RC6_TIME_BASE 16 - -#define NEC_CAP(n) ((n) << 24) -#define GPIO_SEL(n) ((n) << 16) -#define DISABLE_NEC (BIT(4) | BIT(8)) -#define ENABLE_RC5 (BIT(0) | BIT(9)) -#define ENABLE_RC6 (BIT(0) | BIT(7)) -#define ACK_IR_INT (BIT(0) | BIT(1)) -#define ACK_RC6_INT (BIT(31)) - -#define NEC_ANY (RC_PROTO_BIT_NEC | RC_PROTO_BIT_NECX | RC_PROTO_BIT_NEC32) - -struct tango_ir { - void __iomem *rc5_base; - void __iomem *rc6_base; - struct rc_dev *rc; - struct clk *clk; -}; - -static void tango_ir_handle_nec(struct tango_ir *ir) -{ - u32 v, code; - enum rc_proto proto; - - v = readl_relaxed(ir->rc5_base + IR_NEC_DATA); - if (!v) { - rc_repeat(ir->rc); - return; - } - - code = ir_nec_bytes_to_scancode(v, v >> 8, v >> 16, v >> 24, &proto); - rc_keydown(ir->rc, proto, code, 0); -} - -static void tango_ir_handle_rc5(struct tango_ir *ir) -{ - u32 data, field, toggle, addr, cmd, code; - - data = readl_relaxed(ir->rc5_base + IR_RC5_DATA); - if (data & BIT(31)) - return; - - field = data >> 12 & 1; - toggle = data >> 11 & 1; - addr = data >> 6 & 0x1f; - cmd = (data & 0x3f) | (field ^ 1) << 6; - - code = RC_SCANCODE_RC5(addr, cmd); - rc_keydown(ir->rc, RC_PROTO_RC5, code, toggle); -} - -static void tango_ir_handle_rc6(struct tango_ir *ir) -{ - u32 data0, data1, toggle, mode, addr, cmd, code; - - data0 = readl_relaxed(ir->rc6_base + RC6_DATA0); - data1 = readl_relaxed(ir->rc6_base + RC6_DATA1); - - mode = data0 >> 1 & 7; - if (mode != 0) - return; - - toggle = data0 & 1; - addr = data0 >> 16; - cmd = data1; - - code = RC_SCANCODE_RC6_0(addr, cmd); - rc_keydown(ir->rc, RC_PROTO_RC6_0, code, toggle); -} - -static irqreturn_t tango_ir_irq(int irq, void *dev_id) -{ - struct tango_ir *ir = dev_id; - unsigned int rc5_stat; - unsigned int rc6_stat; - - rc5_stat = readl_relaxed(ir->rc5_base + IR_INT); - writel_relaxed(rc5_stat, ir->rc5_base + IR_INT); - - rc6_stat = readl_relaxed(ir->rc6_base + RC6_CTRL); - writel_relaxed(rc6_stat, ir->rc6_base + RC6_CTRL); - - if (!(rc5_stat & 3) && !(rc6_stat & BIT(31))) - return IRQ_NONE; - - if (rc5_stat & BIT(0)) - tango_ir_handle_rc5(ir); - - if (rc5_stat & BIT(1)) - tango_ir_handle_nec(ir); - - if (rc6_stat & BIT(31)) - tango_ir_handle_rc6(ir); - - return IRQ_HANDLED; -} - -static int tango_change_protocol(struct rc_dev *dev, u64 *rc_type) -{ - struct tango_ir *ir = dev->priv; - u32 rc5_ctrl = DISABLE_NEC; - u32 rc6_ctrl = 0; - - if (*rc_type & NEC_ANY) - rc5_ctrl = 0; - - if (*rc_type & RC_PROTO_BIT_RC5) - rc5_ctrl |= ENABLE_RC5; - - if (*rc_type & RC_PROTO_BIT_RC6_0) - rc6_ctrl = ENABLE_RC6; - - writel_relaxed(rc5_ctrl, ir->rc5_base + IR_CTRL); - writel_relaxed(rc6_ctrl, ir->rc6_base + RC6_CTRL); - - return 0; -} - -static int tango_ir_probe(struct platform_device *pdev) -{ - const char *map_name = RC_MAP_TANGO; - struct device *dev = &pdev->dev; - struct rc_dev *rc; - struct tango_ir *ir; - u64 clkrate, clkdiv; - int irq, err; - u32 val; - - irq = platform_get_irq(pdev, 0); - if (irq <= 0) - return -EINVAL; - - ir = devm_kzalloc(dev, sizeof(*ir), GFP_KERNEL); - if (!ir) - return -ENOMEM; - - ir->rc5_base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(ir->rc5_base)) - return PTR_ERR(ir->rc5_base); - - ir->rc6_base = devm_platform_ioremap_resource(pdev, 1); - if (IS_ERR(ir->rc6_base)) - return PTR_ERR(ir->rc6_base); - - ir->clk = devm_clk_get(dev, NULL); - if (IS_ERR(ir->clk)) - return PTR_ERR(ir->clk); - - rc = devm_rc_allocate_device(dev, RC_DRIVER_SCANCODE); - if (!rc) - return -ENOMEM; - - of_property_read_string(dev->of_node, "linux,rc-map-name", &map_name); - - rc->device_name = DRIVER_NAME; - rc->driver_name = DRIVER_NAME; - rc->input_phys = DRIVER_NAME "/input0"; - rc->map_name = map_name; - rc->allowed_protocols = NEC_ANY | RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC6_0; - rc->change_protocol = tango_change_protocol; - rc->priv = ir; - ir->rc = rc; - - err = clk_prepare_enable(ir->clk); - if (err) - return err; - - clkrate = clk_get_rate(ir->clk); - - clkdiv = clkrate * NEC_TIME_BASE; - do_div(clkdiv, 1000000); - - val = NEC_CAP(31) | GPIO_SEL(12) | clkdiv; - writel_relaxed(val, ir->rc5_base + IR_NEC_CTRL); - - clkdiv = clkrate * RC5_TIME_BASE; - do_div(clkdiv, 1000000); - - writel_relaxed(DISABLE_NEC, ir->rc5_base + IR_CTRL); - writel_relaxed(clkdiv, ir->rc5_base + IR_RC5_CLK_DIV); - writel_relaxed(ACK_IR_INT, ir->rc5_base + IR_INT); - - clkdiv = clkrate * RC6_TIME_BASE; - do_div(clkdiv, RC6_CARRIER); - - writel_relaxed(ACK_RC6_INT, ir->rc6_base + RC6_CTRL); - writel_relaxed((clkdiv >> 2) << 18 | clkdiv, ir->rc6_base + RC6_CLKDIV); - - err = devm_request_irq(dev, irq, tango_ir_irq, IRQF_SHARED, - dev_name(dev), ir); - if (err) - goto err_clk; - - err = devm_rc_register_device(dev, rc); - if (err) - goto err_clk; - - platform_set_drvdata(pdev, ir); - return 0; - -err_clk: - clk_disable_unprepare(ir->clk); - return err; -} - -static int tango_ir_remove(struct platform_device *pdev) -{ - struct tango_ir *ir = platform_get_drvdata(pdev); - - clk_disable_unprepare(ir->clk); - return 0; -} - -static const struct of_device_id tango_ir_dt_ids[] = { - { .compatible = "sigma,smp8642-ir" }, - { } -}; -MODULE_DEVICE_TABLE(of, tango_ir_dt_ids); - -static struct platform_driver tango_ir_driver = { - .probe = tango_ir_probe, - .remove = tango_ir_remove, - .driver = { - .name = DRIVER_NAME, - .of_match_table = tango_ir_dt_ids, - }, -}; -module_platform_driver(tango_ir_driver); - -MODULE_DESCRIPTION("SMP86xx IR decoder driver"); -MODULE_AUTHOR("Mans Rullgard "); -MODULE_LICENSE("GPL"); diff --git a/include/media/rc-map.h b/include/media/rc-map.h index b5585d14fff4..b50443d6fd77 100644 --- a/include/media/rc-map.h +++ b/include/media/rc-map.h @@ -312,7 +312,6 @@ struct rc_map *rc_map_get(const char *name); #define RC_MAP_SNAPSTREAM_FIREFLY "rc-snapstream-firefly" #define RC_MAP_STREAMZAP "rc-streamzap" #define RC_MAP_SU3000 "rc-su3000" -#define RC_MAP_TANGO "rc-tango" #define RC_MAP_TANIX_TX3MINI "rc-tanix-tx3mini" #define RC_MAP_TANIX_TX5MAX "rc-tanix-tx5max" #define RC_MAP_TBS_NEC "rc-tbs-nec" From 52518e513d6dbb71a9cd8f7a1b83b76fe6f8709c Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 21 Apr 2021 15:58:41 +0200 Subject: [PATCH 141/394] media: rc: clean up Kconfig dependencies I came across a randconfig build failure from one driver that only depends on CONFIG_USB_ARCH_HAS_HCD but fails when built without CONFIG_USB: ld: drivers/media/rc/ir_toy.o: in function `irtoy_disconnect': ir_toy.c:(.text+0x24): undefined reference to `usb_kill_urb' ld: ir_toy.c:(.text+0x2c): undefined reference to `usb_free_urb' ld: ir_toy.c:(.text+0x34): undefined reference to `usb_kill_urb' ld: ir_toy.c:(.text+0x3c): undefined reference to `usb_free_urb' Upon a closer look, I find that a lot of the other drivers 'select USB' rather than stating 'depends on USB' as is common for most subsystems. I also find that all except one driver have an extra 'depends on RC_CORE' that is already implied by the top-level 'if RC_CORE' check. Clean up both by reducing the dependencies to the required set. Signed-off-by: Arnd Bergmann Acked-by: Randy Dunlap Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/Kconfig | 73 ++++++---------------------------------- 1 file changed, 11 insertions(+), 62 deletions(-) diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index ae0025fba21c..d0a8326b75c2 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig @@ -19,7 +19,6 @@ source "drivers/media/rc/keymaps/Kconfig" config LIRC bool "LIRC user interface" - depends on RC_CORE help Enable this option to enable the Linux Infrared Remote Control user interface (e.g. /dev/lirc*). This interface @@ -41,12 +40,10 @@ config BPF_LIRC_MODE2 menuconfig RC_DECODERS bool "Remote controller decoders" - depends on RC_CORE if RC_DECODERS config IR_NEC_DECODER tristate "Enable IR raw decoder for the NEC protocol" - depends on RC_CORE select BITREVERSE help @@ -55,7 +52,6 @@ config IR_NEC_DECODER config IR_RC5_DECODER tristate "Enable IR raw decoder for the RC-5 protocol" - depends on RC_CORE select BITREVERSE help @@ -64,7 +60,6 @@ config IR_RC5_DECODER config IR_RC6_DECODER tristate "Enable IR raw decoder for the RC6 protocol" - depends on RC_CORE select BITREVERSE help @@ -73,7 +68,6 @@ config IR_RC6_DECODER config IR_JVC_DECODER tristate "Enable IR raw decoder for the JVC protocol" - depends on RC_CORE select BITREVERSE help @@ -82,7 +76,6 @@ config IR_JVC_DECODER config IR_SONY_DECODER tristate "Enable IR raw decoder for the Sony protocol" - depends on RC_CORE select BITREVERSE help @@ -91,7 +84,6 @@ config IR_SONY_DECODER config IR_SANYO_DECODER tristate "Enable IR raw decoder for the Sanyo protocol" - depends on RC_CORE select BITREVERSE help @@ -101,7 +93,6 @@ config IR_SANYO_DECODER config IR_SHARP_DECODER tristate "Enable IR raw decoder for the Sharp protocol" - depends on RC_CORE select BITREVERSE help @@ -111,7 +102,6 @@ config IR_SHARP_DECODER config IR_MCE_KBD_DECODER tristate "Enable IR raw decoder for the MCE keyboard/mouse protocol" - depends on RC_CORE select BITREVERSE help @@ -121,7 +111,6 @@ config IR_MCE_KBD_DECODER config IR_XMP_DECODER tristate "Enable IR raw decoder for the XMP protocol" - depends on RC_CORE select BITREVERSE help @@ -130,7 +119,6 @@ config IR_XMP_DECODER config IR_IMON_DECODER tristate "Enable IR raw decoder for the iMON protocol" - depends on RC_CORE help Enable this option if you have iMON PAD or Antec Veris infrared remote control and you would like to use it with a raw IR @@ -138,7 +126,6 @@ config IR_IMON_DECODER config IR_RCMM_DECODER tristate "Enable IR raw decoder for the RC-MM protocol" - depends on RC_CORE help Enable this option when you have IR with RC-MM protocol, and you need the software decoder. The driver supports 12, @@ -153,15 +140,12 @@ endif #RC_DECODERS menuconfig RC_DEVICES bool "Remote Controller devices" - depends on RC_CORE if RC_DEVICES config RC_ATI_REMOTE tristate "ATI / X10 based USB RF remote controls" - depends on USB_ARCH_HAS_HCD - depends on RC_CORE - select USB + depends on USB help Say Y here if you want to use an X10 based USB remote control. These are RF remotes with USB receivers. @@ -179,7 +163,6 @@ config RC_ATI_REMOTE config IR_ENE tristate "ENE eHome Receiver/Transceiver (pnp id: ENE0100/ENE02xxx)" depends on PNP || COMPILE_TEST - depends on RC_CORE help Say Y here to enable support for integrated infrared receiver /transceiver made by ENE. @@ -192,7 +175,6 @@ config IR_ENE config IR_HIX5HD2 tristate "Hisilicon hix5hd2 IR remote control" - depends on RC_CORE depends on OF || COMPILE_TEST help Say Y here if you want to use hisilicon hix5hd2 remote control. @@ -203,9 +185,7 @@ config IR_HIX5HD2 config IR_IMON tristate "SoundGraph iMON Receiver and Display" - depends on USB_ARCH_HAS_HCD - depends on RC_CORE - select USB + depends on USB help Say Y here if you want to use a SoundGraph iMON (aka Antec Veris) IR Receiver and/or LCD/VFD/VGA display. @@ -215,9 +195,7 @@ config IR_IMON config IR_IMON_RAW tristate "SoundGraph iMON Receiver (early raw IR models)" - depends on USB_ARCH_HAS_HCD - depends on RC_CORE - select USB + depends on USB help Say Y here if you want to use a SoundGraph iMON IR Receiver, early raw models. @@ -227,9 +205,7 @@ config IR_IMON_RAW config IR_MCEUSB tristate "Windows Media Center Ed. eHome Infrared Transceiver" - depends on USB_ARCH_HAS_HCD - depends on RC_CORE - select USB + depends on USB help Say Y here if you want to use a Windows Media Center Edition eHome Infrared Transceiver. @@ -240,7 +216,6 @@ config IR_MCEUSB config IR_ITE_CIR tristate "ITE Tech Inc. IT8712/IT8512 Consumer Infrared Transceiver" depends on PNP || COMPILE_TEST - depends on RC_CORE help Say Y here to enable support for integrated infrared receivers /transceivers made by ITE Tech Inc. These are found in @@ -253,7 +228,6 @@ config IR_ITE_CIR config IR_FINTEK tristate "Fintek Consumer Infrared Transceiver" depends on PNP || COMPILE_TEST - depends on RC_CORE help Say Y here to enable support for integrated infrared receiver /transceiver made by Fintek. This chip is found on assorted @@ -264,7 +238,6 @@ config IR_FINTEK config IR_MESON tristate "Amlogic Meson IR remote receiver" - depends on RC_CORE depends on ARCH_MESON || COMPILE_TEST help Say Y if you want to use the IR remote receiver available @@ -275,7 +248,6 @@ config IR_MESON config IR_MTK tristate "Mediatek IR remote receiver" - depends on RC_CORE depends on ARCH_MEDIATEK || COMPILE_TEST help Say Y if you want to use the IR remote receiver available @@ -287,7 +259,6 @@ config IR_MTK config IR_NUVOTON tristate "Nuvoton w836x7hg Consumer Infrared Transceiver" depends on PNP || COMPILE_TEST - depends on RC_CORE help Say Y here to enable support for integrated infrared receiver /transceiver made by Nuvoton (formerly Winbond). This chip is @@ -299,11 +270,9 @@ config IR_NUVOTON config IR_REDRAT3 tristate "RedRat3 IR Transceiver" - depends on USB_ARCH_HAS_HCD - depends on RC_CORE + depends on USB select NEW_LEDS select LEDS_CLASS - select USB help Say Y here if you want to use a RedRat3 Infrared Transceiver. @@ -322,9 +291,7 @@ config IR_SPI config IR_STREAMZAP tristate "Streamzap PC Remote IR Receiver" - depends on USB_ARCH_HAS_HCD - depends on RC_CORE - select USB + depends on USB help Say Y here if you want to use a Streamzap PC Remote Infrared Receiver. @@ -335,7 +302,6 @@ config IR_STREAMZAP config IR_WINBOND_CIR tristate "Winbond IR remote control" depends on (X86 && PNP) || COMPILE_TEST - depends on RC_CORE select NEW_LEDS select LEDS_CLASS select BITREVERSE @@ -350,9 +316,7 @@ config IR_WINBOND_CIR config IR_IGORPLUGUSB tristate "IgorPlug-USB IR Receiver" - depends on USB_ARCH_HAS_HCD - depends on RC_CORE - select USB + depends on USB help Say Y here if you want to use the IgorPlug-USB IR Receiver by Igor Cesko. This device is included on the Fit-PC2. @@ -365,9 +329,7 @@ config IR_IGORPLUGUSB config IR_IGUANA tristate "IguanaWorks USB IR Transceiver" - depends on USB_ARCH_HAS_HCD - depends on RC_CORE - select USB + depends on USB help Say Y here if you want to use the IguanaWorks USB IR Transceiver. Both infrared receive and send are supported. If you want to @@ -381,9 +343,7 @@ config IR_IGUANA config IR_TTUSBIR tristate "TechnoTrend USB IR Receiver" - depends on USB_ARCH_HAS_HCD - depends on RC_CORE - select USB + depends on USB select NEW_LEDS select LEDS_CLASS help @@ -407,7 +367,6 @@ source "drivers/media/rc/img-ir/Kconfig" config RC_LOOPBACK tristate "Remote Control Loopback Driver" - depends on RC_CORE help Say Y here if you want support for the remote control loopback driver which allows TX data to be sent back as RX data. @@ -420,7 +379,6 @@ config RC_LOOPBACK config IR_GPIO_CIR tristate "GPIO IR remote control" - depends on RC_CORE depends on (OF && GPIOLIB) || COMPILE_TEST help Say Y if you want to use GPIO based IR Receiver. @@ -430,7 +388,6 @@ config IR_GPIO_CIR config IR_GPIO_TX tristate "GPIO IR Bit Banging Transmitter" - depends on RC_CORE depends on LIRC depends on (OF && GPIOLIB) || COMPILE_TEST help @@ -442,7 +399,6 @@ config IR_GPIO_TX config IR_PWM_TX tristate "PWM IR transmitter" - depends on RC_CORE depends on LIRC depends on PWM depends on OF || COMPILE_TEST @@ -455,7 +411,6 @@ config IR_PWM_TX config RC_ST tristate "ST remote control receiver" - depends on RC_CORE depends on ARCH_STI || COMPILE_TEST help Say Y here if you want support for ST remote control driver @@ -466,7 +421,6 @@ config RC_ST config IR_SUNXI tristate "SUNXI IR remote control" - depends on RC_CORE depends on ARCH_SUNXI || COMPILE_TEST help Say Y if you want to use sunXi internal IR Controller @@ -476,7 +430,6 @@ config IR_SUNXI config IR_SERIAL tristate "Homebrew Serial Port Receiver" - depends on RC_CORE help Say Y if you want to use Homebrew Serial Port Receivers and Transceivers. @@ -492,7 +445,6 @@ config IR_SERIAL_TRANSMITTER config IR_SIR tristate "Built-in SIR IrDA port" - depends on RC_CORE help Say Y if you want to use a IrDA SIR port Transceivers. @@ -501,9 +453,7 @@ config IR_SIR config RC_XBOX_DVD tristate "Xbox DVD Movie Playback Kit" - depends on RC_CORE - depends on USB_ARCH_HAS_HCD - select USB + depends on USB help Say Y here if you want to use the Xbox DVD Movie Playback Kit. These are IR remotes with USB receivers for the Original Xbox (2001). @@ -513,8 +463,7 @@ config RC_XBOX_DVD config IR_TOY tristate "Infrared Toy and IR Droid" - depends on RC_CORE - depends on USB_ARCH_HAS_HCD + depends on USB help Say Y here if you want to use the Infrared Toy or IR Droid, USB versions. From ca8519ddc4d7e27d941a50e310a0f6bcfafdc8a9 Mon Sep 17 00:00:00 2001 From: Ye Bin Date: Fri, 9 Apr 2021 11:51:44 +0200 Subject: [PATCH 142/394] media: siano: use DEFINE_MUTEX() for mutex lock and LIST_HEAD for list head mutex lock can be initialized automatically with DEFINE_MUTEX() rather than explicitly calling mutex_init(). list head can be initialized automatically with LIST_HEAD() rather than explicitly calling INIT_LIST_HEAD(). Reported-by: Hulk Robot Signed-off-by: Ye Bin Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smsdvb-main.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/media/common/siano/smsdvb-main.c b/drivers/media/common/siano/smsdvb-main.c index cd5bafe9a3ac..b8a163a47d09 100644 --- a/drivers/media/common/siano/smsdvb-main.c +++ b/drivers/media/common/siano/smsdvb-main.c @@ -26,8 +26,8 @@ Copyright (C) 2006-2008, Uri Shkolnik DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -static struct list_head g_smsdvb_clients; -static struct mutex g_smsdvb_clientslock; +static LIST_HEAD(g_smsdvb_clients); +static DEFINE_MUTEX(g_smsdvb_clientslock); static u32 sms_to_guard_interval_table[] = { [0] = GUARD_INTERVAL_1_32, @@ -1236,9 +1236,6 @@ static int __init smsdvb_module_init(void) { int rc; - INIT_LIST_HEAD(&g_smsdvb_clients); - mutex_init(&g_smsdvb_clientslock); - smsdvb_debugfs_register(); rc = smscore_register_hotplug(smsdvb_hotplug); From afccc0bbab594bf70f950eea19b60737e763b192 Mon Sep 17 00:00:00 2001 From: wengjianfeng Date: Thu, 8 Apr 2021 12:07:31 +0200 Subject: [PATCH 143/394] media: dvb-frontends: remove redundant words and fix several typos change 'purpous' to 'purpose'. change 'frequecy' to 'frequency'. remove redundant words struct and enum. Signed-off-by: wengjianfeng Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/drx39xyj/drxj.h | 35 +++++++++++---------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/drivers/media/dvb-frontends/drx39xyj/drxj.h b/drivers/media/dvb-frontends/drx39xyj/drxj.h index d62412f71c88..232b3b0d68c8 100644 --- a/drivers/media/dvb-frontends/drx39xyj/drxj.h +++ b/drivers/media/dvb-frontends/drx39xyj/drxj.h @@ -75,9 +75,9 @@ TYPEDEFS u16 result_len; /*< result length in byte */ u16 *parameter; - /*< General purpous param */ + /*< General purpose param */ u16 *result; - /*< General purpous param */}; + /*< General purpose param */}; /*============================================================================*/ /*============================================================================*/ @@ -131,7 +131,7 @@ TYPEDEFS DRXJ_CFG_MAX /* dummy, never to be used */}; /* -* /struct enum drxj_cfg_smart_ant_io * smart antenna i/o. +* /enum drxj_cfg_smart_ant_io * smart antenna i/o. */ enum drxj_cfg_smart_ant_io { DRXJ_SMT_ANT_OUTPUT = 0, @@ -139,7 +139,7 @@ enum drxj_cfg_smart_ant_io { }; /* -* /struct struct drxj_cfg_smart_ant * Set smart antenna. +* /struct drxj_cfg_smart_ant * Set smart antenna. */ struct drxj_cfg_smart_ant { enum drxj_cfg_smart_ant_io io; @@ -159,7 +159,7 @@ struct drxj_agc_status { /* DRXJ_CFG_AGC_RF, DRXJ_CFG_AGC_IF */ /* -* /struct enum drxj_agc_ctrl_mode * Available AGCs modes in the DRXJ. +* /enum drxj_agc_ctrl_mode * Available AGCs modes in the DRXJ. */ enum drxj_agc_ctrl_mode { DRX_AGC_CTRL_AUTO = 0, @@ -167,7 +167,7 @@ struct drxj_agc_status { DRX_AGC_CTRL_OFF}; /* -* /struct struct drxj_cfg_agc * Generic interface for all AGCs present on the DRXJ. +* /struct drxj_cfg_agc * Generic interface for all AGCs present on the DRXJ. */ struct drxj_cfg_agc { enum drx_standard standard; /* standard for which these settings apply */ @@ -183,7 +183,7 @@ struct drxj_agc_status { /* DRXJ_CFG_PRE_SAW */ /* -* /struct struct drxj_cfg_pre_saw * Interface to configure pre SAW sense. +* /struct drxj_cfg_pre_saw * Interface to configure pre SAW sense. */ struct drxj_cfg_pre_saw { enum drx_standard standard; /* standard to which these settings apply */ @@ -193,7 +193,7 @@ struct drxj_agc_status { /* DRXJ_CFG_AFE_GAIN */ /* -* /struct struct drxj_cfg_afe_gain * Interface to configure gain of AFE (LNA + PGA). +* /struct drxj_cfg_afe_gain * Interface to configure gain of AFE (LNA + PGA). */ struct drxj_cfg_afe_gain { enum drx_standard standard; /* standard to which these settings apply */ @@ -220,14 +220,14 @@ struct drxj_agc_status { }; /* -* /struct struct drxj_cfg_vsb_misc * symbol error rate +* /struct drxj_cfg_vsb_misc * symbol error rate */ struct drxj_cfg_vsb_misc { u32 symb_error; /*< symbol error rate sps */}; /* -* /enum enum drxj_mpeg_output_clock_rate * Mpeg output clock rate. +* /enum drxj_mpeg_output_clock_rate * Mpeg output clock rate. * */ enum drxj_mpeg_start_width { @@ -235,7 +235,7 @@ struct drxj_agc_status { DRXJ_MPEG_START_WIDTH_8CLKCYC}; /* -* /enum enum drxj_mpeg_output_clock_rate * Mpeg output clock rate. +* /enum drxj_mpeg_output_clock_rate * Mpeg output clock rate. * */ enum drxj_mpeg_output_clock_rate { @@ -261,7 +261,7 @@ struct drxj_agc_status { enum drxj_mpeg_start_width mpeg_start_width; /*< set MPEG output start width */}; /* -* /enum enum drxj_xtal_freq * Supported external crystal reference frequency. +* /enum drxj_xtal_freq * Supported external crystal reference frequency. */ enum drxj_xtal_freq { DRXJ_XTAL_FREQ_RSVD, @@ -270,14 +270,15 @@ struct drxj_agc_status { DRXJ_XTAL_FREQ_4MHZ}; /* -* /enum enum drxj_xtal_freq * Supported external crystal reference frequency. +* /enum drxj_xtal_freq * Supported external crystal reference frequency. */ enum drxji2c_speed { DRXJ_I2C_SPEED_400KBPS, DRXJ_I2C_SPEED_100KBPS}; /* -* /struct struct drxj_cfg_hw_cfg * Get hw configuration, such as crystal reference frequency, I2C speed, etc... +* /struct drxj_cfg_hw_cfg * Get hw configuration, such as crystal +* reference frequency, I2C speed, etc... */ struct drxj_cfg_hw_cfg { enum drxj_xtal_freq xtal_freq; @@ -364,7 +365,7 @@ struct drxj_cfg_oob_misc { DRXJ_SIF_ATTENUATION_9DB}; /* -* /struct struct drxj_cfg_atv_output * SIF attenuation setting. +* /struct drxj_cfg_atv_output * SIF attenuation setting. * */ struct drxj_cfg_atv_output { @@ -453,10 +454,10 @@ struct drxj_cfg_atv_output { enum drxuio_mode uio_gpio_mode; /*< current mode of ASEL pin */ enum drxuio_mode uio_irqn_mode; /*< current mode of IRQN pin */ - /* IQM fs frequecy shift and inversion */ + /* IQM fs frequency shift and inversion */ u32 iqm_fs_rate_ofs; /*< frequency shifter setting after setchannel */ bool pos_image; /*< True: positive image */ - /* IQM RC frequecy shift */ + /* IQM RC frequency shift */ u32 iqm_rc_rate_ofs; /*< frequency shifter setting after setchannel */ /* ATV configuration */ From 9c87ae1a0dbeb5794957421157fd266d38a869b4 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Thu, 6 May 2021 07:38:56 +0200 Subject: [PATCH 144/394] media: rc: i2c: Fix an error message 'ret' is known to be 1 here. In fact 'i' is expected instead. Store the return value of 'i2c_master_recv()' in 'ret' so that the error message print the correct error code. Fixes: acaa34bf06e9 ("media: rc: implement zilog transmitter") Signed-off-by: Christophe JAILLET Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ir-kbd-i2c.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/ir-kbd-i2c.c b/drivers/media/i2c/ir-kbd-i2c.c index e8119ad0bc71..92376592455e 100644 --- a/drivers/media/i2c/ir-kbd-i2c.c +++ b/drivers/media/i2c/ir-kbd-i2c.c @@ -678,8 +678,8 @@ static int zilog_tx(struct rc_dev *rcdev, unsigned int *txbuf, goto out_unlock; } - i = i2c_master_recv(ir->tx_c, buf, 1); - if (i != 1) { + ret = i2c_master_recv(ir->tx_c, buf, 1); + if (ret != 1) { dev_err(&ir->rc->dev, "i2c_master_recv failed with %d\n", ret); ret = -EIO; goto out_unlock; From 37d9d42f9e78bfe8ec04fd5e049111beb5f59e01 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 11 May 2021 09:22:19 +0200 Subject: [PATCH 145/394] media: lmedm04: delete lme2510_get_adapter_count() The adapter count is fixed at compile time so we can delete the lme2510_get_adapter_count() function and set ".num_adapters = 1" instead. There is also no need to create a zeroed adapter element at the end of the array. Remove that as well. Signed-off-by: Dan Carpenter Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/lmedm04.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c index 1b6d4e4c52ca..fe4d886442a4 100644 --- a/drivers/media/usb/dvb-usb-v2/lmedm04.c +++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c @@ -1122,11 +1122,6 @@ static int lme2510_powerup(struct dvb_usb_device *d, int onoff) return ret; } -static int lme2510_get_adapter_count(struct dvb_usb_device *d) -{ - return 1; -} - static int lme2510_identify_state(struct dvb_usb_device *d, const char **name) { struct lme2510_state *st = d->priv; @@ -1211,12 +1206,12 @@ static struct dvb_usb_device_properties lme2510_props = { .frontend_attach = dm04_lme2510_frontend_attach, .tuner_attach = dm04_lme2510_tuner, .get_stream_config = lme2510_get_stream_config, - .get_adapter_count = lme2510_get_adapter_count, .streaming_ctrl = lme2510_streaming_ctrl, .get_rc_config = lme2510_get_rc_config, .exit = lme2510_exit, + .num_adapters = 1, .adapter = { { .caps = DVB_USB_ADAP_HAS_PID_FILTER| @@ -1227,8 +1222,6 @@ static struct dvb_usb_device_properties lme2510_props = { .stream = DVB_USB_STREAM_BULK(0x86, 10, 4096), }, - { - } }, }; From c680ed46e418e9c785d76cf44eb33bfd1e8cf3f6 Mon Sep 17 00:00:00 2001 From: Pavel Skripkin Date: Fri, 7 May 2021 14:50:43 +0200 Subject: [PATCH 146/394] media: dvb-usb: fix wrong definition syzbot reported WARNING in vmalloc. The problem was in zero size passed to vmalloc. The root case was in wrong cxusb_bluebird_lgz201_properties definition. adapter array has only 1 entry, but num_adapters was 2. Call Trace: __vmalloc_node mm/vmalloc.c:2963 [inline] vmalloc+0x67/0x80 mm/vmalloc.c:2996 dvb_dmx_init+0xe4/0xb90 drivers/media/dvb-core/dvb_demux.c:1251 dvb_usb_adapter_dvb_init+0x564/0x860 drivers/media/usb/dvb-usb/dvb-usb-dvb.c:184 dvb_usb_adapter_init drivers/media/usb/dvb-usb/dvb-usb-init.c:86 [inline] dvb_usb_init drivers/media/usb/dvb-usb/dvb-usb-init.c:184 [inline] dvb_usb_device_init.cold+0xc94/0x146e drivers/media/usb/dvb-usb/dvb-usb-init.c:308 cxusb_probe+0x159/0x5e0 drivers/media/usb/dvb-usb/cxusb.c:1634 Fixes: 4d43e13f723e ("V4L/DVB (4643): Multi-input patch for DVB-USB device") Cc: stable@vger.kernel.org Reported-by: syzbot+7336195c02c1bd2f64e1@syzkaller.appspotmail.com Signed-off-by: Pavel Skripkin Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb/cxusb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c index 761992ad05e2..7707de7bae7c 100644 --- a/drivers/media/usb/dvb-usb/cxusb.c +++ b/drivers/media/usb/dvb-usb/cxusb.c @@ -1947,7 +1947,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = { .size_of_priv = sizeof(struct cxusb_state), - .num_adapters = 2, + .num_adapters = 1, .adapter = { { .num_frontends = 1, From 118f3e1562f2b15e30ed65a2718cd9ed710054b1 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Thu, 29 Apr 2021 16:48:09 +0200 Subject: [PATCH 147/394] media: uapi: mpeg2: Rename "quantization" to "quantisation" The MPEG-2 specification refers to the quantisation matrices using the word "quantisation". Make the V4L2 interface more ergonomic by matching the MPEG-2 spec. Signed-off-by: Ezequiel Garcia Tested-by: Jernej Skrabec Reviewed-by: Jernej Skrabec Tested-by: Daniel Almeida Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../media/v4l/ext-ctrls-codec.rst | 16 ++++++------ .../media/v4l/pixfmt-compressed.rst | 4 +-- .../media/v4l/vidioc-queryctrl.rst | 6 ++--- .../media/videodev2.h.rst.exceptions | 2 +- drivers/media/v4l2-core/v4l2-ctrls.c | 12 ++++----- drivers/staging/media/hantro/hantro_drv.c | 2 +- .../media/hantro/hantro_g1_mpeg2_dec.c | 15 +++++------ drivers/staging/media/hantro/hantro_hw.h | 2 +- drivers/staging/media/hantro/hantro_mpeg2.c | 2 +- .../media/hantro/rk3399_vpu_hw_mpeg2_dec.c | 14 +++++----- drivers/staging/media/sunxi/cedrus/cedrus.c | 2 +- drivers/staging/media/sunxi/cedrus/cedrus.h | 2 +- .../staging/media/sunxi/cedrus/cedrus_dec.c | 4 +-- .../staging/media/sunxi/cedrus/cedrus_mpeg2.c | 26 +++++++++---------- include/media/mpeg2-ctrls.h | 6 ++--- include/media/v4l2-ctrls.h | 4 +-- 16 files changed, 57 insertions(+), 62 deletions(-) diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst index 514b334470ea..2835ce739478 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst @@ -1755,8 +1755,8 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - \normalsize -``V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION (struct)`` - Specifies quantization matrices (as extracted from the bitstream) for the +``V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION (struct)`` + Specifies quantisation matrices (as extracted from the bitstream) for the associated MPEG-2 slice data. .. note:: @@ -1764,7 +1764,7 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - This compound control is not yet part of the public kernel API and it is expected to change. -.. c:type:: v4l2_ctrl_mpeg2_quantization +.. c:type:: v4l2_ctrl_mpeg2_quantisation .. tabularcolumns:: |p{0.8cm}|p{8.0cm}|p{8.5cm}| @@ -1774,7 +1774,7 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - \small -.. flat-table:: struct v4l2_ctrl_mpeg2_quantization +.. flat-table:: struct v4l2_ctrl_mpeg2_quantisation :header-rows: 0 :stub-columns: 0 :widths: 1 1 2 @@ -1798,24 +1798,24 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - YUV formats. * - __u8 - ``intra_quantiser_matrix[64]`` - - The quantization matrix coefficients for intra-coded frames, in zigzag + - The quantisation matrix coefficients for intra-coded frames, in zigzag scanning order. It is relevant for both luma and chroma components, although it can be superseded by the chroma-specific matrix for non-4:2:0 YUV formats. * - __u8 - ``non_intra_quantiser_matrix[64]`` - - The quantization matrix coefficients for non-intra-coded frames, in + - The quantisation matrix coefficients for non-intra-coded frames, in zigzag scanning order. It is relevant for both luma and chroma components, although it can be superseded by the chroma-specific matrix for non-4:2:0 YUV formats. * - __u8 - ``chroma_intra_quantiser_matrix[64]`` - - The quantization matrix coefficients for the chominance component of + - The quantisation matrix coefficients for the chominance component of intra-coded frames, in zigzag scanning order. Only relevant for non-4:2:0 YUV formats. * - __u8 - ``chroma_non_intra_quantiser_matrix[64]`` - - The quantization matrix coefficients for the chrominance component of + - The quantisation matrix coefficients for the chrominance component of non-intra-coded frames, in zigzag scanning order. Only relevant for non-4:2:0 YUV formats. diff --git a/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst b/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst index 6dba70da822b..cba607f789f0 100644 --- a/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst +++ b/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst @@ -115,8 +115,8 @@ Compressed Formats MPEG-2 pipeline (using the :ref:`mem2mem` and :ref:`media-request-api`). Metadata associated with the frame to decode is required to be passed through the ``V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS`` control and - quantization matrices can optionally be specified through the - ``V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION`` control. + quantisation matrices can optionally be specified through the + ``V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION`` control. See the :ref:`associated Codec Control IDs `. Exactly one output and one capture buffer must be provided for use with this pixel format. The output buffer must contain the appropriate number diff --git a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst index 8a285daedc6a..4362945fd39b 100644 --- a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst +++ b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst @@ -423,12 +423,12 @@ See also the examples in :ref:`control`. - n/a - A struct :c:type:`v4l2_ctrl_mpeg2_slice_params`, containing MPEG-2 slice parameters for stateless video decoders. - * - ``V4L2_CTRL_TYPE_MPEG2_QUANTIZATION`` + * - ``V4L2_CTRL_TYPE_MPEG2_QUANTISATION`` - n/a - n/a - n/a - - A struct :c:type:`v4l2_ctrl_mpeg2_quantization`, containing MPEG-2 - quantization matrices for stateless video decoders. + - A struct :c:type:`v4l2_ctrl_mpeg2_quantisation`, containing MPEG-2 + quantisation matrices for stateless video decoders. * - ``V4L2_CTRL_TYPE_AREA`` - n/a - n/a diff --git a/Documentation/userspace-api/media/videodev2.h.rst.exceptions b/Documentation/userspace-api/media/videodev2.h.rst.exceptions index f59940352faa..5b2ebaa35d24 100644 --- a/Documentation/userspace-api/media/videodev2.h.rst.exceptions +++ b/Documentation/userspace-api/media/videodev2.h.rst.exceptions @@ -135,7 +135,7 @@ replace symbol V4L2_CTRL_TYPE_U16 :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_U32 :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_U8 :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS :c:type:`v4l2_ctrl_type` -replace symbol V4L2_CTRL_TYPE_MPEG2_QUANTIZATION :c:type:`v4l2_ctrl_type` +replace symbol V4L2_CTRL_TYPE_MPEG2_QUANTISATION :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_H264_SPS :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_H264_PPS :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_H264_SCALING_MATRIX :c:type:`v4l2_ctrl_type` diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index 0d7fe1bd975a..1ed62f0ed66f 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -966,7 +966,7 @@ const char *v4l2_ctrl_get_name(u32 id) case V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX: return "Frame LTR Index"; case V4L2_CID_MPEG_VIDEO_USE_LTR_FRAMES: return "Use LTR Frames"; case V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS: return "MPEG-2 Slice Parameters"; - case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION: return "MPEG-2 Quantization Matrices"; + case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION: return "MPEG-2 Quantisation Matrices"; case V4L2_CID_FWHT_I_FRAME_QP: return "FWHT I-Frame QP Value"; case V4L2_CID_FWHT_P_FRAME_QP: return "FWHT P-Frame QP Value"; @@ -1490,8 +1490,8 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, case V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS: *type = V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS; break; - case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION: - *type = V4L2_CTRL_TYPE_MPEG2_QUANTIZATION; + case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION: + *type = V4L2_CTRL_TYPE_MPEG2_QUANTISATION; break; case V4L2_CID_STATELESS_FWHT_PARAMS: *type = V4L2_CTRL_TYPE_FWHT_PARAMS; @@ -1942,7 +1942,7 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, break; - case V4L2_CTRL_TYPE_MPEG2_QUANTIZATION: + case V4L2_CTRL_TYPE_MPEG2_QUANTISATION: break; case V4L2_CTRL_TYPE_FWHT_PARAMS: @@ -2911,8 +2911,8 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, case V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS: elem_size = sizeof(struct v4l2_ctrl_mpeg2_slice_params); break; - case V4L2_CTRL_TYPE_MPEG2_QUANTIZATION: - elem_size = sizeof(struct v4l2_ctrl_mpeg2_quantization); + case V4L2_CTRL_TYPE_MPEG2_QUANTISATION: + elem_size = sizeof(struct v4l2_ctrl_mpeg2_quantisation); break; case V4L2_CTRL_TYPE_FWHT_PARAMS: elem_size = sizeof(struct v4l2_ctrl_fwht_params); diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c index 074b9bb30d6d..b7b4328d3c6d 100644 --- a/drivers/staging/media/hantro/hantro_drv.c +++ b/drivers/staging/media/hantro/hantro_drv.c @@ -303,7 +303,7 @@ static const struct hantro_ctrl controls[] = { }, { .codec = HANTRO_MPEG2_DECODER, .cfg = { - .id = V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION, + .id = V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION, }, }, { .codec = HANTRO_VP8_DECODER, diff --git a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c index 0fd306806f16..55d07aa7756b 100644 --- a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c +++ b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c @@ -82,17 +82,14 @@ #define PICT_FRAME 3 static void -hantro_g1_mpeg2_dec_set_quantization(struct hantro_dev *vpu, +hantro_g1_mpeg2_dec_set_quantisation(struct hantro_dev *vpu, struct hantro_ctx *ctx) { - struct v4l2_ctrl_mpeg2_quantization *quantization; + struct v4l2_ctrl_mpeg2_quantisation *q; - quantization = hantro_get_ctrl(ctx, - V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION); - hantro_mpeg2_dec_copy_qtable(ctx->mpeg2_dec.qtable.cpu, - quantization); - vdpu_write_relaxed(vpu, ctx->mpeg2_dec.qtable.dma, - G1_REG_QTABLE_BASE); + q = hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION); + hantro_mpeg2_dec_copy_qtable(ctx->mpeg2_dec.qtable.cpu, q); + vdpu_write_relaxed(vpu, ctx->mpeg2_dec.qtable.dma, G1_REG_QTABLE_BASE); } static void @@ -238,7 +235,7 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx) reg = G1_REG_APF_THRESHOLD(8); vdpu_write_relaxed(vpu, reg, G1_SWREG(55)); - hantro_g1_mpeg2_dec_set_quantization(vpu, ctx); + hantro_g1_mpeg2_dec_set_quantisation(vpu, ctx); hantro_g1_mpeg2_dec_set_buffers(vpu, ctx, &src_buf->vb2_buf, &dst_buf->vb2_buf, diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h index 0a42df22472e..3d8b53567f16 100644 --- a/drivers/staging/media/hantro/hantro_hw.h +++ b/drivers/staging/media/hantro/hantro_hw.h @@ -223,7 +223,7 @@ hantro_h264_mv_size(unsigned int width, unsigned int height) void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx); void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx); void hantro_mpeg2_dec_copy_qtable(u8 *qtable, - const struct v4l2_ctrl_mpeg2_quantization *ctrl); + const struct v4l2_ctrl_mpeg2_quantisation *ctrl); int hantro_mpeg2_dec_init(struct hantro_ctx *ctx); void hantro_mpeg2_dec_exit(struct hantro_ctx *ctx); diff --git a/drivers/staging/media/hantro/hantro_mpeg2.c b/drivers/staging/media/hantro/hantro_mpeg2.c index 53a99a9988d5..04e545eb0a83 100644 --- a/drivers/staging/media/hantro/hantro_mpeg2.c +++ b/drivers/staging/media/hantro/hantro_mpeg2.c @@ -19,7 +19,7 @@ static const u8 zigzag[64] = { }; void hantro_mpeg2_dec_copy_qtable(u8 *qtable, - const struct v4l2_ctrl_mpeg2_quantization *ctrl) + const struct v4l2_ctrl_mpeg2_quantisation *ctrl) { int i, n; diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c index f610fa5b4335..61a54549774d 100644 --- a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c +++ b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c @@ -84,16 +84,14 @@ #define PICT_FRAME 3 static void -rk3399_vpu_mpeg2_dec_set_quantization(struct hantro_dev *vpu, +rk3399_vpu_mpeg2_dec_set_quantisation(struct hantro_dev *vpu, struct hantro_ctx *ctx) { - struct v4l2_ctrl_mpeg2_quantization *quantization; + struct v4l2_ctrl_mpeg2_quantisation *q; - quantization = hantro_get_ctrl(ctx, - V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION); - hantro_mpeg2_dec_copy_qtable(ctx->mpeg2_dec.qtable.cpu, quantization); - vdpu_write_relaxed(vpu, ctx->mpeg2_dec.qtable.dma, - VDPU_REG_QTABLE_BASE); + q = hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION); + hantro_mpeg2_dec_copy_qtable(ctx->mpeg2_dec.qtable.cpu, q); + vdpu_write_relaxed(vpu, ctx->mpeg2_dec.qtable.dma, VDPU_REG_QTABLE_BASE); } static void @@ -243,7 +241,7 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx) VDPU_REG_MV_ACCURACY_BWD(1); vdpu_write_relaxed(vpu, reg, VDPU_SWREG(136)); - rk3399_vpu_mpeg2_dec_set_quantization(vpu, ctx); + rk3399_vpu_mpeg2_dec_set_quantisation(vpu, ctx); rk3399_vpu_mpeg2_dec_set_buffers(vpu, ctx, &src_buf->vb2_buf, &dst_buf->vb2_buf, diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c index 92812d1a39d4..62a5407664ae 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus.c @@ -37,7 +37,7 @@ static const struct cedrus_control cedrus_controls[] = { }, { .cfg = { - .id = V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION, + .id = V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION, }, .codec = CEDRUS_CODEC_MPEG2, }, diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h index 15f147dad4cb..6516bff3d319 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus.h +++ b/drivers/staging/media/sunxi/cedrus/cedrus.h @@ -69,7 +69,7 @@ struct cedrus_h264_run { struct cedrus_mpeg2_run { const struct v4l2_ctrl_mpeg2_slice_params *slice_params; - const struct v4l2_ctrl_mpeg2_quantization *quantization; + const struct v4l2_ctrl_mpeg2_quantisation *quantisation; }; struct cedrus_h265_run { diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c index d696b3ec70c0..238f779d2ba4 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c @@ -42,8 +42,8 @@ void cedrus_device_run(void *priv) case V4L2_PIX_FMT_MPEG2_SLICE: run.mpeg2.slice_params = cedrus_find_control_data(ctx, V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS); - run.mpeg2.quantization = cedrus_find_control_data(ctx, - V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION); + run.mpeg2.quantisation = cedrus_find_control_data(ctx, + V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION); break; case V4L2_PIX_FMT_H264_SLICE: diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c index 8bcd6b8f9e2d..459f71679a4f 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c @@ -13,9 +13,9 @@ #include "cedrus_hw.h" #include "cedrus_regs.h" -/* Default MPEG-2 quantization coefficients, from the specification. */ +/* Default MPEG-2 quantisation coefficients, from the specification. */ -static const u8 intra_quantization_matrix_default[64] = { +static const u8 intra_quantisation_matrix_default[64] = { 8, 16, 16, 19, 16, 19, 22, 22, 22, 22, 22, 22, 26, 24, 26, 27, 27, 27, 26, 26, 26, 26, 27, 27, @@ -26,7 +26,7 @@ static const u8 intra_quantization_matrix_default[64] = { 46, 46, 56, 56, 58, 69, 69, 83 }; -static const u8 non_intra_quantization_matrix_default[64] = { +static const u8 non_intra_quantisation_matrix_default[64] = { 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, @@ -77,7 +77,7 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run) const struct v4l2_ctrl_mpeg2_slice_params *slice_params; const struct v4l2_mpeg2_sequence *sequence; const struct v4l2_mpeg2_picture *picture; - const struct v4l2_ctrl_mpeg2_quantization *quantization; + const struct v4l2_ctrl_mpeg2_quantisation *quantisation; dma_addr_t src_buf_addr, dst_luma_addr, dst_chroma_addr; dma_addr_t fwd_luma_addr, fwd_chroma_addr; dma_addr_t bwd_luma_addr, bwd_chroma_addr; @@ -93,17 +93,17 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run) sequence = &slice_params->sequence; picture = &slice_params->picture; - quantization = run->mpeg2.quantization; + quantisation = run->mpeg2.quantisation; /* Activate MPEG engine. */ cedrus_engine_enable(ctx, CEDRUS_CODEC_MPEG2); - /* Set intra quantization matrix. */ + /* Set intra quantisation matrix. */ - if (quantization && quantization->load_intra_quantiser_matrix) - matrix = quantization->intra_quantiser_matrix; + if (quantisation && quantisation->load_intra_quantiser_matrix) + matrix = quantisation->intra_quantiser_matrix; else - matrix = intra_quantization_matrix_default; + matrix = intra_quantisation_matrix_default; for (i = 0; i < 64; i++) { reg = VE_DEC_MPEG_IQMINPUT_WEIGHT(i, matrix[i]); @@ -112,12 +112,12 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run) cedrus_write(dev, VE_DEC_MPEG_IQMINPUT, reg); } - /* Set non-intra quantization matrix. */ + /* Set non-intra quantisation matrix. */ - if (quantization && quantization->load_non_intra_quantiser_matrix) - matrix = quantization->non_intra_quantiser_matrix; + if (quantisation && quantisation->load_non_intra_quantiser_matrix) + matrix = quantisation->non_intra_quantiser_matrix; else - matrix = non_intra_quantization_matrix_default; + matrix = non_intra_quantisation_matrix_default; for (i = 0; i < 64; i++) { reg = VE_DEC_MPEG_IQMINPUT_WEIGHT(i, matrix[i]); diff --git a/include/media/mpeg2-ctrls.h b/include/media/mpeg2-ctrls.h index 2a4ae6701166..b8adf3ac2c1d 100644 --- a/include/media/mpeg2-ctrls.h +++ b/include/media/mpeg2-ctrls.h @@ -12,11 +12,11 @@ #define _MPEG2_CTRLS_H_ #define V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS (V4L2_CID_CODEC_BASE+250) -#define V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION (V4L2_CID_CODEC_BASE+251) +#define V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION (V4L2_CID_CODEC_BASE+251) /* enum v4l2_ctrl_type type values */ #define V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS 0x0103 -#define V4L2_CTRL_TYPE_MPEG2_QUANTIZATION 0x0104 +#define V4L2_CTRL_TYPE_MPEG2_QUANTISATION 0x0104 #define V4L2_MPEG2_PICTURE_CODING_TYPE_I 1 #define V4L2_MPEG2_PICTURE_CODING_TYPE_P 2 @@ -66,7 +66,7 @@ struct v4l2_ctrl_mpeg2_slice_params { __u32 quantiser_scale_code; }; -struct v4l2_ctrl_mpeg2_quantization { +struct v4l2_ctrl_mpeg2_quantisation { /* ISO/IEC 13818-2, ITU-T Rec. H.262: Quant matrix extension */ __u8 load_intra_quantiser_matrix; __u8 load_non_intra_quantiser_matrix; diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h index a5953b812878..a38e6bd02a6a 100644 --- a/include/media/v4l2-ctrls.h +++ b/include/media/v4l2-ctrls.h @@ -41,7 +41,7 @@ struct video_device; * @p_u32: Pointer to a 32-bit unsigned value. * @p_char: Pointer to a string. * @p_mpeg2_slice_params: Pointer to a MPEG2 slice parameters structure. - * @p_mpeg2_quantization: Pointer to a MPEG2 quantization data structure. + * @p_mpeg2_quantisation: Pointer to a MPEG2 quantisation data structure. * @p_fwht_params: Pointer to a FWHT stateless parameters structure. * @p_h264_sps: Pointer to a struct v4l2_ctrl_h264_sps. * @p_h264_pps: Pointer to a struct v4l2_ctrl_h264_pps. @@ -67,7 +67,7 @@ union v4l2_ctrl_ptr { u32 *p_u32; char *p_char; struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params; - struct v4l2_ctrl_mpeg2_quantization *p_mpeg2_quantization; + struct v4l2_ctrl_mpeg2_quantisation *p_mpeg2_quantisation; struct v4l2_ctrl_fwht_params *p_fwht_params; struct v4l2_ctrl_h264_sps *p_h264_sps; struct v4l2_ctrl_h264_pps *p_h264_pps; From 81bbb65f19819440b42270e1f033d9b14279540c Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Thu, 29 Apr 2021 16:48:10 +0200 Subject: [PATCH 148/394] media: uapi: mpeg2: rework quantisation matrices semantics As stated in the MPEG-2 specification, section 6.3.7 "Quant matrix extension": Each quantisation matrix has a default set of values. When a sequence_header_code is decoded all matrices shall be reset to their default values. User defined matrices may be downloaded and this can occur in a sequence_header() or in a quant_matrix_extension(). The load_intra_quantiser_matrix syntax elements are transmitted in the bitstream headers, signalling that a quantisation matrix needs to be loaded and used for pictures transmitted afterwards (until the matrices are reset). This "load" semantics are implemented in the V4L2 interface without the need of any "load" flags: passing the control is effectively a load. Therefore, rework the V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION semantics to match the MPEG-2 semantics. Quantisation matrices values are now initialized by the V4L2 control core to their reset default value, and applications are expected to reset their values as specified. The quantisation control is therefore optional, and used to load bitstream-defined values in the quantisation matrices. Signed-off-by: Ezequiel Garcia Co-developed-by: Nicolas Dufresne Signed-off-by: Nicolas Dufresne Tested-by: Jernej Skrabec Reviewed-by: Jernej Skrabec Tested-by: Daniel Almeida Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../media/v4l/ext-ctrls-codec.rst | 17 --------- drivers/media/v4l2-core/v4l2-ctrls.c | 26 +++++++++++++ .../staging/media/sunxi/cedrus/cedrus_mpeg2.c | 38 +------------------ include/media/mpeg2-ctrls.h | 5 --- 4 files changed, 28 insertions(+), 58 deletions(-) diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst index 2835ce739478..bfbc5fda9f9b 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst @@ -1779,23 +1779,6 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - :stub-columns: 0 :widths: 1 1 2 - * - __u8 - - ``load_intra_quantiser_matrix`` - - One bit to indicate whether to load the ``intra_quantiser_matrix`` data. - * - __u8 - - ``load_non_intra_quantiser_matrix`` - - One bit to indicate whether to load the ``non_intra_quantiser_matrix`` - data. - * - __u8 - - ``load_chroma_intra_quantiser_matrix`` - - One bit to indicate whether to load the - ``chroma_intra_quantiser_matrix`` data, only relevant for non-4:2:0 YUV - formats. - * - __u8 - - ``load_chroma_non_intra_quantiser_matrix`` - - One bit to indicate whether to load the - ``chroma_non_intra_quantiser_matrix`` data, only relevant for non-4:2:0 - YUV formats. * - __u8 - ``intra_quantiser_matrix[64]`` - The quantisation matrix coefficients for intra-coded frames, in zigzag diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index 1ed62f0ed66f..41955ea9230d 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -57,6 +57,18 @@ static bool is_new_manual(const struct v4l2_ctrl *master) return master->is_auto && master->val == master->manual_mode_value; } +/* Default intra MPEG-2 quantisation coefficients, from the specification. */ +static const u8 mpeg2_intra_quant_matrix[64] = { + 8, 16, 16, 19, 16, 19, 22, 22, + 22, 22, 22, 22, 26, 24, 26, 27, + 27, 27, 26, 26, 26, 26, 27, 27, + 27, 29, 29, 29, 34, 34, 34, 29, + 29, 29, 27, 27, 29, 29, 32, 32, + 34, 34, 37, 38, 37, 35, 35, 34, + 35, 38, 38, 40, 40, 40, 48, 48, + 46, 46, 56, 56, 58, 69, 69, 83 +}; + /* Returns NULL or a character pointer array containing the menu for the given control ID. The pointer array ends with a NULL pointer. An empty string signifies a menu entry that is invalid. This allows @@ -1692,6 +1704,7 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx, union v4l2_ctrl_ptr ptr) { struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params; + struct v4l2_ctrl_mpeg2_quantisation *p_mpeg2_quant; struct v4l2_ctrl_vp8_frame *p_vp8_frame; struct v4l2_ctrl_fwht_params *p_fwht_params; void *p = ptr.p + idx * ctrl->elem_size; @@ -1716,6 +1729,19 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx, p_mpeg2_slice_params->picture.picture_coding_type = V4L2_MPEG2_PICTURE_CODING_TYPE_I; break; + case V4L2_CTRL_TYPE_MPEG2_QUANTISATION: + p_mpeg2_quant = p; + + memcpy(p_mpeg2_quant->intra_quantiser_matrix, + mpeg2_intra_quant_matrix, + ARRAY_SIZE(mpeg2_intra_quant_matrix)); + /* + * The default non-intra MPEG-2 quantisation + * coefficients are all 16, as per the specification. + */ + memset(p_mpeg2_quant->non_intra_quantiser_matrix, 16, + sizeof(p_mpeg2_quant->non_intra_quantiser_matrix)); + break; case V4L2_CTRL_TYPE_VP8_FRAME: p_vp8_frame = p; p_vp8_frame->num_dct_parts = 1; diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c index 459f71679a4f..e3154f631858 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c @@ -13,30 +13,6 @@ #include "cedrus_hw.h" #include "cedrus_regs.h" -/* Default MPEG-2 quantisation coefficients, from the specification. */ - -static const u8 intra_quantisation_matrix_default[64] = { - 8, 16, 16, 19, 16, 19, 22, 22, - 22, 22, 22, 22, 26, 24, 26, 27, - 27, 27, 26, 26, 26, 26, 27, 27, - 27, 29, 29, 29, 34, 34, 34, 29, - 29, 29, 27, 27, 29, 29, 32, 32, - 34, 34, 37, 38, 37, 35, 35, 34, - 35, 38, 38, 40, 40, 40, 48, 48, - 46, 46, 56, 56, 58, 69, 69, 83 -}; - -static const u8 non_intra_quantisation_matrix_default[64] = { - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16 -}; - static enum cedrus_irq_status cedrus_mpeg2_irq_status(struct cedrus_ctx *ctx) { struct cedrus_dev *dev = ctx->dev; @@ -99,12 +75,7 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run) cedrus_engine_enable(ctx, CEDRUS_CODEC_MPEG2); /* Set intra quantisation matrix. */ - - if (quantisation && quantisation->load_intra_quantiser_matrix) - matrix = quantisation->intra_quantiser_matrix; - else - matrix = intra_quantisation_matrix_default; - + matrix = quantisation->intra_quantiser_matrix; for (i = 0; i < 64; i++) { reg = VE_DEC_MPEG_IQMINPUT_WEIGHT(i, matrix[i]); reg |= VE_DEC_MPEG_IQMINPUT_FLAG_INTRA; @@ -113,12 +84,7 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run) } /* Set non-intra quantisation matrix. */ - - if (quantisation && quantisation->load_non_intra_quantiser_matrix) - matrix = quantisation->non_intra_quantiser_matrix; - else - matrix = non_intra_quantisation_matrix_default; - + matrix = quantisation->non_intra_quantiser_matrix; for (i = 0; i < 64; i++) { reg = VE_DEC_MPEG_IQMINPUT_WEIGHT(i, matrix[i]); reg |= VE_DEC_MPEG_IQMINPUT_FLAG_NON_INTRA; diff --git a/include/media/mpeg2-ctrls.h b/include/media/mpeg2-ctrls.h index b8adf3ac2c1d..8ea2c7f3a172 100644 --- a/include/media/mpeg2-ctrls.h +++ b/include/media/mpeg2-ctrls.h @@ -68,11 +68,6 @@ struct v4l2_ctrl_mpeg2_slice_params { struct v4l2_ctrl_mpeg2_quantisation { /* ISO/IEC 13818-2, ITU-T Rec. H.262: Quant matrix extension */ - __u8 load_intra_quantiser_matrix; - __u8 load_non_intra_quantiser_matrix; - __u8 load_chroma_intra_quantiser_matrix; - __u8 load_chroma_non_intra_quantiser_matrix; - __u8 intra_quantiser_matrix[64]; __u8 non_intra_quantiser_matrix[64]; __u8 chroma_intra_quantiser_matrix[64]; From 88e78409a83a579fde7f150be7ebeefab0e1f774 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Thu, 29 Apr 2021 16:48:11 +0200 Subject: [PATCH 149/394] media: uapi: mpeg2: Cleanup flags Our current MPEG-2 uAPI uses 1-byte fields for MPEG-2 boolean syntax elements. Clean these by adding a 'flags' field and flag macro for each boolean syntax element. A follow-up change will refactor this uAPI so we don't need to add padding fields just yet. Signed-off-by: Ezequiel Garcia Tested-by: Jonas Karlman Tested-by: Jernej Skrabec Reviewed-by: Jernej Skrabec Tested-by: Daniel Almeida Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../media/v4l/ext-ctrls-codec.rst | 77 +++++++++++++------ drivers/media/v4l2-core/v4l2-ctrls.c | 14 ++-- .../media/hantro/hantro_g1_mpeg2_dec.c | 76 +++++++++--------- .../media/hantro/rk3399_vpu_hw_mpeg2_dec.c | 76 +++++++++--------- .../staging/media/sunxi/cedrus/cedrus_mpeg2.c | 38 ++++----- include/media/mpeg2-ctrls.h | 36 +++++---- 6 files changed, 175 insertions(+), 142 deletions(-) diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst index bfbc5fda9f9b..aa11346e7e27 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst @@ -1687,13 +1687,28 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - - ``profile_and_level_indication`` - The current profile and level indication as extracted from the bitstream. - * - __u8 - - ``progressive_sequence`` - - Indication that all the frames for the sequence are progressive instead - of interlaced. * - __u8 - ``chroma_format`` - The chrominance sub-sampling format (1: 4:2:0, 2: 4:2:2, 3: 4:4:4). + * - __u32 + - ``flags`` + - See :ref:`MPEG-2 Sequence Flags `. + +.. _mpeg2_sequence_flags: + +``MPEG-2 Sequence Flags`` + +.. cssclass:: longtable + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + :widths: 1 1 2 + + * - ``V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE`` + - 0x00000001 + - Indication that all the frames for the sequence are progressive instead + of interlaced. .. c:type:: v4l2_mpeg2_picture @@ -1726,29 +1741,45 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - - ``picture_structure`` - Picture structure (1: interlaced top field, 2: interlaced bottom field, 3: progressive frame). - * - __u8 - - ``top_field_first`` - - If set to 1 and interlaced stream, top field is output first. - * - __u8 - - ``frame_pred_frame_dct`` - - If set to 1, only frame-DCT and frame prediction are used. - * - __u8 - - ``concealment_motion_vectors`` - - If set to 1, motion vectors are coded for intra macroblocks. - * - __u8 - - ``q_scale_type`` + * - __u32 + - ``flags`` + - See :ref:`MPEG-2 Picture Flags `. + + +.. _mpeg2_picture_flags: + +``MPEG-2 Picture Flags`` + +.. cssclass:: longtable + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + :widths: 1 1 2 + + * - ``V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST`` + - 0x00000001 + - If set and it's an interlaced stream, top field is output first. + * - ``V4L2_MPEG2_PIC_FLAG_FRAME_PRED_DCT`` + - 0x00000002 + - If set only frame-DCT and frame prediction are used. + * - ``V4L2_MPEG2_PIC_FLAG_CONCEALMENT_MV`` + - 0x00000004 + - If set motion vectors are coded for intra macroblocks. + * - ``V4L2_MPEG2_PIC_FLAG_Q_SCALE_TYPE`` + - 0x00000008 - This flag affects the inverse quantization process. - * - __u8 - - ``intra_vlc_format`` + * - ``V4L2_MPEG2_PIC_FLAG_INTRA_VLC`` + - 0x00000010 - This flag affects the decoding of transform coefficient data. - * - __u8 - - ``alternate_scan`` + * - ``V4L2_MPEG2_PIC_FLAG_ALT_SCAN`` + - 0x00000020 - This flag affects the decoding of transform coefficient data. - * - __u8 - - ``repeat_first_field`` + * - ``V4L2_MPEG2_PIC_FLAG_REPEAT_FIRST`` + - 0x00000040 - This flag affects the decoding process of progressive frames. - * - __u16 - - ``progressive_frame`` + * - ``V4L2_MPEG2_PIC_FLAG_PROGRESSIVE`` + - 0x00000080 - Indicates whether the current frame is progressive. .. raw:: latex diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index 41955ea9230d..37531302dd3a 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -1727,7 +1727,7 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx, /* interlaced top field */ p_mpeg2_slice_params->picture.picture_structure = 1; p_mpeg2_slice_params->picture.picture_coding_type = - V4L2_MPEG2_PICTURE_CODING_TYPE_I; + V4L2_MPEG2_PIC_CODING_TYPE_I; break; case V4L2_CTRL_TYPE_MPEG2_QUANTISATION: p_mpeg2_quant = p; @@ -1949,18 +1949,18 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, } switch (p_mpeg2_slice_params->picture.picture_structure) { - case 1: /* interlaced top field */ - case 2: /* interlaced bottom field */ - case 3: /* progressive */ + case V4L2_MPEG2_PIC_TOP_FIELD: + case V4L2_MPEG2_PIC_BOTTOM_FIELD: + case V4L2_MPEG2_PIC_FRAME: break; default: return -EINVAL; } switch (p_mpeg2_slice_params->picture.picture_coding_type) { - case V4L2_MPEG2_PICTURE_CODING_TYPE_I: - case V4L2_MPEG2_PICTURE_CODING_TYPE_P: - case V4L2_MPEG2_PICTURE_CODING_TYPE_B: + case V4L2_MPEG2_PIC_CODING_TYPE_I: + case V4L2_MPEG2_PIC_CODING_TYPE_P: + case V4L2_MPEG2_PIC_CODING_TYPE_B: break; default: return -EINVAL; diff --git a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c index 55d07aa7756b..925341891b7f 100644 --- a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c +++ b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c @@ -77,10 +77,6 @@ #define G1_REG_APF_THRESHOLD(v) (((v) << 0) & GENMASK(13, 0)) -#define PICT_TOP_FIELD 1 -#define PICT_BOTTOM_FIELD 2 -#define PICT_FRAME 3 - static void hantro_g1_mpeg2_dec_set_quantisation(struct hantro_dev *vpu, struct hantro_ctx *ctx) @@ -96,19 +92,19 @@ static void hantro_g1_mpeg2_dec_set_buffers(struct hantro_dev *vpu, struct hantro_ctx *ctx, struct vb2_buffer *src_buf, struct vb2_buffer *dst_buf, - const struct v4l2_mpeg2_sequence *sequence, - const struct v4l2_mpeg2_picture *picture, + const struct v4l2_mpeg2_sequence *seq, + const struct v4l2_mpeg2_picture *pic, const struct v4l2_ctrl_mpeg2_slice_params *slice_params) { dma_addr_t forward_addr = 0, backward_addr = 0; dma_addr_t current_addr, addr; - switch (picture->picture_coding_type) { - case V4L2_MPEG2_PICTURE_CODING_TYPE_B: + switch (pic->picture_coding_type) { + case V4L2_MPEG2_PIC_CODING_TYPE_B: backward_addr = hantro_get_ref(ctx, slice_params->backward_ref_ts); fallthrough; - case V4L2_MPEG2_PICTURE_CODING_TYPE_P: + case V4L2_MPEG2_PIC_CODING_TYPE_P: forward_addr = hantro_get_ref(ctx, slice_params->forward_ref_ts); } @@ -121,7 +117,7 @@ hantro_g1_mpeg2_dec_set_buffers(struct hantro_dev *vpu, struct hantro_ctx *ctx, addr = hantro_get_dec_buf_addr(ctx, dst_buf); current_addr = addr; - if (picture->picture_structure == PICT_BOTTOM_FIELD) + if (pic->picture_structure == V4L2_MPEG2_PIC_BOTTOM_FIELD) addr += ALIGN(ctx->dst_fmt.width, 16); vdpu_write_relaxed(vpu, addr, G1_REG_DEC_OUT_BASE); @@ -131,18 +127,18 @@ hantro_g1_mpeg2_dec_set_buffers(struct hantro_dev *vpu, struct hantro_ctx *ctx, backward_addr = current_addr; /* Set forward ref frame (top/bottom field) */ - if (picture->picture_structure == PICT_FRAME || - picture->picture_coding_type == V4L2_MPEG2_PICTURE_CODING_TYPE_B || - (picture->picture_structure == PICT_TOP_FIELD && - picture->top_field_first) || - (picture->picture_structure == PICT_BOTTOM_FIELD && - !picture->top_field_first)) { + if (pic->picture_structure == V4L2_MPEG2_PIC_FRAME || + pic->picture_coding_type == V4L2_MPEG2_PIC_CODING_TYPE_B || + (pic->picture_structure == V4L2_MPEG2_PIC_TOP_FIELD && + pic->flags & V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST) || + (pic->picture_structure == V4L2_MPEG2_PIC_BOTTOM_FIELD && + !(pic->flags & V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST))) { vdpu_write_relaxed(vpu, forward_addr, G1_REG_REFER0_BASE); vdpu_write_relaxed(vpu, forward_addr, G1_REG_REFER1_BASE); - } else if (picture->picture_structure == PICT_TOP_FIELD) { + } else if (pic->picture_structure == V4L2_MPEG2_PIC_TOP_FIELD) { vdpu_write_relaxed(vpu, forward_addr, G1_REG_REFER0_BASE); vdpu_write_relaxed(vpu, current_addr, G1_REG_REFER1_BASE); - } else if (picture->picture_structure == PICT_BOTTOM_FIELD) { + } else if (pic->picture_structure == V4L2_MPEG2_PIC_BOTTOM_FIELD) { vdpu_write_relaxed(vpu, current_addr, G1_REG_REFER0_BASE); vdpu_write_relaxed(vpu, forward_addr, G1_REG_REFER1_BASE); } @@ -157,8 +153,8 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx) struct hantro_dev *vpu = ctx->dev; struct vb2_v4l2_buffer *src_buf, *dst_buf; const struct v4l2_ctrl_mpeg2_slice_params *slice_params; - const struct v4l2_mpeg2_sequence *sequence; - const struct v4l2_mpeg2_picture *picture; + const struct v4l2_mpeg2_sequence *seq; + const struct v4l2_mpeg2_picture *pic; u32 reg; src_buf = hantro_get_src_buf(ctx); @@ -169,8 +165,8 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx) slice_params = hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS); - sequence = &slice_params->sequence; - picture = &slice_params->picture; + seq = &slice_params->sequence; + pic = &slice_params->picture; reg = G1_REG_DEC_AXI_RD_ID(0) | G1_REG_DEC_TIMEOUT_E(1) | @@ -190,11 +186,11 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx) reg = G1_REG_DEC_MODE(5) | G1_REG_RLC_MODE_E(0) | - G1_REG_PIC_INTERLACE_E(!sequence->progressive_sequence) | - G1_REG_PIC_FIELDMODE_E(picture->picture_structure != PICT_FRAME) | - G1_REG_PIC_B_E(picture->picture_coding_type == V4L2_MPEG2_PICTURE_CODING_TYPE_B) | - G1_REG_PIC_INTER_E(picture->picture_coding_type != V4L2_MPEG2_PICTURE_CODING_TYPE_I) | - G1_REG_PIC_TOPFIELD_E(picture->picture_structure == PICT_TOP_FIELD) | + G1_REG_PIC_INTERLACE_E(!(seq->flags & V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE)) | + G1_REG_PIC_FIELDMODE_E(pic->picture_structure != V4L2_MPEG2_PIC_FRAME) | + G1_REG_PIC_B_E(pic->picture_coding_type == V4L2_MPEG2_PIC_CODING_TYPE_B) | + G1_REG_PIC_INTER_E(pic->picture_coding_type != V4L2_MPEG2_PIC_CODING_TYPE_I) | + G1_REG_PIC_TOPFIELD_E(pic->picture_structure == V4L2_MPEG2_PIC_TOP_FIELD) | G1_REG_FWD_INTERLACE_E(0) | G1_REG_FILTERING_DIS(1) | G1_REG_WRITE_MVS_E(0) | @@ -203,27 +199,27 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx) reg = G1_REG_PIC_MB_WIDTH(MB_WIDTH(ctx->dst_fmt.width)) | G1_REG_PIC_MB_HEIGHT_P(MB_HEIGHT(ctx->dst_fmt.height)) | - G1_REG_ALT_SCAN_E(picture->alternate_scan) | - G1_REG_TOPFIELDFIRST_E(picture->top_field_first); + G1_REG_ALT_SCAN_E(pic->flags & V4L2_MPEG2_PIC_FLAG_ALT_SCAN) | + G1_REG_TOPFIELDFIRST_E(pic->flags & V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST); vdpu_write_relaxed(vpu, reg, G1_SWREG(4)); reg = G1_REG_STRM_START_BIT(slice_params->data_bit_offset) | - G1_REG_QSCALE_TYPE(picture->q_scale_type) | - G1_REG_CON_MV_E(picture->concealment_motion_vectors) | - G1_REG_INTRA_DC_PREC(picture->intra_dc_precision) | - G1_REG_INTRA_VLC_TAB(picture->intra_vlc_format) | - G1_REG_FRAME_PRED_DCT(picture->frame_pred_frame_dct); + G1_REG_QSCALE_TYPE(pic->flags & V4L2_MPEG2_PIC_FLAG_Q_SCALE_TYPE) | + G1_REG_CON_MV_E(pic->flags & V4L2_MPEG2_PIC_FLAG_CONCEALMENT_MV) | + G1_REG_INTRA_DC_PREC(pic->intra_dc_precision) | + G1_REG_INTRA_VLC_TAB(pic->flags & V4L2_MPEG2_PIC_FLAG_INTRA_VLC) | + G1_REG_FRAME_PRED_DCT(pic->flags & V4L2_MPEG2_PIC_FLAG_FRAME_PRED_DCT); vdpu_write_relaxed(vpu, reg, G1_SWREG(5)); reg = G1_REG_INIT_QP(1) | G1_REG_STREAM_LEN(slice_params->bit_size >> 3); vdpu_write_relaxed(vpu, reg, G1_SWREG(6)); - reg = G1_REG_ALT_SCAN_FLAG_E(picture->alternate_scan) | - G1_REG_FCODE_FWD_HOR(picture->f_code[0][0]) | - G1_REG_FCODE_FWD_VER(picture->f_code[0][1]) | - G1_REG_FCODE_BWD_HOR(picture->f_code[1][0]) | - G1_REG_FCODE_BWD_VER(picture->f_code[1][1]) | + reg = G1_REG_ALT_SCAN_FLAG_E(pic->flags & V4L2_MPEG2_PIC_FLAG_ALT_SCAN) | + G1_REG_FCODE_FWD_HOR(pic->f_code[0][0]) | + G1_REG_FCODE_FWD_VER(pic->f_code[0][1]) | + G1_REG_FCODE_BWD_HOR(pic->f_code[1][0]) | + G1_REG_FCODE_BWD_VER(pic->f_code[1][1]) | G1_REG_MV_ACCURACY_FWD(1) | G1_REG_MV_ACCURACY_BWD(1); vdpu_write_relaxed(vpu, reg, G1_SWREG(18)); @@ -239,7 +235,7 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx) hantro_g1_mpeg2_dec_set_buffers(vpu, ctx, &src_buf->vb2_buf, &dst_buf->vb2_buf, - sequence, picture, slice_params); + seq, pic, slice_params); hantro_end_prepare_run(ctx); diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c index 61a54549774d..ff54398f6643 100644 --- a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c +++ b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c @@ -79,10 +79,6 @@ #define VDPU_REG_MV_ACCURACY_FWD(v) ((v) ? BIT(2) : 0) #define VDPU_REG_MV_ACCURACY_BWD(v) ((v) ? BIT(1) : 0) -#define PICT_TOP_FIELD 1 -#define PICT_BOTTOM_FIELD 2 -#define PICT_FRAME 3 - static void rk3399_vpu_mpeg2_dec_set_quantisation(struct hantro_dev *vpu, struct hantro_ctx *ctx) @@ -99,19 +95,19 @@ rk3399_vpu_mpeg2_dec_set_buffers(struct hantro_dev *vpu, struct hantro_ctx *ctx, struct vb2_buffer *src_buf, struct vb2_buffer *dst_buf, - const struct v4l2_mpeg2_sequence *sequence, - const struct v4l2_mpeg2_picture *picture, + const struct v4l2_mpeg2_sequence *seq, + const struct v4l2_mpeg2_picture *pic, const struct v4l2_ctrl_mpeg2_slice_params *slice_params) { dma_addr_t forward_addr = 0, backward_addr = 0; dma_addr_t current_addr, addr; - switch (picture->picture_coding_type) { - case V4L2_MPEG2_PICTURE_CODING_TYPE_B: + switch (pic->picture_coding_type) { + case V4L2_MPEG2_PIC_CODING_TYPE_B: backward_addr = hantro_get_ref(ctx, slice_params->backward_ref_ts); fallthrough; - case V4L2_MPEG2_PICTURE_CODING_TYPE_P: + case V4L2_MPEG2_PIC_CODING_TYPE_P: forward_addr = hantro_get_ref(ctx, slice_params->forward_ref_ts); } @@ -124,7 +120,7 @@ rk3399_vpu_mpeg2_dec_set_buffers(struct hantro_dev *vpu, addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0); current_addr = addr; - if (picture->picture_structure == PICT_BOTTOM_FIELD) + if (pic->picture_structure == V4L2_MPEG2_PIC_BOTTOM_FIELD) addr += ALIGN(ctx->dst_fmt.width, 16); vdpu_write_relaxed(vpu, addr, VDPU_REG_DEC_OUT_BASE); @@ -134,18 +130,18 @@ rk3399_vpu_mpeg2_dec_set_buffers(struct hantro_dev *vpu, backward_addr = current_addr; /* Set forward ref frame (top/bottom field) */ - if (picture->picture_structure == PICT_FRAME || - picture->picture_coding_type == V4L2_MPEG2_PICTURE_CODING_TYPE_B || - (picture->picture_structure == PICT_TOP_FIELD && - picture->top_field_first) || - (picture->picture_structure == PICT_BOTTOM_FIELD && - !picture->top_field_first)) { + if (pic->picture_structure == V4L2_MPEG2_PIC_FRAME || + pic->picture_coding_type == V4L2_MPEG2_PIC_CODING_TYPE_B || + (pic->picture_structure == V4L2_MPEG2_PIC_TOP_FIELD && + pic->flags & V4L2_MPEG2_PIC_TOP_FIELD) || + (pic->picture_structure == V4L2_MPEG2_PIC_BOTTOM_FIELD && + !(pic->flags & V4L2_MPEG2_PIC_TOP_FIELD))) { vdpu_write_relaxed(vpu, forward_addr, VDPU_REG_REFER0_BASE); vdpu_write_relaxed(vpu, forward_addr, VDPU_REG_REFER1_BASE); - } else if (picture->picture_structure == PICT_TOP_FIELD) { + } else if (pic->picture_structure == V4L2_MPEG2_PIC_TOP_FIELD) { vdpu_write_relaxed(vpu, forward_addr, VDPU_REG_REFER0_BASE); vdpu_write_relaxed(vpu, current_addr, VDPU_REG_REFER1_BASE); - } else if (picture->picture_structure == PICT_BOTTOM_FIELD) { + } else if (pic->picture_structure == V4L2_MPEG2_PIC_BOTTOM_FIELD) { vdpu_write_relaxed(vpu, current_addr, VDPU_REG_REFER0_BASE); vdpu_write_relaxed(vpu, forward_addr, VDPU_REG_REFER1_BASE); } @@ -160,8 +156,8 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx) struct hantro_dev *vpu = ctx->dev; struct vb2_v4l2_buffer *src_buf, *dst_buf; const struct v4l2_ctrl_mpeg2_slice_params *slice_params; - const struct v4l2_mpeg2_sequence *sequence; - const struct v4l2_mpeg2_picture *picture; + const struct v4l2_mpeg2_sequence *seq; + const struct v4l2_mpeg2_picture *pic; u32 reg; src_buf = hantro_get_src_buf(ctx); @@ -171,8 +167,8 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx) slice_params = hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS); - sequence = &slice_params->sequence; - picture = &slice_params->picture; + seq = &slice_params->sequence; + pic = &slice_params->picture; reg = VDPU_REG_DEC_ADV_PRE_DIS(0) | VDPU_REG_DEC_SCMD_DIS(0) | @@ -207,11 +203,11 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx) vdpu_write_relaxed(vpu, reg, VDPU_SWREG(56)); reg = VDPU_REG_RLC_MODE_E(0) | - VDPU_REG_PIC_INTERLACE_E(!sequence->progressive_sequence) | - VDPU_REG_PIC_FIELDMODE_E(picture->picture_structure != PICT_FRAME) | - VDPU_REG_PIC_B_E(picture->picture_coding_type == V4L2_MPEG2_PICTURE_CODING_TYPE_B) | - VDPU_REG_PIC_INTER_E(picture->picture_coding_type != V4L2_MPEG2_PICTURE_CODING_TYPE_I) | - VDPU_REG_PIC_TOPFIELD_E(picture->picture_structure == PICT_TOP_FIELD) | + VDPU_REG_PIC_INTERLACE_E(!(seq->flags & V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE)) | + VDPU_REG_PIC_FIELDMODE_E(pic->picture_structure != V4L2_MPEG2_PIC_FRAME) | + VDPU_REG_PIC_B_E(pic->picture_coding_type == V4L2_MPEG2_PIC_CODING_TYPE_B) | + VDPU_REG_PIC_INTER_E(pic->picture_coding_type != V4L2_MPEG2_PIC_CODING_TYPE_I) | + VDPU_REG_PIC_TOPFIELD_E(pic->picture_structure == V4L2_MPEG2_PIC_TOP_FIELD) | VDPU_REG_FWD_INTERLACE_E(0) | VDPU_REG_WRITE_MVS_E(0) | VDPU_REG_DEC_TIMEOUT_E(1) | @@ -220,23 +216,23 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx) reg = VDPU_REG_PIC_MB_WIDTH(MB_WIDTH(ctx->dst_fmt.width)) | VDPU_REG_PIC_MB_HEIGHT_P(MB_HEIGHT(ctx->dst_fmt.height)) | - VDPU_REG_ALT_SCAN_E(picture->alternate_scan) | - VDPU_REG_TOPFIELDFIRST_E(picture->top_field_first); + VDPU_REG_ALT_SCAN_E(pic->flags & V4L2_MPEG2_PIC_FLAG_ALT_SCAN) | + VDPU_REG_TOPFIELDFIRST_E(pic->flags & V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST); vdpu_write_relaxed(vpu, reg, VDPU_SWREG(120)); reg = VDPU_REG_STRM_START_BIT(slice_params->data_bit_offset) | - VDPU_REG_QSCALE_TYPE(picture->q_scale_type) | - VDPU_REG_CON_MV_E(picture->concealment_motion_vectors) | - VDPU_REG_INTRA_DC_PREC(picture->intra_dc_precision) | - VDPU_REG_INTRA_VLC_TAB(picture->intra_vlc_format) | - VDPU_REG_FRAME_PRED_DCT(picture->frame_pred_frame_dct); + VDPU_REG_QSCALE_TYPE(pic->flags & V4L2_MPEG2_PIC_FLAG_Q_SCALE_TYPE) | + VDPU_REG_CON_MV_E(pic->flags & V4L2_MPEG2_PIC_FLAG_CONCEALMENT_MV) | + VDPU_REG_INTRA_DC_PREC(pic->intra_dc_precision) | + VDPU_REG_INTRA_VLC_TAB(pic->flags & V4L2_MPEG2_PIC_FLAG_INTRA_VLC) | + VDPU_REG_FRAME_PRED_DCT(pic->flags & V4L2_MPEG2_PIC_FLAG_FRAME_PRED_DCT); vdpu_write_relaxed(vpu, reg, VDPU_SWREG(122)); - reg = VDPU_REG_ALT_SCAN_FLAG_E(picture->alternate_scan) | - VDPU_REG_FCODE_FWD_HOR(picture->f_code[0][0]) | - VDPU_REG_FCODE_FWD_VER(picture->f_code[0][1]) | - VDPU_REG_FCODE_BWD_HOR(picture->f_code[1][0]) | - VDPU_REG_FCODE_BWD_VER(picture->f_code[1][1]) | + reg = VDPU_REG_ALT_SCAN_FLAG_E(pic->flags & V4L2_MPEG2_PIC_FLAG_ALT_SCAN) | + VDPU_REG_FCODE_FWD_HOR(pic->f_code[0][0]) | + VDPU_REG_FCODE_FWD_VER(pic->f_code[0][1]) | + VDPU_REG_FCODE_BWD_HOR(pic->f_code[1][0]) | + VDPU_REG_FCODE_BWD_VER(pic->f_code[1][1]) | VDPU_REG_MV_ACCURACY_FWD(1) | VDPU_REG_MV_ACCURACY_BWD(1); vdpu_write_relaxed(vpu, reg, VDPU_SWREG(136)); @@ -245,7 +241,7 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx) rk3399_vpu_mpeg2_dec_set_buffers(vpu, ctx, &src_buf->vb2_buf, &dst_buf->vb2_buf, - sequence, picture, slice_params); + seq, pic, slice_params); /* Kick the watchdog and start decoding */ hantro_end_prepare_run(ctx); diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c index e3154f631858..e39a17d28c7d 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c @@ -51,8 +51,8 @@ static void cedrus_mpeg2_irq_disable(struct cedrus_ctx *ctx) static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run) { const struct v4l2_ctrl_mpeg2_slice_params *slice_params; - const struct v4l2_mpeg2_sequence *sequence; - const struct v4l2_mpeg2_picture *picture; + const struct v4l2_mpeg2_sequence *seq; + const struct v4l2_mpeg2_picture *pic; const struct v4l2_ctrl_mpeg2_quantisation *quantisation; dma_addr_t src_buf_addr, dst_luma_addr, dst_chroma_addr; dma_addr_t fwd_luma_addr, fwd_chroma_addr; @@ -66,8 +66,8 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run) u32 reg; slice_params = run->mpeg2.slice_params; - sequence = &slice_params->sequence; - picture = &slice_params->picture; + seq = &slice_params->sequence; + pic = &slice_params->picture; quantisation = run->mpeg2.quantisation; @@ -94,19 +94,19 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run) /* Set MPEG picture header. */ - reg = VE_DEC_MPEG_MP12HDR_SLICE_TYPE(picture->picture_coding_type); - reg |= VE_DEC_MPEG_MP12HDR_F_CODE(0, 0, picture->f_code[0][0]); - reg |= VE_DEC_MPEG_MP12HDR_F_CODE(0, 1, picture->f_code[0][1]); - reg |= VE_DEC_MPEG_MP12HDR_F_CODE(1, 0, picture->f_code[1][0]); - reg |= VE_DEC_MPEG_MP12HDR_F_CODE(1, 1, picture->f_code[1][1]); - reg |= VE_DEC_MPEG_MP12HDR_INTRA_DC_PRECISION(picture->intra_dc_precision); - reg |= VE_DEC_MPEG_MP12HDR_INTRA_PICTURE_STRUCTURE(picture->picture_structure); - reg |= VE_DEC_MPEG_MP12HDR_TOP_FIELD_FIRST(picture->top_field_first); - reg |= VE_DEC_MPEG_MP12HDR_FRAME_PRED_FRAME_DCT(picture->frame_pred_frame_dct); - reg |= VE_DEC_MPEG_MP12HDR_CONCEALMENT_MOTION_VECTORS(picture->concealment_motion_vectors); - reg |= VE_DEC_MPEG_MP12HDR_Q_SCALE_TYPE(picture->q_scale_type); - reg |= VE_DEC_MPEG_MP12HDR_INTRA_VLC_FORMAT(picture->intra_vlc_format); - reg |= VE_DEC_MPEG_MP12HDR_ALTERNATE_SCAN(picture->alternate_scan); + reg = VE_DEC_MPEG_MP12HDR_SLICE_TYPE(pic->picture_coding_type); + reg |= VE_DEC_MPEG_MP12HDR_F_CODE(0, 0, pic->f_code[0][0]); + reg |= VE_DEC_MPEG_MP12HDR_F_CODE(0, 1, pic->f_code[0][1]); + reg |= VE_DEC_MPEG_MP12HDR_F_CODE(1, 0, pic->f_code[1][0]); + reg |= VE_DEC_MPEG_MP12HDR_F_CODE(1, 1, pic->f_code[1][1]); + reg |= VE_DEC_MPEG_MP12HDR_INTRA_DC_PRECISION(pic->intra_dc_precision); + reg |= VE_DEC_MPEG_MP12HDR_INTRA_PICTURE_STRUCTURE(pic->picture_structure); + reg |= VE_DEC_MPEG_MP12HDR_TOP_FIELD_FIRST(pic->flags & V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST); + reg |= VE_DEC_MPEG_MP12HDR_FRAME_PRED_FRAME_DCT(pic->flags & V4L2_MPEG2_PIC_FLAG_FRAME_PRED_DCT); + reg |= VE_DEC_MPEG_MP12HDR_CONCEALMENT_MOTION_VECTORS(pic->flags & V4L2_MPEG2_PIC_FLAG_CONCEALMENT_MV); + reg |= VE_DEC_MPEG_MP12HDR_Q_SCALE_TYPE(pic->flags & V4L2_MPEG2_PIC_FLAG_Q_SCALE_TYPE); + reg |= VE_DEC_MPEG_MP12HDR_INTRA_VLC_FORMAT(pic->flags & V4L2_MPEG2_PIC_FLAG_INTRA_VLC); + reg |= VE_DEC_MPEG_MP12HDR_ALTERNATE_SCAN(pic->flags & V4L2_MPEG2_PIC_FLAG_ALT_SCAN); reg |= VE_DEC_MPEG_MP12HDR_FULL_PEL_FORWARD_VECTOR(0); reg |= VE_DEC_MPEG_MP12HDR_FULL_PEL_BACKWARD_VECTOR(0); @@ -114,8 +114,8 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run) /* Set frame dimensions. */ - reg = VE_DEC_MPEG_PICCODEDSIZE_WIDTH(sequence->horizontal_size); - reg |= VE_DEC_MPEG_PICCODEDSIZE_HEIGHT(sequence->vertical_size); + reg = VE_DEC_MPEG_PICCODEDSIZE_WIDTH(seq->horizontal_size); + reg |= VE_DEC_MPEG_PICCODEDSIZE_HEIGHT(seq->vertical_size); cedrus_write(dev, VE_DEC_MPEG_PICCODEDSIZE, reg); diff --git a/include/media/mpeg2-ctrls.h b/include/media/mpeg2-ctrls.h index 8ea2c7f3a172..d3190979d574 100644 --- a/include/media/mpeg2-ctrls.h +++ b/include/media/mpeg2-ctrls.h @@ -18,10 +18,7 @@ #define V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS 0x0103 #define V4L2_CTRL_TYPE_MPEG2_QUANTISATION 0x0104 -#define V4L2_MPEG2_PICTURE_CODING_TYPE_I 1 -#define V4L2_MPEG2_PICTURE_CODING_TYPE_P 2 -#define V4L2_MPEG2_PICTURE_CODING_TYPE_B 3 -#define V4L2_MPEG2_PICTURE_CODING_TYPE_D 4 +#define V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE 0x0001 struct v4l2_mpeg2_sequence { /* ISO/IEC 13818-2, ITU-T Rec. H.262: Sequence header */ @@ -31,10 +28,29 @@ struct v4l2_mpeg2_sequence { /* ISO/IEC 13818-2, ITU-T Rec. H.262: Sequence extension */ __u16 profile_and_level_indication; - __u8 progressive_sequence; __u8 chroma_format; + + __u32 flags; }; +#define V4L2_MPEG2_PIC_CODING_TYPE_I 1 +#define V4L2_MPEG2_PIC_CODING_TYPE_P 2 +#define V4L2_MPEG2_PIC_CODING_TYPE_B 3 +#define V4L2_MPEG2_PIC_CODING_TYPE_D 4 + +#define V4L2_MPEG2_PIC_TOP_FIELD 0x1 +#define V4L2_MPEG2_PIC_BOTTOM_FIELD 0x2 +#define V4L2_MPEG2_PIC_FRAME 0x3 + +#define V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST 0x0001 +#define V4L2_MPEG2_PIC_FLAG_FRAME_PRED_DCT 0x0002 +#define V4L2_MPEG2_PIC_FLAG_CONCEALMENT_MV 0x0004 +#define V4L2_MPEG2_PIC_FLAG_Q_SCALE_TYPE 0x0008 +#define V4L2_MPEG2_PIC_FLAG_INTRA_VLC 0x0010 +#define V4L2_MPEG2_PIC_FLAG_ALT_SCAN 0x0020 +#define V4L2_MPEG2_PIC_FLAG_REPEAT_FIRST 0x0040 +#define V4L2_MPEG2_PIC_FLAG_PROGRESSIVE 0x0080 + struct v4l2_mpeg2_picture { /* ISO/IEC 13818-2, ITU-T Rec. H.262: Picture header */ __u8 picture_coding_type; @@ -43,14 +59,8 @@ struct v4l2_mpeg2_picture { __u8 f_code[2][2]; __u8 intra_dc_precision; __u8 picture_structure; - __u8 top_field_first; - __u8 frame_pred_frame_dct; - __u8 concealment_motion_vectors; - __u8 q_scale_type; - __u8 intra_vlc_format; - __u8 alternate_scan; - __u8 repeat_first_field; - __u16 progressive_frame; + + __u32 flags; }; struct v4l2_ctrl_mpeg2_slice_params { From f329e21e9dadc5c8ee37c781b30fe63bf7217201 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Thu, 29 Apr 2021 16:48:12 +0200 Subject: [PATCH 150/394] media: uapi: mpeg2: Split sequence and picture parameters Typically, bitstreams are composed of a sequence header, followed by a number of picture header and picture coding extension headers. Each picture can be composed of a number of slices. Let's split the MPEG-2 uAPI to follow these semantics more closely, allowing more usage flexibility. Having these controls split up allows applications to set a sequence control at the beginning of a sequence, and then set a picture control for each frame. While here add padding fields where needed, and document the uAPI header thoroughly. Note that the V4L2_CTRL_TYPE_{} defines had to be moved because it clashes with existing ones. This is not really an issue since they will be re-defined when the controls are moved out of staging. Signed-off-by: Ezequiel Garcia Tested-by: Jonas Karlman Tested-by: Jernej Skrabec Reviewed-by: Jernej Skrabec Tested-by: Daniel Almeida Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../media/v4l/ext-ctrls-codec.rst | 64 +++++++---- .../media/v4l/pixfmt-compressed.rst | 5 +- .../media/v4l/vidioc-queryctrl.rst | 12 ++ .../media/videodev2.h.rst.exceptions | 2 + drivers/media/v4l2-core/v4l2-ctrls.c | 56 +++++++-- drivers/staging/media/hantro/hantro_drv.c | 10 ++ .../media/hantro/hantro_g1_mpeg2_dec.c | 14 ++- .../media/hantro/rk3399_vpu_hw_mpeg2_dec.c | 14 ++- drivers/staging/media/sunxi/cedrus/cedrus.c | 12 ++ drivers/staging/media/sunxi/cedrus/cedrus.h | 2 + .../staging/media/sunxi/cedrus/cedrus_dec.c | 4 + .../staging/media/sunxi/cedrus/cedrus_mpeg2.c | 8 +- include/media/mpeg2-ctrls.h | 107 ++++++++++++++---- include/media/v4l2-ctrls.h | 4 + 14 files changed, 238 insertions(+), 76 deletions(-) diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst index aa11346e7e27..f96a2dcb22cc 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst @@ -1636,14 +1636,6 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - * - __u32 - ``data_bit_offset`` - Offset (in bits) to the video data in the current slice data. - * - struct :c:type:`v4l2_mpeg2_sequence` - - ``sequence`` - - Structure with MPEG-2 sequence metadata, merging relevant fields from - the sequence header and sequence extension parts of the bitstream. - * - struct :c:type:`v4l2_mpeg2_picture` - - ``picture`` - - Structure with MPEG-2 picture metadata, merging relevant fields from - the picture header and picture coding extension parts of the bitstream. * - __u64 - ``backward_ref_ts`` - Timestamp of the V4L2 capture buffer to use as backward reference, used @@ -1661,14 +1653,28 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - * - __u32 - ``quantiser_scale_code`` - Code used to determine the quantization scale to use for the IDCT. + * - __u8 + - ``reserved`` + - Applications and drivers must set this to zero. -.. c:type:: v4l2_mpeg2_sequence +``V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE (struct)`` + Specifies the sequence parameters (as extracted from the bitstream) for the + associated MPEG-2 slice data. This includes fields matching the syntax + elements from the sequence header and sequence extension parts of the + bitstream as specified by :ref:`mpeg2part2`. + + .. note:: + + This compound control is not yet part of the public kernel API and + it is expected to change. + +.. c:type:: v4l2_ctrl_mpeg2_sequence .. cssclass:: longtable .. tabularcolumns:: |p{1.4cm}|p{6.5cm}|p{9.4cm}| -.. flat-table:: struct v4l2_mpeg2_sequence +.. flat-table:: struct v4l2_ctrl_mpeg2_sequence :header-rows: 0 :stub-columns: 0 :widths: 1 1 2 @@ -1690,7 +1696,7 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - * - __u8 - ``chroma_format`` - The chrominance sub-sampling format (1: 4:2:0, 2: 4:2:2, 3: 4:4:4). - * - __u32 + * - __u8 - ``flags`` - See :ref:`MPEG-2 Sequence Flags `. @@ -1706,11 +1712,22 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - :widths: 1 1 2 * - ``V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE`` - - 0x00000001 + - 0x01 - Indication that all the frames for the sequence are progressive instead of interlaced. -.. c:type:: v4l2_mpeg2_picture +``V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE (struct)`` + Specifies the picture parameters (as extracted from the bitstream) for the + associated MPEG-2 slice data. This includes fields matching the syntax + elements from the picture header and picture coding extension parts of the + bitstream as specified by :ref:`mpeg2part2`. + + .. note:: + + This compound control is not yet part of the public kernel API and + it is expected to change. + +.. c:type:: v4l2_ctrl_mpeg2_picture .. raw:: latex @@ -1720,30 +1737,33 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - .. tabularcolumns:: |p{1.0cm}|p{5.6cm}|p{10.7cm}| -.. flat-table:: struct v4l2_mpeg2_picture +.. flat-table:: struct v4l2_ctrl_mpeg2_picture :header-rows: 0 :stub-columns: 0 :widths: 1 1 2 + * - __u32 + - ``flags`` + - See :ref:`MPEG-2 Picture Flags `. + * - __u8 + - ``f_code[2][2]`` + - Motion vector codes. * - __u8 - ``picture_coding_type`` - Picture coding type for the frame covered by the current slice (V4L2_MPEG2_PICTURE_CODING_TYPE_I, V4L2_MPEG2_PICTURE_CODING_TYPE_P or V4L2_MPEG2_PICTURE_CODING_TYPE_B). * - __u8 - - ``f_code[2][2]`` - - Motion vector codes. + - ``picture_structure`` + - Picture structure (1: interlaced top field, 2: interlaced bottom field, + 3: progressive frame). * - __u8 - ``intra_dc_precision`` - Precision of Discrete Cosine transform (0: 8 bits precision, 1: 9 bits precision, 2: 10 bits precision, 3: 11 bits precision). * - __u8 - - ``picture_structure`` - - Picture structure (1: interlaced top field, 2: interlaced bottom field, - 3: progressive frame). - * - __u32 - - ``flags`` - - See :ref:`MPEG-2 Picture Flags `. + - ``reserved[5]`` + - Applications and drivers must set this to zero. .. _mpeg2_picture_flags: diff --git a/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst b/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst index cba607f789f0..bbbacbd65d6f 100644 --- a/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst +++ b/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst @@ -114,8 +114,9 @@ Compressed Formats This format is adapted for stateless video decoders that implement a MPEG-2 pipeline (using the :ref:`mem2mem` and :ref:`media-request-api`). Metadata associated with the frame to decode is required to be passed - through the ``V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS`` control and - quantisation matrices can optionally be specified through the + through the ``V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE``, + ``V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE``, and ``V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS`` + controls. Quantisation matrices can optionally be specified through the ``V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION`` control. See the :ref:`associated Codec Control IDs `. Exactly one output and one capture buffer must be provided for use with diff --git a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst index 4362945fd39b..afc1505a3a7e 100644 --- a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst +++ b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst @@ -429,6 +429,18 @@ See also the examples in :ref:`control`. - n/a - A struct :c:type:`v4l2_ctrl_mpeg2_quantisation`, containing MPEG-2 quantisation matrices for stateless video decoders. + * - ``V4L2_CTRL_TYPE_MPEG2_SEQUENCE`` + - n/a + - n/a + - n/a + - A struct :c:type:`v4l2_ctrl_mpeg2_sequence`, containing MPEG-2 + sequence parameters for stateless video decoders. + * - ``V4L2_CTRL_TYPE_MPEG2_PICTURE`` + - n/a + - n/a + - n/a + - A struct :c:type:`v4l2_ctrl_mpeg2_picture`, containing MPEG-2 + picture parameters for stateless video decoders. * - ``V4L2_CTRL_TYPE_AREA`` - n/a - n/a diff --git a/Documentation/userspace-api/media/videodev2.h.rst.exceptions b/Documentation/userspace-api/media/videodev2.h.rst.exceptions index 5b2ebaa35d24..928fdc419ee3 100644 --- a/Documentation/userspace-api/media/videodev2.h.rst.exceptions +++ b/Documentation/userspace-api/media/videodev2.h.rst.exceptions @@ -134,6 +134,8 @@ replace symbol V4L2_CTRL_TYPE_STRING :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_U16 :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_U32 :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_U8 :c:type:`v4l2_ctrl_type` +replace symbol V4L2_CTRL_TYPE_MPEG2_SEQUENCE :c:type:`v4l2_ctrl_type` +replace symbol V4L2_CTRL_TYPE_MPEG2_PICTURE :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_MPEG2_QUANTISATION :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_H264_SPS :c:type:`v4l2_ctrl_type` diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index 37531302dd3a..59b16f70b093 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -977,6 +977,8 @@ const char *v4l2_ctrl_get_name(u32 id) case V4L2_CID_MPEG_VIDEO_LTR_COUNT: return "LTR Count"; case V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX: return "Frame LTR Index"; case V4L2_CID_MPEG_VIDEO_USE_LTR_FRAMES: return "Use LTR Frames"; + case V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE: return "MPEG-2 Sequence Header"; + case V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE: return "MPEG-2 Picture Header"; case V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS: return "MPEG-2 Slice Parameters"; case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION: return "MPEG-2 Quantisation Matrices"; case V4L2_CID_FWHT_I_FRAME_QP: return "FWHT I-Frame QP Value"; @@ -1499,6 +1501,12 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, case V4L2_CID_RDS_TX_ALT_FREQS: *type = V4L2_CTRL_TYPE_U32; break; + case V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE: + *type = V4L2_CTRL_TYPE_MPEG2_SEQUENCE; + break; + case V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE: + *type = V4L2_CTRL_TYPE_MPEG2_PICTURE; + break; case V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS: *type = V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS; break; @@ -1703,7 +1711,8 @@ static bool std_equal(const struct v4l2_ctrl *ctrl, u32 idx, static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx, union v4l2_ctrl_ptr ptr) { - struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params; + struct v4l2_ctrl_mpeg2_sequence *p_mpeg2_sequence; + struct v4l2_ctrl_mpeg2_picture *p_mpeg2_picture; struct v4l2_ctrl_mpeg2_quantisation *p_mpeg2_quant; struct v4l2_ctrl_vp8_frame *p_vp8_frame; struct v4l2_ctrl_fwht_params *p_fwht_params; @@ -1720,13 +1729,18 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx, * v4l2_ctrl_type enum. */ switch ((u32)ctrl->type) { - case V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS: - p_mpeg2_slice_params = p; + case V4L2_CTRL_TYPE_MPEG2_SEQUENCE: + p_mpeg2_sequence = p; + /* 4:2:0 */ - p_mpeg2_slice_params->sequence.chroma_format = 1; + p_mpeg2_sequence->chroma_format = 1; + break; + case V4L2_CTRL_TYPE_MPEG2_PICTURE: + p_mpeg2_picture = p; + /* interlaced top field */ - p_mpeg2_slice_params->picture.picture_structure = 1; - p_mpeg2_slice_params->picture.picture_coding_type = + p_mpeg2_picture->picture_structure = V4L2_MPEG2_PIC_TOP_FIELD; + p_mpeg2_picture->picture_coding_type = V4L2_MPEG2_PIC_CODING_TYPE_I; break; case V4L2_CTRL_TYPE_MPEG2_QUANTISATION: @@ -1909,6 +1923,8 @@ static void std_log(const struct v4l2_ctrl *ctrl) static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, union v4l2_ctrl_ptr ptr) { + struct v4l2_ctrl_mpeg2_sequence *p_mpeg2_sequence; + struct v4l2_ctrl_mpeg2_picture *p_mpeg2_picture; struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params; struct v4l2_ctrl_vp8_frame *p_vp8_frame; struct v4l2_ctrl_fwht_params *p_fwht_params; @@ -1926,10 +1942,10 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, unsigned int i; switch ((u32)ctrl->type) { - case V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS: - p_mpeg2_slice_params = p; + case V4L2_CTRL_TYPE_MPEG2_SEQUENCE: + p_mpeg2_sequence = p; - switch (p_mpeg2_slice_params->sequence.chroma_format) { + switch (p_mpeg2_sequence->chroma_format) { case 1: /* 4:2:0 */ case 2: /* 4:2:2 */ case 3: /* 4:4:4 */ @@ -1937,8 +1953,12 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, default: return -EINVAL; } + break; - switch (p_mpeg2_slice_params->picture.intra_dc_precision) { + case V4L2_CTRL_TYPE_MPEG2_PICTURE: + p_mpeg2_picture = p; + + switch (p_mpeg2_picture->intra_dc_precision) { case 0: /* 8 bits */ case 1: /* 9 bits */ case 2: /* 10 bits */ @@ -1948,7 +1968,7 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, return -EINVAL; } - switch (p_mpeg2_slice_params->picture.picture_structure) { + switch (p_mpeg2_picture->picture_structure) { case V4L2_MPEG2_PIC_TOP_FIELD: case V4L2_MPEG2_PIC_BOTTOM_FIELD: case V4L2_MPEG2_PIC_FRAME: @@ -1957,7 +1977,7 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, return -EINVAL; } - switch (p_mpeg2_slice_params->picture.picture_coding_type) { + switch (p_mpeg2_picture->picture_coding_type) { case V4L2_MPEG2_PIC_CODING_TYPE_I: case V4L2_MPEG2_PIC_CODING_TYPE_P: case V4L2_MPEG2_PIC_CODING_TYPE_B: @@ -1965,7 +1985,13 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, default: return -EINVAL; } + zero_reserved(*p_mpeg2_picture); + break; + case V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS: + p_mpeg2_slice_params = p; + + zero_reserved(*p_mpeg2_slice_params); break; case V4L2_CTRL_TYPE_MPEG2_QUANTISATION: @@ -2934,6 +2960,12 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, case V4L2_CTRL_TYPE_U32: elem_size = sizeof(u32); break; + case V4L2_CTRL_TYPE_MPEG2_SEQUENCE: + elem_size = sizeof(struct v4l2_ctrl_mpeg2_sequence); + break; + case V4L2_CTRL_TYPE_MPEG2_PICTURE: + elem_size = sizeof(struct v4l2_ctrl_mpeg2_picture); + break; case V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS: elem_size = sizeof(struct v4l2_ctrl_mpeg2_slice_params); break; diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c index b7b4328d3c6d..4505aac2b9bb 100644 --- a/drivers/staging/media/hantro/hantro_drv.c +++ b/drivers/staging/media/hantro/hantro_drv.c @@ -295,6 +295,16 @@ static const struct hantro_ctrl controls[] = { .def = 50, .ops = &hantro_jpeg_ctrl_ops, }, + }, { + .codec = HANTRO_MPEG2_DECODER, + .cfg = { + .id = V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE, + }, + }, { + .codec = HANTRO_MPEG2_DECODER, + .cfg = { + .id = V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE, + }, }, { .codec = HANTRO_MPEG2_DECODER, .cfg = { diff --git a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c index 925341891b7f..fd61e1fae30e 100644 --- a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c +++ b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c @@ -92,8 +92,8 @@ static void hantro_g1_mpeg2_dec_set_buffers(struct hantro_dev *vpu, struct hantro_ctx *ctx, struct vb2_buffer *src_buf, struct vb2_buffer *dst_buf, - const struct v4l2_mpeg2_sequence *seq, - const struct v4l2_mpeg2_picture *pic, + const struct v4l2_ctrl_mpeg2_sequence *seq, + const struct v4l2_ctrl_mpeg2_picture *pic, const struct v4l2_ctrl_mpeg2_slice_params *slice_params) { dma_addr_t forward_addr = 0, backward_addr = 0; @@ -153,8 +153,8 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx) struct hantro_dev *vpu = ctx->dev; struct vb2_v4l2_buffer *src_buf, *dst_buf; const struct v4l2_ctrl_mpeg2_slice_params *slice_params; - const struct v4l2_mpeg2_sequence *seq; - const struct v4l2_mpeg2_picture *pic; + const struct v4l2_ctrl_mpeg2_sequence *seq; + const struct v4l2_ctrl_mpeg2_picture *pic; u32 reg; src_buf = hantro_get_src_buf(ctx); @@ -165,8 +165,10 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx) slice_params = hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS); - seq = &slice_params->sequence; - pic = &slice_params->picture; + seq = hantro_get_ctrl(ctx, + V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE); + pic = hantro_get_ctrl(ctx, + V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE); reg = G1_REG_DEC_AXI_RD_ID(0) | G1_REG_DEC_TIMEOUT_E(1) | diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c index ff54398f6643..5b383906af59 100644 --- a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c +++ b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c @@ -95,8 +95,8 @@ rk3399_vpu_mpeg2_dec_set_buffers(struct hantro_dev *vpu, struct hantro_ctx *ctx, struct vb2_buffer *src_buf, struct vb2_buffer *dst_buf, - const struct v4l2_mpeg2_sequence *seq, - const struct v4l2_mpeg2_picture *pic, + const struct v4l2_ctrl_mpeg2_sequence *seq, + const struct v4l2_ctrl_mpeg2_picture *pic, const struct v4l2_ctrl_mpeg2_slice_params *slice_params) { dma_addr_t forward_addr = 0, backward_addr = 0; @@ -156,8 +156,8 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx) struct hantro_dev *vpu = ctx->dev; struct vb2_v4l2_buffer *src_buf, *dst_buf; const struct v4l2_ctrl_mpeg2_slice_params *slice_params; - const struct v4l2_mpeg2_sequence *seq; - const struct v4l2_mpeg2_picture *pic; + const struct v4l2_ctrl_mpeg2_sequence *seq; + const struct v4l2_ctrl_mpeg2_picture *pic; u32 reg; src_buf = hantro_get_src_buf(ctx); @@ -167,8 +167,10 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx) slice_params = hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS); - seq = &slice_params->sequence; - pic = &slice_params->picture; + seq = hantro_get_ctrl(ctx, + V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE); + pic = hantro_get_ctrl(ctx, + V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE); reg = VDPU_REG_DEC_ADV_PRE_DIS(0) | VDPU_REG_DEC_SCMD_DIS(0) | diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c index 62a5407664ae..878752b30c10 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus.c @@ -29,6 +29,18 @@ #include "cedrus_hw.h" static const struct cedrus_control cedrus_controls[] = { + { + .cfg = { + .id = V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE, + }, + .codec = CEDRUS_CODEC_MPEG2, + }, + { + .cfg = { + .id = V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE, + }, + .codec = CEDRUS_CODEC_MPEG2, + }, { .cfg = { .id = V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS, diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h index 6516bff3d319..989873ccb98c 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus.h +++ b/drivers/staging/media/sunxi/cedrus/cedrus.h @@ -68,6 +68,8 @@ struct cedrus_h264_run { }; struct cedrus_mpeg2_run { + const struct v4l2_ctrl_mpeg2_sequence *sequence; + const struct v4l2_ctrl_mpeg2_picture *picture; const struct v4l2_ctrl_mpeg2_slice_params *slice_params; const struct v4l2_ctrl_mpeg2_quantisation *quantisation; }; diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c index 238f779d2ba4..f4cc6aebfac9 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c @@ -40,6 +40,10 @@ void cedrus_device_run(void *priv) switch (ctx->src_fmt.pixelformat) { case V4L2_PIX_FMT_MPEG2_SLICE: + run.mpeg2.sequence = cedrus_find_control_data(ctx, + V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE); + run.mpeg2.picture = cedrus_find_control_data(ctx, + V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE); run.mpeg2.slice_params = cedrus_find_control_data(ctx, V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS); run.mpeg2.quantisation = cedrus_find_control_data(ctx, diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c index e39a17d28c7d..65a175c6a5c2 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c @@ -51,8 +51,8 @@ static void cedrus_mpeg2_irq_disable(struct cedrus_ctx *ctx) static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run) { const struct v4l2_ctrl_mpeg2_slice_params *slice_params; - const struct v4l2_mpeg2_sequence *seq; - const struct v4l2_mpeg2_picture *pic; + const struct v4l2_ctrl_mpeg2_sequence *seq; + const struct v4l2_ctrl_mpeg2_picture *pic; const struct v4l2_ctrl_mpeg2_quantisation *quantisation; dma_addr_t src_buf_addr, dst_luma_addr, dst_chroma_addr; dma_addr_t fwd_luma_addr, fwd_chroma_addr; @@ -66,8 +66,8 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run) u32 reg; slice_params = run->mpeg2.slice_params; - seq = &slice_params->sequence; - pic = &slice_params->picture; + seq = run->mpeg2.sequence; + pic = run->mpeg2.picture; quantisation = run->mpeg2.quantisation; diff --git a/include/media/mpeg2-ctrls.h b/include/media/mpeg2-ctrls.h index d3190979d574..b4a6aa16d4c0 100644 --- a/include/media/mpeg2-ctrls.h +++ b/include/media/mpeg2-ctrls.h @@ -13,24 +13,44 @@ #define V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS (V4L2_CID_CODEC_BASE+250) #define V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION (V4L2_CID_CODEC_BASE+251) +#define V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE (V4L2_CID_CODEC_BASE+252) +#define V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE (V4L2_CID_CODEC_BASE+253) /* enum v4l2_ctrl_type type values */ -#define V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS 0x0103 -#define V4L2_CTRL_TYPE_MPEG2_QUANTISATION 0x0104 +#define V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS 0x0130 +#define V4L2_CTRL_TYPE_MPEG2_QUANTISATION 0x0131 +#define V4L2_CTRL_TYPE_MPEG2_SEQUENCE 0x0132 +#define V4L2_CTRL_TYPE_MPEG2_PICTURE 0x0133 -#define V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE 0x0001 +#define V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE 0x01 -struct v4l2_mpeg2_sequence { - /* ISO/IEC 13818-2, ITU-T Rec. H.262: Sequence header */ +/** + * struct v4l2_ctrl_mpeg2_sequence - MPEG-2 sequence header + * + * All the members on this structure match the sequence header and sequence + * extension syntaxes as specified by the MPEG-2 specification. + * + * Fields horizontal_size, vertical_size and vbv_buffer_size are a + * combination of respective _value and extension syntax elements, + * as described in section 6.3.3 "Sequence header". + * + * @horizontal_size: combination of elements horizontal_size_value and + * horizontal_size_extension. + * @vertical_size: combination of elements vertical_size_value and + * vertical_size_extension. + * @vbv_buffer_size: combination of elements vbv_buffer_size_value and + * vbv_buffer_size_extension. + * @profile_and_level_indication: see MPEG-2 specification. + * @chroma_format: see MPEG-2 specification. + * @flags: see V4L2_MPEG2_SEQ_FLAG_{}. + */ +struct v4l2_ctrl_mpeg2_sequence { __u16 horizontal_size; __u16 vertical_size; __u32 vbv_buffer_size; - - /* ISO/IEC 13818-2, ITU-T Rec. H.262: Sequence extension */ __u16 profile_and_level_indication; __u8 chroma_format; - - __u32 flags; + __u8 flags; }; #define V4L2_MPEG2_PIC_CODING_TYPE_I 1 @@ -51,33 +71,72 @@ struct v4l2_mpeg2_sequence { #define V4L2_MPEG2_PIC_FLAG_REPEAT_FIRST 0x0040 #define V4L2_MPEG2_PIC_FLAG_PROGRESSIVE 0x0080 -struct v4l2_mpeg2_picture { - /* ISO/IEC 13818-2, ITU-T Rec. H.262: Picture header */ - __u8 picture_coding_type; - - /* ISO/IEC 13818-2, ITU-T Rec. H.262: Picture coding extension */ - __u8 f_code[2][2]; - __u8 intra_dc_precision; - __u8 picture_structure; - +/** + * struct v4l2_ctrl_mpeg2_picture - MPEG-2 picture header + * + * All the members on this structure match the picture header and picture + * coding extension syntaxes as specified by the MPEG-2 specification. + * + * @flags: see V4L2_MPEG2_PIC_FLAG_{}. + * @f_code[2][2]: see MPEG-2 specification. + * @picture_coding_type: see MPEG-2 specification. + * @picture_structure: see V4L2_MPEG2_PIC_{}_FIELD. + * @intra_dc_precision: see MPEG-2 specification. + * @reserved: padding field. Should be zeroed by applications. + */ +struct v4l2_ctrl_mpeg2_picture { __u32 flags; + __u8 f_code[2][2]; + __u8 picture_coding_type; + __u8 picture_structure; + __u8 intra_dc_precision; + __u8 reserved[5]; }; +/** + * struct v4l2_ctrl_mpeg2_slice_params - MPEG-2 slice header + * + * @backward_ref_ts: timestamp of the V4L2 capture buffer to use as + * reference for backward prediction. + * @forward_ref_ts: timestamp of the V4L2 capture buffer to use as + * reference for forward prediction. These timestamp refers to the + * timestamp field in struct v4l2_buffer. Use v4l2_timeval_to_ns() + * to convert the struct timeval to a __u64. + * @quantiser_scale_code: quantiser scale integer matching an + * homonymous syntax element. + * @reserved: padding field. Should be zeroed by applications. + */ struct v4l2_ctrl_mpeg2_slice_params { __u32 bit_size; __u32 data_bit_offset; __u64 backward_ref_ts; __u64 forward_ref_ts; - - struct v4l2_mpeg2_sequence sequence; - struct v4l2_mpeg2_picture picture; - - /* ISO/IEC 13818-2, ITU-T Rec. H.262: Slice */ __u32 quantiser_scale_code; + __u32 reserved; }; +/** + * struct v4l2_ctrl_mpeg2_quantisation - MPEG-2 quantisation + * + * Quantization matrices as specified by section 6.3.7 + * "Quant matrix extension". + * + * @intra_quantiser_matrix: The quantisation matrix coefficients + * for intra-coded frames, in zigzag scanning order. It is relevant + * for both luma and chroma components, although it can be superseded + * by the chroma-specific matrix for non-4:2:0 YUV formats. + * @non_intra_quantiser_matrix: The quantisation matrix coefficients + * for non-intra-coded frames, in zigzag scanning order. It is relevant + * for both luma and chroma components, although it can be superseded + * by the chroma-specific matrix for non-4:2:0 YUV formats. + * @chroma_intra_quantiser_matrix: The quantisation matrix coefficients + * for the chominance component of intra-coded frames, in zigzag scanning + * order. Only relevant for 4:2:2 and 4:4:4 YUV formats. + * @chroma_non_intra_quantiser_matrix: The quantisation matrix coefficients + * for the chrominance component of non-intra-coded frames, in zigzag scanning + * order. Only relevant for 4:2:2 and 4:4:4 YUV formats. + */ struct v4l2_ctrl_mpeg2_quantisation { - /* ISO/IEC 13818-2, ITU-T Rec. H.262: Quant matrix extension */ __u8 intra_quantiser_matrix[64]; __u8 non_intra_quantiser_matrix[64]; __u8 chroma_intra_quantiser_matrix[64]; diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h index a38e6bd02a6a..572ff7eb7be1 100644 --- a/include/media/v4l2-ctrls.h +++ b/include/media/v4l2-ctrls.h @@ -40,6 +40,8 @@ struct video_device; * @p_u16: Pointer to a 16-bit unsigned value. * @p_u32: Pointer to a 32-bit unsigned value. * @p_char: Pointer to a string. + * @p_mpeg2_sequence: Pointer to a MPEG2 sequence structure. + * @p_mpeg2_picture: Pointer to a MPEG2 picture structure. * @p_mpeg2_slice_params: Pointer to a MPEG2 slice parameters structure. * @p_mpeg2_quantisation: Pointer to a MPEG2 quantisation data structure. * @p_fwht_params: Pointer to a FWHT stateless parameters structure. @@ -66,6 +68,8 @@ union v4l2_ctrl_ptr { u16 *p_u16; u32 *p_u32; char *p_char; + struct v4l2_ctrl_mpeg2_sequence *p_mpeg2_sequence; + struct v4l2_ctrl_mpeg2_picture *p_mpeg2_picture; struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params; struct v4l2_ctrl_mpeg2_quantisation *p_mpeg2_quantisation; struct v4l2_ctrl_fwht_params *p_fwht_params; From b6d7e8031c9c17462935329ca8b37f0da2f99da0 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Thu, 29 Apr 2021 16:48:13 +0200 Subject: [PATCH 151/394] media: uapi: mpeg2: Move reference buffer fields The forward and backwards references are specified per-picture and not per-slice. Move it to V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE. Signed-off-by: Ezequiel Garcia Tested-by: Jernej Skrabec Reviewed-by: Jernej Skrabec Tested-by: Daniel Almeida Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../media/v4l/ext-ctrls-codec.rst | 28 +++++++++---------- .../media/hantro/hantro_g1_mpeg2_dec.c | 6 ++-- .../media/hantro/rk3399_vpu_hw_mpeg2_dec.c | 6 ++-- .../staging/media/sunxi/cedrus/cedrus_mpeg2.c | 4 +-- include/media/mpeg2-ctrls.h | 16 +++++------ 5 files changed, 28 insertions(+), 32 deletions(-) diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst index f96a2dcb22cc..1765b2a1129d 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst @@ -1636,20 +1636,6 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - * - __u32 - ``data_bit_offset`` - Offset (in bits) to the video data in the current slice data. - * - __u64 - - ``backward_ref_ts`` - - Timestamp of the V4L2 capture buffer to use as backward reference, used - with B-coded and P-coded frames. The timestamp refers to the - ``timestamp`` field in struct :c:type:`v4l2_buffer`. Use the - :c:func:`v4l2_timeval_to_ns()` function to convert the struct - :c:type:`timeval` in struct :c:type:`v4l2_buffer` to a __u64. - * - __u64 - - ``forward_ref_ts`` - - Timestamp for the V4L2 capture buffer to use as forward reference, used - with B-coded frames. The timestamp refers to the ``timestamp`` field in - struct :c:type:`v4l2_buffer`. Use the :c:func:`v4l2_timeval_to_ns()` - function to convert the struct :c:type:`timeval` in struct - :c:type:`v4l2_buffer` to a __u64. * - __u32 - ``quantiser_scale_code`` - Code used to determine the quantization scale to use for the IDCT. @@ -1742,6 +1728,20 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - :stub-columns: 0 :widths: 1 1 2 + * - __u64 + - ``backward_ref_ts`` + - Timestamp of the V4L2 capture buffer to use as backward reference, used + with B-coded and P-coded frames. The timestamp refers to the + ``timestamp`` field in struct :c:type:`v4l2_buffer`. Use the + :c:func:`v4l2_timeval_to_ns()` function to convert the struct + :c:type:`timeval` in struct :c:type:`v4l2_buffer` to a __u64. + * - __u64 + - ``forward_ref_ts`` + - Timestamp for the V4L2 capture buffer to use as forward reference, used + with B-coded frames. The timestamp refers to the ``timestamp`` field in + struct :c:type:`v4l2_buffer`. Use the :c:func:`v4l2_timeval_to_ns()` + function to convert the struct :c:type:`timeval` in struct + :c:type:`v4l2_buffer` to a __u64. * - __u32 - ``flags`` - See :ref:`MPEG-2 Picture Flags `. diff --git a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c index fd61e1fae30e..19c897cbd348 100644 --- a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c +++ b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c @@ -101,12 +101,10 @@ hantro_g1_mpeg2_dec_set_buffers(struct hantro_dev *vpu, struct hantro_ctx *ctx, switch (pic->picture_coding_type) { case V4L2_MPEG2_PIC_CODING_TYPE_B: - backward_addr = hantro_get_ref(ctx, - slice_params->backward_ref_ts); + backward_addr = hantro_get_ref(ctx, pic->backward_ref_ts); fallthrough; case V4L2_MPEG2_PIC_CODING_TYPE_P: - forward_addr = hantro_get_ref(ctx, - slice_params->forward_ref_ts); + forward_addr = hantro_get_ref(ctx, pic->forward_ref_ts); } /* Source bitstream buffer */ diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c index 5b383906af59..18bd14704ebf 100644 --- a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c +++ b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c @@ -104,12 +104,10 @@ rk3399_vpu_mpeg2_dec_set_buffers(struct hantro_dev *vpu, switch (pic->picture_coding_type) { case V4L2_MPEG2_PIC_CODING_TYPE_B: - backward_addr = hantro_get_ref(ctx, - slice_params->backward_ref_ts); + backward_addr = hantro_get_ref(ctx, pic->backward_ref_ts); fallthrough; case V4L2_MPEG2_PIC_CODING_TYPE_P: - forward_addr = hantro_get_ref(ctx, - slice_params->forward_ref_ts); + forward_addr = hantro_get_ref(ctx, pic->forward_ref_ts); } /* Source bitstream buffer */ diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c index 65a175c6a5c2..16e99792cf42 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c @@ -128,14 +128,14 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run) vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); - forward_idx = vb2_find_timestamp(vq, slice_params->forward_ref_ts, 0); + forward_idx = vb2_find_timestamp(vq, pic->forward_ref_ts, 0); fwd_luma_addr = cedrus_dst_buf_addr(ctx, forward_idx, 0); fwd_chroma_addr = cedrus_dst_buf_addr(ctx, forward_idx, 1); cedrus_write(dev, VE_DEC_MPEG_FWD_REF_LUMA_ADDR, fwd_luma_addr); cedrus_write(dev, VE_DEC_MPEG_FWD_REF_CHROMA_ADDR, fwd_chroma_addr); - backward_idx = vb2_find_timestamp(vq, slice_params->backward_ref_ts, 0); + backward_idx = vb2_find_timestamp(vq, pic->backward_ref_ts, 0); bwd_luma_addr = cedrus_dst_buf_addr(ctx, backward_idx, 0); bwd_chroma_addr = cedrus_dst_buf_addr(ctx, backward_idx, 1); diff --git a/include/media/mpeg2-ctrls.h b/include/media/mpeg2-ctrls.h index b4a6aa16d4c0..922ca2243f44 100644 --- a/include/media/mpeg2-ctrls.h +++ b/include/media/mpeg2-ctrls.h @@ -77,6 +77,12 @@ struct v4l2_ctrl_mpeg2_sequence { * All the members on this structure match the picture header and picture * coding extension syntaxes as specified by the MPEG-2 specification. * + * @backward_ref_ts: timestamp of the V4L2 capture buffer to use as + * reference for backward prediction. + * @forward_ref_ts: timestamp of the V4L2 capture buffer to use as + * reference for forward prediction. These timestamp refers to the + * timestamp field in struct v4l2_buffer. Use v4l2_timeval_to_ns() + * to convert the struct timeval to a __u64. * @flags: see V4L2_MPEG2_PIC_FLAG_{}. * @f_code[2][2]: see MPEG-2 specification. * @picture_coding_type: see MPEG-2 specification. @@ -85,6 +91,8 @@ struct v4l2_ctrl_mpeg2_sequence { * @reserved: padding field. Should be zeroed by applications. */ struct v4l2_ctrl_mpeg2_picture { + __u64 backward_ref_ts; + __u64 forward_ref_ts; __u32 flags; __u8 f_code[2][2]; __u8 picture_coding_type; @@ -96,12 +104,6 @@ struct v4l2_ctrl_mpeg2_picture { /** * struct v4l2_ctrl_mpeg2_slice_params - MPEG-2 slice header * - * @backward_ref_ts: timestamp of the V4L2 capture buffer to use as - * reference for backward prediction. - * @forward_ref_ts: timestamp of the V4L2 capture buffer to use as - * reference for forward prediction. These timestamp refers to the - * timestamp field in struct v4l2_buffer. Use v4l2_timeval_to_ns() - * to convert the struct timeval to a __u64. * @quantiser_scale_code: quantiser scale integer matching an * homonymous syntax element. * @reserved: padding field. Should be zeroed by applications. @@ -109,8 +111,6 @@ struct v4l2_ctrl_mpeg2_picture { struct v4l2_ctrl_mpeg2_slice_params { __u32 bit_size; __u32 data_bit_offset; - __u64 backward_ref_ts; - __u64 forward_ref_ts; __u32 quantiser_scale_code; __u32 reserved; }; From 701a6a410c319729c86bfb696860f21adbff1bfa Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Thu, 29 Apr 2021 16:48:14 +0200 Subject: [PATCH 152/394] media: hantro/cedrus: Remove unneeded slice size and slice offset The MPEG2_SLICE_PARAMS control is designed to refer to a single slice. However, the Hantro and Cedrus drivers operate in per-frame mode, and so does the current Ffmpeg and GStreamer implementations that are tested with these two drivers. In other words, the drivers are expecting all the slices in a picture (with either frame or field structure) to be contained in the OUTPUT buffer, which means the slice size and offset shouldn't be used. Signed-off-by: Ezequiel Garcia Tested-by: Jernej Skrabec Reviewed-by: Jernej Skrabec Tested-by: Daniel Almeida Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c | 4 ++-- drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c | 4 ++-- drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c | 7 +++---- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c index 19c897cbd348..b9c8b288987a 100644 --- a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c +++ b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c @@ -203,7 +203,7 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx) G1_REG_TOPFIELDFIRST_E(pic->flags & V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST); vdpu_write_relaxed(vpu, reg, G1_SWREG(4)); - reg = G1_REG_STRM_START_BIT(slice_params->data_bit_offset) | + reg = G1_REG_STRM_START_BIT(0) | G1_REG_QSCALE_TYPE(pic->flags & V4L2_MPEG2_PIC_FLAG_Q_SCALE_TYPE) | G1_REG_CON_MV_E(pic->flags & V4L2_MPEG2_PIC_FLAG_CONCEALMENT_MV) | G1_REG_INTRA_DC_PREC(pic->intra_dc_precision) | @@ -212,7 +212,7 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx) vdpu_write_relaxed(vpu, reg, G1_SWREG(5)); reg = G1_REG_INIT_QP(1) | - G1_REG_STREAM_LEN(slice_params->bit_size >> 3); + G1_REG_STREAM_LEN(vb2_get_plane_payload(&src_buf->vb2_buf, 0)); vdpu_write_relaxed(vpu, reg, G1_SWREG(6)); reg = G1_REG_ALT_SCAN_FLAG_E(pic->flags & V4L2_MPEG2_PIC_FLAG_ALT_SCAN) | diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c index 18bd14704ebf..314269811244 100644 --- a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c +++ b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c @@ -177,7 +177,7 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx) vdpu_write_relaxed(vpu, reg, VDPU_SWREG(50)); reg = VDPU_REG_INIT_QP(1) | - VDPU_REG_STREAM_LEN(slice_params->bit_size >> 3); + VDPU_REG_STREAM_LEN(vb2_get_plane_payload(&src_buf->vb2_buf, 0)); vdpu_write_relaxed(vpu, reg, VDPU_SWREG(51)); reg = VDPU_REG_APF_THRESHOLD(8) | @@ -220,7 +220,7 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx) VDPU_REG_TOPFIELDFIRST_E(pic->flags & V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST); vdpu_write_relaxed(vpu, reg, VDPU_SWREG(120)); - reg = VDPU_REG_STRM_START_BIT(slice_params->data_bit_offset) | + reg = VDPU_REG_STRM_START_BIT(0) | VDPU_REG_QSCALE_TYPE(pic->flags & V4L2_MPEG2_PIC_FLAG_Q_SCALE_TYPE) | VDPU_REG_CON_MV_E(pic->flags & V4L2_MPEG2_PIC_FLAG_CONCEALMENT_MV) | VDPU_REG_INTRA_DC_PREC(pic->intra_dc_precision) | diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c index 16e99792cf42..fd71cb175318 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c @@ -152,10 +152,9 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run) /* Source offset and length in bits. */ - cedrus_write(dev, VE_DEC_MPEG_VLD_OFFSET, - slice_params->data_bit_offset); + cedrus_write(dev, VE_DEC_MPEG_VLD_OFFSET, 0); - reg = slice_params->bit_size - slice_params->data_bit_offset; + reg = vb2_get_plane_payload(&run->src->vb2_buf, 0) * 8; cedrus_write(dev, VE_DEC_MPEG_VLD_LEN, reg); /* Source beginning and end addresses. */ @@ -169,7 +168,7 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run) cedrus_write(dev, VE_DEC_MPEG_VLD_ADDR, reg); - reg = src_buf_addr + DIV_ROUND_UP(slice_params->bit_size, 8); + reg = src_buf_addr + vb2_get_plane_payload(&run->src->vb2_buf, 0); cedrus_write(dev, VE_DEC_MPEG_VLD_END_ADDR, reg); /* Macroblock address: start at the beginning. */ From 45f97ba1ce8059632c6f1518fda1faedd7db55fb Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Thu, 29 Apr 2021 16:48:15 +0200 Subject: [PATCH 153/394] media: uapi: mpeg2: Remove V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS The Hantro and Cedrus drivers work in frame-mode, meaning they expect all the slices in a picture (either frame or field structure) to be passed in each OUTPUT buffer. These two are the only V4L2 MPEG-2 stateless decoders currently supported. Given the VA-API drivers also work per-frame, coalescing all the MPEG-2 slices in a buffer before the decoding operation, it makes sense to not expect slice-mode drivers and therefore remove V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS. This is done to avoid carrying an unused interface. If needed, this control can be added without breaking backwards compatibility. Note that this would mean introducing a enumerator control to specify the decoding mode (see V4L2_CID_STATELESS_H264_DECODE_MODE). Signed-off-by: Ezequiel Garcia Co-developed-by: Nicolas Dufresne Signed-off-by: Nicolas Dufresne Tested-by: Jernej Skrabec Reviewed-by: Jernej Skrabec Tested-by: Daniel Almeida Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../media/v4l/ext-ctrls-codec.rst | 35 ------------------- .../media/v4l/pixfmt-compressed.rst | 6 ++-- .../media/v4l/vidioc-queryctrl.rst | 6 ---- .../media/videodev2.h.rst.exceptions | 1 - drivers/media/v4l2-core/v4l2-ctrls.c | 19 ---------- drivers/staging/media/hantro/hantro_drv.c | 5 --- .../media/hantro/hantro_g1_mpeg2_dec.c | 9 ++--- .../media/hantro/rk3399_vpu_hw_mpeg2_dec.c | 8 ++--- drivers/staging/media/sunxi/cedrus/cedrus.c | 6 ---- drivers/staging/media/sunxi/cedrus/cedrus.h | 1 - .../staging/media/sunxi/cedrus/cedrus_dec.c | 2 -- .../staging/media/sunxi/cedrus/cedrus_mpeg2.c | 2 -- include/media/mpeg2-ctrls.h | 16 --------- include/media/v4l2-ctrls.h | 2 -- 14 files changed, 7 insertions(+), 111 deletions(-) diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst index 1765b2a1129d..f10b04fba229 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst @@ -1608,41 +1608,6 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - .. _v4l2-mpeg-mpeg2: -``V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS (struct)`` - Specifies the slice parameters (as extracted from the bitstream) for the - associated MPEG-2 slice data. This includes the necessary parameters for - configuring a stateless hardware decoding pipeline for MPEG-2. - The bitstream parameters are defined according to :ref:`mpeg2part2`. - - .. note:: - - This compound control is not yet part of the public kernel API and - it is expected to change. - -.. c:type:: v4l2_ctrl_mpeg2_slice_params - -.. tabularcolumns:: |p{5.6cm}|p{4.6cm}|p{7.1cm}| - -.. cssclass:: longtable - -.. flat-table:: struct v4l2_ctrl_mpeg2_slice_params - :header-rows: 0 - :stub-columns: 0 - :widths: 1 1 2 - - * - __u32 - - ``bit_size`` - - Size (in bits) of the current slice data. - * - __u32 - - ``data_bit_offset`` - - Offset (in bits) to the video data in the current slice data. - * - __u32 - - ``quantiser_scale_code`` - - Code used to determine the quantization scale to use for the IDCT. - * - __u8 - - ``reserved`` - - Applications and drivers must set this to zero. - ``V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE (struct)`` Specifies the sequence parameters (as extracted from the bitstream) for the associated MPEG-2 slice data. This includes fields matching the syntax diff --git a/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst b/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst index bbbacbd65d6f..6c10a062adac 100644 --- a/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst +++ b/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst @@ -114,9 +114,9 @@ Compressed Formats This format is adapted for stateless video decoders that implement a MPEG-2 pipeline (using the :ref:`mem2mem` and :ref:`media-request-api`). Metadata associated with the frame to decode is required to be passed - through the ``V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE``, - ``V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE``, and ``V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS`` - controls. Quantisation matrices can optionally be specified through the + through the ``V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE`` and + ``V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE`` controls. + Quantisation matrices can optionally be specified through the ``V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION`` control. See the :ref:`associated Codec Control IDs `. Exactly one output and one capture buffer must be provided for use with diff --git a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst index afc1505a3a7e..07e54029e1e9 100644 --- a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst +++ b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst @@ -417,12 +417,6 @@ See also the examples in :ref:`control`. - any - An unsigned 32-bit valued control ranging from minimum to maximum inclusive. The step value indicates the increment between values. - * - ``V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS`` - - n/a - - n/a - - n/a - - A struct :c:type:`v4l2_ctrl_mpeg2_slice_params`, containing MPEG-2 - slice parameters for stateless video decoders. * - ``V4L2_CTRL_TYPE_MPEG2_QUANTISATION`` - n/a - n/a diff --git a/Documentation/userspace-api/media/videodev2.h.rst.exceptions b/Documentation/userspace-api/media/videodev2.h.rst.exceptions index 928fdc419ee3..2217b56c2686 100644 --- a/Documentation/userspace-api/media/videodev2.h.rst.exceptions +++ b/Documentation/userspace-api/media/videodev2.h.rst.exceptions @@ -136,7 +136,6 @@ replace symbol V4L2_CTRL_TYPE_U32 :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_U8 :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_MPEG2_SEQUENCE :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_MPEG2_PICTURE :c:type:`v4l2_ctrl_type` -replace symbol V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_MPEG2_QUANTISATION :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_H264_SPS :c:type:`v4l2_ctrl_type` replace symbol V4L2_CTRL_TYPE_H264_PPS :c:type:`v4l2_ctrl_type` diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index 59b16f70b093..6a033102d31b 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -979,7 +979,6 @@ const char *v4l2_ctrl_get_name(u32 id) case V4L2_CID_MPEG_VIDEO_USE_LTR_FRAMES: return "Use LTR Frames"; case V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE: return "MPEG-2 Sequence Header"; case V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE: return "MPEG-2 Picture Header"; - case V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS: return "MPEG-2 Slice Parameters"; case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION: return "MPEG-2 Quantisation Matrices"; case V4L2_CID_FWHT_I_FRAME_QP: return "FWHT I-Frame QP Value"; case V4L2_CID_FWHT_P_FRAME_QP: return "FWHT P-Frame QP Value"; @@ -1507,9 +1506,6 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, case V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE: *type = V4L2_CTRL_TYPE_MPEG2_PICTURE; break; - case V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS: - *type = V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS; - break; case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION: *type = V4L2_CTRL_TYPE_MPEG2_QUANTISATION; break; @@ -1723,11 +1719,6 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx, else memset(p, 0, ctrl->elem_size); - /* - * The cast is needed to get rid of a gcc warning complaining that - * V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS is not part of the - * v4l2_ctrl_type enum. - */ switch ((u32)ctrl->type) { case V4L2_CTRL_TYPE_MPEG2_SEQUENCE: p_mpeg2_sequence = p; @@ -1925,7 +1916,6 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, { struct v4l2_ctrl_mpeg2_sequence *p_mpeg2_sequence; struct v4l2_ctrl_mpeg2_picture *p_mpeg2_picture; - struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params; struct v4l2_ctrl_vp8_frame *p_vp8_frame; struct v4l2_ctrl_fwht_params *p_fwht_params; struct v4l2_ctrl_h264_sps *p_h264_sps; @@ -1988,12 +1978,6 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, zero_reserved(*p_mpeg2_picture); break; - case V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS: - p_mpeg2_slice_params = p; - - zero_reserved(*p_mpeg2_slice_params); - break; - case V4L2_CTRL_TYPE_MPEG2_QUANTISATION: break; @@ -2966,9 +2950,6 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, case V4L2_CTRL_TYPE_MPEG2_PICTURE: elem_size = sizeof(struct v4l2_ctrl_mpeg2_picture); break; - case V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS: - elem_size = sizeof(struct v4l2_ctrl_mpeg2_slice_params); - break; case V4L2_CTRL_TYPE_MPEG2_QUANTISATION: elem_size = sizeof(struct v4l2_ctrl_mpeg2_quantisation); break; diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c index 4505aac2b9bb..dc9478ac7141 100644 --- a/drivers/staging/media/hantro/hantro_drv.c +++ b/drivers/staging/media/hantro/hantro_drv.c @@ -305,11 +305,6 @@ static const struct hantro_ctrl controls[] = { .cfg = { .id = V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE, }, - }, { - .codec = HANTRO_MPEG2_DECODER, - .cfg = { - .id = V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS, - }, }, { .codec = HANTRO_MPEG2_DECODER, .cfg = { diff --git a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c index b9c8b288987a..25d912cbe2ff 100644 --- a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c +++ b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c @@ -93,8 +93,7 @@ hantro_g1_mpeg2_dec_set_buffers(struct hantro_dev *vpu, struct hantro_ctx *ctx, struct vb2_buffer *src_buf, struct vb2_buffer *dst_buf, const struct v4l2_ctrl_mpeg2_sequence *seq, - const struct v4l2_ctrl_mpeg2_picture *pic, - const struct v4l2_ctrl_mpeg2_slice_params *slice_params) + const struct v4l2_ctrl_mpeg2_picture *pic) { dma_addr_t forward_addr = 0, backward_addr = 0; dma_addr_t current_addr, addr; @@ -150,7 +149,6 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx) { struct hantro_dev *vpu = ctx->dev; struct vb2_v4l2_buffer *src_buf, *dst_buf; - const struct v4l2_ctrl_mpeg2_slice_params *slice_params; const struct v4l2_ctrl_mpeg2_sequence *seq; const struct v4l2_ctrl_mpeg2_picture *pic; u32 reg; @@ -161,8 +159,6 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx) /* Apply request controls if any */ hantro_start_prepare_run(ctx); - slice_params = hantro_get_ctrl(ctx, - V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS); seq = hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE); pic = hantro_get_ctrl(ctx, @@ -232,10 +228,9 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx) vdpu_write_relaxed(vpu, reg, G1_SWREG(55)); hantro_g1_mpeg2_dec_set_quantisation(vpu, ctx); - hantro_g1_mpeg2_dec_set_buffers(vpu, ctx, &src_buf->vb2_buf, &dst_buf->vb2_buf, - seq, pic, slice_params); + seq, pic); hantro_end_prepare_run(ctx); diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c index 314269811244..d16d76760278 100644 --- a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c +++ b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c @@ -96,8 +96,7 @@ rk3399_vpu_mpeg2_dec_set_buffers(struct hantro_dev *vpu, struct vb2_buffer *src_buf, struct vb2_buffer *dst_buf, const struct v4l2_ctrl_mpeg2_sequence *seq, - const struct v4l2_ctrl_mpeg2_picture *pic, - const struct v4l2_ctrl_mpeg2_slice_params *slice_params) + const struct v4l2_ctrl_mpeg2_picture *pic) { dma_addr_t forward_addr = 0, backward_addr = 0; dma_addr_t current_addr, addr; @@ -153,7 +152,6 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx) { struct hantro_dev *vpu = ctx->dev; struct vb2_v4l2_buffer *src_buf, *dst_buf; - const struct v4l2_ctrl_mpeg2_slice_params *slice_params; const struct v4l2_ctrl_mpeg2_sequence *seq; const struct v4l2_ctrl_mpeg2_picture *pic; u32 reg; @@ -163,8 +161,6 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx) hantro_start_prepare_run(ctx); - slice_params = hantro_get_ctrl(ctx, - V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS); seq = hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE); pic = hantro_get_ctrl(ctx, @@ -241,7 +237,7 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx) rk3399_vpu_mpeg2_dec_set_buffers(vpu, ctx, &src_buf->vb2_buf, &dst_buf->vb2_buf, - seq, pic, slice_params); + seq, pic); /* Kick the watchdog and start decoding */ hantro_end_prepare_run(ctx); diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c index 878752b30c10..4430c8fa2cc7 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus.c @@ -41,12 +41,6 @@ static const struct cedrus_control cedrus_controls[] = { }, .codec = CEDRUS_CODEC_MPEG2, }, - { - .cfg = { - .id = V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS, - }, - .codec = CEDRUS_CODEC_MPEG2, - }, { .cfg = { .id = V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION, diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h index 989873ccb98c..bbcdcd0787cf 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus.h +++ b/drivers/staging/media/sunxi/cedrus/cedrus.h @@ -70,7 +70,6 @@ struct cedrus_h264_run { struct cedrus_mpeg2_run { const struct v4l2_ctrl_mpeg2_sequence *sequence; const struct v4l2_ctrl_mpeg2_picture *picture; - const struct v4l2_ctrl_mpeg2_slice_params *slice_params; const struct v4l2_ctrl_mpeg2_quantisation *quantisation; }; diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c index f4cc6aebfac9..e98185c1f5a7 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c @@ -44,8 +44,6 @@ void cedrus_device_run(void *priv) V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE); run.mpeg2.picture = cedrus_find_control_data(ctx, V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE); - run.mpeg2.slice_params = cedrus_find_control_data(ctx, - V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS); run.mpeg2.quantisation = cedrus_find_control_data(ctx, V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION); break; diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c index fd71cb175318..5dad2f296c6d 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c @@ -50,7 +50,6 @@ static void cedrus_mpeg2_irq_disable(struct cedrus_ctx *ctx) static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run) { - const struct v4l2_ctrl_mpeg2_slice_params *slice_params; const struct v4l2_ctrl_mpeg2_sequence *seq; const struct v4l2_ctrl_mpeg2_picture *pic; const struct v4l2_ctrl_mpeg2_quantisation *quantisation; @@ -65,7 +64,6 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run) unsigned int i; u32 reg; - slice_params = run->mpeg2.slice_params; seq = run->mpeg2.sequence; pic = run->mpeg2.picture; diff --git a/include/media/mpeg2-ctrls.h b/include/media/mpeg2-ctrls.h index 922ca2243f44..a84ce088a42e 100644 --- a/include/media/mpeg2-ctrls.h +++ b/include/media/mpeg2-ctrls.h @@ -11,13 +11,11 @@ #ifndef _MPEG2_CTRLS_H_ #define _MPEG2_CTRLS_H_ -#define V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS (V4L2_CID_CODEC_BASE+250) #define V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION (V4L2_CID_CODEC_BASE+251) #define V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE (V4L2_CID_CODEC_BASE+252) #define V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE (V4L2_CID_CODEC_BASE+253) /* enum v4l2_ctrl_type type values */ -#define V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS 0x0130 #define V4L2_CTRL_TYPE_MPEG2_QUANTISATION 0x0131 #define V4L2_CTRL_TYPE_MPEG2_SEQUENCE 0x0132 #define V4L2_CTRL_TYPE_MPEG2_PICTURE 0x0133 @@ -101,20 +99,6 @@ struct v4l2_ctrl_mpeg2_picture { __u8 reserved[5]; }; -/** - * struct v4l2_ctrl_mpeg2_slice_params - MPEG-2 slice header - * - * @quantiser_scale_code: quantiser scale integer matching an - * homonymous syntax element. - * @reserved: padding field. Should be zeroed by applications. - */ -struct v4l2_ctrl_mpeg2_slice_params { - __u32 bit_size; - __u32 data_bit_offset; - __u32 quantiser_scale_code; - __u32 reserved; -}; - /** * struct v4l2_ctrl_mpeg2_quantisation - MPEG-2 quantisation * diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h index 572ff7eb7be1..215e44172c66 100644 --- a/include/media/v4l2-ctrls.h +++ b/include/media/v4l2-ctrls.h @@ -42,7 +42,6 @@ struct video_device; * @p_char: Pointer to a string. * @p_mpeg2_sequence: Pointer to a MPEG2 sequence structure. * @p_mpeg2_picture: Pointer to a MPEG2 picture structure. - * @p_mpeg2_slice_params: Pointer to a MPEG2 slice parameters structure. * @p_mpeg2_quantisation: Pointer to a MPEG2 quantisation data structure. * @p_fwht_params: Pointer to a FWHT stateless parameters structure. * @p_h264_sps: Pointer to a struct v4l2_ctrl_h264_sps. @@ -70,7 +69,6 @@ union v4l2_ctrl_ptr { char *p_char; struct v4l2_ctrl_mpeg2_sequence *p_mpeg2_sequence; struct v4l2_ctrl_mpeg2_picture *p_mpeg2_picture; - struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params; struct v4l2_ctrl_mpeg2_quantisation *p_mpeg2_quantisation; struct v4l2_ctrl_fwht_params *p_fwht_params; struct v4l2_ctrl_h264_sps *p_h264_sps; From 2f0968827a48a3b01a0cc9185abd41978d5ce918 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Thu, 29 Apr 2021 16:48:16 +0200 Subject: [PATCH 154/394] media: uapi: Move the MPEG-2 stateless control type out of staging Move the MPEG-2 stateless control types out of staging, and re-number it to avoid any confusion. Signed-off-by: Ezequiel Garcia Tested-by: Jernej Skrabec Reviewed-by: Jernej Skrabec Tested-by: Daniel Almeida Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/mpeg2-ctrls.h | 4 ---- include/uapi/linux/videodev2.h | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/media/mpeg2-ctrls.h b/include/media/mpeg2-ctrls.h index a84ce088a42e..a3d19de9e53a 100644 --- a/include/media/mpeg2-ctrls.h +++ b/include/media/mpeg2-ctrls.h @@ -16,10 +16,6 @@ #define V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE (V4L2_CID_CODEC_BASE+253) /* enum v4l2_ctrl_type type values */ -#define V4L2_CTRL_TYPE_MPEG2_QUANTISATION 0x0131 -#define V4L2_CTRL_TYPE_MPEG2_SEQUENCE 0x0132 -#define V4L2_CTRL_TYPE_MPEG2_PICTURE 0x0133 - #define V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE 0x01 /** diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 311a01cc5775..d3bb18a3a51b 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -1807,6 +1807,10 @@ enum v4l2_ctrl_type { V4L2_CTRL_TYPE_FWHT_PARAMS = 0x0220, V4L2_CTRL_TYPE_VP8_FRAME = 0x0240, + + V4L2_CTRL_TYPE_MPEG2_QUANTISATION = 0x0250, + V4L2_CTRL_TYPE_MPEG2_SEQUENCE = 0x0251, + V4L2_CTRL_TYPE_MPEG2_PICTURE = 0x0252, }; /* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */ From 3c994c6d21db2269518648f0dab21f10fd46e4ee Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Thu, 29 Apr 2021 16:48:17 +0200 Subject: [PATCH 155/394] media: controls: Log MPEG-2 stateless control in .std_log Simply print the type of the control. Signed-off-by: Ezequiel Garcia Tested-by: Jernej Skrabec Reviewed-by: Jernej Skrabec Tested-by: Daniel Almeida Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-ctrls.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index 6a033102d31b..a693ff8dc3dc 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -1873,6 +1873,15 @@ static void std_log(const struct v4l2_ctrl *ctrl) case V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY: pr_cont("HDR10_MASTERING_DISPLAY"); break; + case V4L2_CTRL_TYPE_MPEG2_QUANTISATION: + pr_cont("MPEG2_QUANTISATION"); + break; + case V4L2_CTRL_TYPE_MPEG2_SEQUENCE: + pr_cont("MPEG2_SEQUENCE"); + break; + case V4L2_CTRL_TYPE_MPEG2_PICTURE: + pr_cont("MPEG2_PICTURE"); + break; default: pr_cont("unknown type %d", ctrl->type); break; From f4815b399111d992c1118c708f464a847dfd29e2 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Thu, 29 Apr 2021 16:48:18 +0200 Subject: [PATCH 156/394] media: uapi: move MPEG-2 stateless controls out of staging Until now, the MPEG-2 V4L2 API was not exported as a public API, and only defined in a private media header (media/mpeg2-ctrls.h). After reviewing the MPEG-2 specification in detail, and reworking the controls so they match the MPEG-2 semantics properly, we can consider it ready. Signed-off-by: Ezequiel Garcia Tested-by: Jernej Skrabec Reviewed-by: Jernej Skrabec Tested-by: Daniel Almeida Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../media/v4l/ext-ctrls-codec-stateless.rst | 214 +++++++++++++++++ .../media/v4l/ext-ctrls-codec.rst | 216 ------------------ .../media/v4l/pixfmt-compressed.rst | 10 +- .../media/v4l/vidioc-g-ext-ctrls.rst | 12 + drivers/media/v4l2-core/v4l2-ctrls.c | 12 +- drivers/staging/media/hantro/hantro_drv.c | 6 +- .../media/hantro/hantro_g1_mpeg2_dec.c | 6 +- .../media/hantro/rk3399_vpu_hw_mpeg2_dec.c | 6 +- drivers/staging/media/sunxi/cedrus/cedrus.c | 6 +- .../staging/media/sunxi/cedrus/cedrus_dec.c | 6 +- include/media/mpeg2-ctrls.h | 126 ---------- include/media/v4l2-ctrls.h | 1 - include/uapi/linux/v4l2-controls.h | 112 +++++++++ include/uapi/linux/videodev2.h | 3 + 14 files changed, 367 insertions(+), 369 deletions(-) delete mode 100644 include/media/mpeg2-ctrls.h diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst index 3fc04daa9ffb..2aa508ffb6b9 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst @@ -1244,3 +1244,217 @@ FWHT Flags * - __u8 - ``padding[3]`` - Applications and drivers must set this to zero. + +.. _v4l2-codec-stateless-mpeg2: + +``V4L2_CID_STATELESS_MPEG2_SEQUENCE (struct)`` + Specifies the sequence parameters (as extracted from the bitstream) for the + associated MPEG-2 slice data. This includes fields matching the syntax + elements from the sequence header and sequence extension parts of the + bitstream as specified by :ref:`mpeg2part2`. + +.. c:type:: v4l2_ctrl_mpeg2_sequence + +.. raw:: latex + + \small + +.. cssclass:: longtable + +.. tabularcolumns:: |p{1.4cm}|p{6.5cm}|p{9.4cm}| + +.. flat-table:: struct v4l2_ctrl_mpeg2_sequence + :header-rows: 0 + :stub-columns: 0 + :widths: 1 1 2 + + * - __u16 + - ``horizontal_size`` + - The width of the displayable part of the frame's luminance component. + * - __u16 + - ``vertical_size`` + - The height of the displayable part of the frame's luminance component. + * - __u32 + - ``vbv_buffer_size`` + - Used to calculate the required size of the video buffering verifier, + defined (in bits) as: 16 * 1024 * vbv_buffer_size. + * - __u16 + - ``profile_and_level_indication`` + - The current profile and level indication as extracted from the + bitstream. + * - __u8 + - ``chroma_format`` + - The chrominance sub-sampling format (1: 4:2:0, 2: 4:2:2, 3: 4:4:4). + * - __u8 + - ``flags`` + - See :ref:`MPEG-2 Sequence Flags `. + +.. _mpeg2_sequence_flags: + +``MPEG-2 Sequence Flags`` + +.. cssclass:: longtable + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + :widths: 1 1 2 + + * - ``V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE`` + - 0x01 + - Indication that all the frames for the sequence are progressive instead + of interlaced. + +.. raw:: latex + + \normalsize + +``V4L2_CID_STATELESS_MPEG2_PICTURE (struct)`` + Specifies the picture parameters (as extracted from the bitstream) for the + associated MPEG-2 slice data. This includes fields matching the syntax + elements from the picture header and picture coding extension parts of the + bitstream as specified by :ref:`mpeg2part2`. + +.. c:type:: v4l2_ctrl_mpeg2_picture + +.. raw:: latex + + \small + +.. cssclass:: longtable + +.. tabularcolumns:: |p{1.0cm}|p{5.6cm}|p{10.7cm}| + +.. flat-table:: struct v4l2_ctrl_mpeg2_picture + :header-rows: 0 + :stub-columns: 0 + :widths: 1 1 2 + + * - __u64 + - ``backward_ref_ts`` + - Timestamp of the V4L2 capture buffer to use as backward reference, used + with B-coded and P-coded frames. The timestamp refers to the + ``timestamp`` field in struct :c:type:`v4l2_buffer`. Use the + :c:func:`v4l2_timeval_to_ns()` function to convert the struct + :c:type:`timeval` in struct :c:type:`v4l2_buffer` to a __u64. + * - __u64 + - ``forward_ref_ts`` + - Timestamp for the V4L2 capture buffer to use as forward reference, used + with B-coded frames. The timestamp refers to the ``timestamp`` field in + struct :c:type:`v4l2_buffer`. Use the :c:func:`v4l2_timeval_to_ns()` + function to convert the struct :c:type:`timeval` in struct + :c:type:`v4l2_buffer` to a __u64. + * - __u32 + - ``flags`` + - See :ref:`MPEG-2 Picture Flags `. + * - __u8 + - ``f_code[2][2]`` + - Motion vector codes. + * - __u8 + - ``picture_coding_type`` + - Picture coding type for the frame covered by the current slice + (V4L2_MPEG2_PICTURE_CODING_TYPE_I, V4L2_MPEG2_PICTURE_CODING_TYPE_P or + V4L2_MPEG2_PICTURE_CODING_TYPE_B). + * - __u8 + - ``picture_structure`` + - Picture structure (1: interlaced top field, 2: interlaced bottom field, + 3: progressive frame). + * - __u8 + - ``intra_dc_precision`` + - Precision of Discrete Cosine transform (0: 8 bits precision, + 1: 9 bits precision, 2: 10 bits precision, 3: 11 bits precision). + * - __u8 + - ``reserved[5]`` + - Applications and drivers must set this to zero. + +.. _mpeg2_picture_flags: + +``MPEG-2 Picture Flags`` + +.. cssclass:: longtable + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + :widths: 1 1 2 + + * - ``V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST`` + - 0x00000001 + - If set and it's an interlaced stream, top field is output first. + * - ``V4L2_MPEG2_PIC_FLAG_FRAME_PRED_DCT`` + - 0x00000002 + - If set only frame-DCT and frame prediction are used. + * - ``V4L2_MPEG2_PIC_FLAG_CONCEALMENT_MV`` + - 0x00000004 + - If set motion vectors are coded for intra macroblocks. + * - ``V4L2_MPEG2_PIC_FLAG_Q_SCALE_TYPE`` + - 0x00000008 + - This flag affects the inverse quantization process. + * - ``V4L2_MPEG2_PIC_FLAG_INTRA_VLC`` + - 0x00000010 + - This flag affects the decoding of transform coefficient data. + * - ``V4L2_MPEG2_PIC_FLAG_ALT_SCAN`` + - 0x00000020 + - This flag affects the decoding of transform coefficient data. + * - ``V4L2_MPEG2_PIC_FLAG_REPEAT_FIRST`` + - 0x00000040 + - This flag affects the decoding process of progressive frames. + * - ``V4L2_MPEG2_PIC_FLAG_PROGRESSIVE`` + - 0x00000080 + - Indicates whether the current frame is progressive. + +.. raw:: latex + + \normalsize + +``V4L2_CID_STATELESS_MPEG2_QUANTISATION (struct)`` + Specifies quantisation matrices, in zigzag scanning order, for the + associated MPEG-2 slice data. This control is initialized by the kernel + to the matrices default values. If a bitstream transmits a user-defined + quantisation matrices load, applications are expected to use this control. + Applications are also expected to set the control loading the default + values, if the quantisation matrices need to be reset, for instance on a + sequence header. This process is specified by section 6.3.7. + "Quant matrix extension" of the specification. + +.. c:type:: v4l2_ctrl_mpeg2_quantisation + +.. tabularcolumns:: |p{0.8cm}|p{8.0cm}|p{8.5cm}| + +.. cssclass:: longtable + +.. raw:: latex + + \small + +.. flat-table:: struct v4l2_ctrl_mpeg2_quantisation + :header-rows: 0 + :stub-columns: 0 + :widths: 1 1 2 + + * - __u8 + - ``intra_quantiser_matrix[64]`` + - The quantisation matrix coefficients for intra-coded frames, in zigzag + scanning order. It is relevant for both luma and chroma components, + although it can be superseded by the chroma-specific matrix for + non-4:2:0 YUV formats. + * - __u8 + - ``non_intra_quantiser_matrix[64]`` + - The quantisation matrix coefficients for non-intra-coded frames, in + zigzag scanning order. It is relevant for both luma and chroma + components, although it can be superseded by the chroma-specific matrix + for non-4:2:0 YUV formats. + * - __u8 + - ``chroma_intra_quantiser_matrix[64]`` + - The quantisation matrix coefficients for the chominance component of + intra-coded frames, in zigzag scanning order. Only relevant for + non-4:2:0 YUV formats. + * - __u8 + - ``chroma_non_intra_quantiser_matrix[64]`` + - The quantisation matrix coefficients for the chrominance component of + non-intra-coded frames, in zigzag scanning order. Only relevant for + non-4:2:0 YUV formats. + +.. raw:: latex + + \normalsize diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst index f10b04fba229..0b8061666c57 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst @@ -1606,222 +1606,6 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - ``V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L6_BR (integer)`` Indicates bit rate (bps) for hierarchical coding layer 6 for H264 encoder. -.. _v4l2-mpeg-mpeg2: - -``V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE (struct)`` - Specifies the sequence parameters (as extracted from the bitstream) for the - associated MPEG-2 slice data. This includes fields matching the syntax - elements from the sequence header and sequence extension parts of the - bitstream as specified by :ref:`mpeg2part2`. - - .. note:: - - This compound control is not yet part of the public kernel API and - it is expected to change. - -.. c:type:: v4l2_ctrl_mpeg2_sequence - -.. cssclass:: longtable - -.. tabularcolumns:: |p{1.4cm}|p{6.5cm}|p{9.4cm}| - -.. flat-table:: struct v4l2_ctrl_mpeg2_sequence - :header-rows: 0 - :stub-columns: 0 - :widths: 1 1 2 - - * - __u16 - - ``horizontal_size`` - - The width of the displayable part of the frame's luminance component. - * - __u16 - - ``vertical_size`` - - The height of the displayable part of the frame's luminance component. - * - __u32 - - ``vbv_buffer_size`` - - Used to calculate the required size of the video buffering verifier, - defined (in bits) as: 16 * 1024 * vbv_buffer_size. - * - __u16 - - ``profile_and_level_indication`` - - The current profile and level indication as extracted from the - bitstream. - * - __u8 - - ``chroma_format`` - - The chrominance sub-sampling format (1: 4:2:0, 2: 4:2:2, 3: 4:4:4). - * - __u8 - - ``flags`` - - See :ref:`MPEG-2 Sequence Flags `. - -.. _mpeg2_sequence_flags: - -``MPEG-2 Sequence Flags`` - -.. cssclass:: longtable - -.. flat-table:: - :header-rows: 0 - :stub-columns: 0 - :widths: 1 1 2 - - * - ``V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE`` - - 0x01 - - Indication that all the frames for the sequence are progressive instead - of interlaced. - -``V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE (struct)`` - Specifies the picture parameters (as extracted from the bitstream) for the - associated MPEG-2 slice data. This includes fields matching the syntax - elements from the picture header and picture coding extension parts of the - bitstream as specified by :ref:`mpeg2part2`. - - .. note:: - - This compound control is not yet part of the public kernel API and - it is expected to change. - -.. c:type:: v4l2_ctrl_mpeg2_picture - -.. raw:: latex - - \small - -.. cssclass:: longtable - -.. tabularcolumns:: |p{1.0cm}|p{5.6cm}|p{10.7cm}| - -.. flat-table:: struct v4l2_ctrl_mpeg2_picture - :header-rows: 0 - :stub-columns: 0 - :widths: 1 1 2 - - * - __u64 - - ``backward_ref_ts`` - - Timestamp of the V4L2 capture buffer to use as backward reference, used - with B-coded and P-coded frames. The timestamp refers to the - ``timestamp`` field in struct :c:type:`v4l2_buffer`. Use the - :c:func:`v4l2_timeval_to_ns()` function to convert the struct - :c:type:`timeval` in struct :c:type:`v4l2_buffer` to a __u64. - * - __u64 - - ``forward_ref_ts`` - - Timestamp for the V4L2 capture buffer to use as forward reference, used - with B-coded frames. The timestamp refers to the ``timestamp`` field in - struct :c:type:`v4l2_buffer`. Use the :c:func:`v4l2_timeval_to_ns()` - function to convert the struct :c:type:`timeval` in struct - :c:type:`v4l2_buffer` to a __u64. - * - __u32 - - ``flags`` - - See :ref:`MPEG-2 Picture Flags `. - * - __u8 - - ``f_code[2][2]`` - - Motion vector codes. - * - __u8 - - ``picture_coding_type`` - - Picture coding type for the frame covered by the current slice - (V4L2_MPEG2_PICTURE_CODING_TYPE_I, V4L2_MPEG2_PICTURE_CODING_TYPE_P or - V4L2_MPEG2_PICTURE_CODING_TYPE_B). - * - __u8 - - ``picture_structure`` - - Picture structure (1: interlaced top field, 2: interlaced bottom field, - 3: progressive frame). - * - __u8 - - ``intra_dc_precision`` - - Precision of Discrete Cosine transform (0: 8 bits precision, - 1: 9 bits precision, 2: 10 bits precision, 3: 11 bits precision). - * - __u8 - - ``reserved[5]`` - - Applications and drivers must set this to zero. - - -.. _mpeg2_picture_flags: - -``MPEG-2 Picture Flags`` - -.. cssclass:: longtable - -.. flat-table:: - :header-rows: 0 - :stub-columns: 0 - :widths: 1 1 2 - - * - ``V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST`` - - 0x00000001 - - If set and it's an interlaced stream, top field is output first. - * - ``V4L2_MPEG2_PIC_FLAG_FRAME_PRED_DCT`` - - 0x00000002 - - If set only frame-DCT and frame prediction are used. - * - ``V4L2_MPEG2_PIC_FLAG_CONCEALMENT_MV`` - - 0x00000004 - - If set motion vectors are coded for intra macroblocks. - * - ``V4L2_MPEG2_PIC_FLAG_Q_SCALE_TYPE`` - - 0x00000008 - - This flag affects the inverse quantization process. - * - ``V4L2_MPEG2_PIC_FLAG_INTRA_VLC`` - - 0x00000010 - - This flag affects the decoding of transform coefficient data. - * - ``V4L2_MPEG2_PIC_FLAG_ALT_SCAN`` - - 0x00000020 - - This flag affects the decoding of transform coefficient data. - * - ``V4L2_MPEG2_PIC_FLAG_REPEAT_FIRST`` - - 0x00000040 - - This flag affects the decoding process of progressive frames. - * - ``V4L2_MPEG2_PIC_FLAG_PROGRESSIVE`` - - 0x00000080 - - Indicates whether the current frame is progressive. - -.. raw:: latex - - \normalsize - -``V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION (struct)`` - Specifies quantisation matrices (as extracted from the bitstream) for the - associated MPEG-2 slice data. - - .. note:: - - This compound control is not yet part of the public kernel API and - it is expected to change. - -.. c:type:: v4l2_ctrl_mpeg2_quantisation - -.. tabularcolumns:: |p{0.8cm}|p{8.0cm}|p{8.5cm}| - -.. cssclass:: longtable - -.. raw:: latex - - \small - -.. flat-table:: struct v4l2_ctrl_mpeg2_quantisation - :header-rows: 0 - :stub-columns: 0 - :widths: 1 1 2 - - * - __u8 - - ``intra_quantiser_matrix[64]`` - - The quantisation matrix coefficients for intra-coded frames, in zigzag - scanning order. It is relevant for both luma and chroma components, - although it can be superseded by the chroma-specific matrix for - non-4:2:0 YUV formats. - * - __u8 - - ``non_intra_quantiser_matrix[64]`` - - The quantisation matrix coefficients for non-intra-coded frames, in - zigzag scanning order. It is relevant for both luma and chroma - components, although it can be superseded by the chroma-specific matrix - for non-4:2:0 YUV formats. - * - __u8 - - ``chroma_intra_quantiser_matrix[64]`` - - The quantisation matrix coefficients for the chominance component of - intra-coded frames, in zigzag scanning order. Only relevant for - non-4:2:0 YUV formats. - * - __u8 - - ``chroma_non_intra_quantiser_matrix[64]`` - - The quantisation matrix coefficients for the chrominance component of - non-intra-coded frames, in zigzag scanning order. Only relevant for - non-4:2:0 YUV formats. - -.. raw:: latex - - \normalsize - ``V4L2_CID_FWHT_I_FRAME_QP (integer)`` Quantization parameter for an I frame for FWHT. Valid range: from 1 to 31. diff --git a/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst b/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst index 6c10a062adac..0ede39907ee2 100644 --- a/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst +++ b/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst @@ -112,13 +112,13 @@ Compressed Formats - 'MG2S' - MPEG-2 parsed slice data, as extracted from the MPEG-2 bitstream. This format is adapted for stateless video decoders that implement a - MPEG-2 pipeline (using the :ref:`mem2mem` and :ref:`media-request-api`). + MPEG-2 pipeline with the :ref:`stateless_decoder`. Metadata associated with the frame to decode is required to be passed - through the ``V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE`` and - ``V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE`` controls. + through the ``V4L2_CID_STATELESS_MPEG2_SEQUENCE`` and + ``V4L2_CID_STATELESS_MPEG2_PICTURE`` controls. Quantisation matrices can optionally be specified through the - ``V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION`` control. - See the :ref:`associated Codec Control IDs `. + ``V4L2_CID_STATELESS_MPEG2_QUANTISATION`` control. + See the :ref:`associated Codec Control IDs `. Exactly one output and one capture buffer must be provided for use with this pixel format. The output buffer must contain the appropriate number of macroblocks to decode a full corresponding frame to the matching diff --git a/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst b/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst index 3ba22983d21f..2d6bc8d94380 100644 --- a/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst +++ b/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst @@ -221,6 +221,18 @@ still cause this situation. - ``p_vp8_frame`` - A pointer to a struct :c:type:`v4l2_ctrl_vp8_frame`. Valid if this control is of type ``V4L2_CTRL_TYPE_VP8_FRAME``. + * - struct :c:type:`v4l2_ctrl_mpeg2_sequence` * + - ``p_mpeg2_sequence`` + - A pointer to a struct :c:type:`v4l2_ctrl_mpeg2_sequence`. Valid if this control is + of type ``V4L2_CTRL_TYPE_MPEG2_SEQUENCE``. + * - struct :c:type:`v4l2_ctrl_mpeg2_picture` * + - ``p_mpeg2_picture`` + - A pointer to a struct :c:type:`v4l2_ctrl_mpeg2_picture`. Valid if this control is + of type ``V4L2_CTRL_TYPE_MPEG2_PICTURE``. + * - struct :c:type:`v4l2_ctrl_mpeg2_quantisation` * + - ``p_mpeg2_quantisation`` + - A pointer to a struct :c:type:`v4l2_ctrl_mpeg2_quantisation`. Valid if this control is + of type ``V4L2_CTRL_TYPE_MPEG2_QUANTISATION``. * - struct :c:type:`v4l2_ctrl_hdr10_cll_info` * - ``p_hdr10_cll`` - A pointer to a struct :c:type:`v4l2_ctrl_hdr10_cll_info`. Valid if this control is diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index a693ff8dc3dc..d4e2c7318ee6 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -977,9 +977,6 @@ const char *v4l2_ctrl_get_name(u32 id) case V4L2_CID_MPEG_VIDEO_LTR_COUNT: return "LTR Count"; case V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX: return "Frame LTR Index"; case V4L2_CID_MPEG_VIDEO_USE_LTR_FRAMES: return "Use LTR Frames"; - case V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE: return "MPEG-2 Sequence Header"; - case V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE: return "MPEG-2 Picture Header"; - case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION: return "MPEG-2 Quantisation Matrices"; case V4L2_CID_FWHT_I_FRAME_QP: return "FWHT I-Frame QP Value"; case V4L2_CID_FWHT_P_FRAME_QP: return "FWHT P-Frame QP Value"; @@ -1228,6 +1225,9 @@ const char *v4l2_ctrl_get_name(u32 id) case V4L2_CID_STATELESS_H264_DECODE_PARAMS: return "H264 Decode Parameters"; case V4L2_CID_STATELESS_FWHT_PARAMS: return "FWHT Stateless Parameters"; case V4L2_CID_STATELESS_VP8_FRAME: return "VP8 Frame Parameters"; + case V4L2_CID_STATELESS_MPEG2_SEQUENCE: return "MPEG-2 Sequence Header"; + case V4L2_CID_STATELESS_MPEG2_PICTURE: return "MPEG-2 Picture Header"; + case V4L2_CID_STATELESS_MPEG2_QUANTISATION: return "MPEG-2 Quantisation Matrices"; /* Colorimetry controls */ /* Keep the order of the 'case's the same as in v4l2-controls.h! */ @@ -1500,13 +1500,13 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, case V4L2_CID_RDS_TX_ALT_FREQS: *type = V4L2_CTRL_TYPE_U32; break; - case V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE: + case V4L2_CID_STATELESS_MPEG2_SEQUENCE: *type = V4L2_CTRL_TYPE_MPEG2_SEQUENCE; break; - case V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE: + case V4L2_CID_STATELESS_MPEG2_PICTURE: *type = V4L2_CTRL_TYPE_MPEG2_PICTURE; break; - case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION: + case V4L2_CID_STATELESS_MPEG2_QUANTISATION: *type = V4L2_CTRL_TYPE_MPEG2_QUANTISATION; break; case V4L2_CID_STATELESS_FWHT_PARAMS: diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c index dc9478ac7141..2f6b01c7a6a0 100644 --- a/drivers/staging/media/hantro/hantro_drv.c +++ b/drivers/staging/media/hantro/hantro_drv.c @@ -298,17 +298,17 @@ static const struct hantro_ctrl controls[] = { }, { .codec = HANTRO_MPEG2_DECODER, .cfg = { - .id = V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE, + .id = V4L2_CID_STATELESS_MPEG2_SEQUENCE, }, }, { .codec = HANTRO_MPEG2_DECODER, .cfg = { - .id = V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE, + .id = V4L2_CID_STATELESS_MPEG2_PICTURE, }, }, { .codec = HANTRO_MPEG2_DECODER, .cfg = { - .id = V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION, + .id = V4L2_CID_STATELESS_MPEG2_QUANTISATION, }, }, { .codec = HANTRO_VP8_DECODER, diff --git a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c index 25d912cbe2ff..6ee1a19d189b 100644 --- a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c +++ b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c @@ -83,7 +83,7 @@ hantro_g1_mpeg2_dec_set_quantisation(struct hantro_dev *vpu, { struct v4l2_ctrl_mpeg2_quantisation *q; - q = hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION); + q = hantro_get_ctrl(ctx, V4L2_CID_STATELESS_MPEG2_QUANTISATION); hantro_mpeg2_dec_copy_qtable(ctx->mpeg2_dec.qtable.cpu, q); vdpu_write_relaxed(vpu, ctx->mpeg2_dec.qtable.dma, G1_REG_QTABLE_BASE); } @@ -160,9 +160,9 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx) hantro_start_prepare_run(ctx); seq = hantro_get_ctrl(ctx, - V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE); + V4L2_CID_STATELESS_MPEG2_SEQUENCE); pic = hantro_get_ctrl(ctx, - V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE); + V4L2_CID_STATELESS_MPEG2_PICTURE); reg = G1_REG_DEC_AXI_RD_ID(0) | G1_REG_DEC_TIMEOUT_E(1) | diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c index d16d76760278..2527dce7eb18 100644 --- a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c +++ b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c @@ -85,7 +85,7 @@ rk3399_vpu_mpeg2_dec_set_quantisation(struct hantro_dev *vpu, { struct v4l2_ctrl_mpeg2_quantisation *q; - q = hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION); + q = hantro_get_ctrl(ctx, V4L2_CID_STATELESS_MPEG2_QUANTISATION); hantro_mpeg2_dec_copy_qtable(ctx->mpeg2_dec.qtable.cpu, q); vdpu_write_relaxed(vpu, ctx->mpeg2_dec.qtable.dma, VDPU_REG_QTABLE_BASE); } @@ -162,9 +162,9 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx) hantro_start_prepare_run(ctx); seq = hantro_get_ctrl(ctx, - V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE); + V4L2_CID_STATELESS_MPEG2_SEQUENCE); pic = hantro_get_ctrl(ctx, - V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE); + V4L2_CID_STATELESS_MPEG2_PICTURE); reg = VDPU_REG_DEC_ADV_PRE_DIS(0) | VDPU_REG_DEC_SCMD_DIS(0) | diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c index 4430c8fa2cc7..fa348c09f844 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus.c @@ -31,19 +31,19 @@ static const struct cedrus_control cedrus_controls[] = { { .cfg = { - .id = V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE, + .id = V4L2_CID_STATELESS_MPEG2_SEQUENCE, }, .codec = CEDRUS_CODEC_MPEG2, }, { .cfg = { - .id = V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE, + .id = V4L2_CID_STATELESS_MPEG2_PICTURE, }, .codec = CEDRUS_CODEC_MPEG2, }, { .cfg = { - .id = V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION, + .id = V4L2_CID_STATELESS_MPEG2_QUANTISATION, }, .codec = CEDRUS_CODEC_MPEG2, }, diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c index e98185c1f5a7..97e410d92506 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c @@ -41,11 +41,11 @@ void cedrus_device_run(void *priv) switch (ctx->src_fmt.pixelformat) { case V4L2_PIX_FMT_MPEG2_SLICE: run.mpeg2.sequence = cedrus_find_control_data(ctx, - V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE); + V4L2_CID_STATELESS_MPEG2_SEQUENCE); run.mpeg2.picture = cedrus_find_control_data(ctx, - V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE); + V4L2_CID_STATELESS_MPEG2_PICTURE); run.mpeg2.quantisation = cedrus_find_control_data(ctx, - V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION); + V4L2_CID_STATELESS_MPEG2_QUANTISATION); break; case V4L2_PIX_FMT_H264_SLICE: diff --git a/include/media/mpeg2-ctrls.h b/include/media/mpeg2-ctrls.h deleted file mode 100644 index a3d19de9e53a..000000000000 --- a/include/media/mpeg2-ctrls.h +++ /dev/null @@ -1,126 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * These are the MPEG2 state controls for use with stateless MPEG-2 - * codec drivers. - * - * It turns out that these structs are not stable yet and will undergo - * more changes. So keep them private until they are stable and ready to - * become part of the official public API. - */ - -#ifndef _MPEG2_CTRLS_H_ -#define _MPEG2_CTRLS_H_ - -#define V4L2_CID_MPEG_VIDEO_MPEG2_QUANTISATION (V4L2_CID_CODEC_BASE+251) -#define V4L2_CID_MPEG_VIDEO_MPEG2_SEQUENCE (V4L2_CID_CODEC_BASE+252) -#define V4L2_CID_MPEG_VIDEO_MPEG2_PICTURE (V4L2_CID_CODEC_BASE+253) - -/* enum v4l2_ctrl_type type values */ -#define V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE 0x01 - -/** - * struct v4l2_ctrl_mpeg2_sequence - MPEG-2 sequence header - * - * All the members on this structure match the sequence header and sequence - * extension syntaxes as specified by the MPEG-2 specification. - * - * Fields horizontal_size, vertical_size and vbv_buffer_size are a - * combination of respective _value and extension syntax elements, - * as described in section 6.3.3 "Sequence header". - * - * @horizontal_size: combination of elements horizontal_size_value and - * horizontal_size_extension. - * @vertical_size: combination of elements vertical_size_value and - * vertical_size_extension. - * @vbv_buffer_size: combination of elements vbv_buffer_size_value and - * vbv_buffer_size_extension. - * @profile_and_level_indication: see MPEG-2 specification. - * @chroma_format: see MPEG-2 specification. - * @flags: see V4L2_MPEG2_SEQ_FLAG_{}. - */ -struct v4l2_ctrl_mpeg2_sequence { - __u16 horizontal_size; - __u16 vertical_size; - __u32 vbv_buffer_size; - __u16 profile_and_level_indication; - __u8 chroma_format; - __u8 flags; -}; - -#define V4L2_MPEG2_PIC_CODING_TYPE_I 1 -#define V4L2_MPEG2_PIC_CODING_TYPE_P 2 -#define V4L2_MPEG2_PIC_CODING_TYPE_B 3 -#define V4L2_MPEG2_PIC_CODING_TYPE_D 4 - -#define V4L2_MPEG2_PIC_TOP_FIELD 0x1 -#define V4L2_MPEG2_PIC_BOTTOM_FIELD 0x2 -#define V4L2_MPEG2_PIC_FRAME 0x3 - -#define V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST 0x0001 -#define V4L2_MPEG2_PIC_FLAG_FRAME_PRED_DCT 0x0002 -#define V4L2_MPEG2_PIC_FLAG_CONCEALMENT_MV 0x0004 -#define V4L2_MPEG2_PIC_FLAG_Q_SCALE_TYPE 0x0008 -#define V4L2_MPEG2_PIC_FLAG_INTRA_VLC 0x0010 -#define V4L2_MPEG2_PIC_FLAG_ALT_SCAN 0x0020 -#define V4L2_MPEG2_PIC_FLAG_REPEAT_FIRST 0x0040 -#define V4L2_MPEG2_PIC_FLAG_PROGRESSIVE 0x0080 - -/** - * struct v4l2_ctrl_mpeg2_picture - MPEG-2 picture header - * - * All the members on this structure match the picture header and picture - * coding extension syntaxes as specified by the MPEG-2 specification. - * - * @backward_ref_ts: timestamp of the V4L2 capture buffer to use as - * reference for backward prediction. - * @forward_ref_ts: timestamp of the V4L2 capture buffer to use as - * reference for forward prediction. These timestamp refers to the - * timestamp field in struct v4l2_buffer. Use v4l2_timeval_to_ns() - * to convert the struct timeval to a __u64. - * @flags: see V4L2_MPEG2_PIC_FLAG_{}. - * @f_code[2][2]: see MPEG-2 specification. - * @picture_coding_type: see MPEG-2 specification. - * @picture_structure: see V4L2_MPEG2_PIC_{}_FIELD. - * @intra_dc_precision: see MPEG-2 specification. - * @reserved: padding field. Should be zeroed by applications. - */ -struct v4l2_ctrl_mpeg2_picture { - __u64 backward_ref_ts; - __u64 forward_ref_ts; - __u32 flags; - __u8 f_code[2][2]; - __u8 picture_coding_type; - __u8 picture_structure; - __u8 intra_dc_precision; - __u8 reserved[5]; -}; - -/** - * struct v4l2_ctrl_mpeg2_quantisation - MPEG-2 quantisation - * - * Quantization matrices as specified by section 6.3.7 - * "Quant matrix extension". - * - * @intra_quantiser_matrix: The quantisation matrix coefficients - * for intra-coded frames, in zigzag scanning order. It is relevant - * for both luma and chroma components, although it can be superseded - * by the chroma-specific matrix for non-4:2:0 YUV formats. - * @non_intra_quantiser_matrix: The quantisation matrix coefficients - * for non-intra-coded frames, in zigzag scanning order. It is relevant - * for both luma and chroma components, although it can be superseded - * by the chroma-specific matrix for non-4:2:0 YUV formats. - * @chroma_intra_quantiser_matrix: The quantisation matrix coefficients - * for the chominance component of intra-coded frames, in zigzag scanning - * order. Only relevant for 4:2:2 and 4:4:4 YUV formats. - * @chroma_non_intra_quantiser_matrix: The quantisation matrix coefficients - * for the chrominance component of non-intra-coded frames, in zigzag scanning - * order. Only relevant for 4:2:2 and 4:4:4 YUV formats. - */ -struct v4l2_ctrl_mpeg2_quantisation { - __u8 intra_quantiser_matrix[64]; - __u8 non_intra_quantiser_matrix[64]; - __u8 chroma_intra_quantiser_matrix[64]; - __u8 chroma_non_intra_quantiser_matrix[64]; -}; - -#endif diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h index 215e44172c66..575b59fbac77 100644 --- a/include/media/v4l2-ctrls.h +++ b/include/media/v4l2-ctrls.h @@ -17,7 +17,6 @@ * Include the stateless codec compound control definitions. * This will move to the public headers once this API is fully stable. */ -#include #include /* forward references */ diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h index d43bec5f1afd..f96bea19c991 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h @@ -1862,6 +1862,118 @@ struct v4l2_ctrl_vp8_frame { __u64 flags; }; +/* Stateless MPEG-2 controls */ + +#define V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE 0x01 + +#define V4L2_CID_STATELESS_MPEG2_SEQUENCE (V4L2_CID_CODEC_STATELESS_BASE+220) +/** + * struct v4l2_ctrl_mpeg2_sequence - MPEG-2 sequence header + * + * All the members on this structure match the sequence header and sequence + * extension syntaxes as specified by the MPEG-2 specification. + * + * Fields horizontal_size, vertical_size and vbv_buffer_size are a + * combination of respective _value and extension syntax elements, + * as described in section 6.3.3 "Sequence header". + * + * @horizontal_size: combination of elements horizontal_size_value and + * horizontal_size_extension. + * @vertical_size: combination of elements vertical_size_value and + * vertical_size_extension. + * @vbv_buffer_size: combination of elements vbv_buffer_size_value and + * vbv_buffer_size_extension. + * @profile_and_level_indication: see MPEG-2 specification. + * @chroma_format: see MPEG-2 specification. + * @flags: see V4L2_MPEG2_SEQ_FLAG_{}. + */ +struct v4l2_ctrl_mpeg2_sequence { + __u16 horizontal_size; + __u16 vertical_size; + __u32 vbv_buffer_size; + __u16 profile_and_level_indication; + __u8 chroma_format; + __u8 flags; +}; + +#define V4L2_MPEG2_PIC_CODING_TYPE_I 1 +#define V4L2_MPEG2_PIC_CODING_TYPE_P 2 +#define V4L2_MPEG2_PIC_CODING_TYPE_B 3 +#define V4L2_MPEG2_PIC_CODING_TYPE_D 4 + +#define V4L2_MPEG2_PIC_TOP_FIELD 0x1 +#define V4L2_MPEG2_PIC_BOTTOM_FIELD 0x2 +#define V4L2_MPEG2_PIC_FRAME 0x3 + +#define V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST 0x0001 +#define V4L2_MPEG2_PIC_FLAG_FRAME_PRED_DCT 0x0002 +#define V4L2_MPEG2_PIC_FLAG_CONCEALMENT_MV 0x0004 +#define V4L2_MPEG2_PIC_FLAG_Q_SCALE_TYPE 0x0008 +#define V4L2_MPEG2_PIC_FLAG_INTRA_VLC 0x0010 +#define V4L2_MPEG2_PIC_FLAG_ALT_SCAN 0x0020 +#define V4L2_MPEG2_PIC_FLAG_REPEAT_FIRST 0x0040 +#define V4L2_MPEG2_PIC_FLAG_PROGRESSIVE 0x0080 + +#define V4L2_CID_STATELESS_MPEG2_PICTURE (V4L2_CID_CODEC_STATELESS_BASE+221) +/** + * struct v4l2_ctrl_mpeg2_picture - MPEG-2 picture header + * + * All the members on this structure match the picture header and picture + * coding extension syntaxes as specified by the MPEG-2 specification. + * + * @backward_ref_ts: timestamp of the V4L2 capture buffer to use as + * reference for backward prediction. + * @forward_ref_ts: timestamp of the V4L2 capture buffer to use as + * reference for forward prediction. These timestamp refers to the + * timestamp field in struct v4l2_buffer. Use v4l2_timeval_to_ns() + * to convert the struct timeval to a __u64. + * @flags: see V4L2_MPEG2_PIC_FLAG_{}. + * @f_code: see MPEG-2 specification. + * @picture_coding_type: see MPEG-2 specification. + * @picture_structure: see V4L2_MPEG2_PIC_{}_FIELD. + * @intra_dc_precision: see MPEG-2 specification. + * @reserved: padding field. Should be zeroed by applications. + */ +struct v4l2_ctrl_mpeg2_picture { + __u64 backward_ref_ts; + __u64 forward_ref_ts; + __u32 flags; + __u8 f_code[2][2]; + __u8 picture_coding_type; + __u8 picture_structure; + __u8 intra_dc_precision; + __u8 reserved[5]; +}; + +#define V4L2_CID_STATELESS_MPEG2_QUANTISATION (V4L2_CID_CODEC_STATELESS_BASE+222) +/** + * struct v4l2_ctrl_mpeg2_quantisation - MPEG-2 quantisation + * + * Quantisation matrices as specified by section 6.3.7 + * "Quant matrix extension". + * + * @intra_quantiser_matrix: The quantisation matrix coefficients + * for intra-coded frames, in zigzag scanning order. It is relevant + * for both luma and chroma components, although it can be superseded + * by the chroma-specific matrix for non-4:2:0 YUV formats. + * @non_intra_quantiser_matrix: The quantisation matrix coefficients + * for non-intra-coded frames, in zigzag scanning order. It is relevant + * for both luma and chroma components, although it can be superseded + * by the chroma-specific matrix for non-4:2:0 YUV formats. + * @chroma_intra_quantiser_matrix: The quantisation matrix coefficients + * for the chominance component of intra-coded frames, in zigzag scanning + * order. Only relevant for 4:2:2 and 4:4:4 YUV formats. + * @chroma_non_intra_quantiser_matrix: The quantisation matrix coefficients + * for the chrominance component of non-intra-coded frames, in zigzag scanning + * order. Only relevant for 4:2:2 and 4:4:4 YUV formats. + */ +struct v4l2_ctrl_mpeg2_quantisation { + __u8 intra_quantiser_matrix[64]; + __u8 non_intra_quantiser_matrix[64]; + __u8 chroma_intra_quantiser_matrix[64]; + __u8 chroma_non_intra_quantiser_matrix[64]; +}; + #define V4L2_CID_COLORIMETRY_CLASS_BASE (V4L2_CTRL_CLASS_COLORIMETRY | 0x900) #define V4L2_CID_COLORIMETRY_CLASS (V4L2_CTRL_CLASS_COLORIMETRY | 1) diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index d3bb18a3a51b..9260791b8438 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -1747,6 +1747,9 @@ struct v4l2_ext_control { struct v4l2_ctrl_h264_decode_params __user *p_h264_decode_params; struct v4l2_ctrl_fwht_params __user *p_fwht_params; struct v4l2_ctrl_vp8_frame __user *p_vp8_frame; + struct v4l2_ctrl_mpeg2_sequence __user *p_mpeg2_sequence; + struct v4l2_ctrl_mpeg2_picture __user *p_mpeg2_picture; + struct v4l2_ctrl_mpeg2_quantisation __user *p_mpeg2_quantisation; void __user *ptr; }; } __attribute__ ((packed)); From d2fcc9c2de1191ea80366e3658711753738dd10a Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 13 Apr 2021 04:29:52 +0200 Subject: [PATCH 157/394] media: imx: imx7_mipi_csis: Fix logging of only error event counters The mipi_csis_events array ends with 6 non-error events, not 4. Update mipi_csis_log_counters() accordingly. While at it, log event counters in forward order, as there's no reason to log them backward. Signed-off-by: Laurent Pinchart Acked-by: Rui Miguel Silva Reviewed-by: Frieder Schrempf Tested-by: Frieder Schrempf Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/imx7-mipi-csis.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c index 1dc680d94a46..47e3175729c0 100644 --- a/drivers/staging/media/imx/imx7-mipi-csis.c +++ b/drivers/staging/media/imx/imx7-mipi-csis.c @@ -666,13 +666,15 @@ static void mipi_csis_clear_counters(struct csi_state *state) static void mipi_csis_log_counters(struct csi_state *state, bool non_errors) { - int i = non_errors ? MIPI_CSIS_NUM_EVENTS : MIPI_CSIS_NUM_EVENTS - 4; + unsigned int num_events = non_errors ? MIPI_CSIS_NUM_EVENTS + : MIPI_CSIS_NUM_EVENTS - 6; struct device *dev = &state->pdev->dev; unsigned long flags; + unsigned int i; spin_lock_irqsave(&state->slock, flags); - for (i--; i >= 0; i--) { + for (i = 0; i < num_events; ++i) { if (state->events[i].counter > 0 || state->debug) dev_info(dev, "%s events: %d\n", state->events[i].name, state->events[i].counter); From 7fe1de81ddda28f584e55b847bc4f036e95c8ed2 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 13 Apr 2021 04:29:53 +0200 Subject: [PATCH 158/394] media: imx: imx7_mipi_csis: Count the CSI-2 debug interrupts In addition to the main interrupts that flag errors and other events, the CSI-2 receiver has debug interrupt sources that flag various events useful for debugging. Add those sources to the event counter mechanism and print them when debugging is enabled. Signed-off-by: Laurent Pinchart Acked-by: Rui Miguel Silva Reviewed-by: Frieder Schrempf Tested-by: Frieder Schrempf Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/imx7-mipi-csis.c | 69 ++++++++++++++++------ 1 file changed, 51 insertions(+), 18 deletions(-) diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c index 47e3175729c0..4d1ac228eb59 100644 --- a/drivers/staging/media/imx/imx7-mipi-csis.c +++ b/drivers/staging/media/imx/imx7-mipi-csis.c @@ -195,6 +195,24 @@ /* Debug control register */ #define MIPI_CSIS_DBG_CTRL 0xc0 +#define MIPI_CSIS_DBG_INTR_MSK 0xc4 +#define MIPI_CSIS_DBG_INTR_MSK_DT_NOT_SUPPORT BIT(25) +#define MIPI_CSIS_DBG_INTR_MSK_DT_IGNORE BIT(24) +#define MIPI_CSIS_DBG_INTR_MSK_ERR_FRAME_SIZE BIT(20) +#define MIPI_CSIS_DBG_INTR_MSK_TRUNCATED_FRAME BIT(16) +#define MIPI_CSIS_DBG_INTR_MSK_EARLY_FE BIT(12) +#define MIPI_CSIS_DBG_INTR_MSK_EARLY_FS BIT(8) +#define MIPI_CSIS_DBG_INTR_MSK_CAM_VSYNC_FALL BIT(4) +#define MIPI_CSIS_DBG_INTR_MSK_CAM_VSYNC_RISE BIT(0) +#define MIPI_CSIS_DBG_INTR_SRC 0xc8 +#define MIPI_CSIS_DBG_INTR_SRC_DT_NOT_SUPPORT BIT(25) +#define MIPI_CSIS_DBG_INTR_SRC_DT_IGNORE BIT(24) +#define MIPI_CSIS_DBG_INTR_SRC_ERR_FRAME_SIZE BIT(20) +#define MIPI_CSIS_DBG_INTR_SRC_TRUNCATED_FRAME BIT(16) +#define MIPI_CSIS_DBG_INTR_SRC_EARLY_FE BIT(12) +#define MIPI_CSIS_DBG_INTR_SRC_EARLY_FS BIT(8) +#define MIPI_CSIS_DBG_INTR_SRC_CAM_VSYNC_FALL BIT(4) +#define MIPI_CSIS_DBG_INTR_SRC_CAM_VSYNC_RISE BIT(0) /* Non-image packet data buffers */ #define MIPI_CSIS_PKTDATA_ODD 0x2000 @@ -210,6 +228,7 @@ enum { }; struct mipi_csis_event { + bool debug; u32 mask; const char * const name; unsigned int counter; @@ -217,22 +236,30 @@ struct mipi_csis_event { static const struct mipi_csis_event mipi_csis_events[] = { /* Errors */ - { MIPI_CSIS_INT_SRC_ERR_SOT_HS, "SOT Error" }, - { MIPI_CSIS_INT_SRC_ERR_LOST_FS, "Lost Frame Start Error" }, - { MIPI_CSIS_INT_SRC_ERR_LOST_FE, "Lost Frame End Error" }, - { MIPI_CSIS_INT_SRC_ERR_OVER, "FIFO Overflow Error" }, - { MIPI_CSIS_INT_SRC_ERR_WRONG_CFG, "Wrong Configuration Error" }, - { MIPI_CSIS_INT_SRC_ERR_ECC, "ECC Error" }, - { MIPI_CSIS_INT_SRC_ERR_CRC, "CRC Error" }, - { MIPI_CSIS_INT_SRC_ERR_UNKNOWN, "Unknown Error" }, + { false, MIPI_CSIS_INT_SRC_ERR_SOT_HS, "SOT Error" }, + { false, MIPI_CSIS_INT_SRC_ERR_LOST_FS, "Lost Frame Start Error" }, + { false, MIPI_CSIS_INT_SRC_ERR_LOST_FE, "Lost Frame End Error" }, + { false, MIPI_CSIS_INT_SRC_ERR_OVER, "FIFO Overflow Error" }, + { false, MIPI_CSIS_INT_SRC_ERR_WRONG_CFG, "Wrong Configuration Error" }, + { false, MIPI_CSIS_INT_SRC_ERR_ECC, "ECC Error" }, + { false, MIPI_CSIS_INT_SRC_ERR_CRC, "CRC Error" }, + { false, MIPI_CSIS_INT_SRC_ERR_UNKNOWN, "Unknown Error" }, + { true, MIPI_CSIS_DBG_INTR_SRC_DT_NOT_SUPPORT, "Data Type Not Supported" }, + { true, MIPI_CSIS_DBG_INTR_SRC_DT_IGNORE, "Data Type Ignored" }, + { true, MIPI_CSIS_DBG_INTR_SRC_ERR_FRAME_SIZE, "Frame Size Error" }, + { true, MIPI_CSIS_DBG_INTR_SRC_TRUNCATED_FRAME, "Truncated Frame" }, + { true, MIPI_CSIS_DBG_INTR_SRC_EARLY_FE, "Early Frame End" }, + { true, MIPI_CSIS_DBG_INTR_SRC_EARLY_FS, "Early Frame Start" }, /* Non-image data receive events */ - { MIPI_CSIS_INT_SRC_EVEN_BEFORE, "Non-image data before even frame" }, - { MIPI_CSIS_INT_SRC_EVEN_AFTER, "Non-image data after even frame" }, - { MIPI_CSIS_INT_SRC_ODD_BEFORE, "Non-image data before odd frame" }, - { MIPI_CSIS_INT_SRC_ODD_AFTER, "Non-image data after odd frame" }, + { false, MIPI_CSIS_INT_SRC_EVEN_BEFORE, "Non-image data before even frame" }, + { false, MIPI_CSIS_INT_SRC_EVEN_AFTER, "Non-image data after even frame" }, + { false, MIPI_CSIS_INT_SRC_ODD_BEFORE, "Non-image data before odd frame" }, + { false, MIPI_CSIS_INT_SRC_ODD_AFTER, "Non-image data after odd frame" }, /* Frame start/end */ - { MIPI_CSIS_INT_SRC_FRAME_START, "Frame Start" }, - { MIPI_CSIS_INT_SRC_FRAME_END, "Frame End" }, + { false, MIPI_CSIS_INT_SRC_FRAME_START, "Frame Start" }, + { false, MIPI_CSIS_INT_SRC_FRAME_END, "Frame End" }, + { true, MIPI_CSIS_DBG_INTR_SRC_CAM_VSYNC_FALL, "VSYNC Falling Edge" }, + { true, MIPI_CSIS_DBG_INTR_SRC_CAM_VSYNC_RISE, "VSYNC Rising Edge" }, }; #define MIPI_CSIS_NUM_EVENTS ARRAY_SIZE(mipi_csis_events) @@ -455,6 +482,7 @@ static const struct csis_pix_format *find_csis_format(u32 code) static void mipi_csis_enable_interrupts(struct csi_state *state, bool on) { mipi_csis_write(state, MIPI_CSIS_INT_MSK, on ? 0xffffffff : 0); + mipi_csis_write(state, MIPI_CSIS_DBG_INTR_MSK, on ? 0xffffffff : 0); } static void mipi_csis_sw_reset(struct csi_state *state) @@ -667,7 +695,7 @@ static void mipi_csis_clear_counters(struct csi_state *state) static void mipi_csis_log_counters(struct csi_state *state, bool non_errors) { unsigned int num_events = non_errors ? MIPI_CSIS_NUM_EVENTS - : MIPI_CSIS_NUM_EVENTS - 6; + : MIPI_CSIS_NUM_EVENTS - 8; struct device *dev = &state->pdev->dev; unsigned long flags; unsigned int i; @@ -962,22 +990,27 @@ static irqreturn_t mipi_csis_irq_handler(int irq, void *dev_id) unsigned long flags; unsigned int i; u32 status; + u32 dbg_status; status = mipi_csis_read(state, MIPI_CSIS_INT_SRC); + dbg_status = mipi_csis_read(state, MIPI_CSIS_DBG_INTR_SRC); spin_lock_irqsave(&state->slock, flags); /* Update the event/error counters */ if ((status & MIPI_CSIS_INT_SRC_ERRORS) || state->debug) { for (i = 0; i < MIPI_CSIS_NUM_EVENTS; i++) { - if (!(status & state->events[i].mask)) - continue; - state->events[i].counter++; + struct mipi_csis_event *event = &state->events[i]; + + if ((!event->debug && (status & event->mask)) || + (event->debug && (dbg_status & event->mask))) + event->counter++; } } spin_unlock_irqrestore(&state->slock, flags); mipi_csis_write(state, MIPI_CSIS_INT_SRC, status); + mipi_csis_write(state, MIPI_CSIS_DBG_INTR_SRC, dbg_status); return IRQ_HANDLED; } From ca403b37cd9548115e2aeed61f6d147cc6f0d507 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 13 Apr 2021 04:29:54 +0200 Subject: [PATCH 159/394] media: imx: imx7_mipi_csis: Update ISP_CONFIG macros for quad pixel mode The i.MX8MM expands the DOUBLE_CMPNT bit in the ISP_CONFIG register into a two bits field that support quad pixel mode in addition to the single and double modes. Update the ISP_CONFIG register macros to support this. Signed-off-by: Laurent Pinchart Acked-by: Rui Miguel Silva Reviewed-by: Frieder Schrempf Tested-by: Frieder Schrempf Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/imx7-mipi-csis.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c index 4d1ac228eb59..fe6aa1d0afa1 100644 --- a/drivers/staging/media/imx/imx7-mipi-csis.c +++ b/drivers/staging/media/imx/imx7-mipi-csis.c @@ -166,7 +166,9 @@ #define MIPI_CSIS_ISP_CONFIG_CH(n) (0x40 + (n) * 0x10) #define MIPI_CSIS_ISPCFG_MEM_FULL_GAP_MSK (0xff << 24) #define MIPI_CSIS_ISPCFG_MEM_FULL_GAP(x) ((x) << 24) -#define MIPI_CSIS_ISPCFG_DOUBLE_CMPNT BIT(12) +#define MIPI_CSIS_ISPCFG_PIXEL_MODE_SINGLE (0 << 12) +#define MIPI_CSIS_ISPCFG_PIXEL_MODE_DUAL (1 << 12) +#define MIPI_CSIS_ISPCFG_PIXEL_MODE_QUAD (2 << 12) /* i.MX8M[MNP] only */ #define MIPI_CSIS_ISPCFG_ALIGN_32BIT BIT(11) #define MIPI_CSIS_ISPCFG_FMT_YCBCR422_8BIT (0x1e << 2) #define MIPI_CSIS_ISPCFG_FMT_RAW8 (0x2a << 2) From eed6a93044e38a63e397f7aef8dbc7ee667459fb Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 13 Apr 2021 04:29:55 +0200 Subject: [PATCH 160/394] media: imx: imx7_mipi_csis: Move static data to top of mipi_csis_dump_regs() It's customary to declare static variables at the top of the function, with a blank line separating them from the non-static variables. Signed-off-by: Laurent Pinchart Acked-by: Rui Miguel Silva Reviewed-by: Frieder Schrempf Tested-by: Frieder Schrempf Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/imx7-mipi-csis.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c index fe6aa1d0afa1..1697d8740241 100644 --- a/drivers/staging/media/imx/imx7-mipi-csis.c +++ b/drivers/staging/media/imx/imx7-mipi-csis.c @@ -429,9 +429,6 @@ static inline u32 mipi_csis_read(struct csi_state *state, u32 reg) static int mipi_csis_dump_regs(struct csi_state *state) { - struct device *dev = &state->pdev->dev; - unsigned int i; - u32 cfg; static const struct { u32 offset; const char * const name; @@ -450,6 +447,10 @@ static int mipi_csis_dump_regs(struct csi_state *state) { MIPI_CSIS_DBG_CTRL, "DBG_CTRL" }, }; + struct device *dev = &state->pdev->dev; + unsigned int i; + u32 cfg; + dev_info(dev, "--- REGISTERS ---\n"); for (i = 0; i < ARRAY_SIZE(registers); i++) { From 2cb7c5c08cf25b0d2d375732a76b1185c92a1853 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 13 Apr 2021 04:29:56 +0200 Subject: [PATCH 161/394] media: imx: imx7_mipi_csis: Minimize locking in get/set format Reduce the code sections that are run with the lock held in the get/set format handlers: - mipi_csis_get_format() retrieves a pointer to the format, and thus doesn't need locking as long as the arguments passed to the function don't require locking either. - sdformat is a structure passed by the caller, not an internal state, and thus doesn't require locking. Signed-off-by: Laurent Pinchart Acked-by: Rui Miguel Silva Tested-by: Frieder Schrempf Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/imx7-mipi-csis.c | 36 ++++++++++++---------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c index 1697d8740241..f195c65563e7 100644 --- a/drivers/staging/media/imx/imx7-mipi-csis.c +++ b/drivers/staging/media/imx/imx7-mipi-csis.c @@ -859,8 +859,9 @@ static int mipi_csis_get_fmt(struct v4l2_subdev *mipi_sd, struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); struct v4l2_mbus_framefmt *fmt; - mutex_lock(&state->lock); fmt = mipi_csis_get_format(state, cfg, sdformat->which, sdformat->pad); + + mutex_lock(&state->lock); sdformat->format = *fmt; mutex_unlock(&state->lock); @@ -918,24 +919,17 @@ static int mipi_csis_set_fmt(struct v4l2_subdev *mipi_sd, if (sdformat->pad != CSIS_PAD_SINK) return -EINVAL; - fmt = mipi_csis_get_format(state, cfg, sdformat->which, sdformat->pad); - - mutex_lock(&state->lock); - - /* Validate the media bus code and clamp the size. */ - csis_fmt = find_csis_format(sdformat->format.code); - if (!csis_fmt) - csis_fmt = &mipi_csis_formats[0]; - - fmt->code = csis_fmt->code; - fmt->width = sdformat->format.width; - fmt->height = sdformat->format.height; - /* + * Validate the media bus code and clamp and align the size. + * * The total number of bits per line must be a multiple of 8. We thus * need to align the width for formats that are not multiples of 8 * bits. */ + csis_fmt = find_csis_format(sdformat->format.code); + if (!csis_fmt) + csis_fmt = &mipi_csis_formats[0]; + switch (csis_fmt->width % 8) { case 0: align = 0; @@ -955,8 +949,18 @@ static int mipi_csis_set_fmt(struct v4l2_subdev *mipi_sd, break; } - v4l_bound_align_image(&fmt->width, 1, CSIS_MAX_PIX_WIDTH, align, - &fmt->height, 1, CSIS_MAX_PIX_HEIGHT, 0, 0); + v4l_bound_align_image(&sdformat->format.width, 1, + CSIS_MAX_PIX_WIDTH, align, + &sdformat->format.height, 1, + CSIS_MAX_PIX_HEIGHT, 0, 0); + + fmt = mipi_csis_get_format(state, cfg, sdformat->which, sdformat->pad); + + mutex_lock(&state->lock); + + fmt->code = csis_fmt->code; + fmt->width = sdformat->format.width; + fmt->height = sdformat->format.height; sdformat->format = *fmt; From 90ce0472182f5dffc67155601ea0a927dfb3e9d6 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 13 Apr 2021 04:29:57 +0200 Subject: [PATCH 162/394] media: imx: imx7_mipi_csis: Don't set subdev data The driver doesn't need to store subdev data, as the subdev is embedded in csi_state and is thus accessed using container_of. Signed-off-by: Laurent Pinchart Acked-by: Rui Miguel Silva Tested-by: Frieder Schrempf Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/imx7-mipi-csis.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c index f195c65563e7..08ec87950699 100644 --- a/drivers/staging/media/imx/imx7-mipi-csis.c +++ b/drivers/staging/media/imx/imx7-mipi-csis.c @@ -1104,8 +1104,6 @@ static int mipi_csis_subdev_init(struct v4l2_subdev *mipi_sd, state->csis_fmt = &mipi_csis_formats[0]; mipi_csis_init_cfg(mipi_sd, NULL); - v4l2_set_subdevdata(mipi_sd, &pdev->dev); - state->pads[CSIS_PAD_SINK].flags = MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_MUST_CONNECT; state->pads[CSIS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE From b329650e3f2d4369ec66e2fae2227beb7de37bca Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 13 Apr 2021 04:29:58 +0200 Subject: [PATCH 163/394] media: imx: imx7_mipi_csis: Reorganize code in sections Improve readability by reorganizing the code in sections. No functional change intended. Signed-off-by: Laurent Pinchart Acked-by: Rui Miguel Silva Tested-by: Frieder Schrempf Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/imx7-mipi-csis.c | 539 +++++++++++---------- 1 file changed, 283 insertions(+), 256 deletions(-) diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c index 08ec87950699..1831ff4cc629 100644 --- a/drivers/staging/media/imx/imx7-mipi-csis.c +++ b/drivers/staging/media/imx/imx7-mipi-csis.c @@ -324,6 +324,10 @@ struct csi_state { struct regulator *mipi_phy_regulator; }; +/* ----------------------------------------------------------------------------- + * Format helpers + */ + struct csis_pix_format { u32 code; u32 fmt_reg; @@ -417,61 +421,6 @@ static const struct csis_pix_format mipi_csis_formats[] = { } }; -static inline void mipi_csis_write(struct csi_state *state, u32 reg, u32 val) -{ - writel(val, state->regs + reg); -} - -static inline u32 mipi_csis_read(struct csi_state *state, u32 reg) -{ - return readl(state->regs + reg); -} - -static int mipi_csis_dump_regs(struct csi_state *state) -{ - static const struct { - u32 offset; - const char * const name; - } registers[] = { - { MIPI_CSIS_CMN_CTRL, "CMN_CTRL" }, - { MIPI_CSIS_CLK_CTRL, "CLK_CTRL" }, - { MIPI_CSIS_INT_MSK, "INT_MSK" }, - { MIPI_CSIS_DPHY_STATUS, "DPHY_STATUS" }, - { MIPI_CSIS_DPHY_CMN_CTRL, "DPHY_CMN_CTRL" }, - { MIPI_CSIS_DPHY_SCTRL_L, "DPHY_SCTRL_L" }, - { MIPI_CSIS_DPHY_SCTRL_H, "DPHY_SCTRL_H" }, - { MIPI_CSIS_ISP_CONFIG_CH(0), "ISP_CONFIG_CH0" }, - { MIPI_CSIS_ISP_RESOL_CH(0), "ISP_RESOL_CH0" }, - { MIPI_CSIS_SDW_CONFIG_CH(0), "SDW_CONFIG_CH0" }, - { MIPI_CSIS_SDW_RESOL_CH(0), "SDW_RESOL_CH0" }, - { MIPI_CSIS_DBG_CTRL, "DBG_CTRL" }, - }; - - struct device *dev = &state->pdev->dev; - unsigned int i; - u32 cfg; - - dev_info(dev, "--- REGISTERS ---\n"); - - for (i = 0; i < ARRAY_SIZE(registers); i++) { - cfg = mipi_csis_read(state, registers[i].offset); - dev_info(dev, "%14s: 0x%08x\n", registers[i].name, cfg); - } - - return 0; -} - -static struct csi_state * -mipi_notifier_to_csis_state(struct v4l2_async_notifier *n) -{ - return container_of(n, struct csi_state, notifier); -} - -static struct csi_state *mipi_sd_to_csis_state(struct v4l2_subdev *sdev) -{ - return container_of(sdev, struct csi_state, mipi_sd); -} - static const struct csis_pix_format *find_csis_format(u32 code) { unsigned int i; @@ -482,6 +431,20 @@ static const struct csis_pix_format *find_csis_format(u32 code) return NULL; } +/* ----------------------------------------------------------------------------- + * Hardware configuration + */ + +static inline u32 mipi_csis_read(struct csi_state *state, u32 reg) +{ + return readl(state->regs + reg); +} + +static inline void mipi_csis_write(struct csi_state *state, u32 reg, u32 val) +{ + writel(val, state->regs + reg); +} + static void mipi_csis_enable_interrupts(struct csi_state *state, bool on) { mipi_csis_write(state, MIPI_CSIS_INT_MSK, on ? 0xffffffff : 0); @@ -684,6 +647,41 @@ static void mipi_csis_stop_stream(struct csi_state *state) mipi_csis_system_enable(state, false); } +static irqreturn_t mipi_csis_irq_handler(int irq, void *dev_id) +{ + struct csi_state *state = dev_id; + unsigned long flags; + unsigned int i; + u32 status; + u32 dbg_status; + + status = mipi_csis_read(state, MIPI_CSIS_INT_SRC); + dbg_status = mipi_csis_read(state, MIPI_CSIS_DBG_INTR_SRC); + + spin_lock_irqsave(&state->slock, flags); + + /* Update the event/error counters */ + if ((status & MIPI_CSIS_INT_SRC_ERRORS) || state->debug) { + for (i = 0; i < MIPI_CSIS_NUM_EVENTS; i++) { + struct mipi_csis_event *event = &state->events[i]; + + if ((!event->debug && (status & event->mask)) || + (event->debug && (dbg_status & event->mask))) + event->counter++; + } + } + spin_unlock_irqrestore(&state->slock, flags); + + mipi_csis_write(state, MIPI_CSIS_INT_SRC, status); + mipi_csis_write(state, MIPI_CSIS_DBG_INTR_SRC, dbg_status); + + return IRQ_HANDLED; +} + +/* ----------------------------------------------------------------------------- + * Debug + */ + static void mipi_csis_clear_counters(struct csi_state *state) { unsigned long flags; @@ -713,9 +711,72 @@ static void mipi_csis_log_counters(struct csi_state *state, bool non_errors) spin_unlock_irqrestore(&state->slock, flags); } -/* +static int mipi_csis_dump_regs(struct csi_state *state) +{ + static const struct { + u32 offset; + const char * const name; + } registers[] = { + { MIPI_CSIS_CMN_CTRL, "CMN_CTRL" }, + { MIPI_CSIS_CLK_CTRL, "CLK_CTRL" }, + { MIPI_CSIS_INT_MSK, "INT_MSK" }, + { MIPI_CSIS_DPHY_STATUS, "DPHY_STATUS" }, + { MIPI_CSIS_DPHY_CMN_CTRL, "DPHY_CMN_CTRL" }, + { MIPI_CSIS_DPHY_SCTRL_L, "DPHY_SCTRL_L" }, + { MIPI_CSIS_DPHY_SCTRL_H, "DPHY_SCTRL_H" }, + { MIPI_CSIS_ISP_CONFIG_CH(0), "ISP_CONFIG_CH0" }, + { MIPI_CSIS_ISP_RESOL_CH(0), "ISP_RESOL_CH0" }, + { MIPI_CSIS_SDW_CONFIG_CH(0), "SDW_CONFIG_CH0" }, + { MIPI_CSIS_SDW_RESOL_CH(0), "SDW_RESOL_CH0" }, + { MIPI_CSIS_DBG_CTRL, "DBG_CTRL" }, + }; + + struct device *dev = &state->pdev->dev; + unsigned int i; + u32 cfg; + + dev_info(dev, "--- REGISTERS ---\n"); + + for (i = 0; i < ARRAY_SIZE(registers); i++) { + cfg = mipi_csis_read(state, registers[i].offset); + dev_info(dev, "%14s: 0x%08x\n", registers[i].name, cfg); + } + + return 0; +} + +static int mipi_csis_dump_regs_show(struct seq_file *m, void *private) +{ + struct csi_state *state = m->private; + + return mipi_csis_dump_regs(state); +} +DEFINE_SHOW_ATTRIBUTE(mipi_csis_dump_regs); + +static void mipi_csis_debugfs_init(struct csi_state *state) +{ + state->debugfs_root = debugfs_create_dir(dev_name(state->dev), NULL); + + debugfs_create_bool("debug_enable", 0600, state->debugfs_root, + &state->debug); + debugfs_create_file("dump_regs", 0600, state->debugfs_root, state, + &mipi_csis_dump_regs_fops); +} + +static void mipi_csis_debugfs_exit(struct csi_state *state) +{ + debugfs_remove_recursive(state->debugfs_root); +} + +/* ----------------------------------------------------------------------------- * V4L2 subdev operations */ + +static struct csi_state *mipi_sd_to_csis_state(struct v4l2_subdev *sdev) +{ + return container_of(sdev, struct csi_state, mipi_sd); +} + static int mipi_csis_s_stream(struct v4l2_subdev *mipi_sd, int enable) { struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); @@ -774,35 +835,6 @@ done: return ret; } -static int mipi_csis_link_setup(struct media_entity *entity, - const struct media_pad *local_pad, - const struct media_pad *remote_pad, u32 flags) -{ - struct v4l2_subdev *mipi_sd = media_entity_to_v4l2_subdev(entity); - struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); - struct v4l2_subdev *remote_sd; - - dev_dbg(state->dev, "link setup %s -> %s", remote_pad->entity->name, - local_pad->entity->name); - - /* We only care about the link to the source. */ - if (!(local_pad->flags & MEDIA_PAD_FL_SINK)) - return 0; - - remote_sd = media_entity_to_v4l2_subdev(remote_pad->entity); - - if (flags & MEDIA_LNK_FL_ENABLED) { - if (state->src_sd) - return -EBUSY; - - state->src_sd = remote_sd; - } else { - state->src_sd = NULL; - } - - return 0; -} - static struct v4l2_mbus_framefmt * mipi_csis_get_format(struct csi_state *state, struct v4l2_subdev_pad_config *cfg, @@ -991,47 +1023,10 @@ static int mipi_csis_log_status(struct v4l2_subdev *mipi_sd) return 0; } -static irqreturn_t mipi_csis_irq_handler(int irq, void *dev_id) -{ - struct csi_state *state = dev_id; - unsigned long flags; - unsigned int i; - u32 status; - u32 dbg_status; - - status = mipi_csis_read(state, MIPI_CSIS_INT_SRC); - dbg_status = mipi_csis_read(state, MIPI_CSIS_DBG_INTR_SRC); - - spin_lock_irqsave(&state->slock, flags); - - /* Update the event/error counters */ - if ((status & MIPI_CSIS_INT_SRC_ERRORS) || state->debug) { - for (i = 0; i < MIPI_CSIS_NUM_EVENTS; i++) { - struct mipi_csis_event *event = &state->events[i]; - - if ((!event->debug && (status & event->mask)) || - (event->debug && (dbg_status & event->mask))) - event->counter++; - } - } - spin_unlock_irqrestore(&state->slock, flags); - - mipi_csis_write(state, MIPI_CSIS_INT_SRC, status); - mipi_csis_write(state, MIPI_CSIS_DBG_INTR_SRC, dbg_status); - - return IRQ_HANDLED; -} - static const struct v4l2_subdev_core_ops mipi_csis_core_ops = { .log_status = mipi_csis_log_status, }; -static const struct media_entity_operations mipi_csis_entity_ops = { - .link_setup = mipi_csis_link_setup, - .link_validate = v4l2_subdev_link_validate, - .get_fwnode_pad = v4l2_subdev_get_fwnode_pad_1_to_1, -}; - static const struct v4l2_subdev_video_ops mipi_csis_video_ops = { .s_stream = mipi_csis_s_stream, }; @@ -1049,24 +1044,54 @@ static const struct v4l2_subdev_ops mipi_csis_subdev_ops = { .pad = &mipi_csis_pad_ops, }; -static int mipi_csis_parse_dt(struct platform_device *pdev, - struct csi_state *state) +/* ----------------------------------------------------------------------------- + * Media entity operations + */ + +static int mipi_csis_link_setup(struct media_entity *entity, + const struct media_pad *local_pad, + const struct media_pad *remote_pad, u32 flags) { - struct device_node *node = pdev->dev.of_node; + struct v4l2_subdev *mipi_sd = media_entity_to_v4l2_subdev(entity); + struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + struct v4l2_subdev *remote_sd; - if (of_property_read_u32(node, "clock-frequency", - &state->clk_frequency)) - state->clk_frequency = DEFAULT_SCLK_CSIS_FREQ; + dev_dbg(state->dev, "link setup %s -> %s", remote_pad->entity->name, + local_pad->entity->name); - /* Get MIPI PHY resets */ - state->mrst = devm_reset_control_get_exclusive(&pdev->dev, NULL); - if (IS_ERR(state->mrst)) - return PTR_ERR(state->mrst); + /* We only care about the link to the source. */ + if (!(local_pad->flags & MEDIA_PAD_FL_SINK)) + return 0; + + remote_sd = media_entity_to_v4l2_subdev(remote_pad->entity); + + if (flags & MEDIA_LNK_FL_ENABLED) { + if (state->src_sd) + return -EBUSY; + + state->src_sd = remote_sd; + } else { + state->src_sd = NULL; + } return 0; } -static int mipi_csis_pm_resume(struct device *dev, bool runtime); +static const struct media_entity_operations mipi_csis_entity_ops = { + .link_setup = mipi_csis_link_setup, + .link_validate = v4l2_subdev_link_validate, + .get_fwnode_pad = v4l2_subdev_get_fwnode_pad_1_to_1, +}; + +/* ----------------------------------------------------------------------------- + * Async subdev notifier + */ + +static struct csi_state * +mipi_notifier_to_csis_state(struct v4l2_async_notifier *n) +{ + return container_of(n, struct csi_state, notifier); +} static int mipi_csis_notify_bound(struct v4l2_async_notifier *notifier, struct v4l2_subdev *sd, @@ -1082,36 +1107,6 @@ static const struct v4l2_async_notifier_operations mipi_csis_notify_ops = { .bound = mipi_csis_notify_bound, }; -static int mipi_csis_subdev_init(struct v4l2_subdev *mipi_sd, - struct platform_device *pdev, - const struct v4l2_subdev_ops *ops) -{ - struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); - - v4l2_subdev_init(mipi_sd, ops); - mipi_sd->owner = THIS_MODULE; - snprintf(mipi_sd->name, sizeof(mipi_sd->name), "%s.%d", - CSIS_SUBDEV_NAME, state->index); - - mipi_sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; - mipi_sd->ctrl_handler = NULL; - - mipi_sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; - mipi_sd->entity.ops = &mipi_csis_entity_ops; - - mipi_sd->dev = &pdev->dev; - - state->csis_fmt = &mipi_csis_formats[0]; - mipi_csis_init_cfg(mipi_sd, NULL); - - state->pads[CSIS_PAD_SINK].flags = MEDIA_PAD_FL_SINK - | MEDIA_PAD_FL_MUST_CONNECT; - state->pads[CSIS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE - | MEDIA_PAD_FL_MUST_CONNECT; - return media_entity_pads_init(&mipi_sd->entity, CSIS_PADS_NUM, - state->pads); -} - static int mipi_csis_async_register(struct csi_state *state) { struct v4l2_fwnode_endpoint vep = { @@ -1161,27 +1156,138 @@ err_parse: return ret; } -static int mipi_csis_dump_regs_show(struct seq_file *m, void *private) +/* ----------------------------------------------------------------------------- + * Suspend/resume + */ + +static int mipi_csis_pm_suspend(struct device *dev, bool runtime) { - struct csi_state *state = m->private; + struct v4l2_subdev *mipi_sd = dev_get_drvdata(dev); + struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + int ret = 0; - return mipi_csis_dump_regs(state); -} -DEFINE_SHOW_ATTRIBUTE(mipi_csis_dump_regs); + mutex_lock(&state->lock); + if (state->flags & ST_POWERED) { + mipi_csis_stop_stream(state); + ret = regulator_disable(state->mipi_phy_regulator); + if (ret) + goto unlock; + mipi_csis_clk_disable(state); + state->flags &= ~ST_POWERED; + if (!runtime) + state->flags |= ST_SUSPENDED; + } -static void mipi_csis_debugfs_init(struct csi_state *state) -{ - state->debugfs_root = debugfs_create_dir(dev_name(state->dev), NULL); +unlock: + mutex_unlock(&state->lock); - debugfs_create_bool("debug_enable", 0600, state->debugfs_root, - &state->debug); - debugfs_create_file("dump_regs", 0600, state->debugfs_root, state, - &mipi_csis_dump_regs_fops); + return ret ? -EAGAIN : 0; } -static void mipi_csis_debugfs_exit(struct csi_state *state) +static int mipi_csis_pm_resume(struct device *dev, bool runtime) { - debugfs_remove_recursive(state->debugfs_root); + struct v4l2_subdev *mipi_sd = dev_get_drvdata(dev); + struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + int ret = 0; + + mutex_lock(&state->lock); + if (!runtime && !(state->flags & ST_SUSPENDED)) + goto unlock; + + if (!(state->flags & ST_POWERED)) { + ret = regulator_enable(state->mipi_phy_regulator); + if (ret) + goto unlock; + + state->flags |= ST_POWERED; + mipi_csis_clk_enable(state); + } + if (state->flags & ST_STREAMING) + mipi_csis_start_stream(state); + + state->flags &= ~ST_SUSPENDED; + +unlock: + mutex_unlock(&state->lock); + + return ret ? -EAGAIN : 0; +} + +static int __maybe_unused mipi_csis_suspend(struct device *dev) +{ + return mipi_csis_pm_suspend(dev, false); +} + +static int __maybe_unused mipi_csis_resume(struct device *dev) +{ + return mipi_csis_pm_resume(dev, false); +} + +static int __maybe_unused mipi_csis_runtime_suspend(struct device *dev) +{ + return mipi_csis_pm_suspend(dev, true); +} + +static int __maybe_unused mipi_csis_runtime_resume(struct device *dev) +{ + return mipi_csis_pm_resume(dev, true); +} + +static const struct dev_pm_ops mipi_csis_pm_ops = { + SET_RUNTIME_PM_OPS(mipi_csis_runtime_suspend, mipi_csis_runtime_resume, + NULL) + SET_SYSTEM_SLEEP_PM_OPS(mipi_csis_suspend, mipi_csis_resume) +}; + +/* ----------------------------------------------------------------------------- + * Probe/remove & platform driver + */ + +static int mipi_csis_subdev_init(struct v4l2_subdev *mipi_sd, + struct platform_device *pdev, + const struct v4l2_subdev_ops *ops) +{ + struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + + v4l2_subdev_init(mipi_sd, ops); + mipi_sd->owner = THIS_MODULE; + snprintf(mipi_sd->name, sizeof(mipi_sd->name), "%s.%d", + CSIS_SUBDEV_NAME, state->index); + + mipi_sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; + mipi_sd->ctrl_handler = NULL; + + mipi_sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; + mipi_sd->entity.ops = &mipi_csis_entity_ops; + + mipi_sd->dev = &pdev->dev; + + state->csis_fmt = &mipi_csis_formats[0]; + mipi_csis_init_cfg(mipi_sd, NULL); + + state->pads[CSIS_PAD_SINK].flags = MEDIA_PAD_FL_SINK + | MEDIA_PAD_FL_MUST_CONNECT; + state->pads[CSIS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE + | MEDIA_PAD_FL_MUST_CONNECT; + return media_entity_pads_init(&mipi_sd->entity, CSIS_PADS_NUM, + state->pads); +} + +static int mipi_csis_parse_dt(struct platform_device *pdev, + struct csi_state *state) +{ + struct device_node *node = pdev->dev.of_node; + + if (of_property_read_u32(node, "clock-frequency", + &state->clk_frequency)) + state->clk_frequency = DEFAULT_SCLK_CSIS_FREQ; + + /* Get MIPI PHY resets */ + state->mrst = devm_reset_control_get_exclusive(&pdev->dev, NULL); + if (IS_ERR(state->mrst)) + return PTR_ERR(state->mrst); + + return 0; } static int mipi_csis_probe(struct platform_device *pdev) @@ -1279,79 +1385,6 @@ disable_clock: return ret; } -static int mipi_csis_pm_suspend(struct device *dev, bool runtime) -{ - struct v4l2_subdev *mipi_sd = dev_get_drvdata(dev); - struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); - int ret = 0; - - mutex_lock(&state->lock); - if (state->flags & ST_POWERED) { - mipi_csis_stop_stream(state); - ret = regulator_disable(state->mipi_phy_regulator); - if (ret) - goto unlock; - mipi_csis_clk_disable(state); - state->flags &= ~ST_POWERED; - if (!runtime) - state->flags |= ST_SUSPENDED; - } - -unlock: - mutex_unlock(&state->lock); - - return ret ? -EAGAIN : 0; -} - -static int mipi_csis_pm_resume(struct device *dev, bool runtime) -{ - struct v4l2_subdev *mipi_sd = dev_get_drvdata(dev); - struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); - int ret = 0; - - mutex_lock(&state->lock); - if (!runtime && !(state->flags & ST_SUSPENDED)) - goto unlock; - - if (!(state->flags & ST_POWERED)) { - ret = regulator_enable(state->mipi_phy_regulator); - if (ret) - goto unlock; - - state->flags |= ST_POWERED; - mipi_csis_clk_enable(state); - } - if (state->flags & ST_STREAMING) - mipi_csis_start_stream(state); - - state->flags &= ~ST_SUSPENDED; - -unlock: - mutex_unlock(&state->lock); - - return ret ? -EAGAIN : 0; -} - -static int __maybe_unused mipi_csis_suspend(struct device *dev) -{ - return mipi_csis_pm_suspend(dev, false); -} - -static int __maybe_unused mipi_csis_resume(struct device *dev) -{ - return mipi_csis_pm_resume(dev, false); -} - -static int __maybe_unused mipi_csis_runtime_suspend(struct device *dev) -{ - return mipi_csis_pm_suspend(dev, true); -} - -static int __maybe_unused mipi_csis_runtime_resume(struct device *dev) -{ - return mipi_csis_pm_resume(dev, true); -} - static int mipi_csis_remove(struct platform_device *pdev) { struct v4l2_subdev *mipi_sd = platform_get_drvdata(pdev); @@ -1372,12 +1405,6 @@ static int mipi_csis_remove(struct platform_device *pdev) return 0; } -static const struct dev_pm_ops mipi_csis_pm_ops = { - SET_RUNTIME_PM_OPS(mipi_csis_runtime_suspend, mipi_csis_runtime_resume, - NULL) - SET_SYSTEM_SLEEP_PM_OPS(mipi_csis_suspend, mipi_csis_resume) -}; - static const struct of_device_id mipi_csis_of_match[] = { { .compatible = "fsl,imx7-mipi-csi2", }, { /* sentinel */ }, From 996f6f517dc79f337faf29d9db54ceb9a3169787 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 13 Apr 2021 04:29:59 +0200 Subject: [PATCH 164/394] media: imx: imx7_mipi_csis: Set the CLKSETTLE register field Set the CLKSETTLE field explicitly, with a value hardcoded to 0. This brings no functional change, but prepares for calculation of the CLKSETTLE value. Signed-off-by: Laurent Pinchart Acked-by: Rui Miguel Silva Tested-by: Frieder Schrempf Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/imx7-mipi-csis.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c index 1831ff4cc629..5dc001a415d4 100644 --- a/drivers/staging/media/imx/imx7-mipi-csis.c +++ b/drivers/staging/media/imx/imx7-mipi-csis.c @@ -310,6 +310,7 @@ struct csi_state { u32 clk_frequency; u32 hs_settle; + u32 clk_settle; struct reset_control *mrst; @@ -540,11 +541,15 @@ static int mipi_csis_calculate_params(struct csi_state *state) /* * The HSSETTLE counter value is document in a table, but can also - * easily be calculated. + * easily be calculated. Hardcode the CLKSETTLE value to 0 for now + * (which is documented as corresponding to CSI-2 v0.87 to v1.00) until + * we figure out how to compute it correctly. */ state->hs_settle = (lane_rate - 5000000) / 45000000; - dev_dbg(state->dev, "lane rate %u, Ths_settle %u\n", - lane_rate, state->hs_settle); + state->clk_settle = 0; + + dev_dbg(state->dev, "lane rate %u, Tclk_settle %u, Ths_settle %u\n", + lane_rate, state->clk_settle, state->hs_settle); return 0; } @@ -563,7 +568,8 @@ static void mipi_csis_set_params(struct csi_state *state) __mipi_csis_set_format(state); mipi_csis_write(state, MIPI_CSIS_DPHY_CMN_CTRL, - MIPI_CSIS_DPHY_CMN_CTRL_HSSETTLE(state->hs_settle)); + MIPI_CSIS_DPHY_CMN_CTRL_HSSETTLE(state->hs_settle) | + MIPI_CSIS_DPHY_CMN_CTRL_CLKSETTLE(state->clk_settle)); val = (0 << MIPI_CSIS_ISP_SYNC_HSYNC_LINTV_OFFSET) | (0 << MIPI_CSIS_ISP_SYNC_VSYNC_SINTV_OFFSET) From 492d418c082c10c97ad1ca3d35ac8c2438b4fc17 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 13 Apr 2021 04:30:00 +0200 Subject: [PATCH 165/394] media: imx: imx7_mipi_csis: Drop unused csis_hw_reset structure The csis_hw_reset structure is instantiated as a member of csi_state, but that member is never used. Drop it. Signed-off-by: Laurent Pinchart Acked-by: Rui Miguel Silva Tested-by: Frieder Schrempf Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/imx7-mipi-csis.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c index 5dc001a415d4..e01838931e6f 100644 --- a/drivers/staging/media/imx/imx7-mipi-csis.c +++ b/drivers/staging/media/imx/imx7-mipi-csis.c @@ -278,12 +278,6 @@ static const char * const mipi_csis_clk_id[] = { "phy", }; -struct csis_hw_reset { - struct regmap *src; - u8 req_src; - u8 rst_bit; -}; - struct csi_state { /* lock elements below */ struct mutex lock; @@ -321,7 +315,6 @@ struct csi_state { struct mipi_csis_event events[MIPI_CSIS_NUM_EVENTS]; - struct csis_hw_reset hw_reset; struct regulator *mipi_phy_regulator; }; From 3acb88893a799d5bd612213ea3fc67f2f3280f29 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 13 Apr 2021 04:30:01 +0200 Subject: [PATCH 166/394] media: imx: imx7_mipi_csis: Store CSI-2 data type in format structure Replace the register value stored in the csis_pix_format structure with the CSI-2 data type. The register value is simply computed from the data type using a shift. This prepares for i.MX8MP support that needs the same data type in a different hardware register. Signed-off-by: Laurent Pinchart Acked-by: Rui Miguel Silva Tested-by: Frieder Schrempf Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/imx7-mipi-csis.c | 71 +++++++++++++--------- 1 file changed, 42 insertions(+), 29 deletions(-) diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c index e01838931e6f..1036e39ce0ab 100644 --- a/drivers/staging/media/imx/imx7-mipi-csis.c +++ b/drivers/staging/media/imx/imx7-mipi-csis.c @@ -170,13 +170,7 @@ #define MIPI_CSIS_ISPCFG_PIXEL_MODE_DUAL (1 << 12) #define MIPI_CSIS_ISPCFG_PIXEL_MODE_QUAD (2 << 12) /* i.MX8M[MNP] only */ #define MIPI_CSIS_ISPCFG_ALIGN_32BIT BIT(11) -#define MIPI_CSIS_ISPCFG_FMT_YCBCR422_8BIT (0x1e << 2) -#define MIPI_CSIS_ISPCFG_FMT_RAW8 (0x2a << 2) -#define MIPI_CSIS_ISPCFG_FMT_RAW10 (0x2b << 2) -#define MIPI_CSIS_ISPCFG_FMT_RAW12 (0x2c << 2) -#define MIPI_CSIS_ISPCFG_FMT_RAW14 (0x2d << 2) -/* User defined formats, x = 1...4 */ -#define MIPI_CSIS_ISPCFG_FMT_USER(x) ((0x30 + (x) - 1) << 2) +#define MIPI_CSIS_ISPCFG_FMT(fmt) ((fmt) << 2) #define MIPI_CSIS_ISPCFG_FMT_MASK (0x3f << 2) /* ISP Image Resolution register */ @@ -223,6 +217,25 @@ #define DEFAULT_SCLK_CSIS_FREQ 166000000UL +/* MIPI CSI-2 Data Types */ +#define MIPI_CSI2_DATA_TYPE_YUV420_8 0x18 +#define MIPI_CSI2_DATA_TYPE_YUV420_10 0x19 +#define MIPI_CSI2_DATA_TYPE_LE_YUV420_8 0x1a +#define MIPI_CSI2_DATA_TYPE_CS_YUV420_8 0x1c +#define MIPI_CSI2_DATA_TYPE_CS_YUV420_10 0x1d +#define MIPI_CSI2_DATA_TYPE_YUV422_8 0x1e +#define MIPI_CSI2_DATA_TYPE_YUV422_10 0x1f +#define MIPI_CSI2_DATA_TYPE_RGB565 0x22 +#define MIPI_CSI2_DATA_TYPE_RGB666 0x23 +#define MIPI_CSI2_DATA_TYPE_RGB888 0x24 +#define MIPI_CSI2_DATA_TYPE_RAW6 0x28 +#define MIPI_CSI2_DATA_TYPE_RAW7 0x29 +#define MIPI_CSI2_DATA_TYPE_RAW8 0x2a +#define MIPI_CSI2_DATA_TYPE_RAW10 0x2b +#define MIPI_CSI2_DATA_TYPE_RAW12 0x2c +#define MIPI_CSI2_DATA_TYPE_RAW14 0x2d +#define MIPI_CSI2_DATA_TYPE_USER(x) (0x30 + (x)) + enum { ST_POWERED = 1, ST_STREAMING = 2, @@ -324,7 +337,7 @@ struct csi_state { struct csis_pix_format { u32 code; - u32 fmt_reg; + u32 data_type; u8 width; }; @@ -332,85 +345,85 @@ static const struct csis_pix_format mipi_csis_formats[] = { /* YUV formats. */ { .code = MEDIA_BUS_FMT_UYVY8_1X16, - .fmt_reg = MIPI_CSIS_ISPCFG_FMT_YCBCR422_8BIT, + .data_type = MIPI_CSI2_DATA_TYPE_YUV422_8, .width = 16, }, /* RAW (Bayer and greyscale) formats. */ { .code = MEDIA_BUS_FMT_SBGGR8_1X8, - .fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW8, + .data_type = MIPI_CSI2_DATA_TYPE_RAW8, .width = 8, }, { .code = MEDIA_BUS_FMT_SGBRG8_1X8, - .fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW8, + .data_type = MIPI_CSI2_DATA_TYPE_RAW8, .width = 8, }, { .code = MEDIA_BUS_FMT_SGRBG8_1X8, - .fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW8, + .data_type = MIPI_CSI2_DATA_TYPE_RAW8, .width = 8, }, { .code = MEDIA_BUS_FMT_SRGGB8_1X8, - .fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW8, + .data_type = MIPI_CSI2_DATA_TYPE_RAW8, .width = 8, }, { .code = MEDIA_BUS_FMT_Y8_1X8, - .fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW8, + .data_type = MIPI_CSI2_DATA_TYPE_RAW8, .width = 8, }, { .code = MEDIA_BUS_FMT_SBGGR10_1X10, - .fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW10, + .data_type = MIPI_CSI2_DATA_TYPE_RAW10, .width = 10, }, { .code = MEDIA_BUS_FMT_SGBRG10_1X10, - .fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW10, + .data_type = MIPI_CSI2_DATA_TYPE_RAW10, .width = 10, }, { .code = MEDIA_BUS_FMT_SGRBG10_1X10, - .fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW10, + .data_type = MIPI_CSI2_DATA_TYPE_RAW10, .width = 10, }, { .code = MEDIA_BUS_FMT_SRGGB10_1X10, - .fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW10, + .data_type = MIPI_CSI2_DATA_TYPE_RAW10, .width = 10, }, { .code = MEDIA_BUS_FMT_Y10_1X10, - .fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW10, + .data_type = MIPI_CSI2_DATA_TYPE_RAW10, .width = 10, }, { .code = MEDIA_BUS_FMT_SBGGR12_1X12, - .fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW12, + .data_type = MIPI_CSI2_DATA_TYPE_RAW12, .width = 12, }, { .code = MEDIA_BUS_FMT_SGBRG12_1X12, - .fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW12, + .data_type = MIPI_CSI2_DATA_TYPE_RAW12, .width = 12, }, { .code = MEDIA_BUS_FMT_SGRBG12_1X12, - .fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW12, + .data_type = MIPI_CSI2_DATA_TYPE_RAW12, .width = 12, }, { .code = MEDIA_BUS_FMT_SRGGB12_1X12, - .fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW12, + .data_type = MIPI_CSI2_DATA_TYPE_RAW12, .width = 12, }, { .code = MEDIA_BUS_FMT_Y12_1X12, - .fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW12, + .data_type = MIPI_CSI2_DATA_TYPE_RAW12, .width = 12, }, { .code = MEDIA_BUS_FMT_SBGGR14_1X14, - .fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW14, + .data_type = MIPI_CSI2_DATA_TYPE_RAW14, .width = 14, }, { .code = MEDIA_BUS_FMT_SGBRG14_1X14, - .fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW14, + .data_type = MIPI_CSI2_DATA_TYPE_RAW14, .width = 14, }, { .code = MEDIA_BUS_FMT_SGRBG14_1X14, - .fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW14, + .data_type = MIPI_CSI2_DATA_TYPE_RAW14, .width = 14, }, { .code = MEDIA_BUS_FMT_SRGGB14_1X14, - .fmt_reg = MIPI_CSIS_ISPCFG_FMT_RAW14, + .data_type = MIPI_CSI2_DATA_TYPE_RAW14, .width = 14, } }; @@ -502,7 +515,7 @@ static void __mipi_csis_set_format(struct csi_state *state) /* Color format */ val = mipi_csis_read(state, MIPI_CSIS_ISP_CONFIG_CH(0)); val &= ~(MIPI_CSIS_ISPCFG_ALIGN_32BIT | MIPI_CSIS_ISPCFG_FMT_MASK); - val |= state->csis_fmt->fmt_reg; + val |= MIPI_CSIS_ISPCFG_FMT(state->csis_fmt->data_type); mipi_csis_write(state, MIPI_CSIS_ISP_CONFIG_CH(0), val); /* Pixel resolution */ From cbf15686dd8b10f1c3c0ce29d09fc88fc3db4b9e Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 13 Apr 2021 04:30:02 +0200 Subject: [PATCH 167/394] media: imx: imx7_mipi_csis: Drop csi_state phy field The phy field of the csi_state structure is unused. Drop it. Signed-off-by: Laurent Pinchart Acked-by: Rui Miguel Silva Tested-by: Frieder Schrempf Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/imx7-mipi-csis.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c index 1036e39ce0ab..d818b066e511 100644 --- a/drivers/staging/media/imx/imx7-mipi-csis.c +++ b/drivers/staging/media/imx/imx7-mipi-csis.c @@ -304,7 +304,6 @@ struct csi_state { u8 index; struct platform_device *pdev; - struct phy *phy; void __iomem *regs; int irq; u32 flags; From b0db06bb98b55ce5040aab5133f6fcd7c0631e29 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 13 Apr 2021 04:30:03 +0200 Subject: [PATCH 168/394] media: imx: imx7_mipi_csis: Rename mipi_sd to sd The CSIS is modelled as a single subdev, there's thus no ambiguity regarding which subdev the code refers to. Rename mipi_sd to sd. Signed-off-by: Laurent Pinchart Acked-by: Rui Miguel Silva Tested-by: Frieder Schrempf Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/imx7-mipi-csis.c | 91 +++++++++++----------- 1 file changed, 45 insertions(+), 46 deletions(-) diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c index d818b066e511..382d02f54239 100644 --- a/drivers/staging/media/imx/imx7-mipi-csis.c +++ b/drivers/staging/media/imx/imx7-mipi-csis.c @@ -298,7 +298,7 @@ struct csi_state { spinlock_t slock; struct device *dev; struct media_pad pads[CSIS_PADS_NUM]; - struct v4l2_subdev mipi_sd; + struct v4l2_subdev sd; struct v4l2_async_notifier notifier; struct v4l2_subdev *src_sd; @@ -785,12 +785,12 @@ static void mipi_csis_debugfs_exit(struct csi_state *state) static struct csi_state *mipi_sd_to_csis_state(struct v4l2_subdev *sdev) { - return container_of(sdev, struct csi_state, mipi_sd); + return container_of(sdev, struct csi_state, sd); } -static int mipi_csis_s_stream(struct v4l2_subdev *mipi_sd, int enable) +static int mipi_csis_s_stream(struct v4l2_subdev *sd, int enable) { - struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + struct csi_state *state = mipi_sd_to_csis_state(sd); int ret; if (enable) { @@ -853,15 +853,15 @@ mipi_csis_get_format(struct csi_state *state, unsigned int pad) { if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_format(&state->mipi_sd, cfg, pad); + return v4l2_subdev_get_try_format(&state->sd, cfg, pad); return &state->format_mbus; } -static int mipi_csis_init_cfg(struct v4l2_subdev *mipi_sd, +static int mipi_csis_init_cfg(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg) { - struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + struct csi_state *state = mipi_sd_to_csis_state(sd); struct v4l2_mbus_framefmt *fmt_sink; struct v4l2_mbus_framefmt *fmt_source; enum v4l2_subdev_format_whence which; @@ -895,11 +895,11 @@ static int mipi_csis_init_cfg(struct v4l2_subdev *mipi_sd, return 0; } -static int mipi_csis_get_fmt(struct v4l2_subdev *mipi_sd, +static int mipi_csis_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_format *sdformat) { - struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + struct csi_state *state = mipi_sd_to_csis_state(sd); struct v4l2_mbus_framefmt *fmt; fmt = mipi_csis_get_format(state, cfg, sdformat->which, sdformat->pad); @@ -911,11 +911,11 @@ static int mipi_csis_get_fmt(struct v4l2_subdev *mipi_sd, return 0; } -static int mipi_csis_enum_mbus_code(struct v4l2_subdev *mipi_sd, +static int mipi_csis_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_mbus_code_enum *code) { - struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + struct csi_state *state = mipi_sd_to_csis_state(sd); /* * The CSIS can't transcode in any way, the source format is identical @@ -943,11 +943,11 @@ static int mipi_csis_enum_mbus_code(struct v4l2_subdev *mipi_sd, return 0; } -static int mipi_csis_set_fmt(struct v4l2_subdev *mipi_sd, +static int mipi_csis_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_format *sdformat) { - struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + struct csi_state *state = mipi_sd_to_csis_state(sd); struct csis_pix_format const *csis_fmt; struct v4l2_mbus_framefmt *fmt; unsigned int align; @@ -957,7 +957,7 @@ static int mipi_csis_set_fmt(struct v4l2_subdev *mipi_sd, * modified. */ if (sdformat->pad == CSIS_PAD_SOURCE) - return mipi_csis_get_fmt(mipi_sd, cfg, sdformat); + return mipi_csis_get_fmt(sd, cfg, sdformat); if (sdformat->pad != CSIS_PAD_SINK) return -EINVAL; @@ -1021,9 +1021,9 @@ static int mipi_csis_set_fmt(struct v4l2_subdev *mipi_sd, return 0; } -static int mipi_csis_log_status(struct v4l2_subdev *mipi_sd) +static int mipi_csis_log_status(struct v4l2_subdev *sd) { - struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + struct csi_state *state = mipi_sd_to_csis_state(sd); mutex_lock(&state->lock); mipi_csis_log_counters(state, true); @@ -1063,8 +1063,8 @@ static int mipi_csis_link_setup(struct media_entity *entity, const struct media_pad *local_pad, const struct media_pad *remote_pad, u32 flags) { - struct v4l2_subdev *mipi_sd = media_entity_to_v4l2_subdev(entity); - struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); + struct csi_state *state = mipi_sd_to_csis_state(sd); struct v4l2_subdev *remote_sd; dev_dbg(state->dev, "link setup %s -> %s", remote_pad->entity->name, @@ -1109,7 +1109,7 @@ static int mipi_csis_notify_bound(struct v4l2_async_notifier *notifier, struct v4l2_async_subdev *asd) { struct csi_state *state = mipi_notifier_to_csis_state(notifier); - struct media_pad *sink = &state->mipi_sd.entity.pads[CSIS_PAD_SINK]; + struct media_pad *sink = &state->sd.entity.pads[CSIS_PAD_SINK]; return v4l2_create_fwnode_links_to_pad(sd, sink, 0); } @@ -1154,12 +1154,11 @@ static int mipi_csis_async_register(struct csi_state *state) state->notifier.ops = &mipi_csis_notify_ops; - ret = v4l2_async_subdev_notifier_register(&state->mipi_sd, - &state->notifier); + ret = v4l2_async_subdev_notifier_register(&state->sd, &state->notifier); if (ret) return ret; - return v4l2_async_register_subdev(&state->mipi_sd); + return v4l2_async_register_subdev(&state->sd); err_parse: fwnode_handle_put(ep); @@ -1173,8 +1172,8 @@ err_parse: static int mipi_csis_pm_suspend(struct device *dev, bool runtime) { - struct v4l2_subdev *mipi_sd = dev_get_drvdata(dev); - struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + struct v4l2_subdev *sd = dev_get_drvdata(dev); + struct csi_state *state = mipi_sd_to_csis_state(sd); int ret = 0; mutex_lock(&state->lock); @@ -1197,8 +1196,8 @@ unlock: static int mipi_csis_pm_resume(struct device *dev, bool runtime) { - struct v4l2_subdev *mipi_sd = dev_get_drvdata(dev); - struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + struct v4l2_subdev *sd = dev_get_drvdata(dev); + struct csi_state *state = mipi_sd_to_csis_state(sd); int ret = 0; mutex_lock(&state->lock); @@ -1254,33 +1253,33 @@ static const struct dev_pm_ops mipi_csis_pm_ops = { * Probe/remove & platform driver */ -static int mipi_csis_subdev_init(struct v4l2_subdev *mipi_sd, +static int mipi_csis_subdev_init(struct v4l2_subdev *sd, struct platform_device *pdev, const struct v4l2_subdev_ops *ops) { - struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + struct csi_state *state = mipi_sd_to_csis_state(sd); - v4l2_subdev_init(mipi_sd, ops); - mipi_sd->owner = THIS_MODULE; - snprintf(mipi_sd->name, sizeof(mipi_sd->name), "%s.%d", + v4l2_subdev_init(sd, ops); + sd->owner = THIS_MODULE; + snprintf(sd->name, sizeof(sd->name), "%s.%d", CSIS_SUBDEV_NAME, state->index); - mipi_sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; - mipi_sd->ctrl_handler = NULL; + sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; + sd->ctrl_handler = NULL; - mipi_sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; - mipi_sd->entity.ops = &mipi_csis_entity_ops; + sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; + sd->entity.ops = &mipi_csis_entity_ops; - mipi_sd->dev = &pdev->dev; + sd->dev = &pdev->dev; state->csis_fmt = &mipi_csis_formats[0]; - mipi_csis_init_cfg(mipi_sd, NULL); + mipi_csis_init_cfg(sd, NULL); state->pads[CSIS_PAD_SINK].flags = MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_MUST_CONNECT; state->pads[CSIS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE | MEDIA_PAD_FL_MUST_CONNECT; - return media_entity_pads_init(&mipi_sd->entity, CSIS_PADS_NUM, + return media_entity_pads_init(&sd->entity, CSIS_PADS_NUM, state->pads); } @@ -1353,10 +1352,10 @@ static int mipi_csis_probe(struct platform_device *pdev) goto disable_clock; } - platform_set_drvdata(pdev, &state->mipi_sd); + platform_set_drvdata(pdev, &state->sd); mutex_init(&state->lock); - ret = mipi_csis_subdev_init(&state->mipi_sd, pdev, + ret = mipi_csis_subdev_init(&state->sd, pdev, &mipi_csis_subdev_ops); if (ret < 0) goto disable_clock; @@ -1385,10 +1384,10 @@ static int mipi_csis_probe(struct platform_device *pdev) unregister_all: mipi_csis_debugfs_exit(state); cleanup: - media_entity_cleanup(&state->mipi_sd.entity); + media_entity_cleanup(&state->sd.entity); v4l2_async_notifier_unregister(&state->notifier); v4l2_async_notifier_cleanup(&state->notifier); - v4l2_async_unregister_subdev(&state->mipi_sd); + v4l2_async_unregister_subdev(&state->sd); disable_clock: mipi_csis_clk_disable(state); mutex_destroy(&state->lock); @@ -1398,18 +1397,18 @@ disable_clock: static int mipi_csis_remove(struct platform_device *pdev) { - struct v4l2_subdev *mipi_sd = platform_get_drvdata(pdev); - struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); + struct v4l2_subdev *sd = platform_get_drvdata(pdev); + struct csi_state *state = mipi_sd_to_csis_state(sd); mipi_csis_debugfs_exit(state); v4l2_async_notifier_unregister(&state->notifier); v4l2_async_notifier_cleanup(&state->notifier); - v4l2_async_unregister_subdev(&state->mipi_sd); + v4l2_async_unregister_subdev(&state->sd); pm_runtime_disable(&pdev->dev); mipi_csis_pm_suspend(&pdev->dev, true); mipi_csis_clk_disable(state); - media_entity_cleanup(&state->mipi_sd.entity); + media_entity_cleanup(&state->sd.entity); mutex_destroy(&state->lock); pm_runtime_set_suspended(&pdev->dev); From f65ffcd8abf976d90c6fbcb1c1045c22974dfd81 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 13 Apr 2021 04:30:04 +0200 Subject: [PATCH 169/394] media: imx: imx7_mipi_csis: Rename csi_state flag field to state The flag field of the csi_state structure contains the device state. Rename it accordingly. Signed-off-by: Laurent Pinchart Acked-by: Rui Miguel Silva Tested-by: Frieder Schrempf Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/imx7-mipi-csis.c | 26 +++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c index 382d02f54239..a8e0a5c487a0 100644 --- a/drivers/staging/media/imx/imx7-mipi-csis.c +++ b/drivers/staging/media/imx/imx7-mipi-csis.c @@ -306,7 +306,7 @@ struct csi_state { struct platform_device *pdev; void __iomem *regs; int irq; - u32 flags; + u32 state; struct dentry *debugfs_root; bool debug; @@ -812,7 +812,7 @@ static int mipi_csis_s_stream(struct v4l2_subdev *sd, int enable) mutex_lock(&state->lock); if (enable) { - if (state->flags & ST_SUSPENDED) { + if (state->state & ST_SUSPENDED) { ret = -EBUSY; goto unlock; } @@ -824,14 +824,14 @@ static int mipi_csis_s_stream(struct v4l2_subdev *sd, int enable) mipi_csis_log_counters(state, true); - state->flags |= ST_STREAMING; + state->state |= ST_STREAMING; } else { v4l2_subdev_call(state->src_sd, video, s_stream, 0); ret = v4l2_subdev_call(state->src_sd, core, s_power, 0); if (ret == -ENOIOCTLCMD) ret = 0; mipi_csis_stop_stream(state); - state->flags &= ~ST_STREAMING; + state->state &= ~ST_STREAMING; if (state->debug) mipi_csis_log_counters(state, true); } @@ -1027,7 +1027,7 @@ static int mipi_csis_log_status(struct v4l2_subdev *sd) mutex_lock(&state->lock); mipi_csis_log_counters(state, true); - if (state->debug && (state->flags & ST_POWERED)) + if (state->debug && (state->state & ST_POWERED)) mipi_csis_dump_regs(state); mutex_unlock(&state->lock); @@ -1177,15 +1177,15 @@ static int mipi_csis_pm_suspend(struct device *dev, bool runtime) int ret = 0; mutex_lock(&state->lock); - if (state->flags & ST_POWERED) { + if (state->state & ST_POWERED) { mipi_csis_stop_stream(state); ret = regulator_disable(state->mipi_phy_regulator); if (ret) goto unlock; mipi_csis_clk_disable(state); - state->flags &= ~ST_POWERED; + state->state &= ~ST_POWERED; if (!runtime) - state->flags |= ST_SUSPENDED; + state->state |= ST_SUSPENDED; } unlock: @@ -1201,21 +1201,21 @@ static int mipi_csis_pm_resume(struct device *dev, bool runtime) int ret = 0; mutex_lock(&state->lock); - if (!runtime && !(state->flags & ST_SUSPENDED)) + if (!runtime && !(state->state & ST_SUSPENDED)) goto unlock; - if (!(state->flags & ST_POWERED)) { + if (!(state->state & ST_POWERED)) { ret = regulator_enable(state->mipi_phy_regulator); if (ret) goto unlock; - state->flags |= ST_POWERED; + state->state |= ST_POWERED; mipi_csis_clk_enable(state); } - if (state->flags & ST_STREAMING) + if (state->state & ST_STREAMING) mipi_csis_start_stream(state); - state->flags &= ~ST_SUSPENDED; + state->state &= ~ST_SUSPENDED; unlock: mutex_unlock(&state->lock); From e71bcbe65f67abdcc144729c9bad957424043b81 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 13 Apr 2021 04:30:05 +0200 Subject: [PATCH 170/394] media: imx: imx7_mipi_csis: Turn csi_state irq field into local variable The irq field of the csi_state structure is only used in mipi_csis_probe(). Turn it into a local variable. Signed-off-by: Laurent Pinchart Acked-by: Rui Miguel Silva Tested-by: Frieder Schrempf Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/imx7-mipi-csis.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c index a8e0a5c487a0..89e9a2cc7784 100644 --- a/drivers/staging/media/imx/imx7-mipi-csis.c +++ b/drivers/staging/media/imx/imx7-mipi-csis.c @@ -305,7 +305,6 @@ struct csi_state { u8 index; struct platform_device *pdev; void __iomem *regs; - int irq; u32 state; struct dentry *debugfs_root; @@ -1304,6 +1303,7 @@ static int mipi_csis_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct csi_state *state; + int irq; int ret; state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL); @@ -1331,9 +1331,9 @@ static int mipi_csis_probe(struct platform_device *pdev) if (IS_ERR(state->regs)) return PTR_ERR(state->regs); - state->irq = platform_get_irq(pdev, 0); - if (state->irq < 0) - return state->irq; + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; ret = mipi_csis_clk_get(state); if (ret < 0) @@ -1345,8 +1345,8 @@ static int mipi_csis_probe(struct platform_device *pdev) return ret; } - ret = devm_request_irq(dev, state->irq, mipi_csis_irq_handler, - 0, dev_name(dev), state); + ret = devm_request_irq(dev, irq, mipi_csis_irq_handler, 0, + dev_name(dev), state); if (ret) { dev_err(dev, "Interrupt request failed\n"); goto disable_clock; From deb1c97283a4065ae99bbb67b9b373dd02826d13 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 13 Apr 2021 04:30:06 +0200 Subject: [PATCH 171/394] media: imx: imx7_mipi_csis: Don't pass pdev to mipi_csis_parse_dt() The mipi_csis_parse_dt() function is called with a pointer to the csi_state, which contains all the information necessary. Don't pass the platform device pointer as well. Signed-off-by: Laurent Pinchart Acked-by: Rui Miguel Silva Tested-by: Frieder Schrempf Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/imx7-mipi-csis.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c index 89e9a2cc7784..4d1819b7c9c4 100644 --- a/drivers/staging/media/imx/imx7-mipi-csis.c +++ b/drivers/staging/media/imx/imx7-mipi-csis.c @@ -1282,17 +1282,16 @@ static int mipi_csis_subdev_init(struct v4l2_subdev *sd, state->pads); } -static int mipi_csis_parse_dt(struct platform_device *pdev, - struct csi_state *state) +static int mipi_csis_parse_dt(struct csi_state *state) { - struct device_node *node = pdev->dev.of_node; + struct device_node *node = state->dev->of_node; if (of_property_read_u32(node, "clock-frequency", &state->clk_frequency)) state->clk_frequency = DEFAULT_SCLK_CSIS_FREQ; /* Get MIPI PHY resets */ - state->mrst = devm_reset_control_get_exclusive(&pdev->dev, NULL); + state->mrst = devm_reset_control_get_exclusive(state->dev, NULL); if (IS_ERR(state->mrst)) return PTR_ERR(state->mrst); @@ -1315,7 +1314,7 @@ static int mipi_csis_probe(struct platform_device *pdev) state->pdev = pdev; state->dev = dev; - ret = mipi_csis_parse_dt(pdev, state); + ret = mipi_csis_parse_dt(state); if (ret < 0) { dev_err(dev, "Failed to parse device tree: %d\n", ret); return ret; From 96703073ecb36376579c7b8e2a34dbaf025909cb Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 13 Apr 2021 04:30:07 +0200 Subject: [PATCH 172/394] media: imx: imx7_mipi_csis: Pass csi_state to mipi_csis_subdev_init() Pass the csi_state pointer to the mipi_csis_subdev_init() function, instead of miscellaneous information scattered in different arguments. Signed-off-by: Laurent Pinchart Acked-by: Rui Miguel Silva Tested-by: Frieder Schrempf Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/imx7-mipi-csis.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c index 4d1819b7c9c4..5e2ae59fc9df 100644 --- a/drivers/staging/media/imx/imx7-mipi-csis.c +++ b/drivers/staging/media/imx/imx7-mipi-csis.c @@ -1252,13 +1252,11 @@ static const struct dev_pm_ops mipi_csis_pm_ops = { * Probe/remove & platform driver */ -static int mipi_csis_subdev_init(struct v4l2_subdev *sd, - struct platform_device *pdev, - const struct v4l2_subdev_ops *ops) +static int mipi_csis_subdev_init(struct csi_state *state) { - struct csi_state *state = mipi_sd_to_csis_state(sd); + struct v4l2_subdev *sd = &state->sd; - v4l2_subdev_init(sd, ops); + v4l2_subdev_init(sd, &mipi_csis_subdev_ops); sd->owner = THIS_MODULE; snprintf(sd->name, sizeof(sd->name), "%s.%d", CSIS_SUBDEV_NAME, state->index); @@ -1269,7 +1267,7 @@ static int mipi_csis_subdev_init(struct v4l2_subdev *sd, sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; sd->entity.ops = &mipi_csis_entity_ops; - sd->dev = &pdev->dev; + sd->dev = state->dev; state->csis_fmt = &mipi_csis_formats[0]; mipi_csis_init_cfg(sd, NULL); @@ -1354,8 +1352,7 @@ static int mipi_csis_probe(struct platform_device *pdev) platform_set_drvdata(pdev, &state->sd); mutex_init(&state->lock); - ret = mipi_csis_subdev_init(&state->sd, pdev, - &mipi_csis_subdev_ops); + ret = mipi_csis_subdev_init(state); if (ret < 0) goto disable_clock; From 62bd05a4f9fffe17f9bddb9f5d28fe229c200abd Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 13 Apr 2021 04:30:08 +0200 Subject: [PATCH 173/394] media: imx: imx7_mipi_csis: Drop csi_state pdev field The pdev field of the csi_state structure is only used to access the device pointer, which is stored in a separate field. Drop the pdev field, as well as a few local dev variables. Signed-off-by: Laurent Pinchart Acked-by: Rui Miguel Silva Tested-by: Frieder Schrempf Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/imx7-mipi-csis.c | 30 ++++++++++------------ 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c index 5e2ae59fc9df..5c7f9f28103b 100644 --- a/drivers/staging/media/imx/imx7-mipi-csis.c +++ b/drivers/staging/media/imx/imx7-mipi-csis.c @@ -303,7 +303,6 @@ struct csi_state { struct v4l2_subdev *src_sd; u8 index; - struct platform_device *pdev; void __iomem *regs; u32 state; @@ -615,13 +614,12 @@ static void mipi_csis_clk_disable(struct csi_state *state) static int mipi_csis_clk_get(struct csi_state *state) { - struct device *dev = &state->pdev->dev; unsigned int i; int ret; state->num_clks = ARRAY_SIZE(mipi_csis_clk_id); - state->clks = devm_kcalloc(dev, state->num_clks, sizeof(*state->clks), - GFP_KERNEL); + state->clks = devm_kcalloc(state->dev, state->num_clks, + sizeof(*state->clks), GFP_KERNEL); if (!state->clks) return -ENOMEM; @@ -629,7 +627,7 @@ static int mipi_csis_clk_get(struct csi_state *state) for (i = 0; i < state->num_clks; i++) state->clks[i].id = mipi_csis_clk_id[i]; - ret = devm_clk_bulk_get(dev, state->num_clks, state->clks); + ret = devm_clk_bulk_get(state->dev, state->num_clks, state->clks); if (ret < 0) return ret; @@ -637,8 +635,8 @@ static int mipi_csis_clk_get(struct csi_state *state) ret = clk_set_rate(state->clks[MIPI_CSIS_CLK_WRAP].clk, state->clk_frequency); if (ret < 0) - dev_err(dev, "set rate=%d failed: %d\n", state->clk_frequency, - ret); + dev_err(state->dev, "set rate=%d failed: %d\n", + state->clk_frequency, ret); return ret; } @@ -707,7 +705,6 @@ static void mipi_csis_log_counters(struct csi_state *state, bool non_errors) { unsigned int num_events = non_errors ? MIPI_CSIS_NUM_EVENTS : MIPI_CSIS_NUM_EVENTS - 8; - struct device *dev = &state->pdev->dev; unsigned long flags; unsigned int i; @@ -715,7 +712,8 @@ static void mipi_csis_log_counters(struct csi_state *state, bool non_errors) for (i = 0; i < num_events; ++i) { if (state->events[i].counter > 0 || state->debug) - dev_info(dev, "%s events: %d\n", state->events[i].name, + dev_info(state->dev, "%s events: %d\n", + state->events[i].name, state->events[i].counter); } spin_unlock_irqrestore(&state->slock, flags); @@ -741,15 +739,14 @@ static int mipi_csis_dump_regs(struct csi_state *state) { MIPI_CSIS_DBG_CTRL, "DBG_CTRL" }, }; - struct device *dev = &state->pdev->dev; unsigned int i; u32 cfg; - dev_info(dev, "--- REGISTERS ---\n"); + dev_info(state->dev, "--- REGISTERS ---\n"); for (i = 0; i < ARRAY_SIZE(registers); i++) { cfg = mipi_csis_read(state, registers[i].offset); - dev_info(dev, "%14s: 0x%08x\n", registers[i].name, cfg); + dev_info(state->dev, "%14s: 0x%08x\n", registers[i].name, cfg); } return 0; @@ -799,7 +796,7 @@ static int mipi_csis_s_stream(struct v4l2_subdev *sd, int enable) mipi_csis_clear_counters(state); - ret = pm_runtime_resume_and_get(&state->pdev->dev); + ret = pm_runtime_resume_and_get(state->dev); if (ret < 0) return ret; @@ -840,7 +837,7 @@ unlock: done: if (!enable || ret < 0) - pm_runtime_put(&state->pdev->dev); + pm_runtime_put(state->dev); return ret; } @@ -1309,7 +1306,6 @@ static int mipi_csis_probe(struct platform_device *pdev) spin_lock_init(&state->slock); - state->pdev = pdev; state->dev = dev; ret = mipi_csis_parse_dt(state); @@ -1358,7 +1354,7 @@ static int mipi_csis_probe(struct platform_device *pdev) ret = mipi_csis_async_register(state); if (ret < 0) { - dev_err(&pdev->dev, "async register failed: %d\n", ret); + dev_err(dev, "async register failed: %d\n", ret); goto cleanup; } @@ -1372,7 +1368,7 @@ static int mipi_csis_probe(struct platform_device *pdev) goto unregister_all; } - dev_info(&pdev->dev, "lanes: %d, freq: %u\n", + dev_info(dev, "lanes: %d, freq: %u\n", state->bus.num_data_lanes, state->clk_frequency); return 0; From b4eb02656d0944e03eb991f3feda52f653693653 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 13 Apr 2021 04:30:09 +0200 Subject: [PATCH 174/394] media: imx: imx7_mipi_csis: Make csi_state num_clocks field unsigned The num_clocks field of the csi_state only stores positive values, make it unsigned. Signed-off-by: Laurent Pinchart Acked-by: Rui Miguel Silva Tested-by: Frieder Schrempf Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/imx7-mipi-csis.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c index 5c7f9f28103b..363aa28fae57 100644 --- a/drivers/staging/media/imx/imx7-mipi-csis.c +++ b/drivers/staging/media/imx/imx7-mipi-csis.c @@ -309,7 +309,7 @@ struct csi_state { struct dentry *debugfs_root; bool debug; - int num_clks; + unsigned int num_clks; struct clk_bulk_data *clks; u32 clk_frequency; From 0092d4a8ea7f7414a2ca64d455e2fdb0306d8d56 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 13 Apr 2021 04:30:10 +0200 Subject: [PATCH 175/394] media: imx: imx7_mipi_csis: Reorganize csi_state structure Group the fiels of the csi_state structure logically to improve readability. Signed-off-by: Laurent Pinchart Acked-by: Rui Miguel Silva Tested-by: Frieder Schrempf Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/imx7-mipi-csis.c | 35 +++++++++------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c index 363aa28fae57..c302b095ce74 100644 --- a/drivers/staging/media/imx/imx7-mipi-csis.c +++ b/drivers/staging/media/imx/imx7-mipi-csis.c @@ -292,40 +292,33 @@ static const char * const mipi_csis_clk_id[] = { }; struct csi_state { - /* lock elements below */ - struct mutex lock; - /* lock for event handler */ - spinlock_t slock; struct device *dev; - struct media_pad pads[CSIS_PADS_NUM]; + void __iomem *regs; + unsigned int num_clks; + struct clk_bulk_data *clks; + struct reset_control *mrst; + struct regulator *mipi_phy_regulator; + u8 index; + struct v4l2_subdev sd; + struct media_pad pads[CSIS_PADS_NUM]; struct v4l2_async_notifier notifier; struct v4l2_subdev *src_sd; - u8 index; - void __iomem *regs; - u32 state; - - struct dentry *debugfs_root; - bool debug; - - unsigned int num_clks; - struct clk_bulk_data *clks; - + struct v4l2_fwnode_bus_mipi_csi2 bus; u32 clk_frequency; u32 hs_settle; u32 clk_settle; - struct reset_control *mrst; - + struct mutex lock; /* Protect csis_fmt, format_mbus and state */ const struct csis_pix_format *csis_fmt; struct v4l2_mbus_framefmt format_mbus; + u32 state; - struct v4l2_fwnode_bus_mipi_csi2 bus; - + spinlock_t slock; /* Protect events */ struct mipi_csis_event events[MIPI_CSIS_NUM_EVENTS]; - - struct regulator *mipi_phy_regulator; + struct dentry *debugfs_root; + bool debug; }; /* ----------------------------------------------------------------------------- From 7479454cfef039f208cfd1e5b6cead38dc0caa05 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 13 Apr 2021 04:30:11 +0200 Subject: [PATCH 176/394] media: imx: imx7_mipi_csis: Reorganize mipi_csis_probe() Group the operations performed in mipi_csis_probe() logically to improve readability. Signed-off-by: Laurent Pinchart Acked-by: Rui Miguel Silva Tested-by: Frieder Schrempf Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/imx7-mipi-csis.c | 30 ++++++++++++++-------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c index c302b095ce74..a1eaccc922a2 100644 --- a/drivers/staging/media/imx/imx7-mipi-csis.c +++ b/drivers/staging/media/imx/imx7-mipi-csis.c @@ -1297,22 +1297,21 @@ static int mipi_csis_probe(struct platform_device *pdev) if (!state) return -ENOMEM; + mutex_init(&state->lock); spin_lock_init(&state->slock); state->dev = dev; + memcpy(state->events, mipi_csis_events, sizeof(state->events)); + + /* Parse DT properties. */ ret = mipi_csis_parse_dt(state); if (ret < 0) { dev_err(dev, "Failed to parse device tree: %d\n", ret); return ret; } - ret = mipi_csis_phy_init(state); - if (ret < 0) - return ret; - - mipi_csis_phy_reset(state); - + /* Acquire resources. */ state->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(state->regs)) return PTR_ERR(state->regs); @@ -1321,16 +1320,24 @@ static int mipi_csis_probe(struct platform_device *pdev) if (irq < 0) return irq; + ret = mipi_csis_phy_init(state); + if (ret < 0) + return ret; + ret = mipi_csis_clk_get(state); if (ret < 0) return ret; + /* Reset PHY and enable the clocks. */ + mipi_csis_phy_reset(state); + ret = mipi_csis_clk_enable(state); if (ret < 0) { dev_err(state->dev, "failed to enable clocks: %d\n", ret); return ret; } + /* Now that the hardware is initialized, request the interrupt. */ ret = devm_request_irq(dev, irq, mipi_csis_irq_handler, 0, dev_name(dev), state); if (ret) { @@ -1338,22 +1345,23 @@ static int mipi_csis_probe(struct platform_device *pdev) goto disable_clock; } - platform_set_drvdata(pdev, &state->sd); - - mutex_init(&state->lock); + /* Initialize and register the subdev. */ ret = mipi_csis_subdev_init(state); if (ret < 0) goto disable_clock; + platform_set_drvdata(pdev, &state->sd); + ret = mipi_csis_async_register(state); if (ret < 0) { dev_err(dev, "async register failed: %d\n", ret); goto cleanup; } - memcpy(state->events, mipi_csis_events, sizeof(state->events)); - + /* Initialize debugfs. */ mipi_csis_debugfs_init(state); + + /* Enable runtime PM. */ pm_runtime_enable(dev); if (!pm_runtime_enabled(dev)) { ret = mipi_csis_pm_resume(dev, true); From 88fc81388df942e580b65afa197c97c490b5b855 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 13 Apr 2021 04:30:12 +0200 Subject: [PATCH 177/394] media: imx: imx7_mipi_csis: Reject invalid data-lanes settings The CSIS doesn't support data lanes reordering. Reject invalid settings. Signed-off-by: Laurent Pinchart Acked-by: Rui Miguel Silva Tested-by: Frieder Schrempf Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/imx7-mipi-csis.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c index a1eaccc922a2..14ff785ba5d5 100644 --- a/drivers/staging/media/imx/imx7-mipi-csis.c +++ b/drivers/staging/media/imx/imx7-mipi-csis.c @@ -1114,6 +1114,7 @@ static int mipi_csis_async_register(struct csi_state *state) }; struct v4l2_async_subdev *asd; struct fwnode_handle *ep; + unsigned int i; int ret; v4l2_async_notifier_init(&state->notifier); @@ -1127,6 +1128,14 @@ static int mipi_csis_async_register(struct csi_state *state) if (ret) goto err_parse; + for (i = 0; i < vep.bus.mipi_csi2.num_data_lanes; ++i) { + if (vep.bus.mipi_csi2.data_lanes[i] != i + 1) { + dev_err(state->dev, + "data lanes reordering is not supported"); + goto err_parse; + } + } + state->bus = vep.bus.mipi_csi2; dev_dbg(state->dev, "data lanes: %d\n", state->bus.num_data_lanes); From acdff8e14ae9e992526d050f8cee2264710de33e Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sun, 16 May 2021 00:32:26 +0200 Subject: [PATCH 178/394] media: imx: imx7_mipi_csis: Move PHY control to dedicated functions Move the PHY regulator and reset handling to dedicated functions. This groups all related code together, and prepares for i.MX8 support that doesn't require control of the PHY regulator and reset. Signed-off-by: Laurent Pinchart Acked-by: Rui Miguel Silva Tested-by: Frieder Schrempf Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/imx7-mipi-csis.c | 64 +++++++++++++--------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c index 14ff785ba5d5..3c43441653c3 100644 --- a/drivers/staging/media/imx/imx7-mipi-csis.c +++ b/drivers/staging/media/imx/imx7-mipi-csis.c @@ -457,25 +457,6 @@ static void mipi_csis_sw_reset(struct csi_state *state) usleep_range(10, 20); } -static int mipi_csis_phy_init(struct csi_state *state) -{ - state->mipi_phy_regulator = devm_regulator_get(state->dev, "phy"); - if (IS_ERR(state->mipi_phy_regulator)) - return PTR_ERR(state->mipi_phy_regulator); - - return regulator_set_voltage(state->mipi_phy_regulator, 1000000, - 1000000); -} - -static void mipi_csis_phy_reset(struct csi_state *state) -{ - reset_control_assert(state->mrst); - - msleep(20); - - reset_control_deassert(state->mrst); -} - static void mipi_csis_system_enable(struct csi_state *state, int on) { u32 val, mask; @@ -679,6 +660,42 @@ static irqreturn_t mipi_csis_irq_handler(int irq, void *dev_id) return IRQ_HANDLED; } +/* ----------------------------------------------------------------------------- + * PHY regulator and reset + */ + +static int mipi_csis_phy_enable(struct csi_state *state) +{ + return regulator_enable(state->mipi_phy_regulator); +} + +static int mipi_csis_phy_disable(struct csi_state *state) +{ + return regulator_disable(state->mipi_phy_regulator); +} + +static void mipi_csis_phy_reset(struct csi_state *state) +{ + reset_control_assert(state->mrst); + msleep(20); + reset_control_deassert(state->mrst); +} + +static int mipi_csis_phy_init(struct csi_state *state) +{ + /* Get MIPI PHY reset and regulator. */ + state->mrst = devm_reset_control_get_exclusive(state->dev, NULL); + if (IS_ERR(state->mrst)) + return PTR_ERR(state->mrst); + + state->mipi_phy_regulator = devm_regulator_get(state->dev, "phy"); + if (IS_ERR(state->mipi_phy_regulator)) + return PTR_ERR(state->mipi_phy_regulator); + + return regulator_set_voltage(state->mipi_phy_regulator, 1000000, + 1000000); +} + /* ----------------------------------------------------------------------------- * Debug */ @@ -1177,7 +1194,7 @@ static int mipi_csis_pm_suspend(struct device *dev, bool runtime) mutex_lock(&state->lock); if (state->state & ST_POWERED) { mipi_csis_stop_stream(state); - ret = regulator_disable(state->mipi_phy_regulator); + ret = mipi_csis_phy_disable(state); if (ret) goto unlock; mipi_csis_clk_disable(state); @@ -1203,7 +1220,7 @@ static int mipi_csis_pm_resume(struct device *dev, bool runtime) goto unlock; if (!(state->state & ST_POWERED)) { - ret = regulator_enable(state->mipi_phy_regulator); + ret = mipi_csis_phy_enable(state); if (ret) goto unlock; @@ -1287,11 +1304,6 @@ static int mipi_csis_parse_dt(struct csi_state *state) &state->clk_frequency)) state->clk_frequency = DEFAULT_SCLK_CSIS_FREQ; - /* Get MIPI PHY resets */ - state->mrst = devm_reset_control_get_exclusive(state->dev, NULL); - if (IS_ERR(state->mrst)) - return PTR_ERR(state->mrst); - return 0; } From 85b62ff2cb971c53a9a0cfafd31b07a92bb0fa19 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sun, 18 Apr 2021 22:15:56 +0200 Subject: [PATCH 179/394] media: dt-bindings: media: nxp,imx7-mipi-csi2: Add i.MX8MM support The i.MX8MM integrates a newer version of the CSIS CSI-2 receiver as the i.MX7 family. Differences in integration are are: - An additional clock is required - Up to 4 data lanes are supported - No reset or PHY supply is present Support it in the DT binding. Signed-off-by: Laurent Pinchart Acked-by: Rui Miguel Silva Reviewed-by: Rob Herring Signed-off-by: Mauro Carvalho Chehab --- .../bindings/media/nxp,imx7-mipi-csi2.yaml | 109 +++++++++++++++--- 1 file changed, 95 insertions(+), 14 deletions(-) diff --git a/Documentation/devicetree/bindings/media/nxp,imx7-mipi-csi2.yaml b/Documentation/devicetree/bindings/media/nxp,imx7-mipi-csi2.yaml index d8ed480482b9..7c09eec78ce5 100644 --- a/Documentation/devicetree/bindings/media/nxp,imx7-mipi-csi2.yaml +++ b/Documentation/devicetree/bindings/media/nxp,imx7-mipi-csi2.yaml @@ -4,15 +4,17 @@ $id: http://devicetree.org/schemas/media/nxp,imx7-mipi-csi2.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: NXP i.MX7 MIPI CSI-2 receiver +title: NXP i.MX7 and i.MX8 MIPI CSI-2 receiver maintainers: - Rui Miguel Silva + - Laurent Pinchart description: |- - The NXP i.MX7 SoC family includes a MIPI CSI-2 receiver IP core, documented - as "CSIS V3.3". The IP core seems to originate from Samsung, and may be - compatible with some of the Exynos4 ad S5P SoCs. + The NXP i.MX7 and i.MX8 families contain SoCs that include a MIPI CSI-2 + receiver IP core named CSIS. The IP core originates from Samsung, and may be + compatible with some of the Exynos4 and S5P SoCs. i.MX7 SoCs use CSIS version + 3.3, and i.MX8 SoCs use CSIS version 3.6.3. While the CSI-2 receiver is separate from the MIPI D-PHY IP core, the PHY is completely wrapped by the CSIS and doesn't expose a control interface of its @@ -20,7 +22,9 @@ description: |- properties: compatible: - const: fsl,imx7-mipi-csi2 + enum: + - fsl,imx7-mipi-csi2 + - fsl,imx8mm-mipi-csi2 reg: maxItems: 1 @@ -29,16 +33,20 @@ properties: maxItems: 1 clocks: + minItems: 3 items: - description: The peripheral clock (a.k.a. APB clock) - description: The external clock (optionally used as the pixel clock) - description: The MIPI D-PHY clock + - description: The AXI clock clock-names: + minItems: 3 items: - const: pclk - const: wrap - const: phy + - const: axi power-domains: maxItems: 1 @@ -71,16 +79,30 @@ properties: properties: data-lanes: - oneOf: - - items: - - const: 1 - - items: - - const: 1 - - const: 2 + items: + minItems: 1 + maxItems: 4 + items: + - const: 1 + - const: 2 + - const: 3 + - const: 4 required: - data-lanes + allOf: + - if: + properties: + compatible: + contains: + const: fsl,imx7-mipi-csi2 + then: + properties: + data-lanes: + items: + maxItems: 2 + port@1: $ref: /schemas/graph.yaml#/properties/port description: @@ -93,12 +115,29 @@ required: - clocks - clock-names - power-domains - - phy-supply - - resets - ports additionalProperties: false +allOf: + - if: + properties: + compatible: + contains: + const: fsl,imx7-mipi-csi2 + then: + required: + - phy-supply + - resets + else: + properties: + clocks: + minItems: 4 + clock-names: + minItems: 4 + phy-supply: false + resets: false + examples: - | #include @@ -106,7 +145,7 @@ examples: #include #include - mipi_csi: mipi-csi@30750000 { + mipi-csi@30750000 { compatible = "fsl,imx7-mipi-csi2"; reg = <0x30750000 0x10000>; interrupts = ; @@ -144,4 +183,46 @@ examples: }; }; + - | + #include + #include + #include + + mipi-csi@32e30000 { + compatible = "fsl,imx8mm-mipi-csi2"; + reg = <0x32e30000 0x1000>; + interrupts = ; + clock-frequency = <333000000>; + clocks = <&clk IMX8MM_CLK_DISP_APB_ROOT>, + <&clk IMX8MM_CLK_CSI1_ROOT>, + <&clk IMX8MM_CLK_CSI1_PHY_REF>, + <&clk IMX8MM_CLK_DISP_AXI_ROOT>; + clock-names = "pclk", "wrap", "phy", "axi"; + power-domains = <&mipi_pd>; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + imx8mm_mipi_csi_in: endpoint { + remote-endpoint = <&imx477_out>; + data-lanes = <1 2 3 4>; + }; + }; + + port@1 { + reg = <1>; + + imx8mm_mipi_csi_out: endpoint { + remote-endpoint = <&csi_in>; + }; + }; + }; + }; + ... From f0e7cfbb43f1961f12b9903f602b6e6ddf1ada02 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 13 Apr 2021 04:30:14 +0200 Subject: [PATCH 180/394] media: imx: imx7_mipi_csis: Add i.MX8MM support The CSI-2 receiver in the i.MX8MM is a newer version of the one found in the i.MX7. Differences are minimal, support it in the imx7_mipi_csis driver. Signed-off-by: Laurent Pinchart Acked-by: Rui Miguel Silva Tested-by: Frieder Schrempf Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/imx7-mipi-csis.c | 59 ++++++++++++++++++---- 1 file changed, 49 insertions(+), 10 deletions(-) diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c index 3c43441653c3..d573f3475d28 100644 --- a/drivers/staging/media/imx/imx7-mipi-csis.c +++ b/drivers/staging/media/imx/imx7-mipi-csis.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -283,21 +284,33 @@ enum mipi_csis_clk { MIPI_CSIS_CLK_PCLK, MIPI_CSIS_CLK_WRAP, MIPI_CSIS_CLK_PHY, + MIPI_CSIS_CLK_AXI, }; static const char * const mipi_csis_clk_id[] = { "pclk", "wrap", "phy", + "axi", +}; + +enum mipi_csis_version { + MIPI_CSIS_V3_3, + MIPI_CSIS_V3_6_3, +}; + +struct mipi_csis_info { + enum mipi_csis_version version; + unsigned int num_clocks; }; struct csi_state { struct device *dev; void __iomem *regs; - unsigned int num_clks; struct clk_bulk_data *clks; struct reset_control *mrst; struct regulator *mipi_phy_regulator; + const struct mipi_csis_info *info; u8 index; struct v4l2_subdev sd; @@ -539,7 +552,8 @@ static void mipi_csis_set_params(struct csi_state *state) val = mipi_csis_read(state, MIPI_CSIS_CMN_CTRL); val &= ~MIPI_CSIS_CMN_CTRL_LANE_NR_MASK; val |= (lanes - 1) << MIPI_CSIS_CMN_CTRL_LANE_NR_OFFSET; - val |= MIPI_CSIS_CMN_CTRL_INTER_MODE; + if (state->info->version == MIPI_CSIS_V3_3) + val |= MIPI_CSIS_CMN_CTRL_INTER_MODE; mipi_csis_write(state, MIPI_CSIS_CMN_CTRL, val); __mipi_csis_set_format(state); @@ -578,12 +592,12 @@ static void mipi_csis_set_params(struct csi_state *state) static int mipi_csis_clk_enable(struct csi_state *state) { - return clk_bulk_prepare_enable(state->num_clks, state->clks); + return clk_bulk_prepare_enable(state->info->num_clocks, state->clks); } static void mipi_csis_clk_disable(struct csi_state *state) { - clk_bulk_disable_unprepare(state->num_clks, state->clks); + clk_bulk_disable_unprepare(state->info->num_clocks, state->clks); } static int mipi_csis_clk_get(struct csi_state *state) @@ -591,17 +605,17 @@ static int mipi_csis_clk_get(struct csi_state *state) unsigned int i; int ret; - state->num_clks = ARRAY_SIZE(mipi_csis_clk_id); - state->clks = devm_kcalloc(state->dev, state->num_clks, + state->clks = devm_kcalloc(state->dev, state->info->num_clocks, sizeof(*state->clks), GFP_KERNEL); if (!state->clks) return -ENOMEM; - for (i = 0; i < state->num_clks; i++) + for (i = 0; i < state->info->num_clocks; i++) state->clks[i].id = mipi_csis_clk_id[i]; - ret = devm_clk_bulk_get(state->dev, state->num_clks, state->clks); + ret = devm_clk_bulk_get(state->dev, state->info->num_clocks, + state->clks); if (ret < 0) return ret; @@ -666,16 +680,25 @@ static irqreturn_t mipi_csis_irq_handler(int irq, void *dev_id) static int mipi_csis_phy_enable(struct csi_state *state) { + if (state->info->version != MIPI_CSIS_V3_3) + return 0; + return regulator_enable(state->mipi_phy_regulator); } static int mipi_csis_phy_disable(struct csi_state *state) { + if (state->info->version != MIPI_CSIS_V3_3) + return 0; + return regulator_disable(state->mipi_phy_regulator); } static void mipi_csis_phy_reset(struct csi_state *state) { + if (state->info->version != MIPI_CSIS_V3_3) + return; + reset_control_assert(state->mrst); msleep(20); reset_control_deassert(state->mrst); @@ -683,6 +706,9 @@ static void mipi_csis_phy_reset(struct csi_state *state) static int mipi_csis_phy_init(struct csi_state *state) { + if (state->info->version != MIPI_CSIS_V3_3) + return 0; + /* Get MIPI PHY reset and regulator. */ state->mrst = devm_reset_control_get_exclusive(state->dev, NULL); if (IS_ERR(state->mrst)) @@ -1322,6 +1348,7 @@ static int mipi_csis_probe(struct platform_device *pdev) spin_lock_init(&state->slock); state->dev = dev; + state->info = of_device_get_match_data(dev); memcpy(state->events, mipi_csis_events, sizeof(state->events)); @@ -1430,7 +1457,19 @@ static int mipi_csis_remove(struct platform_device *pdev) } static const struct of_device_id mipi_csis_of_match[] = { - { .compatible = "fsl,imx7-mipi-csi2", }, + { + .compatible = "fsl,imx7-mipi-csi2", + .data = &(const struct mipi_csis_info){ + .version = MIPI_CSIS_V3_3, + .num_clocks = 3, + }, + }, { + .compatible = "fsl,imx8mm-mipi-csi2", + .data = &(const struct mipi_csis_info){ + .version = MIPI_CSIS_V3_6_3, + .num_clocks = 4, + }, + }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, mipi_csis_of_match); @@ -1447,6 +1486,6 @@ static struct platform_driver mipi_csis_driver = { module_platform_driver(mipi_csis_driver); -MODULE_DESCRIPTION("i.MX7 MIPI CSI-2 Receiver driver"); +MODULE_DESCRIPTION("i.MX7 & i.MX8 MIPI CSI-2 receiver driver"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:imx7-mipi-csi2"); From 2fb27551ba4053ae503ce6c3b7b5d87cd206b1fd Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sun, 18 Apr 2021 22:14:06 +0200 Subject: [PATCH 181/394] media: imx: imx7_mipi_csis: Update MAINTAINERS Given my recent contributions to the imx7-mipi-csis driver, I can as well be listed as a maintainer. Signed-off-by: Laurent Pinchart Reviewed-by: Rui Miguel Silva Signed-off-by: Mauro Carvalho Chehab --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index bd7aff0c120f..2d06dc43fe70 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11283,6 +11283,7 @@ F: include/media/imx.h MEDIA DRIVERS FOR FREESCALE IMX7 M: Rui Miguel Silva +M: Laurent Pinchart L: linux-media@vger.kernel.org S: Maintained T: git git://linuxtv.org/media_tree.git From c3bf5129f33923c92bf3bddaf4359b7b25ecb4ba Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 27 Apr 2021 10:38:33 +0200 Subject: [PATCH 182/394] media: v4l2-ctrls: always copy the controls on completion When v4l2_ctrl_request_complete() is called and there is no control handler object found in the request, then create such an object so that all controls at completion state can be stored and are available to userspace. Otherwise any attempt by userspace to read the completed request data will fail. If allocating the control handler object failed, then indicate that by returning ENOMEM when attempting to get the controls from the completed request instead of returning ENOENT. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-ctrls.c | 36 ++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index d4e2c7318ee6..09992e76bad6 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -4121,8 +4121,19 @@ v4l2_ctrls_find_req_obj(struct v4l2_ctrl_handler *hdl, obj = media_request_object_find(req, &req_ops, hdl); if (obj) return obj; + /* + * If there are no controls in this completed request, + * then that can only happen if: + * + * 1) no controls were present in the queued request, and + * 2) v4l2_ctrl_request_complete() could not allocate a + * control handler object to store the completed state in. + * + * So return ENOMEM to indicate that there was an out-of-memory + * error. + */ if (!set) - return ERR_PTR(-ENOENT); + return ERR_PTR(-ENOMEM); new_hdl = kzalloc(sizeof(*new_hdl), GFP_KERNEL); if (!new_hdl) @@ -4133,8 +4144,8 @@ v4l2_ctrls_find_req_obj(struct v4l2_ctrl_handler *hdl, if (!ret) ret = v4l2_ctrl_request_bind(req, new_hdl, hdl); if (ret) { + v4l2_ctrl_handler_free(new_hdl); kfree(new_hdl); - return ERR_PTR(ret); } @@ -4728,8 +4739,25 @@ void v4l2_ctrl_request_complete(struct media_request *req, * wants to leave the controls unchanged. */ obj = media_request_object_find(req, &req_ops, main_hdl); - if (!obj) - return; + if (!obj) { + int ret; + + /* Create a new request so the driver can return controls */ + hdl = kzalloc(sizeof(*hdl), GFP_KERNEL); + if (!hdl) + return; + + ret = v4l2_ctrl_handler_init(hdl, (main_hdl->nr_of_buckets - 1) * 8); + if (!ret) + ret = v4l2_ctrl_request_bind(req, hdl, main_hdl); + if (ret) { + v4l2_ctrl_handler_free(hdl); + kfree(hdl); + return; + } + hdl->request_is_queued = true; + obj = media_request_object_find(req, &req_ops, main_hdl); + } hdl = container_of(obj, struct v4l2_ctrl_handler, req_obj); list_for_each_entry(ref, &hdl->ctrl_refs, node) { From 71c689dc2e732d4cb190aaf0edea73116b1611bd Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 27 Apr 2021 14:07:03 +0200 Subject: [PATCH 183/394] media: v4l2-ctrls: split up into four source files The v4l2-ctrls.c source has become much too big, so split it up into four separate parts: v4l2-ctrls-core.c: contains the core framework code v4l2-ctrls-api.c: contains the uAPI interface to the framework v4l2-ctrls-defs.c: contains the control definitions v4l2-ctrls-request.c: contains the Request API helpers And it adds a new v4l2-ctrls-priv.h. No code was changed, but a number of checkpatch.pl warnings were fixed (alignment, f == NULL -> !f, long comment block coding style, unsigned -> unsigned int). The copyright statements were updated as well since they were quite out of date. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../media/v4l/ext-ctrls-codec-stateless.rst | 4 +- drivers/media/v4l2-core/Makefile | 5 +- drivers/media/v4l2-core/v4l2-ctrls-api.c | 1225 ++++ drivers/media/v4l2-core/v4l2-ctrls-core.c | 1939 +++++++ drivers/media/v4l2-core/v4l2-ctrls-defs.c | 1575 +++++ drivers/media/v4l2-core/v4l2-ctrls-priv.h | 96 + drivers/media/v4l2-core/v4l2-ctrls-request.c | 496 ++ drivers/media/v4l2-core/v4l2-ctrls.c | 5111 ----------------- 8 files changed, 5336 insertions(+), 5115 deletions(-) create mode 100644 drivers/media/v4l2-core/v4l2-ctrls-api.c create mode 100644 drivers/media/v4l2-core/v4l2-ctrls-core.c create mode 100644 drivers/media/v4l2-core/v4l2-ctrls-defs.c create mode 100644 drivers/media/v4l2-core/v4l2-ctrls-priv.h create mode 100644 drivers/media/v4l2-core/v4l2-ctrls-request.c delete mode 100644 drivers/media/v4l2-core/v4l2-ctrls.c diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst index 2aa508ffb6b9..72f5e85b4f34 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst @@ -1353,8 +1353,8 @@ FWHT Flags * - __u8 - ``picture_coding_type`` - Picture coding type for the frame covered by the current slice - (V4L2_MPEG2_PICTURE_CODING_TYPE_I, V4L2_MPEG2_PICTURE_CODING_TYPE_P or - V4L2_MPEG2_PICTURE_CODING_TYPE_B). + (V4L2_MPEG2_PIC_CODING_TYPE_I, V4L2_MPEG2_PIC_CODING_TYPE_P or + V4L2_MPEG2_PIC_CODING_TYPE_B). * - __u8 - ``picture_structure`` - Picture structure (1: interlaced top field, 2: interlaced bottom field, diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile index e4cd589b99a5..ad967b72fb5d 100644 --- a/drivers/media/v4l2-core/Makefile +++ b/drivers/media/v4l2-core/Makefile @@ -6,8 +6,9 @@ tuner-objs := tuner-core.o videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \ - v4l2-event.o v4l2-ctrls.o v4l2-subdev.o \ - v4l2-async.o v4l2-common.o + v4l2-event.o v4l2-subdev.o v4l2-async.o v4l2-common.o \ + v4l2-ctrls-core.o v4l2-ctrls-api.o \ + v4l2-ctrls-request.o v4l2-ctrls-defs.o videodev-$(CONFIG_COMPAT) += v4l2-compat-ioctl32.o videodev-$(CONFIG_TRACEPOINTS) += v4l2-trace.o videodev-$(CONFIG_MEDIA_CONTROLLER) += v4l2-mc.o diff --git a/drivers/media/v4l2-core/v4l2-ctrls-api.c b/drivers/media/v4l2-core/v4l2-ctrls-api.c new file mode 100644 index 000000000000..db9baa0bd05f --- /dev/null +++ b/drivers/media/v4l2-core/v4l2-ctrls-api.c @@ -0,0 +1,1225 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * V4L2 controls framework uAPI implementation: + * + * Copyright (C) 2010-2021 Hans Verkuil + */ + +#define pr_fmt(fmt) "v4l2-ctrls: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "v4l2-ctrls-priv.h" + +/* Internal temporary helper struct, one for each v4l2_ext_control */ +struct v4l2_ctrl_helper { + /* Pointer to the control reference of the master control */ + struct v4l2_ctrl_ref *mref; + /* The control ref corresponding to the v4l2_ext_control ID field. */ + struct v4l2_ctrl_ref *ref; + /* + * v4l2_ext_control index of the next control belonging to the + * same cluster, or 0 if there isn't any. + */ + u32 next; +}; + +/* + * Helper functions to copy control payload data from kernel space to + * user space and vice versa. + */ + +/* Helper function: copy the given control value back to the caller */ +static int ptr_to_user(struct v4l2_ext_control *c, + struct v4l2_ctrl *ctrl, + union v4l2_ctrl_ptr ptr) +{ + u32 len; + + if (ctrl->is_ptr && !ctrl->is_string) + return copy_to_user(c->ptr, ptr.p_const, c->size) ? + -EFAULT : 0; + + switch (ctrl->type) { + case V4L2_CTRL_TYPE_STRING: + len = strlen(ptr.p_char); + if (c->size < len + 1) { + c->size = ctrl->elem_size; + return -ENOSPC; + } + return copy_to_user(c->string, ptr.p_char, len + 1) ? + -EFAULT : 0; + case V4L2_CTRL_TYPE_INTEGER64: + c->value64 = *ptr.p_s64; + break; + default: + c->value = *ptr.p_s32; + break; + } + return 0; +} + +/* Helper function: copy the current control value back to the caller */ +static int cur_to_user(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl) +{ + return ptr_to_user(c, ctrl, ctrl->p_cur); +} + +/* Helper function: copy the new control value back to the caller */ +static int new_to_user(struct v4l2_ext_control *c, + struct v4l2_ctrl *ctrl) +{ + return ptr_to_user(c, ctrl, ctrl->p_new); +} + +/* Helper function: copy the request value back to the caller */ +static int req_to_user(struct v4l2_ext_control *c, + struct v4l2_ctrl_ref *ref) +{ + return ptr_to_user(c, ref->ctrl, ref->p_req); +} + +/* Helper function: copy the initial control value back to the caller */ +static int def_to_user(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl) +{ + int idx; + + for (idx = 0; idx < ctrl->elems; idx++) + ctrl->type_ops->init(ctrl, idx, ctrl->p_new); + + return ptr_to_user(c, ctrl, ctrl->p_new); +} + +/* Helper function: copy the caller-provider value to the given control value */ +static int user_to_ptr(struct v4l2_ext_control *c, + struct v4l2_ctrl *ctrl, + union v4l2_ctrl_ptr ptr) +{ + int ret; + u32 size; + + ctrl->is_new = 1; + if (ctrl->is_ptr && !ctrl->is_string) { + unsigned int idx; + + ret = copy_from_user(ptr.p, c->ptr, c->size) ? -EFAULT : 0; + if (ret || !ctrl->is_array) + return ret; + for (idx = c->size / ctrl->elem_size; idx < ctrl->elems; idx++) + ctrl->type_ops->init(ctrl, idx, ptr); + return 0; + } + + switch (ctrl->type) { + case V4L2_CTRL_TYPE_INTEGER64: + *ptr.p_s64 = c->value64; + break; + case V4L2_CTRL_TYPE_STRING: + size = c->size; + if (size == 0) + return -ERANGE; + if (size > ctrl->maximum + 1) + size = ctrl->maximum + 1; + ret = copy_from_user(ptr.p_char, c->string, size) ? -EFAULT : 0; + if (!ret) { + char last = ptr.p_char[size - 1]; + + ptr.p_char[size - 1] = 0; + /* + * If the string was longer than ctrl->maximum, + * then return an error. + */ + if (strlen(ptr.p_char) == ctrl->maximum && last) + return -ERANGE; + } + return ret; + default: + *ptr.p_s32 = c->value; + break; + } + return 0; +} + +/* Helper function: copy the caller-provider value as the new control value */ +static int user_to_new(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl) +{ + return user_to_ptr(c, ctrl, ctrl->p_new); +} + +/* + * VIDIOC_G/TRY/S_EXT_CTRLS implementation + */ + +/* + * Some general notes on the atomic requirements of VIDIOC_G/TRY/S_EXT_CTRLS: + * + * It is not a fully atomic operation, just best-effort only. After all, if + * multiple controls have to be set through multiple i2c writes (for example) + * then some initial writes may succeed while others fail. Thus leaving the + * system in an inconsistent state. The question is how much effort you are + * willing to spend on trying to make something atomic that really isn't. + * + * From the point of view of an application the main requirement is that + * when you call VIDIOC_S_EXT_CTRLS and some values are invalid then an + * error should be returned without actually affecting any controls. + * + * If all the values are correct, then it is acceptable to just give up + * in case of low-level errors. + * + * It is important though that the application can tell when only a partial + * configuration was done. The way we do that is through the error_idx field + * of struct v4l2_ext_controls: if that is equal to the count field then no + * controls were affected. Otherwise all controls before that index were + * successful in performing their 'get' or 'set' operation, the control at + * the given index failed, and you don't know what happened with the controls + * after the failed one. Since if they were part of a control cluster they + * could have been successfully processed (if a cluster member was encountered + * at index < error_idx), they could have failed (if a cluster member was at + * error_idx), or they may not have been processed yet (if the first cluster + * member appeared after error_idx). + * + * It is all fairly theoretical, though. In practice all you can do is to + * bail out. If error_idx == count, then it is an application bug. If + * error_idx < count then it is only an application bug if the error code was + * EBUSY. That usually means that something started streaming just when you + * tried to set the controls. In all other cases it is a driver/hardware + * problem and all you can do is to retry or bail out. + * + * Note that these rules do not apply to VIDIOC_TRY_EXT_CTRLS: since that + * never modifies controls the error_idx is just set to whatever control + * has an invalid value. + */ + +/* + * Prepare for the extended g/s/try functions. + * Find the controls in the control array and do some basic checks. + */ +static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl, + struct v4l2_ext_controls *cs, + struct v4l2_ctrl_helper *helpers, + struct video_device *vdev, + bool get) +{ + struct v4l2_ctrl_helper *h; + bool have_clusters = false; + u32 i; + + for (i = 0, h = helpers; i < cs->count; i++, h++) { + struct v4l2_ext_control *c = &cs->controls[i]; + struct v4l2_ctrl_ref *ref; + struct v4l2_ctrl *ctrl; + u32 id = c->id & V4L2_CTRL_ID_MASK; + + cs->error_idx = i; + + if (cs->which && + cs->which != V4L2_CTRL_WHICH_DEF_VAL && + cs->which != V4L2_CTRL_WHICH_REQUEST_VAL && + V4L2_CTRL_ID2WHICH(id) != cs->which) { + dprintk(vdev, + "invalid which 0x%x or control id 0x%x\n", + cs->which, id); + return -EINVAL; + } + + /* + * Old-style private controls are not allowed for + * extended controls. + */ + if (id >= V4L2_CID_PRIVATE_BASE) { + dprintk(vdev, + "old-style private controls not allowed\n"); + return -EINVAL; + } + ref = find_ref_lock(hdl, id); + if (!ref) { + dprintk(vdev, "cannot find control id 0x%x\n", id); + return -EINVAL; + } + h->ref = ref; + ctrl = ref->ctrl; + if (ctrl->flags & V4L2_CTRL_FLAG_DISABLED) { + dprintk(vdev, "control id 0x%x is disabled\n", id); + return -EINVAL; + } + + if (ctrl->cluster[0]->ncontrols > 1) + have_clusters = true; + if (ctrl->cluster[0] != ctrl) + ref = find_ref_lock(hdl, ctrl->cluster[0]->id); + if (ctrl->is_ptr && !ctrl->is_string) { + unsigned int tot_size = ctrl->elems * ctrl->elem_size; + + if (c->size < tot_size) { + /* + * In the get case the application first + * queries to obtain the size of the control. + */ + if (get) { + c->size = tot_size; + return -ENOSPC; + } + dprintk(vdev, + "pointer control id 0x%x size too small, %d bytes but %d bytes needed\n", + id, c->size, tot_size); + return -EFAULT; + } + c->size = tot_size; + } + /* Store the ref to the master control of the cluster */ + h->mref = ref; + /* + * Initially set next to 0, meaning that there is no other + * control in this helper array belonging to the same + * cluster. + */ + h->next = 0; + } + + /* + * We are done if there were no controls that belong to a multi- + * control cluster. + */ + if (!have_clusters) + return 0; + + /* + * The code below figures out in O(n) time which controls in the list + * belong to the same cluster. + */ + + /* This has to be done with the handler lock taken. */ + mutex_lock(hdl->lock); + + /* First zero the helper field in the master control references */ + for (i = 0; i < cs->count; i++) + helpers[i].mref->helper = NULL; + for (i = 0, h = helpers; i < cs->count; i++, h++) { + struct v4l2_ctrl_ref *mref = h->mref; + + /* + * If the mref->helper is set, then it points to an earlier + * helper that belongs to the same cluster. + */ + if (mref->helper) { + /* + * Set the next field of mref->helper to the current + * index: this means that the earlier helper now + * points to the next helper in the same cluster. + */ + mref->helper->next = i; + /* + * mref should be set only for the first helper in the + * cluster, clear the others. + */ + h->mref = NULL; + } + /* Point the mref helper to the current helper struct. */ + mref->helper = h; + } + mutex_unlock(hdl->lock); + return 0; +} + +/* + * Handles the corner case where cs->count == 0. It checks whether the + * specified control class exists. If that class ID is 0, then it checks + * whether there are any controls at all. + */ +static int class_check(struct v4l2_ctrl_handler *hdl, u32 which) +{ + if (which == 0 || which == V4L2_CTRL_WHICH_DEF_VAL || + which == V4L2_CTRL_WHICH_REQUEST_VAL) + return 0; + return find_ref_lock(hdl, which | 1) ? 0 : -EINVAL; +} + +/* + * Get extended controls. Allocates the helpers array if needed. + * + * Note that v4l2_g_ext_ctrls_common() with 'which' set to + * V4L2_CTRL_WHICH_REQUEST_VAL is only called if the request was + * completed, and in that case valid_p_req is true for all controls. + */ +int v4l2_g_ext_ctrls_common(struct v4l2_ctrl_handler *hdl, + struct v4l2_ext_controls *cs, + struct video_device *vdev) +{ + struct v4l2_ctrl_helper helper[4]; + struct v4l2_ctrl_helper *helpers = helper; + int ret; + int i, j; + bool is_default, is_request; + + is_default = (cs->which == V4L2_CTRL_WHICH_DEF_VAL); + is_request = (cs->which == V4L2_CTRL_WHICH_REQUEST_VAL); + + cs->error_idx = cs->count; + cs->which = V4L2_CTRL_ID2WHICH(cs->which); + + if (!hdl) + return -EINVAL; + + if (cs->count == 0) + return class_check(hdl, cs->which); + + if (cs->count > ARRAY_SIZE(helper)) { + helpers = kvmalloc_array(cs->count, sizeof(helper[0]), + GFP_KERNEL); + if (!helpers) + return -ENOMEM; + } + + ret = prepare_ext_ctrls(hdl, cs, helpers, vdev, true); + cs->error_idx = cs->count; + + for (i = 0; !ret && i < cs->count; i++) + if (helpers[i].ref->ctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY) + ret = -EACCES; + + for (i = 0; !ret && i < cs->count; i++) { + struct v4l2_ctrl *master; + bool is_volatile = false; + u32 idx = i; + + if (!helpers[i].mref) + continue; + + master = helpers[i].mref->ctrl; + cs->error_idx = i; + + v4l2_ctrl_lock(master); + + /* + * g_volatile_ctrl will update the new control values. + * This makes no sense for V4L2_CTRL_WHICH_DEF_VAL and + * V4L2_CTRL_WHICH_REQUEST_VAL. In the case of requests + * it is v4l2_ctrl_request_complete() that copies the + * volatile controls at the time of request completion + * to the request, so you don't want to do that again. + */ + if (!is_default && !is_request && + ((master->flags & V4L2_CTRL_FLAG_VOLATILE) || + (master->has_volatiles && !is_cur_manual(master)))) { + for (j = 0; j < master->ncontrols; j++) + cur_to_new(master->cluster[j]); + ret = call_op(master, g_volatile_ctrl); + is_volatile = true; + } + + if (ret) { + v4l2_ctrl_unlock(master); + break; + } + + /* + * Copy the default value (if is_default is true), the + * request value (if is_request is true and p_req is valid), + * the new volatile value (if is_volatile is true) or the + * current value. + */ + do { + struct v4l2_ctrl_ref *ref = helpers[idx].ref; + + if (is_default) + ret = def_to_user(cs->controls + idx, ref->ctrl); + else if (is_request && ref->valid_p_req) + ret = req_to_user(cs->controls + idx, ref); + else if (is_volatile) + ret = new_to_user(cs->controls + idx, ref->ctrl); + else + ret = cur_to_user(cs->controls + idx, ref->ctrl); + idx = helpers[idx].next; + } while (!ret && idx); + + v4l2_ctrl_unlock(master); + } + + if (cs->count > ARRAY_SIZE(helper)) + kvfree(helpers); + return ret; +} + +int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct video_device *vdev, + struct media_device *mdev, struct v4l2_ext_controls *cs) +{ + if (cs->which == V4L2_CTRL_WHICH_REQUEST_VAL) + return v4l2_g_ext_ctrls_request(hdl, vdev, mdev, cs); + + return v4l2_g_ext_ctrls_common(hdl, cs, vdev); +} +EXPORT_SYMBOL(v4l2_g_ext_ctrls); + +/* Validate controls. */ +static int validate_ctrls(struct v4l2_ext_controls *cs, + struct v4l2_ctrl_helper *helpers, + struct video_device *vdev, + bool set) +{ + unsigned int i; + int ret = 0; + + cs->error_idx = cs->count; + for (i = 0; i < cs->count; i++) { + struct v4l2_ctrl *ctrl = helpers[i].ref->ctrl; + union v4l2_ctrl_ptr p_new; + + cs->error_idx = i; + + if (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY) { + dprintk(vdev, + "control id 0x%x is read-only\n", + ctrl->id); + return -EACCES; + } + /* + * This test is also done in try_set_control_cluster() which + * is called in atomic context, so that has the final say, + * but it makes sense to do an up-front check as well. Once + * an error occurs in try_set_control_cluster() some other + * controls may have been set already and we want to do a + * best-effort to avoid that. + */ + if (set && (ctrl->flags & V4L2_CTRL_FLAG_GRABBED)) { + dprintk(vdev, + "control id 0x%x is grabbed, cannot set\n", + ctrl->id); + return -EBUSY; + } + /* + * Skip validation for now if the payload needs to be copied + * from userspace into kernelspace. We'll validate those later. + */ + if (ctrl->is_ptr) + continue; + if (ctrl->type == V4L2_CTRL_TYPE_INTEGER64) + p_new.p_s64 = &cs->controls[i].value64; + else + p_new.p_s32 = &cs->controls[i].value; + ret = validate_new(ctrl, p_new); + if (ret) + return ret; + } + return 0; +} + +/* Try or try-and-set controls */ +int try_set_ext_ctrls_common(struct v4l2_fh *fh, + struct v4l2_ctrl_handler *hdl, + struct v4l2_ext_controls *cs, + struct video_device *vdev, bool set) +{ + struct v4l2_ctrl_helper helper[4]; + struct v4l2_ctrl_helper *helpers = helper; + unsigned int i, j; + int ret; + + cs->error_idx = cs->count; + + /* Default value cannot be changed */ + if (cs->which == V4L2_CTRL_WHICH_DEF_VAL) { + dprintk(vdev, "%s: cannot change default value\n", + video_device_node_name(vdev)); + return -EINVAL; + } + + cs->which = V4L2_CTRL_ID2WHICH(cs->which); + + if (!hdl) { + dprintk(vdev, "%s: invalid null control handler\n", + video_device_node_name(vdev)); + return -EINVAL; + } + + if (cs->count == 0) + return class_check(hdl, cs->which); + + if (cs->count > ARRAY_SIZE(helper)) { + helpers = kvmalloc_array(cs->count, sizeof(helper[0]), + GFP_KERNEL); + if (!helpers) + return -ENOMEM; + } + ret = prepare_ext_ctrls(hdl, cs, helpers, vdev, false); + if (!ret) + ret = validate_ctrls(cs, helpers, vdev, set); + if (ret && set) + cs->error_idx = cs->count; + for (i = 0; !ret && i < cs->count; i++) { + struct v4l2_ctrl *master; + u32 idx = i; + + if (!helpers[i].mref) + continue; + + cs->error_idx = i; + master = helpers[i].mref->ctrl; + v4l2_ctrl_lock(master); + + /* Reset the 'is_new' flags of the cluster */ + for (j = 0; j < master->ncontrols; j++) + if (master->cluster[j]) + master->cluster[j]->is_new = 0; + + /* + * For volatile autoclusters that are currently in auto mode + * we need to discover if it will be set to manual mode. + * If so, then we have to copy the current volatile values + * first since those will become the new manual values (which + * may be overwritten by explicit new values from this set + * of controls). + */ + if (master->is_auto && master->has_volatiles && + !is_cur_manual(master)) { + /* Pick an initial non-manual value */ + s32 new_auto_val = master->manual_mode_value + 1; + u32 tmp_idx = idx; + + do { + /* + * Check if the auto control is part of the + * list, and remember the new value. + */ + if (helpers[tmp_idx].ref->ctrl == master) + new_auto_val = cs->controls[tmp_idx].value; + tmp_idx = helpers[tmp_idx].next; + } while (tmp_idx); + /* + * If the new value == the manual value, then copy + * the current volatile values. + */ + if (new_auto_val == master->manual_mode_value) + update_from_auto_cluster(master); + } + + /* + * Copy the new caller-supplied control values. + * user_to_new() sets 'is_new' to 1. + */ + do { + struct v4l2_ctrl *ctrl = helpers[idx].ref->ctrl; + + ret = user_to_new(cs->controls + idx, ctrl); + if (!ret && ctrl->is_ptr) { + ret = validate_new(ctrl, ctrl->p_new); + if (ret) + dprintk(vdev, + "failed to validate control %s (%d)\n", + v4l2_ctrl_get_name(ctrl->id), ret); + } + idx = helpers[idx].next; + } while (!ret && idx); + + if (!ret) + ret = try_or_set_cluster(fh, master, + !hdl->req_obj.req && set, 0); + if (!ret && hdl->req_obj.req && set) { + for (j = 0; j < master->ncontrols; j++) { + struct v4l2_ctrl_ref *ref = + find_ref(hdl, master->cluster[j]->id); + + new_to_req(ref); + } + } + + /* Copy the new values back to userspace. */ + if (!ret) { + idx = i; + do { + ret = new_to_user(cs->controls + idx, + helpers[idx].ref->ctrl); + idx = helpers[idx].next; + } while (!ret && idx); + } + v4l2_ctrl_unlock(master); + } + + if (cs->count > ARRAY_SIZE(helper)) + kvfree(helpers); + return ret; +} + +static int try_set_ext_ctrls(struct v4l2_fh *fh, + struct v4l2_ctrl_handler *hdl, + struct video_device *vdev, + struct media_device *mdev, + struct v4l2_ext_controls *cs, bool set) +{ + int ret; + + if (cs->which == V4L2_CTRL_WHICH_REQUEST_VAL) + return try_set_ext_ctrls_request(fh, hdl, vdev, mdev, cs, set); + + ret = try_set_ext_ctrls_common(fh, hdl, cs, vdev, set); + if (ret) + dprintk(vdev, + "%s: try_set_ext_ctrls_common failed (%d)\n", + video_device_node_name(vdev), ret); + + return ret; +} + +int v4l2_try_ext_ctrls(struct v4l2_ctrl_handler *hdl, + struct video_device *vdev, + struct media_device *mdev, + struct v4l2_ext_controls *cs) +{ + return try_set_ext_ctrls(NULL, hdl, vdev, mdev, cs, false); +} +EXPORT_SYMBOL(v4l2_try_ext_ctrls); + +int v4l2_s_ext_ctrls(struct v4l2_fh *fh, + struct v4l2_ctrl_handler *hdl, + struct video_device *vdev, + struct media_device *mdev, + struct v4l2_ext_controls *cs) +{ + return try_set_ext_ctrls(fh, hdl, vdev, mdev, cs, true); +} +EXPORT_SYMBOL(v4l2_s_ext_ctrls); + +/* + * VIDIOC_G/S_CTRL implementation + */ + +/* Helper function to get a single control */ +static int get_ctrl(struct v4l2_ctrl *ctrl, struct v4l2_ext_control *c) +{ + struct v4l2_ctrl *master = ctrl->cluster[0]; + int ret = 0; + int i; + + /* Compound controls are not supported. The new_to_user() and + * cur_to_user() calls below would need to be modified not to access + * userspace memory when called from get_ctrl(). + */ + if (!ctrl->is_int && ctrl->type != V4L2_CTRL_TYPE_INTEGER64) + return -EINVAL; + + if (ctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY) + return -EACCES; + + v4l2_ctrl_lock(master); + /* g_volatile_ctrl will update the current control values */ + if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) { + for (i = 0; i < master->ncontrols; i++) + cur_to_new(master->cluster[i]); + ret = call_op(master, g_volatile_ctrl); + new_to_user(c, ctrl); + } else { + cur_to_user(c, ctrl); + } + v4l2_ctrl_unlock(master); + return ret; +} + +int v4l2_g_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_control *control) +{ + struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, control->id); + struct v4l2_ext_control c; + int ret; + + if (!ctrl || !ctrl->is_int) + return -EINVAL; + ret = get_ctrl(ctrl, &c); + control->value = c.value; + return ret; +} +EXPORT_SYMBOL(v4l2_g_ctrl); + +/* Helper function for VIDIOC_S_CTRL compatibility */ +static int set_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 ch_flags) +{ + struct v4l2_ctrl *master = ctrl->cluster[0]; + int ret; + int i; + + /* Reset the 'is_new' flags of the cluster */ + for (i = 0; i < master->ncontrols; i++) + if (master->cluster[i]) + master->cluster[i]->is_new = 0; + + ret = validate_new(ctrl, ctrl->p_new); + if (ret) + return ret; + + /* + * For autoclusters with volatiles that are switched from auto to + * manual mode we have to update the current volatile values since + * those will become the initial manual values after such a switch. + */ + if (master->is_auto && master->has_volatiles && ctrl == master && + !is_cur_manual(master) && ctrl->val == master->manual_mode_value) + update_from_auto_cluster(master); + + ctrl->is_new = 1; + return try_or_set_cluster(fh, master, true, ch_flags); +} + +/* Helper function for VIDIOC_S_CTRL compatibility */ +static int set_ctrl_lock(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, + struct v4l2_ext_control *c) +{ + int ret; + + v4l2_ctrl_lock(ctrl); + user_to_new(c, ctrl); + ret = set_ctrl(fh, ctrl, 0); + if (!ret) + cur_to_user(c, ctrl); + v4l2_ctrl_unlock(ctrl); + return ret; +} + +int v4l2_s_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl, + struct v4l2_control *control) +{ + struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, control->id); + struct v4l2_ext_control c = { control->id }; + int ret; + + if (!ctrl || !ctrl->is_int) + return -EINVAL; + + if (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY) + return -EACCES; + + c.value = control->value; + ret = set_ctrl_lock(fh, ctrl, &c); + control->value = c.value; + return ret; +} +EXPORT_SYMBOL(v4l2_s_ctrl); + +/* + * Helper functions for drivers to get/set controls. + */ + +s32 v4l2_ctrl_g_ctrl(struct v4l2_ctrl *ctrl) +{ + struct v4l2_ext_control c; + + /* It's a driver bug if this happens. */ + if (WARN_ON(!ctrl->is_int)) + return 0; + c.value = 0; + get_ctrl(ctrl, &c); + return c.value; +} +EXPORT_SYMBOL(v4l2_ctrl_g_ctrl); + +s64 v4l2_ctrl_g_ctrl_int64(struct v4l2_ctrl *ctrl) +{ + struct v4l2_ext_control c; + + /* It's a driver bug if this happens. */ + if (WARN_ON(ctrl->is_ptr || ctrl->type != V4L2_CTRL_TYPE_INTEGER64)) + return 0; + c.value64 = 0; + get_ctrl(ctrl, &c); + return c.value64; +} +EXPORT_SYMBOL(v4l2_ctrl_g_ctrl_int64); + +int __v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val) +{ + lockdep_assert_held(ctrl->handler->lock); + + /* It's a driver bug if this happens. */ + if (WARN_ON(!ctrl->is_int)) + return -EINVAL; + ctrl->val = val; + return set_ctrl(NULL, ctrl, 0); +} +EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl); + +int __v4l2_ctrl_s_ctrl_int64(struct v4l2_ctrl *ctrl, s64 val) +{ + lockdep_assert_held(ctrl->handler->lock); + + /* It's a driver bug if this happens. */ + if (WARN_ON(ctrl->is_ptr || ctrl->type != V4L2_CTRL_TYPE_INTEGER64)) + return -EINVAL; + *ctrl->p_new.p_s64 = val; + return set_ctrl(NULL, ctrl, 0); +} +EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_int64); + +int __v4l2_ctrl_s_ctrl_string(struct v4l2_ctrl *ctrl, const char *s) +{ + lockdep_assert_held(ctrl->handler->lock); + + /* It's a driver bug if this happens. */ + if (WARN_ON(ctrl->type != V4L2_CTRL_TYPE_STRING)) + return -EINVAL; + strscpy(ctrl->p_new.p_char, s, ctrl->maximum + 1); + return set_ctrl(NULL, ctrl, 0); +} +EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_string); + +int __v4l2_ctrl_s_ctrl_compound(struct v4l2_ctrl *ctrl, + enum v4l2_ctrl_type type, const void *p) +{ + lockdep_assert_held(ctrl->handler->lock); + + /* It's a driver bug if this happens. */ + if (WARN_ON(ctrl->type != type)) + return -EINVAL; + memcpy(ctrl->p_new.p, p, ctrl->elems * ctrl->elem_size); + return set_ctrl(NULL, ctrl, 0); +} +EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_compound); + +/* + * Modify the range of a control. + */ +int __v4l2_ctrl_modify_range(struct v4l2_ctrl *ctrl, + s64 min, s64 max, u64 step, s64 def) +{ + bool value_changed; + bool range_changed = false; + int ret; + + lockdep_assert_held(ctrl->handler->lock); + + switch (ctrl->type) { + case V4L2_CTRL_TYPE_INTEGER: + case V4L2_CTRL_TYPE_INTEGER64: + case V4L2_CTRL_TYPE_BOOLEAN: + case V4L2_CTRL_TYPE_MENU: + case V4L2_CTRL_TYPE_INTEGER_MENU: + case V4L2_CTRL_TYPE_BITMASK: + case V4L2_CTRL_TYPE_U8: + case V4L2_CTRL_TYPE_U16: + case V4L2_CTRL_TYPE_U32: + if (ctrl->is_array) + return -EINVAL; + ret = check_range(ctrl->type, min, max, step, def); + if (ret) + return ret; + break; + default: + return -EINVAL; + } + if (ctrl->minimum != min || ctrl->maximum != max || + ctrl->step != step || ctrl->default_value != def) { + range_changed = true; + ctrl->minimum = min; + ctrl->maximum = max; + ctrl->step = step; + ctrl->default_value = def; + } + cur_to_new(ctrl); + if (validate_new(ctrl, ctrl->p_new)) { + if (ctrl->type == V4L2_CTRL_TYPE_INTEGER64) + *ctrl->p_new.p_s64 = def; + else + *ctrl->p_new.p_s32 = def; + } + + if (ctrl->type == V4L2_CTRL_TYPE_INTEGER64) + value_changed = *ctrl->p_new.p_s64 != *ctrl->p_cur.p_s64; + else + value_changed = *ctrl->p_new.p_s32 != *ctrl->p_cur.p_s32; + if (value_changed) + ret = set_ctrl(NULL, ctrl, V4L2_EVENT_CTRL_CH_RANGE); + else if (range_changed) + send_event(NULL, ctrl, V4L2_EVENT_CTRL_CH_RANGE); + return ret; +} +EXPORT_SYMBOL(__v4l2_ctrl_modify_range); + +/* Implement VIDIOC_QUERY_EXT_CTRL */ +int v4l2_query_ext_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_query_ext_ctrl *qc) +{ + const unsigned int next_flags = V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND; + u32 id = qc->id & V4L2_CTRL_ID_MASK; + struct v4l2_ctrl_ref *ref; + struct v4l2_ctrl *ctrl; + + if (!hdl) + return -EINVAL; + + mutex_lock(hdl->lock); + + /* Try to find it */ + ref = find_ref(hdl, id); + + if ((qc->id & next_flags) && !list_empty(&hdl->ctrl_refs)) { + bool is_compound; + /* Match any control that is not hidden */ + unsigned int mask = 1; + bool match = false; + + if ((qc->id & next_flags) == V4L2_CTRL_FLAG_NEXT_COMPOUND) { + /* Match any hidden control */ + match = true; + } else if ((qc->id & next_flags) == next_flags) { + /* Match any control, compound or not */ + mask = 0; + } + + /* Find the next control with ID > qc->id */ + + /* Did we reach the end of the control list? */ + if (id >= node2id(hdl->ctrl_refs.prev)) { + ref = NULL; /* Yes, so there is no next control */ + } else if (ref) { + /* + * We found a control with the given ID, so just get + * the next valid one in the list. + */ + list_for_each_entry_continue(ref, &hdl->ctrl_refs, node) { + is_compound = ref->ctrl->is_array || + ref->ctrl->type >= V4L2_CTRL_COMPOUND_TYPES; + if (id < ref->ctrl->id && + (is_compound & mask) == match) + break; + } + if (&ref->node == &hdl->ctrl_refs) + ref = NULL; + } else { + /* + * No control with the given ID exists, so start + * searching for the next largest ID. We know there + * is one, otherwise the first 'if' above would have + * been true. + */ + list_for_each_entry(ref, &hdl->ctrl_refs, node) { + is_compound = ref->ctrl->is_array || + ref->ctrl->type >= V4L2_CTRL_COMPOUND_TYPES; + if (id < ref->ctrl->id && + (is_compound & mask) == match) + break; + } + if (&ref->node == &hdl->ctrl_refs) + ref = NULL; + } + } + mutex_unlock(hdl->lock); + + if (!ref) + return -EINVAL; + + ctrl = ref->ctrl; + memset(qc, 0, sizeof(*qc)); + if (id >= V4L2_CID_PRIVATE_BASE) + qc->id = id; + else + qc->id = ctrl->id; + strscpy(qc->name, ctrl->name, sizeof(qc->name)); + qc->flags = user_flags(ctrl); + qc->type = ctrl->type; + qc->elem_size = ctrl->elem_size; + qc->elems = ctrl->elems; + qc->nr_of_dims = ctrl->nr_of_dims; + memcpy(qc->dims, ctrl->dims, qc->nr_of_dims * sizeof(qc->dims[0])); + qc->minimum = ctrl->minimum; + qc->maximum = ctrl->maximum; + qc->default_value = ctrl->default_value; + if (ctrl->type == V4L2_CTRL_TYPE_MENU || + ctrl->type == V4L2_CTRL_TYPE_INTEGER_MENU) + qc->step = 1; + else + qc->step = ctrl->step; + return 0; +} +EXPORT_SYMBOL(v4l2_query_ext_ctrl); + +/* Implement VIDIOC_QUERYCTRL */ +int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc) +{ + struct v4l2_query_ext_ctrl qec = { qc->id }; + int rc; + + rc = v4l2_query_ext_ctrl(hdl, &qec); + if (rc) + return rc; + + qc->id = qec.id; + qc->type = qec.type; + qc->flags = qec.flags; + strscpy(qc->name, qec.name, sizeof(qc->name)); + switch (qc->type) { + case V4L2_CTRL_TYPE_INTEGER: + case V4L2_CTRL_TYPE_BOOLEAN: + case V4L2_CTRL_TYPE_MENU: + case V4L2_CTRL_TYPE_INTEGER_MENU: + case V4L2_CTRL_TYPE_STRING: + case V4L2_CTRL_TYPE_BITMASK: + qc->minimum = qec.minimum; + qc->maximum = qec.maximum; + qc->step = qec.step; + qc->default_value = qec.default_value; + break; + default: + qc->minimum = 0; + qc->maximum = 0; + qc->step = 0; + qc->default_value = 0; + break; + } + return 0; +} +EXPORT_SYMBOL(v4l2_queryctrl); + +/* Implement VIDIOC_QUERYMENU */ +int v4l2_querymenu(struct v4l2_ctrl_handler *hdl, struct v4l2_querymenu *qm) +{ + struct v4l2_ctrl *ctrl; + u32 i = qm->index; + + ctrl = v4l2_ctrl_find(hdl, qm->id); + if (!ctrl) + return -EINVAL; + + qm->reserved = 0; + /* Sanity checks */ + switch (ctrl->type) { + case V4L2_CTRL_TYPE_MENU: + if (!ctrl->qmenu) + return -EINVAL; + break; + case V4L2_CTRL_TYPE_INTEGER_MENU: + if (!ctrl->qmenu_int) + return -EINVAL; + break; + default: + return -EINVAL; + } + + if (i < ctrl->minimum || i > ctrl->maximum) + return -EINVAL; + + /* Use mask to see if this menu item should be skipped */ + if (ctrl->menu_skip_mask & (1ULL << i)) + return -EINVAL; + /* Empty menu items should also be skipped */ + if (ctrl->type == V4L2_CTRL_TYPE_MENU) { + if (!ctrl->qmenu[i] || ctrl->qmenu[i][0] == '\0') + return -EINVAL; + strscpy(qm->name, ctrl->qmenu[i], sizeof(qm->name)); + } else { + qm->value = ctrl->qmenu_int[i]; + } + return 0; +} +EXPORT_SYMBOL(v4l2_querymenu); + +/* + * VIDIOC_LOG_STATUS helpers + */ + +int v4l2_ctrl_log_status(struct file *file, void *fh) +{ + struct video_device *vfd = video_devdata(file); + struct v4l2_fh *vfh = file->private_data; + + if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) && vfd->v4l2_dev) + v4l2_ctrl_handler_log_status(vfh->ctrl_handler, + vfd->v4l2_dev->name); + return 0; +} +EXPORT_SYMBOL(v4l2_ctrl_log_status); + +int v4l2_ctrl_subdev_log_status(struct v4l2_subdev *sd) +{ + v4l2_ctrl_handler_log_status(sd->ctrl_handler, sd->name); + return 0; +} +EXPORT_SYMBOL(v4l2_ctrl_subdev_log_status); + +/* + * VIDIOC_(UN)SUBSCRIBE_EVENT implementation + */ + +static int v4l2_ctrl_add_event(struct v4l2_subscribed_event *sev, + unsigned int elems) +{ + struct v4l2_ctrl *ctrl = v4l2_ctrl_find(sev->fh->ctrl_handler, sev->id); + + if (!ctrl) + return -EINVAL; + + v4l2_ctrl_lock(ctrl); + list_add_tail(&sev->node, &ctrl->ev_subs); + if (ctrl->type != V4L2_CTRL_TYPE_CTRL_CLASS && + (sev->flags & V4L2_EVENT_SUB_FL_SEND_INITIAL)) + send_initial_event(sev->fh, ctrl); + v4l2_ctrl_unlock(ctrl); + return 0; +} + +static void v4l2_ctrl_del_event(struct v4l2_subscribed_event *sev) +{ + struct v4l2_ctrl *ctrl = v4l2_ctrl_find(sev->fh->ctrl_handler, sev->id); + + if (!ctrl) + return; + + v4l2_ctrl_lock(ctrl); + list_del(&sev->node); + v4l2_ctrl_unlock(ctrl); +} + +void v4l2_ctrl_replace(struct v4l2_event *old, const struct v4l2_event *new) +{ + u32 old_changes = old->u.ctrl.changes; + + old->u.ctrl = new->u.ctrl; + old->u.ctrl.changes |= old_changes; +} +EXPORT_SYMBOL(v4l2_ctrl_replace); + +void v4l2_ctrl_merge(const struct v4l2_event *old, struct v4l2_event *new) +{ + new->u.ctrl.changes |= old->u.ctrl.changes; +} +EXPORT_SYMBOL(v4l2_ctrl_merge); + +const struct v4l2_subscribed_event_ops v4l2_ctrl_sub_ev_ops = { + .add = v4l2_ctrl_add_event, + .del = v4l2_ctrl_del_event, + .replace = v4l2_ctrl_replace, + .merge = v4l2_ctrl_merge, +}; +EXPORT_SYMBOL(v4l2_ctrl_sub_ev_ops); + +int v4l2_ctrl_subscribe_event(struct v4l2_fh *fh, + const struct v4l2_event_subscription *sub) +{ + if (sub->type == V4L2_EVENT_CTRL) + return v4l2_event_subscribe(fh, sub, 0, &v4l2_ctrl_sub_ev_ops); + return -EINVAL; +} +EXPORT_SYMBOL(v4l2_ctrl_subscribe_event); + +int v4l2_ctrl_subdev_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, + struct v4l2_event_subscription *sub) +{ + if (!sd->ctrl_handler) + return -EINVAL; + return v4l2_ctrl_subscribe_event(fh, sub); +} +EXPORT_SYMBOL(v4l2_ctrl_subdev_subscribe_event); + +/* + * poll helper + */ +__poll_t v4l2_ctrl_poll(struct file *file, struct poll_table_struct *wait) +{ + struct v4l2_fh *fh = file->private_data; + + poll_wait(file, &fh->wait, wait); + if (v4l2_event_pending(fh)) + return EPOLLPRI; + return 0; +} +EXPORT_SYMBOL(v4l2_ctrl_poll); diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c new file mode 100644 index 000000000000..081439224357 --- /dev/null +++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c @@ -0,0 +1,1939 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * V4L2 controls framework core implementation. + * + * Copyright (C) 2010-2021 Hans Verkuil + */ + +#include +#include +#include +#include +#include +#include + +#include "v4l2-ctrls-priv.h" + +static const union v4l2_ctrl_ptr ptr_null; + +static void fill_event(struct v4l2_event *ev, struct v4l2_ctrl *ctrl, + u32 changes) +{ + memset(ev, 0, sizeof(*ev)); + ev->type = V4L2_EVENT_CTRL; + ev->id = ctrl->id; + ev->u.ctrl.changes = changes; + ev->u.ctrl.type = ctrl->type; + ev->u.ctrl.flags = user_flags(ctrl); + if (ctrl->is_ptr) + ev->u.ctrl.value64 = 0; + else + ev->u.ctrl.value64 = *ctrl->p_cur.p_s64; + ev->u.ctrl.minimum = ctrl->minimum; + ev->u.ctrl.maximum = ctrl->maximum; + if (ctrl->type == V4L2_CTRL_TYPE_MENU + || ctrl->type == V4L2_CTRL_TYPE_INTEGER_MENU) + ev->u.ctrl.step = 1; + else + ev->u.ctrl.step = ctrl->step; + ev->u.ctrl.default_value = ctrl->default_value; +} + +void send_initial_event(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl) +{ + struct v4l2_event ev; + u32 changes = V4L2_EVENT_CTRL_CH_FLAGS; + + if (!(ctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY)) + changes |= V4L2_EVENT_CTRL_CH_VALUE; + fill_event(&ev, ctrl, changes); + v4l2_event_queue_fh(fh, &ev); +} + +void send_event(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 changes) +{ + struct v4l2_event ev; + struct v4l2_subscribed_event *sev; + + if (list_empty(&ctrl->ev_subs)) + return; + fill_event(&ev, ctrl, changes); + + list_for_each_entry(sev, &ctrl->ev_subs, node) + if (sev->fh != fh || + (sev->flags & V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK)) + v4l2_event_queue_fh(sev->fh, &ev); +} + +static bool std_equal(const struct v4l2_ctrl *ctrl, u32 idx, + union v4l2_ctrl_ptr ptr1, + union v4l2_ctrl_ptr ptr2) +{ + switch (ctrl->type) { + case V4L2_CTRL_TYPE_BUTTON: + return false; + case V4L2_CTRL_TYPE_STRING: + idx *= ctrl->elem_size; + /* strings are always 0-terminated */ + return !strcmp(ptr1.p_char + idx, ptr2.p_char + idx); + case V4L2_CTRL_TYPE_INTEGER64: + return ptr1.p_s64[idx] == ptr2.p_s64[idx]; + case V4L2_CTRL_TYPE_U8: + return ptr1.p_u8[idx] == ptr2.p_u8[idx]; + case V4L2_CTRL_TYPE_U16: + return ptr1.p_u16[idx] == ptr2.p_u16[idx]; + case V4L2_CTRL_TYPE_U32: + return ptr1.p_u32[idx] == ptr2.p_u32[idx]; + default: + if (ctrl->is_int) + return ptr1.p_s32[idx] == ptr2.p_s32[idx]; + idx *= ctrl->elem_size; + return !memcmp(ptr1.p_const + idx, ptr2.p_const + idx, + ctrl->elem_size); + } +} + +/* Default intra MPEG-2 quantisation coefficients, from the specification. */ +static const u8 mpeg2_intra_quant_matrix[64] = { + 8, 16, 16, 19, 16, 19, 22, 22, + 22, 22, 22, 22, 26, 24, 26, 27, + 27, 27, 26, 26, 26, 26, 27, 27, + 27, 29, 29, 29, 34, 34, 34, 29, + 29, 29, 27, 27, 29, 29, 32, 32, + 34, 34, 37, 38, 37, 35, 35, 34, + 35, 38, 38, 40, 40, 40, 48, 48, + 46, 46, 56, 56, 58, 69, 69, 83 +}; + +static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx, + union v4l2_ctrl_ptr ptr) +{ + struct v4l2_ctrl_mpeg2_sequence *p_mpeg2_sequence; + struct v4l2_ctrl_mpeg2_picture *p_mpeg2_picture; + struct v4l2_ctrl_mpeg2_quantisation *p_mpeg2_quant; + struct v4l2_ctrl_vp8_frame *p_vp8_frame; + struct v4l2_ctrl_fwht_params *p_fwht_params; + void *p = ptr.p + idx * ctrl->elem_size; + + if (ctrl->p_def.p_const) + memcpy(p, ctrl->p_def.p_const, ctrl->elem_size); + else + memset(p, 0, ctrl->elem_size); + + switch ((u32)ctrl->type) { + case V4L2_CTRL_TYPE_MPEG2_SEQUENCE: + p_mpeg2_sequence = p; + + /* 4:2:0 */ + p_mpeg2_sequence->chroma_format = 1; + break; + case V4L2_CTRL_TYPE_MPEG2_PICTURE: + p_mpeg2_picture = p; + + /* interlaced top field */ + p_mpeg2_picture->picture_structure = V4L2_MPEG2_PIC_TOP_FIELD; + p_mpeg2_picture->picture_coding_type = + V4L2_MPEG2_PIC_CODING_TYPE_I; + break; + case V4L2_CTRL_TYPE_MPEG2_QUANTISATION: + p_mpeg2_quant = p; + + memcpy(p_mpeg2_quant->intra_quantiser_matrix, + mpeg2_intra_quant_matrix, + ARRAY_SIZE(mpeg2_intra_quant_matrix)); + /* + * The default non-intra MPEG-2 quantisation + * coefficients are all 16, as per the specification. + */ + memset(p_mpeg2_quant->non_intra_quantiser_matrix, 16, + sizeof(p_mpeg2_quant->non_intra_quantiser_matrix)); + break; + case V4L2_CTRL_TYPE_VP8_FRAME: + p_vp8_frame = p; + p_vp8_frame->num_dct_parts = 1; + break; + case V4L2_CTRL_TYPE_FWHT_PARAMS: + p_fwht_params = p; + p_fwht_params->version = V4L2_FWHT_VERSION; + p_fwht_params->width = 1280; + p_fwht_params->height = 720; + p_fwht_params->flags = V4L2_FWHT_FL_PIXENC_YUV | + (2 << V4L2_FWHT_FL_COMPONENTS_NUM_OFFSET); + break; + } +} + +static void std_init(const struct v4l2_ctrl *ctrl, u32 idx, + union v4l2_ctrl_ptr ptr) +{ + switch (ctrl->type) { + case V4L2_CTRL_TYPE_STRING: + idx *= ctrl->elem_size; + memset(ptr.p_char + idx, ' ', ctrl->minimum); + ptr.p_char[idx + ctrl->minimum] = '\0'; + break; + case V4L2_CTRL_TYPE_INTEGER64: + ptr.p_s64[idx] = ctrl->default_value; + break; + case V4L2_CTRL_TYPE_INTEGER: + case V4L2_CTRL_TYPE_INTEGER_MENU: + case V4L2_CTRL_TYPE_MENU: + case V4L2_CTRL_TYPE_BITMASK: + case V4L2_CTRL_TYPE_BOOLEAN: + ptr.p_s32[idx] = ctrl->default_value; + break; + case V4L2_CTRL_TYPE_BUTTON: + case V4L2_CTRL_TYPE_CTRL_CLASS: + ptr.p_s32[idx] = 0; + break; + case V4L2_CTRL_TYPE_U8: + ptr.p_u8[idx] = ctrl->default_value; + break; + case V4L2_CTRL_TYPE_U16: + ptr.p_u16[idx] = ctrl->default_value; + break; + case V4L2_CTRL_TYPE_U32: + ptr.p_u32[idx] = ctrl->default_value; + break; + default: + std_init_compound(ctrl, idx, ptr); + break; + } +} + +static void std_log(const struct v4l2_ctrl *ctrl) +{ + union v4l2_ctrl_ptr ptr = ctrl->p_cur; + + if (ctrl->is_array) { + unsigned i; + + for (i = 0; i < ctrl->nr_of_dims; i++) + pr_cont("[%u]", ctrl->dims[i]); + pr_cont(" "); + } + + switch (ctrl->type) { + case V4L2_CTRL_TYPE_INTEGER: + pr_cont("%d", *ptr.p_s32); + break; + case V4L2_CTRL_TYPE_BOOLEAN: + pr_cont("%s", *ptr.p_s32 ? "true" : "false"); + break; + case V4L2_CTRL_TYPE_MENU: + pr_cont("%s", ctrl->qmenu[*ptr.p_s32]); + break; + case V4L2_CTRL_TYPE_INTEGER_MENU: + pr_cont("%lld", ctrl->qmenu_int[*ptr.p_s32]); + break; + case V4L2_CTRL_TYPE_BITMASK: + pr_cont("0x%08x", *ptr.p_s32); + break; + case V4L2_CTRL_TYPE_INTEGER64: + pr_cont("%lld", *ptr.p_s64); + break; + case V4L2_CTRL_TYPE_STRING: + pr_cont("%s", ptr.p_char); + break; + case V4L2_CTRL_TYPE_U8: + pr_cont("%u", (unsigned)*ptr.p_u8); + break; + case V4L2_CTRL_TYPE_U16: + pr_cont("%u", (unsigned)*ptr.p_u16); + break; + case V4L2_CTRL_TYPE_U32: + pr_cont("%u", (unsigned)*ptr.p_u32); + break; + case V4L2_CTRL_TYPE_H264_SPS: + pr_cont("H264_SPS"); + break; + case V4L2_CTRL_TYPE_H264_PPS: + pr_cont("H264_PPS"); + break; + case V4L2_CTRL_TYPE_H264_SCALING_MATRIX: + pr_cont("H264_SCALING_MATRIX"); + break; + case V4L2_CTRL_TYPE_H264_SLICE_PARAMS: + pr_cont("H264_SLICE_PARAMS"); + break; + case V4L2_CTRL_TYPE_H264_DECODE_PARAMS: + pr_cont("H264_DECODE_PARAMS"); + break; + case V4L2_CTRL_TYPE_H264_PRED_WEIGHTS: + pr_cont("H264_PRED_WEIGHTS"); + break; + case V4L2_CTRL_TYPE_FWHT_PARAMS: + pr_cont("FWHT_PARAMS"); + break; + case V4L2_CTRL_TYPE_VP8_FRAME: + pr_cont("VP8_FRAME"); + break; + case V4L2_CTRL_TYPE_HDR10_CLL_INFO: + pr_cont("HDR10_CLL_INFO"); + break; + case V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY: + pr_cont("HDR10_MASTERING_DISPLAY"); + break; + case V4L2_CTRL_TYPE_MPEG2_QUANTISATION: + pr_cont("MPEG2_QUANTISATION"); + break; + case V4L2_CTRL_TYPE_MPEG2_SEQUENCE: + pr_cont("MPEG2_SEQUENCE"); + break; + case V4L2_CTRL_TYPE_MPEG2_PICTURE: + pr_cont("MPEG2_PICTURE"); + break; + default: + pr_cont("unknown type %d", ctrl->type); + break; + } +} + +/* + * Round towards the closest legal value. Be careful when we are + * close to the maximum range of the control type to prevent + * wrap-arounds. + */ +#define ROUND_TO_RANGE(val, offset_type, ctrl) \ +({ \ + offset_type offset; \ + if ((ctrl)->maximum >= 0 && \ + val >= (ctrl)->maximum - (s32)((ctrl)->step / 2)) \ + val = (ctrl)->maximum; \ + else \ + val += (s32)((ctrl)->step / 2); \ + val = clamp_t(typeof(val), val, \ + (ctrl)->minimum, (ctrl)->maximum); \ + offset = (val) - (ctrl)->minimum; \ + offset = (ctrl)->step * (offset / (u32)(ctrl)->step); \ + val = (ctrl)->minimum + offset; \ + 0; \ +}) + +/* Validate a new control */ + +#define zero_padding(s) \ + memset(&(s).padding, 0, sizeof((s).padding)) +#define zero_reserved(s) \ + memset(&(s).reserved, 0, sizeof((s).reserved)) + +/* + * Compound controls validation requires setting unused fields/flags to zero + * in order to properly detect unchanged controls with std_equal's memcmp. + */ +static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, + union v4l2_ctrl_ptr ptr) +{ + struct v4l2_ctrl_mpeg2_sequence *p_mpeg2_sequence; + struct v4l2_ctrl_mpeg2_picture *p_mpeg2_picture; + struct v4l2_ctrl_vp8_frame *p_vp8_frame; + struct v4l2_ctrl_fwht_params *p_fwht_params; + struct v4l2_ctrl_h264_sps *p_h264_sps; + struct v4l2_ctrl_h264_pps *p_h264_pps; + struct v4l2_ctrl_h264_pred_weights *p_h264_pred_weights; + struct v4l2_ctrl_h264_slice_params *p_h264_slice_params; + struct v4l2_ctrl_h264_decode_params *p_h264_dec_params; + struct v4l2_ctrl_hevc_sps *p_hevc_sps; + struct v4l2_ctrl_hevc_pps *p_hevc_pps; + struct v4l2_ctrl_hevc_slice_params *p_hevc_slice_params; + struct v4l2_ctrl_hdr10_mastering_display *p_hdr10_mastering; + struct v4l2_area *area; + void *p = ptr.p + idx * ctrl->elem_size; + unsigned int i; + + switch ((u32)ctrl->type) { + case V4L2_CTRL_TYPE_MPEG2_SEQUENCE: + p_mpeg2_sequence = p; + + switch (p_mpeg2_sequence->chroma_format) { + case 1: /* 4:2:0 */ + case 2: /* 4:2:2 */ + case 3: /* 4:4:4 */ + break; + default: + return -EINVAL; + } + break; + + case V4L2_CTRL_TYPE_MPEG2_PICTURE: + p_mpeg2_picture = p; + + switch (p_mpeg2_picture->intra_dc_precision) { + case 0: /* 8 bits */ + case 1: /* 9 bits */ + case 2: /* 10 bits */ + case 3: /* 11 bits */ + break; + default: + return -EINVAL; + } + + switch (p_mpeg2_picture->picture_structure) { + case V4L2_MPEG2_PIC_TOP_FIELD: + case V4L2_MPEG2_PIC_BOTTOM_FIELD: + case V4L2_MPEG2_PIC_FRAME: + break; + default: + return -EINVAL; + } + + switch (p_mpeg2_picture->picture_coding_type) { + case V4L2_MPEG2_PIC_CODING_TYPE_I: + case V4L2_MPEG2_PIC_CODING_TYPE_P: + case V4L2_MPEG2_PIC_CODING_TYPE_B: + break; + default: + return -EINVAL; + } + zero_reserved(*p_mpeg2_picture); + break; + + case V4L2_CTRL_TYPE_MPEG2_QUANTISATION: + break; + + case V4L2_CTRL_TYPE_FWHT_PARAMS: + p_fwht_params = p; + if (p_fwht_params->version < V4L2_FWHT_VERSION) + return -EINVAL; + if (!p_fwht_params->width || !p_fwht_params->height) + return -EINVAL; + break; + + case V4L2_CTRL_TYPE_H264_SPS: + p_h264_sps = p; + + /* Some syntax elements are only conditionally valid */ + if (p_h264_sps->pic_order_cnt_type != 0) { + p_h264_sps->log2_max_pic_order_cnt_lsb_minus4 = 0; + } else if (p_h264_sps->pic_order_cnt_type != 1) { + p_h264_sps->num_ref_frames_in_pic_order_cnt_cycle = 0; + p_h264_sps->offset_for_non_ref_pic = 0; + p_h264_sps->offset_for_top_to_bottom_field = 0; + memset(&p_h264_sps->offset_for_ref_frame, 0, + sizeof(p_h264_sps->offset_for_ref_frame)); + } + + if (!V4L2_H264_SPS_HAS_CHROMA_FORMAT(p_h264_sps)) { + p_h264_sps->chroma_format_idc = 1; + p_h264_sps->bit_depth_luma_minus8 = 0; + p_h264_sps->bit_depth_chroma_minus8 = 0; + + p_h264_sps->flags &= + ~V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS; + + if (p_h264_sps->chroma_format_idc < 3) + p_h264_sps->flags &= + ~V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE; + } + + if (p_h264_sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY) + p_h264_sps->flags &= + ~V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD; + + /* + * Chroma 4:2:2 format require at least High 4:2:2 profile. + * + * The H264 specification and well-known parser implementations + * use profile-idc values directly, as that is clearer and + * less ambiguous. We do the same here. + */ + if (p_h264_sps->profile_idc < 122 && + p_h264_sps->chroma_format_idc > 1) + return -EINVAL; + /* Chroma 4:4:4 format require at least High 4:2:2 profile */ + if (p_h264_sps->profile_idc < 244 && + p_h264_sps->chroma_format_idc > 2) + return -EINVAL; + if (p_h264_sps->chroma_format_idc > 3) + return -EINVAL; + + if (p_h264_sps->bit_depth_luma_minus8 > 6) + return -EINVAL; + if (p_h264_sps->bit_depth_chroma_minus8 > 6) + return -EINVAL; + if (p_h264_sps->log2_max_frame_num_minus4 > 12) + return -EINVAL; + if (p_h264_sps->pic_order_cnt_type > 2) + return -EINVAL; + if (p_h264_sps->log2_max_pic_order_cnt_lsb_minus4 > 12) + return -EINVAL; + if (p_h264_sps->max_num_ref_frames > V4L2_H264_REF_LIST_LEN) + return -EINVAL; + break; + + case V4L2_CTRL_TYPE_H264_PPS: + p_h264_pps = p; + + if (p_h264_pps->num_slice_groups_minus1 > 7) + return -EINVAL; + if (p_h264_pps->num_ref_idx_l0_default_active_minus1 > + (V4L2_H264_REF_LIST_LEN - 1)) + return -EINVAL; + if (p_h264_pps->num_ref_idx_l1_default_active_minus1 > + (V4L2_H264_REF_LIST_LEN - 1)) + return -EINVAL; + if (p_h264_pps->weighted_bipred_idc > 2) + return -EINVAL; + /* + * pic_init_qp_minus26 shall be in the range of + * -(26 + QpBdOffset_y) to +25, inclusive, + * where QpBdOffset_y is 6 * bit_depth_luma_minus8 + */ + if (p_h264_pps->pic_init_qp_minus26 < -62 || + p_h264_pps->pic_init_qp_minus26 > 25) + return -EINVAL; + if (p_h264_pps->pic_init_qs_minus26 < -26 || + p_h264_pps->pic_init_qs_minus26 > 25) + return -EINVAL; + if (p_h264_pps->chroma_qp_index_offset < -12 || + p_h264_pps->chroma_qp_index_offset > 12) + return -EINVAL; + if (p_h264_pps->second_chroma_qp_index_offset < -12 || + p_h264_pps->second_chroma_qp_index_offset > 12) + return -EINVAL; + break; + + case V4L2_CTRL_TYPE_H264_SCALING_MATRIX: + break; + + case V4L2_CTRL_TYPE_H264_PRED_WEIGHTS: + p_h264_pred_weights = p; + + if (p_h264_pred_weights->luma_log2_weight_denom > 7) + return -EINVAL; + if (p_h264_pred_weights->chroma_log2_weight_denom > 7) + return -EINVAL; + break; + + case V4L2_CTRL_TYPE_H264_SLICE_PARAMS: + p_h264_slice_params = p; + + if (p_h264_slice_params->slice_type != V4L2_H264_SLICE_TYPE_B) + p_h264_slice_params->flags &= + ~V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED; + + if (p_h264_slice_params->colour_plane_id > 2) + return -EINVAL; + if (p_h264_slice_params->cabac_init_idc > 2) + return -EINVAL; + if (p_h264_slice_params->disable_deblocking_filter_idc > 2) + return -EINVAL; + if (p_h264_slice_params->slice_alpha_c0_offset_div2 < -6 || + p_h264_slice_params->slice_alpha_c0_offset_div2 > 6) + return -EINVAL; + if (p_h264_slice_params->slice_beta_offset_div2 < -6 || + p_h264_slice_params->slice_beta_offset_div2 > 6) + return -EINVAL; + + if (p_h264_slice_params->slice_type == V4L2_H264_SLICE_TYPE_I || + p_h264_slice_params->slice_type == V4L2_H264_SLICE_TYPE_SI) + p_h264_slice_params->num_ref_idx_l0_active_minus1 = 0; + if (p_h264_slice_params->slice_type != V4L2_H264_SLICE_TYPE_B) + p_h264_slice_params->num_ref_idx_l1_active_minus1 = 0; + + if (p_h264_slice_params->num_ref_idx_l0_active_minus1 > + (V4L2_H264_REF_LIST_LEN - 1)) + return -EINVAL; + if (p_h264_slice_params->num_ref_idx_l1_active_minus1 > + (V4L2_H264_REF_LIST_LEN - 1)) + return -EINVAL; + zero_reserved(*p_h264_slice_params); + break; + + case V4L2_CTRL_TYPE_H264_DECODE_PARAMS: + p_h264_dec_params = p; + + if (p_h264_dec_params->nal_ref_idc > 3) + return -EINVAL; + for (i = 0; i < V4L2_H264_NUM_DPB_ENTRIES; i++) { + struct v4l2_h264_dpb_entry *dpb_entry = + &p_h264_dec_params->dpb[i]; + + zero_reserved(*dpb_entry); + } + zero_reserved(*p_h264_dec_params); + break; + + case V4L2_CTRL_TYPE_VP8_FRAME: + p_vp8_frame = p; + + switch (p_vp8_frame->num_dct_parts) { + case 1: + case 2: + case 4: + case 8: + break; + default: + return -EINVAL; + } + zero_padding(p_vp8_frame->segment); + zero_padding(p_vp8_frame->lf); + zero_padding(p_vp8_frame->quant); + zero_padding(p_vp8_frame->entropy); + zero_padding(p_vp8_frame->coder_state); + break; + + case V4L2_CTRL_TYPE_HEVC_SPS: + p_hevc_sps = p; + + if (!(p_hevc_sps->flags & V4L2_HEVC_SPS_FLAG_PCM_ENABLED)) { + p_hevc_sps->pcm_sample_bit_depth_luma_minus1 = 0; + p_hevc_sps->pcm_sample_bit_depth_chroma_minus1 = 0; + p_hevc_sps->log2_min_pcm_luma_coding_block_size_minus3 = 0; + p_hevc_sps->log2_diff_max_min_pcm_luma_coding_block_size = 0; + } + + if (!(p_hevc_sps->flags & + V4L2_HEVC_SPS_FLAG_LONG_TERM_REF_PICS_PRESENT)) + p_hevc_sps->num_long_term_ref_pics_sps = 0; + break; + + case V4L2_CTRL_TYPE_HEVC_PPS: + p_hevc_pps = p; + + if (!(p_hevc_pps->flags & + V4L2_HEVC_PPS_FLAG_CU_QP_DELTA_ENABLED)) + p_hevc_pps->diff_cu_qp_delta_depth = 0; + + if (!(p_hevc_pps->flags & V4L2_HEVC_PPS_FLAG_TILES_ENABLED)) { + p_hevc_pps->num_tile_columns_minus1 = 0; + p_hevc_pps->num_tile_rows_minus1 = 0; + memset(&p_hevc_pps->column_width_minus1, 0, + sizeof(p_hevc_pps->column_width_minus1)); + memset(&p_hevc_pps->row_height_minus1, 0, + sizeof(p_hevc_pps->row_height_minus1)); + + p_hevc_pps->flags &= + ~V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED; + } + + if (p_hevc_pps->flags & + V4L2_HEVC_PPS_FLAG_PPS_DISABLE_DEBLOCKING_FILTER) { + p_hevc_pps->pps_beta_offset_div2 = 0; + p_hevc_pps->pps_tc_offset_div2 = 0; + } + + zero_padding(*p_hevc_pps); + break; + + case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS: + p_hevc_slice_params = p; + + if (p_hevc_slice_params->num_active_dpb_entries > + V4L2_HEVC_DPB_ENTRIES_NUM_MAX) + return -EINVAL; + + zero_padding(p_hevc_slice_params->pred_weight_table); + + for (i = 0; i < p_hevc_slice_params->num_active_dpb_entries; + i++) { + struct v4l2_hevc_dpb_entry *dpb_entry = + &p_hevc_slice_params->dpb[i]; + + zero_padding(*dpb_entry); + } + + zero_padding(*p_hevc_slice_params); + break; + + case V4L2_CTRL_TYPE_HDR10_CLL_INFO: + break; + + case V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY: + p_hdr10_mastering = p; + + for (i = 0; i < 3; ++i) { + if (p_hdr10_mastering->display_primaries_x[i] < + V4L2_HDR10_MASTERING_PRIMARIES_X_LOW || + p_hdr10_mastering->display_primaries_x[i] > + V4L2_HDR10_MASTERING_PRIMARIES_X_HIGH || + p_hdr10_mastering->display_primaries_y[i] < + V4L2_HDR10_MASTERING_PRIMARIES_Y_LOW || + p_hdr10_mastering->display_primaries_y[i] > + V4L2_HDR10_MASTERING_PRIMARIES_Y_HIGH) + return -EINVAL; + } + + if (p_hdr10_mastering->white_point_x < + V4L2_HDR10_MASTERING_WHITE_POINT_X_LOW || + p_hdr10_mastering->white_point_x > + V4L2_HDR10_MASTERING_WHITE_POINT_X_HIGH || + p_hdr10_mastering->white_point_y < + V4L2_HDR10_MASTERING_WHITE_POINT_Y_LOW || + p_hdr10_mastering->white_point_y > + V4L2_HDR10_MASTERING_WHITE_POINT_Y_HIGH) + return -EINVAL; + + if (p_hdr10_mastering->max_display_mastering_luminance < + V4L2_HDR10_MASTERING_MAX_LUMA_LOW || + p_hdr10_mastering->max_display_mastering_luminance > + V4L2_HDR10_MASTERING_MAX_LUMA_HIGH || + p_hdr10_mastering->min_display_mastering_luminance < + V4L2_HDR10_MASTERING_MIN_LUMA_LOW || + p_hdr10_mastering->min_display_mastering_luminance > + V4L2_HDR10_MASTERING_MIN_LUMA_HIGH) + return -EINVAL; + + /* The following restriction comes from ITU-T Rec. H.265 spec */ + if (p_hdr10_mastering->max_display_mastering_luminance == + V4L2_HDR10_MASTERING_MAX_LUMA_LOW && + p_hdr10_mastering->min_display_mastering_luminance == + V4L2_HDR10_MASTERING_MIN_LUMA_HIGH) + return -EINVAL; + + break; + + case V4L2_CTRL_TYPE_AREA: + area = p; + if (!area->width || !area->height) + return -EINVAL; + break; + + default: + return -EINVAL; + } + + return 0; +} + +static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx, + union v4l2_ctrl_ptr ptr) +{ + size_t len; + u64 offset; + s64 val; + + switch ((u32)ctrl->type) { + case V4L2_CTRL_TYPE_INTEGER: + return ROUND_TO_RANGE(ptr.p_s32[idx], u32, ctrl); + case V4L2_CTRL_TYPE_INTEGER64: + /* + * We can't use the ROUND_TO_RANGE define here due to + * the u64 divide that needs special care. + */ + val = ptr.p_s64[idx]; + if (ctrl->maximum >= 0 && val >= ctrl->maximum - (s64)(ctrl->step / 2)) + val = ctrl->maximum; + else + val += (s64)(ctrl->step / 2); + val = clamp_t(s64, val, ctrl->minimum, ctrl->maximum); + offset = val - ctrl->minimum; + do_div(offset, ctrl->step); + ptr.p_s64[idx] = ctrl->minimum + offset * ctrl->step; + return 0; + case V4L2_CTRL_TYPE_U8: + return ROUND_TO_RANGE(ptr.p_u8[idx], u8, ctrl); + case V4L2_CTRL_TYPE_U16: + return ROUND_TO_RANGE(ptr.p_u16[idx], u16, ctrl); + case V4L2_CTRL_TYPE_U32: + return ROUND_TO_RANGE(ptr.p_u32[idx], u32, ctrl); + + case V4L2_CTRL_TYPE_BOOLEAN: + ptr.p_s32[idx] = !!ptr.p_s32[idx]; + return 0; + + case V4L2_CTRL_TYPE_MENU: + case V4L2_CTRL_TYPE_INTEGER_MENU: + if (ptr.p_s32[idx] < ctrl->minimum || ptr.p_s32[idx] > ctrl->maximum) + return -ERANGE; + if (ptr.p_s32[idx] < BITS_PER_LONG_LONG && + (ctrl->menu_skip_mask & BIT_ULL(ptr.p_s32[idx]))) + return -EINVAL; + if (ctrl->type == V4L2_CTRL_TYPE_MENU && + ctrl->qmenu[ptr.p_s32[idx]][0] == '\0') + return -EINVAL; + return 0; + + case V4L2_CTRL_TYPE_BITMASK: + ptr.p_s32[idx] &= ctrl->maximum; + return 0; + + case V4L2_CTRL_TYPE_BUTTON: + case V4L2_CTRL_TYPE_CTRL_CLASS: + ptr.p_s32[idx] = 0; + return 0; + + case V4L2_CTRL_TYPE_STRING: + idx *= ctrl->elem_size; + len = strlen(ptr.p_char + idx); + if (len < ctrl->minimum) + return -ERANGE; + if ((len - (u32)ctrl->minimum) % (u32)ctrl->step) + return -ERANGE; + return 0; + + default: + return std_validate_compound(ctrl, idx, ptr); + } +} + +static const struct v4l2_ctrl_type_ops std_type_ops = { + .equal = std_equal, + .init = std_init, + .log = std_log, + .validate = std_validate, +}; + +void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl, v4l2_ctrl_notify_fnc notify, void *priv) +{ + if (!ctrl) + return; + if (!notify) { + ctrl->call_notify = 0; + return; + } + if (WARN_ON(ctrl->handler->notify && ctrl->handler->notify != notify)) + return; + ctrl->handler->notify = notify; + ctrl->handler->notify_priv = priv; + ctrl->call_notify = 1; +} +EXPORT_SYMBOL(v4l2_ctrl_notify); + +/* Copy the one value to another. */ +static void ptr_to_ptr(struct v4l2_ctrl *ctrl, + union v4l2_ctrl_ptr from, union v4l2_ctrl_ptr to) +{ + if (ctrl == NULL) + return; + memcpy(to.p, from.p_const, ctrl->elems * ctrl->elem_size); +} + +/* Copy the new value to the current value. */ +void new_to_cur(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 ch_flags) +{ + bool changed; + + if (ctrl == NULL) + return; + + /* has_changed is set by cluster_changed */ + changed = ctrl->has_changed; + if (changed) + ptr_to_ptr(ctrl, ctrl->p_new, ctrl->p_cur); + + if (ch_flags & V4L2_EVENT_CTRL_CH_FLAGS) { + /* Note: CH_FLAGS is only set for auto clusters. */ + ctrl->flags &= + ~(V4L2_CTRL_FLAG_INACTIVE | V4L2_CTRL_FLAG_VOLATILE); + if (!is_cur_manual(ctrl->cluster[0])) { + ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; + if (ctrl->cluster[0]->has_volatiles) + ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; + } + fh = NULL; + } + if (changed || ch_flags) { + /* If a control was changed that was not one of the controls + modified by the application, then send the event to all. */ + if (!ctrl->is_new) + fh = NULL; + send_event(fh, ctrl, + (changed ? V4L2_EVENT_CTRL_CH_VALUE : 0) | ch_flags); + if (ctrl->call_notify && changed && ctrl->handler->notify) + ctrl->handler->notify(ctrl, ctrl->handler->notify_priv); + } +} + +/* Copy the current value to the new value */ +void cur_to_new(struct v4l2_ctrl *ctrl) +{ + if (ctrl == NULL) + return; + ptr_to_ptr(ctrl, ctrl->p_cur, ctrl->p_new); +} + +/* Copy the new value to the request value */ +void new_to_req(struct v4l2_ctrl_ref *ref) +{ + if (!ref) + return; + ptr_to_ptr(ref->ctrl, ref->ctrl->p_new, ref->p_req); + ref->valid_p_req = true; +} + +/* Copy the current value to the request value */ +void cur_to_req(struct v4l2_ctrl_ref *ref) +{ + if (!ref) + return; + ptr_to_ptr(ref->ctrl, ref->ctrl->p_cur, ref->p_req); + ref->valid_p_req = true; +} + +/* Copy the request value to the new value */ +void req_to_new(struct v4l2_ctrl_ref *ref) +{ + if (!ref) + return; + if (ref->valid_p_req) + ptr_to_ptr(ref->ctrl, ref->p_req, ref->ctrl->p_new); + else + ptr_to_ptr(ref->ctrl, ref->ctrl->p_cur, ref->ctrl->p_new); +} + +/* Control range checking */ +int check_range(enum v4l2_ctrl_type type, + s64 min, s64 max, u64 step, s64 def) +{ + switch (type) { + case V4L2_CTRL_TYPE_BOOLEAN: + if (step != 1 || max > 1 || min < 0) + return -ERANGE; + fallthrough; + case V4L2_CTRL_TYPE_U8: + case V4L2_CTRL_TYPE_U16: + case V4L2_CTRL_TYPE_U32: + case V4L2_CTRL_TYPE_INTEGER: + case V4L2_CTRL_TYPE_INTEGER64: + if (step == 0 || min > max || def < min || def > max) + return -ERANGE; + return 0; + case V4L2_CTRL_TYPE_BITMASK: + if (step || min || !max || (def & ~max)) + return -ERANGE; + return 0; + case V4L2_CTRL_TYPE_MENU: + case V4L2_CTRL_TYPE_INTEGER_MENU: + if (min > max || def < min || def > max) + return -ERANGE; + /* Note: step == menu_skip_mask for menu controls. + So here we check if the default value is masked out. */ + if (step && ((1 << def) & step)) + return -EINVAL; + return 0; + case V4L2_CTRL_TYPE_STRING: + if (min > max || min < 0 || step < 1 || def) + return -ERANGE; + return 0; + default: + return 0; + } +} + +/* Validate a new control */ +int validate_new(const struct v4l2_ctrl *ctrl, union v4l2_ctrl_ptr p_new) +{ + unsigned idx; + int err = 0; + + for (idx = 0; !err && idx < ctrl->elems; idx++) + err = ctrl->type_ops->validate(ctrl, idx, p_new); + return err; +} + +/* Set the handler's error code if it wasn't set earlier already */ +static inline int handler_set_err(struct v4l2_ctrl_handler *hdl, int err) +{ + if (hdl->error == 0) + hdl->error = err; + return err; +} + +/* Initialize the handler */ +int v4l2_ctrl_handler_init_class(struct v4l2_ctrl_handler *hdl, + unsigned nr_of_controls_hint, + struct lock_class_key *key, const char *name) +{ + mutex_init(&hdl->_lock); + hdl->lock = &hdl->_lock; + lockdep_set_class_and_name(hdl->lock, key, name); + INIT_LIST_HEAD(&hdl->ctrls); + INIT_LIST_HEAD(&hdl->ctrl_refs); + hdl->nr_of_buckets = 1 + nr_of_controls_hint / 8; + hdl->buckets = kvmalloc_array(hdl->nr_of_buckets, + sizeof(hdl->buckets[0]), + GFP_KERNEL | __GFP_ZERO); + hdl->error = hdl->buckets ? 0 : -ENOMEM; + v4l2_ctrl_handler_init_request(hdl); + return hdl->error; +} +EXPORT_SYMBOL(v4l2_ctrl_handler_init_class); + +/* Free all controls and control refs */ +void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl) +{ + struct v4l2_ctrl_ref *ref, *next_ref; + struct v4l2_ctrl *ctrl, *next_ctrl; + struct v4l2_subscribed_event *sev, *next_sev; + + if (hdl == NULL || hdl->buckets == NULL) + return; + + v4l2_ctrl_handler_free_request(hdl); + + mutex_lock(hdl->lock); + /* Free all nodes */ + list_for_each_entry_safe(ref, next_ref, &hdl->ctrl_refs, node) { + list_del(&ref->node); + kfree(ref); + } + /* Free all controls owned by the handler */ + list_for_each_entry_safe(ctrl, next_ctrl, &hdl->ctrls, node) { + list_del(&ctrl->node); + list_for_each_entry_safe(sev, next_sev, &ctrl->ev_subs, node) + list_del(&sev->node); + kvfree(ctrl); + } + kvfree(hdl->buckets); + hdl->buckets = NULL; + hdl->cached = NULL; + hdl->error = 0; + mutex_unlock(hdl->lock); + mutex_destroy(&hdl->_lock); +} +EXPORT_SYMBOL(v4l2_ctrl_handler_free); + +/* For backwards compatibility: V4L2_CID_PRIVATE_BASE should no longer + be used except in G_CTRL, S_CTRL, QUERYCTRL and QUERYMENU when dealing + with applications that do not use the NEXT_CTRL flag. + + We just find the n-th private user control. It's O(N), but that should not + be an issue in this particular case. */ +static struct v4l2_ctrl_ref *find_private_ref( + struct v4l2_ctrl_handler *hdl, u32 id) +{ + struct v4l2_ctrl_ref *ref; + + id -= V4L2_CID_PRIVATE_BASE; + list_for_each_entry(ref, &hdl->ctrl_refs, node) { + /* Search for private user controls that are compatible with + VIDIOC_G/S_CTRL. */ + if (V4L2_CTRL_ID2WHICH(ref->ctrl->id) == V4L2_CTRL_CLASS_USER && + V4L2_CTRL_DRIVER_PRIV(ref->ctrl->id)) { + if (!ref->ctrl->is_int) + continue; + if (id == 0) + return ref; + id--; + } + } + return NULL; +} + +/* Find a control with the given ID. */ +struct v4l2_ctrl_ref *find_ref(struct v4l2_ctrl_handler *hdl, u32 id) +{ + struct v4l2_ctrl_ref *ref; + int bucket; + + id &= V4L2_CTRL_ID_MASK; + + /* Old-style private controls need special handling */ + if (id >= V4L2_CID_PRIVATE_BASE) + return find_private_ref(hdl, id); + bucket = id % hdl->nr_of_buckets; + + /* Simple optimization: cache the last control found */ + if (hdl->cached && hdl->cached->ctrl->id == id) + return hdl->cached; + + /* Not in cache, search the hash */ + ref = hdl->buckets ? hdl->buckets[bucket] : NULL; + while (ref && ref->ctrl->id != id) + ref = ref->next; + + if (ref) + hdl->cached = ref; /* cache it! */ + return ref; +} + +/* Find a control with the given ID. Take the handler's lock first. */ +struct v4l2_ctrl_ref *find_ref_lock(struct v4l2_ctrl_handler *hdl, u32 id) +{ + struct v4l2_ctrl_ref *ref = NULL; + + if (hdl) { + mutex_lock(hdl->lock); + ref = find_ref(hdl, id); + mutex_unlock(hdl->lock); + } + return ref; +} + +/* Find a control with the given ID. */ +struct v4l2_ctrl *v4l2_ctrl_find(struct v4l2_ctrl_handler *hdl, u32 id) +{ + struct v4l2_ctrl_ref *ref = find_ref_lock(hdl, id); + + return ref ? ref->ctrl : NULL; +} +EXPORT_SYMBOL(v4l2_ctrl_find); + +/* Allocate a new v4l2_ctrl_ref and hook it into the handler. */ +int handler_new_ref(struct v4l2_ctrl_handler *hdl, + struct v4l2_ctrl *ctrl, + struct v4l2_ctrl_ref **ctrl_ref, + bool from_other_dev, bool allocate_req) +{ + struct v4l2_ctrl_ref *ref; + struct v4l2_ctrl_ref *new_ref; + u32 id = ctrl->id; + u32 class_ctrl = V4L2_CTRL_ID2WHICH(id) | 1; + int bucket = id % hdl->nr_of_buckets; /* which bucket to use */ + unsigned int size_extra_req = 0; + + if (ctrl_ref) + *ctrl_ref = NULL; + + /* + * Automatically add the control class if it is not yet present and + * the new control is not a compound control. + */ + if (ctrl->type < V4L2_CTRL_COMPOUND_TYPES && + id != class_ctrl && find_ref_lock(hdl, class_ctrl) == NULL) + if (!v4l2_ctrl_new_std(hdl, NULL, class_ctrl, 0, 0, 0, 0)) + return hdl->error; + + if (hdl->error) + return hdl->error; + + if (allocate_req) + size_extra_req = ctrl->elems * ctrl->elem_size; + new_ref = kzalloc(sizeof(*new_ref) + size_extra_req, GFP_KERNEL); + if (!new_ref) + return handler_set_err(hdl, -ENOMEM); + new_ref->ctrl = ctrl; + new_ref->from_other_dev = from_other_dev; + if (size_extra_req) + new_ref->p_req.p = &new_ref[1]; + + INIT_LIST_HEAD(&new_ref->node); + + mutex_lock(hdl->lock); + + /* Add immediately at the end of the list if the list is empty, or if + the last element in the list has a lower ID. + This ensures that when elements are added in ascending order the + insertion is an O(1) operation. */ + if (list_empty(&hdl->ctrl_refs) || id > node2id(hdl->ctrl_refs.prev)) { + list_add_tail(&new_ref->node, &hdl->ctrl_refs); + goto insert_in_hash; + } + + /* Find insert position in sorted list */ + list_for_each_entry(ref, &hdl->ctrl_refs, node) { + if (ref->ctrl->id < id) + continue; + /* Don't add duplicates */ + if (ref->ctrl->id == id) { + kfree(new_ref); + goto unlock; + } + list_add(&new_ref->node, ref->node.prev); + break; + } + +insert_in_hash: + /* Insert the control node in the hash */ + new_ref->next = hdl->buckets[bucket]; + hdl->buckets[bucket] = new_ref; + if (ctrl_ref) + *ctrl_ref = new_ref; + if (ctrl->handler == hdl) { + /* By default each control starts in a cluster of its own. + * new_ref->ctrl is basically a cluster array with one + * element, so that's perfect to use as the cluster pointer. + * But only do this for the handler that owns the control. + */ + ctrl->cluster = &new_ref->ctrl; + ctrl->ncontrols = 1; + } + +unlock: + mutex_unlock(hdl->lock); + return 0; +} + +/* Add a new control */ +static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, + const struct v4l2_ctrl_ops *ops, + const struct v4l2_ctrl_type_ops *type_ops, + u32 id, const char *name, enum v4l2_ctrl_type type, + s64 min, s64 max, u64 step, s64 def, + const u32 dims[V4L2_CTRL_MAX_DIMS], u32 elem_size, + u32 flags, const char * const *qmenu, + const s64 *qmenu_int, const union v4l2_ctrl_ptr p_def, + void *priv) +{ + struct v4l2_ctrl *ctrl; + unsigned sz_extra; + unsigned nr_of_dims = 0; + unsigned elems = 1; + bool is_array; + unsigned tot_ctrl_size; + unsigned idx; + void *data; + int err; + + if (hdl->error) + return NULL; + + while (dims && dims[nr_of_dims]) { + elems *= dims[nr_of_dims]; + nr_of_dims++; + if (nr_of_dims == V4L2_CTRL_MAX_DIMS) + break; + } + is_array = nr_of_dims > 0; + + /* Prefill elem_size for all types handled by std_type_ops */ + switch ((u32)type) { + case V4L2_CTRL_TYPE_INTEGER64: + elem_size = sizeof(s64); + break; + case V4L2_CTRL_TYPE_STRING: + elem_size = max + 1; + break; + case V4L2_CTRL_TYPE_U8: + elem_size = sizeof(u8); + break; + case V4L2_CTRL_TYPE_U16: + elem_size = sizeof(u16); + break; + case V4L2_CTRL_TYPE_U32: + elem_size = sizeof(u32); + break; + case V4L2_CTRL_TYPE_MPEG2_SEQUENCE: + elem_size = sizeof(struct v4l2_ctrl_mpeg2_sequence); + break; + case V4L2_CTRL_TYPE_MPEG2_PICTURE: + elem_size = sizeof(struct v4l2_ctrl_mpeg2_picture); + break; + case V4L2_CTRL_TYPE_MPEG2_QUANTISATION: + elem_size = sizeof(struct v4l2_ctrl_mpeg2_quantisation); + break; + case V4L2_CTRL_TYPE_FWHT_PARAMS: + elem_size = sizeof(struct v4l2_ctrl_fwht_params); + break; + case V4L2_CTRL_TYPE_H264_SPS: + elem_size = sizeof(struct v4l2_ctrl_h264_sps); + break; + case V4L2_CTRL_TYPE_H264_PPS: + elem_size = sizeof(struct v4l2_ctrl_h264_pps); + break; + case V4L2_CTRL_TYPE_H264_SCALING_MATRIX: + elem_size = sizeof(struct v4l2_ctrl_h264_scaling_matrix); + break; + case V4L2_CTRL_TYPE_H264_SLICE_PARAMS: + elem_size = sizeof(struct v4l2_ctrl_h264_slice_params); + break; + case V4L2_CTRL_TYPE_H264_DECODE_PARAMS: + elem_size = sizeof(struct v4l2_ctrl_h264_decode_params); + break; + case V4L2_CTRL_TYPE_H264_PRED_WEIGHTS: + elem_size = sizeof(struct v4l2_ctrl_h264_pred_weights); + break; + case V4L2_CTRL_TYPE_VP8_FRAME: + elem_size = sizeof(struct v4l2_ctrl_vp8_frame); + break; + case V4L2_CTRL_TYPE_HEVC_SPS: + elem_size = sizeof(struct v4l2_ctrl_hevc_sps); + break; + case V4L2_CTRL_TYPE_HEVC_PPS: + elem_size = sizeof(struct v4l2_ctrl_hevc_pps); + break; + case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS: + elem_size = sizeof(struct v4l2_ctrl_hevc_slice_params); + break; + case V4L2_CTRL_TYPE_HDR10_CLL_INFO: + elem_size = sizeof(struct v4l2_ctrl_hdr10_cll_info); + break; + case V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY: + elem_size = sizeof(struct v4l2_ctrl_hdr10_mastering_display); + break; + case V4L2_CTRL_TYPE_AREA: + elem_size = sizeof(struct v4l2_area); + break; + default: + if (type < V4L2_CTRL_COMPOUND_TYPES) + elem_size = sizeof(s32); + break; + } + tot_ctrl_size = elem_size * elems; + + /* Sanity checks */ + if (id == 0 || name == NULL || !elem_size || + id >= V4L2_CID_PRIVATE_BASE || + (type == V4L2_CTRL_TYPE_MENU && qmenu == NULL) || + (type == V4L2_CTRL_TYPE_INTEGER_MENU && qmenu_int == NULL)) { + handler_set_err(hdl, -ERANGE); + return NULL; + } + err = check_range(type, min, max, step, def); + if (err) { + handler_set_err(hdl, err); + return NULL; + } + if (is_array && + (type == V4L2_CTRL_TYPE_BUTTON || + type == V4L2_CTRL_TYPE_CTRL_CLASS)) { + handler_set_err(hdl, -EINVAL); + return NULL; + } + + sz_extra = 0; + if (type == V4L2_CTRL_TYPE_BUTTON) + flags |= V4L2_CTRL_FLAG_WRITE_ONLY | + V4L2_CTRL_FLAG_EXECUTE_ON_WRITE; + else if (type == V4L2_CTRL_TYPE_CTRL_CLASS) + flags |= V4L2_CTRL_FLAG_READ_ONLY; + else if (type == V4L2_CTRL_TYPE_INTEGER64 || + type == V4L2_CTRL_TYPE_STRING || + type >= V4L2_CTRL_COMPOUND_TYPES || + is_array) + sz_extra += 2 * tot_ctrl_size; + + if (type >= V4L2_CTRL_COMPOUND_TYPES && p_def.p_const) + sz_extra += elem_size; + + ctrl = kvzalloc(sizeof(*ctrl) + sz_extra, GFP_KERNEL); + if (ctrl == NULL) { + handler_set_err(hdl, -ENOMEM); + return NULL; + } + + INIT_LIST_HEAD(&ctrl->node); + INIT_LIST_HEAD(&ctrl->ev_subs); + ctrl->handler = hdl; + ctrl->ops = ops; + ctrl->type_ops = type_ops ? type_ops : &std_type_ops; + ctrl->id = id; + ctrl->name = name; + ctrl->type = type; + ctrl->flags = flags; + ctrl->minimum = min; + ctrl->maximum = max; + ctrl->step = step; + ctrl->default_value = def; + ctrl->is_string = !is_array && type == V4L2_CTRL_TYPE_STRING; + ctrl->is_ptr = is_array || type >= V4L2_CTRL_COMPOUND_TYPES || ctrl->is_string; + ctrl->is_int = !ctrl->is_ptr && type != V4L2_CTRL_TYPE_INTEGER64; + ctrl->is_array = is_array; + ctrl->elems = elems; + ctrl->nr_of_dims = nr_of_dims; + if (nr_of_dims) + memcpy(ctrl->dims, dims, nr_of_dims * sizeof(dims[0])); + ctrl->elem_size = elem_size; + if (type == V4L2_CTRL_TYPE_MENU) + ctrl->qmenu = qmenu; + else if (type == V4L2_CTRL_TYPE_INTEGER_MENU) + ctrl->qmenu_int = qmenu_int; + ctrl->priv = priv; + ctrl->cur.val = ctrl->val = def; + data = &ctrl[1]; + + if (!ctrl->is_int) { + ctrl->p_new.p = data; + ctrl->p_cur.p = data + tot_ctrl_size; + } else { + ctrl->p_new.p = &ctrl->val; + ctrl->p_cur.p = &ctrl->cur.val; + } + + if (type >= V4L2_CTRL_COMPOUND_TYPES && p_def.p_const) { + ctrl->p_def.p = ctrl->p_cur.p + tot_ctrl_size; + memcpy(ctrl->p_def.p, p_def.p_const, elem_size); + } + + for (idx = 0; idx < elems; idx++) { + ctrl->type_ops->init(ctrl, idx, ctrl->p_cur); + ctrl->type_ops->init(ctrl, idx, ctrl->p_new); + } + + if (handler_new_ref(hdl, ctrl, NULL, false, false)) { + kvfree(ctrl); + return NULL; + } + mutex_lock(hdl->lock); + list_add_tail(&ctrl->node, &hdl->ctrls); + mutex_unlock(hdl->lock); + return ctrl; +} + +struct v4l2_ctrl *v4l2_ctrl_new_custom(struct v4l2_ctrl_handler *hdl, + const struct v4l2_ctrl_config *cfg, void *priv) +{ + bool is_menu; + struct v4l2_ctrl *ctrl; + const char *name = cfg->name; + const char * const *qmenu = cfg->qmenu; + const s64 *qmenu_int = cfg->qmenu_int; + enum v4l2_ctrl_type type = cfg->type; + u32 flags = cfg->flags; + s64 min = cfg->min; + s64 max = cfg->max; + u64 step = cfg->step; + s64 def = cfg->def; + + if (name == NULL) + v4l2_ctrl_fill(cfg->id, &name, &type, &min, &max, &step, + &def, &flags); + + is_menu = (type == V4L2_CTRL_TYPE_MENU || + type == V4L2_CTRL_TYPE_INTEGER_MENU); + if (is_menu) + WARN_ON(step); + else + WARN_ON(cfg->menu_skip_mask); + if (type == V4L2_CTRL_TYPE_MENU && !qmenu) { + qmenu = v4l2_ctrl_get_menu(cfg->id); + } else if (type == V4L2_CTRL_TYPE_INTEGER_MENU && !qmenu_int) { + handler_set_err(hdl, -EINVAL); + return NULL; + } + + ctrl = v4l2_ctrl_new(hdl, cfg->ops, cfg->type_ops, cfg->id, name, + type, min, max, + is_menu ? cfg->menu_skip_mask : step, def, + cfg->dims, cfg->elem_size, + flags, qmenu, qmenu_int, cfg->p_def, priv); + if (ctrl) + ctrl->is_private = cfg->is_private; + return ctrl; +} +EXPORT_SYMBOL(v4l2_ctrl_new_custom); + +/* Helper function for standard non-menu controls */ +struct v4l2_ctrl *v4l2_ctrl_new_std(struct v4l2_ctrl_handler *hdl, + const struct v4l2_ctrl_ops *ops, + u32 id, s64 min, s64 max, u64 step, s64 def) +{ + const char *name; + enum v4l2_ctrl_type type; + u32 flags; + + v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags); + if (type == V4L2_CTRL_TYPE_MENU || + type == V4L2_CTRL_TYPE_INTEGER_MENU || + type >= V4L2_CTRL_COMPOUND_TYPES) { + handler_set_err(hdl, -EINVAL); + return NULL; + } + return v4l2_ctrl_new(hdl, ops, NULL, id, name, type, + min, max, step, def, NULL, 0, + flags, NULL, NULL, ptr_null, NULL); +} +EXPORT_SYMBOL(v4l2_ctrl_new_std); + +/* Helper function for standard menu controls */ +struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl, + const struct v4l2_ctrl_ops *ops, + u32 id, u8 _max, u64 mask, u8 _def) +{ + const char * const *qmenu = NULL; + const s64 *qmenu_int = NULL; + unsigned int qmenu_int_len = 0; + const char *name; + enum v4l2_ctrl_type type; + s64 min; + s64 max = _max; + s64 def = _def; + u64 step; + u32 flags; + + v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags); + + if (type == V4L2_CTRL_TYPE_MENU) + qmenu = v4l2_ctrl_get_menu(id); + else if (type == V4L2_CTRL_TYPE_INTEGER_MENU) + qmenu_int = v4l2_ctrl_get_int_menu(id, &qmenu_int_len); + + if ((!qmenu && !qmenu_int) || (qmenu_int && max > qmenu_int_len)) { + handler_set_err(hdl, -EINVAL); + return NULL; + } + return v4l2_ctrl_new(hdl, ops, NULL, id, name, type, + 0, max, mask, def, NULL, 0, + flags, qmenu, qmenu_int, ptr_null, NULL); +} +EXPORT_SYMBOL(v4l2_ctrl_new_std_menu); + +/* Helper function for standard menu controls with driver defined menu */ +struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items(struct v4l2_ctrl_handler *hdl, + const struct v4l2_ctrl_ops *ops, u32 id, u8 _max, + u64 mask, u8 _def, const char * const *qmenu) +{ + enum v4l2_ctrl_type type; + const char *name; + u32 flags; + u64 step; + s64 min; + s64 max = _max; + s64 def = _def; + + /* v4l2_ctrl_new_std_menu_items() should only be called for + * standard controls without a standard menu. + */ + if (v4l2_ctrl_get_menu(id)) { + handler_set_err(hdl, -EINVAL); + return NULL; + } + + v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags); + if (type != V4L2_CTRL_TYPE_MENU || qmenu == NULL) { + handler_set_err(hdl, -EINVAL); + return NULL; + } + return v4l2_ctrl_new(hdl, ops, NULL, id, name, type, + 0, max, mask, def, NULL, 0, + flags, qmenu, NULL, ptr_null, NULL); + +} +EXPORT_SYMBOL(v4l2_ctrl_new_std_menu_items); + +/* Helper function for standard compound controls */ +struct v4l2_ctrl *v4l2_ctrl_new_std_compound(struct v4l2_ctrl_handler *hdl, + const struct v4l2_ctrl_ops *ops, u32 id, + const union v4l2_ctrl_ptr p_def) +{ + const char *name; + enum v4l2_ctrl_type type; + u32 flags; + s64 min, max, step, def; + + v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags); + if (type < V4L2_CTRL_COMPOUND_TYPES) { + handler_set_err(hdl, -EINVAL); + return NULL; + } + return v4l2_ctrl_new(hdl, ops, NULL, id, name, type, + min, max, step, def, NULL, 0, + flags, NULL, NULL, p_def, NULL); +} +EXPORT_SYMBOL(v4l2_ctrl_new_std_compound); + +/* Helper function for standard integer menu controls */ +struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl, + const struct v4l2_ctrl_ops *ops, + u32 id, u8 _max, u8 _def, const s64 *qmenu_int) +{ + const char *name; + enum v4l2_ctrl_type type; + s64 min; + u64 step; + s64 max = _max; + s64 def = _def; + u32 flags; + + v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags); + if (type != V4L2_CTRL_TYPE_INTEGER_MENU) { + handler_set_err(hdl, -EINVAL); + return NULL; + } + return v4l2_ctrl_new(hdl, ops, NULL, id, name, type, + 0, max, 0, def, NULL, 0, + flags, NULL, qmenu_int, ptr_null, NULL); +} +EXPORT_SYMBOL(v4l2_ctrl_new_int_menu); + +/* Add the controls from another handler to our own. */ +int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl, + struct v4l2_ctrl_handler *add, + bool (*filter)(const struct v4l2_ctrl *ctrl), + bool from_other_dev) +{ + struct v4l2_ctrl_ref *ref; + int ret = 0; + + /* Do nothing if either handler is NULL or if they are the same */ + if (!hdl || !add || hdl == add) + return 0; + if (hdl->error) + return hdl->error; + mutex_lock(add->lock); + list_for_each_entry(ref, &add->ctrl_refs, node) { + struct v4l2_ctrl *ctrl = ref->ctrl; + + /* Skip handler-private controls. */ + if (ctrl->is_private) + continue; + /* And control classes */ + if (ctrl->type == V4L2_CTRL_TYPE_CTRL_CLASS) + continue; + /* Filter any unwanted controls */ + if (filter && !filter(ctrl)) + continue; + ret = handler_new_ref(hdl, ctrl, NULL, from_other_dev, false); + if (ret) + break; + } + mutex_unlock(add->lock); + return ret; +} +EXPORT_SYMBOL(v4l2_ctrl_add_handler); + +bool v4l2_ctrl_radio_filter(const struct v4l2_ctrl *ctrl) +{ + if (V4L2_CTRL_ID2WHICH(ctrl->id) == V4L2_CTRL_CLASS_FM_TX) + return true; + if (V4L2_CTRL_ID2WHICH(ctrl->id) == V4L2_CTRL_CLASS_FM_RX) + return true; + switch (ctrl->id) { + case V4L2_CID_AUDIO_MUTE: + case V4L2_CID_AUDIO_VOLUME: + case V4L2_CID_AUDIO_BALANCE: + case V4L2_CID_AUDIO_BASS: + case V4L2_CID_AUDIO_TREBLE: + case V4L2_CID_AUDIO_LOUDNESS: + return true; + default: + break; + } + return false; +} +EXPORT_SYMBOL(v4l2_ctrl_radio_filter); + +/* Cluster controls */ +void v4l2_ctrl_cluster(unsigned ncontrols, struct v4l2_ctrl **controls) +{ + bool has_volatiles = false; + int i; + + /* The first control is the master control and it must not be NULL */ + if (WARN_ON(ncontrols == 0 || controls[0] == NULL)) + return; + + for (i = 0; i < ncontrols; i++) { + if (controls[i]) { + controls[i]->cluster = controls; + controls[i]->ncontrols = ncontrols; + if (controls[i]->flags & V4L2_CTRL_FLAG_VOLATILE) + has_volatiles = true; + } + } + controls[0]->has_volatiles = has_volatiles; +} +EXPORT_SYMBOL(v4l2_ctrl_cluster); + +void v4l2_ctrl_auto_cluster(unsigned ncontrols, struct v4l2_ctrl **controls, + u8 manual_val, bool set_volatile) +{ + struct v4l2_ctrl *master = controls[0]; + u32 flag = 0; + int i; + + v4l2_ctrl_cluster(ncontrols, controls); + WARN_ON(ncontrols <= 1); + WARN_ON(manual_val < master->minimum || manual_val > master->maximum); + WARN_ON(set_volatile && !has_op(master, g_volatile_ctrl)); + master->is_auto = true; + master->has_volatiles = set_volatile; + master->manual_mode_value = manual_val; + master->flags |= V4L2_CTRL_FLAG_UPDATE; + + if (!is_cur_manual(master)) + flag = V4L2_CTRL_FLAG_INACTIVE | + (set_volatile ? V4L2_CTRL_FLAG_VOLATILE : 0); + + for (i = 1; i < ncontrols; i++) + if (controls[i]) + controls[i]->flags |= flag; +} +EXPORT_SYMBOL(v4l2_ctrl_auto_cluster); + +/* + * Obtain the current volatile values of an autocluster and mark them + * as new. + */ +void update_from_auto_cluster(struct v4l2_ctrl *master) +{ + int i; + + for (i = 1; i < master->ncontrols; i++) + cur_to_new(master->cluster[i]); + if (!call_op(master, g_volatile_ctrl)) + for (i = 1; i < master->ncontrols; i++) + if (master->cluster[i]) + master->cluster[i]->is_new = 1; +} + +/* + * Return non-zero if one or more of the controls in the cluster has a new + * value that differs from the current value. + */ +static int cluster_changed(struct v4l2_ctrl *master) +{ + bool changed = false; + unsigned int idx; + int i; + + for (i = 0; i < master->ncontrols; i++) { + struct v4l2_ctrl *ctrl = master->cluster[i]; + bool ctrl_changed = false; + + if (!ctrl) + continue; + + if (ctrl->flags & V4L2_CTRL_FLAG_EXECUTE_ON_WRITE) { + changed = true; + ctrl_changed = true; + } + + /* + * Set has_changed to false to avoid generating + * the event V4L2_EVENT_CTRL_CH_VALUE + */ + if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) { + ctrl->has_changed = false; + continue; + } + + for (idx = 0; !ctrl_changed && idx < ctrl->elems; idx++) + ctrl_changed = !ctrl->type_ops->equal(ctrl, idx, + ctrl->p_cur, ctrl->p_new); + ctrl->has_changed = ctrl_changed; + changed |= ctrl->has_changed; + } + return changed; +} + +/* + * Core function that calls try/s_ctrl and ensures that the new value is + * copied to the current value on a set. + * Must be called with ctrl->handler->lock held. + */ +int try_or_set_cluster(struct v4l2_fh *fh, struct v4l2_ctrl *master, + bool set, u32 ch_flags) +{ + bool update_flag; + int ret; + int i; + + /* + * Go through the cluster and either validate the new value or + * (if no new value was set), copy the current value to the new + * value, ensuring a consistent view for the control ops when + * called. + */ + for (i = 0; i < master->ncontrols; i++) { + struct v4l2_ctrl *ctrl = master->cluster[i]; + + if (!ctrl) + continue; + + if (!ctrl->is_new) { + cur_to_new(ctrl); + continue; + } + /* + * Check again: it may have changed since the + * previous check in try_or_set_ext_ctrls(). + */ + if (set && (ctrl->flags & V4L2_CTRL_FLAG_GRABBED)) + return -EBUSY; + } + + ret = call_op(master, try_ctrl); + + /* Don't set if there is no change */ + if (ret || !set || !cluster_changed(master)) + return ret; + ret = call_op(master, s_ctrl); + if (ret) + return ret; + + /* If OK, then make the new values permanent. */ + update_flag = is_cur_manual(master) != is_new_manual(master); + + for (i = 0; i < master->ncontrols; i++) { + /* + * If we switch from auto to manual mode, and this cluster + * contains volatile controls, then all non-master controls + * have to be marked as changed. The 'new' value contains + * the volatile value (obtained by update_from_auto_cluster), + * which now has to become the current value. + */ + if (i && update_flag && is_new_manual(master) && + master->has_volatiles && master->cluster[i]) + master->cluster[i]->has_changed = true; + + new_to_cur(fh, master->cluster[i], ch_flags | + ((update_flag && i > 0) ? V4L2_EVENT_CTRL_CH_FLAGS : 0)); + } + return 0; +} + +/* Activate/deactivate a control. */ +void v4l2_ctrl_activate(struct v4l2_ctrl *ctrl, bool active) +{ + /* invert since the actual flag is called 'inactive' */ + bool inactive = !active; + bool old; + + if (ctrl == NULL) + return; + + if (inactive) + /* set V4L2_CTRL_FLAG_INACTIVE */ + old = test_and_set_bit(4, &ctrl->flags); + else + /* clear V4L2_CTRL_FLAG_INACTIVE */ + old = test_and_clear_bit(4, &ctrl->flags); + if (old != inactive) + send_event(NULL, ctrl, V4L2_EVENT_CTRL_CH_FLAGS); +} +EXPORT_SYMBOL(v4l2_ctrl_activate); + +void __v4l2_ctrl_grab(struct v4l2_ctrl *ctrl, bool grabbed) +{ + bool old; + + if (ctrl == NULL) + return; + + lockdep_assert_held(ctrl->handler->lock); + + if (grabbed) + /* set V4L2_CTRL_FLAG_GRABBED */ + old = test_and_set_bit(1, &ctrl->flags); + else + /* clear V4L2_CTRL_FLAG_GRABBED */ + old = test_and_clear_bit(1, &ctrl->flags); + if (old != grabbed) + send_event(NULL, ctrl, V4L2_EVENT_CTRL_CH_FLAGS); +} +EXPORT_SYMBOL(__v4l2_ctrl_grab); + +/* Call s_ctrl for all controls owned by the handler */ +int __v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl) +{ + struct v4l2_ctrl *ctrl; + int ret = 0; + + if (hdl == NULL) + return 0; + + lockdep_assert_held(hdl->lock); + + list_for_each_entry(ctrl, &hdl->ctrls, node) + ctrl->done = false; + + list_for_each_entry(ctrl, &hdl->ctrls, node) { + struct v4l2_ctrl *master = ctrl->cluster[0]; + int i; + + /* Skip if this control was already handled by a cluster. */ + /* Skip button controls and read-only controls. */ + if (ctrl->done || ctrl->type == V4L2_CTRL_TYPE_BUTTON || + (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY)) + continue; + + for (i = 0; i < master->ncontrols; i++) { + if (master->cluster[i]) { + cur_to_new(master->cluster[i]); + master->cluster[i]->is_new = 1; + master->cluster[i]->done = true; + } + } + ret = call_op(master, s_ctrl); + if (ret) + break; + } + + return ret; +} +EXPORT_SYMBOL_GPL(__v4l2_ctrl_handler_setup); + +int v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl) +{ + int ret; + + if (hdl == NULL) + return 0; + + mutex_lock(hdl->lock); + ret = __v4l2_ctrl_handler_setup(hdl); + mutex_unlock(hdl->lock); + + return ret; +} +EXPORT_SYMBOL(v4l2_ctrl_handler_setup); + +/* Log the control name and value */ +static void log_ctrl(const struct v4l2_ctrl *ctrl, + const char *prefix, const char *colon) +{ + if (ctrl->flags & (V4L2_CTRL_FLAG_DISABLED | V4L2_CTRL_FLAG_WRITE_ONLY)) + return; + if (ctrl->type == V4L2_CTRL_TYPE_CTRL_CLASS) + return; + + pr_info("%s%s%s: ", prefix, colon, ctrl->name); + + ctrl->type_ops->log(ctrl); + + if (ctrl->flags & (V4L2_CTRL_FLAG_INACTIVE | + V4L2_CTRL_FLAG_GRABBED | + V4L2_CTRL_FLAG_VOLATILE)) { + if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE) + pr_cont(" inactive"); + if (ctrl->flags & V4L2_CTRL_FLAG_GRABBED) + pr_cont(" grabbed"); + if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) + pr_cont(" volatile"); + } + pr_cont("\n"); +} + +/* Log all controls owned by the handler */ +void v4l2_ctrl_handler_log_status(struct v4l2_ctrl_handler *hdl, + const char *prefix) +{ + struct v4l2_ctrl *ctrl; + const char *colon = ""; + int len; + + if (!hdl) + return; + if (!prefix) + prefix = ""; + len = strlen(prefix); + if (len && prefix[len - 1] != ' ') + colon = ": "; + mutex_lock(hdl->lock); + list_for_each_entry(ctrl, &hdl->ctrls, node) + if (!(ctrl->flags & V4L2_CTRL_FLAG_DISABLED)) + log_ctrl(ctrl, prefix, colon); + mutex_unlock(hdl->lock); +} +EXPORT_SYMBOL(v4l2_ctrl_handler_log_status); + +int v4l2_ctrl_new_fwnode_properties(struct v4l2_ctrl_handler *hdl, + const struct v4l2_ctrl_ops *ctrl_ops, + const struct v4l2_fwnode_device_properties *p) +{ + if (p->orientation != V4L2_FWNODE_PROPERTY_UNSET) { + u32 orientation_ctrl; + + switch (p->orientation) { + case V4L2_FWNODE_ORIENTATION_FRONT: + orientation_ctrl = V4L2_CAMERA_ORIENTATION_FRONT; + break; + case V4L2_FWNODE_ORIENTATION_BACK: + orientation_ctrl = V4L2_CAMERA_ORIENTATION_BACK; + break; + case V4L2_FWNODE_ORIENTATION_EXTERNAL: + orientation_ctrl = V4L2_CAMERA_ORIENTATION_EXTERNAL; + break; + default: + return -EINVAL; + } + if (!v4l2_ctrl_new_std_menu(hdl, ctrl_ops, + V4L2_CID_CAMERA_ORIENTATION, + V4L2_CAMERA_ORIENTATION_EXTERNAL, 0, + orientation_ctrl)) + return hdl->error; + } + + if (p->rotation != V4L2_FWNODE_PROPERTY_UNSET) { + if (!v4l2_ctrl_new_std(hdl, ctrl_ops, + V4L2_CID_CAMERA_SENSOR_ROTATION, + p->rotation, p->rotation, 1, + p->rotation)) + return hdl->error; + } + + return hdl->error; +} +EXPORT_SYMBOL(v4l2_ctrl_new_fwnode_properties); diff --git a/drivers/media/v4l2-core/v4l2-ctrls-defs.c b/drivers/media/v4l2-core/v4l2-ctrls-defs.c new file mode 100644 index 000000000000..7963c7b43450 --- /dev/null +++ b/drivers/media/v4l2-core/v4l2-ctrls-defs.c @@ -0,0 +1,1575 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * V4L2 controls framework control definitions. + * + * Copyright (C) 2010-2021 Hans Verkuil + */ + +#include +#include + +/* + * Returns NULL or a character pointer array containing the menu for + * the given control ID. The pointer array ends with a NULL pointer. + * An empty string signifies a menu entry that is invalid. This allows + * drivers to disable certain options if it is not supported. + */ +const char * const *v4l2_ctrl_get_menu(u32 id) +{ + static const char * const mpeg_audio_sampling_freq[] = { + "44.1 kHz", + "48 kHz", + "32 kHz", + NULL + }; + static const char * const mpeg_audio_encoding[] = { + "MPEG-1/2 Layer I", + "MPEG-1/2 Layer II", + "MPEG-1/2 Layer III", + "MPEG-2/4 AAC", + "AC-3", + NULL + }; + static const char * const mpeg_audio_l1_bitrate[] = { + "32 kbps", + "64 kbps", + "96 kbps", + "128 kbps", + "160 kbps", + "192 kbps", + "224 kbps", + "256 kbps", + "288 kbps", + "320 kbps", + "352 kbps", + "384 kbps", + "416 kbps", + "448 kbps", + NULL + }; + static const char * const mpeg_audio_l2_bitrate[] = { + "32 kbps", + "48 kbps", + "56 kbps", + "64 kbps", + "80 kbps", + "96 kbps", + "112 kbps", + "128 kbps", + "160 kbps", + "192 kbps", + "224 kbps", + "256 kbps", + "320 kbps", + "384 kbps", + NULL + }; + static const char * const mpeg_audio_l3_bitrate[] = { + "32 kbps", + "40 kbps", + "48 kbps", + "56 kbps", + "64 kbps", + "80 kbps", + "96 kbps", + "112 kbps", + "128 kbps", + "160 kbps", + "192 kbps", + "224 kbps", + "256 kbps", + "320 kbps", + NULL + }; + static const char * const mpeg_audio_ac3_bitrate[] = { + "32 kbps", + "40 kbps", + "48 kbps", + "56 kbps", + "64 kbps", + "80 kbps", + "96 kbps", + "112 kbps", + "128 kbps", + "160 kbps", + "192 kbps", + "224 kbps", + "256 kbps", + "320 kbps", + "384 kbps", + "448 kbps", + "512 kbps", + "576 kbps", + "640 kbps", + NULL + }; + static const char * const mpeg_audio_mode[] = { + "Stereo", + "Joint Stereo", + "Dual", + "Mono", + NULL + }; + static const char * const mpeg_audio_mode_extension[] = { + "Bound 4", + "Bound 8", + "Bound 12", + "Bound 16", + NULL + }; + static const char * const mpeg_audio_emphasis[] = { + "No Emphasis", + "50/15 us", + "CCITT J17", + NULL + }; + static const char * const mpeg_audio_crc[] = { + "No CRC", + "16-bit CRC", + NULL + }; + static const char * const mpeg_audio_dec_playback[] = { + "Auto", + "Stereo", + "Left", + "Right", + "Mono", + "Swapped Stereo", + NULL + }; + static const char * const mpeg_video_encoding[] = { + "MPEG-1", + "MPEG-2", + "MPEG-4 AVC", + NULL + }; + static const char * const mpeg_video_aspect[] = { + "1x1", + "4x3", + "16x9", + "2.21x1", + NULL + }; + static const char * const mpeg_video_bitrate_mode[] = { + "Variable Bitrate", + "Constant Bitrate", + "Constant Quality", + NULL + }; + static const char * const mpeg_stream_type[] = { + "MPEG-2 Program Stream", + "MPEG-2 Transport Stream", + "MPEG-1 System Stream", + "MPEG-2 DVD-compatible Stream", + "MPEG-1 VCD-compatible Stream", + "MPEG-2 SVCD-compatible Stream", + NULL + }; + static const char * const mpeg_stream_vbi_fmt[] = { + "No VBI", + "Private Packet, IVTV Format", + NULL + }; + static const char * const camera_power_line_frequency[] = { + "Disabled", + "50 Hz", + "60 Hz", + "Auto", + NULL + }; + static const char * const camera_exposure_auto[] = { + "Auto Mode", + "Manual Mode", + "Shutter Priority Mode", + "Aperture Priority Mode", + NULL + }; + static const char * const camera_exposure_metering[] = { + "Average", + "Center Weighted", + "Spot", + "Matrix", + NULL + }; + static const char * const camera_auto_focus_range[] = { + "Auto", + "Normal", + "Macro", + "Infinity", + NULL + }; + static const char * const colorfx[] = { + "None", + "Black & White", + "Sepia", + "Negative", + "Emboss", + "Sketch", + "Sky Blue", + "Grass Green", + "Skin Whiten", + "Vivid", + "Aqua", + "Art Freeze", + "Silhouette", + "Solarization", + "Antique", + "Set Cb/Cr", + NULL + }; + static const char * const auto_n_preset_white_balance[] = { + "Manual", + "Auto", + "Incandescent", + "Fluorescent", + "Fluorescent H", + "Horizon", + "Daylight", + "Flash", + "Cloudy", + "Shade", + NULL, + }; + static const char * const camera_iso_sensitivity_auto[] = { + "Manual", + "Auto", + NULL + }; + static const char * const scene_mode[] = { + "None", + "Backlight", + "Beach/Snow", + "Candle Light", + "Dusk/Dawn", + "Fall Colors", + "Fireworks", + "Landscape", + "Night", + "Party/Indoor", + "Portrait", + "Sports", + "Sunset", + "Text", + NULL + }; + static const char * const tune_emphasis[] = { + "None", + "50 Microseconds", + "75 Microseconds", + NULL, + }; + static const char * const header_mode[] = { + "Separate Buffer", + "Joined With 1st Frame", + NULL, + }; + static const char * const multi_slice[] = { + "Single", + "Max Macroblocks", + "Max Bytes", + NULL, + }; + static const char * const entropy_mode[] = { + "CAVLC", + "CABAC", + NULL, + }; + static const char * const mpeg_h264_level[] = { + "1", + "1b", + "1.1", + "1.2", + "1.3", + "2", + "2.1", + "2.2", + "3", + "3.1", + "3.2", + "4", + "4.1", + "4.2", + "5", + "5.1", + "5.2", + "6.0", + "6.1", + "6.2", + NULL, + }; + static const char * const h264_loop_filter[] = { + "Enabled", + "Disabled", + "Disabled at Slice Boundary", + NULL, + }; + static const char * const h264_profile[] = { + "Baseline", + "Constrained Baseline", + "Main", + "Extended", + "High", + "High 10", + "High 422", + "High 444 Predictive", + "High 10 Intra", + "High 422 Intra", + "High 444 Intra", + "CAVLC 444 Intra", + "Scalable Baseline", + "Scalable High", + "Scalable High Intra", + "Stereo High", + "Multiview High", + "Constrained High", + NULL, + }; + static const char * const vui_sar_idc[] = { + "Unspecified", + "1:1", + "12:11", + "10:11", + "16:11", + "40:33", + "24:11", + "20:11", + "32:11", + "80:33", + "18:11", + "15:11", + "64:33", + "160:99", + "4:3", + "3:2", + "2:1", + "Extended SAR", + NULL, + }; + static const char * const h264_fp_arrangement_type[] = { + "Checkerboard", + "Column", + "Row", + "Side by Side", + "Top Bottom", + "Temporal", + NULL, + }; + static const char * const h264_fmo_map_type[] = { + "Interleaved Slices", + "Scattered Slices", + "Foreground with Leftover", + "Box Out", + "Raster Scan", + "Wipe Scan", + "Explicit", + NULL, + }; + static const char * const h264_decode_mode[] = { + "Slice-Based", + "Frame-Based", + NULL, + }; + static const char * const h264_start_code[] = { + "No Start Code", + "Annex B Start Code", + NULL, + }; + static const char * const h264_hierarchical_coding_type[] = { + "Hier Coding B", + "Hier Coding P", + NULL, + }; + static const char * const mpeg_mpeg2_level[] = { + "Low", + "Main", + "High 1440", + "High", + NULL, + }; + static const char * const mpeg2_profile[] = { + "Simple", + "Main", + "SNR Scalable", + "Spatially Scalable", + "High", + NULL, + }; + static const char * const mpeg_mpeg4_level[] = { + "0", + "0b", + "1", + "2", + "3", + "3b", + "4", + "5", + NULL, + }; + static const char * const mpeg4_profile[] = { + "Simple", + "Advanced Simple", + "Core", + "Simple Scalable", + "Advanced Coding Efficiency", + NULL, + }; + + static const char * const vpx_golden_frame_sel[] = { + "Use Previous Frame", + "Use Previous Specific Frame", + NULL, + }; + static const char * const vp8_profile[] = { + "0", + "1", + "2", + "3", + NULL, + }; + static const char * const vp9_profile[] = { + "0", + "1", + "2", + "3", + NULL, + }; + static const char * const vp9_level[] = { + "1", + "1.1", + "2", + "2.1", + "3", + "3.1", + "4", + "4.1", + "5", + "5.1", + "5.2", + "6", + "6.1", + "6.2", + NULL, + }; + + static const char * const flash_led_mode[] = { + "Off", + "Flash", + "Torch", + NULL, + }; + static const char * const flash_strobe_source[] = { + "Software", + "External", + NULL, + }; + + static const char * const jpeg_chroma_subsampling[] = { + "4:4:4", + "4:2:2", + "4:2:0", + "4:1:1", + "4:1:0", + "Gray", + NULL, + }; + static const char * const dv_tx_mode[] = { + "DVI-D", + "HDMI", + NULL, + }; + static const char * const dv_rgb_range[] = { + "Automatic", + "RGB Limited Range (16-235)", + "RGB Full Range (0-255)", + NULL, + }; + static const char * const dv_it_content_type[] = { + "Graphics", + "Photo", + "Cinema", + "Game", + "No IT Content", + NULL, + }; + static const char * const detect_md_mode[] = { + "Disabled", + "Global", + "Threshold Grid", + "Region Grid", + NULL, + }; + + static const char * const hevc_profile[] = { + "Main", + "Main Still Picture", + "Main 10", + NULL, + }; + static const char * const hevc_level[] = { + "1", + "2", + "2.1", + "3", + "3.1", + "4", + "4.1", + "5", + "5.1", + "5.2", + "6", + "6.1", + "6.2", + NULL, + }; + static const char * const hevc_hierarchial_coding_type[] = { + "B", + "P", + NULL, + }; + static const char * const hevc_refresh_type[] = { + "None", + "CRA", + "IDR", + NULL, + }; + static const char * const hevc_size_of_length_field[] = { + "0", + "1", + "2", + "4", + NULL, + }; + static const char * const hevc_tier[] = { + "Main", + "High", + NULL, + }; + static const char * const hevc_loop_filter_mode[] = { + "Disabled", + "Enabled", + "Disabled at slice boundary", + "NULL", + }; + static const char * const hevc_decode_mode[] = { + "Slice-Based", + "Frame-Based", + NULL, + }; + static const char * const hevc_start_code[] = { + "No Start Code", + "Annex B Start Code", + NULL, + }; + static const char * const camera_orientation[] = { + "Front", + "Back", + "External", + NULL, + }; + static const char * const mpeg_video_frame_skip[] = { + "Disabled", + "Level Limit", + "VBV/CPB Limit", + NULL, + }; + + switch (id) { + case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: + return mpeg_audio_sampling_freq; + case V4L2_CID_MPEG_AUDIO_ENCODING: + return mpeg_audio_encoding; + case V4L2_CID_MPEG_AUDIO_L1_BITRATE: + return mpeg_audio_l1_bitrate; + case V4L2_CID_MPEG_AUDIO_L2_BITRATE: + return mpeg_audio_l2_bitrate; + case V4L2_CID_MPEG_AUDIO_L3_BITRATE: + return mpeg_audio_l3_bitrate; + case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: + return mpeg_audio_ac3_bitrate; + case V4L2_CID_MPEG_AUDIO_MODE: + return mpeg_audio_mode; + case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: + return mpeg_audio_mode_extension; + case V4L2_CID_MPEG_AUDIO_EMPHASIS: + return mpeg_audio_emphasis; + case V4L2_CID_MPEG_AUDIO_CRC: + return mpeg_audio_crc; + case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK: + case V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK: + return mpeg_audio_dec_playback; + case V4L2_CID_MPEG_VIDEO_ENCODING: + return mpeg_video_encoding; + case V4L2_CID_MPEG_VIDEO_ASPECT: + return mpeg_video_aspect; + case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: + return mpeg_video_bitrate_mode; + case V4L2_CID_MPEG_STREAM_TYPE: + return mpeg_stream_type; + case V4L2_CID_MPEG_STREAM_VBI_FMT: + return mpeg_stream_vbi_fmt; + case V4L2_CID_POWER_LINE_FREQUENCY: + return camera_power_line_frequency; + case V4L2_CID_EXPOSURE_AUTO: + return camera_exposure_auto; + case V4L2_CID_EXPOSURE_METERING: + return camera_exposure_metering; + case V4L2_CID_AUTO_FOCUS_RANGE: + return camera_auto_focus_range; + case V4L2_CID_COLORFX: + return colorfx; + case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE: + return auto_n_preset_white_balance; + case V4L2_CID_ISO_SENSITIVITY_AUTO: + return camera_iso_sensitivity_auto; + case V4L2_CID_SCENE_MODE: + return scene_mode; + case V4L2_CID_TUNE_PREEMPHASIS: + return tune_emphasis; + case V4L2_CID_TUNE_DEEMPHASIS: + return tune_emphasis; + case V4L2_CID_FLASH_LED_MODE: + return flash_led_mode; + case V4L2_CID_FLASH_STROBE_SOURCE: + return flash_strobe_source; + case V4L2_CID_MPEG_VIDEO_HEADER_MODE: + return header_mode; + case V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE: + return mpeg_video_frame_skip; + case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: + return multi_slice; + case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: + return entropy_mode; + case V4L2_CID_MPEG_VIDEO_H264_LEVEL: + return mpeg_h264_level; + case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE: + return h264_loop_filter; + case V4L2_CID_MPEG_VIDEO_H264_PROFILE: + return h264_profile; + case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC: + return vui_sar_idc; + case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE: + return h264_fp_arrangement_type; + case V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE: + return h264_fmo_map_type; + case V4L2_CID_STATELESS_H264_DECODE_MODE: + return h264_decode_mode; + case V4L2_CID_STATELESS_H264_START_CODE: + return h264_start_code; + case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE: + return h264_hierarchical_coding_type; + case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL: + return mpeg_mpeg2_level; + case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE: + return mpeg2_profile; + case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: + return mpeg_mpeg4_level; + case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: + return mpeg4_profile; + case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL: + return vpx_golden_frame_sel; + case V4L2_CID_MPEG_VIDEO_VP8_PROFILE: + return vp8_profile; + case V4L2_CID_MPEG_VIDEO_VP9_PROFILE: + return vp9_profile; + case V4L2_CID_MPEG_VIDEO_VP9_LEVEL: + return vp9_level; + case V4L2_CID_JPEG_CHROMA_SUBSAMPLING: + return jpeg_chroma_subsampling; + case V4L2_CID_DV_TX_MODE: + return dv_tx_mode; + case V4L2_CID_DV_TX_RGB_RANGE: + case V4L2_CID_DV_RX_RGB_RANGE: + return dv_rgb_range; + case V4L2_CID_DV_TX_IT_CONTENT_TYPE: + case V4L2_CID_DV_RX_IT_CONTENT_TYPE: + return dv_it_content_type; + case V4L2_CID_DETECT_MD_MODE: + return detect_md_mode; + case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: + return hevc_profile; + case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: + return hevc_level; + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE: + return hevc_hierarchial_coding_type; + case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE: + return hevc_refresh_type; + case V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD: + return hevc_size_of_length_field; + case V4L2_CID_MPEG_VIDEO_HEVC_TIER: + return hevc_tier; + case V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE: + return hevc_loop_filter_mode; + case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE: + return hevc_decode_mode; + case V4L2_CID_MPEG_VIDEO_HEVC_START_CODE: + return hevc_start_code; + case V4L2_CID_CAMERA_ORIENTATION: + return camera_orientation; + default: + return NULL; + } +} +EXPORT_SYMBOL(v4l2_ctrl_get_menu); + +#define __v4l2_qmenu_int_len(arr, len) ({ *(len) = ARRAY_SIZE(arr); (arr); }) +/* + * Returns NULL or an s64 type array containing the menu for given + * control ID. The total number of the menu items is returned in @len. + */ +const s64 *v4l2_ctrl_get_int_menu(u32 id, u32 *len) +{ + static const s64 qmenu_int_vpx_num_partitions[] = { + 1, 2, 4, 8, + }; + + static const s64 qmenu_int_vpx_num_ref_frames[] = { + 1, 2, 3, + }; + + switch (id) { + case V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS: + return __v4l2_qmenu_int_len(qmenu_int_vpx_num_partitions, len); + case V4L2_CID_MPEG_VIDEO_VPX_NUM_REF_FRAMES: + return __v4l2_qmenu_int_len(qmenu_int_vpx_num_ref_frames, len); + default: + *len = 0; + return NULL; + } +} +EXPORT_SYMBOL(v4l2_ctrl_get_int_menu); + +/* Return the control name. */ +const char *v4l2_ctrl_get_name(u32 id) +{ + switch (id) { + /* USER controls */ + /* Keep the order of the 'case's the same as in v4l2-controls.h! */ + case V4L2_CID_USER_CLASS: return "User Controls"; + case V4L2_CID_BRIGHTNESS: return "Brightness"; + case V4L2_CID_CONTRAST: return "Contrast"; + case V4L2_CID_SATURATION: return "Saturation"; + case V4L2_CID_HUE: return "Hue"; + case V4L2_CID_AUDIO_VOLUME: return "Volume"; + case V4L2_CID_AUDIO_BALANCE: return "Balance"; + case V4L2_CID_AUDIO_BASS: return "Bass"; + case V4L2_CID_AUDIO_TREBLE: return "Treble"; + case V4L2_CID_AUDIO_MUTE: return "Mute"; + case V4L2_CID_AUDIO_LOUDNESS: return "Loudness"; + case V4L2_CID_BLACK_LEVEL: return "Black Level"; + case V4L2_CID_AUTO_WHITE_BALANCE: return "White Balance, Automatic"; + case V4L2_CID_DO_WHITE_BALANCE: return "Do White Balance"; + case V4L2_CID_RED_BALANCE: return "Red Balance"; + case V4L2_CID_BLUE_BALANCE: return "Blue Balance"; + case V4L2_CID_GAMMA: return "Gamma"; + case V4L2_CID_EXPOSURE: return "Exposure"; + case V4L2_CID_AUTOGAIN: return "Gain, Automatic"; + case V4L2_CID_GAIN: return "Gain"; + case V4L2_CID_HFLIP: return "Horizontal Flip"; + case V4L2_CID_VFLIP: return "Vertical Flip"; + case V4L2_CID_POWER_LINE_FREQUENCY: return "Power Line Frequency"; + case V4L2_CID_HUE_AUTO: return "Hue, Automatic"; + case V4L2_CID_WHITE_BALANCE_TEMPERATURE: return "White Balance Temperature"; + case V4L2_CID_SHARPNESS: return "Sharpness"; + case V4L2_CID_BACKLIGHT_COMPENSATION: return "Backlight Compensation"; + case V4L2_CID_CHROMA_AGC: return "Chroma AGC"; + case V4L2_CID_COLOR_KILLER: return "Color Killer"; + case V4L2_CID_COLORFX: return "Color Effects"; + case V4L2_CID_AUTOBRIGHTNESS: return "Brightness, Automatic"; + case V4L2_CID_BAND_STOP_FILTER: return "Band-Stop Filter"; + case V4L2_CID_ROTATE: return "Rotate"; + case V4L2_CID_BG_COLOR: return "Background Color"; + case V4L2_CID_CHROMA_GAIN: return "Chroma Gain"; + case V4L2_CID_ILLUMINATORS_1: return "Illuminator 1"; + case V4L2_CID_ILLUMINATORS_2: return "Illuminator 2"; + case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: return "Min Number of Capture Buffers"; + case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: return "Min Number of Output Buffers"; + case V4L2_CID_ALPHA_COMPONENT: return "Alpha Component"; + case V4L2_CID_COLORFX_CBCR: return "Color Effects, CbCr"; + + /* + * Codec controls + * + * The MPEG controls are applicable to all codec controls + * and the 'MPEG' part of the define is historical. + * + * Keep the order of the 'case's the same as in videodev2.h! + */ + case V4L2_CID_CODEC_CLASS: return "Codec Controls"; + case V4L2_CID_MPEG_STREAM_TYPE: return "Stream Type"; + case V4L2_CID_MPEG_STREAM_PID_PMT: return "Stream PMT Program ID"; + case V4L2_CID_MPEG_STREAM_PID_AUDIO: return "Stream Audio Program ID"; + case V4L2_CID_MPEG_STREAM_PID_VIDEO: return "Stream Video Program ID"; + case V4L2_CID_MPEG_STREAM_PID_PCR: return "Stream PCR Program ID"; + case V4L2_CID_MPEG_STREAM_PES_ID_AUDIO: return "Stream PES Audio ID"; + case V4L2_CID_MPEG_STREAM_PES_ID_VIDEO: return "Stream PES Video ID"; + case V4L2_CID_MPEG_STREAM_VBI_FMT: return "Stream VBI Format"; + case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: return "Audio Sampling Frequency"; + case V4L2_CID_MPEG_AUDIO_ENCODING: return "Audio Encoding"; + case V4L2_CID_MPEG_AUDIO_L1_BITRATE: return "Audio Layer I Bitrate"; + case V4L2_CID_MPEG_AUDIO_L2_BITRATE: return "Audio Layer II Bitrate"; + case V4L2_CID_MPEG_AUDIO_L3_BITRATE: return "Audio Layer III Bitrate"; + case V4L2_CID_MPEG_AUDIO_MODE: return "Audio Stereo Mode"; + case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: return "Audio Stereo Mode Extension"; + case V4L2_CID_MPEG_AUDIO_EMPHASIS: return "Audio Emphasis"; + case V4L2_CID_MPEG_AUDIO_CRC: return "Audio CRC"; + case V4L2_CID_MPEG_AUDIO_MUTE: return "Audio Mute"; + case V4L2_CID_MPEG_AUDIO_AAC_BITRATE: return "Audio AAC Bitrate"; + case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: return "Audio AC-3 Bitrate"; + case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK: return "Audio Playback"; + case V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK: return "Audio Multilingual Playback"; + case V4L2_CID_MPEG_VIDEO_ENCODING: return "Video Encoding"; + case V4L2_CID_MPEG_VIDEO_ASPECT: return "Video Aspect"; + case V4L2_CID_MPEG_VIDEO_B_FRAMES: return "Video B Frames"; + case V4L2_CID_MPEG_VIDEO_GOP_SIZE: return "Video GOP Size"; + case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: return "Video GOP Closure"; + case V4L2_CID_MPEG_VIDEO_PULLDOWN: return "Video Pulldown"; + case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: return "Video Bitrate Mode"; + case V4L2_CID_MPEG_VIDEO_CONSTANT_QUALITY: return "Constant Quality"; + case V4L2_CID_MPEG_VIDEO_BITRATE: return "Video Bitrate"; + case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: return "Video Peak Bitrate"; + case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION: return "Video Temporal Decimation"; + case V4L2_CID_MPEG_VIDEO_MUTE: return "Video Mute"; + case V4L2_CID_MPEG_VIDEO_MUTE_YUV: return "Video Mute YUV"; + case V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE: return "Decoder Slice Interface"; + case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER: return "MPEG4 Loop Filter Enable"; + case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB: return "Number of Intra Refresh MBs"; + case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE: return "Frame Level Rate Control Enable"; + case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE: return "H264 MB Level Rate Control"; + case V4L2_CID_MPEG_VIDEO_HEADER_MODE: return "Sequence Header Mode"; + case V4L2_CID_MPEG_VIDEO_MAX_REF_PIC: return "Max Number of Reference Pics"; + case V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE: return "Frame Skip Mode"; + case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY: return "Display Delay"; + case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY_ENABLE: return "Display Delay Enable"; + case V4L2_CID_MPEG_VIDEO_AU_DELIMITER: return "Generate Access Unit Delimiters"; + case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP: return "H263 I-Frame QP Value"; + case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP: return "H263 P-Frame QP Value"; + case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP: return "H263 B-Frame QP Value"; + case V4L2_CID_MPEG_VIDEO_H263_MIN_QP: return "H263 Minimum QP Value"; + case V4L2_CID_MPEG_VIDEO_H263_MAX_QP: return "H263 Maximum QP Value"; + case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP: return "H264 I-Frame QP Value"; + case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP: return "H264 P-Frame QP Value"; + case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP: return "H264 B-Frame QP Value"; + case V4L2_CID_MPEG_VIDEO_H264_MAX_QP: return "H264 Maximum QP Value"; + case V4L2_CID_MPEG_VIDEO_H264_MIN_QP: return "H264 Minimum QP Value"; + case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM: return "H264 8x8 Transform Enable"; + case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE: return "H264 CPB Buffer Size"; + case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: return "H264 Entropy Mode"; + case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD: return "H264 I-Frame Period"; + case V4L2_CID_MPEG_VIDEO_H264_LEVEL: return "H264 Level"; + case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA: return "H264 Loop Filter Alpha Offset"; + case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA: return "H264 Loop Filter Beta Offset"; + case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE: return "H264 Loop Filter Mode"; + case V4L2_CID_MPEG_VIDEO_H264_PROFILE: return "H264 Profile"; + case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT: return "Vertical Size of SAR"; + case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH: return "Horizontal Size of SAR"; + case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE: return "Aspect Ratio VUI Enable"; + case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC: return "VUI Aspect Ratio IDC"; + case V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING: return "H264 Enable Frame Packing SEI"; + case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_CURRENT_FRAME_0: return "H264 Set Curr. Frame as Frame0"; + case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE: return "H264 FP Arrangement Type"; + case V4L2_CID_MPEG_VIDEO_H264_FMO: return "H264 Flexible MB Ordering"; + case V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE: return "H264 Map Type for FMO"; + case V4L2_CID_MPEG_VIDEO_H264_FMO_SLICE_GROUP: return "H264 FMO Number of Slice Groups"; + case V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_DIRECTION: return "H264 FMO Direction of Change"; + case V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_RATE: return "H264 FMO Size of 1st Slice Grp"; + case V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH: return "H264 FMO No. of Consecutive MBs"; + case V4L2_CID_MPEG_VIDEO_H264_ASO: return "H264 Arbitrary Slice Ordering"; + case V4L2_CID_MPEG_VIDEO_H264_ASO_SLICE_ORDER: return "H264 ASO Slice Order"; + case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING: return "Enable H264 Hierarchical Coding"; + case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE: return "H264 Hierarchical Coding Type"; + case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER:return "H264 Number of HC Layers"; + case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP: + return "H264 Set QP Value for HC Layers"; + case V4L2_CID_MPEG_VIDEO_H264_CONSTRAINED_INTRA_PREDICTION: + return "H264 Constrained Intra Pred"; + case V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET: return "H264 Chroma QP Index Offset"; + case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP: return "H264 I-Frame Minimum QP Value"; + case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP: return "H264 I-Frame Maximum QP Value"; + case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP: return "H264 P-Frame Minimum QP Value"; + case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP: return "H264 P-Frame Maximum QP Value"; + case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MIN_QP: return "H264 B-Frame Minimum QP Value"; + case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MAX_QP: return "H264 B-Frame Maximum QP Value"; + case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L0_BR: return "H264 Hierarchical Lay 0 Bitrate"; + case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L1_BR: return "H264 Hierarchical Lay 1 Bitrate"; + case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L2_BR: return "H264 Hierarchical Lay 2 Bitrate"; + case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L3_BR: return "H264 Hierarchical Lay 3 Bitrate"; + case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L4_BR: return "H264 Hierarchical Lay 4 Bitrate"; + case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L5_BR: return "H264 Hierarchical Lay 5 Bitrate"; + case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L6_BR: return "H264 Hierarchical Lay 6 Bitrate"; + case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL: return "MPEG2 Level"; + case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE: return "MPEG2 Profile"; + case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP: return "MPEG4 I-Frame QP Value"; + case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP: return "MPEG4 P-Frame QP Value"; + case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP: return "MPEG4 B-Frame QP Value"; + case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP: return "MPEG4 Minimum QP Value"; + case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP: return "MPEG4 Maximum QP Value"; + case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: return "MPEG4 Level"; + case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: return "MPEG4 Profile"; + case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL: return "Quarter Pixel Search Enable"; + case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES: return "Maximum Bytes in a Slice"; + case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB: return "Number of MBs in a Slice"; + case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: return "Slice Partitioning Method"; + case V4L2_CID_MPEG_VIDEO_VBV_SIZE: return "VBV Buffer Size"; + case V4L2_CID_MPEG_VIDEO_DEC_PTS: return "Video Decoder PTS"; + case V4L2_CID_MPEG_VIDEO_DEC_FRAME: return "Video Decoder Frame Count"; + case V4L2_CID_MPEG_VIDEO_DEC_CONCEAL_COLOR: return "Video Decoder Conceal Color"; + case V4L2_CID_MPEG_VIDEO_VBV_DELAY: return "Initial Delay for VBV Control"; + case V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE: return "Horizontal MV Search Range"; + case V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE: return "Vertical MV Search Range"; + case V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER: return "Repeat Sequence Header"; + case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME: return "Force Key Frame"; + case V4L2_CID_MPEG_VIDEO_BASELAYER_PRIORITY_ID: return "Base Layer Priority ID"; + case V4L2_CID_MPEG_VIDEO_LTR_COUNT: return "LTR Count"; + case V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX: return "Frame LTR Index"; + case V4L2_CID_MPEG_VIDEO_USE_LTR_FRAMES: return "Use LTR Frames"; + case V4L2_CID_FWHT_I_FRAME_QP: return "FWHT I-Frame QP Value"; + case V4L2_CID_FWHT_P_FRAME_QP: return "FWHT P-Frame QP Value"; + + /* VPX controls */ + case V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS: return "VPX Number of Partitions"; + case V4L2_CID_MPEG_VIDEO_VPX_IMD_DISABLE_4X4: return "VPX Intra Mode Decision Disable"; + case V4L2_CID_MPEG_VIDEO_VPX_NUM_REF_FRAMES: return "VPX No. of Refs for P Frame"; + case V4L2_CID_MPEG_VIDEO_VPX_FILTER_LEVEL: return "VPX Loop Filter Level Range"; + case V4L2_CID_MPEG_VIDEO_VPX_FILTER_SHARPNESS: return "VPX Deblocking Effect Control"; + case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_REF_PERIOD: return "VPX Golden Frame Refresh Period"; + case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL: return "VPX Golden Frame Indicator"; + case V4L2_CID_MPEG_VIDEO_VPX_MIN_QP: return "VPX Minimum QP Value"; + case V4L2_CID_MPEG_VIDEO_VPX_MAX_QP: return "VPX Maximum QP Value"; + case V4L2_CID_MPEG_VIDEO_VPX_I_FRAME_QP: return "VPX I-Frame QP Value"; + case V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP: return "VPX P-Frame QP Value"; + case V4L2_CID_MPEG_VIDEO_VP8_PROFILE: return "VP8 Profile"; + case V4L2_CID_MPEG_VIDEO_VP9_PROFILE: return "VP9 Profile"; + case V4L2_CID_MPEG_VIDEO_VP9_LEVEL: return "VP9 Level"; + + /* HEVC controls */ + case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP: return "HEVC I-Frame QP Value"; + case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP: return "HEVC P-Frame QP Value"; + case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP: return "HEVC B-Frame QP Value"; + case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP: return "HEVC Minimum QP Value"; + case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP: return "HEVC Maximum QP Value"; + case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MIN_QP: return "HEVC I-Frame Minimum QP Value"; + case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MAX_QP: return "HEVC I-Frame Maximum QP Value"; + case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MIN_QP: return "HEVC P-Frame Minimum QP Value"; + case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MAX_QP: return "HEVC P-Frame Maximum QP Value"; + case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MIN_QP: return "HEVC B-Frame Minimum QP Value"; + case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MAX_QP: return "HEVC B-Frame Maximum QP Value"; + case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: return "HEVC Profile"; + case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: return "HEVC Level"; + case V4L2_CID_MPEG_VIDEO_HEVC_TIER: return "HEVC Tier"; + case V4L2_CID_MPEG_VIDEO_HEVC_FRAME_RATE_RESOLUTION: return "HEVC Frame Rate Resolution"; + case V4L2_CID_MPEG_VIDEO_HEVC_MAX_PARTITION_DEPTH: return "HEVC Maximum Coding Unit Depth"; + case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE: return "HEVC Refresh Type"; + case V4L2_CID_MPEG_VIDEO_HEVC_CONST_INTRA_PRED: return "HEVC Constant Intra Prediction"; + case V4L2_CID_MPEG_VIDEO_HEVC_LOSSLESS_CU: return "HEVC Lossless Encoding"; + case V4L2_CID_MPEG_VIDEO_HEVC_WAVEFRONT: return "HEVC Wavefront"; + case V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE: return "HEVC Loop Filter"; + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_QP: return "HEVC QP Values"; + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE: return "HEVC Hierarchical Coding Type"; + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER: return "HEVC Hierarchical Coding Layer"; + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_QP: return "HEVC Hierarchical Layer 0 QP"; + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_QP: return "HEVC Hierarchical Layer 1 QP"; + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_QP: return "HEVC Hierarchical Layer 2 QP"; + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_QP: return "HEVC Hierarchical Layer 3 QP"; + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_QP: return "HEVC Hierarchical Layer 4 QP"; + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_QP: return "HEVC Hierarchical Layer 5 QP"; + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_QP: return "HEVC Hierarchical Layer 6 QP"; + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_BR: return "HEVC Hierarchical Lay 0 BitRate"; + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_BR: return "HEVC Hierarchical Lay 1 BitRate"; + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_BR: return "HEVC Hierarchical Lay 2 BitRate"; + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_BR: return "HEVC Hierarchical Lay 3 BitRate"; + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_BR: return "HEVC Hierarchical Lay 4 BitRate"; + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR: return "HEVC Hierarchical Lay 5 BitRate"; + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_BR: return "HEVC Hierarchical Lay 6 BitRate"; + case V4L2_CID_MPEG_VIDEO_HEVC_GENERAL_PB: return "HEVC General PB"; + case V4L2_CID_MPEG_VIDEO_HEVC_TEMPORAL_ID: return "HEVC Temporal ID"; + case V4L2_CID_MPEG_VIDEO_HEVC_STRONG_SMOOTHING: return "HEVC Strong Intra Smoothing"; + case V4L2_CID_MPEG_VIDEO_HEVC_INTRA_PU_SPLIT: return "HEVC Intra PU Split"; + case V4L2_CID_MPEG_VIDEO_HEVC_TMV_PREDICTION: return "HEVC TMV Prediction"; + case V4L2_CID_MPEG_VIDEO_HEVC_MAX_NUM_MERGE_MV_MINUS1: return "HEVC Max Num of Candidate MVs"; + case V4L2_CID_MPEG_VIDEO_HEVC_WITHOUT_STARTCODE: return "HEVC ENC Without Startcode"; + case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_PERIOD: return "HEVC Num of I-Frame b/w 2 IDR"; + case V4L2_CID_MPEG_VIDEO_HEVC_LF_BETA_OFFSET_DIV2: return "HEVC Loop Filter Beta Offset"; + case V4L2_CID_MPEG_VIDEO_HEVC_LF_TC_OFFSET_DIV2: return "HEVC Loop Filter TC Offset"; + case V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD: return "HEVC Size of Length Field"; + case V4L2_CID_MPEG_VIDEO_REF_NUMBER_FOR_PFRAMES: return "Reference Frames for a P-Frame"; + case V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR: return "Prepend SPS and PPS to IDR"; + case V4L2_CID_MPEG_VIDEO_HEVC_SPS: return "HEVC Sequence Parameter Set"; + case V4L2_CID_MPEG_VIDEO_HEVC_PPS: return "HEVC Picture Parameter Set"; + case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS: return "HEVC Slice Parameters"; + case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE: return "HEVC Decode Mode"; + case V4L2_CID_MPEG_VIDEO_HEVC_START_CODE: return "HEVC Start Code"; + + /* CAMERA controls */ + /* Keep the order of the 'case's the same as in v4l2-controls.h! */ + case V4L2_CID_CAMERA_CLASS: return "Camera Controls"; + case V4L2_CID_EXPOSURE_AUTO: return "Auto Exposure"; + case V4L2_CID_EXPOSURE_ABSOLUTE: return "Exposure Time, Absolute"; + case V4L2_CID_EXPOSURE_AUTO_PRIORITY: return "Exposure, Dynamic Framerate"; + case V4L2_CID_PAN_RELATIVE: return "Pan, Relative"; + case V4L2_CID_TILT_RELATIVE: return "Tilt, Relative"; + case V4L2_CID_PAN_RESET: return "Pan, Reset"; + case V4L2_CID_TILT_RESET: return "Tilt, Reset"; + case V4L2_CID_PAN_ABSOLUTE: return "Pan, Absolute"; + case V4L2_CID_TILT_ABSOLUTE: return "Tilt, Absolute"; + case V4L2_CID_FOCUS_ABSOLUTE: return "Focus, Absolute"; + case V4L2_CID_FOCUS_RELATIVE: return "Focus, Relative"; + case V4L2_CID_FOCUS_AUTO: return "Focus, Automatic Continuous"; + case V4L2_CID_ZOOM_ABSOLUTE: return "Zoom, Absolute"; + case V4L2_CID_ZOOM_RELATIVE: return "Zoom, Relative"; + case V4L2_CID_ZOOM_CONTINUOUS: return "Zoom, Continuous"; + case V4L2_CID_PRIVACY: return "Privacy"; + case V4L2_CID_IRIS_ABSOLUTE: return "Iris, Absolute"; + case V4L2_CID_IRIS_RELATIVE: return "Iris, Relative"; + case V4L2_CID_AUTO_EXPOSURE_BIAS: return "Auto Exposure, Bias"; + case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE: return "White Balance, Auto & Preset"; + case V4L2_CID_WIDE_DYNAMIC_RANGE: return "Wide Dynamic Range"; + case V4L2_CID_IMAGE_STABILIZATION: return "Image Stabilization"; + case V4L2_CID_ISO_SENSITIVITY: return "ISO Sensitivity"; + case V4L2_CID_ISO_SENSITIVITY_AUTO: return "ISO Sensitivity, Auto"; + case V4L2_CID_EXPOSURE_METERING: return "Exposure, Metering Mode"; + case V4L2_CID_SCENE_MODE: return "Scene Mode"; + case V4L2_CID_3A_LOCK: return "3A Lock"; + case V4L2_CID_AUTO_FOCUS_START: return "Auto Focus, Start"; + case V4L2_CID_AUTO_FOCUS_STOP: return "Auto Focus, Stop"; + case V4L2_CID_AUTO_FOCUS_STATUS: return "Auto Focus, Status"; + case V4L2_CID_AUTO_FOCUS_RANGE: return "Auto Focus, Range"; + case V4L2_CID_PAN_SPEED: return "Pan, Speed"; + case V4L2_CID_TILT_SPEED: return "Tilt, Speed"; + case V4L2_CID_UNIT_CELL_SIZE: return "Unit Cell Size"; + case V4L2_CID_CAMERA_ORIENTATION: return "Camera Orientation"; + case V4L2_CID_CAMERA_SENSOR_ROTATION: return "Camera Sensor Rotation"; + + /* FM Radio Modulator controls */ + /* Keep the order of the 'case's the same as in v4l2-controls.h! */ + case V4L2_CID_FM_TX_CLASS: return "FM Radio Modulator Controls"; + case V4L2_CID_RDS_TX_DEVIATION: return "RDS Signal Deviation"; + case V4L2_CID_RDS_TX_PI: return "RDS Program ID"; + case V4L2_CID_RDS_TX_PTY: return "RDS Program Type"; + case V4L2_CID_RDS_TX_PS_NAME: return "RDS PS Name"; + case V4L2_CID_RDS_TX_RADIO_TEXT: return "RDS Radio Text"; + case V4L2_CID_RDS_TX_MONO_STEREO: return "RDS Stereo"; + case V4L2_CID_RDS_TX_ARTIFICIAL_HEAD: return "RDS Artificial Head"; + case V4L2_CID_RDS_TX_COMPRESSED: return "RDS Compressed"; + case V4L2_CID_RDS_TX_DYNAMIC_PTY: return "RDS Dynamic PTY"; + case V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT: return "RDS Traffic Announcement"; + case V4L2_CID_RDS_TX_TRAFFIC_PROGRAM: return "RDS Traffic Program"; + case V4L2_CID_RDS_TX_MUSIC_SPEECH: return "RDS Music"; + case V4L2_CID_RDS_TX_ALT_FREQS_ENABLE: return "RDS Enable Alt Frequencies"; + case V4L2_CID_RDS_TX_ALT_FREQS: return "RDS Alternate Frequencies"; + case V4L2_CID_AUDIO_LIMITER_ENABLED: return "Audio Limiter Feature Enabled"; + case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME: return "Audio Limiter Release Time"; + case V4L2_CID_AUDIO_LIMITER_DEVIATION: return "Audio Limiter Deviation"; + case V4L2_CID_AUDIO_COMPRESSION_ENABLED: return "Audio Compression Enabled"; + case V4L2_CID_AUDIO_COMPRESSION_GAIN: return "Audio Compression Gain"; + case V4L2_CID_AUDIO_COMPRESSION_THRESHOLD: return "Audio Compression Threshold"; + case V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME: return "Audio Compression Attack Time"; + case V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME: return "Audio Compression Release Time"; + case V4L2_CID_PILOT_TONE_ENABLED: return "Pilot Tone Feature Enabled"; + case V4L2_CID_PILOT_TONE_DEVIATION: return "Pilot Tone Deviation"; + case V4L2_CID_PILOT_TONE_FREQUENCY: return "Pilot Tone Frequency"; + case V4L2_CID_TUNE_PREEMPHASIS: return "Pre-Emphasis"; + case V4L2_CID_TUNE_POWER_LEVEL: return "Tune Power Level"; + case V4L2_CID_TUNE_ANTENNA_CAPACITOR: return "Tune Antenna Capacitor"; + + /* Flash controls */ + /* Keep the order of the 'case's the same as in v4l2-controls.h! */ + case V4L2_CID_FLASH_CLASS: return "Flash Controls"; + case V4L2_CID_FLASH_LED_MODE: return "LED Mode"; + case V4L2_CID_FLASH_STROBE_SOURCE: return "Strobe Source"; + case V4L2_CID_FLASH_STROBE: return "Strobe"; + case V4L2_CID_FLASH_STROBE_STOP: return "Stop Strobe"; + case V4L2_CID_FLASH_STROBE_STATUS: return "Strobe Status"; + case V4L2_CID_FLASH_TIMEOUT: return "Strobe Timeout"; + case V4L2_CID_FLASH_INTENSITY: return "Intensity, Flash Mode"; + case V4L2_CID_FLASH_TORCH_INTENSITY: return "Intensity, Torch Mode"; + case V4L2_CID_FLASH_INDICATOR_INTENSITY: return "Intensity, Indicator"; + case V4L2_CID_FLASH_FAULT: return "Faults"; + case V4L2_CID_FLASH_CHARGE: return "Charge"; + case V4L2_CID_FLASH_READY: return "Ready to Strobe"; + + /* JPEG encoder controls */ + /* Keep the order of the 'case's the same as in v4l2-controls.h! */ + case V4L2_CID_JPEG_CLASS: return "JPEG Compression Controls"; + case V4L2_CID_JPEG_CHROMA_SUBSAMPLING: return "Chroma Subsampling"; + case V4L2_CID_JPEG_RESTART_INTERVAL: return "Restart Interval"; + case V4L2_CID_JPEG_COMPRESSION_QUALITY: return "Compression Quality"; + case V4L2_CID_JPEG_ACTIVE_MARKER: return "Active Markers"; + + /* Image source controls */ + /* Keep the order of the 'case's the same as in v4l2-controls.h! */ + case V4L2_CID_IMAGE_SOURCE_CLASS: return "Image Source Controls"; + case V4L2_CID_VBLANK: return "Vertical Blanking"; + case V4L2_CID_HBLANK: return "Horizontal Blanking"; + case V4L2_CID_ANALOGUE_GAIN: return "Analogue Gain"; + case V4L2_CID_TEST_PATTERN_RED: return "Red Pixel Value"; + case V4L2_CID_TEST_PATTERN_GREENR: return "Green (Red) Pixel Value"; + case V4L2_CID_TEST_PATTERN_BLUE: return "Blue Pixel Value"; + case V4L2_CID_TEST_PATTERN_GREENB: return "Green (Blue) Pixel Value"; + + /* Image processing controls */ + /* Keep the order of the 'case's the same as in v4l2-controls.h! */ + case V4L2_CID_IMAGE_PROC_CLASS: return "Image Processing Controls"; + case V4L2_CID_LINK_FREQ: return "Link Frequency"; + case V4L2_CID_PIXEL_RATE: return "Pixel Rate"; + case V4L2_CID_TEST_PATTERN: return "Test Pattern"; + case V4L2_CID_DEINTERLACING_MODE: return "Deinterlacing Mode"; + case V4L2_CID_DIGITAL_GAIN: return "Digital Gain"; + + /* DV controls */ + /* Keep the order of the 'case's the same as in v4l2-controls.h! */ + case V4L2_CID_DV_CLASS: return "Digital Video Controls"; + case V4L2_CID_DV_TX_HOTPLUG: return "Hotplug Present"; + case V4L2_CID_DV_TX_RXSENSE: return "RxSense Present"; + case V4L2_CID_DV_TX_EDID_PRESENT: return "EDID Present"; + case V4L2_CID_DV_TX_MODE: return "Transmit Mode"; + case V4L2_CID_DV_TX_RGB_RANGE: return "Tx RGB Quantization Range"; + case V4L2_CID_DV_TX_IT_CONTENT_TYPE: return "Tx IT Content Type"; + case V4L2_CID_DV_RX_POWER_PRESENT: return "Power Present"; + case V4L2_CID_DV_RX_RGB_RANGE: return "Rx RGB Quantization Range"; + case V4L2_CID_DV_RX_IT_CONTENT_TYPE: return "Rx IT Content Type"; + + case V4L2_CID_FM_RX_CLASS: return "FM Radio Receiver Controls"; + case V4L2_CID_TUNE_DEEMPHASIS: return "De-Emphasis"; + case V4L2_CID_RDS_RECEPTION: return "RDS Reception"; + case V4L2_CID_RF_TUNER_CLASS: return "RF Tuner Controls"; + case V4L2_CID_RF_TUNER_RF_GAIN: return "RF Gain"; + case V4L2_CID_RF_TUNER_LNA_GAIN_AUTO: return "LNA Gain, Auto"; + case V4L2_CID_RF_TUNER_LNA_GAIN: return "LNA Gain"; + case V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO: return "Mixer Gain, Auto"; + case V4L2_CID_RF_TUNER_MIXER_GAIN: return "Mixer Gain"; + case V4L2_CID_RF_TUNER_IF_GAIN_AUTO: return "IF Gain, Auto"; + case V4L2_CID_RF_TUNER_IF_GAIN: return "IF Gain"; + case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO: return "Bandwidth, Auto"; + case V4L2_CID_RF_TUNER_BANDWIDTH: return "Bandwidth"; + case V4L2_CID_RF_TUNER_PLL_LOCK: return "PLL Lock"; + case V4L2_CID_RDS_RX_PTY: return "RDS Program Type"; + case V4L2_CID_RDS_RX_PS_NAME: return "RDS PS Name"; + case V4L2_CID_RDS_RX_RADIO_TEXT: return "RDS Radio Text"; + case V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT: return "RDS Traffic Announcement"; + case V4L2_CID_RDS_RX_TRAFFIC_PROGRAM: return "RDS Traffic Program"; + case V4L2_CID_RDS_RX_MUSIC_SPEECH: return "RDS Music"; + + /* Detection controls */ + /* Keep the order of the 'case's the same as in v4l2-controls.h! */ + case V4L2_CID_DETECT_CLASS: return "Detection Controls"; + case V4L2_CID_DETECT_MD_MODE: return "Motion Detection Mode"; + case V4L2_CID_DETECT_MD_GLOBAL_THRESHOLD: return "MD Global Threshold"; + case V4L2_CID_DETECT_MD_THRESHOLD_GRID: return "MD Threshold Grid"; + case V4L2_CID_DETECT_MD_REGION_GRID: return "MD Region Grid"; + + /* Stateless Codec controls */ + /* Keep the order of the 'case's the same as in v4l2-controls.h! */ + case V4L2_CID_CODEC_STATELESS_CLASS: return "Stateless Codec Controls"; + case V4L2_CID_STATELESS_H264_DECODE_MODE: return "H264 Decode Mode"; + case V4L2_CID_STATELESS_H264_START_CODE: return "H264 Start Code"; + case V4L2_CID_STATELESS_H264_SPS: return "H264 Sequence Parameter Set"; + case V4L2_CID_STATELESS_H264_PPS: return "H264 Picture Parameter Set"; + case V4L2_CID_STATELESS_H264_SCALING_MATRIX: return "H264 Scaling Matrix"; + case V4L2_CID_STATELESS_H264_PRED_WEIGHTS: return "H264 Prediction Weight Table"; + case V4L2_CID_STATELESS_H264_SLICE_PARAMS: return "H264 Slice Parameters"; + case V4L2_CID_STATELESS_H264_DECODE_PARAMS: return "H264 Decode Parameters"; + case V4L2_CID_STATELESS_FWHT_PARAMS: return "FWHT Stateless Parameters"; + case V4L2_CID_STATELESS_VP8_FRAME: return "VP8 Frame Parameters"; + case V4L2_CID_STATELESS_MPEG2_SEQUENCE: return "MPEG-2 Sequence Header"; + case V4L2_CID_STATELESS_MPEG2_PICTURE: return "MPEG-2 Picture Header"; + case V4L2_CID_STATELESS_MPEG2_QUANTISATION: return "MPEG-2 Quantisation Matrices"; + + /* Colorimetry controls */ + /* Keep the order of the 'case's the same as in v4l2-controls.h! */ + case V4L2_CID_COLORIMETRY_CLASS: return "Colorimetry Controls"; + case V4L2_CID_COLORIMETRY_HDR10_CLL_INFO: return "HDR10 Content Light Info"; + case V4L2_CID_COLORIMETRY_HDR10_MASTERING_DISPLAY: return "HDR10 Mastering Display"; + default: + return NULL; + } +} +EXPORT_SYMBOL(v4l2_ctrl_get_name); + +void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, + s64 *min, s64 *max, u64 *step, s64 *def, u32 *flags) +{ + *name = v4l2_ctrl_get_name(id); + *flags = 0; + + switch (id) { + case V4L2_CID_AUDIO_MUTE: + case V4L2_CID_AUDIO_LOUDNESS: + case V4L2_CID_AUTO_WHITE_BALANCE: + case V4L2_CID_AUTOGAIN: + case V4L2_CID_HFLIP: + case V4L2_CID_VFLIP: + case V4L2_CID_HUE_AUTO: + case V4L2_CID_CHROMA_AGC: + case V4L2_CID_COLOR_KILLER: + case V4L2_CID_AUTOBRIGHTNESS: + case V4L2_CID_MPEG_AUDIO_MUTE: + case V4L2_CID_MPEG_VIDEO_MUTE: + case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: + case V4L2_CID_MPEG_VIDEO_PULLDOWN: + case V4L2_CID_EXPOSURE_AUTO_PRIORITY: + case V4L2_CID_FOCUS_AUTO: + case V4L2_CID_PRIVACY: + case V4L2_CID_AUDIO_LIMITER_ENABLED: + case V4L2_CID_AUDIO_COMPRESSION_ENABLED: + case V4L2_CID_PILOT_TONE_ENABLED: + case V4L2_CID_ILLUMINATORS_1: + case V4L2_CID_ILLUMINATORS_2: + case V4L2_CID_FLASH_STROBE_STATUS: + case V4L2_CID_FLASH_CHARGE: + case V4L2_CID_FLASH_READY: + case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER: + case V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE: + case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY_ENABLE: + case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE: + case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE: + case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM: + case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE: + case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL: + case V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER: + case V4L2_CID_MPEG_VIDEO_AU_DELIMITER: + case V4L2_CID_WIDE_DYNAMIC_RANGE: + case V4L2_CID_IMAGE_STABILIZATION: + case V4L2_CID_RDS_RECEPTION: + case V4L2_CID_RF_TUNER_LNA_GAIN_AUTO: + case V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO: + case V4L2_CID_RF_TUNER_IF_GAIN_AUTO: + case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO: + case V4L2_CID_RF_TUNER_PLL_LOCK: + case V4L2_CID_RDS_TX_MONO_STEREO: + case V4L2_CID_RDS_TX_ARTIFICIAL_HEAD: + case V4L2_CID_RDS_TX_COMPRESSED: + case V4L2_CID_RDS_TX_DYNAMIC_PTY: + case V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT: + case V4L2_CID_RDS_TX_TRAFFIC_PROGRAM: + case V4L2_CID_RDS_TX_MUSIC_SPEECH: + case V4L2_CID_RDS_TX_ALT_FREQS_ENABLE: + case V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT: + case V4L2_CID_RDS_RX_TRAFFIC_PROGRAM: + case V4L2_CID_RDS_RX_MUSIC_SPEECH: + *type = V4L2_CTRL_TYPE_BOOLEAN; + *min = 0; + *max = *step = 1; + break; + case V4L2_CID_ROTATE: + *type = V4L2_CTRL_TYPE_INTEGER; + *flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; + break; + case V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE: + case V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE: + case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY: + *type = V4L2_CTRL_TYPE_INTEGER; + break; + case V4L2_CID_MPEG_VIDEO_LTR_COUNT: + *type = V4L2_CTRL_TYPE_INTEGER; + break; + case V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX: + *type = V4L2_CTRL_TYPE_INTEGER; + *flags |= V4L2_CTRL_FLAG_EXECUTE_ON_WRITE; + break; + case V4L2_CID_MPEG_VIDEO_USE_LTR_FRAMES: + *type = V4L2_CTRL_TYPE_BITMASK; + *flags |= V4L2_CTRL_FLAG_EXECUTE_ON_WRITE; + break; + case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME: + case V4L2_CID_PAN_RESET: + case V4L2_CID_TILT_RESET: + case V4L2_CID_FLASH_STROBE: + case V4L2_CID_FLASH_STROBE_STOP: + case V4L2_CID_AUTO_FOCUS_START: + case V4L2_CID_AUTO_FOCUS_STOP: + case V4L2_CID_DO_WHITE_BALANCE: + *type = V4L2_CTRL_TYPE_BUTTON; + *flags |= V4L2_CTRL_FLAG_WRITE_ONLY | + V4L2_CTRL_FLAG_EXECUTE_ON_WRITE; + *min = *max = *step = *def = 0; + break; + case V4L2_CID_POWER_LINE_FREQUENCY: + case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: + case V4L2_CID_MPEG_AUDIO_ENCODING: + case V4L2_CID_MPEG_AUDIO_L1_BITRATE: + case V4L2_CID_MPEG_AUDIO_L2_BITRATE: + case V4L2_CID_MPEG_AUDIO_L3_BITRATE: + case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: + case V4L2_CID_MPEG_AUDIO_MODE: + case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: + case V4L2_CID_MPEG_AUDIO_EMPHASIS: + case V4L2_CID_MPEG_AUDIO_CRC: + case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK: + case V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK: + case V4L2_CID_MPEG_VIDEO_ENCODING: + case V4L2_CID_MPEG_VIDEO_ASPECT: + case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: + case V4L2_CID_MPEG_STREAM_TYPE: + case V4L2_CID_MPEG_STREAM_VBI_FMT: + case V4L2_CID_EXPOSURE_AUTO: + case V4L2_CID_AUTO_FOCUS_RANGE: + case V4L2_CID_COLORFX: + case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE: + case V4L2_CID_TUNE_PREEMPHASIS: + case V4L2_CID_FLASH_LED_MODE: + case V4L2_CID_FLASH_STROBE_SOURCE: + case V4L2_CID_MPEG_VIDEO_HEADER_MODE: + case V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE: + case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: + case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: + case V4L2_CID_MPEG_VIDEO_H264_LEVEL: + case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE: + case V4L2_CID_MPEG_VIDEO_H264_PROFILE: + case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC: + case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE: + case V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE: + case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE: + case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL: + case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE: + case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: + case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: + case V4L2_CID_JPEG_CHROMA_SUBSAMPLING: + case V4L2_CID_ISO_SENSITIVITY_AUTO: + case V4L2_CID_EXPOSURE_METERING: + case V4L2_CID_SCENE_MODE: + case V4L2_CID_DV_TX_MODE: + case V4L2_CID_DV_TX_RGB_RANGE: + case V4L2_CID_DV_TX_IT_CONTENT_TYPE: + case V4L2_CID_DV_RX_RGB_RANGE: + case V4L2_CID_DV_RX_IT_CONTENT_TYPE: + case V4L2_CID_TEST_PATTERN: + case V4L2_CID_DEINTERLACING_MODE: + case V4L2_CID_TUNE_DEEMPHASIS: + case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL: + case V4L2_CID_MPEG_VIDEO_VP8_PROFILE: + case V4L2_CID_MPEG_VIDEO_VP9_PROFILE: + case V4L2_CID_MPEG_VIDEO_VP9_LEVEL: + case V4L2_CID_DETECT_MD_MODE: + case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: + case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE: + case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE: + case V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD: + case V4L2_CID_MPEG_VIDEO_HEVC_TIER: + case V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE: + case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE: + case V4L2_CID_MPEG_VIDEO_HEVC_START_CODE: + case V4L2_CID_STATELESS_H264_DECODE_MODE: + case V4L2_CID_STATELESS_H264_START_CODE: + case V4L2_CID_CAMERA_ORIENTATION: + *type = V4L2_CTRL_TYPE_MENU; + break; + case V4L2_CID_LINK_FREQ: + *type = V4L2_CTRL_TYPE_INTEGER_MENU; + break; + case V4L2_CID_RDS_TX_PS_NAME: + case V4L2_CID_RDS_TX_RADIO_TEXT: + case V4L2_CID_RDS_RX_PS_NAME: + case V4L2_CID_RDS_RX_RADIO_TEXT: + *type = V4L2_CTRL_TYPE_STRING; + break; + case V4L2_CID_ISO_SENSITIVITY: + case V4L2_CID_AUTO_EXPOSURE_BIAS: + case V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS: + case V4L2_CID_MPEG_VIDEO_VPX_NUM_REF_FRAMES: + *type = V4L2_CTRL_TYPE_INTEGER_MENU; + break; + case V4L2_CID_USER_CLASS: + case V4L2_CID_CAMERA_CLASS: + case V4L2_CID_CODEC_CLASS: + case V4L2_CID_FM_TX_CLASS: + case V4L2_CID_FLASH_CLASS: + case V4L2_CID_JPEG_CLASS: + case V4L2_CID_IMAGE_SOURCE_CLASS: + case V4L2_CID_IMAGE_PROC_CLASS: + case V4L2_CID_DV_CLASS: + case V4L2_CID_FM_RX_CLASS: + case V4L2_CID_RF_TUNER_CLASS: + case V4L2_CID_DETECT_CLASS: + case V4L2_CID_CODEC_STATELESS_CLASS: + case V4L2_CID_COLORIMETRY_CLASS: + *type = V4L2_CTRL_TYPE_CTRL_CLASS; + /* You can neither read nor write these */ + *flags |= V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY; + *min = *max = *step = *def = 0; + break; + case V4L2_CID_BG_COLOR: + *type = V4L2_CTRL_TYPE_INTEGER; + *step = 1; + *min = 0; + /* Max is calculated as RGB888 that is 2^24 */ + *max = 0xFFFFFF; + break; + case V4L2_CID_FLASH_FAULT: + case V4L2_CID_JPEG_ACTIVE_MARKER: + case V4L2_CID_3A_LOCK: + case V4L2_CID_AUTO_FOCUS_STATUS: + case V4L2_CID_DV_TX_HOTPLUG: + case V4L2_CID_DV_TX_RXSENSE: + case V4L2_CID_DV_TX_EDID_PRESENT: + case V4L2_CID_DV_RX_POWER_PRESENT: + *type = V4L2_CTRL_TYPE_BITMASK; + break; + case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: + case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: + *type = V4L2_CTRL_TYPE_INTEGER; + *flags |= V4L2_CTRL_FLAG_READ_ONLY; + break; + case V4L2_CID_MPEG_VIDEO_DEC_PTS: + *type = V4L2_CTRL_TYPE_INTEGER64; + *flags |= V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY; + *min = *def = 0; + *max = 0x1ffffffffLL; + *step = 1; + break; + case V4L2_CID_MPEG_VIDEO_DEC_FRAME: + *type = V4L2_CTRL_TYPE_INTEGER64; + *flags |= V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY; + *min = *def = 0; + *max = 0x7fffffffffffffffLL; + *step = 1; + break; + case V4L2_CID_MPEG_VIDEO_DEC_CONCEAL_COLOR: + *type = V4L2_CTRL_TYPE_INTEGER64; + *min = 0; + /* default for 8 bit black, luma is 16, chroma is 128 */ + *def = 0x8000800010LL; + *max = 0xffffffffffffLL; + *step = 1; + break; + case V4L2_CID_PIXEL_RATE: + *type = V4L2_CTRL_TYPE_INTEGER64; + *flags |= V4L2_CTRL_FLAG_READ_ONLY; + break; + case V4L2_CID_DETECT_MD_REGION_GRID: + *type = V4L2_CTRL_TYPE_U8; + break; + case V4L2_CID_DETECT_MD_THRESHOLD_GRID: + *type = V4L2_CTRL_TYPE_U16; + break; + case V4L2_CID_RDS_TX_ALT_FREQS: + *type = V4L2_CTRL_TYPE_U32; + break; + case V4L2_CID_STATELESS_MPEG2_SEQUENCE: + *type = V4L2_CTRL_TYPE_MPEG2_SEQUENCE; + break; + case V4L2_CID_STATELESS_MPEG2_PICTURE: + *type = V4L2_CTRL_TYPE_MPEG2_PICTURE; + break; + case V4L2_CID_STATELESS_MPEG2_QUANTISATION: + *type = V4L2_CTRL_TYPE_MPEG2_QUANTISATION; + break; + case V4L2_CID_STATELESS_FWHT_PARAMS: + *type = V4L2_CTRL_TYPE_FWHT_PARAMS; + break; + case V4L2_CID_STATELESS_H264_SPS: + *type = V4L2_CTRL_TYPE_H264_SPS; + break; + case V4L2_CID_STATELESS_H264_PPS: + *type = V4L2_CTRL_TYPE_H264_PPS; + break; + case V4L2_CID_STATELESS_H264_SCALING_MATRIX: + *type = V4L2_CTRL_TYPE_H264_SCALING_MATRIX; + break; + case V4L2_CID_STATELESS_H264_SLICE_PARAMS: + *type = V4L2_CTRL_TYPE_H264_SLICE_PARAMS; + break; + case V4L2_CID_STATELESS_H264_DECODE_PARAMS: + *type = V4L2_CTRL_TYPE_H264_DECODE_PARAMS; + break; + case V4L2_CID_STATELESS_H264_PRED_WEIGHTS: + *type = V4L2_CTRL_TYPE_H264_PRED_WEIGHTS; + break; + case V4L2_CID_STATELESS_VP8_FRAME: + *type = V4L2_CTRL_TYPE_VP8_FRAME; + break; + case V4L2_CID_MPEG_VIDEO_HEVC_SPS: + *type = V4L2_CTRL_TYPE_HEVC_SPS; + break; + case V4L2_CID_MPEG_VIDEO_HEVC_PPS: + *type = V4L2_CTRL_TYPE_HEVC_PPS; + break; + case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS: + *type = V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS; + break; + case V4L2_CID_UNIT_CELL_SIZE: + *type = V4L2_CTRL_TYPE_AREA; + *flags |= V4L2_CTRL_FLAG_READ_ONLY; + break; + case V4L2_CID_COLORIMETRY_HDR10_CLL_INFO: + *type = V4L2_CTRL_TYPE_HDR10_CLL_INFO; + break; + case V4L2_CID_COLORIMETRY_HDR10_MASTERING_DISPLAY: + *type = V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY; + break; + default: + *type = V4L2_CTRL_TYPE_INTEGER; + break; + } + switch (id) { + case V4L2_CID_MPEG_AUDIO_ENCODING: + case V4L2_CID_MPEG_AUDIO_MODE: + case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: + case V4L2_CID_MPEG_VIDEO_B_FRAMES: + case V4L2_CID_MPEG_STREAM_TYPE: + *flags |= V4L2_CTRL_FLAG_UPDATE; + break; + case V4L2_CID_AUDIO_VOLUME: + case V4L2_CID_AUDIO_BALANCE: + case V4L2_CID_AUDIO_BASS: + case V4L2_CID_AUDIO_TREBLE: + case V4L2_CID_BRIGHTNESS: + case V4L2_CID_CONTRAST: + case V4L2_CID_SATURATION: + case V4L2_CID_HUE: + case V4L2_CID_RED_BALANCE: + case V4L2_CID_BLUE_BALANCE: + case V4L2_CID_GAMMA: + case V4L2_CID_SHARPNESS: + case V4L2_CID_CHROMA_GAIN: + case V4L2_CID_RDS_TX_DEVIATION: + case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME: + case V4L2_CID_AUDIO_LIMITER_DEVIATION: + case V4L2_CID_AUDIO_COMPRESSION_GAIN: + case V4L2_CID_AUDIO_COMPRESSION_THRESHOLD: + case V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME: + case V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME: + case V4L2_CID_PILOT_TONE_DEVIATION: + case V4L2_CID_PILOT_TONE_FREQUENCY: + case V4L2_CID_TUNE_POWER_LEVEL: + case V4L2_CID_TUNE_ANTENNA_CAPACITOR: + case V4L2_CID_RF_TUNER_RF_GAIN: + case V4L2_CID_RF_TUNER_LNA_GAIN: + case V4L2_CID_RF_TUNER_MIXER_GAIN: + case V4L2_CID_RF_TUNER_IF_GAIN: + case V4L2_CID_RF_TUNER_BANDWIDTH: + case V4L2_CID_DETECT_MD_GLOBAL_THRESHOLD: + *flags |= V4L2_CTRL_FLAG_SLIDER; + break; + case V4L2_CID_PAN_RELATIVE: + case V4L2_CID_TILT_RELATIVE: + case V4L2_CID_FOCUS_RELATIVE: + case V4L2_CID_IRIS_RELATIVE: + case V4L2_CID_ZOOM_RELATIVE: + *flags |= V4L2_CTRL_FLAG_WRITE_ONLY | + V4L2_CTRL_FLAG_EXECUTE_ON_WRITE; + break; + case V4L2_CID_FLASH_STROBE_STATUS: + case V4L2_CID_AUTO_FOCUS_STATUS: + case V4L2_CID_FLASH_READY: + case V4L2_CID_DV_TX_HOTPLUG: + case V4L2_CID_DV_TX_RXSENSE: + case V4L2_CID_DV_TX_EDID_PRESENT: + case V4L2_CID_DV_RX_POWER_PRESENT: + case V4L2_CID_DV_RX_IT_CONTENT_TYPE: + case V4L2_CID_RDS_RX_PTY: + case V4L2_CID_RDS_RX_PS_NAME: + case V4L2_CID_RDS_RX_RADIO_TEXT: + case V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT: + case V4L2_CID_RDS_RX_TRAFFIC_PROGRAM: + case V4L2_CID_RDS_RX_MUSIC_SPEECH: + case V4L2_CID_CAMERA_ORIENTATION: + case V4L2_CID_CAMERA_SENSOR_ROTATION: + *flags |= V4L2_CTRL_FLAG_READ_ONLY; + break; + case V4L2_CID_RF_TUNER_PLL_LOCK: + *flags |= V4L2_CTRL_FLAG_VOLATILE; + break; + } +} +EXPORT_SYMBOL(v4l2_ctrl_fill); diff --git a/drivers/media/v4l2-core/v4l2-ctrls-priv.h b/drivers/media/v4l2-core/v4l2-ctrls-priv.h new file mode 100644 index 000000000000..d4bf2c716f97 --- /dev/null +++ b/drivers/media/v4l2-core/v4l2-ctrls-priv.h @@ -0,0 +1,96 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * V4L2 controls framework private header. + * + * Copyright (C) 2010-2021 Hans Verkuil + */ + +#ifndef _V4L2_CTRLS_PRIV_H_ +#define _V4L2_CTRLS_PRIV_H_ + +#define dprintk(vdev, fmt, arg...) do { \ + if (!WARN_ON(!(vdev)) && ((vdev)->dev_debug & V4L2_DEV_DEBUG_CTRL)) \ + printk(KERN_DEBUG pr_fmt("%s: %s: " fmt), \ + __func__, video_device_node_name(vdev), ##arg); \ +} while (0) + +#define has_op(master, op) \ + ((master)->ops && (master)->ops->op) +#define call_op(master, op) \ + (has_op(master, op) ? (master)->ops->op(master) : 0) + +static inline u32 node2id(struct list_head *node) +{ + return list_entry(node, struct v4l2_ctrl_ref, node)->ctrl->id; +} + +/* + * Small helper function to determine if the autocluster is set to manual + * mode. + */ +static inline bool is_cur_manual(const struct v4l2_ctrl *master) +{ + return master->is_auto && master->cur.val == master->manual_mode_value; +} + +/* + * Small helper function to determine if the autocluster will be set to manual + * mode. + */ +static inline bool is_new_manual(const struct v4l2_ctrl *master) +{ + return master->is_auto && master->val == master->manual_mode_value; +} + +static inline u32 user_flags(const struct v4l2_ctrl *ctrl) +{ + u32 flags = ctrl->flags; + + if (ctrl->is_ptr) + flags |= V4L2_CTRL_FLAG_HAS_PAYLOAD; + + return flags; +} + +/* v4l2-ctrls-core.c */ +void cur_to_new(struct v4l2_ctrl *ctrl); +void cur_to_req(struct v4l2_ctrl_ref *ref); +void new_to_cur(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 ch_flags); +void new_to_req(struct v4l2_ctrl_ref *ref); +void req_to_new(struct v4l2_ctrl_ref *ref); +void send_initial_event(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl); +void send_event(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 changes); +int validate_new(const struct v4l2_ctrl *ctrl, union v4l2_ctrl_ptr p_new); +int handler_new_ref(struct v4l2_ctrl_handler *hdl, + struct v4l2_ctrl *ctrl, + struct v4l2_ctrl_ref **ctrl_ref, + bool from_other_dev, bool allocate_req); +struct v4l2_ctrl_ref *find_ref(struct v4l2_ctrl_handler *hdl, u32 id); +struct v4l2_ctrl_ref *find_ref_lock(struct v4l2_ctrl_handler *hdl, u32 id); +int check_range(enum v4l2_ctrl_type type, + s64 min, s64 max, u64 step, s64 def); +void update_from_auto_cluster(struct v4l2_ctrl *master); +int try_or_set_cluster(struct v4l2_fh *fh, struct v4l2_ctrl *master, + bool set, u32 ch_flags); + +/* v4l2-ctrls-api.c */ +int v4l2_g_ext_ctrls_common(struct v4l2_ctrl_handler *hdl, + struct v4l2_ext_controls *cs, + struct video_device *vdev); +int try_set_ext_ctrls_common(struct v4l2_fh *fh, + struct v4l2_ctrl_handler *hdl, + struct v4l2_ext_controls *cs, + struct video_device *vdev, bool set); + +/* v4l2-ctrls-request.c */ +void v4l2_ctrl_handler_init_request(struct v4l2_ctrl_handler *hdl); +void v4l2_ctrl_handler_free_request(struct v4l2_ctrl_handler *hdl); +int v4l2_g_ext_ctrls_request(struct v4l2_ctrl_handler *hdl, struct video_device *vdev, + struct media_device *mdev, struct v4l2_ext_controls *cs); +int try_set_ext_ctrls_request(struct v4l2_fh *fh, + struct v4l2_ctrl_handler *hdl, + struct video_device *vdev, + struct media_device *mdev, + struct v4l2_ext_controls *cs, bool set); + +#endif diff --git a/drivers/media/v4l2-core/v4l2-ctrls-request.c b/drivers/media/v4l2-core/v4l2-ctrls-request.c new file mode 100644 index 000000000000..7d098f287fd9 --- /dev/null +++ b/drivers/media/v4l2-core/v4l2-ctrls-request.c @@ -0,0 +1,496 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * V4L2 controls framework Request API implementation. + * + * Copyright (C) 2018-2021 Hans Verkuil + */ + +#define pr_fmt(fmt) "v4l2-ctrls: " fmt + +#include +#include +#include +#include +#include + +#include "v4l2-ctrls-priv.h" + +/* Initialize the request-related fields in a control handler */ +void v4l2_ctrl_handler_init_request(struct v4l2_ctrl_handler *hdl) +{ + INIT_LIST_HEAD(&hdl->requests); + INIT_LIST_HEAD(&hdl->requests_queued); + hdl->request_is_queued = false; + media_request_object_init(&hdl->req_obj); +} + +/* Free the request-related fields in a control handler */ +void v4l2_ctrl_handler_free_request(struct v4l2_ctrl_handler *hdl) +{ + struct v4l2_ctrl_handler *req, *next_req; + + /* + * Do nothing if this isn't the main handler or the main + * handler is not used in any request. + * + * The main handler can be identified by having a NULL ops pointer in + * the request object. + */ + if (hdl->req_obj.ops || list_empty(&hdl->requests)) + return; + + /* + * If the main handler is freed and it is used by handler objects in + * outstanding requests, then unbind and put those objects before + * freeing the main handler. + */ + list_for_each_entry_safe(req, next_req, &hdl->requests, requests) { + media_request_object_unbind(&req->req_obj); + media_request_object_put(&req->req_obj); + } +} + +static int v4l2_ctrl_request_clone(struct v4l2_ctrl_handler *hdl, + const struct v4l2_ctrl_handler *from) +{ + struct v4l2_ctrl_ref *ref; + int err = 0; + + if (WARN_ON(!hdl || hdl == from)) + return -EINVAL; + + if (hdl->error) + return hdl->error; + + WARN_ON(hdl->lock != &hdl->_lock); + + mutex_lock(from->lock); + list_for_each_entry(ref, &from->ctrl_refs, node) { + struct v4l2_ctrl *ctrl = ref->ctrl; + struct v4l2_ctrl_ref *new_ref; + + /* Skip refs inherited from other devices */ + if (ref->from_other_dev) + continue; + err = handler_new_ref(hdl, ctrl, &new_ref, false, true); + if (err) + break; + } + mutex_unlock(from->lock); + return err; +} + +static void v4l2_ctrl_request_queue(struct media_request_object *obj) +{ + struct v4l2_ctrl_handler *hdl = + container_of(obj, struct v4l2_ctrl_handler, req_obj); + struct v4l2_ctrl_handler *main_hdl = obj->priv; + + mutex_lock(main_hdl->lock); + list_add_tail(&hdl->requests_queued, &main_hdl->requests_queued); + hdl->request_is_queued = true; + mutex_unlock(main_hdl->lock); +} + +static void v4l2_ctrl_request_unbind(struct media_request_object *obj) +{ + struct v4l2_ctrl_handler *hdl = + container_of(obj, struct v4l2_ctrl_handler, req_obj); + struct v4l2_ctrl_handler *main_hdl = obj->priv; + + mutex_lock(main_hdl->lock); + list_del_init(&hdl->requests); + if (hdl->request_is_queued) { + list_del_init(&hdl->requests_queued); + hdl->request_is_queued = false; + } + mutex_unlock(main_hdl->lock); +} + +static void v4l2_ctrl_request_release(struct media_request_object *obj) +{ + struct v4l2_ctrl_handler *hdl = + container_of(obj, struct v4l2_ctrl_handler, req_obj); + + v4l2_ctrl_handler_free(hdl); + kfree(hdl); +} + +static const struct media_request_object_ops req_ops = { + .queue = v4l2_ctrl_request_queue, + .unbind = v4l2_ctrl_request_unbind, + .release = v4l2_ctrl_request_release, +}; + +struct v4l2_ctrl_handler *v4l2_ctrl_request_hdl_find(struct media_request *req, + struct v4l2_ctrl_handler *parent) +{ + struct media_request_object *obj; + + if (WARN_ON(req->state != MEDIA_REQUEST_STATE_VALIDATING && + req->state != MEDIA_REQUEST_STATE_QUEUED)) + return NULL; + + obj = media_request_object_find(req, &req_ops, parent); + if (obj) + return container_of(obj, struct v4l2_ctrl_handler, req_obj); + return NULL; +} +EXPORT_SYMBOL_GPL(v4l2_ctrl_request_hdl_find); + +struct v4l2_ctrl * +v4l2_ctrl_request_hdl_ctrl_find(struct v4l2_ctrl_handler *hdl, u32 id) +{ + struct v4l2_ctrl_ref *ref = find_ref_lock(hdl, id); + + return (ref && ref->valid_p_req) ? ref->ctrl : NULL; +} +EXPORT_SYMBOL_GPL(v4l2_ctrl_request_hdl_ctrl_find); + +static int v4l2_ctrl_request_bind(struct media_request *req, + struct v4l2_ctrl_handler *hdl, + struct v4l2_ctrl_handler *from) +{ + int ret; + + ret = v4l2_ctrl_request_clone(hdl, from); + + if (!ret) { + ret = media_request_object_bind(req, &req_ops, + from, false, &hdl->req_obj); + if (!ret) { + mutex_lock(from->lock); + list_add_tail(&hdl->requests, &from->requests); + mutex_unlock(from->lock); + } + } + return ret; +} + +static struct media_request_object * +v4l2_ctrls_find_req_obj(struct v4l2_ctrl_handler *hdl, + struct media_request *req, bool set) +{ + struct media_request_object *obj; + struct v4l2_ctrl_handler *new_hdl; + int ret; + + if (IS_ERR(req)) + return ERR_CAST(req); + + if (set && WARN_ON(req->state != MEDIA_REQUEST_STATE_UPDATING)) + return ERR_PTR(-EBUSY); + + obj = media_request_object_find(req, &req_ops, hdl); + if (obj) + return obj; + /* + * If there are no controls in this completed request, + * then that can only happen if: + * + * 1) no controls were present in the queued request, and + * 2) v4l2_ctrl_request_complete() could not allocate a + * control handler object to store the completed state in. + * + * So return ENOMEM to indicate that there was an out-of-memory + * error. + */ + if (!set) + return ERR_PTR(-ENOMEM); + + new_hdl = kzalloc(sizeof(*new_hdl), GFP_KERNEL); + if (!new_hdl) + return ERR_PTR(-ENOMEM); + + obj = &new_hdl->req_obj; + ret = v4l2_ctrl_handler_init(new_hdl, (hdl->nr_of_buckets - 1) * 8); + if (!ret) + ret = v4l2_ctrl_request_bind(req, new_hdl, hdl); + if (ret) { + v4l2_ctrl_handler_free(new_hdl); + kfree(new_hdl); + return ERR_PTR(ret); + } + + media_request_object_get(obj); + return obj; +} + +int v4l2_g_ext_ctrls_request(struct v4l2_ctrl_handler *hdl, struct video_device *vdev, + struct media_device *mdev, struct v4l2_ext_controls *cs) +{ + struct media_request_object *obj = NULL; + struct media_request *req = NULL; + int ret; + + if (!mdev || cs->request_fd < 0) + return -EINVAL; + + req = media_request_get_by_fd(mdev, cs->request_fd); + if (IS_ERR(req)) + return PTR_ERR(req); + + if (req->state != MEDIA_REQUEST_STATE_COMPLETE) { + media_request_put(req); + return -EACCES; + } + + ret = media_request_lock_for_access(req); + if (ret) { + media_request_put(req); + return ret; + } + + obj = v4l2_ctrls_find_req_obj(hdl, req, false); + if (IS_ERR(obj)) { + media_request_unlock_for_access(req); + media_request_put(req); + return PTR_ERR(obj); + } + + hdl = container_of(obj, struct v4l2_ctrl_handler, + req_obj); + ret = v4l2_g_ext_ctrls_common(hdl, cs, vdev); + + media_request_unlock_for_access(req); + media_request_object_put(obj); + media_request_put(req); + return ret; +} + +int try_set_ext_ctrls_request(struct v4l2_fh *fh, + struct v4l2_ctrl_handler *hdl, + struct video_device *vdev, + struct media_device *mdev, + struct v4l2_ext_controls *cs, bool set) +{ + struct media_request_object *obj = NULL; + struct media_request *req = NULL; + int ret; + + if (!mdev) { + dprintk(vdev, "%s: missing media device\n", + video_device_node_name(vdev)); + return -EINVAL; + } + + if (cs->request_fd < 0) { + dprintk(vdev, "%s: invalid request fd %d\n", + video_device_node_name(vdev), cs->request_fd); + return -EINVAL; + } + + req = media_request_get_by_fd(mdev, cs->request_fd); + if (IS_ERR(req)) { + dprintk(vdev, "%s: cannot find request fd %d\n", + video_device_node_name(vdev), cs->request_fd); + return PTR_ERR(req); + } + + ret = media_request_lock_for_update(req); + if (ret) { + dprintk(vdev, "%s: cannot lock request fd %d\n", + video_device_node_name(vdev), cs->request_fd); + media_request_put(req); + return ret; + } + + obj = v4l2_ctrls_find_req_obj(hdl, req, set); + if (IS_ERR(obj)) { + dprintk(vdev, + "%s: cannot find request object for request fd %d\n", + video_device_node_name(vdev), + cs->request_fd); + media_request_unlock_for_update(req); + media_request_put(req); + return PTR_ERR(obj); + } + + hdl = container_of(obj, struct v4l2_ctrl_handler, + req_obj); + ret = try_set_ext_ctrls_common(fh, hdl, cs, vdev, set); + if (ret) + dprintk(vdev, + "%s: try_set_ext_ctrls_common failed (%d)\n", + video_device_node_name(vdev), ret); + + media_request_unlock_for_update(req); + media_request_object_put(obj); + media_request_put(req); + + return ret; +} + +void v4l2_ctrl_request_complete(struct media_request *req, + struct v4l2_ctrl_handler *main_hdl) +{ + struct media_request_object *obj; + struct v4l2_ctrl_handler *hdl; + struct v4l2_ctrl_ref *ref; + + if (!req || !main_hdl) + return; + + /* + * Note that it is valid if nothing was found. It means + * that this request doesn't have any controls and so just + * wants to leave the controls unchanged. + */ + obj = media_request_object_find(req, &req_ops, main_hdl); + if (!obj) { + int ret; + + /* Create a new request so the driver can return controls */ + hdl = kzalloc(sizeof(*hdl), GFP_KERNEL); + if (!hdl) + return; + + ret = v4l2_ctrl_handler_init(hdl, (main_hdl->nr_of_buckets - 1) * 8); + if (!ret) + ret = v4l2_ctrl_request_bind(req, hdl, main_hdl); + if (ret) { + v4l2_ctrl_handler_free(hdl); + kfree(hdl); + return; + } + hdl->request_is_queued = true; + obj = media_request_object_find(req, &req_ops, main_hdl); + } + hdl = container_of(obj, struct v4l2_ctrl_handler, req_obj); + + list_for_each_entry(ref, &hdl->ctrl_refs, node) { + struct v4l2_ctrl *ctrl = ref->ctrl; + struct v4l2_ctrl *master = ctrl->cluster[0]; + unsigned int i; + + if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) { + v4l2_ctrl_lock(master); + /* g_volatile_ctrl will update the current control values */ + for (i = 0; i < master->ncontrols; i++) + cur_to_new(master->cluster[i]); + call_op(master, g_volatile_ctrl); + new_to_req(ref); + v4l2_ctrl_unlock(master); + continue; + } + if (ref->valid_p_req) + continue; + + /* Copy the current control value into the request */ + v4l2_ctrl_lock(ctrl); + cur_to_req(ref); + v4l2_ctrl_unlock(ctrl); + } + + mutex_lock(main_hdl->lock); + WARN_ON(!hdl->request_is_queued); + list_del_init(&hdl->requests_queued); + hdl->request_is_queued = false; + mutex_unlock(main_hdl->lock); + media_request_object_complete(obj); + media_request_object_put(obj); +} +EXPORT_SYMBOL(v4l2_ctrl_request_complete); + +int v4l2_ctrl_request_setup(struct media_request *req, + struct v4l2_ctrl_handler *main_hdl) +{ + struct media_request_object *obj; + struct v4l2_ctrl_handler *hdl; + struct v4l2_ctrl_ref *ref; + int ret = 0; + + if (!req || !main_hdl) + return 0; + + if (WARN_ON(req->state != MEDIA_REQUEST_STATE_QUEUED)) + return -EBUSY; + + /* + * Note that it is valid if nothing was found. It means + * that this request doesn't have any controls and so just + * wants to leave the controls unchanged. + */ + obj = media_request_object_find(req, &req_ops, main_hdl); + if (!obj) + return 0; + if (obj->completed) { + media_request_object_put(obj); + return -EBUSY; + } + hdl = container_of(obj, struct v4l2_ctrl_handler, req_obj); + + list_for_each_entry(ref, &hdl->ctrl_refs, node) + ref->req_done = false; + + list_for_each_entry(ref, &hdl->ctrl_refs, node) { + struct v4l2_ctrl *ctrl = ref->ctrl; + struct v4l2_ctrl *master = ctrl->cluster[0]; + bool have_new_data = false; + int i; + + /* + * Skip if this control was already handled by a cluster. + * Skip button controls and read-only controls. + */ + if (ref->req_done || (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY)) + continue; + + v4l2_ctrl_lock(master); + for (i = 0; i < master->ncontrols; i++) { + if (master->cluster[i]) { + struct v4l2_ctrl_ref *r = + find_ref(hdl, master->cluster[i]->id); + + if (r->valid_p_req) { + have_new_data = true; + break; + } + } + } + if (!have_new_data) { + v4l2_ctrl_unlock(master); + continue; + } + + for (i = 0; i < master->ncontrols; i++) { + if (master->cluster[i]) { + struct v4l2_ctrl_ref *r = + find_ref(hdl, master->cluster[i]->id); + + req_to_new(r); + master->cluster[i]->is_new = 1; + r->req_done = true; + } + } + /* + * For volatile autoclusters that are currently in auto mode + * we need to discover if it will be set to manual mode. + * If so, then we have to copy the current volatile values + * first since those will become the new manual values (which + * may be overwritten by explicit new values from this set + * of controls). + */ + if (master->is_auto && master->has_volatiles && + !is_cur_manual(master)) { + s32 new_auto_val = *master->p_new.p_s32; + + /* + * If the new value == the manual value, then copy + * the current volatile values. + */ + if (new_auto_val == master->manual_mode_value) + update_from_auto_cluster(master); + } + + ret = try_or_set_cluster(NULL, master, true, 0); + v4l2_ctrl_unlock(master); + + if (ret) + break; + } + + media_request_object_put(obj); + return ret; +} +EXPORT_SYMBOL(v4l2_ctrl_request_setup); diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c deleted file mode 100644 index 09992e76bad6..000000000000 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ /dev/null @@ -1,5111 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - V4L2 controls framework implementation. - - Copyright (C) 2010 Hans Verkuil - - */ - -#define pr_fmt(fmt) "v4l2-ctrls: " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define dprintk(vdev, fmt, arg...) do { \ - if (!WARN_ON(!(vdev)) && ((vdev)->dev_debug & V4L2_DEV_DEBUG_CTRL)) \ - printk(KERN_DEBUG pr_fmt("%s: %s: " fmt), \ - __func__, video_device_node_name(vdev), ##arg); \ -} while (0) - -#define has_op(master, op) \ - (master->ops && master->ops->op) -#define call_op(master, op) \ - (has_op(master, op) ? master->ops->op(master) : 0) - -static const union v4l2_ctrl_ptr ptr_null; - -/* Internal temporary helper struct, one for each v4l2_ext_control */ -struct v4l2_ctrl_helper { - /* Pointer to the control reference of the master control */ - struct v4l2_ctrl_ref *mref; - /* The control ref corresponding to the v4l2_ext_control ID field. */ - struct v4l2_ctrl_ref *ref; - /* v4l2_ext_control index of the next control belonging to the - same cluster, or 0 if there isn't any. */ - u32 next; -}; - -/* Small helper function to determine if the autocluster is set to manual - mode. */ -static bool is_cur_manual(const struct v4l2_ctrl *master) -{ - return master->is_auto && master->cur.val == master->manual_mode_value; -} - -/* Same as above, but this checks the against the new value instead of the - current value. */ -static bool is_new_manual(const struct v4l2_ctrl *master) -{ - return master->is_auto && master->val == master->manual_mode_value; -} - -/* Default intra MPEG-2 quantisation coefficients, from the specification. */ -static const u8 mpeg2_intra_quant_matrix[64] = { - 8, 16, 16, 19, 16, 19, 22, 22, - 22, 22, 22, 22, 26, 24, 26, 27, - 27, 27, 26, 26, 26, 26, 27, 27, - 27, 29, 29, 29, 34, 34, 34, 29, - 29, 29, 27, 27, 29, 29, 32, 32, - 34, 34, 37, 38, 37, 35, 35, 34, - 35, 38, 38, 40, 40, 40, 48, 48, - 46, 46, 56, 56, 58, 69, 69, 83 -}; - -/* Returns NULL or a character pointer array containing the menu for - the given control ID. The pointer array ends with a NULL pointer. - An empty string signifies a menu entry that is invalid. This allows - drivers to disable certain options if it is not supported. */ -const char * const *v4l2_ctrl_get_menu(u32 id) -{ - static const char * const mpeg_audio_sampling_freq[] = { - "44.1 kHz", - "48 kHz", - "32 kHz", - NULL - }; - static const char * const mpeg_audio_encoding[] = { - "MPEG-1/2 Layer I", - "MPEG-1/2 Layer II", - "MPEG-1/2 Layer III", - "MPEG-2/4 AAC", - "AC-3", - NULL - }; - static const char * const mpeg_audio_l1_bitrate[] = { - "32 kbps", - "64 kbps", - "96 kbps", - "128 kbps", - "160 kbps", - "192 kbps", - "224 kbps", - "256 kbps", - "288 kbps", - "320 kbps", - "352 kbps", - "384 kbps", - "416 kbps", - "448 kbps", - NULL - }; - static const char * const mpeg_audio_l2_bitrate[] = { - "32 kbps", - "48 kbps", - "56 kbps", - "64 kbps", - "80 kbps", - "96 kbps", - "112 kbps", - "128 kbps", - "160 kbps", - "192 kbps", - "224 kbps", - "256 kbps", - "320 kbps", - "384 kbps", - NULL - }; - static const char * const mpeg_audio_l3_bitrate[] = { - "32 kbps", - "40 kbps", - "48 kbps", - "56 kbps", - "64 kbps", - "80 kbps", - "96 kbps", - "112 kbps", - "128 kbps", - "160 kbps", - "192 kbps", - "224 kbps", - "256 kbps", - "320 kbps", - NULL - }; - static const char * const mpeg_audio_ac3_bitrate[] = { - "32 kbps", - "40 kbps", - "48 kbps", - "56 kbps", - "64 kbps", - "80 kbps", - "96 kbps", - "112 kbps", - "128 kbps", - "160 kbps", - "192 kbps", - "224 kbps", - "256 kbps", - "320 kbps", - "384 kbps", - "448 kbps", - "512 kbps", - "576 kbps", - "640 kbps", - NULL - }; - static const char * const mpeg_audio_mode[] = { - "Stereo", - "Joint Stereo", - "Dual", - "Mono", - NULL - }; - static const char * const mpeg_audio_mode_extension[] = { - "Bound 4", - "Bound 8", - "Bound 12", - "Bound 16", - NULL - }; - static const char * const mpeg_audio_emphasis[] = { - "No Emphasis", - "50/15 us", - "CCITT J17", - NULL - }; - static const char * const mpeg_audio_crc[] = { - "No CRC", - "16-bit CRC", - NULL - }; - static const char * const mpeg_audio_dec_playback[] = { - "Auto", - "Stereo", - "Left", - "Right", - "Mono", - "Swapped Stereo", - NULL - }; - static const char * const mpeg_video_encoding[] = { - "MPEG-1", - "MPEG-2", - "MPEG-4 AVC", - NULL - }; - static const char * const mpeg_video_aspect[] = { - "1x1", - "4x3", - "16x9", - "2.21x1", - NULL - }; - static const char * const mpeg_video_bitrate_mode[] = { - "Variable Bitrate", - "Constant Bitrate", - "Constant Quality", - NULL - }; - static const char * const mpeg_stream_type[] = { - "MPEG-2 Program Stream", - "MPEG-2 Transport Stream", - "MPEG-1 System Stream", - "MPEG-2 DVD-compatible Stream", - "MPEG-1 VCD-compatible Stream", - "MPEG-2 SVCD-compatible Stream", - NULL - }; - static const char * const mpeg_stream_vbi_fmt[] = { - "No VBI", - "Private Packet, IVTV Format", - NULL - }; - static const char * const camera_power_line_frequency[] = { - "Disabled", - "50 Hz", - "60 Hz", - "Auto", - NULL - }; - static const char * const camera_exposure_auto[] = { - "Auto Mode", - "Manual Mode", - "Shutter Priority Mode", - "Aperture Priority Mode", - NULL - }; - static const char * const camera_exposure_metering[] = { - "Average", - "Center Weighted", - "Spot", - "Matrix", - NULL - }; - static const char * const camera_auto_focus_range[] = { - "Auto", - "Normal", - "Macro", - "Infinity", - NULL - }; - static const char * const colorfx[] = { - "None", - "Black & White", - "Sepia", - "Negative", - "Emboss", - "Sketch", - "Sky Blue", - "Grass Green", - "Skin Whiten", - "Vivid", - "Aqua", - "Art Freeze", - "Silhouette", - "Solarization", - "Antique", - "Set Cb/Cr", - NULL - }; - static const char * const auto_n_preset_white_balance[] = { - "Manual", - "Auto", - "Incandescent", - "Fluorescent", - "Fluorescent H", - "Horizon", - "Daylight", - "Flash", - "Cloudy", - "Shade", - NULL, - }; - static const char * const camera_iso_sensitivity_auto[] = { - "Manual", - "Auto", - NULL - }; - static const char * const scene_mode[] = { - "None", - "Backlight", - "Beach/Snow", - "Candle Light", - "Dusk/Dawn", - "Fall Colors", - "Fireworks", - "Landscape", - "Night", - "Party/Indoor", - "Portrait", - "Sports", - "Sunset", - "Text", - NULL - }; - static const char * const tune_emphasis[] = { - "None", - "50 Microseconds", - "75 Microseconds", - NULL, - }; - static const char * const header_mode[] = { - "Separate Buffer", - "Joined With 1st Frame", - NULL, - }; - static const char * const multi_slice[] = { - "Single", - "Max Macroblocks", - "Max Bytes", - NULL, - }; - static const char * const entropy_mode[] = { - "CAVLC", - "CABAC", - NULL, - }; - static const char * const mpeg_h264_level[] = { - "1", - "1b", - "1.1", - "1.2", - "1.3", - "2", - "2.1", - "2.2", - "3", - "3.1", - "3.2", - "4", - "4.1", - "4.2", - "5", - "5.1", - "5.2", - "6.0", - "6.1", - "6.2", - NULL, - }; - static const char * const h264_loop_filter[] = { - "Enabled", - "Disabled", - "Disabled at Slice Boundary", - NULL, - }; - static const char * const h264_profile[] = { - "Baseline", - "Constrained Baseline", - "Main", - "Extended", - "High", - "High 10", - "High 422", - "High 444 Predictive", - "High 10 Intra", - "High 422 Intra", - "High 444 Intra", - "CAVLC 444 Intra", - "Scalable Baseline", - "Scalable High", - "Scalable High Intra", - "Stereo High", - "Multiview High", - "Constrained High", - NULL, - }; - static const char * const vui_sar_idc[] = { - "Unspecified", - "1:1", - "12:11", - "10:11", - "16:11", - "40:33", - "24:11", - "20:11", - "32:11", - "80:33", - "18:11", - "15:11", - "64:33", - "160:99", - "4:3", - "3:2", - "2:1", - "Extended SAR", - NULL, - }; - static const char * const h264_fp_arrangement_type[] = { - "Checkerboard", - "Column", - "Row", - "Side by Side", - "Top Bottom", - "Temporal", - NULL, - }; - static const char * const h264_fmo_map_type[] = { - "Interleaved Slices", - "Scattered Slices", - "Foreground with Leftover", - "Box Out", - "Raster Scan", - "Wipe Scan", - "Explicit", - NULL, - }; - static const char * const h264_decode_mode[] = { - "Slice-Based", - "Frame-Based", - NULL, - }; - static const char * const h264_start_code[] = { - "No Start Code", - "Annex B Start Code", - NULL, - }; - static const char * const h264_hierarchical_coding_type[] = { - "Hier Coding B", - "Hier Coding P", - NULL, - }; - static const char * const mpeg_mpeg2_level[] = { - "Low", - "Main", - "High 1440", - "High", - NULL, - }; - static const char * const mpeg2_profile[] = { - "Simple", - "Main", - "SNR Scalable", - "Spatially Scalable", - "High", - NULL, - }; - static const char * const mpeg_mpeg4_level[] = { - "0", - "0b", - "1", - "2", - "3", - "3b", - "4", - "5", - NULL, - }; - static const char * const mpeg4_profile[] = { - "Simple", - "Advanced Simple", - "Core", - "Simple Scalable", - "Advanced Coding Efficiency", - NULL, - }; - - static const char * const vpx_golden_frame_sel[] = { - "Use Previous Frame", - "Use Previous Specific Frame", - NULL, - }; - static const char * const vp8_profile[] = { - "0", - "1", - "2", - "3", - NULL, - }; - static const char * const vp9_profile[] = { - "0", - "1", - "2", - "3", - NULL, - }; - static const char * const vp9_level[] = { - "1", - "1.1", - "2", - "2.1", - "3", - "3.1", - "4", - "4.1", - "5", - "5.1", - "5.2", - "6", - "6.1", - "6.2", - NULL, - }; - - static const char * const flash_led_mode[] = { - "Off", - "Flash", - "Torch", - NULL, - }; - static const char * const flash_strobe_source[] = { - "Software", - "External", - NULL, - }; - - static const char * const jpeg_chroma_subsampling[] = { - "4:4:4", - "4:2:2", - "4:2:0", - "4:1:1", - "4:1:0", - "Gray", - NULL, - }; - static const char * const dv_tx_mode[] = { - "DVI-D", - "HDMI", - NULL, - }; - static const char * const dv_rgb_range[] = { - "Automatic", - "RGB Limited Range (16-235)", - "RGB Full Range (0-255)", - NULL, - }; - static const char * const dv_it_content_type[] = { - "Graphics", - "Photo", - "Cinema", - "Game", - "No IT Content", - NULL, - }; - static const char * const detect_md_mode[] = { - "Disabled", - "Global", - "Threshold Grid", - "Region Grid", - NULL, - }; - - static const char * const hevc_profile[] = { - "Main", - "Main Still Picture", - "Main 10", - NULL, - }; - static const char * const hevc_level[] = { - "1", - "2", - "2.1", - "3", - "3.1", - "4", - "4.1", - "5", - "5.1", - "5.2", - "6", - "6.1", - "6.2", - NULL, - }; - static const char * const hevc_hierarchial_coding_type[] = { - "B", - "P", - NULL, - }; - static const char * const hevc_refresh_type[] = { - "None", - "CRA", - "IDR", - NULL, - }; - static const char * const hevc_size_of_length_field[] = { - "0", - "1", - "2", - "4", - NULL, - }; - static const char * const hevc_tier[] = { - "Main", - "High", - NULL, - }; - static const char * const hevc_loop_filter_mode[] = { - "Disabled", - "Enabled", - "Disabled at slice boundary", - "NULL", - }; - static const char * const hevc_decode_mode[] = { - "Slice-Based", - "Frame-Based", - NULL, - }; - static const char * const hevc_start_code[] = { - "No Start Code", - "Annex B Start Code", - NULL, - }; - static const char * const camera_orientation[] = { - "Front", - "Back", - "External", - NULL, - }; - static const char * const mpeg_video_frame_skip[] = { - "Disabled", - "Level Limit", - "VBV/CPB Limit", - NULL, - }; - - switch (id) { - case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: - return mpeg_audio_sampling_freq; - case V4L2_CID_MPEG_AUDIO_ENCODING: - return mpeg_audio_encoding; - case V4L2_CID_MPEG_AUDIO_L1_BITRATE: - return mpeg_audio_l1_bitrate; - case V4L2_CID_MPEG_AUDIO_L2_BITRATE: - return mpeg_audio_l2_bitrate; - case V4L2_CID_MPEG_AUDIO_L3_BITRATE: - return mpeg_audio_l3_bitrate; - case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: - return mpeg_audio_ac3_bitrate; - case V4L2_CID_MPEG_AUDIO_MODE: - return mpeg_audio_mode; - case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: - return mpeg_audio_mode_extension; - case V4L2_CID_MPEG_AUDIO_EMPHASIS: - return mpeg_audio_emphasis; - case V4L2_CID_MPEG_AUDIO_CRC: - return mpeg_audio_crc; - case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK: - case V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK: - return mpeg_audio_dec_playback; - case V4L2_CID_MPEG_VIDEO_ENCODING: - return mpeg_video_encoding; - case V4L2_CID_MPEG_VIDEO_ASPECT: - return mpeg_video_aspect; - case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: - return mpeg_video_bitrate_mode; - case V4L2_CID_MPEG_STREAM_TYPE: - return mpeg_stream_type; - case V4L2_CID_MPEG_STREAM_VBI_FMT: - return mpeg_stream_vbi_fmt; - case V4L2_CID_POWER_LINE_FREQUENCY: - return camera_power_line_frequency; - case V4L2_CID_EXPOSURE_AUTO: - return camera_exposure_auto; - case V4L2_CID_EXPOSURE_METERING: - return camera_exposure_metering; - case V4L2_CID_AUTO_FOCUS_RANGE: - return camera_auto_focus_range; - case V4L2_CID_COLORFX: - return colorfx; - case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE: - return auto_n_preset_white_balance; - case V4L2_CID_ISO_SENSITIVITY_AUTO: - return camera_iso_sensitivity_auto; - case V4L2_CID_SCENE_MODE: - return scene_mode; - case V4L2_CID_TUNE_PREEMPHASIS: - return tune_emphasis; - case V4L2_CID_TUNE_DEEMPHASIS: - return tune_emphasis; - case V4L2_CID_FLASH_LED_MODE: - return flash_led_mode; - case V4L2_CID_FLASH_STROBE_SOURCE: - return flash_strobe_source; - case V4L2_CID_MPEG_VIDEO_HEADER_MODE: - return header_mode; - case V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE: - return mpeg_video_frame_skip; - case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: - return multi_slice; - case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: - return entropy_mode; - case V4L2_CID_MPEG_VIDEO_H264_LEVEL: - return mpeg_h264_level; - case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE: - return h264_loop_filter; - case V4L2_CID_MPEG_VIDEO_H264_PROFILE: - return h264_profile; - case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC: - return vui_sar_idc; - case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE: - return h264_fp_arrangement_type; - case V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE: - return h264_fmo_map_type; - case V4L2_CID_STATELESS_H264_DECODE_MODE: - return h264_decode_mode; - case V4L2_CID_STATELESS_H264_START_CODE: - return h264_start_code; - case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE: - return h264_hierarchical_coding_type; - case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL: - return mpeg_mpeg2_level; - case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE: - return mpeg2_profile; - case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: - return mpeg_mpeg4_level; - case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: - return mpeg4_profile; - case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL: - return vpx_golden_frame_sel; - case V4L2_CID_MPEG_VIDEO_VP8_PROFILE: - return vp8_profile; - case V4L2_CID_MPEG_VIDEO_VP9_PROFILE: - return vp9_profile; - case V4L2_CID_MPEG_VIDEO_VP9_LEVEL: - return vp9_level; - case V4L2_CID_JPEG_CHROMA_SUBSAMPLING: - return jpeg_chroma_subsampling; - case V4L2_CID_DV_TX_MODE: - return dv_tx_mode; - case V4L2_CID_DV_TX_RGB_RANGE: - case V4L2_CID_DV_RX_RGB_RANGE: - return dv_rgb_range; - case V4L2_CID_DV_TX_IT_CONTENT_TYPE: - case V4L2_CID_DV_RX_IT_CONTENT_TYPE: - return dv_it_content_type; - case V4L2_CID_DETECT_MD_MODE: - return detect_md_mode; - case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: - return hevc_profile; - case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: - return hevc_level; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE: - return hevc_hierarchial_coding_type; - case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE: - return hevc_refresh_type; - case V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD: - return hevc_size_of_length_field; - case V4L2_CID_MPEG_VIDEO_HEVC_TIER: - return hevc_tier; - case V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE: - return hevc_loop_filter_mode; - case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE: - return hevc_decode_mode; - case V4L2_CID_MPEG_VIDEO_HEVC_START_CODE: - return hevc_start_code; - case V4L2_CID_CAMERA_ORIENTATION: - return camera_orientation; - default: - return NULL; - } -} -EXPORT_SYMBOL(v4l2_ctrl_get_menu); - -#define __v4l2_qmenu_int_len(arr, len) ({ *(len) = ARRAY_SIZE(arr); arr; }) -/* - * Returns NULL or an s64 type array containing the menu for given - * control ID. The total number of the menu items is returned in @len. - */ -const s64 *v4l2_ctrl_get_int_menu(u32 id, u32 *len) -{ - static const s64 qmenu_int_vpx_num_partitions[] = { - 1, 2, 4, 8, - }; - - static const s64 qmenu_int_vpx_num_ref_frames[] = { - 1, 2, 3, - }; - - switch (id) { - case V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS: - return __v4l2_qmenu_int_len(qmenu_int_vpx_num_partitions, len); - case V4L2_CID_MPEG_VIDEO_VPX_NUM_REF_FRAMES: - return __v4l2_qmenu_int_len(qmenu_int_vpx_num_ref_frames, len); - default: - *len = 0; - return NULL; - } -} -EXPORT_SYMBOL(v4l2_ctrl_get_int_menu); - -/* Return the control name. */ -const char *v4l2_ctrl_get_name(u32 id) -{ - switch (id) { - /* USER controls */ - /* Keep the order of the 'case's the same as in v4l2-controls.h! */ - case V4L2_CID_USER_CLASS: return "User Controls"; - case V4L2_CID_BRIGHTNESS: return "Brightness"; - case V4L2_CID_CONTRAST: return "Contrast"; - case V4L2_CID_SATURATION: return "Saturation"; - case V4L2_CID_HUE: return "Hue"; - case V4L2_CID_AUDIO_VOLUME: return "Volume"; - case V4L2_CID_AUDIO_BALANCE: return "Balance"; - case V4L2_CID_AUDIO_BASS: return "Bass"; - case V4L2_CID_AUDIO_TREBLE: return "Treble"; - case V4L2_CID_AUDIO_MUTE: return "Mute"; - case V4L2_CID_AUDIO_LOUDNESS: return "Loudness"; - case V4L2_CID_BLACK_LEVEL: return "Black Level"; - case V4L2_CID_AUTO_WHITE_BALANCE: return "White Balance, Automatic"; - case V4L2_CID_DO_WHITE_BALANCE: return "Do White Balance"; - case V4L2_CID_RED_BALANCE: return "Red Balance"; - case V4L2_CID_BLUE_BALANCE: return "Blue Balance"; - case V4L2_CID_GAMMA: return "Gamma"; - case V4L2_CID_EXPOSURE: return "Exposure"; - case V4L2_CID_AUTOGAIN: return "Gain, Automatic"; - case V4L2_CID_GAIN: return "Gain"; - case V4L2_CID_HFLIP: return "Horizontal Flip"; - case V4L2_CID_VFLIP: return "Vertical Flip"; - case V4L2_CID_POWER_LINE_FREQUENCY: return "Power Line Frequency"; - case V4L2_CID_HUE_AUTO: return "Hue, Automatic"; - case V4L2_CID_WHITE_BALANCE_TEMPERATURE: return "White Balance Temperature"; - case V4L2_CID_SHARPNESS: return "Sharpness"; - case V4L2_CID_BACKLIGHT_COMPENSATION: return "Backlight Compensation"; - case V4L2_CID_CHROMA_AGC: return "Chroma AGC"; - case V4L2_CID_COLOR_KILLER: return "Color Killer"; - case V4L2_CID_COLORFX: return "Color Effects"; - case V4L2_CID_AUTOBRIGHTNESS: return "Brightness, Automatic"; - case V4L2_CID_BAND_STOP_FILTER: return "Band-Stop Filter"; - case V4L2_CID_ROTATE: return "Rotate"; - case V4L2_CID_BG_COLOR: return "Background Color"; - case V4L2_CID_CHROMA_GAIN: return "Chroma Gain"; - case V4L2_CID_ILLUMINATORS_1: return "Illuminator 1"; - case V4L2_CID_ILLUMINATORS_2: return "Illuminator 2"; - case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: return "Min Number of Capture Buffers"; - case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: return "Min Number of Output Buffers"; - case V4L2_CID_ALPHA_COMPONENT: return "Alpha Component"; - case V4L2_CID_COLORFX_CBCR: return "Color Effects, CbCr"; - - /* Codec controls */ - /* The MPEG controls are applicable to all codec controls - * and the 'MPEG' part of the define is historical */ - /* Keep the order of the 'case's the same as in videodev2.h! */ - case V4L2_CID_CODEC_CLASS: return "Codec Controls"; - case V4L2_CID_MPEG_STREAM_TYPE: return "Stream Type"; - case V4L2_CID_MPEG_STREAM_PID_PMT: return "Stream PMT Program ID"; - case V4L2_CID_MPEG_STREAM_PID_AUDIO: return "Stream Audio Program ID"; - case V4L2_CID_MPEG_STREAM_PID_VIDEO: return "Stream Video Program ID"; - case V4L2_CID_MPEG_STREAM_PID_PCR: return "Stream PCR Program ID"; - case V4L2_CID_MPEG_STREAM_PES_ID_AUDIO: return "Stream PES Audio ID"; - case V4L2_CID_MPEG_STREAM_PES_ID_VIDEO: return "Stream PES Video ID"; - case V4L2_CID_MPEG_STREAM_VBI_FMT: return "Stream VBI Format"; - case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: return "Audio Sampling Frequency"; - case V4L2_CID_MPEG_AUDIO_ENCODING: return "Audio Encoding"; - case V4L2_CID_MPEG_AUDIO_L1_BITRATE: return "Audio Layer I Bitrate"; - case V4L2_CID_MPEG_AUDIO_L2_BITRATE: return "Audio Layer II Bitrate"; - case V4L2_CID_MPEG_AUDIO_L3_BITRATE: return "Audio Layer III Bitrate"; - case V4L2_CID_MPEG_AUDIO_MODE: return "Audio Stereo Mode"; - case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: return "Audio Stereo Mode Extension"; - case V4L2_CID_MPEG_AUDIO_EMPHASIS: return "Audio Emphasis"; - case V4L2_CID_MPEG_AUDIO_CRC: return "Audio CRC"; - case V4L2_CID_MPEG_AUDIO_MUTE: return "Audio Mute"; - case V4L2_CID_MPEG_AUDIO_AAC_BITRATE: return "Audio AAC Bitrate"; - case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: return "Audio AC-3 Bitrate"; - case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK: return "Audio Playback"; - case V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK: return "Audio Multilingual Playback"; - case V4L2_CID_MPEG_VIDEO_ENCODING: return "Video Encoding"; - case V4L2_CID_MPEG_VIDEO_ASPECT: return "Video Aspect"; - case V4L2_CID_MPEG_VIDEO_B_FRAMES: return "Video B Frames"; - case V4L2_CID_MPEG_VIDEO_GOP_SIZE: return "Video GOP Size"; - case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: return "Video GOP Closure"; - case V4L2_CID_MPEG_VIDEO_PULLDOWN: return "Video Pulldown"; - case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: return "Video Bitrate Mode"; - case V4L2_CID_MPEG_VIDEO_CONSTANT_QUALITY: return "Constant Quality"; - case V4L2_CID_MPEG_VIDEO_BITRATE: return "Video Bitrate"; - case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: return "Video Peak Bitrate"; - case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION: return "Video Temporal Decimation"; - case V4L2_CID_MPEG_VIDEO_MUTE: return "Video Mute"; - case V4L2_CID_MPEG_VIDEO_MUTE_YUV: return "Video Mute YUV"; - case V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE: return "Decoder Slice Interface"; - case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER: return "MPEG4 Loop Filter Enable"; - case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB: return "Number of Intra Refresh MBs"; - case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE: return "Frame Level Rate Control Enable"; - case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE: return "H264 MB Level Rate Control"; - case V4L2_CID_MPEG_VIDEO_HEADER_MODE: return "Sequence Header Mode"; - case V4L2_CID_MPEG_VIDEO_MAX_REF_PIC: return "Max Number of Reference Pics"; - case V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE: return "Frame Skip Mode"; - case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY: return "Display Delay"; - case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY_ENABLE: return "Display Delay Enable"; - case V4L2_CID_MPEG_VIDEO_AU_DELIMITER: return "Generate Access Unit Delimiters"; - case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP: return "H263 I-Frame QP Value"; - case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP: return "H263 P-Frame QP Value"; - case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP: return "H263 B-Frame QP Value"; - case V4L2_CID_MPEG_VIDEO_H263_MIN_QP: return "H263 Minimum QP Value"; - case V4L2_CID_MPEG_VIDEO_H263_MAX_QP: return "H263 Maximum QP Value"; - case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP: return "H264 I-Frame QP Value"; - case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP: return "H264 P-Frame QP Value"; - case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP: return "H264 B-Frame QP Value"; - case V4L2_CID_MPEG_VIDEO_H264_MAX_QP: return "H264 Maximum QP Value"; - case V4L2_CID_MPEG_VIDEO_H264_MIN_QP: return "H264 Minimum QP Value"; - case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM: return "H264 8x8 Transform Enable"; - case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE: return "H264 CPB Buffer Size"; - case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: return "H264 Entropy Mode"; - case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD: return "H264 I-Frame Period"; - case V4L2_CID_MPEG_VIDEO_H264_LEVEL: return "H264 Level"; - case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA: return "H264 Loop Filter Alpha Offset"; - case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA: return "H264 Loop Filter Beta Offset"; - case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE: return "H264 Loop Filter Mode"; - case V4L2_CID_MPEG_VIDEO_H264_PROFILE: return "H264 Profile"; - case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT: return "Vertical Size of SAR"; - case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH: return "Horizontal Size of SAR"; - case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE: return "Aspect Ratio VUI Enable"; - case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC: return "VUI Aspect Ratio IDC"; - case V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING: return "H264 Enable Frame Packing SEI"; - case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_CURRENT_FRAME_0: return "H264 Set Curr. Frame as Frame0"; - case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE: return "H264 FP Arrangement Type"; - case V4L2_CID_MPEG_VIDEO_H264_FMO: return "H264 Flexible MB Ordering"; - case V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE: return "H264 Map Type for FMO"; - case V4L2_CID_MPEG_VIDEO_H264_FMO_SLICE_GROUP: return "H264 FMO Number of Slice Groups"; - case V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_DIRECTION: return "H264 FMO Direction of Change"; - case V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_RATE: return "H264 FMO Size of 1st Slice Grp"; - case V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH: return "H264 FMO No. of Consecutive MBs"; - case V4L2_CID_MPEG_VIDEO_H264_ASO: return "H264 Arbitrary Slice Ordering"; - case V4L2_CID_MPEG_VIDEO_H264_ASO_SLICE_ORDER: return "H264 ASO Slice Order"; - case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING: return "Enable H264 Hierarchical Coding"; - case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE: return "H264 Hierarchical Coding Type"; - case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER:return "H264 Number of HC Layers"; - case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP: - return "H264 Set QP Value for HC Layers"; - case V4L2_CID_MPEG_VIDEO_H264_CONSTRAINED_INTRA_PREDICTION: - return "H264 Constrained Intra Pred"; - case V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET: return "H264 Chroma QP Index Offset"; - case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP: return "H264 I-Frame Minimum QP Value"; - case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP: return "H264 I-Frame Maximum QP Value"; - case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP: return "H264 P-Frame Minimum QP Value"; - case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP: return "H264 P-Frame Maximum QP Value"; - case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MIN_QP: return "H264 B-Frame Minimum QP Value"; - case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MAX_QP: return "H264 B-Frame Maximum QP Value"; - case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L0_BR: return "H264 Hierarchical Lay 0 Bitrate"; - case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L1_BR: return "H264 Hierarchical Lay 1 Bitrate"; - case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L2_BR: return "H264 Hierarchical Lay 2 Bitrate"; - case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L3_BR: return "H264 Hierarchical Lay 3 Bitrate"; - case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L4_BR: return "H264 Hierarchical Lay 4 Bitrate"; - case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L5_BR: return "H264 Hierarchical Lay 5 Bitrate"; - case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L6_BR: return "H264 Hierarchical Lay 6 Bitrate"; - case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL: return "MPEG2 Level"; - case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE: return "MPEG2 Profile"; - case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP: return "MPEG4 I-Frame QP Value"; - case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP: return "MPEG4 P-Frame QP Value"; - case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP: return "MPEG4 B-Frame QP Value"; - case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP: return "MPEG4 Minimum QP Value"; - case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP: return "MPEG4 Maximum QP Value"; - case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: return "MPEG4 Level"; - case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: return "MPEG4 Profile"; - case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL: return "Quarter Pixel Search Enable"; - case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES: return "Maximum Bytes in a Slice"; - case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB: return "Number of MBs in a Slice"; - case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: return "Slice Partitioning Method"; - case V4L2_CID_MPEG_VIDEO_VBV_SIZE: return "VBV Buffer Size"; - case V4L2_CID_MPEG_VIDEO_DEC_PTS: return "Video Decoder PTS"; - case V4L2_CID_MPEG_VIDEO_DEC_FRAME: return "Video Decoder Frame Count"; - case V4L2_CID_MPEG_VIDEO_DEC_CONCEAL_COLOR: return "Video Decoder Conceal Color"; - case V4L2_CID_MPEG_VIDEO_VBV_DELAY: return "Initial Delay for VBV Control"; - case V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE: return "Horizontal MV Search Range"; - case V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE: return "Vertical MV Search Range"; - case V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER: return "Repeat Sequence Header"; - case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME: return "Force Key Frame"; - case V4L2_CID_MPEG_VIDEO_BASELAYER_PRIORITY_ID: return "Base Layer Priority ID"; - case V4L2_CID_MPEG_VIDEO_LTR_COUNT: return "LTR Count"; - case V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX: return "Frame LTR Index"; - case V4L2_CID_MPEG_VIDEO_USE_LTR_FRAMES: return "Use LTR Frames"; - case V4L2_CID_FWHT_I_FRAME_QP: return "FWHT I-Frame QP Value"; - case V4L2_CID_FWHT_P_FRAME_QP: return "FWHT P-Frame QP Value"; - - /* VPX controls */ - case V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS: return "VPX Number of Partitions"; - case V4L2_CID_MPEG_VIDEO_VPX_IMD_DISABLE_4X4: return "VPX Intra Mode Decision Disable"; - case V4L2_CID_MPEG_VIDEO_VPX_NUM_REF_FRAMES: return "VPX No. of Refs for P Frame"; - case V4L2_CID_MPEG_VIDEO_VPX_FILTER_LEVEL: return "VPX Loop Filter Level Range"; - case V4L2_CID_MPEG_VIDEO_VPX_FILTER_SHARPNESS: return "VPX Deblocking Effect Control"; - case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_REF_PERIOD: return "VPX Golden Frame Refresh Period"; - case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL: return "VPX Golden Frame Indicator"; - case V4L2_CID_MPEG_VIDEO_VPX_MIN_QP: return "VPX Minimum QP Value"; - case V4L2_CID_MPEG_VIDEO_VPX_MAX_QP: return "VPX Maximum QP Value"; - case V4L2_CID_MPEG_VIDEO_VPX_I_FRAME_QP: return "VPX I-Frame QP Value"; - case V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP: return "VPX P-Frame QP Value"; - case V4L2_CID_MPEG_VIDEO_VP8_PROFILE: return "VP8 Profile"; - case V4L2_CID_MPEG_VIDEO_VP9_PROFILE: return "VP9 Profile"; - case V4L2_CID_MPEG_VIDEO_VP9_LEVEL: return "VP9 Level"; - - /* HEVC controls */ - case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP: return "HEVC I-Frame QP Value"; - case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP: return "HEVC P-Frame QP Value"; - case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP: return "HEVC B-Frame QP Value"; - case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP: return "HEVC Minimum QP Value"; - case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP: return "HEVC Maximum QP Value"; - case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MIN_QP: return "HEVC I-Frame Minimum QP Value"; - case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MAX_QP: return "HEVC I-Frame Maximum QP Value"; - case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MIN_QP: return "HEVC P-Frame Minimum QP Value"; - case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MAX_QP: return "HEVC P-Frame Maximum QP Value"; - case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MIN_QP: return "HEVC B-Frame Minimum QP Value"; - case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MAX_QP: return "HEVC B-Frame Maximum QP Value"; - case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: return "HEVC Profile"; - case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: return "HEVC Level"; - case V4L2_CID_MPEG_VIDEO_HEVC_TIER: return "HEVC Tier"; - case V4L2_CID_MPEG_VIDEO_HEVC_FRAME_RATE_RESOLUTION: return "HEVC Frame Rate Resolution"; - case V4L2_CID_MPEG_VIDEO_HEVC_MAX_PARTITION_DEPTH: return "HEVC Maximum Coding Unit Depth"; - case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE: return "HEVC Refresh Type"; - case V4L2_CID_MPEG_VIDEO_HEVC_CONST_INTRA_PRED: return "HEVC Constant Intra Prediction"; - case V4L2_CID_MPEG_VIDEO_HEVC_LOSSLESS_CU: return "HEVC Lossless Encoding"; - case V4L2_CID_MPEG_VIDEO_HEVC_WAVEFRONT: return "HEVC Wavefront"; - case V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE: return "HEVC Loop Filter"; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_QP: return "HEVC QP Values"; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE: return "HEVC Hierarchical Coding Type"; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER: return "HEVC Hierarchical Coding Layer"; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_QP: return "HEVC Hierarchical Layer 0 QP"; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_QP: return "HEVC Hierarchical Layer 1 QP"; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_QP: return "HEVC Hierarchical Layer 2 QP"; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_QP: return "HEVC Hierarchical Layer 3 QP"; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_QP: return "HEVC Hierarchical Layer 4 QP"; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_QP: return "HEVC Hierarchical Layer 5 QP"; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_QP: return "HEVC Hierarchical Layer 6 QP"; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_BR: return "HEVC Hierarchical Lay 0 BitRate"; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_BR: return "HEVC Hierarchical Lay 1 BitRate"; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_BR: return "HEVC Hierarchical Lay 2 BitRate"; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_BR: return "HEVC Hierarchical Lay 3 BitRate"; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_BR: return "HEVC Hierarchical Lay 4 BitRate"; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR: return "HEVC Hierarchical Lay 5 BitRate"; - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_BR: return "HEVC Hierarchical Lay 6 BitRate"; - case V4L2_CID_MPEG_VIDEO_HEVC_GENERAL_PB: return "HEVC General PB"; - case V4L2_CID_MPEG_VIDEO_HEVC_TEMPORAL_ID: return "HEVC Temporal ID"; - case V4L2_CID_MPEG_VIDEO_HEVC_STRONG_SMOOTHING: return "HEVC Strong Intra Smoothing"; - case V4L2_CID_MPEG_VIDEO_HEVC_INTRA_PU_SPLIT: return "HEVC Intra PU Split"; - case V4L2_CID_MPEG_VIDEO_HEVC_TMV_PREDICTION: return "HEVC TMV Prediction"; - case V4L2_CID_MPEG_VIDEO_HEVC_MAX_NUM_MERGE_MV_MINUS1: return "HEVC Max Num of Candidate MVs"; - case V4L2_CID_MPEG_VIDEO_HEVC_WITHOUT_STARTCODE: return "HEVC ENC Without Startcode"; - case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_PERIOD: return "HEVC Num of I-Frame b/w 2 IDR"; - case V4L2_CID_MPEG_VIDEO_HEVC_LF_BETA_OFFSET_DIV2: return "HEVC Loop Filter Beta Offset"; - case V4L2_CID_MPEG_VIDEO_HEVC_LF_TC_OFFSET_DIV2: return "HEVC Loop Filter TC Offset"; - case V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD: return "HEVC Size of Length Field"; - case V4L2_CID_MPEG_VIDEO_REF_NUMBER_FOR_PFRAMES: return "Reference Frames for a P-Frame"; - case V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR: return "Prepend SPS and PPS to IDR"; - case V4L2_CID_MPEG_VIDEO_HEVC_SPS: return "HEVC Sequence Parameter Set"; - case V4L2_CID_MPEG_VIDEO_HEVC_PPS: return "HEVC Picture Parameter Set"; - case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS: return "HEVC Slice Parameters"; - case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE: return "HEVC Decode Mode"; - case V4L2_CID_MPEG_VIDEO_HEVC_START_CODE: return "HEVC Start Code"; - - /* CAMERA controls */ - /* Keep the order of the 'case's the same as in v4l2-controls.h! */ - case V4L2_CID_CAMERA_CLASS: return "Camera Controls"; - case V4L2_CID_EXPOSURE_AUTO: return "Auto Exposure"; - case V4L2_CID_EXPOSURE_ABSOLUTE: return "Exposure Time, Absolute"; - case V4L2_CID_EXPOSURE_AUTO_PRIORITY: return "Exposure, Dynamic Framerate"; - case V4L2_CID_PAN_RELATIVE: return "Pan, Relative"; - case V4L2_CID_TILT_RELATIVE: return "Tilt, Relative"; - case V4L2_CID_PAN_RESET: return "Pan, Reset"; - case V4L2_CID_TILT_RESET: return "Tilt, Reset"; - case V4L2_CID_PAN_ABSOLUTE: return "Pan, Absolute"; - case V4L2_CID_TILT_ABSOLUTE: return "Tilt, Absolute"; - case V4L2_CID_FOCUS_ABSOLUTE: return "Focus, Absolute"; - case V4L2_CID_FOCUS_RELATIVE: return "Focus, Relative"; - case V4L2_CID_FOCUS_AUTO: return "Focus, Automatic Continuous"; - case V4L2_CID_ZOOM_ABSOLUTE: return "Zoom, Absolute"; - case V4L2_CID_ZOOM_RELATIVE: return "Zoom, Relative"; - case V4L2_CID_ZOOM_CONTINUOUS: return "Zoom, Continuous"; - case V4L2_CID_PRIVACY: return "Privacy"; - case V4L2_CID_IRIS_ABSOLUTE: return "Iris, Absolute"; - case V4L2_CID_IRIS_RELATIVE: return "Iris, Relative"; - case V4L2_CID_AUTO_EXPOSURE_BIAS: return "Auto Exposure, Bias"; - case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE: return "White Balance, Auto & Preset"; - case V4L2_CID_WIDE_DYNAMIC_RANGE: return "Wide Dynamic Range"; - case V4L2_CID_IMAGE_STABILIZATION: return "Image Stabilization"; - case V4L2_CID_ISO_SENSITIVITY: return "ISO Sensitivity"; - case V4L2_CID_ISO_SENSITIVITY_AUTO: return "ISO Sensitivity, Auto"; - case V4L2_CID_EXPOSURE_METERING: return "Exposure, Metering Mode"; - case V4L2_CID_SCENE_MODE: return "Scene Mode"; - case V4L2_CID_3A_LOCK: return "3A Lock"; - case V4L2_CID_AUTO_FOCUS_START: return "Auto Focus, Start"; - case V4L2_CID_AUTO_FOCUS_STOP: return "Auto Focus, Stop"; - case V4L2_CID_AUTO_FOCUS_STATUS: return "Auto Focus, Status"; - case V4L2_CID_AUTO_FOCUS_RANGE: return "Auto Focus, Range"; - case V4L2_CID_PAN_SPEED: return "Pan, Speed"; - case V4L2_CID_TILT_SPEED: return "Tilt, Speed"; - case V4L2_CID_UNIT_CELL_SIZE: return "Unit Cell Size"; - case V4L2_CID_CAMERA_ORIENTATION: return "Camera Orientation"; - case V4L2_CID_CAMERA_SENSOR_ROTATION: return "Camera Sensor Rotation"; - - /* FM Radio Modulator controls */ - /* Keep the order of the 'case's the same as in v4l2-controls.h! */ - case V4L2_CID_FM_TX_CLASS: return "FM Radio Modulator Controls"; - case V4L2_CID_RDS_TX_DEVIATION: return "RDS Signal Deviation"; - case V4L2_CID_RDS_TX_PI: return "RDS Program ID"; - case V4L2_CID_RDS_TX_PTY: return "RDS Program Type"; - case V4L2_CID_RDS_TX_PS_NAME: return "RDS PS Name"; - case V4L2_CID_RDS_TX_RADIO_TEXT: return "RDS Radio Text"; - case V4L2_CID_RDS_TX_MONO_STEREO: return "RDS Stereo"; - case V4L2_CID_RDS_TX_ARTIFICIAL_HEAD: return "RDS Artificial Head"; - case V4L2_CID_RDS_TX_COMPRESSED: return "RDS Compressed"; - case V4L2_CID_RDS_TX_DYNAMIC_PTY: return "RDS Dynamic PTY"; - case V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT: return "RDS Traffic Announcement"; - case V4L2_CID_RDS_TX_TRAFFIC_PROGRAM: return "RDS Traffic Program"; - case V4L2_CID_RDS_TX_MUSIC_SPEECH: return "RDS Music"; - case V4L2_CID_RDS_TX_ALT_FREQS_ENABLE: return "RDS Enable Alt Frequencies"; - case V4L2_CID_RDS_TX_ALT_FREQS: return "RDS Alternate Frequencies"; - case V4L2_CID_AUDIO_LIMITER_ENABLED: return "Audio Limiter Feature Enabled"; - case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME: return "Audio Limiter Release Time"; - case V4L2_CID_AUDIO_LIMITER_DEVIATION: return "Audio Limiter Deviation"; - case V4L2_CID_AUDIO_COMPRESSION_ENABLED: return "Audio Compression Enabled"; - case V4L2_CID_AUDIO_COMPRESSION_GAIN: return "Audio Compression Gain"; - case V4L2_CID_AUDIO_COMPRESSION_THRESHOLD: return "Audio Compression Threshold"; - case V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME: return "Audio Compression Attack Time"; - case V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME: return "Audio Compression Release Time"; - case V4L2_CID_PILOT_TONE_ENABLED: return "Pilot Tone Feature Enabled"; - case V4L2_CID_PILOT_TONE_DEVIATION: return "Pilot Tone Deviation"; - case V4L2_CID_PILOT_TONE_FREQUENCY: return "Pilot Tone Frequency"; - case V4L2_CID_TUNE_PREEMPHASIS: return "Pre-Emphasis"; - case V4L2_CID_TUNE_POWER_LEVEL: return "Tune Power Level"; - case V4L2_CID_TUNE_ANTENNA_CAPACITOR: return "Tune Antenna Capacitor"; - - /* Flash controls */ - /* Keep the order of the 'case's the same as in v4l2-controls.h! */ - case V4L2_CID_FLASH_CLASS: return "Flash Controls"; - case V4L2_CID_FLASH_LED_MODE: return "LED Mode"; - case V4L2_CID_FLASH_STROBE_SOURCE: return "Strobe Source"; - case V4L2_CID_FLASH_STROBE: return "Strobe"; - case V4L2_CID_FLASH_STROBE_STOP: return "Stop Strobe"; - case V4L2_CID_FLASH_STROBE_STATUS: return "Strobe Status"; - case V4L2_CID_FLASH_TIMEOUT: return "Strobe Timeout"; - case V4L2_CID_FLASH_INTENSITY: return "Intensity, Flash Mode"; - case V4L2_CID_FLASH_TORCH_INTENSITY: return "Intensity, Torch Mode"; - case V4L2_CID_FLASH_INDICATOR_INTENSITY: return "Intensity, Indicator"; - case V4L2_CID_FLASH_FAULT: return "Faults"; - case V4L2_CID_FLASH_CHARGE: return "Charge"; - case V4L2_CID_FLASH_READY: return "Ready to Strobe"; - - /* JPEG encoder controls */ - /* Keep the order of the 'case's the same as in v4l2-controls.h! */ - case V4L2_CID_JPEG_CLASS: return "JPEG Compression Controls"; - case V4L2_CID_JPEG_CHROMA_SUBSAMPLING: return "Chroma Subsampling"; - case V4L2_CID_JPEG_RESTART_INTERVAL: return "Restart Interval"; - case V4L2_CID_JPEG_COMPRESSION_QUALITY: return "Compression Quality"; - case V4L2_CID_JPEG_ACTIVE_MARKER: return "Active Markers"; - - /* Image source controls */ - /* Keep the order of the 'case's the same as in v4l2-controls.h! */ - case V4L2_CID_IMAGE_SOURCE_CLASS: return "Image Source Controls"; - case V4L2_CID_VBLANK: return "Vertical Blanking"; - case V4L2_CID_HBLANK: return "Horizontal Blanking"; - case V4L2_CID_ANALOGUE_GAIN: return "Analogue Gain"; - case V4L2_CID_TEST_PATTERN_RED: return "Red Pixel Value"; - case V4L2_CID_TEST_PATTERN_GREENR: return "Green (Red) Pixel Value"; - case V4L2_CID_TEST_PATTERN_BLUE: return "Blue Pixel Value"; - case V4L2_CID_TEST_PATTERN_GREENB: return "Green (Blue) Pixel Value"; - - /* Image processing controls */ - /* Keep the order of the 'case's the same as in v4l2-controls.h! */ - case V4L2_CID_IMAGE_PROC_CLASS: return "Image Processing Controls"; - case V4L2_CID_LINK_FREQ: return "Link Frequency"; - case V4L2_CID_PIXEL_RATE: return "Pixel Rate"; - case V4L2_CID_TEST_PATTERN: return "Test Pattern"; - case V4L2_CID_DEINTERLACING_MODE: return "Deinterlacing Mode"; - case V4L2_CID_DIGITAL_GAIN: return "Digital Gain"; - - /* DV controls */ - /* Keep the order of the 'case's the same as in v4l2-controls.h! */ - case V4L2_CID_DV_CLASS: return "Digital Video Controls"; - case V4L2_CID_DV_TX_HOTPLUG: return "Hotplug Present"; - case V4L2_CID_DV_TX_RXSENSE: return "RxSense Present"; - case V4L2_CID_DV_TX_EDID_PRESENT: return "EDID Present"; - case V4L2_CID_DV_TX_MODE: return "Transmit Mode"; - case V4L2_CID_DV_TX_RGB_RANGE: return "Tx RGB Quantization Range"; - case V4L2_CID_DV_TX_IT_CONTENT_TYPE: return "Tx IT Content Type"; - case V4L2_CID_DV_RX_POWER_PRESENT: return "Power Present"; - case V4L2_CID_DV_RX_RGB_RANGE: return "Rx RGB Quantization Range"; - case V4L2_CID_DV_RX_IT_CONTENT_TYPE: return "Rx IT Content Type"; - - case V4L2_CID_FM_RX_CLASS: return "FM Radio Receiver Controls"; - case V4L2_CID_TUNE_DEEMPHASIS: return "De-Emphasis"; - case V4L2_CID_RDS_RECEPTION: return "RDS Reception"; - case V4L2_CID_RF_TUNER_CLASS: return "RF Tuner Controls"; - case V4L2_CID_RF_TUNER_RF_GAIN: return "RF Gain"; - case V4L2_CID_RF_TUNER_LNA_GAIN_AUTO: return "LNA Gain, Auto"; - case V4L2_CID_RF_TUNER_LNA_GAIN: return "LNA Gain"; - case V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO: return "Mixer Gain, Auto"; - case V4L2_CID_RF_TUNER_MIXER_GAIN: return "Mixer Gain"; - case V4L2_CID_RF_TUNER_IF_GAIN_AUTO: return "IF Gain, Auto"; - case V4L2_CID_RF_TUNER_IF_GAIN: return "IF Gain"; - case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO: return "Bandwidth, Auto"; - case V4L2_CID_RF_TUNER_BANDWIDTH: return "Bandwidth"; - case V4L2_CID_RF_TUNER_PLL_LOCK: return "PLL Lock"; - case V4L2_CID_RDS_RX_PTY: return "RDS Program Type"; - case V4L2_CID_RDS_RX_PS_NAME: return "RDS PS Name"; - case V4L2_CID_RDS_RX_RADIO_TEXT: return "RDS Radio Text"; - case V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT: return "RDS Traffic Announcement"; - case V4L2_CID_RDS_RX_TRAFFIC_PROGRAM: return "RDS Traffic Program"; - case V4L2_CID_RDS_RX_MUSIC_SPEECH: return "RDS Music"; - - /* Detection controls */ - /* Keep the order of the 'case's the same as in v4l2-controls.h! */ - case V4L2_CID_DETECT_CLASS: return "Detection Controls"; - case V4L2_CID_DETECT_MD_MODE: return "Motion Detection Mode"; - case V4L2_CID_DETECT_MD_GLOBAL_THRESHOLD: return "MD Global Threshold"; - case V4L2_CID_DETECT_MD_THRESHOLD_GRID: return "MD Threshold Grid"; - case V4L2_CID_DETECT_MD_REGION_GRID: return "MD Region Grid"; - - /* Stateless Codec controls */ - /* Keep the order of the 'case's the same as in v4l2-controls.h! */ - case V4L2_CID_CODEC_STATELESS_CLASS: return "Stateless Codec Controls"; - case V4L2_CID_STATELESS_H264_DECODE_MODE: return "H264 Decode Mode"; - case V4L2_CID_STATELESS_H264_START_CODE: return "H264 Start Code"; - case V4L2_CID_STATELESS_H264_SPS: return "H264 Sequence Parameter Set"; - case V4L2_CID_STATELESS_H264_PPS: return "H264 Picture Parameter Set"; - case V4L2_CID_STATELESS_H264_SCALING_MATRIX: return "H264 Scaling Matrix"; - case V4L2_CID_STATELESS_H264_PRED_WEIGHTS: return "H264 Prediction Weight Table"; - case V4L2_CID_STATELESS_H264_SLICE_PARAMS: return "H264 Slice Parameters"; - case V4L2_CID_STATELESS_H264_DECODE_PARAMS: return "H264 Decode Parameters"; - case V4L2_CID_STATELESS_FWHT_PARAMS: return "FWHT Stateless Parameters"; - case V4L2_CID_STATELESS_VP8_FRAME: return "VP8 Frame Parameters"; - case V4L2_CID_STATELESS_MPEG2_SEQUENCE: return "MPEG-2 Sequence Header"; - case V4L2_CID_STATELESS_MPEG2_PICTURE: return "MPEG-2 Picture Header"; - case V4L2_CID_STATELESS_MPEG2_QUANTISATION: return "MPEG-2 Quantisation Matrices"; - - /* Colorimetry controls */ - /* Keep the order of the 'case's the same as in v4l2-controls.h! */ - case V4L2_CID_COLORIMETRY_CLASS: return "Colorimetry Controls"; - case V4L2_CID_COLORIMETRY_HDR10_CLL_INFO: return "HDR10 Content Light Info"; - case V4L2_CID_COLORIMETRY_HDR10_MASTERING_DISPLAY: return "HDR10 Mastering Display"; - default: - return NULL; - } -} -EXPORT_SYMBOL(v4l2_ctrl_get_name); - -void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, - s64 *min, s64 *max, u64 *step, s64 *def, u32 *flags) -{ - *name = v4l2_ctrl_get_name(id); - *flags = 0; - - switch (id) { - case V4L2_CID_AUDIO_MUTE: - case V4L2_CID_AUDIO_LOUDNESS: - case V4L2_CID_AUTO_WHITE_BALANCE: - case V4L2_CID_AUTOGAIN: - case V4L2_CID_HFLIP: - case V4L2_CID_VFLIP: - case V4L2_CID_HUE_AUTO: - case V4L2_CID_CHROMA_AGC: - case V4L2_CID_COLOR_KILLER: - case V4L2_CID_AUTOBRIGHTNESS: - case V4L2_CID_MPEG_AUDIO_MUTE: - case V4L2_CID_MPEG_VIDEO_MUTE: - case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: - case V4L2_CID_MPEG_VIDEO_PULLDOWN: - case V4L2_CID_EXPOSURE_AUTO_PRIORITY: - case V4L2_CID_FOCUS_AUTO: - case V4L2_CID_PRIVACY: - case V4L2_CID_AUDIO_LIMITER_ENABLED: - case V4L2_CID_AUDIO_COMPRESSION_ENABLED: - case V4L2_CID_PILOT_TONE_ENABLED: - case V4L2_CID_ILLUMINATORS_1: - case V4L2_CID_ILLUMINATORS_2: - case V4L2_CID_FLASH_STROBE_STATUS: - case V4L2_CID_FLASH_CHARGE: - case V4L2_CID_FLASH_READY: - case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER: - case V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE: - case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY_ENABLE: - case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE: - case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE: - case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM: - case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE: - case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL: - case V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER: - case V4L2_CID_MPEG_VIDEO_AU_DELIMITER: - case V4L2_CID_WIDE_DYNAMIC_RANGE: - case V4L2_CID_IMAGE_STABILIZATION: - case V4L2_CID_RDS_RECEPTION: - case V4L2_CID_RF_TUNER_LNA_GAIN_AUTO: - case V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO: - case V4L2_CID_RF_TUNER_IF_GAIN_AUTO: - case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO: - case V4L2_CID_RF_TUNER_PLL_LOCK: - case V4L2_CID_RDS_TX_MONO_STEREO: - case V4L2_CID_RDS_TX_ARTIFICIAL_HEAD: - case V4L2_CID_RDS_TX_COMPRESSED: - case V4L2_CID_RDS_TX_DYNAMIC_PTY: - case V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT: - case V4L2_CID_RDS_TX_TRAFFIC_PROGRAM: - case V4L2_CID_RDS_TX_MUSIC_SPEECH: - case V4L2_CID_RDS_TX_ALT_FREQS_ENABLE: - case V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT: - case V4L2_CID_RDS_RX_TRAFFIC_PROGRAM: - case V4L2_CID_RDS_RX_MUSIC_SPEECH: - *type = V4L2_CTRL_TYPE_BOOLEAN; - *min = 0; - *max = *step = 1; - break; - case V4L2_CID_ROTATE: - *type = V4L2_CTRL_TYPE_INTEGER; - *flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; - break; - case V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE: - case V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE: - case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY: - *type = V4L2_CTRL_TYPE_INTEGER; - break; - case V4L2_CID_MPEG_VIDEO_LTR_COUNT: - *type = V4L2_CTRL_TYPE_INTEGER; - break; - case V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX: - *type = V4L2_CTRL_TYPE_INTEGER; - *flags |= V4L2_CTRL_FLAG_EXECUTE_ON_WRITE; - break; - case V4L2_CID_MPEG_VIDEO_USE_LTR_FRAMES: - *type = V4L2_CTRL_TYPE_BITMASK; - *flags |= V4L2_CTRL_FLAG_EXECUTE_ON_WRITE; - break; - case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME: - case V4L2_CID_PAN_RESET: - case V4L2_CID_TILT_RESET: - case V4L2_CID_FLASH_STROBE: - case V4L2_CID_FLASH_STROBE_STOP: - case V4L2_CID_AUTO_FOCUS_START: - case V4L2_CID_AUTO_FOCUS_STOP: - case V4L2_CID_DO_WHITE_BALANCE: - *type = V4L2_CTRL_TYPE_BUTTON; - *flags |= V4L2_CTRL_FLAG_WRITE_ONLY | - V4L2_CTRL_FLAG_EXECUTE_ON_WRITE; - *min = *max = *step = *def = 0; - break; - case V4L2_CID_POWER_LINE_FREQUENCY: - case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: - case V4L2_CID_MPEG_AUDIO_ENCODING: - case V4L2_CID_MPEG_AUDIO_L1_BITRATE: - case V4L2_CID_MPEG_AUDIO_L2_BITRATE: - case V4L2_CID_MPEG_AUDIO_L3_BITRATE: - case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: - case V4L2_CID_MPEG_AUDIO_MODE: - case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: - case V4L2_CID_MPEG_AUDIO_EMPHASIS: - case V4L2_CID_MPEG_AUDIO_CRC: - case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK: - case V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK: - case V4L2_CID_MPEG_VIDEO_ENCODING: - case V4L2_CID_MPEG_VIDEO_ASPECT: - case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: - case V4L2_CID_MPEG_STREAM_TYPE: - case V4L2_CID_MPEG_STREAM_VBI_FMT: - case V4L2_CID_EXPOSURE_AUTO: - case V4L2_CID_AUTO_FOCUS_RANGE: - case V4L2_CID_COLORFX: - case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE: - case V4L2_CID_TUNE_PREEMPHASIS: - case V4L2_CID_FLASH_LED_MODE: - case V4L2_CID_FLASH_STROBE_SOURCE: - case V4L2_CID_MPEG_VIDEO_HEADER_MODE: - case V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE: - case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: - case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: - case V4L2_CID_MPEG_VIDEO_H264_LEVEL: - case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE: - case V4L2_CID_MPEG_VIDEO_H264_PROFILE: - case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC: - case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE: - case V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE: - case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE: - case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL: - case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE: - case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: - case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: - case V4L2_CID_JPEG_CHROMA_SUBSAMPLING: - case V4L2_CID_ISO_SENSITIVITY_AUTO: - case V4L2_CID_EXPOSURE_METERING: - case V4L2_CID_SCENE_MODE: - case V4L2_CID_DV_TX_MODE: - case V4L2_CID_DV_TX_RGB_RANGE: - case V4L2_CID_DV_TX_IT_CONTENT_TYPE: - case V4L2_CID_DV_RX_RGB_RANGE: - case V4L2_CID_DV_RX_IT_CONTENT_TYPE: - case V4L2_CID_TEST_PATTERN: - case V4L2_CID_DEINTERLACING_MODE: - case V4L2_CID_TUNE_DEEMPHASIS: - case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL: - case V4L2_CID_MPEG_VIDEO_VP8_PROFILE: - case V4L2_CID_MPEG_VIDEO_VP9_PROFILE: - case V4L2_CID_MPEG_VIDEO_VP9_LEVEL: - case V4L2_CID_DETECT_MD_MODE: - case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: - case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: - case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE: - case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE: - case V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD: - case V4L2_CID_MPEG_VIDEO_HEVC_TIER: - case V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE: - case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE: - case V4L2_CID_MPEG_VIDEO_HEVC_START_CODE: - case V4L2_CID_STATELESS_H264_DECODE_MODE: - case V4L2_CID_STATELESS_H264_START_CODE: - case V4L2_CID_CAMERA_ORIENTATION: - *type = V4L2_CTRL_TYPE_MENU; - break; - case V4L2_CID_LINK_FREQ: - *type = V4L2_CTRL_TYPE_INTEGER_MENU; - break; - case V4L2_CID_RDS_TX_PS_NAME: - case V4L2_CID_RDS_TX_RADIO_TEXT: - case V4L2_CID_RDS_RX_PS_NAME: - case V4L2_CID_RDS_RX_RADIO_TEXT: - *type = V4L2_CTRL_TYPE_STRING; - break; - case V4L2_CID_ISO_SENSITIVITY: - case V4L2_CID_AUTO_EXPOSURE_BIAS: - case V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS: - case V4L2_CID_MPEG_VIDEO_VPX_NUM_REF_FRAMES: - *type = V4L2_CTRL_TYPE_INTEGER_MENU; - break; - case V4L2_CID_USER_CLASS: - case V4L2_CID_CAMERA_CLASS: - case V4L2_CID_CODEC_CLASS: - case V4L2_CID_FM_TX_CLASS: - case V4L2_CID_FLASH_CLASS: - case V4L2_CID_JPEG_CLASS: - case V4L2_CID_IMAGE_SOURCE_CLASS: - case V4L2_CID_IMAGE_PROC_CLASS: - case V4L2_CID_DV_CLASS: - case V4L2_CID_FM_RX_CLASS: - case V4L2_CID_RF_TUNER_CLASS: - case V4L2_CID_DETECT_CLASS: - case V4L2_CID_CODEC_STATELESS_CLASS: - case V4L2_CID_COLORIMETRY_CLASS: - *type = V4L2_CTRL_TYPE_CTRL_CLASS; - /* You can neither read nor write these */ - *flags |= V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY; - *min = *max = *step = *def = 0; - break; - case V4L2_CID_BG_COLOR: - *type = V4L2_CTRL_TYPE_INTEGER; - *step = 1; - *min = 0; - /* Max is calculated as RGB888 that is 2^24 */ - *max = 0xFFFFFF; - break; - case V4L2_CID_FLASH_FAULT: - case V4L2_CID_JPEG_ACTIVE_MARKER: - case V4L2_CID_3A_LOCK: - case V4L2_CID_AUTO_FOCUS_STATUS: - case V4L2_CID_DV_TX_HOTPLUG: - case V4L2_CID_DV_TX_RXSENSE: - case V4L2_CID_DV_TX_EDID_PRESENT: - case V4L2_CID_DV_RX_POWER_PRESENT: - *type = V4L2_CTRL_TYPE_BITMASK; - break; - case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: - case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: - *type = V4L2_CTRL_TYPE_INTEGER; - *flags |= V4L2_CTRL_FLAG_READ_ONLY; - break; - case V4L2_CID_MPEG_VIDEO_DEC_PTS: - *type = V4L2_CTRL_TYPE_INTEGER64; - *flags |= V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY; - *min = *def = 0; - *max = 0x1ffffffffLL; - *step = 1; - break; - case V4L2_CID_MPEG_VIDEO_DEC_FRAME: - *type = V4L2_CTRL_TYPE_INTEGER64; - *flags |= V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY; - *min = *def = 0; - *max = 0x7fffffffffffffffLL; - *step = 1; - break; - case V4L2_CID_MPEG_VIDEO_DEC_CONCEAL_COLOR: - *type = V4L2_CTRL_TYPE_INTEGER64; - *min = 0; - /* default for 8 bit black, luma is 16, chroma is 128 */ - *def = 0x8000800010LL; - *max = 0xffffffffffffLL; - *step = 1; - break; - case V4L2_CID_PIXEL_RATE: - *type = V4L2_CTRL_TYPE_INTEGER64; - *flags |= V4L2_CTRL_FLAG_READ_ONLY; - break; - case V4L2_CID_DETECT_MD_REGION_GRID: - *type = V4L2_CTRL_TYPE_U8; - break; - case V4L2_CID_DETECT_MD_THRESHOLD_GRID: - *type = V4L2_CTRL_TYPE_U16; - break; - case V4L2_CID_RDS_TX_ALT_FREQS: - *type = V4L2_CTRL_TYPE_U32; - break; - case V4L2_CID_STATELESS_MPEG2_SEQUENCE: - *type = V4L2_CTRL_TYPE_MPEG2_SEQUENCE; - break; - case V4L2_CID_STATELESS_MPEG2_PICTURE: - *type = V4L2_CTRL_TYPE_MPEG2_PICTURE; - break; - case V4L2_CID_STATELESS_MPEG2_QUANTISATION: - *type = V4L2_CTRL_TYPE_MPEG2_QUANTISATION; - break; - case V4L2_CID_STATELESS_FWHT_PARAMS: - *type = V4L2_CTRL_TYPE_FWHT_PARAMS; - break; - case V4L2_CID_STATELESS_H264_SPS: - *type = V4L2_CTRL_TYPE_H264_SPS; - break; - case V4L2_CID_STATELESS_H264_PPS: - *type = V4L2_CTRL_TYPE_H264_PPS; - break; - case V4L2_CID_STATELESS_H264_SCALING_MATRIX: - *type = V4L2_CTRL_TYPE_H264_SCALING_MATRIX; - break; - case V4L2_CID_STATELESS_H264_SLICE_PARAMS: - *type = V4L2_CTRL_TYPE_H264_SLICE_PARAMS; - break; - case V4L2_CID_STATELESS_H264_DECODE_PARAMS: - *type = V4L2_CTRL_TYPE_H264_DECODE_PARAMS; - break; - case V4L2_CID_STATELESS_H264_PRED_WEIGHTS: - *type = V4L2_CTRL_TYPE_H264_PRED_WEIGHTS; - break; - case V4L2_CID_STATELESS_VP8_FRAME: - *type = V4L2_CTRL_TYPE_VP8_FRAME; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_SPS: - *type = V4L2_CTRL_TYPE_HEVC_SPS; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_PPS: - *type = V4L2_CTRL_TYPE_HEVC_PPS; - break; - case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS: - *type = V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS; - break; - case V4L2_CID_UNIT_CELL_SIZE: - *type = V4L2_CTRL_TYPE_AREA; - *flags |= V4L2_CTRL_FLAG_READ_ONLY; - break; - case V4L2_CID_COLORIMETRY_HDR10_CLL_INFO: - *type = V4L2_CTRL_TYPE_HDR10_CLL_INFO; - break; - case V4L2_CID_COLORIMETRY_HDR10_MASTERING_DISPLAY: - *type = V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY; - break; - default: - *type = V4L2_CTRL_TYPE_INTEGER; - break; - } - switch (id) { - case V4L2_CID_MPEG_AUDIO_ENCODING: - case V4L2_CID_MPEG_AUDIO_MODE: - case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: - case V4L2_CID_MPEG_VIDEO_B_FRAMES: - case V4L2_CID_MPEG_STREAM_TYPE: - *flags |= V4L2_CTRL_FLAG_UPDATE; - break; - case V4L2_CID_AUDIO_VOLUME: - case V4L2_CID_AUDIO_BALANCE: - case V4L2_CID_AUDIO_BASS: - case V4L2_CID_AUDIO_TREBLE: - case V4L2_CID_BRIGHTNESS: - case V4L2_CID_CONTRAST: - case V4L2_CID_SATURATION: - case V4L2_CID_HUE: - case V4L2_CID_RED_BALANCE: - case V4L2_CID_BLUE_BALANCE: - case V4L2_CID_GAMMA: - case V4L2_CID_SHARPNESS: - case V4L2_CID_CHROMA_GAIN: - case V4L2_CID_RDS_TX_DEVIATION: - case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME: - case V4L2_CID_AUDIO_LIMITER_DEVIATION: - case V4L2_CID_AUDIO_COMPRESSION_GAIN: - case V4L2_CID_AUDIO_COMPRESSION_THRESHOLD: - case V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME: - case V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME: - case V4L2_CID_PILOT_TONE_DEVIATION: - case V4L2_CID_PILOT_TONE_FREQUENCY: - case V4L2_CID_TUNE_POWER_LEVEL: - case V4L2_CID_TUNE_ANTENNA_CAPACITOR: - case V4L2_CID_RF_TUNER_RF_GAIN: - case V4L2_CID_RF_TUNER_LNA_GAIN: - case V4L2_CID_RF_TUNER_MIXER_GAIN: - case V4L2_CID_RF_TUNER_IF_GAIN: - case V4L2_CID_RF_TUNER_BANDWIDTH: - case V4L2_CID_DETECT_MD_GLOBAL_THRESHOLD: - *flags |= V4L2_CTRL_FLAG_SLIDER; - break; - case V4L2_CID_PAN_RELATIVE: - case V4L2_CID_TILT_RELATIVE: - case V4L2_CID_FOCUS_RELATIVE: - case V4L2_CID_IRIS_RELATIVE: - case V4L2_CID_ZOOM_RELATIVE: - *flags |= V4L2_CTRL_FLAG_WRITE_ONLY | - V4L2_CTRL_FLAG_EXECUTE_ON_WRITE; - break; - case V4L2_CID_FLASH_STROBE_STATUS: - case V4L2_CID_AUTO_FOCUS_STATUS: - case V4L2_CID_FLASH_READY: - case V4L2_CID_DV_TX_HOTPLUG: - case V4L2_CID_DV_TX_RXSENSE: - case V4L2_CID_DV_TX_EDID_PRESENT: - case V4L2_CID_DV_RX_POWER_PRESENT: - case V4L2_CID_DV_RX_IT_CONTENT_TYPE: - case V4L2_CID_RDS_RX_PTY: - case V4L2_CID_RDS_RX_PS_NAME: - case V4L2_CID_RDS_RX_RADIO_TEXT: - case V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT: - case V4L2_CID_RDS_RX_TRAFFIC_PROGRAM: - case V4L2_CID_RDS_RX_MUSIC_SPEECH: - case V4L2_CID_CAMERA_ORIENTATION: - case V4L2_CID_CAMERA_SENSOR_ROTATION: - *flags |= V4L2_CTRL_FLAG_READ_ONLY; - break; - case V4L2_CID_RF_TUNER_PLL_LOCK: - *flags |= V4L2_CTRL_FLAG_VOLATILE; - break; - } -} -EXPORT_SYMBOL(v4l2_ctrl_fill); - -static u32 user_flags(const struct v4l2_ctrl *ctrl) -{ - u32 flags = ctrl->flags; - - if (ctrl->is_ptr) - flags |= V4L2_CTRL_FLAG_HAS_PAYLOAD; - - return flags; -} - -static void fill_event(struct v4l2_event *ev, struct v4l2_ctrl *ctrl, u32 changes) -{ - memset(ev, 0, sizeof(*ev)); - ev->type = V4L2_EVENT_CTRL; - ev->id = ctrl->id; - ev->u.ctrl.changes = changes; - ev->u.ctrl.type = ctrl->type; - ev->u.ctrl.flags = user_flags(ctrl); - if (ctrl->is_ptr) - ev->u.ctrl.value64 = 0; - else - ev->u.ctrl.value64 = *ctrl->p_cur.p_s64; - ev->u.ctrl.minimum = ctrl->minimum; - ev->u.ctrl.maximum = ctrl->maximum; - if (ctrl->type == V4L2_CTRL_TYPE_MENU - || ctrl->type == V4L2_CTRL_TYPE_INTEGER_MENU) - ev->u.ctrl.step = 1; - else - ev->u.ctrl.step = ctrl->step; - ev->u.ctrl.default_value = ctrl->default_value; -} - -static void send_event(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 changes) -{ - struct v4l2_event ev; - struct v4l2_subscribed_event *sev; - - if (list_empty(&ctrl->ev_subs)) - return; - fill_event(&ev, ctrl, changes); - - list_for_each_entry(sev, &ctrl->ev_subs, node) - if (sev->fh != fh || - (sev->flags & V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK)) - v4l2_event_queue_fh(sev->fh, &ev); -} - -static bool std_equal(const struct v4l2_ctrl *ctrl, u32 idx, - union v4l2_ctrl_ptr ptr1, - union v4l2_ctrl_ptr ptr2) -{ - switch (ctrl->type) { - case V4L2_CTRL_TYPE_BUTTON: - return false; - case V4L2_CTRL_TYPE_STRING: - idx *= ctrl->elem_size; - /* strings are always 0-terminated */ - return !strcmp(ptr1.p_char + idx, ptr2.p_char + idx); - case V4L2_CTRL_TYPE_INTEGER64: - return ptr1.p_s64[idx] == ptr2.p_s64[idx]; - case V4L2_CTRL_TYPE_U8: - return ptr1.p_u8[idx] == ptr2.p_u8[idx]; - case V4L2_CTRL_TYPE_U16: - return ptr1.p_u16[idx] == ptr2.p_u16[idx]; - case V4L2_CTRL_TYPE_U32: - return ptr1.p_u32[idx] == ptr2.p_u32[idx]; - default: - if (ctrl->is_int) - return ptr1.p_s32[idx] == ptr2.p_s32[idx]; - idx *= ctrl->elem_size; - return !memcmp(ptr1.p_const + idx, ptr2.p_const + idx, - ctrl->elem_size); - } -} - -static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx, - union v4l2_ctrl_ptr ptr) -{ - struct v4l2_ctrl_mpeg2_sequence *p_mpeg2_sequence; - struct v4l2_ctrl_mpeg2_picture *p_mpeg2_picture; - struct v4l2_ctrl_mpeg2_quantisation *p_mpeg2_quant; - struct v4l2_ctrl_vp8_frame *p_vp8_frame; - struct v4l2_ctrl_fwht_params *p_fwht_params; - void *p = ptr.p + idx * ctrl->elem_size; - - if (ctrl->p_def.p_const) - memcpy(p, ctrl->p_def.p_const, ctrl->elem_size); - else - memset(p, 0, ctrl->elem_size); - - switch ((u32)ctrl->type) { - case V4L2_CTRL_TYPE_MPEG2_SEQUENCE: - p_mpeg2_sequence = p; - - /* 4:2:0 */ - p_mpeg2_sequence->chroma_format = 1; - break; - case V4L2_CTRL_TYPE_MPEG2_PICTURE: - p_mpeg2_picture = p; - - /* interlaced top field */ - p_mpeg2_picture->picture_structure = V4L2_MPEG2_PIC_TOP_FIELD; - p_mpeg2_picture->picture_coding_type = - V4L2_MPEG2_PIC_CODING_TYPE_I; - break; - case V4L2_CTRL_TYPE_MPEG2_QUANTISATION: - p_mpeg2_quant = p; - - memcpy(p_mpeg2_quant->intra_quantiser_matrix, - mpeg2_intra_quant_matrix, - ARRAY_SIZE(mpeg2_intra_quant_matrix)); - /* - * The default non-intra MPEG-2 quantisation - * coefficients are all 16, as per the specification. - */ - memset(p_mpeg2_quant->non_intra_quantiser_matrix, 16, - sizeof(p_mpeg2_quant->non_intra_quantiser_matrix)); - break; - case V4L2_CTRL_TYPE_VP8_FRAME: - p_vp8_frame = p; - p_vp8_frame->num_dct_parts = 1; - break; - case V4L2_CTRL_TYPE_FWHT_PARAMS: - p_fwht_params = p; - p_fwht_params->version = V4L2_FWHT_VERSION; - p_fwht_params->width = 1280; - p_fwht_params->height = 720; - p_fwht_params->flags = V4L2_FWHT_FL_PIXENC_YUV | - (2 << V4L2_FWHT_FL_COMPONENTS_NUM_OFFSET); - break; - } -} - -static void std_init(const struct v4l2_ctrl *ctrl, u32 idx, - union v4l2_ctrl_ptr ptr) -{ - switch (ctrl->type) { - case V4L2_CTRL_TYPE_STRING: - idx *= ctrl->elem_size; - memset(ptr.p_char + idx, ' ', ctrl->minimum); - ptr.p_char[idx + ctrl->minimum] = '\0'; - break; - case V4L2_CTRL_TYPE_INTEGER64: - ptr.p_s64[idx] = ctrl->default_value; - break; - case V4L2_CTRL_TYPE_INTEGER: - case V4L2_CTRL_TYPE_INTEGER_MENU: - case V4L2_CTRL_TYPE_MENU: - case V4L2_CTRL_TYPE_BITMASK: - case V4L2_CTRL_TYPE_BOOLEAN: - ptr.p_s32[idx] = ctrl->default_value; - break; - case V4L2_CTRL_TYPE_BUTTON: - case V4L2_CTRL_TYPE_CTRL_CLASS: - ptr.p_s32[idx] = 0; - break; - case V4L2_CTRL_TYPE_U8: - ptr.p_u8[idx] = ctrl->default_value; - break; - case V4L2_CTRL_TYPE_U16: - ptr.p_u16[idx] = ctrl->default_value; - break; - case V4L2_CTRL_TYPE_U32: - ptr.p_u32[idx] = ctrl->default_value; - break; - default: - std_init_compound(ctrl, idx, ptr); - break; - } -} - -static void std_log(const struct v4l2_ctrl *ctrl) -{ - union v4l2_ctrl_ptr ptr = ctrl->p_cur; - - if (ctrl->is_array) { - unsigned i; - - for (i = 0; i < ctrl->nr_of_dims; i++) - pr_cont("[%u]", ctrl->dims[i]); - pr_cont(" "); - } - - switch (ctrl->type) { - case V4L2_CTRL_TYPE_INTEGER: - pr_cont("%d", *ptr.p_s32); - break; - case V4L2_CTRL_TYPE_BOOLEAN: - pr_cont("%s", *ptr.p_s32 ? "true" : "false"); - break; - case V4L2_CTRL_TYPE_MENU: - pr_cont("%s", ctrl->qmenu[*ptr.p_s32]); - break; - case V4L2_CTRL_TYPE_INTEGER_MENU: - pr_cont("%lld", ctrl->qmenu_int[*ptr.p_s32]); - break; - case V4L2_CTRL_TYPE_BITMASK: - pr_cont("0x%08x", *ptr.p_s32); - break; - case V4L2_CTRL_TYPE_INTEGER64: - pr_cont("%lld", *ptr.p_s64); - break; - case V4L2_CTRL_TYPE_STRING: - pr_cont("%s", ptr.p_char); - break; - case V4L2_CTRL_TYPE_U8: - pr_cont("%u", (unsigned)*ptr.p_u8); - break; - case V4L2_CTRL_TYPE_U16: - pr_cont("%u", (unsigned)*ptr.p_u16); - break; - case V4L2_CTRL_TYPE_U32: - pr_cont("%u", (unsigned)*ptr.p_u32); - break; - case V4L2_CTRL_TYPE_H264_SPS: - pr_cont("H264_SPS"); - break; - case V4L2_CTRL_TYPE_H264_PPS: - pr_cont("H264_PPS"); - break; - case V4L2_CTRL_TYPE_H264_SCALING_MATRIX: - pr_cont("H264_SCALING_MATRIX"); - break; - case V4L2_CTRL_TYPE_H264_SLICE_PARAMS: - pr_cont("H264_SLICE_PARAMS"); - break; - case V4L2_CTRL_TYPE_H264_DECODE_PARAMS: - pr_cont("H264_DECODE_PARAMS"); - break; - case V4L2_CTRL_TYPE_H264_PRED_WEIGHTS: - pr_cont("H264_PRED_WEIGHTS"); - break; - case V4L2_CTRL_TYPE_FWHT_PARAMS: - pr_cont("FWHT_PARAMS"); - break; - case V4L2_CTRL_TYPE_VP8_FRAME: - pr_cont("VP8_FRAME"); - break; - case V4L2_CTRL_TYPE_HDR10_CLL_INFO: - pr_cont("HDR10_CLL_INFO"); - break; - case V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY: - pr_cont("HDR10_MASTERING_DISPLAY"); - break; - case V4L2_CTRL_TYPE_MPEG2_QUANTISATION: - pr_cont("MPEG2_QUANTISATION"); - break; - case V4L2_CTRL_TYPE_MPEG2_SEQUENCE: - pr_cont("MPEG2_SEQUENCE"); - break; - case V4L2_CTRL_TYPE_MPEG2_PICTURE: - pr_cont("MPEG2_PICTURE"); - break; - default: - pr_cont("unknown type %d", ctrl->type); - break; - } -} - -/* - * Round towards the closest legal value. Be careful when we are - * close to the maximum range of the control type to prevent - * wrap-arounds. - */ -#define ROUND_TO_RANGE(val, offset_type, ctrl) \ -({ \ - offset_type offset; \ - if ((ctrl)->maximum >= 0 && \ - val >= (ctrl)->maximum - (s32)((ctrl)->step / 2)) \ - val = (ctrl)->maximum; \ - else \ - val += (s32)((ctrl)->step / 2); \ - val = clamp_t(typeof(val), val, \ - (ctrl)->minimum, (ctrl)->maximum); \ - offset = (val) - (ctrl)->minimum; \ - offset = (ctrl)->step * (offset / (u32)(ctrl)->step); \ - val = (ctrl)->minimum + offset; \ - 0; \ -}) - -/* Validate a new control */ - -#define zero_padding(s) \ - memset(&(s).padding, 0, sizeof((s).padding)) -#define zero_reserved(s) \ - memset(&(s).reserved, 0, sizeof((s).reserved)) - -/* - * Compound controls validation requires setting unused fields/flags to zero - * in order to properly detect unchanged controls with std_equal's memcmp. - */ -static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, - union v4l2_ctrl_ptr ptr) -{ - struct v4l2_ctrl_mpeg2_sequence *p_mpeg2_sequence; - struct v4l2_ctrl_mpeg2_picture *p_mpeg2_picture; - struct v4l2_ctrl_vp8_frame *p_vp8_frame; - struct v4l2_ctrl_fwht_params *p_fwht_params; - struct v4l2_ctrl_h264_sps *p_h264_sps; - struct v4l2_ctrl_h264_pps *p_h264_pps; - struct v4l2_ctrl_h264_pred_weights *p_h264_pred_weights; - struct v4l2_ctrl_h264_slice_params *p_h264_slice_params; - struct v4l2_ctrl_h264_decode_params *p_h264_dec_params; - struct v4l2_ctrl_hevc_sps *p_hevc_sps; - struct v4l2_ctrl_hevc_pps *p_hevc_pps; - struct v4l2_ctrl_hevc_slice_params *p_hevc_slice_params; - struct v4l2_ctrl_hdr10_mastering_display *p_hdr10_mastering; - struct v4l2_area *area; - void *p = ptr.p + idx * ctrl->elem_size; - unsigned int i; - - switch ((u32)ctrl->type) { - case V4L2_CTRL_TYPE_MPEG2_SEQUENCE: - p_mpeg2_sequence = p; - - switch (p_mpeg2_sequence->chroma_format) { - case 1: /* 4:2:0 */ - case 2: /* 4:2:2 */ - case 3: /* 4:4:4 */ - break; - default: - return -EINVAL; - } - break; - - case V4L2_CTRL_TYPE_MPEG2_PICTURE: - p_mpeg2_picture = p; - - switch (p_mpeg2_picture->intra_dc_precision) { - case 0: /* 8 bits */ - case 1: /* 9 bits */ - case 2: /* 10 bits */ - case 3: /* 11 bits */ - break; - default: - return -EINVAL; - } - - switch (p_mpeg2_picture->picture_structure) { - case V4L2_MPEG2_PIC_TOP_FIELD: - case V4L2_MPEG2_PIC_BOTTOM_FIELD: - case V4L2_MPEG2_PIC_FRAME: - break; - default: - return -EINVAL; - } - - switch (p_mpeg2_picture->picture_coding_type) { - case V4L2_MPEG2_PIC_CODING_TYPE_I: - case V4L2_MPEG2_PIC_CODING_TYPE_P: - case V4L2_MPEG2_PIC_CODING_TYPE_B: - break; - default: - return -EINVAL; - } - zero_reserved(*p_mpeg2_picture); - break; - - case V4L2_CTRL_TYPE_MPEG2_QUANTISATION: - break; - - case V4L2_CTRL_TYPE_FWHT_PARAMS: - p_fwht_params = p; - if (p_fwht_params->version < V4L2_FWHT_VERSION) - return -EINVAL; - if (!p_fwht_params->width || !p_fwht_params->height) - return -EINVAL; - break; - - case V4L2_CTRL_TYPE_H264_SPS: - p_h264_sps = p; - - /* Some syntax elements are only conditionally valid */ - if (p_h264_sps->pic_order_cnt_type != 0) { - p_h264_sps->log2_max_pic_order_cnt_lsb_minus4 = 0; - } else if (p_h264_sps->pic_order_cnt_type != 1) { - p_h264_sps->num_ref_frames_in_pic_order_cnt_cycle = 0; - p_h264_sps->offset_for_non_ref_pic = 0; - p_h264_sps->offset_for_top_to_bottom_field = 0; - memset(&p_h264_sps->offset_for_ref_frame, 0, - sizeof(p_h264_sps->offset_for_ref_frame)); - } - - if (!V4L2_H264_SPS_HAS_CHROMA_FORMAT(p_h264_sps)) { - p_h264_sps->chroma_format_idc = 1; - p_h264_sps->bit_depth_luma_minus8 = 0; - p_h264_sps->bit_depth_chroma_minus8 = 0; - - p_h264_sps->flags &= - ~V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS; - - if (p_h264_sps->chroma_format_idc < 3) - p_h264_sps->flags &= - ~V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE; - } - - if (p_h264_sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY) - p_h264_sps->flags &= - ~V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD; - - /* - * Chroma 4:2:2 format require at least High 4:2:2 profile. - * - * The H264 specification and well-known parser implementations - * use profile-idc values directly, as that is clearer and - * less ambiguous. We do the same here. - */ - if (p_h264_sps->profile_idc < 122 && - p_h264_sps->chroma_format_idc > 1) - return -EINVAL; - /* Chroma 4:4:4 format require at least High 4:2:2 profile */ - if (p_h264_sps->profile_idc < 244 && - p_h264_sps->chroma_format_idc > 2) - return -EINVAL; - if (p_h264_sps->chroma_format_idc > 3) - return -EINVAL; - - if (p_h264_sps->bit_depth_luma_minus8 > 6) - return -EINVAL; - if (p_h264_sps->bit_depth_chroma_minus8 > 6) - return -EINVAL; - if (p_h264_sps->log2_max_frame_num_minus4 > 12) - return -EINVAL; - if (p_h264_sps->pic_order_cnt_type > 2) - return -EINVAL; - if (p_h264_sps->log2_max_pic_order_cnt_lsb_minus4 > 12) - return -EINVAL; - if (p_h264_sps->max_num_ref_frames > V4L2_H264_REF_LIST_LEN) - return -EINVAL; - break; - - case V4L2_CTRL_TYPE_H264_PPS: - p_h264_pps = p; - - if (p_h264_pps->num_slice_groups_minus1 > 7) - return -EINVAL; - if (p_h264_pps->num_ref_idx_l0_default_active_minus1 > - (V4L2_H264_REF_LIST_LEN - 1)) - return -EINVAL; - if (p_h264_pps->num_ref_idx_l1_default_active_minus1 > - (V4L2_H264_REF_LIST_LEN - 1)) - return -EINVAL; - if (p_h264_pps->weighted_bipred_idc > 2) - return -EINVAL; - /* - * pic_init_qp_minus26 shall be in the range of - * -(26 + QpBdOffset_y) to +25, inclusive, - * where QpBdOffset_y is 6 * bit_depth_luma_minus8 - */ - if (p_h264_pps->pic_init_qp_minus26 < -62 || - p_h264_pps->pic_init_qp_minus26 > 25) - return -EINVAL; - if (p_h264_pps->pic_init_qs_minus26 < -26 || - p_h264_pps->pic_init_qs_minus26 > 25) - return -EINVAL; - if (p_h264_pps->chroma_qp_index_offset < -12 || - p_h264_pps->chroma_qp_index_offset > 12) - return -EINVAL; - if (p_h264_pps->second_chroma_qp_index_offset < -12 || - p_h264_pps->second_chroma_qp_index_offset > 12) - return -EINVAL; - break; - - case V4L2_CTRL_TYPE_H264_SCALING_MATRIX: - break; - - case V4L2_CTRL_TYPE_H264_PRED_WEIGHTS: - p_h264_pred_weights = p; - - if (p_h264_pred_weights->luma_log2_weight_denom > 7) - return -EINVAL; - if (p_h264_pred_weights->chroma_log2_weight_denom > 7) - return -EINVAL; - break; - - case V4L2_CTRL_TYPE_H264_SLICE_PARAMS: - p_h264_slice_params = p; - - if (p_h264_slice_params->slice_type != V4L2_H264_SLICE_TYPE_B) - p_h264_slice_params->flags &= - ~V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED; - - if (p_h264_slice_params->colour_plane_id > 2) - return -EINVAL; - if (p_h264_slice_params->cabac_init_idc > 2) - return -EINVAL; - if (p_h264_slice_params->disable_deblocking_filter_idc > 2) - return -EINVAL; - if (p_h264_slice_params->slice_alpha_c0_offset_div2 < -6 || - p_h264_slice_params->slice_alpha_c0_offset_div2 > 6) - return -EINVAL; - if (p_h264_slice_params->slice_beta_offset_div2 < -6 || - p_h264_slice_params->slice_beta_offset_div2 > 6) - return -EINVAL; - - if (p_h264_slice_params->slice_type == V4L2_H264_SLICE_TYPE_I || - p_h264_slice_params->slice_type == V4L2_H264_SLICE_TYPE_SI) - p_h264_slice_params->num_ref_idx_l0_active_minus1 = 0; - if (p_h264_slice_params->slice_type != V4L2_H264_SLICE_TYPE_B) - p_h264_slice_params->num_ref_idx_l1_active_minus1 = 0; - - if (p_h264_slice_params->num_ref_idx_l0_active_minus1 > - (V4L2_H264_REF_LIST_LEN - 1)) - return -EINVAL; - if (p_h264_slice_params->num_ref_idx_l1_active_minus1 > - (V4L2_H264_REF_LIST_LEN - 1)) - return -EINVAL; - zero_reserved(*p_h264_slice_params); - break; - - case V4L2_CTRL_TYPE_H264_DECODE_PARAMS: - p_h264_dec_params = p; - - if (p_h264_dec_params->nal_ref_idc > 3) - return -EINVAL; - for (i = 0; i < V4L2_H264_NUM_DPB_ENTRIES; i++) { - struct v4l2_h264_dpb_entry *dpb_entry = - &p_h264_dec_params->dpb[i]; - - zero_reserved(*dpb_entry); - } - zero_reserved(*p_h264_dec_params); - break; - - case V4L2_CTRL_TYPE_VP8_FRAME: - p_vp8_frame = p; - - switch (p_vp8_frame->num_dct_parts) { - case 1: - case 2: - case 4: - case 8: - break; - default: - return -EINVAL; - } - zero_padding(p_vp8_frame->segment); - zero_padding(p_vp8_frame->lf); - zero_padding(p_vp8_frame->quant); - zero_padding(p_vp8_frame->entropy); - zero_padding(p_vp8_frame->coder_state); - break; - - case V4L2_CTRL_TYPE_HEVC_SPS: - p_hevc_sps = p; - - if (!(p_hevc_sps->flags & V4L2_HEVC_SPS_FLAG_PCM_ENABLED)) { - p_hevc_sps->pcm_sample_bit_depth_luma_minus1 = 0; - p_hevc_sps->pcm_sample_bit_depth_chroma_minus1 = 0; - p_hevc_sps->log2_min_pcm_luma_coding_block_size_minus3 = 0; - p_hevc_sps->log2_diff_max_min_pcm_luma_coding_block_size = 0; - } - - if (!(p_hevc_sps->flags & - V4L2_HEVC_SPS_FLAG_LONG_TERM_REF_PICS_PRESENT)) - p_hevc_sps->num_long_term_ref_pics_sps = 0; - break; - - case V4L2_CTRL_TYPE_HEVC_PPS: - p_hevc_pps = p; - - if (!(p_hevc_pps->flags & - V4L2_HEVC_PPS_FLAG_CU_QP_DELTA_ENABLED)) - p_hevc_pps->diff_cu_qp_delta_depth = 0; - - if (!(p_hevc_pps->flags & V4L2_HEVC_PPS_FLAG_TILES_ENABLED)) { - p_hevc_pps->num_tile_columns_minus1 = 0; - p_hevc_pps->num_tile_rows_minus1 = 0; - memset(&p_hevc_pps->column_width_minus1, 0, - sizeof(p_hevc_pps->column_width_minus1)); - memset(&p_hevc_pps->row_height_minus1, 0, - sizeof(p_hevc_pps->row_height_minus1)); - - p_hevc_pps->flags &= - ~V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED; - } - - if (p_hevc_pps->flags & - V4L2_HEVC_PPS_FLAG_PPS_DISABLE_DEBLOCKING_FILTER) { - p_hevc_pps->pps_beta_offset_div2 = 0; - p_hevc_pps->pps_tc_offset_div2 = 0; - } - - zero_padding(*p_hevc_pps); - break; - - case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS: - p_hevc_slice_params = p; - - if (p_hevc_slice_params->num_active_dpb_entries > - V4L2_HEVC_DPB_ENTRIES_NUM_MAX) - return -EINVAL; - - zero_padding(p_hevc_slice_params->pred_weight_table); - - for (i = 0; i < p_hevc_slice_params->num_active_dpb_entries; - i++) { - struct v4l2_hevc_dpb_entry *dpb_entry = - &p_hevc_slice_params->dpb[i]; - - zero_padding(*dpb_entry); - } - - zero_padding(*p_hevc_slice_params); - break; - - case V4L2_CTRL_TYPE_HDR10_CLL_INFO: - break; - - case V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY: - p_hdr10_mastering = p; - - for (i = 0; i < 3; ++i) { - if (p_hdr10_mastering->display_primaries_x[i] < - V4L2_HDR10_MASTERING_PRIMARIES_X_LOW || - p_hdr10_mastering->display_primaries_x[i] > - V4L2_HDR10_MASTERING_PRIMARIES_X_HIGH || - p_hdr10_mastering->display_primaries_y[i] < - V4L2_HDR10_MASTERING_PRIMARIES_Y_LOW || - p_hdr10_mastering->display_primaries_y[i] > - V4L2_HDR10_MASTERING_PRIMARIES_Y_HIGH) - return -EINVAL; - } - - if (p_hdr10_mastering->white_point_x < - V4L2_HDR10_MASTERING_WHITE_POINT_X_LOW || - p_hdr10_mastering->white_point_x > - V4L2_HDR10_MASTERING_WHITE_POINT_X_HIGH || - p_hdr10_mastering->white_point_y < - V4L2_HDR10_MASTERING_WHITE_POINT_Y_LOW || - p_hdr10_mastering->white_point_y > - V4L2_HDR10_MASTERING_WHITE_POINT_Y_HIGH) - return -EINVAL; - - if (p_hdr10_mastering->max_display_mastering_luminance < - V4L2_HDR10_MASTERING_MAX_LUMA_LOW || - p_hdr10_mastering->max_display_mastering_luminance > - V4L2_HDR10_MASTERING_MAX_LUMA_HIGH || - p_hdr10_mastering->min_display_mastering_luminance < - V4L2_HDR10_MASTERING_MIN_LUMA_LOW || - p_hdr10_mastering->min_display_mastering_luminance > - V4L2_HDR10_MASTERING_MIN_LUMA_HIGH) - return -EINVAL; - - /* The following restriction comes from ITU-T Rec. H.265 spec */ - if (p_hdr10_mastering->max_display_mastering_luminance == - V4L2_HDR10_MASTERING_MAX_LUMA_LOW && - p_hdr10_mastering->min_display_mastering_luminance == - V4L2_HDR10_MASTERING_MIN_LUMA_HIGH) - return -EINVAL; - - break; - - case V4L2_CTRL_TYPE_AREA: - area = p; - if (!area->width || !area->height) - return -EINVAL; - break; - - default: - return -EINVAL; - } - - return 0; -} - -static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx, - union v4l2_ctrl_ptr ptr) -{ - size_t len; - u64 offset; - s64 val; - - switch ((u32)ctrl->type) { - case V4L2_CTRL_TYPE_INTEGER: - return ROUND_TO_RANGE(ptr.p_s32[idx], u32, ctrl); - case V4L2_CTRL_TYPE_INTEGER64: - /* - * We can't use the ROUND_TO_RANGE define here due to - * the u64 divide that needs special care. - */ - val = ptr.p_s64[idx]; - if (ctrl->maximum >= 0 && val >= ctrl->maximum - (s64)(ctrl->step / 2)) - val = ctrl->maximum; - else - val += (s64)(ctrl->step / 2); - val = clamp_t(s64, val, ctrl->minimum, ctrl->maximum); - offset = val - ctrl->minimum; - do_div(offset, ctrl->step); - ptr.p_s64[idx] = ctrl->minimum + offset * ctrl->step; - return 0; - case V4L2_CTRL_TYPE_U8: - return ROUND_TO_RANGE(ptr.p_u8[idx], u8, ctrl); - case V4L2_CTRL_TYPE_U16: - return ROUND_TO_RANGE(ptr.p_u16[idx], u16, ctrl); - case V4L2_CTRL_TYPE_U32: - return ROUND_TO_RANGE(ptr.p_u32[idx], u32, ctrl); - - case V4L2_CTRL_TYPE_BOOLEAN: - ptr.p_s32[idx] = !!ptr.p_s32[idx]; - return 0; - - case V4L2_CTRL_TYPE_MENU: - case V4L2_CTRL_TYPE_INTEGER_MENU: - if (ptr.p_s32[idx] < ctrl->minimum || ptr.p_s32[idx] > ctrl->maximum) - return -ERANGE; - if (ptr.p_s32[idx] < BITS_PER_LONG_LONG && - (ctrl->menu_skip_mask & BIT_ULL(ptr.p_s32[idx]))) - return -EINVAL; - if (ctrl->type == V4L2_CTRL_TYPE_MENU && - ctrl->qmenu[ptr.p_s32[idx]][0] == '\0') - return -EINVAL; - return 0; - - case V4L2_CTRL_TYPE_BITMASK: - ptr.p_s32[idx] &= ctrl->maximum; - return 0; - - case V4L2_CTRL_TYPE_BUTTON: - case V4L2_CTRL_TYPE_CTRL_CLASS: - ptr.p_s32[idx] = 0; - return 0; - - case V4L2_CTRL_TYPE_STRING: - idx *= ctrl->elem_size; - len = strlen(ptr.p_char + idx); - if (len < ctrl->minimum) - return -ERANGE; - if ((len - (u32)ctrl->minimum) % (u32)ctrl->step) - return -ERANGE; - return 0; - - default: - return std_validate_compound(ctrl, idx, ptr); - } -} - -static const struct v4l2_ctrl_type_ops std_type_ops = { - .equal = std_equal, - .init = std_init, - .log = std_log, - .validate = std_validate, -}; - -/* Helper function: copy the given control value back to the caller */ -static int ptr_to_user(struct v4l2_ext_control *c, - struct v4l2_ctrl *ctrl, - union v4l2_ctrl_ptr ptr) -{ - u32 len; - - if (ctrl->is_ptr && !ctrl->is_string) - return copy_to_user(c->ptr, ptr.p_const, c->size) ? - -EFAULT : 0; - - switch (ctrl->type) { - case V4L2_CTRL_TYPE_STRING: - len = strlen(ptr.p_char); - if (c->size < len + 1) { - c->size = ctrl->elem_size; - return -ENOSPC; - } - return copy_to_user(c->string, ptr.p_char, len + 1) ? - -EFAULT : 0; - case V4L2_CTRL_TYPE_INTEGER64: - c->value64 = *ptr.p_s64; - break; - default: - c->value = *ptr.p_s32; - break; - } - return 0; -} - -/* Helper function: copy the current control value back to the caller */ -static int cur_to_user(struct v4l2_ext_control *c, - struct v4l2_ctrl *ctrl) -{ - return ptr_to_user(c, ctrl, ctrl->p_cur); -} - -/* Helper function: copy the new control value back to the caller */ -static int new_to_user(struct v4l2_ext_control *c, - struct v4l2_ctrl *ctrl) -{ - return ptr_to_user(c, ctrl, ctrl->p_new); -} - -/* Helper function: copy the request value back to the caller */ -static int req_to_user(struct v4l2_ext_control *c, - struct v4l2_ctrl_ref *ref) -{ - return ptr_to_user(c, ref->ctrl, ref->p_req); -} - -/* Helper function: copy the initial control value back to the caller */ -static int def_to_user(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl) -{ - int idx; - - for (idx = 0; idx < ctrl->elems; idx++) - ctrl->type_ops->init(ctrl, idx, ctrl->p_new); - - return ptr_to_user(c, ctrl, ctrl->p_new); -} - -/* Helper function: copy the caller-provider value to the given control value */ -static int user_to_ptr(struct v4l2_ext_control *c, - struct v4l2_ctrl *ctrl, - union v4l2_ctrl_ptr ptr) -{ - int ret; - u32 size; - - ctrl->is_new = 1; - if (ctrl->is_ptr && !ctrl->is_string) { - unsigned idx; - - ret = copy_from_user(ptr.p, c->ptr, c->size) ? -EFAULT : 0; - if (ret || !ctrl->is_array) - return ret; - for (idx = c->size / ctrl->elem_size; idx < ctrl->elems; idx++) - ctrl->type_ops->init(ctrl, idx, ptr); - return 0; - } - - switch (ctrl->type) { - case V4L2_CTRL_TYPE_INTEGER64: - *ptr.p_s64 = c->value64; - break; - case V4L2_CTRL_TYPE_STRING: - size = c->size; - if (size == 0) - return -ERANGE; - if (size > ctrl->maximum + 1) - size = ctrl->maximum + 1; - ret = copy_from_user(ptr.p_char, c->string, size) ? -EFAULT : 0; - if (!ret) { - char last = ptr.p_char[size - 1]; - - ptr.p_char[size - 1] = 0; - /* If the string was longer than ctrl->maximum, - then return an error. */ - if (strlen(ptr.p_char) == ctrl->maximum && last) - return -ERANGE; - } - return ret; - default: - *ptr.p_s32 = c->value; - break; - } - return 0; -} - -/* Helper function: copy the caller-provider value as the new control value */ -static int user_to_new(struct v4l2_ext_control *c, - struct v4l2_ctrl *ctrl) -{ - return user_to_ptr(c, ctrl, ctrl->p_new); -} - -/* Copy the one value to another. */ -static void ptr_to_ptr(struct v4l2_ctrl *ctrl, - union v4l2_ctrl_ptr from, union v4l2_ctrl_ptr to) -{ - if (ctrl == NULL) - return; - memcpy(to.p, from.p_const, ctrl->elems * ctrl->elem_size); -} - -/* Copy the new value to the current value. */ -static void new_to_cur(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 ch_flags) -{ - bool changed; - - if (ctrl == NULL) - return; - - /* has_changed is set by cluster_changed */ - changed = ctrl->has_changed; - if (changed) - ptr_to_ptr(ctrl, ctrl->p_new, ctrl->p_cur); - - if (ch_flags & V4L2_EVENT_CTRL_CH_FLAGS) { - /* Note: CH_FLAGS is only set for auto clusters. */ - ctrl->flags &= - ~(V4L2_CTRL_FLAG_INACTIVE | V4L2_CTRL_FLAG_VOLATILE); - if (!is_cur_manual(ctrl->cluster[0])) { - ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; - if (ctrl->cluster[0]->has_volatiles) - ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; - } - fh = NULL; - } - if (changed || ch_flags) { - /* If a control was changed that was not one of the controls - modified by the application, then send the event to all. */ - if (!ctrl->is_new) - fh = NULL; - send_event(fh, ctrl, - (changed ? V4L2_EVENT_CTRL_CH_VALUE : 0) | ch_flags); - if (ctrl->call_notify && changed && ctrl->handler->notify) - ctrl->handler->notify(ctrl, ctrl->handler->notify_priv); - } -} - -/* Copy the current value to the new value */ -static void cur_to_new(struct v4l2_ctrl *ctrl) -{ - if (ctrl == NULL) - return; - ptr_to_ptr(ctrl, ctrl->p_cur, ctrl->p_new); -} - -/* Copy the new value to the request value */ -static void new_to_req(struct v4l2_ctrl_ref *ref) -{ - if (!ref) - return; - ptr_to_ptr(ref->ctrl, ref->ctrl->p_new, ref->p_req); - ref->valid_p_req = true; -} - -/* Copy the current value to the request value */ -static void cur_to_req(struct v4l2_ctrl_ref *ref) -{ - if (!ref) - return; - ptr_to_ptr(ref->ctrl, ref->ctrl->p_cur, ref->p_req); - ref->valid_p_req = true; -} - -/* Copy the request value to the new value */ -static void req_to_new(struct v4l2_ctrl_ref *ref) -{ - if (!ref) - return; - if (ref->valid_p_req) - ptr_to_ptr(ref->ctrl, ref->p_req, ref->ctrl->p_new); - else - ptr_to_ptr(ref->ctrl, ref->ctrl->p_cur, ref->ctrl->p_new); -} - -/* Return non-zero if one or more of the controls in the cluster has a new - value that differs from the current value. */ -static int cluster_changed(struct v4l2_ctrl *master) -{ - bool changed = false; - unsigned idx; - int i; - - for (i = 0; i < master->ncontrols; i++) { - struct v4l2_ctrl *ctrl = master->cluster[i]; - bool ctrl_changed = false; - - if (ctrl == NULL) - continue; - - if (ctrl->flags & V4L2_CTRL_FLAG_EXECUTE_ON_WRITE) - changed = ctrl_changed = true; - - /* - * Set has_changed to false to avoid generating - * the event V4L2_EVENT_CTRL_CH_VALUE - */ - if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) { - ctrl->has_changed = false; - continue; - } - - for (idx = 0; !ctrl_changed && idx < ctrl->elems; idx++) - ctrl_changed = !ctrl->type_ops->equal(ctrl, idx, - ctrl->p_cur, ctrl->p_new); - ctrl->has_changed = ctrl_changed; - changed |= ctrl->has_changed; - } - return changed; -} - -/* Control range checking */ -static int check_range(enum v4l2_ctrl_type type, - s64 min, s64 max, u64 step, s64 def) -{ - switch (type) { - case V4L2_CTRL_TYPE_BOOLEAN: - if (step != 1 || max > 1 || min < 0) - return -ERANGE; - fallthrough; - case V4L2_CTRL_TYPE_U8: - case V4L2_CTRL_TYPE_U16: - case V4L2_CTRL_TYPE_U32: - case V4L2_CTRL_TYPE_INTEGER: - case V4L2_CTRL_TYPE_INTEGER64: - if (step == 0 || min > max || def < min || def > max) - return -ERANGE; - return 0; - case V4L2_CTRL_TYPE_BITMASK: - if (step || min || !max || (def & ~max)) - return -ERANGE; - return 0; - case V4L2_CTRL_TYPE_MENU: - case V4L2_CTRL_TYPE_INTEGER_MENU: - if (min > max || def < min || def > max) - return -ERANGE; - /* Note: step == menu_skip_mask for menu controls. - So here we check if the default value is masked out. */ - if (step && ((1 << def) & step)) - return -EINVAL; - return 0; - case V4L2_CTRL_TYPE_STRING: - if (min > max || min < 0 || step < 1 || def) - return -ERANGE; - return 0; - default: - return 0; - } -} - -/* Validate a new control */ -static int validate_new(const struct v4l2_ctrl *ctrl, union v4l2_ctrl_ptr p_new) -{ - unsigned idx; - int err = 0; - - for (idx = 0; !err && idx < ctrl->elems; idx++) - err = ctrl->type_ops->validate(ctrl, idx, p_new); - return err; -} - -static inline u32 node2id(struct list_head *node) -{ - return list_entry(node, struct v4l2_ctrl_ref, node)->ctrl->id; -} - -/* Set the handler's error code if it wasn't set earlier already */ -static inline int handler_set_err(struct v4l2_ctrl_handler *hdl, int err) -{ - if (hdl->error == 0) - hdl->error = err; - return err; -} - -/* Initialize the handler */ -int v4l2_ctrl_handler_init_class(struct v4l2_ctrl_handler *hdl, - unsigned nr_of_controls_hint, - struct lock_class_key *key, const char *name) -{ - mutex_init(&hdl->_lock); - hdl->lock = &hdl->_lock; - lockdep_set_class_and_name(hdl->lock, key, name); - INIT_LIST_HEAD(&hdl->ctrls); - INIT_LIST_HEAD(&hdl->ctrl_refs); - INIT_LIST_HEAD(&hdl->requests); - INIT_LIST_HEAD(&hdl->requests_queued); - hdl->request_is_queued = false; - hdl->nr_of_buckets = 1 + nr_of_controls_hint / 8; - hdl->buckets = kvmalloc_array(hdl->nr_of_buckets, - sizeof(hdl->buckets[0]), - GFP_KERNEL | __GFP_ZERO); - hdl->error = hdl->buckets ? 0 : -ENOMEM; - media_request_object_init(&hdl->req_obj); - return hdl->error; -} -EXPORT_SYMBOL(v4l2_ctrl_handler_init_class); - -/* Free all controls and control refs */ -void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl) -{ - struct v4l2_ctrl_ref *ref, *next_ref; - struct v4l2_ctrl *ctrl, *next_ctrl; - struct v4l2_subscribed_event *sev, *next_sev; - - if (hdl == NULL || hdl->buckets == NULL) - return; - - /* - * If the main handler is freed and it is used by handler objects in - * outstanding requests, then unbind and put those objects before - * freeing the main handler. - * - * The main handler can be identified by having a NULL ops pointer in - * the request object. - */ - if (!hdl->req_obj.ops && !list_empty(&hdl->requests)) { - struct v4l2_ctrl_handler *req, *next_req; - - list_for_each_entry_safe(req, next_req, &hdl->requests, requests) { - media_request_object_unbind(&req->req_obj); - media_request_object_put(&req->req_obj); - } - } - mutex_lock(hdl->lock); - /* Free all nodes */ - list_for_each_entry_safe(ref, next_ref, &hdl->ctrl_refs, node) { - list_del(&ref->node); - kfree(ref); - } - /* Free all controls owned by the handler */ - list_for_each_entry_safe(ctrl, next_ctrl, &hdl->ctrls, node) { - list_del(&ctrl->node); - list_for_each_entry_safe(sev, next_sev, &ctrl->ev_subs, node) - list_del(&sev->node); - kvfree(ctrl); - } - kvfree(hdl->buckets); - hdl->buckets = NULL; - hdl->cached = NULL; - hdl->error = 0; - mutex_unlock(hdl->lock); - mutex_destroy(&hdl->_lock); -} -EXPORT_SYMBOL(v4l2_ctrl_handler_free); - -/* For backwards compatibility: V4L2_CID_PRIVATE_BASE should no longer - be used except in G_CTRL, S_CTRL, QUERYCTRL and QUERYMENU when dealing - with applications that do not use the NEXT_CTRL flag. - - We just find the n-th private user control. It's O(N), but that should not - be an issue in this particular case. */ -static struct v4l2_ctrl_ref *find_private_ref( - struct v4l2_ctrl_handler *hdl, u32 id) -{ - struct v4l2_ctrl_ref *ref; - - id -= V4L2_CID_PRIVATE_BASE; - list_for_each_entry(ref, &hdl->ctrl_refs, node) { - /* Search for private user controls that are compatible with - VIDIOC_G/S_CTRL. */ - if (V4L2_CTRL_ID2WHICH(ref->ctrl->id) == V4L2_CTRL_CLASS_USER && - V4L2_CTRL_DRIVER_PRIV(ref->ctrl->id)) { - if (!ref->ctrl->is_int) - continue; - if (id == 0) - return ref; - id--; - } - } - return NULL; -} - -/* Find a control with the given ID. */ -static struct v4l2_ctrl_ref *find_ref(struct v4l2_ctrl_handler *hdl, u32 id) -{ - struct v4l2_ctrl_ref *ref; - int bucket; - - id &= V4L2_CTRL_ID_MASK; - - /* Old-style private controls need special handling */ - if (id >= V4L2_CID_PRIVATE_BASE) - return find_private_ref(hdl, id); - bucket = id % hdl->nr_of_buckets; - - /* Simple optimization: cache the last control found */ - if (hdl->cached && hdl->cached->ctrl->id == id) - return hdl->cached; - - /* Not in cache, search the hash */ - ref = hdl->buckets ? hdl->buckets[bucket] : NULL; - while (ref && ref->ctrl->id != id) - ref = ref->next; - - if (ref) - hdl->cached = ref; /* cache it! */ - return ref; -} - -/* Find a control with the given ID. Take the handler's lock first. */ -static struct v4l2_ctrl_ref *find_ref_lock( - struct v4l2_ctrl_handler *hdl, u32 id) -{ - struct v4l2_ctrl_ref *ref = NULL; - - if (hdl) { - mutex_lock(hdl->lock); - ref = find_ref(hdl, id); - mutex_unlock(hdl->lock); - } - return ref; -} - -/* Find a control with the given ID. */ -struct v4l2_ctrl *v4l2_ctrl_find(struct v4l2_ctrl_handler *hdl, u32 id) -{ - struct v4l2_ctrl_ref *ref = find_ref_lock(hdl, id); - - return ref ? ref->ctrl : NULL; -} -EXPORT_SYMBOL(v4l2_ctrl_find); - -/* Allocate a new v4l2_ctrl_ref and hook it into the handler. */ -static int handler_new_ref(struct v4l2_ctrl_handler *hdl, - struct v4l2_ctrl *ctrl, - struct v4l2_ctrl_ref **ctrl_ref, - bool from_other_dev, bool allocate_req) -{ - struct v4l2_ctrl_ref *ref; - struct v4l2_ctrl_ref *new_ref; - u32 id = ctrl->id; - u32 class_ctrl = V4L2_CTRL_ID2WHICH(id) | 1; - int bucket = id % hdl->nr_of_buckets; /* which bucket to use */ - unsigned int size_extra_req = 0; - - if (ctrl_ref) - *ctrl_ref = NULL; - - /* - * Automatically add the control class if it is not yet present and - * the new control is not a compound control. - */ - if (ctrl->type < V4L2_CTRL_COMPOUND_TYPES && - id != class_ctrl && find_ref_lock(hdl, class_ctrl) == NULL) - if (!v4l2_ctrl_new_std(hdl, NULL, class_ctrl, 0, 0, 0, 0)) - return hdl->error; - - if (hdl->error) - return hdl->error; - - if (allocate_req) - size_extra_req = ctrl->elems * ctrl->elem_size; - new_ref = kzalloc(sizeof(*new_ref) + size_extra_req, GFP_KERNEL); - if (!new_ref) - return handler_set_err(hdl, -ENOMEM); - new_ref->ctrl = ctrl; - new_ref->from_other_dev = from_other_dev; - if (size_extra_req) - new_ref->p_req.p = &new_ref[1]; - - INIT_LIST_HEAD(&new_ref->node); - - mutex_lock(hdl->lock); - - /* Add immediately at the end of the list if the list is empty, or if - the last element in the list has a lower ID. - This ensures that when elements are added in ascending order the - insertion is an O(1) operation. */ - if (list_empty(&hdl->ctrl_refs) || id > node2id(hdl->ctrl_refs.prev)) { - list_add_tail(&new_ref->node, &hdl->ctrl_refs); - goto insert_in_hash; - } - - /* Find insert position in sorted list */ - list_for_each_entry(ref, &hdl->ctrl_refs, node) { - if (ref->ctrl->id < id) - continue; - /* Don't add duplicates */ - if (ref->ctrl->id == id) { - kfree(new_ref); - goto unlock; - } - list_add(&new_ref->node, ref->node.prev); - break; - } - -insert_in_hash: - /* Insert the control node in the hash */ - new_ref->next = hdl->buckets[bucket]; - hdl->buckets[bucket] = new_ref; - if (ctrl_ref) - *ctrl_ref = new_ref; - if (ctrl->handler == hdl) { - /* By default each control starts in a cluster of its own. - * new_ref->ctrl is basically a cluster array with one - * element, so that's perfect to use as the cluster pointer. - * But only do this for the handler that owns the control. - */ - ctrl->cluster = &new_ref->ctrl; - ctrl->ncontrols = 1; - } - -unlock: - mutex_unlock(hdl->lock); - return 0; -} - -/* Add a new control */ -static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, - const struct v4l2_ctrl_ops *ops, - const struct v4l2_ctrl_type_ops *type_ops, - u32 id, const char *name, enum v4l2_ctrl_type type, - s64 min, s64 max, u64 step, s64 def, - const u32 dims[V4L2_CTRL_MAX_DIMS], u32 elem_size, - u32 flags, const char * const *qmenu, - const s64 *qmenu_int, const union v4l2_ctrl_ptr p_def, - void *priv) -{ - struct v4l2_ctrl *ctrl; - unsigned sz_extra; - unsigned nr_of_dims = 0; - unsigned elems = 1; - bool is_array; - unsigned tot_ctrl_size; - unsigned idx; - void *data; - int err; - - if (hdl->error) - return NULL; - - while (dims && dims[nr_of_dims]) { - elems *= dims[nr_of_dims]; - nr_of_dims++; - if (nr_of_dims == V4L2_CTRL_MAX_DIMS) - break; - } - is_array = nr_of_dims > 0; - - /* Prefill elem_size for all types handled by std_type_ops */ - switch ((u32)type) { - case V4L2_CTRL_TYPE_INTEGER64: - elem_size = sizeof(s64); - break; - case V4L2_CTRL_TYPE_STRING: - elem_size = max + 1; - break; - case V4L2_CTRL_TYPE_U8: - elem_size = sizeof(u8); - break; - case V4L2_CTRL_TYPE_U16: - elem_size = sizeof(u16); - break; - case V4L2_CTRL_TYPE_U32: - elem_size = sizeof(u32); - break; - case V4L2_CTRL_TYPE_MPEG2_SEQUENCE: - elem_size = sizeof(struct v4l2_ctrl_mpeg2_sequence); - break; - case V4L2_CTRL_TYPE_MPEG2_PICTURE: - elem_size = sizeof(struct v4l2_ctrl_mpeg2_picture); - break; - case V4L2_CTRL_TYPE_MPEG2_QUANTISATION: - elem_size = sizeof(struct v4l2_ctrl_mpeg2_quantisation); - break; - case V4L2_CTRL_TYPE_FWHT_PARAMS: - elem_size = sizeof(struct v4l2_ctrl_fwht_params); - break; - case V4L2_CTRL_TYPE_H264_SPS: - elem_size = sizeof(struct v4l2_ctrl_h264_sps); - break; - case V4L2_CTRL_TYPE_H264_PPS: - elem_size = sizeof(struct v4l2_ctrl_h264_pps); - break; - case V4L2_CTRL_TYPE_H264_SCALING_MATRIX: - elem_size = sizeof(struct v4l2_ctrl_h264_scaling_matrix); - break; - case V4L2_CTRL_TYPE_H264_SLICE_PARAMS: - elem_size = sizeof(struct v4l2_ctrl_h264_slice_params); - break; - case V4L2_CTRL_TYPE_H264_DECODE_PARAMS: - elem_size = sizeof(struct v4l2_ctrl_h264_decode_params); - break; - case V4L2_CTRL_TYPE_H264_PRED_WEIGHTS: - elem_size = sizeof(struct v4l2_ctrl_h264_pred_weights); - break; - case V4L2_CTRL_TYPE_VP8_FRAME: - elem_size = sizeof(struct v4l2_ctrl_vp8_frame); - break; - case V4L2_CTRL_TYPE_HEVC_SPS: - elem_size = sizeof(struct v4l2_ctrl_hevc_sps); - break; - case V4L2_CTRL_TYPE_HEVC_PPS: - elem_size = sizeof(struct v4l2_ctrl_hevc_pps); - break; - case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS: - elem_size = sizeof(struct v4l2_ctrl_hevc_slice_params); - break; - case V4L2_CTRL_TYPE_HDR10_CLL_INFO: - elem_size = sizeof(struct v4l2_ctrl_hdr10_cll_info); - break; - case V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY: - elem_size = sizeof(struct v4l2_ctrl_hdr10_mastering_display); - break; - case V4L2_CTRL_TYPE_AREA: - elem_size = sizeof(struct v4l2_area); - break; - default: - if (type < V4L2_CTRL_COMPOUND_TYPES) - elem_size = sizeof(s32); - break; - } - tot_ctrl_size = elem_size * elems; - - /* Sanity checks */ - if (id == 0 || name == NULL || !elem_size || - id >= V4L2_CID_PRIVATE_BASE || - (type == V4L2_CTRL_TYPE_MENU && qmenu == NULL) || - (type == V4L2_CTRL_TYPE_INTEGER_MENU && qmenu_int == NULL)) { - handler_set_err(hdl, -ERANGE); - return NULL; - } - err = check_range(type, min, max, step, def); - if (err) { - handler_set_err(hdl, err); - return NULL; - } - if (is_array && - (type == V4L2_CTRL_TYPE_BUTTON || - type == V4L2_CTRL_TYPE_CTRL_CLASS)) { - handler_set_err(hdl, -EINVAL); - return NULL; - } - - sz_extra = 0; - if (type == V4L2_CTRL_TYPE_BUTTON) - flags |= V4L2_CTRL_FLAG_WRITE_ONLY | - V4L2_CTRL_FLAG_EXECUTE_ON_WRITE; - else if (type == V4L2_CTRL_TYPE_CTRL_CLASS) - flags |= V4L2_CTRL_FLAG_READ_ONLY; - else if (type == V4L2_CTRL_TYPE_INTEGER64 || - type == V4L2_CTRL_TYPE_STRING || - type >= V4L2_CTRL_COMPOUND_TYPES || - is_array) - sz_extra += 2 * tot_ctrl_size; - - if (type >= V4L2_CTRL_COMPOUND_TYPES && p_def.p_const) - sz_extra += elem_size; - - ctrl = kvzalloc(sizeof(*ctrl) + sz_extra, GFP_KERNEL); - if (ctrl == NULL) { - handler_set_err(hdl, -ENOMEM); - return NULL; - } - - INIT_LIST_HEAD(&ctrl->node); - INIT_LIST_HEAD(&ctrl->ev_subs); - ctrl->handler = hdl; - ctrl->ops = ops; - ctrl->type_ops = type_ops ? type_ops : &std_type_ops; - ctrl->id = id; - ctrl->name = name; - ctrl->type = type; - ctrl->flags = flags; - ctrl->minimum = min; - ctrl->maximum = max; - ctrl->step = step; - ctrl->default_value = def; - ctrl->is_string = !is_array && type == V4L2_CTRL_TYPE_STRING; - ctrl->is_ptr = is_array || type >= V4L2_CTRL_COMPOUND_TYPES || ctrl->is_string; - ctrl->is_int = !ctrl->is_ptr && type != V4L2_CTRL_TYPE_INTEGER64; - ctrl->is_array = is_array; - ctrl->elems = elems; - ctrl->nr_of_dims = nr_of_dims; - if (nr_of_dims) - memcpy(ctrl->dims, dims, nr_of_dims * sizeof(dims[0])); - ctrl->elem_size = elem_size; - if (type == V4L2_CTRL_TYPE_MENU) - ctrl->qmenu = qmenu; - else if (type == V4L2_CTRL_TYPE_INTEGER_MENU) - ctrl->qmenu_int = qmenu_int; - ctrl->priv = priv; - ctrl->cur.val = ctrl->val = def; - data = &ctrl[1]; - - if (!ctrl->is_int) { - ctrl->p_new.p = data; - ctrl->p_cur.p = data + tot_ctrl_size; - } else { - ctrl->p_new.p = &ctrl->val; - ctrl->p_cur.p = &ctrl->cur.val; - } - - if (type >= V4L2_CTRL_COMPOUND_TYPES && p_def.p_const) { - ctrl->p_def.p = ctrl->p_cur.p + tot_ctrl_size; - memcpy(ctrl->p_def.p, p_def.p_const, elem_size); - } - - for (idx = 0; idx < elems; idx++) { - ctrl->type_ops->init(ctrl, idx, ctrl->p_cur); - ctrl->type_ops->init(ctrl, idx, ctrl->p_new); - } - - if (handler_new_ref(hdl, ctrl, NULL, false, false)) { - kvfree(ctrl); - return NULL; - } - mutex_lock(hdl->lock); - list_add_tail(&ctrl->node, &hdl->ctrls); - mutex_unlock(hdl->lock); - return ctrl; -} - -struct v4l2_ctrl *v4l2_ctrl_new_custom(struct v4l2_ctrl_handler *hdl, - const struct v4l2_ctrl_config *cfg, void *priv) -{ - bool is_menu; - struct v4l2_ctrl *ctrl; - const char *name = cfg->name; - const char * const *qmenu = cfg->qmenu; - const s64 *qmenu_int = cfg->qmenu_int; - enum v4l2_ctrl_type type = cfg->type; - u32 flags = cfg->flags; - s64 min = cfg->min; - s64 max = cfg->max; - u64 step = cfg->step; - s64 def = cfg->def; - - if (name == NULL) - v4l2_ctrl_fill(cfg->id, &name, &type, &min, &max, &step, - &def, &flags); - - is_menu = (type == V4L2_CTRL_TYPE_MENU || - type == V4L2_CTRL_TYPE_INTEGER_MENU); - if (is_menu) - WARN_ON(step); - else - WARN_ON(cfg->menu_skip_mask); - if (type == V4L2_CTRL_TYPE_MENU && !qmenu) { - qmenu = v4l2_ctrl_get_menu(cfg->id); - } else if (type == V4L2_CTRL_TYPE_INTEGER_MENU && !qmenu_int) { - handler_set_err(hdl, -EINVAL); - return NULL; - } - - ctrl = v4l2_ctrl_new(hdl, cfg->ops, cfg->type_ops, cfg->id, name, - type, min, max, - is_menu ? cfg->menu_skip_mask : step, def, - cfg->dims, cfg->elem_size, - flags, qmenu, qmenu_int, cfg->p_def, priv); - if (ctrl) - ctrl->is_private = cfg->is_private; - return ctrl; -} -EXPORT_SYMBOL(v4l2_ctrl_new_custom); - -/* Helper function for standard non-menu controls */ -struct v4l2_ctrl *v4l2_ctrl_new_std(struct v4l2_ctrl_handler *hdl, - const struct v4l2_ctrl_ops *ops, - u32 id, s64 min, s64 max, u64 step, s64 def) -{ - const char *name; - enum v4l2_ctrl_type type; - u32 flags; - - v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags); - if (type == V4L2_CTRL_TYPE_MENU || - type == V4L2_CTRL_TYPE_INTEGER_MENU || - type >= V4L2_CTRL_COMPOUND_TYPES) { - handler_set_err(hdl, -EINVAL); - return NULL; - } - return v4l2_ctrl_new(hdl, ops, NULL, id, name, type, - min, max, step, def, NULL, 0, - flags, NULL, NULL, ptr_null, NULL); -} -EXPORT_SYMBOL(v4l2_ctrl_new_std); - -/* Helper function for standard menu controls */ -struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl, - const struct v4l2_ctrl_ops *ops, - u32 id, u8 _max, u64 mask, u8 _def) -{ - const char * const *qmenu = NULL; - const s64 *qmenu_int = NULL; - unsigned int qmenu_int_len = 0; - const char *name; - enum v4l2_ctrl_type type; - s64 min; - s64 max = _max; - s64 def = _def; - u64 step; - u32 flags; - - v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags); - - if (type == V4L2_CTRL_TYPE_MENU) - qmenu = v4l2_ctrl_get_menu(id); - else if (type == V4L2_CTRL_TYPE_INTEGER_MENU) - qmenu_int = v4l2_ctrl_get_int_menu(id, &qmenu_int_len); - - if ((!qmenu && !qmenu_int) || (qmenu_int && max > qmenu_int_len)) { - handler_set_err(hdl, -EINVAL); - return NULL; - } - return v4l2_ctrl_new(hdl, ops, NULL, id, name, type, - 0, max, mask, def, NULL, 0, - flags, qmenu, qmenu_int, ptr_null, NULL); -} -EXPORT_SYMBOL(v4l2_ctrl_new_std_menu); - -/* Helper function for standard menu controls with driver defined menu */ -struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items(struct v4l2_ctrl_handler *hdl, - const struct v4l2_ctrl_ops *ops, u32 id, u8 _max, - u64 mask, u8 _def, const char * const *qmenu) -{ - enum v4l2_ctrl_type type; - const char *name; - u32 flags; - u64 step; - s64 min; - s64 max = _max; - s64 def = _def; - - /* v4l2_ctrl_new_std_menu_items() should only be called for - * standard controls without a standard menu. - */ - if (v4l2_ctrl_get_menu(id)) { - handler_set_err(hdl, -EINVAL); - return NULL; - } - - v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags); - if (type != V4L2_CTRL_TYPE_MENU || qmenu == NULL) { - handler_set_err(hdl, -EINVAL); - return NULL; - } - return v4l2_ctrl_new(hdl, ops, NULL, id, name, type, - 0, max, mask, def, NULL, 0, - flags, qmenu, NULL, ptr_null, NULL); - -} -EXPORT_SYMBOL(v4l2_ctrl_new_std_menu_items); - -/* Helper function for standard compound controls */ -struct v4l2_ctrl *v4l2_ctrl_new_std_compound(struct v4l2_ctrl_handler *hdl, - const struct v4l2_ctrl_ops *ops, u32 id, - const union v4l2_ctrl_ptr p_def) -{ - const char *name; - enum v4l2_ctrl_type type; - u32 flags; - s64 min, max, step, def; - - v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags); - if (type < V4L2_CTRL_COMPOUND_TYPES) { - handler_set_err(hdl, -EINVAL); - return NULL; - } - return v4l2_ctrl_new(hdl, ops, NULL, id, name, type, - min, max, step, def, NULL, 0, - flags, NULL, NULL, p_def, NULL); -} -EXPORT_SYMBOL(v4l2_ctrl_new_std_compound); - -/* Helper function for standard integer menu controls */ -struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl, - const struct v4l2_ctrl_ops *ops, - u32 id, u8 _max, u8 _def, const s64 *qmenu_int) -{ - const char *name; - enum v4l2_ctrl_type type; - s64 min; - u64 step; - s64 max = _max; - s64 def = _def; - u32 flags; - - v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags); - if (type != V4L2_CTRL_TYPE_INTEGER_MENU) { - handler_set_err(hdl, -EINVAL); - return NULL; - } - return v4l2_ctrl_new(hdl, ops, NULL, id, name, type, - 0, max, 0, def, NULL, 0, - flags, NULL, qmenu_int, ptr_null, NULL); -} -EXPORT_SYMBOL(v4l2_ctrl_new_int_menu); - -/* Add the controls from another handler to our own. */ -int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl, - struct v4l2_ctrl_handler *add, - bool (*filter)(const struct v4l2_ctrl *ctrl), - bool from_other_dev) -{ - struct v4l2_ctrl_ref *ref; - int ret = 0; - - /* Do nothing if either handler is NULL or if they are the same */ - if (!hdl || !add || hdl == add) - return 0; - if (hdl->error) - return hdl->error; - mutex_lock(add->lock); - list_for_each_entry(ref, &add->ctrl_refs, node) { - struct v4l2_ctrl *ctrl = ref->ctrl; - - /* Skip handler-private controls. */ - if (ctrl->is_private) - continue; - /* And control classes */ - if (ctrl->type == V4L2_CTRL_TYPE_CTRL_CLASS) - continue; - /* Filter any unwanted controls */ - if (filter && !filter(ctrl)) - continue; - ret = handler_new_ref(hdl, ctrl, NULL, from_other_dev, false); - if (ret) - break; - } - mutex_unlock(add->lock); - return ret; -} -EXPORT_SYMBOL(v4l2_ctrl_add_handler); - -bool v4l2_ctrl_radio_filter(const struct v4l2_ctrl *ctrl) -{ - if (V4L2_CTRL_ID2WHICH(ctrl->id) == V4L2_CTRL_CLASS_FM_TX) - return true; - if (V4L2_CTRL_ID2WHICH(ctrl->id) == V4L2_CTRL_CLASS_FM_RX) - return true; - switch (ctrl->id) { - case V4L2_CID_AUDIO_MUTE: - case V4L2_CID_AUDIO_VOLUME: - case V4L2_CID_AUDIO_BALANCE: - case V4L2_CID_AUDIO_BASS: - case V4L2_CID_AUDIO_TREBLE: - case V4L2_CID_AUDIO_LOUDNESS: - return true; - default: - break; - } - return false; -} -EXPORT_SYMBOL(v4l2_ctrl_radio_filter); - -/* Cluster controls */ -void v4l2_ctrl_cluster(unsigned ncontrols, struct v4l2_ctrl **controls) -{ - bool has_volatiles = false; - int i; - - /* The first control is the master control and it must not be NULL */ - if (WARN_ON(ncontrols == 0 || controls[0] == NULL)) - return; - - for (i = 0; i < ncontrols; i++) { - if (controls[i]) { - controls[i]->cluster = controls; - controls[i]->ncontrols = ncontrols; - if (controls[i]->flags & V4L2_CTRL_FLAG_VOLATILE) - has_volatiles = true; - } - } - controls[0]->has_volatiles = has_volatiles; -} -EXPORT_SYMBOL(v4l2_ctrl_cluster); - -void v4l2_ctrl_auto_cluster(unsigned ncontrols, struct v4l2_ctrl **controls, - u8 manual_val, bool set_volatile) -{ - struct v4l2_ctrl *master = controls[0]; - u32 flag = 0; - int i; - - v4l2_ctrl_cluster(ncontrols, controls); - WARN_ON(ncontrols <= 1); - WARN_ON(manual_val < master->minimum || manual_val > master->maximum); - WARN_ON(set_volatile && !has_op(master, g_volatile_ctrl)); - master->is_auto = true; - master->has_volatiles = set_volatile; - master->manual_mode_value = manual_val; - master->flags |= V4L2_CTRL_FLAG_UPDATE; - - if (!is_cur_manual(master)) - flag = V4L2_CTRL_FLAG_INACTIVE | - (set_volatile ? V4L2_CTRL_FLAG_VOLATILE : 0); - - for (i = 1; i < ncontrols; i++) - if (controls[i]) - controls[i]->flags |= flag; -} -EXPORT_SYMBOL(v4l2_ctrl_auto_cluster); - -/* Activate/deactivate a control. */ -void v4l2_ctrl_activate(struct v4l2_ctrl *ctrl, bool active) -{ - /* invert since the actual flag is called 'inactive' */ - bool inactive = !active; - bool old; - - if (ctrl == NULL) - return; - - if (inactive) - /* set V4L2_CTRL_FLAG_INACTIVE */ - old = test_and_set_bit(4, &ctrl->flags); - else - /* clear V4L2_CTRL_FLAG_INACTIVE */ - old = test_and_clear_bit(4, &ctrl->flags); - if (old != inactive) - send_event(NULL, ctrl, V4L2_EVENT_CTRL_CH_FLAGS); -} -EXPORT_SYMBOL(v4l2_ctrl_activate); - -void __v4l2_ctrl_grab(struct v4l2_ctrl *ctrl, bool grabbed) -{ - bool old; - - if (ctrl == NULL) - return; - - lockdep_assert_held(ctrl->handler->lock); - - if (grabbed) - /* set V4L2_CTRL_FLAG_GRABBED */ - old = test_and_set_bit(1, &ctrl->flags); - else - /* clear V4L2_CTRL_FLAG_GRABBED */ - old = test_and_clear_bit(1, &ctrl->flags); - if (old != grabbed) - send_event(NULL, ctrl, V4L2_EVENT_CTRL_CH_FLAGS); -} -EXPORT_SYMBOL(__v4l2_ctrl_grab); - -/* Log the control name and value */ -static void log_ctrl(const struct v4l2_ctrl *ctrl, - const char *prefix, const char *colon) -{ - if (ctrl->flags & (V4L2_CTRL_FLAG_DISABLED | V4L2_CTRL_FLAG_WRITE_ONLY)) - return; - if (ctrl->type == V4L2_CTRL_TYPE_CTRL_CLASS) - return; - - pr_info("%s%s%s: ", prefix, colon, ctrl->name); - - ctrl->type_ops->log(ctrl); - - if (ctrl->flags & (V4L2_CTRL_FLAG_INACTIVE | - V4L2_CTRL_FLAG_GRABBED | - V4L2_CTRL_FLAG_VOLATILE)) { - if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE) - pr_cont(" inactive"); - if (ctrl->flags & V4L2_CTRL_FLAG_GRABBED) - pr_cont(" grabbed"); - if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) - pr_cont(" volatile"); - } - pr_cont("\n"); -} - -/* Log all controls owned by the handler */ -void v4l2_ctrl_handler_log_status(struct v4l2_ctrl_handler *hdl, - const char *prefix) -{ - struct v4l2_ctrl *ctrl; - const char *colon = ""; - int len; - - if (hdl == NULL) - return; - if (prefix == NULL) - prefix = ""; - len = strlen(prefix); - if (len && prefix[len - 1] != ' ') - colon = ": "; - mutex_lock(hdl->lock); - list_for_each_entry(ctrl, &hdl->ctrls, node) - if (!(ctrl->flags & V4L2_CTRL_FLAG_DISABLED)) - log_ctrl(ctrl, prefix, colon); - mutex_unlock(hdl->lock); -} -EXPORT_SYMBOL(v4l2_ctrl_handler_log_status); - -int v4l2_ctrl_subdev_log_status(struct v4l2_subdev *sd) -{ - v4l2_ctrl_handler_log_status(sd->ctrl_handler, sd->name); - return 0; -} -EXPORT_SYMBOL(v4l2_ctrl_subdev_log_status); - -/* Call s_ctrl for all controls owned by the handler */ -int __v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl) -{ - struct v4l2_ctrl *ctrl; - int ret = 0; - - if (hdl == NULL) - return 0; - - lockdep_assert_held(hdl->lock); - - list_for_each_entry(ctrl, &hdl->ctrls, node) - ctrl->done = false; - - list_for_each_entry(ctrl, &hdl->ctrls, node) { - struct v4l2_ctrl *master = ctrl->cluster[0]; - int i; - - /* Skip if this control was already handled by a cluster. */ - /* Skip button controls and read-only controls. */ - if (ctrl->done || ctrl->type == V4L2_CTRL_TYPE_BUTTON || - (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY)) - continue; - - for (i = 0; i < master->ncontrols; i++) { - if (master->cluster[i]) { - cur_to_new(master->cluster[i]); - master->cluster[i]->is_new = 1; - master->cluster[i]->done = true; - } - } - ret = call_op(master, s_ctrl); - if (ret) - break; - } - - return ret; -} -EXPORT_SYMBOL_GPL(__v4l2_ctrl_handler_setup); - -int v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl) -{ - int ret; - - if (hdl == NULL) - return 0; - - mutex_lock(hdl->lock); - ret = __v4l2_ctrl_handler_setup(hdl); - mutex_unlock(hdl->lock); - - return ret; -} -EXPORT_SYMBOL(v4l2_ctrl_handler_setup); - -/* Implement VIDIOC_QUERY_EXT_CTRL */ -int v4l2_query_ext_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_query_ext_ctrl *qc) -{ - const unsigned next_flags = V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND; - u32 id = qc->id & V4L2_CTRL_ID_MASK; - struct v4l2_ctrl_ref *ref; - struct v4l2_ctrl *ctrl; - - if (hdl == NULL) - return -EINVAL; - - mutex_lock(hdl->lock); - - /* Try to find it */ - ref = find_ref(hdl, id); - - if ((qc->id & next_flags) && !list_empty(&hdl->ctrl_refs)) { - bool is_compound; - /* Match any control that is not hidden */ - unsigned mask = 1; - bool match = false; - - if ((qc->id & next_flags) == V4L2_CTRL_FLAG_NEXT_COMPOUND) { - /* Match any hidden control */ - match = true; - } else if ((qc->id & next_flags) == next_flags) { - /* Match any control, compound or not */ - mask = 0; - } - - /* Find the next control with ID > qc->id */ - - /* Did we reach the end of the control list? */ - if (id >= node2id(hdl->ctrl_refs.prev)) { - ref = NULL; /* Yes, so there is no next control */ - } else if (ref) { - /* We found a control with the given ID, so just get - the next valid one in the list. */ - list_for_each_entry_continue(ref, &hdl->ctrl_refs, node) { - is_compound = ref->ctrl->is_array || - ref->ctrl->type >= V4L2_CTRL_COMPOUND_TYPES; - if (id < ref->ctrl->id && - (is_compound & mask) == match) - break; - } - if (&ref->node == &hdl->ctrl_refs) - ref = NULL; - } else { - /* No control with the given ID exists, so start - searching for the next largest ID. We know there - is one, otherwise the first 'if' above would have - been true. */ - list_for_each_entry(ref, &hdl->ctrl_refs, node) { - is_compound = ref->ctrl->is_array || - ref->ctrl->type >= V4L2_CTRL_COMPOUND_TYPES; - if (id < ref->ctrl->id && - (is_compound & mask) == match) - break; - } - if (&ref->node == &hdl->ctrl_refs) - ref = NULL; - } - } - mutex_unlock(hdl->lock); - - if (!ref) - return -EINVAL; - - ctrl = ref->ctrl; - memset(qc, 0, sizeof(*qc)); - if (id >= V4L2_CID_PRIVATE_BASE) - qc->id = id; - else - qc->id = ctrl->id; - strscpy(qc->name, ctrl->name, sizeof(qc->name)); - qc->flags = user_flags(ctrl); - qc->type = ctrl->type; - qc->elem_size = ctrl->elem_size; - qc->elems = ctrl->elems; - qc->nr_of_dims = ctrl->nr_of_dims; - memcpy(qc->dims, ctrl->dims, qc->nr_of_dims * sizeof(qc->dims[0])); - qc->minimum = ctrl->minimum; - qc->maximum = ctrl->maximum; - qc->default_value = ctrl->default_value; - if (ctrl->type == V4L2_CTRL_TYPE_MENU - || ctrl->type == V4L2_CTRL_TYPE_INTEGER_MENU) - qc->step = 1; - else - qc->step = ctrl->step; - return 0; -} -EXPORT_SYMBOL(v4l2_query_ext_ctrl); - -/* Implement VIDIOC_QUERYCTRL */ -int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc) -{ - struct v4l2_query_ext_ctrl qec = { qc->id }; - int rc; - - rc = v4l2_query_ext_ctrl(hdl, &qec); - if (rc) - return rc; - - qc->id = qec.id; - qc->type = qec.type; - qc->flags = qec.flags; - strscpy(qc->name, qec.name, sizeof(qc->name)); - switch (qc->type) { - case V4L2_CTRL_TYPE_INTEGER: - case V4L2_CTRL_TYPE_BOOLEAN: - case V4L2_CTRL_TYPE_MENU: - case V4L2_CTRL_TYPE_INTEGER_MENU: - case V4L2_CTRL_TYPE_STRING: - case V4L2_CTRL_TYPE_BITMASK: - qc->minimum = qec.minimum; - qc->maximum = qec.maximum; - qc->step = qec.step; - qc->default_value = qec.default_value; - break; - default: - qc->minimum = 0; - qc->maximum = 0; - qc->step = 0; - qc->default_value = 0; - break; - } - return 0; -} -EXPORT_SYMBOL(v4l2_queryctrl); - -/* Implement VIDIOC_QUERYMENU */ -int v4l2_querymenu(struct v4l2_ctrl_handler *hdl, struct v4l2_querymenu *qm) -{ - struct v4l2_ctrl *ctrl; - u32 i = qm->index; - - ctrl = v4l2_ctrl_find(hdl, qm->id); - if (!ctrl) - return -EINVAL; - - qm->reserved = 0; - /* Sanity checks */ - switch (ctrl->type) { - case V4L2_CTRL_TYPE_MENU: - if (ctrl->qmenu == NULL) - return -EINVAL; - break; - case V4L2_CTRL_TYPE_INTEGER_MENU: - if (ctrl->qmenu_int == NULL) - return -EINVAL; - break; - default: - return -EINVAL; - } - - if (i < ctrl->minimum || i > ctrl->maximum) - return -EINVAL; - - /* Use mask to see if this menu item should be skipped */ - if (ctrl->menu_skip_mask & (1ULL << i)) - return -EINVAL; - /* Empty menu items should also be skipped */ - if (ctrl->type == V4L2_CTRL_TYPE_MENU) { - if (ctrl->qmenu[i] == NULL || ctrl->qmenu[i][0] == '\0') - return -EINVAL; - strscpy(qm->name, ctrl->qmenu[i], sizeof(qm->name)); - } else { - qm->value = ctrl->qmenu_int[i]; - } - return 0; -} -EXPORT_SYMBOL(v4l2_querymenu); - -static int v4l2_ctrl_request_clone(struct v4l2_ctrl_handler *hdl, - const struct v4l2_ctrl_handler *from) -{ - struct v4l2_ctrl_ref *ref; - int err = 0; - - if (WARN_ON(!hdl || hdl == from)) - return -EINVAL; - - if (hdl->error) - return hdl->error; - - WARN_ON(hdl->lock != &hdl->_lock); - - mutex_lock(from->lock); - list_for_each_entry(ref, &from->ctrl_refs, node) { - struct v4l2_ctrl *ctrl = ref->ctrl; - struct v4l2_ctrl_ref *new_ref; - - /* Skip refs inherited from other devices */ - if (ref->from_other_dev) - continue; - err = handler_new_ref(hdl, ctrl, &new_ref, false, true); - if (err) - break; - } - mutex_unlock(from->lock); - return err; -} - -static void v4l2_ctrl_request_queue(struct media_request_object *obj) -{ - struct v4l2_ctrl_handler *hdl = - container_of(obj, struct v4l2_ctrl_handler, req_obj); - struct v4l2_ctrl_handler *main_hdl = obj->priv; - - mutex_lock(main_hdl->lock); - list_add_tail(&hdl->requests_queued, &main_hdl->requests_queued); - hdl->request_is_queued = true; - mutex_unlock(main_hdl->lock); -} - -static void v4l2_ctrl_request_unbind(struct media_request_object *obj) -{ - struct v4l2_ctrl_handler *hdl = - container_of(obj, struct v4l2_ctrl_handler, req_obj); - struct v4l2_ctrl_handler *main_hdl = obj->priv; - - mutex_lock(main_hdl->lock); - list_del_init(&hdl->requests); - if (hdl->request_is_queued) { - list_del_init(&hdl->requests_queued); - hdl->request_is_queued = false; - } - mutex_unlock(main_hdl->lock); -} - -static void v4l2_ctrl_request_release(struct media_request_object *obj) -{ - struct v4l2_ctrl_handler *hdl = - container_of(obj, struct v4l2_ctrl_handler, req_obj); - - v4l2_ctrl_handler_free(hdl); - kfree(hdl); -} - -static const struct media_request_object_ops req_ops = { - .queue = v4l2_ctrl_request_queue, - .unbind = v4l2_ctrl_request_unbind, - .release = v4l2_ctrl_request_release, -}; - -struct v4l2_ctrl_handler *v4l2_ctrl_request_hdl_find(struct media_request *req, - struct v4l2_ctrl_handler *parent) -{ - struct media_request_object *obj; - - if (WARN_ON(req->state != MEDIA_REQUEST_STATE_VALIDATING && - req->state != MEDIA_REQUEST_STATE_QUEUED)) - return NULL; - - obj = media_request_object_find(req, &req_ops, parent); - if (obj) - return container_of(obj, struct v4l2_ctrl_handler, req_obj); - return NULL; -} -EXPORT_SYMBOL_GPL(v4l2_ctrl_request_hdl_find); - -struct v4l2_ctrl * -v4l2_ctrl_request_hdl_ctrl_find(struct v4l2_ctrl_handler *hdl, u32 id) -{ - struct v4l2_ctrl_ref *ref = find_ref_lock(hdl, id); - - return (ref && ref->valid_p_req) ? ref->ctrl : NULL; -} -EXPORT_SYMBOL_GPL(v4l2_ctrl_request_hdl_ctrl_find); - -static int v4l2_ctrl_request_bind(struct media_request *req, - struct v4l2_ctrl_handler *hdl, - struct v4l2_ctrl_handler *from) -{ - int ret; - - ret = v4l2_ctrl_request_clone(hdl, from); - - if (!ret) { - ret = media_request_object_bind(req, &req_ops, - from, false, &hdl->req_obj); - if (!ret) { - mutex_lock(from->lock); - list_add_tail(&hdl->requests, &from->requests); - mutex_unlock(from->lock); - } - } - return ret; -} - -/* Some general notes on the atomic requirements of VIDIOC_G/TRY/S_EXT_CTRLS: - - It is not a fully atomic operation, just best-effort only. After all, if - multiple controls have to be set through multiple i2c writes (for example) - then some initial writes may succeed while others fail. Thus leaving the - system in an inconsistent state. The question is how much effort you are - willing to spend on trying to make something atomic that really isn't. - - From the point of view of an application the main requirement is that - when you call VIDIOC_S_EXT_CTRLS and some values are invalid then an - error should be returned without actually affecting any controls. - - If all the values are correct, then it is acceptable to just give up - in case of low-level errors. - - It is important though that the application can tell when only a partial - configuration was done. The way we do that is through the error_idx field - of struct v4l2_ext_controls: if that is equal to the count field then no - controls were affected. Otherwise all controls before that index were - successful in performing their 'get' or 'set' operation, the control at - the given index failed, and you don't know what happened with the controls - after the failed one. Since if they were part of a control cluster they - could have been successfully processed (if a cluster member was encountered - at index < error_idx), they could have failed (if a cluster member was at - error_idx), or they may not have been processed yet (if the first cluster - member appeared after error_idx). - - It is all fairly theoretical, though. In practice all you can do is to - bail out. If error_idx == count, then it is an application bug. If - error_idx < count then it is only an application bug if the error code was - EBUSY. That usually means that something started streaming just when you - tried to set the controls. In all other cases it is a driver/hardware - problem and all you can do is to retry or bail out. - - Note that these rules do not apply to VIDIOC_TRY_EXT_CTRLS: since that - never modifies controls the error_idx is just set to whatever control - has an invalid value. - */ - -/* Prepare for the extended g/s/try functions. - Find the controls in the control array and do some basic checks. */ -static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl, - struct v4l2_ext_controls *cs, - struct v4l2_ctrl_helper *helpers, - struct video_device *vdev, - bool get) -{ - struct v4l2_ctrl_helper *h; - bool have_clusters = false; - u32 i; - - for (i = 0, h = helpers; i < cs->count; i++, h++) { - struct v4l2_ext_control *c = &cs->controls[i]; - struct v4l2_ctrl_ref *ref; - struct v4l2_ctrl *ctrl; - u32 id = c->id & V4L2_CTRL_ID_MASK; - - cs->error_idx = i; - - if (cs->which && - cs->which != V4L2_CTRL_WHICH_DEF_VAL && - cs->which != V4L2_CTRL_WHICH_REQUEST_VAL && - V4L2_CTRL_ID2WHICH(id) != cs->which) { - dprintk(vdev, - "invalid which 0x%x or control id 0x%x\n", - cs->which, id); - return -EINVAL; - } - - /* Old-style private controls are not allowed for - extended controls */ - if (id >= V4L2_CID_PRIVATE_BASE) { - dprintk(vdev, - "old-style private controls not allowed\n"); - return -EINVAL; - } - ref = find_ref_lock(hdl, id); - if (ref == NULL) { - dprintk(vdev, "cannot find control id 0x%x\n", id); - return -EINVAL; - } - h->ref = ref; - ctrl = ref->ctrl; - if (ctrl->flags & V4L2_CTRL_FLAG_DISABLED) { - dprintk(vdev, "control id 0x%x is disabled\n", id); - return -EINVAL; - } - - if (ctrl->cluster[0]->ncontrols > 1) - have_clusters = true; - if (ctrl->cluster[0] != ctrl) - ref = find_ref_lock(hdl, ctrl->cluster[0]->id); - if (ctrl->is_ptr && !ctrl->is_string) { - unsigned tot_size = ctrl->elems * ctrl->elem_size; - - if (c->size < tot_size) { - /* - * In the get case the application first - * queries to obtain the size of the control. - */ - if (get) { - c->size = tot_size; - return -ENOSPC; - } - dprintk(vdev, - "pointer control id 0x%x size too small, %d bytes but %d bytes needed\n", - id, c->size, tot_size); - return -EFAULT; - } - c->size = tot_size; - } - /* Store the ref to the master control of the cluster */ - h->mref = ref; - /* Initially set next to 0, meaning that there is no other - control in this helper array belonging to the same - cluster */ - h->next = 0; - } - - /* We are done if there were no controls that belong to a multi- - control cluster. */ - if (!have_clusters) - return 0; - - /* The code below figures out in O(n) time which controls in the list - belong to the same cluster. */ - - /* This has to be done with the handler lock taken. */ - mutex_lock(hdl->lock); - - /* First zero the helper field in the master control references */ - for (i = 0; i < cs->count; i++) - helpers[i].mref->helper = NULL; - for (i = 0, h = helpers; i < cs->count; i++, h++) { - struct v4l2_ctrl_ref *mref = h->mref; - - /* If the mref->helper is set, then it points to an earlier - helper that belongs to the same cluster. */ - if (mref->helper) { - /* Set the next field of mref->helper to the current - index: this means that that earlier helper now - points to the next helper in the same cluster. */ - mref->helper->next = i; - /* mref should be set only for the first helper in the - cluster, clear the others. */ - h->mref = NULL; - } - /* Point the mref helper to the current helper struct. */ - mref->helper = h; - } - mutex_unlock(hdl->lock); - return 0; -} - -/* Handles the corner case where cs->count == 0. It checks whether the - specified control class exists. If that class ID is 0, then it checks - whether there are any controls at all. */ -static int class_check(struct v4l2_ctrl_handler *hdl, u32 which) -{ - if (which == 0 || which == V4L2_CTRL_WHICH_DEF_VAL || - which == V4L2_CTRL_WHICH_REQUEST_VAL) - return 0; - return find_ref_lock(hdl, which | 1) ? 0 : -EINVAL; -} - -/* - * Get extended controls. Allocates the helpers array if needed. - * - * Note that v4l2_g_ext_ctrls_common() with 'which' set to - * V4L2_CTRL_WHICH_REQUEST_VAL is only called if the request was - * completed, and in that case valid_p_req is true for all controls. - */ -static int v4l2_g_ext_ctrls_common(struct v4l2_ctrl_handler *hdl, - struct v4l2_ext_controls *cs, - struct video_device *vdev) -{ - struct v4l2_ctrl_helper helper[4]; - struct v4l2_ctrl_helper *helpers = helper; - int ret; - int i, j; - bool is_default, is_request; - - is_default = (cs->which == V4L2_CTRL_WHICH_DEF_VAL); - is_request = (cs->which == V4L2_CTRL_WHICH_REQUEST_VAL); - - cs->error_idx = cs->count; - cs->which = V4L2_CTRL_ID2WHICH(cs->which); - - if (hdl == NULL) - return -EINVAL; - - if (cs->count == 0) - return class_check(hdl, cs->which); - - if (cs->count > ARRAY_SIZE(helper)) { - helpers = kvmalloc_array(cs->count, sizeof(helper[0]), - GFP_KERNEL); - if (helpers == NULL) - return -ENOMEM; - } - - ret = prepare_ext_ctrls(hdl, cs, helpers, vdev, true); - cs->error_idx = cs->count; - - for (i = 0; !ret && i < cs->count; i++) - if (helpers[i].ref->ctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY) - ret = -EACCES; - - for (i = 0; !ret && i < cs->count; i++) { - struct v4l2_ctrl *master; - bool is_volatile = false; - u32 idx = i; - - if (helpers[i].mref == NULL) - continue; - - master = helpers[i].mref->ctrl; - cs->error_idx = i; - - v4l2_ctrl_lock(master); - - /* - * g_volatile_ctrl will update the new control values. - * This makes no sense for V4L2_CTRL_WHICH_DEF_VAL and - * V4L2_CTRL_WHICH_REQUEST_VAL. In the case of requests - * it is v4l2_ctrl_request_complete() that copies the - * volatile controls at the time of request completion - * to the request, so you don't want to do that again. - */ - if (!is_default && !is_request && - ((master->flags & V4L2_CTRL_FLAG_VOLATILE) || - (master->has_volatiles && !is_cur_manual(master)))) { - for (j = 0; j < master->ncontrols; j++) - cur_to_new(master->cluster[j]); - ret = call_op(master, g_volatile_ctrl); - is_volatile = true; - } - - if (ret) { - v4l2_ctrl_unlock(master); - break; - } - - /* - * Copy the default value (if is_default is true), the - * request value (if is_request is true and p_req is valid), - * the new volatile value (if is_volatile is true) or the - * current value. - */ - do { - struct v4l2_ctrl_ref *ref = helpers[idx].ref; - - if (is_default) - ret = def_to_user(cs->controls + idx, ref->ctrl); - else if (is_request && ref->valid_p_req) - ret = req_to_user(cs->controls + idx, ref); - else if (is_volatile) - ret = new_to_user(cs->controls + idx, ref->ctrl); - else - ret = cur_to_user(cs->controls + idx, ref->ctrl); - idx = helpers[idx].next; - } while (!ret && idx); - - v4l2_ctrl_unlock(master); - } - - if (cs->count > ARRAY_SIZE(helper)) - kvfree(helpers); - return ret; -} - -static struct media_request_object * -v4l2_ctrls_find_req_obj(struct v4l2_ctrl_handler *hdl, - struct media_request *req, bool set) -{ - struct media_request_object *obj; - struct v4l2_ctrl_handler *new_hdl; - int ret; - - if (IS_ERR(req)) - return ERR_CAST(req); - - if (set && WARN_ON(req->state != MEDIA_REQUEST_STATE_UPDATING)) - return ERR_PTR(-EBUSY); - - obj = media_request_object_find(req, &req_ops, hdl); - if (obj) - return obj; - /* - * If there are no controls in this completed request, - * then that can only happen if: - * - * 1) no controls were present in the queued request, and - * 2) v4l2_ctrl_request_complete() could not allocate a - * control handler object to store the completed state in. - * - * So return ENOMEM to indicate that there was an out-of-memory - * error. - */ - if (!set) - return ERR_PTR(-ENOMEM); - - new_hdl = kzalloc(sizeof(*new_hdl), GFP_KERNEL); - if (!new_hdl) - return ERR_PTR(-ENOMEM); - - obj = &new_hdl->req_obj; - ret = v4l2_ctrl_handler_init(new_hdl, (hdl->nr_of_buckets - 1) * 8); - if (!ret) - ret = v4l2_ctrl_request_bind(req, new_hdl, hdl); - if (ret) { - v4l2_ctrl_handler_free(new_hdl); - kfree(new_hdl); - return ERR_PTR(ret); - } - - media_request_object_get(obj); - return obj; -} - -int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct video_device *vdev, - struct media_device *mdev, struct v4l2_ext_controls *cs) -{ - struct media_request_object *obj = NULL; - struct media_request *req = NULL; - int ret; - - if (cs->which == V4L2_CTRL_WHICH_REQUEST_VAL) { - if (!mdev || cs->request_fd < 0) - return -EINVAL; - - req = media_request_get_by_fd(mdev, cs->request_fd); - if (IS_ERR(req)) - return PTR_ERR(req); - - if (req->state != MEDIA_REQUEST_STATE_COMPLETE) { - media_request_put(req); - return -EACCES; - } - - ret = media_request_lock_for_access(req); - if (ret) { - media_request_put(req); - return ret; - } - - obj = v4l2_ctrls_find_req_obj(hdl, req, false); - if (IS_ERR(obj)) { - media_request_unlock_for_access(req); - media_request_put(req); - return PTR_ERR(obj); - } - - hdl = container_of(obj, struct v4l2_ctrl_handler, - req_obj); - } - - ret = v4l2_g_ext_ctrls_common(hdl, cs, vdev); - - if (obj) { - media_request_unlock_for_access(req); - media_request_object_put(obj); - media_request_put(req); - } - return ret; -} -EXPORT_SYMBOL(v4l2_g_ext_ctrls); - -/* Helper function to get a single control */ -static int get_ctrl(struct v4l2_ctrl *ctrl, struct v4l2_ext_control *c) -{ - struct v4l2_ctrl *master = ctrl->cluster[0]; - int ret = 0; - int i; - - /* Compound controls are not supported. The new_to_user() and - * cur_to_user() calls below would need to be modified not to access - * userspace memory when called from get_ctrl(). - */ - if (!ctrl->is_int && ctrl->type != V4L2_CTRL_TYPE_INTEGER64) - return -EINVAL; - - if (ctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY) - return -EACCES; - - v4l2_ctrl_lock(master); - /* g_volatile_ctrl will update the current control values */ - if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) { - for (i = 0; i < master->ncontrols; i++) - cur_to_new(master->cluster[i]); - ret = call_op(master, g_volatile_ctrl); - new_to_user(c, ctrl); - } else { - cur_to_user(c, ctrl); - } - v4l2_ctrl_unlock(master); - return ret; -} - -int v4l2_g_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_control *control) -{ - struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, control->id); - struct v4l2_ext_control c; - int ret; - - if (ctrl == NULL || !ctrl->is_int) - return -EINVAL; - ret = get_ctrl(ctrl, &c); - control->value = c.value; - return ret; -} -EXPORT_SYMBOL(v4l2_g_ctrl); - -s32 v4l2_ctrl_g_ctrl(struct v4l2_ctrl *ctrl) -{ - struct v4l2_ext_control c; - - /* It's a driver bug if this happens. */ - if (WARN_ON(!ctrl->is_int)) - return 0; - c.value = 0; - get_ctrl(ctrl, &c); - return c.value; -} -EXPORT_SYMBOL(v4l2_ctrl_g_ctrl); - -s64 v4l2_ctrl_g_ctrl_int64(struct v4l2_ctrl *ctrl) -{ - struct v4l2_ext_control c; - - /* It's a driver bug if this happens. */ - if (WARN_ON(ctrl->is_ptr || ctrl->type != V4L2_CTRL_TYPE_INTEGER64)) - return 0; - c.value64 = 0; - get_ctrl(ctrl, &c); - return c.value64; -} -EXPORT_SYMBOL(v4l2_ctrl_g_ctrl_int64); - - -/* Core function that calls try/s_ctrl and ensures that the new value is - copied to the current value on a set. - Must be called with ctrl->handler->lock held. */ -static int try_or_set_cluster(struct v4l2_fh *fh, struct v4l2_ctrl *master, - bool set, u32 ch_flags) -{ - bool update_flag; - int ret; - int i; - - /* Go through the cluster and either validate the new value or - (if no new value was set), copy the current value to the new - value, ensuring a consistent view for the control ops when - called. */ - for (i = 0; i < master->ncontrols; i++) { - struct v4l2_ctrl *ctrl = master->cluster[i]; - - if (ctrl == NULL) - continue; - - if (!ctrl->is_new) { - cur_to_new(ctrl); - continue; - } - /* Check again: it may have changed since the - previous check in try_or_set_ext_ctrls(). */ - if (set && (ctrl->flags & V4L2_CTRL_FLAG_GRABBED)) - return -EBUSY; - } - - ret = call_op(master, try_ctrl); - - /* Don't set if there is no change */ - if (ret || !set || !cluster_changed(master)) - return ret; - ret = call_op(master, s_ctrl); - if (ret) - return ret; - - /* If OK, then make the new values permanent. */ - update_flag = is_cur_manual(master) != is_new_manual(master); - - for (i = 0; i < master->ncontrols; i++) { - /* - * If we switch from auto to manual mode, and this cluster - * contains volatile controls, then all non-master controls - * have to be marked as changed. The 'new' value contains - * the volatile value (obtained by update_from_auto_cluster), - * which now has to become the current value. - */ - if (i && update_flag && is_new_manual(master) && - master->has_volatiles && master->cluster[i]) - master->cluster[i]->has_changed = true; - - new_to_cur(fh, master->cluster[i], ch_flags | - ((update_flag && i > 0) ? V4L2_EVENT_CTRL_CH_FLAGS : 0)); - } - return 0; -} - -/* Validate controls. */ -static int validate_ctrls(struct v4l2_ext_controls *cs, - struct v4l2_ctrl_helper *helpers, - struct video_device *vdev, - bool set) -{ - unsigned i; - int ret = 0; - - cs->error_idx = cs->count; - for (i = 0; i < cs->count; i++) { - struct v4l2_ctrl *ctrl = helpers[i].ref->ctrl; - union v4l2_ctrl_ptr p_new; - - cs->error_idx = i; - - if (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY) { - dprintk(vdev, - "control id 0x%x is read-only\n", - ctrl->id); - return -EACCES; - } - /* This test is also done in try_set_control_cluster() which - is called in atomic context, so that has the final say, - but it makes sense to do an up-front check as well. Once - an error occurs in try_set_control_cluster() some other - controls may have been set already and we want to do a - best-effort to avoid that. */ - if (set && (ctrl->flags & V4L2_CTRL_FLAG_GRABBED)) { - dprintk(vdev, - "control id 0x%x is grabbed, cannot set\n", - ctrl->id); - return -EBUSY; - } - /* - * Skip validation for now if the payload needs to be copied - * from userspace into kernelspace. We'll validate those later. - */ - if (ctrl->is_ptr) - continue; - if (ctrl->type == V4L2_CTRL_TYPE_INTEGER64) - p_new.p_s64 = &cs->controls[i].value64; - else - p_new.p_s32 = &cs->controls[i].value; - ret = validate_new(ctrl, p_new); - if (ret) - return ret; - } - return 0; -} - -/* Obtain the current volatile values of an autocluster and mark them - as new. */ -static void update_from_auto_cluster(struct v4l2_ctrl *master) -{ - int i; - - for (i = 1; i < master->ncontrols; i++) - cur_to_new(master->cluster[i]); - if (!call_op(master, g_volatile_ctrl)) - for (i = 1; i < master->ncontrols; i++) - if (master->cluster[i]) - master->cluster[i]->is_new = 1; -} - -/* Try or try-and-set controls */ -static int try_set_ext_ctrls_common(struct v4l2_fh *fh, - struct v4l2_ctrl_handler *hdl, - struct v4l2_ext_controls *cs, - struct video_device *vdev, bool set) -{ - struct v4l2_ctrl_helper helper[4]; - struct v4l2_ctrl_helper *helpers = helper; - unsigned i, j; - int ret; - - cs->error_idx = cs->count; - - /* Default value cannot be changed */ - if (cs->which == V4L2_CTRL_WHICH_DEF_VAL) { - dprintk(vdev, "%s: cannot change default value\n", - video_device_node_name(vdev)); - return -EINVAL; - } - - cs->which = V4L2_CTRL_ID2WHICH(cs->which); - - if (hdl == NULL) { - dprintk(vdev, "%s: invalid null control handler\n", - video_device_node_name(vdev)); - return -EINVAL; - } - - if (cs->count == 0) - return class_check(hdl, cs->which); - - if (cs->count > ARRAY_SIZE(helper)) { - helpers = kvmalloc_array(cs->count, sizeof(helper[0]), - GFP_KERNEL); - if (!helpers) - return -ENOMEM; - } - ret = prepare_ext_ctrls(hdl, cs, helpers, vdev, false); - if (!ret) - ret = validate_ctrls(cs, helpers, vdev, set); - if (ret && set) - cs->error_idx = cs->count; - for (i = 0; !ret && i < cs->count; i++) { - struct v4l2_ctrl *master; - u32 idx = i; - - if (helpers[i].mref == NULL) - continue; - - cs->error_idx = i; - master = helpers[i].mref->ctrl; - v4l2_ctrl_lock(master); - - /* Reset the 'is_new' flags of the cluster */ - for (j = 0; j < master->ncontrols; j++) - if (master->cluster[j]) - master->cluster[j]->is_new = 0; - - /* For volatile autoclusters that are currently in auto mode - we need to discover if it will be set to manual mode. - If so, then we have to copy the current volatile values - first since those will become the new manual values (which - may be overwritten by explicit new values from this set - of controls). */ - if (master->is_auto && master->has_volatiles && - !is_cur_manual(master)) { - /* Pick an initial non-manual value */ - s32 new_auto_val = master->manual_mode_value + 1; - u32 tmp_idx = idx; - - do { - /* Check if the auto control is part of the - list, and remember the new value. */ - if (helpers[tmp_idx].ref->ctrl == master) - new_auto_val = cs->controls[tmp_idx].value; - tmp_idx = helpers[tmp_idx].next; - } while (tmp_idx); - /* If the new value == the manual value, then copy - the current volatile values. */ - if (new_auto_val == master->manual_mode_value) - update_from_auto_cluster(master); - } - - /* Copy the new caller-supplied control values. - user_to_new() sets 'is_new' to 1. */ - do { - struct v4l2_ctrl *ctrl = helpers[idx].ref->ctrl; - - ret = user_to_new(cs->controls + idx, ctrl); - if (!ret && ctrl->is_ptr) { - ret = validate_new(ctrl, ctrl->p_new); - if (ret) - dprintk(vdev, - "failed to validate control %s (%d)\n", - v4l2_ctrl_get_name(ctrl->id), ret); - } - idx = helpers[idx].next; - } while (!ret && idx); - - if (!ret) - ret = try_or_set_cluster(fh, master, - !hdl->req_obj.req && set, 0); - if (!ret && hdl->req_obj.req && set) { - for (j = 0; j < master->ncontrols; j++) { - struct v4l2_ctrl_ref *ref = - find_ref(hdl, master->cluster[j]->id); - - new_to_req(ref); - } - } - - /* Copy the new values back to userspace. */ - if (!ret) { - idx = i; - do { - ret = new_to_user(cs->controls + idx, - helpers[idx].ref->ctrl); - idx = helpers[idx].next; - } while (!ret && idx); - } - v4l2_ctrl_unlock(master); - } - - if (cs->count > ARRAY_SIZE(helper)) - kvfree(helpers); - return ret; -} - -static int try_set_ext_ctrls(struct v4l2_fh *fh, - struct v4l2_ctrl_handler *hdl, - struct video_device *vdev, - struct media_device *mdev, - struct v4l2_ext_controls *cs, bool set) -{ - struct media_request_object *obj = NULL; - struct media_request *req = NULL; - int ret; - - if (cs->which == V4L2_CTRL_WHICH_REQUEST_VAL) { - if (!mdev) { - dprintk(vdev, "%s: missing media device\n", - video_device_node_name(vdev)); - return -EINVAL; - } - - if (cs->request_fd < 0) { - dprintk(vdev, "%s: invalid request fd %d\n", - video_device_node_name(vdev), cs->request_fd); - return -EINVAL; - } - - req = media_request_get_by_fd(mdev, cs->request_fd); - if (IS_ERR(req)) { - dprintk(vdev, "%s: cannot find request fd %d\n", - video_device_node_name(vdev), cs->request_fd); - return PTR_ERR(req); - } - - ret = media_request_lock_for_update(req); - if (ret) { - dprintk(vdev, "%s: cannot lock request fd %d\n", - video_device_node_name(vdev), cs->request_fd); - media_request_put(req); - return ret; - } - - obj = v4l2_ctrls_find_req_obj(hdl, req, set); - if (IS_ERR(obj)) { - dprintk(vdev, - "%s: cannot find request object for request fd %d\n", - video_device_node_name(vdev), - cs->request_fd); - media_request_unlock_for_update(req); - media_request_put(req); - return PTR_ERR(obj); - } - hdl = container_of(obj, struct v4l2_ctrl_handler, - req_obj); - } - - ret = try_set_ext_ctrls_common(fh, hdl, cs, vdev, set); - if (ret) - dprintk(vdev, - "%s: try_set_ext_ctrls_common failed (%d)\n", - video_device_node_name(vdev), ret); - - if (obj) { - media_request_unlock_for_update(req); - media_request_object_put(obj); - media_request_put(req); - } - - return ret; -} - -int v4l2_try_ext_ctrls(struct v4l2_ctrl_handler *hdl, - struct video_device *vdev, - struct media_device *mdev, - struct v4l2_ext_controls *cs) -{ - return try_set_ext_ctrls(NULL, hdl, vdev, mdev, cs, false); -} -EXPORT_SYMBOL(v4l2_try_ext_ctrls); - -int v4l2_s_ext_ctrls(struct v4l2_fh *fh, - struct v4l2_ctrl_handler *hdl, - struct video_device *vdev, - struct media_device *mdev, - struct v4l2_ext_controls *cs) -{ - return try_set_ext_ctrls(fh, hdl, vdev, mdev, cs, true); -} -EXPORT_SYMBOL(v4l2_s_ext_ctrls); - -/* Helper function for VIDIOC_S_CTRL compatibility */ -static int set_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 ch_flags) -{ - struct v4l2_ctrl *master = ctrl->cluster[0]; - int ret; - int i; - - /* Reset the 'is_new' flags of the cluster */ - for (i = 0; i < master->ncontrols; i++) - if (master->cluster[i]) - master->cluster[i]->is_new = 0; - - ret = validate_new(ctrl, ctrl->p_new); - if (ret) - return ret; - - /* For autoclusters with volatiles that are switched from auto to - manual mode we have to update the current volatile values since - those will become the initial manual values after such a switch. */ - if (master->is_auto && master->has_volatiles && ctrl == master && - !is_cur_manual(master) && ctrl->val == master->manual_mode_value) - update_from_auto_cluster(master); - - ctrl->is_new = 1; - return try_or_set_cluster(fh, master, true, ch_flags); -} - -/* Helper function for VIDIOC_S_CTRL compatibility */ -static int set_ctrl_lock(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, - struct v4l2_ext_control *c) -{ - int ret; - - v4l2_ctrl_lock(ctrl); - user_to_new(c, ctrl); - ret = set_ctrl(fh, ctrl, 0); - if (!ret) - cur_to_user(c, ctrl); - v4l2_ctrl_unlock(ctrl); - return ret; -} - -int v4l2_s_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl, - struct v4l2_control *control) -{ - struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, control->id); - struct v4l2_ext_control c = { control->id }; - int ret; - - if (ctrl == NULL || !ctrl->is_int) - return -EINVAL; - - if (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY) - return -EACCES; - - c.value = control->value; - ret = set_ctrl_lock(fh, ctrl, &c); - control->value = c.value; - return ret; -} -EXPORT_SYMBOL(v4l2_s_ctrl); - -int __v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val) -{ - lockdep_assert_held(ctrl->handler->lock); - - /* It's a driver bug if this happens. */ - if (WARN_ON(!ctrl->is_int)) - return -EINVAL; - ctrl->val = val; - return set_ctrl(NULL, ctrl, 0); -} -EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl); - -int __v4l2_ctrl_s_ctrl_int64(struct v4l2_ctrl *ctrl, s64 val) -{ - lockdep_assert_held(ctrl->handler->lock); - - /* It's a driver bug if this happens. */ - if (WARN_ON(ctrl->is_ptr || ctrl->type != V4L2_CTRL_TYPE_INTEGER64)) - return -EINVAL; - *ctrl->p_new.p_s64 = val; - return set_ctrl(NULL, ctrl, 0); -} -EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_int64); - -int __v4l2_ctrl_s_ctrl_string(struct v4l2_ctrl *ctrl, const char *s) -{ - lockdep_assert_held(ctrl->handler->lock); - - /* It's a driver bug if this happens. */ - if (WARN_ON(ctrl->type != V4L2_CTRL_TYPE_STRING)) - return -EINVAL; - strscpy(ctrl->p_new.p_char, s, ctrl->maximum + 1); - return set_ctrl(NULL, ctrl, 0); -} -EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_string); - -int __v4l2_ctrl_s_ctrl_compound(struct v4l2_ctrl *ctrl, - enum v4l2_ctrl_type type, const void *p) -{ - lockdep_assert_held(ctrl->handler->lock); - - /* It's a driver bug if this happens. */ - if (WARN_ON(ctrl->type != type)) - return -EINVAL; - memcpy(ctrl->p_new.p, p, ctrl->elems * ctrl->elem_size); - return set_ctrl(NULL, ctrl, 0); -} -EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_compound); - -void v4l2_ctrl_request_complete(struct media_request *req, - struct v4l2_ctrl_handler *main_hdl) -{ - struct media_request_object *obj; - struct v4l2_ctrl_handler *hdl; - struct v4l2_ctrl_ref *ref; - - if (!req || !main_hdl) - return; - - /* - * Note that it is valid if nothing was found. It means - * that this request doesn't have any controls and so just - * wants to leave the controls unchanged. - */ - obj = media_request_object_find(req, &req_ops, main_hdl); - if (!obj) { - int ret; - - /* Create a new request so the driver can return controls */ - hdl = kzalloc(sizeof(*hdl), GFP_KERNEL); - if (!hdl) - return; - - ret = v4l2_ctrl_handler_init(hdl, (main_hdl->nr_of_buckets - 1) * 8); - if (!ret) - ret = v4l2_ctrl_request_bind(req, hdl, main_hdl); - if (ret) { - v4l2_ctrl_handler_free(hdl); - kfree(hdl); - return; - } - hdl->request_is_queued = true; - obj = media_request_object_find(req, &req_ops, main_hdl); - } - hdl = container_of(obj, struct v4l2_ctrl_handler, req_obj); - - list_for_each_entry(ref, &hdl->ctrl_refs, node) { - struct v4l2_ctrl *ctrl = ref->ctrl; - struct v4l2_ctrl *master = ctrl->cluster[0]; - unsigned int i; - - if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) { - v4l2_ctrl_lock(master); - /* g_volatile_ctrl will update the current control values */ - for (i = 0; i < master->ncontrols; i++) - cur_to_new(master->cluster[i]); - call_op(master, g_volatile_ctrl); - new_to_req(ref); - v4l2_ctrl_unlock(master); - continue; - } - if (ref->valid_p_req) - continue; - - /* Copy the current control value into the request */ - v4l2_ctrl_lock(ctrl); - cur_to_req(ref); - v4l2_ctrl_unlock(ctrl); - } - - mutex_lock(main_hdl->lock); - WARN_ON(!hdl->request_is_queued); - list_del_init(&hdl->requests_queued); - hdl->request_is_queued = false; - mutex_unlock(main_hdl->lock); - media_request_object_complete(obj); - media_request_object_put(obj); -} -EXPORT_SYMBOL(v4l2_ctrl_request_complete); - -int v4l2_ctrl_request_setup(struct media_request *req, - struct v4l2_ctrl_handler *main_hdl) -{ - struct media_request_object *obj; - struct v4l2_ctrl_handler *hdl; - struct v4l2_ctrl_ref *ref; - int ret = 0; - - if (!req || !main_hdl) - return 0; - - if (WARN_ON(req->state != MEDIA_REQUEST_STATE_QUEUED)) - return -EBUSY; - - /* - * Note that it is valid if nothing was found. It means - * that this request doesn't have any controls and so just - * wants to leave the controls unchanged. - */ - obj = media_request_object_find(req, &req_ops, main_hdl); - if (!obj) - return 0; - if (obj->completed) { - media_request_object_put(obj); - return -EBUSY; - } - hdl = container_of(obj, struct v4l2_ctrl_handler, req_obj); - - list_for_each_entry(ref, &hdl->ctrl_refs, node) - ref->req_done = false; - - list_for_each_entry(ref, &hdl->ctrl_refs, node) { - struct v4l2_ctrl *ctrl = ref->ctrl; - struct v4l2_ctrl *master = ctrl->cluster[0]; - bool have_new_data = false; - int i; - - /* - * Skip if this control was already handled by a cluster. - * Skip button controls and read-only controls. - */ - if (ref->req_done || (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY)) - continue; - - v4l2_ctrl_lock(master); - for (i = 0; i < master->ncontrols; i++) { - if (master->cluster[i]) { - struct v4l2_ctrl_ref *r = - find_ref(hdl, master->cluster[i]->id); - - if (r->valid_p_req) { - have_new_data = true; - break; - } - } - } - if (!have_new_data) { - v4l2_ctrl_unlock(master); - continue; - } - - for (i = 0; i < master->ncontrols; i++) { - if (master->cluster[i]) { - struct v4l2_ctrl_ref *r = - find_ref(hdl, master->cluster[i]->id); - - req_to_new(r); - master->cluster[i]->is_new = 1; - r->req_done = true; - } - } - /* - * For volatile autoclusters that are currently in auto mode - * we need to discover if it will be set to manual mode. - * If so, then we have to copy the current volatile values - * first since those will become the new manual values (which - * may be overwritten by explicit new values from this set - * of controls). - */ - if (master->is_auto && master->has_volatiles && - !is_cur_manual(master)) { - s32 new_auto_val = *master->p_new.p_s32; - - /* - * If the new value == the manual value, then copy - * the current volatile values. - */ - if (new_auto_val == master->manual_mode_value) - update_from_auto_cluster(master); - } - - ret = try_or_set_cluster(NULL, master, true, 0); - v4l2_ctrl_unlock(master); - - if (ret) - break; - } - - media_request_object_put(obj); - return ret; -} -EXPORT_SYMBOL(v4l2_ctrl_request_setup); - -void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl, v4l2_ctrl_notify_fnc notify, void *priv) -{ - if (ctrl == NULL) - return; - if (notify == NULL) { - ctrl->call_notify = 0; - return; - } - if (WARN_ON(ctrl->handler->notify && ctrl->handler->notify != notify)) - return; - ctrl->handler->notify = notify; - ctrl->handler->notify_priv = priv; - ctrl->call_notify = 1; -} -EXPORT_SYMBOL(v4l2_ctrl_notify); - -int __v4l2_ctrl_modify_range(struct v4l2_ctrl *ctrl, - s64 min, s64 max, u64 step, s64 def) -{ - bool value_changed; - bool range_changed = false; - int ret; - - lockdep_assert_held(ctrl->handler->lock); - - switch (ctrl->type) { - case V4L2_CTRL_TYPE_INTEGER: - case V4L2_CTRL_TYPE_INTEGER64: - case V4L2_CTRL_TYPE_BOOLEAN: - case V4L2_CTRL_TYPE_MENU: - case V4L2_CTRL_TYPE_INTEGER_MENU: - case V4L2_CTRL_TYPE_BITMASK: - case V4L2_CTRL_TYPE_U8: - case V4L2_CTRL_TYPE_U16: - case V4L2_CTRL_TYPE_U32: - if (ctrl->is_array) - return -EINVAL; - ret = check_range(ctrl->type, min, max, step, def); - if (ret) - return ret; - break; - default: - return -EINVAL; - } - if ((ctrl->minimum != min) || (ctrl->maximum != max) || - (ctrl->step != step) || ctrl->default_value != def) { - range_changed = true; - ctrl->minimum = min; - ctrl->maximum = max; - ctrl->step = step; - ctrl->default_value = def; - } - cur_to_new(ctrl); - if (validate_new(ctrl, ctrl->p_new)) { - if (ctrl->type == V4L2_CTRL_TYPE_INTEGER64) - *ctrl->p_new.p_s64 = def; - else - *ctrl->p_new.p_s32 = def; - } - - if (ctrl->type == V4L2_CTRL_TYPE_INTEGER64) - value_changed = *ctrl->p_new.p_s64 != *ctrl->p_cur.p_s64; - else - value_changed = *ctrl->p_new.p_s32 != *ctrl->p_cur.p_s32; - if (value_changed) - ret = set_ctrl(NULL, ctrl, V4L2_EVENT_CTRL_CH_RANGE); - else if (range_changed) - send_event(NULL, ctrl, V4L2_EVENT_CTRL_CH_RANGE); - return ret; -} -EXPORT_SYMBOL(__v4l2_ctrl_modify_range); - -static int v4l2_ctrl_add_event(struct v4l2_subscribed_event *sev, unsigned elems) -{ - struct v4l2_ctrl *ctrl = v4l2_ctrl_find(sev->fh->ctrl_handler, sev->id); - - if (ctrl == NULL) - return -EINVAL; - - v4l2_ctrl_lock(ctrl); - list_add_tail(&sev->node, &ctrl->ev_subs); - if (ctrl->type != V4L2_CTRL_TYPE_CTRL_CLASS && - (sev->flags & V4L2_EVENT_SUB_FL_SEND_INITIAL)) { - struct v4l2_event ev; - u32 changes = V4L2_EVENT_CTRL_CH_FLAGS; - - if (!(ctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY)) - changes |= V4L2_EVENT_CTRL_CH_VALUE; - fill_event(&ev, ctrl, changes); - /* Mark the queue as active, allowing this initial - event to be accepted. */ - sev->elems = elems; - v4l2_event_queue_fh(sev->fh, &ev); - } - v4l2_ctrl_unlock(ctrl); - return 0; -} - -static void v4l2_ctrl_del_event(struct v4l2_subscribed_event *sev) -{ - struct v4l2_ctrl *ctrl = v4l2_ctrl_find(sev->fh->ctrl_handler, sev->id); - - if (ctrl == NULL) - return; - - v4l2_ctrl_lock(ctrl); - list_del(&sev->node); - v4l2_ctrl_unlock(ctrl); -} - -void v4l2_ctrl_replace(struct v4l2_event *old, const struct v4l2_event *new) -{ - u32 old_changes = old->u.ctrl.changes; - - old->u.ctrl = new->u.ctrl; - old->u.ctrl.changes |= old_changes; -} -EXPORT_SYMBOL(v4l2_ctrl_replace); - -void v4l2_ctrl_merge(const struct v4l2_event *old, struct v4l2_event *new) -{ - new->u.ctrl.changes |= old->u.ctrl.changes; -} -EXPORT_SYMBOL(v4l2_ctrl_merge); - -const struct v4l2_subscribed_event_ops v4l2_ctrl_sub_ev_ops = { - .add = v4l2_ctrl_add_event, - .del = v4l2_ctrl_del_event, - .replace = v4l2_ctrl_replace, - .merge = v4l2_ctrl_merge, -}; -EXPORT_SYMBOL(v4l2_ctrl_sub_ev_ops); - -int v4l2_ctrl_log_status(struct file *file, void *fh) -{ - struct video_device *vfd = video_devdata(file); - struct v4l2_fh *vfh = file->private_data; - - if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) && vfd->v4l2_dev) - v4l2_ctrl_handler_log_status(vfh->ctrl_handler, - vfd->v4l2_dev->name); - return 0; -} -EXPORT_SYMBOL(v4l2_ctrl_log_status); - -int v4l2_ctrl_subscribe_event(struct v4l2_fh *fh, - const struct v4l2_event_subscription *sub) -{ - if (sub->type == V4L2_EVENT_CTRL) - return v4l2_event_subscribe(fh, sub, 0, &v4l2_ctrl_sub_ev_ops); - return -EINVAL; -} -EXPORT_SYMBOL(v4l2_ctrl_subscribe_event); - -int v4l2_ctrl_subdev_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, - struct v4l2_event_subscription *sub) -{ - if (!sd->ctrl_handler) - return -EINVAL; - return v4l2_ctrl_subscribe_event(fh, sub); -} -EXPORT_SYMBOL(v4l2_ctrl_subdev_subscribe_event); - -__poll_t v4l2_ctrl_poll(struct file *file, struct poll_table_struct *wait) -{ - struct v4l2_fh *fh = file->private_data; - - poll_wait(file, &fh->wait, wait); - if (v4l2_event_pending(fh)) - return EPOLLPRI; - return 0; -} -EXPORT_SYMBOL(v4l2_ctrl_poll); - -int v4l2_ctrl_new_fwnode_properties(struct v4l2_ctrl_handler *hdl, - const struct v4l2_ctrl_ops *ctrl_ops, - const struct v4l2_fwnode_device_properties *p) -{ - if (p->orientation != V4L2_FWNODE_PROPERTY_UNSET) { - u32 orientation_ctrl; - - switch (p->orientation) { - case V4L2_FWNODE_ORIENTATION_FRONT: - orientation_ctrl = V4L2_CAMERA_ORIENTATION_FRONT; - break; - case V4L2_FWNODE_ORIENTATION_BACK: - orientation_ctrl = V4L2_CAMERA_ORIENTATION_BACK; - break; - case V4L2_FWNODE_ORIENTATION_EXTERNAL: - orientation_ctrl = V4L2_CAMERA_ORIENTATION_EXTERNAL; - break; - default: - return -EINVAL; - } - if (!v4l2_ctrl_new_std_menu(hdl, ctrl_ops, - V4L2_CID_CAMERA_ORIENTATION, - V4L2_CAMERA_ORIENTATION_EXTERNAL, 0, - orientation_ctrl)) - return hdl->error; - } - - if (p->rotation != V4L2_FWNODE_PROPERTY_UNSET) { - if (!v4l2_ctrl_new_std(hdl, ctrl_ops, - V4L2_CID_CAMERA_SENSOR_ROTATION, - p->rotation, p->rotation, 1, - p->rotation)) - return hdl->error; - } - - return hdl->error; -} -EXPORT_SYMBOL(v4l2_ctrl_new_fwnode_properties); From de646852cdadf7da2267e06297f7f6fe22dfb899 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 31 May 2021 17:05:45 +0200 Subject: [PATCH 184/394] media: move ttpci-eeprom to common The ttpci-eeprom is actually an independent driver that doesn't depend on the stuff under drivers/media/pci/ttpci/. Also, it is used by an USB driver (pctv452e). So, move it to the common directory. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/Kconfig | 4 ++++ drivers/media/common/Makefile | 1 + drivers/media/{pci/ttpci => common}/ttpci-eeprom.c | 0 drivers/media/{pci/ttpci => common}/ttpci-eeprom.h | 0 drivers/media/pci/ttpci/Makefile | 2 +- drivers/media/usb/Kconfig | 5 ----- drivers/media/usb/dvb-usb/Makefile | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) rename drivers/media/{pci/ttpci => common}/ttpci-eeprom.c (100%) rename drivers/media/{pci/ttpci => common}/ttpci-eeprom.h (100%) diff --git a/drivers/media/common/Kconfig b/drivers/media/common/Kconfig index 4ea03b7899a8..0f6bde0f793e 100644 --- a/drivers/media/common/Kconfig +++ b/drivers/media/common/Kconfig @@ -13,6 +13,10 @@ config VIDEO_TVEEPROM tristate depends on I2C +config TTPCI_EEPROM + tristate + depends on I2C + config CYPRESS_FIRMWARE tristate depends on USB diff --git a/drivers/media/common/Makefile b/drivers/media/common/Makefile index b71e4b62eea5..55b5a1900124 100644 --- a/drivers/media/common/Makefile +++ b/drivers/media/common/Makefile @@ -3,3 +3,4 @@ obj-y += b2c2/ saa7146/ siano/ v4l2-tpg/ videobuf2/ obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o obj-$(CONFIG_CYPRESS_FIRMWARE) += cypress_firmware.o +obj-$(CONFIG_TTPCI_EEPROM) += ttpci-eeprom.o diff --git a/drivers/media/pci/ttpci/ttpci-eeprom.c b/drivers/media/common/ttpci-eeprom.c similarity index 100% rename from drivers/media/pci/ttpci/ttpci-eeprom.c rename to drivers/media/common/ttpci-eeprom.c diff --git a/drivers/media/pci/ttpci/ttpci-eeprom.h b/drivers/media/common/ttpci-eeprom.h similarity index 100% rename from drivers/media/pci/ttpci/ttpci-eeprom.h rename to drivers/media/common/ttpci-eeprom.h diff --git a/drivers/media/pci/ttpci/Makefile b/drivers/media/pci/ttpci/Makefile index 9b44c479fcdd..61001fa5a93e 100644 --- a/drivers/media/pci/ttpci/Makefile +++ b/drivers/media/pci/ttpci/Makefile @@ -10,7 +10,6 @@ ifdef CONFIG_DVB_AV7110_IR dvb-ttpci-objs += av7110_ir.o endif -obj-$(CONFIG_TTPCI_EEPROM) += ttpci-eeprom.o obj-$(CONFIG_DVB_BUDGET_CORE) += budget-core.o obj-$(CONFIG_DVB_BUDGET) += budget.o obj-$(CONFIG_DVB_BUDGET_AV) += budget-av.o @@ -20,3 +19,4 @@ obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o ccflags-y += -I $(srctree)/drivers/media/dvb-frontends/ ccflags-y += -I $(srctree)/drivers/media/tuners +ccflags-y += -I $(srctree)/drivers/media/common diff --git a/drivers/media/usb/Kconfig b/drivers/media/usb/Kconfig index 00feadb217d8..f97153df3c84 100644 --- a/drivers/media/usb/Kconfig +++ b/drivers/media/usb/Kconfig @@ -1,10 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only -# This Kconfig option is also used by the legacy av7110 driver -config TTPCI_EEPROM - tristate - depends on I2C - if USB && MEDIA_SUPPORT menuconfig MEDIA_USB_SUPPORT diff --git a/drivers/media/usb/dvb-usb/Makefile b/drivers/media/usb/dvb-usb/Makefile index 28e4806a87cd..c22514948db2 100644 --- a/drivers/media/usb/dvb-usb/Makefile +++ b/drivers/media/usb/dvb-usb/Makefile @@ -83,4 +83,4 @@ obj-$(CONFIG_DVB_USB_TECHNISAT_USB2) += dvb-usb-technisat-usb2.o ccflags-y += -I$(srctree)/drivers/media/dvb-frontends/ # due to tuner-xc3028 ccflags-y += -I$(srctree)/drivers/media/tuners -ccflags-y += -I$(srctree)/drivers/media/pci/ttpci +ccflags-y += -I$(srctree)/drivers/media/common From 989cf18ed08f8b6efd1d1592d1d0108fa09b98f5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 31 May 2021 17:27:09 +0200 Subject: [PATCH 185/394] media: av7110: move driver to staging This driver is really old, from devices that aren't manufactured anymore for more than a decade. Also, the decoder supports only MPEG2, with is not compatible with several modern DVB streams. It is also the only upstream driver relying on the DVB "full-featured" API. Some changes at the frontend drivers seem to have broken it without anybody noticing. Due to that, it sounds it is time to retire the driver for good. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ttpci/Kconfig | 74 ------------------- drivers/media/pci/ttpci/Makefile | 9 --- drivers/media/pci/ttpci/budget.h | 2 +- drivers/staging/media/Kconfig | 2 + drivers/staging/media/Makefile | 1 + drivers/staging/media/av7110/Kconfig | 74 +++++++++++++++++++ drivers/staging/media/av7110/Makefile | 20 +++++ drivers/staging/media/av7110/TODO | 3 + .../ttpci => staging/media/av7110}/av7110.c | 0 .../ttpci => staging/media/av7110}/av7110.h | 0 .../media/av7110}/av7110_av.c | 0 .../media/av7110}/av7110_av.h | 0 .../media/av7110}/av7110_ca.c | 0 .../media/av7110}/av7110_ca.h | 0 .../media/av7110}/av7110_hw.c | 0 .../media/av7110}/av7110_hw.h | 0 .../media/av7110}/av7110_ipack.c | 0 .../media/av7110}/av7110_ipack.h | 0 .../media/av7110}/av7110_ir.c | 0 .../media/av7110}/av7110_v4l.c | 0 .../media/av7110}/budget-patch.c | 0 .../media/av7110}/dvb_filter.c | 0 .../media/av7110}/dvb_filter.h | 0 23 files changed, 101 insertions(+), 84 deletions(-) create mode 100644 drivers/staging/media/av7110/Kconfig create mode 100644 drivers/staging/media/av7110/Makefile create mode 100644 drivers/staging/media/av7110/TODO rename drivers/{media/pci/ttpci => staging/media/av7110}/av7110.c (100%) rename drivers/{media/pci/ttpci => staging/media/av7110}/av7110.h (100%) rename drivers/{media/pci/ttpci => staging/media/av7110}/av7110_av.c (100%) rename drivers/{media/pci/ttpci => staging/media/av7110}/av7110_av.h (100%) rename drivers/{media/pci/ttpci => staging/media/av7110}/av7110_ca.c (100%) rename drivers/{media/pci/ttpci => staging/media/av7110}/av7110_ca.h (100%) rename drivers/{media/pci/ttpci => staging/media/av7110}/av7110_hw.c (100%) rename drivers/{media/pci/ttpci => staging/media/av7110}/av7110_hw.h (100%) rename drivers/{media/pci/ttpci => staging/media/av7110}/av7110_ipack.c (100%) rename drivers/{media/pci/ttpci => staging/media/av7110}/av7110_ipack.h (100%) rename drivers/{media/pci/ttpci => staging/media/av7110}/av7110_ir.c (100%) rename drivers/{media/pci/ttpci => staging/media/av7110}/av7110_v4l.c (100%) rename drivers/{media/pci/ttpci => staging/media/av7110}/budget-patch.c (100%) rename drivers/{media/pci/ttpci => staging/media/av7110}/dvb_filter.c (100%) rename drivers/{media/pci/ttpci => staging/media/av7110}/dvb_filter.h (100%) diff --git a/drivers/media/pci/ttpci/Kconfig b/drivers/media/pci/ttpci/Kconfig index 8a362ee9105f..65a6832a6b96 100644 --- a/drivers/media/pci/ttpci/Kconfig +++ b/drivers/media/pci/ttpci/Kconfig @@ -1,56 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only -config DVB_AV7110_IR - bool - depends on RC_CORE=y || RC_CORE = DVB_AV7110 - default DVB_AV7110 - -config DVB_AV7110 - tristate "AV7110 cards" - depends on DVB_CORE && PCI && I2C - select TTPCI_EEPROM - select VIDEO_SAA7146_VV - depends on VIDEO_DEV # dependencies of VIDEO_SAA7146_VV - select DVB_VES1820 if MEDIA_SUBDRV_AUTOSELECT - select DVB_VES1X93 if MEDIA_SUBDRV_AUTOSELECT - select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT - select DVB_TDA8083 if MEDIA_SUBDRV_AUTOSELECT - select DVB_SP8870 if MEDIA_SUBDRV_AUTOSELECT - select DVB_STV0297 if MEDIA_SUBDRV_AUTOSELECT - select DVB_L64781 if MEDIA_SUBDRV_AUTOSELECT - select DVB_LNBP21 if MEDIA_SUBDRV_AUTOSELECT - help - Support for SAA7146 and AV7110 based DVB cards as produced - by Fujitsu-Siemens, Technotrend, Hauppauge and others. - - This driver only supports the fullfeatured cards with - onboard MPEG2 decoder. - - This driver needs an external firmware. Please use the script - "/scripts/get_dvb_firmware av7110" to - download/extract it, and then copy it to /usr/lib/hotplug/firmware - or /lib/firmware (depending on configuration of firmware hotplug). - - Alternatively, you can download the file and use the kernel's - EXTRA_FIRMWARE configuration option to build it into your - kernel image by adding the filename to the EXTRA_FIRMWARE - configuration option string. - - Say Y if you own such a card and want to use it. - -config DVB_AV7110_OSD - bool "AV7110 OSD support" - depends on DVB_AV7110 - default y if DVB_AV7110=y || DVB_AV7110=m - help - The AV7110 firmware provides some code to generate an OnScreenDisplay - on the video output. This is kind of nonstandard and not guaranteed to - be maintained. - - Anyway, some popular DVB software like VDR uses this OSD to render - its menus, so say Y if you want to use this software. - - All other people say N. - config DVB_BUDGET_CORE tristate "SAA7146 DVB cards (aka Budget, Nova-PCI)" depends on DVB_CORE && PCI && I2C @@ -136,25 +84,3 @@ config DVB_BUDGET_AV To compile this driver as a module, choose M here: the module will be called budget-av. - -config DVB_BUDGET_PATCH - tristate "AV7110 cards with Budget Patch" - depends on DVB_BUDGET_CORE && I2C - depends on DVB_AV7110 - select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT - select DVB_VES1X93 if MEDIA_SUBDRV_AUTOSELECT - select DVB_TDA8083 if MEDIA_SUBDRV_AUTOSELECT - help - Support for Budget Patch (full TS) modification on - SAA7146+AV7110 based cards (DVB-S cards). This - driver doesn't use onboard MPEG2 decoder. The - card is driven in Budget-only mode. Card is - required to have loaded firmware to tune properly. - Firmware can be loaded by insertion and removal of - standard AV7110 driver prior to loading this - driver. - - Say Y if you own such a card and want to use it. - - To compile this driver as a module, choose M here: the - module will be called budget-patch. diff --git a/drivers/media/pci/ttpci/Makefile b/drivers/media/pci/ttpci/Makefile index 61001fa5a93e..b0708f6e40cc 100644 --- a/drivers/media/pci/ttpci/Makefile +++ b/drivers/media/pci/ttpci/Makefile @@ -1,21 +1,12 @@ # SPDX-License-Identifier: GPL-2.0 # # Makefile for the kernel SAA7146 FULL TS DVB device driver -# and the AV7110 DVB device driver # -dvb-ttpci-objs := av7110_hw.o av7110_v4l.o av7110_av.o av7110_ca.o av7110.o av7110_ipack.o dvb_filter.o - -ifdef CONFIG_DVB_AV7110_IR -dvb-ttpci-objs += av7110_ir.o -endif - obj-$(CONFIG_DVB_BUDGET_CORE) += budget-core.o obj-$(CONFIG_DVB_BUDGET) += budget.o obj-$(CONFIG_DVB_BUDGET_AV) += budget-av.o obj-$(CONFIG_DVB_BUDGET_CI) += budget-ci.o -obj-$(CONFIG_DVB_BUDGET_PATCH) += budget-patch.o -obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o ccflags-y += -I $(srctree)/drivers/media/dvb-frontends/ ccflags-y += -I $(srctree)/drivers/media/tuners diff --git a/drivers/media/pci/ttpci/budget.h b/drivers/media/pci/ttpci/budget.h index a7463daf39f1..bd87432e6cde 100644 --- a/drivers/media/pci/ttpci/budget.h +++ b/drivers/media/pci/ttpci/budget.h @@ -8,7 +8,6 @@ #include #include #include -#include "dvb_filter.h" #include #include @@ -28,6 +27,7 @@ extern int budget_debug; __func__, ##arg); \ } while (0) +#define TS_SIZE 188 struct budget_info { char *name; diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig index ca59986b20f8..e3aaae920847 100644 --- a/drivers/staging/media/Kconfig +++ b/drivers/staging/media/Kconfig @@ -42,4 +42,6 @@ source "drivers/staging/media/tegra-video/Kconfig" source "drivers/staging/media/ipu3/Kconfig" +source "drivers/staging/media/av7110/Kconfig" + endif diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile index 716929a1a313..5b5afc5b03a0 100644 --- a/drivers/staging/media/Makefile +++ b/drivers/staging/media/Makefile @@ -10,3 +10,4 @@ obj-$(CONFIG_TEGRA_VDE) += tegra-vde/ obj-$(CONFIG_VIDEO_HANTRO) += hantro/ obj-$(CONFIG_VIDEO_IPU3_IMGU) += ipu3/ obj-$(CONFIG_VIDEO_ZORAN) += zoran/ +obj-$(CONFIG_DVB_AV7110) += av7110/ diff --git a/drivers/staging/media/av7110/Kconfig b/drivers/staging/media/av7110/Kconfig new file mode 100644 index 000000000000..e19d24bf2eb4 --- /dev/null +++ b/drivers/staging/media/av7110/Kconfig @@ -0,0 +1,74 @@ +# SPDX-License-Identifier: GPL-2.0-only +config DVB_AV7110_IR + bool + depends on RC_CORE=y || RC_CORE = DVB_AV7110 + default DVB_AV7110 + +config DVB_AV7110 + tristate "AV7110 cards" + depends on DVB_CORE && PCI && I2C + select TTPCI_EEPROM + select VIDEO_SAA7146_VV + depends on VIDEO_DEV # dependencies of VIDEO_SAA7146_VV + select DVB_VES1820 if MEDIA_SUBDRV_AUTOSELECT + select DVB_VES1X93 if MEDIA_SUBDRV_AUTOSELECT + select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT + select DVB_TDA8083 if MEDIA_SUBDRV_AUTOSELECT + select DVB_SP8870 if MEDIA_SUBDRV_AUTOSELECT + select DVB_STV0297 if MEDIA_SUBDRV_AUTOSELECT + select DVB_L64781 if MEDIA_SUBDRV_AUTOSELECT + select DVB_LNBP21 if MEDIA_SUBDRV_AUTOSELECT + help + Support for SAA7146 and AV7110 based DVB cards as produced + by Fujitsu-Siemens, Technotrend, Hauppauge and others. + + This driver only supports the fullfeatured cards with + onboard MPEG2 decoder. + + This driver needs an external firmware. Please use the script + "/scripts/get_dvb_firmware av7110" to + download/extract it, and then copy it to /usr/lib/hotplug/firmware + or /lib/firmware (depending on configuration of firmware hotplug). + + Alternatively, you can download the file and use the kernel's + EXTRA_FIRMWARE configuration option to build it into your + kernel image by adding the filename to the EXTRA_FIRMWARE + configuration option string. + + Say Y if you own such a card and want to use it. + +config DVB_AV7110_OSD + bool "AV7110 OSD support" + depends on DVB_AV7110 + default y if DVB_AV7110=y || DVB_AV7110=m + help + The AV7110 firmware provides some code to generate an OnScreenDisplay + on the video output. This is kind of nonstandard and not guaranteed to + be maintained. + + Anyway, some popular DVB software like VDR uses this OSD to render + its menus, so say Y if you want to use this software. + + All other people say N. + +config DVB_BUDGET_PATCH + tristate "AV7110 cards with Budget Patch" + depends on DVB_BUDGET_CORE && I2C + depends on DVB_AV7110 + select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT + select DVB_VES1X93 if MEDIA_SUBDRV_AUTOSELECT + select DVB_TDA8083 if MEDIA_SUBDRV_AUTOSELECT + help + Support for Budget Patch (full TS) modification on + SAA7146+AV7110 based cards (DVB-S cards). This + driver doesn't use onboard MPEG2 decoder. The + card is driven in Budget-only mode. Card is + required to have loaded firmware to tune properly. + Firmware can be loaded by insertion and removal of + standard AV7110 driver prior to loading this + driver. + + Say Y if you own such a card and want to use it. + + To compile this driver as a module, choose M here: the + module will be called budget-patch. diff --git a/drivers/staging/media/av7110/Makefile b/drivers/staging/media/av7110/Makefile new file mode 100644 index 000000000000..dcabecf1abde --- /dev/null +++ b/drivers/staging/media/av7110/Makefile @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Makefile for the AV7110 DVB device driver +# + +dvb-ttpci-objs := av7110_hw.o av7110_v4l.o av7110_av.o av7110_ca.o av7110.o \ + av7110_ipack.o dvb_filter.o + +ifdef CONFIG_DVB_AV7110_IR +dvb-ttpci-objs += av7110_ir.o +endif + +obj-$(CONFIG_DVB_BUDGET_PATCH) += budget-patch.o + +obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o + +ccflags-y += -I $(srctree)/drivers/media/dvb-frontends +ccflags-y += -I $(srctree)/drivers/media/tuners +ccflags-y += -I $(srctree)/drivers/media/pci/ttpci +ccflags-y += -I $(srctree)/drivers/media/common diff --git a/drivers/staging/media/av7110/TODO b/drivers/staging/media/av7110/TODO new file mode 100644 index 000000000000..60062d8441b3 --- /dev/null +++ b/drivers/staging/media/av7110/TODO @@ -0,0 +1,3 @@ +- This driver is too old and relies on a different API. + Drop it from Kernel on a couple of versions. +- Cleanup patches for the drivers here won't be accepted. diff --git a/drivers/media/pci/ttpci/av7110.c b/drivers/staging/media/av7110/av7110.c similarity index 100% rename from drivers/media/pci/ttpci/av7110.c rename to drivers/staging/media/av7110/av7110.c diff --git a/drivers/media/pci/ttpci/av7110.h b/drivers/staging/media/av7110/av7110.h similarity index 100% rename from drivers/media/pci/ttpci/av7110.h rename to drivers/staging/media/av7110/av7110.h diff --git a/drivers/media/pci/ttpci/av7110_av.c b/drivers/staging/media/av7110/av7110_av.c similarity index 100% rename from drivers/media/pci/ttpci/av7110_av.c rename to drivers/staging/media/av7110/av7110_av.c diff --git a/drivers/media/pci/ttpci/av7110_av.h b/drivers/staging/media/av7110/av7110_av.h similarity index 100% rename from drivers/media/pci/ttpci/av7110_av.h rename to drivers/staging/media/av7110/av7110_av.h diff --git a/drivers/media/pci/ttpci/av7110_ca.c b/drivers/staging/media/av7110/av7110_ca.c similarity index 100% rename from drivers/media/pci/ttpci/av7110_ca.c rename to drivers/staging/media/av7110/av7110_ca.c diff --git a/drivers/media/pci/ttpci/av7110_ca.h b/drivers/staging/media/av7110/av7110_ca.h similarity index 100% rename from drivers/media/pci/ttpci/av7110_ca.h rename to drivers/staging/media/av7110/av7110_ca.h diff --git a/drivers/media/pci/ttpci/av7110_hw.c b/drivers/staging/media/av7110/av7110_hw.c similarity index 100% rename from drivers/media/pci/ttpci/av7110_hw.c rename to drivers/staging/media/av7110/av7110_hw.c diff --git a/drivers/media/pci/ttpci/av7110_hw.h b/drivers/staging/media/av7110/av7110_hw.h similarity index 100% rename from drivers/media/pci/ttpci/av7110_hw.h rename to drivers/staging/media/av7110/av7110_hw.h diff --git a/drivers/media/pci/ttpci/av7110_ipack.c b/drivers/staging/media/av7110/av7110_ipack.c similarity index 100% rename from drivers/media/pci/ttpci/av7110_ipack.c rename to drivers/staging/media/av7110/av7110_ipack.c diff --git a/drivers/media/pci/ttpci/av7110_ipack.h b/drivers/staging/media/av7110/av7110_ipack.h similarity index 100% rename from drivers/media/pci/ttpci/av7110_ipack.h rename to drivers/staging/media/av7110/av7110_ipack.h diff --git a/drivers/media/pci/ttpci/av7110_ir.c b/drivers/staging/media/av7110/av7110_ir.c similarity index 100% rename from drivers/media/pci/ttpci/av7110_ir.c rename to drivers/staging/media/av7110/av7110_ir.c diff --git a/drivers/media/pci/ttpci/av7110_v4l.c b/drivers/staging/media/av7110/av7110_v4l.c similarity index 100% rename from drivers/media/pci/ttpci/av7110_v4l.c rename to drivers/staging/media/av7110/av7110_v4l.c diff --git a/drivers/media/pci/ttpci/budget-patch.c b/drivers/staging/media/av7110/budget-patch.c similarity index 100% rename from drivers/media/pci/ttpci/budget-patch.c rename to drivers/staging/media/av7110/budget-patch.c diff --git a/drivers/media/pci/ttpci/dvb_filter.c b/drivers/staging/media/av7110/dvb_filter.c similarity index 100% rename from drivers/media/pci/ttpci/dvb_filter.c rename to drivers/staging/media/av7110/dvb_filter.c diff --git a/drivers/media/pci/ttpci/dvb_filter.h b/drivers/staging/media/av7110/dvb_filter.h similarity index 100% rename from drivers/media/pci/ttpci/dvb_filter.h rename to drivers/staging/media/av7110/dvb_filter.h From b998a59f82f1152605eae4f7617778020549e81a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 31 May 2021 22:34:24 +0200 Subject: [PATCH 186/394] media: sp8870: move it to staging This driver is used only by av7110, which is preparing for its retirement. So, move this ancillary driver to stay together with av7110. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/Kconfig | 12 ----------- drivers/media/dvb-frontends/Makefile | 1 - drivers/staging/media/av7110/Kconfig | 20 +++++++++++++++++++ drivers/staging/media/av7110/Makefile | 2 ++ .../media/av7110}/sp8870.c | 0 .../media/av7110}/sp8870.h | 0 6 files changed, 22 insertions(+), 13 deletions(-) rename drivers/{media/dvb-frontends => staging/media/av7110}/sp8870.c (100%) rename drivers/{media/dvb-frontends => staging/media/av7110}/sp8870.h (100%) diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig index 3468b07b62fe..2c1ed98d43c5 100644 --- a/drivers/media/dvb-frontends/Kconfig +++ b/drivers/media/dvb-frontends/Kconfig @@ -323,18 +323,6 @@ config DVB_TDA10071 comment "DVB-T (terrestrial) frontends" depends on DVB_CORE -config DVB_SP8870 - tristate "Spase sp8870 based" - depends on DVB_CORE && I2C - default m if !MEDIA_SUBDRV_AUTOSELECT - help - A DVB-T tuner module. Say Y when you want to support this frontend. - - This driver needs external firmware. Please use the command - "/scripts/get_dvb_firmware sp8870" to - download/extract it, and then copy it to /usr/lib/hotplug/firmware - or /lib/firmware (depending on configuration of firmware hotplug). - config DVB_SP887X tristate "Spase sp887x based" depends on DVB_CORE && I2C diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile index b9f47d68e14e..d32e4c0be576 100644 --- a/drivers/media/dvb-frontends/Makefile +++ b/drivers/media/dvb-frontends/Makefile @@ -20,7 +20,6 @@ obj-$(CONFIG_DVB_PLL) += dvb-pll.o obj-$(CONFIG_DVB_STV0299) += stv0299.o obj-$(CONFIG_DVB_STB0899) += stb0899.o obj-$(CONFIG_DVB_STB6100) += stb6100.o -obj-$(CONFIG_DVB_SP8870) += sp8870.o obj-$(CONFIG_DVB_CX22700) += cx22700.o obj-$(CONFIG_DVB_S5H1432) += s5h1432.o obj-$(CONFIG_DVB_CX24110) += cx24110.o diff --git a/drivers/staging/media/av7110/Kconfig b/drivers/staging/media/av7110/Kconfig index e19d24bf2eb4..9faf9d2d4001 100644 --- a/drivers/staging/media/av7110/Kconfig +++ b/drivers/staging/media/av7110/Kconfig @@ -72,3 +72,23 @@ config DVB_BUDGET_PATCH To compile this driver as a module, choose M here: the module will be called budget-patch. + +if DVB_AV7110 + +# Frontend driver that it is used only by AV7110 driver +# While technically independent, it doesn't make sense to keep +# it if we drop support for AV7110, as no other driver will use it. + +config DVB_SP8870 + tristate "Spase sp8870 based" + depends on DVB_CORE && I2C + default m if !MEDIA_SUBDRV_AUTOSELECT + help + A DVB-T tuner module. Say Y when you want to support this frontend. + + This driver needs external firmware. Please use the command + "/scripts/get_dvb_firmware sp8870" to + download/extract it, and then copy it to /usr/lib/hotplug/firmware + or /lib/firmware (depending on configuration of firmware hotplug). + +endif diff --git a/drivers/staging/media/av7110/Makefile b/drivers/staging/media/av7110/Makefile index dcabecf1abde..307b267598ea 100644 --- a/drivers/staging/media/av7110/Makefile +++ b/drivers/staging/media/av7110/Makefile @@ -14,6 +14,8 @@ obj-$(CONFIG_DVB_BUDGET_PATCH) += budget-patch.o obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o +obj-$(CONFIG_DVB_SP8870) += sp8870.o + ccflags-y += -I $(srctree)/drivers/media/dvb-frontends ccflags-y += -I $(srctree)/drivers/media/tuners ccflags-y += -I $(srctree)/drivers/media/pci/ttpci diff --git a/drivers/media/dvb-frontends/sp8870.c b/drivers/staging/media/av7110/sp8870.c similarity index 100% rename from drivers/media/dvb-frontends/sp8870.c rename to drivers/staging/media/av7110/sp8870.c diff --git a/drivers/media/dvb-frontends/sp8870.h b/drivers/staging/media/av7110/sp8870.h similarity index 100% rename from drivers/media/dvb-frontends/sp8870.h rename to drivers/staging/media/av7110/sp8870.h From 1cb13613735a15b994b680ae5ef18aaf79108b95 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 2 Jun 2021 10:42:28 +0200 Subject: [PATCH 187/394] media: mc-request.c: allow object_bind in QUEUED state If a request was queued without a control handler object, and a control handler object is then created and bound to the request when copying controls on request completion, then a WARN_ON in mc-request.c is triggered since at that time the request is in state QUEUED, and not UPDATING. But this is too strict, and in this case it must also allow binding objects when in state QUEUED. This patch was unfortunately lost when the "always copy the controls on completion" patch was posted, it should have been part of that commit. Signed-off-by: Hans Verkuil Fixes: c3bf5129f339 ("media: v4l2-ctrls: always copy the controls on completion") Signed-off-by: Mauro Carvalho Chehab --- drivers/media/mc/mc-request.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/mc/mc-request.c b/drivers/media/mc/mc-request.c index c0782fd96c59..addb8f2d8939 100644 --- a/drivers/media/mc/mc-request.c +++ b/drivers/media/mc/mc-request.c @@ -414,7 +414,8 @@ int media_request_object_bind(struct media_request *req, spin_lock_irqsave(&req->lock, flags); - if (WARN_ON(req->state != MEDIA_REQUEST_STATE_UPDATING)) + if (WARN_ON(req->state != MEDIA_REQUEST_STATE_UPDATING && + req->state != MEDIA_REQUEST_STATE_QUEUED)) goto unlock; obj->req = req; From ff3cc65cadb5d7333fde557b38cbb60b3a6cf496 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Fri, 5 Mar 2021 18:38:39 +0100 Subject: [PATCH 188/394] media: v4l: async, fwnode: Improve module organisation The V4L2 async framework is generally used with the V4L2 fwnode, which also depends on the former. There are a few exceptions but they are relatively few. At the same time there is a vast number of systems that need videodev module, but have no use for v4l2-async that's now part of videodev. In order to improve, split the v4l2-async into its own module. Selecting V4L2_FWNODE also selects V4L2_ASYNC. This also moves the initialisation of the debufs entries for async subdevs to loading of the v4l2-async module. The directory is named as "v4l2-async". Signed-off-by: Sakari Ailus Reviewed-by: Ezequiel Garcia Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/Kconfig | 11 +++++++++++ drivers/media/v4l2-core/Kconfig | 5 +++++ drivers/media/v4l2-core/Makefile | 5 +++-- drivers/media/v4l2-core/v4l2-async.c | 23 +++++++++++++++++++++-- drivers/media/v4l2-core/v4l2-dev.c | 5 ----- 5 files changed, 40 insertions(+), 9 deletions(-) diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 462c0e059754..4f1dafc64816 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -217,6 +217,7 @@ config VIDEO_ADV7180 depends on GPIOLIB && VIDEO_V4L2 && I2C select MEDIA_CONTROLLER select VIDEO_V4L2_SUBDEV_API + select V4L2_ASYNC help Support for the Analog Devices ADV7180 video decoder. @@ -534,6 +535,7 @@ config VIDEO_ADV7175 config VIDEO_ADV7343 tristate "ADV7343 video encoder" depends on I2C + select V4L2_ASYNC help Support for Analog Devices I2C bus based ADV7343 encoder. @@ -652,6 +654,7 @@ config SDR_MAX2175 tristate "Maxim 2175 RF to Bits tuner" depends on VIDEO_V4L2 && MEDIA_SDR_SUPPORT && I2C select REGMAP_I2C + select V4L2_ASYNC help Support for Maxim 2175 tuner. It is an advanced analog/digital radio receiver with RF-to-Bits front-end designed for SDR solutions. @@ -668,6 +671,7 @@ menu "Miscellaneous helper chips" config VIDEO_THS7303 tristate "THS7303/53 Video Amplifier" depends on VIDEO_V4L2 && I2C + select V4L2_ASYNC help Support for TI THS7303/53 video amplifier @@ -1341,6 +1345,7 @@ config VIDEO_AD5820 tristate "AD5820 lens voice coil support" depends on GPIOLIB && I2C && VIDEO_V4L2 select MEDIA_CONTROLLER + select V4L2_ASYNC help This is a driver for the AD5820 camera lens voice coil. It is used for example in Nokia N900 (RX-51). @@ -1350,6 +1355,7 @@ config VIDEO_AK7375 depends on I2C && VIDEO_V4L2 select MEDIA_CONTROLLER select VIDEO_V4L2_SUBDEV_API + select V4L2_ASYNC help This is a driver for the AK7375 camera lens voice coil. AK7375 is a 12 bit DAC with 120mA output current sink @@ -1361,6 +1367,7 @@ config VIDEO_DW9714 depends on I2C && VIDEO_V4L2 select MEDIA_CONTROLLER select VIDEO_V4L2_SUBDEV_API + select V4L2_ASYNC help This is a driver for the DW9714 camera lens voice coil. DW9714 is a 10 bit DAC with 120mA output current sink @@ -1384,6 +1391,7 @@ config VIDEO_DW9807_VCM depends on I2C && VIDEO_V4L2 select MEDIA_CONTROLLER select VIDEO_V4L2_SUBDEV_API + select V4L2_ASYNC help This is a driver for the DW9807 camera lens voice coil. DW9807 is a 10 bit DAC with 100mA output current sink @@ -1399,6 +1407,7 @@ config VIDEO_ADP1653 tristate "ADP1653 flash support" depends on I2C && VIDEO_V4L2 select MEDIA_CONTROLLER + select V4L2_ASYNC help This is a driver for the ADP1653 flash controller. It is used for example in Nokia N900. @@ -1408,6 +1417,7 @@ config VIDEO_LM3560 depends on I2C && VIDEO_V4L2 select MEDIA_CONTROLLER select REGMAP_I2C + select V4L2_ASYNC help This is a driver for the lm3560 dual flash controllers. It controls flash, torch LEDs. @@ -1417,6 +1427,7 @@ config VIDEO_LM3646 depends on I2C && VIDEO_V4L2 select MEDIA_CONTROLLER select REGMAP_I2C + select V4L2_ASYNC help This is a driver for the lm3646 dual flash controllers. It controls flash, torch LEDs. diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig index bf49f83cb86f..02dc1787e953 100644 --- a/drivers/media/v4l2-core/Kconfig +++ b/drivers/media/v4l2-core/Kconfig @@ -62,6 +62,7 @@ config V4L2_FLASH_LED_CLASS tristate "V4L2 flash API for LED flash class devices" depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API depends on LEDS_CLASS_FLASH + select V4L2_ASYNC help Say Y here to enable V4L2 flash API support for LED flash class drivers. @@ -70,6 +71,10 @@ config V4L2_FLASH_LED_CLASS config V4L2_FWNODE tristate + select V4L2_ASYNC + +config V4L2_ASYNC + tristate # Used by drivers that need Videobuf modules config VIDEOBUF_GEN diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile index ad967b72fb5d..66a78c556c98 100644 --- a/drivers/media/v4l2-core/Makefile +++ b/drivers/media/v4l2-core/Makefile @@ -6,7 +6,7 @@ tuner-objs := tuner-core.o videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \ - v4l2-event.o v4l2-subdev.o v4l2-async.o v4l2-common.o \ + v4l2-event.o v4l2-subdev.o v4l2-common.o \ v4l2-ctrls-core.o v4l2-ctrls-api.o \ v4l2-ctrls-request.o v4l2-ctrls-defs.o videodev-$(CONFIG_COMPAT) += v4l2-compat-ioctl32.o @@ -15,8 +15,9 @@ videodev-$(CONFIG_MEDIA_CONTROLLER) += v4l2-mc.o videodev-$(CONFIG_SPI) += v4l2-spi.o videodev-$(CONFIG_VIDEO_V4L2_I2C) += v4l2-i2c.o -obj-$(CONFIG_V4L2_FWNODE) += v4l2-fwnode.o obj-$(CONFIG_VIDEO_V4L2) += videodev.o +obj-$(CONFIG_V4L2_FWNODE) += v4l2-fwnode.o +obj-$(CONFIG_V4L2_ASYNC) += v4l2-async.o obj-$(CONFIG_VIDEO_V4L2) += v4l2-dv-timings.o obj-$(CONFIG_VIDEO_TUNER) += tuner.o diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c index e638aa8aecb7..cd9e78c63791 100644 --- a/drivers/media/v4l2-core/v4l2-async.c +++ b/drivers/media/v4l2-core/v4l2-async.c @@ -854,8 +854,27 @@ static int pending_subdevs_show(struct seq_file *s, void *data) } DEFINE_SHOW_ATTRIBUTE(pending_subdevs); -void v4l2_async_debug_init(struct dentry *debugfs_dir) +static struct dentry *v4l2_async_debugfs_dir; + +static int __init v4l2_async_init(void) { - debugfs_create_file("pending_async_subdevices", 0444, debugfs_dir, NULL, + v4l2_async_debugfs_dir = debugfs_create_dir("v4l2-async", NULL); + debugfs_create_file("pending_async_subdevices", 0444, + v4l2_async_debugfs_dir, NULL, &pending_subdevs_fops); + + return 0; } + +static void __exit v4l2_async_exit(void) +{ + debugfs_remove_recursive(v4l2_async_debugfs_dir); +} + +subsys_initcall(v4l2_async_init); +module_exit(v4l2_async_exit); + +MODULE_AUTHOR("Guennadi Liakhovetski "); +MODULE_AUTHOR("Sakari Ailus "); +MODULE_AUTHOR("Ezequiel Garcia "); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index 7d0edf3530be..4aa8fcd674d7 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -39,8 +39,6 @@ __func__, ##arg); \ } while (0) -static struct dentry *v4l2_debugfs_dir; - /* * sysfs stuff */ @@ -1121,8 +1119,6 @@ static int __init videodev_init(void) return -EIO; } - v4l2_debugfs_dir = debugfs_create_dir("video4linux", NULL); - v4l2_async_debug_init(v4l2_debugfs_dir); return 0; } @@ -1130,7 +1126,6 @@ static void __exit videodev_exit(void) { dev_t dev = MKDEV(VIDEO_MAJOR, 0); - debugfs_remove_recursive(v4l2_debugfs_dir); class_unregister(&video_class); unregister_chrdev_region(dev, VIDEO_NUM_DEVICES); } From dc794d3d24246588d4db88c9d2c2ad67273027fd Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 12 Apr 2021 13:04:33 +0200 Subject: [PATCH 189/394] media: staging: ipu3-imgu: Move the UAPI header from include under include/uapi The header defines the user space interface but may be mistaken as kernel-only header due to its location. Add "uapi" directory under driver's include directory and move the header there. Suggested-by: Greg KH Signed-off-by: Sakari Ailus Reviewed-by: Bingbu Cao Signed-off-by: Mauro Carvalho Chehab --- Documentation/admin-guide/media/ipu3.rst | 35 ++++++++++--------- .../media/v4l/pixfmt-meta-intel-ipu3.rst | 2 +- .../ipu3/include/{ => uapi}/intel-ipu3.h | 0 drivers/staging/media/ipu3/ipu3-abi.h | 2 +- 4 files changed, 20 insertions(+), 19 deletions(-) rename drivers/staging/media/ipu3/include/{ => uapi}/intel-ipu3.h (100%) diff --git a/Documentation/admin-guide/media/ipu3.rst b/Documentation/admin-guide/media/ipu3.rst index f59697c7b374..d6454f637ff4 100644 --- a/Documentation/admin-guide/media/ipu3.rst +++ b/Documentation/admin-guide/media/ipu3.rst @@ -234,22 +234,23 @@ The IPU3 ImgU pipelines can be configured using the Media Controller, defined at Running mode and firmware binary selection ------------------------------------------ -ImgU works based on firmware, currently the ImgU firmware support run 2 pipes in -time-sharing with single input frame data. Each pipe can run at certain mode - -"VIDEO" or "STILL", "VIDEO" mode is commonly used for video frames capture, and -"STILL" is used for still frame capture. However, you can also select "VIDEO" to -capture still frames if you want to capture images with less system load and -power. For "STILL" mode, ImgU will try to use smaller BDS factor and output -larger bayer frame for further YUV processing than "VIDEO" mode to get high -quality images. Besides, "STILL" mode need XNR3 to do noise reduction, hence -"STILL" mode will need more power and memory bandwidth than "VIDEO" mode. TNR -will be enabled in "VIDEO" mode and bypassed by "STILL" mode. ImgU is running at -“VIDEO” mode by default, the user can use v4l2 control V4L2_CID_INTEL_IPU3_MODE -(currently defined in drivers/staging/media/ipu3/include/intel-ipu3.h) to query -and set the running mode. For user, there is no difference for buffer queueing -between the "VIDEO" and "STILL" mode, mandatory input and main output node -should be enabled and buffers need be queued, the statistics and the view-finder -queues are optional. +ImgU works based on firmware, currently the ImgU firmware support run 2 pipes +in time-sharing with single input frame data. Each pipe can run at certain mode +- "VIDEO" or "STILL", "VIDEO" mode is commonly used for video frames capture, +and "STILL" is used for still frame capture. However, you can also select +"VIDEO" to capture still frames if you want to capture images with less system +load and power. For "STILL" mode, ImgU will try to use smaller BDS factor and +output larger bayer frame for further YUV processing than "VIDEO" mode to get +high quality images. Besides, "STILL" mode need XNR3 to do noise reduction, +hence "STILL" mode will need more power and memory bandwidth than "VIDEO" mode. +TNR will be enabled in "VIDEO" mode and bypassed by "STILL" mode. ImgU is +running at “VIDEO” mode by default, the user can use v4l2 control +V4L2_CID_INTEL_IPU3_MODE (currently defined in +drivers/staging/media/ipu3/include/uapi/intel-ipu3.h) to query and set the +running mode. For user, there is no difference for buffer queueing between the +"VIDEO" and "STILL" mode, mandatory input and main output node should be +enabled and buffers need be queued, the statistics and the view-finder queues +are optional. The firmware binary will be selected according to current running mode, such log "using binary if_to_osys_striped " or "using binary if_to_osys_primary_striped" @@ -586,7 +587,7 @@ preserved. References ========== -.. [#f5] drivers/staging/media/ipu3/include/intel-ipu3.h +.. [#f5] drivers/staging/media/ipu3/include/uapi/intel-ipu3.h .. [#f1] https://github.com/intel/nvt diff --git a/Documentation/userspace-api/media/v4l/pixfmt-meta-intel-ipu3.rst b/Documentation/userspace-api/media/v4l/pixfmt-meta-intel-ipu3.rst index 5f33d35532ef..84d81dd7a7b5 100644 --- a/Documentation/userspace-api/media/v4l/pixfmt-meta-intel-ipu3.rst +++ b/Documentation/userspace-api/media/v4l/pixfmt-meta-intel-ipu3.rst @@ -78,4 +78,4 @@ hardware and algorithm details. Intel IPU3 ImgU uAPI data types =============================== -.. kernel-doc:: drivers/staging/media/ipu3/include/intel-ipu3.h +.. kernel-doc:: drivers/staging/media/ipu3/include/uapi/intel-ipu3.h diff --git a/drivers/staging/media/ipu3/include/intel-ipu3.h b/drivers/staging/media/ipu3/include/uapi/intel-ipu3.h similarity index 100% rename from drivers/staging/media/ipu3/include/intel-ipu3.h rename to drivers/staging/media/ipu3/include/uapi/intel-ipu3.h diff --git a/drivers/staging/media/ipu3/ipu3-abi.h b/drivers/staging/media/ipu3/ipu3-abi.h index e1185602c7fd..c76935b436d7 100644 --- a/drivers/staging/media/ipu3/ipu3-abi.h +++ b/drivers/staging/media/ipu3/ipu3-abi.h @@ -4,7 +4,7 @@ #ifndef __IPU3_ABI_H #define __IPU3_ABI_H -#include "include/intel-ipu3.h" +#include "include/uapi/intel-ipu3.h" /******************* IMGU Hardware information *******************/ From caad79405086151dec128f78274a999f15d947ed Mon Sep 17 00:00:00 2001 From: Bernhard Wimmer Date: Wed, 21 Apr 2021 23:33:19 +0200 Subject: [PATCH 190/394] media: Documentation: ccs: Fix the op_pll_multiplier address According to the CCS spec the op_pll_multiplier address is 0x030e, not 0x031e. Signed-off-by: Bernhard Wimmer Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- Documentation/driver-api/media/drivers/ccs/ccs-regs.asc | 2 +- Documentation/driver-api/media/drivers/ccs/mk-ccs-regs | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Documentation/driver-api/media/drivers/ccs/ccs-regs.asc b/Documentation/driver-api/media/drivers/ccs/ccs-regs.asc index f2042acc8a45..bbf9213c3388 100644 --- a/Documentation/driver-api/media/drivers/ccs/ccs-regs.asc +++ b/Documentation/driver-api/media/drivers/ccs/ccs-regs.asc @@ -210,7 +210,7 @@ pll_multiplier 0x0306 16 op_pix_clk_div 0x0308 16 op_sys_clk_div 0x030a 16 op_pre_pll_clk_div 0x030c 16 -op_pll_multiplier 0x031e 16 +op_pll_multiplier 0x030e 16 pll_mode 0x0310 8 - f 0 0 - e single 0 diff --git a/Documentation/driver-api/media/drivers/ccs/mk-ccs-regs b/Documentation/driver-api/media/drivers/ccs/mk-ccs-regs index 6668deaf2f19..2a4edc7e051a 100755 --- a/Documentation/driver-api/media/drivers/ccs/mk-ccs-regs +++ b/Documentation/driver-api/media/drivers/ccs/mk-ccs-regs @@ -72,13 +72,14 @@ $uc_header =~ s/[^A-Z0-9]/_/g; my $copyright = "/* Copyright (C) 2019--2020 Intel Corporation */\n"; my $license = "SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause"; +my $note = "/*\n * Generated by $0;\n * do not modify.\n */\n"; for my $fh ($A, $LC) { - print $fh "// $license\n$copyright\n" if defined $fh; + print $fh "// $license\n$copyright$note\n" if defined $fh; } for my $fh ($H, $LH) { - print $fh "/* $license */\n$copyright\n"; + print $fh "/* $license */\n$copyright$note\n"; } sub bit_def($) { From 0e3e0c9369c822b7f1dd11504eeb98cfd4aabf24 Mon Sep 17 00:00:00 2001 From: Bernhard Wimmer Date: Wed, 21 Apr 2021 23:33:20 +0200 Subject: [PATCH 191/394] media: ccs: Fix the op_pll_multiplier address According to the CCS spec the op_pll_multiplier address is 0x030e, not 0x031e. Signed-off-by: Bernhard Wimmer Signed-off-by: Sakari Ailus Cc: stable@vger.kernel.org Fixes: 6493c4b777c2 ("media: smiapp: Import CCS definitions") Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ccs/ccs-limits.c | 4 ++++ drivers/media/i2c/ccs/ccs-limits.h | 4 ++++ drivers/media/i2c/ccs/ccs-regs.h | 6 +++++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/media/i2c/ccs/ccs-limits.c b/drivers/media/i2c/ccs/ccs-limits.c index f5511789ac83..4969fa425317 100644 --- a/drivers/media/i2c/ccs/ccs-limits.c +++ b/drivers/media/i2c/ccs/ccs-limits.c @@ -1,5 +1,9 @@ // SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause /* Copyright (C) 2019--2020 Intel Corporation */ +/* + * Generated by Documentation/driver-api/media/drivers/ccs/mk-ccs-regs; + * do not modify. + */ #include "ccs-limits.h" #include "ccs-regs.h" diff --git a/drivers/media/i2c/ccs/ccs-limits.h b/drivers/media/i2c/ccs/ccs-limits.h index 1efa43c23a2e..551d3ee9d04e 100644 --- a/drivers/media/i2c/ccs/ccs-limits.h +++ b/drivers/media/i2c/ccs/ccs-limits.h @@ -1,5 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause */ /* Copyright (C) 2019--2020 Intel Corporation */ +/* + * Generated by Documentation/driver-api/media/drivers/ccs/mk-ccs-regs; + * do not modify. + */ #ifndef __CCS_LIMITS_H__ #define __CCS_LIMITS_H__ diff --git a/drivers/media/i2c/ccs/ccs-regs.h b/drivers/media/i2c/ccs/ccs-regs.h index 4b3e5df2121f..6ce84c5ecf20 100644 --- a/drivers/media/i2c/ccs/ccs-regs.h +++ b/drivers/media/i2c/ccs/ccs-regs.h @@ -1,5 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause */ /* Copyright (C) 2019--2020 Intel Corporation */ +/* + * Generated by Documentation/driver-api/media/drivers/ccs/mk-ccs-regs; + * do not modify. + */ #ifndef __CCS_REGS_H__ #define __CCS_REGS_H__ @@ -202,7 +206,7 @@ #define CCS_R_OP_PIX_CLK_DIV (0x0308 | CCS_FL_16BIT) #define CCS_R_OP_SYS_CLK_DIV (0x030a | CCS_FL_16BIT) #define CCS_R_OP_PRE_PLL_CLK_DIV (0x030c | CCS_FL_16BIT) -#define CCS_R_OP_PLL_MULTIPLIER (0x031e | CCS_FL_16BIT) +#define CCS_R_OP_PLL_MULTIPLIER (0x030e | CCS_FL_16BIT) #define CCS_R_PLL_MODE 0x0310 #define CCS_PLL_MODE_SHIFT 0U #define CCS_PLL_MODE_MASK 0x1 From 2cb2705cf7ffe41dc5bd81290e4241bfb7f031cc Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Sun, 4 Apr 2021 20:14:09 +0200 Subject: [PATCH 192/394] media: ipu3-cio2: Fix reference counting when looping over ACPI devices When we continue, due to device is disabled, loop we have to drop reference count. When we have an array full of devices we have to also drop the reference count. Note, in this case the cio2_bridge_unregister_sensors() is called by the caller. Fixes: 803abec64ef9 ("media: ipu3-cio2: Add cio2-bridge to ipu3-cio2 driver") Signed-off-by: Andy Shevchenko Reviewed-by: Daniel Scally Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/intel/ipu3/cio2-bridge.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.c b/drivers/media/pci/intel/ipu3/cio2-bridge.c index e8511787c1e4..4657e99df033 100644 --- a/drivers/media/pci/intel/ipu3/cio2-bridge.c +++ b/drivers/media/pci/intel/ipu3/cio2-bridge.c @@ -173,14 +173,15 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg, int ret; for_each_acpi_dev_match(adev, cfg->hid, NULL, -1) { - if (!adev->status.enabled) + if (!adev->status.enabled) { + acpi_dev_put(adev); continue; + } if (bridge->n_sensors >= CIO2_NUM_PORTS) { + acpi_dev_put(adev); dev_err(&cio2->dev, "Exceeded available CIO2 ports\n"); - cio2_bridge_unregister_sensors(bridge); - ret = -EINVAL; - goto err_out; + return -EINVAL; } sensor = &bridge->sensors[bridge->n_sensors]; @@ -228,7 +229,6 @@ err_free_swnodes: software_node_unregister_nodes(sensor->swnodes); err_put_adev: acpi_dev_put(sensor->adev); -err_out: return ret; } From 24786ccd9c80fdb05494aa4d90fcb8f34295c193 Mon Sep 17 00:00:00 2001 From: Dillon Min Date: Tue, 4 May 2021 07:09:53 +0200 Subject: [PATCH 193/394] media: i2c: ov2659: Use clk_{prepare_enable,disable_unprepare}() to set xvclk on/off On some platform(imx6q), xvclk might not switch on in advance, also for power save purpose, xvclk should not be always on. so, add clk_prepare_enable(), clk_disable_unprepare() in driver side to set xvclk on/off at proper stage. Add following changes: - add 'struct clk *clk;' in 'struct ov2659 {}' - enable xvclk in ov2659_power_on() - disable xvclk in ov2659_power_off() Signed-off-by: Dillon Min Acked-by: Lad Prabhakar Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov2659.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c index a3c8eae68486..7c1781f646ce 100644 --- a/drivers/media/i2c/ov2659.c +++ b/drivers/media/i2c/ov2659.c @@ -204,6 +204,7 @@ struct ov2659 { struct i2c_client *client; struct v4l2_ctrl_handler ctrls; struct v4l2_ctrl *link_frequency; + struct clk *clk; const struct ov2659_framesize *frame_size; struct sensor_register *format_ctrl_regs; struct ov2659_pll_ctrl pll; @@ -1268,6 +1269,8 @@ static int ov2659_power_off(struct device *dev) gpiod_set_value(ov2659->pwdn_gpio, 1); + clk_disable_unprepare(ov2659->clk); + return 0; } @@ -1276,9 +1279,17 @@ static int ov2659_power_on(struct device *dev) struct i2c_client *client = to_i2c_client(dev); struct v4l2_subdev *sd = i2c_get_clientdata(client); struct ov2659 *ov2659 = to_ov2659(sd); + int ret; dev_dbg(&client->dev, "%s:\n", __func__); + ret = clk_prepare_enable(ov2659->clk); + if (ret) { + dev_err(&client->dev, "%s: failed to enable clock\n", + __func__); + return ret; + } + gpiod_set_value(ov2659->pwdn_gpio, 0); if (ov2659->resetb_gpio) { @@ -1423,7 +1434,6 @@ static int ov2659_probe(struct i2c_client *client) const struct ov2659_platform_data *pdata = ov2659_get_pdata(client); struct v4l2_subdev *sd; struct ov2659 *ov2659; - struct clk *clk; int ret; if (!pdata) { @@ -1438,11 +1448,11 @@ static int ov2659_probe(struct i2c_client *client) ov2659->pdata = pdata; ov2659->client = client; - clk = devm_clk_get(&client->dev, "xvclk"); - if (IS_ERR(clk)) - return PTR_ERR(clk); + ov2659->clk = devm_clk_get(&client->dev, "xvclk"); + if (IS_ERR(ov2659->clk)) + return PTR_ERR(ov2659->clk); - ov2659->xvclk_frequency = clk_get_rate(clk); + ov2659->xvclk_frequency = clk_get_rate(ov2659->clk); if (ov2659->xvclk_frequency < 6000000 || ov2659->xvclk_frequency > 27000000) return -EINVAL; @@ -1504,7 +1514,9 @@ static int ov2659_probe(struct i2c_client *client) ov2659->frame_size = &ov2659_framesizes[2]; ov2659->format_ctrl_regs = ov2659_formats[0].format_ctrl_regs; - ov2659_power_on(&client->dev); + ret = ov2659_power_on(&client->dev); + if (ret < 0) + goto error; ret = ov2659_detect(sd); if (ret < 0) From c492ec9ae9ede77dd794b14913b0382376da2bff Mon Sep 17 00:00:00 2001 From: Shawn Tu Date: Fri, 16 Apr 2021 11:58:58 +0200 Subject: [PATCH 194/394] media: ov8856: Add support for 2 data lanes The OV8856 sensor can output frames with 2/4 CSI2 data lanes. This commit adds support for 2 lane mode in addition to the 4 lane and also configuring the data lane settings in the driver based on system configuration. - Fix Bayer order output in 1640x1232 binning registers - supported data lanes + 3280x2464 on 2 & 4 lanes + 1640x1232 on 2 & 4 lanes + 3264x2448 on 4 lanes + 1632x1224 on 4 lanes Signed-off-by: Shawn Tu Acked-by: Andrey Konovalov Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov8856.c | 2331 ++++++++++++++++++++++-------------- 1 file changed, 1430 insertions(+), 901 deletions(-) diff --git a/drivers/media/i2c/ov8856.c b/drivers/media/i2c/ov8856.c index 2875f8e4ddcb..d145f004fd8d 100644 --- a/drivers/media/i2c/ov8856.c +++ b/drivers/media/i2c/ov8856.c @@ -18,8 +18,6 @@ #define OV8856_REG_VALUE_16BIT 2 #define OV8856_REG_VALUE_24BIT 3 -#define OV8856_LINK_FREQ_360MHZ 360000000ULL -#define OV8856_LINK_FREQ_180MHZ 180000000ULL #define OV8856_SCLK 144000000ULL #define OV8856_XVCLK_19_2 19200000 #define OV8856_DATA_LANES 4 @@ -78,6 +76,10 @@ #define OV8856_TEST_PATTERN_ENABLE BIT(7) #define OV8856_TEST_PATTERN_BAR_SHIFT 2 +#define NUM_REGS 7 +#define NUM_MODE_REGS 187 +#define NUM_MODE_REGS_2 200 + #define to_ov8856(_sd) container_of(_sd, struct ov8856, sd) static const char * const ov8856_supply_names[] = { @@ -86,11 +88,6 @@ static const char * const ov8856_supply_names[] = { "dvdd", /* Digital core power */ }; -enum { - OV8856_LINK_FREQ_720MBPS, - OV8856_LINK_FREQ_360MBPS, -}; - struct ov8856_reg { u16 address; u8 val; @@ -126,812 +123,1234 @@ struct ov8856_mode { /* Sensor register settings for this resolution */ const struct ov8856_reg_list reg_list; + + /* Number of data lanes */ + u8 data_lanes; }; -static const struct ov8856_reg mipi_data_rate_720mbps[] = { - {0x0103, 0x01}, - {0x0100, 0x00}, - {0x0302, 0x4b}, - {0x0303, 0x01}, - {0x030b, 0x02}, - {0x030d, 0x4b}, - {0x031e, 0x0c}, +struct ov8856_mipi_data_rates { + const struct ov8856_reg regs_0[NUM_REGS]; + const struct ov8856_reg regs_1[NUM_REGS]; }; -static const struct ov8856_reg mipi_data_rate_360mbps[] = { - {0x0103, 0x01}, - {0x0100, 0x00}, - {0x0302, 0x4b}, - {0x0303, 0x03}, - {0x030b, 0x02}, - {0x030d, 0x4b}, - {0x031e, 0x0c}, +static const struct ov8856_mipi_data_rates mipi_data_rate_lane_2 = { + //mipi_data_rate_1440mbps + { + {0x0103, 0x01}, + {0x0100, 0x00}, + {0x0302, 0x43}, + {0x0303, 0x00}, + {0x030b, 0x02}, + {0x030d, 0x4b}, + {0x031e, 0x0c} + }, + //mipi_data_rate_720mbps + { + {0x0103, 0x01}, + {0x0100, 0x00}, + {0x0302, 0x4b}, + {0x0303, 0x01}, + {0x030b, 0x02}, + {0x030d, 0x4b}, + {0x031e, 0x0c} + } }; -static const struct ov8856_reg mode_3280x2464_regs[] = { - {0x3000, 0x20}, - {0x3003, 0x08}, - {0x300e, 0x20}, - {0x3010, 0x00}, - {0x3015, 0x84}, - {0x3018, 0x72}, - {0x3021, 0x23}, - {0x3033, 0x24}, - {0x3500, 0x00}, - {0x3501, 0x9a}, - {0x3502, 0x20}, - {0x3503, 0x08}, - {0x3505, 0x83}, - {0x3508, 0x01}, - {0x3509, 0x80}, - {0x350c, 0x00}, - {0x350d, 0x80}, - {0x350e, 0x04}, - {0x350f, 0x00}, - {0x3510, 0x00}, - {0x3511, 0x02}, - {0x3512, 0x00}, - {0x3600, 0x72}, - {0x3601, 0x40}, - {0x3602, 0x30}, - {0x3610, 0xc5}, - {0x3611, 0x58}, - {0x3612, 0x5c}, - {0x3613, 0xca}, - {0x3614, 0x20}, - {0x3628, 0xff}, - {0x3629, 0xff}, - {0x362a, 0xff}, - {0x3633, 0x10}, - {0x3634, 0x10}, - {0x3635, 0x10}, - {0x3636, 0x10}, - {0x3663, 0x08}, - {0x3669, 0x34}, - {0x366e, 0x10}, - {0x3706, 0x86}, - {0x370b, 0x7e}, - {0x3714, 0x23}, - {0x3730, 0x12}, - {0x3733, 0x10}, - {0x3764, 0x00}, - {0x3765, 0x00}, - {0x3769, 0x62}, - {0x376a, 0x2a}, - {0x376b, 0x30}, - {0x3780, 0x00}, - {0x3781, 0x24}, - {0x3782, 0x00}, - {0x3783, 0x23}, - {0x3798, 0x2f}, - {0x37a1, 0x60}, - {0x37a8, 0x6a}, - {0x37ab, 0x3f}, - {0x37c2, 0x04}, - {0x37c3, 0xf1}, - {0x37c9, 0x80}, - {0x37cb, 0x16}, - {0x37cc, 0x16}, - {0x37cd, 0x16}, - {0x37ce, 0x16}, - {0x3800, 0x00}, - {0x3801, 0x00}, - {0x3802, 0x00}, - {0x3803, 0x06}, - {0x3804, 0x0c}, - {0x3805, 0xdf}, - {0x3806, 0x09}, - {0x3807, 0xa7}, - {0x3808, 0x0c}, - {0x3809, 0xd0}, - {0x380a, 0x09}, - {0x380b, 0xa0}, - {0x380c, 0x07}, - {0x380d, 0x88}, - {0x380e, 0x09}, - {0x380f, 0xb8}, - {0x3810, 0x00}, - {0x3811, 0x00}, - {0x3812, 0x00}, - {0x3813, 0x01}, - {0x3814, 0x01}, - {0x3815, 0x01}, - {0x3816, 0x00}, - {0x3817, 0x00}, - {0x3818, 0x00}, - {0x3819, 0x10}, - {0x3820, 0x80}, - {0x3821, 0x46}, - {0x382a, 0x01}, - {0x382b, 0x01}, - {0x3830, 0x06}, - {0x3836, 0x02}, - {0x3862, 0x04}, - {0x3863, 0x08}, - {0x3cc0, 0x33}, - {0x3d85, 0x17}, - {0x3d8c, 0x73}, - {0x3d8d, 0xde}, - {0x4001, 0xe0}, - {0x4003, 0x40}, - {0x4008, 0x00}, - {0x4009, 0x0b}, - {0x400a, 0x00}, - {0x400b, 0x84}, - {0x400f, 0x80}, - {0x4010, 0xf0}, - {0x4011, 0xff}, - {0x4012, 0x02}, - {0x4013, 0x01}, - {0x4014, 0x01}, - {0x4015, 0x01}, - {0x4042, 0x00}, - {0x4043, 0x80}, - {0x4044, 0x00}, - {0x4045, 0x80}, - {0x4046, 0x00}, - {0x4047, 0x80}, - {0x4048, 0x00}, - {0x4049, 0x80}, - {0x4041, 0x03}, - {0x404c, 0x20}, - {0x404d, 0x00}, - {0x404e, 0x20}, - {0x4203, 0x80}, - {0x4307, 0x30}, - {0x4317, 0x00}, - {0x4503, 0x08}, - {0x4601, 0x80}, - {0x4800, 0x44}, - {0x4816, 0x53}, - {0x481b, 0x58}, - {0x481f, 0x27}, - {0x4837, 0x16}, - {0x483c, 0x0f}, - {0x484b, 0x05}, - {0x5000, 0x57}, - {0x5001, 0x0a}, - {0x5004, 0x04}, - {0x502e, 0x03}, - {0x5030, 0x41}, - {0x5780, 0x14}, - {0x5781, 0x0f}, - {0x5782, 0x44}, - {0x5783, 0x02}, - {0x5784, 0x01}, - {0x5785, 0x01}, - {0x5786, 0x00}, - {0x5787, 0x04}, - {0x5788, 0x02}, - {0x5789, 0x0f}, - {0x578a, 0xfd}, - {0x578b, 0xf5}, - {0x578c, 0xf5}, - {0x578d, 0x03}, - {0x578e, 0x08}, - {0x578f, 0x0c}, - {0x5790, 0x08}, - {0x5791, 0x04}, - {0x5792, 0x00}, - {0x5793, 0x52}, - {0x5794, 0xa3}, - {0x5795, 0x02}, - {0x5796, 0x20}, - {0x5797, 0x20}, - {0x5798, 0xd5}, - {0x5799, 0xd5}, - {0x579a, 0x00}, - {0x579b, 0x50}, - {0x579c, 0x00}, - {0x579d, 0x2c}, - {0x579e, 0x0c}, - {0x579f, 0x40}, - {0x57a0, 0x09}, - {0x57a1, 0x40}, - {0x59f8, 0x3d}, - {0x5a08, 0x02}, - {0x5b00, 0x02}, - {0x5b01, 0x10}, - {0x5b02, 0x03}, - {0x5b03, 0xcf}, - {0x5b05, 0x6c}, - {0x5e00, 0x00} +static const struct ov8856_mipi_data_rates mipi_data_rate_lane_4 = { + //mipi_data_rate_720mbps + { + {0x0103, 0x01}, + {0x0100, 0x00}, + {0x0302, 0x4b}, + {0x0303, 0x01}, + {0x030b, 0x02}, + {0x030d, 0x4b}, + {0x031e, 0x0c} + }, + //mipi_data_rate_360mbps + { + {0x0103, 0x01}, + {0x0100, 0x00}, + {0x0302, 0x4b}, + {0x0303, 0x03}, + {0x030b, 0x02}, + {0x030d, 0x4b}, + {0x031e, 0x0c} + } }; -static const struct ov8856_reg mode_3264x2448_regs[] = { - {0x0103, 0x01}, - {0x0302, 0x3c}, - {0x0303, 0x01}, - {0x031e, 0x0c}, - {0x3000, 0x20}, - {0x3003, 0x08}, - {0x300e, 0x20}, - {0x3010, 0x00}, - {0x3015, 0x84}, - {0x3018, 0x72}, - {0x3021, 0x23}, - {0x3033, 0x24}, - {0x3500, 0x00}, - {0x3501, 0x9a}, - {0x3502, 0x20}, - {0x3503, 0x08}, - {0x3505, 0x83}, - {0x3508, 0x01}, - {0x3509, 0x80}, - {0x350c, 0x00}, - {0x350d, 0x80}, - {0x350e, 0x04}, - {0x350f, 0x00}, - {0x3510, 0x00}, - {0x3511, 0x02}, - {0x3512, 0x00}, - {0x3600, 0x72}, - {0x3601, 0x40}, - {0x3602, 0x30}, - {0x3610, 0xc5}, - {0x3611, 0x58}, - {0x3612, 0x5c}, - {0x3613, 0xca}, - {0x3614, 0x60}, - {0x3628, 0xff}, - {0x3629, 0xff}, - {0x362a, 0xff}, - {0x3633, 0x10}, - {0x3634, 0x10}, - {0x3635, 0x10}, - {0x3636, 0x10}, - {0x3663, 0x08}, - {0x3669, 0x34}, - {0x366d, 0x00}, - {0x366e, 0x10}, - {0x3706, 0x86}, - {0x370b, 0x7e}, - {0x3714, 0x23}, - {0x3730, 0x12}, - {0x3733, 0x10}, - {0x3764, 0x00}, - {0x3765, 0x00}, - {0x3769, 0x62}, - {0x376a, 0x2a}, - {0x376b, 0x30}, - {0x3780, 0x00}, - {0x3781, 0x24}, - {0x3782, 0x00}, - {0x3783, 0x23}, - {0x3798, 0x2f}, - {0x37a1, 0x60}, - {0x37a8, 0x6a}, - {0x37ab, 0x3f}, - {0x37c2, 0x04}, - {0x37c3, 0xf1}, - {0x37c9, 0x80}, - {0x37cb, 0x16}, - {0x37cc, 0x16}, - {0x37cd, 0x16}, - {0x37ce, 0x16}, - {0x3800, 0x00}, - {0x3801, 0x00}, - {0x3802, 0x00}, - {0x3803, 0x0c}, - {0x3804, 0x0c}, - {0x3805, 0xdf}, - {0x3806, 0x09}, - {0x3807, 0xa3}, - {0x3808, 0x0c}, - {0x3809, 0xc0}, - {0x380a, 0x09}, - {0x380b, 0x90}, - {0x380c, 0x07}, - {0x380d, 0x8c}, - {0x380e, 0x09}, - {0x380f, 0xb2}, - {0x3810, 0x00}, - {0x3811, 0x04}, - {0x3812, 0x00}, - {0x3813, 0x01}, - {0x3814, 0x01}, - {0x3815, 0x01}, - {0x3816, 0x00}, - {0x3817, 0x00}, - {0x3818, 0x00}, - {0x3819, 0x10}, - {0x3820, 0x80}, - {0x3821, 0x46}, - {0x382a, 0x01}, - {0x382b, 0x01}, - {0x3830, 0x06}, - {0x3836, 0x02}, - {0x3862, 0x04}, - {0x3863, 0x08}, - {0x3cc0, 0x33}, - {0x3d85, 0x17}, - {0x3d8c, 0x73}, - {0x3d8d, 0xde}, - {0x4001, 0xe0}, - {0x4003, 0x40}, - {0x4008, 0x00}, - {0x4009, 0x0b}, - {0x400a, 0x00}, - {0x400b, 0x84}, - {0x400f, 0x80}, - {0x4010, 0xf0}, - {0x4011, 0xff}, - {0x4012, 0x02}, - {0x4013, 0x01}, - {0x4014, 0x01}, - {0x4015, 0x01}, - {0x4042, 0x00}, - {0x4043, 0x80}, - {0x4044, 0x00}, - {0x4045, 0x80}, - {0x4046, 0x00}, - {0x4047, 0x80}, - {0x4048, 0x00}, - {0x4049, 0x80}, - {0x4041, 0x03}, - {0x404c, 0x20}, - {0x404d, 0x00}, - {0x404e, 0x20}, - {0x4203, 0x80}, - {0x4307, 0x30}, - {0x4317, 0x00}, - {0x4502, 0x50}, - {0x4503, 0x08}, - {0x4601, 0x80}, - {0x4800, 0x44}, - {0x4816, 0x53}, - {0x481b, 0x50}, - {0x481f, 0x27}, - {0x4823, 0x3c}, - {0x482b, 0x00}, - {0x4831, 0x66}, - {0x4837, 0x16}, - {0x483c, 0x0f}, - {0x484b, 0x05}, - {0x5000, 0x77}, - {0x5001, 0x0a}, - {0x5003, 0xc8}, - {0x5004, 0x04}, - {0x5006, 0x00}, - {0x5007, 0x00}, - {0x502e, 0x03}, - {0x5030, 0x41}, - {0x5780, 0x14}, - {0x5781, 0x0f}, - {0x5782, 0x44}, - {0x5783, 0x02}, - {0x5784, 0x01}, - {0x5785, 0x01}, - {0x5786, 0x00}, - {0x5787, 0x04}, - {0x5788, 0x02}, - {0x5789, 0x0f}, - {0x578a, 0xfd}, - {0x578b, 0xf5}, - {0x578c, 0xf5}, - {0x578d, 0x03}, - {0x578e, 0x08}, - {0x578f, 0x0c}, - {0x5790, 0x08}, - {0x5791, 0x04}, - {0x5792, 0x00}, - {0x5793, 0x52}, - {0x5794, 0xa3}, - {0x5795, 0x02}, - {0x5796, 0x20}, - {0x5797, 0x20}, - {0x5798, 0xd5}, - {0x5799, 0xd5}, - {0x579a, 0x00}, - {0x579b, 0x50}, - {0x579c, 0x00}, - {0x579d, 0x2c}, - {0x579e, 0x0c}, - {0x579f, 0x40}, - {0x57a0, 0x09}, - {0x57a1, 0x40}, - {0x59f8, 0x3d}, - {0x5a08, 0x02}, - {0x5b00, 0x02}, - {0x5b01, 0x10}, - {0x5b02, 0x03}, - {0x5b03, 0xcf}, - {0x5b05, 0x6c}, - {0x5e00, 0x00}, - {0x5e10, 0xfc} +static const struct ov8856_reg lane_2_mode_3280x2464[] = { + /* 3280x2464 resolution */ + {0x3000, 0x20}, + {0x3003, 0x08}, + {0x300e, 0x20}, + {0x3010, 0x00}, + {0x3015, 0x84}, + {0x3018, 0x32}, + {0x3021, 0x23}, + {0x3033, 0x24}, + {0x3500, 0x00}, + {0x3501, 0x9a}, + {0x3502, 0x20}, + {0x3503, 0x08}, + {0x3505, 0x83}, + {0x3508, 0x01}, + {0x3509, 0x80}, + {0x350c, 0x00}, + {0x350d, 0x80}, + {0x350e, 0x04}, + {0x350f, 0x00}, + {0x3510, 0x00}, + {0x3511, 0x02}, + {0x3512, 0x00}, + {0x3600, 0x72}, + {0x3601, 0x40}, + {0x3602, 0x30}, + {0x3610, 0xc5}, + {0x3611, 0x58}, + {0x3612, 0x5c}, + {0x3613, 0xca}, + {0x3614, 0x50}, + {0x3628, 0xff}, + {0x3629, 0xff}, + {0x362a, 0xff}, + {0x3633, 0x10}, + {0x3634, 0x10}, + {0x3635, 0x10}, + {0x3636, 0x10}, + {0x3663, 0x08}, + {0x3669, 0x34}, + {0x366e, 0x10}, + {0x3706, 0x86}, + {0x370b, 0x7e}, + {0x3714, 0x23}, + {0x3730, 0x12}, + {0x3733, 0x10}, + {0x3764, 0x00}, + {0x3765, 0x00}, + {0x3769, 0x62}, + {0x376a, 0x2a}, + {0x376b, 0x30}, + {0x3780, 0x00}, + {0x3781, 0x24}, + {0x3782, 0x00}, + {0x3783, 0x23}, + {0x3798, 0x2f}, + {0x37a1, 0x60}, + {0x37a8, 0x6a}, + {0x37ab, 0x3f}, + {0x37c2, 0x04}, + {0x37c3, 0xf1}, + {0x37c9, 0x80}, + {0x37cb, 0x16}, + {0x37cc, 0x16}, + {0x37cd, 0x16}, + {0x37ce, 0x16}, + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0x06}, + {0x3804, 0x0c}, + {0x3805, 0xdf}, + {0x3806, 0x09}, + {0x3807, 0xa7}, + {0x3808, 0x0c}, + {0x3809, 0xd0}, + {0x380a, 0x09}, + {0x380b, 0xa0}, + {0x380c, 0x07}, + {0x380d, 0x88}, + {0x380e, 0x09}, + {0x380f, 0xb8}, + {0x3810, 0x00}, + {0x3811, 0x00}, + {0x3812, 0x00}, + {0x3813, 0x01}, + {0x3814, 0x01}, + {0x3815, 0x01}, + {0x3816, 0x00}, + {0x3817, 0x00}, + {0x3818, 0x00}, + {0x3819, 0x00}, + {0x3820, 0x80}, + {0x3821, 0x46}, + {0x382a, 0x01}, + {0x382b, 0x01}, + {0x3830, 0x06}, + {0x3836, 0x02}, + {0x3837, 0x10}, + {0x3862, 0x04}, + {0x3863, 0x08}, + {0x3cc0, 0x33}, + {0x3d85, 0x14}, + {0x3d8c, 0x73}, + {0x3d8d, 0xde}, + {0x4001, 0xe0}, + {0x4003, 0x40}, + {0x4008, 0x00}, + {0x4009, 0x0b}, + {0x400a, 0x00}, + {0x400b, 0x84}, + {0x400f, 0x80}, + {0x4010, 0xf0}, + {0x4011, 0xff}, + {0x4012, 0x02}, + {0x4013, 0x01}, + {0x4014, 0x01}, + {0x4015, 0x01}, + {0x4042, 0x00}, + {0x4043, 0x80}, + {0x4044, 0x00}, + {0x4045, 0x80}, + {0x4046, 0x00}, + {0x4047, 0x80}, + {0x4048, 0x00}, + {0x4049, 0x80}, + {0x4041, 0x03}, + {0x404c, 0x20}, + {0x404d, 0x00}, + {0x404e, 0x20}, + {0x4203, 0x80}, + {0x4307, 0x30}, + {0x4317, 0x00}, + {0x4503, 0x08}, + {0x4601, 0x80}, + {0x4800, 0x44}, + {0x4816, 0x53}, + {0x481b, 0x58}, + {0x481f, 0x27}, + {0x4837, 0x0c}, + {0x483c, 0x0f}, + {0x484b, 0x05}, + {0x5000, 0x57}, + {0x5001, 0x0a}, + {0x5004, 0x04}, + {0x502e, 0x03}, + {0x5030, 0x41}, + {0x5795, 0x02}, + {0x5796, 0x20}, + {0x5797, 0x20}, + {0x5798, 0xd5}, + {0x5799, 0xd5}, + {0x579a, 0x00}, + {0x579b, 0x50}, + {0x579c, 0x00}, + {0x579d, 0x2c}, + {0x579e, 0x0c}, + {0x579f, 0x40}, + {0x57a0, 0x09}, + {0x57a1, 0x40}, + {0x5780, 0x14}, + {0x5781, 0x0f}, + {0x5782, 0x44}, + {0x5783, 0x02}, + {0x5784, 0x01}, + {0x5785, 0x01}, + {0x5786, 0x00}, + {0x5787, 0x04}, + {0x5788, 0x02}, + {0x5789, 0x0f}, + {0x578a, 0xfd}, + {0x578b, 0xf5}, + {0x578c, 0xf5}, + {0x578d, 0x03}, + {0x578e, 0x08}, + {0x578f, 0x0c}, + {0x5790, 0x08}, + {0x5791, 0x04}, + {0x5792, 0x00}, + {0x5793, 0x52}, + {0x5794, 0xa3}, + {0x59f8, 0x3d}, + {0x5a08, 0x02}, + {0x5b00, 0x02}, + {0x5b01, 0x10}, + {0x5b02, 0x03}, + {0x5b03, 0xcf}, + {0x5b05, 0x6c}, + {0x5e00, 0x00} }; -static const struct ov8856_reg mode_1640x1232_regs[] = { - {0x3000, 0x20}, - {0x3003, 0x08}, - {0x300e, 0x20}, - {0x3010, 0x00}, - {0x3015, 0x84}, - {0x3018, 0x72}, - {0x3021, 0x23}, - {0x3033, 0x24}, - {0x3500, 0x00}, - {0x3501, 0x4c}, - {0x3502, 0xe0}, - {0x3503, 0x08}, - {0x3505, 0x83}, - {0x3508, 0x01}, - {0x3509, 0x80}, - {0x350c, 0x00}, - {0x350d, 0x80}, - {0x350e, 0x04}, - {0x350f, 0x00}, - {0x3510, 0x00}, - {0x3511, 0x02}, - {0x3512, 0x00}, - {0x3600, 0x72}, - {0x3601, 0x40}, - {0x3602, 0x30}, - {0x3610, 0xc5}, - {0x3611, 0x58}, - {0x3612, 0x5c}, - {0x3613, 0xca}, - {0x3614, 0x20}, - {0x3628, 0xff}, - {0x3629, 0xff}, - {0x362a, 0xff}, - {0x3633, 0x10}, - {0x3634, 0x10}, - {0x3635, 0x10}, - {0x3636, 0x10}, - {0x3663, 0x08}, - {0x3669, 0x34}, - {0x366e, 0x08}, - {0x3706, 0x86}, - {0x370b, 0x7e}, - {0x3714, 0x27}, - {0x3730, 0x12}, - {0x3733, 0x10}, - {0x3764, 0x00}, - {0x3765, 0x00}, - {0x3769, 0x62}, - {0x376a, 0x2a}, - {0x376b, 0x30}, - {0x3780, 0x00}, - {0x3781, 0x24}, - {0x3782, 0x00}, - {0x3783, 0x23}, - {0x3798, 0x2f}, - {0x37a1, 0x60}, - {0x37a8, 0x6a}, - {0x37ab, 0x3f}, - {0x37c2, 0x14}, - {0x37c3, 0xf1}, - {0x37c9, 0x80}, - {0x37cb, 0x16}, - {0x37cc, 0x16}, - {0x37cd, 0x16}, - {0x37ce, 0x16}, - {0x3800, 0x00}, - {0x3801, 0x00}, - {0x3802, 0x00}, - {0x3803, 0x06}, - {0x3804, 0x0c}, - {0x3805, 0xdf}, - {0x3806, 0x09}, - {0x3807, 0xa7}, - {0x3808, 0x06}, - {0x3809, 0x68}, - {0x380a, 0x04}, - {0x380b, 0xd0}, - {0x380c, 0x0e}, - {0x380d, 0xec}, - {0x380e, 0x04}, - {0x380f, 0xe8}, - {0x3810, 0x00}, - {0x3811, 0x00}, - {0x3812, 0x00}, - {0x3813, 0x01}, - {0x3814, 0x03}, - {0x3815, 0x01}, - {0x3816, 0x00}, - {0x3817, 0x00}, - {0x3818, 0x00}, - {0x3819, 0x10}, - {0x3820, 0x90}, - {0x3821, 0x67}, - {0x382a, 0x03}, - {0x382b, 0x01}, - {0x3830, 0x06}, - {0x3836, 0x02}, - {0x3862, 0x04}, - {0x3863, 0x08}, - {0x3cc0, 0x33}, - {0x3d85, 0x17}, - {0x3d8c, 0x73}, - {0x3d8d, 0xde}, - {0x4001, 0xe0}, - {0x4003, 0x40}, - {0x4008, 0x00}, - {0x4009, 0x05}, - {0x400a, 0x00}, - {0x400b, 0x84}, - {0x400f, 0x80}, - {0x4010, 0xf0}, - {0x4011, 0xff}, - {0x4012, 0x02}, - {0x4013, 0x01}, - {0x4014, 0x01}, - {0x4015, 0x01}, - {0x4042, 0x00}, - {0x4043, 0x80}, - {0x4044, 0x00}, - {0x4045, 0x80}, - {0x4046, 0x00}, - {0x4047, 0x80}, - {0x4048, 0x00}, - {0x4049, 0x80}, - {0x4041, 0x03}, - {0x404c, 0x20}, - {0x404d, 0x00}, - {0x404e, 0x20}, - {0x4203, 0x80}, - {0x4307, 0x30}, - {0x4317, 0x00}, - {0x4503, 0x08}, - {0x4601, 0x80}, - {0x4800, 0x44}, - {0x4816, 0x53}, - {0x481b, 0x58}, - {0x481f, 0x27}, - {0x4837, 0x16}, - {0x483c, 0x0f}, - {0x484b, 0x05}, - {0x5000, 0x57}, - {0x5001, 0x0a}, - {0x5004, 0x04}, - {0x502e, 0x03}, - {0x5030, 0x41}, - {0x5780, 0x14}, - {0x5781, 0x0f}, - {0x5782, 0x44}, - {0x5783, 0x02}, - {0x5784, 0x01}, - {0x5785, 0x01}, - {0x5786, 0x00}, - {0x5787, 0x04}, - {0x5788, 0x02}, - {0x5789, 0x0f}, - {0x578a, 0xfd}, - {0x578b, 0xf5}, - {0x578c, 0xf5}, - {0x578d, 0x03}, - {0x578e, 0x08}, - {0x578f, 0x0c}, - {0x5790, 0x08}, - {0x5791, 0x04}, - {0x5792, 0x00}, - {0x5793, 0x52}, - {0x5794, 0xa3}, - {0x5795, 0x00}, - {0x5796, 0x10}, - {0x5797, 0x10}, - {0x5798, 0x73}, - {0x5799, 0x73}, - {0x579a, 0x00}, - {0x579b, 0x28}, - {0x579c, 0x00}, - {0x579d, 0x16}, - {0x579e, 0x06}, - {0x579f, 0x20}, - {0x57a0, 0x04}, - {0x57a1, 0xa0}, - {0x59f8, 0x3d}, - {0x5a08, 0x02}, - {0x5b00, 0x02}, - {0x5b01, 0x10}, - {0x5b02, 0x03}, - {0x5b03, 0xcf}, - {0x5b05, 0x6c}, - {0x5e00, 0x00} +static const struct ov8856_reg lane_2_mode_1640x1232[] = { + /* 1640x1232 resolution */ + {0x3000, 0x20}, + {0x3003, 0x08}, + {0x300e, 0x20}, + {0x3010, 0x00}, + {0x3015, 0x84}, + {0x3018, 0x32}, + {0x3021, 0x23}, + {0x3033, 0x24}, + {0x3500, 0x00}, + {0x3501, 0x4c}, + {0x3502, 0xe0}, + {0x3503, 0x08}, + {0x3505, 0x83}, + {0x3508, 0x01}, + {0x3509, 0x80}, + {0x350c, 0x00}, + {0x350d, 0x80}, + {0x350e, 0x04}, + {0x350f, 0x00}, + {0x3510, 0x00}, + {0x3511, 0x02}, + {0x3512, 0x00}, + {0x3600, 0x72}, + {0x3601, 0x40}, + {0x3602, 0x30}, + {0x3610, 0xc5}, + {0x3611, 0x58}, + {0x3612, 0x5c}, + {0x3613, 0xca}, + {0x3614, 0x50}, + {0x3628, 0xff}, + {0x3629, 0xff}, + {0x362a, 0xff}, + {0x3633, 0x10}, + {0x3634, 0x10}, + {0x3635, 0x10}, + {0x3636, 0x10}, + {0x3663, 0x08}, + {0x3669, 0x34}, + {0x366e, 0x08}, + {0x3706, 0x86}, + {0x370b, 0x7e}, + {0x3714, 0x27}, + {0x3730, 0x12}, + {0x3733, 0x10}, + {0x3764, 0x00}, + {0x3765, 0x00}, + {0x3769, 0x62}, + {0x376a, 0x2a}, + {0x376b, 0x30}, + {0x3780, 0x00}, + {0x3781, 0x24}, + {0x3782, 0x00}, + {0x3783, 0x23}, + {0x3798, 0x2f}, + {0x37a1, 0x60}, + {0x37a8, 0x6a}, + {0x37ab, 0x3f}, + {0x37c2, 0x14}, + {0x37c3, 0xf1}, + {0x37c9, 0x80}, + {0x37cb, 0x16}, + {0x37cc, 0x16}, + {0x37cd, 0x16}, + {0x37ce, 0x16}, + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0x00}, + {0x3804, 0x0c}, + {0x3805, 0xdf}, + {0x3806, 0x09}, + {0x3807, 0xaf}, + {0x3808, 0x06}, + {0x3809, 0x68}, + {0x380a, 0x04}, + {0x380b, 0xd0}, + {0x380c, 0x0c}, + {0x380d, 0x60}, + {0x380e, 0x05}, + {0x380f, 0xea}, + {0x3810, 0x00}, + {0x3811, 0x04}, + {0x3812, 0x00}, + {0x3813, 0x05}, + {0x3814, 0x03}, + {0x3815, 0x01}, + {0x3816, 0x00}, + {0x3817, 0x00}, + {0x3818, 0x00}, + {0x3819, 0x00}, + {0x3820, 0x90}, + {0x3821, 0x67}, + {0x382a, 0x03}, + {0x382b, 0x01}, + {0x3830, 0x06}, + {0x3836, 0x02}, + {0x3837, 0x10}, + {0x3862, 0x04}, + {0x3863, 0x08}, + {0x3cc0, 0x33}, + {0x3d85, 0x14}, + {0x3d8c, 0x73}, + {0x3d8d, 0xde}, + {0x4001, 0xe0}, + {0x4003, 0x40}, + {0x4008, 0x00}, + {0x4009, 0x05}, + {0x400a, 0x00}, + {0x400b, 0x84}, + {0x400f, 0x80}, + {0x4010, 0xf0}, + {0x4011, 0xff}, + {0x4012, 0x02}, + {0x4013, 0x01}, + {0x4014, 0x01}, + {0x4015, 0x01}, + {0x4042, 0x00}, + {0x4043, 0x80}, + {0x4044, 0x00}, + {0x4045, 0x80}, + {0x4046, 0x00}, + {0x4047, 0x80}, + {0x4048, 0x00}, + {0x4049, 0x80}, + {0x4041, 0x03}, + {0x404c, 0x20}, + {0x404d, 0x00}, + {0x404e, 0x20}, + {0x4203, 0x80}, + {0x4307, 0x30}, + {0x4317, 0x00}, + {0x4503, 0x08}, + {0x4601, 0x80}, + {0x4800, 0x44}, + {0x4816, 0x53}, + {0x481b, 0x58}, + {0x481f, 0x27}, + {0x4837, 0x16}, + {0x483c, 0x0f}, + {0x484b, 0x05}, + {0x5000, 0x57}, + {0x5001, 0x0a}, + {0x5004, 0x04}, + {0x502e, 0x03}, + {0x5030, 0x41}, + {0x5795, 0x00}, + {0x5796, 0x10}, + {0x5797, 0x10}, + {0x5798, 0x73}, + {0x5799, 0x73}, + {0x579a, 0x00}, + {0x579b, 0x28}, + {0x579c, 0x00}, + {0x579d, 0x16}, + {0x579e, 0x06}, + {0x579f, 0x20}, + {0x57a0, 0x04}, + {0x57a1, 0xa0}, + {0x5780, 0x14}, + {0x5781, 0x0f}, + {0x5782, 0x44}, + {0x5783, 0x02}, + {0x5784, 0x01}, + {0x5785, 0x01}, + {0x5786, 0x00}, + {0x5787, 0x04}, + {0x5788, 0x02}, + {0x5789, 0x0f}, + {0x578a, 0xfd}, + {0x578b, 0xf5}, + {0x578c, 0xf5}, + {0x578d, 0x03}, + {0x578e, 0x08}, + {0x578f, 0x0c}, + {0x5790, 0x08}, + {0x5791, 0x04}, + {0x5792, 0x00}, + {0x5793, 0x52}, + {0x5794, 0xa3}, + {0x59f8, 0x3d}, + {0x5a08, 0x02}, + {0x5b00, 0x02}, + {0x5b01, 0x10}, + {0x5b02, 0x03}, + {0x5b03, 0xcf}, + {0x5b05, 0x6c}, + {0x5e00, 0x00} }; -static const struct ov8856_reg mode_1632x1224_regs[] = { - {0x0103, 0x01}, - {0x0302, 0x3c}, - {0x0303, 0x01}, - {0x031e, 0x0c}, - {0x3000, 0x20}, - {0x3003, 0x08}, - {0x300e, 0x20}, - {0x3010, 0x00}, - {0x3015, 0x84}, - {0x3018, 0x72}, - {0x3021, 0x23}, - {0x3033, 0x24}, - {0x3500, 0x00}, - {0x3501, 0x4c}, - {0x3502, 0xe0}, - {0x3503, 0x08}, - {0x3505, 0x83}, - {0x3508, 0x01}, - {0x3509, 0x80}, - {0x350c, 0x00}, - {0x350d, 0x80}, - {0x350e, 0x04}, - {0x350f, 0x00}, - {0x3510, 0x00}, - {0x3511, 0x02}, - {0x3512, 0x00}, - {0x3600, 0x72}, - {0x3601, 0x40}, - {0x3602, 0x30}, - {0x3610, 0xc5}, - {0x3611, 0x58}, - {0x3612, 0x5c}, - {0x3613, 0xca}, - {0x3614, 0x60}, - {0x3628, 0xff}, - {0x3629, 0xff}, - {0x362a, 0xff}, - {0x3633, 0x10}, - {0x3634, 0x10}, - {0x3635, 0x10}, - {0x3636, 0x10}, - {0x3663, 0x08}, - {0x3669, 0x34}, - {0x366d, 0x00}, - {0x366e, 0x08}, - {0x3706, 0x86}, - {0x370b, 0x7e}, - {0x3714, 0x27}, - {0x3730, 0x12}, - {0x3733, 0x10}, - {0x3764, 0x00}, - {0x3765, 0x00}, - {0x3769, 0x62}, - {0x376a, 0x2a}, - {0x376b, 0x30}, - {0x3780, 0x00}, - {0x3781, 0x24}, - {0x3782, 0x00}, - {0x3783, 0x23}, - {0x3798, 0x2f}, - {0x37a1, 0x60}, - {0x37a8, 0x6a}, - {0x37ab, 0x3f}, - {0x37c2, 0x14}, - {0x37c3, 0xf1}, - {0x37c9, 0x80}, - {0x37cb, 0x16}, - {0x37cc, 0x16}, - {0x37cd, 0x16}, - {0x37ce, 0x16}, - {0x3800, 0x00}, - {0x3801, 0x00}, - {0x3802, 0x00}, - {0x3803, 0x0c}, - {0x3804, 0x0c}, - {0x3805, 0xdf}, - {0x3806, 0x09}, - {0x3807, 0xa3}, - {0x3808, 0x06}, - {0x3809, 0x60}, - {0x380a, 0x04}, - {0x380b, 0xc8}, - {0x380c, 0x07}, - {0x380d, 0x8c}, - {0x380e, 0x09}, - {0x380f, 0xb2}, - {0x3810, 0x00}, - {0x3811, 0x02}, - {0x3812, 0x00}, - {0x3813, 0x01}, - {0x3814, 0x03}, - {0x3815, 0x01}, - {0x3816, 0x00}, - {0x3817, 0x00}, - {0x3818, 0x00}, - {0x3819, 0x10}, - {0x3820, 0x80}, - {0x3821, 0x47}, - {0x382a, 0x03}, - {0x382b, 0x01}, - {0x3830, 0x06}, - {0x3836, 0x02}, - {0x3862, 0x04}, - {0x3863, 0x08}, - {0x3cc0, 0x33}, - {0x3d85, 0x17}, - {0x3d8c, 0x73}, - {0x3d8d, 0xde}, - {0x4001, 0xe0}, - {0x4003, 0x40}, - {0x4008, 0x00}, - {0x4009, 0x05}, - {0x400a, 0x00}, - {0x400b, 0x84}, - {0x400f, 0x80}, - {0x4010, 0xf0}, - {0x4011, 0xff}, - {0x4012, 0x02}, - {0x4013, 0x01}, - {0x4014, 0x01}, - {0x4015, 0x01}, - {0x4042, 0x00}, - {0x4043, 0x80}, - {0x4044, 0x00}, - {0x4045, 0x80}, - {0x4046, 0x00}, - {0x4047, 0x80}, - {0x4048, 0x00}, - {0x4049, 0x80}, - {0x4041, 0x03}, - {0x404c, 0x20}, - {0x404d, 0x00}, - {0x404e, 0x20}, - {0x4203, 0x80}, - {0x4307, 0x30}, - {0x4317, 0x00}, - {0x4502, 0x50}, - {0x4503, 0x08}, - {0x4601, 0x80}, - {0x4800, 0x44}, - {0x4816, 0x53}, - {0x481b, 0x50}, - {0x481f, 0x27}, - {0x4823, 0x3c}, - {0x482b, 0x00}, - {0x4831, 0x66}, - {0x4837, 0x16}, - {0x483c, 0x0f}, - {0x484b, 0x05}, - {0x5000, 0x77}, - {0x5001, 0x0a}, - {0x5003, 0xc8}, - {0x5004, 0x04}, - {0x5006, 0x00}, - {0x5007, 0x00}, - {0x502e, 0x03}, - {0x5030, 0x41}, - {0x5795, 0x00}, - {0x5796, 0x10}, - {0x5797, 0x10}, - {0x5798, 0x73}, - {0x5799, 0x73}, - {0x579a, 0x00}, - {0x579b, 0x28}, - {0x579c, 0x00}, - {0x579d, 0x16}, - {0x579e, 0x06}, - {0x579f, 0x20}, - {0x57a0, 0x04}, - {0x57a1, 0xa0}, - {0x5780, 0x14}, - {0x5781, 0x0f}, - {0x5782, 0x44}, - {0x5783, 0x02}, - {0x5784, 0x01}, - {0x5785, 0x01}, - {0x5786, 0x00}, - {0x5787, 0x04}, - {0x5788, 0x02}, - {0x5789, 0x0f}, - {0x578a, 0xfd}, - {0x578b, 0xf5}, - {0x578c, 0xf5}, - {0x578d, 0x03}, - {0x578e, 0x08}, - {0x578f, 0x0c}, - {0x5790, 0x08}, - {0x5791, 0x04}, - {0x5792, 0x00}, - {0x5793, 0x52}, - {0x5794, 0xa3}, - {0x59f8, 0x3d}, - {0x5a08, 0x02}, - {0x5b00, 0x02}, - {0x5b01, 0x10}, - {0x5b02, 0x03}, - {0x5b03, 0xcf}, - {0x5b05, 0x6c}, - {0x5e00, 0x00}, - {0x5e10, 0xfc} +static const struct ov8856_reg lane_4_mode_3280x2464[] = { + /* 3280x2464 resolution */ + {0x3000, 0x20}, + {0x3003, 0x08}, + {0x300e, 0x20}, + {0x3010, 0x00}, + {0x3015, 0x84}, + {0x3018, 0x72}, + {0x3021, 0x23}, + {0x3033, 0x24}, + {0x3500, 0x00}, + {0x3501, 0x9a}, + {0x3502, 0x20}, + {0x3503, 0x08}, + {0x3505, 0x83}, + {0x3508, 0x01}, + {0x3509, 0x80}, + {0x350c, 0x00}, + {0x350d, 0x80}, + {0x350e, 0x04}, + {0x350f, 0x00}, + {0x3510, 0x00}, + {0x3511, 0x02}, + {0x3512, 0x00}, + {0x3600, 0x72}, + {0x3601, 0x40}, + {0x3602, 0x30}, + {0x3610, 0xc5}, + {0x3611, 0x58}, + {0x3612, 0x5c}, + {0x3613, 0xca}, + {0x3614, 0x20}, + {0x3628, 0xff}, + {0x3629, 0xff}, + {0x362a, 0xff}, + {0x3633, 0x10}, + {0x3634, 0x10}, + {0x3635, 0x10}, + {0x3636, 0x10}, + {0x3663, 0x08}, + {0x3669, 0x34}, + {0x366e, 0x10}, + {0x3706, 0x86}, + {0x370b, 0x7e}, + {0x3714, 0x23}, + {0x3730, 0x12}, + {0x3733, 0x10}, + {0x3764, 0x00}, + {0x3765, 0x00}, + {0x3769, 0x62}, + {0x376a, 0x2a}, + {0x376b, 0x30}, + {0x3780, 0x00}, + {0x3781, 0x24}, + {0x3782, 0x00}, + {0x3783, 0x23}, + {0x3798, 0x2f}, + {0x37a1, 0x60}, + {0x37a8, 0x6a}, + {0x37ab, 0x3f}, + {0x37c2, 0x04}, + {0x37c3, 0xf1}, + {0x37c9, 0x80}, + {0x37cb, 0x16}, + {0x37cc, 0x16}, + {0x37cd, 0x16}, + {0x37ce, 0x16}, + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0x06}, + {0x3804, 0x0c}, + {0x3805, 0xdf}, + {0x3806, 0x09}, + {0x3807, 0xa7}, + {0x3808, 0x0c}, + {0x3809, 0xd0}, + {0x380a, 0x09}, + {0x380b, 0xa0}, + {0x380c, 0x07}, + {0x380d, 0x88}, + {0x380e, 0x09}, + {0x380f, 0xb8}, + {0x3810, 0x00}, + {0x3811, 0x00}, + {0x3812, 0x00}, + {0x3813, 0x01}, + {0x3814, 0x01}, + {0x3815, 0x01}, + {0x3816, 0x00}, + {0x3817, 0x00}, + {0x3818, 0x00}, + {0x3819, 0x10}, + {0x3820, 0x80}, + {0x3821, 0x46}, + {0x382a, 0x01}, + {0x382b, 0x01}, + {0x3830, 0x06}, + {0x3836, 0x02}, + {0x3862, 0x04}, + {0x3863, 0x08}, + {0x3cc0, 0x33}, + {0x3d85, 0x17}, + {0x3d8c, 0x73}, + {0x3d8d, 0xde}, + {0x4001, 0xe0}, + {0x4003, 0x40}, + {0x4008, 0x00}, + {0x4009, 0x0b}, + {0x400a, 0x00}, + {0x400b, 0x84}, + {0x400f, 0x80}, + {0x4010, 0xf0}, + {0x4011, 0xff}, + {0x4012, 0x02}, + {0x4013, 0x01}, + {0x4014, 0x01}, + {0x4015, 0x01}, + {0x4042, 0x00}, + {0x4043, 0x80}, + {0x4044, 0x00}, + {0x4045, 0x80}, + {0x4046, 0x00}, + {0x4047, 0x80}, + {0x4048, 0x00}, + {0x4049, 0x80}, + {0x4041, 0x03}, + {0x404c, 0x20}, + {0x404d, 0x00}, + {0x404e, 0x20}, + {0x4203, 0x80}, + {0x4307, 0x30}, + {0x4317, 0x00}, + {0x4503, 0x08}, + {0x4601, 0x80}, + {0x4800, 0x44}, + {0x4816, 0x53}, + {0x481b, 0x58}, + {0x481f, 0x27}, + {0x4837, 0x16}, + {0x483c, 0x0f}, + {0x484b, 0x05}, + {0x5000, 0x57}, + {0x5001, 0x0a}, + {0x5004, 0x04}, + {0x502e, 0x03}, + {0x5030, 0x41}, + {0x5780, 0x14}, + {0x5781, 0x0f}, + {0x5782, 0x44}, + {0x5783, 0x02}, + {0x5784, 0x01}, + {0x5785, 0x01}, + {0x5786, 0x00}, + {0x5787, 0x04}, + {0x5788, 0x02}, + {0x5789, 0x0f}, + {0x578a, 0xfd}, + {0x578b, 0xf5}, + {0x578c, 0xf5}, + {0x578d, 0x03}, + {0x578e, 0x08}, + {0x578f, 0x0c}, + {0x5790, 0x08}, + {0x5791, 0x04}, + {0x5792, 0x00}, + {0x5793, 0x52}, + {0x5794, 0xa3}, + {0x5795, 0x02}, + {0x5796, 0x20}, + {0x5797, 0x20}, + {0x5798, 0xd5}, + {0x5799, 0xd5}, + {0x579a, 0x00}, + {0x579b, 0x50}, + {0x579c, 0x00}, + {0x579d, 0x2c}, + {0x579e, 0x0c}, + {0x579f, 0x40}, + {0x57a0, 0x09}, + {0x57a1, 0x40}, + {0x59f8, 0x3d}, + {0x5a08, 0x02}, + {0x5b00, 0x02}, + {0x5b01, 0x10}, + {0x5b02, 0x03}, + {0x5b03, 0xcf}, + {0x5b05, 0x6c}, + {0x5e00, 0x00} +}; + +static const struct ov8856_reg lane_4_mode_1640x1232[] = { + /* 1640x1232 resolution */ + {0x3000, 0x20}, + {0x3003, 0x08}, + {0x300e, 0x20}, + {0x3010, 0x00}, + {0x3015, 0x84}, + {0x3018, 0x72}, + {0x3021, 0x23}, + {0x3033, 0x24}, + {0x3500, 0x00}, + {0x3501, 0x4c}, + {0x3502, 0xe0}, + {0x3503, 0x08}, + {0x3505, 0x83}, + {0x3508, 0x01}, + {0x3509, 0x80}, + {0x350c, 0x00}, + {0x350d, 0x80}, + {0x350e, 0x04}, + {0x350f, 0x00}, + {0x3510, 0x00}, + {0x3511, 0x02}, + {0x3512, 0x00}, + {0x3600, 0x72}, + {0x3601, 0x40}, + {0x3602, 0x30}, + {0x3610, 0xc5}, + {0x3611, 0x58}, + {0x3612, 0x5c}, + {0x3613, 0xca}, + {0x3614, 0x20}, + {0x3628, 0xff}, + {0x3629, 0xff}, + {0x362a, 0xff}, + {0x3633, 0x10}, + {0x3634, 0x10}, + {0x3635, 0x10}, + {0x3636, 0x10}, + {0x3663, 0x08}, + {0x3669, 0x34}, + {0x366e, 0x08}, + {0x3706, 0x86}, + {0x370b, 0x7e}, + {0x3714, 0x27}, + {0x3730, 0x12}, + {0x3733, 0x10}, + {0x3764, 0x00}, + {0x3765, 0x00}, + {0x3769, 0x62}, + {0x376a, 0x2a}, + {0x376b, 0x30}, + {0x3780, 0x00}, + {0x3781, 0x24}, + {0x3782, 0x00}, + {0x3783, 0x23}, + {0x3798, 0x2f}, + {0x37a1, 0x60}, + {0x37a8, 0x6a}, + {0x37ab, 0x3f}, + {0x37c2, 0x14}, + {0x37c3, 0xf1}, + {0x37c9, 0x80}, + {0x37cb, 0x16}, + {0x37cc, 0x16}, + {0x37cd, 0x16}, + {0x37ce, 0x16}, + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0x00}, + {0x3804, 0x0c}, + {0x3805, 0xdf}, + {0x3806, 0x09}, + {0x3807, 0xaf}, + {0x3808, 0x06}, + {0x3809, 0x68}, + {0x380a, 0x04}, + {0x380b, 0xd0}, + {0x380c, 0x0e}, + {0x380d, 0xec}, + {0x380e, 0x04}, + {0x380f, 0xe8}, + {0x3810, 0x00}, + {0x3811, 0x04}, + {0x3812, 0x00}, + {0x3813, 0x05}, + {0x3814, 0x03}, + {0x3815, 0x01}, + {0x3816, 0x00}, + {0x3817, 0x00}, + {0x3818, 0x00}, + {0x3819, 0x10}, + {0x3820, 0x90}, + {0x3821, 0x67}, + {0x382a, 0x03}, + {0x382b, 0x01}, + {0x3830, 0x06}, + {0x3836, 0x02}, + {0x3862, 0x04}, + {0x3863, 0x08}, + {0x3cc0, 0x33}, + {0x3d85, 0x17}, + {0x3d8c, 0x73}, + {0x3d8d, 0xde}, + {0x4001, 0xe0}, + {0x4003, 0x40}, + {0x4008, 0x00}, + {0x4009, 0x05}, + {0x400a, 0x00}, + {0x400b, 0x84}, + {0x400f, 0x80}, + {0x4010, 0xf0}, + {0x4011, 0xff}, + {0x4012, 0x02}, + {0x4013, 0x01}, + {0x4014, 0x01}, + {0x4015, 0x01}, + {0x4042, 0x00}, + {0x4043, 0x80}, + {0x4044, 0x00}, + {0x4045, 0x80}, + {0x4046, 0x00}, + {0x4047, 0x80}, + {0x4048, 0x00}, + {0x4049, 0x80}, + {0x4041, 0x03}, + {0x404c, 0x20}, + {0x404d, 0x00}, + {0x404e, 0x20}, + {0x4203, 0x80}, + {0x4307, 0x30}, + {0x4317, 0x00}, + {0x4503, 0x08}, + {0x4601, 0x80}, + {0x4800, 0x44}, + {0x4816, 0x53}, + {0x481b, 0x58}, + {0x481f, 0x27}, + {0x4837, 0x16}, + {0x483c, 0x0f}, + {0x484b, 0x05}, + {0x5000, 0x57}, + {0x5001, 0x0a}, + {0x5004, 0x04}, + {0x502e, 0x03}, + {0x5030, 0x41}, + {0x5780, 0x14}, + {0x5781, 0x0f}, + {0x5782, 0x44}, + {0x5783, 0x02}, + {0x5784, 0x01}, + {0x5785, 0x01}, + {0x5786, 0x00}, + {0x5787, 0x04}, + {0x5788, 0x02}, + {0x5789, 0x0f}, + {0x578a, 0xfd}, + {0x578b, 0xf5}, + {0x578c, 0xf5}, + {0x578d, 0x03}, + {0x578e, 0x08}, + {0x578f, 0x0c}, + {0x5790, 0x08}, + {0x5791, 0x04}, + {0x5792, 0x00}, + {0x5793, 0x52}, + {0x5794, 0xa3}, + {0x5795, 0x00}, + {0x5796, 0x10}, + {0x5797, 0x10}, + {0x5798, 0x73}, + {0x5799, 0x73}, + {0x579a, 0x00}, + {0x579b, 0x28}, + {0x579c, 0x00}, + {0x579d, 0x16}, + {0x579e, 0x06}, + {0x579f, 0x20}, + {0x57a0, 0x04}, + {0x57a1, 0xa0}, + {0x59f8, 0x3d}, + {0x5a08, 0x02}, + {0x5b00, 0x02}, + {0x5b01, 0x10}, + {0x5b02, 0x03}, + {0x5b03, 0xcf}, + {0x5b05, 0x6c}, + {0x5e00, 0x00} +}; + +static const struct ov8856_reg lane_4_mode_3264x2448[] = { + /* 3264x2448 resolution */ + {0x0103, 0x01}, + {0x0302, 0x3c}, + {0x0303, 0x01}, + {0x031e, 0x0c}, + {0x3000, 0x20}, + {0x3003, 0x08}, + {0x300e, 0x20}, + {0x3010, 0x00}, + {0x3015, 0x84}, + {0x3018, 0x72}, + {0x3021, 0x23}, + {0x3033, 0x24}, + {0x3500, 0x00}, + {0x3501, 0x9a}, + {0x3502, 0x20}, + {0x3503, 0x08}, + {0x3505, 0x83}, + {0x3508, 0x01}, + {0x3509, 0x80}, + {0x350c, 0x00}, + {0x350d, 0x80}, + {0x350e, 0x04}, + {0x350f, 0x00}, + {0x3510, 0x00}, + {0x3511, 0x02}, + {0x3512, 0x00}, + {0x3600, 0x72}, + {0x3601, 0x40}, + {0x3602, 0x30}, + {0x3610, 0xc5}, + {0x3611, 0x58}, + {0x3612, 0x5c}, + {0x3613, 0xca}, + {0x3614, 0x60}, + {0x3628, 0xff}, + {0x3629, 0xff}, + {0x362a, 0xff}, + {0x3633, 0x10}, + {0x3634, 0x10}, + {0x3635, 0x10}, + {0x3636, 0x10}, + {0x3663, 0x08}, + {0x3669, 0x34}, + {0x366d, 0x00}, + {0x366e, 0x10}, + {0x3706, 0x86}, + {0x370b, 0x7e}, + {0x3714, 0x23}, + {0x3730, 0x12}, + {0x3733, 0x10}, + {0x3764, 0x00}, + {0x3765, 0x00}, + {0x3769, 0x62}, + {0x376a, 0x2a}, + {0x376b, 0x30}, + {0x3780, 0x00}, + {0x3781, 0x24}, + {0x3782, 0x00}, + {0x3783, 0x23}, + {0x3798, 0x2f}, + {0x37a1, 0x60}, + {0x37a8, 0x6a}, + {0x37ab, 0x3f}, + {0x37c2, 0x04}, + {0x37c3, 0xf1}, + {0x37c9, 0x80}, + {0x37cb, 0x16}, + {0x37cc, 0x16}, + {0x37cd, 0x16}, + {0x37ce, 0x16}, + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0x0c}, + {0x3804, 0x0c}, + {0x3805, 0xdf}, + {0x3806, 0x09}, + {0x3807, 0xa3}, + {0x3808, 0x0c}, + {0x3809, 0xc0}, + {0x380a, 0x09}, + {0x380b, 0x90}, + {0x380c, 0x07}, + {0x380d, 0x8c}, + {0x380e, 0x09}, + {0x380f, 0xb2}, + {0x3810, 0x00}, + {0x3811, 0x04}, + {0x3812, 0x00}, + {0x3813, 0x01}, + {0x3814, 0x01}, + {0x3815, 0x01}, + {0x3816, 0x00}, + {0x3817, 0x00}, + {0x3818, 0x00}, + {0x3819, 0x10}, + {0x3820, 0x80}, + {0x3821, 0x46}, + {0x382a, 0x01}, + {0x382b, 0x01}, + {0x3830, 0x06}, + {0x3836, 0x02}, + {0x3862, 0x04}, + {0x3863, 0x08}, + {0x3cc0, 0x33}, + {0x3d85, 0x17}, + {0x3d8c, 0x73}, + {0x3d8d, 0xde}, + {0x4001, 0xe0}, + {0x4003, 0x40}, + {0x4008, 0x00}, + {0x4009, 0x0b}, + {0x400a, 0x00}, + {0x400b, 0x84}, + {0x400f, 0x80}, + {0x4010, 0xf0}, + {0x4011, 0xff}, + {0x4012, 0x02}, + {0x4013, 0x01}, + {0x4014, 0x01}, + {0x4015, 0x01}, + {0x4042, 0x00}, + {0x4043, 0x80}, + {0x4044, 0x00}, + {0x4045, 0x80}, + {0x4046, 0x00}, + {0x4047, 0x80}, + {0x4048, 0x00}, + {0x4049, 0x80}, + {0x4041, 0x03}, + {0x404c, 0x20}, + {0x404d, 0x00}, + {0x404e, 0x20}, + {0x4203, 0x80}, + {0x4307, 0x30}, + {0x4317, 0x00}, + {0x4502, 0x50}, + {0x4503, 0x08}, + {0x4601, 0x80}, + {0x4800, 0x44}, + {0x4816, 0x53}, + {0x481b, 0x50}, + {0x481f, 0x27}, + {0x4823, 0x3c}, + {0x482b, 0x00}, + {0x4831, 0x66}, + {0x4837, 0x16}, + {0x483c, 0x0f}, + {0x484b, 0x05}, + {0x5000, 0x77}, + {0x5001, 0x0a}, + {0x5003, 0xc8}, + {0x5004, 0x04}, + {0x5006, 0x00}, + {0x5007, 0x00}, + {0x502e, 0x03}, + {0x5030, 0x41}, + {0x5780, 0x14}, + {0x5781, 0x0f}, + {0x5782, 0x44}, + {0x5783, 0x02}, + {0x5784, 0x01}, + {0x5785, 0x01}, + {0x5786, 0x00}, + {0x5787, 0x04}, + {0x5788, 0x02}, + {0x5789, 0x0f}, + {0x578a, 0xfd}, + {0x578b, 0xf5}, + {0x578c, 0xf5}, + {0x578d, 0x03}, + {0x578e, 0x08}, + {0x578f, 0x0c}, + {0x5790, 0x08}, + {0x5791, 0x04}, + {0x5792, 0x00}, + {0x5793, 0x52}, + {0x5794, 0xa3}, + {0x5795, 0x02}, + {0x5796, 0x20}, + {0x5797, 0x20}, + {0x5798, 0xd5}, + {0x5799, 0xd5}, + {0x579a, 0x00}, + {0x579b, 0x50}, + {0x579c, 0x00}, + {0x579d, 0x2c}, + {0x579e, 0x0c}, + {0x579f, 0x40}, + {0x57a0, 0x09}, + {0x57a1, 0x40}, + {0x59f8, 0x3d}, + {0x5a08, 0x02}, + {0x5b00, 0x02}, + {0x5b01, 0x10}, + {0x5b02, 0x03}, + {0x5b03, 0xcf}, + {0x5b05, 0x6c}, + {0x5e00, 0x00}, + {0x5e10, 0xfc} +}; + +static const struct ov8856_reg lane_4_mode_1632x1224[] = { + /* 1632x1224 resolution */ + {0x0103, 0x01}, + {0x0302, 0x3c}, + {0x0303, 0x01}, + {0x031e, 0x0c}, + {0x3000, 0x20}, + {0x3003, 0x08}, + {0x300e, 0x20}, + {0x3010, 0x00}, + {0x3015, 0x84}, + {0x3018, 0x72}, + {0x3021, 0x23}, + {0x3033, 0x24}, + {0x3500, 0x00}, + {0x3501, 0x4c}, + {0x3502, 0xe0}, + {0x3503, 0x08}, + {0x3505, 0x83}, + {0x3508, 0x01}, + {0x3509, 0x80}, + {0x350c, 0x00}, + {0x350d, 0x80}, + {0x350e, 0x04}, + {0x350f, 0x00}, + {0x3510, 0x00}, + {0x3511, 0x02}, + {0x3512, 0x00}, + {0x3600, 0x72}, + {0x3601, 0x40}, + {0x3602, 0x30}, + {0x3610, 0xc5}, + {0x3611, 0x58}, + {0x3612, 0x5c}, + {0x3613, 0xca}, + {0x3614, 0x60}, + {0x3628, 0xff}, + {0x3629, 0xff}, + {0x362a, 0xff}, + {0x3633, 0x10}, + {0x3634, 0x10}, + {0x3635, 0x10}, + {0x3636, 0x10}, + {0x3663, 0x08}, + {0x3669, 0x34}, + {0x366d, 0x00}, + {0x366e, 0x08}, + {0x3706, 0x86}, + {0x370b, 0x7e}, + {0x3714, 0x27}, + {0x3730, 0x12}, + {0x3733, 0x10}, + {0x3764, 0x00}, + {0x3765, 0x00}, + {0x3769, 0x62}, + {0x376a, 0x2a}, + {0x376b, 0x30}, + {0x3780, 0x00}, + {0x3781, 0x24}, + {0x3782, 0x00}, + {0x3783, 0x23}, + {0x3798, 0x2f}, + {0x37a1, 0x60}, + {0x37a8, 0x6a}, + {0x37ab, 0x3f}, + {0x37c2, 0x14}, + {0x37c3, 0xf1}, + {0x37c9, 0x80}, + {0x37cb, 0x16}, + {0x37cc, 0x16}, + {0x37cd, 0x16}, + {0x37ce, 0x16}, + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0x0c}, + {0x3804, 0x0c}, + {0x3805, 0xdf}, + {0x3806, 0x09}, + {0x3807, 0xa3}, + {0x3808, 0x06}, + {0x3809, 0x60}, + {0x380a, 0x04}, + {0x380b, 0xc8}, + {0x380c, 0x07}, + {0x380d, 0x8c}, + {0x380e, 0x09}, + {0x380f, 0xb2}, + {0x3810, 0x00}, + {0x3811, 0x02}, + {0x3812, 0x00}, + {0x3813, 0x01}, + {0x3814, 0x03}, + {0x3815, 0x01}, + {0x3816, 0x00}, + {0x3817, 0x00}, + {0x3818, 0x00}, + {0x3819, 0x10}, + {0x3820, 0x80}, + {0x3821, 0x47}, + {0x382a, 0x03}, + {0x382b, 0x01}, + {0x3830, 0x06}, + {0x3836, 0x02}, + {0x3862, 0x04}, + {0x3863, 0x08}, + {0x3cc0, 0x33}, + {0x3d85, 0x17}, + {0x3d8c, 0x73}, + {0x3d8d, 0xde}, + {0x4001, 0xe0}, + {0x4003, 0x40}, + {0x4008, 0x00}, + {0x4009, 0x05}, + {0x400a, 0x00}, + {0x400b, 0x84}, + {0x400f, 0x80}, + {0x4010, 0xf0}, + {0x4011, 0xff}, + {0x4012, 0x02}, + {0x4013, 0x01}, + {0x4014, 0x01}, + {0x4015, 0x01}, + {0x4042, 0x00}, + {0x4043, 0x80}, + {0x4044, 0x00}, + {0x4045, 0x80}, + {0x4046, 0x00}, + {0x4047, 0x80}, + {0x4048, 0x00}, + {0x4049, 0x80}, + {0x4041, 0x03}, + {0x404c, 0x20}, + {0x404d, 0x00}, + {0x404e, 0x20}, + {0x4203, 0x80}, + {0x4307, 0x30}, + {0x4317, 0x00}, + {0x4502, 0x50}, + {0x4503, 0x08}, + {0x4601, 0x80}, + {0x4800, 0x44}, + {0x4816, 0x53}, + {0x481b, 0x50}, + {0x481f, 0x27}, + {0x4823, 0x3c}, + {0x482b, 0x00}, + {0x4831, 0x66}, + {0x4837, 0x16}, + {0x483c, 0x0f}, + {0x484b, 0x05}, + {0x5000, 0x77}, + {0x5001, 0x0a}, + {0x5003, 0xc8}, + {0x5004, 0x04}, + {0x5006, 0x00}, + {0x5007, 0x00}, + {0x502e, 0x03}, + {0x5030, 0x41}, + {0x5795, 0x00}, + {0x5796, 0x10}, + {0x5797, 0x10}, + {0x5798, 0x73}, + {0x5799, 0x73}, + {0x579a, 0x00}, + {0x579b, 0x28}, + {0x579c, 0x00}, + {0x579d, 0x16}, + {0x579e, 0x06}, + {0x579f, 0x20}, + {0x57a0, 0x04}, + {0x57a1, 0xa0}, + {0x5780, 0x14}, + {0x5781, 0x0f}, + {0x5782, 0x44}, + {0x5783, 0x02}, + {0x5784, 0x01}, + {0x5785, 0x01}, + {0x5786, 0x00}, + {0x5787, 0x04}, + {0x5788, 0x02}, + {0x5789, 0x0f}, + {0x578a, 0xfd}, + {0x578b, 0xf5}, + {0x578c, 0xf5}, + {0x578d, 0x03}, + {0x578e, 0x08}, + {0x578f, 0x0c}, + {0x5790, 0x08}, + {0x5791, 0x04}, + {0x5792, 0x00}, + {0x5793, 0x52}, + {0x5794, 0xa3}, + {0x59f8, 0x3d}, + {0x5a08, 0x02}, + {0x5b00, 0x02}, + {0x5b01, 0x10}, + {0x5b02, 0x03}, + {0x5b03, 0xcf}, + {0x5b05, 0x6c}, + {0x5e00, 0x00}, + {0x5e10, 0xfc} }; static const char * const ov8856_test_pattern_menu[] = { @@ -942,77 +1361,6 @@ static const char * const ov8856_test_pattern_menu[] = { "Bottom-Top Darker Color Bar" }; -static const s64 link_freq_menu_items[] = { - OV8856_LINK_FREQ_360MHZ, - OV8856_LINK_FREQ_180MHZ -}; - -static const struct ov8856_link_freq_config link_freq_configs[] = { - [OV8856_LINK_FREQ_720MBPS] = { - .reg_list = { - .num_of_regs = ARRAY_SIZE(mipi_data_rate_720mbps), - .regs = mipi_data_rate_720mbps, - } - }, - [OV8856_LINK_FREQ_360MBPS] = { - .reg_list = { - .num_of_regs = ARRAY_SIZE(mipi_data_rate_360mbps), - .regs = mipi_data_rate_360mbps, - } - } -}; - -static const struct ov8856_mode supported_modes[] = { - { - .width = 3280, - .height = 2464, - .hts = 1928, - .vts_def = 2488, - .vts_min = 2488, - .reg_list = { - .num_of_regs = ARRAY_SIZE(mode_3280x2464_regs), - .regs = mode_3280x2464_regs, - }, - .link_freq_index = OV8856_LINK_FREQ_720MBPS, - }, - { - .width = 3264, - .height = 2448, - .hts = 1932, - .vts_def = 2482, - .vts_min = 2482, - .reg_list = { - .num_of_regs = ARRAY_SIZE(mode_3264x2448_regs), - .regs = mode_3264x2448_regs, - }, - .link_freq_index = OV8856_LINK_FREQ_720MBPS, - }, - { - .width = 1640, - .height = 1232, - .hts = 3820, - .vts_def = 1256, - .vts_min = 1256, - .reg_list = { - .num_of_regs = ARRAY_SIZE(mode_1640x1232_regs), - .regs = mode_1640x1232_regs, - }, - .link_freq_index = OV8856_LINK_FREQ_360MBPS, - }, - { - .width = 1632, - .height = 1224, - .hts = 1932, - .vts_def = 2482, - .vts_min = 2482, - .reg_list = { - .num_of_regs = ARRAY_SIZE(mode_1632x1224_regs), - .regs = mode_1632x1224_regs, - }, - .link_freq_index = OV8856_LINK_FREQ_360MBPS, - } -}; - struct ov8856 { struct v4l2_subdev sd; struct media_pad pad; @@ -1037,20 +1385,173 @@ struct ov8856 { /* Streaming on/off */ bool streaming; + + /* lanes index */ + u8 nlanes; + + const struct ov8856_lane_cfg *priv_lane; + u8 modes_size; }; -static u64 to_pixel_rate(u32 f_index) +struct ov8856_lane_cfg { + const s64 link_freq_menu_items[2]; + const struct ov8856_link_freq_config link_freq_configs[2]; + const struct ov8856_mode supported_modes[4]; +}; + +static const struct ov8856_lane_cfg lane_cfg_2 = { + { + 720000000, + 360000000, + }, + {{ + .reg_list = { + .num_of_regs = + ARRAY_SIZE(mipi_data_rate_lane_2.regs_0), + .regs = mipi_data_rate_lane_2.regs_0, + } + }, + { + .reg_list = { + .num_of_regs = + ARRAY_SIZE(mipi_data_rate_lane_2.regs_1), + .regs = mipi_data_rate_lane_2.regs_1, + } + }}, + {{ + .width = 3280, + .height = 2464, + .hts = 1928, + .vts_def = 2488, + .vts_min = 2488, + .reg_list = { + .num_of_regs = + ARRAY_SIZE(lane_2_mode_3280x2464), + .regs = lane_2_mode_3280x2464, + }, + .link_freq_index = 0, + .data_lanes = 2, + }, + { + .width = 1640, + .height = 1232, + .hts = 3168, + .vts_def = 1514, + .vts_min = 1514, + .reg_list = { + .num_of_regs = + ARRAY_SIZE(lane_2_mode_1640x1232), + .regs = lane_2_mode_1640x1232, + }, + .link_freq_index = 1, + .data_lanes = 2, + }} +}; + +static const struct ov8856_lane_cfg lane_cfg_4 = { + { + 360000000, + 180000000, + }, + {{ + .reg_list = { + .num_of_regs = + ARRAY_SIZE(mipi_data_rate_lane_4.regs_0), + .regs = mipi_data_rate_lane_4.regs_0, + } + }, + { + .reg_list = { + .num_of_regs = + ARRAY_SIZE(mipi_data_rate_lane_4.regs_1), + .regs = mipi_data_rate_lane_4.regs_1, + } + }}, + {{ + .width = 3280, + .height = 2464, + .hts = 1928, + .vts_def = 2488, + .vts_min = 2488, + .reg_list = { + .num_of_regs = + ARRAY_SIZE(lane_4_mode_3280x2464), + .regs = lane_4_mode_3280x2464, + }, + .link_freq_index = 0, + .data_lanes = 4, + }, + { + .width = 1640, + .height = 1232, + .hts = 3820, + .vts_def = 1256, + .vts_min = 1256, + .reg_list = { + .num_of_regs = + ARRAY_SIZE(lane_4_mode_1640x1232), + .regs = lane_4_mode_1640x1232, + }, + .link_freq_index = 1, + .data_lanes = 4, + }, + { + .width = 3264, + .height = 2448, + .hts = 1932, + .vts_def = 2482, + .vts_min = 2482, + .reg_list = { + .num_of_regs = + ARRAY_SIZE(lane_4_mode_3264x2448), + .regs = lane_4_mode_3264x2448, + }, + .link_freq_index = 0, + .data_lanes = 4, + }, + { + .width = 1632, + .height = 1224, + .hts = 1932, + .vts_def = 2482, + .vts_min = 2482, + .reg_list = { + .num_of_regs = + ARRAY_SIZE(lane_4_mode_1632x1224), + .regs = lane_4_mode_1632x1224, + }, + .link_freq_index = 1, + .data_lanes = 4, + }} +}; + +static unsigned int ov8856_modes_num(const struct ov8856 *ov8856) { - u64 pixel_rate = link_freq_menu_items[f_index] * 2 * OV8856_DATA_LANES; + unsigned int i, count = 0; + + for (i = 0; i < ARRAY_SIZE(ov8856->priv_lane->supported_modes); i++) { + if (ov8856->priv_lane->supported_modes[i].width == 0) + break; + count++; + } + + return count; +} + +static u64 to_rate(const s64 *link_freq_menu_items, + u32 f_index, u8 nlanes) +{ + u64 pixel_rate = link_freq_menu_items[f_index] * 2 * nlanes; do_div(pixel_rate, OV8856_RGB_DEPTH); return pixel_rate; } -static u64 to_pixels_per_line(u32 hts, u32 f_index) +static u64 to_pixels_per_line(const s64 *link_freq_menu_items, u32 hts, + u32 f_index, u8 nlanes) { - u64 ppl = hts * to_pixel_rate(f_index); + u64 ppl = hts * to_rate(link_freq_menu_items, f_index, nlanes); do_div(ppl, OV8856_SCLK); @@ -1229,23 +1730,32 @@ static int ov8856_init_controls(struct ov8856 *ov8856) ctrl_hdlr->lock = &ov8856->mutex; ov8856->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &ov8856_ctrl_ops, V4L2_CID_LINK_FREQ, - ARRAY_SIZE(link_freq_menu_items) - 1, - 0, link_freq_menu_items); + ARRAY_SIZE + (ov8856->priv_lane->link_freq_menu_items) + - 1, + 0, ov8856->priv_lane->link_freq_menu_items); if (ov8856->link_freq) ov8856->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; ov8856->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &ov8856_ctrl_ops, V4L2_CID_PIXEL_RATE, 0, - to_pixel_rate(OV8856_LINK_FREQ_720MBPS), - 1, - to_pixel_rate(OV8856_LINK_FREQ_720MBPS)); + to_rate(ov8856->priv_lane->link_freq_menu_items, + 0, + ov8856->cur_mode->data_lanes), 1, + to_rate(ov8856->priv_lane->link_freq_menu_items, + 0, + ov8856->cur_mode->data_lanes)); ov8856->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov8856_ctrl_ops, V4L2_CID_VBLANK, ov8856->cur_mode->vts_min - ov8856->cur_mode->height, OV8856_VTS_MAX - ov8856->cur_mode->height, 1, - ov8856->cur_mode->vts_def - ov8856->cur_mode->height); - h_blank = to_pixels_per_line(ov8856->cur_mode->hts, - ov8856->cur_mode->link_freq_index) - ov8856->cur_mode->width; + ov8856->cur_mode->vts_def - + ov8856->cur_mode->height); + h_blank = to_pixels_per_line(ov8856->priv_lane->link_freq_menu_items, + ov8856->cur_mode->hts, + ov8856->cur_mode->link_freq_index, + ov8856->cur_mode->data_lanes) - + ov8856->cur_mode->width; ov8856->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov8856_ctrl_ops, V4L2_CID_HBLANK, h_blank, h_blank, 1, h_blank); @@ -1292,7 +1802,8 @@ static int ov8856_start_streaming(struct ov8856 *ov8856) int link_freq_index, ret; link_freq_index = ov8856->cur_mode->link_freq_index; - reg_list = &link_freq_configs[link_freq_index].reg_list; + reg_list = &ov8856->priv_lane->link_freq_configs[link_freq_index].reg_list; + ret = ov8856_write_reg_list(ov8856, reg_list); if (ret) { dev_err(&client->dev, "failed to set plls"); @@ -1461,9 +1972,9 @@ static int ov8856_set_format(struct v4l2_subdev *sd, const struct ov8856_mode *mode; s32 vblank_def, h_blank; - mode = v4l2_find_nearest_size(supported_modes, - ARRAY_SIZE(supported_modes), width, - height, fmt->format.width, + mode = v4l2_find_nearest_size(ov8856->priv_lane->supported_modes, + ov8856->modes_size, + width, height, fmt->format.width, fmt->format.height); mutex_lock(&ov8856->mutex); @@ -1474,7 +1985,9 @@ static int ov8856_set_format(struct v4l2_subdev *sd, ov8856->cur_mode = mode; __v4l2_ctrl_s_ctrl(ov8856->link_freq, mode->link_freq_index); __v4l2_ctrl_s_ctrl_int64(ov8856->pixel_rate, - to_pixel_rate(mode->link_freq_index)); + to_rate(ov8856->priv_lane->link_freq_menu_items, + mode->link_freq_index, + ov8856->cur_mode->data_lanes)); /* Update limits and set FPS to default */ vblank_def = mode->vts_def - mode->height; @@ -1483,8 +1996,11 @@ static int ov8856_set_format(struct v4l2_subdev *sd, OV8856_VTS_MAX - mode->height, 1, vblank_def); __v4l2_ctrl_s_ctrl(ov8856->vblank, vblank_def); - h_blank = to_pixels_per_line(mode->hts, mode->link_freq_index) - - mode->width; + h_blank = to_pixels_per_line(ov8856->priv_lane->link_freq_menu_items, + mode->hts, + mode->link_freq_index, + ov8856->cur_mode->data_lanes) + - mode->width; __v4l2_ctrl_modify_range(ov8856->hblank, h_blank, h_blank, 1, h_blank); } @@ -1529,15 +2045,17 @@ static int ov8856_enum_frame_size(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_frame_size_enum *fse) { - if (fse->index >= ARRAY_SIZE(supported_modes)) + struct ov8856 *ov8856 = to_ov8856(sd); + + if (fse->index >= ov8856->modes_size) return -EINVAL; if (fse->code != MEDIA_BUS_FMT_SGRBG10_1X10) return -EINVAL; - fse->min_width = supported_modes[fse->index].width; + fse->min_width = ov8856->priv_lane->supported_modes[fse->index].width; fse->max_width = fse->min_width; - fse->min_height = supported_modes[fse->index].height; + fse->min_height = ov8856->priv_lane->supported_modes[fse->index].height; fse->max_height = fse->min_height; return 0; @@ -1548,7 +2066,7 @@ static int ov8856_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) struct ov8856 *ov8856 = to_ov8856(sd); mutex_lock(&ov8856->mutex); - ov8856_update_pad_format(&supported_modes[0], + ov8856_update_pad_format(&ov8856->priv_lane->supported_modes[0], v4l2_subdev_get_try_format(sd, fh->pad, 0)); mutex_unlock(&ov8856->mutex); @@ -1695,29 +2213,40 @@ static int ov8856_get_hwcfg(struct ov8856 *ov8856, struct device *dev) if (ret) return ret; - if (bus_cfg.bus.mipi_csi2.num_data_lanes != OV8856_DATA_LANES) { + /* Get number of data lanes */ + if (bus_cfg.bus.mipi_csi2.num_data_lanes != 2 && + bus_cfg.bus.mipi_csi2.num_data_lanes != 4) { dev_err(dev, "number of CSI2 data lanes %d is not supported", bus_cfg.bus.mipi_csi2.num_data_lanes); ret = -EINVAL; goto check_hwcfg_error; } + dev_dbg(dev, "Using %u data lanes\n", ov8856->cur_mode->data_lanes); + + if (bus_cfg.bus.mipi_csi2.num_data_lanes == 2) + ov8856->priv_lane = &lane_cfg_2; + else + ov8856->priv_lane = &lane_cfg_4; + + ov8856->modes_size = ov8856_modes_num(ov8856); + if (!bus_cfg.nr_of_link_frequencies) { dev_err(dev, "no link frequencies defined"); ret = -EINVAL; goto check_hwcfg_error; } - for (i = 0; i < ARRAY_SIZE(link_freq_menu_items); i++) { + for (i = 0; i < ARRAY_SIZE(ov8856->priv_lane->link_freq_menu_items); i++) { for (j = 0; j < bus_cfg.nr_of_link_frequencies; j++) { - if (link_freq_menu_items[i] == - bus_cfg.link_frequencies[j]) + if (ov8856->priv_lane->link_freq_menu_items[i] == + bus_cfg.link_frequencies[j]) break; } if (j == bus_cfg.nr_of_link_frequencies) { dev_err(dev, "no link frequency %lld supported", - link_freq_menu_items[i]); + ov8856->priv_lane->link_freq_menu_items[i]); ret = -EINVAL; goto check_hwcfg_error; } @@ -1776,7 +2305,7 @@ static int ov8856_probe(struct i2c_client *client) } mutex_init(&ov8856->mutex); - ov8856->cur_mode = &supported_modes[0]; + ov8856->cur_mode = &ov8856->priv_lane->supported_modes[0]; ret = ov8856_init_controls(ov8856); if (ret) { dev_err(&client->dev, "failed to init controls: %d", ret); From c19b93a69c8ea6d672b786d1e130e9b4260b4e71 Mon Sep 17 00:00:00 2001 From: Shawn Tu Date: Fri, 16 Apr 2021 11:58:59 +0200 Subject: [PATCH 195/394] media: ov8856: add vflip/hflip control support Add V4L2 controls: horizontal/vertical flip, keep SGRBG10 Bayer order output (via change v/hflip) Signed-off-by: Shawn Tu Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov8856.c | 118 +++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/drivers/media/i2c/ov8856.c b/drivers/media/i2c/ov8856.c index d145f004fd8d..a6bc665a6430 100644 --- a/drivers/media/i2c/ov8856.c +++ b/drivers/media/i2c/ov8856.c @@ -80,6 +80,25 @@ #define NUM_MODE_REGS 187 #define NUM_MODE_REGS_2 200 +/* Flip Mirror Controls from sensor */ +#define OV8856_REG_FORMAT1 0x3820 +#define OV8856_REG_FORMAT2 0x3821 +#define OV8856_REG_FORMAT1_OP_1 BIT(1) +#define OV8856_REG_FORMAT1_OP_2 BIT(2) +#define OV8856_REG_FORMAT1_OP_3 BIT(6) +#define OV8856_REG_FORMAT2_OP_1 BIT(1) +#define OV8856_REG_FORMAT2_OP_2 BIT(2) +#define OV8856_REG_FORMAT2_OP_3 BIT(6) +#define OV8856_REG_FLIP_OPT_1 0x376b +#define OV8856_REG_FLIP_OPT_2 0x5001 +#define OV8856_REG_FLIP_OPT_3 0x502e +#define OV8856_REG_MIRROR_OPT_1 0x5004 +#define OV8856_REG_FLIP_OP_0 BIT(0) +#define OV8856_REG_FLIP_OP_1 BIT(1) +#define OV8856_REG_FLIP_OP_2 BIT(2) +#define OV8856_REG_MIRROR_OP_1 BIT(1) +#define OV8856_REG_MIRROR_OP_2 BIT(2) + #define to_ov8856(_sd) container_of(_sd, struct ov8856, sd) static const char * const ov8856_supply_names[] = { @@ -1653,6 +1672,93 @@ static int ov8856_test_pattern(struct ov8856 *ov8856, u32 pattern) OV8856_REG_VALUE_08BIT, pattern); } +static int ov8856_set_ctrl_hflip(struct ov8856 *ov8856, u32 ctrl_val) +{ + int ret; + u32 val; + + ret = ov8856_read_reg(ov8856, OV8856_REG_MIRROR_OPT_1, + OV8856_REG_VALUE_08BIT, &val); + if (ret) + return ret; + + ret = ov8856_write_reg(ov8856, OV8856_REG_MIRROR_OPT_1, + OV8856_REG_VALUE_08BIT, + ctrl_val ? val & ~OV8856_REG_MIRROR_OP_2 : + val | OV8856_REG_MIRROR_OP_2); + + if (ret) + return ret; + + ret = ov8856_read_reg(ov8856, OV8856_REG_FORMAT2, + OV8856_REG_VALUE_08BIT, &val); + if (ret) + return ret; + + return ov8856_write_reg(ov8856, OV8856_REG_FORMAT2, + OV8856_REG_VALUE_08BIT, + ctrl_val ? val & ~OV8856_REG_FORMAT2_OP_1 & + ~OV8856_REG_FORMAT2_OP_2 & + ~OV8856_REG_FORMAT2_OP_3 : + val | OV8856_REG_FORMAT2_OP_1 | + OV8856_REG_FORMAT2_OP_2 | + OV8856_REG_FORMAT2_OP_3); +} + +static int ov8856_set_ctrl_vflip(struct ov8856 *ov8856, u8 ctrl_val) +{ + int ret; + u32 val; + + ret = ov8856_read_reg(ov8856, OV8856_REG_FLIP_OPT_1, + OV8856_REG_VALUE_08BIT, &val); + if (ret) + return ret; + + ret = ov8856_write_reg(ov8856, OV8856_REG_FLIP_OPT_1, + OV8856_REG_VALUE_08BIT, + ctrl_val ? val | OV8856_REG_FLIP_OP_1 | + OV8856_REG_FLIP_OP_2 : + val & ~OV8856_REG_FLIP_OP_1 & + ~OV8856_REG_FLIP_OP_2); + + ret = ov8856_read_reg(ov8856, OV8856_REG_FLIP_OPT_2, + OV8856_REG_VALUE_08BIT, &val); + if (ret) + return ret; + + ret = ov8856_write_reg(ov8856, OV8856_REG_FLIP_OPT_2, + OV8856_REG_VALUE_08BIT, + ctrl_val ? val | OV8856_REG_FLIP_OP_2 : + val & ~OV8856_REG_FLIP_OP_2); + + ret = ov8856_read_reg(ov8856, OV8856_REG_FLIP_OPT_3, + OV8856_REG_VALUE_08BIT, &val); + if (ret) + return ret; + + ret = ov8856_write_reg(ov8856, OV8856_REG_FLIP_OPT_3, + OV8856_REG_VALUE_08BIT, + ctrl_val ? val & ~OV8856_REG_FLIP_OP_0 & + ~OV8856_REG_FLIP_OP_1 : + val | OV8856_REG_FLIP_OP_0 | + OV8856_REG_FLIP_OP_1); + + ret = ov8856_read_reg(ov8856, OV8856_REG_FORMAT1, + OV8856_REG_VALUE_08BIT, &val); + if (ret) + return ret; + + return ov8856_write_reg(ov8856, OV8856_REG_FORMAT1, + OV8856_REG_VALUE_08BIT, + ctrl_val ? val | OV8856_REG_FORMAT1_OP_1 | + OV8856_REG_FORMAT1_OP_3 | + OV8856_REG_FORMAT1_OP_2 : + val & ~OV8856_REG_FORMAT1_OP_1 & + ~OV8856_REG_FORMAT1_OP_3 & + ~OV8856_REG_FORMAT1_OP_2); +} + static int ov8856_set_ctrl(struct v4l2_ctrl *ctrl) { struct ov8856 *ov8856 = container_of(ctrl->handler, @@ -1702,6 +1808,14 @@ static int ov8856_set_ctrl(struct v4l2_ctrl *ctrl) ret = ov8856_test_pattern(ov8856, ctrl->val); break; + case V4L2_CID_HFLIP: + ret = ov8856_set_ctrl_hflip(ov8856, ctrl->val); + break; + + case V4L2_CID_VFLIP: + ret = ov8856_set_ctrl_vflip(ov8856, ctrl->val); + break; + default: ret = -EINVAL; break; @@ -1778,6 +1892,10 @@ static int ov8856_init_controls(struct ov8856 *ov8856) V4L2_CID_TEST_PATTERN, ARRAY_SIZE(ov8856_test_pattern_menu) - 1, 0, 0, ov8856_test_pattern_menu); + v4l2_ctrl_new_std(ctrl_hdlr, &ov8856_ctrl_ops, + V4L2_CID_HFLIP, 0, 1, 1, 0); + v4l2_ctrl_new_std(ctrl_hdlr, &ov8856_ctrl_ops, + V4L2_CID_VFLIP, 0, 1, 1, 0); if (ctrl_hdlr->error) return ctrl_hdlr->error; From cef944c8f5ae192636f53682797d62bd61859646 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Thu, 29 Apr 2021 22:59:19 +0200 Subject: [PATCH 196/394] media: staging: ipu3-imgu: Document pages field The pages field in struct imgu_css_map was missing. Document it. Reported-by: Hans Verkuil Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/ipu3/ipu3-css-pool.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/media/ipu3/ipu3-css-pool.h b/drivers/staging/media/ipu3/ipu3-css-pool.h index 35519a08c08c..3f9e32e0e9a7 100644 --- a/drivers/staging/media/ipu3/ipu3-css-pool.h +++ b/drivers/staging/media/ipu3/ipu3-css-pool.h @@ -15,6 +15,7 @@ struct imgu_device; * @size: size of the buffer in bytes. * @vaddr: kernel virtual address. * @daddr: iova dma address to access IPU3. + * @pages: pages mapped to this buffer */ struct imgu_css_map { size_t size; From 45dbd70c35d6a5fec4b7b45cde75b1341ede52a2 Mon Sep 17 00:00:00 2001 From: Paul Kocialkowski Date: Mon, 12 Apr 2021 09:48:31 +0200 Subject: [PATCH 197/394] media: i2c: ov8865: remove unnecessary NULL check The check on mode_index is sufficient to ensure that we have a valid mode. Remove the explicit mode check similarly to commit 38a50230292f ("media: i2c: ov5648: remove unnecessary NULL check") Signed-off-by: Paul Kocialkowski Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov8865.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c index 3bf6ee4898a9..b16c82559800 100644 --- a/drivers/media/i2c/ov8865.c +++ b/drivers/media/i2c/ov8865.c @@ -2689,7 +2689,7 @@ static int ov8865_enum_frame_interval(struct v4l2_subdev *subdev, } } - if (mode_index == ARRAY_SIZE(ov8865_modes) || !mode) + if (mode_index == ARRAY_SIZE(ov8865_modes)) return -EINVAL; interval_enum->interval = mode->frame_interval; From d953e3cb4adf66322862d459451435a2eb1b7770 Mon Sep 17 00:00:00 2001 From: Shawn Tu Date: Fri, 30 Apr 2021 16:05:49 +0200 Subject: [PATCH 198/394] media: imx208: Add imx208 camera sensor driver Add a V4L2 sub-device driver for the Sony IMX208 image sensor. This is a camera sensor using the I2C bus for control and the CSI-2 bus for data. [Sakari Ailus: Rename sensor async register function to make it compile, use exposure_max and wrap a few long lines.] Signed-off-by: Ping-Chung Chen Signed-off-by: Yeh, Andy Signed-off-by: Shawn Tu Reviewed-by: Tomasz Figa Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- MAINTAINERS | 7 + drivers/media/i2c/Kconfig | 11 + drivers/media/i2c/Makefile | 1 + drivers/media/i2c/imx208.c | 1087 ++++++++++++++++++++++++++++++++++++ 4 files changed, 1106 insertions(+) create mode 100644 drivers/media/i2c/imx208.c diff --git a/MAINTAINERS b/MAINTAINERS index 768f4ba6b349..0fee01ceb151 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -17002,6 +17002,13 @@ S: Maintained F: drivers/ssb/ F: include/linux/ssb/ +SONY IMX208 SENSOR DRIVER +M: Sakari Ailus +L: linux-media@vger.kernel.org +S: Maintained +T: git git://linuxtv.org/media_tree.git +F: drivers/media/i2c/imx208.c + SONY IMX214 SENSOR DRIVER M: Ricardo Ribalda L: linux-media@vger.kernel.org diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 4f1dafc64816..588f8eb95984 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -742,6 +742,17 @@ config VIDEO_HI556 To compile this driver as a module, choose M here: the module will be called hi556. +config VIDEO_IMX208 + tristate "Sony IMX208 sensor support" + depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API + depends on MEDIA_CAMERA_SUPPORT + help + This is a Video4Linux2 sensor driver for the Sony + IMX208 camera. + + To compile this driver as a module, choose M here: the + module will be called imx208. + config VIDEO_IMX214 tristate "Sony IMX214 sensor support" depends on GPIOLIB && I2C && VIDEO_V4L2 diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index 0c067beca066..1168fa6b84ed 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -116,6 +116,7 @@ obj-$(CONFIG_VIDEO_ML86V7667) += ml86v7667.o obj-$(CONFIG_VIDEO_OV2659) += ov2659.o obj-$(CONFIG_VIDEO_TC358743) += tc358743.o obj-$(CONFIG_VIDEO_HI556) += hi556.o +obj-$(CONFIG_VIDEO_IMX208) += imx208.o obj-$(CONFIG_VIDEO_IMX214) += imx214.o obj-$(CONFIG_VIDEO_IMX219) += imx219.o obj-$(CONFIG_VIDEO_IMX258) += imx258.o diff --git a/drivers/media/i2c/imx208.c b/drivers/media/i2c/imx208.c new file mode 100644 index 000000000000..9ed261ea7255 --- /dev/null +++ b/drivers/media/i2c/imx208.c @@ -0,0 +1,1087 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2021 Intel Corporation + +#include +#include +#include +#include +#include +#include +#include +#include + +#define IMX208_REG_MODE_SELECT 0x0100 +#define IMX208_MODE_STANDBY 0x00 +#define IMX208_MODE_STREAMING 0x01 + +/* Chip ID */ +#define IMX208_REG_CHIP_ID 0x0000 +#define IMX208_CHIP_ID 0x0208 + +/* V_TIMING internal */ +#define IMX208_REG_VTS 0x0340 +#define IMX208_VTS_60FPS 0x0472 +#define IMX208_VTS_BINNING 0x0239 +#define IMX208_VTS_60FPS_MIN 0x0458 +#define IMX208_VTS_BINNING_MIN 0x0230 +#define IMX208_VTS_MAX 0xffff + +/* HBLANK control - read only */ +#define IMX208_PPL_384MHZ 2248 +#define IMX208_PPL_96MHZ 2248 + +/* Exposure control */ +#define IMX208_REG_EXPOSURE 0x0202 +#define IMX208_EXPOSURE_MIN 4 +#define IMX208_EXPOSURE_STEP 1 +#define IMX208_EXPOSURE_DEFAULT 0x190 +#define IMX208_EXPOSURE_MAX 65535 + +/* Analog gain control */ +#define IMX208_REG_ANALOG_GAIN 0x0204 +#define IMX208_ANA_GAIN_MIN 0 +#define IMX208_ANA_GAIN_MAX 0x00e0 +#define IMX208_ANA_GAIN_STEP 1 +#define IMX208_ANA_GAIN_DEFAULT 0x0 + +/* Digital gain control */ +#define IMX208_REG_GR_DIGITAL_GAIN 0x020e +#define IMX208_REG_R_DIGITAL_GAIN 0x0210 +#define IMX208_REG_B_DIGITAL_GAIN 0x0212 +#define IMX208_REG_GB_DIGITAL_GAIN 0x0214 +#define IMX208_DIGITAL_GAIN_SHIFT 8 + +/* Orientation */ +#define IMX208_REG_ORIENTATION_CONTROL 0x0101 + +/* Test Pattern Control */ +#define IMX208_REG_TEST_PATTERN_MODE 0x0600 +#define IMX208_TEST_PATTERN_DISABLE 0x0 +#define IMX208_TEST_PATTERN_SOLID_COLOR 0x1 +#define IMX208_TEST_PATTERN_COLOR_BARS 0x2 +#define IMX208_TEST_PATTERN_GREY_COLOR 0x3 +#define IMX208_TEST_PATTERN_PN9 0x4 +#define IMX208_TEST_PATTERN_FIX_1 0x100 +#define IMX208_TEST_PATTERN_FIX_2 0x101 +#define IMX208_TEST_PATTERN_FIX_3 0x102 +#define IMX208_TEST_PATTERN_FIX_4 0x103 +#define IMX208_TEST_PATTERN_FIX_5 0x104 +#define IMX208_TEST_PATTERN_FIX_6 0x105 + +/* OTP Access */ +#define IMX208_OTP_BASE 0x3500 +#define IMX208_OTP_SIZE 40 + +struct imx208_reg { + u16 address; + u8 val; +}; + +struct imx208_reg_list { + u32 num_of_regs; + const struct imx208_reg *regs; +}; + +/* Link frequency config */ +struct imx208_link_freq_config { + u32 pixels_per_line; + + /* PLL registers for this link frequency */ + struct imx208_reg_list reg_list; +}; + +/* Mode : resolution and related config&values */ +struct imx208_mode { + /* Frame width */ + u32 width; + /* Frame height */ + u32 height; + + /* V-timing */ + u32 vts_def; + u32 vts_min; + + /* Index of Link frequency config to be used */ + u32 link_freq_index; + /* Default register values */ + struct imx208_reg_list reg_list; +}; + +static const struct imx208_reg pll_ctrl_reg[] = { + {0x0305, 0x02}, + {0x0307, 0x50}, + {0x303C, 0x3C}, +}; + +static const struct imx208_reg mode_1936x1096_60fps_regs[] = { + {0x0340, 0x04}, + {0x0341, 0x72}, + {0x0342, 0x04}, + {0x0343, 0x64}, + {0x034C, 0x07}, + {0x034D, 0x90}, + {0x034E, 0x04}, + {0x034F, 0x48}, + {0x0381, 0x01}, + {0x0383, 0x01}, + {0x0385, 0x01}, + {0x0387, 0x01}, + {0x3048, 0x00}, + {0x3050, 0x01}, + {0x30D5, 0x00}, + {0x3301, 0x00}, + {0x3318, 0x62}, + {0x0202, 0x01}, + {0x0203, 0x90}, + {0x0205, 0x00}, +}; + +static const struct imx208_reg mode_968_548_60fps_regs[] = { + {0x0340, 0x02}, + {0x0341, 0x39}, + {0x0342, 0x08}, + {0x0343, 0xC8}, + {0x034C, 0x03}, + {0x034D, 0xC8}, + {0x034E, 0x02}, + {0x034F, 0x24}, + {0x0381, 0x01}, + {0x0383, 0x03}, + {0x0385, 0x01}, + {0x0387, 0x03}, + {0x3048, 0x01}, + {0x3050, 0x02}, + {0x30D5, 0x03}, + {0x3301, 0x10}, + {0x3318, 0x75}, + {0x0202, 0x01}, + {0x0203, 0x90}, + {0x0205, 0x00}, +}; + +static const s64 imx208_discrete_digital_gain[] = { + 1, 2, 4, 8, 16, +}; + +static const char * const imx208_test_pattern_menu[] = { + "Disabled", + "Solid Color", + "100% Color Bar", + "Fade to Grey Color Bar", + "PN9", + "Fixed Pattern1", + "Fixed Pattern2", + "Fixed Pattern3", + "Fixed Pattern4", + "Fixed Pattern5", + "Fixed Pattern6" +}; + +static const int imx208_test_pattern_val[] = { + IMX208_TEST_PATTERN_DISABLE, + IMX208_TEST_PATTERN_SOLID_COLOR, + IMX208_TEST_PATTERN_COLOR_BARS, + IMX208_TEST_PATTERN_GREY_COLOR, + IMX208_TEST_PATTERN_PN9, + IMX208_TEST_PATTERN_FIX_1, + IMX208_TEST_PATTERN_FIX_2, + IMX208_TEST_PATTERN_FIX_3, + IMX208_TEST_PATTERN_FIX_4, + IMX208_TEST_PATTERN_FIX_5, + IMX208_TEST_PATTERN_FIX_6, +}; + +/* Configurations for supported link frequencies */ +#define IMX208_MHZ (1000 * 1000ULL) +#define IMX208_LINK_FREQ_384MHZ (384ULL * IMX208_MHZ) +#define IMX208_LINK_FREQ_96MHZ (96ULL * IMX208_MHZ) + +#define IMX208_DATA_RATE_DOUBLE 2 +#define IMX208_NUM_OF_LANES 2 +#define IMX208_PIXEL_BITS 10 + +enum { + IMX208_LINK_FREQ_384MHZ_INDEX, + IMX208_LINK_FREQ_96MHZ_INDEX, +}; + +/* + * pixel_rate = link_freq * data-rate * nr_of_lanes / bits_per_sample + * data rate => double data rate; number of lanes => 2; bits per pixel => 10 + */ +static u64 link_freq_to_pixel_rate(u64 f) +{ + f *= IMX208_DATA_RATE_DOUBLE * IMX208_NUM_OF_LANES; + do_div(f, IMX208_PIXEL_BITS); + + return f; +} + +/* Menu items for LINK_FREQ V4L2 control */ +static const s64 link_freq_menu_items[] = { + [IMX208_LINK_FREQ_384MHZ_INDEX] = IMX208_LINK_FREQ_384MHZ, + [IMX208_LINK_FREQ_96MHZ_INDEX] = IMX208_LINK_FREQ_96MHZ, +}; + +/* Link frequency configs */ +static const struct imx208_link_freq_config link_freq_configs[] = { + [IMX208_LINK_FREQ_384MHZ_INDEX] = { + .pixels_per_line = IMX208_PPL_384MHZ, + .reg_list = { + .num_of_regs = ARRAY_SIZE(pll_ctrl_reg), + .regs = pll_ctrl_reg, + } + }, + [IMX208_LINK_FREQ_96MHZ_INDEX] = { + .pixels_per_line = IMX208_PPL_96MHZ, + .reg_list = { + .num_of_regs = ARRAY_SIZE(pll_ctrl_reg), + .regs = pll_ctrl_reg, + } + }, +}; + +/* Mode configs */ +static const struct imx208_mode supported_modes[] = { + { + .width = 1936, + .height = 1096, + .vts_def = IMX208_VTS_60FPS, + .vts_min = IMX208_VTS_60FPS_MIN, + .reg_list = { + .num_of_regs = ARRAY_SIZE(mode_1936x1096_60fps_regs), + .regs = mode_1936x1096_60fps_regs, + }, + .link_freq_index = IMX208_LINK_FREQ_384MHZ_INDEX, + }, + { + .width = 968, + .height = 548, + .vts_def = IMX208_VTS_BINNING, + .vts_min = IMX208_VTS_BINNING_MIN, + .reg_list = { + .num_of_regs = ARRAY_SIZE(mode_968_548_60fps_regs), + .regs = mode_968_548_60fps_regs, + }, + .link_freq_index = IMX208_LINK_FREQ_96MHZ_INDEX, + }, +}; + +struct imx208 { + struct v4l2_subdev sd; + struct media_pad pad; + + struct v4l2_ctrl_handler ctrl_handler; + /* V4L2 Controls */ + struct v4l2_ctrl *link_freq; + struct v4l2_ctrl *pixel_rate; + struct v4l2_ctrl *vblank; + struct v4l2_ctrl *hblank; + struct v4l2_ctrl *vflip; + struct v4l2_ctrl *hflip; + + /* Current mode */ + const struct imx208_mode *cur_mode; + + /* + * Mutex for serialized access: + * Protect sensor set pad format and start/stop streaming safely. + * Protect access to sensor v4l2 controls. + */ + struct mutex imx208_mx; + + /* Streaming on/off */ + bool streaming; + + /* OTP data */ + bool otp_read; + char otp_data[IMX208_OTP_SIZE]; +}; + +static inline struct imx208 *to_imx208(struct v4l2_subdev *_sd) +{ + return container_of(_sd, struct imx208, sd); +} + +/* Get bayer order based on flip setting. */ +static u32 imx208_get_format_code(struct imx208 *imx208) +{ + /* + * Only one bayer order is supported. + * It depends on the flip settings. + */ + static const u32 codes[2][2] = { + { MEDIA_BUS_FMT_SRGGB10_1X10, MEDIA_BUS_FMT_SGRBG10_1X10, }, + { MEDIA_BUS_FMT_SGBRG10_1X10, MEDIA_BUS_FMT_SBGGR10_1X10, }, + }; + + return codes[imx208->vflip->val][imx208->hflip->val]; +} + +/* Read registers up to 4 at a time */ +static int imx208_read_reg(struct imx208 *imx208, u16 reg, u32 len, u32 *val) +{ + struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd); + struct i2c_msg msgs[2]; + u8 addr_buf[2] = { reg >> 8, reg & 0xff }; + u8 data_buf[4] = { 0, }; + int ret; + + if (len > 4) + return -EINVAL; + + /* Write register address */ + msgs[0].addr = client->addr; + msgs[0].flags = 0; + msgs[0].len = ARRAY_SIZE(addr_buf); + msgs[0].buf = addr_buf; + + /* Read data from register */ + msgs[1].addr = client->addr; + msgs[1].flags = I2C_M_RD; + msgs[1].len = len; + msgs[1].buf = &data_buf[4 - len]; + + ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); + if (ret != ARRAY_SIZE(msgs)) + return -EIO; + + *val = get_unaligned_be32(data_buf); + + return 0; +} + +/* Write registers up to 4 at a time */ +static int imx208_write_reg(struct imx208 *imx208, u16 reg, u32 len, u32 val) +{ + struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd); + u8 buf[6]; + + if (len > 4) + return -EINVAL; + + put_unaligned_be16(reg, buf); + put_unaligned_be32(val << (8 * (4 - len)), buf + 2); + if (i2c_master_send(client, buf, len + 2) != len + 2) + return -EIO; + + return 0; +} + +/* Write a list of registers */ +static int imx208_write_regs(struct imx208 *imx208, + const struct imx208_reg *regs, u32 len) +{ + struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd); + unsigned int i; + int ret; + + for (i = 0; i < len; i++) { + ret = imx208_write_reg(imx208, regs[i].address, 1, + regs[i].val); + if (ret) { + dev_err_ratelimited(&client->dev, + "Failed to write reg 0x%4.4x. error = %d\n", + regs[i].address, ret); + + return ret; + } + } + + return 0; +} + +/* Open sub-device */ +static int imx208_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) +{ + struct v4l2_mbus_framefmt *try_fmt = + v4l2_subdev_get_try_format(sd, fh->pad, 0); + + /* Initialize try_fmt */ + try_fmt->width = supported_modes[0].width; + try_fmt->height = supported_modes[0].height; + try_fmt->code = MEDIA_BUS_FMT_SRGGB10_1X10; + try_fmt->field = V4L2_FIELD_NONE; + + return 0; +} + +static int imx208_update_digital_gain(struct imx208 *imx208, u32 len, u32 val) +{ + int ret; + + val = imx208_discrete_digital_gain[val] << IMX208_DIGITAL_GAIN_SHIFT; + + ret = imx208_write_reg(imx208, IMX208_REG_GR_DIGITAL_GAIN, 2, val); + if (ret) + return ret; + + ret = imx208_write_reg(imx208, IMX208_REG_GB_DIGITAL_GAIN, 2, val); + if (ret) + return ret; + + ret = imx208_write_reg(imx208, IMX208_REG_R_DIGITAL_GAIN, 2, val); + if (ret) + return ret; + + return imx208_write_reg(imx208, IMX208_REG_B_DIGITAL_GAIN, 2, val); +} + +static int imx208_set_ctrl(struct v4l2_ctrl *ctrl) +{ + struct imx208 *imx208 = + container_of(ctrl->handler, struct imx208, ctrl_handler); + struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd); + int ret; + + /* + * Applying V4L2 control value only happens + * when power is up for streaming + */ + if (!pm_runtime_get_if_in_use(&client->dev)) + return 0; + + switch (ctrl->id) { + case V4L2_CID_ANALOGUE_GAIN: + ret = imx208_write_reg(imx208, IMX208_REG_ANALOG_GAIN, + 2, ctrl->val); + break; + case V4L2_CID_EXPOSURE: + ret = imx208_write_reg(imx208, IMX208_REG_EXPOSURE, + 2, ctrl->val); + break; + case V4L2_CID_DIGITAL_GAIN: + ret = imx208_update_digital_gain(imx208, 2, ctrl->val); + break; + case V4L2_CID_VBLANK: + /* Update VTS that meets expected vertical blanking */ + ret = imx208_write_reg(imx208, IMX208_REG_VTS, 2, + imx208->cur_mode->height + ctrl->val); + break; + case V4L2_CID_TEST_PATTERN: + ret = imx208_write_reg(imx208, IMX208_REG_TEST_PATTERN_MODE, + 2, imx208_test_pattern_val[ctrl->val]); + break; + case V4L2_CID_HFLIP: + case V4L2_CID_VFLIP: + ret = imx208_write_reg(imx208, IMX208_REG_ORIENTATION_CONTROL, + 1, + imx208->hflip->val | + imx208->vflip->val << 1); + break; + default: + ret = -EINVAL; + dev_err(&client->dev, + "ctrl(id:0x%x,val:0x%x) is not handled\n", + ctrl->id, ctrl->val); + break; + } + + pm_runtime_put(&client->dev); + + return ret; +} + +static const struct v4l2_ctrl_ops imx208_ctrl_ops = { + .s_ctrl = imx208_set_ctrl, +}; + +static const struct v4l2_ctrl_config imx208_digital_gain_control = { + .ops = &imx208_ctrl_ops, + .id = V4L2_CID_DIGITAL_GAIN, + .name = "Digital Gain", + .type = V4L2_CTRL_TYPE_INTEGER_MENU, + .min = 0, + .max = ARRAY_SIZE(imx208_discrete_digital_gain) - 1, + .step = 0, + .def = 0, + .menu_skip_mask = 0, + .qmenu_int = imx208_discrete_digital_gain, +}; + +static int imx208_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) +{ + struct imx208 *imx208 = to_imx208(sd); + + if (code->index > 0) + return -EINVAL; + + code->code = imx208_get_format_code(imx208); + + return 0; +} + +static int imx208_enum_frame_size(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_frame_size_enum *fse) +{ + struct imx208 *imx208 = to_imx208(sd); + + if (fse->index >= ARRAY_SIZE(supported_modes)) + return -EINVAL; + + if (fse->code != imx208_get_format_code(imx208)) + return -EINVAL; + + fse->min_width = supported_modes[fse->index].width; + fse->max_width = fse->min_width; + fse->min_height = supported_modes[fse->index].height; + fse->max_height = fse->min_height; + + return 0; +} + +static void imx208_mode_to_pad_format(struct imx208 *imx208, + const struct imx208_mode *mode, + struct v4l2_subdev_format *fmt) +{ + fmt->format.width = mode->width; + fmt->format.height = mode->height; + fmt->format.code = imx208_get_format_code(imx208); + fmt->format.field = V4L2_FIELD_NONE; +} + +static int __imx208_get_pad_format(struct imx208 *imx208, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *fmt) +{ + if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) + fmt->format = *v4l2_subdev_get_try_format(&imx208->sd, cfg, + fmt->pad); + else + imx208_mode_to_pad_format(imx208, imx208->cur_mode, fmt); + + return 0; +} + +static int imx208_get_pad_format(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *fmt) +{ + struct imx208 *imx208 = to_imx208(sd); + int ret; + + mutex_lock(&imx208->imx208_mx); + ret = __imx208_get_pad_format(imx208, cfg, fmt); + mutex_unlock(&imx208->imx208_mx); + + return ret; +} + +static int imx208_set_pad_format(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *fmt) +{ + struct imx208 *imx208 = to_imx208(sd); + const struct imx208_mode *mode; + s32 vblank_def; + s32 vblank_min; + s64 h_blank; + s64 pixel_rate; + s64 link_freq; + + mutex_lock(&imx208->imx208_mx); + + fmt->format.code = imx208_get_format_code(imx208); + mode = v4l2_find_nearest_size(supported_modes, + ARRAY_SIZE(supported_modes), width, height, + fmt->format.width, fmt->format.height); + imx208_mode_to_pad_format(imx208, mode, fmt); + if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { + *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format; + } else { + imx208->cur_mode = mode; + __v4l2_ctrl_s_ctrl(imx208->link_freq, mode->link_freq_index); + link_freq = link_freq_menu_items[mode->link_freq_index]; + pixel_rate = link_freq_to_pixel_rate(link_freq); + __v4l2_ctrl_s_ctrl_int64(imx208->pixel_rate, pixel_rate); + /* Update limits and set FPS to default */ + vblank_def = imx208->cur_mode->vts_def - + imx208->cur_mode->height; + vblank_min = imx208->cur_mode->vts_min - + imx208->cur_mode->height; + __v4l2_ctrl_modify_range(imx208->vblank, vblank_min, + IMX208_VTS_MAX - imx208->cur_mode->height, + 1, vblank_def); + __v4l2_ctrl_s_ctrl(imx208->vblank, vblank_def); + h_blank = + link_freq_configs[mode->link_freq_index].pixels_per_line + - imx208->cur_mode->width; + __v4l2_ctrl_modify_range(imx208->hblank, h_blank, + h_blank, 1, h_blank); + } + + mutex_unlock(&imx208->imx208_mx); + + return 0; +} + +/* Start streaming */ +static int imx208_start_streaming(struct imx208 *imx208) +{ + struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd); + const struct imx208_reg_list *reg_list; + int ret, link_freq_index; + + /* Setup PLL */ + link_freq_index = imx208->cur_mode->link_freq_index; + reg_list = &link_freq_configs[link_freq_index].reg_list; + ret = imx208_write_regs(imx208, reg_list->regs, reg_list->num_of_regs); + if (ret) { + dev_err(&client->dev, "%s failed to set plls\n", __func__); + return ret; + } + + /* Apply default values of current mode */ + reg_list = &imx208->cur_mode->reg_list; + ret = imx208_write_regs(imx208, reg_list->regs, reg_list->num_of_regs); + if (ret) { + dev_err(&client->dev, "%s failed to set mode\n", __func__); + return ret; + } + + /* Apply customized values from user */ + ret = __v4l2_ctrl_handler_setup(imx208->sd.ctrl_handler); + if (ret) + return ret; + + /* set stream on register */ + return imx208_write_reg(imx208, IMX208_REG_MODE_SELECT, + 1, IMX208_MODE_STREAMING); +} + +/* Stop streaming */ +static int imx208_stop_streaming(struct imx208 *imx208) +{ + struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd); + int ret; + + /* set stream off register */ + ret = imx208_write_reg(imx208, IMX208_REG_MODE_SELECT, + 1, IMX208_MODE_STANDBY); + if (ret) + dev_err(&client->dev, "%s failed to set stream\n", __func__); + + /* + * Return success even if it was an error, as there is nothing the + * caller can do about it. + */ + return 0; +} + +static int imx208_set_stream(struct v4l2_subdev *sd, int enable) +{ + struct imx208 *imx208 = to_imx208(sd); + struct i2c_client *client = v4l2_get_subdevdata(sd); + int ret = 0; + + mutex_lock(&imx208->imx208_mx); + if (imx208->streaming == enable) { + mutex_unlock(&imx208->imx208_mx); + return 0; + } + + if (enable) { + ret = pm_runtime_get_sync(&client->dev); + if (ret < 0) + goto err_rpm_put; + + /* + * Apply default & customized values + * and then start streaming. + */ + ret = imx208_start_streaming(imx208); + if (ret) + goto err_rpm_put; + } else { + imx208_stop_streaming(imx208); + pm_runtime_put(&client->dev); + } + + imx208->streaming = enable; + mutex_unlock(&imx208->imx208_mx); + + /* vflip and hflip cannot change during streaming */ + v4l2_ctrl_grab(imx208->vflip, enable); + v4l2_ctrl_grab(imx208->hflip, enable); + + return ret; + +err_rpm_put: + pm_runtime_put(&client->dev); + mutex_unlock(&imx208->imx208_mx); + + return ret; +} + +static int __maybe_unused imx208_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct imx208 *imx208 = to_imx208(sd); + + if (imx208->streaming) + imx208_stop_streaming(imx208); + + return 0; +} + +static int __maybe_unused imx208_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct imx208 *imx208 = to_imx208(sd); + int ret; + + if (imx208->streaming) { + ret = imx208_start_streaming(imx208); + if (ret) + goto error; + } + + return 0; + +error: + imx208_stop_streaming(imx208); + imx208->streaming = 0; + + return ret; +} + +/* Verify chip ID */ +static int imx208_identify_module(struct imx208 *imx208) +{ + struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd); + int ret; + u32 val; + + ret = imx208_read_reg(imx208, IMX208_REG_CHIP_ID, + 2, &val); + if (ret) { + dev_err(&client->dev, "failed to read chip id %x\n", + IMX208_CHIP_ID); + return ret; + } + + if (val != IMX208_CHIP_ID) { + dev_err(&client->dev, "chip id mismatch: %x!=%x\n", + IMX208_CHIP_ID, val); + return -EIO; + } + + return 0; +} + +static const struct v4l2_subdev_video_ops imx208_video_ops = { + .s_stream = imx208_set_stream, +}; + +static const struct v4l2_subdev_pad_ops imx208_pad_ops = { + .enum_mbus_code = imx208_enum_mbus_code, + .get_fmt = imx208_get_pad_format, + .set_fmt = imx208_set_pad_format, + .enum_frame_size = imx208_enum_frame_size, +}; + +static const struct v4l2_subdev_ops imx208_subdev_ops = { + .video = &imx208_video_ops, + .pad = &imx208_pad_ops, +}; + +static const struct v4l2_subdev_internal_ops imx208_internal_ops = { + .open = imx208_open, +}; + +static int imx208_read_otp(struct imx208 *imx208) +{ + struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd); + struct i2c_msg msgs[2]; + u8 addr_buf[2] = { IMX208_OTP_BASE >> 8, IMX208_OTP_BASE & 0xff }; + int ret = 0; + + mutex_lock(&imx208->imx208_mx); + + if (imx208->otp_read) + goto out_unlock; + + ret = pm_runtime_get_sync(&client->dev); + if (ret < 0) { + pm_runtime_put_noidle(&client->dev); + goto out_unlock; + } + + /* Write register address */ + msgs[0].addr = client->addr; + msgs[0].flags = 0; + msgs[0].len = ARRAY_SIZE(addr_buf); + msgs[0].buf = addr_buf; + + /* Read data from registers */ + msgs[1].addr = client->addr; + msgs[1].flags = I2C_M_RD; + msgs[1].len = sizeof(imx208->otp_data); + msgs[1].buf = imx208->otp_data; + + ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); + if (ret == ARRAY_SIZE(msgs)) { + imx208->otp_read = true; + ret = 0; + } + + pm_runtime_put(&client->dev); + +out_unlock: + mutex_unlock(&imx208->imx208_mx); + + return ret; +} + +static ssize_t otp_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct i2c_client *client = to_i2c_client(kobj_to_dev(kobj)); + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct imx208 *imx208 = to_imx208(sd); + int ret; + + ret = imx208_read_otp(imx208); + if (ret) + return ret; + + memcpy(buf, &imx208->otp_data[off], count); + return count; +} + +static const BIN_ATTR_RO(otp, IMX208_OTP_SIZE); + +/* Initialize control handlers */ +static int imx208_init_controls(struct imx208 *imx208) +{ + struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd); + struct v4l2_ctrl_handler *ctrl_hdlr = &imx208->ctrl_handler; + s64 exposure_max; + s64 vblank_def; + s64 vblank_min; + s64 pixel_rate_min; + s64 pixel_rate_max; + int ret; + + ret = v4l2_ctrl_handler_init(ctrl_hdlr, 8); + if (ret) + return ret; + + mutex_init(&imx208->imx208_mx); + ctrl_hdlr->lock = &imx208->imx208_mx; + imx208->link_freq = + v4l2_ctrl_new_int_menu(ctrl_hdlr, + &imx208_ctrl_ops, + V4L2_CID_LINK_FREQ, + ARRAY_SIZE(link_freq_menu_items) - 1, + 0, link_freq_menu_items); + + if (imx208->link_freq) + imx208->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; + + pixel_rate_max = link_freq_to_pixel_rate(link_freq_menu_items[0]); + pixel_rate_min = + link_freq_to_pixel_rate(link_freq_menu_items[ARRAY_SIZE(link_freq_menu_items) - 1]); + /* By default, PIXEL_RATE is read only */ + imx208->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx208_ctrl_ops, + V4L2_CID_PIXEL_RATE, + pixel_rate_min, pixel_rate_max, + 1, pixel_rate_max); + + vblank_def = imx208->cur_mode->vts_def - imx208->cur_mode->height; + vblank_min = imx208->cur_mode->vts_min - imx208->cur_mode->height; + imx208->vblank = + v4l2_ctrl_new_std(ctrl_hdlr, &imx208_ctrl_ops, V4L2_CID_VBLANK, + vblank_min, + IMX208_VTS_MAX - imx208->cur_mode->height, 1, + vblank_def); + + imx208->hblank = + v4l2_ctrl_new_std(ctrl_hdlr, &imx208_ctrl_ops, V4L2_CID_HBLANK, + IMX208_PPL_384MHZ - imx208->cur_mode->width, + IMX208_PPL_384MHZ - imx208->cur_mode->width, + 1, + IMX208_PPL_384MHZ - imx208->cur_mode->width); + + if (imx208->hblank) + imx208->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; + + exposure_max = imx208->cur_mode->vts_def - 8; + v4l2_ctrl_new_std(ctrl_hdlr, &imx208_ctrl_ops, V4L2_CID_EXPOSURE, + IMX208_EXPOSURE_MIN, exposure_max, + IMX208_EXPOSURE_STEP, IMX208_EXPOSURE_DEFAULT); + + imx208->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx208_ctrl_ops, + V4L2_CID_HFLIP, 0, 1, 1, 0); + imx208->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx208_ctrl_ops, + V4L2_CID_VFLIP, 0, 1, 1, 0); + + v4l2_ctrl_new_std(ctrl_hdlr, &imx208_ctrl_ops, V4L2_CID_ANALOGUE_GAIN, + IMX208_ANA_GAIN_MIN, IMX208_ANA_GAIN_MAX, + IMX208_ANA_GAIN_STEP, IMX208_ANA_GAIN_DEFAULT); + + v4l2_ctrl_new_custom(ctrl_hdlr, &imx208_digital_gain_control, NULL); + + v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx208_ctrl_ops, + V4L2_CID_TEST_PATTERN, + ARRAY_SIZE(imx208_test_pattern_menu) - 1, + 0, 0, imx208_test_pattern_menu); + + if (ctrl_hdlr->error) { + ret = ctrl_hdlr->error; + dev_err(&client->dev, "%s control init failed (%d)\n", + __func__, ret); + goto error; + } + + imx208->sd.ctrl_handler = ctrl_hdlr; + + return 0; + +error: + v4l2_ctrl_handler_free(ctrl_hdlr); + mutex_destroy(&imx208->imx208_mx); + + return ret; +} + +static void imx208_free_controls(struct imx208 *imx208) +{ + v4l2_ctrl_handler_free(imx208->sd.ctrl_handler); +} + +static int imx208_probe(struct i2c_client *client) +{ + struct imx208 *imx208; + int ret; + u32 val = 0; + + device_property_read_u32(&client->dev, "clock-frequency", &val); + if (val != 19200000) { + dev_err(&client->dev, + "Unsupported clock-frequency %u. Expected 19200000.\n", + val); + return -EINVAL; + } + + imx208 = devm_kzalloc(&client->dev, sizeof(*imx208), GFP_KERNEL); + if (!imx208) + return -ENOMEM; + + /* Initialize subdev */ + v4l2_i2c_subdev_init(&imx208->sd, client, &imx208_subdev_ops); + + /* Check module identity */ + ret = imx208_identify_module(imx208); + if (ret) { + dev_err(&client->dev, "failed to find sensor: %d", ret); + goto error_probe; + } + + /* Set default mode to max resolution */ + imx208->cur_mode = &supported_modes[0]; + + ret = imx208_init_controls(imx208); + if (ret) { + dev_err(&client->dev, "failed to init controls: %d", ret); + goto error_probe; + } + + /* Initialize subdev */ + imx208->sd.internal_ops = &imx208_internal_ops; + imx208->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; + imx208->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; + + /* Initialize source pad */ + imx208->pad.flags = MEDIA_PAD_FL_SOURCE; + ret = media_entity_pads_init(&imx208->sd.entity, 1, &imx208->pad); + if (ret) { + dev_err(&client->dev, "%s failed:%d\n", __func__, ret); + goto error_handler_free; + } + + ret = v4l2_async_register_subdev_sensor(&imx208->sd); + if (ret < 0) + goto error_media_entity; + + ret = device_create_bin_file(&client->dev, &bin_attr_otp); + if (ret) { + dev_err(&client->dev, "sysfs otp creation failed\n"); + goto error_async_subdev; + } + + pm_runtime_set_active(&client->dev); + pm_runtime_enable(&client->dev); + pm_runtime_idle(&client->dev); + + return 0; + +error_async_subdev: + v4l2_async_unregister_subdev(&imx208->sd); + +error_media_entity: + media_entity_cleanup(&imx208->sd.entity); + +error_handler_free: + imx208_free_controls(imx208); + +error_probe: + mutex_destroy(&imx208->imx208_mx); + + return ret; +} + +static int imx208_remove(struct i2c_client *client) +{ + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct imx208 *imx208 = to_imx208(sd); + + device_remove_bin_file(&client->dev, &bin_attr_otp); + v4l2_async_unregister_subdev(sd); + media_entity_cleanup(&sd->entity); + imx208_free_controls(imx208); + + pm_runtime_disable(&client->dev); + pm_runtime_set_suspended(&client->dev); + + mutex_destroy(&imx208->imx208_mx); + + return 0; +} + +static const struct dev_pm_ops imx208_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(imx208_suspend, imx208_resume) +}; + +#ifdef CONFIG_ACPI +static const struct acpi_device_id imx208_acpi_ids[] = { + { "INT3478" }, + { /* sentinel */ } +}; + +MODULE_DEVICE_TABLE(acpi, imx208_acpi_ids); +#endif + +static struct i2c_driver imx208_i2c_driver = { + .driver = { + .name = "imx208", + .pm = &imx208_pm_ops, + .acpi_match_table = ACPI_PTR(imx208_acpi_ids), + }, + .probe_new = imx208_probe, + .remove = imx208_remove, +}; + +module_i2c_driver(imx208_i2c_driver); + +MODULE_AUTHOR("Yeh, Andy "); +MODULE_AUTHOR("Chen, Ping-chung "); +MODULE_AUTHOR("Shawn Tu "); +MODULE_DESCRIPTION("Sony IMX208 sensor driver"); +MODULE_LICENSE("GPL v2"); From 47926106af78d5fe6817c8db966213801950eed3 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Wed, 5 May 2021 22:17:17 +0200 Subject: [PATCH 199/394] media: i2c: ov2659: Fix an error message 'ret' is known to be 0 here and printing -ENODEV wouldn't be really helpful. So remove it from the error message. Signed-off-by: Christophe JAILLET Acked-by: Lad Prabhakar Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov2659.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c index 7c1781f646ce..befef14aa86b 100644 --- a/drivers/media/i2c/ov2659.c +++ b/drivers/media/i2c/ov2659.c @@ -1377,8 +1377,7 @@ static int ov2659_detect(struct v4l2_subdev *sd) id = OV265X_ID(pid, ver); if (id != OV2659_ID) { dev_err(&client->dev, - "Sensor detection failed (%04X, %d)\n", - id, ret); + "Sensor detection failed (%04X)\n", id); ret = -ENODEV; } else { dev_info(&client->dev, "Found OV%04X sensor\n", id); From 92fbe0323d1b6f596643bb5c91b886789bb90228 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Wed, 5 May 2021 22:20:37 +0200 Subject: [PATCH 200/394] media: i2c: ov9650: Fix an error message 'ret' is known to be 0 here and printing -ENODEV wouldn't be really helpful. So remove it from the error message. Signed-off-by: Christophe JAILLET Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ov9650.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/ov9650.c b/drivers/media/i2c/ov9650.c index 4fe68aa55789..a9f13dc2f053 100644 --- a/drivers/media/i2c/ov9650.c +++ b/drivers/media/i2c/ov9650.c @@ -1479,8 +1479,8 @@ static int ov965x_detect_sensor(struct v4l2_subdev *sd) if (ov965x->id == OV9650_ID || ov965x->id == OV9652_ID) { v4l2_info(sd, "Found OV%04X sensor\n", ov965x->id); } else { - v4l2_err(sd, "Sensor detection failed (%04X, %d)\n", - ov965x->id, ret); + v4l2_err(sd, "Sensor detection failed (%04X)\n", + ov965x->id); ret = -ENODEV; } } From d443d838f6d76c8e1acbd4e27583cb2948066f0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20S=C3=B6derlund?= Date: Tue, 11 May 2021 16:23:20 +0200 Subject: [PATCH 201/394] media: dt-bindings: media: renesas,isp: Add bindings for ISP Channel Selector MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add bindings for Renesas R-Car ISP Channel Selector IP. The ISP is responsible for filtering the MIPI CSI-2 bus and directing the different CSI-2 virtual channels to different R-Car VIN instances (DMA engines) for capture. Signed-off-by: Niklas Söderlund Reviewed-by: Rob Herring Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- .../bindings/media/renesas,isp.yaml | 196 ++++++++++++++++++ MAINTAINERS | 1 + 2 files changed, 197 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/renesas,isp.yaml diff --git a/Documentation/devicetree/bindings/media/renesas,isp.yaml b/Documentation/devicetree/bindings/media/renesas,isp.yaml new file mode 100644 index 000000000000..514857d36f6b --- /dev/null +++ b/Documentation/devicetree/bindings/media/renesas,isp.yaml @@ -0,0 +1,196 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +# Copyright (C) 2021 Renesas Electronics Corp. +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/renesas,isp.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Renesas R-Car ISP Channel Selector + +maintainers: + - Niklas Söderlund + +description: + The R-Car ISP Channel Selector provides MIPI CSI-2 VC and DT filtering + capabilities for the Renesas R-Car family of devices. It is used in + conjunction with the R-Car VIN and CSI-2 modules, which provides the video + capture capabilities. + +properties: + compatible: + items: + - enum: + - renesas,r8a779a0-isp # V3U + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + power-domains: + maxItems: 1 + + resets: + maxItems: 1 + + ports: + $ref: /schemas/graph.yaml#/properties/ports + + properties: + port@0: + $ref: /schemas/graph.yaml#/properties/port + description: + Input port node, multiple endpoints describing the connected R-Car + CSI-2 receivers. + + port@1: + $ref: /schemas/graph.yaml#/properties/port + description: + Single endpoint describing the R-Car VIN connected to output port 0. + + port@2: + $ref: /schemas/graph.yaml#/properties/port + description: + Single endpoint describing the R-Car VIN connected to output port 1. + + port@3: + $ref: /schemas/graph.yaml#/properties/port + description: + Single endpoint describing the R-Car VIN connected to output port 2. + + port@4: + $ref: /schemas/graph.yaml#/properties/port + description: + Single endpoint describing the R-Car VIN connected to output port 3. + + port@5: + $ref: /schemas/graph.yaml#/properties/port + description: + Single endpoint describing the R-Car VIN connected to output port 4. + + port@6: + $ref: /schemas/graph.yaml#/properties/port + description: + Single endpoint describing the R-Car VIN connected to output port 5. + + port@7: + $ref: /schemas/graph.yaml#/properties/port + description: + Single endpoint describing the R-Car VIN connected to output port 6. + + port@8: + $ref: /schemas/graph.yaml#/properties/port + description: + Single endpoint describing the R-Car VIN connected to output port 7. + + required: + - port@0 + - port@1 + - port@2 + - port@3 + - port@4 + - port@5 + - port@6 + - port@7 + - port@8 + +required: + - compatible + - reg + - interrupts + - clocks + - power-domains + - resets + - ports + +additionalProperties: false + +examples: + - | + #include + #include + #include + + isp1: isp@fed20000 { + compatible = "renesas,r8a779a0-isp"; + reg = <0xfed20000 0x10000>; + interrupts = ; + clocks = <&cpg CPG_MOD 613>; + power-domains = <&sysc R8A779A0_PD_A3ISP01>; + resets = <&cpg 613>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + #address-cells = <1>; + #size-cells = <0>; + + reg = <0>; + isp1csi41: endpoint@1 { + reg = <1>; + remote-endpoint = <&csi41isp1>; + }; + }; + + port@1 { + reg = <1>; + isp1vin08: endpoint { + remote-endpoint = <&vin08isp1>; + }; + }; + + port@2 { + reg = <2>; + isp1vin09: endpoint { + remote-endpoint = <&vin09isp1>; + }; + }; + + port@3 { + reg = <3>; + isp1vin10: endpoint { + remote-endpoint = <&vin10isp1>; + }; + }; + + port@4 { + reg = <4>; + isp1vin11: endpoint { + remote-endpoint = <&vin11isp1>; + }; + }; + + port@5 { + reg = <5>; + isp1vin12: endpoint { + remote-endpoint = <&vin12isp1>; + }; + }; + + port@6 { + reg = <6>; + isp1vin13: endpoint { + remote-endpoint = <&vin13isp1>; + }; + }; + + port@7 { + reg = <7>; + isp1vin14: endpoint { + remote-endpoint = <&vin14isp1>; + }; + }; + + port@8 { + reg = <8>; + isp1vin15: endpoint { + remote-endpoint = <&vin15isp1>; + }; + }; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 0fee01ceb151..5e1bbb39a68e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11400,6 +11400,7 @@ L: linux-renesas-soc@vger.kernel.org S: Supported T: git git://linuxtv.org/media_tree.git F: Documentation/devicetree/bindings/media/renesas,csi2.yaml +F: Documentation/devicetree/bindings/media/renesas,isp.yaml F: Documentation/devicetree/bindings/media/renesas,vin.yaml F: drivers/media/platform/rcar-vin/ From 8f6a0eabb1f21a23a570b0986c8abe9fded3ad6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20S=C3=B6derlund?= Date: Tue, 11 May 2021 16:33:32 +0200 Subject: [PATCH 202/394] media: dt-bindings: media: renesas,vin: Add r8a779a0 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Document support for the VIN module in the Renesas V3U (r8a779a0) SoC. The V3U is different from other SoCs as it have 32 instead of 8 (most of Gen3) or 16 (V3H) VIN instances. The VIN instances are also connected to a new IP the R-Car ISP Channel Selector. Signed-off-by: Niklas Söderlund Reviewed-by: Rob Herring Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- .../bindings/media/renesas,vin.yaml | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/media/renesas,vin.yaml b/Documentation/devicetree/bindings/media/renesas,vin.yaml index dd1a5ce5896c..5ba06b0f030b 100644 --- a/Documentation/devicetree/bindings/media/renesas,vin.yaml +++ b/Documentation/devicetree/bindings/media/renesas,vin.yaml @@ -51,6 +51,7 @@ properties: - renesas,vin-r8a77980 # R-Car V3H - renesas,vin-r8a77990 # R-Car E3 - renesas,vin-r8a77995 # R-Car D3 + - renesas,vin-r8a779a0 # R-Car V3U reg: maxItems: 1 @@ -111,7 +112,7 @@ properties: description: VIN channel number $ref: /schemas/types.yaml#/definitions/uint32 minimum: 0 - maximum: 15 + maximum: 31 ports: $ref: /schemas/graph.yaml#/properties/ports @@ -187,6 +188,29 @@ properties: - required: - endpoint@3 + port@2: + $ref: /schemas/graph.yaml#/properties/port + description: + Input port node, multiple endpoints describing all the R-Car ISP + modules connected the VIN. + + properties: + endpoint@0: + $ref: /schemas/graph.yaml#/properties/endpoint + description: Endpoint connected to ISP0. + + endpoint@1: + $ref: /schemas/graph.yaml#/properties/endpoint + description: Endpoint connected to ISP1. + + endpoint@2: + $ref: /schemas/graph.yaml#/properties/endpoint + description: Endpoint connected to ISP2. + + endpoint@3: + $ref: /schemas/graph.yaml#/properties/endpoint + description: Endpoint connected to ISP3. + required: - compatible - reg From 6e2202ca1ee034920b029124151754aec67b61ba Mon Sep 17 00:00:00 2001 From: Stanimir Varbanov Date: Wed, 28 Apr 2021 23:50:20 +0200 Subject: [PATCH 203/394] media: venus: hfi_cmds: Fix conceal color property The conceal color property used for Venus v4 and v6 has the same payload structure. But currently v4 follow down to payload structure for v1. Correct this by moving set_property to v4. Fixes: 4ef6039fad8f ("media: venus: vdec: Add support for conceal control") Signed-off-by: Stanimir Varbanov Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/venus/hfi_cmds.c | 22 ++++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/media/platform/qcom/venus/hfi_cmds.c b/drivers/media/platform/qcom/venus/hfi_cmds.c index 11a8347e5f5c..4b9dea7f6940 100644 --- a/drivers/media/platform/qcom/venus/hfi_cmds.c +++ b/drivers/media/platform/qcom/venus/hfi_cmds.c @@ -1226,6 +1226,17 @@ pkt_session_set_property_4xx(struct hfi_session_set_property_pkt *pkt, pkt->shdr.hdr.size += sizeof(u32) + sizeof(*hdr10); break; } + case HFI_PROPERTY_PARAM_VDEC_CONCEAL_COLOR: { + struct hfi_conceal_color_v4 *color = prop_data; + u32 *in = pdata; + + color->conceal_color_8bit = *in & 0xff; + color->conceal_color_8bit |= ((*in >> 10) & 0xff) << 8; + color->conceal_color_8bit |= ((*in >> 20) & 0xff) << 16; + color->conceal_color_10bit = *in; + pkt->shdr.hdr.size += sizeof(u32) + sizeof(*color); + break; + } case HFI_PROPERTY_CONFIG_VENC_MAX_BITRATE: case HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER: @@ -1279,17 +1290,6 @@ pkt_session_set_property_6xx(struct hfi_session_set_property_pkt *pkt, pkt->shdr.hdr.size += sizeof(u32) + sizeof(*cq); break; } - case HFI_PROPERTY_PARAM_VDEC_CONCEAL_COLOR: { - struct hfi_conceal_color_v4 *color = prop_data; - u32 *in = pdata; - - color->conceal_color_8bit = *in & 0xff; - color->conceal_color_8bit |= ((*in >> 10) & 0xff) << 8; - color->conceal_color_8bit |= ((*in >> 20) & 0xff) << 16; - color->conceal_color_10bit = *in; - pkt->shdr.hdr.size += sizeof(u32) + sizeof(*color); - break; - } default: return pkt_session_set_property_4xx(pkt, cookie, ptype, pdata); } From 0394360eafa08766424c194d9096c535e6f2833f Mon Sep 17 00:00:00 2001 From: Yangtao Li Date: Sun, 14 Mar 2021 17:34:07 +0100 Subject: [PATCH 204/394] media: venus: Convert to use resource-managed OPP API Use resource-managed OPP API to simplify code. Signed-off-by: Yangtao Li Signed-off-by: Dmitry Osipenko Signed-off-by: Stanimir Varbanov Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/venus/core.h | 1 - .../media/platform/qcom/venus/pm_helpers.c | 42 +++++-------------- 2 files changed, 11 insertions(+), 32 deletions(-) diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h index 745f226a523f..56054c3db8ca 100644 --- a/drivers/media/platform/qcom/venus/core.h +++ b/drivers/media/platform/qcom/venus/core.h @@ -155,7 +155,6 @@ struct venus_core { struct clk *vcodec1_clks[VIDC_VCODEC_CLKS_NUM_MAX]; struct icc_path *video_path; struct icc_path *cpucfg_path; - struct opp_table *opp_table; bool has_opp_table; struct device *pmdomains[VIDC_PMDOMAINS_NUM_MAX]; struct device_link *opp_dl_venus; diff --git a/drivers/media/platform/qcom/venus/pm_helpers.c b/drivers/media/platform/qcom/venus/pm_helpers.c index d0fddf5e9a69..fc204e4046aa 100644 --- a/drivers/media/platform/qcom/venus/pm_helpers.c +++ b/drivers/media/platform/qcom/venus/pm_helpers.c @@ -300,16 +300,15 @@ static int core_get_v1(struct venus_core *core) if (ret) return ret; - core->opp_table = dev_pm_opp_set_clkname(core->dev, "core"); - if (IS_ERR(core->opp_table)) - return PTR_ERR(core->opp_table); + ret = devm_pm_opp_set_clkname(core->dev, "core"); + if (ret) + return ret; return 0; } static void core_put_v1(struct venus_core *core) { - dev_pm_opp_put_clkname(core->opp_table); } static int core_power_v1(struct venus_core *core, int on) @@ -788,7 +787,6 @@ static int venc_power_v4(struct device *dev, int on) static int vcodec_domains_get(struct venus_core *core) { int ret; - struct opp_table *opp_table; struct device **opp_virt_dev; struct device *dev = core->dev; const struct venus_resources *res = core->res; @@ -811,11 +809,9 @@ skip_pmdomains: return 0; /* Attach the power domain for setting performance state */ - opp_table = dev_pm_opp_attach_genpd(dev, res->opp_pmdomain, &opp_virt_dev); - if (IS_ERR(opp_table)) { - ret = PTR_ERR(opp_table); + ret = devm_pm_opp_attach_genpd(dev, res->opp_pmdomain, &opp_virt_dev); + if (ret) goto opp_attach_err; - } core->opp_pmdomain = *opp_virt_dev; core->opp_dl_venus = device_link_add(dev, core->opp_pmdomain, @@ -824,13 +820,11 @@ skip_pmdomains: DL_FLAG_STATELESS); if (!core->opp_dl_venus) { ret = -ENODEV; - goto opp_dl_add_err; + goto opp_attach_err; } return 0; -opp_dl_add_err: - dev_pm_opp_detach_genpd(core->opp_table); opp_attach_err: for (i = 0; i < res->vcodec_pmdomains_num; i++) { if (IS_ERR_OR_NULL(core->pmdomains[i])) @@ -861,8 +855,6 @@ skip_pmdomains: if (core->opp_dl_venus) device_link_del(core->opp_dl_venus); - - dev_pm_opp_detach_genpd(core->opp_table); } static int core_resets_reset(struct venus_core *core) @@ -941,45 +933,33 @@ static int core_get_v4(struct venus_core *core) if (legacy_binding) return 0; - core->opp_table = dev_pm_opp_set_clkname(dev, "core"); - if (IS_ERR(core->opp_table)) - return PTR_ERR(core->opp_table); + ret = devm_pm_opp_set_clkname(dev, "core"); + if (ret) + return ret; if (core->res->opp_pmdomain) { - ret = dev_pm_opp_of_add_table(dev); + ret = devm_pm_opp_of_add_table(dev); if (!ret) { core->has_opp_table = true; } else if (ret != -ENODEV) { dev_err(dev, "invalid OPP table in device tree\n"); - dev_pm_opp_put_clkname(core->opp_table); return ret; } } ret = vcodec_domains_get(core); - if (ret) { - if (core->has_opp_table) - dev_pm_opp_of_remove_table(dev); - dev_pm_opp_put_clkname(core->opp_table); + if (ret) return ret; - } return 0; } static void core_put_v4(struct venus_core *core) { - struct device *dev = core->dev; - if (legacy_binding) return; vcodec_domains_put(core); - - if (core->has_opp_table) - dev_pm_opp_of_remove_table(dev); - dev_pm_opp_put_clkname(core->opp_table); - } static int core_power_v4(struct venus_core *core, int on) From 51bb3989c2a1c49b8cebdb753a0ab28d5a546b52 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Wed, 10 Feb 2021 23:57:20 +0100 Subject: [PATCH 205/394] media: venus: hfi_cmds.h: Replace one-element array with flexible-array member MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is a regular need in the kernel to provide a way to declare having a dynamically sized set of trailing elements in a structure. Kernel code should always use “flexible array members”[1] for these cases. The older style of one-element or zero-length arrays should no longer be used[2]. Use flexible-array member in struct hfi_sys_set_property_pkt instead of one-element array. Also, this helps with the ongoing efforts to enable -Warray-bounds and fix the following warnings: drivers/media/platform/qcom/venus/hfi_cmds.c: In function ‘pkt_sys_coverage_config’: drivers/media/platform/qcom/venus/hfi_cmds.c:57:11: warning: array subscript 1 is above array bounds of ‘u32[1]’ {aka ‘unsigned int[1]’} [-Warray-bounds] 57 | pkt->data[1] = mode; | ~~~~~~~~~^~~ [1] https://en.wikipedia.org/wiki/Flexible_array_member [2] https://www.kernel.org/doc/html/v5.9/process/deprecated.html#zero-length-and-one-element-arrays Link: https://github.com/KSPP/linux/issues/79 Link: https://github.com/KSPP/linux/issues/109 Build-tested-by: kernel test robot Link: https://lore.kernel.org/lkml/602416da.iZqae7Dbk7nyl6OY%25lkp@intel.com/ Signed-off-by: Gustavo A. R. Silva Signed-off-by: Stanimir Varbanov Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/venus/hfi_cmds.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/qcom/venus/hfi_cmds.h b/drivers/media/platform/qcom/venus/hfi_cmds.h index 83705e237f1c..327ed90a2788 100644 --- a/drivers/media/platform/qcom/venus/hfi_cmds.h +++ b/drivers/media/platform/qcom/venus/hfi_cmds.h @@ -68,7 +68,7 @@ struct hfi_sys_release_resource_pkt { struct hfi_sys_set_property_pkt { struct hfi_pkt_hdr hdr; u32 num_properties; - u32 data[1]; + u32 data[]; }; struct hfi_sys_get_property_pkt { From 3cfe5815ce0ee87f4979787cc7af23404a02edc1 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Mon, 12 Apr 2021 08:58:43 +0200 Subject: [PATCH 206/394] media: venus: Enable low power setting for encoder Set the FW to run in low power for encoder to accommodate more session without losing much on quality. Signed-off-by: Dikshita Agarwal Signed-off-by: Stanimir Varbanov Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/venus/core.h | 6 + drivers/media/platform/qcom/venus/helpers.c | 2 + .../media/platform/qcom/venus/hfi_helper.h | 10 +- .../media/platform/qcom/venus/hfi_platform.c | 16 +++ .../media/platform/qcom/venus/hfi_platform.h | 4 + .../platform/qcom/venus/hfi_platform_v4.c | 28 +++-- .../platform/qcom/venus/hfi_platform_v6.c | 28 +++-- .../media/platform/qcom/venus/pm_helpers.c | 106 +++++++++++++++--- 8 files changed, 166 insertions(+), 34 deletions(-) diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h index 56054c3db8ca..8df2d497d706 100644 --- a/drivers/media/platform/qcom/venus/core.h +++ b/drivers/media/platform/qcom/venus/core.h @@ -292,6 +292,7 @@ struct clock_data { unsigned long freq; unsigned long vpp_freq; unsigned long vsp_freq; + unsigned long low_power_freq; }; #define to_venus_buffer(ptr) container_of(ptr, struct venus_buffer, vb) @@ -315,6 +316,10 @@ struct venus_ts_metadata { struct v4l2_timecode tc; }; +enum venus_inst_modes { + VENUS_LOW_POWER = BIT(0), +}; + /** * struct venus_inst - holds per instance parameters * @@ -444,6 +449,7 @@ struct venus_inst { unsigned int pic_struct; bool next_buf_last; bool drain_active; + enum venus_inst_modes flags; }; #define IS_V1(core) ((core)->res->hfi_version == HFI_VERSION_1XX) diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c index b813d6dba481..b691215a3bf2 100644 --- a/drivers/media/platform/qcom/venus/helpers.c +++ b/drivers/media/platform/qcom/venus/helpers.c @@ -1627,6 +1627,8 @@ int venus_helper_session_init(struct venus_inst *inst) session_type); inst->clk_data.vsp_freq = hfi_platform_get_codec_vsp_freq(version, codec, session_type); + inst->clk_data.low_power_freq = hfi_platform_get_codec_lp_freq(version, codec, + session_type); return 0; } diff --git a/drivers/media/platform/qcom/venus/hfi_helper.h b/drivers/media/platform/qcom/venus/hfi_helper.h index 63cd347a62da..b0a9beb4163c 100644 --- a/drivers/media/platform/qcom/venus/hfi_helper.h +++ b/drivers/media/platform/qcom/venus/hfi_helper.h @@ -415,9 +415,6 @@ #define HFI_BUFFER_MODE_RING 0x1000002 #define HFI_BUFFER_MODE_DYNAMIC 0x1000003 -#define HFI_VENC_PERFMODE_MAX_QUALITY 0x1 -#define HFI_VENC_PERFMODE_POWER_SAVE 0x2 - /* * HFI_PROPERTY_SYS_COMMON_START * HFI_DOMAIN_BASE_COMMON + HFI_ARCH_COMMON_OFFSET + 0x0000 @@ -848,6 +845,13 @@ struct hfi_framesize { u32 height; }; +#define HFI_VENC_PERFMODE_MAX_QUALITY 0x1 +#define HFI_VENC_PERFMODE_POWER_SAVE 0x2 + +struct hfi_perf_mode { + u32 video_perf_mode; +}; + #define VIDC_CORE_ID_DEFAULT 0 #define VIDC_CORE_ID_1 1 #define VIDC_CORE_ID_2 2 diff --git a/drivers/media/platform/qcom/venus/hfi_platform.c b/drivers/media/platform/qcom/venus/hfi_platform.c index 8f47804e973f..f5b4e1f4764f 100644 --- a/drivers/media/platform/qcom/venus/hfi_platform.c +++ b/drivers/media/platform/qcom/venus/hfi_platform.c @@ -50,6 +50,22 @@ hfi_platform_get_codec_vsp_freq(enum hfi_version version, u32 codec, u32 session return freq; } +unsigned long +hfi_platform_get_codec_lp_freq(enum hfi_version version, u32 codec, u32 session_type) +{ + const struct hfi_platform *plat; + unsigned long freq = 0; + + plat = hfi_platform_get(version); + if (!plat) + return 0; + + if (plat->codec_lp_freq) + freq = plat->codec_lp_freq(session_type, codec); + + return freq; +} + u8 hfi_platform_num_vpp_pipes(enum hfi_version version) { const struct hfi_platform *plat; diff --git a/drivers/media/platform/qcom/venus/hfi_platform.h b/drivers/media/platform/qcom/venus/hfi_platform.h index 3819bb2b36bd..2dbe608c53af 100644 --- a/drivers/media/platform/qcom/venus/hfi_platform.h +++ b/drivers/media/platform/qcom/venus/hfi_platform.h @@ -43,11 +43,13 @@ struct hfi_platform_codec_freq_data { u32 session_type; unsigned long vpp_freq; unsigned long vsp_freq; + unsigned long low_power_freq; }; struct hfi_platform { unsigned long (*codec_vpp_freq)(u32 session_type, u32 codec); unsigned long (*codec_vsp_freq)(u32 session_type, u32 codec); + unsigned long (*codec_lp_freq)(u32 session_type, u32 codec); void (*codecs)(u32 *enc_codecs, u32 *dec_codecs, u32 *count); const struct hfi_plat_caps *(*capabilities)(unsigned int *entries); u8 (*num_vpp_pipes)(void); @@ -63,5 +65,7 @@ unsigned long hfi_platform_get_codec_vpp_freq(enum hfi_version version, u32 code u32 session_type); unsigned long hfi_platform_get_codec_vsp_freq(enum hfi_version version, u32 codec, u32 session_type); +unsigned long hfi_platform_get_codec_lp_freq(enum hfi_version version, u32 codec, + u32 session_type); u8 hfi_platform_num_vpp_pipes(enum hfi_version version); #endif diff --git a/drivers/media/platform/qcom/venus/hfi_platform_v4.c b/drivers/media/platform/qcom/venus/hfi_platform_v4.c index 3848bb6d7408..3f7f5277a50e 100644 --- a/drivers/media/platform/qcom/venus/hfi_platform_v4.c +++ b/drivers/media/platform/qcom/venus/hfi_platform_v4.c @@ -262,14 +262,14 @@ static void get_codecs(u32 *enc_codecs, u32 *dec_codecs, u32 *count) } static const struct hfi_platform_codec_freq_data codec_freq_data[] = { - { V4L2_PIX_FMT_H264, VIDC_SESSION_TYPE_ENC, 675, 10 }, - { V4L2_PIX_FMT_HEVC, VIDC_SESSION_TYPE_ENC, 675, 10 }, - { V4L2_PIX_FMT_VP8, VIDC_SESSION_TYPE_ENC, 675, 10 }, - { V4L2_PIX_FMT_MPEG2, VIDC_SESSION_TYPE_DEC, 200, 10 }, - { V4L2_PIX_FMT_H264, VIDC_SESSION_TYPE_DEC, 200, 10 }, - { V4L2_PIX_FMT_HEVC, VIDC_SESSION_TYPE_DEC, 200, 10 }, - { V4L2_PIX_FMT_VP8, VIDC_SESSION_TYPE_DEC, 200, 10 }, - { V4L2_PIX_FMT_VP9, VIDC_SESSION_TYPE_DEC, 200, 10 }, + { V4L2_PIX_FMT_H264, VIDC_SESSION_TYPE_ENC, 675, 10, 320 }, + { V4L2_PIX_FMT_HEVC, VIDC_SESSION_TYPE_ENC, 675, 10, 320 }, + { V4L2_PIX_FMT_VP8, VIDC_SESSION_TYPE_ENC, 675, 10, 320 }, + { V4L2_PIX_FMT_MPEG2, VIDC_SESSION_TYPE_DEC, 200, 10, 200 }, + { V4L2_PIX_FMT_H264, VIDC_SESSION_TYPE_DEC, 200, 10, 200 }, + { V4L2_PIX_FMT_HEVC, VIDC_SESSION_TYPE_DEC, 200, 10, 200 }, + { V4L2_PIX_FMT_VP8, VIDC_SESSION_TYPE_DEC, 200, 10, 200 }, + { V4L2_PIX_FMT_VP9, VIDC_SESSION_TYPE_DEC, 200, 10, 200 }, }; static const struct hfi_platform_codec_freq_data * @@ -311,9 +311,21 @@ static unsigned long codec_vsp_freq(u32 session_type, u32 codec) return 0; } +static unsigned long codec_lp_freq(u32 session_type, u32 codec) +{ + const struct hfi_platform_codec_freq_data *data; + + data = get_codec_freq_data(session_type, codec); + if (data) + return data->low_power_freq; + + return 0; +} + const struct hfi_platform hfi_plat_v4 = { .codec_vpp_freq = codec_vpp_freq, .codec_vsp_freq = codec_vsp_freq, + .codec_lp_freq = codec_lp_freq, .codecs = get_codecs, .capabilities = get_capabilities, }; diff --git a/drivers/media/platform/qcom/venus/hfi_platform_v6.c b/drivers/media/platform/qcom/venus/hfi_platform_v6.c index dd1a03911b6c..d8243b22568a 100644 --- a/drivers/media/platform/qcom/venus/hfi_platform_v6.c +++ b/drivers/media/platform/qcom/venus/hfi_platform_v6.c @@ -262,14 +262,14 @@ static void get_codecs(u32 *enc_codecs, u32 *dec_codecs, u32 *count) } static const struct hfi_platform_codec_freq_data codec_freq_data[] = { - { V4L2_PIX_FMT_H264, VIDC_SESSION_TYPE_ENC, 675, 25 }, - { V4L2_PIX_FMT_HEVC, VIDC_SESSION_TYPE_ENC, 675, 25 }, - { V4L2_PIX_FMT_VP8, VIDC_SESSION_TYPE_ENC, 675, 60 }, - { V4L2_PIX_FMT_MPEG2, VIDC_SESSION_TYPE_DEC, 200, 25 }, - { V4L2_PIX_FMT_H264, VIDC_SESSION_TYPE_DEC, 200, 25 }, - { V4L2_PIX_FMT_HEVC, VIDC_SESSION_TYPE_DEC, 200, 25 }, - { V4L2_PIX_FMT_VP8, VIDC_SESSION_TYPE_DEC, 200, 60 }, - { V4L2_PIX_FMT_VP9, VIDC_SESSION_TYPE_DEC, 200, 60 }, + { V4L2_PIX_FMT_H264, VIDC_SESSION_TYPE_ENC, 675, 25, 320 }, + { V4L2_PIX_FMT_HEVC, VIDC_SESSION_TYPE_ENC, 675, 25, 320 }, + { V4L2_PIX_FMT_VP8, VIDC_SESSION_TYPE_ENC, 675, 60, 320 }, + { V4L2_PIX_FMT_MPEG2, VIDC_SESSION_TYPE_DEC, 200, 25, 200 }, + { V4L2_PIX_FMT_H264, VIDC_SESSION_TYPE_DEC, 200, 25, 200 }, + { V4L2_PIX_FMT_HEVC, VIDC_SESSION_TYPE_DEC, 200, 25, 200 }, + { V4L2_PIX_FMT_VP8, VIDC_SESSION_TYPE_DEC, 200, 60, 200 }, + { V4L2_PIX_FMT_VP9, VIDC_SESSION_TYPE_DEC, 200, 60, 200 }, }; static const struct hfi_platform_codec_freq_data * @@ -311,6 +311,17 @@ static unsigned long codec_vsp_freq(u32 session_type, u32 codec) return 0; } +static unsigned long codec_lp_freq(u32 session_type, u32 codec) +{ + const struct hfi_platform_codec_freq_data *data; + + data = get_codec_freq_data(session_type, codec); + if (data) + return data->low_power_freq; + + return 0; +} + static u8 num_vpp_pipes(void) { return 4; @@ -319,6 +330,7 @@ static u8 num_vpp_pipes(void) const struct hfi_platform hfi_plat_v6 = { .codec_vpp_freq = codec_vpp_freq, .codec_vsp_freq = codec_vsp_freq, + .codec_lp_freq = codec_lp_freq, .codecs = get_codecs, .capabilities = get_capabilities, .num_vpp_pipes = num_vpp_pipes, diff --git a/drivers/media/platform/qcom/venus/pm_helpers.c b/drivers/media/platform/qcom/venus/pm_helpers.c index fc204e4046aa..3e2345eb47f7 100644 --- a/drivers/media/platform/qcom/venus/pm_helpers.c +++ b/drivers/media/platform/qcom/venus/pm_helpers.c @@ -523,8 +523,50 @@ static int poweron_coreid(struct venus_core *core, unsigned int coreid_mask) return 0; } +static inline int power_save_mode_enable(struct venus_inst *inst, + bool enable) +{ + struct venc_controls *enc_ctr = &inst->controls.enc; + const u32 ptype = HFI_PROPERTY_CONFIG_VENC_PERF_MODE; + u32 venc_mode; + int ret = 0; + + if (inst->session_type != VIDC_SESSION_TYPE_ENC) + return 0; + + if (enc_ctr->bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) + enable = false; + + venc_mode = enable ? HFI_VENC_PERFMODE_POWER_SAVE : + HFI_VENC_PERFMODE_MAX_QUALITY; + + ret = hfi_session_set_property(inst, ptype, &venc_mode); + if (ret) + return ret; + + inst->flags = enable ? inst->flags | VENUS_LOW_POWER : + inst->flags & ~VENUS_LOW_POWER; + + return ret; +} + +static int move_core_to_power_save_mode(struct venus_core *core, + u32 core_id) +{ + struct venus_inst *inst = NULL; + + mutex_lock(&core->lock); + list_for_each_entry(inst, &core->instances, list) { + if (inst->clk_data.core_id == core_id && + inst->session_type == VIDC_SESSION_TYPE_ENC) + power_save_mode_enable(inst, true); + } + mutex_unlock(&core->lock); + return 0; +} + static void -min_loaded_core(struct venus_inst *inst, u32 *min_coreid, u32 *min_load) +min_loaded_core(struct venus_inst *inst, u32 *min_coreid, u32 *min_load, bool low_power) { u32 mbs_per_sec, load, core1_load = 0, core2_load = 0; u32 cores_max = core_num_max(inst); @@ -542,7 +584,14 @@ min_loaded_core(struct venus_inst *inst, u32 *min_coreid, u32 *min_load) if (inst_pos->state != INST_START) continue; - vpp_freq = inst_pos->clk_data.vpp_freq; + if (inst->session_type == VIDC_SESSION_TYPE_DEC) + vpp_freq = inst_pos->clk_data.vpp_freq; + else if (inst->session_type == VIDC_SESSION_TYPE_ENC) + vpp_freq = low_power ? inst_pos->clk_data.vpp_freq : + inst_pos->clk_data.low_power_freq; + else + continue; + coreid = inst_pos->clk_data.core_id; mbs_per_sec = load_per_instance(inst_pos); @@ -574,9 +623,11 @@ static int decide_core(struct venus_inst *inst) { const u32 ptype = HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE; struct venus_core *core = inst->core; - u32 min_coreid, min_load, inst_load; + u32 min_coreid, min_load, cur_inst_load; + u32 min_lp_coreid, min_lp_load, cur_inst_lp_load; struct hfi_videocores_usage_type cu; unsigned long max_freq; + int ret = 0; if (legacy_binding) { if (inst->session_type == VIDC_SESSION_TYPE_DEC) @@ -590,23 +641,43 @@ static int decide_core(struct venus_inst *inst) if (inst->clk_data.core_id != VIDC_CORE_ID_DEFAULT) return 0; - inst_load = load_per_instance(inst); - inst_load *= inst->clk_data.vpp_freq; + cur_inst_load = load_per_instance(inst); + cur_inst_load *= inst->clk_data.vpp_freq; + /*TODO : divide this inst->load by work_route */ + + cur_inst_lp_load = load_per_instance(inst); + cur_inst_lp_load *= inst->clk_data.low_power_freq; + /*TODO : divide this inst->load by work_route */ + max_freq = core->res->freq_tbl[0].freq; - min_loaded_core(inst, &min_coreid, &min_load); + min_loaded_core(inst, &min_coreid, &min_load, false); + min_loaded_core(inst, &min_lp_coreid, &min_lp_load, true); - if ((inst_load + min_load) > max_freq) { - dev_warn(core->dev, "HW is overloaded, needed: %u max: %lu\n", - inst_load, max_freq); + if (cur_inst_load + min_load <= max_freq) { + inst->clk_data.core_id = min_coreid; + cu.video_core_enable_mask = min_coreid; + } else if (cur_inst_lp_load + min_load <= max_freq) { + /* Move current instance to LP and return */ + inst->clk_data.core_id = min_coreid; + cu.video_core_enable_mask = min_coreid; + power_save_mode_enable(inst, true); + } else if (cur_inst_lp_load + min_lp_load <= max_freq) { + /* Move all instances to LP mode and return */ + inst->clk_data.core_id = min_lp_coreid; + cu.video_core_enable_mask = min_lp_coreid; + move_core_to_power_save_mode(core, min_lp_coreid); + } else { + dev_warn(core->dev, "HW can't support this load"); return -EINVAL; } - inst->clk_data.core_id = min_coreid; - cu.video_core_enable_mask = min_coreid; - done: - return hfi_session_set_property(inst, ptype, &cu); + ret = hfi_session_set_property(inst, ptype, &cu); + if (ret) + return ret; + + return ret; } static int acquire_core(struct venus_inst *inst) @@ -1005,7 +1076,7 @@ static int core_power_v4(struct venus_core *core, int on) static unsigned long calculate_inst_freq(struct venus_inst *inst, unsigned long filled_len) { - unsigned long vpp_freq = 0, vsp_freq = 0; + unsigned long vpp_freq_per_mb = 0, vpp_freq = 0, vsp_freq = 0; u32 fps = (u32)inst->fps; u32 mbs_per_sec; @@ -1014,7 +1085,12 @@ static unsigned long calculate_inst_freq(struct venus_inst *inst, if (inst->state != INST_START) return 0; - vpp_freq = mbs_per_sec * inst->clk_data.vpp_freq; + if (inst->session_type == VIDC_SESSION_TYPE_ENC) + vpp_freq_per_mb = inst->flags & VENUS_LOW_POWER ? + inst->clk_data.low_power_freq : + inst->clk_data.vpp_freq; + + vpp_freq = mbs_per_sec * vpp_freq_per_mb; /* 21 / 20 is overhead factor */ vpp_freq += vpp_freq / 20; vsp_freq = mbs_per_sec * inst->clk_data.vsp_freq; From 6fc46680520f38af8425a447de5e0f84106512eb Mon Sep 17 00:00:00 2001 From: Zhen Lei Date: Mon, 10 May 2021 13:57:52 +0200 Subject: [PATCH 207/394] media: venus: helpers: Delete an unneeded bool conversion The result of an expression consisting of a single relational operator is already of the bool type and does not need to be evaluated explicitly. No functional change. Signed-off-by: Zhen Lei Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/venus/helpers.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c index b691215a3bf2..1fe6d463dc99 100644 --- a/drivers/media/platform/qcom/venus/helpers.c +++ b/drivers/media/platform/qcom/venus/helpers.c @@ -595,8 +595,7 @@ static int platform_get_bufreq(struct venus_inst *inst, u32 buftype, params.dec.is_secondary_output = inst->opb_buftype == HFI_BUFFER_OUTPUT2; params.dec.is_interlaced = - inst->pic_struct != HFI_INTERLACE_FRAME_PROGRESSIVE ? - true : false; + inst->pic_struct != HFI_INTERLACE_FRAME_PROGRESSIVE; } else { params.width = inst->out_width; params.height = inst->out_height; From 83df8dfd57be041669e6dc365caf1d5f1b2791b8 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Tue, 2 Mar 2021 15:42:35 +0100 Subject: [PATCH 208/394] media: dt-bindings: media: Document RDA5807 FM radio bindings Add documentation for the devicetree bindings of the RDA5807 FM radio I2C chip from Unisoc. Signed-off-by: Paul Cercueil Reviewed-by: Rob Herring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../bindings/media/i2c/rda,rda5807.yaml | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/i2c/rda,rda5807.yaml diff --git a/Documentation/devicetree/bindings/media/i2c/rda,rda5807.yaml b/Documentation/devicetree/bindings/media/i2c/rda,rda5807.yaml new file mode 100644 index 000000000000..f50e54a722eb --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/rda,rda5807.yaml @@ -0,0 +1,67 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/i2c/rda,rda5807.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Unisoc Communications RDA5807 FM radio receiver + +maintainers: + - Paul Cercueil + +properties: + compatible: + enum: + - rda,rda5807 + + reg: + description: I2C address. + maxItems: 1 + + power-supply: true + + rda,lnan: + description: Use LNAN input port. + type: boolean + + rda,lnap: + description: Use LNAP input port. + type: boolean + + rda,analog-out: + description: Enable analog audio output. + type: boolean + + rda,i2s-out: + description: Enable I2S digital audio output. + type: boolean + + rda,lna-microamp: + description: LNA working current, in micro-amperes. + default: 2500 + enum: [1800, 2100, 2500, 3000] + +required: + - compatible + - reg + - power-supply + +additionalProperties: false + +examples: + - | + i2c0 { + #address-cells = <1>; + #size-cells = <0>; + + radio@11 { + compatible = "rda,rda5807"; + reg = <0x11>; + + power-supply = <&ldo6>; + + rda,lnan; + rda,lnap; + rda,analog-out; + }; + }; From 90c3493e4d9e2e1450b5d3ffd314ff350f5132a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20S=C3=B6derlund?= Date: Fri, 12 Mar 2021 14:03:30 +0100 Subject: [PATCH 209/394] media: dt-bindings: media: renesas,vin: Add r8a77961 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the compatible string for M3-W+ (r8a77961) to the list of supported SoCs. Signed-off-by: Niklas Söderlund Acked-by: Rob Herring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/devicetree/bindings/media/renesas,vin.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/media/renesas,vin.yaml b/Documentation/devicetree/bindings/media/renesas,vin.yaml index 5ba06b0f030b..39bb6db2fb32 100644 --- a/Documentation/devicetree/bindings/media/renesas,vin.yaml +++ b/Documentation/devicetree/bindings/media/renesas,vin.yaml @@ -46,6 +46,7 @@ properties: - renesas,vin-r8a7779 # R-Car H1 - renesas,vin-r8a7795 # R-Car H3 - renesas,vin-r8a7796 # R-Car M3-W + - renesas,vin-r8a77961 # R-Car M3-W+ - renesas,vin-r8a77965 # R-Car M3-N - renesas,vin-r8a77970 # R-Car V3M - renesas,vin-r8a77980 # R-Car V3H From be6cdcf2c9c97c5a702adb95520d0268c8ecc1ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20S=C3=B6derlund?= Date: Fri, 12 Mar 2021 14:04:21 +0100 Subject: [PATCH 210/394] media: dt-bindings: media: renesas,csi2: Add r8a77961 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the compatible string for M3-W+ (r8a77961) to the list of supported SoCs. Signed-off-by: Niklas Söderlund Acked-by: Rob Herring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/devicetree/bindings/media/renesas,csi2.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/media/renesas,csi2.yaml b/Documentation/devicetree/bindings/media/renesas,csi2.yaml index 20396f1be999..23703b767f5b 100644 --- a/Documentation/devicetree/bindings/media/renesas,csi2.yaml +++ b/Documentation/devicetree/bindings/media/renesas,csi2.yaml @@ -25,6 +25,7 @@ properties: - renesas,r8a774e1-csi2 # RZ/G2H - renesas,r8a7795-csi2 # R-Car H3 - renesas,r8a7796-csi2 # R-Car M3-W + - renesas,r8a77961-csi2 # R-Car M3-W+ - renesas,r8a77965-csi2 # R-Car M3-N - renesas,r8a77970-csi2 # R-Car V3M - renesas,r8a77980-csi2 # R-Car V3H From 14480e8df8b511bb904ad79b61bc0b6c29f989a2 Mon Sep 17 00:00:00 2001 From: Tian Tao Date: Wed, 7 Apr 2021 08:24:39 +0200 Subject: [PATCH 211/394] media: camss: move to use request_irq by IRQF_NO_AUTOEN flag disable_irq() after request_irq() still has a time gap in which interrupts can come. request_irq() with IRQF_NO_AUTOEN flag will disable IRQ auto-enable because of requesting. this patch is made base on "add IRQF_NO_AUTOEN for request_irq" which is being merged: https://lore.kernel.org/patchwork/patch/1388765/ Signed-off-by: Tian Tao Reviewed-by: Robert Foss Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/camss/camss-csid.c | 5 ++--- drivers/media/platform/qcom/camss/camss-csiphy.c | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c index 7e2490ca1ad1..251f4c4afe19 100644 --- a/drivers/media/platform/qcom/camss/camss-csid.c +++ b/drivers/media/platform/qcom/camss/camss-csid.c @@ -581,14 +581,13 @@ int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid, snprintf(csid->irq_name, sizeof(csid->irq_name), "%s_%s%d", dev_name(dev), MSM_CSID_NAME, csid->id); ret = devm_request_irq(dev, csid->irq, csid->ops->isr, - IRQF_TRIGGER_RISING, csid->irq_name, csid); + IRQF_TRIGGER_RISING | IRQF_NO_AUTOEN, + csid->irq_name, csid); if (ret < 0) { dev_err(dev, "request_irq failed: %d\n", ret); return ret; } - disable_irq(csid->irq); - /* Clocks */ csid->nclocks = 0; diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c index b623e007aec6..35470cbaea86 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c @@ -617,14 +617,13 @@ int msm_csiphy_subdev_init(struct camss *camss, dev_name(dev), MSM_CSIPHY_NAME, csiphy->id); ret = devm_request_irq(dev, csiphy->irq, csiphy->ops->isr, - IRQF_TRIGGER_RISING, csiphy->irq_name, csiphy); + IRQF_TRIGGER_RISING | IRQF_NO_AUTOEN, + csiphy->irq_name, csiphy); if (ret < 0) { dev_err(dev, "request_irq failed: %d\n", ret); return ret; } - disable_irq(csiphy->irq); - /* Clocks */ csiphy->nclocks = 0; From a3a54bf4bddaecda8b5767209cfc703f0be2841d Mon Sep 17 00:00:00 2001 From: Tong Zhang Date: Thu, 29 Apr 2021 00:12:26 +0200 Subject: [PATCH 212/394] media: bt878: do not schedule tasklet when it is not setup There is a problem with the tasklet in bt878. bt->tasklet is set by dvb-bt8xx.ko, and bt878.ko can be loaded independently. In this case if interrupt comes it may cause null-ptr-dereference. To solve this issue, we check if the tasklet is actually set before calling tasklet_schedule. [ 1.750438] bt878(0): irq FDSR FBUS risc_pc= [ 1.750728] BUG: kernel NULL pointer dereference, address: 0000000000000000 [ 1.752969] RIP: 0010:0x0 [ 1.757526] Call Trace: [ 1.757659] [ 1.757770] tasklet_action_common.isra.0+0x107/0x110 [ 1.758041] tasklet_action+0x22/0x30 [ 1.758237] __do_softirq+0xe0/0x29b [ 1.758430] irq_exit_rcu+0xa4/0xb0 [ 1.758618] common_interrupt+0x8d/0xa0 [ 1.758824] Signed-off-by: Tong Zhang Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/bt878.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/pci/bt8xx/bt878.c b/drivers/media/pci/bt8xx/bt878.c index 78dd35c9b65d..7ca309121fb5 100644 --- a/drivers/media/pci/bt8xx/bt878.c +++ b/drivers/media/pci/bt8xx/bt878.c @@ -300,7 +300,8 @@ static irqreturn_t bt878_irq(int irq, void *dev_id) } if (astat & BT878_ARISCI) { bt->finished_block = (stat & BT878_ARISCS) >> 28; - tasklet_schedule(&bt->tasklet); + if (bt->tasklet.callback) + tasklet_schedule(&bt->tasklet); break; } count++; From ac5688637144644f06ed1f3c6d4dd8bb7db96020 Mon Sep 17 00:00:00 2001 From: Igor Matheus Andrade Torrente Date: Tue, 4 May 2021 20:32:49 +0200 Subject: [PATCH 213/394] media: em28xx: Fix possible memory leak of em28xx struct The em28xx struct kref isn't being decreased after an error in the em28xx_ir_init, leading to a possible memory leak. A kref_put and em28xx_shutdown_buttons is added to the error handler code. Signed-off-by: Igor Matheus Andrade Torrente Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-input.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c index 5aa15a7a49de..59529cbf9cd0 100644 --- a/drivers/media/usb/em28xx/em28xx-input.c +++ b/drivers/media/usb/em28xx/em28xx-input.c @@ -720,7 +720,8 @@ static int em28xx_ir_init(struct em28xx *dev) dev->board.has_ir_i2c = 0; dev_warn(&dev->intf->dev, "No i2c IR remote control device found.\n"); - return -ENODEV; + err = -ENODEV; + goto ref_put; } } @@ -735,7 +736,7 @@ static int em28xx_ir_init(struct em28xx *dev) ir = kzalloc(sizeof(*ir), GFP_KERNEL); if (!ir) - return -ENOMEM; + goto ref_put; rc = rc_allocate_device(RC_DRIVER_SCANCODE); if (!rc) goto error; @@ -839,6 +840,9 @@ error: dev->ir = NULL; rc_free_device(rc); kfree(ir); +ref_put: + em28xx_shutdown_buttons(dev); + kref_put(&dev->ref, em28xx_free_device); return err; } From ba1ed4ae760a81caf39f54232e089d95157a0dba Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Wed, 5 May 2021 14:23:45 +0200 Subject: [PATCH 214/394] media: rkvdec: Fix .buf_prepare The driver should only set the payload on .buf_prepare if the buffer is CAPTURE type. If an OUTPUT buffer has a zero bytesused set by userspace then v4l2-core will set it to buffer length. If we overwrite bytesused for OUTPUT buffers, too, then vb2_get_plane_payload() will return incorrect value which might be then written to hw registers by the driver in rkvdec-h264.c. [Changed the comment and used V4L2_TYPE_IS_CAPTURE macro] Fixes: cd33c830448ba ("media: rkvdec: Add the rkvdec driver") Signed-off-by: Ezequiel Garcia Signed-off-by: Adrian Ratiu Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/rkvdec/rkvdec.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c index 8c17615f3a7a..7131156c1f2c 100644 --- a/drivers/staging/media/rkvdec/rkvdec.c +++ b/drivers/staging/media/rkvdec/rkvdec.c @@ -481,7 +481,15 @@ static int rkvdec_buf_prepare(struct vb2_buffer *vb) if (vb2_plane_size(vb, i) < sizeimage) return -EINVAL; } - vb2_set_plane_payload(vb, 0, f->fmt.pix_mp.plane_fmt[0].sizeimage); + + /* + * Buffer's bytesused must be written by driver for CAPTURE buffers. + * (for OUTPUT buffers, if userspace passes 0 bytesused, v4l2-core sets + * it to buffer length). + */ + if (V4L2_TYPE_IS_CAPTURE(vq->type)) + vb2_set_plane_payload(vb, 0, f->fmt.pix_mp.plane_fmt[0].sizeimage); + return 0; } From 082aaecff35fbe1937531057911b1dd1fc6b496e Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Wed, 5 May 2021 14:23:46 +0200 Subject: [PATCH 215/394] media: hantro: Fix .buf_prepare The driver should only set the payload on .buf_prepare if the buffer is CAPTURE type. If an OUTPUT buffer has a zero bytesused set by userspace then v4l2-core will set it to buffer length. If we overwrite bytesused for OUTPUT buffers, too, then vb2_get_plane_payload() will return incorrect value which might be then written to hw registers by the driver in hantro_g1_h264_dec.c. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/hantro/hantro_v4l2.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/staging/media/hantro/hantro_v4l2.c b/drivers/staging/media/hantro/hantro_v4l2.c index 1bc118e375a1..7ccc6405036a 100644 --- a/drivers/staging/media/hantro/hantro_v4l2.c +++ b/drivers/staging/media/hantro/hantro_v4l2.c @@ -639,7 +639,14 @@ static int hantro_buf_prepare(struct vb2_buffer *vb) ret = hantro_buf_plane_check(vb, pix_fmt); if (ret) return ret; - vb2_set_plane_payload(vb, 0, pix_fmt->plane_fmt[0].sizeimage); + /* + * Buffer's bytesused must be written by driver for CAPTURE buffers. + * (for OUTPUT buffers, if userspace passes 0 bytesused, v4l2-core sets + * it to buffer length). + */ + if (V4L2_TYPE_IS_CAPTURE(vq->type)) + vb2_set_plane_payload(vb, 0, pix_fmt->plane_fmt[0].sizeimage); + return 0; } From d84b9202d712309840f8b5abee0ed272506563bd Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Wed, 5 May 2021 14:23:47 +0200 Subject: [PATCH 216/394] media: cedrus: Fix .buf_prepare The driver should only set the payload on .buf_prepare if the buffer is CAPTURE type. If an OUTPUT buffer has a zero bytesused set by userspace then v4l2-core will set it to buffer length. If we overwrite bytesused for OUTPUT buffers, too, then vb2_get_plane_payload() will return incorrect value which might be then written to hw registers by the driver in cedrus_h264.c or cedrus_vp8.c. Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/sunxi/cedrus/cedrus_video.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging/media/sunxi/cedrus/cedrus_video.c index 9ddd789d0b1f..32c13ecb22d8 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c @@ -457,7 +457,13 @@ static int cedrus_buf_prepare(struct vb2_buffer *vb) if (vb2_plane_size(vb, 0) < pix_fmt->sizeimage) return -EINVAL; - vb2_set_plane_payload(vb, 0, pix_fmt->sizeimage); + /* + * Buffer's bytesused must be written by driver for CAPTURE buffers. + * (for OUTPUT buffers, if userspace passes 0 bytesused, v4l2-core sets + * it to buffer length). + */ + if (V4L2_TYPE_IS_CAPTURE(vq->type)) + vb2_set_plane_payload(vb, 0, pix_fmt->sizeimage); return 0; } From ef677df92e450b90688828a5e44b94c8dc156e62 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 6 May 2021 14:06:57 +0200 Subject: [PATCH 217/394] media: adv7842: support EDIDs up to 4 blocks The adv7842 driver didn't support EDIDs of 3 or 4 blocks, even though the hardware supports this. It is a bit more complicated due to the fact that the adv7842 can expose two EDIDs: one digital, one analog, for DVI-I connectors. In that case the VGA_EDID_ENABLE bit is set and blocks 0 and 1 of the EDID eeprom are used for the DVI-D part and block 2 is used for the DVI-A part of the DVI-I connector. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7842.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c index ff10af757b99..78e61fe6f2f0 100644 --- a/drivers/media/i2c/adv7842.c +++ b/drivers/media/i2c/adv7842.c @@ -98,12 +98,12 @@ struct adv7842_state { v4l2_std_id norm; struct { - u8 edid[256]; + u8 edid[512]; u32 blocks; u32 present; } hdmi_edid; struct { - u8 edid[256]; + u8 edid[128]; u32 blocks; u32 present; } vga_edid; @@ -720,6 +720,9 @@ static int edid_write_vga_segment(struct v4l2_subdev *sd) v4l2_dbg(2, debug, sd, "%s: write EDID on VGA port\n", __func__); + if (!state->vga_edid.present) + return 0; + /* HPA disable on port A and B */ io_write_and_or(sd, 0x20, 0xcf, 0x00); @@ -763,7 +766,7 @@ static int edid_write_hdmi_segment(struct v4l2_subdev *sd, u8 port) struct adv7842_state *state = to_state(sd); const u8 *edid = state->hdmi_edid.edid; u32 blocks = state->hdmi_edid.blocks; - int spa_loc; + unsigned int spa_loc; u16 pa, parent_pa; int err = 0; int i; @@ -796,12 +799,14 @@ static int edid_write_hdmi_segment(struct v4l2_subdev *sd, u8 port) pa = (edid[spa_loc] << 8) | edid[spa_loc + 1]; } - /* edid segment pointer '0' for HDMI ports */ - rep_write_and_or(sd, 0x77, 0xef, 0x00); - for (i = 0; !err && i < blocks * 128; i += I2C_SMBUS_BLOCK_MAX) + for (i = 0; !err && i < blocks * 128; i += I2C_SMBUS_BLOCK_MAX) { + /* set edid segment pointer for HDMI ports */ + if (i % 256 == 0) + rep_write_and_or(sd, 0x77, 0xef, i >= 256 ? 0x10 : 0x00); err = i2c_smbus_write_i2c_block_data(state->i2c_edid, i, I2C_SMBUS_BLOCK_MAX, edid + i); + } if (err) return err; @@ -2491,9 +2496,17 @@ static int adv7842_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) return 0; } +/* + * If the VGA_EDID_ENABLE bit is set (Repeater Map 0x7f, bit 7), then + * the first two blocks of the EDID are for the HDMI, and the first block + * of segment 1 (i.e. the third block of the EDID) is for VGA. + * So if a VGA EDID is installed, then the maximum size of the HDMI EDID + * is 2 blocks. + */ static int adv7842_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *e) { struct adv7842_state *state = to_state(sd); + unsigned int max_blocks = e->pad == ADV7842_EDID_PORT_VGA ? 1 : 4; int err = 0; memset(e->reserved, 0, sizeof(e->reserved)); @@ -2502,8 +2515,12 @@ static int adv7842_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *e) return -EINVAL; if (e->start_block != 0) return -EINVAL; - if (e->blocks > 2) { - e->blocks = 2; + if (e->pad < ADV7842_EDID_PORT_VGA && state->vga_edid.blocks) + max_blocks = 2; + if (e->pad == ADV7842_EDID_PORT_VGA && state->hdmi_edid.blocks > 2) + return -EBUSY; + if (e->blocks > max_blocks) { + e->blocks = max_blocks; return -E2BIG; } @@ -2514,7 +2531,7 @@ static int adv7842_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *e) switch (e->pad) { case ADV7842_EDID_PORT_VGA: - memset(&state->vga_edid.edid, 0, 256); + memset(&state->vga_edid.edid, 0, sizeof(state->vga_edid.edid)); state->vga_edid.blocks = e->blocks; state->vga_edid.present = e->blocks ? 0x1 : 0x0; if (e->blocks) @@ -2523,7 +2540,7 @@ static int adv7842_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *e) break; case ADV7842_EDID_PORT_A: case ADV7842_EDID_PORT_B: - memset(&state->hdmi_edid.edid, 0, 256); + memset(&state->hdmi_edid.edid, 0, sizeof(state->hdmi_edid.edid)); state->hdmi_edid.blocks = e->blocks; if (e->blocks) { state->hdmi_edid.present |= 0x04 << e->pad; From f9c2fd3bb85768f35e1d2bb6b357a214db3b7817 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Thu, 6 May 2021 23:06:34 +0200 Subject: [PATCH 218/394] media: ttpci: switch from 'pci_' to 'dma_' API The wrappers in include/linux/pci-dma-compat.h should go away. The patch has been generated with the coccinelle script below and has been hand modified to replace GFP_ with a correct flag. It has been compile tested. When memory is allocated in 'ace_allocate_descriptors()' and 'ace_init()' GFP_KERNEL can be used because both functions are called from the probe function and no lock is acquired. @@ @@ - PCI_DMA_BIDIRECTIONAL + DMA_BIDIRECTIONAL @@ @@ - PCI_DMA_TODEVICE + DMA_TO_DEVICE @@ @@ - PCI_DMA_FROMDEVICE + DMA_FROM_DEVICE @@ @@ - PCI_DMA_NONE + DMA_NONE @@ expression e1, e2, e3; @@ - pci_alloc_consistent(e1, e2, e3) + dma_alloc_coherent(&e1->dev, e2, e3, GFP_) @@ expression e1, e2, e3; @@ - pci_zalloc_consistent(e1, e2, e3) + dma_alloc_coherent(&e1->dev, e2, e3, GFP_) @@ expression e1, e2, e3, e4; @@ - pci_free_consistent(e1, e2, e3, e4) + dma_free_coherent(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_map_single(e1, e2, e3, e4) + dma_map_single(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_unmap_single(e1, e2, e3, e4) + dma_unmap_single(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4, e5; @@ - pci_map_page(e1, e2, e3, e4, e5) + dma_map_page(&e1->dev, e2, e3, e4, e5) @@ expression e1, e2, e3, e4; @@ - pci_unmap_page(e1, e2, e3, e4) + dma_unmap_page(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_map_sg(e1, e2, e3, e4) + dma_map_sg(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_unmap_sg(e1, e2, e3, e4) + dma_unmap_sg(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_dma_sync_single_for_cpu(e1, e2, e3, e4) + dma_sync_single_for_cpu(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_dma_sync_single_for_device(e1, e2, e3, e4) + dma_sync_single_for_device(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_dma_sync_sg_for_cpu(e1, e2, e3, e4) + dma_sync_sg_for_cpu(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_dma_sync_sg_for_device(e1, e2, e3, e4) + dma_sync_sg_for_device(&e1->dev, e2, e3, e4) @@ expression e1, e2; @@ - pci_dma_mapping_error(e1, e2) + dma_mapping_error(&e1->dev, e2) @@ expression e1, e2; @@ - pci_set_dma_mask(e1, e2) + dma_set_mask(&e1->dev, e2) @@ expression e1, e2; @@ - pci_set_consistent_dma_mask(e1, e2) + dma_set_coherent_mask(&e1->dev, e2) Signed-off-by: Christophe JAILLET Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ttpci/budget-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/pci/ttpci/budget-core.c b/drivers/media/pci/ttpci/budget-core.c index d405eea5c37f..5d5796f24469 100644 --- a/drivers/media/pci/ttpci/budget-core.c +++ b/drivers/media/pci/ttpci/budget-core.c @@ -180,7 +180,8 @@ static void vpeirq(struct tasklet_struct *t) u32 count; /* Ensure streamed PCI data is synced to CPU */ - pci_dma_sync_sg_for_cpu(budget->dev->pci, budget->pt.slist, budget->pt.nents, PCI_DMA_FROMDEVICE); + dma_sync_sg_for_cpu(&budget->dev->pci->dev, budget->pt.slist, + budget->pt.nents, DMA_FROM_DEVICE); /* nearest lower position divisible by 188 */ newdma -= newdma % 188; From 01fe904c9afd26e79c1f73aa0ca2e3d785e5e319 Mon Sep 17 00:00:00 2001 From: Lv Yunlong Date: Sun, 9 May 2021 10:12:31 +0200 Subject: [PATCH 219/394] media: exynos4-is: Fix a use after free in isp_video_release In isp_video_release, file->private_data is freed via _vb2_fop_release()->v4l2_fh_release(). But the freed file->private_data is still used in v4l2_fh_is_singular_file() ->v4l2_fh_is_singular(file->private_data), which is a use after free bug. My patch uses a variable 'is_singular_file' to avoid the uaf. v3: https://lore.kernel.org/patchwork/patch/1419058/ Fixes: 34947b8aebe3f ("[media] exynos4-is: Add the FIMC-IS ISP capture DMA driver") Signed-off-by: Lv Yunlong Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos4-is/fimc-isp-video.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c index 8d9dc597deaa..83688a7982f7 100644 --- a/drivers/media/platform/exynos4-is/fimc-isp-video.c +++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c @@ -305,17 +305,20 @@ static int isp_video_release(struct file *file) struct fimc_is_video *ivc = &isp->video_capture; struct media_entity *entity = &ivc->ve.vdev.entity; struct media_device *mdev = entity->graph_obj.mdev; + bool is_singular_file; mutex_lock(&isp->video_lock); - if (v4l2_fh_is_singular_file(file) && ivc->streaming) { + is_singular_file = v4l2_fh_is_singular_file(file); + + if (is_singular_file && ivc->streaming) { media_pipeline_stop(entity); ivc->streaming = 0; } _vb2_fop_release(file, NULL); - if (v4l2_fh_is_singular_file(file)) { + if (is_singular_file) { fimc_pipeline_call(&ivc->ve, close); mutex_lock(&mdev->graph_mutex); From 7dd0c9e547b6924e18712b6b51aa3cba1896ee2c Mon Sep 17 00:00:00 2001 From: Lv Yunlong Date: Sun, 9 May 2021 10:24:02 +0200 Subject: [PATCH 220/394] media: v4l2-core: Avoid the dangling pointer in v4l2_fh_release A use after free bug caused by the dangling pointer filp->privitate_data in v4l2_fh_release. See https://lore.kernel.org/patchwork/patch/1419058/. My patch sets the dangling pointer to NULL to provide robust. Signed-off-by: Lv Yunlong Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-fh.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/v4l2-core/v4l2-fh.c b/drivers/media/v4l2-core/v4l2-fh.c index 684574f58e82..90eec79ee995 100644 --- a/drivers/media/v4l2-core/v4l2-fh.c +++ b/drivers/media/v4l2-core/v4l2-fh.c @@ -96,6 +96,7 @@ int v4l2_fh_release(struct file *filp) v4l2_fh_del(fh); v4l2_fh_exit(fh); kfree(fh); + filp->private_data = NULL; } return 0; } From d2a0f8d6afdabf5d03a1b2fce73326bf0666ec18 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Tue, 11 May 2021 13:55:24 +0200 Subject: [PATCH 221/394] media: saa7134: Remove unnecessary INIT_LIST_HEAD() The list_head saa7134_devlist is initialized statically. It is unnecessary to initialize by INIT_LIST_HEAD(). Reported-by: Hulk Robot Signed-off-by: Yang Yingliang Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7134/saa7134-core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/pci/saa7134/saa7134-core.c b/drivers/media/pci/saa7134/saa7134-core.c index efb757d5168a..ec8dd41f9ebb 100644 --- a/drivers/media/pci/saa7134/saa7134-core.c +++ b/drivers/media/pci/saa7134/saa7134-core.c @@ -1524,7 +1524,6 @@ static struct pci_driver saa7134_pci_driver = { static int __init saa7134_init(void) { - INIT_LIST_HEAD(&saa7134_devlist); pr_info("saa7130/34: v4l2 driver version %s loaded\n", SAA7134_VERSION); return pci_register_driver(&saa7134_pci_driver); From 1a4520090681853e6b850cbe54b27247a013e0e5 Mon Sep 17 00:00:00 2001 From: Zheyu Ma Date: Wed, 12 May 2021 17:18:36 +0200 Subject: [PATCH 222/394] media: bt8xx: Fix a missing check bug in bt878_probe In 'bt878_irq', the driver calls 'tasklet_schedule', but this tasklet is set in 'dvb_bt8xx_load_card' of another driver 'dvb-bt8xx'. However, this two drivers are separate. The user may not load the 'dvb-bt8xx' driver when loading the 'bt8xx' driver, that is, the tasklet has not been initialized when 'tasklet_schedule' is called, so it is necessary to check whether the tasklet is initialized in 'bt878_probe'. Fix this by adding a check at the end of bt878_probe. The KASAN's report reveals it: BUG: unable to handle kernel NULL pointer dereference at 0000000000000000 PGD 800000006aab2067 P4D 800000006aab2067 PUD 6b2ea067 PMD 0 Oops: 0010 [#1] PREEMPT SMP KASAN PTI CPU: 2 PID: 8724 Comm: syz-executor.0 Not tainted 4.19.177- gdba4159c14ef-dirty #40 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.0-59- gc9ba5276e321-prebuilt.qemu.org 04/01/2014 RIP: 0010: (null) Code: Bad RIP value. RSP: 0018:ffff88806c287ea0 EFLAGS: 00010246 RAX: fffffbfff1b01774 RBX: dffffc0000000000 RCX: 0000000000000000 RDX: 0000000000000000 RSI: 1ffffffff1b01775 RDI: 0000000000000000 RBP: ffff88806c287f00 R08: fffffbfff1b01774 R09: fffffbfff1b01774 R10: 0000000000000001 R11: fffffbfff1b01773 R12: 0000000000000000 R13: ffff88806c29f530 R14: ffffffff8d80bb88 R15: ffffffff8d80bb90 FS: 00007f6b550e6700(0000) GS:ffff88806c280000(0000) knlGS: 0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffffffffffffffd6 CR3: 000000005ec98000 CR4: 00000000000006e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: tasklet_action_common.isra.17+0x141/0x420 kernel/softirq.c:522 tasklet_action+0x50/0x70 kernel/softirq.c:540 __do_softirq+0x224/0x92c kernel/softirq.c:292 invoke_softirq kernel/softirq.c:372 [inline] irq_exit+0x15a/0x180 kernel/softirq.c:412 exiting_irq arch/x86/include/asm/apic.h:535 [inline] do_IRQ+0x123/0x1e0 arch/x86/kernel/irq.c:260 common_interrupt+0xf/0xf arch/x86/entry/entry_64.S:670 RIP: 0010:__do_sys_interrupt kernel/sys.c:2593 [inline] RIP: 0010:__se_sys_interrupt kernel/sys.c:2584 [inline] RIP: 0010:__x64_sys_interrupt+0x5b/0x80 kernel/sys.c:2584 Code: ba 00 04 00 00 48 c7 c7 c0 99 31 8c e8 ae 76 5e 01 48 85 c0 75 21 e8 14 ae 24 00 48 c7 c3 c0 99 31 8c b8 0c 00 00 00 0f 01 c1 <31> db e8 fe ad 24 00 48 89 d8 5b 5d c3 48 c7 c3 ea ff ff ff eb ec RSP: 0018:ffff888054167f10 EFLAGS: 00000212 ORIG_RAX: ffffffffffffffde RAX: 000000000000000c RBX: ffffffff8c3199c0 RCX: ffffc90001ca6000 RDX: 000000000000001a RSI: ffffffff813478fc RDI: ffffffff8c319dc0 RBP: ffff888054167f18 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000080 R11: fffffbfff18633b7 R12: ffff888054167f58 R13: ffff88805f638000 R14: 0000000000000000 R15: 0000000000000000 do_syscall_64+0xb0/0x4e0 arch/x86/entry/common.c:293 entry_SYSCALL_64_after_hwframe+0x49/0xbe RIP: 0033:0x4692a9 Code: f7 d8 64 89 02 b8 ff ff ff ff c3 66 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 bc ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007f6b550e5c48 EFLAGS: 00000246 ORIG_RAX: 000000000000014f RAX: ffffffffffffffda RBX: 000000000077bf60 RCX: 00000000004692a9 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000020000140 RBP: 00000000004cf7eb R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 000000000077bf60 R13: 0000000000000000 R14: 000000000077bf60 R15: 00007fff55a1dca0 Modules linked in: Dumping ftrace buffer: (ftrace buffer empty) CR2: 0000000000000000 ---[ end trace 68e5849c3f77cbb6 ]--- RIP: 0010: (null) Code: Bad RIP value. RSP: 0018:ffff88806c287ea0 EFLAGS: 00010246 RAX: fffffbfff1b01774 RBX: dffffc0000000000 RCX: 0000000000000000 RDX: 0000000000000000 RSI: 1ffffffff1b01775 RDI: 0000000000000000 RBP: ffff88806c287f00 R08: fffffbfff1b01774 R09: fffffbfff1b01774 R10: 0000000000000001 R11: fffffbfff1b01773 R12: 0000000000000000 R13: ffff88806c29f530 R14: ffffffff8d80bb88 R15: ffffffff8d80bb90 FS: 00007f6b550e6700(0000) GS:ffff88806c280000(0000) knlGS: 0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffffffffffffffd6 CR3: 000000005ec98000 CR4: 00000000000006e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Reported-by: Zheyu Ma Signed-off-by: Zheyu Ma Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/bt8xx/bt878.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/pci/bt8xx/bt878.c b/drivers/media/pci/bt8xx/bt878.c index 7ca309121fb5..90972d6952f1 100644 --- a/drivers/media/pci/bt8xx/bt878.c +++ b/drivers/media/pci/bt8xx/bt878.c @@ -478,6 +478,9 @@ static int bt878_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) btwrite(0, BT878_AINT_MASK); bt878_num++; + if (!bt->tasklet.func) + tasklet_disable(&bt->tasklet); + return 0; fail2: From 6cf16148899fc021dbd352d0177ff015ab12823b Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Wed, 12 May 2021 19:35:14 +0200 Subject: [PATCH 223/394] media: radio: si4713: constify static struct v4l2_ioctl_ops The only usage of radio_si4713_ioctl_ops is to assign its address to the ioctl_ops field in the video_device struct, which is a pointer to const. Make it const to allow the compiler to put it in read-only memory. Signed-off-by: Rikard Falkeborn Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/si4713/radio-platform-si4713.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/radio/si4713/radio-platform-si4713.c b/drivers/media/radio/si4713/radio-platform-si4713.c index a7dfe5f55c18..433f9642786d 100644 --- a/drivers/media/radio/si4713/radio-platform-si4713.c +++ b/drivers/media/radio/si4713/radio-platform-si4713.c @@ -110,7 +110,7 @@ static long radio_si4713_default(struct file *file, void *p, ioctl, cmd, arg); } -static struct v4l2_ioctl_ops radio_si4713_ioctl_ops = { +static const struct v4l2_ioctl_ops radio_si4713_ioctl_ops = { .vidioc_querycap = radio_si4713_querycap, .vidioc_g_modulator = radio_si4713_g_modulator, .vidioc_s_modulator = radio_si4713_s_modulator, From 0909f4acb916f4ce0217f01ff31a9e0296b536da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20S=C3=B6derlund?= Date: Thu, 13 May 2021 14:47:15 +0200 Subject: [PATCH 224/394] media: rcar-vin: Enable support for r8a77961 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enable support for M3-W+ (r8a77961). Signed-off-by: Niklas Söderlund Tested-by: LUU HOAI Reviewed-by: Geert Uytterhoeven Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/rcar-vin/rcar-core.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index cb3025992817..33957cc9118c 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -1362,6 +1362,10 @@ static const struct of_device_id rvin_of_id_table[] = { .compatible = "renesas,vin-r8a7796", .data = &rcar_info_r8a7796, }, + { + .compatible = "renesas,vin-r8a77961", + .data = &rcar_info_r8a7796, + }, { .compatible = "renesas,vin-r8a77965", .data = &rcar_info_r8a77965, From 4c6178f31e7d33c87f9f046e3bcbaa15a1802ff9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20S=C3=B6derlund?= Date: Thu, 13 May 2021 16:09:14 +0200 Subject: [PATCH 225/394] media: rcar-csi2: Enable support for r8a77961 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enable support for M3-W+ (r8a77961). Signed-off-by: Niklas Söderlund Tested-by: LUU HOAI Reviewed-by: Geert Uytterhoeven Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/rcar-vin/rcar-csi2.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c b/drivers/media/platform/rcar-vin/rcar-csi2.c index 99bf814eb2a7..b87d5453e418 100644 --- a/drivers/media/platform/rcar-vin/rcar-csi2.c +++ b/drivers/media/platform/rcar-vin/rcar-csi2.c @@ -1121,6 +1121,11 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a7796 = { .num_channels = 4, }; +static const struct rcar_csi2_info rcar_csi2_info_r8a77961 = { + .hsfreqrange = hsfreqrange_m3w_h3es1, + .num_channels = 4, +}; + static const struct rcar_csi2_info rcar_csi2_info_r8a77965 = { .init_phtw = rcsi2_init_phtw_h3_v3h_m3n, .hsfreqrange = hsfreqrange_h3_v3h_m3n, @@ -1173,6 +1178,10 @@ static const struct of_device_id rcar_csi2_of_table[] = { .compatible = "renesas,r8a7796-csi2", .data = &rcar_csi2_info_r8a7796, }, + { + .compatible = "renesas,r8a77961-csi2", + .data = &rcar_csi2_info_r8a77961, + }, { .compatible = "renesas,r8a77965-csi2", .data = &rcar_csi2_info_r8a77965, From 2c1e75f5baac5432749b90174a7a1f50a97327b2 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 14 May 2021 00:03:17 +0200 Subject: [PATCH 226/394] media: meson: vdec: remove redundant initialization of variable reg_cur The variable reg_cur is being initialized with a value that is never read, it is being updated later on. The assignment is redundant and can be removed. Addresses-Coverity: ("Unused value") Signed-off-by: Colin Ian King Acked-by: Martin Blumenstingl Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/meson/vdec/vdec_helpers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/media/meson/vdec/vdec_helpers.c b/drivers/staging/media/meson/vdec/vdec_helpers.c index 7f07a9175815..b9125c295d1d 100644 --- a/drivers/staging/media/meson/vdec/vdec_helpers.c +++ b/drivers/staging/media/meson/vdec/vdec_helpers.c @@ -183,7 +183,7 @@ int amvdec_set_canvases(struct amvdec_session *sess, u32 pixfmt = sess->pixfmt_cap; u32 width = ALIGN(sess->width, 32); u32 height = ALIGN(sess->height, 32); - u32 reg_cur = reg_base[0]; + u32 reg_cur; u32 reg_num_cur = 0; u32 reg_base_cur = 0; int i = 0; From 1fcbeeb506fd785025a37d1a874108756abbef6b Mon Sep 17 00:00:00 2001 From: Ding Senjie Date: Fri, 14 May 2021 14:35:21 +0200 Subject: [PATCH 227/394] media: mtk-vpu: Use devm_platform_ioremap_resource_byname Use the devm_platform_ioremap_resource_byname() helper instead of calling platform_get_resource_byname() and devm_ioremap_resource() separately. Signed-off-by: Ding Senjie Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mtk-vpu/mtk_vpu.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/mtk-vpu/mtk_vpu.c b/drivers/media/platform/mtk-vpu/mtk_vpu.c index c8a56271b259..ef458b417fa7 100644 --- a/drivers/media/platform/mtk-vpu/mtk_vpu.c +++ b/drivers/media/platform/mtk-vpu/mtk_vpu.c @@ -821,13 +821,11 @@ static int mtk_vpu_probe(struct platform_device *pdev) return -ENOMEM; vpu->dev = &pdev->dev; - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tcm"); - vpu->reg.tcm = devm_ioremap_resource(dev, res); + vpu->reg.tcm = devm_platform_ioremap_resource_byname(pdev, "tcm"); if (IS_ERR((__force void *)vpu->reg.tcm)) return PTR_ERR((__force void *)vpu->reg.tcm); - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_reg"); - vpu->reg.cfg = devm_ioremap_resource(dev, res); + vpu->reg.cfg = devm_platform_ioremap_resource_byname(pdev, "cfg_reg"); if (IS_ERR((__force void *)vpu->reg.cfg)) return PTR_ERR((__force void *)vpu->reg.cfg); From 8f2e452730d2bcd59fe05246f0e19a4c52e0012d Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 14 May 2021 16:20:38 +0200 Subject: [PATCH 228/394] media: au0828: fix a NULL vs IS_ERR() check The media_device_usb_allocate() function returns error pointers when it's enabled and something goes wrong. It can return NULL as well, but only if CONFIG_MEDIA_CONTROLLER is disabled so that doesn't apply here. Fixes: 812658d88d26 ("media: change au0828 to use Media Device Allocator API") Signed-off-by: Dan Carpenter Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- 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 a8a72d5fbd12..caefac07af92 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -199,8 +199,8 @@ static int au0828_media_device_init(struct au0828_dev *dev, struct media_device *mdev; mdev = media_device_usb_allocate(udev, KBUILD_MODNAME, THIS_MODULE); - if (!mdev) - return -ENOMEM; + if (IS_ERR(mdev)) + return PTR_ERR(mdev); dev->media_dev = mdev; #endif From d67fa04ce41f7b5d92563734d76c55a676846cc4 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Fri, 14 May 2021 17:27:34 +0200 Subject: [PATCH 229/394] media: media/test_drivers: Drop unnecessary NULL check after container_of The result of container_of() operations is never NULL unless the embedded element is the first element of the structure. This is not the case here. The NULL check is therefore unnecessary and misleading. Remove it. This change was made automatically with the following Coccinelle script. @@ type t; identifier v; statement s; @@ <+... ( t v = container_of(...); | v = container_of(...); ) ... when != v - if (\( !v \| v == NULL \) ) s ...+> Signed-off-by: Guenter Roeck Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vim2m.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/media/test-drivers/vim2m.c b/drivers/media/test-drivers/vim2m.c index a24624353f9e..d714fe50afe5 100644 --- a/drivers/media/test-drivers/vim2m.c +++ b/drivers/media/test-drivers/vim2m.c @@ -624,11 +624,6 @@ static void device_work(struct work_struct *w) curr_ctx = container_of(w, struct vim2m_ctx, work_run.work); - if (!curr_ctx) { - pr_err("Instance released before the end of transaction\n"); - return; - } - vim2m_dev = curr_ctx->dev; src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx); From a6b1e7093f0a099571fc8836ab4a589633f956a8 Mon Sep 17 00:00:00 2001 From: Zhen Lei Date: Sat, 15 May 2021 08:58:30 +0200 Subject: [PATCH 230/394] media: tc358743: Fix error return code in tc358743_probe_of() When the CSI bps per lane is not in the valid range, an appropriate error code -EINVAL should be returned. However, we currently do not explicitly assign this error code to 'ret'. As a result, 0 was incorrectly returned. Fixes: 256148246852 ("[media] tc358743: support probe from device tree") Reported-by: Hulk Robot Signed-off-by: Zhen Lei Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/tc358743.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c index 1b309bb743c7..f21da11caf22 100644 --- a/drivers/media/i2c/tc358743.c +++ b/drivers/media/i2c/tc358743.c @@ -1974,6 +1974,7 @@ static int tc358743_probe_of(struct tc358743_state *state) bps_pr_lane = 2 * endpoint.link_frequencies[0]; if (bps_pr_lane < 62500000U || bps_pr_lane > 1000000000U) { dev_err(dev, "unsupported bps per lane: %u bps\n", bps_pr_lane); + ret = -EINVAL; goto disable_clk; } From dd706623fcab3ba808a2c48855e5e8aa2c6e8fbf Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Mon, 17 May 2021 05:11:23 +0200 Subject: [PATCH 231/394] media: bdisp: remove redundant dev_err call in bdisp_probe() There is a error message within devm_ioremap_resource already, so remove the dev_err call to avoid redundant error message. Signed-off-by: Yang Yingliang Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/sti/bdisp/bdisp-v4l2.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c index 85288da9d2ae..6413cd279125 100644 --- a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c +++ b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c @@ -1318,7 +1318,6 @@ static int bdisp_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); bdisp->regs = devm_ioremap_resource(dev, res); if (IS_ERR(bdisp->regs)) { - dev_err(dev, "failed to get regs\n"); ret = PTR_ERR(bdisp->regs); goto err_wq; } From c75f11fbe4de0d4ccba14e7125607fd5ca12e294 Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Mon, 17 May 2021 12:07:48 +0200 Subject: [PATCH 232/394] media: atmel: atmel-isc: Remove redundant assignment to i Variable i is being assigned a value however the assignment is never read, so this redundant assignment can be removed. Clean up the following clang-analyzer warning: drivers/media/platform/atmel/atmel-isc-base.c:975:2: warning: Value stored to 'i' is never read [clang-analyzer-deadcode.DeadStores]. Reported-by: Abaci Robot Signed-off-by: Jiapeng Chong Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/atmel/atmel-isc-base.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index ce8e1351fa53..a017572c870c 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -972,7 +972,6 @@ static int isc_enum_fmt_vid_cap(struct file *file, void *priv, index -= ARRAY_SIZE(controller_formats); - i = 0; supported_index = 0; for (i = 0; i < ARRAY_SIZE(formats_list); i++) { From 8610b3a2abfd0a043df91ac2754a406d7d42b207 Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Mon, 17 May 2021 12:09:20 +0200 Subject: [PATCH 233/394] media: st-delta: Remove redundant assignment to ret Variable ret is being assigned a value however the assignment is never read, so this redundant assignment can be removed. Clean up the following clang-analyzer warning: drivers/media/platform/sti/delta/delta-v4l2.c:1010:4: warning: Value stored to 'ret' is never read [clang-analyzer-deadcode.DeadStores]. Reported-by: Abaci Robot Signed-off-by: Jiapeng Chong Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/sti/delta/delta-v4l2.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/platform/sti/delta/delta-v4l2.c b/drivers/media/platform/sti/delta/delta-v4l2.c index 064a00a3084a..c887a31ebb54 100644 --- a/drivers/media/platform/sti/delta/delta-v4l2.c +++ b/drivers/media/platform/sti/delta/delta-v4l2.c @@ -1007,7 +1007,6 @@ static void delta_run_work(struct work_struct *work) dev_err(delta->dev, "%s NULL decoded frame\n", ctx->name); - ret = -EIO; goto out; } From e6001f6922cfda7b76f594595ebb38351c313da2 Mon Sep 17 00:00:00 2001 From: Evgeny Novikov Date: Mon, 17 May 2021 14:49:18 +0200 Subject: [PATCH 234/394] media: v4l: cadence: Handle errors of clk_prepare_enable() Handle errors of clk_prepare_enable() in csi2tx_get_resources(). Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Evgeny Novikov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/cadence/cdns-csi2tx.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/cadence/cdns-csi2tx.c b/drivers/media/platform/cadence/cdns-csi2tx.c index e4d08acfbb49..765ae408970a 100644 --- a/drivers/media/platform/cadence/cdns-csi2tx.c +++ b/drivers/media/platform/cadence/cdns-csi2tx.c @@ -436,6 +436,7 @@ static int csi2tx_get_resources(struct csi2tx_priv *csi2tx, struct resource *res; unsigned int i; u32 dev_cfg; + int ret; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); csi2tx->base = devm_ioremap_resource(&pdev->dev, res); @@ -454,7 +455,12 @@ static int csi2tx_get_resources(struct csi2tx_priv *csi2tx, return PTR_ERR(csi2tx->esc_clk); } - clk_prepare_enable(csi2tx->p_clk); + ret = clk_prepare_enable(csi2tx->p_clk); + if (ret) { + dev_err(&pdev->dev, "Couldn't prepare and enable p_clk\n"); + return ret; + } + dev_cfg = readl(csi2tx->base + CSI2TX_DEVICE_CONFIG_REG); clk_disable_unprepare(csi2tx->p_clk); From 0a045eac8d0427b64577a24d74bb8347c905ac65 Mon Sep 17 00:00:00 2001 From: Pavel Skripkin Date: Mon, 17 May 2021 21:18:14 +0200 Subject: [PATCH 235/394] media: zr364xx: fix memory leak in zr364xx_start_readpipe syzbot reported memory leak in zr364xx driver. The problem was in non-freed urb in case of usb_submit_urb() fail. backtrace: [] kmalloc include/linux/slab.h:561 [inline] [] usb_alloc_urb+0x66/0xe0 drivers/usb/core/urb.c:74 [] zr364xx_start_readpipe+0x78/0x130 drivers/media/usb/zr364xx/zr364xx.c:1022 [] zr364xx_board_init drivers/media/usb/zr364xx/zr364xx.c:1383 [inline] [] zr364xx_probe+0x6a3/0x851 drivers/media/usb/zr364xx/zr364xx.c:1516 [] usb_probe_interface+0x177/0x370 drivers/usb/core/driver.c:396 [] really_probe+0x159/0x500 drivers/base/dd.c:576 Fixes: ccbf035ae5de ("V4L/DVB (12278): zr364xx: implement V4L2_CAP_STREAMING") Cc: stable@vger.kernel.org Reported-by: syzbot+af4fa391ef18efdd5f69@syzkaller.appspotmail.com Signed-off-by: Pavel Skripkin Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/zr364xx/zr364xx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/usb/zr364xx/zr364xx.c b/drivers/media/usb/zr364xx/zr364xx.c index 1ef611e08323..538a330046ec 100644 --- a/drivers/media/usb/zr364xx/zr364xx.c +++ b/drivers/media/usb/zr364xx/zr364xx.c @@ -1032,6 +1032,7 @@ static int zr364xx_start_readpipe(struct zr364xx_camera *cam) DBG("submitting URB %p\n", pipe_info->stream_urb); retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL); if (retval) { + usb_free_urb(pipe_info->stream_urb); printk(KERN_ERR KBUILD_MODNAME ": start read pipe failed\n"); return retval; } From b75a44de44f4921cb84e855f54419e812badc325 Mon Sep 17 00:00:00 2001 From: Wang Qing Date: Tue, 18 May 2021 13:49:08 +0200 Subject: [PATCH 236/394] media: staging: media: zoran: fix some formatting issues fixing WARNING: Possible repeated word: 'in' as "in in a VIDIOCSFBUF ioctl", limit the number of words per line. Signed-off-by: Wang Qing Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/zoran/zoran_card.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/staging/media/zoran/zoran_card.c b/drivers/staging/media/zoran/zoran_card.c index dfc60e2e9dd7..f259585b0689 100644 --- a/drivers/staging/media/zoran/zoran_card.c +++ b/drivers/staging/media/zoran/zoran_card.c @@ -37,9 +37,10 @@ module_param_array(card, int, NULL, 0444); MODULE_PARM_DESC(card, "Card type"); /* - * The video mem address of the video card. The driver has a little database for some videocards - * to determine it from there. If your video card is not in there you have either to give it to - * the driver as a parameter or set in in a VIDIOCSFBUF ioctl + * The video mem address of the video card. The driver has a little database + * for some videocards to determine it from there. If your video card is not + * in there you have either to give it to the driver as a parameter or set + * in a VIDIOCSFBUF ioctl */ static unsigned long vidmem; /* default = 0 - Video memory base address */ From efdd0d42e27695ade6eff777bd416973a631b71c Mon Sep 17 00:00:00 2001 From: Corentin Labbe Date: Tue, 18 May 2021 14:41:09 +0200 Subject: [PATCH 237/394] media: staging: media: zoran: remove detect_guest_activity The detect_guest_activity function is no longer used, so lets removed it. [hverkuil: remove dump_guests() as well as that too is now unused] Signed-off-by: Corentin Labbe Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/zoran/zoran_device.c | 65 ---------------------- drivers/staging/media/zoran/zoran_device.h | 2 - 2 files changed, 67 deletions(-) diff --git a/drivers/staging/media/zoran/zoran_device.c b/drivers/staging/media/zoran/zoran_device.c index cf788d9cd1df..5b12a730a229 100644 --- a/drivers/staging/media/zoran/zoran_device.c +++ b/drivers/staging/media/zoran/zoran_device.c @@ -147,71 +147,6 @@ int post_office_read(struct zoran *zr, unsigned int guest, unsigned int reg) return btread(ZR36057_POR) & 0xFF; } -/* - * detect guests - */ - -static void dump_guests(struct zoran *zr) -{ - if (zr36067_debug > 2) { - int i, guest[8]; - - /* do not print random data */ - guest[0] = 0; - - for (i = 1; i < 8; i++) /* Don't read jpeg codec here */ - guest[i] = post_office_read(zr, i, 0); - - pci_info(zr->pci_dev, "Guests: %*ph\n", 8, guest); - } -} - -void detect_guest_activity(struct zoran *zr) -{ - int timeout, i, j, res, guest[8], guest0[8], change[8][3]; - ktime_t t0, t1; - - /* do not print random data */ - guest[0] = 0; - guest0[0] = 0; - - dump_guests(zr); - pci_info(zr->pci_dev, "Detecting guests activity, please wait...\n"); - for (i = 1; i < 8; i++) /* Don't read jpeg codec here */ - guest0[i] = guest[i] = post_office_read(zr, i, 0); - - timeout = 0; - j = 0; - t0 = ktime_get(); - while (timeout < 10000) { - udelay(10); - timeout++; - for (i = 1; (i < 8) && (j < 8); i++) { - res = post_office_read(zr, i, 0); - if (res != guest[i]) { - t1 = ktime_get(); - change[j][0] = ktime_to_us(ktime_sub(t1, t0)); - t0 = t1; - change[j][1] = i; - change[j][2] = res; - j++; - guest[i] = res; - } - } - if (j >= 8) - break; - } - - pci_info(zr->pci_dev, "Guests: %*ph\n", 8, guest0); - - if (j == 0) { - pci_info(zr->pci_dev, "No activity detected.\n"); - return; - } - for (i = 0; i < j; i++) - pci_info(zr->pci_dev, "%6d: %d => 0x%02x\n", change[i][0], change[i][1], change[i][2]); -} - /* * JPEG Codec access */ diff --git a/drivers/staging/media/zoran/zoran_device.h b/drivers/staging/media/zoran/zoran_device.h index 24be19a61b6d..6c5d70238228 100644 --- a/drivers/staging/media/zoran/zoran_device.h +++ b/drivers/staging/media/zoran/zoran_device.h @@ -20,8 +20,6 @@ extern int post_office_wait(struct zoran *zr); extern int post_office_write(struct zoran *zr, unsigned int guest, unsigned int reg, unsigned int value); extern int post_office_read(struct zoran *zr, unsigned int guest, unsigned int reg); -extern void detect_guest_activity(struct zoran *zr); - extern void jpeg_codec_sleep(struct zoran *zr, int sleep); extern int jpeg_codec_reset(struct zoran *zr); From 4283d387d9cbf5deb464675e050b17f34a9a8c02 Mon Sep 17 00:00:00 2001 From: Corentin Labbe Date: Tue, 18 May 2021 14:41:10 +0200 Subject: [PATCH 238/394] media: staging: media: zoran: multiple assignments should be avoided Remove all multiple assignments. Signed-off-by: Corentin Labbe Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/zoran/zoran_driver.c | 6 ++++-- drivers/staging/media/zoran/zr36016.c | 3 ++- drivers/staging/media/zoran/zr36050.c | 3 ++- drivers/staging/media/zoran/zr36060.c | 3 ++- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/staging/media/zoran/zoran_driver.c b/drivers/staging/media/zoran/zoran_driver.c index e8902f824d6c..46382e43f1bf 100644 --- a/drivers/staging/media/zoran/zoran_driver.c +++ b/drivers/staging/media/zoran/zoran_driver.c @@ -678,12 +678,14 @@ static int zoran_g_selection(struct file *file, void *__fh, struct v4l2_selectio sel->r.height = zr->jpg_settings.img_height; break; case V4L2_SEL_TGT_CROP_DEFAULT: - sel->r.top = sel->r.left = 0; + sel->r.top = 0; + sel->r.left = 0; sel->r.width = BUZ_MIN_WIDTH; sel->r.height = BUZ_MIN_HEIGHT; break; case V4L2_SEL_TGT_CROP_BOUNDS: - sel->r.top = sel->r.left = 0; + sel->r.top = 0; + sel->r.left = 0; sel->r.width = BUZ_MAX_WIDTH; sel->r.height = BUZ_MAX_HEIGHT; break; diff --git a/drivers/staging/media/zoran/zr36016.c b/drivers/staging/media/zoran/zr36016.c index 2d7dc7abde79..82702a13b05f 100644 --- a/drivers/staging/media/zoran/zr36016.c +++ b/drivers/staging/media/zoran/zr36016.c @@ -361,7 +361,8 @@ static int zr36016_setup(struct videocodec *codec) return -ENOSPC; } //mem structure init - codec->data = ptr = kzalloc(sizeof(struct zr36016), GFP_KERNEL); + ptr = kzalloc(sizeof(struct zr36016), GFP_KERNEL); + codec->data = ptr; if (!ptr) return -ENOMEM; diff --git a/drivers/staging/media/zoran/zr36050.c b/drivers/staging/media/zoran/zr36050.c index 2826f4e5d37b..a78862852a47 100644 --- a/drivers/staging/media/zoran/zr36050.c +++ b/drivers/staging/media/zoran/zr36050.c @@ -754,7 +754,8 @@ static int zr36050_setup(struct videocodec *codec) return -ENOSPC; } //mem structure init - codec->data = ptr = kzalloc(sizeof(struct zr36050), GFP_KERNEL); + ptr = kzalloc(sizeof(struct zr36050), GFP_KERNEL); + codec->data = ptr; if (!ptr) return -ENOMEM; diff --git a/drivers/staging/media/zoran/zr36060.c b/drivers/staging/media/zoran/zr36060.c index 4f9eb9ff2c42..1c3af11b5f24 100644 --- a/drivers/staging/media/zoran/zr36060.c +++ b/drivers/staging/media/zoran/zr36060.c @@ -790,7 +790,8 @@ static int zr36060_setup(struct videocodec *codec) return -ENOSPC; } //mem structure init - codec->data = ptr = kzalloc(sizeof(*ptr), GFP_KERNEL); + ptr = kzalloc(sizeof(*ptr), GFP_KERNEL); + codec->data = ptr; if (!ptr) return -ENOMEM; From 87c5d693f94975a262fa891fbc944957ea041603 Mon Sep 17 00:00:00 2001 From: Corentin Labbe Date: Tue, 18 May 2021 14:41:11 +0200 Subject: [PATCH 239/394] media: staging: media: zoran: remove blank line Minor style fix by removing useless blank line. Signed-off-by: Corentin Labbe Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/zoran/zoran.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/media/zoran/zoran.h b/drivers/staging/media/zoran/zoran.h index e7fe8da7732c..b1ad2a2b914c 100644 --- a/drivers/staging/media/zoran/zoran.h +++ b/drivers/staging/media/zoran/zoran.h @@ -158,7 +158,6 @@ struct zoran_jpg_settings { struct v4l2_jpegcompression jpg_comp; /* JPEG-specific capture settings */ }; - struct zoran; /* zoran_fh contains per-open() settings */ From b8c8c4959ce372820575f28981b7a033243363e5 Mon Sep 17 00:00:00 2001 From: Corentin Labbe Date: Tue, 18 May 2021 14:41:12 +0200 Subject: [PATCH 240/394] media: staging: media: zoran: fix kzalloc style Prefer kzalloc(sizeof(*prt)...) over kzalloc(sizeof(struct.../ Signed-off-by: Corentin Labbe Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/zoran/zr36016.c | 2 +- drivers/staging/media/zoran/zr36050.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/zoran/zr36016.c b/drivers/staging/media/zoran/zr36016.c index 82702a13b05f..9b350a885879 100644 --- a/drivers/staging/media/zoran/zr36016.c +++ b/drivers/staging/media/zoran/zr36016.c @@ -361,7 +361,7 @@ static int zr36016_setup(struct videocodec *codec) return -ENOSPC; } //mem structure init - ptr = kzalloc(sizeof(struct zr36016), GFP_KERNEL); + ptr = kzalloc(sizeof(*ptr), GFP_KERNEL); codec->data = ptr; if (!ptr) return -ENOMEM; diff --git a/drivers/staging/media/zoran/zr36050.c b/drivers/staging/media/zoran/zr36050.c index a78862852a47..8bb101fa18bc 100644 --- a/drivers/staging/media/zoran/zr36050.c +++ b/drivers/staging/media/zoran/zr36050.c @@ -754,7 +754,7 @@ static int zr36050_setup(struct videocodec *codec) return -ENOSPC; } //mem structure init - ptr = kzalloc(sizeof(struct zr36050), GFP_KERNEL); + ptr = kzalloc(sizeof(*ptr), GFP_KERNEL); codec->data = ptr; if (!ptr) return -ENOMEM; From 5ef8a20af18716f97875714a32266256f6aa6f60 Mon Sep 17 00:00:00 2001 From: Corentin Labbe Date: Tue, 18 May 2021 14:41:13 +0200 Subject: [PATCH 241/394] media: staging: media: zoran: change asm header As asked by checkpatch, convert a asm/xxx header to a linux one. Signed-off-by: Corentin Labbe Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/zoran/zr36050.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/media/zoran/zr36050.c b/drivers/staging/media/zoran/zr36050.c index 8bb101fa18bc..c62af27f2683 100644 --- a/drivers/staging/media/zoran/zr36050.c +++ b/drivers/staging/media/zoran/zr36050.c @@ -16,7 +16,7 @@ #include /* I/O commands, error codes */ -#include +#include /* headerfile of this module */ #include "zr36050.h" From cca65f64045523f923380171bf6d329bfd79970f Mon Sep 17 00:00:00 2001 From: Evgeny Novikov Date: Tue, 18 May 2021 20:57:22 +0200 Subject: [PATCH 242/394] media: v4l: cadence: Handle errors of clk_prepare_enable() Handle errors of clk_prepare_enable() in csi2rx_get_resources(). Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Evgeny Novikov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/cadence/cdns-csi2rx.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c index c68a3eac62cd..f2b4ddd31177 100644 --- a/drivers/media/platform/cadence/cdns-csi2rx.c +++ b/drivers/media/platform/cadence/cdns-csi2rx.c @@ -282,6 +282,7 @@ static int csi2rx_get_resources(struct csi2rx_priv *csi2rx, struct resource *res; unsigned char i; u32 dev_cfg; + int ret; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); csi2rx->base = devm_ioremap_resource(&pdev->dev, res); @@ -315,7 +316,12 @@ static int csi2rx_get_resources(struct csi2rx_priv *csi2rx, return -EINVAL; } - clk_prepare_enable(csi2rx->p_clk); + ret = clk_prepare_enable(csi2rx->p_clk); + if (ret) { + dev_err(&pdev->dev, "Couldn't prepare and enable P clock\n"); + return ret; + } + dev_cfg = readl(csi2rx->base + CSI2RX_DEVICE_CFG_REG); clk_disable_unprepare(csi2rx->p_clk); From b7fdd208687ba59ebfb09b2199596471c63b69e3 Mon Sep 17 00:00:00 2001 From: Evgeny Novikov Date: Wed, 19 May 2021 14:04:49 +0200 Subject: [PATCH 243/394] media: st-hva: Fix potential NULL pointer dereferences When ctx_id >= HVA_MAX_INSTANCES in hva_hw_its_irq_thread() it tries to access fields of ctx that is NULL at that point. The patch gets rid of these accesses. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Evgeny Novikov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/sti/hva/hva-hw.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/platform/sti/hva/hva-hw.c b/drivers/media/platform/sti/hva/hva-hw.c index 77b8bfa5e0c5..30fb1aa4a351 100644 --- a/drivers/media/platform/sti/hva/hva-hw.c +++ b/drivers/media/platform/sti/hva/hva-hw.c @@ -130,8 +130,7 @@ static irqreturn_t hva_hw_its_irq_thread(int irq, void *arg) ctx_id = (hva->sts_reg & 0xFF00) >> 8; if (ctx_id >= HVA_MAX_INSTANCES) { dev_err(dev, "%s %s: bad context identifier: %d\n", - ctx->name, __func__, ctx_id); - ctx->hw_err = true; + HVA_PREFIX, __func__, ctx_id); goto out; } From 99c2caa64580f999f4552eaeb3ed6f6c5f172d93 Mon Sep 17 00:00:00 2001 From: Herman Date: Thu, 20 May 2021 11:35:53 +0200 Subject: [PATCH 244/394] media: drivers/media/usb/em28xx/em28xx-cards.c : fix typo issues change 'Configuare' into 'Configure' change 'Configuared' into 'Configured' Signed-off-by: Herman Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-cards.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index ba9292e2a587..c1e0dccb7408 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -4065,15 +4065,15 @@ static int em28xx_usb_probe(struct usb_interface *intf, dev->dev_next->dvb_max_pkt_size_isoc = dev->dvb_max_pkt_size_isoc_ts2; dev->dev_next->dvb_alt_isoc = dev->dvb_alt_isoc; - /* Configuare hardware to support TS2*/ + /* Configure hardware to support TS2*/ if (dev->dvb_xfer_bulk) { - /* The ep4 and ep5 are configuared for BULK */ + /* The ep4 and ep5 are configured for BULK */ em28xx_write_reg(dev, 0x0b, 0x96); mdelay(100); em28xx_write_reg(dev, 0x0b, 0x80); mdelay(100); } else { - /* The ep4 and ep5 are configuared for ISO */ + /* The ep4 and ep5 are configured for ISO */ em28xx_write_reg(dev, 0x0b, 0x96); mdelay(100); em28xx_write_reg(dev, 0x0b, 0x82); From 66933f4b90ddd8abaa2e123e09c51ecc25331b40 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 20 May 2021 18:02:49 +0200 Subject: [PATCH 245/394] media: hantro: test the correct variable in probe() This should be testing "vpu->clocks[0].clk" instead of "vpu->clocks". Fixes: eb4cacdfb998 ("media: hantro: add fallback handling for single irq/clk") Signed-off-by: Dan Carpenter Reviewed-by: Emil Velikov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/hantro/hantro_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c index 2f6b01c7a6a0..4914987cfd9d 100644 --- a/drivers/staging/media/hantro/hantro_drv.c +++ b/drivers/staging/media/hantro/hantro_drv.c @@ -783,8 +783,8 @@ static int hantro_probe(struct platform_device *pdev) * actual name in the DT bindings. */ vpu->clocks[0].clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(vpu->clocks)) - return PTR_ERR(vpu->clocks); + if (IS_ERR(vpu->clocks[0].clk)) + return PTR_ERR(vpu->clocks[0].clk); } num_bases = vpu->variant->num_regs ?: 1; From 6d0aac74e1e28691e355a7a40bd5961d495982a2 Mon Sep 17 00:00:00 2001 From: Herman Date: Fri, 21 May 2021 04:14:57 +0200 Subject: [PATCH 246/394] media: drivers/media/platform/Rcar_jpu.c : fix typo issues change 'requerment' into 'requirement' change 'quantanization' into 'quantization' change 'qantization' into 'quantization' Signed-off-by: Herman Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/rcar_jpu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/rcar_jpu.c b/drivers/media/platform/rcar_jpu.c index a7c198c17deb..f57158bf2b11 100644 --- a/drivers/media/platform/rcar_jpu.c +++ b/drivers/media/platform/rcar_jpu.c @@ -42,7 +42,7 @@ /* * Align JPEG header end to cache line to make sure we will not have any issues - * with cache; additionally to requerment (33.3.27 R01UH0501EJ0100 Rev.1.00) + * with cache; additionally to requirement (33.3.27 R01UH0501EJ0100 Rev.1.00) */ #define JPU_JPEG_HDR_SIZE (ALIGN(0x258, L1_CACHE_BYTES)) #define JPU_JPEG_MAX_BYTES_PER_PIXEL 2 /* 16 bit precision format */ @@ -121,7 +121,7 @@ #define JCCMD_JEND (1 << 2) #define JCCMD_JSRT (1 << 0) -/* JPEG code quantanization table number register */ +/* JPEG code quantization table number register */ #define JCQTN 0x0c #define JCQTN_SHIFT(t) (((t) - 1) << 1) @@ -1644,7 +1644,7 @@ static int jpu_probe(struct platform_device *pdev) goto device_register_rollback; } - /* fill in qantization and Huffman tables for encoder */ + /* fill in quantization and Huffman tables for encoder */ for (i = 0; i < JPU_MAX_QUALITY; i++) jpu_generate_hdr(i, (unsigned char *)jpeg_hdrs[i]); From bf950fdc71fe756ea6407f2cbf6ce051b8f5ea07 Mon Sep 17 00:00:00 2001 From: Herman Date: Fri, 21 May 2021 10:36:29 +0200 Subject: [PATCH 247/394] media: drivers/media/usb/gspca/cpia1.c : fix spelling typo change 'then' into 'than' Signed-off-by: Herman Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/gspca/cpia1.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/media/usb/gspca/cpia1.c b/drivers/media/usb/gspca/cpia1.c index d93d384286c1..46ed95483e22 100644 --- a/drivers/media/usb/gspca/cpia1.c +++ b/drivers/media/usb/gspca/cpia1.c @@ -365,8 +365,9 @@ struct sd { static const struct v4l2_pix_format mode[] = { {160, 120, V4L2_PIX_FMT_CPIA1, V4L2_FIELD_NONE, /* The sizeimage is trial and error, as with low framerates - the camera will pad out usb frames, making the image - data larger then strictly necessary */ + * the camera will pad out usb frames, making the image + * data larger than strictly necessary + */ .bytesperline = 160, .sizeimage = 65536, .colorspace = V4L2_COLORSPACE_SRGB, From d170ebb00472268410dce80ae4834c98e79315da Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 21 May 2021 10:45:44 +0200 Subject: [PATCH 248/394] media: uapi/linux/cec-funcs.h: set delay to 1 if unnused If the audio_out_delay value is unused, then set it to 1, not 0. The value 0 is reserved, and 1 is a much safer value since it translates to a delay of (1 - 1) * 2 = 0 ms. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/cec-funcs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/uapi/linux/cec-funcs.h b/include/uapi/linux/cec-funcs.h index 37590027b604..c3baaea0b8ef 100644 --- a/include/uapi/linux/cec-funcs.h +++ b/include/uapi/linux/cec-funcs.h @@ -1665,7 +1665,7 @@ static inline void cec_ops_report_current_latency(const struct cec_msg *msg, if (*audio_out_compensated == 3 && msg->len >= 7) *audio_out_delay = msg->msg[6]; else - *audio_out_delay = 0; + *audio_out_delay = 1; } static inline void cec_msg_request_current_latency(struct cec_msg *msg, From ce67eaca95f8ab5c6aae41a10adfe9a6e8efa58c Mon Sep 17 00:00:00 2001 From: Joe Richey Date: Fri, 21 May 2021 10:58:46 +0200 Subject: [PATCH 249/394] media: vicodec: Use _BITUL() macro in UAPI headers Replace BIT() in v4l2's UPAI header with _BITUL(). BIT() is not defined in the UAPI headers and its usage may cause userspace build errors. Fixes: 206bc0f6fb94 ("media: vicodec: mark the stateless FWHT API as stable") Signed-off-by: Joe Richey Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/v4l2-controls.h | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h index f96bea19c991..fdf97a6d7d18 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h @@ -50,6 +50,7 @@ #ifndef __LINUX_V4L2_CONTROLS_H #define __LINUX_V4L2_CONTROLS_H +#include #include /* Control classes */ @@ -1602,30 +1603,30 @@ struct v4l2_ctrl_h264_decode_params { #define V4L2_FWHT_VERSION 3 /* Set if this is an interlaced format */ -#define V4L2_FWHT_FL_IS_INTERLACED BIT(0) +#define V4L2_FWHT_FL_IS_INTERLACED _BITUL(0) /* Set if this is a bottom-first (NTSC) interlaced format */ -#define V4L2_FWHT_FL_IS_BOTTOM_FIRST BIT(1) +#define V4L2_FWHT_FL_IS_BOTTOM_FIRST _BITUL(1) /* Set if each 'frame' contains just one field */ -#define V4L2_FWHT_FL_IS_ALTERNATE BIT(2) +#define V4L2_FWHT_FL_IS_ALTERNATE _BITUL(2) /* * If V4L2_FWHT_FL_IS_ALTERNATE was set, then this is set if this * 'frame' is the bottom field, else it is the top field. */ -#define V4L2_FWHT_FL_IS_BOTTOM_FIELD BIT(3) +#define V4L2_FWHT_FL_IS_BOTTOM_FIELD _BITUL(3) /* Set if the Y' plane is uncompressed */ -#define V4L2_FWHT_FL_LUMA_IS_UNCOMPRESSED BIT(4) +#define V4L2_FWHT_FL_LUMA_IS_UNCOMPRESSED _BITUL(4) /* Set if the Cb plane is uncompressed */ -#define V4L2_FWHT_FL_CB_IS_UNCOMPRESSED BIT(5) +#define V4L2_FWHT_FL_CB_IS_UNCOMPRESSED _BITUL(5) /* Set if the Cr plane is uncompressed */ -#define V4L2_FWHT_FL_CR_IS_UNCOMPRESSED BIT(6) +#define V4L2_FWHT_FL_CR_IS_UNCOMPRESSED _BITUL(6) /* Set if the chroma plane is full height, if cleared it is half height */ -#define V4L2_FWHT_FL_CHROMA_FULL_HEIGHT BIT(7) +#define V4L2_FWHT_FL_CHROMA_FULL_HEIGHT _BITUL(7) /* Set if the chroma plane is full width, if cleared it is half width */ -#define V4L2_FWHT_FL_CHROMA_FULL_WIDTH BIT(8) +#define V4L2_FWHT_FL_CHROMA_FULL_WIDTH _BITUL(8) /* Set if the alpha plane is uncompressed */ -#define V4L2_FWHT_FL_ALPHA_IS_UNCOMPRESSED BIT(9) +#define V4L2_FWHT_FL_ALPHA_IS_UNCOMPRESSED _BITUL(9) /* Set if this is an I Frame */ -#define V4L2_FWHT_FL_I_FRAME BIT(10) +#define V4L2_FWHT_FL_I_FRAME _BITUL(10) /* A 4-values flag - the number of components - 1 */ #define V4L2_FWHT_FL_COMPONENTS_NUM_MSK GENMASK(18, 16) From 8c8b9a9be2afa8bd6a72ad1130532baab9fab89d Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 21 May 2021 15:28:38 +0200 Subject: [PATCH 250/394] media: dtv5100: fix control-request directions The direction of the pipe argument must match the request-type direction bit or control requests may fail depending on the host-controller-driver implementation. Fix the control requests which erroneously used usb_rcvctrlpipe(). Fixes: 8466028be792 ("V4L/DVB (8734): Initial support for AME DTV-5100 USB2.0 DVB-T") Cc: stable@vger.kernel.org # 2.6.28 Signed-off-by: Johan Hovold Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb/dtv5100.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/media/usb/dvb-usb/dtv5100.c b/drivers/media/usb/dvb-usb/dtv5100.c index fba06932a9e0..1c13e493322c 100644 --- a/drivers/media/usb/dvb-usb/dtv5100.c +++ b/drivers/media/usb/dvb-usb/dtv5100.c @@ -26,6 +26,7 @@ static int dtv5100_i2c_msg(struct dvb_usb_device *d, u8 addr, u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen) { struct dtv5100_state *st = d->priv; + unsigned int pipe; u8 request; u8 type; u16 value; @@ -34,6 +35,7 @@ static int dtv5100_i2c_msg(struct dvb_usb_device *d, u8 addr, switch (wlen) { case 1: /* write { reg }, read { value } */ + pipe = usb_rcvctrlpipe(d->udev, 0); request = (addr == DTV5100_DEMOD_ADDR ? DTV5100_DEMOD_READ : DTV5100_TUNER_READ); type = USB_TYPE_VENDOR | USB_DIR_IN; @@ -41,6 +43,7 @@ static int dtv5100_i2c_msg(struct dvb_usb_device *d, u8 addr, break; case 2: /* write { reg, value } */ + pipe = usb_sndctrlpipe(d->udev, 0); request = (addr == DTV5100_DEMOD_ADDR ? DTV5100_DEMOD_WRITE : DTV5100_TUNER_WRITE); type = USB_TYPE_VENDOR | USB_DIR_OUT; @@ -54,7 +57,7 @@ static int dtv5100_i2c_msg(struct dvb_usb_device *d, u8 addr, memcpy(st->data, rbuf, rlen); msleep(1); /* avoid I2C errors */ - return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), request, + return usb_control_msg(d->udev, pipe, request, type, value, index, st->data, rlen, DTV5100_USB_TIMEOUT); } @@ -141,7 +144,7 @@ static int dtv5100_probe(struct usb_interface *intf, /* initialize non qt1010/zl10353 part? */ for (i = 0; dtv5100_init[i].request; i++) { - ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), dtv5100_init[i].request, USB_TYPE_VENDOR | USB_DIR_OUT, dtv5100_init[i].value, From 53ae298fde7adcc4b1432bce2dbdf8dac54dfa72 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 21 May 2021 15:28:39 +0200 Subject: [PATCH 251/394] media: gspca/sq905: fix control-request direction The direction of the pipe argument must match the request-type direction bit or control requests may fail depending on the host-controller-driver implementation. Fix the USB_REQ_SYNCH_FRAME request which erroneously used usb_sndctrlpipe(). Fixes: 27d35fc3fb06 ("V4L/DVB (10639): gspca - sq905: New subdriver.") Cc: stable@vger.kernel.org # 2.6.30 Signed-off-by: Johan Hovold Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/gspca/sq905.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/usb/gspca/sq905.c b/drivers/media/usb/gspca/sq905.c index 949111070971..32504ebcfd4d 100644 --- a/drivers/media/usb/gspca/sq905.c +++ b/drivers/media/usb/gspca/sq905.c @@ -116,7 +116,7 @@ static int sq905_command(struct gspca_dev *gspca_dev, u16 index) } ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), + usb_rcvctrlpipe(gspca_dev->dev, 0), USB_REQ_SYNCH_FRAME, /* request */ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, SQ905_PING, 0, gspca_dev->usb_buf, 1, From 5eabfbdd7d6a473afbbd4916877ee04801ca2c45 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Sat, 22 May 2021 05:19:11 +0200 Subject: [PATCH 252/394] media: staging: media: tegra-vde: add missing error return code in tegra_vde_probe() Add missing return error code when pm_runtime_resume_and_get() failed. Fixes: dc8276b78917 ("staging: media: tegra-vde: use pm_runtime_resume_and_get()") Reported-by: Hulk Robot Signed-off-by: Yang Yingliang Reviewed-by: Dmitry Osipenko Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/tegra-vde/vde.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/media/tegra-vde/vde.c b/drivers/staging/media/tegra-vde/vde.c index e025b69776f2..ed4c1250b303 100644 --- a/drivers/staging/media/tegra-vde/vde.c +++ b/drivers/staging/media/tegra-vde/vde.c @@ -1071,7 +1071,8 @@ static int tegra_vde_probe(struct platform_device *pdev) * power-cycle it in order to put hardware into a predictable lower * power state. */ - if (pm_runtime_resume_and_get(dev) < 0) + err = pm_runtime_resume_and_get(dev); + if (err) goto err_pm_runtime; pm_runtime_put(dev); From 8ed339f23d41e21660a389adf2e7b2966d457ff6 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 24 May 2021 13:09:18 +0200 Subject: [PATCH 253/394] media: gspca/gl860: fix zero-length control requests The direction of the pipe argument must match the request-type direction bit or control requests may fail depending on the host-controller-driver implementation. Control transfers without a data stage are treated as OUT requests by the USB stack and should be using usb_sndctrlpipe(). Failing to do so will now trigger a warning. Fix the gl860_RTx() helper so that zero-length control reads fail with an error message instead. Note that there are no current callers that would trigger this. Fixes: 4f7cb8837cec ("V4L/DVB (12954): gspca - gl860: Addition of GL860 based webcams") Signed-off-by: Johan Hovold Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/gspca/gl860/gl860.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/usb/gspca/gl860/gl860.c b/drivers/media/usb/gspca/gl860/gl860.c index 2c05ea2598e7..ce4ee8bc75c8 100644 --- a/drivers/media/usb/gspca/gl860/gl860.c +++ b/drivers/media/usb/gspca/gl860/gl860.c @@ -561,8 +561,8 @@ int gl860_RTx(struct gspca_dev *gspca_dev, len, 400 + 200 * (len > 1)); memcpy(pdata, gspca_dev->usb_buf, len); } else { - r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - req, pref, val, index, NULL, len, 400); + gspca_err(gspca_dev, "zero-length read request\n"); + r = -EINVAL; } } From b4bb4d425b7b02424afea2dfdcd77b3b4794175e Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 24 May 2021 13:09:19 +0200 Subject: [PATCH 254/394] media: gspca/sunplus: fix zero-length control requests The direction of the pipe argument must match the request-type direction bit or control requests may fail depending on the host-controller-driver implementation. Control transfers without a data stage are treated as OUT requests by the USB stack and should be using usb_sndctrlpipe(). Failing to do so will now trigger a warning. Fix the single zero-length control request which was using the read-register helper, and update the helper so that zero-length reads fail with an error message instead. Fixes: 6a7eba24e4f0 ("V4L/DVB (8157): gspca: all subdrivers") Cc: stable@vger.kernel.org # 2.6.27 Signed-off-by: Johan Hovold Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/gspca/sunplus.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/media/usb/gspca/sunplus.c b/drivers/media/usb/gspca/sunplus.c index ace3da40006e..971dee0a56da 100644 --- a/drivers/media/usb/gspca/sunplus.c +++ b/drivers/media/usb/gspca/sunplus.c @@ -242,6 +242,10 @@ static void reg_r(struct gspca_dev *gspca_dev, gspca_err(gspca_dev, "reg_r: buffer overflow\n"); return; } + if (len == 0) { + gspca_err(gspca_dev, "reg_r: zero-length read\n"); + return; + } if (gspca_dev->usb_err < 0) return; ret = usb_control_msg(gspca_dev->dev, @@ -250,7 +254,7 @@ static void reg_r(struct gspca_dev *gspca_dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, /* value */ index, - len ? gspca_dev->usb_buf : NULL, len, + gspca_dev->usb_buf, len, 500); if (ret < 0) { pr_err("reg_r err %d\n", ret); @@ -727,7 +731,7 @@ static int sd_start(struct gspca_dev *gspca_dev) case MegaImageVI: reg_w_riv(gspca_dev, 0xf0, 0, 0); spca504B_WaitCmdStatus(gspca_dev); - reg_r(gspca_dev, 0xf0, 4, 0); + reg_w_riv(gspca_dev, 0xf0, 4, 0); spca504B_WaitCmdStatus(gspca_dev); break; default: From 25d5ce3a606a1eb23a9265d615a92a876ff9cb5f Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 24 May 2021 13:09:20 +0200 Subject: [PATCH 255/394] media: rtl28xxu: fix zero-length control request The direction of the pipe argument must match the request-type direction bit or control requests may fail depending on the host-controller-driver implementation. Control transfers without a data stage are treated as OUT requests by the USB stack and should be using usb_sndctrlpipe(). Failing to do so will now trigger a warning. Fix the zero-length i2c-read request used for type detection by attempting to read a single byte instead. Reported-by: syzbot+faf11bbadc5a372564da@syzkaller.appspotmail.com Fixes: d0f232e823af ("[media] rtl28xxu: add heuristic to detect chip type") Cc: stable@vger.kernel.org # 4.0 Cc: Antti Palosaari Signed-off-by: Johan Hovold Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index 97ed17a141bb..2c04ed8af0e4 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c @@ -612,8 +612,9 @@ static int rtl28xxu_read_config(struct dvb_usb_device *d) static int rtl28xxu_identify_state(struct dvb_usb_device *d, const char **name) { struct rtl28xxu_dev *dev = d_to_priv(d); + u8 buf[1]; int ret; - struct rtl28xxu_req req_demod_i2c = {0x0020, CMD_I2C_DA_RD, 0, NULL}; + struct rtl28xxu_req req_demod_i2c = {0x0020, CMD_I2C_DA_RD, 1, buf}; dev_dbg(&d->intf->dev, "\n"); From 80daed70c6dcc79f5ef36b98157062b0f3522732 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Mon, 24 May 2021 15:35:51 +0200 Subject: [PATCH 256/394] media: imx: imx7_mipi_csis: Fix error return code in mipi_csis_async_register() Fix to return negative error code -EINVAL from the error handling case instead of 0, as done elsewhere in this function. Fixes: 88fc81388df9 ("media: imx: imx7_mipi_csis: Reject invalid data-lanes settings") Reported-by: Hulk Robot Signed-off-by: Wei Yongjun Acked-by: Rui Miguel Silva Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/imx7-mipi-csis.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c index d573f3475d28..9cd3c86fee58 100644 --- a/drivers/staging/media/imx/imx7-mipi-csis.c +++ b/drivers/staging/media/imx/imx7-mipi-csis.c @@ -1175,6 +1175,7 @@ static int mipi_csis_async_register(struct csi_state *state) if (vep.bus.mipi_csi2.data_lanes[i] != i + 1) { dev_err(state->dev, "data lanes reordering is not supported"); + ret = -EINVAL; goto err_parse; } } From 35037eab4acae8c2d01612d906d479f7006a733c Mon Sep 17 00:00:00 2001 From: lijian Date: Tue, 25 May 2021 11:41:48 +0200 Subject: [PATCH 257/394] media: v4l2-dev.c: Modified the macro SET_VALID_IOCTL Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects. So modified the macro SET_VALID_IOCTL with do - while loop. [hverkuil: checkpatch: add parenthesis around 'ops'] Signed-off-by: lijian Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-dev.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index 4aa8fcd674d7..d03ace324db0 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -518,9 +518,8 @@ static int get_index(struct video_device *vdev) return find_first_zero_bit(used, VIDEO_NUM_DEVICES); } -#define SET_VALID_IOCTL(ops, cmd, op) \ - if (ops->op) \ - set_bit(_IOC_NR(cmd), valid_ioctls) +#define SET_VALID_IOCTL(ops, cmd, op) \ + do { if ((ops)->op) set_bit(_IOC_NR(cmd), valid_ioctls); } while (0) /* This determines which ioctls are actually implemented in the driver. It's a one-time thing which simplifies video_ioctl2 as it can just do From 2bcfc81147b9266a521e5cfe2d9abbf64a2ceef4 Mon Sep 17 00:00:00 2001 From: lijian Date: Wed, 26 May 2021 11:47:12 +0200 Subject: [PATCH 258/394] media: videobuf-dma-sg: void function return statements are not generally useful void function videobuf_vm_close return statements are not generally useful, so deleted the return in function videobuf_vm_close(). Signed-off-by: lijian Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/videobuf-dma-sg.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/v4l2-core/videobuf-dma-sg.c b/drivers/media/v4l2-core/videobuf-dma-sg.c index 8dd0562de287..f75e5eedeee0 100644 --- a/drivers/media/v4l2-core/videobuf-dma-sg.c +++ b/drivers/media/v4l2-core/videobuf-dma-sg.c @@ -423,7 +423,6 @@ static void videobuf_vm_close(struct vm_area_struct *vma) videobuf_queue_unlock(q); kfree(map); } - return; } /* From 98b9c7890b2d74d2f5342ef23d12c4bcbbec54bf Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 2 Jun 2021 15:06:12 +0200 Subject: [PATCH 259/394] docs: admin-guide: media: ipu3.rst: replace some characters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The conversion tools used during DocBook/LaTeX/html/Markdown->ReST conversion and some cut-and-pasted text contain some characters that aren't easily reachable on standard keyboards and/or could cause troubles when parsed by the documentation build system. Replace the occurences of the following characters: - U+201c ('“'): LEFT DOUBLE QUOTATION MARK - U+201d ('”'): RIGHT DOUBLE QUOTATION MARK Signed-off-by: Mauro Carvalho Chehab --- Documentation/admin-guide/media/ipu3.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/admin-guide/media/ipu3.rst b/Documentation/admin-guide/media/ipu3.rst index d6454f637ff4..52c1c04173da 100644 --- a/Documentation/admin-guide/media/ipu3.rst +++ b/Documentation/admin-guide/media/ipu3.rst @@ -244,7 +244,7 @@ output larger bayer frame for further YUV processing than "VIDEO" mode to get high quality images. Besides, "STILL" mode need XNR3 to do noise reduction, hence "STILL" mode will need more power and memory bandwidth than "VIDEO" mode. TNR will be enabled in "VIDEO" mode and bypassed by "STILL" mode. ImgU is -running at “VIDEO” mode by default, the user can use v4l2 control +running at "VIDEO" mode by default, the user can use v4l2 control V4L2_CID_INTEL_IPU3_MODE (currently defined in drivers/staging/media/ipu3/include/uapi/intel-ipu3.h) to query and set the running mode. For user, there is no difference for buffer queueing between the From 9df4827523bdc4032b1021395e8ee6f880d1e8b1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 2 Jun 2021 15:06:43 +0200 Subject: [PATCH 260/394] docs: driver-api: media: zoran: replace SOFT HYPHEN character MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the occurences of the following character: - U+00ad ('­'): SOFT HYPHEN as ASCII HYPHEN is preferred over SOFT HYPHEN At least with some fonts, a SOFT HYPHEN is displayed as a blank space. Signed-off-by: Mauro Carvalho Chehab --- Documentation/driver-api/media/drivers/zoran.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/driver-api/media/drivers/zoran.rst b/Documentation/driver-api/media/drivers/zoran.rst index 83cbae9cedef..b205e10c3154 100644 --- a/Documentation/driver-api/media/drivers/zoran.rst +++ b/Documentation/driver-api/media/drivers/zoran.rst @@ -319,7 +319,7 @@ Conexant bt866 TV encoder ~~~~~~~~~~~~~~~~~~~~~~~~~ - is used in AVS6EYES, and -- can generate: NTSC/PAL, PAL­M, PAL­N +- can generate: NTSC/PAL, PAL-M, PAL-N The adv717x, should be able to produce PAL N. But you find nothing PAL N specific in the registers. Seem that you have to reuse a other standard From d4a84f86e9169e07595dd399c42bc7728d077531 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 2 Jun 2021 15:12:17 +0200 Subject: [PATCH 261/394] docs: userspace-api: media: fdl-appendix.rst: replace some characters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The conversion tools used during DocBook/LaTeX/html/Markdown->ReST conversion and some cut-and-pasted text contain some characters that aren't easily reachable on standard keyboards and/or could cause troubles when parsed by the documentation build system. Replace the occurences of the following characters: - U+201c ('“'): LEFT DOUBLE QUOTATION MARK - U+201d ('”'): RIGHT DOUBLE QUOTATION MARK Signed-off-by: Mauro Carvalho Chehab --- .../userspace-api/media/fdl-appendix.rst | 64 +++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/Documentation/userspace-api/media/fdl-appendix.rst b/Documentation/userspace-api/media/fdl-appendix.rst index 683ebed87017..b1bc725b4ec7 100644 --- a/Documentation/userspace-api/media/fdl-appendix.rst +++ b/Documentation/userspace-api/media/fdl-appendix.rst @@ -13,14 +13,14 @@ GNU Free Documentation License =========== The purpose of this License is to make a manual, textbook, or other -written document “free” in the sense of freedom: to assure everyone the +written document "free" in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others. -This License is a kind of “copyleft”, which means that derivative works +This License is a kind of "copyleft", which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software. @@ -44,21 +44,21 @@ works whose purpose is instruction or reference. This License applies to any manual or other work that contains a notice placed by the copyright holder saying it can be distributed under the -terms of this License. The “Document”, below, refers to any such manual +terms of this License. The "Document", below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as -“you”. +"you". .. _fdl-modified: -A “Modified Version” of the Document means any work containing the +A "Modified Version" of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language. .. _fdl-secondary: -A “Secondary Section” is a named appendix or a front-matter section of +A "Secondary Section" is a named appendix or a front-matter section of the :ref:`Document ` that deals exclusively with the relationship of the publishers or authors of the Document to the Document's overall subject (or to related matters) and contains nothing @@ -72,7 +72,7 @@ regarding them. .. _fdl-invariant: -The “Invariant Sections” are certain +The "Invariant Sections" are certain :ref:`Secondary Sections ` whose titles are designated, as being those of Invariant Sections, in the notice that says that the :ref:`Document ` is released under this License. @@ -80,14 +80,14 @@ as being those of Invariant Sections, in the notice that says that the .. _fdl-cover-texts: -The “Cover Texts” are certain short passages of text that are listed, as +The "Cover Texts" are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the :ref:`Document ` is released under this License. .. _fdl-transparent: -A “Transparent” copy of the :ref:`Document ` means a +A "Transparent" copy of the :ref:`Document ` means a machine-readable copy, represented in a format whose specification is available to the general public, whose contents can be viewed and edited directly and straightforwardly with generic text editors or (for images @@ -97,7 +97,7 @@ formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup has been designed to thwart or discourage subsequent modification by readers is not Transparent. A copy that is -not “Transparent” is called “Opaque”. +not "Transparent" is called "Opaque". Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, LaTeX input format, SGML or XML @@ -111,10 +111,10 @@ word processors for output purposes only. .. _fdl-title-page: -The “Title Page” means, for a printed book, the title page itself, plus +The "Title Page" means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which -do not have any title page as such, “Title Page” means the text near the +do not have any title page as such, "Title Page" means the text near the most prominent appearance of the work's title, preceding the beginning of the body of the text. @@ -242,11 +242,11 @@ Modified Version: Include an unaltered copy of this License. - **I.** - Preserve the section entitled “History”, and its title, and add to it + Preserve the section entitled "History", and its title, and add to it an item stating at least the title, year, new authors, and publisher of the :ref:`Modified Version ` as given on the :ref:`Title Page `. If there is no section entitled - “History” in the :ref:`Document `, create one stating + "History" in the :ref:`Document `, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence. @@ -256,13 +256,13 @@ Modified Version: :ref:`Document ` for public access to a :ref:`Transparent ` copy of the Document, and likewise the network locations given in the Document for previous - versions it was based on. These may be placed in the “History” + versions it was based on. These may be placed in the "History" section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission. - **K.** - In any section entitled “Acknowledgements” or “Dedications”, preserve + In any section entitled "Acknowledgements" or "Dedications", preserve the section's title, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein. @@ -274,11 +274,11 @@ Modified Version: part of the section titles. - **M.** - Delete any section entitled “Endorsements”. Such a section may not be + Delete any section entitled "Endorsements". Such a section may not be included in the :ref:`Modified Version `. - **N.** - Do not retitle any existing section as “Endorsements” or to conflict + Do not retitle any existing section as "Endorsements" or to conflict in title with any :ref:`Invariant Section `. If the :ref:`Modified Version ` includes new @@ -290,7 +290,7 @@ of :ref:`Invariant Sections ` in the Modified Version's license notice. These titles must be distinct from any other section titles. -You may add a section entitled “Endorsements”, provided it contains +You may add a section entitled "Endorsements", provided it contains nothing but endorsements of your :ref:`Modified Version ` by various parties--for example, statements of peer review or that the text has been approved by @@ -337,11 +337,11 @@ the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work. -In the combination, you must combine any sections entitled “History” in -the various original documents, forming one section entitled “History”; -likewise combine any sections entitled “Acknowledgements”, and any -sections entitled “Dedications”. You must delete all sections entitled -“Endorsements.” +In the combination, you must combine any sections entitled "History" in +the various original documents, forming one section entitled "History"; +likewise combine any sections entitled "Acknowledgements", and any +sections entitled "Dedications". You must delete all sections entitled +"Endorsements." .. _fdl-section6: @@ -372,7 +372,7 @@ with other separate and independent documents or works, in or on a volume of a storage or distribution medium, does not as a whole count as a :ref:`Modified Version ` of the Document, provided no compilation copyright is claimed for the compilation. Such a compilation -is called an “aggregate”, and this License does not apply to the other +is called an "aggregate", and this License does not apply to the other self-contained works thus compiled with the Document , on account of their being thus compiled, if they are not themselves derivative works of the Document. If the :ref:`Cover Text ` @@ -429,7 +429,7 @@ concerns. See Each version of the License is given a distinguishing version number. If the :ref:`Document ` specifies that a particular -numbered version of this License “or any later version” applies to it, +numbered version of this License "or any later version" applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not @@ -455,13 +455,13 @@ notices just after the title page: being LIST THEIR TITLES, with the :ref:`Front-Cover Texts ` being LIST, and with the :ref:`Back-Cover Texts ` being LIST. A copy - of the license is included in the section entitled “GNU Free - Documentation License”. + of the license is included in the section entitled "GNU Free + Documentation License". -If you have no :ref:`Invariant Sections `, write “with -no Invariant Sections” instead of saying which ones are invariant. If -you have no :ref:`Front-Cover Texts `, write “no -Front-Cover Texts” instead of “Front-Cover Texts being LIST”; likewise +If you have no :ref:`Invariant Sections `, write "with +no Invariant Sections" instead of saying which ones are invariant. If +you have no :ref:`Front-Cover Texts `, write "no +Front-Cover Texts" instead of "Front-Cover Texts being LIST"; likewise for :ref:`Back-Cover Texts `. If your document contains nontrivial examples of program code, we From eff7d26abc05821fd4ff32f2eef0a37cf977535b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 2 Jun 2021 15:12:18 +0200 Subject: [PATCH 262/394] docs: userspace-api: media: v4l: replace some characters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The conversion tools used during DocBook/LaTeX/html/Markdown->ReST conversion and some cut-and-pasted text contain some characters that aren't easily reachable on standard keyboards and/or could cause troubles when parsed by the documentation build system. Replace the occurences of the following characters: - U+00a0 (' '): NO-BREAK SPACE as it can cause lines being truncated on PDF output - U+2014 ('—'): EM DASH - U+2019 ('’'): RIGHT SINGLE QUOTATION MARK Note that Sphinx auto-translates '---' into EM DASH. Signed-off-by: Mauro Carvalho Chehab --- Documentation/userspace-api/media/v4l/biblio.rst | 8 ++++---- Documentation/userspace-api/media/v4l/dev-decoder.rst | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Documentation/userspace-api/media/v4l/biblio.rst b/Documentation/userspace-api/media/v4l/biblio.rst index 64d241daf63c..7b8e6738ff9e 100644 --- a/Documentation/userspace-api/media/v4l/biblio.rst +++ b/Documentation/userspace-api/media/v4l/biblio.rst @@ -51,7 +51,7 @@ ISO 13818-1 =========== -:title: ITU-T Rec. H.222.0 | ISO/IEC 13818-1 "Information technology — Generic coding of moving pictures and associated audio information: Systems" +:title: ITU-T Rec. H.222.0 | ISO/IEC 13818-1 "Information technology --- Generic coding of moving pictures and associated audio information: Systems" :author: International Telecommunication Union (http://www.itu.ch), International Organisation for Standardisation (http://www.iso.ch) @@ -61,7 +61,7 @@ ISO 13818-2 =========== -:title: ITU-T Rec. H.262 | ISO/IEC 13818-2 "Information technology — Generic coding of moving pictures and associated audio information: Video" +:title: ITU-T Rec. H.262 | ISO/IEC 13818-2 "Information technology --- Generic coding of moving pictures and associated audio information: Video" :author: International Telecommunication Union (http://www.itu.ch), International Organisation for Standardisation (http://www.iso.ch) @@ -150,7 +150,7 @@ ITU-T.81 ======== -:title: ITU-T Recommendation T.81 "Information Technology — Digital Compression and Coding of Continous-Tone Still Images — Requirements and Guidelines" +:title: ITU-T Recommendation T.81 "Information Technology --- Digital Compression and Coding of Continous-Tone Still Images --- Requirements and Guidelines" :author: International Telecommunication Union (http://www.itu.int) @@ -310,7 +310,7 @@ ISO 12232:2006 ============== -:title: Photography — Digital still cameras — Determination of exposure index, ISO speed ratings, standard output sensitivity, and recommended exposure index +:title: Photography --- Digital still cameras --- Determination of exposure index, ISO speed ratings, standard output sensitivity, and recommended exposure index :author: International Organization for Standardization (http://www.iso.org) diff --git a/Documentation/userspace-api/media/v4l/dev-decoder.rst b/Documentation/userspace-api/media/v4l/dev-decoder.rst index 3d4138a4ba69..5b9b83feeceb 100644 --- a/Documentation/userspace-api/media/v4l/dev-decoder.rst +++ b/Documentation/userspace-api/media/v4l/dev-decoder.rst @@ -38,7 +38,7 @@ Conventions and Notations Used in This Document 6. i = [a..b]: sequence of integers from a to b, inclusive, i.e. i = [0..2]: i = 0, 1, 2. -7. Given an ``OUTPUT`` buffer A, then A’ represents a buffer on the ``CAPTURE`` +7. Given an ``OUTPUT`` buffer A, then A' represents a buffer on the ``CAPTURE`` queue containing data that resulted from processing buffer A. .. _decoder-glossary: @@ -288,7 +288,7 @@ Initialization Changing the ``OUTPUT`` format may change the currently set ``CAPTURE`` format. How the new ``CAPTURE`` format is determined is up to the decoder - and the client must ensure it matches its needs afterwards. + and the client must ensure it matches its needs afterwards. 2. Allocate source (bytestream) buffers via :c:func:`VIDIOC_REQBUFS` on ``OUTPUT``. @@ -874,7 +874,7 @@ it may be affected as per normal decoder operation. any of the following results on the ``CAPTURE`` queue is allowed: - {A’, B’, G’, H’}, {A’, G’, H’}, {G’, H’}. + {A', B', G', H'}, {A', G', H'}, {G', H'}. To determine the CAPTURE buffer containing the first decoded frame after the seek, the client may observe the timestamps to match the CAPTURE and OUTPUT From c11669f738f48c7b3cf3b7ec700af33e1566d9c3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 2 Jun 2021 15:12:18 +0200 Subject: [PATCH 263/394] docs: userspace-api: media: dvb: replace some characters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The conversion tools used during DocBook/LaTeX/html/Markdown->ReST conversion and some cut-and-pasted text contain some characters that aren't easily reachable on standard keyboards and/or could cause troubles when parsed by the documentation build system. Replace the occurences of the following characters: - U+00a0 (' '): NO-BREAK SPACE as it can cause lines being truncated on PDF output - U+2019 ('’'): RIGHT SINGLE QUOTATION MARK - U+201c ('“'): LEFT DOUBLE QUOTATION MARK - U+201d ('”'): RIGHT DOUBLE QUOTATION MARK Signed-off-by: Mauro Carvalho Chehab --- .../userspace-api/media/dvb/audio-set-bypass-mode.rst | 2 +- Documentation/userspace-api/media/dvb/audio.rst | 2 +- Documentation/userspace-api/media/dvb/dmx-fopen.rst | 2 +- Documentation/userspace-api/media/dvb/dmx-fread.rst | 2 +- Documentation/userspace-api/media/dvb/dmx-set-filter.rst | 2 +- Documentation/userspace-api/media/dvb/intro.rst | 6 +++--- Documentation/userspace-api/media/dvb/video.rst | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Documentation/userspace-api/media/dvb/audio-set-bypass-mode.rst b/Documentation/userspace-api/media/dvb/audio-set-bypass-mode.rst index ecac02f1b2fc..80d551a2053a 100644 --- a/Documentation/userspace-api/media/dvb/audio-set-bypass-mode.rst +++ b/Documentation/userspace-api/media/dvb/audio-set-bypass-mode.rst @@ -50,7 +50,7 @@ Description This ioctl call asks the Audio Device to bypass the Audio decoder and forward the stream without decoding. This mode shall be used if streams -that can’t be handled by the Digital TV system shall be decoded. Dolby +that can't be handled by the Digital TV system shall be decoded. Dolby DigitalTM streams are automatically forwarded by the Digital TV subsystem if the hardware can handle it. diff --git a/Documentation/userspace-api/media/dvb/audio.rst b/Documentation/userspace-api/media/dvb/audio.rst index eaae5675a47d..aa753336b31f 100644 --- a/Documentation/userspace-api/media/dvb/audio.rst +++ b/Documentation/userspace-api/media/dvb/audio.rst @@ -11,7 +11,7 @@ TV hardware. It can be accessed through ``/dev/dvb/adapter?/audio?``. Data types and ioctl definitions can be accessed by including ``linux/dvb/audio.h`` in your application. -Please note that some Digital TV cards don’t have their own MPEG decoder, which +Please note that some Digital TV cards don't have their own MPEG decoder, which results in the omission of the audio and video device. These ioctls were also used by V4L2 to control MPEG decoders implemented diff --git a/Documentation/userspace-api/media/dvb/dmx-fopen.rst b/Documentation/userspace-api/media/dvb/dmx-fopen.rst index 8f0a2b831d4a..50b36eb4371e 100644 --- a/Documentation/userspace-api/media/dvb/dmx-fopen.rst +++ b/Documentation/userspace-api/media/dvb/dmx-fopen.rst @@ -82,7 +82,7 @@ appropriately. :widths: 1 16 - - ``EMFILE`` - - “Too many open files”, i.e. no more filters available. + - "Too many open files", i.e. no more filters available. The generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/userspace-api/media/dvb/dmx-fread.rst b/Documentation/userspace-api/media/dvb/dmx-fread.rst index 78e9daef595a..88c4cddf7c30 100644 --- a/Documentation/userspace-api/media/dvb/dmx-fread.rst +++ b/Documentation/userspace-api/media/dvb/dmx-fread.rst @@ -34,7 +34,7 @@ Description This system call returns filtered data, which might be section or Packetized Elementary Stream (PES) data. The filtered data is transferred from -the driver’s internal circular buffer to ``buf``. The maximum amount of data +the driver's internal circular buffer to ``buf``. The maximum amount of data to be transferred is implied by count. .. note:: diff --git a/Documentation/userspace-api/media/dvb/dmx-set-filter.rst b/Documentation/userspace-api/media/dvb/dmx-set-filter.rst index f43455b7adae..1b8c8071b14f 100644 --- a/Documentation/userspace-api/media/dvb/dmx-set-filter.rst +++ b/Documentation/userspace-api/media/dvb/dmx-set-filter.rst @@ -37,7 +37,7 @@ parameters provided. A timeout may be defined stating number of seconds to wait for a section to be loaded. A value of 0 means that no timeout should be applied. Finally there is a flag field where it is possible to state whether a section should be CRC-checked, whether the filter should -be a ”one-shot” filter, i.e. if the filtering operation should be +be a "one-shot" filter, i.e. if the filtering operation should be stopped after the first section is received, and whether the filtering operation should be started immediately (without waiting for a :ref:`DMX_START` ioctl call). If a filter was previously set-up, this diff --git a/Documentation/userspace-api/media/dvb/intro.rst b/Documentation/userspace-api/media/dvb/intro.rst index a935f3914e56..6784ae79657c 100644 --- a/Documentation/userspace-api/media/dvb/intro.rst +++ b/Documentation/userspace-api/media/dvb/intro.rst @@ -107,7 +107,7 @@ Audio and video decoder a Systems on a Chip (SoC) integrated circuit. It may also not be needed for certain usages (e.g. for data-only - uses like “internet over satellite”). + uses like "internet over satellite"). :ref:`stb_components` shows a crude schematic of the control and data flow between those components. @@ -148,9 +148,9 @@ individual devices are called: - ``/dev/dvb/adapterN/caM``, -where ``N`` enumerates the Digital TV cards in a system starting from 0, and +where ``N`` enumerates the Digital TV cards in a system starting from 0, and ``M`` enumerates the devices of each type within each adapter, starting -from 0, too. We will omit the “``/dev/dvb/adapterN/``\ ” in the further +from 0, too. We will omit the "``/dev/dvb/adapterN/``\ " in the further discussion of these devices. More details about the data structures and function calls of all the diff --git a/Documentation/userspace-api/media/dvb/video.rst b/Documentation/userspace-api/media/dvb/video.rst index 38a8d39a1d25..808705b769a1 100644 --- a/Documentation/userspace-api/media/dvb/video.rst +++ b/Documentation/userspace-api/media/dvb/video.rst @@ -16,7 +16,7 @@ stream, not its presentation on the TV or computer screen. On PCs this is typically handled by an associated video4linux device, e.g. **/dev/video**, which allows scaling and defining output windows. -Some Digital TV cards don’t have their own MPEG decoder, which results in the +Some Digital TV cards don't have their own MPEG decoder, which results in the omission of the audio and video device as well as the video4linux device. From cd40407a8a018d43fdb05c84a76af96f8bce9ac2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 1 Jun 2021 11:27:04 +0200 Subject: [PATCH 264/394] media: ivtv: get rid of DVB deprecated ioctls The ivtv driver has gained support a long time ago for audio and video settings via V4L2 API. Let's drop support of the duplicated controls implemented abusing the DVB API. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/ivtv/Kconfig | 12 -- drivers/media/pci/ivtv/ivtv-driver.h | 2 - drivers/media/pci/ivtv/ivtv-ioctl.c | 221 --------------------------- 3 files changed, 235 deletions(-) diff --git a/drivers/media/pci/ivtv/Kconfig b/drivers/media/pci/ivtv/Kconfig index c729e54692c4..e70502902b73 100644 --- a/drivers/media/pci/ivtv/Kconfig +++ b/drivers/media/pci/ivtv/Kconfig @@ -29,18 +29,6 @@ config VIDEO_IVTV To compile this driver as a module, choose M here: the module will be called ivtv. -config VIDEO_IVTV_DEPRECATED_IOCTLS - bool "enable the DVB ioctls abuse on ivtv driver" - depends on VIDEO_IVTV - help - Enable the usage of the a DVB set of ioctls that were abused by - IVTV driver for a while. - - Those ioctls were not needed for a long time, as IVTV implements - the proper V4L2 ioctls since kernel 3.3. - - If unsure, say N. - config VIDEO_IVTV_ALSA tristate "Conexant cx23415/cx23416 ALSA interface for PCM audio capture" depends on VIDEO_IVTV && SND diff --git a/drivers/media/pci/ivtv/ivtv-driver.h b/drivers/media/pci/ivtv/ivtv-driver.h index e5efe525ad7b..4cf92dee6527 100644 --- a/drivers/media/pci/ivtv/ivtv-driver.h +++ b/drivers/media/pci/ivtv/ivtv-driver.h @@ -57,8 +57,6 @@ #include #include -#include -#include #include #include #include diff --git a/drivers/media/pci/ivtv/ivtv-ioctl.c b/drivers/media/pci/ivtv/ivtv-ioctl.c index 35dccb31174c..da19b2e95e6c 100644 --- a/drivers/media/pci/ivtv/ivtv-ioctl.c +++ b/drivers/media/pci/ivtv/ivtv-ioctl.c @@ -23,11 +23,6 @@ #include #include #include -#ifdef CONFIG_VIDEO_IVTV_DEPRECATED_IOCTLS -#include -#include -#include -#endif u16 ivtv_service2vbi(int type) { @@ -1606,38 +1601,11 @@ static int ivtv_try_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder return ivtv_video_command(itv, id, dec, true); } -#ifdef CONFIG_VIDEO_IVTV_DEPRECATED_IOCTLS -static __inline__ void warn_deprecated_ioctl(const char *name) -{ - pr_warn_once("warning: the %s ioctl is deprecated. Don't use it, as it will be removed soon\n", - name); -} - -#ifdef CONFIG_COMPAT -struct compat_video_event { - __s32 type; - /* unused, make sure to use atomic time for y2038 if it ever gets used */ - compat_long_t timestamp; - union { - video_size_t size; - unsigned int frame_rate; /* in frames per 1000sec */ - unsigned char vsync_field; /* unknown/odd/even/progressive */ - } u; -}; -#define VIDEO_GET_EVENT32 _IOR('o', 28, struct compat_video_event) -#endif - -#endif - static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg) { struct ivtv_open_id *id = fh2id(filp->private_data); struct ivtv *itv = id->itv; struct ivtv_stream *s = &itv->streams[id->type]; -#ifdef CONFIG_VIDEO_IVTV_DEPRECATED_IOCTLS - int nonblocking = filp->f_flags & O_NONBLOCK; - unsigned long iarg = (unsigned long)arg; -#endif switch (cmd) { case IVTV_IOC_DMA_FRAME: { @@ -1669,169 +1637,6 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg) if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) return -EINVAL; return ivtv_passthrough_mode(itv, *(int *)arg != 0); -#ifdef CONFIG_VIDEO_IVTV_DEPRECATED_IOCTLS - case VIDEO_GET_PTS: { - s64 *pts = arg; - s64 frame; - - warn_deprecated_ioctl("VIDEO_GET_PTS"); - if (s->type < IVTV_DEC_STREAM_TYPE_MPG) { - *pts = s->dma_pts; - break; - } - if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) - return -EINVAL; - return ivtv_g_pts_frame(itv, pts, &frame); - } - - case VIDEO_GET_FRAME_COUNT: { - s64 *frame = arg; - s64 pts; - - warn_deprecated_ioctl("VIDEO_GET_FRAME_COUNT"); - if (s->type < IVTV_DEC_STREAM_TYPE_MPG) { - *frame = 0; - break; - } - if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) - return -EINVAL; - return ivtv_g_pts_frame(itv, &pts, frame); - } - - case VIDEO_PLAY: { - struct v4l2_decoder_cmd dc; - - warn_deprecated_ioctl("VIDEO_PLAY"); - memset(&dc, 0, sizeof(dc)); - dc.cmd = V4L2_DEC_CMD_START; - return ivtv_video_command(itv, id, &dc, 0); - } - - case VIDEO_STOP: { - struct v4l2_decoder_cmd dc; - - warn_deprecated_ioctl("VIDEO_STOP"); - memset(&dc, 0, sizeof(dc)); - dc.cmd = V4L2_DEC_CMD_STOP; - dc.flags = V4L2_DEC_CMD_STOP_TO_BLACK | V4L2_DEC_CMD_STOP_IMMEDIATELY; - return ivtv_video_command(itv, id, &dc, 0); - } - - case VIDEO_FREEZE: { - struct v4l2_decoder_cmd dc; - - warn_deprecated_ioctl("VIDEO_FREEZE"); - memset(&dc, 0, sizeof(dc)); - dc.cmd = V4L2_DEC_CMD_PAUSE; - return ivtv_video_command(itv, id, &dc, 0); - } - - case VIDEO_CONTINUE: { - struct v4l2_decoder_cmd dc; - - warn_deprecated_ioctl("VIDEO_CONTINUE"); - memset(&dc, 0, sizeof(dc)); - dc.cmd = V4L2_DEC_CMD_RESUME; - return ivtv_video_command(itv, id, &dc, 0); - } - - case VIDEO_COMMAND: - case VIDEO_TRY_COMMAND: { - /* Note: struct v4l2_decoder_cmd has the same layout as - struct video_command */ - struct v4l2_decoder_cmd *dc = arg; - int try = (cmd == VIDEO_TRY_COMMAND); - - if (try) - warn_deprecated_ioctl("VIDEO_TRY_COMMAND"); - else - warn_deprecated_ioctl("VIDEO_COMMAND"); - return ivtv_video_command(itv, id, dc, try); - } - -#ifdef CONFIG_COMPAT - case VIDEO_GET_EVENT32: -#endif - case VIDEO_GET_EVENT: { -#ifdef CONFIG_COMPAT - struct compat_video_event *ev32 = arg; -#endif - struct video_event *ev = arg; - DEFINE_WAIT(wait); - - warn_deprecated_ioctl("VIDEO_GET_EVENT"); - if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) - return -EINVAL; - memset(ev, 0, sizeof(*ev)); - set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags); - - while (1) { - if (test_and_clear_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags)) - ev->type = VIDEO_EVENT_DECODER_STOPPED; - else if (test_and_clear_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags)) { - unsigned char vsync_field; - - ev->type = VIDEO_EVENT_VSYNC; - vsync_field = test_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags) ? - VIDEO_VSYNC_FIELD_ODD : VIDEO_VSYNC_FIELD_EVEN; - if (itv->output_mode == OUT_UDMA_YUV && - (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) == - IVTV_YUV_MODE_PROGRESSIVE) { - vsync_field = VIDEO_VSYNC_FIELD_PROGRESSIVE; - } -#ifdef CONFIG_COMPAT - if (cmd == VIDEO_GET_EVENT32) - ev32->u.vsync_field = vsync_field; - else -#endif - ev->u.vsync_field = vsync_field; - } - if (ev->type) - return 0; - if (nonblocking) - return -EAGAIN; - /* Wait for event. Note that serialize_lock is locked, - so to allow other processes to access the driver while - we are waiting unlock first and later lock again. */ - mutex_unlock(&itv->serialize_lock); - prepare_to_wait(&itv->event_waitq, &wait, TASK_INTERRUPTIBLE); - if (!test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags) && - !test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags)) - schedule(); - finish_wait(&itv->event_waitq, &wait); - mutex_lock(&itv->serialize_lock); - if (signal_pending(current)) { - /* return if a signal was received */ - IVTV_DEBUG_INFO("User stopped wait for event\n"); - return -EINTR; - } - } - break; - } - - case VIDEO_SELECT_SOURCE: - warn_deprecated_ioctl("VIDEO_SELECT_SOURCE"); - if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) - return -EINVAL; - return ivtv_passthrough_mode(itv, iarg == VIDEO_SOURCE_DEMUX); - - case AUDIO_SET_MUTE: - warn_deprecated_ioctl("AUDIO_SET_MUTE"); - itv->speed_mute_audio = iarg; - return 0; - - case AUDIO_CHANNEL_SELECT: - warn_deprecated_ioctl("AUDIO_CHANNEL_SELECT"); - if (iarg > AUDIO_STEREO_SWAPPED) - return -EINVAL; - return v4l2_ctrl_s_ctrl(itv->ctrl_audio_playback, iarg + 1); - - case AUDIO_BILINGUAL_CHANNEL_SELECT: - warn_deprecated_ioctl("AUDIO_BILINGUAL_CHANNEL_SELECT"); - if (iarg > AUDIO_STEREO_SWAPPED) - return -EINVAL; - return v4l2_ctrl_s_ctrl(itv->ctrl_audio_multilingual_playback, iarg + 1); -#endif default: return -EINVAL; } @@ -1846,17 +1651,6 @@ static long ivtv_default(struct file *file, void *fh, bool valid_prio, if (!valid_prio) { switch (cmd) { case IVTV_IOC_PASSTHROUGH_MODE: -#ifdef CONFIG_VIDEO_IVTV_DEPRECATED_IOCTLS - case VIDEO_PLAY: - case VIDEO_STOP: - case VIDEO_FREEZE: - case VIDEO_CONTINUE: - case VIDEO_COMMAND: - case VIDEO_SELECT_SOURCE: - case AUDIO_SET_MUTE: - case AUDIO_CHANNEL_SELECT: - case AUDIO_BILINGUAL_CHANNEL_SELECT: -#endif return -EBUSY; } } @@ -1874,21 +1668,6 @@ static long ivtv_default(struct file *file, void *fh, bool valid_prio, case IVTV_IOC_DMA_FRAME: case IVTV_IOC_PASSTHROUGH_MODE: -#ifdef CONFIG_VIDEO_IVTV_DEPRECATED_IOCTLS - case VIDEO_GET_PTS: - case VIDEO_GET_FRAME_COUNT: - case VIDEO_GET_EVENT: - case VIDEO_PLAY: - case VIDEO_STOP: - case VIDEO_FREEZE: - case VIDEO_CONTINUE: - case VIDEO_COMMAND: - case VIDEO_TRY_COMMAND: - case VIDEO_SELECT_SOURCE: - case AUDIO_SET_MUTE: - case AUDIO_CHANNEL_SELECT: - case AUDIO_BILINGUAL_CHANNEL_SELECT: -#endif return ivtv_decoder_ioctls(file, cmd, (void *)arg); default: From 819fbd3d8ef36c09576c2a0ffea503f5c46e9177 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 1 Jun 2021 11:31:30 +0200 Subject: [PATCH 265/394] media: dvb header files: move some headers to staging The audio, video and OSD APIs are used upstream only by the av7110 driver, which was moved to staging. So, move the corresponding header files to it. Signed-off-by: Mauro Carvalho Chehab --- .../linux/dvb => drivers/staging/media/av7110}/audio.h | 0 drivers/staging/media/av7110/av7110.h | 7 ++++--- .../uapi/linux/dvb => drivers/staging/media/av7110}/osd.h | 0 .../linux/dvb => drivers/staging/media/av7110}/video.h | 0 4 files changed, 4 insertions(+), 3 deletions(-) rename {include/uapi/linux/dvb => drivers/staging/media/av7110}/audio.h (100%) rename {include/uapi/linux/dvb => drivers/staging/media/av7110}/osd.h (100%) rename {include/uapi/linux/dvb => drivers/staging/media/av7110}/video.h (100%) diff --git a/include/uapi/linux/dvb/audio.h b/drivers/staging/media/av7110/audio.h similarity index 100% rename from include/uapi/linux/dvb/audio.h rename to drivers/staging/media/av7110/audio.h diff --git a/drivers/staging/media/av7110/av7110.h b/drivers/staging/media/av7110/av7110.h index 809d938ae166..b8e8fc8ddbe9 100644 --- a/drivers/staging/media/av7110/av7110.h +++ b/drivers/staging/media/av7110/av7110.h @@ -9,11 +9,12 @@ #include #include -#include -#include +#include "video.h" +#include "audio.h" +#include "osd.h" + #include #include -#include #include #include diff --git a/include/uapi/linux/dvb/osd.h b/drivers/staging/media/av7110/osd.h similarity index 100% rename from include/uapi/linux/dvb/osd.h rename to drivers/staging/media/av7110/osd.h diff --git a/include/uapi/linux/dvb/video.h b/drivers/staging/media/av7110/video.h similarity index 100% rename from include/uapi/linux/dvb/video.h rename to drivers/staging/media/av7110/video.h From 793e52d4e77d49737ad83cb11925c98f4907fcb1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 1 Jun 2021 11:41:39 +0200 Subject: [PATCH 266/394] media: docs: move DVB audio/video docs to staging The only upstream driver using the API described there is the av7110 driver. As the driver was moved to staging, move the API bits to staging as well. Signed-off-by: Mauro Carvalho Chehab --- Documentation/userspace-api/media/Makefile | 10 +---- .../media/audio.h.rst.exceptions | 19 --------- .../userspace-api/media/dvb/headers.rst | 7 ---- .../media/dvb/legacy_dvb_apis.rst | 7 ---- .../media/video.h.rst.exceptions | 39 ------------------- .../audio-bilingual-channel-select.rst | 0 .../media/av7110}/audio-channel-select.rst | 0 .../media/av7110}/audio-clear-buffer.rst | 0 .../staging/media/av7110}/audio-continue.rst | 0 .../staging/media/av7110}/audio-fclose.rst | 0 .../staging/media/av7110}/audio-fopen.rst | 0 .../staging/media/av7110}/audio-fwrite.rst | 0 .../media/av7110}/audio-get-capabilities.rst | 0 .../media/av7110}/audio-get-status.rst | 0 .../staging/media/av7110}/audio-pause.rst | 0 .../staging/media/av7110}/audio-play.rst | 0 .../media/av7110}/audio-select-source.rst | 0 .../media/av7110}/audio-set-av-sync.rst | 0 .../media/av7110}/audio-set-bypass-mode.rst | 0 .../staging/media/av7110}/audio-set-id.rst | 0 .../staging/media/av7110}/audio-set-mixer.rst | 0 .../staging/media/av7110}/audio-set-mute.rst | 0 .../media/av7110}/audio-set-streamtype.rst | 0 .../staging/media/av7110}/audio-stop.rst | 0 .../staging/media/av7110}/audio.rst | 0 .../media/av7110}/audio_data_types.rst | 0 .../media/av7110}/audio_function_calls.rst | 0 .../media/av7110}/video-clear-buffer.rst | 0 .../staging/media/av7110}/video-command.rst | 0 .../staging/media/av7110}/video-continue.rst | 0 .../media/av7110}/video-fast-forward.rst | 0 .../staging/media/av7110}/video-fclose.rst | 0 .../staging/media/av7110}/video-fopen.rst | 0 .../staging/media/av7110}/video-freeze.rst | 0 .../staging/media/av7110}/video-fwrite.rst | 0 .../media/av7110}/video-get-capabilities.rst | 0 .../staging/media/av7110}/video-get-event.rst | 0 .../media/av7110}/video-get-frame-count.rst | 0 .../staging/media/av7110}/video-get-pts.rst | 0 .../staging/media/av7110}/video-get-size.rst | 0 .../media/av7110}/video-get-status.rst | 0 .../staging/media/av7110}/video-play.rst | 0 .../media/av7110}/video-select-source.rst | 0 .../staging/media/av7110}/video-set-blank.rst | 0 .../av7110}/video-set-display-format.rst | 0 .../media/av7110}/video-set-format.rst | 0 .../media/av7110}/video-set-streamtype.rst | 0 .../media/av7110}/video-slowmotion.rst | 0 .../media/av7110}/video-stillpicture.rst | 0 .../staging/media/av7110}/video-stop.rst | 0 .../media/av7110}/video-try-command.rst | 0 .../staging/media/av7110}/video.rst | 0 .../media/av7110}/video_function_calls.rst | 0 .../staging/media/av7110}/video_types.rst | 0 54 files changed, 2 insertions(+), 80 deletions(-) delete mode 100644 Documentation/userspace-api/media/audio.h.rst.exceptions delete mode 100644 Documentation/userspace-api/media/video.h.rst.exceptions rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/audio-bilingual-channel-select.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/audio-channel-select.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/audio-clear-buffer.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/audio-continue.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/audio-fclose.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/audio-fopen.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/audio-fwrite.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/audio-get-capabilities.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/audio-get-status.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/audio-pause.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/audio-play.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/audio-select-source.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/audio-set-av-sync.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/audio-set-bypass-mode.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/audio-set-id.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/audio-set-mixer.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/audio-set-mute.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/audio-set-streamtype.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/audio-stop.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/audio.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/audio_data_types.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/audio_function_calls.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/video-clear-buffer.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/video-command.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/video-continue.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/video-fast-forward.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/video-fclose.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/video-fopen.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/video-freeze.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/video-fwrite.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/video-get-capabilities.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/video-get-event.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/video-get-frame-count.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/video-get-pts.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/video-get-size.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/video-get-status.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/video-play.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/video-select-source.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/video-set-blank.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/video-set-display-format.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/video-set-format.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/video-set-streamtype.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/video-slowmotion.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/video-stillpicture.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/video-stop.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/video-try-command.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/video.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/video_function_calls.rst (100%) rename {Documentation/userspace-api/media/dvb => drivers/staging/media/av7110}/video_types.rst (100%) diff --git a/Documentation/userspace-api/media/Makefile b/Documentation/userspace-api/media/Makefile index 81a4a1a53bce..00922aa7efde 100644 --- a/Documentation/userspace-api/media/Makefile +++ b/Documentation/userspace-api/media/Makefile @@ -7,8 +7,8 @@ PARSER = $(srctree)/Documentation/sphinx/parse-headers.pl UAPI = $(srctree)/include/uapi/linux KAPI = $(srctree)/include/linux -FILES = audio.h.rst ca.h.rst dmx.h.rst frontend.h.rst net.h.rst video.h.rst \ - videodev2.h.rst media.h.rst cec.h.rst lirc.h.rst +FILES = ca.h.rst dmx.h.rst frontend.h.rst net.h.rst \ + videodev2.h.rst media.h.rst cec.h.rst lirc.h.rst TARGETS := $(addprefix $(BUILDDIR)/, $(FILES)) @@ -21,9 +21,6 @@ quiet_gen_rst = echo ' PARSE $(patsubst $(srctree)/%,%,$<)'; \ silent_gen_rst = ${gen_rst} -$(BUILDDIR)/audio.h.rst: ${UAPI}/dvb/audio.h ${PARSER} $(SRC_DIR)/audio.h.rst.exceptions - @$($(quiet)gen_rst) - $(BUILDDIR)/ca.h.rst: ${UAPI}/dvb/ca.h ${PARSER} $(SRC_DIR)/ca.h.rst.exceptions @$($(quiet)gen_rst) @@ -36,9 +33,6 @@ $(BUILDDIR)/frontend.h.rst: ${UAPI}/dvb/frontend.h ${PARSER} $(SRC_DIR)/frontend $(BUILDDIR)/net.h.rst: ${UAPI}/dvb/net.h ${PARSER} $(SRC_DIR)/net.h.rst.exceptions @$($(quiet)gen_rst) -$(BUILDDIR)/video.h.rst: ${UAPI}/dvb/video.h ${PARSER} $(SRC_DIR)/video.h.rst.exceptions - @$($(quiet)gen_rst) - $(BUILDDIR)/videodev2.h.rst: ${UAPI}/videodev2.h ${PARSER} $(SRC_DIR)/videodev2.h.rst.exceptions @$($(quiet)gen_rst) diff --git a/Documentation/userspace-api/media/audio.h.rst.exceptions b/Documentation/userspace-api/media/audio.h.rst.exceptions deleted file mode 100644 index cf6620477f73..000000000000 --- a/Documentation/userspace-api/media/audio.h.rst.exceptions +++ /dev/null @@ -1,19 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 - -# Ignore header name -ignore define _DVBAUDIO_H_ - -# Undocumented audio caps, as this is a deprecated API anyway -ignore define AUDIO_CAP_DTS -ignore define AUDIO_CAP_LPCM -ignore define AUDIO_CAP_MP1 -ignore define AUDIO_CAP_MP2 -ignore define AUDIO_CAP_MP3 -ignore define AUDIO_CAP_AAC -ignore define AUDIO_CAP_OGG -ignore define AUDIO_CAP_SDDS -ignore define AUDIO_CAP_AC3 - -# some typedefs should point to struct/enums -replace typedef audio_mixer_t :c:type:`audio_mixer` -replace typedef audio_status_t :c:type:`audio_status` diff --git a/Documentation/userspace-api/media/dvb/headers.rst b/Documentation/userspace-api/media/dvb/headers.rst index 9743ffc35096..88c3eb33a89e 100644 --- a/Documentation/userspace-api/media/dvb/headers.rst +++ b/Documentation/userspace-api/media/dvb/headers.rst @@ -14,10 +14,3 @@ Digital TV uAPI headers .. kernel-include:: $BUILDDIR/ca.h.rst .. kernel-include:: $BUILDDIR/net.h.rst - -Legacy uAPI -*********** - -.. kernel-include:: $BUILDDIR/audio.h.rst - -.. kernel-include:: $BUILDDIR/video.h.rst diff --git a/Documentation/userspace-api/media/dvb/legacy_dvb_apis.rst b/Documentation/userspace-api/media/dvb/legacy_dvb_apis.rst index 6104879d728a..b97d56ee543c 100644 --- a/Documentation/userspace-api/media/dvb/legacy_dvb_apis.rst +++ b/Documentation/userspace-api/media/dvb/legacy_dvb_apis.rst @@ -11,11 +11,6 @@ The APIs described here **should not** be used on new drivers or applications. The DVBv3 frontend API has issues with new delivery systems, including DVB-S2, DVB-T2, ISDB, etc. -There's just one driver for a very legacy hardware using the Digital TV -audio and video APIs. No modern drivers should use it. Instead, audio and -video should be using the V4L2 and ALSA APIs, and the pipelines should -be set via the Media Controller API. - .. attention:: The APIs described here doesn't necessarily reflect the current @@ -28,5 +23,3 @@ be set via the Media Controller API. :maxdepth: 1 frontend_legacy_dvbv3_api - video - audio diff --git a/Documentation/userspace-api/media/video.h.rst.exceptions b/Documentation/userspace-api/media/video.h.rst.exceptions deleted file mode 100644 index ea9de59ad8b7..000000000000 --- a/Documentation/userspace-api/media/video.h.rst.exceptions +++ /dev/null @@ -1,39 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 - -# Ignore header name -ignore define _UAPI_DVBVIDEO_H_ - -# This is a deprecated obscure API. Just ignore things we don't know -ignore define VIDEO_CMD_PLAY -ignore define VIDEO_CMD_STOP -ignore define VIDEO_CMD_FREEZE -ignore define VIDEO_CMD_CONTINUE -ignore define VIDEO_CMD_FREEZE_TO_BLACK -ignore define VIDEO_CMD_STOP_TO_BLACK -ignore define VIDEO_CMD_STOP_IMMEDIATELY -ignore define VIDEO_PLAY_FMT_NONE -ignore define VIDEO_PLAY_FMT_GOP -ignore define VIDEO_VSYNC_FIELD_UNKNOWN -ignore define VIDEO_VSYNC_FIELD_ODD -ignore define VIDEO_VSYNC_FIELD_EVEN -ignore define VIDEO_VSYNC_FIELD_PROGRESSIVE -ignore define VIDEO_EVENT_SIZE_CHANGED -ignore define VIDEO_EVENT_FRAME_RATE_CHANGED -ignore define VIDEO_EVENT_DECODER_STOPPED -ignore define VIDEO_EVENT_VSYNC -ignore define VIDEO_CAP_MPEG1 -ignore define VIDEO_CAP_MPEG2 -ignore define VIDEO_CAP_SYS -ignore define VIDEO_CAP_PROG -ignore define VIDEO_CAP_SPU -ignore define VIDEO_CAP_NAVI -ignore define VIDEO_CAP_CSS - -# some typedefs should point to struct/enums -replace typedef video_format_t :c:type:`video_format` -replace typedef video_system_t :c:type:`video_system` -replace typedef video_displayformat_t :c:type:`video_displayformat` -replace typedef video_size_t :c:type:`video_size` -replace typedef video_stream_source_t :c:type:`video_stream_source` -replace typedef video_play_state_t :c:type:`video_play_state` -replace typedef video_navi_pack_t :c:type:`video_navi_pack` diff --git a/Documentation/userspace-api/media/dvb/audio-bilingual-channel-select.rst b/drivers/staging/media/av7110/audio-bilingual-channel-select.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/audio-bilingual-channel-select.rst rename to drivers/staging/media/av7110/audio-bilingual-channel-select.rst diff --git a/Documentation/userspace-api/media/dvb/audio-channel-select.rst b/drivers/staging/media/av7110/audio-channel-select.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/audio-channel-select.rst rename to drivers/staging/media/av7110/audio-channel-select.rst diff --git a/Documentation/userspace-api/media/dvb/audio-clear-buffer.rst b/drivers/staging/media/av7110/audio-clear-buffer.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/audio-clear-buffer.rst rename to drivers/staging/media/av7110/audio-clear-buffer.rst diff --git a/Documentation/userspace-api/media/dvb/audio-continue.rst b/drivers/staging/media/av7110/audio-continue.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/audio-continue.rst rename to drivers/staging/media/av7110/audio-continue.rst diff --git a/Documentation/userspace-api/media/dvb/audio-fclose.rst b/drivers/staging/media/av7110/audio-fclose.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/audio-fclose.rst rename to drivers/staging/media/av7110/audio-fclose.rst diff --git a/Documentation/userspace-api/media/dvb/audio-fopen.rst b/drivers/staging/media/av7110/audio-fopen.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/audio-fopen.rst rename to drivers/staging/media/av7110/audio-fopen.rst diff --git a/Documentation/userspace-api/media/dvb/audio-fwrite.rst b/drivers/staging/media/av7110/audio-fwrite.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/audio-fwrite.rst rename to drivers/staging/media/av7110/audio-fwrite.rst diff --git a/Documentation/userspace-api/media/dvb/audio-get-capabilities.rst b/drivers/staging/media/av7110/audio-get-capabilities.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/audio-get-capabilities.rst rename to drivers/staging/media/av7110/audio-get-capabilities.rst diff --git a/Documentation/userspace-api/media/dvb/audio-get-status.rst b/drivers/staging/media/av7110/audio-get-status.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/audio-get-status.rst rename to drivers/staging/media/av7110/audio-get-status.rst diff --git a/Documentation/userspace-api/media/dvb/audio-pause.rst b/drivers/staging/media/av7110/audio-pause.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/audio-pause.rst rename to drivers/staging/media/av7110/audio-pause.rst diff --git a/Documentation/userspace-api/media/dvb/audio-play.rst b/drivers/staging/media/av7110/audio-play.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/audio-play.rst rename to drivers/staging/media/av7110/audio-play.rst diff --git a/Documentation/userspace-api/media/dvb/audio-select-source.rst b/drivers/staging/media/av7110/audio-select-source.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/audio-select-source.rst rename to drivers/staging/media/av7110/audio-select-source.rst diff --git a/Documentation/userspace-api/media/dvb/audio-set-av-sync.rst b/drivers/staging/media/av7110/audio-set-av-sync.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/audio-set-av-sync.rst rename to drivers/staging/media/av7110/audio-set-av-sync.rst diff --git a/Documentation/userspace-api/media/dvb/audio-set-bypass-mode.rst b/drivers/staging/media/av7110/audio-set-bypass-mode.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/audio-set-bypass-mode.rst rename to drivers/staging/media/av7110/audio-set-bypass-mode.rst diff --git a/Documentation/userspace-api/media/dvb/audio-set-id.rst b/drivers/staging/media/av7110/audio-set-id.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/audio-set-id.rst rename to drivers/staging/media/av7110/audio-set-id.rst diff --git a/Documentation/userspace-api/media/dvb/audio-set-mixer.rst b/drivers/staging/media/av7110/audio-set-mixer.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/audio-set-mixer.rst rename to drivers/staging/media/av7110/audio-set-mixer.rst diff --git a/Documentation/userspace-api/media/dvb/audio-set-mute.rst b/drivers/staging/media/av7110/audio-set-mute.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/audio-set-mute.rst rename to drivers/staging/media/av7110/audio-set-mute.rst diff --git a/Documentation/userspace-api/media/dvb/audio-set-streamtype.rst b/drivers/staging/media/av7110/audio-set-streamtype.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/audio-set-streamtype.rst rename to drivers/staging/media/av7110/audio-set-streamtype.rst diff --git a/Documentation/userspace-api/media/dvb/audio-stop.rst b/drivers/staging/media/av7110/audio-stop.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/audio-stop.rst rename to drivers/staging/media/av7110/audio-stop.rst diff --git a/Documentation/userspace-api/media/dvb/audio.rst b/drivers/staging/media/av7110/audio.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/audio.rst rename to drivers/staging/media/av7110/audio.rst diff --git a/Documentation/userspace-api/media/dvb/audio_data_types.rst b/drivers/staging/media/av7110/audio_data_types.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/audio_data_types.rst rename to drivers/staging/media/av7110/audio_data_types.rst diff --git a/Documentation/userspace-api/media/dvb/audio_function_calls.rst b/drivers/staging/media/av7110/audio_function_calls.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/audio_function_calls.rst rename to drivers/staging/media/av7110/audio_function_calls.rst diff --git a/Documentation/userspace-api/media/dvb/video-clear-buffer.rst b/drivers/staging/media/av7110/video-clear-buffer.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/video-clear-buffer.rst rename to drivers/staging/media/av7110/video-clear-buffer.rst diff --git a/Documentation/userspace-api/media/dvb/video-command.rst b/drivers/staging/media/av7110/video-command.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/video-command.rst rename to drivers/staging/media/av7110/video-command.rst diff --git a/Documentation/userspace-api/media/dvb/video-continue.rst b/drivers/staging/media/av7110/video-continue.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/video-continue.rst rename to drivers/staging/media/av7110/video-continue.rst diff --git a/Documentation/userspace-api/media/dvb/video-fast-forward.rst b/drivers/staging/media/av7110/video-fast-forward.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/video-fast-forward.rst rename to drivers/staging/media/av7110/video-fast-forward.rst diff --git a/Documentation/userspace-api/media/dvb/video-fclose.rst b/drivers/staging/media/av7110/video-fclose.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/video-fclose.rst rename to drivers/staging/media/av7110/video-fclose.rst diff --git a/Documentation/userspace-api/media/dvb/video-fopen.rst b/drivers/staging/media/av7110/video-fopen.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/video-fopen.rst rename to drivers/staging/media/av7110/video-fopen.rst diff --git a/Documentation/userspace-api/media/dvb/video-freeze.rst b/drivers/staging/media/av7110/video-freeze.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/video-freeze.rst rename to drivers/staging/media/av7110/video-freeze.rst diff --git a/Documentation/userspace-api/media/dvb/video-fwrite.rst b/drivers/staging/media/av7110/video-fwrite.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/video-fwrite.rst rename to drivers/staging/media/av7110/video-fwrite.rst diff --git a/Documentation/userspace-api/media/dvb/video-get-capabilities.rst b/drivers/staging/media/av7110/video-get-capabilities.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/video-get-capabilities.rst rename to drivers/staging/media/av7110/video-get-capabilities.rst diff --git a/Documentation/userspace-api/media/dvb/video-get-event.rst b/drivers/staging/media/av7110/video-get-event.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/video-get-event.rst rename to drivers/staging/media/av7110/video-get-event.rst diff --git a/Documentation/userspace-api/media/dvb/video-get-frame-count.rst b/drivers/staging/media/av7110/video-get-frame-count.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/video-get-frame-count.rst rename to drivers/staging/media/av7110/video-get-frame-count.rst diff --git a/Documentation/userspace-api/media/dvb/video-get-pts.rst b/drivers/staging/media/av7110/video-get-pts.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/video-get-pts.rst rename to drivers/staging/media/av7110/video-get-pts.rst diff --git a/Documentation/userspace-api/media/dvb/video-get-size.rst b/drivers/staging/media/av7110/video-get-size.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/video-get-size.rst rename to drivers/staging/media/av7110/video-get-size.rst diff --git a/Documentation/userspace-api/media/dvb/video-get-status.rst b/drivers/staging/media/av7110/video-get-status.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/video-get-status.rst rename to drivers/staging/media/av7110/video-get-status.rst diff --git a/Documentation/userspace-api/media/dvb/video-play.rst b/drivers/staging/media/av7110/video-play.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/video-play.rst rename to drivers/staging/media/av7110/video-play.rst diff --git a/Documentation/userspace-api/media/dvb/video-select-source.rst b/drivers/staging/media/av7110/video-select-source.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/video-select-source.rst rename to drivers/staging/media/av7110/video-select-source.rst diff --git a/Documentation/userspace-api/media/dvb/video-set-blank.rst b/drivers/staging/media/av7110/video-set-blank.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/video-set-blank.rst rename to drivers/staging/media/av7110/video-set-blank.rst diff --git a/Documentation/userspace-api/media/dvb/video-set-display-format.rst b/drivers/staging/media/av7110/video-set-display-format.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/video-set-display-format.rst rename to drivers/staging/media/av7110/video-set-display-format.rst diff --git a/Documentation/userspace-api/media/dvb/video-set-format.rst b/drivers/staging/media/av7110/video-set-format.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/video-set-format.rst rename to drivers/staging/media/av7110/video-set-format.rst diff --git a/Documentation/userspace-api/media/dvb/video-set-streamtype.rst b/drivers/staging/media/av7110/video-set-streamtype.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/video-set-streamtype.rst rename to drivers/staging/media/av7110/video-set-streamtype.rst diff --git a/Documentation/userspace-api/media/dvb/video-slowmotion.rst b/drivers/staging/media/av7110/video-slowmotion.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/video-slowmotion.rst rename to drivers/staging/media/av7110/video-slowmotion.rst diff --git a/Documentation/userspace-api/media/dvb/video-stillpicture.rst b/drivers/staging/media/av7110/video-stillpicture.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/video-stillpicture.rst rename to drivers/staging/media/av7110/video-stillpicture.rst diff --git a/Documentation/userspace-api/media/dvb/video-stop.rst b/drivers/staging/media/av7110/video-stop.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/video-stop.rst rename to drivers/staging/media/av7110/video-stop.rst diff --git a/Documentation/userspace-api/media/dvb/video-try-command.rst b/drivers/staging/media/av7110/video-try-command.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/video-try-command.rst rename to drivers/staging/media/av7110/video-try-command.rst diff --git a/Documentation/userspace-api/media/dvb/video.rst b/drivers/staging/media/av7110/video.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/video.rst rename to drivers/staging/media/av7110/video.rst diff --git a/Documentation/userspace-api/media/dvb/video_function_calls.rst b/drivers/staging/media/av7110/video_function_calls.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/video_function_calls.rst rename to drivers/staging/media/av7110/video_function_calls.rst diff --git a/Documentation/userspace-api/media/dvb/video_types.rst b/drivers/staging/media/av7110/video_types.rst similarity index 100% rename from Documentation/userspace-api/media/dvb/video_types.rst rename to drivers/staging/media/av7110/video_types.rst From df5ce27d96532844232b16bd0105defc5684e7ce Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 2 Jun 2021 16:42:39 +0200 Subject: [PATCH 267/394] media: gspca: ov519: replace RIGHT SINGLE QUOTATION MARK MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the occurences of the following character: - U+2019 ('’'): RIGHT SINGLE QUOTATION MARK By a normal single comma character. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/gspca/ov519.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/usb/gspca/ov519.c b/drivers/media/usb/gspca/ov519.c index cd6776c3163b..bffa94e76da5 100644 --- a/drivers/media/usb/gspca/ov519.c +++ b/drivers/media/usb/gspca/ov519.c @@ -614,7 +614,7 @@ static const struct ov_i2c_regvals norm_3620b[] = { /* * From the datasheet: "Note that after writing to register COMH * (0x12) to change the sensor mode, registers related to the - * sensor’s cropping window will be reset back to their default + * sensor's cropping window will be reset back to their default * values." * * "wait 4096 external clock ... to make sure the sensor is From ffcf1b0ae3fa84f5f3f4bd1ee440e60b72f5c840 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 2 Jun 2021 16:42:39 +0200 Subject: [PATCH 268/394] media: rtl28xxu: replace a NO-BREAK SPACE character MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of using: - U+00a0 (' '): NO-BREAK SPACE Use a normal white space. This was probably introduced by some cut-and-paste. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index 2c04ed8af0e4..83705730e37e 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c @@ -1777,7 +1777,7 @@ static int rtl2832u_rc_query(struct dvb_usb_device *d) ir_raw_event_store_with_filter(d->rc_dev, &ev); } - /* 'flush' ir_raw_event_store_with_filter() */ + /* 'flush' ir_raw_event_store_with_filter() */ ir_raw_event_handle(d->rc_dev); exit: return ret; From a4c3793e71f3322b910d5ac46882120bd149b08b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 2 Jun 2021 16:42:42 +0200 Subject: [PATCH 269/394] media: allegro-dvt: avoid EN DASH char While there's nothing wrong with EN DASH on C code, this probably came from some cut-and paste from an ITU-T table. It sounds better to just an HYPHEN here. Reviewed-by: Michael Tretter Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/allegro-dvt/nal-h264.c | 2 +- drivers/media/platform/allegro-dvt/nal-hevc.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/allegro-dvt/nal-h264.c b/drivers/media/platform/allegro-dvt/nal-h264.c index 94dd9266d850..0ab2fcbee1b9 100644 --- a/drivers/media/platform/allegro-dvt/nal-h264.c +++ b/drivers/media/platform/allegro-dvt/nal-h264.c @@ -25,7 +25,7 @@ #include "nal-rbsp.h" /* - * See Rec. ITU-T H.264 (04/2017) Table 7-1 – NAL unit type codes, syntax + * See Rec. ITU-T H.264 (04/2017) Table 7-1 - NAL unit type codes, syntax * element categories, and NAL unit type classes */ enum nal_unit_type { diff --git a/drivers/media/platform/allegro-dvt/nal-hevc.c b/drivers/media/platform/allegro-dvt/nal-hevc.c index 5db540c69bfe..15a352e45831 100644 --- a/drivers/media/platform/allegro-dvt/nal-hevc.c +++ b/drivers/media/platform/allegro-dvt/nal-hevc.c @@ -25,7 +25,7 @@ #include "nal-rbsp.h" /* - * See Rec. ITU-T H.265 (02/2018) Table 7-1 – NAL unit type codes and NAL unit + * See Rec. ITU-T H.265 (02/2018) Table 7-1 - NAL unit type codes and NAL unit * type classes */ enum nal_unit_type { From 35c47f8d9a34cfa4b17109501526411d74341c8b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 2 Jun 2021 16:42:45 +0200 Subject: [PATCH 270/394] media: saa7134: drop a NO-BREAK SPACE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are two spaces on a comment there, being one of them an U+00a0 (' '): NO-BREAK SPACE. Drop it. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7134/saa7134-tvaudio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/pci/saa7134/saa7134-tvaudio.c b/drivers/media/pci/saa7134/saa7134-tvaudio.c index aa0895d2d735..9e0c442abc76 100644 --- a/drivers/media/pci/saa7134/saa7134-tvaudio.c +++ b/drivers/media/pci/saa7134/saa7134-tvaudio.c @@ -871,7 +871,7 @@ void saa7134_enable_i2s(struct saa7134_dev *dev) switch (dev->pci->device) { case PCI_DEVICE_ID_PHILIPS_SAA7133: case PCI_DEVICE_ID_PHILIPS_SAA7135: - /* Set I2S format (SONY)  */ + /* Set I2S format (SONY) */ saa_writeb(SAA7133_I2S_AUDIO_CONTROL, 0x00); /* Start I2S */ saa_writeb(SAA7134_I2S_AUDIO_OUTPUT, 0x11); From 730f055666a30b8224d639110eb9b25eaa87883a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 2 Jun 2021 16:42:49 +0200 Subject: [PATCH 271/394] media: rc: ite-cir: replace some an EN DASH MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of using U+2013 ('–'): EN DASH, let's just use an hyphen there, as this was probably introduced by some cut-and-paste from some other place. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/ite-cir.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/rc/ite-cir.h b/drivers/media/rc/ite-cir.h index ce7a40b10828..4b4294d77555 100644 --- a/drivers/media/rc/ite-cir.h +++ b/drivers/media/rc/ite-cir.h @@ -167,7 +167,7 @@ struct ite_dev { * hardware data obtained from: * * IT8712F - * Environment Control – Low Pin Count Input / Output + * Environment Control - Low Pin Count Input / Output * (EC - LPC I/O) * Preliminary Specification V0. 81 */ From 5b448065febe1c6bb6693735844f2fb2b7b654dc Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 2 Jun 2021 16:42:46 +0200 Subject: [PATCH 272/394] media: pci: tw5864: avoid usage of some characters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are several comments on this driver using those chars: - U+2013 ('–'): EN DASH - U+2018 ('‘'): LEFT SINGLE QUOTATION MARK - U+2019 ('’'): RIGHT SINGLE QUOTATION MARK They probably came from cut-and-pasting some texts found elsewhere. While there's nothing wrong on having those on comments in C, it is better to use ASCII chars for those specific cases, as the current variant doesn't really add any value. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/tw5864/tw5864-reg.h | 62 +++++++++++++-------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/drivers/media/pci/tw5864/tw5864-reg.h b/drivers/media/pci/tw5864/tw5864-reg.h index a74f30f2f78e..a26a439c4dc0 100644 --- a/drivers/media/pci/tw5864/tw5864-reg.h +++ b/drivers/media/pci/tw5864/tw5864-reg.h @@ -289,13 +289,13 @@ /* OSD enable bit for each channel */ #define TW5864_DSP_OSD_ENABLE 0x0228 -/* 0x0280 ~ 0x029c – Motion Vector for 1st 4x4 Block, e.g., 80 (X), 84 (Y) */ +/* 0x0280 ~ 0x029c - Motion Vector for 1st 4x4 Block, e.g., 80 (X), 84 (Y) */ #define TW5864_ME_MV_VEC1 0x0280 -/* 0x02a0 ~ 0x02bc – Motion Vector for 2nd 4x4 Block, e.g., A0 (X), A4 (Y) */ +/* 0x02a0 ~ 0x02bc - Motion Vector for 2nd 4x4 Block, e.g., A0 (X), A4 (Y) */ #define TW5864_ME_MV_VEC2 0x02a0 -/* 0x02c0 ~ 0x02dc – Motion Vector for 3rd 4x4 Block, e.g., C0 (X), C4 (Y) */ +/* 0x02c0 ~ 0x02dc - Motion Vector for 3rd 4x4 Block, e.g., C0 (X), C4 (Y) */ #define TW5864_ME_MV_VEC3 0x02c0 -/* 0x02e0 ~ 0x02fc – Motion Vector for 4th 4x4 Block, e.g., E0 (X), E4 (Y) */ +/* 0x02e0 ~ 0x02fc - Motion Vector for 4th 4x4 Block, e.g., E0 (X), E4 (Y) */ #define TW5864_ME_MV_VEC4 0x02e0 /* @@ -462,13 +462,13 @@ #define TW5864_VLC_BUF 0x100c /* Define controls in register TW5864_VLC_BUF */ -/* VLC BK0 full status, write ‘1’ to clear */ +/* VLC BK0 full status, write '1' to clear */ #define TW5864_VLC_BK0_FULL BIT(0) -/* VLC BK1 full status, write ‘1’ to clear */ +/* VLC BK1 full status, write '1' to clear */ #define TW5864_VLC_BK1_FULL BIT(1) -/* VLC end slice status, write ‘1’ to clear */ +/* VLC end slice status, write '1' to clear */ #define TW5864_VLC_END_SLICE BIT(2) -/* VLC Buffer overflow status, write ‘1’ to clear */ +/* VLC Buffer overflow status, write '1' to clear */ #define TW5864_DSP_RD_OF BIT(3) /* VLC string length in either buffer 0 or 1 at end of frame */ #define TW5864_VLC_STREAM_LEN_SHIFT 4 @@ -476,7 +476,7 @@ /* [15:0] Total coefficient number in a frame */ #define TW5864_TOTAL_COEF_NO 0x1010 -/* [0] VLC Encoder Interrupt. Write ‘1’ to clear */ +/* [0] VLC Encoder Interrupt. Write '1' to clear */ #define TW5864_VLC_DSP_INTR 0x1014 /* [31:0] VLC stream CRC checksum */ #define TW5864_VLC_STREAM_CRC 0x1018 @@ -494,7 +494,7 @@ */ #define TW5864_VLC_RD_BRST BIT(1) -/* 0x2000 ~ 0x2ffc -- H264 Stream Memory Map */ +/* 0x2000 ~ 0x2ffc - H264 Stream Memory Map */ /* * A word is 4 bytes. I.e., * VLC_STREAM_MEM[0] address: 0x2000 @@ -506,7 +506,7 @@ #define TW5864_VLC_STREAM_MEM_MAX_OFFSET 0x3ff #define TW5864_VLC_STREAM_MEM(offset) (TW5864_VLC_STREAM_MEM_START + 4 * offset) -/* 0x4000 ~ 0x4ffc -- Audio Register Map */ +/* 0x4000 ~ 0x4ffc - Audio Register Map */ /* [31:0] config 1ms cnt = Realtime clk/1000 */ #define TW5864_CFG_1MS_CNT 0x4000 @@ -688,10 +688,10 @@ /* * [1:0] - * 2’b00 phase set to 180 degree - * 2’b01 phase set to 270 degree - * 2’b10 phase set to 0 degree - * 2’b11 phase set to 90 degree + * 2'b00 phase set to 180 degree + * 2'b01 phase set to 270 degree + * 2'b10 phase set to 0 degree + * 2'b11 phase set to 90 degree */ #define TW5864_I2C_PHASE_CFG 0x800c @@ -826,7 +826,7 @@ /* SPLL_IREF, SPLL_LPX4, SPLL_CPX4, SPLL_PD, SPLL_DBG */ #define TW5864_SPLL 0x8028 -/* 0x8800 ~ 0x88fc -- Interrupt Register Map */ +/* 0x8800 ~ 0x88fc - Interrupt Register Map */ /* * Trigger mode of interrupt source 0 ~ 15 * 1 Edge trigger mode @@ -909,7 +909,7 @@ #define TW5864_INTR_I2C_DONE BIT(25) #define TW5864_INTR_AD BIT(26) -/* 0x9000 ~ 0x920c -- Video Capture (VIF) Register Map */ +/* 0x9000 ~ 0x920c - Video Capture (VIF) Register Map */ /* * H264EN_CH_STATUS[n] Status of Vsync synchronized H264EN_CH_EN (Read Only) * 1 Channel Enabled @@ -1009,7 +1009,7 @@ /* GPIO Output Enable of Group n */ #define TW5864_GPIO_OEN (0xff << 8) -/* 0xa000 ~ 0xa8ff – DDR Controller Register Map */ +/* 0xa000 ~ 0xa8ff - DDR Controller Register Map */ /* DDR Controller A */ /* * [2:0] Data valid counter after read command to DDR. This is the delay value @@ -1111,7 +1111,7 @@ */ #define TW5864_DDR_B_OFFSET 0x0800 -/* 0xb004 ~ 0xb018 – HW version/ARB12 Register Map */ +/* 0xb004 ~ 0xb018 - HW version/ARB12 Register Map */ /* [15:0] Default is C013 */ #define TW5864_HW_VERSION 0xb004 @@ -1145,7 +1145,7 @@ /* ARB12 maximum value of time out counter (default 15"h1FF) */ #define TW5864_ARB12_TIME_OUT_CNT 0x7fff -/* 0xb800 ~ 0xb80c -- Indirect Access Register Map */ +/* 0xb800 ~ 0xb80c - Indirect Access Register Map */ /* * Spec says: * In order to access the indirect register space, the following procedure is @@ -1177,7 +1177,7 @@ /* [31:0] Data used to read/write indirect register space */ #define TW5864_IND_DATA 0xb804 -/* 0xc000 ~ 0xc7fc -- Preview Register Map */ +/* 0xc000 ~ 0xc7fc - Preview Register Map */ /* Mostly skipped this section. */ /* * [15:0] Status of Vsync Synchronized PCI_PV_CH_EN (Read Only) @@ -1192,12 +1192,12 @@ */ #define TW5864_PCI_PV_CH_EN 0xc004 -/* 0xc800 ~ 0xc804 -- JPEG Capture Register Map */ +/* 0xc800 ~ 0xc804 - JPEG Capture Register Map */ /* Skipped. */ -/* 0xd000 ~ 0xd0fc -- JPEG Control Register Map */ +/* 0xd000 ~ 0xd0fc - JPEG Control Register Map */ /* Skipped. */ -/* 0xe000 ~ 0xfc04 – Motion Vector Register Map */ +/* 0xe000 ~ 0xfc04 - Motion Vector Register Map */ /* ME Motion Vector data (Four Byte Each) 0xe000 ~ 0xe7fc */ #define TW5864_ME_MV_VEC_START 0xe000 @@ -1231,7 +1231,7 @@ */ #define TW5864_MPI_DDR_SEL2 BIT(15) -/* 0x18000 ~ 0x181fc – PCI Master/Slave Control Map */ +/* 0x18000 ~ 0x181fc - PCI Master/Slave Control Map */ #define TW5864_PCI_INTR_STATUS 0x18000 /* Define controls in register TW5864_PCI_INTR_STATUS */ /* vlc done */ @@ -1400,11 +1400,11 @@ #define TW5864_VLC_STREAM_BASE_ADDR 0x18080 /* MV stream base address */ #define TW5864_MV_STREAM_BASE_ADDR 0x18084 -/* 0x180a0 – 0x180bc: audio burst base address. Skipped. */ -/* 0x180c0 ~ 0x180dc – JPEG Push Mode Buffer Base Address. Skipped. */ -/* 0x18100 – 0x1817c: preview burst base address. Skipped. */ +/* 0x180a0 ~ 0x180bc: audio burst base address. Skipped. */ +/* 0x180c0 ~ 0x180dc: JPEG Push Mode Buffer Base Address. Skipped. */ +/* 0x18100 ~ 0x1817c: preview burst base address. Skipped. */ -/* 0x80000 ~ 0x87fff -- DDR Burst RW Register Map */ +/* 0x80000 ~ 0x87fff - DDR Burst RW Register Map */ #define TW5864_DDR_CTL 0x80000 /* Define controls in register TW5864_DDR_CTL */ #define TW5864_BRST_LENGTH_SHIFT 2 @@ -1516,7 +1516,7 @@ * Vertical Sharpness Control. Writable. * 0 = None (default) * 7 = Highest - * **Note: VSHP must be set to ‘0’ if COMB = 0 + * **Note: VSHP must be set to '0' if COMB = 0 */ #define TW5864_INDIR_VIN_1_VSHP 0x07 @@ -1595,7 +1595,7 @@ #define TW5864_INDIR_VIN_9_CNTRST(channel) (0x009 + channel * 0x010) /* - * These bits control the brightness. They have value of –128 to 127 in 2's + * These bits control the brightness. They have value of -128 to 127 in 2's * complement form. Positive value increases brightness. A value 0 has no * effect on the data. The default is 00h. */ From a810ed0b3370e0b3f448233d526d085effd1f829 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 12 Apr 2021 13:02:09 +0200 Subject: [PATCH 273/394] media: videobuf2-v4l2.c: add vb2_queue_change_type() helper On some platforms a video device can capture either video data or metadata. The driver can implement vidioc functions for both video and metadata, and use a single vb2_queue for the buffers. However, vb2_queue requires choosing a single buffer type, which conflicts with the idea of capturing either video or metadata. The buffer type of vb2_queue can be changed, but it's not obvious how this should be done in the drivers. To help this, add a new helper function vb2_queue_change_type() which ensures the correct checks and documents how it can be used. Signed-off-by: Tomi Valkeinen Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/videobuf2/videobuf2-v4l2.c | 14 ++++++++++++++ include/media/videobuf2-v4l2.h | 16 ++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c index 7e96f67c60ba..2988bb38ceb1 100644 --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c @@ -939,6 +939,20 @@ void vb2_queue_release(struct vb2_queue *q) } EXPORT_SYMBOL_GPL(vb2_queue_release); +int vb2_queue_change_type(struct vb2_queue *q, unsigned int type) +{ + if (type == q->type) + return 0; + + if (vb2_is_busy(q)) + return -EBUSY; + + q->type = type; + + return 0; +} +EXPORT_SYMBOL_GPL(vb2_queue_change_type); + __poll_t vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait) { struct video_device *vfd = video_devdata(file); diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h index c203047eb834..b66585e304e2 100644 --- a/include/media/videobuf2-v4l2.h +++ b/include/media/videobuf2-v4l2.h @@ -261,6 +261,22 @@ int __must_check vb2_queue_init_name(struct vb2_queue *q, const char *name); */ void vb2_queue_release(struct vb2_queue *q); +/** + * vb2_queue_change_type() - change the type of an inactive vb2_queue + * @q: pointer to &struct vb2_queue with videobuf2 queue. + * @type: the type to change to (V4L2_BUF_TYPE_VIDEO_*) + * + * This function changes the type of the vb2_queue. This is only possible + * if the queue is not busy (i.e. no buffers have been allocated). + * + * vb2_queue_change_type() can be used to support multiple buffer types using + * the same queue. The driver can implement v4l2_ioctl_ops.vidioc_reqbufs and + * v4l2_ioctl_ops.vidioc_create_bufs functions and call vb2_queue_change_type() + * before calling vb2_ioctl_reqbufs() or vb2_ioctl_create_bufs(), and thus + * "lock" the buffer type until the buffers have been released. + */ +int vb2_queue_change_type(struct vb2_queue *q, unsigned int type); + /** * vb2_poll() - implements poll userspace operation * @q: pointer to &struct vb2_queue with videobuf2 queue. From 2d8b2a6431b38f4cb4046636117940b0cb0b3ecf Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 12 Apr 2021 13:02:10 +0200 Subject: [PATCH 274/394] media: vivid: remove stream_sliced_vbi_cap field Vivid tracks the VBI capture mode in vivid_dev->stream_sliced_vbi_cap field. We can just look at the buffer type instead, and drop the field. Signed-off-by: Tomi Valkeinen Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vivid/vivid-core.h | 1 - drivers/media/test-drivers/vivid/vivid-kthread-cap.c | 2 +- drivers/media/test-drivers/vivid/vivid-vbi-cap.c | 6 ++---- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/media/test-drivers/vivid/vivid-core.h b/drivers/media/test-drivers/vivid/vivid-core.h index cdff6cd264d0..1e3c4f5a9413 100644 --- a/drivers/media/test-drivers/vivid/vivid-core.h +++ b/drivers/media/test-drivers/vivid/vivid-core.h @@ -429,7 +429,6 @@ struct vivid_dev { u32 vbi_cap_seq_start; u32 vbi_cap_seq_count; bool vbi_cap_streaming; - bool stream_sliced_vbi_cap; u32 meta_cap_seq_start; u32 meta_cap_seq_count; bool meta_cap_streaming; diff --git a/drivers/media/test-drivers/vivid/vivid-kthread-cap.c b/drivers/media/test-drivers/vivid/vivid-kthread-cap.c index c0dc609c1358..9da730ccfa94 100644 --- a/drivers/media/test-drivers/vivid/vivid-kthread-cap.c +++ b/drivers/media/test-drivers/vivid/vivid-kthread-cap.c @@ -752,7 +752,7 @@ static noinline_for_stack void vivid_thread_vid_cap_tick(struct vivid_dev *dev, v4l2_ctrl_request_setup(vbi_cap_buf->vb.vb2_buf.req_obj.req, &dev->ctrl_hdl_vbi_cap); - if (dev->stream_sliced_vbi_cap) + if (vbi_cap_buf->vb.vb2_buf.type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) vivid_sliced_vbi_cap_process(dev, vbi_cap_buf); else vivid_raw_vbi_cap_process(dev, vbi_cap_buf); diff --git a/drivers/media/test-drivers/vivid/vivid-vbi-cap.c b/drivers/media/test-drivers/vivid/vivid-vbi-cap.c index 1a9348eea781..387df4ff01b0 100644 --- a/drivers/media/test-drivers/vivid/vivid-vbi-cap.c +++ b/drivers/media/test-drivers/vivid/vivid-vbi-cap.c @@ -255,9 +255,8 @@ int vidioc_s_fmt_vbi_cap(struct file *file, void *priv, if (ret) return ret; - if (dev->stream_sliced_vbi_cap && vb2_is_busy(&dev->vb_vbi_cap_q)) + if (f->type != V4L2_BUF_TYPE_VBI_CAPTURE && vb2_is_busy(&dev->vb_vbi_cap_q)) return -EBUSY; - dev->stream_sliced_vbi_cap = false; dev->vbi_cap_dev.queue->type = V4L2_BUF_TYPE_VBI_CAPTURE; return 0; } @@ -322,10 +321,9 @@ int vidioc_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format if (ret) return ret; - if (!dev->stream_sliced_vbi_cap && vb2_is_busy(&dev->vb_vbi_cap_q)) + if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE && vb2_is_busy(&dev->vb_vbi_cap_q)) return -EBUSY; dev->service_set_cap = vbi->service_set; - dev->stream_sliced_vbi_cap = true; dev->vbi_cap_dev.queue->type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; return 0; } From c9cbf021c82c3fa5b0beaa7d6e7f3f5706aeabfa Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 12 Apr 2021 13:02:11 +0200 Subject: [PATCH 275/394] media: vivid: use vb2_queue_change_type Use the new vb2_queue_change_type() function in .vidioc_reqbufs and .vidioc_create_bufs instead of changing the queue type manually in vidioc_s_fmt_vbi_cap() and vidioc_s_fmt_sliced_vbi_cap(). This allows for a more consistent behavior, as .vidioc_reqbufs and .vidioc_create_bufs are when the queue will become "busy". Signed-off-by: Tomi Valkeinen Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vivid/vivid-core.c | 44 ++++++++++++++++++- .../media/test-drivers/vivid/vivid-vbi-cap.c | 2 - 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/drivers/media/test-drivers/vivid/vivid-core.c b/drivers/media/test-drivers/vivid/vivid-core.c index ca0ebf6ad9cc..d2bd2653cf54 100644 --- a/drivers/media/test-drivers/vivid/vivid-core.c +++ b/drivers/media/test-drivers/vivid/vivid-core.c @@ -656,6 +656,46 @@ static const struct v4l2_file_operations vivid_radio_fops = { .unlocked_ioctl = video_ioctl2, }; +static int vidioc_reqbufs(struct file *file, void *priv, + struct v4l2_requestbuffers *p) +{ + struct video_device *vdev = video_devdata(file); + int r; + + /* + * Sliced and raw VBI capture share the same queue so we must + * change the type. + */ + if (p->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE || + p->type == V4L2_BUF_TYPE_VBI_CAPTURE) { + r = vb2_queue_change_type(vdev->queue, p->type); + if (r) + return r; + } + + return vb2_ioctl_reqbufs(file, priv, p); +} + +static int vidioc_create_bufs(struct file *file, void *priv, + struct v4l2_create_buffers *p) +{ + struct video_device *vdev = video_devdata(file); + int r; + + /* + * Sliced and raw VBI capture share the same queue so we must + * change the type. + */ + if (p->format.type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE || + p->format.type == V4L2_BUF_TYPE_VBI_CAPTURE) { + r = vb2_queue_change_type(vdev->queue, p->format.type); + if (r) + return r; + } + + return vb2_ioctl_create_bufs(file, priv, p); +} + static const struct v4l2_ioctl_ops vivid_ioctl_ops = { .vidioc_querycap = vidioc_querycap, @@ -717,8 +757,8 @@ static const struct v4l2_ioctl_ops vivid_ioctl_ops = { .vidioc_g_fbuf = vidioc_g_fbuf, .vidioc_s_fbuf = vidioc_s_fbuf, - .vidioc_reqbufs = vb2_ioctl_reqbufs, - .vidioc_create_bufs = vb2_ioctl_create_bufs, + .vidioc_reqbufs = vidioc_reqbufs, + .vidioc_create_bufs = vidioc_create_bufs, .vidioc_prepare_buf = vb2_ioctl_prepare_buf, .vidioc_querybuf = vb2_ioctl_querybuf, .vidioc_qbuf = vb2_ioctl_qbuf, diff --git a/drivers/media/test-drivers/vivid/vivid-vbi-cap.c b/drivers/media/test-drivers/vivid/vivid-vbi-cap.c index 387df4ff01b0..b65b02eeeb97 100644 --- a/drivers/media/test-drivers/vivid/vivid-vbi-cap.c +++ b/drivers/media/test-drivers/vivid/vivid-vbi-cap.c @@ -257,7 +257,6 @@ int vidioc_s_fmt_vbi_cap(struct file *file, void *priv, return ret; if (f->type != V4L2_BUF_TYPE_VBI_CAPTURE && vb2_is_busy(&dev->vb_vbi_cap_q)) return -EBUSY; - dev->vbi_cap_dev.queue->type = V4L2_BUF_TYPE_VBI_CAPTURE; return 0; } @@ -324,7 +323,6 @@ int vidioc_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE && vb2_is_busy(&dev->vb_vbi_cap_q)) return -EBUSY; dev->service_set_cap = vbi->service_set; - dev->vbi_cap_dev.queue->type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; return 0; } From 269b4dd3e8b34edec44c5bb0016ee96353638618 Mon Sep 17 00:00:00 2001 From: John Cox Date: Fri, 30 Apr 2021 18:48:13 +0200 Subject: [PATCH 276/394] media: hevc: Add sps_max_sub_layers_minus1 to v4l2_ctrl_hevc_sps sps_max_sub_layers_minus1 is needed if the driver wishes to determine whether or not a frame might be used for reference. Signed-off-by: John Cox Reviewed-by: Benjamin Gaignard Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst | 3 +++ include/media/hevc-ctrls.h | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst index 0b8061666c57..2b5edab55bb4 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst @@ -2707,6 +2707,9 @@ enum v4l2_mpeg_video_hevc_size_of_length_field - * - __u8 - ``chroma_format_idc`` - + * - __u8 + - ``sps_max_sub_layers_minus1`` + - * - __u64 - ``flags`` - See :ref:`Sequence Parameter Set Flags ` diff --git a/include/media/hevc-ctrls.h b/include/media/hevc-ctrls.h index 226fcfa0e026..36e4c93707ae 100644 --- a/include/media/hevc-ctrls.h +++ b/include/media/hevc-ctrls.h @@ -75,8 +75,7 @@ struct v4l2_ctrl_hevc_sps { __u8 num_short_term_ref_pic_sets; __u8 num_long_term_ref_pics_sps; __u8 chroma_format_idc; - - __u8 padding; + __u8 sps_max_sub_layers_minus1; __u64 flags; }; From f84bc784fa614ae9dba9fb79af2b8f143248c112 Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Tue, 13 Apr 2021 12:56:59 +0200 Subject: [PATCH 277/394] media: atmel: atmel-isc: specialize gamma table into product specific Separate the gamma table from the isc base file into the specific sama5d2 product file. Add a pointer to the gamma table and entries count inside the platform driver specific struct. [hverkuil: made isc_sama5d2_gamma_table static] Signed-off-by: Eugen Hristev Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/atmel/atmel-isc-base.c | 47 ++----------------- drivers/media/platform/atmel/atmel-isc.h | 11 +++-- .../media/platform/atmel/atmel-sama5d2-isc.c | 45 ++++++++++++++++++ 3 files changed, 56 insertions(+), 47 deletions(-) diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index a017572c870c..46d384332a58 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -176,48 +176,6 @@ struct isc_format formats_list[] = { }; -/* Gamma table with gamma 1/2.2 */ -const u32 isc_gamma_table[GAMMA_MAX + 1][GAMMA_ENTRIES] = { - /* 0 --> gamma 1/1.8 */ - { 0x65, 0x66002F, 0x950025, 0xBB0020, 0xDB001D, 0xF8001A, - 0x1130018, 0x12B0017, 0x1420016, 0x1580014, 0x16D0013, 0x1810012, - 0x1940012, 0x1A60012, 0x1B80011, 0x1C90010, 0x1DA0010, 0x1EA000F, - 0x1FA000F, 0x209000F, 0x218000F, 0x227000E, 0x235000E, 0x243000E, - 0x251000E, 0x25F000D, 0x26C000D, 0x279000D, 0x286000D, 0x293000C, - 0x2A0000C, 0x2AC000C, 0x2B8000C, 0x2C4000C, 0x2D0000B, 0x2DC000B, - 0x2E7000B, 0x2F3000B, 0x2FE000B, 0x309000B, 0x314000B, 0x31F000A, - 0x32A000A, 0x334000B, 0x33F000A, 0x349000A, 0x354000A, 0x35E000A, - 0x368000A, 0x372000A, 0x37C000A, 0x386000A, 0x3900009, 0x399000A, - 0x3A30009, 0x3AD0009, 0x3B60009, 0x3BF000A, 0x3C90009, 0x3D20009, - 0x3DB0009, 0x3E40009, 0x3ED0009, 0x3F60009 }, - - /* 1 --> gamma 1/2 */ - { 0x7F, 0x800034, 0xB50028, 0xDE0021, 0x100001E, 0x11E001B, - 0x1390019, 0x1520017, 0x16A0015, 0x1800014, 0x1940014, 0x1A80013, - 0x1BB0012, 0x1CD0011, 0x1DF0010, 0x1EF0010, 0x200000F, 0x20F000F, - 0x21F000E, 0x22D000F, 0x23C000E, 0x24A000E, 0x258000D, 0x265000D, - 0x273000C, 0x27F000D, 0x28C000C, 0x299000C, 0x2A5000C, 0x2B1000B, - 0x2BC000C, 0x2C8000B, 0x2D3000C, 0x2DF000B, 0x2EA000A, 0x2F5000A, - 0x2FF000B, 0x30A000A, 0x314000B, 0x31F000A, 0x329000A, 0x333000A, - 0x33D0009, 0x3470009, 0x350000A, 0x35A0009, 0x363000A, 0x36D0009, - 0x3760009, 0x37F0009, 0x3880009, 0x3910009, 0x39A0009, 0x3A30009, - 0x3AC0008, 0x3B40009, 0x3BD0008, 0x3C60008, 0x3CE0008, 0x3D60009, - 0x3DF0008, 0x3E70008, 0x3EF0008, 0x3F70008 }, - - /* 2 --> gamma 1/2.2 */ - { 0x99, 0x9B0038, 0xD4002A, 0xFF0023, 0x122001F, 0x141001B, - 0x15D0019, 0x1760017, 0x18E0015, 0x1A30015, 0x1B80013, 0x1CC0012, - 0x1DE0011, 0x1F00010, 0x2010010, 0x2110010, 0x221000F, 0x230000F, - 0x23F000E, 0x24D000E, 0x25B000D, 0x269000C, 0x276000C, 0x283000C, - 0x28F000C, 0x29B000C, 0x2A7000C, 0x2B3000B, 0x2BF000B, 0x2CA000B, - 0x2D5000B, 0x2E0000A, 0x2EB000A, 0x2F5000A, 0x2FF000A, 0x30A000A, - 0x3140009, 0x31E0009, 0x327000A, 0x3310009, 0x33A0009, 0x3440009, - 0x34D0009, 0x3560009, 0x35F0009, 0x3680008, 0x3710008, 0x3790009, - 0x3820008, 0x38A0008, 0x3930008, 0x39B0008, 0x3A30008, 0x3AB0008, - 0x3B30008, 0x3BB0008, 0x3C30008, 0x3CB0007, 0x3D20008, 0x3DA0007, - 0x3E20007, 0x3E90007, 0x3F00008, 0x3F80007 }, -}; - #define ISC_IS_FORMAT_RAW(mbus_code) \ (((mbus_code) & 0xf000) == 0x3000) @@ -691,7 +649,7 @@ static void isc_set_pipeline(struct isc_device *isc, u32 pipeline) regmap_write(regmap, ISC_CFA_CFG, bay_cfg | ISC_CFA_CFG_EITPOL); - gamma = &isc_gamma_table[ctrls->gamma_index][0]; + gamma = &isc->gamma_table[ctrls->gamma_index][0]; regmap_bulk_write(regmap, ISC_GAM_BENTRY, gamma, GAMMA_ENTRIES); regmap_bulk_write(regmap, ISC_GAM_GENTRY, gamma, GAMMA_ENTRIES); regmap_bulk_write(regmap, ISC_GAM_RENTRY, gamma, GAMMA_ENTRIES); @@ -2085,7 +2043,8 @@ static int isc_ctrl_init(struct isc_device *isc) v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BRIGHTNESS, -1024, 1023, 1, 0); v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST, -2048, 2047, 1, 256); - v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAMMA, 0, GAMMA_MAX, 1, 2); + v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAMMA, 0, isc->gamma_max, 1, + isc->gamma_max); isc->awb_ctrl = v4l2_ctrl_new_std(hdl, &isc_awb_ops, V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1); diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h index fab8eca58d93..f1df47a4655b 100644 --- a/drivers/media/platform/atmel/atmel-isc.h +++ b/drivers/media/platform/atmel/atmel-isc.h @@ -187,6 +187,10 @@ struct isc_ctrls { * * @current_subdev: current subdevice: the sensor * @subdev_entities: list of subdevice entitites + * + * @gamma_table: pointer to the table with gamma values, has + * gamma_max sets of GAMMA_ENTRIES entries each + * @gamma_max: maximum number of sets of inside the gamma_table */ struct isc_device { struct regmap *regmap; @@ -245,16 +249,17 @@ struct isc_device { struct v4l2_ctrl *gr_off_ctrl; struct v4l2_ctrl *gb_off_ctrl; }; -}; -#define GAMMA_MAX 2 #define GAMMA_ENTRIES 64 + /* pointer to the defined gamma table */ + const u32 (*gamma_table)[GAMMA_ENTRIES]; + u32 gamma_max; +}; #define ATMEL_ISC_NAME "atmel-isc" extern struct isc_format formats_list[]; extern const struct isc_format controller_formats[]; -extern const u32 isc_gamma_table[GAMMA_MAX + 1][GAMMA_ENTRIES]; extern const struct regmap_config isc_regmap_config; extern const struct v4l2_async_notifier_operations isc_async_ops; diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c index 61d9885765f4..e7156169febe 100644 --- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c +++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c @@ -54,6 +54,48 @@ #define ISC_CLK_MAX_DIV 255 +/* Gamma table with gamma 1/2.2 */ +static const u32 isc_sama5d2_gamma_table[][GAMMA_ENTRIES] = { + /* 0 --> gamma 1/1.8 */ + { 0x65, 0x66002F, 0x950025, 0xBB0020, 0xDB001D, 0xF8001A, + 0x1130018, 0x12B0017, 0x1420016, 0x1580014, 0x16D0013, 0x1810012, + 0x1940012, 0x1A60012, 0x1B80011, 0x1C90010, 0x1DA0010, 0x1EA000F, + 0x1FA000F, 0x209000F, 0x218000F, 0x227000E, 0x235000E, 0x243000E, + 0x251000E, 0x25F000D, 0x26C000D, 0x279000D, 0x286000D, 0x293000C, + 0x2A0000C, 0x2AC000C, 0x2B8000C, 0x2C4000C, 0x2D0000B, 0x2DC000B, + 0x2E7000B, 0x2F3000B, 0x2FE000B, 0x309000B, 0x314000B, 0x31F000A, + 0x32A000A, 0x334000B, 0x33F000A, 0x349000A, 0x354000A, 0x35E000A, + 0x368000A, 0x372000A, 0x37C000A, 0x386000A, 0x3900009, 0x399000A, + 0x3A30009, 0x3AD0009, 0x3B60009, 0x3BF000A, 0x3C90009, 0x3D20009, + 0x3DB0009, 0x3E40009, 0x3ED0009, 0x3F60009 }, + + /* 1 --> gamma 1/2 */ + { 0x7F, 0x800034, 0xB50028, 0xDE0021, 0x100001E, 0x11E001B, + 0x1390019, 0x1520017, 0x16A0015, 0x1800014, 0x1940014, 0x1A80013, + 0x1BB0012, 0x1CD0011, 0x1DF0010, 0x1EF0010, 0x200000F, 0x20F000F, + 0x21F000E, 0x22D000F, 0x23C000E, 0x24A000E, 0x258000D, 0x265000D, + 0x273000C, 0x27F000D, 0x28C000C, 0x299000C, 0x2A5000C, 0x2B1000B, + 0x2BC000C, 0x2C8000B, 0x2D3000C, 0x2DF000B, 0x2EA000A, 0x2F5000A, + 0x2FF000B, 0x30A000A, 0x314000B, 0x31F000A, 0x329000A, 0x333000A, + 0x33D0009, 0x3470009, 0x350000A, 0x35A0009, 0x363000A, 0x36D0009, + 0x3760009, 0x37F0009, 0x3880009, 0x3910009, 0x39A0009, 0x3A30009, + 0x3AC0008, 0x3B40009, 0x3BD0008, 0x3C60008, 0x3CE0008, 0x3D60009, + 0x3DF0008, 0x3E70008, 0x3EF0008, 0x3F70008 }, + + /* 2 --> gamma 1/2.2 */ + { 0x99, 0x9B0038, 0xD4002A, 0xFF0023, 0x122001F, 0x141001B, + 0x15D0019, 0x1760017, 0x18E0015, 0x1A30015, 0x1B80013, 0x1CC0012, + 0x1DE0011, 0x1F00010, 0x2010010, 0x2110010, 0x221000F, 0x230000F, + 0x23F000E, 0x24D000E, 0x25B000D, 0x269000C, 0x276000C, 0x283000C, + 0x28F000C, 0x29B000C, 0x2A7000C, 0x2B3000B, 0x2BF000B, 0x2CA000B, + 0x2D5000B, 0x2E0000A, 0x2EB000A, 0x2F5000A, 0x2FF000A, 0x30A000A, + 0x3140009, 0x31E0009, 0x327000A, 0x3310009, 0x33A0009, 0x3440009, + 0x34D0009, 0x3560009, 0x35F0009, 0x3680008, 0x3710008, 0x3790009, + 0x3820008, 0x38A0008, 0x3930008, 0x39B0008, 0x3A30008, 0x3AB0008, + 0x3B30008, 0x3BB0008, 0x3C30008, 0x3CB0007, 0x3D20008, 0x3DA0007, + 0x3E20007, 0x3E90007, 0x3F00008, 0x3F80007 }, +}; + static int isc_parse_dt(struct device *dev, struct isc_device *isc) { struct device_node *np = dev->of_node; @@ -150,6 +192,9 @@ static int atmel_isc_probe(struct platform_device *pdev) return ret; } + isc->gamma_table = isc_sama5d2_gamma_table; + isc->gamma_max = 2; + ret = isc_pipeline_init(isc); if (ret) return ret; From d5475b3c901a007e74544e7704a1c2107dbcc115 Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Tue, 13 Apr 2021 12:57:00 +0200 Subject: [PATCH 278/394] media: atmel: atmel-isc: specialize driver name constant The driver name constant must defined based on product driver, thus moving the constant directly where it's required. This will allow each ISC based product to define it's own name. Signed-off-by: Eugen Hristev Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/atmel/atmel-isc-base.c | 4 ++-- drivers/media/platform/atmel/atmel-isc.h | 2 -- drivers/media/platform/atmel/atmel-sama5d2-isc.c | 4 ++-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index 46d384332a58..d987a8891bd9 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -909,7 +909,7 @@ static int isc_querycap(struct file *file, void *priv, { struct isc_device *isc = video_drvdata(file); - strscpy(cap->driver, ATMEL_ISC_NAME, sizeof(cap->driver)); + strscpy(cap->driver, "microchip-isc", sizeof(cap->driver)); strscpy(cap->card, "Atmel Image Sensor Controller", sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", isc->v4l2_dev.name); @@ -2261,7 +2261,7 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier) } /* Register video device */ - strscpy(vdev->name, ATMEL_ISC_NAME, sizeof(vdev->name)); + strscpy(vdev->name, "microchip-isc", sizeof(vdev->name)); vdev->release = video_device_release_empty; vdev->fops = &isc_fops; vdev->ioctl_ops = &isc_ioctl_ops; diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h index f1df47a4655b..8d81d9967ad2 100644 --- a/drivers/media/platform/atmel/atmel-isc.h +++ b/drivers/media/platform/atmel/atmel-isc.h @@ -256,8 +256,6 @@ struct isc_device { u32 gamma_max; }; -#define ATMEL_ISC_NAME "atmel-isc" - extern struct isc_format formats_list[]; extern const struct isc_format controller_formats[]; extern const struct regmap_config isc_regmap_config; diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c index e7156169febe..7e94db04a796 100644 --- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c +++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c @@ -185,7 +185,7 @@ static int atmel_isc_probe(struct platform_device *pdev) return irq; ret = devm_request_irq(dev, irq, isc_interrupt, 0, - ATMEL_ISC_NAME, isc); + "atmel-sama5d2-isc", isc); if (ret < 0) { dev_err(dev, "can't register ISR for IRQ %u (ret=%i)\n", irq, ret); @@ -364,7 +364,7 @@ static struct platform_driver atmel_isc_driver = { .probe = atmel_isc_probe, .remove = atmel_isc_remove, .driver = { - .name = ATMEL_ISC_NAME, + .name = "atmel-sama5d2-isc", .pm = &atmel_isc_dev_pm_ops, .of_match_table = of_match_ptr(atmel_isc_of_match), }, From 5122e8d15a0703b6d8bf6cb703536d29f8aa74cf Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Tue, 13 Apr 2021 12:57:01 +0200 Subject: [PATCH 279/394] media: atmel: atmel-isc: add checks for limiting frame sizes When calling the subdev, certain subdev drivers will overwrite the frame size and adding sizes which are beyond the ISC's capabilities. Thus we need to ensure the frame size is cropped to the maximum caps. Signed-off-by: Eugen Hristev Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/atmel/atmel-isc-base.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index d987a8891bd9..02f1d1c6b06e 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -1338,6 +1338,12 @@ static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f, v4l2_fill_pix_format(pixfmt, &format.format); + /* Limit to Atmel ISC hardware capabilities */ + if (pixfmt->width > ISC_MAX_SUPPORT_WIDTH) + pixfmt->width = ISC_MAX_SUPPORT_WIDTH; + if (pixfmt->height > ISC_MAX_SUPPORT_HEIGHT) + pixfmt->height = ISC_MAX_SUPPORT_HEIGHT; + pixfmt->field = V4L2_FIELD_NONE; pixfmt->bytesperline = (pixfmt->width * isc->try_config.bpp) >> 3; pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height; @@ -1373,6 +1379,12 @@ static int isc_set_fmt(struct isc_device *isc, struct v4l2_format *f) if (ret < 0) return ret; + /* Limit to Atmel ISC hardware capabilities */ + if (pixfmt->width > ISC_MAX_SUPPORT_WIDTH) + pixfmt->width = ISC_MAX_SUPPORT_WIDTH; + if (pixfmt->height > ISC_MAX_SUPPORT_HEIGHT) + pixfmt->height = ISC_MAX_SUPPORT_HEIGHT; + isc->fmt = *f; if (isc->try_config.sd_format && isc->config.sd_format && From f794bc16a52da70e015dca0093bba9afba7d1b6c Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Tue, 13 Apr 2021 12:57:02 +0200 Subject: [PATCH 280/394] media: atmel: atmel-isc: specialize max width and max height Move the max width and max height constants to the product specific driver and have them in the device struct. Signed-off-by: Eugen Hristev Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/atmel/atmel-isc-base.c | 28 +++++++++---------- drivers/media/platform/atmel/atmel-isc.h | 9 ++++-- .../media/platform/atmel/atmel-sama5d2-isc.c | 7 +++-- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index 02f1d1c6b06e..ed0048e79f3b 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -1216,8 +1216,8 @@ static void isc_try_fse(struct isc_device *isc, * just use the maximum ISC can receive. */ if (ret) { - pad_cfg->try_crop.width = ISC_MAX_SUPPORT_WIDTH; - pad_cfg->try_crop.height = ISC_MAX_SUPPORT_HEIGHT; + pad_cfg->try_crop.width = isc->max_width; + pad_cfg->try_crop.height = isc->max_height; } else { pad_cfg->try_crop.width = fse.max_width; pad_cfg->try_crop.height = fse.max_height; @@ -1294,10 +1294,10 @@ static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f, isc->try_config.sd_format = sd_fmt; /* Limit to Atmel ISC hardware capabilities */ - if (pixfmt->width > ISC_MAX_SUPPORT_WIDTH) - pixfmt->width = ISC_MAX_SUPPORT_WIDTH; - if (pixfmt->height > ISC_MAX_SUPPORT_HEIGHT) - pixfmt->height = ISC_MAX_SUPPORT_HEIGHT; + if (pixfmt->width > isc->max_width) + pixfmt->width = isc->max_width; + if (pixfmt->height > isc->max_height) + pixfmt->height = isc->max_height; /* * The mbus format is the one the subdev outputs. @@ -1339,10 +1339,10 @@ static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f, v4l2_fill_pix_format(pixfmt, &format.format); /* Limit to Atmel ISC hardware capabilities */ - if (pixfmt->width > ISC_MAX_SUPPORT_WIDTH) - pixfmt->width = ISC_MAX_SUPPORT_WIDTH; - if (pixfmt->height > ISC_MAX_SUPPORT_HEIGHT) - pixfmt->height = ISC_MAX_SUPPORT_HEIGHT; + if (pixfmt->width > isc->max_width) + pixfmt->width = isc->max_width; + if (pixfmt->height > isc->max_height) + pixfmt->height = isc->max_height; pixfmt->field = V4L2_FIELD_NONE; pixfmt->bytesperline = (pixfmt->width * isc->try_config.bpp) >> 3; @@ -1380,10 +1380,10 @@ static int isc_set_fmt(struct isc_device *isc, struct v4l2_format *f) return ret; /* Limit to Atmel ISC hardware capabilities */ - if (pixfmt->width > ISC_MAX_SUPPORT_WIDTH) - pixfmt->width = ISC_MAX_SUPPORT_WIDTH; - if (pixfmt->height > ISC_MAX_SUPPORT_HEIGHT) - pixfmt->height = ISC_MAX_SUPPORT_HEIGHT; + if (f->fmt.pix.width > isc->max_width) + f->fmt.pix.width = isc->max_width; + if (f->fmt.pix.height > isc->max_height) + f->fmt.pix.height = isc->max_height; isc->fmt = *f; diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h index 8d81d9967ad2..6becc6c3aaf0 100644 --- a/drivers/media/platform/atmel/atmel-isc.h +++ b/drivers/media/platform/atmel/atmel-isc.h @@ -10,9 +10,6 @@ */ #ifndef _ATMEL_ISC_H_ -#define ISC_MAX_SUPPORT_WIDTH 2592 -#define ISC_MAX_SUPPORT_HEIGHT 1944 - #define ISC_CLK_MAX_DIV 255 enum isc_clk_id { @@ -191,6 +188,9 @@ struct isc_ctrls { * @gamma_table: pointer to the table with gamma values, has * gamma_max sets of GAMMA_ENTRIES entries each * @gamma_max: maximum number of sets of inside the gamma_table + * + * @max_width: maximum frame width, dependent on the internal RAM + * @max_height: maximum frame height, dependent on the internal RAM */ struct isc_device { struct regmap *regmap; @@ -254,6 +254,9 @@ struct isc_device { /* pointer to the defined gamma table */ const u32 (*gamma_table)[GAMMA_ENTRIES]; u32 gamma_max; + + u32 max_width; + u32 max_height; }; extern struct isc_format formats_list[]; diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c index 7e94db04a796..72112e025690 100644 --- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c +++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c @@ -49,8 +49,8 @@ #include "atmel-isc-regs.h" #include "atmel-isc.h" -#define ISC_MAX_SUPPORT_WIDTH 2592 -#define ISC_MAX_SUPPORT_HEIGHT 1944 +#define ISC_SAMA5D2_MAX_SUPPORT_WIDTH 2592 +#define ISC_SAMA5D2_MAX_SUPPORT_HEIGHT 1944 #define ISC_CLK_MAX_DIV 255 @@ -195,6 +195,9 @@ static int atmel_isc_probe(struct platform_device *pdev) isc->gamma_table = isc_sama5d2_gamma_table; isc->gamma_max = 2; + isc->max_width = ISC_SAMA5D2_MAX_SUPPORT_WIDTH; + isc->max_height = ISC_SAMA5D2_MAX_SUPPORT_HEIGHT; + ret = isc_pipeline_init(isc); if (ret) return ret; From cd5af39467bdc768387d841186a71bb2d947b29c Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Tue, 13 Apr 2021 12:57:03 +0200 Subject: [PATCH 281/394] media: atmel: atmel-isc: specialize dma cfg The dma configuration (DCFG) is specific to the product. Move this configuration in the product specific driver, and add the field inside the driver struct. Signed-off-by: Eugen Hristev Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/atmel/atmel-isc-base.c | 3 +-- drivers/media/platform/atmel/atmel-isc.h | 2 ++ drivers/media/platform/atmel/atmel-sama5d2-isc.c | 3 +++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index ed0048e79f3b..07ba439eb7e9 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -724,8 +724,7 @@ static int isc_configure(struct isc_device *isc) rlp_mode = isc->config.rlp_cfg_mode; pipeline = isc->config.bits_pipeline; - dcfg = isc->config.dcfg_imode | - ISC_DCFG_YMBSIZE_BEATS8 | ISC_DCFG_CMBSIZE_BEATS8; + dcfg = isc->config.dcfg_imode | isc->dcfg; pfe_cfg0 |= subdev->pfe_cfg0 | ISC_PFE_CFG0_MODE_PROGRESSIVE; mask = ISC_PFE_CFG0_BPS_MASK | ISC_PFE_CFG0_HPOL_LOW | diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h index 6becc6c3aaf0..d14ae096fbf6 100644 --- a/drivers/media/platform/atmel/atmel-isc.h +++ b/drivers/media/platform/atmel/atmel-isc.h @@ -150,6 +150,7 @@ struct isc_ctrls { * @hclock: Hclock clock input (refer datasheet) * @ispck: iscpck clock (refer datasheet) * @isc_clks: ISC clocks + * @dcfg: DMA master configuration, architecture dependent * * @dev: Registered device driver * @v4l2_dev: v4l2 registered device @@ -197,6 +198,7 @@ struct isc_device { struct clk *hclock; struct clk *ispck; struct isc_clk isc_clks[2]; + u32 dcfg; struct device *dev; struct v4l2_device v4l2_dev; diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c index 72112e025690..4fa5e86f4244 100644 --- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c +++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c @@ -198,6 +198,9 @@ static int atmel_isc_probe(struct platform_device *pdev) isc->max_width = ISC_SAMA5D2_MAX_SUPPORT_WIDTH; isc->max_height = ISC_SAMA5D2_MAX_SUPPORT_HEIGHT; + /* sama5d2-isc - 8 bits per beat */ + isc->dcfg = ISC_DCFG_YMBSIZE_BEATS8 | ISC_DCFG_CMBSIZE_BEATS8; + ret = isc_pipeline_init(isc); if (ret) return ret; From 2ede3975c0a8530663de38b485abbaa18ede0bad Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Tue, 13 Apr 2021 12:57:04 +0200 Subject: [PATCH 282/394] media: atmel: atmel-isc: extract CSC submodule config into separate function The CSC submodule is a part of the atmel-isc pipeline, and stands for Color Space Conversion. It is used to apply a matrix transformation to RGB pixels to convert them to the YUV components. The CSC submodule should be initialized in the product specific driver as it's product specific. Other products can implement it differently. [hverkuil: made isc_sama5d2_config_csc static] Signed-off-by: Eugen Hristev Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/atmel/atmel-isc-base.c | 8 +------- drivers/media/platform/atmel/atmel-isc.h | 7 +++++++ drivers/media/platform/atmel/atmel-sama5d2-isc.c | 15 +++++++++++++++ 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index 07ba439eb7e9..6c709f6a408c 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -654,13 +654,7 @@ static void isc_set_pipeline(struct isc_device *isc, u32 pipeline) regmap_bulk_write(regmap, ISC_GAM_GENTRY, gamma, GAMMA_ENTRIES); regmap_bulk_write(regmap, ISC_GAM_RENTRY, gamma, GAMMA_ENTRIES); - /* Convert RGB to YUV */ - regmap_write(regmap, ISC_CSC_YR_YG, 0x42 | (0x81 << 16)); - regmap_write(regmap, ISC_CSC_YB_OY, 0x19 | (0x10 << 16)); - regmap_write(regmap, ISC_CSC_CBR_CBG, 0xFDA | (0xFB6 << 16)); - regmap_write(regmap, ISC_CSC_CBB_OCB, 0x70 | (0x80 << 16)); - regmap_write(regmap, ISC_CSC_CRR_CRG, 0x70 | (0xFA2 << 16)); - regmap_write(regmap, ISC_CSC_CRB_OCR, 0xFEE | (0x80 << 16)); + isc->config_csc(isc); regmap_write(regmap, ISC_CBC_BRIGHT, ctrls->brightness); regmap_write(regmap, ISC_CBC_CONTRAST, ctrls->contrast); diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h index d14ae096fbf6..bb0b4419deff 100644 --- a/drivers/media/platform/atmel/atmel-isc.h +++ b/drivers/media/platform/atmel/atmel-isc.h @@ -192,6 +192,9 @@ struct isc_ctrls { * * @max_width: maximum frame width, dependent on the internal RAM * @max_height: maximum frame height, dependent on the internal RAM + * + * @config_csc: pointer to a function that initializes product + * specific CSC module */ struct isc_device { struct regmap *regmap; @@ -259,6 +262,10 @@ struct isc_device { u32 max_width; u32 max_height; + + struct { + void (*config_csc)(struct isc_device *isc); + }; }; extern struct isc_format formats_list[]; diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c index 4fa5e86f4244..9ea1cec7bdae 100644 --- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c +++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c @@ -54,6 +54,19 @@ #define ISC_CLK_MAX_DIV 255 +static void isc_sama5d2_config_csc(struct isc_device *isc) +{ + struct regmap *regmap = isc->regmap; + + /* Convert RGB to YUV */ + regmap_write(regmap, ISC_CSC_YR_YG, 0x42 | (0x81 << 16)); + regmap_write(regmap, ISC_CSC_YB_OY, 0x19 | (0x10 << 16)); + regmap_write(regmap, ISC_CSC_CBR_CBG, 0xFDA | (0xFB6 << 16)); + regmap_write(regmap, ISC_CSC_CBB_OCB, 0x70 | (0x80 << 16)); + regmap_write(regmap, ISC_CSC_CRR_CRG, 0x70 | (0xFA2 << 16)); + regmap_write(regmap, ISC_CSC_CRB_OCR, 0xFEE | (0x80 << 16)); +} + /* Gamma table with gamma 1/2.2 */ static const u32 isc_sama5d2_gamma_table[][GAMMA_ENTRIES] = { /* 0 --> gamma 1/1.8 */ @@ -198,6 +211,8 @@ static int atmel_isc_probe(struct platform_device *pdev) isc->max_width = ISC_SAMA5D2_MAX_SUPPORT_WIDTH; isc->max_height = ISC_SAMA5D2_MAX_SUPPORT_HEIGHT; + isc->config_csc = isc_sama5d2_config_csc; + /* sama5d2-isc - 8 bits per beat */ isc->dcfg = ISC_DCFG_YMBSIZE_BEATS8 | ISC_DCFG_CMBSIZE_BEATS8; From c59744de8a536130eba7916a010bba00bccee74b Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Tue, 13 Apr 2021 12:57:05 +0200 Subject: [PATCH 283/394] media: atmel: atmel-isc-base: add id to clock debug message Add the clock id to the debug message regarding clock setup Signed-off-by: Eugen Hristev Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/atmel/atmel-isc-base.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index 6c709f6a408c..f9190fccb482 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -281,8 +281,8 @@ static int isc_clk_enable(struct clk_hw *hw) unsigned long flags; unsigned int status; - dev_dbg(isc_clk->dev, "ISC CLK: %s, div = %d, parent id = %d\n", - __func__, isc_clk->div, isc_clk->parent_id); + dev_dbg(isc_clk->dev, "ISC CLK: %s, id = %d, div = %d, parent id = %d\n", + __func__, id, isc_clk->div, isc_clk->parent_id); spin_lock_irqsave(&isc_clk->lock, flags); regmap_update_bits(regmap, ISC_CLKCFG, From ffeeb01d11397bdeac0f5a1e1462eba440c23dc3 Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Tue, 13 Apr 2021 12:57:06 +0200 Subject: [PATCH 284/394] media: atmel: atmel-isc: create register offsets struct Create a struct that holds register offsets that are product specific. Add initially the CSC register. This allows each product that contains a variant of the ISC to add their own register offset. Signed-off-by: Eugen Hristev Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/atmel/atmel-isc-base.c | 2 +- drivers/media/platform/atmel/atmel-isc-regs.h | 3 +++ drivers/media/platform/atmel/atmel-isc.h | 12 +++++++++++ .../media/platform/atmel/atmel-sama5d2-isc.c | 20 +++++++++++++------ 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index f9190fccb482..18136e58a754 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -2326,7 +2326,7 @@ int isc_pipeline_init(struct isc_device *isc) REG_FIELD(ISC_GAM_CTRL, 1, 1), REG_FIELD(ISC_GAM_CTRL, 2, 2), REG_FIELD(ISC_GAM_CTRL, 3, 3), - REG_FIELD(ISC_CSC_CTRL, 0, 0), + REG_FIELD(ISC_CSC_CTRL + isc->offsets.csc, 0, 0), REG_FIELD(ISC_CBC_CTRL, 0, 0), REG_FIELD(ISC_SUB422_CTRL, 0, 0), REG_FIELD(ISC_SUB420_CTRL, 0, 0), diff --git a/drivers/media/platform/atmel/atmel-isc-regs.h b/drivers/media/platform/atmel/atmel-isc-regs.h index f1e160ed4351..5a65600c5f88 100644 --- a/drivers/media/platform/atmel/atmel-isc-regs.h +++ b/drivers/media/platform/atmel/atmel-isc-regs.h @@ -153,6 +153,9 @@ /* ISC_Gamma Correction Green Entry Register */ #define ISC_GAM_RENTRY 0x00000298 +/* Offset for CSC register specific to sama5d2 product */ +#define ISC_SAMA5D2_CSC_OFFSET 0 + /* Color Space Conversion Control Register */ #define ISC_CSC_CTRL 0x00000398 diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h index bb0b4419deff..ef3a0451192d 100644 --- a/drivers/media/platform/atmel/atmel-isc.h +++ b/drivers/media/platform/atmel/atmel-isc.h @@ -144,6 +144,14 @@ struct isc_ctrls { #define ISC_PIPE_LINE_NODE_NUM 11 +/* + * struct isc_reg_offsets - ISC device register offsets + * @csc: Offset for the CSC register + */ +struct isc_reg_offsets { + u32 csc; +}; + /* * struct isc_device - ISC device driver data/config struct * @regmap: Register map @@ -195,6 +203,8 @@ struct isc_ctrls { * * @config_csc: pointer to a function that initializes product * specific CSC module + * + * @offsets: struct holding the product specific register offsets */ struct isc_device { struct regmap *regmap; @@ -266,6 +276,8 @@ struct isc_device { struct { void (*config_csc)(struct isc_device *isc); }; + + struct isc_reg_offsets offsets; }; extern struct isc_format formats_list[]; diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c index 9ea1cec7bdae..607b9e306f9d 100644 --- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c +++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c @@ -59,12 +59,18 @@ static void isc_sama5d2_config_csc(struct isc_device *isc) struct regmap *regmap = isc->regmap; /* Convert RGB to YUV */ - regmap_write(regmap, ISC_CSC_YR_YG, 0x42 | (0x81 << 16)); - regmap_write(regmap, ISC_CSC_YB_OY, 0x19 | (0x10 << 16)); - regmap_write(regmap, ISC_CSC_CBR_CBG, 0xFDA | (0xFB6 << 16)); - regmap_write(regmap, ISC_CSC_CBB_OCB, 0x70 | (0x80 << 16)); - regmap_write(regmap, ISC_CSC_CRR_CRG, 0x70 | (0xFA2 << 16)); - regmap_write(regmap, ISC_CSC_CRB_OCR, 0xFEE | (0x80 << 16)); + regmap_write(regmap, ISC_CSC_YR_YG + isc->offsets.csc, + 0x42 | (0x81 << 16)); + regmap_write(regmap, ISC_CSC_YB_OY + isc->offsets.csc, + 0x19 | (0x10 << 16)); + regmap_write(regmap, ISC_CSC_CBR_CBG + isc->offsets.csc, + 0xFDA | (0xFB6 << 16)); + regmap_write(regmap, ISC_CSC_CBB_OCB + isc->offsets.csc, + 0x70 | (0x80 << 16)); + regmap_write(regmap, ISC_CSC_CRR_CRG + isc->offsets.csc, + 0x70 | (0xFA2 << 16)); + regmap_write(regmap, ISC_CSC_CRB_OCR + isc->offsets.csc, + 0xFEE | (0x80 << 16)); } /* Gamma table with gamma 1/2.2 */ @@ -213,6 +219,8 @@ static int atmel_isc_probe(struct platform_device *pdev) isc->config_csc = isc_sama5d2_config_csc; + isc->offsets.csc = ISC_SAMA5D2_CSC_OFFSET; + /* sama5d2-isc - 8 bits per beat */ isc->dcfg = ISC_DCFG_YMBSIZE_BEATS8 | ISC_DCFG_CMBSIZE_BEATS8; From d3b2ee5478c8569d32c4726c5920b96a9855419c Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Tue, 13 Apr 2021 12:57:07 +0200 Subject: [PATCH 285/394] media: atmel: atmel-isc: extract CBC submodule config into separate function The CBC submodule is a part of the atmel-isc pipeline, and stands for Contrast Brightness Control. It is used to apply gains and offsets to the luma (Y) and chroma (U, V) components of the YUV elements. The CBC submodule should be initialized in the product specific driver as it's product specific. Other products can implement it differently [hverkuil: made isc_sama5d2_config_cbc static] Signed-off-by: Eugen Hristev Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/atmel/atmel-isc-base.c | 4 +--- drivers/media/platform/atmel/atmel-isc.h | 3 +++ drivers/media/platform/atmel/atmel-sama5d2-isc.c | 9 +++++++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index 18136e58a754..865410e10e70 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -655,9 +655,7 @@ static void isc_set_pipeline(struct isc_device *isc, u32 pipeline) regmap_bulk_write(regmap, ISC_GAM_RENTRY, gamma, GAMMA_ENTRIES); isc->config_csc(isc); - - regmap_write(regmap, ISC_CBC_BRIGHT, ctrls->brightness); - regmap_write(regmap, ISC_CBC_CONTRAST, ctrls->contrast); + isc->config_cbc(isc); } static int isc_update_profile(struct isc_device *isc) diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h index ef3a0451192d..cb47932197b1 100644 --- a/drivers/media/platform/atmel/atmel-isc.h +++ b/drivers/media/platform/atmel/atmel-isc.h @@ -203,6 +203,8 @@ struct isc_reg_offsets { * * @config_csc: pointer to a function that initializes product * specific CSC module + * @config_cbc: pointer to a function that initializes product + * specific CBC module * * @offsets: struct holding the product specific register offsets */ @@ -275,6 +277,7 @@ struct isc_device { struct { void (*config_csc)(struct isc_device *isc); + void (*config_cbc)(struct isc_device *isc); }; struct isc_reg_offsets offsets; diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c index 607b9e306f9d..b5f654f263cc 100644 --- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c +++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c @@ -73,6 +73,14 @@ static void isc_sama5d2_config_csc(struct isc_device *isc) 0xFEE | (0x80 << 16)); } +static void isc_sama5d2_config_cbc(struct isc_device *isc) +{ + struct regmap *regmap = isc->regmap; + + regmap_write(regmap, ISC_CBC_BRIGHT, isc->ctrls.brightness); + regmap_write(regmap, ISC_CBC_CONTRAST, isc->ctrls.contrast); +} + /* Gamma table with gamma 1/2.2 */ static const u32 isc_sama5d2_gamma_table[][GAMMA_ENTRIES] = { /* 0 --> gamma 1/1.8 */ @@ -218,6 +226,7 @@ static int atmel_isc_probe(struct platform_device *pdev) isc->max_height = ISC_SAMA5D2_MAX_SUPPORT_HEIGHT; isc->config_csc = isc_sama5d2_config_csc; + isc->config_cbc = isc_sama5d2_config_cbc; isc->offsets.csc = ISC_SAMA5D2_CSC_OFFSET; From 4fc9e8a775d4b3630d1bab6ad58a02dae943787f Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Tue, 13 Apr 2021 12:57:08 +0200 Subject: [PATCH 286/394] media: atmel: atmel-isc: add CBC to the reg offsets struct The CBC submodule is a part of the atmel-isc pipeline, and stands for Contrast Brightness Control. It is used to apply gains and offsets to the luma (Y) and chroma (U, V) components of the YUV elements. Add cbc to the reg offsets struct. This will allow different products to have a different reg offset for this particular module. Signed-off-by: Eugen Hristev Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/atmel/atmel-isc-base.c | 2 +- drivers/media/platform/atmel/atmel-isc-regs.h | 3 +++ drivers/media/platform/atmel/atmel-isc.h | 2 ++ drivers/media/platform/atmel/atmel-sama5d2-isc.c | 7 +++++-- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index 865410e10e70..b7728914fda8 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -2325,7 +2325,7 @@ int isc_pipeline_init(struct isc_device *isc) REG_FIELD(ISC_GAM_CTRL, 2, 2), REG_FIELD(ISC_GAM_CTRL, 3, 3), REG_FIELD(ISC_CSC_CTRL + isc->offsets.csc, 0, 0), - REG_FIELD(ISC_CBC_CTRL, 0, 0), + REG_FIELD(ISC_CBC_CTRL + isc->offsets.cbc, 0, 0), REG_FIELD(ISC_SUB422_CTRL, 0, 0), REG_FIELD(ISC_SUB420_CTRL, 0, 0), }; diff --git a/drivers/media/platform/atmel/atmel-isc-regs.h b/drivers/media/platform/atmel/atmel-isc-regs.h index 5a65600c5f88..a5e2fe01ba9f 100644 --- a/drivers/media/platform/atmel/atmel-isc-regs.h +++ b/drivers/media/platform/atmel/atmel-isc-regs.h @@ -177,6 +177,9 @@ /* Color Space Conversion CRB OCR Register */ #define ISC_CSC_CRB_OCR 0x000003b0 +/* Offset for CBC register specific to sama5d2 product */ +#define ISC_SAMA5D2_CBC_OFFSET 0 + /* Contrast And Brightness Control Register */ #define ISC_CBC_CTRL 0x000003b4 diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h index cb47932197b1..b1fe93c93c61 100644 --- a/drivers/media/platform/atmel/atmel-isc.h +++ b/drivers/media/platform/atmel/atmel-isc.h @@ -147,9 +147,11 @@ struct isc_ctrls { /* * struct isc_reg_offsets - ISC device register offsets * @csc: Offset for the CSC register + * @cbc: Offset for the CBC register */ struct isc_reg_offsets { u32 csc; + u32 cbc; }; /* diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c index b5f654f263cc..657d50ae9fa8 100644 --- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c +++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c @@ -77,8 +77,10 @@ static void isc_sama5d2_config_cbc(struct isc_device *isc) { struct regmap *regmap = isc->regmap; - regmap_write(regmap, ISC_CBC_BRIGHT, isc->ctrls.brightness); - regmap_write(regmap, ISC_CBC_CONTRAST, isc->ctrls.contrast); + regmap_write(regmap, ISC_CBC_BRIGHT + isc->offsets.cbc, + isc->ctrls.brightness); + regmap_write(regmap, ISC_CBC_CONTRAST + isc->offsets.cbc, + isc->ctrls.contrast); } /* Gamma table with gamma 1/2.2 */ @@ -229,6 +231,7 @@ static int atmel_isc_probe(struct platform_device *pdev) isc->config_cbc = isc_sama5d2_config_cbc; isc->offsets.csc = ISC_SAMA5D2_CSC_OFFSET; + isc->offsets.cbc = ISC_SAMA5D2_CBC_OFFSET; /* sama5d2-isc - 8 bits per beat */ isc->dcfg = ISC_DCFG_YMBSIZE_BEATS8 | ISC_DCFG_CMBSIZE_BEATS8; From 87b62b6d55dd78597b95f3df8111e3d533357b89 Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Tue, 13 Apr 2021 12:57:09 +0200 Subject: [PATCH 287/394] media: atmel: atmel-isc: add SUB422 and SUB420 to register offsets The SUB submodules are a part of the atmel-isc pipeline, and stand for Subsampling. They are used to subsample the original YUV 4:4:4 pixel ratio aspect to either 4:2:2 or 4:2:0. Add sub420 and sub422 to the reg offsets struct. This will allow different products to have a different reg offset for these particular modules. Signed-off-by: Eugen Hristev Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/atmel/atmel-isc-base.c | 4 ++-- drivers/media/platform/atmel/atmel-isc-regs.h | 4 ++++ drivers/media/platform/atmel/atmel-isc.h | 4 ++++ drivers/media/platform/atmel/atmel-sama5d2-isc.c | 2 ++ 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index b7728914fda8..b398cdfdc2c9 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -2326,8 +2326,8 @@ int isc_pipeline_init(struct isc_device *isc) REG_FIELD(ISC_GAM_CTRL, 3, 3), REG_FIELD(ISC_CSC_CTRL + isc->offsets.csc, 0, 0), REG_FIELD(ISC_CBC_CTRL + isc->offsets.cbc, 0, 0), - REG_FIELD(ISC_SUB422_CTRL, 0, 0), - REG_FIELD(ISC_SUB420_CTRL, 0, 0), + REG_FIELD(ISC_SUB422_CTRL + isc->offsets.sub422, 0, 0), + REG_FIELD(ISC_SUB420_CTRL + isc->offsets.sub420, 0, 0), }; for (i = 0; i < ISC_PIPE_LINE_NODE_NUM; i++) { diff --git a/drivers/media/platform/atmel/atmel-isc-regs.h b/drivers/media/platform/atmel/atmel-isc-regs.h index a5e2fe01ba9f..04839def6ef6 100644 --- a/drivers/media/platform/atmel/atmel-isc-regs.h +++ b/drivers/media/platform/atmel/atmel-isc-regs.h @@ -194,9 +194,13 @@ #define ISC_CBC_CONTRAST 0x000003c0 #define ISC_CBC_CONTRAST_MASK GENMASK(11, 0) +/* Offset for SUB422 register specific to sama5d2 product */ +#define ISC_SAMA5D2_SUB422_OFFSET 0 /* Subsampling 4:4:4 to 4:2:2 Control Register */ #define ISC_SUB422_CTRL 0x000003c4 +/* Offset for SUB420 register specific to sama5d2 product */ +#define ISC_SAMA5D2_SUB420_OFFSET 0 /* Subsampling 4:2:2 to 4:2:0 Control Register */ #define ISC_SUB420_CTRL 0x000003cc diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h index b1fe93c93c61..fb7257872e7c 100644 --- a/drivers/media/platform/atmel/atmel-isc.h +++ b/drivers/media/platform/atmel/atmel-isc.h @@ -148,10 +148,14 @@ struct isc_ctrls { * struct isc_reg_offsets - ISC device register offsets * @csc: Offset for the CSC register * @cbc: Offset for the CBC register + * @sub422: Offset for the SUB422 register + * @sub420: Offset for the SUB420 register */ struct isc_reg_offsets { u32 csc; u32 cbc; + u32 sub422; + u32 sub420; }; /* diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c index 657d50ae9fa8..8211ee9bd8b9 100644 --- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c +++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c @@ -232,6 +232,8 @@ static int atmel_isc_probe(struct platform_device *pdev) isc->offsets.csc = ISC_SAMA5D2_CSC_OFFSET; isc->offsets.cbc = ISC_SAMA5D2_CBC_OFFSET; + isc->offsets.sub422 = ISC_SAMA5D2_SUB422_OFFSET; + isc->offsets.sub420 = ISC_SAMA5D2_SUB420_OFFSET; /* sama5d2-isc - 8 bits per beat */ isc->dcfg = ISC_DCFG_YMBSIZE_BEATS8 | ISC_DCFG_CMBSIZE_BEATS8; From 40ee17d1b41ccc8c65f831d37008e25d3ae03646 Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Tue, 13 Apr 2021 12:57:10 +0200 Subject: [PATCH 288/394] media: atmel: atmel-isc: add RLP to register offsets The RLP submodule is a part of the atmel-isc pipeline, and stands for Rounding,Limiting and Packaging. It used to extract specific data from the ISC pipeline. For example if we want to output greyscale 8 bit, we would use limiting to 8 bits, and packaging to Luma component only. Add rlp to the reg offsets struct. This will allow different products to have a different reg offset for this particular module. Signed-off-by: Eugen Hristev Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/atmel/atmel-isc-base.c | 4 ++-- drivers/media/platform/atmel/atmel-isc-regs.h | 2 ++ drivers/media/platform/atmel/atmel-isc.h | 2 ++ drivers/media/platform/atmel/atmel-sama5d2-isc.c | 1 + 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index b398cdfdc2c9..25c90b821067 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -726,8 +726,8 @@ static int isc_configure(struct isc_device *isc) regmap_update_bits(regmap, ISC_PFE_CFG0, mask, pfe_cfg0); - regmap_update_bits(regmap, ISC_RLP_CFG, ISC_RLP_CFG_MODE_MASK, - rlp_mode); + regmap_update_bits(regmap, ISC_RLP_CFG + isc->offsets.rlp, + ISC_RLP_CFG_MODE_MASK, rlp_mode); regmap_write(regmap, ISC_DCFG, dcfg); diff --git a/drivers/media/platform/atmel/atmel-isc-regs.h b/drivers/media/platform/atmel/atmel-isc-regs.h index 04839def6ef6..2205484e04fc 100644 --- a/drivers/media/platform/atmel/atmel-isc-regs.h +++ b/drivers/media/platform/atmel/atmel-isc-regs.h @@ -204,6 +204,8 @@ /* Subsampling 4:2:2 to 4:2:0 Control Register */ #define ISC_SUB420_CTRL 0x000003cc +/* Offset for RLP register specific to sama5d2 product */ +#define ISC_SAMA5D2_RLP_OFFSET 0 /* Rounding, Limiting and Packing Configuration Register */ #define ISC_RLP_CFG 0x000003d0 diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h index fb7257872e7c..b7d4e7fab570 100644 --- a/drivers/media/platform/atmel/atmel-isc.h +++ b/drivers/media/platform/atmel/atmel-isc.h @@ -150,12 +150,14 @@ struct isc_ctrls { * @cbc: Offset for the CBC register * @sub422: Offset for the SUB422 register * @sub420: Offset for the SUB420 register + * @rlp: Offset for the RLP register */ struct isc_reg_offsets { u32 csc; u32 cbc; u32 sub422; u32 sub420; + u32 rlp; }; /* diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c index 8211ee9bd8b9..06257806c8ae 100644 --- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c +++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c @@ -234,6 +234,7 @@ static int atmel_isc_probe(struct platform_device *pdev) isc->offsets.cbc = ISC_SAMA5D2_CBC_OFFSET; isc->offsets.sub422 = ISC_SAMA5D2_SUB422_OFFSET; isc->offsets.sub420 = ISC_SAMA5D2_SUB420_OFFSET; + isc->offsets.rlp = ISC_SAMA5D2_RLP_OFFSET; /* sama5d2-isc - 8 bits per beat */ isc->dcfg = ISC_DCFG_YMBSIZE_BEATS8 | ISC_DCFG_CMBSIZE_BEATS8; From 1a3ac5d51541b6a816380bafd7c3e240ff9542d9 Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Tue, 13 Apr 2021 12:57:11 +0200 Subject: [PATCH 289/394] media: atmel: atmel-isc: add HIS to register offsets The HIS submodule is a part of the atmel-isc pipeline, and stands for Histogram. This module performs a color histogram that can be read and used by the main processor. Add his to the reg offsets struct. This will allow different products to have a different reg offset for this particular module. Signed-off-by: Eugen Hristev Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/atmel/atmel-isc-base.c | 11 +++++++---- drivers/media/platform/atmel/atmel-isc-regs.h | 2 ++ drivers/media/platform/atmel/atmel-isc.h | 2 ++ drivers/media/platform/atmel/atmel-sama5d2-isc.c | 1 + 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index 25c90b821067..5c95aa45cf6c 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -686,12 +686,13 @@ static void isc_set_histogram(struct isc_device *isc, bool enable) struct isc_ctrls *ctrls = &isc->ctrls; if (enable) { - regmap_write(regmap, ISC_HIS_CFG, + regmap_write(regmap, ISC_HIS_CFG + isc->offsets.his, ISC_HIS_CFG_MODE_GR | (isc->config.sd_format->cfa_baycfg << ISC_HIS_CFG_BAYSEL_SHIFT) | ISC_HIS_CFG_RAR); - regmap_write(regmap, ISC_HIS_CTRL, ISC_HIS_CTRL_EN); + regmap_write(regmap, ISC_HIS_CTRL + isc->offsets.his, + ISC_HIS_CTRL_EN); regmap_write(regmap, ISC_INTEN, ISC_INT_HISDONE); ctrls->hist_id = ISC_HIS_CFG_MODE_GR; isc_update_profile(isc); @@ -700,7 +701,8 @@ static void isc_set_histogram(struct isc_device *isc, bool enable) ctrls->hist_stat = HIST_ENABLED; } else { regmap_write(regmap, ISC_INTDIS, ISC_INT_HISDONE); - regmap_write(regmap, ISC_HIS_CTRL, ISC_HIS_CTRL_DIS); + regmap_write(regmap, ISC_HIS_CTRL + isc->offsets.his, + ISC_HIS_CTRL_DIS); ctrls->hist_stat = HIST_DISABLED; } @@ -1836,7 +1838,8 @@ static void isc_awb_work(struct work_struct *w) ctrls->awb = ISC_WB_NONE; } } - regmap_write(regmap, ISC_HIS_CFG, hist_id | baysel | ISC_HIS_CFG_RAR); + regmap_write(regmap, ISC_HIS_CFG + isc->offsets.his, + hist_id | baysel | ISC_HIS_CFG_RAR); isc_update_profile(isc); /* if awb has been disabled, we don't need to start another histogram */ if (ctrls->awb) diff --git a/drivers/media/platform/atmel/atmel-isc-regs.h b/drivers/media/platform/atmel/atmel-isc-regs.h index 2205484e04fc..0ab280ab59ec 100644 --- a/drivers/media/platform/atmel/atmel-isc-regs.h +++ b/drivers/media/platform/atmel/atmel-isc-regs.h @@ -224,6 +224,8 @@ #define ISC_RLP_CFG_MODE_YYCC_LIMITED 0xc #define ISC_RLP_CFG_MODE_MASK GENMASK(3, 0) +/* Offset for HIS register specific to sama5d2 product */ +#define ISC_SAMA5D2_HIS_OFFSET 0 /* Histogram Control Register */ #define ISC_HIS_CTRL 0x000003d4 diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h index b7d4e7fab570..652285dc9f52 100644 --- a/drivers/media/platform/atmel/atmel-isc.h +++ b/drivers/media/platform/atmel/atmel-isc.h @@ -151,6 +151,7 @@ struct isc_ctrls { * @sub422: Offset for the SUB422 register * @sub420: Offset for the SUB420 register * @rlp: Offset for the RLP register + * @his: Offset for the HIS related registers */ struct isc_reg_offsets { u32 csc; @@ -158,6 +159,7 @@ struct isc_reg_offsets { u32 sub422; u32 sub420; u32 rlp; + u32 his; }; /* diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c index 06257806c8ae..77be62a070db 100644 --- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c +++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c @@ -235,6 +235,7 @@ static int atmel_isc_probe(struct platform_device *pdev) isc->offsets.sub422 = ISC_SAMA5D2_SUB422_OFFSET; isc->offsets.sub420 = ISC_SAMA5D2_SUB420_OFFSET; isc->offsets.rlp = ISC_SAMA5D2_RLP_OFFSET; + isc->offsets.his = ISC_SAMA5D2_HIS_OFFSET; /* sama5d2-isc - 8 bits per beat */ isc->dcfg = ISC_DCFG_YMBSIZE_BEATS8 | ISC_DCFG_CMBSIZE_BEATS8; From e891009857716e17129899fe6345e7968010917f Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Tue, 13 Apr 2021 12:57:12 +0200 Subject: [PATCH 290/394] media: atmel: atmel-isc: add DMA to register offsets The DMA submodule is a part of the atmel-isc pipeline, and stands for Direct Memory Access. It acts like a master on the AXI bus of the SoC, and can directly write the RAM area with the pixel data from the ISC internal sram. Add dma to the reg offsets struct. This will allow different products to have a different reg offset for this particular module. Signed-off-by: Eugen Hristev Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/atmel/atmel-isc-base.c | 19 ++++++++++++------- drivers/media/platform/atmel/atmel-isc-regs.h | 3 +++ drivers/media/platform/atmel/atmel-isc.h | 2 ++ .../media/platform/atmel/atmel-sama5d2-isc.c | 1 + 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index 5c95aa45cf6c..e010429fc44d 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -601,16 +601,20 @@ static void isc_start_dma(struct isc_device *isc) ISC_PFE_CFG0_COLEN | ISC_PFE_CFG0_ROWEN); addr0 = vb2_dma_contig_plane_dma_addr(&isc->cur_frm->vb.vb2_buf, 0); - regmap_write(regmap, ISC_DAD0, addr0); + regmap_write(regmap, ISC_DAD0 + isc->offsets.dma, addr0); switch (isc->config.fourcc) { case V4L2_PIX_FMT_YUV420: - regmap_write(regmap, ISC_DAD1, addr0 + (sizeimage * 2) / 3); - regmap_write(regmap, ISC_DAD2, addr0 + (sizeimage * 5) / 6); + regmap_write(regmap, ISC_DAD1 + isc->offsets.dma, + addr0 + (sizeimage * 2) / 3); + regmap_write(regmap, ISC_DAD2 + isc->offsets.dma, + addr0 + (sizeimage * 5) / 6); break; case V4L2_PIX_FMT_YUV422P: - regmap_write(regmap, ISC_DAD1, addr0 + sizeimage / 2); - regmap_write(regmap, ISC_DAD2, addr0 + (sizeimage * 3) / 4); + regmap_write(regmap, ISC_DAD1 + isc->offsets.dma, + addr0 + sizeimage / 2); + regmap_write(regmap, ISC_DAD2 + isc->offsets.dma, + addr0 + (sizeimage * 3) / 4); break; default: break; @@ -618,7 +622,8 @@ static void isc_start_dma(struct isc_device *isc) dctrl_dview = isc->config.dctrl_dview; - regmap_write(regmap, ISC_DCTRL, dctrl_dview | ISC_DCTRL_IE_IS); + regmap_write(regmap, ISC_DCTRL + isc->offsets.dma, + dctrl_dview | ISC_DCTRL_IE_IS); spin_lock(&isc->awb_lock); regmap_write(regmap, ISC_CTRLEN, ISC_CTRL_CAPTURE); spin_unlock(&isc->awb_lock); @@ -731,7 +736,7 @@ static int isc_configure(struct isc_device *isc) regmap_update_bits(regmap, ISC_RLP_CFG + isc->offsets.rlp, ISC_RLP_CFG_MODE_MASK, rlp_mode); - regmap_write(regmap, ISC_DCFG, dcfg); + regmap_write(regmap, ISC_DCFG + isc->offsets.dma, dcfg); /* Set the pipeline */ isc_set_pipeline(isc, pipeline); diff --git a/drivers/media/platform/atmel/atmel-isc-regs.h b/drivers/media/platform/atmel/atmel-isc-regs.h index 0ab280ab59ec..4940998c82a2 100644 --- a/drivers/media/platform/atmel/atmel-isc-regs.h +++ b/drivers/media/platform/atmel/atmel-isc-regs.h @@ -247,6 +247,9 @@ #define ISC_HIS_CFG_RAR BIT(8) +/* Offset for DMA register specific to sama5d2 product */ +#define ISC_SAMA5D2_DMA_OFFSET 0 + /* DMA Configuration Register */ #define ISC_DCFG 0x000003e0 #define ISC_DCFG_IMODE_PACKED8 0x0 diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h index 652285dc9f52..52a9199d65ee 100644 --- a/drivers/media/platform/atmel/atmel-isc.h +++ b/drivers/media/platform/atmel/atmel-isc.h @@ -152,6 +152,7 @@ struct isc_ctrls { * @sub420: Offset for the SUB420 register * @rlp: Offset for the RLP register * @his: Offset for the HIS related registers + * @dma: Offset for the DMA related registers */ struct isc_reg_offsets { u32 csc; @@ -160,6 +161,7 @@ struct isc_reg_offsets { u32 sub420; u32 rlp; u32 his; + u32 dma; }; /* diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c index 77be62a070db..0b31dcf1443b 100644 --- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c +++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c @@ -236,6 +236,7 @@ static int atmel_isc_probe(struct platform_device *pdev) isc->offsets.sub420 = ISC_SAMA5D2_SUB420_OFFSET; isc->offsets.rlp = ISC_SAMA5D2_RLP_OFFSET; isc->offsets.his = ISC_SAMA5D2_HIS_OFFSET; + isc->offsets.dma = ISC_SAMA5D2_DMA_OFFSET; /* sama5d2-isc - 8 bits per beat */ isc->dcfg = ISC_DCFG_YMBSIZE_BEATS8 | ISC_DCFG_CMBSIZE_BEATS8; From d51470069eb169d54f2b14d07d613b69f62615b8 Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Tue, 13 Apr 2021 12:57:13 +0200 Subject: [PATCH 291/394] media: atmel: atmel-isc: add support for version register Add support for version register and print it at probe time. Signed-off-by: Eugen Hristev Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/atmel/atmel-isc-regs.h | 5 +++++ drivers/media/platform/atmel/atmel-isc.h | 2 ++ drivers/media/platform/atmel/atmel-sama5d2-isc.c | 5 +++++ 3 files changed, 12 insertions(+) diff --git a/drivers/media/platform/atmel/atmel-isc-regs.h b/drivers/media/platform/atmel/atmel-isc-regs.h index 4940998c82a2..344668dcfcf4 100644 --- a/drivers/media/platform/atmel/atmel-isc-regs.h +++ b/drivers/media/platform/atmel/atmel-isc-regs.h @@ -295,6 +295,11 @@ /* DMA Address 2 Register */ #define ISC_DAD2 0x000003fc +/* Offset for version register specific to sama5d2 product */ +#define ISC_SAMA5D2_VERSION_OFFSET 0 +/* Version Register */ +#define ISC_VERSION 0x0000040c + /* Histogram Entry */ #define ISC_HIS_ENTRY 0x00000410 diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h index 52a9199d65ee..676a5be1ee8c 100644 --- a/drivers/media/platform/atmel/atmel-isc.h +++ b/drivers/media/platform/atmel/atmel-isc.h @@ -153,6 +153,7 @@ struct isc_ctrls { * @rlp: Offset for the RLP register * @his: Offset for the HIS related registers * @dma: Offset for the DMA related registers + * @version: Offset for the version register */ struct isc_reg_offsets { u32 csc; @@ -162,6 +163,7 @@ struct isc_reg_offsets { u32 rlp; u32 his; u32 dma; + u32 version; }; /* diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c index 0b31dcf1443b..059dc5d3c664 100644 --- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c +++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c @@ -189,6 +189,7 @@ static int atmel_isc_probe(struct platform_device *pdev) struct isc_subdev_entity *subdev_entity; int irq; int ret; + u32 ver; isc = devm_kzalloc(dev, sizeof(*isc), GFP_KERNEL); if (!isc) @@ -237,6 +238,7 @@ static int atmel_isc_probe(struct platform_device *pdev) isc->offsets.rlp = ISC_SAMA5D2_RLP_OFFSET; isc->offsets.his = ISC_SAMA5D2_HIS_OFFSET; isc->offsets.dma = ISC_SAMA5D2_DMA_OFFSET; + isc->offsets.version = ISC_SAMA5D2_VERSION_OFFSET; /* sama5d2-isc - 8 bits per beat */ isc->dcfg = ISC_DCFG_YMBSIZE_BEATS8 | ISC_DCFG_CMBSIZE_BEATS8; @@ -332,6 +334,9 @@ static int atmel_isc_probe(struct platform_device *pdev) pm_runtime_enable(dev); pm_request_idle(dev); + regmap_read(isc->regmap, ISC_VERSION + isc->offsets.version, &ver); + dev_info(dev, "Microchip ISC version %x\n", ver); + return 0; cleanup_subdev: From 629de518e6f3b81bc1d7486a9b2e0a8fb100e18e Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Tue, 13 Apr 2021 12:57:14 +0200 Subject: [PATCH 292/394] media: atmel: atmel-isc: add his_entry to register offsets Add his_entry to the reg offsets struct. This will allow different products to have a different reg offset for this particular module. Signed-off-by: Eugen Hristev Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/atmel/atmel-isc-base.c | 3 ++- drivers/media/platform/atmel/atmel-isc-regs.h | 2 ++ drivers/media/platform/atmel/atmel-isc.h | 2 ++ drivers/media/platform/atmel/atmel-sama5d2-isc.c | 1 + 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index e010429fc44d..cfe60b2882ac 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -1684,7 +1684,8 @@ static void isc_hist_count(struct isc_device *isc, u32 *min, u32 *max) *min = 0; *max = HIST_ENTRIES; - regmap_bulk_read(regmap, ISC_HIS_ENTRY, hist_entry, HIST_ENTRIES); + regmap_bulk_read(regmap, ISC_HIS_ENTRY + isc->offsets.his_entry, + hist_entry, HIST_ENTRIES); *hist_count = 0; /* diff --git a/drivers/media/platform/atmel/atmel-isc-regs.h b/drivers/media/platform/atmel/atmel-isc-regs.h index 344668dcfcf4..a15c13e1a833 100644 --- a/drivers/media/platform/atmel/atmel-isc-regs.h +++ b/drivers/media/platform/atmel/atmel-isc-regs.h @@ -300,6 +300,8 @@ /* Version Register */ #define ISC_VERSION 0x0000040c +/* Offset for version register specific to sama5d2 product */ +#define ISC_SAMA5D2_HIS_ENTRY_OFFSET 0 /* Histogram Entry */ #define ISC_HIS_ENTRY 0x00000410 diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h index 676a5be1ee8c..c5d956fd20a0 100644 --- a/drivers/media/platform/atmel/atmel-isc.h +++ b/drivers/media/platform/atmel/atmel-isc.h @@ -154,6 +154,7 @@ struct isc_ctrls { * @his: Offset for the HIS related registers * @dma: Offset for the DMA related registers * @version: Offset for the version register + * @his_entry: Offset for the HIS entries registers */ struct isc_reg_offsets { u32 csc; @@ -164,6 +165,7 @@ struct isc_reg_offsets { u32 his; u32 dma; u32 version; + u32 his_entry; }; /* diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c index 059dc5d3c664..72cb91b4b8ba 100644 --- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c +++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c @@ -239,6 +239,7 @@ static int atmel_isc_probe(struct platform_device *pdev) isc->offsets.his = ISC_SAMA5D2_HIS_OFFSET; isc->offsets.dma = ISC_SAMA5D2_DMA_OFFSET; isc->offsets.version = ISC_SAMA5D2_VERSION_OFFSET; + isc->offsets.his_entry = ISC_SAMA5D2_HIS_ENTRY_OFFSET; /* sama5d2-isc - 8 bits per beat */ isc->dcfg = ISC_DCFG_YMBSIZE_BEATS8 | ISC_DCFG_CMBSIZE_BEATS8; From a911e927443477d67f4c577bfb68b0d41680f4a0 Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Tue, 13 Apr 2021 12:57:15 +0200 Subject: [PATCH 293/394] media: atmel: atmel-isc: add register description for additional modules Add register description for additional pipeline modules: the Defective Pixel Correction (DPC) and the Vertical and Horizontal Scaler(VHXS) Signed-off-by: Eugen Hristev Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/atmel/atmel-isc-regs.h | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/drivers/media/platform/atmel/atmel-isc-regs.h b/drivers/media/platform/atmel/atmel-isc-regs.h index a15c13e1a833..457eed74cda9 100644 --- a/drivers/media/platform/atmel/atmel-isc-regs.h +++ b/drivers/media/platform/atmel/atmel-isc-regs.h @@ -90,6 +90,46 @@ #define ISC_INT_DDONE BIT(8) #define ISC_INT_HISDONE BIT(12) +/* ISC DPC Control Register */ +#define ISC_DPC_CTRL 0x40 + +#define ISC_DPC_CTRL_DPCEN BIT(0) +#define ISC_DPC_CTRL_GDCEN BIT(1) +#define ISC_DPC_CTRL_BLCEN BIT(2) + +/* ISC DPC Config Register */ +#define ISC_DPC_CFG 0x44 + +#define ISC_DPC_CFG_BAYSEL_SHIFT 0 + +#define ISC_DPC_CFG_EITPOL BIT(4) + +#define ISC_DPC_CFG_TA_ENABLE BIT(14) +#define ISC_DPC_CFG_TC_ENABLE BIT(13) +#define ISC_DPC_CFG_TM_ENABLE BIT(12) + +#define ISC_DPC_CFG_RE_MODE BIT(17) + +#define ISC_DPC_CFG_GDCCLP_SHIFT 20 +#define ISC_DPC_CFG_GDCCLP_MASK GENMASK(22, 20) + +#define ISC_DPC_CFG_BLOFF_SHIFT 24 +#define ISC_DPC_CFG_BLOFF_MASK GENMASK(31, 24) + +#define ISC_DPC_CFG_BAYCFG_SHIFT 0 +#define ISC_DPC_CFG_BAYCFG_MASK GENMASK(1, 0) +/* ISC DPC Threshold Median Register */ +#define ISC_DPC_THRESHM 0x48 + +/* ISC DPC Threshold Closest Register */ +#define ISC_DPC_THRESHC 0x4C + +/* ISC DPC Threshold Average Register */ +#define ISC_DPC_THRESHA 0x50 + +/* ISC DPC STatus Register */ +#define ISC_DPC_SR 0x54 + /* ISC White Balance Control Register */ #define ISC_WB_CTRL 0x00000058 @@ -153,6 +193,33 @@ /* ISC_Gamma Correction Green Entry Register */ #define ISC_GAM_RENTRY 0x00000298 +/* ISC VHXS Control Register */ +#define ISC_VHXS_CTRL 0x398 + +/* ISC VHXS Source Size Register */ +#define ISC_VHXS_SS 0x39C + +/* ISC VHXS Destination Size Register */ +#define ISC_VHXS_DS 0x3A0 + +/* ISC Vertical Factor Register */ +#define ISC_VXS_FACT 0x3a4 + +/* ISC Horizontal Factor Register */ +#define ISC_HXS_FACT 0x3a8 + +/* ISC Vertical Config Register */ +#define ISC_VXS_CFG 0x3ac + +/* ISC Horizontal Config Register */ +#define ISC_HXS_CFG 0x3b0 + +/* ISC Vertical Tap Register */ +#define ISC_VXS_TAP 0x3b4 + +/* ISC Horizontal Tap Register */ +#define ISC_HXS_TAP 0x434 + /* Offset for CSC register specific to sama5d2 product */ #define ISC_SAMA5D2_CSC_OFFSET 0 From 5507b10109253a19765880fffff6e9fff3810868 Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Tue, 13 Apr 2021 12:57:16 +0200 Subject: [PATCH 294/394] media: atmel: atmel-isc: extend pipeline with extra modules Newer ISC pipelines have the additional modules of Defective Pixel Correction -> DPC itself, Defective Pixel Correction -> Green Disparity Correction (DPC_GDC) Defective Pixel Correction -> Black Level Correction (DPC_BLC) Vertical and Horizontal Scaler -> VHXS Some products have this full pipeline (sama7g5), other products do not (sama5d2) Add the modules to the isc base, and also extend the register range to include the modules. Signed-off-by: Eugen Hristev Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/atmel/atmel-isc-base.c | 11 ++++++-- drivers/media/platform/atmel/atmel-isc.h | 28 +++++++++++-------- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index cfe60b2882ac..a6b62e009c38 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -2324,8 +2324,14 @@ int isc_pipeline_init(struct isc_device *isc) struct regmap_field *regs; unsigned int i; - /* WB-->CFA-->CC-->GAM-->CSC-->CBC-->SUB422-->SUB420 */ + /* + * DPCEN-->GDCEN-->BLCEN-->WB-->CFA-->CC--> + * GAM-->VHXS-->CSC-->CBC-->SUB422-->SUB420 + */ const struct reg_field regfields[ISC_PIPE_LINE_NODE_NUM] = { + REG_FIELD(ISC_DPC_CTRL, 0, 0), + REG_FIELD(ISC_DPC_CTRL, 1, 1), + REG_FIELD(ISC_DPC_CTRL, 2, 2), REG_FIELD(ISC_WB_CTRL, 0, 0), REG_FIELD(ISC_CFA_CTRL, 0, 0), REG_FIELD(ISC_CC_CTRL, 0, 0), @@ -2333,6 +2339,7 @@ int isc_pipeline_init(struct isc_device *isc) REG_FIELD(ISC_GAM_CTRL, 1, 1), REG_FIELD(ISC_GAM_CTRL, 2, 2), REG_FIELD(ISC_GAM_CTRL, 3, 3), + REG_FIELD(ISC_VHXS_CTRL, 0, 0), REG_FIELD(ISC_CSC_CTRL + isc->offsets.csc, 0, 0), REG_FIELD(ISC_CBC_CTRL + isc->offsets.cbc, 0, 0), REG_FIELD(ISC_SUB422_CTRL + isc->offsets.sub422, 0, 0), @@ -2351,7 +2358,7 @@ int isc_pipeline_init(struct isc_device *isc) } /* regmap configuration */ -#define ATMEL_ISC_REG_MAX 0xbfc +#define ATMEL_ISC_REG_MAX 0xd5c const struct regmap_config isc_regmap_config = { .reg_bits = 32, .reg_stride = 4, diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h index c5d956fd20a0..f574bcc3ba67 100644 --- a/drivers/media/platform/atmel/atmel-isc.h +++ b/drivers/media/platform/atmel/atmel-isc.h @@ -68,17 +68,21 @@ struct isc_format { }; /* Pipeline bitmap */ -#define WB_ENABLE BIT(0) -#define CFA_ENABLE BIT(1) -#define CC_ENABLE BIT(2) -#define GAM_ENABLE BIT(3) -#define GAM_BENABLE BIT(4) -#define GAM_GENABLE BIT(5) -#define GAM_RENABLE BIT(6) -#define CSC_ENABLE BIT(7) -#define CBC_ENABLE BIT(8) -#define SUB422_ENABLE BIT(9) -#define SUB420_ENABLE BIT(10) +#define DPC_DPCENABLE BIT(0) +#define DPC_GDCENABLE BIT(1) +#define DPC_BLCENABLE BIT(2) +#define WB_ENABLE BIT(3) +#define CFA_ENABLE BIT(4) +#define CC_ENABLE BIT(5) +#define GAM_ENABLE BIT(6) +#define GAM_BENABLE BIT(7) +#define GAM_GENABLE BIT(8) +#define GAM_RENABLE BIT(9) +#define VHXS_ENABLE BIT(10) +#define CSC_ENABLE BIT(11) +#define CBC_ENABLE BIT(12) +#define SUB422_ENABLE BIT(13) +#define SUB420_ENABLE BIT(14) #define GAM_ENABLES (GAM_RENABLE | GAM_GENABLE | GAM_BENABLE | GAM_ENABLE) @@ -142,7 +146,7 @@ struct isc_ctrls { u32 hist_minmax[HIST_BAYER][2]; }; -#define ISC_PIPE_LINE_NODE_NUM 11 +#define ISC_PIPE_LINE_NODE_NUM 15 /* * struct isc_reg_offsets - ISC device register offsets From 2873f85bd318bfc3f453fa78facb2b77632b36d8 Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Tue, 13 Apr 2021 12:57:17 +0200 Subject: [PATCH 295/394] media: atmel: atmel-isc: add CC initialization function The CC submodule is a part of the atmel-isc pipeline, and stands for Color Correction. It is used to apply gains and offsets to the chroma (U, V) components of the YUV elements. Implement the CC submodule initialization, as a product specific function, which currently configures the neutral point in color correction. [hverkuil: made isc_sama5d2_config_cc static] Signed-off-by: Eugen Hristev Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/atmel/atmel-isc-base.c | 1 + drivers/media/platform/atmel/atmel-isc.h | 3 +++ drivers/media/platform/atmel/atmel-sama5d2-isc.c | 14 ++++++++++++++ 3 files changed, 18 insertions(+) diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index a6b62e009c38..ffce8de2cf4d 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -661,6 +661,7 @@ static void isc_set_pipeline(struct isc_device *isc, u32 pipeline) isc->config_csc(isc); isc->config_cbc(isc); + isc->config_cc(isc); } static int isc_update_profile(struct isc_device *isc) diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h index f574bcc3ba67..a5f8d5001381 100644 --- a/drivers/media/platform/atmel/atmel-isc.h +++ b/drivers/media/platform/atmel/atmel-isc.h @@ -225,6 +225,8 @@ struct isc_reg_offsets { * specific CSC module * @config_cbc: pointer to a function that initializes product * specific CBC module + * @config_cc: pointer to a function that initializes product + * specific CC module * * @offsets: struct holding the product specific register offsets */ @@ -298,6 +300,7 @@ struct isc_device { struct { void (*config_csc)(struct isc_device *isc); void (*config_cbc)(struct isc_device *isc); + void (*config_cc)(struct isc_device *isc); }; struct isc_reg_offsets offsets; diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c index 72cb91b4b8ba..3d2e6e68015a 100644 --- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c +++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c @@ -83,6 +83,19 @@ static void isc_sama5d2_config_cbc(struct isc_device *isc) isc->ctrls.contrast); } +static void isc_sama5d2_config_cc(struct isc_device *isc) +{ + struct regmap *regmap = isc->regmap; + + /* Configure each register at the neutral fixed point 1.0 or 0.0 */ + regmap_write(regmap, ISC_CC_RR_RG, (1 << 8)); + regmap_write(regmap, ISC_CC_RB_OR, 0); + regmap_write(regmap, ISC_CC_GR_GG, (1 << 8) << 16); + regmap_write(regmap, ISC_CC_GB_OG, 0); + regmap_write(regmap, ISC_CC_BR_BG, 0); + regmap_write(regmap, ISC_CC_BB_OB, (1 << 8)); +} + /* Gamma table with gamma 1/2.2 */ static const u32 isc_sama5d2_gamma_table[][GAMMA_ENTRIES] = { /* 0 --> gamma 1/1.8 */ @@ -230,6 +243,7 @@ static int atmel_isc_probe(struct platform_device *pdev) isc->config_csc = isc_sama5d2_config_csc; isc->config_cbc = isc_sama5d2_config_cbc; + isc->config_cc = isc_sama5d2_config_cc; isc->offsets.csc = ISC_SAMA5D2_CSC_OFFSET; isc->offsets.cbc = ISC_SAMA5D2_CBC_OFFSET; From 8f1b451c87ee054f3f5238ac00593e7adaf96152 Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Tue, 13 Apr 2021 12:57:18 +0200 Subject: [PATCH 296/394] media: atmel: atmel-isc: create product specific v4l2 controls config Create product specific callback for initializing v4l2 controls. Call this from v4l2 controls init function. [hverkuil: made isc_sama5d2_config_ctrls static] Signed-off-by: Eugen Hristev Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/atmel/atmel-isc-base.c | 5 +++-- drivers/media/platform/atmel/atmel-isc.h | 5 +++++ drivers/media/platform/atmel/atmel-sama5d2-isc.c | 12 ++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index ffce8de2cf4d..8ed8b8a4840c 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -2051,11 +2051,12 @@ static int isc_ctrl_init(struct isc_device *isc) if (ret < 0) return ret; + /* Initialize product specific controls. For example, contrast */ + isc->config_ctrls(isc, ops); + ctrls->brightness = 0; - ctrls->contrast = 256; v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BRIGHTNESS, -1024, 1023, 1, 0); - v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST, -2048, 2047, 1, 256); v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAMMA, 0, isc->gamma_max, 1, isc->gamma_max); isc->awb_ctrl = v4l2_ctrl_new_std(hdl, &isc_awb_ops, diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h index a5f8d5001381..eb549fadb1a8 100644 --- a/drivers/media/platform/atmel/atmel-isc.h +++ b/drivers/media/platform/atmel/atmel-isc.h @@ -227,6 +227,8 @@ struct isc_reg_offsets { * specific CBC module * @config_cc: pointer to a function that initializes product * specific CC module + * @config_ctrls: pointer to a functoin that initializes product + * specific v4l2 controls. * * @offsets: struct holding the product specific register offsets */ @@ -301,6 +303,9 @@ struct isc_device { void (*config_csc)(struct isc_device *isc); void (*config_cbc)(struct isc_device *isc); void (*config_cc)(struct isc_device *isc); + + void (*config_ctrls)(struct isc_device *isc, + const struct v4l2_ctrl_ops *ops); }; struct isc_reg_offsets offsets; diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c index 3d2e6e68015a..6c8555e22bbe 100644 --- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c +++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c @@ -96,6 +96,17 @@ static void isc_sama5d2_config_cc(struct isc_device *isc) regmap_write(regmap, ISC_CC_BB_OB, (1 << 8)); } +static void isc_sama5d2_config_ctrls(struct isc_device *isc, + const struct v4l2_ctrl_ops *ops) +{ + struct isc_ctrls *ctrls = &isc->ctrls; + struct v4l2_ctrl_handler *hdl = &ctrls->handler; + + ctrls->contrast = 256; + + v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST, -2048, 2047, 1, 256); +} + /* Gamma table with gamma 1/2.2 */ static const u32 isc_sama5d2_gamma_table[][GAMMA_ENTRIES] = { /* 0 --> gamma 1/1.8 */ @@ -244,6 +255,7 @@ static int atmel_isc_probe(struct platform_device *pdev) isc->config_csc = isc_sama5d2_config_csc; isc->config_cbc = isc_sama5d2_config_cbc; isc->config_cc = isc_sama5d2_config_cc; + isc->config_ctrls = isc_sama5d2_config_ctrls; isc->offsets.csc = ISC_SAMA5D2_CSC_OFFSET; isc->offsets.cbc = ISC_SAMA5D2_CBC_OFFSET; From 883285556388affe1273a50d1af8772c30aa6d89 Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Tue, 13 Apr 2021 12:57:19 +0200 Subject: [PATCH 297/394] media: atmel: atmel-isc: create callback for DPC submodule product specific The DPC submodule is a part of the atmel-isc pipeline, and stands for Defective Pixel Correction. Its purpose is to detect defective pixels and correct them if possible with the help of adjacent pixels. Create a product specific callback for initializing the DPC submodule of the pipeline. For sama5d2 product, this module does not exist, thus this function is a noop. [hverkuil: made isc_sama5d2_config_dpc static] Signed-off-by: Eugen Hristev Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/atmel/atmel-isc-base.c | 1 + drivers/media/platform/atmel/atmel-isc.h | 3 +++ drivers/media/platform/atmel/atmel-sama5d2-isc.c | 6 ++++++ 3 files changed, 10 insertions(+) diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index 8ed8b8a4840c..777a5dc19d6e 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -659,6 +659,7 @@ static void isc_set_pipeline(struct isc_device *isc, u32 pipeline) regmap_bulk_write(regmap, ISC_GAM_GENTRY, gamma, GAMMA_ENTRIES); regmap_bulk_write(regmap, ISC_GAM_RENTRY, gamma, GAMMA_ENTRIES); + isc->config_dpc(isc); isc->config_csc(isc); isc->config_cbc(isc); isc->config_cc(isc); diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h index eb549fadb1a8..d6cd85a4c3e9 100644 --- a/drivers/media/platform/atmel/atmel-isc.h +++ b/drivers/media/platform/atmel/atmel-isc.h @@ -221,6 +221,8 @@ struct isc_reg_offsets { * @max_width: maximum frame width, dependent on the internal RAM * @max_height: maximum frame height, dependent on the internal RAM * + * @config_dpc: pointer to a function that initializes product + * specific DPC module * @config_csc: pointer to a function that initializes product * specific CSC module * @config_cbc: pointer to a function that initializes product @@ -300,6 +302,7 @@ struct isc_device { u32 max_height; struct { + void (*config_dpc)(struct isc_device *isc); void (*config_csc)(struct isc_device *isc); void (*config_cbc)(struct isc_device *isc); void (*config_cc)(struct isc_device *isc); diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c index 6c8555e22bbe..b6b7dbdbfd1d 100644 --- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c +++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c @@ -107,6 +107,11 @@ static void isc_sama5d2_config_ctrls(struct isc_device *isc, v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST, -2048, 2047, 1, 256); } +static void isc_sama5d2_config_dpc(struct isc_device *isc) +{ + /* This module is not present on sama5d2 pipeline */ +} + /* Gamma table with gamma 1/2.2 */ static const u32 isc_sama5d2_gamma_table[][GAMMA_ENTRIES] = { /* 0 --> gamma 1/1.8 */ @@ -252,6 +257,7 @@ static int atmel_isc_probe(struct platform_device *pdev) isc->max_width = ISC_SAMA5D2_MAX_SUPPORT_WIDTH; isc->max_height = ISC_SAMA5D2_MAX_SUPPORT_HEIGHT; + isc->config_dpc = isc_sama5d2_config_dpc; isc->config_csc = isc_sama5d2_config_csc; isc->config_cbc = isc_sama5d2_config_cbc; isc->config_cc = isc_sama5d2_config_cc; From e48848a6af150ed09d9761167aad2a7cd023470b Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Tue, 13 Apr 2021 12:57:20 +0200 Subject: [PATCH 298/394] media: atmel: atmel-isc: create callback for GAM submodule product specific The GAM submodule is a part of the atmel-isc pipeline, and stands for Gamma Correction. It is used to apply the gamma curve to the incoming pixels. Create a product specific callback for initializing the GAM submodule of the pipeline. For sama5d2 product, there is no special configuration at this moment, thus this function is a noop. [hverkuil: made isc_sama5d2_config_gam static] Signed-off-by: Eugen Hristev Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/atmel/atmel-isc-base.c | 1 + drivers/media/platform/atmel/atmel-isc.h | 3 +++ drivers/media/platform/atmel/atmel-sama5d2-isc.c | 6 ++++++ 3 files changed, 10 insertions(+) diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index 777a5dc19d6e..aef0d6570d39 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -663,6 +663,7 @@ static void isc_set_pipeline(struct isc_device *isc, u32 pipeline) isc->config_csc(isc); isc->config_cbc(isc); isc->config_cc(isc); + isc->config_gam(isc); } static int isc_update_profile(struct isc_device *isc) diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h index d6cd85a4c3e9..1e6988f1876e 100644 --- a/drivers/media/platform/atmel/atmel-isc.h +++ b/drivers/media/platform/atmel/atmel-isc.h @@ -229,6 +229,8 @@ struct isc_reg_offsets { * specific CBC module * @config_cc: pointer to a function that initializes product * specific CC module + * @config_gam: pointer to a function that initializes product + * specific GAMMA module * @config_ctrls: pointer to a functoin that initializes product * specific v4l2 controls. * @@ -306,6 +308,7 @@ struct isc_device { void (*config_csc)(struct isc_device *isc); void (*config_cbc)(struct isc_device *isc); void (*config_cc)(struct isc_device *isc); + void (*config_gam)(struct isc_device *isc); void (*config_ctrls)(struct isc_device *isc, const struct v4l2_ctrl_ops *ops); diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c index b6b7dbdbfd1d..6973c65822d8 100644 --- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c +++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c @@ -112,6 +112,11 @@ static void isc_sama5d2_config_dpc(struct isc_device *isc) /* This module is not present on sama5d2 pipeline */ } +static void isc_sama5d2_config_gam(struct isc_device *isc) +{ + /* No specific gamma configuration */ +} + /* Gamma table with gamma 1/2.2 */ static const u32 isc_sama5d2_gamma_table[][GAMMA_ENTRIES] = { /* 0 --> gamma 1/1.8 */ @@ -261,6 +266,7 @@ static int atmel_isc_probe(struct platform_device *pdev) isc->config_csc = isc_sama5d2_config_csc; isc->config_cbc = isc_sama5d2_config_cbc; isc->config_cc = isc_sama5d2_config_cc; + isc->config_gam = isc_sama5d2_config_gam; isc->config_ctrls = isc_sama5d2_config_ctrls; isc->offsets.csc = ISC_SAMA5D2_CSC_OFFSET; From ef9b7779688b2d4a772a5089aba2eacbe336779e Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Tue, 13 Apr 2021 12:57:21 +0200 Subject: [PATCH 299/394] media: atmel: atmel-isc: create callback for RLP submodule product specific The RLP submodule is a part of the atmel-isc pipeline, and stands for Rounding,Limiting and Packaging. It used to extract specific data from the ISC pipeline. For example if we want to output greyscale 8 bit, we would use limiting to 8 bits, and packaging to Luma component only. Create a product specific callback for initializing the RLP submodule of the pipeline [hverkuil: made isc_sama5d2_config_rlp static] Signed-off-by: Eugen Hristev Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/atmel/atmel-isc-base.c | 6 ++---- drivers/media/platform/atmel/atmel-isc.h | 3 +++ drivers/media/platform/atmel/atmel-sama5d2-isc.c | 10 ++++++++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index aef0d6570d39..67c16ca17672 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -719,11 +719,10 @@ static void isc_set_histogram(struct isc_device *isc, bool enable) static int isc_configure(struct isc_device *isc) { struct regmap *regmap = isc->regmap; - u32 pfe_cfg0, rlp_mode, dcfg, mask, pipeline; + u32 pfe_cfg0, dcfg, mask, pipeline; struct isc_subdev_entity *subdev = isc->current_subdev; pfe_cfg0 = isc->config.sd_format->pfe_cfg0_bps; - rlp_mode = isc->config.rlp_cfg_mode; pipeline = isc->config.bits_pipeline; dcfg = isc->config.dcfg_imode | isc->dcfg; @@ -736,8 +735,7 @@ static int isc_configure(struct isc_device *isc) regmap_update_bits(regmap, ISC_PFE_CFG0, mask, pfe_cfg0); - regmap_update_bits(regmap, ISC_RLP_CFG + isc->offsets.rlp, - ISC_RLP_CFG_MODE_MASK, rlp_mode); + isc->config_rlp(isc); regmap_write(regmap, ISC_DCFG + isc->offsets.dma, dcfg); diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h index 1e6988f1876e..abeef7b2ab27 100644 --- a/drivers/media/platform/atmel/atmel-isc.h +++ b/drivers/media/platform/atmel/atmel-isc.h @@ -231,6 +231,8 @@ struct isc_reg_offsets { * specific CC module * @config_gam: pointer to a function that initializes product * specific GAMMA module + * @config_rlp: pointer to a function that initializes product + * specific RLP module * @config_ctrls: pointer to a functoin that initializes product * specific v4l2 controls. * @@ -309,6 +311,7 @@ struct isc_device { void (*config_cbc)(struct isc_device *isc); void (*config_cc)(struct isc_device *isc); void (*config_gam)(struct isc_device *isc); + void (*config_rlp)(struct isc_device *isc); void (*config_ctrls)(struct isc_device *isc, const struct v4l2_ctrl_ops *ops); diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c index 6973c65822d8..292532da26da 100644 --- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c +++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c @@ -117,6 +117,15 @@ static void isc_sama5d2_config_gam(struct isc_device *isc) /* No specific gamma configuration */ } +static void isc_sama5d2_config_rlp(struct isc_device *isc) +{ + struct regmap *regmap = isc->regmap; + u32 rlp_mode = isc->config.rlp_cfg_mode; + + regmap_update_bits(regmap, ISC_RLP_CFG + isc->offsets.rlp, + ISC_RLP_CFG_MODE_MASK, rlp_mode); +} + /* Gamma table with gamma 1/2.2 */ static const u32 isc_sama5d2_gamma_table[][GAMMA_ENTRIES] = { /* 0 --> gamma 1/1.8 */ @@ -267,6 +276,7 @@ static int atmel_isc_probe(struct platform_device *pdev) isc->config_cbc = isc_sama5d2_config_cbc; isc->config_cc = isc_sama5d2_config_cc; isc->config_gam = isc_sama5d2_config_gam; + isc->config_rlp = isc_sama5d2_config_rlp; isc->config_ctrls = isc_sama5d2_config_ctrls; isc->offsets.csc = ISC_SAMA5D2_CSC_OFFSET; From 415dbe4efafa29896a9567c3054dd25a749b8857 Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Tue, 13 Apr 2021 12:57:22 +0200 Subject: [PATCH 300/394] media: atmel: atmel-isc: move the formats list into product specific code The list of input and output formats has to be product specific. Move this list into the product specific code. Have pointers to these arrays inside the device struct. Signed-off-by: Eugen Hristev Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/atmel/atmel-isc-base.c | 167 ++---------------- drivers/media/platform/atmel/atmel-isc.h | 12 +- .../media/platform/atmel/atmel-sama5d2-isc.c | 136 ++++++++++++++ 3 files changed, 165 insertions(+), 150 deletions(-) diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index 67c16ca17672..90a62d43fdb1 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -45,137 +45,6 @@ module_param(sensor_preferred, uint, 0644); MODULE_PARM_DESC(sensor_preferred, "Sensor is preferred to output the specified format (1-on 0-off), default 1"); -/* This is a list of the formats that the ISC can *output* */ -const struct isc_format controller_formats[] = { - { - .fourcc = V4L2_PIX_FMT_ARGB444, - }, - { - .fourcc = V4L2_PIX_FMT_ARGB555, - }, - { - .fourcc = V4L2_PIX_FMT_RGB565, - }, - { - .fourcc = V4L2_PIX_FMT_ABGR32, - }, - { - .fourcc = V4L2_PIX_FMT_XBGR32, - }, - { - .fourcc = V4L2_PIX_FMT_YUV420, - }, - { - .fourcc = V4L2_PIX_FMT_YUYV, - }, - { - .fourcc = V4L2_PIX_FMT_YUV422P, - }, - { - .fourcc = V4L2_PIX_FMT_GREY, - }, - { - .fourcc = V4L2_PIX_FMT_Y10, - }, -}; - -/* This is a list of formats that the ISC can receive as *input* */ -struct isc_format formats_list[] = { - { - .fourcc = V4L2_PIX_FMT_SBGGR8, - .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8, - .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, - .cfa_baycfg = ISC_BAY_CFG_BGBG, - }, - { - .fourcc = V4L2_PIX_FMT_SGBRG8, - .mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8, - .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, - .cfa_baycfg = ISC_BAY_CFG_GBGB, - }, - { - .fourcc = V4L2_PIX_FMT_SGRBG8, - .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8, - .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, - .cfa_baycfg = ISC_BAY_CFG_GRGR, - }, - { - .fourcc = V4L2_PIX_FMT_SRGGB8, - .mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8, - .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, - .cfa_baycfg = ISC_BAY_CFG_RGRG, - }, - { - .fourcc = V4L2_PIX_FMT_SBGGR10, - .mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10, - .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, - .cfa_baycfg = ISC_BAY_CFG_RGRG, - }, - { - .fourcc = V4L2_PIX_FMT_SGBRG10, - .mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10, - .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, - .cfa_baycfg = ISC_BAY_CFG_GBGB, - }, - { - .fourcc = V4L2_PIX_FMT_SGRBG10, - .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10, - .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, - .cfa_baycfg = ISC_BAY_CFG_GRGR, - }, - { - .fourcc = V4L2_PIX_FMT_SRGGB10, - .mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10, - .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, - .cfa_baycfg = ISC_BAY_CFG_RGRG, - }, - { - .fourcc = V4L2_PIX_FMT_SBGGR12, - .mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12, - .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, - .cfa_baycfg = ISC_BAY_CFG_BGBG, - }, - { - .fourcc = V4L2_PIX_FMT_SGBRG12, - .mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12, - .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, - .cfa_baycfg = ISC_BAY_CFG_GBGB, - }, - { - .fourcc = V4L2_PIX_FMT_SGRBG12, - .mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12, - .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, - .cfa_baycfg = ISC_BAY_CFG_GRGR, - }, - { - .fourcc = V4L2_PIX_FMT_SRGGB12, - .mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12, - .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, - .cfa_baycfg = ISC_BAY_CFG_RGRG, - }, - { - .fourcc = V4L2_PIX_FMT_GREY, - .mbus_code = MEDIA_BUS_FMT_Y8_1X8, - .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, - }, - { - .fourcc = V4L2_PIX_FMT_YUYV, - .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, - .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, - }, - { - .fourcc = V4L2_PIX_FMT_RGB565, - .mbus_code = MEDIA_BUS_FMT_RGB565_2X8_LE, - .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, - }, - { - .fourcc = V4L2_PIX_FMT_Y10, - .mbus_code = MEDIA_BUS_FMT_Y10_1X10, - .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, - }, - -}; - #define ISC_IS_FORMAT_RAW(mbus_code) \ (((mbus_code) & 0xf000) == 0x3000) @@ -919,24 +788,25 @@ static int isc_querycap(struct file *file, void *priv, static int isc_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) { + struct isc_device *isc = video_drvdata(file); u32 index = f->index; u32 i, supported_index; - if (index < ARRAY_SIZE(controller_formats)) { - f->pixelformat = controller_formats[index].fourcc; + if (index < isc->controller_formats_size) { + f->pixelformat = isc->controller_formats[index].fourcc; return 0; } - index -= ARRAY_SIZE(controller_formats); + index -= isc->controller_formats_size; supported_index = 0; - for (i = 0; i < ARRAY_SIZE(formats_list); i++) { - if (!ISC_IS_FORMAT_RAW(formats_list[i].mbus_code) || - !formats_list[i].sd_support) + for (i = 0; i < isc->formats_list_size; i++) { + if (!ISC_IS_FORMAT_RAW(isc->formats_list[i].mbus_code) || + !isc->formats_list[i].sd_support) continue; if (supported_index == index) { - f->pixelformat = formats_list[i].fourcc; + f->pixelformat = isc->formats_list[i].fourcc; return 0; } supported_index++; @@ -1477,8 +1347,8 @@ static int isc_enum_framesizes(struct file *file, void *fh, if (isc->user_formats[i]->fourcc == fsize->pixel_format) ret = 0; - for (i = 0; i < ARRAY_SIZE(controller_formats); i++) - if (controller_formats[i].fourcc == fsize->pixel_format) + for (i = 0; i < isc->controller_formats_size; i++) + if (isc->controller_formats[i].fourcc == fsize->pixel_format) ret = 0; if (ret) @@ -1514,8 +1384,8 @@ static int isc_enum_frameintervals(struct file *file, void *fh, if (isc->user_formats[i]->fourcc == fival->pixel_format) ret = 0; - for (i = 0; i < ARRAY_SIZE(controller_formats); i++) - if (controller_formats[i].fourcc == fival->pixel_format) + for (i = 0; i < isc->controller_formats_size; i++) + if (isc->controller_formats[i].fourcc == fival->pixel_format) ret = 0; if (ret) @@ -2126,12 +1996,13 @@ static void isc_async_unbind(struct v4l2_async_notifier *notifier, v4l2_ctrl_handler_free(&isc->ctrls.handler); } -static struct isc_format *find_format_by_code(unsigned int code, int *index) +static struct isc_format *find_format_by_code(struct isc_device *isc, + unsigned int code, int *index) { - struct isc_format *fmt = &formats_list[0]; + struct isc_format *fmt = &isc->formats_list[0]; unsigned int i; - for (i = 0; i < ARRAY_SIZE(formats_list); i++) { + for (i = 0; i < isc->formats_list_size; i++) { if (fmt->mbus_code == code) { *index = i; return fmt; @@ -2148,7 +2019,7 @@ static int isc_formats_init(struct isc_device *isc) struct isc_format *fmt; struct v4l2_subdev *subdev = isc->current_subdev->sd; unsigned int num_fmts, i, j; - u32 list_size = ARRAY_SIZE(formats_list); + u32 list_size = isc->formats_list_size; struct v4l2_subdev_mbus_code_enum mbus_code = { .which = V4L2_SUBDEV_FORMAT_ACTIVE, }; @@ -2158,7 +2029,7 @@ static int isc_formats_init(struct isc_device *isc) NULL, &mbus_code)) { mbus_code.index++; - fmt = find_format_by_code(mbus_code.code, &i); + fmt = find_format_by_code(isc, mbus_code.code, &i); if (!fmt) { v4l2_warn(&isc->v4l2_dev, "Mbus code %x not supported\n", mbus_code.code); @@ -2179,7 +2050,7 @@ static int isc_formats_init(struct isc_device *isc) if (!isc->user_formats) return -ENOMEM; - fmt = &formats_list[0]; + fmt = &isc->formats_list[0]; for (i = 0, j = 0; i < list_size; i++) { if (fmt->sd_support) isc->user_formats[j++] = fmt; diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h index abeef7b2ab27..14e318a7373c 100644 --- a/drivers/media/platform/atmel/atmel-isc.h +++ b/drivers/media/platform/atmel/atmel-isc.h @@ -237,6 +237,12 @@ struct isc_reg_offsets { * specific v4l2 controls. * * @offsets: struct holding the product specific register offsets + * @controller_formats: pointer to the array of possible formats that the + * controller can output + * @formats_list: pointer to the array of possible formats that can + * be used as an input to the controller + * @controller_formats_size: size of controller_formats array + * @formats_list_size: size of formats_list array */ struct isc_device { struct regmap *regmap; @@ -318,10 +324,12 @@ struct isc_device { }; struct isc_reg_offsets offsets; + const struct isc_format *controller_formats; + struct isc_format *formats_list; + u32 controller_formats_size; + u32 formats_list_size; }; -extern struct isc_format formats_list[]; -extern const struct isc_format controller_formats[]; extern const struct regmap_config isc_regmap_config; extern const struct v4l2_async_notifier_operations isc_async_ops; diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c index 292532da26da..95cad167a264 100644 --- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c +++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c @@ -54,6 +54,137 @@ #define ISC_CLK_MAX_DIV 255 +/* This is a list of the formats that the ISC can *output* */ +static const struct isc_format sama5d2_controller_formats[] = { + { + .fourcc = V4L2_PIX_FMT_ARGB444, + }, + { + .fourcc = V4L2_PIX_FMT_ARGB555, + }, + { + .fourcc = V4L2_PIX_FMT_RGB565, + }, + { + .fourcc = V4L2_PIX_FMT_ABGR32, + }, + { + .fourcc = V4L2_PIX_FMT_XBGR32, + }, + { + .fourcc = V4L2_PIX_FMT_YUV420, + }, + { + .fourcc = V4L2_PIX_FMT_YUYV, + }, + { + .fourcc = V4L2_PIX_FMT_YUV422P, + }, + { + .fourcc = V4L2_PIX_FMT_GREY, + }, + { + .fourcc = V4L2_PIX_FMT_Y10, + }, +}; + +/* This is a list of formats that the ISC can receive as *input* */ +static struct isc_format sama5d2_formats_list[] = { + { + .fourcc = V4L2_PIX_FMT_SBGGR8, + .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8, + .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, + .cfa_baycfg = ISC_BAY_CFG_BGBG, + }, + { + .fourcc = V4L2_PIX_FMT_SGBRG8, + .mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8, + .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, + .cfa_baycfg = ISC_BAY_CFG_GBGB, + }, + { + .fourcc = V4L2_PIX_FMT_SGRBG8, + .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8, + .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, + .cfa_baycfg = ISC_BAY_CFG_GRGR, + }, + { + .fourcc = V4L2_PIX_FMT_SRGGB8, + .mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8, + .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, + .cfa_baycfg = ISC_BAY_CFG_RGRG, + }, + { + .fourcc = V4L2_PIX_FMT_SBGGR10, + .mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10, + .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, + .cfa_baycfg = ISC_BAY_CFG_RGRG, + }, + { + .fourcc = V4L2_PIX_FMT_SGBRG10, + .mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10, + .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, + .cfa_baycfg = ISC_BAY_CFG_GBGB, + }, + { + .fourcc = V4L2_PIX_FMT_SGRBG10, + .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10, + .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, + .cfa_baycfg = ISC_BAY_CFG_GRGR, + }, + { + .fourcc = V4L2_PIX_FMT_SRGGB10, + .mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10, + .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, + .cfa_baycfg = ISC_BAY_CFG_RGRG, + }, + { + .fourcc = V4L2_PIX_FMT_SBGGR12, + .mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12, + .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, + .cfa_baycfg = ISC_BAY_CFG_BGBG, + }, + { + .fourcc = V4L2_PIX_FMT_SGBRG12, + .mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12, + .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, + .cfa_baycfg = ISC_BAY_CFG_GBGB, + }, + { + .fourcc = V4L2_PIX_FMT_SGRBG12, + .mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12, + .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, + .cfa_baycfg = ISC_BAY_CFG_GRGR, + }, + { + .fourcc = V4L2_PIX_FMT_SRGGB12, + .mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12, + .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, + .cfa_baycfg = ISC_BAY_CFG_RGRG, + }, + { + .fourcc = V4L2_PIX_FMT_GREY, + .mbus_code = MEDIA_BUS_FMT_Y8_1X8, + .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, + }, + { + .fourcc = V4L2_PIX_FMT_YUYV, + .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, + .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, + }, + { + .fourcc = V4L2_PIX_FMT_RGB565, + .mbus_code = MEDIA_BUS_FMT_RGB565_2X8_LE, + .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, + }, + { + .fourcc = V4L2_PIX_FMT_Y10, + .mbus_code = MEDIA_BUS_FMT_Y10_1X10, + .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, + }, + +}; + static void isc_sama5d2_config_csc(struct isc_device *isc) { struct regmap *regmap = isc->regmap; @@ -289,6 +420,11 @@ static int atmel_isc_probe(struct platform_device *pdev) isc->offsets.version = ISC_SAMA5D2_VERSION_OFFSET; isc->offsets.his_entry = ISC_SAMA5D2_HIS_ENTRY_OFFSET; + isc->controller_formats = sama5d2_controller_formats; + isc->controller_formats_size = ARRAY_SIZE(sama5d2_controller_formats); + isc->formats_list = sama5d2_formats_list; + isc->formats_list_size = ARRAY_SIZE(sama5d2_formats_list); + /* sama5d2-isc - 8 bits per beat */ isc->dcfg = ISC_DCFG_YMBSIZE_BEATS8 | ISC_DCFG_CMBSIZE_BEATS8; From 049a38fc9681b3c6103496104b22d49b60660a64 Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Tue, 13 Apr 2021 12:57:23 +0200 Subject: [PATCH 301/394] media: atmel: atmel-isc: create an adapt pipeline callback for product specific Once the pipeline is set in the base code, create a callback that will adapt the ISC pipeline to each product. Create the adapt_pipeline callback that will be used in this fashion. [hverkuil: made isc_sama5d2_adapt_pipeline static] Signed-off-by: Eugen Hristev Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/atmel/atmel-isc-base.c | 4 ++++ drivers/media/platform/atmel/atmel-isc.h | 5 +++++ drivers/media/platform/atmel/atmel-sama5d2-isc.c | 11 +++++++++++ 3 files changed, 20 insertions(+) diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index 90a62d43fdb1..7862d6bf850d 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -1059,6 +1059,10 @@ static int isc_try_configure_pipeline(struct isc_device *isc) default: isc->try_config.bits_pipeline = 0x0; } + + /* Tune the pipeline to product specific */ + isc->adapt_pipeline(isc); + return 0; } diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h index 14e318a7373c..19cc60dfcbe0 100644 --- a/drivers/media/platform/atmel/atmel-isc.h +++ b/drivers/media/platform/atmel/atmel-isc.h @@ -236,6 +236,9 @@ struct isc_reg_offsets { * @config_ctrls: pointer to a functoin that initializes product * specific v4l2 controls. * + * @adapt_pipeline: pointer to a function that adapts the pipeline bits + * to the product specific pipeline + * * @offsets: struct holding the product specific register offsets * @controller_formats: pointer to the array of possible formats that the * controller can output @@ -321,6 +324,8 @@ struct isc_device { void (*config_ctrls)(struct isc_device *isc, const struct v4l2_ctrl_ops *ops); + + void (*adapt_pipeline)(struct isc_device *isc); }; struct isc_reg_offsets offsets; diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c index 95cad167a264..8579f27800ae 100644 --- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c +++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c @@ -54,6 +54,10 @@ #define ISC_CLK_MAX_DIV 255 +#define ISC_SAMA5D2_PIPELINE \ + (WB_ENABLE | CFA_ENABLE | CC_ENABLE | GAM_ENABLES | CSC_ENABLE | \ + CBC_ENABLE | SUB422_ENABLE | SUB420_ENABLE) + /* This is a list of the formats that the ISC can *output* */ static const struct isc_format sama5d2_controller_formats[] = { { @@ -257,6 +261,11 @@ static void isc_sama5d2_config_rlp(struct isc_device *isc) ISC_RLP_CFG_MODE_MASK, rlp_mode); } +static void isc_sama5d2_adapt_pipeline(struct isc_device *isc) +{ + isc->try_config.bits_pipeline &= ISC_SAMA5D2_PIPELINE; +} + /* Gamma table with gamma 1/2.2 */ static const u32 isc_sama5d2_gamma_table[][GAMMA_ENTRIES] = { /* 0 --> gamma 1/1.8 */ @@ -410,6 +419,8 @@ static int atmel_isc_probe(struct platform_device *pdev) isc->config_rlp = isc_sama5d2_config_rlp; isc->config_ctrls = isc_sama5d2_config_ctrls; + isc->adapt_pipeline = isc_sama5d2_adapt_pipeline; + isc->offsets.csc = ISC_SAMA5D2_CSC_OFFSET; isc->offsets.cbc = ISC_SAMA5D2_CBC_OFFSET; isc->offsets.sub422 = ISC_SAMA5D2_SUB422_OFFSET; From 0baf7a3241ac5d41de833f3b3df0961f40802b44 Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Tue, 13 Apr 2021 12:57:24 +0200 Subject: [PATCH 302/394] media: atmel: atmel-isc-regs: add additional fields for sama7g5 type pipeline Add additional fields for registers present in sama7g5 type pipeline. Extend register masks for additional bits in sama7g5 type pipeline registers. Signed-off-by: Eugen Hristev Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/atmel/atmel-isc-regs.h | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/atmel/atmel-isc-regs.h b/drivers/media/platform/atmel/atmel-isc-regs.h index 457eed74cda9..5f99bf7717c1 100644 --- a/drivers/media/platform/atmel/atmel-isc-regs.h +++ b/drivers/media/platform/atmel/atmel-isc-regs.h @@ -289,8 +289,18 @@ #define ISC_RLP_CFG_MODE_ARGB32 0xa #define ISC_RLP_CFG_MODE_YYCC 0xb #define ISC_RLP_CFG_MODE_YYCC_LIMITED 0xc +#define ISC_RLP_CFG_MODE_YCYC 0xd #define ISC_RLP_CFG_MODE_MASK GENMASK(3, 0) +#define ISC_RLP_CFG_LSH BIT(5) + +#define ISC_RLP_CFG_YMODE_YUYV (3 << 6) +#define ISC_RLP_CFG_YMODE_YVYU (2 << 6) +#define ISC_RLP_CFG_YMODE_VYUY (0 << 6) +#define ISC_RLP_CFG_YMODE_UYVY (1 << 6) + +#define ISC_RLP_CFG_YMODE_MASK GENMASK(7, 6) + /* Offset for HIS register specific to sama5d2 product */ #define ISC_SAMA5D2_HIS_OFFSET 0 /* Histogram Control Register */ @@ -332,13 +342,15 @@ #define ISC_DCFG_YMBSIZE_BEATS4 (0x1 << 4) #define ISC_DCFG_YMBSIZE_BEATS8 (0x2 << 4) #define ISC_DCFG_YMBSIZE_BEATS16 (0x3 << 4) -#define ISC_DCFG_YMBSIZE_MASK GENMASK(5, 4) +#define ISC_DCFG_YMBSIZE_BEATS32 (0x4 << 4) +#define ISC_DCFG_YMBSIZE_MASK GENMASK(6, 4) #define ISC_DCFG_CMBSIZE_SINGLE (0x0 << 8) #define ISC_DCFG_CMBSIZE_BEATS4 (0x1 << 8) #define ISC_DCFG_CMBSIZE_BEATS8 (0x2 << 8) #define ISC_DCFG_CMBSIZE_BEATS16 (0x3 << 8) -#define ISC_DCFG_CMBSIZE_MASK GENMASK(9, 8) +#define ISC_DCFG_CMBSIZE_BEATS32 (0x4 << 8) +#define ISC_DCFG_CMBSIZE_MASK GENMASK(10, 8) /* DMA Control Register */ #define ISC_DCTRL 0x000003e4 From debfa496871c181b658def0f2b200302bd9b1216 Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Tue, 13 Apr 2021 12:57:25 +0200 Subject: [PATCH 303/394] media: atmel: atmel-isc-base: add support for more formats and additional pipeline modules Add support for additional formats supported by newer pipelines, and for additional pipeline modules. Signed-off-by: Eugen Hristev Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/atmel/atmel-isc-base.c | 48 +++++++++++++++---- 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index 7862d6bf850d..dcb321ad10b8 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -855,6 +855,8 @@ static int isc_try_validate_formats(struct isc_device *isc) case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_YUV422P: case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_VYUY: ret = 0; yuv = true; break; @@ -869,6 +871,7 @@ static int isc_try_validate_formats(struct isc_device *isc) break; case V4L2_PIX_FMT_GREY: case V4L2_PIX_FMT_Y10: + case V4L2_PIX_FMT_Y16: ret = 0; grey = true; break; @@ -899,6 +902,8 @@ static int isc_try_validate_formats(struct isc_device *isc) */ static int isc_try_configure_rlp_dma(struct isc_device *isc, bool direct_dump) { + isc->try_config.rlp_cfg_mode = 0; + switch (isc->try_config.fourcc) { case V4L2_PIX_FMT_SBGGR8: case V4L2_PIX_FMT_SGBRG8: @@ -965,7 +970,19 @@ static int isc_try_configure_rlp_dma(struct isc_device *isc, bool direct_dump) isc->try_config.bpp = 16; break; case V4L2_PIX_FMT_YUYV: - isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YYCC; + isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YCYC | ISC_RLP_CFG_YMODE_YUYV; + isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED32; + isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; + isc->try_config.bpp = 16; + break; + case V4L2_PIX_FMT_UYVY: + isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YCYC | ISC_RLP_CFG_YMODE_UYVY; + isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED32; + isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; + isc->try_config.bpp = 16; + break; + case V4L2_PIX_FMT_VYUY: + isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YCYC | ISC_RLP_CFG_YMODE_VYUY; isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED32; isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; isc->try_config.bpp = 16; @@ -976,8 +993,11 @@ static int isc_try_configure_rlp_dma(struct isc_device *isc, bool direct_dump) isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; isc->try_config.bpp = 8; break; + case V4L2_PIX_FMT_Y16: + isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DATY10 | ISC_RLP_CFG_LSH; + fallthrough; case V4L2_PIX_FMT_Y10: - isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DATY10; + isc->try_config.rlp_cfg_mode |= ISC_RLP_CFG_MODE_DATY10; isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16; isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; isc->try_config.bpp = 16; @@ -1011,7 +1031,8 @@ static int isc_try_configure_pipeline(struct isc_device *isc) /* if sensor format is RAW, we convert inside ISC */ if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) { isc->try_config.bits_pipeline = CFA_ENABLE | - WB_ENABLE | GAM_ENABLES; + WB_ENABLE | GAM_ENABLES | DPC_BLCENABLE | + CC_ENABLE; } else { isc->try_config.bits_pipeline = 0x0; } @@ -1020,8 +1041,9 @@ static int isc_try_configure_pipeline(struct isc_device *isc) /* if sensor format is RAW, we convert inside ISC */ if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) { isc->try_config.bits_pipeline = CFA_ENABLE | - CSC_ENABLE | WB_ENABLE | GAM_ENABLES | - SUB420_ENABLE | SUB422_ENABLE | CBC_ENABLE; + CSC_ENABLE | GAM_ENABLES | WB_ENABLE | + SUB420_ENABLE | SUB422_ENABLE | CBC_ENABLE | + DPC_BLCENABLE; } else { isc->try_config.bits_pipeline = 0x0; } @@ -1031,33 +1053,39 @@ static int isc_try_configure_pipeline(struct isc_device *isc) if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) { isc->try_config.bits_pipeline = CFA_ENABLE | CSC_ENABLE | WB_ENABLE | GAM_ENABLES | - SUB422_ENABLE | CBC_ENABLE; + SUB422_ENABLE | CBC_ENABLE | DPC_BLCENABLE; } else { isc->try_config.bits_pipeline = 0x0; } break; case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_VYUY: /* if sensor format is RAW, we convert inside ISC */ if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) { isc->try_config.bits_pipeline = CFA_ENABLE | CSC_ENABLE | WB_ENABLE | GAM_ENABLES | - SUB422_ENABLE | CBC_ENABLE; + SUB422_ENABLE | CBC_ENABLE | DPC_BLCENABLE; } else { isc->try_config.bits_pipeline = 0x0; } break; case V4L2_PIX_FMT_GREY: - if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) { + case V4L2_PIX_FMT_Y16: /* if sensor format is RAW, we convert inside ISC */ + if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) { isc->try_config.bits_pipeline = CFA_ENABLE | CSC_ENABLE | WB_ENABLE | GAM_ENABLES | - CBC_ENABLE; + CBC_ENABLE | DPC_BLCENABLE; } else { isc->try_config.bits_pipeline = 0x0; } break; default: - isc->try_config.bits_pipeline = 0x0; + if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) + isc->try_config.bits_pipeline = WB_ENABLE | DPC_BLCENABLE; + else + isc->try_config.bits_pipeline = 0x0; } /* Tune the pipeline to product specific */ From 2672a9397221d6ded067a205211897f3e3d712dc Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Tue, 13 Apr 2021 12:57:26 +0200 Subject: [PATCH 304/394] media: atmel: atmel-isc-sama5d2: remove duplicate define Remove a duplicate definition of clock max divider Signed-off-by: Eugen Hristev Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/atmel/atmel-sama5d2-isc.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c index 8579f27800ae..925aa80a139b 100644 --- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c +++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c @@ -52,8 +52,6 @@ #define ISC_SAMA5D2_MAX_SUPPORT_WIDTH 2592 #define ISC_SAMA5D2_MAX_SUPPORT_HEIGHT 1944 -#define ISC_CLK_MAX_DIV 255 - #define ISC_SAMA5D2_PIPELINE \ (WB_ENABLE | CFA_ENABLE | CC_ENABLE | GAM_ENABLES | CSC_ENABLE | \ CBC_ENABLE | SUB422_ENABLE | SUB420_ENABLE) From 54203301d02a3afff13a002f3c2cffb30f59a2fb Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Thu, 15 Apr 2021 10:55:30 +0200 Subject: [PATCH 305/394] media: dt-bindings: media: atmel-isc: convert to yaml Convert the Atmel ISC to yaml binding format. Signed-off-by: Eugen Hristev Reviewed-by: Rob Herring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../devicetree/bindings/media/atmel,isc.yaml | 114 ++++++++++++++++++ .../devicetree/bindings/media/atmel-isc.txt | 65 ---------- 2 files changed, 114 insertions(+), 65 deletions(-) create mode 100644 Documentation/devicetree/bindings/media/atmel,isc.yaml delete mode 100644 Documentation/devicetree/bindings/media/atmel-isc.txt diff --git a/Documentation/devicetree/bindings/media/atmel,isc.yaml b/Documentation/devicetree/bindings/media/atmel,isc.yaml new file mode 100644 index 000000000000..3e4bb8892d94 --- /dev/null +++ b/Documentation/devicetree/bindings/media/atmel,isc.yaml @@ -0,0 +1,114 @@ +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (C) 2016-2021 Microchip Technology, Inc. +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/atmel,isc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Atmel Image Sensor Controller (ISC) + +maintainers: + - Eugen Hristev + +description: | + The Image Sensor Controller (ISC) device provides the video input capabilities for the + Atmel/Microchip AT91 SAMA family of devices. + + The ISC has a single parallel input that supports RAW Bayer, RGB or YUV video, + with both external synchronization and BT.656 synchronization for the latter. + +properties: + compatible: + const: atmel,sama5d2-isc + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + minItems: 3 + maxItems: 3 + + clock-names: + items: + - const: hclock + - const: iscck + - const: gck + + '#clock-cells': + const: 0 + + clock-output-names: + const: isc-mck + + port: + $ref: /schemas/graph.yaml#/properties/port + description: + Input port node, single endpoint describing the input pad. + + properties: + endpoint: + $ref: video-interfaces.yaml# + + properties: + remote-endpoint: true + + bus-width: + enum: [8, 9, 10, 11, 12] + default: 12 + + hsync-active: + enum: [0, 1] + default: 1 + + vsync-active: + enum: [0, 1] + default: 1 + + pclk-sample: + enum: [0, 1] + default: 1 + + required: + - remote-endpoint + + additionalProperties: false + + additionalProperties: false + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + - clock-output-names + - port + +additionalProperties: false + +examples: + - | + #include + + isc: isc@f0008000 { + compatible = "atmel,sama5d2-isc"; + reg = <0xf0008000 0x4000>; + interrupts = <46 IRQ_TYPE_LEVEL_HIGH 5>; + clocks = <&isc_clk>, <&iscck>, <&isc_gclk>; + clock-names = "hclock", "iscck", "gck"; + #clock-cells = <0>; + clock-output-names = "isc-mck"; + + port { + isc_0: endpoint { + remote-endpoint = <&ov7740_0>; + hsync-active = <1>; + vsync-active = <0>; + pclk-sample = <1>; + bus-width = <8>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/media/atmel-isc.txt b/Documentation/devicetree/bindings/media/atmel-isc.txt deleted file mode 100644 index bbe0e87c6188..000000000000 --- a/Documentation/devicetree/bindings/media/atmel-isc.txt +++ /dev/null @@ -1,65 +0,0 @@ -Atmel Image Sensor Controller (ISC) ----------------------------------------------- - -Required properties for ISC: -- compatible - Must be "atmel,sama5d2-isc". -- reg - Physical base address and length of the registers set for the device. -- interrupts - Should contain IRQ line for the ISC. -- clocks - List of clock specifiers, corresponding to entries in - the clock-names property; - Please refer to clock-bindings.txt. -- clock-names - Required elements: "hclock", "iscck", "gck". -- #clock-cells - Should be 0. -- clock-output-names - Should be "isc-mck". -- pinctrl-names, pinctrl-0 - Please refer to pinctrl-bindings.txt. - -ISC supports a single port node with parallel bus. It should contain one -'port' child node with child 'endpoint' node. Please refer to the bindings -defined in Documentation/devicetree/bindings/media/video-interfaces.txt. - -Example: -isc: isc@f0008000 { - compatible = "atmel,sama5d2-isc"; - reg = <0xf0008000 0x4000>; - interrupts = <46 IRQ_TYPE_LEVEL_HIGH 5>; - clocks = <&isc_clk>, <&iscck>, <&isc_gclk>; - clock-names = "hclock", "iscck", "gck"; - #clock-cells = <0>; - clock-output-names = "isc-mck"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_isc_base &pinctrl_isc_data_8bit &pinctrl_isc_data_9_10 &pinctrl_isc_data_11_12>; - - port { - isc_0: endpoint { - remote-endpoint = <&ov7740_0>; - hsync-active = <1>; - vsync-active = <0>; - pclk-sample = <1>; - }; - }; -}; - -i2c1: i2c@fc028000 { - ov7740: camera@21 { - compatible = "ovti,ov7740"; - reg = <0x21>; - clocks = <&isc>; - clock-names = "xvclk"; - assigned-clocks = <&isc>; - assigned-clock-rates = <24000000>; - - port { - ov7740_0: endpoint { - remote-endpoint = <&isc_0>; - }; - }; - }; -}; From 7b8d3d03df83aae74519b34022e95dec577af1df Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Thu, 15 Apr 2021 20:45:00 +0200 Subject: [PATCH 306/394] media: dt-bindings: media: add microchip,xisc device bindings Add bindings for the Microchip eXtended Image Sensor Controller. Based on the atmel,isc.yaml binding. Signed-off-by: Eugen Hristev Reviewed-by: Rob Herring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../bindings/media/microchip,xisc.yaml | 129 ++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/microchip,xisc.yaml diff --git a/Documentation/devicetree/bindings/media/microchip,xisc.yaml b/Documentation/devicetree/bindings/media/microchip,xisc.yaml new file mode 100644 index 000000000000..41afe2e5f133 --- /dev/null +++ b/Documentation/devicetree/bindings/media/microchip,xisc.yaml @@ -0,0 +1,129 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (C) 2021 Microchip Technology, Inc. +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/microchip,xisc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Microchip eXtended Image Sensor Controller (XISC) + +maintainers: + - Eugen Hristev + +description: | + The eXtended Image Sensor Controller (XISC) device provides the video input capabilities for the + Microchip AT91 SAM family of devices. + + The XISC has a single internal parallel input that supports RAW Bayer, RGB or YUV video. + The source can be either a demuxer from a CSI2 type of bus, or a simple direct bridge to a + parallel sensor. + + The XISC provides one clock output that is used to clock the demuxer/bridge. + +properties: + compatible: + const: microchip,sama7g5-isc + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-names: + items: + - const: hclock + + '#clock-cells': + const: 0 + + clock-output-names: + const: isc-mck + + microchip,mipi-mode: + type: boolean + description: + As the XISC is usually connected to a demux/bridge, the XISC receives + the same type of input, however, it should be aware of the type of + signals received. The mipi-mode enables different internal handling + of the data and clock lines. + + port: + $ref: /schemas/graph.yaml#/properties/port + description: + Input port node, single endpoint describing the input pad. + + properties: + endpoint: + $ref: video-interfaces.yaml# + + properties: + bus-type: + enum: [5, 6] + + remote-endpoint: true + + bus-width: + enum: [8, 9, 10, 11, 12] + default: 12 + + hsync-active: + enum: [0, 1] + default: 1 + + vsync-active: + enum: [0, 1] + default: 1 + + pclk-sample: + enum: [0, 1] + default: 1 + + required: + - remote-endpoint + - bus-type + + additionalProperties: false + + additionalProperties: false + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + - clock-output-names + - port + +additionalProperties: false + +examples: + - | + #include + #include + #include + + xisc: xisc@e1408000 { + compatible = "microchip,sama7g5-isc"; + reg = <0xe1408000 0x2000>; + interrupts = ; + clocks = <&pmc PMC_TYPE_PERIPHERAL 56>; + clock-names = "hclock"; + #clock-cells = <0>; + clock-output-names = "isc-mck"; + + port { + xisc_in: endpoint { + bus-type = <5>; /* Parallel */ + remote-endpoint = <&csi2dc_out>; + hsync-active = <1>; + vsync-active = <1>; + bus-width = <12>; + }; + }; + }; + From c9aa973884a163ecb6d5d4d3be9137058adcaf8c Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Tue, 13 Apr 2021 12:57:29 +0200 Subject: [PATCH 307/394] media: atmel: atmel-isc: add microchip-xisc driver Add driver for the extended variant of the isc, the microchip XISC present on sama7g5 product. [hverkuil: drop MODULE_SUPPORTED_DEVICE, no longer exists] [hverkuil: made isc_sama7g5_config_csc et al static] [hverkuil: made sama7g5_controller_formats et al static] Signed-off-by: Eugen Hristev Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/Makefile | 1 + drivers/media/platform/atmel/Kconfig | 11 + drivers/media/platform/atmel/Makefile | 2 + drivers/media/platform/atmel/atmel-isc-base.c | 2 +- drivers/media/platform/atmel/atmel-isc-regs.h | 26 + .../media/platform/atmel/atmel-sama7g5-isc.c | 630 ++++++++++++++++++ 6 files changed, 671 insertions(+), 1 deletion(-) create mode 100644 drivers/media/platform/atmel/atmel-sama7g5-isc.c diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile index eedc14aafb32..73ce083c2fc6 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile @@ -67,6 +67,7 @@ obj-$(CONFIG_VIDEO_RCAR_VIN) += rcar-vin/ obj-$(CONFIG_VIDEO_ATMEL_ISC) += atmel/ obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel/ +obj-$(CONFIG_VIDEO_ATMEL_XISC) += atmel/ obj-$(CONFIG_VIDEO_STM32_DCMI) += stm32/ diff --git a/drivers/media/platform/atmel/Kconfig b/drivers/media/platform/atmel/Kconfig index 1850fe7f9360..99b51213f871 100644 --- a/drivers/media/platform/atmel/Kconfig +++ b/drivers/media/platform/atmel/Kconfig @@ -12,6 +12,17 @@ config VIDEO_ATMEL_ISC This module makes the ATMEL Image Sensor Controller available as a v4l2 device. +config VIDEO_ATMEL_XISC + tristate "ATMEL eXtended Image Sensor Controller (XISC) support" + depends on VIDEO_V4L2 && COMMON_CLK && VIDEO_V4L2_SUBDEV_API + depends on ARCH_AT91 || COMPILE_TEST + select VIDEOBUF2_DMA_CONTIG + select REGMAP_MMIO + select V4L2_FWNODE + help + This module makes the ATMEL eXtended Image Sensor Controller + available as a v4l2 device. + config VIDEO_ATMEL_ISI tristate "ATMEL Image Sensor Interface (ISI) support" depends on VIDEO_V4L2 && OF diff --git a/drivers/media/platform/atmel/Makefile b/drivers/media/platform/atmel/Makefile index 2dba38994a70..c5c01556c653 100644 --- a/drivers/media/platform/atmel/Makefile +++ b/drivers/media/platform/atmel/Makefile @@ -1,5 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only atmel-isc-objs = atmel-sama5d2-isc.o atmel-isc-base.o +atmel-xisc-objs = atmel-sama7g5-isc.o atmel-isc-base.o obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel-isi.o obj-$(CONFIG_VIDEO_ATMEL_ISC) += atmel-isc.o +obj-$(CONFIG_VIDEO_ATMEL_XISC) += atmel-xisc.o diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index dcb321ad10b8..46c6e3e20f33 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -600,7 +600,7 @@ static int isc_configure(struct isc_device *isc) mask = ISC_PFE_CFG0_BPS_MASK | ISC_PFE_CFG0_HPOL_LOW | ISC_PFE_CFG0_VPOL_LOW | ISC_PFE_CFG0_PPOL_LOW | ISC_PFE_CFG0_MODE_MASK | ISC_PFE_CFG0_CCIR_CRC | - ISC_PFE_CFG0_CCIR656; + ISC_PFE_CFG0_CCIR656 | ISC_PFE_CFG0_MIPI; regmap_update_bits(regmap, ISC_PFE_CFG0, mask, pfe_cfg0); diff --git a/drivers/media/platform/atmel/atmel-isc-regs.h b/drivers/media/platform/atmel/atmel-isc-regs.h index 5f99bf7717c1..d06b72228d4f 100644 --- a/drivers/media/platform/atmel/atmel-isc-regs.h +++ b/drivers/media/platform/atmel/atmel-isc-regs.h @@ -26,6 +26,7 @@ #define ISC_PFE_CFG0_PPOL_LOW BIT(2) #define ISC_PFE_CFG0_CCIR656 BIT(9) #define ISC_PFE_CFG0_CCIR_CRC BIT(10) +#define ISC_PFE_CFG0_MIPI BIT(14) #define ISC_PFE_CFG0_MODE_PROGRESSIVE (0x0 << 4) #define ISC_PFE_CFG0_MODE_MASK GENMASK(6, 4) @@ -184,6 +185,8 @@ /* ISC Gamma Correction Control Register */ #define ISC_GAM_CTRL 0x00000094 +#define ISC_GAM_CTRL_BIPART BIT(4) + /* ISC_Gamma Correction Blue Entry Register */ #define ISC_GAM_BENTRY 0x00000098 @@ -222,6 +225,8 @@ /* Offset for CSC register specific to sama5d2 product */ #define ISC_SAMA5D2_CSC_OFFSET 0 +/* Offset for CSC register specific to sama7g5 product */ +#define ISC_SAMA7G5_CSC_OFFSET 0x11c /* Color Space Conversion Control Register */ #define ISC_CSC_CTRL 0x00000398 @@ -246,6 +251,8 @@ /* Offset for CBC register specific to sama5d2 product */ #define ISC_SAMA5D2_CBC_OFFSET 0 +/* Offset for CBC register specific to sama7g5 product */ +#define ISC_SAMA7G5_CBC_OFFSET 0x11c /* Contrast And Brightness Control Register */ #define ISC_CBC_CTRL 0x000003b4 @@ -261,18 +268,30 @@ #define ISC_CBC_CONTRAST 0x000003c0 #define ISC_CBC_CONTRAST_MASK GENMASK(11, 0) +/* Hue Register */ +#define ISC_CBCHS_HUE 0x4e0 +/* Saturation Register */ +#define ISC_CBCHS_SAT 0x4e4 + /* Offset for SUB422 register specific to sama5d2 product */ #define ISC_SAMA5D2_SUB422_OFFSET 0 +/* Offset for SUB422 register specific to sama7g5 product */ +#define ISC_SAMA7G5_SUB422_OFFSET 0x124 + /* Subsampling 4:4:4 to 4:2:2 Control Register */ #define ISC_SUB422_CTRL 0x000003c4 /* Offset for SUB420 register specific to sama5d2 product */ #define ISC_SAMA5D2_SUB420_OFFSET 0 +/* Offset for SUB420 register specific to sama7g5 product */ +#define ISC_SAMA7G5_SUB420_OFFSET 0x124 /* Subsampling 4:2:2 to 4:2:0 Control Register */ #define ISC_SUB420_CTRL 0x000003cc /* Offset for RLP register specific to sama5d2 product */ #define ISC_SAMA5D2_RLP_OFFSET 0 +/* Offset for RLP register specific to sama7g5 product */ +#define ISC_SAMA7G5_RLP_OFFSET 0x124 /* Rounding, Limiting and Packing Configuration Register */ #define ISC_RLP_CFG 0x000003d0 @@ -303,6 +322,8 @@ /* Offset for HIS register specific to sama5d2 product */ #define ISC_SAMA5D2_HIS_OFFSET 0 +/* Offset for HIS register specific to sama7g5 product */ +#define ISC_SAMA7G5_HIS_OFFSET 0x124 /* Histogram Control Register */ #define ISC_HIS_CTRL 0x000003d4 @@ -326,6 +347,8 @@ /* Offset for DMA register specific to sama5d2 product */ #define ISC_SAMA5D2_DMA_OFFSET 0 +/* Offset for DMA register specific to sama7g5 product */ +#define ISC_SAMA7G5_DMA_OFFSET 0x13c /* DMA Configuration Register */ #define ISC_DCFG 0x000003e0 @@ -376,11 +399,14 @@ /* Offset for version register specific to sama5d2 product */ #define ISC_SAMA5D2_VERSION_OFFSET 0 +#define ISC_SAMA7G5_VERSION_OFFSET 0x13c /* Version Register */ #define ISC_VERSION 0x0000040c /* Offset for version register specific to sama5d2 product */ #define ISC_SAMA5D2_HIS_ENTRY_OFFSET 0 +/* Offset for version register specific to sama7g5 product */ +#define ISC_SAMA7G5_HIS_ENTRY_OFFSET 0x14c /* Histogram Entry */ #define ISC_HIS_ENTRY 0x00000410 diff --git a/drivers/media/platform/atmel/atmel-sama7g5-isc.c b/drivers/media/platform/atmel/atmel-sama7g5-isc.c new file mode 100644 index 000000000000..f2785131ff56 --- /dev/null +++ b/drivers/media/platform/atmel/atmel-sama7g5-isc.c @@ -0,0 +1,630 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Microchip eXtended Image Sensor Controller (XISC) driver + * + * Copyright (C) 2019-2021 Microchip Technology, Inc. and its subsidiaries + * + * Author: Eugen Hristev + * + * Sensor-->PFE-->DPC-->WB-->CFA-->CC-->GAM-->VHXS-->CSC-->CBHS-->SUB-->RLP-->DMA-->HIS + * + * ISC video pipeline integrates the following submodules: + * PFE: Parallel Front End to sample the camera sensor input stream + * DPC: Defective Pixel Correction with black offset correction, green disparity + * correction and defective pixel correction (3 modules total) + * WB: Programmable white balance in the Bayer domain + * CFA: Color filter array interpolation module + * CC: Programmable color correction + * GAM: Gamma correction + *VHXS: Vertical and Horizontal Scaler + * CSC: Programmable color space conversion + *CBHS: Contrast Brightness Hue and Saturation control + * SUB: This module performs YCbCr444 to YCbCr420 chrominance subsampling + * RLP: This module performs rounding, range limiting + * and packing of the incoming data + * DMA: This module performs DMA master accesses to write frames to external RAM + * HIS: Histogram module performs statistic counters on the frames + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "atmel-isc-regs.h" +#include "atmel-isc.h" + +#define ISC_SAMA7G5_MAX_SUPPORT_WIDTH 3264 +#define ISC_SAMA7G5_MAX_SUPPORT_HEIGHT 2464 + +#define ISC_SAMA7G5_PIPELINE \ + (WB_ENABLE | CFA_ENABLE | CC_ENABLE | GAM_ENABLES | CSC_ENABLE | \ + CBC_ENABLE | SUB422_ENABLE | SUB420_ENABLE) + +/* This is a list of the formats that the ISC can *output* */ +static const struct isc_format sama7g5_controller_formats[] = { + { + .fourcc = V4L2_PIX_FMT_ARGB444, + }, + { + .fourcc = V4L2_PIX_FMT_ARGB555, + }, + { + .fourcc = V4L2_PIX_FMT_RGB565, + }, + { + .fourcc = V4L2_PIX_FMT_ABGR32, + }, + { + .fourcc = V4L2_PIX_FMT_XBGR32, + }, + { + .fourcc = V4L2_PIX_FMT_YUV420, + }, + { + .fourcc = V4L2_PIX_FMT_UYVY, + }, + { + .fourcc = V4L2_PIX_FMT_VYUY, + }, + { + .fourcc = V4L2_PIX_FMT_YUYV, + }, + { + .fourcc = V4L2_PIX_FMT_YUV422P, + }, + { + .fourcc = V4L2_PIX_FMT_GREY, + }, + { + .fourcc = V4L2_PIX_FMT_Y10, + }, + { + .fourcc = V4L2_PIX_FMT_Y16, + }, +}; + +/* This is a list of formats that the ISC can receive as *input* */ +static struct isc_format sama7g5_formats_list[] = { + { + .fourcc = V4L2_PIX_FMT_SBGGR8, + .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8, + .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, + .cfa_baycfg = ISC_BAY_CFG_BGBG, + }, + { + .fourcc = V4L2_PIX_FMT_SGBRG8, + .mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8, + .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, + .cfa_baycfg = ISC_BAY_CFG_GBGB, + }, + { + .fourcc = V4L2_PIX_FMT_SGRBG8, + .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8, + .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, + .cfa_baycfg = ISC_BAY_CFG_GRGR, + }, + { + .fourcc = V4L2_PIX_FMT_SRGGB8, + .mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8, + .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, + .cfa_baycfg = ISC_BAY_CFG_RGRG, + }, + { + .fourcc = V4L2_PIX_FMT_SBGGR10, + .mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10, + .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, + .cfa_baycfg = ISC_BAY_CFG_RGRG, + }, + { + .fourcc = V4L2_PIX_FMT_SGBRG10, + .mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10, + .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, + .cfa_baycfg = ISC_BAY_CFG_GBGB, + }, + { + .fourcc = V4L2_PIX_FMT_SGRBG10, + .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10, + .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, + .cfa_baycfg = ISC_BAY_CFG_GRGR, + }, + { + .fourcc = V4L2_PIX_FMT_SRGGB10, + .mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10, + .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, + .cfa_baycfg = ISC_BAY_CFG_RGRG, + }, + { + .fourcc = V4L2_PIX_FMT_SBGGR12, + .mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12, + .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, + .cfa_baycfg = ISC_BAY_CFG_BGBG, + }, + { + .fourcc = V4L2_PIX_FMT_SGBRG12, + .mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12, + .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, + .cfa_baycfg = ISC_BAY_CFG_GBGB, + }, + { + .fourcc = V4L2_PIX_FMT_SGRBG12, + .mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12, + .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, + .cfa_baycfg = ISC_BAY_CFG_GRGR, + }, + { + .fourcc = V4L2_PIX_FMT_SRGGB12, + .mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12, + .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, + .cfa_baycfg = ISC_BAY_CFG_RGRG, + }, + { + .fourcc = V4L2_PIX_FMT_GREY, + .mbus_code = MEDIA_BUS_FMT_Y8_1X8, + .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, + }, + { + .fourcc = V4L2_PIX_FMT_YUYV, + .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, + .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, + }, + { + .fourcc = V4L2_PIX_FMT_UYVY, + .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, + .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, + }, + { + .fourcc = V4L2_PIX_FMT_RGB565, + .mbus_code = MEDIA_BUS_FMT_RGB565_2X8_LE, + .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, + }, + { + .fourcc = V4L2_PIX_FMT_Y10, + .mbus_code = MEDIA_BUS_FMT_Y10_1X10, + .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, + }, + +}; + +static void isc_sama7g5_config_csc(struct isc_device *isc) +{ + struct regmap *regmap = isc->regmap; + + /* Convert RGB to YUV */ + regmap_write(regmap, ISC_CSC_YR_YG + isc->offsets.csc, + 0x42 | (0x81 << 16)); + regmap_write(regmap, ISC_CSC_YB_OY + isc->offsets.csc, + 0x19 | (0x10 << 16)); + regmap_write(regmap, ISC_CSC_CBR_CBG + isc->offsets.csc, + 0xFDA | (0xFB6 << 16)); + regmap_write(regmap, ISC_CSC_CBB_OCB + isc->offsets.csc, + 0x70 | (0x80 << 16)); + regmap_write(regmap, ISC_CSC_CRR_CRG + isc->offsets.csc, + 0x70 | (0xFA2 << 16)); + regmap_write(regmap, ISC_CSC_CRB_OCR + isc->offsets.csc, + 0xFEE | (0x80 << 16)); +} + +static void isc_sama7g5_config_cbc(struct isc_device *isc) +{ + struct regmap *regmap = isc->regmap; + + /* Configure what is set via v4l2 ctrls */ + regmap_write(regmap, ISC_CBC_BRIGHT + isc->offsets.cbc, isc->ctrls.brightness); + regmap_write(regmap, ISC_CBC_CONTRAST + isc->offsets.cbc, isc->ctrls.contrast); + /* Configure Hue and Saturation as neutral midpoint */ + regmap_write(regmap, ISC_CBCHS_HUE, 0); + regmap_write(regmap, ISC_CBCHS_SAT, (1 << 4)); +} + +static void isc_sama7g5_config_cc(struct isc_device *isc) +{ + struct regmap *regmap = isc->regmap; + + /* Configure each register at the neutral fixed point 1.0 or 0.0 */ + regmap_write(regmap, ISC_CC_RR_RG, (1 << 8)); + regmap_write(regmap, ISC_CC_RB_OR, 0); + regmap_write(regmap, ISC_CC_GR_GG, (1 << 8) << 16); + regmap_write(regmap, ISC_CC_GB_OG, 0); + regmap_write(regmap, ISC_CC_BR_BG, 0); + regmap_write(regmap, ISC_CC_BB_OB, (1 << 8)); +} + +static void isc_sama7g5_config_ctrls(struct isc_device *isc, + const struct v4l2_ctrl_ops *ops) +{ + struct isc_ctrls *ctrls = &isc->ctrls; + struct v4l2_ctrl_handler *hdl = &ctrls->handler; + + ctrls->contrast = 16; + + v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST, -2048, 2047, 1, 16); +} + +static void isc_sama7g5_config_dpc(struct isc_device *isc) +{ + u32 bay_cfg = isc->config.sd_format->cfa_baycfg; + struct regmap *regmap = isc->regmap; + + regmap_update_bits(regmap, ISC_DPC_CFG, ISC_DPC_CFG_BLOFF_MASK, + (64 << ISC_DPC_CFG_BLOFF_SHIFT)); + regmap_update_bits(regmap, ISC_DPC_CFG, ISC_DPC_CFG_BAYCFG_MASK, + (bay_cfg << ISC_DPC_CFG_BAYCFG_SHIFT)); +} + +static void isc_sama7g5_config_gam(struct isc_device *isc) +{ + struct regmap *regmap = isc->regmap; + + regmap_update_bits(regmap, ISC_GAM_CTRL, ISC_GAM_CTRL_BIPART, + ISC_GAM_CTRL_BIPART); +} + +static void isc_sama7g5_config_rlp(struct isc_device *isc) +{ + struct regmap *regmap = isc->regmap; + u32 rlp_mode = isc->config.rlp_cfg_mode; + + regmap_update_bits(regmap, ISC_RLP_CFG + isc->offsets.rlp, + ISC_RLP_CFG_MODE_MASK | ISC_RLP_CFG_LSH | + ISC_RLP_CFG_YMODE_MASK, rlp_mode); +} + +static void isc_sama7g5_adapt_pipeline(struct isc_device *isc) +{ + isc->try_config.bits_pipeline &= ISC_SAMA7G5_PIPELINE; +} + +/* Gamma table with gamma 1/2.2 */ +static const u32 isc_sama7g5_gamma_table[][GAMMA_ENTRIES] = { + /* index 0 --> gamma bipartite */ + { + 0x980, 0x4c0320, 0x650260, 0x7801e0, 0x8701a0, 0x940180, + 0xa00160, 0xab0120, 0xb40120, 0xbd0120, 0xc60100, 0xce0100, + 0xd600e0, 0xdd00e0, 0xe400e0, 0xeb00c0, 0xf100c0, 0xf700c0, + 0xfd00c0, 0x10300a0, 0x10800c0, 0x10e00a0, 0x11300a0, 0x11800a0, + 0x11d00a0, 0x12200a0, 0x12700a0, 0x12c0080, 0x13000a0, 0x1350080, + 0x13900a0, 0x13e0080, 0x1420076, 0x17d0062, 0x1ae0054, 0x1d8004a, + 0x1fd0044, 0x21f003e, 0x23e003a, 0x25b0036, 0x2760032, 0x28f0030, + 0x2a7002e, 0x2be002c, 0x2d4002c, 0x2ea0028, 0x2fe0028, 0x3120026, + 0x3250024, 0x3370024, 0x3490022, 0x35a0022, 0x36b0020, 0x37b0020, + 0x38b0020, 0x39b001e, 0x3aa001e, 0x3b9001c, 0x3c7001c, 0x3d5001c, + 0x3e3001c, 0x3f1001c, 0x3ff001a, 0x40c001a }, +}; + +static int xisc_parse_dt(struct device *dev, struct isc_device *isc) +{ + struct device_node *np = dev->of_node; + struct device_node *epn = NULL; + struct isc_subdev_entity *subdev_entity; + unsigned int flags; + int ret; + bool mipi_mode; + + INIT_LIST_HEAD(&isc->subdev_entities); + + mipi_mode = of_property_read_bool(np, "microchip,mipi-mode"); + + while (1) { + struct v4l2_fwnode_endpoint v4l2_epn = { .bus_type = 0 }; + + epn = of_graph_get_next_endpoint(np, epn); + if (!epn) + return 0; + + ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(epn), + &v4l2_epn); + if (ret) { + ret = -EINVAL; + dev_err(dev, "Could not parse the endpoint\n"); + break; + } + + subdev_entity = devm_kzalloc(dev, sizeof(*subdev_entity), + GFP_KERNEL); + if (!subdev_entity) { + ret = -ENOMEM; + break; + } + subdev_entity->epn = epn; + + flags = v4l2_epn.bus.parallel.flags; + + if (flags & V4L2_MBUS_HSYNC_ACTIVE_LOW) + subdev_entity->pfe_cfg0 = ISC_PFE_CFG0_HPOL_LOW; + + if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW) + subdev_entity->pfe_cfg0 |= ISC_PFE_CFG0_VPOL_LOW; + + if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING) + subdev_entity->pfe_cfg0 |= ISC_PFE_CFG0_PPOL_LOW; + + if (v4l2_epn.bus_type == V4L2_MBUS_BT656) + subdev_entity->pfe_cfg0 |= ISC_PFE_CFG0_CCIR_CRC | + ISC_PFE_CFG0_CCIR656; + + if (mipi_mode) + subdev_entity->pfe_cfg0 |= ISC_PFE_CFG0_MIPI; + + list_add_tail(&subdev_entity->list, &isc->subdev_entities); + } + of_node_put(epn); + + return ret; +} + +static int microchip_xisc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct isc_device *isc; + struct resource *res; + void __iomem *io_base; + struct isc_subdev_entity *subdev_entity; + int irq; + int ret; + u32 ver; + + isc = devm_kzalloc(dev, sizeof(*isc), GFP_KERNEL); + if (!isc) + return -ENOMEM; + + platform_set_drvdata(pdev, isc); + isc->dev = dev; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + io_base = devm_ioremap_resource(dev, res); + if (IS_ERR(io_base)) + return PTR_ERR(io_base); + + isc->regmap = devm_regmap_init_mmio(dev, io_base, &isc_regmap_config); + if (IS_ERR(isc->regmap)) { + ret = PTR_ERR(isc->regmap); + dev_err(dev, "failed to init register map: %d\n", ret); + return ret; + } + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + ret = devm_request_irq(dev, irq, isc_interrupt, 0, + "microchip-sama7g5-xisc", isc); + if (ret < 0) { + dev_err(dev, "can't register ISR for IRQ %u (ret=%i)\n", + irq, ret); + return ret; + } + + isc->gamma_table = isc_sama7g5_gamma_table; + isc->gamma_max = 0; + + isc->max_width = ISC_SAMA7G5_MAX_SUPPORT_WIDTH; + isc->max_height = ISC_SAMA7G5_MAX_SUPPORT_HEIGHT; + + isc->config_dpc = isc_sama7g5_config_dpc; + isc->config_csc = isc_sama7g5_config_csc; + isc->config_cbc = isc_sama7g5_config_cbc; + isc->config_cc = isc_sama7g5_config_cc; + isc->config_gam = isc_sama7g5_config_gam; + isc->config_rlp = isc_sama7g5_config_rlp; + isc->config_ctrls = isc_sama7g5_config_ctrls; + + isc->adapt_pipeline = isc_sama7g5_adapt_pipeline; + + isc->offsets.csc = ISC_SAMA7G5_CSC_OFFSET; + isc->offsets.cbc = ISC_SAMA7G5_CBC_OFFSET; + isc->offsets.sub422 = ISC_SAMA7G5_SUB422_OFFSET; + isc->offsets.sub420 = ISC_SAMA7G5_SUB420_OFFSET; + isc->offsets.rlp = ISC_SAMA7G5_RLP_OFFSET; + isc->offsets.his = ISC_SAMA7G5_HIS_OFFSET; + isc->offsets.dma = ISC_SAMA7G5_DMA_OFFSET; + isc->offsets.version = ISC_SAMA7G5_VERSION_OFFSET; + isc->offsets.his_entry = ISC_SAMA7G5_HIS_ENTRY_OFFSET; + + isc->controller_formats = sama7g5_controller_formats; + isc->controller_formats_size = ARRAY_SIZE(sama7g5_controller_formats); + isc->formats_list = sama7g5_formats_list; + isc->formats_list_size = ARRAY_SIZE(sama7g5_formats_list); + + /* sama7g5-isc RAM access port is full AXI4 - 32 bits per beat */ + isc->dcfg = ISC_DCFG_YMBSIZE_BEATS32 | ISC_DCFG_CMBSIZE_BEATS32; + + ret = isc_pipeline_init(isc); + if (ret) + return ret; + + isc->hclock = devm_clk_get(dev, "hclock"); + if (IS_ERR(isc->hclock)) { + ret = PTR_ERR(isc->hclock); + dev_err(dev, "failed to get hclock: %d\n", ret); + return ret; + } + + ret = clk_prepare_enable(isc->hclock); + if (ret) { + dev_err(dev, "failed to enable hclock: %d\n", ret); + return ret; + } + + ret = isc_clk_init(isc); + if (ret) { + dev_err(dev, "failed to init isc clock: %d\n", ret); + goto unprepare_hclk; + } + + isc->ispck = isc->isc_clks[ISC_ISPCK].clk; + + ret = clk_prepare_enable(isc->ispck); + if (ret) { + dev_err(dev, "failed to enable ispck: %d\n", ret); + goto unprepare_hclk; + } + + /* ispck should be greater or equal to hclock */ + ret = clk_set_rate(isc->ispck, clk_get_rate(isc->hclock)); + if (ret) { + dev_err(dev, "failed to set ispck rate: %d\n", ret); + goto unprepare_clk; + } + + ret = v4l2_device_register(dev, &isc->v4l2_dev); + if (ret) { + dev_err(dev, "unable to register v4l2 device.\n"); + goto unprepare_clk; + } + + ret = xisc_parse_dt(dev, isc); + if (ret) { + dev_err(dev, "fail to parse device tree\n"); + goto unregister_v4l2_device; + } + + if (list_empty(&isc->subdev_entities)) { + dev_err(dev, "no subdev found\n"); + ret = -ENODEV; + goto unregister_v4l2_device; + } + + list_for_each_entry(subdev_entity, &isc->subdev_entities, list) { + struct v4l2_async_subdev *asd; + + v4l2_async_notifier_init(&subdev_entity->notifier); + + asd = v4l2_async_notifier_add_fwnode_remote_subdev( + &subdev_entity->notifier, + of_fwnode_handle(subdev_entity->epn), + struct v4l2_async_subdev); + + of_node_put(subdev_entity->epn); + subdev_entity->epn = NULL; + + if (IS_ERR(asd)) { + ret = PTR_ERR(asd); + goto cleanup_subdev; + } + + subdev_entity->notifier.ops = &isc_async_ops; + + ret = v4l2_async_notifier_register(&isc->v4l2_dev, + &subdev_entity->notifier); + if (ret) { + dev_err(dev, "fail to register async notifier\n"); + goto cleanup_subdev; + } + + if (video_is_registered(&isc->video_dev)) + break; + } + + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + pm_request_idle(dev); + + regmap_read(isc->regmap, ISC_VERSION + isc->offsets.version, &ver); + dev_info(dev, "Microchip XISC version %x\n", ver); + + return 0; + +cleanup_subdev: + isc_subdev_cleanup(isc); + +unregister_v4l2_device: + v4l2_device_unregister(&isc->v4l2_dev); + +unprepare_clk: + clk_disable_unprepare(isc->ispck); +unprepare_hclk: + clk_disable_unprepare(isc->hclock); + + isc_clk_cleanup(isc); + + return ret; +} + +static int microchip_xisc_remove(struct platform_device *pdev) +{ + struct isc_device *isc = platform_get_drvdata(pdev); + + pm_runtime_disable(&pdev->dev); + + isc_subdev_cleanup(isc); + + v4l2_device_unregister(&isc->v4l2_dev); + + clk_disable_unprepare(isc->ispck); + clk_disable_unprepare(isc->hclock); + + isc_clk_cleanup(isc); + + return 0; +} + +static int __maybe_unused xisc_runtime_suspend(struct device *dev) +{ + struct isc_device *isc = dev_get_drvdata(dev); + + clk_disable_unprepare(isc->ispck); + clk_disable_unprepare(isc->hclock); + + return 0; +} + +static int __maybe_unused xisc_runtime_resume(struct device *dev) +{ + struct isc_device *isc = dev_get_drvdata(dev); + int ret; + + ret = clk_prepare_enable(isc->hclock); + if (ret) + return ret; + + ret = clk_prepare_enable(isc->ispck); + if (ret) + clk_disable_unprepare(isc->hclock); + + return ret; +} + +static const struct dev_pm_ops microchip_xisc_dev_pm_ops = { + SET_RUNTIME_PM_OPS(xisc_runtime_suspend, xisc_runtime_resume, NULL) +}; + +static const struct of_device_id microchip_xisc_of_match[] = { + { .compatible = "microchip,sama7g5-isc" }, + { } +}; +MODULE_DEVICE_TABLE(of, microchip_xisc_of_match); + +static struct platform_driver microchip_xisc_driver = { + .probe = microchip_xisc_probe, + .remove = microchip_xisc_remove, + .driver = { + .name = "microchip-sama7g5-xisc", + .pm = µchip_xisc_dev_pm_ops, + .of_match_table = of_match_ptr(microchip_xisc_of_match), + }, +}; + +module_platform_driver(microchip_xisc_driver); + +MODULE_AUTHOR("Eugen Hristev "); +MODULE_DESCRIPTION("The V4L2 driver for Microchip-XISC"); +MODULE_LICENSE("GPL v2"); From 671d07658531422eaba9ef0a399532b39361abf3 Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Tue, 13 Apr 2021 12:57:30 +0200 Subject: [PATCH 308/394] media: MAINTAINERS: update ISC driver bindings file ISC driver was converted to yaml. Update maintainers file. Signed-off-by: Eugen Hristev Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 5e1bbb39a68e..ffe537b3f732 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11990,7 +11990,7 @@ MICROCHIP ISC DRIVER M: Eugen Hristev L: linux-media@vger.kernel.org S: Supported -F: Documentation/devicetree/bindings/media/atmel-isc.txt +F: Documentation/devicetree/bindings/media/atmel,isc.yaml F: drivers/media/platform/atmel/atmel-isc-base.c F: drivers/media/platform/atmel/atmel-isc-regs.h F: drivers/media/platform/atmel/atmel-isc.h From 038cc978777378884a40d1517c88eace13ddc49d Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Tue, 13 Apr 2021 12:57:31 +0200 Subject: [PATCH 309/394] media: MAINTAINERS: add xisc files to isc driver entry Add XISC driver and binding files to the ISC driver entry. Signed-off-by: Eugen Hristev Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- MAINTAINERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index ffe537b3f732..f086d2c305b5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11991,10 +11991,12 @@ M: Eugen Hristev L: linux-media@vger.kernel.org S: Supported F: Documentation/devicetree/bindings/media/atmel,isc.yaml +F: Documentation/devicetree/bindings/media/microchip,xisc.yaml F: drivers/media/platform/atmel/atmel-isc-base.c F: drivers/media/platform/atmel/atmel-isc-regs.h F: drivers/media/platform/atmel/atmel-isc.h F: drivers/media/platform/atmel/atmel-sama5d2-isc.c +F: drivers/media/platform/atmel/atmel-sama7g5-isc.c F: include/linux/atmel-isc-media.h MICROCHIP ISI DRIVER From bc4f21fcc03ddd816dac1db00918680bf7bf9d86 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 5 May 2021 21:06:18 +0200 Subject: [PATCH 310/394] media: mxl692: make a const array static, makes object smaller Don't populate the const array fw_hdr on the stack but instead it static. Makes the object code smaller by 5 bytes: Before: text data bss dec hex filename 31948 12072 64 44084 ac34 drivers/media/dvb-frontends/mxl692.o After: text data bss dec hex filename 31879 12136 64 44079 ac2f drivers/media/dvb-frontends/mxl692.o (gcc version 10.3.0) Signed-off-by: Colin Ian King Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/mxl692.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/media/dvb-frontends/mxl692.c b/drivers/media/dvb-frontends/mxl692.c index 83030643aba7..a246db683cdf 100644 --- a/drivers/media/dvb-frontends/mxl692.c +++ b/drivers/media/dvb-frontends/mxl692.c @@ -224,7 +224,9 @@ static int mxl692_validate_fw_header(struct mxl692_dev *dev, u32 ix, temp; __be32 *local_buf = NULL; u8 temp_cksum = 0; - const u8 fw_hdr[] = { 0x4D, 0x31, 0x10, 0x02, 0x40, 0x00, 0x00, 0x80 }; + static const u8 fw_hdr[] = { + 0x4D, 0x31, 0x10, 0x02, 0x40, 0x00, 0x00, 0x80 + }; if (memcmp(buffer, fw_hdr, 8) != 0) { status = -EINVAL; From 321c0d383dc3aa1b00a1a1e0957f1543fc84a028 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Fri, 21 May 2021 14:18:27 +0200 Subject: [PATCH 311/394] media: cxd2880-spi: Fix some error messages Fix some erroneous function names in some error messages. Remove some spurious or useless trailing and leading character in some messages. Signed-off-by: Christophe JAILLET Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/spi/cxd2880-spi.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/media/spi/cxd2880-spi.c b/drivers/media/spi/cxd2880-spi.c index 931ec0727cd3..e5094fff04c5 100644 --- a/drivers/media/spi/cxd2880-spi.c +++ b/drivers/media/spi/cxd2880-spi.c @@ -147,7 +147,7 @@ static int cxd2880_spi_read_ts(struct spi_device *spi, ret = spi_sync(spi, &message); if (ret) - pr_err("spi_write_then_read failed\n"); + pr_err("spi_sync failed\n"); return ret; } @@ -401,7 +401,7 @@ static int cxd2880_start_feed(struct dvb_demux_feed *feed) dvb_spi, "cxd2880_ts_read"); if (IS_ERR(dvb_spi->cxd2880_ts_read_thread)) { - pr_err("kthread_run failed/\n"); + pr_err("kthread_run failed\n"); kfree(dvb_spi->ts_buf); dvb_spi->ts_buf = NULL; memset(&dvb_spi->filter_config, 0, @@ -448,7 +448,7 @@ static int cxd2880_stop_feed(struct dvb_demux_feed *feed) * in dvb_spi->all_pid_feed_count. */ if (dvb_spi->all_pid_feed_count <= 0) { - pr_err("PID %d not found.\n", feed->pid); + pr_err("PID %d not found\n", feed->pid); return -EINVAL; } dvb_spi->all_pid_feed_count--; @@ -485,7 +485,7 @@ static int cxd2880_stop_feed(struct dvb_demux_feed *feed) ret_stop = kthread_stop(dvb_spi->cxd2880_ts_read_thread); if (ret_stop) { - pr_err("'kthread_stop failed. (%d)\n", ret_stop); + pr_err("kthread_stop failed. (%d)\n", ret_stop); ret = ret_stop; } kfree(dvb_spi->ts_buf); @@ -512,7 +512,7 @@ cxd2880_spi_probe(struct spi_device *spi) struct cxd2880_config config; if (!spi) { - pr_err("invalid arg.\n"); + pr_err("invalid arg\n"); return -EINVAL; } @@ -596,7 +596,7 @@ cxd2880_spi_probe(struct spi_device *spi) ret = dvb_spi->demux.dmx.connect_frontend(&dvb_spi->demux.dmx, &dvb_spi->dmx_fe); if (ret < 0) { - pr_err("dvb_register_frontend() failed\n"); + pr_err("connect_frontend() failed\n"); goto fail_fe_conn; } From 9ad1efee086e0e913914fa2b2173efb830bad68c Mon Sep 17 00:00:00 2001 From: Dongliang Mu Date: Tue, 25 May 2021 15:06:52 +0200 Subject: [PATCH 312/394] media: dvd_usb: memory leak in cinergyt2_fe_attach When the driver fails to talk with the hardware with dvb_usb_generic_rw, it will return an error to dvb_usb_adapter_frontend_init. However, the driver forgets to free the resource (e.g., struct cinergyt2_fe_state), which leads to a memory leak. Fix this by freeing struct cinergyt2_fe_state when dvb_usb_generic_rw fails in cinergyt2_frontend_attach. backtrace: [<0000000056e17b1a>] kmalloc include/linux/slab.h:552 [inline] [<0000000056e17b1a>] kzalloc include/linux/slab.h:682 [inline] [<0000000056e17b1a>] cinergyt2_fe_attach+0x21/0x80 drivers/media/usb/dvb-usb/cinergyT2-fe.c:271 [<00000000ae0b1711>] cinergyt2_frontend_attach+0x21/0x70 drivers/media/usb/dvb-usb/cinergyT2-core.c:74 [<00000000d0254861>] dvb_usb_adapter_frontend_init+0x11b/0x1b0 drivers/media/usb/dvb-usb/dvb-usb-dvb.c:290 [<0000000002e08ac6>] dvb_usb_adapter_init drivers/media/usb/dvb-usb/dvb-usb-init.c:84 [inline] [<0000000002e08ac6>] dvb_usb_init drivers/media/usb/dvb-usb/dvb-usb-init.c:173 [inline] [<0000000002e08ac6>] dvb_usb_device_init.cold+0x4d0/0x6ae drivers/media/usb/dvb-usb/dvb-usb-init.c:287 Reported-by: syzbot+e1de8986786b3722050e@syzkaller.appspotmail.com Signed-off-by: Dongliang Mu Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb/cinergyT2-core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/usb/dvb-usb/cinergyT2-core.c b/drivers/media/usb/dvb-usb/cinergyT2-core.c index 969a7ec71dff..4116ba5c45fc 100644 --- a/drivers/media/usb/dvb-usb/cinergyT2-core.c +++ b/drivers/media/usb/dvb-usb/cinergyT2-core.c @@ -78,6 +78,8 @@ static int cinergyt2_frontend_attach(struct dvb_usb_adapter *adap) ret = dvb_usb_generic_rw(d, st->data, 1, st->data, 3, 0); if (ret < 0) { + if (adap->fe_adap[0].fe) + adap->fe_adap[0].fe->ops.release(adap->fe_adap[0].fe); deb_rc("cinergyt2_power_ctrl() Failed to retrieve sleep state info\n"); } mutex_unlock(&d->data_mutex); From da9a805b1249be685c2bee110eb1260d610bd5d0 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Tue, 1 Jun 2021 13:07:46 +0200 Subject: [PATCH 313/394] media: cinergyt2: make properties const The dvb_usb_device_properties can be const. This makes it clear that the static can be shared across threads. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb/cinergyT2-core.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/media/usb/dvb-usb/cinergyT2-core.c b/drivers/media/usb/dvb-usb/cinergyT2-core.c index 4116ba5c45fc..23f1093d28f8 100644 --- a/drivers/media/usb/dvb-usb/cinergyT2-core.c +++ b/drivers/media/usb/dvb-usb/cinergyT2-core.c @@ -29,10 +29,8 @@ struct cinergyt2_state { unsigned char data[64]; }; -/* We are missing a release hook with usb_device data */ -static struct dvb_usb_device *cinergyt2_usb_device; - -static struct dvb_usb_device_properties cinergyt2_properties; +/* Forward declaration */ +static const struct dvb_usb_device_properties cinergyt2_properties; static int cinergyt2_streaming_ctrl(struct dvb_usb_adapter *adap, int enable) { @@ -84,9 +82,6 @@ static int cinergyt2_frontend_attach(struct dvb_usb_adapter *adap) } mutex_unlock(&d->data_mutex); - /* Copy this pointer as we are gonna need it in the release phase */ - cinergyt2_usb_device = adap->dev; - return ret; } @@ -205,7 +200,7 @@ static struct usb_device_id cinergyt2_usb_table[] = { MODULE_DEVICE_TABLE(usb, cinergyt2_usb_table); -static struct dvb_usb_device_properties cinergyt2_properties = { +static const struct dvb_usb_device_properties cinergyt2_properties = { .size_of_priv = sizeof(struct cinergyt2_state), .num_adapters = 1, .adapter = { From 04297b00dfb45277b8b661d48a7a5e29876fc6ae Mon Sep 17 00:00:00 2001 From: Evgeny Novikov Date: Tue, 1 Jun 2021 14:56:43 +0200 Subject: [PATCH 314/394] media: st_rc: Handle errors of clk_prepare_enable() Hadle errors of clk_prepare_enable() in st_rc_hardware_init() and its callers. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Evgeny Novikov Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/st_rc.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/drivers/media/rc/st_rc.c b/drivers/media/rc/st_rc.c index 3237fef5d502..d79d1e3996b2 100644 --- a/drivers/media/rc/st_rc.c +++ b/drivers/media/rc/st_rc.c @@ -157,8 +157,9 @@ static irqreturn_t st_rc_rx_interrupt(int irq, void *data) return IRQ_HANDLED; } -static void st_rc_hardware_init(struct st_rc_device *dev) +static int st_rc_hardware_init(struct st_rc_device *dev) { + int ret; int baseclock, freqdiff; unsigned int rx_max_symbol_per = MAX_SYMB_TIME; unsigned int rx_sampling_freq_div; @@ -166,7 +167,12 @@ static void st_rc_hardware_init(struct st_rc_device *dev) /* Enable the IP */ reset_control_deassert(dev->rstc); - clk_prepare_enable(dev->sys_clock); + ret = clk_prepare_enable(dev->sys_clock); + if (ret) { + dev_err(dev->dev, "Failed to prepare/enable system clock\n"); + return ret; + } + baseclock = clk_get_rate(dev->sys_clock); /* IRB input pins are inverted internally from high to low. */ @@ -184,6 +190,8 @@ static void st_rc_hardware_init(struct st_rc_device *dev) } writel(rx_max_symbol_per, dev->rx_base + IRB_MAX_SYM_PERIOD); + + return 0; } static int st_rc_remove(struct platform_device *pdev) @@ -287,7 +295,9 @@ static int st_rc_probe(struct platform_device *pdev) rc_dev->dev = dev; platform_set_drvdata(pdev, rc_dev); - st_rc_hardware_init(rc_dev); + ret = st_rc_hardware_init(rc_dev); + if (ret) + goto err; rdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; /* rx sampling rate is 10Mhz */ @@ -359,6 +369,7 @@ static int st_rc_suspend(struct device *dev) static int st_rc_resume(struct device *dev) { + int ret; struct st_rc_device *rc_dev = dev_get_drvdata(dev); struct rc_dev *rdev = rc_dev->rdev; @@ -367,7 +378,10 @@ static int st_rc_resume(struct device *dev) rc_dev->irq_wake = 0; } else { pinctrl_pm_select_default_state(dev); - st_rc_hardware_init(rc_dev); + ret = st_rc_hardware_init(rc_dev); + if (ret) + return ret; + if (rdev->users) { writel(IRB_RX_INTS, rc_dev->rx_base + IRB_RX_INT_EN); writel(0x01, rc_dev->rx_base + IRB_RX_EN); From 53a370f621a04a06bd2402c13580d7e4eb172c98 Mon Sep 17 00:00:00 2001 From: Alexander Voronov Date: Tue, 1 Jun 2021 22:28:12 +0200 Subject: [PATCH 315/394] media: rc: add keymap for Toshiba CT-90405 remote This is an NEC remote control device shipped with some Toshiba TVs. Signed-off-by: Alexander Voronov Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- .../devicetree/bindings/media/rc.yaml | 1 + drivers/media/rc/keymaps/Makefile | 1 + drivers/media/rc/keymaps/rc-ct-90405.c | 86 +++++++++++++++++++ include/media/rc-map.h | 1 + 4 files changed, 89 insertions(+) create mode 100644 drivers/media/rc/keymaps/rc-ct-90405.c diff --git a/Documentation/devicetree/bindings/media/rc.yaml b/Documentation/devicetree/bindings/media/rc.yaml index 12d838b05632..d4c541c4b164 100644 --- a/Documentation/devicetree/bindings/media/rc.yaml +++ b/Documentation/devicetree/bindings/media/rc.yaml @@ -45,6 +45,7 @@ properties: - rc-cec - rc-cinergy - rc-cinergy-1400 + - rc-ct-90405 - rc-d680-dmb - rc-delock-61959 - rc-dib0700-nec diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile index f609dfe7fd76..5fe5c9e1a46d 100644 --- a/drivers/media/rc/keymaps/Makefile +++ b/drivers/media/rc/keymaps/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ rc-budget-ci-old.o \ rc-cinergy-1400.o \ rc-cinergy.o \ + rc-ct-90405.o \ rc-d680-dmb.o \ rc-delock-61959.o \ rc-dib0700-nec.o \ diff --git a/drivers/media/rc/keymaps/rc-ct-90405.c b/drivers/media/rc/keymaps/rc-ct-90405.c new file mode 100644 index 000000000000..8914c83c9d9f --- /dev/null +++ b/drivers/media/rc/keymaps/rc-ct-90405.c @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Toshiba CT-90405 remote controller keytable + * + * Copyright (C) 2021 Alexander Voronov + */ + +#include +#include + +static struct rc_map_table ct_90405[] = { + { 0x4014, KEY_SWITCHVIDEOMODE }, + { 0x4012, KEY_POWER }, + { 0x4044, KEY_TV }, + { 0x40be43, KEY_3D_MODE }, + { 0x400c, KEY_SUBTITLE }, + { 0x4001, KEY_NUMERIC_1 }, + { 0x4002, KEY_NUMERIC_2 }, + { 0x4003, KEY_NUMERIC_3 }, + { 0x4004, KEY_NUMERIC_4 }, + { 0x4005, KEY_NUMERIC_5 }, + { 0x4006, KEY_NUMERIC_6 }, + { 0x4007, KEY_NUMERIC_7 }, + { 0x4008, KEY_NUMERIC_8 }, + { 0x4009, KEY_NUMERIC_9 }, + { 0x4062, KEY_AUDIO_DESC }, + { 0x4000, KEY_NUMERIC_0 }, + { 0x401a, KEY_VOLUMEUP }, + { 0x401e, KEY_VOLUMEDOWN }, + { 0x4016, KEY_INFO }, + { 0x4010, KEY_MUTE }, + { 0x401b, KEY_CHANNELUP }, + { 0x401f, KEY_CHANNELDOWN }, + { 0x40da, KEY_VENDOR }, + { 0x4066, KEY_PLAYER }, + { 0x4017, KEY_TEXT }, + { 0x4047, KEY_LIST }, + { 0x4073, KEY_PAGEUP }, + { 0x4045, KEY_PROGRAM }, + { 0x4043, KEY_EXIT }, + { 0x4074, KEY_PAGEDOWN }, + { 0x4064, KEY_BACK }, + { 0x405b, KEY_MENU }, + { 0x4019, KEY_UP }, + { 0x4040, KEY_RIGHT }, + { 0x401d, KEY_DOWN }, + { 0x4042, KEY_LEFT }, + { 0x4021, KEY_OK }, + { 0x4053, KEY_REWIND }, + { 0x4067, KEY_PLAY }, + { 0x400d, KEY_FASTFORWARD }, + { 0x4054, KEY_PREVIOUS }, + { 0x4068, KEY_STOP }, + { 0x406a, KEY_PAUSE }, + { 0x4015, KEY_NEXT }, + { 0x4048, KEY_RED }, + { 0x4049, KEY_GREEN }, + { 0x404a, KEY_YELLOW }, + { 0x404b, KEY_BLUE }, + { 0x406f, KEY_RECORD } +}; + +static struct rc_map_list ct_90405_map = { + .map = { + .scan = ct_90405, + .size = ARRAY_SIZE(ct_90405), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_CT_90405, + } +}; + +static int __init init_rc_map_ct_90405(void) +{ + return rc_map_register(&ct_90405_map); +} + +static void __exit exit_rc_map_ct_90405(void) +{ + rc_map_unregister(&ct_90405_map); +} + +module_init(init_rc_map_ct_90405) +module_exit(exit_rc_map_ct_90405) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Alexander Voronov "); diff --git a/include/media/rc-map.h b/include/media/rc-map.h index b50443d6fd77..793b54342dff 100644 --- a/include/media/rc-map.h +++ b/include/media/rc-map.h @@ -231,6 +231,7 @@ struct rc_map *rc_map_get(const char *name); #define RC_MAP_CEC "rc-cec" #define RC_MAP_CINERGY "rc-cinergy" #define RC_MAP_CINERGY_1400 "rc-cinergy-1400" +#define RC_MAP_CT_90405 "rc-ct-90405" #define RC_MAP_D680_DMB "rc-d680-dmb" #define RC_MAP_DELOCK_61959 "rc-delock-61959" #define RC_MAP_DIB0700_NEC_TABLE "rc-dib0700-nec" From f1d9f315924f02ed8aabada04a04b20a0c6cc9be Mon Sep 17 00:00:00 2001 From: Zhen Lei Date: Thu, 3 Jun 2021 09:02:30 +0200 Subject: [PATCH 316/394] media: imon: use DEVICE_ATTR_RW() helper macro Use DEVICE_ATTR_RW() helper macro instead of DEVICE_ATTR(), which is simpler and more readable. Due to the names of the read and write functions of the sysfs attribute is normalized, there is a natural association. Signed-off-by: Zhen Lei Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/imon.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c index a7962ca2ac8e..2ca4e86c7b9f 100644 --- a/drivers/media/rc/imon.c +++ b/drivers/media/rc/imon.c @@ -780,7 +780,7 @@ static int send_set_imon_clock(struct imon_context *ictx, /* * These are the sysfs functions to handle the association on the iMON 2.4G LT. */ -static ssize_t show_associate_remote(struct device *d, +static ssize_t associate_remote_show(struct device *d, struct device_attribute *attr, char *buf) { @@ -800,7 +800,7 @@ static ssize_t show_associate_remote(struct device *d, return strlen(buf); } -static ssize_t store_associate_remote(struct device *d, +static ssize_t associate_remote_store(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { @@ -822,7 +822,7 @@ static ssize_t store_associate_remote(struct device *d, /* * sysfs functions to control internal imon clock */ -static ssize_t show_imon_clock(struct device *d, +static ssize_t imon_clock_show(struct device *d, struct device_attribute *attr, char *buf) { struct imon_context *ictx = dev_get_drvdata(d); @@ -848,7 +848,7 @@ static ssize_t show_imon_clock(struct device *d, return len; } -static ssize_t store_imon_clock(struct device *d, +static ssize_t imon_clock_store(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { @@ -895,11 +895,8 @@ exit: } -static DEVICE_ATTR(imon_clock, S_IWUSR | S_IRUGO, show_imon_clock, - store_imon_clock); - -static DEVICE_ATTR(associate_remote, S_IWUSR | S_IRUGO, show_associate_remote, - store_associate_remote); +static DEVICE_ATTR_RW(imon_clock); +static DEVICE_ATTR_RW(associate_remote); static struct attribute *imon_display_sysfs_entries[] = { &dev_attr_imon_clock.attr, From 4dd0f63b51c24afd2f34afbae2e728cf00c390e6 Mon Sep 17 00:00:00 2001 From: Benjamin Gaignard Date: Thu, 3 Jun 2021 13:49:56 +0200 Subject: [PATCH 317/394] media: hevc: Add fields and flags for hevc PPS Add fields and flags as they are defined in 7.4.3.3.1 "General picture parameter set RBSP semantics of the H.265 ITU specification. Signed-off-by: Benjamin Gaignard Reviewed-by: Ezequiel Garcia Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../userspace-api/media/v4l/ext-ctrls-codec.rst | 14 ++++++++++++++ include/media/hevc-ctrls.h | 4 ++++ 2 files changed, 18 insertions(+) diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst index 2b5edab55bb4..15468dcfaf08 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst @@ -2786,6 +2786,12 @@ enum v4l2_mpeg_video_hevc_size_of_length_field - * - __u8 - ``num_extra_slice_header_bits`` - + * - __u8 + - ``num_ref_idx_l0_default_active_minus1`` + - Specifies the inferred value of num_ref_idx_l0_active_minus1 + * - __u8 + - ``num_ref_idx_l1_default_active_minus1`` + - Specifies the inferred value of num_ref_idx_l1_active_minus1 * - __s8 - ``init_qp_minus26`` - @@ -2896,6 +2902,14 @@ enum v4l2_mpeg_video_hevc_size_of_length_field - * - ``V4L2_HEVC_PPS_FLAG_SLICE_SEGMENT_HEADER_EXTENSION_PRESENT`` - 0x00040000 - + * - ``V4L2_HEVC_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT`` + - 0x00080000 + - Specifies the presence of deblocking filter control syntax elements in + the PPS + * - ``V4L2_HEVC_PPS_FLAG_UNIFORM_SPACING`` + - 0x00100000 + - Specifies that tile column boundaries and likewise tile row boundaries + are distributed uniformly across the picture .. raw:: latex diff --git a/include/media/hevc-ctrls.h b/include/media/hevc-ctrls.h index 36e4c93707ae..3b525fd6e618 100644 --- a/include/media/hevc-ctrls.h +++ b/include/media/hevc-ctrls.h @@ -99,10 +99,14 @@ struct v4l2_ctrl_hevc_sps { #define V4L2_HEVC_PPS_FLAG_PPS_DISABLE_DEBLOCKING_FILTER (1ULL << 16) #define V4L2_HEVC_PPS_FLAG_LISTS_MODIFICATION_PRESENT (1ULL << 17) #define V4L2_HEVC_PPS_FLAG_SLICE_SEGMENT_HEADER_EXTENSION_PRESENT (1ULL << 18) +#define V4L2_HEVC_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT (1ULL << 19) +#define V4L2_HEVC_PPS_FLAG_UNIFORM_SPACING (1ULL << 20) struct v4l2_ctrl_hevc_pps { /* ISO/IEC 23008-2, ITU-T Rec. H.265: Picture parameter set */ __u8 num_extra_slice_header_bits; + __u8 num_ref_idx_l0_default_active_minus1; + __u8 num_ref_idx_l1_default_active_minus1; __s8 init_qp_minus26; __u8 diff_cu_qp_delta_depth; __s8 pps_cb_qp_offset; From d395a78db9eabd12633b39e05c80e803543b6590 Mon Sep 17 00:00:00 2001 From: Benjamin Gaignard Date: Thu, 3 Jun 2021 13:49:57 +0200 Subject: [PATCH 318/394] media: hevc: Add decode params control Add decode params control and the associated structure to group all the information that are needed to decode a reference frame as is described in ITU-T Rec. H.265 section "8.3.2 Decoding process for reference picture set". Adapt Cedrus driver to these changes. Signed-off-by: Benjamin Gaignard Reviewed-by: Ezequiel Garcia Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../media/v4l/ext-ctrls-codec.rst | 94 +++++++++++++++---- .../media/v4l/vidioc-queryctrl.rst | 6 ++ drivers/media/v4l2-core/v4l2-ctrls-core.c | 21 +++-- drivers/media/v4l2-core/v4l2-ctrls-defs.c | 4 + drivers/staging/media/sunxi/cedrus/cedrus.c | 6 ++ drivers/staging/media/sunxi/cedrus/cedrus.h | 1 + .../staging/media/sunxi/cedrus/cedrus_dec.c | 2 + .../staging/media/sunxi/cedrus/cedrus_h265.c | 12 ++- include/media/hevc-ctrls.h | 29 ++++-- 9 files changed, 136 insertions(+), 39 deletions(-) diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst index 15468dcfaf08..8c6e2a11ed95 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst @@ -3000,9 +3000,6 @@ enum v4l2_mpeg_video_hevc_size_of_length_field - * - __u8 - ``pic_struct`` - - * - __u8 - - ``num_active_dpb_entries`` - - The number of entries in ``dpb``. * - __u8 - ``ref_idx_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]`` - The list of L0 reference elements as indices in the DPB. @@ -3010,22 +3007,8 @@ enum v4l2_mpeg_video_hevc_size_of_length_field - - ``ref_idx_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]`` - The list of L1 reference elements as indices in the DPB. * - __u8 - - ``num_rps_poc_st_curr_before`` - - The number of reference pictures in the short-term set that come before - the current frame. - * - __u8 - - ``num_rps_poc_st_curr_after`` - - The number of reference pictures in the short-term set that come after - the current frame. - * - __u8 - - ``num_rps_poc_lt_curr`` - - The number of reference pictures in the long-term set. - * - __u8 - - ``padding[7]`` + - ``padding`` - Applications and drivers must set this to zero. - * - struct :c:type:`v4l2_hevc_dpb_entry` - - ``dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]`` - - The decoded picture buffer, for meta-data about reference frames. * - struct :c:type:`v4l2_hevc_pred_weight_table` - ``pred_weight_table`` - The prediction weight coefficients for inter-picture prediction. @@ -3281,3 +3264,78 @@ enum v4l2_mpeg_video_hevc_size_of_length_field - encoding the next frame queued after setting this control. This provides a bitmask which consists of bits [0, LTR_COUNT-1]. This is applicable to the H264 and HEVC encoders. + +``V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS (struct)`` + Specifies various decode parameters, especially the references picture order + count (POC) for all the lists (short, long, before, current, after) and the + number of entries for each of them. + These parameters are defined according to :ref:`hevc`. + They are described in section 8.3 "Slice decoding process" of the + specification. + +.. c:type:: v4l2_ctrl_hevc_decode_params + +.. cssclass:: longtable + +.. flat-table:: struct v4l2_ctrl_hevc_decode_params + :header-rows: 0 + :stub-columns: 0 + :widths: 1 1 2 + + * - __s32 + - ``pic_order_cnt_val`` + - PicOrderCntVal as described in section 8.3.1 "Decoding process + for picture order count" of the specification. + * - __u8 + - ``num_active_dpb_entries`` + - The number of entries in ``dpb``. + * - struct :c:type:`v4l2_hevc_dpb_entry` + - ``dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]`` + - The decoded picture buffer, for meta-data about reference frames. + * - __u8 + - ``num_poc_st_curr_before`` + - The number of reference pictures in the short-term set that come before + the current frame. + * - __u8 + - ``num_poc_st_curr_after`` + - The number of reference pictures in the short-term set that come after + the current frame. + * - __u8 + - ``num_poc_lt_curr`` + - The number of reference pictures in the long-term set. + * - __u8 + - ``poc_st_curr_before[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]`` + - PocStCurrBefore as described in section 8.3.2 "Decoding process for reference + picture set. + * - __u8 + - ``poc_st_curr_after[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]`` + - PocStCurrAfter as described in section 8.3.2 "Decoding process for reference + picture set. + * - __u8 + - ``poc_lt_curr[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]`` + - PocLtCurr as described in section 8.3.2 "Decoding process for reference + picture set. + * - __u64 + - ``flags`` + - See :ref:`Decode Parameters Flags ` + +.. _hevc_decode_params_flags: + +``Decode Parameters Flags`` + +.. cssclass:: longtable + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + :widths: 1 1 2 + + * - ``V4L2_HEVC_DECODE_PARAM_FLAG_IRAP_PIC`` + - 0x00000001 + - + * - ``V4L2_HEVC_DECODE_PARAM_FLAG_IDR_PIC`` + - 0x00000002 + - + * - ``V4L2_HEVC_DECODE_PARAM_FLAG_NO_OUTPUT_OF_PRIOR`` + - 0x00000004 + - diff --git a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst index 07e54029e1e9..f9ecf6276129 100644 --- a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst +++ b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst @@ -501,6 +501,12 @@ See also the examples in :ref:`control`. - n/a - A struct :c:type:`v4l2_ctrl_vp8_frame`, containing VP8 frame parameters for stateless video decoders. + * - ``V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS`` + - n/a + - n/a + - n/a + - A struct :c:type:`v4l2_ctrl_hevc_decode_params`, containing HEVC + decoding parameters for stateless video decoders. .. raw:: latex diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c index 081439224357..c4b5082849b6 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls-core.c +++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c @@ -337,6 +337,7 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, struct v4l2_ctrl_hevc_pps *p_hevc_pps; struct v4l2_ctrl_hevc_slice_params *p_hevc_slice_params; struct v4l2_ctrl_hdr10_mastering_display *p_hdr10_mastering; + struct v4l2_ctrl_hevc_decode_params *p_hevc_decode_params; struct v4l2_area *area; void *p = ptr.p + idx * ctrl->elem_size; unsigned int i; @@ -616,23 +617,26 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, zero_padding(*p_hevc_pps); break; - case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS: - p_hevc_slice_params = p; + case V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS: + p_hevc_decode_params = p; - if (p_hevc_slice_params->num_active_dpb_entries > + if (p_hevc_decode_params->num_active_dpb_entries > V4L2_HEVC_DPB_ENTRIES_NUM_MAX) return -EINVAL; - zero_padding(p_hevc_slice_params->pred_weight_table); - - for (i = 0; i < p_hevc_slice_params->num_active_dpb_entries; + for (i = 0; i < p_hevc_decode_params->num_active_dpb_entries; i++) { struct v4l2_hevc_dpb_entry *dpb_entry = - &p_hevc_slice_params->dpb[i]; + &p_hevc_decode_params->dpb[i]; zero_padding(*dpb_entry); } + break; + case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS: + p_hevc_slice_params = p; + + zero_padding(p_hevc_slice_params->pred_weight_table); zero_padding(*p_hevc_slice_params); break; @@ -1236,6 +1240,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS: elem_size = sizeof(struct v4l2_ctrl_hevc_slice_params); break; + case V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS: + elem_size = sizeof(struct v4l2_ctrl_hevc_decode_params); + break; case V4L2_CTRL_TYPE_HDR10_CLL_INFO: elem_size = sizeof(struct v4l2_ctrl_hdr10_cll_info); break; diff --git a/drivers/media/v4l2-core/v4l2-ctrls-defs.c b/drivers/media/v4l2-core/v4l2-ctrls-defs.c index 7963c7b43450..b6344bbf1e00 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls-defs.c +++ b/drivers/media/v4l2-core/v4l2-ctrls-defs.c @@ -996,6 +996,7 @@ const char *v4l2_ctrl_get_name(u32 id) case V4L2_CID_MPEG_VIDEO_HEVC_SPS: return "HEVC Sequence Parameter Set"; case V4L2_CID_MPEG_VIDEO_HEVC_PPS: return "HEVC Picture Parameter Set"; case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS: return "HEVC Slice Parameters"; + case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS: return "HEVC Decode Parameters"; case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE: return "HEVC Decode Mode"; case V4L2_CID_MPEG_VIDEO_HEVC_START_CODE: return "HEVC Start Code"; @@ -1487,6 +1488,9 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS: *type = V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS; break; + case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS: + *type = V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS; + break; case V4L2_CID_UNIT_CELL_SIZE: *type = V4L2_CTRL_TYPE_AREA; *flags |= V4L2_CTRL_FLAG_READ_ONLY; diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c index fa348c09f844..c0d005dafc6c 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus.c @@ -157,6 +157,12 @@ static const struct cedrus_control cedrus_controls[] = { }, .codec = CEDRUS_CODEC_VP8, }, + { + .cfg = { + .id = V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS, + }, + .codec = CEDRUS_CODEC_H265, + }, }; #define CEDRUS_CONTROLS_COUNT ARRAY_SIZE(cedrus_controls) diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h index bbcdcd0787cf..88afba17b78b 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus.h +++ b/drivers/staging/media/sunxi/cedrus/cedrus.h @@ -77,6 +77,7 @@ struct cedrus_h265_run { const struct v4l2_ctrl_hevc_sps *sps; const struct v4l2_ctrl_hevc_pps *pps; const struct v4l2_ctrl_hevc_slice_params *slice_params; + const struct v4l2_ctrl_hevc_decode_params *decode_params; }; struct cedrus_vp8_run { diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c index 97e410d92506..40e8c4123f76 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c @@ -70,6 +70,8 @@ void cedrus_device_run(void *priv) V4L2_CID_MPEG_VIDEO_HEVC_PPS); run.h265.slice_params = cedrus_find_control_data(ctx, V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS); + run.h265.decode_params = cedrus_find_control_data(ctx, + V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS); break; case V4L2_PIX_FMT_VP8_FRAME: diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c index 10744fab7cea..6821e3d05d34 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c @@ -245,6 +245,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx, const struct v4l2_ctrl_hevc_sps *sps; const struct v4l2_ctrl_hevc_pps *pps; const struct v4l2_ctrl_hevc_slice_params *slice_params; + const struct v4l2_ctrl_hevc_decode_params *decode_params; const struct v4l2_hevc_pred_weight_table *pred_weight_table; dma_addr_t src_buf_addr; dma_addr_t src_buf_end_addr; @@ -256,6 +257,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx, sps = run->h265.sps; pps = run->h265.pps; slice_params = run->h265.slice_params; + decode_params = run->h265.decode_params; pred_weight_table = &slice_params->pred_weight_table; /* MV column buffer size and allocation. */ @@ -487,7 +489,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx, reg = VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_TC_OFFSET_DIV2(slice_params->slice_tc_offset_div2) | VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_BETA_OFFSET_DIV2(slice_params->slice_beta_offset_div2) | - VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_POC_BIGEST_IN_RPS_ST(slice_params->num_rps_poc_st_curr_after == 0) | + VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_POC_BIGEST_IN_RPS_ST(decode_params->num_poc_st_curr_after == 0) | VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_CR_QP_OFFSET(slice_params->slice_cr_qp_offset) | VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_CB_QP_OFFSET(slice_params->slice_cb_qp_offset) | VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_QP_DELTA(slice_params->slice_qp_delta); @@ -527,8 +529,8 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx, cedrus_write(dev, VE_DEC_H265_NEIGHBOR_INFO_ADDR, reg); /* Write decoded picture buffer in pic list. */ - cedrus_h265_frame_info_write_dpb(ctx, slice_params->dpb, - slice_params->num_active_dpb_entries); + cedrus_h265_frame_info_write_dpb(ctx, decode_params->dpb, + decode_params->num_active_dpb_entries); /* Output frame. */ @@ -545,7 +547,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx, /* Reference picture list 0 (for P/B frames). */ if (slice_params->slice_type != V4L2_HEVC_SLICE_TYPE_I) { - cedrus_h265_ref_pic_list_write(dev, slice_params->dpb, + cedrus_h265_ref_pic_list_write(dev, decode_params->dpb, slice_params->ref_idx_l0, slice_params->num_ref_idx_l0_active_minus1 + 1, VE_DEC_H265_SRAM_OFFSET_REF_PIC_LIST0); @@ -564,7 +566,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx, /* Reference picture list 1 (for B frames). */ if (slice_params->slice_type == V4L2_HEVC_SLICE_TYPE_B) { - cedrus_h265_ref_pic_list_write(dev, slice_params->dpb, + cedrus_h265_ref_pic_list_write(dev, decode_params->dpb, slice_params->ref_idx_l1, slice_params->num_ref_idx_l1_active_minus1 + 1, VE_DEC_H265_SRAM_OFFSET_REF_PIC_LIST1); diff --git a/include/media/hevc-ctrls.h b/include/media/hevc-ctrls.h index 3b525fd6e618..1b702c3230fb 100644 --- a/include/media/hevc-ctrls.h +++ b/include/media/hevc-ctrls.h @@ -19,6 +19,7 @@ #define V4L2_CID_MPEG_VIDEO_HEVC_SPS (V4L2_CID_CODEC_BASE + 1008) #define V4L2_CID_MPEG_VIDEO_HEVC_PPS (V4L2_CID_CODEC_BASE + 1009) #define V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS (V4L2_CID_CODEC_BASE + 1010) +#define V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS (V4L2_CID_CODEC_BASE + 1012) #define V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE (V4L2_CID_CODEC_BASE + 1015) #define V4L2_CID_MPEG_VIDEO_HEVC_START_CODE (V4L2_CID_CODEC_BASE + 1016) @@ -26,6 +27,7 @@ #define V4L2_CTRL_TYPE_HEVC_SPS 0x0120 #define V4L2_CTRL_TYPE_HEVC_PPS 0x0121 #define V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS 0x0122 +#define V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS 0x0124 enum v4l2_mpeg_video_hevc_decode_mode { V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_SLICE_BASED, @@ -194,18 +196,10 @@ struct v4l2_ctrl_hevc_slice_params { __u8 pic_struct; /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */ - __u8 num_active_dpb_entries; __u8 ref_idx_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; __u8 ref_idx_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; - __u8 num_rps_poc_st_curr_before; - __u8 num_rps_poc_st_curr_after; - __u8 num_rps_poc_lt_curr; - - __u8 padding; - - /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */ - struct v4l2_hevc_dpb_entry dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; + __u8 padding[5]; /* ISO/IEC 23008-2, ITU-T Rec. H.265: Weighted prediction parameter */ struct v4l2_hevc_pred_weight_table pred_weight_table; @@ -213,4 +207,21 @@ struct v4l2_ctrl_hevc_slice_params { __u64 flags; }; +#define V4L2_HEVC_DECODE_PARAM_FLAG_IRAP_PIC 0x1 +#define V4L2_HEVC_DECODE_PARAM_FLAG_IDR_PIC 0x2 +#define V4L2_HEVC_DECODE_PARAM_FLAG_NO_OUTPUT_OF_PRIOR 0x4 + +struct v4l2_ctrl_hevc_decode_params { + __s32 pic_order_cnt_val; + __u8 num_active_dpb_entries; + struct v4l2_hevc_dpb_entry dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; + __u8 num_poc_st_curr_before; + __u8 num_poc_st_curr_after; + __u8 num_poc_lt_curr; + __u8 poc_st_curr_before[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; + __u8 poc_st_curr_after[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; + __u8 poc_lt_curr[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; + __u64 flags; +}; + #endif From 42cb2a8f27d284b6c73dfc23bed4d6991f3bc1a3 Mon Sep 17 00:00:00 2001 From: Benjamin Gaignard Date: Thu, 3 Jun 2021 13:49:58 +0200 Subject: [PATCH 319/394] media: hantro: change hantro_codec_ops run prototype to return errors Change hantro_codec_ops run prototype from 'void' to 'int'. This allows the driver to cancel the job if an error occurs while configuring the hardware. Signed-off-by: Benjamin Gaignard Reviewed-by: Ezequiel Garcia Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/hantro/hantro_drv.c | 4 +++- .../staging/media/hantro/hantro_g1_h264_dec.c | 10 +++++++--- .../media/hantro/hantro_g1_mpeg2_dec.c | 4 +++- .../staging/media/hantro/hantro_g1_vp8_dec.c | 6 ++++-- .../staging/media/hantro/hantro_h1_jpeg_enc.c | 4 +++- drivers/staging/media/hantro/hantro_hw.h | 19 ++++++++++--------- .../media/hantro/rk3399_vpu_hw_jpeg_enc.c | 4 +++- .../media/hantro/rk3399_vpu_hw_mpeg2_dec.c | 4 +++- .../media/hantro/rk3399_vpu_hw_vp8_dec.c | 6 ++++-- 9 files changed, 40 insertions(+), 21 deletions(-) diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c index 4914987cfd9d..e255756dfd9e 100644 --- a/drivers/staging/media/hantro/hantro_drv.c +++ b/drivers/staging/media/hantro/hantro_drv.c @@ -170,7 +170,9 @@ static void device_run(void *priv) v4l2_m2m_buf_copy_metadata(src, dst, true); - ctx->codec_ops->run(ctx); + if (ctx->codec_ops->run(ctx)) + goto err_cancel_job; + return; err_cancel_job: diff --git a/drivers/staging/media/hantro/hantro_g1_h264_dec.c b/drivers/staging/media/hantro/hantro_g1_h264_dec.c index 845bef73d218..5c792b7bcb79 100644 --- a/drivers/staging/media/hantro/hantro_g1_h264_dec.c +++ b/drivers/staging/media/hantro/hantro_g1_h264_dec.c @@ -273,13 +273,15 @@ static void set_buffers(struct hantro_ctx *ctx) vdpu_write_relaxed(vpu, ctx->h264_dec.priv.dma, G1_REG_ADDR_QTABLE); } -void hantro_g1_h264_dec_run(struct hantro_ctx *ctx) +int hantro_g1_h264_dec_run(struct hantro_ctx *ctx) { struct hantro_dev *vpu = ctx->dev; + int ret; /* Prepare the H264 decoder context. */ - if (hantro_h264_dec_prepare_run(ctx)) - return; + ret = hantro_h264_dec_prepare_run(ctx); + if (ret) + return ret; /* Configure hardware registers. */ set_params(ctx); @@ -301,4 +303,6 @@ void hantro_g1_h264_dec_run(struct hantro_ctx *ctx) G1_REG_CONFIG_DEC_CLK_GATE_E, G1_REG_CONFIG); vdpu_write(vpu, G1_REG_INTERRUPT_DEC_E, G1_REG_INTERRUPT); + + return 0; } diff --git a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c index 6ee1a19d189b..9aea331e1a3c 100644 --- a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c +++ b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c @@ -145,7 +145,7 @@ hantro_g1_mpeg2_dec_set_buffers(struct hantro_dev *vpu, struct hantro_ctx *ctx, vdpu_write_relaxed(vpu, backward_addr, G1_REG_REFER3_BASE); } -void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx) +int hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx) { struct hantro_dev *vpu = ctx->dev; struct vb2_v4l2_buffer *src_buf, *dst_buf; @@ -235,4 +235,6 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx) hantro_end_prepare_run(ctx); vdpu_write(vpu, G1_REG_INTERRUPT_DEC_E, G1_REG_INTERRUPT); + + return 0; } diff --git a/drivers/staging/media/hantro/hantro_g1_vp8_dec.c b/drivers/staging/media/hantro/hantro_g1_vp8_dec.c index 57002ba70176..96622a7f8279 100644 --- a/drivers/staging/media/hantro/hantro_g1_vp8_dec.c +++ b/drivers/staging/media/hantro/hantro_g1_vp8_dec.c @@ -425,7 +425,7 @@ static void cfg_buffers(struct hantro_ctx *ctx, vdpu_write_relaxed(vpu, dst_dma, G1_REG_ADDR_DST); } -void hantro_g1_vp8_dec_run(struct hantro_ctx *ctx) +int hantro_g1_vp8_dec_run(struct hantro_ctx *ctx) { const struct v4l2_ctrl_vp8_frame *hdr; struct hantro_dev *vpu = ctx->dev; @@ -438,7 +438,7 @@ void hantro_g1_vp8_dec_run(struct hantro_ctx *ctx) hdr = hantro_get_ctrl(ctx, V4L2_CID_STATELESS_VP8_FRAME); if (WARN_ON(!hdr)) - return; + return -EINVAL; /* Reset segment_map buffer in keyframe */ if (V4L2_VP8_FRAME_IS_KEY_FRAME(hdr) && ctx->vp8_dec.segment_map.cpu) @@ -498,4 +498,6 @@ void hantro_g1_vp8_dec_run(struct hantro_ctx *ctx) hantro_end_prepare_run(ctx); vdpu_write(vpu, G1_REG_INTERRUPT_DEC_E, G1_REG_INTERRUPT); + + return 0; } diff --git a/drivers/staging/media/hantro/hantro_h1_jpeg_enc.c b/drivers/staging/media/hantro/hantro_h1_jpeg_enc.c index b88dc4ed06db..56cf261a8e95 100644 --- a/drivers/staging/media/hantro/hantro_h1_jpeg_enc.c +++ b/drivers/staging/media/hantro/hantro_h1_jpeg_enc.c @@ -88,7 +88,7 @@ hantro_h1_jpeg_enc_set_qtable(struct hantro_dev *vpu, } } -void hantro_h1_jpeg_enc_run(struct hantro_ctx *ctx) +int hantro_h1_jpeg_enc_run(struct hantro_ctx *ctx) { struct hantro_dev *vpu = ctx->dev; struct vb2_v4l2_buffer *src_buf, *dst_buf; @@ -136,6 +136,8 @@ void hantro_h1_jpeg_enc_run(struct hantro_ctx *ctx) hantro_end_prepare_run(ctx); vepu_write(vpu, reg, H1_REG_ENC_CTRL); + + return 0; } void hantro_jpeg_enc_done(struct hantro_ctx *ctx) diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h index 3d8b53567f16..4b73c8011b25 100644 --- a/drivers/staging/media/hantro/hantro_hw.h +++ b/drivers/staging/media/hantro/hantro_hw.h @@ -133,14 +133,15 @@ struct hantro_postproc_ctx { * Optional and called from process context. * @run: Start single {en,de)coding job. Called from atomic context * to indicate that a pair of buffers is ready and the hardware - * should be programmed and started. + * should be programmed and started. Returns zero if OK, a + * negative value in error cases. * @done: Read back processing results and additional data from hardware. * @reset: Reset the hardware in case of a timeout. */ struct hantro_codec_ops { int (*init)(struct hantro_ctx *ctx); void (*exit)(struct hantro_ctx *ctx); - void (*run)(struct hantro_ctx *ctx); + int (*run)(struct hantro_ctx *ctx); void (*done)(struct hantro_ctx *ctx); void (*reset)(struct hantro_ctx *ctx); }; @@ -180,8 +181,8 @@ void hantro_end_prepare_run(struct hantro_ctx *ctx); irqreturn_t hantro_g1_irq(int irq, void *dev_id); void hantro_g1_reset(struct hantro_ctx *ctx); -void hantro_h1_jpeg_enc_run(struct hantro_ctx *ctx); -void rk3399_vpu_jpeg_enc_run(struct hantro_ctx *ctx); +int hantro_h1_jpeg_enc_run(struct hantro_ctx *ctx); +int rk3399_vpu_jpeg_enc_run(struct hantro_ctx *ctx); int hantro_jpeg_enc_init(struct hantro_ctx *ctx); void hantro_jpeg_enc_exit(struct hantro_ctx *ctx); void hantro_jpeg_enc_done(struct hantro_ctx *ctx); @@ -189,7 +190,7 @@ void hantro_jpeg_enc_done(struct hantro_ctx *ctx); dma_addr_t hantro_h264_get_ref_buf(struct hantro_ctx *ctx, unsigned int dpb_idx); int hantro_h264_dec_prepare_run(struct hantro_ctx *ctx); -void hantro_g1_h264_dec_run(struct hantro_ctx *ctx); +int hantro_g1_h264_dec_run(struct hantro_ctx *ctx); int hantro_h264_dec_init(struct hantro_ctx *ctx); void hantro_h264_dec_exit(struct hantro_ctx *ctx); @@ -220,15 +221,15 @@ hantro_h264_mv_size(unsigned int width, unsigned int height) return 64 * MB_WIDTH(width) * MB_WIDTH(height) + 32; } -void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx); -void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx); +int hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx); +int rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx); void hantro_mpeg2_dec_copy_qtable(u8 *qtable, const struct v4l2_ctrl_mpeg2_quantisation *ctrl); int hantro_mpeg2_dec_init(struct hantro_ctx *ctx); void hantro_mpeg2_dec_exit(struct hantro_ctx *ctx); -void hantro_g1_vp8_dec_run(struct hantro_ctx *ctx); -void rk3399_vpu_vp8_dec_run(struct hantro_ctx *ctx); +int hantro_g1_vp8_dec_run(struct hantro_ctx *ctx); +int rk3399_vpu_vp8_dec_run(struct hantro_ctx *ctx); int hantro_vp8_dec_init(struct hantro_ctx *ctx); void hantro_vp8_dec_exit(struct hantro_ctx *ctx); void hantro_vp8_prob_update(struct hantro_ctx *ctx, diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_jpeg_enc.c b/drivers/staging/media/hantro/rk3399_vpu_hw_jpeg_enc.c index 3498e6124acd..3a27ebef4f38 100644 --- a/drivers/staging/media/hantro/rk3399_vpu_hw_jpeg_enc.c +++ b/drivers/staging/media/hantro/rk3399_vpu_hw_jpeg_enc.c @@ -118,7 +118,7 @@ rk3399_vpu_jpeg_enc_set_qtable(struct hantro_dev *vpu, } } -void rk3399_vpu_jpeg_enc_run(struct hantro_ctx *ctx) +int rk3399_vpu_jpeg_enc_run(struct hantro_ctx *ctx) { struct hantro_dev *vpu = ctx->dev; struct vb2_v4l2_buffer *src_buf, *dst_buf; @@ -168,4 +168,6 @@ void rk3399_vpu_jpeg_enc_run(struct hantro_ctx *ctx) /* Kick the watchdog and start encoding */ hantro_end_prepare_run(ctx); vepu_write(vpu, reg, VEPU_REG_ENCODE_START); + + return 0; } diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c index 2527dce7eb18..683982c24c2d 100644 --- a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c +++ b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c @@ -148,7 +148,7 @@ rk3399_vpu_mpeg2_dec_set_buffers(struct hantro_dev *vpu, vdpu_write_relaxed(vpu, backward_addr, VDPU_REG_REFER3_BASE); } -void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx) +int rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx) { struct hantro_dev *vpu = ctx->dev; struct vb2_v4l2_buffer *src_buf, *dst_buf; @@ -244,4 +244,6 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx) reg = vdpu_read(vpu, VDPU_SWREG(57)) | VDPU_REG_DEC_E(1); vdpu_write(vpu, reg, VDPU_SWREG(57)); + + return 0; } diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_vp8_dec.c b/drivers/staging/media/hantro/rk3399_vpu_hw_vp8_dec.c index 8661a3cc1e6b..e5d20fe5b007 100644 --- a/drivers/staging/media/hantro/rk3399_vpu_hw_vp8_dec.c +++ b/drivers/staging/media/hantro/rk3399_vpu_hw_vp8_dec.c @@ -503,7 +503,7 @@ static void cfg_buffers(struct hantro_ctx *ctx, vdpu_write_relaxed(vpu, dst_dma, VDPU_REG_ADDR_DST); } -void rk3399_vpu_vp8_dec_run(struct hantro_ctx *ctx) +int rk3399_vpu_vp8_dec_run(struct hantro_ctx *ctx) { const struct v4l2_ctrl_vp8_frame *hdr; struct hantro_dev *vpu = ctx->dev; @@ -516,7 +516,7 @@ void rk3399_vpu_vp8_dec_run(struct hantro_ctx *ctx) hdr = hantro_get_ctrl(ctx, V4L2_CID_STATELESS_VP8_FRAME); if (WARN_ON(!hdr)) - return; + return -EINVAL; /* Reset segment_map buffer in keyframe */ if (V4L2_VP8_FRAME_IS_KEY_FRAME(hdr) && ctx->vp8_dec.segment_map.cpu) @@ -589,4 +589,6 @@ void rk3399_vpu_vp8_dec_run(struct hantro_ctx *ctx) hantro_end_prepare_run(ctx); hantro_reg_write(vpu, &vp8_dec_start_dec, 1); + + return 0; } From 8968cfc282955c3f853b34d9ceaaa1ba33943e94 Mon Sep 17 00:00:00 2001 From: Benjamin Gaignard Date: Thu, 3 Jun 2021 13:49:59 +0200 Subject: [PATCH 320/394] media: hantro: Define HEVC codec profiles and supported features Define which HEVC profiles (up to level 5.1) and features (no scaling, no 10 bits) are supported by the driver. Signed-off-by: Benjamin Gaignard Reviewed-by: Ezequiel Garcia Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/hantro/hantro.h | 3 ++ drivers/staging/media/hantro/hantro_drv.c | 58 +++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/drivers/staging/media/hantro/hantro.h b/drivers/staging/media/hantro/hantro.h index 6c1b888abe75..4368c0962768 100644 --- a/drivers/staging/media/hantro/hantro.h +++ b/drivers/staging/media/hantro/hantro.h @@ -34,6 +34,7 @@ struct hantro_codec_ops; #define HANTRO_MPEG2_DECODER BIT(16) #define HANTRO_VP8_DECODER BIT(17) #define HANTRO_H264_DECODER BIT(18) +#define HANTRO_HEVC_DECODER BIT(19) #define HANTRO_DECODERS 0xffff0000 /** @@ -99,6 +100,7 @@ struct hantro_variant { * @HANTRO_MODE_H264_DEC: H264 decoder. * @HANTRO_MODE_MPEG2_DEC: MPEG-2 decoder. * @HANTRO_MODE_VP8_DEC: VP8 decoder. + * @HANTRO_MODE_HEVC_DEC: HEVC decoder. */ enum hantro_codec_mode { HANTRO_MODE_NONE = -1, @@ -106,6 +108,7 @@ enum hantro_codec_mode { HANTRO_MODE_H264_DEC, HANTRO_MODE_MPEG2_DEC, HANTRO_MODE_VP8_DEC, + HANTRO_MODE_HEVC_DEC, }; /* diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c index e255756dfd9e..0e25d377f077 100644 --- a/drivers/staging/media/hantro/hantro_drv.c +++ b/drivers/staging/media/hantro/hantro_drv.c @@ -254,6 +254,18 @@ static int hantro_try_ctrl(struct v4l2_ctrl *ctrl) if (sps->bit_depth_luma_minus8 != 0) /* Only 8-bit is supported */ return -EINVAL; + } else if (ctrl->id == V4L2_CID_MPEG_VIDEO_HEVC_SPS) { + const struct v4l2_ctrl_hevc_sps *sps = ctrl->p_new.p_hevc_sps; + + if (sps->bit_depth_luma_minus8 != sps->bit_depth_chroma_minus8) + /* Luma and chroma bit depth mismatch */ + return -EINVAL; + if (sps->bit_depth_luma_minus8 != 0) + /* Only 8-bit is supported */ + return -EINVAL; + if (sps->flags & V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED) + /* No scaling support */ + return -EINVAL; } return 0; } @@ -365,6 +377,52 @@ static const struct hantro_ctrl controls[] = { .def = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN, } }, { + .codec = HANTRO_HEVC_DECODER, + .cfg = { + .id = V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE, + .min = V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_FRAME_BASED, + .max = V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_FRAME_BASED, + .def = V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_FRAME_BASED, + }, + }, { + .codec = HANTRO_HEVC_DECODER, + .cfg = { + .id = V4L2_CID_MPEG_VIDEO_HEVC_START_CODE, + .min = V4L2_MPEG_VIDEO_HEVC_START_CODE_ANNEX_B, + .max = V4L2_MPEG_VIDEO_HEVC_START_CODE_ANNEX_B, + .def = V4L2_MPEG_VIDEO_HEVC_START_CODE_ANNEX_B, + }, + }, { + .codec = HANTRO_HEVC_DECODER, + .cfg = { + .id = V4L2_CID_MPEG_VIDEO_HEVC_PROFILE, + .min = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN, + .max = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10, + .def = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN, + }, + }, { + .codec = HANTRO_HEVC_DECODER, + .cfg = { + .id = V4L2_CID_MPEG_VIDEO_HEVC_LEVEL, + .min = V4L2_MPEG_VIDEO_HEVC_LEVEL_1, + .max = V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1, + }, + }, { + .codec = HANTRO_HEVC_DECODER, + .cfg = { + .id = V4L2_CID_MPEG_VIDEO_HEVC_SPS, + .ops = &hantro_ctrl_ops, + }, + }, { + .codec = HANTRO_HEVC_DECODER, + .cfg = { + .id = V4L2_CID_MPEG_VIDEO_HEVC_PPS, + }, + }, { + .codec = HANTRO_HEVC_DECODER, + .cfg = { + .id = V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS, + }, }, }; From 31ad15e688e58a94779971f428c414b7a3f882d1 Mon Sep 17 00:00:00 2001 From: Benjamin Gaignard Date: Thu, 3 Jun 2021 13:50:00 +0200 Subject: [PATCH 321/394] media: hantro: Only use postproc when post processed formats are defined If the variant doesn't support postprocessed formats make sure it will be ok. Signed-off-by: Benjamin Gaignard Reviewed-by: Ezequiel Garcia Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/hantro/hantro.h | 8 ++------ drivers/staging/media/hantro/hantro_postproc.c | 14 ++++++++++++++ drivers/staging/media/hantro/hantro_v4l2.c | 4 +++- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/drivers/staging/media/hantro/hantro.h b/drivers/staging/media/hantro/hantro.h index 4368c0962768..e50d39b51902 100644 --- a/drivers/staging/media/hantro/hantro.h +++ b/drivers/staging/media/hantro/hantro.h @@ -413,12 +413,8 @@ hantro_get_dst_buf(struct hantro_ctx *ctx) return v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); } -static inline bool -hantro_needs_postproc(const struct hantro_ctx *ctx, - const struct hantro_fmt *fmt) -{ - return !ctx->is_encoder && fmt->fourcc != V4L2_PIX_FMT_NV12; -} +bool hantro_needs_postproc(const struct hantro_ctx *ctx, + const struct hantro_fmt *fmt); static inline dma_addr_t hantro_get_dec_buf_addr(struct hantro_ctx *ctx, struct vb2_buffer *vb) diff --git a/drivers/staging/media/hantro/hantro_postproc.c b/drivers/staging/media/hantro/hantro_postproc.c index 6d2a8f2a8f0b..ed8916c950a4 100644 --- a/drivers/staging/media/hantro/hantro_postproc.c +++ b/drivers/staging/media/hantro/hantro_postproc.c @@ -50,6 +50,20 @@ const struct hantro_postproc_regs hantro_g1_postproc_regs = { .display_width = {G1_REG_PP_DISPLAY_WIDTH, 0, 0xfff}, }; +bool hantro_needs_postproc(const struct hantro_ctx *ctx, + const struct hantro_fmt *fmt) +{ + struct hantro_dev *vpu = ctx->dev; + + if (ctx->is_encoder) + return false; + + if (!vpu->variant->postproc_fmts) + return false; + + return fmt->fourcc != V4L2_PIX_FMT_NV12; +} + void hantro_postproc_enable(struct hantro_ctx *ctx) { struct hantro_dev *vpu = ctx->dev; diff --git a/drivers/staging/media/hantro/hantro_v4l2.c b/drivers/staging/media/hantro/hantro_v4l2.c index 7ccc6405036a..aca92cebb2af 100644 --- a/drivers/staging/media/hantro/hantro_v4l2.c +++ b/drivers/staging/media/hantro/hantro_v4l2.c @@ -55,7 +55,9 @@ static const struct hantro_fmt * hantro_get_postproc_formats(const struct hantro_ctx *ctx, unsigned int *num_fmts) { - if (ctx->is_encoder) { + struct hantro_dev *vpu = ctx->dev; + + if (ctx->is_encoder || !vpu->variant->postproc_fmts) { *num_fmts = 0; return NULL; } From 35f51f6091bcf2cb90d9ac2f41465c415a34632e Mon Sep 17 00:00:00 2001 From: Benjamin Gaignard Date: Thu, 3 Jun 2021 13:50:01 +0200 Subject: [PATCH 322/394] media: uapi: Add a control for HANTRO driver The HEVC HANTRO driver needs to know the number of bits to skip at the beginning of the slice header. That is a hardware specific requirement so create a dedicated control for this purpose. Signed-off-by: Benjamin Gaignard Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../userspace-api/media/drivers/hantro.rst | 19 +++++++++++++++++++ .../userspace-api/media/drivers/index.rst | 1 + include/media/hevc-ctrls.h | 13 +++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 Documentation/userspace-api/media/drivers/hantro.rst diff --git a/Documentation/userspace-api/media/drivers/hantro.rst b/Documentation/userspace-api/media/drivers/hantro.rst new file mode 100644 index 000000000000..cd9754b4e005 --- /dev/null +++ b/Documentation/userspace-api/media/drivers/hantro.rst @@ -0,0 +1,19 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Hantro video decoder driver +=========================== + +The Hantro video decoder driver implements the following driver-specific controls: + +``V4L2_CID_HANTRO_HEVC_SLICE_HEADER_SKIP (integer)`` + Specifies to Hantro HEVC video decoder driver the number of data (in bits) to + skip in the slice segment header. + If non-IDR, the bits to be skipped go from syntax element "pic_output_flag" + to before syntax element "slice_temporal_mvp_enabled_flag". + If IDR, the skipped bits are just "pic_output_flag" + (separate_colour_plane_flag is not supported). + +.. note:: + + This control is not yet part of the public kernel API and + it is expected to change. diff --git a/Documentation/userspace-api/media/drivers/index.rst b/Documentation/userspace-api/media/drivers/index.rst index 1a9038f5f9fa..12e3c512d718 100644 --- a/Documentation/userspace-api/media/drivers/index.rst +++ b/Documentation/userspace-api/media/drivers/index.rst @@ -33,6 +33,7 @@ For more details see the file COPYING in the source distribution of Linux. ccs cx2341x-uapi + hantro imx-uapi max2175 meye-uapi diff --git a/include/media/hevc-ctrls.h b/include/media/hevc-ctrls.h index 1b702c3230fb..53c0038c792b 100644 --- a/include/media/hevc-ctrls.h +++ b/include/media/hevc-ctrls.h @@ -224,4 +224,17 @@ struct v4l2_ctrl_hevc_decode_params { __u64 flags; }; +/* MPEG-class control IDs specific to the Hantro driver as defined by V4L2 */ +#define V4L2_CID_CODEC_HANTRO_BASE (V4L2_CTRL_CLASS_CODEC | 0x1200) +/* + * V4L2_CID_HANTRO_HEVC_SLICE_HEADER_SKIP - + * the number of data (in bits) to skip in the + * slice segment header. + * If non-IDR, the bits to be skipped go from syntax element "pic_output_flag" + * to before syntax element "slice_temporal_mvp_enabled_flag". + * If IDR, the skipped bits are just "pic_output_flag" + * (separate_colour_plane_flag is not supported). + */ +#define V4L2_CID_HANTRO_HEVC_SLICE_HEADER_SKIP (V4L2_CID_CODEC_HANTRO_BASE + 0) + #endif From b7782b34a76615f8199daf1bce544aa73e35f44d Mon Sep 17 00:00:00 2001 From: Benjamin Gaignard Date: Thu, 3 Jun 2021 13:50:02 +0200 Subject: [PATCH 323/394] media: hantro: handle V4L2_PIX_FMT_HEVC_SLICE control Make sure that V4L2_PIX_FMT_HEVC_SLICE is correctly handled by the driver. Signed-off-by: Benjamin Gaignard Reviewed-by: Ezequiel Garcia Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/hantro/hantro_v4l2.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/media/hantro/hantro_v4l2.c b/drivers/staging/media/hantro/hantro_v4l2.c index aca92cebb2af..bcb0bdff4a9a 100644 --- a/drivers/staging/media/hantro/hantro_v4l2.c +++ b/drivers/staging/media/hantro/hantro_v4l2.c @@ -392,6 +392,7 @@ hantro_update_requires_request(struct hantro_ctx *ctx, u32 fourcc) case V4L2_PIX_FMT_MPEG2_SLICE: case V4L2_PIX_FMT_VP8_FRAME: case V4L2_PIX_FMT_H264_SLICE: + case V4L2_PIX_FMT_HEVC_SLICE: ctx->fh.m2m_ctx->out_q_ctx.q.requires_requests = true; break; default: From cb5dd5a0fa518dff14ff2b90837c3c8f98f4dd5c Mon Sep 17 00:00:00 2001 From: Benjamin Gaignard Date: Thu, 3 Jun 2021 13:50:03 +0200 Subject: [PATCH 324/394] media: hantro: Introduce G2/HEVC decoder Implement all the logic to get G2 hardware decoding HEVC frames. It supports up level 5.1 HEVC stream. It doesn't support yet 10 bits formats or the scaling feature. Add HANTRO HEVC dedicated control to skip some bits at the beginning of the slice header. That is very specific to this hardware so can't go into uapi structures. Computing the needed value is complex and requires information from the stream that only the userland knows so let it provide the correct value to the driver. Signed-off-by: Benjamin Gaignard Co-developed-by: Adrian Ratiu Signed-off-by: Adrian Ratiu Co-developed-by: Ezequiel Garcia Signed-off-by: Ezequiel Garcia Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/hantro/Makefile | 2 + drivers/staging/media/hantro/hantro.h | 2 + drivers/staging/media/hantro/hantro_drv.c | 36 ++ .../staging/media/hantro/hantro_g2_hevc_dec.c | 586 ++++++++++++++++++ drivers/staging/media/hantro/hantro_g2_regs.h | 198 ++++++ drivers/staging/media/hantro/hantro_hevc.c | 333 ++++++++++ drivers/staging/media/hantro/hantro_hw.h | 51 ++ 7 files changed, 1208 insertions(+) create mode 100644 drivers/staging/media/hantro/hantro_g2_hevc_dec.c create mode 100644 drivers/staging/media/hantro/hantro_g2_regs.h create mode 100644 drivers/staging/media/hantro/hantro_hevc.c diff --git a/drivers/staging/media/hantro/Makefile b/drivers/staging/media/hantro/Makefile index f4b99901eeee..23bfc423b23c 100644 --- a/drivers/staging/media/hantro/Makefile +++ b/drivers/staging/media/hantro/Makefile @@ -10,12 +10,14 @@ hantro-vpu-y += \ hantro_g1.o \ hantro_g1_h264_dec.o \ hantro_g1_mpeg2_dec.o \ + hantro_g2_hevc_dec.o \ hantro_g1_vp8_dec.o \ rk3399_vpu_hw_jpeg_enc.o \ rk3399_vpu_hw_mpeg2_dec.o \ rk3399_vpu_hw_vp8_dec.o \ hantro_jpeg.o \ hantro_h264.o \ + hantro_hevc.o \ hantro_mpeg2.o \ hantro_vp8.o diff --git a/drivers/staging/media/hantro/hantro.h b/drivers/staging/media/hantro/hantro.h index e50d39b51902..a70c386de6f1 100644 --- a/drivers/staging/media/hantro/hantro.h +++ b/drivers/staging/media/hantro/hantro.h @@ -221,6 +221,7 @@ struct hantro_dev { * @jpeg_enc: JPEG-encoding context. * @mpeg2_dec: MPEG-2-decoding context. * @vp8_dec: VP8-decoding context. + * @hevc_dec: HEVC-decoding context. */ struct hantro_ctx { struct hantro_dev *dev; @@ -247,6 +248,7 @@ struct hantro_ctx { struct hantro_jpeg_enc_hw_ctx jpeg_enc; struct hantro_mpeg2_dec_hw_ctx mpeg2_dec; struct hantro_vp8_dec_hw_ctx vp8_dec; + struct hantro_hevc_dec_hw_ctx hevc_dec; }; }; diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c index 0e25d377f077..d448cdff59ea 100644 --- a/drivers/staging/media/hantro/hantro_drv.c +++ b/drivers/staging/media/hantro/hantro_drv.c @@ -290,6 +290,26 @@ static int hantro_jpeg_s_ctrl(struct v4l2_ctrl *ctrl) return 0; } +static int hantro_hevc_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct hantro_ctx *ctx; + + ctx = container_of(ctrl->handler, + struct hantro_ctx, ctrl_handler); + + vpu_debug(1, "s_ctrl: id = %d, val = %d\n", ctrl->id, ctrl->val); + + switch (ctrl->id) { + case V4L2_CID_HANTRO_HEVC_SLICE_HEADER_SKIP: + ctx->hevc_dec.ctrls.hevc_hdr_skip_length = ctrl->val; + break; + default: + return -EINVAL; + } + + return 0; +} + static const struct v4l2_ctrl_ops hantro_ctrl_ops = { .try_ctrl = hantro_try_ctrl, }; @@ -298,6 +318,10 @@ static const struct v4l2_ctrl_ops hantro_jpeg_ctrl_ops = { .s_ctrl = hantro_jpeg_s_ctrl, }; +static const struct v4l2_ctrl_ops hantro_hevc_ctrl_ops = { + .s_ctrl = hantro_hevc_s_ctrl, +}; + static const struct hantro_ctrl controls[] = { { .codec = HANTRO_JPEG_ENCODER, @@ -423,6 +447,18 @@ static const struct hantro_ctrl controls[] = { .cfg = { .id = V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS, }, + }, { + .codec = HANTRO_HEVC_DECODER, + .cfg = { + .id = V4L2_CID_HANTRO_HEVC_SLICE_HEADER_SKIP, + .name = "Hantro HEVC slice header skip bytes", + .type = V4L2_CTRL_TYPE_INTEGER, + .min = 0, + .def = 0, + .max = 0x100, + .step = 1, + .ops = &hantro_hevc_ctrl_ops, + }, }, }; diff --git a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c new file mode 100644 index 000000000000..340efb57fd18 --- /dev/null +++ b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c @@ -0,0 +1,586 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Hantro VPU HEVC codec driver + * + * Copyright (C) 2020 Safran Passenger Innovations LLC + */ + +#include "hantro_hw.h" +#include "hantro_g2_regs.h" + +#define HEVC_DEC_MODE 0xC + +#define BUS_WIDTH_32 0 +#define BUS_WIDTH_64 1 +#define BUS_WIDTH_128 2 +#define BUS_WIDTH_256 3 + +static inline void hantro_write_addr(struct hantro_dev *vpu, + unsigned long offset, + dma_addr_t addr) +{ + vdpu_write(vpu, addr & 0xffffffff, offset); +} + +static void prepare_tile_info_buffer(struct hantro_ctx *ctx) +{ + struct hantro_dev *vpu = ctx->dev; + const struct hantro_hevc_dec_ctrls *ctrls = &ctx->hevc_dec.ctrls; + const struct v4l2_ctrl_hevc_pps *pps = ctrls->pps; + const struct v4l2_ctrl_hevc_sps *sps = ctrls->sps; + u16 *p = (u16 *)((u8 *)ctx->hevc_dec.tile_sizes.cpu); + unsigned int num_tile_rows = pps->num_tile_rows_minus1 + 1; + unsigned int num_tile_cols = pps->num_tile_columns_minus1 + 1; + unsigned int pic_width_in_ctbs, pic_height_in_ctbs; + unsigned int max_log2_ctb_size, ctb_size; + bool tiles_enabled, uniform_spacing; + u32 no_chroma = 0; + + tiles_enabled = !!(pps->flags & V4L2_HEVC_PPS_FLAG_TILES_ENABLED); + uniform_spacing = !!(pps->flags & V4L2_HEVC_PPS_FLAG_UNIFORM_SPACING); + + hantro_reg_write(vpu, &g2_tile_e, tiles_enabled); + + max_log2_ctb_size = sps->log2_min_luma_coding_block_size_minus3 + 3 + + sps->log2_diff_max_min_luma_coding_block_size; + pic_width_in_ctbs = (sps->pic_width_in_luma_samples + + (1 << max_log2_ctb_size) - 1) >> max_log2_ctb_size; + pic_height_in_ctbs = (sps->pic_height_in_luma_samples + (1 << max_log2_ctb_size) - 1) + >> max_log2_ctb_size; + ctb_size = 1 << max_log2_ctb_size; + + vpu_debug(1, "Preparing tile sizes buffer for %dx%d CTBs (CTB size %d)\n", + pic_width_in_ctbs, pic_height_in_ctbs, ctb_size); + + if (tiles_enabled) { + unsigned int i, j, h; + + vpu_debug(1, "Tiles enabled! %dx%d\n", num_tile_cols, num_tile_rows); + + hantro_reg_write(vpu, &g2_num_tile_rows, num_tile_rows); + hantro_reg_write(vpu, &g2_num_tile_cols, num_tile_cols); + + /* write width + height for each tile in pic */ + if (!uniform_spacing) { + u32 tmp_w = 0, tmp_h = 0; + + for (i = 0; i < num_tile_rows; i++) { + if (i == num_tile_rows - 1) + h = pic_height_in_ctbs - tmp_h; + else + h = pps->row_height_minus1[i] + 1; + tmp_h += h; + if (i == 0 && h == 1 && ctb_size == 16) + no_chroma = 1; + for (j = 0, tmp_w = 0; j < num_tile_cols - 1; j++) { + tmp_w += pps->column_width_minus1[j] + 1; + *p++ = pps->column_width_minus1[j + 1]; + *p++ = h; + if (i == 0 && h == 1 && ctb_size == 16) + no_chroma = 1; + } + /* last column */ + *p++ = pic_width_in_ctbs - tmp_w; + *p++ = h; + } + } else { /* uniform spacing */ + u32 tmp, prev_h, prev_w; + + for (i = 0, prev_h = 0; i < num_tile_rows; i++) { + tmp = (i + 1) * pic_height_in_ctbs / num_tile_rows; + h = tmp - prev_h; + prev_h = tmp; + if (i == 0 && h == 1 && ctb_size == 16) + no_chroma = 1; + for (j = 0, prev_w = 0; j < num_tile_cols; j++) { + tmp = (j + 1) * pic_width_in_ctbs / num_tile_cols; + *p++ = tmp - prev_w; + *p++ = h; + if (j == 0 && + (pps->column_width_minus1[0] + 1) == 1 && + ctb_size == 16) + no_chroma = 1; + prev_w = tmp; + } + } + } + } else { + hantro_reg_write(vpu, &g2_num_tile_rows, 1); + hantro_reg_write(vpu, &g2_num_tile_cols, 1); + + /* There's one tile, with dimensions equal to pic size. */ + p[0] = pic_width_in_ctbs; + p[1] = pic_height_in_ctbs; + } + + if (no_chroma) + vpu_debug(1, "%s: no chroma!\n", __func__); +} + +static void set_params(struct hantro_ctx *ctx) +{ + const struct hantro_hevc_dec_ctrls *ctrls = &ctx->hevc_dec.ctrls; + const struct v4l2_ctrl_hevc_sps *sps = ctrls->sps; + const struct v4l2_ctrl_hevc_pps *pps = ctrls->pps; + const struct v4l2_ctrl_hevc_decode_params *decode_params = ctrls->decode_params; + struct hantro_dev *vpu = ctx->dev; + u32 min_log2_cb_size, max_log2_ctb_size, min_cb_size, max_ctb_size; + u32 pic_width_in_min_cbs, pic_height_in_min_cbs; + u32 pic_width_aligned, pic_height_aligned; + u32 partial_ctb_x, partial_ctb_y; + + hantro_reg_write(vpu, &g2_bit_depth_y_minus8, sps->bit_depth_luma_minus8); + hantro_reg_write(vpu, &g2_bit_depth_c_minus8, sps->bit_depth_chroma_minus8); + + hantro_reg_write(vpu, &g2_output_8_bits, 0); + + hantro_reg_write(vpu, &g2_hdr_skip_length, ctrls->hevc_hdr_skip_length); + + min_log2_cb_size = sps->log2_min_luma_coding_block_size_minus3 + 3; + max_log2_ctb_size = min_log2_cb_size + sps->log2_diff_max_min_luma_coding_block_size; + + hantro_reg_write(vpu, &g2_min_cb_size, min_log2_cb_size); + hantro_reg_write(vpu, &g2_max_cb_size, max_log2_ctb_size); + + min_cb_size = 1 << min_log2_cb_size; + max_ctb_size = 1 << max_log2_ctb_size; + + pic_width_in_min_cbs = sps->pic_width_in_luma_samples / min_cb_size; + pic_height_in_min_cbs = sps->pic_height_in_luma_samples / min_cb_size; + pic_width_aligned = ALIGN(sps->pic_width_in_luma_samples, max_ctb_size); + pic_height_aligned = ALIGN(sps->pic_height_in_luma_samples, max_ctb_size); + + partial_ctb_x = !!(sps->pic_width_in_luma_samples != pic_width_aligned); + partial_ctb_y = !!(sps->pic_height_in_luma_samples != pic_height_aligned); + + hantro_reg_write(vpu, &g2_partial_ctb_x, partial_ctb_x); + hantro_reg_write(vpu, &g2_partial_ctb_y, partial_ctb_y); + + hantro_reg_write(vpu, &g2_pic_width_in_cbs, pic_width_in_min_cbs); + hantro_reg_write(vpu, &g2_pic_height_in_cbs, pic_height_in_min_cbs); + + hantro_reg_write(vpu, &g2_pic_width_4x4, + (pic_width_in_min_cbs * min_cb_size) / 4); + hantro_reg_write(vpu, &g2_pic_height_4x4, + (pic_height_in_min_cbs * min_cb_size) / 4); + + hantro_reg_write(vpu, &hevc_max_inter_hierdepth, + sps->max_transform_hierarchy_depth_inter); + hantro_reg_write(vpu, &hevc_max_intra_hierdepth, + sps->max_transform_hierarchy_depth_intra); + hantro_reg_write(vpu, &hevc_min_trb_size, + sps->log2_min_luma_transform_block_size_minus2 + 2); + hantro_reg_write(vpu, &hevc_max_trb_size, + sps->log2_min_luma_transform_block_size_minus2 + 2 + + sps->log2_diff_max_min_luma_transform_block_size); + + hantro_reg_write(vpu, &g2_tempor_mvp_e, + !!(sps->flags & V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED) && + !(decode_params->flags & V4L2_HEVC_DECODE_PARAM_FLAG_IDR_PIC)); + hantro_reg_write(vpu, &g2_strong_smooth_e, + !!(sps->flags & V4L2_HEVC_SPS_FLAG_STRONG_INTRA_SMOOTHING_ENABLED)); + hantro_reg_write(vpu, &g2_asym_pred_e, + !!(sps->flags & V4L2_HEVC_SPS_FLAG_AMP_ENABLED)); + hantro_reg_write(vpu, &g2_sao_e, + !!(sps->flags & V4L2_HEVC_SPS_FLAG_SAMPLE_ADAPTIVE_OFFSET)); + hantro_reg_write(vpu, &g2_sign_data_hide, + !!(pps->flags & V4L2_HEVC_PPS_FLAG_SIGN_DATA_HIDING_ENABLED)); + + if (pps->flags & V4L2_HEVC_PPS_FLAG_CU_QP_DELTA_ENABLED) { + hantro_reg_write(vpu, &g2_cu_qpd_e, 1); + hantro_reg_write(vpu, &g2_max_cu_qpd_depth, pps->diff_cu_qp_delta_depth); + } else { + hantro_reg_write(vpu, &g2_cu_qpd_e, 0); + hantro_reg_write(vpu, &g2_max_cu_qpd_depth, 0); + } + + if (pps->flags & V4L2_HEVC_PPS_FLAG_PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT) { + hantro_reg_write(vpu, &g2_cb_qp_offset, pps->pps_cb_qp_offset); + hantro_reg_write(vpu, &g2_cr_qp_offset, pps->pps_cr_qp_offset); + } else { + hantro_reg_write(vpu, &g2_cb_qp_offset, 0); + hantro_reg_write(vpu, &g2_cr_qp_offset, 0); + } + + hantro_reg_write(vpu, &g2_filt_offset_beta, pps->pps_beta_offset_div2); + hantro_reg_write(vpu, &g2_filt_offset_tc, pps->pps_tc_offset_div2); + hantro_reg_write(vpu, &g2_slice_hdr_ext_e, + !!(pps->flags & V4L2_HEVC_PPS_FLAG_SLICE_SEGMENT_HEADER_EXTENSION_PRESENT)); + hantro_reg_write(vpu, &g2_slice_hdr_ext_bits, pps->num_extra_slice_header_bits); + hantro_reg_write(vpu, &g2_slice_chqp_present, + !!(pps->flags & V4L2_HEVC_PPS_FLAG_PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT)); + hantro_reg_write(vpu, &g2_weight_bipr_idc, + !!(pps->flags & V4L2_HEVC_PPS_FLAG_WEIGHTED_BIPRED)); + hantro_reg_write(vpu, &g2_transq_bypass, + !!(pps->flags & V4L2_HEVC_PPS_FLAG_TRANSQUANT_BYPASS_ENABLED)); + hantro_reg_write(vpu, &g2_list_mod_e, + !!(pps->flags & V4L2_HEVC_PPS_FLAG_LISTS_MODIFICATION_PRESENT)); + hantro_reg_write(vpu, &g2_entropy_sync_e, + !!(pps->flags & V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED)); + hantro_reg_write(vpu, &g2_cabac_init_present, + !!(pps->flags & V4L2_HEVC_PPS_FLAG_CABAC_INIT_PRESENT)); + hantro_reg_write(vpu, &g2_idr_pic_e, + !!(decode_params->flags & V4L2_HEVC_DECODE_PARAM_FLAG_IRAP_PIC)); + hantro_reg_write(vpu, &hevc_parallel_merge, + pps->log2_parallel_merge_level_minus2 + 2); + hantro_reg_write(vpu, &g2_pcm_filt_d, + !!(sps->flags & V4L2_HEVC_SPS_FLAG_PCM_LOOP_FILTER_DISABLED)); + hantro_reg_write(vpu, &g2_pcm_e, + !!(sps->flags & V4L2_HEVC_SPS_FLAG_PCM_ENABLED)); + if (sps->flags & V4L2_HEVC_SPS_FLAG_PCM_ENABLED) { + hantro_reg_write(vpu, &g2_max_pcm_size, + sps->log2_diff_max_min_pcm_luma_coding_block_size + + sps->log2_min_pcm_luma_coding_block_size_minus3 + 3); + hantro_reg_write(vpu, &g2_min_pcm_size, + sps->log2_min_pcm_luma_coding_block_size_minus3 + 3); + hantro_reg_write(vpu, &g2_bit_depth_pcm_y, + sps->pcm_sample_bit_depth_luma_minus1 + 1); + hantro_reg_write(vpu, &g2_bit_depth_pcm_c, + sps->pcm_sample_bit_depth_chroma_minus1 + 1); + } else { + hantro_reg_write(vpu, &g2_max_pcm_size, 0); + hantro_reg_write(vpu, &g2_min_pcm_size, 0); + hantro_reg_write(vpu, &g2_bit_depth_pcm_y, 0); + hantro_reg_write(vpu, &g2_bit_depth_pcm_c, 0); + } + + hantro_reg_write(vpu, &g2_start_code_e, 1); + hantro_reg_write(vpu, &g2_init_qp, pps->init_qp_minus26 + 26); + hantro_reg_write(vpu, &g2_weight_pred_e, + !!(pps->flags & V4L2_HEVC_PPS_FLAG_WEIGHTED_PRED)); + hantro_reg_write(vpu, &g2_cabac_init_present, + !!(pps->flags & V4L2_HEVC_PPS_FLAG_CABAC_INIT_PRESENT)); + hantro_reg_write(vpu, &g2_const_intra_e, + !!(pps->flags & V4L2_HEVC_PPS_FLAG_CONSTRAINED_INTRA_PRED)); + hantro_reg_write(vpu, &g2_transform_skip, + !!(pps->flags & V4L2_HEVC_PPS_FLAG_TRANSFORM_SKIP_ENABLED)); + hantro_reg_write(vpu, &g2_out_filtering_dis, + !!(pps->flags & V4L2_HEVC_PPS_FLAG_PPS_DISABLE_DEBLOCKING_FILTER)); + hantro_reg_write(vpu, &g2_filt_ctrl_pres, + !!(pps->flags & V4L2_HEVC_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT)); + hantro_reg_write(vpu, &g2_dependent_slice, + !!(pps->flags & V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT_ENABLED)); + hantro_reg_write(vpu, &g2_filter_override, + !!(pps->flags & V4L2_HEVC_PPS_FLAG_DEBLOCKING_FILTER_OVERRIDE_ENABLED)); + hantro_reg_write(vpu, &g2_refidx0_active, + pps->num_ref_idx_l0_default_active_minus1 + 1); + hantro_reg_write(vpu, &g2_refidx1_active, + pps->num_ref_idx_l1_default_active_minus1 + 1); + hantro_reg_write(vpu, &g2_apf_threshold, 8); +} + +static int find_ref_pic_index(const struct v4l2_hevc_dpb_entry *dpb, int pic_order_cnt) +{ + int i; + + for (i = 0; i < V4L2_HEVC_DPB_ENTRIES_NUM_MAX; i++) { + if (dpb[i].pic_order_cnt[0] == pic_order_cnt) + return i; + } + + return 0x0; +} + +static void set_ref_pic_list(struct hantro_ctx *ctx) +{ + const struct hantro_hevc_dec_ctrls *ctrls = &ctx->hevc_dec.ctrls; + struct hantro_dev *vpu = ctx->dev; + const struct v4l2_ctrl_hevc_decode_params *decode_params = ctrls->decode_params; + const struct v4l2_hevc_dpb_entry *dpb = decode_params->dpb; + u32 list0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX] = {}; + u32 list1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX] = {}; + static const struct hantro_reg ref_pic_regs0[] = { + hevc_rlist_f0, + hevc_rlist_f1, + hevc_rlist_f2, + hevc_rlist_f3, + hevc_rlist_f4, + hevc_rlist_f5, + hevc_rlist_f6, + hevc_rlist_f7, + hevc_rlist_f8, + hevc_rlist_f9, + hevc_rlist_f10, + hevc_rlist_f11, + hevc_rlist_f12, + hevc_rlist_f13, + hevc_rlist_f14, + hevc_rlist_f15, + }; + static const struct hantro_reg ref_pic_regs1[] = { + hevc_rlist_b0, + hevc_rlist_b1, + hevc_rlist_b2, + hevc_rlist_b3, + hevc_rlist_b4, + hevc_rlist_b5, + hevc_rlist_b6, + hevc_rlist_b7, + hevc_rlist_b8, + hevc_rlist_b9, + hevc_rlist_b10, + hevc_rlist_b11, + hevc_rlist_b12, + hevc_rlist_b13, + hevc_rlist_b14, + hevc_rlist_b15, + }; + unsigned int i, j; + + /* List 0 contains: short term before, short term after and long term */ + j = 0; + for (i = 0; i < decode_params->num_poc_st_curr_before && j < ARRAY_SIZE(list0); i++) + list0[j++] = find_ref_pic_index(dpb, decode_params->poc_st_curr_before[i]); + for (i = 0; i < decode_params->num_poc_st_curr_after && j < ARRAY_SIZE(list0); i++) + list0[j++] = find_ref_pic_index(dpb, decode_params->poc_st_curr_after[i]); + for (i = 0; i < decode_params->num_poc_lt_curr && j < ARRAY_SIZE(list0); i++) + list0[j++] = find_ref_pic_index(dpb, decode_params->poc_lt_curr[i]); + + /* Fill the list, copying over and over */ + i = 0; + while (j < ARRAY_SIZE(list0)) + list0[j++] = list0[i++]; + + j = 0; + for (i = 0; i < decode_params->num_poc_st_curr_after && j < ARRAY_SIZE(list1); i++) + list1[j++] = find_ref_pic_index(dpb, decode_params->poc_st_curr_after[i]); + for (i = 0; i < decode_params->num_poc_st_curr_before && j < ARRAY_SIZE(list1); i++) + list1[j++] = find_ref_pic_index(dpb, decode_params->poc_st_curr_before[i]); + for (i = 0; i < decode_params->num_poc_lt_curr && j < ARRAY_SIZE(list1); i++) + list1[j++] = find_ref_pic_index(dpb, decode_params->poc_lt_curr[i]); + + i = 0; + while (j < ARRAY_SIZE(list1)) + list1[j++] = list1[i++]; + + for (i = 0; i < V4L2_HEVC_DPB_ENTRIES_NUM_MAX; i++) { + hantro_reg_write(vpu, &ref_pic_regs0[i], list0[i]); + hantro_reg_write(vpu, &ref_pic_regs1[i], list1[i]); + } +} + +static int set_ref(struct hantro_ctx *ctx) +{ + const struct hantro_hevc_dec_ctrls *ctrls = &ctx->hevc_dec.ctrls; + const struct v4l2_ctrl_hevc_sps *sps = ctrls->sps; + const struct v4l2_ctrl_hevc_pps *pps = ctrls->pps; + const struct v4l2_ctrl_hevc_decode_params *decode_params = ctrls->decode_params; + const struct v4l2_hevc_dpb_entry *dpb = decode_params->dpb; + dma_addr_t luma_addr, chroma_addr, mv_addr = 0; + struct hantro_dev *vpu = ctx->dev; + size_t cr_offset = hantro_hevc_chroma_offset(sps); + size_t mv_offset = hantro_hevc_motion_vectors_offset(sps); + u32 max_ref_frames; + u16 dpb_longterm_e; + static const struct hantro_reg cur_poc[] = { + hevc_cur_poc_00, + hevc_cur_poc_01, + hevc_cur_poc_02, + hevc_cur_poc_03, + hevc_cur_poc_04, + hevc_cur_poc_05, + hevc_cur_poc_06, + hevc_cur_poc_07, + hevc_cur_poc_08, + hevc_cur_poc_09, + hevc_cur_poc_10, + hevc_cur_poc_11, + hevc_cur_poc_12, + hevc_cur_poc_13, + hevc_cur_poc_14, + hevc_cur_poc_15, + }; + unsigned int i; + + max_ref_frames = decode_params->num_poc_lt_curr + + decode_params->num_poc_st_curr_before + + decode_params->num_poc_st_curr_after; + /* + * Set max_ref_frames to non-zero to avoid HW hang when decoding + * badly marked I-frames. + */ + max_ref_frames = max_ref_frames ? max_ref_frames : 1; + hantro_reg_write(vpu, &g2_num_ref_frames, max_ref_frames); + hantro_reg_write(vpu, &g2_filter_over_slices, + !!(pps->flags & V4L2_HEVC_PPS_FLAG_PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED)); + hantro_reg_write(vpu, &g2_filter_over_tiles, + !!(pps->flags & V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED)); + + /* + * Write POC count diff from current pic. For frame decoding only compute + * pic_order_cnt[0] and ignore pic_order_cnt[1] used in field-coding. + */ + for (i = 0; i < decode_params->num_active_dpb_entries && i < ARRAY_SIZE(cur_poc); i++) { + char poc_diff = decode_params->pic_order_cnt_val - dpb[i].pic_order_cnt[0]; + + hantro_reg_write(vpu, &cur_poc[i], poc_diff); + } + + if (i < ARRAY_SIZE(cur_poc)) { + /* + * After the references, fill one entry pointing to itself, + * i.e. difference is zero. + */ + hantro_reg_write(vpu, &cur_poc[i], 0); + i++; + } + + /* Fill the rest with the current picture */ + for (; i < ARRAY_SIZE(cur_poc); i++) + hantro_reg_write(vpu, &cur_poc[i], decode_params->pic_order_cnt_val); + + set_ref_pic_list(ctx); + + /* We will only keep the references picture that are still used */ + ctx->hevc_dec.ref_bufs_used = 0; + + /* Set up addresses of DPB buffers */ + dpb_longterm_e = 0; + for (i = 0; i < decode_params->num_active_dpb_entries && + i < (V4L2_HEVC_DPB_ENTRIES_NUM_MAX - 1); i++) { + luma_addr = hantro_hevc_get_ref_buf(ctx, dpb[i].pic_order_cnt[0]); + if (!luma_addr) + return -ENOMEM; + + chroma_addr = luma_addr + cr_offset; + mv_addr = luma_addr + mv_offset; + + if (dpb[i].rps == V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR) + dpb_longterm_e |= BIT(V4L2_HEVC_DPB_ENTRIES_NUM_MAX - 1 - i); + + hantro_write_addr(vpu, G2_REG_ADDR_REF(i), luma_addr); + hantro_write_addr(vpu, G2_REG_CHR_REF(i), chroma_addr); + hantro_write_addr(vpu, G2_REG_DMV_REF(i), mv_addr); + } + + luma_addr = hantro_hevc_get_ref_buf(ctx, decode_params->pic_order_cnt_val); + if (!luma_addr) + return -ENOMEM; + + chroma_addr = luma_addr + cr_offset; + mv_addr = luma_addr + mv_offset; + + hantro_write_addr(vpu, G2_REG_ADDR_REF(i), luma_addr); + hantro_write_addr(vpu, G2_REG_CHR_REF(i), chroma_addr); + hantro_write_addr(vpu, G2_REG_DMV_REF(i++), mv_addr); + + hantro_write_addr(vpu, G2_ADDR_DST, luma_addr); + hantro_write_addr(vpu, G2_ADDR_DST_CHR, chroma_addr); + hantro_write_addr(vpu, G2_ADDR_DST_MV, mv_addr); + + hantro_hevc_ref_remove_unused(ctx); + + for (; i < V4L2_HEVC_DPB_ENTRIES_NUM_MAX; i++) { + hantro_write_addr(vpu, G2_REG_ADDR_REF(i), 0); + hantro_write_addr(vpu, G2_REG_CHR_REF(i), 0); + hantro_write_addr(vpu, G2_REG_DMV_REF(i), 0); + } + + hantro_reg_write(vpu, &g2_refer_lterm_e, dpb_longterm_e); + + return 0; +} + +static void set_buffers(struct hantro_ctx *ctx) +{ + struct vb2_v4l2_buffer *src_buf, *dst_buf; + struct hantro_dev *vpu = ctx->dev; + const struct hantro_hevc_dec_ctrls *ctrls = &ctx->hevc_dec.ctrls; + const struct v4l2_ctrl_hevc_sps *sps = ctrls->sps; + size_t cr_offset = hantro_hevc_chroma_offset(sps); + dma_addr_t src_dma, dst_dma; + u32 src_len, src_buf_len; + + src_buf = hantro_get_src_buf(ctx); + dst_buf = hantro_get_dst_buf(ctx); + + /* Source (stream) buffer. */ + src_dma = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0); + src_len = vb2_get_plane_payload(&src_buf->vb2_buf, 0); + src_buf_len = vb2_plane_size(&src_buf->vb2_buf, 0); + + hantro_write_addr(vpu, G2_ADDR_STR, src_dma); + hantro_reg_write(vpu, &g2_stream_len, src_len); + hantro_reg_write(vpu, &g2_strm_buffer_len, src_buf_len); + hantro_reg_write(vpu, &g2_strm_start_offset, 0); + hantro_reg_write(vpu, &g2_write_mvs_e, 1); + + /* Destination (decoded frame) buffer. */ + dst_dma = hantro_get_dec_buf_addr(ctx, &dst_buf->vb2_buf); + + hantro_write_addr(vpu, G2_RASTER_SCAN, dst_dma); + hantro_write_addr(vpu, G2_RASTER_SCAN_CHR, dst_dma + cr_offset); + hantro_write_addr(vpu, G2_ADDR_TILE_SIZE, ctx->hevc_dec.tile_sizes.dma); + hantro_write_addr(vpu, G2_TILE_FILTER, ctx->hevc_dec.tile_filter.dma); + hantro_write_addr(vpu, G2_TILE_SAO, ctx->hevc_dec.tile_sao.dma); + hantro_write_addr(vpu, G2_TILE_BSD, ctx->hevc_dec.tile_bsd.dma); +} + +static void hantro_g2_check_idle(struct hantro_dev *vpu) +{ + int i; + + for (i = 0; i < 3; i++) { + u32 status; + + /* Make sure the VPU is idle */ + status = vdpu_read(vpu, G2_REG_INTERRUPT); + if (status & G2_REG_INTERRUPT_DEC_E) { + dev_warn(vpu->dev, "device still running, aborting"); + status |= G2_REG_INTERRUPT_DEC_ABORT_E | G2_REG_INTERRUPT_DEC_IRQ_DIS; + vdpu_write(vpu, status, G2_REG_INTERRUPT); + } + } +} + +int hantro_g2_hevc_dec_run(struct hantro_ctx *ctx) +{ + struct hantro_dev *vpu = ctx->dev; + int ret; + + hantro_g2_check_idle(vpu); + + /* Prepare HEVC decoder context. */ + ret = hantro_hevc_dec_prepare_run(ctx); + if (ret) + return ret; + + /* Configure hardware registers. */ + set_params(ctx); + + /* set reference pictures */ + ret = set_ref(ctx); + if (ret) + return ret; + + set_buffers(ctx); + prepare_tile_info_buffer(ctx); + + hantro_end_prepare_run(ctx); + + hantro_reg_write(vpu, &g2_mode, HEVC_DEC_MODE); + hantro_reg_write(vpu, &g2_clk_gate_e, 1); + + /* Don't disable output */ + hantro_reg_write(vpu, &g2_out_dis, 0); + + /* Don't compress buffers */ + hantro_reg_write(vpu, &g2_ref_compress_bypass, 1); + + /* use NV12 as output format */ + hantro_reg_write(vpu, &g2_out_rs_e, 1); + + /* Bus width and max burst */ + hantro_reg_write(vpu, &g2_buswidth, BUS_WIDTH_128); + hantro_reg_write(vpu, &g2_max_burst, 16); + + /* Swap */ + hantro_reg_write(vpu, &g2_strm_swap, 0xf); + hantro_reg_write(vpu, &g2_dirmv_swap, 0xf); + hantro_reg_write(vpu, &g2_compress_swap, 0xf); + + /* Start decoding! */ + vdpu_write(vpu, G2_REG_INTERRUPT_DEC_E, G2_REG_INTERRUPT); + + return 0; +} diff --git a/drivers/staging/media/hantro/hantro_g2_regs.h b/drivers/staging/media/hantro/hantro_g2_regs.h new file mode 100644 index 000000000000..bb22fa921914 --- /dev/null +++ b/drivers/staging/media/hantro/hantro_g2_regs.h @@ -0,0 +1,198 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2021, Collabora + * + * Author: Benjamin Gaignard + */ + +#ifndef HANTRO_G2_REGS_H_ +#define HANTRO_G2_REGS_H_ + +#include "hantro.h" + +#define G2_SWREG(nr) ((nr) * 4) + +#define G2_DEC_REG(b, s, m) \ + ((const struct hantro_reg) { \ + .base = G2_SWREG(b), \ + .shift = s, \ + .mask = m, \ + }) + +#define G2_REG_VERSION G2_SWREG(0) + +#define G2_REG_INTERRUPT G2_SWREG(1) +#define G2_REG_INTERRUPT_DEC_RDY_INT BIT(12) +#define G2_REG_INTERRUPT_DEC_ABORT_E BIT(5) +#define G2_REG_INTERRUPT_DEC_IRQ_DIS BIT(4) +#define G2_REG_INTERRUPT_DEC_E BIT(0) + +#define g2_strm_swap G2_DEC_REG(2, 28, 0xf) +#define g2_dirmv_swap G2_DEC_REG(2, 20, 0xf) + +#define g2_mode G2_DEC_REG(3, 27, 0x1f) +#define g2_compress_swap G2_DEC_REG(3, 20, 0xf) +#define g2_ref_compress_bypass G2_DEC_REG(3, 17, 0x1) +#define g2_out_rs_e G2_DEC_REG(3, 16, 0x1) +#define g2_out_dis G2_DEC_REG(3, 15, 0x1) +#define g2_out_filtering_dis G2_DEC_REG(3, 14, 0x1) +#define g2_write_mvs_e G2_DEC_REG(3, 12, 0x1) + +#define g2_pic_width_in_cbs G2_DEC_REG(4, 19, 0x1fff) +#define g2_pic_height_in_cbs G2_DEC_REG(4, 6, 0x1fff) +#define g2_num_ref_frames G2_DEC_REG(4, 0, 0x1f) + +#define g2_scaling_list_e G2_DEC_REG(5, 24, 0x1) +#define g2_cb_qp_offset G2_DEC_REG(5, 19, 0x1f) +#define g2_cr_qp_offset G2_DEC_REG(5, 14, 0x1f) +#define g2_sign_data_hide G2_DEC_REG(5, 12, 0x1) +#define g2_tempor_mvp_e G2_DEC_REG(5, 11, 0x1) +#define g2_max_cu_qpd_depth G2_DEC_REG(5, 5, 0x3f) +#define g2_cu_qpd_e G2_DEC_REG(5, 4, 0x1) + +#define g2_stream_len G2_DEC_REG(6, 0, 0xffffffff) + +#define g2_cabac_init_present G2_DEC_REG(7, 31, 0x1) +#define g2_weight_pred_e G2_DEC_REG(7, 28, 0x1) +#define g2_weight_bipr_idc G2_DEC_REG(7, 26, 0x3) +#define g2_filter_over_slices G2_DEC_REG(7, 25, 0x1) +#define g2_filter_over_tiles G2_DEC_REG(7, 24, 0x1) +#define g2_asym_pred_e G2_DEC_REG(7, 23, 0x1) +#define g2_sao_e G2_DEC_REG(7, 22, 0x1) +#define g2_pcm_filt_d G2_DEC_REG(7, 21, 0x1) +#define g2_slice_chqp_present G2_DEC_REG(7, 20, 0x1) +#define g2_dependent_slice G2_DEC_REG(7, 19, 0x1) +#define g2_filter_override G2_DEC_REG(7, 18, 0x1) +#define g2_strong_smooth_e G2_DEC_REG(7, 17, 0x1) +#define g2_filt_offset_beta G2_DEC_REG(7, 12, 0x1f) +#define g2_filt_offset_tc G2_DEC_REG(7, 7, 0x1f) +#define g2_slice_hdr_ext_e G2_DEC_REG(7, 6, 0x1) +#define g2_slice_hdr_ext_bits G2_DEC_REG(7, 3, 0x7) + +#define g2_const_intra_e G2_DEC_REG(8, 31, 0x1) +#define g2_filt_ctrl_pres G2_DEC_REG(8, 30, 0x1) +#define g2_idr_pic_e G2_DEC_REG(8, 16, 0x1) +#define g2_bit_depth_pcm_y G2_DEC_REG(8, 12, 0xf) +#define g2_bit_depth_pcm_c G2_DEC_REG(8, 8, 0xf) +#define g2_bit_depth_y_minus8 G2_DEC_REG(8, 6, 0x3) +#define g2_bit_depth_c_minus8 G2_DEC_REG(8, 4, 0x3) +#define g2_output_8_bits G2_DEC_REG(8, 3, 0x1) + +#define g2_refidx1_active G2_DEC_REG(9, 19, 0x1f) +#define g2_refidx0_active G2_DEC_REG(9, 14, 0x1f) +#define g2_hdr_skip_length G2_DEC_REG(9, 0, 0x3fff) + +#define g2_start_code_e G2_DEC_REG(10, 31, 0x1) +#define g2_init_qp G2_DEC_REG(10, 24, 0x3f) +#define g2_num_tile_cols G2_DEC_REG(10, 19, 0x1f) +#define g2_num_tile_rows G2_DEC_REG(10, 14, 0x1f) +#define g2_tile_e G2_DEC_REG(10, 1, 0x1) +#define g2_entropy_sync_e G2_DEC_REG(10, 0, 0x1) + +#define g2_refer_lterm_e G2_DEC_REG(12, 16, 0xffff) +#define g2_min_cb_size G2_DEC_REG(12, 13, 0x7) +#define g2_max_cb_size G2_DEC_REG(12, 10, 0x7) +#define g2_min_pcm_size G2_DEC_REG(12, 7, 0x7) +#define g2_max_pcm_size G2_DEC_REG(12, 4, 0x7) +#define g2_pcm_e G2_DEC_REG(12, 3, 0x1) +#define g2_transform_skip G2_DEC_REG(12, 2, 0x1) +#define g2_transq_bypass G2_DEC_REG(12, 1, 0x1) +#define g2_list_mod_e G2_DEC_REG(12, 0, 0x1) + +#define hevc_min_trb_size G2_DEC_REG(13, 13, 0x7) +#define hevc_max_trb_size G2_DEC_REG(13, 10, 0x7) +#define hevc_max_intra_hierdepth G2_DEC_REG(13, 7, 0x7) +#define hevc_max_inter_hierdepth G2_DEC_REG(13, 4, 0x7) +#define hevc_parallel_merge G2_DEC_REG(13, 0, 0xf) + +#define hevc_rlist_f0 G2_DEC_REG(14, 0, 0x1f) +#define hevc_rlist_f1 G2_DEC_REG(14, 10, 0x1f) +#define hevc_rlist_f2 G2_DEC_REG(14, 20, 0x1f) +#define hevc_rlist_b0 G2_DEC_REG(14, 5, 0x1f) +#define hevc_rlist_b1 G2_DEC_REG(14, 15, 0x1f) +#define hevc_rlist_b2 G2_DEC_REG(14, 25, 0x1f) + +#define hevc_rlist_f3 G2_DEC_REG(15, 0, 0x1f) +#define hevc_rlist_f4 G2_DEC_REG(15, 10, 0x1f) +#define hevc_rlist_f5 G2_DEC_REG(15, 20, 0x1f) +#define hevc_rlist_b3 G2_DEC_REG(15, 5, 0x1f) +#define hevc_rlist_b4 G2_DEC_REG(15, 15, 0x1f) +#define hevc_rlist_b5 G2_DEC_REG(15, 25, 0x1f) + +#define hevc_rlist_f6 G2_DEC_REG(16, 0, 0x1f) +#define hevc_rlist_f7 G2_DEC_REG(16, 10, 0x1f) +#define hevc_rlist_f8 G2_DEC_REG(16, 20, 0x1f) +#define hevc_rlist_b6 G2_DEC_REG(16, 5, 0x1f) +#define hevc_rlist_b7 G2_DEC_REG(16, 15, 0x1f) +#define hevc_rlist_b8 G2_DEC_REG(16, 25, 0x1f) + +#define hevc_rlist_f9 G2_DEC_REG(17, 0, 0x1f) +#define hevc_rlist_f10 G2_DEC_REG(17, 10, 0x1f) +#define hevc_rlist_f11 G2_DEC_REG(17, 20, 0x1f) +#define hevc_rlist_b9 G2_DEC_REG(17, 5, 0x1f) +#define hevc_rlist_b10 G2_DEC_REG(17, 15, 0x1f) +#define hevc_rlist_b11 G2_DEC_REG(17, 25, 0x1f) + +#define hevc_rlist_f12 G2_DEC_REG(18, 0, 0x1f) +#define hevc_rlist_f13 G2_DEC_REG(18, 10, 0x1f) +#define hevc_rlist_f14 G2_DEC_REG(18, 20, 0x1f) +#define hevc_rlist_b12 G2_DEC_REG(18, 5, 0x1f) +#define hevc_rlist_b13 G2_DEC_REG(18, 15, 0x1f) +#define hevc_rlist_b14 G2_DEC_REG(18, 25, 0x1f) + +#define hevc_rlist_f15 G2_DEC_REG(19, 0, 0x1f) +#define hevc_rlist_b15 G2_DEC_REG(19, 5, 0x1f) + +#define g2_partial_ctb_x G2_DEC_REG(20, 31, 0x1) +#define g2_partial_ctb_y G2_DEC_REG(20, 30, 0x1) +#define g2_pic_width_4x4 G2_DEC_REG(20, 16, 0xfff) +#define g2_pic_height_4x4 G2_DEC_REG(20, 0, 0xfff) +#define hevc_cur_poc_00 G2_DEC_REG(46, 24, 0xff) +#define hevc_cur_poc_01 G2_DEC_REG(46, 16, 0xff) +#define hevc_cur_poc_02 G2_DEC_REG(46, 8, 0xff) +#define hevc_cur_poc_03 G2_DEC_REG(46, 0, 0xff) + +#define hevc_cur_poc_04 G2_DEC_REG(47, 24, 0xff) +#define hevc_cur_poc_05 G2_DEC_REG(47, 16, 0xff) +#define hevc_cur_poc_06 G2_DEC_REG(47, 8, 0xff) +#define hevc_cur_poc_07 G2_DEC_REG(47, 0, 0xff) + +#define hevc_cur_poc_08 G2_DEC_REG(48, 24, 0xff) +#define hevc_cur_poc_09 G2_DEC_REG(48, 16, 0xff) +#define hevc_cur_poc_10 G2_DEC_REG(48, 8, 0xff) +#define hevc_cur_poc_11 G2_DEC_REG(48, 0, 0xff) + +#define hevc_cur_poc_12 G2_DEC_REG(49, 24, 0xff) +#define hevc_cur_poc_13 G2_DEC_REG(49, 16, 0xff) +#define hevc_cur_poc_14 G2_DEC_REG(49, 8, 0xff) +#define hevc_cur_poc_15 G2_DEC_REG(49, 0, 0xff) + +#define g2_apf_threshold G2_DEC_REG(55, 0, 0xffff) + +#define g2_clk_gate_e G2_DEC_REG(58, 16, 0x1) +#define g2_buswidth G2_DEC_REG(58, 8, 0x7) +#define g2_max_burst G2_DEC_REG(58, 0, 0xff) + +#define G2_REG_CONFIG G2_SWREG(58) +#define G2_REG_CONFIG_DEC_CLK_GATE_E BIT(16) +#define G2_REG_CONFIG_DEC_CLK_GATE_IDLE_E BIT(17) + +#define G2_ADDR_DST (G2_SWREG(65)) +#define G2_REG_ADDR_REF(i) (G2_SWREG(67) + ((i) * 0x8)) +#define G2_ADDR_DST_CHR (G2_SWREG(99)) +#define G2_REG_CHR_REF(i) (G2_SWREG(101) + ((i) * 0x8)) +#define G2_ADDR_DST_MV (G2_SWREG(133)) +#define G2_REG_DMV_REF(i) (G2_SWREG(135) + ((i) * 0x8)) +#define G2_ADDR_TILE_SIZE (G2_SWREG(167)) +#define G2_ADDR_STR (G2_SWREG(169)) +#define HEVC_SCALING_LIST (G2_SWREG(171)) +#define G2_RASTER_SCAN (G2_SWREG(175)) +#define G2_RASTER_SCAN_CHR (G2_SWREG(177)) +#define G2_TILE_FILTER (G2_SWREG(179)) +#define G2_TILE_SAO (G2_SWREG(181)) +#define G2_TILE_BSD (G2_SWREG(183)) + +#define g2_strm_buffer_len G2_DEC_REG(258, 0, 0xffffffff) +#define g2_strm_start_offset G2_DEC_REG(259, 0, 0xffffffff) + +#endif diff --git a/drivers/staging/media/hantro/hantro_hevc.c b/drivers/staging/media/hantro/hantro_hevc.c new file mode 100644 index 000000000000..5347f5a41c2a --- /dev/null +++ b/drivers/staging/media/hantro/hantro_hevc.c @@ -0,0 +1,333 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Hantro VPU HEVC codec driver + * + * Copyright (C) 2020 Safran Passenger Innovations LLC + */ + +#include +#include + +#include "hantro.h" +#include "hantro_hw.h" + +#define VERT_FILTER_RAM_SIZE 8 /* bytes per pixel row */ +/* + * BSD control data of current picture at tile border + * 128 bits per 4x4 tile = 128/(8*4) bytes per row + */ +#define BSD_CTRL_RAM_SIZE 4 /* bytes per pixel row */ +/* tile border coefficients of filter */ +#define VERT_SAO_RAM_SIZE 48 /* bytes per pixel */ + +#define MAX_TILE_COLS 20 +#define MAX_TILE_ROWS 22 + +#define UNUSED_REF -1 + +#define G2_ALIGN 16 + +size_t hantro_hevc_chroma_offset(const struct v4l2_ctrl_hevc_sps *sps) +{ + int bytes_per_pixel = sps->bit_depth_luma_minus8 == 0 ? 1 : 2; + + return sps->pic_width_in_luma_samples * + sps->pic_height_in_luma_samples * bytes_per_pixel; +} + +size_t hantro_hevc_motion_vectors_offset(const struct v4l2_ctrl_hevc_sps *sps) +{ + size_t cr_offset = hantro_hevc_chroma_offset(sps); + + return ALIGN((cr_offset * 3) / 2, G2_ALIGN); +} + +static size_t hantro_hevc_mv_size(const struct v4l2_ctrl_hevc_sps *sps) +{ + u32 min_cb_log2_size_y = sps->log2_min_luma_coding_block_size_minus3 + 3; + u32 ctb_log2_size_y = min_cb_log2_size_y + sps->log2_diff_max_min_luma_coding_block_size; + u32 pic_width_in_ctbs_y = (sps->pic_width_in_luma_samples + (1 << ctb_log2_size_y) - 1) + >> ctb_log2_size_y; + u32 pic_height_in_ctbs_y = (sps->pic_height_in_luma_samples + (1 << ctb_log2_size_y) - 1) + >> ctb_log2_size_y; + size_t mv_size; + + mv_size = pic_width_in_ctbs_y * pic_height_in_ctbs_y * + (1 << (2 * (ctb_log2_size_y - 4))) * 16; + + vpu_debug(4, "%dx%d (CTBs) %zu MV bytes\n", + pic_width_in_ctbs_y, pic_height_in_ctbs_y, mv_size); + + return mv_size; +} + +static size_t hantro_hevc_ref_size(struct hantro_ctx *ctx) +{ + const struct hantro_hevc_dec_ctrls *ctrls = &ctx->hevc_dec.ctrls; + const struct v4l2_ctrl_hevc_sps *sps = ctrls->sps; + + return hantro_hevc_motion_vectors_offset(sps) + hantro_hevc_mv_size(sps); +} + +static void hantro_hevc_ref_free(struct hantro_ctx *ctx) +{ + struct hantro_hevc_dec_hw_ctx *hevc_dec = &ctx->hevc_dec; + struct hantro_dev *vpu = ctx->dev; + int i; + + for (i = 0; i < NUM_REF_PICTURES; i++) { + if (hevc_dec->ref_bufs[i].cpu) + dma_free_coherent(vpu->dev, hevc_dec->ref_bufs[i].size, + hevc_dec->ref_bufs[i].cpu, + hevc_dec->ref_bufs[i].dma); + } +} + +static void hantro_hevc_ref_init(struct hantro_ctx *ctx) +{ + struct hantro_hevc_dec_hw_ctx *hevc_dec = &ctx->hevc_dec; + int i; + + for (i = 0; i < NUM_REF_PICTURES; i++) + hevc_dec->ref_bufs_poc[i] = UNUSED_REF; +} + +dma_addr_t hantro_hevc_get_ref_buf(struct hantro_ctx *ctx, + int poc) +{ + struct hantro_hevc_dec_hw_ctx *hevc_dec = &ctx->hevc_dec; + int i; + + /* Find the reference buffer in already know ones */ + for (i = 0; i < NUM_REF_PICTURES; i++) { + if (hevc_dec->ref_bufs_poc[i] == poc) { + hevc_dec->ref_bufs_used |= 1 << i; + return hevc_dec->ref_bufs[i].dma; + } + } + + /* Allocate a new reference buffer */ + for (i = 0; i < NUM_REF_PICTURES; i++) { + if (hevc_dec->ref_bufs_poc[i] == UNUSED_REF) { + if (!hevc_dec->ref_bufs[i].cpu) { + struct hantro_dev *vpu = ctx->dev; + + /* + * Allocate the space needed for the raw data + + * motion vector data. Optimizations could be to + * allocate raw data in non coherent memory and only + * clear the motion vector data. + */ + hevc_dec->ref_bufs[i].cpu = + dma_alloc_coherent(vpu->dev, + hantro_hevc_ref_size(ctx), + &hevc_dec->ref_bufs[i].dma, + GFP_KERNEL); + if (!hevc_dec->ref_bufs[i].cpu) + return 0; + + hevc_dec->ref_bufs[i].size = hantro_hevc_ref_size(ctx); + } + hevc_dec->ref_bufs_used |= 1 << i; + memset(hevc_dec->ref_bufs[i].cpu, 0, hantro_hevc_ref_size(ctx)); + hevc_dec->ref_bufs_poc[i] = poc; + + return hevc_dec->ref_bufs[i].dma; + } + } + + return 0; +} + +void hantro_hevc_ref_remove_unused(struct hantro_ctx *ctx) +{ + struct hantro_hevc_dec_hw_ctx *hevc_dec = &ctx->hevc_dec; + int i; + + /* Just tag buffer as unused, do not free them */ + for (i = 0; i < NUM_REF_PICTURES; i++) { + if (hevc_dec->ref_bufs_poc[i] == UNUSED_REF) + continue; + + if (hevc_dec->ref_bufs_used & (1 << i)) + continue; + + hevc_dec->ref_bufs_poc[i] = UNUSED_REF; + } +} + +static int tile_buffer_reallocate(struct hantro_ctx *ctx) +{ + struct hantro_dev *vpu = ctx->dev; + struct hantro_hevc_dec_hw_ctx *hevc_dec = &ctx->hevc_dec; + const struct hantro_hevc_dec_ctrls *ctrls = &ctx->hevc_dec.ctrls; + const struct v4l2_ctrl_hevc_pps *pps = ctrls->pps; + const struct v4l2_ctrl_hevc_sps *sps = ctrls->sps; + unsigned int num_tile_cols = pps->num_tile_columns_minus1 + 1; + unsigned int height64 = (sps->pic_height_in_luma_samples + 63) & ~63; + unsigned int size; + + if (num_tile_cols <= 1 || + num_tile_cols <= hevc_dec->num_tile_cols_allocated) + return 0; + + /* Need to reallocate due to tiles passed via PPS */ + if (hevc_dec->tile_filter.cpu) { + dma_free_coherent(vpu->dev, hevc_dec->tile_filter.size, + hevc_dec->tile_filter.cpu, + hevc_dec->tile_filter.dma); + hevc_dec->tile_filter.cpu = NULL; + } + + if (hevc_dec->tile_sao.cpu) { + dma_free_coherent(vpu->dev, hevc_dec->tile_sao.size, + hevc_dec->tile_sao.cpu, + hevc_dec->tile_sao.dma); + hevc_dec->tile_sao.cpu = NULL; + } + + if (hevc_dec->tile_bsd.cpu) { + dma_free_coherent(vpu->dev, hevc_dec->tile_bsd.size, + hevc_dec->tile_bsd.cpu, + hevc_dec->tile_bsd.dma); + hevc_dec->tile_bsd.cpu = NULL; + } + + size = VERT_FILTER_RAM_SIZE * height64 * (num_tile_cols - 1); + hevc_dec->tile_filter.cpu = dma_alloc_coherent(vpu->dev, size, + &hevc_dec->tile_filter.dma, + GFP_KERNEL); + if (!hevc_dec->tile_filter.cpu) + goto err_free_tile_buffers; + hevc_dec->tile_filter.size = size; + + size = VERT_SAO_RAM_SIZE * height64 * (num_tile_cols - 1); + hevc_dec->tile_sao.cpu = dma_alloc_coherent(vpu->dev, size, + &hevc_dec->tile_sao.dma, + GFP_KERNEL); + if (!hevc_dec->tile_sao.cpu) + goto err_free_tile_buffers; + hevc_dec->tile_sao.size = size; + + size = BSD_CTRL_RAM_SIZE * height64 * (num_tile_cols - 1); + hevc_dec->tile_bsd.cpu = dma_alloc_coherent(vpu->dev, size, + &hevc_dec->tile_bsd.dma, + GFP_KERNEL); + if (!hevc_dec->tile_bsd.cpu) + goto err_free_tile_buffers; + hevc_dec->tile_bsd.size = size; + + hevc_dec->num_tile_cols_allocated = num_tile_cols; + + return 0; + +err_free_tile_buffers: + if (hevc_dec->tile_filter.cpu) + dma_free_coherent(vpu->dev, hevc_dec->tile_filter.size, + hevc_dec->tile_filter.cpu, + hevc_dec->tile_filter.dma); + hevc_dec->tile_filter.cpu = NULL; + + if (hevc_dec->tile_sao.cpu) + dma_free_coherent(vpu->dev, hevc_dec->tile_sao.size, + hevc_dec->tile_sao.cpu, + hevc_dec->tile_sao.dma); + hevc_dec->tile_sao.cpu = NULL; + + if (hevc_dec->tile_bsd.cpu) + dma_free_coherent(vpu->dev, hevc_dec->tile_bsd.size, + hevc_dec->tile_bsd.cpu, + hevc_dec->tile_bsd.dma); + hevc_dec->tile_bsd.cpu = NULL; + + return -ENOMEM; +} + +int hantro_hevc_dec_prepare_run(struct hantro_ctx *ctx) +{ + struct hantro_hevc_dec_hw_ctx *hevc_ctx = &ctx->hevc_dec; + struct hantro_hevc_dec_ctrls *ctrls = &hevc_ctx->ctrls; + int ret; + + hantro_start_prepare_run(ctx); + + ctrls->decode_params = + hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS); + if (WARN_ON(!ctrls->decode_params)) + return -EINVAL; + + ctrls->sps = + hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_HEVC_SPS); + if (WARN_ON(!ctrls->sps)) + return -EINVAL; + + ctrls->pps = + hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_HEVC_PPS); + if (WARN_ON(!ctrls->pps)) + return -EINVAL; + + ret = tile_buffer_reallocate(ctx); + if (ret) + return ret; + + return 0; +} + +void hantro_hevc_dec_exit(struct hantro_ctx *ctx) +{ + struct hantro_dev *vpu = ctx->dev; + struct hantro_hevc_dec_hw_ctx *hevc_dec = &ctx->hevc_dec; + + if (hevc_dec->tile_sizes.cpu) + dma_free_coherent(vpu->dev, hevc_dec->tile_sizes.size, + hevc_dec->tile_sizes.cpu, + hevc_dec->tile_sizes.dma); + hevc_dec->tile_sizes.cpu = NULL; + + if (hevc_dec->tile_filter.cpu) + dma_free_coherent(vpu->dev, hevc_dec->tile_filter.size, + hevc_dec->tile_filter.cpu, + hevc_dec->tile_filter.dma); + hevc_dec->tile_filter.cpu = NULL; + + if (hevc_dec->tile_sao.cpu) + dma_free_coherent(vpu->dev, hevc_dec->tile_sao.size, + hevc_dec->tile_sao.cpu, + hevc_dec->tile_sao.dma); + hevc_dec->tile_sao.cpu = NULL; + + if (hevc_dec->tile_bsd.cpu) + dma_free_coherent(vpu->dev, hevc_dec->tile_bsd.size, + hevc_dec->tile_bsd.cpu, + hevc_dec->tile_bsd.dma); + hevc_dec->tile_bsd.cpu = NULL; + + hantro_hevc_ref_free(ctx); +} + +int hantro_hevc_dec_init(struct hantro_ctx *ctx) +{ + struct hantro_dev *vpu = ctx->dev; + struct hantro_hevc_dec_hw_ctx *hevc_dec = &ctx->hevc_dec; + unsigned int size; + + memset(hevc_dec, 0, sizeof(*hevc_dec)); + + /* + * Maximum number of tiles times width and height (2 bytes each), + * rounding up to next 16 bytes boundary + one extra 16 byte + * chunk (HW guys wanted to have this). + */ + size = round_up(MAX_TILE_COLS * MAX_TILE_ROWS * 4 * sizeof(u16) + 16, 16); + hevc_dec->tile_sizes.cpu = dma_alloc_coherent(vpu->dev, size, + &hevc_dec->tile_sizes.dma, + GFP_KERNEL); + if (!hevc_dec->tile_sizes.cpu) + return -ENOMEM; + + hevc_dec->tile_sizes.size = size; + + hantro_hevc_ref_init(ctx); + + return 0; +} diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h index 4b73c8011b25..a4aef5fa03ba 100644 --- a/drivers/staging/media/hantro/hantro_hw.h +++ b/drivers/staging/media/hantro/hantro_hw.h @@ -20,6 +20,8 @@ #define MB_WIDTH(w) DIV_ROUND_UP(w, MB_DIM) #define MB_HEIGHT(h) DIV_ROUND_UP(h, MB_DIM) +#define NUM_REF_PICTURES (V4L2_HEVC_DPB_ENTRIES_NUM_MAX + 1) + struct hantro_dev; struct hantro_ctx; struct hantro_buf; @@ -95,6 +97,46 @@ struct hantro_h264_dec_hw_ctx { struct hantro_h264_dec_ctrls ctrls; }; +/** + * struct hantro_hevc_dec_ctrls + * @decode_params: Decode params + * @sps: SPS info + * @pps: PPS info + * @hevc_hdr_skip_length: the number of data (in bits) to skip in the + * slice segment header syntax after 'slice type' + * token + */ +struct hantro_hevc_dec_ctrls { + const struct v4l2_ctrl_hevc_decode_params *decode_params; + const struct v4l2_ctrl_hevc_sps *sps; + const struct v4l2_ctrl_hevc_pps *pps; + u32 hevc_hdr_skip_length; +}; + +/** + * struct hantro_hevc_dec_hw_ctx + * @tile_sizes: Tile sizes buffer + * @tile_filter: Tile vertical filter buffer + * @tile_sao: Tile SAO buffer + * @tile_bsd: Tile BSD control buffer + * @ref_bufs: Internal reference buffers + * @ref_bufs_poc: Internal reference buffers picture order count + * @ref_bufs_used: Bitfield of used reference buffers + * @ctrls: V4L2 controls attached to a run + * @num_tile_cols_allocated: number of allocated tiles + */ +struct hantro_hevc_dec_hw_ctx { + struct hantro_aux_buf tile_sizes; + struct hantro_aux_buf tile_filter; + struct hantro_aux_buf tile_sao; + struct hantro_aux_buf tile_bsd; + struct hantro_aux_buf ref_bufs[NUM_REF_PICTURES]; + int ref_bufs_poc[NUM_REF_PICTURES]; + u32 ref_bufs_used; + struct hantro_hevc_dec_ctrls ctrls; + unsigned int num_tile_cols_allocated; +}; + /** * struct hantro_mpeg2_dec_hw_ctx * @@ -194,6 +236,15 @@ int hantro_g1_h264_dec_run(struct hantro_ctx *ctx); int hantro_h264_dec_init(struct hantro_ctx *ctx); void hantro_h264_dec_exit(struct hantro_ctx *ctx); +int hantro_hevc_dec_init(struct hantro_ctx *ctx); +void hantro_hevc_dec_exit(struct hantro_ctx *ctx); +int hantro_g2_hevc_dec_run(struct hantro_ctx *ctx); +int hantro_hevc_dec_prepare_run(struct hantro_ctx *ctx); +dma_addr_t hantro_hevc_get_ref_buf(struct hantro_ctx *ctx, int poc); +void hantro_hevc_ref_remove_unused(struct hantro_ctx *ctx); +size_t hantro_hevc_chroma_offset(const struct v4l2_ctrl_hevc_sps *sps); +size_t hantro_hevc_motion_vectors_offset(const struct v4l2_ctrl_hevc_sps *sps); + static inline size_t hantro_h264_mv_size(unsigned int width, unsigned int height) { From 45040f675041956ad763f9ef139ecee3647aa8bb Mon Sep 17 00:00:00 2001 From: Benjamin Gaignard Date: Thu, 3 Jun 2021 13:50:04 +0200 Subject: [PATCH 325/394] media: hantro: IMX8M: add variant for G2/HEVC codec Add variant to IMX8M to enable G2/HEVC codec. Define the capabilities for the hardware up to 3840x2160. G2 doesn't have a postprocessor, uses the same clocks and has it own interrupt. Signed-off-by: Benjamin Gaignard Reviewed-by: Philipp Zabel Reviewed-by: Ezequiel Garcia Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/hantro/hantro_drv.c | 1 + drivers/staging/media/hantro/hantro_hw.h | 1 + drivers/staging/media/hantro/imx8m_vpu_hw.c | 96 ++++++++++++++++++++- 3 files changed, 96 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c index d448cdff59ea..dbc69ee0b562 100644 --- a/drivers/staging/media/hantro/hantro_drv.c +++ b/drivers/staging/media/hantro/hantro_drv.c @@ -588,6 +588,7 @@ static const struct of_device_id of_hantro_match[] = { #endif #ifdef CONFIG_VIDEO_HANTRO_IMX8M { .compatible = "nxp,imx8mq-vpu", .data = &imx8mq_vpu_variant, }, + { .compatible = "nxp,imx8mq-vpu-g2", .data = &imx8mq_vpu_g2_variant }, #endif #ifdef CONFIG_VIDEO_HANTRO_SAMA5D4 { .compatible = "microchip,sama5d4-vdec", .data = &sama5d4_vdec_variant, }, diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h index a4aef5fa03ba..5737a7707944 100644 --- a/drivers/staging/media/hantro/hantro_hw.h +++ b/drivers/staging/media/hantro/hantro_hw.h @@ -208,6 +208,7 @@ extern const struct hantro_variant rk3328_vpu_variant; extern const struct hantro_variant rk3288_vpu_variant; extern const struct hantro_variant imx8mq_vpu_variant; extern const struct hantro_variant sama5d4_vdec_variant; +extern const struct hantro_variant imx8mq_vpu_g2_variant; extern const struct hantro_postproc_regs hantro_g1_postproc_regs; diff --git a/drivers/staging/media/hantro/imx8m_vpu_hw.c b/drivers/staging/media/hantro/imx8m_vpu_hw.c index 9eb556460e52..ea919bfb9891 100644 --- a/drivers/staging/media/hantro/imx8m_vpu_hw.c +++ b/drivers/staging/media/hantro/imx8m_vpu_hw.c @@ -9,6 +9,9 @@ #include #include "hantro.h" +#include "hantro_jpeg.h" +#include "hantro_g1_regs.h" +#include "hantro_g2_regs.h" #define CTRL_SOFT_RESET 0x00 #define RESET_G1 BIT(1) @@ -128,6 +131,62 @@ static const struct hantro_fmt imx8m_vpu_dec_fmts[] = { }, }; +static const struct hantro_fmt imx8m_vpu_g2_dec_fmts[] = { + { + .fourcc = V4L2_PIX_FMT_NV12, + .codec_mode = HANTRO_MODE_NONE, + }, + { + .fourcc = V4L2_PIX_FMT_HEVC_SLICE, + .codec_mode = HANTRO_MODE_HEVC_DEC, + .max_depth = 2, + .frmsize = { + .min_width = 48, + .max_width = 3840, + .step_width = MB_DIM, + .min_height = 48, + .max_height = 2160, + .step_height = MB_DIM, + }, + }, +}; + +static irqreturn_t imx8m_vpu_g1_irq(int irq, void *dev_id) +{ + struct hantro_dev *vpu = dev_id; + enum vb2_buffer_state state; + u32 status; + + status = vdpu_read(vpu, G1_REG_INTERRUPT); + state = (status & G1_REG_INTERRUPT_DEC_RDY_INT) ? + VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR; + + vdpu_write(vpu, 0, G1_REG_INTERRUPT); + vdpu_write(vpu, G1_REG_CONFIG_DEC_CLK_GATE_E, G1_REG_CONFIG); + + hantro_irq_done(vpu, state); + + return IRQ_HANDLED; +} + +static irqreturn_t imx8m_vpu_g2_irq(int irq, void *dev_id) +{ + struct hantro_dev *vpu = dev_id; + enum vb2_buffer_state state; + u32 status; + + status = vdpu_read(vpu, G2_REG_INTERRUPT); + state = (status & G2_REG_INTERRUPT_DEC_RDY_INT) ? + VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR; + + vdpu_write(vpu, 0, G2_REG_INTERRUPT); + vdpu_write(vpu, G2_REG_CONFIG_DEC_CLK_GATE_E, G2_REG_CONFIG); + + hantro_irq_done(vpu, state); + + return IRQ_HANDLED; +} + static int imx8mq_vpu_hw_init(struct hantro_dev *vpu) { vpu->ctrl_base = vpu->reg_bases[vpu->variant->num_regs - 1]; @@ -142,6 +201,13 @@ static void imx8m_vpu_g1_reset(struct hantro_ctx *ctx) imx8m_soft_reset(vpu, RESET_G1); } +static void imx8m_vpu_g2_reset(struct hantro_ctx *ctx) +{ + struct hantro_dev *vpu = ctx->dev; + + imx8m_soft_reset(vpu, RESET_G2); +} + /* * Supported codec ops. */ @@ -167,13 +233,25 @@ static const struct hantro_codec_ops imx8mq_vpu_codec_ops[] = { }, }; +static const struct hantro_codec_ops imx8mq_vpu_g2_codec_ops[] = { + [HANTRO_MODE_HEVC_DEC] = { + .run = hantro_g2_hevc_dec_run, + .reset = imx8m_vpu_g2_reset, + .init = hantro_hevc_dec_init, + .exit = hantro_hevc_dec_exit, + }, +}; + /* * VPU variants. */ static const struct hantro_irq imx8mq_irqs[] = { - { "g1", hantro_g1_irq }, - { "g2", NULL /* TODO: imx8m_vpu_g2_irq */ }, + { "g1", imx8m_vpu_g1_irq }, +}; + +static const struct hantro_irq imx8mq_g2_irqs[] = { + { "g2", imx8m_vpu_g2_irq }, }; static const char * const imx8mq_clk_names[] = { "g1", "g2", "bus" }; @@ -197,3 +275,17 @@ const struct hantro_variant imx8mq_vpu_variant = { .reg_names = imx8mq_reg_names, .num_regs = ARRAY_SIZE(imx8mq_reg_names) }; + +const struct hantro_variant imx8mq_vpu_g2_variant = { + .dec_offset = 0x0, + .dec_fmts = imx8m_vpu_g2_dec_fmts, + .num_dec_fmts = ARRAY_SIZE(imx8m_vpu_g2_dec_fmts), + .codec = HANTRO_HEVC_DECODER, + .codec_ops = imx8mq_vpu_g2_codec_ops, + .init = imx8mq_vpu_hw_init, + .runtime_resume = imx8mq_runtime_resume, + .irqs = imx8mq_g2_irqs, + .num_irqs = ARRAY_SIZE(imx8mq_g2_irqs), + .clk_names = imx8mq_clk_names, + .num_clocks = ARRAY_SIZE(imx8mq_clk_names), +}; From 3d42c93e5fc9e67e0023b7242097f1c1c2cead01 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 9 Jun 2021 14:43:16 +0200 Subject: [PATCH 326/394] media: dmxdev: change the check for problems allocing secfeed While the logic there is right, it tricks static check analyzers, like smatch: drivers/media/dvb-core/dmxdev.c:729 dvb_dmxdev_filter_start() error: we previously assumed '*secfeed' could be null (see line 719) Because the implementation of the filter itself is made via a callback, with its real implementation at the dvbdmx_allocate_section_feed() inside dvb_demux.c. So, change the check logic to make it clear that the function will not try to use *secfeed == NULL. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dmxdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c index f14a872d1268..5d5a48475a54 100644 --- a/drivers/media/dvb-core/dmxdev.c +++ b/drivers/media/dvb-core/dmxdev.c @@ -720,7 +720,7 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter) ret = dmxdev->demux->allocate_section_feed(dmxdev->demux, secfeed, dvb_dmxdev_section_callback); - if (ret < 0) { + if (!*secfeed) { pr_err("DVB (%s): could not alloc feed\n", __func__); return ret; From 4c6e0976295add7f0ed94d276c04a3d6f1ea8f83 Mon Sep 17 00:00:00 2001 From: Benjamin Drung Date: Sat, 5 Jun 2021 22:15:36 +0200 Subject: [PATCH 327/394] media: uvcvideo: Fix pixel format change for Elgato Cam Link 4K The Elgato Cam Link 4K HDMI video capture card reports to support three different pixel formats, where the first format depends on the connected HDMI device. ``` $ v4l2-ctl -d /dev/video0 --list-formats-ext ioctl: VIDIOC_ENUM_FMT Type: Video Capture [0]: 'NV12' (Y/CbCr 4:2:0) Size: Discrete 3840x2160 Interval: Discrete 0.033s (29.970 fps) [1]: 'NV12' (Y/CbCr 4:2:0) Size: Discrete 3840x2160 Interval: Discrete 0.033s (29.970 fps) [2]: 'YU12' (Planar YUV 4:2:0) Size: Discrete 3840x2160 Interval: Discrete 0.033s (29.970 fps) ``` Changing the pixel format to anything besides the first pixel format does not work: ``` $ v4l2-ctl -d /dev/video0 --try-fmt-video pixelformat=YU12 Format Video Capture: Width/Height : 3840/2160 Pixel Format : 'NV12' (Y/CbCr 4:2:0) Field : None Bytes per Line : 3840 Size Image : 12441600 Colorspace : sRGB Transfer Function : Rec. 709 YCbCr/HSV Encoding: Rec. 709 Quantization : Default (maps to Limited Range) Flags : ``` User space applications like VLC might show an error message on the terminal in that case: ``` libv4l2: error set_fmt gave us a different result than try_fmt! ``` Depending on the error handling of the user space applications, they might display a distorted video, because they use the wrong pixel format for decoding the stream. The Elgato Cam Link 4K responds to the USB video probe VS_PROBE_CONTROL/VS_COMMIT_CONTROL with a malformed data structure: The second byte contains bFormatIndex (instead of being the second byte of bmHint). The first byte is always zero. The third byte is always 1. The firmware bug was reported to Elgato on 2020-12-01 and it was forwarded by the support team to the developers as feature request. There is no firmware update available since then. The latest firmware for Elgato Cam Link 4K as of 2021-03-23 has MCU 20.02.19 and FPGA 67. Therefore correct the malformed data structure for this device. The change was successfully tested with VLC, OBS, and Chromium using different pixel formats (YUYV, NV12, YU12), resolutions (3840x2160, 1920x1080), and frame rates (29.970 and 59.940 fps). Cc: stable@vger.kernel.org Signed-off-by: Benjamin Drung Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/uvc/uvc_video.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c index a777b389a66e..e16464606b14 100644 --- a/drivers/media/usb/uvc/uvc_video.c +++ b/drivers/media/usb/uvc/uvc_video.c @@ -127,10 +127,37 @@ int uvc_query_ctrl(struct uvc_device *dev, u8 query, u8 unit, static void uvc_fixup_video_ctrl(struct uvc_streaming *stream, struct uvc_streaming_control *ctrl) { + static const struct usb_device_id elgato_cam_link_4k = { + USB_DEVICE(0x0fd9, 0x0066) + }; struct uvc_format *format = NULL; struct uvc_frame *frame = NULL; unsigned int i; + /* + * The response of the Elgato Cam Link 4K is incorrect: The second byte + * contains bFormatIndex (instead of being the second byte of bmHint). + * The first byte is always zero. The third byte is always 1. + * + * The UVC 1.5 class specification defines the first five bits in the + * bmHint bitfield. The remaining bits are reserved and should be zero. + * Therefore a valid bmHint will be less than 32. + * + * Latest Elgato Cam Link 4K firmware as of 2021-03-23 needs this fix. + * MCU: 20.02.19, FPGA: 67 + */ + if (usb_match_one_id(stream->dev->intf, &elgato_cam_link_4k) && + ctrl->bmHint > 255) { + u8 corrected_format_index = ctrl->bmHint >> 8; + + uvc_dbg(stream->dev, VIDEO, + "Correct USB video probe response from {bmHint: 0x%04x, bFormatIndex: %u} to {bmHint: 0x%04x, bFormatIndex: %u}\n", + ctrl->bmHint, ctrl->bFormatIndex, + 1, corrected_format_index); + ctrl->bmHint = 1; + ctrl->bFormatIndex = corrected_format_index; + } + for (i = 0; i < stream->nformats; ++i) { if (stream->format[i].index == ctrl->bFormatIndex) { format = &stream->format[i]; From 703ac06a88f07f1fdde795d00c0296750e2b8e4c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 5 Jun 2021 14:00:54 +0200 Subject: [PATCH 328/394] media: docs: */media/index.rst: don't use ReST doc:`foo` The :doc:`foo` tag is auto-generated via automarkup.py. So, use the filename at the sources, instead of :doc:`foo`. Signed-off-by: Mauro Carvalho Chehab --- Documentation/admin-guide/media/index.rst | 12 +++++++----- Documentation/driver-api/media/index.rst | 10 ++++++---- Documentation/userspace-api/media/index.rst | 12 +++++++----- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/Documentation/admin-guide/media/index.rst b/Documentation/admin-guide/media/index.rst index 6e0d2bae7154..c676af665111 100644 --- a/Documentation/admin-guide/media/index.rst +++ b/Documentation/admin-guide/media/index.rst @@ -11,12 +11,14 @@ its supported drivers. Please see: -- :doc:`/userspace-api/media/index` - for the userspace APIs used on media devices. +Documentation/userspace-api/media/index.rst -- :doc:`/driver-api/media/index` - for driver development information and Kernel APIs used by - media devices; + - for the userspace APIs used on media devices. + +Documentation/driver-api/media/index.rst + + - for driver development information and Kernel APIs used by + media devices; The media subsystem =================== diff --git a/Documentation/driver-api/media/index.rst b/Documentation/driver-api/media/index.rst index 2ad71dfa8828..813d7db59da7 100644 --- a/Documentation/driver-api/media/index.rst +++ b/Documentation/driver-api/media/index.rst @@ -11,11 +11,13 @@ its supported drivers. Please see: -- :doc:`/admin-guide/media/index` - for usage information about media subsystem and supported drivers; +Documentation/admin-guide/media/index.rst -- :doc:`/userspace-api/media/index` - for the userspace APIs used on media devices. + - for usage information about media subsystem and supported drivers; + +Documentation/userspace-api/media/index.rst + + - for the userspace APIs used on media devices. .. only:: html diff --git a/Documentation/userspace-api/media/index.rst b/Documentation/userspace-api/media/index.rst index 7f42f83b9f59..d839904be085 100644 --- a/Documentation/userspace-api/media/index.rst +++ b/Documentation/userspace-api/media/index.rst @@ -11,12 +11,14 @@ used by media devices. Please see: -- :doc:`/admin-guide/media/index` - for usage information about media subsystem and supported drivers; +Documentation/admin-guide/media/index.rst -- :doc:`/driver-api/media/index` - for driver development information and Kernel APIs used by - media devices; + - for usage information about media subsystem and supported drivers; + +Documentation/driver-api/media/index.rst + + - for driver development information and Kernel APIs used by + media devices; .. only:: html From d759cd46b9f15180321b6f246a6e0964d4510aef Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 5 Jun 2021 14:40:12 +0200 Subject: [PATCH 329/394] media: userspace-api: avoid using ReST :doc:`foo` markup The :doc:`foo` tag is auto-generated via automarkup.py. So, use the filename at the sources, instead of :doc:`foo`. Signed-off-by: Mauro Carvalho Chehab --- Documentation/userspace-api/media/glossary.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/userspace-api/media/glossary.rst b/Documentation/userspace-api/media/glossary.rst index cb165d7176b7..96a360edbf3b 100644 --- a/Documentation/userspace-api/media/glossary.rst +++ b/Documentation/userspace-api/media/glossary.rst @@ -116,7 +116,7 @@ Glossary - :term:`RC API`; and - :term:`V4L2 API`. - See :doc:`index`. + See Documentation/userspace-api/media/index.rst. MC API **Media Controller API** From a169c44e58190bbdaf9c8d345cd445eec2c2b010 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 5 Jun 2021 14:40:12 +0200 Subject: [PATCH 330/394] media: driver-api: drivers: avoid using ReST :doc:`foo` markup The :doc:`foo` tag is auto-generated via automarkup.py. So, use the filename at the sources, instead of :doc:`foo`. Signed-off-by: Mauro Carvalho Chehab --- Documentation/driver-api/media/drivers/bttv-devel.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/driver-api/media/drivers/bttv-devel.rst b/Documentation/driver-api/media/drivers/bttv-devel.rst index c9aa8b95a5e5..0885a04563a9 100644 --- a/Documentation/driver-api/media/drivers/bttv-devel.rst +++ b/Documentation/driver-api/media/drivers/bttv-devel.rst @@ -21,7 +21,7 @@ log, telling which card type is used. Like this one:: You should verify this is correct. If it isn't, you have to pass the correct board type as insmod argument, ``insmod bttv card=2`` for -example. The file :doc:`/admin-guide/media/bttv-cardlist` has a list +example. The file Documentation/admin-guide/media/bttv-cardlist.rst has a list of valid arguments for card. If your card isn't listed there, you might check the source code for From 6ef43d273e8562366035d8086008e4000a270fd8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 5 Jun 2021 14:40:12 +0200 Subject: [PATCH 331/394] media: admin-guide: avoid using ReST :doc:`foo` markup The :doc:`foo` tag is auto-generated via automarkup.py. So, use the filename at the sources, instead of :doc:`foo`. Signed-off-by: Mauro Carvalho Chehab --- Documentation/admin-guide/media/bt8xx.rst | 15 ++++++++------- Documentation/admin-guide/media/bttv.rst | 21 +++++++++++---------- Documentation/admin-guide/media/saa7134.rst | 3 ++- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/Documentation/admin-guide/media/bt8xx.rst b/Documentation/admin-guide/media/bt8xx.rst index 1382ada1e38e..3589f6ab7e46 100644 --- a/Documentation/admin-guide/media/bt8xx.rst +++ b/Documentation/admin-guide/media/bt8xx.rst @@ -15,11 +15,12 @@ Authors: General information ------------------- -This class of cards has a bt878a as the PCI interface, and require the bttv driver -for accessing the i2c bus and the gpio pins of the bt8xx chipset. +This class of cards has a bt878a as the PCI interface, and require the bttv +driver for accessing the i2c bus and the gpio pins of the bt8xx chipset. -Please see :doc:`bttv-cardlist` for a complete list of Cards based on the -Conexant Bt8xx PCI bridge supported by the Linux Kernel. +Please see Documentation/admin-guide/media/bttv-cardlist.rst for a complete +list of Cards based on the Conexant Bt8xx PCI bridge supported by the +Linux Kernel. In order to be able to compile the kernel, some config options should be enabled:: @@ -80,7 +81,7 @@ for dvb-bt8xx drivers by passing modprobe parameters may be necessary. Running TwinHan and Clones ~~~~~~~~~~~~~~~~~~~~~~~~~~ -As shown at :doc:`bttv-cardlist`, TwinHan and +As shown at Documentation/admin-guide/media/bttv-cardlist.rst, TwinHan and clones use ``card=113`` modprobe parameter. So, in order to properly detect it for devices without EEPROM, you should use:: @@ -105,12 +106,12 @@ The autodetected values are determined by the cards' "response string". In your logs see f. ex.: dst_get_device_id: Recognize [DSTMCI]. For bug reports please send in a complete log with verbose=4 activated. -Please also see :doc:`ci`. +Please also see Documentation/admin-guide/media/ci.rst. Running multiple cards ~~~~~~~~~~~~~~~~~~~~~~ -See :doc:`bttv-cardlist` for a complete list of +See Documentation/admin-guide/media/bttv-cardlist.rst for a complete list of Card ID. Some examples: =========================== === diff --git a/Documentation/admin-guide/media/bttv.rst b/Documentation/admin-guide/media/bttv.rst index 0ef1f203104d..125f6f47123d 100644 --- a/Documentation/admin-guide/media/bttv.rst +++ b/Documentation/admin-guide/media/bttv.rst @@ -24,7 +24,8 @@ If your board has digital TV, you'll also need:: ./scripts/config -m DVB_BT8XX -In this case, please see :doc:`bt8xx` for additional notes. +In this case, please see Documentation/admin-guide/media/bt8xx.rst +for additional notes. Make bttv work with your card ----------------------------- @@ -39,7 +40,7 @@ If it doesn't bttv likely could not autodetect your card and needs some insmod options. The most important insmod option for bttv is "card=n" to select the correct card type. If you get video but no sound you've very likely specified the wrong (or no) card type. A list of supported -cards is in :doc:`bttv-cardlist`. +cards is in Documentation/admin-guide/media/bttv-cardlist.rst. If bttv takes very long to load (happens sometimes with the cheap cards which have no tuner), try adding this to your modules configuration @@ -57,8 +58,8 @@ directory should be enough for it to be autoload during the driver's probing mode (e. g. when the Kernel boots or when the driver is manually loaded via ``modprobe`` command). -If your card isn't listed in :doc:`bttv-cardlist` or if you have -trouble making audio work, please read :ref:`still_doesnt_work`. +If your card isn't listed in Documentation/admin-guide/media/bttv-cardlist.rst +or if you have trouble making audio work, please read :ref:`still_doesnt_work`. Autodetecting cards @@ -77,8 +78,8 @@ the Subsystem ID in the second line, looks like this: only bt878-based cards can have a subsystem ID (which does not mean that every card really has one). bt848 cards can't have a Subsystem ID and therefore can't be autodetected. There is a list with the ID's -at :doc:`bttv-cardlist` (in case you are interested or want to mail -patches with updates). +at Documentation/admin-guide/media/bttv-cardlist.rst +(in case you are interested or want to mail patches with updates). .. _still_doesnt_work: @@ -259,15 +260,15 @@ bug. It is very helpful if you can tell where exactly it broke With a hard freeze you probably doesn't find anything in the logfiles. The only way to capture any kernel messages is to hook up a serial console and let some terminal application log the messages. /me uses -screen. See :doc:`/admin-guide/serial-console` for details on setting -up a serial console. +screen. See Documentation/admin-guide/serial-console.rst for details on +setting up a serial console. -Read :doc:`/admin-guide/bug-hunting` to learn how to get any useful +Read Documentation/admin-guide/bug-hunting.rst to learn how to get any useful information out of a register+stack dump printed by the kernel on protection faults (so-called "kernel oops"). If you run into some kind of deadlock, you can try to dump a call trace -for each process using sysrq-t (see :doc:`/admin-guide/sysrq`). +for each process using sysrq-t (see Documentation/admin-guide/sysrq.rst). This way it is possible to figure where *exactly* some process in "D" state is stuck. diff --git a/Documentation/admin-guide/media/saa7134.rst b/Documentation/admin-guide/media/saa7134.rst index 7ab9c70b9abe..51eae7eb5ab7 100644 --- a/Documentation/admin-guide/media/saa7134.rst +++ b/Documentation/admin-guide/media/saa7134.rst @@ -50,7 +50,8 @@ To build and install, you should run:: Once the new Kernel is booted, saa7134 driver should be loaded automatically. Depending on the card you might have to pass ``card=`` as insmod option. -If so, please check :doc:`saa7134-cardlist` for valid choices. +If so, please check Documentation/admin-guide/media/saa7134-cardlist.rst +for valid choices. Once you have your card type number, you can pass a modules configuration via a file (usually, it is either ``/etc/modules.conf`` or some file at From d382c5be4cc24597d5d12800558e537bbc12a71a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 16 Jun 2021 13:02:07 +0200 Subject: [PATCH 332/394] media: dvb_ca_en50221: avoid speculation from CA slot As warned by smatch: drivers/media/dvb-core/dvb_ca_en50221.c:1392 dvb_ca_en50221_io_do_ioctl() warn: potential spectre issue 'ca->slot_info' [r] (local cap) There's a potential of using a CAM ioctl for speculation. The risk here is minimum, as only a small subset of DVB boards have CI, with a CAM module installed. Also, exploiting it would require a user capable of starting a DVB application. There are probably a lot of easier ways to try to exploit. Yet, it doesn't harm addressing it. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_ca_en50221.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c index b7e4a3371176..15a08d8c69ef 100644 --- a/drivers/media/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb-core/dvb_ca_en50221.c @@ -1386,6 +1386,7 @@ static int dvb_ca_en50221_io_do_ioctl(struct file *file, err = -EINVAL; goto out_unlock; } + slot = array_index_nospec(slot, ca->slot_count); info->type = CA_CI_LINK; info->flags = 0; From abc0226df64dc137b48b911c1fe4319aec5891bb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 16 Jun 2021 13:13:54 +0200 Subject: [PATCH 333/394] media: dvb_net: avoid speculation from net slot The risk of especulation is actually almost-non-existing here, as there are very few users of TCP/IP using the DVB stack, as, this is mainly used with DVB-S/S2 cards, and only by people that receives TCP/IP from satellite connections, which limits a lot the number of users of such feature(*). (*) In thesis, DVB-C cards could also benefit from it, but I'm yet to see a hardware that supports it. Yet, fixing it is trivial. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_net.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/media/dvb-core/dvb_net.c b/drivers/media/dvb-core/dvb_net.c index 89620da983ba..dddebea644bb 100644 --- a/drivers/media/dvb-core/dvb_net.c +++ b/drivers/media/dvb-core/dvb_net.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -1462,14 +1463,20 @@ static int dvb_net_do_ioctl(struct file *file, struct net_device *netdev; struct dvb_net_priv *priv_data; struct dvb_net_if *dvbnetif = parg; + int if_num = dvbnetif->if_num; - if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX || - !dvbnet->state[dvbnetif->if_num]) { + if (if_num >= DVB_NET_DEVICES_MAX) { + ret = -EINVAL; + goto ioctl_error; + } + if_num = array_index_nospec(if_num, DVB_NET_DEVICES_MAX); + + if (!dvbnet->state[if_num]) { ret = -EINVAL; goto ioctl_error; } - netdev = dvbnet->device[dvbnetif->if_num]; + netdev = dvbnet->device[if_num]; priv_data = netdev_priv(netdev); dvbnetif->pid=priv_data->pid; @@ -1522,14 +1529,20 @@ static int dvb_net_do_ioctl(struct file *file, struct net_device *netdev; struct dvb_net_priv *priv_data; struct __dvb_net_if_old *dvbnetif = parg; + int if_num = dvbnetif->if_num; - if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX || - !dvbnet->state[dvbnetif->if_num]) { + if (if_num >= DVB_NET_DEVICES_MAX) { + ret = -EINVAL; + goto ioctl_error; + } + if_num = array_index_nospec(if_num, DVB_NET_DEVICES_MAX); + + if (!dvbnet->state[if_num]) { ret = -EINVAL; goto ioctl_error; } - netdev = dvbnet->device[dvbnetif->if_num]; + netdev = dvbnet->device[if_num]; priv_data = netdev_priv(netdev); dvbnetif->pid=priv_data->pid; From 1fec2ecc252301110e4149e6183fa70460d29674 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 9 Jun 2021 14:32:29 +0200 Subject: [PATCH 334/394] media: dvbdev: fix error logic at dvb_register_device() As reported by smatch: drivers/media/dvb-core/dvbdev.c: drivers/media/dvb-core/dvbdev.c:510 dvb_register_device() warn: '&dvbdev->list_head' not removed from list drivers/media/dvb-core/dvbdev.c: drivers/media/dvb-core/dvbdev.c:530 dvb_register_device() warn: '&dvbdev->list_head' not removed from list drivers/media/dvb-core/dvbdev.c: drivers/media/dvb-core/dvbdev.c:545 dvb_register_device() warn: '&dvbdev->list_head' not removed from list The error logic inside dvb_register_device() doesn't remove devices from the dvb_adapter_list in case of errors. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvbdev.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 3862ddc86ec4..795d9bfaba5c 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -506,6 +506,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, break; if (minor == MAX_DVB_MINORS) { + list_del (&dvbdev->list_head); kfree(dvbdevfops); kfree(dvbdev); up_write(&minor_rwsem); @@ -526,6 +527,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, __func__); dvb_media_device_free(dvbdev); + list_del (&dvbdev->list_head); kfree(dvbdevfops); kfree(dvbdev); mutex_unlock(&dvbdev_register_lock); @@ -541,6 +543,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, pr_err("%s: failed to create device dvb%d.%s%d (%ld)\n", __func__, adap->num, dnames[type], id, PTR_ERR(clsdev)); dvb_media_device_free(dvbdev); + list_del (&dvbdev->list_head); kfree(dvbdevfops); kfree(dvbdev); return PTR_ERR(clsdev); From ba9139116bc053897e6fb16a51c463604c4da371 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 10 Jun 2021 08:20:16 +0200 Subject: [PATCH 335/394] media: sun6i-csi: add a missing return code As pointed by smatch, there's a missing return code: drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c:485 sun6i_video_open() warn: missing error code 'ret' Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c index 3181d0781b61..07b2161392d2 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c @@ -481,8 +481,10 @@ static int sun6i_video_open(struct file *file) goto fh_release; /* check if already powered */ - if (!v4l2_fh_is_singular_file(file)) + if (!v4l2_fh_is_singular_file(file)) { + ret = -EBUSY; goto unlock; + } ret = sun6i_csi_set_power(video->csi, true); if (ret < 0) From 7f9197f11888c45d1aab470b7fd2c1f1fc1a2a35 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 10 Jun 2021 08:33:12 +0200 Subject: [PATCH 336/394] media: saa7134: use more meaninful goto labels Instead of just numbering fail0 to fail4, use more meaninful goto labels. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7134/saa7134-core.c | 34 ++++++++++++------------ 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/media/pci/saa7134/saa7134-core.c b/drivers/media/pci/saa7134/saa7134-core.c index ec8dd41f9ebb..97b1767f1fff 100644 --- a/drivers/media/pci/saa7134/saa7134-core.c +++ b/drivers/media/pci/saa7134/saa7134-core.c @@ -1031,7 +1031,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev, dev->media_dev = kzalloc(sizeof(*dev->media_dev), GFP_KERNEL); if (!dev->media_dev) { err = -ENOMEM; - goto fail0; + goto err_free_dev; } media_device_pci_init(dev->media_dev, pci_dev, dev->name); dev->v4l2_dev.mdev = dev->media_dev; @@ -1039,13 +1039,13 @@ static int saa7134_initdev(struct pci_dev *pci_dev, err = v4l2_device_register(&pci_dev->dev, &dev->v4l2_dev); if (err) - goto fail0; + goto err_free_dev; /* pci init */ dev->pci = pci_dev; if (pci_enable_device(pci_dev)) { err = -EIO; - goto fail1; + goto err_v4l2_unregister; } /* pci quirks */ @@ -1095,7 +1095,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev, err = pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32)); if (err) { pr_warn("%s: Oops: no 32bit PCI DMA ???\n", dev->name); - goto fail1; + goto err_v4l2_unregister; } /* board config */ @@ -1129,7 +1129,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev, err = -EBUSY; pr_err("%s: can't get MMIO memory @ 0x%llx\n", dev->name,(unsigned long long)pci_resource_start(pci_dev,0)); - goto fail1; + goto err_v4l2_unregister; } dev->lmmio = ioremap(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0)); @@ -1138,7 +1138,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev, err = -EIO; pr_err("%s: can't ioremap() MMIO memory\n", dev->name); - goto fail2; + goto err_release_mem_reg; } /* initialize hardware #1 */ @@ -1151,7 +1151,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev, if (err < 0) { pr_err("%s: can't get IRQ %d\n", dev->name,pci_dev->irq); - goto fail3; + goto err_iounmap; } /* wait a bit, register i2c bus */ @@ -1217,7 +1217,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev, if (err < 0) { pr_info("%s: can't register video device\n", dev->name); - goto fail4; + goto err_unregister_video; } pr_info("%s: registered device %s [v4l2]\n", dev->name, video_device_node_name(dev->video_dev)); @@ -1234,7 +1234,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev, err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI, vbi_nr[dev->nr]); if (err < 0) - goto fail4; + goto err_unregister_video; pr_info("%s: registered device %s\n", dev->name, video_device_node_name(dev->vbi_dev)); @@ -1248,7 +1248,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev, err = video_register_device(dev->radio_dev,VFL_TYPE_RADIO, radio_nr[dev->nr]); if (err < 0) - goto fail4; + goto err_unregister_video; pr_info("%s: registered device %s\n", dev->name, video_device_node_name(dev->radio_dev)); } @@ -1259,7 +1259,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev, err = v4l2_mc_create_media_graph(dev->media_dev); if (err) { pr_err("failed to create media graph\n"); - goto fail4; + goto err_unregister_video; } #endif /* everything worked */ @@ -1278,24 +1278,24 @@ static int saa7134_initdev(struct pci_dev *pci_dev, #ifdef CONFIG_MEDIA_CONTROLLER err = media_device_register(dev->media_dev); if (err) - goto fail4; + goto err_unregister_video; #endif return 0; - fail4: +err_unregister_video: saa7134_unregister_video(dev); saa7134_i2c_unregister(dev); free_irq(pci_dev->irq, dev); - fail3: +err_iounmap: saa7134_hwfini(dev); iounmap(dev->lmmio); - fail2: +err_release_mem_reg: release_mem_region(pci_resource_start(pci_dev,0), pci_resource_len(pci_dev,0)); - fail1: +err_v4l2_unregister: v4l2_device_unregister(&dev->v4l2_dev); - fail0: +err_free_dev: #ifdef CONFIG_MEDIA_CONTROLLER kfree(dev->media_dev); #endif From 235406dca37ecf6f00e0378e965a3dd37590c389 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 10 Jun 2021 08:40:58 +0200 Subject: [PATCH 337/394] media: saa7134: fix saa7134_initdev error handling logic Smatch reported an issue there: drivers/media/pci/saa7134/saa7134-core.c:1302 saa7134_initdev() warn: '&dev->devlist' not removed from list But besides freeing the list, the media controller graph also needs to be cleaned up on errors. Address those issues. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/saa7134/saa7134-core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/media/pci/saa7134/saa7134-core.c b/drivers/media/pci/saa7134/saa7134-core.c index 97b1767f1fff..47158ab3956b 100644 --- a/drivers/media/pci/saa7134/saa7134-core.c +++ b/drivers/media/pci/saa7134/saa7134-core.c @@ -1277,14 +1277,17 @@ static int saa7134_initdev(struct pci_dev *pci_dev, */ #ifdef CONFIG_MEDIA_CONTROLLER err = media_device_register(dev->media_dev); - if (err) + if (err) { + media_device_cleanup(dev->media_dev); goto err_unregister_video; + } #endif return 0; err_unregister_video: saa7134_unregister_video(dev); + list_del(&dev->devlist); saa7134_i2c_unregister(dev); free_irq(pci_dev->irq, dev); err_iounmap: From 5368b1ee2939961a16e74972b69088433fc52195 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 10 Jun 2021 08:57:02 +0200 Subject: [PATCH 338/394] media: siano: fix device register error path As reported by smatch: drivers/media/common/siano/smsdvb-main.c:1231 smsdvb_hotplug() warn: '&client->entry' not removed from list If an error occur at the end of the registration logic, it won't drop the device from the list. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smsdvb-main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/media/common/siano/smsdvb-main.c b/drivers/media/common/siano/smsdvb-main.c index b8a163a47d09..f80caaa333da 100644 --- a/drivers/media/common/siano/smsdvb-main.c +++ b/drivers/media/common/siano/smsdvb-main.c @@ -1212,6 +1212,10 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, return 0; media_graph_error: + mutex_lock(&g_smsdvb_clientslock); + list_del(&client->entry); + mutex_unlock(&g_smsdvb_clientslock); + smsdvb_debugfs_release(client); client_error: From dba328bab4c6fa4ec1ed3be616f7196865f2ce41 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 10 Jun 2021 16:00:53 +0200 Subject: [PATCH 339/394] media: ttusb-dec: cleanup an error handling logic Simplify the logic at ttusb_dec_send_command(). Besides avoiding some code duplication, as a side effect, this could remove this false positive return with spatch: drivers/media/usb/ttusb-dec/ttusb_dec.c:380 ttusb_dec_send_command() warn: inconsistent returns '&dec->usb_mutex'. Locked on : 330 Unlocked on: 354,365,380 Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/ttusb-dec/ttusb_dec.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/drivers/media/usb/ttusb-dec/ttusb_dec.c b/drivers/media/usb/ttusb-dec/ttusb_dec.c index a852ee5f7ac9..bfda46a36dc5 100644 --- a/drivers/media/usb/ttusb-dec/ttusb_dec.c +++ b/drivers/media/usb/ttusb-dec/ttusb_dec.c @@ -324,10 +324,10 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, if (!b) return -ENOMEM; - if ((result = mutex_lock_interruptible(&dec->usb_mutex))) { - kfree(b); + result = mutex_lock_interruptible(&dec->usb_mutex); + if (result) { printk("%s: Failed to lock usb mutex.\n", __func__); - return result; + goto err; } b[0] = 0xaa; @@ -349,9 +349,7 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, if (result) { printk("%s: command bulk message failed: error %d\n", __func__, result); - mutex_unlock(&dec->usb_mutex); - kfree(b); - return result; + goto err; } result = usb_bulk_msg(dec->udev, dec->result_pipe, b, @@ -360,9 +358,7 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, if (result) { printk("%s: result bulk message failed: error %d\n", __func__, result); - mutex_unlock(&dec->usb_mutex); - kfree(b); - return result; + goto err; } else { if (debug) { printk(KERN_DEBUG "%s: result: %*ph\n", @@ -373,12 +369,13 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, *result_length = b[3]; if (cmd_result && b[3] > 0) memcpy(cmd_result, &b[4], b[3]); - - mutex_unlock(&dec->usb_mutex); - - kfree(b); - return 0; } + +err: + mutex_unlock(&dec->usb_mutex); + + kfree(b); + return result; } static int ttusb_dec_get_stb_state (struct ttusb_dec *dec, unsigned int *mode, From 60f0618d157b8c8bf1d09d4a6e10070a0b580160 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 14 Jun 2021 10:43:24 +0200 Subject: [PATCH 340/394] media: dvb-core: frontend: make GET/SET safer The implementation for FE_SET_PROPERTY/FE_GET_PROPERTY has a debug code that might be explored via spectre. Improve the logic in order to mitigate such risk. It should be noticed that, before this patch, the logic which implements FE_GET_PROPERTY doesn't check the length passed by the user, which might lead to expose some information. This is probably not exploitable, though, as the frontend drivers won't rely on the buffer length value set by userspace, but it helps to return a valid value back to userspace. The code was changed to only try to access an array based on userspace values only when DVB debug is turned on, helping to reduce the attack surface, as a speculation attack would work only if DVB dev_dbg() macros are enabled, which is usually enabled only on test Kernels or by the root user. As a side effect, a const array size can now be reduced by ~570 bytes, as it now needs to contain just the name of each DTV command. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_frontend.c | 212 ++++++++++++++------------ 1 file changed, 112 insertions(+), 100 deletions(-) diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index a6915582d1a6..258637d762d6 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -1063,107 +1064,97 @@ static int dvb_frontend_clear_cache(struct dvb_frontend *fe) return 0; } -#define _DTV_CMD(n, s, b) \ -[n] = { \ - .name = #n, \ - .cmd = n, \ - .set = s,\ - .buffer = b \ -} +#define _DTV_CMD(n) \ + [n] = #n -struct dtv_cmds_h { - char *name; /* A display name for debugging purposes */ - - __u32 cmd; /* A unique ID */ - - /* Flags */ - __u32 set:1; /* Either a set or get property */ - __u32 buffer:1; /* Does this property use the buffer? */ - __u32 reserved:30; /* Align */ -}; - -static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = { - _DTV_CMD(DTV_TUNE, 1, 0), - _DTV_CMD(DTV_CLEAR, 1, 0), +static char *dtv_cmds[DTV_MAX_COMMAND + 1] = { + _DTV_CMD(DTV_TUNE), + _DTV_CMD(DTV_CLEAR), /* Set */ - _DTV_CMD(DTV_FREQUENCY, 1, 0), - _DTV_CMD(DTV_BANDWIDTH_HZ, 1, 0), - _DTV_CMD(DTV_MODULATION, 1, 0), - _DTV_CMD(DTV_INVERSION, 1, 0), - _DTV_CMD(DTV_DISEQC_MASTER, 1, 1), - _DTV_CMD(DTV_SYMBOL_RATE, 1, 0), - _DTV_CMD(DTV_INNER_FEC, 1, 0), - _DTV_CMD(DTV_VOLTAGE, 1, 0), - _DTV_CMD(DTV_TONE, 1, 0), - _DTV_CMD(DTV_PILOT, 1, 0), - _DTV_CMD(DTV_ROLLOFF, 1, 0), - _DTV_CMD(DTV_DELIVERY_SYSTEM, 1, 0), - _DTV_CMD(DTV_HIERARCHY, 1, 0), - _DTV_CMD(DTV_CODE_RATE_HP, 1, 0), - _DTV_CMD(DTV_CODE_RATE_LP, 1, 0), - _DTV_CMD(DTV_GUARD_INTERVAL, 1, 0), - _DTV_CMD(DTV_TRANSMISSION_MODE, 1, 0), - _DTV_CMD(DTV_INTERLEAVING, 1, 0), + _DTV_CMD(DTV_FREQUENCY), + _DTV_CMD(DTV_BANDWIDTH_HZ), + _DTV_CMD(DTV_MODULATION), + _DTV_CMD(DTV_INVERSION), + _DTV_CMD(DTV_DISEQC_MASTER), + _DTV_CMD(DTV_SYMBOL_RATE), + _DTV_CMD(DTV_INNER_FEC), + _DTV_CMD(DTV_VOLTAGE), + _DTV_CMD(DTV_TONE), + _DTV_CMD(DTV_PILOT), + _DTV_CMD(DTV_ROLLOFF), + _DTV_CMD(DTV_DELIVERY_SYSTEM), + _DTV_CMD(DTV_HIERARCHY), + _DTV_CMD(DTV_CODE_RATE_HP), + _DTV_CMD(DTV_CODE_RATE_LP), + _DTV_CMD(DTV_GUARD_INTERVAL), + _DTV_CMD(DTV_TRANSMISSION_MODE), + _DTV_CMD(DTV_INTERLEAVING), - _DTV_CMD(DTV_ISDBT_PARTIAL_RECEPTION, 1, 0), - _DTV_CMD(DTV_ISDBT_SOUND_BROADCASTING, 1, 0), - _DTV_CMD(DTV_ISDBT_SB_SUBCHANNEL_ID, 1, 0), - _DTV_CMD(DTV_ISDBT_SB_SEGMENT_IDX, 1, 0), - _DTV_CMD(DTV_ISDBT_SB_SEGMENT_COUNT, 1, 0), - _DTV_CMD(DTV_ISDBT_LAYER_ENABLED, 1, 0), - _DTV_CMD(DTV_ISDBT_LAYERA_FEC, 1, 0), - _DTV_CMD(DTV_ISDBT_LAYERA_MODULATION, 1, 0), - _DTV_CMD(DTV_ISDBT_LAYERA_SEGMENT_COUNT, 1, 0), - _DTV_CMD(DTV_ISDBT_LAYERA_TIME_INTERLEAVING, 1, 0), - _DTV_CMD(DTV_ISDBT_LAYERB_FEC, 1, 0), - _DTV_CMD(DTV_ISDBT_LAYERB_MODULATION, 1, 0), - _DTV_CMD(DTV_ISDBT_LAYERB_SEGMENT_COUNT, 1, 0), - _DTV_CMD(DTV_ISDBT_LAYERB_TIME_INTERLEAVING, 1, 0), - _DTV_CMD(DTV_ISDBT_LAYERC_FEC, 1, 0), - _DTV_CMD(DTV_ISDBT_LAYERC_MODULATION, 1, 0), - _DTV_CMD(DTV_ISDBT_LAYERC_SEGMENT_COUNT, 1, 0), - _DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING, 1, 0), + _DTV_CMD(DTV_ISDBT_PARTIAL_RECEPTION), + _DTV_CMD(DTV_ISDBT_SOUND_BROADCASTING), + _DTV_CMD(DTV_ISDBT_SB_SUBCHANNEL_ID), + _DTV_CMD(DTV_ISDBT_SB_SEGMENT_IDX), + _DTV_CMD(DTV_ISDBT_SB_SEGMENT_COUNT), + _DTV_CMD(DTV_ISDBT_LAYER_ENABLED), + _DTV_CMD(DTV_ISDBT_LAYERA_FEC), + _DTV_CMD(DTV_ISDBT_LAYERA_MODULATION), + _DTV_CMD(DTV_ISDBT_LAYERA_SEGMENT_COUNT), + _DTV_CMD(DTV_ISDBT_LAYERA_TIME_INTERLEAVING), + _DTV_CMD(DTV_ISDBT_LAYERB_FEC), + _DTV_CMD(DTV_ISDBT_LAYERB_MODULATION), + _DTV_CMD(DTV_ISDBT_LAYERB_SEGMENT_COUNT), + _DTV_CMD(DTV_ISDBT_LAYERB_TIME_INTERLEAVING), + _DTV_CMD(DTV_ISDBT_LAYERC_FEC), + _DTV_CMD(DTV_ISDBT_LAYERC_MODULATION), + _DTV_CMD(DTV_ISDBT_LAYERC_SEGMENT_COUNT), + _DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING), - _DTV_CMD(DTV_STREAM_ID, 1, 0), - _DTV_CMD(DTV_DVBT2_PLP_ID_LEGACY, 1, 0), - _DTV_CMD(DTV_SCRAMBLING_SEQUENCE_INDEX, 1, 0), - _DTV_CMD(DTV_LNA, 1, 0), + _DTV_CMD(DTV_STREAM_ID), + _DTV_CMD(DTV_DVBT2_PLP_ID_LEGACY), + _DTV_CMD(DTV_SCRAMBLING_SEQUENCE_INDEX), + _DTV_CMD(DTV_LNA), /* Get */ - _DTV_CMD(DTV_DISEQC_SLAVE_REPLY, 0, 1), - _DTV_CMD(DTV_API_VERSION, 0, 0), + _DTV_CMD(DTV_DISEQC_SLAVE_REPLY), + _DTV_CMD(DTV_API_VERSION), - _DTV_CMD(DTV_ENUM_DELSYS, 0, 0), + _DTV_CMD(DTV_ENUM_DELSYS), - _DTV_CMD(DTV_ATSCMH_PARADE_ID, 1, 0), - _DTV_CMD(DTV_ATSCMH_RS_FRAME_ENSEMBLE, 1, 0), + _DTV_CMD(DTV_ATSCMH_PARADE_ID), + _DTV_CMD(DTV_ATSCMH_RS_FRAME_ENSEMBLE), - _DTV_CMD(DTV_ATSCMH_FIC_VER, 0, 0), - _DTV_CMD(DTV_ATSCMH_NOG, 0, 0), - _DTV_CMD(DTV_ATSCMH_TNOG, 0, 0), - _DTV_CMD(DTV_ATSCMH_SGN, 0, 0), - _DTV_CMD(DTV_ATSCMH_PRC, 0, 0), - _DTV_CMD(DTV_ATSCMH_RS_FRAME_MODE, 0, 0), - _DTV_CMD(DTV_ATSCMH_RS_CODE_MODE_PRI, 0, 0), - _DTV_CMD(DTV_ATSCMH_RS_CODE_MODE_SEC, 0, 0), - _DTV_CMD(DTV_ATSCMH_SCCC_BLOCK_MODE, 0, 0), - _DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_A, 0, 0), - _DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_B, 0, 0), - _DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_C, 0, 0), - _DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_D, 0, 0), + _DTV_CMD(DTV_ATSCMH_FIC_VER), + _DTV_CMD(DTV_ATSCMH_NOG), + _DTV_CMD(DTV_ATSCMH_TNOG), + _DTV_CMD(DTV_ATSCMH_SGN), + _DTV_CMD(DTV_ATSCMH_PRC), + _DTV_CMD(DTV_ATSCMH_RS_FRAME_MODE), + _DTV_CMD(DTV_ATSCMH_RS_CODE_MODE_PRI), + _DTV_CMD(DTV_ATSCMH_RS_CODE_MODE_SEC), + _DTV_CMD(DTV_ATSCMH_SCCC_BLOCK_MODE), + _DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_A), + _DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_B), + _DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_C), + _DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_D), /* Statistics API */ - _DTV_CMD(DTV_STAT_SIGNAL_STRENGTH, 0, 0), - _DTV_CMD(DTV_STAT_CNR, 0, 0), - _DTV_CMD(DTV_STAT_PRE_ERROR_BIT_COUNT, 0, 0), - _DTV_CMD(DTV_STAT_PRE_TOTAL_BIT_COUNT, 0, 0), - _DTV_CMD(DTV_STAT_POST_ERROR_BIT_COUNT, 0, 0), - _DTV_CMD(DTV_STAT_POST_TOTAL_BIT_COUNT, 0, 0), - _DTV_CMD(DTV_STAT_ERROR_BLOCK_COUNT, 0, 0), - _DTV_CMD(DTV_STAT_TOTAL_BLOCK_COUNT, 0, 0), + _DTV_CMD(DTV_STAT_SIGNAL_STRENGTH), + _DTV_CMD(DTV_STAT_CNR), + _DTV_CMD(DTV_STAT_PRE_ERROR_BIT_COUNT), + _DTV_CMD(DTV_STAT_PRE_TOTAL_BIT_COUNT), + _DTV_CMD(DTV_STAT_POST_ERROR_BIT_COUNT), + _DTV_CMD(DTV_STAT_POST_TOTAL_BIT_COUNT), + _DTV_CMD(DTV_STAT_ERROR_BLOCK_COUNT), + _DTV_CMD(DTV_STAT_TOTAL_BLOCK_COUNT), }; +static char *dtv_cmd_name(u32 cmd) +{ + cmd = array_index_nospec(cmd, DTV_MAX_COMMAND); + return dtv_cmds[cmd]; +} + /* Synchronise the legacy tuning parameters into the cache, so that demodulator * drivers can use a single set_frontend tuning function, regardless of whether * it's being used for the legacy or new API, reducing code and complexity. @@ -1346,6 +1337,7 @@ static int dtv_property_process_get(struct dvb_frontend *fe, struct file *file) { int ncaps; + unsigned int len = 1; switch (tvp->cmd) { case DTV_ENUM_DELSYS: @@ -1355,6 +1347,7 @@ static int dtv_property_process_get(struct dvb_frontend *fe, ncaps++; } tvp->u.buffer.len = ncaps; + len = ncaps; break; case DTV_FREQUENCY: tvp->u.data = c->frequency; @@ -1532,27 +1525,51 @@ static int dtv_property_process_get(struct dvb_frontend *fe, /* Fill quality measures */ case DTV_STAT_SIGNAL_STRENGTH: tvp->u.st = c->strength; + if (tvp->u.buffer.len > MAX_DTV_STATS * sizeof(u32)) + tvp->u.buffer.len = MAX_DTV_STATS * sizeof(u32); + len = tvp->u.buffer.len; break; case DTV_STAT_CNR: tvp->u.st = c->cnr; + if (tvp->u.buffer.len > MAX_DTV_STATS * sizeof(u32)) + tvp->u.buffer.len = MAX_DTV_STATS * sizeof(u32); + len = tvp->u.buffer.len; break; case DTV_STAT_PRE_ERROR_BIT_COUNT: tvp->u.st = c->pre_bit_error; + if (tvp->u.buffer.len > MAX_DTV_STATS * sizeof(u32)) + tvp->u.buffer.len = MAX_DTV_STATS * sizeof(u32); + len = tvp->u.buffer.len; break; case DTV_STAT_PRE_TOTAL_BIT_COUNT: tvp->u.st = c->pre_bit_count; + if (tvp->u.buffer.len > MAX_DTV_STATS * sizeof(u32)) + tvp->u.buffer.len = MAX_DTV_STATS * sizeof(u32); + len = tvp->u.buffer.len; break; case DTV_STAT_POST_ERROR_BIT_COUNT: tvp->u.st = c->post_bit_error; + if (tvp->u.buffer.len > MAX_DTV_STATS * sizeof(u32)) + tvp->u.buffer.len = MAX_DTV_STATS * sizeof(u32); + len = tvp->u.buffer.len; break; case DTV_STAT_POST_TOTAL_BIT_COUNT: tvp->u.st = c->post_bit_count; + if (tvp->u.buffer.len > MAX_DTV_STATS * sizeof(u32)) + tvp->u.buffer.len = MAX_DTV_STATS * sizeof(u32); + len = tvp->u.buffer.len; break; case DTV_STAT_ERROR_BLOCK_COUNT: tvp->u.st = c->block_error; + if (tvp->u.buffer.len > MAX_DTV_STATS * sizeof(u32)) + tvp->u.buffer.len = MAX_DTV_STATS * sizeof(u32); + len = tvp->u.buffer.len; break; case DTV_STAT_TOTAL_BLOCK_COUNT: tvp->u.st = c->block_count; + if (tvp->u.buffer.len > MAX_DTV_STATS * sizeof(u32)) + tvp->u.buffer.len = MAX_DTV_STATS * sizeof(u32); + len = tvp->u.buffer.len; break; default: dev_dbg(fe->dvb->device, @@ -1561,18 +1578,13 @@ static int dtv_property_process_get(struct dvb_frontend *fe, return -EINVAL; } - if (!dtv_cmds[tvp->cmd].buffer) - dev_dbg(fe->dvb->device, - "%s: GET cmd 0x%08x (%s) = 0x%08x\n", - __func__, tvp->cmd, dtv_cmds[tvp->cmd].name, - tvp->u.data); - else - dev_dbg(fe->dvb->device, - "%s: GET cmd 0x%08x (%s) len %d: %*ph\n", - __func__, - tvp->cmd, dtv_cmds[tvp->cmd].name, - tvp->u.buffer.len, - tvp->u.buffer.len, tvp->u.buffer.data); + if (len < 1) + len = 1; + + dev_dbg(fe->dvb->device, + "%s: GET cmd 0x%08x (%s) len %d: %*ph\n", + __func__, tvp->cmd, dtv_cmd_name(tvp->cmd), + tvp->u.buffer.len, tvp->u.buffer.len, tvp->u.buffer.data); return 0; } @@ -1870,7 +1882,7 @@ static int dtv_property_process_set(struct dvb_frontend *fe, else dev_dbg(fe->dvb->device, "%s: SET cmd 0x%08x (%s) to 0x%08x\n", - __func__, cmd, dtv_cmds[cmd].name, data); + __func__, cmd, dtv_cmd_name(cmd), data); switch (cmd) { case DTV_CLEAR: /* From 128916984208d8f7ccaed6eda840c603fa112910 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 10 Jun 2021 11:53:45 +0200 Subject: [PATCH 341/394] media: xilinx: simplify get fourcc logic Right now, there are two calls for xvip_get_format_by_fourcc(). If the first one fails, it is called again in order to pick the first available format: V4L2_PIX_FMT_YUYV. This ends by producing a smatch warnings: drivers/media/platform/xilinx/xilinx-dma.c:555 __xvip_dma_try_format() error: 'info' dereferencing possible ERR_PTR() drivers/media/platform/xilinx/xilinx-dma.c: drivers/media/platform/xilinx/xilinx-dma.c:664 xvip_dma_init() error: 'dma->fmtinfo' dereferencing possible ERR_PTR() as it is hard for an static analyzer to ensure that calling xvip_get_format_by_fourcc(XVIP_DMA_DEF_FORMAT) won't return an error. So, better to optimize the logic, ensuring that the function will never return an error. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/xilinx/xilinx-dma.c | 5 +---- drivers/media/platform/xilinx/xilinx-vip.c | 6 +++--- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c index 2a56201cb853..338c3661d809 100644 --- a/drivers/media/platform/xilinx/xilinx-dma.c +++ b/drivers/media/platform/xilinx/xilinx-dma.c @@ -26,7 +26,6 @@ #include "xilinx-vip.h" #include "xilinx-vipp.h" -#define XVIP_DMA_DEF_FORMAT V4L2_PIX_FMT_YUYV #define XVIP_DMA_DEF_WIDTH 1920 #define XVIP_DMA_DEF_HEIGHT 1080 @@ -549,8 +548,6 @@ __xvip_dma_try_format(struct xvip_dma *dma, struct v4l2_pix_format *pix, * requested format isn't supported. */ info = xvip_get_format_by_fourcc(pix->pixelformat); - if (IS_ERR(info)) - info = xvip_get_format_by_fourcc(XVIP_DMA_DEF_FORMAT); pix->pixelformat = info->fourcc; pix->field = V4L2_FIELD_NONE; @@ -660,7 +657,7 @@ int xvip_dma_init(struct xvip_composite_device *xdev, struct xvip_dma *dma, INIT_LIST_HEAD(&dma->queued_bufs); spin_lock_init(&dma->queued_lock); - dma->fmtinfo = xvip_get_format_by_fourcc(XVIP_DMA_DEF_FORMAT); + dma->fmtinfo = xvip_get_format_by_fourcc(V4L2_PIX_FMT_YUYV); dma->format.pixelformat = dma->fmtinfo->fourcc; dma->format.colorspace = V4L2_COLORSPACE_SRGB; dma->format.field = V4L2_FIELD_NONE; diff --git a/drivers/media/platform/xilinx/xilinx-vip.c b/drivers/media/platform/xilinx/xilinx-vip.c index 6ad61b08a31a..a4eb57683411 100644 --- a/drivers/media/platform/xilinx/xilinx-vip.c +++ b/drivers/media/platform/xilinx/xilinx-vip.c @@ -70,8 +70,8 @@ EXPORT_SYMBOL_GPL(xvip_get_format_by_code); * @fourcc: the format 4CC * * Return: a pointer to the format information structure corresponding to the - * given V4L2 format @fourcc, or ERR_PTR if no corresponding format can be - * found. + * given V4L2 format @fourcc. If not found, return a pointer to the first + * available format (V4L2_PIX_FMT_YUYV). */ const struct xvip_video_format *xvip_get_format_by_fourcc(u32 fourcc) { @@ -84,7 +84,7 @@ const struct xvip_video_format *xvip_get_format_by_fourcc(u32 fourcc) return format; } - return ERR_PTR(-EINVAL); + return &xvip_video_formats[0]; } EXPORT_SYMBOL_GPL(xvip_get_format_by_fourcc); From c73c23f347168e315d65fd3b7cffca8439724b26 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Thu, 3 Jun 2021 02:17:08 +0200 Subject: [PATCH 342/394] media: venus: hfi_cmds: Fix packet size calculation Now that a one-element array was replaced with a flexible-array member in struct hfi_sys_set_property_pkt, use the struct_size() helper to correctly calculate the packet size. Fixes: 701e10b3fd9f ("media: venus: hfi_cmds.h: Replace one-element array with flexible-array member") Signed-off-by: Gustavo A. R. Silva Signed-off-by: Stanimir Varbanov Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/venus/hfi_cmds.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/qcom/venus/hfi_cmds.c b/drivers/media/platform/qcom/venus/hfi_cmds.c index 4b9dea7f6940..f51024786991 100644 --- a/drivers/media/platform/qcom/venus/hfi_cmds.c +++ b/drivers/media/platform/qcom/venus/hfi_cmds.c @@ -3,6 +3,7 @@ * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * Copyright (C) 2017 Linaro Ltd. */ +#include #include #include @@ -27,7 +28,7 @@ void pkt_sys_idle_indicator(struct hfi_sys_set_property_pkt *pkt, u32 enable) { struct hfi_enable *hfi = (struct hfi_enable *)&pkt->data[1]; - pkt->hdr.size = sizeof(*pkt) + sizeof(*hfi) + sizeof(u32); + pkt->hdr.size = struct_size(pkt, data, 1) + sizeof(*hfi); pkt->hdr.pkt_type = HFI_CMD_SYS_SET_PROPERTY; pkt->num_properties = 1; pkt->data[0] = HFI_PROPERTY_SYS_IDLE_INDICATOR; @@ -39,7 +40,7 @@ void pkt_sys_debug_config(struct hfi_sys_set_property_pkt *pkt, u32 mode, { struct hfi_debug_config *hfi; - pkt->hdr.size = sizeof(*pkt) + sizeof(*hfi) + sizeof(u32); + pkt->hdr.size = struct_size(pkt, data, 1) + sizeof(*hfi); pkt->hdr.pkt_type = HFI_CMD_SYS_SET_PROPERTY; pkt->num_properties = 1; pkt->data[0] = HFI_PROPERTY_SYS_DEBUG_CONFIG; @@ -50,7 +51,7 @@ void pkt_sys_debug_config(struct hfi_sys_set_property_pkt *pkt, u32 mode, void pkt_sys_coverage_config(struct hfi_sys_set_property_pkt *pkt, u32 mode) { - pkt->hdr.size = sizeof(*pkt) + sizeof(u32); + pkt->hdr.size = struct_size(pkt, data, 2); pkt->hdr.pkt_type = HFI_CMD_SYS_SET_PROPERTY; pkt->num_properties = 1; pkt->data[0] = HFI_PROPERTY_SYS_CONFIG_COVERAGE; @@ -116,7 +117,7 @@ void pkt_sys_power_control(struct hfi_sys_set_property_pkt *pkt, u32 enable) { struct hfi_enable *hfi = (struct hfi_enable *)&pkt->data[1]; - pkt->hdr.size = sizeof(*pkt) + sizeof(*hfi) + sizeof(u32); + pkt->hdr.size = struct_size(pkt, data, 1) + sizeof(*hfi); pkt->hdr.pkt_type = HFI_CMD_SYS_SET_PROPERTY; pkt->num_properties = 1; pkt->data[0] = HFI_PROPERTY_SYS_CODEC_POWER_PLANE_CTRL; From 6f2f49ae4c287fbaaed89b2b262a9b99d27302fb Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Fri, 4 Jun 2021 02:43:38 +0200 Subject: [PATCH 343/394] media: venus: hfi_msgs.h: Replace one-element arrays with flexible-array members MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is a regular need in the kernel to provide a way to declare having a dynamically sized set of trailing elements in a structure. Kernel code should always use “flexible array members”[1] for these cases. The older style of one-element or zero-length arrays should no longer be used[2]. Use flexible-array members in struct hfi_msg_sys_property_info_pkt and hfi_msg_session_property_info_pkt instead of one-element arrays, and refactor the code accordingly. Also, this helps with the ongoing efforts to enable -Warray-bounds by fixing the following warnings: CC [M] drivers/media/platform/qcom/venus/hfi_msgs.o drivers/media/platform/qcom/venus/hfi_msgs.c: In function ‘hfi_sys_property_info’: drivers/media/platform/qcom/venus/hfi_msgs.c:246:35: warning: array subscript 1 is above array bounds of ‘u32[1]’ {aka ‘unsigned int[1]’} [-Warray-bounds] 246 | if (req_bytes < 128 || !pkt->data[1] || pkt->num_properties > 1) | ~~~~~~~~~^~~ drivers/media/platform/qcom/venus/hfi_msgs.c: In function ‘hfi_session_prop_info’: drivers/media/platform/qcom/venus/hfi_msgs.c:342:62: warning: array subscript 1 is above array bounds of ‘u32[1]’ {aka ‘unsigned int[1]’} [-Warray-bounds] 342 | if (!req_bytes || req_bytes % sizeof(*buf_req) || !pkt->data[1]) | ~~~~~~~~~^~~ [1] https://en.wikipedia.org/wiki/Flexible_array_member [2] https://www.kernel.org/doc/html/v5.9/process/deprecated.html#zero-length-and-one-element-arrays Link: https://github.com/KSPP/linux/issues/79 Link: https://github.com/KSPP/linux/issues/109 Co-developed-by: Kees Cook Signed-off-by: Kees Cook Signed-off-by: Gustavo A. R. Silva Signed-off-by: Stanimir Varbanov Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/qcom/venus/hfi_msgs.c | 16 ++++++++-------- drivers/media/platform/qcom/venus/hfi_msgs.h | 6 ++++-- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/media/platform/qcom/venus/hfi_msgs.c b/drivers/media/platform/qcom/venus/hfi_msgs.c index a2d436d407b2..d9fde66f6fa8 100644 --- a/drivers/media/platform/qcom/venus/hfi_msgs.c +++ b/drivers/media/platform/qcom/venus/hfi_msgs.c @@ -251,11 +251,11 @@ sys_get_prop_image_version(struct device *dev, req_bytes = pkt->hdr.size - sizeof(*pkt); - if (req_bytes < VER_STR_SZ || !pkt->data[1] || pkt->num_properties > 1) + if (req_bytes < VER_STR_SZ || !pkt->data[0] || pkt->num_properties > 1) /* bad packet */ return; - img_ver = (u8 *)&pkt->data[1]; + img_ver = pkt->data; dev_dbg(dev, VDBGL "F/W version: %s\n", img_ver); @@ -277,7 +277,7 @@ static void hfi_sys_property_info(struct venus_core *core, return; } - switch (pkt->data[0]) { + switch (pkt->property) { case HFI_PROPERTY_SYS_IMAGE_VERSION: sys_get_prop_image_version(dev, pkt); break; @@ -338,7 +338,7 @@ session_get_prop_profile_level(struct hfi_msg_session_property_info_pkt *pkt, /* bad packet */ return HFI_ERR_SESSION_INVALID_PARAMETER; - hfi = (struct hfi_profile_level *)&pkt->data[1]; + hfi = (struct hfi_profile_level *)&pkt->data[0]; profile_level->profile = hfi->profile; profile_level->level = hfi->level; @@ -355,11 +355,11 @@ session_get_prop_buf_req(struct hfi_msg_session_property_info_pkt *pkt, req_bytes = pkt->shdr.hdr.size - sizeof(*pkt); - if (!req_bytes || req_bytes % sizeof(*buf_req) || !pkt->data[1]) + if (!req_bytes || req_bytes % sizeof(*buf_req) || !pkt->data[0]) /* bad packet */ return HFI_ERR_SESSION_INVALID_PARAMETER; - buf_req = (struct hfi_buffer_requirements *)&pkt->data[1]; + buf_req = (struct hfi_buffer_requirements *)&pkt->data[0]; if (!buf_req) return HFI_ERR_SESSION_INVALID_PARAMETER; @@ -391,7 +391,7 @@ static void hfi_session_prop_info(struct venus_core *core, goto done; } - switch (pkt->data[0]) { + switch (pkt->property) { case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS: memset(hprop->bufreq, 0, sizeof(hprop->bufreq)); error = session_get_prop_buf_req(pkt, hprop->bufreq); @@ -404,7 +404,7 @@ static void hfi_session_prop_info(struct venus_core *core, case HFI_PROPERTY_CONFIG_VDEC_ENTROPY: break; default: - dev_dbg(dev, VDBGM "unknown property id:%x\n", pkt->data[0]); + dev_dbg(dev, VDBGM "unknown property id:%x\n", pkt->property); return; } diff --git a/drivers/media/platform/qcom/venus/hfi_msgs.h b/drivers/media/platform/qcom/venus/hfi_msgs.h index 526d9f5b487b..510513697335 100644 --- a/drivers/media/platform/qcom/venus/hfi_msgs.h +++ b/drivers/media/platform/qcom/venus/hfi_msgs.h @@ -113,7 +113,8 @@ struct hfi_msg_sys_ping_ack_pkt { struct hfi_msg_sys_property_info_pkt { struct hfi_pkt_hdr hdr; u32 num_properties; - u32 data[1]; + u32 property; + u8 data[]; }; struct hfi_msg_session_load_resources_done_pkt { @@ -233,7 +234,8 @@ struct hfi_msg_session_parse_sequence_header_done_pkt { struct hfi_msg_session_property_info_pkt { struct hfi_session_hdr_pkt shdr; u32 num_properties; - u32 data[1]; + u32 property; + u8 data[]; }; struct hfi_msg_session_release_resources_done_pkt { From 0d346d2a6f54f06f36b224fd27cd6eafe8c83be9 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 10 Jun 2021 17:55:58 +0300 Subject: [PATCH 344/394] media: v4l2-subdev: add subdev-wide state struct We have 'struct v4l2_subdev_pad_config' which contains configuration for a single pad used for the TRY functionality, and an array of those structs is passed to various v4l2_subdev_pad_ops. I was working on subdev internal routing between pads, and realized that there's no way to add TRY functionality for routes, which is not pad specific configuration. Adding a separate struct for try-route config wouldn't work either, as e.g. set-fmt needs to know the try-route configuration to propagate the settings. This patch adds a new struct, 'struct v4l2_subdev_state' (which at the moment only contains the v4l2_subdev_pad_config array) and the new struct is used in most of the places where v4l2_subdev_pad_config was used. All v4l2_subdev_pad_ops functions taking v4l2_subdev_pad_config are changed to instead take v4l2_subdev_state. The changes to drivers/media/v4l2-core/v4l2-subdev.c and include/media/v4l2-subdev.h were written by hand, and all the driver changes were done with the semantic patch below. The spatch needs to be applied to a select list of directories. I used the following shell commands to apply the spatch: dirs="drivers/media/i2c drivers/media/platform drivers/media/usb drivers/media/test-drivers/vimc drivers/media/pci drivers/staging/media" for dir in $dirs; do spatch -j8 --dir --include-headers --no-show-diff --in-place --sp-file v4l2-subdev-state.cocci $dir; done Note that Coccinelle chokes on a few drivers (gcc extensions?). With minor changes we can make Coccinelle run fine, and these changes can be reverted after spatch. The diff for these changes is: For drivers/media/i2c/s5k5baf.c: @@ -1481,7 +1481,7 @@ static int s5k5baf_set_selection(struct v4l2_subdev *sd, &s5k5baf_cis_rect, v4l2_subdev_get_try_crop(sd, cfg, PAD_CIS), v4l2_subdev_get_try_compose(sd, cfg, PAD_CIS), - v4l2_subdev_get_try_crop(sd, cfg, PAD_OUT) + v4l2_subdev_get_try_crop(sd, cfg, PAD_OUT), }; s5k5baf_set_rect_and_adjust(rects, rtype, &sel->r); return 0; For drivers/media/platform/s3c-camif/camif-capture.c: @@ -1230,7 +1230,7 @@ static int s3c_camif_subdev_get_fmt(struct v4l2_subdev *sd, *mf = camif->mbus_fmt; break; - case CAMIF_SD_PAD_SOURCE_C...CAMIF_SD_PAD_SOURCE_P: + case CAMIF_SD_PAD_SOURCE_C: /* crop rectangle at camera interface input */ mf->width = camif->camif_crop.width; mf->height = camif->camif_crop.height; @@ -1332,7 +1332,7 @@ static int s3c_camif_subdev_set_fmt(struct v4l2_subdev *sd, } break; - case CAMIF_SD_PAD_SOURCE_C...CAMIF_SD_PAD_SOURCE_P: + case CAMIF_SD_PAD_SOURCE_C: /* Pixel format can be only changed on the sink pad. */ mf->code = camif->mbus_fmt.code; mf->width = crop->width; The semantic patch is: // // Change function parameter @@ identifier func; identifier cfg; @@ func(..., - struct v4l2_subdev_pad_config *cfg + struct v4l2_subdev_state *sd_state , ...) { <... - cfg + sd_state ...> } // Change function declaration parameter @@ identifier func; identifier cfg; type T; @@ T func(..., - struct v4l2_subdev_pad_config *cfg + struct v4l2_subdev_state *sd_state , ...); // Change function return value @@ identifier func; @@ - struct v4l2_subdev_pad_config + struct v4l2_subdev_state *func(...) { ... } // Change function declaration return value @@ identifier func; @@ - struct v4l2_subdev_pad_config + struct v4l2_subdev_state *func(...); // Some drivers pass a local pad_cfg for a single pad to a called function. Wrap it // inside a pad_state. @@ identifier func; identifier pad_cfg; @@ func(...) { ... struct v4l2_subdev_pad_config pad_cfg; + struct v4l2_subdev_state pad_state = { .pads = &pad_cfg }; <+... ( v4l2_subdev_call | sensor_call | isi_try_fse | isc_try_fse | saa_call_all ) (..., - &pad_cfg + &pad_state ,...) ...+> } // If the function uses fields from pad_config, access via state->pads @@ identifier func; identifier state; @@ func(..., struct v4l2_subdev_state *state , ...) { <... ( - state->try_fmt + state->pads->try_fmt | - state->try_crop + state->pads->try_crop | - state->try_compose + state->pads->try_compose ) ...> } // If the function accesses the filehandle, use fh->state instead @@ struct v4l2_subdev_fh *fh; @@ - fh->pad + fh->state @@ struct v4l2_subdev_fh fh; @@ - fh.pad + fh.state // Start of vsp1 specific @@ @@ struct vsp1_entity { ... - struct v4l2_subdev_pad_config *config; + struct v4l2_subdev_state *config; ... }; @@ symbol entity; @@ vsp1_entity_init(...) { ... entity->config = - v4l2_subdev_alloc_pad_config + v4l2_subdev_alloc_state (&entity->subdev); ... } @@ symbol entity; @@ vsp1_entity_destroy(...) { ... - v4l2_subdev_free_pad_config + v4l2_subdev_free_state (entity->config); ... } @exists@ identifier func =~ "(^vsp1.*)|(hsit_set_format)|(sru_enum_frame_size)|(sru_set_format)|(uif_get_selection)|(uif_set_selection)|(uds_enum_frame_size)|(uds_set_format)|(brx_set_format)|(brx_get_selection)|(histo_get_selection)|(histo_set_selection)|(brx_set_selection)"; symbol config; @@ func(...) { ... - struct v4l2_subdev_pad_config *config; + struct v4l2_subdev_state *config; ... } // End of vsp1 specific // Start of rcar specific @@ identifier sd; identifier pad_cfg; @@ rvin_try_format(...) { ... - struct v4l2_subdev_pad_config *pad_cfg; + struct v4l2_subdev_state *sd_state; ... - pad_cfg = v4l2_subdev_alloc_pad_config(sd); + sd_state = v4l2_subdev_alloc_state(sd); <... - pad_cfg + sd_state ...> - v4l2_subdev_free_pad_config(pad_cfg); + v4l2_subdev_free_state(sd_state); ... } // End of rcar specific // Start of rockchip specific @@ identifier func =~ "(rkisp1_rsz_get_pad_fmt)|(rkisp1_rsz_get_pad_crop)|(rkisp1_rsz_register)"; symbol rsz; symbol pad_cfg; @@ func(...) { + struct v4l2_subdev_state state = { .pads = rsz->pad_cfg }; ... - rsz->pad_cfg + &state ... } @@ identifier func =~ "(rkisp1_isp_get_pad_fmt)|(rkisp1_isp_get_pad_crop)"; symbol isp; symbol pad_cfg; @@ func(...) { + struct v4l2_subdev_state state = { .pads = isp->pad_cfg }; ... - isp->pad_cfg + &state ... } @@ symbol rkisp1; symbol isp; symbol pad_cfg; @@ rkisp1_isp_register(...) { + struct v4l2_subdev_state state = { .pads = rkisp1->isp.pad_cfg }; ... - rkisp1->isp.pad_cfg + &state ... } // End of rockchip specific // Start of tegra-video specific @@ identifier sd; identifier pad_cfg; @@ __tegra_channel_try_format(...) { ... - struct v4l2_subdev_pad_config *pad_cfg; + struct v4l2_subdev_state *sd_state; ... - pad_cfg = v4l2_subdev_alloc_pad_config(sd); + sd_state = v4l2_subdev_alloc_state(sd); <... - pad_cfg + sd_state ...> - v4l2_subdev_free_pad_config(pad_cfg); + v4l2_subdev_free_state(sd_state); ... } @@ identifier sd_state; @@ __tegra_channel_try_format(...) { ... struct v4l2_subdev_state *sd_state; <... - sd_state->try_crop + sd_state->pads->try_crop ...> } // End of tegra-video specific // Signed-off-by: Tomi Valkeinen Acked-by: Laurent Pinchart Acked-by: Sakari Ailus Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7170.c | 6 +- drivers/media/i2c/adv7175.c | 6 +- drivers/media/i2c/adv7180.c | 18 +-- drivers/media/i2c/adv7183.c | 8 +- drivers/media/i2c/adv748x/adv748x-afe.c | 13 +- drivers/media/i2c/adv748x/adv748x-csi2.c | 14 +- drivers/media/i2c/adv748x/adv748x-hdmi.c | 13 +- drivers/media/i2c/adv7511-v4l2.c | 10 +- drivers/media/i2c/adv7604.c | 12 +- drivers/media/i2c/adv7842.c | 12 +- drivers/media/i2c/ak881x.c | 6 +- drivers/media/i2c/ccs/ccs-core.c | 84 +++++----- drivers/media/i2c/cx25840/cx25840-core.c | 2 +- drivers/media/i2c/et8ek8/et8ek8_driver.c | 23 +-- drivers/media/i2c/hi556.c | 15 +- drivers/media/i2c/imx208.c | 19 +-- drivers/media/i2c/imx214.c | 37 +++-- drivers/media/i2c/imx219.c | 30 ++-- drivers/media/i2c/imx258.c | 19 +-- drivers/media/i2c/imx274.c | 38 ++--- drivers/media/i2c/imx290.c | 20 +-- drivers/media/i2c/imx319.c | 18 +-- drivers/media/i2c/imx334.c | 28 ++-- drivers/media/i2c/imx355.c | 18 +-- drivers/media/i2c/m5mols/m5mols_core.c | 21 ++- drivers/media/i2c/max9286.c | 17 +- drivers/media/i2c/ml86v7667.c | 4 +- drivers/media/i2c/mt9m001.c | 18 +-- drivers/media/i2c/mt9m032.c | 38 +++-- drivers/media/i2c/mt9m111.c | 18 +-- drivers/media/i2c/mt9p031.c | 45 +++--- drivers/media/i2c/mt9t001.c | 44 +++--- drivers/media/i2c/mt9t112.c | 14 +- drivers/media/i2c/mt9v011.c | 6 +- drivers/media/i2c/mt9v032.c | 44 +++--- drivers/media/i2c/mt9v111.c | 25 +-- drivers/media/i2c/noon010pc30.c | 19 ++- drivers/media/i2c/ov02a10.c | 17 +- drivers/media/i2c/ov13858.c | 18 +-- drivers/media/i2c/ov2640.c | 16 +- drivers/media/i2c/ov2659.c | 14 +- drivers/media/i2c/ov2680.c | 23 +-- drivers/media/i2c/ov2685.c | 10 +- drivers/media/i2c/ov2740.c | 15 +- drivers/media/i2c/ov5640.c | 14 +- drivers/media/i2c/ov5645.c | 38 ++--- drivers/media/i2c/ov5647.c | 26 ++-- drivers/media/i2c/ov5648.c | 14 +- drivers/media/i2c/ov5670.c | 19 +-- drivers/media/i2c/ov5675.c | 15 +- drivers/media/i2c/ov5695.c | 15 +- drivers/media/i2c/ov6650.c | 28 ++-- drivers/media/i2c/ov7251.c | 39 ++--- drivers/media/i2c/ov7670.c | 17 +- drivers/media/i2c/ov772x.c | 12 +- drivers/media/i2c/ov7740.c | 17 +- drivers/media/i2c/ov8856.c | 15 +- drivers/media/i2c/ov8865.c | 14 +- drivers/media/i2c/ov9640.c | 8 +- drivers/media/i2c/ov9650.c | 17 +- drivers/media/i2c/ov9734.c | 15 +- drivers/media/i2c/rdacm20.c | 4 +- drivers/media/i2c/rdacm21.c | 4 +- drivers/media/i2c/rj54n1cb0c.c | 12 +- drivers/media/i2c/s5c73m3/s5c73m3-core.c | 55 +++---- drivers/media/i2c/s5k4ecgx.c | 22 +-- drivers/media/i2c/s5k5baf.c | 49 +++--- drivers/media/i2c/s5k6a3.c | 19 ++- drivers/media/i2c/s5k6aa.c | 39 +++-- drivers/media/i2c/saa6752hs.c | 6 +- drivers/media/i2c/saa7115.c | 2 +- drivers/media/i2c/saa717x.c | 2 +- drivers/media/i2c/sr030pc30.c | 8 +- drivers/media/i2c/st-mipid02.c | 21 +-- drivers/media/i2c/tc358743.c | 8 +- drivers/media/i2c/tda1997x.c | 14 +- drivers/media/i2c/tvp514x.c | 12 +- drivers/media/i2c/tvp5150.c | 20 +-- drivers/media/i2c/tvp7002.c | 11 +- drivers/media/i2c/tw9910.c | 10 +- drivers/media/i2c/vs6624.c | 8 +- drivers/media/pci/cx18/cx18-av-core.c | 2 +- drivers/media/pci/intel/ipu3/ipu3-cio2-main.c | 17 +- drivers/media/pci/saa7134/saa7134-empress.c | 5 +- drivers/media/platform/atmel/atmel-isc-base.c | 19 ++- drivers/media/platform/atmel/atmel-isi.c | 19 ++- drivers/media/platform/cadence/cdns-csi2tx.c | 14 +- .../media/platform/exynos4-is/fimc-capture.c | 22 +-- drivers/media/platform/exynos4-is/fimc-isp.c | 37 +++-- drivers/media/platform/exynos4-is/fimc-lite.c | 39 ++--- drivers/media/platform/exynos4-is/mipi-csis.c | 17 +- .../media/platform/marvell-ccic/mcam-core.c | 5 +- drivers/media/platform/omap3isp/ispccdc.c | 85 +++++----- drivers/media/platform/omap3isp/ispccp2.c | 49 +++--- drivers/media/platform/omap3isp/ispcsi2.c | 41 +++-- drivers/media/platform/omap3isp/isppreview.c | 69 +++++---- drivers/media/platform/omap3isp/ispresizer.c | 70 +++++---- drivers/media/platform/pxa_camera.c | 5 +- .../media/platform/qcom/camss/camss-csid.c | 35 +++-- .../media/platform/qcom/camss/camss-csiphy.c | 40 +++-- .../media/platform/qcom/camss/camss-ispif.c | 36 +++-- drivers/media/platform/qcom/camss/camss-vfe.c | 84 +++++----- drivers/media/platform/rcar-vin/rcar-csi2.c | 8 +- drivers/media/platform/rcar-vin/rcar-v4l2.c | 10 +- drivers/media/platform/renesas-ceu.c | 7 +- .../platform/rockchip/rkisp1/rkisp1-isp.c | 112 ++++++++------ .../platform/rockchip/rkisp1/rkisp1-resizer.c | 95 ++++++++---- .../media/platform/s3c-camif/camif-capture.c | 18 +-- drivers/media/platform/stm32/stm32-dcmi.c | 14 +- .../platform/sunxi/sun4i-csi/sun4i_v4l2.c | 16 +- drivers/media/platform/ti-vpe/cal-camerarx.c | 35 +++-- drivers/media/platform/via-camera.c | 5 +- drivers/media/platform/video-mux.c | 22 +-- drivers/media/platform/vsp1/vsp1_brx.c | 34 ++-- drivers/media/platform/vsp1/vsp1_clu.c | 13 +- drivers/media/platform/vsp1/vsp1_entity.c | 59 +++---- drivers/media/platform/vsp1/vsp1_entity.h | 20 +-- drivers/media/platform/vsp1/vsp1_histo.c | 51 +++--- drivers/media/platform/vsp1/vsp1_hsit.c | 14 +- drivers/media/platform/vsp1/vsp1_lif.c | 13 +- drivers/media/platform/vsp1/vsp1_lut.c | 13 +- drivers/media/platform/vsp1/vsp1_rwpf.c | 32 ++-- drivers/media/platform/vsp1/vsp1_rwpf.h | 2 +- drivers/media/platform/vsp1/vsp1_sru.c | 22 +-- drivers/media/platform/vsp1/vsp1_uds.c | 22 +-- drivers/media/platform/vsp1/vsp1_uif.c | 27 ++-- .../media/platform/xilinx/xilinx-csi2rxss.c | 26 ++-- drivers/media/platform/xilinx/xilinx-tpg.c | 25 +-- drivers/media/platform/xilinx/xilinx-vip.c | 12 +- drivers/media/platform/xilinx/xilinx-vip.h | 4 +- .../media/test-drivers/vimc/vimc-debayer.c | 20 +-- drivers/media/test-drivers/vimc/vimc-scaler.c | 36 ++--- drivers/media/test-drivers/vimc/vimc-sensor.c | 16 +- drivers/media/usb/go7007/s2250-board.c | 2 +- drivers/media/v4l2-core/v4l2-subdev.c | 146 ++++++++++-------- .../media/atomisp/i2c/atomisp-gc0310.c | 10 +- .../media/atomisp/i2c/atomisp-gc2235.c | 10 +- .../media/atomisp/i2c/atomisp-mt9m114.c | 12 +- .../media/atomisp/i2c/atomisp-ov2680.c | 10 +- .../media/atomisp/i2c/atomisp-ov2722.c | 10 +- .../media/atomisp/i2c/ov5693/atomisp-ov5693.c | 10 +- .../staging/media/atomisp/pci/atomisp_cmd.c | 33 ++-- .../staging/media/atomisp/pci/atomisp_csi2.c | 28 ++-- .../staging/media/atomisp/pci/atomisp_csi2.h | 2 +- .../staging/media/atomisp/pci/atomisp_file.c | 14 +- .../staging/media/atomisp/pci/atomisp_fops.c | 6 +- .../media/atomisp/pci/atomisp_subdev.c | 64 ++++---- .../media/atomisp/pci/atomisp_subdev.h | 9 +- .../staging/media/atomisp/pci/atomisp_tpg.c | 12 +- drivers/staging/media/imx/imx-ic-prp.c | 19 +-- drivers/staging/media/imx/imx-ic-prpencvf.c | 31 ++-- drivers/staging/media/imx/imx-media-csi.c | 82 +++++----- drivers/staging/media/imx/imx-media-utils.c | 4 +- drivers/staging/media/imx/imx-media-vdic.c | 24 +-- drivers/staging/media/imx/imx-media.h | 2 +- drivers/staging/media/imx/imx6-mipi-csi2.c | 12 +- drivers/staging/media/imx/imx7-media-csi.c | 33 ++-- drivers/staging/media/imx/imx7-mipi-csis.c | 34 ++-- drivers/staging/media/ipu3/ipu3-v4l2.c | 26 ++-- drivers/staging/media/omap4iss/iss_csi2.c | 37 +++-- drivers/staging/media/omap4iss/iss_ipipe.c | 37 +++-- drivers/staging/media/omap4iss/iss_ipipeif.c | 47 +++--- drivers/staging/media/omap4iss/iss_resizer.c | 39 +++-- drivers/staging/media/tegra-video/csi.c | 10 +- drivers/staging/media/tegra-video/vi.c | 24 +-- include/media/v4l2-subdev.h | 74 +++++---- 166 files changed, 2165 insertions(+), 1805 deletions(-) diff --git a/drivers/media/i2c/adv7170.c b/drivers/media/i2c/adv7170.c index e4e8fda51ad8..714e31f993e1 100644 --- a/drivers/media/i2c/adv7170.c +++ b/drivers/media/i2c/adv7170.c @@ -250,7 +250,7 @@ static int adv7170_s_routing(struct v4l2_subdev *sd, } static int adv7170_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->pad || code->index >= ARRAY_SIZE(adv7170_codes)) @@ -261,7 +261,7 @@ static int adv7170_enum_mbus_code(struct v4l2_subdev *sd, } static int adv7170_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *mf = &format->format; @@ -284,7 +284,7 @@ static int adv7170_get_fmt(struct v4l2_subdev *sd, } static int adv7170_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *mf = &format->format; diff --git a/drivers/media/i2c/adv7175.c b/drivers/media/i2c/adv7175.c index 0cdd8e033197..1813f67f0fe1 100644 --- a/drivers/media/i2c/adv7175.c +++ b/drivers/media/i2c/adv7175.c @@ -288,7 +288,7 @@ static int adv7175_s_routing(struct v4l2_subdev *sd, } static int adv7175_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->pad || code->index >= ARRAY_SIZE(adv7175_codes)) @@ -299,7 +299,7 @@ static int adv7175_enum_mbus_code(struct v4l2_subdev *sd, } static int adv7175_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *mf = &format->format; @@ -322,7 +322,7 @@ static int adv7175_get_fmt(struct v4l2_subdev *sd, } static int adv7175_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *mf = &format->format; diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c index 44bb6fe85644..fa5bc55bc944 100644 --- a/drivers/media/i2c/adv7180.c +++ b/drivers/media/i2c/adv7180.c @@ -633,7 +633,7 @@ static void adv7180_exit_controls(struct adv7180_state *state) } static int adv7180_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->index != 0) @@ -699,13 +699,13 @@ static int adv7180_set_field_mode(struct adv7180_state *state) } static int adv7180_get_pad_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct adv7180_state *state = to_state(sd); if (format->which == V4L2_SUBDEV_FORMAT_TRY) { - format->format = *v4l2_subdev_get_try_format(sd, cfg, 0); + format->format = *v4l2_subdev_get_try_format(sd, sd_state, 0); } else { adv7180_mbus_fmt(sd, &format->format); format->format.field = state->field; @@ -715,7 +715,7 @@ static int adv7180_get_pad_format(struct v4l2_subdev *sd, } static int adv7180_set_pad_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct adv7180_state *state = to_state(sd); @@ -742,7 +742,7 @@ static int adv7180_set_pad_format(struct v4l2_subdev *sd, adv7180_set_power(state, true); } } else { - framefmt = v4l2_subdev_get_try_format(sd, cfg, 0); + framefmt = v4l2_subdev_get_try_format(sd, sd_state, 0); *framefmt = format->format; } @@ -750,14 +750,14 @@ static int adv7180_set_pad_format(struct v4l2_subdev *sd, } static int adv7180_init_cfg(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg) + struct v4l2_subdev_state *sd_state) { struct v4l2_subdev_format fmt = { - .which = cfg ? V4L2_SUBDEV_FORMAT_TRY - : V4L2_SUBDEV_FORMAT_ACTIVE, + .which = sd_state ? V4L2_SUBDEV_FORMAT_TRY + : V4L2_SUBDEV_FORMAT_ACTIVE, }; - return adv7180_set_pad_format(sd, cfg, &fmt); + return adv7180_set_pad_format(sd, sd_state, &fmt); } static int adv7180_get_mbus_config(struct v4l2_subdev *sd, diff --git a/drivers/media/i2c/adv7183.c b/drivers/media/i2c/adv7183.c index 8bcd632c081a..92cafdea3f1f 100644 --- a/drivers/media/i2c/adv7183.c +++ b/drivers/media/i2c/adv7183.c @@ -409,7 +409,7 @@ static int adv7183_g_input_status(struct v4l2_subdev *sd, u32 *status) } static int adv7183_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->pad || code->index > 0) @@ -420,7 +420,7 @@ static int adv7183_enum_mbus_code(struct v4l2_subdev *sd, } static int adv7183_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct adv7183 *decoder = to_adv7183(sd); @@ -443,12 +443,12 @@ static int adv7183_set_fmt(struct v4l2_subdev *sd, if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) decoder->fmt = *fmt; else - cfg->try_fmt = *fmt; + sd_state->pads->try_fmt = *fmt; return 0; } static int adv7183_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct adv7183 *decoder = to_adv7183(sd); diff --git a/drivers/media/i2c/adv748x/adv748x-afe.c b/drivers/media/i2c/adv748x/adv748x-afe.c index 4052cf67bf16..02eabe10ab97 100644 --- a/drivers/media/i2c/adv748x/adv748x-afe.c +++ b/drivers/media/i2c/adv748x/adv748x-afe.c @@ -331,7 +331,7 @@ static int adv748x_afe_propagate_pixelrate(struct adv748x_afe *afe) } static int adv748x_afe_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->index != 0) @@ -343,7 +343,7 @@ static int adv748x_afe_enum_mbus_code(struct v4l2_subdev *sd, } static int adv748x_afe_get_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *sdformat) { struct adv748x_afe *afe = adv748x_sd_to_afe(sd); @@ -354,7 +354,8 @@ static int adv748x_afe_get_format(struct v4l2_subdev *sd, return -EINVAL; if (sdformat->which == V4L2_SUBDEV_FORMAT_TRY) { - mbusformat = v4l2_subdev_get_try_format(sd, cfg, sdformat->pad); + mbusformat = v4l2_subdev_get_try_format(sd, sd_state, + sdformat->pad); sdformat->format = *mbusformat; } else { adv748x_afe_fill_format(afe, &sdformat->format); @@ -365,7 +366,7 @@ static int adv748x_afe_get_format(struct v4l2_subdev *sd, } static int adv748x_afe_set_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *sdformat) { struct v4l2_mbus_framefmt *mbusformat; @@ -375,9 +376,9 @@ static int adv748x_afe_set_format(struct v4l2_subdev *sd, return -EINVAL; if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE) - return adv748x_afe_get_format(sd, cfg, sdformat); + return adv748x_afe_get_format(sd, sd_state, sdformat); - mbusformat = v4l2_subdev_get_try_format(sd, cfg, sdformat->pad); + mbusformat = v4l2_subdev_get_try_format(sd, sd_state, sdformat->pad); *mbusformat = sdformat->format; return 0; diff --git a/drivers/media/i2c/adv748x/adv748x-csi2.c b/drivers/media/i2c/adv748x/adv748x-csi2.c index fa9278a08fde..589e9644fcdc 100644 --- a/drivers/media/i2c/adv748x/adv748x-csi2.c +++ b/drivers/media/i2c/adv748x/adv748x-csi2.c @@ -141,26 +141,26 @@ static const struct v4l2_subdev_video_ops adv748x_csi2_video_ops = { static struct v4l2_mbus_framefmt * adv748x_csi2_get_pad_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad, u32 which) { struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd); if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_format(sd, cfg, pad); + return v4l2_subdev_get_try_format(sd, sd_state, pad); return &tx->format; } static int adv748x_csi2_get_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *sdformat) { struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd); struct adv748x_state *state = tx->state; struct v4l2_mbus_framefmt *mbusformat; - mbusformat = adv748x_csi2_get_pad_format(sd, cfg, sdformat->pad, + mbusformat = adv748x_csi2_get_pad_format(sd, sd_state, sdformat->pad, sdformat->which); if (!mbusformat) return -EINVAL; @@ -175,7 +175,7 @@ static int adv748x_csi2_get_format(struct v4l2_subdev *sd, } static int adv748x_csi2_set_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *sdformat) { struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd); @@ -183,7 +183,7 @@ static int adv748x_csi2_set_format(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mbusformat; int ret = 0; - mbusformat = adv748x_csi2_get_pad_format(sd, cfg, sdformat->pad, + mbusformat = adv748x_csi2_get_pad_format(sd, sd_state, sdformat->pad, sdformat->which); if (!mbusformat) return -EINVAL; @@ -193,7 +193,7 @@ static int adv748x_csi2_set_format(struct v4l2_subdev *sd, if (sdformat->pad == ADV748X_CSI2_SOURCE) { const struct v4l2_mbus_framefmt *sink_fmt; - sink_fmt = adv748x_csi2_get_pad_format(sd, cfg, + sink_fmt = adv748x_csi2_get_pad_format(sd, sd_state, ADV748X_CSI2_SINK, sdformat->which); diff --git a/drivers/media/i2c/adv748x/adv748x-hdmi.c b/drivers/media/i2c/adv748x/adv748x-hdmi.c index c557f8fdf11a..52fa7bd75660 100644 --- a/drivers/media/i2c/adv748x/adv748x-hdmi.c +++ b/drivers/media/i2c/adv748x/adv748x-hdmi.c @@ -409,7 +409,7 @@ static int adv748x_hdmi_propagate_pixelrate(struct adv748x_hdmi *hdmi) } static int adv748x_hdmi_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->index != 0) @@ -421,7 +421,7 @@ static int adv748x_hdmi_enum_mbus_code(struct v4l2_subdev *sd, } static int adv748x_hdmi_get_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *sdformat) { struct adv748x_hdmi *hdmi = adv748x_sd_to_hdmi(sd); @@ -431,7 +431,8 @@ static int adv748x_hdmi_get_format(struct v4l2_subdev *sd, return -EINVAL; if (sdformat->which == V4L2_SUBDEV_FORMAT_TRY) { - mbusformat = v4l2_subdev_get_try_format(sd, cfg, sdformat->pad); + mbusformat = v4l2_subdev_get_try_format(sd, sd_state, + sdformat->pad); sdformat->format = *mbusformat; } else { adv748x_hdmi_fill_format(hdmi, &sdformat->format); @@ -442,7 +443,7 @@ static int adv748x_hdmi_get_format(struct v4l2_subdev *sd, } static int adv748x_hdmi_set_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *sdformat) { struct v4l2_mbus_framefmt *mbusformat; @@ -451,9 +452,9 @@ static int adv748x_hdmi_set_format(struct v4l2_subdev *sd, return -EINVAL; if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE) - return adv748x_hdmi_get_format(sd, cfg, sdformat); + return adv748x_hdmi_get_format(sd, sd_state, sdformat); - mbusformat = v4l2_subdev_get_try_format(sd, cfg, sdformat->pad); + mbusformat = v4l2_subdev_get_try_format(sd, sd_state, sdformat->pad); *mbusformat = sdformat->format; return 0; diff --git a/drivers/media/i2c/adv7511-v4l2.c b/drivers/media/i2c/adv7511-v4l2.c index 5fc6c06edda1..41f4e749a859 100644 --- a/drivers/media/i2c/adv7511-v4l2.c +++ b/drivers/media/i2c/adv7511-v4l2.c @@ -1216,7 +1216,7 @@ static int adv7511_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) } static int adv7511_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->pad != 0) @@ -1247,7 +1247,7 @@ static void adv7511_fill_format(struct adv7511_state *state, } static int adv7511_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct adv7511_state *state = get_adv7511_state(sd); @@ -1261,7 +1261,7 @@ static int adv7511_get_fmt(struct v4l2_subdev *sd, if (format->which == V4L2_SUBDEV_FORMAT_TRY) { struct v4l2_mbus_framefmt *fmt; - fmt = v4l2_subdev_get_try_format(sd, cfg, format->pad); + fmt = v4l2_subdev_get_try_format(sd, sd_state, format->pad); format->format.code = fmt->code; format->format.colorspace = fmt->colorspace; format->format.ycbcr_enc = fmt->ycbcr_enc; @@ -1279,7 +1279,7 @@ static int adv7511_get_fmt(struct v4l2_subdev *sd, } static int adv7511_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct adv7511_state *state = get_adv7511_state(sd); @@ -1316,7 +1316,7 @@ static int adv7511_set_fmt(struct v4l2_subdev *sd, if (format->which == V4L2_SUBDEV_FORMAT_TRY) { struct v4l2_mbus_framefmt *fmt; - fmt = v4l2_subdev_get_try_format(sd, cfg, format->pad); + fmt = v4l2_subdev_get_try_format(sd, sd_state, format->pad); fmt->code = format->format.code; fmt->colorspace = format->format.colorspace; fmt->ycbcr_enc = format->format.ycbcr_enc; diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index 3049aa2fd0f0..122e1fdccd96 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -1833,7 +1833,7 @@ static int adv76xx_s_routing(struct v4l2_subdev *sd, } static int adv76xx_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct adv76xx_state *state = to_state(sd); @@ -1913,7 +1913,7 @@ static void adv76xx_setup_format(struct adv76xx_state *state) } static int adv76xx_get_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct adv76xx_state *state = to_state(sd); @@ -1926,7 +1926,7 @@ static int adv76xx_get_format(struct v4l2_subdev *sd, if (format->which == V4L2_SUBDEV_FORMAT_TRY) { struct v4l2_mbus_framefmt *fmt; - fmt = v4l2_subdev_get_try_format(sd, cfg, format->pad); + fmt = v4l2_subdev_get_try_format(sd, sd_state, format->pad); format->format.code = fmt->code; } else { format->format.code = state->format->code; @@ -1936,7 +1936,7 @@ static int adv76xx_get_format(struct v4l2_subdev *sd, } static int adv76xx_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct adv76xx_state *state = to_state(sd); @@ -1956,7 +1956,7 @@ static int adv76xx_get_selection(struct v4l2_subdev *sd, } static int adv76xx_set_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct adv76xx_state *state = to_state(sd); @@ -1975,7 +1975,7 @@ static int adv76xx_set_format(struct v4l2_subdev *sd, if (format->which == V4L2_SUBDEV_FORMAT_TRY) { struct v4l2_mbus_framefmt *fmt; - fmt = v4l2_subdev_get_try_format(sd, cfg, format->pad); + fmt = v4l2_subdev_get_try_format(sd, sd_state, format->pad); fmt->code = format->format.code; } else { state->format = info; diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c index 78e61fe6f2f0..263713963a00 100644 --- a/drivers/media/i2c/adv7842.c +++ b/drivers/media/i2c/adv7842.c @@ -1993,7 +1993,7 @@ static int adv7842_s_routing(struct v4l2_subdev *sd, } static int adv7842_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->index >= ARRAY_SIZE(adv7842_formats)) @@ -2069,7 +2069,7 @@ static void adv7842_setup_format(struct adv7842_state *state) } static int adv7842_get_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct adv7842_state *state = to_state(sd); @@ -2097,7 +2097,7 @@ static int adv7842_get_format(struct v4l2_subdev *sd, if (format->which == V4L2_SUBDEV_FORMAT_TRY) { struct v4l2_mbus_framefmt *fmt; - fmt = v4l2_subdev_get_try_format(sd, cfg, format->pad); + fmt = v4l2_subdev_get_try_format(sd, sd_state, format->pad); format->format.code = fmt->code; } else { format->format.code = state->format->code; @@ -2107,7 +2107,7 @@ static int adv7842_get_format(struct v4l2_subdev *sd, } static int adv7842_set_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct adv7842_state *state = to_state(sd); @@ -2117,7 +2117,7 @@ static int adv7842_set_format(struct v4l2_subdev *sd, return -EINVAL; if (state->mode == ADV7842_MODE_SDP) - return adv7842_get_format(sd, cfg, format); + return adv7842_get_format(sd, sd_state, format); info = adv7842_format_info(state, format->format.code); if (info == NULL) @@ -2129,7 +2129,7 @@ static int adv7842_set_format(struct v4l2_subdev *sd, if (format->which == V4L2_SUBDEV_FORMAT_TRY) { struct v4l2_mbus_framefmt *fmt; - fmt = v4l2_subdev_get_try_format(sd, cfg, format->pad); + fmt = v4l2_subdev_get_try_format(sd, sd_state, format->pad); fmt->code = format->format.code; } else { state->format = info; diff --git a/drivers/media/i2c/ak881x.c b/drivers/media/i2c/ak881x.c index 1adaf470c75a..dc569d5a4d9d 100644 --- a/drivers/media/i2c/ak881x.c +++ b/drivers/media/i2c/ak881x.c @@ -91,7 +91,7 @@ static int ak881x_s_register(struct v4l2_subdev *sd, #endif static int ak881x_fill_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *mf = &format->format; @@ -111,7 +111,7 @@ static int ak881x_fill_fmt(struct v4l2_subdev *sd, } static int ak881x_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->pad || code->index) @@ -122,7 +122,7 @@ static int ak881x_enum_mbus_code(struct v4l2_subdev *sd, } static int ak881x_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct i2c_client *client = v4l2_get_subdevdata(sd); diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index a349189a38db..a9403a227c6b 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -1944,7 +1944,7 @@ static int ccs_set_stream(struct v4l2_subdev *subdev, int enable) } static int ccs_enum_mbus_code(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct i2c_client *client = v4l2_get_subdevdata(subdev); @@ -1997,13 +1997,13 @@ static u32 __ccs_get_mbus_code(struct v4l2_subdev *subdev, unsigned int pad) } static int __ccs_get_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct ccs_subdev *ssd = to_ccs_subdev(subdev); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - fmt->format = *v4l2_subdev_get_try_format(subdev, cfg, + fmt->format = *v4l2_subdev_get_try_format(subdev, sd_state, fmt->pad); } else { struct v4l2_rect *r; @@ -2023,21 +2023,21 @@ static int __ccs_get_format(struct v4l2_subdev *subdev, } static int ccs_get_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct ccs_sensor *sensor = to_ccs_sensor(subdev); int rval; mutex_lock(&sensor->mutex); - rval = __ccs_get_format(subdev, cfg, fmt); + rval = __ccs_get_format(subdev, sd_state, fmt); mutex_unlock(&sensor->mutex); return rval; } static void ccs_get_crop_compose(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_rect **crops, struct v4l2_rect **comps, int which) { @@ -2054,24 +2054,25 @@ static void ccs_get_crop_compose(struct v4l2_subdev *subdev, if (crops) { for (i = 0; i < subdev->entity.num_pads; i++) crops[i] = v4l2_subdev_get_try_crop(subdev, - cfg, i); + sd_state, + i); } if (comps) - *comps = v4l2_subdev_get_try_compose(subdev, cfg, + *comps = v4l2_subdev_get_try_compose(subdev, sd_state, CCS_PAD_SINK); } } /* Changes require propagation only on sink pad. */ static void ccs_propagate(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, int which, + struct v4l2_subdev_state *sd_state, int which, int target) { struct ccs_sensor *sensor = to_ccs_sensor(subdev); struct ccs_subdev *ssd = to_ccs_subdev(subdev); struct v4l2_rect *comp, *crops[CCS_PADS]; - ccs_get_crop_compose(subdev, cfg, crops, &comp, which); + ccs_get_crop_compose(subdev, sd_state, crops, &comp, which); switch (target) { case V4L2_SEL_TGT_CROP: @@ -2111,7 +2112,7 @@ static const struct ccs_csi_data_format } static int ccs_set_format_source(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct ccs_sensor *sensor = to_ccs_sensor(subdev); @@ -2122,7 +2123,7 @@ static int ccs_set_format_source(struct v4l2_subdev *subdev, unsigned int i; int rval; - rval = __ccs_get_format(subdev, cfg, fmt); + rval = __ccs_get_format(subdev, sd_state, fmt); if (rval) return rval; @@ -2164,7 +2165,7 @@ static int ccs_set_format_source(struct v4l2_subdev *subdev, } static int ccs_set_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct ccs_sensor *sensor = to_ccs_sensor(subdev); @@ -2176,7 +2177,7 @@ static int ccs_set_format(struct v4l2_subdev *subdev, if (fmt->pad == ssd->source_pad) { int rval; - rval = ccs_set_format_source(subdev, cfg, fmt); + rval = ccs_set_format_source(subdev, sd_state, fmt); mutex_unlock(&sensor->mutex); @@ -2198,7 +2199,7 @@ static int ccs_set_format(struct v4l2_subdev *subdev, CCS_LIM(sensor, MIN_Y_OUTPUT_SIZE), CCS_LIM(sensor, MAX_Y_OUTPUT_SIZE)); - ccs_get_crop_compose(subdev, cfg, crops, NULL, fmt->which); + ccs_get_crop_compose(subdev, sd_state, crops, NULL, fmt->which); crops[ssd->sink_pad]->left = 0; crops[ssd->sink_pad]->top = 0; @@ -2206,7 +2207,7 @@ static int ccs_set_format(struct v4l2_subdev *subdev, crops[ssd->sink_pad]->height = fmt->format.height; if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) ssd->sink_fmt = *crops[ssd->sink_pad]; - ccs_propagate(subdev, cfg, fmt->which, V4L2_SEL_TGT_CROP); + ccs_propagate(subdev, sd_state, fmt->which, V4L2_SEL_TGT_CROP); mutex_unlock(&sensor->mutex); @@ -2258,7 +2259,7 @@ static int scaling_goodness(struct v4l2_subdev *subdev, int w, int ask_w, } static void ccs_set_compose_binner(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel, struct v4l2_rect **crops, struct v4l2_rect *comp) @@ -2306,7 +2307,7 @@ static void ccs_set_compose_binner(struct v4l2_subdev *subdev, * result. */ static void ccs_set_compose_scaler(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel, struct v4l2_rect **crops, struct v4l2_rect *comp) @@ -2421,25 +2422,25 @@ static void ccs_set_compose_scaler(struct v4l2_subdev *subdev, } /* We're only called on source pads. This function sets scaling. */ static int ccs_set_compose(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct ccs_sensor *sensor = to_ccs_sensor(subdev); struct ccs_subdev *ssd = to_ccs_subdev(subdev); struct v4l2_rect *comp, *crops[CCS_PADS]; - ccs_get_crop_compose(subdev, cfg, crops, &comp, sel->which); + ccs_get_crop_compose(subdev, sd_state, crops, &comp, sel->which); sel->r.top = 0; sel->r.left = 0; if (ssd == sensor->binner) - ccs_set_compose_binner(subdev, cfg, sel, crops, comp); + ccs_set_compose_binner(subdev, sd_state, sel, crops, comp); else - ccs_set_compose_scaler(subdev, cfg, sel, crops, comp); + ccs_set_compose_scaler(subdev, sd_state, sel, crops, comp); *comp = sel->r; - ccs_propagate(subdev, cfg, sel->which, V4L2_SEL_TGT_COMPOSE); + ccs_propagate(subdev, sd_state, sel->which, V4L2_SEL_TGT_COMPOSE); if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) return ccs_pll_blanking_update(sensor); @@ -2486,7 +2487,7 @@ static int __ccs_sel_supported(struct v4l2_subdev *subdev, } static int ccs_set_crop(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct ccs_sensor *sensor = to_ccs_sensor(subdev); @@ -2494,7 +2495,7 @@ static int ccs_set_crop(struct v4l2_subdev *subdev, struct v4l2_rect *src_size, *crops[CCS_PADS]; struct v4l2_rect _r; - ccs_get_crop_compose(subdev, cfg, crops, NULL, sel->which); + ccs_get_crop_compose(subdev, sd_state, crops, NULL, sel->which); if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) { if (sel->pad == ssd->sink_pad) @@ -2505,16 +2506,18 @@ static int ccs_set_crop(struct v4l2_subdev *subdev, if (sel->pad == ssd->sink_pad) { _r.left = 0; _r.top = 0; - _r.width = v4l2_subdev_get_try_format(subdev, cfg, + _r.width = v4l2_subdev_get_try_format(subdev, + sd_state, sel->pad) ->width; - _r.height = v4l2_subdev_get_try_format(subdev, cfg, + _r.height = v4l2_subdev_get_try_format(subdev, + sd_state, sel->pad) ->height; src_size = &_r; } else { src_size = v4l2_subdev_get_try_compose( - subdev, cfg, ssd->sink_pad); + subdev, sd_state, ssd->sink_pad); } } @@ -2532,7 +2535,7 @@ static int ccs_set_crop(struct v4l2_subdev *subdev, *crops[sel->pad] = sel->r; if (ssd != sensor->pixel_array && sel->pad == CCS_PAD_SINK) - ccs_propagate(subdev, cfg, sel->which, V4L2_SEL_TGT_CROP); + ccs_propagate(subdev, sd_state, sel->which, V4L2_SEL_TGT_CROP); return 0; } @@ -2546,7 +2549,7 @@ static void ccs_get_native_size(struct ccs_subdev *ssd, struct v4l2_rect *r) } static int __ccs_get_selection(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct ccs_sensor *sensor = to_ccs_sensor(subdev); @@ -2559,13 +2562,14 @@ static int __ccs_get_selection(struct v4l2_subdev *subdev, if (ret) return ret; - ccs_get_crop_compose(subdev, cfg, crops, &comp, sel->which); + ccs_get_crop_compose(subdev, sd_state, crops, &comp, sel->which); if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) { sink_fmt = ssd->sink_fmt; } else { struct v4l2_mbus_framefmt *fmt = - v4l2_subdev_get_try_format(subdev, cfg, ssd->sink_pad); + v4l2_subdev_get_try_format(subdev, sd_state, + ssd->sink_pad); sink_fmt.left = 0; sink_fmt.top = 0; @@ -2596,21 +2600,21 @@ static int __ccs_get_selection(struct v4l2_subdev *subdev, } static int ccs_get_selection(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct ccs_sensor *sensor = to_ccs_sensor(subdev); int rval; mutex_lock(&sensor->mutex); - rval = __ccs_get_selection(subdev, cfg, sel); + rval = __ccs_get_selection(subdev, sd_state, sel); mutex_unlock(&sensor->mutex); return rval; } static int ccs_set_selection(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct ccs_sensor *sensor = to_ccs_sensor(subdev); @@ -2634,10 +2638,10 @@ static int ccs_set_selection(struct v4l2_subdev *subdev, switch (sel->target) { case V4L2_SEL_TGT_CROP: - ret = ccs_set_crop(subdev, cfg, sel); + ret = ccs_set_crop(subdev, sd_state, sel); break; case V4L2_SEL_TGT_COMPOSE: - ret = ccs_set_compose(subdev, cfg, sel); + ret = ccs_set_compose(subdev, sd_state, sel); break; default: ret = -EINVAL; @@ -3028,9 +3032,9 @@ static int ccs_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) for (i = 0; i < ssd->npads; i++) { struct v4l2_mbus_framefmt *try_fmt = - v4l2_subdev_get_try_format(sd, fh->pad, i); + v4l2_subdev_get_try_format(sd, fh->state, i); struct v4l2_rect *try_crop = - v4l2_subdev_get_try_crop(sd, fh->pad, i); + v4l2_subdev_get_try_crop(sd, fh->state, i); struct v4l2_rect *try_comp; ccs_get_native_size(ssd, try_crop); @@ -3043,7 +3047,7 @@ static int ccs_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) if (ssd != sensor->pixel_array) continue; - try_comp = v4l2_subdev_get_try_compose(sd, fh->pad, i); + try_comp = v4l2_subdev_get_try_compose(sd, fh->state, i); *try_comp = *try_crop; } diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c index e2e935f78986..dc31944c7d5b 100644 --- a/drivers/media/i2c/cx25840/cx25840-core.c +++ b/drivers/media/i2c/cx25840/cx25840-core.c @@ -1746,7 +1746,7 @@ static int cx25840_s_ctrl(struct v4l2_ctrl *ctrl) /* ----------------------------------------------------------------------- */ static int cx25840_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *fmt = &format->format; diff --git a/drivers/media/i2c/et8ek8/et8ek8_driver.c b/drivers/media/i2c/et8ek8/et8ek8_driver.c index bb3eac5e005e..c7b91c0c03b5 100644 --- a/drivers/media/i2c/et8ek8/et8ek8_driver.c +++ b/drivers/media/i2c/et8ek8/et8ek8_driver.c @@ -882,7 +882,7 @@ out: */ #define MAX_FMTS 4 static int et8ek8_enum_mbus_code(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct et8ek8_reglist **list = @@ -920,7 +920,7 @@ static int et8ek8_enum_mbus_code(struct v4l2_subdev *subdev, } static int et8ek8_enum_frame_size(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { struct et8ek8_reglist **list = @@ -958,7 +958,7 @@ static int et8ek8_enum_frame_size(struct v4l2_subdev *subdev, } static int et8ek8_enum_frame_ival(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_interval_enum *fie) { struct et8ek8_reglist **list = @@ -990,12 +990,13 @@ static int et8ek8_enum_frame_ival(struct v4l2_subdev *subdev, static struct v4l2_mbus_framefmt * __et8ek8_get_pad_format(struct et8ek8_sensor *sensor, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which) { switch (which) { case V4L2_SUBDEV_FORMAT_TRY: - return v4l2_subdev_get_try_format(&sensor->subdev, cfg, pad); + return v4l2_subdev_get_try_format(&sensor->subdev, sd_state, + pad); case V4L2_SUBDEV_FORMAT_ACTIVE: return &sensor->format; default: @@ -1004,13 +1005,14 @@ __et8ek8_get_pad_format(struct et8ek8_sensor *sensor, } static int et8ek8_get_pad_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct et8ek8_sensor *sensor = to_et8ek8_sensor(subdev); struct v4l2_mbus_framefmt *format; - format = __et8ek8_get_pad_format(sensor, cfg, fmt->pad, fmt->which); + format = __et8ek8_get_pad_format(sensor, sd_state, fmt->pad, + fmt->which); if (!format) return -EINVAL; @@ -1020,14 +1022,15 @@ static int et8ek8_get_pad_format(struct v4l2_subdev *subdev, } static int et8ek8_set_pad_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct et8ek8_sensor *sensor = to_et8ek8_sensor(subdev); struct v4l2_mbus_framefmt *format; struct et8ek8_reglist *reglist; - format = __et8ek8_get_pad_format(sensor, cfg, fmt->pad, fmt->which); + format = __et8ek8_get_pad_format(sensor, sd_state, fmt->pad, + fmt->which); if (!format) return -EINVAL; @@ -1327,7 +1330,7 @@ static int et8ek8_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) struct et8ek8_reglist *reglist; reglist = et8ek8_reglist_find_type(&meta_reglist, ET8EK8_REGLIST_MODE); - format = __et8ek8_get_pad_format(sensor, fh->pad, 0, + format = __et8ek8_get_pad_format(sensor, fh->state, 0, V4L2_SUBDEV_FORMAT_TRY); et8ek8_reglist_to_mbus(reglist, format); diff --git a/drivers/media/i2c/hi556.c b/drivers/media/i2c/hi556.c index 627ccfa34835..8db1cbedc1fd 100644 --- a/drivers/media/i2c/hi556.c +++ b/drivers/media/i2c/hi556.c @@ -875,7 +875,7 @@ error: } static int hi556_set_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct hi556 *hi556 = to_hi556(sd); @@ -890,7 +890,7 @@ static int hi556_set_format(struct v4l2_subdev *sd, mutex_lock(&hi556->mutex); hi556_assign_pad_format(mode, &fmt->format); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format; + *v4l2_subdev_get_try_format(sd, sd_state, fmt->pad) = fmt->format; } else { hi556->cur_mode = mode; __v4l2_ctrl_s_ctrl(hi556->link_freq, mode->link_freq_index); @@ -917,14 +917,15 @@ static int hi556_set_format(struct v4l2_subdev *sd, } static int hi556_get_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct hi556 *hi556 = to_hi556(sd); mutex_lock(&hi556->mutex); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) - fmt->format = *v4l2_subdev_get_try_format(&hi556->sd, cfg, + fmt->format = *v4l2_subdev_get_try_format(&hi556->sd, + sd_state, fmt->pad); else hi556_assign_pad_format(hi556->cur_mode, &fmt->format); @@ -935,7 +936,7 @@ static int hi556_get_format(struct v4l2_subdev *sd, } static int hi556_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->index > 0) @@ -947,7 +948,7 @@ static int hi556_enum_mbus_code(struct v4l2_subdev *sd, } static int hi556_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { if (fse->index >= ARRAY_SIZE(supported_modes)) @@ -970,7 +971,7 @@ static int hi556_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) mutex_lock(&hi556->mutex); hi556_assign_pad_format(&supported_modes[0], - v4l2_subdev_get_try_format(sd, fh->pad, 0)); + v4l2_subdev_get_try_format(sd, fh->state, 0)); mutex_unlock(&hi556->mutex); return 0; diff --git a/drivers/media/i2c/imx208.c b/drivers/media/i2c/imx208.c index 9ed261ea7255..6f3d9c1b5879 100644 --- a/drivers/media/i2c/imx208.c +++ b/drivers/media/i2c/imx208.c @@ -395,7 +395,7 @@ static int imx208_write_regs(struct imx208 *imx208, static int imx208_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { struct v4l2_mbus_framefmt *try_fmt = - v4l2_subdev_get_try_format(sd, fh->pad, 0); + v4l2_subdev_get_try_format(sd, fh->state, 0); /* Initialize try_fmt */ try_fmt->width = supported_modes[0].width; @@ -500,7 +500,7 @@ static const struct v4l2_ctrl_config imx208_digital_gain_control = { }; static int imx208_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct imx208 *imx208 = to_imx208(sd); @@ -514,7 +514,7 @@ static int imx208_enum_mbus_code(struct v4l2_subdev *sd, } static int imx208_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { struct imx208 *imx208 = to_imx208(sd); @@ -544,11 +544,12 @@ static void imx208_mode_to_pad_format(struct imx208 *imx208, } static int __imx208_get_pad_format(struct imx208 *imx208, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) - fmt->format = *v4l2_subdev_get_try_format(&imx208->sd, cfg, + fmt->format = *v4l2_subdev_get_try_format(&imx208->sd, + sd_state, fmt->pad); else imx208_mode_to_pad_format(imx208, imx208->cur_mode, fmt); @@ -557,21 +558,21 @@ static int __imx208_get_pad_format(struct imx208 *imx208, } static int imx208_get_pad_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct imx208 *imx208 = to_imx208(sd); int ret; mutex_lock(&imx208->imx208_mx); - ret = __imx208_get_pad_format(imx208, cfg, fmt); + ret = __imx208_get_pad_format(imx208, sd_state, fmt); mutex_unlock(&imx208->imx208_mx); return ret; } static int imx208_set_pad_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct imx208 *imx208 = to_imx208(sd); @@ -590,7 +591,7 @@ static int imx208_set_pad_format(struct v4l2_subdev *sd, fmt->format.width, fmt->format.height); imx208_mode_to_pad_format(imx208, mode, fmt); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format; + *v4l2_subdev_get_try_format(sd, sd_state, fmt->pad) = fmt->format; } else { imx208->cur_mode = mode; __v4l2_ctrl_s_ctrl(imx208->link_freq, mode->link_freq_index); diff --git a/drivers/media/i2c/imx214.c b/drivers/media/i2c/imx214.c index 1a770a530cf5..83c1737abeec 100644 --- a/drivers/media/i2c/imx214.c +++ b/drivers/media/i2c/imx214.c @@ -474,7 +474,7 @@ static int __maybe_unused imx214_power_off(struct device *dev) } static int imx214_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->index > 0) @@ -486,7 +486,7 @@ static int imx214_enum_mbus_code(struct v4l2_subdev *sd, } static int imx214_enum_frame_size(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { if (fse->code != IMX214_MBUS_CODE) @@ -534,13 +534,13 @@ static const struct v4l2_subdev_core_ops imx214_core_ops = { static struct v4l2_mbus_framefmt * __imx214_get_pad_format(struct imx214 *imx214, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which) { switch (which) { case V4L2_SUBDEV_FORMAT_TRY: - return v4l2_subdev_get_try_format(&imx214->sd, cfg, pad); + return v4l2_subdev_get_try_format(&imx214->sd, sd_state, pad); case V4L2_SUBDEV_FORMAT_ACTIVE: return &imx214->fmt; default: @@ -549,13 +549,14 @@ __imx214_get_pad_format(struct imx214 *imx214, } static int imx214_get_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct imx214 *imx214 = to_imx214(sd); mutex_lock(&imx214->mutex); - format->format = *__imx214_get_pad_format(imx214, cfg, format->pad, + format->format = *__imx214_get_pad_format(imx214, sd_state, + format->pad, format->which); mutex_unlock(&imx214->mutex); @@ -563,12 +564,13 @@ static int imx214_get_format(struct v4l2_subdev *sd, } static struct v4l2_rect * -__imx214_get_pad_crop(struct imx214 *imx214, struct v4l2_subdev_pad_config *cfg, +__imx214_get_pad_crop(struct imx214 *imx214, + struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which) { switch (which) { case V4L2_SUBDEV_FORMAT_TRY: - return v4l2_subdev_get_try_crop(&imx214->sd, cfg, pad); + return v4l2_subdev_get_try_crop(&imx214->sd, sd_state, pad); case V4L2_SUBDEV_FORMAT_ACTIVE: return &imx214->crop; default: @@ -577,7 +579,7 @@ __imx214_get_pad_crop(struct imx214 *imx214, struct v4l2_subdev_pad_config *cfg, } static int imx214_set_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct imx214 *imx214 = to_imx214(sd); @@ -587,7 +589,8 @@ static int imx214_set_format(struct v4l2_subdev *sd, mutex_lock(&imx214->mutex); - __crop = __imx214_get_pad_crop(imx214, cfg, format->pad, format->which); + __crop = __imx214_get_pad_crop(imx214, sd_state, format->pad, + format->which); mode = v4l2_find_nearest_size(imx214_modes, ARRAY_SIZE(imx214_modes), width, height, @@ -597,7 +600,7 @@ static int imx214_set_format(struct v4l2_subdev *sd, __crop->width = mode->width; __crop->height = mode->height; - __format = __imx214_get_pad_format(imx214, cfg, format->pad, + __format = __imx214_get_pad_format(imx214, sd_state, format->pad, format->which); __format->width = __crop->width; __format->height = __crop->height; @@ -617,7 +620,7 @@ static int imx214_set_format(struct v4l2_subdev *sd, } static int imx214_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct imx214 *imx214 = to_imx214(sd); @@ -626,22 +629,22 @@ static int imx214_get_selection(struct v4l2_subdev *sd, return -EINVAL; mutex_lock(&imx214->mutex); - sel->r = *__imx214_get_pad_crop(imx214, cfg, sel->pad, + sel->r = *__imx214_get_pad_crop(imx214, sd_state, sel->pad, sel->which); mutex_unlock(&imx214->mutex); return 0; } static int imx214_entity_init_cfg(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg) + struct v4l2_subdev_state *sd_state) { struct v4l2_subdev_format fmt = { }; - fmt.which = cfg ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; + fmt.which = sd_state ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; fmt.format.width = imx214_modes[0].width; fmt.format.height = imx214_modes[0].height; - imx214_set_format(subdev, cfg, &fmt); + imx214_set_format(subdev, sd_state, &fmt); return 0; } @@ -808,7 +811,7 @@ static int imx214_g_frame_interval(struct v4l2_subdev *subdev, } static int imx214_enum_frame_interval(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_interval_enum *fie) { const struct imx214_mode *mode; diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c index 74a0bf9b088b..e10af3f74b38 100644 --- a/drivers/media/i2c/imx219.c +++ b/drivers/media/i2c/imx219.c @@ -689,7 +689,7 @@ static int imx219_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { struct imx219 *imx219 = to_imx219(sd); struct v4l2_mbus_framefmt *try_fmt = - v4l2_subdev_get_try_format(sd, fh->pad, 0); + v4l2_subdev_get_try_format(sd, fh->state, 0); struct v4l2_rect *try_crop; mutex_lock(&imx219->mutex); @@ -702,7 +702,7 @@ static int imx219_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) try_fmt->field = V4L2_FIELD_NONE; /* Initialize try_crop rectangle. */ - try_crop = v4l2_subdev_get_try_crop(sd, fh->pad, 0); + try_crop = v4l2_subdev_get_try_crop(sd, fh->state, 0); try_crop->top = IMX219_PIXEL_ARRAY_TOP; try_crop->left = IMX219_PIXEL_ARRAY_LEFT; try_crop->width = IMX219_PIXEL_ARRAY_WIDTH; @@ -803,7 +803,7 @@ static const struct v4l2_ctrl_ops imx219_ctrl_ops = { }; static int imx219_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct imx219 *imx219 = to_imx219(sd); @@ -819,7 +819,7 @@ static int imx219_enum_mbus_code(struct v4l2_subdev *sd, } static int imx219_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { struct imx219 *imx219 = to_imx219(sd); @@ -863,12 +863,13 @@ static void imx219_update_pad_format(struct imx219 *imx219, } static int __imx219_get_pad_format(struct imx219 *imx219, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { struct v4l2_mbus_framefmt *try_fmt = - v4l2_subdev_get_try_format(&imx219->sd, cfg, fmt->pad); + v4l2_subdev_get_try_format(&imx219->sd, sd_state, + fmt->pad); /* update the code which could change due to vflip or hflip: */ try_fmt->code = imx219_get_format_code(imx219, try_fmt->code); fmt->format = *try_fmt; @@ -882,21 +883,21 @@ static int __imx219_get_pad_format(struct imx219 *imx219, } static int imx219_get_pad_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct imx219 *imx219 = to_imx219(sd); int ret; mutex_lock(&imx219->mutex); - ret = __imx219_get_pad_format(imx219, cfg, fmt); + ret = __imx219_get_pad_format(imx219, sd_state, fmt); mutex_unlock(&imx219->mutex); return ret; } static int imx219_set_pad_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct imx219 *imx219 = to_imx219(sd); @@ -922,7 +923,7 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd, fmt->format.width, fmt->format.height); imx219_update_pad_format(imx219, mode, fmt); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - framefmt = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); *framefmt = fmt->format; } else if (imx219->mode != mode || imx219->fmt.code != fmt->format.code) { @@ -979,12 +980,13 @@ static int imx219_set_framefmt(struct imx219 *imx219) } static const struct v4l2_rect * -__imx219_get_pad_crop(struct imx219 *imx219, struct v4l2_subdev_pad_config *cfg, +__imx219_get_pad_crop(struct imx219 *imx219, + struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which) { switch (which) { case V4L2_SUBDEV_FORMAT_TRY: - return v4l2_subdev_get_try_crop(&imx219->sd, cfg, pad); + return v4l2_subdev_get_try_crop(&imx219->sd, sd_state, pad); case V4L2_SUBDEV_FORMAT_ACTIVE: return &imx219->mode->crop; } @@ -993,7 +995,7 @@ __imx219_get_pad_crop(struct imx219 *imx219, struct v4l2_subdev_pad_config *cfg, } static int imx219_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { switch (sel->target) { @@ -1001,7 +1003,7 @@ static int imx219_get_selection(struct v4l2_subdev *sd, struct imx219 *imx219 = to_imx219(sd); mutex_lock(&imx219->mutex); - sel->r = *__imx219_get_pad_crop(imx219, cfg, sel->pad, + sel->r = *__imx219_get_pad_crop(imx219, sd_state, sel->pad, sel->which); mutex_unlock(&imx219->mutex); diff --git a/drivers/media/i2c/imx258.c b/drivers/media/i2c/imx258.c index 90529424d5b6..7ab9e5f9f267 100644 --- a/drivers/media/i2c/imx258.c +++ b/drivers/media/i2c/imx258.c @@ -710,7 +710,7 @@ static int imx258_write_regs(struct imx258 *imx258, static int imx258_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { struct v4l2_mbus_framefmt *try_fmt = - v4l2_subdev_get_try_format(sd, fh->pad, 0); + v4l2_subdev_get_try_format(sd, fh->state, 0); /* Initialize try_fmt */ try_fmt->width = supported_modes[0].width; @@ -820,7 +820,7 @@ static const struct v4l2_ctrl_ops imx258_ctrl_ops = { }; static int imx258_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { /* Only one bayer order(GRBG) is supported */ @@ -833,7 +833,7 @@ static int imx258_enum_mbus_code(struct v4l2_subdev *sd, } static int imx258_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { if (fse->index >= ARRAY_SIZE(supported_modes)) @@ -860,11 +860,12 @@ static void imx258_update_pad_format(const struct imx258_mode *mode, } static int __imx258_get_pad_format(struct imx258 *imx258, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) - fmt->format = *v4l2_subdev_get_try_format(&imx258->sd, cfg, + fmt->format = *v4l2_subdev_get_try_format(&imx258->sd, + sd_state, fmt->pad); else imx258_update_pad_format(imx258->cur_mode, fmt); @@ -873,21 +874,21 @@ static int __imx258_get_pad_format(struct imx258 *imx258, } static int imx258_get_pad_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct imx258 *imx258 = to_imx258(sd); int ret; mutex_lock(&imx258->mutex); - ret = __imx258_get_pad_format(imx258, cfg, fmt); + ret = __imx258_get_pad_format(imx258, sd_state, fmt); mutex_unlock(&imx258->mutex); return ret; } static int imx258_set_pad_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct imx258 *imx258 = to_imx258(sd); @@ -909,7 +910,7 @@ static int imx258_set_pad_format(struct v4l2_subdev *sd, fmt->format.width, fmt->format.height); imx258_update_pad_format(mode, fmt); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - framefmt = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); *framefmt = fmt->format; } else { imx258->cur_mode = mode; diff --git a/drivers/media/i2c/imx274.c b/drivers/media/i2c/imx274.c index ee2127436f0b..0dce92872176 100644 --- a/drivers/media/i2c/imx274.c +++ b/drivers/media/i2c/imx274.c @@ -996,7 +996,7 @@ static int imx274_binning_goodness(struct stimx274 *imx274, * Must be called with imx274->lock locked. * * @imx274: The device object - * @cfg: The pad config we are editing for TRY requests + * @sd_state: The subdev state we are editing for TRY requests * @which: V4L2_SUBDEV_FORMAT_ACTIVE or V4L2_SUBDEV_FORMAT_TRY from the caller * @width: Input-output parameter: set to the desired width before * the call, contains the chosen value after returning successfully @@ -1005,7 +1005,7 @@ static int imx274_binning_goodness(struct stimx274 *imx274, * available (when called from set_fmt) */ static int __imx274_change_compose(struct stimx274 *imx274, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, u32 which, u32 *width, u32 *height, @@ -1019,8 +1019,8 @@ static int __imx274_change_compose(struct stimx274 *imx274, int best_goodness = INT_MIN; if (which == V4L2_SUBDEV_FORMAT_TRY) { - cur_crop = &cfg->try_crop; - tgt_fmt = &cfg->try_fmt; + cur_crop = &sd_state->pads->try_crop; + tgt_fmt = &sd_state->pads->try_fmt; } else { cur_crop = &imx274->crop; tgt_fmt = &imx274->format; @@ -1061,7 +1061,7 @@ static int __imx274_change_compose(struct stimx274 *imx274, /** * imx274_get_fmt - Get the pad format * @sd: Pointer to V4L2 Sub device structure - * @cfg: Pointer to sub device pad information structure + * @sd_state: Pointer to sub device state structure * @fmt: Pointer to pad level media bus format * * This function is used to get the pad format information. @@ -1069,7 +1069,7 @@ static int __imx274_change_compose(struct stimx274 *imx274, * Return: 0 on success */ static int imx274_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct stimx274 *imx274 = to_imx274(sd); @@ -1083,7 +1083,7 @@ static int imx274_get_fmt(struct v4l2_subdev *sd, /** * imx274_set_fmt - This is used to set the pad format * @sd: Pointer to V4L2 Sub device structure - * @cfg: Pointer to sub device pad information structure + * @sd_state: Pointer to sub device state information structure * @format: Pointer to pad level media bus format * * This function is used to set the pad format. @@ -1091,7 +1091,7 @@ static int imx274_get_fmt(struct v4l2_subdev *sd, * Return: 0 on success */ static int imx274_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *fmt = &format->format; @@ -1100,7 +1100,7 @@ static int imx274_set_fmt(struct v4l2_subdev *sd, mutex_lock(&imx274->lock); - err = __imx274_change_compose(imx274, cfg, format->which, + err = __imx274_change_compose(imx274, sd_state, format->which, &fmt->width, &fmt->height, 0); if (err) @@ -1113,7 +1113,7 @@ static int imx274_set_fmt(struct v4l2_subdev *sd, */ fmt->field = V4L2_FIELD_NONE; if (format->which == V4L2_SUBDEV_FORMAT_TRY) - cfg->try_fmt = *fmt; + sd_state->pads->try_fmt = *fmt; else imx274->format = *fmt; @@ -1124,7 +1124,7 @@ out: } static int imx274_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct stimx274 *imx274 = to_imx274(sd); @@ -1144,8 +1144,8 @@ static int imx274_get_selection(struct v4l2_subdev *sd, } if (sel->which == V4L2_SUBDEV_FORMAT_TRY) { - src_crop = &cfg->try_crop; - src_fmt = &cfg->try_fmt; + src_crop = &sd_state->pads->try_crop; + src_fmt = &sd_state->pads->try_fmt; } else { src_crop = &imx274->crop; src_fmt = &imx274->format; @@ -1179,7 +1179,7 @@ static int imx274_get_selection(struct v4l2_subdev *sd, } static int imx274_set_selection_crop(struct stimx274 *imx274, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct v4l2_rect *tgt_crop; @@ -1216,7 +1216,7 @@ static int imx274_set_selection_crop(struct stimx274 *imx274, sel->r = new_crop; if (sel->which == V4L2_SUBDEV_FORMAT_TRY) - tgt_crop = &cfg->try_crop; + tgt_crop = &sd_state->pads->try_crop; else tgt_crop = &imx274->crop; @@ -1230,7 +1230,7 @@ static int imx274_set_selection_crop(struct stimx274 *imx274, /* if crop size changed then reset the output image size */ if (size_changed) - __imx274_change_compose(imx274, cfg, sel->which, + __imx274_change_compose(imx274, sd_state, sel->which, &new_crop.width, &new_crop.height, sel->flags); @@ -1240,7 +1240,7 @@ static int imx274_set_selection_crop(struct stimx274 *imx274, } static int imx274_set_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct stimx274 *imx274 = to_imx274(sd); @@ -1249,13 +1249,13 @@ static int imx274_set_selection(struct v4l2_subdev *sd, return -EINVAL; if (sel->target == V4L2_SEL_TGT_CROP) - return imx274_set_selection_crop(imx274, cfg, sel); + return imx274_set_selection_crop(imx274, sd_state, sel); if (sel->target == V4L2_SEL_TGT_COMPOSE) { int err; mutex_lock(&imx274->lock); - err = __imx274_change_compose(imx274, cfg, sel->which, + err = __imx274_change_compose(imx274, sd_state, sel->which, &sel->r.width, &sel->r.height, sel->flags); mutex_unlock(&imx274->lock); diff --git a/drivers/media/i2c/imx290.c b/drivers/media/i2c/imx290.c index 06020e648a97..bf7a6c37ca5d 100644 --- a/drivers/media/i2c/imx290.c +++ b/drivers/media/i2c/imx290.c @@ -516,7 +516,7 @@ static const struct v4l2_ctrl_ops imx290_ctrl_ops = { }; static int imx290_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->index >= ARRAY_SIZE(imx290_formats)) @@ -528,7 +528,7 @@ static int imx290_enum_mbus_code(struct v4l2_subdev *sd, } static int imx290_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { const struct imx290 *imx290 = to_imx290(sd); @@ -550,7 +550,7 @@ static int imx290_enum_frame_size(struct v4l2_subdev *sd, } static int imx290_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct imx290 *imx290 = to_imx290(sd); @@ -559,7 +559,7 @@ static int imx290_get_fmt(struct v4l2_subdev *sd, mutex_lock(&imx290->lock); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) - framefmt = v4l2_subdev_get_try_format(&imx290->sd, cfg, + framefmt = v4l2_subdev_get_try_format(&imx290->sd, sd_state, fmt->pad); else framefmt = &imx290->current_format; @@ -596,8 +596,8 @@ static u64 imx290_calc_pixel_rate(struct imx290 *imx290) } static int imx290_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_format *fmt) + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_format *fmt) { struct imx290 *imx290 = to_imx290(sd); const struct imx290_mode *mode; @@ -624,7 +624,7 @@ static int imx290_set_fmt(struct v4l2_subdev *sd, fmt->format.field = V4L2_FIELD_NONE; if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - format = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + format = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); } else { format = &imx290->current_format; imx290->current_mode = mode; @@ -646,15 +646,15 @@ static int imx290_set_fmt(struct v4l2_subdev *sd, } static int imx290_entity_init_cfg(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg) + struct v4l2_subdev_state *sd_state) { struct v4l2_subdev_format fmt = { 0 }; - fmt.which = cfg ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; + fmt.which = sd_state ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; fmt.format.width = 1920; fmt.format.height = 1080; - imx290_set_fmt(subdev, cfg, &fmt); + imx290_set_fmt(subdev, sd_state, &fmt); return 0; } diff --git a/drivers/media/i2c/imx319.c b/drivers/media/i2c/imx319.c index 4e0a8c9d271f..dba0854ab5aa 100644 --- a/drivers/media/i2c/imx319.c +++ b/drivers/media/i2c/imx319.c @@ -1860,7 +1860,7 @@ static int imx319_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { struct imx319 *imx319 = to_imx319(sd); struct v4l2_mbus_framefmt *try_fmt = - v4l2_subdev_get_try_format(sd, fh->pad, 0); + v4l2_subdev_get_try_format(sd, fh->state, 0); mutex_lock(&imx319->mutex); @@ -1947,7 +1947,7 @@ static const struct v4l2_ctrl_ops imx319_ctrl_ops = { }; static int imx319_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct imx319 *imx319 = to_imx319(sd); @@ -1963,7 +1963,7 @@ static int imx319_enum_mbus_code(struct v4l2_subdev *sd, } static int imx319_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { struct imx319 *imx319 = to_imx319(sd); @@ -1997,14 +1997,14 @@ static void imx319_update_pad_format(struct imx319 *imx319, } static int imx319_do_get_pad_format(struct imx319 *imx319, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct v4l2_mbus_framefmt *framefmt; struct v4l2_subdev *sd = &imx319->sd; if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - framefmt = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); fmt->format = *framefmt; } else { imx319_update_pad_format(imx319, imx319->cur_mode, fmt); @@ -2014,14 +2014,14 @@ static int imx319_do_get_pad_format(struct imx319 *imx319, } static int imx319_get_pad_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct imx319 *imx319 = to_imx319(sd); int ret; mutex_lock(&imx319->mutex); - ret = imx319_do_get_pad_format(imx319, cfg, fmt); + ret = imx319_do_get_pad_format(imx319, sd_state, fmt); mutex_unlock(&imx319->mutex); return ret; @@ -2029,7 +2029,7 @@ static int imx319_get_pad_format(struct v4l2_subdev *sd, static int imx319_set_pad_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct imx319 *imx319 = to_imx319(sd); @@ -2055,7 +2055,7 @@ imx319_set_pad_format(struct v4l2_subdev *sd, fmt->format.width, fmt->format.height); imx319_update_pad_format(imx319, mode, fmt); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - framefmt = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); *framefmt = fmt->format; } else { imx319->cur_mode = mode; diff --git a/drivers/media/i2c/imx334.c b/drivers/media/i2c/imx334.c index 23f28606e570..062125501788 100644 --- a/drivers/media/i2c/imx334.c +++ b/drivers/media/i2c/imx334.c @@ -497,13 +497,13 @@ static const struct v4l2_ctrl_ops imx334_ctrl_ops = { /** * imx334_enum_mbus_code() - Enumerate V4L2 sub-device mbus codes * @sd: pointer to imx334 V4L2 sub-device structure - * @cfg: V4L2 sub-device pad configuration + * @sd_state: V4L2 sub-device state * @code: V4L2 sub-device code enumeration need to be filled * * Return: 0 if successful, error code otherwise. */ static int imx334_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->index > 0) @@ -517,13 +517,13 @@ static int imx334_enum_mbus_code(struct v4l2_subdev *sd, /** * imx334_enum_frame_size() - Enumerate V4L2 sub-device frame sizes * @sd: pointer to imx334 V4L2 sub-device structure - * @cfg: V4L2 sub-device pad configuration + * @sd_state: V4L2 sub-device state * @fsize: V4L2 sub-device size enumeration need to be filled * * Return: 0 if successful, error code otherwise. */ static int imx334_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fsize) { if (fsize->index > 0) @@ -564,13 +564,13 @@ static void imx334_fill_pad_format(struct imx334 *imx334, /** * imx334_get_pad_format() - Get subdevice pad format * @sd: pointer to imx334 V4L2 sub-device structure - * @cfg: V4L2 sub-device pad configuration + * @sd_state: V4L2 sub-device state * @fmt: V4L2 sub-device format need to be set * * Return: 0 if successful, error code otherwise. */ static int imx334_get_pad_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct imx334 *imx334 = to_imx334(sd); @@ -580,7 +580,7 @@ static int imx334_get_pad_format(struct v4l2_subdev *sd, if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { struct v4l2_mbus_framefmt *framefmt; - framefmt = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); fmt->format = *framefmt; } else { imx334_fill_pad_format(imx334, imx334->cur_mode, fmt); @@ -594,13 +594,13 @@ static int imx334_get_pad_format(struct v4l2_subdev *sd, /** * imx334_set_pad_format() - Set subdevice pad format * @sd: pointer to imx334 V4L2 sub-device structure - * @cfg: V4L2 sub-device pad configuration + * @sd_state: V4L2 sub-device state * @fmt: V4L2 sub-device format need to be set * * Return: 0 if successful, error code otherwise. */ static int imx334_set_pad_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct imx334 *imx334 = to_imx334(sd); @@ -615,7 +615,7 @@ static int imx334_set_pad_format(struct v4l2_subdev *sd, if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { struct v4l2_mbus_framefmt *framefmt; - framefmt = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); *framefmt = fmt->format; } else { ret = imx334_update_controls(imx334, mode); @@ -631,20 +631,20 @@ static int imx334_set_pad_format(struct v4l2_subdev *sd, /** * imx334_init_pad_cfg() - Initialize sub-device pad configuration * @sd: pointer to imx334 V4L2 sub-device structure - * @cfg: V4L2 sub-device pad configuration + * @sd_state: V4L2 sub-device state * * Return: 0 if successful, error code otherwise. */ static int imx334_init_pad_cfg(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg) + struct v4l2_subdev_state *sd_state) { struct imx334 *imx334 = to_imx334(sd); struct v4l2_subdev_format fmt = { 0 }; - fmt.which = cfg ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; + fmt.which = sd_state ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; imx334_fill_pad_format(imx334, &supported_mode, &fmt); - return imx334_set_pad_format(sd, cfg, &fmt); + return imx334_set_pad_format(sd, sd_state, &fmt); } /** diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c index 93f13a04439a..cb51c81786bd 100644 --- a/drivers/media/i2c/imx355.c +++ b/drivers/media/i2c/imx355.c @@ -1161,7 +1161,7 @@ static int imx355_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { struct imx355 *imx355 = to_imx355(sd); struct v4l2_mbus_framefmt *try_fmt = - v4l2_subdev_get_try_format(sd, fh->pad, 0); + v4l2_subdev_get_try_format(sd, fh->state, 0); mutex_lock(&imx355->mutex); @@ -1248,7 +1248,7 @@ static const struct v4l2_ctrl_ops imx355_ctrl_ops = { }; static int imx355_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct imx355 *imx355 = to_imx355(sd); @@ -1264,7 +1264,7 @@ static int imx355_enum_mbus_code(struct v4l2_subdev *sd, } static int imx355_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { struct imx355 *imx355 = to_imx355(sd); @@ -1298,14 +1298,14 @@ static void imx355_update_pad_format(struct imx355 *imx355, } static int imx355_do_get_pad_format(struct imx355 *imx355, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct v4l2_mbus_framefmt *framefmt; struct v4l2_subdev *sd = &imx355->sd; if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - framefmt = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); fmt->format = *framefmt; } else { imx355_update_pad_format(imx355, imx355->cur_mode, fmt); @@ -1315,14 +1315,14 @@ static int imx355_do_get_pad_format(struct imx355 *imx355, } static int imx355_get_pad_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct imx355 *imx355 = to_imx355(sd); int ret; mutex_lock(&imx355->mutex); - ret = imx355_do_get_pad_format(imx355, cfg, fmt); + ret = imx355_do_get_pad_format(imx355, sd_state, fmt); mutex_unlock(&imx355->mutex); return ret; @@ -1330,7 +1330,7 @@ static int imx355_get_pad_format(struct v4l2_subdev *sd, static int imx355_set_pad_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct imx355 *imx355 = to_imx355(sd); @@ -1356,7 +1356,7 @@ imx355_set_pad_format(struct v4l2_subdev *sd, fmt->format.width, fmt->format.height); imx355_update_pad_format(imx355, mode, fmt); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - framefmt = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); *framefmt = fmt->format; } else { imx355->cur_mode = mode; diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c index 21666d705e37..e29be0242f07 100644 --- a/drivers/media/i2c/m5mols/m5mols_core.c +++ b/drivers/media/i2c/m5mols/m5mols_core.c @@ -539,17 +539,19 @@ static int __find_resolution(struct v4l2_subdev *sd, } static struct v4l2_mbus_framefmt *__find_format(struct m5mols_info *info, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, enum v4l2_subdev_format_whence which, enum m5mols_restype type) { if (which == V4L2_SUBDEV_FORMAT_TRY) - return cfg ? v4l2_subdev_get_try_format(&info->sd, cfg, 0) : NULL; + return sd_state ? v4l2_subdev_get_try_format(&info->sd, + sd_state, 0) : NULL; return &info->ffmt[type]; } -static int m5mols_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, +static int m5mols_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct m5mols_info *info = to_m5mols(sd); @@ -558,7 +560,7 @@ static int m5mols_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config mutex_lock(&info->lock); - format = __find_format(info, cfg, fmt->which, info->res_type); + format = __find_format(info, sd_state, fmt->which, info->res_type); if (format) fmt->format = *format; else @@ -568,7 +570,8 @@ static int m5mols_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config return ret; } -static int m5mols_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, +static int m5mols_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct m5mols_info *info = to_m5mols(sd); @@ -582,7 +585,7 @@ static int m5mols_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config if (ret < 0) return ret; - sfmt = __find_format(info, cfg, fmt->which, type); + sfmt = __find_format(info, sd_state, fmt->which, type); if (!sfmt) return 0; @@ -648,7 +651,7 @@ static int m5mols_set_frame_desc(struct v4l2_subdev *sd, unsigned int pad, static int m5mols_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (!code || code->index >= SIZE_DEFAULT_FFMT) @@ -909,7 +912,9 @@ static const struct v4l2_subdev_core_ops m5mols_core_ops = { */ static int m5mols_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { - struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(sd, fh->pad, 0); + struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(sd, + fh->state, + 0); *format = m5mols_default_ffmt[0]; return 0; diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c index 6fd4d59fcc72..4631bfeeacc0 100644 --- a/drivers/media/i2c/max9286.c +++ b/drivers/media/i2c/max9286.c @@ -712,7 +712,7 @@ static int max9286_s_stream(struct v4l2_subdev *sd, int enable) } static int max9286_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->pad || code->index > 0) @@ -725,12 +725,12 @@ static int max9286_enum_mbus_code(struct v4l2_subdev *sd, static struct v4l2_mbus_framefmt * max9286_get_pad_format(struct max9286_priv *priv, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad, u32 which) { switch (which) { case V4L2_SUBDEV_FORMAT_TRY: - return v4l2_subdev_get_try_format(&priv->sd, cfg, pad); + return v4l2_subdev_get_try_format(&priv->sd, sd_state, pad); case V4L2_SUBDEV_FORMAT_ACTIVE: return &priv->fmt[pad]; default: @@ -739,7 +739,7 @@ max9286_get_pad_format(struct max9286_priv *priv, } static int max9286_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct max9286_priv *priv = sd_to_max9286(sd); @@ -760,7 +760,8 @@ static int max9286_set_fmt(struct v4l2_subdev *sd, break; } - cfg_fmt = max9286_get_pad_format(priv, cfg, format->pad, format->which); + cfg_fmt = max9286_get_pad_format(priv, sd_state, format->pad, + format->which); if (!cfg_fmt) return -EINVAL; @@ -772,7 +773,7 @@ static int max9286_set_fmt(struct v4l2_subdev *sd, } static int max9286_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct max9286_priv *priv = sd_to_max9286(sd); @@ -788,7 +789,7 @@ static int max9286_get_fmt(struct v4l2_subdev *sd, if (pad == MAX9286_SRC_PAD) pad = __ffs(priv->bound_sources); - cfg_fmt = max9286_get_pad_format(priv, cfg, pad, format->which); + cfg_fmt = max9286_get_pad_format(priv, sd_state, pad, format->which); if (!cfg_fmt) return -EINVAL; @@ -832,7 +833,7 @@ static int max9286_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh) unsigned int i; for (i = 0; i < MAX9286_N_SINKS; i++) { - format = v4l2_subdev_get_try_format(subdev, fh->pad, i); + format = v4l2_subdev_get_try_format(subdev, fh->state, i); max9286_init_format(format); } diff --git a/drivers/media/i2c/ml86v7667.c b/drivers/media/i2c/ml86v7667.c index ff212335326a..4a1410ebb4c8 100644 --- a/drivers/media/i2c/ml86v7667.c +++ b/drivers/media/i2c/ml86v7667.c @@ -188,7 +188,7 @@ static int ml86v7667_g_input_status(struct v4l2_subdev *sd, u32 *status) } static int ml86v7667_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->pad || code->index > 0) @@ -200,7 +200,7 @@ static int ml86v7667_enum_mbus_code(struct v4l2_subdev *sd, } static int ml86v7667_fill_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct ml86v7667_priv *priv = to_ml86v7667(sd); diff --git a/drivers/media/i2c/mt9m001.c b/drivers/media/i2c/mt9m001.c index 58c85a3bccf6..c9f0bd997ea7 100644 --- a/drivers/media/i2c/mt9m001.c +++ b/drivers/media/i2c/mt9m001.c @@ -254,7 +254,7 @@ unlock: } static int mt9m001_set_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -295,7 +295,7 @@ static int mt9m001_set_selection(struct v4l2_subdev *sd, } static int mt9m001_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -320,7 +320,7 @@ static int mt9m001_get_selection(struct v4l2_subdev *sd, } static int mt9m001_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -331,7 +331,7 @@ static int mt9m001_get_fmt(struct v4l2_subdev *sd, return -EINVAL; if (format->which == V4L2_SUBDEV_FORMAT_TRY) { - mf = v4l2_subdev_get_try_format(sd, cfg, 0); + mf = v4l2_subdev_get_try_format(sd, sd_state, 0); format->format = *mf; return 0; } @@ -377,7 +377,7 @@ static int mt9m001_s_fmt(struct v4l2_subdev *sd, } static int mt9m001_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *mf = &format->format; @@ -411,7 +411,7 @@ static int mt9m001_set_fmt(struct v4l2_subdev *sd, if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) return mt9m001_s_fmt(sd, fmt, mf); - cfg->try_fmt = *mf; + sd_state->pads->try_fmt = *mf; return 0; } @@ -657,12 +657,12 @@ static const struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = { }; static int mt9m001_init_cfg(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg) + struct v4l2_subdev_state *sd_state) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9m001 *mt9m001 = to_mt9m001(client); struct v4l2_mbus_framefmt *try_fmt = - v4l2_subdev_get_try_format(sd, cfg, 0); + v4l2_subdev_get_try_format(sd, sd_state, 0); try_fmt->width = MT9M001_MAX_WIDTH; try_fmt->height = MT9M001_MAX_HEIGHT; @@ -677,7 +677,7 @@ static int mt9m001_init_cfg(struct v4l2_subdev *sd, } static int mt9m001_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct i2c_client *client = v4l2_get_subdevdata(sd); diff --git a/drivers/media/i2c/mt9m032.c b/drivers/media/i2c/mt9m032.c index 5a4c0f9d1eee..ba0c0ea91c95 100644 --- a/drivers/media/i2c/mt9m032.c +++ b/drivers/media/i2c/mt9m032.c @@ -304,7 +304,7 @@ static int mt9m032_setup_pll(struct mt9m032 *sensor) */ static int mt9m032_enum_mbus_code(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->index != 0) @@ -315,7 +315,7 @@ static int mt9m032_enum_mbus_code(struct v4l2_subdev *subdev, } static int mt9m032_enum_frame_size(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { if (fse->index != 0 || fse->code != MEDIA_BUS_FMT_Y8_1X8) @@ -332,18 +332,19 @@ static int mt9m032_enum_frame_size(struct v4l2_subdev *subdev, /** * __mt9m032_get_pad_crop() - get crop rect * @sensor: pointer to the sensor struct - * @cfg: v4l2_subdev_pad_config for getting the try crop rect from + * @sd_state: v4l2_subdev_state for getting the try crop rect from * @which: select try or active crop rect * * Returns a pointer the current active or fh relative try crop rect */ static struct v4l2_rect * -__mt9m032_get_pad_crop(struct mt9m032 *sensor, struct v4l2_subdev_pad_config *cfg, +__mt9m032_get_pad_crop(struct mt9m032 *sensor, + struct v4l2_subdev_state *sd_state, enum v4l2_subdev_format_whence which) { switch (which) { case V4L2_SUBDEV_FORMAT_TRY: - return v4l2_subdev_get_try_crop(&sensor->subdev, cfg, 0); + return v4l2_subdev_get_try_crop(&sensor->subdev, sd_state, 0); case V4L2_SUBDEV_FORMAT_ACTIVE: return &sensor->crop; default: @@ -354,18 +355,20 @@ __mt9m032_get_pad_crop(struct mt9m032 *sensor, struct v4l2_subdev_pad_config *cf /** * __mt9m032_get_pad_format() - get format * @sensor: pointer to the sensor struct - * @cfg: v4l2_subdev_pad_config for getting the try format from + * @sd_state: v4l2_subdev_state for getting the try format from * @which: select try or active format * * Returns a pointer the current active or fh relative try format */ static struct v4l2_mbus_framefmt * -__mt9m032_get_pad_format(struct mt9m032 *sensor, struct v4l2_subdev_pad_config *cfg, +__mt9m032_get_pad_format(struct mt9m032 *sensor, + struct v4l2_subdev_state *sd_state, enum v4l2_subdev_format_whence which) { switch (which) { case V4L2_SUBDEV_FORMAT_TRY: - return v4l2_subdev_get_try_format(&sensor->subdev, cfg, 0); + return v4l2_subdev_get_try_format(&sensor->subdev, sd_state, + 0); case V4L2_SUBDEV_FORMAT_ACTIVE: return &sensor->format; default: @@ -374,20 +377,20 @@ __mt9m032_get_pad_format(struct mt9m032 *sensor, struct v4l2_subdev_pad_config * } static int mt9m032_get_pad_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct mt9m032 *sensor = to_mt9m032(subdev); mutex_lock(&sensor->lock); - fmt->format = *__mt9m032_get_pad_format(sensor, cfg, fmt->which); + fmt->format = *__mt9m032_get_pad_format(sensor, sd_state, fmt->which); mutex_unlock(&sensor->lock); return 0; } static int mt9m032_set_pad_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct mt9m032 *sensor = to_mt9m032(subdev); @@ -401,7 +404,7 @@ static int mt9m032_set_pad_format(struct v4l2_subdev *subdev, } /* Scaling is not supported, the format is thus fixed. */ - fmt->format = *__mt9m032_get_pad_format(sensor, cfg, fmt->which); + fmt->format = *__mt9m032_get_pad_format(sensor, sd_state, fmt->which); ret = 0; done: @@ -410,7 +413,7 @@ done: } static int mt9m032_get_pad_selection(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct mt9m032 *sensor = to_mt9m032(subdev); @@ -419,14 +422,14 @@ static int mt9m032_get_pad_selection(struct v4l2_subdev *subdev, return -EINVAL; mutex_lock(&sensor->lock); - sel->r = *__mt9m032_get_pad_crop(sensor, cfg, sel->which); + sel->r = *__mt9m032_get_pad_crop(sensor, sd_state, sel->which); mutex_unlock(&sensor->lock); return 0; } static int mt9m032_set_pad_selection(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct mt9m032 *sensor = to_mt9m032(subdev); @@ -462,13 +465,14 @@ static int mt9m032_set_pad_selection(struct v4l2_subdev *subdev, rect.height = min_t(unsigned int, rect.height, MT9M032_PIXEL_ARRAY_HEIGHT - rect.top); - __crop = __mt9m032_get_pad_crop(sensor, cfg, sel->which); + __crop = __mt9m032_get_pad_crop(sensor, sd_state, sel->which); if (rect.width != __crop->width || rect.height != __crop->height) { /* Reset the output image size if the crop rectangle size has * been modified. */ - format = __mt9m032_get_pad_format(sensor, cfg, sel->which); + format = __mt9m032_get_pad_format(sensor, sd_state, + sel->which); format->width = rect.width; format->height = rect.height; } diff --git a/drivers/media/i2c/mt9m111.c b/drivers/media/i2c/mt9m111.c index 0e11734f75aa..91a44359bcd3 100644 --- a/drivers/media/i2c/mt9m111.c +++ b/drivers/media/i2c/mt9m111.c @@ -449,7 +449,7 @@ static int mt9m111_reset(struct mt9m111 *mt9m111) } static int mt9m111_set_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -493,7 +493,7 @@ static int mt9m111_set_selection(struct v4l2_subdev *sd, } static int mt9m111_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -518,7 +518,7 @@ static int mt9m111_get_selection(struct v4l2_subdev *sd, } static int mt9m111_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *mf = &format->format; @@ -529,7 +529,7 @@ static int mt9m111_get_fmt(struct v4l2_subdev *sd, if (format->which == V4L2_SUBDEV_FORMAT_TRY) { #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API - mf = v4l2_subdev_get_try_format(sd, cfg, format->pad); + mf = v4l2_subdev_get_try_format(sd, sd_state, format->pad); format->format = *mf; return 0; #else @@ -624,7 +624,7 @@ static int mt9m111_set_pixfmt(struct mt9m111 *mt9m111, } static int mt9m111_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *mf = &format->format; @@ -678,7 +678,7 @@ static int mt9m111_set_fmt(struct v4l2_subdev *sd, mf->xfer_func = V4L2_XFER_FUNC_DEFAULT; if (format->which == V4L2_SUBDEV_FORMAT_TRY) { - cfg->try_fmt = *mf; + sd_state->pads->try_fmt = *mf; return 0; } @@ -1100,7 +1100,7 @@ static int mt9m111_s_frame_interval(struct v4l2_subdev *sd, } static int mt9m111_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->pad || code->index >= ARRAY_SIZE(mt9m111_colour_fmts)) @@ -1119,11 +1119,11 @@ static int mt9m111_s_stream(struct v4l2_subdev *sd, int enable) } static int mt9m111_init_cfg(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg) + struct v4l2_subdev_state *sd_state) { #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API struct v4l2_mbus_framefmt *format = - v4l2_subdev_get_try_format(sd, cfg, 0); + v4l2_subdev_get_try_format(sd, sd_state, 0); format->width = MT9M111_MAX_WIDTH; format->height = MT9M111_MAX_HEIGHT; diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c index a633b934d93e..6eb88ef99783 100644 --- a/drivers/media/i2c/mt9p031.c +++ b/drivers/media/i2c/mt9p031.c @@ -470,7 +470,7 @@ static int mt9p031_s_stream(struct v4l2_subdev *subdev, int enable) } static int mt9p031_enum_mbus_code(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct mt9p031 *mt9p031 = to_mt9p031(subdev); @@ -483,7 +483,7 @@ static int mt9p031_enum_mbus_code(struct v4l2_subdev *subdev, } static int mt9p031_enum_frame_size(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { struct mt9p031 *mt9p031 = to_mt9p031(subdev); @@ -501,12 +501,14 @@ static int mt9p031_enum_frame_size(struct v4l2_subdev *subdev, } static struct v4l2_mbus_framefmt * -__mt9p031_get_pad_format(struct mt9p031 *mt9p031, struct v4l2_subdev_pad_config *cfg, +__mt9p031_get_pad_format(struct mt9p031 *mt9p031, + struct v4l2_subdev_state *sd_state, unsigned int pad, u32 which) { switch (which) { case V4L2_SUBDEV_FORMAT_TRY: - return v4l2_subdev_get_try_format(&mt9p031->subdev, cfg, pad); + return v4l2_subdev_get_try_format(&mt9p031->subdev, sd_state, + pad); case V4L2_SUBDEV_FORMAT_ACTIVE: return &mt9p031->format; default: @@ -515,12 +517,14 @@ __mt9p031_get_pad_format(struct mt9p031 *mt9p031, struct v4l2_subdev_pad_config } static struct v4l2_rect * -__mt9p031_get_pad_crop(struct mt9p031 *mt9p031, struct v4l2_subdev_pad_config *cfg, - unsigned int pad, u32 which) +__mt9p031_get_pad_crop(struct mt9p031 *mt9p031, + struct v4l2_subdev_state *sd_state, + unsigned int pad, u32 which) { switch (which) { case V4L2_SUBDEV_FORMAT_TRY: - return v4l2_subdev_get_try_crop(&mt9p031->subdev, cfg, pad); + return v4l2_subdev_get_try_crop(&mt9p031->subdev, sd_state, + pad); case V4L2_SUBDEV_FORMAT_ACTIVE: return &mt9p031->crop; default: @@ -529,18 +533,18 @@ __mt9p031_get_pad_crop(struct mt9p031 *mt9p031, struct v4l2_subdev_pad_config *c } static int mt9p031_get_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct mt9p031 *mt9p031 = to_mt9p031(subdev); - fmt->format = *__mt9p031_get_pad_format(mt9p031, cfg, fmt->pad, + fmt->format = *__mt9p031_get_pad_format(mt9p031, sd_state, fmt->pad, fmt->which); return 0; } static int mt9p031_set_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct mt9p031 *mt9p031 = to_mt9p031(subdev); @@ -551,7 +555,7 @@ static int mt9p031_set_format(struct v4l2_subdev *subdev, unsigned int hratio; unsigned int vratio; - __crop = __mt9p031_get_pad_crop(mt9p031, cfg, format->pad, + __crop = __mt9p031_get_pad_crop(mt9p031, sd_state, format->pad, format->which); /* Clamp the width and height to avoid dividing by zero. */ @@ -567,7 +571,7 @@ static int mt9p031_set_format(struct v4l2_subdev *subdev, hratio = DIV_ROUND_CLOSEST(__crop->width, width); vratio = DIV_ROUND_CLOSEST(__crop->height, height); - __format = __mt9p031_get_pad_format(mt9p031, cfg, format->pad, + __format = __mt9p031_get_pad_format(mt9p031, sd_state, format->pad, format->which); __format->width = __crop->width / hratio; __format->height = __crop->height / vratio; @@ -578,7 +582,7 @@ static int mt9p031_set_format(struct v4l2_subdev *subdev, } static int mt9p031_get_selection(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct mt9p031 *mt9p031 = to_mt9p031(subdev); @@ -586,12 +590,13 @@ static int mt9p031_get_selection(struct v4l2_subdev *subdev, if (sel->target != V4L2_SEL_TGT_CROP) return -EINVAL; - sel->r = *__mt9p031_get_pad_crop(mt9p031, cfg, sel->pad, sel->which); + sel->r = *__mt9p031_get_pad_crop(mt9p031, sd_state, sel->pad, + sel->which); return 0; } static int mt9p031_set_selection(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct mt9p031 *mt9p031 = to_mt9p031(subdev); @@ -621,13 +626,15 @@ static int mt9p031_set_selection(struct v4l2_subdev *subdev, rect.height = min_t(unsigned int, rect.height, MT9P031_PIXEL_ARRAY_HEIGHT - rect.top); - __crop = __mt9p031_get_pad_crop(mt9p031, cfg, sel->pad, sel->which); + __crop = __mt9p031_get_pad_crop(mt9p031, sd_state, sel->pad, + sel->which); if (rect.width != __crop->width || rect.height != __crop->height) { /* Reset the output image size if the crop rectangle size has * been modified. */ - __format = __mt9p031_get_pad_format(mt9p031, cfg, sel->pad, + __format = __mt9p031_get_pad_format(mt9p031, sd_state, + sel->pad, sel->which); __format->width = rect.width; __format->height = rect.height; @@ -942,13 +949,13 @@ static int mt9p031_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh) struct v4l2_mbus_framefmt *format; struct v4l2_rect *crop; - crop = v4l2_subdev_get_try_crop(subdev, fh->pad, 0); + crop = v4l2_subdev_get_try_crop(subdev, fh->state, 0); crop->left = MT9P031_COLUMN_START_DEF; crop->top = MT9P031_ROW_START_DEF; crop->width = MT9P031_WINDOW_WIDTH_DEF; crop->height = MT9P031_WINDOW_HEIGHT_DEF; - format = v4l2_subdev_get_try_format(subdev, fh->pad, 0); + format = v4l2_subdev_get_try_format(subdev, fh->state, 0); if (mt9p031->model == MT9P031_MODEL_MONOCHROME) format->code = MEDIA_BUS_FMT_Y12_1X12; diff --git a/drivers/media/i2c/mt9t001.c b/drivers/media/i2c/mt9t001.c index 2e96ff5234b4..b651ee4a26e8 100644 --- a/drivers/media/i2c/mt9t001.c +++ b/drivers/media/i2c/mt9t001.c @@ -252,12 +252,14 @@ e_power: */ static struct v4l2_mbus_framefmt * -__mt9t001_get_pad_format(struct mt9t001 *mt9t001, struct v4l2_subdev_pad_config *cfg, +__mt9t001_get_pad_format(struct mt9t001 *mt9t001, + struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which) { switch (which) { case V4L2_SUBDEV_FORMAT_TRY: - return v4l2_subdev_get_try_format(&mt9t001->subdev, cfg, pad); + return v4l2_subdev_get_try_format(&mt9t001->subdev, sd_state, + pad); case V4L2_SUBDEV_FORMAT_ACTIVE: return &mt9t001->format; default: @@ -266,12 +268,14 @@ __mt9t001_get_pad_format(struct mt9t001 *mt9t001, struct v4l2_subdev_pad_config } static struct v4l2_rect * -__mt9t001_get_pad_crop(struct mt9t001 *mt9t001, struct v4l2_subdev_pad_config *cfg, +__mt9t001_get_pad_crop(struct mt9t001 *mt9t001, + struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which) { switch (which) { case V4L2_SUBDEV_FORMAT_TRY: - return v4l2_subdev_get_try_crop(&mt9t001->subdev, cfg, pad); + return v4l2_subdev_get_try_crop(&mt9t001->subdev, sd_state, + pad); case V4L2_SUBDEV_FORMAT_ACTIVE: return &mt9t001->crop; default: @@ -335,7 +339,7 @@ static int mt9t001_s_stream(struct v4l2_subdev *subdev, int enable) } static int mt9t001_enum_mbus_code(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->index > 0) @@ -346,7 +350,7 @@ static int mt9t001_enum_mbus_code(struct v4l2_subdev *subdev, } static int mt9t001_enum_frame_size(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { if (fse->index >= 8 || fse->code != MEDIA_BUS_FMT_SGRBG10_1X10) @@ -361,18 +365,19 @@ static int mt9t001_enum_frame_size(struct v4l2_subdev *subdev, } static int mt9t001_get_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct mt9t001 *mt9t001 = to_mt9t001(subdev); - format->format = *__mt9t001_get_pad_format(mt9t001, cfg, format->pad, + format->format = *__mt9t001_get_pad_format(mt9t001, sd_state, + format->pad, format->which); return 0; } static int mt9t001_set_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct mt9t001 *mt9t001 = to_mt9t001(subdev); @@ -383,7 +388,7 @@ static int mt9t001_set_format(struct v4l2_subdev *subdev, unsigned int hratio; unsigned int vratio; - __crop = __mt9t001_get_pad_crop(mt9t001, cfg, format->pad, + __crop = __mt9t001_get_pad_crop(mt9t001, sd_state, format->pad, format->which); /* Clamp the width and height to avoid dividing by zero. */ @@ -399,7 +404,7 @@ static int mt9t001_set_format(struct v4l2_subdev *subdev, hratio = DIV_ROUND_CLOSEST(__crop->width, width); vratio = DIV_ROUND_CLOSEST(__crop->height, height); - __format = __mt9t001_get_pad_format(mt9t001, cfg, format->pad, + __format = __mt9t001_get_pad_format(mt9t001, sd_state, format->pad, format->which); __format->width = __crop->width / hratio; __format->height = __crop->height / vratio; @@ -410,7 +415,7 @@ static int mt9t001_set_format(struct v4l2_subdev *subdev, } static int mt9t001_get_selection(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct mt9t001 *mt9t001 = to_mt9t001(subdev); @@ -418,12 +423,13 @@ static int mt9t001_get_selection(struct v4l2_subdev *subdev, if (sel->target != V4L2_SEL_TGT_CROP) return -EINVAL; - sel->r = *__mt9t001_get_pad_crop(mt9t001, cfg, sel->pad, sel->which); + sel->r = *__mt9t001_get_pad_crop(mt9t001, sd_state, sel->pad, + sel->which); return 0; } static int mt9t001_set_selection(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct mt9t001 *mt9t001 = to_mt9t001(subdev); @@ -455,13 +461,15 @@ static int mt9t001_set_selection(struct v4l2_subdev *subdev, rect.height = min_t(unsigned int, rect.height, MT9T001_PIXEL_ARRAY_HEIGHT - rect.top); - __crop = __mt9t001_get_pad_crop(mt9t001, cfg, sel->pad, sel->which); + __crop = __mt9t001_get_pad_crop(mt9t001, sd_state, sel->pad, + sel->which); if (rect.width != __crop->width || rect.height != __crop->height) { /* Reset the output image size if the crop rectangle size has * been modified. */ - __format = __mt9t001_get_pad_format(mt9t001, cfg, sel->pad, + __format = __mt9t001_get_pad_format(mt9t001, sd_state, + sel->pad, sel->which); __format->width = rect.width; __format->height = rect.height; @@ -798,13 +806,13 @@ static int mt9t001_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh) struct v4l2_mbus_framefmt *format; struct v4l2_rect *crop; - crop = v4l2_subdev_get_try_crop(subdev, fh->pad, 0); + crop = v4l2_subdev_get_try_crop(subdev, fh->state, 0); crop->left = MT9T001_COLUMN_START_DEF; crop->top = MT9T001_ROW_START_DEF; crop->width = MT9T001_WINDOW_WIDTH_DEF + 1; crop->height = MT9T001_WINDOW_HEIGHT_DEF + 1; - format = v4l2_subdev_get_try_format(subdev, fh->pad, 0); + format = v4l2_subdev_get_try_format(subdev, fh->state, 0); format->code = MEDIA_BUS_FMT_SGRBG10_1X10; format->width = MT9T001_WINDOW_WIDTH_DEF + 1; format->height = MT9T001_WINDOW_HEIGHT_DEF + 1; diff --git a/drivers/media/i2c/mt9t112.c b/drivers/media/i2c/mt9t112.c index ae3c336eadf5..8d2e3caa9b28 100644 --- a/drivers/media/i2c/mt9t112.c +++ b/drivers/media/i2c/mt9t112.c @@ -872,8 +872,8 @@ static int mt9t112_set_params(struct mt9t112_priv *priv, } static int mt9t112_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_selection *sel) + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_selection *sel) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9t112_priv *priv = to_mt9t112(client); @@ -897,7 +897,7 @@ static int mt9t112_get_selection(struct v4l2_subdev *sd, } static int mt9t112_set_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -912,7 +912,7 @@ static int mt9t112_set_selection(struct v4l2_subdev *sd, } static int mt9t112_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *mf = &format->format; @@ -953,7 +953,7 @@ static int mt9t112_s_fmt(struct v4l2_subdev *sd, } static int mt9t112_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -982,13 +982,13 @@ static int mt9t112_set_fmt(struct v4l2_subdev *sd, if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) return mt9t112_s_fmt(sd, mf); - cfg->try_fmt = *mf; + sd_state->pads->try_fmt = *mf; return 0; } static int mt9t112_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct i2c_client *client = v4l2_get_subdevdata(sd); diff --git a/drivers/media/i2c/mt9v011.c b/drivers/media/i2c/mt9v011.c index 46ef74a2ca36..7699e64e1127 100644 --- a/drivers/media/i2c/mt9v011.c +++ b/drivers/media/i2c/mt9v011.c @@ -327,7 +327,7 @@ static int mt9v011_reset(struct v4l2_subdev *sd, u32 val) } static int mt9v011_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->pad || code->index > 0) @@ -338,7 +338,7 @@ static int mt9v011_enum_mbus_code(struct v4l2_subdev *sd, } static int mt9v011_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *fmt = &format->format; @@ -358,7 +358,7 @@ static int mt9v011_set_fmt(struct v4l2_subdev *sd, set_res(sd); } else { - cfg->try_fmt = *fmt; + sd_state->pads->try_fmt = *fmt; } return 0; diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c index 5bd3ae82992f..4cfdd3dfbd42 100644 --- a/drivers/media/i2c/mt9v032.c +++ b/drivers/media/i2c/mt9v032.c @@ -349,12 +349,14 @@ static int __mt9v032_set_power(struct mt9v032 *mt9v032, bool on) */ static struct v4l2_mbus_framefmt * -__mt9v032_get_pad_format(struct mt9v032 *mt9v032, struct v4l2_subdev_pad_config *cfg, +__mt9v032_get_pad_format(struct mt9v032 *mt9v032, + struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which) { switch (which) { case V4L2_SUBDEV_FORMAT_TRY: - return v4l2_subdev_get_try_format(&mt9v032->subdev, cfg, pad); + return v4l2_subdev_get_try_format(&mt9v032->subdev, sd_state, + pad); case V4L2_SUBDEV_FORMAT_ACTIVE: return &mt9v032->format; default: @@ -363,12 +365,14 @@ __mt9v032_get_pad_format(struct mt9v032 *mt9v032, struct v4l2_subdev_pad_config } static struct v4l2_rect * -__mt9v032_get_pad_crop(struct mt9v032 *mt9v032, struct v4l2_subdev_pad_config *cfg, +__mt9v032_get_pad_crop(struct mt9v032 *mt9v032, + struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which) { switch (which) { case V4L2_SUBDEV_FORMAT_TRY: - return v4l2_subdev_get_try_crop(&mt9v032->subdev, cfg, pad); + return v4l2_subdev_get_try_crop(&mt9v032->subdev, sd_state, + pad); case V4L2_SUBDEV_FORMAT_ACTIVE: return &mt9v032->crop; default: @@ -425,7 +429,7 @@ static int mt9v032_s_stream(struct v4l2_subdev *subdev, int enable) } static int mt9v032_enum_mbus_code(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct mt9v032 *mt9v032 = to_mt9v032(subdev); @@ -438,7 +442,7 @@ static int mt9v032_enum_mbus_code(struct v4l2_subdev *subdev, } static int mt9v032_enum_frame_size(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { struct mt9v032 *mt9v032 = to_mt9v032(subdev); @@ -457,12 +461,13 @@ static int mt9v032_enum_frame_size(struct v4l2_subdev *subdev, } static int mt9v032_get_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct mt9v032 *mt9v032 = to_mt9v032(subdev); - format->format = *__mt9v032_get_pad_format(mt9v032, cfg, format->pad, + format->format = *__mt9v032_get_pad_format(mt9v032, sd_state, + format->pad, format->which); return 0; } @@ -492,7 +497,7 @@ static unsigned int mt9v032_calc_ratio(unsigned int input, unsigned int output) } static int mt9v032_set_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct mt9v032 *mt9v032 = to_mt9v032(subdev); @@ -503,7 +508,7 @@ static int mt9v032_set_format(struct v4l2_subdev *subdev, unsigned int hratio; unsigned int vratio; - __crop = __mt9v032_get_pad_crop(mt9v032, cfg, format->pad, + __crop = __mt9v032_get_pad_crop(mt9v032, sd_state, format->pad, format->which); /* Clamp the width and height to avoid dividing by zero. */ @@ -519,7 +524,7 @@ static int mt9v032_set_format(struct v4l2_subdev *subdev, hratio = mt9v032_calc_ratio(__crop->width, width); vratio = mt9v032_calc_ratio(__crop->height, height); - __format = __mt9v032_get_pad_format(mt9v032, cfg, format->pad, + __format = __mt9v032_get_pad_format(mt9v032, sd_state, format->pad, format->which); __format->width = __crop->width / hratio; __format->height = __crop->height / vratio; @@ -536,7 +541,7 @@ static int mt9v032_set_format(struct v4l2_subdev *subdev, } static int mt9v032_get_selection(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct mt9v032 *mt9v032 = to_mt9v032(subdev); @@ -544,12 +549,13 @@ static int mt9v032_get_selection(struct v4l2_subdev *subdev, if (sel->target != V4L2_SEL_TGT_CROP) return -EINVAL; - sel->r = *__mt9v032_get_pad_crop(mt9v032, cfg, sel->pad, sel->which); + sel->r = *__mt9v032_get_pad_crop(mt9v032, sd_state, sel->pad, + sel->which); return 0; } static int mt9v032_set_selection(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct mt9v032 *mt9v032 = to_mt9v032(subdev); @@ -581,13 +587,15 @@ static int mt9v032_set_selection(struct v4l2_subdev *subdev, rect.height = min_t(unsigned int, rect.height, MT9V032_PIXEL_ARRAY_HEIGHT - rect.top); - __crop = __mt9v032_get_pad_crop(mt9v032, cfg, sel->pad, sel->which); + __crop = __mt9v032_get_pad_crop(mt9v032, sd_state, sel->pad, + sel->which); if (rect.width != __crop->width || rect.height != __crop->height) { /* Reset the output image size if the crop rectangle size has * been modified. */ - __format = __mt9v032_get_pad_format(mt9v032, cfg, sel->pad, + __format = __mt9v032_get_pad_format(mt9v032, sd_state, + sel->pad, sel->which); __format->width = rect.width; __format->height = rect.height; @@ -922,13 +930,13 @@ static int mt9v032_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh) struct v4l2_mbus_framefmt *format; struct v4l2_rect *crop; - crop = v4l2_subdev_get_try_crop(subdev, fh->pad, 0); + crop = v4l2_subdev_get_try_crop(subdev, fh->state, 0); crop->left = MT9V032_COLUMN_START_DEF; crop->top = MT9V032_ROW_START_DEF; crop->width = MT9V032_WINDOW_WIDTH_DEF; crop->height = MT9V032_WINDOW_HEIGHT_DEF; - format = v4l2_subdev_get_try_format(subdev, fh->pad, 0); + format = v4l2_subdev_get_try_format(subdev, fh->state, 0); if (mt9v032->model->color) format->code = MEDIA_BUS_FMT_SGRBG10_1X10; diff --git a/drivers/media/i2c/mt9v111.c b/drivers/media/i2c/mt9v111.c index 97c7527b74ed..2dc4a0f24ce8 100644 --- a/drivers/media/i2c/mt9v111.c +++ b/drivers/media/i2c/mt9v111.c @@ -791,16 +791,16 @@ static int mt9v111_g_frame_interval(struct v4l2_subdev *sd, static struct v4l2_mbus_framefmt *__mt9v111_get_pad_format( struct mt9v111_dev *mt9v111, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which) { switch (which) { case V4L2_SUBDEV_FORMAT_TRY: #if IS_ENABLED(CONFIG_VIDEO_V4L2_SUBDEV_API) - return v4l2_subdev_get_try_format(&mt9v111->sd, cfg, pad); + return v4l2_subdev_get_try_format(&mt9v111->sd, sd_state, pad); #else - return &cfg->try_fmt; + return &sd_state->pads->try_fmt; #endif case V4L2_SUBDEV_FORMAT_ACTIVE: return &mt9v111->fmt; @@ -810,7 +810,7 @@ static struct v4l2_mbus_framefmt *__mt9v111_get_pad_format( } static int mt9v111_enum_mbus_code(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->pad || code->index > ARRAY_SIZE(mt9v111_formats) - 1) @@ -822,7 +822,7 @@ static int mt9v111_enum_mbus_code(struct v4l2_subdev *subdev, } static int mt9v111_enum_frame_interval(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_interval_enum *fie) { unsigned int i; @@ -845,7 +845,7 @@ static int mt9v111_enum_frame_interval(struct v4l2_subdev *sd, } static int mt9v111_enum_frame_size(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { if (fse->pad || fse->index >= ARRAY_SIZE(mt9v111_frame_sizes)) @@ -860,7 +860,7 @@ static int mt9v111_enum_frame_size(struct v4l2_subdev *subdev, } static int mt9v111_get_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct mt9v111_dev *mt9v111 = sd_to_mt9v111(subdev); @@ -869,7 +869,8 @@ static int mt9v111_get_format(struct v4l2_subdev *subdev, return -EINVAL; mutex_lock(&mt9v111->stream_mutex); - format->format = *__mt9v111_get_pad_format(mt9v111, cfg, format->pad, + format->format = *__mt9v111_get_pad_format(mt9v111, sd_state, + format->pad, format->which); mutex_unlock(&mt9v111->stream_mutex); @@ -877,7 +878,7 @@ static int mt9v111_get_format(struct v4l2_subdev *subdev, } static int mt9v111_set_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct mt9v111_dev *mt9v111 = sd_to_mt9v111(subdev); @@ -925,7 +926,7 @@ static int mt9v111_set_format(struct v4l2_subdev *subdev, new_fmt.height = mt9v111_frame_sizes[idx].height; /* Update the device (or pad) format if it has changed. */ - __fmt = __mt9v111_get_pad_format(mt9v111, cfg, format->pad, + __fmt = __mt9v111_get_pad_format(mt9v111, sd_state, format->pad, format->which); /* Format hasn't changed, stop here. */ @@ -954,9 +955,9 @@ done: } static int mt9v111_init_cfg(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg) + struct v4l2_subdev_state *sd_state) { - cfg->try_fmt = mt9v111_def_fmt; + sd_state->pads->try_fmt = mt9v111_def_fmt; return 0; } diff --git a/drivers/media/i2c/noon010pc30.c b/drivers/media/i2c/noon010pc30.c index 87d76a7f691a..f3ac379ef34a 100644 --- a/drivers/media/i2c/noon010pc30.c +++ b/drivers/media/i2c/noon010pc30.c @@ -488,7 +488,7 @@ unlock: } static int noon010_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->index >= ARRAY_SIZE(noon010_formats)) @@ -499,15 +499,15 @@ static int noon010_enum_mbus_code(struct v4l2_subdev *sd, } static int noon010_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct noon010_info *info = to_noon010(sd); struct v4l2_mbus_framefmt *mf; if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - if (cfg) { - mf = v4l2_subdev_get_try_format(sd, cfg, 0); + if (sd_state) { + mf = v4l2_subdev_get_try_format(sd, sd_state, 0); fmt->format = *mf; } return 0; @@ -539,7 +539,8 @@ static const struct noon010_format *noon010_try_fmt(struct v4l2_subdev *sd, return &noon010_formats[i]; } -static int noon010_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, +static int noon010_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct noon010_info *info = to_noon010(sd); @@ -554,8 +555,8 @@ static int noon010_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config fmt->format.field = V4L2_FIELD_NONE; if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - if (cfg) { - mf = v4l2_subdev_get_try_format(sd, cfg, 0); + if (sd_state) { + mf = v4l2_subdev_get_try_format(sd, sd_state, 0); *mf = fmt->format; } return 0; @@ -637,7 +638,9 @@ static int noon010_log_status(struct v4l2_subdev *sd) static int noon010_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { - struct v4l2_mbus_framefmt *mf = v4l2_subdev_get_try_format(sd, fh->pad, 0); + struct v4l2_mbus_framefmt *mf = v4l2_subdev_get_try_format(sd, + fh->state, + 0); mf->width = noon010_sizes[0].width; mf->height = noon010_sizes[0].height; diff --git a/drivers/media/i2c/ov02a10.c b/drivers/media/i2c/ov02a10.c index a1d7314b20a9..a3ce5500d355 100644 --- a/drivers/media/i2c/ov02a10.c +++ b/drivers/media/i2c/ov02a10.c @@ -295,7 +295,7 @@ static void ov02a10_fill_fmt(const struct ov02a10_mode *mode, } static int ov02a10_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct ov02a10 *ov02a10 = to_ov02a10(sd); @@ -315,7 +315,7 @@ static int ov02a10_set_fmt(struct v4l2_subdev *sd, ov02a10_fill_fmt(ov02a10->cur_mode, mbus_fmt); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) - frame_fmt = v4l2_subdev_get_try_format(sd, cfg, 0); + frame_fmt = v4l2_subdev_get_try_format(sd, sd_state, 0); else frame_fmt = &ov02a10->fmt; @@ -327,7 +327,7 @@ out_unlock: } static int ov02a10_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct ov02a10 *ov02a10 = to_ov02a10(sd); @@ -336,7 +336,8 @@ static int ov02a10_get_fmt(struct v4l2_subdev *sd, mutex_lock(&ov02a10->mutex); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + fmt->format = *v4l2_subdev_get_try_format(sd, sd_state, + fmt->pad); } else { fmt->format = ov02a10->fmt; mbus_fmt->code = ov02a10->fmt.code; @@ -349,7 +350,7 @@ static int ov02a10_get_fmt(struct v4l2_subdev *sd, } static int ov02a10_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct ov02a10 *ov02a10 = to_ov02a10(sd); @@ -363,7 +364,7 @@ static int ov02a10_enum_mbus_code(struct v4l2_subdev *sd, } static int ov02a10_enum_frame_sizes(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { if (fse->index >= ARRAY_SIZE(supported_modes)) @@ -511,7 +512,7 @@ static int __ov02a10_stop_stream(struct ov02a10 *ov02a10) } static int ov02a10_entity_init_cfg(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg) + struct v4l2_subdev_state *sd_state) { struct v4l2_subdev_format fmt = { .which = V4L2_SUBDEV_FORMAT_TRY, @@ -521,7 +522,7 @@ static int ov02a10_entity_init_cfg(struct v4l2_subdev *sd, } }; - ov02a10_set_fmt(sd, cfg, &fmt); + ov02a10_set_fmt(sd, sd_state, &fmt); return 0; } diff --git a/drivers/media/i2c/ov13858.c b/drivers/media/i2c/ov13858.c index 9598c0b19603..7fc70af53e45 100644 --- a/drivers/media/i2c/ov13858.c +++ b/drivers/media/i2c/ov13858.c @@ -1150,7 +1150,7 @@ static int ov13858_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { struct ov13858 *ov13858 = to_ov13858(sd); struct v4l2_mbus_framefmt *try_fmt = v4l2_subdev_get_try_format(sd, - fh->pad, + fh->state, 0); mutex_lock(&ov13858->mutex); @@ -1275,7 +1275,7 @@ static const struct v4l2_ctrl_ops ov13858_ctrl_ops = { }; static int ov13858_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { /* Only one bayer order(GRBG) is supported */ @@ -1288,7 +1288,7 @@ static int ov13858_enum_mbus_code(struct v4l2_subdev *sd, } static int ov13858_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { if (fse->index >= ARRAY_SIZE(supported_modes)) @@ -1315,14 +1315,14 @@ static void ov13858_update_pad_format(const struct ov13858_mode *mode, } static int ov13858_do_get_pad_format(struct ov13858 *ov13858, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct v4l2_mbus_framefmt *framefmt; struct v4l2_subdev *sd = &ov13858->sd; if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - framefmt = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); fmt->format = *framefmt; } else { ov13858_update_pad_format(ov13858->cur_mode, fmt); @@ -1332,14 +1332,14 @@ static int ov13858_do_get_pad_format(struct ov13858 *ov13858, } static int ov13858_get_pad_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct ov13858 *ov13858 = to_ov13858(sd); int ret; mutex_lock(&ov13858->mutex); - ret = ov13858_do_get_pad_format(ov13858, cfg, fmt); + ret = ov13858_do_get_pad_format(ov13858, sd_state, fmt); mutex_unlock(&ov13858->mutex); return ret; @@ -1347,7 +1347,7 @@ static int ov13858_get_pad_format(struct v4l2_subdev *sd, static int ov13858_set_pad_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct ov13858 *ov13858 = to_ov13858(sd); @@ -1371,7 +1371,7 @@ ov13858_set_pad_format(struct v4l2_subdev *sd, fmt->format.width, fmt->format.height); ov13858_update_pad_format(mode, fmt); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - framefmt = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); *framefmt = fmt->format; } else { ov13858->cur_mode = mode; diff --git a/drivers/media/i2c/ov2640.c b/drivers/media/i2c/ov2640.c index 4a4bd5b665a1..4b75da55b260 100644 --- a/drivers/media/i2c/ov2640.c +++ b/drivers/media/i2c/ov2640.c @@ -913,7 +913,7 @@ err: } static int ov2640_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *mf = &format->format; @@ -925,7 +925,7 @@ static int ov2640_get_fmt(struct v4l2_subdev *sd, if (format->which == V4L2_SUBDEV_FORMAT_TRY) { #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API - mf = v4l2_subdev_get_try_format(sd, cfg, 0); + mf = v4l2_subdev_get_try_format(sd, sd_state, 0); format->format = *mf; return 0; #else @@ -946,7 +946,7 @@ static int ov2640_get_fmt(struct v4l2_subdev *sd, } static int ov2640_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *mf = &format->format; @@ -996,7 +996,7 @@ static int ov2640_set_fmt(struct v4l2_subdev *sd, /* select format */ priv->cfmt_code = mf->code; } else { - cfg->try_fmt = *mf; + sd_state->pads->try_fmt = *mf; } out: mutex_unlock(&priv->lock); @@ -1005,11 +1005,11 @@ out: } static int ov2640_init_cfg(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg) + struct v4l2_subdev_state *sd_state) { #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API struct v4l2_mbus_framefmt *try_fmt = - v4l2_subdev_get_try_format(sd, cfg, 0); + v4l2_subdev_get_try_format(sd, sd_state, 0); const struct ov2640_win_size *win = ov2640_select_win(SVGA_WIDTH, SVGA_HEIGHT); @@ -1026,7 +1026,7 @@ static int ov2640_init_cfg(struct v4l2_subdev *sd, } static int ov2640_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->pad || code->index >= ARRAY_SIZE(ov2640_codes)) @@ -1037,7 +1037,7 @@ static int ov2640_enum_mbus_code(struct v4l2_subdev *sd, } static int ov2640_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c index befef14aa86b..13ded5b2aa66 100644 --- a/drivers/media/i2c/ov2659.c +++ b/drivers/media/i2c/ov2659.c @@ -980,7 +980,7 @@ static int ov2659_init(struct v4l2_subdev *sd, u32 val) */ static int ov2659_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -996,7 +996,7 @@ static int ov2659_enum_mbus_code(struct v4l2_subdev *sd, } static int ov2659_enum_frame_sizes(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -1022,7 +1022,7 @@ static int ov2659_enum_frame_sizes(struct v4l2_subdev *sd, } static int ov2659_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -1034,7 +1034,7 @@ static int ov2659_get_fmt(struct v4l2_subdev *sd, #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API struct v4l2_mbus_framefmt *mf; - mf = v4l2_subdev_get_try_format(sd, cfg, 0); + mf = v4l2_subdev_get_try_format(sd, sd_state, 0); mutex_lock(&ov2659->lock); fmt->format = *mf; mutex_unlock(&ov2659->lock); @@ -1084,7 +1084,7 @@ static void __ov2659_try_frame_size(struct v4l2_mbus_framefmt *mf, } static int ov2659_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -1114,7 +1114,7 @@ static int ov2659_set_fmt(struct v4l2_subdev *sd, if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API - mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + mf = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); *mf = fmt->format; #endif } else { @@ -1311,7 +1311,7 @@ static int ov2659_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *format = - v4l2_subdev_get_try_format(sd, fh->pad, 0); + v4l2_subdev_get_try_format(sd, fh->state, 0); dev_dbg(&client->dev, "%s:\n", __func__); diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c index 178dfe985a25..906c711f6821 100644 --- a/drivers/media/i2c/ov2680.c +++ b/drivers/media/i2c/ov2680.c @@ -645,7 +645,7 @@ unlock: } static int ov2680_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct ov2680_dev *sensor = to_ov2680_dev(sd); @@ -659,7 +659,7 @@ static int ov2680_enum_mbus_code(struct v4l2_subdev *sd, } static int ov2680_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct ov2680_dev *sensor = to_ov2680_dev(sd); @@ -673,7 +673,8 @@ static int ov2680_get_fmt(struct v4l2_subdev *sd, if (format->which == V4L2_SUBDEV_FORMAT_TRY) { #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API - fmt = v4l2_subdev_get_try_format(&sensor->sd, cfg, format->pad); + fmt = v4l2_subdev_get_try_format(&sensor->sd, sd_state, + format->pad); #else ret = -EINVAL; #endif @@ -690,7 +691,7 @@ static int ov2680_get_fmt(struct v4l2_subdev *sd, } static int ov2680_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct ov2680_dev *sensor = to_ov2680_dev(sd); @@ -721,7 +722,7 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd, if (format->which == V4L2_SUBDEV_FORMAT_TRY) { #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API - try_fmt = v4l2_subdev_get_try_format(sd, cfg, 0); + try_fmt = v4l2_subdev_get_try_format(sd, sd_state, 0); format->format = *try_fmt; #endif goto unlock; @@ -743,22 +744,22 @@ unlock: } static int ov2680_init_cfg(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg) + struct v4l2_subdev_state *sd_state) { struct v4l2_subdev_format fmt = { - .which = cfg ? V4L2_SUBDEV_FORMAT_TRY - : V4L2_SUBDEV_FORMAT_ACTIVE, + .which = sd_state ? V4L2_SUBDEV_FORMAT_TRY + : V4L2_SUBDEV_FORMAT_ACTIVE, .format = { .width = 800, .height = 600, } }; - return ov2680_set_fmt(sd, cfg, &fmt); + return ov2680_set_fmt(sd, sd_state, &fmt); } static int ov2680_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { int index = fse->index; @@ -775,7 +776,7 @@ static int ov2680_enum_frame_size(struct v4l2_subdev *sd, } static int ov2680_enum_frame_interval(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_interval_enum *fie) { struct v4l2_fract tpf; diff --git a/drivers/media/i2c/ov2685.c b/drivers/media/i2c/ov2685.c index 2f3836dd8eed..b6e010ea3249 100644 --- a/drivers/media/i2c/ov2685.c +++ b/drivers/media/i2c/ov2685.c @@ -328,7 +328,7 @@ static void ov2685_fill_fmt(const struct ov2685_mode *mode, } static int ov2685_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct ov2685 *ov2685 = to_ov2685(sd); @@ -341,7 +341,7 @@ static int ov2685_set_fmt(struct v4l2_subdev *sd, } static int ov2685_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct ov2685 *ov2685 = to_ov2685(sd); @@ -353,7 +353,7 @@ static int ov2685_get_fmt(struct v4l2_subdev *sd, } static int ov2685_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->index >= ARRAY_SIZE(supported_modes)) @@ -365,7 +365,7 @@ static int ov2685_enum_mbus_code(struct v4l2_subdev *sd, } static int ov2685_enum_frame_sizes(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { int index = fse->index; @@ -493,7 +493,7 @@ static int ov2685_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) mutex_lock(&ov2685->mutex); - try_fmt = v4l2_subdev_get_try_format(sd, fh->pad, 0); + try_fmt = v4l2_subdev_get_try_format(sd, fh->state, 0); /* Initialize try_fmt */ ov2685_fill_fmt(&supported_modes[0], try_fmt); diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c index 54779f720f9d..599369a3d192 100644 --- a/drivers/media/i2c/ov2740.c +++ b/drivers/media/i2c/ov2740.c @@ -810,7 +810,7 @@ exit: } static int ov2740_set_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct ov2740 *ov2740 = to_ov2740(sd); @@ -825,7 +825,7 @@ static int ov2740_set_format(struct v4l2_subdev *sd, mutex_lock(&ov2740->mutex); ov2740_update_pad_format(mode, &fmt->format); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format; + *v4l2_subdev_get_try_format(sd, sd_state, fmt->pad) = fmt->format; } else { ov2740->cur_mode = mode; __v4l2_ctrl_s_ctrl(ov2740->link_freq, mode->link_freq_index); @@ -850,14 +850,15 @@ static int ov2740_set_format(struct v4l2_subdev *sd, } static int ov2740_get_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct ov2740 *ov2740 = to_ov2740(sd); mutex_lock(&ov2740->mutex); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) - fmt->format = *v4l2_subdev_get_try_format(&ov2740->sd, cfg, + fmt->format = *v4l2_subdev_get_try_format(&ov2740->sd, + sd_state, fmt->pad); else ov2740_update_pad_format(ov2740->cur_mode, &fmt->format); @@ -868,7 +869,7 @@ static int ov2740_get_format(struct v4l2_subdev *sd, } static int ov2740_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->index > 0) @@ -880,7 +881,7 @@ static int ov2740_enum_mbus_code(struct v4l2_subdev *sd, } static int ov2740_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { if (fse->index >= ARRAY_SIZE(supported_modes)) @@ -903,7 +904,7 @@ static int ov2740_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) mutex_lock(&ov2740->mutex); ov2740_update_pad_format(&supported_modes[0], - v4l2_subdev_get_try_format(sd, fh->pad, 0)); + v4l2_subdev_get_try_format(sd, fh->state, 0)); mutex_unlock(&ov2740->mutex); return 0; diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c index 5b9cc71df473..f6e1e51e0375 100644 --- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c @@ -2227,7 +2227,7 @@ find_mode: } static int ov5640_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct ov5640_dev *sensor = to_ov5640_dev(sd); @@ -2239,7 +2239,7 @@ static int ov5640_get_fmt(struct v4l2_subdev *sd, mutex_lock(&sensor->lock); if (format->which == V4L2_SUBDEV_FORMAT_TRY) - fmt = v4l2_subdev_get_try_format(&sensor->sd, cfg, + fmt = v4l2_subdev_get_try_format(&sensor->sd, sd_state, format->pad); else fmt = &sensor->fmt; @@ -2285,7 +2285,7 @@ static int ov5640_try_fmt_internal(struct v4l2_subdev *sd, } static int ov5640_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct ov5640_dev *sensor = to_ov5640_dev(sd); @@ -2310,7 +2310,7 @@ static int ov5640_set_fmt(struct v4l2_subdev *sd, goto out; if (format->which == V4L2_SUBDEV_FORMAT_TRY) - fmt = v4l2_subdev_get_try_format(sd, cfg, 0); + fmt = v4l2_subdev_get_try_format(sd, sd_state, 0); else fmt = &sensor->fmt; @@ -2818,7 +2818,7 @@ free_ctrls: } static int ov5640_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { if (fse->pad != 0) @@ -2838,7 +2838,7 @@ static int ov5640_enum_frame_size(struct v4l2_subdev *sd, static int ov5640_enum_frame_interval( struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_interval_enum *fie) { struct ov5640_dev *sensor = to_ov5640_dev(sd); @@ -2924,7 +2924,7 @@ out: } static int ov5640_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->pad != 0) diff --git a/drivers/media/i2c/ov5645.c b/drivers/media/i2c/ov5645.c index a6c17d15d754..368fa21e675e 100644 --- a/drivers/media/i2c/ov5645.c +++ b/drivers/media/i2c/ov5645.c @@ -837,7 +837,7 @@ static const struct v4l2_ctrl_ops ov5645_ctrl_ops = { }; static int ov5645_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->index > 0) @@ -849,7 +849,7 @@ static int ov5645_enum_mbus_code(struct v4l2_subdev *sd, } static int ov5645_enum_frame_size(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { if (fse->code != MEDIA_BUS_FMT_UYVY8_2X8) @@ -868,13 +868,13 @@ static int ov5645_enum_frame_size(struct v4l2_subdev *subdev, static struct v4l2_mbus_framefmt * __ov5645_get_pad_format(struct ov5645 *ov5645, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which) { switch (which) { case V4L2_SUBDEV_FORMAT_TRY: - return v4l2_subdev_get_try_format(&ov5645->sd, cfg, pad); + return v4l2_subdev_get_try_format(&ov5645->sd, sd_state, pad); case V4L2_SUBDEV_FORMAT_ACTIVE: return &ov5645->fmt; default: @@ -883,23 +883,25 @@ __ov5645_get_pad_format(struct ov5645 *ov5645, } static int ov5645_get_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct ov5645 *ov5645 = to_ov5645(sd); - format->format = *__ov5645_get_pad_format(ov5645, cfg, format->pad, + format->format = *__ov5645_get_pad_format(ov5645, sd_state, + format->pad, format->which); return 0; } static struct v4l2_rect * -__ov5645_get_pad_crop(struct ov5645 *ov5645, struct v4l2_subdev_pad_config *cfg, +__ov5645_get_pad_crop(struct ov5645 *ov5645, + struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which) { switch (which) { case V4L2_SUBDEV_FORMAT_TRY: - return v4l2_subdev_get_try_crop(&ov5645->sd, cfg, pad); + return v4l2_subdev_get_try_crop(&ov5645->sd, sd_state, pad); case V4L2_SUBDEV_FORMAT_ACTIVE: return &ov5645->crop; default: @@ -908,7 +910,7 @@ __ov5645_get_pad_crop(struct ov5645 *ov5645, struct v4l2_subdev_pad_config *cfg, } static int ov5645_set_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct ov5645 *ov5645 = to_ov5645(sd); @@ -917,8 +919,8 @@ static int ov5645_set_format(struct v4l2_subdev *sd, const struct ov5645_mode_info *new_mode; int ret; - __crop = __ov5645_get_pad_crop(ov5645, cfg, format->pad, - format->which); + __crop = __ov5645_get_pad_crop(ov5645, sd_state, format->pad, + format->which); new_mode = v4l2_find_nearest_size(ov5645_mode_info_data, ARRAY_SIZE(ov5645_mode_info_data), @@ -942,8 +944,8 @@ static int ov5645_set_format(struct v4l2_subdev *sd, ov5645->current_mode = new_mode; } - __format = __ov5645_get_pad_format(ov5645, cfg, format->pad, - format->which); + __format = __ov5645_get_pad_format(ov5645, sd_state, format->pad, + format->which); __format->width = __crop->width; __format->height = __crop->height; __format->code = MEDIA_BUS_FMT_UYVY8_2X8; @@ -956,21 +958,21 @@ static int ov5645_set_format(struct v4l2_subdev *sd, } static int ov5645_entity_init_cfg(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg) + struct v4l2_subdev_state *sd_state) { struct v4l2_subdev_format fmt = { 0 }; - fmt.which = cfg ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; + fmt.which = sd_state ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; fmt.format.width = 1920; fmt.format.height = 1080; - ov5645_set_format(subdev, cfg, &fmt); + ov5645_set_format(subdev, sd_state, &fmt); return 0; } static int ov5645_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct ov5645 *ov5645 = to_ov5645(sd); @@ -978,7 +980,7 @@ static int ov5645_get_selection(struct v4l2_subdev *sd, if (sel->target != V4L2_SEL_TGT_CROP) return -EINVAL; - sel->r = *__ov5645_get_pad_crop(ov5645, cfg, sel->pad, + sel->r = *__ov5645_get_pad_crop(ov5645, sd_state, sel->pad, sel->which); return 0; } diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c index 38faa74755e3..d346d18ce629 100644 --- a/drivers/media/i2c/ov5647.c +++ b/drivers/media/i2c/ov5647.c @@ -856,12 +856,13 @@ static const struct v4l2_subdev_core_ops ov5647_subdev_core_ops = { }; static const struct v4l2_rect * -__ov5647_get_pad_crop(struct ov5647 *ov5647, struct v4l2_subdev_pad_config *cfg, +__ov5647_get_pad_crop(struct ov5647 *ov5647, + struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which) { switch (which) { case V4L2_SUBDEV_FORMAT_TRY: - return v4l2_subdev_get_try_crop(&ov5647->sd, cfg, pad); + return v4l2_subdev_get_try_crop(&ov5647->sd, sd_state, pad); case V4L2_SUBDEV_FORMAT_ACTIVE: return &ov5647->mode->crop; } @@ -918,7 +919,7 @@ static const struct v4l2_subdev_video_ops ov5647_subdev_video_ops = { }; static int ov5647_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->index > 0) @@ -930,7 +931,7 @@ static int ov5647_enum_mbus_code(struct v4l2_subdev *sd, } static int ov5647_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { const struct v4l2_mbus_framefmt *fmt; @@ -949,7 +950,7 @@ static int ov5647_enum_frame_size(struct v4l2_subdev *sd, } static int ov5647_get_pad_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *fmt = &format->format; @@ -959,7 +960,8 @@ static int ov5647_get_pad_fmt(struct v4l2_subdev *sd, mutex_lock(&sensor->lock); switch (format->which) { case V4L2_SUBDEV_FORMAT_TRY: - sensor_format = v4l2_subdev_get_try_format(sd, cfg, format->pad); + sensor_format = v4l2_subdev_get_try_format(sd, sd_state, + format->pad); break; default: sensor_format = &sensor->mode->format; @@ -973,7 +975,7 @@ static int ov5647_get_pad_fmt(struct v4l2_subdev *sd, } static int ov5647_set_pad_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *fmt = &format->format; @@ -987,7 +989,7 @@ static int ov5647_set_pad_fmt(struct v4l2_subdev *sd, /* Update the sensor mode and apply at it at streamon time. */ mutex_lock(&sensor->lock); if (format->which == V4L2_SUBDEV_FORMAT_TRY) { - *v4l2_subdev_get_try_format(sd, cfg, format->pad) = mode->format; + *v4l2_subdev_get_try_format(sd, sd_state, format->pad) = mode->format; } else { int exposure_max, exposure_def; int hblank, vblank; @@ -1020,7 +1022,7 @@ static int ov5647_set_pad_fmt(struct v4l2_subdev *sd, } static int ov5647_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { switch (sel->target) { @@ -1028,7 +1030,7 @@ static int ov5647_get_selection(struct v4l2_subdev *sd, struct ov5647 *sensor = to_sensor(sd); mutex_lock(&sensor->lock); - sel->r = *__ov5647_get_pad_crop(sensor, cfg, sel->pad, + sel->r = *__ov5647_get_pad_crop(sensor, sd_state, sel->pad, sel->which); mutex_unlock(&sensor->lock); @@ -1104,8 +1106,8 @@ static int ov5647_detect(struct v4l2_subdev *sd) static int ov5647_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { struct v4l2_mbus_framefmt *format = - v4l2_subdev_get_try_format(sd, fh->pad, 0); - struct v4l2_rect *crop = v4l2_subdev_get_try_crop(sd, fh->pad, 0); + v4l2_subdev_get_try_format(sd, fh->state, 0); + struct v4l2_rect *crop = v4l2_subdev_get_try_crop(sd, fh->state, 0); crop->left = OV5647_PIXEL_ARRAY_LEFT; crop->top = OV5647_PIXEL_ARRAY_TOP; diff --git a/drivers/media/i2c/ov5648.c b/drivers/media/i2c/ov5648.c index 07e64ff0be3f..947d437ed0ef 100644 --- a/drivers/media/i2c/ov5648.c +++ b/drivers/media/i2c/ov5648.c @@ -2188,7 +2188,7 @@ static const struct v4l2_subdev_video_ops ov5648_subdev_video_ops = { /* Subdev Pad Operations */ static int ov5648_enum_mbus_code(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *config, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code_enum) { if (code_enum->index >= ARRAY_SIZE(ov5648_mbus_codes)) @@ -2217,7 +2217,7 @@ static void ov5648_mbus_format_fill(struct v4l2_mbus_framefmt *mbus_format, } static int ov5648_get_fmt(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *config, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct ov5648_sensor *sensor = ov5648_subdev_sensor(subdev); @@ -2226,7 +2226,7 @@ static int ov5648_get_fmt(struct v4l2_subdev *subdev, mutex_lock(&sensor->mutex); if (format->which == V4L2_SUBDEV_FORMAT_TRY) - *mbus_format = *v4l2_subdev_get_try_format(subdev, config, + *mbus_format = *v4l2_subdev_get_try_format(subdev, sd_state, format->pad); else ov5648_mbus_format_fill(mbus_format, sensor->state.mbus_code, @@ -2238,7 +2238,7 @@ static int ov5648_get_fmt(struct v4l2_subdev *subdev, } static int ov5648_set_fmt(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *config, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct ov5648_sensor *sensor = ov5648_subdev_sensor(subdev); @@ -2279,7 +2279,7 @@ static int ov5648_set_fmt(struct v4l2_subdev *subdev, ov5648_mbus_format_fill(mbus_format, mbus_code, mode); if (format->which == V4L2_SUBDEV_FORMAT_TRY) - *v4l2_subdev_get_try_format(subdev, config, format->pad) = + *v4l2_subdev_get_try_format(subdev, sd_state, format->pad) = *mbus_format; else if (sensor->state.mode != mode || sensor->state.mbus_code != mbus_code) @@ -2292,7 +2292,7 @@ complete: } static int ov5648_enum_frame_size(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *config, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *size_enum) { const struct ov5648_mode *mode; @@ -2309,7 +2309,7 @@ static int ov5648_enum_frame_size(struct v4l2_subdev *subdev, } static int ov5648_enum_frame_interval(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *config, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_interval_enum *interval_enum) { const struct ov5648_mode *mode = NULL; diff --git a/drivers/media/i2c/ov5670.c b/drivers/media/i2c/ov5670.c index 182f271f118f..49189926afd6 100644 --- a/drivers/media/i2c/ov5670.c +++ b/drivers/media/i2c/ov5670.c @@ -1937,7 +1937,7 @@ static int ov5670_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { struct ov5670 *ov5670 = to_ov5670(sd); struct v4l2_mbus_framefmt *try_fmt = - v4l2_subdev_get_try_format(sd, fh->pad, 0); + v4l2_subdev_get_try_format(sd, fh->state, 0); mutex_lock(&ov5670->mutex); @@ -2153,7 +2153,7 @@ error: } static int ov5670_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { /* Only one bayer order GRBG is supported */ @@ -2166,7 +2166,7 @@ static int ov5670_enum_mbus_code(struct v4l2_subdev *sd, } static int ov5670_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { if (fse->index >= ARRAY_SIZE(supported_modes)) @@ -2193,11 +2193,12 @@ static void ov5670_update_pad_format(const struct ov5670_mode *mode, } static int ov5670_do_get_pad_format(struct ov5670 *ov5670, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) - fmt->format = *v4l2_subdev_get_try_format(&ov5670->sd, cfg, + fmt->format = *v4l2_subdev_get_try_format(&ov5670->sd, + sd_state, fmt->pad); else ov5670_update_pad_format(ov5670->cur_mode, fmt); @@ -2206,21 +2207,21 @@ static int ov5670_do_get_pad_format(struct ov5670 *ov5670, } static int ov5670_get_pad_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct ov5670 *ov5670 = to_ov5670(sd); int ret; mutex_lock(&ov5670->mutex); - ret = ov5670_do_get_pad_format(ov5670, cfg, fmt); + ret = ov5670_do_get_pad_format(ov5670, sd_state, fmt); mutex_unlock(&ov5670->mutex); return ret; } static int ov5670_set_pad_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct ov5670 *ov5670 = to_ov5670(sd); @@ -2238,7 +2239,7 @@ static int ov5670_set_pad_format(struct v4l2_subdev *sd, fmt->format.width, fmt->format.height); ov5670_update_pad_format(mode, fmt); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format; + *v4l2_subdev_get_try_format(sd, sd_state, fmt->pad) = fmt->format; } else { ov5670->cur_mode = mode; __v4l2_ctrl_s_ctrl(ov5670->link_freq, mode->link_freq_index); diff --git a/drivers/media/i2c/ov5675.c b/drivers/media/i2c/ov5675.c index e7e297a23960..da5850b7ad07 100644 --- a/drivers/media/i2c/ov5675.c +++ b/drivers/media/i2c/ov5675.c @@ -923,7 +923,7 @@ static int __maybe_unused ov5675_resume(struct device *dev) } static int ov5675_set_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct ov5675 *ov5675 = to_ov5675(sd); @@ -938,7 +938,7 @@ static int ov5675_set_format(struct v4l2_subdev *sd, mutex_lock(&ov5675->mutex); ov5675_update_pad_format(mode, &fmt->format); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format; + *v4l2_subdev_get_try_format(sd, sd_state, fmt->pad) = fmt->format; } else { ov5675->cur_mode = mode; __v4l2_ctrl_s_ctrl(ov5675->link_freq, mode->link_freq_index); @@ -964,14 +964,15 @@ static int ov5675_set_format(struct v4l2_subdev *sd, } static int ov5675_get_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct ov5675 *ov5675 = to_ov5675(sd); mutex_lock(&ov5675->mutex); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) - fmt->format = *v4l2_subdev_get_try_format(&ov5675->sd, cfg, + fmt->format = *v4l2_subdev_get_try_format(&ov5675->sd, + sd_state, fmt->pad); else ov5675_update_pad_format(ov5675->cur_mode, &fmt->format); @@ -982,7 +983,7 @@ static int ov5675_get_format(struct v4l2_subdev *sd, } static int ov5675_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->index > 0) @@ -994,7 +995,7 @@ static int ov5675_enum_mbus_code(struct v4l2_subdev *sd, } static int ov5675_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { if (fse->index >= ARRAY_SIZE(supported_modes)) @@ -1017,7 +1018,7 @@ static int ov5675_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) mutex_lock(&ov5675->mutex); ov5675_update_pad_format(&supported_modes[0], - v4l2_subdev_get_try_format(sd, fh->pad, 0)); + v4l2_subdev_get_try_format(sd, fh->state, 0)); mutex_unlock(&ov5675->mutex); return 0; diff --git a/drivers/media/i2c/ov5695.c b/drivers/media/i2c/ov5695.c index 469d941813c6..439385938a51 100644 --- a/drivers/media/i2c/ov5695.c +++ b/drivers/media/i2c/ov5695.c @@ -806,7 +806,7 @@ ov5695_find_best_fit(struct v4l2_subdev_format *fmt) } static int ov5695_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct ov5695 *ov5695 = to_ov5695(sd); @@ -822,7 +822,7 @@ static int ov5695_set_fmt(struct v4l2_subdev *sd, fmt->format.field = V4L2_FIELD_NONE; if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API - *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format; + *v4l2_subdev_get_try_format(sd, sd_state, fmt->pad) = fmt->format; #endif } else { ov5695->cur_mode = mode; @@ -841,7 +841,7 @@ static int ov5695_set_fmt(struct v4l2_subdev *sd, } static int ov5695_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct ov5695 *ov5695 = to_ov5695(sd); @@ -850,7 +850,8 @@ static int ov5695_get_fmt(struct v4l2_subdev *sd, mutex_lock(&ov5695->mutex); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API - fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + fmt->format = *v4l2_subdev_get_try_format(sd, sd_state, + fmt->pad); #else mutex_unlock(&ov5695->mutex); return -EINVAL; @@ -867,7 +868,7 @@ static int ov5695_get_fmt(struct v4l2_subdev *sd, } static int ov5695_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->index != 0) @@ -878,7 +879,7 @@ static int ov5695_enum_mbus_code(struct v4l2_subdev *sd, } static int ov5695_enum_frame_sizes(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { if (fse->index >= ARRAY_SIZE(supported_modes)) @@ -1052,7 +1053,7 @@ static int ov5695_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { struct ov5695 *ov5695 = to_ov5695(sd); struct v4l2_mbus_framefmt *try_fmt = - v4l2_subdev_get_try_format(sd, fh->pad, 0); + v4l2_subdev_get_try_format(sd, fh->state, 0); const struct ov5695_mode *def_mode = &supported_modes[0]; mutex_lock(&ov5695->mutex); diff --git a/drivers/media/i2c/ov6650.c b/drivers/media/i2c/ov6650.c index 85dd13694bd2..f67412150b16 100644 --- a/drivers/media/i2c/ov6650.c +++ b/drivers/media/i2c/ov6650.c @@ -467,7 +467,7 @@ static int ov6650_s_power(struct v4l2_subdev *sd, int on) } static int ov6650_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -492,7 +492,7 @@ static int ov6650_get_selection(struct v4l2_subdev *sd, } static int ov6650_set_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -535,7 +535,7 @@ static int ov6650_set_selection(struct v4l2_subdev *sd, } static int ov6650_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *mf = &format->format; @@ -550,9 +550,9 @@ static int ov6650_get_fmt(struct v4l2_subdev *sd, /* update media bus format code and frame size */ if (format->which == V4L2_SUBDEV_FORMAT_TRY) { - mf->width = cfg->try_fmt.width; - mf->height = cfg->try_fmt.height; - mf->code = cfg->try_fmt.code; + mf->width = sd_state->pads->try_fmt.width; + mf->height = sd_state->pads->try_fmt.height; + mf->code = sd_state->pads->try_fmt.code; } else { mf->width = priv->rect.width >> priv->half_scale; @@ -668,7 +668,7 @@ static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) } static int ov6650_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *mf = &format->format; @@ -701,15 +701,15 @@ static int ov6650_set_fmt(struct v4l2_subdev *sd, if (format->which == V4L2_SUBDEV_FORMAT_TRY) { /* store media bus format code and frame size in pad config */ - cfg->try_fmt.width = mf->width; - cfg->try_fmt.height = mf->height; - cfg->try_fmt.code = mf->code; + sd_state->pads->try_fmt.width = mf->width; + sd_state->pads->try_fmt.height = mf->height; + sd_state->pads->try_fmt.code = mf->code; /* return default mbus frame format updated with pad config */ *mf = ov6650_def_fmt; - mf->width = cfg->try_fmt.width; - mf->height = cfg->try_fmt.height; - mf->code = cfg->try_fmt.code; + mf->width = sd_state->pads->try_fmt.width; + mf->height = sd_state->pads->try_fmt.height; + mf->code = sd_state->pads->try_fmt.code; } else { /* apply new media bus format code and frame size */ @@ -728,7 +728,7 @@ static int ov6650_set_fmt(struct v4l2_subdev *sd, } static int ov6650_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->pad || code->index >= ARRAY_SIZE(ov6650_codes)) diff --git a/drivers/media/i2c/ov7251.c b/drivers/media/i2c/ov7251.c index 0c10203f822b..ebb299f207e5 100644 --- a/drivers/media/i2c/ov7251.c +++ b/drivers/media/i2c/ov7251.c @@ -898,7 +898,7 @@ static const struct v4l2_ctrl_ops ov7251_ctrl_ops = { }; static int ov7251_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->index > 0) @@ -910,7 +910,7 @@ static int ov7251_enum_mbus_code(struct v4l2_subdev *sd, } static int ov7251_enum_frame_size(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { if (fse->code != MEDIA_BUS_FMT_Y10_1X10) @@ -928,7 +928,7 @@ static int ov7251_enum_frame_size(struct v4l2_subdev *subdev, } static int ov7251_enum_frame_ival(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_interval_enum *fie) { unsigned int index = fie->index; @@ -950,13 +950,13 @@ static int ov7251_enum_frame_ival(struct v4l2_subdev *subdev, static struct v4l2_mbus_framefmt * __ov7251_get_pad_format(struct ov7251 *ov7251, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which) { switch (which) { case V4L2_SUBDEV_FORMAT_TRY: - return v4l2_subdev_get_try_format(&ov7251->sd, cfg, pad); + return v4l2_subdev_get_try_format(&ov7251->sd, sd_state, pad); case V4L2_SUBDEV_FORMAT_ACTIVE: return &ov7251->fmt; default: @@ -965,13 +965,14 @@ __ov7251_get_pad_format(struct ov7251 *ov7251, } static int ov7251_get_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct ov7251 *ov7251 = to_ov7251(sd); mutex_lock(&ov7251->lock); - format->format = *__ov7251_get_pad_format(ov7251, cfg, format->pad, + format->format = *__ov7251_get_pad_format(ov7251, sd_state, + format->pad, format->which); mutex_unlock(&ov7251->lock); @@ -979,12 +980,13 @@ static int ov7251_get_format(struct v4l2_subdev *sd, } static struct v4l2_rect * -__ov7251_get_pad_crop(struct ov7251 *ov7251, struct v4l2_subdev_pad_config *cfg, +__ov7251_get_pad_crop(struct ov7251 *ov7251, + struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which) { switch (which) { case V4L2_SUBDEV_FORMAT_TRY: - return v4l2_subdev_get_try_crop(&ov7251->sd, cfg, pad); + return v4l2_subdev_get_try_crop(&ov7251->sd, sd_state, pad); case V4L2_SUBDEV_FORMAT_ACTIVE: return &ov7251->crop; default: @@ -1027,7 +1029,7 @@ ov7251_find_mode_by_ival(struct ov7251 *ov7251, struct v4l2_fract *timeperframe) } static int ov7251_set_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct ov7251 *ov7251 = to_ov7251(sd); @@ -1038,7 +1040,8 @@ static int ov7251_set_format(struct v4l2_subdev *sd, mutex_lock(&ov7251->lock); - __crop = __ov7251_get_pad_crop(ov7251, cfg, format->pad, format->which); + __crop = __ov7251_get_pad_crop(ov7251, sd_state, format->pad, + format->which); new_mode = v4l2_find_nearest_size(ov7251_mode_info_data, ARRAY_SIZE(ov7251_mode_info_data), @@ -1077,7 +1080,7 @@ static int ov7251_set_format(struct v4l2_subdev *sd, ov7251->current_mode = new_mode; } - __format = __ov7251_get_pad_format(ov7251, cfg, format->pad, + __format = __ov7251_get_pad_format(ov7251, sd_state, format->pad, format->which); __format->width = __crop->width; __format->height = __crop->height; @@ -1098,24 +1101,24 @@ exit: } static int ov7251_entity_init_cfg(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg) + struct v4l2_subdev_state *sd_state) { struct v4l2_subdev_format fmt = { - .which = cfg ? V4L2_SUBDEV_FORMAT_TRY - : V4L2_SUBDEV_FORMAT_ACTIVE, + .which = sd_state ? V4L2_SUBDEV_FORMAT_TRY + : V4L2_SUBDEV_FORMAT_ACTIVE, .format = { .width = 640, .height = 480 } }; - ov7251_set_format(subdev, cfg, &fmt); + ov7251_set_format(subdev, sd_state, &fmt); return 0; } static int ov7251_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct ov7251 *ov7251 = to_ov7251(sd); @@ -1124,7 +1127,7 @@ static int ov7251_get_selection(struct v4l2_subdev *sd, return -EINVAL; mutex_lock(&ov7251->lock); - sel->r = *__ov7251_get_pad_crop(ov7251, cfg, sel->pad, + sel->r = *__ov7251_get_pad_crop(ov7251, sd_state, sel->pad, sel->which); mutex_unlock(&ov7251->lock); diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c index d2df811b1a40..196746423116 100644 --- a/drivers/media/i2c/ov7670.c +++ b/drivers/media/i2c/ov7670.c @@ -960,7 +960,7 @@ static int ov7670_set_hw(struct v4l2_subdev *sd, int hstart, int hstop, static int ov7670_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->pad || code->index >= N_OV7670_FMTS) @@ -1105,7 +1105,7 @@ static int ov7670_apply_fmt(struct v4l2_subdev *sd) * Set a format. */ static int ov7670_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct ov7670_info *info = to_state(sd); @@ -1122,7 +1122,8 @@ static int ov7670_set_fmt(struct v4l2_subdev *sd, if (ret) return ret; #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API - mbus_fmt = v4l2_subdev_get_try_format(sd, cfg, format->pad); + mbus_fmt = v4l2_subdev_get_try_format(sd, sd_state, + format->pad); *mbus_fmt = format->format; #endif return 0; @@ -1144,7 +1145,7 @@ static int ov7670_set_fmt(struct v4l2_subdev *sd, } static int ov7670_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct ov7670_info *info = to_state(sd); @@ -1154,7 +1155,7 @@ static int ov7670_get_fmt(struct v4l2_subdev *sd, if (format->which == V4L2_SUBDEV_FORMAT_TRY) { #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API - mbus_fmt = v4l2_subdev_get_try_format(sd, cfg, 0); + mbus_fmt = v4l2_subdev_get_try_format(sd, sd_state, 0); format->format = *mbus_fmt; return 0; #else @@ -1202,7 +1203,7 @@ static int ov7670_s_frame_interval(struct v4l2_subdev *sd, static int ov7670_frame_rates[] = { 30, 15, 10, 5, 1 }; static int ov7670_enum_frame_interval(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_interval_enum *fie) { struct ov7670_info *info = to_state(sd); @@ -1241,7 +1242,7 @@ static int ov7670_enum_frame_interval(struct v4l2_subdev *sd, * Frame size enumeration */ static int ov7670_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { struct ov7670_info *info = to_state(sd); @@ -1724,7 +1725,7 @@ static void ov7670_get_default_format(struct v4l2_subdev *sd, static int ov7670_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { struct v4l2_mbus_framefmt *format = - v4l2_subdev_get_try_format(sd, fh->pad, 0); + v4l2_subdev_get_try_format(sd, fh->state, 0); ov7670_get_default_format(sd, format); diff --git a/drivers/media/i2c/ov772x.c b/drivers/media/i2c/ov772x.c index d94cf2d39c2a..78602a2f70b0 100644 --- a/drivers/media/i2c/ov772x.c +++ b/drivers/media/i2c/ov772x.c @@ -1157,7 +1157,7 @@ ov772x_set_fmt_error: } static int ov772x_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct ov772x_priv *priv = to_ov772x(sd); @@ -1179,7 +1179,7 @@ static int ov772x_get_selection(struct v4l2_subdev *sd, } static int ov772x_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *mf = &format->format; @@ -1198,7 +1198,7 @@ static int ov772x_get_fmt(struct v4l2_subdev *sd, } static int ov772x_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct ov772x_priv *priv = to_ov772x(sd); @@ -1222,7 +1222,7 @@ static int ov772x_set_fmt(struct v4l2_subdev *sd, mf->xfer_func = V4L2_XFER_FUNC_DEFAULT; if (format->which == V4L2_SUBDEV_FORMAT_TRY) { - cfg->try_fmt = *mf; + sd_state->pads->try_fmt = *mf; return 0; } @@ -1320,7 +1320,7 @@ static const struct v4l2_subdev_core_ops ov772x_subdev_core_ops = { }; static int ov772x_enum_frame_interval(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_interval_enum *fie) { if (fie->pad || fie->index >= ARRAY_SIZE(ov772x_frame_intervals)) @@ -1338,7 +1338,7 @@ static int ov772x_enum_frame_interval(struct v4l2_subdev *sd, } static int ov772x_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->pad || code->index >= ARRAY_SIZE(ov772x_cfmts)) diff --git a/drivers/media/i2c/ov7740.c b/drivers/media/i2c/ov7740.c index e0ff6506a543..2539cfee85c8 100644 --- a/drivers/media/i2c/ov7740.c +++ b/drivers/media/i2c/ov7740.c @@ -707,7 +707,7 @@ static const struct ov7740_pixfmt ov7740_formats[] = { #define N_OV7740_FMTS ARRAY_SIZE(ov7740_formats) static int ov7740_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->pad || code->index >= N_OV7740_FMTS) @@ -719,7 +719,7 @@ static int ov7740_enum_mbus_code(struct v4l2_subdev *sd, } static int ov7740_enum_frame_interval(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_interval_enum *fie) { if (fie->pad) @@ -738,7 +738,7 @@ static int ov7740_enum_frame_interval(struct v4l2_subdev *sd, } static int ov7740_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { if (fse->pad) @@ -801,7 +801,7 @@ static int ov7740_try_fmt_internal(struct v4l2_subdev *sd, } static int ov7740_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev); @@ -823,7 +823,8 @@ static int ov7740_set_fmt(struct v4l2_subdev *sd, if (ret) goto error; #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API - mbus_fmt = v4l2_subdev_get_try_format(sd, cfg, format->pad); + mbus_fmt = v4l2_subdev_get_try_format(sd, sd_state, + format->pad); *mbus_fmt = format->format; #endif mutex_unlock(&ov7740->mutex); @@ -846,7 +847,7 @@ error: } static int ov7740_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev); @@ -858,7 +859,7 @@ static int ov7740_get_fmt(struct v4l2_subdev *sd, mutex_lock(&ov7740->mutex); if (format->which == V4L2_SUBDEV_FORMAT_TRY) { #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API - mbus_fmt = v4l2_subdev_get_try_format(sd, cfg, 0); + mbus_fmt = v4l2_subdev_get_try_format(sd, sd_state, 0); format->format = *mbus_fmt; ret = 0; #else @@ -903,7 +904,7 @@ static int ov7740_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev); struct v4l2_mbus_framefmt *format = - v4l2_subdev_get_try_format(sd, fh->pad, 0); + v4l2_subdev_get_try_format(sd, fh->state, 0); mutex_lock(&ov7740->mutex); ov7740_get_default_format(sd, format); diff --git a/drivers/media/i2c/ov8856.c b/drivers/media/i2c/ov8856.c index a6bc665a6430..88e19f30d376 100644 --- a/drivers/media/i2c/ov8856.c +++ b/drivers/media/i2c/ov8856.c @@ -2083,7 +2083,7 @@ static int __maybe_unused ov8856_resume(struct device *dev) } static int ov8856_set_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct ov8856 *ov8856 = to_ov8856(sd); @@ -2098,7 +2098,7 @@ static int ov8856_set_format(struct v4l2_subdev *sd, mutex_lock(&ov8856->mutex); ov8856_update_pad_format(mode, &fmt->format); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format; + *v4l2_subdev_get_try_format(sd, sd_state, fmt->pad) = fmt->format; } else { ov8856->cur_mode = mode; __v4l2_ctrl_s_ctrl(ov8856->link_freq, mode->link_freq_index); @@ -2129,14 +2129,15 @@ static int ov8856_set_format(struct v4l2_subdev *sd, } static int ov8856_get_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct ov8856 *ov8856 = to_ov8856(sd); mutex_lock(&ov8856->mutex); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) - fmt->format = *v4l2_subdev_get_try_format(&ov8856->sd, cfg, + fmt->format = *v4l2_subdev_get_try_format(&ov8856->sd, + sd_state, fmt->pad); else ov8856_update_pad_format(ov8856->cur_mode, &fmt->format); @@ -2147,7 +2148,7 @@ static int ov8856_get_format(struct v4l2_subdev *sd, } static int ov8856_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { /* Only one bayer order GRBG is supported */ @@ -2160,7 +2161,7 @@ static int ov8856_enum_mbus_code(struct v4l2_subdev *sd, } static int ov8856_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { struct ov8856 *ov8856 = to_ov8856(sd); @@ -2185,7 +2186,7 @@ static int ov8856_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) mutex_lock(&ov8856->mutex); ov8856_update_pad_format(&ov8856->priv_lane->supported_modes[0], - v4l2_subdev_get_try_format(sd, fh->pad, 0)); + v4l2_subdev_get_try_format(sd, fh->state, 0)); mutex_unlock(&ov8856->mutex); return 0; diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c index b16c82559800..ce50f3ea87b8 100644 --- a/drivers/media/i2c/ov8865.c +++ b/drivers/media/i2c/ov8865.c @@ -2542,7 +2542,7 @@ static const struct v4l2_subdev_video_ops ov8865_subdev_video_ops = { /* Subdev Pad Operations */ static int ov8865_enum_mbus_code(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *config, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code_enum) { if (code_enum->index >= ARRAY_SIZE(ov8865_mbus_codes)) @@ -2571,7 +2571,7 @@ static void ov8865_mbus_format_fill(struct v4l2_mbus_framefmt *mbus_format, } static int ov8865_get_fmt(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *config, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct ov8865_sensor *sensor = ov8865_subdev_sensor(subdev); @@ -2580,7 +2580,7 @@ static int ov8865_get_fmt(struct v4l2_subdev *subdev, mutex_lock(&sensor->mutex); if (format->which == V4L2_SUBDEV_FORMAT_TRY) - *mbus_format = *v4l2_subdev_get_try_format(subdev, config, + *mbus_format = *v4l2_subdev_get_try_format(subdev, sd_state, format->pad); else ov8865_mbus_format_fill(mbus_format, sensor->state.mbus_code, @@ -2592,7 +2592,7 @@ static int ov8865_get_fmt(struct v4l2_subdev *subdev, } static int ov8865_set_fmt(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *config, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct ov8865_sensor *sensor = ov8865_subdev_sensor(subdev); @@ -2633,7 +2633,7 @@ static int ov8865_set_fmt(struct v4l2_subdev *subdev, ov8865_mbus_format_fill(mbus_format, mbus_code, mode); if (format->which == V4L2_SUBDEV_FORMAT_TRY) - *v4l2_subdev_get_try_format(subdev, config, format->pad) = + *v4l2_subdev_get_try_format(subdev, sd_state, format->pad) = *mbus_format; else if (sensor->state.mode != mode || sensor->state.mbus_code != mbus_code) @@ -2646,7 +2646,7 @@ complete: } static int ov8865_enum_frame_size(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *config, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *size_enum) { const struct ov8865_mode *mode; @@ -2663,7 +2663,7 @@ static int ov8865_enum_frame_size(struct v4l2_subdev *subdev, } static int ov8865_enum_frame_interval(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *config, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_interval_enum *interval_enum) { const struct ov8865_mode *mode = NULL; diff --git a/drivers/media/i2c/ov9640.c b/drivers/media/i2c/ov9640.c index d36b04c49628..0bab8c2cf160 100644 --- a/drivers/media/i2c/ov9640.c +++ b/drivers/media/i2c/ov9640.c @@ -519,7 +519,7 @@ static int ov9640_s_fmt(struct v4l2_subdev *sd, } static int ov9640_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *mf = &format->format; @@ -547,13 +547,13 @@ static int ov9640_set_fmt(struct v4l2_subdev *sd, if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) return ov9640_s_fmt(sd, mf); - cfg->try_fmt = *mf; + sd_state->pads->try_fmt = *mf; return 0; } static int ov9640_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->pad || code->index >= ARRAY_SIZE(ov9640_codes)) @@ -565,7 +565,7 @@ static int ov9640_enum_mbus_code(struct v4l2_subdev *sd, } static int ov9640_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) diff --git a/drivers/media/i2c/ov9650.c b/drivers/media/i2c/ov9650.c index a9f13dc2f053..c313e11a9754 100644 --- a/drivers/media/i2c/ov9650.c +++ b/drivers/media/i2c/ov9650.c @@ -1070,7 +1070,7 @@ static void ov965x_get_default_format(struct v4l2_mbus_framefmt *mf) } static int ov965x_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->index >= ARRAY_SIZE(ov965x_formats)) @@ -1081,7 +1081,7 @@ static int ov965x_enum_mbus_code(struct v4l2_subdev *sd, } static int ov965x_enum_frame_sizes(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { int i = ARRAY_SIZE(ov965x_formats); @@ -1167,14 +1167,14 @@ static int ov965x_s_frame_interval(struct v4l2_subdev *sd, } static int ov965x_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct ov965x *ov965x = to_ov965x(sd); struct v4l2_mbus_framefmt *mf; if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - mf = v4l2_subdev_get_try_format(sd, cfg, 0); + mf = v4l2_subdev_get_try_format(sd, sd_state, 0); fmt->format = *mf; return 0; } @@ -1212,7 +1212,7 @@ static void __ov965x_try_frame_size(struct v4l2_mbus_framefmt *mf, } static int ov965x_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { unsigned int index = ARRAY_SIZE(ov965x_formats); @@ -1234,8 +1234,9 @@ static int ov965x_set_fmt(struct v4l2_subdev *sd, mutex_lock(&ov965x->lock); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - if (cfg) { - mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + if (sd_state) { + mf = v4l2_subdev_get_try_format(sd, sd_state, + fmt->pad); *mf = fmt->format; } } else { @@ -1364,7 +1365,7 @@ static int ov965x_s_stream(struct v4l2_subdev *sd, int on) static int ov965x_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { struct v4l2_mbus_framefmt *mf = - v4l2_subdev_get_try_format(sd, fh->pad, 0); + v4l2_subdev_get_try_format(sd, fh->state, 0); ov965x_get_default_format(mf); return 0; diff --git a/drivers/media/i2c/ov9734.c b/drivers/media/i2c/ov9734.c index ba156683c533..af50c66cf5ce 100644 --- a/drivers/media/i2c/ov9734.c +++ b/drivers/media/i2c/ov9734.c @@ -705,7 +705,7 @@ exit: } static int ov9734_set_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct ov9734 *ov9734 = to_ov9734(sd); @@ -720,7 +720,7 @@ static int ov9734_set_format(struct v4l2_subdev *sd, mutex_lock(&ov9734->mutex); ov9734_update_pad_format(mode, &fmt->format); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format; + *v4l2_subdev_get_try_format(sd, sd_state, fmt->pad) = fmt->format; } else { ov9734->cur_mode = mode; __v4l2_ctrl_s_ctrl(ov9734->link_freq, mode->link_freq_index); @@ -746,14 +746,15 @@ static int ov9734_set_format(struct v4l2_subdev *sd, } static int ov9734_get_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct ov9734 *ov9734 = to_ov9734(sd); mutex_lock(&ov9734->mutex); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) - fmt->format = *v4l2_subdev_get_try_format(&ov9734->sd, cfg, + fmt->format = *v4l2_subdev_get_try_format(&ov9734->sd, + sd_state, fmt->pad); else ov9734_update_pad_format(ov9734->cur_mode, &fmt->format); @@ -764,7 +765,7 @@ static int ov9734_get_format(struct v4l2_subdev *sd, } static int ov9734_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->index > 0) @@ -776,7 +777,7 @@ static int ov9734_enum_mbus_code(struct v4l2_subdev *sd, } static int ov9734_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { if (fse->index >= ARRAY_SIZE(supported_modes)) @@ -799,7 +800,7 @@ static int ov9734_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) mutex_lock(&ov9734->mutex); ov9734_update_pad_format(&supported_modes[0], - v4l2_subdev_get_try_format(sd, fh->pad, 0)); + v4l2_subdev_get_try_format(sd, fh->state, 0)); mutex_unlock(&ov9734->mutex); return 0; diff --git a/drivers/media/i2c/rdacm20.c b/drivers/media/i2c/rdacm20.c index 90eb73f0e6e9..a4b639cf8063 100644 --- a/drivers/media/i2c/rdacm20.c +++ b/drivers/media/i2c/rdacm20.c @@ -403,7 +403,7 @@ static int rdacm20_s_stream(struct v4l2_subdev *sd, int enable) } static int rdacm20_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->pad || code->index > 0) @@ -415,7 +415,7 @@ static int rdacm20_enum_mbus_code(struct v4l2_subdev *sd, } static int rdacm20_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *mf = &format->format; diff --git a/drivers/media/i2c/rdacm21.c b/drivers/media/i2c/rdacm21.c index 179d107f494c..5b78d8185773 100644 --- a/drivers/media/i2c/rdacm21.c +++ b/drivers/media/i2c/rdacm21.c @@ -281,7 +281,7 @@ static int rdacm21_s_stream(struct v4l2_subdev *sd, int enable) } static int rdacm21_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->pad || code->index > 0) @@ -293,7 +293,7 @@ static int rdacm21_enum_mbus_code(struct v4l2_subdev *sd, } static int rdacm21_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *mf = &format->format; diff --git a/drivers/media/i2c/rj54n1cb0c.c b/drivers/media/i2c/rj54n1cb0c.c index 4cc51e001874..2e4018c26912 100644 --- a/drivers/media/i2c/rj54n1cb0c.c +++ b/drivers/media/i2c/rj54n1cb0c.c @@ -488,7 +488,7 @@ static int reg_write_multiple(struct i2c_client *client, } static int rj54n1_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->pad || code->index >= ARRAY_SIZE(rj54n1_colour_fmts)) @@ -541,7 +541,7 @@ static int rj54n1_sensor_scale(struct v4l2_subdev *sd, s32 *in_w, s32 *in_h, s32 *out_w, s32 *out_h); static int rj54n1_set_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -578,7 +578,7 @@ static int rj54n1_set_selection(struct v4l2_subdev *sd, } static int rj54n1_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -603,7 +603,7 @@ static int rj54n1_get_selection(struct v4l2_subdev *sd, } static int rj54n1_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *mf = &format->format; @@ -973,7 +973,7 @@ static int rj54n1_reg_init(struct i2c_client *client) } static int rj54n1_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *mf = &format->format; @@ -1009,7 +1009,7 @@ static int rj54n1_set_fmt(struct v4l2_subdev *sd, &mf->height, 84, RJ54N1_MAX_HEIGHT, align, 0); if (format->which == V4L2_SUBDEV_FORMAT_TRY) { - cfg->try_fmt = *mf; + sd_state->pads->try_fmt = *mf; return 0; } diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c index 71804a70bc6d..e2b88c5e4f98 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c +++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c @@ -817,7 +817,7 @@ static const struct s5c73m3_frame_size *s5c73m3_find_frame_size( } static void s5c73m3_oif_try_format(struct s5c73m3 *state, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt, const struct s5c73m3_frame_size **fs) { @@ -844,8 +844,8 @@ static void s5c73m3_oif_try_format(struct s5c73m3 *state, *fs = state->oif_pix_size[RES_ISP]; else *fs = s5c73m3_find_frame_size( - v4l2_subdev_get_try_format(sd, cfg, - OIF_ISP_PAD), + v4l2_subdev_get_try_format(sd, sd_state, + OIF_ISP_PAD), RES_ISP); break; } @@ -854,7 +854,7 @@ static void s5c73m3_oif_try_format(struct s5c73m3 *state, } static void s5c73m3_try_format(struct s5c73m3 *state, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt, const struct s5c73m3_frame_size **fs) { @@ -946,7 +946,7 @@ static int s5c73m3_oif_s_frame_interval(struct v4l2_subdev *sd, } static int s5c73m3_oif_enum_frame_interval(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_interval_enum *fie) { struct s5c73m3 *state = oif_sd_to_s5c73m3(sd); @@ -984,7 +984,7 @@ static int s5c73m3_oif_get_pad_code(int pad, int index) } static int s5c73m3_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct s5c73m3 *state = sensor_sd_to_s5c73m3(sd); @@ -992,7 +992,8 @@ static int s5c73m3_get_fmt(struct v4l2_subdev *sd, u32 code; if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + fmt->format = *v4l2_subdev_get_try_format(sd, sd_state, + fmt->pad); return 0; } @@ -1018,7 +1019,7 @@ static int s5c73m3_get_fmt(struct v4l2_subdev *sd, } static int s5c73m3_oif_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct s5c73m3 *state = oif_sd_to_s5c73m3(sd); @@ -1026,7 +1027,8 @@ static int s5c73m3_oif_get_fmt(struct v4l2_subdev *sd, u32 code; if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + fmt->format = *v4l2_subdev_get_try_format(sd, sd_state, + fmt->pad); return 0; } @@ -1056,7 +1058,7 @@ static int s5c73m3_oif_get_fmt(struct v4l2_subdev *sd, } static int s5c73m3_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { const struct s5c73m3_frame_size *frame_size = NULL; @@ -1066,10 +1068,10 @@ static int s5c73m3_set_fmt(struct v4l2_subdev *sd, mutex_lock(&state->lock); - s5c73m3_try_format(state, cfg, fmt, &frame_size); + s5c73m3_try_format(state, sd_state, fmt, &frame_size); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + mf = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); *mf = fmt->format; } else { switch (fmt->pad) { @@ -1095,7 +1097,7 @@ static int s5c73m3_set_fmt(struct v4l2_subdev *sd, } static int s5c73m3_oif_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { const struct s5c73m3_frame_size *frame_size = NULL; @@ -1105,13 +1107,14 @@ static int s5c73m3_oif_set_fmt(struct v4l2_subdev *sd, mutex_lock(&state->lock); - s5c73m3_oif_try_format(state, cfg, fmt, &frame_size); + s5c73m3_oif_try_format(state, sd_state, fmt, &frame_size); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + mf = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); *mf = fmt->format; if (fmt->pad == OIF_ISP_PAD) { - mf = v4l2_subdev_get_try_format(sd, cfg, OIF_SOURCE_PAD); + mf = v4l2_subdev_get_try_format(sd, sd_state, + OIF_SOURCE_PAD); mf->width = fmt->format.width; mf->height = fmt->format.height; } @@ -1183,7 +1186,7 @@ static int s5c73m3_oif_set_frame_desc(struct v4l2_subdev *sd, unsigned int pad, } static int s5c73m3_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { static const int codes[] = { @@ -1199,7 +1202,7 @@ static int s5c73m3_enum_mbus_code(struct v4l2_subdev *sd, } static int s5c73m3_oif_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { int ret; @@ -1214,7 +1217,7 @@ static int s5c73m3_oif_enum_mbus_code(struct v4l2_subdev *sd, } static int s5c73m3_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { int idx; @@ -1241,7 +1244,7 @@ static int s5c73m3_enum_frame_size(struct v4l2_subdev *sd, } static int s5c73m3_oif_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { struct s5c73m3 *state = oif_sd_to_s5c73m3(sd); @@ -1259,7 +1262,7 @@ static int s5c73m3_oif_enum_frame_size(struct v4l2_subdev *sd, if (fse->which == V4L2_SUBDEV_FORMAT_TRY) { struct v4l2_mbus_framefmt *mf; - mf = v4l2_subdev_get_try_format(sd, cfg, + mf = v4l2_subdev_get_try_format(sd, sd_state, OIF_ISP_PAD); w = mf->width; @@ -1315,11 +1318,11 @@ static int s5c73m3_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { struct v4l2_mbus_framefmt *mf; - mf = v4l2_subdev_get_try_format(sd, fh->pad, S5C73M3_ISP_PAD); + mf = v4l2_subdev_get_try_format(sd, fh->state, S5C73M3_ISP_PAD); s5c73m3_fill_mbus_fmt(mf, &s5c73m3_isp_resolutions[1], S5C73M3_ISP_FMT); - mf = v4l2_subdev_get_try_format(sd, fh->pad, S5C73M3_JPEG_PAD); + mf = v4l2_subdev_get_try_format(sd, fh->state, S5C73M3_JPEG_PAD); s5c73m3_fill_mbus_fmt(mf, &s5c73m3_jpeg_resolutions[1], S5C73M3_JPEG_FMT); @@ -1330,15 +1333,15 @@ static int s5c73m3_oif_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { struct v4l2_mbus_framefmt *mf; - mf = v4l2_subdev_get_try_format(sd, fh->pad, OIF_ISP_PAD); + mf = v4l2_subdev_get_try_format(sd, fh->state, OIF_ISP_PAD); s5c73m3_fill_mbus_fmt(mf, &s5c73m3_isp_resolutions[1], S5C73M3_ISP_FMT); - mf = v4l2_subdev_get_try_format(sd, fh->pad, OIF_JPEG_PAD); + mf = v4l2_subdev_get_try_format(sd, fh->state, OIF_JPEG_PAD); s5c73m3_fill_mbus_fmt(mf, &s5c73m3_jpeg_resolutions[1], S5C73M3_JPEG_FMT); - mf = v4l2_subdev_get_try_format(sd, fh->pad, OIF_SOURCE_PAD); + mf = v4l2_subdev_get_try_format(sd, fh->state, OIF_SOURCE_PAD); s5c73m3_fill_mbus_fmt(mf, &s5c73m3_isp_resolutions[1], S5C73M3_ISP_FMT); return 0; diff --git a/drivers/media/i2c/s5k4ecgx.c b/drivers/media/i2c/s5k4ecgx.c index 4e97309a67f4..af9a305242cd 100644 --- a/drivers/media/i2c/s5k4ecgx.c +++ b/drivers/media/i2c/s5k4ecgx.c @@ -525,7 +525,7 @@ static int s5k4ecgx_try_frame_size(struct v4l2_mbus_framefmt *mf, } static int s5k4ecgx_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->index >= ARRAY_SIZE(s5k4ecgx_formats)) @@ -535,15 +535,16 @@ static int s5k4ecgx_enum_mbus_code(struct v4l2_subdev *sd, return 0; } -static int s5k4ecgx_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_format *fmt) +static int s5k4ecgx_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_format *fmt) { struct s5k4ecgx *priv = to_s5k4ecgx(sd); struct v4l2_mbus_framefmt *mf; if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - if (cfg) { - mf = v4l2_subdev_get_try_format(sd, cfg, 0); + if (sd_state) { + mf = v4l2_subdev_get_try_format(sd, sd_state, 0); fmt->format = *mf; } return 0; @@ -575,7 +576,8 @@ static const struct s5k4ecgx_pixfmt *s5k4ecgx_try_fmt(struct v4l2_subdev *sd, return &s5k4ecgx_formats[i]; } -static int s5k4ecgx_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, +static int s5k4ecgx_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct s5k4ecgx *priv = to_s5k4ecgx(sd); @@ -590,8 +592,8 @@ static int s5k4ecgx_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_confi fmt->format.field = V4L2_FIELD_NONE; if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - if (cfg) { - mf = v4l2_subdev_get_try_format(sd, cfg, 0); + if (sd_state) { + mf = v4l2_subdev_get_try_format(sd, sd_state, 0); *mf = fmt->format; } return 0; @@ -686,7 +688,9 @@ static int s5k4ecgx_registered(struct v4l2_subdev *sd) */ static int s5k4ecgx_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { - struct v4l2_mbus_framefmt *mf = v4l2_subdev_get_try_format(sd, fh->pad, 0); + struct v4l2_mbus_framefmt *mf = v4l2_subdev_get_try_format(sd, + fh->state, + 0); mf->width = s5k4ecgx_prev_sizes[0].size.width; mf->height = s5k4ecgx_prev_sizes[0].size.height; diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c index bc560817e504..6a5dceb699a8 100644 --- a/drivers/media/i2c/s5k5baf.c +++ b/drivers/media/i2c/s5k5baf.c @@ -1180,7 +1180,7 @@ static int s5k5baf_s_frame_interval(struct v4l2_subdev *sd, * V4L2 subdev pad level and video operations */ static int s5k5baf_enum_frame_interval(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_interval_enum *fie) { if (fie->index > S5K5BAF_MAX_FR_TIME - S5K5BAF_MIN_FR_TIME || @@ -1199,7 +1199,7 @@ static int s5k5baf_enum_frame_interval(struct v4l2_subdev *sd, } static int s5k5baf_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->pad == PAD_CIS) { @@ -1217,7 +1217,7 @@ static int s5k5baf_enum_mbus_code(struct v4l2_subdev *sd, } static int s5k5baf_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { int i; @@ -1274,15 +1274,16 @@ static int s5k5baf_try_isp_format(struct v4l2_mbus_framefmt *mf) return pixfmt; } -static int s5k5baf_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_format *fmt) +static int s5k5baf_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_format *fmt) { struct s5k5baf *state = to_s5k5baf(sd); const struct s5k5baf_pixfmt *pixfmt; struct v4l2_mbus_framefmt *mf; if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + mf = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); fmt->format = *mf; return 0; } @@ -1304,8 +1305,9 @@ static int s5k5baf_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config return 0; } -static int s5k5baf_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_format *fmt) +static int s5k5baf_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_format *fmt) { struct v4l2_mbus_framefmt *mf = &fmt->format; struct s5k5baf *state = to_s5k5baf(sd); @@ -1315,7 +1317,7 @@ static int s5k5baf_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config mf->field = V4L2_FIELD_NONE; if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = *mf; + *v4l2_subdev_get_try_format(sd, sd_state, fmt->pad) = *mf; return 0; } @@ -1367,7 +1369,7 @@ static int s5k5baf_is_bound_target(u32 target) } static int s5k5baf_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { enum selection_rect rtype; @@ -1387,9 +1389,11 @@ static int s5k5baf_get_selection(struct v4l2_subdev *sd, if (sel->which == V4L2_SUBDEV_FORMAT_TRY) { if (rtype == R_COMPOSE) - sel->r = *v4l2_subdev_get_try_compose(sd, cfg, sel->pad); + sel->r = *v4l2_subdev_get_try_compose(sd, sd_state, + sel->pad); else - sel->r = *v4l2_subdev_get_try_crop(sd, cfg, sel->pad); + sel->r = *v4l2_subdev_get_try_crop(sd, sd_state, + sel->pad); return 0; } @@ -1458,7 +1462,7 @@ static bool s5k5baf_cmp_rect(const struct v4l2_rect *r1, } static int s5k5baf_set_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { static enum selection_rect rtype; @@ -1479,9 +1483,12 @@ static int s5k5baf_set_selection(struct v4l2_subdev *sd, if (sel->which == V4L2_SUBDEV_FORMAT_TRY) { rects = (struct v4l2_rect * []) { &s5k5baf_cis_rect, - v4l2_subdev_get_try_crop(sd, cfg, PAD_CIS), - v4l2_subdev_get_try_compose(sd, cfg, PAD_CIS), - v4l2_subdev_get_try_crop(sd, cfg, PAD_OUT) + v4l2_subdev_get_try_crop(sd, sd_state, + PAD_CIS), + v4l2_subdev_get_try_compose(sd, sd_state, + PAD_CIS), + v4l2_subdev_get_try_crop(sd, sd_state, + PAD_OUT) }; s5k5baf_set_rect_and_adjust(rects, rtype, &sel->r); return 0; @@ -1699,22 +1706,22 @@ static int s5k5baf_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { struct v4l2_mbus_framefmt *mf; - mf = v4l2_subdev_get_try_format(sd, fh->pad, PAD_CIS); + mf = v4l2_subdev_get_try_format(sd, fh->state, PAD_CIS); s5k5baf_try_cis_format(mf); if (s5k5baf_is_cis_subdev(sd)) return 0; - mf = v4l2_subdev_get_try_format(sd, fh->pad, PAD_OUT); + mf = v4l2_subdev_get_try_format(sd, fh->state, PAD_OUT); mf->colorspace = s5k5baf_formats[0].colorspace; mf->code = s5k5baf_formats[0].code; mf->width = s5k5baf_cis_rect.width; mf->height = s5k5baf_cis_rect.height; mf->field = V4L2_FIELD_NONE; - *v4l2_subdev_get_try_crop(sd, fh->pad, PAD_CIS) = s5k5baf_cis_rect; - *v4l2_subdev_get_try_compose(sd, fh->pad, PAD_CIS) = s5k5baf_cis_rect; - *v4l2_subdev_get_try_crop(sd, fh->pad, PAD_OUT) = s5k5baf_cis_rect; + *v4l2_subdev_get_try_crop(sd, fh->state, PAD_CIS) = s5k5baf_cis_rect; + *v4l2_subdev_get_try_compose(sd, fh->state, PAD_CIS) = s5k5baf_cis_rect; + *v4l2_subdev_get_try_crop(sd, fh->state, PAD_OUT) = s5k5baf_cis_rect; return 0; } diff --git a/drivers/media/i2c/s5k6a3.c b/drivers/media/i2c/s5k6a3.c index f26c168ef942..b97dd6149e90 100644 --- a/drivers/media/i2c/s5k6a3.c +++ b/drivers/media/i2c/s5k6a3.c @@ -99,7 +99,7 @@ static const struct v4l2_mbus_framefmt *find_sensor_format( } static int s5k6a3_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->index >= ARRAY_SIZE(s5k6a3_formats)) @@ -123,17 +123,18 @@ static void s5k6a3_try_format(struct v4l2_mbus_framefmt *mf) } static struct v4l2_mbus_framefmt *__s5k6a3_get_format( - struct s5k6a3 *sensor, struct v4l2_subdev_pad_config *cfg, + struct s5k6a3 *sensor, struct v4l2_subdev_state *sd_state, u32 pad, enum v4l2_subdev_format_whence which) { if (which == V4L2_SUBDEV_FORMAT_TRY) - return cfg ? v4l2_subdev_get_try_format(&sensor->subdev, cfg, pad) : NULL; + return sd_state ? v4l2_subdev_get_try_format(&sensor->subdev, + sd_state, pad) : NULL; return &sensor->format; } static int s5k6a3_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct s5k6a3 *sensor = sd_to_s5k6a3(sd); @@ -141,7 +142,7 @@ static int s5k6a3_set_fmt(struct v4l2_subdev *sd, s5k6a3_try_format(&fmt->format); - mf = __s5k6a3_get_format(sensor, cfg, fmt->pad, fmt->which); + mf = __s5k6a3_get_format(sensor, sd_state, fmt->pad, fmt->which); if (mf) { mutex_lock(&sensor->lock); *mf = fmt->format; @@ -151,13 +152,13 @@ static int s5k6a3_set_fmt(struct v4l2_subdev *sd, } static int s5k6a3_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct s5k6a3 *sensor = sd_to_s5k6a3(sd); struct v4l2_mbus_framefmt *mf; - mf = __s5k6a3_get_format(sensor, cfg, fmt->pad, fmt->which); + mf = __s5k6a3_get_format(sensor, sd_state, fmt->pad, fmt->which); mutex_lock(&sensor->lock); fmt->format = *mf; @@ -173,7 +174,9 @@ static const struct v4l2_subdev_pad_ops s5k6a3_pad_ops = { static int s5k6a3_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { - struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(sd, fh->pad, 0); + struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(sd, + fh->state, + 0); *format = s5k6a3_formats[0]; format->width = S5K6A3_DEFAULT_WIDTH; diff --git a/drivers/media/i2c/s5k6aa.c b/drivers/media/i2c/s5k6aa.c index e9be7323a22e..105a4b7d8354 100644 --- a/drivers/media/i2c/s5k6aa.c +++ b/drivers/media/i2c/s5k6aa.c @@ -997,7 +997,7 @@ static int s5k6aa_s_frame_interval(struct v4l2_subdev *sd, * V4L2 subdev pad level and video operations */ static int s5k6aa_enum_frame_interval(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_interval_enum *fie) { struct s5k6aa *s5k6aa = to_s5k6aa(sd); @@ -1024,7 +1024,7 @@ static int s5k6aa_enum_frame_interval(struct v4l2_subdev *sd, } static int s5k6aa_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->index >= ARRAY_SIZE(s5k6aa_formats)) @@ -1035,7 +1035,7 @@ static int s5k6aa_enum_mbus_code(struct v4l2_subdev *sd, } static int s5k6aa_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { int i = ARRAY_SIZE(s5k6aa_formats); @@ -1057,14 +1057,15 @@ static int s5k6aa_enum_frame_size(struct v4l2_subdev *sd, } static struct v4l2_rect * -__s5k6aa_get_crop_rect(struct s5k6aa *s5k6aa, struct v4l2_subdev_pad_config *cfg, +__s5k6aa_get_crop_rect(struct s5k6aa *s5k6aa, + struct v4l2_subdev_state *sd_state, enum v4l2_subdev_format_whence which) { if (which == V4L2_SUBDEV_FORMAT_ACTIVE) return &s5k6aa->ccd_rect; WARN_ON(which != V4L2_SUBDEV_FORMAT_TRY); - return v4l2_subdev_get_try_crop(&s5k6aa->sd, cfg, 0); + return v4l2_subdev_get_try_crop(&s5k6aa->sd, sd_state, 0); } static void s5k6aa_try_format(struct s5k6aa *s5k6aa, @@ -1088,7 +1089,8 @@ static void s5k6aa_try_format(struct s5k6aa *s5k6aa, mf->field = V4L2_FIELD_NONE; } -static int s5k6aa_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, +static int s5k6aa_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct s5k6aa *s5k6aa = to_s5k6aa(sd); @@ -1097,7 +1099,7 @@ static int s5k6aa_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config memset(fmt->reserved, 0, sizeof(fmt->reserved)); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - mf = v4l2_subdev_get_try_format(sd, cfg, 0); + mf = v4l2_subdev_get_try_format(sd, sd_state, 0); fmt->format = *mf; return 0; } @@ -1109,7 +1111,8 @@ static int s5k6aa_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config return 0; } -static int s5k6aa_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, +static int s5k6aa_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct s5k6aa *s5k6aa = to_s5k6aa(sd); @@ -1122,8 +1125,8 @@ static int s5k6aa_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config s5k6aa_try_format(s5k6aa, &fmt->format); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); - crop = v4l2_subdev_get_try_crop(sd, cfg, 0); + mf = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); + crop = v4l2_subdev_get_try_crop(sd, sd_state, 0); } else { if (s5k6aa->streaming) { ret = -EBUSY; @@ -1163,7 +1166,7 @@ static int s5k6aa_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config } static int s5k6aa_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct s5k6aa *s5k6aa = to_s5k6aa(sd); @@ -1175,7 +1178,7 @@ static int s5k6aa_get_selection(struct v4l2_subdev *sd, memset(sel->reserved, 0, sizeof(sel->reserved)); mutex_lock(&s5k6aa->lock); - rect = __s5k6aa_get_crop_rect(s5k6aa, cfg, sel->which); + rect = __s5k6aa_get_crop_rect(s5k6aa, sd_state, sel->which); sel->r = *rect; mutex_unlock(&s5k6aa->lock); @@ -1186,7 +1189,7 @@ static int s5k6aa_get_selection(struct v4l2_subdev *sd, } static int s5k6aa_set_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct s5k6aa *s5k6aa = to_s5k6aa(sd); @@ -1198,13 +1201,13 @@ static int s5k6aa_set_selection(struct v4l2_subdev *sd, return -EINVAL; mutex_lock(&s5k6aa->lock); - crop_r = __s5k6aa_get_crop_rect(s5k6aa, cfg, sel->which); + crop_r = __s5k6aa_get_crop_rect(s5k6aa, sd_state, sel->which); if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) { mf = &s5k6aa->preset->mbus_fmt; s5k6aa->apply_crop = 1; } else { - mf = v4l2_subdev_get_try_format(sd, cfg, 0); + mf = v4l2_subdev_get_try_format(sd, sd_state, 0); } v4l_bound_align_image(&sel->r.width, mf->width, S5K6AA_WIN_WIDTH_MAX, 1, @@ -1425,8 +1428,10 @@ static int s5k6aa_initialize_ctrls(struct s5k6aa *s5k6aa) */ static int s5k6aa_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { - struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(sd, fh->pad, 0); - struct v4l2_rect *crop = v4l2_subdev_get_try_crop(sd, fh->pad, 0); + struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(sd, + fh->state, + 0); + struct v4l2_rect *crop = v4l2_subdev_get_try_crop(sd, fh->state, 0); format->colorspace = s5k6aa_formats[0].colorspace; format->code = s5k6aa_formats[0].code; diff --git a/drivers/media/i2c/saa6752hs.c b/drivers/media/i2c/saa6752hs.c index 6171ced809bb..a7f043cad149 100644 --- a/drivers/media/i2c/saa6752hs.c +++ b/drivers/media/i2c/saa6752hs.c @@ -543,7 +543,7 @@ static int saa6752hs_init(struct v4l2_subdev *sd, u32 leading_null_bytes) } static int saa6752hs_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *f = &format->format; @@ -563,7 +563,7 @@ static int saa6752hs_get_fmt(struct v4l2_subdev *sd, } static int saa6752hs_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *f = &format->format; @@ -595,7 +595,7 @@ static int saa6752hs_set_fmt(struct v4l2_subdev *sd, f->colorspace = V4L2_COLORSPACE_SMPTE170M; if (format->which == V4L2_SUBDEV_FORMAT_TRY) { - cfg->try_fmt = *f; + sd_state->pads->try_fmt = *f; return 0; } diff --git a/drivers/media/i2c/saa7115.c b/drivers/media/i2c/saa7115.c index 88dc6baac639..a958bbc2c33d 100644 --- a/drivers/media/i2c/saa7115.c +++ b/drivers/media/i2c/saa7115.c @@ -1167,7 +1167,7 @@ static int saa711x_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_f } static int saa711x_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *fmt = &format->format; diff --git a/drivers/media/i2c/saa717x.c b/drivers/media/i2c/saa717x.c index ba103a6a1875..adf905360171 100644 --- a/drivers/media/i2c/saa717x.c +++ b/drivers/media/i2c/saa717x.c @@ -980,7 +980,7 @@ static int saa717x_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_regi #endif static int saa717x_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *fmt = &format->format; diff --git a/drivers/media/i2c/sr030pc30.c b/drivers/media/i2c/sr030pc30.c index 46924024faa8..19c0252df2f1 100644 --- a/drivers/media/i2c/sr030pc30.c +++ b/drivers/media/i2c/sr030pc30.c @@ -468,7 +468,7 @@ static int sr030pc30_s_ctrl(struct v4l2_ctrl *ctrl) } static int sr030pc30_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (!code || code->pad || @@ -480,7 +480,7 @@ static int sr030pc30_enum_mbus_code(struct v4l2_subdev *sd, } static int sr030pc30_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *mf; @@ -525,7 +525,7 @@ static const struct sr030pc30_format *try_fmt(struct v4l2_subdev *sd, /* Return nearest media bus frame format. */ static int sr030pc30_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct sr030pc30_info *info = sd ? to_sr030pc30(sd) : NULL; @@ -541,7 +541,7 @@ static int sr030pc30_set_fmt(struct v4l2_subdev *sd, fmt = try_fmt(sd, mf); if (format->which == V4L2_SUBDEV_FORMAT_TRY) { - cfg->try_fmt = *mf; + sd_state->pads->try_fmt = *mf; return 0; } diff --git a/drivers/media/i2c/st-mipid02.c b/drivers/media/i2c/st-mipid02.c index 7f07ef56fbbd..f630b88cbfaa 100644 --- a/drivers/media/i2c/st-mipid02.c +++ b/drivers/media/i2c/st-mipid02.c @@ -643,7 +643,7 @@ out: } static int mipid02_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct mipid02_dev *bridge = to_mipid02_dev(sd); @@ -670,7 +670,7 @@ static int mipid02_enum_mbus_code(struct v4l2_subdev *sd, } static int mipid02_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *mbus_fmt = &format->format; @@ -687,7 +687,8 @@ static int mipid02_get_fmt(struct v4l2_subdev *sd, return -EINVAL; if (format->which == V4L2_SUBDEV_FORMAT_TRY) - fmt = v4l2_subdev_get_try_format(&bridge->sd, cfg, format->pad); + fmt = v4l2_subdev_get_try_format(&bridge->sd, sd_state, + format->pad); else fmt = &bridge->fmt; @@ -704,7 +705,7 @@ static int mipid02_get_fmt(struct v4l2_subdev *sd, } static void mipid02_set_fmt_source(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct mipid02_dev *bridge = to_mipid02_dev(sd); @@ -718,11 +719,11 @@ static void mipid02_set_fmt_source(struct v4l2_subdev *sd, if (format->which != V4L2_SUBDEV_FORMAT_TRY) return; - *v4l2_subdev_get_try_format(sd, cfg, format->pad) = format->format; + *v4l2_subdev_get_try_format(sd, sd_state, format->pad) = format->format; } static void mipid02_set_fmt_sink(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct mipid02_dev *bridge = to_mipid02_dev(sd); @@ -731,7 +732,7 @@ static void mipid02_set_fmt_sink(struct v4l2_subdev *sd, format->format.code = get_fmt_code(format->format.code); if (format->which == V4L2_SUBDEV_FORMAT_TRY) - fmt = v4l2_subdev_get_try_format(sd, cfg, format->pad); + fmt = v4l2_subdev_get_try_format(sd, sd_state, format->pad); else fmt = &bridge->fmt; @@ -739,7 +740,7 @@ static void mipid02_set_fmt_sink(struct v4l2_subdev *sd, } static int mipid02_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct mipid02_dev *bridge = to_mipid02_dev(sd); @@ -762,9 +763,9 @@ static int mipid02_set_fmt(struct v4l2_subdev *sd, } if (format->pad == MIPID02_SOURCE) - mipid02_set_fmt_source(sd, cfg, format); + mipid02_set_fmt_source(sd, sd_state, format); else - mipid02_set_fmt_sink(sd, cfg, format); + mipid02_set_fmt_sink(sd, sd_state, format); error: mutex_unlock(&bridge->lock); diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c index f21da11caf22..3205cd8298dd 100644 --- a/drivers/media/i2c/tc358743.c +++ b/drivers/media/i2c/tc358743.c @@ -1649,7 +1649,7 @@ static int tc358743_s_stream(struct v4l2_subdev *sd, int enable) /* --------------- PAD OPS --------------- */ static int tc358743_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { switch (code->index) { @@ -1666,7 +1666,7 @@ static int tc358743_enum_mbus_code(struct v4l2_subdev *sd, } static int tc358743_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct tc358743_state *state = to_state(sd); @@ -1702,13 +1702,13 @@ static int tc358743_get_fmt(struct v4l2_subdev *sd, } static int tc358743_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct tc358743_state *state = to_state(sd); u32 code = format->format.code; /* is overwritten by get_fmt */ - int ret = tc358743_get_fmt(sd, cfg, format); + int ret = tc358743_get_fmt(sd, sd_state, format); format->format.code = code; diff --git a/drivers/media/i2c/tda1997x.c b/drivers/media/i2c/tda1997x.c index 89bb7e6dc7a4..91e6db847bb5 100644 --- a/drivers/media/i2c/tda1997x.c +++ b/drivers/media/i2c/tda1997x.c @@ -1718,19 +1718,19 @@ static const struct v4l2_subdev_video_ops tda1997x_video_ops = { */ static int tda1997x_init_cfg(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg) + struct v4l2_subdev_state *sd_state) { struct tda1997x_state *state = to_state(sd); struct v4l2_mbus_framefmt *mf; - mf = v4l2_subdev_get_try_format(sd, cfg, 0); + mf = v4l2_subdev_get_try_format(sd, sd_state, 0); mf->code = state->mbus_codes[0]; return 0; } static int tda1997x_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct tda1997x_state *state = to_state(sd); @@ -1762,7 +1762,7 @@ static void tda1997x_fill_format(struct tda1997x_state *state, } static int tda1997x_get_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct tda1997x_state *state = to_state(sd); @@ -1775,7 +1775,7 @@ static int tda1997x_get_format(struct v4l2_subdev *sd, if (format->which == V4L2_SUBDEV_FORMAT_TRY) { struct v4l2_mbus_framefmt *fmt; - fmt = v4l2_subdev_get_try_format(sd, cfg, format->pad); + fmt = v4l2_subdev_get_try_format(sd, sd_state, format->pad); format->format.code = fmt->code; } else format->format.code = state->mbus_code; @@ -1784,7 +1784,7 @@ static int tda1997x_get_format(struct v4l2_subdev *sd, } static int tda1997x_set_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct tda1997x_state *state = to_state(sd); @@ -1809,7 +1809,7 @@ static int tda1997x_set_format(struct v4l2_subdev *sd, if (format->which == V4L2_SUBDEV_FORMAT_TRY) { struct v4l2_mbus_framefmt *fmt; - fmt = v4l2_subdev_get_try_format(sd, cfg, format->pad); + fmt = v4l2_subdev_get_try_format(sd, sd_state, format->pad); *fmt = format->format; } else { int ret = tda1997x_setup_format(state, format->format.code); diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c index a7fbe5b400c2..cee60f945036 100644 --- a/drivers/media/i2c/tvp514x.c +++ b/drivers/media/i2c/tvp514x.c @@ -853,13 +853,13 @@ static const struct v4l2_ctrl_ops tvp514x_ctrl_ops = { /** * tvp514x_enum_mbus_code() - V4L2 decoder interface handler for enum_mbus_code * @sd: pointer to standard V4L2 sub-device structure - * @cfg: pad configuration + * @sd_state: subdev state * @code: pointer to v4l2_subdev_mbus_code_enum structure * * Enumertaes mbus codes supported */ static int tvp514x_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { u32 pad = code->pad; @@ -880,13 +880,13 @@ static int tvp514x_enum_mbus_code(struct v4l2_subdev *sd, /** * tvp514x_get_pad_format() - V4L2 decoder interface handler for get pad format * @sd: pointer to standard V4L2 sub-device structure - * @cfg: pad configuration + * @sd_state: subdev state * @format: pointer to v4l2_subdev_format structure * * Retrieves pad format which is active or tried based on requirement */ static int tvp514x_get_pad_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct tvp514x_decoder *decoder = to_decoder(sd); @@ -912,13 +912,13 @@ static int tvp514x_get_pad_format(struct v4l2_subdev *sd, /** * tvp514x_set_pad_format() - V4L2 decoder interface handler for set pad format * @sd: pointer to standard V4L2 sub-device structure - * @cfg: pad configuration + * @sd_state: subdev state * @fmt: pointer to v4l2_subdev_format structure * * Set pad format for the output pad */ static int tvp514x_set_pad_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct tvp514x_decoder *decoder = to_decoder(sd); diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c index 374a9da75e4d..30c63552556d 100644 --- a/drivers/media/i2c/tvp5150.c +++ b/drivers/media/i2c/tvp5150.c @@ -1027,7 +1027,7 @@ static void tvp5150_set_default(v4l2_std_id std, struct v4l2_rect *crop) static struct v4l2_rect * tvp5150_get_pad_crop(struct tvp5150 *decoder, - struct v4l2_subdev_pad_config *cfg, unsigned int pad, + struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which) { switch (which) { @@ -1035,7 +1035,7 @@ tvp5150_get_pad_crop(struct tvp5150 *decoder, return &decoder->rect; case V4L2_SUBDEV_FORMAT_TRY: #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) - return v4l2_subdev_get_try_crop(&decoder->sd, cfg, pad); + return v4l2_subdev_get_try_crop(&decoder->sd, sd_state, pad); #else return ERR_PTR(-EINVAL); #endif @@ -1045,7 +1045,7 @@ tvp5150_get_pad_crop(struct tvp5150 *decoder, } static int tvp5150_fill_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *f; @@ -1104,7 +1104,7 @@ static void tvp5150_set_hw_selection(struct v4l2_subdev *sd, } static int tvp5150_set_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct tvp5150 *decoder = to_tvp5150(sd); @@ -1138,7 +1138,7 @@ static int tvp5150_set_selection(struct v4l2_subdev *sd, sel->which == V4L2_SUBDEV_FORMAT_TRY) return 0; - crop = tvp5150_get_pad_crop(decoder, cfg, sel->pad, sel->which); + crop = tvp5150_get_pad_crop(decoder, sd_state, sel->pad, sel->which); if (IS_ERR(crop)) return PTR_ERR(crop); @@ -1156,7 +1156,7 @@ static int tvp5150_set_selection(struct v4l2_subdev *sd, } static int tvp5150_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct tvp5150 *decoder = container_of(sd, struct tvp5150, sd); @@ -1180,7 +1180,7 @@ static int tvp5150_get_selection(struct v4l2_subdev *sd, sel->r.height = TVP5150_V_MAX_OTHERS; return 0; case V4L2_SEL_TGT_CROP: - crop = tvp5150_get_pad_crop(decoder, cfg, sel->pad, + crop = tvp5150_get_pad_crop(decoder, sd_state, sel->pad, sel->which); if (IS_ERR(crop)) return PTR_ERR(crop); @@ -1208,7 +1208,7 @@ static int tvp5150_get_mbus_config(struct v4l2_subdev *sd, V4L2 subdev pad ops ****************************************************************************/ static int tvp5150_init_cfg(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg) + struct v4l2_subdev_state *sd_state) { struct tvp5150 *decoder = to_tvp5150(sd); v4l2_std_id std; @@ -1229,7 +1229,7 @@ static int tvp5150_init_cfg(struct v4l2_subdev *sd, } static int tvp5150_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->pad || code->index) @@ -1240,7 +1240,7 @@ static int tvp5150_enum_mbus_code(struct v4l2_subdev *sd, } static int tvp5150_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { struct tvp5150 *decoder = to_tvp5150(sd); diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c index ada4ec5ef782..2de18833b07b 100644 --- a/drivers/media/i2c/tvp7002.c +++ b/drivers/media/i2c/tvp7002.c @@ -797,7 +797,8 @@ static const struct v4l2_ctrl_ops tvp7002_ctrl_ops = { * Enumerate supported digital video formats for pad. */ static int -tvp7002_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, +tvp7002_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { /* Check requested format index is within range */ @@ -818,7 +819,8 @@ tvp7002_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cf * get video format for pad. */ static int -tvp7002_get_pad_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, +tvp7002_get_pad_format(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct tvp7002 *tvp7002 = to_tvp7002(sd); @@ -841,10 +843,11 @@ tvp7002_get_pad_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cf * set video format for pad. */ static int -tvp7002_set_pad_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, +tvp7002_set_pad_format(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { - return tvp7002_get_pad_format(sd, cfg, fmt); + return tvp7002_get_pad_format(sd, sd_state, fmt); } /* V4L2 core operation handlers */ diff --git a/drivers/media/i2c/tw9910.c b/drivers/media/i2c/tw9910.c index a25a350b0ddc..09f5b3986928 100644 --- a/drivers/media/i2c/tw9910.c +++ b/drivers/media/i2c/tw9910.c @@ -720,7 +720,7 @@ tw9910_set_fmt_error: } static int tw9910_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -746,7 +746,7 @@ static int tw9910_get_selection(struct v4l2_subdev *sd, } static int tw9910_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *mf = &format->format; @@ -797,7 +797,7 @@ static int tw9910_s_fmt(struct v4l2_subdev *sd, } static int tw9910_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *mf = &format->format; @@ -829,7 +829,7 @@ static int tw9910_set_fmt(struct v4l2_subdev *sd, if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) return tw9910_s_fmt(sd, mf); - cfg->try_fmt = *mf; + sd_state->pads->try_fmt = *mf; return 0; } @@ -886,7 +886,7 @@ static const struct v4l2_subdev_core_ops tw9910_subdev_core_ops = { }; static int tw9910_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->pad || code->index) diff --git a/drivers/media/i2c/vs6624.c b/drivers/media/i2c/vs6624.c index c292c92e37b9..29003dec6f2d 100644 --- a/drivers/media/i2c/vs6624.c +++ b/drivers/media/i2c/vs6624.c @@ -546,7 +546,7 @@ static int vs6624_s_ctrl(struct v4l2_ctrl *ctrl) } static int vs6624_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->pad || code->index >= ARRAY_SIZE(vs6624_formats)) @@ -557,7 +557,7 @@ static int vs6624_enum_mbus_code(struct v4l2_subdev *sd, } static int vs6624_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *fmt = &format->format; @@ -587,7 +587,7 @@ static int vs6624_set_fmt(struct v4l2_subdev *sd, fmt->colorspace = vs6624_formats[index].colorspace; if (format->which == V4L2_SUBDEV_FORMAT_TRY) { - cfg->try_fmt = *fmt; + sd_state->pads->try_fmt = *fmt; return 0; } @@ -637,7 +637,7 @@ static int vs6624_set_fmt(struct v4l2_subdev *sd, } static int vs6624_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct vs6624 *sensor = to_vs6624(sd); diff --git a/drivers/media/pci/cx18/cx18-av-core.c b/drivers/media/pci/cx18/cx18-av-core.c index 11cfe35fd730..76e5a504df8c 100644 --- a/drivers/media/pci/cx18/cx18-av-core.c +++ b/drivers/media/pci/cx18/cx18-av-core.c @@ -930,7 +930,7 @@ static int cx18_av_s_ctrl(struct v4l2_ctrl *ctrl) } static int cx18_av_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *fmt = &format->format; diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c index ca8040d1a725..47db0ee0fcbf 100644 --- a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c @@ -1199,11 +1199,11 @@ static int cio2_subdev_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) }; /* Initialize try_fmt */ - format = v4l2_subdev_get_try_format(sd, fh->pad, CIO2_PAD_SINK); + format = v4l2_subdev_get_try_format(sd, fh->state, CIO2_PAD_SINK); *format = fmt_default; /* same as sink */ - format = v4l2_subdev_get_try_format(sd, fh->pad, CIO2_PAD_SOURCE); + format = v4l2_subdev_get_try_format(sd, fh->state, CIO2_PAD_SOURCE); *format = fmt_default; return 0; @@ -1217,7 +1217,7 @@ static int cio2_subdev_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) * return -EINVAL or zero on success */ static int cio2_subdev_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct cio2_queue *q = container_of(sd, struct cio2_queue, subdev); @@ -1225,7 +1225,8 @@ static int cio2_subdev_get_fmt(struct v4l2_subdev *sd, mutex_lock(&q->subdev_lock); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) - fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + fmt->format = *v4l2_subdev_get_try_format(sd, sd_state, + fmt->pad); else fmt->format = q->subdev_fmt; @@ -1242,7 +1243,7 @@ static int cio2_subdev_get_fmt(struct v4l2_subdev *sd, * return -EINVAL or zero on success */ static int cio2_subdev_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct cio2_queue *q = container_of(sd, struct cio2_queue, subdev); @@ -1255,10 +1256,10 @@ static int cio2_subdev_set_fmt(struct v4l2_subdev *sd, * source always propagates from sink */ if (fmt->pad == CIO2_PAD_SOURCE) - return cio2_subdev_get_fmt(sd, cfg, fmt); + return cio2_subdev_get_fmt(sd, sd_state, fmt); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) - mbus = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + mbus = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); else mbus = &q->subdev_fmt; @@ -1283,7 +1284,7 @@ static int cio2_subdev_set_fmt(struct v4l2_subdev *sd, } static int cio2_subdev_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->index >= ARRAY_SIZE(formats)) diff --git a/drivers/media/pci/saa7134/saa7134-empress.c b/drivers/media/pci/saa7134/saa7134-empress.c index 76a37fbd8458..aafbb34765b0 100644 --- a/drivers/media/pci/saa7134/saa7134-empress.c +++ b/drivers/media/pci/saa7134/saa7134-empress.c @@ -138,12 +138,15 @@ static int empress_try_fmt_vid_cap(struct file *file, void *priv, { struct saa7134_dev *dev = video_drvdata(file); struct v4l2_subdev_pad_config pad_cfg; + struct v4l2_subdev_state pad_state = { + .pads = &pad_cfg + }; struct v4l2_subdev_format format = { .which = V4L2_SUBDEV_FORMAT_TRY, }; v4l2_fill_mbus_format(&format.format, &f->fmt.pix, MEDIA_BUS_FMT_FIXED); - saa_call_all(dev, pad, set_fmt, &pad_cfg, &format); + saa_call_all(dev, pad, set_fmt, &pad_state, &format); v4l2_fill_pix_format(&f->fmt.pix, &format.format); f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index 46c6e3e20f33..19daa49bf604 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -1095,7 +1095,7 @@ static int isc_try_configure_pipeline(struct isc_device *isc) } static void isc_try_fse(struct isc_device *isc, - struct v4l2_subdev_pad_config *pad_cfg) + struct v4l2_subdev_state *sd_state) { int ret; struct v4l2_subdev_frame_size_enum fse = {}; @@ -1111,17 +1111,17 @@ static void isc_try_fse(struct isc_device *isc, fse.which = V4L2_SUBDEV_FORMAT_TRY; ret = v4l2_subdev_call(isc->current_subdev->sd, pad, enum_frame_size, - pad_cfg, &fse); + sd_state, &fse); /* * Attempt to obtain format size from subdev. If not available, * just use the maximum ISC can receive. */ if (ret) { - pad_cfg->try_crop.width = isc->max_width; - pad_cfg->try_crop.height = isc->max_height; + sd_state->pads->try_crop.width = isc->max_width; + sd_state->pads->try_crop.height = isc->max_height; } else { - pad_cfg->try_crop.width = fse.max_width; - pad_cfg->try_crop.height = fse.max_height; + sd_state->pads->try_crop.width = fse.max_width; + sd_state->pads->try_crop.height = fse.max_height; } } @@ -1132,6 +1132,9 @@ static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f, struct isc_format *sd_fmt = NULL, *direct_fmt = NULL; struct v4l2_pix_format *pixfmt = &f->fmt.pix; struct v4l2_subdev_pad_config pad_cfg = {}; + struct v4l2_subdev_state pad_state = { + .pads = &pad_cfg + }; struct v4l2_subdev_format format = { .which = V4L2_SUBDEV_FORMAT_TRY, }; @@ -1229,11 +1232,11 @@ static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f, goto isc_try_fmt_err; /* Obtain frame sizes if possible to have crop requirements ready */ - isc_try_fse(isc, &pad_cfg); + isc_try_fse(isc, &pad_state); v4l2_fill_mbus_format(&format.format, pixfmt, mbus_code); ret = v4l2_subdev_call(isc->current_subdev->sd, pad, set_fmt, - &pad_cfg, &format); + &pad_state, &format); if (ret < 0) goto isc_try_fmt_subdev_err; diff --git a/drivers/media/platform/atmel/atmel-isi.c b/drivers/media/platform/atmel/atmel-isi.c index 5b1dd358f2e6..095d80c4f59e 100644 --- a/drivers/media/platform/atmel/atmel-isi.c +++ b/drivers/media/platform/atmel/atmel-isi.c @@ -557,7 +557,7 @@ static const struct isi_format *find_format_by_fourcc(struct atmel_isi *isi, } static void isi_try_fse(struct atmel_isi *isi, const struct isi_format *isi_fmt, - struct v4l2_subdev_pad_config *pad_cfg) + struct v4l2_subdev_state *sd_state) { int ret; struct v4l2_subdev_frame_size_enum fse = { @@ -566,17 +566,17 @@ static void isi_try_fse(struct atmel_isi *isi, const struct isi_format *isi_fmt, }; ret = v4l2_subdev_call(isi->entity.subdev, pad, enum_frame_size, - pad_cfg, &fse); + sd_state, &fse); /* * Attempt to obtain format size from subdev. If not available, * just use the maximum ISI can receive. */ if (ret) { - pad_cfg->try_crop.width = MAX_SUPPORT_WIDTH; - pad_cfg->try_crop.height = MAX_SUPPORT_HEIGHT; + sd_state->pads->try_crop.width = MAX_SUPPORT_WIDTH; + sd_state->pads->try_crop.height = MAX_SUPPORT_HEIGHT; } else { - pad_cfg->try_crop.width = fse.max_width; - pad_cfg->try_crop.height = fse.max_height; + sd_state->pads->try_crop.width = fse.max_width; + sd_state->pads->try_crop.height = fse.max_height; } } @@ -586,6 +586,9 @@ static int isi_try_fmt(struct atmel_isi *isi, struct v4l2_format *f, const struct isi_format *isi_fmt; struct v4l2_pix_format *pixfmt = &f->fmt.pix; struct v4l2_subdev_pad_config pad_cfg = {}; + struct v4l2_subdev_state pad_state = { + .pads = &pad_cfg + }; struct v4l2_subdev_format format = { .which = V4L2_SUBDEV_FORMAT_TRY, }; @@ -603,10 +606,10 @@ static int isi_try_fmt(struct atmel_isi *isi, struct v4l2_format *f, v4l2_fill_mbus_format(&format.format, pixfmt, isi_fmt->mbus_code); - isi_try_fse(isi, isi_fmt, &pad_cfg); + isi_try_fse(isi, isi_fmt, &pad_state); ret = v4l2_subdev_call(isi->entity.subdev, pad, set_fmt, - &pad_cfg, &format); + &pad_state, &format); if (ret < 0) return ret; diff --git a/drivers/media/platform/cadence/cdns-csi2tx.c b/drivers/media/platform/cadence/cdns-csi2tx.c index 765ae408970a..5a67fba73ddd 100644 --- a/drivers/media/platform/cadence/cdns-csi2tx.c +++ b/drivers/media/platform/cadence/cdns-csi2tx.c @@ -156,7 +156,7 @@ static const struct csi2tx_fmt *csi2tx_get_fmt_from_mbus(u32 mbus) } static int csi2tx_enum_mbus_code(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->pad || code->index >= ARRAY_SIZE(csi2tx_formats)) @@ -169,20 +169,20 @@ static int csi2tx_enum_mbus_code(struct v4l2_subdev *subdev, static struct v4l2_mbus_framefmt * __csi2tx_get_pad_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct csi2tx_priv *csi2tx = v4l2_subdev_to_csi2tx(subdev); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_format(subdev, cfg, + return v4l2_subdev_get_try_format(subdev, sd_state, fmt->pad); return &csi2tx->pad_fmts[fmt->pad]; } static int csi2tx_get_pad_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { const struct v4l2_mbus_framefmt *format; @@ -191,7 +191,7 @@ static int csi2tx_get_pad_format(struct v4l2_subdev *subdev, if (fmt->pad == CSI2TX_PAD_SOURCE) return -EINVAL; - format = __csi2tx_get_pad_format(subdev, cfg, fmt); + format = __csi2tx_get_pad_format(subdev, sd_state, fmt); if (!format) return -EINVAL; @@ -201,7 +201,7 @@ static int csi2tx_get_pad_format(struct v4l2_subdev *subdev, } static int csi2tx_set_pad_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { const struct v4l2_mbus_framefmt *src_format = &fmt->format; @@ -214,7 +214,7 @@ static int csi2tx_set_pad_format(struct v4l2_subdev *subdev, if (!csi2tx_get_fmt_from_mbus(fmt->format.code)) src_format = &fmt_default; - dst_format = __csi2tx_get_pad_format(subdev, cfg, fmt); + dst_format = __csi2tx_get_pad_format(subdev, sd_state, fmt); if (!dst_format) return -EINVAL; diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c index 0da36443173c..7ff4024003f4 100644 --- a/drivers/media/platform/exynos4-is/fimc-capture.c +++ b/drivers/media/platform/exynos4-is/fimc-capture.c @@ -1454,7 +1454,7 @@ void fimc_sensor_notify(struct v4l2_subdev *sd, unsigned int notification, } static int fimc_subdev_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct fimc_fmt *fmt; @@ -1467,7 +1467,7 @@ static int fimc_subdev_enum_mbus_code(struct v4l2_subdev *sd, } static int fimc_subdev_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct fimc_dev *fimc = v4l2_get_subdevdata(sd); @@ -1476,7 +1476,7 @@ static int fimc_subdev_get_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf; if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + mf = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); fmt->format = *mf; return 0; } @@ -1508,7 +1508,7 @@ static int fimc_subdev_get_fmt(struct v4l2_subdev *sd, } static int fimc_subdev_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct fimc_dev *fimc = v4l2_get_subdevdata(sd); @@ -1531,7 +1531,7 @@ static int fimc_subdev_set_fmt(struct v4l2_subdev *sd, mf->colorspace = V4L2_COLORSPACE_JPEG; if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + mf = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); *mf = fmt->format; return 0; } @@ -1574,7 +1574,7 @@ static int fimc_subdev_set_fmt(struct v4l2_subdev *sd, } static int fimc_subdev_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct fimc_dev *fimc = v4l2_get_subdevdata(sd); @@ -1601,10 +1601,10 @@ static int fimc_subdev_get_selection(struct v4l2_subdev *sd, return 0; case V4L2_SEL_TGT_CROP: - try_sel = v4l2_subdev_get_try_crop(sd, cfg, sel->pad); + try_sel = v4l2_subdev_get_try_crop(sd, sd_state, sel->pad); break; case V4L2_SEL_TGT_COMPOSE: - try_sel = v4l2_subdev_get_try_compose(sd, cfg, sel->pad); + try_sel = v4l2_subdev_get_try_compose(sd, sd_state, sel->pad); f = &ctx->d_frame; break; default: @@ -1630,7 +1630,7 @@ static int fimc_subdev_get_selection(struct v4l2_subdev *sd, } static int fimc_subdev_set_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct fimc_dev *fimc = v4l2_get_subdevdata(sd); @@ -1648,10 +1648,10 @@ static int fimc_subdev_set_selection(struct v4l2_subdev *sd, switch (sel->target) { case V4L2_SEL_TGT_CROP: - try_sel = v4l2_subdev_get_try_crop(sd, cfg, sel->pad); + try_sel = v4l2_subdev_get_try_crop(sd, sd_state, sel->pad); break; case V4L2_SEL_TGT_COMPOSE: - try_sel = v4l2_subdev_get_try_compose(sd, cfg, sel->pad); + try_sel = v4l2_subdev_get_try_compose(sd, sd_state, sel->pad); f = &ctx->d_frame; break; default: diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c index 74b49d30901e..855235bea46d 100644 --- a/drivers/media/platform/exynos4-is/fimc-isp.c +++ b/drivers/media/platform/exynos4-is/fimc-isp.c @@ -106,7 +106,7 @@ static const struct media_entity_operations fimc_is_subdev_media_ops = { }; static int fimc_is_subdev_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { const struct fimc_fmt *fmt; @@ -119,14 +119,14 @@ static int fimc_is_subdev_enum_mbus_code(struct v4l2_subdev *sd, } static int fimc_isp_subdev_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct fimc_isp *isp = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *mf = &fmt->format; if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - *mf = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + *mf = *v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); return 0; } @@ -156,7 +156,7 @@ static int fimc_isp_subdev_get_fmt(struct v4l2_subdev *sd, } static void __isp_subdev_try_format(struct fimc_isp *isp, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct v4l2_mbus_framefmt *mf = &fmt->format; @@ -172,8 +172,9 @@ static void __isp_subdev_try_format(struct fimc_isp *isp, mf->code = MEDIA_BUS_FMT_SGRBG10_1X10; } else { if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) - format = v4l2_subdev_get_try_format(&isp->subdev, cfg, - FIMC_ISP_SD_PAD_SINK); + format = v4l2_subdev_get_try_format(&isp->subdev, + sd_state, + FIMC_ISP_SD_PAD_SINK); else format = &isp->sink_fmt; @@ -191,7 +192,7 @@ static void __isp_subdev_try_format(struct fimc_isp *isp, } static int fimc_isp_subdev_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct fimc_isp *isp = v4l2_get_subdevdata(sd); @@ -203,10 +204,10 @@ static int fimc_isp_subdev_set_fmt(struct v4l2_subdev *sd, __func__, fmt->pad, mf->code, mf->width, mf->height); mutex_lock(&isp->subdev_lock); - __isp_subdev_try_format(isp, cfg, fmt); + __isp_subdev_try_format(isp, sd_state, fmt); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + mf = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); *mf = fmt->format; /* Propagate format to the source pads */ @@ -217,8 +218,10 @@ static int fimc_isp_subdev_set_fmt(struct v4l2_subdev *sd, for (pad = FIMC_ISP_SD_PAD_SRC_FIFO; pad < FIMC_ISP_SD_PADS_NUM; pad++) { format.pad = pad; - __isp_subdev_try_format(isp, cfg, &format); - mf = v4l2_subdev_get_try_format(sd, cfg, pad); + __isp_subdev_try_format(isp, sd_state, + &format); + mf = v4l2_subdev_get_try_format(sd, sd_state, + pad); *mf = format.format; } } @@ -230,7 +233,8 @@ static int fimc_isp_subdev_set_fmt(struct v4l2_subdev *sd, isp->sink_fmt = *mf; format.pad = FIMC_ISP_SD_PAD_SRC_DMA; - __isp_subdev_try_format(isp, cfg, &format); + __isp_subdev_try_format(isp, sd_state, + &format); isp->src_fmt = format.format; __is_set_frame_size(is, &isp->src_fmt); @@ -370,15 +374,18 @@ static int fimc_isp_subdev_open(struct v4l2_subdev *sd, .field = V4L2_FIELD_NONE, }; - format = v4l2_subdev_get_try_format(sd, fh->pad, FIMC_ISP_SD_PAD_SINK); + format = v4l2_subdev_get_try_format(sd, fh->state, + FIMC_ISP_SD_PAD_SINK); *format = fmt; - format = v4l2_subdev_get_try_format(sd, fh->pad, FIMC_ISP_SD_PAD_SRC_FIFO); + format = v4l2_subdev_get_try_format(sd, fh->state, + FIMC_ISP_SD_PAD_SRC_FIFO); fmt.width = DEFAULT_PREVIEW_STILL_WIDTH; fmt.height = DEFAULT_PREVIEW_STILL_HEIGHT; *format = fmt; - format = v4l2_subdev_get_try_format(sd, fh->pad, FIMC_ISP_SD_PAD_SRC_DMA); + format = v4l2_subdev_get_try_format(sd, fh->state, + FIMC_ISP_SD_PAD_SRC_DMA); *format = fmt; return 0; diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c index 4d8b18078ff3..aaa3af0493ce 100644 --- a/drivers/media/platform/exynos4-is/fimc-lite.c +++ b/drivers/media/platform/exynos4-is/fimc-lite.c @@ -550,7 +550,7 @@ static const struct v4l2_file_operations fimc_lite_fops = { */ static const struct fimc_fmt *fimc_lite_subdev_try_fmt(struct fimc_lite *fimc, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct flite_drvdata *dd = fimc->dd; @@ -574,14 +574,16 @@ static const struct fimc_fmt *fimc_lite_subdev_try_fmt(struct fimc_lite *fimc, struct v4l2_rect *rect; if (format->which == V4L2_SUBDEV_FORMAT_TRY) { - sink_fmt = v4l2_subdev_get_try_format(&fimc->subdev, cfg, - FLITE_SD_PAD_SINK); + sink_fmt = v4l2_subdev_get_try_format(&fimc->subdev, + sd_state, + FLITE_SD_PAD_SINK); mf->code = sink_fmt->code; mf->colorspace = sink_fmt->colorspace; - rect = v4l2_subdev_get_try_crop(&fimc->subdev, cfg, - FLITE_SD_PAD_SINK); + rect = v4l2_subdev_get_try_crop(&fimc->subdev, + sd_state, + FLITE_SD_PAD_SINK); } else { mf->code = sink->fmt->mbus_code; mf->colorspace = sink->fmt->colorspace; @@ -1002,7 +1004,7 @@ static const struct media_entity_operations fimc_lite_subdev_media_ops = { }; static int fimc_lite_subdev_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { const struct fimc_fmt *fmt; @@ -1016,16 +1018,16 @@ static int fimc_lite_subdev_enum_mbus_code(struct v4l2_subdev *sd, static struct v4l2_mbus_framefmt *__fimc_lite_subdev_get_try_fmt( struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, unsigned int pad) + struct v4l2_subdev_state *sd_state, unsigned int pad) { if (pad != FLITE_SD_PAD_SINK) pad = FLITE_SD_PAD_SOURCE_DMA; - return v4l2_subdev_get_try_format(sd, cfg, pad); + return v4l2_subdev_get_try_format(sd, sd_state, pad); } static int fimc_lite_subdev_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct fimc_lite *fimc = v4l2_get_subdevdata(sd); @@ -1033,7 +1035,7 @@ static int fimc_lite_subdev_get_fmt(struct v4l2_subdev *sd, struct flite_frame *f = &fimc->inp_frame; if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - mf = __fimc_lite_subdev_get_try_fmt(sd, cfg, fmt->pad); + mf = __fimc_lite_subdev_get_try_fmt(sd, sd_state, fmt->pad); fmt->format = *mf; return 0; } @@ -1056,7 +1058,7 @@ static int fimc_lite_subdev_get_fmt(struct v4l2_subdev *sd, } static int fimc_lite_subdev_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct fimc_lite *fimc = v4l2_get_subdevdata(sd); @@ -1078,17 +1080,18 @@ static int fimc_lite_subdev_set_fmt(struct v4l2_subdev *sd, return -EBUSY; } - ffmt = fimc_lite_subdev_try_fmt(fimc, cfg, fmt); + ffmt = fimc_lite_subdev_try_fmt(fimc, sd_state, fmt); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { struct v4l2_mbus_framefmt *src_fmt; - mf = __fimc_lite_subdev_get_try_fmt(sd, cfg, fmt->pad); + mf = __fimc_lite_subdev_get_try_fmt(sd, sd_state, fmt->pad); *mf = fmt->format; if (fmt->pad == FLITE_SD_PAD_SINK) { unsigned int pad = FLITE_SD_PAD_SOURCE_DMA; - src_fmt = __fimc_lite_subdev_get_try_fmt(sd, cfg, pad); + src_fmt = __fimc_lite_subdev_get_try_fmt(sd, sd_state, + pad); *src_fmt = *mf; } @@ -1116,7 +1119,7 @@ static int fimc_lite_subdev_set_fmt(struct v4l2_subdev *sd, } static int fimc_lite_subdev_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct fimc_lite *fimc = v4l2_get_subdevdata(sd); @@ -1128,7 +1131,7 @@ static int fimc_lite_subdev_get_selection(struct v4l2_subdev *sd, return -EINVAL; if (sel->which == V4L2_SUBDEV_FORMAT_TRY) { - sel->r = *v4l2_subdev_get_try_crop(sd, cfg, sel->pad); + sel->r = *v4l2_subdev_get_try_crop(sd, sd_state, sel->pad); return 0; } @@ -1151,7 +1154,7 @@ static int fimc_lite_subdev_get_selection(struct v4l2_subdev *sd, } static int fimc_lite_subdev_set_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct fimc_lite *fimc = v4l2_get_subdevdata(sd); @@ -1165,7 +1168,7 @@ static int fimc_lite_subdev_set_selection(struct v4l2_subdev *sd, fimc_lite_try_crop(fimc, &sel->r); if (sel->which == V4L2_SUBDEV_FORMAT_TRY) { - *v4l2_subdev_get_try_crop(sd, cfg, sel->pad) = sel->r; + *v4l2_subdev_get_try_crop(sd, sd_state, sel->pad) = sel->r; } else { unsigned long flags; spin_lock_irqsave(&fimc->slock, flags); diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c index ebf39c856894..32b23329b033 100644 --- a/drivers/media/platform/exynos4-is/mipi-csis.c +++ b/drivers/media/platform/exynos4-is/mipi-csis.c @@ -537,7 +537,7 @@ unlock: } static int s5pcsis_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->index >= ARRAY_SIZE(s5pcsis_formats)) @@ -565,23 +565,25 @@ static struct csis_pix_format const *s5pcsis_try_format( } static struct v4l2_mbus_framefmt *__s5pcsis_get_format( - struct csis_state *state, struct v4l2_subdev_pad_config *cfg, + struct csis_state *state, struct v4l2_subdev_state *sd_state, enum v4l2_subdev_format_whence which) { if (which == V4L2_SUBDEV_FORMAT_TRY) - return cfg ? v4l2_subdev_get_try_format(&state->sd, cfg, 0) : NULL; + return sd_state ? v4l2_subdev_get_try_format(&state->sd, + sd_state, 0) : NULL; return &state->format; } -static int s5pcsis_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, +static int s5pcsis_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct csis_state *state = sd_to_csis_state(sd); struct csis_pix_format const *csis_fmt; struct v4l2_mbus_framefmt *mf; - mf = __s5pcsis_get_format(state, cfg, fmt->which); + mf = __s5pcsis_get_format(state, sd_state, fmt->which); if (fmt->pad == CSIS_PAD_SOURCE) { if (mf) { @@ -602,13 +604,14 @@ static int s5pcsis_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config return 0; } -static int s5pcsis_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, +static int s5pcsis_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct csis_state *state = sd_to_csis_state(sd); struct v4l2_mbus_framefmt *mf; - mf = __s5pcsis_get_format(state, cfg, fmt->which); + mf = __s5pcsis_get_format(state, sd_state, fmt->which); if (!mf) return -EINVAL; diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index ea87110d9073..070a0f3fc337 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c @@ -1350,6 +1350,9 @@ static int mcam_vidioc_try_fmt_vid_cap(struct file *filp, void *priv, struct mcam_format_struct *f; struct v4l2_pix_format *pix = &fmt->fmt.pix; struct v4l2_subdev_pad_config pad_cfg; + struct v4l2_subdev_state pad_state = { + .pads = &pad_cfg + }; struct v4l2_subdev_format format = { .which = V4L2_SUBDEV_FORMAT_TRY, }; @@ -1358,7 +1361,7 @@ static int mcam_vidioc_try_fmt_vid_cap(struct file *filp, void *priv, f = mcam_find_format(pix->pixelformat); pix->pixelformat = f->pixelformat; v4l2_fill_mbus_format(&format.format, pix, f->mbus_code); - ret = sensor_call(cam, pad, set_fmt, &pad_cfg, &format); + ret = sensor_call(cam, pad, set_fmt, &pad_state, &format); v4l2_fill_pix_format(pix, &format.format); pix->bytesperline = pix->width * f->bpp; switch (f->pixelformat) { diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c index 4e8905ef362f..108b5e9f82cb 100644 --- a/drivers/media/platform/omap3isp/ispccdc.c +++ b/drivers/media/platform/omap3isp/ispccdc.c @@ -29,7 +29,8 @@ #define CCDC_MIN_HEIGHT 32 static struct v4l2_mbus_framefmt * -__ccdc_get_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_pad_config *cfg, +__ccdc_get_format(struct isp_ccdc_device *ccdc, + struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which); static const unsigned int ccdc_fmts[] = { @@ -1936,21 +1937,25 @@ static int ccdc_set_stream(struct v4l2_subdev *sd, int enable) } static struct v4l2_mbus_framefmt * -__ccdc_get_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_pad_config *cfg, +__ccdc_get_format(struct isp_ccdc_device *ccdc, + struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which) { if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_format(&ccdc->subdev, cfg, pad); + return v4l2_subdev_get_try_format(&ccdc->subdev, sd_state, + pad); else return &ccdc->formats[pad]; } static struct v4l2_rect * -__ccdc_get_crop(struct isp_ccdc_device *ccdc, struct v4l2_subdev_pad_config *cfg, +__ccdc_get_crop(struct isp_ccdc_device *ccdc, + struct v4l2_subdev_state *sd_state, enum v4l2_subdev_format_whence which) { if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_crop(&ccdc->subdev, cfg, CCDC_PAD_SOURCE_OF); + return v4l2_subdev_get_try_crop(&ccdc->subdev, sd_state, + CCDC_PAD_SOURCE_OF); else return &ccdc->crop; } @@ -1963,7 +1968,8 @@ __ccdc_get_crop(struct isp_ccdc_device *ccdc, struct v4l2_subdev_pad_config *cfg * @fmt: Format */ static void -ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_pad_config *cfg, +ccdc_try_format(struct isp_ccdc_device *ccdc, + struct v4l2_subdev_state *sd_state, unsigned int pad, struct v4l2_mbus_framefmt *fmt, enum v4l2_subdev_format_whence which) { @@ -1999,7 +2005,8 @@ ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_pad_config *cfg case CCDC_PAD_SOURCE_OF: pixelcode = fmt->code; field = fmt->field; - *fmt = *__ccdc_get_format(ccdc, cfg, CCDC_PAD_SINK, which); + *fmt = *__ccdc_get_format(ccdc, sd_state, CCDC_PAD_SINK, + which); /* In SYNC mode the bridge converts YUV formats from 2X8 to * 1X16. In BT.656 no such conversion occurs. As we don't know @@ -2024,7 +2031,7 @@ ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_pad_config *cfg } /* Hardcode the output size to the crop rectangle size. */ - crop = __ccdc_get_crop(ccdc, cfg, which); + crop = __ccdc_get_crop(ccdc, sd_state, which); fmt->width = crop->width; fmt->height = crop->height; @@ -2041,7 +2048,8 @@ ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_pad_config *cfg break; case CCDC_PAD_SOURCE_VP: - *fmt = *__ccdc_get_format(ccdc, cfg, CCDC_PAD_SINK, which); + *fmt = *__ccdc_get_format(ccdc, sd_state, CCDC_PAD_SINK, + which); /* The video port interface truncates the data to 10 bits. */ info = omap3isp_video_format_info(fmt->code); @@ -2118,7 +2126,7 @@ static void ccdc_try_crop(struct isp_ccdc_device *ccdc, * return -EINVAL or zero on success */ static int ccdc_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd); @@ -2133,7 +2141,7 @@ static int ccdc_enum_mbus_code(struct v4l2_subdev *sd, break; case CCDC_PAD_SOURCE_OF: - format = __ccdc_get_format(ccdc, cfg, code->pad, + format = __ccdc_get_format(ccdc, sd_state, code->pad, code->which); if (format->code == MEDIA_BUS_FMT_YUYV8_2X8 || @@ -2164,7 +2172,7 @@ static int ccdc_enum_mbus_code(struct v4l2_subdev *sd, if (code->index != 0) return -EINVAL; - format = __ccdc_get_format(ccdc, cfg, code->pad, + format = __ccdc_get_format(ccdc, sd_state, code->pad, code->which); /* A pixel code equal to 0 means that the video port doesn't @@ -2184,7 +2192,7 @@ static int ccdc_enum_mbus_code(struct v4l2_subdev *sd, } static int ccdc_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd); @@ -2196,7 +2204,7 @@ static int ccdc_enum_frame_size(struct v4l2_subdev *sd, format.code = fse->code; format.width = 1; format.height = 1; - ccdc_try_format(ccdc, cfg, fse->pad, &format, fse->which); + ccdc_try_format(ccdc, sd_state, fse->pad, &format, fse->which); fse->min_width = format.width; fse->min_height = format.height; @@ -2206,7 +2214,7 @@ static int ccdc_enum_frame_size(struct v4l2_subdev *sd, format.code = fse->code; format.width = -1; format.height = -1; - ccdc_try_format(ccdc, cfg, fse->pad, &format, fse->which); + ccdc_try_format(ccdc, sd_state, fse->pad, &format, fse->which); fse->max_width = format.width; fse->max_height = format.height; @@ -2224,7 +2232,8 @@ static int ccdc_enum_frame_size(struct v4l2_subdev *sd, * * Return 0 on success or a negative error code otherwise. */ -static int ccdc_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, +static int ccdc_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd); @@ -2240,12 +2249,13 @@ static int ccdc_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_pad_con sel->r.width = INT_MAX; sel->r.height = INT_MAX; - format = __ccdc_get_format(ccdc, cfg, CCDC_PAD_SINK, sel->which); + format = __ccdc_get_format(ccdc, sd_state, CCDC_PAD_SINK, + sel->which); ccdc_try_crop(ccdc, format, &sel->r); break; case V4L2_SEL_TGT_CROP: - sel->r = *__ccdc_get_crop(ccdc, cfg, sel->which); + sel->r = *__ccdc_get_crop(ccdc, sd_state, sel->which); break; default: @@ -2266,7 +2276,8 @@ static int ccdc_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_pad_con * * Return 0 on success or a negative error code otherwise. */ -static int ccdc_set_selection(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, +static int ccdc_set_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd); @@ -2285,17 +2296,19 @@ static int ccdc_set_selection(struct v4l2_subdev *sd, struct v4l2_subdev_pad_con * rectangle. */ if (sel->flags & V4L2_SEL_FLAG_KEEP_CONFIG) { - sel->r = *__ccdc_get_crop(ccdc, cfg, sel->which); + sel->r = *__ccdc_get_crop(ccdc, sd_state, sel->which); return 0; } - format = __ccdc_get_format(ccdc, cfg, CCDC_PAD_SINK, sel->which); + format = __ccdc_get_format(ccdc, sd_state, CCDC_PAD_SINK, sel->which); ccdc_try_crop(ccdc, format, &sel->r); - *__ccdc_get_crop(ccdc, cfg, sel->which) = sel->r; + *__ccdc_get_crop(ccdc, sd_state, sel->which) = sel->r; /* Update the source format. */ - format = __ccdc_get_format(ccdc, cfg, CCDC_PAD_SOURCE_OF, sel->which); - ccdc_try_format(ccdc, cfg, CCDC_PAD_SOURCE_OF, format, sel->which); + format = __ccdc_get_format(ccdc, sd_state, CCDC_PAD_SOURCE_OF, + sel->which); + ccdc_try_format(ccdc, sd_state, CCDC_PAD_SOURCE_OF, format, + sel->which); return 0; } @@ -2309,13 +2322,14 @@ static int ccdc_set_selection(struct v4l2_subdev *sd, struct v4l2_subdev_pad_con * Return 0 on success or -EINVAL if the pad is invalid or doesn't correspond * to the format type. */ -static int ccdc_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, +static int ccdc_get_format(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *format; - format = __ccdc_get_format(ccdc, cfg, fmt->pad, fmt->which); + format = __ccdc_get_format(ccdc, sd_state, fmt->pad, fmt->which); if (format == NULL) return -EINVAL; @@ -2332,24 +2346,25 @@ static int ccdc_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config * Return 0 on success or -EINVAL if the pad is invalid or doesn't correspond * to the format type. */ -static int ccdc_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, +static int ccdc_set_format(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *format; struct v4l2_rect *crop; - format = __ccdc_get_format(ccdc, cfg, fmt->pad, fmt->which); + format = __ccdc_get_format(ccdc, sd_state, fmt->pad, fmt->which); if (format == NULL) return -EINVAL; - ccdc_try_format(ccdc, cfg, fmt->pad, &fmt->format, fmt->which); + ccdc_try_format(ccdc, sd_state, fmt->pad, &fmt->format, fmt->which); *format = fmt->format; /* Propagate the format from sink to source */ if (fmt->pad == CCDC_PAD_SINK) { /* Reset the crop rectangle. */ - crop = __ccdc_get_crop(ccdc, cfg, fmt->which); + crop = __ccdc_get_crop(ccdc, sd_state, fmt->which); crop->left = 0; crop->top = 0; crop->width = fmt->format.width; @@ -2358,16 +2373,16 @@ static int ccdc_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config ccdc_try_crop(ccdc, &fmt->format, crop); /* Update the source formats. */ - format = __ccdc_get_format(ccdc, cfg, CCDC_PAD_SOURCE_OF, + format = __ccdc_get_format(ccdc, sd_state, CCDC_PAD_SOURCE_OF, fmt->which); *format = fmt->format; - ccdc_try_format(ccdc, cfg, CCDC_PAD_SOURCE_OF, format, + ccdc_try_format(ccdc, sd_state, CCDC_PAD_SOURCE_OF, format, fmt->which); - format = __ccdc_get_format(ccdc, cfg, CCDC_PAD_SOURCE_VP, + format = __ccdc_get_format(ccdc, sd_state, CCDC_PAD_SOURCE_VP, fmt->which); *format = fmt->format; - ccdc_try_format(ccdc, cfg, CCDC_PAD_SOURCE_VP, format, + ccdc_try_format(ccdc, sd_state, CCDC_PAD_SOURCE_VP, format, fmt->which); } @@ -2454,7 +2469,7 @@ static int ccdc_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10; format.format.width = 4096; format.format.height = 4096; - ccdc_set_format(sd, fh ? fh->pad : NULL, &format); + ccdc_set_format(sd, fh ? fh->state : NULL, &format); return 0; } diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c index d0a49cdfd22d..acb58b6ddba1 100644 --- a/drivers/media/platform/omap3isp/ispccp2.c +++ b/drivers/media/platform/omap3isp/ispccp2.c @@ -618,11 +618,13 @@ static const unsigned int ccp2_fmts[] = { * return format structure or NULL on error */ static struct v4l2_mbus_framefmt * -__ccp2_get_format(struct isp_ccp2_device *ccp2, struct v4l2_subdev_pad_config *cfg, - unsigned int pad, enum v4l2_subdev_format_whence which) +__ccp2_get_format(struct isp_ccp2_device *ccp2, + struct v4l2_subdev_state *sd_state, + unsigned int pad, enum v4l2_subdev_format_whence which) { if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_format(&ccp2->subdev, cfg, pad); + return v4l2_subdev_get_try_format(&ccp2->subdev, sd_state, + pad); else return &ccp2->formats[pad]; } @@ -636,7 +638,8 @@ __ccp2_get_format(struct isp_ccp2_device *ccp2, struct v4l2_subdev_pad_config *c * @which : wanted subdev format */ static void ccp2_try_format(struct isp_ccp2_device *ccp2, - struct v4l2_subdev_pad_config *cfg, unsigned int pad, + struct v4l2_subdev_state *sd_state, + unsigned int pad, struct v4l2_mbus_framefmt *fmt, enum v4l2_subdev_format_whence which) { @@ -670,7 +673,8 @@ static void ccp2_try_format(struct isp_ccp2_device *ccp2, * When CCP2 write to memory feature will be added this * should be changed properly. */ - format = __ccp2_get_format(ccp2, cfg, CCP2_PAD_SINK, which); + format = __ccp2_get_format(ccp2, sd_state, CCP2_PAD_SINK, + which); memcpy(fmt, format, sizeof(*fmt)); fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; break; @@ -688,7 +692,7 @@ static void ccp2_try_format(struct isp_ccp2_device *ccp2, * return -EINVAL or zero on success */ static int ccp2_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd); @@ -703,8 +707,8 @@ static int ccp2_enum_mbus_code(struct v4l2_subdev *sd, if (code->index != 0) return -EINVAL; - format = __ccp2_get_format(ccp2, cfg, CCP2_PAD_SINK, - code->which); + format = __ccp2_get_format(ccp2, sd_state, CCP2_PAD_SINK, + code->which); code->code = format->code; } @@ -712,7 +716,7 @@ static int ccp2_enum_mbus_code(struct v4l2_subdev *sd, } static int ccp2_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd); @@ -724,7 +728,7 @@ static int ccp2_enum_frame_size(struct v4l2_subdev *sd, format.code = fse->code; format.width = 1; format.height = 1; - ccp2_try_format(ccp2, cfg, fse->pad, &format, fse->which); + ccp2_try_format(ccp2, sd_state, fse->pad, &format, fse->which); fse->min_width = format.width; fse->min_height = format.height; @@ -734,7 +738,7 @@ static int ccp2_enum_frame_size(struct v4l2_subdev *sd, format.code = fse->code; format.width = -1; format.height = -1; - ccp2_try_format(ccp2, cfg, fse->pad, &format, fse->which); + ccp2_try_format(ccp2, sd_state, fse->pad, &format, fse->which); fse->max_width = format.width; fse->max_height = format.height; @@ -748,13 +752,14 @@ static int ccp2_enum_frame_size(struct v4l2_subdev *sd, * @fmt : pointer to v4l2 subdev format structure * return -EINVAL or zero on success */ -static int ccp2_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_format *fmt) +static int ccp2_get_format(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_format *fmt) { struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *format; - format = __ccp2_get_format(ccp2, cfg, fmt->pad, fmt->which); + format = __ccp2_get_format(ccp2, sd_state, fmt->pad, fmt->which); if (format == NULL) return -EINVAL; @@ -769,25 +774,27 @@ static int ccp2_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config * @fmt : pointer to v4l2 subdev format structure * returns zero */ -static int ccp2_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_format *fmt) +static int ccp2_set_format(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_format *fmt) { struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *format; - format = __ccp2_get_format(ccp2, cfg, fmt->pad, fmt->which); + format = __ccp2_get_format(ccp2, sd_state, fmt->pad, fmt->which); if (format == NULL) return -EINVAL; - ccp2_try_format(ccp2, cfg, fmt->pad, &fmt->format, fmt->which); + ccp2_try_format(ccp2, sd_state, fmt->pad, &fmt->format, fmt->which); *format = fmt->format; /* Propagate the format from sink to source */ if (fmt->pad == CCP2_PAD_SINK) { - format = __ccp2_get_format(ccp2, cfg, CCP2_PAD_SOURCE, + format = __ccp2_get_format(ccp2, sd_state, CCP2_PAD_SOURCE, fmt->which); *format = fmt->format; - ccp2_try_format(ccp2, cfg, CCP2_PAD_SOURCE, format, fmt->which); + ccp2_try_format(ccp2, sd_state, CCP2_PAD_SOURCE, format, + fmt->which); } return 0; @@ -812,7 +819,7 @@ static int ccp2_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10; format.format.width = 4096; format.format.height = 4096; - ccp2_set_format(sd, fh ? fh->pad : NULL, &format); + ccp2_set_format(sd, fh ? fh->state : NULL, &format); return 0; } diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c index fd493c5e4e24..6302e0c94034 100644 --- a/drivers/media/platform/omap3isp/ispcsi2.c +++ b/drivers/media/platform/omap3isp/ispcsi2.c @@ -827,17 +827,20 @@ static const struct isp_video_operations csi2_ispvideo_ops = { */ static struct v4l2_mbus_framefmt * -__csi2_get_format(struct isp_csi2_device *csi2, struct v4l2_subdev_pad_config *cfg, +__csi2_get_format(struct isp_csi2_device *csi2, + struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which) { if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_format(&csi2->subdev, cfg, pad); + return v4l2_subdev_get_try_format(&csi2->subdev, sd_state, + pad); else return &csi2->formats[pad]; } static void -csi2_try_format(struct isp_csi2_device *csi2, struct v4l2_subdev_pad_config *cfg, +csi2_try_format(struct isp_csi2_device *csi2, + struct v4l2_subdev_state *sd_state, unsigned int pad, struct v4l2_mbus_framefmt *fmt, enum v4l2_subdev_format_whence which) { @@ -867,7 +870,8 @@ csi2_try_format(struct isp_csi2_device *csi2, struct v4l2_subdev_pad_config *cfg * compression. */ pixelcode = fmt->code; - format = __csi2_get_format(csi2, cfg, CSI2_PAD_SINK, which); + format = __csi2_get_format(csi2, sd_state, CSI2_PAD_SINK, + which); memcpy(fmt, format, sizeof(*fmt)); /* @@ -893,7 +897,7 @@ csi2_try_format(struct isp_csi2_device *csi2, struct v4l2_subdev_pad_config *cfg * return -EINVAL or zero on success */ static int csi2_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd); @@ -906,7 +910,7 @@ static int csi2_enum_mbus_code(struct v4l2_subdev *sd, code->code = csi2_input_fmts[code->index]; } else { - format = __csi2_get_format(csi2, cfg, CSI2_PAD_SINK, + format = __csi2_get_format(csi2, sd_state, CSI2_PAD_SINK, code->which); switch (code->index) { case 0: @@ -930,7 +934,7 @@ static int csi2_enum_mbus_code(struct v4l2_subdev *sd, } static int csi2_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd); @@ -942,7 +946,7 @@ static int csi2_enum_frame_size(struct v4l2_subdev *sd, format.code = fse->code; format.width = 1; format.height = 1; - csi2_try_format(csi2, cfg, fse->pad, &format, fse->which); + csi2_try_format(csi2, sd_state, fse->pad, &format, fse->which); fse->min_width = format.width; fse->min_height = format.height; @@ -952,7 +956,7 @@ static int csi2_enum_frame_size(struct v4l2_subdev *sd, format.code = fse->code; format.width = -1; format.height = -1; - csi2_try_format(csi2, cfg, fse->pad, &format, fse->which); + csi2_try_format(csi2, sd_state, fse->pad, &format, fse->which); fse->max_width = format.width; fse->max_height = format.height; @@ -966,13 +970,14 @@ static int csi2_enum_frame_size(struct v4l2_subdev *sd, * @fmt: pointer to v4l2 subdev format structure * return -EINVAL or zero on success */ -static int csi2_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, +static int csi2_get_format(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *format; - format = __csi2_get_format(csi2, cfg, fmt->pad, fmt->which); + format = __csi2_get_format(csi2, sd_state, fmt->pad, fmt->which); if (format == NULL) return -EINVAL; @@ -987,25 +992,27 @@ static int csi2_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config * @fmt: pointer to v4l2 subdev format structure * return -EINVAL or zero on success */ -static int csi2_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, +static int csi2_set_format(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *format; - format = __csi2_get_format(csi2, cfg, fmt->pad, fmt->which); + format = __csi2_get_format(csi2, sd_state, fmt->pad, fmt->which); if (format == NULL) return -EINVAL; - csi2_try_format(csi2, cfg, fmt->pad, &fmt->format, fmt->which); + csi2_try_format(csi2, sd_state, fmt->pad, &fmt->format, fmt->which); *format = fmt->format; /* Propagate the format from sink to source */ if (fmt->pad == CSI2_PAD_SINK) { - format = __csi2_get_format(csi2, cfg, CSI2_PAD_SOURCE, + format = __csi2_get_format(csi2, sd_state, CSI2_PAD_SOURCE, fmt->which); *format = fmt->format; - csi2_try_format(csi2, cfg, CSI2_PAD_SOURCE, format, fmt->which); + csi2_try_format(csi2, sd_state, CSI2_PAD_SOURCE, format, + fmt->which); } return 0; @@ -1030,7 +1037,7 @@ static int csi2_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10; format.format.width = 4096; format.format.height = 4096; - csi2_set_format(sd, fh ? fh->pad : NULL, &format); + csi2_set_format(sd, fh ? fh->state : NULL, &format); return 0; } diff --git a/drivers/media/platform/omap3isp/isppreview.c b/drivers/media/platform/omap3isp/isppreview.c index 607b7685c982..53aedec7990d 100644 --- a/drivers/media/platform/omap3isp/isppreview.c +++ b/drivers/media/platform/omap3isp/isppreview.c @@ -1679,21 +1679,25 @@ static int preview_set_stream(struct v4l2_subdev *sd, int enable) } static struct v4l2_mbus_framefmt * -__preview_get_format(struct isp_prev_device *prev, struct v4l2_subdev_pad_config *cfg, +__preview_get_format(struct isp_prev_device *prev, + struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which) { if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_format(&prev->subdev, cfg, pad); + return v4l2_subdev_get_try_format(&prev->subdev, sd_state, + pad); else return &prev->formats[pad]; } static struct v4l2_rect * -__preview_get_crop(struct isp_prev_device *prev, struct v4l2_subdev_pad_config *cfg, +__preview_get_crop(struct isp_prev_device *prev, + struct v4l2_subdev_state *sd_state, enum v4l2_subdev_format_whence which) { if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_crop(&prev->subdev, cfg, PREV_PAD_SINK); + return v4l2_subdev_get_try_crop(&prev->subdev, sd_state, + PREV_PAD_SINK); else return &prev->crop; } @@ -1729,7 +1733,8 @@ static const unsigned int preview_output_fmts[] = { * engine limits and the format and crop rectangles on other pads. */ static void preview_try_format(struct isp_prev_device *prev, - struct v4l2_subdev_pad_config *cfg, unsigned int pad, + struct v4l2_subdev_state *sd_state, + unsigned int pad, struct v4l2_mbus_framefmt *fmt, enum v4l2_subdev_format_whence which) { @@ -1770,7 +1775,8 @@ static void preview_try_format(struct isp_prev_device *prev, case PREV_PAD_SOURCE: pixelcode = fmt->code; - *fmt = *__preview_get_format(prev, cfg, PREV_PAD_SINK, which); + *fmt = *__preview_get_format(prev, sd_state, PREV_PAD_SINK, + which); switch (pixelcode) { case MEDIA_BUS_FMT_YUYV8_1X16: @@ -1788,7 +1794,7 @@ static void preview_try_format(struct isp_prev_device *prev, * is not supported yet, hardcode the output size to the crop * rectangle size. */ - crop = __preview_get_crop(prev, cfg, which); + crop = __preview_get_crop(prev, sd_state, which); fmt->width = crop->width; fmt->height = crop->height; @@ -1862,7 +1868,7 @@ static void preview_try_crop(struct isp_prev_device *prev, * return -EINVAL or zero on success */ static int preview_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { switch (code->pad) { @@ -1886,7 +1892,7 @@ static int preview_enum_mbus_code(struct v4l2_subdev *sd, } static int preview_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { struct isp_prev_device *prev = v4l2_get_subdevdata(sd); @@ -1898,7 +1904,7 @@ static int preview_enum_frame_size(struct v4l2_subdev *sd, format.code = fse->code; format.width = 1; format.height = 1; - preview_try_format(prev, cfg, fse->pad, &format, fse->which); + preview_try_format(prev, sd_state, fse->pad, &format, fse->which); fse->min_width = format.width; fse->min_height = format.height; @@ -1908,7 +1914,7 @@ static int preview_enum_frame_size(struct v4l2_subdev *sd, format.code = fse->code; format.width = -1; format.height = -1; - preview_try_format(prev, cfg, fse->pad, &format, fse->which); + preview_try_format(prev, sd_state, fse->pad, &format, fse->which); fse->max_width = format.width; fse->max_height = format.height; @@ -1926,7 +1932,7 @@ static int preview_enum_frame_size(struct v4l2_subdev *sd, * Return 0 on success or a negative error code otherwise. */ static int preview_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct isp_prev_device *prev = v4l2_get_subdevdata(sd); @@ -1942,13 +1948,13 @@ static int preview_get_selection(struct v4l2_subdev *sd, sel->r.width = INT_MAX; sel->r.height = INT_MAX; - format = __preview_get_format(prev, cfg, PREV_PAD_SINK, + format = __preview_get_format(prev, sd_state, PREV_PAD_SINK, sel->which); preview_try_crop(prev, format, &sel->r); break; case V4L2_SEL_TGT_CROP: - sel->r = *__preview_get_crop(prev, cfg, sel->which); + sel->r = *__preview_get_crop(prev, sd_state, sel->which); break; default: @@ -1969,7 +1975,7 @@ static int preview_get_selection(struct v4l2_subdev *sd, * Return 0 on success or a negative error code otherwise. */ static int preview_set_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct isp_prev_device *prev = v4l2_get_subdevdata(sd); @@ -1988,17 +1994,20 @@ static int preview_set_selection(struct v4l2_subdev *sd, * rectangle. */ if (sel->flags & V4L2_SEL_FLAG_KEEP_CONFIG) { - sel->r = *__preview_get_crop(prev, cfg, sel->which); + sel->r = *__preview_get_crop(prev, sd_state, sel->which); return 0; } - format = __preview_get_format(prev, cfg, PREV_PAD_SINK, sel->which); + format = __preview_get_format(prev, sd_state, PREV_PAD_SINK, + sel->which); preview_try_crop(prev, format, &sel->r); - *__preview_get_crop(prev, cfg, sel->which) = sel->r; + *__preview_get_crop(prev, sd_state, sel->which) = sel->r; /* Update the source format. */ - format = __preview_get_format(prev, cfg, PREV_PAD_SOURCE, sel->which); - preview_try_format(prev, cfg, PREV_PAD_SOURCE, format, sel->which); + format = __preview_get_format(prev, sd_state, PREV_PAD_SOURCE, + sel->which); + preview_try_format(prev, sd_state, PREV_PAD_SOURCE, format, + sel->which); return 0; } @@ -2010,13 +2019,14 @@ static int preview_set_selection(struct v4l2_subdev *sd, * @fmt: pointer to v4l2 subdev format structure * return -EINVAL or zero on success */ -static int preview_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, +static int preview_get_format(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct isp_prev_device *prev = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *format; - format = __preview_get_format(prev, cfg, fmt->pad, fmt->which); + format = __preview_get_format(prev, sd_state, fmt->pad, fmt->which); if (format == NULL) return -EINVAL; @@ -2031,24 +2041,25 @@ static int preview_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_con * @fmt: pointer to v4l2 subdev format structure * return -EINVAL or zero on success */ -static int preview_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, +static int preview_set_format(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct isp_prev_device *prev = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *format; struct v4l2_rect *crop; - format = __preview_get_format(prev, cfg, fmt->pad, fmt->which); + format = __preview_get_format(prev, sd_state, fmt->pad, fmt->which); if (format == NULL) return -EINVAL; - preview_try_format(prev, cfg, fmt->pad, &fmt->format, fmt->which); + preview_try_format(prev, sd_state, fmt->pad, &fmt->format, fmt->which); *format = fmt->format; /* Propagate the format from sink to source */ if (fmt->pad == PREV_PAD_SINK) { /* Reset the crop rectangle. */ - crop = __preview_get_crop(prev, cfg, fmt->which); + crop = __preview_get_crop(prev, sd_state, fmt->which); crop->left = 0; crop->top = 0; crop->width = fmt->format.width; @@ -2057,9 +2068,9 @@ static int preview_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_con preview_try_crop(prev, &fmt->format, crop); /* Update the source format. */ - format = __preview_get_format(prev, cfg, PREV_PAD_SOURCE, + format = __preview_get_format(prev, sd_state, PREV_PAD_SOURCE, fmt->which); - preview_try_format(prev, cfg, PREV_PAD_SOURCE, format, + preview_try_format(prev, sd_state, PREV_PAD_SOURCE, format, fmt->which); } @@ -2086,7 +2097,7 @@ static int preview_init_formats(struct v4l2_subdev *sd, format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10; format.format.width = 4096; format.format.height = 4096; - preview_set_format(sd, fh ? fh->pad : NULL, &format); + preview_set_format(sd, fh ? fh->state : NULL, &format); return 0; } diff --git a/drivers/media/platform/omap3isp/ispresizer.c b/drivers/media/platform/omap3isp/ispresizer.c index 78d9dd7ea2da..ed2fb0c7a57e 100644 --- a/drivers/media/platform/omap3isp/ispresizer.c +++ b/drivers/media/platform/omap3isp/ispresizer.c @@ -114,11 +114,12 @@ static const struct isprsz_coef filter_coefs = { * return zero */ static struct v4l2_mbus_framefmt * -__resizer_get_format(struct isp_res_device *res, struct v4l2_subdev_pad_config *cfg, +__resizer_get_format(struct isp_res_device *res, + struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which) { if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_format(&res->subdev, cfg, pad); + return v4l2_subdev_get_try_format(&res->subdev, sd_state, pad); else return &res->formats[pad]; } @@ -130,11 +131,13 @@ __resizer_get_format(struct isp_res_device *res, struct v4l2_subdev_pad_config * * @which : wanted subdev crop rectangle */ static struct v4l2_rect * -__resizer_get_crop(struct isp_res_device *res, struct v4l2_subdev_pad_config *cfg, +__resizer_get_crop(struct isp_res_device *res, + struct v4l2_subdev_state *sd_state, enum v4l2_subdev_format_whence which) { if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_crop(&res->subdev, cfg, RESZ_PAD_SINK); + return v4l2_subdev_get_try_crop(&res->subdev, sd_state, + RESZ_PAD_SINK); else return &res->crop.request; } @@ -1220,7 +1223,7 @@ static void resizer_try_crop(const struct v4l2_mbus_framefmt *sink, * Return 0 on success or a negative error code otherwise. */ static int resizer_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct isp_res_device *res = v4l2_get_subdevdata(sd); @@ -1231,9 +1234,9 @@ static int resizer_get_selection(struct v4l2_subdev *sd, if (sel->pad != RESZ_PAD_SINK) return -EINVAL; - format_sink = __resizer_get_format(res, cfg, RESZ_PAD_SINK, + format_sink = __resizer_get_format(res, sd_state, RESZ_PAD_SINK, sel->which); - format_source = __resizer_get_format(res, cfg, RESZ_PAD_SOURCE, + format_source = __resizer_get_format(res, sd_state, RESZ_PAD_SOURCE, sel->which); switch (sel->target) { @@ -1248,7 +1251,7 @@ static int resizer_get_selection(struct v4l2_subdev *sd, break; case V4L2_SEL_TGT_CROP: - sel->r = *__resizer_get_crop(res, cfg, sel->which); + sel->r = *__resizer_get_crop(res, sd_state, sel->which); resizer_calc_ratios(res, &sel->r, format_source, &ratio); break; @@ -1273,7 +1276,7 @@ static int resizer_get_selection(struct v4l2_subdev *sd, * Return 0 on success or a negative error code otherwise. */ static int resizer_set_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct isp_res_device *res = v4l2_get_subdevdata(sd); @@ -1287,9 +1290,9 @@ static int resizer_set_selection(struct v4l2_subdev *sd, sel->pad != RESZ_PAD_SINK) return -EINVAL; - format_sink = __resizer_get_format(res, cfg, RESZ_PAD_SINK, + format_sink = __resizer_get_format(res, sd_state, RESZ_PAD_SINK, sel->which); - format_source = *__resizer_get_format(res, cfg, RESZ_PAD_SOURCE, + format_source = *__resizer_get_format(res, sd_state, RESZ_PAD_SOURCE, sel->which); dev_dbg(isp->dev, "%s(%s): req %ux%u -> (%d,%d)/%ux%u -> %ux%u\n", @@ -1307,7 +1310,7 @@ static int resizer_set_selection(struct v4l2_subdev *sd, * stored the mangled rectangle. */ resizer_try_crop(format_sink, &format_source, &sel->r); - *__resizer_get_crop(res, cfg, sel->which) = sel->r; + *__resizer_get_crop(res, sd_state, sel->which) = sel->r; resizer_calc_ratios(res, &sel->r, &format_source, &ratio); dev_dbg(isp->dev, "%s(%s): got %ux%u -> (%d,%d)/%ux%u -> %ux%u\n", @@ -1317,7 +1320,8 @@ static int resizer_set_selection(struct v4l2_subdev *sd, format_source.width, format_source.height); if (sel->which == V4L2_SUBDEV_FORMAT_TRY) { - *__resizer_get_format(res, cfg, RESZ_PAD_SOURCE, sel->which) = + *__resizer_get_format(res, sd_state, RESZ_PAD_SOURCE, + sel->which) = format_source; return 0; } @@ -1328,7 +1332,7 @@ static int resizer_set_selection(struct v4l2_subdev *sd, */ spin_lock_irqsave(&res->lock, flags); - *__resizer_get_format(res, cfg, RESZ_PAD_SOURCE, sel->which) = + *__resizer_get_format(res, sd_state, RESZ_PAD_SOURCE, sel->which) = format_source; res->ratio = ratio; @@ -1371,7 +1375,8 @@ static unsigned int resizer_max_in_width(struct isp_res_device *res) * @which : wanted subdev format */ static void resizer_try_format(struct isp_res_device *res, - struct v4l2_subdev_pad_config *cfg, unsigned int pad, + struct v4l2_subdev_state *sd_state, + unsigned int pad, struct v4l2_mbus_framefmt *fmt, enum v4l2_subdev_format_whence which) { @@ -1392,10 +1397,11 @@ static void resizer_try_format(struct isp_res_device *res, break; case RESZ_PAD_SOURCE: - format = __resizer_get_format(res, cfg, RESZ_PAD_SINK, which); + format = __resizer_get_format(res, sd_state, RESZ_PAD_SINK, + which); fmt->code = format->code; - crop = *__resizer_get_crop(res, cfg, which); + crop = *__resizer_get_crop(res, sd_state, which); resizer_calc_ratios(res, &crop, fmt, &ratio); break; } @@ -1412,7 +1418,7 @@ static void resizer_try_format(struct isp_res_device *res, * return -EINVAL or zero on success */ static int resizer_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct isp_res_device *res = v4l2_get_subdevdata(sd); @@ -1427,7 +1433,7 @@ static int resizer_enum_mbus_code(struct v4l2_subdev *sd, if (code->index != 0) return -EINVAL; - format = __resizer_get_format(res, cfg, RESZ_PAD_SINK, + format = __resizer_get_format(res, sd_state, RESZ_PAD_SINK, code->which); code->code = format->code; } @@ -1436,7 +1442,7 @@ static int resizer_enum_mbus_code(struct v4l2_subdev *sd, } static int resizer_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { struct isp_res_device *res = v4l2_get_subdevdata(sd); @@ -1448,7 +1454,7 @@ static int resizer_enum_frame_size(struct v4l2_subdev *sd, format.code = fse->code; format.width = 1; format.height = 1; - resizer_try_format(res, cfg, fse->pad, &format, fse->which); + resizer_try_format(res, sd_state, fse->pad, &format, fse->which); fse->min_width = format.width; fse->min_height = format.height; @@ -1458,7 +1464,7 @@ static int resizer_enum_frame_size(struct v4l2_subdev *sd, format.code = fse->code; format.width = -1; format.height = -1; - resizer_try_format(res, cfg, fse->pad, &format, fse->which); + resizer_try_format(res, sd_state, fse->pad, &format, fse->which); fse->max_width = format.width; fse->max_height = format.height; @@ -1472,13 +1478,14 @@ static int resizer_enum_frame_size(struct v4l2_subdev *sd, * @fmt : pointer to v4l2 subdev format structure * return -EINVAL or zero on success */ -static int resizer_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, +static int resizer_get_format(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct isp_res_device *res = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *format; - format = __resizer_get_format(res, cfg, fmt->pad, fmt->which); + format = __resizer_get_format(res, sd_state, fmt->pad, fmt->which); if (format == NULL) return -EINVAL; @@ -1493,33 +1500,34 @@ static int resizer_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_con * @fmt : pointer to v4l2 subdev format structure * return -EINVAL or zero on success */ -static int resizer_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, +static int resizer_set_format(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct isp_res_device *res = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *format; struct v4l2_rect *crop; - format = __resizer_get_format(res, cfg, fmt->pad, fmt->which); + format = __resizer_get_format(res, sd_state, fmt->pad, fmt->which); if (format == NULL) return -EINVAL; - resizer_try_format(res, cfg, fmt->pad, &fmt->format, fmt->which); + resizer_try_format(res, sd_state, fmt->pad, &fmt->format, fmt->which); *format = fmt->format; if (fmt->pad == RESZ_PAD_SINK) { /* reset crop rectangle */ - crop = __resizer_get_crop(res, cfg, fmt->which); + crop = __resizer_get_crop(res, sd_state, fmt->which); crop->left = 0; crop->top = 0; crop->width = fmt->format.width; crop->height = fmt->format.height; /* Propagate the format from sink to source */ - format = __resizer_get_format(res, cfg, RESZ_PAD_SOURCE, + format = __resizer_get_format(res, sd_state, RESZ_PAD_SOURCE, fmt->which); *format = fmt->format; - resizer_try_format(res, cfg, RESZ_PAD_SOURCE, format, + resizer_try_format(res, sd_state, RESZ_PAD_SOURCE, format, fmt->which); } @@ -1570,7 +1578,7 @@ static int resizer_init_formats(struct v4l2_subdev *sd, format.format.code = MEDIA_BUS_FMT_YUYV8_1X16; format.format.width = 4096; format.format.height = 4096; - resizer_set_format(sd, fh ? fh->pad : NULL, &format); + resizer_set_format(sd, fh ? fh->state : NULL, &format); return 0; } diff --git a/drivers/media/platform/pxa_camera.c b/drivers/media/platform/pxa_camera.c index dd510ee9b58a..ec4c010644ca 100644 --- a/drivers/media/platform/pxa_camera.c +++ b/drivers/media/platform/pxa_camera.c @@ -1792,6 +1792,9 @@ static int pxac_vidioc_try_fmt_vid_cap(struct file *filp, void *priv, const struct pxa_camera_format_xlate *xlate; struct v4l2_pix_format *pix = &f->fmt.pix; struct v4l2_subdev_pad_config pad_cfg; + struct v4l2_subdev_state pad_state = { + .pads = &pad_cfg + }; struct v4l2_subdev_format format = { .which = V4L2_SUBDEV_FORMAT_TRY, }; @@ -1816,7 +1819,7 @@ static int pxac_vidioc_try_fmt_vid_cap(struct file *filp, void *priv, pixfmt == V4L2_PIX_FMT_YUV422P ? 4 : 0); v4l2_fill_mbus_format(mf, pix, xlate->code); - ret = sensor_call(pcdev, pad, set_fmt, &pad_cfg, &format); + ret = sensor_call(pcdev, pad, set_fmt, &pad_state, &format); if (ret < 0) return ret; diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c index 251f4c4afe19..a1637b78568b 100644 --- a/drivers/media/platform/qcom/camss/camss-csid.c +++ b/drivers/media/platform/qcom/camss/camss-csid.c @@ -245,12 +245,13 @@ static int csid_set_stream(struct v4l2_subdev *sd, int enable) */ static struct v4l2_mbus_framefmt * __csid_get_format(struct csid_device *csid, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which) { if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_format(&csid->subdev, cfg, pad); + return v4l2_subdev_get_try_format(&csid->subdev, sd_state, + pad); return &csid->fmt[pad]; } @@ -264,7 +265,7 @@ __csid_get_format(struct csid_device *csid, * @which: wanted subdev format */ static void csid_try_format(struct csid_device *csid, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad, struct v4l2_mbus_framefmt *fmt, enum v4l2_subdev_format_whence which) @@ -297,7 +298,7 @@ static void csid_try_format(struct csid_device *csid, /* keep pad formats in sync */ u32 code = fmt->code; - *fmt = *__csid_get_format(csid, cfg, + *fmt = *__csid_get_format(csid, sd_state, MSM_CSID_PAD_SINK, which); fmt->code = csid->ops->src_pad_code(csid, fmt->code, 0, code); } else { @@ -331,7 +332,7 @@ static void csid_try_format(struct csid_device *csid, * return -EINVAL or zero on success */ static int csid_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct csid_device *csid = v4l2_get_subdevdata(sd); @@ -345,7 +346,7 @@ static int csid_enum_mbus_code(struct v4l2_subdev *sd, if (csid->testgen_mode->cur.val == 0) { struct v4l2_mbus_framefmt *sink_fmt; - sink_fmt = __csid_get_format(csid, cfg, + sink_fmt = __csid_get_format(csid, sd_state, MSM_CSID_PAD_SINK, code->which); @@ -372,7 +373,7 @@ static int csid_enum_mbus_code(struct v4l2_subdev *sd, * return -EINVAL or zero on success */ static int csid_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { struct csid_device *csid = v4l2_get_subdevdata(sd); @@ -384,7 +385,7 @@ static int csid_enum_frame_size(struct v4l2_subdev *sd, format.code = fse->code; format.width = 1; format.height = 1; - csid_try_format(csid, cfg, fse->pad, &format, fse->which); + csid_try_format(csid, sd_state, fse->pad, &format, fse->which); fse->min_width = format.width; fse->min_height = format.height; @@ -394,7 +395,7 @@ static int csid_enum_frame_size(struct v4l2_subdev *sd, format.code = fse->code; format.width = -1; format.height = -1; - csid_try_format(csid, cfg, fse->pad, &format, fse->which); + csid_try_format(csid, sd_state, fse->pad, &format, fse->which); fse->max_width = format.width; fse->max_height = format.height; @@ -410,13 +411,13 @@ static int csid_enum_frame_size(struct v4l2_subdev *sd, * Return -EINVAL or zero on success */ static int csid_get_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct csid_device *csid = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *format; - format = __csid_get_format(csid, cfg, fmt->pad, fmt->which); + format = __csid_get_format(csid, sd_state, fmt->pad, fmt->which); if (format == NULL) return -EINVAL; @@ -434,26 +435,26 @@ static int csid_get_format(struct v4l2_subdev *sd, * Return -EINVAL or zero on success */ static int csid_set_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct csid_device *csid = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *format; - format = __csid_get_format(csid, cfg, fmt->pad, fmt->which); + format = __csid_get_format(csid, sd_state, fmt->pad, fmt->which); if (format == NULL) return -EINVAL; - csid_try_format(csid, cfg, fmt->pad, &fmt->format, fmt->which); + csid_try_format(csid, sd_state, fmt->pad, &fmt->format, fmt->which); *format = fmt->format; /* Propagate the format from sink to source */ if (fmt->pad == MSM_CSID_PAD_SINK) { - format = __csid_get_format(csid, cfg, MSM_CSID_PAD_SRC, + format = __csid_get_format(csid, sd_state, MSM_CSID_PAD_SRC, fmt->which); *format = fmt->format; - csid_try_format(csid, cfg, MSM_CSID_PAD_SRC, format, + csid_try_format(csid, sd_state, MSM_CSID_PAD_SRC, format, fmt->which); } @@ -482,7 +483,7 @@ static int csid_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) } }; - return csid_set_format(sd, fh ? fh->pad : NULL, &format); + return csid_set_format(sd, fh ? fh->state : NULL, &format); } /* diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c index 35470cbaea86..24eec16197e7 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c @@ -338,12 +338,13 @@ static int csiphy_set_stream(struct v4l2_subdev *sd, int enable) */ static struct v4l2_mbus_framefmt * __csiphy_get_format(struct csiphy_device *csiphy, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which) { if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_format(&csiphy->subdev, cfg, pad); + return v4l2_subdev_get_try_format(&csiphy->subdev, sd_state, + pad); return &csiphy->fmt[pad]; } @@ -357,7 +358,7 @@ __csiphy_get_format(struct csiphy_device *csiphy, * @which: wanted subdev format */ static void csiphy_try_format(struct csiphy_device *csiphy, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad, struct v4l2_mbus_framefmt *fmt, enum v4l2_subdev_format_whence which) @@ -387,7 +388,8 @@ static void csiphy_try_format(struct csiphy_device *csiphy, case MSM_CSIPHY_PAD_SRC: /* Set and return a format same as sink pad */ - *fmt = *__csiphy_get_format(csiphy, cfg, MSM_CSID_PAD_SINK, + *fmt = *__csiphy_get_format(csiphy, sd_state, + MSM_CSID_PAD_SINK, which); break; @@ -402,7 +404,7 @@ static void csiphy_try_format(struct csiphy_device *csiphy, * return -EINVAL or zero on success */ static int csiphy_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct csiphy_device *csiphy = v4l2_get_subdevdata(sd); @@ -417,7 +419,8 @@ static int csiphy_enum_mbus_code(struct v4l2_subdev *sd, if (code->index > 0) return -EINVAL; - format = __csiphy_get_format(csiphy, cfg, MSM_CSIPHY_PAD_SINK, + format = __csiphy_get_format(csiphy, sd_state, + MSM_CSIPHY_PAD_SINK, code->which); code->code = format->code; @@ -434,7 +437,7 @@ static int csiphy_enum_mbus_code(struct v4l2_subdev *sd, * return -EINVAL or zero on success */ static int csiphy_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { struct csiphy_device *csiphy = v4l2_get_subdevdata(sd); @@ -446,7 +449,7 @@ static int csiphy_enum_frame_size(struct v4l2_subdev *sd, format.code = fse->code; format.width = 1; format.height = 1; - csiphy_try_format(csiphy, cfg, fse->pad, &format, fse->which); + csiphy_try_format(csiphy, sd_state, fse->pad, &format, fse->which); fse->min_width = format.width; fse->min_height = format.height; @@ -456,7 +459,7 @@ static int csiphy_enum_frame_size(struct v4l2_subdev *sd, format.code = fse->code; format.width = -1; format.height = -1; - csiphy_try_format(csiphy, cfg, fse->pad, &format, fse->which); + csiphy_try_format(csiphy, sd_state, fse->pad, &format, fse->which); fse->max_width = format.width; fse->max_height = format.height; @@ -472,13 +475,13 @@ static int csiphy_enum_frame_size(struct v4l2_subdev *sd, * Return -EINVAL or zero on success */ static int csiphy_get_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct csiphy_device *csiphy = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *format; - format = __csiphy_get_format(csiphy, cfg, fmt->pad, fmt->which); + format = __csiphy_get_format(csiphy, sd_state, fmt->pad, fmt->which); if (format == NULL) return -EINVAL; @@ -496,26 +499,29 @@ static int csiphy_get_format(struct v4l2_subdev *sd, * Return -EINVAL or zero on success */ static int csiphy_set_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct csiphy_device *csiphy = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *format; - format = __csiphy_get_format(csiphy, cfg, fmt->pad, fmt->which); + format = __csiphy_get_format(csiphy, sd_state, fmt->pad, fmt->which); if (format == NULL) return -EINVAL; - csiphy_try_format(csiphy, cfg, fmt->pad, &fmt->format, fmt->which); + csiphy_try_format(csiphy, sd_state, fmt->pad, &fmt->format, + fmt->which); *format = fmt->format; /* Propagate the format from sink to source */ if (fmt->pad == MSM_CSIPHY_PAD_SINK) { - format = __csiphy_get_format(csiphy, cfg, MSM_CSIPHY_PAD_SRC, + format = __csiphy_get_format(csiphy, sd_state, + MSM_CSIPHY_PAD_SRC, fmt->which); *format = fmt->format; - csiphy_try_format(csiphy, cfg, MSM_CSIPHY_PAD_SRC, format, + csiphy_try_format(csiphy, sd_state, MSM_CSIPHY_PAD_SRC, + format, fmt->which); } @@ -545,7 +551,7 @@ static int csiphy_init_formats(struct v4l2_subdev *sd, } }; - return csiphy_set_format(sd, fh ? fh->pad : NULL, &format); + return csiphy_set_format(sd, fh ? fh->state : NULL, &format); } /* diff --git a/drivers/media/platform/qcom/camss/camss-ispif.c b/drivers/media/platform/qcom/camss/camss-ispif.c index 1b716182d35c..ba5d65f6ef34 100644 --- a/drivers/media/platform/qcom/camss/camss-ispif.c +++ b/drivers/media/platform/qcom/camss/camss-ispif.c @@ -874,12 +874,13 @@ static int ispif_set_stream(struct v4l2_subdev *sd, int enable) */ static struct v4l2_mbus_framefmt * __ispif_get_format(struct ispif_line *line, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which) { if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_format(&line->subdev, cfg, pad); + return v4l2_subdev_get_try_format(&line->subdev, sd_state, + pad); return &line->fmt[pad]; } @@ -893,7 +894,7 @@ __ispif_get_format(struct ispif_line *line, * @which: wanted subdev format */ static void ispif_try_format(struct ispif_line *line, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad, struct v4l2_mbus_framefmt *fmt, enum v4l2_subdev_format_whence which) @@ -923,7 +924,7 @@ static void ispif_try_format(struct ispif_line *line, case MSM_ISPIF_PAD_SRC: /* Set and return a format same as sink pad */ - *fmt = *__ispif_get_format(line, cfg, MSM_ISPIF_PAD_SINK, + *fmt = *__ispif_get_format(line, sd_state, MSM_ISPIF_PAD_SINK, which); break; @@ -940,7 +941,7 @@ static void ispif_try_format(struct ispif_line *line, * return -EINVAL or zero on success */ static int ispif_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct ispif_line *line = v4l2_get_subdevdata(sd); @@ -955,7 +956,8 @@ static int ispif_enum_mbus_code(struct v4l2_subdev *sd, if (code->index > 0) return -EINVAL; - format = __ispif_get_format(line, cfg, MSM_ISPIF_PAD_SINK, + format = __ispif_get_format(line, sd_state, + MSM_ISPIF_PAD_SINK, code->which); code->code = format->code; @@ -972,7 +974,7 @@ static int ispif_enum_mbus_code(struct v4l2_subdev *sd, * return -EINVAL or zero on success */ static int ispif_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { struct ispif_line *line = v4l2_get_subdevdata(sd); @@ -984,7 +986,7 @@ static int ispif_enum_frame_size(struct v4l2_subdev *sd, format.code = fse->code; format.width = 1; format.height = 1; - ispif_try_format(line, cfg, fse->pad, &format, fse->which); + ispif_try_format(line, sd_state, fse->pad, &format, fse->which); fse->min_width = format.width; fse->min_height = format.height; @@ -994,7 +996,7 @@ static int ispif_enum_frame_size(struct v4l2_subdev *sd, format.code = fse->code; format.width = -1; format.height = -1; - ispif_try_format(line, cfg, fse->pad, &format, fse->which); + ispif_try_format(line, sd_state, fse->pad, &format, fse->which); fse->max_width = format.width; fse->max_height = format.height; @@ -1010,13 +1012,13 @@ static int ispif_enum_frame_size(struct v4l2_subdev *sd, * Return -EINVAL or zero on success */ static int ispif_get_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct ispif_line *line = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *format; - format = __ispif_get_format(line, cfg, fmt->pad, fmt->which); + format = __ispif_get_format(line, sd_state, fmt->pad, fmt->which); if (format == NULL) return -EINVAL; @@ -1034,26 +1036,26 @@ static int ispif_get_format(struct v4l2_subdev *sd, * Return -EINVAL or zero on success */ static int ispif_set_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct ispif_line *line = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *format; - format = __ispif_get_format(line, cfg, fmt->pad, fmt->which); + format = __ispif_get_format(line, sd_state, fmt->pad, fmt->which); if (format == NULL) return -EINVAL; - ispif_try_format(line, cfg, fmt->pad, &fmt->format, fmt->which); + ispif_try_format(line, sd_state, fmt->pad, &fmt->format, fmt->which); *format = fmt->format; /* Propagate the format from sink to source */ if (fmt->pad == MSM_ISPIF_PAD_SINK) { - format = __ispif_get_format(line, cfg, MSM_ISPIF_PAD_SRC, + format = __ispif_get_format(line, sd_state, MSM_ISPIF_PAD_SRC, fmt->which); *format = fmt->format; - ispif_try_format(line, cfg, MSM_ISPIF_PAD_SRC, format, + ispif_try_format(line, sd_state, MSM_ISPIF_PAD_SRC, format, fmt->which); } @@ -1082,7 +1084,7 @@ static int ispif_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) } }; - return ispif_set_format(sd, fh ? fh->pad : NULL, &format); + return ispif_set_format(sd, fh ? fh->state : NULL, &format); } /* diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c index 27ab20c5b57e..e0f3a36f3f3f 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe.c +++ b/drivers/media/platform/qcom/camss/camss-vfe.c @@ -763,12 +763,13 @@ static int vfe_set_stream(struct v4l2_subdev *sd, int enable) */ static struct v4l2_mbus_framefmt * __vfe_get_format(struct vfe_line *line, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which) { if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_format(&line->subdev, cfg, pad); + return v4l2_subdev_get_try_format(&line->subdev, sd_state, + pad); return &line->fmt[pad]; } @@ -783,11 +784,11 @@ __vfe_get_format(struct vfe_line *line, */ static struct v4l2_rect * __vfe_get_compose(struct vfe_line *line, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, enum v4l2_subdev_format_whence which) { if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_compose(&line->subdev, cfg, + return v4l2_subdev_get_try_compose(&line->subdev, sd_state, MSM_VFE_PAD_SINK); return &line->compose; @@ -803,11 +804,11 @@ __vfe_get_compose(struct vfe_line *line, */ static struct v4l2_rect * __vfe_get_crop(struct vfe_line *line, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, enum v4l2_subdev_format_whence which) { if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_crop(&line->subdev, cfg, + return v4l2_subdev_get_try_crop(&line->subdev, sd_state, MSM_VFE_PAD_SRC); return &line->crop; @@ -822,7 +823,7 @@ __vfe_get_crop(struct vfe_line *line, * @which: wanted subdev format */ static void vfe_try_format(struct vfe_line *line, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad, struct v4l2_mbus_framefmt *fmt, enum v4l2_subdev_format_whence which) @@ -854,14 +855,15 @@ static void vfe_try_format(struct vfe_line *line, /* Set and return a format same as sink pad */ code = fmt->code; - *fmt = *__vfe_get_format(line, cfg, MSM_VFE_PAD_SINK, which); + *fmt = *__vfe_get_format(line, sd_state, MSM_VFE_PAD_SINK, + which); fmt->code = vfe_src_pad_code(line, fmt->code, 0, code); if (line->id == VFE_LINE_PIX) { struct v4l2_rect *rect; - rect = __vfe_get_crop(line, cfg, which); + rect = __vfe_get_crop(line, sd_state, which); fmt->width = rect->width; fmt->height = rect->height; @@ -881,13 +883,13 @@ static void vfe_try_format(struct vfe_line *line, * @which: wanted subdev format */ static void vfe_try_compose(struct vfe_line *line, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_rect *rect, enum v4l2_subdev_format_whence which) { struct v4l2_mbus_framefmt *fmt; - fmt = __vfe_get_format(line, cfg, MSM_VFE_PAD_SINK, which); + fmt = __vfe_get_format(line, sd_state, MSM_VFE_PAD_SINK, which); if (rect->width > fmt->width) rect->width = fmt->width; @@ -920,13 +922,13 @@ static void vfe_try_compose(struct vfe_line *line, * @which: wanted subdev format */ static void vfe_try_crop(struct vfe_line *line, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_rect *rect, enum v4l2_subdev_format_whence which) { struct v4l2_rect *compose; - compose = __vfe_get_compose(line, cfg, which); + compose = __vfe_get_compose(line, sd_state, which); if (rect->width > compose->width) rect->width = compose->width; @@ -964,7 +966,7 @@ static void vfe_try_crop(struct vfe_line *line, * return -EINVAL or zero on success */ static int vfe_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct vfe_line *line = v4l2_get_subdevdata(sd); @@ -977,7 +979,7 @@ static int vfe_enum_mbus_code(struct v4l2_subdev *sd, } else { struct v4l2_mbus_framefmt *sink_fmt; - sink_fmt = __vfe_get_format(line, cfg, MSM_VFE_PAD_SINK, + sink_fmt = __vfe_get_format(line, sd_state, MSM_VFE_PAD_SINK, code->which); code->code = vfe_src_pad_code(line, sink_fmt->code, @@ -998,7 +1000,7 @@ static int vfe_enum_mbus_code(struct v4l2_subdev *sd, * Return -EINVAL or zero on success */ static int vfe_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { struct vfe_line *line = v4l2_get_subdevdata(sd); @@ -1010,7 +1012,7 @@ static int vfe_enum_frame_size(struct v4l2_subdev *sd, format.code = fse->code; format.width = 1; format.height = 1; - vfe_try_format(line, cfg, fse->pad, &format, fse->which); + vfe_try_format(line, sd_state, fse->pad, &format, fse->which); fse->min_width = format.width; fse->min_height = format.height; @@ -1020,7 +1022,7 @@ static int vfe_enum_frame_size(struct v4l2_subdev *sd, format.code = fse->code; format.width = -1; format.height = -1; - vfe_try_format(line, cfg, fse->pad, &format, fse->which); + vfe_try_format(line, sd_state, fse->pad, &format, fse->which); fse->max_width = format.width; fse->max_height = format.height; @@ -1036,13 +1038,13 @@ static int vfe_enum_frame_size(struct v4l2_subdev *sd, * Return -EINVAL or zero on success */ static int vfe_get_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct vfe_line *line = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *format; - format = __vfe_get_format(line, cfg, fmt->pad, fmt->which); + format = __vfe_get_format(line, sd_state, fmt->pad, fmt->which); if (format == NULL) return -EINVAL; @@ -1052,7 +1054,7 @@ static int vfe_get_format(struct v4l2_subdev *sd, } static int vfe_set_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel); /* @@ -1064,17 +1066,17 @@ static int vfe_set_selection(struct v4l2_subdev *sd, * Return -EINVAL or zero on success */ static int vfe_set_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct vfe_line *line = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *format; - format = __vfe_get_format(line, cfg, fmt->pad, fmt->which); + format = __vfe_get_format(line, sd_state, fmt->pad, fmt->which); if (format == NULL) return -EINVAL; - vfe_try_format(line, cfg, fmt->pad, &fmt->format, fmt->which); + vfe_try_format(line, sd_state, fmt->pad, &fmt->format, fmt->which); *format = fmt->format; if (fmt->pad == MSM_VFE_PAD_SINK) { @@ -1082,11 +1084,11 @@ static int vfe_set_format(struct v4l2_subdev *sd, int ret; /* Propagate the format from sink to source */ - format = __vfe_get_format(line, cfg, MSM_VFE_PAD_SRC, + format = __vfe_get_format(line, sd_state, MSM_VFE_PAD_SRC, fmt->which); *format = fmt->format; - vfe_try_format(line, cfg, MSM_VFE_PAD_SRC, format, + vfe_try_format(line, sd_state, MSM_VFE_PAD_SRC, format, fmt->which); if (line->id != VFE_LINE_PIX) @@ -1098,7 +1100,7 @@ static int vfe_set_format(struct v4l2_subdev *sd, sel.target = V4L2_SEL_TGT_COMPOSE; sel.r.width = fmt->format.width; sel.r.height = fmt->format.height; - ret = vfe_set_selection(sd, cfg, &sel); + ret = vfe_set_selection(sd, sd_state, &sel); if (ret < 0) return ret; } @@ -1115,7 +1117,7 @@ static int vfe_set_format(struct v4l2_subdev *sd, * Return -EINVAL or zero on success */ static int vfe_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct vfe_line *line = v4l2_get_subdevdata(sd); @@ -1131,7 +1133,7 @@ static int vfe_get_selection(struct v4l2_subdev *sd, case V4L2_SEL_TGT_COMPOSE_BOUNDS: fmt.pad = sel->pad; fmt.which = sel->which; - ret = vfe_get_format(sd, cfg, &fmt); + ret = vfe_get_format(sd, sd_state, &fmt); if (ret < 0) return ret; @@ -1141,7 +1143,7 @@ static int vfe_get_selection(struct v4l2_subdev *sd, sel->r.height = fmt.format.height; break; case V4L2_SEL_TGT_COMPOSE: - rect = __vfe_get_compose(line, cfg, sel->which); + rect = __vfe_get_compose(line, sd_state, sel->which); if (rect == NULL) return -EINVAL; @@ -1153,7 +1155,7 @@ static int vfe_get_selection(struct v4l2_subdev *sd, else if (sel->pad == MSM_VFE_PAD_SRC) switch (sel->target) { case V4L2_SEL_TGT_CROP_BOUNDS: - rect = __vfe_get_compose(line, cfg, sel->which); + rect = __vfe_get_compose(line, sd_state, sel->which); if (rect == NULL) return -EINVAL; @@ -1163,7 +1165,7 @@ static int vfe_get_selection(struct v4l2_subdev *sd, sel->r.height = rect->height; break; case V4L2_SEL_TGT_CROP: - rect = __vfe_get_crop(line, cfg, sel->which); + rect = __vfe_get_crop(line, sd_state, sel->which); if (rect == NULL) return -EINVAL; @@ -1185,7 +1187,7 @@ static int vfe_get_selection(struct v4l2_subdev *sd, * Return -EINVAL or zero on success */ static int vfe_set_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct vfe_line *line = v4l2_get_subdevdata(sd); @@ -1199,11 +1201,11 @@ static int vfe_set_selection(struct v4l2_subdev *sd, sel->pad == MSM_VFE_PAD_SINK) { struct v4l2_subdev_selection crop = { 0 }; - rect = __vfe_get_compose(line, cfg, sel->which); + rect = __vfe_get_compose(line, sd_state, sel->which); if (rect == NULL) return -EINVAL; - vfe_try_compose(line, cfg, &sel->r, sel->which); + vfe_try_compose(line, sd_state, &sel->r, sel->which); *rect = sel->r; /* Reset source crop selection */ @@ -1211,28 +1213,28 @@ static int vfe_set_selection(struct v4l2_subdev *sd, crop.pad = MSM_VFE_PAD_SRC; crop.target = V4L2_SEL_TGT_CROP; crop.r = *rect; - ret = vfe_set_selection(sd, cfg, &crop); + ret = vfe_set_selection(sd, sd_state, &crop); } else if (sel->target == V4L2_SEL_TGT_CROP && sel->pad == MSM_VFE_PAD_SRC) { struct v4l2_subdev_format fmt = { 0 }; - rect = __vfe_get_crop(line, cfg, sel->which); + rect = __vfe_get_crop(line, sd_state, sel->which); if (rect == NULL) return -EINVAL; - vfe_try_crop(line, cfg, &sel->r, sel->which); + vfe_try_crop(line, sd_state, &sel->r, sel->which); *rect = sel->r; /* Reset source pad format width and height */ fmt.which = sel->which; fmt.pad = MSM_VFE_PAD_SRC; - ret = vfe_get_format(sd, cfg, &fmt); + ret = vfe_get_format(sd, sd_state, &fmt); if (ret < 0) return ret; fmt.format.width = rect->width; fmt.format.height = rect->height; - ret = vfe_set_format(sd, cfg, &fmt); + ret = vfe_set_format(sd, sd_state, &fmt); } else { ret = -EINVAL; } @@ -1262,7 +1264,7 @@ static int vfe_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) } }; - return vfe_set_format(sd, fh ? fh->pad : NULL, &format); + return vfe_set_format(sd, fh ? fh->state : NULL, &format); } /* diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c b/drivers/media/platform/rcar-vin/rcar-csi2.c index b87d5453e418..a128bf80e42c 100644 --- a/drivers/media/platform/rcar-vin/rcar-csi2.c +++ b/drivers/media/platform/rcar-vin/rcar-csi2.c @@ -717,7 +717,7 @@ out: } static int rcsi2_set_pad_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct rcar_csi2 *priv = sd_to_csi2(sd); @@ -729,7 +729,7 @@ static int rcsi2_set_pad_format(struct v4l2_subdev *sd, if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) { priv->mf = format->format; } else { - framefmt = v4l2_subdev_get_try_format(sd, cfg, 0); + framefmt = v4l2_subdev_get_try_format(sd, sd_state, 0); *framefmt = format->format; } @@ -737,7 +737,7 @@ static int rcsi2_set_pad_format(struct v4l2_subdev *sd, } static int rcsi2_get_pad_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct rcar_csi2 *priv = sd_to_csi2(sd); @@ -745,7 +745,7 @@ static int rcsi2_get_pad_format(struct v4l2_subdev *sd, if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) format->format = priv->mf; else - format->format = *v4l2_subdev_get_try_format(sd, cfg, 0); + format->format = *v4l2_subdev_get_try_format(sd, sd_state, 0); return 0; } diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index b1e9f86caa5c..cca15a10c0b3 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -243,7 +243,7 @@ static int rvin_try_format(struct rvin_dev *vin, u32 which, struct v4l2_rect *src_rect) { struct v4l2_subdev *sd = vin_to_source(vin); - struct v4l2_subdev_pad_config *pad_cfg; + struct v4l2_subdev_state *sd_state; struct v4l2_subdev_format format = { .which = which, .pad = vin->parallel.source_pad, @@ -252,8 +252,8 @@ static int rvin_try_format(struct rvin_dev *vin, u32 which, u32 width, height; int ret; - pad_cfg = v4l2_subdev_alloc_pad_config(sd); - if (pad_cfg == NULL) + sd_state = v4l2_subdev_alloc_state(sd); + if (sd_state == NULL) return -ENOMEM; if (!rvin_format_from_pixel(vin, pix->pixelformat)) @@ -266,7 +266,7 @@ static int rvin_try_format(struct rvin_dev *vin, u32 which, width = pix->width; height = pix->height; - ret = v4l2_subdev_call(sd, pad, set_fmt, pad_cfg, &format); + ret = v4l2_subdev_call(sd, pad, set_fmt, sd_state, &format); if (ret < 0 && ret != -ENOIOCTLCMD) goto done; ret = 0; @@ -288,7 +288,7 @@ static int rvin_try_format(struct rvin_dev *vin, u32 which, rvin_format_align(vin, pix); done: - v4l2_subdev_free_pad_config(pad_cfg); + v4l2_subdev_free_state(sd_state); return ret; } diff --git a/drivers/media/platform/renesas-ceu.c b/drivers/media/platform/renesas-ceu.c index 17f01b6e3fe0..f432032c7084 100644 --- a/drivers/media/platform/renesas-ceu.c +++ b/drivers/media/platform/renesas-ceu.c @@ -794,6 +794,9 @@ static int __ceu_try_fmt(struct ceu_device *ceudev, struct v4l2_format *v4l2_fmt struct v4l2_pix_format_mplane *pix = &v4l2_fmt->fmt.pix_mp; struct v4l2_subdev *v4l2_sd = ceu_sd->v4l2_sd; struct v4l2_subdev_pad_config pad_cfg; + struct v4l2_subdev_state pad_state = { + .pads = &pad_cfg + }; const struct ceu_fmt *ceu_fmt; u32 mbus_code_old; u32 mbus_code; @@ -850,13 +853,13 @@ static int __ceu_try_fmt(struct ceu_device *ceudev, struct v4l2_format *v4l2_fmt * time. */ sd_format.format.code = mbus_code; - ret = v4l2_subdev_call(v4l2_sd, pad, set_fmt, &pad_cfg, &sd_format); + ret = v4l2_subdev_call(v4l2_sd, pad, set_fmt, &pad_state, &sd_format); if (ret) { if (ret == -EINVAL) { /* fallback */ sd_format.format.code = mbus_code_old; ret = v4l2_subdev_call(v4l2_sd, pad, set_fmt, - &pad_cfg, &sd_format); + &pad_state, &sd_format); } if (ret) diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c index 2e5b57e3aedc..d596bc040005 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c @@ -208,24 +208,30 @@ static struct v4l2_subdev *rkisp1_get_remote_sensor(struct v4l2_subdev *sd) static struct v4l2_mbus_framefmt * rkisp1_isp_get_pad_fmt(struct rkisp1_isp *isp, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad, u32 which) { + struct v4l2_subdev_state state = { + .pads = isp->pad_cfg + }; if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_format(&isp->sd, cfg, pad); + return v4l2_subdev_get_try_format(&isp->sd, sd_state, pad); else - return v4l2_subdev_get_try_format(&isp->sd, isp->pad_cfg, pad); + return v4l2_subdev_get_try_format(&isp->sd, &state, pad); } static struct v4l2_rect * rkisp1_isp_get_pad_crop(struct rkisp1_isp *isp, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad, u32 which) { + struct v4l2_subdev_state state = { + .pads = isp->pad_cfg + }; if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_crop(&isp->sd, cfg, pad); + return v4l2_subdev_get_try_crop(&isp->sd, sd_state, pad); else - return v4l2_subdev_get_try_crop(&isp->sd, isp->pad_cfg, pad); + return v4l2_subdev_get_try_crop(&isp->sd, &state, pad); } /* ---------------------------------------------------------------------------- @@ -561,7 +567,7 @@ static void rkisp1_isp_start(struct rkisp1_device *rkisp1) */ static int rkisp1_isp_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { unsigned int i, dir; @@ -601,7 +607,7 @@ static int rkisp1_isp_enum_mbus_code(struct v4l2_subdev *sd, } static int rkisp1_isp_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { const struct rkisp1_isp_mbus_info *mbus_info; @@ -634,37 +640,37 @@ static int rkisp1_isp_enum_frame_size(struct v4l2_subdev *sd, } static int rkisp1_isp_init_config(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg) + struct v4l2_subdev_state *sd_state) { struct v4l2_mbus_framefmt *sink_fmt, *src_fmt; struct v4l2_rect *sink_crop, *src_crop; - sink_fmt = v4l2_subdev_get_try_format(sd, cfg, + sink_fmt = v4l2_subdev_get_try_format(sd, sd_state, RKISP1_ISP_PAD_SINK_VIDEO); sink_fmt->width = RKISP1_DEFAULT_WIDTH; sink_fmt->height = RKISP1_DEFAULT_HEIGHT; sink_fmt->field = V4L2_FIELD_NONE; sink_fmt->code = RKISP1_DEF_SINK_PAD_FMT; - sink_crop = v4l2_subdev_get_try_crop(sd, cfg, + sink_crop = v4l2_subdev_get_try_crop(sd, sd_state, RKISP1_ISP_PAD_SINK_VIDEO); sink_crop->width = RKISP1_DEFAULT_WIDTH; sink_crop->height = RKISP1_DEFAULT_HEIGHT; sink_crop->left = 0; sink_crop->top = 0; - src_fmt = v4l2_subdev_get_try_format(sd, cfg, + src_fmt = v4l2_subdev_get_try_format(sd, sd_state, RKISP1_ISP_PAD_SOURCE_VIDEO); *src_fmt = *sink_fmt; src_fmt->code = RKISP1_DEF_SRC_PAD_FMT; - src_crop = v4l2_subdev_get_try_crop(sd, cfg, + src_crop = v4l2_subdev_get_try_crop(sd, sd_state, RKISP1_ISP_PAD_SOURCE_VIDEO); *src_crop = *sink_crop; - sink_fmt = v4l2_subdev_get_try_format(sd, cfg, + sink_fmt = v4l2_subdev_get_try_format(sd, sd_state, RKISP1_ISP_PAD_SINK_PARAMS); - src_fmt = v4l2_subdev_get_try_format(sd, cfg, + src_fmt = v4l2_subdev_get_try_format(sd, sd_state, RKISP1_ISP_PAD_SOURCE_STATS); sink_fmt->width = 0; sink_fmt->height = 0; @@ -676,7 +682,7 @@ static int rkisp1_isp_init_config(struct v4l2_subdev *sd, } static void rkisp1_isp_set_src_fmt(struct rkisp1_isp *isp, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_mbus_framefmt *format, unsigned int which) { @@ -684,9 +690,9 @@ static void rkisp1_isp_set_src_fmt(struct rkisp1_isp *isp, struct v4l2_mbus_framefmt *src_fmt; const struct v4l2_rect *src_crop; - src_fmt = rkisp1_isp_get_pad_fmt(isp, cfg, + src_fmt = rkisp1_isp_get_pad_fmt(isp, sd_state, RKISP1_ISP_PAD_SOURCE_VIDEO, which); - src_crop = rkisp1_isp_get_pad_crop(isp, cfg, + src_crop = rkisp1_isp_get_pad_crop(isp, sd_state, RKISP1_ISP_PAD_SOURCE_VIDEO, which); src_fmt->code = format->code; @@ -717,17 +723,17 @@ static void rkisp1_isp_set_src_fmt(struct rkisp1_isp *isp, } static void rkisp1_isp_set_src_crop(struct rkisp1_isp *isp, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_rect *r, unsigned int which) { struct v4l2_mbus_framefmt *src_fmt; const struct v4l2_rect *sink_crop; struct v4l2_rect *src_crop; - src_crop = rkisp1_isp_get_pad_crop(isp, cfg, + src_crop = rkisp1_isp_get_pad_crop(isp, sd_state, RKISP1_ISP_PAD_SOURCE_VIDEO, which); - sink_crop = rkisp1_isp_get_pad_crop(isp, cfg, + sink_crop = rkisp1_isp_get_pad_crop(isp, sd_state, RKISP1_ISP_PAD_SINK_VIDEO, which); @@ -740,21 +746,23 @@ static void rkisp1_isp_set_src_crop(struct rkisp1_isp *isp, *r = *src_crop; /* Propagate to out format */ - src_fmt = rkisp1_isp_get_pad_fmt(isp, cfg, + src_fmt = rkisp1_isp_get_pad_fmt(isp, sd_state, RKISP1_ISP_PAD_SOURCE_VIDEO, which); - rkisp1_isp_set_src_fmt(isp, cfg, src_fmt, which); + rkisp1_isp_set_src_fmt(isp, sd_state, src_fmt, which); } static void rkisp1_isp_set_sink_crop(struct rkisp1_isp *isp, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_rect *r, unsigned int which) { struct v4l2_rect *sink_crop, *src_crop; struct v4l2_mbus_framefmt *sink_fmt; - sink_crop = rkisp1_isp_get_pad_crop(isp, cfg, RKISP1_ISP_PAD_SINK_VIDEO, + sink_crop = rkisp1_isp_get_pad_crop(isp, sd_state, + RKISP1_ISP_PAD_SINK_VIDEO, which); - sink_fmt = rkisp1_isp_get_pad_fmt(isp, cfg, RKISP1_ISP_PAD_SINK_VIDEO, + sink_fmt = rkisp1_isp_get_pad_fmt(isp, sd_state, + RKISP1_ISP_PAD_SINK_VIDEO, which); sink_crop->left = ALIGN(r->left, 2); @@ -766,13 +774,13 @@ static void rkisp1_isp_set_sink_crop(struct rkisp1_isp *isp, *r = *sink_crop; /* Propagate to out crop */ - src_crop = rkisp1_isp_get_pad_crop(isp, cfg, + src_crop = rkisp1_isp_get_pad_crop(isp, sd_state, RKISP1_ISP_PAD_SOURCE_VIDEO, which); - rkisp1_isp_set_src_crop(isp, cfg, src_crop, which); + rkisp1_isp_set_src_crop(isp, sd_state, src_crop, which); } static void rkisp1_isp_set_sink_fmt(struct rkisp1_isp *isp, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_mbus_framefmt *format, unsigned int which) { @@ -780,7 +788,8 @@ static void rkisp1_isp_set_sink_fmt(struct rkisp1_isp *isp, struct v4l2_mbus_framefmt *sink_fmt; struct v4l2_rect *sink_crop; - sink_fmt = rkisp1_isp_get_pad_fmt(isp, cfg, RKISP1_ISP_PAD_SINK_VIDEO, + sink_fmt = rkisp1_isp_get_pad_fmt(isp, sd_state, + RKISP1_ISP_PAD_SINK_VIDEO, which); sink_fmt->code = format->code; mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code); @@ -801,36 +810,40 @@ static void rkisp1_isp_set_sink_fmt(struct rkisp1_isp *isp, *format = *sink_fmt; /* Propagate to in crop */ - sink_crop = rkisp1_isp_get_pad_crop(isp, cfg, RKISP1_ISP_PAD_SINK_VIDEO, + sink_crop = rkisp1_isp_get_pad_crop(isp, sd_state, + RKISP1_ISP_PAD_SINK_VIDEO, which); - rkisp1_isp_set_sink_crop(isp, cfg, sink_crop, which); + rkisp1_isp_set_sink_crop(isp, sd_state, sink_crop, which); } static int rkisp1_isp_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct rkisp1_isp *isp = container_of(sd, struct rkisp1_isp, sd); mutex_lock(&isp->ops_lock); - fmt->format = *rkisp1_isp_get_pad_fmt(isp, cfg, fmt->pad, fmt->which); + fmt->format = *rkisp1_isp_get_pad_fmt(isp, sd_state, fmt->pad, + fmt->which); mutex_unlock(&isp->ops_lock); return 0; } static int rkisp1_isp_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct rkisp1_isp *isp = container_of(sd, struct rkisp1_isp, sd); mutex_lock(&isp->ops_lock); if (fmt->pad == RKISP1_ISP_PAD_SINK_VIDEO) - rkisp1_isp_set_sink_fmt(isp, cfg, &fmt->format, fmt->which); + rkisp1_isp_set_sink_fmt(isp, sd_state, &fmt->format, + fmt->which); else if (fmt->pad == RKISP1_ISP_PAD_SOURCE_VIDEO) - rkisp1_isp_set_src_fmt(isp, cfg, &fmt->format, fmt->which); + rkisp1_isp_set_src_fmt(isp, sd_state, &fmt->format, + fmt->which); else - fmt->format = *rkisp1_isp_get_pad_fmt(isp, cfg, fmt->pad, + fmt->format = *rkisp1_isp_get_pad_fmt(isp, sd_state, fmt->pad, fmt->which); mutex_unlock(&isp->ops_lock); @@ -838,7 +851,7 @@ static int rkisp1_isp_set_fmt(struct v4l2_subdev *sd, } static int rkisp1_isp_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct rkisp1_isp *isp = container_of(sd, struct rkisp1_isp, sd); @@ -854,20 +867,20 @@ static int rkisp1_isp_get_selection(struct v4l2_subdev *sd, if (sel->pad == RKISP1_ISP_PAD_SINK_VIDEO) { struct v4l2_mbus_framefmt *fmt; - fmt = rkisp1_isp_get_pad_fmt(isp, cfg, sel->pad, + fmt = rkisp1_isp_get_pad_fmt(isp, sd_state, sel->pad, sel->which); sel->r.height = fmt->height; sel->r.width = fmt->width; sel->r.left = 0; sel->r.top = 0; } else { - sel->r = *rkisp1_isp_get_pad_crop(isp, cfg, - RKISP1_ISP_PAD_SINK_VIDEO, - sel->which); + sel->r = *rkisp1_isp_get_pad_crop(isp, sd_state, + RKISP1_ISP_PAD_SINK_VIDEO, + sel->which); } break; case V4L2_SEL_TGT_CROP: - sel->r = *rkisp1_isp_get_pad_crop(isp, cfg, sel->pad, + sel->r = *rkisp1_isp_get_pad_crop(isp, sd_state, sel->pad, sel->which); break; default: @@ -878,7 +891,7 @@ static int rkisp1_isp_get_selection(struct v4l2_subdev *sd, } static int rkisp1_isp_set_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct rkisp1_device *rkisp1 = @@ -893,9 +906,9 @@ static int rkisp1_isp_set_selection(struct v4l2_subdev *sd, sel->pad, sel->r.left, sel->r.top, sel->r.width, sel->r.height); mutex_lock(&isp->ops_lock); if (sel->pad == RKISP1_ISP_PAD_SINK_VIDEO) - rkisp1_isp_set_sink_crop(isp, cfg, &sel->r, sel->which); + rkisp1_isp_set_sink_crop(isp, sd_state, &sel->r, sel->which); else if (sel->pad == RKISP1_ISP_PAD_SOURCE_VIDEO) - rkisp1_isp_set_src_crop(isp, cfg, &sel->r, sel->which); + rkisp1_isp_set_src_crop(isp, sd_state, &sel->r, sel->which); else ret = -EINVAL; @@ -1037,6 +1050,9 @@ static const struct v4l2_subdev_ops rkisp1_isp_ops = { int rkisp1_isp_register(struct rkisp1_device *rkisp1) { + struct v4l2_subdev_state state = { + .pads = rkisp1->isp.pad_cfg + }; struct rkisp1_isp *isp = &rkisp1->isp; struct media_pad *pads = isp->pads; struct v4l2_subdev *sd = &isp->sd; @@ -1069,7 +1085,7 @@ int rkisp1_isp_register(struct rkisp1_device *rkisp1) goto err_cleanup_media_entity; } - rkisp1_isp_init_config(sd, rkisp1->isp.pad_cfg); + rkisp1_isp_init_config(sd, &state); return 0; err_cleanup_media_entity: diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c index 79deed8adcea..2070f4b06705 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c @@ -180,24 +180,30 @@ static const struct rkisp1_rsz_config rkisp1_rsz_config_sp = { static struct v4l2_mbus_framefmt * rkisp1_rsz_get_pad_fmt(struct rkisp1_resizer *rsz, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad, u32 which) { + struct v4l2_subdev_state state = { + .pads = rsz->pad_cfg + }; if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_format(&rsz->sd, cfg, pad); + return v4l2_subdev_get_try_format(&rsz->sd, sd_state, pad); else - return v4l2_subdev_get_try_format(&rsz->sd, rsz->pad_cfg, pad); + return v4l2_subdev_get_try_format(&rsz->sd, &state, pad); } static struct v4l2_rect * rkisp1_rsz_get_pad_crop(struct rkisp1_resizer *rsz, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad, u32 which) { + struct v4l2_subdev_state state = { + .pads = rsz->pad_cfg + }; if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_crop(&rsz->sd, cfg, pad); + return v4l2_subdev_get_try_crop(&rsz->sd, sd_state, pad); else - return v4l2_subdev_get_try_crop(&rsz->sd, rsz->pad_cfg, pad); + return v4l2_subdev_get_try_crop(&rsz->sd, &state, pad); } /* ---------------------------------------------------------------------------- @@ -451,12 +457,15 @@ static void rkisp1_rsz_config(struct rkisp1_resizer *rsz, */ static int rkisp1_rsz_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct rkisp1_resizer *rsz = container_of(sd, struct rkisp1_resizer, sd); struct v4l2_subdev_pad_config dummy_cfg; + struct v4l2_subdev_state pad_state = { + .pads = &dummy_cfg + }; u32 pad = code->pad; int ret; @@ -481,7 +490,7 @@ static int rkisp1_rsz_enum_mbus_code(struct v4l2_subdev *sd, /* supported mbus codes on the sink pad are the same as isp src pad */ code->pad = RKISP1_ISP_PAD_SOURCE_VIDEO; ret = v4l2_subdev_call(&rsz->rkisp1->isp.sd, pad, enum_mbus_code, - &dummy_cfg, code); + &pad_state, code); /* restore pad */ code->pad = pad; @@ -490,24 +499,27 @@ static int rkisp1_rsz_enum_mbus_code(struct v4l2_subdev *sd, } static int rkisp1_rsz_init_config(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg) + struct v4l2_subdev_state *sd_state) { struct v4l2_mbus_framefmt *sink_fmt, *src_fmt; struct v4l2_rect *sink_crop; - sink_fmt = v4l2_subdev_get_try_format(sd, cfg, RKISP1_RSZ_PAD_SRC); + sink_fmt = v4l2_subdev_get_try_format(sd, sd_state, + RKISP1_RSZ_PAD_SRC); sink_fmt->width = RKISP1_DEFAULT_WIDTH; sink_fmt->height = RKISP1_DEFAULT_HEIGHT; sink_fmt->field = V4L2_FIELD_NONE; sink_fmt->code = RKISP1_DEF_FMT; - sink_crop = v4l2_subdev_get_try_crop(sd, cfg, RKISP1_RSZ_PAD_SINK); + sink_crop = v4l2_subdev_get_try_crop(sd, sd_state, + RKISP1_RSZ_PAD_SINK); sink_crop->width = RKISP1_DEFAULT_WIDTH; sink_crop->height = RKISP1_DEFAULT_HEIGHT; sink_crop->left = 0; sink_crop->top = 0; - src_fmt = v4l2_subdev_get_try_format(sd, cfg, RKISP1_RSZ_PAD_SINK); + src_fmt = v4l2_subdev_get_try_format(sd, sd_state, + RKISP1_RSZ_PAD_SINK); *src_fmt = *sink_fmt; /* NOTE: there is no crop in the source pad, only in the sink */ @@ -516,15 +528,17 @@ static int rkisp1_rsz_init_config(struct v4l2_subdev *sd, } static void rkisp1_rsz_set_src_fmt(struct rkisp1_resizer *rsz, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_mbus_framefmt *format, unsigned int which) { const struct rkisp1_isp_mbus_info *sink_mbus_info; struct v4l2_mbus_framefmt *src_fmt, *sink_fmt; - sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SINK, which); - src_fmt = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SRC, which); + sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, sd_state, RKISP1_RSZ_PAD_SINK, + which); + src_fmt = rkisp1_rsz_get_pad_fmt(rsz, sd_state, RKISP1_RSZ_PAD_SRC, + which); sink_mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code); /* for YUV formats, userspace can change the mbus code on the src pad if it is supported */ @@ -543,7 +557,7 @@ static void rkisp1_rsz_set_src_fmt(struct rkisp1_resizer *rsz, } static void rkisp1_rsz_set_sink_crop(struct rkisp1_resizer *rsz, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_rect *r, unsigned int which) { @@ -551,8 +565,10 @@ static void rkisp1_rsz_set_sink_crop(struct rkisp1_resizer *rsz, struct v4l2_mbus_framefmt *sink_fmt; struct v4l2_rect *sink_crop; - sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SINK, which); - sink_crop = rkisp1_rsz_get_pad_crop(rsz, cfg, RKISP1_RSZ_PAD_SINK, + sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, sd_state, RKISP1_RSZ_PAD_SINK, + which); + sink_crop = rkisp1_rsz_get_pad_crop(rsz, sd_state, + RKISP1_RSZ_PAD_SINK, which); /* Not crop for MP bayer raw data */ @@ -579,7 +595,7 @@ static void rkisp1_rsz_set_sink_crop(struct rkisp1_resizer *rsz, } static void rkisp1_rsz_set_sink_fmt(struct rkisp1_resizer *rsz, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_mbus_framefmt *format, unsigned int which) { @@ -587,9 +603,12 @@ static void rkisp1_rsz_set_sink_fmt(struct rkisp1_resizer *rsz, struct v4l2_mbus_framefmt *sink_fmt, *src_fmt; struct v4l2_rect *sink_crop; - sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SINK, which); - src_fmt = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SRC, which); - sink_crop = rkisp1_rsz_get_pad_crop(rsz, cfg, RKISP1_RSZ_PAD_SINK, + sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, sd_state, RKISP1_RSZ_PAD_SINK, + which); + src_fmt = rkisp1_rsz_get_pad_fmt(rsz, sd_state, RKISP1_RSZ_PAD_SRC, + which); + sink_crop = rkisp1_rsz_get_pad_crop(rsz, sd_state, + RKISP1_RSZ_PAD_SINK, which); if (rsz->id == RKISP1_SELFPATH) sink_fmt->code = MEDIA_BUS_FMT_YUYV8_2X8; @@ -617,24 +636,25 @@ static void rkisp1_rsz_set_sink_fmt(struct rkisp1_resizer *rsz, *format = *sink_fmt; /* Update sink crop */ - rkisp1_rsz_set_sink_crop(rsz, cfg, sink_crop, which); + rkisp1_rsz_set_sink_crop(rsz, sd_state, sink_crop, which); } static int rkisp1_rsz_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct rkisp1_resizer *rsz = container_of(sd, struct rkisp1_resizer, sd); mutex_lock(&rsz->ops_lock); - fmt->format = *rkisp1_rsz_get_pad_fmt(rsz, cfg, fmt->pad, fmt->which); + fmt->format = *rkisp1_rsz_get_pad_fmt(rsz, sd_state, fmt->pad, + fmt->which); mutex_unlock(&rsz->ops_lock); return 0; } static int rkisp1_rsz_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct rkisp1_resizer *rsz = @@ -642,16 +662,18 @@ static int rkisp1_rsz_set_fmt(struct v4l2_subdev *sd, mutex_lock(&rsz->ops_lock); if (fmt->pad == RKISP1_RSZ_PAD_SINK) - rkisp1_rsz_set_sink_fmt(rsz, cfg, &fmt->format, fmt->which); + rkisp1_rsz_set_sink_fmt(rsz, sd_state, &fmt->format, + fmt->which); else - rkisp1_rsz_set_src_fmt(rsz, cfg, &fmt->format, fmt->which); + rkisp1_rsz_set_src_fmt(rsz, sd_state, &fmt->format, + fmt->which); mutex_unlock(&rsz->ops_lock); return 0; } static int rkisp1_rsz_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct rkisp1_resizer *rsz = @@ -665,7 +687,8 @@ static int rkisp1_rsz_get_selection(struct v4l2_subdev *sd, mutex_lock(&rsz->ops_lock); switch (sel->target) { case V4L2_SEL_TGT_CROP_BOUNDS: - mf_sink = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SINK, + mf_sink = rkisp1_rsz_get_pad_fmt(rsz, sd_state, + RKISP1_RSZ_PAD_SINK, sel->which); sel->r.height = mf_sink->height; sel->r.width = mf_sink->width; @@ -673,7 +696,8 @@ static int rkisp1_rsz_get_selection(struct v4l2_subdev *sd, sel->r.top = 0; break; case V4L2_SEL_TGT_CROP: - sel->r = *rkisp1_rsz_get_pad_crop(rsz, cfg, RKISP1_RSZ_PAD_SINK, + sel->r = *rkisp1_rsz_get_pad_crop(rsz, sd_state, + RKISP1_RSZ_PAD_SINK, sel->which); break; default: @@ -685,7 +709,7 @@ static int rkisp1_rsz_get_selection(struct v4l2_subdev *sd, } static int rkisp1_rsz_set_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct rkisp1_resizer *rsz = @@ -698,7 +722,7 @@ static int rkisp1_rsz_set_selection(struct v4l2_subdev *sd, sel->pad, sel->r.left, sel->r.top, sel->r.width, sel->r.height); mutex_lock(&rsz->ops_lock); - rkisp1_rsz_set_sink_crop(rsz, cfg, &sel->r, sel->which); + rkisp1_rsz_set_sink_crop(rsz, sd_state, &sel->r, sel->which); mutex_unlock(&rsz->ops_lock); return 0; @@ -764,6 +788,9 @@ static void rkisp1_rsz_unregister(struct rkisp1_resizer *rsz) static int rkisp1_rsz_register(struct rkisp1_resizer *rsz) { + struct v4l2_subdev_state state = { + .pads = rsz->pad_cfg + }; static const char * const dev_names[] = { RKISP1_RSZ_MP_DEV_NAME, RKISP1_RSZ_SP_DEV_NAME @@ -802,7 +829,7 @@ static int rkisp1_rsz_register(struct rkisp1_resizer *rsz) goto err_cleanup_media_entity; } - rkisp1_rsz_init_config(sd, rsz->pad_cfg); + rkisp1_rsz_init_config(sd, &state); return 0; err_cleanup_media_entity: diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c index 62241ec3b978..140854ab4dd8 100644 --- a/drivers/media/platform/s3c-camif/camif-capture.c +++ b/drivers/media/platform/s3c-camif/camif-capture.c @@ -1199,7 +1199,7 @@ static const u32 camif_mbus_formats[] = { */ static int s3c_camif_subdev_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->index >= ARRAY_SIZE(camif_mbus_formats)) @@ -1210,14 +1210,14 @@ static int s3c_camif_subdev_enum_mbus_code(struct v4l2_subdev *sd, } static int s3c_camif_subdev_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct camif_dev *camif = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *mf = &fmt->format; if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + mf = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); fmt->format = *mf; return 0; } @@ -1278,7 +1278,7 @@ static void __camif_subdev_try_format(struct camif_dev *camif, } static int s3c_camif_subdev_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct camif_dev *camif = v4l2_get_subdevdata(sd); @@ -1306,7 +1306,7 @@ static int s3c_camif_subdev_set_fmt(struct v4l2_subdev *sd, __camif_subdev_try_format(camif, mf, fmt->pad); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + mf = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); *mf = fmt->format; mutex_unlock(&camif->lock); return 0; @@ -1345,7 +1345,7 @@ static int s3c_camif_subdev_set_fmt(struct v4l2_subdev *sd, } static int s3c_camif_subdev_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct camif_dev *camif = v4l2_get_subdevdata(sd); @@ -1358,7 +1358,7 @@ static int s3c_camif_subdev_get_selection(struct v4l2_subdev *sd, return -EINVAL; if (sel->which == V4L2_SUBDEV_FORMAT_TRY) { - sel->r = *v4l2_subdev_get_try_crop(sd, cfg, sel->pad); + sel->r = *v4l2_subdev_get_try_crop(sd, sd_state, sel->pad); return 0; } @@ -1432,7 +1432,7 @@ static void __camif_try_crop(struct camif_dev *camif, struct v4l2_rect *r) } static int s3c_camif_subdev_set_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct camif_dev *camif = v4l2_get_subdevdata(sd); @@ -1446,7 +1446,7 @@ static int s3c_camif_subdev_set_selection(struct v4l2_subdev *sd, __camif_try_crop(camif, &sel->r); if (sel->which == V4L2_SUBDEV_FORMAT_TRY) { - *v4l2_subdev_get_try_crop(sd, cfg, sel->pad) = sel->r; + *v4l2_subdev_get_try_crop(sd, sd_state, sel->pad) = sel->r; } else { unsigned long flags; unsigned int i; diff --git a/drivers/media/platform/stm32/stm32-dcmi.c b/drivers/media/platform/stm32/stm32-dcmi.c index b33c6e7ae0a1..d914ccef9831 100644 --- a/drivers/media/platform/stm32/stm32-dcmi.c +++ b/drivers/media/platform/stm32/stm32-dcmi.c @@ -600,7 +600,7 @@ static struct media_entity *dcmi_find_source(struct stm32_dcmi *dcmi) } static int dcmi_pipeline_s_fmt(struct stm32_dcmi *dcmi, - struct v4l2_subdev_pad_config *pad_cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct media_entity *entity = &dcmi->source->entity; @@ -642,7 +642,7 @@ static int dcmi_pipeline_s_fmt(struct stm32_dcmi *dcmi, format->format.width, format->format.height); fmt.pad = pad->index; - ret = v4l2_subdev_call(subdev, pad, set_fmt, pad_cfg, &fmt); + ret = v4l2_subdev_call(subdev, pad, set_fmt, sd_state, &fmt); if (ret < 0) { dev_err(dcmi->dev, "%s: Failed to set format 0x%x %ux%u on \"%s\":%d pad (%d)\n", __func__, format->format.code, @@ -978,6 +978,9 @@ static int dcmi_try_fmt(struct stm32_dcmi *dcmi, struct v4l2_format *f, struct dcmi_framesize sd_fsize; struct v4l2_pix_format *pix = &f->fmt.pix; struct v4l2_subdev_pad_config pad_cfg; + struct v4l2_subdev_state pad_state = { + .pads = &pad_cfg + }; struct v4l2_subdev_format format = { .which = V4L2_SUBDEV_FORMAT_TRY, }; @@ -1013,7 +1016,7 @@ static int dcmi_try_fmt(struct stm32_dcmi *dcmi, struct v4l2_format *f, v4l2_fill_mbus_format(&format.format, pix, sd_fmt->mbus_code); ret = v4l2_subdev_call(dcmi->source, pad, set_fmt, - &pad_cfg, &format); + &pad_state, &format); if (ret < 0) return ret; @@ -1163,6 +1166,9 @@ static int dcmi_set_sensor_format(struct stm32_dcmi *dcmi, .which = V4L2_SUBDEV_FORMAT_TRY, }; struct v4l2_subdev_pad_config pad_cfg; + struct v4l2_subdev_state pad_state = { + .pads = &pad_cfg + }; int ret; sd_fmt = find_format_by_fourcc(dcmi, pix->pixelformat); @@ -1176,7 +1182,7 @@ static int dcmi_set_sensor_format(struct stm32_dcmi *dcmi, v4l2_fill_mbus_format(&format.format, pix, sd_fmt->mbus_code); ret = v4l2_subdev_call(dcmi->source, pad, set_fmt, - &pad_cfg, &format); + &pad_state, &format); if (ret < 0) return ret; diff --git a/drivers/media/platform/sunxi/sun4i-csi/sun4i_v4l2.c b/drivers/media/platform/sunxi/sun4i-csi/sun4i_v4l2.c index 54b909987caa..3872027ed2fa 100644 --- a/drivers/media/platform/sunxi/sun4i-csi/sun4i_v4l2.c +++ b/drivers/media/platform/sunxi/sun4i-csi/sun4i_v4l2.c @@ -271,25 +271,26 @@ static const struct v4l2_mbus_framefmt sun4i_csi_pad_fmt_default = { }; static int sun4i_csi_subdev_init_cfg(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg) + struct v4l2_subdev_state *sd_state) { struct v4l2_mbus_framefmt *fmt; - fmt = v4l2_subdev_get_try_format(subdev, cfg, CSI_SUBDEV_SINK); + fmt = v4l2_subdev_get_try_format(subdev, sd_state, CSI_SUBDEV_SINK); *fmt = sun4i_csi_pad_fmt_default; return 0; } static int sun4i_csi_subdev_get_fmt(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct sun4i_csi *csi = container_of(subdev, struct sun4i_csi, subdev); struct v4l2_mbus_framefmt *subdev_fmt; if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) - subdev_fmt = v4l2_subdev_get_try_format(subdev, cfg, fmt->pad); + subdev_fmt = v4l2_subdev_get_try_format(subdev, sd_state, + fmt->pad); else subdev_fmt = &csi->subdev_fmt; @@ -299,14 +300,15 @@ static int sun4i_csi_subdev_get_fmt(struct v4l2_subdev *subdev, } static int sun4i_csi_subdev_set_fmt(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct sun4i_csi *csi = container_of(subdev, struct sun4i_csi, subdev); struct v4l2_mbus_framefmt *subdev_fmt; if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) - subdev_fmt = v4l2_subdev_get_try_format(subdev, cfg, fmt->pad); + subdev_fmt = v4l2_subdev_get_try_format(subdev, sd_state, + fmt->pad); else subdev_fmt = &csi->subdev_fmt; @@ -325,7 +327,7 @@ static int sun4i_csi_subdev_set_fmt(struct v4l2_subdev *subdev, static int sun4i_csi_subdev_enum_mbus_code(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *mbus) { if (mbus->index >= ARRAY_SIZE(sun4i_csi_formats)) diff --git a/drivers/media/platform/ti-vpe/cal-camerarx.c b/drivers/media/platform/ti-vpe/cal-camerarx.c index cbe6114908de..124a4e2bdefe 100644 --- a/drivers/media/platform/ti-vpe/cal-camerarx.c +++ b/drivers/media/platform/ti-vpe/cal-camerarx.c @@ -586,12 +586,12 @@ static inline struct cal_camerarx *to_cal_camerarx(struct v4l2_subdev *sd) static struct v4l2_mbus_framefmt * cal_camerarx_get_pad_format(struct cal_camerarx *phy, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad, u32 which) { switch (which) { case V4L2_SUBDEV_FORMAT_TRY: - return v4l2_subdev_get_try_format(&phy->subdev, cfg, pad); + return v4l2_subdev_get_try_format(&phy->subdev, sd_state, pad); case V4L2_SUBDEV_FORMAT_ACTIVE: return &phy->formats[pad]; default: @@ -611,7 +611,7 @@ static int cal_camerarx_sd_s_stream(struct v4l2_subdev *sd, int enable) } static int cal_camerarx_sd_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct cal_camerarx *phy = to_cal_camerarx(sd); @@ -623,7 +623,7 @@ static int cal_camerarx_sd_enum_mbus_code(struct v4l2_subdev *sd, if (code->index > 0) return -EINVAL; - fmt = cal_camerarx_get_pad_format(phy, cfg, + fmt = cal_camerarx_get_pad_format(phy, sd_state, CAL_CAMERARX_PAD_SINK, code->which); code->code = fmt->code; @@ -639,7 +639,7 @@ static int cal_camerarx_sd_enum_mbus_code(struct v4l2_subdev *sd, } static int cal_camerarx_sd_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { struct cal_camerarx *phy = to_cal_camerarx(sd); @@ -652,7 +652,7 @@ static int cal_camerarx_sd_enum_frame_size(struct v4l2_subdev *sd, if (fse->pad == CAL_CAMERARX_PAD_SOURCE) { struct v4l2_mbus_framefmt *fmt; - fmt = cal_camerarx_get_pad_format(phy, cfg, + fmt = cal_camerarx_get_pad_format(phy, sd_state, CAL_CAMERARX_PAD_SINK, fse->which); if (fse->code != fmt->code) @@ -679,20 +679,21 @@ static int cal_camerarx_sd_enum_frame_size(struct v4l2_subdev *sd, } static int cal_camerarx_sd_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct cal_camerarx *phy = to_cal_camerarx(sd); struct v4l2_mbus_framefmt *fmt; - fmt = cal_camerarx_get_pad_format(phy, cfg, format->pad, format->which); + fmt = cal_camerarx_get_pad_format(phy, sd_state, format->pad, + format->which); format->format = *fmt; return 0; } static int cal_camerarx_sd_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct cal_camerarx *phy = to_cal_camerarx(sd); @@ -702,7 +703,7 @@ static int cal_camerarx_sd_set_fmt(struct v4l2_subdev *sd, /* No transcoding, source and sink formats must match. */ if (format->pad == CAL_CAMERARX_PAD_SOURCE) - return cal_camerarx_sd_get_fmt(sd, cfg, format); + return cal_camerarx_sd_get_fmt(sd, sd_state, format); /* * Default to the first format is the requested media bus code isn't @@ -727,11 +728,13 @@ static int cal_camerarx_sd_set_fmt(struct v4l2_subdev *sd, format->format.code = fmtinfo->code; /* Store the format and propagate it to the source pad. */ - fmt = cal_camerarx_get_pad_format(phy, cfg, CAL_CAMERARX_PAD_SINK, + fmt = cal_camerarx_get_pad_format(phy, sd_state, + CAL_CAMERARX_PAD_SINK, format->which); *fmt = format->format; - fmt = cal_camerarx_get_pad_format(phy, cfg, CAL_CAMERARX_PAD_SOURCE, + fmt = cal_camerarx_get_pad_format(phy, sd_state, + CAL_CAMERARX_PAD_SOURCE, format->which); *fmt = format->format; @@ -742,11 +745,11 @@ static int cal_camerarx_sd_set_fmt(struct v4l2_subdev *sd, } static int cal_camerarx_sd_init_cfg(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg) + struct v4l2_subdev_state *sd_state) { struct v4l2_subdev_format format = { - .which = cfg ? V4L2_SUBDEV_FORMAT_TRY - : V4L2_SUBDEV_FORMAT_ACTIVE, + .which = sd_state ? V4L2_SUBDEV_FORMAT_TRY + : V4L2_SUBDEV_FORMAT_ACTIVE, .pad = CAL_CAMERARX_PAD_SINK, .format = { .width = 640, @@ -760,7 +763,7 @@ static int cal_camerarx_sd_init_cfg(struct v4l2_subdev *sd, }, }; - return cal_camerarx_sd_set_fmt(sd, cfg, &format); + return cal_camerarx_sd_set_fmt(sd, sd_state, &format); } static const struct v4l2_subdev_video_ops cal_camerarx_video_ops = { diff --git a/drivers/media/platform/via-camera.c b/drivers/media/platform/via-camera.c index ed0ad68c5c48..3655573e8581 100644 --- a/drivers/media/platform/via-camera.c +++ b/drivers/media/platform/via-camera.c @@ -844,6 +844,9 @@ static int viacam_do_try_fmt(struct via_camera *cam, { int ret; struct v4l2_subdev_pad_config pad_cfg; + struct v4l2_subdev_state pad_state = { + .pads = &pad_cfg + }; struct v4l2_subdev_format format = { .which = V4L2_SUBDEV_FORMAT_TRY, }; @@ -852,7 +855,7 @@ static int viacam_do_try_fmt(struct via_camera *cam, upix->pixelformat = f->pixelformat; viacam_fmt_pre(upix, spix); v4l2_fill_mbus_format(&format.format, spix, f->mbus_code); - ret = sensor_call(cam, pad, set_fmt, &pad_cfg, &format); + ret = sensor_call(cam, pad, set_fmt, &pad_state, &format); v4l2_fill_pix_format(spix, &format.format); viacam_fmt_post(upix, spix); return ret; diff --git a/drivers/media/platform/video-mux.c b/drivers/media/platform/video-mux.c index 133122e38515..f7e2a5e48ccf 100644 --- a/drivers/media/platform/video-mux.c +++ b/drivers/media/platform/video-mux.c @@ -140,14 +140,14 @@ static const struct v4l2_subdev_video_ops video_mux_subdev_video_ops = { static struct v4l2_mbus_framefmt * __video_mux_get_pad_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad, u32 which) { struct video_mux *vmux = v4l2_subdev_to_video_mux(sd); switch (which) { case V4L2_SUBDEV_FORMAT_TRY: - return v4l2_subdev_get_try_format(sd, cfg, pad); + return v4l2_subdev_get_try_format(sd, sd_state, pad); case V4L2_SUBDEV_FORMAT_ACTIVE: return &vmux->format_mbus[pad]; default: @@ -156,14 +156,15 @@ __video_mux_get_pad_format(struct v4l2_subdev *sd, } static int video_mux_get_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *sdformat) { struct video_mux *vmux = v4l2_subdev_to_video_mux(sd); mutex_lock(&vmux->lock); - sdformat->format = *__video_mux_get_pad_format(sd, cfg, sdformat->pad, + sdformat->format = *__video_mux_get_pad_format(sd, sd_state, + sdformat->pad, sdformat->which); mutex_unlock(&vmux->lock); @@ -172,7 +173,7 @@ static int video_mux_get_format(struct v4l2_subdev *sd, } static int video_mux_set_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *sdformat) { struct video_mux *vmux = v4l2_subdev_to_video_mux(sd); @@ -180,12 +181,13 @@ static int video_mux_set_format(struct v4l2_subdev *sd, struct media_pad *pad = &vmux->pads[sdformat->pad]; u16 source_pad = sd->entity.num_pads - 1; - mbusformat = __video_mux_get_pad_format(sd, cfg, sdformat->pad, - sdformat->which); + mbusformat = __video_mux_get_pad_format(sd, sd_state, sdformat->pad, + sdformat->which); if (!mbusformat) return -EINVAL; - source_mbusformat = __video_mux_get_pad_format(sd, cfg, source_pad, + source_mbusformat = __video_mux_get_pad_format(sd, sd_state, + source_pad, sdformat->which); if (!source_mbusformat) return -EINVAL; @@ -310,7 +312,7 @@ static int video_mux_set_format(struct v4l2_subdev *sd, } static int video_mux_init_cfg(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg) + struct v4l2_subdev_state *sd_state) { struct video_mux *vmux = v4l2_subdev_to_video_mux(sd); struct v4l2_mbus_framefmt *mbusformat; @@ -319,7 +321,7 @@ static int video_mux_init_cfg(struct v4l2_subdev *sd, mutex_lock(&vmux->lock); for (i = 0; i < sd->entity.num_pads; i++) { - mbusformat = v4l2_subdev_get_try_format(sd, cfg, i); + mbusformat = v4l2_subdev_get_try_format(sd, sd_state, i); *mbusformat = video_mux_format_mbus_default; } diff --git a/drivers/media/platform/vsp1/vsp1_brx.c b/drivers/media/platform/vsp1/vsp1_brx.c index 2d86c718a5cf..89385b4cabe5 100644 --- a/drivers/media/platform/vsp1/vsp1_brx.c +++ b/drivers/media/platform/vsp1/vsp1_brx.c @@ -65,7 +65,7 @@ static const struct v4l2_ctrl_ops brx_ctrl_ops = { */ static int brx_enum_mbus_code(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { static const unsigned int codes[] = { @@ -73,12 +73,12 @@ static int brx_enum_mbus_code(struct v4l2_subdev *subdev, MEDIA_BUS_FMT_AYUV8_1X32, }; - return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes, + return vsp1_subdev_enum_mbus_code(subdev, sd_state, code, codes, ARRAY_SIZE(codes)); } static int brx_enum_frame_size(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { if (fse->index) @@ -97,14 +97,14 @@ static int brx_enum_frame_size(struct v4l2_subdev *subdev, } static struct v4l2_rect *brx_get_compose(struct vsp1_brx *brx, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad) { - return v4l2_subdev_get_try_compose(&brx->entity.subdev, cfg, pad); + return v4l2_subdev_get_try_compose(&brx->entity.subdev, sd_state, pad); } static void brx_try_format(struct vsp1_brx *brx, - struct v4l2_subdev_pad_config *config, + struct v4l2_subdev_state *sd_state, unsigned int pad, struct v4l2_mbus_framefmt *fmt) { struct v4l2_mbus_framefmt *format; @@ -119,7 +119,7 @@ static void brx_try_format(struct vsp1_brx *brx, default: /* The BRx can't perform format conversion. */ - format = vsp1_entity_get_pad_format(&brx->entity, config, + format = vsp1_entity_get_pad_format(&brx->entity, sd_state, BRX_PAD_SINK(0)); fmt->code = format->code; break; @@ -132,17 +132,18 @@ static void brx_try_format(struct vsp1_brx *brx, } static int brx_set_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct vsp1_brx *brx = to_brx(subdev); - struct v4l2_subdev_pad_config *config; + struct v4l2_subdev_state *config; struct v4l2_mbus_framefmt *format; int ret = 0; mutex_lock(&brx->entity.lock); - config = vsp1_entity_get_pad_config(&brx->entity, cfg, fmt->which); + config = vsp1_entity_get_pad_config(&brx->entity, sd_state, + fmt->which); if (!config) { ret = -EINVAL; goto done; @@ -181,11 +182,11 @@ done: } static int brx_get_selection(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct vsp1_brx *brx = to_brx(subdev); - struct v4l2_subdev_pad_config *config; + struct v4l2_subdev_state *config; if (sel->pad == brx->entity.source_pad) return -EINVAL; @@ -199,7 +200,7 @@ static int brx_get_selection(struct v4l2_subdev *subdev, return 0; case V4L2_SEL_TGT_COMPOSE: - config = vsp1_entity_get_pad_config(&brx->entity, cfg, + config = vsp1_entity_get_pad_config(&brx->entity, sd_state, sel->which); if (!config) return -EINVAL; @@ -215,11 +216,11 @@ static int brx_get_selection(struct v4l2_subdev *subdev, } static int brx_set_selection(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct vsp1_brx *brx = to_brx(subdev); - struct v4l2_subdev_pad_config *config; + struct v4l2_subdev_state *config; struct v4l2_mbus_framefmt *format; struct v4l2_rect *compose; int ret = 0; @@ -232,7 +233,8 @@ static int brx_set_selection(struct v4l2_subdev *subdev, mutex_lock(&brx->entity.lock); - config = vsp1_entity_get_pad_config(&brx->entity, cfg, sel->which); + config = vsp1_entity_get_pad_config(&brx->entity, sd_state, + sel->which); if (!config) { ret = -EINVAL; goto done; diff --git a/drivers/media/platform/vsp1/vsp1_clu.c b/drivers/media/platform/vsp1/vsp1_clu.c index a47b23bf5abf..c5217fee24f1 100644 --- a/drivers/media/platform/vsp1/vsp1_clu.c +++ b/drivers/media/platform/vsp1/vsp1_clu.c @@ -123,27 +123,28 @@ static const unsigned int clu_codes[] = { }; static int clu_enum_mbus_code(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { - return vsp1_subdev_enum_mbus_code(subdev, cfg, code, clu_codes, + return vsp1_subdev_enum_mbus_code(subdev, sd_state, code, clu_codes, ARRAY_SIZE(clu_codes)); } static int clu_enum_frame_size(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { - return vsp1_subdev_enum_frame_size(subdev, cfg, fse, CLU_MIN_SIZE, + return vsp1_subdev_enum_frame_size(subdev, sd_state, fse, + CLU_MIN_SIZE, CLU_MIN_SIZE, CLU_MAX_SIZE, CLU_MAX_SIZE); } static int clu_set_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { - return vsp1_subdev_set_pad_format(subdev, cfg, fmt, clu_codes, + return vsp1_subdev_set_pad_format(subdev, sd_state, fmt, clu_codes, ARRAY_SIZE(clu_codes), CLU_MIN_SIZE, CLU_MIN_SIZE, CLU_MAX_SIZE, CLU_MAX_SIZE); diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c index aa9d2286056e..6f51e5c75543 100644 --- a/drivers/media/platform/vsp1/vsp1_entity.c +++ b/drivers/media/platform/vsp1/vsp1_entity.c @@ -103,7 +103,7 @@ void vsp1_entity_configure_partition(struct vsp1_entity *entity, /** * vsp1_entity_get_pad_config - Get the pad configuration for an entity * @entity: the entity - * @cfg: the TRY pad configuration + * @sd_state: the TRY state * @which: configuration selector (ACTIVE or TRY) * * When called with which set to V4L2_SUBDEV_FORMAT_ACTIVE the caller must hold @@ -114,9 +114,9 @@ void vsp1_entity_configure_partition(struct vsp1_entity *entity, * and simply returned when requested. The ACTIVE configuration comes from the * entity structure. */ -struct v4l2_subdev_pad_config * +struct v4l2_subdev_state * vsp1_entity_get_pad_config(struct vsp1_entity *entity, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, enum v4l2_subdev_format_whence which) { switch (which) { @@ -124,14 +124,14 @@ vsp1_entity_get_pad_config(struct vsp1_entity *entity, return entity->config; case V4L2_SUBDEV_FORMAT_TRY: default: - return cfg; + return sd_state; } } /** * vsp1_entity_get_pad_format - Get a pad format from storage for an entity * @entity: the entity - * @cfg: the configuration storage + * @sd_state: the state storage * @pad: the pad number * * Return the format stored in the given configuration for an entity's pad. The @@ -139,16 +139,16 @@ vsp1_entity_get_pad_config(struct vsp1_entity *entity, */ struct v4l2_mbus_framefmt * vsp1_entity_get_pad_format(struct vsp1_entity *entity, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad) { - return v4l2_subdev_get_try_format(&entity->subdev, cfg, pad); + return v4l2_subdev_get_try_format(&entity->subdev, sd_state, pad); } /** * vsp1_entity_get_pad_selection - Get a pad selection from storage for entity * @entity: the entity - * @cfg: the configuration storage + * @sd_state: the state storage * @pad: the pad number * @target: the selection target * @@ -158,14 +158,16 @@ vsp1_entity_get_pad_format(struct vsp1_entity *entity, */ struct v4l2_rect * vsp1_entity_get_pad_selection(struct vsp1_entity *entity, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad, unsigned int target) { switch (target) { case V4L2_SEL_TGT_COMPOSE: - return v4l2_subdev_get_try_compose(&entity->subdev, cfg, pad); + return v4l2_subdev_get_try_compose(&entity->subdev, sd_state, + pad); case V4L2_SEL_TGT_CROP: - return v4l2_subdev_get_try_crop(&entity->subdev, cfg, pad); + return v4l2_subdev_get_try_crop(&entity->subdev, sd_state, + pad); default: return NULL; } @@ -180,7 +182,7 @@ vsp1_entity_get_pad_selection(struct vsp1_entity *entity, * function can be used as a handler for the subdev pad::init_cfg operation. */ int vsp1_entity_init_cfg(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg) + struct v4l2_subdev_state *sd_state) { struct v4l2_subdev_format format; unsigned int pad; @@ -189,10 +191,10 @@ int vsp1_entity_init_cfg(struct v4l2_subdev *subdev, memset(&format, 0, sizeof(format)); format.pad = pad; - format.which = cfg ? V4L2_SUBDEV_FORMAT_TRY + format.which = sd_state ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; - v4l2_subdev_call(subdev, pad, set_fmt, cfg, &format); + v4l2_subdev_call(subdev, pad, set_fmt, sd_state, &format); } return 0; @@ -208,13 +210,13 @@ int vsp1_entity_init_cfg(struct v4l2_subdev *subdev, * a direct drop-in for the operation handler. */ int vsp1_subdev_get_pad_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct vsp1_entity *entity = to_vsp1_entity(subdev); - struct v4l2_subdev_pad_config *config; + struct v4l2_subdev_state *config; - config = vsp1_entity_get_pad_config(entity, cfg, fmt->which); + config = vsp1_entity_get_pad_config(entity, sd_state, fmt->which); if (!config) return -EINVAL; @@ -239,7 +241,7 @@ int vsp1_subdev_get_pad_format(struct v4l2_subdev *subdev, * the sink pad. */ int vsp1_subdev_enum_mbus_code(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code, const unsigned int *codes, unsigned int ncodes) { @@ -251,7 +253,7 @@ int vsp1_subdev_enum_mbus_code(struct v4l2_subdev *subdev, code->code = codes[code->index]; } else { - struct v4l2_subdev_pad_config *config; + struct v4l2_subdev_state *config; struct v4l2_mbus_framefmt *format; /* @@ -261,7 +263,8 @@ int vsp1_subdev_enum_mbus_code(struct v4l2_subdev *subdev, if (code->index) return -EINVAL; - config = vsp1_entity_get_pad_config(entity, cfg, code->which); + config = vsp1_entity_get_pad_config(entity, sd_state, + code->which); if (!config) return -EINVAL; @@ -290,17 +293,17 @@ int vsp1_subdev_enum_mbus_code(struct v4l2_subdev *subdev, * source pad size identical to the sink pad. */ int vsp1_subdev_enum_frame_size(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse, unsigned int min_width, unsigned int min_height, unsigned int max_width, unsigned int max_height) { struct vsp1_entity *entity = to_vsp1_entity(subdev); - struct v4l2_subdev_pad_config *config; + struct v4l2_subdev_state *config; struct v4l2_mbus_framefmt *format; int ret = 0; - config = vsp1_entity_get_pad_config(entity, cfg, fse->which); + config = vsp1_entity_get_pad_config(entity, sd_state, fse->which); if (!config) return -EINVAL; @@ -353,14 +356,14 @@ done: * source pad. */ int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt, const unsigned int *codes, unsigned int ncodes, unsigned int min_width, unsigned int min_height, unsigned int max_width, unsigned int max_height) { struct vsp1_entity *entity = to_vsp1_entity(subdev); - struct v4l2_subdev_pad_config *config; + struct v4l2_subdev_state *config; struct v4l2_mbus_framefmt *format; struct v4l2_rect *selection; unsigned int i; @@ -368,7 +371,7 @@ int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev, mutex_lock(&entity->lock); - config = vsp1_entity_get_pad_config(entity, cfg, fmt->which); + config = vsp1_entity_get_pad_config(entity, sd_state, fmt->which); if (!config) { ret = -EINVAL; goto done; @@ -672,7 +675,7 @@ int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity, * Allocate the pad configuration to store formats and selection * rectangles. */ - entity->config = v4l2_subdev_alloc_pad_config(&entity->subdev); + entity->config = v4l2_subdev_alloc_state(&entity->subdev); if (entity->config == NULL) { media_entity_cleanup(&entity->subdev.entity); return -ENOMEM; @@ -687,6 +690,6 @@ void vsp1_entity_destroy(struct vsp1_entity *entity) entity->ops->destroy(entity); if (entity->subdev.ctrl_handler) v4l2_ctrl_handler_free(entity->subdev.ctrl_handler); - v4l2_subdev_free_pad_config(entity->config); + v4l2_subdev_free_state(entity->config); media_entity_cleanup(&entity->subdev.entity); } diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h index a1ceb37bb837..f22724439cdc 100644 --- a/drivers/media/platform/vsp1/vsp1_entity.h +++ b/drivers/media/platform/vsp1/vsp1_entity.h @@ -115,7 +115,7 @@ struct vsp1_entity { unsigned int sink_pad; struct v4l2_subdev subdev; - struct v4l2_subdev_pad_config *config; + struct v4l2_subdev_state *config; struct mutex lock; /* Protects the pad config */ }; @@ -136,20 +136,20 @@ int vsp1_entity_link_setup(struct media_entity *entity, const struct media_pad *local, const struct media_pad *remote, u32 flags); -struct v4l2_subdev_pad_config * +struct v4l2_subdev_state * vsp1_entity_get_pad_config(struct vsp1_entity *entity, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, enum v4l2_subdev_format_whence which); struct v4l2_mbus_framefmt * vsp1_entity_get_pad_format(struct vsp1_entity *entity, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad); struct v4l2_rect * vsp1_entity_get_pad_selection(struct vsp1_entity *entity, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad, unsigned int target); int vsp1_entity_init_cfg(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg); + struct v4l2_subdev_state *sd_state); void vsp1_entity_route_setup(struct vsp1_entity *entity, struct vsp1_pipeline *pipe, @@ -173,20 +173,20 @@ void vsp1_entity_configure_partition(struct vsp1_entity *entity, struct media_pad *vsp1_entity_remote_pad(struct media_pad *pad); int vsp1_subdev_get_pad_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt); int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt, const unsigned int *codes, unsigned int ncodes, unsigned int min_width, unsigned int min_height, unsigned int max_width, unsigned int max_height); int vsp1_subdev_enum_mbus_code(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code, const unsigned int *codes, unsigned int ncodes); int vsp1_subdev_enum_frame_size(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse, unsigned int min_w, unsigned int min_h, unsigned int max_w, unsigned int max_h); diff --git a/drivers/media/platform/vsp1/vsp1_histo.c b/drivers/media/platform/vsp1/vsp1_histo.c index a91e142bcb94..5e5013d2cd2a 100644 --- a/drivers/media/platform/vsp1/vsp1_histo.c +++ b/drivers/media/platform/vsp1/vsp1_histo.c @@ -170,7 +170,7 @@ static const struct vb2_ops histo_video_queue_qops = { */ static int histo_enum_mbus_code(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct vsp1_histogram *histo = subdev_to_histo(subdev); @@ -180,28 +180,30 @@ static int histo_enum_mbus_code(struct v4l2_subdev *subdev, return 0; } - return vsp1_subdev_enum_mbus_code(subdev, cfg, code, histo->formats, + return vsp1_subdev_enum_mbus_code(subdev, sd_state, code, + histo->formats, histo->num_formats); } static int histo_enum_frame_size(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { if (fse->pad != HISTO_PAD_SINK) return -EINVAL; - return vsp1_subdev_enum_frame_size(subdev, cfg, fse, HISTO_MIN_SIZE, + return vsp1_subdev_enum_frame_size(subdev, sd_state, fse, + HISTO_MIN_SIZE, HISTO_MIN_SIZE, HISTO_MAX_SIZE, HISTO_MAX_SIZE); } static int histo_get_selection(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct vsp1_histogram *histo = subdev_to_histo(subdev); - struct v4l2_subdev_pad_config *config; + struct v4l2_subdev_state *config; struct v4l2_mbus_framefmt *format; struct v4l2_rect *crop; int ret = 0; @@ -211,7 +213,8 @@ static int histo_get_selection(struct v4l2_subdev *subdev, mutex_lock(&histo->entity.lock); - config = vsp1_entity_get_pad_config(&histo->entity, cfg, sel->which); + config = vsp1_entity_get_pad_config(&histo->entity, sd_state, + sel->which); if (!config) { ret = -EINVAL; goto done; @@ -256,15 +259,15 @@ done: } static int histo_set_crop(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *config, - struct v4l2_subdev_selection *sel) + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_selection *sel) { struct vsp1_histogram *histo = subdev_to_histo(subdev); struct v4l2_mbus_framefmt *format; struct v4l2_rect *selection; /* The crop rectangle must be inside the input frame. */ - format = vsp1_entity_get_pad_format(&histo->entity, config, + format = vsp1_entity_get_pad_format(&histo->entity, sd_state, HISTO_PAD_SINK); sel->r.left = clamp_t(unsigned int, sel->r.left, 0, format->width - 1); sel->r.top = clamp_t(unsigned int, sel->r.top, 0, format->height - 1); @@ -274,11 +277,11 @@ static int histo_set_crop(struct v4l2_subdev *subdev, format->height - sel->r.top); /* Set the crop rectangle and reset the compose rectangle. */ - selection = vsp1_entity_get_pad_selection(&histo->entity, config, + selection = vsp1_entity_get_pad_selection(&histo->entity, sd_state, sel->pad, V4L2_SEL_TGT_CROP); *selection = sel->r; - selection = vsp1_entity_get_pad_selection(&histo->entity, config, + selection = vsp1_entity_get_pad_selection(&histo->entity, sd_state, sel->pad, V4L2_SEL_TGT_COMPOSE); *selection = sel->r; @@ -287,7 +290,7 @@ static int histo_set_crop(struct v4l2_subdev *subdev, } static int histo_set_compose(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *config, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct vsp1_histogram *histo = subdev_to_histo(subdev); @@ -303,7 +306,8 @@ static int histo_set_compose(struct v4l2_subdev *subdev, sel->r.left = 0; sel->r.top = 0; - crop = vsp1_entity_get_pad_selection(&histo->entity, config, sel->pad, + crop = vsp1_entity_get_pad_selection(&histo->entity, sd_state, + sel->pad, V4L2_SEL_TGT_CROP); /* @@ -329,7 +333,7 @@ static int histo_set_compose(struct v4l2_subdev *subdev, ratio = 1 << (crop->height * 2 / sel->r.height / 3); sel->r.height = crop->height / ratio; - compose = vsp1_entity_get_pad_selection(&histo->entity, config, + compose = vsp1_entity_get_pad_selection(&histo->entity, sd_state, sel->pad, V4L2_SEL_TGT_COMPOSE); *compose = sel->r; @@ -338,11 +342,11 @@ static int histo_set_compose(struct v4l2_subdev *subdev, } static int histo_set_selection(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct vsp1_histogram *histo = subdev_to_histo(subdev); - struct v4l2_subdev_pad_config *config; + struct v4l2_subdev_state *config; int ret; if (sel->pad != HISTO_PAD_SINK) @@ -350,7 +354,8 @@ static int histo_set_selection(struct v4l2_subdev *subdev, mutex_lock(&histo->entity.lock); - config = vsp1_entity_get_pad_config(&histo->entity, cfg, sel->which); + config = vsp1_entity_get_pad_config(&histo->entity, sd_state, + sel->which); if (!config) { ret = -EINVAL; goto done; @@ -369,7 +374,7 @@ done: } static int histo_get_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { if (fmt->pad == HISTO_PAD_SOURCE) { @@ -381,19 +386,19 @@ static int histo_get_format(struct v4l2_subdev *subdev, return 0; } - return vsp1_subdev_get_pad_format(subdev, cfg, fmt); + return vsp1_subdev_get_pad_format(subdev, sd_state, fmt); } static int histo_set_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct vsp1_histogram *histo = subdev_to_histo(subdev); if (fmt->pad != HISTO_PAD_SINK) - return histo_get_format(subdev, cfg, fmt); + return histo_get_format(subdev, sd_state, fmt); - return vsp1_subdev_set_pad_format(subdev, cfg, fmt, + return vsp1_subdev_set_pad_format(subdev, sd_state, fmt, histo->formats, histo->num_formats, HISTO_MIN_SIZE, HISTO_MIN_SIZE, HISTO_MAX_SIZE, HISTO_MAX_SIZE); diff --git a/drivers/media/platform/vsp1/vsp1_hsit.c b/drivers/media/platform/vsp1/vsp1_hsit.c index d5ebd9d08c8a..361a870380c2 100644 --- a/drivers/media/platform/vsp1/vsp1_hsit.c +++ b/drivers/media/platform/vsp1/vsp1_hsit.c @@ -34,7 +34,7 @@ static inline void vsp1_hsit_write(struct vsp1_hsit *hsit, */ static int hsit_enum_mbus_code(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct vsp1_hsit *hsit = to_hsit(subdev); @@ -52,26 +52,28 @@ static int hsit_enum_mbus_code(struct v4l2_subdev *subdev, } static int hsit_enum_frame_size(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { - return vsp1_subdev_enum_frame_size(subdev, cfg, fse, HSIT_MIN_SIZE, + return vsp1_subdev_enum_frame_size(subdev, sd_state, fse, + HSIT_MIN_SIZE, HSIT_MIN_SIZE, HSIT_MAX_SIZE, HSIT_MAX_SIZE); } static int hsit_set_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct vsp1_hsit *hsit = to_hsit(subdev); - struct v4l2_subdev_pad_config *config; + struct v4l2_subdev_state *config; struct v4l2_mbus_framefmt *format; int ret = 0; mutex_lock(&hsit->entity.lock); - config = vsp1_entity_get_pad_config(&hsit->entity, cfg, fmt->which); + config = vsp1_entity_get_pad_config(&hsit->entity, sd_state, + fmt->which); if (!config) { ret = -EINVAL; goto done; diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c index 14ed5d7bd061..6a6857ac9327 100644 --- a/drivers/media/platform/vsp1/vsp1_lif.c +++ b/drivers/media/platform/vsp1/vsp1_lif.c @@ -40,27 +40,28 @@ static const unsigned int lif_codes[] = { }; static int lif_enum_mbus_code(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { - return vsp1_subdev_enum_mbus_code(subdev, cfg, code, lif_codes, + return vsp1_subdev_enum_mbus_code(subdev, sd_state, code, lif_codes, ARRAY_SIZE(lif_codes)); } static int lif_enum_frame_size(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { - return vsp1_subdev_enum_frame_size(subdev, cfg, fse, LIF_MIN_SIZE, + return vsp1_subdev_enum_frame_size(subdev, sd_state, fse, + LIF_MIN_SIZE, LIF_MIN_SIZE, LIF_MAX_SIZE, LIF_MAX_SIZE); } static int lif_set_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { - return vsp1_subdev_set_pad_format(subdev, cfg, fmt, lif_codes, + return vsp1_subdev_set_pad_format(subdev, sd_state, fmt, lif_codes, ARRAY_SIZE(lif_codes), LIF_MIN_SIZE, LIF_MIN_SIZE, LIF_MAX_SIZE, LIF_MAX_SIZE); diff --git a/drivers/media/platform/vsp1/vsp1_lut.c b/drivers/media/platform/vsp1/vsp1_lut.c index 9f88842d7048..ac6802a325f5 100644 --- a/drivers/media/platform/vsp1/vsp1_lut.c +++ b/drivers/media/platform/vsp1/vsp1_lut.c @@ -99,27 +99,28 @@ static const unsigned int lut_codes[] = { }; static int lut_enum_mbus_code(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { - return vsp1_subdev_enum_mbus_code(subdev, cfg, code, lut_codes, + return vsp1_subdev_enum_mbus_code(subdev, sd_state, code, lut_codes, ARRAY_SIZE(lut_codes)); } static int lut_enum_frame_size(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { - return vsp1_subdev_enum_frame_size(subdev, cfg, fse, LUT_MIN_SIZE, + return vsp1_subdev_enum_frame_size(subdev, sd_state, fse, + LUT_MIN_SIZE, LUT_MIN_SIZE, LUT_MAX_SIZE, LUT_MAX_SIZE); } static int lut_set_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { - return vsp1_subdev_set_pad_format(subdev, cfg, fmt, lut_codes, + return vsp1_subdev_set_pad_format(subdev, sd_state, fmt, lut_codes, ARRAY_SIZE(lut_codes), LUT_MIN_SIZE, LUT_MIN_SIZE, LUT_MAX_SIZE, LUT_MAX_SIZE); diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.c b/drivers/media/platform/vsp1/vsp1_rwpf.c index 049bdd958e56..22a82d218152 100644 --- a/drivers/media/platform/vsp1/vsp1_rwpf.c +++ b/drivers/media/platform/vsp1/vsp1_rwpf.c @@ -17,9 +17,9 @@ #define RWPF_MIN_HEIGHT 1 struct v4l2_rect *vsp1_rwpf_get_crop(struct vsp1_rwpf *rwpf, - struct v4l2_subdev_pad_config *config) + struct v4l2_subdev_state *sd_state) { - return v4l2_subdev_get_try_crop(&rwpf->entity.subdev, config, + return v4l2_subdev_get_try_crop(&rwpf->entity.subdev, sd_state, RWPF_PAD_SINK); } @@ -28,7 +28,7 @@ struct v4l2_rect *vsp1_rwpf_get_crop(struct vsp1_rwpf *rwpf, */ static int vsp1_rwpf_enum_mbus_code(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { static const unsigned int codes[] = { @@ -46,28 +46,30 @@ static int vsp1_rwpf_enum_mbus_code(struct v4l2_subdev *subdev, } static int vsp1_rwpf_enum_frame_size(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { struct vsp1_rwpf *rwpf = to_rwpf(subdev); - return vsp1_subdev_enum_frame_size(subdev, cfg, fse, RWPF_MIN_WIDTH, + return vsp1_subdev_enum_frame_size(subdev, sd_state, fse, + RWPF_MIN_WIDTH, RWPF_MIN_HEIGHT, rwpf->max_width, rwpf->max_height); } static int vsp1_rwpf_set_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct vsp1_rwpf *rwpf = to_rwpf(subdev); - struct v4l2_subdev_pad_config *config; + struct v4l2_subdev_state *config; struct v4l2_mbus_framefmt *format; int ret = 0; mutex_lock(&rwpf->entity.lock); - config = vsp1_entity_get_pad_config(&rwpf->entity, cfg, fmt->which); + config = vsp1_entity_get_pad_config(&rwpf->entity, sd_state, + fmt->which); if (!config) { ret = -EINVAL; goto done; @@ -128,11 +130,11 @@ done: } static int vsp1_rwpf_get_selection(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct vsp1_rwpf *rwpf = to_rwpf(subdev); - struct v4l2_subdev_pad_config *config; + struct v4l2_subdev_state *config; struct v4l2_mbus_framefmt *format; int ret = 0; @@ -145,7 +147,8 @@ static int vsp1_rwpf_get_selection(struct v4l2_subdev *subdev, mutex_lock(&rwpf->entity.lock); - config = vsp1_entity_get_pad_config(&rwpf->entity, cfg, sel->which); + config = vsp1_entity_get_pad_config(&rwpf->entity, sd_state, + sel->which); if (!config) { ret = -EINVAL; goto done; @@ -176,11 +179,11 @@ done: } static int vsp1_rwpf_set_selection(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct vsp1_rwpf *rwpf = to_rwpf(subdev); - struct v4l2_subdev_pad_config *config; + struct v4l2_subdev_state *config; struct v4l2_mbus_framefmt *format; struct v4l2_rect *crop; int ret = 0; @@ -197,7 +200,8 @@ static int vsp1_rwpf_set_selection(struct v4l2_subdev *subdev, mutex_lock(&rwpf->entity.lock); - config = vsp1_entity_get_pad_config(&rwpf->entity, cfg, sel->which); + config = vsp1_entity_get_pad_config(&rwpf->entity, sd_state, + sel->which); if (!config) { ret = -EINVAL; goto done; diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h index 2f3582590618..eac5c04c2239 100644 --- a/drivers/media/platform/vsp1/vsp1_rwpf.h +++ b/drivers/media/platform/vsp1/vsp1_rwpf.h @@ -84,6 +84,6 @@ int vsp1_rwpf_init_ctrls(struct vsp1_rwpf *rwpf, unsigned int ncontrols); extern const struct v4l2_subdev_pad_ops vsp1_rwpf_pad_ops; struct v4l2_rect *vsp1_rwpf_get_crop(struct vsp1_rwpf *rwpf, - struct v4l2_subdev_pad_config *config); + struct v4l2_subdev_state *sd_state); #endif /* __VSP1_RWPF_H__ */ diff --git a/drivers/media/platform/vsp1/vsp1_sru.c b/drivers/media/platform/vsp1/vsp1_sru.c index 2b65457ee12f..b614a2aea461 100644 --- a/drivers/media/platform/vsp1/vsp1_sru.c +++ b/drivers/media/platform/vsp1/vsp1_sru.c @@ -106,7 +106,7 @@ static const struct v4l2_ctrl_config sru_intensity_control = { */ static int sru_enum_mbus_code(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { static const unsigned int codes[] = { @@ -114,20 +114,21 @@ static int sru_enum_mbus_code(struct v4l2_subdev *subdev, MEDIA_BUS_FMT_AYUV8_1X32, }; - return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes, + return vsp1_subdev_enum_mbus_code(subdev, sd_state, code, codes, ARRAY_SIZE(codes)); } static int sru_enum_frame_size(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { struct vsp1_sru *sru = to_sru(subdev); - struct v4l2_subdev_pad_config *config; + struct v4l2_subdev_state *config; struct v4l2_mbus_framefmt *format; int ret = 0; - config = vsp1_entity_get_pad_config(&sru->entity, cfg, fse->which); + config = vsp1_entity_get_pad_config(&sru->entity, sd_state, + fse->which); if (!config) return -EINVAL; @@ -164,7 +165,7 @@ done: } static void sru_try_format(struct vsp1_sru *sru, - struct v4l2_subdev_pad_config *config, + struct v4l2_subdev_state *sd_state, unsigned int pad, struct v4l2_mbus_framefmt *fmt) { struct v4l2_mbus_framefmt *format; @@ -184,7 +185,7 @@ static void sru_try_format(struct vsp1_sru *sru, case SRU_PAD_SOURCE: /* The SRU can't perform format conversion. */ - format = vsp1_entity_get_pad_format(&sru->entity, config, + format = vsp1_entity_get_pad_format(&sru->entity, sd_state, SRU_PAD_SINK); fmt->code = format->code; @@ -216,17 +217,18 @@ static void sru_try_format(struct vsp1_sru *sru, } static int sru_set_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct vsp1_sru *sru = to_sru(subdev); - struct v4l2_subdev_pad_config *config; + struct v4l2_subdev_state *config; struct v4l2_mbus_framefmt *format; int ret = 0; mutex_lock(&sru->entity.lock); - config = vsp1_entity_get_pad_config(&sru->entity, cfg, fmt->which); + config = vsp1_entity_get_pad_config(&sru->entity, sd_state, + fmt->which); if (!config) { ret = -EINVAL; goto done; diff --git a/drivers/media/platform/vsp1/vsp1_uds.c b/drivers/media/platform/vsp1/vsp1_uds.c index 5fc04c082d1a..1c290cda005a 100644 --- a/drivers/media/platform/vsp1/vsp1_uds.c +++ b/drivers/media/platform/vsp1/vsp1_uds.c @@ -111,7 +111,7 @@ static unsigned int uds_compute_ratio(unsigned int input, unsigned int output) */ static int uds_enum_mbus_code(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { static const unsigned int codes[] = { @@ -119,20 +119,21 @@ static int uds_enum_mbus_code(struct v4l2_subdev *subdev, MEDIA_BUS_FMT_AYUV8_1X32, }; - return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes, + return vsp1_subdev_enum_mbus_code(subdev, sd_state, code, codes, ARRAY_SIZE(codes)); } static int uds_enum_frame_size(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { struct vsp1_uds *uds = to_uds(subdev); - struct v4l2_subdev_pad_config *config; + struct v4l2_subdev_state *config; struct v4l2_mbus_framefmt *format; int ret = 0; - config = vsp1_entity_get_pad_config(&uds->entity, cfg, fse->which); + config = vsp1_entity_get_pad_config(&uds->entity, sd_state, + fse->which); if (!config) return -EINVAL; @@ -164,7 +165,7 @@ done: } static void uds_try_format(struct vsp1_uds *uds, - struct v4l2_subdev_pad_config *config, + struct v4l2_subdev_state *sd_state, unsigned int pad, struct v4l2_mbus_framefmt *fmt) { struct v4l2_mbus_framefmt *format; @@ -184,7 +185,7 @@ static void uds_try_format(struct vsp1_uds *uds, case UDS_PAD_SOURCE: /* The UDS scales but can't perform format conversion. */ - format = vsp1_entity_get_pad_format(&uds->entity, config, + format = vsp1_entity_get_pad_format(&uds->entity, sd_state, UDS_PAD_SINK); fmt->code = format->code; @@ -200,17 +201,18 @@ static void uds_try_format(struct vsp1_uds *uds, } static int uds_set_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct vsp1_uds *uds = to_uds(subdev); - struct v4l2_subdev_pad_config *config; + struct v4l2_subdev_state *config; struct v4l2_mbus_framefmt *format; int ret = 0; mutex_lock(&uds->entity.lock); - config = vsp1_entity_get_pad_config(&uds->entity, cfg, fmt->which); + config = vsp1_entity_get_pad_config(&uds->entity, sd_state, + fmt->which); if (!config) { ret = -EINVAL; goto done; diff --git a/drivers/media/platform/vsp1/vsp1_uif.c b/drivers/media/platform/vsp1/vsp1_uif.c index 467d1072577b..83d7f17df80e 100644 --- a/drivers/media/platform/vsp1/vsp1_uif.c +++ b/drivers/media/platform/vsp1/vsp1_uif.c @@ -54,38 +54,39 @@ static const unsigned int uif_codes[] = { }; static int uif_enum_mbus_code(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { - return vsp1_subdev_enum_mbus_code(subdev, cfg, code, uif_codes, + return vsp1_subdev_enum_mbus_code(subdev, sd_state, code, uif_codes, ARRAY_SIZE(uif_codes)); } static int uif_enum_frame_size(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { - return vsp1_subdev_enum_frame_size(subdev, cfg, fse, UIF_MIN_SIZE, + return vsp1_subdev_enum_frame_size(subdev, sd_state, fse, + UIF_MIN_SIZE, UIF_MIN_SIZE, UIF_MAX_SIZE, UIF_MAX_SIZE); } static int uif_set_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { - return vsp1_subdev_set_pad_format(subdev, cfg, fmt, uif_codes, + return vsp1_subdev_set_pad_format(subdev, sd_state, fmt, uif_codes, ARRAY_SIZE(uif_codes), UIF_MIN_SIZE, UIF_MIN_SIZE, UIF_MAX_SIZE, UIF_MAX_SIZE); } static int uif_get_selection(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct vsp1_uif *uif = to_uif(subdev); - struct v4l2_subdev_pad_config *config; + struct v4l2_subdev_state *config; struct v4l2_mbus_framefmt *format; int ret = 0; @@ -94,7 +95,8 @@ static int uif_get_selection(struct v4l2_subdev *subdev, mutex_lock(&uif->entity.lock); - config = vsp1_entity_get_pad_config(&uif->entity, cfg, sel->which); + config = vsp1_entity_get_pad_config(&uif->entity, sd_state, + sel->which); if (!config) { ret = -EINVAL; goto done; @@ -127,11 +129,11 @@ done: } static int uif_set_selection(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct vsp1_uif *uif = to_uif(subdev); - struct v4l2_subdev_pad_config *config; + struct v4l2_subdev_state *config; struct v4l2_mbus_framefmt *format; struct v4l2_rect *selection; int ret = 0; @@ -142,7 +144,8 @@ static int uif_set_selection(struct v4l2_subdev *subdev, mutex_lock(&uif->entity.lock); - config = vsp1_entity_get_pad_config(&uif->entity, cfg, sel->which); + config = vsp1_entity_get_pad_config(&uif->entity, sd_state, + sel->which); if (!config) { ret = -EINVAL; goto done; diff --git a/drivers/media/platform/xilinx/xilinx-csi2rxss.c b/drivers/media/platform/xilinx/xilinx-csi2rxss.c index fff7ddec6745..b1baf9d7b6ec 100644 --- a/drivers/media/platform/xilinx/xilinx-csi2rxss.c +++ b/drivers/media/platform/xilinx/xilinx-csi2rxss.c @@ -681,12 +681,13 @@ stream_done: static struct v4l2_mbus_framefmt * __xcsi2rxss_get_pad_format(struct xcsi2rxss_state *xcsi2rxss, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad, u32 which) { switch (which) { case V4L2_SUBDEV_FORMAT_TRY: - return v4l2_subdev_get_try_format(&xcsi2rxss->subdev, cfg, pad); + return v4l2_subdev_get_try_format(&xcsi2rxss->subdev, + sd_state, pad); case V4L2_SUBDEV_FORMAT_ACTIVE: return &xcsi2rxss->format; default: @@ -697,7 +698,7 @@ __xcsi2rxss_get_pad_format(struct xcsi2rxss_state *xcsi2rxss, /** * xcsi2rxss_init_cfg - Initialise the pad format config to default * @sd: Pointer to V4L2 Sub device structure - * @cfg: Pointer to sub device pad information structure + * @sd_state: Pointer to sub device state structure * * This function is used to initialize the pad format with the default * values. @@ -705,7 +706,7 @@ __xcsi2rxss_get_pad_format(struct xcsi2rxss_state *xcsi2rxss, * Return: 0 on success */ static int xcsi2rxss_init_cfg(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg) + struct v4l2_subdev_state *sd_state) { struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd); struct v4l2_mbus_framefmt *format; @@ -713,7 +714,7 @@ static int xcsi2rxss_init_cfg(struct v4l2_subdev *sd, mutex_lock(&xcsi2rxss->lock); for (i = 0; i < XCSI_MEDIA_PADS; i++) { - format = v4l2_subdev_get_try_format(sd, cfg, i); + format = v4l2_subdev_get_try_format(sd, sd_state, i); *format = xcsi2rxss->default_format; } mutex_unlock(&xcsi2rxss->lock); @@ -724,7 +725,7 @@ static int xcsi2rxss_init_cfg(struct v4l2_subdev *sd, /** * xcsi2rxss_get_format - Get the pad format * @sd: Pointer to V4L2 Sub device structure - * @cfg: Pointer to sub device pad information structure + * @sd_state: Pointer to sub device state structure * @fmt: Pointer to pad level media bus format * * This function is used to get the pad format information. @@ -732,13 +733,14 @@ static int xcsi2rxss_init_cfg(struct v4l2_subdev *sd, * Return: 0 on success */ static int xcsi2rxss_get_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd); mutex_lock(&xcsi2rxss->lock); - fmt->format = *__xcsi2rxss_get_pad_format(xcsi2rxss, cfg, fmt->pad, + fmt->format = *__xcsi2rxss_get_pad_format(xcsi2rxss, sd_state, + fmt->pad, fmt->which); mutex_unlock(&xcsi2rxss->lock); @@ -748,7 +750,7 @@ static int xcsi2rxss_get_format(struct v4l2_subdev *sd, /** * xcsi2rxss_set_format - This is used to set the pad format * @sd: Pointer to V4L2 Sub device structure - * @cfg: Pointer to sub device pad information structure + * @sd_state: Pointer to sub device state structure * @fmt: Pointer to pad level media bus format * * This function is used to set the pad format. Since the pad format is fixed @@ -759,7 +761,7 @@ static int xcsi2rxss_get_format(struct v4l2_subdev *sd, * Return: 0 on success */ static int xcsi2rxss_set_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd); @@ -773,7 +775,7 @@ static int xcsi2rxss_set_format(struct v4l2_subdev *sd, * CSI format cannot be changed at runtime. * Ensure that format to set is copied to over to CSI pad format */ - __format = __xcsi2rxss_get_pad_format(xcsi2rxss, cfg, + __format = __xcsi2rxss_get_pad_format(xcsi2rxss, sd_state, fmt->pad, fmt->which); /* only sink pad format can be updated */ @@ -811,7 +813,7 @@ static int xcsi2rxss_set_format(struct v4l2_subdev *sd, * Return: -EINVAL or zero on success */ static int xcsi2rxss_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct xcsi2rxss_state *state = to_xcsi2rxssstate(sd); diff --git a/drivers/media/platform/xilinx/xilinx-tpg.c b/drivers/media/platform/xilinx/xilinx-tpg.c index ed01bedb5db6..0f2d5a0edf0c 100644 --- a/drivers/media/platform/xilinx/xilinx-tpg.c +++ b/drivers/media/platform/xilinx/xilinx-tpg.c @@ -251,12 +251,13 @@ static int xtpg_s_stream(struct v4l2_subdev *subdev, int enable) static struct v4l2_mbus_framefmt * __xtpg_get_pad_format(struct xtpg_device *xtpg, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad, u32 which) { switch (which) { case V4L2_SUBDEV_FORMAT_TRY: - return v4l2_subdev_get_try_format(&xtpg->xvip.subdev, cfg, pad); + return v4l2_subdev_get_try_format(&xtpg->xvip.subdev, + sd_state, pad); case V4L2_SUBDEV_FORMAT_ACTIVE: return &xtpg->formats[pad]; default: @@ -265,25 +266,26 @@ __xtpg_get_pad_format(struct xtpg_device *xtpg, } static int xtpg_get_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct xtpg_device *xtpg = to_tpg(subdev); - fmt->format = *__xtpg_get_pad_format(xtpg, cfg, fmt->pad, fmt->which); + fmt->format = *__xtpg_get_pad_format(xtpg, sd_state, fmt->pad, + fmt->which); return 0; } static int xtpg_set_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct xtpg_device *xtpg = to_tpg(subdev); struct v4l2_mbus_framefmt *__format; u32 bayer_phase; - __format = __xtpg_get_pad_format(xtpg, cfg, fmt->pad, fmt->which); + __format = __xtpg_get_pad_format(xtpg, sd_state, fmt->pad, fmt->which); /* In two pads mode the source pad format is always identical to the * sink pad format. @@ -306,7 +308,8 @@ static int xtpg_set_format(struct v4l2_subdev *subdev, /* Propagate the format to the source pad. */ if (xtpg->npads == 2) { - __format = __xtpg_get_pad_format(xtpg, cfg, 1, fmt->which); + __format = __xtpg_get_pad_format(xtpg, sd_state, 1, + fmt->which); *__format = fmt->format; } @@ -318,12 +321,12 @@ static int xtpg_set_format(struct v4l2_subdev *subdev, */ static int xtpg_enum_frame_size(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { struct v4l2_mbus_framefmt *format; - format = v4l2_subdev_get_try_format(subdev, cfg, fse->pad); + format = v4l2_subdev_get_try_format(subdev, sd_state, fse->pad); if (fse->index || fse->code != format->code) return -EINVAL; @@ -351,11 +354,11 @@ static int xtpg_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh) struct xtpg_device *xtpg = to_tpg(subdev); struct v4l2_mbus_framefmt *format; - format = v4l2_subdev_get_try_format(subdev, fh->pad, 0); + format = v4l2_subdev_get_try_format(subdev, fh->state, 0); *format = xtpg->default_format; if (xtpg->npads == 2) { - format = v4l2_subdev_get_try_format(subdev, fh->pad, 1); + format = v4l2_subdev_get_try_format(subdev, fh->state, 1); *format = xtpg->default_format; } diff --git a/drivers/media/platform/xilinx/xilinx-vip.c b/drivers/media/platform/xilinx/xilinx-vip.c index a4eb57683411..425a32dd5d19 100644 --- a/drivers/media/platform/xilinx/xilinx-vip.c +++ b/drivers/media/platform/xilinx/xilinx-vip.c @@ -234,7 +234,7 @@ EXPORT_SYMBOL_GPL(xvip_cleanup_resources); /** * xvip_enum_mbus_code - Enumerate the media format code * @subdev: V4L2 subdevice - * @cfg: V4L2 subdev pad configuration + * @sd_state: V4L2 subdev state * @code: returning media bus code * * Enumerate the media bus code of the subdevice. Return the corresponding @@ -246,7 +246,7 @@ EXPORT_SYMBOL_GPL(xvip_cleanup_resources); * is not valid. */ int xvip_enum_mbus_code(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct v4l2_mbus_framefmt *format; @@ -260,7 +260,7 @@ int xvip_enum_mbus_code(struct v4l2_subdev *subdev, if (code->index) return -EINVAL; - format = v4l2_subdev_get_try_format(subdev, cfg, code->pad); + format = v4l2_subdev_get_try_format(subdev, sd_state, code->pad); code->code = format->code; @@ -271,7 +271,7 @@ EXPORT_SYMBOL_GPL(xvip_enum_mbus_code); /** * xvip_enum_frame_size - Enumerate the media bus frame size * @subdev: V4L2 subdevice - * @cfg: V4L2 subdev pad configuration + * @sd_state: V4L2 subdev state * @fse: returning media bus frame size * * This function is a drop-in implementation of the subdev enum_frame_size pad @@ -284,7 +284,7 @@ EXPORT_SYMBOL_GPL(xvip_enum_mbus_code); * if the index or the code is not valid. */ int xvip_enum_frame_size(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { struct v4l2_mbus_framefmt *format; @@ -295,7 +295,7 @@ int xvip_enum_frame_size(struct v4l2_subdev *subdev, if (fse->which == V4L2_SUBDEV_FORMAT_ACTIVE) return -EINVAL; - format = v4l2_subdev_get_try_format(subdev, cfg, fse->pad); + format = v4l2_subdev_get_try_format(subdev, sd_state, fse->pad); if (fse->index || fse->code != format->code) return -EINVAL; diff --git a/drivers/media/platform/xilinx/xilinx-vip.h b/drivers/media/platform/xilinx/xilinx-vip.h index a528a32ea1dc..d0b0e0600952 100644 --- a/drivers/media/platform/xilinx/xilinx-vip.h +++ b/drivers/media/platform/xilinx/xilinx-vip.h @@ -125,10 +125,10 @@ const struct xvip_video_format *xvip_of_get_format(struct device_node *node); void xvip_set_format_size(struct v4l2_mbus_framefmt *format, const struct v4l2_subdev_format *fmt); int xvip_enum_mbus_code(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code); int xvip_enum_frame_size(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse); static inline u32 xvip_read(struct xvip_device *xvip, u32 addr) diff --git a/drivers/media/test-drivers/vimc/vimc-debayer.c b/drivers/media/test-drivers/vimc/vimc-debayer.c index c3f6fef34f68..2d06cdbacc76 100644 --- a/drivers/media/test-drivers/vimc/vimc-debayer.c +++ b/drivers/media/test-drivers/vimc/vimc-debayer.c @@ -150,17 +150,17 @@ static bool vimc_deb_src_code_is_valid(u32 code) } static int vimc_deb_init_cfg(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg) + struct v4l2_subdev_state *sd_state) { struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *mf; unsigned int i; - mf = v4l2_subdev_get_try_format(sd, cfg, 0); + mf = v4l2_subdev_get_try_format(sd, sd_state, 0); *mf = sink_fmt_default; for (i = 1; i < sd->entity.num_pads; i++) { - mf = v4l2_subdev_get_try_format(sd, cfg, i); + mf = v4l2_subdev_get_try_format(sd, sd_state, i); *mf = sink_fmt_default; mf->code = vdeb->src_code; } @@ -169,7 +169,7 @@ static int vimc_deb_init_cfg(struct v4l2_subdev *sd, } static int vimc_deb_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (VIMC_IS_SRC(code->pad)) { @@ -188,7 +188,7 @@ static int vimc_deb_enum_mbus_code(struct v4l2_subdev *sd, } static int vimc_deb_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { if (fse->index) @@ -213,14 +213,14 @@ static int vimc_deb_enum_frame_size(struct v4l2_subdev *sd, } static int vimc_deb_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd); /* Get the current sink format */ fmt->format = fmt->which == V4L2_SUBDEV_FORMAT_TRY ? - *v4l2_subdev_get_try_format(sd, cfg, 0) : + *v4l2_subdev_get_try_format(sd, sd_state, 0) : vdeb->sink_fmt; /* Set the right code for the source pad */ @@ -251,7 +251,7 @@ static void vimc_deb_adjust_sink_fmt(struct v4l2_mbus_framefmt *fmt) } static int vimc_deb_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd); @@ -266,8 +266,8 @@ static int vimc_deb_set_fmt(struct v4l2_subdev *sd, sink_fmt = &vdeb->sink_fmt; src_code = &vdeb->src_code; } else { - sink_fmt = v4l2_subdev_get_try_format(sd, cfg, 0); - src_code = &v4l2_subdev_get_try_format(sd, cfg, 1)->code; + sink_fmt = v4l2_subdev_get_try_format(sd, sd_state, 0); + src_code = &v4l2_subdev_get_try_format(sd, sd_state, 1)->code; } /* diff --git a/drivers/media/test-drivers/vimc/vimc-scaler.c b/drivers/media/test-drivers/vimc/vimc-scaler.c index 121fa7d62a2e..06880dd0b6ac 100644 --- a/drivers/media/test-drivers/vimc/vimc-scaler.c +++ b/drivers/media/test-drivers/vimc/vimc-scaler.c @@ -84,20 +84,20 @@ static void vimc_sca_adjust_sink_crop(struct v4l2_rect *r, } static int vimc_sca_init_cfg(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg) + struct v4l2_subdev_state *sd_state) { struct v4l2_mbus_framefmt *mf; struct v4l2_rect *r; unsigned int i; - mf = v4l2_subdev_get_try_format(sd, cfg, 0); + mf = v4l2_subdev_get_try_format(sd, sd_state, 0); *mf = sink_fmt_default; - r = v4l2_subdev_get_try_crop(sd, cfg, 0); + r = v4l2_subdev_get_try_crop(sd, sd_state, 0); *r = crop_rect_default; for (i = 1; i < sd->entity.num_pads; i++) { - mf = v4l2_subdev_get_try_format(sd, cfg, i); + mf = v4l2_subdev_get_try_format(sd, sd_state, i); *mf = sink_fmt_default; mf->width = mf->width * sca_mult; mf->height = mf->height * sca_mult; @@ -107,7 +107,7 @@ static int vimc_sca_init_cfg(struct v4l2_subdev *sd, } static int vimc_sca_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { u32 mbus_code = vimc_mbus_code_by_index(code->index); @@ -128,7 +128,7 @@ static int vimc_sca_enum_mbus_code(struct v4l2_subdev *sd, } static int vimc_sca_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { const struct vimc_pix_map *vpix; @@ -156,7 +156,7 @@ static int vimc_sca_enum_frame_size(struct v4l2_subdev *sd, } static int vimc_sca_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd); @@ -164,8 +164,8 @@ static int vimc_sca_get_fmt(struct v4l2_subdev *sd, /* Get the current sink format */ if (format->which == V4L2_SUBDEV_FORMAT_TRY) { - format->format = *v4l2_subdev_get_try_format(sd, cfg, 0); - crop_rect = v4l2_subdev_get_try_crop(sd, cfg, 0); + format->format = *v4l2_subdev_get_try_format(sd, sd_state, 0); + crop_rect = v4l2_subdev_get_try_crop(sd, sd_state, 0); } else { format->format = vsca->sink_fmt; crop_rect = &vsca->crop_rect; @@ -201,7 +201,7 @@ static void vimc_sca_adjust_sink_fmt(struct v4l2_mbus_framefmt *fmt) } static int vimc_sca_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd); @@ -216,8 +216,8 @@ static int vimc_sca_set_fmt(struct v4l2_subdev *sd, sink_fmt = &vsca->sink_fmt; crop_rect = &vsca->crop_rect; } else { - sink_fmt = v4l2_subdev_get_try_format(sd, cfg, 0); - crop_rect = v4l2_subdev_get_try_crop(sd, cfg, 0); + sink_fmt = v4l2_subdev_get_try_format(sd, sd_state, 0); + crop_rect = v4l2_subdev_get_try_crop(sd, sd_state, 0); } /* @@ -254,7 +254,7 @@ static int vimc_sca_set_fmt(struct v4l2_subdev *sd, } static int vimc_sca_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd); @@ -268,8 +268,8 @@ static int vimc_sca_get_selection(struct v4l2_subdev *sd, sink_fmt = &vsca->sink_fmt; crop_rect = &vsca->crop_rect; } else { - sink_fmt = v4l2_subdev_get_try_format(sd, cfg, 0); - crop_rect = v4l2_subdev_get_try_crop(sd, cfg, 0); + sink_fmt = v4l2_subdev_get_try_format(sd, sd_state, 0); + crop_rect = v4l2_subdev_get_try_crop(sd, sd_state, 0); } switch (sel->target) { @@ -287,7 +287,7 @@ static int vimc_sca_get_selection(struct v4l2_subdev *sd, } static int vimc_sca_set_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd); @@ -305,8 +305,8 @@ static int vimc_sca_set_selection(struct v4l2_subdev *sd, crop_rect = &vsca->crop_rect; sink_fmt = &vsca->sink_fmt; } else { - crop_rect = v4l2_subdev_get_try_crop(sd, cfg, 0); - sink_fmt = v4l2_subdev_get_try_format(sd, cfg, 0); + crop_rect = v4l2_subdev_get_try_crop(sd, sd_state, 0); + sink_fmt = v4l2_subdev_get_try_format(sd, sd_state, 0); } switch (sel->target) { diff --git a/drivers/media/test-drivers/vimc/vimc-sensor.c b/drivers/media/test-drivers/vimc/vimc-sensor.c index ba5db5a150b4..74ab79cadb5d 100644 --- a/drivers/media/test-drivers/vimc/vimc-sensor.c +++ b/drivers/media/test-drivers/vimc/vimc-sensor.c @@ -42,14 +42,14 @@ static const struct v4l2_mbus_framefmt fmt_default = { }; static int vimc_sen_init_cfg(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg) + struct v4l2_subdev_state *sd_state) { unsigned int i; for (i = 0; i < sd->entity.num_pads; i++) { struct v4l2_mbus_framefmt *mf; - mf = v4l2_subdev_get_try_format(sd, cfg, i); + mf = v4l2_subdev_get_try_format(sd, sd_state, i); *mf = fmt_default; } @@ -57,7 +57,7 @@ static int vimc_sen_init_cfg(struct v4l2_subdev *sd, } static int vimc_sen_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { u32 mbus_code = vimc_mbus_code_by_index(code->index); @@ -71,7 +71,7 @@ static int vimc_sen_enum_mbus_code(struct v4l2_subdev *sd, } static int vimc_sen_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { const struct vimc_pix_map *vpix; @@ -93,14 +93,14 @@ static int vimc_sen_enum_frame_size(struct v4l2_subdev *sd, } static int vimc_sen_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct vimc_sen_device *vsen = container_of(sd, struct vimc_sen_device, sd); fmt->format = fmt->which == V4L2_SUBDEV_FORMAT_TRY ? - *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) : + *v4l2_subdev_get_try_format(sd, sd_state, fmt->pad) : vsen->mbus_format; return 0; @@ -146,7 +146,7 @@ static void vimc_sen_adjust_fmt(struct v4l2_mbus_framefmt *fmt) } static int vimc_sen_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct vimc_sen_device *vsen = v4l2_get_subdevdata(sd); @@ -159,7 +159,7 @@ static int vimc_sen_set_fmt(struct v4l2_subdev *sd, mf = &vsen->mbus_format; } else { - mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + mf = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); } /* Set the new format */ diff --git a/drivers/media/usb/go7007/s2250-board.c b/drivers/media/usb/go7007/s2250-board.c index b9e45124673b..c742cc88fac5 100644 --- a/drivers/media/usb/go7007/s2250-board.c +++ b/drivers/media/usb/go7007/s2250-board.c @@ -398,7 +398,7 @@ static int s2250_s_ctrl(struct v4l2_ctrl *ctrl) } static int s2250_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *fmt = &format->format; diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index 956dafab43d4..6d3e03036519 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -26,19 +26,21 @@ #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) static int subdev_fh_init(struct v4l2_subdev_fh *fh, struct v4l2_subdev *sd) { - if (sd->entity.num_pads) { - fh->pad = v4l2_subdev_alloc_pad_config(sd); - if (fh->pad == NULL) - return -ENOMEM; - } + struct v4l2_subdev_state *state; + + state = v4l2_subdev_alloc_state(sd); + if (IS_ERR(state)) + return PTR_ERR(state); + + fh->state = state; return 0; } static void subdev_fh_free(struct v4l2_subdev_fh *fh) { - v4l2_subdev_free_pad_config(fh->pad); - fh->pad = NULL; + v4l2_subdev_free_state(fh->state); + fh->state = NULL; } static int subdev_open(struct file *file) @@ -146,63 +148,63 @@ static inline int check_pad(struct v4l2_subdev *sd, u32 pad) return 0; } -static int check_cfg(u32 which, struct v4l2_subdev_pad_config *cfg) +static int check_state_pads(u32 which, struct v4l2_subdev_state *state) { - if (which == V4L2_SUBDEV_FORMAT_TRY && !cfg) + if (which == V4L2_SUBDEV_FORMAT_TRY && (!state || !state->pads)) return -EINVAL; return 0; } static inline int check_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *state, struct v4l2_subdev_format *format) { if (!format) return -EINVAL; return check_which(format->which) ? : check_pad(sd, format->pad) ? : - check_cfg(format->which, cfg); + check_state_pads(format->which, state); } static int call_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *state, struct v4l2_subdev_format *format) { - return check_format(sd, cfg, format) ? : - sd->ops->pad->get_fmt(sd, cfg, format); + return check_format(sd, state, format) ? : + sd->ops->pad->get_fmt(sd, state, format); } static int call_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *state, struct v4l2_subdev_format *format) { - return check_format(sd, cfg, format) ? : - sd->ops->pad->set_fmt(sd, cfg, format); + return check_format(sd, state, format) ? : + sd->ops->pad->set_fmt(sd, state, format); } static int call_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *state, struct v4l2_subdev_mbus_code_enum *code) { if (!code) return -EINVAL; return check_which(code->which) ? : check_pad(sd, code->pad) ? : - check_cfg(code->which, cfg) ? : - sd->ops->pad->enum_mbus_code(sd, cfg, code); + check_state_pads(code->which, state) ? : + sd->ops->pad->enum_mbus_code(sd, state, code); } static int call_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *state, struct v4l2_subdev_frame_size_enum *fse) { if (!fse) return -EINVAL; return check_which(fse->which) ? : check_pad(sd, fse->pad) ? : - check_cfg(fse->which, cfg) ? : - sd->ops->pad->enum_frame_size(sd, cfg, fse); + check_state_pads(fse->which, state) ? : + sd->ops->pad->enum_frame_size(sd, state, fse); } static inline int check_frame_interval(struct v4l2_subdev *sd, @@ -229,42 +231,42 @@ static int call_s_frame_interval(struct v4l2_subdev *sd, } static int call_enum_frame_interval(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *state, struct v4l2_subdev_frame_interval_enum *fie) { if (!fie) return -EINVAL; return check_which(fie->which) ? : check_pad(sd, fie->pad) ? : - check_cfg(fie->which, cfg) ? : - sd->ops->pad->enum_frame_interval(sd, cfg, fie); + check_state_pads(fie->which, state) ? : + sd->ops->pad->enum_frame_interval(sd, state, fie); } static inline int check_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *state, struct v4l2_subdev_selection *sel) { if (!sel) return -EINVAL; return check_which(sel->which) ? : check_pad(sd, sel->pad) ? : - check_cfg(sel->which, cfg); + check_state_pads(sel->which, state); } static int call_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *state, struct v4l2_subdev_selection *sel) { - return check_selection(sd, cfg, sel) ? : - sd->ops->pad->get_selection(sd, cfg, sel); + return check_selection(sd, state, sel) ? : + sd->ops->pad->get_selection(sd, state, sel); } static int call_set_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *state, struct v4l2_subdev_selection *sel) { - return check_selection(sd, cfg, sel) ? : - sd->ops->pad->set_selection(sd, cfg, sel); + return check_selection(sd, state, sel) ? : + sd->ops->pad->set_selection(sd, state, sel); } static inline int check_edid(struct v4l2_subdev *sd, @@ -506,7 +508,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) memset(format->reserved, 0, sizeof(format->reserved)); memset(format->format.reserved, 0, sizeof(format->format.reserved)); - return v4l2_subdev_call(sd, pad, get_fmt, subdev_fh->pad, format); + return v4l2_subdev_call(sd, pad, get_fmt, subdev_fh->state, format); } case VIDIOC_SUBDEV_S_FMT: { @@ -517,7 +519,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) memset(format->reserved, 0, sizeof(format->reserved)); memset(format->format.reserved, 0, sizeof(format->format.reserved)); - return v4l2_subdev_call(sd, pad, set_fmt, subdev_fh->pad, format); + return v4l2_subdev_call(sd, pad, set_fmt, subdev_fh->state, format); } case VIDIOC_SUBDEV_G_CROP: { @@ -531,7 +533,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) sel.target = V4L2_SEL_TGT_CROP; rval = v4l2_subdev_call( - sd, pad, get_selection, subdev_fh->pad, &sel); + sd, pad, get_selection, subdev_fh->state, &sel); crop->rect = sel.r; @@ -553,7 +555,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) sel.r = crop->rect; rval = v4l2_subdev_call( - sd, pad, set_selection, subdev_fh->pad, &sel); + sd, pad, set_selection, subdev_fh->state, &sel); crop->rect = sel.r; @@ -564,7 +566,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) struct v4l2_subdev_mbus_code_enum *code = arg; memset(code->reserved, 0, sizeof(code->reserved)); - return v4l2_subdev_call(sd, pad, enum_mbus_code, subdev_fh->pad, + return v4l2_subdev_call(sd, pad, enum_mbus_code, subdev_fh->state, code); } @@ -572,7 +574,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) struct v4l2_subdev_frame_size_enum *fse = arg; memset(fse->reserved, 0, sizeof(fse->reserved)); - return v4l2_subdev_call(sd, pad, enum_frame_size, subdev_fh->pad, + return v4l2_subdev_call(sd, pad, enum_frame_size, subdev_fh->state, fse); } @@ -597,7 +599,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) struct v4l2_subdev_frame_interval_enum *fie = arg; memset(fie->reserved, 0, sizeof(fie->reserved)); - return v4l2_subdev_call(sd, pad, enum_frame_interval, subdev_fh->pad, + return v4l2_subdev_call(sd, pad, enum_frame_interval, subdev_fh->state, fie); } @@ -606,7 +608,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) memset(sel->reserved, 0, sizeof(sel->reserved)); return v4l2_subdev_call( - sd, pad, get_selection, subdev_fh->pad, sel); + sd, pad, get_selection, subdev_fh->state, sel); } case VIDIOC_SUBDEV_S_SELECTION: { @@ -617,7 +619,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) memset(sel->reserved, 0, sizeof(sel->reserved)); return v4l2_subdev_call( - sd, pad, set_selection, subdev_fh->pad, sel); + sd, pad, set_selection, subdev_fh->state, sel); } case VIDIOC_G_EDID: { @@ -892,35 +894,51 @@ int v4l2_subdev_link_validate(struct media_link *link) } EXPORT_SYMBOL_GPL(v4l2_subdev_link_validate); -struct v4l2_subdev_pad_config * -v4l2_subdev_alloc_pad_config(struct v4l2_subdev *sd) +struct v4l2_subdev_state *v4l2_subdev_alloc_state(struct v4l2_subdev *sd) { - struct v4l2_subdev_pad_config *cfg; + struct v4l2_subdev_state *state; int ret; - if (!sd->entity.num_pads) - return NULL; + state = kzalloc(sizeof(*state), GFP_KERNEL); + if (!state) + return ERR_PTR(-ENOMEM); - cfg = kvmalloc_array(sd->entity.num_pads, sizeof(*cfg), - GFP_KERNEL | __GFP_ZERO); - if (!cfg) - return NULL; - - ret = v4l2_subdev_call(sd, pad, init_cfg, cfg); - if (ret < 0 && ret != -ENOIOCTLCMD) { - kvfree(cfg); - return NULL; + if (sd->entity.num_pads) { + state->pads = kvmalloc_array(sd->entity.num_pads, + sizeof(*state->pads), + GFP_KERNEL | __GFP_ZERO); + if (!state->pads) { + ret = -ENOMEM; + goto err; + } } - return cfg; -} -EXPORT_SYMBOL_GPL(v4l2_subdev_alloc_pad_config); + ret = v4l2_subdev_call(sd, pad, init_cfg, state); + if (ret < 0 && ret != -ENOIOCTLCMD) + goto err; -void v4l2_subdev_free_pad_config(struct v4l2_subdev_pad_config *cfg) -{ - kvfree(cfg); + return state; + +err: + if (state && state->pads) + kvfree(state->pads); + + kfree(state); + + return ERR_PTR(ret); } -EXPORT_SYMBOL_GPL(v4l2_subdev_free_pad_config); +EXPORT_SYMBOL_GPL(v4l2_subdev_alloc_state); + +void v4l2_subdev_free_state(struct v4l2_subdev_state *state) +{ + if (!state) + return; + + kvfree(state->pads); + kfree(state); +} +EXPORT_SYMBOL_GPL(v4l2_subdev_free_state); + #endif /* CONFIG_MEDIA_CONTROLLER */ void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops) diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c index 6c5a378a2eb5..687888d643df 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c @@ -965,7 +965,7 @@ static int startup(struct v4l2_subdev *sd) } static int gc0310_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *fmt = &format->format; @@ -999,7 +999,7 @@ static int gc0310_set_fmt(struct v4l2_subdev *sd, fmt->code = MEDIA_BUS_FMT_SGRBG8_1X8; if (format->which == V4L2_SUBDEV_FORMAT_TRY) { - cfg->try_fmt = *fmt; + sd_state->pads->try_fmt = *fmt; mutex_unlock(&dev->input_lock); return 0; } @@ -1032,7 +1032,7 @@ err: } static int gc0310_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *fmt = &format->format; @@ -1205,7 +1205,7 @@ static int gc0310_g_frame_interval(struct v4l2_subdev *sd, } static int gc0310_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->index >= MAX_FMTS) @@ -1216,7 +1216,7 @@ static int gc0310_enum_mbus_code(struct v4l2_subdev *sd, } static int gc0310_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { int index = fse->index; diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c index 38defa0f8151..9363c1a52ae9 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c @@ -769,7 +769,7 @@ static int startup(struct v4l2_subdev *sd) } static int gc2235_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *fmt = &format->format; @@ -798,7 +798,7 @@ static int gc2235_set_fmt(struct v4l2_subdev *sd, } fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; if (format->which == V4L2_SUBDEV_FORMAT_TRY) { - cfg->try_fmt = *fmt; + sd_state->pads->try_fmt = *fmt; mutex_unlock(&dev->input_lock); return 0; } @@ -827,7 +827,7 @@ err: } static int gc2235_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *fmt = &format->format; @@ -966,7 +966,7 @@ static int gc2235_g_frame_interval(struct v4l2_subdev *sd, } static int gc2235_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->index >= MAX_FMTS) @@ -977,7 +977,7 @@ static int gc2235_enum_mbus_code(struct v4l2_subdev *sd, } static int gc2235_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { int index = fse->index; diff --git a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c index 0a6f8f68b215..11196180a206 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c @@ -803,7 +803,7 @@ static int mt9m114_get_intg_factor(struct i2c_client *client, } static int mt9m114_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *fmt = &format->format; @@ -824,7 +824,7 @@ static int mt9m114_get_fmt(struct v4l2_subdev *sd, } static int mt9m114_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *fmt = &format->format; @@ -848,7 +848,7 @@ static int mt9m114_set_fmt(struct v4l2_subdev *sd, mt9m114_try_res(&width, &height); if (format->which == V4L2_SUBDEV_FORMAT_TRY) { - cfg->try_fmt = *fmt; + sd_state->pads->try_fmt = *fmt; return 0; } res_index = mt9m114_to_res(width, height); @@ -1168,7 +1168,7 @@ static int mt9m114_s_exposure_metering(struct v4l2_subdev *sd, s32 val) * This function is for touch exposure feature. */ static int mt9m114_s_exposure_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -1731,7 +1731,7 @@ static int mt9m114_s_stream(struct v4l2_subdev *sd, int enable) } static int mt9m114_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->index) @@ -1742,7 +1742,7 @@ static int mt9m114_enum_mbus_code(struct v4l2_subdev *sd, } static int mt9m114_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { unsigned int index = fse->index; diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c index eb1ecd198c22..2111e4a478c1 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c @@ -914,7 +914,7 @@ static int get_resolution_index(int w, int h) } static int ov2680_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *fmt = &format->format; @@ -951,7 +951,7 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd, } fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10; if (format->which == V4L2_SUBDEV_FORMAT_TRY) { - cfg->try_fmt = *fmt; + sd_state->pads->try_fmt = *fmt; mutex_unlock(&dev->input_lock); return 0; } @@ -1002,7 +1002,7 @@ err: } static int ov2680_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *fmt = &format->format; @@ -1161,7 +1161,7 @@ static int ov2680_g_frame_interval(struct v4l2_subdev *sd, } static int ov2680_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->index >= MAX_FMTS) @@ -1172,7 +1172,7 @@ static int ov2680_enum_mbus_code(struct v4l2_subdev *sd, } static int ov2680_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { int index = fse->index; diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c index 90a985ee25fa..90d0871a78a3 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c @@ -876,7 +876,7 @@ static int startup(struct v4l2_subdev *sd) } static int ov2722_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *fmt = &format->format; @@ -906,7 +906,7 @@ static int ov2722_set_fmt(struct v4l2_subdev *sd, } fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; if (format->which == V4L2_SUBDEV_FORMAT_TRY) { - cfg->try_fmt = *fmt; + sd_state->pads->try_fmt = *fmt; mutex_unlock(&dev->input_lock); return 0; } @@ -961,7 +961,7 @@ err: } static int ov2722_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *fmt = &format->format; @@ -1104,7 +1104,7 @@ static int ov2722_g_frame_interval(struct v4l2_subdev *sd, } static int ov2722_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->index >= MAX_FMTS) @@ -1115,7 +1115,7 @@ static int ov2722_enum_mbus_code(struct v4l2_subdev *sd, } static int ov2722_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { int index = fse->index; diff --git a/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c b/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c index e698b63d6cb7..0828ca9ab6f2 100644 --- a/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c +++ b/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c @@ -1577,7 +1577,7 @@ static int startup(struct v4l2_subdev *sd) } static int ov5693_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *fmt = &format->format; @@ -1608,7 +1608,7 @@ static int ov5693_set_fmt(struct v4l2_subdev *sd, fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10; if (format->which == V4L2_SUBDEV_FORMAT_TRY) { - cfg->try_fmt = *fmt; + sd_state->pads->try_fmt = *fmt; mutex_unlock(&dev->input_lock); return 0; } @@ -1676,7 +1676,7 @@ err: } static int ov5693_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *fmt = &format->format; @@ -1825,7 +1825,7 @@ static int ov5693_g_frame_interval(struct v4l2_subdev *sd, } static int ov5693_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->index >= MAX_FMTS) @@ -1836,7 +1836,7 @@ static int ov5693_enum_mbus_code(struct v4l2_subdev *sd, } static int ov5693_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { int index = fse->index; diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp_cmd.c index 24d8eaccb9c6..366161cff560 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c +++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c @@ -4842,6 +4842,9 @@ int atomisp_try_fmt(struct video_device *vdev, struct v4l2_pix_format *f, struct atomisp_device *isp = video_get_drvdata(vdev); struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; struct v4l2_subdev_pad_config pad_cfg; + struct v4l2_subdev_state pad_state = { + .pads = &pad_cfg + }; struct v4l2_subdev_format format = { .which = V4L2_SUBDEV_FORMAT_TRY, }; @@ -4877,7 +4880,7 @@ int atomisp_try_fmt(struct video_device *vdev, struct v4l2_pix_format *f, snr_mbus_fmt->width, snr_mbus_fmt->height); ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, - pad, set_fmt, &pad_cfg, &format); + pad, set_fmt, &pad_state, &format); if (ret) return ret; @@ -5252,11 +5255,11 @@ static int atomisp_set_fmt_to_isp(struct video_device *vdev, atomisp_output_fmts[] in atomisp_v4l2.c */ vf_ffmt.code = V4L2_MBUS_FMT_CUSTOM_YUV420; - atomisp_subdev_set_selection(&asd->subdev, fh.pad, + atomisp_subdev_set_selection(&asd->subdev, fh.state, V4L2_SUBDEV_FORMAT_ACTIVE, ATOMISP_SUBDEV_PAD_SOURCE_VF, V4L2_SEL_TGT_COMPOSE, 0, &vf_size); - atomisp_subdev_set_ffmt(&asd->subdev, fh.pad, + atomisp_subdev_set_ffmt(&asd->subdev, fh.state, V4L2_SUBDEV_FORMAT_ACTIVE, ATOMISP_SUBDEV_PAD_SOURCE_VF, &vf_ffmt); asd->video_out_vf.sh_fmt = IA_CSS_FRAME_FORMAT_NV12; @@ -5493,6 +5496,9 @@ static int atomisp_set_fmt_to_snr(struct video_device *vdev, struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; const struct atomisp_format_bridge *format; struct v4l2_subdev_pad_config pad_cfg; + struct v4l2_subdev_state pad_state = { + .pads = &pad_cfg + }; struct v4l2_subdev_format vformat = { .which = V4L2_SUBDEV_FORMAT_TRY, }; @@ -5531,7 +5537,7 @@ static int atomisp_set_fmt_to_snr(struct video_device *vdev, source_pad == ATOMISP_SUBDEV_PAD_SOURCE_VIDEO) { vformat.which = V4L2_SUBDEV_FORMAT_TRY; ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, - pad, set_fmt, &pad_cfg, &vformat); + pad, set_fmt, &pad_state, &vformat); if (ret) return ret; if (ffmt->width < req_ffmt->width || @@ -5569,7 +5575,7 @@ static int atomisp_set_fmt_to_snr(struct video_device *vdev, asd->params.video_dis_en = false; } - atomisp_subdev_set_ffmt(&asd->subdev, fh.pad, + atomisp_subdev_set_ffmt(&asd->subdev, fh.state, V4L2_SUBDEV_FORMAT_ACTIVE, ATOMISP_SUBDEV_PAD_SINK, ffmt); @@ -5648,7 +5654,7 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f) } atomisp_subdev_set_selection( - &asd->subdev, fh.pad, + &asd->subdev, fh.state, V4L2_SUBDEV_FORMAT_ACTIVE, source_pad, V4L2_SEL_TGT_COMPOSE, 0, &r); @@ -5778,7 +5784,7 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f) ATOMISP_SUBDEV_PAD_SINK); isp_source_fmt.code = format_bridge->mbus_code; - atomisp_subdev_set_ffmt(&asd->subdev, fh.pad, + atomisp_subdev_set_ffmt(&asd->subdev, fh.state, V4L2_SUBDEV_FORMAT_ACTIVE, source_pad, &isp_source_fmt); @@ -5897,13 +5903,13 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f) isp_sink_crop.height = f->fmt.pix.height; } - atomisp_subdev_set_selection(&asd->subdev, fh.pad, + atomisp_subdev_set_selection(&asd->subdev, fh.state, V4L2_SUBDEV_FORMAT_ACTIVE, ATOMISP_SUBDEV_PAD_SINK, V4L2_SEL_TGT_CROP, V4L2_SEL_FLAG_KEEP_CONFIG, &isp_sink_crop); - atomisp_subdev_set_selection(&asd->subdev, fh.pad, + atomisp_subdev_set_selection(&asd->subdev, fh.state, V4L2_SUBDEV_FORMAT_ACTIVE, source_pad, V4L2_SEL_TGT_COMPOSE, 0, &isp_sink_crop); @@ -5922,7 +5928,7 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f) f->fmt.pix.height); } - atomisp_subdev_set_selection(&asd->subdev, fh.pad, + atomisp_subdev_set_selection(&asd->subdev, fh.state, V4L2_SUBDEV_FORMAT_ACTIVE, source_pad, V4L2_SEL_TGT_COMPOSE, 0, @@ -5956,14 +5962,14 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f) f->fmt.pix.width, ATOM_ISP_STEP_HEIGHT); } - atomisp_subdev_set_selection(&asd->subdev, fh.pad, + atomisp_subdev_set_selection(&asd->subdev, fh.state, V4L2_SUBDEV_FORMAT_ACTIVE, ATOMISP_SUBDEV_PAD_SINK, V4L2_SEL_TGT_CROP, V4L2_SEL_FLAG_KEEP_CONFIG, &sink_crop); } - atomisp_subdev_set_selection(&asd->subdev, fh.pad, + atomisp_subdev_set_selection(&asd->subdev, fh.state, V4L2_SUBDEV_FORMAT_ACTIVE, source_pad, V4L2_SEL_TGT_COMPOSE, 0, @@ -6054,7 +6060,8 @@ int atomisp_set_fmt_file(struct video_device *vdev, struct v4l2_format *f) ffmt.height = f->fmt.pix.height; ffmt.code = format_bridge->mbus_code; - atomisp_subdev_set_ffmt(&asd->subdev, fh.pad, V4L2_SUBDEV_FORMAT_ACTIVE, + atomisp_subdev_set_ffmt(&asd->subdev, fh.state, + V4L2_SUBDEV_FORMAT_ACTIVE, ATOMISP_SUBDEV_PAD_SINK, &ffmt); return 0; diff --git a/drivers/staging/media/atomisp/pci/atomisp_csi2.c b/drivers/staging/media/atomisp/pci/atomisp_csi2.c index 060b8765ae96..56456e59bf89 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_csi2.c +++ b/drivers/staging/media/atomisp/pci/atomisp_csi2.c @@ -25,13 +25,13 @@ static struct v4l2_mbus_framefmt *__csi2_get_format(struct atomisp_mipi_csi2_device * csi2, - struct - v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, enum v4l2_subdev_format_whence which, unsigned int pad) { if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_format(&csi2->subdev, cfg, pad); + return v4l2_subdev_get_try_format(&csi2->subdev, sd_state, + pad); else return &csi2->formats[pad]; } @@ -44,7 +44,7 @@ static struct v4l2_mbus_framefmt *__csi2_get_format(struct * return -EINVAL or zero on success */ static int csi2_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { const struct atomisp_in_fmt_conv *ic = atomisp_in_fmt_conv; @@ -70,13 +70,13 @@ static int csi2_enum_mbus_code(struct v4l2_subdev *sd, * return -EINVAL or zero on success */ static int csi2_get_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct atomisp_mipi_csi2_device *csi2 = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *format; - format = __csi2_get_format(csi2, cfg, fmt->which, fmt->pad); + format = __csi2_get_format(csi2, sd_state, fmt->which, fmt->pad); fmt->format = *format; @@ -84,12 +84,14 @@ static int csi2_get_format(struct v4l2_subdev *sd, } int atomisp_csi2_set_ffmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int which, uint16_t pad, struct v4l2_mbus_framefmt *ffmt) { struct atomisp_mipi_csi2_device *csi2 = v4l2_get_subdevdata(sd); - struct v4l2_mbus_framefmt *actual_ffmt = __csi2_get_format(csi2, cfg, which, pad); + struct v4l2_mbus_framefmt *actual_ffmt = __csi2_get_format(csi2, + sd_state, + which, pad); if (pad == CSI2_PAD_SINK) { const struct atomisp_in_fmt_conv *ic; @@ -110,12 +112,14 @@ int atomisp_csi2_set_ffmt(struct v4l2_subdev *sd, tmp_ffmt = *ffmt = *actual_ffmt; - return atomisp_csi2_set_ffmt(sd, cfg, which, CSI2_PAD_SOURCE, + return atomisp_csi2_set_ffmt(sd, sd_state, which, + CSI2_PAD_SOURCE, &tmp_ffmt); } /* FIXME: DPCM decompression */ - *actual_ffmt = *ffmt = *__csi2_get_format(csi2, cfg, which, CSI2_PAD_SINK); + *actual_ffmt = *ffmt = *__csi2_get_format(csi2, sd_state, which, + CSI2_PAD_SINK); return 0; } @@ -129,10 +133,10 @@ int atomisp_csi2_set_ffmt(struct v4l2_subdev *sd, * return -EINVAL or zero on success */ static int csi2_set_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { - return atomisp_csi2_set_ffmt(sd, cfg, fmt->which, fmt->pad, + return atomisp_csi2_set_ffmt(sd, sd_state, fmt->which, fmt->pad, &fmt->format); } diff --git a/drivers/staging/media/atomisp/pci/atomisp_csi2.h b/drivers/staging/media/atomisp/pci/atomisp_csi2.h index 59261e8f1a1a..e35711be8a37 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_csi2.h +++ b/drivers/staging/media/atomisp/pci/atomisp_csi2.h @@ -44,7 +44,7 @@ struct atomisp_mipi_csi2_device { }; int atomisp_csi2_set_ffmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int which, uint16_t pad, struct v4l2_mbus_framefmt *ffmt); int atomisp_mipi_csi2_init(struct atomisp_device *isp); diff --git a/drivers/staging/media/atomisp/pci/atomisp_file.c b/drivers/staging/media/atomisp/pci/atomisp_file.c index e568ca99c45a..4570a9ab100b 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_file.c +++ b/drivers/staging/media/atomisp/pci/atomisp_file.c @@ -80,7 +80,7 @@ static int file_input_s_stream(struct v4l2_subdev *sd, int enable) } static int file_input_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *fmt = &format->format; @@ -104,16 +104,16 @@ static int file_input_get_fmt(struct v4l2_subdev *sd, } static int file_input_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *fmt = &format->format; if (format->pad) return -EINVAL; - file_input_get_fmt(sd, cfg, format); + file_input_get_fmt(sd, sd_state, format); if (format->which == V4L2_SUBDEV_FORMAT_TRY) - cfg->try_fmt = *fmt; + sd_state->pads->try_fmt = *fmt; return 0; } @@ -130,7 +130,7 @@ static int file_input_s_power(struct v4l2_subdev *sd, int on) } static int file_input_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { /*to fake*/ @@ -138,7 +138,7 @@ static int file_input_enum_mbus_code(struct v4l2_subdev *sd, } static int file_input_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { /*to fake*/ @@ -146,7 +146,7 @@ static int file_input_enum_frame_size(struct v4l2_subdev *sd, } static int file_input_enum_frame_ival(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_interval_enum *fie) { diff --git a/drivers/staging/media/atomisp/pci/atomisp_fops.c b/drivers/staging/media/atomisp/pci/atomisp_fops.c index 26d05474a035..022efd4151c0 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_fops.c +++ b/drivers/staging/media/atomisp/pci/atomisp_fops.c @@ -963,7 +963,7 @@ static int atomisp_release(struct file *file) if (!isp->sw_contex.file_input && asd->fmt_auto->val) { struct v4l2_mbus_framefmt isp_sink_fmt = { 0 }; - atomisp_subdev_set_ffmt(&asd->subdev, fh.pad, + atomisp_subdev_set_ffmt(&asd->subdev, fh.state, V4L2_SUBDEV_FORMAT_ACTIVE, ATOMISP_SUBDEV_PAD_SINK, &isp_sink_fmt); } @@ -975,7 +975,7 @@ subdev_uninit: if (isp->sw_contex.file_input && asd->fmt_auto->val) { struct v4l2_mbus_framefmt isp_sink_fmt = { 0 }; - atomisp_subdev_set_ffmt(&asd->subdev, fh.pad, + atomisp_subdev_set_ffmt(&asd->subdev, fh.state, V4L2_SUBDEV_FORMAT_ACTIVE, ATOMISP_SUBDEV_PAD_SINK, &isp_sink_fmt); } @@ -1016,7 +1016,7 @@ subdev_uninit: done: if (!acc_node) { - atomisp_subdev_set_selection(&asd->subdev, fh.pad, + atomisp_subdev_set_selection(&asd->subdev, fh.state, V4L2_SUBDEV_FORMAT_ACTIVE, atomisp_subdev_source_pad(vdev), V4L2_SEL_TGT_COMPOSE, 0, diff --git a/drivers/staging/media/atomisp/pci/atomisp_subdev.c b/drivers/staging/media/atomisp/pci/atomisp_subdev.c index aeabd07bf518..12f22ad007c7 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_subdev.c +++ b/drivers/staging/media/atomisp/pci/atomisp_subdev.c @@ -213,7 +213,7 @@ static int isp_subdev_unsubscribe_event(struct v4l2_subdev *sd, * return -EINVAL or zero on success */ static int isp_subdev_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->index >= ARRAY_SIZE(atomisp_in_fmt_conv) - 1) @@ -246,7 +246,7 @@ static int isp_subdev_validate_rect(struct v4l2_subdev *sd, uint32_t pad, } struct v4l2_rect *atomisp_subdev_get_rect(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, u32 which, uint32_t pad, uint32_t target) { @@ -255,9 +255,9 @@ struct v4l2_rect *atomisp_subdev_get_rect(struct v4l2_subdev *sd, if (which == V4L2_SUBDEV_FORMAT_TRY) { switch (target) { case V4L2_SEL_TGT_CROP: - return v4l2_subdev_get_try_crop(sd, cfg, pad); + return v4l2_subdev_get_try_crop(sd, sd_state, pad); case V4L2_SEL_TGT_COMPOSE: - return v4l2_subdev_get_try_compose(sd, cfg, pad); + return v4l2_subdev_get_try_compose(sd, sd_state, pad); } } @@ -273,19 +273,20 @@ struct v4l2_rect *atomisp_subdev_get_rect(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *atomisp_subdev_get_ffmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, uint32_t which, + struct v4l2_subdev_state *sd_state, uint32_t which, uint32_t pad) { struct atomisp_sub_device *isp_sd = v4l2_get_subdevdata(sd); if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_format(sd, cfg, pad); + return v4l2_subdev_get_try_format(sd, sd_state, pad); return &isp_sd->fmt[pad].fmt; } static void isp_get_fmt_rect(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, uint32_t which, + struct v4l2_subdev_state *sd_state, + uint32_t which, struct v4l2_mbus_framefmt **ffmt, struct v4l2_rect *crop[ATOMISP_SUBDEV_PADS_NUM], struct v4l2_rect *comp[ATOMISP_SUBDEV_PADS_NUM]) @@ -293,16 +294,16 @@ static void isp_get_fmt_rect(struct v4l2_subdev *sd, unsigned int i; for (i = 0; i < ATOMISP_SUBDEV_PADS_NUM; i++) { - ffmt[i] = atomisp_subdev_get_ffmt(sd, cfg, which, i); - crop[i] = atomisp_subdev_get_rect(sd, cfg, which, i, + ffmt[i] = atomisp_subdev_get_ffmt(sd, sd_state, which, i); + crop[i] = atomisp_subdev_get_rect(sd, sd_state, which, i, V4L2_SEL_TGT_CROP); - comp[i] = atomisp_subdev_get_rect(sd, cfg, which, i, + comp[i] = atomisp_subdev_get_rect(sd, sd_state, which, i, V4L2_SEL_TGT_COMPOSE); } } static void isp_subdev_propagate(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, u32 which, uint32_t pad, uint32_t target, uint32_t flags) { @@ -313,7 +314,7 @@ static void isp_subdev_propagate(struct v4l2_subdev *sd, if (flags & V4L2_SEL_FLAG_KEEP_CONFIG) return; - isp_get_fmt_rect(sd, cfg, which, ffmt, crop, comp); + isp_get_fmt_rect(sd, sd_state, which, ffmt, crop, comp); switch (pad) { case ATOMISP_SUBDEV_PAD_SINK: { @@ -323,7 +324,7 @@ static void isp_subdev_propagate(struct v4l2_subdev *sd, r.width = ffmt[pad]->width; r.height = ffmt[pad]->height; - atomisp_subdev_set_selection(sd, cfg, which, pad, + atomisp_subdev_set_selection(sd, sd_state, which, pad, target, flags, &r); break; } @@ -331,7 +332,7 @@ static void isp_subdev_propagate(struct v4l2_subdev *sd, } static int isp_subdev_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct v4l2_rect *rec; @@ -340,7 +341,7 @@ static int isp_subdev_get_selection(struct v4l2_subdev *sd, if (rval) return rval; - rec = atomisp_subdev_get_rect(sd, cfg, sel->which, sel->pad, + rec = atomisp_subdev_get_rect(sd, sd_state, sel->which, sel->pad, sel->target); if (!rec) return -EINVAL; @@ -365,7 +366,7 @@ static const char *atomisp_pad_str(unsigned int pad) } int atomisp_subdev_set_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, u32 which, uint32_t pad, uint32_t target, u32 flags, struct v4l2_rect *r) { @@ -382,7 +383,7 @@ int atomisp_subdev_set_selection(struct v4l2_subdev *sd, stream_id = atomisp_source_pad_to_stream_id(isp_sd, vdev_pad); - isp_get_fmt_rect(sd, cfg, which, ffmt, crop, comp); + isp_get_fmt_rect(sd, sd_state, which, ffmt, crop, comp); dev_dbg(isp->dev, "sel: pad %s tgt %s l %d t %d w %d h %d which %s f 0x%8.8x\n", @@ -450,7 +451,8 @@ int atomisp_subdev_set_selection(struct v4l2_subdev *sd, struct v4l2_rect tmp = *crop[pad]; atomisp_subdev_set_selection( - sd, cfg, which, i, V4L2_SEL_TGT_COMPOSE, + sd, sd_state, which, i, + V4L2_SEL_TGT_COMPOSE, flags, &tmp); } } @@ -551,9 +553,9 @@ int atomisp_subdev_set_selection(struct v4l2_subdev *sd, ffmt[pad]->height = comp[pad]->height; } - if (!atomisp_subdev_get_rect(sd, cfg, which, pad, target)) + if (!atomisp_subdev_get_rect(sd, sd_state, which, pad, target)) return -EINVAL; - *r = *atomisp_subdev_get_rect(sd, cfg, which, pad, target); + *r = *atomisp_subdev_get_rect(sd, sd_state, which, pad, target); dev_dbg(isp->dev, "sel actual: l %d t %d w %d h %d\n", r->left, r->top, r->width, r->height); @@ -562,7 +564,7 @@ int atomisp_subdev_set_selection(struct v4l2_subdev *sd, } static int isp_subdev_set_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { int rval = isp_subdev_validate_rect(sd, sel->pad, sel->target); @@ -570,7 +572,8 @@ static int isp_subdev_set_selection(struct v4l2_subdev *sd, if (rval) return rval; - return atomisp_subdev_set_selection(sd, cfg, sel->which, sel->pad, + return atomisp_subdev_set_selection(sd, sd_state, sel->which, + sel->pad, sel->target, sel->flags, &sel->r); } @@ -609,13 +612,14 @@ static int atomisp_get_sensor_bin_factor(struct atomisp_sub_device *asd) } void atomisp_subdev_set_ffmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, uint32_t which, + struct v4l2_subdev_state *sd_state, + uint32_t which, u32 pad, struct v4l2_mbus_framefmt *ffmt) { struct atomisp_sub_device *isp_sd = v4l2_get_subdevdata(sd); struct atomisp_device *isp = isp_sd->isp; struct v4l2_mbus_framefmt *__ffmt = - atomisp_subdev_get_ffmt(sd, cfg, which, pad); + atomisp_subdev_get_ffmt(sd, sd_state, which, pad); u16 vdev_pad = atomisp_subdev_source_pad(sd->devnode); enum atomisp_input_stream_id stream_id; @@ -640,7 +644,7 @@ void atomisp_subdev_set_ffmt(struct v4l2_subdev *sd, *__ffmt = *ffmt; - isp_subdev_propagate(sd, cfg, which, pad, + isp_subdev_propagate(sd, sd_state, which, pad, V4L2_SEL_TGT_CROP, 0); if (which == V4L2_SUBDEV_FORMAT_ACTIVE) { @@ -679,10 +683,11 @@ void atomisp_subdev_set_ffmt(struct v4l2_subdev *sd, * to the format type. */ static int isp_subdev_get_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { - fmt->format = *atomisp_subdev_get_ffmt(sd, cfg, fmt->which, fmt->pad); + fmt->format = *atomisp_subdev_get_ffmt(sd, sd_state, fmt->which, + fmt->pad); return 0; } @@ -698,10 +703,11 @@ static int isp_subdev_get_format(struct v4l2_subdev *sd, * to the format type. */ static int isp_subdev_set_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { - atomisp_subdev_set_ffmt(sd, cfg, fmt->which, fmt->pad, &fmt->format); + atomisp_subdev_set_ffmt(sd, sd_state, fmt->which, fmt->pad, + &fmt->format); return 0; } diff --git a/drivers/staging/media/atomisp/pci/atomisp_subdev.h b/drivers/staging/media/atomisp/pci/atomisp_subdev.h index 330a77eed8aa..d6fcfab6352d 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_subdev.h +++ b/drivers/staging/media/atomisp/pci/atomisp_subdev.h @@ -437,19 +437,20 @@ uint16_t atomisp_subdev_source_pad(struct video_device *vdev); /* Get pointer to appropriate format */ struct v4l2_mbus_framefmt *atomisp_subdev_get_ffmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, uint32_t which, + struct v4l2_subdev_state *sd_state, uint32_t which, uint32_t pad); struct v4l2_rect *atomisp_subdev_get_rect(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, u32 which, uint32_t pad, uint32_t target); int atomisp_subdev_set_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, u32 which, uint32_t pad, uint32_t target, u32 flags, struct v4l2_rect *r); /* Actually set the format */ void atomisp_subdev_set_ffmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, uint32_t which, + struct v4l2_subdev_state *sd_state, + uint32_t which, u32 pad, struct v4l2_mbus_framefmt *ffmt); int atomisp_update_run_mode(struct atomisp_sub_device *asd); diff --git a/drivers/staging/media/atomisp/pci/atomisp_tpg.c b/drivers/staging/media/atomisp/pci/atomisp_tpg.c index 1def80bab180..e29a96da5f98 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_tpg.c +++ b/drivers/staging/media/atomisp/pci/atomisp_tpg.c @@ -29,7 +29,7 @@ static int tpg_s_stream(struct v4l2_subdev *sd, int enable) } static int tpg_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { /*to fake*/ @@ -37,7 +37,7 @@ static int tpg_get_fmt(struct v4l2_subdev *sd, } static int tpg_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) { struct v4l2_mbus_framefmt *fmt = &format->format; @@ -47,7 +47,7 @@ static int tpg_set_fmt(struct v4l2_subdev *sd, /* only raw8 grbg is supported by TPG */ fmt->code = MEDIA_BUS_FMT_SGRBG8_1X8; if (format->which == V4L2_SUBDEV_FORMAT_TRY) { - cfg->try_fmt = *fmt; + sd_state->pads->try_fmt = *fmt; return 0; } return 0; @@ -65,7 +65,7 @@ static int tpg_s_power(struct v4l2_subdev *sd, int on) } static int tpg_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { /*to fake*/ @@ -73,7 +73,7 @@ static int tpg_enum_mbus_code(struct v4l2_subdev *sd, } static int tpg_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { /*to fake*/ @@ -81,7 +81,7 @@ static int tpg_enum_frame_size(struct v4l2_subdev *sd, } static int tpg_enum_frame_ival(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_interval_enum *fie) { /*to fake*/ diff --git a/drivers/staging/media/imx/imx-ic-prp.c b/drivers/staging/media/imx/imx-ic-prp.c index f21ed881295f..ac5fb332088e 100644 --- a/drivers/staging/media/imx/imx-ic-prp.c +++ b/drivers/staging/media/imx/imx-ic-prp.c @@ -79,13 +79,13 @@ static void prp_stop(struct prp_priv *priv) } static struct v4l2_mbus_framefmt * -__prp_get_fmt(struct prp_priv *priv, struct v4l2_subdev_pad_config *cfg, +__prp_get_fmt(struct prp_priv *priv, struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which) { struct imx_ic_priv *ic_priv = priv->ic_priv; if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_format(&ic_priv->sd, cfg, pad); + return v4l2_subdev_get_try_format(&ic_priv->sd, sd_state, pad); else return &priv->format_mbus; } @@ -95,7 +95,7 @@ __prp_get_fmt(struct prp_priv *priv, struct v4l2_subdev_pad_config *cfg, */ static int prp_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct prp_priv *priv = sd_to_priv(sd); @@ -115,7 +115,8 @@ static int prp_enum_mbus_code(struct v4l2_subdev *sd, ret = -EINVAL; goto out; } - infmt = __prp_get_fmt(priv, cfg, PRP_SINK_PAD, code->which); + infmt = __prp_get_fmt(priv, sd_state, PRP_SINK_PAD, + code->which); code->code = infmt->code; break; default: @@ -127,7 +128,7 @@ out: } static int prp_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *sdformat) { struct prp_priv *priv = sd_to_priv(sd); @@ -139,7 +140,7 @@ static int prp_get_fmt(struct v4l2_subdev *sd, mutex_lock(&priv->lock); - fmt = __prp_get_fmt(priv, cfg, sdformat->pad, sdformat->which); + fmt = __prp_get_fmt(priv, sd_state, sdformat->pad, sdformat->which); if (!fmt) { ret = -EINVAL; goto out; @@ -152,7 +153,7 @@ out: } static int prp_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *sdformat) { struct prp_priv *priv = sd_to_priv(sd); @@ -171,7 +172,7 @@ static int prp_set_fmt(struct v4l2_subdev *sd, goto out; } - infmt = __prp_get_fmt(priv, cfg, PRP_SINK_PAD, sdformat->which); + infmt = __prp_get_fmt(priv, sd_state, PRP_SINK_PAD, sdformat->which); switch (sdformat->pad) { case PRP_SINK_PAD: @@ -201,7 +202,7 @@ static int prp_set_fmt(struct v4l2_subdev *sd, imx_media_try_colorimetry(&sdformat->format, true); - fmt = __prp_get_fmt(priv, cfg, sdformat->pad, sdformat->which); + fmt = __prp_get_fmt(priv, sd_state, sdformat->pad, sdformat->which); *fmt = sdformat->format; out: mutex_unlock(&priv->lock); diff --git a/drivers/staging/media/imx/imx-ic-prpencvf.c b/drivers/staging/media/imx/imx-ic-prpencvf.c index d990553de87b..9b81cfbcd777 100644 --- a/drivers/staging/media/imx/imx-ic-prpencvf.c +++ b/drivers/staging/media/imx/imx-ic-prpencvf.c @@ -787,13 +787,13 @@ static void prp_stop(struct prp_priv *priv) } static struct v4l2_mbus_framefmt * -__prp_get_fmt(struct prp_priv *priv, struct v4l2_subdev_pad_config *cfg, +__prp_get_fmt(struct prp_priv *priv, struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which) { struct imx_ic_priv *ic_priv = priv->ic_priv; if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_format(&ic_priv->sd, cfg, pad); + return v4l2_subdev_get_try_format(&ic_priv->sd, sd_state, pad); else return &priv->format_mbus[pad]; } @@ -841,7 +841,7 @@ static bool prp_bound_align_output(struct v4l2_mbus_framefmt *outfmt, */ static int prp_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->pad >= PRPENCVF_NUM_PADS) @@ -852,7 +852,7 @@ static int prp_enum_mbus_code(struct v4l2_subdev *sd, } static int prp_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *sdformat) { struct prp_priv *priv = sd_to_priv(sd); @@ -864,7 +864,7 @@ static int prp_get_fmt(struct v4l2_subdev *sd, mutex_lock(&priv->lock); - fmt = __prp_get_fmt(priv, cfg, sdformat->pad, sdformat->which); + fmt = __prp_get_fmt(priv, sd_state, sdformat->pad, sdformat->which); if (!fmt) { ret = -EINVAL; goto out; @@ -877,7 +877,7 @@ out: } static void prp_try_fmt(struct prp_priv *priv, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *sdformat, const struct imx_media_pixfmt **cc) { @@ -894,7 +894,8 @@ static void prp_try_fmt(struct prp_priv *priv, sdformat->format.code = (*cc)->codes[0]; } - infmt = __prp_get_fmt(priv, cfg, PRPENCVF_SINK_PAD, sdformat->which); + infmt = __prp_get_fmt(priv, sd_state, PRPENCVF_SINK_PAD, + sdformat->which); if (sdformat->pad == PRPENCVF_SRC_PAD) { sdformat->format.field = infmt->field; @@ -920,7 +921,7 @@ static void prp_try_fmt(struct prp_priv *priv, } static int prp_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *sdformat) { struct prp_priv *priv = sd_to_priv(sd); @@ -938,9 +939,9 @@ static int prp_set_fmt(struct v4l2_subdev *sd, goto out; } - prp_try_fmt(priv, cfg, sdformat, &cc); + prp_try_fmt(priv, sd_state, sdformat, &cc); - fmt = __prp_get_fmt(priv, cfg, sdformat->pad, sdformat->which); + fmt = __prp_get_fmt(priv, sd_state, sdformat->pad, sdformat->which); *fmt = sdformat->format; /* propagate a default format to source pad */ @@ -952,9 +953,9 @@ static int prp_set_fmt(struct v4l2_subdev *sd, format.pad = PRPENCVF_SRC_PAD; format.which = sdformat->which; format.format = sdformat->format; - prp_try_fmt(priv, cfg, &format, &outcc); + prp_try_fmt(priv, sd_state, &format, &outcc); - outfmt = __prp_get_fmt(priv, cfg, PRPENCVF_SRC_PAD, + outfmt = __prp_get_fmt(priv, sd_state, PRPENCVF_SRC_PAD, sdformat->which); *outfmt = format.format; if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE) @@ -970,7 +971,7 @@ out: } static int prp_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { struct prp_priv *priv = sd_to_priv(sd); @@ -988,7 +989,7 @@ static int prp_enum_frame_size(struct v4l2_subdev *sd, format.format.code = fse->code; format.format.width = 1; format.format.height = 1; - prp_try_fmt(priv, cfg, &format, &cc); + prp_try_fmt(priv, sd_state, &format, &cc); fse->min_width = format.format.width; fse->min_height = format.format.height; @@ -1000,7 +1001,7 @@ static int prp_enum_frame_size(struct v4l2_subdev *sd, format.format.code = fse->code; format.format.width = -1; format.format.height = -1; - prp_try_fmt(priv, cfg, &format, &cc); + prp_try_fmt(priv, sd_state, &format, &cc); fse->max_width = format.format.width; fse->max_height = format.format.height; out: diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c index e3bfd635a89a..d2f1d40b2d5a 100644 --- a/drivers/staging/media/imx/imx-media-csi.c +++ b/drivers/staging/media/imx/imx-media-csi.c @@ -1139,31 +1139,32 @@ static int csi_link_validate(struct v4l2_subdev *sd, } static struct v4l2_mbus_framefmt * -__csi_get_fmt(struct csi_priv *priv, struct v4l2_subdev_pad_config *cfg, +__csi_get_fmt(struct csi_priv *priv, struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which) { if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_format(&priv->sd, cfg, pad); + return v4l2_subdev_get_try_format(&priv->sd, sd_state, pad); else return &priv->format_mbus[pad]; } static struct v4l2_rect * -__csi_get_crop(struct csi_priv *priv, struct v4l2_subdev_pad_config *cfg, +__csi_get_crop(struct csi_priv *priv, struct v4l2_subdev_state *sd_state, enum v4l2_subdev_format_whence which) { if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_crop(&priv->sd, cfg, CSI_SINK_PAD); + return v4l2_subdev_get_try_crop(&priv->sd, sd_state, + CSI_SINK_PAD); else return &priv->crop; } static struct v4l2_rect * -__csi_get_compose(struct csi_priv *priv, struct v4l2_subdev_pad_config *cfg, +__csi_get_compose(struct csi_priv *priv, struct v4l2_subdev_state *sd_state, enum v4l2_subdev_format_whence which) { if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_compose(&priv->sd, cfg, + return v4l2_subdev_get_try_compose(&priv->sd, sd_state, CSI_SINK_PAD); else return &priv->compose; @@ -1171,7 +1172,7 @@ __csi_get_compose(struct csi_priv *priv, struct v4l2_subdev_pad_config *cfg, static void csi_try_crop(struct csi_priv *priv, struct v4l2_rect *crop, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_mbus_framefmt *infmt, struct v4l2_fwnode_endpoint *upstream_ep) { @@ -1210,7 +1211,7 @@ static void csi_try_crop(struct csi_priv *priv, } static int csi_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct csi_priv *priv = v4l2_get_subdevdata(sd); @@ -1221,7 +1222,7 @@ static int csi_enum_mbus_code(struct v4l2_subdev *sd, mutex_lock(&priv->lock); - infmt = __csi_get_fmt(priv, cfg, CSI_SINK_PAD, code->which); + infmt = __csi_get_fmt(priv, sd_state, CSI_SINK_PAD, code->which); incc = imx_media_find_mbus_format(infmt->code, PIXFMT_SEL_ANY); switch (code->pad) { @@ -1263,7 +1264,7 @@ out: } static int csi_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { struct csi_priv *priv = v4l2_get_subdevdata(sd); @@ -1282,7 +1283,7 @@ static int csi_enum_frame_size(struct v4l2_subdev *sd, fse->min_height = MIN_H; fse->max_height = MAX_H; } else { - crop = __csi_get_crop(priv, cfg, fse->which); + crop = __csi_get_crop(priv, sd_state, fse->which); fse->min_width = fse->index & 1 ? crop->width / 2 : crop->width; @@ -1297,7 +1298,7 @@ static int csi_enum_frame_size(struct v4l2_subdev *sd, } static int csi_enum_frame_interval(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_interval_enum *fie) { struct csi_priv *priv = v4l2_get_subdevdata(sd); @@ -1313,7 +1314,7 @@ static int csi_enum_frame_interval(struct v4l2_subdev *sd, mutex_lock(&priv->lock); input_fi = &priv->frame_interval[CSI_SINK_PAD]; - crop = __csi_get_crop(priv, cfg, fie->which); + crop = __csi_get_crop(priv, sd_state, fie->which); if ((fie->width != crop->width && fie->width != crop->width / 2) || (fie->height != crop->height && fie->height != crop->height / 2)) { @@ -1333,7 +1334,7 @@ out: } static int csi_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *sdformat) { struct csi_priv *priv = v4l2_get_subdevdata(sd); @@ -1345,7 +1346,7 @@ static int csi_get_fmt(struct v4l2_subdev *sd, mutex_lock(&priv->lock); - fmt = __csi_get_fmt(priv, cfg, sdformat->pad, sdformat->which); + fmt = __csi_get_fmt(priv, sd_state, sdformat->pad, sdformat->which); if (!fmt) { ret = -EINVAL; goto out; @@ -1358,11 +1359,11 @@ out: } static void csi_try_field(struct csi_priv *priv, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *sdformat) { struct v4l2_mbus_framefmt *infmt = - __csi_get_fmt(priv, cfg, CSI_SINK_PAD, sdformat->which); + __csi_get_fmt(priv, sd_state, CSI_SINK_PAD, sdformat->which); /* * no restrictions on sink pad field type except must @@ -1408,7 +1409,7 @@ static void csi_try_field(struct csi_priv *priv, static void csi_try_fmt(struct csi_priv *priv, struct v4l2_fwnode_endpoint *upstream_ep, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *sdformat, struct v4l2_rect *crop, struct v4l2_rect *compose, @@ -1418,7 +1419,7 @@ static void csi_try_fmt(struct csi_priv *priv, struct v4l2_mbus_framefmt *infmt; u32 code; - infmt = __csi_get_fmt(priv, cfg, CSI_SINK_PAD, sdformat->which); + infmt = __csi_get_fmt(priv, sd_state, CSI_SINK_PAD, sdformat->which); switch (sdformat->pad) { case CSI_SRC_PAD_DIRECT: @@ -1445,7 +1446,7 @@ static void csi_try_fmt(struct csi_priv *priv, } } - csi_try_field(priv, cfg, sdformat); + csi_try_field(priv, sd_state, sdformat); /* propagate colorimetry from sink */ sdformat->format.colorspace = infmt->colorspace; @@ -1469,7 +1470,7 @@ static void csi_try_fmt(struct csi_priv *priv, sdformat->format.code = (*cc)->codes[0]; } - csi_try_field(priv, cfg, sdformat); + csi_try_field(priv, sd_state, sdformat); /* Reset crop and compose rectangles */ crop->left = 0; @@ -1478,7 +1479,8 @@ static void csi_try_fmt(struct csi_priv *priv, crop->height = sdformat->format.height; if (sdformat->format.field == V4L2_FIELD_ALTERNATE) crop->height *= 2; - csi_try_crop(priv, crop, cfg, &sdformat->format, upstream_ep); + csi_try_crop(priv, crop, sd_state, &sdformat->format, + upstream_ep); compose->left = 0; compose->top = 0; compose->width = crop->width; @@ -1492,7 +1494,7 @@ static void csi_try_fmt(struct csi_priv *priv, } static int csi_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *sdformat) { struct csi_priv *priv = v4l2_get_subdevdata(sd); @@ -1518,12 +1520,13 @@ static int csi_set_fmt(struct v4l2_subdev *sd, goto out; } - crop = __csi_get_crop(priv, cfg, sdformat->which); - compose = __csi_get_compose(priv, cfg, sdformat->which); + crop = __csi_get_crop(priv, sd_state, sdformat->which); + compose = __csi_get_compose(priv, sd_state, sdformat->which); - csi_try_fmt(priv, &upstream_ep, cfg, sdformat, crop, compose, &cc); + csi_try_fmt(priv, &upstream_ep, sd_state, sdformat, crop, compose, + &cc); - fmt = __csi_get_fmt(priv, cfg, sdformat->pad, sdformat->which); + fmt = __csi_get_fmt(priv, sd_state, sdformat->pad, sdformat->which); *fmt = sdformat->format; if (sdformat->pad == CSI_SINK_PAD) { @@ -1538,10 +1541,11 @@ static int csi_set_fmt(struct v4l2_subdev *sd, format.pad = pad; format.which = sdformat->which; format.format = sdformat->format; - csi_try_fmt(priv, &upstream_ep, cfg, &format, + csi_try_fmt(priv, &upstream_ep, sd_state, &format, NULL, compose, &outcc); - outfmt = __csi_get_fmt(priv, cfg, pad, sdformat->which); + outfmt = __csi_get_fmt(priv, sd_state, pad, + sdformat->which); *outfmt = format.format; if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE) @@ -1558,7 +1562,7 @@ out: } static int csi_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct csi_priv *priv = v4l2_get_subdevdata(sd); @@ -1571,9 +1575,9 @@ static int csi_get_selection(struct v4l2_subdev *sd, mutex_lock(&priv->lock); - infmt = __csi_get_fmt(priv, cfg, CSI_SINK_PAD, sel->which); - crop = __csi_get_crop(priv, cfg, sel->which); - compose = __csi_get_compose(priv, cfg, sel->which); + infmt = __csi_get_fmt(priv, sd_state, CSI_SINK_PAD, sel->which); + crop = __csi_get_crop(priv, sd_state, sel->which); + compose = __csi_get_compose(priv, sd_state, sel->which); switch (sel->target) { case V4L2_SEL_TGT_CROP_BOUNDS: @@ -1622,7 +1626,7 @@ static int csi_set_scale(u32 *compose, u32 crop, u32 flags) } static int csi_set_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct csi_priv *priv = v4l2_get_subdevdata(sd); @@ -1647,9 +1651,9 @@ static int csi_set_selection(struct v4l2_subdev *sd, goto out; } - infmt = __csi_get_fmt(priv, cfg, CSI_SINK_PAD, sel->which); - crop = __csi_get_crop(priv, cfg, sel->which); - compose = __csi_get_compose(priv, cfg, sel->which); + infmt = __csi_get_fmt(priv, sd_state, CSI_SINK_PAD, sel->which); + crop = __csi_get_crop(priv, sd_state, sel->which); + compose = __csi_get_compose(priv, sd_state, sel->which); switch (sel->target) { case V4L2_SEL_TGT_CROP: @@ -1665,7 +1669,7 @@ static int csi_set_selection(struct v4l2_subdev *sd, goto out; } - csi_try_crop(priv, &sel->r, cfg, infmt, &upstream_ep); + csi_try_crop(priv, &sel->r, sd_state, infmt, &upstream_ep); *crop = sel->r; @@ -1706,7 +1710,7 @@ static int csi_set_selection(struct v4l2_subdev *sd, for (pad = CSI_SINK_PAD + 1; pad < CSI_NUM_PADS; pad++) { struct v4l2_mbus_framefmt *outfmt; - outfmt = __csi_get_fmt(priv, cfg, pad, sel->which); + outfmt = __csi_get_fmt(priv, sd_state, pad, sel->which); outfmt->width = compose->width; outfmt->height = compose->height; } diff --git a/drivers/staging/media/imx/imx-media-utils.c b/drivers/staging/media/imx/imx-media-utils.c index 5128915a5d6f..6f90acf9c725 100644 --- a/drivers/staging/media/imx/imx-media-utils.c +++ b/drivers/staging/media/imx/imx-media-utils.c @@ -429,7 +429,7 @@ EXPORT_SYMBOL_GPL(imx_media_init_mbus_fmt); * of a subdev. Can be used as the .init_cfg pad operation. */ int imx_media_init_cfg(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg) + struct v4l2_subdev_state *sd_state) { struct v4l2_mbus_framefmt *mf_try; struct v4l2_subdev_format format; @@ -445,7 +445,7 @@ int imx_media_init_cfg(struct v4l2_subdev *sd, if (ret) continue; - mf_try = v4l2_subdev_get_try_format(sd, cfg, pad); + mf_try = v4l2_subdev_get_try_format(sd, sd_state, pad); *mf_try = format.format; } diff --git a/drivers/staging/media/imx/imx-media-vdic.c b/drivers/staging/media/imx/imx-media-vdic.c index abf290bda98d..3c2093c520ba 100644 --- a/drivers/staging/media/imx/imx-media-vdic.c +++ b/drivers/staging/media/imx/imx-media-vdic.c @@ -532,17 +532,17 @@ out: } static struct v4l2_mbus_framefmt * -__vdic_get_fmt(struct vdic_priv *priv, struct v4l2_subdev_pad_config *cfg, +__vdic_get_fmt(struct vdic_priv *priv, struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which) { if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_format(&priv->sd, cfg, pad); + return v4l2_subdev_get_try_format(&priv->sd, sd_state, pad); else return &priv->format_mbus[pad]; } static int vdic_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (code->pad >= VDIC_NUM_PADS) @@ -553,7 +553,7 @@ static int vdic_enum_mbus_code(struct v4l2_subdev *sd, } static int vdic_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *sdformat) { struct vdic_priv *priv = v4l2_get_subdevdata(sd); @@ -565,7 +565,7 @@ static int vdic_get_fmt(struct v4l2_subdev *sd, mutex_lock(&priv->lock); - fmt = __vdic_get_fmt(priv, cfg, sdformat->pad, sdformat->which); + fmt = __vdic_get_fmt(priv, sd_state, sdformat->pad, sdformat->which); if (!fmt) { ret = -EINVAL; goto out; @@ -578,7 +578,7 @@ out: } static void vdic_try_fmt(struct vdic_priv *priv, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *sdformat, const struct imx_media_pixfmt **cc) { @@ -594,7 +594,7 @@ static void vdic_try_fmt(struct vdic_priv *priv, sdformat->format.code = (*cc)->codes[0]; } - infmt = __vdic_get_fmt(priv, cfg, priv->active_input_pad, + infmt = __vdic_get_fmt(priv, sd_state, priv->active_input_pad, sdformat->which); switch (sdformat->pad) { @@ -620,7 +620,7 @@ static void vdic_try_fmt(struct vdic_priv *priv, } static int vdic_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *sdformat) { struct vdic_priv *priv = v4l2_get_subdevdata(sd); @@ -638,9 +638,9 @@ static int vdic_set_fmt(struct v4l2_subdev *sd, goto out; } - vdic_try_fmt(priv, cfg, sdformat, &cc); + vdic_try_fmt(priv, sd_state, sdformat, &cc); - fmt = __vdic_get_fmt(priv, cfg, sdformat->pad, sdformat->which); + fmt = __vdic_get_fmt(priv, sd_state, sdformat->pad, sdformat->which); *fmt = sdformat->format; /* propagate format to source pad */ @@ -653,9 +653,9 @@ static int vdic_set_fmt(struct v4l2_subdev *sd, format.pad = VDIC_SRC_PAD_DIRECT; format.which = sdformat->which; format.format = sdformat->format; - vdic_try_fmt(priv, cfg, &format, &outcc); + vdic_try_fmt(priv, sd_state, &format, &outcc); - outfmt = __vdic_get_fmt(priv, cfg, VDIC_SRC_PAD_DIRECT, + outfmt = __vdic_get_fmt(priv, sd_state, VDIC_SRC_PAD_DIRECT, sdformat->which); *outfmt = format.format; if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE) diff --git a/drivers/staging/media/imx/imx-media.h b/drivers/staging/media/imx/imx-media.h index 492d9a64e704..6740e7917458 100644 --- a/drivers/staging/media/imx/imx-media.h +++ b/drivers/staging/media/imx/imx-media.h @@ -193,7 +193,7 @@ int imx_media_init_mbus_fmt(struct v4l2_mbus_framefmt *mbus, u32 width, u32 height, u32 code, u32 field, const struct imx_media_pixfmt **cc); int imx_media_init_cfg(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg); + struct v4l2_subdev_state *sd_state); void imx_media_try_colorimetry(struct v4l2_mbus_framefmt *tryfmt, bool ic_route); int imx_media_mbus_fmt_to_pix_fmt(struct v4l2_pix_format *pix, diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c index fc2378ac04b7..9de0ebd439dc 100644 --- a/drivers/staging/media/imx/imx6-mipi-csi2.c +++ b/drivers/staging/media/imx/imx6-mipi-csi2.c @@ -508,17 +508,17 @@ out: } static struct v4l2_mbus_framefmt * -__csi2_get_fmt(struct csi2_dev *csi2, struct v4l2_subdev_pad_config *cfg, +__csi2_get_fmt(struct csi2_dev *csi2, struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which) { if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_format(&csi2->sd, cfg, pad); + return v4l2_subdev_get_try_format(&csi2->sd, sd_state, pad); else return &csi2->format_mbus; } static int csi2_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *sdformat) { struct csi2_dev *csi2 = sd_to_dev(sd); @@ -526,7 +526,7 @@ static int csi2_get_fmt(struct v4l2_subdev *sd, mutex_lock(&csi2->lock); - fmt = __csi2_get_fmt(csi2, cfg, sdformat->pad, sdformat->which); + fmt = __csi2_get_fmt(csi2, sd_state, sdformat->pad, sdformat->which); sdformat->format = *fmt; @@ -536,7 +536,7 @@ static int csi2_get_fmt(struct v4l2_subdev *sd, } static int csi2_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *sdformat) { struct csi2_dev *csi2 = sd_to_dev(sd); @@ -557,7 +557,7 @@ static int csi2_set_fmt(struct v4l2_subdev *sd, if (sdformat->pad != CSI2_SINK_PAD) sdformat->format = csi2->format_mbus; - fmt = __csi2_get_fmt(csi2, cfg, sdformat->pad, sdformat->which); + fmt = __csi2_get_fmt(csi2, sd_state, sdformat->pad, sdformat->which); *fmt = sdformat->format; out: diff --git a/drivers/staging/media/imx/imx7-media-csi.c b/drivers/staging/media/imx/imx7-media-csi.c index f85a2f5f1413..894c4de31790 100644 --- a/drivers/staging/media/imx/imx7-media-csi.c +++ b/drivers/staging/media/imx/imx7-media-csi.c @@ -724,7 +724,7 @@ out_unlock: } static int imx7_csi_init_cfg(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg) + struct v4l2_subdev_state *sd_state) { struct imx7_csi *csi = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *mf; @@ -732,7 +732,7 @@ static int imx7_csi_init_cfg(struct v4l2_subdev *sd, int i; for (i = 0; i < IMX7_CSI_PADS_NUM; i++) { - mf = v4l2_subdev_get_try_format(sd, cfg, i); + mf = v4l2_subdev_get_try_format(sd, sd_state, i); ret = imx_media_init_mbus_fmt(mf, 800, 600, 0, V4L2_FIELD_NONE, &csi->cc[i]); @@ -745,18 +745,18 @@ static int imx7_csi_init_cfg(struct v4l2_subdev *sd, static struct v4l2_mbus_framefmt * imx7_csi_get_format(struct imx7_csi *csi, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which) { if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_format(&csi->sd, cfg, pad); + return v4l2_subdev_get_try_format(&csi->sd, sd_state, pad); return &csi->format_mbus[pad]; } static int imx7_csi_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct imx7_csi *csi = v4l2_get_subdevdata(sd); @@ -765,7 +765,8 @@ static int imx7_csi_enum_mbus_code(struct v4l2_subdev *sd, mutex_lock(&csi->lock); - in_fmt = imx7_csi_get_format(csi, cfg, IMX7_CSI_PAD_SINK, code->which); + in_fmt = imx7_csi_get_format(csi, sd_state, IMX7_CSI_PAD_SINK, + code->which); switch (code->pad) { case IMX7_CSI_PAD_SINK: @@ -791,7 +792,7 @@ out_unlock: } static int imx7_csi_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *sdformat) { struct imx7_csi *csi = v4l2_get_subdevdata(sd); @@ -800,7 +801,8 @@ static int imx7_csi_get_fmt(struct v4l2_subdev *sd, mutex_lock(&csi->lock); - fmt = imx7_csi_get_format(csi, cfg, sdformat->pad, sdformat->which); + fmt = imx7_csi_get_format(csi, sd_state, sdformat->pad, + sdformat->which); if (!fmt) { ret = -EINVAL; goto out_unlock; @@ -815,7 +817,7 @@ out_unlock: } static int imx7_csi_try_fmt(struct imx7_csi *csi, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *sdformat, const struct imx_media_pixfmt **cc) { @@ -823,7 +825,7 @@ static int imx7_csi_try_fmt(struct imx7_csi *csi, struct v4l2_mbus_framefmt *in_fmt; u32 code; - in_fmt = imx7_csi_get_format(csi, cfg, IMX7_CSI_PAD_SINK, + in_fmt = imx7_csi_get_format(csi, sd_state, IMX7_CSI_PAD_SINK, sdformat->which); if (!in_fmt) return -EINVAL; @@ -868,7 +870,7 @@ static int imx7_csi_try_fmt(struct imx7_csi *csi, } static int imx7_csi_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *sdformat) { struct imx7_csi *csi = v4l2_get_subdevdata(sd); @@ -889,11 +891,12 @@ static int imx7_csi_set_fmt(struct v4l2_subdev *sd, goto out_unlock; } - ret = imx7_csi_try_fmt(csi, cfg, sdformat, &cc); + ret = imx7_csi_try_fmt(csi, sd_state, sdformat, &cc); if (ret < 0) goto out_unlock; - fmt = imx7_csi_get_format(csi, cfg, sdformat->pad, sdformat->which); + fmt = imx7_csi_get_format(csi, sd_state, sdformat->pad, + sdformat->which); if (!fmt) { ret = -EINVAL; goto out_unlock; @@ -906,11 +909,11 @@ static int imx7_csi_set_fmt(struct v4l2_subdev *sd, format.pad = IMX7_CSI_PAD_SRC; format.which = sdformat->which; format.format = sdformat->format; - if (imx7_csi_try_fmt(csi, cfg, &format, &outcc)) { + if (imx7_csi_try_fmt(csi, sd_state, &format, &outcc)) { ret = -EINVAL; goto out_unlock; } - outfmt = imx7_csi_get_format(csi, cfg, IMX7_CSI_PAD_SRC, + outfmt = imx7_csi_get_format(csi, sd_state, IMX7_CSI_PAD_SRC, sdformat->which); *outfmt = format.format; diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c index 9cd3c86fee58..ead696eb4610 100644 --- a/drivers/staging/media/imx/imx7-mipi-csis.c +++ b/drivers/staging/media/imx/imx7-mipi-csis.c @@ -880,26 +880,26 @@ done: static struct v4l2_mbus_framefmt * mipi_csis_get_format(struct csi_state *state, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, enum v4l2_subdev_format_whence which, unsigned int pad) { if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_format(&state->sd, cfg, pad); + return v4l2_subdev_get_try_format(&state->sd, sd_state, pad); return &state->format_mbus; } static int mipi_csis_init_cfg(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg) + struct v4l2_subdev_state *sd_state) { struct csi_state *state = mipi_sd_to_csis_state(sd); struct v4l2_mbus_framefmt *fmt_sink; struct v4l2_mbus_framefmt *fmt_source; enum v4l2_subdev_format_whence which; - which = cfg ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; - fmt_sink = mipi_csis_get_format(state, cfg, which, CSIS_PAD_SINK); + which = sd_state ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; + fmt_sink = mipi_csis_get_format(state, sd_state, which, CSIS_PAD_SINK); fmt_sink->code = MEDIA_BUS_FMT_UYVY8_1X16; fmt_sink->width = MIPI_CSIS_DEF_PIX_WIDTH; @@ -918,23 +918,25 @@ static int mipi_csis_init_cfg(struct v4l2_subdev *sd, * configuration, cfg is NULL, which indicates there's no source pad * configuration to set. */ - if (!cfg) + if (!sd_state) return 0; - fmt_source = mipi_csis_get_format(state, cfg, which, CSIS_PAD_SOURCE); + fmt_source = mipi_csis_get_format(state, sd_state, which, + CSIS_PAD_SOURCE); *fmt_source = *fmt_sink; return 0; } static int mipi_csis_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *sdformat) { struct csi_state *state = mipi_sd_to_csis_state(sd); struct v4l2_mbus_framefmt *fmt; - fmt = mipi_csis_get_format(state, cfg, sdformat->which, sdformat->pad); + fmt = mipi_csis_get_format(state, sd_state, sdformat->which, + sdformat->pad); mutex_lock(&state->lock); sdformat->format = *fmt; @@ -944,7 +946,7 @@ static int mipi_csis_get_fmt(struct v4l2_subdev *sd, } static int mipi_csis_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct csi_state *state = mipi_sd_to_csis_state(sd); @@ -959,7 +961,8 @@ static int mipi_csis_enum_mbus_code(struct v4l2_subdev *sd, if (code->index > 0) return -EINVAL; - fmt = mipi_csis_get_format(state, cfg, code->which, code->pad); + fmt = mipi_csis_get_format(state, sd_state, code->which, + code->pad); code->code = fmt->code; return 0; } @@ -976,7 +979,7 @@ static int mipi_csis_enum_mbus_code(struct v4l2_subdev *sd, } static int mipi_csis_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *sdformat) { struct csi_state *state = mipi_sd_to_csis_state(sd); @@ -989,7 +992,7 @@ static int mipi_csis_set_fmt(struct v4l2_subdev *sd, * modified. */ if (sdformat->pad == CSIS_PAD_SOURCE) - return mipi_csis_get_fmt(sd, cfg, sdformat); + return mipi_csis_get_fmt(sd, sd_state, sdformat); if (sdformat->pad != CSIS_PAD_SINK) return -EINVAL; @@ -1029,7 +1032,8 @@ static int mipi_csis_set_fmt(struct v4l2_subdev *sd, &sdformat->format.height, 1, CSIS_MAX_PIX_HEIGHT, 0, 0); - fmt = mipi_csis_get_format(state, cfg, sdformat->which, sdformat->pad); + fmt = mipi_csis_get_format(state, sd_state, sdformat->which, + sdformat->pad); mutex_lock(&state->lock); @@ -1040,7 +1044,7 @@ static int mipi_csis_set_fmt(struct v4l2_subdev *sd, sdformat->format = *fmt; /* Propagate the format from sink to source. */ - fmt = mipi_csis_get_format(state, cfg, sdformat->which, + fmt = mipi_csis_get_format(state, sd_state, sdformat->which, CSIS_PAD_SOURCE); *fmt = sdformat->format; diff --git a/drivers/staging/media/ipu3/ipu3-v4l2.c b/drivers/staging/media/ipu3/ipu3-v4l2.c index 6d9c49b39531..38a240764509 100644 --- a/drivers/staging/media/ipu3/ipu3-v4l2.c +++ b/drivers/staging/media/ipu3/ipu3-v4l2.c @@ -36,7 +36,7 @@ static int imgu_subdev_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) /* Initialize try_fmt */ for (i = 0; i < IMGU_NODE_NUM; i++) { struct v4l2_mbus_framefmt *try_fmt = - v4l2_subdev_get_try_format(sd, fh->pad, i); + v4l2_subdev_get_try_format(sd, fh->state, i); try_fmt->width = try_crop.width; try_fmt->height = try_crop.height; @@ -44,8 +44,8 @@ static int imgu_subdev_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) try_fmt->field = V4L2_FIELD_NONE; } - *v4l2_subdev_get_try_crop(sd, fh->pad, IMGU_NODE_IN) = try_crop; - *v4l2_subdev_get_try_compose(sd, fh->pad, IMGU_NODE_IN) = try_crop; + *v4l2_subdev_get_try_crop(sd, fh->state, IMGU_NODE_IN) = try_crop; + *v4l2_subdev_get_try_compose(sd, fh->state, IMGU_NODE_IN) = try_crop; return 0; } @@ -120,7 +120,7 @@ static int imgu_subdev_s_stream(struct v4l2_subdev *sd, int enable) } static int imgu_subdev_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct imgu_device *imgu = v4l2_get_subdevdata(sd); @@ -136,7 +136,7 @@ static int imgu_subdev_get_fmt(struct v4l2_subdev *sd, if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { fmt->format = imgu_pipe->nodes[pad].pad_fmt; } else { - mf = v4l2_subdev_get_try_format(sd, cfg, pad); + mf = v4l2_subdev_get_try_format(sd, sd_state, pad); fmt->format = *mf; } @@ -144,7 +144,7 @@ static int imgu_subdev_get_fmt(struct v4l2_subdev *sd, } static int imgu_subdev_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct imgu_media_pipe *imgu_pipe; @@ -161,7 +161,7 @@ static int imgu_subdev_set_fmt(struct v4l2_subdev *sd, imgu_pipe = &imgu->imgu_pipe[pipe]; if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) - mf = v4l2_subdev_get_try_format(sd, cfg, pad); + mf = v4l2_subdev_get_try_format(sd, sd_state, pad); else mf = &imgu_pipe->nodes[pad].pad_fmt; @@ -189,7 +189,7 @@ static int imgu_subdev_set_fmt(struct v4l2_subdev *sd, } static int imgu_subdev_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct v4l2_rect *try_sel, *r; @@ -202,11 +202,11 @@ static int imgu_subdev_get_selection(struct v4l2_subdev *sd, switch (sel->target) { case V4L2_SEL_TGT_CROP: - try_sel = v4l2_subdev_get_try_crop(sd, cfg, sel->pad); + try_sel = v4l2_subdev_get_try_crop(sd, sd_state, sel->pad); r = &imgu_sd->rect.eff; break; case V4L2_SEL_TGT_COMPOSE: - try_sel = v4l2_subdev_get_try_compose(sd, cfg, sel->pad); + try_sel = v4l2_subdev_get_try_compose(sd, sd_state, sel->pad); r = &imgu_sd->rect.bds; break; default: @@ -222,7 +222,7 @@ static int imgu_subdev_get_selection(struct v4l2_subdev *sd, } static int imgu_subdev_set_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { struct imgu_device *imgu = v4l2_get_subdevdata(sd); @@ -241,11 +241,11 @@ static int imgu_subdev_set_selection(struct v4l2_subdev *sd, switch (sel->target) { case V4L2_SEL_TGT_CROP: - try_sel = v4l2_subdev_get_try_crop(sd, cfg, sel->pad); + try_sel = v4l2_subdev_get_try_crop(sd, sd_state, sel->pad); rect = &imgu_sd->rect.eff; break; case V4L2_SEL_TGT_COMPOSE: - try_sel = v4l2_subdev_get_try_compose(sd, cfg, sel->pad); + try_sel = v4l2_subdev_get_try_compose(sd, sd_state, sel->pad); rect = &imgu_sd->rect.bds; break; default: diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c index a6dc2d2b1228..124ab2f44fbf 100644 --- a/drivers/staging/media/omap4iss/iss_csi2.c +++ b/drivers/staging/media/omap4iss/iss_csi2.c @@ -825,19 +825,20 @@ static const struct iss_video_operations csi2_issvideo_ops = { static struct v4l2_mbus_framefmt * __csi2_get_format(struct iss_csi2_device *csi2, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which) { if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_format(&csi2->subdev, cfg, pad); + return v4l2_subdev_get_try_format(&csi2->subdev, sd_state, + pad); return &csi2->formats[pad]; } static void csi2_try_format(struct iss_csi2_device *csi2, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad, struct v4l2_mbus_framefmt *fmt, enum v4l2_subdev_format_whence which) @@ -868,7 +869,8 @@ csi2_try_format(struct iss_csi2_device *csi2, * compression. */ pixelcode = fmt->code; - format = __csi2_get_format(csi2, cfg, CSI2_PAD_SINK, which); + format = __csi2_get_format(csi2, sd_state, CSI2_PAD_SINK, + which); memcpy(fmt, format, sizeof(*fmt)); /* @@ -894,7 +896,7 @@ csi2_try_format(struct iss_csi2_device *csi2, * return -EINVAL or zero on success */ static int csi2_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct iss_csi2_device *csi2 = v4l2_get_subdevdata(sd); @@ -907,7 +909,7 @@ static int csi2_enum_mbus_code(struct v4l2_subdev *sd, code->code = csi2_input_fmts[code->index]; } else { - format = __csi2_get_format(csi2, cfg, CSI2_PAD_SINK, + format = __csi2_get_format(csi2, sd_state, CSI2_PAD_SINK, code->which); switch (code->index) { case 0: @@ -931,7 +933,7 @@ static int csi2_enum_mbus_code(struct v4l2_subdev *sd, } static int csi2_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { struct iss_csi2_device *csi2 = v4l2_get_subdevdata(sd); @@ -943,7 +945,7 @@ static int csi2_enum_frame_size(struct v4l2_subdev *sd, format.code = fse->code; format.width = 1; format.height = 1; - csi2_try_format(csi2, cfg, fse->pad, &format, fse->which); + csi2_try_format(csi2, sd_state, fse->pad, &format, fse->which); fse->min_width = format.width; fse->min_height = format.height; @@ -953,7 +955,7 @@ static int csi2_enum_frame_size(struct v4l2_subdev *sd, format.code = fse->code; format.width = -1; format.height = -1; - csi2_try_format(csi2, cfg, fse->pad, &format, fse->which); + csi2_try_format(csi2, sd_state, fse->pad, &format, fse->which); fse->max_width = format.width; fse->max_height = format.height; @@ -968,13 +970,13 @@ static int csi2_enum_frame_size(struct v4l2_subdev *sd, * return -EINVAL or zero on success */ static int csi2_get_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct iss_csi2_device *csi2 = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *format; - format = __csi2_get_format(csi2, cfg, fmt->pad, fmt->which); + format = __csi2_get_format(csi2, sd_state, fmt->pad, fmt->which); if (!format) return -EINVAL; @@ -990,25 +992,26 @@ static int csi2_get_format(struct v4l2_subdev *sd, * return -EINVAL or zero on success */ static int csi2_set_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct iss_csi2_device *csi2 = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *format; - format = __csi2_get_format(csi2, cfg, fmt->pad, fmt->which); + format = __csi2_get_format(csi2, sd_state, fmt->pad, fmt->which); if (!format) return -EINVAL; - csi2_try_format(csi2, cfg, fmt->pad, &fmt->format, fmt->which); + csi2_try_format(csi2, sd_state, fmt->pad, &fmt->format, fmt->which); *format = fmt->format; /* Propagate the format from sink to source */ if (fmt->pad == CSI2_PAD_SINK) { - format = __csi2_get_format(csi2, cfg, CSI2_PAD_SOURCE, + format = __csi2_get_format(csi2, sd_state, CSI2_PAD_SOURCE, fmt->which); *format = fmt->format; - csi2_try_format(csi2, cfg, CSI2_PAD_SOURCE, format, fmt->which); + csi2_try_format(csi2, sd_state, CSI2_PAD_SOURCE, format, + fmt->which); } return 0; @@ -1050,7 +1053,7 @@ static int csi2_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10; format.format.width = 4096; format.format.height = 4096; - csi2_set_format(sd, fh ? fh->pad : NULL, &format); + csi2_set_format(sd, fh ? fh->state : NULL, &format); return 0; } diff --git a/drivers/staging/media/omap4iss/iss_ipipe.c b/drivers/staging/media/omap4iss/iss_ipipe.c index 26be078b69f3..23f707cb336f 100644 --- a/drivers/staging/media/omap4iss/iss_ipipe.c +++ b/drivers/staging/media/omap4iss/iss_ipipe.c @@ -21,7 +21,7 @@ static struct v4l2_mbus_framefmt * __ipipe_get_format(struct iss_ipipe_device *ipipe, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which); @@ -175,12 +175,13 @@ static int ipipe_set_stream(struct v4l2_subdev *sd, int enable) static struct v4l2_mbus_framefmt * __ipipe_get_format(struct iss_ipipe_device *ipipe, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which) { if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_format(&ipipe->subdev, cfg, pad); + return v4l2_subdev_get_try_format(&ipipe->subdev, sd_state, + pad); return &ipipe->formats[pad]; } @@ -194,7 +195,7 @@ __ipipe_get_format(struct iss_ipipe_device *ipipe, */ static void ipipe_try_format(struct iss_ipipe_device *ipipe, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, unsigned int pad, struct v4l2_mbus_framefmt *fmt, enum v4l2_subdev_format_whence which) @@ -222,7 +223,8 @@ ipipe_try_format(struct iss_ipipe_device *ipipe, break; case IPIPE_PAD_SOURCE_VP: - format = __ipipe_get_format(ipipe, cfg, IPIPE_PAD_SINK, which); + format = __ipipe_get_format(ipipe, sd_state, IPIPE_PAD_SINK, + which); memcpy(fmt, format, sizeof(*fmt)); fmt->code = MEDIA_BUS_FMT_UYVY8_1X16; @@ -243,7 +245,7 @@ ipipe_try_format(struct iss_ipipe_device *ipipe, * return -EINVAL or zero on success */ static int ipipe_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { switch (code->pad) { @@ -270,7 +272,7 @@ static int ipipe_enum_mbus_code(struct v4l2_subdev *sd, } static int ipipe_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { struct iss_ipipe_device *ipipe = v4l2_get_subdevdata(sd); @@ -282,7 +284,7 @@ static int ipipe_enum_frame_size(struct v4l2_subdev *sd, format.code = fse->code; format.width = 1; format.height = 1; - ipipe_try_format(ipipe, cfg, fse->pad, &format, fse->which); + ipipe_try_format(ipipe, sd_state, fse->pad, &format, fse->which); fse->min_width = format.width; fse->min_height = format.height; @@ -292,7 +294,7 @@ static int ipipe_enum_frame_size(struct v4l2_subdev *sd, format.code = fse->code; format.width = -1; format.height = -1; - ipipe_try_format(ipipe, cfg, fse->pad, &format, fse->which); + ipipe_try_format(ipipe, sd_state, fse->pad, &format, fse->which); fse->max_width = format.width; fse->max_height = format.height; @@ -309,13 +311,13 @@ static int ipipe_enum_frame_size(struct v4l2_subdev *sd, * to the format type. */ static int ipipe_get_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct iss_ipipe_device *ipipe = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *format; - format = __ipipe_get_format(ipipe, cfg, fmt->pad, fmt->which); + format = __ipipe_get_format(ipipe, sd_state, fmt->pad, fmt->which); if (!format) return -EINVAL; @@ -333,25 +335,26 @@ static int ipipe_get_format(struct v4l2_subdev *sd, * to the format type. */ static int ipipe_set_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct iss_ipipe_device *ipipe = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *format; - format = __ipipe_get_format(ipipe, cfg, fmt->pad, fmt->which); + format = __ipipe_get_format(ipipe, sd_state, fmt->pad, fmt->which); if (!format) return -EINVAL; - ipipe_try_format(ipipe, cfg, fmt->pad, &fmt->format, fmt->which); + ipipe_try_format(ipipe, sd_state, fmt->pad, &fmt->format, fmt->which); *format = fmt->format; /* Propagate the format from sink to source */ if (fmt->pad == IPIPE_PAD_SINK) { - format = __ipipe_get_format(ipipe, cfg, IPIPE_PAD_SOURCE_VP, + format = __ipipe_get_format(ipipe, sd_state, + IPIPE_PAD_SOURCE_VP, fmt->which); *format = fmt->format; - ipipe_try_format(ipipe, cfg, IPIPE_PAD_SOURCE_VP, format, + ipipe_try_format(ipipe, sd_state, IPIPE_PAD_SOURCE_VP, format, fmt->which); } @@ -392,7 +395,7 @@ static int ipipe_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10; format.format.width = 4096; format.format.height = 4096; - ipipe_set_format(sd, fh ? fh->pad : NULL, &format); + ipipe_set_format(sd, fh ? fh->state : NULL, &format); return 0; } diff --git a/drivers/staging/media/omap4iss/iss_ipipeif.c b/drivers/staging/media/omap4iss/iss_ipipeif.c index c2978d02e797..5e7f25cd53ac 100644 --- a/drivers/staging/media/omap4iss/iss_ipipeif.c +++ b/drivers/staging/media/omap4iss/iss_ipipeif.c @@ -357,11 +357,12 @@ static int ipipeif_set_stream(struct v4l2_subdev *sd, int enable) static struct v4l2_mbus_framefmt * __ipipeif_get_format(struct iss_ipipeif_device *ipipeif, - struct v4l2_subdev_pad_config *cfg, unsigned int pad, + struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which) { if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_format(&ipipeif->subdev, cfg, pad); + return v4l2_subdev_get_try_format(&ipipeif->subdev, sd_state, + pad); return &ipipeif->formats[pad]; } @@ -374,7 +375,7 @@ __ipipeif_get_format(struct iss_ipipeif_device *ipipeif, */ static void ipipeif_try_format(struct iss_ipipeif_device *ipipeif, - struct v4l2_subdev_pad_config *cfg, unsigned int pad, + struct v4l2_subdev_state *sd_state, unsigned int pad, struct v4l2_mbus_framefmt *fmt, enum v4l2_subdev_format_whence which) { @@ -403,7 +404,8 @@ ipipeif_try_format(struct iss_ipipeif_device *ipipeif, break; case IPIPEIF_PAD_SOURCE_ISIF_SF: - format = __ipipeif_get_format(ipipeif, cfg, IPIPEIF_PAD_SINK, + format = __ipipeif_get_format(ipipeif, sd_state, + IPIPEIF_PAD_SINK, which); memcpy(fmt, format, sizeof(*fmt)); @@ -418,7 +420,8 @@ ipipeif_try_format(struct iss_ipipeif_device *ipipeif, break; case IPIPEIF_PAD_SOURCE_VP: - format = __ipipeif_get_format(ipipeif, cfg, IPIPEIF_PAD_SINK, + format = __ipipeif_get_format(ipipeif, sd_state, + IPIPEIF_PAD_SINK, which); memcpy(fmt, format, sizeof(*fmt)); @@ -442,7 +445,7 @@ ipipeif_try_format(struct iss_ipipeif_device *ipipeif, * return -EINVAL or zero on success */ static int ipipeif_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct iss_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd); @@ -462,7 +465,8 @@ static int ipipeif_enum_mbus_code(struct v4l2_subdev *sd, if (code->index != 0) return -EINVAL; - format = __ipipeif_get_format(ipipeif, cfg, IPIPEIF_PAD_SINK, + format = __ipipeif_get_format(ipipeif, sd_state, + IPIPEIF_PAD_SINK, code->which); code->code = format->code; @@ -476,7 +480,7 @@ static int ipipeif_enum_mbus_code(struct v4l2_subdev *sd, } static int ipipeif_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { struct iss_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd); @@ -488,7 +492,7 @@ static int ipipeif_enum_frame_size(struct v4l2_subdev *sd, format.code = fse->code; format.width = 1; format.height = 1; - ipipeif_try_format(ipipeif, cfg, fse->pad, &format, fse->which); + ipipeif_try_format(ipipeif, sd_state, fse->pad, &format, fse->which); fse->min_width = format.width; fse->min_height = format.height; @@ -498,7 +502,7 @@ static int ipipeif_enum_frame_size(struct v4l2_subdev *sd, format.code = fse->code; format.width = -1; format.height = -1; - ipipeif_try_format(ipipeif, cfg, fse->pad, &format, fse->which); + ipipeif_try_format(ipipeif, sd_state, fse->pad, &format, fse->which); fse->max_width = format.width; fse->max_height = format.height; @@ -515,13 +519,13 @@ static int ipipeif_enum_frame_size(struct v4l2_subdev *sd, * to the format type. */ static int ipipeif_get_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct iss_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *format; - format = __ipipeif_get_format(ipipeif, cfg, fmt->pad, fmt->which); + format = __ipipeif_get_format(ipipeif, sd_state, fmt->pad, fmt->which); if (!format) return -EINVAL; @@ -539,33 +543,36 @@ static int ipipeif_get_format(struct v4l2_subdev *sd, * to the format type. */ static int ipipeif_set_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct iss_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *format; - format = __ipipeif_get_format(ipipeif, cfg, fmt->pad, fmt->which); + format = __ipipeif_get_format(ipipeif, sd_state, fmt->pad, fmt->which); if (!format) return -EINVAL; - ipipeif_try_format(ipipeif, cfg, fmt->pad, &fmt->format, fmt->which); + ipipeif_try_format(ipipeif, sd_state, fmt->pad, &fmt->format, + fmt->which); *format = fmt->format; /* Propagate the format from sink to source */ if (fmt->pad == IPIPEIF_PAD_SINK) { - format = __ipipeif_get_format(ipipeif, cfg, + format = __ipipeif_get_format(ipipeif, sd_state, IPIPEIF_PAD_SOURCE_ISIF_SF, fmt->which); *format = fmt->format; - ipipeif_try_format(ipipeif, cfg, IPIPEIF_PAD_SOURCE_ISIF_SF, + ipipeif_try_format(ipipeif, sd_state, + IPIPEIF_PAD_SOURCE_ISIF_SF, format, fmt->which); - format = __ipipeif_get_format(ipipeif, cfg, + format = __ipipeif_get_format(ipipeif, sd_state, IPIPEIF_PAD_SOURCE_VP, fmt->which); *format = fmt->format; - ipipeif_try_format(ipipeif, cfg, IPIPEIF_PAD_SOURCE_VP, format, + ipipeif_try_format(ipipeif, sd_state, IPIPEIF_PAD_SOURCE_VP, + format, fmt->which); } @@ -608,7 +615,7 @@ static int ipipeif_init_formats(struct v4l2_subdev *sd, format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10; format.format.width = 4096; format.format.height = 4096; - ipipeif_set_format(sd, fh ? fh->pad : NULL, &format); + ipipeif_set_format(sd, fh ? fh->state : NULL, &format); return 0; } diff --git a/drivers/staging/media/omap4iss/iss_resizer.c b/drivers/staging/media/omap4iss/iss_resizer.c index 3b6875cbca9b..a5f8f9f1ab16 100644 --- a/drivers/staging/media/omap4iss/iss_resizer.c +++ b/drivers/staging/media/omap4iss/iss_resizer.c @@ -416,11 +416,12 @@ static int resizer_set_stream(struct v4l2_subdev *sd, int enable) static struct v4l2_mbus_framefmt * __resizer_get_format(struct iss_resizer_device *resizer, - struct v4l2_subdev_pad_config *cfg, unsigned int pad, + struct v4l2_subdev_state *sd_state, unsigned int pad, enum v4l2_subdev_format_whence which) { if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_format(&resizer->subdev, cfg, pad); + return v4l2_subdev_get_try_format(&resizer->subdev, sd_state, + pad); return &resizer->formats[pad]; } @@ -433,7 +434,7 @@ __resizer_get_format(struct iss_resizer_device *resizer, */ static void resizer_try_format(struct iss_resizer_device *resizer, - struct v4l2_subdev_pad_config *cfg, unsigned int pad, + struct v4l2_subdev_state *sd_state, unsigned int pad, struct v4l2_mbus_framefmt *fmt, enum v4l2_subdev_format_whence which) { @@ -461,7 +462,8 @@ resizer_try_format(struct iss_resizer_device *resizer, case RESIZER_PAD_SOURCE_MEM: pixelcode = fmt->code; - format = __resizer_get_format(resizer, cfg, RESIZER_PAD_SINK, + format = __resizer_get_format(resizer, sd_state, + RESIZER_PAD_SINK, which); memcpy(fmt, format, sizeof(*fmt)); @@ -492,7 +494,7 @@ resizer_try_format(struct iss_resizer_device *resizer, * return -EINVAL or zero on success */ static int resizer_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { struct iss_resizer_device *resizer = v4l2_get_subdevdata(sd); @@ -507,7 +509,8 @@ static int resizer_enum_mbus_code(struct v4l2_subdev *sd, break; case RESIZER_PAD_SOURCE_MEM: - format = __resizer_get_format(resizer, cfg, RESIZER_PAD_SINK, + format = __resizer_get_format(resizer, sd_state, + RESIZER_PAD_SINK, code->which); if (code->index == 0) { @@ -537,7 +540,7 @@ static int resizer_enum_mbus_code(struct v4l2_subdev *sd, } static int resizer_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { struct iss_resizer_device *resizer = v4l2_get_subdevdata(sd); @@ -549,7 +552,7 @@ static int resizer_enum_frame_size(struct v4l2_subdev *sd, format.code = fse->code; format.width = 1; format.height = 1; - resizer_try_format(resizer, cfg, fse->pad, &format, fse->which); + resizer_try_format(resizer, sd_state, fse->pad, &format, fse->which); fse->min_width = format.width; fse->min_height = format.height; @@ -559,7 +562,7 @@ static int resizer_enum_frame_size(struct v4l2_subdev *sd, format.code = fse->code; format.width = -1; format.height = -1; - resizer_try_format(resizer, cfg, fse->pad, &format, fse->which); + resizer_try_format(resizer, sd_state, fse->pad, &format, fse->which); fse->max_width = format.width; fse->max_height = format.height; @@ -576,13 +579,13 @@ static int resizer_enum_frame_size(struct v4l2_subdev *sd, * to the format type. */ static int resizer_get_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct iss_resizer_device *resizer = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *format; - format = __resizer_get_format(resizer, cfg, fmt->pad, fmt->which); + format = __resizer_get_format(resizer, sd_state, fmt->pad, fmt->which); if (!format) return -EINVAL; @@ -600,26 +603,28 @@ static int resizer_get_format(struct v4l2_subdev *sd, * to the format type. */ static int resizer_set_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct iss_resizer_device *resizer = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *format; - format = __resizer_get_format(resizer, cfg, fmt->pad, fmt->which); + format = __resizer_get_format(resizer, sd_state, fmt->pad, fmt->which); if (!format) return -EINVAL; - resizer_try_format(resizer, cfg, fmt->pad, &fmt->format, fmt->which); + resizer_try_format(resizer, sd_state, fmt->pad, &fmt->format, + fmt->which); *format = fmt->format; /* Propagate the format from sink to source */ if (fmt->pad == RESIZER_PAD_SINK) { - format = __resizer_get_format(resizer, cfg, + format = __resizer_get_format(resizer, sd_state, RESIZER_PAD_SOURCE_MEM, fmt->which); *format = fmt->format; - resizer_try_format(resizer, cfg, RESIZER_PAD_SOURCE_MEM, format, + resizer_try_format(resizer, sd_state, RESIZER_PAD_SOURCE_MEM, + format, fmt->which); } @@ -662,7 +667,7 @@ static int resizer_init_formats(struct v4l2_subdev *sd, format.format.code = MEDIA_BUS_FMT_UYVY8_1X16; format.format.width = 4096; format.format.height = 4096; - resizer_set_format(sd, fh ? fh->pad : NULL, &format); + resizer_set_format(sd, fh ? fh->state : NULL, &format); return 0; } diff --git a/drivers/staging/media/tegra-video/csi.c b/drivers/staging/media/tegra-video/csi.c index e938bf4c48b6..b26e44adb2be 100644 --- a/drivers/staging/media/tegra-video/csi.c +++ b/drivers/staging/media/tegra-video/csi.c @@ -64,7 +64,7 @@ static const struct v4l2_frmsize_discrete tegra_csi_tpg_sizes[] = { * V4L2 Subdevice Pad Operations */ static int csi_enum_bus_code(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { if (!IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG)) @@ -79,7 +79,7 @@ static int csi_enum_bus_code(struct v4l2_subdev *subdev, } static int csi_get_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct tegra_csi_channel *csi_chan = to_csi_chan(subdev); @@ -127,7 +127,7 @@ static void csi_chan_update_blank_intervals(struct tegra_csi_channel *csi_chan, } static int csi_enum_framesizes(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { unsigned int i; @@ -154,7 +154,7 @@ static int csi_enum_framesizes(struct v4l2_subdev *subdev, } static int csi_enum_frameintervals(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_interval_enum *fie) { struct tegra_csi_channel *csi_chan = to_csi_chan(subdev); @@ -181,7 +181,7 @@ static int csi_enum_frameintervals(struct v4l2_subdev *subdev, } static int csi_set_format(struct v4l2_subdev *subdev, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { struct tegra_csi_channel *csi_chan = to_csi_chan(subdev); diff --git a/drivers/staging/media/tegra-video/vi.c b/drivers/staging/media/tegra-video/vi.c index b76e9110e706..89709cd06d4d 100644 --- a/drivers/staging/media/tegra-video/vi.c +++ b/drivers/staging/media/tegra-video/vi.c @@ -493,7 +493,7 @@ static int __tegra_channel_try_format(struct tegra_vi_channel *chan, const struct tegra_video_format *fmtinfo; struct v4l2_subdev *subdev; struct v4l2_subdev_format fmt; - struct v4l2_subdev_pad_config *pad_cfg; + struct v4l2_subdev_state *sd_state; struct v4l2_subdev_frame_size_enum fse = { .which = V4L2_SUBDEV_FORMAT_TRY, }; @@ -507,8 +507,8 @@ static int __tegra_channel_try_format(struct tegra_vi_channel *chan, if (!subdev) return -ENODEV; - pad_cfg = v4l2_subdev_alloc_pad_config(subdev); - if (!pad_cfg) + sd_state = v4l2_subdev_alloc_state(subdev); + if (!sd_state) return -ENOMEM; /* * Retrieve the format information and if requested format isn't @@ -532,33 +532,33 @@ static int __tegra_channel_try_format(struct tegra_vi_channel *chan, * If not available, try to get crop boundary from subdev. */ fse.code = fmtinfo->code; - ret = v4l2_subdev_call(subdev, pad, enum_frame_size, pad_cfg, &fse); + ret = v4l2_subdev_call(subdev, pad, enum_frame_size, sd_state, &fse); if (ret) { if (!v4l2_subdev_has_op(subdev, pad, get_selection)) { - pad_cfg->try_crop.width = 0; - pad_cfg->try_crop.height = 0; + sd_state->pads->try_crop.width = 0; + sd_state->pads->try_crop.height = 0; } else { ret = v4l2_subdev_call(subdev, pad, get_selection, NULL, &sdsel); if (ret) return -EINVAL; - pad_cfg->try_crop.width = sdsel.r.width; - pad_cfg->try_crop.height = sdsel.r.height; + sd_state->pads->try_crop.width = sdsel.r.width; + sd_state->pads->try_crop.height = sdsel.r.height; } } else { - pad_cfg->try_crop.width = fse.max_width; - pad_cfg->try_crop.height = fse.max_height; + sd_state->pads->try_crop.width = fse.max_width; + sd_state->pads->try_crop.height = fse.max_height; } - ret = v4l2_subdev_call(subdev, pad, set_fmt, pad_cfg, &fmt); + ret = v4l2_subdev_call(subdev, pad, set_fmt, sd_state, &fmt); if (ret < 0) return ret; v4l2_fill_pix_format(pix, &fmt.format); tegra_channel_fmt_align(chan, pix, fmtinfo->bpp); - v4l2_subdev_free_pad_config(pad_cfg); + v4l2_subdev_free_state(sd_state); return 0; } diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index d0e9a5bdb08b..89115ba4c0f2 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -623,6 +623,19 @@ struct v4l2_subdev_pad_config { struct v4l2_rect try_compose; }; +/** + * struct v4l2_subdev_state - Used for storing subdev state information. + * + * @pads: &struct v4l2_subdev_pad_config array + * + * This structure only needs to be passed to the pad op if the 'which' field + * of the main argument is set to %V4L2_SUBDEV_FORMAT_TRY. For + * %V4L2_SUBDEV_FORMAT_ACTIVE it is safe to pass %NULL. + */ +struct v4l2_subdev_state { + struct v4l2_subdev_pad_config *pads; +}; + /** * struct v4l2_subdev_pad_ops - v4l2-subdev pad level operations * @@ -687,27 +700,27 @@ struct v4l2_subdev_pad_config { */ struct v4l2_subdev_pad_ops { int (*init_cfg)(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg); + struct v4l2_subdev_state *state); int (*enum_mbus_code)(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *state, struct v4l2_subdev_mbus_code_enum *code); int (*enum_frame_size)(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *state, struct v4l2_subdev_frame_size_enum *fse); int (*enum_frame_interval)(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *state, struct v4l2_subdev_frame_interval_enum *fie); int (*get_fmt)(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *state, struct v4l2_subdev_format *format); int (*set_fmt)(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *state, struct v4l2_subdev_format *format); int (*get_selection)(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *state, struct v4l2_subdev_selection *sel); int (*set_selection)(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *state, struct v4l2_subdev_selection *sel); int (*get_edid)(struct v4l2_subdev *sd, struct v4l2_edid *edid); int (*set_edid)(struct v4l2_subdev *sd, struct v4l2_edid *edid); @@ -918,14 +931,14 @@ struct v4l2_subdev { * struct v4l2_subdev_fh - Used for storing subdev information per file handle * * @vfh: pointer to &struct v4l2_fh - * @pad: pointer to &struct v4l2_subdev_pad_config + * @state: pointer to &struct v4l2_subdev_state * @owner: module pointer to the owner of this file handle */ struct v4l2_subdev_fh { struct v4l2_fh vfh; struct module *owner; #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) - struct v4l2_subdev_pad_config *pad; + struct v4l2_subdev_state *state; #endif }; @@ -945,17 +958,17 @@ struct v4l2_subdev_fh { * &struct v4l2_subdev_pad_config->try_fmt * * @sd: pointer to &struct v4l2_subdev - * @cfg: pointer to &struct v4l2_subdev_pad_config array. - * @pad: index of the pad in the @cfg array. + * @state: pointer to &struct v4l2_subdev_state + * @pad: index of the pad in the &struct v4l2_subdev_state->pads array */ static inline struct v4l2_mbus_framefmt * v4l2_subdev_get_try_format(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *state, unsigned int pad) { if (WARN_ON(pad >= sd->entity.num_pads)) pad = 0; - return &cfg[pad].try_fmt; + return &state->pads[pad].try_fmt; } /** @@ -963,17 +976,17 @@ v4l2_subdev_get_try_format(struct v4l2_subdev *sd, * &struct v4l2_subdev_pad_config->try_crop * * @sd: pointer to &struct v4l2_subdev - * @cfg: pointer to &struct v4l2_subdev_pad_config array. - * @pad: index of the pad in the @cfg array. + * @state: pointer to &struct v4l2_subdev_state. + * @pad: index of the pad in the &struct v4l2_subdev_state->pads array. */ static inline struct v4l2_rect * v4l2_subdev_get_try_crop(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *state, unsigned int pad) { if (WARN_ON(pad >= sd->entity.num_pads)) pad = 0; - return &cfg[pad].try_crop; + return &state->pads[pad].try_crop; } /** @@ -981,17 +994,17 @@ v4l2_subdev_get_try_crop(struct v4l2_subdev *sd, * &struct v4l2_subdev_pad_config->try_compose * * @sd: pointer to &struct v4l2_subdev - * @cfg: pointer to &struct v4l2_subdev_pad_config array. - * @pad: index of the pad in the @cfg array. + * @state: pointer to &struct v4l2_subdev_state. + * @pad: index of the pad in the &struct v4l2_subdev_state->pads array. */ static inline struct v4l2_rect * v4l2_subdev_get_try_compose(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_state *state, unsigned int pad) { if (WARN_ON(pad >= sd->entity.num_pads)) pad = 0; - return &cfg[pad].try_compose; + return &state->pads[pad].try_compose; } #endif @@ -1093,20 +1106,21 @@ int v4l2_subdev_link_validate_default(struct v4l2_subdev *sd, int v4l2_subdev_link_validate(struct media_link *link); /** - * v4l2_subdev_alloc_pad_config - Allocates memory for pad config + * v4l2_subdev_alloc_state - allocate v4l2_subdev_state * - * @sd: pointer to struct v4l2_subdev + * @sd: pointer to &struct v4l2_subdev for which the state is being allocated. + * + * Must call v4l2_subdev_free_state() when state is no longer needed. */ -struct -v4l2_subdev_pad_config *v4l2_subdev_alloc_pad_config(struct v4l2_subdev *sd); +struct v4l2_subdev_state *v4l2_subdev_alloc_state(struct v4l2_subdev *sd); /** - * v4l2_subdev_free_pad_config - Frees memory allocated by - * v4l2_subdev_alloc_pad_config(). + * v4l2_subdev_free_state - free a v4l2_subdev_state * - * @cfg: pointer to &struct v4l2_subdev_pad_config + * @state: v4l2_subdev_state to be freed. */ -void v4l2_subdev_free_pad_config(struct v4l2_subdev_pad_config *cfg); +void v4l2_subdev_free_state(struct v4l2_subdev_state *state); + #endif /* CONFIG_MEDIA_CONTROLLER */ /** From b6c57d313f5f8d0da150f6e02882f0607443abe7 Mon Sep 17 00:00:00 2001 From: Alexandre Courbot Date: Sat, 5 Jun 2021 04:29:13 +0200 Subject: [PATCH 345/394] media: mtk-vcodec: venc: remove redundant code vidioc_try_fmt() does clamp height and width when called on the OUTPUT queue, so clamping them prior to calling this function is redundant. Set the queue's parameters after calling vidioc_try_fmt() so we can use the values it computed. Signed-off-by: Alexandre Courbot Signed-off-by: Irui Wang Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../media/platform/mtk-vcodec/mtk_vcodec_enc.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c index 4831052f475d..42ff13867940 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c @@ -443,7 +443,6 @@ static int vidioc_venc_s_fmt_out(struct file *file, void *priv, struct mtk_q_data *q_data; int ret, i; const struct mtk_video_fmt *fmt; - struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); if (!vq) { @@ -468,20 +467,13 @@ static int vidioc_venc_s_fmt_out(struct file *file, void *priv, f->fmt.pix.pixelformat = fmt->fourcc; } - pix_fmt_mp->height = clamp(pix_fmt_mp->height, - MTK_VENC_MIN_H, - MTK_VENC_MAX_H); - pix_fmt_mp->width = clamp(pix_fmt_mp->width, - MTK_VENC_MIN_W, - MTK_VENC_MAX_W); - - q_data->visible_width = f->fmt.pix_mp.width; - q_data->visible_height = f->fmt.pix_mp.height; - q_data->fmt = fmt; - ret = vidioc_try_fmt(f, q_data->fmt); + ret = vidioc_try_fmt(f, fmt); if (ret) return ret; + q_data->fmt = fmt; + q_data->visible_width = f->fmt.pix_mp.width; + q_data->visible_height = f->fmt.pix_mp.height; q_data->coded_width = f->fmt.pix_mp.width; q_data->coded_height = f->fmt.pix_mp.height; From 5cd57605771216755bd6f98748d4f11d1e65b780 Mon Sep 17 00:00:00 2001 From: Irui Wang Date: Sat, 5 Jun 2021 04:29:14 +0200 Subject: [PATCH 346/394] media: dt-bindings: media: mtk-vcodec: Add dma-ranges property The mt8192 iommu support 0~16GB iova. We separate it to four banks: 0~4G; 4G~8G; 8G~12G; 12G~16G. The "dma-ranges" could be used to adjust the bank we locate. If we don't set this property. The default range always is 0~4G. This is optional and only needed in mt8192, the dma ranges should not cross 4G/8G/12G. Here we don't have actual bus/parent concept here. And the iova requirement is for our HW. Thus put the property in our node. Acked-by: Rob Herring Signed-off-by: Irui Wang Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/devicetree/bindings/media/mediatek-vcodec.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt b/Documentation/devicetree/bindings/media/mediatek-vcodec.txt index 06db6837cefd..5bb9e6e191b7 100644 --- a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt +++ b/Documentation/devicetree/bindings/media/mediatek-vcodec.txt @@ -22,6 +22,7 @@ Required properties: - iommus : should point to the respective IOMMU block with master port as argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details. +- dma-ranges : describes the dma address range space that the codec hw access. One of the two following nodes: - mediatek,vpu : the node of the video processor unit, if using VPU. - mediatek,scp : the node of the SCP unit, if using SCP. From c2c3bde0e1aed4250e7eafb1bc739760c61d10b8 Mon Sep 17 00:00:00 2001 From: Irui Wang Date: Sat, 5 Jun 2021 04:29:15 +0200 Subject: [PATCH 347/394] media: mtk-vcodec: Support 34bits dma address for venc Use the dma_set_mask_and_coherent helper to set venc DMA bit mask to support 34bits iova space(16GB) that the mt8192 iommu HW support. Whole the iova range separate to 0~4G/4G~8G/8G~12G/12G~16G, regarding which iova range VENC actually locate, it depends on the dma-ranges property of venc dtsi node. Signed-off-by: Irui Wang Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c index 7d7b8cfc2cc5..26b089e81213 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c @@ -361,6 +361,9 @@ static int mtk_vcodec_probe(struct platform_device *pdev) goto err_event_workq; } + if (of_get_property(pdev->dev.of_node, "dma-ranges", NULL)) + dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(34)); + ret = video_register_device(vfd_enc, VFL_TYPE_VIDEO, 1); if (ret) { mtk_v4l2_err("Failed to register video device"); From aa950d8619694fb1a7d0e68aa556976e2f34476d Mon Sep 17 00:00:00 2001 From: Irui Wang Date: Sat, 5 Jun 2021 04:29:16 +0200 Subject: [PATCH 348/394] media: dt-bindings: media: mtk-vcodec: Add binding for MT8192 VENC Updates binding document for mt8192 encoder driver. Acked-by: Rob Herring Signed-off-by: Irui Wang Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/devicetree/bindings/media/mediatek-vcodec.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt b/Documentation/devicetree/bindings/media/mediatek-vcodec.txt index 5bb9e6e191b7..ad1321e5a22d 100644 --- a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt +++ b/Documentation/devicetree/bindings/media/mediatek-vcodec.txt @@ -9,6 +9,7 @@ Required properties: "mediatek,mt8173-vcodec-enc" for mt8173 avc encoder. "mediatek,mt8183-vcodec-enc" for MT8183 encoder. "mediatek,mt8173-vcodec-dec" for MT8173 decoder. + "mediatek,mt8192-vcodec-enc" for MT8192 encoder. - reg : Physical base address of the video codec registers and length of memory mapped region. - interrupts : interrupt number to the cpu. From 37eeacba7cb6bfbed9596e7b2f8b672e1c957ac7 Mon Sep 17 00:00:00 2001 From: Irui Wang Date: Sat, 5 Jun 2021 04:29:17 +0200 Subject: [PATCH 349/394] media: mtk-vcodec: Add MT8192 H264 venc driver Add MT8192 venc driver's compatible and device private data. Reviewed-by: Tzung-Bi Shih Signed-off-by: Irui Wang Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h | 1 + .../media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h index d03cca95e99b..14893d277bb8 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h @@ -302,6 +302,7 @@ struct mtk_vcodec_ctx { enum mtk_chip { MTK_MT8173, MTK_MT8183, + MTK_MT8192, }; /** diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c index 26b089e81213..45d1870c83dd 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c @@ -425,12 +425,26 @@ static const struct mtk_vcodec_enc_pdata mt8183_pdata = { .core_id = VENC_SYS, }; +static const struct mtk_vcodec_enc_pdata mt8192_pdata = { + .chip = MTK_MT8192, + .uses_ext = true, + /* MT8192 supports the same capture formats as MT8183 */ + .capture_formats = mtk_video_formats_capture_mt8183, + .num_capture_formats = ARRAY_SIZE(mtk_video_formats_capture_mt8183), + /* MT8192 supports the same output formats as MT8173 */ + .output_formats = mtk_video_formats_output_mt8173, + .num_output_formats = ARRAY_SIZE(mtk_video_formats_output_mt8173), + .min_bitrate = 64, + .max_bitrate = 100000000, + .core_id = VENC_SYS, +}; static const struct of_device_id mtk_vcodec_enc_match[] = { {.compatible = "mediatek,mt8173-vcodec-enc", .data = &mt8173_avc_pdata}, {.compatible = "mediatek,mt8173-vcodec-enc-vp8", .data = &mt8173_vp8_pdata}, {.compatible = "mediatek,mt8183-vcodec-enc", .data = &mt8183_pdata}, + {.compatible = "mediatek,mt8192-vcodec-enc", .data = &mt8192_pdata}, {}, }; MODULE_DEVICE_TABLE(of, mtk_vcodec_enc_match); From caf231ac25bdde69d257366e2f8d13b37af5458e Mon Sep 17 00:00:00 2001 From: Irui Wang Date: Sat, 5 Jun 2021 04:29:18 +0200 Subject: [PATCH 350/394] media: mtk-vcodec: Support MT8192 H264 4K encoding MT8192 H264 support 4k(3840x2176) and Level 5.1 encoding, add related path according to enc_capability. Signed-off-by: Irui Wang Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../platform/mtk-vcodec/mtk_vcodec_enc.c | 78 +++++++++++++------ .../platform/mtk-vcodec/venc/venc_h264_if.c | 4 + 2 files changed, 57 insertions(+), 25 deletions(-) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c index 42ff13867940..416f356af363 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c @@ -19,23 +19,30 @@ #define MTK_VENC_MIN_W 160U #define MTK_VENC_MIN_H 128U -#define MTK_VENC_MAX_W 1920U -#define MTK_VENC_MAX_H 1088U +#define MTK_VENC_HD_MAX_W 1920U +#define MTK_VENC_HD_MAX_H 1088U +#define MTK_VENC_4K_MAX_W 3840U +#define MTK_VENC_4K_MAX_H 2176U + #define DFT_CFG_WIDTH MTK_VENC_MIN_W #define DFT_CFG_HEIGHT MTK_VENC_MIN_H #define MTK_MAX_CTRLS_HINT 20 #define MTK_DEFAULT_FRAMERATE_NUM 1001 #define MTK_DEFAULT_FRAMERATE_DENOM 30000 +#define MTK_VENC_4K_CAPABILITY_ENABLE BIT(0) static void mtk_venc_worker(struct work_struct *work); -static const struct v4l2_frmsize_stepwise mtk_venc_framesizes = { - MTK_VENC_MIN_W, MTK_VENC_MAX_W, 16, - MTK_VENC_MIN_H, MTK_VENC_MAX_H, 16, +static const struct v4l2_frmsize_stepwise mtk_venc_hd_framesizes = { + MTK_VENC_MIN_W, MTK_VENC_HD_MAX_W, 16, + MTK_VENC_MIN_H, MTK_VENC_HD_MAX_H, 16, }; -#define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(mtk_venc_framesizes) +static const struct v4l2_frmsize_stepwise mtk_venc_4k_framesizes = { + MTK_VENC_MIN_W, MTK_VENC_4K_MAX_W, 16, + MTK_VENC_MIN_H, MTK_VENC_4K_MAX_H, 16, +}; static int vidioc_venc_s_ctrl(struct v4l2_ctrl *ctrl) { @@ -151,17 +158,22 @@ static int vidioc_enum_framesizes(struct file *file, void *fh, struct v4l2_frmsizeenum *fsize) { const struct mtk_video_fmt *fmt; + struct mtk_vcodec_ctx *ctx = fh_to_ctx(fh); if (fsize->index != 0) return -EINVAL; fmt = mtk_venc_find_format(fsize->pixel_format, - fh_to_ctx(fh)->dev->venc_pdata); + ctx->dev->venc_pdata); if (!fmt) return -EINVAL; fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; - fsize->stepwise = mtk_venc_framesizes; + + if (ctx->dev->enc_capability & MTK_VENC_4K_CAPABILITY_ENABLE) + fsize->stepwise = mtk_venc_4k_framesizes; + else + fsize->stepwise = mtk_venc_hd_framesizes; return 0; } @@ -248,7 +260,7 @@ static struct mtk_q_data *mtk_venc_get_q_data(struct mtk_vcodec_ctx *ctx, /* V4L2 specification suggests the driver corrects the format struct if any of * the dimensions is unsupported */ -static int vidioc_try_fmt(struct v4l2_format *f, +static int vidioc_try_fmt(struct mtk_vcodec_ctx *ctx, struct v4l2_format *f, const struct mtk_video_fmt *fmt) { struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; @@ -260,13 +272,22 @@ static int vidioc_try_fmt(struct v4l2_format *f, pix_fmt_mp->plane_fmt[0].bytesperline = 0; } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { int tmp_w, tmp_h; + unsigned int max_width, max_height; + + if (ctx->dev->enc_capability & MTK_VENC_4K_CAPABILITY_ENABLE) { + max_width = MTK_VENC_4K_MAX_W; + max_height = MTK_VENC_4K_MAX_H; + } else { + max_width = MTK_VENC_HD_MAX_W; + max_height = MTK_VENC_HD_MAX_H; + } pix_fmt_mp->height = clamp(pix_fmt_mp->height, MTK_VENC_MIN_H, - MTK_VENC_MAX_H); + max_height); pix_fmt_mp->width = clamp(pix_fmt_mp->width, MTK_VENC_MIN_W, - MTK_VENC_MAX_W); + max_width); /* find next closer width align 16, heign align 32, size align * 64 rectangle @@ -275,16 +296,16 @@ static int vidioc_try_fmt(struct v4l2_format *f, tmp_h = pix_fmt_mp->height; v4l_bound_align_image(&pix_fmt_mp->width, MTK_VENC_MIN_W, - MTK_VENC_MAX_W, 4, + max_width, 4, &pix_fmt_mp->height, MTK_VENC_MIN_H, - MTK_VENC_MAX_H, 5, 6); + max_height, 5, 6); if (pix_fmt_mp->width < tmp_w && - (pix_fmt_mp->width + 16) <= MTK_VENC_MAX_W) + (pix_fmt_mp->width + 16) <= max_width) pix_fmt_mp->width += 16; if (pix_fmt_mp->height < tmp_h && - (pix_fmt_mp->height + 32) <= MTK_VENC_MAX_H) + (pix_fmt_mp->height + 32) <= max_height) pix_fmt_mp->height += 32; mtk_v4l2_debug(0, @@ -405,7 +426,7 @@ static int vidioc_venc_s_fmt_cap(struct file *file, void *priv, } q_data->fmt = fmt; - ret = vidioc_try_fmt(f, q_data->fmt); + ret = vidioc_try_fmt(ctx, f, q_data->fmt); if (ret) return ret; @@ -467,7 +488,7 @@ static int vidioc_venc_s_fmt_out(struct file *file, void *priv, f->fmt.pix.pixelformat = fmt->fourcc; } - ret = vidioc_try_fmt(f, fmt); + ret = vidioc_try_fmt(ctx, f, fmt); if (ret) return ret; @@ -545,7 +566,7 @@ static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv, f->fmt.pix_mp.quantization = ctx->quantization; f->fmt.pix_mp.xfer_func = ctx->xfer_func; - return vidioc_try_fmt(f, fmt); + return vidioc_try_fmt(ctx, f, fmt); } static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv, @@ -567,7 +588,7 @@ static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv, f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT; } - return vidioc_try_fmt(f, fmt); + return vidioc_try_fmt(ctx, f, fmt); } static int vidioc_venc_g_selection(struct file *file, void *priv, @@ -1171,16 +1192,16 @@ void mtk_vcodec_enc_set_default_params(struct mtk_vcodec_ctx *ctx) v4l_bound_align_image(&q_data->coded_width, MTK_VENC_MIN_W, - MTK_VENC_MAX_W, 4, + MTK_VENC_HD_MAX_W, 4, &q_data->coded_height, MTK_VENC_MIN_H, - MTK_VENC_MAX_H, 5, 6); + MTK_VENC_HD_MAX_H, 5, 6); if (q_data->coded_width < DFT_CFG_WIDTH && - (q_data->coded_width + 16) <= MTK_VENC_MAX_W) + (q_data->coded_width + 16) <= MTK_VENC_HD_MAX_W) q_data->coded_width += 16; if (q_data->coded_height < DFT_CFG_HEIGHT && - (q_data->coded_height + 32) <= MTK_VENC_MAX_H) + (q_data->coded_height + 32) <= MTK_VENC_HD_MAX_H) q_data->coded_height += 32; q_data->sizeimage[0] = @@ -1210,6 +1231,12 @@ int mtk_vcodec_enc_ctrls_setup(struct mtk_vcodec_ctx *ctx) { const struct v4l2_ctrl_ops *ops = &mtk_vcodec_enc_ctrl_ops; struct v4l2_ctrl_handler *handler = &ctx->ctrl_hdl; + u8 h264_max_level; + + if (ctx->dev->enc_capability & MTK_VENC_4K_CAPABILITY_ENABLE) + h264_max_level = V4L2_MPEG_VIDEO_H264_LEVEL_5_1; + else + h264_max_level = V4L2_MPEG_VIDEO_H264_LEVEL_4_2; v4l2_ctrl_handler_init(handler, MTK_MAX_CTRLS_HINT); @@ -1240,8 +1267,9 @@ int mtk_vcodec_enc_ctrls_setup(struct mtk_vcodec_ctx *ctx) V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, 0, V4L2_MPEG_VIDEO_H264_PROFILE_HIGH); v4l2_ctrl_new_std_menu(handler, ops, V4L2_CID_MPEG_VIDEO_H264_LEVEL, - V4L2_MPEG_VIDEO_H264_LEVEL_4_2, - 0, V4L2_MPEG_VIDEO_H264_LEVEL_4_0); + h264_max_level, + 0, V4L2_MPEG_VIDEO_H264_LEVEL_4_0); + if (handler->error) { mtk_v4l2_err("Init control handler fail %d", handler->error); diff --git a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c index d0123dfc5f93..b6a4f2074fa5 100644 --- a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c +++ b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c @@ -215,6 +215,10 @@ static unsigned int h264_get_level(struct venc_h264_inst *inst, return 41; case V4L2_MPEG_VIDEO_H264_LEVEL_4_2: return 42; + case V4L2_MPEG_VIDEO_H264_LEVEL_5_0: + return 50; + case V4L2_MPEG_VIDEO_H264_LEVEL_5_1: + return 51; default: mtk_vcodec_debug(inst, "unsupported level %d", level); return 31; From c344f07aa1b4ba38ca8fabe407a2afe2f436323c Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 14 Jun 2021 12:34:02 +0200 Subject: [PATCH 351/394] media: v4l2-core: ignore native time32 ioctls on 64-bit Syzbot found that passing ioctl command 0xc0505609 into a 64-bit kernel from a 32-bit process causes uninitialized kernel memory to get passed to drivers instead of the user space data: BUG: KMSAN: uninit-value in check_array_args drivers/media/v4l2-core/v4l2-ioctl.c:3041 [inline] BUG: KMSAN: uninit-value in video_usercopy+0x1631/0x3d30 drivers/media/v4l2-core/v4l2-ioctl.c:3315 CPU: 0 PID: 19595 Comm: syz-executor.4 Not tainted 5.11.0-rc7-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:79 [inline] dump_stack+0x21c/0x280 lib/dump_stack.c:120 kmsan_report+0xfb/0x1e0 mm/kmsan/kmsan_report.c:118 __msan_warning+0x5f/0xa0 mm/kmsan/kmsan_instr.c:197 check_array_args drivers/media/v4l2-core/v4l2-ioctl.c:3041 [inline] video_usercopy+0x1631/0x3d30 drivers/media/v4l2-core/v4l2-ioctl.c:3315 video_ioctl2+0x9f/0xb0 drivers/media/v4l2-core/v4l2-ioctl.c:3391 v4l2_ioctl+0x255/0x290 drivers/media/v4l2-core/v4l2-dev.c:360 v4l2_compat_ioctl32+0x2c6/0x370 drivers/media/v4l2-core/v4l2-compat-ioctl32.c:1248 __do_compat_sys_ioctl fs/ioctl.c:842 [inline] __se_compat_sys_ioctl+0x53d/0x1100 fs/ioctl.c:793 __ia32_compat_sys_ioctl+0x4a/0x70 fs/ioctl.c:793 do_syscall_32_irqs_on arch/x86/entry/common.c:79 [inline] __do_fast_syscall_32+0x102/0x160 arch/x86/entry/common.c:141 do_fast_syscall_32+0x6a/0xc0 arch/x86/entry/common.c:166 do_SYSENTER_32+0x73/0x90 arch/x86/entry/common.c:209 entry_SYSENTER_compat_after_hwframe+0x4d/0x5c The time32 commands are defined but were never meant to be called on 64-bit machines, as those have always used time64 interfaces. I missed this in my patch that introduced the time64 handling on 32-bit platforms. The problem in this case is the mismatch of one function checking for the numeric value of the command and another function checking for the type of process (native vs compat) instead, with the result being that for this combination, nothing gets copied into the buffer at all. Avoid this by only trying to convert the time32 commands when running on a 32-bit kernel where these are defined in a meaningful way. [hverkuil: fix 3 warnings: switch with no cases] Fixes: 577c89b0ce72 ("media: v4l2-core: fix v4l2_buffer handling for time64 ABI") Reported-by: syzbot+142888ffec98ab194028@syzkaller.appspotmail.com Signed-off-by: Arnd Bergmann Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-ioctl.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 2673f51aafa4..07d823656ee6 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -3072,8 +3072,8 @@ static int check_array_args(unsigned int cmd, void *parg, size_t *array_size, static unsigned int video_translate_cmd(unsigned int cmd) { +#if !defined(CONFIG_64BIT) && defined(CONFIG_COMPAT_32BIT_TIME) switch (cmd) { -#ifdef CONFIG_COMPAT_32BIT_TIME case VIDIOC_DQEVENT_TIME32: return VIDIOC_DQEVENT; case VIDIOC_QUERYBUF_TIME32: @@ -3084,8 +3084,8 @@ static unsigned int video_translate_cmd(unsigned int cmd) return VIDIOC_DQBUF; case VIDIOC_PREPARE_BUF_TIME32: return VIDIOC_PREPARE_BUF; -#endif } +#endif if (in_compat_syscall()) return v4l2_compat_translate_cmd(cmd); @@ -3126,8 +3126,8 @@ static int video_get_user(void __user *arg, void *parg, } else if (in_compat_syscall()) { err = v4l2_compat_get_user(arg, parg, cmd); } else { +#if !defined(CONFIG_64BIT) && defined(CONFIG_COMPAT_32BIT_TIME) switch (cmd) { -#ifdef CONFIG_COMPAT_32BIT_TIME case VIDIOC_QUERYBUF_TIME32: case VIDIOC_QBUF_TIME32: case VIDIOC_DQBUF_TIME32: @@ -3155,8 +3155,8 @@ static int video_get_user(void __user *arg, void *parg, }; break; } -#endif } +#endif } /* zero out anything we don't copy from userspace */ @@ -3181,8 +3181,8 @@ static int video_put_user(void __user *arg, void *parg, if (in_compat_syscall()) return v4l2_compat_put_user(arg, parg, cmd); +#if !defined(CONFIG_64BIT) && defined(CONFIG_COMPAT_32BIT_TIME) switch (cmd) { -#ifdef CONFIG_COMPAT_32BIT_TIME case VIDIOC_DQEVENT_TIME32: { struct v4l2_event *ev = parg; struct v4l2_event_time32 ev32; @@ -3230,8 +3230,8 @@ static int video_put_user(void __user *arg, void *parg, return -EFAULT; break; } -#endif } +#endif return 0; } From 7b53cca764f9b291b7907fcd39d9e66ad728ee0b Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 14 Jun 2021 12:34:03 +0200 Subject: [PATCH 352/394] media: v4l2-core: explicitly clear ioctl input data As seen from a recent syzbot bug report, mistakes in the compat ioctl implementation can lead to uninitialized kernel stack data getting used as input for driver ioctl handlers. The reported bug is now fixed, but it's possible that other related bugs are still present or get added in the future. As the drivers need to check user input already, the possible impact is fairly low, but it might still cause an information leak. To be on the safe side, always clear the entire ioctl buffer before calling the conversion handler functions that are meant to initialize them. Signed-off-by: Arnd Bergmann Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-ioctl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 07d823656ee6..cf50c60bbb5d 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -3124,8 +3124,10 @@ static int video_get_user(void __user *arg, void *parg, if (copy_from_user(parg, (void __user *)arg, n)) err = -EFAULT; } else if (in_compat_syscall()) { + memset(parg, 0, n); err = v4l2_compat_get_user(arg, parg, cmd); } else { + memset(parg, 0, n); #if !defined(CONFIG_64BIT) && defined(CONFIG_COMPAT_32BIT_TIME) switch (cmd) { case VIDIOC_QUERYBUF_TIME32: From e84c8932897e8c59e01c33f4052a72d5b2890884 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 14 Jun 2021 12:34:04 +0200 Subject: [PATCH 353/394] media: v4l2-core: fix whitespace damage in video_get_user() The initialization was indented with an extra tab in most lines, remove them to get the normal coding style. Signed-off-by: Arnd Bergmann Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-ioctl.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index cf50c60bbb5d..05d5db3d85e5 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -3142,18 +3142,18 @@ static int video_get_user(void __user *arg, void *parg, *vb = (struct v4l2_buffer) { .index = vb32.index, - .type = vb32.type, - .bytesused = vb32.bytesused, - .flags = vb32.flags, - .field = vb32.field, - .timestamp.tv_sec = vb32.timestamp.tv_sec, - .timestamp.tv_usec = vb32.timestamp.tv_usec, - .timecode = vb32.timecode, - .sequence = vb32.sequence, - .memory = vb32.memory, - .m.userptr = vb32.m.userptr, - .length = vb32.length, - .request_fd = vb32.request_fd, + .type = vb32.type, + .bytesused = vb32.bytesused, + .flags = vb32.flags, + .field = vb32.field, + .timestamp.tv_sec = vb32.timestamp.tv_sec, + .timestamp.tv_usec = vb32.timestamp.tv_usec, + .timecode = vb32.timecode, + .sequence = vb32.sequence, + .memory = vb32.memory, + .m.userptr = vb32.m.userptr, + .length = vb32.length, + .request_fd = vb32.request_fd, }; break; } From 765ba251d2522e2a0daa2f0793fd0f0ce34816ec Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 14 Jun 2021 12:34:05 +0200 Subject: [PATCH 354/394] media: subdev: remove VIDIOC_DQEVENT_TIME32 handling Converting the VIDIOC_DQEVENT_TIME32/VIDIOC_DQEVENT32/ VIDIOC_DQEVENT32_TIME32 arguments to the canonical form is done in common code, but for some reason I ended up adding another conversion helper to subdev_do_ioctl() as well. I must have concluded that this does not go through the common conversion, but it has done that since the ioctl handler was first added. I assume this one is harmless as there should be no way to arrive here from user space if CONFIG_COMPAT_32BIT_TIME is set, but since it is dead code, it should just get removed. On a 64-bit architecture, as well as a 32-bit architecture without CONFIG_COMPAT_32BIT_TIME, handling this command is a mistake, and the kernel should return an error. Fixes: 1a6c0b36dd19 ("media: v4l2-core: fix VIDIOC_DQEVENT for time64 ABI") Signed-off-by: Arnd Bergmann Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-subdev.c | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index 6d3e03036519..5d27a27cc2f2 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -430,30 +430,6 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) return v4l2_event_dequeue(vfh, arg, file->f_flags & O_NONBLOCK); - case VIDIOC_DQEVENT_TIME32: { - struct v4l2_event_time32 *ev32 = arg; - struct v4l2_event ev = { }; - - if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS)) - return -ENOIOCTLCMD; - - rval = v4l2_event_dequeue(vfh, &ev, file->f_flags & O_NONBLOCK); - - *ev32 = (struct v4l2_event_time32) { - .type = ev.type, - .pending = ev.pending, - .sequence = ev.sequence, - .timestamp.tv_sec = ev.timestamp.tv_sec, - .timestamp.tv_nsec = ev.timestamp.tv_nsec, - .id = ev.id, - }; - - memcpy(&ev32->u, &ev.u, sizeof(ev.u)); - memcpy(&ev32->reserved, &ev.reserved, sizeof(ev.reserved)); - - return rval; - } - case VIDIOC_SUBSCRIBE_EVENT: return v4l2_subdev_call(sd, core, subscribe_event, vfh, arg); From 8162f78d27c61e148a4342c62bddef3c26135bcb Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 14 Jun 2021 12:34:06 +0200 Subject: [PATCH 355/394] media: v4l2-core: return -ENODEV from ioctl when not registered I spotted a minor difference is handling of unregistered devices between native and compat ioctls: the native handler never tries to call into the driver if a device is not marked as registered. I did not check whether this can cause issues in the kernel, or just a different between return codes, but it clearly makes sense that both should behave the same way. Signed-off-by: Arnd Bergmann Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c index 0ca75f6784c5..47aff3b19742 100644 --- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c @@ -1244,6 +1244,9 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) if (!file->f_op->unlocked_ioctl) return ret; + if (!video_is_registered(vdev)) + return -ENODEV; + if (_IOC_TYPE(cmd) == 'V' && _IOC_NR(cmd) < BASE_VIDIOC_PRIVATE) ret = file->f_op->unlocked_ioctl(file, cmd, (unsigned long)compat_ptr(arg)); From b4c650f1af68251f1970aecfc3c2fceec1552da2 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 14 Jun 2021 12:34:07 +0200 Subject: [PATCH 356/394] media: atomisp: remove compat_ioctl32 code This is one of the last remaining users of compat_alloc_user_space() and copy_in_user(), which are in the process of getting removed. As of commit 57e6b6f2303e ("media: atomisp_fops.c: disable atomisp_compat_ioctl32"), nothing in this file is actually getting used as the only reference has been stubbed out. Remove the entire file -- anyone willing to restore the functionality can equally well just look up the contents in the git history if needed. Acked-by: Sakari Ailus Suggested-by: Christoph Hellwig Reviewed-by: Andy Shevchenko Acked-by: Laurent Pinchart Signed-off-by: Arnd Bergmann Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/Makefile | 1 - drivers/staging/media/atomisp/TODO | 5 + .../atomisp/pci/atomisp_compat_ioctl32.c | 1202 ----------------- .../staging/media/atomisp/pci/atomisp_fops.c | 8 +- 4 files changed, 8 insertions(+), 1208 deletions(-) delete mode 100644 drivers/staging/media/atomisp/pci/atomisp_compat_ioctl32.c diff --git a/drivers/staging/media/atomisp/Makefile b/drivers/staging/media/atomisp/Makefile index 51498b2e85b8..606b7754fdfd 100644 --- a/drivers/staging/media/atomisp/Makefile +++ b/drivers/staging/media/atomisp/Makefile @@ -16,7 +16,6 @@ atomisp-objs += \ pci/atomisp_acc.o \ pci/atomisp_cmd.o \ pci/atomisp_compat_css20.o \ - pci/atomisp_compat_ioctl32.o \ pci/atomisp_csi2.o \ pci/atomisp_drvfs.o \ pci/atomisp_file.o \ diff --git a/drivers/staging/media/atomisp/TODO b/drivers/staging/media/atomisp/TODO index 6987bb2d32cf..2d1ef9eb262a 100644 --- a/drivers/staging/media/atomisp/TODO +++ b/drivers/staging/media/atomisp/TODO @@ -120,6 +120,11 @@ TODO for this driver until the other work is done, as there will be a lot of code churn until this driver becomes functional again. +16. Fix private ioctls to not need a compat_ioctl handler for running + 32-bit tasks. The compat code has been removed because of bugs, + and should not be needed for modern drivers. Fixing this properly + unfortunately means an incompatible ABI change. + Limitations =========== diff --git a/drivers/staging/media/atomisp/pci/atomisp_compat_ioctl32.c b/drivers/staging/media/atomisp/pci/atomisp_compat_ioctl32.c deleted file mode 100644 index e5553df5bad4..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp_compat_ioctl32.c +++ /dev/null @@ -1,1202 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Support for Intel Camera Imaging ISP subsystem. - * - * Copyright (c) 2013 Intel Corporation. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - */ -#ifdef CONFIG_COMPAT -#include - -#include - -#include "atomisp_internal.h" -#include "atomisp_compat.h" -#include "atomisp_ioctl.h" -#include "atomisp_compat_ioctl32.h" - -/* Macros borrowed from v4l2-compat-ioctl32.c */ - -#define get_user_cast(__x, __ptr) \ -({ \ - get_user(__x, (typeof(*__ptr) __user *)(__ptr)); \ -}) - -#define put_user_force(__x, __ptr) \ -({ \ - put_user((typeof(*__x) __force *)(__x), __ptr); \ -}) - -/* Use the same argument order as copy_in_user */ -#define assign_in_user(to, from) \ -({ \ - typeof(*from) __assign_tmp; \ - \ - get_user_cast(__assign_tmp, from) || put_user(__assign_tmp, to);\ -}) - -static int get_atomisp_histogram32(struct atomisp_histogram __user *kp, - struct atomisp_histogram32 __user *up) -{ - compat_uptr_t tmp; - - if (!access_ok(up, sizeof(struct atomisp_histogram32)) || - assign_in_user(&kp->num_elements, &up->num_elements) || - get_user(tmp, &up->data) || - put_user(compat_ptr(tmp), &kp->data)) - return -EFAULT; - - return 0; -} - -static int put_atomisp_histogram32(struct atomisp_histogram __user *kp, - struct atomisp_histogram32 __user *up) -{ - void __user *tmp; - - if (!access_ok(up, sizeof(struct atomisp_histogram32)) || - assign_in_user(&up->num_elements, &kp->num_elements) || - get_user(tmp, &kp->data) || - put_user(ptr_to_compat(tmp), &up->data)) - return -EFAULT; - - return 0; -} - -static int get_v4l2_framebuffer32(struct v4l2_framebuffer __user *kp, - struct v4l2_framebuffer32 __user *up) -{ - compat_uptr_t tmp; - - if (!access_ok(up, sizeof(struct v4l2_framebuffer32)) || - get_user(tmp, &up->base) || - put_user_force(compat_ptr(tmp), &kp->base) || - assign_in_user(&kp->capability, &up->capability) || - assign_in_user(&kp->flags, &up->flags) || - copy_in_user(&kp->fmt, &up->fmt, sizeof(kp->fmt))) - return -EFAULT; - - return 0; -} - -static int get_atomisp_dis_statistics32(struct atomisp_dis_statistics __user *kp, - struct atomisp_dis_statistics32 __user *up) -{ - compat_uptr_t hor_prod_odd_real; - compat_uptr_t hor_prod_odd_imag; - compat_uptr_t hor_prod_even_real; - compat_uptr_t hor_prod_even_imag; - compat_uptr_t ver_prod_odd_real; - compat_uptr_t ver_prod_odd_imag; - compat_uptr_t ver_prod_even_real; - compat_uptr_t ver_prod_even_imag; - - if (!access_ok(up, sizeof(struct atomisp_dis_statistics32)) || - copy_in_user(kp, up, sizeof(struct atomisp_dvs_grid_info)) || - get_user(hor_prod_odd_real, - &up->dvs2_stat.hor_prod.odd_real) || - get_user(hor_prod_odd_imag, - &up->dvs2_stat.hor_prod.odd_imag) || - get_user(hor_prod_even_real, - &up->dvs2_stat.hor_prod.even_real) || - get_user(hor_prod_even_imag, - &up->dvs2_stat.hor_prod.even_imag) || - get_user(ver_prod_odd_real, - &up->dvs2_stat.ver_prod.odd_real) || - get_user(ver_prod_odd_imag, - &up->dvs2_stat.ver_prod.odd_imag) || - get_user(ver_prod_even_real, - &up->dvs2_stat.ver_prod.even_real) || - get_user(ver_prod_even_imag, - &up->dvs2_stat.ver_prod.even_imag) || - assign_in_user(&kp->exp_id, &up->exp_id) || - put_user(compat_ptr(hor_prod_odd_real), - &kp->dvs2_stat.hor_prod.odd_real) || - put_user(compat_ptr(hor_prod_odd_imag), - &kp->dvs2_stat.hor_prod.odd_imag) || - put_user(compat_ptr(hor_prod_even_real), - &kp->dvs2_stat.hor_prod.even_real) || - put_user(compat_ptr(hor_prod_even_imag), - &kp->dvs2_stat.hor_prod.even_imag) || - put_user(compat_ptr(ver_prod_odd_real), - &kp->dvs2_stat.ver_prod.odd_real) || - put_user(compat_ptr(ver_prod_odd_imag), - &kp->dvs2_stat.ver_prod.odd_imag) || - put_user(compat_ptr(ver_prod_even_real), - &kp->dvs2_stat.ver_prod.even_real) || - put_user(compat_ptr(ver_prod_even_imag), - &kp->dvs2_stat.ver_prod.even_imag)) - return -EFAULT; - - return 0; -} - -static int put_atomisp_dis_statistics32(struct atomisp_dis_statistics __user *kp, - struct atomisp_dis_statistics32 __user *up) -{ - void __user *hor_prod_odd_real; - void __user *hor_prod_odd_imag; - void __user *hor_prod_even_real; - void __user *hor_prod_even_imag; - void __user *ver_prod_odd_real; - void __user *ver_prod_odd_imag; - void __user *ver_prod_even_real; - void __user *ver_prod_even_imag; - - if (!!access_ok(up, sizeof(struct atomisp_dis_statistics32)) || - copy_in_user(up, kp, sizeof(struct atomisp_dvs_grid_info)) || - get_user(hor_prod_odd_real, - &kp->dvs2_stat.hor_prod.odd_real) || - get_user(hor_prod_odd_imag, - &kp->dvs2_stat.hor_prod.odd_imag) || - get_user(hor_prod_even_real, - &kp->dvs2_stat.hor_prod.even_real) || - get_user(hor_prod_even_imag, - &kp->dvs2_stat.hor_prod.even_imag) || - get_user(ver_prod_odd_real, - &kp->dvs2_stat.ver_prod.odd_real) || - get_user(ver_prod_odd_imag, - &kp->dvs2_stat.ver_prod.odd_imag) || - get_user(ver_prod_even_real, - &kp->dvs2_stat.ver_prod.even_real) || - get_user(ver_prod_even_imag, - &kp->dvs2_stat.ver_prod.even_imag) || - put_user(ptr_to_compat(hor_prod_odd_real), - &up->dvs2_stat.hor_prod.odd_real) || - put_user(ptr_to_compat(hor_prod_odd_imag), - &up->dvs2_stat.hor_prod.odd_imag) || - put_user(ptr_to_compat(hor_prod_even_real), - &up->dvs2_stat.hor_prod.even_real) || - put_user(ptr_to_compat(hor_prod_even_imag), - &up->dvs2_stat.hor_prod.even_imag) || - put_user(ptr_to_compat(ver_prod_odd_real), - &up->dvs2_stat.ver_prod.odd_real) || - put_user(ptr_to_compat(ver_prod_odd_imag), - &up->dvs2_stat.ver_prod.odd_imag) || - put_user(ptr_to_compat(ver_prod_even_real), - &up->dvs2_stat.ver_prod.even_real) || - put_user(ptr_to_compat(ver_prod_even_imag), - &up->dvs2_stat.ver_prod.even_imag) || - assign_in_user(&up->exp_id, &kp->exp_id)) - return -EFAULT; - - return 0; -} - -static int get_atomisp_dis_coefficients32(struct atomisp_dis_coefficients __user *kp, - struct atomisp_dis_coefficients32 __user *up) -{ - compat_uptr_t hor_coefs_odd_real; - compat_uptr_t hor_coefs_odd_imag; - compat_uptr_t hor_coefs_even_real; - compat_uptr_t hor_coefs_even_imag; - compat_uptr_t ver_coefs_odd_real; - compat_uptr_t ver_coefs_odd_imag; - compat_uptr_t ver_coefs_even_real; - compat_uptr_t ver_coefs_even_imag; - - if (!access_ok(up, sizeof(struct atomisp_dis_coefficients32)) || - copy_in_user(kp, up, sizeof(struct atomisp_dvs_grid_info)) || - get_user(hor_coefs_odd_real, &up->hor_coefs.odd_real) || - get_user(hor_coefs_odd_imag, &up->hor_coefs.odd_imag) || - get_user(hor_coefs_even_real, &up->hor_coefs.even_real) || - get_user(hor_coefs_even_imag, &up->hor_coefs.even_imag) || - get_user(ver_coefs_odd_real, &up->ver_coefs.odd_real) || - get_user(ver_coefs_odd_imag, &up->ver_coefs.odd_imag) || - get_user(ver_coefs_even_real, &up->ver_coefs.even_real) || - get_user(ver_coefs_even_imag, &up->ver_coefs.even_imag) || - put_user(compat_ptr(hor_coefs_odd_real), - &kp->hor_coefs.odd_real) || - put_user(compat_ptr(hor_coefs_odd_imag), - &kp->hor_coefs.odd_imag) || - put_user(compat_ptr(hor_coefs_even_real), - &kp->hor_coefs.even_real) || - put_user(compat_ptr(hor_coefs_even_imag), - &kp->hor_coefs.even_imag) || - put_user(compat_ptr(ver_coefs_odd_real), - &kp->ver_coefs.odd_real) || - put_user(compat_ptr(ver_coefs_odd_imag), - &kp->ver_coefs.odd_imag) || - put_user(compat_ptr(ver_coefs_even_real), - &kp->ver_coefs.even_real) || - put_user(compat_ptr(ver_coefs_even_imag), - &kp->ver_coefs.even_imag)) - return -EFAULT; - - return 0; -} - -static int get_atomisp_dvs_6axis_config32(struct atomisp_dvs_6axis_config __user *kp, - struct atomisp_dvs_6axis_config32 __user *up) -{ - compat_uptr_t xcoords_y; - compat_uptr_t ycoords_y; - compat_uptr_t xcoords_uv; - compat_uptr_t ycoords_uv; - - if (!access_ok(up, sizeof(struct atomisp_dvs_6axis_config32)) || - assign_in_user(&kp->exp_id, &up->exp_id) || - assign_in_user(&kp->width_y, &up->width_y) || - assign_in_user(&kp->height_y, &up->height_y) || - assign_in_user(&kp->width_uv, &up->width_uv) || - assign_in_user(&kp->height_uv, &up->height_uv) || - get_user(xcoords_y, &up->xcoords_y) || - get_user(ycoords_y, &up->ycoords_y) || - get_user(xcoords_uv, &up->xcoords_uv) || - get_user(ycoords_uv, &up->ycoords_uv) || - put_user_force(compat_ptr(xcoords_y), &kp->xcoords_y) || - put_user_force(compat_ptr(ycoords_y), &kp->ycoords_y) || - put_user_force(compat_ptr(xcoords_uv), &kp->xcoords_uv) || - put_user_force(compat_ptr(ycoords_uv), &kp->ycoords_uv)) - return -EFAULT; - - return 0; -} - -static int get_atomisp_3a_statistics32(struct atomisp_3a_statistics __user *kp, - struct atomisp_3a_statistics32 __user *up) -{ - compat_uptr_t data; - compat_uptr_t rgby_data; - - if (!access_ok(up, sizeof(struct atomisp_3a_statistics32)) || - copy_in_user(kp, up, sizeof(struct atomisp_grid_info)) || - get_user(rgby_data, &up->rgby_data) || - put_user(compat_ptr(rgby_data), &kp->rgby_data) || - get_user(data, &up->data) || - put_user(compat_ptr(data), &kp->data) || - assign_in_user(&kp->exp_id, &up->exp_id) || - assign_in_user(&kp->isp_config_id, &up->isp_config_id)) - return -EFAULT; - - return 0; -} - -static int put_atomisp_3a_statistics32(struct atomisp_3a_statistics __user *kp, - struct atomisp_3a_statistics32 __user *up) -{ - void __user *data; - void __user *rgby_data; - - if (!access_ok(up, sizeof(struct atomisp_3a_statistics32)) || - copy_in_user(up, kp, sizeof(struct atomisp_grid_info)) || - get_user(rgby_data, &kp->rgby_data) || - put_user(ptr_to_compat(rgby_data), &up->rgby_data) || - get_user(data, &kp->data) || - put_user(ptr_to_compat(data), &up->data) || - assign_in_user(&up->exp_id, &kp->exp_id) || - assign_in_user(&up->isp_config_id, &kp->isp_config_id)) - return -EFAULT; - - return 0; -} - -static int get_atomisp_metadata_stat32(struct atomisp_metadata __user *kp, - struct atomisp_metadata32 __user *up) -{ - compat_uptr_t data; - compat_uptr_t effective_width; - - if (!access_ok(up, sizeof(struct atomisp_metadata32)) || - get_user(data, &up->data) || - put_user(compat_ptr(data), &kp->data) || - assign_in_user(&kp->width, &up->width) || - assign_in_user(&kp->height, &up->height) || - assign_in_user(&kp->stride, &up->stride) || - assign_in_user(&kp->exp_id, &up->exp_id) || - get_user(effective_width, &up->effective_width) || - put_user_force(compat_ptr(effective_width), &kp->effective_width)) - return -EFAULT; - - return 0; -} - -static int put_atomisp_metadata_stat32(struct atomisp_metadata __user *kp, - struct atomisp_metadata32 __user *up) -{ - void __user *data; - void *effective_width; - - if (!access_ok(up, sizeof(struct atomisp_metadata32)) || - get_user(data, &kp->data) || - put_user(ptr_to_compat(data), &up->data) || - assign_in_user(&up->width, &kp->width) || - assign_in_user(&up->height, &kp->height) || - assign_in_user(&up->stride, &kp->stride) || - assign_in_user(&up->exp_id, &kp->exp_id) || - get_user(effective_width, &kp->effective_width) || - put_user(ptr_to_compat((void __user *)effective_width), - &up->effective_width)) - return -EFAULT; - - return 0; -} - -static int -put_atomisp_metadata_by_type_stat32(struct atomisp_metadata_with_type __user *kp, - struct atomisp_metadata_with_type32 __user *up) -{ - void __user *data; - u32 *effective_width; - - if (!access_ok(up, sizeof(struct atomisp_metadata_with_type32)) || - get_user(data, &kp->data) || - put_user(ptr_to_compat(data), &up->data) || - assign_in_user(&up->width, &kp->width) || - assign_in_user(&up->height, &kp->height) || - assign_in_user(&up->stride, &kp->stride) || - assign_in_user(&up->exp_id, &kp->exp_id) || - get_user(effective_width, &kp->effective_width) || - put_user(ptr_to_compat((void __user *)effective_width), - &up->effective_width) || - assign_in_user(&up->type, &kp->type)) - return -EFAULT; - - return 0; -} - -static int -get_atomisp_metadata_by_type_stat32(struct atomisp_metadata_with_type __user *kp, - struct atomisp_metadata_with_type32 __user *up) -{ - compat_uptr_t data; - compat_uptr_t effective_width; - - if (!access_ok(up, sizeof(struct atomisp_metadata_with_type32)) || - get_user(data, &up->data) || - put_user(compat_ptr(data), &kp->data) || - assign_in_user(&kp->width, &up->width) || - assign_in_user(&kp->height, &up->height) || - assign_in_user(&kp->stride, &up->stride) || - assign_in_user(&kp->exp_id, &up->exp_id) || - get_user(effective_width, &up->effective_width) || - put_user_force(compat_ptr(effective_width), &kp->effective_width) || - assign_in_user(&kp->type, &up->type)) - return -EFAULT; - - return 0; -} - -static int -get_atomisp_morph_table32(struct atomisp_morph_table __user *kp, - struct atomisp_morph_table32 __user *up) -{ - unsigned int n = ATOMISP_MORPH_TABLE_NUM_PLANES; - - if (!access_ok(up, sizeof(struct atomisp_morph_table32)) || - assign_in_user(&kp->enabled, &up->enabled) || - assign_in_user(&kp->width, &up->width) || - assign_in_user(&kp->height, &up->height)) - return -EFAULT; - - while (n-- > 0) { - compat_uptr_t coord_kp; - - if (get_user(coord_kp, &up->coordinates_x[n]) || - put_user(compat_ptr(coord_kp), &kp->coordinates_x[n]) || - get_user(coord_kp, &up->coordinates_y[n]) || - put_user(compat_ptr(coord_kp), &kp->coordinates_y[n])) - return -EFAULT; - } - return 0; -} - -static int put_atomisp_morph_table32(struct atomisp_morph_table __user *kp, - struct atomisp_morph_table32 __user *up) -{ - unsigned int n = ATOMISP_MORPH_TABLE_NUM_PLANES; - - if (!access_ok(up, sizeof(struct atomisp_morph_table32)) || - assign_in_user(&up->enabled, &kp->enabled) || - assign_in_user(&up->width, &kp->width) || - assign_in_user(&up->height, &kp->height)) - return -EFAULT; - - while (n-- > 0) { - void __user *coord_kp; - - if (get_user(coord_kp, &kp->coordinates_x[n]) || - put_user(ptr_to_compat(coord_kp), &up->coordinates_x[n]) || - get_user(coord_kp, &kp->coordinates_y[n]) || - put_user(ptr_to_compat(coord_kp), &up->coordinates_y[n])) - return -EFAULT; - } - return 0; -} - -static int get_atomisp_overlay32(struct atomisp_overlay __user *kp, - struct atomisp_overlay32 __user *up) -{ - compat_uptr_t frame; - - if (!access_ok(up, sizeof(struct atomisp_overlay32)) || - get_user(frame, &up->frame) || - put_user_force(compat_ptr(frame), &kp->frame) || - assign_in_user(&kp->bg_y, &up->bg_y) || - assign_in_user(&kp->bg_u, &up->bg_u) || - assign_in_user(&kp->bg_v, &up->bg_v) || - assign_in_user(&kp->blend_input_perc_y, - &up->blend_input_perc_y) || - assign_in_user(&kp->blend_input_perc_u, - &up->blend_input_perc_u) || - assign_in_user(&kp->blend_input_perc_v, - &up->blend_input_perc_v) || - assign_in_user(&kp->blend_overlay_perc_y, - &up->blend_overlay_perc_y) || - assign_in_user(&kp->blend_overlay_perc_u, - &up->blend_overlay_perc_u) || - assign_in_user(&kp->blend_overlay_perc_v, - &up->blend_overlay_perc_v) || - assign_in_user(&kp->overlay_start_x, &up->overlay_start_x) || - assign_in_user(&kp->overlay_start_y, &up->overlay_start_y)) - return -EFAULT; - - return 0; -} - -static int put_atomisp_overlay32(struct atomisp_overlay __user *kp, - struct atomisp_overlay32 __user *up) -{ - void *frame; - - if (!access_ok(up, sizeof(struct atomisp_overlay32)) || - get_user(frame, &kp->frame) || - put_user(ptr_to_compat((void __user *)frame), &up->frame) || - assign_in_user(&up->bg_y, &kp->bg_y) || - assign_in_user(&up->bg_u, &kp->bg_u) || - assign_in_user(&up->bg_v, &kp->bg_v) || - assign_in_user(&up->blend_input_perc_y, - &kp->blend_input_perc_y) || - assign_in_user(&up->blend_input_perc_u, - &kp->blend_input_perc_u) || - assign_in_user(&up->blend_input_perc_v, - &kp->blend_input_perc_v) || - assign_in_user(&up->blend_overlay_perc_y, - &kp->blend_overlay_perc_y) || - assign_in_user(&up->blend_overlay_perc_u, - &kp->blend_overlay_perc_u) || - assign_in_user(&up->blend_overlay_perc_v, - &kp->blend_overlay_perc_v) || - assign_in_user(&up->overlay_start_x, &kp->overlay_start_x) || - assign_in_user(&up->overlay_start_y, &kp->overlay_start_y)) - return -EFAULT; - - return 0; -} - -static int -get_atomisp_calibration_group32(struct atomisp_calibration_group __user *kp, - struct atomisp_calibration_group32 __user *up) -{ - compat_uptr_t calb_grp_values; - - if (!access_ok(up, sizeof(struct atomisp_calibration_group32)) || - assign_in_user(&kp->size, &up->size) || - assign_in_user(&kp->type, &up->type) || - get_user(calb_grp_values, &up->calb_grp_values) || - put_user_force(compat_ptr(calb_grp_values), &kp->calb_grp_values)) - return -EFAULT; - - return 0; -} - -static int -put_atomisp_calibration_group32(struct atomisp_calibration_group __user *kp, - struct atomisp_calibration_group32 __user *up) -{ - void *calb_grp_values; - - if (!access_ok(up, sizeof(struct atomisp_calibration_group32)) || - assign_in_user(&up->size, &kp->size) || - assign_in_user(&up->type, &kp->type) || - get_user(calb_grp_values, &kp->calb_grp_values) || - put_user(ptr_to_compat((void __user *)calb_grp_values), - &up->calb_grp_values)) - return -EFAULT; - - return 0; -} - -static int get_atomisp_acc_fw_load32(struct atomisp_acc_fw_load __user *kp, - struct atomisp_acc_fw_load32 __user *up) -{ - compat_uptr_t data; - - if (!access_ok(up, sizeof(struct atomisp_acc_fw_load32)) || - assign_in_user(&kp->size, &up->size) || - assign_in_user(&kp->fw_handle, &up->fw_handle) || - get_user_cast(data, &up->data) || - put_user(compat_ptr(data), &kp->data)) - return -EFAULT; - - return 0; -} - -static int put_atomisp_acc_fw_load32(struct atomisp_acc_fw_load __user *kp, - struct atomisp_acc_fw_load32 __user *up) -{ - void __user *data; - - if (!access_ok(up, sizeof(struct atomisp_acc_fw_load32)) || - assign_in_user(&up->size, &kp->size) || - assign_in_user(&up->fw_handle, &kp->fw_handle) || - get_user(data, &kp->data) || - put_user(ptr_to_compat(data), &up->data)) - return -EFAULT; - - return 0; -} - -static int get_atomisp_acc_fw_arg32(struct atomisp_acc_fw_arg __user *kp, - struct atomisp_acc_fw_arg32 __user *up) -{ - compat_uptr_t value; - - if (!access_ok(up, sizeof(struct atomisp_acc_fw_arg32)) || - assign_in_user(&kp->fw_handle, &up->fw_handle) || - assign_in_user(&kp->index, &up->index) || - get_user(value, &up->value) || - put_user(compat_ptr(value), &kp->value) || - assign_in_user(&kp->size, &up->size)) - return -EFAULT; - - return 0; -} - -static int put_atomisp_acc_fw_arg32(struct atomisp_acc_fw_arg __user *kp, - struct atomisp_acc_fw_arg32 __user *up) -{ - void __user *value; - - if (!access_ok(up, sizeof(struct atomisp_acc_fw_arg32)) || - assign_in_user(&up->fw_handle, &kp->fw_handle) || - assign_in_user(&up->index, &kp->index) || - get_user(value, &kp->value) || - put_user(ptr_to_compat(value), &up->value) || - assign_in_user(&up->size, &kp->size)) - return -EFAULT; - - return 0; -} - -static int get_v4l2_private_int_data32(struct v4l2_private_int_data __user *kp, - struct v4l2_private_int_data32 __user *up) -{ - compat_uptr_t data; - - if (!access_ok(up, sizeof(struct v4l2_private_int_data32)) || - assign_in_user(&kp->size, &up->size) || - get_user(data, &up->data) || - put_user(compat_ptr(data), &kp->data) || - assign_in_user(&kp->reserved[0], &up->reserved[0]) || - assign_in_user(&kp->reserved[1], &up->reserved[1])) - return -EFAULT; - - return 0; -} - -static int put_v4l2_private_int_data32(struct v4l2_private_int_data __user *kp, - struct v4l2_private_int_data32 __user *up) -{ - void __user *data; - - if (!access_ok(up, sizeof(struct v4l2_private_int_data32)) || - assign_in_user(&up->size, &kp->size) || - get_user(data, &kp->data) || - put_user(ptr_to_compat(data), &up->data) || - assign_in_user(&up->reserved[0], &kp->reserved[0]) || - assign_in_user(&up->reserved[1], &kp->reserved[1])) - return -EFAULT; - - return 0; -} - -static int get_atomisp_shading_table32(struct atomisp_shading_table __user *kp, - struct atomisp_shading_table32 __user *up) -{ - unsigned int n = ATOMISP_NUM_SC_COLORS; - - if (!access_ok(up, sizeof(struct atomisp_shading_table32)) || - assign_in_user(&kp->enable, &up->enable) || - assign_in_user(&kp->sensor_width, &up->sensor_width) || - assign_in_user(&kp->sensor_height, &up->sensor_height) || - assign_in_user(&kp->width, &up->width) || - assign_in_user(&kp->height, &up->height) || - assign_in_user(&kp->fraction_bits, &up->fraction_bits)) - return -EFAULT; - - while (n-- > 0) { - compat_uptr_t tmp; - - if (get_user(tmp, &up->data[n]) || - put_user_force(compat_ptr(tmp), &kp->data[n])) - return -EFAULT; - } - return 0; -} - -static int get_atomisp_acc_map32(struct atomisp_acc_map __user *kp, - struct atomisp_acc_map32 __user *up) -{ - compat_uptr_t user_ptr; - - if (!access_ok(up, sizeof(struct atomisp_acc_map32)) || - assign_in_user(&kp->flags, &up->flags) || - assign_in_user(&kp->length, &up->length) || - get_user(user_ptr, &up->user_ptr) || - put_user(compat_ptr(user_ptr), &kp->user_ptr) || - assign_in_user(&kp->css_ptr, &up->css_ptr) || - assign_in_user(&kp->reserved[0], &up->reserved[0]) || - assign_in_user(&kp->reserved[1], &up->reserved[1]) || - assign_in_user(&kp->reserved[2], &up->reserved[2]) || - assign_in_user(&kp->reserved[3], &up->reserved[3])) - return -EFAULT; - - return 0; -} - -static int put_atomisp_acc_map32(struct atomisp_acc_map __user *kp, - struct atomisp_acc_map32 __user *up) -{ - void __user *user_ptr; - - if (!access_ok(up, sizeof(struct atomisp_acc_map32)) || - assign_in_user(&up->flags, &kp->flags) || - assign_in_user(&up->length, &kp->length) || - get_user(user_ptr, &kp->user_ptr) || - put_user(ptr_to_compat(user_ptr), &up->user_ptr) || - assign_in_user(&up->css_ptr, &kp->css_ptr) || - assign_in_user(&up->reserved[0], &kp->reserved[0]) || - assign_in_user(&up->reserved[1], &kp->reserved[1]) || - assign_in_user(&up->reserved[2], &kp->reserved[2]) || - assign_in_user(&up->reserved[3], &kp->reserved[3])) - return -EFAULT; - - return 0; -} - -static int -get_atomisp_acc_s_mapped_arg32(struct atomisp_acc_s_mapped_arg __user *kp, - struct atomisp_acc_s_mapped_arg32 __user *up) -{ - if (!access_ok(up, sizeof(struct atomisp_acc_s_mapped_arg32)) || - assign_in_user(&kp->fw_handle, &up->fw_handle) || - assign_in_user(&kp->memory, &up->memory) || - assign_in_user(&kp->length, &up->length) || - assign_in_user(&kp->css_ptr, &up->css_ptr)) - return -EFAULT; - - return 0; -} - -static int -put_atomisp_acc_s_mapped_arg32(struct atomisp_acc_s_mapped_arg __user *kp, - struct atomisp_acc_s_mapped_arg32 __user *up) -{ - if (!access_ok(up, sizeof(struct atomisp_acc_s_mapped_arg32)) || - assign_in_user(&up->fw_handle, &kp->fw_handle) || - assign_in_user(&up->memory, &kp->memory) || - assign_in_user(&up->length, &kp->length) || - assign_in_user(&up->css_ptr, &kp->css_ptr)) - return -EFAULT; - - return 0; -} - -static int get_atomisp_parameters32(struct atomisp_parameters __user *kp, - struct atomisp_parameters32 __user *up) -{ - int n = offsetof(struct atomisp_parameters32, output_frame) / - sizeof(compat_uptr_t); - compat_uptr_t stp, mtp, dcp, dscp; - struct { - struct atomisp_shading_table shading_table; - struct atomisp_morph_table morph_table; - struct atomisp_dis_coefficients dvs2_coefs; - struct atomisp_dvs_6axis_config dvs_6axis_config; - } __user *karg = (void __user *)(kp + 1); - - if (!access_ok(up, sizeof(struct atomisp_parameters32))) - return -EFAULT; - - while (n >= 0) { - compat_uptr_t __user *src = (compat_uptr_t __user *)up + n; - void * __user *dst = (void * __user *)kp + n; - compat_uptr_t tmp; - - if (get_user_cast(tmp, src) || put_user_force(compat_ptr(tmp), dst)) - return -EFAULT; - n--; - } - - if (assign_in_user(&kp->isp_config_id, &up->isp_config_id) || - assign_in_user(&kp->per_frame_setting, &up->per_frame_setting) || - get_user(stp, &up->shading_table) || - get_user(mtp, &up->morph_table) || - get_user(dcp, &up->dvs2_coefs) || - get_user(dscp, &up->dvs_6axis_config)) - return -EFAULT; - - /* handle shading table */ - if (stp && (get_atomisp_shading_table32(&karg->shading_table, - compat_ptr(stp)) || - put_user_force(&karg->shading_table, &kp->shading_table))) - return -EFAULT; - - /* handle morph table */ - if (mtp && (get_atomisp_morph_table32(&karg->morph_table, - compat_ptr(mtp)) || - put_user_force(&karg->morph_table, &kp->morph_table))) - return -EFAULT; - - /* handle dvs2 coefficients */ - if (dcp && (get_atomisp_dis_coefficients32(&karg->dvs2_coefs, - compat_ptr(dcp)) || - put_user_force(&karg->dvs2_coefs, &kp->dvs2_coefs))) - return -EFAULT; - - /* handle dvs 6axis configuration */ - if (dscp && - (get_atomisp_dvs_6axis_config32(&karg->dvs_6axis_config, - compat_ptr(dscp)) || - put_user_force(&karg->dvs_6axis_config, &kp->dvs_6axis_config))) - return -EFAULT; - - return 0; -} - -static int -get_atomisp_acc_fw_load_to_pipe32(struct atomisp_acc_fw_load_to_pipe __user *kp, - struct atomisp_acc_fw_load_to_pipe32 __user *up) -{ - compat_uptr_t data; - - if (!access_ok(up, sizeof(struct atomisp_acc_fw_load_to_pipe32)) || - assign_in_user(&kp->flags, &up->flags) || - assign_in_user(&kp->fw_handle, &up->fw_handle) || - assign_in_user(&kp->size, &up->size) || - assign_in_user(&kp->type, &up->type) || - assign_in_user(&kp->reserved[0], &up->reserved[0]) || - assign_in_user(&kp->reserved[1], &up->reserved[1]) || - assign_in_user(&kp->reserved[2], &up->reserved[2]) || - get_user(data, &up->data) || - put_user(compat_ptr(data), &kp->data)) - return -EFAULT; - - return 0; -} - -static int -put_atomisp_acc_fw_load_to_pipe32(struct atomisp_acc_fw_load_to_pipe __user *kp, - struct atomisp_acc_fw_load_to_pipe32 __user *up) -{ - void __user *data; - - if (!access_ok(up, sizeof(struct atomisp_acc_fw_load_to_pipe32)) || - assign_in_user(&up->flags, &kp->flags) || - assign_in_user(&up->fw_handle, &kp->fw_handle) || - assign_in_user(&up->size, &kp->size) || - assign_in_user(&up->type, &kp->type) || - assign_in_user(&up->reserved[0], &kp->reserved[0]) || - assign_in_user(&up->reserved[1], &kp->reserved[1]) || - assign_in_user(&up->reserved[2], &kp->reserved[2]) || - get_user(data, &kp->data) || - put_user(ptr_to_compat(data), &up->data)) - return -EFAULT; - - return 0; -} - -static int -get_atomisp_sensor_ae_bracketing_lut(struct atomisp_sensor_ae_bracketing_lut __user *kp, - struct atomisp_sensor_ae_bracketing_lut32 __user *up) -{ - compat_uptr_t lut; - - if (!access_ok(up, sizeof(struct atomisp_sensor_ae_bracketing_lut32)) || - assign_in_user(&kp->lut_size, &up->lut_size) || - get_user(lut, &up->lut) || - put_user_force(compat_ptr(lut), &kp->lut)) - return -EFAULT; - - return 0; -} - -static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - long ret = -ENOIOCTLCMD; - - if (file->f_op->unlocked_ioctl) - ret = file->f_op->unlocked_ioctl(file, cmd, arg); - - return ret; -} - -static long atomisp_do_compat_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - union { - struct atomisp_histogram his; - struct atomisp_dis_statistics dis_s; - struct atomisp_dis_coefficients dis_c; - struct atomisp_dvs_6axis_config dvs_c; - struct atomisp_3a_statistics s3a_s; - struct atomisp_morph_table mor_t; - struct v4l2_framebuffer v4l2_buf; - struct atomisp_overlay overlay; - struct atomisp_calibration_group cal_grp; - struct atomisp_acc_fw_load acc_fw_load; - struct atomisp_acc_fw_arg acc_fw_arg; - struct v4l2_private_int_data v4l2_pri_data; - struct atomisp_shading_table shd_tbl; - struct atomisp_acc_map acc_map; - struct atomisp_acc_s_mapped_arg acc_map_arg; - struct atomisp_parameters param; - struct atomisp_acc_fw_load_to_pipe acc_fw_to_pipe; - struct atomisp_metadata md; - struct atomisp_metadata_with_type md_with_type; - struct atomisp_sensor_ae_bracketing_lut lut; - } __user *karg; - void __user *up = compat_ptr(arg); - long err = -ENOIOCTLCMD; - - karg = compat_alloc_user_space( - sizeof(*karg) + (cmd == ATOMISP_IOC_S_PARAMETERS32 ? - sizeof(struct atomisp_shading_table) + - sizeof(struct atomisp_morph_table) + - sizeof(struct atomisp_dis_coefficients) + - sizeof(struct atomisp_dvs_6axis_config) : 0)); - if (!karg) - return -ENOMEM; - - /* First, convert the command. */ - switch (cmd) { - case ATOMISP_IOC_G_HISTOGRAM32: - cmd = ATOMISP_IOC_G_HISTOGRAM; - break; - case ATOMISP_IOC_S_HISTOGRAM32: - cmd = ATOMISP_IOC_S_HISTOGRAM; - break; - case ATOMISP_IOC_G_DIS_STAT32: - cmd = ATOMISP_IOC_G_DIS_STAT; - break; - case ATOMISP_IOC_S_DIS_COEFS32: - cmd = ATOMISP_IOC_S_DIS_COEFS; - break; - case ATOMISP_IOC_S_DIS_VECTOR32: - cmd = ATOMISP_IOC_S_DIS_VECTOR; - break; - case ATOMISP_IOC_G_3A_STAT32: - cmd = ATOMISP_IOC_G_3A_STAT; - break; - case ATOMISP_IOC_G_ISP_GDC_TAB32: - cmd = ATOMISP_IOC_G_ISP_GDC_TAB; - break; - case ATOMISP_IOC_S_ISP_GDC_TAB32: - cmd = ATOMISP_IOC_S_ISP_GDC_TAB; - break; - case ATOMISP_IOC_S_ISP_FPN_TABLE32: - cmd = ATOMISP_IOC_S_ISP_FPN_TABLE; - break; - case ATOMISP_IOC_G_ISP_OVERLAY32: - cmd = ATOMISP_IOC_G_ISP_OVERLAY; - break; - case ATOMISP_IOC_S_ISP_OVERLAY32: - cmd = ATOMISP_IOC_S_ISP_OVERLAY; - break; - case ATOMISP_IOC_G_SENSOR_CALIBRATION_GROUP32: - cmd = ATOMISP_IOC_G_SENSOR_CALIBRATION_GROUP; - break; - case ATOMISP_IOC_ACC_LOAD32: - cmd = ATOMISP_IOC_ACC_LOAD; - break; - case ATOMISP_IOC_ACC_S_ARG32: - cmd = ATOMISP_IOC_ACC_S_ARG; - break; - case ATOMISP_IOC_G_SENSOR_PRIV_INT_DATA32: - cmd = ATOMISP_IOC_G_SENSOR_PRIV_INT_DATA; - break; - case ATOMISP_IOC_S_ISP_SHD_TAB32: - cmd = ATOMISP_IOC_S_ISP_SHD_TAB; - break; - case ATOMISP_IOC_ACC_DESTAB32: - cmd = ATOMISP_IOC_ACC_DESTAB; - break; - case ATOMISP_IOC_G_MOTOR_PRIV_INT_DATA32: - cmd = ATOMISP_IOC_G_MOTOR_PRIV_INT_DATA; - break; - case ATOMISP_IOC_ACC_MAP32: - cmd = ATOMISP_IOC_ACC_MAP; - break; - case ATOMISP_IOC_ACC_UNMAP32: - cmd = ATOMISP_IOC_ACC_UNMAP; - break; - case ATOMISP_IOC_ACC_S_MAPPED_ARG32: - cmd = ATOMISP_IOC_ACC_S_MAPPED_ARG; - break; - case ATOMISP_IOC_S_PARAMETERS32: - cmd = ATOMISP_IOC_S_PARAMETERS; - break; - case ATOMISP_IOC_ACC_LOAD_TO_PIPE32: - cmd = ATOMISP_IOC_ACC_LOAD_TO_PIPE; - break; - case ATOMISP_IOC_G_METADATA32: - cmd = ATOMISP_IOC_G_METADATA; - break; - case ATOMISP_IOC_G_METADATA_BY_TYPE32: - cmd = ATOMISP_IOC_G_METADATA_BY_TYPE; - break; - case ATOMISP_IOC_S_SENSOR_AE_BRACKETING_LUT32: - cmd = ATOMISP_IOC_S_SENSOR_AE_BRACKETING_LUT; - break; - } - - switch (cmd) { - case ATOMISP_IOC_G_HISTOGRAM: - case ATOMISP_IOC_S_HISTOGRAM: - err = get_atomisp_histogram32(&karg->his, up); - break; - case ATOMISP_IOC_G_DIS_STAT: - err = get_atomisp_dis_statistics32(&karg->dis_s, up); - break; - case ATOMISP_IOC_S_DIS_COEFS: - err = get_atomisp_dis_coefficients32(&karg->dis_c, up); - break; - case ATOMISP_IOC_S_DIS_VECTOR: - err = get_atomisp_dvs_6axis_config32(&karg->dvs_c, up); - break; - case ATOMISP_IOC_G_3A_STAT: - err = get_atomisp_3a_statistics32(&karg->s3a_s, up); - break; - case ATOMISP_IOC_G_ISP_GDC_TAB: - case ATOMISP_IOC_S_ISP_GDC_TAB: - err = get_atomisp_morph_table32(&karg->mor_t, up); - break; - case ATOMISP_IOC_S_ISP_FPN_TABLE: - err = get_v4l2_framebuffer32(&karg->v4l2_buf, up); - break; - case ATOMISP_IOC_G_ISP_OVERLAY: - case ATOMISP_IOC_S_ISP_OVERLAY: - err = get_atomisp_overlay32(&karg->overlay, up); - break; - case ATOMISP_IOC_G_SENSOR_CALIBRATION_GROUP: - err = get_atomisp_calibration_group32(&karg->cal_grp, up); - break; - case ATOMISP_IOC_ACC_LOAD: - err = get_atomisp_acc_fw_load32(&karg->acc_fw_load, up); - break; - case ATOMISP_IOC_ACC_S_ARG: - case ATOMISP_IOC_ACC_DESTAB: - err = get_atomisp_acc_fw_arg32(&karg->acc_fw_arg, up); - break; - case ATOMISP_IOC_G_SENSOR_PRIV_INT_DATA: - case ATOMISP_IOC_G_MOTOR_PRIV_INT_DATA: - err = get_v4l2_private_int_data32(&karg->v4l2_pri_data, up); - break; - case ATOMISP_IOC_S_ISP_SHD_TAB: - err = get_atomisp_shading_table32(&karg->shd_tbl, up); - break; - case ATOMISP_IOC_ACC_MAP: - case ATOMISP_IOC_ACC_UNMAP: - err = get_atomisp_acc_map32(&karg->acc_map, up); - break; - case ATOMISP_IOC_ACC_S_MAPPED_ARG: - err = get_atomisp_acc_s_mapped_arg32(&karg->acc_map_arg, up); - break; - case ATOMISP_IOC_S_PARAMETERS: - err = get_atomisp_parameters32(&karg->param, up); - break; - case ATOMISP_IOC_ACC_LOAD_TO_PIPE: - err = get_atomisp_acc_fw_load_to_pipe32(&karg->acc_fw_to_pipe, - up); - break; - case ATOMISP_IOC_G_METADATA: - err = get_atomisp_metadata_stat32(&karg->md, up); - break; - case ATOMISP_IOC_G_METADATA_BY_TYPE: - err = get_atomisp_metadata_by_type_stat32(&karg->md_with_type, - up); - break; - case ATOMISP_IOC_S_SENSOR_AE_BRACKETING_LUT: - err = get_atomisp_sensor_ae_bracketing_lut(&karg->lut, up); - break; - } - if (err) - return err; - - err = native_ioctl(file, cmd, (unsigned long)karg); - if (err) - return err; - - switch (cmd) { - case ATOMISP_IOC_G_HISTOGRAM: - err = put_atomisp_histogram32(&karg->his, up); - break; - case ATOMISP_IOC_G_DIS_STAT: - err = put_atomisp_dis_statistics32(&karg->dis_s, up); - break; - case ATOMISP_IOC_G_3A_STAT: - err = put_atomisp_3a_statistics32(&karg->s3a_s, up); - break; - case ATOMISP_IOC_G_ISP_GDC_TAB: - err = put_atomisp_morph_table32(&karg->mor_t, up); - break; - case ATOMISP_IOC_G_ISP_OVERLAY: - err = put_atomisp_overlay32(&karg->overlay, up); - break; - case ATOMISP_IOC_G_SENSOR_CALIBRATION_GROUP: - err = put_atomisp_calibration_group32(&karg->cal_grp, up); - break; - case ATOMISP_IOC_ACC_LOAD: - err = put_atomisp_acc_fw_load32(&karg->acc_fw_load, up); - break; - case ATOMISP_IOC_ACC_S_ARG: - case ATOMISP_IOC_ACC_DESTAB: - err = put_atomisp_acc_fw_arg32(&karg->acc_fw_arg, up); - break; - case ATOMISP_IOC_G_SENSOR_PRIV_INT_DATA: - case ATOMISP_IOC_G_MOTOR_PRIV_INT_DATA: - err = put_v4l2_private_int_data32(&karg->v4l2_pri_data, up); - break; - case ATOMISP_IOC_ACC_MAP: - case ATOMISP_IOC_ACC_UNMAP: - err = put_atomisp_acc_map32(&karg->acc_map, up); - break; - case ATOMISP_IOC_ACC_S_MAPPED_ARG: - err = put_atomisp_acc_s_mapped_arg32(&karg->acc_map_arg, up); - break; - case ATOMISP_IOC_ACC_LOAD_TO_PIPE: - err = put_atomisp_acc_fw_load_to_pipe32(&karg->acc_fw_to_pipe, - up); - break; - case ATOMISP_IOC_G_METADATA: - err = put_atomisp_metadata_stat32(&karg->md, up); - break; - case ATOMISP_IOC_G_METADATA_BY_TYPE: - err = put_atomisp_metadata_by_type_stat32(&karg->md_with_type, - up); - break; - } - - return err; -} - -long atomisp_compat_ioctl32(struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct video_device *vdev = video_devdata(file); - struct atomisp_device *isp = video_get_drvdata(vdev); - long ret = -ENOIOCTLCMD; - - if (!file->f_op->unlocked_ioctl) - return ret; - - switch (cmd) { - case ATOMISP_IOC_G_XNR: - case ATOMISP_IOC_S_XNR: - case ATOMISP_IOC_G_NR: - case ATOMISP_IOC_S_NR: - case ATOMISP_IOC_G_TNR: - case ATOMISP_IOC_S_TNR: - case ATOMISP_IOC_G_BLACK_LEVEL_COMP: - case ATOMISP_IOC_S_BLACK_LEVEL_COMP: - case ATOMISP_IOC_G_EE: - case ATOMISP_IOC_S_EE: - case ATOMISP_IOC_S_DIS_VECTOR: - case ATOMISP_IOC_G_ISP_PARM: - case ATOMISP_IOC_S_ISP_PARM: - case ATOMISP_IOC_G_ISP_GAMMA: - case ATOMISP_IOC_S_ISP_GAMMA: - case ATOMISP_IOC_ISP_MAKERNOTE: - case ATOMISP_IOC_G_ISP_MACC: - case ATOMISP_IOC_S_ISP_MACC: - case ATOMISP_IOC_G_ISP_BAD_PIXEL_DETECTION: - case ATOMISP_IOC_S_ISP_BAD_PIXEL_DETECTION: - case ATOMISP_IOC_G_ISP_FALSE_COLOR_CORRECTION: - case ATOMISP_IOC_S_ISP_FALSE_COLOR_CORRECTION: - case ATOMISP_IOC_G_ISP_CTC: - case ATOMISP_IOC_S_ISP_CTC: - case ATOMISP_IOC_G_ISP_WHITE_BALANCE: - case ATOMISP_IOC_S_ISP_WHITE_BALANCE: - case ATOMISP_IOC_CAMERA_BRIDGE: - case ATOMISP_IOC_G_SENSOR_MODE_DATA: - case ATOMISP_IOC_S_EXPOSURE: - case ATOMISP_IOC_G_3A_CONFIG: - case ATOMISP_IOC_S_3A_CONFIG: - case ATOMISP_IOC_ACC_UNLOAD: - case ATOMISP_IOC_ACC_START: - case ATOMISP_IOC_ACC_WAIT: - case ATOMISP_IOC_ACC_ABORT: - case ATOMISP_IOC_G_ISP_GAMMA_CORRECTION: - case ATOMISP_IOC_S_ISP_GAMMA_CORRECTION: - case ATOMISP_IOC_S_CONT_CAPTURE_CONFIG: - case ATOMISP_IOC_G_DVS2_BQ_RESOLUTIONS: - case ATOMISP_IOC_EXT_ISP_CTRL: - case ATOMISP_IOC_EXP_ID_UNLOCK: - case ATOMISP_IOC_EXP_ID_CAPTURE: - case ATOMISP_IOC_S_ENABLE_DZ_CAPT_PIPE: - case ATOMISP_IOC_G_FORMATS_CONFIG: - case ATOMISP_IOC_S_FORMATS_CONFIG: - case ATOMISP_IOC_S_EXPOSURE_WINDOW: - case ATOMISP_IOC_S_ACC_STATE: - case ATOMISP_IOC_G_ACC_STATE: - case ATOMISP_IOC_INJECT_A_FAKE_EVENT: - case ATOMISP_IOC_G_SENSOR_AE_BRACKETING_INFO: - case ATOMISP_IOC_S_SENSOR_AE_BRACKETING_MODE: - case ATOMISP_IOC_G_SENSOR_AE_BRACKETING_MODE: - case ATOMISP_IOC_G_INVALID_FRAME_NUM: - case ATOMISP_IOC_S_ARRAY_RESOLUTION: - case ATOMISP_IOC_S_SENSOR_RUNMODE: - case ATOMISP_IOC_G_UPDATE_EXPOSURE: - ret = native_ioctl(file, cmd, arg); - break; - - case ATOMISP_IOC_G_HISTOGRAM32: - case ATOMISP_IOC_S_HISTOGRAM32: - case ATOMISP_IOC_G_DIS_STAT32: - case ATOMISP_IOC_S_DIS_COEFS32: - case ATOMISP_IOC_S_DIS_VECTOR32: - case ATOMISP_IOC_G_3A_STAT32: - case ATOMISP_IOC_G_ISP_GDC_TAB32: - case ATOMISP_IOC_S_ISP_GDC_TAB32: - case ATOMISP_IOC_S_ISP_FPN_TABLE32: - case ATOMISP_IOC_G_ISP_OVERLAY32: - case ATOMISP_IOC_S_ISP_OVERLAY32: - case ATOMISP_IOC_G_SENSOR_CALIBRATION_GROUP32: - case ATOMISP_IOC_ACC_LOAD32: - case ATOMISP_IOC_ACC_S_ARG32: - case ATOMISP_IOC_G_SENSOR_PRIV_INT_DATA32: - case ATOMISP_IOC_S_ISP_SHD_TAB32: - case ATOMISP_IOC_ACC_DESTAB32: - case ATOMISP_IOC_G_MOTOR_PRIV_INT_DATA32: - case ATOMISP_IOC_ACC_MAP32: - case ATOMISP_IOC_ACC_UNMAP32: - case ATOMISP_IOC_ACC_S_MAPPED_ARG32: - case ATOMISP_IOC_S_PARAMETERS32: - case ATOMISP_IOC_ACC_LOAD_TO_PIPE32: - case ATOMISP_IOC_G_METADATA32: - case ATOMISP_IOC_G_METADATA_BY_TYPE32: - case ATOMISP_IOC_S_SENSOR_AE_BRACKETING_LUT32: - ret = atomisp_do_compat_ioctl(file, cmd, arg); - break; - - default: - dev_warn(isp->dev, - "%s: unknown ioctl '%c', dir=%d, #%d (0x%08x)\n", - __func__, _IOC_TYPE(cmd), _IOC_DIR(cmd), _IOC_NR(cmd), - cmd); - break; - } - return ret; -} -#endif /* CONFIG_COMPAT */ diff --git a/drivers/staging/media/atomisp/pci/atomisp_fops.c b/drivers/staging/media/atomisp/pci/atomisp_fops.c index 022efd4151c0..f82bf082aa79 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_fops.c +++ b/drivers/staging/media/atomisp/pci/atomisp_fops.c @@ -1283,7 +1283,8 @@ const struct v4l2_file_operations atomisp_fops = { .unlocked_ioctl = video_ioctl2, #ifdef CONFIG_COMPAT /* - * There are problems with this code. Disable this for now. + * this was removed because of bugs, the interface + * needs to be made safe for compat tasks instead. .compat_ioctl32 = atomisp_compat_ioctl32, */ #endif @@ -1297,10 +1298,7 @@ const struct v4l2_file_operations atomisp_file_fops = { .mmap = atomisp_file_mmap, .unlocked_ioctl = video_ioctl2, #ifdef CONFIG_COMPAT - /* - * There are problems with this code. Disable this for now. - .compat_ioctl32 = atomisp_compat_ioctl32, - */ + /* .compat_ioctl32 = atomisp_compat_ioctl32, */ #endif .poll = atomisp_poll, }; From 0a7790be182d32b9b332a37cb4206e24fe94b728 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 14 Jun 2021 12:34:09 +0200 Subject: [PATCH 357/394] media: subdev: disallow ioctl for saa6588/davinci The saa6588_ioctl() function expects to get called from other kernel functions with a 'saa6588_command' pointer, but I found nothing stops it from getting called from user space instead, which seems rather dangerous. The same thing happens in the davinci vpbe driver with its VENC_GET_FLD command. As a quick fix, add a separate .command() callback pointer for this driver and change the two callers over to that. This change can easily get backported to stable kernels if necessary, but since there are only two drivers, we may want to eventually replace this with a set of more specialized callbacks in the long run. Fixes: c3fda7f835b0 ("V4L/DVB (10537): saa6588: convert to v4l2_subdev.") Cc: stable@vger.kernel.org Signed-off-by: Arnd Bergmann Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/saa6588.c | 4 ++-- drivers/media/pci/bt8xx/bttv-driver.c | 6 +++--- drivers/media/pci/saa7134/saa7134-video.c | 6 +++--- drivers/media/platform/davinci/vpbe_display.c | 2 +- drivers/media/platform/davinci/vpbe_venc.c | 6 ++---- include/media/v4l2-subdev.h | 4 ++++ 6 files changed, 15 insertions(+), 13 deletions(-) diff --git a/drivers/media/i2c/saa6588.c b/drivers/media/i2c/saa6588.c index ecb491d5f2ab..d1e0716bdfff 100644 --- a/drivers/media/i2c/saa6588.c +++ b/drivers/media/i2c/saa6588.c @@ -380,7 +380,7 @@ static void saa6588_configure(struct saa6588 *s) /* ---------------------------------------------------------------------- */ -static long saa6588_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +static long saa6588_command(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { struct saa6588 *s = to_saa6588(sd); struct saa6588_command *a = arg; @@ -433,7 +433,7 @@ static int saa6588_s_tuner(struct v4l2_subdev *sd, const struct v4l2_tuner *vt) /* ----------------------------------------------------------------------- */ static const struct v4l2_subdev_core_ops saa6588_core_ops = { - .ioctl = saa6588_ioctl, + .command = saa6588_command, }; static const struct v4l2_subdev_tuner_ops saa6588_tuner_ops = { diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index 1f62a9d8ea1d..0e9df8b35ac6 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c @@ -3179,7 +3179,7 @@ static int radio_release(struct file *file) btv->radio_user--; - bttv_call_all(btv, core, ioctl, SAA6588_CMD_CLOSE, &cmd); + bttv_call_all(btv, core, command, SAA6588_CMD_CLOSE, &cmd); if (btv->radio_user == 0) btv->has_radio_tuner = 0; @@ -3260,7 +3260,7 @@ static ssize_t radio_read(struct file *file, char __user *data, cmd.result = -ENODEV; radio_enable(btv); - bttv_call_all(btv, core, ioctl, SAA6588_CMD_READ, &cmd); + bttv_call_all(btv, core, command, SAA6588_CMD_READ, &cmd); return cmd.result; } @@ -3281,7 +3281,7 @@ static __poll_t radio_poll(struct file *file, poll_table *wait) cmd.instance = file; cmd.event_list = wait; cmd.poll_mask = res; - bttv_call_all(btv, core, ioctl, SAA6588_CMD_POLL, &cmd); + bttv_call_all(btv, core, command, SAA6588_CMD_POLL, &cmd); return cmd.poll_mask; } diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c index 0f9d6b9edb90..374c8e1087de 100644 --- a/drivers/media/pci/saa7134/saa7134-video.c +++ b/drivers/media/pci/saa7134/saa7134-video.c @@ -1181,7 +1181,7 @@ static int video_release(struct file *file) saa_call_all(dev, tuner, standby); if (vdev->vfl_type == VFL_TYPE_RADIO) - saa_call_all(dev, core, ioctl, SAA6588_CMD_CLOSE, &cmd); + saa_call_all(dev, core, command, SAA6588_CMD_CLOSE, &cmd); mutex_unlock(&dev->lock); return 0; @@ -1200,7 +1200,7 @@ static ssize_t radio_read(struct file *file, char __user *data, cmd.result = -ENODEV; mutex_lock(&dev->lock); - saa_call_all(dev, core, ioctl, SAA6588_CMD_READ, &cmd); + saa_call_all(dev, core, command, SAA6588_CMD_READ, &cmd); mutex_unlock(&dev->lock); return cmd.result; @@ -1216,7 +1216,7 @@ static __poll_t radio_poll(struct file *file, poll_table *wait) cmd.event_list = wait; cmd.poll_mask = 0; mutex_lock(&dev->lock); - saa_call_all(dev, core, ioctl, SAA6588_CMD_POLL, &cmd); + saa_call_all(dev, core, command, SAA6588_CMD_POLL, &cmd); mutex_unlock(&dev->lock); return rc | cmd.poll_mask; diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c index d19bad997f30..bf3c3e76b921 100644 --- a/drivers/media/platform/davinci/vpbe_display.c +++ b/drivers/media/platform/davinci/vpbe_display.c @@ -47,7 +47,7 @@ static int venc_is_second_field(struct vpbe_display *disp_dev) ret = v4l2_subdev_call(vpbe_dev->venc, core, - ioctl, + command, VENC_GET_FLD, &val); if (ret < 0) { diff --git a/drivers/media/platform/davinci/vpbe_venc.c b/drivers/media/platform/davinci/vpbe_venc.c index 8caa084e5704..bde241c26d79 100644 --- a/drivers/media/platform/davinci/vpbe_venc.c +++ b/drivers/media/platform/davinci/vpbe_venc.c @@ -521,9 +521,7 @@ static int venc_s_routing(struct v4l2_subdev *sd, u32 input, u32 output, return ret; } -static long venc_ioctl(struct v4l2_subdev *sd, - unsigned int cmd, - void *arg) +static long venc_command(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { u32 val; @@ -542,7 +540,7 @@ static long venc_ioctl(struct v4l2_subdev *sd, } static const struct v4l2_subdev_core_ops venc_core_ops = { - .ioctl = venc_ioctl, + .command = venc_command, }; static const struct v4l2_subdev_video_ops venc_video_ops = { diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 89115ba4c0f2..95f8bfd63273 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -162,6 +162,9 @@ struct v4l2_subdev_io_pin_config { * @s_gpio: set GPIO pins. Very simple right now, might need to be extended with * a direction argument if needed. * + * @command: called by in-kernel drivers in order to call functions internal + * to subdev drivers driver that have a separate callback. + * * @ioctl: called at the end of ioctl() syscall handler at the V4L2 core. * used to provide support for private ioctls used on the driver. * @@ -193,6 +196,7 @@ struct v4l2_subdev_core_ops { int (*load_fw)(struct v4l2_subdev *sd); int (*reset)(struct v4l2_subdev *sd, u32 val); int (*s_gpio)(struct v4l2_subdev *sd, u32 val); + long (*command)(struct v4l2_subdev *sd, unsigned int cmd, void *arg); long (*ioctl)(struct v4l2_subdev *sd, unsigned int cmd, void *arg); #ifdef CONFIG_COMPAT long (*compat_ioctl32)(struct v4l2_subdev *sd, unsigned int cmd, From ca816468bc3712c8ae120a94c19983851a4c6c4a Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Tue, 4 May 2021 14:26:48 +0200 Subject: [PATCH 358/394] media: coda: set debugfs blobs to read only Those blobs can only be read. So, don't confuse users with 'writable' flags. Signed-off-by: Wolfram Sang Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/coda/coda-common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index 2017de85713e..0e312b0842d7 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c @@ -1935,7 +1935,7 @@ int coda_alloc_aux_buf(struct coda_dev *dev, struct coda_aux_buf *buf, if (name && parent) { buf->blob.data = buf->vaddr; buf->blob.size = size; - buf->dentry = debugfs_create_blob(name, 0644, parent, + buf->dentry = debugfs_create_blob(name, 0444, parent, &buf->blob); } @@ -3233,7 +3233,7 @@ static int coda_probe(struct platform_device *pdev) memset(dev->iram.vaddr, 0, dev->iram.size); dev->iram.blob.data = dev->iram.vaddr; dev->iram.blob.size = dev->iram.size; - dev->iram.dentry = debugfs_create_blob("iram", 0644, + dev->iram.dentry = debugfs_create_blob("iram", 0444, dev->debugfs_root, &dev->iram.blob); } From e198be37e52551bb863d07d2edc535d0932a3c4f Mon Sep 17 00:00:00 2001 From: Steve Longerbeam Date: Mon, 17 May 2021 16:29:23 +0200 Subject: [PATCH 359/394] media: imx-csi: Skip first few frames from a BT.656 source Some BT.656 sensors (e.g. ADV718x) transmit frames with unstable BT.656 sync codes after initial power on. This confuses the imx CSI,resulting in vertical and/or horizontal sync issues. Skip the first 20 frames to avoid the unstable sync codes. [fabio: fixed checkpatch warning and increased the frame skipping to 20] Signed-off-by: Steve Longerbeam Signed-off-by: Fabio Estevam Reviewed-by: Tim Harvey Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/imx-media-csi.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c index d2f1d40b2d5a..bb1305c9daaf 100644 --- a/drivers/staging/media/imx/imx-media-csi.c +++ b/drivers/staging/media/imx/imx-media-csi.c @@ -750,9 +750,10 @@ static int csi_setup(struct csi_priv *priv) static int csi_start(struct csi_priv *priv) { - struct v4l2_fract *output_fi; + struct v4l2_fract *input_fi, *output_fi; int ret; + input_fi = &priv->frame_interval[CSI_SINK_PAD]; output_fi = &priv->frame_interval[priv->active_output_pad]; /* start upstream */ @@ -761,6 +762,17 @@ static int csi_start(struct csi_priv *priv) if (ret) return ret; + /* Skip first few frames from a BT.656 source */ + if (priv->upstream_ep.bus_type == V4L2_MBUS_BT656) { + u32 delay_usec, bad_frames = 20; + + delay_usec = DIV_ROUND_UP_ULL((u64)USEC_PER_SEC * + input_fi->numerator * bad_frames, + input_fi->denominator); + + usleep_range(delay_usec, delay_usec + 1000); + } + if (priv->dest == IPU_CSI_DEST_IDMAC) { ret = csi_idmac_start(priv); if (ret) From 2b889a4afcacef4888ac8203a60e68004816e1fd Mon Sep 17 00:00:00 2001 From: Evgeny Novikov Date: Wed, 26 May 2021 16:35:06 +0200 Subject: [PATCH 360/394] media: marvell-ccic: set error code in probe When i2c_new_client_device() fails, cafe_pci_probe() cleans up all resources and returns 0. The patch sets the error code on the corresponding path. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Evgeny Novikov Acked-by: Sakari Ailus Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/marvell-ccic/cafe-driver.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/marvell-ccic/cafe-driver.c b/drivers/media/platform/marvell-ccic/cafe-driver.c index baac86f3d153..9aa374fa8b36 100644 --- a/drivers/media/platform/marvell-ccic/cafe-driver.c +++ b/drivers/media/platform/marvell-ccic/cafe-driver.c @@ -486,6 +486,7 @@ static int cafe_pci_probe(struct pci_dev *pdev, struct cafe_camera *cam; struct mcam_camera *mcam; struct v4l2_async_subdev *asd; + struct i2c_client *i2c_dev; /* * Start putting together one of our big camera structures. @@ -561,11 +562,16 @@ static int cafe_pci_probe(struct pci_dev *pdev, clkdev_create(mcam->mclk, "xclk", "%d-%04x", i2c_adapter_id(cam->i2c_adapter), ov7670_info.addr); - if (!IS_ERR(i2c_new_client_device(cam->i2c_adapter, &ov7670_info))) { - cam->registered = 1; - return 0; + i2c_dev = i2c_new_client_device(cam->i2c_adapter, &ov7670_info); + if (IS_ERR(i2c_dev)) { + ret = PTR_ERR(i2c_dev); + goto out_mccic_shutdown; } + cam->registered = 1; + return 0; + +out_mccic_shutdown: mccic_shutdown(mcam); out_smbus_shutdown: cafe_smbus_shutdown(cam); From 5d11e6aad1811ea293ee2996cec9124f7fccb661 Mon Sep 17 00:00:00 2001 From: Dillon Min Date: Wed, 26 May 2021 17:18:32 +0200 Subject: [PATCH 361/394] media: s5p-g2d: Fix a memory leak on ctx->fh.m2m_ctx The m2m_ctx resources was allocated by v4l2_m2m_ctx_init() in g2d_open() should be freed from g2d_release() when it's not used. Fix it Fixes: 918847341af0 ("[media] v4l: add G2D driver for s5p device family") Signed-off-by: Dillon Min Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-g2d/g2d.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/platform/s5p-g2d/g2d.c b/drivers/media/platform/s5p-g2d/g2d.c index 15bcb7f6e113..1cb5eaabf340 100644 --- a/drivers/media/platform/s5p-g2d/g2d.c +++ b/drivers/media/platform/s5p-g2d/g2d.c @@ -276,6 +276,9 @@ static int g2d_release(struct file *file) struct g2d_dev *dev = video_drvdata(file); struct g2d_ctx *ctx = fh2ctx(file->private_data); + mutex_lock(&dev->mutex); + v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); + mutex_unlock(&dev->mutex); v4l2_ctrl_handler_free(&ctx->ctrl_handler); v4l2_fh_del(&ctx->fh); v4l2_fh_exit(&ctx->fh); From 584b2373eef9c487620153a758072e295ab28cc1 Mon Sep 17 00:00:00 2001 From: Piyush Thange Date: Wed, 26 May 2021 17:26:19 +0200 Subject: [PATCH 362/394] media: usb: cpia2: Fixed Coding Style issues Fixed all the Coding style issues generated by checkpatch.pl. The changes made considering the --strict option. Signed-off-by: Piyush Thange Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/cpia2/cpia2_v4l.c | 149 ++++++++++++++-------------- 1 file changed, 74 insertions(+), 75 deletions(-) diff --git a/drivers/media/usb/cpia2/cpia2_v4l.c b/drivers/media/usb/cpia2/cpia2_v4l.c index 69d5c628a797..926ecfc9b64a 100644 --- a/drivers/media/usb/cpia2/cpia2_v4l.c +++ b/drivers/media/usb/cpia2/cpia2_v4l.c @@ -140,10 +140,10 @@ static ssize_t cpia2_v4l_read(struct file *file, char __user *buf, size_t count, loff_t *off) { struct camera_data *cam = video_drvdata(file); - int noblock = file->f_flags&O_NONBLOCK; + int noblock = file->f_flags & O_NONBLOCK; ssize_t ret; - if(!cam) + if (!cam) return -EINVAL; if (mutex_lock_interruptible(&cam->v4l2_lock)) @@ -153,7 +153,6 @@ static ssize_t cpia2_v4l_read(struct file *file, char __user *buf, size_t count, return ret; } - /****************************************************************************** * * cpia2_v4l_poll @@ -170,7 +169,6 @@ static __poll_t cpia2_v4l_poll(struct file *filp, struct poll_table_struct *wait return res; } - static int sync(struct camera_data *cam, int frame_nr) { struct framebuf *frame = &cam->buffers[frame_nr]; @@ -247,8 +245,8 @@ static int cpia2_querycap(struct file *file, void *fh, struct v4l2_capability *v break; } - if (usb_make_path(cam->dev, vc->bus_info, sizeof(vc->bus_info)) <0) - memset(vc->bus_info,0, sizeof(vc->bus_info)); + if (usb_make_path(cam->dev, vc->bus_info, sizeof(vc->bus_info)) < 0) + memset(vc->bus_info, 0, sizeof(vc->bus_info)); return 0; } @@ -289,7 +287,7 @@ static int cpia2_s_input(struct file *file, void *fh, unsigned int i) *****************************************************************************/ static int cpia2_enum_fmt_vid_cap(struct file *file, void *fh, - struct v4l2_fmtdesc *f) + struct v4l2_fmtdesc *f) { if (f->index > 1) return -EINVAL; @@ -310,13 +308,13 @@ static int cpia2_enum_fmt_vid_cap(struct file *file, void *fh, *****************************************************************************/ static int cpia2_try_fmt_vid_cap(struct file *file, void *fh, - struct v4l2_format *f) + struct v4l2_format *f) { struct camera_data *cam = video_drvdata(file); if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG && f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG) - return -EINVAL; + return -EINVAL; f->fmt.pix.field = V4L2_FIELD_NONE; f->fmt.pix.bytesperline = 0; @@ -371,19 +369,20 @@ static int cpia2_try_fmt_vid_cap(struct file *file, void *fh, *****************************************************************************/ static int cpia2_s_fmt_vid_cap(struct file *file, void *_fh, - struct v4l2_format *f) + struct v4l2_format *f) { struct camera_data *cam = video_drvdata(file); int err, frame; err = cpia2_try_fmt_vid_cap(file, _fh, f); - if(err != 0) + if (err != 0) return err; cam->pixelformat = f->fmt.pix.pixelformat; /* NOTE: This should be set to 1 for MJPEG, but some apps don't handle - * the missing Huffman table properly. */ + * the missing Huffman table properly. + */ cam->params.compression.inhibit_htables = 0; /*f->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG;*/ @@ -421,7 +420,7 @@ static int cpia2_s_fmt_vid_cap(struct file *file, void *_fh, *****************************************************************************/ static int cpia2_g_fmt_vid_cap(struct file *file, void *fh, - struct v4l2_format *f) + struct v4l2_format *f) { struct camera_data *cam = video_drvdata(file); @@ -547,9 +546,8 @@ static const struct { }; static int cpia2_enum_framesizes(struct file *file, void *fh, - struct v4l2_frmsizeenum *fsize) + struct v4l2_frmsizeenum *fsize) { - if (fsize->pixel_format != V4L2_PIX_FMT_MJPEG && fsize->pixel_format != V4L2_PIX_FMT_JPEG) return -EINVAL; @@ -563,7 +561,7 @@ static int cpia2_enum_framesizes(struct file *file, void *fh, } static int cpia2_enum_frameintervals(struct file *file, void *fh, - struct v4l2_frmivalenum *fival) + struct v4l2_frmivalenum *fival) { struct camera_data *cam = video_drvdata(file); int max = ARRAY_SIZE(framerate_controls) - 1; @@ -665,19 +663,18 @@ static int cpia2_g_jpegcomp(struct file *file, void *fh, struct v4l2_jpegcompres parms->quality = 80; // TODO: Can this be made meaningful? parms->jpeg_markers = V4L2_JPEG_MARKER_DQT | V4L2_JPEG_MARKER_DRI; - if(!cam->params.compression.inhibit_htables) { + if (!cam->params.compression.inhibit_htables) parms->jpeg_markers |= V4L2_JPEG_MARKER_DHT; - } parms->APPn = cam->APPn; parms->APP_len = cam->APP_len; - if(cam->APP_len > 0) { + if (cam->APP_len > 0) { memcpy(parms->APP_data, cam->APP_data, cam->APP_len); parms->jpeg_markers |= V4L2_JPEG_MARKER_APP; } parms->COM_len = cam->COM_len; - if(cam->COM_len > 0) { + if (cam->COM_len > 0) { memcpy(parms->COM_data, cam->COM_data, cam->COM_len); parms->jpeg_markers |= JPEG_MARKER_COM; } @@ -698,7 +695,7 @@ static int cpia2_g_jpegcomp(struct file *file, void *fh, struct v4l2_jpegcompres *****************************************************************************/ static int cpia2_s_jpegcomp(struct file *file, void *fh, - const struct v4l2_jpegcompression *parms) + const struct v4l2_jpegcompression *parms) { struct camera_data *cam = video_drvdata(file); @@ -708,9 +705,9 @@ static int cpia2_s_jpegcomp(struct file *file, void *fh, cam->params.compression.inhibit_htables = !(parms->jpeg_markers & V4L2_JPEG_MARKER_DHT); - if(parms->APP_len != 0) { - if(parms->APP_len > 0 && - parms->APP_len <= sizeof(cam->APP_data) && + if (parms->APP_len != 0) { + if (parms->APP_len > 0 && + parms->APP_len <= sizeof(cam->APP_data) && parms->APPn >= 0 && parms->APPn <= 15) { cam->APPn = parms->APPn; cam->APP_len = parms->APP_len; @@ -724,9 +721,9 @@ static int cpia2_s_jpegcomp(struct file *file, void *fh, cam->APP_len = 0; } - if(parms->COM_len != 0) { - if(parms->COM_len > 0 && - parms->COM_len <= sizeof(cam->COM_data)) { + if (parms->COM_len != 0) { + if (parms->COM_len > 0 && + parms->COM_len <= sizeof(cam->COM_data)) { cam->COM_len = parms->COM_len; memcpy(cam->COM_data, parms->COM_data, parms->COM_len); } else { @@ -751,8 +748,8 @@ static int cpia2_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers { struct camera_data *cam = video_drvdata(file); - if(req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - req->memory != V4L2_MEMORY_MMAP) + if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || + req->memory != V4L2_MEMORY_MMAP) return -EINVAL; DBG("REQBUFS requested:%d returning:%d\n", req->count, cam->num_frames); @@ -774,8 +771,8 @@ static int cpia2_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf) { struct camera_data *cam = video_drvdata(file); - if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - buf->index >= cam->num_frames) + if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || + buf->index >= cam->num_frames) return -EINVAL; buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer; @@ -783,7 +780,7 @@ static int cpia2_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf) buf->memory = V4L2_MEMORY_MMAP; - if(cam->mmapped) + if (cam->mmapped) buf->flags = V4L2_BUF_FLAG_MAPPED; else buf->flags = 0; @@ -806,8 +803,8 @@ static int cpia2_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf) } DBG("QUERYBUF index:%d offset:%d flags:%d seq:%d bytesused:%d\n", - buf->index, buf->m.offset, buf->flags, buf->sequence, - buf->bytesused); + buf->index, buf->m.offset, buf->flags, buf->sequence, + buf->bytesused); return 0; } @@ -824,14 +821,14 @@ static int cpia2_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf) { struct camera_data *cam = video_drvdata(file); - if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - buf->memory != V4L2_MEMORY_MMAP || + if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || + buf->memory != V4L2_MEMORY_MMAP || buf->index >= cam->num_frames) return -EINVAL; DBG("QBUF #%d\n", buf->index); - if(cam->buffers[buf->index].status == FRAME_READY) + if (cam->buffers[buf->index].status == FRAME_READY) cam->buffers[buf->index].status = FRAME_EMPTY; return 0; @@ -849,9 +846,10 @@ static int find_earliest_filled_buffer(struct camera_data *cam) { int i; int found = -1; - for (i=0; inum_frames; i++) { - if(cam->buffers[i].status == FRAME_READY) { - if(found < 0) { + + for (i = 0; i < cam->num_frames; i++) { + if (cam->buffers[i].status == FRAME_READY) { + if (found < 0) { found = i; } else { /* find which buffer is earlier */ @@ -876,22 +874,23 @@ static int cpia2_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) struct camera_data *cam = video_drvdata(file); int frame; - if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - buf->memory != V4L2_MEMORY_MMAP) + if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || + buf->memory != V4L2_MEMORY_MMAP) return -EINVAL; frame = find_earliest_filled_buffer(cam); - if(frame < 0 && file->f_flags&O_NONBLOCK) + if (frame < 0 && file->f_flags & O_NONBLOCK) return -EAGAIN; - if(frame < 0) { + if (frame < 0) { /* Wait for a frame to become available */ - struct framebuf *cb=cam->curbuff; + struct framebuf *cb = cam->curbuff; + mutex_unlock(&cam->v4l2_lock); wait_event_interruptible(cam->wq_stream, !video_is_registered(&cam->vdev) || - (cb=cam->curbuff)->status == FRAME_READY); + (cb = cam->curbuff)->status == FRAME_READY); mutex_lock(&cam->v4l2_lock); if (signal_pending(current)) return -ERESTARTSYS; @@ -900,7 +899,6 @@ static int cpia2_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) frame = cb->num; } - buf->index = frame; buf->bytesused = cam->buffers[buf->index].length; buf->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE @@ -931,7 +929,7 @@ static int cpia2_streamon(struct file *file, void *fh, enum v4l2_buf_type type) if (!cam->streaming) { ret = cpia2_usb_stream_start(cam, - cam->params.camera_state.stream_mode); + cam->params.camera_state.stream_mode); if (!ret) v4l2_ctrl_grab(cam->usb_alt, true); } @@ -969,7 +967,7 @@ static int cpia2_mmap(struct file *file, struct vm_area_struct *area) return -ERESTARTSYS; retval = cpia2_remap_buffer(cam, area); - if(!retval) + if (!retval) cam->stream_fh = file->private_data; mutex_unlock(&cam->v4l2_lock); return retval; @@ -1080,39 +1078,42 @@ int cpia2_register_camera(struct camera_data *cam) v4l2_ctrl_handler_init(hdl, 12); v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops, - V4L2_CID_BRIGHTNESS, - cam->params.pnp_id.device_type == DEVICE_STV_672 ? 1 : 0, - 255, 1, DEFAULT_BRIGHTNESS); + V4L2_CID_BRIGHTNESS, + cam->params.pnp_id.device_type == DEVICE_STV_672 ? 1 : 0, + 255, 1, DEFAULT_BRIGHTNESS); v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops, - V4L2_CID_CONTRAST, 0, 255, 1, DEFAULT_CONTRAST); + V4L2_CID_CONTRAST, 0, 255, 1, DEFAULT_CONTRAST); v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops, - V4L2_CID_SATURATION, 0, 255, 1, DEFAULT_SATURATION); + V4L2_CID_SATURATION, 0, 255, 1, DEFAULT_SATURATION); v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops, - V4L2_CID_HFLIP, 0, 1, 1, 0); + V4L2_CID_HFLIP, 0, 1, 1, 0); v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops, - V4L2_CID_JPEG_ACTIVE_MARKER, 0, - V4L2_JPEG_ACTIVE_MARKER_DHT, 0, - V4L2_JPEG_ACTIVE_MARKER_DHT); + V4L2_CID_JPEG_ACTIVE_MARKER, 0, + V4L2_JPEG_ACTIVE_MARKER_DHT, 0, + V4L2_JPEG_ACTIVE_MARKER_DHT); v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops, - V4L2_CID_JPEG_COMPRESSION_QUALITY, 1, - 100, 1, 100); + V4L2_CID_JPEG_COMPRESSION_QUALITY, 1, + 100, 1, 100); cpia2_usb_alt.def = alternate; cam->usb_alt = v4l2_ctrl_new_custom(hdl, &cpia2_usb_alt, NULL); /* VP5 Only */ if (cam->params.pnp_id.device_type != DEVICE_STV_672) v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops, - V4L2_CID_VFLIP, 0, 1, 1, 0); + V4L2_CID_VFLIP, 0, 1, 1, 0); /* Flicker control only valid for 672 */ if (cam->params.pnp_id.device_type == DEVICE_STV_672) v4l2_ctrl_new_std_menu(hdl, &cpia2_ctrl_ops, - V4L2_CID_POWER_LINE_FREQUENCY, - V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, 0); + V4L2_CID_POWER_LINE_FREQUENCY, + V4L2_CID_POWER_LINE_FREQUENCY_60HZ, + 0, 0); /* Light control only valid for the QX5 Microscope */ if (cam->params.pnp_id.product == 0x151) { cam->top_light = v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops, - V4L2_CID_ILLUMINATORS_1, 0, 1, 1, 0); + V4L2_CID_ILLUMINATORS_1, + 0, 1, 1, 0); cam->bottom_light = v4l2_ctrl_new_std(hdl, &cpia2_ctrl_ops, - V4L2_CID_ILLUMINATORS_2, 0, 1, 1, 0); + V4L2_CID_ILLUMINATORS_2, + 0, 1, 1, 0); v4l2_ctrl_cluster(2, &cam->top_light); } @@ -1159,28 +1160,28 @@ void cpia2_unregister_camera(struct camera_data *cam) *****************************************************************************/ static void __init check_parameters(void) { - if(buffer_size < PAGE_SIZE) { + if (buffer_size < PAGE_SIZE) { buffer_size = PAGE_SIZE; LOG("buffer_size too small, setting to %d\n", buffer_size); - } else if(buffer_size > 1024*1024) { + } else if (buffer_size > 1024 * 1024) { /* arbitrary upper limiit */ - buffer_size = 1024*1024; + buffer_size = 1024 * 1024; LOG("buffer_size ridiculously large, setting to %d\n", buffer_size); } else { - buffer_size += PAGE_SIZE-1; - buffer_size &= ~(PAGE_SIZE-1); + buffer_size += PAGE_SIZE - 1; + buffer_size &= ~(PAGE_SIZE - 1); } - if(num_buffers < 1) { + if (num_buffers < 1) { num_buffers = 1; LOG("num_buffers too small, setting to %d\n", num_buffers); - } else if(num_buffers > VIDEO_MAX_FRAME) { + } else if (num_buffers > VIDEO_MAX_FRAME) { num_buffers = VIDEO_MAX_FRAME; LOG("num_buffers too large, setting to %d\n", num_buffers); } - if(alternate < USBIF_ISO_1 || alternate > USBIF_ISO_6) { + if (alternate < USBIF_ISO_1 || alternate > USBIF_ISO_6) { alternate = DEFAULT_ALT; LOG("alternate specified is invalid, using %d\n", alternate); } @@ -1197,7 +1198,6 @@ static void __init check_parameters(void) /************ Module Stuff ***************/ - /****************************************************************************** * * cpia2_init/module_init @@ -1211,7 +1211,6 @@ static int __init cpia2_init(void) return cpia2_usb_init(); } - /****************************************************************************** * * cpia2_exit/module_exit From 40d62da2a1278ea1e58ed8e304142cf09de41232 Mon Sep 17 00:00:00 2001 From: lijian Date: Thu, 27 May 2021 04:46:43 +0200 Subject: [PATCH 363/394] media: v4l2-event: Modified variable type 'unsigned' to 'unsigned int' Prefer 'unsigned int' to bare use of 'unsigned'. So modified variable type 'unsigned' to 'unsigned int' in v4l2-event.c. Signed-off-by: lijian Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-event.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-event.c b/drivers/media/v4l2-core/v4l2-event.c index caad58bde326..c5ce9f11ad7b 100644 --- a/drivers/media/v4l2-core/v4l2-event.c +++ b/drivers/media/v4l2-core/v4l2-event.c @@ -18,7 +18,7 @@ #include #include -static unsigned sev_pos(const struct v4l2_subscribed_event *sev, unsigned idx) +static unsigned int sev_pos(const struct v4l2_subscribed_event *sev, unsigned int idx) { idx += sev->first; return idx >= sev->elems ? idx - sev->elems : idx; @@ -221,12 +221,12 @@ static void __v4l2_event_unsubscribe(struct v4l2_subscribed_event *sev) } int v4l2_event_subscribe(struct v4l2_fh *fh, - const struct v4l2_event_subscription *sub, unsigned elems, + const struct v4l2_event_subscription *sub, unsigned int elems, const struct v4l2_subscribed_event_ops *ops) { struct v4l2_subscribed_event *sev, *found_ev; unsigned long flags; - unsigned i; + unsigned int i; int ret = 0; if (sub->type == V4L2_EVENT_ALL) From e70bc1ea973ddac75119c75fe11b064dd8731051 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20S=C3=B6derlund?= Date: Fri, 11 Jun 2021 18:07:34 +0200 Subject: [PATCH 364/394] media: rcar-csi2: Add support for Y10 and Y8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for two new media bus formats, Y10 and Y8. Signed-off-by: Niklas Söderlund Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/rcar-vin/rcar-csi2.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c b/drivers/media/platform/rcar-vin/rcar-csi2.c index a128bf80e42c..e28eff039688 100644 --- a/drivers/media/platform/rcar-vin/rcar-csi2.c +++ b/drivers/media/platform/rcar-vin/rcar-csi2.c @@ -320,10 +320,12 @@ static const struct rcar_csi2_format rcar_csi2_formats[] = { { .code = MEDIA_BUS_FMT_YUYV8_1X16, .datatype = 0x1e, .bpp = 16 }, { .code = MEDIA_BUS_FMT_UYVY8_2X8, .datatype = 0x1e, .bpp = 16 }, { .code = MEDIA_BUS_FMT_YUYV10_2X10, .datatype = 0x1e, .bpp = 20 }, + { .code = MEDIA_BUS_FMT_Y10_1X10, .datatype = 0x2b, .bpp = 10 }, { .code = MEDIA_BUS_FMT_SBGGR8_1X8, .datatype = 0x2a, .bpp = 8 }, { .code = MEDIA_BUS_FMT_SGBRG8_1X8, .datatype = 0x2a, .bpp = 8 }, { .code = MEDIA_BUS_FMT_SGRBG8_1X8, .datatype = 0x2a, .bpp = 8 }, { .code = MEDIA_BUS_FMT_SRGGB8_1X8, .datatype = 0x2a, .bpp = 8 }, + { .code = MEDIA_BUS_FMT_Y8_1X8, .datatype = 0x2a, .bpp = 8 }, }; static const struct rcar_csi2_format *rcsi2_code_to_fmt(unsigned int code) From 682e69d7a262d8959f8b8cc1a8ed68bc6ec4be61 Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Sat, 12 Jun 2021 01:42:00 +0200 Subject: [PATCH 365/394] media: imx-jpeg: Constify static struct v4l2_m2m_ops The only usage of mxc_jpeg_m2m_ops is to pass its address to v4l2_m2m_init() which takes a pointer to const struct v4l2_m2m_ops. Make it const to allow the compiler to put it in read-only memory. Signed-off-by: Rikard Falkeborn Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/imx-jpeg/mxc-jpeg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/imx-jpeg/mxc-jpeg.c index 03b9264af068..3a49007e1264 100644 --- a/drivers/media/platform/imx-jpeg/mxc-jpeg.c +++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.c @@ -1890,7 +1890,7 @@ static const struct v4l2_file_operations mxc_jpeg_fops = { .mmap = v4l2_m2m_fop_mmap, }; -static struct v4l2_m2m_ops mxc_jpeg_m2m_ops = { +static const struct v4l2_m2m_ops mxc_jpeg_m2m_ops = { .device_run = mxc_jpeg_device_run, }; From 7ec1c4a57c428a2114b81059e8683f8cf348920f Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Sat, 12 Jun 2021 01:42:01 +0200 Subject: [PATCH 366/394] media: imx-jpeg: Constify static struct mxc_jpeg_fmt It is only read-from, so make it const. In order to be able to do this, constify all places where mxc_jpeg_fmt is used, in function arguments, return values and pointers. On top of that, make the name a pointer to const char. On aarch64, this shrinks object code size with 550 bytes with gcc 11.1.0, and almost 2kB with clang 12.0.0. Signed-off-by: Rikard Falkeborn Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/imx-jpeg/mxc-jpeg.c | 16 ++++++++-------- drivers/media/platform/imx-jpeg/mxc-jpeg.h | 18 +++++++++--------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/media/platform/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/imx-jpeg/mxc-jpeg.c index 3a49007e1264..755138063ee6 100644 --- a/drivers/media/platform/imx-jpeg/mxc-jpeg.c +++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.c @@ -62,7 +62,7 @@ #include "mxc-jpeg-hw.h" #include "mxc-jpeg.h" -static struct mxc_jpeg_fmt mxc_formats[] = { +static const struct mxc_jpeg_fmt mxc_formats[] = { { .name = "JPEG", .fourcc = V4L2_PIX_FMT_JPEG, @@ -341,7 +341,7 @@ static inline struct mxc_jpeg_ctx *mxc_jpeg_fh_to_ctx(struct v4l2_fh *fh) return container_of(fh, struct mxc_jpeg_ctx, fh); } -static int enum_fmt(struct mxc_jpeg_fmt *mxc_formats, int n, +static int enum_fmt(const struct mxc_jpeg_fmt *mxc_formats, int n, struct v4l2_fmtdesc *f, u32 type) { int i, num = 0; @@ -368,13 +368,13 @@ static int enum_fmt(struct mxc_jpeg_fmt *mxc_formats, int n, return 0; } -static struct mxc_jpeg_fmt *mxc_jpeg_find_format(struct mxc_jpeg_ctx *ctx, - u32 pixelformat) +static const struct mxc_jpeg_fmt *mxc_jpeg_find_format(struct mxc_jpeg_ctx *ctx, + u32 pixelformat) { unsigned int k; for (k = 0; k < MXC_JPEG_NUM_FORMATS; k++) { - struct mxc_jpeg_fmt *fmt = &mxc_formats[k]; + const struct mxc_jpeg_fmt *fmt = &mxc_formats[k]; if (fmt->fourcc == pixelformat) return fmt; @@ -1536,7 +1536,7 @@ static int mxc_jpeg_enum_fmt_vid_out(struct file *file, void *priv, MXC_JPEG_FMT_TYPE_RAW); } -static int mxc_jpeg_try_fmt(struct v4l2_format *f, struct mxc_jpeg_fmt *fmt, +static int mxc_jpeg_try_fmt(struct v4l2_format *f, const struct mxc_jpeg_fmt *fmt, struct mxc_jpeg_ctx *ctx, int q_type) { struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; @@ -1612,7 +1612,7 @@ static int mxc_jpeg_try_fmt_vid_cap(struct file *file, void *priv, struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv); struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; struct device *dev = jpeg->dev; - struct mxc_jpeg_fmt *fmt; + const struct mxc_jpeg_fmt *fmt; u32 fourcc = f->fmt.pix_mp.pixelformat; int q_type = (jpeg->mode == MXC_JPEG_DECODE) ? @@ -1643,7 +1643,7 @@ static int mxc_jpeg_try_fmt_vid_out(struct file *file, void *priv, struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv); struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; struct device *dev = jpeg->dev; - struct mxc_jpeg_fmt *fmt; + const struct mxc_jpeg_fmt *fmt; u32 fourcc = f->fmt.pix_mp.pixelformat; int q_type = (jpeg->mode == MXC_JPEG_ENCODE) ? diff --git a/drivers/media/platform/imx-jpeg/mxc-jpeg.h b/drivers/media/platform/imx-jpeg/mxc-jpeg.h index 7697de490d2e..4c210852e876 100644 --- a/drivers/media/platform/imx-jpeg/mxc-jpeg.h +++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.h @@ -51,7 +51,7 @@ enum mxc_jpeg_mode { * @flags: flags describing format applicability */ struct mxc_jpeg_fmt { - char *name; + const char *name; u32 fourcc; enum v4l2_jpeg_chroma_subsampling subsampling; int nc; @@ -74,14 +74,14 @@ struct mxc_jpeg_desc { } __packed; struct mxc_jpeg_q_data { - struct mxc_jpeg_fmt *fmt; - u32 sizeimage[MXC_JPEG_MAX_PLANES]; - u32 bytesperline[MXC_JPEG_MAX_PLANES]; - int w; - int w_adjusted; - int h; - int h_adjusted; - unsigned int sequence; + const struct mxc_jpeg_fmt *fmt; + u32 sizeimage[MXC_JPEG_MAX_PLANES]; + u32 bytesperline[MXC_JPEG_MAX_PLANES]; + int w; + int w_adjusted; + int h; + int h_adjusted; + unsigned int sequence; }; struct mxc_jpeg_ctx { From 00ae4ebc2d07db50d8432ebec3158c96b36f1a6d Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sun, 13 Jun 2021 19:36:34 +0200 Subject: [PATCH 367/394] media: pci: cx88: switch from 'pci_' to 'dma_' API The wrappers in include/linux/pci-dma-compat.h should go away. The patch has been generated with the coccinelle script below and has been hand modified to replace GFP_ with a correct flag. It has been compile tested. Only 2 functions allocate some memory. They are both in cx88-core.c When memory is allocated in 'cx88_risc_buffer()', GFP_KERNEL can be used because its 2 callers end up to '.buf_prepare' functions in 'vb2_ops' structures. The call chains are: .buf_prepare (cx88-vbi.c) --> buffer_prepare (cx88-vbi.c) --> cx88_risc_buffer .buf_prepare (cx88-video.c) --> buffer_prepare (cx88-video.c) --> cx88_risc_buffer When memory is allocated in 'cx88_risc_databuffer()', GFP_KERNEL can be used because its 2 callers end up to 'snd_cx88_hw_params' which already uses GFP_KERNEL and '.buf_prepare' functions in 'vb2_ops' structures. The call chains are: snd_cx88_hw_params (cx88-alsa.c) --> cx88_risc_databuffer .buf_prepare (cx88-blackbird.c) --> buffer_prepare (cx88-blackbird.c) --> cx8802_buf_prepare (cx88-mpeg.c) --> cx88_risc_databuffer .buf_prepare (cx88-dvb.c) --> buffer_prepare (cx88-dvb.c) --> cx8802_buf_prepare (cx88-mpeg.c) --> cx88_risc_databuffer @@ @@ - PCI_DMA_BIDIRECTIONAL + DMA_BIDIRECTIONAL @@ @@ - PCI_DMA_TODEVICE + DMA_TO_DEVICE @@ @@ - PCI_DMA_FROMDEVICE + DMA_FROM_DEVICE @@ @@ - PCI_DMA_NONE + DMA_NONE @@ expression e1, e2, e3; @@ - pci_alloc_consistent(e1, e2, e3) + dma_alloc_coherent(&e1->dev, e2, e3, GFP_) @@ expression e1, e2, e3; @@ - pci_zalloc_consistent(e1, e2, e3) + dma_alloc_coherent(&e1->dev, e2, e3, GFP_) @@ expression e1, e2, e3, e4; @@ - pci_free_consistent(e1, e2, e3, e4) + dma_free_coherent(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_map_single(e1, e2, e3, e4) + dma_map_single(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_unmap_single(e1, e2, e3, e4) + dma_unmap_single(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4, e5; @@ - pci_map_page(e1, e2, e3, e4, e5) + dma_map_page(&e1->dev, e2, e3, e4, e5) @@ expression e1, e2, e3, e4; @@ - pci_unmap_page(e1, e2, e3, e4) + dma_unmap_page(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_map_sg(e1, e2, e3, e4) + dma_map_sg(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_unmap_sg(e1, e2, e3, e4) + dma_unmap_sg(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_dma_sync_single_for_cpu(e1, e2, e3, e4) + dma_sync_single_for_cpu(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_dma_sync_single_for_device(e1, e2, e3, e4) + dma_sync_single_for_device(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_dma_sync_sg_for_cpu(e1, e2, e3, e4) + dma_sync_sg_for_cpu(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_dma_sync_sg_for_device(e1, e2, e3, e4) + dma_sync_sg_for_device(&e1->dev, e2, e3, e4) @@ expression e1, e2; @@ - pci_dma_mapping_error(e1, e2) + dma_mapping_error(&e1->dev, e2) @@ expression e1, e2; @@ - pci_set_dma_mask(e1, e2) + dma_set_mask(&e1->dev, e2) @@ expression e1, e2; @@ - pci_set_consistent_dma_mask(e1, e2) + dma_set_coherent_mask(&e1->dev, e2) Signed-off-by: Christophe JAILLET Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx88/cx88-alsa.c | 6 +++--- drivers/media/pci/cx88/cx88-blackbird.c | 3 ++- drivers/media/pci/cx88/cx88-core.c | 6 ++++-- drivers/media/pci/cx88/cx88-dvb.c | 3 ++- drivers/media/pci/cx88/cx88-mpeg.c | 6 +++--- drivers/media/pci/cx88/cx88-vbi.c | 3 ++- drivers/media/pci/cx88/cx88-video.c | 5 +++-- 7 files changed, 19 insertions(+), 13 deletions(-) diff --git a/drivers/media/pci/cx88/cx88-alsa.c b/drivers/media/pci/cx88/cx88-alsa.c index c83814c052d3..29fb1311e443 100644 --- a/drivers/media/pci/cx88/cx88-alsa.c +++ b/drivers/media/pci/cx88/cx88-alsa.c @@ -357,8 +357,8 @@ static int dsp_buffer_free(struct cx88_audio_dev *chip) cx88_alsa_dma_unmap(chip); cx88_alsa_dma_free(chip->buf); if (risc->cpu) - pci_free_consistent(chip->pci, risc->size, - risc->cpu, risc->dma); + dma_free_coherent(&chip->pci->dev, risc->size, risc->cpu, + risc->dma); kfree(chip->buf); chip->buf = NULL; @@ -868,7 +868,7 @@ static int snd_cx88_create(struct snd_card *card, struct pci_dev *pci, return err; } - err = pci_set_dma_mask(pci, DMA_BIT_MASK(32)); + err = dma_set_mask(&pci->dev, DMA_BIT_MASK(32)); if (err) { dprintk(0, "%s/1: Oops: no 32bit PCI DMA ???\n", core->name); cx88_core_put(core, pci); diff --git a/drivers/media/pci/cx88/cx88-blackbird.c b/drivers/media/pci/cx88/cx88-blackbird.c index fa4ca002ed19..d5da3bd5695d 100644 --- a/drivers/media/pci/cx88/cx88-blackbird.c +++ b/drivers/media/pci/cx88/cx88-blackbird.c @@ -685,7 +685,8 @@ static void buffer_finish(struct vb2_buffer *vb) struct cx88_riscmem *risc = &buf->risc; if (risc->cpu) - pci_free_consistent(dev->pci, risc->size, risc->cpu, risc->dma); + dma_free_coherent(&dev->pci->dev, risc->size, risc->cpu, + risc->dma); memset(risc, 0, sizeof(*risc)); } diff --git a/drivers/media/pci/cx88/cx88-core.c b/drivers/media/pci/cx88/cx88-core.c index 48c8a3429542..89d4d5a3ba34 100644 --- a/drivers/media/pci/cx88/cx88-core.c +++ b/drivers/media/pci/cx88/cx88-core.c @@ -152,7 +152,8 @@ int cx88_risc_buffer(struct pci_dev *pci, struct cx88_riscmem *risc, instructions += 4; risc->size = instructions * 8; risc->dma = 0; - risc->cpu = pci_zalloc_consistent(pci, risc->size, &risc->dma); + risc->cpu = dma_alloc_coherent(&pci->dev, risc->size, &risc->dma, + GFP_KERNEL); if (!risc->cpu) return -ENOMEM; @@ -190,7 +191,8 @@ int cx88_risc_databuffer(struct pci_dev *pci, struct cx88_riscmem *risc, instructions += 3; risc->size = instructions * 8; risc->dma = 0; - risc->cpu = pci_zalloc_consistent(pci, risc->size, &risc->dma); + risc->cpu = dma_alloc_coherent(&pci->dev, risc->size, &risc->dma, + GFP_KERNEL); if (!risc->cpu) return -ENOMEM; diff --git a/drivers/media/pci/cx88/cx88-dvb.c b/drivers/media/pci/cx88/cx88-dvb.c index 202ff9e8c257..2087f2491c42 100644 --- a/drivers/media/pci/cx88/cx88-dvb.c +++ b/drivers/media/pci/cx88/cx88-dvb.c @@ -103,7 +103,8 @@ static void buffer_finish(struct vb2_buffer *vb) struct cx88_riscmem *risc = &buf->risc; if (risc->cpu) - pci_free_consistent(dev->pci, risc->size, risc->cpu, risc->dma); + dma_free_coherent(&dev->pci->dev, risc->size, risc->cpu, + risc->dma); memset(risc, 0, sizeof(*risc)); } diff --git a/drivers/media/pci/cx88/cx88-mpeg.c b/drivers/media/pci/cx88/cx88-mpeg.c index a3edb548afde..680e1e3fe89b 100644 --- a/drivers/media/pci/cx88/cx88-mpeg.c +++ b/drivers/media/pci/cx88/cx88-mpeg.c @@ -226,8 +226,8 @@ int cx8802_buf_prepare(struct vb2_queue *q, struct cx8802_dev *dev, dev->ts_packet_size, dev->ts_packet_count, 0); if (rc) { if (risc->cpu) - pci_free_consistent(dev->pci, risc->size, - risc->cpu, risc->dma); + dma_free_coherent(&dev->pci->dev, risc->size, + risc->cpu, risc->dma); memset(risc, 0, sizeof(*risc)); return rc; } @@ -386,7 +386,7 @@ static int cx8802_init_common(struct cx8802_dev *dev) if (pci_enable_device(dev->pci)) return -EIO; pci_set_master(dev->pci); - err = pci_set_dma_mask(dev->pci, DMA_BIT_MASK(32)); + err = dma_set_mask(&dev->pci->dev, DMA_BIT_MASK(32)); if (err) { pr_err("Oops: no 32bit PCI DMA ???\n"); return -EIO; diff --git a/drivers/media/pci/cx88/cx88-vbi.c b/drivers/media/pci/cx88/cx88-vbi.c index 58489ea0c1da..a075788c64d4 100644 --- a/drivers/media/pci/cx88/cx88-vbi.c +++ b/drivers/media/pci/cx88/cx88-vbi.c @@ -159,7 +159,8 @@ static void buffer_finish(struct vb2_buffer *vb) struct cx88_riscmem *risc = &buf->risc; if (risc->cpu) - pci_free_consistent(dev->pci, risc->size, risc->cpu, risc->dma); + dma_free_coherent(&dev->pci->dev, risc->size, risc->cpu, + risc->dma); memset(risc, 0, sizeof(*risc)); } diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c index 8cffdacf6007..c17ad9f7d822 100644 --- a/drivers/media/pci/cx88/cx88-video.c +++ b/drivers/media/pci/cx88/cx88-video.c @@ -492,7 +492,8 @@ static void buffer_finish(struct vb2_buffer *vb) struct cx88_riscmem *risc = &buf->risc; if (risc->cpu) - pci_free_consistent(dev->pci, risc->size, risc->cpu, risc->dma); + dma_free_coherent(&dev->pci->dev, risc->size, risc->cpu, + risc->dma); memset(risc, 0, sizeof(*risc)); } @@ -1288,7 +1289,7 @@ static int cx8800_initdev(struct pci_dev *pci_dev, (unsigned long long)pci_resource_start(pci_dev, 0)); pci_set_master(pci_dev); - err = pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32)); + err = dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(32)); if (err) { pr_err("Oops: no 32bit PCI DMA ???\n"); goto fail_core; From 7629cbd6872f6aef0b7f1e20812194f4f4249bb2 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 10 Jun 2021 08:11:40 +0200 Subject: [PATCH 368/394] media: adv7842: remove spurious & and fix vga_edid size No need to use & to get the start address of an array. Fix the size of vga_edid.edid to a single block (128 bytes) to fix this smatch error: adv7842.c:2538 adv7842_set_edid() error: memcpy() '&state->vga_edid.edid' too small (128 vs 512) Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7842.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c index 263713963a00..7f8acbdf0db4 100644 --- a/drivers/media/i2c/adv7842.c +++ b/drivers/media/i2c/adv7842.c @@ -2531,20 +2531,20 @@ static int adv7842_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *e) switch (e->pad) { case ADV7842_EDID_PORT_VGA: - memset(&state->vga_edid.edid, 0, sizeof(state->vga_edid.edid)); + memset(state->vga_edid.edid, 0, sizeof(state->vga_edid.edid)); state->vga_edid.blocks = e->blocks; state->vga_edid.present = e->blocks ? 0x1 : 0x0; if (e->blocks) - memcpy(&state->vga_edid.edid, e->edid, 128 * e->blocks); + memcpy(state->vga_edid.edid, e->edid, 128); err = edid_write_vga_segment(sd); break; case ADV7842_EDID_PORT_A: case ADV7842_EDID_PORT_B: - memset(&state->hdmi_edid.edid, 0, sizeof(state->hdmi_edid.edid)); + memset(state->hdmi_edid.edid, 0, sizeof(state->hdmi_edid.edid)); state->hdmi_edid.blocks = e->blocks; if (e->blocks) { state->hdmi_edid.present |= 0x04 << e->pad; - memcpy(&state->hdmi_edid.edid, e->edid, 128 * e->blocks); + memcpy(state->hdmi_edid.edid, e->edid, 128 * e->blocks); } else { state->hdmi_edid.present &= ~(0x04 << e->pad); adv7842_s_detect_tx_5v_ctrl(sd); From 493ae3f2ba13a1c0a9d866c6c24a43ebe0d1ba42 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 10 Jun 2021 08:23:10 +0200 Subject: [PATCH 369/394] media: mtk-vcodec: fix kerneldoc warnings Fix the following kerneldoc warnings: drivers/media/platform/mtk-vcodec/venc_ipi_msg.h:31: warning: Enum value 'AP_IPIMSG_ENC_INIT' not described in enum 'venc_ipi_msg_id' drivers/media/platform/mtk-vcodec/venc_ipi_msg.h:31: warning: Enum value 'AP_IPIMSG_ENC_SET_PARAM' not described in enum 'venc_ipi_msg_id' drivers/media/platform/mtk-vcodec/venc_ipi_msg.h:31: warning: Enum value 'AP_IPIMSG_ENC_ENCODE' not described in enum 'venc_ipi_msg_id' drivers/media/platform/mtk-vcodec/venc_ipi_msg.h:31: warning: Enum value 'AP_IPIMSG_ENC_DEINIT' not described in enum 'venc_ipi_msg_id' drivers/media/platform/mtk-vcodec/venc_ipi_msg.h:31: warning: Enum value 'VPU_IPIMSG_ENC_INIT_DONE' not described in enum 'venc_ipi_msg_id' drivers/media/platform/mtk-vcodec/venc_ipi_msg.h:31: warning: Enum value 'VPU_IPIMSG_ENC_SET_PARAM_DONE' not described in enum 'venc_ipi_msg_id' drivers/media/platform/mtk-vcodec/venc_ipi_msg.h:31: warning: Enum value 'VPU_IPIMSG_ENC_ENCODE_DONE' not described in enum 'venc_ipi_msg_id' drivers/media/platform/mtk-vcodec/venc_ipi_msg.h:31: warning: Enum value 'VPU_IPIMSG_ENC_DEINIT_DONE' not described in enum 'venc_ipi_msg_id' drivers/media/platform/mtk-vcodec/venc_ipi_msg.h:31: warning: Excess enum value 'VPU_IPIMSG_ENC_XXX_DONE' description in 'venc_ipi_msg_id' drivers/media/platform/mtk-vcodec/venc_ipi_msg.h:31: warning: Excess enum value 'AP_IPIMSG_ENC_XXX' description in 'venc_ipi_msg_id' drivers/media/platform/mtk-vcodec/venc_ipi_msg.h:120: warning: Enum value 'VENC_IPI_MSG_STATUS_OK' not described in enum 'venc_ipi_msg_status' drivers/media/platform/mtk-vcodec/venc_ipi_msg.h:120: warning: Enum value 'VENC_IPI_MSG_STATUS_FAIL' not described in enum 'venc_ipi_msg_status' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:50: warning: Enum value 'VDEC_SYS' not described in enum 'mtk_hw_reg_idx' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:50: warning: Enum value 'VDEC_MISC' not described in enum 'mtk_hw_reg_idx' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:50: warning: Enum value 'VDEC_LD' not described in enum 'mtk_hw_reg_idx' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:50: warning: Enum value 'VDEC_TOP' not described in enum 'mtk_hw_reg_idx' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:50: warning: Enum value 'VDEC_CM' not described in enum 'mtk_hw_reg_idx' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:50: warning: Enum value 'VDEC_AD' not described in enum 'mtk_hw_reg_idx' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:50: warning: Enum value 'VDEC_AV' not described in enum 'mtk_hw_reg_idx' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:50: warning: Enum value 'VDEC_PP' not described in enum 'mtk_hw_reg_idx' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:50: warning: Enum value 'VDEC_HWD' not described in enum 'mtk_hw_reg_idx' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:50: warning: Enum value 'VDEC_HWQ' not described in enum 'mtk_hw_reg_idx' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:50: warning: Enum value 'VDEC_HWB' not described in enum 'mtk_hw_reg_idx' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:50: warning: Enum value 'VDEC_HWG' not described in enum 'mtk_hw_reg_idx' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:50: warning: Enum value 'NUM_MAX_VDEC_REG_BASE' not described in enum 'mtk_hw_reg_idx' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:50: warning: Enum value 'VENC_SYS' not described in enum 'mtk_hw_reg_idx' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:50: warning: Enum value 'VENC_LT_SYS' not described in enum 'mtk_hw_reg_idx' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:50: warning: Enum value 'NUM_MAX_VCODEC_REG_BASE' not described in enum 'mtk_hw_reg_idx' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:58: warning: Enum value 'MTK_INST_DECODER' not described in enum 'mtk_instance_type' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:58: warning: Enum value 'MTK_INST_ENCODER' not described in enum 'mtk_instance_type' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:87: warning: Enum value 'MTK_ENCODE_PARAM_NONE' not described in enum 'mtk_encode_param' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:87: warning: Enum value 'MTK_ENCODE_PARAM_BITRATE' not described in enum 'mtk_encode_param' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:87: warning: Enum value 'MTK_ENCODE_PARAM_FRAMERATE' not described in enum 'mtk_encode_param' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:87: warning: Enum value 'MTK_ENCODE_PARAM_INTRA_PERIOD' not described in enum 'mtk_encode_param' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:87: warning: Enum value 'MTK_ENCODE_PARAM_FORCE_INTRA' not described in enum 'mtk_encode_param' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:87: warning: Enum value 'MTK_ENCODE_PARAM_GOP_SIZE' not described in enum 'mtk_encode_param' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:103: warning: Function parameter or member 'fourcc' not described in 'mtk_video_fmt' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:103: warning: Function parameter or member 'type' not described in 'mtk_video_fmt' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:103: warning: Function parameter or member 'num_planes' not described in 'mtk_video_fmt' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:103: warning: Function parameter or member 'flags' not described in 'mtk_video_fmt' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:112: warning: Function parameter or member 'fourcc' not described in 'mtk_codec_framesizes' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:112: warning: Function parameter or member 'stepwise' not described in 'mtk_codec_framesizes' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:120: warning: Enum value 'MTK_Q_DATA_SRC' not described in enum 'mtk_q_type' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:120: warning: Enum value 'MTK_Q_DATA_DST' not described in enum 'mtk_q_type' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:134: warning: Function parameter or member 'visible_width' not described in 'mtk_q_data' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:134: warning: Function parameter or member 'visible_height' not described in 'mtk_q_data' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:134: warning: Function parameter or member 'coded_width' not described in 'mtk_q_data' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:134: warning: Function parameter or member 'coded_height' not described in 'mtk_q_data' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:134: warning: Function parameter or member 'field' not described in 'mtk_q_data' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:134: warning: Function parameter or member 'bytesperline' not described in 'mtk_q_data' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:134: warning: Function parameter or member 'sizeimage' not described in 'mtk_q_data' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:134: warning: Function parameter or member 'fmt' not described in 'mtk_q_data' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:177: warning: Function parameter or member 'clk_name' not described in 'mtk_vcodec_clk_info' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:177: warning: Function parameter or member 'vcodec_clk' not described in 'mtk_vcodec_clk_info' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:185: warning: Function parameter or member 'clk_info' not described in 'mtk_vcodec_clk' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:185: warning: Function parameter or member 'clk_num' not described in 'mtk_vcodec_clk' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:198: warning: Function parameter or member 'vdec_clk' not described in 'mtk_vcodec_pm' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:198: warning: Function parameter or member 'larbvdec' not described in 'mtk_vcodec_pm' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:198: warning: Function parameter or member 'venc_clk' not described in 'mtk_vcodec_pm' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:198: warning: Function parameter or member 'larbvenc' not described in 'mtk_vcodec_pm' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:198: warning: Function parameter or member 'dev' not described in 'mtk_vcodec_pm' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:198: warning: Function parameter or member 'mtkdev' not described in 'mtk_vcodec_pm' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:300: warning: Function parameter or member 'decoded_frame_cnt' not described in 'mtk_vcodec_ctx' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:332: warning: Function parameter or member 'min_bitrate' not described in 'mtk_vcodec_enc_pdata' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:405: warning: Function parameter or member 'venc_pdata' not described in 'mtk_vcodec_dev' drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h:405: warning: Function parameter or member 'decode_workqueue' not described in 'mtk_vcodec_dev' drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h:27: warning: Enum value 'AP_IPIMSG_DEC_INIT' not described in enum 'vdec_ipi_msgid' drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h:27: warning: Enum value 'AP_IPIMSG_DEC_START' not described in enum 'vdec_ipi_msgid' drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h:27: warning: Enum value 'AP_IPIMSG_DEC_END' not described in enum 'vdec_ipi_msgid' drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h:27: warning: Enum value 'AP_IPIMSG_DEC_DEINIT' not described in enum 'vdec_ipi_msgid' drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h:27: warning: Enum value 'AP_IPIMSG_DEC_RESET' not described in enum 'vdec_ipi_msgid' drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h:27: warning: Enum value 'VPU_IPIMSG_DEC_INIT_ACK' not described in enum 'vdec_ipi_msgid' drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h:27: warning: Enum value 'VPU_IPIMSG_DEC_START_ACK' not described in enum 'vdec_ipi_msgid' drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h:27: warning: Enum value 'VPU_IPIMSG_DEC_END_ACK' not described in enum 'vdec_ipi_msgid' drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h:27: warning: Enum value 'VPU_IPIMSG_DEC_DEINIT_ACK' not described in enum 'vdec_ipi_msgid' drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h:27: warning: Enum value 'VPU_IPIMSG_DEC_RESET_ACK' not described in enum 'vdec_ipi_msgid' drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h:27: warning: Excess enum value 'AP_IPIMSG_XXX' description in 'vdec_ipi_msgid' drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h:27: warning: Excess enum value 'VPU_IPIMSG_XXX_ACK' description in 'vdec_ipi_msgid' In some cases I just changed /** to /*, in other cases the missing field descriptions were added. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../platform/mtk-vcodec/mtk_vcodec_drv.h | 25 +++++++++++-------- .../media/platform/mtk-vcodec/vdec_ipi_msg.h | 2 +- .../media/platform/mtk-vcodec/venc_ipi_msg.h | 4 +-- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h index 14893d277bb8..c6c7672fecfb 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h @@ -25,7 +25,7 @@ #define MTK_V4L2_BENCHMARK 0 #define WAIT_INTR_TIMEOUT_MS 1000 -/** +/* * enum mtk_hw_reg_idx - MTK hw register base index */ enum mtk_hw_reg_idx { @@ -49,7 +49,7 @@ enum mtk_hw_reg_idx { NUM_MAX_VCODEC_REG_BASE }; -/** +/* * enum mtk_instance_type - The type of an MTK Vcodec instance. */ enum mtk_instance_type { @@ -74,7 +74,7 @@ enum mtk_instance_state { MTK_STATE_ABORT = 4, }; -/** +/* * enum mtk_encode_param - General encoding parameters type */ enum mtk_encode_param { @@ -92,7 +92,7 @@ enum mtk_fmt_type { MTK_FMT_FRAME = 2, }; -/** +/* * struct mtk_video_fmt - Structure used to store information about pixelformats */ struct mtk_video_fmt { @@ -102,7 +102,7 @@ struct mtk_video_fmt { u32 flags; }; -/** +/* * struct mtk_codec_framesizes - Structure used to store information about * framesizes */ @@ -111,7 +111,7 @@ struct mtk_codec_framesizes { struct v4l2_frmsize_stepwise stepwise; }; -/** +/* * enum mtk_q_type - Type of queue */ enum mtk_q_type { @@ -119,7 +119,7 @@ enum mtk_q_type { MTK_Q_DATA_DST = 1, }; -/** +/* * struct mtk_q_data - Structure used to store information about queue */ struct mtk_q_data { @@ -168,7 +168,7 @@ struct mtk_enc_params { unsigned int force_intra; }; -/** +/* * struct mtk_vcodec_clk_info - Structure used to store clock name */ struct mtk_vcodec_clk_info { @@ -176,7 +176,7 @@ struct mtk_vcodec_clk_info { struct clk *vcodec_clk; }; -/** +/* * struct mtk_vcodec_clk - Structure used to store vcodec clock information */ struct mtk_vcodec_clk { @@ -184,7 +184,7 @@ struct mtk_vcodec_clk { int clk_num; }; -/** +/* * struct mtk_vcodec_pm - Power management data structure */ struct mtk_vcodec_pm { @@ -255,6 +255,7 @@ struct vdec_pic_info { * @ycbcr_enc: enum v4l2_ycbcr_encoding, Y'CbCr encoding * @quantization: enum v4l2_quantization, colorspace quantization * @xfer_func: enum v4l2_xfer_func, colorspace transfer function + * @decoded_frame_cnt: number of decoded frames * @lock: protect variables accessed by V4L2 threads and worker thread such as * mtk_video_dec_buf. */ @@ -311,7 +312,7 @@ enum mtk_chip { * @chip: chip this encoder is compatible with * * @uses_ext: whether the encoder uses the extended firmware messaging format - * @min_birate: minimum supported encoding bitrate + * @min_bitrate: minimum supported encoding bitrate * @max_bitrate: maximum supported encoding bitrate * @capture_formats: array of supported capture formats * @num_capture_formats: number of entries in capture_formats @@ -348,10 +349,12 @@ struct mtk_vcodec_enc_pdata { * @curr_ctx: The context that is waiting for codec hardware * * @reg_base: Mapped address of MTK Vcodec registers. + * @venc_pdata: encoder IC-specific data * * @fw_handler: used to communicate with the firmware. * @id_counter: used to identify current opened instance * + * @decode_workqueue: decode work queue * @encode_workqueue: encode work queue * * @int_cond: used to identify interrupt condition happen diff --git a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h index 47a1c1c0fd04..68e8d5cb16d7 100644 --- a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h +++ b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h @@ -7,7 +7,7 @@ #ifndef _VDEC_IPI_MSG_H_ #define _VDEC_IPI_MSG_H_ -/** +/* * enum vdec_ipi_msgid - message id between AP and VPU * @AP_IPIMSG_XXX : AP to VPU cmd message id * @VPU_IPIMSG_XXX_ACK : VPU ack AP cmd message id diff --git a/drivers/media/platform/mtk-vcodec/venc_ipi_msg.h b/drivers/media/platform/mtk-vcodec/venc_ipi_msg.h index 5f53d4255c36..587a2cf15b76 100644 --- a/drivers/media/platform/mtk-vcodec/venc_ipi_msg.h +++ b/drivers/media/platform/mtk-vcodec/venc_ipi_msg.h @@ -12,7 +12,7 @@ #define AP_IPIMSG_VENC_BASE 0xC000 #define VPU_IPIMSG_VENC_BASE 0xD000 -/** +/* * enum venc_ipi_msg_id - message id between AP and VPU * (ipi stands for inter-processor interrupt) * @AP_IPIMSG_ENC_XXX: AP to VPU cmd message id @@ -111,7 +111,7 @@ struct venc_ap_ipi_msg_deinit { uint32_t vpu_inst_addr; }; -/** +/* * enum venc_ipi_msg_status - VPU ack AP cmd status */ enum venc_ipi_msg_status { From b32178e77d257c148b8ad8c31db36bb0c2d49bab Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Mon, 14 Jun 2021 23:32:10 +0200 Subject: [PATCH 370/394] media: dt-bindings: media: rockchip-vpu: add new compatibles Add compatibles for RK3036, RK3066, RK3188 and RK3228. Also reflect the changes to the additional clocks for RK3066/RK3188. Signed-off-by: Alex Bee Reviewed-by: Rob Herring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../bindings/media/rockchip-vpu.yaml | 33 ++++++++++++++----- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/Documentation/devicetree/bindings/media/rockchip-vpu.yaml b/Documentation/devicetree/bindings/media/rockchip-vpu.yaml index c81dbc3e8960..b88172a59de7 100644 --- a/Documentation/devicetree/bindings/media/rockchip-vpu.yaml +++ b/Documentation/devicetree/bindings/media/rockchip-vpu.yaml @@ -15,10 +15,19 @@ description: properties: compatible: - enum: - - rockchip,rk3288-vpu - - rockchip,rk3328-vpu - - rockchip,rk3399-vpu + oneOf: + - enum: + - rockchip,rk3036-vpu + - rockchip,rk3066-vpu + - rockchip,rk3288-vpu + - rockchip,rk3328-vpu + - rockchip,rk3399-vpu + - items: + - const: rockchip,rk3188-vpu + - const: rockchip,rk3066-vpu + - items: + - const: rockchip,rk3228-vpu + - const: rockchip,rk3399-vpu reg: maxItems: 1 @@ -35,12 +44,20 @@ properties: - const: vdpu clocks: - maxItems: 2 + oneOf: + - maxItems: 2 + - maxItems: 4 clock-names: - items: - - const: aclk - - const: hclk + oneOf: + - items: + - const: aclk + - const: hclk + - items: + - const: aclk_vdpu + - const: hclk_vdpu + - const: aclk_vepu + - const: hclk_vepu power-domains: maxItems: 1 From 502cf736419aba4cfa0a6737cf66d286c699f144 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Mon, 14 Jun 2021 23:32:11 +0200 Subject: [PATCH 371/394] media: dt-bindings: media: rockchip-vdec: add RK3228 compatible Document the RK3228 compatible for rockchip-vdec. Also add the optional assigned-clocks and assigned-clock-rates properties. Signed-off-by: Alex Bee Reviewed-by: Rob Herring Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../devicetree/bindings/media/rockchip,vdec.yaml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/media/rockchip,vdec.yaml b/Documentation/devicetree/bindings/media/rockchip,vdec.yaml index 8d35c327018b..089f11d21b25 100644 --- a/Documentation/devicetree/bindings/media/rockchip,vdec.yaml +++ b/Documentation/devicetree/bindings/media/rockchip,vdec.yaml @@ -15,7 +15,11 @@ description: |- properties: compatible: - const: rockchip,rk3399-vdec + oneOf: + - const: rockchip,rk3399-vdec + - items: + - const: rockchip,rk3228-vdec + - const: rockchip,rk3399-vdec reg: maxItems: 1 @@ -37,6 +41,10 @@ properties: - const: cabac - const: core + assigned-clocks: true + + assigned-clock-rates: true + power-domains: maxItems: 1 From 4b898fedeb26c4d09b83a2c5a3246a34ab99e216 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Mon, 14 Jun 2021 23:32:12 +0200 Subject: [PATCH 372/394] media: hantro: reorder variants Reorder variants in hantro driver alphanumeric. Signed-off-by: Alex Bee Reviewed-by: Ezequiel Garcia Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/hantro/hantro_drv.c | 4 ++-- drivers/staging/media/hantro/hantro_hw.h | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c index dbc69ee0b562..34e778e1cea1 100644 --- a/drivers/staging/media/hantro/hantro_drv.c +++ b/drivers/staging/media/hantro/hantro_drv.c @@ -582,9 +582,9 @@ static const struct v4l2_file_operations hantro_fops = { static const struct of_device_id of_hantro_match[] = { #ifdef CONFIG_VIDEO_HANTRO_ROCKCHIP - { .compatible = "rockchip,rk3399-vpu", .data = &rk3399_vpu_variant, }, - { .compatible = "rockchip,rk3328-vpu", .data = &rk3328_vpu_variant, }, { .compatible = "rockchip,rk3288-vpu", .data = &rk3288_vpu_variant, }, + { .compatible = "rockchip,rk3328-vpu", .data = &rk3328_vpu_variant, }, + { .compatible = "rockchip,rk3399-vpu", .data = &rk3399_vpu_variant, }, #endif #ifdef CONFIG_VIDEO_HANTRO_IMX8M { .compatible = "nxp,imx8mq-vpu", .data = &imx8mq_vpu_variant, }, diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h index 5737a7707944..7fa67d0c7e0f 100644 --- a/drivers/staging/media/hantro/hantro_hw.h +++ b/drivers/staging/media/hantro/hantro_hw.h @@ -203,12 +203,12 @@ enum hantro_enc_fmt { RK3288_VPU_ENC_FMT_UYVY422 = 3, }; -extern const struct hantro_variant rk3399_vpu_variant; -extern const struct hantro_variant rk3328_vpu_variant; -extern const struct hantro_variant rk3288_vpu_variant; -extern const struct hantro_variant imx8mq_vpu_variant; -extern const struct hantro_variant sama5d4_vdec_variant; extern const struct hantro_variant imx8mq_vpu_g2_variant; +extern const struct hantro_variant imx8mq_vpu_variant; +extern const struct hantro_variant rk3288_vpu_variant; +extern const struct hantro_variant rk3328_vpu_variant; +extern const struct hantro_variant rk3399_vpu_variant; +extern const struct hantro_variant sama5d4_vdec_variant; extern const struct hantro_postproc_regs hantro_g1_postproc_regs; From c9caebd57b3a0e3fc981bfc9e79de5c4086e0c1b Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Mon, 14 Jun 2021 23:32:13 +0200 Subject: [PATCH 373/394] media: hantro: merge Rockchip platform drivers Merge the two Rockchip platform drivers into one as it was suggested at [1] and [2]. This will hopefully make it easier to add new variants (which are surely to come for Rockchip). Also rename from "rk3288" to "v(d/e)pu1" and "rk3399" to "v(d/e)pu2" where applicable, as this is the dicition the vendor uses and will also refelect the variants that get added later in this series. Rename from "rk3288" to "rockchip" if applicable to both hardware versions. [1] https://patchwork.kernel.org/project/linux-rockchip/patch/20210107134101.195426-6-paul.kocialkowski@bootlin.com/ [2] https://patchwork.kernel.org/project/linux-rockchip/patch/20210525152225.154302-5-knaerzche@gmail.com/ Signed-off-by: Alex Bee Reviewed-by: Ezequiel Garcia Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/hantro/Makefile | 9 +- drivers/staging/media/hantro/hantro_hw.h | 22 +- drivers/staging/media/hantro/rk3288_vpu_hw.c | 208 ---------- drivers/staging/media/hantro/rk3399_vpu_hw.c | 222 ----------- ...jpeg_enc.c => rockchip_vpu2_hw_jpeg_enc.c} | 30 +- ...eg2_dec.c => rockchip_vpu2_hw_mpeg2_dec.c} | 25 +- ...w_vp8_dec.c => rockchip_vpu2_hw_vp8_dec.c} | 2 +- ...rk3399_vpu_regs.h => rockchip_vpu2_regs.h} | 6 +- .../staging/media/hantro/rockchip_vpu_hw.c | 356 ++++++++++++++++++ 9 files changed, 402 insertions(+), 478 deletions(-) delete mode 100644 drivers/staging/media/hantro/rk3288_vpu_hw.c delete mode 100644 drivers/staging/media/hantro/rk3399_vpu_hw.c rename drivers/staging/media/hantro/{rk3399_vpu_hw_jpeg_enc.c => rockchip_vpu2_hw_jpeg_enc.c} (87%) rename drivers/staging/media/hantro/{rk3399_vpu_hw_mpeg2_dec.c => rockchip_vpu2_hw_mpeg2_dec.c} (94%) rename drivers/staging/media/hantro/{rk3399_vpu_hw_vp8_dec.c => rockchip_vpu2_hw_vp8_dec.c} (99%) rename drivers/staging/media/hantro/{rk3399_vpu_regs.h => rockchip_vpu2_regs.h} (99%) create mode 100644 drivers/staging/media/hantro/rockchip_vpu_hw.c diff --git a/drivers/staging/media/hantro/Makefile b/drivers/staging/media/hantro/Makefile index 23bfc423b23c..287370188d2a 100644 --- a/drivers/staging/media/hantro/Makefile +++ b/drivers/staging/media/hantro/Makefile @@ -12,9 +12,9 @@ hantro-vpu-y += \ hantro_g1_mpeg2_dec.o \ hantro_g2_hevc_dec.o \ hantro_g1_vp8_dec.o \ - rk3399_vpu_hw_jpeg_enc.o \ - rk3399_vpu_hw_mpeg2_dec.o \ - rk3399_vpu_hw_vp8_dec.o \ + rockchip_vpu2_hw_jpeg_enc.o \ + rockchip_vpu2_hw_mpeg2_dec.o \ + rockchip_vpu2_hw_vp8_dec.o \ hantro_jpeg.o \ hantro_h264.o \ hantro_hevc.o \ @@ -28,5 +28,4 @@ hantro-vpu-$(CONFIG_VIDEO_HANTRO_SAMA5D4) += \ sama5d4_vdec_hw.o hantro-vpu-$(CONFIG_VIDEO_HANTRO_ROCKCHIP) += \ - rk3288_vpu_hw.o \ - rk3399_vpu_hw.o + rockchip_vpu_hw.o diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h index 7fa67d0c7e0f..a7b75b05e849 100644 --- a/drivers/staging/media/hantro/hantro_hw.h +++ b/drivers/staging/media/hantro/hantro_hw.h @@ -191,16 +191,16 @@ struct hantro_codec_ops { /** * enum hantro_enc_fmt - source format ID for hardware registers. * - * @RK3288_VPU_ENC_FMT_YUV420P: Y/CbCr 4:2:0 planar format - * @RK3288_VPU_ENC_FMT_YUV420SP: Y/CbCr 4:2:0 semi-planar format - * @RK3288_VPU_ENC_FMT_YUYV422: YUV 4:2:2 packed format (YUYV) - * @RK3288_VPU_ENC_FMT_UYVY422: YUV 4:2:2 packed format (UYVY) + * @ROCKCHIP_VPU_ENC_FMT_YUV420P: Y/CbCr 4:2:0 planar format + * @ROCKCHIP_VPU_ENC_FMT_YUV420SP: Y/CbCr 4:2:0 semi-planar format + * @ROCKCHIP_VPU_ENC_FMT_YUYV422: YUV 4:2:2 packed format (YUYV) + * @ROCKCHIP_VPU_ENC_FMT_UYVY422: YUV 4:2:2 packed format (UYVY) */ enum hantro_enc_fmt { - RK3288_VPU_ENC_FMT_YUV420P = 0, - RK3288_VPU_ENC_FMT_YUV420SP = 1, - RK3288_VPU_ENC_FMT_YUYV422 = 2, - RK3288_VPU_ENC_FMT_UYVY422 = 3, + ROCKCHIP_VPU_ENC_FMT_YUV420P = 0, + ROCKCHIP_VPU_ENC_FMT_YUV420SP = 1, + ROCKCHIP_VPU_ENC_FMT_YUYV422 = 2, + ROCKCHIP_VPU_ENC_FMT_UYVY422 = 3, }; extern const struct hantro_variant imx8mq_vpu_g2_variant; @@ -225,7 +225,7 @@ irqreturn_t hantro_g1_irq(int irq, void *dev_id); void hantro_g1_reset(struct hantro_ctx *ctx); int hantro_h1_jpeg_enc_run(struct hantro_ctx *ctx); -int rk3399_vpu_jpeg_enc_run(struct hantro_ctx *ctx); +int rockchip_vpu2_jpeg_enc_run(struct hantro_ctx *ctx); int hantro_jpeg_enc_init(struct hantro_ctx *ctx); void hantro_jpeg_enc_exit(struct hantro_ctx *ctx); void hantro_jpeg_enc_done(struct hantro_ctx *ctx); @@ -274,14 +274,14 @@ hantro_h264_mv_size(unsigned int width, unsigned int height) } int hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx); -int rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx); +int rockchip_vpu2_mpeg2_dec_run(struct hantro_ctx *ctx); void hantro_mpeg2_dec_copy_qtable(u8 *qtable, const struct v4l2_ctrl_mpeg2_quantisation *ctrl); int hantro_mpeg2_dec_init(struct hantro_ctx *ctx); void hantro_mpeg2_dec_exit(struct hantro_ctx *ctx); int hantro_g1_vp8_dec_run(struct hantro_ctx *ctx); -int rk3399_vpu_vp8_dec_run(struct hantro_ctx *ctx); +int rockchip_vpu2_vp8_dec_run(struct hantro_ctx *ctx); int hantro_vp8_dec_init(struct hantro_ctx *ctx); void hantro_vp8_dec_exit(struct hantro_ctx *ctx); void hantro_vp8_prob_update(struct hantro_ctx *ctx, diff --git a/drivers/staging/media/hantro/rk3288_vpu_hw.c b/drivers/staging/media/hantro/rk3288_vpu_hw.c deleted file mode 100644 index fefd45269e52..000000000000 --- a/drivers/staging/media/hantro/rk3288_vpu_hw.c +++ /dev/null @@ -1,208 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Hantro VPU codec driver - * - * Copyright (C) 2018 Rockchip Electronics Co., Ltd. - * Jeffy Chen - */ - -#include - -#include "hantro.h" -#include "hantro_jpeg.h" -#include "hantro_h1_regs.h" - -#define RK3288_ACLK_MAX_FREQ (400 * 1000 * 1000) - -/* - * Supported formats. - */ - -static const struct hantro_fmt rk3288_vpu_enc_fmts[] = { - { - .fourcc = V4L2_PIX_FMT_YUV420M, - .codec_mode = HANTRO_MODE_NONE, - .enc_fmt = RK3288_VPU_ENC_FMT_YUV420P, - }, - { - .fourcc = V4L2_PIX_FMT_NV12M, - .codec_mode = HANTRO_MODE_NONE, - .enc_fmt = RK3288_VPU_ENC_FMT_YUV420SP, - }, - { - .fourcc = V4L2_PIX_FMT_YUYV, - .codec_mode = HANTRO_MODE_NONE, - .enc_fmt = RK3288_VPU_ENC_FMT_YUYV422, - }, - { - .fourcc = V4L2_PIX_FMT_UYVY, - .codec_mode = HANTRO_MODE_NONE, - .enc_fmt = RK3288_VPU_ENC_FMT_UYVY422, - }, - { - .fourcc = V4L2_PIX_FMT_JPEG, - .codec_mode = HANTRO_MODE_JPEG_ENC, - .max_depth = 2, - .header_size = JPEG_HEADER_SIZE, - .frmsize = { - .min_width = 96, - .max_width = 8192, - .step_width = MB_DIM, - .min_height = 32, - .max_height = 8192, - .step_height = MB_DIM, - }, - }, -}; - -static const struct hantro_fmt rk3288_vpu_postproc_fmts[] = { - { - .fourcc = V4L2_PIX_FMT_YUYV, - .codec_mode = HANTRO_MODE_NONE, - }, -}; - -static const struct hantro_fmt rk3288_vpu_dec_fmts[] = { - { - .fourcc = V4L2_PIX_FMT_NV12, - .codec_mode = HANTRO_MODE_NONE, - }, - { - .fourcc = V4L2_PIX_FMT_H264_SLICE, - .codec_mode = HANTRO_MODE_H264_DEC, - .max_depth = 2, - .frmsize = { - .min_width = 48, - .max_width = 4096, - .step_width = MB_DIM, - .min_height = 48, - .max_height = 2304, - .step_height = MB_DIM, - }, - }, - { - .fourcc = V4L2_PIX_FMT_MPEG2_SLICE, - .codec_mode = HANTRO_MODE_MPEG2_DEC, - .max_depth = 2, - .frmsize = { - .min_width = 48, - .max_width = 1920, - .step_width = MB_DIM, - .min_height = 48, - .max_height = 1088, - .step_height = MB_DIM, - }, - }, - { - .fourcc = V4L2_PIX_FMT_VP8_FRAME, - .codec_mode = HANTRO_MODE_VP8_DEC, - .max_depth = 2, - .frmsize = { - .min_width = 48, - .max_width = 3840, - .step_width = MB_DIM, - .min_height = 48, - .max_height = 2160, - .step_height = MB_DIM, - }, - }, -}; - -static irqreturn_t rk3288_vepu_irq(int irq, void *dev_id) -{ - struct hantro_dev *vpu = dev_id; - enum vb2_buffer_state state; - u32 status; - - status = vepu_read(vpu, H1_REG_INTERRUPT); - state = (status & H1_REG_INTERRUPT_FRAME_RDY) ? - VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR; - - vepu_write(vpu, 0, H1_REG_INTERRUPT); - vepu_write(vpu, 0, H1_REG_AXI_CTRL); - - hantro_irq_done(vpu, state); - - return IRQ_HANDLED; -} - -static int rk3288_vpu_hw_init(struct hantro_dev *vpu) -{ - /* Bump ACLK to max. possible freq. to improve performance. */ - clk_set_rate(vpu->clocks[0].clk, RK3288_ACLK_MAX_FREQ); - return 0; -} - -static void rk3288_vpu_enc_reset(struct hantro_ctx *ctx) -{ - struct hantro_dev *vpu = ctx->dev; - - vepu_write(vpu, H1_REG_INTERRUPT_DIS_BIT, H1_REG_INTERRUPT); - vepu_write(vpu, 0, H1_REG_ENC_CTRL); - vepu_write(vpu, 0, H1_REG_AXI_CTRL); -} - -/* - * Supported codec ops. - */ - -static const struct hantro_codec_ops rk3288_vpu_codec_ops[] = { - [HANTRO_MODE_JPEG_ENC] = { - .run = hantro_h1_jpeg_enc_run, - .reset = rk3288_vpu_enc_reset, - .init = hantro_jpeg_enc_init, - .done = hantro_jpeg_enc_done, - .exit = hantro_jpeg_enc_exit, - }, - [HANTRO_MODE_H264_DEC] = { - .run = hantro_g1_h264_dec_run, - .reset = hantro_g1_reset, - .init = hantro_h264_dec_init, - .exit = hantro_h264_dec_exit, - }, - [HANTRO_MODE_MPEG2_DEC] = { - .run = hantro_g1_mpeg2_dec_run, - .reset = hantro_g1_reset, - .init = hantro_mpeg2_dec_init, - .exit = hantro_mpeg2_dec_exit, - }, - [HANTRO_MODE_VP8_DEC] = { - .run = hantro_g1_vp8_dec_run, - .reset = hantro_g1_reset, - .init = hantro_vp8_dec_init, - .exit = hantro_vp8_dec_exit, - }, -}; - -/* - * VPU variant. - */ - -static const struct hantro_irq rk3288_irqs[] = { - { "vepu", rk3288_vepu_irq }, - { "vdpu", hantro_g1_irq }, -}; - -static const char * const rk3288_clk_names[] = { - "aclk", "hclk" -}; - -const struct hantro_variant rk3288_vpu_variant = { - .enc_offset = 0x0, - .enc_fmts = rk3288_vpu_enc_fmts, - .num_enc_fmts = ARRAY_SIZE(rk3288_vpu_enc_fmts), - .dec_offset = 0x400, - .dec_fmts = rk3288_vpu_dec_fmts, - .num_dec_fmts = ARRAY_SIZE(rk3288_vpu_dec_fmts), - .postproc_fmts = rk3288_vpu_postproc_fmts, - .num_postproc_fmts = ARRAY_SIZE(rk3288_vpu_postproc_fmts), - .postproc_regs = &hantro_g1_postproc_regs, - .codec = HANTRO_JPEG_ENCODER | HANTRO_MPEG2_DECODER | - HANTRO_VP8_DECODER | HANTRO_H264_DECODER, - .codec_ops = rk3288_vpu_codec_ops, - .irqs = rk3288_irqs, - .num_irqs = ARRAY_SIZE(rk3288_irqs), - .init = rk3288_vpu_hw_init, - .clk_names = rk3288_clk_names, - .num_clocks = ARRAY_SIZE(rk3288_clk_names) -}; diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw.c b/drivers/staging/media/hantro/rk3399_vpu_hw.c deleted file mode 100644 index 7a7962cf771e..000000000000 --- a/drivers/staging/media/hantro/rk3399_vpu_hw.c +++ /dev/null @@ -1,222 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Hantro VPU codec driver - * - * Copyright (C) 2018 Rockchip Electronics Co., Ltd. - * Jeffy Chen - */ - -#include - -#include "hantro.h" -#include "hantro_jpeg.h" -#include "rk3399_vpu_regs.h" - -#define RK3399_ACLK_MAX_FREQ (400 * 1000 * 1000) - -/* - * Supported formats. - */ - -static const struct hantro_fmt rk3399_vpu_enc_fmts[] = { - { - .fourcc = V4L2_PIX_FMT_YUV420M, - .codec_mode = HANTRO_MODE_NONE, - .enc_fmt = RK3288_VPU_ENC_FMT_YUV420P, - }, - { - .fourcc = V4L2_PIX_FMT_NV12M, - .codec_mode = HANTRO_MODE_NONE, - .enc_fmt = RK3288_VPU_ENC_FMT_YUV420SP, - }, - { - .fourcc = V4L2_PIX_FMT_YUYV, - .codec_mode = HANTRO_MODE_NONE, - .enc_fmt = RK3288_VPU_ENC_FMT_YUYV422, - }, - { - .fourcc = V4L2_PIX_FMT_UYVY, - .codec_mode = HANTRO_MODE_NONE, - .enc_fmt = RK3288_VPU_ENC_FMT_UYVY422, - }, - { - .fourcc = V4L2_PIX_FMT_JPEG, - .codec_mode = HANTRO_MODE_JPEG_ENC, - .max_depth = 2, - .header_size = JPEG_HEADER_SIZE, - .frmsize = { - .min_width = 96, - .max_width = 8192, - .step_width = MB_DIM, - .min_height = 32, - .max_height = 8192, - .step_height = MB_DIM, - }, - }, -}; - -static const struct hantro_fmt rk3399_vpu_dec_fmts[] = { - { - .fourcc = V4L2_PIX_FMT_NV12, - .codec_mode = HANTRO_MODE_NONE, - }, - { - .fourcc = V4L2_PIX_FMT_MPEG2_SLICE, - .codec_mode = HANTRO_MODE_MPEG2_DEC, - .max_depth = 2, - .frmsize = { - .min_width = 48, - .max_width = 1920, - .step_width = MB_DIM, - .min_height = 48, - .max_height = 1088, - .step_height = MB_DIM, - }, - }, - { - .fourcc = V4L2_PIX_FMT_VP8_FRAME, - .codec_mode = HANTRO_MODE_VP8_DEC, - .max_depth = 2, - .frmsize = { - .min_width = 48, - .max_width = 3840, - .step_width = MB_DIM, - .min_height = 48, - .max_height = 2160, - .step_height = MB_DIM, - }, - }, -}; - -static irqreturn_t rk3399_vepu_irq(int irq, void *dev_id) -{ - struct hantro_dev *vpu = dev_id; - enum vb2_buffer_state state; - u32 status; - - status = vepu_read(vpu, VEPU_REG_INTERRUPT); - state = (status & VEPU_REG_INTERRUPT_FRAME_READY) ? - VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR; - - vepu_write(vpu, 0, VEPU_REG_INTERRUPT); - vepu_write(vpu, 0, VEPU_REG_AXI_CTRL); - - hantro_irq_done(vpu, state); - - return IRQ_HANDLED; -} - -static irqreturn_t rk3399_vdpu_irq(int irq, void *dev_id) -{ - struct hantro_dev *vpu = dev_id; - enum vb2_buffer_state state; - u32 status; - - status = vdpu_read(vpu, VDPU_REG_INTERRUPT); - state = (status & VDPU_REG_INTERRUPT_DEC_IRQ) ? - VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR; - - vdpu_write(vpu, 0, VDPU_REG_INTERRUPT); - vdpu_write(vpu, 0, VDPU_REG_AXI_CTRL); - - hantro_irq_done(vpu, state); - - return IRQ_HANDLED; -} - -static int rk3399_vpu_hw_init(struct hantro_dev *vpu) -{ - /* Bump ACLK to max. possible freq. to improve performance. */ - clk_set_rate(vpu->clocks[0].clk, RK3399_ACLK_MAX_FREQ); - return 0; -} - -static void rk3399_vpu_enc_reset(struct hantro_ctx *ctx) -{ - struct hantro_dev *vpu = ctx->dev; - - vepu_write(vpu, VEPU_REG_INTERRUPT_DIS_BIT, VEPU_REG_INTERRUPT); - vepu_write(vpu, 0, VEPU_REG_ENCODE_START); - vepu_write(vpu, 0, VEPU_REG_AXI_CTRL); -} - -static void rk3399_vpu_dec_reset(struct hantro_ctx *ctx) -{ - struct hantro_dev *vpu = ctx->dev; - - vdpu_write(vpu, VDPU_REG_INTERRUPT_DEC_IRQ_DIS, VDPU_REG_INTERRUPT); - vdpu_write(vpu, 0, VDPU_REG_EN_FLAGS); - vdpu_write(vpu, 1, VDPU_REG_SOFT_RESET); -} - -/* - * Supported codec ops. - */ - -static const struct hantro_codec_ops rk3399_vpu_codec_ops[] = { - [HANTRO_MODE_JPEG_ENC] = { - .run = rk3399_vpu_jpeg_enc_run, - .reset = rk3399_vpu_enc_reset, - .init = hantro_jpeg_enc_init, - .exit = hantro_jpeg_enc_exit, - }, - [HANTRO_MODE_MPEG2_DEC] = { - .run = rk3399_vpu_mpeg2_dec_run, - .reset = rk3399_vpu_dec_reset, - .init = hantro_mpeg2_dec_init, - .exit = hantro_mpeg2_dec_exit, - }, - [HANTRO_MODE_VP8_DEC] = { - .run = rk3399_vpu_vp8_dec_run, - .reset = rk3399_vpu_dec_reset, - .init = hantro_vp8_dec_init, - .exit = hantro_vp8_dec_exit, - }, -}; - -/* - * VPU variant. - */ - -static const struct hantro_irq rk3399_irqs[] = { - { "vepu", rk3399_vepu_irq }, - { "vdpu", rk3399_vdpu_irq }, -}; - -static const char * const rk3399_clk_names[] = { - "aclk", "hclk" -}; - -const struct hantro_variant rk3399_vpu_variant = { - .enc_offset = 0x0, - .enc_fmts = rk3399_vpu_enc_fmts, - .num_enc_fmts = ARRAY_SIZE(rk3399_vpu_enc_fmts), - .dec_offset = 0x400, - .dec_fmts = rk3399_vpu_dec_fmts, - .num_dec_fmts = ARRAY_SIZE(rk3399_vpu_dec_fmts), - .codec = HANTRO_JPEG_ENCODER | HANTRO_MPEG2_DECODER | - HANTRO_VP8_DECODER, - .codec_ops = rk3399_vpu_codec_ops, - .irqs = rk3399_irqs, - .num_irqs = ARRAY_SIZE(rk3399_irqs), - .init = rk3399_vpu_hw_init, - .clk_names = rk3399_clk_names, - .num_clocks = ARRAY_SIZE(rk3399_clk_names) -}; - -static const struct hantro_irq rk3328_irqs[] = { - { "vdpu", rk3399_vdpu_irq }, -}; - -const struct hantro_variant rk3328_vpu_variant = { - .dec_offset = 0x400, - .dec_fmts = rk3399_vpu_dec_fmts, - .num_dec_fmts = ARRAY_SIZE(rk3399_vpu_dec_fmts), - .codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER, - .codec_ops = rk3399_vpu_codec_ops, - .irqs = rk3328_irqs, - .num_irqs = ARRAY_SIZE(rk3328_irqs), - .init = rk3399_vpu_hw_init, - .clk_names = rk3399_clk_names, - .num_clocks = ARRAY_SIZE(rk3399_clk_names), -}; diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_jpeg_enc.c b/drivers/staging/media/hantro/rockchip_vpu2_hw_jpeg_enc.c similarity index 87% rename from drivers/staging/media/hantro/rk3399_vpu_hw_jpeg_enc.c rename to drivers/staging/media/hantro/rockchip_vpu2_hw_jpeg_enc.c index 3a27ebef4f38..991213ce1610 100644 --- a/drivers/staging/media/hantro/rk3399_vpu_hw_jpeg_enc.c +++ b/drivers/staging/media/hantro/rockchip_vpu2_hw_jpeg_enc.c @@ -28,12 +28,12 @@ #include "hantro.h" #include "hantro_v4l2.h" #include "hantro_hw.h" -#include "rk3399_vpu_regs.h" +#include "rockchip_vpu2_regs.h" #define VEPU_JPEG_QUANT_TABLE_COUNT 16 -static void rk3399_vpu_set_src_img_ctrl(struct hantro_dev *vpu, - struct hantro_ctx *ctx) +static void rockchip_vpu2_set_src_img_ctrl(struct hantro_dev *vpu, + struct hantro_ctx *ctx) { struct v4l2_pix_format_mplane *pix_fmt = &ctx->src_fmt; u32 reg; @@ -59,9 +59,9 @@ static void rk3399_vpu_set_src_img_ctrl(struct hantro_dev *vpu, vepu_write_relaxed(vpu, reg, VEPU_REG_ENC_CTRL1); } -static void rk3399_vpu_jpeg_enc_set_buffers(struct hantro_dev *vpu, - struct hantro_ctx *ctx, - struct vb2_buffer *src_buf) +static void rockchip_vpu2_jpeg_enc_set_buffers(struct hantro_dev *vpu, + struct hantro_ctx *ctx, + struct vb2_buffer *src_buf) { struct v4l2_pix_format_mplane *pix_fmt = &ctx->src_fmt; dma_addr_t src[3]; @@ -92,9 +92,9 @@ static void rk3399_vpu_jpeg_enc_set_buffers(struct hantro_dev *vpu, } static void -rk3399_vpu_jpeg_enc_set_qtable(struct hantro_dev *vpu, - unsigned char *luma_qtable, - unsigned char *chroma_qtable) +rockchip_vpu2_jpeg_enc_set_qtable(struct hantro_dev *vpu, + unsigned char *luma_qtable, + unsigned char *chroma_qtable) { u32 reg, i; __be32 *luma_qtable_p; @@ -118,7 +118,7 @@ rk3399_vpu_jpeg_enc_set_qtable(struct hantro_dev *vpu, } } -int rk3399_vpu_jpeg_enc_run(struct hantro_ctx *ctx) +int rockchip_vpu2_jpeg_enc_run(struct hantro_ctx *ctx) { struct hantro_dev *vpu = ctx->dev; struct vb2_v4l2_buffer *src_buf, *dst_buf; @@ -141,11 +141,11 @@ int rk3399_vpu_jpeg_enc_run(struct hantro_ctx *ctx) vepu_write_relaxed(vpu, VEPU_REG_ENCODE_FORMAT_JPEG, VEPU_REG_ENCODE_START); - rk3399_vpu_set_src_img_ctrl(vpu, ctx); - rk3399_vpu_jpeg_enc_set_buffers(vpu, ctx, &src_buf->vb2_buf); - rk3399_vpu_jpeg_enc_set_qtable(vpu, - hantro_jpeg_get_qtable(0), - hantro_jpeg_get_qtable(1)); + rockchip_vpu2_set_src_img_ctrl(vpu, ctx); + rockchip_vpu2_jpeg_enc_set_buffers(vpu, ctx, &src_buf->vb2_buf); + rockchip_vpu2_jpeg_enc_set_qtable(vpu, + hantro_jpeg_get_qtable(0), + hantro_jpeg_get_qtable(1)); reg = VEPU_REG_OUTPUT_SWAP32 | VEPU_REG_OUTPUT_SWAP16 diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c b/drivers/staging/media/hantro/rockchip_vpu2_hw_mpeg2_dec.c similarity index 94% rename from drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c rename to drivers/staging/media/hantro/rockchip_vpu2_hw_mpeg2_dec.c index 683982c24c2d..b66737fab46b 100644 --- a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c +++ b/drivers/staging/media/hantro/rockchip_vpu2_hw_mpeg2_dec.c @@ -80,8 +80,8 @@ #define VDPU_REG_MV_ACCURACY_BWD(v) ((v) ? BIT(1) : 0) static void -rk3399_vpu_mpeg2_dec_set_quantisation(struct hantro_dev *vpu, - struct hantro_ctx *ctx) +rockchip_vpu2_mpeg2_dec_set_quantisation(struct hantro_dev *vpu, + struct hantro_ctx *ctx) { struct v4l2_ctrl_mpeg2_quantisation *q; @@ -91,12 +91,12 @@ rk3399_vpu_mpeg2_dec_set_quantisation(struct hantro_dev *vpu, } static void -rk3399_vpu_mpeg2_dec_set_buffers(struct hantro_dev *vpu, - struct hantro_ctx *ctx, - struct vb2_buffer *src_buf, - struct vb2_buffer *dst_buf, - const struct v4l2_ctrl_mpeg2_sequence *seq, - const struct v4l2_ctrl_mpeg2_picture *pic) +rockchip_vpu2_mpeg2_dec_set_buffers(struct hantro_dev *vpu, + struct hantro_ctx *ctx, + struct vb2_buffer *src_buf, + struct vb2_buffer *dst_buf, + const struct v4l2_ctrl_mpeg2_sequence *seq, + const struct v4l2_ctrl_mpeg2_picture *pic) { dma_addr_t forward_addr = 0, backward_addr = 0; dma_addr_t current_addr, addr; @@ -148,7 +148,7 @@ rk3399_vpu_mpeg2_dec_set_buffers(struct hantro_dev *vpu, vdpu_write_relaxed(vpu, backward_addr, VDPU_REG_REFER3_BASE); } -int rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx) +int rockchip_vpu2_mpeg2_dec_run(struct hantro_ctx *ctx) { struct hantro_dev *vpu = ctx->dev; struct vb2_v4l2_buffer *src_buf, *dst_buf; @@ -233,11 +233,10 @@ int rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx) VDPU_REG_MV_ACCURACY_BWD(1); vdpu_write_relaxed(vpu, reg, VDPU_SWREG(136)); - rk3399_vpu_mpeg2_dec_set_quantisation(vpu, ctx); + rockchip_vpu2_mpeg2_dec_set_quantisation(vpu, ctx); - rk3399_vpu_mpeg2_dec_set_buffers(vpu, ctx, &src_buf->vb2_buf, - &dst_buf->vb2_buf, - seq, pic); + rockchip_vpu2_mpeg2_dec_set_buffers(vpu, ctx, &src_buf->vb2_buf, + &dst_buf->vb2_buf, seq, pic); /* Kick the watchdog and start decoding */ hantro_end_prepare_run(ctx); diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_vp8_dec.c b/drivers/staging/media/hantro/rockchip_vpu2_hw_vp8_dec.c similarity index 99% rename from drivers/staging/media/hantro/rk3399_vpu_hw_vp8_dec.c rename to drivers/staging/media/hantro/rockchip_vpu2_hw_vp8_dec.c index e5d20fe5b007..951b55f58a61 100644 --- a/drivers/staging/media/hantro/rk3399_vpu_hw_vp8_dec.c +++ b/drivers/staging/media/hantro/rockchip_vpu2_hw_vp8_dec.c @@ -503,7 +503,7 @@ static void cfg_buffers(struct hantro_ctx *ctx, vdpu_write_relaxed(vpu, dst_dma, VDPU_REG_ADDR_DST); } -int rk3399_vpu_vp8_dec_run(struct hantro_ctx *ctx) +int rockchip_vpu2_vp8_dec_run(struct hantro_ctx *ctx) { const struct v4l2_ctrl_vp8_frame *hdr; struct hantro_dev *vpu = ctx->dev; diff --git a/drivers/staging/media/hantro/rk3399_vpu_regs.h b/drivers/staging/media/hantro/rockchip_vpu2_regs.h similarity index 99% rename from drivers/staging/media/hantro/rk3399_vpu_regs.h rename to drivers/staging/media/hantro/rockchip_vpu2_regs.h index 88d096920f30..49e40889545b 100644 --- a/drivers/staging/media/hantro/rk3399_vpu_regs.h +++ b/drivers/staging/media/hantro/rockchip_vpu2_regs.h @@ -6,8 +6,8 @@ * Alpha Lin */ -#ifndef RK3399_VPU_REGS_H_ -#define RK3399_VPU_REGS_H_ +#ifndef ROCKCHIP_VPU2_REGS_H_ +#define ROCKCHIP_VPU2_REGS_H_ /* Encoder registers. */ #define VEPU_REG_VP8_QUT_1ST(i) (0x000 + ((i) * 0x24)) @@ -597,4 +597,4 @@ #define VDPU_REG_PRED_FLT_PRED_BC_TAP_4_3(x) (((x) & 0x3ff) << 12) #define VDPU_REG_PRED_FLT_PRED_BC_TAP_5_0(x) (((x) & 0x3ff) << 2) -#endif /* RK3399_VPU_REGS_H_ */ +#endif /* ROCKCHIP_VPU2_REGS_H_ */ diff --git a/drivers/staging/media/hantro/rockchip_vpu_hw.c b/drivers/staging/media/hantro/rockchip_vpu_hw.c new file mode 100644 index 000000000000..bf760e8e65ce --- /dev/null +++ b/drivers/staging/media/hantro/rockchip_vpu_hw.c @@ -0,0 +1,356 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Hantro VPU codec driver + * + * Copyright (C) 2018 Rockchip Electronics Co., Ltd. + * Jeffy Chen + */ + +#include + +#include "hantro.h" +#include "hantro_jpeg.h" +#include "hantro_h1_regs.h" +#include "rockchip_vpu2_regs.h" + +#define RK3288_ACLK_MAX_FREQ (400 * 1000 * 1000) + +/* + * Supported formats. + */ + +static const struct hantro_fmt rockchip_vpu_enc_fmts[] = { + { + .fourcc = V4L2_PIX_FMT_YUV420M, + .codec_mode = HANTRO_MODE_NONE, + .enc_fmt = ROCKCHIP_VPU_ENC_FMT_YUV420P, + }, + { + .fourcc = V4L2_PIX_FMT_NV12M, + .codec_mode = HANTRO_MODE_NONE, + .enc_fmt = ROCKCHIP_VPU_ENC_FMT_YUV420SP, + }, + { + .fourcc = V4L2_PIX_FMT_YUYV, + .codec_mode = HANTRO_MODE_NONE, + .enc_fmt = ROCKCHIP_VPU_ENC_FMT_YUYV422, + }, + { + .fourcc = V4L2_PIX_FMT_UYVY, + .codec_mode = HANTRO_MODE_NONE, + .enc_fmt = ROCKCHIP_VPU_ENC_FMT_UYVY422, + }, + { + .fourcc = V4L2_PIX_FMT_JPEG, + .codec_mode = HANTRO_MODE_JPEG_ENC, + .max_depth = 2, + .header_size = JPEG_HEADER_SIZE, + .frmsize = { + .min_width = 96, + .max_width = 8192, + .step_width = MB_DIM, + .min_height = 32, + .max_height = 8192, + .step_height = MB_DIM, + }, + }, +}; + +static const struct hantro_fmt rockchip_vpu1_postproc_fmts[] = { + { + .fourcc = V4L2_PIX_FMT_YUYV, + .codec_mode = HANTRO_MODE_NONE, + }, +}; + +static const struct hantro_fmt rk3288_vpu_dec_fmts[] = { + { + .fourcc = V4L2_PIX_FMT_NV12, + .codec_mode = HANTRO_MODE_NONE, + }, + { + .fourcc = V4L2_PIX_FMT_H264_SLICE, + .codec_mode = HANTRO_MODE_H264_DEC, + .max_depth = 2, + .frmsize = { + .min_width = 48, + .max_width = 4096, + .step_width = MB_DIM, + .min_height = 48, + .max_height = 2304, + .step_height = MB_DIM, + }, + }, + { + .fourcc = V4L2_PIX_FMT_MPEG2_SLICE, + .codec_mode = HANTRO_MODE_MPEG2_DEC, + .max_depth = 2, + .frmsize = { + .min_width = 48, + .max_width = 1920, + .step_width = MB_DIM, + .min_height = 48, + .max_height = 1088, + .step_height = MB_DIM, + }, + }, + { + .fourcc = V4L2_PIX_FMT_VP8_FRAME, + .codec_mode = HANTRO_MODE_VP8_DEC, + .max_depth = 2, + .frmsize = { + .min_width = 48, + .max_width = 3840, + .step_width = MB_DIM, + .min_height = 48, + .max_height = 2160, + .step_height = MB_DIM, + }, + }, +}; + +static const struct hantro_fmt rk3399_vpu_dec_fmts[] = { + { + .fourcc = V4L2_PIX_FMT_NV12, + .codec_mode = HANTRO_MODE_NONE, + }, + { + .fourcc = V4L2_PIX_FMT_MPEG2_SLICE, + .codec_mode = HANTRO_MODE_MPEG2_DEC, + .max_depth = 2, + .frmsize = { + .min_width = 48, + .max_width = 1920, + .step_width = MB_DIM, + .min_height = 48, + .max_height = 1088, + .step_height = MB_DIM, + }, + }, + { + .fourcc = V4L2_PIX_FMT_VP8_FRAME, + .codec_mode = HANTRO_MODE_VP8_DEC, + .max_depth = 2, + .frmsize = { + .min_width = 48, + .max_width = 3840, + .step_width = MB_DIM, + .min_height = 48, + .max_height = 2160, + .step_height = MB_DIM, + }, + }, +}; + +static irqreturn_t rockchip_vpu1_vepu_irq(int irq, void *dev_id) +{ + struct hantro_dev *vpu = dev_id; + enum vb2_buffer_state state; + u32 status; + + status = vepu_read(vpu, H1_REG_INTERRUPT); + state = (status & H1_REG_INTERRUPT_FRAME_RDY) ? + VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR; + + vepu_write(vpu, 0, H1_REG_INTERRUPT); + vepu_write(vpu, 0, H1_REG_AXI_CTRL); + + hantro_irq_done(vpu, state); + + return IRQ_HANDLED; +} + +static irqreturn_t rockchip_vpu2_vdpu_irq(int irq, void *dev_id) +{ + struct hantro_dev *vpu = dev_id; + enum vb2_buffer_state state; + u32 status; + + status = vdpu_read(vpu, VDPU_REG_INTERRUPT); + state = (status & VDPU_REG_INTERRUPT_DEC_IRQ) ? + VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR; + + vdpu_write(vpu, 0, VDPU_REG_INTERRUPT); + vdpu_write(vpu, 0, VDPU_REG_AXI_CTRL); + + hantro_irq_done(vpu, state); + + return IRQ_HANDLED; +} + +static irqreturn_t rockchip_vpu2_vepu_irq(int irq, void *dev_id) +{ + struct hantro_dev *vpu = dev_id; + enum vb2_buffer_state state; + u32 status; + + status = vepu_read(vpu, VEPU_REG_INTERRUPT); + state = (status & VEPU_REG_INTERRUPT_FRAME_READY) ? + VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR; + + vepu_write(vpu, 0, VEPU_REG_INTERRUPT); + vepu_write(vpu, 0, VEPU_REG_AXI_CTRL); + + hantro_irq_done(vpu, state); + + return IRQ_HANDLED; +} + +static int rockchip_vpu_hw_init(struct hantro_dev *vpu) +{ + /* Bump ACLK to max. possible freq. to improve performance. */ + clk_set_rate(vpu->clocks[0].clk, RK3288_ACLK_MAX_FREQ); + return 0; +} + +static void rockchip_vpu1_enc_reset(struct hantro_ctx *ctx) +{ + struct hantro_dev *vpu = ctx->dev; + + vepu_write(vpu, H1_REG_INTERRUPT_DIS_BIT, H1_REG_INTERRUPT); + vepu_write(vpu, 0, H1_REG_ENC_CTRL); + vepu_write(vpu, 0, H1_REG_AXI_CTRL); +} + +static void rockchip_vpu2_dec_reset(struct hantro_ctx *ctx) +{ + struct hantro_dev *vpu = ctx->dev; + + vdpu_write(vpu, VDPU_REG_INTERRUPT_DEC_IRQ_DIS, VDPU_REG_INTERRUPT); + vdpu_write(vpu, 0, VDPU_REG_EN_FLAGS); + vdpu_write(vpu, 1, VDPU_REG_SOFT_RESET); +} + +static void rockchip_vpu2_enc_reset(struct hantro_ctx *ctx) +{ + struct hantro_dev *vpu = ctx->dev; + + vepu_write(vpu, VEPU_REG_INTERRUPT_DIS_BIT, VEPU_REG_INTERRUPT); + vepu_write(vpu, 0, VEPU_REG_ENCODE_START); + vepu_write(vpu, 0, VEPU_REG_AXI_CTRL); +} + +/* + * Supported codec ops. + */ + +static const struct hantro_codec_ops rk3288_vpu_codec_ops[] = { + [HANTRO_MODE_JPEG_ENC] = { + .run = hantro_h1_jpeg_enc_run, + .reset = rockchip_vpu1_enc_reset, + .init = hantro_jpeg_enc_init, + .done = hantro_jpeg_enc_done, + .exit = hantro_jpeg_enc_exit, + }, + [HANTRO_MODE_H264_DEC] = { + .run = hantro_g1_h264_dec_run, + .reset = hantro_g1_reset, + .init = hantro_h264_dec_init, + .exit = hantro_h264_dec_exit, + }, + [HANTRO_MODE_MPEG2_DEC] = { + .run = hantro_g1_mpeg2_dec_run, + .reset = hantro_g1_reset, + .init = hantro_mpeg2_dec_init, + .exit = hantro_mpeg2_dec_exit, + }, + [HANTRO_MODE_VP8_DEC] = { + .run = hantro_g1_vp8_dec_run, + .reset = hantro_g1_reset, + .init = hantro_vp8_dec_init, + .exit = hantro_vp8_dec_exit, + }, +}; + +static const struct hantro_codec_ops rk3399_vpu_codec_ops[] = { + [HANTRO_MODE_JPEG_ENC] = { + .run = rockchip_vpu2_jpeg_enc_run, + .reset = rockchip_vpu2_enc_reset, + .init = hantro_jpeg_enc_init, + .exit = hantro_jpeg_enc_exit, + }, + [HANTRO_MODE_MPEG2_DEC] = { + .run = rockchip_vpu2_mpeg2_dec_run, + .reset = rockchip_vpu2_dec_reset, + .init = hantro_mpeg2_dec_init, + .exit = hantro_mpeg2_dec_exit, + }, + [HANTRO_MODE_VP8_DEC] = { + .run = rockchip_vpu2_vp8_dec_run, + .reset = rockchip_vpu2_dec_reset, + .init = hantro_vp8_dec_init, + .exit = hantro_vp8_dec_exit, + }, +}; + +/* + * VPU variant. + */ + +static const struct hantro_irq rockchip_vpu1_irqs[] = { + { "vepu", rockchip_vpu1_vepu_irq }, + { "vdpu", hantro_g1_irq }, +}; + +static const struct hantro_irq rockchip_vdpu2_irqs[] = { + { "vdpu", rockchip_vpu2_vdpu_irq }, +}; + +static const struct hantro_irq rockchip_vpu2_irqs[] = { + { "vepu", rockchip_vpu2_vepu_irq }, + { "vdpu", rockchip_vpu2_vdpu_irq }, +}; + +static const char * const rockchip_vpu_clk_names[] = { + "aclk", "hclk" +}; + +const struct hantro_variant rk3288_vpu_variant = { + .enc_offset = 0x0, + .enc_fmts = rockchip_vpu_enc_fmts, + .num_enc_fmts = ARRAY_SIZE(rockchip_vpu_enc_fmts), + .dec_offset = 0x400, + .dec_fmts = rk3288_vpu_dec_fmts, + .num_dec_fmts = ARRAY_SIZE(rk3288_vpu_dec_fmts), + .postproc_fmts = rockchip_vpu1_postproc_fmts, + .num_postproc_fmts = ARRAY_SIZE(rockchip_vpu1_postproc_fmts), + .postproc_regs = &hantro_g1_postproc_regs, + .codec = HANTRO_JPEG_ENCODER | HANTRO_MPEG2_DECODER | + HANTRO_VP8_DECODER | HANTRO_H264_DECODER, + .codec_ops = rk3288_vpu_codec_ops, + .irqs = rockchip_vpu1_irqs, + .num_irqs = ARRAY_SIZE(rockchip_vpu1_irqs), + .init = rockchip_vpu_hw_init, + .clk_names = rockchip_vpu_clk_names, + .num_clocks = ARRAY_SIZE(rockchip_vpu_clk_names) +}; + +const struct hantro_variant rk3328_vpu_variant = { + .dec_offset = 0x400, + .dec_fmts = rk3399_vpu_dec_fmts, + .num_dec_fmts = ARRAY_SIZE(rk3399_vpu_dec_fmts), + .codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER, + .codec_ops = rk3399_vpu_codec_ops, + .irqs = rockchip_vdpu2_irqs, + .num_irqs = ARRAY_SIZE(rockchip_vdpu2_irqs), + .init = rockchip_vpu_hw_init, + .clk_names = rockchip_vpu_clk_names, + .num_clocks = ARRAY_SIZE(rockchip_vpu_clk_names), +}; + +const struct hantro_variant rk3399_vpu_variant = { + .enc_offset = 0x0, + .enc_fmts = rockchip_vpu_enc_fmts, + .num_enc_fmts = ARRAY_SIZE(rockchip_vpu_enc_fmts), + .dec_offset = 0x400, + .dec_fmts = rk3399_vpu_dec_fmts, + .num_dec_fmts = ARRAY_SIZE(rk3399_vpu_dec_fmts), + .codec = HANTRO_JPEG_ENCODER | HANTRO_MPEG2_DECODER | + HANTRO_VP8_DECODER, + .codec_ops = rk3399_vpu_codec_ops, + .irqs = rockchip_vpu2_irqs, + .num_irqs = ARRAY_SIZE(rockchip_vpu2_irqs), + .init = rockchip_vpu_hw_init, + .clk_names = rockchip_vpu_clk_names, + .num_clocks = ARRAY_SIZE(rockchip_vpu_clk_names) +}; From 78bb1ae5472cabfaf474d348437c25ccaddde75e Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Mon, 14 Jun 2021 23:32:14 +0200 Subject: [PATCH 374/394] media: hantro: add support for Rockchip RK3066 RK3066's VPU IP block is the predecessor from what RK3288 has. The hardware differences are: - supports decoding frame sizes up to 1920x1088 only - doesn't have the 'G1_REG_SOFT_RESET' register (requires another .reset callback for hantro_codec_ops, since writing this register will result in non-working IP block) - has one ACLK/HCLK per vdpu/vepu - ACLKs can be clocked up to 300 MHz only - no MMU (no changes required: CMA will be transparently used) Add a new RK3066 variant which reflect this differences. This variant can be used for RK3188 as well. Signed-off-by: Alex Bee Reviewed-by: Ezequiel Garcia Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/hantro/hantro_drv.c | 1 + drivers/staging/media/hantro/hantro_hw.h | 1 + .../staging/media/hantro/rockchip_vpu_hw.c | 121 ++++++++++++++++++ 3 files changed, 123 insertions(+) diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c index 34e778e1cea1..aaef66c4c795 100644 --- a/drivers/staging/media/hantro/hantro_drv.c +++ b/drivers/staging/media/hantro/hantro_drv.c @@ -582,6 +582,7 @@ static const struct v4l2_file_operations hantro_fops = { static const struct of_device_id of_hantro_match[] = { #ifdef CONFIG_VIDEO_HANTRO_ROCKCHIP + { .compatible = "rockchip,rk3066-vpu", .data = &rk3066_vpu_variant, }, { .compatible = "rockchip,rk3288-vpu", .data = &rk3288_vpu_variant, }, { .compatible = "rockchip,rk3328-vpu", .data = &rk3328_vpu_variant, }, { .compatible = "rockchip,rk3399-vpu", .data = &rk3399_vpu_variant, }, diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h index a7b75b05e849..77df0eba4e6f 100644 --- a/drivers/staging/media/hantro/hantro_hw.h +++ b/drivers/staging/media/hantro/hantro_hw.h @@ -205,6 +205,7 @@ enum hantro_enc_fmt { extern const struct hantro_variant imx8mq_vpu_g2_variant; extern const struct hantro_variant imx8mq_vpu_variant; +extern const struct hantro_variant rk3066_vpu_variant; extern const struct hantro_variant rk3288_vpu_variant; extern const struct hantro_variant rk3328_vpu_variant; extern const struct hantro_variant rk3399_vpu_variant; diff --git a/drivers/staging/media/hantro/rockchip_vpu_hw.c b/drivers/staging/media/hantro/rockchip_vpu_hw.c index bf760e8e65ce..b370b5e802fa 100644 --- a/drivers/staging/media/hantro/rockchip_vpu_hw.c +++ b/drivers/staging/media/hantro/rockchip_vpu_hw.c @@ -10,9 +10,11 @@ #include "hantro.h" #include "hantro_jpeg.h" +#include "hantro_g1_regs.h" #include "hantro_h1_regs.h" #include "rockchip_vpu2_regs.h" +#define RK3066_ACLK_MAX_FREQ (300 * 1000 * 1000) #define RK3288_ACLK_MAX_FREQ (400 * 1000 * 1000) /* @@ -63,6 +65,52 @@ static const struct hantro_fmt rockchip_vpu1_postproc_fmts[] = { }, }; +static const struct hantro_fmt rk3066_vpu_dec_fmts[] = { + { + .fourcc = V4L2_PIX_FMT_NV12, + .codec_mode = HANTRO_MODE_NONE, + }, + { + .fourcc = V4L2_PIX_FMT_H264_SLICE, + .codec_mode = HANTRO_MODE_H264_DEC, + .max_depth = 2, + .frmsize = { + .min_width = 48, + .max_width = 1920, + .step_width = MB_DIM, + .min_height = 48, + .max_height = 1088, + .step_height = MB_DIM, + }, + }, + { + .fourcc = V4L2_PIX_FMT_MPEG2_SLICE, + .codec_mode = HANTRO_MODE_MPEG2_DEC, + .max_depth = 2, + .frmsize = { + .min_width = 48, + .max_width = 1920, + .step_width = MB_DIM, + .min_height = 48, + .max_height = 1088, + .step_height = MB_DIM, + }, + }, + { + .fourcc = V4L2_PIX_FMT_VP8_FRAME, + .codec_mode = HANTRO_MODE_VP8_DEC, + .max_depth = 2, + .frmsize = { + .min_width = 48, + .max_width = 1920, + .step_width = MB_DIM, + .min_height = 48, + .max_height = 1088, + .step_height = MB_DIM, + }, + }, +}; + static const struct hantro_fmt rk3288_vpu_dec_fmts[] = { { .fourcc = V4L2_PIX_FMT_NV12, @@ -196,6 +244,14 @@ static irqreturn_t rockchip_vpu2_vepu_irq(int irq, void *dev_id) return IRQ_HANDLED; } +static int rk3066_vpu_hw_init(struct hantro_dev *vpu) +{ + /* Bump ACLKs to max. possible freq. to improve performance. */ + clk_set_rate(vpu->clocks[0].clk, RK3066_ACLK_MAX_FREQ); + clk_set_rate(vpu->clocks[2].clk, RK3066_ACLK_MAX_FREQ); + return 0; +} + static int rockchip_vpu_hw_init(struct hantro_dev *vpu) { /* Bump ACLK to max. possible freq. to improve performance. */ @@ -203,6 +259,14 @@ static int rockchip_vpu_hw_init(struct hantro_dev *vpu) return 0; } +static void rk3066_vpu_dec_reset(struct hantro_ctx *ctx) +{ + struct hantro_dev *vpu = ctx->dev; + + vdpu_write(vpu, G1_REG_INTERRUPT_DEC_IRQ_DIS, G1_REG_INTERRUPT); + vdpu_write(vpu, G1_REG_CONFIG_DEC_CLK_GATE_E, G1_REG_CONFIG); +} + static void rockchip_vpu1_enc_reset(struct hantro_ctx *ctx) { struct hantro_dev *vpu = ctx->dev; @@ -233,6 +297,33 @@ static void rockchip_vpu2_enc_reset(struct hantro_ctx *ctx) /* * Supported codec ops. */ +static const struct hantro_codec_ops rk3066_vpu_codec_ops[] = { + [HANTRO_MODE_JPEG_ENC] = { + .run = hantro_h1_jpeg_enc_run, + .reset = rockchip_vpu1_enc_reset, + .init = hantro_jpeg_enc_init, + .done = hantro_jpeg_enc_done, + .exit = hantro_jpeg_enc_exit, + }, + [HANTRO_MODE_H264_DEC] = { + .run = hantro_g1_h264_dec_run, + .reset = rk3066_vpu_dec_reset, + .init = hantro_h264_dec_init, + .exit = hantro_h264_dec_exit, + }, + [HANTRO_MODE_MPEG2_DEC] = { + .run = hantro_g1_mpeg2_dec_run, + .reset = rk3066_vpu_dec_reset, + .init = hantro_mpeg2_dec_init, + .exit = hantro_mpeg2_dec_exit, + }, + [HANTRO_MODE_VP8_DEC] = { + .run = hantro_g1_vp8_dec_run, + .reset = rk3066_vpu_dec_reset, + .init = hantro_vp8_dec_init, + .exit = hantro_vp8_dec_exit, + }, +}; static const struct hantro_codec_ops rk3288_vpu_codec_ops[] = { [HANTRO_MODE_JPEG_ENC] = { @@ -301,10 +392,40 @@ static const struct hantro_irq rockchip_vpu2_irqs[] = { { "vdpu", rockchip_vpu2_vdpu_irq }, }; +static const char * const rk3066_vpu_clk_names[] = { + "aclk_vdpu", "hclk_vdpu", + "aclk_vepu", "hclk_vepu" +}; + static const char * const rockchip_vpu_clk_names[] = { "aclk", "hclk" }; +/* + * Despite this variant has separate clocks for decoder and encoder, + * it's still required to enable all four of them for either decoding + * or encoding and we can't split it in separate g1/h1 variants. + */ +const struct hantro_variant rk3066_vpu_variant = { + .enc_offset = 0x0, + .enc_fmts = rockchip_vpu_enc_fmts, + .num_enc_fmts = ARRAY_SIZE(rockchip_vpu_enc_fmts), + .dec_offset = 0x400, + .dec_fmts = rk3066_vpu_dec_fmts, + .num_dec_fmts = ARRAY_SIZE(rk3066_vpu_dec_fmts), + .postproc_fmts = rockchip_vpu1_postproc_fmts, + .num_postproc_fmts = ARRAY_SIZE(rockchip_vpu1_postproc_fmts), + .postproc_regs = &hantro_g1_postproc_regs, + .codec = HANTRO_JPEG_ENCODER | HANTRO_MPEG2_DECODER | + HANTRO_VP8_DECODER | HANTRO_H264_DECODER, + .codec_ops = rk3066_vpu_codec_ops, + .irqs = rockchip_vpu1_irqs, + .num_irqs = ARRAY_SIZE(rockchip_vpu1_irqs), + .init = rk3066_vpu_hw_init, + .clk_names = rk3066_vpu_clk_names, + .num_clocks = ARRAY_SIZE(rk3066_vpu_clk_names) +}; + const struct hantro_variant rk3288_vpu_variant = { .enc_offset = 0x0, .enc_fmts = rockchip_vpu_enc_fmts, From 4f34591568e7a1e4a9d0839b4c8d3155f3047f72 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Mon, 14 Jun 2021 23:32:15 +0200 Subject: [PATCH 375/394] media: hantro: add support for Rockchip RK3036 RK3036's VPU IP block is the same as RK3288 has, except that it doesn't have an encoder, decoding is supported up to 1920x1088 only and the axi clock can be set to 300 MHz max. Add a new RK3036 variant which reflects these differences. Signed-off-by: Alex Bee Reviewed-by: Ezequiel Garcia Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/hantro/hantro_drv.c | 1 + drivers/staging/media/hantro/hantro_hw.h | 1 + .../staging/media/hantro/rockchip_vpu_hw.c | 49 +++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c index aaef66c4c795..31d8449ca1d2 100644 --- a/drivers/staging/media/hantro/hantro_drv.c +++ b/drivers/staging/media/hantro/hantro_drv.c @@ -582,6 +582,7 @@ static const struct v4l2_file_operations hantro_fops = { static const struct of_device_id of_hantro_match[] = { #ifdef CONFIG_VIDEO_HANTRO_ROCKCHIP + { .compatible = "rockchip,rk3036-vpu", .data = &rk3036_vpu_variant, }, { .compatible = "rockchip,rk3066-vpu", .data = &rk3066_vpu_variant, }, { .compatible = "rockchip,rk3288-vpu", .data = &rk3288_vpu_variant, }, { .compatible = "rockchip,rk3328-vpu", .data = &rk3328_vpu_variant, }, diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h index 77df0eba4e6f..5dcf65805396 100644 --- a/drivers/staging/media/hantro/hantro_hw.h +++ b/drivers/staging/media/hantro/hantro_hw.h @@ -205,6 +205,7 @@ enum hantro_enc_fmt { extern const struct hantro_variant imx8mq_vpu_g2_variant; extern const struct hantro_variant imx8mq_vpu_variant; +extern const struct hantro_variant rk3036_vpu_variant; extern const struct hantro_variant rk3066_vpu_variant; extern const struct hantro_variant rk3288_vpu_variant; extern const struct hantro_variant rk3328_vpu_variant; diff --git a/drivers/staging/media/hantro/rockchip_vpu_hw.c b/drivers/staging/media/hantro/rockchip_vpu_hw.c index b370b5e802fa..3ccc16413f42 100644 --- a/drivers/staging/media/hantro/rockchip_vpu_hw.c +++ b/drivers/staging/media/hantro/rockchip_vpu_hw.c @@ -244,6 +244,13 @@ static irqreturn_t rockchip_vpu2_vepu_irq(int irq, void *dev_id) return IRQ_HANDLED; } +static int rk3036_vpu_hw_init(struct hantro_dev *vpu) +{ + /* Bump ACLK to max. possible freq. to improve performance. */ + clk_set_rate(vpu->clocks[0].clk, RK3066_ACLK_MAX_FREQ); + return 0; +} + static int rk3066_vpu_hw_init(struct hantro_dev *vpu) { /* Bump ACLKs to max. possible freq. to improve performance. */ @@ -297,6 +304,27 @@ static void rockchip_vpu2_enc_reset(struct hantro_ctx *ctx) /* * Supported codec ops. */ +static const struct hantro_codec_ops rk3036_vpu_codec_ops[] = { + [HANTRO_MODE_H264_DEC] = { + .run = hantro_g1_h264_dec_run, + .reset = hantro_g1_reset, + .init = hantro_h264_dec_init, + .exit = hantro_h264_dec_exit, + }, + [HANTRO_MODE_MPEG2_DEC] = { + .run = hantro_g1_mpeg2_dec_run, + .reset = hantro_g1_reset, + .init = hantro_mpeg2_dec_init, + .exit = hantro_mpeg2_dec_exit, + }, + [HANTRO_MODE_VP8_DEC] = { + .run = hantro_g1_vp8_dec_run, + .reset = hantro_g1_reset, + .init = hantro_vp8_dec_init, + .exit = hantro_vp8_dec_exit, + }, +}; + static const struct hantro_codec_ops rk3066_vpu_codec_ops[] = { [HANTRO_MODE_JPEG_ENC] = { .run = hantro_h1_jpeg_enc_run, @@ -378,6 +406,10 @@ static const struct hantro_codec_ops rk3399_vpu_codec_ops[] = { * VPU variant. */ +static const struct hantro_irq rockchip_vdpu1_irqs[] = { + { "vdpu", hantro_g1_irq }, +}; + static const struct hantro_irq rockchip_vpu1_irqs[] = { { "vepu", rockchip_vpu1_vepu_irq }, { "vdpu", hantro_g1_irq }, @@ -401,6 +433,23 @@ static const char * const rockchip_vpu_clk_names[] = { "aclk", "hclk" }; +const struct hantro_variant rk3036_vpu_variant = { + .dec_offset = 0x400, + .dec_fmts = rk3066_vpu_dec_fmts, + .num_dec_fmts = ARRAY_SIZE(rk3066_vpu_dec_fmts), + .postproc_fmts = rockchip_vpu1_postproc_fmts, + .num_postproc_fmts = ARRAY_SIZE(rockchip_vpu1_postproc_fmts), + .postproc_regs = &hantro_g1_postproc_regs, + .codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER | + HANTRO_H264_DECODER, + .codec_ops = rk3036_vpu_codec_ops, + .irqs = rockchip_vdpu1_irqs, + .num_irqs = ARRAY_SIZE(rockchip_vdpu1_irqs), + .init = rk3036_vpu_hw_init, + .clk_names = rockchip_vpu_clk_names, + .num_clocks = ARRAY_SIZE(rockchip_vpu_clk_names) +}; + /* * Despite this variant has separate clocks for decoder and encoder, * it's still required to enable all four of them for either decoding From 3de09c7ae70d544b13b4da74fa3ebd4c25eb9ab9 Mon Sep 17 00:00:00 2001 From: Jacopo Mondi Date: Wed, 16 Jun 2021 14:46:02 +0200 Subject: [PATCH 376/394] media: i2c: max9286: Adjust parameters indent The parameters to max9286_i2c_mux_configure() fits on the previous line. Adjust it. Cosmetic change only. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart Reviewed-by: Kieran Bingham Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/max9286.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c index 4631bfeeacc0..e3c23916b926 100644 --- a/drivers/media/i2c/max9286.c +++ b/drivers/media/i2c/max9286.c @@ -287,9 +287,8 @@ static int max9286_i2c_mux_select(struct i2c_mux_core *muxc, u32 chan) priv->mux_channel = chan; - max9286_i2c_mux_configure(priv, - MAX9286_FWDCCEN(chan) | - MAX9286_REVCCEN(chan)); + max9286_i2c_mux_configure(priv, MAX9286_FWDCCEN(chan) | + MAX9286_REVCCEN(chan)); return 0; } From f78723eb627554213048918caa02a42cae66884e Mon Sep 17 00:00:00 2001 From: Jacopo Mondi Date: Wed, 16 Jun 2021 14:46:03 +0200 Subject: [PATCH 377/394] media: i2c: max9286: Rename reverse_channel_mv Rename the reverse_channel_mv variable to init_rev_chan_mv as the next patch will cache the reverse channel amplitude in a new driver variable. Signed-off-by: Jacopo Mondi Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/max9286.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c index e3c23916b926..22021e90e322 100644 --- a/drivers/media/i2c/max9286.c +++ b/drivers/media/i2c/max9286.c @@ -163,7 +163,8 @@ struct max9286_priv { unsigned int mux_channel; bool mux_open; - u32 reverse_channel_mv; + /* The initial reverse control channel amplitude. */ + u32 init_rev_chan_mv; struct v4l2_ctrl_handler ctrls; struct v4l2_ctrl *pixelrate; @@ -563,7 +564,7 @@ static int max9286_notify_bound(struct v4l2_async_notifier *notifier, * - Disable auto-ack as communication on the control channel are now * stable. */ - if (priv->reverse_channel_mv < 170) + if (priv->init_rev_chan_mv < 170) max9286_reverse_channel_setup(priv, 170); max9286_check_config_link(priv, priv->source_mask); @@ -972,7 +973,7 @@ static int max9286_setup(struct max9286_priv *priv) * only. This should be disabled after the mux is initialised. */ max9286_configure_i2c(priv, true); - max9286_reverse_channel_setup(priv, priv->reverse_channel_mv); + max9286_reverse_channel_setup(priv, priv->init_rev_chan_mv); /* * Enable GMSL links, mask unused ones and autodetect link @@ -1237,9 +1238,9 @@ static int max9286_parse_dt(struct max9286_priv *priv) if (of_property_read_u32(dev->of_node, "maxim,reverse-channel-microvolt", &reverse_channel_microvolt)) - priv->reverse_channel_mv = 170; + priv->init_rev_chan_mv = 170; else - priv->reverse_channel_mv = reverse_channel_microvolt / 1000U; + priv->init_rev_chan_mv = reverse_channel_microvolt / 1000U; priv->route_mask = priv->source_mask; From 902edc2a1c1ae4b514efd800dc5d5bc5b6d58991 Mon Sep 17 00:00:00 2001 From: Jacopo Mondi Date: Wed, 16 Jun 2021 14:46:04 +0200 Subject: [PATCH 378/394] media: i2c: max9286: Cache channel amplitude Cache the current channel amplitude in a driver variable to skip updating it if the newly requested value is the same as the currently configured one. Signed-off-by: Jacopo Mondi Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/max9286.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c index 22021e90e322..53368625fb8e 100644 --- a/drivers/media/i2c/max9286.c +++ b/drivers/media/i2c/max9286.c @@ -165,6 +165,7 @@ struct max9286_priv { /* The initial reverse control channel amplitude. */ u32 init_rev_chan_mv; + u32 rev_chan_mv; struct v4l2_ctrl_handler ctrls; struct v4l2_ctrl *pixelrate; @@ -341,8 +342,15 @@ static void max9286_configure_i2c(struct max9286_priv *priv, bool localack) static void max9286_reverse_channel_setup(struct max9286_priv *priv, unsigned int chan_amplitude) { + u8 chan_config; + + if (priv->rev_chan_mv == chan_amplitude) + return; + + priv->rev_chan_mv = chan_amplitude; + /* Reverse channel transmission time: default to 1. */ - u8 chan_config = MAX9286_REV_TRF(1); + chan_config = MAX9286_REV_TRF(1); /* * Reverse channel setup. @@ -564,8 +572,7 @@ static int max9286_notify_bound(struct v4l2_async_notifier *notifier, * - Disable auto-ack as communication on the control channel are now * stable. */ - if (priv->init_rev_chan_mv < 170) - max9286_reverse_channel_setup(priv, 170); + max9286_reverse_channel_setup(priv, 170); max9286_check_config_link(priv, priv->source_mask); /* From 731c24ffa2b1614335987645d8821bf2ceedc841 Mon Sep 17 00:00:00 2001 From: Jacopo Mondi Date: Wed, 16 Jun 2021 14:46:05 +0200 Subject: [PATCH 379/394] media: i2c: max9286: Define high channel amplitude Provide a macro to define the reverse channel amplitude to be used to compensate the remote serializer noise immunity. While at it, update a comment. Signed-off-by: Jacopo Mondi Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/max9286.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c index 53368625fb8e..b0cd9fc8f7e2 100644 --- a/drivers/media/i2c/max9286.c +++ b/drivers/media/i2c/max9286.c @@ -113,6 +113,7 @@ #define MAX9286_REV_TRF(n) ((n) << 4) #define MAX9286_REV_AMP(n) ((((n) - 30) / 10) << 1) /* in mV */ #define MAX9286_REV_AMP_X BIT(0) +#define MAX9286_REV_AMP_HIGH 170 /* Register 0x3f */ #define MAX9286_EN_REV_CFG BIT(6) #define MAX9286_REV_FLEN(n) ((n) - 20) @@ -567,12 +568,12 @@ static int max9286_notify_bound(struct v4l2_async_notifier *notifier, * channels: * * - Increase the reverse channel amplitude to compensate for the - * remote ends high threshold, if not done already + * remote ends high threshold * - Verify all configuration links are properly detected * - Disable auto-ack as communication on the control channel are now * stable. */ - max9286_reverse_channel_setup(priv, 170); + max9286_reverse_channel_setup(priv, MAX9286_REV_AMP_HIGH); max9286_check_config_link(priv, priv->source_mask); /* From 4ff5278dcef900879252556a51b74b33efb06623 Mon Sep 17 00:00:00 2001 From: Jacopo Mondi Date: Wed, 16 Jun 2021 14:46:06 +0200 Subject: [PATCH 380/394] media: i2c: max9286: Rework comments in .bound() Rephrase a comment in .bound() callback to make it clear we register a subdev notifier and remove a redundant comment about disabling i2c auto-ack. No functional changes intended. Signed-off-by: Jacopo Mondi Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/max9286.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c index b0cd9fc8f7e2..1aa2c58fd38c 100644 --- a/drivers/media/i2c/max9286.c +++ b/drivers/media/i2c/max9286.c @@ -556,9 +556,9 @@ static int max9286_notify_bound(struct v4l2_async_notifier *notifier, subdev->name, src_pad, index); /* - * We can only register v4l2_async_notifiers, which do not provide a - * means to register a complete callback. bound_sources allows us to - * identify when all remote serializers have completed their probe. + * As we register a subdev notifiers we won't get a .complete() callback + * here, so we have to use bound_sources to identify when all remote + * serializers have probed. */ if (priv->bound_sources != priv->source_mask) return 0; @@ -575,11 +575,6 @@ static int max9286_notify_bound(struct v4l2_async_notifier *notifier, */ max9286_reverse_channel_setup(priv, MAX9286_REV_AMP_HIGH); max9286_check_config_link(priv, priv->source_mask); - - /* - * Re-configure I2C with local acknowledge disabled after cameras have - * probed. - */ max9286_configure_i2c(priv, false); return max9286_set_pixelrate(priv); From ad01032aaf437c526d7135384bb4f998828d0cfc Mon Sep 17 00:00:00 2001 From: Jacopo Mondi Date: Wed, 16 Jun 2021 14:46:07 +0200 Subject: [PATCH 381/394] media: i2c: max9271: Check max9271_write() return Check the return value of the max9271_write() function in the max9271 library driver. While at it, modify an existing condition to be made identical to other checks. Signed-off-by: Jacopo Mondi Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/max9271.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/drivers/media/i2c/max9271.c b/drivers/media/i2c/max9271.c index c495582dcff6..2c7dc7fb9846 100644 --- a/drivers/media/i2c/max9271.c +++ b/drivers/media/i2c/max9271.c @@ -106,7 +106,10 @@ int max9271_set_serial_link(struct max9271_device *dev, bool enable) * Short delays here appear to show bit-errors in the writes following. * Therefore a conservative delay seems best here. */ - max9271_write(dev, 0x04, val); + ret = max9271_write(dev, 0x04, val); + if (ret < 0) + return ret; + usleep_range(5000, 8000); return 0; @@ -118,7 +121,7 @@ int max9271_configure_i2c(struct max9271_device *dev, u8 i2c_config) int ret; ret = max9271_write(dev, 0x0d, i2c_config); - if (ret) + if (ret < 0) return ret; /* The delay required after an I2C bus configuration change is not @@ -143,7 +146,10 @@ int max9271_set_high_threshold(struct max9271_device *dev, bool enable) * Enable or disable reverse channel high threshold to increase * immunity to power supply noise. */ - max9271_write(dev, 0x08, enable ? ret | BIT(0) : ret & ~BIT(0)); + ret = max9271_write(dev, 0x08, enable ? ret | BIT(0) : ret & ~BIT(0)); + if (ret < 0) + return ret; + usleep_range(2000, 2500); return 0; @@ -152,6 +158,8 @@ EXPORT_SYMBOL_GPL(max9271_set_high_threshold); int max9271_configure_gmsl_link(struct max9271_device *dev) { + int ret; + /* * Configure the GMSL link: * @@ -162,16 +170,24 @@ int max9271_configure_gmsl_link(struct max9271_device *dev) * * TODO: Make the GMSL link configuration parametric. */ - max9271_write(dev, 0x07, MAX9271_DBL | MAX9271_HVEN | - MAX9271_EDC_1BIT_PARITY); + ret = max9271_write(dev, 0x07, MAX9271_DBL | MAX9271_HVEN | + MAX9271_EDC_1BIT_PARITY); + if (ret < 0) + return ret; + usleep_range(5000, 8000); /* * Adjust spread spectrum to +4% and auto-detect pixel clock * and serial link rate. */ - max9271_write(dev, 0x02, MAX9271_SPREAD_SPECT_4 | MAX9271_R02_RES | - MAX9271_PCLK_AUTODETECT | MAX9271_SERIAL_AUTODETECT); + ret = max9271_write(dev, 0x02, + MAX9271_SPREAD_SPECT_4 | MAX9271_R02_RES | + MAX9271_PCLK_AUTODETECT | + MAX9271_SERIAL_AUTODETECT); + if (ret < 0) + return ret; + usleep_range(5000, 8000); return 0; From 9e0bf8393d0602cc7fda749b77cf8ec7f81249cb Mon Sep 17 00:00:00 2001 From: Jacopo Mondi Date: Wed, 16 Jun 2021 14:46:08 +0200 Subject: [PATCH 382/394] media: i2c: max9271: Introduce wake_up() function The MAX9271 chip manual prescribes a delay of 5 milliseconds after the chip exits from low power state. Add a new function to the max9271 library driver that wakes up the chip with a dummy i2c transaction and implements the correct delay of 5 milliseconds after the chip exits from low power state. Use the newly introduced function in the rdacm20 and rdacm21 camera drivers. The former was not respecting the required delay while the latter was waiting for a too-short timeout. Signed-off-by: Jacopo Mondi Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/max9271.c | 12 ++++++++++++ drivers/media/i2c/max9271.h | 9 +++++++++ drivers/media/i2c/rdacm20.c | 4 +--- drivers/media/i2c/rdacm21.c | 5 +---- 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/drivers/media/i2c/max9271.c b/drivers/media/i2c/max9271.c index 2c7dc7fb9846..ff86c8c4ea61 100644 --- a/drivers/media/i2c/max9271.c +++ b/drivers/media/i2c/max9271.c @@ -80,6 +80,18 @@ static int max9271_pclk_detect(struct max9271_device *dev) return -EIO; } +void max9271_wake_up(struct max9271_device *dev) +{ + /* + * Use the chip default address as this function has to be called + * before any other one. + */ + dev->client->addr = MAX9271_DEFAULT_ADDR; + i2c_smbus_read_byte(dev->client); + usleep_range(5000, 8000); +} +EXPORT_SYMBOL_GPL(max9271_wake_up); + int max9271_set_serial_link(struct max9271_device *dev, bool enable) { int ret; diff --git a/drivers/media/i2c/max9271.h b/drivers/media/i2c/max9271.h index d78fb21441e9..dc5e4e70ba6f 100644 --- a/drivers/media/i2c/max9271.h +++ b/drivers/media/i2c/max9271.h @@ -85,6 +85,15 @@ struct max9271_device { struct i2c_client *client; }; +/** + * max9271_wake_up() - Wake up the serializer by issuing an i2c transaction + * @dev: The max9271 device + * + * This function shall be called before any other interaction with the + * serializer. + */ +void max9271_wake_up(struct max9271_device *dev); + /** * max9271_set_serial_link() - Enable/disable serial link * @dev: The max9271 device diff --git a/drivers/media/i2c/rdacm20.c b/drivers/media/i2c/rdacm20.c index a4b639cf8063..ecd8bf97aae1 100644 --- a/drivers/media/i2c/rdacm20.c +++ b/drivers/media/i2c/rdacm20.c @@ -455,9 +455,7 @@ static int rdacm20_initialize(struct rdacm20_device *dev) unsigned int retry = 3; int ret; - /* Verify communication with the MAX9271: ping to wakeup. */ - dev->serializer->client->addr = MAX9271_DEFAULT_ADDR; - i2c_smbus_read_byte(dev->serializer->client); + max9271_wake_up(dev->serializer); /* Serial link disabled during config as it needs a valid pixel clock. */ ret = max9271_set_serial_link(dev->serializer, false); diff --git a/drivers/media/i2c/rdacm21.c b/drivers/media/i2c/rdacm21.c index 5b78d8185773..67ed1e5c450d 100644 --- a/drivers/media/i2c/rdacm21.c +++ b/drivers/media/i2c/rdacm21.c @@ -450,10 +450,7 @@ static int rdacm21_initialize(struct rdacm21_device *dev) { int ret; - /* Verify communication with the MAX9271: ping to wakeup. */ - dev->serializer.client->addr = MAX9271_DEFAULT_ADDR; - i2c_smbus_read_byte(dev->serializer.client); - usleep_range(3000, 5000); + max9271_wake_up(&dev->serializer); /* Enable reverse channel and disable the serial link. */ ret = max9271_set_serial_link(&dev->serializer, false); From 7028772092b7f2fc50de7f00aa0817505b3b11f7 Mon Sep 17 00:00:00 2001 From: Jacopo Mondi Date: Wed, 16 Jun 2021 14:46:09 +0200 Subject: [PATCH 383/394] media: i2c: rdacm21: Add delay after OV490 reset Add a delay after the OV490 chip is put in reset state. The reset signal shall be held low for at least 250 useconds. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart Reviewed-by: Kieran Bingham Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/rdacm21.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/media/i2c/rdacm21.c b/drivers/media/i2c/rdacm21.c index 67ed1e5c450d..336fd5d482b7 100644 --- a/drivers/media/i2c/rdacm21.c +++ b/drivers/media/i2c/rdacm21.c @@ -469,7 +469,10 @@ static int rdacm21_initialize(struct rdacm21_device *dev) if (ret) return ret; - /* Enable GPIO1 and hold OV490 in reset during max9271 configuration. */ + /* + * Enable GPIO1 and hold OV490 in reset during max9271 configuration. + * The reset signal has to be asserted for at least 250 useconds. + */ ret = max9271_enable_gpios(&dev->serializer, MAX9271_GPIO1OUT); if (ret) return ret; @@ -477,6 +480,7 @@ static int rdacm21_initialize(struct rdacm21_device *dev) ret = max9271_clear_gpios(&dev->serializer, MAX9271_GPIO1OUT); if (ret) return ret; + usleep_range(250, 500); ret = max9271_configure_gmsl_link(&dev->serializer); if (ret) From ff75332b260cd33cc19000fdb5d256d9db4470d1 Mon Sep 17 00:00:00 2001 From: Jacopo Mondi Date: Wed, 16 Jun 2021 14:46:10 +0200 Subject: [PATCH 384/394] media: i2c: rdacm21: Fix OV10640 powerup The OV10640 image sensor powerdown signal is controlled by the first line of the OV490 GPIO pad #1, but the pad #0 identifier OV490_GPIO_OUTPUT_VALUE0 was erroneously used. As a result the image sensor powerdown signal was never asserted but was left floating and kept high by an internal pull-up resistor, causing sporadic failures during the image sensor startup phase. Fix this by using the correct GPIO pad identifier and wait the mandatory 1.5 millisecond delay after the powerup lane is asserted. The reset delay is not characterized in the chip manual if not as "255 XVCLK + initialization". Wait for at least 3 milliseconds to guarantee the SCCB bus is available. While at it also fix the reset sequence, as the reset line was released before the powerdown one, and the line was not cycled. This commit fixes a sporadic start-up error triggered by a failure to read the OV10640 chip ID: rdacm21 8-0054: OV10640 ID mismatch: (0x01) Fixes: a59f853b3b4b ("media: i2c: Add driver for RDACM21 camera module") Signed-off-by: Jacopo Mondi Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/rdacm21.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/rdacm21.c b/drivers/media/i2c/rdacm21.c index 336fd5d482b7..6ab8a894e94b 100644 --- a/drivers/media/i2c/rdacm21.c +++ b/drivers/media/i2c/rdacm21.c @@ -333,13 +333,19 @@ static int ov10640_initialize(struct rdacm21_device *dev) { u8 val; - /* Power-up OV10640 by setting RESETB and PWDNB pins high. */ + /* Enable GPIO0#0 (reset) and GPIO1#0 (pwdn) as output lines. */ ov490_write_reg(dev, OV490_GPIO_SEL0, OV490_GPIO0); ov490_write_reg(dev, OV490_GPIO_SEL1, OV490_SPWDN0); ov490_write_reg(dev, OV490_GPIO_DIRECTION0, OV490_GPIO0); ov490_write_reg(dev, OV490_GPIO_DIRECTION1, OV490_SPWDN0); + + /* Power up OV10640 and then reset it. */ + ov490_write_reg(dev, OV490_GPIO_OUTPUT_VALUE1, OV490_SPWDN0); + usleep_range(1500, 3000); + + ov490_write_reg(dev, OV490_GPIO_OUTPUT_VALUE0, 0x00); + usleep_range(1500, 3000); ov490_write_reg(dev, OV490_GPIO_OUTPUT_VALUE0, OV490_GPIO0); - ov490_write_reg(dev, OV490_GPIO_OUTPUT_VALUE0, OV490_SPWDN0); usleep_range(3000, 5000); /* Read OV10640 ID to test communications. */ From 2b821698dc73c00719e3dc367db712f727bbda85 Mon Sep 17 00:00:00 2001 From: Jacopo Mondi Date: Wed, 16 Jun 2021 14:46:11 +0200 Subject: [PATCH 385/394] media: i2c: rdacm21: Power up OV10640 before OV490 The current RDACM21 initialization routine powers up the OV10640 image sensor after the OV490 ISP. The ISP is programmed with a firmware loaded from an embedded serial flash that (most probably) tries to interact and program also the image sensor connected to the ISP. As described in commit "media: i2c: rdacm21: Fix OV10640 powerup" the image sensor powerdown signal is kept high by an internal pull up resistor and occasionally fails to startup correctly if the powerdown line is not asserted explicitly. Failures in the OV10640 startup causes the OV490 firmware to fail to boot correctly resulting in the camera module initialization to fail consequentially. Fix this by powering up the OV10640 image sensor before testing the OV490 firmware boot completion, by splitting the ov10640_initialize() function in an ov10640_power_up() one and an ov10640_check_id() one. Also make sure the OV10640 identification procedure gives enough time to the image sensor to resume after the programming phase performed by the OV490 firmware by repeating the ID read procedure. This commit fixes a sporadic start-up error triggered by a failure to detect the OV490 firmware boot completion: rdacm21 8-0054: Timeout waiting for firmware boot [hverkuil: fixed two typos in commit log] Fixes: a59f853b3b4b ("media: i2c: Add driver for RDACM21 camera module") Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart Reviewed-by: Kieran Bingham Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/rdacm21.c | 42 ++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/drivers/media/i2c/rdacm21.c b/drivers/media/i2c/rdacm21.c index 6ab8a894e94b..12ec5467ed1e 100644 --- a/drivers/media/i2c/rdacm21.c +++ b/drivers/media/i2c/rdacm21.c @@ -69,6 +69,7 @@ #define OV490_ISP_VSIZE_LOW 0x80820062 #define OV490_ISP_VSIZE_HIGH 0x80820063 +#define OV10640_PID_TIMEOUT 20 #define OV10640_ID_HIGH 0xa6 #define OV10640_CHIP_ID 0x300a #define OV10640_PIXEL_RATE 55000000 @@ -329,10 +330,8 @@ static const struct v4l2_subdev_ops rdacm21_subdev_ops = { .pad = &rdacm21_subdev_pad_ops, }; -static int ov10640_initialize(struct rdacm21_device *dev) +static void ov10640_power_up(struct rdacm21_device *dev) { - u8 val; - /* Enable GPIO0#0 (reset) and GPIO1#0 (pwdn) as output lines. */ ov490_write_reg(dev, OV490_GPIO_SEL0, OV490_GPIO0); ov490_write_reg(dev, OV490_GPIO_SEL1, OV490_SPWDN0); @@ -347,18 +346,35 @@ static int ov10640_initialize(struct rdacm21_device *dev) usleep_range(1500, 3000); ov490_write_reg(dev, OV490_GPIO_OUTPUT_VALUE0, OV490_GPIO0); usleep_range(3000, 5000); +} + +static int ov10640_check_id(struct rdacm21_device *dev) +{ + unsigned int i; + u8 val; /* Read OV10640 ID to test communications. */ - ov490_write_reg(dev, OV490_SCCB_SLAVE0_DIR, OV490_SCCB_SLAVE_READ); - ov490_write_reg(dev, OV490_SCCB_SLAVE0_ADDR_HIGH, OV10640_CHIP_ID >> 8); - ov490_write_reg(dev, OV490_SCCB_SLAVE0_ADDR_LOW, OV10640_CHIP_ID & 0xff); + for (i = 0; i < OV10640_PID_TIMEOUT; ++i) { + ov490_write_reg(dev, OV490_SCCB_SLAVE0_DIR, + OV490_SCCB_SLAVE_READ); + ov490_write_reg(dev, OV490_SCCB_SLAVE0_ADDR_HIGH, + OV10640_CHIP_ID >> 8); + ov490_write_reg(dev, OV490_SCCB_SLAVE0_ADDR_LOW, + OV10640_CHIP_ID & 0xff); - /* Trigger SCCB slave transaction and give it some time to complete. */ - ov490_write_reg(dev, OV490_HOST_CMD, OV490_HOST_CMD_TRIGGER); - usleep_range(1000, 1500); + /* + * Trigger SCCB slave transaction and give it some time + * to complete. + */ + ov490_write_reg(dev, OV490_HOST_CMD, OV490_HOST_CMD_TRIGGER); + usleep_range(1000, 1500); - ov490_read_reg(dev, OV490_SCCB_SLAVE0_DIR, &val); - if (val != OV10640_ID_HIGH) { + ov490_read_reg(dev, OV490_SCCB_SLAVE0_DIR, &val); + if (val == OV10640_ID_HIGH) + break; + usleep_range(1000, 1500); + } + if (i == OV10640_PID_TIMEOUT) { dev_err(dev->dev, "OV10640 ID mismatch: (0x%02x)\n", val); return -ENODEV; } @@ -374,6 +390,8 @@ static int ov490_initialize(struct rdacm21_device *dev) unsigned int i; int ret; + ov10640_power_up(dev); + /* * Read OV490 Id to test communications. Give it up to 40msec to * exit from reset. @@ -411,7 +429,7 @@ static int ov490_initialize(struct rdacm21_device *dev) return -ENODEV; } - ret = ov10640_initialize(dev); + ret = ov10640_check_id(dev); if (ret) return ret; From 1524bb765d33a5b999b7af361e1e0fc9068b79d5 Mon Sep 17 00:00:00 2001 From: Jacopo Mondi Date: Wed, 16 Jun 2021 14:46:13 +0200 Subject: [PATCH 386/394] media: i2c: rdacm20: Embed 'serializer' field There's no reason to allocate dynamically the 'serializer' field in the driver structure. Embed the field and adjust all its users in the driver. Signed-off-by: Jacopo Mondi Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/rdacm20.c | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/drivers/media/i2c/rdacm20.c b/drivers/media/i2c/rdacm20.c index ecd8bf97aae1..91b9b68e115c 100644 --- a/drivers/media/i2c/rdacm20.c +++ b/drivers/media/i2c/rdacm20.c @@ -312,7 +312,7 @@ static const struct ov10635_reg { struct rdacm20_device { struct device *dev; - struct max9271_device *serializer; + struct max9271_device serializer; struct i2c_client *sensor; struct v4l2_subdev sd; struct media_pad pad; @@ -399,7 +399,7 @@ static int rdacm20_s_stream(struct v4l2_subdev *sd, int enable) { struct rdacm20_device *dev = sd_to_rdacm20(sd); - return max9271_set_serial_link(dev->serializer, enable); + return max9271_set_serial_link(&dev->serializer, enable); } static int rdacm20_enum_mbus_code(struct v4l2_subdev *sd, @@ -455,10 +455,10 @@ static int rdacm20_initialize(struct rdacm20_device *dev) unsigned int retry = 3; int ret; - max9271_wake_up(dev->serializer); + max9271_wake_up(&dev->serializer); /* Serial link disabled during config as it needs a valid pixel clock. */ - ret = max9271_set_serial_link(dev->serializer, false); + ret = max9271_set_serial_link(&dev->serializer, false); if (ret) return ret; @@ -466,35 +466,35 @@ static int rdacm20_initialize(struct rdacm20_device *dev) * Ensure that we have a good link configuration before attempting to * identify the device. */ - max9271_configure_i2c(dev->serializer, MAX9271_I2CSLVSH_469NS_234NS | - MAX9271_I2CSLVTO_1024US | - MAX9271_I2CMSTBT_105KBPS); + max9271_configure_i2c(&dev->serializer, MAX9271_I2CSLVSH_469NS_234NS | + MAX9271_I2CSLVTO_1024US | + MAX9271_I2CMSTBT_105KBPS); - max9271_configure_gmsl_link(dev->serializer); + max9271_configure_gmsl_link(&dev->serializer); - ret = max9271_verify_id(dev->serializer); + ret = max9271_verify_id(&dev->serializer); if (ret < 0) return ret; - ret = max9271_set_address(dev->serializer, dev->addrs[0]); + ret = max9271_set_address(&dev->serializer, dev->addrs[0]); if (ret < 0) return ret; - dev->serializer->client->addr = dev->addrs[0]; + dev->serializer.client->addr = dev->addrs[0]; /* * Reset the sensor by cycling the OV10635 reset signal connected to the * MAX9271 GPIO1 and verify communication with the OV10635. */ - ret = max9271_enable_gpios(dev->serializer, MAX9271_GPIO1OUT); + ret = max9271_enable_gpios(&dev->serializer, MAX9271_GPIO1OUT); if (ret) return ret; - ret = max9271_clear_gpios(dev->serializer, MAX9271_GPIO1OUT); + ret = max9271_clear_gpios(&dev->serializer, MAX9271_GPIO1OUT); if (ret) return ret; usleep_range(10000, 15000); - ret = max9271_set_gpios(dev->serializer, MAX9271_GPIO1OUT); + ret = max9271_set_gpios(&dev->serializer, MAX9271_GPIO1OUT); if (ret) return ret; usleep_range(10000, 15000); @@ -552,13 +552,7 @@ static int rdacm20_probe(struct i2c_client *client) if (!dev) return -ENOMEM; dev->dev = &client->dev; - - dev->serializer = devm_kzalloc(&client->dev, sizeof(*dev->serializer), - GFP_KERNEL); - if (!dev->serializer) - return -ENOMEM; - - dev->serializer->client = client; + dev->serializer.client = client; ret = of_property_read_u32_array(client->dev.of_node, "reg", dev->addrs, 2); From 09741de09bf8a05558c37b2bbd85ca8f516fb753 Mon Sep 17 00:00:00 2001 From: Jacopo Mondi Date: Wed, 16 Jun 2021 14:46:12 +0200 Subject: [PATCH 387/394] media: i2c: rdacm20: Enable noise immunity Enable the noise immunity threshold at the end of the rdacm20 initialization routine. The rdacm20 camera module has been so far tested with a startup delay that allowed the embedded MCU to program the serializer. If the initialization routine is run before the MCU programs the serializer and the image sensor and their addresses gets changed by the rdacm20 driver it is required to manually enable the noise immunity threshold to make the communication on the control channel more reliable. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart Reviewed-by: Kieran Bingham Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/rdacm20.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/media/i2c/rdacm20.c b/drivers/media/i2c/rdacm20.c index 91b9b68e115c..9d5de15fbdb8 100644 --- a/drivers/media/i2c/rdacm20.c +++ b/drivers/media/i2c/rdacm20.c @@ -539,7 +539,19 @@ again: dev_info(dev->dev, "Identified MAX9271 + OV10635 device\n"); - return 0; + /* + * Set reverse channel high threshold to increase noise immunity. + * + * This should be compensated by increasing the reverse channel + * amplitude on the remote deserializer side. + * + * TODO Inspect the embedded MCU programming sequence to make sure + * there are no conflicts with the configuration applied here. + * + * TODO Clarify the embedded MCU startup delay to avoid write + * collisions on the I2C bus. + */ + return max9271_set_high_threshold(&dev->serializer, true); } static int rdacm20_probe(struct i2c_client *client) From 59a81c70b0b3563fe8426b0fe4d96263b6fa8823 Mon Sep 17 00:00:00 2001 From: Jacopo Mondi Date: Wed, 16 Jun 2021 14:46:14 +0200 Subject: [PATCH 388/394] media: i2c: rdacm20: Report camera module name When the device is identified the driver currently reports the names of the chips embedded in the camera module. Report the name of the camera module itself instead. Cosmetic change only. Signed-off-by: Jacopo Mondi Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/rdacm20.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/i2c/rdacm20.c b/drivers/media/i2c/rdacm20.c index 9d5de15fbdb8..343604b61e2a 100644 --- a/drivers/media/i2c/rdacm20.c +++ b/drivers/media/i2c/rdacm20.c @@ -537,7 +537,7 @@ again: if (ret) return ret; - dev_info(dev->dev, "Identified MAX9271 + OV10635 device\n"); + dev_info(dev->dev, "Identified RDACM20 camera module\n"); /* * Set reverse channel high threshold to increase noise immunity. From 47f8b8a2cfee45f2405527e225a566fe39f9d400 Mon Sep 17 00:00:00 2001 From: Jacopo Mondi Date: Wed, 16 Jun 2021 14:46:15 +0200 Subject: [PATCH 389/394] media: i2c: rdacm20: Check return values The camera module initialization routine does not check the return value of a few functions. Fix that. Signed-off-by: Jacopo Mondi Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/rdacm20.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/rdacm20.c b/drivers/media/i2c/rdacm20.c index 343604b61e2a..0fc5512cd5e7 100644 --- a/drivers/media/i2c/rdacm20.c +++ b/drivers/media/i2c/rdacm20.c @@ -466,11 +466,16 @@ static int rdacm20_initialize(struct rdacm20_device *dev) * Ensure that we have a good link configuration before attempting to * identify the device. */ - max9271_configure_i2c(&dev->serializer, MAX9271_I2CSLVSH_469NS_234NS | - MAX9271_I2CSLVTO_1024US | - MAX9271_I2CMSTBT_105KBPS); + ret = max9271_configure_i2c(&dev->serializer, + MAX9271_I2CSLVSH_469NS_234NS | + MAX9271_I2CSLVTO_1024US | + MAX9271_I2CMSTBT_105KBPS); + if (ret) + return ret; - max9271_configure_gmsl_link(&dev->serializer); + ret = max9271_configure_gmsl_link(&dev->serializer); + if (ret) + return ret; ret = max9271_verify_id(&dev->serializer); if (ret < 0) From 198bb646e8553e8abd8d83492a27b601ab97b75d Mon Sep 17 00:00:00 2001 From: Jacopo Mondi Date: Wed, 16 Jun 2021 14:46:16 +0200 Subject: [PATCH 390/394] media: i2c: rdacm20: Re-work ov10635 reset The OV10635 image sensor embedded in the camera module is currently reset after the MAX9271 initialization with two long delays that were most probably not correctly characterized. Re-work the image sensor reset procedure by holding the chip in reset during the MAX9271 configuration, removing the long sleep delays and only wait after the chip exits from reset for 350-500 microseconds interval, which is larger than the minimum (2048 * (1 / XVCLK)) timeout characterized in the chip manual. Signed-off-by: Jacopo Mondi Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/rdacm20.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/drivers/media/i2c/rdacm20.c b/drivers/media/i2c/rdacm20.c index 0fc5512cd5e7..025a610de893 100644 --- a/drivers/media/i2c/rdacm20.c +++ b/drivers/media/i2c/rdacm20.c @@ -473,6 +473,19 @@ static int rdacm20_initialize(struct rdacm20_device *dev) if (ret) return ret; + /* + * Hold OV10635 in reset during max9271 configuration. The reset signal + * has to be asserted for at least 200 microseconds. + */ + ret = max9271_enable_gpios(&dev->serializer, MAX9271_GPIO1OUT); + if (ret) + return ret; + + ret = max9271_clear_gpios(&dev->serializer, MAX9271_GPIO1OUT); + if (ret) + return ret; + usleep_range(200, 500); + ret = max9271_configure_gmsl_link(&dev->serializer); if (ret) return ret; @@ -487,22 +500,14 @@ static int rdacm20_initialize(struct rdacm20_device *dev) dev->serializer.client->addr = dev->addrs[0]; /* - * Reset the sensor by cycling the OV10635 reset signal connected to the - * MAX9271 GPIO1 and verify communication with the OV10635. + * Release ov10635 from reset and initialize it. The image sensor + * requires at least 2048 XVCLK cycles (85 micro-seconds at 24MHz) + * before being available. Stay safe and wait up to 500 micro-seconds. */ - ret = max9271_enable_gpios(&dev->serializer, MAX9271_GPIO1OUT); - if (ret) - return ret; - - ret = max9271_clear_gpios(&dev->serializer, MAX9271_GPIO1OUT); - if (ret) - return ret; - usleep_range(10000, 15000); - ret = max9271_set_gpios(&dev->serializer, MAX9271_GPIO1OUT); if (ret) return ret; - usleep_range(10000, 15000); + usleep_range(100, 500); again: ret = ov10635_read16(dev, OV10635_PID); From 50e7a31d30e8221632675abed3be306382324ca2 Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Wed, 16 Jun 2021 17:19:06 +0200 Subject: [PATCH 391/394] media: Fix Media Controller API config checks Smatch static checker warns that "mdev" can be null: sound/usb/media.c:287 snd_media_device_create() warn: 'mdev' can also be NULL If CONFIG_MEDIA_CONTROLLER is disabled, this file should not be included in the build. The below conditions in the sound/usb/Makefile are in place to ensure that media.c isn't included in the build. sound/usb/Makefile: snd-usb-audio-$(CONFIG_SND_USB_AUDIO_USE_MEDIA_CONTROLLER) += media.o select SND_USB_AUDIO_USE_MEDIA_CONTROLLER if MEDIA_CONTROLLER && (MEDIA_SUPPORT=y || MEDIA_SUPPORT=SND_USB_AUDIO) The following config check in include/media/media-dev-allocator.h is in place to enable the API only when CONFIG_MEDIA_CONTROLLER and CONFIG_USB are enabled. #if defined(CONFIG_MEDIA_CONTROLLER) && defined(CONFIG_USB) This check doesn't work as intended when CONFIG_USB=m. When CONFIG_USB=m, CONFIG_USB_MODULE is defined and CONFIG_USB is not. The above config check doesn't catch that CONFIG_USB is defined as a module and disables the API. This results in sound/usb enabling Media Controller specific ALSA driver code, while Media disables the Media Controller API. Fix the problem requires two changes: 1. Change the check to use IS_ENABLED to detect when CONFIG_USB is enabled as a module or static. Since CONFIG_MEDIA_CONTROLLER is a bool, leave the check unchanged to be consistent with drivers/media/Makefile. 2. Change the drivers/media/mc/Makefile to include mc-dev-allocator.o in mc-objs when CONFIG_USB is enabled. Link: https://lore.kernel.org/alsa-devel/YLeAvT+R22FQ%2FEyw@mwanda/ Reported-by: Dan Carpenter Signed-off-by: Shuah Khan Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/mc/Makefile | 2 +- include/media/media-dev-allocator.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/mc/Makefile b/drivers/media/mc/Makefile index 119037f0e686..2b7af42ba59c 100644 --- a/drivers/media/mc/Makefile +++ b/drivers/media/mc/Makefile @@ -3,7 +3,7 @@ mc-objs := mc-device.o mc-devnode.o mc-entity.o \ mc-request.o -ifeq ($(CONFIG_USB),y) +ifneq ($(CONFIG_USB),) mc-objs += mc-dev-allocator.o endif diff --git a/include/media/media-dev-allocator.h b/include/media/media-dev-allocator.h index b35ea6062596..2ab54d426c64 100644 --- a/include/media/media-dev-allocator.h +++ b/include/media/media-dev-allocator.h @@ -19,7 +19,7 @@ struct usb_device; -#if defined(CONFIG_MEDIA_CONTROLLER) && defined(CONFIG_USB) +#if defined(CONFIG_MEDIA_CONTROLLER) && IS_ENABLED(CONFIG_USB) /** * media_device_usb_allocate() - Allocate and return struct &media device * From 95778c2d0979618e3349b1d2324ec282a5a6adbf Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 22 Mar 2021 15:44:08 +0100 Subject: [PATCH 392/394] media: video-mux: Skip dangling endpoints i.MX6 device tree include files contain dangling endpoints for the board device tree writers' convenience. These are still included in many existing device trees. Treat dangling endpoints as non-existent to support them. Signed-off-by: Philipp Zabel Signed-off-by: Hans Verkuil Fixes: 612b385efb1e ("media: video-mux: Create media links in bound notifier") Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/video-mux.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/video-mux.c b/drivers/media/platform/video-mux.c index f7e2a5e48ccf..905005e271ca 100644 --- a/drivers/media/platform/video-mux.c +++ b/drivers/media/platform/video-mux.c @@ -364,7 +364,7 @@ static int video_mux_async_register(struct video_mux *vmux, for (i = 0; i < num_input_pads; i++) { struct v4l2_async_subdev *asd; - struct fwnode_handle *ep; + struct fwnode_handle *ep, *remote_ep; ep = fwnode_graph_get_endpoint_by_id( dev_fwnode(vmux->subdev.dev), i, 0, @@ -372,6 +372,14 @@ static int video_mux_async_register(struct video_mux *vmux, if (!ep) continue; + /* Skip dangling endpoints for backwards compatibility */ + remote_ep = fwnode_graph_get_remote_endpoint(ep); + if (!remote_ep) { + fwnode_handle_put(ep); + continue; + } + fwnode_handle_put(remote_ep); + asd = v4l2_async_notifier_add_fwnode_remote_subdev( &vmux->notifier, ep, struct v4l2_async_subdev); From 11420749c6b4b237361750de3d5b5579175f8622 Mon Sep 17 00:00:00 2001 From: Dafna Hirschfeld Date: Fri, 23 Apr 2021 19:27:45 +0200 Subject: [PATCH 393/394] media: mtk-vpu: on suspend, read/write regs only if vpu is running If the vpu is not running, we should not rely on VPU_IDLE_REG value. In this case, the suspend cb should only unprepare the clock. This fixes a system-wide suspend to ram failure: [ 273.073363] PM: suspend entry (deep) [ 273.410502] mtk-msdc 11230000.mmc: phase: [map:ffffffff] [maxlen:32] [final:10] [ 273.455926] Filesystems sync: 0.378 seconds [ 273.589707] Freezing user space processes ... (elapsed 0.003 seconds) done. [ 273.600104] OOM killer disabled. [ 273.603409] Freezing remaining freezable tasks ... (elapsed 0.001 seconds) done. [ 273.613361] mwifiex_sdio mmc2:0001:1: None of the WOWLAN triggers enabled [ 274.784952] mtk_vpu 10020000.vpu: vpu idle timeout [ 274.789764] PM: dpm_run_callback(): platform_pm_suspend+0x0/0x70 returns -5 [ 274.796740] mtk_vpu 10020000.vpu: PM: failed to suspend: error -5 [ 274.802842] PM: Some devices failed to suspend, or early wake event detected [ 275.426489] OOM killer enabled. [ 275.429718] Restarting tasks ... [ 275.435765] done. [ 275.447510] PM: suspend exit Fixes: 1f565e263c3e ("media: mtk-vpu: VPU should be in idle state before system is suspended") Signed-off-by: Dafna Hirschfeld Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mtk-vpu/mtk_vpu.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/media/platform/mtk-vpu/mtk_vpu.c b/drivers/media/platform/mtk-vpu/mtk_vpu.c index ef458b417fa7..ec290dde59cf 100644 --- a/drivers/media/platform/mtk-vpu/mtk_vpu.c +++ b/drivers/media/platform/mtk-vpu/mtk_vpu.c @@ -985,6 +985,12 @@ static int mtk_vpu_suspend(struct device *dev) return ret; } + if (!vpu_running(vpu)) { + vpu_clock_disable(vpu); + clk_unprepare(vpu->clk); + return 0; + } + mutex_lock(&vpu->vpu_mutex); /* disable vpu timer interrupt */ vpu_cfg_writel(vpu, vpu_cfg_readl(vpu, VPU_INT_STATUS) | VPU_IDLE_STATE, From 61c6f04a988e420a1fc5e8e81cf9aebf142a7bd6 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Fri, 23 Apr 2021 22:44:57 +0200 Subject: [PATCH 394/394] media: s5p-mfc: Fix display delay control creation v4l2_ctrl_new_std() fails if the caller provides no 'step' parameter for integer control, so define it to fix following error: s5p_mfc_dec_ctrls_setup:1166: Adding control (1) failed Fixes: c3042bff918a ("media: s5p-mfc: Use display delay and display enable std controls") Signed-off-by: Marek Szyprowski Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-mfc/s5p_mfc_dec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c index a92a9ca6e87e..c1d3bda8385b 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c @@ -172,6 +172,7 @@ static struct mfc_control controls[] = { .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 0, .maximum = 16383, + .step = 1, .default_value = 0, }, {