mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
media: rockchip: cif fixes the problem of failure to get sof
Signed-off-by: Zefa Chen <zefa.chen@rock-chips.com> Change-Id: I5d76a221154809d7fa351e7f9ff0db8fe5b94bde
This commit is contained in:
@@ -5120,6 +5120,14 @@ static u32 rkcif_lvds_get_sof(struct rkcif_device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 rkcif_lvds_set_sof(struct rkcif_device *dev, u32 seq)
|
||||
{
|
||||
if (dev)
|
||||
atomic_set(&dev->lvds_subdev.frm_sync_seq, seq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rkcif_register_lvds_subdev(struct rkcif_device *dev)
|
||||
{
|
||||
struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
|
||||
@@ -5205,6 +5213,14 @@ static u32 rkcif_dvp_get_sof(struct rkcif_device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 rkcif_dvp_set_sof(struct rkcif_device *dev, u32 seq)
|
||||
{
|
||||
if (dev)
|
||||
atomic_set(&dev->dvp_sof_subdev.frm_sync_seq, seq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct v4l2_subdev_core_ops rkcif_dvp_sof_sd_core_ops = {
|
||||
.subscribe_event = rkcif_sof_subscribe_event,
|
||||
.unsubscribe_event = v4l2_event_subdev_unsubscribe,
|
||||
@@ -6169,23 +6185,42 @@ static void rkcif_update_stream_toisp(struct rkcif_device *cif_dev,
|
||||
stream->frame_idx++;
|
||||
}
|
||||
|
||||
u32 rkcif_get_sof(struct rkcif_device *cif_dev)
|
||||
static u32 rkcif_get_sof(struct rkcif_device *cif_dev)
|
||||
{
|
||||
u32 val = 0x0;
|
||||
struct rkcif_sensor_info *sensor = cif_dev->active_sensor;
|
||||
struct csi2_dev *csi;
|
||||
|
||||
if (sensor->mbus.type == V4L2_MBUS_CSI2_DPHY ||
|
||||
sensor->mbus.type == V4L2_MBUS_CSI2_CPHY)
|
||||
val = rkcif_csi2_get_sof();
|
||||
else if (sensor->mbus.type == V4L2_MBUS_CCP2)
|
||||
sensor->mbus.type == V4L2_MBUS_CSI2_CPHY) {
|
||||
csi = container_of(sensor->sd, struct csi2_dev, sd);
|
||||
val = rkcif_csi2_get_sof(csi);
|
||||
} else if (sensor->mbus.type == V4L2_MBUS_CCP2) {
|
||||
val = rkcif_lvds_get_sof(cif_dev);
|
||||
else if (sensor->mbus.type == V4L2_MBUS_PARALLEL ||
|
||||
sensor->mbus.type == V4L2_MBUS_BT656)
|
||||
} else if (sensor->mbus.type == V4L2_MBUS_PARALLEL ||
|
||||
sensor->mbus.type == V4L2_MBUS_BT656) {
|
||||
val = rkcif_dvp_get_sof(cif_dev);
|
||||
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
static void rkcif_set_sof(struct rkcif_device *cif_dev, u32 seq)
|
||||
{
|
||||
struct rkcif_sensor_info *sensor = cif_dev->active_sensor;
|
||||
struct csi2_dev *csi;
|
||||
|
||||
if (sensor->mbus.type == V4L2_MBUS_CSI2_DPHY ||
|
||||
sensor->mbus.type == V4L2_MBUS_CSI2_CPHY) {
|
||||
csi = container_of(sensor->sd, struct csi2_dev, sd);
|
||||
rkcif_csi2_set_sof(csi, seq);
|
||||
} else if (sensor->mbus.type == V4L2_MBUS_CCP2) {
|
||||
rkcif_lvds_set_sof(cif_dev, seq);
|
||||
} else if (sensor->mbus.type == V4L2_MBUS_PARALLEL ||
|
||||
sensor->mbus.type == V4L2_MBUS_BT656) {
|
||||
rkcif_dvp_set_sof(cif_dev, seq);
|
||||
}
|
||||
}
|
||||
|
||||
static int rkcif_do_reset_work(struct rkcif_device *cif_dev,
|
||||
enum rkmodule_reset_src reset_src)
|
||||
{
|
||||
@@ -6247,7 +6282,7 @@ static int rkcif_do_reset_work(struct rkcif_device *cif_dev,
|
||||
|
||||
v4l2_dbg(1, rkcif_debug, &cif_dev->v4l2_dev,
|
||||
"%s stop stream[%d] in streaming, frm_id:%d, csi_sof:%d\n",
|
||||
__func__, stream->id, stream->frame_idx, rkcif_csi2_get_sof());
|
||||
__func__, stream->id, stream->frame_idx, rkcif_get_sof(cif_dev));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -6317,7 +6352,7 @@ static int rkcif_do_reset_work(struct rkcif_device *cif_dev,
|
||||
v4l2_dbg(1, rkcif_debug, &cif_dev->v4l2_dev,
|
||||
"resume stream[%d], frm_idx:%d, csi_sof:%d\n",
|
||||
stream->id, stream->frame_idx,
|
||||
rkcif_csi2_get_sof());
|
||||
rkcif_get_sof(cif_dev));
|
||||
}
|
||||
|
||||
rockchip_set_system_status(SYS_STATUS_CIF0);
|
||||
@@ -6327,7 +6362,7 @@ static int rkcif_do_reset_work(struct rkcif_device *cif_dev,
|
||||
|
||||
if (p->subdevs[i] == terminal_sensor->sd) {
|
||||
|
||||
rkcif_csi2_set_sof(resume_info->frm_sync_seq);
|
||||
rkcif_set_sof(cif_dev, resume_info->frm_sync_seq);
|
||||
|
||||
if (reset_src == RKCIF_RESET_SRC_ERR_CSI2 ||
|
||||
reset_src == RKCIF_RESET_SRC_ERR_HOTPLUG ||
|
||||
@@ -6341,7 +6376,7 @@ static int rkcif_do_reset_work(struct rkcif_device *cif_dev,
|
||||
}
|
||||
} else {
|
||||
if (p->subdevs[i] == terminal_sensor->sd)
|
||||
rkcif_csi2_set_sof(resume_info->frm_sync_seq);
|
||||
rkcif_set_sof(cif_dev, resume_info->frm_sync_seq);
|
||||
|
||||
ret = v4l2_subdev_call(p->subdevs[i], video, s_stream, on);
|
||||
}
|
||||
@@ -6948,15 +6983,18 @@ static void rkcif_deal_sof(struct rkcif_device *cif_dev)
|
||||
{
|
||||
struct rkcif_stream *detect_stream = &cif_dev->stream[0];
|
||||
struct v4l2_mbus_config *mbus = &cif_dev->active_sensor->mbus;
|
||||
struct csi2_dev *csi;
|
||||
unsigned long flags;
|
||||
|
||||
if (mbus->type == V4L2_MBUS_CSI2_DPHY ||
|
||||
mbus->type == V4L2_MBUS_CSI2_CPHY)
|
||||
rkcif_csi2_event_inc_sof();
|
||||
else if (mbus->type == V4L2_MBUS_CCP2)
|
||||
mbus->type == V4L2_MBUS_CSI2_CPHY) {
|
||||
csi = container_of(cif_dev->active_sensor->sd, struct csi2_dev, sd);
|
||||
rkcif_csi2_event_inc_sof(csi);
|
||||
} else if (mbus->type == V4L2_MBUS_CCP2) {
|
||||
rkcif_lvds_event_inc_sof(cif_dev);
|
||||
else
|
||||
} else {
|
||||
rkcif_dvp_event_inc_sof(cif_dev);
|
||||
}
|
||||
|
||||
detect_stream->fs_cnt_in_single_frame++;
|
||||
spin_lock_irqsave(&detect_stream->fps_lock, flags);
|
||||
|
||||
@@ -115,11 +115,6 @@ enum rkcif_state {
|
||||
RKCIF_STATE_RESET_IN_STREAMING,
|
||||
};
|
||||
|
||||
enum host_type_t {
|
||||
RK_CSI_RXHOST,
|
||||
RK_DSI_RXHOST
|
||||
};
|
||||
|
||||
enum rkcif_lvds_pad {
|
||||
RKCIF_LVDS_PAD_SINK = 0x0,
|
||||
RKCIF_LVDS_PAD_SRC_ID0,
|
||||
@@ -760,7 +755,6 @@ void rkcif_unregister_lvds_subdev(struct rkcif_device *dev);
|
||||
int rkcif_register_dvp_sof_subdev(struct rkcif_device *dev);
|
||||
void rkcif_unregister_dvp_sof_subdev(struct rkcif_device *dev);
|
||||
void rkcif_irq_lite_lvds(struct rkcif_device *cif_dev);
|
||||
u32 rkcif_get_sof(struct rkcif_device *cif_dev);
|
||||
int rkcif_plat_init(struct rkcif_device *cif_dev, struct device_node *node, int inf_id);
|
||||
int rkcif_plat_uninit(struct rkcif_device *cif_dev);
|
||||
int rkcif_attach_hw(struct rkcif_device *cif_dev);
|
||||
|
||||
@@ -15,157 +15,15 @@
|
||||
#include <linux/of_graph.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/reset.h>
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-fwnode.h>
|
||||
#include <media/v4l2-subdev.h>
|
||||
#include <media/v4l2-event.h>
|
||||
|
||||
#include "mipi-csi2.h"
|
||||
|
||||
static int csi2_debug;
|
||||
module_param_named(debug_csi2, csi2_debug, int, 0644);
|
||||
MODULE_PARM_DESC(debug_csi2, "Debug level (0-1)");
|
||||
|
||||
/*
|
||||
* there must be 5 pads: 1 input pad from sensor, and
|
||||
* the 4 virtual channel output pads
|
||||
*/
|
||||
#define CSI2_SINK_PAD 0
|
||||
#define CSI2_NUM_SINK_PADS 4
|
||||
#define CSI2_NUM_SRC_PADS 8
|
||||
#define CSI2_NUM_PADS 5
|
||||
#define CSI2_NUM_PADS_MAX 9
|
||||
#define CSI2_NUM_PADS_SINGLE_LINK 2
|
||||
#define MAX_CSI2_SENSORS 2
|
||||
|
||||
#define RKCIF_DEFAULT_WIDTH 640
|
||||
#define RKCIF_DEFAULT_HEIGHT 480
|
||||
|
||||
/*
|
||||
* The default maximum bit-rate per lane in Mbps, if the
|
||||
* source subdev does not provide V4L2_CID_LINK_FREQ.
|
||||
*/
|
||||
#define CSI2_DEFAULT_MAX_MBPS 849
|
||||
|
||||
#define IMX_MEDIA_GRP_ID_CSI2 BIT(8)
|
||||
#define CSIHOST_MAX_ERRINT_COUNT 10
|
||||
|
||||
/*
|
||||
* add new chip id in tail in time order
|
||||
* by increasing to distinguish csi2 host version
|
||||
*/
|
||||
enum rkcsi2_chip_id {
|
||||
CHIP_PX30_CSI2,
|
||||
CHIP_RK1808_CSI2,
|
||||
CHIP_RK3128_CSI2,
|
||||
CHIP_RK3288_CSI2,
|
||||
CHIP_RV1126_CSI2,
|
||||
CHIP_RK3568_CSI2,
|
||||
CHIP_RK3588_CSI2,
|
||||
};
|
||||
|
||||
enum csi2_pads {
|
||||
RK_CSI2_PAD_SINK = 0,
|
||||
RK_CSI2X_PAD_SOURCE0,
|
||||
RK_CSI2X_PAD_SOURCE1,
|
||||
RK_CSI2X_PAD_SOURCE2,
|
||||
RK_CSI2X_PAD_SOURCE3
|
||||
};
|
||||
|
||||
enum csi2_err {
|
||||
RK_CSI2_ERR_SOTSYN = 0x0,
|
||||
RK_CSI2_ERR_FS_FE_MIS,
|
||||
RK_CSI2_ERR_FRM_SEQ_ERR,
|
||||
RK_CSI2_ERR_CRC_ONCE,
|
||||
RK_CSI2_ERR_CRC,
|
||||
RK_CSI2_ERR_ALL,
|
||||
RK_CSI2_ERR_MAX
|
||||
};
|
||||
|
||||
enum host_type_t {
|
||||
RK_CSI_RXHOST,
|
||||
RK_DSI_RXHOST
|
||||
};
|
||||
|
||||
struct csi2_match_data {
|
||||
int chip_id;
|
||||
int num_pads;
|
||||
};
|
||||
|
||||
struct csi2_sensor {
|
||||
struct v4l2_subdev *sd;
|
||||
struct v4l2_mbus_config mbus;
|
||||
int lanes;
|
||||
};
|
||||
|
||||
struct csi2_err_stats {
|
||||
unsigned int cnt;
|
||||
};
|
||||
|
||||
struct csi2_dev {
|
||||
struct device *dev;
|
||||
struct v4l2_subdev sd;
|
||||
struct media_pad pad[CSI2_NUM_PADS_MAX];
|
||||
struct clk_bulk_data *clks_bulk;
|
||||
int clks_num;
|
||||
struct reset_control *rsts_bulk;
|
||||
|
||||
void __iomem *base;
|
||||
struct v4l2_async_notifier notifier;
|
||||
struct v4l2_fwnode_bus_mipi_csi2 bus;
|
||||
|
||||
/* lock to protect all members below */
|
||||
struct mutex lock;
|
||||
|
||||
struct v4l2_mbus_framefmt format_mbus;
|
||||
struct v4l2_rect crop;
|
||||
int stream_count;
|
||||
struct v4l2_subdev *src_sd;
|
||||
bool sink_linked[CSI2_NUM_SRC_PADS];
|
||||
struct csi2_sensor sensors[MAX_CSI2_SENSORS];
|
||||
const struct csi2_match_data *match_data;
|
||||
int num_sensors;
|
||||
atomic_t frm_sync_seq;
|
||||
struct csi2_err_stats err_list[RK_CSI2_ERR_MAX];
|
||||
};
|
||||
|
||||
#define DEVICE_NAME "rockchip-mipi-csi2"
|
||||
|
||||
/* CSI Host Registers Define */
|
||||
#define CSIHOST_N_LANES 0x04
|
||||
#define CSIHOST_DPHY_SHUTDOWNZ 0x08
|
||||
#define CSIHOST_PHY_RSTZ 0x0c
|
||||
#define CSIHOST_RESETN 0x10
|
||||
#define CSIHOST_PHY_STATE 0x14
|
||||
#define CSIHOST_ERR1 0x20
|
||||
#define CSIHOST_ERR2 0x24
|
||||
#define CSIHOST_MSK1 0x28
|
||||
#define CSIHOST_MSK2 0x2c
|
||||
#define CSIHOST_CONTROL 0x40
|
||||
|
||||
#define CSIHOST_ERR1_PHYERR_SPTSYNCHS 0x0000000f
|
||||
#define CSIHOST_ERR1_ERR_BNDRY_MATCH 0x000000f0
|
||||
#define CSIHOST_ERR1_ERR_SEQ 0x00000f00
|
||||
#define CSIHOST_ERR1_ERR_FRM_DATA 0x0000f000
|
||||
#define CSIHOST_ERR1_ERR_CRC 0x1f000000
|
||||
|
||||
#define CSIHOST_ERR2_PHYERR_ESC 0x0000000f
|
||||
#define CSIHOST_ERR2_PHYERR_SOTHS 0x000000f0
|
||||
#define CSIHOST_ERR2_ECC_CORRECTED 0x00000f00
|
||||
#define CSIHOST_ERR2_ERR_ID 0x0000f000
|
||||
#define CSIHOST_ERR2_PHYERR_CODEHS 0x01000000
|
||||
|
||||
#define SW_CPHY_EN(x) ((x) << 0)
|
||||
#define SW_DSI_EN(x) ((x) << 4)
|
||||
#define SW_DATATYPE_FS(x) ((x) << 8)
|
||||
#define SW_DATATYPE_FE(x) ((x) << 14)
|
||||
#define SW_DATATYPE_LS(x) ((x) << 20)
|
||||
#define SW_DATATYPE_LE(x) ((x) << 26)
|
||||
|
||||
#define write_csihost_reg(base, addr, val) writel(val, (addr) + (base))
|
||||
#define read_csihost_reg(base, addr) readl((addr) + (base))
|
||||
|
||||
static struct csi2_dev *g_csi2_dev;
|
||||
static ATOMIC_NOTIFIER_HEAD(g_csi_host_chain);
|
||||
|
||||
int rkcif_csi2_register_notifier(struct notifier_block *nb)
|
||||
@@ -604,32 +462,30 @@ static const struct media_entity_operations csi2_entity_ops = {
|
||||
.link_validate = v4l2_subdev_link_validate,
|
||||
};
|
||||
|
||||
void rkcif_csi2_event_inc_sof(void)
|
||||
void rkcif_csi2_event_inc_sof(struct csi2_dev *csi2_dev)
|
||||
{
|
||||
if (g_csi2_dev) {
|
||||
if (csi2_dev) {
|
||||
struct v4l2_event event = {
|
||||
.type = V4L2_EVENT_FRAME_SYNC,
|
||||
.u.frame_sync.frame_sequence =
|
||||
atomic_inc_return(&g_csi2_dev->frm_sync_seq) - 1,
|
||||
atomic_inc_return(&csi2_dev->frm_sync_seq) - 1,
|
||||
};
|
||||
v4l2_event_queue(g_csi2_dev->sd.devnode, &event);
|
||||
v4l2_event_queue(csi2_dev->sd.devnode, &event);
|
||||
}
|
||||
}
|
||||
|
||||
u32 rkcif_csi2_get_sof(void)
|
||||
u32 rkcif_csi2_get_sof(struct csi2_dev *csi2_dev)
|
||||
{
|
||||
if (g_csi2_dev) {
|
||||
return atomic_read(&g_csi2_dev->frm_sync_seq) - 1;
|
||||
}
|
||||
if (csi2_dev)
|
||||
return atomic_read(&csi2_dev->frm_sync_seq) - 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rkcif_csi2_set_sof(u32 seq)
|
||||
void rkcif_csi2_set_sof(struct csi2_dev *csi2_dev, u32 seq)
|
||||
{
|
||||
if (g_csi2_dev) {
|
||||
atomic_set(&g_csi2_dev->frm_sync_seq, seq);
|
||||
}
|
||||
if (csi2_dev)
|
||||
atomic_set(&csi2_dev->frm_sync_seq, seq);
|
||||
}
|
||||
|
||||
static int rkcif_csi2_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
|
||||
@@ -1029,8 +885,6 @@ static int csi2_probe(struct platform_device *pdev)
|
||||
|
||||
csi2_hw_do_reset(csi2);
|
||||
|
||||
g_csi2_dev = csi2;
|
||||
|
||||
v4l2_info(&csi2->sd, "probe success, v4l2_dev:%s!\n", csi2->sd.v4l2_dev->name);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -4,13 +4,153 @@
|
||||
#define _RKCIF_MIPI_CSI2_H_
|
||||
|
||||
#include <linux/notifier.h>
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-fwnode.h>
|
||||
#include <media/v4l2-subdev.h>
|
||||
#include <media/v4l2-event.h>
|
||||
|
||||
#define CSI2_ERR_FSFE_MASK (0xff << 8)
|
||||
#define CSI2_ERR_COUNT_ALL_MASK (0xff)
|
||||
|
||||
u32 rkcif_csi2_get_sof(void);
|
||||
void rkcif_csi2_set_sof(u32 seq);
|
||||
void rkcif_csi2_event_inc_sof(void);
|
||||
/*
|
||||
* there must be 5 pads: 1 input pad from sensor, and
|
||||
* the 4 virtual channel output pads
|
||||
*/
|
||||
#define CSI2_SINK_PAD 0
|
||||
#define CSI2_NUM_SINK_PADS 4
|
||||
#define CSI2_NUM_SRC_PADS 8
|
||||
#define CSI2_NUM_PADS 5
|
||||
#define CSI2_NUM_PADS_MAX 9
|
||||
#define CSI2_NUM_PADS_SINGLE_LINK 2
|
||||
#define MAX_CSI2_SENSORS 2
|
||||
|
||||
#define RKCIF_DEFAULT_WIDTH 640
|
||||
#define RKCIF_DEFAULT_HEIGHT 480
|
||||
|
||||
/*
|
||||
* The default maximum bit-rate per lane in Mbps, if the
|
||||
* source subdev does not provide V4L2_CID_LINK_FREQ.
|
||||
*/
|
||||
#define CSI2_DEFAULT_MAX_MBPS 849
|
||||
|
||||
#define IMX_MEDIA_GRP_ID_CSI2 BIT(8)
|
||||
#define CSIHOST_MAX_ERRINT_COUNT 10
|
||||
|
||||
#define DEVICE_NAME "rockchip-mipi-csi2"
|
||||
|
||||
/* CSI Host Registers Define */
|
||||
#define CSIHOST_N_LANES 0x04
|
||||
#define CSIHOST_DPHY_SHUTDOWNZ 0x08
|
||||
#define CSIHOST_PHY_RSTZ 0x0c
|
||||
#define CSIHOST_RESETN 0x10
|
||||
#define CSIHOST_PHY_STATE 0x14
|
||||
#define CSIHOST_ERR1 0x20
|
||||
#define CSIHOST_ERR2 0x24
|
||||
#define CSIHOST_MSK1 0x28
|
||||
#define CSIHOST_MSK2 0x2c
|
||||
#define CSIHOST_CONTROL 0x40
|
||||
|
||||
#define CSIHOST_ERR1_PHYERR_SPTSYNCHS 0x0000000f
|
||||
#define CSIHOST_ERR1_ERR_BNDRY_MATCH 0x000000f0
|
||||
#define CSIHOST_ERR1_ERR_SEQ 0x00000f00
|
||||
#define CSIHOST_ERR1_ERR_FRM_DATA 0x0000f000
|
||||
#define CSIHOST_ERR1_ERR_CRC 0x1f000000
|
||||
|
||||
#define CSIHOST_ERR2_PHYERR_ESC 0x0000000f
|
||||
#define CSIHOST_ERR2_PHYERR_SOTHS 0x000000f0
|
||||
#define CSIHOST_ERR2_ECC_CORRECTED 0x00000f00
|
||||
#define CSIHOST_ERR2_ERR_ID 0x0000f000
|
||||
#define CSIHOST_ERR2_PHYERR_CODEHS 0x01000000
|
||||
|
||||
#define SW_CPHY_EN(x) ((x) << 0)
|
||||
#define SW_DSI_EN(x) ((x) << 4)
|
||||
#define SW_DATATYPE_FS(x) ((x) << 8)
|
||||
#define SW_DATATYPE_FE(x) ((x) << 14)
|
||||
#define SW_DATATYPE_LS(x) ((x) << 20)
|
||||
#define SW_DATATYPE_LE(x) ((x) << 26)
|
||||
|
||||
/*
|
||||
* add new chip id in tail in time order
|
||||
* by increasing to distinguish csi2 host version
|
||||
*/
|
||||
enum rkcsi2_chip_id {
|
||||
CHIP_PX30_CSI2,
|
||||
CHIP_RK1808_CSI2,
|
||||
CHIP_RK3128_CSI2,
|
||||
CHIP_RK3288_CSI2,
|
||||
CHIP_RV1126_CSI2,
|
||||
CHIP_RK3568_CSI2,
|
||||
CHIP_RK3588_CSI2,
|
||||
};
|
||||
|
||||
enum csi2_pads {
|
||||
RK_CSI2_PAD_SINK = 0,
|
||||
RK_CSI2X_PAD_SOURCE0,
|
||||
RK_CSI2X_PAD_SOURCE1,
|
||||
RK_CSI2X_PAD_SOURCE2,
|
||||
RK_CSI2X_PAD_SOURCE3
|
||||
};
|
||||
|
||||
enum csi2_err {
|
||||
RK_CSI2_ERR_SOTSYN = 0x0,
|
||||
RK_CSI2_ERR_FS_FE_MIS,
|
||||
RK_CSI2_ERR_FRM_SEQ_ERR,
|
||||
RK_CSI2_ERR_CRC_ONCE,
|
||||
RK_CSI2_ERR_CRC,
|
||||
RK_CSI2_ERR_ALL,
|
||||
RK_CSI2_ERR_MAX
|
||||
};
|
||||
|
||||
enum host_type_t {
|
||||
RK_CSI_RXHOST,
|
||||
RK_DSI_RXHOST
|
||||
};
|
||||
|
||||
struct csi2_match_data {
|
||||
int chip_id;
|
||||
int num_pads;
|
||||
};
|
||||
|
||||
struct csi2_sensor {
|
||||
struct v4l2_subdev *sd;
|
||||
struct v4l2_mbus_config mbus;
|
||||
int lanes;
|
||||
};
|
||||
|
||||
struct csi2_err_stats {
|
||||
unsigned int cnt;
|
||||
};
|
||||
|
||||
struct csi2_dev {
|
||||
struct device *dev;
|
||||
struct v4l2_subdev sd;
|
||||
struct media_pad pad[CSI2_NUM_PADS_MAX];
|
||||
struct clk_bulk_data *clks_bulk;
|
||||
int clks_num;
|
||||
struct reset_control *rsts_bulk;
|
||||
|
||||
void __iomem *base;
|
||||
struct v4l2_async_notifier notifier;
|
||||
struct v4l2_fwnode_bus_mipi_csi2 bus;
|
||||
|
||||
/* lock to protect all members below */
|
||||
struct mutex lock;
|
||||
|
||||
struct v4l2_mbus_framefmt format_mbus;
|
||||
struct v4l2_rect crop;
|
||||
int stream_count;
|
||||
struct v4l2_subdev *src_sd;
|
||||
bool sink_linked[CSI2_NUM_SRC_PADS];
|
||||
struct csi2_sensor sensors[MAX_CSI2_SENSORS];
|
||||
const struct csi2_match_data *match_data;
|
||||
int num_sensors;
|
||||
atomic_t frm_sync_seq;
|
||||
struct csi2_err_stats err_list[RK_CSI2_ERR_MAX];
|
||||
};
|
||||
|
||||
u32 rkcif_csi2_get_sof(struct csi2_dev *csi2_dev);
|
||||
void rkcif_csi2_set_sof(struct csi2_dev *csi2_dev, u32 seq);
|
||||
void rkcif_csi2_event_inc_sof(struct csi2_dev *csi2_dev);
|
||||
int __init rkcif_csi2_plat_drv_init(void);
|
||||
void __exit rkcif_csi2_plat_drv_exit(void);
|
||||
int rkcif_csi2_register_notifier(struct notifier_block *nb);
|
||||
|
||||
Reference in New Issue
Block a user