linux/drivers/media/platform/nxp/imx8mq-mipi-csi2.c

1118 lines
28 KiB
C
Raw Permalink Normal View History

// SPDX-License-Identifier: GPL-2.0
/*
* NXP i.MX8MQ SoC series MIPI-CSI2 receiver driver
*
* Copyright (C) 2021 Purism SPC
*/
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/interconnect.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/reset.h>
#include <linux/spinlock.h>
#include <media/v4l2-common.h>
#include <media/v4l2-device.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-mc.h>
#include <media/v4l2-subdev.h>
#define MIPI_CSI2_DRIVER_NAME "imx8mq-mipi-csi2"
#define MIPI_CSI2_SUBDEV_NAME MIPI_CSI2_DRIVER_NAME
#define MIPI_CSI2_PAD_SINK 0
#define MIPI_CSI2_PAD_SOURCE 1
#define MIPI_CSI2_PADS_NUM 2
#define MIPI_CSI2_DEF_PIX_WIDTH 640
#define MIPI_CSI2_DEF_PIX_HEIGHT 480
/* Register map definition */
/* i.MX8MQ CSI-2 controller CSR */
#define CSI2RX_CFG_NUM_LANES 0x100
#define CSI2RX_CFG_DISABLE_DATA_LANES 0x104
#define CSI2RX_BIT_ERR 0x108
#define CSI2RX_IRQ_STATUS 0x10c
#define CSI2RX_IRQ_MASK 0x110
#define CSI2RX_IRQ_MASK_ALL 0x1ff
#define CSI2RX_IRQ_MASK_ULPS_STATUS_CHANGE 0x8
#define CSI2RX_ULPS_STATUS 0x114
#define CSI2RX_PPI_ERRSOT_HS 0x118
#define CSI2RX_PPI_ERRSOTSYNC_HS 0x11c
#define CSI2RX_PPI_ERRESC 0x120
#define CSI2RX_PPI_ERRSYNCESC 0x124
#define CSI2RX_PPI_ERRCONTROL 0x128
#define CSI2RX_CFG_DISABLE_PAYLOAD_0 0x12c
#define CSI2RX_CFG_VID_VC_IGNORE 0x180
#define CSI2RX_CFG_VID_VC 0x184
#define CSI2RX_CFG_VID_P_FIFO_SEND_LEVEL 0x188
#define CSI2RX_CFG_DISABLE_PAYLOAD_1 0x130
struct csi_state;
enum {
ST_POWERED = 1,
ST_STREAMING = 2,
ST_SUSPENDED = 4,
};
enum imx8mq_mipi_csi_clk {
CSI2_CLK_CORE,
CSI2_CLK_ESC,
CSI2_CLK_UI,
CSI2_NUM_CLKS,
};
static const char * const imx8mq_mipi_csi_clk_id[CSI2_NUM_CLKS] = {
[CSI2_CLK_CORE] = "core",
[CSI2_CLK_ESC] = "esc",
[CSI2_CLK_UI] = "ui",
};
#define CSI2_NUM_CLKS ARRAY_SIZE(imx8mq_mipi_csi_clk_id)
struct imx8mq_plat_data {
int (*enable)(struct csi_state *state, u32 hs_settle);
void (*disable)(struct csi_state *state);
bool use_reg_csr;
};
/*
* The send level configures the number of entries that must accumulate in
* the Pixel FIFO before the data will be transferred to the video output.
* The exact value needed for this configuration is dependent on the rate at
* which the sensor transfers data to the CSI-2 Controller and the user
* video clock.
*
* The calculation is the classical rate-in rate-out type of problem: If the
* video bandwidth is 10% faster than the incoming mipi data and the video
* line length is 500 pixels, then the fifo should be allowed to fill
* 10% of the line length or 50 pixels. If the gap data is ok, then the level
* can be set to 16 and ignored.
*/
#define CSI2RX_SEND_LEVEL 64
struct csi_state {
struct device *dev;
const struct imx8mq_plat_data *pdata;
void __iomem *regs;
struct clk_bulk_data clks[CSI2_NUM_CLKS];
struct reset_control *rst;
struct regulator *mipi_phy_regulator;
struct v4l2_subdev sd;
struct media_pad pads[MIPI_CSI2_PADS_NUM];
struct v4l2_async_notifier notifier;
struct v4l2_subdev *src_sd;
struct v4l2_mbus_config_mipi_csi2 bus;
struct mutex lock; /* Protect state */
u32 state;
struct regmap *phy_gpr;
u8 phy_gpr_reg;
struct icc_path *icc_path;
s32 icc_path_bw;
};
/* -----------------------------------------------------------------------------
* Format helpers
*/
struct csi2_pix_format {
u32 code;
u8 width;
};
/* -----------------------------------------------------------------------------
* i.MX8MQ GPR
*/
#define GPR_CSI2_1_RX_ENABLE BIT(13)
#define GPR_CSI2_1_VID_INTFC_ENB BIT(12)
#define GPR_CSI2_1_HSEL BIT(10)
#define GPR_CSI2_1_CONT_CLK_MODE BIT(8)
#define GPR_CSI2_1_S_PRG_RXHS_SETTLE(x) (((x) & 0x3f) << 2)
static int imx8mq_gpr_enable(struct csi_state *state, u32 hs_settle)
{
regmap_update_bits(state->phy_gpr,
state->phy_gpr_reg,
0x3fff,
GPR_CSI2_1_RX_ENABLE |
GPR_CSI2_1_VID_INTFC_ENB |
GPR_CSI2_1_HSEL |
GPR_CSI2_1_CONT_CLK_MODE |
GPR_CSI2_1_S_PRG_RXHS_SETTLE(hs_settle));
return 0;
}
static const struct imx8mq_plat_data imx8mq_data = {
.enable = imx8mq_gpr_enable,
};
/* -----------------------------------------------------------------------------
* i.MX8QXP
*/
#define CSI2SS_PL_CLK_INTERVAL_US 100
#define CSI2SS_PL_CLK_TIMEOUT_US 100000
#define CSI2SS_PLM_CTRL 0x0
#define CSI2SS_PLM_CTRL_ENABLE_PL BIT(0)
#define CSI2SS_PLM_CTRL_VSYNC_OVERRIDE BIT(9)
#define CSI2SS_PLM_CTRL_HSYNC_OVERRIDE BIT(10)
#define CSI2SS_PLM_CTRL_VALID_OVERRIDE BIT(11)
#define CSI2SS_PLM_CTRL_POLARITY_HIGH BIT(12)
#define CSI2SS_PLM_CTRL_PL_CLK_RUN BIT(31)
#define CSI2SS_PHY_CTRL 0x4
#define CSI2SS_PHY_CTRL_RX_ENABLE BIT(0)
#define CSI2SS_PHY_CTRL_AUTO_PD_EN BIT(1)
#define CSI2SS_PHY_CTRL_DDRCLK_EN BIT(2)
#define CSI2SS_PHY_CTRL_CONT_CLK_MODE BIT(3)
#define CSI2SS_PHY_CTRL_RX_HS_SETTLE_MASK GENMASK(9, 4)
#define CSI2SS_PHY_CTRL_RTERM_SEL BIT(21)
#define CSI2SS_PHY_CTRL_PD BIT(22)
#define CSI2SS_DATA_TYPE_DISABLE_BF 0x38
#define CSI2SS_DATA_TYPE_DISABLE_BF_MASK GENMASK(23, 0)
#define CSI2SS_CTRL_CLK_RESET 0x44
#define CSI2SS_CTRL_CLK_RESET_EN BIT(0)
static int imx8qxp_gpr_enable(struct csi_state *state, u32 hs_settle)
{
int ret;
u32 val;
/* Clear format */
regmap_clear_bits(state->phy_gpr, CSI2SS_DATA_TYPE_DISABLE_BF,
CSI2SS_DATA_TYPE_DISABLE_BF_MASK);
regmap_write(state->phy_gpr, CSI2SS_PLM_CTRL, 0x0);
regmap_write(state->phy_gpr, CSI2SS_PHY_CTRL,
FIELD_PREP(CSI2SS_PHY_CTRL_RX_HS_SETTLE_MASK, hs_settle) |
CSI2SS_PHY_CTRL_RX_ENABLE | CSI2SS_PHY_CTRL_DDRCLK_EN |
CSI2SS_PHY_CTRL_CONT_CLK_MODE | CSI2SS_PHY_CTRL_PD |
CSI2SS_PHY_CTRL_RTERM_SEL | CSI2SS_PHY_CTRL_AUTO_PD_EN);
ret = regmap_read_poll_timeout(state->phy_gpr, CSI2SS_PLM_CTRL,
val, !(val & CSI2SS_PLM_CTRL_PL_CLK_RUN),
CSI2SS_PL_CLK_INTERVAL_US,
CSI2SS_PL_CLK_TIMEOUT_US);
if (ret) {
dev_err(state->dev, "Timeout waiting for Pixel-Link clock\n");
return ret;
}
/* Enable Pixel link Master */
regmap_set_bits(state->phy_gpr, CSI2SS_PLM_CTRL,
CSI2SS_PLM_CTRL_ENABLE_PL | CSI2SS_PLM_CTRL_VALID_OVERRIDE);
/* PHY Enable */
regmap_clear_bits(state->phy_gpr, CSI2SS_PHY_CTRL,
CSI2SS_PHY_CTRL_PD | CSI2SS_PLM_CTRL_POLARITY_HIGH);
/* Release Reset */
regmap_set_bits(state->phy_gpr, CSI2SS_CTRL_CLK_RESET, CSI2SS_CTRL_CLK_RESET_EN);
return ret;
}
static void imx8qxp_gpr_disable(struct csi_state *state)
{
/* Disable Pixel Link */
regmap_write(state->phy_gpr, CSI2SS_PLM_CTRL, 0x0);
/* Disable PHY */
regmap_write(state->phy_gpr, CSI2SS_PHY_CTRL, 0x0);
regmap_clear_bits(state->phy_gpr, CSI2SS_CTRL_CLK_RESET,
CSI2SS_CTRL_CLK_RESET_EN);
};
static const struct imx8mq_plat_data imx8qxp_data = {
.enable = imx8qxp_gpr_enable,
.disable = imx8qxp_gpr_disable,
.use_reg_csr = true,
};
static const struct csi2_pix_format imx8mq_mipi_csi_formats[] = {
/* RAW (Bayer and greyscale) formats. */
{
.code = MEDIA_BUS_FMT_SBGGR8_1X8,
.width = 8,
}, {
.code = MEDIA_BUS_FMT_SGBRG8_1X8,
.width = 8,
}, {
.code = MEDIA_BUS_FMT_SGRBG8_1X8,
.width = 8,
}, {
.code = MEDIA_BUS_FMT_SRGGB8_1X8,
.width = 8,
}, {
.code = MEDIA_BUS_FMT_Y8_1X8,
.width = 8,
}, {
.code = MEDIA_BUS_FMT_SBGGR10_1X10,
.width = 10,
}, {
.code = MEDIA_BUS_FMT_SGBRG10_1X10,
.width = 10,
}, {
.code = MEDIA_BUS_FMT_SGRBG10_1X10,
.width = 10,
}, {
.code = MEDIA_BUS_FMT_SRGGB10_1X10,
.width = 10,
}, {
.code = MEDIA_BUS_FMT_Y10_1X10,
.width = 10,
}, {
.code = MEDIA_BUS_FMT_SBGGR12_1X12,
.width = 12,
}, {
.code = MEDIA_BUS_FMT_SGBRG12_1X12,
.width = 12,
}, {
.code = MEDIA_BUS_FMT_SGRBG12_1X12,
.width = 12,
}, {
.code = MEDIA_BUS_FMT_SRGGB12_1X12,
.width = 12,
}, {
.code = MEDIA_BUS_FMT_Y12_1X12,
.width = 12,
}, {
.code = MEDIA_BUS_FMT_SBGGR14_1X14,
.width = 14,
}, {
.code = MEDIA_BUS_FMT_SGBRG14_1X14,
.width = 14,
}, {
.code = MEDIA_BUS_FMT_SGRBG14_1X14,
.width = 14,
}, {
.code = MEDIA_BUS_FMT_SRGGB14_1X14,
.width = 14,
},
/* YUV formats */
{
.code = MEDIA_BUS_FMT_YUYV8_1X16,
.width = 16,
}, {
.code = MEDIA_BUS_FMT_UYVY8_1X16,
.width = 16,
}
};
static const struct csi2_pix_format *find_csi2_format(u32 code)
{
unsigned int i;
for (i = 0; i < ARRAY_SIZE(imx8mq_mipi_csi_formats); i++)
if (code == imx8mq_mipi_csi_formats[i].code)
return &imx8mq_mipi_csi_formats[i];
return NULL;
}
/* -----------------------------------------------------------------------------
* Hardware configuration
*/
static inline void imx8mq_mipi_csi_write(struct csi_state *state, u32 reg, u32 val)
{
writel(val, state->regs + reg);
}
static int imx8mq_mipi_csi_sw_reset(struct csi_state *state)
{
int ret;
/*
* these are most likely self-clearing reset bits. to make it
* more clear, the reset-imx7 driver should implement the
* .reset() operation.
*/
ret = reset_control_assert(state->rst);
if (ret < 0) {
dev_err(state->dev, "Failed to assert resets: %d\n", ret);
return ret;
}
return 0;
}
static void imx8mq_mipi_csi_set_params(struct csi_state *state)
{
int lanes = state->bus.num_data_lanes;
imx8mq_mipi_csi_write(state, CSI2RX_CFG_NUM_LANES, lanes - 1);
imx8mq_mipi_csi_write(state, CSI2RX_CFG_DISABLE_DATA_LANES,
(0xf << lanes) & 0xf);
imx8mq_mipi_csi_write(state, CSI2RX_IRQ_MASK, CSI2RX_IRQ_MASK_ALL);
/*
* 0x180 bit 0 controls the Virtual Channel behaviour: when set the
* interface ignores the Virtual Channel (VC) field in received packets;
* when cleared it causes the interface to only accept packets whose VC
* matches the value to which VC is set at offset 0x184.
*/
imx8mq_mipi_csi_write(state, CSI2RX_CFG_VID_VC_IGNORE, 1);
imx8mq_mipi_csi_write(state, CSI2RX_CFG_VID_P_FIFO_SEND_LEVEL,
CSI2RX_SEND_LEVEL);
}
static int imx8mq_mipi_csi_clk_enable(struct csi_state *state)
{
return clk_bulk_prepare_enable(CSI2_NUM_CLKS, state->clks);
}
static void imx8mq_mipi_csi_clk_disable(struct csi_state *state)
{
clk_bulk_disable_unprepare(CSI2_NUM_CLKS, state->clks);
}
static int imx8mq_mipi_csi_clk_get(struct csi_state *state)
{
unsigned int i;
for (i = 0; i < CSI2_NUM_CLKS; i++)
state->clks[i].id = imx8mq_mipi_csi_clk_id[i];
return devm_clk_bulk_get(state->dev, CSI2_NUM_CLKS, state->clks);
}
static int imx8mq_mipi_csi_calc_hs_settle(struct csi_state *state,
struct v4l2_subdev_state *sd_state,
u32 *hs_settle)
{
struct media_pad *src_pad;
s64 link_freq;
u32 lane_rate;
unsigned long esc_clk_rate;
u32 min_ths_settle, max_ths_settle, ths_settle_ns, esc_clk_period_ns;
const struct v4l2_mbus_framefmt *fmt;
const struct csi2_pix_format *csi2_fmt;
src_pad = media_entity_remote_source_pad_unique(&sd_state->sd->entity);
if (IS_ERR(src_pad)) {
dev_err(state->dev, "can't get source pad of %s (%ld)\n",
sd_state->sd->name, PTR_ERR(src_pad));
return PTR_ERR(src_pad);
}
/* Calculate the line rate from the pixel rate. */
media: v4l: subdev: Switch to stream-aware state functions Switch all drivers accessing sub-device state to use the stream-aware functions. We will soon remove the old ones. This patch has been generated using the following Coccinelle script: ---------8<------------ @@ expression E1, E2, E3; @@ - v4l2_subdev_get_pad_format(E1, E2, E3) + v4l2_subdev_state_get_format(E2, E3) @@ expression E1, E2, E3; @@ - v4l2_subdev_get_pad_crop(E1, E2, E3) + v4l2_subdev_state_get_crop(E2, E3) @@ expression E1, E2, E3; @@ - v4l2_subdev_get_pad_compose(E1, E2, E3) + v4l2_subdev_state_get_compose(E2, E3) @@ expression E1, E2, E3; @@ - v4l2_subdev_get_try_format(E1, E2, E3) + v4l2_subdev_state_get_format(E2, E3) @@ expression E1, E2, E3; @@ - v4l2_subdev_get_try_crop(E1, E2, E3) + v4l2_subdev_state_get_crop(E2, E3) @@ expression E1, E2, E3; @@ - v4l2_subdev_get_try_compose(E1, E2, E3) + v4l2_subdev_state_get_compose(E2, E3) ---------8<------------ Additionally drivers/media/i2c/s5k5baf.c and drivers/media/platform/samsung/s3c-camif/camif-capture.c have been manually changed as Coccinelle didn't. Further local variables have been removed as they became unused as a result of the other changes. Also Coccinelle introduced indentation by space in files drivers/media/i2c/st-mipid02.c and drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c. This has been also corrected. The diff from Coccinelle-generated changes are: > diff --git b/drivers/media/i2c/imx319.c a/drivers/media/i2c/imx319.c > index e549692ff478..420984382173 100644 > --- b/drivers/media/i2c/imx319.c > +++ a/drivers/media/i2c/imx319.c > @@ -2001,7 +2001,6 @@ static int imx319_do_get_pad_format(struct imx319 *imx319, > 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_state_get_format(sd_state, fmt->pad); > diff --git b/drivers/media/i2c/imx355.c a/drivers/media/i2c/imx355.c > index 96bdde685d65..e1b1d2fc79dd 100644 > --- b/drivers/media/i2c/imx355.c > +++ a/drivers/media/i2c/imx355.c > @@ -1299,7 +1299,6 @@ static int imx355_do_get_pad_format(struct imx355 *imx355, > 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_state_get_format(sd_state, fmt->pad); > diff --git b/drivers/media/i2c/ov08x40.c a/drivers/media/i2c/ov08x40.c > index ca799bbcfdb7..abbb0b774d43 100644 > --- b/drivers/media/i2c/ov08x40.c > +++ a/drivers/media/i2c/ov08x40.c > @@ -2774,7 +2774,6 @@ static int ov08x40_do_get_pad_format(struct ov08x40 *ov08x, > struct v4l2_subdev_format *fmt) > { > struct v4l2_mbus_framefmt *framefmt; > - struct v4l2_subdev *sd = &ov08x->sd; > > if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { > framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad); > diff --git b/drivers/media/i2c/ov13858.c a/drivers/media/i2c/ov13858.c > index 7816d9787c61..09387e335d80 100644 > --- b/drivers/media/i2c/ov13858.c > +++ a/drivers/media/i2c/ov13858.c > @@ -1316,7 +1316,6 @@ static int ov13858_do_get_pad_format(struct ov13858 *ov13858, > 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_state_get_format(sd_state, fmt->pad); > diff --git b/drivers/media/i2c/ov13b10.c a/drivers/media/i2c/ov13b10.c > index 268cd4b03f9c..c06411d5ee2b 100644 > --- b/drivers/media/i2c/ov13b10.c > +++ a/drivers/media/i2c/ov13b10.c > @@ -1001,7 +1001,6 @@ static int ov13b10_do_get_pad_format(struct ov13b10 *ov13b, > struct v4l2_subdev_format *fmt) > { > struct v4l2_mbus_framefmt *framefmt; > - struct v4l2_subdev *sd = &ov13b->sd; > > if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { > framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad); > diff --git b/drivers/media/i2c/s5c73m3/s5c73m3-core.c a/drivers/media/i2c/s5c73m3/s5c73m3-core.c > index 47605e36bc60..8f9b5713daf7 100644 > --- b/drivers/media/i2c/s5c73m3/s5c73m3-core.c > +++ a/drivers/media/i2c/s5c73m3/s5c73m3-core.c > @@ -819,7 +819,6 @@ static void s5c73m3_oif_try_format(struct s5c73m3 *state, > struct v4l2_subdev_format *fmt, > const struct s5c73m3_frame_size **fs) > { > - struct v4l2_subdev *sd = &state->sensor_sd; > u32 code; > > switch (fmt->pad) { > diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c > index 67da2045f543..03ccfb0e1e11 100644 > --- a/drivers/media/i2c/s5k5baf.c > +++ b/drivers/media/i2c/s5k5baf.c > @@ -1472,14 +1472,11 @@ 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, 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_cis_rect, > + v4l2_subdev_state_get_crop(sd_state, PAD_CIS), > + v4l2_subdev_state_get_compose(sd_state, PAD_CIS), > + v4l2_subdev_state_get_crop(sd_state, PAD_OUT) > + }; > s5k5baf_set_rect_and_adjust(rects, rtype, &sel->r); > return 0; > } > diff --git b/drivers/media/platform/samsung/s3c-camif/camif-capture.c a/drivers/media/platform/samsung/s3c-camif/camif-capture.c > index 295e083f38e8..be58260ea67e 100644 > --- b/drivers/media/platform/samsung/s3c-camif/camif-capture.c > +++ a/drivers/media/platform/samsung/s3c-camif/camif-capture.c > @@ -1216,7 +1216,7 @@ static int s3c_camif_subdev_get_fmt(struct v4l2_subdev *sd, > struct v4l2_mbus_framefmt *mf = &fmt->format; > > if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { > - mf = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); > + mf = v4l2_subdev_state_get_format(sd_state, fmt->pad); > fmt->format = *mf; > return 0; > } > @@ -1305,7 +1305,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, sd_state, fmt->pad); > + mf = v4l2_subdev_state_get_format(sd_state, fmt->pad); > *mf = fmt->format; > mutex_unlock(&camif->lock); > return 0; > diff --git b/drivers/media/platform/ti/cal/cal-camerarx.c a/drivers/media/platform/ti/cal/cal-camerarx.c > index cea454ed9c20..61433744c6c4 100644 > --- b/drivers/media/platform/ti/cal/cal-camerarx.c > +++ a/drivers/media/platform/ti/cal/cal-camerarx.c > @@ -621,8 +621,6 @@ static int cal_camerarx_sd_enum_mbus_code(struct v4l2_subdev *sd, > struct v4l2_subdev_state *state, > struct v4l2_subdev_mbus_code_enum *code) > { > - struct cal_camerarx *phy = to_cal_camerarx(sd); > - > /* No transcoding, source and sink codes must match. */ > if (cal_rx_pad_is_source(code->pad)) { > struct v4l2_mbus_framefmt *fmt; > diff --git b/drivers/staging/media/imx/imx-ic-prp.c a/drivers/staging/media/imx/imx-ic-prp.c > index dd558fac6477..61d69f19657e 100644 > --- b/drivers/staging/media/imx/imx-ic-prp.c > +++ a/drivers/staging/media/imx/imx-ic-prp.c > @@ -82,8 +82,6 @@ static struct v4l2_mbus_framefmt * > __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_state_get_format(sd_state, pad); > else > diff --git b/drivers/staging/media/imx/imx-ic-prpencvf.c a/drivers/staging/media/imx/imx-ic-prpencvf.c > index 02db7dbb884b..ec73c901079e 100644 > --- b/drivers/staging/media/imx/imx-ic-prpencvf.c > +++ a/drivers/staging/media/imx/imx-ic-prpencvf.c > @@ -790,8 +790,6 @@ static struct v4l2_mbus_framefmt * > __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_state_get_format(sd_state, pad); > else > diff --git a/drivers/media/i2c/st-mipid02.c b/drivers/media/i2c/st-mipid02.c > index 9c9361354c00..b08a249b5fdd 100644 > --- a/drivers/media/i2c/st-mipid02.c > +++ b/drivers/media/i2c/st-mipid02.c > @@ -751,7 +751,7 @@ static void mipid02_set_fmt_source(struct v4l2_subdev *sd, > format->format = bridge->fmt; > else > format->format = *v4l2_subdev_state_get_format(sd_state, > - MIPID02_SINK_0); > + MIPID02_SINK_0); > > /* but code may need to be converted */ > format->format.code = serial_to_parallel_code(format->format.code); > diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c > index 117912d3bfbd..96353648c032 100644 > --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c > +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c > @@ -319,7 +319,7 @@ static void rkisp1_isp_start(struct rkisp1_isp *isp, > rkisp1_write(rkisp1, RKISP1_CIF_ISP_CTRL, val); > > src_fmt = v4l2_subdev_state_get_format(sd_state, > - RKISP1_ISP_PAD_SOURCE_VIDEO); > + RKISP1_ISP_PAD_SOURCE_VIDEO); > src_info = rkisp1_mbus_info_get_by_code(src_fmt->code); > > if (src_info->pixel_enc != V4L2_PIXEL_ENC_BAYER) > @@ -475,9 +475,9 @@ static void rkisp1_isp_set_src_fmt(struct rkisp1_isp *isp, > sink_fmt = v4l2_subdev_state_get_format(sd_state, > RKISP1_ISP_PAD_SINK_VIDEO); > src_fmt = v4l2_subdev_state_get_format(sd_state, > - RKISP1_ISP_PAD_SOURCE_VIDEO); > + RKISP1_ISP_PAD_SOURCE_VIDEO); > src_crop = v4l2_subdev_state_get_crop(sd_state, > - RKISP1_ISP_PAD_SOURCE_VIDEO); > + RKISP1_ISP_PAD_SOURCE_VIDEO); > > /* > * Media bus code. The ISP can operate in pass-through mode (Bayer in, Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
2023-10-13 09:37:10 +02:00
fmt = v4l2_subdev_state_get_format(sd_state, MIPI_CSI2_PAD_SINK);
csi2_fmt = find_csi2_format(fmt->code);
link_freq = v4l2_get_link_freq(src_pad, csi2_fmt->width,
state->bus.num_data_lanes * 2);
if (link_freq < 0) {
dev_err(state->dev, "Unable to obtain link frequency: %d\n",
(int)link_freq);
return link_freq;
}
lane_rate = link_freq * 2;
if (lane_rate < 80000000 || lane_rate > 1500000000) {
dev_dbg(state->dev, "Out-of-bound lane rate %u\n", lane_rate);
return -EINVAL;
}
/*
* The D-PHY specification requires Ths-settle to be in the range
* 85ns + 6*UI to 140ns + 10*UI, with the unit interval UI being half
* the clock period.
*
* The Ths-settle value is expressed in the hardware as a multiple of
* the Esc clock period:
*
* Ths-settle = (PRG_RXHS_SETTLE + 1) * Tperiod of RxClkInEsc
*
* Due to the one cycle inaccuracy introduced by rounding, the
* documentation recommends picking a value away from the boundaries.
* Let's pick the average.
*/
esc_clk_rate = clk_get_rate(state->clks[CSI2_CLK_ESC].clk);
if (!esc_clk_rate) {
dev_err(state->dev, "Could not get esc clock rate.\n");
return -EINVAL;
}
dev_dbg(state->dev, "esc clk rate: %lu\n", esc_clk_rate);
esc_clk_period_ns = 1000000000 / esc_clk_rate;
min_ths_settle = 85 + 6 * 1000000 / (lane_rate / 1000);
max_ths_settle = 140 + 10 * 1000000 / (lane_rate / 1000);
ths_settle_ns = (min_ths_settle + max_ths_settle) / 2;
*hs_settle = ths_settle_ns / esc_clk_period_ns - 1;
dev_dbg(state->dev, "lane rate %u Ths_settle %u hs_settle %u\n",
lane_rate, ths_settle_ns, *hs_settle);
return 0;
}
static int imx8mq_mipi_csi_start_stream(struct csi_state *state,
struct v4l2_subdev_state *sd_state)
{
int ret;
u32 hs_settle = 0;
ret = imx8mq_mipi_csi_sw_reset(state);
if (ret)
return ret;
imx8mq_mipi_csi_set_params(state);
ret = imx8mq_mipi_csi_calc_hs_settle(state, sd_state, &hs_settle);
if (ret)
return ret;
ret = state->pdata->enable(state, hs_settle);
if (ret)
return ret;
return 0;
}
static void imx8mq_mipi_csi_stop_stream(struct csi_state *state)
{
imx8mq_mipi_csi_write(state, CSI2RX_CFG_DISABLE_DATA_LANES, 0xf);
if (state->pdata->disable)
state->pdata->disable(state);
}
/* -----------------------------------------------------------------------------
* V4L2 subdev operations
*/
static struct csi_state *mipi_sd_to_csi2_state(struct v4l2_subdev *sdev)
{
return container_of(sdev, struct csi_state, sd);
}
static int imx8mq_mipi_csi_s_stream(struct v4l2_subdev *sd, int enable)
{
struct csi_state *state = mipi_sd_to_csi2_state(sd);
struct v4l2_subdev_state *sd_state;
int ret = 0;
if (enable) {
ret = pm_runtime_resume_and_get(state->dev);
if (ret < 0)
return ret;
}
mutex_lock(&state->lock);
if (enable) {
if (state->state & ST_SUSPENDED) {
ret = -EBUSY;
goto unlock;
}
sd_state = v4l2_subdev_lock_and_get_active_state(sd);
ret = imx8mq_mipi_csi_start_stream(state, sd_state);
v4l2_subdev_unlock_state(sd_state);
if (ret < 0)
goto unlock;
ret = v4l2_subdev_call(state->src_sd, video, s_stream, 1);
if (ret < 0)
goto unlock;
state->state |= ST_STREAMING;
} else {
v4l2_subdev_call(state->src_sd, video, s_stream, 0);
imx8mq_mipi_csi_stop_stream(state);
state->state &= ~ST_STREAMING;
}
unlock:
mutex_unlock(&state->lock);
if (!enable || ret < 0)
pm_runtime_put(state->dev);
return ret;
}
static int imx8mq_mipi_csi_init_state(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state)
{
struct v4l2_mbus_framefmt *fmt_sink;
struct v4l2_mbus_framefmt *fmt_source;
media: v4l: subdev: Switch to stream-aware state functions Switch all drivers accessing sub-device state to use the stream-aware functions. We will soon remove the old ones. This patch has been generated using the following Coccinelle script: ---------8<------------ @@ expression E1, E2, E3; @@ - v4l2_subdev_get_pad_format(E1, E2, E3) + v4l2_subdev_state_get_format(E2, E3) @@ expression E1, E2, E3; @@ - v4l2_subdev_get_pad_crop(E1, E2, E3) + v4l2_subdev_state_get_crop(E2, E3) @@ expression E1, E2, E3; @@ - v4l2_subdev_get_pad_compose(E1, E2, E3) + v4l2_subdev_state_get_compose(E2, E3) @@ expression E1, E2, E3; @@ - v4l2_subdev_get_try_format(E1, E2, E3) + v4l2_subdev_state_get_format(E2, E3) @@ expression E1, E2, E3; @@ - v4l2_subdev_get_try_crop(E1, E2, E3) + v4l2_subdev_state_get_crop(E2, E3) @@ expression E1, E2, E3; @@ - v4l2_subdev_get_try_compose(E1, E2, E3) + v4l2_subdev_state_get_compose(E2, E3) ---------8<------------ Additionally drivers/media/i2c/s5k5baf.c and drivers/media/platform/samsung/s3c-camif/camif-capture.c have been manually changed as Coccinelle didn't. Further local variables have been removed as they became unused as a result of the other changes. Also Coccinelle introduced indentation by space in files drivers/media/i2c/st-mipid02.c and drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c. This has been also corrected. The diff from Coccinelle-generated changes are: > diff --git b/drivers/media/i2c/imx319.c a/drivers/media/i2c/imx319.c > index e549692ff478..420984382173 100644 > --- b/drivers/media/i2c/imx319.c > +++ a/drivers/media/i2c/imx319.c > @@ -2001,7 +2001,6 @@ static int imx319_do_get_pad_format(struct imx319 *imx319, > 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_state_get_format(sd_state, fmt->pad); > diff --git b/drivers/media/i2c/imx355.c a/drivers/media/i2c/imx355.c > index 96bdde685d65..e1b1d2fc79dd 100644 > --- b/drivers/media/i2c/imx355.c > +++ a/drivers/media/i2c/imx355.c > @@ -1299,7 +1299,6 @@ static int imx355_do_get_pad_format(struct imx355 *imx355, > 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_state_get_format(sd_state, fmt->pad); > diff --git b/drivers/media/i2c/ov08x40.c a/drivers/media/i2c/ov08x40.c > index ca799bbcfdb7..abbb0b774d43 100644 > --- b/drivers/media/i2c/ov08x40.c > +++ a/drivers/media/i2c/ov08x40.c > @@ -2774,7 +2774,6 @@ static int ov08x40_do_get_pad_format(struct ov08x40 *ov08x, > struct v4l2_subdev_format *fmt) > { > struct v4l2_mbus_framefmt *framefmt; > - struct v4l2_subdev *sd = &ov08x->sd; > > if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { > framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad); > diff --git b/drivers/media/i2c/ov13858.c a/drivers/media/i2c/ov13858.c > index 7816d9787c61..09387e335d80 100644 > --- b/drivers/media/i2c/ov13858.c > +++ a/drivers/media/i2c/ov13858.c > @@ -1316,7 +1316,6 @@ static int ov13858_do_get_pad_format(struct ov13858 *ov13858, > 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_state_get_format(sd_state, fmt->pad); > diff --git b/drivers/media/i2c/ov13b10.c a/drivers/media/i2c/ov13b10.c > index 268cd4b03f9c..c06411d5ee2b 100644 > --- b/drivers/media/i2c/ov13b10.c > +++ a/drivers/media/i2c/ov13b10.c > @@ -1001,7 +1001,6 @@ static int ov13b10_do_get_pad_format(struct ov13b10 *ov13b, > struct v4l2_subdev_format *fmt) > { > struct v4l2_mbus_framefmt *framefmt; > - struct v4l2_subdev *sd = &ov13b->sd; > > if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { > framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad); > diff --git b/drivers/media/i2c/s5c73m3/s5c73m3-core.c a/drivers/media/i2c/s5c73m3/s5c73m3-core.c > index 47605e36bc60..8f9b5713daf7 100644 > --- b/drivers/media/i2c/s5c73m3/s5c73m3-core.c > +++ a/drivers/media/i2c/s5c73m3/s5c73m3-core.c > @@ -819,7 +819,6 @@ static void s5c73m3_oif_try_format(struct s5c73m3 *state, > struct v4l2_subdev_format *fmt, > const struct s5c73m3_frame_size **fs) > { > - struct v4l2_subdev *sd = &state->sensor_sd; > u32 code; > > switch (fmt->pad) { > diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c > index 67da2045f543..03ccfb0e1e11 100644 > --- a/drivers/media/i2c/s5k5baf.c > +++ b/drivers/media/i2c/s5k5baf.c > @@ -1472,14 +1472,11 @@ 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, 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_cis_rect, > + v4l2_subdev_state_get_crop(sd_state, PAD_CIS), > + v4l2_subdev_state_get_compose(sd_state, PAD_CIS), > + v4l2_subdev_state_get_crop(sd_state, PAD_OUT) > + }; > s5k5baf_set_rect_and_adjust(rects, rtype, &sel->r); > return 0; > } > diff --git b/drivers/media/platform/samsung/s3c-camif/camif-capture.c a/drivers/media/platform/samsung/s3c-camif/camif-capture.c > index 295e083f38e8..be58260ea67e 100644 > --- b/drivers/media/platform/samsung/s3c-camif/camif-capture.c > +++ a/drivers/media/platform/samsung/s3c-camif/camif-capture.c > @@ -1216,7 +1216,7 @@ static int s3c_camif_subdev_get_fmt(struct v4l2_subdev *sd, > struct v4l2_mbus_framefmt *mf = &fmt->format; > > if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { > - mf = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); > + mf = v4l2_subdev_state_get_format(sd_state, fmt->pad); > fmt->format = *mf; > return 0; > } > @@ -1305,7 +1305,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, sd_state, fmt->pad); > + mf = v4l2_subdev_state_get_format(sd_state, fmt->pad); > *mf = fmt->format; > mutex_unlock(&camif->lock); > return 0; > diff --git b/drivers/media/platform/ti/cal/cal-camerarx.c a/drivers/media/platform/ti/cal/cal-camerarx.c > index cea454ed9c20..61433744c6c4 100644 > --- b/drivers/media/platform/ti/cal/cal-camerarx.c > +++ a/drivers/media/platform/ti/cal/cal-camerarx.c > @@ -621,8 +621,6 @@ static int cal_camerarx_sd_enum_mbus_code(struct v4l2_subdev *sd, > struct v4l2_subdev_state *state, > struct v4l2_subdev_mbus_code_enum *code) > { > - struct cal_camerarx *phy = to_cal_camerarx(sd); > - > /* No transcoding, source and sink codes must match. */ > if (cal_rx_pad_is_source(code->pad)) { > struct v4l2_mbus_framefmt *fmt; > diff --git b/drivers/staging/media/imx/imx-ic-prp.c a/drivers/staging/media/imx/imx-ic-prp.c > index dd558fac6477..61d69f19657e 100644 > --- b/drivers/staging/media/imx/imx-ic-prp.c > +++ a/drivers/staging/media/imx/imx-ic-prp.c > @@ -82,8 +82,6 @@ static struct v4l2_mbus_framefmt * > __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_state_get_format(sd_state, pad); > else > diff --git b/drivers/staging/media/imx/imx-ic-prpencvf.c a/drivers/staging/media/imx/imx-ic-prpencvf.c > index 02db7dbb884b..ec73c901079e 100644 > --- b/drivers/staging/media/imx/imx-ic-prpencvf.c > +++ a/drivers/staging/media/imx/imx-ic-prpencvf.c > @@ -790,8 +790,6 @@ static struct v4l2_mbus_framefmt * > __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_state_get_format(sd_state, pad); > else > diff --git a/drivers/media/i2c/st-mipid02.c b/drivers/media/i2c/st-mipid02.c > index 9c9361354c00..b08a249b5fdd 100644 > --- a/drivers/media/i2c/st-mipid02.c > +++ b/drivers/media/i2c/st-mipid02.c > @@ -751,7 +751,7 @@ static void mipid02_set_fmt_source(struct v4l2_subdev *sd, > format->format = bridge->fmt; > else > format->format = *v4l2_subdev_state_get_format(sd_state, > - MIPID02_SINK_0); > + MIPID02_SINK_0); > > /* but code may need to be converted */ > format->format.code = serial_to_parallel_code(format->format.code); > diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c > index 117912d3bfbd..96353648c032 100644 > --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c > +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c > @@ -319,7 +319,7 @@ static void rkisp1_isp_start(struct rkisp1_isp *isp, > rkisp1_write(rkisp1, RKISP1_CIF_ISP_CTRL, val); > > src_fmt = v4l2_subdev_state_get_format(sd_state, > - RKISP1_ISP_PAD_SOURCE_VIDEO); > + RKISP1_ISP_PAD_SOURCE_VIDEO); > src_info = rkisp1_mbus_info_get_by_code(src_fmt->code); > > if (src_info->pixel_enc != V4L2_PIXEL_ENC_BAYER) > @@ -475,9 +475,9 @@ static void rkisp1_isp_set_src_fmt(struct rkisp1_isp *isp, > sink_fmt = v4l2_subdev_state_get_format(sd_state, > RKISP1_ISP_PAD_SINK_VIDEO); > src_fmt = v4l2_subdev_state_get_format(sd_state, > - RKISP1_ISP_PAD_SOURCE_VIDEO); > + RKISP1_ISP_PAD_SOURCE_VIDEO); > src_crop = v4l2_subdev_state_get_crop(sd_state, > - RKISP1_ISP_PAD_SOURCE_VIDEO); > + RKISP1_ISP_PAD_SOURCE_VIDEO); > > /* > * Media bus code. The ISP can operate in pass-through mode (Bayer in, Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
2023-10-13 09:37:10 +02:00
fmt_sink = v4l2_subdev_state_get_format(sd_state, MIPI_CSI2_PAD_SINK);
fmt_source = v4l2_subdev_state_get_format(sd_state,
MIPI_CSI2_PAD_SOURCE);
fmt_sink->code = MEDIA_BUS_FMT_SGBRG10_1X10;
fmt_sink->width = MIPI_CSI2_DEF_PIX_WIDTH;
fmt_sink->height = MIPI_CSI2_DEF_PIX_HEIGHT;
fmt_sink->field = V4L2_FIELD_NONE;
fmt_sink->colorspace = V4L2_COLORSPACE_RAW;
fmt_sink->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt_sink->colorspace);
fmt_sink->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt_sink->colorspace);
fmt_sink->quantization =
V4L2_MAP_QUANTIZATION_DEFAULT(false, fmt_sink->colorspace,
fmt_sink->ycbcr_enc);
*fmt_source = *fmt_sink;
return 0;
}
static int imx8mq_mipi_csi_enum_mbus_code(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_mbus_code_enum *code)
{
/*
* We can't transcode in any way, the source format is identical
* to the sink format.
*/
if (code->pad == MIPI_CSI2_PAD_SOURCE) {
struct v4l2_mbus_framefmt *fmt;
if (code->index > 0)
return -EINVAL;
media: v4l: subdev: Switch to stream-aware state functions Switch all drivers accessing sub-device state to use the stream-aware functions. We will soon remove the old ones. This patch has been generated using the following Coccinelle script: ---------8<------------ @@ expression E1, E2, E3; @@ - v4l2_subdev_get_pad_format(E1, E2, E3) + v4l2_subdev_state_get_format(E2, E3) @@ expression E1, E2, E3; @@ - v4l2_subdev_get_pad_crop(E1, E2, E3) + v4l2_subdev_state_get_crop(E2, E3) @@ expression E1, E2, E3; @@ - v4l2_subdev_get_pad_compose(E1, E2, E3) + v4l2_subdev_state_get_compose(E2, E3) @@ expression E1, E2, E3; @@ - v4l2_subdev_get_try_format(E1, E2, E3) + v4l2_subdev_state_get_format(E2, E3) @@ expression E1, E2, E3; @@ - v4l2_subdev_get_try_crop(E1, E2, E3) + v4l2_subdev_state_get_crop(E2, E3) @@ expression E1, E2, E3; @@ - v4l2_subdev_get_try_compose(E1, E2, E3) + v4l2_subdev_state_get_compose(E2, E3) ---------8<------------ Additionally drivers/media/i2c/s5k5baf.c and drivers/media/platform/samsung/s3c-camif/camif-capture.c have been manually changed as Coccinelle didn't. Further local variables have been removed as they became unused as a result of the other changes. Also Coccinelle introduced indentation by space in files drivers/media/i2c/st-mipid02.c and drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c. This has been also corrected. The diff from Coccinelle-generated changes are: > diff --git b/drivers/media/i2c/imx319.c a/drivers/media/i2c/imx319.c > index e549692ff478..420984382173 100644 > --- b/drivers/media/i2c/imx319.c > +++ a/drivers/media/i2c/imx319.c > @@ -2001,7 +2001,6 @@ static int imx319_do_get_pad_format(struct imx319 *imx319, > 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_state_get_format(sd_state, fmt->pad); > diff --git b/drivers/media/i2c/imx355.c a/drivers/media/i2c/imx355.c > index 96bdde685d65..e1b1d2fc79dd 100644 > --- b/drivers/media/i2c/imx355.c > +++ a/drivers/media/i2c/imx355.c > @@ -1299,7 +1299,6 @@ static int imx355_do_get_pad_format(struct imx355 *imx355, > 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_state_get_format(sd_state, fmt->pad); > diff --git b/drivers/media/i2c/ov08x40.c a/drivers/media/i2c/ov08x40.c > index ca799bbcfdb7..abbb0b774d43 100644 > --- b/drivers/media/i2c/ov08x40.c > +++ a/drivers/media/i2c/ov08x40.c > @@ -2774,7 +2774,6 @@ static int ov08x40_do_get_pad_format(struct ov08x40 *ov08x, > struct v4l2_subdev_format *fmt) > { > struct v4l2_mbus_framefmt *framefmt; > - struct v4l2_subdev *sd = &ov08x->sd; > > if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { > framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad); > diff --git b/drivers/media/i2c/ov13858.c a/drivers/media/i2c/ov13858.c > index 7816d9787c61..09387e335d80 100644 > --- b/drivers/media/i2c/ov13858.c > +++ a/drivers/media/i2c/ov13858.c > @@ -1316,7 +1316,6 @@ static int ov13858_do_get_pad_format(struct ov13858 *ov13858, > 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_state_get_format(sd_state, fmt->pad); > diff --git b/drivers/media/i2c/ov13b10.c a/drivers/media/i2c/ov13b10.c > index 268cd4b03f9c..c06411d5ee2b 100644 > --- b/drivers/media/i2c/ov13b10.c > +++ a/drivers/media/i2c/ov13b10.c > @@ -1001,7 +1001,6 @@ static int ov13b10_do_get_pad_format(struct ov13b10 *ov13b, > struct v4l2_subdev_format *fmt) > { > struct v4l2_mbus_framefmt *framefmt; > - struct v4l2_subdev *sd = &ov13b->sd; > > if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { > framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad); > diff --git b/drivers/media/i2c/s5c73m3/s5c73m3-core.c a/drivers/media/i2c/s5c73m3/s5c73m3-core.c > index 47605e36bc60..8f9b5713daf7 100644 > --- b/drivers/media/i2c/s5c73m3/s5c73m3-core.c > +++ a/drivers/media/i2c/s5c73m3/s5c73m3-core.c > @@ -819,7 +819,6 @@ static void s5c73m3_oif_try_format(struct s5c73m3 *state, > struct v4l2_subdev_format *fmt, > const struct s5c73m3_frame_size **fs) > { > - struct v4l2_subdev *sd = &state->sensor_sd; > u32 code; > > switch (fmt->pad) { > diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c > index 67da2045f543..03ccfb0e1e11 100644 > --- a/drivers/media/i2c/s5k5baf.c > +++ b/drivers/media/i2c/s5k5baf.c > @@ -1472,14 +1472,11 @@ 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, 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_cis_rect, > + v4l2_subdev_state_get_crop(sd_state, PAD_CIS), > + v4l2_subdev_state_get_compose(sd_state, PAD_CIS), > + v4l2_subdev_state_get_crop(sd_state, PAD_OUT) > + }; > s5k5baf_set_rect_and_adjust(rects, rtype, &sel->r); > return 0; > } > diff --git b/drivers/media/platform/samsung/s3c-camif/camif-capture.c a/drivers/media/platform/samsung/s3c-camif/camif-capture.c > index 295e083f38e8..be58260ea67e 100644 > --- b/drivers/media/platform/samsung/s3c-camif/camif-capture.c > +++ a/drivers/media/platform/samsung/s3c-camif/camif-capture.c > @@ -1216,7 +1216,7 @@ static int s3c_camif_subdev_get_fmt(struct v4l2_subdev *sd, > struct v4l2_mbus_framefmt *mf = &fmt->format; > > if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { > - mf = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); > + mf = v4l2_subdev_state_get_format(sd_state, fmt->pad); > fmt->format = *mf; > return 0; > } > @@ -1305,7 +1305,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, sd_state, fmt->pad); > + mf = v4l2_subdev_state_get_format(sd_state, fmt->pad); > *mf = fmt->format; > mutex_unlock(&camif->lock); > return 0; > diff --git b/drivers/media/platform/ti/cal/cal-camerarx.c a/drivers/media/platform/ti/cal/cal-camerarx.c > index cea454ed9c20..61433744c6c4 100644 > --- b/drivers/media/platform/ti/cal/cal-camerarx.c > +++ a/drivers/media/platform/ti/cal/cal-camerarx.c > @@ -621,8 +621,6 @@ static int cal_camerarx_sd_enum_mbus_code(struct v4l2_subdev *sd, > struct v4l2_subdev_state *state, > struct v4l2_subdev_mbus_code_enum *code) > { > - struct cal_camerarx *phy = to_cal_camerarx(sd); > - > /* No transcoding, source and sink codes must match. */ > if (cal_rx_pad_is_source(code->pad)) { > struct v4l2_mbus_framefmt *fmt; > diff --git b/drivers/staging/media/imx/imx-ic-prp.c a/drivers/staging/media/imx/imx-ic-prp.c > index dd558fac6477..61d69f19657e 100644 > --- b/drivers/staging/media/imx/imx-ic-prp.c > +++ a/drivers/staging/media/imx/imx-ic-prp.c > @@ -82,8 +82,6 @@ static struct v4l2_mbus_framefmt * > __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_state_get_format(sd_state, pad); > else > diff --git b/drivers/staging/media/imx/imx-ic-prpencvf.c a/drivers/staging/media/imx/imx-ic-prpencvf.c > index 02db7dbb884b..ec73c901079e 100644 > --- b/drivers/staging/media/imx/imx-ic-prpencvf.c > +++ a/drivers/staging/media/imx/imx-ic-prpencvf.c > @@ -790,8 +790,6 @@ static struct v4l2_mbus_framefmt * > __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_state_get_format(sd_state, pad); > else > diff --git a/drivers/media/i2c/st-mipid02.c b/drivers/media/i2c/st-mipid02.c > index 9c9361354c00..b08a249b5fdd 100644 > --- a/drivers/media/i2c/st-mipid02.c > +++ b/drivers/media/i2c/st-mipid02.c > @@ -751,7 +751,7 @@ static void mipid02_set_fmt_source(struct v4l2_subdev *sd, > format->format = bridge->fmt; > else > format->format = *v4l2_subdev_state_get_format(sd_state, > - MIPID02_SINK_0); > + MIPID02_SINK_0); > > /* but code may need to be converted */ > format->format.code = serial_to_parallel_code(format->format.code); > diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c > index 117912d3bfbd..96353648c032 100644 > --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c > +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c > @@ -319,7 +319,7 @@ static void rkisp1_isp_start(struct rkisp1_isp *isp, > rkisp1_write(rkisp1, RKISP1_CIF_ISP_CTRL, val); > > src_fmt = v4l2_subdev_state_get_format(sd_state, > - RKISP1_ISP_PAD_SOURCE_VIDEO); > + RKISP1_ISP_PAD_SOURCE_VIDEO); > src_info = rkisp1_mbus_info_get_by_code(src_fmt->code); > > if (src_info->pixel_enc != V4L2_PIXEL_ENC_BAYER) > @@ -475,9 +475,9 @@ static void rkisp1_isp_set_src_fmt(struct rkisp1_isp *isp, > sink_fmt = v4l2_subdev_state_get_format(sd_state, > RKISP1_ISP_PAD_SINK_VIDEO); > src_fmt = v4l2_subdev_state_get_format(sd_state, > - RKISP1_ISP_PAD_SOURCE_VIDEO); > + RKISP1_ISP_PAD_SOURCE_VIDEO); > src_crop = v4l2_subdev_state_get_crop(sd_state, > - RKISP1_ISP_PAD_SOURCE_VIDEO); > + RKISP1_ISP_PAD_SOURCE_VIDEO); > > /* > * Media bus code. The ISP can operate in pass-through mode (Bayer in, Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
2023-10-13 09:37:10 +02:00
fmt = v4l2_subdev_state_get_format(sd_state, code->pad);
code->code = fmt->code;
return 0;
}
if (code->pad != MIPI_CSI2_PAD_SINK)
return -EINVAL;
if (code->index >= ARRAY_SIZE(imx8mq_mipi_csi_formats))
return -EINVAL;
code->code = imx8mq_mipi_csi_formats[code->index].code;
return 0;
}
static int imx8mq_mipi_csi_set_fmt(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_format *sdformat)
{
const struct csi2_pix_format *csi2_fmt;
struct v4l2_mbus_framefmt *fmt;
/*
* The device can't transcode in any way, the source format can't be
* modified.
*/
if (sdformat->pad == MIPI_CSI2_PAD_SOURCE)
return v4l2_subdev_get_fmt(sd, sd_state, sdformat);
if (sdformat->pad != MIPI_CSI2_PAD_SINK)
return -EINVAL;
csi2_fmt = find_csi2_format(sdformat->format.code);
if (!csi2_fmt)
csi2_fmt = &imx8mq_mipi_csi_formats[0];
media: v4l: subdev: Switch to stream-aware state functions Switch all drivers accessing sub-device state to use the stream-aware functions. We will soon remove the old ones. This patch has been generated using the following Coccinelle script: ---------8<------------ @@ expression E1, E2, E3; @@ - v4l2_subdev_get_pad_format(E1, E2, E3) + v4l2_subdev_state_get_format(E2, E3) @@ expression E1, E2, E3; @@ - v4l2_subdev_get_pad_crop(E1, E2, E3) + v4l2_subdev_state_get_crop(E2, E3) @@ expression E1, E2, E3; @@ - v4l2_subdev_get_pad_compose(E1, E2, E3) + v4l2_subdev_state_get_compose(E2, E3) @@ expression E1, E2, E3; @@ - v4l2_subdev_get_try_format(E1, E2, E3) + v4l2_subdev_state_get_format(E2, E3) @@ expression E1, E2, E3; @@ - v4l2_subdev_get_try_crop(E1, E2, E3) + v4l2_subdev_state_get_crop(E2, E3) @@ expression E1, E2, E3; @@ - v4l2_subdev_get_try_compose(E1, E2, E3) + v4l2_subdev_state_get_compose(E2, E3) ---------8<------------ Additionally drivers/media/i2c/s5k5baf.c and drivers/media/platform/samsung/s3c-camif/camif-capture.c have been manually changed as Coccinelle didn't. Further local variables have been removed as they became unused as a result of the other changes. Also Coccinelle introduced indentation by space in files drivers/media/i2c/st-mipid02.c and drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c. This has been also corrected. The diff from Coccinelle-generated changes are: > diff --git b/drivers/media/i2c/imx319.c a/drivers/media/i2c/imx319.c > index e549692ff478..420984382173 100644 > --- b/drivers/media/i2c/imx319.c > +++ a/drivers/media/i2c/imx319.c > @@ -2001,7 +2001,6 @@ static int imx319_do_get_pad_format(struct imx319 *imx319, > 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_state_get_format(sd_state, fmt->pad); > diff --git b/drivers/media/i2c/imx355.c a/drivers/media/i2c/imx355.c > index 96bdde685d65..e1b1d2fc79dd 100644 > --- b/drivers/media/i2c/imx355.c > +++ a/drivers/media/i2c/imx355.c > @@ -1299,7 +1299,6 @@ static int imx355_do_get_pad_format(struct imx355 *imx355, > 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_state_get_format(sd_state, fmt->pad); > diff --git b/drivers/media/i2c/ov08x40.c a/drivers/media/i2c/ov08x40.c > index ca799bbcfdb7..abbb0b774d43 100644 > --- b/drivers/media/i2c/ov08x40.c > +++ a/drivers/media/i2c/ov08x40.c > @@ -2774,7 +2774,6 @@ static int ov08x40_do_get_pad_format(struct ov08x40 *ov08x, > struct v4l2_subdev_format *fmt) > { > struct v4l2_mbus_framefmt *framefmt; > - struct v4l2_subdev *sd = &ov08x->sd; > > if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { > framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad); > diff --git b/drivers/media/i2c/ov13858.c a/drivers/media/i2c/ov13858.c > index 7816d9787c61..09387e335d80 100644 > --- b/drivers/media/i2c/ov13858.c > +++ a/drivers/media/i2c/ov13858.c > @@ -1316,7 +1316,6 @@ static int ov13858_do_get_pad_format(struct ov13858 *ov13858, > 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_state_get_format(sd_state, fmt->pad); > diff --git b/drivers/media/i2c/ov13b10.c a/drivers/media/i2c/ov13b10.c > index 268cd4b03f9c..c06411d5ee2b 100644 > --- b/drivers/media/i2c/ov13b10.c > +++ a/drivers/media/i2c/ov13b10.c > @@ -1001,7 +1001,6 @@ static int ov13b10_do_get_pad_format(struct ov13b10 *ov13b, > struct v4l2_subdev_format *fmt) > { > struct v4l2_mbus_framefmt *framefmt; > - struct v4l2_subdev *sd = &ov13b->sd; > > if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { > framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad); > diff --git b/drivers/media/i2c/s5c73m3/s5c73m3-core.c a/drivers/media/i2c/s5c73m3/s5c73m3-core.c > index 47605e36bc60..8f9b5713daf7 100644 > --- b/drivers/media/i2c/s5c73m3/s5c73m3-core.c > +++ a/drivers/media/i2c/s5c73m3/s5c73m3-core.c > @@ -819,7 +819,6 @@ static void s5c73m3_oif_try_format(struct s5c73m3 *state, > struct v4l2_subdev_format *fmt, > const struct s5c73m3_frame_size **fs) > { > - struct v4l2_subdev *sd = &state->sensor_sd; > u32 code; > > switch (fmt->pad) { > diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c > index 67da2045f543..03ccfb0e1e11 100644 > --- a/drivers/media/i2c/s5k5baf.c > +++ b/drivers/media/i2c/s5k5baf.c > @@ -1472,14 +1472,11 @@ 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, 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_cis_rect, > + v4l2_subdev_state_get_crop(sd_state, PAD_CIS), > + v4l2_subdev_state_get_compose(sd_state, PAD_CIS), > + v4l2_subdev_state_get_crop(sd_state, PAD_OUT) > + }; > s5k5baf_set_rect_and_adjust(rects, rtype, &sel->r); > return 0; > } > diff --git b/drivers/media/platform/samsung/s3c-camif/camif-capture.c a/drivers/media/platform/samsung/s3c-camif/camif-capture.c > index 295e083f38e8..be58260ea67e 100644 > --- b/drivers/media/platform/samsung/s3c-camif/camif-capture.c > +++ a/drivers/media/platform/samsung/s3c-camif/camif-capture.c > @@ -1216,7 +1216,7 @@ static int s3c_camif_subdev_get_fmt(struct v4l2_subdev *sd, > struct v4l2_mbus_framefmt *mf = &fmt->format; > > if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { > - mf = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); > + mf = v4l2_subdev_state_get_format(sd_state, fmt->pad); > fmt->format = *mf; > return 0; > } > @@ -1305,7 +1305,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, sd_state, fmt->pad); > + mf = v4l2_subdev_state_get_format(sd_state, fmt->pad); > *mf = fmt->format; > mutex_unlock(&camif->lock); > return 0; > diff --git b/drivers/media/platform/ti/cal/cal-camerarx.c a/drivers/media/platform/ti/cal/cal-camerarx.c > index cea454ed9c20..61433744c6c4 100644 > --- b/drivers/media/platform/ti/cal/cal-camerarx.c > +++ a/drivers/media/platform/ti/cal/cal-camerarx.c > @@ -621,8 +621,6 @@ static int cal_camerarx_sd_enum_mbus_code(struct v4l2_subdev *sd, > struct v4l2_subdev_state *state, > struct v4l2_subdev_mbus_code_enum *code) > { > - struct cal_camerarx *phy = to_cal_camerarx(sd); > - > /* No transcoding, source and sink codes must match. */ > if (cal_rx_pad_is_source(code->pad)) { > struct v4l2_mbus_framefmt *fmt; > diff --git b/drivers/staging/media/imx/imx-ic-prp.c a/drivers/staging/media/imx/imx-ic-prp.c > index dd558fac6477..61d69f19657e 100644 > --- b/drivers/staging/media/imx/imx-ic-prp.c > +++ a/drivers/staging/media/imx/imx-ic-prp.c > @@ -82,8 +82,6 @@ static struct v4l2_mbus_framefmt * > __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_state_get_format(sd_state, pad); > else > diff --git b/drivers/staging/media/imx/imx-ic-prpencvf.c a/drivers/staging/media/imx/imx-ic-prpencvf.c > index 02db7dbb884b..ec73c901079e 100644 > --- b/drivers/staging/media/imx/imx-ic-prpencvf.c > +++ a/drivers/staging/media/imx/imx-ic-prpencvf.c > @@ -790,8 +790,6 @@ static struct v4l2_mbus_framefmt * > __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_state_get_format(sd_state, pad); > else > diff --git a/drivers/media/i2c/st-mipid02.c b/drivers/media/i2c/st-mipid02.c > index 9c9361354c00..b08a249b5fdd 100644 > --- a/drivers/media/i2c/st-mipid02.c > +++ b/drivers/media/i2c/st-mipid02.c > @@ -751,7 +751,7 @@ static void mipid02_set_fmt_source(struct v4l2_subdev *sd, > format->format = bridge->fmt; > else > format->format = *v4l2_subdev_state_get_format(sd_state, > - MIPID02_SINK_0); > + MIPID02_SINK_0); > > /* but code may need to be converted */ > format->format.code = serial_to_parallel_code(format->format.code); > diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c > index 117912d3bfbd..96353648c032 100644 > --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c > +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c > @@ -319,7 +319,7 @@ static void rkisp1_isp_start(struct rkisp1_isp *isp, > rkisp1_write(rkisp1, RKISP1_CIF_ISP_CTRL, val); > > src_fmt = v4l2_subdev_state_get_format(sd_state, > - RKISP1_ISP_PAD_SOURCE_VIDEO); > + RKISP1_ISP_PAD_SOURCE_VIDEO); > src_info = rkisp1_mbus_info_get_by_code(src_fmt->code); > > if (src_info->pixel_enc != V4L2_PIXEL_ENC_BAYER) > @@ -475,9 +475,9 @@ static void rkisp1_isp_set_src_fmt(struct rkisp1_isp *isp, > sink_fmt = v4l2_subdev_state_get_format(sd_state, > RKISP1_ISP_PAD_SINK_VIDEO); > src_fmt = v4l2_subdev_state_get_format(sd_state, > - RKISP1_ISP_PAD_SOURCE_VIDEO); > + RKISP1_ISP_PAD_SOURCE_VIDEO); > src_crop = v4l2_subdev_state_get_crop(sd_state, > - RKISP1_ISP_PAD_SOURCE_VIDEO); > + RKISP1_ISP_PAD_SOURCE_VIDEO); > > /* > * Media bus code. The ISP can operate in pass-through mode (Bayer in, Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
2023-10-13 09:37:10 +02:00
fmt = v4l2_subdev_state_get_format(sd_state, sdformat->pad);
fmt->code = csi2_fmt->code;
fmt->width = sdformat->format.width;
fmt->height = sdformat->format.height;
sdformat->format = *fmt;
/* Propagate the format from sink to source. */
media: v4l: subdev: Switch to stream-aware state functions Switch all drivers accessing sub-device state to use the stream-aware functions. We will soon remove the old ones. This patch has been generated using the following Coccinelle script: ---------8<------------ @@ expression E1, E2, E3; @@ - v4l2_subdev_get_pad_format(E1, E2, E3) + v4l2_subdev_state_get_format(E2, E3) @@ expression E1, E2, E3; @@ - v4l2_subdev_get_pad_crop(E1, E2, E3) + v4l2_subdev_state_get_crop(E2, E3) @@ expression E1, E2, E3; @@ - v4l2_subdev_get_pad_compose(E1, E2, E3) + v4l2_subdev_state_get_compose(E2, E3) @@ expression E1, E2, E3; @@ - v4l2_subdev_get_try_format(E1, E2, E3) + v4l2_subdev_state_get_format(E2, E3) @@ expression E1, E2, E3; @@ - v4l2_subdev_get_try_crop(E1, E2, E3) + v4l2_subdev_state_get_crop(E2, E3) @@ expression E1, E2, E3; @@ - v4l2_subdev_get_try_compose(E1, E2, E3) + v4l2_subdev_state_get_compose(E2, E3) ---------8<------------ Additionally drivers/media/i2c/s5k5baf.c and drivers/media/platform/samsung/s3c-camif/camif-capture.c have been manually changed as Coccinelle didn't. Further local variables have been removed as they became unused as a result of the other changes. Also Coccinelle introduced indentation by space in files drivers/media/i2c/st-mipid02.c and drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c. This has been also corrected. The diff from Coccinelle-generated changes are: > diff --git b/drivers/media/i2c/imx319.c a/drivers/media/i2c/imx319.c > index e549692ff478..420984382173 100644 > --- b/drivers/media/i2c/imx319.c > +++ a/drivers/media/i2c/imx319.c > @@ -2001,7 +2001,6 @@ static int imx319_do_get_pad_format(struct imx319 *imx319, > 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_state_get_format(sd_state, fmt->pad); > diff --git b/drivers/media/i2c/imx355.c a/drivers/media/i2c/imx355.c > index 96bdde685d65..e1b1d2fc79dd 100644 > --- b/drivers/media/i2c/imx355.c > +++ a/drivers/media/i2c/imx355.c > @@ -1299,7 +1299,6 @@ static int imx355_do_get_pad_format(struct imx355 *imx355, > 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_state_get_format(sd_state, fmt->pad); > diff --git b/drivers/media/i2c/ov08x40.c a/drivers/media/i2c/ov08x40.c > index ca799bbcfdb7..abbb0b774d43 100644 > --- b/drivers/media/i2c/ov08x40.c > +++ a/drivers/media/i2c/ov08x40.c > @@ -2774,7 +2774,6 @@ static int ov08x40_do_get_pad_format(struct ov08x40 *ov08x, > struct v4l2_subdev_format *fmt) > { > struct v4l2_mbus_framefmt *framefmt; > - struct v4l2_subdev *sd = &ov08x->sd; > > if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { > framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad); > diff --git b/drivers/media/i2c/ov13858.c a/drivers/media/i2c/ov13858.c > index 7816d9787c61..09387e335d80 100644 > --- b/drivers/media/i2c/ov13858.c > +++ a/drivers/media/i2c/ov13858.c > @@ -1316,7 +1316,6 @@ static int ov13858_do_get_pad_format(struct ov13858 *ov13858, > 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_state_get_format(sd_state, fmt->pad); > diff --git b/drivers/media/i2c/ov13b10.c a/drivers/media/i2c/ov13b10.c > index 268cd4b03f9c..c06411d5ee2b 100644 > --- b/drivers/media/i2c/ov13b10.c > +++ a/drivers/media/i2c/ov13b10.c > @@ -1001,7 +1001,6 @@ static int ov13b10_do_get_pad_format(struct ov13b10 *ov13b, > struct v4l2_subdev_format *fmt) > { > struct v4l2_mbus_framefmt *framefmt; > - struct v4l2_subdev *sd = &ov13b->sd; > > if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { > framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad); > diff --git b/drivers/media/i2c/s5c73m3/s5c73m3-core.c a/drivers/media/i2c/s5c73m3/s5c73m3-core.c > index 47605e36bc60..8f9b5713daf7 100644 > --- b/drivers/media/i2c/s5c73m3/s5c73m3-core.c > +++ a/drivers/media/i2c/s5c73m3/s5c73m3-core.c > @@ -819,7 +819,6 @@ static void s5c73m3_oif_try_format(struct s5c73m3 *state, > struct v4l2_subdev_format *fmt, > const struct s5c73m3_frame_size **fs) > { > - struct v4l2_subdev *sd = &state->sensor_sd; > u32 code; > > switch (fmt->pad) { > diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c > index 67da2045f543..03ccfb0e1e11 100644 > --- a/drivers/media/i2c/s5k5baf.c > +++ b/drivers/media/i2c/s5k5baf.c > @@ -1472,14 +1472,11 @@ 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, 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_cis_rect, > + v4l2_subdev_state_get_crop(sd_state, PAD_CIS), > + v4l2_subdev_state_get_compose(sd_state, PAD_CIS), > + v4l2_subdev_state_get_crop(sd_state, PAD_OUT) > + }; > s5k5baf_set_rect_and_adjust(rects, rtype, &sel->r); > return 0; > } > diff --git b/drivers/media/platform/samsung/s3c-camif/camif-capture.c a/drivers/media/platform/samsung/s3c-camif/camif-capture.c > index 295e083f38e8..be58260ea67e 100644 > --- b/drivers/media/platform/samsung/s3c-camif/camif-capture.c > +++ a/drivers/media/platform/samsung/s3c-camif/camif-capture.c > @@ -1216,7 +1216,7 @@ static int s3c_camif_subdev_get_fmt(struct v4l2_subdev *sd, > struct v4l2_mbus_framefmt *mf = &fmt->format; > > if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { > - mf = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); > + mf = v4l2_subdev_state_get_format(sd_state, fmt->pad); > fmt->format = *mf; > return 0; > } > @@ -1305,7 +1305,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, sd_state, fmt->pad); > + mf = v4l2_subdev_state_get_format(sd_state, fmt->pad); > *mf = fmt->format; > mutex_unlock(&camif->lock); > return 0; > diff --git b/drivers/media/platform/ti/cal/cal-camerarx.c a/drivers/media/platform/ti/cal/cal-camerarx.c > index cea454ed9c20..61433744c6c4 100644 > --- b/drivers/media/platform/ti/cal/cal-camerarx.c > +++ a/drivers/media/platform/ti/cal/cal-camerarx.c > @@ -621,8 +621,6 @@ static int cal_camerarx_sd_enum_mbus_code(struct v4l2_subdev *sd, > struct v4l2_subdev_state *state, > struct v4l2_subdev_mbus_code_enum *code) > { > - struct cal_camerarx *phy = to_cal_camerarx(sd); > - > /* No transcoding, source and sink codes must match. */ > if (cal_rx_pad_is_source(code->pad)) { > struct v4l2_mbus_framefmt *fmt; > diff --git b/drivers/staging/media/imx/imx-ic-prp.c a/drivers/staging/media/imx/imx-ic-prp.c > index dd558fac6477..61d69f19657e 100644 > --- b/drivers/staging/media/imx/imx-ic-prp.c > +++ a/drivers/staging/media/imx/imx-ic-prp.c > @@ -82,8 +82,6 @@ static struct v4l2_mbus_framefmt * > __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_state_get_format(sd_state, pad); > else > diff --git b/drivers/staging/media/imx/imx-ic-prpencvf.c a/drivers/staging/media/imx/imx-ic-prpencvf.c > index 02db7dbb884b..ec73c901079e 100644 > --- b/drivers/staging/media/imx/imx-ic-prpencvf.c > +++ a/drivers/staging/media/imx/imx-ic-prpencvf.c > @@ -790,8 +790,6 @@ static struct v4l2_mbus_framefmt * > __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_state_get_format(sd_state, pad); > else > diff --git a/drivers/media/i2c/st-mipid02.c b/drivers/media/i2c/st-mipid02.c > index 9c9361354c00..b08a249b5fdd 100644 > --- a/drivers/media/i2c/st-mipid02.c > +++ b/drivers/media/i2c/st-mipid02.c > @@ -751,7 +751,7 @@ static void mipid02_set_fmt_source(struct v4l2_subdev *sd, > format->format = bridge->fmt; > else > format->format = *v4l2_subdev_state_get_format(sd_state, > - MIPID02_SINK_0); > + MIPID02_SINK_0); > > /* but code may need to be converted */ > format->format.code = serial_to_parallel_code(format->format.code); > diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c > index 117912d3bfbd..96353648c032 100644 > --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c > +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c > @@ -319,7 +319,7 @@ static void rkisp1_isp_start(struct rkisp1_isp *isp, > rkisp1_write(rkisp1, RKISP1_CIF_ISP_CTRL, val); > > src_fmt = v4l2_subdev_state_get_format(sd_state, > - RKISP1_ISP_PAD_SOURCE_VIDEO); > + RKISP1_ISP_PAD_SOURCE_VIDEO); > src_info = rkisp1_mbus_info_get_by_code(src_fmt->code); > > if (src_info->pixel_enc != V4L2_PIXEL_ENC_BAYER) > @@ -475,9 +475,9 @@ static void rkisp1_isp_set_src_fmt(struct rkisp1_isp *isp, > sink_fmt = v4l2_subdev_state_get_format(sd_state, > RKISP1_ISP_PAD_SINK_VIDEO); > src_fmt = v4l2_subdev_state_get_format(sd_state, > - RKISP1_ISP_PAD_SOURCE_VIDEO); > + RKISP1_ISP_PAD_SOURCE_VIDEO); > src_crop = v4l2_subdev_state_get_crop(sd_state, > - RKISP1_ISP_PAD_SOURCE_VIDEO); > + RKISP1_ISP_PAD_SOURCE_VIDEO); > > /* > * Media bus code. The ISP can operate in pass-through mode (Bayer in, Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
2023-10-13 09:37:10 +02:00
fmt = v4l2_subdev_state_get_format(sd_state, MIPI_CSI2_PAD_SOURCE);
*fmt = sdformat->format;
return 0;
}
static const struct v4l2_subdev_video_ops imx8mq_mipi_csi_video_ops = {
.s_stream = imx8mq_mipi_csi_s_stream,
};
static const struct v4l2_subdev_pad_ops imx8mq_mipi_csi_pad_ops = {
.enum_mbus_code = imx8mq_mipi_csi_enum_mbus_code,
.get_fmt = v4l2_subdev_get_fmt,
.set_fmt = imx8mq_mipi_csi_set_fmt,
};
static const struct v4l2_subdev_ops imx8mq_mipi_csi_subdev_ops = {
.video = &imx8mq_mipi_csi_video_ops,
.pad = &imx8mq_mipi_csi_pad_ops,
};
static const struct v4l2_subdev_internal_ops imx8mq_mipi_csi_internal_ops = {
.init_state = imx8mq_mipi_csi_init_state,
};
/* -----------------------------------------------------------------------------
* Media entity operations
*/
static const struct media_entity_operations imx8mq_mipi_csi_entity_ops = {
.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_csi2_state(struct v4l2_async_notifier *n)
{
return container_of(n, struct csi_state, notifier);
}
static int imx8mq_mipi_csi_notify_bound(struct v4l2_async_notifier *notifier,
struct v4l2_subdev *sd,
struct v4l2_async_connection *asd)
{
struct csi_state *state = mipi_notifier_to_csi2_state(notifier);
struct media_pad *sink = &state->sd.entity.pads[MIPI_CSI2_PAD_SINK];
state->src_sd = sd;
return v4l2_create_fwnode_links_to_pad(sd, sink, MEDIA_LNK_FL_ENABLED |
MEDIA_LNK_FL_IMMUTABLE);
}
static const struct v4l2_async_notifier_operations imx8mq_mipi_csi_notify_ops = {
.bound = imx8mq_mipi_csi_notify_bound,
};
static int imx8mq_mipi_csi_async_register(struct csi_state *state)
{
struct v4l2_fwnode_endpoint vep = {
.bus_type = V4L2_MBUS_CSI2_DPHY,
};
struct v4l2_async_connection *asd;
struct fwnode_handle *ep;
unsigned int i;
int ret;
v4l2_async_subdev_nf_init(&state->notifier, &state->sd);
ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(state->dev), 0, 0,
FWNODE_GRAPH_ENDPOINT_NEXT);
if (!ep)
return -ENOTCONN;
ret = v4l2_fwnode_endpoint_parse(ep, &vep);
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");
ret = -EINVAL;
goto err_parse;
}
}
state->bus = vep.bus.mipi_csi2;
dev_dbg(state->dev, "data lanes: %d flags: 0x%08x\n",
state->bus.num_data_lanes,
state->bus.flags);
asd = v4l2_async_nf_add_fwnode_remote(&state->notifier, ep,
struct v4l2_async_connection);
if (IS_ERR(asd)) {
ret = PTR_ERR(asd);
goto err_parse;
}
fwnode_handle_put(ep);
state->notifier.ops = &imx8mq_mipi_csi_notify_ops;
ret = v4l2_async_nf_register(&state->notifier);
if (ret)
return ret;
return v4l2_async_register_subdev(&state->sd);
err_parse:
fwnode_handle_put(ep);
return ret;
}
/* -----------------------------------------------------------------------------
* Suspend/resume
*/
static void imx8mq_mipi_csi_pm_suspend(struct device *dev)
{
struct v4l2_subdev *sd = dev_get_drvdata(dev);
struct csi_state *state = mipi_sd_to_csi2_state(sd);
mutex_lock(&state->lock);
if (state->state & ST_POWERED) {
imx8mq_mipi_csi_stop_stream(state);
imx8mq_mipi_csi_clk_disable(state);
state->state &= ~ST_POWERED;
}
mutex_unlock(&state->lock);
}
static int imx8mq_mipi_csi_pm_resume(struct device *dev)
{
struct v4l2_subdev *sd = dev_get_drvdata(dev);
struct csi_state *state = mipi_sd_to_csi2_state(sd);
struct v4l2_subdev_state *sd_state;
int ret = 0;
mutex_lock(&state->lock);
if (!(state->state & ST_POWERED)) {
state->state |= ST_POWERED;
ret = imx8mq_mipi_csi_clk_enable(state);
}
if (state->state & ST_STREAMING) {
sd_state = v4l2_subdev_lock_and_get_active_state(sd);
ret = imx8mq_mipi_csi_start_stream(state, sd_state);
v4l2_subdev_unlock_state(sd_state);
if (ret)
goto unlock;
}
state->state &= ~ST_SUSPENDED;
unlock:
mutex_unlock(&state->lock);
return ret ? -EAGAIN : 0;
}
static int imx8mq_mipi_csi_suspend(struct device *dev)
{
struct v4l2_subdev *sd = dev_get_drvdata(dev);
struct csi_state *state = mipi_sd_to_csi2_state(sd);
imx8mq_mipi_csi_pm_suspend(dev);
state->state |= ST_SUSPENDED;
return 0;
}
static int imx8mq_mipi_csi_resume(struct device *dev)
{
struct v4l2_subdev *sd = dev_get_drvdata(dev);
struct csi_state *state = mipi_sd_to_csi2_state(sd);
if (!(state->state & ST_SUSPENDED))
return 0;
return imx8mq_mipi_csi_pm_resume(dev);
}
static int imx8mq_mipi_csi_runtime_suspend(struct device *dev)
{
struct v4l2_subdev *sd = dev_get_drvdata(dev);
struct csi_state *state = mipi_sd_to_csi2_state(sd);
int ret;
imx8mq_mipi_csi_pm_suspend(dev);
ret = icc_set_bw(state->icc_path, 0, 0);
if (ret)
dev_err(dev, "icc_set_bw failed with %d\n", ret);
return ret;
}
static int imx8mq_mipi_csi_runtime_resume(struct device *dev)
{
struct v4l2_subdev *sd = dev_get_drvdata(dev);
struct csi_state *state = mipi_sd_to_csi2_state(sd);
int ret;
ret = icc_set_bw(state->icc_path, 0, state->icc_path_bw);
if (ret) {
dev_err(dev, "icc_set_bw failed with %d\n", ret);
return ret;
}
return imx8mq_mipi_csi_pm_resume(dev);
}
static const struct dev_pm_ops imx8mq_mipi_csi_pm_ops = {
RUNTIME_PM_OPS(imx8mq_mipi_csi_runtime_suspend,
imx8mq_mipi_csi_runtime_resume, NULL)
SYSTEM_SLEEP_PM_OPS(imx8mq_mipi_csi_suspend, imx8mq_mipi_csi_resume)
};
/* -----------------------------------------------------------------------------
* Probe/remove & platform driver
*/
static int imx8mq_mipi_csi_subdev_init(struct csi_state *state)
{
struct v4l2_subdev *sd = &state->sd;
int ret;
v4l2_subdev_init(sd, &imx8mq_mipi_csi_subdev_ops);
sd->internal_ops = &imx8mq_mipi_csi_internal_ops;
sd->owner = THIS_MODULE;
snprintf(sd->name, sizeof(sd->name), "%s %s",
MIPI_CSI2_SUBDEV_NAME, dev_name(state->dev));
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
sd->entity.ops = &imx8mq_mipi_csi_entity_ops;
sd->dev = state->dev;
state->pads[MIPI_CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK
| MEDIA_PAD_FL_MUST_CONNECT;
state->pads[MIPI_CSI2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE
| MEDIA_PAD_FL_MUST_CONNECT;
ret = media_entity_pads_init(&sd->entity, MIPI_CSI2_PADS_NUM,
state->pads);
if (ret)
return ret;
ret = v4l2_subdev_init_finalize(sd);
if (ret) {
media_entity_cleanup(&sd->entity);
return ret;
}
return 0;
}
static void imx8mq_mipi_csi_release_icc(struct platform_device *pdev)
{
struct v4l2_subdev *sd = dev_get_drvdata(&pdev->dev);
struct csi_state *state = mipi_sd_to_csi2_state(sd);
icc_put(state->icc_path);
}
static int imx8mq_mipi_csi_init_icc(struct platform_device *pdev)
{
struct v4l2_subdev *sd = dev_get_drvdata(&pdev->dev);
struct csi_state *state = mipi_sd_to_csi2_state(sd);
/* Optional interconnect request */
state->icc_path = of_icc_get(&pdev->dev, "dram");
if (IS_ERR_OR_NULL(state->icc_path))
return PTR_ERR_OR_ZERO(state->icc_path);
state->icc_path_bw = MBps_to_icc(700);
return 0;
}
static int imx8mq_mipi_csi_parse_dt(struct csi_state *state)
{
struct device *dev = state->dev;
struct device_node *np = state->dev->of_node;
struct device_node *node;
phandle ph;
u32 out_val[2];
int ret = 0;
state->rst = devm_reset_control_array_get_exclusive(dev);
if (IS_ERR(state->rst)) {
dev_err(dev, "Failed to get reset: %pe\n", state->rst);
return PTR_ERR(state->rst);
}
if (state->pdata->use_reg_csr) {
const struct regmap_config regmap_config = {
.reg_bits = 32,
.val_bits = 32,
.reg_stride = 4,
};
void __iomem *base;
base = devm_platform_ioremap_resource(to_platform_device(dev), 1);
if (IS_ERR(base))
return dev_err_probe(dev, PTR_ERR(base), "Missing CSR register\n");
state->phy_gpr = devm_regmap_init_mmio(dev, base, &regmap_config);
if (IS_ERR(state->phy_gpr))
return dev_err_probe(dev, PTR_ERR(state->phy_gpr),
"Failed to init CSI MMIO regmap\n");
return 0;
}
ret = of_property_read_u32_array(np, "fsl,mipi-phy-gpr", out_val,
ARRAY_SIZE(out_val));
if (ret) {
dev_err(dev, "no fsl,mipi-phy-gpr property found: %d\n", ret);
return ret;
}
ph = *out_val;
node = of_find_node_by_phandle(ph);
if (!node) {
dev_err(dev, "Error finding node by phandle\n");
return -ENODEV;
}
state->phy_gpr = syscon_node_to_regmap(node);
of_node_put(node);
if (IS_ERR(state->phy_gpr)) {
dev_err(dev, "failed to get gpr regmap: %pe\n", state->phy_gpr);
return PTR_ERR(state->phy_gpr);
}
state->phy_gpr_reg = out_val[1];
dev_dbg(dev, "phy gpr register set to 0x%x\n", state->phy_gpr_reg);
return ret;
}
static int imx8mq_mipi_csi_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct csi_state *state;
int ret;
state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL);
if (!state)
return -ENOMEM;
state->dev = dev;
state->pdata = of_device_get_match_data(dev);
ret = imx8mq_mipi_csi_parse_dt(state);
if (ret < 0) {
dev_err(dev, "Failed to parse device tree: %d\n", ret);
return ret;
}
/* Acquire resources. */
state->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(state->regs))
return PTR_ERR(state->regs);
ret = imx8mq_mipi_csi_clk_get(state);
if (ret < 0)
return ret;
platform_set_drvdata(pdev, &state->sd);
mutex_init(&state->lock);
ret = imx8mq_mipi_csi_subdev_init(state);
if (ret < 0)
goto mutex;
ret = imx8mq_mipi_csi_init_icc(pdev);
if (ret)
goto mutex;
/* Enable runtime PM. */
pm_runtime_enable(dev);
if (!pm_runtime_enabled(dev)) {
ret = imx8mq_mipi_csi_runtime_resume(dev);
if (ret < 0)
goto icc;
}
ret = imx8mq_mipi_csi_async_register(state);
if (ret < 0)
goto cleanup;
return 0;
cleanup:
pm_runtime_disable(&pdev->dev);
imx8mq_mipi_csi_runtime_suspend(&pdev->dev);
media_entity_cleanup(&state->sd.entity);
v4l2_subdev_cleanup(&state->sd);
v4l2_async_nf_unregister(&state->notifier);
v4l2_async_nf_cleanup(&state->notifier);
v4l2_async_unregister_subdev(&state->sd);
icc:
imx8mq_mipi_csi_release_icc(pdev);
mutex:
mutex_destroy(&state->lock);
return ret;
}
static void imx8mq_mipi_csi_remove(struct platform_device *pdev)
{
struct v4l2_subdev *sd = platform_get_drvdata(pdev);
struct csi_state *state = mipi_sd_to_csi2_state(sd);
v4l2_async_nf_unregister(&state->notifier);
v4l2_async_nf_cleanup(&state->notifier);
v4l2_async_unregister_subdev(&state->sd);
pm_runtime_disable(&pdev->dev);
imx8mq_mipi_csi_runtime_suspend(&pdev->dev);
media_entity_cleanup(&state->sd.entity);
v4l2_subdev_cleanup(&state->sd);
mutex_destroy(&state->lock);
pm_runtime_set_suspended(&pdev->dev);
imx8mq_mipi_csi_release_icc(pdev);
}
static const struct of_device_id imx8mq_mipi_csi_of_match[] = {
{ .compatible = "fsl,imx8mq-mipi-csi2", .data = &imx8mq_data },
{ .compatible = "fsl,imx8qxp-mipi-csi2", .data = &imx8qxp_data },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, imx8mq_mipi_csi_of_match);
static struct platform_driver imx8mq_mipi_csi_driver = {
.probe = imx8mq_mipi_csi_probe,
.remove = imx8mq_mipi_csi_remove,
.driver = {
.of_match_table = imx8mq_mipi_csi_of_match,
.name = MIPI_CSI2_DRIVER_NAME,
.pm = pm_ptr(&imx8mq_mipi_csi_pm_ops),
},
};
module_platform_driver(imx8mq_mipi_csi_driver);
MODULE_DESCRIPTION("i.MX8MQ MIPI CSI-2 receiver driver");
MODULE_AUTHOR("Martin Kepplinger <martin.kepplinger@puri.sm>");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:imx8mq-mipi-csi2");