Hello guys; I am confused about changing all the structer because I2C communication is OK and Other structers is fine. I need to change initiliazation stucters only ,actually ioctl_g_ifparm structer but when I look at the MIPI CSI2 format , all the driver should be changed and written from beggining. Is there any way to change the ioctl_g_ifparm(); struct by not corrupting other initialization structers or all shape of the code.
This is the initialization structers which I referred from ov5640_mipi.c file;
/****** Could be changed to the MIPI CSI2 Format ******/
static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
{
if (s == NULL) {
pr_err(" ERROR!! no slave device set!\n");
return -1;
}
memset(p, 0, sizeof(*p));
p->u.bt656.clock_curr = imx290_data.mclk;
pr_debug(" clock_curr=mclk=%d\n", imx290_data.mclk);
pr_info(" clock_curr=mclk=%d\n", imx290_data.mclk);
p->if_type = V4L2_IF_TYPE_BT656;
p->u.bt656.mode = V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT;
p->u.bt656.clock_min = IMX290_XCLK_MIN;
p->u.bt656.clock_max = IMX290_XCLK_MAX;
p->u.bt656.bt_sync_correct = 1; /* Indicate external vsync */
return 0;
}
static int ioctl_s_power(struct v4l2_int_device *s, int on)
{
struct sensor_data *sensor = s->priv;
if (on && !sensor->on) {
if (io_regulator)
if (regulator_enable(io_regulator) != 0)
return -EIO;
if (core_regulator)
if (regulator_enable(core_regulator) != 0)
return -EIO;
if (gpo_regulator)
if (regulator_enable(gpo_regulator) != 0)
return -EIO;
if (analog_regulator)
if (regulator_enable(analog_regulator) != 0)
return -EIO;
} else if (!on && sensor->on) {
if (analog_regulator)
regulator_disable(analog_regulator);
if (core_regulator)
regulator_disable(core_regulator);
if (io_regulator)
regulator_disable(io_regulator);
if (gpo_regulator)
regulator_disable(gpo_regulator);
}
sensor->on = on;
return 0;
}
static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a) // get parameters
{
struct sensor_data *sensor = s->priv;
struct v4l2_captureparm *cparm = &a->parm.capture;
int ret = 0;
switch (a->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
memset(a, 0, sizeof(*a));
a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
cparm->capability = sensor->streamcap.capability;
cparm->timeperframe = sensor->streamcap.timeperframe;
cparm->capturemode = sensor->streamcap.capturemode;
ret = 0;
break;
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
case V4L2_BUF_TYPE_VBI_CAPTURE:
case V4L2_BUF_TYPE_VBI_OUTPUT:
case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
ret = -EINVAL;
break;
default:
pr_debug(" type is unknown - %d\n", a->type);
ret = -EINVAL;
break;
}
return ret;
}
static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
{
struct sensor_data *sensor = s->priv;
struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;
u32 tgt_fps; /* target frames per secound */
enum imx290_frame_rate frame_rate; // frame değerleri için
enum imx290_mode orig_mode;
int ret = 0;
switch (a->type) {
/* This is the only case currently handled. */
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
/* Check that the new frame rate is allowed. */
if ((timeperframe->numerator == 0) ||
(timeperframe->denominator == 0)) {
timeperframe->denominator = DEFAULT_FPS;
timeperframe->numerator = 1;
}
tgt_fps = timeperframe->denominator /
timeperframe->numerator;
if (tgt_fps > MAX_FPS) {
timeperframe->denominator = MAX_FPS;
timeperframe->numerator = 1;
}
/* Actual frame rate we use */
tgt_fps = timeperframe->denominator /
timeperframe->numerator;
if (tgt_fps == 25) //full hd1080p 25 fps
frame_rate = imx290_250_fps;
else if (tgt_fps == 30) //720phd 30 fps
frame_rate = imx290_30_fps;
else {
pr_err(" The camera frame rate is not supported!\n");
return -EINVAL;
}
orig_mode = sensor->streamcap.capturemode;
ret = imx290_init_mode(frame_rate,
(u32)a->parm.capture.capturemode, orig_mode); /// camera initialization
if (ret < 0)
return ret;
sensor->streamcap.timeperframe = *timeperframe;
sensor->streamcap.capturemode =
(u32)a->parm.capture.capturemode;
break;
/* These are all the possible cases. */
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
case V4L2_BUF_TYPE_VBI_CAPTURE:
case V4L2_BUF_TYPE_VBI_OUTPUT:
case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
pr_debug(" type is not " \
"V4L2_BUF_TYPE_VIDEO_CAPTURE but %d\n",
a->type);
ret = -EINVAL;
break;
default:
pr_debug(" type is unknown - %d\n", a->type);
ret = -EINVAL;
break;
}
return ret;
}
static int ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)///get capture format
{
struct sensor_data *sensor = s->priv;
f->fmt.pix = sensor->pix;
return 0;
}
static int ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
{
int ret = 0;
switch (vc->id) {
case V4L2_CID_BRIGHTNESS:
vc->value = imx290_data.brightness;
break;
case V4L2_CID_HUE:
vc->value = imx290_data.hue;
break;
case V4L2_CID_CONTRAST:
vc->value = imx290_data.contrast;
break;
case V4L2_CID_SATURATION:
vc->value = imx290_data.saturation;
break;
case V4L2_CID_RED_BALANCE:
vc->value = imx290_data.red;
break;
case V4L2_CID_BLUE_BALANCE:
vc->value = imx290_data.blue;
break;
case V4L2_CID_EXPOSURE:
vc->value = imx290_data.ae_mode;
break;
default:
ret = -EINVAL;
}
return ret;
}
static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
{
int retval = 0;
pr_debug("In imx290:ioctl_s_ctrl %d\n",vc->id);
switch (vc->id) {
case V4L2_CID_BRIGHTNESS:
break;
case V4L2_CID_CONTRAST:
break;
case V4L2_CID_SATURATION:
break;
case V4L2_CID_HUE:
break;
case V4L2_CID_AUTO_WHITE_BALANCE:
break;
case V4L2_CID_DO_WHITE_BALANCE:
break;
case V4L2_CID_RED_BALANCE:
break;
case V4L2_CID_BLUE_BALANCE:
break;
case V4L2_CID_GAMMA:
break;
case V4L2_CID_EXPOSURE:
break;
case V4L2_CID_AUTOGAIN:
break;
case V4L2_CID_GAIN:
break;
case V4L2_CID_HFLIP:
break;
case V4L2_CID_VFLIP:
break;
default:
retval = -EPERM;
break;
}
return retval;
}
static int ioctl_enum_framesizes(struct v4l2_int_device *s, struct v4l2_frmsizeenum *fsize)
{
if (fsize->index > imx290_mode_MAX)
return -EINVAL;
fsize->pixel_format = imx290_data.pix.pixelformat;
fsize->discrete.width =
max(imx290_mode_info_data[0][fsize->index].width,
imx290_mode_info_data[1][fsize->index].width);
fsize->discrete.height =
max(imx290_mode_info_data[0][fsize->index].height,
imx290_mode_info_data[1][fsize->index].height);
return 0;
}
static int ioctl_enum_frameintervals(struct v4l2_int_device *s,struct v4l2_frmivalenum *fival)
{
int i, j, count = 0;
fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
fival->discrete.numerator = 1;
for (i = 0; i < ARRAY_SIZE(imx290_mode_info_data); i++)
for (j = 0; j < (imx290_mode_MAX + 1); j++)
if (fival->pixel_format == imx290_data.pix.pixelformat
&& fival->width == imx290_mode_info_data[i][j].width
&& fival->height == imx290_mode_info_data[i][j].height
&& imx290_mode_info_data[i][j].init_data_ptr != NULL
&& fival->index == count++) {
fival->discrete.denominator =
imx290_framerates[i];
return 0;
}
return -EINVAL;
}
static int ioctl_g_chip_ident(struct v4l2_int_device *s, int *id)
{
((struct v4l2_dbg_chip_ident *)id)->match.type =V4L2_CHIP_MATCH_I2C_DRIVER;
strcpy(((struct v4l2_dbg_chip_ident *)id)->match.name,"imx290_mipi_camera");
return 0;
}
static int ioctl_init(struct v4l2_int_device *s)
{
return 0;
}
static int ioctl_enum_fmt_cap(struct v4l2_int_device *s, struct v4l2_fmtdesc *fmt)
{
if (fmt->index > imx290_mode_MAX) //fmt->index = Number of the format in the enumeration
return -EINVAL;
fmt->pixelformat = imx290_data.pix.pixelformat; //pixelformat = The image format identifier
return 0;
}
static int ioctl_dev_init(struct v4l2_int_device *s) //device initialization
{
struct sensor_data *sensor = s->priv;
u32 tgt_xclk; /* target xclk */
u32 tgt_fps; /* target frames per secound */
int ret;
enum imx290_frame_rate frame_rate;
void *mipi_csi2_info;
imx290_data.on = true;
/* mclk */
tgt_xclk = imx290_data.mclk;
imx290_data.mclk = tgt_xclk;
pr_debug(" Setting mclk to %d MHz\n", tgt_xclk / 1000000);
/* Default camera frame rate is set in probe */
tgt_fps = sensor->streamcap.timeperframe.denominator /
sensor->streamcap.timeperframe.numerator;
if (tgt_fps == 25) //full hd
frame_rate = imx290_25_fps;
else if (tgt_fps == 30) // 720HD
frame_rate = imx290_30_fps;
else
return -EINVAL;
mipi_csi2_info = mipi_csi2_get_info();
/* enable mipi csi2 */
if (mipi_csi2_info)
mipi_csi2_enable(mipi_csi2_info);
else {
printk(KERN_ERR "%s() in %s: Fail to get mipi_csi2_info!\n",
__func__, __FILE__);
return -EPERM;
}
ret = imx290_init_mode(frame_rate, imx290_mode_INIT, imx290_mode_INIT);
return ret;
}
static int ioctl_dev_exit(struct v4l2_int_device *s)
{
void *mipi_csi2_info;
mipi_csi2_info = mipi_csi2_get_info();
/* disable mipi csi2 */
if (mipi_csi2_info)
if (mipi_csi2_get_status(mipi_csi2_info))
mipi_csi2_disable(mipi_csi2_info);
return 0;
}
static struct v4l2_int_ioctl_desc imx290_ioctl_desc[] = {
{vidioc_int_dev_init_num, (v4l2_int_ioctl_func *) ioctl_dev_init},
{vidioc_int_dev_exit_num, ioctl_dev_exit},
{vidioc_int_s_power_num, (v4l2_int_ioctl_func *) ioctl_s_power},
{vidioc_int_g_ifparm_num, (v4l2_int_ioctl_func *) ioctl_g_ifparm},
{vidioc_int_init_num, (v4l2_int_ioctl_func *) ioctl_init},
{vidioc_int_enum_fmt_cap_num, (v4l2_int_ioctl_func *) ioctl_enum_fmt_cap},
{vidioc_int_g_fmt_cap_num, (v4l2_int_ioctl_func *) ioctl_g_fmt_cap},
{vidioc_int_g_parm_num, (v4l2_int_ioctl_func *) ioctl_g_parm},
{vidioc_int_s_parm_num, (v4l2_int_ioctl_func *) ioctl_s_parm},
{vidioc_int_g_ctrl_num, (v4l2_int_ioctl_func *) ioctl_g_ctrl},
{vidioc_int_s_ctrl_num, (v4l2_int_ioctl_func *) ioctl_s_ctrl},
{vidioc_int_enum_framesizes_num, (v4l2_int_ioctl_func *) ioctl_enum_framesizes},
{vidioc_int_enum_frameintervals_num,(v4l2_int_ioctl_func *) ioctl_enum_frameintervals},
{vidioc_int_g_chip_ident_num, (v4l2_int_ioctl_func *) ioctl_g_chip_ident},
};