static __s32 camera_req_mclk_pin(__u32 csi_index) { char *csi_para[2] = {"csi0_para", "csi1_para"}; int req_status; script_item_u item; script_item_value_type_e type; /* »ñÈ¡gpio list */ type = script_get_item(csi_para[csi_index], "csi_ck", &item); if(SCIRPT_ITEM_VALUE_TYPE_PIO != type) { camera_err("script_get_item return type err\n"); return -ECFGERR; } /* ÉêÇëgpio */ req_status = gpio_request(item.gpio.gpio, NULL); if(0 != req_status) { camera_err("request gpio failed\n"); return -ENORMALPIN; } /* ÅäÖÃgpio */ if(0 != sw_gpio_setall_range(&item.gpio, 1)) { camera_err("sw_gpio_setall_range failed\n"); gpio_free(item.gpio.gpio); return -ECFGPIN; } /* ÊÍ·Ågpio */ if(0 == req_status) gpio_free(item.gpio.gpio); return 0; }
static __s32 camera_get_board_info(__camera_detector_t *camera_detector) { char *csi[2] = {"csi0_para", "csi1_para"}; __s32 value; __s32 ret; //get camera number if (camera_sub_name_exist(csi[0], "csi_used") && camera_sub_name_exist(csi[1], "csi_used")) { camera_detector->num = 2; } else if (camera_sub_name_exist(csi[0], "csi_used")) { ret = camera_get_sysconfig(csi[0], "csi_dev_qty", &value, 1); if (ret < 0) { return -ECFGNOEX; } else { camera_detector->num = value; if ((camera_detector->num > 2) || (camera_detector->num <= 0)) { return -ECAMNUMERR; } } } else { return -ECFGERR; } camera_get_para(camera_detector, 0, csi[0], FALSE); if (camera_detector->num == 2) { if (camera_sub_name_exist(csi[1], "csi_used")) { camera_get_para(camera_detector, 1, csi[1], FALSE); } else { camera_get_para(camera_detector, 1, csi[0], TRUE); } } //get I2C adapter camera_detector->camera[0].i2c_adap = i2c_get_adapter(camera_detector->camera[0].i2c_id); if (camera_detector->camera[0].i2c_adap == NULL) { camera_err("get I2C adapter fail, I2C id: %d \n", camera_detector->camera[0].i2c_id); return -EI2CADAPTER; } if (camera_detector->num == 2) { if (camera_detector->camera[0].i2c_id != camera_detector->camera[1].i2c_id) { camera_detector->camera[1].i2c_adap = i2c_get_adapter(camera_detector->camera[1].i2c_id); if (camera_detector->camera[1].i2c_adap == NULL) { camera_err("get I2C adapter fail, I2C id: %d \n", camera_detector->camera[1].i2c_id); return -EI2CADAPTER; } } else { camera_detector->camera[1].i2c_adap = camera_detector->camera[0].i2c_adap; } } return 0; }
static __s32 camera_req_mclk_pin(__u32 csi_index) { #ifdef VFE_GPIO char *csi_para[2] = {"csi0", "csi1"}; int req_status; script_item_u item; script_item_value_type_e type; char pin_name[32]; __u32 config; /* ��ȡgpio list */ type = script_get_item(csi_para[csi_index], "vip_csi_mck", &item); if(SCIRPT_ITEM_VALUE_TYPE_PIO != type) { camera_err("script_get_item return type err\n"); return -ECFGERR; } /* ����gpio */ req_status = gpio_request(item.gpio.gpio, NULL); if(0 != req_status) { camera_err("request gpio failed\n"); return -ENORMALPIN; } /* ����gpio */ sunxi_gpio_to_name(item.gpio.gpio, pin_name); config = SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_FUNC, item.gpio.mul_sel); pin_config_set(SUNXI_PINCTRL, pin_name, config); if (item.gpio.pull != GPIO_PULL_DEFAULT) { config = SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_PUD, item.gpio.pull); pin_config_set(SUNXI_PINCTRL, pin_name, config); } if (item.gpio.drv_level != GPIO_DRVLVL_DEFAULT) { config = SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_DRV, item.gpio.drv_level); pin_config_set(SUNXI_PINCTRL, pin_name, config); } if (item.gpio.data != GPIO_DATA_DEFAULT) { config = SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_DAT, item.gpio.data); pin_config_set(SUNXI_PINCTRL, pin_name, config); } /* �ͷ�gpio */ if(0 == req_status) gpio_free(item.gpio.gpio); return 0; #else return 0; #endif }
static __s32 camera_diff_i2c_id_detect(__camera_detector_t *camera_detector, __camera_list_t *camera_list, __u32 camera_list_size) { __u32 i, j; __u32 camera_detected = 0; __s32 ret = 0; detect_print("camera_diff_i2c_id_detect!!\n"); for (i = 0; i < camera_detector->num; i++) { for (j = 0; j < camera_list_size; j++) { if (camera_list[j].need_detect) { camera_list[j].pwr_on(j, &camera_detector->camera[i]); ret = camera_list[j].detect(j, camera_detector->camera[i].i2c_adap); if (ret == 0) { camera_list[j].pwr_off(j, &camera_detector->camera[i]); strcpy(camera_detector->camera[i].name, camera_list[j].name); camera_detector->camera[i].i2c_addr = camera_list[j].i2c_addr; camera_detected++; break; } } } } if (camera_detector->num != camera_detected) { camera_err("detect camera fail in func: camera_diff_i2c_id_detect !!\n"); return -EDETECTFAIL; } return 0; }
static __s32 camera_request_clk(__u32 csi_index, struct clk **csi_module_clk, struct clk **csi_clk_src, __hdle *csi_pin_hd) { #ifdef VFE_CLK char *csi[2] = {VFE_MASTER_CLK0, VFE_MASTER_CLK1}; __s32 ret = 0; //*csi_pin_hd = gpio_request_ex(csi_para[csi_index], NULL); ret = camera_req_mclk_pin(csi_index); if(ret != 0) { camera_err("request Mclock fail !!\n"); return ret; } *csi_module_clk = clk_get(NULL, csi[csi_index]); if(*csi_module_clk == NULL) { camera_err("get %s module clk error!\n", csi[csi_index]); return -ECLKSRC; } *csi_clk_src = clk_get(NULL, HOSC_CLK); if (*csi_clk_src == NULL) { camera_err("get %s hosc source clk error!\n", csi[csi_index]); return -ECLKSRC; } ret = clk_set_parent(*csi_module_clk, *csi_clk_src); if (ret == -1) { camera_err(" csi set parent failed \n"); return -ECLKSRC; } clk_put(*csi_clk_src); ret = clk_set_rate(*csi_module_clk, CSI_MCLK); if (ret == -1) { camera_err("set %s module clock error\n", csi[csi_index]); return -ECLKSRC; } ret = clk_prepare_enable(*csi_module_clk); if (ret == -1) { camera_err("enable module clock error\n"); return -ECLKSRC; } return 0; #else return 0; #endif }
static __s32 camera_request_clk(__u32 csi_index, struct clk **csi_module_clk, struct clk **csi_clk_src, __hdle *csi_pin_hd) { char *csi[2] = {CLK_MOD_CSI0, CLK_MOD_CSI1}; __s32 ret = 0; //*csi_pin_hd = gpio_request_ex(csi_para[csi_index], NULL); ret = camera_req_mclk_pin(csi_index); if(ret != 0) { camera_err("request Mclock fail !!\n"); return ret; } *csi_module_clk = clk_get(NULL, csi[csi_index]); if(*csi_module_clk == NULL) { camera_err("get %s module clk error!\n", csi[csi_index]); return -ECLKSRC; } *csi_clk_src = clk_get(NULL, CLK_SYS_HOSC);//"hosc" if (*csi_clk_src == NULL) { camera_err("get %s hosc source clk error!\n", csi[csi_index]); return -ECLKSRC; } ret = clk_set_parent(*csi_module_clk, *csi_clk_src); if (ret == -1) { camera_err(" csi set parent failed \n"); return -ECLKSRC; } clk_put(*csi_clk_src); ret = clk_set_rate(*csi_module_clk, CSI_MCLK); if (ret == -1) { camera_err("set %s module clock error\n", csi[csi_index]); return -ECLKSRC; } ret = clk_enable(*csi_module_clk); if (ret == -1) { camera_err("enable module clock error\n"); return -ECLKSRC; } return 0; }
static int __init camera_detector_init(void) { int err = 0; __u32 camera_list_size; char *camera_list_para = "camera_list_para"; char *camera_list_para_used = "camera_list_para_used"; detect_print("camera detect driver init\n"); if (!camera_sub_name_exist(camera_list_para, camera_list_para_used)) { __s32 value, ret; ret = camera_get_sysconfig(camera_list_para, camera_list_para_used, &value, 1); if (ret < 0) { detect_print("[camera_list_para] not exist in sys_config1.fex !! \n"); } else if (value == 0) { detect_print("[camera_list_para]->camera_list_para_used = 0," "maybe somebody does not want to use camera detector ...... \n"); } detect_print("camera detector exit, it will do nothing ...... \n"); goto exit; } camera_detector_device.groups = dev_attr_groups; err = device_register(&camera_detector_device); if (err) { camera_err("%s register camera detect driver as misc device error\n", __FUNCTION__); goto exit; } memset(camera_detector, 0, sizeof(__camera_detector_t)); err = camera_get_board_info(camera_detector); if (err) { camera_err("camera_get_board_info fail !!\n"); goto exit; } camera_list_size = sizeof(camera_list) / sizeof(__camera_list_t); camera_init_module_list(camera_list_size); camera_mclk_open(camera_detector); if ((camera_detector->camera[0].i2c_id == camera_detector->camera[1].i2c_id) && (camera_detector->num == 2)) { camera_same_i2c_id_detect(camera_detector, camera_list, camera_list_size); } else if ((camera_detector->camera[0].i2c_id != camera_detector->camera[1].i2c_id) || (camera_detector->num == 1)) { camera_diff_i2c_id_detect(camera_detector, camera_list, camera_list_size); } camera_mclk_close(camera_detector); return 0; exit: return err; }
/* use_b_para: TRUE: use para from [csi0_para] _b para FALSE: NOT use para from [csi0_para] _b para */ static __s32 camera_get_para(__camera_detector_t *camera_detector, __u32 camera_index, char *main_name, __bool use_b_para) { __u32 para_index; __u32 pin_struct_size; //char csi_drv_node[2][MAX_NODE_NAME_LEN] = {"/dev/video0", "/dev/video1"}; char csi_drv_node[2][MAX_NODE_NAME_LEN] = {"sun5i_csi0", "sun5i_csi1"}; __s32 ret; pin_struct_size = sizeof(__camera_gpio_set_t)/sizeof(__s32); if (strcmp(main_name, "csi0_para") == 0) { para_index = 0; } else { para_index = 1; } memcpy(camera_detector->camera[camera_index].drv_node_name, csi_drv_node[para_index], MAX_NODE_NAME_LEN); if (use_b_para) { camera_get_sysconfig(main_name, "csi_twi_id_b", &(camera_detector->camera[camera_index].i2c_id), 1); ret = camera_get_sysconfig(main_name, "csi_facing_b", (__s32 *)(&(camera_detector->camera[camera_index].facing)), 1); if (ret < 0) { detect_print("if you want to use camera detector, " "please add csi_facing_b in the [csi0_para]!! \n"); } camera_get_sysconfig(main_name, "csi_reset_b", (__s32 *)camera_detector->camera[camera_index].reset_pin, pin_struct_size); camera_get_sysconfig(main_name, "csi_power_en_b", (__s32 *)camera_detector->camera[camera_index].pwr_pin, pin_struct_size); camera_get_sysconfig(main_name, "csi_stby_b", (__s32 *)camera_detector->camera[camera_index].stby_pin, pin_struct_size); camera_get_sysconfig(main_name, "csi_af_en_b", (__s32 *)camera_detector->camera[camera_index].af_pwr_pin, pin_struct_size); camera_get_sysconfig(main_name, "csi_iovdd_b", (__s32 *)camera_detector->camera[camera_index].iovdd_str, MAX_VDD_STR_LEN); camera_get_sysconfig(main_name, "csi_avdd_b", (__s32 *)camera_detector->camera[camera_index].avdd_str, MAX_VDD_STR_LEN); camera_get_sysconfig(main_name, "csi_dvdd_b", (__s32 *)camera_detector->camera[camera_index].dvdd_str, MAX_VDD_STR_LEN); } else { camera_get_sysconfig(main_name, "csi_twi_id", &(camera_detector->camera[camera_index].i2c_id), 1); ret = camera_get_sysconfig(main_name, "csi_facing", (__s32 *)(&(camera_detector->camera[camera_index].facing)), 1); if (ret < 0) { detect_print("if you want to use camera detector, " "please add csi_facing in the [csi0_para]!! \n"); } camera_get_sysconfig(main_name, "csi_reset", (__s32 *)camera_detector->camera[camera_index].reset_pin, pin_struct_size); camera_get_sysconfig(main_name, "csi_power_en", (__s32 *)camera_detector->camera[camera_index].pwr_pin, pin_struct_size); camera_get_sysconfig(main_name, "csi_stby", (__s32 *)camera_detector->camera[camera_index].stby_pin, pin_struct_size); camera_get_sysconfig(main_name, "csi_af_en", (__s32 *)camera_detector->camera[camera_index].af_pwr_pin, pin_struct_size); camera_get_sysconfig(main_name, "csi_iovdd", (__s32 *)camera_detector->camera[camera_index].iovdd_str, MAX_VDD_STR_LEN); camera_get_sysconfig(main_name, "csi_avdd", (__s32 *)camera_detector->camera[camera_index].avdd_str, MAX_VDD_STR_LEN); camera_get_sysconfig(main_name, "csi_dvdd", (__s32 *)camera_detector->camera[camera_index].dvdd_str, MAX_VDD_STR_LEN); } if (camera_detector->camera[camera_index].reset_pin->port != 0) { camera_detector->camera[camera_index].reset_pin_used = 1; } if (camera_detector->camera[camera_index].pwr_pin->port != 0) { camera_detector->camera[camera_index].pwr_pin_used = 1; } if (camera_detector->camera[camera_index].stby_pin->port != 0) { camera_detector->camera[camera_index].stby_pin_used = 1; } if (strcmp(camera_detector->camera[camera_index].iovdd_str, "")) { camera_detector->camera[camera_index].iovdd = regulator_get(NULL, camera_detector->camera[camera_index].iovdd_str); if (IS_ERR(camera_detector->camera[camera_index].iovdd)) { camera_err("get regulator csi_iovdd error!! \n"); return -EPMUPIN; } } if (strcmp(camera_detector->camera[camera_index].avdd_str, "")) { camera_detector->camera[camera_index].avdd = regulator_get(NULL, camera_detector->camera[camera_index].avdd_str); if (IS_ERR(camera_detector->camera[camera_index].avdd)) { camera_err("get regulator csi_avdd error!! \n"); return -EPMUPIN; } } if (strcmp(camera_detector->camera[camera_index].dvdd_str, "")) { camera_detector->camera[camera_index].dvdd = regulator_get(NULL, camera_detector->camera[camera_index].dvdd_str); if (IS_ERR(camera_detector->camera[camera_index].dvdd)) { camera_err("get regulator csi_dvdd error!! \n"); return -EPMUPIN; } } return 0; }
static __s32 camera_same_i2c_id_detect(__camera_detector_t *camera_detector, __camera_list_t *camera_list, __u32 camera_list_size) { __u32 i, j; __u32 camera_detected = 0; __s32 ret = 0; detect_print("camera_same_i2c_id_detect!!\n"); detect_print("camera_detector->num = %d,camera_list_size = %d!!\n",camera_detector->num,camera_list_size); for (i = 0; i < camera_detector->num; i++) { for (j = 0; j < camera_list_size; j++) { if (camera_list[j].need_detect) { camera_stby_on_sensor(j,&camera_detector->camera[0]); camera_stby_on_sensor(j,&camera_detector->camera[1]); camera_list[j].pwr_on(j, &camera_detector->camera[i]); ret = camera_list[j].detect(j, camera_detector->camera[i].i2c_adap); if (ret == 0) { //camera_list[j].need_detect=false; camera_detected++; //camera_list[j].pwr_off(j, &camera_detector->camera[i]); strcpy(camera_detector->camera[i].name, camera_list[j].name); camera_detector->camera[i].i2c_addr = camera_list[j].i2c_addr; if(strcmp(camera_detector->camera[i].name,"gc2035") == 0 ) camera_detector->camera[i].i2c_addr=0x88; break; } } } } for (i = 0; i < camera_detector->num; i++) { unsigned int a,b,c; a=b=c=0; if(camera_detector->camera[i].iovdd) { while(regulator_is_enabled(camera_detector->camera[i].iovdd)) { a++; regulator_disable(camera_detector->camera[i].iovdd); //printk("cam[%d]iovdd count=%d\n",i,a); if(a>100) break; } regulator_put(camera_detector->camera[i].iovdd); } if(camera_detector->camera[i].avdd) { while(regulator_is_enabled(camera_detector->camera[i].avdd)) { b++; regulator_disable(camera_detector->camera[i].avdd); //printk("cam[%d]avdd count=%d\n",i,b); if(b>100) break; } regulator_put(camera_detector->camera[i].avdd); } if(camera_detector->camera[i].dvdd) { while(regulator_is_enabled(camera_detector->camera[i].dvdd)) { c++; regulator_disable(camera_detector->camera[i].dvdd); //printk("cam[%d]dvdd count=%d\n",i,c); if(c>100) break; } regulator_put(camera_detector->camera[i].dvdd); } } if (camera_detector->num != camera_detected) { camera_err("detect camera fail in func: camera_same_i2c_id_detect !!\n"); return -EDETECTFAIL; } detect_print("camera_detector->camera[0].name=%s,camera_detector->camera[1].name=%s\n",camera_detector->camera[0].name,camera_detector->camera[1].name); return 0; }
static __s32 camera_diff_i2c_id_detect(__camera_detector_t *camera_detector, __camera_list_t *camera_list, __u32 camera_list_size) { __u32 i, j; __u32 camera_detected = 0; __s32 ret = 0; detect_print("camera_diff_i2c_id_detect!!\n"); for (i = 0; i < camera_detector->num; i++) { for (j = 0; j < camera_list_size; j++) { if (camera_list[j].need_detect) { camera_list[j].pwr_on(j, &camera_detector->camera[i]); ret = camera_list[j].detect(j, camera_detector->camera[i].i2c_adap); camera_list[j].pwr_off(j, &camera_detector->camera[i]);//xiongbiao if (ret == 0) { //camera_list[j].pwr_off(j, &camera_detector->camera[i]); strcpy(camera_detector->camera[i].name, camera_list[j].name); camera_detector->camera[i].i2c_addr = camera_list[j].i2c_addr; camera_detected++; break; } } } } // for (i = 0; i < camera_detector->num; i++) { // unsigned int a,b,c; // a=b=c=0; // if(camera_detector->camera[i].iovdd) { // while(regulator_is_enabled(camera_detector->camera[i].iovdd)) // { // a++; // regulator_disable(camera_detector->camera[i].iovdd); // //printk("cam[%d]iovdd count=%d\n",i,a); // if(a>100) // break; // } // regulator_put(camera_detector->camera[i].iovdd); // } // if(camera_detector->camera[i].avdd) { // while(regulator_is_enabled(camera_detector->camera[i].avdd)) // { // b++; // regulator_disable(camera_detector->camera[i].avdd); // //printk("cam[%d]avdd count=%d\n",i,b); // if(b>100) // break; // } // regulator_put(camera_detector->camera[i].avdd); // } // if(camera_detector->camera[i].dvdd) { // while(regulator_is_enabled(camera_detector->camera[i].dvdd)) // { // c++; // regulator_disable(camera_detector->camera[i].dvdd); // //printk("cam[%d]dvdd count=%d\n",i,c); // if(c>100) // break; // } // regulator_put(camera_detector->camera[i].dvdd); // } // } if (camera_detector->num != camera_detected) { camera_err("detect camera fail in func: camera_diff_i2c_id_detect !!\n"); return -EDETECTFAIL; } return 0; }