diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index d6d4ceb2c78f..edc46eb4b0a8 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -493,14 +493,15 @@ static int soc_camera_init_user_formats(struct soc_camera_device *icd) struct soc_camera_host *ici = to_soc_camera_host(icd->parent); unsigned int i, fmts = 0, raw_fmts = 0; int ret; - struct v4l2_subdev_mbus_code_enum code = { - .which = V4L2_SUBDEV_FORMAT_ACTIVE, - }; + u32 code; - while (!v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code)) { + while (!v4l2_subdev_call(sd, video, enum_mbus_fmt, raw_fmts, &code)) raw_fmts++; - code.index++; - } + + if (!raw_fmts) + dev_err(icd->pdev, + "%s(%d): raw_fmts is NULL\n", + __func__, __LINE__); if (!ici->ops->get_formats) /* @@ -534,12 +535,11 @@ static int soc_camera_init_user_formats(struct soc_camera_device *icd) fmts = 0; for (i = 0; i < raw_fmts; i++) if (!ici->ops->get_formats) { - code.index = i; - v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code); + v4l2_subdev_call(sd, video, enum_mbus_fmt, i, &code); icd->user_formats[fmts].host_fmt = - soc_mbus_get_fmtdesc(code.code); + soc_mbus_get_fmtdesc(code); if (icd->user_formats[fmts].host_fmt) - icd->user_formats[fmts++].code = code.code; + icd->user_formats[fmts++].code = code; } else { ret = ici->ops->get_formats(icd, i, &icd->user_formats[fmts]); @@ -914,6 +914,31 @@ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv, return ret; } +/* + * ddl@rock-chips.com : + * Add ioctrl - VIDIOC_ENUM_FRAMEINTERVALS for soc-camera. + */ +static int soc_camera_enum_frameintervals(struct file *file, void *priv, + struct v4l2_frmivalenum *fival) +{ + struct soc_camera_device *icd = file->private_data; + struct soc_camera_host *ici = to_soc_camera_host(icd->parent); + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + int ret; + + WARN_ON(priv != file->private_data); + + ret = v4l2_subdev_call(sd, video, enum_frameintervals, fival); + if (ret == -ENOIOCTLCMD) { + if (ici->ops->enum_frameinervals) + ret = ici->ops->enum_frameinervals(icd, fival); + else + ret = -ENOIOCTLCMD; + } + + return ret; +} + static int soc_camera_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) { @@ -937,6 +962,7 @@ static int soc_camera_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct soc_camera_device *icd = file->private_data; + struct soc_camera_host *ici = to_soc_camera_host(icd->parent); struct v4l2_pix_format *pix = &f->fmt.pix; WARN_ON(priv != file->private_data); @@ -953,6 +979,8 @@ static int soc_camera_g_fmt_vid_cap(struct file *file, void *priv, pix->colorspace = icd->colorspace; dev_dbg(icd->pdev, "current_fmt->fourcc: 0x%08x\n", icd->current_fmt->host_fmt->fourcc); + + ici->ops->get_fmt(icd, f); return 0; } @@ -990,8 +1018,12 @@ static int soc_camera_streamon(struct file *file, void *priv, else ret = vb2_streamon(&icd->vb2_vidq, i); - if (!ret) + if (!ret) { v4l2_subdev_call(sd, video, s_stream, 1); + if (ici->ops->s_stream) + /* ddl@rock-chips.com : Add stream control for host */ + ici->ops->s_stream(icd, 1); + } return ret; } @@ -1012,6 +1044,11 @@ static int soc_camera_streamoff(struct file *file, void *priv, if (icd->streamer != file) return -EBUSY; + /* ddl@rock-chips.com: v0.1.1 */ + v4l2_subdev_call(sd, video, s_stream, 0); + if (ici->ops->s_stream) + ici->ops->s_stream(icd, 0); + /* * This calls buf_release from host driver's videobuf_queue_ops for all * remaining buffers. When the last buffer is freed, stop capture @@ -1026,6 +1063,183 @@ static int soc_camera_streamoff(struct file *file, void *priv, return ret; } +static int soc_camera_queryctrl(struct file *file, void *priv, + struct v4l2_queryctrl *qc) +{ + struct soc_camera_device *icd = file->private_data; + struct soc_camera_host *ici = to_soc_camera_host(icd->parent); + int i; + + WARN_ON(priv != file->private_data); + + if (!qc->id) + return -EINVAL; + + /* first device controls + * if device support digital zoom ,first use it to do zoom,zyc + */ + for (i = 0; i < icd->ops->num_controls; i++) + if (qc->id == icd->ops->controls[i].id) { + memcpy(qc, &icd->ops->controls[i], sizeof(*qc)); + return 0; + } + + /* then check host controls */ + for (i = 0; i < ici->ops->num_controls; i++) + if (qc->id == ici->ops->controls[i].id) { + memcpy(qc, &ici->ops->controls[i], sizeof(*qc)); + return 0; + } + + return -EINVAL; +} + +/* ddl@rock-chips.com : Add ioctrl -VIDIOC_QUERYMENU */ +static int soc_camera_querymenu(struct file *file, void *priv, + struct v4l2_querymenu *qm) +{ + struct soc_camera_device *icd = file->private_data; + struct v4l2_queryctrl qctrl; + int i, j; + + qctrl.id = qm->id; + + if (soc_camera_queryctrl(file, priv, &qctrl)) + return -EINVAL; + + for (i = 0; i < icd->ops->num_menus; i++) { + if (qm->id == icd->ops->menus[i].id) { + for (j = 0; j <= (qctrl.maximum - qctrl.minimum); j++) { + if (qm->index == icd->ops->menus[i].index) { + snprintf(qm->name, sizeof(qm->name), + icd->ops->menus[i].name); + qm->reserved = 0; + + return 0; + } else { + i++; + if (i >= icd->ops->num_menus) + return -EINVAL; + } + } + } + } + + return 0; +} + +static int soc_camera_g_ctrl(struct file *file, void *priv, + struct v4l2_control *ctrl) +{ + struct soc_camera_device *icd = file->private_data; + struct soc_camera_host *ici = to_soc_camera_host(icd->parent); + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + int ret; + + WARN_ON(priv != file->private_data); + + if (ici->ops->get_ctrl) { + ret = ici->ops->get_ctrl(icd, ctrl); + if (ret != -ENOIOCTLCMD) + return ret; + } + + return v4l2_subdev_call(sd, core, g_ctrl, ctrl); +} + +static int soc_camera_s_ctrl(struct file *file, void *priv, + struct v4l2_control *ctrl) +{ + struct soc_camera_device *icd = file->private_data; + struct soc_camera_host *ici = to_soc_camera_host(icd->parent); + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + int ret; + + WARN_ON(priv != file->private_data); + + if (ici->ops->set_ctrl) { + ret = ici->ops->set_ctrl(icd, ctrl); + if (ret != -ENOIOCTLCMD) + return ret; + } + + return v4l2_subdev_call(sd, core, s_ctrl, ctrl); +} + +/* ddl@rock-chips.com : Add ioctrl -VIDIOC_XXX_ext_ctrl for soc-camera */ +static int soc_camera_try_ext_ctrl(struct file *file, void *priv, + struct v4l2_ext_controls *ctrl) +{ + struct soc_camera_device *icd = file->private_data; + const struct v4l2_queryctrl *qctrl; + int i; + + WARN_ON(priv != file->private_data); + + /*current kernel version don't define + *this member for struct v4l2_ext_control. + */ + + /* + *if (ctrl->ctrl_class != V4L2_CTRL_CLASS_CAMERA) + * return -EINVAL; + */ + + for (i = 0; i < ctrl->count; i++) { + qctrl = soc_camera_find_qctrl(icd->ops, ctrl->controls[i].id); + if (!qctrl) + return -EINVAL; + + if ((ctrl->controls[i].value < qctrl->minimum) || + (ctrl->controls[i].value > qctrl->minimum)) + return -ERANGE; + } + + return 0; +} + + /* ddl@rock-chips.com : Add ioctrl -VIDIOC_XXX_ext_ctrl for soc-camera */ +static int soc_camera_g_ext_ctrl(struct file *file, void *priv, + struct v4l2_ext_controls *ctrl) +{ + struct soc_camera_device *icd = file->private_data; + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + + WARN_ON(priv != file->private_data); + + /*current kernel version don't define + *this member for struct v4l2_ext_control. + */ + + /* + *if (ctrl->ctrl_class != V4L2_CTRL_CLASS_CAMERA) + * return -EINVAL; + */ + + return v4l2_subdev_call(sd, core, g_ext_ctrls, ctrl); +} + + /* ddl@rock-chips.com : Add ioctrl -VIDIOC_XXX_ext_ctrl for soc-camera */ +static int soc_camera_s_ext_ctrl(struct file *file, void *priv, + struct v4l2_ext_controls *ctrl) +{ + struct soc_camera_device *icd = file->private_data; + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + + WARN_ON(priv != file->private_data); + + /*current kernel version don't define + *this member for struct v4l2_ext_control. + */ + + /* + *if (ctrl->ctrl_class != V4L2_CTRL_CLASS_CAMERA) + * return -EINVAL; + */ + + return v4l2_subdev_call(sd, core, s_ext_ctrls, ctrl); +} + static int soc_camera_cropcap(struct file *file, void *fh, struct v4l2_cropcap *a) { @@ -1339,6 +1553,7 @@ static int soc_camera_probe_finish(struct soc_camera_device *icd) icd->colorspace = mf->colorspace; icd->field = mf->field; } + soc_camera_remove_device(icd); return 0; @@ -1748,6 +1963,7 @@ static int soc_camera_probe(struct soc_camera_host *ici, { struct soc_camera_desc *sdesc = to_soc_camera_desc(icd); struct soc_camera_host_desc *shd = &sdesc->host_desc; + struct soc_camera_subdev_desc *ssdd = &sdesc->subdev_desc; struct device *control = NULL; int ret; @@ -1764,11 +1980,15 @@ static int soc_camera_probe(struct soc_camera_host *ici, if (ret < 0) return ret; + ret = soc_camera_power_on(icd->pdev, ssdd, NULL); + if (ret < 0) + goto eadd; + /* Must have icd->vdev before registering the device */ ret = video_dev_create(icd); if (ret < 0) goto evdc; - + ssdd->socdev = icd; /* * ..._video_start() will create a device node, video_register_device() * itself is protected against concurrent open() calls, but we also have @@ -2124,6 +2344,21 @@ static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = { .vidioc_expbuf = soc_camera_expbuf, .vidioc_streamon = soc_camera_streamon, .vidioc_streamoff = soc_camera_streamoff, + + .vidioc_queryctrl = soc_camera_queryctrl, + /* ddl@rock-chips.com: Add ioctrl - vidioc_querymenu for soc-camera */ + .vidioc_querymenu = soc_camera_querymenu, + .vidioc_g_ctrl = soc_camera_g_ctrl, + .vidioc_s_ctrl = soc_camera_s_ctrl, + /* ddl@rock-chips.com: Add ioctrl - vidioc_g_ext_ctrls for soc-camera */ + .vidioc_g_ext_ctrls = soc_camera_g_ext_ctrl, + /* ddl@rock-chips.com: Add ioctrl - vidioc_s_ext_ctrls for soc-camera */ + .vidioc_s_ext_ctrls = soc_camera_s_ext_ctrl, + /* ddl@rock-chips.com: Add ioctrl - vidioc_try_ext_ctrls for soc-camera */ + .vidioc_try_ext_ctrls = soc_camera_try_ext_ctrl, + /* ddl@rock-chips.com: Add ioctrl - VIDIOC_ENUM_FRAMEINTERVALS for soc-camera */ + .vidioc_enum_frameintervals = soc_camera_enum_frameintervals, + .vidioc_cropcap = soc_camera_cropcap, .vidioc_g_crop = soc_camera_g_crop, .vidioc_s_crop = soc_camera_s_crop, @@ -2143,6 +2378,7 @@ static int video_dev_create(struct soc_camera_device *icd) strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name)); + vdev->dev_parent = icd->pdev; vdev->v4l2_dev = &ici->v4l2_dev; vdev->fops = &soc_camera_fops; vdev->ioctl_ops = &soc_camera_ioctl_ops; diff --git a/drivers/media/v4l2-core/videobuf-dma-contig.c b/drivers/media/v4l2-core/videobuf-dma-contig.c index e02353e340dd..c194bafb609f 100644 --- a/drivers/media/v4l2-core/videobuf-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf-dma-contig.c @@ -265,6 +265,8 @@ static int __videobuf_iolock(struct videobuf_queue *q, return -ENOMEM; break; case V4L2_MEMORY_OVERLAY: + /* ddl@rock-chips.com : nzy modify V4L2_MEMORY_OVERLAY */ + break; default: dev_dbg(q->dev, "%s memory method OVERLAY/unknown\n", __func__); return -EINVAL; diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 51299a5644be..79de6de5bb0c 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -1,36 +1,44 @@ -obj-$(CONFIG_RK30_CAMERA_PINGPONG) += rk30_camera_pingpong.o generic_sensor.o \ -gc0307.o \ -gc0308.o \ -gc0309.o \ -gc0328.o \ -gc0329.o \ -gc2015.o \ -gc2035.o \ -gt2005.o \ -hm2057.o \ -hm5065.o \ -mt9p111.o \ -nt99160_2way.o \ -nt99240_2way.o \ -ov2659.o \ -ov5640.o \ -sp0838.o \ -sp2518.o -obj-$(CONFIG_RK30_CAMERA_ONEFRAME) += rk30_camera_oneframe.o generic_sensor.o \ -gc0307.o \ -gc0308.o \ -gc0309.o \ -gc0328.o \ -gc0329.o \ -gc2015.o \ -gc2035.o \ -gt2005.o \ -hm2057.o \ -hm5065.o \ -mt9p111.o \ -nt99160_2way.o \ -nt99240_2way.o \ -ov2659.o \ -ov5640.o \ -sp0838.o \ -sp2518.o +obj-$(CONFIG_RK30_CAMERA_PINGPONG) += rk30_camera_pingpong.o generic_sensor.o \ +gc0307.o \ +gc0308.o \ +gc0309.o \ +gc0328.o \ +gc0329.o \ +gc2015.o \ +gc2035.o \ +gc2145.o \ +gc2155.o \ +gt2005.o \ +hm2057.o \ +hm5065.o \ +mt9p111.o \ +nt99160_2way.o \ +nt99240_2way.o \ +ov2659.o \ +ov5640.o \ +sp0838.o \ +sp2518.o \ +tp2825.o \ +adv7181.o +obj-$(CONFIG_RK30_CAMERA_ONEFRAME) += rk30_camera_oneframe.o generic_sensor.o \ +gc0307.o \ +gc0308.o \ +gc0309.o \ +gc0328.o \ +gc0329.o \ +gc2015.o \ +gc2035.o \ +gc2145.o \ +gc2155.o \ +gt2005.o \ +hm2057.o \ +hm5065.o \ +mt9p111.o \ +nt99160_2way.o \ +nt99240_2way.o \ +ov2659.o \ +ov5640.o \ +sp0838.o \ +sp2518.o \ +tp2825.o \ +adv7181.o diff --git a/drivers/media/video/adv7181.c b/drivers/media/video/adv7181.c new file mode 100644 index 000000000000..84ad9bdfebae --- /dev/null +++ b/drivers/media/video/adv7181.c @@ -0,0 +1,1555 @@ +/* + * drivers/media/video/adv7181.c + * + * Copyright (C) ROCKCHIP, Inc. + * Author:zhoupeng + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "generic_sensor.h" +#include +#include +#include +#include + + +/* + * Driver Version Note + *v0.0.1: this driver is compatible with generic_sensor + *v0.0.2: support debug_fs for debug + */ +static int version = KERNEL_VERSION(0, 0, 1); +module_param(version, int, S_IRUGO); + +static int debug; +module_param(debug, int, S_IRUGO|S_IWUSR); + +#define dprintk(level, fmt, arg...) do { \ + if (debug >= level) \ + printk(KERN_WARNING fmt, ## arg); \ +} while (0) +#define debug_printk(format, ...) dprintk(1, format, ## __VA_ARGS__) +/* Sensor Driver Configuration Begin */ +#define SENSOR_NAME RK29_CAM_SENSOR_ADV7181 +#define SENSOR_V4L2_IDENT V4L2_IDENT_ADV7181 +#define SENSOR_ID 0x20 +#define SENSOR_BUS_PARAM (V4L2_MBUS_MASTER | \ + V4L2_MBUS_PCLK_SAMPLE_RISING | \ + V4L2_MBUS_HSYNC_ACTIVE_HIGH | \ + V4L2_MBUS_VSYNC_ACTIVE_HIGH | \ + V4L2_MBUS_DATA_ACTIVE_HIGH | \ + SOCAM_MCLK_24MHZ) + +#define ADV7181_STATUS1_REG 0x10 +#define ADV7181_STATUS1_IN_LOCK 0x01 +#define ADV7181_STATUS1_AUTOD_MASK 0x70 +#define ADV7181_STATUS1_AUTOD_NTSM_M_J 0x00 +#define ADV7181_STATUS1_AUTOD_NTSC_4_43 0x10 +#define ADV7181_STATUS1_AUTOD_PAL_M 0x20 +#define ADV7181_STATUS1_AUTOD_PAL_60 0x30 +#define ADV7181_STATUS1_AUTOD_PAL_B_G 0x40 +#define ADV7181_STATUS1_AUTOD_SECAM 0x50 +#define ADV7181_STATUS1_AUTOD_PAL_COMB 0x60 +#define ADV7181_STATUS1_AUTOD_SECAM_525 0x70 + +#define ADV7181_INPUT_CONTROL 0x00 +#define ADV7181_INPUT_DEFAULT 0x00 +#define ADV7181_INPUT_CVBS_AIN2 0x00 +#define ADV7181_INPUT_CVBS_AIN3 0x01 +#define ADV7181_INPUT_CVBS_AIN5 0x02 +#define ADV7181_INPUT_CVBS_AIN6 0x03 +#define ADV7181_INPUT_CVBS_AIN8 0x04 +#define ADV7181_INPUT_CVBS_AIN10 0x05 +#define ADV7181_INPUT_CVBS_AIN1 0x0B +#define ADV7181_INPUT_CVBS_AIN4 0x0D +#define ADV7181_INPUT_CVBS_AIN7 0x0F +#define ADV7181_INPUT_YPRPB_AIN6_8_10 0x09 + +static int SENSOR_PREVIEW_W = 720; +static int SENSOR_PREVIEW_H = 480; + +static struct rk_camera_device_signal_config dev_info[] = { + { + .type = RK_CAMERA_DEVICE_CVBS_NTSC, + .code = MEDIA_BUS_FMT_UYVY8_2X8, + .crop = { + .top = 24, + .left = 0, + .width = 720, + .height = 480 + } + } +}; + +static struct rk_camera_device_defrect defrects[4]; +static struct rk_camera_device_channel_info channel_infos; +static int now_channel_value = ADV7181_INPUT_CVBS_AIN1; +static char input_mode[10] = "NTSC"; + +#define SENSOR_PREVIEW_FPS 30000 /* 30fps */ +#define SENSOR_FULLRES_L_FPS 15000 /* 15fps */ +#define SENSOR_FULLRES_H_FPS 15000 /* 15fps */ +#define SENSOR_720P_FPS 0 +#define SENSOR_1080P_FPS 0 + +#define SENSOR_REGISTER_LEN 1 /* sensor register address bytes */ +#define SENSOR_VALUE_LEN 1 /* sensor register value bytes */ + +static unsigned int SensorConfiguration = (CFG_Effect | CFG_Scene); +static unsigned int SensorChipID[] = {SENSOR_ID}; +/* Sensor Driver Configuration End */ + + +#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) +#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) + +#define SensorRegVal(a, b) CONS4(SensorReg, SENSOR_REGISTER_LEN, Val, SENSOR_VALUE_LEN)(a, b) +#define sensor_write(client, reg, v) CONS4(sensor_write_reg, SENSOR_REGISTER_LEN, val, SENSOR_VALUE_LEN)(client, (reg), (v)) +#define sensor_read(client, reg, v) CONS4(sensor_read_reg, SENSOR_REGISTER_LEN, val, SENSOR_VALUE_LEN)(client, (reg), (v)) +#define sensor_write_array generic_sensor_write_array +static void adv7181_reinit_parameter(v4l2_std_id std, + struct generic_sensor *sensor); +static void adv7181_send_uevent(struct generic_sensor *sensor); + +struct sensor_parameter { + unsigned int PreviewDummyPixels; + unsigned int CaptureDummyPixels; + unsigned int preview_exposure; + + unsigned short int preview_line_width; + unsigned short int preview_gain; + unsigned short int PreviewPclk; + unsigned short int CapturePclk; + char awb[6]; +}; + +struct specific_sensor { + struct generic_sensor common_sensor; + struct sensor_parameter parameter; +}; + +/* + * The follow setting need been filled. + * + * Must Filled: + * sensor_init_data : Sensor initial setting; + * sensor_fullres_lowfps_data : Sensor full resolution setting with best auality, recommand for video; + * sensor_preview_data : Sensor preview resolution setting, recommand it is vga or svga; + * sensor_softreset_data : Sensor software reset register; + * sensor_check_id_data : Sensir chip id register; + * + * Optional filled: + * sensor_fullres_highfps_data: Sensor full resolution setting with high framerate, recommand for video; + * sensor_720p: Sensor 720p setting, it is for video; + * sensor_1080p: Sensor 1080p setting, it is for video; + * + * :::::WARNING::::: + * The SensorEnd which is the setting end flag must be filled int the last of each setting; + */ + +/* Sensor initial setting */ +static struct rk_sensor_reg sensor_init_data[] = { +/* + {0x04, 0xC5}, + {0xE6, 0x4f}, + */ + SensorEnd +}; +/* Senor full resolution setting: recommand for capture */ +static struct rk_sensor_reg sensor_fullres_lowfps_data[] = { + SensorEnd +}; +/* Senor full resolution setting: recommand for video */ +static struct rk_sensor_reg sensor_fullres_highfps_data[] = { + SensorEnd +}; +/* Preview resolution setting*/ + +static struct rk_sensor_reg sensor_preview_data_yc[] = { + {0x04, 0x57},//Enable SFL + {0x1D, 0x47},//Enable 28MHz Crystal + {0x31, 0x02},//Clears NEWAV_MODE, 0xSAV/EAV to suit ADV video encoders + {0x3A, 0x13},//Set Latch Clock & turn off ADC2 & ADC3 + {0x3B, 0x81},//Enable Internal Bias + {0x3D, 0xA2},//MWE Enable Manual Window, 0xColour Kill Threshold to 2 + {0x3E, 0x6A},//BLM optimisation + {0x3F, 0xA0},//BGB + {0x86, 0x0B},//Enable stdi_line_count_mode + {0x69, 0x03},//Sets SDM_SEL to 03 for YC/CVBS Auto + {0xF3, 0x03},//Enable Anti Alias Filters on ADC0 & ADC1 + {0xF9, 0x03},//Set max v lock range + {0xC4, 0x80},//Enable maual input muxing + {0xC3, 0xED},//ADC1 to Ain9 (C) and ADC0 to Ain7 (Y) + {0x0E, 0x80},//ADI Recommended Setting + {0x52, 0x46},//ADI Recommended Setting + {0x54, 0x80},//ADI Recommended Setting + {0x7F, 0xFF},//ADI Recommended Setting + {0x81, 0x30},//ADI Recommended Setting + {0x90, 0xC9},//ADI Recommended Setting + {0x91, 0x40},//ADI Recommended Setting + {0x92, 0x3C},//ADI Recommended Setting + {0x93, 0xCA},//ADI Recommended Setting + {0x94, 0xD5},//ADI Recommended Setting + {0xB1, 0xFF},//ADI Recommended Setting + {0xB6, 0x08},//ADI Recommended Setting + {0xC0, 0x9A},//ADI Recommended Setting + {0xCF, 0x50},//ADI Recommended Setting + {0xD0, 0x4E},//ADI Recommended Setting + {0xD1, 0xB9},//ADI Recommended Setting + {0xD6, 0xDD},//ADI Recommended Setting + {0xD7, 0xE2},//ADI Recommended Setting + {0xE5, 0x51},//ADI Recommended Setting + {0xF6, 0x3B},//ADI Recommended Setting + {0x0E, 0x00},//ADI Recommended Setting + {0x03, 0x4C},//disable out put + SensorEnd +}; + +static struct rk_sensor_reg sensor_preview_data_cvbs[] = { + {0x04, 0x77}, + {0x17, 0x41}, + {0x1D, 0x47}, + {0x31, 0x02}, + {0x3A, 0x17}, + {0x3B, 0x81}, + {0x3D, 0xA2}, + {0x3E, 0x6A}, + {0x3F, 0xA0}, + {0x86, 0x0B}, + {0xF3, 0x01}, + {0xF9, 0x03}, + {0x0E, 0x80}, + {0x52, 0x46}, + {0x54, 0x80}, + {0x7F, 0xFF}, + {0x81, 0x30}, + {0x90, 0xC9}, + {0x91, 0x40}, + {0x92, 0x3C}, + {0x93, 0xCA}, + {0x94, 0xD5}, + {0xB1, 0xFF}, + {0xB6, 0x08}, + {0xC0, 0x9A}, + {0xCF, 0x50}, + {0xD0, 0x4E}, + {0xD1, 0xB9}, + {0xD6, 0xDD}, + {0xD7, 0xE2}, + {0xE5, 0x51}, + {0xF6, 0x3B}, + {0x0E, 0x00}, + {0x03, 0x4C}, //disable out put + SensorEnd +}; + +static struct rk_sensor_reg sensor_preview_data_yprpb_p[] = { +/* + {0x05, 0x01},//PRIM_MODE = 001b COMP + {0x06, 0x06},//VID_STD for 525P 2x1 + {0xC3, 0x56},//ADC1 to Ain8, ADC0 to Ain10, + {0xC4, 0xB4},//Enables manual override of mux & ADC2 to Ain6. + {0x1D, 0x47},//Enable 28.63636MHz crystal + {0x3A, 0x11},//Set Latch Clock 01b. Power down ADC3. + {0x3B, 0x81},//Enable Internal Bias + {0x3C, 0x3B},//PLL QPUMP to 011b + {0x6B, 0x83},//422 8bit out + {0xC9, 0x0C},//Enable 8-bit mode using psuedo DDR + {0x73, 0xCF},//Enable Manual Gain and set CH_A gain + {0x74, 0xA3},//Set CH_A and CH_B Gain - 0FAh + {0x75, 0xE8},//Set CH_B and CH_C Gain + {0x76, 0xFA},//Set CH_C Gain + {0x7B, 0x0E},//Turn on EAV and SAV Codes. + {0x85, 0x19},//Turn off SSPD and force SOY + {0x86, 0x0B},//Enable STDI Line Count Mode + {0xBF, 0x06},//Blue Screen Free Run Colour + {0xC0, 0x40},//default color + {0xC1, 0xF0},//default color + {0xC2, 0x80},//Default color + {0xC5, 0x01},// + {0x0E, 0x80},//ADI recommended sequence + {0x52, 0x46},//ADI recommended sequence + {0x54, 0x80},//ADI Recommended Setting + {0x57, 0x01},//ADI recommended sequence + {0xF6, 0x3B},//ADI Recommended Setting + {0x0E, 0x00},//ADI recommended sequence + {0x67, 0x33},//DPP Filters *** + */ + /*##CP 525p/625p## + *525p/60Hz YPrPb In 8Bit 422 HS/VS Encoder + */ + {0x05, 0x01}, + {0x06, 0x06}, + {0xc3, 0x56}, + {0xc4, 0xb4}, + {0x1d, 0x47}, + {0x3a, 0x11}, + {0x3b, 0x81}, + {0x3c, 0x3b}, + {0x6b, 0x83}, + {0xc9, 0x00}, + {0x73, 0x10}, + {0x74, 0xa3}, + {0x75, 0xe8}, + {0x76, 0xfa}, + {0x7b, 0x1c}, + {0x85, 0x19}, + {0x86, 0x0b}, + {0xbf, 0x06}, + {0xc0, 0x40}, + {0xc1, 0xf0}, + {0xc2, 0x80}, + {0xc5, 0x01}, + {0xc9, 0x08}, + {0x0e, 0x80}, + {0x52, 0x46}, + {0x54, 0x80}, + {0x57, 0x01}, + {0xf6, 0x3b}, + {0x0e, 0x00}, + {0x67, 0x2f}, + {0x03, 0x4C}, //disable out put + SensorEnd +}; + +static struct rk_sensor_reg sensor_preview_data_yprpb_i[] = { +/* ##SDP YPrPb## + * :AUTODETECT YPbPr In, 8 Bit 422 Encoder + */ + {0x8D, 0x83},//ADI Recommended + {0x1D, 0x47},//Enable 28MHz Crystal + {0x27, 0x98},//YC Delay, 0x Swap Cb and Cr + {0x31, 0x02},//Clears NEWAV_MODE, 0xSAV/EAV to suit ADV video encoders + {0x3A, 0x11},//set latch clock settings to 001b, 0xPower Down ADC3 + {0x3B, 0x81},//Enable internal Bias + {0x3D, 0xA2},//MWE Enable Manual Window + {0x3E, 0x6A},//BLM optimisation + {0x3F, 0xA0},//ADI Recommended + {0x86, 0x0B},//Enable stdi_line_count_mode + {0xB4, 0xF9},//ADI Recommended + {0xB5, 0x00},//ADI Recommended + {0xC3, 0x46},//ADC1 to Ain6 (Pr), 0xADC0 to Ain10 (Y), 0x + {0xC4, 0xB5},//ADC2 to Ain8 (Pb) and enables manual override of mux + {0xF3, 0x07},//Enable Anti Alias Filters on ADC 0,1,2 + {0xF9, 0x03},//Set max v lock range + {0x0E, 0x80},//ADI Recommended Setting + {0x52, 0x46},//ADI Recommended Setting + {0x54, 0x80},//ADI Recommended Setting + {0x7F, 0xFF},//ADI Recommended Setting + {0x81, 0x30},//ADI Recommended Setting + {0x90, 0xC9},//ADI Recommended Setting + {0x91, 0x40},//ADI Recommended Setting + {0x92, 0x3C},//ADI Recommended Setting + {0x93, 0xCA},//ADI Recommended Setting + {0x94, 0xD5},//ADI Recommended Setting + {0x7E, 0x73},//ADI Recommended Setting + {0xB1, 0xFF},//ADI Recommended Setting + {0xB6, 0x08},//ADI Recommended Setting + {0xC0, 0x9A},//ADI Recommended Setting + {0xCF, 0x50},//ADI Recommended Setting + {0xD0, 0x4E},//ADI Recommended Setting + {0xD1, 0xB9},//ADI Recommended Setting + {0xD6, 0xDD},//ADI Recommended Setting + {0xE5, 0x51},//ADI Recommended Setting + {0xF6, 0x3B},//ADI Recommended Setting + {0x0E, 0x00},//ADI Recommended Setting + {0x03, 0x4C},//8 Bit Mode; disable out put + SensorEnd +}; + +static struct rk_sensor_reg sensor_preview_data[] = { + /* autodetect cvbs in ntsc/pal/secam 8-bit 422 encode */ + {0x04, 0x77}, + {0x17, 0x41}, + {0x1D, 0x47}, + {0x31, 0x02}, + {0x3A, 0x17}, + {0x3B, 0x81}, + {0x3D, 0xA2}, + {0x3E, 0x6A}, + {0x3F, 0xA0}, + {0x86, 0x0B}, + {0xF3, 0x01}, + {0xF9, 0x03}, + {0x0E, 0x80}, + {0x52, 0x46}, + {0x54, 0x80}, + {0x7F, 0xFF}, + {0x81, 0x30}, + {0x90, 0xC9}, + {0x91, 0x40}, + {0x92, 0x3C}, + {0x93, 0xCA}, + {0x94, 0xD5}, + {0xB1, 0xFF}, + {0xB6, 0x08}, + {0xC0, 0x9A}, + {0xCF, 0x50}, + {0xD0, 0x4E}, + {0xD1, 0xB9}, + {0xD6, 0xDD}, + {0xD7, 0xE2}, + {0xE5, 0x51}, + {0xF6, 0x3B}, + {0x0E, 0x00}, + {0x03, 0x4C}, //disable out put + SensorEnd +}; + +/* 1280x720 */ +static struct rk_sensor_reg sensor_720p[] = { + SensorEnd +}; + +/* 1920x1080 */ +static struct rk_sensor_reg sensor_1080p[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_softreset_data[] = { + /*SensorRegVal(0x0f, 0x00 | 0x80),*/ + SensorEnd +}; + +static struct rk_sensor_reg sensor_check_id_data[] = { + SensorRegVal(0x11, 0x0), + SensorEnd +}; +/* + * The following setting must been filled, + * if the function is turn on by CONFIG_SENSOR_xxxx + */ +static struct rk_sensor_reg sensor_WhiteB_Auto[] = { + SensorEnd +}; +/* Cloudy Colour Temperature : 6500K - 8000K */ +static struct rk_sensor_reg sensor_WhiteB_Cloudy[] = { + SensorEnd +}; +/* ClearDay Colour Temperature : 5000K - 6500K */ +static struct rk_sensor_reg sensor_WhiteB_ClearDay[] = { + SensorEnd +}; +/* Office Colour Temperature : 3500K - 5000K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[] = { + SensorEnd +}; +/* Home Colour Temperature : 2500K - 3500K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[] = { + SensorEnd +}; +static struct rk_sensor_reg *sensor_WhiteBalanceSeqe[] = { + sensor_WhiteB_Auto, + sensor_WhiteB_TungstenLamp1, + sensor_WhiteB_TungstenLamp2, + sensor_WhiteB_ClearDay, + sensor_WhiteB_Cloudy, + NULL, +}; + +static struct rk_sensor_reg sensor_Brightness0[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness1[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness2[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness3[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness4[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness5[] = { + SensorEnd +}; + +static struct rk_sensor_reg *sensor_BrightnessSeqe[] = { + sensor_Brightness0, + sensor_Brightness1, + sensor_Brightness2, + sensor_Brightness3, + sensor_Brightness4, + sensor_Brightness5, + NULL, +}; + +static struct rk_sensor_reg sensor_Effect_Normal[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_WandB[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Sepia[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Negative[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Bluish[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Green[] = { + SensorEnd +}; + +static struct rk_sensor_reg *sensor_EffectSeqe[] = { + sensor_Effect_Normal, + sensor_Effect_WandB, + sensor_Effect_Negative, + sensor_Effect_Sepia, + sensor_Effect_Bluish, + sensor_Effect_Green, + NULL, +}; + +static struct rk_sensor_reg sensor_Exposure0[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure1[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure2[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure3[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure4[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure5[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure6[] = { + SensorEnd +}; + +static struct rk_sensor_reg *sensor_ExposureSeqe[] = { + sensor_Exposure0, + sensor_Exposure1, + sensor_Exposure2, + sensor_Exposure3, + sensor_Exposure4, + sensor_Exposure5, + sensor_Exposure6, + NULL, +}; + +static struct rk_sensor_reg sensor_Saturation0[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Saturation1[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Saturation2[] = { + SensorEnd +}; +static struct rk_sensor_reg *sensor_SaturationSeqe[] = { + sensor_Saturation0, + sensor_Saturation1, + sensor_Saturation2, + NULL, +}; + +static struct rk_sensor_reg sensor_Contrast0[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast1[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast2[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast3[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast4[] = { + SensorEnd +}; + + +static struct rk_sensor_reg sensor_Contrast5[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast6[] = { + SensorEnd +}; +static struct rk_sensor_reg *sensor_ContrastSeqe[] = { + sensor_Contrast0, + sensor_Contrast1, + sensor_Contrast2, + sensor_Contrast3, + sensor_Contrast4, + sensor_Contrast5, + sensor_Contrast6, + NULL, +}; + +static struct rk_sensor_reg sensor_SceneAuto[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_SceneNight[] = { + SensorEnd +}; +static struct rk_sensor_reg *sensor_SceneSeqe[] = { + sensor_SceneAuto, + sensor_SceneNight, + NULL, +}; + +static struct rk_sensor_reg sensor_Zoom0[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Zoom1[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Zoom2[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Zoom3[] = { + SensorEnd +}; + +static struct rk_sensor_reg *sensor_ZoomSeqe[] = { + sensor_Zoom0, + sensor_Zoom1, + sensor_Zoom2, + sensor_Zoom3, + NULL, +}; + +/* + * User could be add v4l2_querymenu in sensor_controls by new_usr_v4l2menu + */ +static struct v4l2_querymenu sensor_menus[] = { +}; + +/* + * User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl + */ + +static inline int adv7181_channel_set(struct i2c_client *client, + struct sensor_v4l2ctrl_info_s *ctrl_info, + struct v4l2_ext_control *ext_ctrl) +{ + struct generic_sensor *sensor = to_generic_sensor(client); + struct rk_sensor_sequence *sensor_series = + sensor->info_priv.sensor_series; + int series_num = sensor->info_priv.num_series; + int ret = 0; + int i; + int id; + int channel_ain; + + if ((ext_ctrl->value < ctrl_info->qctrl->minimum) || + (ext_ctrl->value > ctrl_info->qctrl->maximum)) { + SENSOR_TR("%s(%d):channel(%d) is not support\n", + __func__, __LINE__, ext_ctrl->value); + ret = -EINVAL; + goto end; + } + if (sensor->channel_id != ext_ctrl->value) { + SENSOR_TR("%s(%d):set channel(%d)!\n", + __func__, __LINE__, ext_ctrl->value); + sensor->channel_id = ext_ctrl->value; + id = sensor->channel_id; + for (i = 0; i < series_num; i++) + if ((sensor_series[i].property == SEQUENCE_PREVIEW) && + (sensor_series[i].data[0].reg != SEQCMD_END)) + break; + if (strstr(channel_infos.channel_info[id], "cvbs")) { + ret = sscanf(channel_infos.channel_info[id], "%*s %d", + &channel_ain); + if (IS_ERR_VALUE(ret)) { + SENSOR_TR("%s(%d): channel_infos err!\n", + __func__, __LINE__); + ret = -EINVAL; + goto end; + } + switch (channel_ain) { + case 1: + now_channel_value = ADV7181_INPUT_CVBS_AIN1; + break; + case 2: + now_channel_value = ADV7181_INPUT_CVBS_AIN2; + break; + case 3: + now_channel_value = ADV7181_INPUT_CVBS_AIN3; + break; + case 4: + now_channel_value = ADV7181_INPUT_CVBS_AIN4; + break; + case 5: + now_channel_value = ADV7181_INPUT_CVBS_AIN5; + break; + case 6: + now_channel_value = ADV7181_INPUT_CVBS_AIN6; + break; + case 7: + now_channel_value = ADV7181_INPUT_CVBS_AIN7; + break; + case 8: + now_channel_value = ADV7181_INPUT_CVBS_AIN8; + break; + case 10: + now_channel_value = ADV7181_INPUT_CVBS_AIN10; + break; + } + sensor_series[i].data = sensor_preview_data_cvbs; + sensor->info_priv.dev_sig_cnf.type = + RK_CAMERA_DEVICE_CVBS_NTSC; + sensor->info_priv.dev_sig_cnf.code = + MEDIA_BUS_FMT_UYVY8_2X8; + adv7181_reinit_parameter(V4L2_STD_NTSC, sensor); + } else if (strstr(channel_infos.channel_info[id], "yprpb")) { + now_channel_value = ADV7181_INPUT_DEFAULT; + sensor_series[i].data = sensor_preview_data_yprpb_p; + sensor->info_priv.dev_sig_cnf.type = + RK_CAMERA_DEVICE_BT601_PIONGPONG; + sensor->info_priv.dev_sig_cnf.code = + MEDIA_BUS_FMT_YVYU8_2X8; + adv7181_reinit_parameter(V4L2_STD_525_60, sensor); + } else if (strstr(channel_infos.channel_info[id], "ycrpc")) { + now_channel_value = ADV7181_INPUT_YPRPB_AIN6_8_10; + sensor_series[i].data = sensor_preview_data_yprpb_i; + sensor->info_priv.dev_sig_cnf.type = + RK_CAMERA_DEVICE_CVBS_NTSC; + sensor->info_priv.dev_sig_cnf.code = + MEDIA_BUS_FMT_UYVY8_2X8; + } else if (strstr(channel_infos.channel_info[id], "yc")) { + SENSOR_TR("%s(%d): yc signal not support\n", + __func__, __LINE__); + ret = -EINVAL; + goto end; + now_channel_value = ADV7181_INPUT_DEFAULT; + sensor_series[i].data = sensor_preview_data_yc; + } + + sensor_write(client, ADV7181_INPUT_CONTROL, now_channel_value); + generic_sensor_write_array(client, sensor_series[i].data); + } + +end: + return ret; +} + +static inline int sensor_v4l2ctrl_inside_cb(struct soc_camera_device *icd, + struct sensor_v4l2ctrl_info_s *ctrl_info, + struct v4l2_ext_control *ext_ctrl, + bool is_set) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct generic_sensor *sensor = to_generic_sensor(client); + int ret = 0; + + switch (ctrl_info->qctrl->id) { + case V4L2_CID_DEINTERLACE: + { + if (is_set) { + SENSOR_TR("deinterlace isn't support set!\n"); + ret = -EINVAL; + goto cb_end; + } else { + if ((RK_CAMERA_DEVICE_BT601_8 == + sensor->info_priv.dev_sig_cnf.type) || + (RK_CAMERA_DEVICE_BT601_PIONGPONG == + sensor->info_priv.dev_sig_cnf.type)) { + /* don't need deinterlace process */ + ext_ctrl->value = 0; + ctrl_info->cur_value = 0; + } else { + ext_ctrl->value = 1; + ctrl_info->cur_value = 1; + } + } + break; + } + case V4L2_CID_CHANNEL: + { + if (is_set) { + ret = adv7181_channel_set(client, ctrl_info, ext_ctrl); + if (ret) + goto cb_end; + } else { + ext_ctrl->value = sensor->channel_id; + ctrl_info->cur_value = sensor->channel_id; + } + break; + } + case V4L2_CID_VIDEO_STATE: + { + if (is_set) { + SENSOR_TR("%s(%d): set isn't support!\n", + __func__, __LINE__); + } else { + ext_ctrl->value = sensor->info_priv.video_state; + ctrl_info->cur_value = sensor->info_priv.video_state; + } + break; + } + default: + { + SENSOR_TR("%s(%d): cmd(0x%x) is unknown !", + __func__, __LINE__, ctrl_info->qctrl->id); + ret = -EINVAL; + } + } + +cb_end: + return ret; +} + +static struct sensor_v4l2ctrl_usr_s sensor_controls[] = { + { + { + V4L2_CID_DEINTERLACE, + V4L2_CTRL_TYPE_BOOLEAN, + "deinterlace", + 0, + 1, + 1, + 0 + }, + sensor_v4l2ctrl_inside_cb, + NULL + }, + { + { + V4L2_CID_CHANNEL, + V4L2_CTRL_TYPE_INTEGER, + "channel", + 0, + 4, + 1, + 0 + }, + sensor_v4l2ctrl_inside_cb, + NULL + }, + { + { + V4L2_CID_VIDEO_STATE, + V4L2_CTRL_TYPE_BOOLEAN, + "video_state", + 0, + 1, + 1, + 0 + }, + sensor_v4l2ctrl_inside_cb, + NULL + } +}; + +/* + * MUST define the current used format as the first item + */ +static struct rk_sensor_datafmt sensor_colour_fmts[] = { + {MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, +}; + +/* + ********************************************************** + * Following is local code: + * + * Please codeing your program here + ********************************************************** + */ +static int sensor_parameter_record(struct i2c_client *client) +{ + return 0; +} + +static int sensor_ae_transfer(struct i2c_client *client) +{ + return 0; +} +/* + ********************************************************** + * Following is callback + * If necessary, you could coding these callback + ********************************************************** + */ +static void adv7181_reinit_parameter(v4l2_std_id std, + struct generic_sensor *sensor) +{ + struct rk_sensor_sequence *series = sensor->info_priv.sensor_series; + int num_series = sensor->info_priv.num_series; + int i; + + if (std == V4L2_STD_NTSC || std == V4L2_STD_NTSC_443) { + SENSOR_PREVIEW_W = 720; + SENSOR_PREVIEW_H = 480; + strcpy(input_mode, "NTSC"); + } else if (std == V4L2_STD_PAL || std == V4L2_STD_PAL_60 || + std == V4L2_STD_PAL_M) { + SENSOR_PREVIEW_W = 720; + SENSOR_PREVIEW_H = 576; + strcpy(input_mode, "PAL"); + } else { + SENSOR_PREVIEW_W = 1024; + SENSOR_PREVIEW_H = 500; + strcpy(input_mode, "YUV"); + } + for (i = 0; i < 4; i++) { + if ((defrects[i].width == SENSOR_PREVIEW_W) && + (defrects[i].height == SENSOR_PREVIEW_H)) { + SENSOR_PREVIEW_W = defrects[i].defrect.width; + SENSOR_PREVIEW_H = defrects[i].defrect.height; + memcpy(&sensor->info_priv.dev_sig_cnf.crop, + &defrects[i].defrect, + sizeof(defrects[i].defrect)); + + if (!defrects[i].interface) { + SENSOR_TR("%s(%d): interface is NULL\n", + __func__, __LINE__); + continue; + } + + SENSOR_TR("%s(%d): type 0x%x\n", __func__, __LINE__, + sensor->info_priv.dev_sig_cnf.type); + } + } + /*update sensor info_priv*/ + for (i = 0; i < num_series; i++) { + series[i].gSeq_info.w = SENSOR_PREVIEW_W; + series[i].gSeq_info.h = SENSOR_PREVIEW_H; + } + generic_sensor_get_max_min_res(sensor->info_priv.sensor_series, + sensor->info_priv.num_series, + &(sensor->info_priv.max_real_res), + &(sensor->info_priv.max_res), + &(sensor->info_priv.min_res)); +} + +static void adv7181_send_uevent(struct generic_sensor *sensor) +{ + char *event_msg = NULL; + char *envp[2]; + + event_msg = kasprintf(GFP_KERNEL, + "CVBS_NAME=ADV7181, NOW_INPUT_MODE=%s, RESOLUTION=%dx%d", + input_mode, SENSOR_PREVIEW_W, SENSOR_PREVIEW_H); + SENSOR_TR("%s(%d): event_msg: %s\n", __func__, __LINE__, event_msg); + envp[0] = event_msg; + envp[1] = NULL; + kobject_uevent_env(&(sensor->subdev.v4l2_dev->dev->kobj), + KOBJ_CHANGE, envp); +} + +static v4l2_std_id adv7181_std_to_v4l2(u8 status1) +{ + /* in case V4L2_IN_ST_NO_SIGNAL */ + if (!(status1 & ADV7181_STATUS1_IN_LOCK)) + return V4L2_STD_UNKNOWN; + + switch (status1 & ADV7181_STATUS1_AUTOD_MASK) { + case ADV7181_STATUS1_AUTOD_NTSM_M_J: + return V4L2_STD_NTSC; + case ADV7181_STATUS1_AUTOD_NTSC_4_43: + return V4L2_STD_NTSC_443; + case ADV7181_STATUS1_AUTOD_PAL_M: + return V4L2_STD_PAL_M; + case ADV7181_STATUS1_AUTOD_PAL_60: + return V4L2_STD_PAL_60; + case ADV7181_STATUS1_AUTOD_PAL_B_G: + return V4L2_STD_PAL; + case ADV7181_STATUS1_AUTOD_SECAM: + return V4L2_STD_SECAM; + case ADV7181_STATUS1_AUTOD_PAL_COMB: + return V4L2_STD_PAL_Nc | V4L2_STD_PAL_N; + case ADV7181_STATUS1_AUTOD_SECAM_525: + return V4L2_STD_SECAM; + default: + return V4L2_STD_UNKNOWN; + } +} + +static u32 adv7181_status_to_v4l2(u8 status1) +{ + if (!(status1 & ADV7181_STATUS1_IN_LOCK)) + return V4L2_IN_ST_NO_SIGNAL; + + return 0; +} + +static int adv7181_uevent_video_state(struct i2c_client *client, int state) +{ + struct generic_sensor *sensor = to_generic_sensor(client); + char *event_msg = NULL; + char *envp[2]; + + return 0; + event_msg = kasprintf(GFP_KERNEL, "CVBS_NAME=ADV7181, VIDEO_STATUS=%d", state); + SENSOR_TR("%s(%d): event_msg: %s\n", __func__, __LINE__, event_msg); + envp[0] = event_msg; + envp[1] = NULL; + kobject_uevent_env(&(sensor->subdev.v4l2_dev->dev->kobj), KOBJ_CHANGE, envp); + + return 0; +} + +static int adv7181_status(struct i2c_client *client, u32 *status, + v4l2_std_id *std) +{ + unsigned char status1 = 0; + int ret = 0; + struct generic_sensor *sensor = to_generic_sensor(client); + + ret = sensor_read(client, ADV7181_STATUS1_REG, &status1); + + if (IS_ERR_VALUE(ret)) { + SENSOR_TR("%s(%d): register read failed: 0x%x\n", + __func__, __LINE__, ADV7181_STATUS1_REG); + return status1; + } + SENSOR_DG("%s(%d): ADV7181_STATUS1_REG read : 0x%x\n", + __func__, __LINE__, status1); + + if (status1 < 0) + return status1; + + if (adv7181_status_to_v4l2(status1) == V4L2_IN_ST_NO_SIGNAL) { + sensor->info_priv.video_state = RK_CAM_INPUT_VIDEO_STATE_LOSS; + adv7181_uevent_video_state(client, 0); + } else { + if (sensor->info_priv.video_state == RK_CAM_INPUT_VIDEO_STATE_LOSS) { + sensor->info_priv.video_state = RK_CAM_INPUT_VIDEO_STATE_LOCKED; + adv7181_uevent_video_state(client, 1); + } + } + + if (status) + *status = adv7181_status_to_v4l2(status1); + if (std) + *std = adv7181_std_to_v4l2(status1); + + return 0; +} + +/* + * the function is called in open sensor + */ +static int sensor_activate_cb(struct i2c_client *client) +{ + struct generic_sensor *sensor = to_generic_sensor(client); +/* u32 status = V4L2_IN_ST_NO_SIGNAL; + v4l2_std_id std; + + while (status == V4L2_IN_ST_NO_SIGNAL) { + msleep(20); + adv7181_status(client, &status, NULL); + } + SENSOR_TR("status %d\n", (int)status); + adv7181_status(client, NULL, &std); + adv7181_reinit_parameter(std, sensor); + SENSOR_TR("%s(%d):now mode %s\n", __func__, __LINE__, input_mode); + */ + SENSOR_DG("%s: %d\n", __func__, __LINE__); + sensor_write(client, ADV7181_INPUT_CONTROL, now_channel_value); + + sensor->info_priv.video_state = RK_CAM_INPUT_VIDEO_STATE_LOCKED; + if (sensor->state_check_work.state_check_wq) { + SENSOR_DG("sensor_activate_cb: queue_delayed_work 1000ms"); + queue_delayed_work(sensor->state_check_work.state_check_wq, + &sensor->state_check_work.work, 100); + } + + return 0; +} +/* + * the function is called in close sensor + */ +static int sensor_deactivate_cb(struct i2c_client *client) +{ + int ret = 0; + struct generic_sensor *sensor = to_generic_sensor(client); + + ret = cancel_delayed_work_sync(&sensor->state_check_work.work); + return ret; +} + +static int sensor_s_stream(struct v4l2_subdev *sd, int enable) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + + SENSOR_DG("stream %d\n", enable); + if (enable) + sensor_write(client, 0x03, 0x0C); + else + sensor_write(client, 0x03, 0x4C); + return 0; +} + +/* + * the function is called before sensor register setting in VIDIOC_S_FMT +*/ +static int sensor_s_fmt_cb_th(struct i2c_client *client, + struct v4l2_mbus_framefmt *mf, + bool capture) +{ + if (capture) + sensor_parameter_record(client); + + return 0; +} +/* + * the function is called after sensor register setting finished in VIDIOC_S_FMT + */ +static int sensor_s_fmt_cb_bh(struct i2c_client *client, + struct v4l2_mbus_framefmt *mf, + bool capture) +{ + if (capture) + sensor_ae_transfer(client); + + return 0; +} +static int sensor_try_fmt_cb_th(struct i2c_client *client, + struct v4l2_mbus_framefmt *mf) +{ + return 0; +} + +static int sensor_softrest_usr_cb(struct i2c_client *client, + struct rk_sensor_reg *series) +{ + return 0; +} +static int sensor_check_id_usr_cb(struct i2c_client *client, + struct rk_sensor_reg *series) +{ + return 0; +} + +static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg) +{ + return 0; +} + +static int sensor_resume(struct soc_camera_device *icd) +{ + SENSOR_DG("Resume"); + + return 0; +} +static int sensor_mirror_cb(struct i2c_client *client, int mirror) +{ + return 0; +} +/* + * the function is v4l2 control V4L2_CID_HFLIP callback + */ +static int sensor_v4l2ctrl_mirror_cb(struct soc_camera_device *icd, + struct sensor_v4l2ctrl_info_s *ctrl_info, + struct v4l2_ext_control *ext_ctrl) +{ + SENSOR_DG("sensor_mirror success, value:0x%x", ext_ctrl->value); + return 0; +} + +static int sensor_flip_cb(struct i2c_client *client, int flip) +{ + return 0; +} +/* + * the function is v4l2 control V4L2_CID_VFLIP callback + */ +static int sensor_v4l2ctrl_flip_cb(struct soc_camera_device *icd, + struct sensor_v4l2ctrl_info_s *ctrl_info, + struct v4l2_ext_control *ext_ctrl) +{ + SENSOR_DG("sensor_flip success, value:0x%x", ext_ctrl->value); + return 0; +} +/* + * the functions are focus callbacks + */ +static int sensor_focus_init_usr_cb(struct i2c_client *client) +{ + return 0; +} + +static int sensor_focus_af_single_usr_cb(struct i2c_client *client) +{ + return 0; +} + +static int sensor_focus_af_near_usr_cb(struct i2c_client *client) +{ + return 0; +} + +static int sensor_focus_af_far_usr_cb(struct i2c_client *client) +{ + return 0; +} + +static int sensor_focus_af_specialpos_usr_cb(struct i2c_client *client, int pos) +{ + return 0; +} + +static int sensor_focus_af_const_usr_cb(struct i2c_client *client) +{ + return 0; +} +static int sensor_focus_af_const_pause_usr_cb(struct i2c_client *client) +{ + return 0; +} +static int sensor_focus_af_close_usr_cb(struct i2c_client *client) +{ + return 0; +} + +static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client, + int *zone_tm_pos) +{ + return 0; +} + +/* + *face defect call back + */ +static int sensor_face_detect_usr_cb(struct i2c_client *client, int on) +{ + return 0; +} + +/* config debug fs ops */ +#define DEBUG_FS_NTSC_WIDTH 0x8000 +#define DEBUG_FS_NTSC_HEIGHT 0x8001 +#define DEBUG_FS_NTSC_LEFT 0x8002 +#define DEBUG_FS_NTSC_TOP 0x8003 + +#define DEBUG_FS_PAL_WIDTH 0x8004 +#define DEBUG_FS_PAL_HEIGHT 0x8005 +#define DEBUG_FS_PAL_LEFT 0x8006 +#define DEBUG_FS_PAL_TOP 0x8007 + +static ssize_t adv7181_debugfs_reg_write(struct file *file, + const char __user *buf, + size_t count, loff_t *ppos) +{ + struct specific_sensor *spsensor = + ((struct seq_file *)file->private_data)->private; + struct i2c_client *client = spsensor->common_sensor.client; + int reg, val, ret; + unsigned char read; + char kbuf[30]; + int nbytes = min(count, sizeof(kbuf) - 1); + int i = 0; + + if (copy_from_user(kbuf, buf, nbytes)) + return -EFAULT; + + kbuf[nbytes] = '\0'; + if (sscanf(kbuf, " %x %x", ®, &val) != 2) + return -EINVAL; + + SENSOR_TR("%s(%d): register write reg: 0x%x, val 0x%x\n", + __func__, __LINE__, reg, val); + + switch (reg) { + case DEBUG_FS_NTSC_WIDTH: + { + for (i = 0; i < 4; i++) + if (defrects[i].height == 480) + defrects[i].defrect.width = val; + break; + } + case DEBUG_FS_NTSC_HEIGHT: + { + for (i = 0; i < 4; i++) + if (defrects[i].height == 480) + defrects[i].defrect.height = val; + break; + } + case DEBUG_FS_NTSC_TOP: + { + for (i = 0; i < 4; i++) + if (defrects[i].height == 480) + defrects[i].defrect.top = val; + break; + } + case DEBUG_FS_NTSC_LEFT: + { + for (i = 0; i < 4; i++) + if (defrects[i].height == 480) + defrects[i].defrect.left = val; + break; + } + case DEBUG_FS_PAL_WIDTH: + { + for (i = 0; i < 4; i++) + if (defrects[i].height == 576) + defrects[i].defrect.width = val; + break; + } + case DEBUG_FS_PAL_HEIGHT: + { + for (i = 0; i < 4; i++) + if (defrects[i].height == 576) + defrects[i].defrect.height = val; + break; + } + case DEBUG_FS_PAL_LEFT: + { + for (i = 0; i < 4; i++) + if (defrects[i].height == 576) + defrects[i].defrect.left = val; + break; + } + case DEBUG_FS_PAL_TOP: + { + for (i = 0; i < 4; i++) + if (defrects[i].height == 576) + defrects[i].defrect.top = val; + break; + } + default: + { + ret = sensor_write(client, reg, val); + if (IS_ERR_VALUE(ret)) { + SENSOR_TR("d_fs: write fail: 0x%x, val 0x%x\n", + reg, val); + } + + ret = sensor_read(client, reg, &read); + if (IS_ERR_VALUE(ret)) { + SENSOR_TR("d_fs: write fail: 0x%x, val 0x%x\n", + reg, read); + } else + SENSOR_TR("d_fs: read 0x%x return 0x%x\n", + reg, val); + break; + } + } + + return count; +} + +static int adv7181_debugfs_reg_show(struct seq_file *s, void *v) +{ + int i, ret; + unsigned char val; + struct specific_sensor *spsensor = s->private; + struct i2c_client *client = spsensor->common_sensor.client; + + SENSOR_TR("%s(%d): test\n", __func__, __LINE__); + + for (i = 0; i <= 0xff; i++) { + ret = sensor_read(client, i, &val); + if (IS_ERR_VALUE(ret)) + SENSOR_TR("%s(%d): register read failed: 0x%x\n", + __func__, __LINE__, i); + + seq_printf(s, "0x%02x : 0x%02x\n", i, (u8)val); + } + + return 0; +} + +static int adv7181_debugfs_open(struct inode *inode, struct file *file) +{ + struct specific_sensor *spsensor = inode->i_private; + + return single_open(file, adv7181_debugfs_reg_show, spsensor); +} + +static const struct file_operations adv7181_debugfs_fops = { + .owner = THIS_MODULE, + .open = adv7181_debugfs_open, + .read = seq_read, + .write = adv7181_debugfs_reg_write, + .llseek = seq_lseek, + .release = single_release +}; + +static void adv7181_check_state_work(struct work_struct *work) +{ + struct rk_state_check_work *state_check_work = + container_of(work, struct rk_state_check_work, work.work); + struct generic_sensor *sensor = + container_of(state_check_work, + struct generic_sensor, + state_check_work); + struct i2c_client *client = sensor->client; + static v4l2_std_id std_old = V4L2_STD_NTSC; + v4l2_std_id std; + + if ((sensor->info_priv.dev_sig_cnf.type == + RK_CAMERA_DEVICE_BT601_8) || + (sensor->info_priv.dev_sig_cnf.type == + RK_CAMERA_DEVICE_BT601_PIONGPONG)) + return; + + adv7181_status(client, NULL, &std); + if ((std_old != std) && (std != V4L2_STD_UNKNOWN)) { + adv7181_reinit_parameter(std, sensor); + adv7181_send_uevent(sensor); + std_old = std; + SENSOR_TR("%s(%d):now mode %s\n", + __func__, __LINE__, input_mode); + } + + queue_delayed_work(sensor->state_check_work.state_check_wq, + &sensor->state_check_work.work, 100); +} + +/* + * The function can been run in sensor_init_parametres which run in + * sensor_probe, so user can do some initialization in the function. + */ +static void sensor_init_parameters_user(struct specific_sensor *spsensor, + struct soc_camera_device *icd) +{ + struct soc_camera_desc *desc = to_soc_camera_desc(icd); + struct rk29camera_platform_data *pdata = desc->subdev_desc.drv_priv; + struct rkcamera_platform_data *sensor_device = NULL, *new_camera; + struct dentry *debugfs_dir = + spsensor->common_sensor.info_priv.debugfs_dir; + int i; + + new_camera = pdata->register_dev_new; + while (new_camera != NULL) { + SENSOR_TR("%s(%d): icd_name %s, new_camera_name %s.\n", + __func__, __LINE__, + dev_name(icd->pdev), new_camera->dev_name); + if (strcmp(dev_name(icd->pdev), new_camera->dev_name) == 0) { + sensor_device = new_camera; + break; + } + new_camera = new_camera->next_camera; + } + if (!sensor_device) { + SENSOR_TR("%s(%d): Could not find %s\n", __func__, __LINE__, + dev_name(icd->pdev)); + return; + } + memcpy(&defrects, &sensor_device->defrects, + sizeof(sensor_device->defrects)); + for (i = 0; i < 4; i++) { + if ((defrects[i].width == SENSOR_PREVIEW_W) && + (defrects[i].height == SENSOR_PREVIEW_H)) { + memcpy(&dev_info[0].crop, &defrects[i].defrect, + sizeof(dev_info[0].crop)); + if (!strcmp(defrects[i].interface, "bt601_8")) + dev_info[i].type = RK_CAMERA_DEVICE_BT601_8; + if (!strcmp(defrects[i].interface, "cvbs_ntsc")) + dev_info[i].type = RK_CAMERA_DEVICE_CVBS_NTSC; + if (!strcmp(defrects[i].interface, "cvbs_pal")) + dev_info[i].type = RK_CAMERA_DEVICE_CVBS_PAL; + } + } + + SENSOR_TR("%s(%d): channel %d, default %d\n", __func__, __LINE__, + sensor_device->channel_info.channel_total, + sensor_device->channel_info.default_id); + spsensor->common_sensor.channel_id = + sensor_device->channel_info.default_id; + memcpy(&channel_infos, &sensor_device->channel_info, + sizeof(channel_infos)); + for (i = 0; i < 5; i++) { + SENSOR_TR("%s(%d): channel_ain%d %s\n", __func__, __LINE__, i, + channel_infos.channel_info[i]); + } + + /* init irq interrupt */ + /*SENSOR_TR("%s(%d): irq_active %d.\n", + __func__, __LINE__, new_camera->io.gpio_irq); + if (gpio_request(new_camera->io.gpio_irq, NULL) != 0) { + gpio_free(new_camera->io.gpio_irq); + SENSOR_TR("%s(%d): request irq gpio error\n", + __func__, __LINE__); + } + + spsensor->common_sensor.irq = gpio_to_irq(new_camera->io.gpio_irq); + ret = request_irq(spsensor->common_sensor.irq, ADV7181_irq, + IRQF_TRIGGER_FALLING, dev_name(icd->pdev), spsensor); + + if (ret < 0) { + SENSOR_TR("%s(%d): request irq failed\n", __func__, __LINE__); + free_irq(spsensor->common_sensor.irq, spsensor); + } + */ + + /* init debugfs */ + debugfs_dir = debugfs_create_dir("adv7181", NULL); + if (IS_ERR(debugfs_dir)) + SENSOR_TR("%s(%d): create debugfs dir failed\n", + __func__, __LINE__); + else + debugfs_create_file("register", S_IRUSR, debugfs_dir, spsensor, + &adv7181_debugfs_fops); + + /* init work_queue for state_check */ + INIT_DELAYED_WORK(&spsensor->common_sensor.state_check_work.work, + adv7181_check_state_work); + spsensor->common_sensor.state_check_work.state_check_wq = + create_singlethread_workqueue(SENSOR_NAME_STRING(_state_check_workqueue)); + if (spsensor->common_sensor.state_check_work.state_check_wq == NULL) { + SENSOR_TR("%s(%d): %s create failed.\n", __func__, __LINE__, + SENSOR_NAME_STRING(_state_check_workqueue)); + BUG(); + } + + memcpy(&spsensor->common_sensor.info_priv.dev_sig_cnf, + &dev_info[0], sizeof(dev_info)); + spsensor->common_sensor.crop_percent = 0; + spsensor->common_sensor.sensor_cb.sensor_s_stream_cb = sensor_s_stream; +} + +/* + * :::::WARNING::::: + * It is not allowed to modify the following code + */ + +sensor_init_parameters_default_code(); + +sensor_v4l2_struct_initialization(); + +sensor_probe_default_code(); + +sensor_remove_default_code(); + +sensor_driver_default_module_code(); + diff --git a/drivers/media/video/gc0307.c b/drivers/media/video/gc0307.c old mode 100755 new mode 100644 index 8e024f00583b..add574a029df --- a/drivers/media/video/gc0307.c +++ b/drivers/media/video/gc0307.c @@ -1,3 +1,16 @@ +/* + * drivers/media/video/gc0307.c + * + * Copyright (C) ROCKCHIP, Inc. + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ #include "generic_sensor.h" @@ -1022,7 +1035,7 @@ static struct sensor_v4l2ctrl_usr_s sensor_controls[] = //MUST define the current used format as the first item static struct rk_sensor_datafmt sensor_colour_fmts[] = { - {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} + {MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} }; /*static struct soc_camera_ops sensor_ops;*/ diff --git a/drivers/media/video/gc0308.c b/drivers/media/video/gc0308.c old mode 100755 new mode 100644 index 93d78ec88e51..339bc3d042b6 --- a/drivers/media/video/gc0308.c +++ b/drivers/media/video/gc0308.c @@ -1,3 +1,16 @@ +/* + * drivers/media/video/gc0308.c + * + * Copyright (C) ROCKCHIP, Inc. + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ #include "generic_sensor.h" /* @@ -910,7 +923,7 @@ static struct sensor_v4l2ctrl_usr_s sensor_controls[] = //MUST define the current used format as the first item static struct rk_sensor_datafmt sensor_colour_fmts[] = { - {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} + {MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} }; /*static struct soc_camera_ops sensor_ops;*/ diff --git a/drivers/media/video/gc0309.c b/drivers/media/video/gc0309.c old mode 100755 new mode 100644 index 7204463605d8..2bf995317d3c --- a/drivers/media/video/gc0309.c +++ b/drivers/media/video/gc0309.c @@ -1,3 +1,16 @@ +/* + * drivers/media/video/gc0309.c + * + * Copyright (C) ROCKCHIP, Inc. + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ #include "generic_sensor.h" @@ -860,7 +873,7 @@ static struct sensor_v4l2ctrl_usr_s sensor_controls[] = //MUST define the current used format as the first item static struct rk_sensor_datafmt sensor_colour_fmts[] = { - {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} + {MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} }; /*static struct soc_camera_ops sensor_ops;*/ diff --git a/drivers/media/video/gc0328.c b/drivers/media/video/gc0328.c old mode 100755 new mode 100644 index 55fca1c41507..d89c97bf9fef --- a/drivers/media/video/gc0328.c +++ b/drivers/media/video/gc0328.c @@ -1,3 +1,16 @@ +/* + * drivers/media/video/gc0328.c + * + * Copyright (C) ROCKCHIP, Inc. + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ #include "generic_sensor.h" @@ -769,7 +782,7 @@ static struct sensor_v4l2ctrl_usr_s sensor_controls[] = //MUST define the current used format as the first item static struct rk_sensor_datafmt sensor_colour_fmts[] = { - {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} + {MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} }; /*static struct soc_camera_ops sensor_ops;*/ diff --git a/drivers/media/video/gc0329.c b/drivers/media/video/gc0329.c old mode 100755 new mode 100644 index df393d1cae1c..fc557e0c9446 --- a/drivers/media/video/gc0329.c +++ b/drivers/media/video/gc0329.c @@ -1,3 +1,16 @@ +/* + * drivers/media/video/gc0329.c + * + * Copyright (C) ROCKCHIP, Inc. + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ #include "generic_sensor.h" @@ -844,7 +857,7 @@ static struct sensor_v4l2ctrl_usr_s sensor_controls[] = //MUST define the current used format as the first item static struct rk_sensor_datafmt sensor_colour_fmts[] = { - {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} + {MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} }; //static struct soc_camera_ops sensor_ops; diff --git a/drivers/media/video/gc2015.c b/drivers/media/video/gc2015.c old mode 100755 new mode 100644 index db58e05e323d..503a67efd6d9 --- a/drivers/media/video/gc2015.c +++ b/drivers/media/video/gc2015.c @@ -1,3 +1,16 @@ +/* + * drivers/media/video/gc2015.c + * + * Copyright (C) ROCKCHIP, Inc. + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ #include "generic_sensor.h" /* @@ -833,7 +846,7 @@ static struct sensor_v4l2ctrl_usr_s sensor_controls[] = //MUST define the current used format as the first item static struct rk_sensor_datafmt sensor_colour_fmts[] = { - {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG} + {MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG} }; /*static struct soc_camera_ops sensor_ops;*/ diff --git a/drivers/media/video/gc2035.c b/drivers/media/video/gc2035.c old mode 100755 new mode 100644 index ffd401abe502..cd3516468f46 --- a/drivers/media/video/gc2035.c +++ b/drivers/media/video/gc2035.c @@ -1,3 +1,16 @@ +/* + * drivers/media/video/gc2035.c + * + * Copyright (C) ROCKCHIP, Inc. + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ #include "generic_sensor.h" @@ -1190,7 +1203,7 @@ static struct sensor_v4l2ctrl_usr_s sensor_controls[] = //MUST define the current used format as the first item static struct rk_sensor_datafmt sensor_colour_fmts[] = { - {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG} + {MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG} }; /*static struct soc_camera_ops sensor_ops;*/ diff --git a/drivers/media/video/gc2145.c b/drivers/media/video/gc2145.c new file mode 100644 index 000000000000..fd426975bc08 --- /dev/null +++ b/drivers/media/video/gc2145.c @@ -0,0 +1,1699 @@ +/* + * drivers/media/video/gc2145.c + * + * Copyright (C) ROCKCHIP, Inc. + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "generic_sensor.h" + +/* +* Driver Version Note +*v0.0.1: this driver is compatible with generic_sensor +*v0.0.3: +* add sensor_focus_af_const_pause_usr_cb; +*/ +static int version = KERNEL_VERSION(0, 0, 3); +module_param(version, int, S_IRUGO); + +static int debug; +module_param(debug, int, S_IRUGO | S_IWUSR); + +#define dprintk(level, fmt, arg...) do { \ + if (debug >= level) \ + printk(KERN_WARNING fmt, ## arg); \ +} while (0) + +/* Sensor Driver Configuration Begin */ +#define SENSOR_NAME RK29_CAM_SENSOR_GC2145 +#define SENSOR_V4L2_IDENT V4L2_IDENT_GC2145 +#define SENSOR_ID 0x2145 +#define SENSOR_BUS_PARAM (V4L2_MBUS_MASTER |\ + V4L2_MBUS_PCLK_SAMPLE_RISING |\ + V4L2_MBUS_HSYNC_ACTIVE_HIGH |\ + V4L2_MBUS_VSYNC_ACTIVE_LOW |\ + V4L2_MBUS_DATA_ACTIVE_HIGH |\ + SOCAM_MCLK_24MHZ) +#define SENSOR_PREVIEW_W 800 +#define SENSOR_PREVIEW_H 600 +#define SENSOR_PREVIEW_FPS 15000 // 15fps +#define SENSOR_FULLRES_L_FPS 7500 // 7.5fps +#define SENSOR_FULLRES_H_FPS 7500 // 7.5fps +#define SENSOR_720P_FPS 15000 +#define SENSOR_1080P_FPS 0 + +#define SENSOR_REGISTER_LEN 1 // sensor register address bytes +#define SENSOR_VALUE_LEN 1 // sensor register value bytes +static unsigned int SensorConfiguration = + (CFG_WhiteBalance | CFG_Effect | CFG_Scene); +static unsigned int SensorChipID[] = { SENSOR_ID }; +/* Sensor Driver Configuration End */ + +#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) +#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) + +#define SensorRegVal(a, b) CONS4(SensorReg, SENSOR_REGISTER_LEN, Val, SENSOR_VALUE_LEN)(a, b) +#define sensor_write(client, reg, v) CONS4(sensor_write_reg, SENSOR_REGISTER_LEN, val, SENSOR_VALUE_LEN)(client, (reg), (v)) +#define sensor_read(client, reg, v) CONS4(sensor_read_reg, SENSOR_REGISTER_LEN, val, SENSOR_VALUE_LEN)(client, (reg), (v)) +#define sensor_write_array generic_sensor_write_array + +struct sensor_parameter { + unsigned int PreviewDummyPixels; + unsigned int CaptureDummyPixels; + unsigned int preview_exposure; + unsigned short int preview_line_width; + unsigned short int preview_gain; + + unsigned short int PreviewPclk; + unsigned short int CapturePclk; + char awb[6]; +}; + +struct specific_sensor { + struct generic_sensor common_sensor; + //define user data below + struct sensor_parameter parameter; + u16 shutter; + +}; + +/* +* The follow setting need been filled. +* +* Must Filled: +* sensor_init_data : Sensor initial setting; +* sensor_fullres_lowfps_data : Sensor full resolution setting with best auality, recommand for video; +* sensor_preview_data : Sensor preview resolution setting, recommand it is vga or svga; +* sensor_softreset_data : Sensor software reset register; +* sensor_check_id_data : Sensir chip id register; +* +* Optional filled: +* sensor_fullres_highfps_data: Sensor full resolution setting with high framerate, recommand for video; +* sensor_720p: Sensor 720p setting, it is for video; +* sensor_1080p: Sensor 1080p setting, it is for video; +* +* :::::WARNING::::: +* The SensorEnd which is the setting end flag must be filled int the last of each setting; +*/ + +/* Sensor initial setting */ +static struct rk_sensor_reg sensor_init_data[] = { + //SENSORDB("GC2145_Sensor_Init"}, + {0xfe, 0xf0}, + {0xfe, 0xf0}, + {0xfe, 0xf0}, + {0xfc, 0x06}, + {0xf6, 0x00}, + {0xf7, 0x1d}, + {0xf8, 0x84}, + {0xfa, 0x00}, + {0xf9, 0xfe}, + {0xf2, 0x00}, + ///////////////////////////////////////////////// + //////////////////ISP reg////////////////////// + + //////////////////////////////////////////////////// + {0xfe, 0x00}, + {0x03, 0x04}, + {0x04, 0xe2}, + {0x09, 0x00}, + {0x0a, 0x00}, + {0x0b, 0x00}, + {0x0c, 0x00}, + {0x0d, 0x04}, + {0x0e, 0xc0}, + {0x0f, 0x06}, + {0x10, 0x52}, + {0x12, 0x2e}, + {0x17, 0x14}, //mirror + {0x18, 0x22}, + {0x19, 0x0e}, + {0x1a, 0x01}, + {0x1b, 0x4b}, + {0x1c, 0x07}, + {0x1d, 0x10}, + {0x1e, 0x88}, + {0x1f, 0x78}, + {0x20, 0x03}, + {0x21, 0x40}, + {0x22, 0xa0}, + {0x24, 0x16}, + {0x25, 0x01}, + {0x26, 0x10}, + {0x2d, 0x60}, + {0x30, 0x01}, + {0x31, 0x90}, + {0x33, 0x06}, + {0x34, 0x01}, + ///////////////////////////////////////////////// + //////////////////ISP reg//////////////////// + ///////////////////////////////////////////////// + {0xfe, 0x00}, + {0x80, 0x7f}, + {0x81, 0x26}, + {0x82, 0xfa}, + {0x83, 0x00}, + {0x84, 0x00}, + {0x86, 0x02}, + {0x88, 0x03}, + {0x89, 0x03}, + {0x85, 0x08}, + {0x8a, 0x00}, + {0x8b, 0x00}, + {0xb0, 0x55}, + {0xc3, 0x00}, + {0xc4, 0x80}, + {0xc5, 0x90}, + {0xc6, 0x3b}, + {0xc7, 0x46}, + {0xec, 0x06}, + {0xed, 0x04}, + {0xee, 0x60}, + {0xef, 0x90}, + {0xb6, 0x01}, + {0x90, 0x01}, + {0x91, 0x00}, + {0x92, 0x00}, + {0x93, 0x00}, + {0x94, 0x00}, + {0x95, 0x04}, + {0x96, 0xb0}, + {0x97, 0x06}, + {0x98, 0x40}, + ///////////////////////////////////////// + /////////// BLK //////////////////////// + ///////////////////////////////////////// + {0xfe, 0x00}, + {0x40, 0x42}, + {0x41, 0x00}, + {0x43, 0x5b}, + {0x5e, 0x00}, + {0x5f, 0x00}, + {0x60, 0x00}, + {0x61, 0x00}, + {0x62, 0x00}, + {0x63, 0x00}, + {0x64, 0x00}, + {0x65, 0x00}, + {0x66, 0x20}, + {0x67, 0x20}, + {0x68, 0x20}, + {0x69, 0x20}, + {0x76, 0x00}, + {0x6a, 0x08}, + {0x6b, 0x08}, + {0x6c, 0x08}, + {0x6d, 0x08}, + {0x6e, 0x08}, + {0x6f, 0x08}, + {0x70, 0x08}, + {0x71, 0x08}, + {0x76, 0x00}, + {0x72, 0xf0}, + {0x7e, 0x3c}, + {0x7f, 0x00}, + {0xfe, 0x02}, + {0x48, 0x15}, + {0x49, 0x00}, + {0x4b, 0x0b}, + {0xfe, 0x00}, + //////////////////////////////////////// + /////////// AEC //////////////////////// + //////////////////////////////////////// + {0xfe, 0x01}, + {0x01, 0x04}, + {0x02, 0xc0}, + {0x03, 0x04}, + {0x04, 0x90}, + {0x05, 0x30}, + {0x06, 0x90}, + {0x07, 0x30}, + {0x08, 0x80}, + {0x09, 0x00}, + {0x0a, 0x82}, + {0x0b, 0x11}, + {0x0c, 0x10}, + {0x11, 0x10}, + {0x13, 0x7b}, + {0x17, 0x00}, + {0x1c, 0x11}, + {0x1e, 0x61}, + {0x1f, 0x35}, + {0x20, 0x40}, + {0x22, 0x40}, + {0x23, 0x20}, + {0xfe, 0x02}, + {0x0f, 0x04}, + {0xfe, 0x01}, + {0x12, 0x35}, + {0x15, 0xb0}, + {0x10, 0x31}, + {0x3e, 0x28}, + {0x3f, 0xb0}, + {0x40, 0x90}, + {0x41, 0x0f}, + + ///////////////////////////// + //////// INTPEE ///////////// + ///////////////////////////// + {0xfe, 0x02}, + {0x90, 0x6c}, + {0x91, 0x03}, + {0x92, 0xcb}, + {0x94, 0x33}, + {0x95, 0x84}, + {0x97, 0x45}, //65 kent + {0xa2, 0x11}, + {0xfe, 0x00}, + ///////////////////////////// + //////// DNDD/////////////// + ///////////////////////////// + {0xfe, 0x02}, + {0x80, 0xc1}, + {0x81, 0x08}, + {0x82, 0x1f}, //08 by kent + {0x83, 0x10}, //05 by kent + {0x84, 0x0a}, + {0x86, 0xf0}, + {0x87, 0x50}, + {0x88, 0x15}, + {0x89, 0xb0}, + {0x8a, 0x30}, + {0x8b, 0x10}, + ///////////////////////////////////////// + /////////// ASDE //////////////////////// + ///////////////////////////////////////// + {0xfe, 0x01}, + {0x21, 0x04}, + {0xfe, 0x02}, + {0xa3, 0x50}, + {0xa4, 0x20}, + {0xa5, 0x40}, + {0xa6, 0x80}, + {0xab, 0x40}, + {0xae, 0x0c}, + {0xb3, 0x46}, + {0xb4, 0x64}, + {0xb6, 0x38}, + {0xb7, 0x01}, + {0xb9, 0x2b}, + {0x3c, 0x04}, + {0x3d, 0x15}, + {0x4b, 0x06}, + {0x4c, 0x20}, + {0xfe, 0x00}, + ///////////////////////////////////////// + /////////// GAMMA //////////////////////// + ///////////////////////////////////////// + + ///////////////////gamma1//////////////////// +#if 1 + {0xfe, 0x02}, + {0x10, 0x09}, + {0x11, 0x0d}, + {0x12, 0x13}, + {0x13, 0x19}, + {0x14, 0x27}, + {0x15, 0x37}, + {0x16, 0x45}, + {0x17, 0x53}, + {0x18, 0x69}, + {0x19, 0x7d}, + {0x1a, 0x8f}, + {0x1b, 0x9d}, + {0x1c, 0xa9}, + {0x1d, 0xbd}, + {0x1e, 0xcd}, + {0x1f, 0xd9}, + {0x20, 0xe3}, + {0x21, 0xea}, + {0x22, 0xef}, + {0x23, 0xf5}, + {0x24, 0xf9}, + {0x25, 0xff}, +#else + {0xfe, 0x02}, + {0x10, 0x0a}, + {0x11, 0x12}, + {0x12, 0x19}, + {0x13, 0x1f}, + {0x14, 0x2c}, + {0x15, 0x38}, + {0x16, 0x42}, + {0x17, 0x4e}, + {0x18, 0x63}, + {0x19, 0x76}, + {0x1a, 0x87}, + {0x1b, 0x96}, + {0x1c, 0xa2}, + {0x1d, 0xb8}, + {0x1e, 0xcb}, + {0x1f, 0xd8}, + {0x20, 0xe2}, + {0x21, 0xe9}, + {0x22, 0xf0}, + {0x23, 0xf8}, + {0x24, 0xfd}, + {0x25, 0xff}, + {0xfe, 0x00}, +#endif + {0xfe, 0x00}, + {0xc6, 0x20}, + {0xc7, 0x2b}, + ///////////////////gamma2//////////////////// +#if 1 + {0xfe, 0x02}, + {0x26, 0x0f}, + {0x27, 0x14}, + {0x28, 0x19}, + {0x29, 0x1e}, + {0x2a, 0x27}, + {0x2b, 0x33}, + {0x2c, 0x3b}, + {0x2d, 0x45}, + {0x2e, 0x59}, + {0x2f, 0x69}, + {0x30, 0x7c}, + {0x31, 0x89}, + {0x32, 0x98}, + {0x33, 0xae}, + {0x34, 0xc0}, + {0x35, 0xcf}, + {0x36, 0xda}, + {0x37, 0xe2}, + {0x38, 0xe9}, + {0x39, 0xf3}, + {0x3a, 0xf9}, + {0x3b, 0xff}, +#else + ////Gamma outdoor + {0xfe, 0x02}, + {0x26, 0x17}, + {0x27, 0x18}, + {0x28, 0x1c}, + {0x29, 0x20}, + {0x2a, 0x28}, + {0x2b, 0x34}, + {0x2c, 0x40}, + {0x2d, 0x49}, + {0x2e, 0x5b}, + {0x2f, 0x6d}, + {0x30, 0x7d}, + {0x31, 0x89}, + {0x32, 0x97}, + {0x33, 0xac}, + {0x34, 0xc0}, + {0x35, 0xcf}, + {0x36, 0xda}, + {0x37, 0xe5}, + {0x38, 0xec}, + {0x39, 0xf8}, + {0x3a, 0xfd}, + {0x3b, 0xff}, +#endif + /////////////////////////////////////////////// + ///////////YCP /////////////////////// + /////////////////////////////////////////////// + {0xfe, 0x02}, + {0xd1, 0x40}, //32 kent + {0xd2, 0x40}, //32 + {0xd3, 0x48}, //40 + {0xd6, 0xf0}, + {0xd7, 0x10}, + {0xd8, 0xda}, + {0xdd, 0x14}, + {0xde, 0x86}, + {0xed, 0x80}, + {0xee, 0x00}, + {0xef, 0x3f}, + {0xd8, 0xd8}, + ///////////////////abs///////////////// + {0xfe, 0x01}, + {0x9f, 0x40}, + ///////////////////////////////////////////// + //////////////////////// LSC /////////////// + ////////////////////////////////////////// + {0xfe, 0x01}, + {0xc2, 0x14}, + {0xc3, 0x0d}, + {0xc4, 0x0c}, + {0xc8, 0x15}, + {0xc9, 0x0d}, + {0xca, 0x0a}, + {0xbc, 0x24}, + {0xbd, 0x10}, + {0xbe, 0x0b}, + {0xb6, 0x25}, + {0xb7, 0x16}, + {0xb8, 0x15}, + {0xc5, 0x00}, + {0xc6, 0x00}, + {0xc7, 0x00}, + {0xcb, 0x00}, + {0xcc, 0x00}, + {0xcd, 0x00}, + {0xbf, 0x07}, + {0xc0, 0x00}, + {0xc1, 0x00}, + {0xb9, 0x00}, + {0xba, 0x00}, + {0xbb, 0x00}, + {0xaa, 0x01}, + {0xab, 0x01}, + {0xac, 0x00}, + {0xad, 0x05}, + {0xae, 0x06}, + {0xaf, 0x0e}, + {0xb0, 0x0b}, + {0xb1, 0x07}, + {0xb2, 0x06}, + {0xb3, 0x17}, + {0xb4, 0x0e}, + {0xb5, 0x0e}, + {0xd0, 0x09}, + {0xd1, 0x00}, + {0xd2, 0x00}, + {0xd6, 0x08}, + {0xd7, 0x00}, + {0xd8, 0x00}, + {0xd9, 0x00}, + {0xda, 0x00}, + {0xdb, 0x00}, + {0xd3, 0x0a}, + {0xd4, 0x00}, + {0xd5, 0x00}, + {0xa4, 0x00}, + {0xa5, 0x00}, + {0xa6, 0x77}, + {0xa7, 0x77}, + {0xa8, 0x77}, + {0xa9, 0x77}, + {0xa1, 0x80}, + {0xa2, 0x80}, + + {0xfe, 0x01}, + {0xdf, 0x0d}, + {0xdc, 0x25}, + {0xdd, 0x30}, + {0xe0, 0x77}, + {0xe1, 0x80}, + {0xe2, 0x77}, + {0xe3, 0x90}, + {0xe6, 0x90}, + {0xe7, 0xa0}, + {0xe8, 0x90}, + {0xe9, 0xa0}, + {0xfe, 0x00}, + /////////////////////////////////////////////// + /////////// AWB//////////////////////// + /////////////////////////////////////////////// + {0xfe, 0x01}, + {0x4f, 0x00}, + {0x4f, 0x00}, + {0x4b, 0x01}, + {0x4f, 0x00}, + + {0x4c, 0x01}, // D75 + {0x4d, 0x71}, + {0x4e, 0x01}, + {0x4c, 0x01}, + {0x4d, 0x91}, + {0x4e, 0x01}, + {0x4c, 0x01}, + {0x4d, 0x70}, + {0x4e, 0x01}, + {0x4c, 0x01}, // D65 + {0x4d, 0x90}, + {0x4e, 0x02}, + {0x4c, 0x01}, + {0x4d, 0xb0}, + {0x4e, 0x02}, + {0x4c, 0x01}, + {0x4d, 0x8f}, + {0x4e, 0x02}, + {0x4c, 0x01}, + {0x4d, 0x6f}, + {0x4e, 0x02}, + {0x4c, 0x01}, + {0x4d, 0xaf}, + {0x4e, 0x02}, + {0x4c, 0x01}, + {0x4d, 0xd0}, + {0x4e, 0x02}, + {0x4c, 0x01}, + {0x4d, 0xf0}, + {0x4e, 0x02}, + {0x4c, 0x01}, + {0x4d, 0xcf}, + {0x4e, 0x02}, + {0x4c, 0x01}, + {0x4d, 0xef}, + {0x4e, 0x02}, + {0x4c, 0x01}, //D50 + {0x4d, 0x6e}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0x8e}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0xae}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0xce}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0x4d}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0x6d}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0x8d}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0xad}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0xcd}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0x4c}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0x6c}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0x8c}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0xac}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0xcc}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0xcb}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0x4b}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0x6b}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0x8b}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0xab}, + {0x4e, 0x03}, + {0x4c, 0x01}, //CWF + {0x4d, 0x8a}, + {0x4e, 0x04}, + {0x4c, 0x01}, + {0x4d, 0xaa}, + {0x4e, 0x04}, + {0x4c, 0x01}, + {0x4d, 0xca}, + {0x4e, 0x04}, + {0x4c, 0x01}, + {0x4d, 0xca}, + {0x4e, 0x04}, + {0x4c, 0x01}, + {0x4d, 0xc9}, + {0x4e, 0x04}, + {0x4c, 0x01}, + {0x4d, 0x8a}, + {0x4e, 0x04}, + {0x4c, 0x01}, + {0x4d, 0x89}, + {0x4e, 0x04}, + {0x4c, 0x01}, + {0x4d, 0xa9}, + {0x4e, 0x04}, + {0x4c, 0x02}, //tl84 + {0x4d, 0x0b}, + {0x4e, 0x05}, + {0x4c, 0x02}, + {0x4d, 0x0a}, + {0x4e, 0x05}, + {0x4c, 0x01}, + {0x4d, 0xeb}, + {0x4e, 0x05}, + {0x4c, 0x01}, + {0x4d, 0xea}, + {0x4e, 0x05}, + {0x4c, 0x02}, + {0x4d, 0x09}, + {0x4e, 0x05}, + {0x4c, 0x02}, + {0x4d, 0x29}, + {0x4e, 0x05}, + {0x4c, 0x02}, + {0x4d, 0x2a}, + {0x4e, 0x05}, + {0x4c, 0x02}, + {0x4d, 0x4a}, + {0x4e, 0x05}, + //{0x4c , 0x02}, //A + //{0x4d , 0x6a}, + //{0x4e , 0x06}, + {0x4c, 0x02}, + {0x4d, 0x8a}, + {0x4e, 0x06}, + {0x4c, 0x02}, + {0x4d, 0x49}, + {0x4e, 0x06}, + {0x4c, 0x02}, + {0x4d, 0x69}, + {0x4e, 0x06}, + {0x4c, 0x02}, + {0x4d, 0x89}, + {0x4e, 0x06}, + {0x4c, 0x02}, + {0x4d, 0xa9}, + {0x4e, 0x06}, + {0x4c, 0x02}, + {0x4d, 0x48}, + {0x4e, 0x06}, + {0x4c, 0x02}, + {0x4d, 0x68}, + {0x4e, 0x06}, + {0x4c, 0x02}, + {0x4d, 0x69}, + {0x4e, 0x06}, + {0x4c, 0x02}, //H + {0x4d, 0xca}, + {0x4e, 0x07}, + {0x4c, 0x02}, + {0x4d, 0xc9}, + {0x4e, 0x07}, + {0x4c, 0x02}, + {0x4d, 0xe9}, + {0x4e, 0x07}, + {0x4c, 0x03}, + {0x4d, 0x09}, + {0x4e, 0x07}, + {0x4c, 0x02}, + {0x4d, 0xc8}, + {0x4e, 0x07}, + {0x4c, 0x02}, + {0x4d, 0xe8}, + {0x4e, 0x07}, + {0x4c, 0x02}, + {0x4d, 0xa7}, + {0x4e, 0x07}, + {0x4c, 0x02}, + {0x4d, 0xc7}, + {0x4e, 0x07}, + {0x4c, 0x02}, + {0x4d, 0xe7}, + {0x4e, 0x07}, + {0x4c, 0x03}, + {0x4d, 0x07}, + {0x4e, 0x07}, + + {0x4f, 0x01}, + {0x50, 0x80}, + {0x51, 0xa8}, + {0x52, 0x47}, + {0x53, 0x38}, + {0x54, 0xc7}, + {0x56, 0x0e}, + {0x58, 0x08}, + {0x5b, 0x00}, + {0x5c, 0x74}, + {0x5d, 0x8b}, + {0x61, 0xdb}, + {0x62, 0xb8}, + {0x63, 0x86}, + {0x64, 0xc0}, + {0x65, 0x04}, + {0x67, 0xa8}, + {0x68, 0xb0}, + {0x69, 0x00}, + {0x6a, 0xa8}, + {0x6b, 0xb0}, + {0x6c, 0xaf}, + {0x6d, 0x8b}, + {0x6e, 0x50}, + {0x6f, 0x18}, + {0x73, 0xf0}, + {0x70, 0x0d}, + {0x71, 0x60}, + {0x72, 0x80}, + {0x74, 0x01}, + {0x75, 0x01}, + {0x7f, 0x0c}, + {0x76, 0x70}, + {0x77, 0x58}, + {0x78, 0xa0}, + {0x79, 0x5e}, + {0x7a, 0x54}, + {0x7b, 0x58}, + {0xfe, 0x00}, + ////////////////////////////////////////// + ///////////CC//////////////////////// + ////////////////////////////////////////// + {0xfe, 0x02}, + {0xc0, 0x01}, + {0xc1, 0x44}, + {0xc2, 0xfd}, + {0xc3, 0x04}, + {0xc4, 0xF0}, + {0xc5, 0x48}, + {0xc6, 0xfd}, + {0xc7, 0x46}, + {0xc8, 0xfd}, + {0xc9, 0x02}, + {0xca, 0xe0}, + {0xcb, 0x45}, + {0xcc, 0xec}, + {0xcd, 0x48}, + {0xce, 0xf0}, + {0xcf, 0xf0}, + {0xe3, 0x0c}, + {0xe4, 0x4b}, + {0xe5, 0xe0}, + ////////////////////////////////////////// + ///////////ABS //////////////////// + ////////////////////////////////////////// + {0xfe, 0x01}, + {0x9f, 0x40}, + {0xfe, 0x00}, + ////////////////////////////////////// + /////////// OUTPUT //////////////// + ////////////////////////////////////// + {0xfe, 0x00}, + {0xf2, 0x0f}, + ///////////////dark sun//////////////////// + {0xfe, 0x02}, + {0x40, 0xbf}, + {0x46, 0xcf}, + {0xfe, 0x00}, + + //////////////frame rate 50Hz///////// + {0xfe, 0x00}, + {0x05, 0x01}, + {0x06, 0x56}, + {0x07, 0x00}, + {0x08, 0x32}, + {0xfe, 0x01}, + {0x25, 0x00}, + {0x26, 0xfa}, + + {0x27, 0x04}, + {0x28, 0xe2}, //20fps + {0x29, 0x07}, + {0x2a, 0xd0}, //14fps + {0x2b, 0x09}, + {0x2c, 0xc4}, //12fps + {0x2d, 0x0b}, + {0x2e, 0xb8}, //8fps + {0xfe, 0x00}, + + //SENSORDB("GC2145_Sensor_SVGA"}, + + {0xfe, 0x00}, + {0xfd, 0x01}, + {0xfa, 0x00}, + //// crop window + {0xfe, 0x00}, + {0x90, 0x01}, + {0x91, 0x00}, + {0x92, 0x00}, + {0x93, 0x00}, + {0x94, 0x00}, + {0x95, 0x02}, + {0x96, 0x58}, + {0x97, 0x03}, + {0x98, 0x20}, + {0x99, 0x11}, + {0x9a, 0x06}, + //// AWB + {0xfe, 0x00}, + {0xec, 0x02}, + {0xed, 0x02}, + {0xee, 0x30}, + {0xef, 0x48}, + {0xfe, 0x02}, + {0x9d, 0x08}, + {0xfe, 0x01}, + {0x74, 0x00}, + //// AEC + {0xfe, 0x01}, + {0x01, 0x04}, + {0x02, 0x60}, + {0x03, 0x02}, + {0x04, 0x48}, + {0x05, 0x18}, + {0x06, 0x50}, + {0x07, 0x10}, + {0x08, 0x38}, + {0x0a, 0x80}, + {0x21, 0x04}, + {0xfe, 0x00}, + {0x20, 0x03}, + {0xfe, 0x00}, + SensorEnd +}; +/* Senor full resolution setting: recommand for capture */ +static struct rk_sensor_reg sensor_fullres_lowfps_data[] = { + + //SENSORDB("GC2145_Sensor_2M"}, + {0xfe, 0x00}, + {0xfd, 0x00}, + {0xfa, 0x11}, + //// crop window + {0xfe, 0x00}, + {0x90, 0x01}, + {0x91, 0x00}, + {0x92, 0x00}, + {0x93, 0x00}, + {0x94, 0x00}, + {0x95, 0x04}, + {0x96, 0xb0}, + {0x97, 0x06}, + {0x98, 0x40}, + {0x99, 0x11}, + {0x9a, 0x06}, + //// AWB + {0xfe, 0x00}, + {0xec, 0x06}, + {0xed, 0x04}, + {0xee, 0x60}, + {0xef, 0x90}, + {0xfe, 0x01}, + {0x74, 0x01}, + //// AEC + {0xfe, 0x01}, + {0x01, 0x04}, + {0x02, 0xc0}, + {0x03, 0x04}, + {0x04, 0x90}, + {0x05, 0x30}, + {0x06, 0x90}, + {0x07, 0x30}, + {0x08, 0x80}, + {0x0a, 0x82}, + {0xfe, 0x01}, + {0x21, 0x15}, + {0xfe, 0x00}, + {0x20, 0x15}, //if 0xfa=11,then 0x21=15;else if 0xfa=00,then 0x21=04 + {0xfe, 0x00}, + SensorEnd +}; + +/* Senor full resolution setting: recommand for video */ +static struct rk_sensor_reg sensor_fullres_highfps_data[] = { + SensorEnd +}; +/* Preview resolution setting*/ +static struct rk_sensor_reg sensor_preview_data[] = { + + //SENSORDB("GC2145_Sensor_SVGA"}, + + {0xfe, 0x00}, + {0xb6, 0x01}, + {0xfd, 0x01}, + {0xfa, 0x00}, + //// crop window + {0xfe, 0x00}, + {0x90, 0x01}, + {0x91, 0x00}, + {0x92, 0x00}, + {0x93, 0x00}, + {0x94, 0x00}, + {0x95, 0x02}, + {0x96, 0x58}, + {0x97, 0x03}, + {0x98, 0x20}, + {0x99, 0x11}, + {0x9a, 0x06}, + //// AWB + {0xfe, 0x00}, + {0xec, 0x02}, + {0xed, 0x02}, + {0xee, 0x30}, + {0xef, 0x48}, + {0xfe, 0x02}, + {0x9d, 0x08}, + {0xfe, 0x01}, + {0x74, 0x00}, + //// AEC + {0xfe, 0x01}, + {0x01, 0x04}, + {0x02, 0x60}, + {0x03, 0x02}, + {0x04, 0x48}, + {0x05, 0x18}, + {0x06, 0x50}, + {0x07, 0x10}, + {0x08, 0x38}, + {0x0a, 0x80}, + {0x21, 0x04}, + {0xfe, 0x00}, + {0x20, 0x03}, + {0xfe, 0x00}, + SensorEnd +}; +/* 1280x720 */ +static struct rk_sensor_reg sensor_720p[] = { +#if 0 + {0xfe, 0x00}, + //{0xfa , 0x11}, + {0xb6, 0x01}, + {0xfd, 0x00}, + //// crop window + {0xfe, 0x00}, + {0x99, 0x55}, + {0x9a, 0x06}, + {0x9b, 0x00}, + {0x9c, 0x00}, + {0x9d, 0x01}, + {0x9e, 0x23}, + {0x9f, 0x00}, + {0xa0, 0x00}, + {0xa1, 0x01}, + {0xa2, 0x23}, + + {0x90, 0x01}, + {0x91, 0x00}, + {0x92, 0x78}, + {0x93, 0x00}, + {0x94, 0x00}, + {0x95, 0x02}, + {0x96, 0xd0}, + {0x97, 0x05}, + {0x98, 0x00}, + //// AWB + {0xfe, 0x00}, + {0xec, 0x06}, + {0xed, 0x04}, + {0xee, 0x60}, + {0xef, 0x90}, + {0xfe, 0x01}, + {0x74, 0x01}, + //// AEC + {0xfe, 0x01}, + {0x01, 0x04}, + {0x02, 0xc0}, + {0x03, 0x04}, + {0x04, 0x90}, + {0x05, 0x30}, + {0x06, 0x90}, + {0x07, 0x30}, + {0x08, 0x80}, + {0x0a, 0x82}, + {0xfe, 0x01}, + {0x21, 0x15}, + {0xfe, 0x00}, + {0x20, 0x15}, //if 0xfa=11,then 0x21=15;else if 0xfa=00,then 0x21=04 + {0xfe, 0x00}, +#endif + SensorEnd +}; + +/* 1920x1080 */ +static struct rk_sensor_reg sensor_1080p[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_softreset_data[] = { + SensorRegVal(0xfe, 80), + SensorWaitMs(5), + SensorEnd +}; + +static struct rk_sensor_reg sensor_check_id_data[] = { + SensorRegVal(0xf0, 0), + SensorRegVal(0xf1, 0), + SensorEnd +}; +/* +* The following setting must been filled, if the function is turn on by CONFIG_SENSOR_xxxx +*/ +static struct rk_sensor_reg sensor_WhiteB_Auto[] = { + {0xfe, 0x00}, + {0xb3, 0x61}, + {0xb4, 0x40}, + {0xb5, 0x61}, + {0x82, 0xfe}, + SensorEnd +}; +/* Cloudy Colour Temperature : 6500K - 8000K */ +static struct rk_sensor_reg sensor_WhiteB_Cloudy[] = { + {0xfe, 0x00}, + {0x82, 0xfc}, + {0xb3, 0x58}, + {0xb4, 0x40}, + {0xb5, 0x50}, + + SensorEnd +}; +/* ClearDay Colour Temperature : 5000K - 6500K */ +static struct rk_sensor_reg sensor_WhiteB_ClearDay[] = { + //Sunny + {0xfe, 0x00}, + {0x82, 0xfc}, + {0xb3, 0x70}, + {0xb4, 0x40}, + {0xb5, 0x50}, + SensorEnd +}; +/* Office Colour Temperature : 3500K - 5000K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[] = { + //Office + {0xfe, 0x00}, + {0x82, 0xfc}, + {0xb3, 0x50}, + {0xb4, 0x40}, + {0xb5, 0xa8}, + SensorEnd +}; +/* Home Colour Temperature : 2500K - 3500K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[] = { + //Home + {0xfe, 0x00}, + {0x82, 0xfc}, + {0xb3, 0xa0}, + {0xb4, 0x45}, + {0xb5, 0x40}, + SensorEnd +}; + +static struct rk_sensor_reg *sensor_WhiteBalanceSeqe[] = { + sensor_WhiteB_Auto, + sensor_WhiteB_Cloudy, + sensor_WhiteB_ClearDay, + sensor_WhiteB_TungstenLamp1, + sensor_WhiteB_TungstenLamp2, + NULL, +}; + +static struct rk_sensor_reg sensor_Brightness0[] = { + // Brightness -2 + + {0xfe, 0x01}, + {0x13, 0x10}, + {0xfe, 0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness1[] = { + // Brightness -1 + + {0xfe, 0x01}, + {0x13, 0x20}, + {0xfe, 0x00}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness2[] = { + // Brightness 0 + + {0xfe, 0x01}, + {0x13, 0x30}, + {0xfe, 0x00}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness3[] = { + // Brightness +1 + {0xfe, 0x01}, + {0x13, 0x40}, + {0xfe, 0x00}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness4[] = { + // Brightness +2 + {0xfe, 0x01}, + {0x13, 0x45}, + {0xfe, 0x00}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness5[] = { + // Brightness +3 + {0xfe, 0x01}, + {0x13, 0x50}, + {0xfe, 0x00}, + SensorEnd +}; +static struct rk_sensor_reg *sensor_BrightnessSeqe[] = { + sensor_Brightness0, + sensor_Brightness1, + sensor_Brightness2, + sensor_Brightness3, + sensor_Brightness4, + sensor_Brightness5, + NULL, +}; + +static struct rk_sensor_reg sensor_Effect_Normal[] = { + {0xfe, 0x00}, + {0x83, 0xe0}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_WandB[] = { + {0xfe, 0x00}, + {0x83, 0x12}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Sepia[] = { + {0xfe, 0x00}, + {0x83, 0x82}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Negative[] = { + //Negative + {0xfe, 0x00}, + {0x83, 0x01}, + SensorEnd +}; +static struct rk_sensor_reg sensor_Effect_Bluish[] = { + // Bluish + {0xfe, 0x00}, + {0x83, 0x62}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Green[] = { + // Greenish + {0xfe, 0x00}, + {0x83, 0x52}, + SensorEnd +}; +static struct rk_sensor_reg *sensor_EffectSeqe[] = { + sensor_Effect_Normal, + sensor_Effect_WandB, + sensor_Effect_Negative, + sensor_Effect_Sepia, + sensor_Effect_Bluish, + sensor_Effect_Green, + NULL, +}; + +static struct rk_sensor_reg sensor_Exposure0[] = { + {0xfe, 0x01}, + {0x13, 0x60}, + {0xfe, 0x00}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure1[] = { + {0xfe, 0x01}, + {0x13, 0x65}, + {0xfe, 0x00}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure2[] = { + {0xfe, 0x01}, + {0x13, 0x70}, + {0xfe, 0x00}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure3[] = { + {0xfe, 0x01}, + {0x13, 0x7b}, + {0xfe, 0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure4[] = { + {0xfe, 0x01}, + {0x13, 0x85}, + {0xfe, 0x00}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure5[] = { + {0xfe, 0x01}, + {0x13, 0x90}, + {0xfe, 0x00}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure6[] = { + {0xfe, 0x01}, + {0x13, 0x95}, + {0xfe, 0x00}, + + SensorEnd +}; + +static struct rk_sensor_reg *sensor_ExposureSeqe[] = { + sensor_Exposure0, + sensor_Exposure1, + sensor_Exposure2, + sensor_Exposure3, + sensor_Exposure4, + sensor_Exposure5, + sensor_Exposure6, + NULL, +}; + +static struct rk_sensor_reg sensor_Saturation0[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Saturation1[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Saturation2[] = { + SensorEnd +}; +static struct rk_sensor_reg *sensor_SaturationSeqe[] = { + sensor_Saturation0, + sensor_Saturation1, + sensor_Saturation2, + NULL, +}; + +static struct rk_sensor_reg sensor_Contrast0[] = { + //Contrast -3 + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast1[] = { + //Contrast -2 + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast2[] = { + // Contrast -1 + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast3[] = { + //Contrast 0 + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast4[] = { + //Contrast +1 + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast5[] = { + //Contrast +2 + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast6[] = { + //Contrast +3 + + SensorEnd +}; +static struct rk_sensor_reg *sensor_ContrastSeqe[] = { + sensor_Contrast0, + sensor_Contrast1, + sensor_Contrast2, + sensor_Contrast3, + sensor_Contrast4, + sensor_Contrast5, + sensor_Contrast6, + NULL, +}; +static struct rk_sensor_reg sensor_SceneAuto[] = { + {0xfe, 0x01}, + + {0x3c, 0x40}, + {0xfe, 0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_SceneNight[] = { + {0xfe, 0x01}, + + {0x3c, 0x60}, + {0xfe, 0x00}, + SensorEnd +}; +static struct rk_sensor_reg *sensor_SceneSeqe[] = { + sensor_SceneAuto, + sensor_SceneNight, + NULL, +}; + +static struct rk_sensor_reg sensor_Zoom0[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Zoom1[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Zoom2[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Zoom3[] = { + SensorEnd +}; +static struct rk_sensor_reg *sensor_ZoomSeqe[] = { + sensor_Zoom0, + sensor_Zoom1, + sensor_Zoom2, + sensor_Zoom3, + NULL, +}; + +/* +* User could be add v4l2_querymenu in sensor_controls by new_usr_v4l2menu +*/ +static struct v4l2_querymenu sensor_menus[] = { +}; +/* +* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl +*/ +static struct sensor_v4l2ctrl_usr_s sensor_controls[] = { +}; + +//MUST define the current used format as the first item +static struct rk_sensor_datafmt sensor_colour_fmts[] = { + {MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG} +}; +/*static struct soc_camera_ops sensor_ops;*/ + +/* +********************************************************** +* Following is local code: +* +* Please codeing your program here +********************************************************** +*/ +/* +********************************************************** +* Following is callback +* If necessary, you could coding these callback +********************************************************** +*/ +/* +* the function is called in open sensor +*/ +static int sensor_activate_cb(struct i2c_client *client) +{ + + return 0; +} + +/* +* the function is called in close sensor +*/ +static int sensor_deactivate_cb(struct i2c_client *client) +{ + //sensor_write(client, 0xfe, 0xf0); + //sensor_write(client, 0xfe, 0xf0); + //sensor_write(client, 0xfe, 0xf0); + //sensor_write(client, 0xfa, 0x73); + //sensor_write(client, 0x24, 0x00); + return 0; +} + +/* +* the function is called before sensor register setting in VIDIOC_S_FMT +*/ +static unsigned int shutter_h, shutter_l, cap; +static int sensor_s_fmt_cb_th(struct i2c_client *client, + struct v4l2_mbus_framefmt *mf, bool capture) +{ + char value; + unsigned int pid = 0, shutter, temp_reg; + + if ((mf->width == 800 && mf->height == 600) && (cap == 1)) { + cap = 0; + sensor_write(client, 0xb6, 0x00); // AEC off + sensor_write(client, 0x03, shutter_h); + sensor_write(client, 0x04, shutter_l); + msleep(50); + printk("set preview for rewrite 0x03"); + } + if (mf->width == 1600 && mf->height == 1200) { + + cap = 1; + sensor_write(client, 0xfe, 0x00); + sensor_write(client, 0xb6, 0x00); + sensor_read(client, 0x03, &value); + shutter_h = value; + pid |= (value << 8); + sensor_read(client, 0x04, &value); + shutter_l = value; + pid |= (value & 0xff); + shutter = pid; + + temp_reg = shutter / 2; + + if (temp_reg < 1) + temp_reg = 1; + + sensor_write(client, 0x03, ((temp_reg >> 8) & 0x1f)); + sensor_write(client, 0x04, (temp_reg & 0xff)); + } + + return 0; +} + +/* +* the function is called after sensor register setting finished in VIDIOC_S_FMT +*/ +static int sensor_s_fmt_cb_bh(struct i2c_client *client, + struct v4l2_mbus_framefmt *mf, bool capture) +{ + /* add delay for rk312x */ + msleep(300); + return 0; +} +static int sensor_softrest_usr_cb(struct i2c_client *client, + struct rk_sensor_reg *series) +{ + + return 0; +} +static int sensor_check_id_usr_cb(struct i2c_client *client, + struct rk_sensor_reg *series) +{ + return 0; +} +static int sensor_try_fmt_cb_th(struct i2c_client *client, + struct v4l2_mbus_framefmt *mf) +{ + return 0; +} +static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg) +{ + //struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (pm_msg.event == PM_EVENT_SUSPEND) { + SENSOR_DG("Suspend"); + + } else { + SENSOR_TR("pm_msg.event(0x%x) != PM_EVENT_SUSPEND\n", + pm_msg.event); + return -EINVAL; + } + return 0; +} + +static int sensor_resume(struct soc_camera_device *icd) +{ + + SENSOR_DG("Resume"); + + return 0; + +} +static int sensor_mirror_cb(struct i2c_client *client, int mirror) +{ + char val; + int err = 0; + + SENSOR_DG("mirror: %d", mirror); + if (mirror) { + sensor_write(client, 0xfe, 0); + err = sensor_read(client, 0x17, &val); + val -= 4; + if (err == 0) { + if ((val & 0x1) == 0) { + err = + sensor_write(client, 0x17, + ((val | 0x1) + 4)); + } else + err = + sensor_write(client, 0x17, + ((val & 0xfe) + 4)); + } + } else { + //do nothing + } + return err; +} + +/* +* the function is v4l2 control V4L2_CID_HFLIP callback +*/ +static int sensor_v4l2ctrl_mirror_cb(struct soc_camera_device *icd, + struct sensor_v4l2ctrl_info_s *ctrl_info, + struct v4l2_ext_control *ext_ctrl) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_mirror_cb(client, ext_ctrl->value) != 0) + SENSOR_TR("sensor_mirror failed, value:0x%x", ext_ctrl->value); + + SENSOR_DG("sensor_mirror success, value:0x%x", ext_ctrl->value); + return 0; +} + +static int sensor_flip_cb(struct i2c_client *client, int flip) +{ + char val; + int err = 0; + + SENSOR_DG("flip: %d", flip); + if (flip) { + + sensor_write(client, 0xfe, 0); + err = sensor_read(client, 0x17, &val); + val -= 4; + if (err == 0) { + if ((val & 0x2) == 0) { + err = + sensor_write(client, 0x17, + ((val | 0x2) + 4)); + } else { + err = + sensor_write(client, 0x17, + ((val & 0xfc) + 4)); + } + } + } else { + //do nothing + } + + return err; +} + +/* +* the function is v4l2 control V4L2_CID_VFLIP callback +*/ +static int sensor_v4l2ctrl_flip_cb(struct soc_camera_device *icd, + struct sensor_v4l2ctrl_info_s *ctrl_info, + struct v4l2_ext_control *ext_ctrl) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_flip_cb(client, ext_ctrl->value) != 0) + SENSOR_TR("sensor_flip failed, value:0x%x", ext_ctrl->value); + + SENSOR_DG("sensor_flip success, value:0x%x", ext_ctrl->value); + return 0; +} + +/* +* the functions are focus callbacks +*/ +static int sensor_focus_init_usr_cb(struct i2c_client *client) +{ + return 0; +} + +static int sensor_focus_af_single_usr_cb(struct i2c_client *client) +{ + return 0; +} + +static int sensor_focus_af_near_usr_cb(struct i2c_client *client) +{ + return 0; +} + +static int sensor_focus_af_far_usr_cb(struct i2c_client *client) +{ + return 0; +} + +static int sensor_focus_af_specialpos_usr_cb(struct i2c_client *client, int pos) +{ + return 0; +} + +static int sensor_focus_af_const_usr_cb(struct i2c_client *client) +{ + return 0; +} +static int sensor_focus_af_const_pause_usr_cb(struct i2c_client *client) +{ + return 0; +} +static int sensor_focus_af_close_usr_cb(struct i2c_client *client) +{ + return 0; +} + +static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client, + int *zone_tm_pos) +{ + return 0; +} + +/* +face defect call back +*/ +static int sensor_face_detect_usr_cb(struct i2c_client *client, int on) +{ + return 0; +} + +/* +* The function can been run in sensor_init_parametres which run in sensor_probe, so user can do some +* initialization in the function. +*/ +static void sensor_init_parameters_user(struct specific_sensor *spsensor, + struct soc_camera_device *icd) +{ + return; +} + +/* +* :::::WARNING::::: +* It is not allowed to modify the following code +*/ + +sensor_init_parameters_default_code(); + +sensor_v4l2_struct_initialization(); + +sensor_probe_default_code(); + +sensor_remove_default_code(); + +sensor_driver_default_module_code(); diff --git a/drivers/media/video/gc2155.c b/drivers/media/video/gc2155.c new file mode 100644 index 000000000000..6440a777e8d3 --- /dev/null +++ b/drivers/media/video/gc2155.c @@ -0,0 +1,1622 @@ +/* + * drivers/media/video/gc2155.c + * + * Copyright (C) ROCKCHIP, Inc. + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "generic_sensor.h" + +/* +* Driver Version Note +*v0.0.1: this driver is compatible with generic_sensor +*v0.0.3: +* add sensor_focus_af_const_pause_usr_cb; +*/ +static int version = KERNEL_VERSION(0,0,3); +module_param(version, int, S_IRUGO); + + +static int debug; +module_param(debug, int, S_IRUGO|S_IWUSR); + +#define dprintk(level, fmt, arg...) do { \ + if (debug >= level) \ + printk(KERN_WARNING fmt , ## arg); } while (0) + +/* Sensor Driver Configuration Begin */ +#define SENSOR_NAME RK29_CAM_SENSOR_GC2155 +#define SENSOR_V4L2_IDENT V4L2_IDENT_GC2155 +#define SENSOR_ID 0x2155 +#define GC2155_SUBSAMPLE ///subsample for video + +#define SENSOR_BUS_PARAM (V4L2_MBUS_MASTER |\ + V4L2_MBUS_PCLK_SAMPLE_RISING|V4L2_MBUS_HSYNC_ACTIVE_HIGH| V4L2_MBUS_VSYNC_ACTIVE_LOW|\ + V4L2_MBUS_DATA_ACTIVE_HIGH |SOCAM_MCLK_24MHZ) +#define SENSOR_PREVIEW_W 800 +#define SENSOR_PREVIEW_H 600 +#define SENSOR_PREVIEW_FPS 15000 // 15fps +#define SENSOR_FULLRES_L_FPS 7500 // 7.5fps +#define SENSOR_FULLRES_H_FPS 7500 // 7.5fps +#define SENSOR_720P_FPS 15000 +#define SENSOR_1080P_FPS 0 + +#define SENSOR_REGISTER_LEN 1 // sensor register address bytes +#define SENSOR_VALUE_LEN 1 // sensor register value bytes +static unsigned int SensorConfiguration = (CFG_WhiteBalance|CFG_Effect|CFG_Scene); +static unsigned int SensorChipID[] = {SENSOR_ID}; +/* Sensor Driver Configuration End */ + + +#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) +#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) + +#define SensorRegVal(a,b) CONS4(SensorReg,SENSOR_REGISTER_LEN,Val,SENSOR_VALUE_LEN)(a,b) +#define sensor_write(client,reg,v) CONS4(sensor_write_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v)) +#define sensor_read(client,reg,v) CONS4(sensor_read_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v)) +#define sensor_write_array generic_sensor_write_array + +struct sensor_parameter +{ + unsigned int PreviewDummyPixels; + unsigned int CaptureDummyPixels; + unsigned int preview_exposure; + unsigned short int preview_line_width; + unsigned short int preview_gain; + + unsigned short int PreviewPclk; + unsigned short int CapturePclk; + char awb[6]; +}; + +struct specific_sensor{ + struct generic_sensor common_sensor; + //define user data below + struct sensor_parameter parameter; + u16 shutter; + +}; + +/* +* The follow setting need been filled. +* +* Must Filled: +* sensor_init_data : Sensor initial setting; +* sensor_fullres_lowfps_data : Sensor full resolution setting with best auality, recommand for video; +* sensor_preview_data : Sensor preview resolution setting, recommand it is vga or svga; +* sensor_softreset_data : Sensor software reset register; +* sensor_check_id_data : Sensir chip id register; +* +* Optional filled: +* sensor_fullres_highfps_data: Sensor full resolution setting with high framerate, recommand for video; +* sensor_720p: Sensor 720p setting, it is for video; +* sensor_1080p: Sensor 1080p setting, it is for video; +* +* :::::WARNING::::: +* The SensorEnd which is the setting end flag must be filled int the last of each setting; +*/ + +/* Sensor initial setting */ +static struct rk_sensor_reg sensor_init_data[] = +{ + //SENSORDB("GC2155_Sensor_Init"}, + {0xfe , 0xf0}, + {0xfe , 0xf0}, + {0xfe , 0xf0}, + {0xfc , 0x06}, + {0xf6 , 0x00}, + {0xf7 , 0x1d}, + {0xf8 , 0x84}, + {0xfa , 0x00}, + {0xf9 , 0xfe}, + {0xf2 , 0x00}, +///////////////////////////////////////////////// +//////////////////ISP reg////////////////////// +//////////////////////////////////////////////////// + {0xfe , 0x00}, + {0x03 , 0x04}, + {0x04 , 0xe2}, + {0x09 , 0x00}, + {0x0a , 0x00}, + {0x0b , 0x00}, + {0x0c , 0x00}, + {0x0d , 0x04}, + {0x0e , 0xc0}, + {0x0f , 0x06}, + {0x10 , 0x50}, + {0x12 , 0x2e}, + {0x17 , 0x14}, // mirror + {0x18 , 0x02}, + {0x19 , 0x0e}, + {0x1a , 0x01}, + {0x1b , 0x4b}, + {0x1c , 0x07}, + {0x1d , 0x10}, + {0x1e , 0x98}, + {0x1f , 0x78}, + {0x20 , 0x05}, + {0x21 , 0x40}, + {0x22 , 0xf0}, + {0x24 , 0x16}, + {0x25 , 0x01}, + {0x26 , 0x10}, + {0x2d , 0x40}, + {0x30 , 0x01}, + {0x31 , 0x90}, + {0x33 , 0x04}, + {0x34 , 0x01}, + ///////////////////////////////////////////////// + //////////////////ISP reg//////////////////// + ///////////////////////////////////////////////// + {0xfe , 0x00}, + {0x80 , 0xff}, + {0x81 , 0x2c}, + {0x82 , 0xfa}, + {0x83 , 0x00}, + {0x84 , 0x00}, //yuv 01 + {0x85 , 0x08}, + {0x86 , 0x02}, + {0x89 , 0x03}, + {0x8a , 0x00}, + {0x8b , 0x00}, + {0xb0 , 0x55}, + {0xc3 , 0x11}, //00 + {0xc4 , 0x20}, + {0xc5 , 0x30}, + {0xc6 , 0x38}, + {0xc7 , 0x40}, + {0xec , 0x02}, + {0xed , 0x04}, + {0xee , 0x60}, + {0xef , 0x90}, + {0xb6 , 0x01}, + {0x90 , 0x01}, + {0x91 , 0x00}, + {0x92 , 0x00}, + {0x93 , 0x00}, + {0x94 , 0x00}, + {0x95 , 0x04}, + {0x96 , 0xb0}, + {0x97 , 0x06}, + {0x98 , 0x40}, + ///////////////////////////////////////// + /////////// BLK //////////////////////// + ///////////////////////////////////////// + {0xfe , 0x00}, + {0x18 , 0x02}, + {0x40 , 0x42}, + {0x41 , 0x00}, + {0x43 , 0x5b},//0x54 + {0x5e , 0x00}, + {0x5f , 0x00}, + {0x60 , 0x00}, + {0x61 , 0x00}, + {0x62 , 0x00}, + {0x63 , 0x00}, + {0x64 , 0x00}, + {0x65 , 0x00}, + {0x66 , 0x20}, + {0x67 , 0x20}, + {0x68 , 0x20}, + {0x69 , 0x20}, + {0x6a , 0x08}, + {0x6b , 0x08}, + {0x6c , 0x08}, + {0x6d , 0x08}, + {0x6e , 0x08}, + {0x6f , 0x08}, + {0x70 , 0x08}, + {0x71 , 0x08}, + {0x72 , 0xf0}, + {0x7e , 0x3c}, + {0x7f , 0x00}, + {0xfe , 0x00}, + //////////////////////////////////////// + /////////// AEC //////////////////////// + //////////////////////////////////////// + {0xfe , 0x01}, + {0x01 , 0x08}, + {0x02 , 0xc0}, + {0x03 , 0x04}, + {0x04 , 0x90}, + {0x05 , 0x30}, + {0x06 , 0x98}, + {0x07 , 0x28}, + {0x08 , 0x6c}, + {0x09 , 0x00}, + {0x0a , 0xc2}, + {0x0b , 0x11}, + {0x0c , 0x10}, + {0x13 , 0x2d}, + {0x17 , 0x00}, + {0x1c , 0x11}, + {0x1e , 0x61}, + {0x1f , 0x30}, + {0x20 , 0x40}, + {0x22 , 0x80}, + {0x23 , 0x20}, + + {0x12 , 0x35}, + {0x15 , 0x50}, + {0x10 , 0x31}, + {0x3e , 0x28}, + {0x3f , 0xe0}, + {0x40 , 0xe0}, + {0x41 , 0x08}, + + {0xfe , 0x02}, + {0x0f , 0x05}, + ///////////////////////////// + //////// INTPEE ///////////// + ///////////////////////////// + {0xfe , 0x02}, + {0x90 , 0x6c}, + {0x91 , 0x03}, + {0x92 , 0xc4}, + {0x97 , 0x64}, + {0x98 , 0x88}, + {0x9d , 0x08}, + {0xa2 , 0x11}, + {0xfe , 0x00}, + ///////////////////////////// + //////// DNDD/////////////// + ///////////////////////////// + {0xfe , 0x02}, + {0x80 , 0xc1}, + {0x81 , 0x08}, + {0x82 , 0x05}, + {0x83 , 0x04}, + {0x84 , 0x0a}, + {0x86 , 0x80}, + {0x87 , 0x30}, + {0x88 , 0x15}, + {0x89 , 0x80}, + {0x8a , 0x60}, + {0x8b , 0x30}, + ///////////////////////////////////////// + /////////// ASDE //////////////////////// + ///////////////////////////////////////// + {0xfe , 0x01}, + {0x21 , 0x14}, + {0xfe , 0x02}, + {0x3c , 0x06}, + {0x3d , 0x40}, + {0x48 , 0x30}, + {0x49 , 0x06}, + {0x4b , 0x08}, + {0x4c , 0x20}, + {0xa3 , 0x50}, + {0xa4 , 0x30}, + {0xa5 , 0x40}, + {0xa6 , 0x80}, + {0xab , 0x40}, + {0xae , 0x0c}, + {0xb3 , 0x42}, + {0xb4 , 0x24}, + {0xb6 , 0x50}, + {0xb7 , 0x01}, + {0xb9 , 0x28}, + {0xfe , 0x00}, + ///////////////////gamma1//////////////////// + {0xfe , 0x02}, + {0x10 , 0x0d}, + {0x11 , 0x12}, + {0x12 , 0x17}, + {0x13 , 0x1c}, + {0x14 , 0x27}, + {0x15 , 0x34}, + {0x16 , 0x44}, + {0x17 , 0x55}, + {0x18 , 0x6e}, + {0x19 , 0x81}, + {0x1a , 0x91}, + {0x1b , 0x9c}, + {0x1c , 0xaa}, + {0x1d , 0xbb}, + {0x1e , 0xca}, + {0x1f , 0xd5}, + {0x20 , 0xe0}, + {0x21 , 0xe7}, + {0x22 , 0xed}, + {0x23 , 0xf6}, + {0x24 , 0xfb}, + {0x25 , 0xff}, + ///////////////////gamma2//////////////////// + {0xfe , 0x02}, + {0x26 , 0x0d}, + {0x27 , 0x12}, + {0x28 , 0x17}, + {0x29 , 0x1c}, + {0x2a , 0x27}, + {0x2b , 0x34}, + {0x2c , 0x44}, + {0x2d , 0x55}, + {0x2e , 0x6e}, + {0x2f , 0x81}, + {0x30 , 0x91}, + {0x31 , 0x9c}, + {0x32 , 0xaa}, + {0x33 , 0xbb}, + {0x34 , 0xca}, + {0x35 , 0xd5}, + {0x36 , 0xe0}, + {0x37 , 0xe7}, + {0x38 , 0xed}, + {0x39 , 0xf6}, + {0x3a , 0xfb}, + {0x3b , 0xff}, + /////////////////////////////////////////////// + ///////////YCP /////////////////////// + /////////////////////////////////////////////// + {0xfe , 0x02}, + {0xd1 , 0x28}, + {0xd2 , 0x28}, + {0xdd , 0x14}, + {0xde , 0x88}, + {0xed , 0x80}, + //////////////////////////// + //////// LSC /////////////// + //////////////////////////// + {0xfe , 0x01}, + {0xc2 , 0x1f}, + {0xc3 , 0x13}, + {0xc4 , 0x0e}, + {0xc8 , 0x16}, + {0xc9 , 0x0f}, + {0xca , 0x0c}, + {0xbc , 0x52}, + {0xbd , 0x2c}, + {0xbe , 0x27}, + {0xb6 , 0x47}, + {0xb7 , 0x32}, + {0xb8 , 0x30}, + {0xc5 , 0x00}, + {0xc6 , 0x00}, + {0xc7 , 0x00}, + {0xcb , 0x00}, + {0xcc , 0x00}, + {0xcd , 0x00}, + {0xbf , 0x0e}, + {0xc0 , 0x00}, + {0xc1 , 0x00}, + {0xb9 , 0x08}, + {0xba , 0x00}, + {0xbb , 0x00}, + {0xaa , 0x0a}, + {0xab , 0x0c}, + {0xac , 0x0d}, + {0xad , 0x02}, + {0xae , 0x06}, + {0xaf , 0x05}, + {0xb0 , 0x00}, + {0xb1 , 0x05}, + {0xb2 , 0x02}, + {0xb3 , 0x04}, + {0xb4 , 0x04}, + {0xb5 , 0x05}, + {0xd0 , 0x00}, + {0xd1 , 0x00}, + {0xd2 , 0x00}, + {0xd6 , 0x02}, + {0xd7 , 0x00}, + {0xd8 , 0x00}, + {0xd9 , 0x00}, + {0xda , 0x00}, + {0xdb , 0x00}, + {0xd3 , 0x00}, + {0xd4 , 0x00}, + {0xd5 , 0x00}, + {0xa4 , 0x04}, + {0xa5 , 0x00}, + {0xa6 , 0x77}, + {0xa7 , 0x77}, + {0xa8 , 0x77}, + {0xa9 , 0x77}, + {0xa1 , 0x80}, + {0xa2 , 0x80}, + + {0xfe , 0x01}, + {0xdc , 0x35}, + {0xdd , 0x28}, + {0xdf , 0x0d}, + {0xe0 , 0x70}, + {0xe1 , 0x78}, + {0xe2 , 0x70}, + {0xe3 , 0x78}, + {0xe6 , 0x90}, + {0xe7 , 0x70}, + {0xe8 , 0x90}, + {0xe9 , 0x70}, + {0xfe , 0x00}, + /////////////////////////////////////////////// + /////////// AWB//////////////////////// + /////////////////////////////////////////////// + {0xfe , 0x01}, + {0x4f , 0x00}, + {0x4f , 0x00}, + {0x4b , 0x01}, + {0x4f , 0x00}, + {0x4c , 0x01}, + {0x4d , 0x71}, + {0x4e , 0x02}, + {0x4c , 0x01}, + {0x4d , 0x91}, + {0x4e , 0x02}, + {0x4c , 0x01}, + {0x4d , 0x50}, + {0x4e , 0x02}, + {0x4c , 0x01}, + {0x4d , 0x70}, + {0x4e , 0x02}, + {0x4c , 0x01}, + {0x4d , 0x90}, + {0x4e , 0x02}, + {0x4c , 0x01}, + {0x4d , 0xb0}, + {0x4e , 0x02}, + {0x4c , 0x01}, + {0x4d , 0xd0}, + {0x4e , 0x02}, + {0x4c , 0x01}, + {0x4d , 0x4f}, + {0x4e , 0x02}, + {0x4c , 0x01}, + {0x4d , 0x6f}, + {0x4e , 0x02}, + {0x4c , 0x01}, + {0x4d , 0x8f}, + {0x4e , 0x02}, + {0x4c , 0x01}, + {0x4d , 0xaf}, + {0x4e , 0x02}, + {0x4c , 0x01}, + {0x4d , 0xcf}, + {0x4e , 0x02}, + {0x4c , 0x01}, + {0x4d , 0x6e}, + {0x4e , 0x03}, + {0x4c , 0x01}, + {0x4d , 0x8e}, + {0x4e , 0x03}, + {0x4c , 0x01}, + {0x4d , 0xae}, + {0x4e , 0x03}, + {0x4c , 0x01}, + {0x4d , 0xce}, + {0x4e , 0x03}, + {0x4c , 0x01}, + {0x4d , 0x4d}, + {0x4e , 0x03}, + {0x4c , 0x01}, + {0x4d , 0x6d}, + {0x4e , 0x03}, + {0x4c , 0x01}, + {0x4d , 0x8d}, + {0x4e , 0x03}, + {0x4c , 0x01}, + {0x4d , 0xad}, + {0x4e , 0x03}, + {0x4c , 0x01}, + {0x4d , 0xcd}, + {0x4e , 0x03}, + {0x4c , 0x01}, + {0x4d , 0x4c}, + {0x4e , 0x03}, + {0x4c , 0x01}, + {0x4d , 0x6c}, + {0x4e , 0x03}, + {0x4c , 0x01}, + {0x4d , 0x8c}, + {0x4e , 0x03}, + {0x4c , 0x01}, + {0x4d , 0xac}, + {0x4e , 0x03}, + {0x4c , 0x01}, + {0x4d , 0xcc}, + {0x4e , 0x03}, + {0x4c , 0x01}, + {0x4d , 0xec}, + {0x4e , 0x03}, + {0x4c , 0x01}, + {0x4d , 0x4b}, + {0x4e , 0x03}, + {0x4c , 0x01}, + {0x4d , 0x6b}, + {0x4e , 0x03}, + {0x4c , 0x01}, + {0x4d , 0x8b}, + {0x4e , 0x03}, + {0x4c , 0x01}, + {0x4d , 0xab}, + {0x4e , 0x03}, + {0x4c , 0x01}, + {0x4d , 0x8a}, + {0x4e , 0x04}, + {0x4c , 0x01}, + {0x4d , 0xaa}, + {0x4e , 0x04}, + {0x4c , 0x01}, + {0x4d , 0xca}, + {0x4e , 0x04}, + {0x4c , 0x01}, + {0x4d , 0xa9}, + {0x4e , 0x04}, + {0x4c , 0x01}, + {0x4d , 0xc9}, + {0x4e , 0x04}, + {0x4c , 0x01}, + {0x4d , 0xcb}, + {0x4e , 0x05}, + {0x4c , 0x01}, + {0x4d , 0xeb}, + {0x4e , 0x05}, + {0x4c , 0x02}, + {0x4d , 0x0b}, + {0x4e , 0x05}, + {0x4c , 0x02}, + {0x4d , 0x2b}, + {0x4e , 0x05}, + {0x4c , 0x02}, + {0x4d , 0x4b}, + {0x4e , 0x05}, + {0x4c , 0x01}, + {0x4d , 0xea}, + {0x4e , 0x05}, + {0x4c , 0x02}, + {0x4d , 0x0a}, + {0x4e , 0x05}, + {0x4c , 0x02}, + {0x4d , 0x2a}, + {0x4e , 0x05}, + {0x4c , 0x02}, + {0x4d , 0x6a}, + {0x4e , 0x06}, + {0x4c , 0x02}, + {0x4d , 0x29}, + {0x4e , 0x06}, + {0x4c , 0x02}, + {0x4d , 0x49}, + {0x4e , 0x06}, + {0x4c , 0x02}, + {0x4d , 0x69}, + {0x4e , 0x06}, + {0x4c , 0x02}, + {0x4d , 0x89}, + {0x4e , 0x06}, + {0x4c , 0x02}, + {0x4d , 0xa9}, + {0x4e , 0x06}, + {0x4c , 0x02}, + {0x4d , 0xc9}, + {0x4e , 0x06}, + {0x4c , 0x02}, + {0x4d , 0x48}, + {0x4e , 0x06}, + {0x4c , 0x02}, + {0x4d , 0x68}, + {0x4e , 0x06}, + {0x4c , 0x03}, + {0x4d , 0x09}, + {0x4e , 0x07}, + {0x4c , 0x02}, + {0x4d , 0xa8}, + {0x4e , 0x07}, + {0x4c , 0x02}, + {0x4d , 0xc8}, + {0x4e , 0x07}, + {0x4c , 0x02}, + {0x4d , 0xe8}, + {0x4e , 0x07}, + {0x4c , 0x03}, + {0x4d , 0x08}, + {0x4e , 0x07}, + {0x4c , 0x03}, + {0x4d , 0x28}, + {0x4e , 0x07}, + {0x4c , 0x02}, + {0x4d , 0x87}, + {0x4e , 0x07}, + {0x4c , 0x02}, + {0x4d , 0xa7}, + {0x4e , 0x07}, + {0x4c , 0x02}, + {0x4d , 0xc7}, + {0x4e , 0x07}, + {0x4c , 0x02}, + {0x4d , 0xe7}, + {0x4e , 0x07}, + {0x4c , 0x03}, + {0x4d , 0x07}, + {0x4e , 0x07}, + {0x4f , 0x01}, + {0xfe , 0x01}, + + {0x50 , 0x80}, + {0x51 , 0xa8}, + {0x52 , 0x57}, + {0x53 , 0x38}, + {0x54 , 0xc7}, + {0x56 , 0x0e}, + {0x58 , 0x08}, + {0x5b , 0x00}, + {0x5c , 0x74}, + {0x5d , 0x8b}, + {0x61 , 0xd3}, + {0x62 , 0x90}, + {0x63 , 0xaa}, + {0x65 , 0x04}, + {0x67 , 0xb2}, + {0x68 , 0xac}, + {0x69 , 0x00}, + {0x6a , 0xb2}, + {0x6b , 0xac}, + {0x6c , 0xdc}, + {0x6d , 0xb0}, + {0x6e , 0x30}, + {0x6f , 0x40}, + {0x70 , 0x05}, + {0x71 , 0x80}, + {0x72 , 0x80}, + {0x73 , 0x30}, + {0x74 , 0x01}, + {0x75 , 0x01}, + {0x7f , 0x08}, + {0x76 , 0x70}, + {0x77 , 0x48}, + {0x78 , 0xa0}, + {0xfe , 0x00}, + ////////////////////////////////////////// + ///////////CC//////////////////////// + ////////////////////////////////////////// + {0xfe , 0x02}, + {0xc0 , 0x01}, + {0xc1 , 0x4a}, + {0xc2 , 0xf3}, + {0xc3 , 0xfc}, + {0xc4 , 0xe4}, + {0xc5 , 0x48}, + {0xc6 , 0xec}, + {0xc7 , 0x45}, + {0xc8 , 0xf8}, + {0xc9 , 0x02}, + {0xca , 0xfe}, + {0xcb , 0x42}, + {0xcc , 0x00}, + {0xcd , 0x45}, + {0xce , 0xf0}, + {0xcf , 0x00}, + {0xe3 , 0xf0}, + {0xe4 , 0x45}, + {0xe5 , 0xe8}, + ////////////////////////////////////////// + ///////////ABS //////////////////// + ////////////////////////////////////////// + {0xfe , 0x01}, + {0x9f , 0x42}, + {0xfe , 0x00}, + + //////////////frame rate 50Hz///////// +#if 1 + {0xfe , 0x00}, + {0x05 , 0x01}, + {0x06 , 0x56}, + {0x07 , 0x00}, + {0x08 , 0x32}, + {0xfe , 0x01}, + {0x25 , 0x00}, + {0x26 , 0xfa}, + {0x27 , 0x04}, + {0x28 , 0xe2}, //20fps + {0x29 , 0x06}, + {0x2a , 0xd6}, //16fps + {0x2b , 0x07}, + {0x2c , 0xd0}, //12fps + {0x2d , 0x0b}, + {0x2e , 0xb8}, //8fps + {0xfe , 0x00}, +#else + //////////////frame rate 50Hz + {0xfe, 0x00}, + {0x05, 0x02}, + {0x06, 0x2d}, + {0x07, 0x00}, + {0x08, 0xa0}, + {0xfe, 0x01}, + {0x25, 0x00}, + {0x26, 0xd4}, + {0x27, 0x04}, + {0x28, 0xf8}, + {0x29, 0x08}, + {0x2a, 0x48}, + {0x2b, 0x0a}, + {0x2c, 0xc4}, + {0x2d, 0x0f}, + {0x2e, 0xbc}, + {0xfe, 0x00}, +#endif + + ///////GC2155_Sensor_SVGA//// + {0xfe , 0x00}, + {0xfa , 0x00}, + {0xfd , 0x01}, + //// crop window + {0xfe , 0x00}, + {0x90 , 0x01}, + {0x91 , 0x00}, + {0x92 , 0x00}, + {0x93 , 0x00}, + {0x94 , 0x00}, + {0x95 , 0x02}, + {0x96 , 0x58}, + {0x97 , 0x03}, + {0x98 , 0x20}, + {0x99 , 0x11}, + {0x9a , 0x06}, + //// AWB + {0xfe , 0x00}, + {0xec , 0x01}, + {0xed , 0x02}, + {0xee , 0x30}, + {0xef , 0x48}, + {0xfe , 0x01}, + {0x74 , 0x00}, + //// AEC + {0xfe , 0x01}, + {0x01 , 0x04}, + {0x02 , 0x60}, + {0x03 , 0x02}, + {0x04 , 0x48}, + {0x05 , 0x18}, + {0x06 , 0x4c}, + {0x07 , 0x14}, + {0x08 , 0x36}, + {0x0a , 0xc0}, + {0x21 , 0x14}, + {0xfe , 0x00}, + //// gamma + {0xfe , 0x00}, + {0xc3 , 0x11}, + {0xc4 , 0x20}, + {0xc5 , 0x30}, + {0xfe , 0x00}, +////////svga setting end////// + + +////////////////////////////////////////// +///////////OUTPUT //////////////////// +////////////////////////////////////////// + {0xfe , 0x00}, + {0xf2 , 0x0f}, + + SensorEnd +}; +/* Senor full resolution setting: recommand for capture */ +static struct rk_sensor_reg sensor_fullres_lowfps_data[] ={ + //SENSORDB("GC2155_Sensor_2M"}, + {0xfe , 0x00}, + {0xb6 , 0x00}, + {0xfa , 0x11}, + {0xfd , 0x00}, + //// crop window + {0xfe , 0x00}, + {0x90 , 0x01}, + {0x91 , 0x00}, + {0x92 , 0x00}, + {0x93 , 0x00}, + {0x94 , 0x00}, + {0x95 , 0x04}, + {0x96 , 0xb0}, + {0x97 , 0x06}, + {0x98 , 0x40}, + {0x99 , 0x11}, + {0x9a , 0x06}, + + {0x9b , 0x00}, + {0x9c , 0x00}, + {0x9d , 0x00}, + {0x9e , 0x00}, + {0x9f , 0x00}, + {0xa0 , 0x00}, + {0xa1 , 0x00}, + {0xa2 ,0x00}, + + //// AWB + {0xfe , 0x00}, + {0xec , 0x02}, + {0xed , 0x04}, + {0xee , 0x60}, + {0xef , 0x90}, + {0xfe , 0x01}, + {0x74 , 0x01}, + //// AEC + {0xfe , 0x01}, + {0x01 , 0x08}, + {0x02 , 0xc0}, + {0x03 , 0x04}, + {0x04 , 0x90}, + {0x05 , 0x30}, + {0x06 , 0x98}, + {0x07 , 0x28}, + {0x08 , 0x6c}, + {0x0a , 0xc2}, + {0x21 , 0x15}, //if 0xfa=11,then 0x21=15;else if 0xfa=00,then 0x21=14 + {0xfe , 0x00}, + //// gamma + {0xfe , 0x00}, + {0xc3 , 0x00}, //if shutter/2 when capture,then exp_gamma_th/2 + {0xc4 , 0x90}, + {0xc5 , 0x98}, + {0xfe , 0x00}, + + SensorEnd +}; + +/* Senor full resolution setting: recommand for video */ +static struct rk_sensor_reg sensor_fullres_highfps_data[] ={ + SensorEnd +}; +/* Preview resolution setting*/ +static struct rk_sensor_reg sensor_preview_data[] = +{ + //SENSORDB("GC2155_Sensor_SVGA"}, + {0xfe , 0x00}, + {0xb6 , 0x01}, + {0xfa , 0x00}, + {0xfd , 0x01}, + +////window setting///// + {0x09 , 0x00}, + {0x0a , 0x00}, + {0x0b , 0x00}, + {0x0c , 0x00}, + {0x0d , 0x04}, + {0x0e , 0xc0}, + {0x0f , 0x06}, + {0x10 , 0x50}, + + //// crop window + {0xfe , 0x00}, + {0x90 , 0x01}, + {0x91 , 0x00}, + {0x92 , 0x00}, + {0x93 , 0x00}, + {0x94 , 0x00}, + {0x95 , 0x02}, + {0x96 , 0x58}, + {0x97 , 0x03}, + {0x98 , 0x20}, + {0x99 , 0x11}, + {0x9a , 0x06}, + {0x9b , 0x00}, + {0x9c , 0x00}, + {0x9d , 0x00}, + {0x9e , 0x00}, + {0x9f , 0x00}, + {0xa0 , 0x00}, + {0xa1 , 0x00}, + {0xa2 ,0x00}, + + //// AWB + {0xfe , 0x00}, + {0xec , 0x01}, + {0xed , 0x02}, + {0xee , 0x30}, + {0xef , 0x48}, + {0xfe , 0x01}, + {0x74 , 0x00}, + //// AEC + {0xfe , 0x01}, + {0x01 , 0x04}, + {0x02 , 0x60}, + {0x03 , 0x02}, + {0x04 , 0x48}, + {0x05 , 0x18}, + {0x06 , 0x4c}, + {0x07 , 0x14}, + {0x08 , 0x36}, + {0x0a , 0xc0}, + {0x21 , 0x14}, + {0xfe , 0x00}, + //// gamma + {0xfe , 0x00}, + {0xc3 , 0x11}, + {0xc4 , 0x20}, + {0xc5 , 0x30}, + {0xfe , 0x00}, + +//////////////frame rate 50Hz///////// +#if 1 + {0xfe , 0x00}, + {0x05 , 0x01}, + {0x06 , 0x56}, + {0x07 , 0x00}, + {0x08 , 0x32}, + {0xfe , 0x01}, + {0x25 , 0x00}, + {0x26 , 0xfa}, + {0x27 , 0x04}, + {0x28 , 0xe2}, //20fps + {0x29 , 0x06}, + {0x2a , 0xd6}, //16fps + {0x2b , 0x07}, + {0x2c , 0xd0}, //12fps + {0x2d , 0x0b}, + {0x2e , 0xb8}, //8fps + {0xfe , 0x00}, +#else + //////////////frame rate 50Hz + {0xfe, 0x00}, + {0x05, 0x02}, + {0x06, 0x2d}, + {0x07, 0x00}, + {0x08, 0xa0}, + {0xfe, 0x01}, + {0x25, 0x00}, + {0x26, 0xd4}, + {0x27, 0x04}, + {0x28, 0xf8}, + {0x29, 0x08}, + {0x2a, 0x48}, + {0x2b, 0x0a}, + {0x2c, 0xc4}, + {0x2d, 0x0f}, + {0x2e, 0xbc}, + {0xfe, 0x00}, +#endif + SensorEnd + +}; +/* 1280x720 */ +static struct rk_sensor_reg sensor_720p[]={ + SensorEnd +}; + +/* 1920x1080 */ +static struct rk_sensor_reg sensor_1080p[]={ + SensorEnd +}; + + +static struct rk_sensor_reg sensor_softreset_data[]={ + SensorRegVal(0xfe,80), + SensorWaitMs(5), + SensorEnd +}; + +static struct rk_sensor_reg sensor_check_id_data[]={ + SensorRegVal(0xf0,0), + SensorRegVal(0xf1,0), + SensorEnd +}; +/* +* The following setting must been filled, if the function is turn on by CONFIG_SENSOR_xxxx +*/ +static struct rk_sensor_reg sensor_WhiteB_Auto[]= +{ + {0xfe , 0x00}, + {0x82 , 0xfe}, + SensorEnd +}; +/* Cloudy Colour Temperature : 6500K - 8000K */ +static struct rk_sensor_reg sensor_WhiteB_Cloudy[]= +{ + {0xfe , 0x00}, + {0x82 , 0xfc}, + {0xb3 , 0x58}, + {0xb4 , 0x40}, + {0xb5 , 0x50}, + SensorEnd +}; +/* ClearDay Colour Temperature : 5000K - 6500K */ +static struct rk_sensor_reg sensor_WhiteB_ClearDay[]= +{ + //Sunny + {0xfe , 0x00}, + {0x82 , 0xfc}, + {0xb3 , 0x70}, + {0xb4 , 0x40}, + {0xb5 , 0x50}, + + SensorEnd +}; +/* Office Colour Temperature : 3500K - 5000K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]= +{ + //Office + {0xfe, 0x00}, + {0x82, 0xfc}, + {0xb3, 0x50}, + {0xb4, 0x40}, + {0xb5, 0xa8}, + SensorEnd + +}; +/* Home Colour Temperature : 2500K - 3500K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]= +{ + //Home + {0xfe, 0x00}, + {0x82, 0xfc}, + {0xb3, 0x50}, + {0xb4, 0x40}, + {0xb5, 0xa8}, + SensorEnd +}; + +static struct rk_sensor_reg *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_Cloudy,sensor_WhiteB_ClearDay, + sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2,NULL, +}; + +static struct rk_sensor_reg sensor_Brightness0[]= +{ + // Brightness -2 + + {0xfe,0x01}, + {0x13,0x10}, + {0xfe,0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness1[]= +{ + // Brightness -1 + + {0xfe,0x01}, + {0x13,0x20}, + {0xfe,0x00}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness2[]= +{ + // Brightness 0 + + {0xfe,0x01}, + {0x13,0x30}, + {0xfe,0x00}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness3[]= +{ + // Brightness +1 + {0xfe,0x01}, + {0x13,0x40}, + {0xfe,0x00}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness4[]= +{ + // Brightness +2 + {0xfe,0x01}, + {0x13,0x45}, + {0xfe,0x00}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness5[]= +{ + // Brightness +3 + {0xfe,0x01}, + {0x13,0x50}, + {0xfe,0x00}, + SensorEnd +}; +static struct rk_sensor_reg *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3, + sensor_Brightness4, sensor_Brightness5,NULL, +}; + +static struct rk_sensor_reg sensor_Effect_Normal[] = +{ + {0xfe, 0x00}, + {0x83, 0xe0}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_WandB[] = +{ + {0xfe, 0x00}, + {0x83, 0x12}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Sepia[] = +{ + {0xfe, 0x00}, + {0x83, 0x82}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Negative[] = +{ + //Negative + {0xfe, 0x00}, + {0x83, 0x01}, + SensorEnd +}; +static struct rk_sensor_reg sensor_Effect_Bluish[] = +{ + // Bluish + {0xfe, 0x00}, + {0x83, 0x62}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Green[] = +{ + // Greenish + {0xfe, 0x00}, + {0x83, 0x52}, + SensorEnd +}; +static struct rk_sensor_reg *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia, + sensor_Effect_Bluish, sensor_Effect_Green,NULL, +}; + +static struct rk_sensor_reg sensor_Exposure0[]= +{ + {0xfe,0x01}, + {0x13,0x20}, + {0xfe,0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure1[]= +{ + + {0xfe,0x01}, + {0x13,0x28}, + {0xfe,0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure2[]= +{ + {0xfe,0x01}, + {0x13,0x30}, + {0xfe,0x00}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure3[]= +{ + {0xfe,0x01}, + {0x13,0x35}, + {0xfe,0x00}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure4[]= +{ + {0xfe,0x01}, + {0x13,0x48}, + {0xfe,0x00}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure5[]= +{ + {0xfe,0x01}, + {0x13,0x50}, + {0xfe,0x00}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure6[]= +{ + {0xfe,0x01}, + {0x13,0x58}, + {0xfe,0x00}, + + SensorEnd +}; + +static struct rk_sensor_reg *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3, + sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL, +}; + +static struct rk_sensor_reg sensor_Saturation0[]= +{ + SensorEnd +}; + +static struct rk_sensor_reg sensor_Saturation1[]= +{ + SensorEnd +}; + +static struct rk_sensor_reg sensor_Saturation2[]= +{ + SensorEnd +}; +static struct rk_sensor_reg *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,}; + +static struct rk_sensor_reg sensor_Contrast0[]= +{ + //Contrast -3 + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast1[]= +{ + //Contrast -2 + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast2[]= +{ + // Contrast -1 + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast3[]= +{ + //Contrast 0 + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast4[]= +{ + //Contrast +1 + + SensorEnd +}; + + +static struct rk_sensor_reg sensor_Contrast5[]= +{ + //Contrast +2 + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast6[]= +{ + //Contrast +3 + + SensorEnd +}; +static struct rk_sensor_reg *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3, + sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL, +}; +static struct rk_sensor_reg sensor_SceneAuto[] = +{ + {0xfe,0x01}, + + {0x3c,0x40}, + {0xfe,0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_SceneNight[] = +{ + {0xfe,0x01}, + + {0x3c,0x60}, + {0xfe,0x00}, + SensorEnd +}; +static struct rk_sensor_reg *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,}; + +static struct rk_sensor_reg sensor_Zoom0[] = +{ + SensorEnd +}; + +static struct rk_sensor_reg sensor_Zoom1[] = +{ + SensorEnd +}; + +static struct rk_sensor_reg sensor_Zoom2[] = +{ + SensorEnd +}; + + +static struct rk_sensor_reg sensor_Zoom3[] = +{ + SensorEnd +}; +static struct rk_sensor_reg *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,}; + +/* +* User could be add v4l2_querymenu in sensor_controls by new_usr_v4l2menu +*/ +static struct v4l2_querymenu sensor_menus[] = +{ +}; +/* +* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl +*/ +static struct sensor_v4l2ctrl_usr_s sensor_controls[] = +{ +}; + +//MUST define the current used format as the first item +static struct rk_sensor_datafmt sensor_colour_fmts[] = { + {MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG} +}; + +/* +********************************************************** +* Following is local code: +* +* Please codeing your program here +********************************************************** +*/ +/* +********************************************************** +* Following is callback +* If necessary, you could coding these callback +********************************************************** +*/ +/* +* the function is called in open sensor +*/ +static int sensor_activate_cb(struct i2c_client *client) +{ + return 0; +} +/* +* the function is called in close sensor +*/ +static int sensor_deactivate_cb(struct i2c_client *client) +{ + //sensor_write(client, 0xfe, 0xf0); + //sensor_write(client, 0xfe, 0xf0); + //sensor_write(client, 0xfe, 0xf0); + //sensor_write(client, 0xfa, 0x73); + //sensor_write(client, 0x24, 0x00); + return 0; +} +/* +* the function is called before sensor register setting in VIDIOC_S_FMT +*/ +static unsigned int shutter_h=0,shutter_l=0,cap=0; +static int sensor_s_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture) +{ + char value; + unsigned int pid=0,shutter,temp_reg; + + if ((mf->width == 800 && mf->height == 600)&&(cap==1)) + { + cap=0; + sensor_write(client, 0xb6, 0x00); // AEC off + sensor_write(client, 0x03, shutter_h); + sensor_write(client, 0x04, shutter_l); + msleep(50); + printk("set preview for rewrite 0x03"); + } + if(mf->width == 1600 && mf->height == 1200){ + cap=1; + sensor_write(client, 0xfe, 0x00); + sensor_write(client, 0xb6, 0x00); + sensor_read(client, 0x03, &value); + shutter_h=value; + pid |= (value << 8); + sensor_read(client, 0x04, &value); + shutter_l=value; + pid |= (value & 0xff); + shutter=pid; + + temp_reg= shutter/2; + + if(temp_reg < 1) temp_reg = 1; + + sensor_write(client, 0x03, ((temp_reg>>8)&0x1f)); + sensor_write(client, 0x04, (temp_reg&0xff)); + } + + return 0; +} +/* +* the function is called after sensor register setting finished in VIDIOC_S_FMT +*/ +static int sensor_s_fmt_cb_bh (struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture) +{ + return 0; +} +static int sensor_softrest_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series) +{ + return 0; +} +static int sensor_check_id_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series) +{ + return 0; +} +static int sensor_try_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf) +{ + return 0; +} +static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg) +{ + //struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (pm_msg.event == PM_EVENT_SUSPEND) { + SENSOR_DG("Suspend"); + + } else { + SENSOR_TR("pm_msg.event(0x%x) != PM_EVENT_SUSPEND\n",pm_msg.event); + return -EINVAL; + } + return 0; +} + +static int sensor_resume(struct soc_camera_device *icd) +{ + + SENSOR_DG("Resume"); + + return 0; + +} +static int sensor_mirror_cb (struct i2c_client *client, int mirror) +{ + char val; + int err = 0; + + SENSOR_DG("mirror: %d",mirror); + if (mirror) { + sensor_write(client, 0xfe, 0); + err = sensor_read(client, 0x17, &val); + val-=4; + if (err == 0) { + if((val & 0x1) == 0){ + err = sensor_write(client, 0x17, ((val |0x1)+4)); + } + else + err = sensor_write(client, 0x17, ((val & 0xfe)+4)); + } + } else { + //do nothing + } + return err; +} +/* +* the function is v4l2 control V4L2_CID_HFLIP callback +*/ +static int sensor_v4l2ctrl_mirror_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, + struct v4l2_ext_control *ext_ctrl) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_mirror_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_mirror failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_mirror success, value:0x%x",ext_ctrl->value); + return 0; +} + +static int sensor_flip_cb(struct i2c_client *client, int flip) +{ + char val; + int err = 0; + + SENSOR_DG("flip: %d",flip); + if (flip) { + sensor_write(client, 0xfe, 0); + err = sensor_read(client, 0x17, &val); + val-=4; + if (err == 0) { + if((val & 0x2) == 0){ + err = sensor_write(client, 0x17, ((val |0x2)+4)); + } + else { + err = sensor_write(client, 0x17, ((val & 0xfc)+4)); + } + } + } else { + //do nothing + } + + return err; +} +/* +* the function is v4l2 control V4L2_CID_VFLIP callback +*/ +static int sensor_v4l2ctrl_flip_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, + struct v4l2_ext_control *ext_ctrl) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_flip_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_flip failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_flip success, value:0x%x",ext_ctrl->value); + return 0; +} +/* +* the functions are focus callbacks +*/ +static int sensor_focus_init_usr_cb(struct i2c_client *client){ + return 0; +} + +static int sensor_focus_af_single_usr_cb(struct i2c_client *client){ + return 0; +} + +static int sensor_focus_af_near_usr_cb(struct i2c_client *client){ + return 0; +} + +static int sensor_focus_af_far_usr_cb(struct i2c_client *client){ + return 0; +} + +static int sensor_focus_af_specialpos_usr_cb(struct i2c_client *client,int pos){ + return 0; +} + +static int sensor_focus_af_const_usr_cb(struct i2c_client *client){ + return 0; +} +static int sensor_focus_af_const_pause_usr_cb(struct i2c_client *client) +{ + return 0; +} +static int sensor_focus_af_close_usr_cb(struct i2c_client *client){ + return 0; +} + +static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client, int *zone_tm_pos) +{ + return 0; +} + +/* +face defect call back +*/ +static int sensor_face_detect_usr_cb(struct i2c_client *client,int on){ + return 0; +} + +/* +* The function can been run in sensor_init_parametres which run in sensor_probe, so user can do some +* initialization in the function. +*/ +static void sensor_init_parameters_user(struct specific_sensor* spsensor,struct soc_camera_device *icd) +{ + return; +} + +/* +* :::::WARNING::::: +* It is not allowed to modify the following code +*/ + +sensor_init_parameters_default_code(); + +sensor_v4l2_struct_initialization(); + +sensor_probe_default_code(); + +sensor_remove_default_code(); + +sensor_driver_default_module_code(); + + + + + diff --git a/drivers/media/video/generic_sensor.c b/drivers/media/video/generic_sensor.c old mode 100755 new mode 100644 index 1e0ee693f5c1..19ebedddaf80 --- a/drivers/media/video/generic_sensor.c +++ b/drivers/media/video/generic_sensor.c @@ -1,3 +1,15 @@ +/* + * Copyright (C) ROCKCHIP, Inc. + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + #include #include #include @@ -60,7 +72,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define CONFIG_SENSOR_I2C_RDWRCHK 0 static const struct rk_sensor_datafmt *generic_sensor_find_datafmt( - enum v4l2_mbus_pixelcode code, const struct rk_sensor_datafmt *fmt, + u32 code, const struct rk_sensor_datafmt *fmt, int n); int sensor_write_reg2val1(struct i2c_client *client, u16 reg,u8 val){ @@ -112,10 +124,7 @@ int generic_sensor_write(struct i2c_client *client,struct rk_sensor_reg* sensor_ int err,cnt = 0,i; u8 buf[6]; struct i2c_msg msg[1]; - u32 i2c_speed; struct generic_sensor *sensor = to_generic_sensor(client); - - i2c_speed = sensor->info_priv.gI2c_speed; err = 0; switch(sensor_reg->reg){ @@ -144,7 +153,6 @@ int generic_sensor_write(struct i2c_client *client,struct rk_sensor_reg* sensor_ msg->addr = client->addr; msg->flags = client->flags; msg->buf = buf; - msg->scl_rate = i2c_speed; /* ddl@rock-chips.com : 100kHz */ // msg->read_type = 0; /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */ msg->len = cnt; cnt = 3; @@ -153,7 +161,6 @@ int generic_sensor_write(struct i2c_client *client,struct rk_sensor_reg* sensor_ debug_printk( "/___________/msg->addr = %x \n",msg->addr); debug_printk( "/___________/msg->flags = %x\n",msg->flags); debug_printk( "/___________/msg->buf = %d\n",msg->buf); - debug_printk( "/___________/msg->scl_rate = %d\n",msg->scl_rate); debug_printk( "/___________/msg->len = %d\n",msg->len); debug_printk( "/___________/client->adapter = %p\n",client->adapter); */ @@ -185,7 +192,6 @@ int generic_sensor_writebuf(struct i2c_client *client, char *buf, int buf_size) msg->addr = client->addr; msg->flags = client->flags; msg->buf = buf; - msg->scl_rate = sensor->info_priv.gI2c_speed; /* ddl@rock-chips.com : 100kHz */ //msg->read_type = 0; msg->len = buf_size; cnt = 3; @@ -281,11 +287,9 @@ int generic_sensor_read(struct i2c_client *client, struct rk_sensor_reg* sensor_ u8 buf_reg[3]; u8 buf_val[3]; struct i2c_msg msg[2]; - u32 i2c_speed; - struct generic_sensor *sensor = to_generic_sensor(client); + struct generic_sensor *sensor = to_generic_sensor(client); debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__); - i2c_speed = sensor->info_priv.gI2c_speed; - + cnt=0; for (i=2; i>=0; i--) { if((sensor_reg->reg_mask) & (0xff<<(i*8))) { @@ -296,7 +300,6 @@ int generic_sensor_read(struct i2c_client *client, struct rk_sensor_reg* sensor_ msg[0].addr = client->addr; msg[0].flags = client->flags; msg[0].buf = buf_reg; - msg[0].scl_rate = i2c_speed; /* ddl@rock-chips.com : 100kHz */ //msg[0].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ msg[0].len = cnt; @@ -312,7 +315,6 @@ int generic_sensor_read(struct i2c_client *client, struct rk_sensor_reg* sensor_ msg[1].flags = client->flags|I2C_M_RD; msg[1].buf = buf_val; msg[1].len = cnt; - msg[1].scl_rate = i2c_speed; /* ddl@rock-chips.com : 100kHz */ //msg[1].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ cnt = 1; @@ -512,7 +514,7 @@ static int sensor_try_fmt(struct i2c_client *client,unsigned int *set_w,unsigned *set_h = tmp_h; //only has the init array if((tmp_w == 10000) && (tmp_index != -1)){ - SENSOR_TR("have not other series meet the requirement except init_serie,array_index = %d",tmp_index); + SENSOR_DG("have not other series meet the requirement except init_serie,array_index = %d", tmp_index); *set_w = sensor->info_priv.sensor_series[tmp_index].gSeq_info.w; *set_h = sensor->info_priv.sensor_series[tmp_index].gSeq_info.h; goto try_end; @@ -560,14 +562,15 @@ int generic_sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf fmt = &(sensor->info_priv.curfmt); mf->code = fmt->code; } - /* ddl@rock-chips.com : It is query max resolution only. */ - if (mf->reserved[6] == 0xfefe5a5a) { - mf->height = sensor->info_priv.max_res.h ; - mf->width = sensor->info_priv.max_res.w; - ret = 0; - SENSOR_DG("Query resolution: %dx%d",mf->width, mf->height); - goto generic_sensor_try_fmt_end; - } + /* ddl@rock-chips.com : It is query max resolution only. */ + if (mf->reserved[6] == 0xfe5a) { + mf->height = sensor->info_priv.max_res.h; + mf->width = sensor->info_priv.max_res.w; + ret = 0; + SENSOR_DG("Query resolution: %dx%d", mf->width, mf->height); + + goto generic_sensor_try_fmt_end; + } //use this to filter unsupported resolutions if (sensor->sensor_cb.sensor_try_fmt_cb_th){ ret = sensor->sensor_cb.sensor_try_fmt_cb_th(client, mf); @@ -596,19 +599,18 @@ generic_sensor_try_fmt_end: int generic_sensor_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *cc) { - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct generic_sensor *sensor = to_generic_sensor(client); - int ret=0; + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct generic_sensor *sensor = to_generic_sensor(client); - cc->bounds.left = 0; - cc->bounds.top = 0; - cc->bounds.width = sensor->info_priv.max_res.w; - cc->bounds.height = sensor->info_priv.max_res.h; - - cc->pixelaspect.denominator = sensor->info_priv.max_res.w; - cc->pixelaspect.numerator = sensor->info_priv.max_res.h; + cc->bounds.left = 0; + cc->bounds.top = 0; + cc->bounds.width = sensor->info_priv.max_res.w; + cc->bounds.height = sensor->info_priv.max_res.h; - return ret; + cc->pixelaspect.denominator = sensor->info_priv.max_res.w; + cc->pixelaspect.numerator = sensor->info_priv.max_res.h; + + return 0; } int generic_sensor_enum_frameintervals(struct v4l2_subdev *sd, struct v4l2_frmivalenum *fival){ @@ -618,7 +620,8 @@ int generic_sensor_enum_frameintervals(struct v4l2_subdev *sd, struct v4l2_frmiv struct generic_sensor *sensor = to_generic_sensor(client); if (fival->height > sensor->info_priv.max_res.h|| fival->width > sensor->info_priv.max_res.w){ - SENSOR_TR("this resolution(%dx%d) isn't support!",fival->width,fival->height); + SENSOR_DG("this resolution(%dx%d) isn't support!", + fival->width, fival->height); err = -1; goto enum_frameintervals_end; } @@ -630,7 +633,10 @@ int generic_sensor_enum_frameintervals(struct v4l2_subdev *sd, struct v4l2_frmiv fival->reserved[1] = (set_w<<16)|set_h; fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; - SENSOR_DG("%dx%d(real:%dx%d) framerate: %d",fival->width,fival->height,set_w,set_h,fival->discrete.denominator); + SENSOR_DG("%dx%d(real:%dx%d) framerate: %d", + fival->width, fival->height, + set_w, set_h, + fival->discrete.denominator); enum_frameintervals_end: return err; } @@ -643,7 +649,7 @@ static enum hrtimer_restart generic_flash_off_func(struct hrtimer *timer){ } /* Find a data format by a pixel code in an array */ static const struct rk_sensor_datafmt *generic_sensor_find_datafmt( - enum v4l2_mbus_pixelcode code, const struct rk_sensor_datafmt *fmt, + u32 code, const struct rk_sensor_datafmt *fmt, int n) { int i; @@ -811,7 +817,6 @@ int generic_sensor_init(struct v4l2_subdev *sd, u32 val) /* ddl@rock-chips.com : i2c speed is config in new_camera_device_ex macro */ if (sensor_device) { - sensor->info_priv.gI2c_speed = sensor_device->i2c_rate; sensor->info_priv.mirror = sensor_device->mirror; } @@ -912,7 +917,8 @@ int generic_sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) struct generic_sensor *sensor = to_generic_sensor(client); struct rk_sensor_sequence *winseqe_set_addr=NULL; struct sensor_v4l2ctrl_info_s *v4l2ctrl_info=NULL; - bool is_capture=(mf->reserved[0]==0xfefe5a5a)?true:false; /* ddl@rock-chips.com : v0.1.5 */ + /* ddl@rock-chips.com : v0.1.5 */ + bool is_capture = (mf->reserved[0] == 0xfe5a) ? true : false; int ret=0; fmt =generic_sensor_find_datafmt(mf->code, sensor->info_priv.datafmt, @@ -961,23 +967,7 @@ sensor_s_fmt_end: Sensor_CropSet(mf,sensor->crop_percent); /* ddl@rock-chips.com: v0.1.b */ return ret; } - int generic_sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct generic_sensor *sensor = to_generic_sensor(client); - if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) - return -EINVAL; - - if (id->match.addr != client->addr) - return -ENODEV; - - id->ident = sensor->info_priv.chip_ident; /* ddl@rock-chips.com : Return OV2655 identifier */ - id->revision = 0; - - return 0; -} - int generic_sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -1013,32 +1003,32 @@ int generic_sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) int generic_sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct generic_sensor *sensor = to_generic_sensor(client); - struct soc_camera_subdev_desc *ssdd = client->dev.platform_data; + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct generic_sensor *sensor = to_generic_sensor(client); + struct soc_camera_subdev_desc *ssdd = client->dev.platform_data; struct soc_camera_device *icd = ssdd->socdev; - struct sensor_v4l2ctrl_info_s *ctrl_info; - struct v4l2_ext_control ext_ctrl; - int ret = 0; + struct sensor_v4l2ctrl_info_s *ctrl_info; + struct v4l2_ext_control ext_ctrl; + int ret = 0; - ctrl_info = sensor_find_ctrl(sensor->ctrls,ctrl->id); - if (!ctrl_info) { - SENSOR_TR("v4l2_control id(0x%x) is invalidate",ctrl->id); - ret = -EINVAL; - } else { + ctrl_info = sensor_find_ctrl(sensor->ctrls, ctrl->id); + if (!ctrl_info) { + SENSOR_DG("v4l2_control id(0x%x) is invalidate", ctrl->id); + ret = -EINVAL; + } else { + ext_ctrl.id = ctrl->id; + ext_ctrl.value = ctrl->value; - ext_ctrl.id = ctrl->id; - ext_ctrl.value = ctrl->value; - - if (ctrl_info->cb) { - ret = (ctrl_info->cb)(icd,ctrl_info, &ext_ctrl,true); - } else { - SENSOR_TR("v4l2_control id(0x%x) callback isn't exist",ctrl->id); - ret = -EINVAL; - } - } + if (ctrl_info->cb) { + ret = ctrl_info->cb(icd, ctrl_info, &ext_ctrl, true); + } else { + SENSOR_TR("v4l2_control id(0x%x) callback isn't exist", + ctrl->id); + ret = -EINVAL; + } + } - return ret; + return ret; } int generic_sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl) @@ -1066,26 +1056,30 @@ int generic_sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext return ret; } -int generic_sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl) +int generic_sensor_s_ext_control(struct soc_camera_device *icd, + struct v4l2_ext_control *ext_ctrl) { - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct generic_sensor *sensor = to_generic_sensor(client); - struct sensor_v4l2ctrl_info_s *ctrl_info; - int ret = 0; - - ctrl_info = sensor_find_ctrl(sensor->ctrls,ext_ctrl->id); - if (!ctrl_info) { - SENSOR_TR("v4l2_ext_control id(0x%x) is invalidate",ext_ctrl->id); - ret = -EINVAL; - } else { - if (ctrl_info->cb) { - ret = (ctrl_info->cb)(icd,ctrl_info, ext_ctrl,true); - } else { - SENSOR_TR("v4l2_ext_control id(0x%x) callback isn't exist",ext_ctrl->id); - ret = -EINVAL; - } - } - return 0; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct generic_sensor *sensor = to_generic_sensor(client); + struct sensor_v4l2ctrl_info_s *ctrl_info; + int ret = 0; + + ctrl_info = sensor_find_ctrl(sensor->ctrls, ext_ctrl->id); + if (!ctrl_info) { + SENSOR_DG("v4l2_ext_control id(0x%x) is invalidate", + ext_ctrl->id); + ret = -EINVAL; + } else { + if (ctrl_info->cb) { + ret = ctrl_info->cb(icd, ctrl_info, ext_ctrl, true); + } else { + SENSOR_TR("v4l2_ext_control id(0x%x) callback isn't exist", + ext_ctrl->id); + ret = -EINVAL; + } + } + + return 0; } int generic_sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) { @@ -1175,7 +1169,7 @@ long generic_sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control for this project */ if (sensor->sensor_gpio_res) { - if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) { + if (sensor->sensor_gpio_res->gpio_flash) { flash_attach = false; } else { flash_attach = true; @@ -1210,9 +1204,18 @@ long generic_sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) } break; } + + case RK29_CAM_SUBDEV_GET_INTERFACE: + { + memcpy(arg, &sensor->info_priv.dev_sig_cnf, + sizeof(sensor->info_priv.dev_sig_cnf)); + SENSOR_DG("%s ioctl get src fmt: %s", __func__, + (char *)arg); + break; + } default: { - SENSOR_TR("%s cmd(0x%x) is unknown !\n",__FUNCTION__,cmd); + SENSOR_DG("%s cmd(0x%x) is unknown !\n",__FUNCTION__,cmd); break; } } @@ -1231,7 +1234,7 @@ int generic_sensor_s_power(struct v4l2_subdev *sd, int on) debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__); if(on) { - ret = soc_camera_power_on(icd->pdev,ssdd); + ret = soc_camera_power_on(icd->pdev, ssdd, NULL); if(ret < 0) SENSOR_TR("%s(%d)power_on fail !\n",__FUNCTION__,__LINE__); @@ -1240,7 +1243,7 @@ int generic_sensor_s_power(struct v4l2_subdev *sd, int on) { v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_DEACTIVATE,NULL); - soc_camera_power_off(icd->pdev,ssdd); + soc_camera_power_off(icd->pdev, ssdd, NULL); if(ret < 0) SENSOR_TR("%s(%d)power_off fail !\n",__FUNCTION__,__LINE__); @@ -1251,7 +1254,7 @@ int generic_sensor_s_power(struct v4l2_subdev *sd, int on) int generic_sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) + u32 *code) { struct i2c_client *client = v4l2_get_subdevdata(sd); diff --git a/drivers/media/video/generic_sensor.h b/drivers/media/video/generic_sensor.h old mode 100755 new mode 100644 index 09043f55aa14..8cef220e66d1 --- a/drivers/media/video/generic_sensor.h +++ b/drivers/media/video/generic_sensor.h @@ -1,3 +1,15 @@ +/* + * Copyright (C) ROCKCHIP, Inc. + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + #ifndef __ASM_ARCH_GENERIC_SENSOR_RK_H_ #include #include @@ -13,7 +25,7 @@ #include #include #include -#include "../../../arch/arm/mach-rockchip/rk30_camera.h" +#include "../../../drivers/soc/rockchip/rk30_camera.h" #include /* Camera Sensor driver */ @@ -100,7 +112,7 @@ struct rk_sensor_sequence { /* only one fixed colorspace per pixelcode */ struct rk_sensor_datafmt { - enum v4l2_mbus_pixelcode code; + u32 code; enum v4l2_colorspace colorspace; }; @@ -201,10 +213,10 @@ typedef struct rk_sensor_priv_s int chip_ident; unsigned int gReg_mask; unsigned int gVal_mask; - unsigned int gI2c_speed; - - bool stream; - + struct rk_camera_device_signal_config dev_sig_cnf; + struct dentry *debugfs_dir; + int video_state; + bool stream; } rk_sensor_info_priv_t; struct sensor_v4l2ctrl_info_s { @@ -245,6 +257,11 @@ struct rk_flash_timer{ struct hrtimer timer; }; +struct rk_state_check_work { + struct workqueue_struct *state_check_wq; + struct delayed_work work; +}; + struct generic_sensor { char dev_name[32]; @@ -254,6 +271,9 @@ struct generic_sensor int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */ int crop_percent; + int irq; + struct rk_state_check_work state_check_work; + int channel_id; bool is_need_tasklock; atomic_t tasklock_cnt; @@ -298,9 +318,8 @@ extern int generic_sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext extern int generic_sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); extern long generic_sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg); extern int generic_sensor_s_power(struct v4l2_subdev *sd, int on);/*yzm*/ -extern int generic_sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index,enum v4l2_mbus_pixelcode *code); +extern int generic_sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, u32 *code); extern int generic_sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf); -extern int generic_sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id); extern int generic_sensor_af_workqueue_set(struct soc_camera_device *icd, enum rk_sensor_focus_wq_cmd cmd, int var, bool wait); extern int generic_sensor_s_stream(struct v4l2_subdev *sd, int enable); extern int generic_sensor_writebuf(struct i2c_client *client, char *buf, int buf_size); @@ -776,7 +795,6 @@ static inline int sensor_v4l2ctrl_flip_default_cb(struct soc_camera_device *icd, spsensor->common_sensor.info_priv.gReg_mask |= (0xff<<(i*8)); \ for (i=0; icommon_sensor.info_priv.gVal_mask |= (0xff<<(i*8)); \ - spsensor->common_sensor.info_priv.gI2c_speed = 100000; \ if (sensor_regarray_check(sensor_softreset_data, sizeof(sensor_softreset_data)/sizeof(struct rk_sensor_reg))==0) { \ spsensor->common_sensor.info_priv.sensor_SfRstSeqe = sensor_softreset_data; \ } else { \ @@ -1226,7 +1244,6 @@ static inline int sensor_v4l2ctrl_flip_default_cb(struct soc_camera_device *icd, .s_ctrl = generic_sensor_s_control,\ .g_ext_ctrls = generic_sensor_g_ext_controls,\ .s_ext_ctrls = generic_sensor_s_ext_controls,\ - .g_chip_ident = generic_sensor_g_chip_ident,\ .ioctl = generic_sensor_ioctl,\ .s_power = generic_sensor_s_power,\ };\ @@ -1293,6 +1310,7 @@ MODULE_DEVICE_TABLE(i2c, sensor_id); \ v4l2_i2c_subdev_init(&spsensor->common_sensor.subdev, client, &sensor_subdev_ops);\ sensor_init_parameters(spsensor,icd);\ + spsensor->common_sensor.client = client;\ \ ret = sensor_video_probe(icd, client);\ \ @@ -1311,7 +1329,6 @@ sensor_probe_end:\ icd->ops = NULL;\ }\ i2c_set_clientdata(client, NULL);\ - client->driver = NULL;\ if (spsensor) {\ kfree(spsensor);\ }\ @@ -1348,7 +1365,6 @@ sensor_probe_end:\ icd->ops = NULL;\ }\ i2c_set_clientdata(client, NULL);\ - client->driver = NULL;\ if (spsensor) {\ kfree(spsensor);\ }\ diff --git a/drivers/media/video/gt2005.c b/drivers/media/video/gt2005.c old mode 100755 new mode 100644 index 4f2ac72c3fe1..103ad6770dac --- a/drivers/media/video/gt2005.c +++ b/drivers/media/video/gt2005.c @@ -1,3 +1,17 @@ +/* + * drivers/media/video/gt2005.c + * + * Copyright (C) ROCKCHIP, Inc. + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + #include "generic_sensor.h" /* * Driver Version Note @@ -1017,7 +1031,7 @@ static struct sensor_v4l2ctrl_usr_s sensor_controls[] = //MUST define the current used format as the first item static struct rk_sensor_datafmt sensor_colour_fmts[] = { - {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG} + {MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG} }; /*static struct soc_camera_ops sensor_ops;*/ diff --git a/drivers/media/video/hm2057.c b/drivers/media/video/hm2057.c old mode 100755 new mode 100644 index 15fdecf28af7..3ecd7c9109c0 --- a/drivers/media/video/hm2057.c +++ b/drivers/media/video/hm2057.c @@ -1,3 +1,16 @@ +/* + * drivers/media/video/hm2057.c + * + * Copyright (C) ROCKCHIP, Inc. + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ #include "generic_sensor.h" @@ -1036,7 +1049,7 @@ static struct sensor_v4l2ctrl_usr_s sensor_controls[] = //MUST define the current used format as the first item static struct rk_sensor_datafmt sensor_colour_fmts[] = { - {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG} + {MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG} }; /*static struct soc_camera_ops sensor_ops;*/ diff --git a/drivers/media/video/hm5065.c b/drivers/media/video/hm5065.c old mode 100755 new mode 100644 index 9ad7adce5e3e..7746993ccc7d --- a/drivers/media/video/hm5065.c +++ b/drivers/media/video/hm5065.c @@ -1,3 +1,17 @@ + /* + * drivers/media/video/hm5065.c + * + * Copyright (C) ROCKCHIP, Inc. + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + #include "generic_sensor.h" /* @@ -2822,7 +2836,7 @@ static struct sensor_v4l2ctrl_usr_s sensor_controls[] = //MUST define the current used format as the first item static struct rk_sensor_datafmt sensor_colour_fmts[] = { - {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG} + {MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG} }; diff --git a/drivers/media/video/mt9p111.c b/drivers/media/video/mt9p111.c old mode 100755 new mode 100644 index d94833148cdd..efb7c1c571a8 --- a/drivers/media/video/mt9p111.c +++ b/drivers/media/video/mt9p111.c @@ -1,3 +1,16 @@ +/* + * drivers/media/video/mt9p111.c + * + * Copyright (C) ROCKCHIP, Inc. + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ #include "generic_sensor.h" /* @@ -2080,8 +2093,8 @@ static struct sensor_v4l2ctrl_usr_s sensor_controls[] = //MUST define the current used format as the first item static struct rk_sensor_datafmt sensor_colour_fmts[] = { - {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, - {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} + {MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, + {MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} }; /*static struct soc_camera_ops sensor_ops;*/ diff --git a/drivers/media/video/nt99160_2way.c b/drivers/media/video/nt99160_2way.c old mode 100755 new mode 100644 index 6ca37e9ab01d..27e6f7215c9e --- a/drivers/media/video/nt99160_2way.c +++ b/drivers/media/video/nt99160_2way.c @@ -1,3 +1,16 @@ +/* + * drivers/media/video/nt99160_2way.c + * + * Copyright (C) ROCKCHIP, Inc. + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ #include "generic_sensor.h" @@ -1008,8 +1021,8 @@ static struct sensor_v4l2ctrl_usr_s sensor_controls[] = //MUST define the current used format as the first item static struct rk_sensor_datafmt sensor_colour_fmts[] = { - {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, - {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} + {MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, + {MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} }; /*static struct soc_camera_ops sensor_ops;*/ diff --git a/drivers/media/video/nt99240_2way.c b/drivers/media/video/nt99240_2way.c old mode 100755 new mode 100644 index c19066b7d1fe..8688150461b8 --- a/drivers/media/video/nt99240_2way.c +++ b/drivers/media/video/nt99240_2way.c @@ -1,3 +1,16 @@ +/* + * drivers/media/video/nt99240_2way.c + * + * Copyright (C) ROCKCHIP, Inc. + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ #include "generic_sensor.h" /* @@ -813,8 +826,8 @@ static struct sensor_v4l2ctrl_usr_s sensor_controls[] = //MUST define the current used format as the first item static struct rk_sensor_datafmt sensor_colour_fmts[] = { - {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG}, - {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG} + {MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG}, + {MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG} }; /*static struct soc_camera_ops sensor_ops;*/ diff --git a/drivers/media/video/ov2659.c b/drivers/media/video/ov2659.c old mode 100755 new mode 100644 index 4d4573da5a89..305b61b74273 --- a/drivers/media/video/ov2659.c +++ b/drivers/media/video/ov2659.c @@ -1,3 +1,16 @@ +/* + * drivers/media/video/ov2659.c + * + * Copyright (C) ROCKCHIP, Inc. + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ #include "generic_sensor.h" #include @@ -719,8 +732,8 @@ static struct sensor_v4l2ctrl_usr_s sensor_controls[] = //MUST define the current used format as the first item static struct rk_sensor_datafmt sensor_colour_fmts[] = { - {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, - {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} + {MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, + {MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} }; //static struct soc_camera_ops sensor_ops;//yzm diff --git a/drivers/media/video/ov5640.c b/drivers/media/video/ov5640.c old mode 100755 new mode 100644 index 7d5904001b54..9a176bfb4198 --- a/drivers/media/video/ov5640.c +++ b/drivers/media/video/ov5640.c @@ -1,4 +1,18 @@ - #include "generic_sensor.h" +/* + * drivers/media/video/ov5640.c + * + * Copyright (C) ROCKCHIP, Inc. + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "generic_sensor.h" /* * Driver Version Note @@ -981,7 +995,7 @@ static struct sensor_v4l2ctrl_usr_s sensor_controls[] = //MUST define the current used format as the first item static struct rk_sensor_datafmt sensor_colour_fmts[] = { - {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG} + {MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG} }; /*static struct soc_camera_ops sensor_ops;*/ diff --git a/drivers/media/video/rk30_camera.c b/drivers/media/video/rk30_camera.c old mode 100755 new mode 100644 index 1747d3331748..f1091b25ddbd --- a/drivers/media/video/rk30_camera.c +++ b/drivers/media/video/rk30_camera.c @@ -1,11 +1,28 @@ +/* + * rk30_camera.c - PXA camera driver file + * + * Copyright (C) 2003, Intel Corporation + * Copyright (C) 2008, Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + #include #include #include #include #include #include -#include "../../../arch/arm/mach-rockchip/rk30_camera.h"/*yzm*/ -#include "../../../arch/arm/mach-rockchip/rk_camera.h"/*yzm*/ +#include "../../../drivers/soc/rockchip/rk30_camera.h"/*yzm*/ +#include "../../../drivers/soc/rockchip/rk_camera.h"/*yzm*/ //**********yzm***********// #include #include diff --git a/drivers/media/video/rk30_camera_oneframe.c b/drivers/media/video/rk30_camera_oneframe.c old mode 100755 new mode 100644 index b20d8b757cef..875a28e94802 --- a/drivers/media/video/rk30_camera_oneframe.c +++ b/drivers/media/video/rk30_camera_oneframe.c @@ -1,3 +1,15 @@ +/* + * Copyright (C) ROCKCHIP, Inc. + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + #include #include #include @@ -18,6 +30,7 @@ #include #include #include +#include #include #include @@ -28,8 +41,9 @@ #include #include "../../video/rockchip/rga/rga.h" -#include "../../../arch/arm/mach-rockchip/rk30_camera.h" +#include "../../../drivers/soc/rockchip/rk30_camera.h" #include +#include #include @@ -41,7 +55,7 @@ #include #include -static int debug = 0; +static int debug; module_param(debug, int, S_IRUGO|S_IWUSR); #define CAMMODULE_NAME "rk_cam_cif" @@ -147,8 +161,8 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define ENABLE_32BIT_BYPASS (0x01<<6) #define DISABLE_32BIT_BYPASS (0x00<<6) -extern unsigned long rk_cif_grf_base; -extern unsigned long rk_cif_cru_base; +extern struct regmap *rk_cif_grf_base; +extern struct regmap *rk_cif_cru_base; #define MIN(x,y) ((xzoominfo.a.c.width != pcdev->icd->user_width) || (pcdev->zoominfo.a.c.height != pcdev->icd->user_height))*/ @@ -242,8 +267,10 @@ static u32 CHIP_NAME; 1. focus mode have some bug,fix it. *v0.2.0: 1. support rk3368. +*v0.3.0: +* 1. supprot rk3228h */ -#define RK_CAM_VERSION_CODE KERNEL_VERSION(0, 2, 0) +#define RK_CAM_VERSION_CODE KERNEL_VERSION(0, 3, 0) static int version = RK_CAM_VERSION_CODE; module_param(version, int, S_IRUGO); @@ -276,7 +303,7 @@ struct rk_camera_buffer { /* common v4l buffer stuff -- must be first */ struct videobuf_buffer vb; - enum v4l2_mbus_pixelcode code; + u32 code; int inwork; }; enum rk_camera_reg_state @@ -336,18 +363,18 @@ struct rk_camera_timer{ struct hrtimer timer; bool istarted; }; -struct rk_cif_clk + +struct rk_cif_clk { - /************must modify start************/ struct clk *pd_cif; struct clk *aclk_cif; - struct clk *hclk_cif; - struct clk *cif_clk_in; - struct clk *cif_clk_out; - /************must modify end************/ + struct clk *hclk_cif; + struct clk *cif_clk_in; + struct clk *cif_clk_out; + struct clk *pclk_cif; + struct reset_control *cif_rst; - // spinlock_t lock; - bool on; + bool on; }; struct rk_cif_crop @@ -399,6 +426,7 @@ struct rk_camera_dev int hostid; int icd_width; int icd_height; + int capture_pingpong; struct rk_cif_crop cropinfo; struct rk_cif_irqinfo irqinfo; @@ -411,6 +439,8 @@ struct rk_camera_dev spinlock_t lock; struct videobuf_buffer *active; + struct videobuf_buffer *active1; + struct videobuf_buffer *active_delay; struct rk_camera_reg reginfo_suspend; struct workqueue_struct *camera_wq; struct rk_camera_work *camera_work; @@ -456,111 +486,111 @@ static void rk_camera_capture_process(struct work_struct *work); static void rk_camera_diffchips(const char *rockchip_name) { - if(strstr(rockchip_name,"3128")||strstr(rockchip_name,"3126")) - { + if (strstr(rockchip_name, "3128") || strstr(rockchip_name, "3126")) { CRU_PCLK_REG30 = 0xbc; - ENANABLE_INVERT_PCLK_CIF0 = ((0x1<<23)|(0x1<<7)); - DISABLE_INVERT_PCLK_CIF0 = ((0x1<<23)|(0x0<<7)); + ENANABLE_INVERT_PCLK_CIF0 = ((0x1 << 23) | (0x1 << 7)); + DISABLE_INVERT_PCLK_CIF0 = ((0x1 << 23) | (0x0 << 7)); ENANABLE_INVERT_PCLK_CIF1 = ENANABLE_INVERT_PCLK_CIF0; DISABLE_INVERT_PCLK_CIF1 = DISABLE_INVERT_PCLK_CIF0; CRU_CLK_OUT = 0xdc; - clk_cif_out_src_gate_en = ((0x1<<23)|(0x1<<7)); + clk_cif_out_src_gate_en = ((0x1 << 23) | (0x1 << 7)); CRU_CLKSEL29_CON = 0xb8; - cif0_clk_sel = ((0x1<<23)|(0x0<<7)); + cif0_clk_sel = ((0x1 << 23) | (0x0 << 7)); CHIP_NAME = 3126; - } - else if(strstr(rockchip_name,"3288")) - { + } else if (strstr(rockchip_name, "3288")) { CRU_PCLK_REG30 = 0xd4; - ENANABLE_INVERT_PCLK_CIF0 = ((0x1<<20)|(0x1<<4)); - DISABLE_INVERT_PCLK_CIF0 = ((0x1<<20)|(0x0<<4)); + ENANABLE_INVERT_PCLK_CIF0 = ((0x1 << 20) | (0x1 << 4)); + DISABLE_INVERT_PCLK_CIF0 = ((0x1 << 20) | (0x0 << 4)); ENANABLE_INVERT_PCLK_CIF1 = ENANABLE_INVERT_PCLK_CIF0; DISABLE_INVERT_PCLK_CIF1 = DISABLE_INVERT_PCLK_CIF0; CRU_CLK_OUT = 0x16c; CHIP_NAME = 3288; - } - else if(strstr(rockchip_name,"3368")) - { + } else if (strstr(rockchip_name, "3368") || + strstr(rockchip_name, "px5") || + strstr(rockchip_name, "px5-evb")) { CRU_PCLK_REG30 = 0x154; - ENANABLE_INVERT_PCLK_CIF0 = ((0x1<<29)|(0x1<<13)); - DISABLE_INVERT_PCLK_CIF0 = ((0x1<<29)|(0x0<<13)); + ENANABLE_INVERT_PCLK_CIF0 = ((0x1 << 29) | (0x1 << 13)); + DISABLE_INVERT_PCLK_CIF0 = ((0x1 << 29) | (0x0 << 13)); ENANABLE_INVERT_PCLK_CIF1 = ENANABLE_INVERT_PCLK_CIF0; DISABLE_INVERT_PCLK_CIF1 = DISABLE_INVERT_PCLK_CIF0; - //CRU_CLK_OUT = 0x16c; + /* CRU_CLK_OUT = 0x16c; */ CHIP_NAME = 3368; + } else if (strstr(rockchip_name, "3228h")) { + CRU_PCLK_REG30 = 0x0410; + ENANABLE_INVERT_PCLK_CIF0 = ((0x1 << 31) | (0x1 << 15)); + DISABLE_INVERT_PCLK_CIF0 = ((0x1 << 31) | (0x0 << 15)); + ENANABLE_INVERT_PCLK_CIF1 = ENANABLE_INVERT_PCLK_CIF0; + DISABLE_INVERT_PCLK_CIF1 = DISABLE_INVERT_PCLK_CIF0; + CHIP_NAME = 3228; } } -static inline void rk_cru_set_soft_reset(u32 idx, bool on , u32 RK_CRU_SOFTRST_CON) +static inline void rk_cru_set_soft_reset(int idx) { - u32 val = 0; - void __iomem *reg; - - if(CHIP_NAME == 3368) - reg = (void*)(rk_cif_cru_base + RK_CRU_SOFTRST_CON); - else - reg = (void*)(RK_CRU_VIRT + RK_CRU_SOFTRST_CON); + struct rk_cif_clk *clk; + clk = &cif_clk[idx]; - if(CHIP_NAME == 3126){ - val = on ? 0x10001U << 14 : 0x10000U << 14; - }else if(CHIP_NAME == 3288){ - val = on ? 0x10001U << 8 : 0x10000U << 8; - }else if(CHIP_NAME == 3368){ - val = on ? 0x10001U << 8 : 0x10000U << 8; + if (clk->cif_rst) { + reset_control_assert(clk->cif_rst); + udelay(5); + reset_control_deassert(clk->cif_rst); } - writel_relaxed(val, reg); - dsb(sy); } static void rk_camera_cif_reset(struct rk_camera_dev *pcdev, int only_rst) { - int ctrl_reg,inten_reg,crop_reg,set_size_reg,for_reg,vir_line_width_reg,scl_reg,y_reg,uv_reg; + int ctrl_reg, inten_reg, crop_reg, set_size_reg, for_reg; + int vir_line_width_reg, scl_reg, y_reg, uv_reg; u32 RK_CRU_SOFTRST_CON = 0; debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__); if(CHIP_NAME == 3126){ RK_CRU_SOFTRST_CON = RK312X_CRU_SOFTRSTS_CON(6); + } else if (CHIP_NAME == 3228) { + RK_CRU_SOFTRST_CON = 0x0324; }else if(CHIP_NAME == 3288){ RK_CRU_SOFTRST_CON = RK3288_CRU_SOFTRSTS_CON(6); }else if(CHIP_NAME == 3368){ RK_CRU_SOFTRST_CON = RK3368_CRU_SOFTRSTS_CON(6); } - - if (only_rst == true) { - rk_cru_set_soft_reset(0, true ,RK_CRU_SOFTRST_CON); - udelay(5); - rk_cru_set_soft_reset(0, false ,RK_CRU_SOFTRST_CON); - } else { - ctrl_reg = read_cif_reg(pcdev->base,CIF_CIF_CTRL); - if (ctrl_reg & ENABLE_CAPTURE) { - write_cif_reg(pcdev->base,CIF_CIF_CTRL, ctrl_reg&~ENABLE_CAPTURE); - } - crop_reg = read_cif_reg(pcdev->base,CIF_CIF_CROP); - set_size_reg = read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE); - inten_reg = read_cif_reg(pcdev->base,CIF_CIF_INTEN); - for_reg = read_cif_reg(pcdev->base,CIF_CIF_FOR); - vir_line_width_reg = read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH); - scl_reg = read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL); - y_reg = read_cif_reg(pcdev->base, CIF_CIF_FRM0_ADDR_Y); - uv_reg = read_cif_reg(pcdev->base, CIF_CIF_FRM0_ADDR_UV); - - rk_cru_set_soft_reset(0, true ,RK_CRU_SOFTRST_CON); - udelay(5); - rk_cru_set_soft_reset(0, false ,RK_CRU_SOFTRST_CON); - write_cif_reg(pcdev->base,CIF_CIF_CTRL, ctrl_reg&~ENABLE_CAPTURE); - write_cif_reg(pcdev->base,CIF_CIF_INTEN, inten_reg); - write_cif_reg(pcdev->base,CIF_CIF_CROP, crop_reg); - write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, set_size_reg); - write_cif_reg(pcdev->base,CIF_CIF_FOR, for_reg); - write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH,vir_line_width_reg); - write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL,scl_reg); - write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y,y_reg); /*ddl@rock-chips.com v0.3.0x13 */ - write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV,uv_reg); - } - return; + if (only_rst == true) { + rk_cru_set_soft_reset(0); + } else { + ctrl_reg = read_cif_reg(pcdev->base, CIF_CIF_CTRL); + if (ctrl_reg & ENABLE_CAPTURE) + write_cif_reg(pcdev->base, CIF_CIF_CTRL, + ctrl_reg & ~ENABLE_CAPTURE); + + crop_reg = read_cif_reg(pcdev->base, CIF_CIF_CROP); + set_size_reg = read_cif_reg(pcdev->base, CIF_CIF_SET_SIZE); + inten_reg = read_cif_reg(pcdev->base, CIF_CIF_INTEN); + for_reg = read_cif_reg(pcdev->base, CIF_CIF_FOR); + vir_line_width_reg = read_cif_reg(pcdev->base, + CIF_CIF_VIR_LINE_WIDTH); + scl_reg = read_cif_reg(pcdev->base, CIF_CIF_SCL_CTRL); + y_reg = read_cif_reg(pcdev->base, CIF_CIF_FRM0_ADDR_Y); + uv_reg = read_cif_reg(pcdev->base, CIF_CIF_FRM0_ADDR_UV); + + rk_cru_set_soft_reset(0); + + write_cif_reg(pcdev->base, CIF_CIF_CTRL, + ctrl_reg & ~ENABLE_CAPTURE); + write_cif_reg(pcdev->base, CIF_CIF_INTEN, inten_reg); + write_cif_reg(pcdev->base, CIF_CIF_CROP, crop_reg); + write_cif_reg(pcdev->base, CIF_CIF_SET_SIZE, set_size_reg); + write_cif_reg(pcdev->base, CIF_CIF_FOR, for_reg); + write_cif_reg(pcdev->base, CIF_CIF_VIR_LINE_WIDTH, + vir_line_width_reg); + write_cif_reg(pcdev->base, CIF_CIF_SCL_CTRL, scl_reg); + write_cif_reg(pcdev->base, CIF_CIF_FRM0_ADDR_Y, y_reg); + write_cif_reg(pcdev->base, CIF_CIF_FRM0_ADDR_UV, uv_reg); + write_cif_reg(pcdev->base, CIF_CIF_FRM1_ADDR_Y, y_reg); + write_cif_reg(pcdev->base, CIF_CIF_FRM1_ADDR_UV, uv_reg); + } + return; } @@ -670,9 +700,9 @@ static void rk_videobuf_free(struct videobuf_queue *vq, struct rk_camera_buffer if (buf->vb.state == VIDEOBUF_NEEDS_INIT) return; - if (in_interrupt()) - BUG(); - /* + BUG_ON(in_interrupt()); + + /* * This waits until this buffer is out of danger, i.e., until it is no * longer in STATE_QUEUED or STATE_ACTIVE */ @@ -690,7 +720,7 @@ static int rk_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer icd->current_fmt->host_fmt); debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__); - + if ((bytes_per_line < 0) || (vb->boff == 0)) return -EINVAL; @@ -764,6 +794,46 @@ static inline void rk_videobuf_capture(struct videobuf_buffer *vb,struct rk_came write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000002);//frame1 has been ready to receive data,frame 2 is not used } } + +static inline void rk_videobuf_capture_mix(struct videobuf_buffer *vb, + struct rk_camera_dev *rk_pcdev, + int fmt_ready) +{ + unsigned long y_addr, uv_addr; + struct rk_camera_dev *pcdev = rk_pcdev; + + debug_printk("/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", + __FILE__, __LINE__, __func__); + + if (vb) { + y_addr = vb->boff; + uv_addr = y_addr + vb->width * vb->height; + + switch (fmt_ready) { + case 0: + write_cif_reg(pcdev->base, + CIF_CIF_FRM0_ADDR_Y, y_addr); + write_cif_reg(pcdev->base, + CIF_CIF_FRM0_ADDR_UV, uv_addr); + write_cif_reg(pcdev->base, + CIF_CIF_FRAME_STATUS, 0x10000000); + break; + case 1: + write_cif_reg(pcdev->base, + CIF_CIF_FRM1_ADDR_Y, y_addr); + write_cif_reg(pcdev->base, + CIF_CIF_FRM1_ADDR_UV, uv_addr); + write_cif_reg(pcdev->base, + CIF_CIF_FRAME_STATUS, 0x10000000); + break; + default: + RKCAMERA_TR("%s(%d): fmt_ready(%d) is wrong!\n", + __func__, __LINE__, fmt_ready); + break; + } + } +} + /* Locking: Caller holds q->irqlock */ static void rk_videobuf_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) @@ -811,14 +881,28 @@ static void rk_videobuf_queue(struct videobuf_queue *vq, } } } -#endif - if (!pcdev->active) { - pcdev->active = vb; - rk_videobuf_capture(vb,pcdev); - if (atomic_read(&pcdev->stop_cif) == false) { //ddl@rock-chips.com v0.3.0x13 - write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL) | ENABLE_CAPTURE)); - } - } +#endif + if (pcdev->capture_pingpong) { + if (!pcdev->active) { + pcdev->active = vb; + rk_videobuf_capture_mix(vb, pcdev, 0); + list_del_init(&vb->queue); + } else if (!pcdev->active1) { + pcdev->active1 = vb; + rk_videobuf_capture_mix(vb, pcdev, 1); + list_del_init(&vb->queue); + } + } else { + if (!pcdev->active) { + pcdev->active = vb; + rk_videobuf_capture(vb, pcdev); + if (atomic_read(&pcdev->stop_cif) == false) + write_cif_reg(pcdev->base, CIF_CIF_CTRL, + (read_cif_reg(pcdev->base, + CIF_CIF_CTRL) | + ENABLE_CAPTURE)); + } + } } #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA) @@ -871,9 +955,8 @@ static int rk_camera_scale_crop_pp(struct work_struct *work){ unsigned long int flags; int scale_times,w,h; int src_y_offset; - int ret = 0; - return ret; + return 0; } #endif #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA) @@ -892,12 +975,10 @@ static int rk_camera_scale_crop_rga(struct work_struct *work){ rga_session session; int rga_times = 3; const struct soc_mbus_pixelfmt *fmt; - int ret = 0; debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__); - return ret; - + return 0; } #endif @@ -1114,6 +1195,156 @@ end: return IRQ_HANDLED; } +static inline irqreturn_t rk_camera_dmairq_pingpong(int irq, void *data) +{ + struct rk_camera_dev *pcdev = data; + struct videobuf_buffer *vb; + struct timeval tv; + unsigned long reg_cifctrl; + struct videobuf_buffer **active = 0; + struct videobuf_buffer *active_buf = NULL; + unsigned long tmp_cif_frmst; + unsigned int frame_num = 0; + int flag = 0; + + debug_printk("/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", + __FILE__, __LINE__, __func__); + + tmp_cif_frmst = read_cif_reg(pcdev->base, CIF_CIF_FRAME_STATUS); + RKCAMERA_DG1("%s(%d): tmp_cif_frmst: 0x%lx\n", + __func__, __LINE__, tmp_cif_frmst); + + reg_cifctrl = read_cif_reg(pcdev->base, CIF_CIF_CTRL); + + /* ddl@rock-chps.com : + * Current VIP is run in One Frame Mode, Frame 1 is validate + * + * frame 0 ready yzm + */ + if (read_cif_reg(pcdev->base, CIF_CIF_FRAME_STATUS) & 0x01) { + /* clear vip interrupte single */ + write_cif_reg(pcdev->base, CIF_CIF_INTSTAT, 0x01); + + pcdev->irqinfo.dmairq_idx++; + if (pcdev->irqinfo.cifirq_abnormal_idx == + pcdev->irqinfo.dmairq_idx) { + write_cif_reg(pcdev->base, CIF_CIF_FRAME_STATUS, + 0x10000002); + + goto end; + } + + if (!pcdev->fps) + do_gettimeofday(&pcdev->first_tv); + + pcdev->fps++; + if (!pcdev->active) + goto end; + if (pcdev->frame_inval > 0) { + pcdev->frame_inval--; + rk_videobuf_capture_mix(pcdev->active, pcdev, 0); + + goto end; + } else if (pcdev->frame_inval) { + RKCAMERA_TR("frame_inval : %0x", pcdev->frame_inval); + pcdev->frame_inval = 0; + } + + if (pcdev->fps == RK30_CAM_FRAME_MEASURE) { + do_gettimeofday(&tv); + pcdev->frame_interval = + ((tv.tv_sec * 1000000 + tv.tv_usec) - + (pcdev->first_tv.tv_sec * 1000000 + + pcdev->first_tv.tv_usec)) + / (RK30_CAM_FRAME_MEASURE - 1); + } + + frame_num = tmp_cif_frmst >> 16; + frame_num = (frame_num % 2); + + if (frame_num) { + active = &pcdev->active; + flag = 0; + } else if (!frame_num) { + active = &pcdev->active1; + flag = 1; + } else { + RKCAMERA_TR("%s(%d): irq frame error\n", + __func__, __LINE__); + goto end; + } + + if (!(*active)) { + RKCAMERA_TR("%s(%d): active = NULL\n", + __func__, __LINE__); + goto end; + } + + vb = *active; + if (!vb) { + RKCAMERA_TR("%s(%d): no active buffer\n", + __func__, __LINE__); + goto end; + } + + if (!list_empty(&pcdev->capture)) { + active_buf = list_entry(pcdev->capture.next, + struct videobuf_buffer, queue); + if (active_buf) { + RKCAMERA_DG1("flag = %d, active_buf->i: %d\n", + flag, active_buf->i); + WARN_ON(active_buf->state != VIDEOBUF_QUEUED); + if (flag == 0) { + pcdev->active_delay = pcdev->active; + pcdev->active = active_buf; + } else if (flag == 1) { + pcdev->active_delay = pcdev->active1; + pcdev->active1 = active_buf; + } else { + RKCAMERA_DG1("irq frame status erro or no a suitable buf!\n"); + goto end; + } + rk_videobuf_capture_mix(active_buf, + pcdev, flag); + list_del_init(&active_buf->queue); + } else { + RKCAMERA_TR("video_buf queue is empty!\n"); + } + } else { + RKCAMERA_TR("video_buf queue is empty!\n"); + goto end; + } + + vb = pcdev->active_delay; + if (!vb) { + RKCAMERA_TR("no acticve buffer!!!\n"); + goto end; + } + + /* ddl@rock-chips.com : + * this vb may be deleted from queue + */ + if ((vb->state == VIDEOBUF_QUEUED) || + (vb->state == VIDEOBUF_ACTIVE)) + list_del_init(&vb->queue); + + do_gettimeofday(&vb->ts); + if ((vb->state == VIDEOBUF_QUEUED) || + (vb->state == VIDEOBUF_ACTIVE)) { + vb->state = VIDEOBUF_DONE; + vb->field_count++; + } + + wake_up(&vb->done); + } + +end: + if ((reg_cifctrl & ENABLE_CAPTURE) == 0) + write_cif_reg(pcdev->base, CIF_CIF_CTRL, + (reg_cifctrl | ENABLE_CAPTURE)); + return IRQ_HANDLED; +} + static irqreturn_t rk_camera_irq(int irq, void *data) { struct rk_camera_dev *pcdev = data; @@ -1145,9 +1376,13 @@ static irqreturn_t rk_camera_irq(int irq, void *data) rk_camera_cif_reset(pcdev,false); debug_printk("receive cif stop request,recevie dma irq ,reg_intstat = 0x%x\n",reg_intstat); wake_up(&pcdev->cif_stop_done); - }else + } else { + if (pcdev->capture_pingpong) + rk_camera_dmairq_pingpong(irq, data); + else rk_camera_dmairq(irq,data); - } + } + } //end: spin_unlock(&pcdev->lock); @@ -1239,178 +1474,192 @@ static void rk_camera_init_videobuf(struct videobuf_queue *q, static int rk_camera_mclk_ctrl(int cif_idx, int on, int clk_rate) { - int err = 0,cif; - struct rk_cif_clk *clk; + int err = 0, cif; + struct rk_cif_clk *clk; debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__); + cif = cif_idx - RK29_CAM_PLATFORM_DEV_ID; + if ((cif < 0) || (cif > 1)) { + RKCAMERA_TR("cif index(%d) is invalidate\n", cif_idx); + err = -1; + goto rk_camera_clk_ctrl_end; + } - cif = cif_idx - RK29_CAM_PLATFORM_DEV_ID; - if ((cif<0)||(cif>1)) { - RKCAMERA_TR(KERN_ERR "cif index(%d) is invalidate\n",cif_idx); - err = -1; - goto rk_camera_clk_ctrl_end; - } - - clk = &cif_clk[cif]; - - if(!clk->aclk_cif || !clk->hclk_cif || !clk->cif_clk_in || !clk->cif_clk_out) { - RKCAMERA_TR(KERN_ERR "failed to get cif clock source\n"); - err = -ENOENT; - goto rk_camera_clk_ctrl_end; - } - - //spin_lock(&clk->lock); - if (on && !clk->on) { - if(CHIP_NAME != 3368) - clk_prepare_enable(clk->pd_cif); - - clk_prepare_enable(clk->aclk_cif); - clk_prepare_enable(clk->hclk_cif); - clk_prepare_enable(clk->cif_clk_in); - clk_prepare_enable(clk->cif_clk_out); - clk_set_rate(clk->cif_clk_out,clk_rate); - clk->on = true; - } else if (!on && clk->on) { - clk_set_rate(clk->cif_clk_out,36000000);/*just for close clk which base on XIN24M */ - clk_disable_unprepare(clk->aclk_cif); - clk_disable_unprepare(clk->hclk_cif); - clk_disable_unprepare(clk->cif_clk_in); - if(CHIP_NAME == 3126){ - write_cru_reg(CRU_CLKSEL29_CON, 0x007c0000); - write_cru_reg(CRU_CLK_OUT, 0x00800080); + clk = &cif_clk[cif]; + if (CHIP_NAME == 3228) { + if (!clk->aclk_cif || !clk->hclk_cif || !clk->cif_clk_out) { + RKCAMERA_TR("failed to get cif clock source\n"); + err = -ENOENT; + goto rk_camera_clk_ctrl_end; } - clk_disable_unprepare(clk->cif_clk_out); - if(CHIP_NAME != 3368) - clk_disable_unprepare(clk->pd_cif); - + } else { + if (!clk->aclk_cif || !clk->hclk_cif || + !clk->cif_clk_in || !clk->cif_clk_out) { + RKCAMERA_TR("failed to get cif clock source\n"); + err = -ENOENT; + goto rk_camera_clk_ctrl_end; + } + } + + /* spin_lock(&clk->lock); */ + if (on && !clk->on) { + if (CHIP_NAME == 3368) + clk_prepare_enable(clk->pclk_cif); + + clk_prepare_enable(clk->aclk_cif); + clk_prepare_enable(clk->hclk_cif); + if (CHIP_NAME != 3228) + clk_prepare_enable(clk->cif_clk_in); + + clk_prepare_enable(clk->cif_clk_out); + clk_set_rate(clk->cif_clk_out, clk_rate); + clk->on = true; + } else if (!on && clk->on) { + clk_set_rate(clk->cif_clk_out,36000000);/*just for close clk which base on XIN24M */ + clk_disable_unprepare(clk->aclk_cif); + clk_disable_unprepare(clk->hclk_cif); + if (CHIP_NAME != 3228) + clk_disable_unprepare(clk->cif_clk_in); + clk_disable_unprepare(clk->cif_clk_out); + if (CHIP_NAME == 3368) + clk_disable_unprepare(clk->pclk_cif); clk->on = false; - } - //spin_unlock(&clk->lock); + } + /* spin_unlock(&clk->lock); */ rk_camera_clk_ctrl_end: - return err; + return err; } + static int rk_camera_activate(struct rk_camera_dev *pcdev, struct soc_camera_device *icd) { - /* - * ddl@rock-chips.com : Cif clk control in rk_sensor_power which in rk_camera.c - */ - debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__); + rk_camera_mclk_ctrl(RK29_CAM_PLATFORM_DEV_ID, 1, 24000000); - write_cif_reg(pcdev->base,CIF_CIF_CTRL,AXI_BURST_16|MODE_ONEFRAME|DISABLE_CAPTURE); /* ddl@rock-chips.com : vip ahb burst 16 */ - //write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01); //capture complete interrupt enable - return 0; + write_cif_reg(pcdev->base, CIF_CIF_CTRL, + AXI_BURST_16 | MODE_ONEFRAME | DISABLE_CAPTURE); + + return 0; } static void rk_camera_deactivate(struct rk_camera_dev *pcdev) { - /* - * ddl@rock-chips.com : Cif clk control in rk_sensor_power which in rk_camera.c - */ + /* + * ddl@rock-chips.com : + * Cif clk control in rk_sensor_power which in rk_camera.c + */ debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__); + rk_camera_mclk_ctrl(RK29_CAM_PLATFORM_DEV_ID, 0, 24000000); - - return; + return; } -/* The following two functions absolutely depend on the fact, that - * there can be only one camera on RK28 quick capture interface */ +/* + * The following two functions absolutely depend on the fact, that + * there can be only one camera on RK28 quick capture interface + */ static int rk_camera_add_device(struct soc_camera_device *icd) { struct soc_camera_host *ici = to_soc_camera_host(icd->parent); - struct rk_camera_dev *pcdev = ici->priv; /*Initialize in rk_camra_prob*/ - struct device *control = to_soc_camera_control(icd); - struct v4l2_subdev *sd; - int ret,i,icd_catch; - struct rk_camera_frmivalenum *fival_list,*fival_nxt; - struct v4l2_cropcap cropcap; - struct v4l2_mbus_framefmt mf; - const struct soc_camera_format_xlate *xlate = NULL; + /*Initialize in rk_camra_prob*/ + struct rk_camera_dev *pcdev = ici->priv; + struct device *control = to_soc_camera_control(icd); + struct v4l2_subdev *sd; + int ret, i, icd_catch; + struct rk_camera_frmivalenum *fival_list, *fival_nxt; + struct v4l2_cropcap cropcap; + struct v4l2_mbus_framefmt mf; + const struct soc_camera_format_xlate *xlate = NULL; - debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__); + mutex_lock(&camera_lock); + if (pcdev->icd) { + ret = -EBUSY; + goto ebusy; + } - - mutex_lock(&camera_lock); - - if (pcdev->icd) { - ret = -EBUSY; - goto ebusy; - } - - RKCAMERA_DG1("%s driver attached to %s\n",RK29_CAM_DRV_NAME,dev_name(icd->pdev)); + RKCAMERA_DG1("%s driver attached to %s\n", + RK29_CAM_DRV_NAME, + dev_name(icd->pdev)); pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT; - pcdev->active = NULL; - pcdev->icd = NULL; + pcdev->active = NULL; + pcdev->active1 = NULL; + pcdev->icd = NULL; pcdev->reginfo_suspend.Inval = Reg_Invalidate; - pcdev->zoominfo.zoom_rate = 100; - pcdev->fps_timer.istarted = false; - - /* ddl@rock-chips.com: capture list must be reset, because this list may be not empty, - * if app havn't dequeue all videobuf before close camera device; - */ - INIT_LIST_HEAD(&pcdev->capture); + pcdev->zoominfo.zoom_rate = 100; + pcdev->fps_timer.istarted = false; - ret = rk_camera_activate(pcdev,icd); - if (ret) - goto ebusy; - /* ddl@rock-chips.com : v4l2_subdev is not created when ici->ops->add called in soc_camera_probe */ - if (control) { //TRUE in open ,FALSE in kernel start - sd = dev_get_drvdata(control); - v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_IOREQUEST,(void*)pcdev->pdata); - #if 0 - ret = v4l2_subdev_call(sd,core, init, 0); - if (ret) - goto ebusy; - #endif - v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_CB_REGISTER,(void*)(&pcdev->icd_cb)); - if (v4l2_subdev_call(sd, video, cropcap, &cropcap) == 0) { - memcpy(&pcdev->cropinfo.bounds ,&cropcap.bounds,sizeof(struct v4l2_rect)); - } else { - xlate = soc_camera_xlate_by_fourcc(icd, V4L2_PIX_FMT_NV12); - mf.width = 10000; - mf.height = 10000; - mf.field = V4L2_FIELD_NONE; - mf.code = xlate->code; - mf.reserved[6] = 0xfefe5a5a; - v4l2_subdev_call(sd, video, try_mbus_fmt, &mf); + /* + * ddl@rock-chips.com: + * capture list must be reset, because this list may be not empty, + * if app havn't dequeue all videobuf before close camera device; + */ + INIT_LIST_HEAD(&pcdev->capture); - pcdev->cropinfo.bounds.left = 0; - pcdev->cropinfo.bounds.top = 0; - pcdev->cropinfo.bounds.width = mf.width; - pcdev->cropinfo.bounds.height = mf.height; - } - } + ret = rk_camera_activate(pcdev, icd); + if (ret) + goto ebusy; + /* + * ddl@rock-chips.com : + * v4l2_subdev is not created when ici->ops->add called in + * soc_camera_probe + * + * TRUE in open ,FALSE in kernel start + */ + if (control) { + sd = dev_get_drvdata(control); + v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_IOREQUEST, + (void *)pcdev->pdata); + v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_CB_REGISTER, + (void *)(&pcdev->icd_cb)); + if (v4l2_subdev_call(sd, video, cropcap, &cropcap) == 0) { + memcpy(&pcdev->cropinfo.bounds, &cropcap.bounds, + sizeof(struct v4l2_rect)); + } else { + xlate = soc_camera_xlate_by_fourcc(icd, + V4L2_PIX_FMT_NV12); + mf.width = 10000; + mf.height = 10000; + mf.field = V4L2_FIELD_NONE; + mf.code = xlate->code; + mf.reserved[6] = 0xfe5a; + v4l2_subdev_call(sd, video, try_mbus_fmt, &mf); - debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__); - pcdev->icd = icd; - pcdev->icd_init = 0; - - icd_catch = 0; - for (i=0; i<2; i++) { - if (pcdev->icd_frmival[i].icd == icd) - icd_catch = 1; - if (pcdev->icd_frmival[i].icd == NULL) { - pcdev->icd_frmival[i].icd = icd; - icd_catch = 1; - } - } - if (icd_catch == 0) { - fival_list = pcdev->icd_frmival[0].fival_list; - fival_nxt = fival_list; - while(fival_nxt != NULL) { - fival_nxt = fival_list->nxt; - kfree(fival_list); - fival_list = fival_nxt; - } - pcdev->icd_frmival[0].icd = icd; - pcdev->icd_frmival[0].fival_list = kzalloc(sizeof(struct rk_camera_frmivalenum),GFP_KERNEL); - } + pcdev->cropinfo.bounds.left = 0; + pcdev->cropinfo.bounds.top = 0; + pcdev->cropinfo.bounds.width = mf.width; + pcdev->cropinfo.bounds.height = mf.height; + } + } + + pcdev->icd = icd; + pcdev->icd_init = 0; + icd_catch = 0; + for (i = 0; i < 2; i++) { + if (pcdev->icd_frmival[i].icd == icd) + icd_catch = 1; + if (!pcdev->icd_frmival[i].icd) { + pcdev->icd_frmival[i].icd = icd; + icd_catch = 1; + } + } + if (icd_catch == 0) { + fival_list = pcdev->icd_frmival[0].fival_list; + fival_nxt = fival_list; + while (fival_nxt) { + fival_nxt = fival_list->nxt; + kfree(fival_list); + fival_list = fival_nxt; + } + pcdev->icd_frmival[0].icd = icd; + pcdev->icd_frmival[0].fival_list = + kzalloc(sizeof(struct rk_camera_frmivalenum), + GFP_KERNEL); + } ebusy: - mutex_unlock(&camera_lock); + mutex_unlock(&camera_lock); - return ret; + return ret; } static void rk_camera_remove_device(struct soc_camera_device *icd) { @@ -1469,6 +1718,7 @@ static void rk_camera_remove_device(struct soc_camera_device *icd) } #endif pcdev->active = NULL; + pcdev->active1 = NULL; pcdev->icd = NULL; pcdev->icd_cb.sensor_cb = NULL; pcdev->reginfo_suspend.Inval = Reg_Invalidate; @@ -1481,7 +1731,8 @@ static void rk_camera_remove_device(struct soc_camera_device *icd) return; } -static int rk_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) + +static int rk_camera_set_bus_param(struct soc_camera_device *icd) { unsigned long bus_flags, camera_flags, common_flags = 0; unsigned int cif_for = 0; @@ -1540,27 +1791,21 @@ static int rk_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING) { if(IS_CIF0()) { - if(CHIP_NAME == 3368) - rk3368_write_cru_reg(CRU_PCLK_REG30, rk3368_read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF0); + if (CHIP_NAME == 3228) + write_grf_reg(CRU_PCLK_REG30, read_grf_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF0); else write_cru_reg(CRU_PCLK_REG30, read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF0); } else { - if(CHIP_NAME == 3368) - rk3368_write_cru_reg(CRU_PCLK_REG30, rk3368_read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF1); - else - write_cru_reg(CRU_PCLK_REG30, read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF1); + write_cru_reg(CRU_PCLK_REG30, read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF1); } } else { if(IS_CIF0()){ - if(CHIP_NAME == 3368) - rk3368_write_cru_reg(CRU_PCLK_REG30, (rk3368_read_cru_reg(CRU_PCLK_REG30) & 0xFFFFFF7F ) | DISABLE_INVERT_PCLK_CIF0); + if (CHIP_NAME == 3228) + write_grf_reg(CRU_PCLK_REG30, (read_grf_reg(CRU_PCLK_REG30) & 0xFFFF7FFF) | DISABLE_INVERT_PCLK_CIF0); else write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFFFF7F ) | DISABLE_INVERT_PCLK_CIF0); } else { - if(CHIP_NAME == 3368) - rk3368_write_cru_reg(CRU_PCLK_REG30, (rk3368_read_cru_reg(CRU_PCLK_REG30) & 0xFFFEFFF) | DISABLE_INVERT_PCLK_CIF1); - else - write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFEFFF) | DISABLE_INVERT_PCLK_CIF1); + write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFEFFF) | DISABLE_INVERT_PCLK_CIF1); } } @@ -1654,14 +1899,44 @@ static const struct soc_mbus_pixelfmt rk_camera_formats[] = { }; -static void rk_camera_setup_format(struct soc_camera_device *icd, __u32 host_pixfmt, enum v4l2_mbus_pixelcode icd_code, struct v4l2_rect *rect) +static void rk_camera_setup_format(struct soc_camera_device *icd, __u32 host_pixfmt, u32 icd_code, struct v4l2_rect *rect) { struct soc_camera_host *ici = to_soc_camera_host(icd->parent); struct rk_camera_dev *pcdev = ici->priv; + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); unsigned int cif_fs = 0,cif_crop = 0; - unsigned int cif_fmt_val = read_cif_reg(pcdev->base,CIF_CIF_FOR) | INPUT_MODE_YUV|YUV_INPUT_422|INPUT_420_ORDER_EVEN|OUTPUT_420_ORDER_EVEN; - + unsigned int cif_fmt_val; const struct soc_mbus_pixelfmt *fmt; + struct rk_camera_device_signal_config dev_sig_cnf; + + v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_GET_INTERFACE, &dev_sig_cnf); + if (dev_sig_cnf.type == RK_CAMERA_DEVICE_CVBS_NTSC) + cif_fmt_val = INPUT_MODE_NTSC | YUV_OUTPUT_420; + else if (dev_sig_cnf.type == RK_CAMERA_DEVICE_CVBS_PAL) + cif_fmt_val = INPUT_MODE_PAL | YUV_OUTPUT_420; + else + cif_fmt_val = INPUT_MODE_YUV | YUV_INPUT_422 | INPUT_420_ORDER_EVEN | OUTPUT_420_ORDER_EVEN; + + if (dev_sig_cnf.type == RK_CAMERA_DEVICE_BT601_8 || + dev_sig_cnf.type == RK_CAMERA_DEVICE_CVBS_DEINTERLACE || + dev_sig_cnf.type == RK_CAMERA_DEVICE_BT601_PIONGPONG) { + if (dev_sig_cnf.dvp.vsync == RK_CAMERA_DEVICE_SIGNAL_HIGH_LEVEL) + cif_fmt_val |= VSY_HIGH_ACTIVE; + else + cif_fmt_val |= VSY_LOW_ACTIVE; + + if (dev_sig_cnf.dvp.hsync == RK_CAMERA_DEVICE_SIGNAL_HIGH_LEVEL) + cif_fmt_val |= HSY_HIGH_ACTIVE; + else + cif_fmt_val |= HSY_LOW_ACTIVE; + } + + pcdev->capture_pingpong = 0; + if (dev_sig_cnf.type == RK_CAMERA_DEVICE_BT601_PIONGPONG) + pcdev->capture_pingpong = 1; + + if (dev_sig_cnf.code) + icd_code = dev_sig_cnf.code; fmt = soc_mbus_get_fmtdesc(icd_code); debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__); @@ -1705,24 +1980,24 @@ static void rk_camera_setup_format(struct soc_camera_device *icd, __u32 host_pix cif_fmt_val |= YUV_OUTPUT_422; break; } - switch (icd_code) - { - case V4L2_MBUS_FMT_UYVY8_2X8: - cif_fmt_val = YUV_INPUT_ORDER_UYVY(cif_fmt_val); - break; - case V4L2_MBUS_FMT_YUYV8_2X8: - cif_fmt_val = YUV_INPUT_ORDER_YUYV(cif_fmt_val); - break; - case V4L2_MBUS_FMT_YVYU8_2X8: - cif_fmt_val = YUV_INPUT_ORDER_YVYU(cif_fmt_val); - break; - case V4L2_MBUS_FMT_VYUY8_2X8: - cif_fmt_val = YUV_INPUT_ORDER_VYUY(cif_fmt_val); - break; - default : + switch (icd_code) + { + case MEDIA_BUS_FMT_UYVY8_2X8: + cif_fmt_val = YUV_INPUT_ORDER_UYVY(cif_fmt_val); + break; + case MEDIA_BUS_FMT_YUYV8_2X8: cif_fmt_val = YUV_INPUT_ORDER_YUYV(cif_fmt_val); - break; - } + break; + case MEDIA_BUS_FMT_YVYU8_2X8: + cif_fmt_val = YUV_INPUT_ORDER_YVYU(cif_fmt_val); + break; + case MEDIA_BUS_FMT_VYUY8_2X8: + cif_fmt_val = YUV_INPUT_ORDER_VYUY(cif_fmt_val); + break; + default : + cif_fmt_val = YUV_INPUT_ORDER_YUYV(cif_fmt_val); + break; + } mdelay(100); rk_camera_cif_reset(pcdev,true); @@ -1733,22 +2008,28 @@ static void rk_camera_setup_format(struct soc_camera_device *icd, __u32 host_pix write_cif_reg(pcdev->base,CIF_CIF_FOR,cif_fmt_val); /* ddl@rock-chips.com: VIP capture mode and capture format must be set before FS register set */ write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xFFFFFFFF); - if((read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_PINGPONG) - ||(read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_LINELOOP)) { - BUG(); - } else{ /* this is one frame mode*/ - cif_crop = (rect->left + (rect->top <<16)); - cif_fs = (rect->width + (rect->height <<16)); - } + + cif_crop = ((rect->left + dev_sig_cnf.crop.left) + + ((rect->top + dev_sig_cnf.crop.top) << 16)); + + if (dev_sig_cnf.crop.width || dev_sig_cnf.crop.height) + cif_fs = (dev_sig_cnf.crop.width + + (dev_sig_cnf.crop.height << 16)); + else + cif_fs = (rect->width + (rect->height << 16)); write_cif_reg(pcdev->base,CIF_CIF_CROP, cif_crop); write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, cif_fs); write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH, rect->width); - write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000003); + if (pcdev->capture_pingpong) + write_cif_reg(pcdev->base, CIF_CIF_FRAME_STATUS, 0x10000002); + else + write_cif_reg(pcdev->base, CIF_CIF_FRAME_STATUS, 0x00000003); /*MUST bypass scale */ write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL,0x10); - RKCAMERA_DG1("CIF_CIF_CROP:0x%x CIF_CIF_FS:0x%x CIF_CIF_FOR:0x%x\n",cif_crop,cif_fs,cif_fmt_val); + RKCAMERA_DG1("CIF_CIF_CROP:0x%x CIF_CIF_FS:0x%x CIF_CIF_FOR:0x%x\n", + cif_crop, cif_fs, cif_fmt_val); return; } @@ -1758,7 +2039,7 @@ static int rk_camera_get_formats(struct soc_camera_device *icd, unsigned int idx struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct device *dev = icd->parent; int formats = 0, ret; - enum v4l2_mbus_pixelcode code; + u32 code; const struct soc_mbus_pixelfmt *fmt; debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__); @@ -1779,11 +2060,11 @@ static int rk_camera_get_formats(struct soc_camera_device *icd, unsigned int idx if (ret < 0) return 0; - switch (code) { - case V4L2_MBUS_FMT_UYVY8_2X8: - case V4L2_MBUS_FMT_YUYV8_2X8: - case V4L2_MBUS_FMT_YVYU8_2X8: - case V4L2_MBUS_FMT_VYUY8_2X8: + switch (code) { + case MEDIA_BUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YVYU8_2X8: + case MEDIA_BUS_FMT_VYUY8_2X8: { #if (CONFIG_CAMERA_SCALE_CROP_MACHINE != RK_CAM_SCALE_CROP_RGA) @@ -1929,6 +2210,26 @@ static bool rk_camera_fmt_capturechk(struct v4l2_format *f) RKCAMERA_DG1("%dx%d is capture format\n",f->fmt.pix.width, f->fmt.pix.height); return ret; } + +static int rk_camera_get_fmt(struct soc_camera_device *icd, + struct v4l2_format *f) +{ + struct v4l2_pix_format *pix = &f->fmt.pix; + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + struct rk_camera_device_signal_config dev_sig_cnf; + + v4l2_subdev_call(sd, core, ioctl, + RK29_CAM_SUBDEV_GET_INTERFACE, &dev_sig_cnf); + if (dev_sig_cnf.crop.width > 32 && dev_sig_cnf.crop.width <= 8192) { + pix->width = dev_sig_cnf.crop.width; + pix->height = dev_sig_cnf.crop.height; + RKCAMERA_DG1("rk_camera_get_fmt: f->fmt->pixsize %dx%d\n", + f->fmt.pix.width, f->fmt.pix.height); + } + + return 0; +} + static int rk_camera_set_fmt(struct soc_camera_device *icd, struct v4l2_format *f) { @@ -2213,21 +2514,20 @@ static int rk_camera_try_fmt(struct soc_camera_device *icd, if (pix->bytesperline < 0) return pix->bytesperline; - /* limit to sensor capabilities */ - memset(&mf,0x00,sizeof(struct v4l2_mbus_framefmt)); + /* limit to sensor capabilities */ + memset(&mf, 0x00, sizeof(struct v4l2_mbus_framefmt)); mf.width = pix->width; mf.height = pix->height; mf.field = pix->field; mf.colorspace = pix->colorspace; mf.code = xlate->code; - /* ddl@rock-chips.com : It is query max resolution only. */ - if ((usr_w == 10000) && (usr_h == 10000)) { - mf.reserved[6] = 0xfefe5a5a; - } + /* ddl@rock-chips.com : It is query max resolution only. */ + if ((usr_w == 10000) && (usr_h == 10000)) + mf.reserved[6] = 0xfe5a; ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf); if (ret < 0) goto RK_CAMERA_TRY_FMT_END; - + /*query resolution.*/ if((usr_w == 10000) && (usr_h == 10000)) { pix->width = mf.width; @@ -2366,10 +2666,13 @@ static int rk_camera_querycap(struct soc_camera_host *ici, } else { strcat(cap->card,orientation); } - - strcat(cap->card,fov); /* ddl@rock-chips.com: v0.3.f */ - cap->version = RK_CAM_VERSION_CODE; - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + + /* ddl@rock-chips.com: v0.3.f */ + strcat(cap->card, fov); + cap->reserved[0] = pcdev->pdata->iommu_enabled; + cap->version = RK_CAM_VERSION_CODE; + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; cap->reserved[0] = pcdev->pdata->iommu_enabled; debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__); @@ -2479,8 +2782,8 @@ static void rk_camera_reinit_work(struct work_struct *work) RKCAMERA_TR("CIF_CIF_CROP = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CROP)); RKCAMERA_TR("CIF_CIF_SET_SIZE = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE)); RKCAMERA_TR("CIF_CIF_SCL_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL)); - if(CHIP_NAME == 3368) - RKCAMERA_TR("CRU_PCLK_REG30 = 0X%x\n",rk3368_read_cru_reg(CRU_PCLK_REG30)); + if (CHIP_NAME == 3228) + RKCAMERA_TR("CRU_PCLK_REG30 = 0X%x\n", read_grf_reg(CRU_PCLK_REG30)); else RKCAMERA_TR("CRU_PCLK_REG30 = 0X%x\n",read_cru_reg(CRU_PCLK_REG30)); RKCAMERA_TR("CIF_CIF_LAST_LINE = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_LINE)); @@ -2495,35 +2798,37 @@ static void rk_camera_reinit_work(struct work_struct *work) RKCAMERA_TR("CIF_CIF_CUR_DST = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_CUR_DST)); RKCAMERA_TR("CIF_CIF_LINE_NUM_ADDR = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LINE_NUM_ADDR)); } - - ctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL); /*ddl@rock-chips.com v0.3.0x13*/ - if (pcdev->reinit_times == 1) { - if (ctrl & ENABLE_CAPTURE) { - RKCAMERA_TR("Sensor data transfer may be error, so reset CIF and reinit sensor for resume!\n"); - pcdev->irqinfo.cifirq_idx = pcdev->irqinfo.dmairq_idx; - rk_camera_cif_reset(pcdev,false); - - v4l2_subdev_call(sd,core, init, 0); - - mf.width = pcdev->icd_width; - mf.height = pcdev->icd_height; - mf.field = V4L2_FIELD_NONE; - mf.code = pcdev->icd->current_fmt->code; - mf.reserved[0] = 0x5a5afefe; - mf.reserved[1] = 0; + /*ddl@rock-chips.com v0.3.0x13*/ + ctrl = read_cif_reg(pcdev->base, CIF_CIF_CTRL); + if (pcdev->reinit_times == 1) { + if (ctrl & ENABLE_CAPTURE) { + RKCAMERA_TR("Sensor data transfer may be error, so reset CIF and reinit sensor for resume!\n"); + pcdev->irqinfo.cifirq_idx = pcdev->irqinfo.dmairq_idx; + rk_camera_cif_reset(pcdev, false); - v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); - - write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)|ENABLE_CAPTURE)); - } else if (pcdev->irqinfo.cifirq_idx != pcdev->irqinfo.dmairq_idx) { - RKCAMERA_TR("CIF may be error, so reset cif for resume\n"); - pcdev->irqinfo.cifirq_idx = pcdev->irqinfo.dmairq_idx; - rk_camera_cif_reset(pcdev,false); - write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)|ENABLE_CAPTURE)); - } - return; - } + v4l2_subdev_call(sd, core, init, 0); + mf.width = pcdev->icd_width; + mf.height = pcdev->icd_height; + mf.field = V4L2_FIELD_NONE; + mf.code = pcdev->icd->current_fmt->code; + mf.reserved[0] = 0x5afe; + mf.reserved[1] = 0; + + v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); + write_cif_reg(pcdev->base, CIF_CIF_CTRL, + (read_cif_reg(pcdev->base, CIF_CIF_CTRL) | + ENABLE_CAPTURE)); + } else if (pcdev->irqinfo.cifirq_idx != pcdev->irqinfo.dmairq_idx) { + RKCAMERA_TR("CIF may be error, so reset cif for resume\n"); + pcdev->irqinfo.cifirq_idx = pcdev->irqinfo.dmairq_idx; + rk_camera_cif_reset(pcdev, false); + write_cif_reg(pcdev->base, CIF_CIF_CTRL, + (read_cif_reg(pcdev->base, CIF_CIF_CTRL) | + ENABLE_CAPTURE)); + } + return; + } atomic_set(&pcdev->stop_cif,true); write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)&(~ENABLE_CAPTURE))); @@ -2700,6 +3005,7 @@ static int rk_camera_s_stream(struct soc_camera_device *icd, int enable) /*must be reinit,or will be somthing wrong in irq process.*/ if(enable == false) { pcdev->active = NULL; + pcdev->active1 = NULL; INIT_LIST_HEAD(&pcdev->capture); } RKCAMERA_DG1("s_stream: enable : 0x%x , CIF_CIF_CTRL = 0x%x\n",enable,read_cif_reg(pcdev->base,CIF_CIF_CTRL)); @@ -2879,9 +3185,16 @@ static int rk_camera_set_digit_zoom(struct soc_camera_device *icd, write_cif_reg(pcdev->base,CIF_CIF_CROP, (a.c.left + (a.c.top<<16))); write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, ((a.c.width ) + (a.c.height<<16))); write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH, a.c.width); - write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000002);//frame1 has been ready to receive data,frame 2 is not used - if(pcdev->active) - rk_videobuf_capture(pcdev->active,pcdev); + if (pcdev->capture_pingpong) { + write_cif_reg(pcdev->base, CIF_CIF_FRAME_STATUS, 0x10000002); + if (pcdev->active) + rk_videobuf_capture_mix(pcdev->active, pcdev, 0); + } else { + /*frame1 has been ready to receive data,frame 2 is not used*/ + write_cif_reg(pcdev->base, CIF_CIF_FRAME_STATUS, 0x00000002); + if (pcdev->active) + rk_videobuf_capture(pcdev->active, pcdev); + } if(tmp_cifctrl & ENABLE_CAPTURE) write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl | ENABLE_CAPTURE)); up(&pcdev->zoominfo.sem); @@ -2980,6 +3293,7 @@ static struct soc_camera_host_ops rk_soc_camera_host_ops = .get_crop = rk_camera_get_crop, .get_formats = rk_camera_get_formats, .put_formats = rk_camera_put_formats, + .get_fmt = rk_camera_get_fmt, .set_fmt = rk_camera_set_fmt, .try_fmt = rk_camera_try_fmt, .init_videobuf = rk_camera_init_videobuf, @@ -3008,7 +3322,8 @@ static int rk_camera_cif_iomux(struct device *dev) __raw_writel(((1<<1)|(1<<(1+16))),RK_GRF_VIRT+0x0380); }else if(CHIP_NAME == 3368){ //__raw_writel(((1<<1)|(1<<(1+16))),RK_GRF_VIRT+0x0900); - __raw_writel(((1<<1)|(1<<(1+16))),rk_cif_grf_base+0x0900); + //__raw_writel(((1<<1)|(1<<(1+16))),rk_cif_grf_base+0x0900); + regmap_write(rk_cif_grf_base, 0x0900, ((1<<1)|(1<<(1+16)))); } /*mux CIF0_CLKOUT*/ @@ -3092,30 +3407,40 @@ static int rk_camera_probe(struct platform_device *pdev) if (IS_CIF0()) { debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$/is_cif0\n"); - clk = &cif_clk[0]; - if(CHIP_NAME != 3368) - cif_clk[0].pd_cif = devm_clk_get(dev_cif, "pd_cif0"); + clk = &cif_clk[0]; + if (CHIP_NAME != 3228) + clk->pd_cif = devm_clk_get(dev_cif, "pd_cif0"); + if (CHIP_NAME == 3368) + clk->pclk_cif = + devm_clk_get(dev_cif, "pclk_cif"); + clk->aclk_cif = devm_clk_get(dev_cif, "aclk_cif0"); + clk->hclk_cif = devm_clk_get(dev_cif, "hclk_cif0"); + if (CHIP_NAME != 3228) + clk->cif_clk_in = devm_clk_get(dev_cif, "cif0_in"); + clk->cif_clk_out = devm_clk_get(dev_cif, "cif0_out"); + clk->cif_rst = devm_reset_control_get(dev_cif, "rst_cif"); + if (IS_ERR_OR_NULL(clk->cif_rst)) { + printk(KERN_ERR "no cif reset resource define\n"); + clk->cif_rst = NULL; + } + /* spin_lock_init(&cif_clk[0].lock); */ + clk->on = false; + rk_camera_cif_iomux(dev_cif); + } else { + clk = &cif_clk[1]; + if (CHIP_NAME != 3368 && CHIP_NAME != 3228) + /*cif0 only */ + clk->pd_cif = devm_clk_get(dev_cif, "pd_cif0"); - cif_clk[0].aclk_cif = devm_clk_get(dev_cif, "aclk_cif0"); - cif_clk[0].hclk_cif = devm_clk_get(dev_cif, "hclk_cif0"); - cif_clk[0].cif_clk_in = devm_clk_get(dev_cif, "cif0_in"); - cif_clk[0].cif_clk_out = devm_clk_get(dev_cif, "cif0_out"); - //spin_lock_init(&cif_clk[0].lock); - cif_clk[0].on = false; - rk_camera_cif_iomux(dev_cif); - } else { - clk = &cif_clk[1]; - if(CHIP_NAME != 3368) - cif_clk[1].pd_cif = devm_clk_get(dev_cif, "pd_cif0");/*cif0 only */ - - cif_clk[1].aclk_cif = devm_clk_get(dev_cif, "aclk_cif0"); - cif_clk[1].hclk_cif = devm_clk_get(dev_cif, "hclk_cif0"); - cif_clk[1].cif_clk_in = devm_clk_get(dev_cif, "cif0_in"); - cif_clk[1].cif_clk_out = devm_clk_get(dev_cif, "cif0_out"); - //spin_lock_init(&cif_clk[1].lock); - cif_clk[1].on = false; - rk_camera_cif_iomux(dev_cif); - } + clk->aclk_cif = devm_clk_get(dev_cif, "aclk_cif0"); + clk->hclk_cif = devm_clk_get(dev_cif, "hclk_cif0"); + if (CHIP_NAME != 3228) + clk->cif_clk_in = devm_clk_get(dev_cif, "cif0_in"); + clk->cif_clk_out = devm_clk_get(dev_cif, "cif0_out"); + /* spin_lock_init(&cif_clk[1].lock); */ + clk->on = false; + rk_camera_cif_iomux(dev_cif); + } debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__); @@ -3155,21 +3480,19 @@ static int rk_camera_probe(struct platform_device *pdev) goto exit_ioremap_vip; } } - pcdev->irqinfo.irq = irq; pcdev->dev = &pdev->dev; - /* config buffer address */ - /* request irq */ - if(irq > 0){ - err = request_irq(pcdev->irqinfo.irq, rk_camera_irq, IRQF_DISABLED | IRQF_SHARED , RK29_CAM_DRV_NAME, - pcdev); + /* config buffer address */ + /* request irq */ + if (irq > 0) { + err = request_irq(pcdev->irqinfo.irq, rk_camera_irq, + IRQF_SHARED, RK29_CAM_DRV_NAME, pcdev); if (err) { dev_err(pcdev->dev, "Camera interrupt register failed \n"); goto exit_reqirq; } } - if(IS_CIF0()) { pcdev->camera_wq = create_workqueue("rk_cam_wkque_cif0"); } else { @@ -3239,21 +3562,7 @@ exit_reqirq: exit_ioremap_vip: release_mem_region(res->start, res->end - res->start + 1); exit_reqmem_vip: - if (clk) { - if(CHIP_NAME != 3368){ - if (clk->pd_cif) - clk_put(clk->pd_cif); - } - if (clk->aclk_cif) - clk_put(clk->aclk_cif); - if (clk->hclk_cif) - clk_put(clk->hclk_cif); - if (clk->cif_clk_in) - clk_put(clk->cif_clk_in); - if (clk->cif_clk_out) - clk_put(clk->cif_clk_out); - } - kfree(pcdev); + kfree(pcdev); exit_alloc: exit: diff --git a/drivers/media/video/rk30_camera_pingpong.c b/drivers/media/video/rk30_camera_pingpong.c old mode 100755 new mode 100644 index 8fe805c0674e..117a2182f4b2 --- a/drivers/media/video/rk30_camera_pingpong.c +++ b/drivers/media/video/rk30_camera_pingpong.c @@ -1,3 +1,15 @@ +/* + * Copyright (C) ROCKCHIP, Inc. + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + #include #include #include @@ -28,7 +40,7 @@ #include #include "../../video/rockchip/rga/rga.h" -#include "../../../arch/arm/mach-rockchip/rk30_camera.h"/*yzm*/ +#include "../../../drivers/soc/rockchip/rk30_camera.h"/*yzm*/ #include /*******yzm********* @@ -161,8 +173,8 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define CIF_F0_READY (0x01<<0) #define CIF_F1_READY (0x01<<1) -extern unsigned long rk_cif_grf_base; -extern unsigned long rk_cif_cru_base; +extern void __iomem *rk_cif_grf_base; +extern void __iomem *rk_cif_cru_base; #define MIN(x,y) ((xy) ? x: y) diff --git a/drivers/media/video/sp0838.c b/drivers/media/video/sp0838.c old mode 100755 new mode 100644 index 941dcb42e372..c107fcb99df0 --- a/drivers/media/video/sp0838.c +++ b/drivers/media/video/sp0838.c @@ -1,4 +1,17 @@ -//#include +/* + * drivers/media/video/sp0838.c + * + * Copyright (C) ROCKCHIP, Inc. + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + #include "generic_sensor.h" /* * Driver Version Note @@ -1351,7 +1364,7 @@ static struct sensor_v4l2ctrl_usr_s sensor_controls[] = //MUST define the current used format as the first item static struct rk_sensor_datafmt sensor_colour_fmts[] = { - {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} + {MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} }; //static struct soc_camera_ops sensor_ops; diff --git a/drivers/media/video/sp2518.c b/drivers/media/video/sp2518.c old mode 100755 new mode 100644 index a003f30f05fc..1614dcbd8939 --- a/drivers/media/video/sp2518.c +++ b/drivers/media/video/sp2518.c @@ -1,3 +1,16 @@ +/* + * drivers/media/video/sp2518.c + * + * Copyright (C) ROCKCHIP, Inc. + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ #include "generic_sensor.h" /* @@ -1051,7 +1064,7 @@ static struct sensor_v4l2ctrl_usr_s sensor_controls[] = //MUST define the current used format as the first item static struct rk_sensor_datafmt sensor_colour_fmts[] = { - {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} + {MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} }; /*static struct soc_camera_ops sensor_ops;*/ diff --git a/drivers/media/video/tp2825.c b/drivers/media/video/tp2825.c new file mode 100644 index 000000000000..fa351ce46d53 --- /dev/null +++ b/drivers/media/video/tp2825.c @@ -0,0 +1,1846 @@ +/* + * drivers/media/video/tp2825.c + * + * Copyright (C) ROCKCHIP, Inc. + * Author:zhoupeng + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "generic_sensor.h" +#include +#include +#include +#include + +/* +* Driver Version Note +*v0.0.1: this driver is compatible with generic_sensor +*v0.0.2: support debug_fs for debug +* support irq interrupt for switch input source +* support support PAL mode +*/ +static int version = KERNEL_VERSION(0, 0, 2); +module_param(version, int, S_IRUGO); + +static int debug; +module_param(debug, int, S_IRUGO | S_IWUSR); + +#define dprintk(level, fmt, arg...) do { \ + if (debug >= level) \ + printk(KERN_WARNING fmt, ## arg); \ +} while (0) +#define debug_printk(format, ...) dprintk(1, format, ## __VA_ARGS__) +/* Sensor Driver Configuration Begin */ +#define SENSOR_NAME RK29_CAM_SENSOR_TP2825 +#define SENSOR_V4L2_IDENT V4L2_IDENT_TP2825 +#define SENSOR_ID 0x2825 +#define SENSOR_BUS_PARAM (V4L2_MBUS_MASTER | \ + V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH | \ + V4L2_MBUS_DATA_ACTIVE_HIGH | SOCAM_MCLK_24MHZ) + +static int SENSOR_PREVIEW_W = 1280; +static int SENSOR_PREVIEW_H = 720; + +static struct rk_camera_device_signal_config dev_info[] = { + { + .type = RK_CAMERA_DEVICE_BT601_PIONGPONG, + .dvp = { + .vsync = RK_CAMERA_DEVICE_SIGNAL_HIGH_LEVEL, + .hsync = RK_CAMERA_DEVICE_SIGNAL_HIGH_LEVEL + }, + .crop = { + .top = 20, + .left = 8, + .width = 1280, + .height = 720 + } + } +}; + +static struct rk_camera_device_defrect defrects[4]; + +#define SENSOR_PREVIEW_FPS 30000 /* 30fps */ +#define SENSOR_FULLRES_L_FPS 15000 /* 15fps */ +#define SENSOR_FULLRES_H_FPS 15000 /* 15fps */ +#define SENSOR_720P_FPS 0 +#define SENSOR_1080P_FPS 0 + +#define SENSOR_REGISTER_LEN 1 /* sensor register address bytes */ +#define SENSOR_VALUE_LEN 1 /* sensor register value bytes */ +static char input_mode[10] = "720P"; +#define SENSOR_CHANNEL_REG 0x41 +#define SENSOR_CLAMPING_CONTROL 0x26 + +static unsigned int SensorConfiguration = (CFG_Effect | CFG_Scene); +static unsigned int SensorChipID[] = {SENSOR_ID}; +/* Sensor Driver Configuration End */ + +#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) +#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) + +#define SensorRegVal(a, b) CONS4(SensorReg, SENSOR_REGISTER_LEN, Val, SENSOR_VALUE_LEN)(a, b) +#define sensor_write(client, reg, v) CONS4(sensor_write_reg, SENSOR_REGISTER_LEN, val, SENSOR_VALUE_LEN)(client, (reg), (v)) +#define sensor_read(client, reg, v) CONS4(sensor_read_reg, SENSOR_REGISTER_LEN, val, SENSOR_VALUE_LEN)(client, (reg), (v)) +#define sensor_write_array generic_sensor_write_array + +struct sensor_parameter { + unsigned int PreviewDummyPixels; + unsigned int CaptureDummyPixels; + unsigned int preview_exposure; + + unsigned short int preview_line_width; + unsigned short int preview_gain; + unsigned short int PreviewPclk; + unsigned short int CapturePclk; + char awb[6]; +}; + +struct specific_sensor { + struct generic_sensor common_sensor; + struct sensor_parameter parameter; +}; + +/* +* The follow setting need been filled. +* +* Must Filled: +* sensor_init_data : Sensor initial setting; +* sensor_fullres_lowfps_data : Sensor full resolution setting with best auality, recommand for video; +* sensor_preview_data : Sensor preview resolution setting, recommand it is vga or svga; +* sensor_softreset_data : Sensor software reset register; +* sensor_check_id_data : Sensir chip id register; +* +* Optional filled: +* sensor_fullres_highfps_data: Sensor full resolution setting with high framerate, recommand for video; +* sensor_720p: Sensor 720p setting, it is for video; +* sensor_1080p: Sensor 1080p setting, it is for video; +* +* :::::WARNING::::: +* The SensorEnd which is the setting end flag must be filled int the last of each setting; +*/ + +/* Sensor initial setting */ +static struct rk_sensor_reg sensor_preview_data[] = { + SensorEnd +}; + +/* Senor full resolution setting: recommand for capture */ +static struct rk_sensor_reg sensor_fullres_lowfps_data[] = { + SensorEnd +}; + +/* Senor full resolution setting: recommand for video */ +static struct rk_sensor_reg sensor_fullres_highfps_data[] = { + SensorEnd +}; + +/* Preview resolution setting*/ +static struct rk_sensor_reg sensor_preview_data_ntsc[] = { + {0x02, 0xCF}, + {0x06, 0x32}, + {0x07, 0xC0}, + {0x08, 0x00}, + {0x09, 0x24}, + {0x0A, 0x48}, + {0x0B, 0xC0}, + {0x0C, 0x53}, + {0x0D, 0x10}, + {0x0E, 0x00}, + {0x0F, 0x00}, + {0x10, 0x5e}, + {0x11, 0x40}, + {0x12, 0x44}, + {0x13, 0x00}, + {0x14, 0x00}, + {0x15, 0x13}, + {0x16, 0x4E}, + {0x17, 0xBC}, + {0x18, 0x15}, + {0x19, 0xF0}, + {0x1A, 0x07}, + {0x1B, 0x00}, + {0x1C, 0x09}, + {0x1D, 0x38}, + {0x1E, 0x80}, + {0x1F, 0x80}, + {0x20, 0xA0}, + {0x21, 0x86}, + {0x22, 0x38}, + {0x23, 0x3C}, + {0x24, 0x56}, + {0x25, 0xFF}, + {0x27, 0x2D}, + {0x28, 0x00}, + {0x29, 0x48}, + {0x2A, 0x30}, + {0x2B, 0x70}, + {0x2C, 0x0A},/*1a*/ + {0x2D, 0x68}, + {0x2E, 0x5E}, + {0x2F, 0x00}, + {0x30, 0x62}, + {0x31, 0xBB}, + {0x32, 0x96}, + {0x33, 0xC0}, + {0x34, 0x00}, + {0x35, 0x65}, + {0x36, 0xDC}, + {0x37, 0x00}, + {0x38, 0x40}, + {0x39, 0x84}, + {0x3A, 0x00}, + {0x3B, 0x03}, + {0x3C, 0x00}, + {0x3D, 0x60}, + {0x3E, 0x00}, + {0x3F, 0x00}, + {0x40, 0x00}, + {0x42, 0x00}, + {0x43, 0x12}, + {0x44, 0x07}, + {0x45, 0x49}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4A, 0x00}, + {0x4B, 0x00}, + {0x4C, 0x03}, + //{0x4D, 0x03}, + {0x4E, 0x37}, + {0x4F, 0x01}, + {0xB5, 0x01}, + {0xB8, 0x02}, + {0xBA, 0x10}, + {0xF3, 0x00}, + {0xF4, 0x00}, + {0xF5, 0x00}, + {0xF6, 0x00}, + {0xF7, 0x00}, + {0xF8, 0x00}, + {0xF9, 0x00}, + {0xFA, 0x00}, + {0xFB, 0x00}, + {0xFC, 0xC0}, + {0xFD, 0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_preview_data_pal[] = { + {0x02, 0xCE}, + {0x06, 0x32}, + {0x07, 0xC0}, + {0x08, 0x00}, + {0x09, 0x24}, + {0x0A, 0x48}, + {0x0B, 0xC0}, + {0x0C, 0x53}, + {0x0D, 0x11}, + {0x0E, 0x00}, + {0x0F, 0x00}, + {0x10, 0x70}, + {0x11, 0x4D}, + {0x12, 0x40}, + {0x13, 0x00}, + {0x14, 0x00}, + {0x15, 0x13}, + {0x16, 0x67}, + {0x17, 0xBC}, + {0x18, 0x16}, + {0x19, 0x20}, + {0x1A, 0x17}, + {0x1B, 0x00}, + {0x1C, 0x09}, + {0x1D, 0x48}, + {0x1E, 0x80}, + {0x1F, 0x80}, + {0x20, 0xB0}, + {0x21, 0x86}, + {0x22, 0x38}, + {0x23, 0x3C}, + {0x24, 0x56}, + {0x25, 0xFF}, + {0x27, 0x2D}, + {0x28, 0x00}, + {0x29, 0x48}, + {0x2A, 0x30}, + {0x2B, 0x70}, + {0x2C, 0x1A}, + {0x2D, 0x60}, + {0x2E, 0x5E}, + {0x2F, 0x00}, + {0x30, 0x7A}, + {0x31, 0x4A}, + {0x32, 0x4D}, + {0x33, 0xF0}, + {0x34, 0x00}, + {0x35, 0x65}, + {0x36, 0xDC}, + {0x37, 0x00}, + {0x38, 0x40}, + {0x39, 0x84}, + {0x3A, 0x00}, + {0x3B, 0x03}, + {0x3C, 0x00}, + {0x3D, 0x60}, + {0x3E, 0x00}, + {0x3F, 0x00}, + {0x40, 0x00}, + {0x42, 0x00}, + {0x43, 0x12}, + {0x44, 0x07}, + {0x45, 0x49}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4A, 0x00}, + {0x4B, 0x00}, + {0x4C, 0x03}, + //{0x4D, 0x03}, + {0x4E, 0x37}, + {0x4F, 0x01}, + {0xB5, 0x01}, + {0xB8, 0x02}, + {0xBA, 0x10}, + {0xF3, 0x00}, + {0xF4, 0x00}, + {0xF5, 0x00}, + {0xF6, 0x00}, + {0xF7, 0x00}, + {0xF8, 0x00}, + {0xF9, 0x00}, + {0xFA, 0x00}, + {0xFB, 0x00}, + {0xFC, 0xC0}, + {0xFD, 0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_preview_data_720p_50hz[] = { + {0x02, 0xCA}, + {0x06, 0x32}, + {0x07, 0xC0}, + {0x08, 0x00}, + {0x09, 0x24}, + {0x0A, 0x48}, + {0x0B, 0xC0}, + {0x0C, 0x43}, + {0x0D, 0x10}, + {0x0E, 0x00}, + {0x0F, 0x00}, + {0x10, 0xf0}, + {0x11, 0x50}, + {0x12, 0x60}, + {0x13, 0x00}, + {0x14, 0x08}, + {0x15, 0x13}, + {0x16, 0x16}, + {0x17, 0x00}, + {0x18, 0x18}, + {0x19, 0xD0}, + {0x1A, 0x25}, + {0x1B, 0x00}, + {0x1C, 0x07}, + {0x1D, 0xBC}, + {0x1E, 0x80}, + {0x1F, 0x80}, + {0x20, 0x60}, + {0x21, 0x86}, + {0x22, 0x38}, + {0x23, 0x3C}, + {0x24, 0x56}, + {0x25, 0xFF}, + {0x27, 0x2D}, + {0x28, 0x00}, + {0x29, 0x48}, + {0x2A, 0x30}, + {0x2B, 0x4A}, + {0x2C, 0x1A}, + {0x2D, 0x30}, + {0x2E, 0x70}, + {0x2F, 0x00}, + {0x30, 0x48}, + {0x31, 0xBB}, + {0x32, 0x2E}, + {0x33, 0x90}, + {0x34, 0x00}, + {0x35, 0x05}, + {0x36, 0xDC}, + {0x37, 0x00}, + {0x38, 0x40}, + {0x39, 0x8C}, + {0x3A, 0x00}, + {0x3B, 0x03}, + {0x3C, 0x00}, + {0x3D, 0x60}, + {0x3E, 0x00}, + {0x3F, 0x00}, + {0x40, 0x00}, + {0x42, 0x00}, + {0x43, 0x12}, + {0x44, 0x07}, + {0x45, 0x49}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4A, 0x00}, + {0x4B, 0x00}, + {0x4C, 0x03}, + //{0x4D, 0x03}, + {0x4E, 0x03}, + {0x4F, 0x01}, + {0xB5, 0x01}, + {0xB8, 0x02}, + {0xBA, 0x10}, + {0xF3, 0x00}, + {0xF4, 0x00}, + {0xF5, 0x00}, + {0xF6, 0x00}, + {0xF7, 0x00}, + {0xF8, 0x00}, + {0xF9, 0x00}, + {0xFA, 0x00}, + {0xFB, 0x00}, + {0xFC, 0xC0}, + {0xFD, 0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_preview_data_720p_30hz[] = { + {0x02, 0xDA}, + {0x06, 0x32}, + {0x07, 0xC0}, + {0x08, 0x00}, + {0x09, 0x24}, + {0x0A, 0x48}, + {0x0B, 0xC0}, + {0x0C, 0x53}, + {0x0D, 0x10}, + {0x0E, 0x00}, + {0x0F, 0x00}, + {0x10, 0xf0}, + {0x11, 0x50}, + {0x12, 0x60}, + {0x13, 0x00}, + {0x14, 0x08}, + {0x15, 0x13}, + {0x16, 0x16}, + {0x17, 0x00}, + {0x18, 0x19}, + {0x19, 0xD0}, + {0x1A, 0x25}, + {0x1B, 0x00}, + {0x1C, 0x06}, + {0x1D, 0x72}, + {0x1E, 0x80}, + {0x1F, 0x80}, + {0x20, 0x60}, + {0x21, 0x86}, + {0x22, 0x38}, + {0x23, 0x3C}, + {0x24, 0x56}, + {0x25, 0xFF}, + {0x27, 0x2D}, + {0x28, 0x00}, + {0x29, 0x48}, + {0x2A, 0x30}, + {0x2B, 0x4A}, + {0x2C, 0x1A}, + {0x2D, 0x30}, + {0x2E, 0x70}, + {0x2F, 0x00}, + {0x30, 0x48}, + {0x31, 0xBB}, + {0x32, 0x2E}, + {0x33, 0x90}, + {0x34, 0x00}, + {0x35, 0x25}, + {0x36, 0xDC}, + {0x37, 0x00}, + {0x38, 0x40}, + {0x39, 0x88}, + {0x3A, 0x00}, + {0x3B, 0x03}, + {0x3C, 0x00}, + {0x3D, 0x60}, + {0x3E, 0x00}, + {0x3F, 0x00}, + {0x40, 0x03}, + {0x42, 0x00}, + {0x43, 0x12}, + {0x44, 0x07}, + {0x45, 0x49}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4A, 0x00}, + {0x4B, 0x00}, + {0x4C, 0x03}, + //{0x4D, 0x03}, + {0x4E, 0x17}, + {0x4F, 0x01}, + {0x85, 0x00}, + {0x88, 0x00}, + {0x8A, 0x00}, + {0xF3, 0x00}, + {0xF4, 0x00}, + {0xF5, 0x00}, + {0xF6, 0x00}, + {0xF7, 0x00}, + {0xF8, 0x00}, + {0xF9, 0x00}, + {0xFA, 0x00}, + {0xFB, 0x00}, + {0xFC, 0xC0}, + {0xFD, 0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_preview_data_720p_25hz[] = { + {0x02, 0xCA}, + {0x06, 0x32}, + {0x07, 0xC0}, + {0x08, 0x00}, + {0x09, 0x24}, + {0x0A, 0x48}, + {0x0B, 0xC0}, + {0x0C, 0x53}, + {0x0D, 0x10}, + {0x0E, 0x00}, + {0x0F, 0x00}, + {0x10, 0xf0}, + {0x11, 0x50}, + {0x12, 0x60}, + {0x13, 0x00}, + {0x14, 0x08}, + {0x15, 0x13}, + {0x16, 0x16}, + {0x17, 0x00}, + {0x18, 0x19}, + {0x19, 0xD0}, + {0x1A, 0x25}, + {0x1B, 0x00}, + {0x1C, 0x07}, + {0x1D, 0xBC}, + {0x1E, 0x80}, + {0x1F, 0x80}, + {0x20, 0x60}, + {0x21, 0x86}, + {0x22, 0x38}, + {0x23, 0x3C}, + {0x24, 0x56}, + {0x25, 0xFF}, + {0x27, 0x2D}, + {0x28, 0x00}, + {0x29, 0x48}, + {0x2A, 0x30}, + {0x2B, 0x70}, + {0x2C, 0x1A}, + {0x2D, 0x30}, + {0x2E, 0x70}, + {0x2F, 0x00}, + {0x30, 0x48}, + {0x31, 0xBB}, + {0x32, 0x2E}, + {0x33, 0x90}, + {0x34, 0x00}, + {0x35, 0x25}, + {0x36, 0xDC}, + {0x37, 0x00}, + {0x38, 0x40}, + {0x39, 0x88}, + {0x3A, 0x00}, + {0x3B, 0x03}, + {0x3C, 0x00}, + {0x3D, 0x60}, + {0x3E, 0x00}, + {0x3F, 0x00}, + {0x40, 0x00}, + {0x42, 0x00}, + {0x43, 0x12}, + {0x44, 0x07}, + {0x45, 0x49}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4A, 0x00}, + {0x4B, 0x00}, + {0x4C, 0x03}, + //{0x4D, 0x03}, + {0x4E, 0x17}, + {0x4F, 0x01}, + {0xB5, 0x01}, + {0xB8, 0x02}, + {0xBA, 0x10}, + {0xF3, 0x00}, + {0xF4, 0x00}, + {0xF5, 0x00}, + {0xF6, 0x00}, + {0xF7, 0x00}, + {0xF8, 0x00}, + {0xF9, 0x00}, + {0xFA, 0x00}, + {0xFB, 0x00}, + {0xFC, 0xC0}, + {0xFD, 0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_init_data[] = { +/*default 720p 50hz*/ + {0x02, 0xCA}, + {0x06, 0x32}, + {0x07, 0xC0}, + {0x08, 0x00}, + {0x09, 0x24}, + {0x0A, 0x48}, + {0x0B, 0xC0}, + {0x0C, 0x43}, + {0x0D, 0x10}, + {0x0E, 0x00}, + {0x0F, 0x00}, + {0x10, 0xf0}, + {0x11, 0x50}, + {0x12, 0x60}, + {0x13, 0x00}, + {0x14, 0x08}, + {0x15, 0x13}, + {0x16, 0x16}, + {0x17, 0x00}, + {0x18, 0x18}, + {0x19, 0xD0}, + {0x1A, 0x25}, + {0x1B, 0x00}, + {0x1C, 0x07}, + {0x1D, 0xBC}, + {0x1E, 0x80}, + {0x1F, 0x80}, + {0x20, 0x60}, + {0x21, 0x86}, + {0x22, 0x38}, + {0x23, 0x3C}, + {0x24, 0x56}, + {0x25, 0xFF}, + {0x27, 0x2D}, + {0x28, 0x00}, + {0x29, 0x48}, + {0x2A, 0x30}, + {0x2B, 0x4A}, + {0x2C, 0x0A}, + {0x2D, 0x30}, + {0x2E, 0x70}, + {0x2F, 0x00}, + {0x30, 0x48}, + {0x31, 0xBB}, + {0x32, 0x2E}, + {0x33, 0x90}, + {0x34, 0x00}, + {0x35, 0x05}, + {0x36, 0xDC}, + {0x37, 0x00}, + {0x38, 0x40}, + {0x39, 0x8C}, + {0x3A, 0x00}, + {0x3B, 0x03}, + {0x3C, 0x00}, + {0x3D, 0x60}, + {0x3E, 0x00}, + {0x3F, 0x00}, + {0x40, 0x00}, + {0x42, 0x00}, + {0x43, 0x12}, + {0x44, 0x07}, + {0x45, 0x49}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4A, 0x00}, + {0x4B, 0x00}, + {0x4C, 0x03}, + //{0x4D, 0x03}, + {0x4E, 0x03}, + {0x4F, 0x01}, + {0xB5, 0x01}, + {0xB8, 0x02}, + {0xBA, 0x10}, + {0xF3, 0x00}, + {0xF4, 0x00}, + {0xF5, 0x00}, + {0xF6, 0x00}, + {0xF7, 0x00}, + {0xF8, 0x00}, + {0xF9, 0x00}, + {0xFA, 0x00}, + {0xFB, 0x00}, + {0xFC, 0xC0}, + {0xFD, 0x00}, + SensorEnd +}; + +/* 1280x720 */ +static struct rk_sensor_reg sensor_720p[] = { + SensorEnd +}; + +/* 1920x1080 */ +static struct rk_sensor_reg sensor_1080p[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_softreset_data[] = { + SensorRegVal(0x06, 0x32 | 0x80), + SensorEnd +}; + +static struct rk_sensor_reg sensor_check_id_data[] = { + SensorRegVal(0xfe, 0x0), + SensorRegVal(0xff, 0x0), + SensorEnd +}; + +/* +* The following setting must been filled, if the function is turn on by CONFIG_SENSOR_xxxx +*/ +static struct rk_sensor_reg sensor_WhiteB_Auto[] = { + SensorEnd +}; + +/* Cloudy Colour Temperature : 6500K - 8000K */ +static struct rk_sensor_reg sensor_WhiteB_Cloudy[] = { + SensorEnd +}; + +/* ClearDay Colour Temperature : 5000K - 6500K */ +static struct rk_sensor_reg sensor_WhiteB_ClearDay[] = { + SensorEnd +}; + +/* Office Colour Temperature : 3500K - 5000K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[] = { + SensorEnd +}; + +/* Home Colour Temperature : 2500K - 3500K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[] = { + SensorEnd +}; + +static struct rk_sensor_reg *sensor_WhiteBalanceSeqe[] = { + sensor_WhiteB_Auto, + sensor_WhiteB_TungstenLamp1, + sensor_WhiteB_TungstenLamp2, + sensor_WhiteB_ClearDay, + sensor_WhiteB_Cloudy, + NULL, +}; + +static struct rk_sensor_reg sensor_Brightness0[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness1[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness2[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness3[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness4[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness5[] = { + SensorEnd +}; + +static struct rk_sensor_reg *sensor_BrightnessSeqe[] = { + sensor_Brightness0, + sensor_Brightness1, + sensor_Brightness2, + sensor_Brightness3, + sensor_Brightness4, + sensor_Brightness5, + NULL, +}; + +static struct rk_sensor_reg sensor_Effect_Normal[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_WandB[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Sepia[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Negative[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Bluish[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Green[] = { + SensorEnd +}; + +static struct rk_sensor_reg *sensor_EffectSeqe[] = { + sensor_Effect_Normal, + sensor_Effect_WandB, + sensor_Effect_Negative, + sensor_Effect_Sepia, + sensor_Effect_Bluish, + sensor_Effect_Green, + NULL, +}; + +static struct rk_sensor_reg sensor_Exposure0[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure1[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure2[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure3[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure4[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure5[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure6[] = { + SensorEnd +}; + +static struct rk_sensor_reg *sensor_ExposureSeqe[] = { + sensor_Exposure0, + sensor_Exposure1, + sensor_Exposure2, + sensor_Exposure3, + sensor_Exposure4, + sensor_Exposure5, + sensor_Exposure6, + NULL, +}; + +static struct rk_sensor_reg sensor_Saturation0[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Saturation1[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Saturation2[] = { + SensorEnd +}; + +static struct rk_sensor_reg *sensor_SaturationSeqe[] = { + sensor_Saturation0, + sensor_Saturation1, + sensor_Saturation2, + NULL, +}; + +static struct rk_sensor_reg sensor_Contrast0[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast1[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast2[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast3[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast4[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast5[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast6[] = { + SensorEnd +}; + +static struct rk_sensor_reg *sensor_ContrastSeqe[] = { + sensor_Contrast0, + sensor_Contrast1, + sensor_Contrast2, + sensor_Contrast3, + sensor_Contrast4, + sensor_Contrast5, + sensor_Contrast6, + NULL, +}; + +static struct rk_sensor_reg sensor_SceneAuto[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_SceneNight[] = { + SensorEnd +}; + +static struct rk_sensor_reg *sensor_SceneSeqe[] = { + sensor_SceneAuto, + sensor_SceneNight, + NULL, +}; + +static struct rk_sensor_reg sensor_Zoom0[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Zoom1[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Zoom2[] = { + SensorEnd +}; + +static struct rk_sensor_reg sensor_Zoom3[] = { + SensorEnd +}; + +static struct rk_sensor_reg *sensor_ZoomSeqe[] = { + sensor_Zoom0, + sensor_Zoom1, + sensor_Zoom2, + sensor_Zoom3, + NULL, +}; + +/* +* User could be add v4l2_querymenu in sensor_controls by new_usr_v4l2menu +*/ +static struct v4l2_querymenu sensor_menus[] = { +}; + +/* +* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl +*/ + +static inline int sensor_v4l2ctrl_inside_cb(struct soc_camera_device *icd, + struct sensor_v4l2ctrl_info_s *ctrl_info, + struct v4l2_ext_control *ext_ctrl, + bool is_set) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct generic_sensor *sensor = to_generic_sensor(client); + int ret = 0; + + switch (ctrl_info->qctrl->id) { + case V4L2_CID_DEINTERLACE: + { + if (is_set) { + SENSOR_TR("%s(%d): deinterlace is not support set!", __func__, __LINE__); + ret = -EINVAL; + } else { + if ((RK_CAMERA_DEVICE_BT601_8 == + sensor->info_priv.dev_sig_cnf.type) || + (RK_CAMERA_DEVICE_BT601_PIONGPONG == + sensor->info_priv.dev_sig_cnf.type)) { + /* don't need deinterlace process */ + ext_ctrl->value = 0; + ctrl_info->cur_value = 0; + } else { + ext_ctrl->value = 1; + ctrl_info->cur_value = 1; + } + } + break; + } + case V4L2_CID_CHANNEL: + { + if (is_set) { + if ((ext_ctrl->value < ctrl_info->qctrl->minimum) || + (ext_ctrl->value > ctrl_info->qctrl->maximum)) { + SENSOR_TR("%s(%d):channel(%d) is not support\n", + __func__, __LINE__, ext_ctrl->value); + ret = -EINVAL; + goto cb_end; + } + if (sensor->channel_id != ext_ctrl->value) { + SENSOR_TR("%s(%d):set channel(%d)!\n", + __func__, __LINE__, ext_ctrl->value); + sensor->channel_id = ext_ctrl->value; + sensor_write(client, SENSOR_CHANNEL_REG, + sensor->channel_id); + sensor_write(client, SENSOR_CLAMPING_CONTROL, + 0x01); + } + } else { + ext_ctrl->value = sensor->channel_id; + ctrl_info->cur_value = sensor->channel_id; + } + break; + } + case V4L2_CID_VIDEO_STATE: + { + if (is_set) { + SENSOR_TR("%s(%d): set isn't support!\n", + __func__, __LINE__); + } else { + ext_ctrl->value = sensor->info_priv.video_state; + ctrl_info->cur_value = sensor->info_priv.video_state; + } + break; + } + default: + { + SENSOR_TR("%s(%d): cmd(0x%x) is unknown !", + __func__, __LINE__, ctrl_info->qctrl->id); + ret = -EINVAL; + } + } + +cb_end: + return ret; +} + +static struct sensor_v4l2ctrl_usr_s sensor_controls[] = { + { + { + V4L2_CID_DEINTERLACE, + V4L2_CTRL_TYPE_BOOLEAN, + "deinterlace", + 0, + 1, + 1, + 0 + }, + sensor_v4l2ctrl_inside_cb, + NULL + }, + { + { + V4L2_CID_CHANNEL, + V4L2_CTRL_TYPE_INTEGER, + "channel", + 0, + 4, + 1, + 0 + }, + sensor_v4l2ctrl_inside_cb, + NULL + }, + { + { + V4L2_CID_VIDEO_STATE, + V4L2_CTRL_TYPE_BOOLEAN, + "video_state", + 0, + 1, + 1, + 0 + }, + sensor_v4l2ctrl_inside_cb, + NULL + } +}; + +/* +* MUST define the current used format as the first item +*/ +static struct rk_sensor_datafmt sensor_colour_fmts[] = { + {MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, +}; + +/* +********************************************************** +* Following is local code: +* +* Please codeing your program here +********************************************************** +*/ +static int sensor_parameter_record(struct i2c_client *client) +{ + return 0; +} + +static int sensor_ae_transfer(struct i2c_client *client) +{ + return 0; +} + +/* +********************************************************** +* Following is callback +* If necessary, you could coding these callback +********************************************************** +*/ +enum { + CVSTD_720P60 = 0, + CVSTD_720P50, + CVSTD_1080P30, + CVSTD_1080P25, + CVSTD_720P30, + CVSTD_720P25, + CVSTD_SD, + CVSTD_NO_DET, + CVSTD_720P30V2, + CVSTD_720P25V2, + CVSTD_NTSC, + CVSTD_PAL +}; + +enum { + VIDEO_UNPLUG, + VIDEO_IN, + VIDEO_LOCKED, + VIDEO_UNLOCK +}; + +#define FLAG_LOSS 0x80 +#define FLAG_LOCKED 0x60 +static int cvstd_mode = CVSTD_720P50; +static int cvstd_old = CVSTD_720P50; +static int cvstd_sd = CVSTD_PAL; + +static void tp2825_reinit_parameter(unsigned char cvstd, struct generic_sensor *sensor) +{ + struct rk_sensor_sequence *series = sensor->info_priv.sensor_series; + int num_series = sensor->info_priv.num_series; + int i; + + if (CVSTD_PAL == cvstd) { + SENSOR_PREVIEW_W = 960; + SENSOR_PREVIEW_H = 576; + sensor->info_priv.dev_sig_cnf.type = RK_CAMERA_DEVICE_CVBS_PAL; + strcpy(input_mode, "PAL"); + } else if (CVSTD_NTSC == cvstd) { + SENSOR_PREVIEW_W = 960; + SENSOR_PREVIEW_H = 480; + sensor->info_priv.dev_sig_cnf.type = RK_CAMERA_DEVICE_CVBS_NTSC; + strcpy(input_mode, "NTSC"); + } else { + SENSOR_PREVIEW_W = 1280; + SENSOR_PREVIEW_H = 720; + sensor->info_priv.dev_sig_cnf.type = RK_CAMERA_DEVICE_BT601_8; + strcpy(input_mode, "720P"); + } + for (i = 0; i < 4; i++) { + if ((defrects[i].width == SENSOR_PREVIEW_W) && + (defrects[i].height == SENSOR_PREVIEW_H)) { + SENSOR_PREVIEW_W = defrects[i].defrect.width; + SENSOR_PREVIEW_H = defrects[i].defrect.height; + memcpy(&sensor->info_priv.dev_sig_cnf.crop, + &defrects[i].defrect, + sizeof(defrects[i].defrect)); + if (!defrects[i].interface) { + SENSOR_TR("%s(%d): interface is NULL\n", + __func__, __LINE__); + continue; + } + if (!strcmp(defrects[i].interface, "bt601_8")) + sensor->info_priv.dev_sig_cnf.type = + RK_CAMERA_DEVICE_BT601_8; + if (!strcmp(defrects[i].interface, "cvbs_ntsc")) + sensor->info_priv.dev_sig_cnf.type = + RK_CAMERA_DEVICE_CVBS_NTSC; + if (!strcmp(defrects[i].interface, "cvbs_pal")) + sensor->info_priv.dev_sig_cnf.type = + RK_CAMERA_DEVICE_CVBS_PAL; + if (!strcmp(defrects[i].interface, "bt601_8_pp")) + sensor->info_priv.dev_sig_cnf.type = + RK_CAMERA_DEVICE_BT601_PIONGPONG; + if (!strcmp(defrects[i].interface, "cvbs_deinterlace")) + sensor->info_priv.dev_sig_cnf.type = + RK_CAMERA_DEVICE_CVBS_DEINTERLACE; + SENSOR_TR("%s(%d): type 0x%x\n", __func__, __LINE__, + sensor->info_priv.dev_sig_cnf.type); + } + } + + /*update sensor info_priv*/ + for (i = 0; i < num_series; i++) { + series[i].gSeq_info.w = SENSOR_PREVIEW_W; + series[i].gSeq_info.h = SENSOR_PREVIEW_H; + } + generic_sensor_get_max_min_res(sensor->info_priv.sensor_series, + sensor->info_priv.num_series, + &(sensor->info_priv.max_real_res), + &(sensor->info_priv.max_res), + &(sensor->info_priv.min_res)); +} + +static int tp2825_uevent_video_state(struct generic_sensor *sensor, int state) +{ + char *event_msg = NULL; + char *envp[2]; + + return 0; + event_msg = kasprintf(GFP_KERNEL, "CVBS_NAME=TP2825, VIDEO_STATUS=%d", + state); + SENSOR_TR("%s(%d): event_msg: %s\n", __func__, __LINE__, event_msg); + envp[0] = event_msg; + envp[1] = NULL; + kobject_uevent_env(&(sensor->subdev.v4l2_dev->dev->kobj), KOBJ_CHANGE, + envp); + + return 0; +} + +static int tp2825_check_cvstd(struct i2c_client *client, bool activate_check) +{ + unsigned char cvstd; + int i; + int ret = -EINVAL; + unsigned char status; + static int state = VIDEO_UNPLUG; + static bool first_reinit = 1; + struct generic_sensor *sensor = to_generic_sensor(client); + struct rk_sensor_sequence *sensor_series = + sensor->info_priv.sensor_series; + int series_num = sensor->info_priv.num_series; + + for (i = 0; i < series_num; i++) + if ((sensor_series[i].property == SEQUENCE_INIT) && + (sensor_series[i].data[0].reg != SEQCMD_END)) + break; + + ret = sensor_read(client, 0x01, &status); + if (IS_ERR_VALUE(ret)) { + SENSOR_TR("sensor read failed\n"); + return -EBUSY; + } + SENSOR_DG("%s(%d): state %d, read 0x01:0x%x\n", __func__, __LINE__, state, status); + + if (status & FLAG_LOSS) { + state = VIDEO_UNPLUG; + tp2825_uevent_video_state(sensor, 0); + sensor_write(client, SENSOR_CLAMPING_CONTROL, 0x01); + sensor->info_priv.video_state = RK_CAM_INPUT_VIDEO_STATE_LOSS; + } else if (FLAG_LOCKED == (status & FLAG_LOCKED)) { + /* video locked */ + if ((state != VIDEO_LOCKED) && !activate_check) { + state = VIDEO_LOCKED; + tp2825_uevent_video_state(sensor, 1); + + sensor_write(client, SENSOR_CLAMPING_CONTROL, 0x02); + } + sensor->info_priv.video_state = RK_CAM_INPUT_VIDEO_STATE_LOCKED; + } else { + /* video in but unlocked */ + state = VIDEO_IN; + + sensor_write(client, SENSOR_CLAMPING_CONTROL, 0x02); + //sensor->info_priv.video_state = RK_CAM_INPUT_VIDEO_STATE_LOSS; + } + SENSOR_DG("%s(%d): state %s\n", __func__, __LINE__, + (VIDEO_UNPLUG == state) ? "UNPLUG" : (VIDEO_LOCKED == state) ? "LOCKED" : "VIDEO_IN"); + + if (state == VIDEO_IN) { + sensor_read(client, 0x03, &cvstd); + SENSOR_TR("%s(%d): cvstd_old %d, read 0x03 return 0x%x", + __func__, __LINE__, cvstd_old, cvstd); + + cvstd &= 0x07; + if (cvstd == cvstd_old) + goto check_end; + + if (cvstd == CVSTD_720P30) { + cvstd_mode = CVSTD_720P30; + SENSOR_TR("%s(%d): 720P30\n", __func__, __LINE__); + sensor_series[i].data = sensor_preview_data_720p_30hz; + } else if (cvstd == CVSTD_720P25) { + cvstd_mode = CVSTD_720P25; + SENSOR_TR("%s(%d): 720P25\n", __func__, __LINE__); + sensor_series[i].data = sensor_preview_data_720p_25hz; + } else if (cvstd == CVSTD_720P60) { + SENSOR_TR("%s(%d): 720P60", __func__, __LINE__); + } else if (cvstd == CVSTD_720P50) { + cvstd_mode = CVSTD_720P50; + SENSOR_TR("%s(%d): 720P50\n", __func__, __LINE__); + sensor_series[i].data = sensor_preview_data_720p_50hz; + } else if (cvstd == CVSTD_1080P30) { + SENSOR_TR("%s(%d): 1080P30", __func__, __LINE__); + } else if (cvstd == CVSTD_1080P25) { + SENSOR_TR("%s(%d): 1080P25", __func__, __LINE__); + } else if (cvstd == CVSTD_SD) { + msleep(80); + ret = sensor_read(client, 0x01, &status); + SENSOR_DG("%s(%d): read 0x01 return 0x%x\n", + __func__, __LINE__, status); + + /* + * 1: pal 0: ntsc + */ + if ((status >> 2) & 0x01) + cvstd_sd = CVSTD_PAL; + else + cvstd_sd = CVSTD_NTSC; + + SENSOR_TR("%s(%d): cvstd_sd is %s\n", + __func__, __LINE__, + (cvstd_sd == CVSTD_PAL) ? "PAL" : "NTSC"); + cvstd_mode = cvstd_sd; + + if (cvstd_mode == CVSTD_PAL) { + sensor_series[i].data = sensor_preview_data_pal; + } else { + sensor_series[i].data = sensor_preview_data_ntsc; + } + } + } else if (state == VIDEO_LOCKED) { + goto check_end; + } else { + SENSOR_TR("tp2825_check_cvstd: check sensor statue failed!\n"); + + goto check_failed; + } + + /* config irq interrupt */ + /*for (i = 0; i < ARRAY_SIZE(sensor_preview_data); i++) { + if (sensor_preview_data[i].reg == 0x4F) + sensor_preview_data[i].val = 0x01; + if (sensor_preview_data[i].reg == 0xB8) + sensor_preview_data[i].val = 0x03; + if (sensor_preview_data[i].reg == 0xBA) + sensor_preview_data[i].val = 0x10; + }*/ + + if (cvstd_mode != cvstd_old) { + tp2825_reinit_parameter(cvstd_mode, sensor); + generic_sensor_write_array(client, sensor_series[i].data); + sensor_write(client, SENSOR_CHANNEL_REG, sensor->channel_id); + } +check_end: + + if (first_reinit) { + first_reinit = false; + tp2825_reinit_parameter(cvstd_mode, sensor); + } + return 0; + +check_failed: + return -1; +} + +/* +* the function is called in open sensor +*/ +static int sensor_activate_cb(struct i2c_client *client) +{ + struct generic_sensor *sensor = to_generic_sensor(client); + + SENSOR_DG("Here I am: %s %d/n", __func__, __LINE__); + sensor_write(client, SENSOR_CHANNEL_REG, sensor->channel_id); + //msleep(200); + tp2825_check_cvstd(client, true); + cvstd_old = cvstd_mode; + sensor->info_priv.video_state = RK_CAM_INPUT_VIDEO_STATE_LOCKED; + + if (sensor->state_check_work.state_check_wq) { + SENSOR_DG("sensor_activate_cb: queue_delayed_work 1000ms"); + queue_delayed_work(sensor->state_check_work.state_check_wq, + &sensor->state_check_work.work, 100); + } + + return 0; +} + +/* +* the function is called in close sensor +*/ +static int sensor_deactivate_cb(struct i2c_client *client) +{ + int ret = 0; + struct generic_sensor *sensor = to_generic_sensor(client); + + ret = cancel_delayed_work_sync(&sensor->state_check_work.work); + return ret; +} + +static int sensor_s_stream(struct v4l2_subdev *sd, int enable) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + + SENSOR_DG("stream %d\n", enable); + if (enable) + sensor_write(client, 0x4D, 0x03); + else + sensor_write(client, 0x4D, 0x00); + return 0; +} + +/* +* the function is called before sensor register setting in VIDIOC_S_FMT +*/ +static int sensor_s_fmt_cb_th(struct i2c_client *client, struct v4l2_mbus_framefmt *mf, bool capture) +{ + if (capture) + sensor_parameter_record(client); + + return 0; +} + +/* +* the function is called after sensor register setting finished in VIDIOC_S_FMT +*/ +static int sensor_s_fmt_cb_bh(struct i2c_client *client, struct v4l2_mbus_framefmt *mf, bool capture) +{ + if (capture) + sensor_ae_transfer(client); + + return 0; +} + +static int sensor_try_fmt_cb_th(struct i2c_client *client, struct v4l2_mbus_framefmt *mf) +{ + return 0; +} + +static int sensor_softrest_usr_cb(struct i2c_client *client, struct rk_sensor_reg *series) +{ + return 0; +} +static int sensor_check_id_usr_cb(struct i2c_client *client, struct rk_sensor_reg *series) +{ + return 0; +} + +static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg) +{ + return 0; +} + +static int sensor_resume(struct soc_camera_device *icd) +{ + SENSOR_DG("Resume"); + + return 0; +} + +static int sensor_mirror_cb(struct i2c_client *client, int mirror) +{ + return 0; +} + +/* +* the function is v4l2 control V4L2_CID_HFLIP callback +*/ +static int sensor_v4l2ctrl_mirror_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, + struct v4l2_ext_control *ext_ctrl) +{ + SENSOR_DG("sensor_mirror success, value:0x%x", ext_ctrl->value); + return 0; +} + +static int sensor_flip_cb(struct i2c_client *client, int flip) +{ + return 0; +} + +/* +* the function is v4l2 control V4L2_CID_VFLIP callback +*/ +static int sensor_v4l2ctrl_flip_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, + struct v4l2_ext_control *ext_ctrl) +{ + SENSOR_DG("sensor_flip success, value:0x%x", ext_ctrl->value); + return 0; +} + +/* +* the functions are focus callbacks +*/ +static int sensor_focus_init_usr_cb(struct i2c_client *client) +{ + return 0; +} + +static int sensor_focus_af_single_usr_cb(struct i2c_client *client) +{ + return 0; +} + +static int sensor_focus_af_near_usr_cb(struct i2c_client *client) +{ + return 0; +} + +static int sensor_focus_af_far_usr_cb(struct i2c_client *client) +{ + return 0; +} + +static int sensor_focus_af_specialpos_usr_cb(struct i2c_client *client, int pos) +{ + return 0; +} + +static int sensor_focus_af_const_usr_cb(struct i2c_client *client) +{ + return 0; +} +static int sensor_focus_af_const_pause_usr_cb(struct i2c_client *client) +{ + return 0; +} +static int sensor_focus_af_close_usr_cb(struct i2c_client *client) +{ + return 0; +} + +static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client, int *zone_tm_pos) +{ + return 0; +} + +/* +face defect call back +*/ +static int sensor_face_detect_usr_cb(struct i2c_client *client, int on) +{ + return 0; +} + +static void tp2825_send_uevent(struct generic_sensor *sensor) +{ + char *event_msg = NULL; + char *envp[2]; + + event_msg = kasprintf(GFP_KERNEL, "CVBS_NAME=TP2825, NOW_INPUT_MODE=%s, RESOLUTION=%dx%d", + input_mode, SENSOR_PREVIEW_W, SENSOR_PREVIEW_H); + SENSOR_TR("%s(%d): event_msg: %s\n", __func__, __LINE__, event_msg); + envp[0] = event_msg; + envp[1] = NULL; + kobject_uevent_env(&(sensor->subdev.v4l2_dev->dev->kobj), KOBJ_CHANGE, envp); +} + +/* tp2825 irq interrupt process */ +static irqreturn_t tp2825_irq(int irq, void *dev_id) +{ + struct specific_sensor *spsensor = (struct specific_sensor *)dev_id; + struct generic_sensor *sensor = &spsensor->common_sensor; + +/* struct i2c_client *client = spsensor->common_sensor.client; + int ret; + unsigned char val; + + ret = sensor_read(client, 0xB5, &val); + if (IS_ERR_VALUE(ret)) { + SENSOR_DG("%s(%d): sensor_read failed", __func__, __LINE__); + return IRQ_HANDLED; + } + SENSOR_DG("%s(%d): read 0xB5 val 0x%x\n", __func__, __LINE__, val); + + ret = sensor_read(client, 0x01, &val); + spsensor->common_sensor.info_priv.video_state = + ((val & 0x80) >> 7) ? + RK_CAM_INPUT_VIDEO_STATE_LOSS : + RK_CAM_INPUT_VIDEO_STATE_LOCKED; + + SENSOR_TR("%s(%d): video status is %s\n", __func__, __LINE__, + spsensor->common_sensor.info_priv.video_state ? + "video present" : + "Video loss"); +*/ + /* + * irq interrupt active while video lossed. + */ + SENSOR_TR("%s(%d): video status is video loss\n", + __func__, __LINE__); + sensor->info_priv.video_state = RK_CAM_INPUT_VIDEO_STATE_LOSS; + tp2825_uevent_video_state(sensor, 0); +/* + ret = sensor_write(client, 0xB5, 0x01); + if (IS_ERR_VALUE(ret)) { + SENSOR_TR("%s(%d): sensor_write failed\n", __func__, __LINE__); + return IRQ_HANDLED; + } + SENSOR_DG("%s(%d): write 0xB5 val 0x01\n", __func__, __LINE__); +*/ + return IRQ_HANDLED; +} + +/* config debug fs ops */ +#define DEBUG_FS_NTSC_WIDTH 0x8000 +#define DEBUG_FS_NTSC_HEIGHT 0x8001 +#define DEBUG_FS_NTSC_LEFT 0x8002 +#define DEBUG_FS_NTSC_TOP 0x8003 + +#define DEBUG_FS_PAL_WIDTH 0x8004 +#define DEBUG_FS_PAL_HEIGHT 0x8005 +#define DEBUG_FS_PAL_LEFT 0x8006 +#define DEBUG_FS_PAL_TOP 0x8007 + +static ssize_t tp2825_debugfs_reg_write(struct file *file, + const char __user *buf, + size_t count, loff_t *ppos) +{ + struct specific_sensor *spsensor = + ((struct seq_file *)file->private_data)->private; + struct i2c_client *client = spsensor->common_sensor.client; + int reg, val, ret; + unsigned char read; + char kbuf[30]; + int nbytes = min(count, sizeof(kbuf) - 1); + int i = 0; + + if (copy_from_user(kbuf, buf, nbytes)) + return -EFAULT; + + kbuf[nbytes] = '\0'; + if (sscanf(kbuf, " %x %x", ®, &val) != 2) + return -EINVAL; + + SENSOR_TR("%s(%d): register write reg: 0x%x, val 0x%x\n", + __func__, __LINE__, reg, val); + + switch (reg) { + case DEBUG_FS_NTSC_WIDTH: + { + for (i = 0; i < 4; i++) + if (defrects[i].height == 480) + defrects[i].defrect.width = val; + break; + } + case DEBUG_FS_NTSC_HEIGHT: + { + for (i = 0; i < 4; i++) + if (defrects[i].height == 480) + defrects[i].defrect.height = val; + break; + } + case DEBUG_FS_NTSC_TOP: + { + for (i = 0; i < 4; i++) + if (defrects[i].height == 480) + defrects[i].defrect.top = val; + break; + } + case DEBUG_FS_NTSC_LEFT: + { + for (i = 0; i < 4; i++) + if (defrects[i].height == 480) + defrects[i].defrect.left = val; + break; + } + case DEBUG_FS_PAL_WIDTH: + { + for (i = 0; i < 4; i++) + if (defrects[i].height == 576) + defrects[i].defrect.width = val; + break; + } + case DEBUG_FS_PAL_HEIGHT: + { + for (i = 0; i < 4; i++) + if (defrects[i].height == 576) + defrects[i].defrect.height = val; + break; + } + case DEBUG_FS_PAL_LEFT: + { + for (i = 0; i < 4; i++) + if (defrects[i].height == 576) + defrects[i].defrect.left = val; + break; + } + case DEBUG_FS_PAL_TOP: + { + for (i = 0; i < 4; i++) + if (defrects[i].height == 576) + defrects[i].defrect.top = val; + break; + } + default: + { + ret = sensor_write(client, reg, val); + if (IS_ERR_VALUE(ret)) { + SENSOR_TR("d_fs: write fail: 0x%x, val 0x%x\n", + reg, val); + } + + ret = sensor_read(client, reg, &read); + if (IS_ERR_VALUE(ret)) { + SENSOR_TR("d_fs: write fail: 0x%x, val 0x%x\n", + reg, read); + } else + SENSOR_TR("d_fs: read 0x%x return 0x%x\n", + reg, val); + break; + } + } + + return count; +} + +static int tp2825_debugfs_reg_show(struct seq_file *s, void *v) +{ + int i, ret; + unsigned char val; + struct specific_sensor *spsensor = s->private; + struct i2c_client *client = spsensor->common_sensor.client; + + SENSOR_TR("%s(%d): test\n", __func__, __LINE__); + + for (i = 0; i < 0xff; i++) { + ret = sensor_read(client, i + 1, &val); + if (IS_ERR_VALUE(ret)) + SENSOR_TR("%s(%d): register read failed: 0x%x\n", + __func__, __LINE__, i + 1); + + seq_printf(s, "0x%02x : 0x%02x\n", i + 1, (u8)val); + } + + return 0; +} + +static int tp2825_debugfs_open(struct inode *inode, struct file *file) +{ + struct specific_sensor *spsensor = inode->i_private; + + return single_open(file, tp2825_debugfs_reg_show, spsensor); +} + +static const struct file_operations tp2825_debugfs_fops = { + .owner = THIS_MODULE, + .open = tp2825_debugfs_open, + .read = seq_read, + .write = tp2825_debugfs_reg_write, + .llseek = seq_lseek, + .release = single_release +}; + +static void tp2825_check_state_work(struct work_struct *work) +{ + struct rk_state_check_work *state_check_work = + container_of(work, struct rk_state_check_work, work.work); + struct generic_sensor *sensor = + container_of(state_check_work, struct generic_sensor, state_check_work); + struct i2c_client *client = sensor->client; + + tp2825_check_cvstd(client, false); + + if (cvstd_old != cvstd_mode) { + cvstd_old = cvstd_mode; + tp2825_send_uevent(sensor); + } + + queue_delayed_work(sensor->state_check_work.state_check_wq, + &sensor->state_check_work.work, 100); +} + +/* +* The function can been run in sensor_init_parametres which run in sensor_probe, so user can do some +* initialization in the function. +*/ +static void sensor_init_parameters_user(struct specific_sensor *spsensor, struct soc_camera_device *icd) +{ + struct soc_camera_desc *desc = to_soc_camera_desc(icd); + struct rk29camera_platform_data *pdata = desc->subdev_desc.drv_priv; + struct rkcamera_platform_data *sensor_device = NULL, *new_camera; + struct dentry *debugfs_dir = spsensor->common_sensor.info_priv.debugfs_dir; + int ret; + + new_camera = pdata->register_dev_new; + while (new_camera != NULL) { + SENSOR_TR("%s(%d): icd_name %s, new_camera_name %s.\n", + __func__, __LINE__, dev_name(icd->pdev), new_camera->dev_name); + if (strcmp(dev_name(icd->pdev), new_camera->dev_name) == 0) { + sensor_device = new_camera; + break; + } + new_camera = new_camera->next_camera; + } + if (!sensor_device) { + SENSOR_TR("%s(%d): Could not find %s\n", __func__, __LINE__, + dev_name(icd->pdev)); + return; + } + memcpy(&defrects, &sensor_device->defrects, + sizeof(sensor_device->defrects)); + SENSOR_TR("%s(%d): channel %d, default %d\n", __func__, __LINE__, + sensor_device->channel_info.channel_total, + sensor_device->channel_info.default_id); + spsensor->common_sensor.channel_id = + sensor_device->channel_info.default_id; + + if (new_camera->io.gpio_irq) { + spsensor->common_sensor.irq = gpiod_to_irq(new_camera->io.gpio_irq); + ret = request_irq(spsensor->common_sensor.irq, tp2825_irq, IRQF_TRIGGER_FALLING, + dev_name(icd->pdev), spsensor); + if (ret < 0) + SENSOR_TR("%s(%d): request irq failed\n", __func__, __LINE__); + } + + /* init debugfs */ + debugfs_dir = debugfs_create_dir("tp2825", NULL); + if (IS_ERR(debugfs_dir)) + SENSOR_TR("%s(%d): create debugfs dir failed\n", __func__, __LINE__); + else + debugfs_create_file("register", S_IRUSR, debugfs_dir, spsensor, &tp2825_debugfs_fops); + + /* init work_queue for state_check */ + INIT_DELAYED_WORK(&spsensor->common_sensor.state_check_work.work, tp2825_check_state_work); + spsensor->common_sensor.state_check_work.state_check_wq = + create_singlethread_workqueue(SENSOR_NAME_STRING(_state_check_workqueue)); + if (spsensor->common_sensor.state_check_work.state_check_wq == NULL) { + SENSOR_TR("%s(%d): %s create failed.\n", __func__, __LINE__, + SENSOR_NAME_STRING(_state_check_workqueue)); + BUG(); + } + + memcpy(&spsensor->common_sensor.info_priv.dev_sig_cnf, &dev_info[0], sizeof(dev_info)); + spsensor->common_sensor.crop_percent = 0; + spsensor->common_sensor.sensor_cb.sensor_s_stream_cb = sensor_s_stream; +} + +/* +* :::::WARNING::::: +* It is not allowed to modify the following code +*/ + +sensor_init_parameters_default_code(); + +sensor_v4l2_struct_initialization(); + +sensor_probe_default_code(); + +sensor_remove_default_code(); + +sensor_driver_default_module_code(); + diff --git a/drivers/soc/rockchip/Makefile b/drivers/soc/rockchip/Makefile index 22e54844968a..9435d6426f9d 100644 --- a/drivers/soc/rockchip/Makefile +++ b/drivers/soc/rockchip/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_FIQ_DEBUGGER) += rk_fiq_debugger.o obj-$(CONFIG_MMC_DW_ROCKCHIP) += sdmmc_vendor_storage.o obj-$(CONFIG_ROCKCHIP_PVTM) += rockchip_pvtm.o obj-$(CONFIG_ROCKCHIP_SUSPEND_MODE) += rockchip_pm_config.o +obj-$(CONFIG_ROCK_CHIP_SOC_CAMERA) += rk_camera.o obj-y += rk_vendor_storage.o obj-y += rockchip-system-status.o diff --git a/drivers/soc/rockchip/rk30_camera.h b/drivers/soc/rockchip/rk30_camera.h new file mode 100644 index 000000000000..5fc3c16c5ff3 --- /dev/null +++ b/drivers/soc/rockchip/rk30_camera.h @@ -0,0 +1,49 @@ +/* + * rk30_camera.h - PXA camera driver header file + * + * Copyright (C) 2003, Intel Corporation + * Copyright (C) 2008, Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef _RK30_CAMERA_H +#define _RK30_CAMERA_H + +#define RK29_CAM_DRV_NAME "rk312x-camera" +#define RK_SUPPORT_CIF0 1 +#define RK_SUPPORT_CIF1 0 +#define RK_CIF_NAME "rk_cif" +#define RK_SENSOR_NAME "rk_sensor" + +#include "rk_camera.h" +#include + +#define CONFIG_CAMERA_INPUT_FMT_SUPPORT (RK_CAM_INPUT_FMT_YUV422) +#ifdef CONFIG_SOC_RK3028 +#define CONFIG_CAMERA_SCALE_CROP_MACHINE RK_CAM_SCALE_CROP_ARM +#else +#define CONFIG_CAMERA_SCALE_CROP_MACHINE RK_CAM_SCALE_CROP_IPP +#endif + +#if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_ARM) + #define CAMERA_SCALE_CROP_MACHINE "arm" +#elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP) + #define CAMERA_SCALE_CROP_MACHINE "ipp" +#elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA) + #define CAMERA_SCALE_CROP_MACHINE "rga" +#elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP) + #define CAMERA_SCALE_CROP_MACHINE "pp" +#endif + +#define CAMERA_VIDEOBUF_ARM_ACCESS 0 + +#endif + diff --git a/drivers/soc/rockchip/rk_camera.c b/drivers/soc/rockchip/rk_camera.c new file mode 100644 index 000000000000..47a0482b1032 --- /dev/null +++ b/drivers/soc/rockchip/rk_camera.c @@ -0,0 +1,1326 @@ +/* + * drivers/soc/rockchip/rk_camera.c + * + * Copyright (C) 2017, ROCKCHIP, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "rk_camera.h" +#include "rk30_camera.h" + +static int camio_version = KERNEL_VERSION(0, 1, 9); +module_param(camio_version, int, S_IRUGO); + +static int camera_debug; +module_param(camera_debug, int, S_IRUGO | S_IWUSR); + +#undef CAMMODULE_NAME +#define CAMMODULE_NAME "rk_cam_io" + +#define ddprintk(level, fmt, arg...) \ + do { \ + if (camera_debug >= level) \ + printk(KERN_WARNING "%s(%d):" fmt"\n", \ + CAMMODULE_NAME, __LINE__, ## arg); \ + } while (0) + +#define dprintk(format, ...) \ + ddprintk(1, format, ## __VA_ARGS__) +#define eprintk(format, ...) \ + printk(KERN_ERR "%s(%d):" format"\n", \ + CAMMODULE_NAME, __LINE__, ## __VA_ARGS__) +#define debug_printk(format, ...) \ + ddprintk(3, format, ## __VA_ARGS__) + +static int rk_sensor_io_init(void); +static int rk_sensor_io_deinit(int sensor); +static int rk_sensor_ioctrl(struct device *dev, + enum rk29camera_ioctrl_cmd cmd, int on); +static int rk_sensor_power(struct device *dev, int on); +static int rk_sensor_register(void); +static int rk_dts_sensor_probe(struct platform_device *pdev); +static int rk_dts_sensor_remove(struct platform_device *pdev); +static int rk_dts_cif_probe(struct platform_device *pdev); +static int rk_dts_cif_remove(struct platform_device *pdev); +static int rk_sensor_powerdown(struct device *dev, int on); + +static struct rkcamera_platform_data *new_camera_head; + +static struct rk29camera_platform_data rk_camera_platform_data = { + .io_init = rk_sensor_io_init, + .io_deinit = rk_sensor_io_deinit, + .sensor_ioctrl = rk_sensor_ioctrl, + .sensor_register = rk_sensor_register, +}; + +struct rk29camera_platform_ioctl_cb sensor_ioctl_cb = { + .sensor_power_cb = NULL, + .sensor_reset_cb = NULL, + .sensor_powerdown_cb = NULL, + .sensor_flash_cb = NULL, + .sensor_af_cb = NULL, +}; + +static u64 rockchip_device_camera_dmamask = 0xffffffffUL; +#if RK_SUPPORT_CIF0 +static struct resource rk_camera_resource_host_0[2] = {}; +#endif +#if RK_SUPPORT_CIF1 +static struct resource rk_camera_resource_host_1[2] = {}; +#endif + +#if RK_SUPPORT_CIF0 +struct platform_device rk_device_camera_host_0 = { + .name = RK29_CAM_DRV_NAME, + /* This is used to put cameras on this interface*/ + .id = RK_CAM_PLATFORM_DEV_ID_0, + .num_resources = ARRAY_SIZE(rk_camera_resource_host_0), + .resource = rk_camera_resource_host_0, + .dev = { + .dma_mask = &rockchip_device_camera_dmamask, + .coherent_dma_mask = 0xffffffffUL, + .platform_data = &rk_camera_platform_data, + } +}; +#endif + +#if RK_SUPPORT_CIF1 +struct platform_device rk_device_camera_host_1 = { + .name = RK29_CAM_DRV_NAME, + /* This is used to put cameras on this interface */ + .id = RK_CAM_PLATFORM_DEV_ID_1, + .num_resources = ARRAY_SIZE(rk_camera_resource_host_1), + .resource = rk_camera_resource_host_1, + .dev = { + .dma_mask = &rockchip_device_camera_dmamask, + .coherent_dma_mask = 0xffffffffUL, + .platform_data = &rk_camera_platform_data, + } +}; +#endif + +static const struct of_device_id of_match_cif[] = { + {.compatible = "rockchip,cif",}, + {}, +}; +MODULE_DEVICE_TABLE(of, of_match_cif); +static struct platform_driver rk_cif_driver = { + .driver = { + .name = RK_CIF_NAME, + .of_match_table = of_match_ptr(of_match_cif), + }, + .probe = rk_dts_cif_probe, + .remove = rk_dts_cif_remove, +}; + +static const struct of_device_id of_match_sensor[] = { + {.compatible = "rockchip,sensor",}, + {}, +}; +MODULE_DEVICE_TABLE(of, of_match_sensor); +static struct platform_driver rk_sensor_driver = { + .driver = { + .name = RK_SENSOR_NAME, + .of_match_table = of_match_ptr(of_match_sensor), + }, + .probe = rk_dts_sensor_probe, + .remove = rk_dts_sensor_remove, +}; + +struct regmap *rk_cif_cru_base; +struct regmap *rk_cif_grf_base; + +static int rk_dts_sensor_remove(struct platform_device *pdev) +{ + return 0; +} + +static int rk_dts_sensor_probe(struct platform_device *pdev) +{ + struct device_node *np, *cp; + int sensor_num = 0, err; + struct device *dev = &pdev->dev; + struct rkcamera_platform_data *new_camera_list; + struct fwnode_handle *child; + int count; + + np = dev->of_node; + if (!np) + return -ENODEV; + + count = device_get_child_node_count(dev); + if (!count) + return -ENODEV; + + device_for_each_child_node(dev, child) { + u32 flash_attach = 0, mir = 0, i2c_chl = 0, i2c_add = 0; + u32 cif_chl = 0, mclk_rate = 0, is_front = 0; + u32 resolution = 0, powerup_sequence = 0; + int pwr_active = 0, rst_active = 0, pwdn_active = 0; + int flash_active = 0; + int orientation = 0; + + char sensor_name[20] = {0}; + char *name = NULL; + const char *status = NULL; + + struct rkcamera_platform_data *new_camera; + + cp = to_of_node(child); + + of_property_read_string(cp, "status", &status); + if (status && !strcmp(status, "disabled")) + continue; + + strcpy(sensor_name, cp->name); + name = sensor_name; + if (strstr(sensor_name, "_") != NULL) + name = strsep(&name, "_"); + + new_camera = kzalloc(sizeof(struct rkcamera_platform_data), + GFP_KERNEL); + if (!new_camera) + return -ENOMEM; + + if (!sensor_num) { + new_camera_head = new_camera; + rk_camera_platform_data.register_dev_new = new_camera_head; + new_camera_list = new_camera; + } + sensor_num++; + new_camera_list->next_camera = new_camera; + new_camera_list = new_camera; + + if (of_property_read_u32(cp, "flash_attach", &flash_attach)) + dprintk("%s:Get %s rockchip,flash_attach failed!\n", + __func__, cp->name); + + if (of_property_read_u32(cp, "mir", &mir)) + dprintk("%s:Get %s rockchip,mir failed!\n", + __func__, cp->name); + + if (of_property_read_u32(cp, "i2c_chl", &i2c_chl)) + dprintk("%s:Get %s rockchip,i2c_chl failed!\n", + __func__, cp->name); + + if (of_property_read_u32(cp, "cif_chl", &cif_chl)) + dprintk("%s:Get %s rockchip,cif_chl failed!\n", + __func__, cp->name); + + if (of_property_read_u32(cp, "mclk_rate", &mclk_rate)) + dprintk("%s:Get %s rockchip,mclk_rate failed!\n", + __func__, cp->name); + + if (of_property_read_u32(cp, "is_front", &is_front)) + dprintk("%s:Get %s rockchip,is_front failed!\n", + __func__, cp->name); + + if (of_property_read_u32(cp, "pwdn_active", &pwdn_active)) + dprintk("%s:Get %s pwdn_active failed!\n", + __func__, cp->name); + + if (of_property_read_u32(cp, "pwr_active", &pwr_active)) + dprintk("%s:Get %s pwr_active failed!\n", + __func__, cp->name); + + if (of_property_read_u32(cp, "rst_active", &rst_active)) + dprintk("%s:Get %s rst_active failed!\n", + __func__, cp->name); + + if (of_property_read_u32(cp, "flash_active", &flash_active)) + dprintk("%s:Get %s flash_active failed!\n", + __func__, cp->name); + + if (of_property_read_u32(cp, "i2c_add", &i2c_add)) + dprintk("%s:Get %s rockchip,i2c_add failed!\n", + __func__, cp->name); + + if (of_property_read_u32(cp, "resolution", &resolution)) + dprintk("%s:Get %s rockchip,resolution failed!\n", + __func__, cp->name); + + if (of_property_read_u32(cp, "powerup_sequence", + &powerup_sequence)) + dprintk("%s:Get %s rockchip,powerup_sequence failed!\n", + __func__, cp->name); + + if (of_property_read_u32(cp, "orientation", &orientation)) + dprintk("%s:Get %s rockchip,orientation failed!\n", + __func__, cp->name); + + of_property_read_u32_array( + cp, + "rockchip,camera-module-defrect0", + (unsigned int *)&new_camera->defrects[0], + 6); + of_property_read_string( + cp, + "rockchip,camera-module-interface0", + &new_camera->defrects[0].interface); + of_property_read_u32_array( + cp, + "rockchip,camera-module-defrect1", + (unsigned int *)&new_camera->defrects[1], + 6); + of_property_read_string( + cp, + "rockchip,camera-module-interface1", + &new_camera->defrects[1].interface); + of_property_read_u32_array( + cp, + "rockchip,camera-module-defrect2", + (unsigned int *)&new_camera->defrects[2], + 6); + of_property_read_string( + cp, + "rockchip,camera-module-interface2", + &new_camera->defrects[2].interface); + of_property_read_u32_array( + cp, + "rockchip,camera-module-defrect3", + (unsigned int *)&new_camera->defrects[3], + 6); + of_property_read_string( + cp, + "rockchip,camera-module-interface3", + &new_camera->defrects[3].interface); + of_property_read_u32_array( + cp, + "rockchip,camera-module-channel", + (unsigned int *)&new_camera->channel_info, + 2); + of_property_read_string( + cp, + "rockchip,camera-module-ain-1", + &new_camera->channel_info.channel_info[0]); + of_property_read_string( + cp, + "rockchip,camera-module-ain-2", + &new_camera->channel_info.channel_info[1]); + of_property_read_string( + cp, + "rockchip,camera-module-ain-3", + &new_camera->channel_info.channel_info[2]); + of_property_read_string( + cp, + "rockchip,camera-module-ain-4", + &new_camera->channel_info.channel_info[3]); + of_property_read_string( + cp, + "rockchip,camera-module-ain-5", + &new_camera->channel_info.channel_info[4]); + + strcpy(new_camera->dev.i2c_cam_info.type, name); + new_camera->dev.i2c_cam_info.addr = i2c_add >> 1; + new_camera->dev.desc_info.host_desc.bus_id = RK29_CAM_PLATFORM_DEV_ID + cif_chl; + new_camera->dev.desc_info.host_desc.i2c_adapter_id = i2c_chl; + new_camera->dev.desc_info.host_desc.module_name = name; + new_camera->dev.device_info.name = "soc-camera-pdrv"; + if (is_front) + sprintf(new_camera->dev_name, "%s_%s", name, "front"); + else + sprintf(new_camera->dev_name, "%s_%s", name, "back"); + new_camera->dev.device_info.dev.init_name = (const char *)&new_camera->dev_name[0]; + + new_camera->io.gpio_reset = devm_get_gpiod_from_child(dev, + "reset", child); + if (IS_ERR(new_camera->io.gpio_reset)) { + eprintk("gpio reset get failed.\n"); + new_camera->io.gpio_reset = NULL; + } + + new_camera->io.gpio_powerdown = devm_get_gpiod_from_child(dev, + "powerdown", child); + if (IS_ERR(new_camera->io.gpio_powerdown)) { + eprintk("gpio powerdown get failed.\n"); + new_camera->io.gpio_powerdown = NULL; + } + + new_camera->io.gpio_power = devm_get_gpiod_from_child(dev, + "power", child); + if (IS_ERR(new_camera->io.gpio_power)) { + eprintk("gpio power get failed.\n"); + new_camera->io.gpio_power = NULL; + } + + new_camera->io.gpio_af = devm_get_gpiod_from_child(dev, + "af", child); + if (IS_ERR(new_camera->io.gpio_af)) { + eprintk("gpio af get failed.\n"); + new_camera->io.gpio_af = NULL; + } + + new_camera->io.gpio_flash = devm_get_gpiod_from_child(dev, + "flash", child); + if (IS_ERR(new_camera->io.gpio_flash)) { + eprintk("gpio flash get failed.\n"); + new_camera->io.gpio_flash = NULL; + } + + new_camera->io.gpio_irq = devm_get_gpiod_from_child(dev, + "irq", child); + if (IS_ERR(new_camera->io.gpio_irq)) { + eprintk("gpio irq get failed.\n"); + new_camera->io.gpio_irq = NULL; + } + + new_camera->io.gpio_flag = ((pwr_active & 0x01) << RK29_CAM_POWERACTIVE_BITPOS) | + ((rst_active & 0x01) << RK29_CAM_RESETACTIVE_BITPOS) | + ((pwdn_active & 0x01) << RK29_CAM_POWERDNACTIVE_BITPOS) | + ((flash_active & 0x01) << RK29_CAM_FLASHACTIVE_BITPOS); + new_camera->orientation = orientation; + new_camera->resolution = resolution; + new_camera->mirror = mir; + new_camera->flash = flash_attach; + new_camera->pwdn_info = ((pwdn_active & 0x10) | 0x01); + new_camera->if_powerdown = true; + new_camera->powerup_sequence = powerup_sequence; + new_camera->mclk_rate = mclk_rate; + new_camera->of_node = cp; + + new_camera->powerdown_pmu_name = NULL; + new_camera->power_pmu_name1 = NULL; + new_camera->power_pmu_name2 = NULL; + new_camera->powerdown_pmu_voltage = 0; + new_camera->power_pmu_name1 = 0; + new_camera->power_pmu_name2 = 0; + + err = of_property_read_string(cp, "rockchip,powerdown_pmu", &(new_camera->powerdown_pmu_name)); + if(err < 0) + dprintk("Get rockchip,powerdown_pmu failed\n"); + + err = of_property_read_string(cp,"rockchip,power_pmu_name1", &(new_camera->power_pmu_name1)); + if(err < 0) + dprintk("Get rockchip,power_pmu_name1 failed\n"); + + err = of_property_read_string(cp,"rockchip,power_pmu_name2", &(new_camera->power_pmu_name2)); + if(err < 0) + dprintk("rockchip,power_pmu_name2 failed\n"); + + if (of_property_read_u32(cp, "rockchip,powerdown_pmu_voltage", &(new_camera->powerdown_pmu_voltage))) + dprintk("%s:Get %s rockchip,powerdown_pmu_voltage failed!\n", __func__, cp->name); + + if (of_property_read_u32(cp, "rockchip,power_pmu_voltage1", &(new_camera->power_pmu_voltage1))) + dprintk("%s:Get %s rockchip,power_pmu_voltage1 failed!\n", __func__, cp->name); + + if (of_property_read_u32(cp, "rockchip,power_pmu_voltage2", &(new_camera->power_pmu_voltage2))) + dprintk("%s:Get %s rockchip,power_pmu_voltage2 failed!\n", __func__, cp->name); + + debug_printk("******************* /n i2c_add = %x\n", new_camera->dev.i2c_cam_info.addr << 1); + debug_printk("******************* /n i2c_chl = %d\n", new_camera->dev.desc_info.host_desc.i2c_adapter_id); + debug_printk("******************* /n init_name = %s\n", new_camera->dev.device_info.dev.init_name); + debug_printk("******************* /n dev_name = %s\n", new_camera->dev_name); + debug_printk("******************* /n module_name = %s\n", new_camera->dev.desc_info.host_desc.module_name); + } + new_camera_list->next_camera = NULL; + + return 0; +} + +static int rk_dts_cif_remove(struct platform_device *pdev) +{ + return 0; +} + +static int rk_dts_cif_probe(struct platform_device *pdev) +{ + int irq, err; + struct device *dev = &pdev->dev; + const char *compatible = NULL; + struct device_node * vpu_node =NULL; + int vpu_iommu_enabled = 0; + + debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__); + + rk_camera_platform_data.cif_dev = &pdev->dev; + + err = of_address_to_resource(dev->of_node, 0, &rk_camera_resource_host_0[0]); + if (err < 0) { + printk(KERN_EMERG "Get register resource from %s platform device failed!", pdev->name); + return -ENODEV; + } + rk_camera_resource_host_0[0].flags = IORESOURCE_MEM; + /*map irqs*/ + irq = irq_of_parse_and_map(dev->of_node, 0); + if (irq < 0) { + printk(KERN_EMERG "Get irq resource from %s platform device failed!", pdev->name); + return -ENODEV;; + } + err = of_property_read_string(dev->of_node->parent, "compatible", &compatible); + rk_camera_platform_data.rockchip_name = compatible; + + vpu_node = of_find_node_by_name(NULL, "vpu_service"); + if (vpu_node) { + err = of_property_read_u32(vpu_node, "iommu_enabled", &vpu_iommu_enabled); + rk_camera_platform_data.iommu_enabled = vpu_iommu_enabled; + of_node_put(vpu_node); + } else { + printk(KERN_ERR "get vpu_node failed, vpu_iommu_enabled == 0 !!!!!!\n"); + } + + /* get cru base */ + vpu_node = of_parse_phandle(dev->of_node, "rockchip,cru", 0); + if (vpu_node) { + rk_cif_cru_base = syscon_node_to_regmap(vpu_node); + if (IS_ERR(rk_cif_cru_base)) { + printk(KERN_ERR "regmap cru failed.\n"); + err = -ENODEV; + } + } + + /* get grf base */ + vpu_node = of_parse_phandle(dev->of_node, "rockchip,grf", 0); + if (vpu_node) { + rk_cif_grf_base = syscon_node_to_regmap(vpu_node); + if (IS_ERR(rk_cif_grf_base)) { + printk(KERN_ERR "regmap grf failed.\n"); + err = -ENODEV; + } + } + + if (err < 0){ + printk(KERN_EMERG "Get rockchip compatible failed!!!!!!"); + return -ENODEV; + } + + rk_camera_resource_host_0[1].start = irq; + rk_camera_resource_host_0[1].end = irq; + rk_camera_resource_host_0[1].flags = IORESOURCE_IRQ; + return 0; +} + +static int rk_cif_sensor_init(void) +{ + debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__); + + platform_driver_register(&rk_cif_driver); + + platform_driver_register(&rk_sensor_driver); + + return 0; +} + +static int sensor_power_default_cb (struct rk29camera_gpio_res *res, int on) +{ + struct gpio_desc *camera_power = res->gpio_power; + int camera_ioflag = res->gpio_flag; + int camera_io_init = res->gpio_init; + int ret = 0; + + struct regulator *ldo_18,*ldo_28; + struct rkcamera_platform_data *dev = + container_of(res, struct rkcamera_platform_data, io); + + int power_pmu_voltage1 = dev->power_pmu_voltage1; + int power_pmu_voltage2 = dev->power_pmu_voltage2; + const char *camera_power_pmu_name1 = dev->power_pmu_name1; + const char *camera_power_pmu_name2 = dev->power_pmu_name2;; + + debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__); + + if (camera_power_pmu_name1 != NULL) { + ldo_28 = regulator_get(NULL, camera_power_pmu_name1); /* vcc18_cif */ + if (on) { + regulator_set_voltage(ldo_28, power_pmu_voltage1, power_pmu_voltage1); + ret = regulator_enable(ldo_28); + //printk("%s set ldo7 vcc28_cif=%dmV end\n", __func__, regulator_get_voltage(ldo_28)); + regulator_put(ldo_28); + + msleep(10); + } else { + while(regulator_is_enabled(ldo_28) > 0) + regulator_disable(ldo_28); + regulator_put(ldo_28); + } + } + + if(camera_power_pmu_name2 != NULL) { + ldo_18 = regulator_get(NULL, camera_power_pmu_name2); /* vcc18_cif */ + if (on) { + regulator_set_voltage(ldo_18, power_pmu_voltage2, power_pmu_voltage2); + //regulator_set_suspend_voltage(ldo, 1800000); + ret = regulator_enable(ldo_18); + //printk("%s set ldo1 vcc18_cif=%dmV end\n", __func__, regulator_get_voltage(ldo_18)); + regulator_put(ldo_18); + + msleep(10); + } else { + while(regulator_is_enabled(ldo_18) > 0) + regulator_disable(ldo_18); + regulator_put(ldo_18); + } + } + + if (camera_power) { + if (camera_io_init & RK29_CAM_POWERACTIVE_MASK) { + if (on) { + gpiod_set_value(camera_power, + ((camera_ioflag & RK29_CAM_POWERACTIVE_MASK) >> + RK29_CAM_POWERACTIVE_BITPOS)); + dprintk("%s PowerPin ..PinLevel = %x", + res->dev_name, + ((camera_ioflag & RK29_CAM_POWERACTIVE_MASK) >> + RK29_CAM_POWERACTIVE_BITPOS)); + msleep(10); + } else { + gpiod_set_value(camera_power, + (((~camera_ioflag) & RK29_CAM_POWERACTIVE_MASK) >> + RK29_CAM_POWERACTIVE_BITPOS)); + dprintk("%s PowerPin ..PinLevel = %x", + res->dev_name, + (((~camera_ioflag) & RK29_CAM_POWERACTIVE_MASK) >> + RK29_CAM_POWERACTIVE_BITPOS)); + } + } else { + ret = RK29_CAM_EIO_REQUESTFAIL; + eprintk("%s PowerPin request failed!", res->dev_name); + } + } else { + ret = RK29_CAM_EIO_INVALID; + } + + return ret; +} + +static int sensor_reset_default_cb (struct rk29camera_gpio_res *res, int on) +{ + struct gpio_desc *camera_reset = res->gpio_reset; + int camera_ioflag = res->gpio_flag; + int camera_io_init = res->gpio_init; + int ret = 0; + + debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__, __FUNCTION__); + + if (camera_reset) { + if (camera_io_init & RK29_CAM_RESETACTIVE_MASK) { + if (on) { + gpiod_set_value(camera_reset, + ((camera_ioflag & RK29_CAM_RESETACTIVE_MASK) >> + RK29_CAM_RESETACTIVE_BITPOS)); + dprintk("%s ResetPin ..PinLevel = %x", + res->dev_name, + ((camera_ioflag & RK29_CAM_RESETACTIVE_MASK) >> + RK29_CAM_RESETACTIVE_BITPOS)); + } else { + gpiod_set_value(camera_reset, + (((~camera_ioflag) & RK29_CAM_RESETACTIVE_MASK) >> + RK29_CAM_RESETACTIVE_BITPOS)); + dprintk("%s ResetPin ..PinLevel = %x", + res->dev_name, + (((~camera_ioflag) & RK29_CAM_RESETACTIVE_MASK) >> + RK29_CAM_RESETACTIVE_BITPOS)); + } + } else { + ret = RK29_CAM_EIO_REQUESTFAIL; + dprintk("%s ResetPin request failed!", + res->dev_name); + } + } else { + ret = RK29_CAM_EIO_INVALID; + } + + return ret; +} + +static int sensor_powerdown_default_cb (struct rk29camera_gpio_res *res, int on) +{ + struct gpio_desc *camera_powerdown = res->gpio_powerdown; + int camera_ioflag = res->gpio_flag; + int camera_io_init = res->gpio_init; + int ret = 0; + + struct regulator *powerdown_pmu; + struct rkcamera_platform_data *dev = + container_of(res, struct rkcamera_platform_data, io); + int powerdown_pmu_voltage = dev->powerdown_pmu_voltage; + const char *powerdown_pmu_name = dev->powerdown_pmu_name; + + debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__, __FUNCTION__); + + if (powerdown_pmu_name != NULL) { + powerdown_pmu = regulator_get(NULL, powerdown_pmu_name); + if (on) { + regulator_set_voltage(powerdown_pmu, powerdown_pmu_voltage, powerdown_pmu_voltage); + ret = regulator_enable(powerdown_pmu); + regulator_put(powerdown_pmu); + } else { + while(regulator_is_enabled(powerdown_pmu) > 0) + regulator_disable(powerdown_pmu); + regulator_put(powerdown_pmu); + } + } + + if (camera_powerdown) { + if (camera_io_init & RK29_CAM_POWERDNACTIVE_MASK) { + if (on) { + gpiod_set_value(camera_powerdown, + ((camera_ioflag & RK29_CAM_POWERDNACTIVE_MASK) >> + RK29_CAM_POWERDNACTIVE_BITPOS)); + dprintk("%s PowerDownPin ..PinLevel = %x", + res->dev_name, + ((camera_ioflag & RK29_CAM_POWERDNACTIVE_MASK) >> + RK29_CAM_POWERDNACTIVE_BITPOS)); + } else { + gpiod_set_value(camera_powerdown, + (((~camera_ioflag) & RK29_CAM_POWERDNACTIVE_MASK) >> + RK29_CAM_POWERDNACTIVE_BITPOS)); + dprintk("%s PowerDownPin ..PinLevel = %x", + res->dev_name, + (((~camera_ioflag) & RK29_CAM_POWERDNACTIVE_MASK) >> + RK29_CAM_POWERDNACTIVE_BITPOS)); + } + } else { + ret = RK29_CAM_EIO_REQUESTFAIL; + dprintk("%s PowerDownPin request failed!", + res->dev_name); + } + }else { + ret = RK29_CAM_EIO_INVALID; + } + + return ret; +} + + +static int sensor_flash_default_cb (struct rk29camera_gpio_res *res, int on) +{ + struct gpio_desc *camera_flash = res->gpio_flash; + int camera_ioflag = res->gpio_flag; + int camera_io_init = res->gpio_init; + int ret = 0; + + debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__); + + if (camera_flash) { + if (camera_io_init & RK29_CAM_FLASHACTIVE_MASK) { + switch (on) + { + case Flash_Off: + { + gpiod_set_value(camera_flash, + (((~camera_ioflag) & RK29_CAM_FLASHACTIVE_MASK) >> + RK29_CAM_FLASHACTIVE_BITPOS)); + dprintk("%s FlashPin ..PinLevel = %x", + res->dev_name, + (((~camera_ioflag) & RK29_CAM_FLASHACTIVE_MASK) >> + RK29_CAM_FLASHACTIVE_BITPOS)); + break; + } + + case Flash_On: + { + gpiod_set_value(camera_flash, + ((camera_ioflag & RK29_CAM_FLASHACTIVE_MASK) >> + RK29_CAM_FLASHACTIVE_BITPOS)); + dprintk("%s FlashPin ..PinLevel = %x", + res->dev_name, + ((camera_ioflag & RK29_CAM_FLASHACTIVE_MASK) >> + RK29_CAM_FLASHACTIVE_BITPOS)); + break; + } + + case Flash_Torch: + { + gpiod_set_value(camera_flash, + ((camera_ioflag & RK29_CAM_FLASHACTIVE_MASK) >> + RK29_CAM_FLASHACTIVE_BITPOS)); + dprintk("%s FlashPin ..PinLevel = %x", + res->dev_name, + ((camera_ioflag & RK29_CAM_FLASHACTIVE_MASK) >> + RK29_CAM_FLASHACTIVE_BITPOS)); + break; + } + + default: + { + eprintk("%s Flash command(%d) is invalidate", + res->dev_name, on); + break; + } + } + } else { + ret = RK29_CAM_EIO_REQUESTFAIL; + eprintk("%s FlashPin request failed!", + res->dev_name); + } + } else { + ret = RK29_CAM_EIO_INVALID; + } + + return ret; +} + +static int sensor_afpower_default_cb (struct rk29camera_gpio_res *res, int on) +{ + struct gpio_desc *camera_af = res->gpio_af; + + debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__, __FUNCTION__); + + if (camera_af) { + gpiod_set_value(camera_af, on); + } + + return 0; +} + +static int _rk_sensor_io_init_(struct rkcamera_platform_data *new_camera) +{ + int ret = 0; + struct rk29camera_gpio_res *gpio_res = &new_camera->io; + struct gpio_desc *camera_reset; + struct gpio_desc *camera_power; + struct gpio_desc *camera_powerdown; + struct gpio_desc *camera_flash; + struct gpio_desc *camera_af; + unsigned int camera_ioflag; + + debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__, __FUNCTION__); + + camera_reset = gpio_res->gpio_reset; + camera_power = gpio_res->gpio_power; + camera_powerdown = gpio_res->gpio_powerdown; + camera_flash = gpio_res->gpio_flash; + camera_af = gpio_res->gpio_af; + camera_ioflag = gpio_res->gpio_flag; + gpio_res->gpio_init = 0; + + if (camera_power) { + gpio_res->gpio_init |= RK29_CAM_POWERACTIVE_MASK; + gpiod_set_value(camera_power, + (((~camera_ioflag) & RK29_CAM_POWERACTIVE_MASK) >> + RK29_CAM_POWERACTIVE_BITPOS)); + gpiod_direction_output(camera_power, + (((~camera_ioflag) & RK29_CAM_POWERACTIVE_MASK) >> + RK29_CAM_POWERACTIVE_BITPOS)); + + dprintk("%s power pin init success(0x%x)", + gpio_res->dev_name, + (((~camera_ioflag) & RK29_CAM_POWERACTIVE_MASK) >> + RK29_CAM_POWERACTIVE_BITPOS)); + } + + if (camera_reset) { + gpio_res->gpio_init |= RK29_CAM_RESETACTIVE_MASK; + gpiod_set_value(camera_reset, + ((camera_ioflag & RK29_CAM_RESETACTIVE_MASK) >> + RK29_CAM_RESETACTIVE_BITPOS)); + gpiod_direction_output(camera_reset, + ((camera_ioflag & RK29_CAM_RESETACTIVE_MASK) >> + RK29_CAM_RESETACTIVE_BITPOS)); + + dprintk("%s reset pin init success(0x%x)", + gpio_res->dev_name, + ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS)); + } + + if (camera_powerdown) { + debug_printk("gpio_res->dev_name: %s", gpio_res->dev_name); + if (strstr(gpio_res->dev_name, "tp2825") || strstr(gpio_res->dev_name, "adv7181")) { + debug_printk("don't control powerdown!\n"); + new_camera->if_powerdown = false; + } + + gpio_res->gpio_init |= RK29_CAM_POWERDNACTIVE_MASK; + gpiod_set_value(camera_powerdown, ((camera_ioflag & RK29_CAM_POWERDNACTIVE_MASK) >> RK29_CAM_POWERDNACTIVE_BITPOS)); + gpiod_direction_output(camera_powerdown, ((camera_ioflag & RK29_CAM_POWERDNACTIVE_MASK) >> RK29_CAM_POWERDNACTIVE_BITPOS)); + + if (!new_camera->if_powerdown) { + gpiod_set_value(camera_powerdown, ((camera_ioflag & RK29_CAM_POWERDNACTIVE_MASK) >> RK29_CAM_POWERDNACTIVE_BITPOS)); + msleep(50); + gpiod_set_value(camera_powerdown, ((~camera_ioflag & RK29_CAM_POWERDNACTIVE_MASK) >> RK29_CAM_POWERDNACTIVE_BITPOS)); + } + + dprintk("%s powerdown pin init success(0x%x)", + gpio_res->dev_name, + ((camera_ioflag & RK29_CAM_POWERDNACTIVE_MASK) >> RK29_CAM_POWERDNACTIVE_BITPOS)); + } + + if (camera_flash) { + gpio_res->gpio_init |= RK29_CAM_FLASHACTIVE_MASK; + gpiod_set_value(camera_flash, ((~camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS)); // falsh off + gpiod_direction_output(camera_flash, ((~camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS)); + + dprintk("%s flash pin init success(0x%x)", + gpio_res->dev_name, + ((camera_ioflag & RK29_CAM_FLASHACTIVE_MASK) >> RK29_CAM_FLASHACTIVE_BITPOS)); + } + + if (camera_af) { + gpio_res->gpio_init |= RK29_CAM_AFACTIVE_MASK; + //gpio_direction_output(camera_af, ((camera_ioflag&RK29_CAM_AFACTIVE_MASK)>>RK29_CAM_AFACTIVE_BITPOS)); + dprintk("%s af pin init success",gpio_res->dev_name); + } + + return ret; +} + +static int _rk_sensor_io_deinit_(struct rk29camera_gpio_res *gpio_res) +{ + struct gpio_desc *camera_reset; + struct gpio_desc *camera_power; + struct gpio_desc *camera_powerdown; + struct gpio_desc *camera_flash; + struct gpio_desc *camera_af; + + debug_printk("/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", + __FILE__, __LINE__, __FUNCTION__); + + camera_reset = gpio_res->gpio_reset; + camera_power = gpio_res->gpio_power; + camera_powerdown = gpio_res->gpio_powerdown; + camera_flash = gpio_res->gpio_flash; + camera_af = gpio_res->gpio_af; + + if (gpio_res->gpio_init & RK29_CAM_POWERACTIVE_MASK) { + if (camera_power) { + gpiod_direction_input(camera_power); + gpiod_put(camera_power); + } + } + + if (gpio_res->gpio_init & RK29_CAM_RESETACTIVE_MASK) { + if (camera_reset) { + gpiod_direction_input(camera_reset); + gpiod_put(camera_reset); + } + } + + if (gpio_res->gpio_init & RK29_CAM_POWERDNACTIVE_MASK) { + if (camera_powerdown) { + gpiod_direction_input(camera_powerdown); + gpiod_put(camera_powerdown); + } + } + + if (gpio_res->gpio_init & RK29_CAM_FLASHACTIVE_MASK) { + if (camera_flash) { + gpiod_direction_input(camera_flash); + gpiod_put(camera_flash); + } + } + + if (gpio_res->gpio_init & RK29_CAM_AFACTIVE_MASK) { + if (camera_af) { + /* gpiod_direction_input(camera_af);*/ + gpiod_put(camera_af); + } + } + gpio_res->gpio_init = 0; + + return 0; +} + +static int rk_sensor_io_init(void) +{ + static bool is_init = false; + + struct rkcamera_platform_data *new_camera; + debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__, __FUNCTION__); + + if (is_init) + return 0; + else + is_init = true; + + if (sensor_ioctl_cb.sensor_power_cb == NULL) + sensor_ioctl_cb.sensor_power_cb = sensor_power_default_cb; + if (sensor_ioctl_cb.sensor_reset_cb == NULL) + sensor_ioctl_cb.sensor_reset_cb = sensor_reset_default_cb; + if (sensor_ioctl_cb.sensor_powerdown_cb == NULL) + sensor_ioctl_cb.sensor_powerdown_cb = sensor_powerdown_default_cb; + if (sensor_ioctl_cb.sensor_flash_cb == NULL) + sensor_ioctl_cb.sensor_flash_cb = sensor_flash_default_cb; + if (sensor_ioctl_cb.sensor_af_cb == NULL) + sensor_ioctl_cb.sensor_af_cb = sensor_afpower_default_cb; + + new_camera = new_camera_head; + while(new_camera != NULL) + { + if (_rk_sensor_io_init_(new_camera) < 0) + _rk_sensor_io_deinit_(&new_camera->io); + new_camera = new_camera->next_camera; + } + return 0; +} + +static int rk_sensor_io_deinit(int sensor) +{ + struct rkcamera_platform_data *new_camera; + + debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__); + + new_camera = new_camera_head; + while(new_camera != NULL) + { + _rk_sensor_io_deinit_(&new_camera->io); + new_camera = new_camera->next_camera; + } + + return 0; +} +static int rk_sensor_ioctrl(struct device *dev,enum rk29camera_ioctrl_cmd cmd, int on) +{ + struct rk29camera_gpio_res *res = NULL; + struct rkcamera_platform_data *new_cam_dev = NULL; + struct rk29camera_platform_data* plat_data = &rk_camera_platform_data; + int ret = RK29_CAM_IO_SUCCESS, i = 0; + struct soc_camera_desc *dev_icl = NULL; + struct rkcamera_platform_data *new_camera; + debug_printk("/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__, __FUNCTION__); + + if (res == NULL) { + new_camera = new_camera_head; + while(new_camera != NULL) { + if (strcmp(new_camera->dev_name, dev_name(dev)) == 0) { + res = (struct rk29camera_gpio_res *)&new_camera->io; + new_cam_dev = &new_camera[i]; + dev_icl = &new_camera->dev.desc_info; + break; + } + new_camera = new_camera->next_camera; + } + } + + if (res == NULL) { + eprintk("%s is not regisiterd in rk29_camera_platform_data!!",dev_name(dev)); + ret = RK29_CAM_EIO_INVALID; + goto rk_sensor_ioctrl_end; + } + + switch (cmd) + { + case Cam_Power: + { + if (sensor_ioctl_cb.sensor_power_cb) { + ret = sensor_ioctl_cb.sensor_power_cb(res, on); + ret = (ret != RK29_CAM_EIO_INVALID)?ret:0; /* ddl@rock-chips.com: v0.1.1 */ + } else { + eprintk("sensor_ioctl_cb.sensor_power_cb is NULL"); + WARN_ON(1); + } + + break; + } + + case Cam_Reset: + { + if (sensor_ioctl_cb.sensor_reset_cb) { + ret = sensor_ioctl_cb.sensor_reset_cb(res, on); + + ret = (ret != RK29_CAM_EIO_INVALID) ? ret : 0; + } else { + eprintk( "sensor_ioctl_cb.sensor_reset_cb is NULL"); + WARN_ON(1); + } + break; + } + + case Cam_PowerDown: + { + if (sensor_ioctl_cb.sensor_powerdown_cb) { + if (new_camera->if_powerdown) + ret = sensor_ioctl_cb.sensor_powerdown_cb(res, on); + } else { + eprintk("sensor_ioctl_cb.sensor_powerdown_cb is NULL"); + WARN_ON(1); + } + break; + } + + case Cam_Flash: + { + if (sensor_ioctl_cb.sensor_flash_cb) { + ret = sensor_ioctl_cb.sensor_flash_cb(res, on); + } else { + eprintk( "sensor_ioctl_cb.sensor_flash_cb is NULL!"); + WARN_ON(1); + } + break; + } + + case Cam_Af: + { + if (sensor_ioctl_cb.sensor_af_cb) { + ret = sensor_ioctl_cb.sensor_af_cb(res, on); + } else { + eprintk( "sensor_ioctl_cb.sensor_af_cb is NULL!"); + WARN_ON(1); + } + break; + } + + case Cam_Mclk: + { + if (plat_data->sensor_mclk && dev_icl) { + plat_data->sensor_mclk(dev_icl->host_desc.bus_id,(on!=0)?1:0,on); + } else { + eprintk("%s(%d): sensor_mclk(%p) or dev_icl(%p) is NULL", + __FUNCTION__,__LINE__,plat_data->sensor_mclk,dev_icl); + } + break; + } + + default: + { + eprintk("%s cmd(0x%x) is unknown!", __FUNCTION__, cmd); + break; + } + } + +rk_sensor_ioctrl_end: + return ret; +} + +static int rk_sensor_pwrseq(struct device *dev,int powerup_sequence, int on, int mclk_rate) +{ + int ret =0; + int i, powerup_type; + + debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__); + + for (i=0; i<8; i++) { + + if (on == 1) + powerup_type = SENSOR_PWRSEQ_GET(powerup_sequence, i); + else + powerup_type = SENSOR_PWRSEQ_GET(powerup_sequence, 7 - i); + + switch (powerup_type) + { + case SENSOR_PWRSEQ_AVDD: + case SENSOR_PWRSEQ_DOVDD: + case SENSOR_PWRSEQ_DVDD: + case SENSOR_PWRSEQ_PWR: + { + ret = rk_sensor_ioctrl(dev, Cam_Power, on); + if (ret < 0) { + eprintk("SENSOR_PWRSEQ_PWR failed"); + } else { + msleep(10); + dprintk("SensorPwrSeq-power: %d", on); + } + break; + } + + case SENSOR_PWRSEQ_HWRST: + { + if (!on) { + rk_sensor_ioctrl(dev, Cam_Reset, 1); + } else { + ret = rk_sensor_ioctrl(dev, Cam_Reset, 1); + msleep(2); + ret |= rk_sensor_ioctrl(dev, Cam_Reset, 0); + } + if (ret < 0) { + eprintk("SENSOR_PWRSEQ_HWRST failed"); + } else { + dprintk("SensorPwrSeq-reset: %d", on); + } + break; + } + + case SENSOR_PWRSEQ_PWRDN: + { + ret = rk_sensor_ioctrl(dev, Cam_PowerDown, !on); + if (ret < 0) { + eprintk("SENSOR_PWRSEQ_PWRDN failed"); + } else { + dprintk("SensorPwrSeq-power down: %d", !on); + } + break; + } + + case SENSOR_PWRSEQ_CLKIN: + { + ret = rk_sensor_ioctrl(dev, Cam_Mclk, (on ? mclk_rate : on)); + if (ret<0) { + eprintk("SENSOR_PWRSEQ_CLKIN failed"); + } else { + dprintk("SensorPwrSeq-clock: %d", on); + } + break; + } + + default: + break; + } + } + + return ret; +} + +static int rk_sensor_power(struct device *dev, int on) +{ + int powerup_sequence,mclk_rate; + + struct rk29camera_platform_data* plat_data = &rk_camera_platform_data; + struct rk29camera_gpio_res *dev_io = NULL; + struct rkcamera_platform_data *new_camera=NULL, *new_device=NULL; + bool real_pwroff = true; + int ret = 0; + + debug_printk("/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__, __FUNCTION__); + + new_camera = plat_data->register_dev_new; + + while (new_camera != NULL) { + if (new_camera->io.gpio_powerdown && new_camera->if_powerdown) { + gpiod_direction_output(new_camera->io.gpio_powerdown, + ((new_camera->io.gpio_flag&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS)); + } + debug_printk("new_camera->dev_name= %s \n", new_camera->dev_name); + debug_printk("dev_name(dev)= %s \n", dev_name(dev)); + if (strcmp(new_camera->dev_name,dev_name(dev))) { + debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i\n", __FILE__, __LINE__); + if (sensor_ioctl_cb.sensor_powerdown_cb && on) + { + debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i\n", __FILE__, __LINE__); + sensor_ioctl_cb.sensor_powerdown_cb(&new_camera->io,1); + } + } else { + new_device = new_camera; + dev_io = &new_camera->io; + debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i\n", __FILE__, __LINE__); + if (!Sensor_Support_DirectResume(new_camera->pwdn_info)) + real_pwroff = true; + else + real_pwroff = false; + } + new_camera = new_camera->next_camera; + } + + if (new_device != NULL) { + powerup_sequence = new_device->powerup_sequence; + if ((new_device->mclk_rate == 24) || (new_device->mclk_rate == 48)) + mclk_rate = new_device->mclk_rate*1000000; + else + mclk_rate = 24000000; + } else { + powerup_sequence = sensor_PWRSEQ_DEFAULT; + mclk_rate = 24000000; + } + + if (on) { + debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i\n", __FILE__, __LINE__); + rk_sensor_pwrseq(dev, powerup_sequence, on,mclk_rate); + } else { + if (real_pwroff) { + if (rk_sensor_pwrseq(dev, powerup_sequence, on, mclk_rate) < 0) /* ddl@rock-chips.com: v0.1.5 */ + goto PowerDown; + + /*ddl@rock-chips.com: all power down switch to Hi-Z after power off*/ + new_camera = plat_data->register_dev_new; + while (new_camera != NULL) { + if ((new_camera->io.gpio_powerdown) && new_camera->if_powerdown) { + gpiod_direction_input(new_camera->io.gpio_powerdown); + } + new_camera->pwdn_info |= 0x01; + new_camera = new_camera->next_camera; + } + } else { +PowerDown: + rk_sensor_ioctrl(dev, Cam_PowerDown, !on); + + rk_sensor_ioctrl(dev, Cam_Mclk, 0); + } + + mdelay(10);/* ddl@rock-chips.com: v0.1.3 */ + } + return ret; +} + +#if 0 +static int rk_sensor_reset(struct device *dev) +{ +#if 0 + rk_sensor_ioctrl(dev,Cam_Reset,1); + msleep(2); + rk_sensor_ioctrl(dev,Cam_Reset,0); +#else + /* + *ddl@rock-chips.com : the rest function invalidate, because this operate is put together in rk_sensor_power; + */ +#endif + return 0; +} +#endif + +static int rk_sensor_powerdown(struct device *dev, int on) +{ + debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__); + + return rk_sensor_ioctrl(dev,Cam_PowerDown,on); +} + +int rk_sensor_register(void) +{ + int i; + struct rkcamera_platform_data *new_camera; + + i = 0; + debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__, __FUNCTION__); + + new_camera = new_camera_head; + + while (new_camera != NULL) { + if (new_camera->dev.i2c_cam_info.addr == INVALID_VALUE) { + WARN(1, KERN_ERR "%s(%d): new_camera[%d] i2c addr is invalidate!", + __FUNCTION__,__LINE__,i); + continue; + } + sprintf(new_camera->dev_name,"%s_%d",new_camera->dev.device_info.dev.init_name,i+3); + new_camera->dev.device_info.dev.init_name =(const char*)&new_camera->dev_name[0]; + new_camera->io.dev_name =(const char*)&new_camera->dev_name[0]; + if (new_camera->orientation == INVALID_VALUE) { + if (strstr(new_camera->dev_name, "back")) { + new_camera->orientation = 90; + } else { + new_camera->orientation = 270; + } + } + /* ddl@rock-chips.com: v0.1.3 */ + if ((new_camera->fov_h <= 0) || (new_camera->fov_h>360)) + new_camera->fov_h = 100; + + if ((new_camera->fov_v <= 0) || (new_camera->fov_v>360)) + new_camera->fov_v = 100; + + new_camera->dev.desc_info.subdev_desc.power = rk_sensor_power; + new_camera->dev.desc_info.subdev_desc.powerdown = rk_sensor_powerdown; + new_camera->dev.desc_info.host_desc.board_info =&new_camera->dev.i2c_cam_info; + + new_camera->dev.device_info.id = i+6; + new_camera->dev.device_info.dev.platform_data = &new_camera->dev.desc_info; + new_camera->dev.desc_info.subdev_desc.drv_priv = &rk_camera_platform_data; + + platform_device_register(&(new_camera->dev.device_info)); + i++; + new_camera = new_camera->next_camera; + } + + return 0; +} + +#include "../../../drivers/media/video/rk30_camera.c" diff --git a/drivers/soc/rockchip/rk_camera.h b/drivers/soc/rockchip/rk_camera.h new file mode 100644 index 000000000000..d8740aaa6780 --- /dev/null +++ b/drivers/soc/rockchip/rk_camera.h @@ -0,0 +1,320 @@ +/* + * camera.h - PXA camera driver header file + * + * Copyright (C) 2003, Intel Corporation + * Copyright (C) 2008, Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _RK_CAMERA_H +#define _RK_CAMERA_H + +#include +#include +#include +#include +#include +#include "rk_camera_sensor_info.h" + +#define RK29_CAM_PLATFORM_DEV_ID 33 +#define RK_CAM_PLATFORM_DEV_ID_0 RK29_CAM_PLATFORM_DEV_ID +#define RK_CAM_PLATFORM_DEV_ID_1 (RK_CAM_PLATFORM_DEV_ID_0+1) +#define INVALID_VALUE -1 +#ifndef INVALID_GPIO +#define INVALID_GPIO INVALID_VALUE +#endif +#define RK29_CAM_IO_SUCCESS 0 +#define RK29_CAM_EIO_INVALID -3 +#define RK29_CAM_EIO_REQUESTFAIL -2 + +#define RK29_CAM_POWERACTIVE_BITPOS 0x00 +#define RK29_CAM_RESETACTIVE_BITPOS 0x01 +#define RK29_CAM_POWERDNACTIVE_BITPOS 0x02 +#define RK29_CAM_FLASHACTIVE_BITPOS 0x03 +#define RK29_CAM_AFACTIVE_BITPOS 0x04 + +#define RK_CAM_SUPPORT_RESOLUTION 0x800000 + +#define _CONS(a,b) a##b +#define CONS(a,b) _CONS(a,b) + +#define _CONS4(a,b,c,d) a##b##c##d +#define CONS4(a,b,c,d) _CONS4(a,b,c,d) + +#define __STR(x) #x +#define _STR(x) __STR(x) +#define STR(x) _STR(x) + +/*---------------- Camera Sensor Must Define Macro Begin ------------------------*/ +/* + * move to rk_camera_sensor_info.h yzm + */ +/*---------------- Camera Sensor Must Define Macro End ------------------------*/ + + +//#define RK29_CAM_POWERACTIVE_BITPOS 0x00 +#define RK29_CAM_POWERACTIVE_MASK (1<reserved[1] = b; +#define Sensor_CropGet(a) a->reserved[1] + +#define RK29_CAM_SUBDEV_HDR_EXPOSURE 0x04 + +#define RK_VIDEOBUF_HDR_EXPOSURE_MINUS_1 0x00 +#define RK_VIDEOBUF_HDR_EXPOSURE_NORMAL 0x01 +#define RK_VIDEOBUF_HDR_EXPOSURE_PLUS_1 0x02 +#define RK_VIDEOBUF_HDR_EXPOSURE_FINISH 0x03 +#define RK_VIDEOBUF_CODE_SET(rk_code,type) rk_code = (('R'<<24)|('K'<<16)|type) +#define RK_VIDEOBUF_CODE_CHK(rk_code) ((rk_code&(('R'<<24)|('K'<<16)))==(('R'<<24)|('K'<<16))) + +enum rk29camera_ioctrl_cmd +{ + Cam_Power, + Cam_Reset, + Cam_PowerDown, + Cam_Flash, + Cam_Mclk, + Cam_Af +}; + +enum rk29sensor_power_cmd +{ + Sensor_Power, + Sensor_Reset, + Sensor_PowerDown, + Sensor_Flash, + Sensor_Af +}; + +enum rk29camera_flash_cmd +{ + Flash_Off, + Flash_On, + Flash_Torch +}; + +struct rk29camera_gpio_res { + struct gpio_desc *gpio_reset; + struct gpio_desc *gpio_power; + struct gpio_desc *gpio_powerdown; + struct gpio_desc *gpio_flash; + struct gpio_desc *gpio_af; + struct gpio_desc *gpio_irq; + unsigned int gpio_flag; + unsigned int gpio_init; + const char *dev_name; +}; + +struct rk29camera_mem_res { + const char *name; + unsigned int start; + unsigned int size; + void __iomem *vbase; //指向IO空间的指针,为了驱动程序的通用性考虑 +}; +struct rk29camera_info { + const char *dev_name; + unsigned int orientation; + struct v4l2_frmivalenum fival[10]; +}; + +struct reginfo_t +{ + u16 reg; + u16 val; + u16 reg_len; + u16 rev; +}; +typedef struct rk_sensor_user_init_data{ + int rk_sensor_init_width; + int rk_sensor_init_height; + unsigned long rk_sensor_init_bus_param; + //enum v4l2_mbus_pixelcode rk_sensor_init_pixelcode; + struct reginfo_t * rk_sensor_init_data; + int rk_sensor_winseq_size; + struct reginfo_t * rk_sensor_init_winseq; + int rk_sensor_init_data_size; +}rk_sensor_user_init_data_s; + +typedef struct rk_camera_device_register_info { + struct i2c_board_info i2c_cam_info; + struct soc_camera_desc desc_info;/*yzm*/ + struct platform_device device_info; +}rk_camera_device_register_info_t; + +enum rk_camera_signal_polarity { + RK_CAMERA_DEVICE_SIGNAL_HIGH_LEVEL = 1, + RK_CAMERA_DEVICE_SIGNAL_LOW_LEVEL = 0, +}; + +enum rk_camera_device_type { + RK_CAMERA_DEVICE_BT601_PIONGPONG = 0x10000010, + RK_CAMERA_DEVICE_BT601_8 = 0x10000011, + RK_CAMERA_DEVICE_BT601_10 = 0x10000012, + RK_CAMERA_DEVICE_BT601_12 = 0x10000014, + RK_CAMERA_DEVICE_BT601_16 = 0x10000018, + + RK_CAMERA_DEVICE_BT656_8 = 0x10000021, + RK_CAMERA_DEVICE_BT656_10 = 0x10000022, + RK_CAMERA_DEVICE_BT656_12 = 0x10000024, + RK_CAMERA_DEVICE_BT656_16 = 0x10000028, + + RK_CAMERA_DEVICE_CVBS_NTSC = 0x20000001, + RK_CAMERA_DEVICE_CVBS_PAL = 0x20000002, + RK_CAMERA_DEVICE_CVBS_DEINTERLACE = 0x20000003, +}; + +struct rk_camera_dvp_config { + enum rk_camera_signal_polarity vsync; + enum rk_camera_signal_polarity hsync; +}; + +struct rk_camera_device_signal_config { + enum rk_camera_device_type type; + u32 code; + struct rk_camera_dvp_config dvp; + struct v4l2_rect crop; +}; + +struct rk_camera_device_defrect { + unsigned int width; + unsigned int height; + struct v4l2_rect defrect; + const char *interface; +}; + +struct rk_camera_device_channel_info { + unsigned int channel_total; + unsigned int default_id; + const char *channel_info[5]; +}; + +struct rkcamera_platform_data { + rk_camera_device_register_info_t dev; + char dev_name[32]; + struct rk29camera_gpio_res io; + int orientation; + int resolution; + int mirror; /* bit0: 0: mirror off + 1: mirror on + bit1: 0: flip off + 1: flip on + */ + bool flash; /* true: the sensor attached flash; + false: the sensor haven't attach flash; + + */ + int pwdn_info; /* bit4: 1: sensor isn't need to be init after exit stanby, it can streaming directly + 0: sensor must be init after exit standby; + + bit0: 1: sensor power have been turn off; + 0: sensor power is always on; + */ + + long powerup_sequence; /* + bit0-bit3 --- power up sequence first step; + bit4-bit7 --- power up sequence second step; + ..... + */ + int mclk_rate; /* MHz : 24/48 */ + int fov_h; /* fied of view horizontal */ + int fov_v; /* fied of view vertical */ + int if_powerdown; /* Whether to control powerdown pin when enter/exit camera; + true: control; false: don't control;*/ + const char *power_pmu_name1; + const char *power_pmu_name2; + const char *powerdown_pmu_name; + int power_pmu_voltage1; + int power_pmu_voltage2; + int powerdown_pmu_voltage; + struct device_node *of_node; + struct rkcamera_platform_data *next_camera;/*yzm*/ + struct rk_camera_device_defrect defrects[4]; + struct rk_camera_device_channel_info channel_info; +}; + +struct rk29camera_platform_data { + int (*io_init)(void); + int (*io_deinit)(int sensor); + int (*sensor_ioctrl)(struct device *dev,enum rk29camera_ioctrl_cmd cmd,int on); + + int (*sensor_register)(void); + int (*sensor_mclk)(int cif_idx, int on, int clk_rate); + + struct rkcamera_platform_data *register_dev_new; //sensor + struct device *cif_dev;/*yzm host*/ + const char *rockchip_name; + int iommu_enabled; +}; + +struct rk29camera_platform_ioctl_cb { + int (*sensor_power_cb)(struct rk29camera_gpio_res *res, int on); + int (*sensor_reset_cb)(struct rk29camera_gpio_res *res, int on); + int (*sensor_powerdown_cb)(struct rk29camera_gpio_res *res, int on); + int (*sensor_flash_cb)(struct rk29camera_gpio_res *res, int on); + int (*sensor_af_cb)(struct rk29camera_gpio_res *res, int on); +}; + +typedef struct rk29_camera_sensor_cb { + int (*sensor_cb)(void *arg); + int (*scale_crop_cb)(struct work_struct *work); +}rk29_camera_sensor_cb_s; + +#endif /* _RK_CAMERA_H */ + diff --git a/drivers/soc/rockchip/rk_camera_sensor_info.h b/drivers/soc/rockchip/rk_camera_sensor_info.h new file mode 100644 index 000000000000..94d6e4b22ce7 --- /dev/null +++ b/drivers/soc/rockchip/rk_camera_sensor_info.h @@ -0,0 +1,414 @@ +/* + * rk_camera_sensor_info.h - PXA camera driver header file + * + * Copyright (C) 2003, Intel Corporation + * Copyright (C) 2008, Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __RK_CAMERA_SENSOR_INFO_H_ +#define __RK_CAMERA_SENSOR_INFO_H_ + +/* Camera Sensor Must Define Macro Begin */ +#define RK29_CAM_SENSOR_OV7675 ov7675 +#define RK29_CAM_SENSOR_OV9650 ov9650 +#define RK29_CAM_SENSOR_OV2640 ov2640 +#define RK29_CAM_SENSOR_OV2655 ov2655 +#define RK29_CAM_SENSOR_OV2659 ov2659 +#define RK29_CAM_SENSOR_GC2145 gc2145 +#define RK29_CAM_SENSOR_GC2155 gc2155 +#define RK29_CAM_SENSOR_OV7690 ov7690 +#define RK29_CAM_SENSOR_OV3640 ov3640 +#define RK29_CAM_SENSOR_OV3660 ov3660 +#define RK29_CAM_SENSOR_OV5640 ov5640 +#define RK29_CAM_SENSOR_OV5642 ov5642 +#define RK29_CAM_SENSOR_S5K6AA s5k6aa +#define RK29_CAM_SENSOR_MT9D112 mt9d112 +#define RK29_CAM_SENSOR_MT9D113 mt9d113 +#define RK29_CAM_SENSOR_MT9P111 mt9p111 +#define RK29_CAM_SENSOR_MT9T111 mt9t111 +#define RK29_CAM_SENSOR_GT2005 gt2005 +#define RK29_CAM_SENSOR_GC0307 gc0307 +#define RK29_CAM_SENSOR_GC0308 gc0308 +#define RK29_CAM_SENSOR_GC0309 gc0309 +#define RK29_CAM_SENSOR_GC2015 gc2015 +#define RK29_CAM_SENSOR_GC0328 gc0328 +#define RK29_CAM_SENSOR_GC0329 gc0329 +#define RK29_CAM_SENSOR_GC2035 gc2035 +#define RK29_CAM_SENSOR_SIV120B siv120b +#define RK29_CAM_SENSOR_SIV121D siv121d +#define RK29_CAM_SENSOR_SID130B sid130B +#define RK29_CAM_SENSOR_HI253 hi253 +#define RK29_CAM_SENSOR_HI704 hi704 +#define RK29_CAM_SENSOR_NT99250 nt99250 +#define RK29_CAM_SENSOR_SP0718 sp0718 +#define RK29_CAM_SENSOR_SP0838 sp0838 +#define RK29_CAM_SENSOR_SP2518 sp2518 +#define RK29_CAM_SENSOR_S5K5CA s5k5ca +#define RK29_CAM_ISP_MTK9335 mtk9335isp +#define RK29_CAM_SENSOR_HM2057 hm2057 +#define RK29_CAM_SENSOR_HM5065 hm5065 +#define RK29_CAM_SENSOR_NT99160 nt99160 +#define RK29_CAM_SENSOR_NT99240 nt99240 +#define RK29_CAM_SENSOR_NT99252 nt99252 +#define RK29_CAM_SENSOR_NT99340 nt99340 +#define RK29_CAM_ISP_ICATCH7002_MI1040 icatchmi1040 +#define RK29_CAM_ISP_ICATCH7002_OV5693 icatchov5693 +#define RK29_CAM_ISP_ICATCH7002_OV8825 icatchov8825 +#define RK29_CAM_ISP_ICATCH7002_OV2720 icatchov2720 +#define RK29_CAM_SENSOR_TP2825 tp2825 /* benjo.zhou#rock-chips.com */ +#define RK29_CAM_SENSOR_ADV7181 adv7181 + +#define RK29_CAM_SENSOR_NAME_OV7675 "ov7675" +#define RK29_CAM_SENSOR_NAME_OV9650 "ov9650" +#define RK29_CAM_SENSOR_NAME_OV2640 "ov2640" +#define RK29_CAM_SENSOR_NAME_OV2655 "ov2655" +#define RK29_CAM_SENSOR_NAME_OV2659 "ov2659" +#define RK29_CAM_SENSOR_NAME_OV7690 "ov7690" +#define RK29_CAM_SENSOR_NAME_OV3640 "ov3640" +#define RK29_CAM_SENSOR_NAME_OV3660 "ov3660" +#define RK29_CAM_SENSOR_NAME_OV5640 "ov5640" +#define RK29_CAM_SENSOR_NAME_OV5642 "ov5642" +#define RK29_CAM_SENSOR_NAME_S5K6AA "s5k6aa" +#define RK29_CAM_SENSOR_NAME_MT9D112 "mt9d112" +#define RK29_CAM_SENSOR_NAME_MT9D113 "mt9d113" +#define RK29_CAM_SENSOR_NAME_MT9P111 "mt9p111" +#define RK29_CAM_SENSOR_NAME_MT9T111 "mt9t111" +#define RK29_CAM_SENSOR_NAME_GT2005 "gt2005" +#define RK29_CAM_SENSOR_NAME_GC0307 "gc0307" +#define RK29_CAM_SENSOR_NAME_GC0308 "gc0308" +#define RK29_CAM_SENSOR_NAME_GC0309 "gc0309" +#define RK29_CAM_SENSOR_NAME_GC2015 "gc2015" +#define RK29_CAM_SENSOR_NAME_GC0328 "gc0328" +#define RK29_CAM_SENSOR_NAME_GC2035 "gc2035" +#define RK29_CAM_SENSOR_NAME_GC2145 "gc2145" +#define RK29_CAM_SENSOR_NAME_GC2155 "gc2155" +#define RK29_CAM_SENSOR_NAME_GC0329 "gc0329" +#define RK29_CAM_SENSOR_NAME_SIV120B "siv120b" +#define RK29_CAM_SENSOR_NAME_SIV121D "siv121d" +#define RK29_CAM_SENSOR_NAME_SID130B "sid130B" +#define RK29_CAM_SENSOR_NAME_HI253 "hi253" +#define RK29_CAM_SENSOR_NAME_HI704 "hi704" +#define RK29_CAM_SENSOR_NAME_NT99250 "nt99250" +#define RK29_CAM_SENSOR_NAME_SP0718 "sp0718" +#define RK29_CAM_SENSOR_NAME_SP0838 "sp0838" +#define RK29_CAM_SENSOR_NAME_SP2518 "sp2518" +#define RK29_CAM_SENSOR_NAME_S5K5CA "s5k5ca" +#define RK29_CAM_ISP_NAME_MTK9335ISP "mtk9335isp" +#define RK29_CAM_SENSOR_NAME_HM2057 "hm2057" +#define RK29_CAM_SENSOR_NAME_HM5065 "hm5065" +#define RK29_CAM_ISP_NAME_ICATCH7002_MI1040 "icatchmi1040" +#define RK29_CAM_ISP_NAME_ICATCH7002_OV5693 "icatchov5693" +#define RK29_CAM_ISP_NAME_ICATCH7002_OV8825 "icatchov8825" +#define RK29_CAM_ISP_NAME_ICATCH7002_OV2720 "icatchov2720" +#define RK29_CAM_SENSOR_NAME_TP2825 "tp2825" +#define RK29_CAM_SENSOR_NAME_ADV7181 "adv7181" + +/* Sensor full resolution define */ +#define ov7675_FULL_RESOLUTION 0x30000 /* 0.3 megapixel */ +#define ov9650_FULL_RESOLUTION 0x130000 /* 1.3 megapixel */ +#define ov2640_FULL_RESOLUTION 0x200000 /* 2 megapixel */ +#define ov2655_FULL_RESOLUTION 0x200000 +#define ov2659_FULL_RESOLUTION 0x200000 +#define gc2145_FULL_RESOLUTION 0x200000 +#define gc2155_FULL_RESOLUTION 0x200000 + +#define ov2660_FULL_RESOLUTION 0x200000 + +#define ov7690_FULL_RESOLUTION 0x300000 +#define ov3640_FULL_RESOLUTION 0x300000 +#define ov3660_FULL_RESOLUTION 0x300000 +#define ov5640_FULL_RESOLUTION 0x500000 +#if defined(CONFIG_SOC_CAMERA_OV5642_INTERPOLATION_8M) + #define ov5642_FULL_RESOLUTION 0x800000 +#else + #define ov5642_FULL_RESOLUTION 0x500000 +#endif +#define s5k6aa_FULL_RESOLUTION 0x130000 +#define mt9d112_FULL_RESOLUTION 0x200000 +#define mt9d113_FULL_RESOLUTION 0x200000 +#define mt9t111_FULL_RESOLUTION 0x300000 +#define mt9p111_FULL_RESOLUTION 0x500000 +#define gt2005_FULL_RESOLUTION 0x200000 +#if defined(CONFIG_SOC_CAMERA_GC0308_INTERPOLATION_5M) + #define gc0308_FULL_RESOLUTION 0x500000 +#elif defined(CONFIG_SOC_CAMERA_GC0308_INTERPOLATION_3M) + #define gc0308_FULL_RESOLUTION 0x300000 +#elif defined(CONFIG_SOC_CAMERA_GC0308_INTERPOLATION_2M) + #define gc0308_FULL_RESOLUTION 0x200000 +#else + #define gc0308_FULL_RESOLUTION 0x30000 +#endif +#define gc0328_FULL_RESOLUTION 0x30000 +#define gc0307_FULL_RESOLUTION 0x30000 +#define gc0309_FULL_RESOLUTION 0x30000 +#define gc2015_FULL_RESOLUTION 0x200000 +#define siv120b_FULL_RESOLUTION 0x30000 +#define siv121d_FULL_RESOLUTION 0x30000 +#define sid130B_FULL_RESOLUTION 0x200000 + +#if defined(CONFIG_SOC_CAMERA_HI253_INTERPOLATION_5M) + #define hi253_FULL_RESOLUTION 0x500000 +#elif defined(CONFIG_SOC_CAMERA_HI253_INTERPOLATION_3M) + #define hi253_FULL_RESOLUTION 0x300000 +#else + #define hi253_FULL_RESOLUTION 0x200000 +#endif + +#define hi704_FULL_RESOLUTION 0x30000 +#define nt99250_FULL_RESOLUTION 0x200000 +#define sp0718_FULL_RESOLUTION 0x30000 +#define sp0838_FULL_RESOLUTION 0x30000 +#define sp2518_FULL_RESOLUTION 0x200000 +#define gc0329_FULL_RESOLUTION 0x30000 +#define s5k5ca_FULL_RESOLUTION 0x300000 +#define mtk9335isp_FULL_RESOLUTION 0x500000 +#define gc2035_FULL_RESOLUTION 0x200000 +#define hm2057_FULL_RESOLUTION 0x200000 +#define hm5065_FULL_RESOLUTION 0x500000 +#define nt99160_FULL_RESOLUTION 0x100000 +#define nt99240_FULL_RESOLUTION 0x200000 +#define nt99252_FULL_RESOLUTION 0x200000 +#define nt99340_FULL_RESOLUTION 0x300000 +#define icatchmi1040_FULL_RESOLUTION 0x200000 +#define icatchov5693_FULL_RESOLUTION 0x500000 +#define icatchov8825_FULL_RESOLUTION 0x800000 +#define icatchov2720_FULL_RESOLUTION 0x210000 +#define tp2825_FULL_RESOLUTION 0x100000 +#define adv7181_FULL_RESOLUTION 0x100000 +#define end_FULL_RESOLUTION 0x00 + +/* Sensor i2c addr define */ +#define ov7675_I2C_ADDR 0x78 +#define ov9650_I2C_ADDR 0x60 +#define ov2640_I2C_ADDR 0x60 +#define ov2655_I2C_ADDR 0x60 +#define ov2659_I2C_ADDR 0x60 +#define gc2145_I2C_ADDR 0x78 +#define gc2155_I2C_ADDR 0x78 + +#define ov7690_I2C_ADDR 0x42 +#define ov3640_I2C_ADDR 0x78 +#define ov3660_I2C_ADDR 0x78 +#define ov5640_I2C_ADDR 0x78 +#define ov5642_I2C_ADDR 0x78 + +#define s5k6aa_I2C_ADDR 0x78 +#define s5k5ca_I2C_ADDR 0x78 + +#define mt9d112_I2C_ADDR 0x78 +#define mt9d113_I2C_ADDR 0x78 +#define mt9t111_I2C_ADDR 0x78 + +#define mt9p111_I2C_ADDR 0x78 +#define gt2005_I2C_ADDR 0x78 +#define gc0307_I2C_ADDR 0x42 +#define gc0328_I2C_ADDR 0x42 +#define gc0308_I2C_ADDR 0x42 +#define gc0309_I2C_ADDR 0x42 +#define gc0329_I2C_ADDR 0x62 +#define gc2015_I2C_ADDR 0x60 +#define gc2035_I2C_ADDR 0x78 + +#define siv120b_I2C_ADDR INVALID_VALUE +#define siv121d_I2C_ADDR INVALID_VALUE +#define sid130B_I2C_ADDR 0x37 + +#define hi253_I2C_ADDR 0x40 +#define hi704_I2C_ADDR 0x60 + +#define nt99160_I2C_ADDR 0x54 +#define nt99240_I2C_ADDR 0x6c +#define nt99250_I2C_ADDR 0x6c +#define nt99252_I2C_ADDR 0x6c +#define nt99340_I2C_ADDR 0x76 + +#define sp0718_I2C_ADDR 0x42 +#define sp0838_I2C_ADDR 0x30 +#define sp0a19_I2C_ADDR 0x7a +#define sp1628_I2C_ADDR 0x78 +#define sp2518_I2C_ADDR 0x60 +#define mtk9335isp_I2C_ADDR 0x50 +#define hm2057_I2C_ADDR 0x48 +#define hm5065_I2C_ADDR 0x3e +#define icatchmi1040_I2C_ADDR 0x78 +#define icatchov5693_I2C_ADDR 0x78 +#define icatchov8825_I2C_ADDR 0x78 +#define icatchov2720_I2C_ADDR 0x78 +#define tp2825_I2C_ADDR 0x88 +#define adv7181_I2C_ADDR 0x42 +#define end_I2C_ADDR INVALID_VALUE + +/* Sensor power active level define */ +#define PWR_ACTIVE_HIGH 0x01 +#define PWR_ACTIVE_LOW 0x0 + +/* Sensor power down active level define */ +#define ov7675_PWRDN_ACTIVE 0x01 +#define ov9650_PWRDN_ACTIVE 0x01 +#define ov2640_PWRDN_ACTIVE 0x01 +#define ov2655_PWRDN_ACTIVE 0x01 +#define ov2659_PWRDN_ACTIVE 0x01 +#define gc2145_PWRDN_ACTIVE 0x01 +#define gc2155_PWRDN_ACTIVE 0x01 + +#define ov7690_PWRDN_ACTIVE 0x01 +#define ov3640_PWRDN_ACTIVE 0x01 +#define ov3660_PWRDN_ACTIVE 0x01 +#define ov5640_PWRDN_ACTIVE 0x01 +#define ov5642_PWRDN_ACTIVE 0x01 + +#define s5k6aa_PWRDN_ACTIVE 0x00 +#define s5k5ca_PWRDN_ACTIVE 0x00 + +#define mt9d112_PWRDN_ACTIVE 0x01 +#define mt9d113_PWRDN_ACTIVE 0x01 +#define mt9t111_PWRDN_ACTIVE 0x01 +#define mt9p111_PWRDN_ACTIVE 0x01 + +#define gt2005_PWRDN_ACTIVE 0x00 +#define gc0307_PWRDN_ACTIVE 0x01 +#define gc0308_PWRDN_ACTIVE 0x01 +#define gc0328_PWRDN_ACTIVE 0x01 +#define gc0309_PWRDN_ACTIVE 0x01 +#define gc0329_PWRDN_ACTIVE 0x01 +#define gc2015_PWRDN_ACTIVE 0x01 +#define gc2035_PWRDN_ACTIVE 0x01 + +#define siv120b_PWRDN_ACTIVE INVALID_VALUE +#define siv121d_PWRDN_ACTIVE INVALID_VALUE +#define sid130B_PWRDN_ACTIVE 0x37 + +#define hi253_PWRDN_ACTIVE 0x01 +#define hi704_PWRDN_ACTIVE 0x01 + +#define nt99160_PWRDN_ACTIVE 0x01 +#define nt99240_PWRDN_ACTIVE 0x01 +#define nt99250_PWRDN_ACTIVE 0x01 +#define nt99252_PWRDN_ACTIVE 0x01 +#define nt99340_PWRDN_ACTIVE 0x01 + +#define sp0718_PWRDN_ACTIVE 0x01 +#define sp0838_PWRDN_ACTIVE 0x01 +#define sp0a19_PWRDN_ACTIVE 0x01 +#define sp1628_PWRDN_ACTIVE 0x01 +#define sp2518_PWRDN_ACTIVE 0x01 +#define hm2057_PWRDN_ACTIVE 0x01 +#define hm5065_PWRDN_ACTIVE 0x00 +#define mtk9335isp_PWRDN_ACTIVE 0x01 +#define tp2825_PWRDN_ACTIVE 0x00 +#define adv7181_PWRDN_ACTIVE 0x00 +#define end_PWRDN_ACTIVE INVALID_VALUE + + +/* Sensor power up sequence define */ +/* type: bit0-bit4 */ +#define SENSOR_PWRSEQ_BEGIN 0x00 +#define SENSOR_PWRSEQ_AVDD 0x01 +#define SENSOR_PWRSEQ_DOVDD 0x02 +#define SENSOR_PWRSEQ_DVDD 0x03 +#define SENSOR_PWRSEQ_PWR 0x04 +#define SENSOR_PWRSEQ_HWRST 0x05 +#define SENSOR_PWRSEQ_PWRDN 0x06 +#define SENSOR_PWRSEQ_CLKIN 0x07 +#define SENSOR_PWRSEQ_END 0x0F + +#define SENSOR_PWRSEQ_SET(type, idx) (type << (idx * 4)) +#define SENSOR_PWRSEQ_GET(seq, idx) ((seq >> (idx * 4)) & 0x0f) + +#define sensor_PWRSEQ_DEFAULT \ + (SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_PWR, 0) |\ + SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_HWRST, 1) |\ + SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_PWRDN, 2) |\ + SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_CLKIN, 3)) + +#define ov7675_PWRSEQ sensor_PWRSEQ_DEFAULT +#define ov9650_PWRSEQ sensor_PWRSEQ_DEFAULT +#define ov2640_PWRSEQ sensor_PWRSEQ_DEFAULT +#define ov2655_PWRSEQ sensor_PWRSEQ_DEFAULT +#define ov2659_PWRSEQ sensor_PWRSEQ_DEFAULT +#define ov7690_PWRSEQ sensor_PWRSEQ_DEFAULT +#define ov3640_PWRSEQ sensor_PWRSEQ_DEFAULT +#define ov3660_PWRSEQ sensor_PWRSEQ_DEFAULT +#define ov5640_PWRSEQ sensor_PWRSEQ_DEFAULT +#define ov5642_PWRSEQ sensor_PWRSEQ_DEFAULT +#define gc2145_PWRSEQ sensor_PWRSEQ_DEFAULT +#define gc2155_PWRSEQ sensor_PWRSEQ_DEFAULT + +#define s5k6aa_PWRSEQ sensor_PWRSEQ_DEFAULT +#define s5k5ca_PWRSEQ sensor_PWRSEQ_DEFAULT + +#define mt9d112_PWRSEQ sensor_PWRSEQ_DEFAULT +#define mt9d113_PWRSEQ sensor_PWRSEQ_DEFAULT +#define mt9t111_PWRSEQ sensor_PWRSEQ_DEFAULT +#define mt9p111_PWRSEQ sensor_PWRSEQ_DEFAULT + +#define gt2005_PWRSEQ sensor_PWRSEQ_DEFAULT +#define gc0307_PWRSEQ sensor_PWRSEQ_DEFAULT +#define gc0308_PWRSEQ sensor_PWRSEQ_DEFAULT +#define gc0328_PWRSEQ sensor_PWRSEQ_DEFAULT +#define gc0309_PWRSEQ sensor_PWRSEQ_DEFAULT +#define gc0329_PWRSEQ sensor_PWRSEQ_DEFAULT +#define gc2015_PWRSEQ sensor_PWRSEQ_DEFAULT +#define gc2035_PWRSEQ sensor_PWRSEQ_DEFAULT + +#define siv120b_PWRSEQ sensor_PWRSEQ_DEFAULT +#define siv121d_PWRSEQ sensor_PWRSEQ_DEFAULT +#define sid130B_PWRSEQ sensor_PWRSEQ_DEFAULT + +#define hi253_PWRSEQ sensor_PWRSEQ_DEFAULT +#define hi704_PWRSEQ sensor_PWRSEQ_DEFAULT + +#define nt99160_PWRSEQ sensor_PWRSEQ_DEFAULT +#define nt99240_PWRSEQ sensor_PWRSEQ_DEFAULT +#define nt99250_PWRSEQ sensor_PWRSEQ_DEFAULT +#define nt99252_PWRSEQ sensor_PWRSEQ_DEFAULT +#define nt99340_PWRSEQ sensor_PWRSEQ_DEFAULT + +#define sp0718_PWRSEQ sensor_PWRSEQ_DEFAULT +#define sp0838_PWRSEQ sensor_PWRSEQ_DEFAULT +#define sp0a19_PWRSEQ sensor_PWRSEQ_DEFAULT +#define sp1628_PWRSEQ sensor_PWRSEQ_DEFAULT +#define sp2518_PWRSEQ sensor_PWRSEQ_DEFAULT +#define hm2057_PWRSEQ sensor_PWRSEQ_DEFAULT +#define hm5065_PWRSEQ \ + (SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_PWR, 1) |\ + SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_HWRST, 2) |\ + SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_PWRDN, 0) |\ + SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_CLKIN, 3)) +#define mtk9335isp_PWRSEQ sensor_PWRSEQ_DEFAULT +#define icatchov5693_PWRSEQ \ + (SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_PWR, 0) |\ + SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_HWRST, 2) |\ + SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_CLKIN, 1)) + +#define icatchov8825_PWRSEQ \ + (SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_PWR, 0) |\ + SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_HWRST, 2) |\ + SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_CLKIN, 1)) + +#define icatchov2720_PWRSEQ \ + (SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_PWR, 0) |\ + SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_HWRST, 2) |\ + SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_CLKIN, 1)) + +#define icatchmi1040_PWRSEQ \ + (SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_PWR, 0) |\ + SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_HWRST, 2) |\ + SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_CLKIN, 1)) + +#define tp2825_PWRSEQ sensor_PWRSEQ_DEFAULT +#define adv7181_PWRSEQ sensor_PWRSEQ_DEFAULT + +#define end_PWRSEQ 0xffffffff +/* Camera Sensor Must Define Macro End */ +#endif diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index 97aa13314bfd..1594f24cedfa 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h @@ -41,6 +41,10 @@ struct soc_camera_device { unsigned char iface; /* Host number */ unsigned char devnum; /* Device number per host */ struct soc_camera_sense *sense; /* See comment in struct definition */ + + struct soc_camera_ops *ops;/*yzm*/ + struct mutex video_lock;/*yzm*/ + struct video_device *vdev; struct v4l2_ctrl_handler ctrl_handler; const struct soc_camera_format_xlate *current_fmt; @@ -94,6 +98,20 @@ struct soc_camera_host_ops { struct module *owner; int (*add)(struct soc_camera_device *); void (*remove)(struct soc_camera_device *); + + int (*suspend)(struct soc_camera_device *, pm_message_t); + int (*resume)(struct soc_camera_device *); + /* ddl@rock-chips.com : + * Add ioctrl - VIDIOC_ENUM_FRAMEINTERVALS for soc-camera + */ + int (*enum_frameinervals)(struct soc_camera_device *, + struct v4l2_frmivalenum *); + int (*get_ctrl)(struct soc_camera_device *, struct v4l2_control *); + int (*set_ctrl)(struct soc_camera_device *, struct v4l2_control *); + int (*s_stream)(struct soc_camera_device *, int enable); + const struct v4l2_queryctrl *controls; + int num_controls; + int (*clock_start)(struct soc_camera_host *); void (*clock_stop)(struct soc_camera_host *); /* @@ -115,6 +133,7 @@ struct soc_camera_host_ops { * to change the output sizes */ int (*set_livecrop)(struct soc_camera_device *, const struct v4l2_crop *); + int (*get_fmt)(struct soc_camera_device *, struct v4l2_format *); int (*set_fmt)(struct soc_camera_device *, struct v4l2_format *); int (*try_fmt)(struct soc_camera_device *, struct v4l2_format *); void (*init_videobuf)(struct videobuf_queue *, @@ -145,6 +164,7 @@ struct soc_camera_subdev_desc { /* sensor driver private platform data */ void *drv_priv; + struct soc_camera_device *socdev;/*yzm*/ /* * Set unbalanced_power to true to deal with legacy drivers, failing to @@ -159,6 +179,8 @@ struct soc_camera_subdev_desc { int (*power)(struct device *, int); int (*reset)(struct device *); + int (*powerdown)(struct device *, int);/*yzm*/ + /* * some platforms may support different data widths than the sensors * native ones due to different data line routing. Let the board code @@ -209,7 +231,7 @@ struct soc_camera_link { unsigned long flags; void *priv; - + void *priv_usr; /* Set by platforms to handle misbehaving drivers */ bool unbalanced_power; /* Used by soc-camera helper functions */ @@ -218,6 +240,7 @@ struct soc_camera_link { /* Optional callbacks to power on or off and reset the sensor */ int (*power)(struct device *, int); int (*reset)(struct device *); + int (*powerdown)(struct device *, int); /*yzm*/ /* * some platforms may support different data widths than the sensors * native ones due to different data line routing. Let the board code @@ -300,6 +323,18 @@ struct soc_camera_format_xlate { const struct soc_mbus_pixelfmt *host_fmt; }; +struct soc_camera_ops { + int (*suspend)(struct soc_camera_device *, pm_message_t state); + int (*resume)(struct soc_camera_device *); + unsigned long (*query_bus_param)(struct soc_camera_device *); + int (*set_bus_param)(struct soc_camera_device *, unsigned long); + int (*enum_input)(struct soc_camera_device *, struct v4l2_input *); + const struct v4l2_queryctrl *controls; + struct v4l2_querymenu *menus; + int num_controls; + int num_menus; +}; + #define SOCAM_SENSE_PCLK_CHANGED (1 << 0) /** @@ -326,6 +361,18 @@ struct soc_camera_sense { unsigned long pixel_clock; }; +static inline struct v4l2_queryctrl const *soc_camera_find_qctrl( + struct soc_camera_ops *ops, int id) +{ + int i; + + for (i = 0; i < ops->num_controls; i++) + if (ops->controls[i].id == id) + return &ops->controls[i]; + + return NULL; +} + #define SOCAM_DATAWIDTH(x) BIT((x) - 1) #define SOCAM_DATAWIDTH_4 SOCAM_DATAWIDTH(4) #define SOCAM_DATAWIDTH_8 SOCAM_DATAWIDTH(8) @@ -336,7 +383,8 @@ struct soc_camera_sense { #define SOCAM_DATAWIDTH_16 SOCAM_DATAWIDTH(16) #define SOCAM_DATAWIDTH_18 SOCAM_DATAWIDTH(18) #define SOCAM_DATAWIDTH_24 SOCAM_DATAWIDTH(24) - +#define SOCAM_MCLK_24MHZ BIT(29) +#define SOCAM_MCLK_48MHZ BIT(31) #define SOCAM_DATAWIDTH_MASK (SOCAM_DATAWIDTH_4 | SOCAM_DATAWIDTH_8 | \ SOCAM_DATAWIDTH_9 | SOCAM_DATAWIDTH_10 | \ SOCAM_DATAWIDTH_12 | SOCAM_DATAWIDTH_15 | \ diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h new file mode 100644 index 000000000000..c14f93ccdd62 --- /dev/null +++ b/include/media/v4l2-chip-ident.h @@ -0,0 +1,413 @@ +/* + v4l2 chip identifiers header + + This header provides a list of chip identifiers that can be returned + through the VIDIOC_DBG_G_CHIP_IDENT ioctl. + + Copyright (C) 2007 Hans Verkuil + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef V4L2_CHIP_IDENT_H_ +#define V4L2_CHIP_IDENT_H_ + +/* VIDIOC_DBG_G_CHIP_IDENT: identifies the actual chip installed on the board */ + +/* KEEP THIS LIST ORDERED BY ID! + Otherwise it will be hard to see which ranges are already in use when + adding support to a new chip family. */ +enum { + /* general idents: reserved range 0-49 */ + V4L2_IDENT_NONE = 0, /* No chip matched */ + V4L2_IDENT_AMBIGUOUS = 1, /* Match too general, multiple chips matched */ + V4L2_IDENT_UNKNOWN = 2, /* Chip found, but cannot identify */ + + /* module tvaudio: reserved range 50-99 */ + V4L2_IDENT_TVAUDIO = 50, /* A tvaudio chip, unknown which it is exactly */ + + /* Sony IMX074 */ + V4L2_IDENT_IMX074 = 74, + + /* module saa7110: just ident 100 */ + V4L2_IDENT_SAA7110 = 100, + + /* module saa7115: reserved range 101-149 */ + V4L2_IDENT_SAA7111 = 101, + V4L2_IDENT_SAA7111A = 102, + V4L2_IDENT_SAA7113 = 103, + V4L2_IDENT_SAA7114 = 104, + V4L2_IDENT_SAA7115 = 105, + V4L2_IDENT_SAA7118 = 108, + + /* module saa7127: reserved range 150-199 */ + V4L2_IDENT_SAA7127 = 157, + V4L2_IDENT_SAA7129 = 159, + + /* module cx25840: reserved range 200-249 */ + V4L2_IDENT_CX25836 = 236, + V4L2_IDENT_CX25837 = 237, + V4L2_IDENT_CX25840 = 240, + V4L2_IDENT_CX25841 = 241, + V4L2_IDENT_CX25842 = 242, + V4L2_IDENT_CX25843 = 243, + + /* OmniVision sensors: reserved range 250-299 */ + V4L2_IDENT_OV7670 = 250, + V4L2_IDENT_OV7720 = 251, + V4L2_IDENT_OV7725 = 252, + V4L2_IDENT_OV7660 = 253, + V4L2_IDENT_OV9650 = 254, + V4L2_IDENT_OV9655 = 255, + V4L2_IDENT_SOI968 = 256, + V4L2_IDENT_OV9640 = 257, + V4L2_IDENT_OV6650 = 258, + V4L2_IDENT_OV2640 = 259, + V4L2_IDENT_OV9740 = 260, + V4L2_IDENT_OV5642 = 261, +/***********yzm**********/ + V4L2_IDENT_OV2655 = 262, /* ddl@rock-chips.com : ov2655 support */ + V4L2_IDENT_OV2659 = 263, + V4L2_IDENT_OV3640 = 264, + V4L2_IDENT_OV5640 = 265, + V4L2_IDENT_OV7675 = 266, + V4L2_IDENT_OV7690 = 267, + V4L2_IDENT_OV3660 = 268, + V4L2_IDENT_TP2825 = 269, + V4L2_IDENT_GC2155 = 270, + V4L2_IDENT_ADV7181 = 271, + V4L2_IDENT_GC2145 = 272, +/***********yzm********end*/ + /* module saa7146: reserved range 300-309 */ + V4L2_IDENT_SAA7146 = 300, +/***********yzm*************/ + /* Samsung sensors: reserved range 310-319 */ + V4L2_IDENT_S5K66A = 310, /* ddl@rock-chips.com : s5k66a support */ + V4L2_IDENT_S5K5CA = 311, /* ddl@rock-chips.com : s5k5ca support */ + + V4L2_IDENT_MTK9335ISP = 320, /* ddl@rock-chips.com : MTK9335ISP support */ + V4L2_IDENT_ICATCH7002_MI1040 = 321, + V4L2_IDENT_ICATCH7002_OV5693 =322, + V4L2_IDENT_ICATCH7002_OV8825 = 323, //zyt + V4L2_IDENT_ICATCH7002_OV2720 = 324, //zyt +/************yzm************end*/ + /* Conexant MPEG encoder/decoders: reserved range 400-420 */ + V4L2_IDENT_CX23418_843 = 403, /* Integrated A/V Decoder on the '418 */ + V4L2_IDENT_CX23415 = 415, + V4L2_IDENT_CX23416 = 416, + V4L2_IDENT_CX23417 = 417, + V4L2_IDENT_CX23418 = 418, + + /* module bt819: reserved range 810-819 */ + V4L2_IDENT_BT815A = 815, + V4L2_IDENT_BT817A = 817, + V4L2_IDENT_BT819A = 819, + + /* module au0828 */ + V4L2_IDENT_AU0828 = 828, + + /* module bttv: ident 848 + 849 */ + V4L2_IDENT_BT848 = 848, + V4L2_IDENT_BT849 = 849, + + /* module bt856: just ident 856 */ + V4L2_IDENT_BT856 = 856, + + /* module bt866: just ident 866 */ + V4L2_IDENT_BT866 = 866, + + /* module bttv: ident 878 + 879 */ + V4L2_IDENT_BT878 = 878, + V4L2_IDENT_BT879 = 879, + + /* module ks0127: reserved range 1120-1129 */ + V4L2_IDENT_KS0122S = 1122, + V4L2_IDENT_KS0127 = 1127, + V4L2_IDENT_KS0127B = 1128, + + /* module indycam: just ident 2000 */ + V4L2_IDENT_INDYCAM = 2000, + + /* module vp27smpx: just ident 2700 */ + V4L2_IDENT_VP27SMPX = 2700, + + /* module vpx3220: reserved range: 3210-3229 */ + V4L2_IDENT_VPX3214C = 3214, + V4L2_IDENT_VPX3216B = 3216, + V4L2_IDENT_VPX3220A = 3220, + + /* VX855 just ident 3409 */ + /* Other via devs could use 3314, 3324, 3327, 3336, 3364, 3353 */ + V4L2_IDENT_VIA_VX855 = 3409, + + /* module tvp5150 */ + V4L2_IDENT_TVP5150 = 5150, + + /* module saa5246a: just ident 5246 */ + V4L2_IDENT_SAA5246A = 5246, + + /* module saa5249: just ident 5249 */ + V4L2_IDENT_SAA5249 = 5249, + + /* module cs5345: just ident 5345 */ + V4L2_IDENT_CS5345 = 5345, + + /* module tea6415c: just ident 6415 */ + V4L2_IDENT_TEA6415C = 6415, + + /* module tea6420: just ident 6420 */ + V4L2_IDENT_TEA6420 = 6420, + + /* module saa6588: just ident 6588 */ + V4L2_IDENT_SAA6588 = 6588, + + /* module vs6624: just ident 6624 */ + V4L2_IDENT_VS6624 = 6624, + + /* module saa6752hs: reserved range 6750-6759 */ + V4L2_IDENT_SAA6752HS = 6752, + V4L2_IDENT_SAA6752HS_AC3 = 6753, + + /* modules tef6862: just ident 6862 */ + V4L2_IDENT_TEF6862 = 6862, + + /* module tvp7002: just ident 7002 */ + V4L2_IDENT_TVP7002 = 7002, + + /* module adv7170: just ident 7170 */ + V4L2_IDENT_ADV7170 = 7170, + + /* module adv7175: just ident 7175 */ + V4L2_IDENT_ADV7175 = 7175, + + /* module adv7180: just ident 7180 */ + V4L2_IDENT_ADV7180 = 7180, + + /* module adv7183: just ident 7183 */ + V4L2_IDENT_ADV7183 = 7183, + + /* module saa7185: just ident 7185 */ + V4L2_IDENT_SAA7185 = 7185, + + /* module saa7191: just ident 7191 */ + V4L2_IDENT_SAA7191 = 7191, + + /* module ths7303: just ident 7303 */ + V4L2_IDENT_THS7303 = 7303, + + /* module adv7343: just ident 7343 */ + V4L2_IDENT_ADV7343 = 7343, + + /* module ths7353: just ident 7353 */ + V4L2_IDENT_THS7353 = 7353, + + /* module adv7393: just ident 7393 */ + V4L2_IDENT_ADV7393 = 7393, + + /* module adv7604: just ident 7604 */ + V4L2_IDENT_ADV7604 = 7604, + + /* module saa7706h: just ident 7706 */ + V4L2_IDENT_SAA7706H = 7706, + + /* module mt9v011, just ident 8243 */ + V4L2_IDENT_MT9V011 = 8243, + + /* module wm8739: just ident 8739 */ + V4L2_IDENT_WM8739 = 8739, + + /* module wm8775: just ident 8775 */ + V4L2_IDENT_WM8775 = 8775, + + /* Marvell controllers starting at 8801 */ + V4L2_IDENT_CAFE = 8801, + V4L2_IDENT_ARMADA610 = 8802, + + /* AKM AK8813/AK8814 */ + V4L2_IDENT_AK8813 = 8813, + V4L2_IDENT_AK8814 = 8814, + + /* module cx23885 and cx25840 */ + V4L2_IDENT_CX23885 = 8850, + V4L2_IDENT_CX23885_AV = 8851, /* Integrated A/V decoder */ + V4L2_IDENT_CX23887 = 8870, + V4L2_IDENT_CX23887_AV = 8871, /* Integrated A/V decoder */ + V4L2_IDENT_CX23888 = 8880, + V4L2_IDENT_CX23888_AV = 8881, /* Integrated A/V decoder */ + V4L2_IDENT_CX23888_IR = 8882, /* Integrated infrared controller */ + + /* module ad9389b: just ident 9389 */ + V4L2_IDENT_AD9389B = 9389, + + /* module tda9840: just ident 9840 */ + V4L2_IDENT_TDA9840 = 9840, + + /* module tw9910: just ident 9910 */ + V4L2_IDENT_TW9910 = 9910, + + /* module sn9c20x: just ident 10000 */ + V4L2_IDENT_SN9C20X = 10000, + + /* Siliconfile sensors: reserved range 10100 - 10199 */ + V4L2_IDENT_NOON010PC30 = 10100,/*yzm*/ + /* module cx231xx and cx25840 */ + V4L2_IDENT_CX2310X_AV = 23099, /* Integrated A/V decoder; not in '100 */ + V4L2_IDENT_CX23100 = 23100, + V4L2_IDENT_CX23101 = 23101, + V4L2_IDENT_CX23102 = 23102, + + /* module msp3400: reserved range 34000-34999 for msp34xx */ + V4L2_IDENT_MSPX4XX = 34000, /* generic MSPX4XX identifier, only + use internally (tveeprom.c). */ + + V4L2_IDENT_MSP3400B = 34002, + V4L2_IDENT_MSP3400C = 34003, + V4L2_IDENT_MSP3400D = 34004, + V4L2_IDENT_MSP3400G = 34007, + V4L2_IDENT_MSP3401G = 34017, + V4L2_IDENT_MSP3402G = 34027, + V4L2_IDENT_MSP3405D = 34054, + V4L2_IDENT_MSP3405G = 34057, + V4L2_IDENT_MSP3407D = 34074, + V4L2_IDENT_MSP3407G = 34077, + + V4L2_IDENT_MSP3410B = 34102, + V4L2_IDENT_MSP3410C = 34103, + V4L2_IDENT_MSP3410D = 34104, + V4L2_IDENT_MSP3410G = 34107, + V4L2_IDENT_MSP3411G = 34117, + V4L2_IDENT_MSP3412G = 34127, + V4L2_IDENT_MSP3415D = 34154, + V4L2_IDENT_MSP3415G = 34157, + V4L2_IDENT_MSP3417D = 34174, + V4L2_IDENT_MSP3417G = 34177, + + V4L2_IDENT_MSP3420G = 34207, + V4L2_IDENT_MSP3421G = 34217, + V4L2_IDENT_MSP3422G = 34227, + V4L2_IDENT_MSP3425G = 34257, + V4L2_IDENT_MSP3427G = 34277, + + V4L2_IDENT_MSP3430G = 34307, + V4L2_IDENT_MSP3431G = 34317, + V4L2_IDENT_MSP3435G = 34357, + V4L2_IDENT_MSP3437G = 34377, + + V4L2_IDENT_MSP3440G = 34407, + V4L2_IDENT_MSP3441G = 34417, + V4L2_IDENT_MSP3442G = 34427, + V4L2_IDENT_MSP3445G = 34457, + V4L2_IDENT_MSP3447G = 34477, + + V4L2_IDENT_MSP3450G = 34507, + V4L2_IDENT_MSP3451G = 34517, + V4L2_IDENT_MSP3452G = 34527, + V4L2_IDENT_MSP3455G = 34557, + V4L2_IDENT_MSP3457G = 34577, + + V4L2_IDENT_MSP3460G = 34607, + V4L2_IDENT_MSP3461G = 34617, + V4L2_IDENT_MSP3465G = 34657, + V4L2_IDENT_MSP3467G = 34677, + + /* module msp3400: reserved range 44000-44999 for msp44xx */ + V4L2_IDENT_MSP4400G = 44007, + V4L2_IDENT_MSP4408G = 44087, + V4L2_IDENT_MSP4410G = 44107, + V4L2_IDENT_MSP4418G = 44187, + V4L2_IDENT_MSP4420G = 44207, + V4L2_IDENT_MSP4428G = 44287, + V4L2_IDENT_MSP4440G = 44407, + V4L2_IDENT_MSP4448G = 44487, + V4L2_IDENT_MSP4450G = 44507, + V4L2_IDENT_MSP4458G = 44587, + + /* Micron CMOS sensor chips: 45000-45099 */ + V4L2_IDENT_MT9M001C12ST = 45000, + V4L2_IDENT_MT9M001C12STM = 45005, + V4L2_IDENT_MT9M111 = 45007, + V4L2_IDENT_MT9M112 = 45008, + V4L2_IDENT_MT9D112 = 45009, /* ddl@rock-chips.com : MT9D112 support */ + V4L2_IDENT_MT9V022IX7ATC = 45010, /* No way to detect "normal" I77ATx */ + V4L2_IDENT_MT9V022IX7ATM = 45015, /* and "lead free" IA7ATx chips */ + V4L2_IDENT_MT9T031 = 45020, + V4L2_IDENT_MT9T111 = 45021, + V4L2_IDENT_MT9T112 = 45022, + V4L2_IDENT_MT9V111 = 45031, + V4L2_IDENT_MT9V112 = 45032, + + V4L2_IDENT_MT9P111 = 45033, /* ddl@rock-chips.com : MT9P111 support */ + V4L2_IDENT_MT9D113 = 45034, /* ddl@rock-chips.com : MT9D113 support */ + + /* HV7131R CMOS sensor: just ident 46000 */ + V4L2_IDENT_HV7131R = 46000, + + /* Sharp RJ54N1CB0C, 0xCB0C = 51980 */ + V4L2_IDENT_RJ54N1CB0C = 51980, + + /* module m52790: just ident 52790 */ + V4L2_IDENT_M52790 = 52790, + + /* module cs53132a: just ident 53132 */ + V4L2_IDENT_CS53l32A = 53132, + + /* modules upd61151 MPEG2 encoder: just ident 54000 */ + V4L2_IDENT_UPD61161 = 54000, + /* modules upd61152 MPEG2 encoder with AC3: just ident 54001 */ + V4L2_IDENT_UPD61162 = 54001, + + /* module upd64031a: just ident 64031 */ + V4L2_IDENT_UPD64031A = 64031, + + /* module upd64083: just ident 64083 */ + V4L2_IDENT_UPD64083 = 64083, + +/*************yzm************/ + V4L2_IDENT_NT99250 = 64100, /* ddl@rock-chips.com : nt99250 support */ + V4L2_IDENT_SID130B = 64101, /* ddl@rock-chips.com : sid130B support */ + + V4L2_IDENT_GT2005 = 64110, /* ddl@rock-chips.com : GT2005 support */ + V4L2_IDENT_GC0307 = 64111, /* ddl@rock-chips.com : GC0308 support */ + V4L2_IDENT_GC0308 = 64112, /* ddl@rock-chips.com : GC0308 support */ + V4L2_IDENT_GC0309 = 64113, /* ddl@rock-chips.com : GC0309 support */ + V4L2_IDENT_GC2015 = 64114, /* ddl@rock-chips.com : gc2015 support */ + V4L2_IDENT_GC0329 = 64115, /* ddl@rock-chips.com : GC0329 support */ + V4L2_IDENT_GC2035= 64116, /* ddl@rock-chips.com : GC0329 support */ + V4L2_IDENT_GC0328 = 64117, + + V4L2_IDENT_SP0838 = 64120, /* ddl@rock-chips.com : SP0838 support */ + V4L2_IDENT_SP2518 = 64121, /* ddl@rock-chips.com : SP2518 support */ + V4L2_IDENT_SP0718 = 64122, /* ddl@rock-chips.com : SP0718 support */ + + V4L2_IDENT_HI253 = 64130, /* ddl@rock-chips.com : hi253 support */ + V4L2_IDENT_HI704 = 64131, /* ddl@rock-chips.com : hi704 support */ + + V4L2_IDENT_SIV120B = 64140, /* ddl@rock-chips.com : siv120b support */ + V4L2_IDENT_SIV121D= 64141, /* ddl@rock-chips.com : sid130B support */ + + + V4L2_IDENT_HM2057 = 64150, + V4L2_IDENT_HM5065 = 64151, + + V4L2_IDENT_NT99160 = 64161, /* oyyf@rock-chips.com : nt99160 support */ + V4L2_IDENT_NT99340 = 64162, /* oyyf@rock-chips.com : nt99340 support */ + V4L2_IDENT_NT99252 = 64163, /* oyyf@rock-chips.com : nt99252 support */ + V4L2_IDENT_NT99240 = 64164, /* oyyf@rock-chips.com : nt99252 support */ +/***********yzm***********end*/ + + /* Don't just add new IDs at the end: KEEP THIS LIST ORDERED BY ID! */ +}; + +#endif diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index ec500b47d41b..735069f81699 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -409,12 +409,30 @@ struct v4l2_subdev_video_ops { struct v4l2_subdev_frame_interval *interval); int (*s_frame_interval)(struct v4l2_subdev *sd, struct v4l2_subdev_frame_interval *interval); + + int (*enum_framesizes)(struct v4l2_subdev *sd, + struct v4l2_frmsizeenum *fsize); + int (*enum_frameintervals)(struct v4l2_subdev *sd, + struct v4l2_frmivalenum *fival); + int (*s_dv_timings)(struct v4l2_subdev *sd, struct v4l2_dv_timings *timings); int (*g_dv_timings)(struct v4l2_subdev *sd, struct v4l2_dv_timings *timings); int (*query_dv_timings)(struct v4l2_subdev *sd, struct v4l2_dv_timings *timings); + + int (*enum_mbus_fmt)(struct v4l2_subdev *sd, unsigned int index, + u32 *code); + int (*enum_mbus_fsizes)(struct v4l2_subdev *sd, + struct v4l2_frmsizeenum *fsize); + int (*g_mbus_fmt)(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *fmt); + int (*try_mbus_fmt)(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *fmt); + int (*s_mbus_fmt)(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *fmt); + int (*g_mbus_config)(struct v4l2_subdev *sd, struct v4l2_mbus_config *cfg); int (*s_mbus_config)(struct v4l2_subdev *sd, diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h index e52eebc016c1..3fbffa78ca17 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h @@ -683,6 +683,27 @@ enum v4l2_exposure_auto_type { #define V4L2_CID_FOCUS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+11) #define V4L2_CID_FOCUS_AUTO (V4L2_CID_CAMERA_CLASS_BASE+12) +/* ddl@rock-chips.com : Add ioctrl - V4L2_CID_SCENE for camera scene control */ +#define V4L2_CID_CAMERA_CLASS_BASE_ROCK (V4L2_CID_CAMERA_CLASS_BASE + 40) +#define V4L2_CID_SCENE (V4L2_CID_CAMERA_CLASS_BASE_ROCK + 1) +#define V4L2_CID_EFFECT (V4L2_CID_CAMERA_CLASS_BASE_ROCK + 2) +#define V4L2_CID_FLASH (V4L2_CID_CAMERA_CLASS_BASE_ROCK + 3) +#define V4L2_CID_FOCUS_CONTINUOUS (V4L2_CID_CAMERA_CLASS_BASE_ROCK + 4) +#define V4L2_CID_FOCUSZONE (V4L2_CID_CAMERA_CLASS_BASE_ROCK + 5) +#define V4L2_CID_FACEDETECT (V4L2_CID_CAMERA_CLASS_BASE_ROCK + 6) +#define V4L2_CID_HDR (V4L2_CID_CAMERA_CLASS_BASE_ROCK + 7) +#define V4L2_CID_ISO (V4L2_CID_CAMERA_CLASS_BASE_ROCK + 8) +#define V4L2_CID_ANTIBANDING (V4L2_CID_CAMERA_CLASS_BASE_ROCK + 9) +#define V4L2_CID_WHITEBALANCE_LOCK (V4L2_CID_CAMERA_CLASS_BASE_ROCK + 10) +#define V4L2_CID_EXPOSURE_LOCK (V4L2_CID_CAMERA_CLASS_BASE_ROCK + 11) +#define V4L2_CID_METERING_AREAS (V4L2_CID_CAMERA_CLASS_BASE_ROCK + 12) +#define V4L2_CID_WDR (V4L2_CID_CAMERA_CLASS_BASE_ROCK + 13) +#define V4L2_CID_EDGE (V4L2_CID_CAMERA_CLASS_BASE_ROCK + 14) +#define V4L2_CID_JPEG_EXIF (V4L2_CID_CAMERA_CLASS_BASE_ROCK + 15) +#define V4L2_CID_DEINTERLACE (V4L2_CID_CAMERA_CLASS_BASE_ROCK + 16) +#define V4L2_CID_CHANNEL (V4L2_CID_CAMERA_CLASS_BASE_ROCK + 17) +#define V4L2_CID_VIDEO_STATE (V4L2_CID_CAMERA_CLASS_BASE_ROCK + 18) + #define V4L2_CID_ZOOM_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+13) #define V4L2_CID_ZOOM_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+14) #define V4L2_CID_ZOOM_CONTINUOUS (V4L2_CID_CAMERA_CLASS_BASE+15) diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index de14cbc2a706..1e124bc99e08 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -1485,6 +1485,7 @@ struct v4l2_ext_control { struct v4l2_ctrl_vp8_frame_hdr __user *p_vp8_frame_hdr; void __user *ptr; }; + __s32 rect[4];/*rockchip add for focus zone*/ } __attribute__ ((packed)); struct v4l2_ext_controls {