media: spi: rk1608: update driver for 5.10 kernel.

Signed-off-by: Sach Lin <sach.lin@rock-chips.com>
Change-Id: Ia8c4a1d068089534a5e2757fc7d601665d7fdd96
This commit is contained in:
Sach Lin
2022-02-24 15:04:37 +08:00
committed by Tao Huang
parent f83021dfe1
commit 6dda2467a8
5 changed files with 86 additions and 28 deletions
+9
View File
@@ -15,6 +15,15 @@ config VIDEO_GS1662
help
Enable the GS1662 driver which serializes video streams.
config VIDEO_ROCKCHIP_PREISP
tristate "Rockchip Image Signal Pre-processing driver"
depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && SPI_MASTER
depends on ARCH_ROCKCHIP || COMPILE_TEST
select V4L2_FWNODE
default n
help
Support for Pre-isp on the rockchip SoC.
endmenu
endif
+2
View File
@@ -1,5 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_VIDEO_GS1662) += gs1662.o
obj-$(CONFIG_CXD2880_SPI_DRV) += cxd2880-spi.o
obj-$(CONFIG_VIDEO_ROCKCHIP_PREISP) += rk1608.o rk1608_dphy.o
rk1608-objs += rk1608_dev.o rk1608_core.o
ccflags-y += -I $(srctree)/drivers/media/dvb-frontends/cxd2880
+20 -22
View File
@@ -580,16 +580,19 @@ static int rk1608_msg_init_sensor(struct rk1608_state *pdata,
static int rk1608_msg_init_dsp_time(struct rk1608_state *pdata,
struct msg_init_dsp_time *msg, int id)
{
struct timeval tv;
u64 usecs64;
u32 mod;
msg->msg_head.size = sizeof(struct msg_init_dsp_time);
msg->msg_head.type = id_msg_sys_time_set_t;
msg->msg_head.id.camera_id = id;
msg->msg_head.mux.sync = 0;
do_gettimeofday(&tv);
msg->tv_sec = tv.tv_sec;
msg->tv_usec = tv.tv_usec;
usecs64 = ktime_to_us(ktime_get());
mod = do_div(usecs64, USEC_PER_MSEC);
msg->tv_usec = mod;
msg->tv_sec = usecs64;
return rk1608_send_msg_to_dsp(pdata, &msg->msg_head);
}
@@ -1030,6 +1033,9 @@ static int rk1608_power_on(struct rk1608_state *pdata)
struct spi_device *spi = pdata->spi;
int ret = 0;
if (pdata->pwren_gpio)
gpiod_direction_output(pdata->pwren_gpio, 1);
if (!IS_ERR(pdata->mclk)) {
ret = clk_set_rate(pdata->mclk, RK1608_MCLK_RATE);
if (ret < 0)
@@ -1094,6 +1100,9 @@ static int rk1608_power_off(struct rk1608_state *pdata)
gpiod_direction_output(pdata->reset_gpio, 0);
rk1608_cs_set_value(pdata, 0);
if (pdata->pwren_gpio)
gpiod_direction_output(pdata->pwren_gpio, 0);
if (!IS_ERR(pdata->mclk))
clk_disable_unprepare(pdata->mclk);
@@ -1880,7 +1889,6 @@ static int preisp_file_import_data(struct rk1608_state *pdata, struct msg *msg)
unsigned int file_size = 0;
unsigned int write_size = 0;
char *file_data = NULL;
struct kstat *stat;
struct msg_xfile *xfile;
char *ref_data_path = REF_DATA_PATH;
@@ -1899,30 +1907,21 @@ static int preisp_file_import_data(struct rk1608_state *pdata, struct msg *msg)
return -EFAULT;
}
stat = kmalloc(sizeof(*stat), GFP_KERNEL);
if (!stat) {
ret = -ENOMEM;
goto err;
}
vfs_stat(file_path, stat);
file_size = stat->size;
file_size = (file_size+0x3)&(~0x3);
dev_info(pdata->dev, "start import %s to addr:0x%x size:%d\n",
file_path, xfile->addr, file_size);
file_path, xfile->addr, xfile->data_size);
file_data = vmalloc(file_size);
file_data = vmalloc(xfile->data_size);
if (!file_data) {
ret = -ENOMEM;
goto err;
}
ret = kernel_read(fp, file_data, file_size, &pos);
if (ret <= 0)
file_size = kernel_read(fp, file_data, xfile->data_size, &pos);
if (file_size <= 0) {
dev_err(pdata->dev, "%s: read error: ret=%d\n",
__func__, ret);
goto err;
}
write_size = (file_size <= xfile->data_size)?file_size:xfile->data_size;
if (file_size != xfile->data_size)
@@ -1946,7 +1945,6 @@ static int preisp_file_import_data(struct rk1608_state *pdata, struct msg *msg)
xfile->path, xfile->addr, file_size);
err:
kfree(stat);
if (file_data)
vfree(file_data);
if (fp)
@@ -2299,7 +2297,7 @@ static void rk1608_dispatch_received_msg(struct rk1608_state *pdata,
#define PREISP_DCROP_CALIB_RATIO 192
#define PREISP_DCROP_CALIB_XOFFSET 196
#define PREISP_DCROP_CALIB_YOFFSET 198
static int rk1608_get_dcrop_cfg(struct v4l2_rect *crop_in,
int rk1608_get_dcrop_cfg(struct v4l2_rect *crop_in,
struct v4l2_rect *crop_out)
{
struct file *fp;
+2
View File
@@ -635,4 +635,6 @@ void rk1608_set_spi_speed(struct rk1608_state *pdata, u32 hz);
int rk1608_set_log_level(struct rk1608_state *pdata, int level);
int rk1608_get_dcrop_cfg(struct v4l2_rect *crop_in,
struct v4l2_rect *crop_out);
#endif
+53 -6
View File
@@ -27,6 +27,7 @@
#include <linux/rkisp1-config.h>
#include <linux/rk-camera-module.h>
#include "rk1608_dphy.h"
#include <linux/compat.h>
#define RK1608_DPHY_NAME "RK1608-dphy"
@@ -201,9 +202,9 @@ static int rk1608_set_fmt(struct v4l2_subdev *sd,
pdata->fmt_inf_idx = idx;
pdata->rk1608_sd->grp_id = pdata->sd.grp_id;
v4l2_subdev_call(pdata->rk1608_sd, pad, set_fmt, cfg, fmt);
pdata->rk1608_sd->grp_id = pdata->sd.grp_id;
remote_ctrl = v4l2_ctrl_find(pdata->rk1608_sd->ctrl_handler,
V4L2_CID_HBLANK);
if (remote_ctrl) {
@@ -249,7 +250,7 @@ static int rk1608_s_frame_interval(struct v4l2_subdev *sd,
return 0;
}
static int rk1608_g_mbus_config(struct v4l2_subdev *sd,
static int rk1608_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
struct v4l2_mbus_config *config)
{
@@ -260,7 +261,7 @@ static int rk1608_g_mbus_config(struct v4l2_subdev *sd,
V4L2_MBUS_CSI2_CHANNEL_0 |
V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
config->type = V4L2_MBUS_CSI2;
config->type = V4L2_MBUS_CSI2_DPHY;
config->flags = val;
return 0;
@@ -310,7 +311,7 @@ static long rk1608_compat_ioctl32(struct v4l2_subdev *sd,
struct preisp_hdrae_exp_s hdrae_exp;
struct rkmodule_inf *inf;
struct rkmodule_awb_cfg *cfg;
long ret;
long ret = -EFAULT;
switch (cmd) {
case PREISP_CMD_SET_HDRAE_EXP:
@@ -327,7 +328,10 @@ static long rk1608_compat_ioctl32(struct v4l2_subdev *sd,
ret = rk1608_ioctl(sd, cmd, inf);
if (!ret)
ret = copy_to_user(up, inf, sizeof(*inf));
if (copy_to_user(up, inf, sizeof(*inf))) {
kfree(inf);
return -EFAULT;
}
kfree(inf);
break;
case RKMODULE_AWB_CFG:
@@ -389,6 +393,47 @@ static int rk1608_set_ctrl(struct v4l2_ctrl *ctrl)
return ret;
}
static int rk1608_get_selection(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_selection *sel)
{
struct rk1608_dphy *pdata = to_state(sd);
u32 idx = pdata->fmt_inf_idx;
if (sel->target != V4L2_SEL_TGT_CROP_BOUNDS)
return -EINVAL;
sel->r.left = 0;
sel->r.top = 0;
sel->r.width = pdata->fmt_inf[idx].mf.width;
sel->r.height = pdata->fmt_inf[idx].mf.height;
return 0;
}
static int rk1608_enum_frame_interval(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_frame_interval_enum *fie)
{
struct rk1608_dphy *pdata = to_state(sd);
u32 idx = pdata->fmt_inf_idx;
int ret = 0;
struct v4l2_fract max_fps = {
.numerator = 10000,
.denominator = 300000,
};
if (fie->index >= pdata->fmt_inf_num)
return -EINVAL;
fie->code = pdata->fmt_inf[idx].mf.code;
fie->width = pdata->fmt_inf[idx].mf.width;
fie->height = pdata->fmt_inf[idx].mf.height;
fie->interval = max_fps;
return ret;
}
static const struct v4l2_ctrl_ops rk1608_ctrl_ops = {
.g_volatile_ctrl = rk1608_g_volatile_ctrl,
.s_ctrl = rk1608_set_ctrl,
@@ -511,7 +556,6 @@ static const struct v4l2_subdev_video_ops rk1608_subdev_video_ops = {
.s_stream = rk1608_s_stream,
.g_frame_interval = rk1608_g_frame_interval,
.s_frame_interval = rk1608_s_frame_interval,
.g_mbus_config = rk1608_g_mbus_config,
};
static const struct v4l2_subdev_pad_ops rk1608_subdev_pad_ops = {
@@ -519,6 +563,9 @@ static const struct v4l2_subdev_pad_ops rk1608_subdev_pad_ops = {
.enum_frame_size = rk1608_enum_frame_sizes,
.get_fmt = rk1608_get_fmt,
.set_fmt = rk1608_set_fmt,
.get_mbus_config = rk1608_g_mbus_config,
.get_selection = rk1608_get_selection,
.enum_frame_interval = rk1608_enum_frame_interval,
};
static const struct v4l2_subdev_core_ops rk1608_core_ops = {