mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 11:26:02 +09:00
media: spi: update 1608 driver
1. update safe read, limit max op size. 2. add dsp time init. 3. add dsp frame control msg. 4. support flip. 5. support file export/import, calib data read/write. 6. add align calculate func. Signed-off-by: Zhenke Fan <fanzy.fan@rock-chips.com> Change-Id: I714aec690d00c9aa6f7f4ef58c3616bfcbf238bb
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -15,7 +15,9 @@
|
||||
#include <linux/version.h>
|
||||
#include "rk1608_dphy.h"
|
||||
|
||||
#define RK1608_VERSION KERNEL_VERSION(0, 0x01, 0x03)
|
||||
#define RK1608_VERSION KERNEL_VERSION(0, 0x01, 0x04)
|
||||
|
||||
#define UPDATE_REF_DATA_FROM_EEPROM (1)
|
||||
|
||||
#define RK1608_OP_TRY_MAX 3
|
||||
#define RK1608_OP_TRY_DELAY 10
|
||||
@@ -41,7 +43,7 @@
|
||||
#define RK1608_MSG_QUEUE_OK_MASK 0xffff0001
|
||||
#define RK1608_MSG_QUEUE_OK_TAG 0x16080001
|
||||
#define RK1608_MAX_OP_BYTES 60000
|
||||
#define MSG_SYNC_TIMEOUT 50
|
||||
#define MSG_SYNC_TIMEOUT 3000
|
||||
|
||||
#define BOOT_FLAG_CRC (0x01 << 0)
|
||||
#define BOOT_FLAG_EXE (0x01 << 1)
|
||||
@@ -70,6 +72,9 @@
|
||||
|
||||
#define ISP_DSP_HDRAE_MAXGRIDITEMS 225
|
||||
|
||||
#define MIRROR_BIT_MASK BIT(0)
|
||||
#define FLIP_BIT_MASK BIT(1)
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
@@ -99,6 +104,7 @@ struct rk1608_state {
|
||||
struct mutex spi2apb_lock; /* protect spi2apb write/read */
|
||||
spinlock_t hdrae_lock; /* protect hdrae parameter */
|
||||
struct gpio_desc *reset_gpio;
|
||||
struct gpio_desc *pwren_gpio;
|
||||
struct gpio_desc *irq_gpio;
|
||||
int irq;
|
||||
struct gpio_desc *wakeup_gpio;
|
||||
@@ -124,6 +130,8 @@ struct rk1608_state {
|
||||
struct v4l2_ctrl *vblank;
|
||||
struct v4l2_ctrl *exposure;
|
||||
struct v4l2_ctrl *gain;
|
||||
struct v4l2_ctrl *h_flip;
|
||||
struct v4l2_ctrl *v_flip;
|
||||
struct v4l2_ctrl_handler ctrl_handler;
|
||||
u32 max_speed_hz;
|
||||
u32 min_speed_hz;
|
||||
@@ -131,6 +139,7 @@ struct rk1608_state {
|
||||
struct preisp_hdrae_exp_s hdrae_exp;
|
||||
u32 set_exp_cnt;
|
||||
const char *firm_name;
|
||||
u8 flip;
|
||||
};
|
||||
|
||||
struct rk1608_section {
|
||||
@@ -229,7 +238,10 @@ struct msg_out_size_head {
|
||||
u16 line_length_pclk;
|
||||
u16 frame_length_lines;
|
||||
u16 mipi_lane;
|
||||
u16 reserved;
|
||||
union {
|
||||
u16 flip;
|
||||
u16 reserved;
|
||||
};
|
||||
};
|
||||
|
||||
struct msg_set_output_size {
|
||||
@@ -237,6 +249,13 @@ struct msg_set_output_size {
|
||||
struct preisp_vc_cfg channel[4];
|
||||
};
|
||||
|
||||
struct msg_init_dsp_time {
|
||||
struct msg msg_head;
|
||||
u16 t_ms;
|
||||
s32 tv_sec;
|
||||
s32 tv_usec;
|
||||
};
|
||||
|
||||
enum ISP_AE_Bayer_Mode_e {
|
||||
BAYER_MODE_MIN = 0,
|
||||
BAYER_MODE_BGGR = 1,
|
||||
@@ -298,6 +317,25 @@ struct msg_set_sensor_info_s {
|
||||
struct ISP_DSP_hdrae_cfg_s dsp_hdrae;
|
||||
};
|
||||
|
||||
struct msg_calib_temp {
|
||||
u32 size; // unit 4 bytes
|
||||
u16 type; // msg identification
|
||||
s8 camera_id;
|
||||
s8 sync;
|
||||
|
||||
u32 temp;
|
||||
u32 calib_version;
|
||||
|
||||
#if UPDATE_REF_DATA_FROM_EEPROM
|
||||
u32 calib_exist;
|
||||
u32 calib_sn_size;
|
||||
u32 calib_sn_offset;
|
||||
u32 calib_sn_code;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define MSG_RESPONSE_ID_OFFSET 0x2ff
|
||||
|
||||
enum {
|
||||
/* AP -> RK1608
|
||||
* 1 msg of sensor
|
||||
@@ -376,9 +414,93 @@ enum {
|
||||
/* RK1608 -> AP
|
||||
* 10 msg of xfile
|
||||
*/
|
||||
id_msg_xfile_import_t = 0x8000 + 0x0600,
|
||||
/* id_msg_xfile_import_t = 0x8000 + 0x0600,
|
||||
* id_msg_xfile_export_t,
|
||||
* id_msg_xfile_mkdir_t
|
||||
*/
|
||||
|
||||
/* for dsp time. */
|
||||
id_msg_frame_time_t = 0x1000,
|
||||
id_msg_sys_time_set_t,
|
||||
|
||||
//calib temperature and version
|
||||
id_msg_temperature_t = 0x1002,
|
||||
id_msg_temperature_req_t = 0x1302,
|
||||
id_msg_calib_temperature_t = 0x1004,
|
||||
id_msg_calib_temperature_req_t = 0x1303,
|
||||
|
||||
id_msg_calibration_write_req_t = 0x1050,
|
||||
id_msg_calibration_write_done_t,
|
||||
id_msg_calibration_read_req_t = 0x1052,
|
||||
id_msg_calibration_read_done_t,
|
||||
id_msg_calibration_write_req_mode2_t = 0x1054,
|
||||
id_msg_calibration_read_req_mode2_t,
|
||||
|
||||
id_msg_calibration_write_req_ret_t = 0x1050 + MSG_RESPONSE_ID_OFFSET,
|
||||
id_msg_calibration_write_done_ret_t = 0x1051 + MSG_RESPONSE_ID_OFFSET,
|
||||
id_msg_calibration_read_req_ret_t = 0x1052 + MSG_RESPONSE_ID_OFFSET,
|
||||
id_msg_calibration_read_done_ret_t = 0x1053 + MSG_RESPONSE_ID_OFFSET,
|
||||
|
||||
|
||||
/* 1808 for disp control */
|
||||
id_msg_disp_set_frame_output_t = 0x1070,
|
||||
id_msg_disp_set_frame_format_t,
|
||||
id_msg_disp_set_frame_type_t,
|
||||
id_msg_disp_set_pro_time_t,
|
||||
id_msg_disp_set_pro_current_t,
|
||||
id_msg_disp_set_denoise_t,
|
||||
id_msg_disp_set_led_on_off_t,
|
||||
|
||||
/* 0xf000 ~ 0xfdff id reversed. */
|
||||
id_msg_xfile_import_t = 0xfe00,
|
||||
id_msg_xfile_export_t,
|
||||
id_msg_xfile_mkdir_t
|
||||
|
||||
};
|
||||
|
||||
|
||||
#define PREISP_CALIB_ITEM_NUM 24
|
||||
#define PREISP_CALIB_MAGIC "#SLM_CALIB_DATA#"
|
||||
|
||||
struct calib_item {
|
||||
unsigned char name[48];
|
||||
unsigned int offset;
|
||||
unsigned int size;
|
||||
unsigned int temp;
|
||||
unsigned int crc32;
|
||||
};
|
||||
|
||||
struct calib_head {
|
||||
unsigned char magic[16];
|
||||
unsigned int version;
|
||||
unsigned int head_size;
|
||||
unsigned int image_size;
|
||||
unsigned int items_number;
|
||||
unsigned char reserved0[32];
|
||||
unsigned int hash_len;
|
||||
unsigned char hash[32];
|
||||
unsigned char reserved1[28];
|
||||
unsigned int sign_tag;
|
||||
unsigned int sign_len;
|
||||
unsigned char rsa_hash[256];
|
||||
unsigned char reserved2[120];
|
||||
struct calib_item item[PREISP_CALIB_ITEM_NUM];
|
||||
};
|
||||
|
||||
#define XFILE_MAX_PATH 256
|
||||
struct msg_xfile {
|
||||
u32 size;
|
||||
u16 type;
|
||||
s8 camera_id;
|
||||
union {
|
||||
s8 sync;
|
||||
s8 ret;
|
||||
};
|
||||
u32 addr;
|
||||
u32 data_size;
|
||||
u32 cb;
|
||||
u32 args;
|
||||
char path[XFILE_MAX_PATH];
|
||||
};
|
||||
|
||||
int rk1608_send_msg_to_dsp(struct rk1608_state *pdata, struct msg *m);
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
* extra sensor,and it is passed to the Soc through ISP.
|
||||
*/
|
||||
|
||||
static DEFINE_MUTEX(rk1608_dphy_mutex);
|
||||
static inline struct rk1608_dphy *to_state(struct v4l2_subdev *sd)
|
||||
{
|
||||
return container_of(sd, struct rk1608_dphy, sd);
|
||||
@@ -248,6 +249,23 @@ static int rk1608_s_frame_interval(struct v4l2_subdev *sd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk1608_g_mbus_config(struct v4l2_subdev *sd,
|
||||
struct v4l2_mbus_config *config)
|
||||
{
|
||||
|
||||
struct rk1608_dphy *pdata = to_state(sd);
|
||||
u32 val = 0;
|
||||
|
||||
val = 1 << (pdata->fmt_inf[pdata->fmt_inf_idx].mipi_lane - 1) |
|
||||
V4L2_MBUS_CSI2_CHANNEL_0 |
|
||||
V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
|
||||
|
||||
config->type = V4L2_MBUS_CSI2;
|
||||
config->flags = val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long rk1608_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
||||
{
|
||||
struct rk1608_dphy *pdata = to_state(sd);
|
||||
@@ -255,12 +273,28 @@ static long rk1608_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
||||
|
||||
switch (cmd) {
|
||||
case PREISP_CMD_SAVE_HDRAE_PARAM:
|
||||
ret = v4l2_subdev_call(pdata->rk1608_sd, core, ioctl,
|
||||
cmd, arg);
|
||||
break;
|
||||
case PREISP_CMD_SET_HDRAE_EXP:
|
||||
case RKMODULE_GET_MODULE_INFO:
|
||||
case RKMODULE_AWB_CFG:
|
||||
|
||||
case PREISP_DISP_SET_FRAME_OUTPUT:
|
||||
case PREISP_DISP_SET_FRAME_FORMAT:
|
||||
case PREISP_DISP_SET_FRAME_TYPE:
|
||||
case PREISP_DISP_SET_PRO_TIME:
|
||||
case PREISP_DISP_SET_PRO_CURRENT:
|
||||
case PREISP_DISP_SET_DENOISE:
|
||||
case PREISP_DISP_WRITE_EEPROM:
|
||||
case PREISP_DISP_READ_EEPROM:
|
||||
case PREISP_DISP_SET_LED_ON_OFF:
|
||||
mutex_lock(&rk1608_dphy_mutex);
|
||||
pdata->rk1608_sd->grp_id = pdata->sd.grp_id;
|
||||
ret = v4l2_subdev_call(pdata->rk1608_sd, core, ioctl,
|
||||
cmd, arg);
|
||||
return ret;
|
||||
mutex_unlock(&rk1608_dphy_mutex);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOIOCTLCMD;
|
||||
break;
|
||||
@@ -275,6 +309,7 @@ static long rk1608_compat_ioctl32(struct v4l2_subdev *sd,
|
||||
void __user *up = compat_ptr(arg);
|
||||
struct preisp_hdrae_exp_s hdrae_exp;
|
||||
struct rkmodule_inf *inf;
|
||||
struct rkmodule_awb_cfg *cfg;
|
||||
long ret;
|
||||
|
||||
switch (cmd) {
|
||||
@@ -295,6 +330,17 @@ static long rk1608_compat_ioctl32(struct v4l2_subdev *sd,
|
||||
ret = copy_to_user(up, inf, sizeof(*inf));
|
||||
kfree(inf);
|
||||
break;
|
||||
case RKMODULE_AWB_CFG:
|
||||
cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
|
||||
if (!cfg) {
|
||||
ret = -ENOMEM;
|
||||
return ret;
|
||||
}
|
||||
if (copy_from_user(cfg, up, sizeof(cfg)))
|
||||
return -EFAULT;
|
||||
ret = rk1608_ioctl(sd, cmd, cfg);
|
||||
kfree(cfg);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOIOCTLCMD;
|
||||
break;
|
||||
@@ -374,7 +420,7 @@ static int rk1608_initialize_controls(struct rk1608_dphy *dphy)
|
||||
{
|
||||
u32 i;
|
||||
int ret;
|
||||
s64 pixel_rate, pixel_bit;
|
||||
u64 pixel_rate, pixel_bit;
|
||||
u32 idx = dphy->fmt_inf_idx;
|
||||
struct v4l2_ctrl_handler *handler;
|
||||
unsigned long flags = V4L2_CTRL_FLAG_VOLATILE |
|
||||
@@ -465,6 +511,7 @@ 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 = {
|
||||
|
||||
@@ -34,6 +34,8 @@ struct rk1608_dphy {
|
||||
struct v4l2_ctrl *vblank;
|
||||
struct v4l2_ctrl *exposure;
|
||||
struct v4l2_ctrl *gain;
|
||||
struct v4l2_ctrl *h_flip;
|
||||
struct v4l2_ctrl *v_flip;
|
||||
struct v4l2_ctrl_handler ctrl_handler;
|
||||
|
||||
u32 cam_nums;
|
||||
@@ -53,4 +55,6 @@ struct rk1608_dphy {
|
||||
u32 fmt_inf_num;
|
||||
u32 fmt_inf_idx;
|
||||
struct rk1608_fmt_inf fmt_inf[RK1608_MAX_FMTINF];
|
||||
|
||||
bool first_stream;
|
||||
};
|
||||
|
||||
@@ -19,6 +19,33 @@
|
||||
#define PREISP_CMD_SAVE_HDRAE_PARAM \
|
||||
_IOW('V', BASE_VIDIOC_PRIVATE + 1, struct preisp_hdrae_para_s)
|
||||
|
||||
#define PREISP_DISP_SET_FRAME_OUTPUT \
|
||||
_IOW('V', BASE_VIDIOC_PRIVATE + 4, int)
|
||||
|
||||
#define PREISP_DISP_SET_FRAME_FORMAT \
|
||||
_IOW('V', BASE_VIDIOC_PRIVATE + 5, unsigned int)
|
||||
|
||||
#define PREISP_DISP_SET_FRAME_TYPE \
|
||||
_IOW('V', BASE_VIDIOC_PRIVATE + 6, unsigned int)
|
||||
|
||||
#define PREISP_DISP_SET_PRO_TIME \
|
||||
_IOW('V', BASE_VIDIOC_PRIVATE + 7, unsigned int)
|
||||
|
||||
#define PREISP_DISP_SET_PRO_CURRENT \
|
||||
_IOW('V', BASE_VIDIOC_PRIVATE + 8, unsigned int)
|
||||
|
||||
#define PREISP_DISP_SET_DENOISE \
|
||||
_IOW('V', BASE_VIDIOC_PRIVATE + 9, unsigned int[2])
|
||||
|
||||
#define PREISP_DISP_WRITE_EEPROM \
|
||||
_IO('V', BASE_VIDIOC_PRIVATE + 10)
|
||||
|
||||
#define PREISP_DISP_READ_EEPROM \
|
||||
_IO('V', BASE_VIDIOC_PRIVATE + 11)
|
||||
|
||||
#define PREISP_DISP_SET_LED_ON_OFF \
|
||||
_IOW('V', BASE_VIDIOC_PRIVATE + 12, unsigned int)
|
||||
|
||||
#define PREISP_POWER_ON _IO('p', 1)
|
||||
#define PREISP_POWER_OFF _IO('p', 2)
|
||||
#define PREISP_REQUEST_SLEEP _IOW('p', 3, s32)
|
||||
|
||||
Reference in New Issue
Block a user