if (sd_fmt->format.code == MEDIA_BUS_FMT_YUYV8_1X16 ||
sd_fmt->format.code == MEDIA_BUS_FMT_YVYU8_2X8 ||
sd_fmt->format.code == MEDIA_BUS_FMT_AYUV8_1X32 ||
- sd_fmt->format.code == MEDIA_BUS_FMT_UYVY8_2X8)
+ sd_fmt->format.code == MEDIA_BUS_FMT_UYVY8_2X8 ||
+ sd_fmt->format.code == MEDIA_BUS_FMT_YUYV8_2X8)
index = 1;
else
index = 0;
*/
#include "mxc-media-dev.h"
+static const struct of_device_id mxc_isi_of_match[];
+
static irqreturn_t mxc_isi_irq_handler(int irq, void *priv)
{
struct mxc_isi_dev *mxc_isi = priv;
return IRQ_HANDLED;
}
+static void disp_mix_sft_rstn(struct regmap *gpr, bool enable)
+{
+ if (!gpr)
+ return;
+
+ if (!enable)
+ /* release isi soft reset */
+ regmap_update_bits(gpr,
+ DISP_MIX_SFT_RSTN_CSR,
+ EN_BUS_BLK_CLK_RSTN | EN_ISI_APB_CLK_RSTN | EN_ISI_PROC_CLK_RSTN,
+ EN_BUS_BLK_CLK_RSTN | EN_ISI_APB_CLK_RSTN | EN_ISI_PROC_CLK_RSTN);
+ else
+ regmap_update_bits(gpr,
+ DISP_MIX_SFT_RSTN_CSR,
+ EN_BUS_BLK_CLK_RSTN | EN_ISI_APB_CLK_RSTN | EN_ISI_APB_CLK_RSTN,
+ 0x0);
+
+}
+
+static void disp_mix_clks_enable(struct regmap *gpr, bool enable)
+{
+ if (!gpr)
+ return;
+
+ if (enable)
+ /* enable isi clks */
+ regmap_update_bits(gpr,
+ DISP_MIX_CLK_EN_CSR,
+ EN_BUS_BLK_CLK | EN_ISI_APB_CLK | EN_ISI_PROC_CLK,
+ EN_BUS_BLK_CLK | EN_ISI_APB_CLK | EN_ISI_PROC_CLK);
+ else
+ /* disable isi clks */
+ regmap_update_bits(gpr,
+ DISP_MIX_CLK_EN_CSR,
+ EN_BUS_BLK_CLK | EN_ISI_APB_CLK | EN_ISI_PROC_CLK,
+ 0x0);
+}
+
/**
* mxc_isi_adjust_mplane_format - adjust bytesperline or sizeimage
*/
return 0;
}
+static int mxc_imx8_clk_get(struct mxc_isi_dev *mxc_isi)
+{
+ struct device *dev = &mxc_isi->pdev->dev;
+
+ mxc_isi->clk = devm_clk_get(dev, NULL);
+
+ if (IS_ERR(mxc_isi->clk)) {
+ dev_err(dev, "failed to get isi clk\n");
+ return PTR_ERR(mxc_isi->clk);
+ }
+
+ return 0;
+}
+
+static int mxc_imx8_clk_enable(struct mxc_isi_dev *mxc_isi)
+{
+ struct device *dev = &mxc_isi->pdev->dev;
+ int ret;
+
+ ret = clk_prepare_enable(mxc_isi->clk);
+ if (ret < 0) {
+ dev_err(dev, "%s, enable clk error\n", __func__);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void mxc_imx8_clk_disable(struct mxc_isi_dev *mxc_isi)
+{
+ clk_disable_unprepare(mxc_isi->clk);
+}
+
+static struct mxc_isi_dev_ops mxc_imx8_data = {
+ .clk_get = mxc_imx8_clk_get,
+ .clk_enable = mxc_imx8_clk_enable,
+ .clk_disable = mxc_imx8_clk_disable,
+};
+
+static int mxc_imx8mn_clk_get(struct mxc_isi_dev *mxc_isi)
+{
+ struct device *dev = &mxc_isi->pdev->dev;
+
+ mxc_isi->clk_disp_axi = devm_clk_get(dev, "disp_axi");
+ if (IS_ERR(mxc_isi->clk_disp_axi)) {
+ dev_err(dev, "failed to get disp_axi clk\n");
+ return PTR_ERR(mxc_isi->clk_disp_axi);
+ }
+
+ mxc_isi->clk_disp_apb = devm_clk_get(dev, "disp_apb");
+ if (IS_ERR(mxc_isi->clk_disp_apb)) {
+ dev_err(dev, "failed to get disp_apb clk\n");
+ return PTR_ERR(mxc_isi->clk_disp_apb);
+ }
+
+ mxc_isi->clk_root_disp_axi = devm_clk_get(dev, "disp_axi_root");
+ if (IS_ERR(mxc_isi->clk_root_disp_axi)) {
+ dev_err(dev, "failed to get disp axi root clk\n");
+ return PTR_ERR(mxc_isi->clk_root_disp_axi);
+ }
+
+ mxc_isi->clk_root_disp_apb = devm_clk_get(dev, "disp_apb_root");
+ if (IS_ERR(mxc_isi->clk_root_disp_apb)) {
+ dev_err(dev, "failed to get disp apb root clk\n");
+ return PTR_ERR(mxc_isi->clk_root_disp_apb);
+ }
+
+ return 0;
+}
+
+static int mxc_imx8mn_clk_enable(struct mxc_isi_dev *mxc_isi)
+{
+ struct device *dev = &mxc_isi->pdev->dev;
+ int ret;
+
+ ret = clk_prepare_enable(mxc_isi->clk_disp_axi);
+ if (ret < 0) {
+ dev_err(dev, "prepare and enable axi clk error\n");
+ return ret;
+ }
+
+ ret = clk_prepare_enable(mxc_isi->clk_disp_apb);
+ if (ret < 0) {
+ dev_err(dev, "prepare and enable abp clk error\n");
+ return ret;
+ }
+
+ ret = clk_prepare_enable(mxc_isi->clk_root_disp_axi);
+ if (ret < 0) {
+ dev_err(dev, "prepare and enable axi root clk error\n");
+ return ret;
+ }
+
+ ret = clk_prepare_enable(mxc_isi->clk_root_disp_apb);
+ if (ret < 0) {
+ dev_err(dev, "prepare and enable apb root clk error\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static void mxc_imx8mn_clk_disable(struct mxc_isi_dev *mxc_isi)
+{
+ clk_disable_unprepare(mxc_isi->clk_root_disp_axi);
+ clk_disable_unprepare(mxc_isi->clk_root_disp_apb);
+ clk_disable_unprepare(mxc_isi->clk_disp_axi);
+ clk_disable_unprepare(mxc_isi->clk_disp_apb);
+}
+
+static struct mxc_isi_dev_ops mxc_imx8mn_data = {
+ .clk_get = mxc_imx8mn_clk_get,
+ .clk_enable = mxc_imx8mn_clk_enable,
+ .clk_disable = mxc_imx8mn_clk_disable,
+};
+
+static int mxc_isi_clk_get(struct mxc_isi_dev *mxc_isi)
+{
+ const struct mxc_isi_dev_ops *ops = mxc_isi->ops;
+
+ if (!ops && !ops->clk_get)
+ return -EINVAL;
+
+ return ops->clk_get(mxc_isi);
+}
+
+static int mxc_isi_clk_enable(struct mxc_isi_dev *mxc_isi)
+{
+ const struct mxc_isi_dev_ops *ops = mxc_isi->ops;
+
+ if (!ops && !ops->clk_enable)
+ return -EINVAL;
+
+ return ops->clk_enable(mxc_isi);
+}
+
+static void mxc_isi_clk_disable(struct mxc_isi_dev *mxc_isi)
+{
+ const struct mxc_isi_dev_ops *ops = mxc_isi->ops;
+
+ if (!ops && !ops->clk_disable)
+ return;
+
+ ops->clk_disable(mxc_isi);
+}
static int mxc_isi_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct mxc_isi_dev *mxc_isi;
struct resource *res;
+ const struct of_device_id *of_id;
int ret = 0;
mxc_isi = devm_kzalloc(dev, sizeof(*mxc_isi), GFP_KERNEL);
return -ENOMEM;
mxc_isi->pdev = pdev;
+ of_id = of_match_node(mxc_isi_of_match, dev->of_node);
+ if (!of_id)
+ return -EINVAL;
+
+ mxc_isi->ops = of_id->data;
+ if (!mxc_isi->ops) {
+ dev_err(dev, "Can't get platform device data\n");
+ return -EINVAL;
+ }
ret = mxc_isi_parse_dt(mxc_isi);
if (ret < 0)
mutex_init(&mxc_isi->m2m_lock);
atomic_set(&mxc_isi->open_count, 0);
- mxc_isi->clk = devm_clk_get(dev, NULL);
- if (IS_ERR(mxc_isi->clk)) {
- dev_err(dev, "failed to get isi clk\n");
- return PTR_ERR(mxc_isi->clk);
+ mxc_isi->gpr = syscon_regmap_lookup_by_phandle(dev->of_node, "isi-gpr");
+ if (IS_ERR(mxc_isi->gpr)) {
+ mxc_isi->gpr = NULL;
+ dev_warn(dev, "can't find isi-gpr property\n");
}
- ret = clk_prepare(mxc_isi->clk);
+
+ ret = mxc_isi_clk_get(mxc_isi);
if (ret < 0) {
- dev_err(dev, "%s, prepare clk error\n", __func__);
- return -EINVAL;
+ dev_err(dev, "ISI_%d get clocks fail\n", mxc_isi->id);
+ return ret;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
return -ENXIO;
}
+ ret = mxc_isi_clk_enable(mxc_isi);
+ if (ret < 0) {
+ dev_err(dev, "ISI_%d enable clocks fail\n", mxc_isi->id);
+ return ret;
+ }
+ disp_mix_sft_rstn(mxc_isi->gpr, false);
+ disp_mix_clks_enable(mxc_isi->gpr, true);
+
mxc_isi_clean_registers(mxc_isi);
ret = devm_request_irq(dev, res->start, mxc_isi_irq_handler,
0, dev_name(dev), mxc_isi);
if (ret < 0) {
dev_err(dev, "failed to install irq (%d)\n", ret);
- return -EINVAL;
+ goto err_clk;
}
ret = mxc_isi_initialize_capture_subdev(mxc_isi);
if (ret < 0) {
dev_err(dev, "failed to init cap subdev (%d)\n", ret);
- return -EINVAL;
+ goto err_clk;
}
platform_set_drvdata(pdev, mxc_isi);
- ret = clk_enable(mxc_isi->clk);
- if (ret < 0) {
- dev_err(dev, "%s, enable clk error\n", __func__);
- goto err_sclk;
- }
-
- clk_disable_unprepare(mxc_isi->clk);
+ mxc_isi_channel_set_chain_buf(mxc_isi);
+ mxc_isi_clk_disable(mxc_isi);
pm_runtime_enable(dev);
return 0;
-err_sclk:
+err_clk:
+ mxc_isi_clk_disable(mxc_isi);
mxc_isi_unregister_capture_subdev(mxc_isi);
return ret;
}
static int mxc_isi_pm_resume(struct device *dev)
{
- return pm_runtime_force_resume(dev);
+ struct mxc_isi_dev *mxc_isi = dev_get_drvdata(dev);
+ int ret;
+
+ ret = pm_runtime_force_resume(dev);
+ if (ret < 0)
+ return ret;
+
+ disp_mix_sft_rstn(mxc_isi->gpr, false);
+ disp_mix_clks_enable(mxc_isi->gpr, true);
+
+ return 0;
}
#endif
{
struct mxc_isi_dev *mxc_isi = dev_get_drvdata(dev);
- clk_disable_unprepare(mxc_isi->clk);
+ mxc_isi_clk_disable(mxc_isi);
+
return 0;
}
struct mxc_isi_dev *mxc_isi = dev_get_drvdata(dev);
int ret;
- ret = clk_prepare_enable(mxc_isi->clk);
- if (ret)
+ ret = mxc_isi_clk_enable(mxc_isi);
+ if (ret) {
dev_err(dev, "%s clk enable fail\n", __func__);
+ return ret;
+ }
- return (ret) ? ret : 0;
+ return 0;
}
static const struct dev_pm_ops mxc_isi_pm_ops = {
};
static const struct of_device_id mxc_isi_of_match[] = {
- {.compatible = "fsl,imx8-isi",},
+ {.compatible = "fsl,imx8-isi", .data = &mxc_imx8_data },
+ {.compatible = "fsl,imx8mn-isi", .data = &mxc_imx8mn_data },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, mxc_isi_of_match);
#define ISI_OF_NODE_NAME "isi"
+/* display_mix_sft_rstn_csr */
+#define EN_BUS_BLK_CLK_RSTN BIT(8)
+#define EN_ISI_APB_CLK_RSTN BIT(7)
+#define EN_ISI_PROC_CLK_RSTN BIT(6)
+
+/* display_mix_clk_en_csr */
+#define EN_BUS_BLK_CLK BIT(8)
+#define EN_ISI_APB_CLK BIT(7)
+#define EN_ISI_PROC_CLK BIT(6)
+
#define MXC_ISI_SD_PAD_SINK_MIPI0_VC0 0
#define MXC_ISI_SD_PAD_SINK_MIPI0_VC1 1
#define MXC_ISI_SD_PAD_SINK_MIPI0_VC2 2
struct mxc_isi_frame src_f;
struct mxc_isi_frame dst_f;
- u32 frame_count;
+ u32 frame_count;
u32 buf_index;
};
+struct mxc_isi_dev_ops {
+ int (*clk_get)(struct mxc_isi_dev *mxc_isi);
+ int (*clk_enable)(struct mxc_isi_dev *mxc_isi);
+ void (*clk_disable)(struct mxc_isi_dev *mxc_isi);
+};
+
struct mxc_isi_dev {
spinlock_t slock;
struct mutex lock;
struct mutex m2m_lock;
wait_queue_head_t irq_queue;
- int id;
+ int id;
void __iomem *regs;
unsigned long state;
struct platform_device *pdev;
- struct v4l2_device *v4l2_dev;
+ struct v4l2_device *v4l2_dev;
struct mxc_isi_m2m_dev m2m;
struct mxc_isi_cap_dev isi_cap;
- struct clk *clk;
+
+ struct clk *clk;
+ struct clk *clk_disp_axi;
+ struct clk *clk_disp_apb;
+ struct clk *clk_root_disp_axi;
+ struct clk *clk_root_disp_apb;
+
+ struct regmap *gpr;
+ const struct mxc_isi_dev_ops *ops;
u32 interface[MAX_PORTS];
u32 flags;
dev_dbg(dev, "CHNL_OUT_BUF2_ADDR_Y 0x8Ch = 0x%8x\n", readl(mxc_isi->regs + 0x8C));
dev_dbg(dev, "CHNL_OUT_BUF2_ADDR_U 0x90h = 0x%8x\n", readl(mxc_isi->regs + 0x90));
dev_dbg(dev, "CHNL_OUT_BUF2_ADDR_V 0x94h = 0x%8x\n", readl(mxc_isi->regs + 0x94));
+ dev_dbg(dev, "CHNL_SCL_IMG_CFG 0x98h = 0x%8x\n", readl(mxc_isi->regs + 0x98));
+ dev_dbg(dev, "CHNL_FLOW_CTRL 0x9Ch = 0x%8x\n", readl(mxc_isi->regs + 0x9C));
}
#else
void dump_isi_regs(struct mxc_isi_dev *mxc_isi)
#define CHNL_OUT_BUF2_ADDR_V 0x94
/* Channel scale image config */
-#define CHNL_SCL_IMG_CFG 0x98
+#define CHNL_SCL_IMG_CFG 0x98
#define CHNL_SCL_IMG_CFG_HEIGHT_OFFSET 16
#define CHNL_SCL_IMG_CFG_HEIGHT_MASK 0x1FFF0000
#define CHNL_SCL_IMG_CFG_WIDTH_OFFSET 0
#define CHNL_SCL_IMG_CFG_WIDTH_MASK 0x1FFF
+/* Channel Flow Control Register */
+#define CHNL_FLOW_CTRL 0x9C
+#define CHNL_FLOW_CTRL_FC_DENOM_MASK 0xFF
+#define CHNL_FLOW_CTRL_FC_DENOM_OFFSET 0
+#define CHNL_FLOW_CTRL_FC_NUMER_MASK 0xFF0000
+#define CHNL_FLOW_CTRL_FC_NUMER_OFFSET 0
+
enum isi_csi_coeff {
YUV2RGB = 0,
RGB2YUV,
#include "mxc-isi-core.h"
#include "mxc-mipi-csi2.h"
#include "mxc-parallel-csi.h"
+#include "mxc-mipi-csi2-sam.h"
+
+static void set_soc_version(struct mxc_md *mxc_md)
+{
+ if (of_machine_is_compatible("fsl,imx8mn"))
+ mxc_md->plat = MXC_IMX8MN;
+ else if (of_machine_is_compatible("fsl,imx8qxp"))
+ mxc_md->plat = MXC_IMX8QXP;
+ else if (of_machine_is_compatible("fsl,imx8qm"))
+ mxc_md->plat = MXC_IMX8QM;
+ else
+ mxc_md->plat = INVALID_SOC;
+}
+
+static enum platform get_soc_version(struct mxc_md *mxc_md)
+{
+ return mxc_md->plat;
+}
/*create default links between registered entities */
static int mxc_md_create_links(struct mxc_md *mxc_md)
struct mxc_sensor_info *sensor;
struct mxc_mipi_csi2_dev *mipi_csi2;
struct mxc_parallel_csi_dev *pcsidev;
+ struct csi_state *state;
int num_sensors = mxc_md->subdev_notifier.num_subdevs;
int i, j, ret = 0;
u16 source_pad, sink_pad;
switch (mxc_isi->interface[IN_PORT]) {
case ISI_INPUT_INTERFACE_MIPI0_CSI2:
- if (mxc_md->mipi_csi2[0] == NULL)
- continue;
- source = &mxc_md->mipi_csi2[0]->sd.entity;
+ if (get_soc_version(mxc_md) == MXC_IMX8MN) {
+ if (mxc_md->state[0] == NULL)
+ continue;
+ source = &mxc_md->state[0]->sd.entity;
+ } else {
+ if (mxc_md->mipi_csi2[0] == NULL)
+ continue;
+ source = &mxc_md->mipi_csi2[0]->sd.entity;
+ }
switch (mxc_isi->interface[SUB_IN_PORT]) {
case ISI_INPUT_SUB_INTERFACE_VC1:
break;
case ISI_INPUT_INTERFACE_MIPI1_CSI2:
- if (mxc_md->mipi_csi2[1] == NULL)
- continue;
- source = &mxc_md->mipi_csi2[1]->sd.entity;
+ if (get_soc_version(mxc_md) == MXC_IMX8MN) {
+ if (mxc_md->state[1] == NULL)
+ continue;
+ source = &mxc_md->state[1]->sd.entity;
+ } else {
+ if (mxc_md->mipi_csi2[1] == NULL)
+ continue;
+ source = &mxc_md->mipi_csi2[1]->sd.entity;
+ }
switch (mxc_isi->interface[SUB_IN_PORT]) {
case ISI_INPUT_SUB_INTERFACE_VC1:
return ret;
v4l2_info(&mxc_md->v4l2_dev, "created link [%s] => [%s]\n",
sensor->sd->entity.name, pcsidev->sd.entity.name);
- } else if (mxc_md->mipi_csi2) {
- mipi_csi2 = mxc_md->mipi_csi2[sensor->id];
- if (mipi_csi2 == NULL)
- continue;
+ } else if (mxc_md->mipi_csi2 || mxc_md->state) {
+ if (get_soc_version(mxc_md) == MXC_IMX8MN) {
+ state = mxc_md->state[sensor->id];
+ if (state == NULL)
+ continue;
+
+ sink = &state->sd.entity;
+ mipi_vc = (state->vchannel == true) ? 4 : 1;
+ } else {
+ mipi_csi2 = mxc_md->mipi_csi2[sensor->id];
+ if (mipi_csi2 == NULL)
+ continue;
+
+ sink = &mipi_csi2->sd.entity;
+ mipi_vc = (mipi_csi2->vchannel == true) ? 4 : 1;
+ }
source = &sensor->sd->entity;
- sink = &mipi_csi2->sd.entity;
source_pad = 0; /* sensor source pad: MIPI_CSI2_SENS_VC0_PAD_SOURCE */
sink_pad = source_pad; /* mipi sink pad: MXC_MIPI_CSI2_VC0_PAD_SINK; */
- if (mipi_csi2->vchannel == true)
- mipi_vc = 4;
- else
- mipi_vc = 1;
-
for (j = 0; j < mipi_vc; j++) {
ret = media_create_pad_link(source, source_pad + j, sink, sink_pad + j,
MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
return ret;
}
v4l2_info(&mxc_md->v4l2_dev, "created link [%s] => [%s]\n",
- sensor->sd->entity.name, mipi_csi2->sd.entity.name);
+ source->name, sink->name);
}
}
dev_info(&mxc_md->pdev->dev, "%s\n", __func__);
return ret;
}
-static int register_mipi_csi2_entity(struct mxc_md *mxc_md,
- struct mxc_mipi_csi2_dev *mipi_csi2)
+static int register_mipi_csi2_entity(struct mxc_md *mxc_md, void *data)
{
- struct v4l2_subdev *sd = &mipi_csi2->sd;
- int ret;
+ struct mxc_mipi_csi2_dev *mipi_csi2 = NULL;
+ struct csi_state *state = NULL;
+ struct v4l2_subdev *sd;
+ int ret, id;
+
+ if (get_soc_version(mxc_md) == MXC_IMX8MN) {
+ state = (struct csi_state *)data;
+ sd = &state->sd;
+ id = state->id;
+ } else {
+ mipi_csi2 = (struct mxc_mipi_csi2_dev *)data;
+ sd = &mipi_csi2->sd;
+ id = mipi_csi2->id;
+ }
- if (WARN_ON(mipi_csi2->id >= MXC_MIPI_CSI2_MAX_DEVS))
+ if (WARN_ON(id >= MXC_MIPI_CSI2_MAX_DEVS || id < 0))
return -ENOENT;
sd->grp_id = GRP_ID_MXC_MIPI_CSI2;
ret = v4l2_device_register_subdev(&mxc_md->v4l2_dev, sd);
- if (!ret)
- mxc_md->mipi_csi2[mipi_csi2->id] = mipi_csi2;
- else
+ if (!ret) {
+ if (get_soc_version(mxc_md) == MXC_IMX8MN)
+ mxc_md->state[id] = state;
+ else
+ mxc_md->mipi_csi2[id] = mipi_csi2;
+ } else
v4l2_err(&mxc_md->v4l2_dev,
- "Failed to register MIPI-CSIS.%d (%d)\n", mipi_csi2->id, ret);
+ "Failed to register MIPI-CSIS.%d (%d)\n", id, ret);
return ret;
}
mxc_md->pdev = pdev;
platform_set_drvdata(pdev, mxc_md);
+ set_soc_version(mxc_md);
+ if (get_soc_version(mxc_md) == INVALID_SOC) {
+ dev_err(dev, "Not support soc\n");
+ return -ENODEV;
+ }
+
mxc_md->parallel_csi = of_property_read_bool(dev->of_node, "parallel_csi");
/* register media device */
}
static const struct of_device_id mxc_md_of_match[] = {
- { .compatible = "fsl,mxc-md",},
+ { .compatible = "fsl,mxc-md",},
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, mxc_md_of_match);
#include <media/v4l2-ioctl.h>
#include <media/v4l2-mem2mem.h>
#include <media/videobuf2-core.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
#include "mxc-mipi-csi2.h"
+#include "mxc-mipi-csi2-sam.h"
#include "mxc-isi-core.h"
#include "mxc-isi-hw.h"
#include "hdmi/mxc-hdmi-rx.h"
IDX_MAX,
};
+enum platform {
+ MXC_IMX8QM = 0,
+ MXC_IMX8QXP,
+ MXC_IMX8MN,
+ INVALID_SOC,
+};
+
struct mxc_sensor_info {
int id;
struct v4l2_subdev *sd;
};
struct mxc_md {
- struct mxc_isi_dev *mxc_isi[MXC_ISI_MAX_DEVS];
- struct mxc_hdmi_rx_dev *hdmi_rx;
- struct mxc_parallel_csi_dev *pcsidev;
- struct mxc_mipi_csi2_dev *mipi_csi2[MXC_MIPI_CSI2_MAX_DEVS];
- struct mxc_sensor_info sensor[MXC_MAX_SENSORS];
- struct mxc_mjpeg_dec *mjpeg_dec;
- struct mxc_mjpeg_enc *mjpeg_enc;
-
- int link_status;
- int num_sensors;
- unsigned int nr_isi;
+ struct mxc_isi_dev *mxc_isi[MXC_ISI_MAX_DEVS];
+ struct mxc_hdmi_rx_dev *hdmi_rx;
+ struct mxc_parallel_csi_dev *pcsidev;
+ struct mxc_mipi_csi2_dev *mipi_csi2[MXC_MIPI_CSI2_MAX_DEVS];
+ struct csi_state *state[MXC_MIPI_CSI2_MAX_DEVS];
+ struct mxc_sensor_info sensor[MXC_MAX_SENSORS];
+ struct mxc_mjpeg_dec *mjpeg_dec;
+ struct mxc_mjpeg_enc *mjpeg_enc;
+
+ int link_status;
+ int num_sensors;
+ u32 nr_isi;
bool parallel_csi;
- struct media_device media_dev;
- struct v4l2_device v4l2_dev;
- struct platform_device *pdev;
+ struct media_device media_dev;
+ struct v4l2_device v4l2_dev;
+ struct platform_device *pdev;
+
+ struct v4l2_async_notifier subdev_notifier;
+ struct v4l2_async_subdev *async_subdevs[MXC_MAX_SENSORS];
- struct v4l2_async_notifier subdev_notifier;
- struct v4l2_async_subdev *async_subdevs[MXC_MAX_SENSORS];
+ enum platform plat;
};
static inline struct mxc_md *notifier_to_mxc_md(struct v4l2_async_notifier *n)