mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 10:58:48 +09:00
Merge commit 'a9ed7b93e657b49420dc7c02c3ce9ce810e9b7d3'
* commit 'a9ed7b93e657b49420dc7c02c3ce9ce810e9b7d3':
media: rockchip: vicap compatible with rk3588s2
media: rockchip: vicap support combine two mipi to one dev
phy: rockchip: csi2-dphy: logic node of mipi phy can control all hw of mipi phy
Conflicts:
drivers/phy/rockchip/phy-rockchip-csi2-dphy.c
Ignore:
commit 08330d500d ("phy: rockchip: csi2-dphy: logic node of mipi phy can control all hw of mipi phy")
Change-Id: Ief48fe16863dc477a183289f9a4c49881d2d2942
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -364,8 +364,8 @@ static int rkcif_scale_enum_framesizes(struct file *file, void *prov,
|
||||
input_rect.height = RKCIF_DEFAULT_HEIGHT;
|
||||
|
||||
if (terminal_sensor && terminal_sensor->sd)
|
||||
get_input_fmt(terminal_sensor->sd,
|
||||
&input_rect, 0, &csi_info);
|
||||
rkcif_get_input_fmt(dev,
|
||||
&input_rect, 0, &csi_info);
|
||||
|
||||
switch (fsize->index) {
|
||||
case SCALE_8TIMES:
|
||||
|
||||
@@ -300,8 +300,8 @@ static int rkcif_tools_enum_framesizes(struct file *file, void *prov,
|
||||
input_rect.height = RKCIF_DEFAULT_HEIGHT;
|
||||
|
||||
if (terminal_sensor && terminal_sensor->sd)
|
||||
get_input_fmt(terminal_sensor->sd,
|
||||
&input_rect, 0, &csi_info);
|
||||
rkcif_get_input_fmt(dev,
|
||||
&input_rect, 0, &csi_info);
|
||||
|
||||
fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
|
||||
s->width = input_rect.width;
|
||||
|
||||
@@ -1556,16 +1556,6 @@ static int subdev_notifier_complete(struct v4l2_async_notifier *notifier)
|
||||
|
||||
if (!completion_done(&dev->cmpl_ntf))
|
||||
complete(&dev->cmpl_ntf);
|
||||
if (dev->active_sensor &&
|
||||
(dev->active_sensor->mbus.type == V4L2_MBUS_CSI2_DPHY ||
|
||||
dev->active_sensor->mbus.type == V4L2_MBUS_CSI2_CPHY)) {
|
||||
ret = v4l2_subdev_call(dev->active_sensor->sd,
|
||||
core, ioctl,
|
||||
RKCIF_CMD_SET_CSI_IDX,
|
||||
&dev->csi_host_idx);
|
||||
if (ret)
|
||||
v4l2_err(&dev->v4l2_dev, "set csi idx %d fail\n", dev->csi_host_idx);
|
||||
}
|
||||
v4l2_info(&dev->v4l2_dev, "Async subdev notifier completed\n");
|
||||
|
||||
return ret;
|
||||
@@ -1924,6 +1914,7 @@ int rkcif_plat_init(struct rkcif_device *cif_dev, struct device_node *node, int
|
||||
cif_dev->early_line = 0;
|
||||
cif_dev->is_thunderboot = false;
|
||||
cif_dev->rdbk_debug = 0;
|
||||
memset(&cif_dev->channels[0].capture_info, 0, sizeof(cif_dev->channels[0].capture_info));
|
||||
if (cif_dev->chip_id == CHIP_RV1126_CIF_LITE)
|
||||
cif_dev->isr_hdl = rkcif_irq_lite_handler;
|
||||
|
||||
@@ -1981,6 +1972,17 @@ int rkcif_plat_init(struct rkcif_device *cif_dev, struct device_node *node, int
|
||||
cif_dev->csi_host_idx = of_alias_get_id(node, "rkcif_mipi_lvds");
|
||||
if (cif_dev->csi_host_idx < 0 || cif_dev->csi_host_idx > 5)
|
||||
cif_dev->csi_host_idx = 0;
|
||||
if (cif_dev->hw_dev->is_rk3588s2) {
|
||||
if (cif_dev->csi_host_idx == 0)
|
||||
cif_dev->csi_host_idx = 2;
|
||||
else if (cif_dev->csi_host_idx == 2)
|
||||
cif_dev->csi_host_idx = 4;
|
||||
else if (cif_dev->csi_host_idx == 3)
|
||||
cif_dev->csi_host_idx = 5;
|
||||
v4l2_info(&cif_dev->v4l2_dev, "rk3588s2 attach to mipi%d\n",
|
||||
cif_dev->csi_host_idx);
|
||||
}
|
||||
cif_dev->csi_host_idx_def = cif_dev->csi_host_idx;
|
||||
cif_dev->media_dev.dev = dev;
|
||||
v4l2_dev = &cif_dev->v4l2_dev;
|
||||
v4l2_dev->mdev = &cif_dev->media_dev;
|
||||
@@ -2143,7 +2145,9 @@ static int rkcif_plat_probe(struct platform_device *pdev)
|
||||
if (sysfs_create_group(&pdev->dev.kobj, &dev_attr_grp))
|
||||
return -ENODEV;
|
||||
|
||||
rkcif_attach_hw(cif_dev);
|
||||
ret = rkcif_attach_hw(cif_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
rkcif_parse_dts(cif_dev);
|
||||
|
||||
|
||||
@@ -280,10 +280,12 @@ struct csi_channel_info {
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int virtual_width;
|
||||
unsigned int left_virtual_width;
|
||||
unsigned int crop_st_x;
|
||||
unsigned int crop_st_y;
|
||||
unsigned int dsi_input;
|
||||
struct rkmodule_lvds_cfg lvds_cfg;
|
||||
struct rkmodule_capture_info capture_info;
|
||||
};
|
||||
|
||||
struct rkcif_vdev_node {
|
||||
@@ -843,6 +845,7 @@ struct rkcif_device {
|
||||
struct rkcif_work_struct reset_work;
|
||||
int id_use_cnt;
|
||||
unsigned int csi_host_idx;
|
||||
unsigned int csi_host_idx_def;
|
||||
unsigned int dvp_sof_in_oneframe;
|
||||
unsigned int wait_line;
|
||||
unsigned int wait_line_bak;
|
||||
@@ -885,7 +888,7 @@ void rkcif_vb_done_tasklet(struct rkcif_stream *stream, struct rkcif_buffer *buf
|
||||
int rkcif_scale_start(struct rkcif_scale_vdev *scale_vdev);
|
||||
|
||||
const struct
|
||||
cif_input_fmt *get_input_fmt(struct v4l2_subdev *sd,
|
||||
cif_input_fmt *rkcif_get_input_fmt(struct rkcif_device *dev,
|
||||
struct v4l2_rect *rect,
|
||||
u32 pad_id, struct csi_channel_info *csi_info);
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/nvmem-consumer.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/of_graph.h>
|
||||
@@ -1252,6 +1253,51 @@ void rkcif_hw_soft_reset(struct rkcif_hw *cif_hw, bool is_rst_iommu)
|
||||
rkcif_iommu_enable(cif_hw);
|
||||
}
|
||||
|
||||
static int rkcif_get_efuse_value(struct device_node *np, char *porp_name,
|
||||
u8 *value)
|
||||
{
|
||||
struct nvmem_cell *cell;
|
||||
unsigned char *buf;
|
||||
size_t len;
|
||||
|
||||
cell = of_nvmem_cell_get(np, porp_name);
|
||||
if (IS_ERR(cell))
|
||||
return PTR_ERR(cell);
|
||||
|
||||
buf = (unsigned char *)nvmem_cell_read(cell, &len);
|
||||
|
||||
nvmem_cell_put(cell);
|
||||
|
||||
if (IS_ERR(buf))
|
||||
return PTR_ERR(buf);
|
||||
|
||||
*value = buf[0];
|
||||
|
||||
kfree(buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rkcif_get_speciand_package_number(struct device_node *np)
|
||||
{
|
||||
u8 spec = 0, package = 0, low = 0, high = 0;
|
||||
|
||||
if (rkcif_get_efuse_value(np, "specification", &spec))
|
||||
return -EINVAL;
|
||||
if (rkcif_get_efuse_value(np, "package_low", &low))
|
||||
return -EINVAL;
|
||||
if (rkcif_get_efuse_value(np, "package_high", &high))
|
||||
return -EINVAL;
|
||||
|
||||
package = ((high & 0x1) << 3) | low;
|
||||
|
||||
/* RK3588S */
|
||||
if (spec == 0x13)
|
||||
return package;
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int rkcif_plat_hw_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct of_device_id *match;
|
||||
@@ -1265,6 +1311,7 @@ static int rkcif_plat_hw_probe(struct platform_device *pdev)
|
||||
int i, ret, irq;
|
||||
bool is_mem_reserved = false;
|
||||
struct notifier_block *notifier;
|
||||
int package = 0;
|
||||
|
||||
match = of_match_node(rkcif_plat_of_match, node);
|
||||
if (IS_ERR(match))
|
||||
@@ -1278,6 +1325,13 @@ static int rkcif_plat_hw_probe(struct platform_device *pdev)
|
||||
dev_set_drvdata(dev, cif_hw);
|
||||
cif_hw->dev = dev;
|
||||
|
||||
package = rkcif_get_speciand_package_number(node);
|
||||
if (package == 0x2) {
|
||||
cif_hw->is_rk3588s2 = true;
|
||||
dev_info(dev, "attach rk3588s2\n");
|
||||
} else {
|
||||
cif_hw->is_rk3588s2 = false;
|
||||
}
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
@@ -1506,6 +1560,7 @@ int rk_cif_plat_drv_init(void)
|
||||
ret = platform_driver_register(&rkcif_hw_plat_drv);
|
||||
if (ret)
|
||||
return ret;
|
||||
rkcif_csi2_hw_plat_drv_init();
|
||||
return rkcif_csi2_plat_drv_init();
|
||||
}
|
||||
|
||||
@@ -1513,6 +1568,7 @@ static void __exit rk_cif_plat_drv_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&rkcif_hw_plat_drv);
|
||||
rkcif_csi2_plat_drv_exit();
|
||||
rkcif_csi2_hw_plat_drv_exit();
|
||||
}
|
||||
|
||||
#if defined(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP) && !defined(CONFIG_INITCALL_ASYNC)
|
||||
|
||||
@@ -152,6 +152,7 @@ struct rkcif_hw {
|
||||
bool is_dma_contig;
|
||||
bool adapt_to_usbcamerahal;
|
||||
u64 irq_time;
|
||||
bool is_rk3588s2;
|
||||
};
|
||||
|
||||
void rkcif_hw_soft_reset(struct rkcif_hw *cif_hw, bool is_rst_iommu);
|
||||
|
||||
@@ -13,12 +13,12 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_graph.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/rk-camera-module.h>
|
||||
#include <media/v4l2-ioctl.h>
|
||||
#include "mipi-csi2.h"
|
||||
#include <linux/rkcif-config.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
static int csi2_debug;
|
||||
@@ -129,47 +129,55 @@ static void csi2_update_sensor_info(struct csi2_dev *csi2)
|
||||
|
||||
}
|
||||
|
||||
static void csi2_hw_do_reset(struct csi2_dev *csi2)
|
||||
static void csi2_hw_do_reset(struct csi2_hw *csi2_hw)
|
||||
{
|
||||
reset_control_assert(csi2->rsts_bulk);
|
||||
|
||||
if (!csi2_hw->rsts_bulk)
|
||||
return;
|
||||
|
||||
reset_control_assert(csi2_hw->rsts_bulk);
|
||||
|
||||
udelay(5);
|
||||
|
||||
reset_control_deassert(csi2->rsts_bulk);
|
||||
reset_control_deassert(csi2_hw->rsts_bulk);
|
||||
}
|
||||
|
||||
static int csi2_enable_clks(struct csi2_dev *csi2)
|
||||
static int csi2_enable_clks(struct csi2_hw *csi2_hw)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = clk_bulk_prepare_enable(csi2->clks_num, csi2->clks_bulk);
|
||||
if (!csi2_hw->clks_bulk)
|
||||
return -EINVAL;
|
||||
|
||||
ret = clk_bulk_prepare_enable(csi2_hw->clks_num, csi2_hw->clks_bulk);
|
||||
if (ret)
|
||||
dev_err(csi2->dev, "failed to enable clks\n");
|
||||
dev_err(csi2_hw->dev, "failed to enable clks\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void csi2_disable_clks(struct csi2_dev *csi2)
|
||||
static void csi2_disable_clks(struct csi2_hw *csi2_hw)
|
||||
{
|
||||
clk_bulk_disable_unprepare(csi2->clks_num, csi2->clks_bulk);
|
||||
if (!csi2_hw->clks_bulk)
|
||||
return;
|
||||
clk_bulk_disable_unprepare(csi2_hw->clks_num, csi2_hw->clks_bulk);
|
||||
}
|
||||
|
||||
static void csi2_disable(struct csi2_dev *csi2)
|
||||
static void csi2_disable(struct csi2_hw *csi2_hw)
|
||||
{
|
||||
void __iomem *base = csi2->base;
|
||||
|
||||
write_csihost_reg(base, CSIHOST_RESETN, 0);
|
||||
write_csihost_reg(base, CSIHOST_MSK1, 0xffffffff);
|
||||
write_csihost_reg(base, CSIHOST_MSK2, 0xffffffff);
|
||||
write_csihost_reg(csi2_hw->base, CSIHOST_RESETN, 0);
|
||||
write_csihost_reg(csi2_hw->base, CSIHOST_MSK1, 0xffffffff);
|
||||
write_csihost_reg(csi2_hw->base, CSIHOST_MSK2, 0xffffffff);
|
||||
}
|
||||
|
||||
static int csi2_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
|
||||
struct v4l2_mbus_config *mbus);
|
||||
|
||||
static void csi2_enable(struct csi2_dev *csi2,
|
||||
static void csi2_enable(struct csi2_hw *csi2_hw,
|
||||
enum host_type_t host_type)
|
||||
{
|
||||
void __iomem *base = csi2->base;
|
||||
void __iomem *base = csi2_hw->base;
|
||||
struct csi2_dev *csi2 = csi2_hw->csi2;
|
||||
int lanes = csi2->bus.num_data_lanes;
|
||||
struct v4l2_mbus_config mbus;
|
||||
u32 val = 0;
|
||||
@@ -207,16 +215,10 @@ static int csi2_start(struct csi2_dev *csi2)
|
||||
{
|
||||
enum host_type_t host_type;
|
||||
int ret, i;
|
||||
int csi_idx = 0;
|
||||
|
||||
atomic_set(&csi2->frm_sync_seq, 0);
|
||||
|
||||
csi2_hw_do_reset(csi2);
|
||||
ret = csi2_enable_clks(csi2);
|
||||
if (ret) {
|
||||
v4l2_err(&csi2->sd, "%s: enable clks failed\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
csi2_update_sensor_info(csi2);
|
||||
|
||||
if (csi2->dsi_input_en == RKMODULE_DSI_INPUT)
|
||||
@@ -224,7 +226,16 @@ static int csi2_start(struct csi2_dev *csi2)
|
||||
else
|
||||
host_type = RK_CSI_RXHOST;
|
||||
|
||||
csi2_enable(csi2, host_type);
|
||||
for (i = 0; i < csi2->csi_info.csi_num; i++) {
|
||||
csi_idx = csi2->csi_info.csi_idx[i];
|
||||
csi2_hw_do_reset(csi2->csi2_hw[csi_idx]);
|
||||
ret = csi2_enable_clks(csi2->csi2_hw[csi_idx]);
|
||||
if (ret) {
|
||||
v4l2_err(&csi2->sd, "%s: enable clks failed\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
csi2_enable(csi2->csi2_hw[csi_idx], host_type);
|
||||
}
|
||||
|
||||
pr_debug("stream sd: %s\n", csi2->src_sd->name);
|
||||
ret = v4l2_subdev_call(csi2->src_sd, video, s_stream, 1);
|
||||
@@ -238,20 +249,29 @@ static int csi2_start(struct csi2_dev *csi2)
|
||||
return 0;
|
||||
|
||||
err_assert_reset:
|
||||
csi2_disable(csi2);
|
||||
csi2_disable_clks(csi2);
|
||||
for (i = 0; i < csi2->csi_info.csi_num; i++) {
|
||||
csi_idx = csi2->csi_info.csi_idx[i];
|
||||
csi2_disable(csi2->csi2_hw[csi_idx]);
|
||||
csi2_disable_clks(csi2->csi2_hw[csi_idx]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void csi2_stop(struct csi2_dev *csi2)
|
||||
{
|
||||
int i = 0;
|
||||
int csi_idx = 0;
|
||||
|
||||
/* stop upstream */
|
||||
v4l2_subdev_call(csi2->src_sd, video, s_stream, 0);
|
||||
|
||||
csi2_disable(csi2);
|
||||
csi2_hw_do_reset(csi2);
|
||||
csi2_disable_clks(csi2);
|
||||
for (i = 0; i < csi2->csi_info.csi_num; i++) {
|
||||
csi_idx = csi2->csi_info.csi_idx[i];
|
||||
csi2_disable(csi2->csi2_hw[csi_idx]);
|
||||
csi2_hw_do_reset(csi2->csi2_hw[csi_idx]);
|
||||
csi2_disable_clks(csi2->csi2_hw[csi_idx]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -361,7 +381,6 @@ static int csi2_media_init(struct v4l2_subdev *sd)
|
||||
csi2->crop.left = 0;
|
||||
csi2->crop.width = RKCIF_DEFAULT_WIDTH;
|
||||
csi2->crop.height = RKCIF_DEFAULT_HEIGHT;
|
||||
csi2->csi_idx = 0;
|
||||
|
||||
return media_entity_pads_init(&sd->entity, num_pads, csi2->pad);
|
||||
}
|
||||
@@ -549,11 +568,19 @@ static int rkcif_csi2_s_power(struct v4l2_subdev *sd, int on)
|
||||
static long rkcif_csi2_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
||||
{
|
||||
struct csi2_dev *csi2 = sd_to_dev(sd);
|
||||
struct v4l2_subdev *sensor = get_remote_sensor(sd);
|
||||
long ret = 0;
|
||||
int i = 0;
|
||||
|
||||
switch (cmd) {
|
||||
case RKCIF_CMD_SET_CSI_IDX:
|
||||
csi2->csi_idx = *((u32 *)arg);
|
||||
csi2->csi_info = *((struct rkcif_csi_info *)arg);
|
||||
for (i = 0; i < csi2->csi_info.csi_num; i++)
|
||||
csi2->csi2_hw[csi2->csi_info.csi_idx[i]]->csi2 = csi2;
|
||||
if (csi2->match_data->chip_id > CHIP_RV1126_CSI2)
|
||||
ret = v4l2_subdev_call(sensor, core, ioctl,
|
||||
RKCIF_CMD_SET_CSI_IDX,
|
||||
arg);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOIOCTLCMD;
|
||||
@@ -568,15 +595,15 @@ static long rkcif_csi2_compat_ioctl32(struct v4l2_subdev *sd,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
void __user *up = compat_ptr(arg);
|
||||
u32 csi_idx = 0;
|
||||
struct rkcif_csi_info csi_info;
|
||||
long ret;
|
||||
|
||||
switch (cmd) {
|
||||
case RKCIF_CMD_SET_CSI_IDX:
|
||||
if (copy_from_user(&csi_idx, up, sizeof(u32)))
|
||||
if (copy_from_user(&csi_info, up, sizeof(struct rkcif_csi_info)))
|
||||
return -EFAULT;
|
||||
|
||||
ret = rkcif_csi2_ioctl(sd, cmd, &csi_idx);
|
||||
ret = rkcif_csi2_ioctl(sd, cmd, &csi_info);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOIOCTLCMD;
|
||||
@@ -721,7 +748,8 @@ static void csi2_find_err_vc(int val, char *vc_info)
|
||||
static irqreturn_t rk_csirx_irq1_handler(int irq, void *ctx)
|
||||
{
|
||||
struct device *dev = ctx;
|
||||
struct csi2_dev *csi2 = sd_to_dev(dev_get_drvdata(dev));
|
||||
struct csi2_hw *csi2_hw = dev_get_drvdata(dev);
|
||||
struct csi2_dev *csi2 = csi2_hw->csi2;
|
||||
struct csi2_err_stats *err_list = NULL;
|
||||
unsigned long err_stat = 0;
|
||||
u32 val;
|
||||
@@ -730,7 +758,7 @@ static irqreturn_t rk_csirx_irq1_handler(int irq, void *ctx)
|
||||
char vc_info[CSI_VCINFO_LEN] = {0};
|
||||
bool is_add_cnt = false;
|
||||
|
||||
val = read_csihost_reg(csi2->base, CSIHOST_ERR1);
|
||||
val = read_csihost_reg(csi2_hw->base, CSIHOST_ERR1);
|
||||
if (val) {
|
||||
if (val & CSIHOST_ERR1_PHYERR_SPTSYNCHS) {
|
||||
err_list = &csi2->err_list[RK_CSI2_ERR_SOTSYN];
|
||||
@@ -739,7 +767,7 @@ static irqreturn_t rk_csirx_irq1_handler(int irq, void *ctx)
|
||||
if (err_list->cnt > 3 &&
|
||||
csi2->err_list[RK_CSI2_ERR_ALL].cnt <= err_list->cnt) {
|
||||
csi2->is_check_sot_sync = false;
|
||||
write_csihost_reg(csi2->base, CSIHOST_MSK1, 0xf);
|
||||
write_csihost_reg(csi2_hw->base, CSIHOST_MSK1, 0xf);
|
||||
}
|
||||
if (csi2->is_check_sot_sync) {
|
||||
csi2_find_err_vc(val & 0xf, vc_info);
|
||||
@@ -804,7 +832,7 @@ static irqreturn_t rk_csirx_irq1_handler(int irq, void *ctx)
|
||||
csi2_err_strncat(err_str, cur_str);
|
||||
}
|
||||
|
||||
pr_err("%s ERR1:0x%x %s\n", csi2->dev_name, val, err_str);
|
||||
pr_err("%s ERR1:0x%x %s\n", csi2_hw->dev_name, val, err_str);
|
||||
|
||||
if (is_add_cnt) {
|
||||
csi2->err_list[RK_CSI2_ERR_ALL].cnt++;
|
||||
@@ -813,7 +841,7 @@ static irqreturn_t rk_csirx_irq1_handler(int irq, void *ctx)
|
||||
|
||||
atomic_notifier_call_chain(&g_csi_host_chain,
|
||||
err_stat,
|
||||
&csi2->csi_idx);
|
||||
&csi2->csi_info.csi_idx[csi2->csi_info.csi_num - 1]);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -824,13 +852,13 @@ static irqreturn_t rk_csirx_irq1_handler(int irq, void *ctx)
|
||||
static irqreturn_t rk_csirx_irq2_handler(int irq, void *ctx)
|
||||
{
|
||||
struct device *dev = ctx;
|
||||
struct csi2_dev *csi2 = sd_to_dev(dev_get_drvdata(dev));
|
||||
struct csi2_hw *csi2_hw = dev_get_drvdata(dev);
|
||||
u32 val;
|
||||
char cur_str[CSI_ERRSTR_LEN] = {0};
|
||||
char err_str[CSI_ERRSTR_LEN] = {0};
|
||||
char vc_info[CSI_VCINFO_LEN] = {0};
|
||||
|
||||
val = read_csihost_reg(csi2->base, CSIHOST_ERR2);
|
||||
val = read_csihost_reg(csi2_hw->base, CSIHOST_ERR2);
|
||||
if (val) {
|
||||
if (val & CSIHOST_ERR2_PHYERR_ESC) {
|
||||
csi2_find_err_vc(val & 0xf, vc_info);
|
||||
@@ -857,7 +885,7 @@ static irqreturn_t rk_csirx_irq2_handler(int irq, void *ctx)
|
||||
csi2_err_strncat(err_str, cur_str);
|
||||
}
|
||||
|
||||
pr_err("%s ERR2:0x%x %s\n", csi2->dev_name, val, err_str);
|
||||
pr_err("%s ERR2:0x%x %s\n", csi2_hw->dev_name, val, err_str);
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
@@ -896,31 +924,43 @@ static int csi2_notifier(struct csi2_dev *csi2)
|
||||
static const struct csi2_match_data rk1808_csi2_match_data = {
|
||||
.chip_id = CHIP_RK1808_CSI2,
|
||||
.num_pads = CSI2_NUM_PADS,
|
||||
.num_hw = 1,
|
||||
};
|
||||
|
||||
static const struct csi2_match_data rk3288_csi2_match_data = {
|
||||
.chip_id = CHIP_RK3288_CSI2,
|
||||
.num_pads = CSI2_NUM_PADS_SINGLE_LINK,
|
||||
.num_hw = 1,
|
||||
};
|
||||
|
||||
static const struct csi2_match_data rv1126_csi2_match_data = {
|
||||
.chip_id = CHIP_RV1126_CSI2,
|
||||
.num_pads = CSI2_NUM_PADS,
|
||||
.num_hw = 1,
|
||||
};
|
||||
|
||||
static const struct csi2_match_data rk3568_csi2_match_data = {
|
||||
.chip_id = CHIP_RK3568_CSI2,
|
||||
.num_pads = CSI2_NUM_PADS,
|
||||
.num_hw = 1,
|
||||
};
|
||||
|
||||
static const struct csi2_match_data rk3588_csi2_match_data = {
|
||||
.chip_id = CHIP_RK3588_CSI2,
|
||||
.num_pads = CSI2_NUM_PADS_MAX,
|
||||
.num_hw = 6,
|
||||
};
|
||||
|
||||
static const struct csi2_match_data rv1106_csi2_match_data = {
|
||||
.chip_id = CHIP_RV1106_CSI2,
|
||||
.num_pads = CSI2_NUM_PADS_MAX,
|
||||
.num_hw = 2,
|
||||
};
|
||||
|
||||
static const struct csi2_match_data rk3562_csi2_match_data = {
|
||||
.chip_id = CHIP_RK3562_CSI2,
|
||||
.num_pads = CSI2_NUM_PADS_MAX,
|
||||
.num_hw = 4,
|
||||
};
|
||||
|
||||
static const struct of_device_id csi2_dt_ids[] = {
|
||||
@@ -944,6 +984,10 @@ static const struct of_device_id csi2_dt_ids[] = {
|
||||
.compatible = "rockchip,rk3588-mipi-csi2",
|
||||
.data = &rk3588_csi2_match_data,
|
||||
},
|
||||
{
|
||||
.compatible = "rockchip,rv1106-mipi-csi2",
|
||||
.data = &rv1106_csi2_match_data,
|
||||
},
|
||||
{
|
||||
.compatible = "rockchip,rk3562-mipi-csi2",
|
||||
.data = &rk3562_csi2_match_data,
|
||||
@@ -952,15 +996,48 @@ static const struct of_device_id csi2_dt_ids[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, csi2_dt_ids);
|
||||
|
||||
static int csi2_attach_hw(struct csi2_dev *csi2)
|
||||
{
|
||||
struct device_node *np;
|
||||
struct platform_device *pdev;
|
||||
struct csi2_hw *hw;
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < csi2->match_data->num_hw; i++) {
|
||||
np = of_parse_phandle(csi2->dev->of_node, "rockchip,hw", i);
|
||||
if (!np || !of_device_is_available(np)) {
|
||||
dev_err(csi2->dev, "failed to get csi2 hw node\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
pdev = of_find_device_by_node(np);
|
||||
of_node_put(np);
|
||||
if (!pdev) {
|
||||
dev_err(csi2->dev, "failed to get csi2 hw from node\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
hw = platform_get_drvdata(pdev);
|
||||
if (!hw) {
|
||||
dev_err(csi2->dev, "failed attach csi2 hw\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hw->csi2 = csi2;
|
||||
csi2->csi2_hw[i] = hw;
|
||||
}
|
||||
dev_info(csi2->dev, "attach to csi2 hw node\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int csi2_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct of_device_id *match;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
struct csi2_dev *csi2 = NULL;
|
||||
struct resource *res;
|
||||
const struct csi2_match_data *data;
|
||||
int ret, irq;
|
||||
int ret;
|
||||
|
||||
match = of_match_node(csi2_dt_ids, node);
|
||||
if (IS_ERR(match))
|
||||
@@ -986,63 +1063,11 @@ static int csi2_probe(struct platform_device *pdev)
|
||||
v4l2_err(&csi2->sd, "failed to copy name\n");
|
||||
platform_set_drvdata(pdev, &csi2->sd);
|
||||
|
||||
csi2->clks_num = devm_clk_bulk_get_all(dev, &csi2->clks_bulk);
|
||||
if (csi2->clks_num < 0) {
|
||||
csi2->clks_num = 0;
|
||||
dev_err(dev, "failed to get csi2 clks\n");
|
||||
ret = csi2_attach_hw(csi2);
|
||||
if (ret) {
|
||||
v4l2_err(&csi2->sd, "must enable all mipi csi2 hw node\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
csi2->rsts_bulk = devm_reset_control_array_get_optional_exclusive(dev);
|
||||
if (IS_ERR(csi2->rsts_bulk)) {
|
||||
if (PTR_ERR(csi2->rsts_bulk) != -EPROBE_DEFER)
|
||||
dev_err(dev, "failed to get csi2 reset\n");
|
||||
csi2->rsts_bulk = NULL;
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
csi2->base = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(csi2->base)) {
|
||||
resource_size_t offset = res->start;
|
||||
resource_size_t size = resource_size(res);
|
||||
|
||||
dev_warn(&pdev->dev, "avoid secondary mipi resource check!\n");
|
||||
|
||||
csi2->base = devm_ioremap(&pdev->dev, offset, size);
|
||||
if (IS_ERR(csi2->base)) {
|
||||
dev_err(&pdev->dev, "Failed to ioremap resource\n");
|
||||
|
||||
return PTR_ERR(csi2->base);
|
||||
}
|
||||
}
|
||||
|
||||
irq = platform_get_irq_byname(pdev, "csi-intr1");
|
||||
if (irq > 0) {
|
||||
ret = devm_request_irq(&pdev->dev, irq,
|
||||
rk_csirx_irq1_handler, 0,
|
||||
dev_driver_string(&pdev->dev),
|
||||
&pdev->dev);
|
||||
if (ret < 0)
|
||||
v4l2_err(&csi2->sd, "request csi-intr1 irq failed: %d\n",
|
||||
ret);
|
||||
csi2->irq1 = irq;
|
||||
} else {
|
||||
v4l2_err(&csi2->sd, "No found irq csi-intr1\n");
|
||||
}
|
||||
|
||||
irq = platform_get_irq_byname(pdev, "csi-intr2");
|
||||
if (irq > 0) {
|
||||
ret = devm_request_irq(&pdev->dev, irq,
|
||||
rk_csirx_irq2_handler, 0,
|
||||
dev_driver_string(&pdev->dev),
|
||||
&pdev->dev);
|
||||
if (ret < 0)
|
||||
v4l2_err(&csi2->sd, "request csi-intr2 failed: %d\n",
|
||||
ret);
|
||||
csi2->irq2 = irq;
|
||||
} else {
|
||||
v4l2_err(&csi2->sd, "No found irq csi-intr2\n");
|
||||
}
|
||||
|
||||
mutex_init(&csi2->lock);
|
||||
|
||||
ret = csi2_media_init(&csi2->sd);
|
||||
@@ -1087,11 +1112,183 @@ int rkcif_csi2_plat_drv_init(void)
|
||||
return platform_driver_register(&csi2_driver);
|
||||
}
|
||||
|
||||
void __exit rkcif_csi2_plat_drv_exit(void)
|
||||
void rkcif_csi2_plat_drv_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&csi2_driver);
|
||||
}
|
||||
|
||||
static const struct csi2_hw_match_data rk1808_csi2_hw_match_data = {
|
||||
.chip_id = CHIP_RK1808_CSI2,
|
||||
};
|
||||
|
||||
static const struct csi2_hw_match_data rk3288_csi2_hw_match_data = {
|
||||
.chip_id = CHIP_RK3288_CSI2,
|
||||
};
|
||||
|
||||
static const struct csi2_hw_match_data rv1126_csi2_hw_match_data = {
|
||||
.chip_id = CHIP_RV1126_CSI2,
|
||||
};
|
||||
|
||||
static const struct csi2_hw_match_data rk3568_csi2_hw_match_data = {
|
||||
.chip_id = CHIP_RK3568_CSI2,
|
||||
};
|
||||
|
||||
static const struct csi2_hw_match_data rk3588_csi2_hw_match_data = {
|
||||
.chip_id = CHIP_RK3588_CSI2,
|
||||
};
|
||||
|
||||
static const struct csi2_hw_match_data rv1106_csi2_hw_match_data = {
|
||||
.chip_id = CHIP_RV1106_CSI2,
|
||||
};
|
||||
|
||||
static const struct csi2_hw_match_data rk3562_csi2_hw_match_data = {
|
||||
.chip_id = CHIP_RK3562_CSI2,
|
||||
};
|
||||
|
||||
static const struct of_device_id csi2_hw_ids[] = {
|
||||
{
|
||||
.compatible = "rockchip,rk1808-mipi-csi2-hw",
|
||||
.data = &rk1808_csi2_hw_match_data,
|
||||
},
|
||||
{
|
||||
.compatible = "rockchip,rk3288-mipi-csi2-hw",
|
||||
.data = &rk3288_csi2_hw_match_data,
|
||||
},
|
||||
{
|
||||
.compatible = "rockchip,rk3568-mipi-csi2-hw",
|
||||
.data = &rk3568_csi2_hw_match_data,
|
||||
},
|
||||
{
|
||||
.compatible = "rockchip,rv1126-mipi-csi2-hw",
|
||||
.data = &rv1126_csi2_hw_match_data,
|
||||
},
|
||||
{
|
||||
.compatible = "rockchip,rk3588-mipi-csi2-hw",
|
||||
.data = &rk3588_csi2_hw_match_data,
|
||||
},
|
||||
{
|
||||
.compatible = "rockchip,rv1106-mipi-csi2-hw",
|
||||
.data = &rv1106_csi2_hw_match_data,
|
||||
},
|
||||
{
|
||||
.compatible = "rockchip,rk3562-mipi-csi2-hw",
|
||||
.data = &rk3588_csi2_hw_match_data,
|
||||
},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, csi2_hw_ids);
|
||||
|
||||
static int csi2_hw_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct of_device_id *match;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
struct csi2_hw *csi2_hw = NULL;
|
||||
struct resource *res;
|
||||
const struct csi2_hw_match_data *data;
|
||||
int ret, irq;
|
||||
|
||||
dev_info(&pdev->dev, "enter mipi csi2 hw probe!\n");
|
||||
match = of_match_node(csi2_hw_ids, node);
|
||||
if (IS_ERR(match))
|
||||
return PTR_ERR(match);
|
||||
data = match->data;
|
||||
|
||||
csi2_hw = devm_kzalloc(&pdev->dev, sizeof(*csi2_hw), GFP_KERNEL);
|
||||
if (!csi2_hw)
|
||||
return -ENOMEM;
|
||||
|
||||
csi2_hw->dev = &pdev->dev;
|
||||
csi2_hw->match_data = data;
|
||||
|
||||
csi2_hw->dev_name = node->name;
|
||||
|
||||
csi2_hw->clks_num = devm_clk_bulk_get_all(dev, &csi2_hw->clks_bulk);
|
||||
if (csi2_hw->clks_num < 0) {
|
||||
csi2_hw->clks_num = 0;
|
||||
dev_err(dev, "failed to get csi2 clks\n");
|
||||
}
|
||||
|
||||
csi2_hw->rsts_bulk = devm_reset_control_array_get_optional_exclusive(dev);
|
||||
if (IS_ERR(csi2_hw->rsts_bulk)) {
|
||||
if (PTR_ERR(csi2_hw->rsts_bulk) != -EPROBE_DEFER)
|
||||
dev_err(dev, "failed to get csi2 reset\n");
|
||||
csi2_hw->rsts_bulk = NULL;
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
csi2_hw->base = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(csi2_hw->base)) {
|
||||
resource_size_t offset = res->start;
|
||||
resource_size_t size = resource_size(res);
|
||||
|
||||
dev_warn(&pdev->dev, "avoid secondary mipi resource check!\n");
|
||||
|
||||
csi2_hw->base = devm_ioremap(&pdev->dev, offset, size);
|
||||
if (IS_ERR(csi2_hw->base)) {
|
||||
dev_err(&pdev->dev, "Failed to ioremap resource\n");
|
||||
|
||||
return PTR_ERR(csi2_hw->base);
|
||||
}
|
||||
}
|
||||
|
||||
irq = platform_get_irq_byname(pdev, "csi-intr1");
|
||||
if (irq > 0) {
|
||||
ret = devm_request_irq(&pdev->dev, irq,
|
||||
rk_csirx_irq1_handler, 0,
|
||||
dev_driver_string(&pdev->dev),
|
||||
&pdev->dev);
|
||||
if (ret < 0)
|
||||
dev_err(&pdev->dev, "request csi-intr1 irq failed: %d\n",
|
||||
ret);
|
||||
csi2_hw->irq1 = irq;
|
||||
} else {
|
||||
dev_err(&pdev->dev, "No found irq csi-intr1\n");
|
||||
}
|
||||
|
||||
irq = platform_get_irq_byname(pdev, "csi-intr2");
|
||||
if (irq > 0) {
|
||||
ret = devm_request_irq(&pdev->dev, irq,
|
||||
rk_csirx_irq2_handler, 0,
|
||||
dev_driver_string(&pdev->dev),
|
||||
&pdev->dev);
|
||||
if (ret < 0)
|
||||
dev_err(&pdev->dev, "request csi-intr2 failed: %d\n",
|
||||
ret);
|
||||
csi2_hw->irq2 = irq;
|
||||
} else {
|
||||
dev_err(&pdev->dev, "No found irq csi-intr2\n");
|
||||
}
|
||||
platform_set_drvdata(pdev, csi2_hw);
|
||||
dev_info(&pdev->dev, "probe success, v4l2_dev:%s!\n", csi2_hw->dev_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int csi2_hw_remove(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver csi2_hw_driver = {
|
||||
.driver = {
|
||||
.name = DEVICE_NAME_HW,
|
||||
.of_match_table = csi2_hw_ids,
|
||||
},
|
||||
.probe = csi2_hw_probe,
|
||||
.remove = csi2_hw_remove,
|
||||
};
|
||||
|
||||
int rkcif_csi2_hw_plat_drv_init(void)
|
||||
{
|
||||
return platform_driver_register(&csi2_hw_driver);
|
||||
}
|
||||
|
||||
void rkcif_csi2_hw_plat_drv_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&csi2_hw_driver);
|
||||
}
|
||||
|
||||
MODULE_DESCRIPTION("Rockchip MIPI CSI2 driver");
|
||||
MODULE_AUTHOR("Macrofly.xu <xuhf@rock-chips.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <media/v4l2-fwnode.h>
|
||||
#include <media/v4l2-subdev.h>
|
||||
#include <media/v4l2-event.h>
|
||||
#include <linux/rkcif-config.h>
|
||||
|
||||
#define CSI2_ERR_FSFE_MASK (0xff << 8)
|
||||
#define CSI2_ERR_COUNT_ALL_MASK (0xff)
|
||||
@@ -42,6 +43,7 @@
|
||||
#define CSIHOST_MAX_ERRINT_COUNT 10
|
||||
|
||||
#define DEVICE_NAME "rockchip-mipi-csi2"
|
||||
#define DEVICE_NAME_HW "rockchip-mipi-csi2-hw"
|
||||
|
||||
/* CSI Host Registers Define */
|
||||
#define CSIHOST_N_LANES 0x04
|
||||
@@ -76,6 +78,8 @@
|
||||
#define SW_DATATYPE_LS(x) ((x) << 20)
|
||||
#define SW_DATATYPE_LE(x) ((x) << 26)
|
||||
|
||||
#define RK_MAX_CSI_HW (6)
|
||||
|
||||
/*
|
||||
* add new chip id in tail in time order
|
||||
* by increasing to distinguish csi2 host version
|
||||
@@ -88,6 +92,7 @@ enum rkcsi2_chip_id {
|
||||
CHIP_RV1126_CSI2,
|
||||
CHIP_RK3568_CSI2,
|
||||
CHIP_RK3588_CSI2,
|
||||
CHIP_RV1106_CSI2,
|
||||
CHIP_RK3562_CSI2,
|
||||
};
|
||||
|
||||
@@ -117,6 +122,11 @@ enum host_type_t {
|
||||
struct csi2_match_data {
|
||||
int chip_id;
|
||||
int num_pads;
|
||||
int num_hw;
|
||||
};
|
||||
|
||||
struct csi2_hw_match_data {
|
||||
int chip_id;
|
||||
};
|
||||
|
||||
struct csi2_sensor_info {
|
||||
@@ -155,10 +165,29 @@ struct csi2_dev {
|
||||
int num_sensors;
|
||||
atomic_t frm_sync_seq;
|
||||
struct csi2_err_stats err_list[RK_CSI2_ERR_MAX];
|
||||
struct csi2_hw *csi2_hw[RK_MAX_CSI_HW];
|
||||
int irq1;
|
||||
int irq2;
|
||||
int dsi_input_en;
|
||||
u32 csi_idx;
|
||||
struct rkcif_csi_info csi_info;
|
||||
const char *dev_name;
|
||||
};
|
||||
|
||||
struct csi2_hw {
|
||||
struct device *dev;
|
||||
struct clk_bulk_data *clks_bulk;
|
||||
int clks_num;
|
||||
struct reset_control *rsts_bulk;
|
||||
struct csi2_dev *csi2;
|
||||
const struct csi2_hw_match_data *match_data;
|
||||
|
||||
void __iomem *base;
|
||||
|
||||
/* lock to protect all members below */
|
||||
struct mutex lock;
|
||||
|
||||
int irq1;
|
||||
int irq2;
|
||||
const char *dev_name;
|
||||
};
|
||||
|
||||
@@ -166,7 +195,9 @@ 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 rkcif_csi2_plat_drv_init(void);
|
||||
void __exit rkcif_csi2_plat_drv_exit(void);
|
||||
void rkcif_csi2_plat_drv_exit(void);
|
||||
int rkcif_csi2_hw_plat_drv_init(void);
|
||||
void rkcif_csi2_hw_plat_drv_exit(void);
|
||||
int rkcif_csi2_register_notifier(struct notifier_block *nb);
|
||||
int rkcif_csi2_unregister_notifier(struct notifier_block *nb);
|
||||
void rkcif_csi2_event_reset_pipe(struct csi2_dev *csi2_dev, int reset_src);
|
||||
|
||||
@@ -337,7 +337,10 @@ static long sditf_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
||||
mode = (struct rkisp_vicap_mode *)arg;
|
||||
memcpy(&priv->mode, mode, sizeof(*mode));
|
||||
sditf_reinit_mode(priv, &priv->mode);
|
||||
mode->input.merge_num = cif_dev->sditf_cnt;
|
||||
if (priv->is_combine_mode)
|
||||
mode->input.merge_num = cif_dev->sditf_cnt;
|
||||
else
|
||||
mode->input.merge_num = 1;
|
||||
mode->input.index = priv->combine_index;
|
||||
return 0;
|
||||
case RKISP_VICAP_CMD_INIT_BUF:
|
||||
@@ -425,6 +428,7 @@ static long sditf_compat_ioctl32(struct v4l2_subdev *sd,
|
||||
static int sditf_channel_enable(struct sditf_priv *priv, int user)
|
||||
{
|
||||
struct rkcif_device *cif_dev = priv->cif_dev;
|
||||
struct rkmodule_capture_info *capture_info = &cif_dev->channels[0].capture_info;
|
||||
unsigned int ch0 = 0, ch1 = 0, ch2 = 0;
|
||||
unsigned int ctrl_val = 0;
|
||||
unsigned int int_en = 0;
|
||||
@@ -432,11 +436,25 @@ static int sditf_channel_enable(struct sditf_priv *priv, int user)
|
||||
unsigned int offset_y = 0;
|
||||
unsigned int width = priv->cap_info.width;
|
||||
unsigned int height = priv->cap_info.height;
|
||||
int csi_idx = cif_dev->csi_host_idx;
|
||||
|
||||
if (capture_info->mode == RKMODULE_MULTI_DEV_COMBINE_ONE &&
|
||||
priv->toisp_inf.link_mode == TOISP_UNITE) {
|
||||
if (capture_info->multi_dev.dev_num != 2 ||
|
||||
capture_info->multi_dev.pixel_offset != RKMOUDLE_UNITE_EXTEND_PIXEL) {
|
||||
v4l2_err(&cif_dev->v4l2_dev,
|
||||
"param error of online mode, combine dev num %d, offset %d\n",
|
||||
capture_info->multi_dev.dev_num,
|
||||
capture_info->multi_dev.pixel_offset);
|
||||
return -EINVAL;
|
||||
}
|
||||
csi_idx = capture_info->multi_dev.dev_idx[user];
|
||||
}
|
||||
|
||||
if (priv->hdr_cfg.hdr_mode == NO_HDR ||
|
||||
priv->hdr_cfg.hdr_mode == HDR_COMPR) {
|
||||
if (cif_dev->inf_id == RKCIF_MIPI_LVDS)
|
||||
ch0 = cif_dev->csi_host_idx * 4;
|
||||
ch0 = csi_idx * 4;
|
||||
else
|
||||
ch0 = 24;//dvp
|
||||
ctrl_val = (ch0 << 3) | 0x1;
|
||||
@@ -491,7 +509,10 @@ static int sditf_channel_enable(struct sditf_priv *priv, int user)
|
||||
}
|
||||
} else {
|
||||
if (priv->toisp_inf.link_mode == TOISP_UNITE) {
|
||||
offset_x = priv->cap_info.width / 2 - RKMOUDLE_UNITE_EXTEND_PIXEL;
|
||||
if (capture_info->mode == RKMODULE_MULTI_DEV_COMBINE_ONE)
|
||||
offset_x = 0;
|
||||
else
|
||||
offset_x = priv->cap_info.width / 2 - RKMOUDLE_UNITE_EXTEND_PIXEL;
|
||||
width = priv->cap_info.width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL;
|
||||
}
|
||||
rkcif_write_register(cif_dev, CIF_REG_TOISP1_CTRL, ctrl_val);
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
*7. add keepint time to csi2 err for resetting
|
||||
*8. mipi supports pdaf/embedded data
|
||||
*9. mipi supports interlaced capture
|
||||
*v0.2.0
|
||||
*1. vicap support combine multi mipi dev to one dev, this function is mainly used for rk3588
|
||||
*/
|
||||
|
||||
#define RKCIF_DRIVER_VERSION RKCIF_API_VERSION
|
||||
|
||||
Reference in New Issue
Block a user