| /* |
| * drivers/amlogic/media/camera/common/config_parser.c |
| * |
| * Copyright (C) 2017 Amlogic, Inc. All rights reserved. |
| * |
| * 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 "config_parser.h" |
| #include <linux/uaccess.h> |
| #include <linux/fs.h> |
| #include <linux/vmalloc.h> |
| #include <linux/errno.h> |
| |
| static struct file *fp; |
| mm_segment_t fs; |
| |
| char *aet_key = "aet_start"; |
| char *hw_key = "hw_start"; |
| char *effect_key = "effect_start"; |
| char *capture_key = "capture_start"; |
| char *scenes_key = "scenes_start"; |
| char *wb_key = "wb_start"; |
| char *wave_key = "wave_start"; |
| char *lens_key = "lens_start"; |
| char *gamma_key = "gamma_start"; |
| char *wb_sensor_key = "mwb_sensor_start"; |
| char *version_key = "version_start"; |
| char *cm_key = "cm_start"; |
| char *nr_key = "nr_start"; |
| char *peaking_key = "peaking_start"; |
| |
| struct buffer_para_s { |
| char *buffer; |
| int data_start; |
| int data_size; |
| int buffer_len; |
| }; |
| |
| void *realloc_mem(char *buffer, int new_size, int *old_size) |
| { |
| char *tmp = vmalloc(new_size); |
| |
| if (*old_size >= new_size) { |
| vfree(tmp); |
| return buffer; |
| } |
| |
| if (tmp != NULL) { |
| memcpy(tmp, buffer, *old_size); |
| *old_size = new_size; |
| vfree(buffer); |
| return tmp; |
| } else |
| return NULL; |
| } |
| |
| /* |
| *************************************** |
| *Name : camera_open_config |
| *Input : *config_file |
| *Output : file size |
| *function : open the firware file, and return total size |
| *************************************** |
| */ |
| |
| int camera_open_config(const char *config_file) |
| { |
| loff_t file_size; |
| struct inode *inode = NULL; |
| |
| fp = filp_open(config_file, O_RDONLY, 0); |
| if (IS_ERR(fp)) { |
| pr_err("read config file error"); |
| return -1; |
| } |
| |
| inode = fp->f_path.dentry->d_inode; |
| file_size = inode->i_size; |
| fs = get_fs(); |
| set_fs(KERNEL_DS); |
| |
| return file_size; |
| |
| } |
| |
| /* |
| *********************************** |
| *Name : camera_read_config |
| *Input : offset |
| *length, read length |
| *buf, return buffer |
| *Output : |
| *function : read data to buffer |
| *********************************** |
| */ |
| |
| int camera_read_config(int offset, int length, char *buf) |
| { |
| loff_t pos = offset; |
| |
| vfs_read(fp, buf, length, &pos); |
| return 0; |
| } |
| |
| /* |
| ********************************** |
| *Name : camera_close_config |
| *Input : |
| *Output : |
| *function : close file |
| ********************************** |
| */ |
| |
| int camera_close_config(void) |
| { |
| set_fs(fs); |
| filp_close(fp, NULL); |
| return 0; |
| } |
| |
| static int camera_read_buff(struct i2c_adapter *adapter, |
| unsigned short i2c_addr, char *buf, int addr_len, |
| int data_len) |
| { |
| int i2c_flag = -1; |
| |
| struct i2c_msg msgs[] = {{ |
| .addr = i2c_addr, .flags = 0, |
| .len = addr_len, .buf = buf, |
| }, { |
| .addr = i2c_addr, .flags = I2C_M_RD, |
| .len = data_len, .buf = buf, |
| } |
| }; |
| |
| i2c_flag = i2c_transfer(adapter, msgs, 2); |
| |
| return i2c_flag; |
| } |
| |
| static int camera_write_buff(struct i2c_adapter *adapter, |
| unsigned short i2c_addr, char *buf, int len) |
| { |
| struct i2c_msg msg[] = {{ |
| .addr = i2c_addr, .flags = 0, /* |I2C_M_TEN, */ |
| .len = len, .buf = buf, |
| } |
| |
| }; |
| |
| if (i2c_transfer(adapter, msg, 1) < 0) |
| return -1; |
| else |
| return 0; |
| } |
| |
| int my_i2c_put_byte(struct i2c_adapter *adapter, unsigned short i2c_addr, |
| unsigned short addr, unsigned char data) |
| { |
| unsigned char buff[4]; |
| |
| buff[0] = (unsigned char)((addr >> 8) & 0xff); |
| buff[1] = (unsigned char)(addr & 0xff); |
| buff[2] = data; |
| if (camera_write_buff(adapter, i2c_addr, buff, 3) < 0) |
| return -1; |
| return 0; |
| } |
| |
| int my_i2c_put_byte_add8(struct i2c_adapter *adapter, unsigned short i2c_addr, |
| char *buf, int len) |
| { |
| if (camera_write_buff(adapter, i2c_addr, buf, len) < 0) |
| return -1; |
| return 0; |
| } |
| |
| int my_i2c_get_byte(struct i2c_adapter *adapter, unsigned short i2c_addr, |
| unsigned short addr) |
| { |
| unsigned char buff[4]; |
| |
| buff[0] = (unsigned char)((addr >> 8) & 0xff); |
| buff[1] = (unsigned char)(addr & 0xff); |
| |
| if (camera_read_buff(adapter, i2c_addr, buff, 2, 1) < 0) |
| return -1; |
| return buff[0]; |
| } |
| |
| int my_i2c_get_word(struct i2c_adapter *adapter, unsigned short i2c_addr) |
| { |
| unsigned char buff[4]; |
| unsigned short data; |
| |
| buff[0] = 0; |
| |
| if (camera_read_buff(adapter, i2c_addr, buff, 1, 2) < 0) |
| return -1; |
| |
| data = buff[0]; |
| data = (data << 8) | buff[1]; |
| |
| return data; |
| } |
| |
| char *search_string(struct buffer_para_s *buf_para, int *offset, int *remained, |
| char *start, char *end) |
| { |
| char *iter, *pter, *buffer; |
| int data_start, data_size, buffer_len; |
| int add = 0; |
| |
| buffer = buf_para->buffer; |
| data_start = buf_para->data_start; |
| data_size = buf_para->data_size; |
| buffer_len = buf_para->buffer_len; |
| iter = strstr(buffer + data_start, start); |
| while (iter == NULL) { |
| if (iter == NULL && *remained < strlen(start)) { |
| pr_err("wrong config file"); |
| return NULL; |
| } |
| memset(buffer, 0, buffer_len); |
| if (*remained < BUFFER_SIZE) { |
| camera_read_config(*offset - strlen(start), |
| *remained, buffer); /* check bounds */ |
| *offset += *remained - strlen(start); |
| data_size = *remained; |
| *remained = 0; |
| data_start = 0; |
| } else { |
| camera_read_config(*offset - strlen(start), |
| BUFFER_SIZE, buffer);/* check bounds */ |
| *offset += BUFFER_SIZE - strlen(start); |
| data_size = BUFFER_SIZE; |
| *remained -= BUFFER_SIZE; |
| data_start = 0; |
| } |
| iter = strstr(buffer, start); |
| } |
| data_start = iter - buffer; |
| /*** check **/ |
| if (data_start > 512) { |
| data_size -= data_start; |
| memmove(buffer, iter, data_size); |
| *(buffer + data_size) = '\0'; |
| iter = buffer; |
| data_start = 0; |
| } |
| pter = strstr(iter + strlen(start), end); |
| while (pter == NULL) { |
| if (pter == NULL && *remained < strlen(end)) { |
| pr_err("wrong config file"); |
| return NULL; |
| } |
| buffer = |
| (char *)realloc_mem(buffer, data_size + BUFFER_SIZE + 1, |
| &buffer_len); |
| if (buffer == NULL) { |
| pr_err("realloc failed\n"); |
| return NULL; |
| } |
| if (*remained < BUFFER_SIZE) { |
| camera_read_config(*offset, *remained, |
| buffer + data_size); /* check bounds */ |
| add = *remained; |
| *offset += *remained; |
| *remained = 0; |
| } else { |
| camera_read_config(*offset, BUFFER_SIZE, |
| buffer + data_size); /* check bounds */ |
| add = BUFFER_SIZE; |
| *remained -= BUFFER_SIZE; |
| *offset += BUFFER_SIZE; |
| } |
| *(buffer + data_size + add) = '\0'; |
| pter = strstr(buffer + data_size - strlen(end), end); |
| data_size += add; |
| } |
| /* if realloc ,iter is invalid,so recalculate */ |
| iter = buffer + data_start; |
| data_start = pter - buffer; |
| |
| buf_para->buffer = buffer; |
| buf_para->data_start = data_start; |
| buf_para->data_size = data_size; |
| buf_para->buffer_len = buffer_len; |
| return iter; |
| } |
| |
| char *search_key(struct buffer_para_s *buf_para, int *offset, int *remained) |
| { |
| char *iter, *buffer; |
| int data_start, data_size, buffer_len; |
| int add = 0; |
| |
| buffer = buf_para->buffer; |
| data_start = buf_para->data_start; |
| data_size = buf_para->data_size; |
| buffer_len = buf_para->buffer_len; |
| |
| iter = strstr(buffer + data_start, "["); |
| while (iter == NULL) { |
| if (iter == NULL && *remained < 20) { |
| pr_err("file end\n"); |
| return NULL; |
| } |
| memset(buffer, 0, buffer_len); |
| if (*remained < BUFFER_SIZE) { |
| camera_read_config(*offset, |
| *remained, buffer); /* check bounds */ |
| *offset += *remained; |
| data_size = *remained; |
| *remained = 0; |
| data_start = 0; |
| } else { |
| camera_read_config(*offset, |
| BUFFER_SIZE, buffer); /* check bounds */ |
| *offset += BUFFER_SIZE; |
| data_size = BUFFER_SIZE; |
| *remained -= BUFFER_SIZE; |
| data_start = 0; |
| } |
| iter = strstr(buffer, "["); |
| } |
| data_start = iter - buffer; |
| /*** check **/ |
| if (data_start + 20 > data_size) { /* ensure we have an complete key */ |
| buffer = |
| (char *)realloc_mem(buffer, data_size + BUFFER_SIZE + 1, |
| &buffer_len); |
| if (buffer == NULL) { |
| pr_err("realloc failed\n"); |
| return NULL; |
| } |
| if (*remained < BUFFER_SIZE) { |
| camera_read_config(*offset, *remained, |
| buffer + data_size); /* check bounds */ |
| add = *remained; |
| *offset += *remained; |
| *remained = 0; |
| |
| } else { |
| camera_read_config(*offset, BUFFER_SIZE, |
| buffer + data_size); /* check bounds */ |
| add = BUFFER_SIZE; |
| *remained -= BUFFER_SIZE; |
| *offset += BUFFER_SIZE; |
| } |
| *(buffer + data_size + add) = '\0'; |
| data_size += add; |
| } |
| /* if realloc ,iter is invalid,so recalculate */ |
| iter = buffer + data_start; |
| |
| buf_para->buffer = buffer; |
| buf_para->data_start = data_start; |
| buf_para->data_size = data_size; |
| buf_para->buffer_len = buffer_len; |
| return iter; |
| } |
| |
| int parse_head(char *buffer, int *sum) |
| { |
| int ret; |
| char *iter; |
| |
| iter = strstr(buffer, "sum"); |
| if (iter == NULL) |
| return -WRONG_FORMAT; |
| iter += 4; /* point to value */ |
| ret = kstrtoint(iter, 10, sum); |
| return 0; |
| } |
| |
| int parse_body_head(char *buffer, int *no, int check, char *name) |
| { |
| int ret; |
| char *iter; |
| |
| iter = strstr(buffer, "no"); |
| iter += 3; |
| ret = kstrtoint(iter, 10, no); |
| iter = strstr(iter, "name"); |
| iter += 5; |
| ret = kstrtos8(name, 16, iter); |
| return 0; |
| } |
| int parse_aet_element_info(char **iter, struct sensor_aet_info_s *info) |
| { |
| int ret; |
| |
| *iter = strstr(*iter, "export"); |
| *iter += 7; |
| ret = kstrtouint(*iter, 16, &(info->fmt_main_fr)); |
| *iter = strstr(*iter, ","); |
| *iter += 1; |
| ret = kstrtouint(*iter, 16, &(info->fmt_capture)); |
| *iter = strstr(*iter, ","); |
| *iter += 1; |
| ret = kstrtouint(*iter, 16, &(info->fmt_hactive)); |
| *iter = strstr(*iter, ","); |
| *iter += 1; |
| ret = kstrtouint(*iter, 16, &(info->fmt_vactive)); |
| *iter = strstr(*iter, ","); |
| *iter += 1; |
| ret = kstrtouint(*iter, 16, &(info->fmt_rated_fr)); |
| *iter = strstr(*iter, ","); |
| *iter += 1; |
| ret = kstrtouint(*iter, 16, &(info->fmt_min_fr)); |
| *iter = strstr(*iter, ","); |
| *iter += 1; |
| ret = kstrtouint(*iter, 16, &(info->tbl_max_step)); |
| *iter = strstr(*iter, ","); |
| *iter += 1; |
| ret = kstrtouint(*iter, 16, &(info->tbl_rated_step)); |
| *iter = strstr(*iter, ","); |
| *iter += 1; |
| ret = kstrtouint(*iter, 16, &(info->tbl_max_gain)); |
| *iter = strstr(*iter, ","); |
| *iter += 1; |
| ret = kstrtouint(*iter, 16, &(info->tbl_min_gain)); |
| *iter = strstr(*iter, ","); |
| *iter += 1; |
| ret = kstrtouint(*iter, |
| 16, &(info->format_transfer_parameter)); |
| *iter = strstr(*iter, ","); |
| *iter += 1; |
| return 0; |
| |
| } |
| |
| int parse_aet_element_tbl(char **iter, struct sensor_aet_s *tbl) |
| { |
| int ret; |
| |
| ret = kstrtouint(*iter, 16, &(tbl->exp)); |
| *iter = strstr(*iter, ","); |
| *iter += 1; |
| ret = kstrtouint(*iter, 16, &(tbl->ag)); |
| *iter = strstr(*iter, ","); |
| *iter += 1; |
| ret = kstrtouint(*iter, 16, &(tbl->vts)); |
| *iter = strstr(*iter, ","); |
| *iter += 1; |
| ret = kstrtouint(*iter, 16, &(tbl->gain)); |
| *iter = strstr(*iter, ","); |
| *iter += 1; |
| ret = kstrtouint(*iter, 16, &(tbl->fr)); |
| *iter = strstr(*iter, ","); |
| *iter += 1; |
| return 0; |
| } |
| |
| int parse_last_aet_element_tbl(char **iter, struct sensor_aet_s *tbl) |
| { |
| int ret; |
| |
| ret = kstrtouint(*iter, 16, &(tbl->exp)); |
| *iter = strstr(*iter, ","); |
| *iter += 1; |
| ret = kstrtouint(*iter, 16, &(tbl->ag)); |
| *iter = strstr(*iter, ","); |
| *iter += 1; |
| ret = kstrtouint(*iter, 16, &(tbl->vts)); |
| *iter = strstr(*iter, ","); |
| *iter += 1; |
| ret = kstrtouint(*iter, 16, &(tbl->gain)); |
| *iter = strstr(*iter, ","); |
| *iter += 1; |
| ret = kstrtouint(*iter, 16, &(tbl->fr)); |
| return 0; |
| } |
| |
| int parse_effect(struct configure_s *cf, struct buffer_para_s *buf_para, |
| int *remained, int *offset) |
| { |
| int ret1, ret2, ret3, sum, check, i; |
| char *iter; |
| |
| iter = search_string(buf_para, offset, remained, "effect_start]", |
| "[effect]"); |
| if (iter == NULL) |
| return -WRONG_FORMAT; |
| /***parser head***/ |
| ret1 = parse_head(iter, &sum); |
| if (ret1 != 0) |
| return -HEAD_FAILED; |
| cf->eff.sum = sum; |
| /**parser body***/ |
| check = 0; |
| while (check < sum) { |
| iter = search_string(buf_para, offset, |
| remained, "[effect]", "[effect"); |
| if (iter == NULL) |
| return -WRONG_FORMAT; |
| ret2 = parse_body_head(iter, &(cf->eff.eff[check].num), check, |
| cf->eff.eff[check].name); |
| if (ret2 != 0) |
| return -BODY_HEAD_FAILED; |
| iter = strstr(iter, "export"); |
| iter += 7; |
| i = 0; |
| while (i < EFFECT_MAX && iter != NULL) { |
| ret3 = kstrtouint(iter, |
| 16, &(cf->eff.eff[check].export[i])); |
| i++; |
| iter = strstr(iter, ","); |
| if (iter == NULL) |
| break; |
| iter += 1; |
| } |
| if (i != EFFECT_MAX) |
| return -CHECK_LEN_FAILED; |
| check++; |
| } |
| if (check != sum) |
| return -CHECK_FAILED; |
| return 0; |
| } |
| |
| int parse_aet(struct configure_s *cf, struct buffer_para_s *buf_para, |
| int *remained, int *offset) |
| { |
| int sum, ret, check, i; |
| char *iter; |
| |
| iter = search_string(buf_para, offset, remained, "aet_start]", "[aet]"); |
| if (iter == NULL) |
| return -WRONG_FORMAT; |
| /***parser head***/ |
| ret = parse_head(iter, &sum); |
| if (sum <= 0) |
| return -HEAD_FAILED; |
| cf->aet.sum = sum; |
| /**parser body***/ |
| for (i = 0; i < sum; i++) { |
| cf->aet.aet[i].info = |
| kmalloc(sizeof(struct sensor_aet_info_s), 0); |
| if ((cf->aet.aet[i].info) == NULL) { |
| while (i-- > 0) |
| kfree(cf->aet.aet[i].info); |
| return -NO_MEM; |
| } |
| } /* alloc head */ |
| check = 0; |
| while (check < sum) { |
| iter = search_string(buf_para, offset, |
| remained, "[aet]", "[aet"); |
| if (iter == NULL) { |
| pr_err("aet wrong config format\n"); |
| ret = -WRONG_FORMAT; |
| goto clean; |
| } |
| ret = parse_body_head(iter, &(cf->aet.aet[check].num), check, |
| cf->aet.aet[check].name); |
| if (ret != 0) { |
| ret = -HEAD_FAILED; |
| goto clean; |
| } |
| ret = parse_aet_element_info(&iter, cf->aet.aet[check].info); |
| if (ret != 0) { |
| ret = -BODY_ELEMENT_FAILED; |
| goto clean; |
| } |
| |
| cf->aet.aet[check].aet_table = |
| vmalloc(sizeof(struct sensor_aet_s) * |
| (cf->aet.aet[check].info->tbl_max_step + 1)); |
| if ((cf->aet.aet[check].aet_table) == NULL) { |
| for (i = 0; i < check; i++) |
| vfree(cf->aet.aet[i].aet_table); |
| ret = -NO_MEM; |
| goto clean; |
| } |
| for (i = 0; i <= cf->aet.aet[check].info->tbl_max_step; i++) { |
| if (i == cf->aet.aet[check].info->tbl_max_step) { |
| ret = parse_last_aet_element_tbl( |
| &iter, &(cf->aet.aet[check].aet_table[i])); |
| } else |
| ret = parse_aet_element_tbl(&iter, |
| &(cf->aet.aet[check].aet_table[i])); |
| if (ret != 0) { |
| ret = -BODY_ELEMENT_FAILED; |
| goto clean_table; |
| } |
| } |
| check++; |
| } |
| return 0; |
| |
| clean_table: |
| for (i = 0; i <= check; i++) |
| vfree(cf->aet.aet[i].aet_table); |
| clean: |
| for (i = 0; i < sum; i++) |
| kfree(cf->aet.aet[i].info); |
| return ret; |
| } |
| |
| int parse_hw(struct configure_s *cf, struct buffer_para_s *buf_para, |
| int *remained, int *offset) |
| { |
| int ret1, ret2, ret3, sum, check, i; |
| char *iter = NULL; |
| char *eter = NULL; |
| |
| iter = search_string(buf_para, offset, remained, "hw_start]", "[hw]"); |
| if (iter == NULL) |
| return -WRONG_FORMAT; |
| /***parser head***/ |
| ret1 = parse_head(iter, &sum); |
| if (ret1 != 0) |
| return -HEAD_FAILED; |
| cf->hw.sum = sum; |
| /**parser body***/ |
| check = 0; |
| while (check < sum) { |
| iter = search_string(buf_para, offset, remained, "[hw]", "[hw"); |
| if (iter == NULL) |
| return -WRONG_FORMAT; |
| ret2 = parse_body_head(iter, &(cf->hw.hw[check].num), check, |
| cf->hw.hw[check].name); |
| if (ret2 != 0) |
| return -BODY_HEAD_FAILED; |
| iter = strstr(iter, "export"); |
| iter += 7; |
| eter = strstr(iter, ";"); |
| if (eter == NULL) |
| return -WRONG_FORMAT; |
| i = 0; |
| while (iter < eter) { |
| ret3 = kstrtouint(iter, |
| 16, &(cf->hw.hw[check].export[i])); |
| i++; |
| iter = strstr(iter, ","); |
| if (iter == NULL) |
| break; |
| iter += 1; |
| } |
| check++; |
| } |
| if (check != sum) |
| return -CHECK_FAILED; |
| return 0; |
| } |
| |
| int parse_wb(struct configure_s *cf, struct buffer_para_s *buf_para, |
| int *remained, int *offset) |
| { |
| int ret1, ret2, ret3, sum, check, i; |
| char *iter = NULL; |
| char *eter = NULL; |
| |
| iter = search_string(buf_para, offset, remained, "wb_start]", "[wb]"); |
| if (iter == NULL) |
| return -WRONG_FORMAT; |
| /***parser head***/ |
| ret1 = parse_head(iter, &sum); |
| if (ret1 != 0) |
| return -HEAD_FAILED; |
| cf->wb.sum = sum; |
| /**parser body***/ |
| check = 0; |
| while (check < sum) { |
| iter = search_string(buf_para, offset, remained, "[wb]", "[wb"); |
| if (iter == NULL) |
| return -WRONG_FORMAT; |
| ret2 = parse_body_head(iter, &(cf->wb.wb[check].num), check, |
| cf->wb.wb[check].name); |
| if (ret2 != 0) |
| return -BODY_HEAD_FAILED; |
| iter = strstr(iter, "export"); |
| iter += 7; |
| eter = strstr(iter, ";"); |
| if (eter == NULL) |
| return -WRONG_FORMAT; |
| i = 0; |
| while (iter < eter) { |
| ret3 = kstrtouint(iter, |
| 16, &(cf->wb.wb[check].export[i])); |
| i++; |
| iter = strstr(iter, ","); |
| if (iter == NULL) |
| break; |
| iter += 1; |
| |
| } |
| if (i != WB_MAX) |
| return -CHECK_LEN_FAILED; |
| check++; |
| } |
| if (check != sum) |
| return -CHECK_FAILED; |
| return 0; |
| |
| } |
| |
| int parse_capture(struct configure_s *cf, struct buffer_para_s *buf_para, |
| int *remained, int *offset) |
| { |
| int ret1, ret2, ret3, sum, check, i; |
| char *iter = NULL; |
| char *eter = NULL; |
| |
| iter = search_string(buf_para, offset, remained, "capture_start]", |
| "[capture]"); |
| if (iter == NULL) |
| return -WRONG_FORMAT; |
| /***parser head***/ |
| ret1 = parse_head(iter, &sum); |
| if (ret1 != 0) |
| return -HEAD_FAILED; |
| cf->capture.sum = sum; |
| /* pr_err("capture sum:%d\n",sum); */ |
| /**parser body***/ |
| check = 0; |
| while (check < sum) { |
| iter = search_string(buf_para, offset, remained, "[capture]", |
| "[capture"); |
| if (iter == NULL) { |
| pr_err("search wrong\n"); |
| return -WRONG_FORMAT; |
| } |
| ret2 = parse_body_head(iter, |
| &(cf->capture.capture[check].num), check, |
| cf->capture.capture[check].name); |
| if (ret2 != 0) |
| return -BODY_HEAD_FAILED; |
| /* pr_err("name:%s\n",cf->capture.capture[check].name); */ |
| iter = strstr(iter, "export"); |
| if (iter == NULL) { |
| pr_err("iter is NULL\n"); |
| return -WRONG_FORMAT; |
| } |
| iter += 7; |
| eter = strstr(iter, ";"); |
| if (eter == NULL) |
| return -WRONG_FORMAT; |
| i = 0; |
| while (iter < eter) { |
| ret3 = kstrtouint(iter, |
| 16, &(cf->capture.capture[check].export[i])); |
| i++; |
| iter = strstr(iter, ","); |
| if (iter == NULL) |
| break; |
| iter += 1; |
| } |
| if (i != CAPTURE_MAX) |
| return -CHECK_LEN_FAILED; |
| check++; |
| } |
| if (check != sum) |
| return -CHECK_FAILED; |
| return 0; |
| |
| } |
| |
| int parse_wave(struct configure_s *cf, struct buffer_para_s *buf_para, |
| int *remained, int *offset) |
| { |
| int i, ret; |
| char *iter = NULL; |
| char *eter = NULL; |
| |
| iter = search_string(buf_para, offset, remained, "wave_start]", |
| "[wave_end]"); |
| if (iter == NULL) |
| return -WRONG_FORMAT; |
| iter = strstr(iter, "export"); |
| iter += 7; |
| eter = strstr(iter, ";"); |
| if (eter == NULL) |
| return -WRONG_FORMAT; |
| i = 0; |
| while (iter < eter) { |
| ret = kstrtouint(iter, 16, &(cf->wave.export[i])); |
| /* pr_err("wave:%x\n",cf->wave.export[i]); */ |
| iter = strstr(iter, ","); |
| i++; |
| if (iter == NULL) |
| break; |
| iter += 1; |
| } |
| if (i != WAVE_MAX) |
| return -CHECK_LEN_FAILED; |
| return 0; |
| } |
| |
| int parse_scene(struct configure_s *cf, struct buffer_para_s *buf_para, |
| int *remained, int *offset) |
| { |
| int sum, ret1, ret2, ret3, check, i; |
| char *iter = NULL; |
| char *eter = NULL; |
| |
| iter = search_string(buf_para, offset, remained, "scenes_start]", |
| "[scenes]"); |
| if (iter == NULL) |
| return -WRONG_FORMAT; |
| /***parser head***/ |
| ret1 = parse_head(iter, &sum); |
| if (sum <= 0) |
| return -HEAD_FAILED; |
| cf->scene.sum = sum; |
| |
| /**parser body***/ |
| check = 0; |
| while (check < sum) { |
| iter = search_string(buf_para, offset, |
| remained, "[scenes]", "[scenes"); |
| if (iter == NULL) { |
| pr_err("scene wrong config format\n"); |
| return -WRONG_FORMAT; |
| } |
| ret2 = parse_body_head(iter, &((cf->scene.scene[check]).num), |
| check, (cf->scene.scene[check].name)); |
| if (ret2 != 0) |
| return -BODY_HEAD_FAILED; |
| iter = strstr(iter, "export"); |
| iter += 7; |
| eter = strstr(iter, ";"); |
| if (eter == NULL) |
| return -WRONG_FORMAT; |
| i = 0; |
| while (iter < eter) { |
| ret3 = kstrtouint(iter, |
| 16, &(cf->scene.scene[check].export[i])); |
| i++; |
| iter = strstr(iter, ","); |
| if (iter == NULL) |
| break; |
| iter += 1; |
| } |
| if (i != SCENE_MAX) |
| return -CHECK_LEN_FAILED; |
| check++; |
| } |
| if (check != sum) |
| return -CHECK_FAILED; |
| return 0; |
| } |
| |
| int parse_lens(struct configure_s *cf, struct buffer_para_s *buf_para, |
| int *remained, int *offset) |
| { |
| int sum, ret1, ret2, ret3, check, i; |
| char *iter = NULL; |
| char *eter = NULL; |
| |
| iter = search_string(buf_para, offset, |
| remained, "lens_start]", "[lens]"); |
| if (iter == NULL) |
| return -WRONG_FORMAT; |
| /***parser head***/ |
| ret1 = parse_head(iter, &sum); |
| if (sum <= 0) |
| return -HEAD_FAILED; |
| cf->lens.sum = sum; |
| |
| /**parser body***/ |
| check = 0; |
| while (check < sum) { |
| iter = search_string(buf_para, offset, |
| remained, "[lens]", "[lens"); |
| if (iter == NULL) { |
| pr_err("lens wrong config format\n"); |
| return -WRONG_FORMAT; |
| } |
| ret2 = parse_body_head(iter, |
| &((cf->lens.lens[check]).num), |
| check, |
| (cf->lens.lens[check].name)); |
| if (ret2 != 0) |
| return -BODY_HEAD_FAILED; |
| iter = strstr(iter, "export"); |
| iter += 7; |
| eter = strstr(iter, ";"); |
| if (eter == NULL) |
| return -WRONG_FORMAT; |
| i = 0; |
| while (iter < eter) { |
| ret3 = kstrtouint(iter, |
| 16, &(cf->lens.lens[check].export[i])); |
| i++; |
| iter = strstr(iter, ","); |
| if (iter == NULL) |
| break; |
| iter += 1; |
| } |
| if (i != LENS_MAX) |
| return -CHECK_LEN_FAILED; |
| check++; |
| } |
| if (check != sum) |
| return -CHECK_FAILED; |
| return 0; |
| } |
| |
| int parse_gamma(struct configure_s *cf, struct buffer_para_s *buf_para, |
| int *remained, int *offset) |
| { |
| int i, ret; |
| char *iter; |
| |
| iter = search_string(buf_para, offset, remained, "gamma_start]", |
| "[gamma_end]"); |
| if (iter == NULL) |
| return -WRONG_FORMAT; |
| /***parser head***/ |
| iter = strstr(iter, "export"); |
| iter += 7; |
| for (i = 0; i < GAMMA_MAX && iter != NULL;) { |
| ret = kstrtouint(iter, 16, &(cf->gamma.gamma_r[i])); |
| i++; |
| iter = strstr(iter, ","); |
| if (iter == NULL) |
| break; |
| iter += 1; |
| } |
| if (i != GAMMA_MAX) |
| return -CHECK_LEN_FAILED; |
| for (i = 0; i < GAMMA_MAX && iter != NULL;) { |
| ret = kstrtouint(iter, 16, &(cf->gamma.gamma_g[i])); |
| i++; |
| iter = strstr(iter, ","); |
| if (iter == NULL) |
| break; |
| iter += 1; |
| } |
| if (i != GAMMA_MAX) |
| return -CHECK_LEN_FAILED; |
| for (i = 0; i < GAMMA_MAX && iter != NULL;) { |
| ret = kstrtouint(iter, |
| 16, &(cf->gamma.gamma_b[i])); |
| i++; |
| iter = strstr(iter, ","); |
| if (iter == NULL) |
| break; |
| iter += 1; |
| } |
| if (i != GAMMA_MAX) |
| return -CHECK_LEN_FAILED; |
| return 0; |
| } |
| |
| int parse_wb_sensor(struct configure_s *cf, struct buffer_para_s *buf_para, |
| int *remained, int *offset) |
| { |
| int i, ret; |
| char *iter; |
| |
| iter = search_string(buf_para, offset, remained, "mwb_sensor_start]", |
| "[mwb_sensor_end]"); |
| if (iter == NULL) |
| return -WRONG_FORMAT; |
| /***parser head***/ |
| iter = strstr(iter, "export"); |
| iter += 7; |
| i = 0; |
| while (i < WB_SENSOR_MAX && iter != NULL) { |
| ret = kstrtouint(iter, 16, &(cf->wb_sensor_data.export[i])); |
| /* pr_err("wb sensor:%x\n",cf->wb_sensor_data.export[i]); */ |
| i++; |
| iter = strstr(iter, ","); |
| if (iter == NULL) |
| break; |
| iter += 1; |
| } |
| if (i != WB_SENSOR_MAX) |
| return -CHECK_LEN_FAILED; |
| return 0; |
| } |
| |
| int parse_version(struct configure_s *cf, struct buffer_para_s *buf_para, |
| int *remained, int *offset) |
| { |
| char *iter, *end; |
| int len = 0; |
| |
| iter = search_string(buf_para, offset, remained, "version_start]", |
| "[version_end]"); |
| if (iter == NULL) |
| return -WRONG_FORMAT; |
| iter = strstr(iter, "Date"); |
| iter += 5; |
| end = strstr(iter, "Module"); |
| if (end == NULL) |
| return -WRONG_FORMAT; |
| len = end - iter; |
| memcpy(cf->version.date, iter, len); |
| cf->version.date[len] = '\0'; |
| |
| iter = end + 7; |
| end = strstr(iter, "Version"); |
| if (end == NULL) |
| return -WRONG_FORMAT; |
| len = end - iter; |
| memcpy(cf->version.module, iter, len); |
| cf->version.module[len] = '\0'; |
| |
| iter = end + 8; |
| end = strstr(iter, "[version"); |
| if (end == NULL) |
| return -WRONG_FORMAT; |
| len = end - iter; |
| memcpy(cf->version.version, iter, len); |
| cf->version.version[len] = '\0'; |
| pr_info("version:%s", cf->version.version); |
| return 0; |
| } |
| |
| int parse_cm(struct configure_s *cf, struct buffer_para_s *buf_para, |
| int *remained, int *offset) |
| { |
| int i; |
| int ret; |
| char *iter; |
| |
| iter = search_string(buf_para, offset, |
| remained, "cm_start]", "[cm_end]"); |
| if (iter == NULL) |
| return -WRONG_FORMAT; |
| /***parser body***/ |
| iter = strstr(iter, "export"); |
| iter += 7; |
| i = 0; |
| while (i < CM_MAX && iter != NULL) { |
| ret = kstrtouint(iter, 16, &(cf->cm.export[i])); |
| /* pr_err("cm:%x\n",cf->cm.export[i]); */ |
| i++; |
| iter = strstr(iter, ","); |
| if (iter == NULL) |
| break; |
| iter += 1; |
| } |
| if (i != CM_MAX) |
| return -CHECK_LEN_FAILED; |
| return 0; |
| } |
| |
| int parse_nr(struct configure_s *cf, struct buffer_para_s *buf_para, |
| int *remained, int *offset) |
| { |
| int ret1, ret2, ret3, sum, check, i; |
| char *iter; |
| |
| iter = search_string(buf_para, offset, remained, "nr_start]", "[nr]"); |
| if (iter == NULL) |
| return -WRONG_FORMAT; |
| /***parser head***/ |
| ret1 = parse_head(iter, &sum); |
| if (ret1 != 0) |
| return -HEAD_FAILED; |
| cf->nr.sum = sum; |
| /* pr_err("nr sum:%d\n",sum); */ |
| /**parser body***/ |
| check = 0; |
| while (check < sum) { |
| iter = search_string(buf_para, offset, remained, "[nr]", "[nr"); |
| if (iter == NULL) { |
| pr_err("search wrong\n"); |
| return -WRONG_FORMAT; |
| } |
| ret2 = parse_body_head(iter, &(cf->nr.nr[check].num), check, |
| cf->nr.nr[check].name); |
| if (ret2 != 0) |
| return -BODY_HEAD_FAILED; |
| iter = strstr(iter, "export"); |
| iter += 7; |
| i = 0; |
| while (i < NR_MAX && iter != NULL) { |
| ret3 = kstrtouint(iter, 16, |
| &(cf->nr.nr[check].export[i])); |
| /* pr_err("nr:%x\n",cf->nr.nr[check].export[i]); */ |
| i++; |
| iter = strstr(iter, ","); |
| if (iter == NULL) |
| break; |
| iter += 1; |
| } |
| if (i != NR_MAX) |
| return -CHECK_LEN_FAILED; |
| check++; |
| } |
| if (check != sum) |
| return -CHECK_FAILED; |
| return 0; |
| } |
| |
| int parse_peaking(struct configure_s *cf, struct buffer_para_s *buf_para, |
| int *remained, int *offset) |
| { |
| int ret1, ret2, ret3, sum, check, i; |
| char *iter; |
| |
| iter = search_string(buf_para, offset, remained, "peaking_start]", |
| "[peaking]"); |
| if (iter == NULL) |
| return -WRONG_FORMAT; |
| /***parser head***/ |
| ret1 = parse_head(iter, &sum); |
| if (ret1 != 0) |
| return -HEAD_FAILED; |
| cf->peaking.sum = sum; |
| /* pr_err("peaking sum:%d\n",sum); */ |
| /**parser body***/ |
| check = 0; |
| while (check < sum) { |
| iter = search_string(buf_para, offset, remained, "[peaking]", |
| "[peaking"); |
| if (iter == NULL) { |
| pr_err("search wrong\n"); |
| return -WRONG_FORMAT; |
| } |
| ret2 = parse_body_head(iter, |
| &(cf->peaking.peaking[check].num), check, |
| cf->peaking.peaking[check].name); |
| if (ret2 != 0) |
| return -BODY_HEAD_FAILED; |
| iter = strstr(iter, "export"); |
| iter += 7; |
| i = 0; |
| while (i < PEAKING_MAX && iter != NULL) { |
| ret3 = kstrtouint(iter, |
| 16, &(cf->peaking.peaking[check].export[i])); |
| i++; |
| iter = strstr(iter, ","); |
| if (iter == NULL) |
| break; |
| iter += 1; |
| } |
| if (i != PEAKING_MAX) |
| return -CHECK_LEN_FAILED; |
| check++; |
| } |
| if (check != sum) |
| return -CHECK_FAILED; |
| return 0; |
| } |
| |
| int parse_config(const char *path, struct configure_s *cf) |
| { |
| char *buffer, *iter; |
| int file_size; |
| int remained_size; |
| int read_offset = 0; |
| int ret = 0; |
| struct buffer_para_s buf_para; |
| |
| buffer = vmalloc(BUFFER_SIZE + 1);/*(char *)*/ |
| if (buffer == NULL) |
| return -NO_MEM; |
| |
| buf_para.buffer = buffer; |
| |
| memset(cf, 0, sizeof(struct configure_s)); |
| file_size = camera_open_config(path); |
| if (file_size < 0) { |
| pr_err("open failed :%d\n", file_size); |
| ret = -READ_ERROR; |
| goto clean_mem; |
| } else if (file_size == 0) { |
| pr_err("file is null\n"); |
| ret = -READ_ERROR; |
| goto clean_all; |
| } else { |
| if (file_size < BUFFER_SIZE) { |
| camera_read_config(0, file_size, buffer); |
| remained_size = 0; |
| read_offset = file_size; |
| *(buffer + file_size) = '\0'; |
| } else { |
| camera_read_config(0, BUFFER_SIZE, buffer); |
| remained_size = file_size - BUFFER_SIZE; |
| read_offset = BUFFER_SIZE; |
| *(buffer + BUFFER_SIZE) = '\0'; |
| } |
| } |
| buf_para.data_start = 0; |
| buf_para.data_size = read_offset; |
| buf_para.buffer_len = BUFFER_SIZE; |
| |
| while (read_offset <= file_size) { |
| iter = search_key(&buf_para, &read_offset, &remained_size); |
| if (iter == NULL) { |
| pr_info("finish parse file\n"); |
| return 0; |
| } |
| iter += 1; |
| buf_para.data_start += 1; |
| switch (*iter) { |
| case 'a': |
| if (memcmp(iter, aet_key, strlen(aet_key)) == 0) { |
| cf->aet_valid = 1; |
| ret = parse_aet(cf, &buf_para, |
| &remained_size, &read_offset); |
| if (ret != 0) { |
| cf->aet_valid = 0; |
| pr_err("aet invalid :%d\n", ret); |
| goto clean_all; |
| } |
| } else |
| buf_para.data_start += strlen(aet_key); |
| break; |
| case 'h': |
| if (memcmp(iter, hw_key, strlen(hw_key)) == 0) { |
| cf->hw_valid = 1; |
| ret = parse_hw(cf, &buf_para, |
| &remained_size, &read_offset); |
| if (ret != 0) { |
| cf->hw_valid = 0; |
| pr_err("hw invalid :%d\n", ret); |
| goto clean_all; |
| } |
| } else |
| buf_para.data_start += strlen(hw_key); |
| break; |
| case 'e': |
| if (memcmp(iter, effect_key, strlen(effect_key)) == 0) { |
| cf->effect_valid = 1; |
| ret = parse_effect(cf, &buf_para, |
| &remained_size, &read_offset); |
| if (ret != 0) { |
| cf->effect_valid = 0; |
| pr_err("effect invalid :%d\n", ret); |
| goto clean_all; |
| } |
| } else |
| buf_para.data_start += strlen(effect_key); |
| break; |
| case 'w': |
| if (*(iter + 1) == 'b') { |
| if (memcmp(iter, wb_key, strlen(wb_key)) == 0) { |
| cf->wb_valid = 1; |
| ret = parse_wb(cf, &buf_para, |
| &remained_size, &read_offset); |
| if (ret != 0) { |
| cf->wb_valid = 0; |
| pr_err("wb invalid :%d\n", ret); |
| goto clean_all; |
| } |
| } else |
| buf_para.data_start += strlen(wb_key); |
| } else if (*(iter + 1) == 'a') { |
| if (memcmp(iter, wave_key, |
| strlen(wave_key)) == 0) { |
| cf->wave_valid = 1; |
| ret = parse_wave(cf, &buf_para, |
| &remained_size, &read_offset); |
| if (ret != 0) { |
| cf->wave_valid = 0; |
| pr_err("wave invalid :%d\n", |
| ret); |
| goto clean_all; |
| } |
| } else |
| buf_para.data_start += strlen(wave_key); |
| } else |
| buf_para.data_start += 1; |
| |
| break; |
| case 's': |
| if (memcmp(iter, scenes_key, |
| strlen(scenes_key)) == 0) { |
| cf->scene_valid = 1; |
| ret = parse_scene(cf, &buf_para, |
| &remained_size, &read_offset); |
| if (ret != 0) { |
| cf->scene_valid = 0; |
| pr_err("scene invalid :%d\n", ret); |
| goto clean_all; |
| } |
| } else |
| buf_para.data_start += strlen(scenes_key); |
| break; |
| case 'c': |
| if (*(iter + 1) == 'a') { |
| if (memcmp(iter, capture_key, |
| strlen(capture_key)) == 0) { |
| cf->capture_valid = 1; |
| ret = parse_capture(cf, &buf_para, |
| &remained_size, &read_offset); |
| if (ret != 0) { |
| cf->capture_valid = 0; |
| pr_err("capture invalid :%d\n", |
| ret); |
| goto clean_all; |
| } |
| } else |
| buf_para.data_start += |
| strlen(capture_key); |
| } else if (*(iter + 1) == 'm') { |
| if (memcmp(iter, cm_key, strlen(cm_key)) == 0) { |
| cf->cm_valid = 1; |
| ret = parse_cm(cf, &buf_para, |
| &remained_size, &read_offset); |
| if (ret != 0) { |
| cf->cm_valid = 0; |
| pr_err("cm invalid :%d\n", ret); |
| goto clean_all; |
| } |
| } else |
| buf_para.data_start += strlen(cm_key); |
| } else |
| buf_para.data_start += 1; |
| break; |
| case 'l': |
| if (memcmp(iter, lens_key, strlen(lens_key)) == 0) { |
| cf->lens_valid = 1; |
| ret = parse_lens(cf, &buf_para, |
| &remained_size, &read_offset); |
| if (ret != 0) { |
| cf->lens_valid = 0; |
| pr_err("lens invalid :%d\n", ret); |
| goto clean_all; |
| } |
| } else |
| buf_para.data_start += strlen(lens_key); |
| break; |
| case 'g': |
| if (memcmp(iter, gamma_key, strlen(gamma_key)) == 0) { |
| cf->gamma_valid = 1; |
| ret = parse_gamma(cf, &buf_para, |
| &remained_size, &read_offset); |
| if (ret != 0) { |
| cf->gamma_valid = 0; |
| pr_err("gamma invalid :%d\n", ret); |
| goto clean_all; |
| } |
| } else |
| buf_para.data_start += strlen(gamma_key); |
| break; |
| case 'm': |
| if (memcmp(iter, wb_sensor_key, |
| strlen(wb_sensor_key)) == 0) { |
| cf->wb_sensor_data_valid = 1; |
| ret = parse_wb_sensor(cf, &buf_para, |
| &remained_size, &read_offset); |
| if (ret != 0) { |
| cf->wb_sensor_data_valid = 0; |
| pr_err("wb sensor data invalid :%d\n", |
| ret); |
| goto clean_all; |
| } |
| } else |
| buf_para.data_start += strlen(wb_sensor_key); |
| break; |
| case 'v': |
| if (memcmp(iter, version_key, |
| strlen(version_key)) == 0) { |
| cf->version_info_valid = 1; |
| ret = parse_version(cf, &buf_para, |
| &remained_size, &read_offset); |
| if (ret != 0) { |
| cf->version_info_valid = 0; |
| pr_err("version info invalid :%d\n", |
| ret); |
| goto clean_all; |
| } |
| } else |
| buf_para.data_start += strlen(version_key); |
| break; |
| case 'n': |
| if (memcmp(iter, nr_key, strlen(nr_key)) == 0) { |
| cf->nr_valid = 1; |
| ret = parse_nr(cf, &buf_para, |
| &remained_size, &read_offset); |
| if (ret != 0) { |
| cf->nr_valid = 0; |
| pr_err("nr invalid :%d\n", ret); |
| goto clean_all; |
| } |
| } else |
| buf_para.data_start += strlen(nr_key); |
| break; |
| case 'p': |
| if (memcmp(iter, peaking_key, |
| strlen(peaking_key)) == 0) { |
| cf->peaking_valid = 1; |
| ret = parse_peaking(cf, &buf_para, |
| &remained_size, &read_offset); |
| if (ret != 0) { |
| cf->peaking_valid = 0; |
| pr_err("peaking invalid :%d\n", ret); |
| goto clean_all; |
| } |
| } else |
| buf_para.data_start += strlen(peaking_key); |
| break; |
| default: |
| buf_para.data_start += 1; |
| break; |
| } |
| } |
| ret = 0; |
| |
| clean_all: |
| camera_close_config(); |
| clean_mem: |
| vfree(buf_para.buffer); |
| return ret; |
| } |
| |
| struct hw_para_s { |
| char name[20]; |
| int size; |
| int *array; |
| }; |
| |
| struct hw_para_s hw_para[] = { |
| {"TOP", XML_TOP, NULL}, {"TP", XML_TP, NULL}, {"CG", XML_CG, NULL}, { |
| "LENS_SHADING", XML_LS, NULL |
| }, {"DFT", XML_DP, NULL}, { |
| "DMS", XML_DM, NULL |
| }, {"MATRIX", XML_CSC, NULL}, { |
| "PEAKING", XML_SH, NULL |
| }, {"NR", XML_NR, NULL}, {"AWB", XML_AWB, NULL}, |
| {"AE", XML_AE, NULL}, {"AF", XML_AF, NULL}, {"BLNR", XML_BN, NULL}, { |
| "DBG", XML_DBG, NULL |
| }, {"GC", XML_GC, NULL}, {"", 0, NULL} |
| }; |
| |
| void init_hw_para(struct xml_default_regs_s *reg) |
| { |
| hw_para[0].array = &(reg->top.reg_map[0]); |
| hw_para[1].array = &(reg->tp.reg_map[0]); |
| hw_para[2].array = &(reg->cg.reg_map[0]); |
| hw_para[3].array = &(reg->ls.reg_map[0]); |
| hw_para[4].array = &(reg->dp.reg_map[0]); |
| hw_para[5].array = &(reg->dm.reg_map[0]); |
| hw_para[6].array = &(reg->csc.reg_map[0]); |
| hw_para[7].array = &(reg->sharp.reg_map[0]); |
| hw_para[8].array = &(reg->nr.reg_map[0]); |
| hw_para[9].array = &(reg->awb_reg.reg_map[0]); |
| hw_para[10].array = &(reg->ae_reg.reg_map[0]); |
| hw_para[11].array = &(reg->af_reg.reg_map[0]); |
| hw_para[12].array = &(reg->bn.reg_map[0]); |
| hw_para[13].array = &(reg->dbg.reg_map[0]); |
| hw_para[14].array = &(reg->gc.reg_map[0]); |
| } |
| |
| /* call back functions */ |
| |
| unsigned int get_aet_max_step(void *priv) |
| { |
| struct camera_priv_data_s *camera_priv_data = |
| (struct camera_priv_data_s *)priv; |
| if (camera_priv_data == NULL || |
| camera_priv_data->sensor_aet_info == NULL) { |
| pr_err("get_aet_max_step null\n"); |
| WARN_ON((!camera_priv_data) || |
| (!camera_priv_data->sensor_aet_info)); |
| } |
| return camera_priv_data->sensor_aet_info->tbl_max_step; |
| } |
| |
| unsigned int get_aet_max_gain(void *priv) |
| { |
| struct camera_priv_data_s *camera_priv_data = |
| (struct camera_priv_data_s *)priv; |
| if (camera_priv_data == NULL || |
| camera_priv_data->sensor_aet_info == NULL) { |
| pr_err("get_aet_max_gain null\n"); |
| WARN_ON((!camera_priv_data) || |
| (!camera_priv_data->sensor_aet_info)); |
| } |
| return camera_priv_data->sensor_aet_info->tbl_max_gain; |
| } |
| |
| unsigned int get_aet_min_gain(void *priv) |
| { |
| struct camera_priv_data_s *camera_priv_data = |
| (struct camera_priv_data_s *)priv; |
| if (camera_priv_data == NULL || |
| camera_priv_data->sensor_aet_info == NULL) { |
| pr_err("get_aet_min_gain null\n"); |
| WARN_ON((!camera_priv_data) || |
| (!camera_priv_data->sensor_aet_info)); |
| } |
| return camera_priv_data->sensor_aet_info->tbl_min_gain; |
| } |
| |
| unsigned int get_aet_current_step(void *priv) |
| { |
| struct camera_priv_data_s *camera_priv_data = |
| (struct camera_priv_data_s *)priv; |
| if (camera_priv_data == NULL || |
| camera_priv_data->sensor_aet_info == NULL) { |
| pr_err("get_aet_current_step null\n"); |
| WARN_ON((!camera_priv_data) || |
| (!camera_priv_data->sensor_aet_info)); |
| } |
| return camera_priv_data->sensor_aet_step; |
| } |
| |
| unsigned int get_aet_current_gain(void *priv) |
| { |
| struct sensor_aet_s *sensor_aet_table; |
| unsigned int sensor_aet_step; |
| struct camera_priv_data_s *camera_priv_data = |
| (struct camera_priv_data_s *)priv; |
| if (camera_priv_data == NULL) |
| WARN_ON(!camera_priv_data); |
| |
| sensor_aet_table = |
| camera_priv_data->sensor_aet_table; |
| sensor_aet_step = camera_priv_data->sensor_aet_step; |
| |
| if (sensor_aet_table == NULL) { |
| pr_err("get_aet_current_gain null\n"); |
| WARN_ON(!sensor_aet_table); |
| } |
| return sensor_aet_table[sensor_aet_step].gain; |
| } |
| |
| unsigned int get_aet_new_gain(void *priv, unsigned int new_step) |
| { |
| struct camera_priv_data_s *camera_priv_data = |
| (struct camera_priv_data_s *)priv; |
| struct sensor_aet_s *sensor_aet_table; |
| |
| if (camera_priv_data == NULL) |
| WARN_ON(!camera_priv_data); |
| sensor_aet_table = |
| camera_priv_data->sensor_aet_table; |
| if (sensor_aet_table == NULL) { |
| pr_err("get_aet_current_gain null\n"); |
| WARN_ON(!sensor_aet_table); |
| } |
| return sensor_aet_table[new_step].gain; |
| } |
| |
| int generate_para(struct cam_parameter_s *para, struct para_index_s pindex, |
| struct configure_s *cf) |
| { |
| int i = 0; |
| int j = 0; |
| struct xml_scenes_s *scene; |
| struct xml_default_regs_s *reg; |
| struct xml_effect_manual_s *effect; |
| struct xml_wb_manual_s *wb; |
| struct xml_capture_s *capture; |
| struct wave_s *wave; |
| |
| /**init callback func**/ |
| para->cam_function.set_af_new_step = NULL; |
| if (cf->aet_valid == 1) { |
| para->cam_function.get_aet_current_step = get_aet_current_step; |
| para->cam_function.get_aet_max_step = get_aet_max_step; |
| para->cam_function.get_aet_current_gain = get_aet_current_gain; |
| para->cam_function.get_aet_min_gain = get_aet_min_gain; |
| para->cam_function.get_aet_max_gain = get_aet_max_gain; |
| para->cam_function.get_aet_gain_by_step = get_aet_new_gain; |
| |
| } |
| /**init scenes**/ |
| if (cf->scene_valid == 1) { |
| para->xml_scenes = |
| vmalloc(sizeof(struct xml_scenes_s)); |
| if (para->xml_scenes == NULL) { |
| pr_err("alloc mem failed\n"); |
| return -ENOMEM; |
| } |
| scene = para->xml_scenes; |
| memcpy(&(scene->ae), |
| cf->scene.scene[pindex.scenes_index].export, |
| AE_LEN * sizeof(unsigned int)); |
| memcpy(&(scene->awb), |
| cf->scene.scene[pindex.scenes_index].export + AE_LEN, |
| AWB_LEN * sizeof(unsigned int)); |
| memcpy(&(scene->af), |
| cf->scene.scene[pindex.scenes_index].export + |
| (AE_LEN + AWB_LEN), |
| AF_LEN * sizeof(unsigned int)); |
| } else |
| para->xml_scenes = NULL; |
| |
| /**init hw**/ |
| if (cf->hw_valid == 1) { |
| para->xml_regs_map = vmalloc(sizeof(struct xml_default_regs_s)); |
| if (para->xml_regs_map == NULL) { |
| pr_err("alloc mem failed\n"); |
| return -ENOMEM; |
| } |
| reg = para->xml_regs_map; |
| init_hw_para(reg); |
| for (i = 0; i < cf->hw.sum; i++) { |
| if ((strcmp(hw_para[i].name, cf->hw.hw[i].name)) == 0) { |
| for (j = 0; j < hw_para[i].size; j++) |
| hw_para[i].array[j] = |
| cf->hw.hw[i].export[j]; |
| } |
| } |
| |
| } else |
| para->xml_regs_map = NULL; |
| /** init gamma **/ |
| if (cf->gamma_valid == 1) { |
| if (para->xml_regs_map == NULL) { |
| para->xml_regs_map = |
| vmalloc(sizeof(struct xml_default_regs_s)); |
| if (para->xml_regs_map == NULL) { |
| pr_err("alloc mem failed\n"); |
| return -ENOMEM; |
| } |
| } |
| reg = para->xml_regs_map; |
| memcpy(reg->lut_gc.gamma_r, cf->gamma.gamma_r, |
| GAMMA_MAX * sizeof(unsigned short)); |
| memcpy(reg->lut_gc.gamma_g, cf->gamma.gamma_g, |
| GAMMA_MAX * sizeof(unsigned short)); |
| memcpy(reg->lut_gc.gamma_b, cf->gamma.gamma_b, |
| GAMMA_MAX * sizeof(unsigned short)); |
| } |
| /**init effect**/ |
| if (cf->effect_valid == 1) { |
| para->xml_effect_manual = |
| kmalloc(sizeof(struct xml_effect_manual_s), 0); |
| if (para->xml_effect_manual == NULL) { |
| pr_err("alloc mem failed\n"); |
| return -ENOMEM; |
| } |
| effect = para->xml_effect_manual; |
| memcpy(effect->csc.reg_map, |
| cf->eff.eff[pindex.effect_index].export, |
| EFFECT_MAX * sizeof(unsigned int)); |
| } else |
| para->xml_effect_manual = NULL; |
| /**init wb**/ |
| if (cf->wb_valid == 1) { |
| para->xml_wb_manual = |
| kmalloc(sizeof(struct xml_wb_manual_s), 0); |
| if (para->xml_wb_manual == NULL) { |
| pr_err("alloc mem failed\n"); |
| return -ENOMEM; |
| } |
| wb = para->xml_wb_manual; |
| memcpy(wb->reg_map, cf->wb.wb[pindex.wb_index].export, |
| 2 * sizeof(unsigned int)); |
| } else |
| para->xml_wb_manual = NULL; |
| |
| /**init capture**/ |
| if (cf->capture_valid == 1) { |
| para->xml_capture = vmalloc(sizeof(struct xml_capture_s)); |
| if (para->xml_capture == NULL) { |
| pr_err("alloc mem failed\n"); |
| return -ENOMEM; |
| } |
| capture = para->xml_capture; |
| capture->ae_try_max_cnt = (unsigned int)(cf->capture. |
| capture[pindex.capture_index].export[0]); |
| capture->sigle_count = (unsigned int)(cf->capture. |
| capture[pindex.capture_index].export[3]); |
| capture->skip_step = (unsigned int)(cf->capture. |
| capture[pindex.capture_index].export[4]); |
| capture->multi_capture_num = (unsigned int)(cf->capture. |
| capture[pindex.capture_index].export[5]); |
| capture->af_mode = (enum cam_scanmode_e)(cf->capture. |
| capture[pindex.capture_index].export[2]); |
| capture->eyetime = (unsigned int)(cf->capture. |
| capture[pindex.capture_index].export[6]); |
| capture->pretime = (unsigned int)(cf->capture. |
| capture[pindex.capture_index].export[7]); |
| capture->postime = (unsigned int)(cf->capture. |
| capture[pindex.capture_index].export[8]); |
| } else |
| para->xml_capture = NULL; |
| /**init wave**/ |
| if (cf->wave_valid == 1) { |
| para->xml_wave = kmalloc(sizeof(struct wave_s), 0); |
| if (para->xml_wave == NULL) { |
| pr_err("alloc mem failed\n"); |
| return -ENOMEM; |
| } |
| wave = para->xml_wave; |
| memcpy(wave, cf->wave.export, WAVE_MAX * sizeof(unsigned int)); |
| } else |
| para->xml_wave = NULL; |
| return 0; |
| } |
| |
| void free_para(struct cam_parameter_s *para) |
| { |
| if (para->xml_peripheral != NULL) { |
| kfree(para->xml_peripheral); |
| para->xml_peripheral = NULL; |
| } |
| if (para->xml_scenes != NULL) { |
| vfree(para->xml_scenes); |
| para->xml_scenes = NULL; |
| } |
| if (para->xml_regs_map != NULL) { |
| vfree(para->xml_regs_map); |
| para->xml_regs_map = NULL; |
| } |
| if (para->xml_effect_manual != NULL) { |
| kfree(para->xml_effect_manual); |
| para->xml_effect_manual = NULL; |
| } |
| if (para->xml_wb_manual != NULL) { |
| kfree(para->xml_wb_manual); |
| para->xml_wb_manual = NULL; |
| } |
| if (para->xml_capture != NULL) { |
| vfree(para->xml_capture); |
| para->xml_capture = NULL; |
| } |
| if (para->xml_wave != NULL) { |
| kfree(para->xml_wave); |
| para->xml_wave = NULL; |
| } |
| } |
| |
| int update_fmt_para(int width, int height, struct cam_parameter_s *para, |
| struct para_index_s *pindex, struct configure_s *cf) |
| { |
| int i = 0; |
| struct xml_default_regs_s *reg; |
| |
| if (cf->lens_valid == 1) { |
| while (i < cf->lens.sum) { |
| if (cf->lens.lens[i].export[0] == width && |
| cf->lens.lens[i].export[1] == height) |
| break; |
| i++; |
| } |
| if (i < cf->lens.sum) |
| pindex->lens_index = i; |
| else { |
| pr_info("width:%x,height:%x no match lens param\n", |
| width, height); |
| pindex->lens_index = 0; |
| } |
| /** init lens **/ |
| if (para->xml_regs_map == NULL) { |
| para->xml_regs_map = |
| vmalloc(sizeof(struct xml_default_regs_s)); |
| if (para->xml_regs_map == NULL) { |
| pr_err("alloc mem failed\n"); |
| return -ENOMEM; |
| } |
| } |
| reg = para->xml_regs_map; |
| memcpy(reg->lnsd.reg_map, |
| cf->lens.lens[pindex->lens_index].export + 2, |
| (LENS_MAX - 2) * sizeof(unsigned int)); |
| } |
| |
| i = 0; |
| if (cf->nr_valid == 1) { |
| while (i < cf->nr.sum) { |
| if (cf->nr.nr[i].export[0] == width && |
| cf->nr.nr[i].export[1] == height) |
| break; |
| i++; |
| } |
| if (i < cf->nr.sum) |
| pindex->nr_index = i; |
| else { |
| pr_info("width:%x,height:%x no match nr param\n", |
| width, height); |
| pindex->nr_index = 0; |
| } |
| /** init nr **/ |
| if (para->xml_regs_map == NULL) { |
| para->xml_regs_map = |
| vmalloc(sizeof(struct xml_default_regs_s)); |
| if (para->xml_regs_map == NULL) { |
| pr_err("alloc mem failed\n"); |
| return -ENOMEM; |
| } |
| } |
| reg = para->xml_regs_map; |
| memcpy(reg->nr.reg_map, cf->nr.nr[pindex->nr_index].export + 2, |
| (NR_MAX - 2) * sizeof(unsigned int)); |
| } |
| |
| i = 0; |
| if (cf->peaking_valid == 1) { |
| while (i < cf->peaking.sum) { |
| if (cf->peaking.peaking[i].export[0] == width && |
| cf->peaking.peaking[i].export[1] == height) |
| break; |
| i++; |
| } |
| if (i < cf->peaking.sum) |
| pindex->peaking_index = i; |
| else { |
| pr_info("width:%x,height:%x no match peaking param\n", |
| width, height); |
| pindex->peaking_index = 0; |
| } |
| /** init sharp **/ |
| if (para->xml_regs_map == NULL) { |
| para->xml_regs_map = |
| vmalloc(sizeof(struct xml_default_regs_s)); |
| if (para->xml_regs_map == NULL) { |
| pr_err("alloc mem failed\n"); |
| return -ENOMEM; |
| } |
| } |
| reg = para->xml_regs_map; |
| memcpy(reg->sharp.reg_map, |
| cf->peaking.peaking[pindex->peaking_index].export + 2, |
| (PEAKING_MAX - 2) * sizeof(unsigned int)); |
| } |
| return 0; |
| } |