| /* |
| * drivers/amlogic/media/vout/backlight/aml_ldim/ldim_drv.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 <linux/version.h> |
| #include <linux/string.h> |
| #include <linux/io.h> |
| #include <linux/mm.h> |
| #include <linux/mutex.h> |
| #include <linux/cdev.h> |
| #include <linux/uaccess.h> |
| #include <linux/timer.h> |
| #include <linux/delay.h> |
| #include <linux/major.h> |
| #include <linux/sched.h> |
| #include <linux/vmalloc.h> |
| #include <linux/types.h> |
| #include <linux/init.h> |
| #include <linux/slab.h> |
| #include <linux/module.h> |
| #include <linux/kernel.h> |
| #include <linux/device.h> |
| #include <linux/interrupt.h> |
| #include <linux/fs.h> |
| #include <linux/miscdevice.h> |
| #include <linux/platform_device.h> |
| #include <linux/moduleparam.h> |
| #include <linux/timer.h> |
| #include <linux/spinlock.h> |
| #include <linux/amlogic/iomap.h> |
| #include <linux/workqueue.h> |
| #include <linux/amlogic/media/vfm/vframe.h> |
| #include <linux/amlogic/media/vout/lcd/aml_ldim.h> |
| #include <linux/amlogic/media/vout/lcd/aml_bl.h> |
| #include <linux/amlogic/media/vout/vout_notify.h> |
| #include <linux/amlogic/media/vout/lcd/lcd_vout.h> |
| #include <linux/amlogic/media/utils/vdec_reg.h> |
| #include <linux/amlogic/media/vout/lcd/lcd_unifykey.h> |
| #include <linux/amlogic/media/vout/lcd/ldim_alg.h> |
| #include "ldim_drv.h" |
| #include "ldim_reg.h" |
| |
| #define AML_LDIM_DEV_NAME "aml_ldim" |
| |
| const char ldim_dev_id[] = "ldim-dev"; |
| unsigned char ldim_debug_print; |
| |
| struct ldim_dev_s { |
| struct ldim_operate_func_s *ldim_op_func; |
| struct ldim_param_s *ldim_db_para; |
| |
| struct cdev cdev; |
| struct device *dev; |
| dev_t aml_ldim_devno; |
| struct class *aml_ldim_clsp; |
| struct cdev *aml_ldim_cdevp; |
| }; |
| static struct ldim_dev_s ldim_dev; |
| static struct LDReg_s nPRM; |
| static struct FW_DAT_s FDat; |
| static struct ldim_fw_para_s ldim_fw_para; |
| static struct aml_ldim_driver_s ldim_driver; |
| |
| static unsigned int ldim_hist_row = 1; |
| static unsigned int ldim_hist_col = 1; |
| static unsigned int ldim_blk_row = 1; |
| static unsigned int ldim_blk_col = 1; |
| static unsigned int ldim_data_min = LD_DATA_MIN; |
| static unsigned int ldim_brightness_level; |
| static unsigned long litgain = LD_DATA_MAX; |
| |
| static unsigned char ldim_on_flag; |
| static unsigned char LDIM_DATA_FROM_DB, db_print_flag; |
| static unsigned char ldim_func_en, ldim_remap_en, ldim_demo_en; |
| static unsigned char ldim_func_bypass; /* for lcd bist pattern */ |
| static unsigned char ldim_brightness_bypass; |
| static unsigned char ldim_level_update; |
| static unsigned char ldim_test_en; |
| |
| static spinlock_t ldim_isr_lock; |
| static spinlock_t rdma_ldim_isr_lock; |
| |
| static struct workqueue_struct *ldim_queue; |
| static struct work_struct ldim_on_vs_work; |
| static struct work_struct ldim_off_vs_work; |
| |
| static unsigned int ldim_irq_cnt; |
| static unsigned int brightness_vs_cnt; |
| |
| /*BL_matrix remap curve*/ |
| static unsigned int bl_remap_curve[16] = { |
| 612, 654, 721, 851, 1001, 1181, 1339, 1516, |
| 1738, 1948, 2152, 2388, 2621, 2889, 3159, 3502 |
| }; |
| static unsigned int fw_LD_Whist[16] = { |
| 32, 64, 96, 128, 160, 192, 224, 256, |
| 288, 320, 352, 384, 416, 448, 480, 512 |
| }; |
| |
| static unsigned int ldim_hist_en; |
| module_param(ldim_hist_en, uint, 0664); |
| MODULE_PARM_DESC(ldim_hist_en, "ldim_hist_en"); |
| |
| static unsigned int ldim_avg_update_en; |
| module_param(ldim_avg_update_en, uint, 0664); |
| MODULE_PARM_DESC(ldim_avg_update_en, "ldim_avg_update_en"); |
| |
| static unsigned int ldim_matrix_update_en; |
| module_param(ldim_matrix_update_en, uint, 0664); |
| MODULE_PARM_DESC(ldim_matrix_update_en, "ldim_matrix_update_en"); |
| |
| static unsigned int ldim_alg_en; |
| module_param(ldim_alg_en, uint, 0664); |
| MODULE_PARM_DESC(ldim_alg_en, "ldim_alg_en"); |
| |
| static unsigned int ldim_top_en; |
| module_param(ldim_top_en, uint, 0664); |
| MODULE_PARM_DESC(ldim_top_en, "ldim_top_en"); |
| |
| static void ldim_dump_histgram(void); |
| static void ldim_get_matrix_info_max_rgb(void); |
| |
| static struct ldim_config_s ldim_config = { |
| .hsize = 3840, |
| .vsize = 2160, |
| .row = 1, |
| .col = 1, |
| .bl_mode = 1, |
| .bl_en = 1, |
| .hvcnt_bypass = 0, |
| }; |
| |
| static void ldim_db_para_print(struct LDReg_s *mLDReg) |
| { |
| int i, len; |
| char *buf; |
| |
| len = 32 * 10 + 10; |
| buf = kcalloc(len, sizeof(char), GFP_KERNEL); |
| if (buf == NULL) { |
| LDIMERR("print buf malloc error\n"); |
| return; |
| } |
| |
| LDIMPR("%s:\n", __func__); |
| pr_info("rgb_base = %d\n" |
| "boost_gain = %d\n" |
| "lpf_res = %d\n" |
| "fw_LD_ThSF = %d\n\n", |
| ldim_fw_para.rgb_base, |
| ldim_fw_para.boost_gain, |
| ldim_fw_para.lpf_res, |
| ldim_fw_para.fw_LD_ThSF_l); |
| |
| pr_info("ld_vgain = %d\n" |
| "ld_hgain = %d\n" |
| "ld_litgain = %d\n\n", |
| mLDReg->reg_LD_Vgain, |
| mLDReg->reg_LD_Hgain, |
| mLDReg->reg_LD_Litgain); |
| |
| pr_info("ld_lut_vdg_lext = %d\n" |
| "ld_lut_hdg_lext = %d\n" |
| "ld_lut_vhk_lext = %d\n\n", |
| mLDReg->reg_LD_LUT_Vdg_LEXT, |
| mLDReg->reg_LD_LUT_Hdg_LEXT, |
| mLDReg->reg_LD_LUT_VHk_LEXT); |
| |
| len = 0; |
| pr_info("ld_lut_hdg:\n"); |
| for (i = 0; i < 32; i++) { |
| len += sprintf(buf+len, "\t%d", |
| mLDReg->reg_LD_LUT_Hdg[i]); |
| if (i % 8 == 7) |
| len += sprintf(buf+len, "\n"); |
| } |
| pr_info("%s\n", buf); |
| |
| len = 0; |
| pr_info("ld_lut_vdg:\n"); |
| for (i = 0; i < 32; i++) { |
| len += sprintf(buf+len, "\t%d", |
| mLDReg->reg_LD_LUT_Vdg[i]); |
| if (i % 8 == 7) |
| len += sprintf(buf+len, "\n"); |
| } |
| pr_info("%s\n", buf); |
| |
| len = 0; |
| pr_info("ld_lut_vhk:\n"); |
| for (i = 0; i < 32; i++) { |
| len += sprintf(buf+len, "\t%d", |
| mLDReg->reg_LD_LUT_VHk[i]); |
| if (i % 8 == 7) |
| len += sprintf(buf+len, "\n"); |
| } |
| pr_info("%s\n", buf); |
| |
| len = 0; |
| pr_info("ld_lut_vhk_pos:\n"); |
| for (i = 0; i < 32; i++) { |
| len += sprintf(buf+len, "\t%d", |
| mLDReg->reg_LD_LUT_VHk_pos[i]); |
| if (i % 8 == 7) |
| len += sprintf(buf+len, "\n"); |
| } |
| pr_info("%s\n", buf); |
| |
| len = 0; |
| pr_info("ld_lut_vhk_neg:\n"); |
| for (i = 0; i < 32; i++) { |
| len += sprintf(buf+len, "\t%d", |
| mLDReg->reg_LD_LUT_VHk_neg[i]); |
| if (i % 8 == 7) |
| len += sprintf(buf+len, "\n"); |
| } |
| pr_info("%s\n", buf); |
| |
| len = 0; |
| pr_info("ld_lut_hhk:\n"); |
| for (i = 0; i < 32; i++) { |
| len += sprintf(buf+len, "\t%d", |
| mLDReg->reg_LD_LUT_HHk[i]); |
| if (i % 8 == 7) |
| len += sprintf(buf+len, "\n"); |
| } |
| pr_info("%s\n", buf); |
| |
| len = 0; |
| pr_info("ld_lut_vho_pos:\n"); |
| for (i = 0; i < 32; i++) { |
| len += sprintf(buf+len, "\t%d", |
| mLDReg->reg_LD_LUT_VHo_pos[i]); |
| if (i % 8 == 7) |
| len += sprintf(buf+len, "\n"); |
| } |
| pr_info("%s\n", buf); |
| |
| len = 0; |
| pr_info("ld_lut_vho_neg:\n"); |
| for (i = 0; i < 32; i++) { |
| len += sprintf(buf+len, "\t%d", |
| mLDReg->reg_LD_LUT_VHo_neg[i]); |
| if (i % 8 == 7) |
| len += sprintf(buf+len, "\n"); |
| } |
| pr_info("%s\n", buf); |
| |
| kfree(buf); |
| } |
| |
| static void ldim_db_load_update(struct LDReg_s *mLDReg, |
| struct ldim_param_s *db_para) |
| { |
| int i; |
| |
| if (db_para == NULL) |
| return; |
| |
| LDIMPR("ldim_db_load_update\n"); |
| /* beam model */ |
| ldim_fw_para.rgb_base = db_para->rgb_base; |
| ldim_fw_para.boost_gain = db_para->boost_gain; |
| ldim_fw_para.lpf_res = db_para->lpf_res; |
| ldim_fw_para.fw_LD_ThSF_l = db_para->fw_ld_th_sf; |
| |
| /* beam curve */ |
| mLDReg->reg_LD_Vgain = db_para->ld_vgain; |
| mLDReg->reg_LD_Hgain = db_para->ld_hgain; |
| mLDReg->reg_LD_Litgain = db_para->ld_litgain; |
| |
| mLDReg->reg_LD_LUT_Vdg_LEXT = db_para->ld_lut_vdg_lext; |
| mLDReg->reg_LD_LUT_Hdg_LEXT = db_para->ld_lut_hdg_lext; |
| mLDReg->reg_LD_LUT_VHk_LEXT = db_para->ld_lut_vhk_lext; |
| |
| for (i = 0; i < 32; i++) { |
| mLDReg->reg_LD_LUT_Hdg[i] = db_para->ld_lut_hdg[i]; |
| mLDReg->reg_LD_LUT_Vdg[i] = db_para->ld_lut_vdg[i]; |
| mLDReg->reg_LD_LUT_VHk[i] = db_para->ld_lut_vhk[i]; |
| } |
| |
| /* beam shape minor adjustment */ |
| for (i = 0; i < 32; i++) { |
| mLDReg->reg_LD_LUT_VHk_pos[i] = db_para->ld_lut_vhk_pos[i]; |
| mLDReg->reg_LD_LUT_VHk_neg[i] = db_para->ld_lut_vhk_neg[i]; |
| mLDReg->reg_LD_LUT_HHk[i] = db_para->ld_lut_hhk[i]; |
| mLDReg->reg_LD_LUT_VHo_pos[i] = db_para->ld_lut_vho_pos[i]; |
| mLDReg->reg_LD_LUT_VHo_neg[i] = db_para->ld_lut_vho_neg[i]; |
| } |
| |
| /* remapping */ |
| /*db_para->lit_idx_th;*/ |
| /*db_para->comp_gain;*/ |
| |
| if (db_print_flag == 1) |
| ldim_db_para_print(mLDReg); |
| } |
| |
| static void ldim_stts_initial(unsigned int pic_h, unsigned int pic_v, |
| unsigned int BLK_Vnum, unsigned int BLK_Hnum) |
| { |
| LDIMPR("%s: %d %d %d %d\n", __func__, pic_h, pic_v, BLK_Vnum, BLK_Hnum); |
| |
| ldim_fw_para.hist_col = BLK_Vnum; |
| ldim_fw_para.hist_row = BLK_Hnum; |
| |
| if (ldim_dev.ldim_op_func == NULL) { |
| LDIMERR("%s: invalid ldim_op_func\n", __func__); |
| return; |
| } |
| if (ldim_dev.ldim_op_func->stts_init) { |
| ldim_dev.ldim_op_func->stts_init(pic_h, pic_v, |
| BLK_Vnum, BLK_Hnum); |
| } |
| } |
| |
| static void LDIM_Initial(unsigned int pic_h, unsigned int pic_v, |
| unsigned int BLK_Vnum, unsigned int BLK_Hnum, |
| unsigned int BackLit_mode, unsigned int ldim_bl_en, |
| unsigned int ldim_hvcnt_bypass) |
| { |
| LDIMPR("%s: %d %d %d %d %d %d %d\n", |
| __func__, pic_h, pic_v, BLK_Vnum, BLK_Hnum, |
| BackLit_mode, ldim_bl_en, ldim_hvcnt_bypass); |
| |
| ldim_matrix_update_en = ldim_bl_en; |
| LD_ConLDReg(&nPRM); |
| /* config params begin */ |
| /* configuration of the panel parameters */ |
| nPRM.reg_LD_pic_RowMax = pic_v; |
| nPRM.reg_LD_pic_ColMax = pic_h; |
| /* Maximum to BLKVMAX , Maximum to BLKHMAX */ |
| nPRM.reg_LD_BLK_Vnum = BLK_Vnum; |
| nPRM.reg_LD_BLK_Hnum = BLK_Hnum; |
| nPRM.reg_LD_BackLit_mode = BackLit_mode; |
| /*config params end */ |
| ld_fw_cfg_once(&nPRM); |
| if (LDIM_DATA_FROM_DB) |
| ldim_db_load_update(&nPRM, ldim_dev.ldim_db_para); |
| |
| if (ldim_dev.ldim_op_func == NULL) { |
| LDIMERR("%s: invalid ldim_op_func\n", __func__); |
| return; |
| } |
| if (ldim_dev.ldim_op_func->ldim_init) { |
| ldim_dev.ldim_op_func->ldim_init(&nPRM, |
| ldim_bl_en, ldim_hvcnt_bypass); |
| } |
| } |
| |
| static void ldim_remap_update(void) |
| { |
| if (ldim_dev.ldim_op_func == NULL) { |
| if (brightness_vs_cnt == 0) |
| LDIMERR("%s: invalid ldim_op_func\n", __func__); |
| return; |
| } |
| if (ldim_dev.ldim_op_func->remap_update) { |
| ldim_dev.ldim_op_func->remap_update(&nPRM, |
| ldim_avg_update_en, ldim_matrix_update_en); |
| } |
| } |
| |
| static irqreturn_t ldim_vsync_isr(int irq, void *dev_id) |
| { |
| unsigned long flags; |
| |
| if (ldim_on_flag == 0) |
| return IRQ_HANDLED; |
| |
| spin_lock_irqsave(&ldim_isr_lock, flags); |
| |
| if (brightness_vs_cnt++ >= 30) /* for debug print */ |
| brightness_vs_cnt = 0; |
| |
| if (ldim_func_en) { |
| if (ldim_avg_update_en) |
| ldim_remap_update(); |
| |
| if (ldim_hist_en) { |
| /*schedule_work(&ldim_on_vs_work);*/ |
| queue_work(ldim_queue, &ldim_on_vs_work); |
| } |
| } else { |
| /*schedule_work(&ldim_off_vs_work);*/ |
| queue_work(ldim_queue, &ldim_off_vs_work); |
| } |
| |
| ldim_irq_cnt++; |
| if (ldim_irq_cnt > 0xfffffff) |
| ldim_irq_cnt = 0; |
| |
| spin_unlock_irqrestore(&ldim_isr_lock, flags); |
| |
| return IRQ_HANDLED; |
| } |
| |
| static void ldim_on_vs_brightness(void) |
| { |
| unsigned int size; |
| unsigned int i; |
| |
| if (ldim_on_flag == 0) |
| return; |
| |
| if (ldim_func_bypass) |
| return; |
| |
| if (ldim_fw_para.fw_alg_frm == NULL) { |
| if (brightness_vs_cnt == 0) |
| LDIMERR("%s: ldim_alg ko is not installed\n", __func__); |
| return; |
| } |
| |
| size = ldim_blk_row * ldim_blk_col; |
| |
| if (ldim_test_en) { |
| for (i = 0; i < size; i++) { |
| ldim_driver.local_ldim_matrix[i] = |
| (unsigned short)nPRM.BL_matrix[i]; |
| ldim_driver.ldim_matrix_buf[i] = |
| ldim_driver.ldim_test_matrix[i]; |
| } |
| } else { |
| for (i = 0; i < size; i++) { |
| ldim_driver.local_ldim_matrix[i] = |
| (unsigned short)nPRM.BL_matrix[i]; |
| ldim_driver.ldim_matrix_buf[i] = |
| (unsigned short) |
| (((nPRM.BL_matrix[i] * litgain) |
| + (LD_DATA_MAX / 2)) >> LD_DATA_DEPTH); |
| } |
| } |
| |
| if (ldim_driver.device_bri_update) { |
| ldim_driver.device_bri_update(ldim_driver.ldim_matrix_buf, |
| size); |
| if (ldim_driver.static_pic_flag == 1) { |
| if (brightness_vs_cnt == 0) { |
| ldim_get_matrix_info_max_rgb(); |
| ldim_dump_histgram(); |
| } |
| } |
| } else { |
| if (brightness_vs_cnt == 0) |
| LDIMERR("%s: device_bri_update is null\n", __func__); |
| } |
| } |
| |
| static void ldim_off_vs_brightness(void) |
| { |
| unsigned int size; |
| unsigned int i; |
| int ret; |
| |
| if (ldim_on_flag == 0) |
| return; |
| |
| size = ldim_blk_row * ldim_blk_col; |
| |
| if (ldim_level_update) { |
| ldim_level_update = 0; |
| if (ldim_debug_print) |
| LDIMPR("%s: level update: 0x%lx\n", __func__, litgain); |
| for (i = 0; i < size; i++) { |
| ldim_driver.local_ldim_matrix[i] = |
| (unsigned short)nPRM.BL_matrix[i]; |
| ldim_driver.ldim_matrix_buf[i] = |
| (unsigned short)(litgain); |
| } |
| } else { |
| if (ldim_driver.device_bri_check) { |
| ret = ldim_driver.device_bri_check(); |
| if (ret) { |
| if (brightness_vs_cnt == 0) { |
| LDIMERR("%s: device_bri_check error\n", |
| __func__); |
| } |
| ldim_level_update = 1; |
| } |
| } |
| return; |
| } |
| |
| if (ldim_driver.device_bri_update) { |
| ldim_driver.device_bri_update(ldim_driver.ldim_matrix_buf, |
| size); |
| if (ldim_driver.static_pic_flag == 1) { |
| if (brightness_vs_cnt == 0) { |
| ldim_get_matrix_info_max_rgb(); |
| ldim_dump_histgram(); |
| } |
| } |
| } else { |
| if (brightness_vs_cnt == 0) |
| LDIMERR("%s: device_bri_update is null\n", __func__); |
| } |
| } |
| |
| static void ldim_on_vs_arithmetic(void) |
| { |
| unsigned int *local_ldim_hist = NULL; |
| unsigned int *local_ldim_max = NULL; |
| unsigned int *local_ldim_max_rgb = NULL; |
| unsigned int i; |
| |
| if (ldim_top_en == 0) |
| return; |
| local_ldim_hist = kcalloc(ldim_hist_row*ldim_hist_col*16, |
| sizeof(unsigned int), GFP_KERNEL); |
| if (local_ldim_hist == NULL) |
| return; |
| |
| local_ldim_max = kcalloc(ldim_hist_row*ldim_hist_col, |
| sizeof(unsigned int), GFP_KERNEL); |
| if (local_ldim_max == NULL) { |
| kfree(local_ldim_hist); |
| return; |
| } |
| local_ldim_max_rgb = kcalloc(ldim_hist_row*ldim_hist_col*3, |
| sizeof(unsigned int), GFP_KERNEL); |
| if (local_ldim_max_rgb == NULL) { |
| kfree(local_ldim_hist); |
| kfree(local_ldim_max); |
| return; |
| } |
| /* spin_lock_irqsave(&ldim_isr_lock, flags); */ |
| memcpy(local_ldim_hist, ldim_driver.hist_matrix, |
| ldim_hist_row*ldim_hist_col*16*sizeof(unsigned int)); |
| memcpy(local_ldim_max, ldim_driver.max_rgb, |
| ldim_hist_row*ldim_hist_col*sizeof(unsigned int)); |
| for (i = 0; i < ldim_hist_row*ldim_hist_col; i++) { |
| (*(local_ldim_max_rgb+i*3)) = |
| (*(local_ldim_max+i))&0x3ff; |
| (*(local_ldim_max_rgb+i*3+1)) = |
| (*(local_ldim_max+i))>>10&0x3ff; |
| (*(local_ldim_max_rgb+i*3+2)) = |
| (*(local_ldim_max+i))>>20&0x3ff; |
| } |
| if (ldim_alg_en) { |
| if (ldim_fw_para.fw_alg_frm) { |
| ldim_fw_para.fw_alg_frm(&ldim_fw_para, |
| local_ldim_max_rgb, local_ldim_hist); |
| } |
| } |
| |
| kfree(local_ldim_hist); |
| kfree(local_ldim_max); |
| kfree(local_ldim_max_rgb); |
| } |
| |
| static void ldim_on_update_brightness(struct work_struct *work) |
| { |
| ldim_stts_read_region(ldim_hist_row, ldim_hist_col); |
| ldim_on_vs_arithmetic(); |
| ldim_on_vs_brightness(); |
| } |
| |
| static void ldim_off_update_brightness(struct work_struct *work) |
| { |
| ldim_off_vs_brightness(); |
| } |
| |
| static void ldim_bl_remap_curve_print(void) |
| { |
| int i = 0, len; |
| char *buf; |
| |
| len = 16 * 8 + 20; |
| buf = kcalloc(len, sizeof(char), GFP_KERNEL); |
| if (buf == NULL) { |
| LDIMERR("print buf malloc error\n"); |
| return; |
| } |
| |
| pr_info("bl_remap_curve:\n"); |
| len = 0; |
| for (i = 0; i < 16; i++) |
| len += sprintf(buf+len, "\t%d", bl_remap_curve[i]); |
| pr_info("%s\n", buf); |
| |
| kfree(buf); |
| } |
| |
| static void ldim_fw_LD_Whist_print(void) |
| { |
| int i = 0, len; |
| char *buf; |
| |
| len = 16 * 8 + 20; |
| buf = kcalloc(len, sizeof(char), GFP_KERNEL); |
| if (buf == NULL) { |
| LDIMERR("print buf malloc error\n"); |
| return; |
| } |
| |
| pr_info("fw_LD_Whist:\n"); |
| len = 0; |
| for (i = 0; i < 16; i++) |
| len += sprintf(buf+len, "\t%d", fw_LD_Whist[i]); |
| pr_info("%s\n", buf); |
| |
| kfree(buf); |
| } |
| |
| static void ldim_ld_remap_lut_print(int index) |
| { |
| int i, j, len; |
| char *buf; |
| |
| len = 32 * 8 + 20; |
| buf = kcalloc(len, sizeof(char), GFP_KERNEL); |
| if (buf == NULL) { |
| LDIMERR("print buf malloc error\n"); |
| return; |
| } |
| |
| if (index == 0xff) { |
| pr_info("LD_remap_lut:\n"); |
| for (i = 0; i < 16; i++) { |
| pr_info(" %d:\n", i); |
| len = 0; |
| for (j = 0; j < 32; j++) { |
| if (j == 16) |
| len += sprintf(buf+len, "\n"); |
| len += sprintf(buf+len, "\t%d", |
| LD_remap_lut[i][j]); |
| } |
| pr_info("%s\n", buf); |
| } |
| } else if (index < 16) { |
| pr_info("LD_remap_lut %d:\n", index); |
| len = 0; |
| for (j = 0; j < 32; j++) { |
| if (j == 16) |
| len += sprintf(buf+len, "\n"); |
| len += sprintf(buf+len, "\t%d", |
| LD_remap_lut[index][j]); |
| } |
| pr_info("%s\n", buf); |
| } else { |
| pr_info("LD_remap_lut invalid index %d\n", index); |
| } |
| pr_info("\n"); |
| |
| kfree(buf); |
| } |
| |
| static void ldim_dump_histgram(void) |
| { |
| unsigned int i, j, k, len; |
| unsigned int *p = NULL; |
| char *buf; |
| |
| p = kcalloc(2048, sizeof(unsigned int), GFP_KERNEL); |
| if (p == NULL) { |
| LDIMERR("ldim_matrix_t malloc error\n"); |
| return; |
| } |
| |
| len = 16 * 10 + 20; |
| buf = kcalloc(len, sizeof(char), GFP_KERNEL); |
| if (buf == NULL) { |
| LDIMERR("print buf malloc error\n"); |
| kfree(p); |
| return; |
| } |
| |
| memcpy(p, ldim_driver.hist_matrix, |
| ldim_hist_row*ldim_hist_col*16*sizeof(unsigned int)); |
| |
| for (i = 0; i < ldim_hist_row; i++) { |
| pr_info("%s: row %d:\n", __func__, i); |
| for (j = 0; j < ldim_hist_col; j++) { |
| len = sprintf(buf, "col %d:\n", j); |
| for (k = 0; k < 16; k++) { |
| len += sprintf(buf+len, "\t0x%x", |
| *(p+i*16*ldim_hist_col+j*16+k)); |
| if (k == 7) |
| len += sprintf(buf+len, "\n"); |
| } |
| pr_info("%s\n\n", buf); |
| } |
| msleep(20); |
| } |
| |
| kfree(buf); |
| kfree(p); |
| } |
| |
| static void ldim_get_matrix_info_TF(void) |
| { |
| unsigned int i, j, len; |
| unsigned int *ldim_matrix_t = NULL; |
| char *buf; |
| |
| ldim_matrix_t = kcalloc(ldim_hist_row*ldim_hist_col, |
| sizeof(unsigned int), GFP_KERNEL); |
| if (ldim_matrix_t == NULL) { |
| LDIMERR("ldim_matrix_t malloc error\n"); |
| return; |
| } |
| |
| len = ldim_blk_col * 10 + 20; |
| buf = kcalloc(len, sizeof(char), GFP_KERNEL); |
| if (buf == NULL) { |
| LDIMERR("print buf malloc error\n"); |
| kfree(ldim_matrix_t); |
| return; |
| } |
| |
| memcpy(ldim_matrix_t, &FDat.TF_BL_matrix[0], |
| ldim_blk_col*ldim_blk_row*sizeof(unsigned int)); |
| |
| pr_info("%s:\n", __func__); |
| for (i = 0; i < ldim_blk_row; i++) { |
| len = 0; |
| for (j = 0; j < ldim_blk_col; j++) { |
| len += sprintf(buf+len, "\t%4d", |
| ldim_matrix_t[ldim_blk_col*i+j]); |
| } |
| pr_info("%s\n", buf); |
| msleep(20); |
| } |
| |
| kfree(buf); |
| kfree(ldim_matrix_t); |
| } |
| |
| static void ldim_get_matrix_info_SF(void) |
| { |
| unsigned int i, j, len; |
| unsigned int *ldim_matrix_t = NULL; |
| char *buf; |
| |
| ldim_matrix_t = kcalloc(ldim_hist_row*ldim_hist_col, |
| sizeof(unsigned int), GFP_KERNEL); |
| if (ldim_matrix_t == NULL) { |
| LDIMERR("ldim_matrix_t malloc error\n"); |
| return; |
| } |
| |
| len = ldim_blk_col * 10 + 20; |
| buf = kcalloc(len, sizeof(char), GFP_KERNEL); |
| if (buf == NULL) { |
| LDIMERR("print buf malloc error\n"); |
| kfree(ldim_matrix_t); |
| return; |
| } |
| |
| memcpy(ldim_matrix_t, &FDat.SF_BL_matrix[0], |
| ldim_blk_col*ldim_blk_row*sizeof(unsigned int)); |
| |
| pr_info("%s:\n", __func__); |
| for (i = 0; i < ldim_blk_row; i++) { |
| len = 0; |
| for (j = 0; j < ldim_blk_col; j++) { |
| len += sprintf(buf+len, "\t%4d", |
| ldim_matrix_t[ldim_blk_col*i+j]); |
| } |
| pr_info("%s\n", buf); |
| msleep(20); |
| } |
| |
| kfree(buf); |
| kfree(ldim_matrix_t); |
| } |
| |
| static void ldim_get_matrix_info_4(void) |
| { |
| unsigned int i, j, k, len; |
| unsigned int *ldim_matrix_t = NULL; |
| char *buf; |
| |
| ldim_matrix_t = kcalloc(ldim_hist_row*ldim_hist_col, |
| 16*sizeof(unsigned int), GFP_KERNEL); |
| if (ldim_matrix_t == NULL) { |
| LDIMERR("ldim_matrix_t malloc error\n"); |
| return; |
| } |
| |
| len = 3 * ldim_blk_col * 10 + 20; |
| buf = kcalloc(len, sizeof(char), GFP_KERNEL); |
| if (buf == NULL) { |
| LDIMERR("print buf malloc error\n"); |
| kfree(ldim_matrix_t); |
| return; |
| } |
| |
| memcpy(ldim_matrix_t, &FDat.last_STA1_MaxRGB[0], |
| ldim_blk_col*ldim_blk_row*3*sizeof(unsigned int)); |
| |
| pr_info("%s:\n", __func__); |
| for (i = 0; i < ldim_blk_row; i++) { |
| len = 0; |
| for (j = 0; j < ldim_blk_col; j++) { |
| len += sprintf(buf+len, "\tcol %d:", ldim_blk_col); |
| for (k = 0; k < 3; k++) { |
| len += sprintf(buf+len, "\t%4d", |
| ldim_matrix_t[3*ldim_blk_col*i+j*3+k]); |
| } |
| len += sprintf(buf+len, "\n"); |
| } |
| pr_info("%s\n", buf); |
| msleep(20); |
| } |
| |
| kfree(buf); |
| kfree(ldim_matrix_t); |
| } |
| |
| static void ldim_get_matrix_info_alpha(void) |
| { |
| unsigned int i, j, len; |
| unsigned int *ldim_matrix_t = NULL; |
| char *buf; |
| |
| ldim_matrix_t = kcalloc(ldim_hist_row*ldim_hist_col, |
| sizeof(unsigned int), GFP_KERNEL); |
| if (ldim_matrix_t == NULL) { |
| LDIMERR("ldim_matrix_t malloc error\n"); |
| return; |
| } |
| |
| len = ldim_blk_col * 10 + 20; |
| buf = kcalloc(len, sizeof(char), GFP_KERNEL); |
| if (buf == NULL) { |
| LDIMERR("print buf malloc error\n"); |
| kfree(ldim_matrix_t); |
| return; |
| } |
| |
| memcpy(ldim_matrix_t, &FDat.TF_BL_alpha[0], |
| ldim_blk_col*ldim_blk_row*sizeof(unsigned int)); |
| |
| pr_info("%s:\n", __func__); |
| for (i = 0; i < ldim_blk_row; i++) { |
| len = 0; |
| for (j = 0; j < ldim_blk_col; j++) { |
| len += sprintf(buf+len, "\t%4d", |
| ldim_matrix_t[ldim_blk_col*i+j]); |
| } |
| pr_info("%s\n", buf); |
| msleep(20); |
| } |
| |
| kfree(buf); |
| kfree(ldim_matrix_t); |
| } |
| |
| static void ldim_get_matrix_info_max_rgb(void) |
| { |
| unsigned int i, j, len; |
| unsigned int *p = NULL; |
| char *buf; |
| |
| p = kcalloc(ldim_blk_col*ldim_blk_row, |
| sizeof(unsigned int), GFP_KERNEL); |
| if (p == NULL) { |
| LDIMERR("ldim_matrix_t malloc error\n"); |
| return; |
| } |
| |
| len = ldim_blk_col * 30 + 20; |
| buf = kcalloc(len, sizeof(char), GFP_KERNEL); |
| if (buf == NULL) { |
| LDIMERR("print buf malloc error\n"); |
| kfree(p); |
| return; |
| } |
| |
| memcpy(p, ldim_driver.max_rgb, |
| ldim_blk_col*ldim_blk_row*sizeof(unsigned int)); |
| |
| pr_info("%s max_rgb:\n", __func__); |
| for (i = 0; i < ldim_blk_row; i++) { |
| len = 0; |
| for (j = 0; j < ldim_blk_col; j++) { |
| len += sprintf(buf+len, "\t(R:%4d, G:%4d, B:%4d)", |
| (*(p + j + i*ldim_blk_col))&0x3ff, |
| (*(p + j + i*ldim_blk_col)>>10)&0x3ff, |
| (*(p + j + i*ldim_blk_col)>>20)&0x3ff); |
| if ((j + 1) % 4 == 0) |
| len += sprintf(buf+len, "\n\n"); |
| } |
| pr_info("%s\n\n", buf); |
| msleep(20); |
| } |
| |
| kfree(buf); |
| kfree(p); |
| } |
| |
| static void ldim_get_matrix(unsigned int *data, unsigned int reg_sel) |
| { |
| /* gMatrix_LUT: s12*100 */ |
| if (reg_sel == 0) |
| LDIM_RD_BASE_LUT(REG_LD_BLK_VIDX_BASE, data, 16, 32); |
| else if (reg_sel == 3) |
| ldim_get_matrix_info_TF(); |
| else if (reg_sel == 4) |
| ldim_get_matrix_info_SF(); |
| else if (reg_sel == 5) |
| ldim_get_matrix_info_4(); |
| else if (reg_sel == 6) |
| ldim_get_matrix_info_alpha(); |
| else if (reg_sel == 7) |
| ldim_get_matrix_info_max_rgb(); |
| else if (reg_sel == REG_LD_LUT_HDG_BASE) |
| LDIM_RD_BASE_LUT_2(REG_LD_LUT_HDG_BASE, data, 10, 32); |
| else if (reg_sel == REG_LD_LUT_VHK_BASE) |
| LDIM_RD_BASE_LUT_2(REG_LD_LUT_VHK_BASE, data, 10, 32); |
| else if (reg_sel == REG_LD_LUT_VDG_BASE) |
| LDIM_RD_BASE_LUT_2(REG_LD_LUT_VDG_BASE, data, 10, 32); |
| } |
| |
| static void ldim_get_matrix_info(void) |
| { |
| unsigned int i, j, len; |
| unsigned short *ldim_matrix_t = NULL; |
| unsigned short *ldim_matrix_spi_t = NULL; |
| char *buf; |
| |
| ldim_matrix_t = kcalloc(ldim_hist_row*ldim_hist_col, |
| sizeof(unsigned short), GFP_KERNEL); |
| if (ldim_matrix_t == NULL) { |
| LDIMERR("ldim_matrix_t malloc error\n"); |
| return; |
| } |
| ldim_matrix_spi_t = kcalloc(ldim_hist_row*ldim_hist_col, |
| sizeof(unsigned short), GFP_KERNEL); |
| if (ldim_matrix_spi_t == NULL) { |
| LDIMERR("ldim_matrix_spi_t malloc error\n"); |
| kfree(ldim_matrix_t); |
| return; |
| } |
| |
| len = ldim_blk_col * 10 + 20; |
| buf = kcalloc(len, sizeof(char), GFP_KERNEL); |
| if (buf == NULL) { |
| LDIMERR("print buf malloc error\n"); |
| kfree(ldim_matrix_t); |
| kfree(ldim_matrix_spi_t); |
| return; |
| } |
| |
| memcpy(ldim_matrix_t, &ldim_driver.local_ldim_matrix[0], |
| ldim_blk_col*ldim_blk_row*sizeof(unsigned short)); |
| memcpy(ldim_matrix_spi_t, |
| &ldim_driver.ldim_matrix_buf[0], |
| ldim_blk_col*ldim_blk_row*sizeof(unsigned short)); |
| |
| pr_info("%s:\n", __func__); |
| for (i = 0; i < ldim_blk_row; i++) { |
| len = 0; |
| for (j = 0; j < ldim_blk_col; j++) { |
| len += sprintf(buf+len, "\t%4d", |
| ldim_matrix_t[ldim_blk_col*i+j]); |
| } |
| pr_info("%s\n", buf); |
| msleep(20); |
| } |
| |
| pr_info("current black_frm: %d\n", ldim_fw_para.black_frm); |
| pr_info("ldim_dev brightness transfer_matrix:\n"); |
| for (i = 0; i < ldim_blk_row; i++) { |
| len = 0; |
| for (j = 0; j < ldim_blk_col; j++) { |
| len += sprintf(buf+len, "\t%4d", |
| ldim_matrix_spi_t[ldim_blk_col*i+j]); |
| } |
| pr_info("%s\n", buf); |
| msleep(20); |
| } |
| pr_info("\n"); |
| |
| kfree(buf); |
| kfree(ldim_matrix_t); |
| kfree(ldim_matrix_spi_t); |
| } |
| |
| static void ldim_nPRM_bl_matrix_info(void) |
| { |
| unsigned int i, j, len; |
| unsigned int ldim_matrix_t[LD_BLKREGNUM] = {0}; |
| char *buf; |
| |
| len = ldim_blk_col * 10 + 20; |
| buf = kcalloc(len, sizeof(char), GFP_KERNEL); |
| if (buf == NULL) { |
| LDIMERR("print buf malloc error\n"); |
| return; |
| } |
| |
| memcpy(&ldim_matrix_t[0], &nPRM.BL_matrix[0], |
| ldim_blk_col*ldim_blk_row*sizeof(unsigned short)); |
| |
| pr_info("%s and spi info:\n", __func__); |
| for (i = 0; i < ldim_blk_row; i++) { |
| len = 0; |
| for (j = 0; j < ldim_blk_col; j++) { |
| len += sprintf(buf+len, "\t0x%x", |
| ldim_matrix_t[ldim_blk_col*i+j]); |
| } |
| pr_info("%s\n", buf); |
| msleep(20); |
| } |
| |
| kfree(buf); |
| } |
| |
| static void ldim_get_test_matrix_info(void) |
| { |
| unsigned int i, n, len; |
| unsigned short *ldim_matrix_t = ldim_driver.ldim_test_matrix; |
| char *buf; |
| |
| n = ldim_blk_col * ldim_blk_row; |
| len = n * 10 + 20; |
| buf = kcalloc(len, sizeof(char), GFP_KERNEL); |
| if (buf == NULL) { |
| LDIMERR("print buf malloc error\n"); |
| return; |
| } |
| |
| pr_info("%s:\n", __func__); |
| pr_info("ldim test_mode: %d, test_matrix:\n", ldim_test_en); |
| len = 0; |
| for (i = 1; i < n; i++) |
| len += sprintf(buf+len, "\t%4d", ldim_matrix_t[i]); |
| pr_info("%s\n", buf); |
| |
| kfree(buf); |
| } |
| |
| static void ldim_sel_int_matrix_mute_print(unsigned int n, |
| unsigned int *matrix) |
| { |
| unsigned int i, len; |
| unsigned int *ldim_matrix_t = NULL; |
| char *buf; |
| |
| ldim_matrix_t = kcalloc(n, sizeof(unsigned int), GFP_KERNEL); |
| if (ldim_matrix_t == NULL) |
| return; |
| |
| len = n * 10 + 20; |
| buf = kcalloc(len, sizeof(char), GFP_KERNEL); |
| if (buf == NULL) { |
| kfree(ldim_matrix_t); |
| return; |
| } |
| |
| memcpy(ldim_matrix_t, matrix, (n * sizeof(unsigned int))); |
| |
| len = 0; |
| for (i = 0; i < n; i++) |
| len += sprintf(buf+len, " %d", ldim_matrix_t[i]); |
| pr_info("for_tool:%s\n", buf); |
| |
| kfree(buf); |
| kfree(ldim_matrix_t); |
| } |
| |
| static void ldim_matrix_bl_matrix_mute_print(void) |
| { |
| unsigned int i, n, len; |
| unsigned short *ldim_matrix_t = NULL; |
| char *buf; |
| |
| n = ldim_hist_row * ldim_hist_col; |
| ldim_matrix_t = kcalloc(n, sizeof(unsigned short), GFP_KERNEL); |
| if (ldim_matrix_t == NULL) |
| return; |
| |
| len = n * 8 + 20; |
| buf = kcalloc(len, sizeof(char), GFP_KERNEL); |
| if (buf == NULL) { |
| kfree(ldim_matrix_t); |
| return; |
| } |
| |
| memcpy(ldim_matrix_t, ldim_driver.local_ldim_matrix, |
| (n * sizeof(unsigned short))); |
| |
| len = 0; |
| for (i = 0; i < n; i++) |
| len += sprintf(buf+len, " %d", ldim_matrix_t[i]); |
| pr_info("for_tool: %d %d%s\n", ldim_hist_row, ldim_hist_col, buf); |
| |
| kfree(buf); |
| kfree(ldim_matrix_t); |
| } |
| |
| static void ldim_matrix_histgram_mute_print(void) |
| { |
| unsigned int i, j, k, len; |
| unsigned int *p = NULL; |
| char *buf; |
| |
| len = ldim_hist_row * ldim_hist_col * 16; |
| p = kcalloc(len, sizeof(unsigned int), GFP_KERNEL); |
| if (p == NULL) |
| return; |
| |
| len = len * 10 + 20; |
| buf = kcalloc(len, sizeof(char), GFP_KERNEL); |
| if (buf == NULL) { |
| kfree(p); |
| return; |
| } |
| |
| memcpy(p, ldim_driver.hist_matrix, |
| ldim_hist_row*ldim_hist_col*16*sizeof(unsigned int)); |
| |
| len = 0; |
| for (i = 0; i < ldim_hist_row; i++) { |
| for (j = 0; j < ldim_hist_col; j++) { |
| for (k = 0; k < 16; k++) { |
| len += sprintf(buf+len, " 0x%x", |
| *(p+i*16*ldim_hist_col+j*16+k)); |
| } |
| } |
| } |
| pr_info("for_tool: %d 16%s\n", (ldim_hist_row * ldim_hist_col), buf); |
| |
| kfree(buf); |
| kfree(p); |
| } |
| |
| static void ldim_matrix_max_rgb_mute_print(void) |
| { |
| unsigned int i, j, len; |
| unsigned int *p = NULL; |
| char *buf; |
| |
| len = ldim_blk_col * ldim_blk_row; |
| p = kcalloc(len, sizeof(unsigned int), GFP_KERNEL); |
| if (p == NULL) |
| return; |
| |
| len = len * 30 + 20; |
| buf = kcalloc(len, sizeof(char), GFP_KERNEL); |
| if (buf == NULL) { |
| kfree(p); |
| return; |
| } |
| |
| memcpy(p, ldim_driver.max_rgb, |
| ldim_blk_col*ldim_blk_row*sizeof(unsigned int)); |
| |
| len = 0; |
| for (i = 0; i < ldim_blk_row; i++) { |
| for (j = 0; j < ldim_blk_col; j++) { |
| len += sprintf(buf+len, " %d %d %d", |
| (*(p + j + i*ldim_blk_col))&0x3ff, |
| (*(p + j + i*ldim_blk_col)>>10)&0x3ff, |
| (*(p + j + i*ldim_blk_col)>>20)&0x3ff); |
| } |
| } |
| pr_info("for_tool: %d 3%s\n", (ldim_hist_row * ldim_hist_col), buf); |
| |
| kfree(buf); |
| kfree(p); |
| } |
| |
| static void ldim_matrix_SF_matrix_mute_print(void) |
| { |
| unsigned int i, n, len; |
| unsigned int *ldim_matrix_t = NULL; |
| char *buf; |
| |
| n = ldim_hist_row * ldim_hist_col; |
| ldim_matrix_t = kcalloc(n, sizeof(unsigned int), GFP_KERNEL); |
| if (ldim_matrix_t == NULL) |
| return; |
| |
| len = n * 10 + 20; |
| buf = kcalloc(len, sizeof(char), GFP_KERNEL); |
| if (buf == NULL) { |
| kfree(ldim_matrix_t); |
| return; |
| } |
| |
| memcpy(ldim_matrix_t, FDat.SF_BL_matrix, (n * sizeof(unsigned int))); |
| |
| len = 0; |
| for (i = 0; i < n; i++) |
| len += sprintf(buf+len, " %d", ldim_matrix_t[i]); |
| pr_info("for_tool: %d %d%s\n", ldim_hist_row, ldim_hist_col, buf); |
| |
| kfree(buf); |
| kfree(ldim_matrix_t); |
| } |
| |
| static void ldim_matrix_LD_remap_LUT_mute_print(void) |
| { |
| unsigned int i, j, n, len; |
| char *buf; |
| |
| n = 16 * 32; |
| len = n * 8 + 20; |
| buf = kcalloc(len, sizeof(char), GFP_KERNEL); |
| if (buf == NULL) { |
| LDIMERR("print buf malloc error\n"); |
| return; |
| } |
| |
| len = 0; |
| for (i = 0; i < 16; i++) { |
| for (j = 0; j < 32; j++) |
| len += sprintf(buf+len, " %d", LD_remap_lut[i][j]); |
| } |
| |
| pr_info("for_tool: 16 32%s\n", buf); |
| |
| kfree(buf); |
| } |
| |
| static void ldim_matrix_LD_remap_LUT_mute_line_print(int index) |
| { |
| unsigned int j, len; |
| char *buf; |
| |
| if (index >= 16) |
| return; |
| |
| len = 32 * 8 + 20; |
| buf = kcalloc(len, sizeof(char), GFP_KERNEL); |
| if (buf == NULL) { |
| LDIMERR("print buf malloc error\n"); |
| return; |
| } |
| |
| len = 0; |
| for (j = 0; j < 32; j++) |
| len += sprintf(buf+len, " %d", LD_remap_lut[index][j]); |
| |
| pr_info("for_tool: %d%s\n", index, buf); |
| |
| kfree(buf); |
| } |
| |
| static void ldim_test_matrix_mute_print(void) |
| { |
| unsigned int i, n, len; |
| unsigned short *p = ldim_driver.ldim_test_matrix; |
| char *buf; |
| |
| n = ldim_blk_col * ldim_blk_row; |
| len = n * 10 + 20; |
| buf = kcalloc(len, sizeof(char), GFP_KERNEL); |
| if (buf == NULL) |
| return; |
| |
| len = 0; |
| for (i = 0; i < n; i++) |
| len += sprintf(buf+len, " %d", p[i]); |
| pr_info("for_tool: %d %d%s\n", ldim_blk_row, ldim_blk_col, buf); |
| |
| kfree(buf); |
| } |
| |
| static void ldim_set_matrix(unsigned int *data, unsigned int reg_sel, |
| unsigned int cnt) |
| { |
| /* gMatrix_LUT: s12*100 */ |
| if (reg_sel == 0) |
| LDIM_WR_BASE_LUT(REG_LD_BLK_VIDX_BASE, data, 16, 32); |
| else if (reg_sel == 2) |
| LDIM_WR_BASE_LUT(REG_LD_LUT_VHK_NEGPOS_BASE, data, 16, 32); |
| else if (reg_sel == 3) |
| LDIM_WR_BASE_LUT(REG_LD_LUT_VHO_NEGPOS_BASE, data, 16, 4); |
| else if (reg_sel == REG_LD_LUT_HDG_BASE) |
| LDIM_WR_BASE_LUT(REG_LD_LUT_HDG_BASE, data, 16, cnt); |
| else if (reg_sel == REG_LD_LUT_VHK_BASE) |
| LDIM_WR_BASE_LUT(REG_LD_LUT_VHK_BASE, data, 16, cnt); |
| else if (reg_sel == REG_LD_LUT_VDG_BASE) |
| LDIM_WR_BASE_LUT(REG_LD_LUT_VDG_BASE, data, 16, cnt); |
| } |
| |
| static void ldim_remap_ctrl(unsigned char status) |
| { |
| unsigned int temp; |
| |
| temp = ldim_matrix_update_en; |
| if (status) { |
| ldim_matrix_update_en = 0; |
| LDIM_WR_32Bits(0x0a, 0x706); |
| msleep(20); |
| ldim_matrix_update_en = temp; |
| } else { |
| ldim_matrix_update_en = 0; |
| LDIM_WR_32Bits(0x0a, 0x600); |
| msleep(20); |
| ldim_matrix_update_en = temp; |
| } |
| LDIMPR("%s: %d\n", __func__, status); |
| } |
| |
| static void ldim_func_ctrl(unsigned char status) |
| { |
| if (status) { |
| /* enable other flag */ |
| ldim_top_en = 1; |
| ldim_hist_en = 1; |
| ldim_alg_en = 1; |
| /* enable update */ |
| ldim_avg_update_en = 1; |
| /*ldim_matrix_update_en = 1;*/ |
| |
| ldim_remap_ctrl(ldim_remap_en); |
| } else { |
| /* disable remap */ |
| ldim_remap_ctrl(0); |
| /* disable update */ |
| ldim_avg_update_en = 0; |
| /*ldim_matrix_update_en = 0;*/ |
| /* disable other flag */ |
| ldim_top_en = 0; |
| ldim_hist_en = 0; |
| ldim_alg_en = 0; |
| |
| /* refresh system brightness */ |
| ldim_level_update = 1; |
| } |
| LDIMPR("%s: %d\n", __func__, status); |
| } |
| |
| static int ldim_on_init(void) |
| { |
| int ret = 0; |
| |
| if (ldim_debug_print) |
| LDIMPR("%s\n", __func__); |
| |
| /* init ldim */ |
| ldim_stts_initial(ldim_config.hsize, ldim_config.vsize, |
| ldim_hist_row, ldim_hist_col); |
| LDIM_Initial(ldim_config.hsize, ldim_config.vsize, |
| ldim_blk_row, ldim_blk_col, ldim_config.bl_mode, 1, 0); |
| |
| ldim_func_ctrl(0); /* default disable ldim function */ |
| |
| if (ldim_driver.pinmux_ctrl) |
| ldim_driver.pinmux_ctrl(1); |
| ldim_on_flag = 1; |
| ldim_level_update = 1; |
| |
| return ret; |
| } |
| |
| static int ldim_power_on(void) |
| { |
| int ret = 0; |
| |
| LDIMPR("%s\n", __func__); |
| |
| ldim_func_ctrl(ldim_func_en); |
| |
| if (ldim_driver.device_power_on) |
| ldim_driver.device_power_on(); |
| ldim_on_flag = 1; |
| ldim_level_update = 1; |
| |
| return ret; |
| } |
| static int ldim_power_off(void) |
| { |
| int ret = 0; |
| |
| LDIMPR("%s\n", __func__); |
| |
| ldim_on_flag = 0; |
| if (ldim_driver.device_power_off) |
| ldim_driver.device_power_off(); |
| |
| ldim_func_ctrl(0); |
| |
| return ret; |
| } |
| |
| static int ldim_set_level(unsigned int level) |
| { |
| struct aml_bl_drv_s *bl_drv = aml_bl_get_driver(); |
| unsigned int level_max, level_min; |
| |
| ldim_brightness_level = level; |
| |
| if (ldim_brightness_bypass) |
| return 0; |
| |
| level_max = bl_drv->bconf->level_max; |
| level_min = bl_drv->bconf->level_min; |
| |
| level = ((level - level_min) * (LD_DATA_MAX - ldim_data_min)) / |
| (level_max - level_min) + ldim_data_min; |
| level &= 0xfff; |
| litgain = (unsigned long)level; |
| ldim_level_update = 1; |
| |
| return 0; |
| } |
| |
| static void ldim_test_ctrl(int flag) |
| { |
| if (flag) /* when enable lcd bist pattern, bypass ldim function */ |
| ldim_func_bypass = 1; |
| else |
| ldim_func_bypass = 0; |
| LDIMPR("%s: ldim_func_bypass = %d\n", __func__, ldim_func_bypass); |
| } |
| |
| static struct aml_ldim_driver_s ldim_driver = { |
| .valid_flag = 0, /* default invalid, active when bl_ctrl_method=ldim */ |
| .dev_index = 0xff, |
| .static_pic_flag = 0, |
| .vsync_change_flag = 0, |
| .pinmux_flag = 0xff, |
| .ldim_conf = &ldim_config, |
| .ldev_conf = NULL, |
| .ldim_matrix_buf = NULL, |
| .hist_matrix = NULL, |
| .max_rgb = NULL, |
| .ldim_test_matrix = NULL, |
| .local_ldim_matrix = NULL, |
| .init = ldim_on_init, |
| .power_on = ldim_power_on, |
| .power_off = ldim_power_off, |
| .set_level = ldim_set_level, |
| .test_ctrl = ldim_test_ctrl, |
| .config_print = NULL, |
| .pinmux_ctrl = NULL, |
| .pwm_vs_update = NULL, |
| .device_power_on = NULL, |
| .device_power_off = NULL, |
| .device_bri_update = NULL, |
| .device_bri_check = NULL, |
| .spi_dev = NULL, |
| .spi_info = NULL, |
| }; |
| |
| struct aml_ldim_driver_s *aml_ldim_get_driver(void) |
| { |
| return &ldim_driver; |
| } |
| |
| /* ****************************************************** |
| * local dimming dummy function for virtual ldim dev |
| * ****************************************************** |
| */ |
| static int ldim_virtual_smr(unsigned short *buf, unsigned char len) |
| { |
| return 0; |
| } |
| |
| static int ldim_virtual_power_on(void) |
| { |
| return 0; |
| } |
| |
| static int ldim_virtual_power_off(void) |
| { |
| return 0; |
| } |
| |
| static int ldim_virtual_driver_update(struct aml_ldim_driver_s *ldim_drv) |
| { |
| ldim_drv->device_power_on = ldim_virtual_power_on; |
| ldim_drv->device_power_off = ldim_virtual_power_off; |
| ldim_drv->device_bri_update = ldim_virtual_smr; |
| |
| return 0; |
| } |
| |
| static int ldim_dev_add_virtual_driver(struct aml_ldim_driver_s *ldim_drv) |
| { |
| LDIMPR("%s\n", __func__); |
| |
| ldim_virtual_driver_update(ldim_drv); |
| ldim_drv->init(); |
| |
| return 0; |
| } |
| /* ****************************************************** */ |
| |
| static int ldim_open(struct inode *inode, struct file *file) |
| { |
| struct ldim_dev_s *devp; |
| /* Get the per-device structure that contains this cdev */ |
| devp = container_of(inode->i_cdev, struct ldim_dev_s, cdev); |
| file->private_data = devp; |
| return 0; |
| } |
| |
| static int ldim_release(struct inode *inode, struct file *file) |
| { |
| file->private_data = NULL; |
| return 0; |
| } |
| |
| static long ldim_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
| { |
| int ret = 0; |
| struct ldim_param_s *db_para; |
| |
| switch (cmd) { |
| case LDIM_IOC_PARA: |
| if (!LDIM_DATA_FROM_DB) |
| return -EINVAL; |
| |
| db_para = kzalloc(sizeof(struct ldim_param_s), GFP_KERNEL); |
| if (db_para == NULL) { |
| LDIMERR("db_para malloc error\n"); |
| return -EINVAL; |
| } |
| ldim_dev.ldim_db_para = db_para; |
| if (copy_from_user(ldim_dev.ldim_db_para, (void __user *)arg, |
| sizeof(struct ldim_param_s))) { |
| ldim_dev.ldim_db_para = NULL; |
| kfree(db_para); |
| return -EINVAL; |
| } |
| |
| LDIM_Initial(ldim_config.hsize, ldim_config.vsize, |
| ldim_blk_row, ldim_blk_col, |
| ldim_config.bl_mode, 1, 0); |
| ldim_dev.ldim_db_para = NULL; |
| kfree(db_para); |
| break; |
| |
| default: |
| ret = -EINVAL; |
| break; |
| } |
| |
| return ret; |
| } |
| |
| #ifdef CONFIG_COMPAT |
| static long ldim_compat_ioctl(struct file *file, unsigned int cmd, |
| unsigned long arg) |
| { |
| unsigned long ret; |
| |
| arg = (unsigned long)compat_ptr(arg); |
| ret = ldim_ioctl(file, cmd, arg); |
| return ret; |
| } |
| #endif |
| |
| static const struct file_operations ldim_fops = { |
| .owner = THIS_MODULE, |
| .open = ldim_open, |
| .release = ldim_release, |
| .unlocked_ioctl = ldim_ioctl, |
| #ifdef CONFIG_COMPAT |
| .compat_ioctl = ldim_compat_ioctl, |
| #endif |
| }; |
| |
| static ssize_t ldim_attr_show(struct class *cla, |
| struct class_attribute *attr, char *buf) |
| { |
| ssize_t len = 0; |
| |
| len += sprintf(buf+len, |
| "\necho hist > /sys/class/aml_ldim/attr\n"); |
| len += sprintf(buf+len, |
| "echo maxrgb > /sys/class/aml_ldim/attr\n"); |
| len += sprintf(buf+len, |
| "echo matrix > /sys/class/aml_ldim/attr\n"); |
| len += sprintf(buf+len, |
| "echo ldim_matrix_get 7 > /sys/class/aml_ldim/attr\n"); |
| len += sprintf(buf+len, |
| "echo ldim_matrix_get 0/1/2/3 > /sys/class/aml_ldim/attr\n"); |
| len += sprintf(buf+len, |
| "echo info > /sys/class/aml_ldim/attr\n"); |
| len += sprintf(buf+len, |
| "echo alg_info > /sys/class/aml_ldim/attr\n"); |
| len += sprintf(buf+len, |
| "echo litgain 4096 > /sys/class/aml_ldim/attr\n"); |
| len += sprintf(buf+len, |
| "echo test_mode 1 > /sys/class/aml_ldim/attr\n"); |
| len += sprintf(buf+len, |
| "echo test_set 0 4095 > /sys/class/aml_ldim/attr\n"); |
| len += sprintf(buf+len, |
| "echo test_set_all 4095 > /sys/class/aml_ldim/attr\n"); |
| |
| len += sprintf(buf+len, |
| "echo ldim_stts_init 8 2 > /sys/class/aml_ldim/attr\n"); |
| len += sprintf(buf+len, |
| "echo ldim_init 8 2 0 1 0 > /sys/class/aml_ldim/attr\n"); |
| |
| len += sprintf(buf+len, |
| "echo fw_LD_ThSF_l 1600 > /sys/class/aml_ldim/attr\n"); |
| len += sprintf(buf+len, |
| "echo fw_LD_ThTF_l 32 > /sys/class/aml_ldim/attr\n"); |
| len += sprintf(buf+len, |
| "echo boost_gain 4 > /sys/class/aml_ldim/attr\n"); |
| len += sprintf(buf+len, |
| "echo alpha_delta 0 > /sys/class/aml_ldim/attr\n"); |
| len += sprintf(buf+len, |
| "echo boost_gain_neg 4 > /sys/class/aml_ldim/attr\n"); |
| len += sprintf(buf+len, |
| "echo TF_alpha 256 > /sys/class/aml_ldim/attr\n"); |
| len += sprintf(buf+len, |
| "echo lpf_gain 0 > /sys/class/aml_ldim/attr\n"); |
| len += sprintf(buf+len, |
| "echo lpf_res 0 > /sys/class/aml_ldim/attr\n"); |
| len += sprintf(buf+len, |
| "echo rgb_base 128 > /sys/class/aml_ldim/attr\n"); |
| |
| len += sprintf(buf+len, |
| "echo ov_gain 16 > /sys/class/aml_ldim/attr\n"); |
| len += sprintf(buf+len, |
| "echo avg_gain 2048 > /sys/class/aml_ldim/attr\n"); |
| |
| len += sprintf(buf+len, |
| "echo LPF_method 3 > /sys/class/aml_ldim/attr\n"); |
| len += sprintf(buf+len, |
| "echo LD_TF_STEP_TH 100 > /sys/class/aml_ldim/attr\n"); |
| len += sprintf(buf+len, |
| "echo TF_step_method 3 > /sys/class/aml_ldim/attr\n"); |
| len += sprintf(buf+len, |
| "echo TF_FRESH_BL 8 > /sys/class/aml_ldim/attr\n"); |
| |
| len += sprintf(buf+len, |
| "echo TF_BLK_FRESH_BL 5 > /sys/class/aml_ldim/attr\n"); |
| len += sprintf(buf+len, |
| "echo side_blk_diff_th 100 > /sys/class/aml_ldim/attr\n"); |
| len += sprintf(buf+len, |
| "echo bbd_th 200 > /sys/class/aml_ldim/attr\n"); |
| len += sprintf(buf+len, |
| "echo bbd_detect_en 1 > /sys/class/aml_ldim/attr\n"); |
| len += sprintf(buf+len, |
| "echo diff_blk_luma_en 1 > /sys/class/aml_ldim/attr\n"); |
| |
| len += sprintf(buf+len, |
| "echo bl_remap_curve > /sys/class/aml_ldim/attr\n"); |
| len += sprintf(buf+len, |
| "echo fw_LD_Whist > /sys/class/aml_ldim/attr\n"); |
| len += sprintf(buf+len, |
| "echo LD_remap_lut > /sys/class/aml_ldim/attr\n"); |
| |
| len += sprintf(buf+len, |
| "echo Sf_bypass 0 > /sys/class/aml_ldim/attr\n"); |
| len += sprintf(buf+len, |
| "echo Boost_light_bypass 0 > /sys/class/aml_ldim/attr\n"); |
| len += sprintf(buf+len, |
| "echo Lpf_bypass 0 > /sys/class/aml_ldim/attr\n"); |
| len += sprintf(buf+len, |
| "echo Ld_remap_bypass 0 > /sys/class/aml_ldim/attr\n"); |
| |
| len += sprintf(buf+len, |
| "echo fw_hist_print 1 > /sys/class/aml_ldim/attr\n"); |
| len += sprintf(buf+len, |
| "echo fw_print_frequent 8 > /sys/class/aml_ldim/attr\n"); |
| len += sprintf(buf+len, |
| "echo Dbprint_lv 1 > /sys/class/aml_ldim/attr\n"); |
| |
| return len; |
| } |
| |
| static ssize_t ldim_attr_store(struct class *cla, |
| struct class_attribute *attr, const char *buf, size_t len) |
| { |
| unsigned int n = 0; |
| char *buf_orig, *ps, *token; |
| /*char *parm[520] = {NULL};*/ |
| char **parm = NULL; |
| char str[3] = {' ', '\n', '\0'}; |
| unsigned int size; |
| int i, j; |
| char *pr_buf; |
| ssize_t pr_len = 0; |
| |
| unsigned int backlit_mod = 0, ldim_bl_en = 0, ldim_hvcnt_bypass = 0; |
| unsigned long val1 = 0; |
| |
| if (!buf) |
| return len; |
| buf_orig = kstrdup(buf, GFP_KERNEL); |
| if (buf_orig == NULL) { |
| LDIMERR("buf malloc error\n"); |
| return len; |
| } |
| parm = kcalloc(520, sizeof(char *), GFP_KERNEL); |
| if (parm == NULL) { |
| LDIMERR("parm malloc error\n"); |
| kfree(buf_orig); |
| return len; |
| } |
| ps = buf_orig; |
| while (1) { |
| token = strsep(&ps, str); |
| if (token == NULL) |
| break; |
| if (*token == '\0') |
| continue; |
| parm[n++] = token; |
| } |
| |
| if (!strcmp(parm[0], "hist")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| ldim_matrix_histgram_mute_print(); |
| goto ldim_attr_store_end; |
| } |
| } |
| ldim_dump_histgram(); |
| } else if (!strcmp(parm[0], "maxrgb")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| ldim_matrix_max_rgb_mute_print(); |
| goto ldim_attr_store_end; |
| } |
| } |
| ldim_get_matrix_info_max_rgb(); |
| } else if (!strcmp(parm[0], "matrix")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| ldim_matrix_bl_matrix_mute_print(); |
| goto ldim_attr_store_end; |
| } |
| } |
| ldim_get_matrix_info(); |
| } else if (!strcmp(parm[0], "SF_matrix")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| ldim_matrix_SF_matrix_mute_print(); |
| goto ldim_attr_store_end; |
| } |
| } |
| ldim_get_matrix_info_SF(); |
| } else if (!strcmp(parm[0], "db_load")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| pr_info("for_tool:%d\n", LDIM_DATA_FROM_DB); |
| goto ldim_attr_store_end; |
| } |
| if (kstrtoul(parm[1], 10, &val1) < 0) |
| goto ldim_attr_store_err; |
| LDIM_DATA_FROM_DB = val1 ? 1 : 0; |
| } |
| pr_info("LDIM_DATA_FROM_DB: %d\n", LDIM_DATA_FROM_DB); |
| } else if (!strcmp(parm[0], "db_print")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| pr_info("for_tool:%d\n", db_print_flag); |
| goto ldim_attr_store_end; |
| } |
| if (kstrtoul(parm[1], 10, &val1) < 0) |
| goto ldim_attr_store_err; |
| db_print_flag = val1 ? 1 : 0; |
| } |
| pr_info("db_print_flag: %d\n", db_print_flag); |
| } else if (!strcmp(parm[0], "db_dump")) { |
| ldim_db_para_print(&nPRM); |
| } else if (!strcmp(parm[0], "ldim_init")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| pr_info("for_tool:%d %d %d %d %d\n", |
| ldim_blk_row, ldim_blk_col, |
| ldim_config.bl_mode, |
| ldim_config.bl_en, |
| ldim_config.hvcnt_bypass); |
| goto ldim_attr_store_end; |
| } |
| } |
| if (parm[5] != NULL) { |
| if (kstrtouint(parm[1], 10, &ldim_blk_row) < 0) |
| goto ldim_attr_store_err; |
| if (kstrtouint(parm[2], 10, &ldim_blk_col) < 0) |
| goto ldim_attr_store_err; |
| if (kstrtouint(parm[3], 10, &backlit_mod) < 0) |
| goto ldim_attr_store_err; |
| if (kstrtouint(parm[4], 10, &ldim_bl_en) < 0) |
| goto ldim_attr_store_err; |
| if (kstrtouint(parm[5], 10, &ldim_hvcnt_bypass) < 0) |
| goto ldim_attr_store_err; |
| |
| ldim_config.row = ldim_blk_row; |
| ldim_config.col = ldim_blk_col; |
| ldim_config.bl_mode = (unsigned char)backlit_mod; |
| ldim_config.bl_en = (unsigned char)ldim_bl_en; |
| ldim_config.hvcnt_bypass = |
| (unsigned char)ldim_hvcnt_bypass; |
| LDIM_Initial(ldim_config.hsize, ldim_config.vsize, |
| ldim_blk_row, ldim_blk_col, |
| backlit_mod, ldim_bl_en, ldim_hvcnt_bypass); |
| pr_info("**************ldim init ok*************\n"); |
| } |
| pr_info("ldim_init param: %d %d %d %d %d\n", |
| ldim_blk_row, ldim_blk_col, |
| ldim_config.bl_mode, ldim_config.bl_en, |
| ldim_config.hvcnt_bypass); |
| } else if (!strcmp(parm[0], "ldim_stts_init")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| pr_info("for_tool:%d %d\n", |
| ldim_hist_row, ldim_hist_col); |
| goto ldim_attr_store_end; |
| } |
| } |
| if (parm[2] != NULL) { |
| if (kstrtouint(parm[1], 10, &ldim_hist_row) < 0) |
| goto ldim_attr_store_err; |
| if (kstrtouint(parm[2], 10, &ldim_hist_col) < 0) |
| goto ldim_attr_store_err; |
| |
| ldim_stts_initial(ldim_config.hsize, ldim_config.vsize, |
| ldim_hist_row, ldim_hist_col); |
| pr_info("************ldim stts init ok*************\n"); |
| } |
| pr_info("ldim_stts_init param: %d %d\n", |
| ldim_hist_row, ldim_hist_col); |
| } else if (!strcmp(parm[0], "frm_size")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| pr_info("for_tool:%d %d\n", |
| ldim_config.hsize, |
| ldim_config.vsize); |
| goto ldim_attr_store_end; |
| } |
| } |
| pr_info("frm_width: %d, frm_height: %d\n", |
| ldim_config.hsize, ldim_config.vsize); |
| } else if (!strcmp(parm[0], "func")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| pr_info("for_tool:%d\n", ldim_func_en); |
| goto ldim_attr_store_end; |
| } |
| if (kstrtoul(parm[1], 10, &val1) < 0) |
| goto ldim_attr_store_err; |
| ldim_func_en = val1 ? 1 : 0; |
| ldim_func_ctrl(ldim_func_en); |
| } |
| pr_info("ldim_func_en: %d\n", ldim_func_en); |
| } else if (!strcmp(parm[0], "remap")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| pr_info("for_tool:%d\n", ldim_remap_en); |
| goto ldim_attr_store_end; |
| } |
| if (kstrtoul(parm[1], 10, &val1) < 0) |
| goto ldim_attr_store_err; |
| if (val1) { |
| if (ldim_func_en) { |
| ldim_remap_en = 1; |
| ldim_remap_ctrl(1); |
| } else { |
| pr_info( |
| "error: ldim_func is disabled\n"); |
| } |
| } else { |
| ldim_remap_en = 0; |
| ldim_remap_ctrl(0); |
| } |
| } |
| pr_info("ldim_remap_en: %d\n", ldim_remap_en); |
| } else if (!strcmp(parm[0], "demo")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| pr_info("for_tool:%d\n", ldim_demo_en); |
| goto ldim_attr_store_end; |
| } |
| if (kstrtoul(parm[1], 10, &val1) < 0) |
| goto ldim_attr_store_err; |
| if (val1) { |
| if (ldim_remap_en) { |
| ldim_demo_en = 1; |
| nPRM.reg_LD_RGBmapping_demo = 1; |
| LDIM_WR_reg_bits(REG_LD_RGB_MOD, 1, |
| 19, 1); |
| } else { |
| pr_info( |
| "error: ldim_remap is disabled\n"); |
| } |
| } else { |
| ldim_demo_en = 0; |
| nPRM.reg_LD_RGBmapping_demo = 0; |
| LDIM_WR_reg_bits(REG_LD_RGB_MOD, 0, 19, 1); |
| } |
| } |
| pr_info("ldim_demo_en: %d\n", ldim_demo_en); |
| } else if (!strcmp(parm[0], "ldim_matrix_get")) { |
| unsigned int data[32] = {0}; |
| unsigned int k, g, reg_sel = 0; |
| |
| if (parm[1] != NULL) { |
| if (kstrtouint(parm[1], 10, ®_sel) < 0) |
| goto ldim_attr_store_err; |
| |
| pr_buf = kzalloc(sizeof(char) * 200, GFP_KERNEL); |
| if (!pr_buf) { |
| LDIMERR("buf malloc error\n"); |
| goto ldim_attr_store_err; |
| } |
| ldim_get_matrix(&data[0], reg_sel); |
| if ((reg_sel == 0) || (reg_sel == 1)) { |
| pr_info("******ldim matrix info start******\n"); |
| for (k = 0; k < 4; k++) { |
| pr_len = 0; |
| for (g = 0; g < 8; g++) { |
| pr_len += sprintf(pr_buf+pr_len, |
| "\t%d", data[8*k+g]); |
| } |
| pr_info("%s\n", pr_buf); |
| } |
| pr_info("*******ldim matrix info end*******\n"); |
| } |
| kfree(pr_buf); |
| } |
| } else if (!strcmp(parm[0], "ldim_matrix_set")) { |
| unsigned int data_set[32] = {0}; |
| unsigned int reg_sel_1 = 0, k1, cnt1 = 0; |
| unsigned long temp_set[32] = {0}; |
| |
| if (parm[2] != NULL) { |
| if (kstrtouint(parm[1], 10, ®_sel_1) < 0) |
| goto ldim_attr_store_err; |
| if (kstrtouint(parm[2], 10, &cnt1) < 0) |
| goto ldim_attr_store_err; |
| |
| for (k1 = 0; k1 < cnt1; k1++) { |
| if (parm[k1+2] != NULL) { |
| temp_set[k1] = kstrtoul(parm[k1+2], |
| 10, &temp_set[k1]); |
| data_set[k1] = |
| (unsigned int)temp_set[k1]; |
| } |
| } |
| ldim_set_matrix(&data_set[0], reg_sel_1, cnt1); |
| pr_info("***********ldim matrix set over***********\n"); |
| } |
| } else if (!strcmp(parm[0], "nPRM_bl_matrix")) { |
| ldim_nPRM_bl_matrix_info(); |
| pr_info("**************ldim matrix(nPRM) info over*********\n"); |
| } else if (!strcmp(parm[0], "data_min")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| pr_info("for_tool:%d\n", ldim_data_min); |
| goto ldim_attr_store_end; |
| } |
| if (kstrtouint(parm[1], 10, &ldim_data_min) < 0) |
| goto ldim_attr_store_err; |
| |
| ldim_set_level(ldim_brightness_level); |
| } |
| LDIMPR("brightness data_min: %d\n", ldim_data_min); |
| } else if (!strcmp(parm[0], "litgain")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| pr_info("for_tool:%ld\n", litgain); |
| goto ldim_attr_store_end; |
| } |
| if (kstrtoul(parm[1], 10, &litgain) < 0) |
| goto ldim_attr_store_err; |
| } |
| pr_info("litgain = %ld\n", litgain); |
| } else if (!strcmp(parm[0], "brightness_bypass")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| pr_info("for_tool:%d\n", |
| ldim_brightness_bypass); |
| goto ldim_attr_store_end; |
| } |
| if (kstrtoul(parm[1], 10, &val1) < 0) |
| goto ldim_attr_store_err; |
| ldim_brightness_bypass = (unsigned char)val1; |
| if (ldim_brightness_bypass == 0) |
| ldim_set_level(ldim_brightness_level); |
| } |
| pr_info("brightness_bypass = %d\n", ldim_brightness_bypass); |
| } else if (!strcmp(parm[0], "test_mode")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| pr_info("for_tool:%d\n", ldim_test_en); |
| goto ldim_attr_store_end; |
| } |
| if (kstrtoul(parm[1], 10, &val1) < 0) |
| goto ldim_attr_store_err; |
| ldim_test_en = (unsigned char)val1; |
| } |
| LDIMPR("test_mode: %d\n", ldim_test_en); |
| } else if (!strcmp(parm[0], "test_set")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| ldim_test_matrix_mute_print(); |
| goto ldim_attr_store_end; |
| } |
| if (!strcmp(parm[1], "w")) { |
| size = ldim_blk_row * ldim_blk_col; |
| if (parm[size+3] == NULL) |
| goto ldim_attr_store_err; |
| if (kstrtouint(parm[2], 10, &i) < 0) |
| goto ldim_attr_store_err; |
| if (kstrtouint(parm[3], 10, &j) < 0) |
| goto ldim_attr_store_err; |
| if ((i != 1) || (j != size)) |
| goto ldim_attr_store_err; |
| for (i = 0; i < size; i++) { |
| if (kstrtouint(parm[i+4], 10, &j) < 0) |
| goto ldim_attr_store_err; |
| ldim_driver.ldim_test_matrix[i] = |
| (unsigned short)j; |
| } |
| goto ldim_attr_store_end; |
| } |
| } |
| if (parm[2] != NULL) { |
| if (kstrtouint(parm[1], 10, &i) < 0) |
| goto ldim_attr_store_err; |
| if (kstrtouint(parm[2], 10, &j) < 0) |
| goto ldim_attr_store_err; |
| |
| size = ldim_blk_row * ldim_blk_col; |
| if (i < size) { |
| ldim_driver.ldim_test_matrix[i] = |
| (unsigned short)j; |
| LDIMPR("set test_matrix[%d] = %4d\n", i, j); |
| } else { |
| LDIMERR("invalid index for test_matrix[%d]\n", |
| i); |
| } |
| goto ldim_attr_store_end; |
| } |
| ldim_get_test_matrix_info(); |
| } else if (!strcmp(parm[0], "test_set_all")) { |
| if (parm[1] != NULL) { |
| if (kstrtouint(parm[1], 10, &j) < 0) |
| goto ldim_attr_store_err; |
| |
| size = ldim_blk_row * ldim_blk_col; |
| for (i = 0; i < size; i++) { |
| ldim_driver.ldim_test_matrix[i] = |
| (unsigned short)j; |
| } |
| LDIMPR("set all test_matrix to %4d\n", j); |
| goto ldim_attr_store_end; |
| } |
| ldim_get_test_matrix_info(); |
| } else if (!strcmp(parm[0], "rs")) { |
| unsigned int reg_addr = 0, reg_val; |
| |
| if (parm[1] != NULL) { |
| if (kstrtouint(parm[1], 16, ®_addr) < 0) |
| goto ldim_attr_store_err; |
| |
| reg_val = LDIM_RD_32Bits(reg_addr); |
| pr_info("reg_addr: 0x%x=0x%x\n", reg_addr, reg_val); |
| } |
| } else if (!strcmp(parm[0], "ws")) { |
| unsigned int reg_addr = 0, reg_val = 0; |
| |
| if (parm[2] != NULL) { |
| if (kstrtouint(parm[1], 16, ®_addr) < 0) |
| goto ldim_attr_store_err; |
| if (kstrtouint(parm[2], 16, ®_val) < 0) |
| goto ldim_attr_store_err; |
| |
| LDIM_WR_32Bits(reg_addr, reg_val); |
| pr_info("reg_addr: 0x%x=0x%x, readback: 0x%x\n", |
| reg_addr, reg_val, LDIM_RD_32Bits(reg_addr)); |
| } |
| } else if (!strcmp(parm[0], "bl_remap_curve")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| ldim_sel_int_matrix_mute_print( |
| 16, bl_remap_curve); |
| goto ldim_attr_store_end; |
| } |
| } |
| if (parm[16] != NULL) { |
| for (i = 0; i < 16; i++) { |
| if (kstrtouint(parm[i+1], 10, |
| &bl_remap_curve[i]) < 0) { |
| goto ldim_attr_store_err; |
| } |
| } |
| } |
| ldim_bl_remap_curve_print(); |
| } else if (!strcmp(parm[0], "fw_LD_Whist")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| ldim_sel_int_matrix_mute_print( |
| 16, fw_LD_Whist); |
| goto ldim_attr_store_end; |
| } |
| } |
| if (parm[16] != NULL) { |
| for (i = 0; i < 16; i++) { |
| if (kstrtouint(parm[i+1], 10, |
| &fw_LD_Whist[i]) < 0) { |
| goto ldim_attr_store_err; |
| } |
| } |
| } |
| ldim_fw_LD_Whist_print(); |
| } else if (!strcmp(parm[0], "LD_remap_lut")) { |
| if (parm[1] == NULL) { |
| ldim_ld_remap_lut_print(0xff); |
| goto ldim_attr_store_end; |
| } |
| if (!strcmp(parm[1], "r")) { |
| ldim_matrix_LD_remap_LUT_mute_print(); |
| goto ldim_attr_store_end; |
| } |
| if (!strcmp(parm[1], "lr")) { /* line read */ |
| if (kstrtouint(parm[2], 10, &i) < 0) |
| goto ldim_attr_store_err; |
| ldim_matrix_LD_remap_LUT_mute_line_print(i); |
| goto ldim_attr_store_end; |
| } |
| if (!strcmp(parm[1], "w")) { |
| if (parm[515] == NULL) |
| goto ldim_attr_store_err; |
| if (kstrtouint(parm[2], 10, &i) < 0) |
| goto ldim_attr_store_err; |
| if (kstrtouint(parm[3], 10, &j) < 0) |
| goto ldim_attr_store_err; |
| if ((i != 16) || (j != 32)) |
| goto ldim_attr_store_err; |
| for (i = 0; i < 16; i++) { |
| for (j = 0; j < 32; j++) { |
| if (kstrtouint(parm[i*32+j+4], 10, |
| &LD_remap_lut[i][j]) < 0) { |
| goto ldim_attr_store_err; |
| } |
| } |
| } |
| goto ldim_attr_store_end; |
| } |
| if (!strcmp(parm[1], "lw")) { /* line write */ |
| if (kstrtouint(parm[2], 10, &i) < 0) |
| goto ldim_attr_store_err; |
| if (parm[34] != NULL) { |
| for (j = 0; j < 32; j++) { |
| if (kstrtouint(parm[j+3], 10, |
| &LD_remap_lut[i][j]) < 0) { |
| goto ldim_attr_store_err; |
| } |
| } |
| } |
| goto ldim_attr_store_end; |
| } |
| |
| if (kstrtouint(parm[1], 10, &i) < 0) |
| goto ldim_attr_store_err; |
| if (parm[33] != NULL) { |
| for (j = 0; j < 32; j++) { |
| if (kstrtouint(parm[j+2], 10, |
| &LD_remap_lut[i][j]) < 0) { |
| goto ldim_attr_store_err; |
| } |
| } |
| } |
| ldim_ld_remap_lut_print(i); |
| } else if (!strcmp(parm[0], "Sf_bypass")) { |
| if (parm[1] != NULL) { |
| if (kstrtoul(parm[1], 10, &val1) < 0) |
| goto ldim_attr_store_err; |
| ldim_fw_para.Sf_bypass = (unsigned char)val1; |
| } |
| pr_info("Sf_bypass = %d\n", ldim_fw_para.Sf_bypass); |
| } else if (!strcmp(parm[0], "Boost_light_bypass")) { |
| if (parm[1] != NULL) { |
| if (kstrtoul(parm[1], 10, &val1) < 0) |
| goto ldim_attr_store_err; |
| ldim_fw_para.Boost_light_bypass = (unsigned char)val1; |
| } |
| pr_info("Boost_light_bypass = %d\n", |
| ldim_fw_para.Boost_light_bypass); |
| } else if (!strcmp(parm[0], "Lpf_bypass")) { |
| if (parm[1] != NULL) { |
| if (kstrtoul(parm[1], 10, &val1) < 0) |
| goto ldim_attr_store_err; |
| ldim_fw_para.Lpf_bypass = (unsigned char)val1; |
| } |
| pr_info("Lpf_bypass = %d\n", ldim_fw_para.Lpf_bypass); |
| } else if (!strcmp(parm[0], "Ld_remap_bypass")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| pr_info("for_tool:%d\n", |
| ldim_fw_para.Ld_remap_bypass); |
| goto ldim_attr_store_end; |
| } |
| if (kstrtoul(parm[1], 10, &val1) < 0) |
| goto ldim_attr_store_err; |
| ldim_fw_para.Ld_remap_bypass = (unsigned char)val1; |
| } |
| pr_info("Ld_remap_bypass = %d\n", ldim_fw_para.Ld_remap_bypass); |
| } else if (!strcmp(parm[0], "ov_gain")) { |
| if (parm[1] != NULL) { |
| if (kstrtouint(parm[1], 10, &ldim_fw_para.ov_gain) < 0) |
| goto ldim_attr_store_err; |
| } |
| pr_info("ov_gain = %d\n", ldim_fw_para.ov_gain); |
| } else if (!strcmp(parm[0], "fw_LD_ThSF_l")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| pr_info("for_tool:%d\n", |
| ldim_fw_para.fw_LD_ThSF_l); |
| goto ldim_attr_store_end; |
| } |
| if (kstrtouint(parm[1], 10, |
| &ldim_fw_para.fw_LD_ThSF_l) < 0) { |
| goto ldim_attr_store_err; |
| } |
| } |
| pr_info("fw_LD_ThSF_l = %d\n", ldim_fw_para.fw_LD_ThSF_l); |
| } else if (!strcmp(parm[0], "fw_LD_ThTF_l")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| pr_info("for_tool:%d\n", |
| ldim_fw_para.fw_LD_ThTF_l); |
| goto ldim_attr_store_end; |
| } |
| if (kstrtouint(parm[1], 10, |
| &ldim_fw_para.fw_LD_ThTF_l) < 0) { |
| goto ldim_attr_store_err; |
| } |
| } |
| pr_info("fw_LD_ThTF_l = %d\n", ldim_fw_para.fw_LD_ThTF_l); |
| } else if (!strcmp(parm[0], "boost_gain")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| pr_info("for_tool:%d\n", |
| ldim_fw_para.boost_gain); |
| goto ldim_attr_store_end; |
| } |
| if (kstrtouint(parm[1], 10, |
| &ldim_fw_para.boost_gain) < 0) { |
| goto ldim_attr_store_err; |
| } |
| } |
| pr_info("boost_gain = %d\n", ldim_fw_para.boost_gain); |
| } else if (!strcmp(parm[0], "boost_gain_neg")) { |
| if (parm[1] != NULL) { |
| if (kstrtouint(parm[1], 10, |
| &ldim_fw_para.boost_gain_neg) < 0) |
| goto ldim_attr_store_err; |
| } |
| pr_info("boost_gain_neg = %d\n", ldim_fw_para.boost_gain_neg); |
| } else if (!strcmp(parm[0], "alpha_delta")) { |
| if (parm[1] != NULL) { |
| if (kstrtouint(parm[1], 10, |
| &ldim_fw_para.alpha_delta) < 0) |
| goto ldim_attr_store_err; |
| } |
| pr_info("alpha_delta = %d\n", ldim_fw_para.alpha_delta); |
| } else if (!strcmp(parm[0], "TF_alpha")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| pr_info("for_tool:%d\n", |
| ldim_fw_para.TF_alpha); |
| goto ldim_attr_store_end; |
| } |
| if (kstrtouint(parm[1], 10, &ldim_fw_para.TF_alpha) < 0) |
| goto ldim_attr_store_err; |
| } |
| pr_info("TF_alpha = %d\n", ldim_fw_para.TF_alpha); |
| } else if (!strcmp(parm[0], "lpf_gain")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| pr_info("for_tool:%d\n", |
| ldim_fw_para.lpf_gain); |
| goto ldim_attr_store_end; |
| } |
| if (kstrtouint(parm[1], 10, &ldim_fw_para.lpf_gain) < 0) |
| goto ldim_attr_store_err; |
| } |
| pr_info("lpf_gain = %d\n", ldim_fw_para.lpf_gain); |
| } else if (!strcmp(parm[0], "lpf_res")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| pr_info("for_tool:%d\n", ldim_fw_para.lpf_res); |
| goto ldim_attr_store_end; |
| } |
| if (kstrtouint(parm[1], 10, &ldim_fw_para.lpf_res) < 0) |
| goto ldim_attr_store_err; |
| } |
| pr_info("lpf_res = %d\n", ldim_fw_para.lpf_res); |
| } else if (!strcmp(parm[0], "rgb_base")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| pr_info("for_tool:%d\n", ldim_fw_para.rgb_base); |
| goto ldim_attr_store_end; |
| } |
| if (kstrtouint(parm[1], 10, &ldim_fw_para.rgb_base) < 0) |
| goto ldim_attr_store_err; |
| } |
| pr_info("rgb_base = %d\n", ldim_fw_para.rgb_base); |
| } else if (!strcmp(parm[0], "avg_gain")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| pr_info("for_tool:%d\n", |
| ldim_fw_para.avg_gain); |
| goto ldim_attr_store_end; |
| } |
| if (kstrtouint(parm[1], 10, &ldim_fw_para.avg_gain) < 0) |
| goto ldim_attr_store_err; |
| } |
| pr_info("avg_gain = %d\n", ldim_fw_para.avg_gain); |
| } else if (!strcmp(parm[0], "fw_rgb_diff_th")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| pr_info("for_tool:%d\n", |
| ldim_fw_para.fw_rgb_diff_th); |
| goto ldim_attr_store_end; |
| } |
| if (kstrtouint(parm[1], 10, |
| &ldim_fw_para.fw_rgb_diff_th) < 0) { |
| goto ldim_attr_store_err; |
| } |
| } |
| pr_info("fw_rgb_diff_th = %d\n", ldim_fw_para.fw_rgb_diff_th); |
| } else if (!strcmp(parm[0], "max_luma")) { |
| if (parm[1] != NULL) { |
| if (kstrtouint(parm[1], 10, &ldim_fw_para.max_luma) < 0) |
| goto ldim_attr_store_err; |
| } |
| pr_info("max_luma = %d\n", ldim_fw_para.max_luma); |
| } else if (!strcmp(parm[0], "lmh_avg_TH")) { |
| if (parm[1] != NULL) { |
| if (kstrtouint(parm[1], 10, |
| &ldim_fw_para.lmh_avg_TH) < 0) { |
| goto ldim_attr_store_err; |
| } |
| } |
| pr_info("lmh_avg_TH = %d\n", ldim_fw_para.lmh_avg_TH); |
| } else if (!strcmp(parm[0], "fw_TF_sum_th")) { |
| if (parm[1] != NULL) { |
| if (kstrtouint(parm[1], 10, |
| &ldim_fw_para.fw_TF_sum_th) < 0) { |
| goto ldim_attr_store_err; |
| } |
| } |
| pr_info("fw_TF_sum_th = %d\n", ldim_fw_para.fw_TF_sum_th); |
| } else if (!strcmp(parm[0], "LPF_method")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| pr_info("for_tool:%d\n", |
| ldim_fw_para.LPF_method); |
| goto ldim_attr_store_end; |
| } |
| if (kstrtouint(parm[1], 10, |
| &ldim_fw_para.LPF_method) < 0) { |
| goto ldim_attr_store_err; |
| } |
| } |
| pr_info("LPF_method = %d\n", ldim_fw_para.LPF_method); |
| } else if (!strcmp(parm[0], "LD_TF_STEP_TH")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| pr_info("for_tool:%d\n", |
| ldim_fw_para.LD_TF_STEP_TH); |
| goto ldim_attr_store_end; |
| } |
| if (kstrtouint(parm[1], 10, |
| &ldim_fw_para.LD_TF_STEP_TH) < 0) { |
| goto ldim_attr_store_err; |
| } |
| } |
| pr_info("LD_TF_STEP_TH = %d\n", ldim_fw_para.LD_TF_STEP_TH); |
| } else if (!strcmp(parm[0], "TF_step_method")) { |
| if (parm[1] != NULL) { |
| if (kstrtouint(parm[1], 10, |
| &ldim_fw_para.TF_step_method) < 0) { |
| goto ldim_attr_store_err; |
| } |
| } |
| pr_info("TF_step_method = %d\n", ldim_fw_para.TF_step_method); |
| } else if (!strcmp(parm[0], "TF_FRESH_BL")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| pr_info("for_tool:%d\n", |
| ldim_fw_para.TF_FRESH_BL); |
| goto ldim_attr_store_end; |
| } |
| if (kstrtouint(parm[1], 10, |
| &ldim_fw_para.TF_FRESH_BL) < 0) { |
| goto ldim_attr_store_err; |
| } |
| } |
| pr_info("TF_FRESH_BL = %d\n", ldim_fw_para.TF_FRESH_BL); |
| } else if (!strcmp(parm[0], "TF_BLK_FRESH_BL")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| pr_info("for_tool:%d\n", |
| ldim_fw_para.TF_BLK_FRESH_BL); |
| goto ldim_attr_store_end; |
| } |
| if (kstrtouint(parm[1], 10, |
| &ldim_fw_para.TF_BLK_FRESH_BL) < 0) { |
| goto ldim_attr_store_err; |
| } |
| } |
| pr_info("TF_BLK_FRESH_BL = %d\n", ldim_fw_para.TF_BLK_FRESH_BL); |
| } else if (!strcmp(parm[0], "bbd_detect_en")) { |
| if (parm[1] != NULL) { |
| if (kstrtoul(parm[1], 10, &val1) < 0) |
| goto ldim_attr_store_err; |
| ldim_fw_para.bbd_detect_en = (unsigned char)val1; |
| } |
| pr_info("bbd_detect_en = %d\n", ldim_fw_para.bbd_detect_en); |
| } else if (!strcmp(parm[0], "side_blk_diff_th")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| pr_info("for_tool:%d\n", |
| ldim_fw_para.side_blk_diff_th); |
| goto ldim_attr_store_end; |
| } |
| if (kstrtouint(parm[1], 10, |
| &ldim_fw_para.side_blk_diff_th) < 0) { |
| goto ldim_attr_store_err; |
| } |
| } |
| pr_info("side_blk_diff_th = %d\n", |
| ldim_fw_para.side_blk_diff_th); |
| } else if (!strcmp(parm[0], "bbd_th")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| pr_info("for_tool:%d\n", ldim_fw_para.bbd_th); |
| goto ldim_attr_store_end; |
| } |
| if (kstrtouint(parm[1], 10, &ldim_fw_para.bbd_th) < 0) |
| goto ldim_attr_store_err; |
| } |
| pr_info("bbd_th = %d\n", ldim_fw_para.bbd_th); |
| } else if (!strcmp(parm[0], "diff_blk_luma_en")) { |
| if (parm[1] != NULL) { |
| if (kstrtoul(parm[1], 10, &val1) < 0) |
| goto ldim_attr_store_err; |
| ldim_fw_para.diff_blk_luma_en = (unsigned char)val1; |
| } |
| pr_info("diff_blk_luma_en = %d\n", |
| ldim_fw_para.diff_blk_luma_en); |
| } else if (!strcmp(parm[0], "fw_hist_print")) { |
| if (parm[1] != NULL) { |
| if (kstrtoul(parm[1], 10, &val1) < 0) |
| goto ldim_attr_store_err; |
| ldim_fw_para.fw_hist_print = (unsigned char)val1; |
| } |
| pr_info("fw_hist_print = %d\n", ldim_fw_para.fw_hist_print); |
| } else if (!strcmp(parm[0], "fw_print_frequent")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| pr_info("for_tool:%d\n", |
| ldim_fw_para.fw_print_frequent); |
| goto ldim_attr_store_end; |
| } |
| if (kstrtouint(parm[1], 10, |
| &ldim_fw_para.fw_print_frequent) < 0) { |
| goto ldim_attr_store_err; |
| } |
| } |
| pr_info("fw_print_frequent = %d\n", |
| ldim_fw_para.fw_print_frequent); |
| } else if (!strcmp(parm[0], "Dbprint_lv")) { |
| if (parm[1] != NULL) { |
| if (!strcmp(parm[1], "r")) { |
| pr_info("for_tool:%d\n", |
| ldim_fw_para.Dbprint_lv); |
| goto ldim_attr_store_end; |
| } |
| if (kstrtouint(parm[1], 10, |
| &ldim_fw_para.Dbprint_lv) < 0) { |
| goto ldim_attr_store_err; |
| } |
| } |
| pr_info("Dbprint_lv = %d\n", ldim_fw_para.Dbprint_lv); |
| } else if (!strcmp(parm[0], "alg_info")) { |
| pr_info("ldim_alg_ver: %s\n", ldim_fw_para.ver_str); |
| pr_info("ldim_fw_alg_frm: 0x%p\n\n", ldim_fw_para.fw_alg_frm); |
| pr_info("litgain = %ld\n\n", litgain); |
| switch (ldim_fw_para.ver_num) { |
| case 0: |
| pr_info("fw_LD_ThSF_l = %d\n" |
| "fw_LD_ThTF_l = %d\n" |
| "boost_gain = %d\n" |
| "TF_alpha = %d\n" |
| "lpf_gain = %d\n" |
| "lpf_res = %d\n" |
| "rgb_base = %d\n\n", |
| ldim_fw_para.fw_LD_ThSF_l, |
| ldim_fw_para.fw_LD_ThTF_l, |
| ldim_fw_para.boost_gain, |
| ldim_fw_para.TF_alpha, |
| ldim_fw_para.lpf_gain, |
| ldim_fw_para.lpf_res, |
| ldim_fw_para.rgb_base); |
| break; |
| case 1: |
| pr_info("fw_LD_ThSF_l = %d\n" |
| "fw_LD_ThTF_l = %d\n" |
| "boost_gain = %d\n" |
| "boost_gain_neg = %d\n" |
| "alpha_delta = %d\n\n", |
| ldim_fw_para.fw_LD_ThSF_l, |
| ldim_fw_para.fw_LD_ThTF_l, |
| ldim_fw_para.boost_gain, |
| ldim_fw_para.boost_gain_neg, |
| ldim_fw_para.alpha_delta); |
| break; |
| default: |
| break; |
| } |
| pr_info("fw_rgb_diff_th = %d\n" |
| "max_luma = %d\n" |
| "lmh_avg_TH = %d\n" |
| "fw_TF_sum_th = %d\n" |
| "LPF_method = %d\n" |
| "LD_TF_STEP_TH = %d\n" |
| "TF_step_method = %d\n" |
| "TF_FRESH_BL = %d\n\n", |
| ldim_fw_para.fw_rgb_diff_th, |
| ldim_fw_para.max_luma, |
| ldim_fw_para.lmh_avg_TH, |
| ldim_fw_para.fw_TF_sum_th, |
| ldim_fw_para.LPF_method, |
| ldim_fw_para.LD_TF_STEP_TH, |
| ldim_fw_para.TF_step_method, |
| ldim_fw_para.TF_FRESH_BL); |
| pr_info("TF_BLK_FRESH_BL = %d\n" |
| "side_blk_diff_th = %d\n" |
| "bbd_th = %d\n" |
| "bbd_detect_en = %d\n" |
| "diff_blk_luma_en = %d\n\n", |
| ldim_fw_para.TF_BLK_FRESH_BL, |
| ldim_fw_para.side_blk_diff_th, |
| ldim_fw_para.bbd_th, |
| ldim_fw_para.bbd_detect_en, |
| ldim_fw_para.diff_blk_luma_en); |
| pr_info("ov_gain = %d\n" |
| "avg_gain = %d\n\n", |
| ldim_fw_para.ov_gain, |
| ldim_fw_para.avg_gain); |
| pr_info("Sf_bypass = %d\n" |
| "Boost_light_bypass = %d\n" |
| "Lpf_bypass = %d\n" |
| "Ld_remap_bypass = %d\n\n", |
| ldim_fw_para.Sf_bypass, |
| ldim_fw_para.Boost_light_bypass, |
| ldim_fw_para.Lpf_bypass, |
| ldim_fw_para.Ld_remap_bypass); |
| pr_info("fw_hist_print = %d\n" |
| "fw_print_frequent = %d\n" |
| "Dbprint_lv = %d\n\n", |
| ldim_fw_para.fw_hist_print, |
| ldim_fw_para.fw_print_frequent, |
| ldim_fw_para.Dbprint_lv); |
| } else if (!strcmp(parm[0], "info")) { |
| pr_info("ldim_drv_ver: %s\n", LDIM_DRV_VER); |
| if (ldim_driver.config_print) |
| ldim_driver.config_print(); |
| pr_info("\nldim_blk_row = %d\n" |
| "ldim_blk_col = %d\n" |
| "ldim_hist_row = %d\n" |
| "ldim_hist_col = %d\n" |
| "ldim_bl_mode = %d\n" |
| "dev_index = %d\n\n", |
| ldim_blk_row, ldim_blk_col, |
| ldim_hist_row, ldim_hist_col, |
| ldim_config.bl_mode, |
| ldim_driver.dev_index); |
| pr_info("ldim_on_flag = %d\n" |
| "ldim_func_en = %d\n" |
| "ldim_remap_en = %d\n" |
| "ldim_demo_en = %d\n" |
| "ldim_func_bypass = %d\n" |
| "ldim_test_en = %d\n" |
| "ldim_avg_update_en = %d\n" |
| "ldim_matrix_update_en = %d\n" |
| "ldim_alg_en = %d\n" |
| "ldim_top_en = %d\n" |
| "ldim_hist_en = %d\n" |
| "ldim_data_min = %d\n" |
| "ldim_data_max = %d\n" |
| "ldim_irq_cnt = %d\n\n", |
| ldim_on_flag, ldim_func_en, |
| ldim_remap_en, ldim_demo_en, |
| ldim_func_bypass, ldim_test_en, |
| ldim_avg_update_en, ldim_matrix_update_en, |
| ldim_alg_en, ldim_top_en, ldim_hist_en, |
| ldim_data_min, LD_DATA_MAX, |
| ldim_irq_cnt); |
| pr_info("nPRM.reg_LD_BLK_Hnum = %d\n" |
| "nPRM.reg_LD_BLK_Vnum = %d\n" |
| "nPRM.reg_LD_pic_RowMax = %d\n" |
| "nPRM.reg_LD_pic_ColMax = %d\n", |
| nPRM.reg_LD_BLK_Hnum, nPRM.reg_LD_BLK_Vnum, |
| nPRM.reg_LD_pic_RowMax, nPRM.reg_LD_pic_ColMax); |
| pr_info("litgain = %ld\n\n", litgain); |
| } else if (!strcmp(parm[0], "print")) { |
| if (parm[1] != NULL) { |
| if (kstrtoul(parm[1], 10, &val1) < 0) |
| goto ldim_attr_store_err; |
| ldim_debug_print = (unsigned char)val1; |
| } |
| pr_info("ldim_debug_print = %d\n", ldim_debug_print); |
| } else if (!strcmp(parm[0], "alg")) { |
| if (ldim_fw_para.fw_alg_para_print) |
| ldim_fw_para.fw_alg_para_print(&ldim_fw_para); |
| else |
| pr_info("ldim_alg para_print is null\n"); |
| } else |
| pr_info("no support cmd!!!\n"); |
| |
| ldim_attr_store_end: |
| kfree(buf_orig); |
| kfree(parm); |
| return len; |
| |
| ldim_attr_store_err: |
| kfree(buf_orig); |
| kfree(parm); |
| return -EINVAL; |
| } |
| |
| static ssize_t ldim_func_en_show(struct class *class, |
| struct class_attribute *attr, char *buf) |
| { |
| int ret = 0; |
| |
| ret = sprintf(buf, "%d\n", ldim_func_en); |
| |
| return ret; |
| } |
| |
| static ssize_t ldim_func_en_store(struct class *class, |
| struct class_attribute *attr, const char *buf, size_t count) |
| { |
| unsigned int val = 0; |
| int ret = 0; |
| |
| ret = kstrtouint(buf, 10, &val); |
| LDIMPR("local diming function: %s\n", (val ? "enable" : "disable")); |
| ldim_func_en = val ? 1 : 0; |
| ldim_func_ctrl(ldim_func_en); |
| |
| return count; |
| } |
| |
| static ssize_t ldim_para_show(struct class *class, |
| struct class_attribute *attr, char *buf) |
| { |
| int len = 0; |
| |
| len = sprintf(buf, "boost_gain=%d\n", ldim_fw_para.boost_gain); |
| |
| return len; |
| } |
| |
| static ssize_t ldim_dump_show(struct class *class, |
| struct class_attribute *attr, char *buf) |
| { |
| int len = 0; |
| |
| len = ldim_hw_reg_dump(buf); |
| |
| return len; |
| } |
| |
| static struct class_attribute aml_ldim_class_attrs[] = { |
| __ATTR(attr, 0644, ldim_attr_show, ldim_attr_store), |
| __ATTR(func_en, 0644, |
| ldim_func_en_show, ldim_func_en_store), |
| __ATTR(para, 0644, ldim_para_show, NULL), |
| __ATTR(dump, 0644, ldim_dump_show, NULL), |
| __ATTR_NULL, |
| }; |
| |
| int aml_ldim_get_config_dts(struct device_node *child) |
| { |
| struct vinfo_s *vinfo = get_current_vinfo(); |
| unsigned int para[5]; |
| int ret; |
| |
| if (child == NULL) { |
| LDIMERR("child device_node is null\n"); |
| return -1; |
| } |
| |
| /* default setting */ |
| ldim_config.hsize = vinfo->width; |
| ldim_config.vsize = vinfo->height; |
| |
| /* get row & col from dts */ |
| ret = of_property_read_u32_array(child, "bl_ldim_region_row_col", |
| para, 2); |
| if (ret) { |
| LDIMERR("failed to get bl_ldim_region_row_col\n"); |
| } else { |
| if ((para[0] * para[1]) > LD_BLKREGNUM) { |
| LDIMERR("region row*col(%d*%d) is out of support\n", |
| para[0], para[1]); |
| } else { |
| ldim_blk_row = para[0]; |
| ldim_blk_col = para[1]; |
| ldim_hist_row = ldim_blk_row; |
| ldim_hist_col = ldim_blk_col; |
| ldim_config.row = ldim_blk_row; |
| ldim_config.col = ldim_blk_col; |
| } |
| } |
| LDIMPR("get region row = %d, col = %d\n", ldim_blk_row, ldim_blk_col); |
| |
| /* get bl_mode from dts */ |
| ret = of_property_read_u32(child, "bl_ldim_mode", ¶[0]); |
| if (ret) |
| LDIMERR("failed to get bl_ldim_mode\n"); |
| else |
| ldim_config.bl_mode = (unsigned char)para[0]; |
| LDIMPR("get bl_mode = %d\n", ldim_config.bl_mode); |
| |
| /* get ldim_dev_index from dts */ |
| ret = of_property_read_u32(child, "ldim_dev_index", ¶[0]); |
| if (ret) |
| LDIMERR("failed to get ldim_dev_index\n"); |
| else |
| ldim_driver.dev_index = (unsigned char)para[0]; |
| if (ldim_driver.dev_index < 0xff) |
| LDIMPR("get ldim_dev_index = %d\n", ldim_driver.dev_index); |
| |
| return 0; |
| } |
| |
| int aml_ldim_get_config_unifykey(unsigned char *buf) |
| { |
| unsigned char *p; |
| struct vinfo_s *vinfo = get_current_vinfo(); |
| |
| /* default setting */ |
| ldim_config.hsize = vinfo->width; |
| ldim_config.vsize = vinfo->height; |
| |
| p = buf; |
| |
| /* ldim: 24byte */ |
| /* get bl_ldim_region_row_col 4byte*/ |
| ldim_blk_row = *(p + LCD_UKEY_BL_LDIM_ROW); |
| ldim_blk_col = *(p + LCD_UKEY_BL_LDIM_COL); |
| ldim_hist_row = ldim_blk_row; |
| ldim_hist_col = ldim_blk_col; |
| ldim_config.row = ldim_blk_row; |
| ldim_config.col = ldim_blk_col; |
| LDIMPR("get region row = %d, col = %d\n", ldim_blk_row, ldim_blk_col); |
| |
| /* get bl_ldim_mode 1byte*/ |
| ldim_config.bl_mode = *(p + LCD_UKEY_BL_LDIM_MODE); |
| LDIMPR("get bl_mode = %d\n", ldim_config.bl_mode); |
| |
| /* get ldim_dev_index 1byte*/ |
| ldim_driver.dev_index = *(p + LCD_UKEY_BL_LDIM_DEV_INDEX); |
| if (ldim_driver.dev_index < 0xff) |
| LDIMPR("get dev_index = %d\n", ldim_driver.dev_index); |
| |
| return 0; |
| } |
| |
| static struct ldim_fw_para_s ldim_fw_para = { |
| /* header */ |
| .para_ver = FW_PARA_VER, |
| .para_size = sizeof(struct ldim_fw_para_s), |
| .ver_str = "not installed", |
| .ver_num = 0, |
| |
| .hist_col = 1, |
| .hist_row = 1, |
| |
| .fw_LD_ThSF_l = 1600, |
| .fw_LD_ThTF_l = 256, |
| .boost_gain = 456, /*norm 256 to 1,T960 finally use*/ |
| .TF_alpha = 256, /*256;*/ |
| .lpf_gain = 128, /* [0~128~256], norm 128 as 1*/ |
| .boost_gain_neg = 3, |
| .alpha_delta = 255,/* to fix flicker */ |
| |
| .lpf_res = 14, /* 1024/9*9 = 13,LPF_method=3 */ |
| .rgb_base = 127, |
| |
| .ov_gain = 16, |
| |
| .avg_gain = LD_DATA_MAX, |
| |
| .LPF_method = 3, |
| .LD_TF_STEP_TH = 100, |
| .TF_step_method = 3, |
| .TF_FRESH_BL = 8, |
| |
| .TF_BLK_FRESH_BL = 5, |
| .side_blk_diff_th = 100, |
| .bbd_th = 200, |
| .bbd_detect_en = 1, |
| .diff_blk_luma_en = 1, |
| |
| .fw_rgb_diff_th = 32760, |
| .max_luma = 4060, |
| .lmh_avg_TH = 200,/*for woman flicker*/ |
| .fw_TF_sum_th = 32760,/*20180530*/ |
| |
| .Sf_bypass = 0, |
| .Boost_light_bypass = 0, |
| .Lpf_bypass = 0, |
| .Ld_remap_bypass = 0, |
| .black_frm = 0, |
| |
| /* debug print flag */ |
| .fw_hist_print = 0, |
| .fw_print_frequent = 8, |
| .Dbprint_lv = 0, |
| |
| .nPRM = &nPRM, |
| .FDat = &FDat, |
| .bl_remap_curve = bl_remap_curve, |
| .fw_LD_Whist = fw_LD_Whist, |
| |
| .fw_alg_frm = NULL, |
| .fw_alg_para_print = NULL, |
| }; |
| |
| struct ldim_fw_para_s *aml_ldim_get_fw_para(void) |
| { |
| return &ldim_fw_para; |
| } |
| EXPORT_SYMBOL(aml_ldim_get_fw_para); |
| |
| static int aml_ldim_malloc(unsigned int blk_row, unsigned int blk_col) |
| { |
| ldim_driver.hist_matrix = kcalloc((blk_row * blk_col * 16), |
| sizeof(unsigned int), GFP_KERNEL); |
| if (ldim_driver.hist_matrix == NULL) { |
| LDIMERR("ldim_driver hist_matrix malloc error\n"); |
| goto ldim_malloc_err0; |
| } |
| ldim_driver.max_rgb = kcalloc((blk_row * blk_col), |
| sizeof(unsigned int), GFP_KERNEL); |
| if (ldim_driver.max_rgb == NULL) { |
| LDIMERR("ldim_driver max_rgb malloc error\n"); |
| goto ldim_malloc_err1; |
| } |
| ldim_driver.ldim_test_matrix = kcalloc((blk_row * blk_col), |
| sizeof(unsigned short), GFP_KERNEL); |
| if (ldim_driver.ldim_test_matrix == NULL) { |
| LDIMERR("ldim_driver ldim_test_matrix malloc error\n"); |
| goto ldim_malloc_err2; |
| } |
| ldim_driver.local_ldim_matrix = kcalloc((blk_row * blk_col), |
| sizeof(unsigned short), GFP_KERNEL); |
| if (ldim_driver.local_ldim_matrix == NULL) { |
| LDIMERR("ldim_driver local_ldim_matrix malloc error\n"); |
| goto ldim_malloc_err3; |
| } |
| ldim_driver.ldim_matrix_buf = kcalloc((blk_row * blk_col), |
| sizeof(unsigned short), GFP_KERNEL); |
| if (ldim_driver.ldim_matrix_buf == NULL) { |
| LDIMERR("ldim_driver ldim_matrix_buf malloc error\n"); |
| goto ldim_malloc_err4; |
| } |
| FDat.SF_BL_matrix = kcalloc((blk_row * blk_col), |
| sizeof(unsigned int), GFP_KERNEL); |
| if (FDat.SF_BL_matrix == NULL) { |
| LDIMERR("ldim_driver FDat.SF_BL_matrix malloc error\n"); |
| goto ldim_malloc_err5; |
| } |
| FDat.last_STA1_MaxRGB = kcalloc((blk_row * blk_col * 3), |
| sizeof(unsigned int), GFP_KERNEL); |
| if (FDat.last_STA1_MaxRGB == NULL) { |
| LDIMERR("ldim_driver FDat.last_STA1_MaxRGB malloc error\n"); |
| goto ldim_malloc_err6; |
| } |
| FDat.TF_BL_matrix = kcalloc((blk_row * blk_col), |
| sizeof(unsigned int), GFP_KERNEL); |
| if (FDat.TF_BL_matrix == NULL) { |
| LDIMERR("ldim_driver FDat.TF_BL_matrix malloc error\n"); |
| goto ldim_malloc_err7; |
| } |
| FDat.TF_BL_matrix_2 = kcalloc((blk_row * blk_col), |
| sizeof(unsigned int), GFP_KERNEL); |
| if (FDat.TF_BL_matrix_2 == NULL) { |
| LDIMERR("ldim_driver FDat.TF_BL_matrix_2 malloc error\n"); |
| goto ldim_malloc_err8; |
| } |
| FDat.TF_BL_alpha = kcalloc((blk_row * blk_col), |
| sizeof(unsigned int), GFP_KERNEL); |
| if (FDat.TF_BL_alpha == NULL) { |
| LDIMERR("ldim_driver FDat.TF_BL_alpha malloc error\n"); |
| goto ldim_malloc_err9; |
| } |
| |
| return 0; |
| |
| ldim_malloc_err9: |
| kfree(FDat.TF_BL_matrix_2); |
| ldim_malloc_err8: |
| kfree(FDat.TF_BL_matrix); |
| ldim_malloc_err7: |
| kfree(FDat.last_STA1_MaxRGB); |
| ldim_malloc_err6: |
| kfree(FDat.SF_BL_matrix); |
| ldim_malloc_err5: |
| kfree(ldim_driver.ldim_matrix_buf); |
| ldim_malloc_err4: |
| kfree(ldim_driver.local_ldim_matrix); |
| ldim_malloc_err3: |
| kfree(ldim_driver.ldim_test_matrix); |
| ldim_malloc_err2: |
| kfree(ldim_driver.max_rgb); |
| ldim_malloc_err1: |
| kfree(ldim_driver.hist_matrix); |
| ldim_malloc_err0: |
| return -1; |
| } |
| |
| static struct ldim_operate_func_s ldim_op_func_txlx = { |
| .h_region_max = 24, |
| .v_region_max = 16, |
| .total_region_max = 384, |
| .remap_update = ldim_remap_update_txlx, |
| .stts_init = ldim_stts_initial_txlx, |
| .ldim_init = ldim_initial_txlx, |
| }; |
| |
| static struct ldim_operate_func_s ldim_op_func_tl1 = { |
| .h_region_max = 31, |
| .v_region_max = 16, |
| .total_region_max = 128, |
| .remap_update = NULL, |
| .stts_init = ldim_stts_initial_tl1, |
| .ldim_init = NULL, |
| }; |
| |
| static int ldim_region_num_check(struct ldim_operate_func_s *ldim_func) |
| { |
| unsigned short temp; |
| |
| if (ldim_func == NULL) { |
| LDIMERR("%s: ldim_func is NULL\n", __func__); |
| return -1; |
| } |
| |
| if (ldim_config.row > ldim_func->v_region_max) { |
| LDIMERR("%s: blk row (%d) is out of support (%d)\n", |
| __func__, ldim_config.row, ldim_func->v_region_max); |
| return -1; |
| } |
| if (ldim_config.col > ldim_func->h_region_max) { |
| LDIMERR("%s: blk col (%d) is out of support (%d)\n", |
| __func__, ldim_config.col, ldim_func->h_region_max); |
| return -1; |
| } |
| temp = ldim_config.row * ldim_config.col; |
| if (temp > ldim_func->total_region_max) { |
| LDIMERR("%s: blk total region (%d) is out of support (%d)\n", |
| __func__, temp, ldim_func->total_region_max); |
| return -1; |
| } |
| |
| return 0; |
| } |
| |
| int aml_ldim_probe(struct platform_device *pdev) |
| { |
| int ret = 0; |
| unsigned int i; |
| unsigned int ldim_vsync_irq = 0; |
| struct ldim_dev_s *devp = &ldim_dev; |
| struct aml_bl_drv_s *bl_drv = aml_bl_get_driver(); |
| |
| memset(devp, 0, (sizeof(struct ldim_dev_s))); |
| |
| #ifdef LDIM_DEBUG_INFO |
| ldim_debug_print = 1; |
| #endif |
| |
| /* function flag */ |
| ldim_on_flag = 0; |
| ldim_func_en = 0; |
| ldim_remap_en = 0; |
| ldim_demo_en = 0; |
| ldim_func_bypass = 0; |
| ldim_test_en = 0; |
| |
| ldim_brightness_level = 0; |
| ldim_level_update = 0; |
| |
| /* alg flag */ |
| ldim_avg_update_en = 0; |
| ldim_matrix_update_en = 0; |
| ldim_alg_en = 0; |
| ldim_top_en = 0; |
| ldim_hist_en = 0; |
| |
| /* db para */ |
| LDIM_DATA_FROM_DB = 0; |
| devp->ldim_db_para = NULL; |
| /* ldim_op_func */ |
| switch (bl_drv->data->chip_type) { |
| case BL_CHIP_TL1: |
| case BL_CHIP_TM2: |
| devp->ldim_op_func = &ldim_op_func_tl1; |
| break; |
| case BL_CHIP_TXLX: |
| devp->ldim_op_func = &ldim_op_func_txlx; |
| break; |
| default: |
| devp->ldim_op_func = NULL; |
| break; |
| } |
| ret = ldim_region_num_check(devp->ldim_op_func); |
| if (ret) |
| return -1; |
| |
| ret = aml_ldim_malloc(ldim_blk_row, ldim_blk_col); |
| if (ret) { |
| LDIMERR("%s failed\n", __func__); |
| goto err; |
| } |
| |
| ret = alloc_chrdev_region(&devp->aml_ldim_devno, 0, 1, |
| AML_LDIM_DEVICE_NAME); |
| if (ret < 0) { |
| LDIMERR("failed to alloc major number\n"); |
| ret = -ENODEV; |
| goto err; |
| } |
| |
| devp->aml_ldim_clsp = class_create(THIS_MODULE, "aml_ldim"); |
| if (IS_ERR(devp->aml_ldim_clsp)) { |
| ret = PTR_ERR(devp->aml_ldim_clsp); |
| return ret; |
| } |
| for (i = 0; aml_ldim_class_attrs[i].attr.name; i++) { |
| if (class_create_file(devp->aml_ldim_clsp, |
| &aml_ldim_class_attrs[i]) < 0) |
| goto err1; |
| } |
| |
| devp->aml_ldim_cdevp = kmalloc(sizeof(struct cdev), GFP_KERNEL); |
| if (!devp->aml_ldim_cdevp) { |
| ret = -ENOMEM; |
| goto err2; |
| } |
| |
| /* connect the file operations with cdev */ |
| cdev_init(devp->aml_ldim_cdevp, &ldim_fops); |
| devp->aml_ldim_cdevp->owner = THIS_MODULE; |
| |
| /* connect the major/minor number to the cdev */ |
| ret = cdev_add(devp->aml_ldim_cdevp, devp->aml_ldim_devno, 1); |
| if (ret) { |
| LDIMERR("failed to add device\n"); |
| goto err3; |
| } |
| |
| devp->dev = device_create(devp->aml_ldim_clsp, NULL, |
| devp->aml_ldim_devno, NULL, AML_LDIM_CLASS_NAME); |
| if (IS_ERR(devp->dev)) { |
| ret = PTR_ERR(devp->dev); |
| goto err4; |
| } |
| |
| ldim_queue = create_workqueue("ldim workqueue"); |
| if (!ldim_queue) { |
| LDIMERR("ldim_queue create failed\n"); |
| ret = -1; |
| goto err; |
| } |
| INIT_WORK(&ldim_on_vs_work, ldim_on_update_brightness); |
| INIT_WORK(&ldim_off_vs_work, ldim_off_update_brightness); |
| |
| spin_lock_init(&ldim_isr_lock); |
| spin_lock_init(&rdma_ldim_isr_lock); |
| |
| bl_drv->res_ldim_vsync_irq = |
| platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
| if (!bl_drv->res_ldim_vsync_irq) { |
| ret = -ENODEV; |
| LDIMERR("ldim_vsync_irq resource error\n"); |
| goto err; |
| } |
| ldim_vsync_irq = bl_drv->res_ldim_vsync_irq->start; |
| if (ldim_debug_print) |
| LDIMPR("ldim_vsync_irq: %d\n", ldim_vsync_irq); |
| if (request_irq(ldim_vsync_irq, ldim_vsync_isr, IRQF_SHARED, |
| "ldim_vsync", (void *)"ldim_vsync")) { |
| LDIMERR("can't request ldim_vsync_irq\n"); |
| } else { |
| if (ldim_debug_print) |
| LDIMPR("request ldim_vsync_irq successful\n"); |
| } |
| |
| if (bl_drv->bconf->method != BL_CTRL_LOCAL_DIMMING) |
| ldim_dev_add_virtual_driver(&ldim_driver); |
| |
| ldim_driver.valid_flag = 1; |
| |
| LDIMPR("%s ok\n", __func__); |
| return 0; |
| |
| err4: |
| cdev_del(&devp->cdev); |
| err3: |
| kfree(devp->aml_ldim_cdevp); |
| err2: |
| for (i = 0; aml_ldim_class_attrs[i].attr.name; i++) { |
| class_remove_file(devp->aml_ldim_clsp, |
| &aml_ldim_class_attrs[i]); |
| } |
| class_destroy(devp->aml_ldim_clsp); |
| err1: |
| unregister_chrdev_region(devp->aml_ldim_devno, 1); |
| err: |
| return ret; |
| } |
| |
| int aml_ldim_remove(void) |
| { |
| unsigned int i; |
| struct ldim_dev_s *devp = &ldim_dev; |
| struct aml_bl_drv_s *bl_drv = aml_bl_get_driver(); |
| |
| kfree(FDat.SF_BL_matrix); |
| kfree(FDat.TF_BL_matrix); |
| kfree(FDat.TF_BL_matrix_2); |
| kfree(FDat.last_STA1_MaxRGB); |
| kfree(FDat.TF_BL_alpha); |
| kfree(ldim_driver.ldim_matrix_buf); |
| kfree(ldim_driver.hist_matrix); |
| kfree(ldim_driver.max_rgb); |
| kfree(ldim_driver.ldim_test_matrix); |
| kfree(ldim_driver.local_ldim_matrix); |
| |
| free_irq(bl_drv->res_ldim_vsync_irq->start, (void *)"ldim_vsync"); |
| |
| cdev_del(devp->aml_ldim_cdevp); |
| kfree(devp->aml_ldim_cdevp); |
| for (i = 0; aml_ldim_class_attrs[i].attr.name; i++) { |
| class_remove_file(devp->aml_ldim_clsp, |
| &aml_ldim_class_attrs[i]); |
| } |
| class_destroy(devp->aml_ldim_clsp); |
| unregister_chrdev_region(devp->aml_ldim_devno, 1); |
| |
| LDIMPR("%s ok\n", __func__); |
| return 0; |
| } |
| |