#include <media/v4l2-common.h>
#include <media/v4l2-chip-ident.h>
#include <media/soc_camera.h>
-#include <mach/rk_camera.h>
-#include <linux/vmalloc.h>
+#include <plat/rk_camera.h>
+
static int debug;
module_param(debug, int, S_IRUGO|S_IWUSR);
#define MAX(x,y) ((x>y) ? x: y)
/* Sensor Driver Configuration */
-#define SENSOR_NAME RK_CAM_SENSOR_GC0307
+#define SENSOR_NAME RK29_CAM_SENSOR_GC0307
#define SENSOR_V4L2_IDENT V4L2_IDENT_GC0307
#define SENSOR_ID 0x99
#define SENSOR_MIN_WIDTH 640//176
#define SENSOR_MIN_HEIGHT 480//144
#define SENSOR_MAX_WIDTH 800//1600
#define SENSOR_MAX_HEIGHT 600//1200
-#define SENSOR_INIT_WIDTH sensor_init_width /* Sensor pixel size for sensor_init_data array */
-#define SENSOR_INIT_HEIGHT sensor_init_height
-#define SENSOR_INIT_WINSEQADR sensor_init_winseq_p
-#define SENSOR_INIT_PIXFMT sensor_init_pixelcode
-#define SENSOR_BUS_PARAM sensor_init_busparam
+#define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */
+#define SENSOR_INIT_HEIGHT 480
+#define SENSOR_INIT_WINSEQADR sensor_vga
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8
#define CONFIG_SENSOR_WhiteBalance 1
#define CONFIG_SENSOR_Brightness 0
#define CONFIG_SENSOR_DigitalZoom 0
#define CONFIG_SENSOR_Focus 0
#define CONFIG_SENSOR_Exposure 0
-#define CONFIG_SENSOR_Flash 0
+#define CONFIG_SENSOR_Flash 1
#define CONFIG_SENSOR_Mirror 0
#define CONFIG_SENSOR_Flip 0
#define CONFIG_SENSOR_I2C_NOSCHED 0
#define CONFIG_SENSOR_I2C_RDWRCHK 0
+#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\
+ SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\
+ SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ)
+
#define COLOR_TEMPERATURE_CLOUDY_DN 6500
#define COLOR_TEMPERATURE_CLOUDY_UP 8000
#define COLOR_TEMPERATURE_CLEARDAY_DN 5000
u8 val;
};
-static s32 sensor_init_width = 0;
-static s32 sensor_init_height = 0;
-static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ);
-static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8;
-static struct reginfo* sensor_init_data_p = NULL;
-static struct reginfo* sensor_init_winseq_p = NULL;
-static struct reginfo* sensor_init_winseq_board = NULL;
-/* init 800*600 SVGA */
+//flash off in fixed time to prevent from too hot , zyc
+struct flash_timer{
+ struct soc_camera_device *icd;
+ struct hrtimer timer;
+};
+static enum hrtimer_restart flash_off_func(struct hrtimer *timer);
+
+static struct flash_timer flash_off_timer;
+//for user defined if user want to customize the series , zyc
+#ifdef CONFIG_GC0307_USER_DEFINED_SERIES
+#include "gc0307_user_series.c"
+#else
+/* init 640X480 VGA */
static struct reginfo sensor_init_data[] =
{
//========= close output
{0xff, 0xff},
};
-
+#endif
static struct reginfo sensor_ClrFmt_YUYV[]=
{
{0xff, 0xff},
#endif
};
-static const struct v4l2_queryctrl sensor_controls[] =
+static struct v4l2_queryctrl sensor_controls[] =
{
#if CONFIG_SENSOR_WhiteBalance
{
#if CONFIG_SENSOR_I2C_NOSCHED
atomic_t tasklock_cnt;
#endif
- struct rkcamera_platform_data *sensor_io_request;
- struct rkcamera_gpio_res *sensor_gpio_res;
+ struct rk29camera_platform_data *sensor_io_request;
+ struct rk29camera_gpio_res *sensor_gpio_res;
};
static struct sensor* to_sensor(const struct i2c_client *client)
return 0;
}
-static int sensor_ioctrl(struct soc_camera_device *icd,enum rksensor_power_cmd cmd, int on)
+static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on)
{
struct soc_camera_link *icl = to_soc_camera_link(icd);
int ret = 0;
{
if (icl->powerdown) {
ret = icl->powerdown(icd->pdev, on);
- if (ret == RK_CAM_IO_SUCCESS) {
+ if (ret == RK29_CAM_IO_SUCCESS) {
if (on == 0) {
mdelay(2);
if (icl->reset)
icl->reset(icd->pdev);
}
- } else if (ret == RK_CAM_EIO_REQUESTFAIL) {
+ } else if (ret == RK29_CAM_EIO_REQUESTFAIL) {
ret = -ENODEV;
goto sensor_power_end;
}
if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) {
sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on);
+ if(on){
+ //flash off after 2 secs
+ hrtimer_cancel(&(flash_off_timer.timer));
+ hrtimer_start(&(flash_off_timer.timer),ktime_set(0, 800*1000*1000),HRTIMER_MODE_REL);
+ }
}
break;
}
return ret;
}
+static enum hrtimer_restart flash_off_func(struct hrtimer *timer){
+ struct flash_timer *fps_timer = container_of(timer, struct flash_timer, timer);
+ sensor_ioctrl(fps_timer->icd,Sensor_Flash,0);
+ SENSOR_DG("%s %s !!!!!!",SENSOR_NAME_STRING(),__FUNCTION__);
+ return 0;
+
+}
static int sensor_init(struct v4l2_subdev *sd, u32 val)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);;
struct sensor *sensor = to_sensor(client);
const struct v4l2_queryctrl *qctrl;
const struct sensor_datafmt *fmt;
- char value;
- int ret,pid = 0,i = 0,j=0;
- struct rkcamera_platform_data* tmp_plat_data =(struct rkcamera_platform_data*)val;
- sensor_init_data_p = sensor_init_data;
- sensor_init_winseq_p = sensor_vga;
- sensor_init_width = 640;
- sensor_init_height = 480;
- if (tmp_plat_data != NULL) {
- for(i = 0;i < RK_CAM_NUM_PER_HOST;i++){
- if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name &&
- (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0))
- break;
- }
- }
- if(tmp_plat_data && (i < RK_CAM_NUM_PER_HOST) && tmp_plat_data->sensor_init_data[i]){
- //user has defined the init data
- //init reg
- if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
- for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){
- sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg;
- sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val;
- }
- sensor_init_data_p = sensor_init_data;
- }
- else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){
- sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data);
- }
- //init winseq
- if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
- int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size;
- if(sensor_init_winseq_board)
- {
- vfree(sensor_init_winseq_board);
- sensor_init_winseq_board = NULL;
- }
- sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size);
- if(!sensor_init_winseq_board)
- SENSOR_TR("%s :vmalloc erro !",__FUNCTION__);
- for(j = 0;j< tmp_winseq_size;j++){
- sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg;
- sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val;
- }
- sensor_init_winseq_p = sensor_init_winseq_board;
- }
- else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){
- sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq);
- }
- //init width,height,bus,pixelcode
- if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE)
- sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width;
- if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE)
- sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height;
- if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE)
- sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param;
- if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE)
- sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode;
- }
+ int ret;
+
+
SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
mdelay(5); */ //delay 5 microseconds
- ret = sensor_write_array(client, sensor_init_data_p);
+ ret = sensor_write_array(client, sensor_init_data);
if (ret != 0)
{
SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
int i;
u8 val;
printk("****************** check init data\n");
- for(i=0; sensor_init_data_p[i].reg!=0xff; i++)
+ for(i=0; sensor_init_data[i].reg!=0xff; i++)
{
- sensor_read(client, sensor_init_data_p[i].reg, &val);
+ sensor_read(client, sensor_init_data[i].reg, &val);
printk("reg 0x%02x: org=0x%02x, val=0x%02x, %s\n",
- sensor_init_data_p[i].reg,
- sensor_init_data_p[i].val,
+ sensor_init_data[i].reg,
+ sensor_init_data[i].val,
val,
- sensor_init_data_p[i].val==val?"O":"X");
+ sensor_init_data[i].val==val?"O":"X");
}
printk("**********************************\n");
qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH);
if (qctrl)
sensor->info_priv.flash = qctrl->default_value;
+ flash_off_timer.icd = icd;
+ flash_off_timer.timer.function = flash_off_func;
#endif
SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height);
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct sensor *sensor = to_sensor(client);
const struct sensor_datafmt *fmt;
- int ret = 0;
+ int ret = 0,set_w,set_h;
fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts,
ARRAY_SIZE(sensor_colour_fmts));
else if (mf->width < SENSOR_MIN_WIDTH)
mf->width = SENSOR_MIN_WIDTH;
+ set_w = mf->width;
+ set_h = mf->height;
+
+ if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg!=0xff)
+ {
+ set_w = 176;
+ set_h = 144;
+ }
+ else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg!=0xff)
+ {
+ set_w = 320;
+ set_h = 240;
+ }
+ else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg!=0xff)
+ {
+ set_w = 352;
+ set_h = 288;
+ }
+ else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg!=0xff)
+ {
+ set_w = 640;
+ set_h = 480;
+ }
+ else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg!=0xff)
+ {
+ set_w = 800;
+ set_h = 600;
+ }
+ else if (((set_w <= 1280) && (set_h <= 720)) && sensor_720p[0].reg!=0xff)
+ {
+ set_w = 1280;
+ set_h = 720;
+ }
+ else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg!=0xff)
+ {
+ set_w = 1280;
+ set_h = 1024;
+ }
+ else
+ {
+ set_w = SENSOR_INIT_WIDTH;
+ set_h = SENSOR_INIT_HEIGHT;
+ }
+
+ mf->width = set_w;
+ mf->height = set_h;
mf->colorspace = fmt->colorspace;
return ret;
SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
switch (cmd)
{
- case RK_CAM_SUBDEV_DEACTIVATE:
+ case RK29_CAM_SUBDEV_DEACTIVATE:
{
sensor_deactivate(client);
break;
}
- case RK_CAM_SUBDEV_IOREQUEST:
+ case RK29_CAM_SUBDEV_IOREQUEST:
{
- sensor->sensor_io_request = (struct rkcamera_platform_data*)arg;
+ sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;
if (sensor->sensor_io_request != NULL) {
- if (sensor->sensor_io_request->gpio_res[0].dev_name &&
- (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) {
- sensor->sensor_gpio_res = (struct rkcamera_gpio_res*)&sensor->sensor_io_request->gpio_res[0];
- } else if (sensor->sensor_io_request->gpio_res[1].dev_name &&
- (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) {
- sensor->sensor_gpio_res = (struct rkcamera_gpio_res*)&sensor->sensor_io_request->gpio_res[1];
+ sensor->sensor_gpio_res = NULL;
+ for (i=0; i<RK29_CAM_SUPPORT_NUMS;i++) {
+ if (sensor->sensor_io_request->gpio_res[i].dev_name &&
+ (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) {
+ sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i];
+ }
+ }
+ if (sensor->sensor_gpio_res == NULL) {
+ SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__);
+ ret = -EINVAL;
+ goto sensor_ioctl_end;
}
} else {
- SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+ SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
ret = -EINVAL;
goto sensor_ioctl_end;
}
if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) {
for (i = 0; i < icd->ops->num_controls; i++) {
if (V4L2_CID_FLASH == icd->ops->controls[i].id) {
- memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl));
+ //memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl));
+ sensor_controls[i].id=0xffff;
}
}
sensor->info_priv.flash = 0xff;
SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING());
+ }else{ //two cameras are the same,need to deal diffrently ,zyc
+ for (i = 0; i < icd->ops->num_controls; i++) {
+ if(0xffff == icd->ops->controls[i].id){
+ sensor_controls[i].id=V4L2_CID_FLASH;
+ }
+ }
}
}
#endif
kfree(sensor);
sensor = NULL;
}
+ hrtimer_init(&(flash_off_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL);
SENSOR_DG("\n%s..%s..%d ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret);
return ret;
}