blob: 5a47adf485340ad7492241638b32b2f9a2ccbfc6 [file] [log] [blame]
/*
* drivers/amlogic/media/enhancement/amvecm/amvecm.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.
*
*/
/* Standard Linux headers */
#include <linux/types.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/errno.h>
#include <linux/uaccess.h>
#include <linux/of.h>
#include <linux/of_device.h>
/* #include <linux/amlogic/aml_common.h> */
#include <linux/ctype.h>/* for parse_para_pq */
#include <linux/vmalloc.h>
#include <linux/amlogic/media/vfm/vframe.h>
#include <linux/amlogic/media/amvecm/amvecm.h>
#include <linux/amlogic/media/vout/vout_notify.h>
#include <linux/io.h>
#include <linux/poll.h>
#include <linux/workqueue.h>
#ifdef CONFIG_AMLOGIC_LCD
#include <linux/amlogic/media/vout/lcd/lcd_notify.h>
#endif
#include "arch/vpp_regs.h"
#include "arch/ve_regs.h"
#include "arch/cm_regs.h"
#include "../../vin/tvin/tvin_global.h"
#include "amve.h"
#include "amcm.h"
#include "amcsc.h"
#include "keystone_correction.h"
#include "bitdepth.h"
#include "cm2_adj.h"
#include <linux/amlogic/media/amdolbyvision/dolby_vision.h>
#include "dnlp_cal.h"
#include "vlock.h"
#include "hdr/am_hdr10_plus.h"
#include "local_contrast.h"
#define pr_amvecm_dbg(fmt, args...)\
do {\
if (debug_amvecm)\
pr_info("AMVECM: " fmt, ## args);\
} while (0)
#define pr_amvecm_error(fmt, args...)\
pr_error("AMVECM: " fmt, ## args)
#define AMVECM_NAME "amvecm"
#define AMVECM_DRIVER_NAME "amvecm"
#define AMVECM_MODULE_NAME "amvecm"
#define AMVECM_DEVICE_NAME "amvecm"
#define AMVECM_CLASS_NAME "amvecm"
#define AMVECM_VER "Ref.2018/11/20"
struct amvecm_dev_s {
dev_t devt;
struct cdev cdev;
dev_t devno;
struct device *dev;
struct class *clsp;
wait_queue_head_t hdr_queue;
/*hdr*/
struct hdr_data_t hdr_d;
};
#ifdef CONFIG_AMLOGIC_LCD
struct work_struct aml_lcd_vlock_param_work;
#endif
static struct amvecm_dev_s amvecm_dev;
spinlock_t vpp_lcd_gamma_lock;
signed int vd1_brightness = 0, vd1_contrast;
static int hue_pre; /*-25~25*/
static int saturation_pre; /*-128~127*/
static int hue_post; /*-25~25*/
static int saturation_post; /*-128~127*/
static s16 saturation_ma;
static s16 saturation_mb;
static s16 saturation_ma_shift;
static s16 saturation_mb_shift;
unsigned int sr1_reg_val[101];
unsigned int sr1_ret_val[101];
struct vpp_hist_param_s vpp_hist_param;
static unsigned int pre_hist_height, pre_hist_width;
static unsigned int pc_mode = 0xff;
static unsigned int pc_mode_last = 0xff;
static struct hdr_metadata_info_s vpp_hdr_metadata_s;
unsigned int atv_source_flg;
/*bit0: brightness
*bit1: brightness2
*bit2: saturation_hue
*bit3: saturation_hue_post
*bit4: contrast
*bit5: contrast2
*/
static int vdj_mode_flg;
struct am_vdj_mode_s vdj_mode_s;
/*void __iomem *amvecm_hiu_reg_base;*//* = *ioremap(0xc883c000, 0x2000); */
static int debug_amvecm;
module_param(debug_amvecm, int, 0664);
MODULE_PARM_DESC(debug_amvecm, "\n debug_amvecm\n");
unsigned int vecm_latch_flag;
module_param(vecm_latch_flag, uint, 0664);
MODULE_PARM_DESC(vecm_latch_flag, "\n vecm_latch_flag\n");
unsigned int vpp_demo_latch_flag;
module_param(vpp_demo_latch_flag, uint, 0664);
MODULE_PARM_DESC(vpp_demo_latch_flag, "\n vpp_demo_latch_flag\n");
unsigned int pq_load_en = 1;/* load pq table enable/disable */
module_param(pq_load_en, uint, 0664);
MODULE_PARM_DESC(pq_load_en, "\n pq_load_en\n");
bool gamma_en; /* wb_gamma_en enable/disable */
module_param(gamma_en, bool, 0664);
MODULE_PARM_DESC(gamma_en, "\n gamma_en\n");
bool wb_en; /* wb_en enable/disable */
module_param(wb_en, bool, 0664);
MODULE_PARM_DESC(wb_en, "\n wb_en\n");
unsigned int probe_ok;/* probe ok or not */
module_param(probe_ok, uint, 0664);
MODULE_PARM_DESC(probe_ok, "\n probe_ok\n");
static unsigned int sr1_index;/* for sr1 read */
module_param(sr1_index, uint, 0664);
MODULE_PARM_DESC(sr1_index, "\n sr1_index\n");
static int mtx_sel_dbg;/* for mtx debug */
module_param(mtx_sel_dbg, uint, 0664);
MODULE_PARM_DESC(mtx_sel_dbg, "\n mtx_sel_dbg\n");
unsigned int pq_user_latch_flag;
module_param(pq_user_latch_flag, uint, 0664);
MODULE_PARM_DESC(pq_user_latch_flag, "\n pq_user_latch_flag\n");
/*0: 709/601 1: bt2020*/
int tx_op_color_primary;
module_param(tx_op_color_primary, int, 0664);
MODULE_PARM_DESC(tx_op_color_primary,
"tx output color_primary");
unsigned int debug_game_mode_1;
module_param(debug_game_mode_1, uint, 0664);
MODULE_PARM_DESC(debug_game_mode_1, "\n debug_game_mode_1\n");
unsigned int pq_user_value;
enum hdr_type_e hdr_source_type = HDRTYPE_SDR;
#define SR0_OFFSET 0xc00
#define SR1_OFFSET 0xc80
unsigned int sr_offset[2] = {0, 0};
bool gamma_working; /* wb_gamma is working or not */
static int wb_init_bypass_coef[24] = {
0, 0, 0, /* pre offset */
1024, 0, 0,
0, 1024, 0,
0, 0, 1024,
0, 0, 0, /* 10'/11'/12' */
0, 0, 0, /* 20'/21'/22' */
0, 0, 0, /* offset */
0, 0, 0 /* mode, right_shift, clip_en */
};
/* vpp brightness/contrast/saturation/hue */
static int __init amvecm_load_pq_val(char *str)
{
int i = 0, err = 0;
char *tk = NULL, *tmp[4];
long val;
if (str == NULL) {
pr_err("[amvecm] pq val error !!!\n");
return 0;
}
for (tk = strsep(&str, ","); tk != NULL; tk = strsep(&str, ",")) {
tmp[i] = tk;
err = kstrtol(tmp[i], 10, &val);
if (err) {
pr_err("[amvecm] pq string error !!!\n");
break;
}
/* pr_err("[amvecm] pq[%d]: %d\n", i, (int)val[i]); */
/* only need to get sat/hue value,*/
/*brightness/contrast can be got from registers */
if (i == 2)
saturation_post = (int)val;
else if (i == 3)
hue_post = (int)val;
i++;
if (i >= 4)
return 0;
}
return 0;
}
__setup("pq=", amvecm_load_pq_val);
static int amvecm_set_contrast2(int val)
{
val += 0x80;
if (get_cpu_type() == MESON_CPU_MAJOR_ID_TL1) {
WRITE_VPP_REG_BITS(VPP_VADJ2_Y_2,
val, 0, 8);
WRITE_VPP_REG_BITS(VPP_VADJ2_MISC, 1, 0, 1);
} else {
WRITE_VPP_REG_BITS(VPP_VADJ2_Y,
val, 0, 8);
WRITE_VPP_REG_BITS(VPP_VADJ_CTRL, 1, 2, 1);
}
return 0;
}
static int amvecm_set_brightness2(int val)
{
if (get_cpu_type() <= MESON_CPU_MAJOR_ID_GXTVBB)
WRITE_VPP_REG_BITS(VPP_VADJ2_Y,
vdj_mode_s.brightness2, 8, 9);
else if (get_cpu_type() == MESON_CPU_MAJOR_ID_TL1)
WRITE_VPP_REG_BITS(VPP_VADJ2_Y_2,
vdj_mode_s.brightness2, 8, 11);
else
WRITE_VPP_REG_BITS(VPP_VADJ2_Y,
vdj_mode_s.brightness2 >> 1, 8, 10);
if (get_cpu_type() == MESON_CPU_MAJOR_ID_TL1)
WRITE_VPP_REG_BITS(VPP_VADJ2_MISC, 1, 0, 1);
else
WRITE_VPP_REG_BITS(VPP_VADJ_CTRL, 1, 2, 1);
return 0;
}
static void amvecm_size_patch(void)
{
unsigned int hs, he, vs, ve;
hs = READ_VPP_REG_BITS(VPP_POSTBLEND_VD1_H_START_END, 16, 13);
he = READ_VPP_REG_BITS(VPP_POSTBLEND_VD1_H_START_END, 0, 13);
vs = READ_VPP_REG_BITS(VPP_POSTBLEND_VD1_V_START_END, 16, 13);
ve = READ_VPP_REG_BITS(VPP_POSTBLEND_VD1_V_START_END, 0, 13);
cm2_frame_size_patch(he-hs+1, ve-vs+1);
}
/* video adj1 */
static ssize_t video_adj1_brightness_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
s32 val = 0;
if (get_cpu_type() <= MESON_CPU_MAJOR_ID_GXTVBB) {
val = (READ_VPP_REG(VPP_VADJ1_Y) >> 8) & 0x1ff;
val = (val << 23) >> 23;
return sprintf(buf, "%d\n", val);
} else if (get_cpu_type() == MESON_CPU_MAJOR_ID_TL1) {
val = (READ_VPP_REG(VPP_VADJ1_Y_2) >> 8) & 0x7ff;
val = (val << 21) >> 21;
return sprintf(buf, "%d\n", val);
}
val = (READ_VPP_REG(VPP_VADJ1_Y) >> 8) & 0x3ff;
val = (val << 22) >> 22;
return sprintf(buf, "%d\n", val << 1);
}
static ssize_t video_adj1_brightness_store(struct class *cla,
struct class_attribute *attr,
const char *buf, size_t count)
{
size_t r;
int val;
r = sscanf(buf, "%d\n", &val);
if ((r != 1) || (val < -1024) || (val > 1023))
return -EINVAL;
if (get_cpu_type() <= MESON_CPU_MAJOR_ID_GXTVBB)
WRITE_VPP_REG_BITS(VPP_VADJ1_Y, val, 8, 9);
else if (get_cpu_type() == MESON_CPU_MAJOR_ID_TL1)
WRITE_VPP_REG_BITS(VPP_VADJ1_Y_2, val, 8, 11);
else
WRITE_VPP_REG_BITS(VPP_VADJ1_Y, val >> 1, 8, 10);
if (get_cpu_type() == MESON_CPU_MAJOR_ID_TL1)
WRITE_VPP_REG_BITS(VPP_VADJ1_MISC, 1, 0, 1);
else
WRITE_VPP_REG_BITS(VPP_VADJ_CTRL, 1, 0, 1);
return count;
}
static ssize_t video_adj1_contrast_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
if (get_cpu_type() == MESON_CPU_MAJOR_ID_TL1)
return sprintf(buf, "%d\n",
(int)(READ_VPP_REG(VPP_VADJ1_Y_2) & 0xff) - 0x80);
else
return sprintf(buf, "%d\n",
(int)(READ_VPP_REG(VPP_VADJ1_Y) & 0xff) - 0x80);
}
static ssize_t video_adj1_contrast_store(struct class *cla,
struct class_attribute *attr,
const char *buf, size_t count)
{
size_t r;
int val;
r = sscanf(buf, "%d\n", &val);
if ((r != 1) || (val < -127) || (val > 127))
return -EINVAL;
val += 0x80;
if (get_cpu_type() == MESON_CPU_MAJOR_ID_TL1) {
WRITE_VPP_REG_BITS(VPP_VADJ1_Y_2, val, 0, 8);
WRITE_VPP_REG_BITS(VPP_VADJ1_MISC, 1, 0, 1);
} else {
WRITE_VPP_REG_BITS(VPP_VADJ1_Y, val, 0, 8);
WRITE_VPP_REG_BITS(VPP_VADJ_CTRL, 1, 0, 1);
}
return count;
}
/* video adj2 */
static ssize_t video_adj2_brightness_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
s32 val = 0;
if (get_cpu_type() <= MESON_CPU_MAJOR_ID_GXTVBB) {
val = (READ_VPP_REG(VPP_VADJ2_Y) >> 8) & 0x1ff;
val = (val << 23) >> 23;
return sprintf(buf, "%d\n", val);
} else if (get_cpu_type() == MESON_CPU_MAJOR_ID_TL1) {
val = (READ_VPP_REG(VPP_VADJ2_Y_2) >> 8) & 0x7ff;
val = (val << 21) >> 21;
return sprintf(buf, "%d\n", val);
}
val = (READ_VPP_REG(VPP_VADJ2_Y) >> 8) & 0x3ff;
val = (val << 22) >> 22;
return sprintf(buf, "%d\n", val << 1);
}
static ssize_t video_adj2_brightness_store(struct class *cla,
struct class_attribute *attr,
const char *buf, size_t count)
{
size_t r;
int val;
r = sscanf(buf, "%d\n", &val);
if ((r != 1) || (val < -1024) || (val > 1023))
return -EINVAL;
amvecm_set_brightness2(val);
return count;
}
static ssize_t video_adj2_contrast_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
if (get_cpu_type() == MESON_CPU_MAJOR_ID_TL1)
return sprintf(buf, "%d\n",
(int)(READ_VPP_REG(VPP_VADJ2_Y_2) & 0xff) - 0x80);
else
return sprintf(buf, "%d\n",
(int)(READ_VPP_REG(VPP_VADJ2_Y) & 0xff) - 0x80);
}
static ssize_t video_adj2_contrast_store(struct class *cla,
struct class_attribute *attr,
const char *buf, size_t count)
{
size_t r;
int val;
r = sscanf(buf, "%d\n", &val);
if ((r != 1) || (val < -127) || (val > 127))
return -EINVAL;
amvecm_set_contrast2(val);
return count;
}
static ssize_t amvecm_usage_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
pr_info("Usage:");
pr_info("brightness_val range:-255~255\n");
pr_info("contrast_val range:-127~127\n");
pr_info("saturation_val range:-128~128\n");
pr_info("hue_val range:-25~25\n");
pr_info("************video brightness & contrast & saturation_hue adj as flow*************\n");
pr_info("echo brightness_val > /sys/class/amvecm/brightness1\n");
pr_info("echo contrast_val > /sys/class/amvecm/contrast1\n");
pr_info("echo saturation_val hue_val > /sys/class/amvecm/saturation_hue_pre\n");
pr_info("************after video+osd blender, brightness & contrast & saturation_hue adj as flow*************\n");
pr_info("echo brightness_val > /sys/class/amvecm/brightness2\n");
pr_info("echo contrast_val > /sys/class/amvecm/contrast2\n");
pr_info("echo saturation_val hue_val > /sys/class/amvecm/saturation_hue_post\n");
return 0;
}
static void parse_param_amvecm(char *buf_orig, char **parm)
{
char *ps, *token;
unsigned int n = 0;
char delim1[3] = " ";
char delim2[2] = "\n";
ps = buf_orig;
strcat(delim1, delim2);
while (1) {
token = strsep(&ps, delim1);
if (token == NULL)
break;
if (*token == '\0')
continue;
parm[n++] = token;
}
}
static void amvecm_3d_sync_status(void)
{
unsigned int sync_h_start, sync_h_end, sync_v_start,
sync_v_end, sync_polarity,
sync_out_inv, sync_en;
if (!is_meson_gxtvbb_cpu()) {
pr_info("\n chip does not support 3D sync process!!!\n");
return;
}
sync_h_start = READ_VPP_REG_BITS(VPU_VPU_3D_SYNC2, 0, 13);
sync_h_end = READ_VPP_REG_BITS(VPU_VPU_3D_SYNC2, 16, 13);
sync_v_start = READ_VPP_REG_BITS(VPU_VPU_3D_SYNC1, 0, 13);
sync_v_end = READ_VPP_REG_BITS(VPU_VPU_3D_SYNC1, 16, 13);
sync_polarity = READ_VPP_REG_BITS(VPU_VPU_3D_SYNC1, 29, 1);
sync_out_inv = READ_VPP_REG_BITS(VPU_VPU_3D_SYNC1, 15, 1);
sync_en = READ_VPP_REG_BITS(VPU_VPU_3D_SYNC1, 31, 1);
pr_info("\n current 3d sync state:\n");
pr_info("sync_h_start:%d\n", sync_h_start);
pr_info("sync_h_end:%d\n", sync_h_end);
pr_info("sync_v_start:%d\n", sync_v_start);
pr_info("sync_v_end:%d\n", sync_v_end);
pr_info("sync_polarity:%d\n", sync_polarity);
pr_info("sync_out_inv:%d\n", sync_out_inv);
pr_info("sync_en:%d\n", sync_en);
pr_info("sync_3d_black_color:%d\n", sync_3d_black_color);
pr_info("sync_3d_sync_to_vbo:%d\n", sync_3d_sync_to_vbo);
}
static ssize_t amvecm_3d_sync_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
ssize_t len = 0;
len += sprintf(buf+len,
"echo hstart val(D) > /sys/class/amvecm/sync_3d\n");
len += sprintf(buf+len,
"echo hend val(D) > /sys/class/amvecm/sync_3d\n");
len += sprintf(buf+len,
"echo vstart val(D) > /sys/class/amvecm/sync_3d\n");
len += sprintf(buf+len,
"echo vend val(D) > /sys/class/amvecm/sync_3d\n");
len += sprintf(buf+len,
"echo pola val(D) > /sys/class/amvecm/sync_3d\n");
len += sprintf(buf+len,
"echo inv val(D) > /sys/class/amvecm/sync_3d\n");
len += sprintf(buf+len,
"echo black_color val(Hex) > /sys/class/amvecm/sync_3d\n");
len += sprintf(buf+len,
"echo sync_to_vx1 val(D) > /sys/class/amvecm/sync_3d\n");
len += sprintf(buf+len,
"echo enable > /sys/class/amvecm/sync_3d\n");
len += sprintf(buf+len,
"echo disable > /sys/class/amvecm/sync_3d\n");
len += sprintf(buf+len,
"echo status > /sys/class/amvecm/sync_3d\n");
return len;
}
static ssize_t amvecm_3d_sync_store(struct class *cla,
struct class_attribute *attr,
const char *buf, size_t count)
{
char *buf_orig, *parm[8] = {NULL};
long val;
if (!buf)
return count;
if (!is_meson_gxtvbb_cpu()) {
pr_info("\n chip does not support 3D sync process!!!\n");
return count;
}
buf_orig = kstrdup(buf, GFP_KERNEL);
parse_param_amvecm(buf_orig, (char **)&parm);
if (!strncmp(parm[0], "hstart", 6)) {
if (kstrtol(parm[1], 10, &val) < 0)
return -EINVAL;
sync_3d_h_start = val&0x1fff;
WRITE_VPP_REG_BITS(VPU_VPU_3D_SYNC2, sync_3d_h_start, 0, 13);
} else if (!strncmp(parm[0], "hend", 4)) {
if (kstrtol(parm[1], 10, &val) < 0)
return -EINVAL;
sync_3d_h_end = val&0x1fff;
WRITE_VPP_REG_BITS(VPU_VPU_3D_SYNC2, sync_3d_h_end, 16, 13);
} else if (!strncmp(parm[0], "vstart", 6)) {
if (kstrtol(parm[1], 10, &val) < 0)
return -EINVAL;
sync_3d_v_start = val&0x1fff;
WRITE_VPP_REG_BITS(VPU_VPU_3D_SYNC1, sync_3d_v_start, 0, 13);
} else if (!strncmp(parm[0], "vend", 4)) {
if (kstrtol(parm[1], 10, &val) < 0)
return -EINVAL;
sync_3d_v_end = val&0x1fff;
WRITE_VPP_REG_BITS(VPU_VPU_3D_SYNC1, sync_3d_v_end, 16, 13);
} else if (!strncmp(parm[0], "pola", 4)) {
if (kstrtol(parm[1], 10, &val) < 0)
return -EINVAL;
sync_3d_polarity = val&0x1;
WRITE_VPP_REG_BITS(VPU_VPU_3D_SYNC1, sync_3d_polarity, 29, 1);
} else if (!strncmp(parm[0], "inv", 3)) {
if (kstrtol(parm[1], 10, &val) < 0)
return -EINVAL;
sync_3d_out_inv = val&0x1;
WRITE_VPP_REG_BITS(VPU_VPU_3D_SYNC1, sync_3d_out_inv, 15, 1);
} else if (!strncmp(parm[0], "black_color", 11)) {
if (kstrtol(parm[1], 16, &val) < 0)
return -EINVAL;
sync_3d_black_color = val&0xffffff;
WRITE_VPP_REG_BITS(VPP_BLEND_ONECOLOR_CTRL,
sync_3d_black_color, 0, 24);
} else if (!strncmp(parm[0], "sync_to_vx1", 11)) {
if (kstrtol(parm[1], 10, &val) < 0)
return -EINVAL;
sync_3d_sync_to_vbo = val&0x1;
} else if (!strncmp(parm[0], "enable", 6)) {
vecm_latch_flag |= FLAG_3D_SYNC_EN;
} else if (!strncmp(parm[0], "disable", 7)) {
vecm_latch_flag |= FLAG_3D_SYNC_DIS;
} else if (!strncmp(parm[0], "status", 7)) {
amvecm_3d_sync_status();
}
kfree(buf_orig);
return count;
}
static ssize_t amvecm_vlock_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
ssize_t len = 0;
len += sprintf(buf+len,
"echo vlock_mode val(0/1/2) > /sys/class/amvecm/vlock\n");
len += sprintf(buf+len,
"echo vlock_en val(0/1) > /sys/class/amvecm/vlock\n");
len += sprintf(buf+len,
"echo vlock_adapt val(0/1) > /sys/class/amvecm/vlock\n");
len += sprintf(buf+len,
"echo vlock_dis_cnt_limit val(D) > /sys/class/amvecm/vlock\n");
len += sprintf(buf+len,
"echo vlock_delta_limit val(D) > /sys/class/amvecm/vlock\n");
len += sprintf(buf+len,
"echo vlock_pll_m_limit val(D) > /sys/class/amvecm/vlock\n");
len += sprintf(buf+len,
"echo vlock_delta_cnt_limit val(D) > /sys/class/amvecm/vlock\n");
len += sprintf(buf+len,
"echo vlock_debug val(0x111) > /sys/class/amvecm/vlock\n");
len += sprintf(buf+len,
"echo vlock_dynamic_adjust val(0/1) > /sys/class/amvecm/vlock\n");
len += sprintf(buf+len,
"echo vlock_dis_cnt_no_vf_limit val(D) > /sys/class/amvecm/vlock\n");
len += sprintf(buf+len,
"echo vlock_line_limit val(D) > /sys/class/amvecm/vlock\n");
len += sprintf(buf+len,
"echo vlock_support val(D) > /sys/class/amvecm/vlock\n");
len += sprintf(buf+len,
"echo enable > /sys/class/amvecm/vlock\n");
len += sprintf(buf+len,
"echo disable > /sys/class/amvecm/vlock\n");
len += sprintf(buf+len,
"echo status > /sys/class/amvecm/vlock\n");
len += sprintf(buf+len,
"echo dump_reg > /sys/class/amvecm/vlock\n");
len += sprintf(buf+len,
"echo log_start > /sys/class/amvecm/vlock\n");
len += sprintf(buf+len,
"echo log_stop > /sys/class/amvecm/vlock\n");
len += sprintf(buf+len,
"echo log_print > /sys/class/amvecm/vlock\n");
return len;
}
static ssize_t amvecm_vlock_store(struct class *cla,
struct class_attribute *attr,
const char *buf, size_t count)
{
char *buf_orig, *parm[8] = {NULL};
long val;
unsigned int temp_val;
enum vlock_param_e sel = VLOCK_PARAM_MAX;
if (!buf)
return count;
if (!is_meson_gxtvbb_cpu() &&
!is_meson_gxbb_cpu() &&
(get_cpu_type() < MESON_CPU_MAJOR_ID_GXL)) {
pr_info("\n chip does not support vlock process!!!\n");
return count;
}
buf_orig = kstrdup(buf, GFP_KERNEL);
parse_param_amvecm(buf_orig, (char **)&parm);
if (!strncmp(parm[0], "vlock_mode", 10)) {
if (kstrtol(parm[1], 10, &val) < 0)
return -EINVAL;
temp_val = val;
sel = VLOCK_MODE;
} else if (!strncmp(parm[0], "vlock_en", 8)) {
if (kstrtol(parm[1], 10, &val) < 0)
return -EINVAL;
temp_val = val;
sel = VLOCK_EN;
} else if (!strncmp(parm[0], "vlock_adapt", 11)) {
if (kstrtol(parm[1], 10, &val) < 0)
return -EINVAL;
temp_val = val;
sel = VLOCK_ADAPT;
} else if (!strncmp(parm[0], "vlock_dis_cnt_limit", 19)) {
if (kstrtol(parm[1], 10, &val) < 0)
return -EINVAL;
temp_val = val;
sel = VLOCK_DIS_CNT_LIMIT;
} else if (!strncmp(parm[0], "vlock_delta_limit", 17)) {
if (kstrtol(parm[1], 10, &val) < 0)
return -EINVAL;
temp_val = val;
sel = VLOCK_DELTA_LIMIT;
} else if (!strncmp(parm[0], "vlock_pll_m_limit", 17)) {
if (kstrtol(parm[1], 10, &val) < 0)
return -EINVAL;
temp_val = val;
sel = VLOCK_PLL_M_LIMIT;
} else if (!strncmp(parm[0], "vlock_delta_cnt_limit", 21)) {
if (kstrtol(parm[1], 10, &val) < 0)
return -EINVAL;
temp_val = val;
sel = VLOCK_DELTA_CNT_LIMIT;
} else if (!strncmp(parm[0], "vlock_debug", 11)) {
if (kstrtol(parm[1], 16, &val) < 0)
return -EINVAL;
temp_val = val;
sel = VLOCK_DEBUG;
} else if (!strncmp(parm[0], "vlock_dynamic_adjust", 20)) {
if (kstrtol(parm[1], 10, &val) < 0)
return -EINVAL;
temp_val = val;
sel = VLOCK_DYNAMIC_ADJUST;
} else if (!strncmp(parm[0], "vlock_line_limit", 17)) {
if (kstrtol(parm[1], 10, &val) < 0)
return -EINVAL;
temp_val = val;
sel = VLOCK_LINE_LIMIT;
} else if (!strncmp(parm[0], "vlock_dis_cnt_no_vf_limit", 25)) {
if (kstrtol(parm[1], 10, &val) < 0)
return -EINVAL;
temp_val = val;
sel = VLOCK_DIS_CNT_NO_VF_LIMIT;
} else if (!strncmp(parm[0], "vlock_line_limit", 16)) {
if (kstrtol(parm[1], 10, &val) < 0)
return -EINVAL;
temp_val = val;
sel = VLOCK_LINE_LIMIT;
} else if (!strncmp(parm[0], "vlock_support", 13)) {
if (kstrtol(parm[1], 10, &val) < 0)
return -EINVAL;
temp_val = val;
sel = VLOCK_SUPPORT;
} else if (!strncmp(parm[0], "enable", 6)) {
vecm_latch_flag |= FLAG_VLOCK_EN;
vlock_set_en(true);
} else if (!strncmp(parm[0], "disable", 7)) {
vecm_latch_flag |= FLAG_VLOCK_DIS;
} else if (!strncmp(parm[0], "status", 6)) {
vlock_status();
} else if (!strncmp(parm[0], "dump_reg", 8)) {
vlock_reg_dump();
} else if (!strncmp(parm[0], "log_start", 9)) {
vlock_log_start();
} else if (!strncmp(parm[0], "log_stop", 8)) {
vlock_log_stop();
} else if (!strncmp(parm[0], "log_print", 9)) {
vlock_log_print();
} else if (!strncmp(parm[0], "phase", 5)) {
if (kstrtol(parm[1], 10, &val) < 0)
return -EINVAL;
vlock_set_phase(val);
} else if (!strncmp(parm[0], "phlock_en", 9)) {
if (kstrtol(parm[1], 10, &val) < 0)
return -EINVAL;
vlock_set_phase_en(val);
} else {
pr_info("----cmd list -----\n");
pr_info("vlock_mode val\n");
pr_info("vlock_en val\n");
pr_info("vlock_debug val\n");
pr_info("vlock_adapt val\n");
pr_info("vlock_dis_cnt_limit val\n");
pr_info("vlock_delta_limit val\n");
pr_info("vlock_dynamic_adjust val\n");
pr_info("vlock_line_limit val\n");
pr_info("vlock_dis_cnt_no_vf_limit val\n");
pr_info("vlock_line_limit val\n");
pr_info("vlock_support val\n");
pr_info("enable\n");
pr_info("disable\n");
pr_info("status\n");
pr_info("dump_reg\n");
pr_info("log_start\n");
pr_info("log_stop\n");
pr_info("log_print\n");
pr_info("phase persent\n");
pr_info("phlock_en val\n");
}
if (sel < VLOCK_PARAM_MAX)
vlock_param_set(temp_val, sel);
kfree(buf_orig);
return count;
}
/* #endif */
static void vpp_backup_histgram(struct vframe_s *vf)
{
unsigned int i = 0;
vpp_hist_param.vpp_hist_pow = vf->prop.hist.hist_pow;
vpp_hist_param.vpp_luma_sum = vf->prop.hist.vpp_luma_sum;
vpp_hist_param.vpp_pixel_sum = vf->prop.hist.vpp_pixel_sum;
for (i = 0; i < 64; i++)
vpp_hist_param.vpp_histgram[i] = vf->prop.hist.vpp_gamma[i];
}
static void vpp_dump_histgram(void)
{
uint i;
pr_info("%s:\n", __func__);
for (i = 0; i < 64; i++) {
pr_info("[%d]0x%-8x\t", i, vpp_hist_param.vpp_histgram[i]);
if ((i+1)%8 == 0)
pr_info("\n");
}
}
void vpp_get_hist_en(void)
{
WRITE_VPP_REG_BITS(VI_HIST_CTRL, 0x1, 11, 3);
WRITE_VPP_REG_BITS(VI_HIST_CTRL, 0x1, 0, 1);
WRITE_VPP_REG(VI_HIST_GCLK_CTRL, 0xffffffff);
WRITE_VPP_REG_BITS(VI_HIST_CTRL, 2, VI_HIST_POW_BIT, VI_HIST_POW_WID);
}
static unsigned int vpp_luma_max;
void vpp_get_vframe_hist_info(struct vframe_s *vf)
{
unsigned int hist_height, hist_width;
u64 divid;
if (get_cpu_type() == MESON_CPU_MAJOR_ID_TL1) {
/*TL1 remove VPP_IN_H_V_SIZE register*/
hist_width = READ_VPP_REG_BITS(VPP_PREBLEND_H_SIZE, 0, 13);
hist_height = READ_VPP_REG_BITS(VPP_PREBLEND_H_SIZE, 16, 13);
} else {
hist_height = READ_VPP_REG_BITS(VPP_IN_H_V_SIZE, 0, 13);
hist_width = READ_VPP_REG_BITS(VPP_IN_H_V_SIZE, 16, 13);
}
if ((hist_height != pre_hist_height) ||
(hist_width != pre_hist_width)) {
pre_hist_height = hist_height;
pre_hist_width = hist_width;
WRITE_VPP_REG_BITS(VI_HIST_PIC_SIZE, hist_height, 16, 13);
WRITE_VPP_REG_BITS(VI_HIST_PIC_SIZE, hist_width, 0, 13);
}
/* fetch hist info */
/* vf->prop.hist.luma_sum = READ_CBUS_REG_BITS(VDIN_HIST_SPL_VAL,*/
/* HIST_LUMA_SUM_BIT, HIST_LUMA_SUM_WID ); */
vf->prop.hist.hist_pow = READ_VPP_REG_BITS(VI_HIST_CTRL,
VI_HIST_POW_BIT, VI_HIST_POW_WID);
vf->prop.hist.vpp_luma_sum = READ_VPP_REG(VI_HIST_SPL_VAL);
/* vf->prop.hist.chroma_sum = READ_CBUS_REG_BITS(VDIN_HIST_CHROMA_SUM,*/
/* HIST_CHROMA_SUM_BIT, HIST_CHROMA_SUM_WID ); */
vf->prop.hist.vpp_chroma_sum = READ_VPP_REG(VI_HIST_CHROMA_SUM);
vf->prop.hist.vpp_pixel_sum = READ_VPP_REG_BITS(VI_HIST_SPL_PIX_CNT,
VI_HIST_PIX_CNT_BIT, VI_HIST_PIX_CNT_WID);
vf->prop.hist.vpp_height = READ_VPP_REG_BITS(VI_HIST_PIC_SIZE,
VI_HIST_PIC_HEIGHT_BIT, VI_HIST_PIC_HEIGHT_WID);
vf->prop.hist.vpp_width = READ_VPP_REG_BITS(VI_HIST_PIC_SIZE,
VI_HIST_PIC_WIDTH_BIT, VI_HIST_PIC_WIDTH_WID);
vf->prop.hist.vpp_luma_max = READ_VPP_REG_BITS(VI_HIST_MAX_MIN,
VI_HIST_MAX_BIT, VI_HIST_MAX_WID);
vf->prop.hist.vpp_luma_min = READ_VPP_REG_BITS(VI_HIST_MAX_MIN,
VI_HIST_MIN_BIT, VI_HIST_MIN_WID);
vf->prop.hist.vpp_gamma[0] = READ_VPP_REG_BITS(VI_DNLP_HIST00,
VI_HIST_ON_BIN_00_BIT, VI_HIST_ON_BIN_00_WID);
vf->prop.hist.vpp_gamma[1] = READ_VPP_REG_BITS(VI_DNLP_HIST00,
VI_HIST_ON_BIN_01_BIT, VI_HIST_ON_BIN_01_WID);
vf->prop.hist.vpp_gamma[2] = READ_VPP_REG_BITS(VI_DNLP_HIST01,
VI_HIST_ON_BIN_02_BIT, VI_HIST_ON_BIN_02_WID);
vf->prop.hist.vpp_gamma[3] = READ_VPP_REG_BITS(VI_DNLP_HIST01,
VI_HIST_ON_BIN_03_BIT, VI_HIST_ON_BIN_03_WID);
vf->prop.hist.vpp_gamma[4] = READ_VPP_REG_BITS(VI_DNLP_HIST02,
VI_HIST_ON_BIN_04_BIT, VI_HIST_ON_BIN_04_WID);
vf->prop.hist.vpp_gamma[5] = READ_VPP_REG_BITS(VI_DNLP_HIST02,
VI_HIST_ON_BIN_05_BIT, VI_HIST_ON_BIN_05_WID);
vf->prop.hist.vpp_gamma[6] = READ_VPP_REG_BITS(VI_DNLP_HIST03,
VI_HIST_ON_BIN_06_BIT, VI_HIST_ON_BIN_06_WID);
vf->prop.hist.vpp_gamma[7] = READ_VPP_REG_BITS(VI_DNLP_HIST03,
VI_HIST_ON_BIN_07_BIT, VI_HIST_ON_BIN_07_WID);
vf->prop.hist.vpp_gamma[8] = READ_VPP_REG_BITS(VI_DNLP_HIST04,
VI_HIST_ON_BIN_08_BIT, VI_HIST_ON_BIN_08_WID);
vf->prop.hist.vpp_gamma[9] = READ_VPP_REG_BITS(VI_DNLP_HIST04,
VI_HIST_ON_BIN_09_BIT, VI_HIST_ON_BIN_09_WID);
vf->prop.hist.vpp_gamma[10] = READ_VPP_REG_BITS(VI_DNLP_HIST05,
VI_HIST_ON_BIN_10_BIT, VI_HIST_ON_BIN_10_WID);
vf->prop.hist.vpp_gamma[11] = READ_VPP_REG_BITS(VI_DNLP_HIST05,
VI_HIST_ON_BIN_11_BIT, VI_HIST_ON_BIN_11_WID);
vf->prop.hist.vpp_gamma[12] = READ_VPP_REG_BITS(VI_DNLP_HIST06,
VI_HIST_ON_BIN_12_BIT, VI_HIST_ON_BIN_12_WID);
vf->prop.hist.vpp_gamma[13] = READ_VPP_REG_BITS(VI_DNLP_HIST06,
VI_HIST_ON_BIN_13_BIT, VI_HIST_ON_BIN_13_WID);
vf->prop.hist.vpp_gamma[14] = READ_VPP_REG_BITS(VI_DNLP_HIST07,
VI_HIST_ON_BIN_14_BIT, VI_HIST_ON_BIN_14_WID);
vf->prop.hist.vpp_gamma[15] = READ_VPP_REG_BITS(VI_DNLP_HIST07,
VI_HIST_ON_BIN_15_BIT, VI_HIST_ON_BIN_15_WID);
vf->prop.hist.vpp_gamma[16] = READ_VPP_REG_BITS(VI_DNLP_HIST08,
VI_HIST_ON_BIN_16_BIT, VI_HIST_ON_BIN_16_WID);
vf->prop.hist.vpp_gamma[17] = READ_VPP_REG_BITS(VI_DNLP_HIST08,
VI_HIST_ON_BIN_17_BIT, VI_HIST_ON_BIN_17_WID);
vf->prop.hist.vpp_gamma[18] = READ_VPP_REG_BITS(VI_DNLP_HIST09,
VI_HIST_ON_BIN_18_BIT, VI_HIST_ON_BIN_18_WID);
vf->prop.hist.vpp_gamma[19] = READ_VPP_REG_BITS(VI_DNLP_HIST09,
VI_HIST_ON_BIN_19_BIT, VI_HIST_ON_BIN_19_WID);
vf->prop.hist.vpp_gamma[20] = READ_VPP_REG_BITS(VI_DNLP_HIST10,
VI_HIST_ON_BIN_20_BIT, VI_HIST_ON_BIN_20_WID);
vf->prop.hist.vpp_gamma[21] = READ_VPP_REG_BITS(VI_DNLP_HIST10,
VI_HIST_ON_BIN_21_BIT, VI_HIST_ON_BIN_21_WID);
vf->prop.hist.vpp_gamma[22] = READ_VPP_REG_BITS(VI_DNLP_HIST11,
VI_HIST_ON_BIN_22_BIT, VI_HIST_ON_BIN_22_WID);
vf->prop.hist.vpp_gamma[23] = READ_VPP_REG_BITS(VI_DNLP_HIST11,
VI_HIST_ON_BIN_23_BIT, VI_HIST_ON_BIN_23_WID);
vf->prop.hist.vpp_gamma[24] = READ_VPP_REG_BITS(VI_DNLP_HIST12,
VI_HIST_ON_BIN_24_BIT, VI_HIST_ON_BIN_24_WID);
vf->prop.hist.vpp_gamma[25] = READ_VPP_REG_BITS(VI_DNLP_HIST12,
VI_HIST_ON_BIN_25_BIT, VI_HIST_ON_BIN_25_WID);
vf->prop.hist.vpp_gamma[26] = READ_VPP_REG_BITS(VI_DNLP_HIST13,
VI_HIST_ON_BIN_26_BIT, VI_HIST_ON_BIN_26_WID);
vf->prop.hist.vpp_gamma[27] = READ_VPP_REG_BITS(VI_DNLP_HIST13,
VI_HIST_ON_BIN_27_BIT, VI_HIST_ON_BIN_27_WID);
vf->prop.hist.vpp_gamma[28] = READ_VPP_REG_BITS(VI_DNLP_HIST14,
VI_HIST_ON_BIN_28_BIT, VI_HIST_ON_BIN_28_WID);
vf->prop.hist.vpp_gamma[29] = READ_VPP_REG_BITS(VI_DNLP_HIST14,
VI_HIST_ON_BIN_29_BIT, VI_HIST_ON_BIN_29_WID);
vf->prop.hist.vpp_gamma[30] = READ_VPP_REG_BITS(VI_DNLP_HIST15,
VI_HIST_ON_BIN_30_BIT, VI_HIST_ON_BIN_30_WID);
vf->prop.hist.vpp_gamma[31] = READ_VPP_REG_BITS(VI_DNLP_HIST15,
VI_HIST_ON_BIN_31_BIT, VI_HIST_ON_BIN_31_WID);
vf->prop.hist.vpp_gamma[32] = READ_VPP_REG_BITS(VI_DNLP_HIST16,
VI_HIST_ON_BIN_32_BIT, VI_HIST_ON_BIN_32_WID);
vf->prop.hist.vpp_gamma[33] = READ_VPP_REG_BITS(VI_DNLP_HIST16,
VI_HIST_ON_BIN_33_BIT, VI_HIST_ON_BIN_33_WID);
vf->prop.hist.vpp_gamma[34] = READ_VPP_REG_BITS(VI_DNLP_HIST17,
VI_HIST_ON_BIN_34_BIT, VI_HIST_ON_BIN_34_WID);
vf->prop.hist.vpp_gamma[35] = READ_VPP_REG_BITS(VI_DNLP_HIST17,
VI_HIST_ON_BIN_35_BIT, VI_HIST_ON_BIN_35_WID);
vf->prop.hist.vpp_gamma[36] = READ_VPP_REG_BITS(VI_DNLP_HIST18,
VI_HIST_ON_BIN_36_BIT, VI_HIST_ON_BIN_36_WID);
vf->prop.hist.vpp_gamma[37] = READ_VPP_REG_BITS(VI_DNLP_HIST18,
VI_HIST_ON_BIN_37_BIT, VI_HIST_ON_BIN_37_WID);
vf->prop.hist.vpp_gamma[38] = READ_VPP_REG_BITS(VI_DNLP_HIST19,
VI_HIST_ON_BIN_38_BIT, VI_HIST_ON_BIN_38_WID);
vf->prop.hist.vpp_gamma[39] = READ_VPP_REG_BITS(VI_DNLP_HIST19,
VI_HIST_ON_BIN_39_BIT, VI_HIST_ON_BIN_39_WID);
vf->prop.hist.vpp_gamma[40] = READ_VPP_REG_BITS(VI_DNLP_HIST20,
VI_HIST_ON_BIN_40_BIT, VI_HIST_ON_BIN_40_WID);
vf->prop.hist.vpp_gamma[41] = READ_VPP_REG_BITS(VI_DNLP_HIST20,
VI_HIST_ON_BIN_41_BIT, VI_HIST_ON_BIN_41_WID);
vf->prop.hist.vpp_gamma[42] = READ_VPP_REG_BITS(VI_DNLP_HIST21,
VI_HIST_ON_BIN_42_BIT, VI_HIST_ON_BIN_42_WID);
vf->prop.hist.vpp_gamma[43] = READ_VPP_REG_BITS(VI_DNLP_HIST21,
VI_HIST_ON_BIN_43_BIT, VI_HIST_ON_BIN_43_WID);
vf->prop.hist.vpp_gamma[44] = READ_VPP_REG_BITS(VI_DNLP_HIST22,
VI_HIST_ON_BIN_44_BIT, VI_HIST_ON_BIN_44_WID);
vf->prop.hist.vpp_gamma[45] = READ_VPP_REG_BITS(VI_DNLP_HIST22,
VI_HIST_ON_BIN_45_BIT, VI_HIST_ON_BIN_45_WID);
vf->prop.hist.vpp_gamma[46] = READ_VPP_REG_BITS(VI_DNLP_HIST23,
VI_HIST_ON_BIN_46_BIT, VI_HIST_ON_BIN_46_WID);
vf->prop.hist.vpp_gamma[47] = READ_VPP_REG_BITS(VI_DNLP_HIST23,
VI_HIST_ON_BIN_47_BIT, VI_HIST_ON_BIN_47_WID);
vf->prop.hist.vpp_gamma[48] = READ_VPP_REG_BITS(VI_DNLP_HIST24,
VI_HIST_ON_BIN_48_BIT, VI_HIST_ON_BIN_48_WID);
vf->prop.hist.vpp_gamma[49] = READ_VPP_REG_BITS(VI_DNLP_HIST24,
VI_HIST_ON_BIN_49_BIT, VI_HIST_ON_BIN_49_WID);
vf->prop.hist.vpp_gamma[50] = READ_VPP_REG_BITS(VI_DNLP_HIST25,
VI_HIST_ON_BIN_50_BIT, VI_HIST_ON_BIN_50_WID);
vf->prop.hist.vpp_gamma[51] = READ_VPP_REG_BITS(VI_DNLP_HIST25,
VI_HIST_ON_BIN_51_BIT, VI_HIST_ON_BIN_51_WID);
vf->prop.hist.vpp_gamma[52] = READ_VPP_REG_BITS(VI_DNLP_HIST26,
VI_HIST_ON_BIN_52_BIT, VI_HIST_ON_BIN_52_WID);
vf->prop.hist.vpp_gamma[53] = READ_VPP_REG_BITS(VI_DNLP_HIST26,
VI_HIST_ON_BIN_53_BIT, VI_HIST_ON_BIN_53_WID);
vf->prop.hist.vpp_gamma[54] = READ_VPP_REG_BITS(VI_DNLP_HIST27,
VI_HIST_ON_BIN_54_BIT, VI_HIST_ON_BIN_54_WID);
vf->prop.hist.vpp_gamma[55] = READ_VPP_REG_BITS(VI_DNLP_HIST27,
VI_HIST_ON_BIN_55_BIT, VI_HIST_ON_BIN_55_WID);
vf->prop.hist.vpp_gamma[56] = READ_VPP_REG_BITS(VI_DNLP_HIST28,
VI_HIST_ON_BIN_56_BIT, VI_HIST_ON_BIN_56_WID);
vf->prop.hist.vpp_gamma[57] = READ_VPP_REG_BITS(VI_DNLP_HIST28,
VI_HIST_ON_BIN_57_BIT, VI_HIST_ON_BIN_57_WID);
vf->prop.hist.vpp_gamma[58] = READ_VPP_REG_BITS(VI_DNLP_HIST29,
VI_HIST_ON_BIN_58_BIT, VI_HIST_ON_BIN_58_WID);
vf->prop.hist.vpp_gamma[59] = READ_VPP_REG_BITS(VI_DNLP_HIST29,
VI_HIST_ON_BIN_59_BIT, VI_HIST_ON_BIN_59_WID);
vf->prop.hist.vpp_gamma[60] = READ_VPP_REG_BITS(VI_DNLP_HIST30,
VI_HIST_ON_BIN_60_BIT, VI_HIST_ON_BIN_60_WID);
vf->prop.hist.vpp_gamma[61] = READ_VPP_REG_BITS(VI_DNLP_HIST30,
VI_HIST_ON_BIN_61_BIT, VI_HIST_ON_BIN_61_WID);
vf->prop.hist.vpp_gamma[62] = READ_VPP_REG_BITS(VI_DNLP_HIST31,
VI_HIST_ON_BIN_62_BIT, VI_HIST_ON_BIN_62_WID);
vf->prop.hist.vpp_gamma[63] = READ_VPP_REG_BITS(VI_DNLP_HIST31,
VI_HIST_ON_BIN_63_BIT, VI_HIST_ON_BIN_63_WID);
if (debug_game_mode_1 &&
(vpp_luma_max != vf->prop.hist.vpp_luma_max)) {
divid = vf->ready_clock_hist[1] = sched_clock();
do_div(divid, 1000);
pr_info("vpp output done %lld us. luma_max(0x%x-->0x%x)\n",
divid, vpp_luma_max, vf->prop.hist.vpp_luma_max);
vpp_luma_max = vf->prop.hist.vpp_luma_max;
}
}
static void ioctrl_get_hdr_metadata(struct vframe_s *vf)
{
if (((vf->signal_type >> 16) & 0xff) == 9) {
if (vf->prop.master_display_colour.present_flag) {
memcpy(vpp_hdr_metadata_s.primaries,
vf->prop.master_display_colour.primaries,
sizeof(u32)*6);
memcpy(vpp_hdr_metadata_s.white_point,
vf->prop.master_display_colour.white_point,
sizeof(u32)*2);
vpp_hdr_metadata_s.luminance[0] =
vf->prop.master_display_colour.luminance[0];
vpp_hdr_metadata_s.luminance[1] =
vf->prop.master_display_colour.luminance[1];
} else
memset(vpp_hdr_metadata_s.primaries, 0,
sizeof(vpp_hdr_metadata_s.primaries));
} else
memset(vpp_hdr_metadata_s.primaries, 0,
sizeof(vpp_hdr_metadata_s.primaries));
}
void vpp_demo_config(struct vframe_s *vf)
{
unsigned int reg_value;
/*dnlp demo config*/
if (vpp_demo_latch_flag & VPP_DEMO_DNLP_EN) {
WRITE_VPP_REG_BITS(VPP_VE_ENABLE_CTRL, 1, 18, 1);
/*bit14-15 left: 2 right: 3*/
WRITE_VPP_REG_BITS(VPP_VE_ENABLE_CTRL, 2, 14, 2);
reg_value = READ_VPP_REG_BITS(VPP_SRSHARP1_CTRL, 0, 1);
if (((vf->height > 1080) && (vf->width > 1920)) ||
(reg_value == 0))
WRITE_VPP_REG_BITS(VPP_VE_DEMO_LEFT_TOP_SCREEN_WIDTH,
1920, 0, 12);
else
WRITE_VPP_REG_BITS(VPP_VE_DEMO_LEFT_TOP_SCREEN_WIDTH,
960, 0, 12);
vpp_demo_latch_flag &= ~VPP_DEMO_DNLP_EN;
} else if (vpp_demo_latch_flag & VPP_DEMO_DNLP_DIS) {
WRITE_VPP_REG_BITS(VPP_VE_ENABLE_CTRL, 0, 18, 1);
WRITE_VPP_REG_BITS(VPP_VE_ENABLE_CTRL, 0, 14, 2);
WRITE_VPP_REG_BITS(VPP_VE_DEMO_LEFT_TOP_SCREEN_WIDTH,
0xfff, 0, 12);
vpp_demo_latch_flag &= ~VPP_DEMO_DNLP_DIS;
}
/*cm demo config*/
if (vpp_demo_latch_flag & VPP_DEMO_CM_EN) {
/*left: 0x1 right: 0x4*/
WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, 0x20f);
WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, 0x1);
vpp_demo_latch_flag &= ~VPP_DEMO_CM_EN;
} else if (vpp_demo_latch_flag & VPP_DEMO_CM_DIS) {
WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, 0x20f);
WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, 0x0);
vpp_demo_latch_flag &= ~VPP_DEMO_CM_DIS;
}
}
void amvecm_video_latch(void)
{
pc_mode_process();
cm_latch_process();
amvecm_size_patch();
ve_dnlp_latch_process();
ve_lcd_gamma_process();
lvds_freq_process();
/* #if (MESON_CPU_TYPE >= MESON_CPU_TYPE_MESONG9TV) */
if (0) {
amvecm_3d_sync_process();
amvecm_3d_black_process();
}
/* #endif */
pq_user_latch_process();
if (cpu_after_eq(MESON_CPU_MAJOR_ID_TL1))
ve_lc_latch_process();
}
int amvecm_on_vs(
struct vframe_s *vf,
struct vframe_s *toggle_vf,
int flags,
unsigned int sps_h_en,
unsigned int sps_v_en)
{
int result = 0;
if (probe_ok == 0)
return 0;
#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
if (for_dolby_vision_certification())
return 0;
#endif
if (!dnlp_insmod_ok)
dnlp_alg_param_init();
if (flags & CSC_FLAG_CHECK_OUTPUT) {
if (toggle_vf)
amvecm_fresh_overscan(toggle_vf);
else if (vf)
amvecm_fresh_overscan(vf);
/* to test if output will change */
return amvecm_matrix_process(
toggle_vf, vf, flags);
}
if ((toggle_vf != NULL) || (vf != NULL)) {
/* matrix adjust */
result = amvecm_matrix_process(toggle_vf, vf, flags);
if (toggle_vf)
ioctrl_get_hdr_metadata(toggle_vf);
if (toggle_vf)
lc_process(toggle_vf, sps_h_en, sps_v_en);
} else {
amvecm_reset_overscan();
result = amvecm_matrix_process(NULL, NULL, flags);
ve_hist_gamma_reset();
lc_process(NULL, sps_h_en, sps_v_en);
}
if (!is_dolby_vision_on())
get_hdr_source_type();
/* add some flag to trigger */
if (vf) {
/*gxlx sharpness adaptive setting*/
if (is_meson_gxlx_cpu())
amve_sharpness_adaptive_setting(vf,
sps_h_en, sps_v_en);
amvecm_bricon_process(
vd1_brightness,
vd1_contrast + vd1_contrast_offset, vf);
amvecm_color_process(
saturation_pre + saturation_offset,
hue_pre, vf);
vpp_demo_config(vf);
}
if (vf)
amvecm_fresh_overscan(vf);
else
amvecm_reset_overscan();
/* pq latch process */
amvecm_video_latch();
return result;
}
EXPORT_SYMBOL(amvecm_on_vs);
void refresh_on_vs(struct vframe_s *vf)
{
if (probe_ok == 0)
return;
if (vf != NULL) {
vpp_get_vframe_hist_info(vf);
#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
if (!for_dolby_vision_certification())
#endif
ve_on_vs(vf);
vpp_backup_histgram(vf);
}
}
EXPORT_SYMBOL(refresh_on_vs);
static int amvecm_open(struct inode *inode, struct file *file)
{
struct amvecm_dev_s *devp;
/* Get the per-device structure that contains this cdev */
devp = container_of(inode->i_cdev, struct amvecm_dev_s, cdev);
file->private_data = devp;
/*init queue*/
init_waitqueue_head(&devp->hdr_queue);
return 0;
}
static int amvecm_release(struct inode *inode, struct file *file)
{
file->private_data = NULL;
return 0;
}
static struct am_regs_s amregs_ext;
struct ve_pq_overscan_s overscan_table[TIMING_MAX];
static int parse_para_pq(const char *para, int para_num, int *result)
{
char *token = NULL;
char *params, *params_base;
int *out = result;
int len = 0, count = 0;
int res = 0;
if (!para)
return 0;
params = kstrdup(para, GFP_KERNEL);
params_base = params;
token = params;
len = strlen(token);
do {
token = strsep(&params, " ");
while (token && (isspace(*token)
|| !isgraph(*token)) && len) {
token++;
len--;
}
if (len == 0)
break;
if (!token || kstrtoint(token, 0, &res) < 0)
break;
len = strlen(token);
*out++ = res;
count++;
} while ((token) && (count < para_num) && (len > 0));
kfree(params_base);
return count;
}
static int amvecm_set_saturation_hue(int mab)
{
s16 mc = 0, md = 0;
s16 ma, mb;
if (mab&0xfc00fc00)
return -EINVAL;
ma = (s16)((mab << 6) >> 22);
mb = (s16)((mab << 22) >> 22);
saturation_ma = ma - 0x100;
saturation_mb = mb;
ma += saturation_ma_shift;
mb += saturation_mb_shift;
if (ma > 511)
ma = 511;
if (ma < -512)
ma = -512;
if (mb > 511)
mb = 511;
if (mb < -512)
mb = -512;
mab = ((ma & 0x3ff) << 16) | (mb & 0x3ff);
if (get_cpu_type() == MESON_CPU_MAJOR_ID_TL1)
WRITE_VPP_REG(VPP_VADJ1_MA_MB_2, mab);
else
WRITE_VPP_REG(VPP_VADJ1_MA_MB, mab);
mc = (s16)((mab<<22)>>22); /* mc = -mb */
mc = 0 - mc;
if (mc > 511)
mc = 511;
if (mc < -512)
mc = -512;
md = (s16)((mab<<6)>>22); /* md = ma; */
mab = ((mc&0x3ff)<<16)|(md&0x3ff);
if (get_cpu_type() == MESON_CPU_MAJOR_ID_TL1) {
WRITE_VPP_REG(VPP_VADJ1_MC_MD_2, mab);
WRITE_VPP_REG_BITS(VPP_VADJ1_MISC, 1, 0, 1);
} else {
WRITE_VPP_REG(VPP_VADJ1_MC_MD, mab);
WRITE_VPP_REG_BITS(VPP_VADJ_CTRL, 1, 0, 1);
}
pr_amvecm_dbg("%s set video_saturation_hue OK!!!\n", __func__);
return 0;
}
static int amvecm_set_saturation_hue_post(int val1,
int val2)
{
int i, ma, mb, mab, mc, md;
int hue_cos_len, hue_sin_len;
int hue_cos[] = {
/*0~12*/
256, 256, 256, 255, 255, 254, 253, 252, 251, 250,
248, 247, 245, 243, 241, 239, 237, 234, 231, 229,
226, 223, 220, 216, 213, 209 /*13~25*/
};
int hue_sin[] = {
-147, -142, -137, -132, -126, -121, -115, -109, -104,
-98, -92, -86, -80, /*-25~-13*/-74, -68, -62, -56,
-50, -44, -38, -31, -25, -19, -13, -6, /*-12~-1*/
0, /*0*/
6, 13, 19, 25, 31, 38, 44, 50, 56,
62, 68, 74, /*1~12*/ 80, 86, 92, 98, 104,
109, 115, 121, 126, 132, 137, 142, 147 /*13~25*/
};
hue_cos_len = sizeof(hue_cos)/sizeof(int);
hue_sin_len = sizeof(hue_sin)/sizeof(int);
i = (val2 > 0) ? val2 : -val2;
if ((val1 < -128) || (val1 > 128) ||
(val2 < -25) || (val2 > 25) ||
(i >= hue_cos_len) ||
(val2 >= hue_sin_len - 25))
return -EINVAL;
saturation_post = val1;
hue_post = val2;
ma = (hue_cos[i]*(saturation_post + 128)) >> 7;
mb = (hue_sin[25+hue_post]*(saturation_post + 128)) >> 7;
if (ma > 511)
ma = 511;
if (ma < -512)
ma = -512;
if (mb > 511)
mb = 511;
if (mb < -512)
mb = -512;
mab = ((ma & 0x3ff) << 16) | (mb & 0x3ff);
pr_info("\n[amvideo..] saturation_post:%d hue_post:%d mab:%x\n",
saturation_post, hue_post, mab);
if (get_cpu_type() == MESON_CPU_MAJOR_ID_TL1)
WRITE_VPP_REG(VPP_VADJ2_MA_MB_2, mab);
else
WRITE_VPP_REG(VPP_VADJ2_MA_MB, mab);
mc = (s16)((mab<<22)>>22); /* mc = -mb */
mc = 0 - mc;
if (mc > 511)
mc = 511;
if (mc < -512)
mc = -512;
md = (s16)((mab<<6)>>22); /* md = ma; */
mab = ((mc&0x3ff)<<16)|(md&0x3ff);
if (get_cpu_type() == MESON_CPU_MAJOR_ID_TL1) {
WRITE_VPP_REG(VPP_VADJ2_MC_MD_2, mab);
WRITE_VPP_REG_BITS(VPP_VADJ2_MISC, 1, 0, 1);
} else {
WRITE_VPP_REG(VPP_VADJ2_MC_MD, mab);
WRITE_VPP_REG_BITS(VPP_VADJ_CTRL, 1, 2, 1);
}
return 0;
}
static int gamma_table_compare(struct tcon_gamma_table_s *table1,
struct tcon_gamma_table_s *table2)
{
int i = 0, flag = 0;
for (i = 0; i < 256; i++)
if (table1->data[i] != table2->data[i]) {
flag = 1;
break;
}
return flag;
}
static void parse_overscan_table(unsigned int length,
struct ve_pq_table_s *amvecm_pq_load_table)
{
unsigned int i;
unsigned int offset = TIMING_UHD + 1;
memset(overscan_table, 0, sizeof(overscan_table));
for (i = 0; i < length; i++) {
overscan_table[i].load_flag =
(amvecm_pq_load_table[i].src_timing >> 31) & 0x1;
overscan_table[i].afd_enable =
(amvecm_pq_load_table[i].src_timing >> 30) & 0x1;
overscan_table[i].screen_mode =
(amvecm_pq_load_table[i].src_timing >> 24) & 0x3f;
overscan_table[i].source =
(amvecm_pq_load_table[i].src_timing >> 16) & 0xff;
overscan_table[i].timing =
amvecm_pq_load_table[i].src_timing & 0xffff;
overscan_table[i].hs =
amvecm_pq_load_table[i].value1 & 0xffff;
overscan_table[i].he =
(amvecm_pq_load_table[i].value1 >> 16) & 0xffff;
overscan_table[i].vs =
amvecm_pq_load_table[i].value2 & 0xffff;
overscan_table[i].ve =
(amvecm_pq_load_table[i].value2 >> 16) & 0xffff;
}
/*because SOURCE_TV is 0,so need to add a flg to check ATV*/
if ((overscan_table[offset].load_flag == 1) &&
(overscan_table[offset].source == SOURCE_TV))
atv_source_flg = 1;
else
atv_source_flg = 0;
}
static long amvecm_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
int ret = 0;
void __user *argp;
unsigned int mem_size;
struct ve_pq_load_s vpp_pq_load;
struct ve_pq_table_s *vpp_pq_load_table = NULL;
enum color_primary_e color_pri;
if (debug_amvecm & 2)
pr_info("[amvecm..] %s: cmd_nr = 0x%x\n",
__func__, _IOC_NR(cmd));
if (probe_ok == 0)
return ret;
if (pq_load_en == 0) {
pr_amvecm_dbg("[amvecm..] pq ioctl function disabled !!\n");
return ret;
}
switch (cmd) {
case AMVECM_IOC_LOAD_REG:
if ((vecm_latch_flag & FLAG_REG_MAP0) &&
(vecm_latch_flag & FLAG_REG_MAP1) &&
(vecm_latch_flag & FLAG_REG_MAP2) &&
(vecm_latch_flag & FLAG_REG_MAP3) &&
(vecm_latch_flag & FLAG_REG_MAP4) &&
(vecm_latch_flag & FLAG_REG_MAP5)) {
ret = -EBUSY;
pr_amvecm_dbg("load regs error: loading regs, please wait\n");
break;
}
if (copy_from_user(&amregs_ext,
(void __user *)arg, sizeof(struct am_regs_s))) {
pr_amvecm_dbg("0x%x load reg errors: can't get buffer length\n",
FLAG_REG_MAP0);
ret = -EFAULT;
} else
ret = cm_load_reg(&amregs_ext);
break;
case AMVECM_IOC_VE_NEW_DNLP:
if (copy_from_user(&dnlp_curve_param_load,
(void __user *)arg,
sizeof(struct ve_dnlp_curve_param_s))) {
pr_amvecm_dbg("dnlp load fail\n");
ret = -EFAULT;
} else {
ve_new_dnlp_param_update();
pr_amvecm_dbg("dnlp load success\n");
}
break;
case AMVECM_IOC_G_HIST_AVG:
argp = (void __user *)arg;
if ((video_ve_hist.height == 0) || (video_ve_hist.width == 0))
ret = -EFAULT;
else if (copy_to_user(argp,
&video_ve_hist,
sizeof(struct ve_hist_s)))
ret = -EFAULT;
break;
case AMVECM_IOC_G_HIST_BIN:
argp = (void __user *)arg;
if (vpp_hist_param.vpp_pixel_sum == 0)
ret = -EFAULT;
else if (copy_to_user(argp, &vpp_hist_param,
sizeof(struct vpp_hist_param_s)))
ret = -EFAULT;
break;
case AMVECM_IOC_G_HDR_METADATA:
argp = (void __user *)arg;
if (copy_to_user(argp, &vpp_hdr_metadata_s,
sizeof(struct hdr_metadata_info_s)))
ret = -EFAULT;
break;
/**********************************************************************/
/*gamma ioctl*/
/**********************************************************************/
case AMVECM_IOC_GAMMA_TABLE_EN:
if (!gamma_en)
return -EINVAL;
vecm_latch_flag |= FLAG_GAMMA_TABLE_EN;
break;
case AMVECM_IOC_GAMMA_TABLE_DIS:
if (!gamma_en)
return -EINVAL;
vecm_latch_flag |= FLAG_GAMMA_TABLE_DIS;
break;
case AMVECM_IOC_GAMMA_TABLE_R:
if (!gamma_en)
return -EINVAL;
if (copy_from_user(&video_gamma_table_ioctl_set,
(void __user *)arg,
sizeof(struct tcon_gamma_table_s)))
ret = -EFAULT;
else if (gamma_table_compare(&video_gamma_table_ioctl_set,
&video_gamma_table_r)) {
memcpy(&video_gamma_table_r,
&video_gamma_table_ioctl_set,
sizeof(struct tcon_gamma_table_s));
vecm_latch_flag |= FLAG_GAMMA_TABLE_R;
} else
pr_amvecm_dbg("load same gamma_r table,no need to change\n");
break;
case AMVECM_IOC_GAMMA_TABLE_G:
if (!gamma_en)
return -EINVAL;
if (copy_from_user(&video_gamma_table_ioctl_set,
(void __user *)arg,
sizeof(struct tcon_gamma_table_s)))
ret = -EFAULT;
else if (gamma_table_compare(&video_gamma_table_ioctl_set,
&video_gamma_table_g)) {
memcpy(&video_gamma_table_g,
&video_gamma_table_ioctl_set,
sizeof(struct tcon_gamma_table_s));
vecm_latch_flag |= FLAG_GAMMA_TABLE_G;
} else
pr_amvecm_dbg("load same gamma_g table,no need to change\n");
break;
case AMVECM_IOC_GAMMA_TABLE_B:
if (!gamma_en)
return -EINVAL;
if (copy_from_user(&video_gamma_table_ioctl_set,
(void __user *)arg,
sizeof(struct tcon_gamma_table_s)))
ret = -EFAULT;
else if (gamma_table_compare(&video_gamma_table_ioctl_set,
&video_gamma_table_b)) {
memcpy(&video_gamma_table_b,
&video_gamma_table_ioctl_set,
sizeof(struct tcon_gamma_table_s));
vecm_latch_flag |= FLAG_GAMMA_TABLE_B;
} else
pr_amvecm_dbg("load same gamma_b table,no need to change\n");
break;
case AMVECM_IOC_S_RGB_OGO:
if (!wb_en)
return -EINVAL;
if (copy_from_user(&video_rgb_ogo,
(void __user *)arg,
sizeof(struct tcon_rgb_ogo_s)))
ret = -EFAULT;
else
ve_ogo_param_update();
break;
case AMVECM_IOC_G_RGB_OGO:
if (!wb_en)
return -EINVAL;
if (copy_to_user((void __user *)arg,
&video_rgb_ogo, sizeof(struct tcon_rgb_ogo_s)))
ret = -EFAULT;
break;
/*VLOCK*/
case AMVECM_IOC_VLOCK_EN:
vecm_latch_flag |= FLAG_VLOCK_EN;
break;
case AMVECM_IOC_VLOCK_DIS:
vecm_latch_flag |= FLAG_VLOCK_DIS;
break;
/*3D-SYNC*/
case AMVECM_IOC_3D_SYNC_EN:
vecm_latch_flag |= FLAG_3D_SYNC_EN;
break;
case AMVECM_IOC_3D_SYNC_DIS:
vecm_latch_flag |= FLAG_3D_SYNC_DIS;
break;
case AMVECM_IOC_SET_OVERSCAN:
if (copy_from_user(&vpp_pq_load,
(void __user *)arg,
sizeof(struct ve_pq_load_s))) {
ret = -EFAULT;
pr_amvecm_dbg("[amvecm..] pq ioctl copy fail!!\n");
break;
}
if (!(vpp_pq_load.param_id & TABLE_NAME_OVERSCAN)) {
ret = -EFAULT;
pr_amvecm_dbg("[amvecm..] overscan ioctl param_id fail!!\n");
break;
}
/*check pq_table length copy_from_user*/
if ((vpp_pq_load.length > TIMING_MAX) ||
(vpp_pq_load.length <= 0)) {
ret = -EFAULT;
pr_amvecm_dbg("[amvecm..] pq ioctl length check fail!!\n");
break;
}
mem_size = vpp_pq_load.length * sizeof(struct ve_pq_table_s);
vpp_pq_load_table = kmalloc(mem_size, GFP_KERNEL);
if (vpp_pq_load_table == NULL) {
pr_info("vpp_pq_load_table kmalloc fail!!!\n");
return -EFAULT;
}
argp = (void __user *)vpp_pq_load.param_ptr;
if (copy_from_user(vpp_pq_load_table, argp, mem_size)) {
pr_amvecm_dbg("[amvecm..] ovescan copy fail!!\n");
break;
}
parse_overscan_table(vpp_pq_load.length, vpp_pq_load_table);
break;
case AMVECM_IOC_G_DNLP_STATE:
if (copy_to_user((void __user *)arg,
&dnlp_en, sizeof(enum dnlp_state_e)))
ret = -EFAULT;
break;
case AMVECM_IOC_S_DNLP_STATE:
if (copy_from_user(&dnlp_en,
(void __user *)arg, sizeof(enum dnlp_state_e)))
ret = -EFAULT;
break;
case AMVECM_IOC_G_PQMODE:
argp = (void __user *)arg;
if (copy_to_user(argp,
&pc_mode, sizeof(enum pc_mode_e)))
ret = -EFAULT;
break;
case AMVECM_IOC_S_PQMODE:
if (copy_from_user(&pc_mode,
(void __user *)arg, sizeof(enum pc_mode_e)))
ret = -EFAULT;
else
pc_mode_last = 0xff;
break;
case AMVECM_IOC_G_CSCTYPE:
argp = (void __user *)arg;
if (copy_to_user(argp,
&cur_csc_type, sizeof(enum vpp_matrix_csc_e)))
ret = -EFAULT;
break;
case AMVECM_IOC_G_COLOR_PRI:
argp = (void __user *)arg;
color_pri = get_color_primary();
if (copy_to_user(argp,
&color_pri, sizeof(enum color_primary_e)))
ret = -EFAULT;
break;
case AMVECM_IOC_S_CSCTYPE:
if (copy_from_user(&cur_csc_type,
(void __user *)arg,
sizeof(enum vpp_matrix_csc_e))) {
ret = -EFAULT;
pr_amvecm_dbg("[amvecm..] cur_csc_type ioctl copy fail!!\n");
}
break;
case AMVECM_IOC_G_PIC_MODE:
argp = (void __user *)arg;
if (copy_to_user(argp,
&vdj_mode_s, sizeof(struct am_vdj_mode_s)))
ret = -EFAULT;
break;
case AMVECM_IOC_S_PIC_MODE:
if (copy_from_user(&vdj_mode_s,
(void __user *)arg,
sizeof(struct am_vdj_mode_s))) {
ret = -EFAULT;
pr_amvecm_dbg("[amvecm..] vdj_mode_s ioctl copy fail!!\n");
break;
}
vdj_mode_flg = vdj_mode_s.flag;
if (vdj_mode_flg & 0x1) { /*brightness*/
vd1_brightness = vdj_mode_s.brightness;
vecm_latch_flag |= FLAG_VADJ1_BRI;
}
if (vdj_mode_flg & 0x2) { /*brightness2*/
if ((vdj_mode_s.brightness2 < -255) ||
(vdj_mode_s.brightness2 > 255)) {
pr_amvecm_dbg("load brightness2 value invalid!!!\n");
return -EINVAL;
}
ret = amvecm_set_brightness2(vdj_mode_s.brightness2);
}
if (vdj_mode_flg & 0x4) { /*saturation_hue*/
ret =
amvecm_set_saturation_hue(vdj_mode_s.saturation_hue);
}
if (vdj_mode_flg & 0x8) { /*saturation_hue_post*/
int parsed[2];
int saturation_hue_post;
char *buf;
saturation_hue_post = vdj_mode_s.saturation_hue_post;
buf = (char *) &saturation_hue_post;
if (likely(parse_para_pq(buf, 2, parsed) != 2)) {
ret = -EINVAL;
break;
}
ret = amvecm_set_saturation_hue_post(parsed[0],
parsed[1]);
if (ret < 0)
break;
}
if (vdj_mode_flg & 0x10) { /*contrast*/
if ((vdj_mode_s.contrast < -1024)
|| (vdj_mode_s.contrast > 1024)) {
ret = -EINVAL;
pr_amvecm_dbg("[amvecm..] ioctrl contrast value invalid!!\n");
break;
}
vd1_contrast = vdj_mode_s.contrast;
vecm_latch_flag |= FLAG_VADJ1_CON;
vecm_latch_flag |= FLAG_VADJ1_COLOR;
}
if (vdj_mode_flg & 0x20) { /*constract2*/
if ((vdj_mode_s.contrast2 < -127)
|| (vdj_mode_s.contrast2 > 127)) {
ret = -EINVAL;
pr_amvecm_dbg("[amvecm..] ioctrl contrast2 value invalid!!\n");
break;
}
ret = amvecm_set_contrast2(vdj_mode_s.contrast2);
}
break;
case AMVECM_IOC_S_LC_CURVE:
if (copy_from_user(&lc_curve_parm_load,
(void __user *)arg,
sizeof(struct ve_lc_curve_parm_s))) {
pr_amvecm_dbg("lc load curve parm fail\n");
ret = -EFAULT;
} else {
ve_lc_curve_update();
pr_amvecm_dbg("lc load curve parm success\n");
}
break;
case AMVECM_IOC_G_HDR_TYPE:
argp = (void __user *)arg;
if (copy_to_user(argp,
&hdr_source_type, sizeof(enum hdr_type_e)))
ret = -EFAULT;
break;
default:
ret = -EINVAL;
break;
}
if (vpp_pq_load_table != NULL)
kfree(vpp_pq_load_table);
return ret;
}
#ifdef CONFIG_COMPAT
static long amvecm_compat_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
unsigned long ret;
arg = (unsigned long)compat_ptr(arg);
ret = amvecm_ioctl(file, cmd, arg);
return ret;
}
#endif
static ssize_t amvecm_dnlp_debug_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
return 0;
}
static void str_sapr_to_d(char *s, int *d, int n)
{
int i, j, count;
long value;
char des[9] = {0};
count = (strlen(s) + n - 2) / (n - 1);
for (i = 0; i < count; i++) {
for (j = 0; j < n - 1; j++)
des[j] = s[j + i * (n - 1)];
des[n - 1] = '\0';
if (kstrtol(des, 10, &value) < 0)
return;
d[i] = value;
}
}
static void d_convert_str(int num,
int num_num, char cur_s[], int char_bit, int bit_chose)
{
char buf[9] = {0};
int i, count;
if (bit_chose == 10)
snprintf(buf, sizeof(buf), "%d", num);
else if (bit_chose == 16)
snprintf(buf, sizeof(buf), "%x", num);
count = strlen(buf);
if (count > 4)
count = 4;
for (i = 0; i < count; i++)
buf[i + char_bit] = buf[i];
for (i = 0; i < char_bit; i++)
buf[i] = '0';
count = strlen(buf);
for (i = 0; i < char_bit; i++)
buf[i] = buf[count - char_bit + i];
if (num_num > 0) {
for (i = 0; i < char_bit; i++)
cur_s[i + num_num * char_bit] =
buf[i];
} else {
for (i = 0; i < char_bit; i++)
cur_s[i] = buf[i];
}
}
static ssize_t amvecm_dnlp_debug_store(struct class *cla,
struct class_attribute *attr, const char *buf, size_t count)
{
int i;
long val = 0;
unsigned int num;
char *buf_orig, *parm[8] = {NULL};
int curve_val[65] = {0};
char *stemp = NULL;
if (!buf)
return count;
stemp = kmalloc(400, GFP_KERNEL);
if (!stemp)
return 0;
memset(stemp, 0, 400);
buf_orig = kstrdup(buf, GFP_KERNEL);
parse_param_amvecm(buf_orig, (char **)&parm);
if (!dnlp_insmod_ok) {
pr_info("dnlp insmod fial\n");
goto free_buf;
}
if (!strcmp(parm[0], "r")) {/*read param*/
if (!strcmp(parm[1], "param")) {
if (!strcmp(parm[2], "all")) {
for (i = 0;
dnlp_parse_cmd[i].value; i++) {
pr_info("%d ",
*(dnlp_parse_cmd[i].value));
}
pr_info("\n");
} else
pr_info("error cmd\n");
} else {
for (i = 0;
dnlp_parse_cmd[i].value; i++) {
if (!strcmp(parm[1],
dnlp_parse_cmd[i].parse_string)) {
pr_info("%d\n",
*(dnlp_parse_cmd[i].value));
break;
}
}
dnlp_dbg_node_copy();
}
} else if (!strcmp(parm[0], "w")) {/*write param*/
for (i = 0; dnlp_parse_cmd[i].value; i++) {
if (!strcmp(parm[1],
dnlp_parse_cmd[i].parse_string)) {
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
*(dnlp_parse_cmd[i].value) = val;
pr_amvecm_dbg(" %s: %d\n",
dnlp_parse_cmd[i].parse_string,
*(dnlp_parse_cmd[i].value));
break;
}
dnlp_dbg_node_copy();
}
} else if (!strcmp(parm[0], "rc")) {/*read curve*/
if (!strcmp(parm[1], "scurv_low")) {
if (parm[2] == NULL) {
pr_info("error cmd\n");
goto free_buf;
} else if (!strcmp(parm[2], "all")) {
for (i = 0; i < 65; i++)
d_convert_str(dnlp_scurv_low_copy[i],
i, stemp, 4, 10);
pr_info("%s\n", stemp);
} else {
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
if ((val > 64) || (val < 0))
pr_info("error cmd\n");
else
pr_info("%d\n",
dnlp_scurv_low_copy[val]);
}
} else if (!strcmp(parm[1], "scurv_mid1")) {
if (parm[2] == NULL) {
pr_info("error cmd\n");
goto free_buf;
} else if (!strcmp(parm[2], "all")) {
for (i = 0; i < 65; i++)
d_convert_str(dnlp_scurv_mid1_copy[i],
i, stemp, 4, 10);
pr_info("%s\n", stemp);
} else {
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
if ((val > 64) || (val < 0))
pr_info("error cmd\n");
else
pr_info("%d\n",
dnlp_scurv_mid1_copy[val]);
}
} else if (!strcmp(parm[1], "scurv_mid2")) {
if (parm[2] == NULL) {
pr_info("error cmd\n");
goto free_buf;
} else if (!strcmp(parm[2], "all")) {
for (i = 0; i < 65; i++)
d_convert_str(dnlp_scurv_mid2_copy[i],
i, stemp, 4, 10);
pr_info("%s\n", stemp);
} else {
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
if ((val > 64) || (val < 0))
pr_info("error cmd\n");
else
pr_info("%d\n",
dnlp_scurv_mid2_copy[val]);
}
} else if (!strcmp(parm[1], "scurv_hgh1")) {
if (parm[2] == NULL) {
pr_info("error cmd\n");
goto free_buf;
} else if (!strcmp(parm[2], "all")) {
for (i = 0; i < 65; i++)
d_convert_str(dnlp_scurv_hgh1_copy[i],
i, stemp, 4, 10);
pr_info("%s\n", stemp);
} else {
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
if ((val > 64) || (val < 0))
pr_info("error cmd\n");
else
pr_info("%d\n",
dnlp_scurv_hgh1_copy[val]);
}
} else if (!strcmp(parm[1], "scurv_hgh2")) {
if (parm[2] == NULL) {
pr_info("error cmd\n");
goto free_buf;
} else if (!strcmp(parm[2], "all")) {
for (i = 0; i < 65; i++)
d_convert_str(dnlp_scurv_hgh2_copy[i],
i, stemp, 4, 10);
pr_info("%s\n", stemp);
} else {
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
if ((val > 64) || (val < 0))
pr_info("error cmd\n");
else
pr_info("%d\n",
dnlp_scurv_hgh2_copy[val]);
}
} else if (!strcmp(parm[1], "gain_var_lut49")) {
if (parm[2] == NULL) {
pr_info("error cmd\n");
goto free_buf;
} else if (!strcmp(parm[2], "all")) {
for (i = 0; i < 49; i++)
d_convert_str(gain_var_lut49_copy[i],
i, stemp, 4, 10);
pr_info("%s\n", stemp);
} else {
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
if ((val > 48) || (val < 0))
pr_info("error cmd\n");
else
pr_info("%d\n",
gain_var_lut49_copy[val]);
}
} else if (!strcmp(parm[1], "wext_gain")) {
if (parm[2] == NULL) {
pr_info("error cmd\n");
goto free_buf;
} else if (!strcmp(parm[2], "all")) {
for (i = 0; i < 48; i++)
d_convert_str(wext_gain_copy[i],
i, stemp, 4, 10);
pr_info("%s\n", stemp);
} else {
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
if ((val > 47) || (val < 0))
pr_info("error cmd\n");
else
pr_info("%d\n", wext_gain_copy[val]);
}
} else if (!strcmp(parm[1], "adp_thrd")) {
if (parm[2] == NULL) {
pr_info("error cmd\n");
goto free_buf;
} else if (!strcmp(parm[2], "all")) {
for (i = 0; i < 33; i++)
d_convert_str(adp_thrd_copy[i],
i, stemp, 4, 10);
pr_info("%s\n", stemp);
} else {
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
if ((val > 32) || (val < 0))
pr_info("error cmd\n");
else
pr_info("%d\n", adp_thrd_copy[val]);
}
} else if (!strcmp(parm[1], "reg_blk_boost_12")) {
if (parm[2] == NULL) {
pr_info("error cmd\n");
goto free_buf;
} else if (!strcmp(parm[2], "all")) {
for (i = 0; i < 13; i++)
d_convert_str(reg_blk_boost_12_copy[i],
i, stemp, 4, 10);
pr_info("%s\n", stemp);
} else {
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
if ((val > 12) || (val < 0))
pr_info("error cmd\n");
else
pr_info("%d\n",
reg_blk_boost_12_copy[val]);
}
} else if (!strcmp(parm[1], "reg_adp_ofset_20")) {
if (parm[2] == NULL) {
pr_info("error cmd\n");
goto free_buf;
} else if (!strcmp(parm[2], "all")) {
for (i = 0; i < 20; i++)
d_convert_str(reg_adp_ofset_20_copy[i],
i, stemp, 4, 10);
pr_info("%s\n", stemp);
} else {
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
if ((val > 19) || (val < 0))
pr_info("error cmd\n");
else
pr_info("%d\n",
reg_adp_ofset_20_copy[val]);
}
} else if (!strcmp(parm[1], "reg_mono_protect")) {
if (parm[2] == NULL) {
pr_info("error cmd\n");
goto free_buf;
} else if (!strcmp(parm[2], "all")) {
for (i = 0; i < 6; i++)
d_convert_str(reg_mono_protect_copy[i],
i, stemp, 4, 10);
pr_info("%s\n", stemp);
} else {
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
if ((val > 5) || (val < 0))
pr_info("error cmd\n");
else
pr_info("%d\n",
reg_mono_protect_copy[val]);
}
} else if (!strcmp(parm[1], "reg_trend_wht_expand_lut8")) {
if (parm[2] == NULL) {
pr_info("error cmd\n");
goto free_buf;
} else if (!strcmp(parm[2], "all")) {
for (i = 0; i < 9; i++)
d_convert_str(
reg_trend_wht_expand_lut8_copy[i],
i, stemp, 4, 10);
pr_info("%s\n", stemp);
} else {
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
if ((val > 8) || (val < 0))
pr_info("error cmd\n");
else
pr_info("%d\n",
reg_trend_wht_expand_lut8_copy[val]);
}
} else if (!strcmp(parm[1], "ve_dnlp_tgt")) {
/*read only curve*/
if (parm[2] == NULL) {
pr_info("error cmd\n");
goto free_buf;
} else if (!strcmp(parm[2], "all")) {
for (i = 0; i < 65; i++)
d_convert_str(ve_dnlp_tgt_copy[i],
i, stemp, 4, 10);
pr_info("%s\n", stemp);
} else
pr_info("error cmd\n");
} else if (!strcmp(parm[1], "GmScurve")) {
/*read only curve*/
if (parm[2] == NULL) {
pr_info("error cmd\n");
goto free_buf;
} else if (!strcmp(parm[2], "all")) {
for (i = 0; i < 65; i++)
d_convert_str(GmScurve_copy[i],
i, stemp, 4, 10);
pr_info("%s\n", stemp);
} else
pr_info("error cmd\n");
} else if (!strcmp(parm[1], "clash_curve")) {
/*read only curve*/
if (parm[2] == NULL) {
pr_info("error cmd\n");
goto free_buf;
} else if (!strcmp(parm[2], "all")) {
for (i = 0; i < 65; i++)
d_convert_str(clash_curve_copy[i],
i, stemp, 4, 10);
pr_info("%s\n", stemp);
} else
pr_info("error cmd\n");
} else if (!strcmp(parm[1], "clsh_scvbld")) {
/*read only curve*/
if (parm[2] == NULL) {
pr_info("error cmd\n");
goto free_buf;
} else if (!strcmp(parm[2], "all")) {
for (i = 0; i < 65; i++)
d_convert_str(clsh_scvbld_copy[i],
i, stemp, 4, 10);
pr_info("%s\n", stemp);
} else
pr_info("error cmd\n");
} else if (!strcmp(parm[1], "blkwht_ebld")) {
/*read only curve*/
if (parm[2] == NULL) {
pr_info("error cmd\n");
goto free_buf;
} else if (!strcmp(parm[2], "all")) {
for (i = 0; i < 65; i++)
d_convert_str(blkwht_ebld_copy[i],
i, stemp, 4, 10);
pr_info("%s\n", stemp);
} else
pr_info("error cmd\n");
} else if (!strcmp(parm[1], "vpp_histgram")) {
/*read only curve*/
if (parm[2] == NULL) {
pr_info("error cmd\n");
goto free_buf;
} else if (!strcmp(parm[2], "all")) {
for (i = 0; i < 64; i++)
d_convert_str(
vpp_hist_param.vpp_histgram[i],
i, stemp, 4, 10);
pr_info("%s\n", stemp);
} else
pr_info("error cmd\n");
}
} else if (!strcmp(parm[0], "wc")) {/*write curve*/
if (!strcmp(parm[1], "scurv_low")) {
if (parm[2] == NULL) {
pr_info("error cmd\n");
goto free_buf;
} else if (!strcmp(parm[2], "all")) {
str_sapr_to_d(parm[3], curve_val, 5);
for (i = 0; i < 65; i++)
dnlp_scurv_low_copy[i] = curve_val[i];
} else {
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
num = val;
if (kstrtoul(parm[3], 10, &val) < 0)
goto free_buf;
if (num > 64)
pr_info("error cmd\n");
else
dnlp_scurv_low_copy[num] = val;
}
} else if (!strcmp(parm[1], "scurv_mid1")) {
if (parm[2] == NULL) {
pr_info("error cmd\n");
goto free_buf;
} else if (!strcmp(parm[2], "all")) {
str_sapr_to_d(parm[3], curve_val, 5);
for (i = 0; i < 65; i++)
dnlp_scurv_mid1_copy[i] = curve_val[i];
} else {
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
num = val;
if (kstrtoul(parm[3], 10, &val) < 0)
goto free_buf;
if (num > 64)
pr_info("error cmd\n");
else
dnlp_scurv_mid1_copy[num] = val;
}
} else if (!strcmp(parm[1], "scurv_mid2")) {
if (parm[2] == NULL) {
pr_info("error cmd\n");
goto free_buf;
} else if (!strcmp(parm[2], "all")) {
str_sapr_to_d(parm[3], curve_val, 5);
for (i = 0; i < 65; i++)
dnlp_scurv_mid2_copy[i] = curve_val[i];
} else {
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
num = val;
if (kstrtoul(parm[3], 10, &val) < 0)
goto free_buf;
if (num > 64)
pr_info("error cmd\n");
else
dnlp_scurv_mid2_copy[num] = val;
}
} else if (!strcmp(parm[1], "scurv_hgh1")) {
if (parm[2] == NULL) {
pr_info("error cmd\n");
goto free_buf;
} else if (!strcmp(parm[2], "all")) {
str_sapr_to_d(parm[3], curve_val, 5);
for (i = 0; i < 65; i++)
dnlp_scurv_hgh1_copy[i] = curve_val[i];
} else {
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
num = val;
if (kstrtoul(parm[3], 10, &val) < 0)
goto free_buf;
if (num > 64)
pr_info("error cmd\n");
else
dnlp_scurv_hgh1_copy[num] = val;
}
} else if (!strcmp(parm[1], "scurv_hgh2")) {
if (parm[2] == NULL) {
pr_info("error cmd\n");
goto free_buf;
} else if (!strcmp(parm[2], "all")) {
str_sapr_to_d(parm[3], curve_val, 5);
for (i = 0; i < 65; i++)
dnlp_scurv_hgh2_copy[i] = curve_val[i];
} else {
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
num = val;
if (kstrtoul(parm[3], 10, &val) < 0)
goto free_buf;
if (num > 64)
pr_info("error cmd\n");
else
dnlp_scurv_hgh2_copy[num] = val;
}
} else if (!strcmp(parm[1], "gain_var_lut49")) {
if (parm[2] == NULL) {
pr_info("error cmd\n");
goto free_buf;
} else if (!strcmp(parm[2], "all")) {
str_sapr_to_d(parm[3], curve_val, 5);
for (i = 0; i < 49; i++)
gain_var_lut49_copy[i] = curve_val[i];
} else {
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
num = val;
if (kstrtoul(parm[3], 10, &val) < 0)
goto free_buf;
if (num > 48)
pr_info("error cmd\n");
else
gain_var_lut49_copy[num] = val;
}
} else if (!strcmp(parm[1], "wext_gain")) {
if (parm[2] == NULL) {
pr_info("error cmd\n");
goto free_buf;
} else if (!strcmp(parm[2], "all")) {
str_sapr_to_d(parm[3], curve_val, 5);
for (i = 0; i < 48; i++)
wext_gain_copy[i] = curve_val[i];
} else {
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
num = val;
if (kstrtoul(parm[3], 10, &val) < 0)
goto free_buf;
if (num > 47)
pr_info("error cmd\n");
else
wext_gain_copy[num] = val;
}
} else if (!strcmp(parm[1], "adp_thrd")) {
if (parm[2] == NULL) {
pr_info("error cmd\n");
goto free_buf;
} else if (!strcmp(parm[2], "all")) {
str_sapr_to_d(parm[3], curve_val, 5);
for (i = 0; i < 33; i++)
adp_thrd_copy[i] = curve_val[i];
} else {
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
num = val;
if (kstrtoul(parm[3], 10, &val) < 0)
goto free_buf;
if (num > 32)
pr_info("error cmd\n");
else
adp_thrd_copy[num] = val;
}
} else if (!strcmp(parm[1], "reg_blk_boost_12")) {
if (parm[2] == NULL) {
pr_info("error cmd\n");
goto free_buf;
} else if (!strcmp(parm[2], "all")) {
str_sapr_to_d(parm[3], curve_val, 5);
for (i = 0; i < 13; i++)
reg_blk_boost_12_copy[i] = curve_val[i];
} else {
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
num = val;
if (kstrtoul(parm[3], 10, &val) < 0)
goto free_buf;
if (num > 12)
pr_info("error cmd\n");
else
reg_blk_boost_12_copy[num] = val;
}
} else if (!strcmp(parm[1], "reg_adp_ofset_20")) {
if (parm[2] == NULL) {
pr_info("error cmd\n");
goto free_buf;
} else if (!strcmp(parm[2], "all")) {
str_sapr_to_d(parm[3], curve_val, 5);
for (i = 0; i < 20; i++)
reg_adp_ofset_20_copy[i] = curve_val[i];
} else {
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
num = val;
if (kstrtoul(parm[3], 10, &val) < 0)
goto free_buf;
if (num > 19)
pr_info("error cmd\n");
else
reg_adp_ofset_20_copy[num] = val;
}
} else if (!strcmp(parm[1], "reg_mono_protect")) {
if (parm[2] == NULL) {
pr_info("error cmd\n");
goto free_buf;
} else if (!strcmp(parm[2], "all")) {
str_sapr_to_d(parm[3], curve_val, 5);
for (i = 0; i < 6; i++)
reg_mono_protect_copy[i] = curve_val[i];
} else {
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
num = val;
if (kstrtoul(parm[3], 10, &val) < 0)
goto free_buf;
if (num > 5)
pr_info("error cmd\n");
else
reg_mono_protect_copy[num] = val;
}
} else if (!strcmp(parm[1], "reg_trend_wht_expand_lut8")) {
if (parm[2] == NULL) {
pr_info("error cmd\n");
goto free_buf;
} else if (!strcmp(parm[2], "all")) {
str_sapr_to_d(parm[3], curve_val, 5);
for (i = 0; i < 9; i++)
reg_trend_wht_expand_lut8_copy[i] =
curve_val[i];
} else {
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
num = val;
if (kstrtoul(parm[3], 10, &val) < 0)
goto free_buf;
if (num > 8)
pr_info("error cmd\n");
else
reg_trend_wht_expand_lut8_copy[num] = val;
}
}
} else if (!strcmp(parm[0], "ro")) {
if (!strcmp(parm[1], "luma_avg4"))
pr_info("%d\n", *ro_luma_avg4_copy);
else if (!strcmp(parm[1], "var_d8"))
pr_info("%d\n", *ro_var_d8_copy);
else if (!strcmp(parm[1], "scurv_gain"))
pr_info("%d\n", *ro_scurv_gain_copy);
else if (!strcmp(parm[1], "blk_wht_ext0"))
pr_info("%d\n", *ro_blk_wht_ext0_copy);
else if (!strcmp(parm[1], "blk_wht_ext1"))
pr_info("%d\n", *ro_blk_wht_ext1_copy);
else if (!strcmp(parm[1], "dnlp_brightness"))
pr_info("%d\n", *ro_dnlp_brightness_copy);
else
pr_info("error cmd\n");
} else if (!strcmp(parm[0], "dnlp_print")) {
if (kstrtoul(parm[1], 16, &val) < 0)
goto free_buf;
*dnlp_printk_copy = val;
pr_info("dnlp_print = %x\n", *dnlp_printk_copy);
}
kfree(buf_orig);
kfree(stemp);
return count;
free_buf:
kfree(buf_orig);
kfree(stemp);
return -EINVAL;
}
static ssize_t amvecm_brightness_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
return sprintf(buf, "%d\n", vd1_brightness);
}
static ssize_t amvecm_brightness_store(struct class *cla,
struct class_attribute *attr,
const char *buf, size_t count)
{
size_t r;
int val;
r = sscanf(buf, "%d\n", &val);
if ((r != 1) || (val < -1024) || (val > 1024))
return -EINVAL;
vd1_brightness = val;
/*vecm_latch_flag |= FLAG_BRI_CON;*/
vecm_latch_flag |= FLAG_VADJ1_BRI;
return count;
}
static ssize_t amvecm_contrast_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
return sprintf(buf, "%d\n", vd1_contrast);
}
static ssize_t amvecm_contrast_store(struct class *cla,
struct class_attribute *attr,
const char *buf, size_t count)
{
size_t r;
int val;
r = sscanf(buf, "%d\n", &val);
if ((r != 1) || (val < -1024) || (val > 1024))
return -EINVAL;
vd1_contrast = val;
/*vecm_latch_flag |= FLAG_BRI_CON;*/
vecm_latch_flag |= FLAG_VADJ1_CON;
vecm_latch_flag |= FLAG_VADJ1_COLOR;
return count;
}
static ssize_t amvecm_saturation_hue_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
if (get_cpu_type() == MESON_CPU_MAJOR_ID_TL1)
return sprintf(buf, "0x%x\n",
READ_VPP_REG(VPP_VADJ1_MA_MB_2));
else
return sprintf(buf, "0x%x\n",
READ_VPP_REG(VPP_VADJ1_MA_MB));
}
static ssize_t amvecm_saturation_hue_store(struct class *cla,
struct class_attribute *attr, const char *buf, size_t count)
{
size_t r;
s32 mab = 0;
r = sscanf(buf, "0x%x", &mab);
if ((r != 1) || (mab&0xfc00fc00))
return -EINVAL;
amvecm_set_saturation_hue(mab);
return count;
}
void vpp_vd_adj1_saturation_hue(signed int sat_val,
signed int hue_val, struct vframe_s *vf)
{
int i, ma, mb, mab, mc, md;
int hue_cos[] = {
/*0~12*/
256, 256, 256, 255, 255, 254, 253, 252, 251, 250, 248, 247, 245,
/*13~25*/
243, 241, 239, 237, 234, 231, 229, 226, 223, 220, 216, 213, 209
};
int hue_sin[] = {
/*-25~-13*/
-147, -142, -137, -132, -126, -121, -115, -109, -104,
-98, -92, -86, -80, -74, -68, -62, -56, -50,
-44, -38, -31, -25, -19, -13, -6, /*-12~-1*/
0, /*0*/
/*1~12*/
6, 13, 19, 25, 31, 38, 44, 50, 56, 62,
68, 74, 80, 86, 92, 98, 104, 109, 115, 121,
126, 132, 137, 142, 147 /*13~25*/
};
i = (hue_val > 0) ? hue_val : -hue_val;
ma = (hue_cos[i]*(sat_val + 128)) >> 7;
mb = (hue_sin[25+hue_val]*(sat_val + 128)) >> 7;
saturation_ma_shift = ma - 0x100;
saturation_mb_shift = mb;
ma += saturation_ma;
mb += saturation_mb;
if (ma > 511)
ma = 511;
if (ma < -512)
ma = -512;
if (mb > 511)
mb = 511;
if (mb < -512)
mb = -512;
mab = ((ma & 0x3ff) << 16) | (mb & 0x3ff);
pr_info("\n[amvideo..] saturation_pre:%d hue_pre:%d mab:%x\n",
sat_val, hue_val, mab);
if (get_cpu_type() == MESON_CPU_MAJOR_ID_TL1)
WRITE_VPP_REG(VPP_VADJ1_MA_MB_2, mab);
else
WRITE_VPP_REG(VPP_VADJ1_MA_MB, mab);
mc = (s16)((mab<<22)>>22); /* mc = -mb */
mc = 0 - mc;
if (mc > 511)
mc = 511;
if (mc < -512)
mc = -512;
md = (s16)((mab<<6)>>22); /* md = ma; */
mab = ((mc&0x3ff)<<16)|(md&0x3ff);
if (get_cpu_type() == MESON_CPU_MAJOR_ID_TL1) {
WRITE_VPP_REG(VPP_VADJ1_MC_MD_2, mab);
WRITE_VPP_REG_BITS(VPP_VADJ1_MISC, 1, 0, 1);
} else {
WRITE_VPP_REG(VPP_VADJ1_MC_MD, mab);
WRITE_VPP_REG_BITS(VPP_VADJ_CTRL, 1, 0, 1);
}
};
static ssize_t amvecm_saturation_hue_pre_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
return snprintf(buf, 20, "%d %d\n", saturation_pre, hue_pre);
}
static ssize_t amvecm_saturation_hue_pre_store(struct class *cla,
struct class_attribute *attr, const char *buf, size_t count)
{
int parsed[2];
if (likely(parse_para_pq(buf, 2, parsed) != 2))
return -EINVAL;
if ((parsed[0] < -128) || (parsed[0] > 128) ||
(parsed[1] < -25) || (parsed[1] > 25)) {
return -EINVAL;
}
saturation_pre = parsed[0];
hue_pre = parsed[1];
vecm_latch_flag |= FLAG_VADJ1_COLOR;
return count;
}
static ssize_t amvecm_saturation_hue_post_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
return snprintf(buf, 20, "%d %d\n", saturation_post, hue_post);
}
static ssize_t amvecm_saturation_hue_post_store(struct class *cla,
struct class_attribute *attr, const char *buf, size_t count)
{
int parsed[2], ret;
if (likely(parse_para_pq(buf, 2, parsed) != 2))
return -EINVAL;
ret = amvecm_set_saturation_hue_post(parsed[0],
parsed[1]);
if (ret < 0)
return ret;
return count;
}
static ssize_t amvecm_cm2_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
pr_info("Usage:");
pr_info(" echo wm addr data0 data1 data2 data3 data4 ");
pr_info("> /sys/class/amvecm/cm2\n");
pr_info(" echo rm addr > /sys/class/amvecm/cm2\n");
return 0;
}
static ssize_t amvecm_cm2_store(struct class *cls,
struct class_attribute *attr,
const char *buffer, size_t count)
{
int n = 0;
char *buf_orig, *ps, *token;
char *parm[7];
u32 addr;
int data[5] = {0};
unsigned int addr_port = VPP_CHROMA_ADDR_PORT;/* 0x1d70; */
unsigned int data_port = VPP_CHROMA_DATA_PORT;/* 0x1d71; */
long val;
char delim1[3] = " ";
char delim2[2] = "\n";
buf_orig = kstrdup(buffer, GFP_KERNEL);
ps = buf_orig;
strcat(delim1, delim2);
while (1) {
token = strsep(&ps, delim1);
if (token == NULL)
break;
if (*token == '\0')
continue;
parm[n++] = token;
}
if (n == 0) {
pr_info("strsep fail,parm[] uninitialized !\n");
kfree(buf_orig);
return -EINVAL;
}
if ((parm[0][0] == 'w') && parm[0][1] == 'm') {
if (n != 7) {
pr_info("read: invalid parameter\n");
pr_info("please: cat /sys/class/amvecm/cm2\n");
kfree(buf_orig);
return count;
}
if (kstrtol(parm[1], 16, &val) < 0)
return -EINVAL;
addr = val;
addr = addr - addr%8;
if (kstrtol(parm[2], 16, &val) < 0)
return -EINVAL;
data[0] = val;
if (kstrtol(parm[3], 16, &val) < 0)
return -EINVAL;
data[1] = val;
if (kstrtol(parm[4], 16, &val) < 0)
return -EINVAL;
data[2] = val;
if (kstrtol(parm[5], 16, &val) < 0)
return -EINVAL;
data[3] = val;
if (kstrtol(parm[6], 16, &val) < 0)
return -EINVAL;
data[4] = val;
WRITE_VPP_REG(addr_port, addr);
WRITE_VPP_REG(data_port, data[0]);
WRITE_VPP_REG(addr_port, addr + 1);
WRITE_VPP_REG(data_port, data[1]);
WRITE_VPP_REG(addr_port, addr + 2);
WRITE_VPP_REG(data_port, data[2]);
WRITE_VPP_REG(addr_port, addr + 3);
WRITE_VPP_REG(data_port, data[3]);
WRITE_VPP_REG(addr_port, addr + 4);
WRITE_VPP_REG(data_port, data[4]);
pr_info("wm: [0x%x] <-- 0x0\n", addr);
} else if ((parm[0][0] == 'r') && parm[0][1] == 'm') {
if (n != 2) {
pr_info("read: invalid parameter\n");
pr_info("please: cat /sys/class/amvecm/cm2\n");
kfree(buf_orig);
return count;
}
if (kstrtol(parm[1], 16, &val) < 0)
return -EINVAL;
addr = val;
addr = addr - addr%8;
WRITE_VPP_REG(addr_port, addr);
data[0] = READ_VPP_REG(data_port);
data[0] = READ_VPP_REG(data_port);
data[0] = READ_VPP_REG(data_port);
WRITE_VPP_REG(addr_port, addr+1);
data[1] = READ_VPP_REG(data_port);
data[1] = READ_VPP_REG(data_port);
data[1] = READ_VPP_REG(data_port);
WRITE_VPP_REG(addr_port, addr+2);
data[2] = READ_VPP_REG(data_port);
data[2] = READ_VPP_REG(data_port);
data[2] = READ_VPP_REG(data_port);
WRITE_VPP_REG(addr_port, addr+3);
data[3] = READ_VPP_REG(data_port);
data[3] = READ_VPP_REG(data_port);
data[3] = READ_VPP_REG(data_port);
WRITE_VPP_REG(addr_port, addr+4);
data[4] = READ_VPP_REG(data_port);
data[4] = READ_VPP_REG(data_port);
data[4] = READ_VPP_REG(data_port);
pr_info("rm:[0x%x]-->[0x%x][0x%x][0x%x][0x%x][0x%x]\n",
addr, data[0], data[1],
data[2], data[3], data[4]);
} else {
pr_info("invalid command\n");
pr_info("please: cat /sys/class/amvecm/bit");
}
kfree(buf_orig);
return count;
}
static ssize_t amvecm_cm_reg_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
pr_info("Usage: echo addr value > /sys/class/amvecm/cm_reg");
return 0;
}
static ssize_t amvecm_cm_reg_store(struct class *cls,
struct class_attribute *attr,
const char *buffer, size_t count)
{
int data[5] = {0};
unsigned int addr, value;
long val = 0;
int i, node, reg_node;
unsigned int addr_port = VPP_CHROMA_ADDR_PORT;/* 0x1d70; */
unsigned int data_port = VPP_CHROMA_DATA_PORT;/* 0x1d71; */
char *buf_orig, *parm[2] = {NULL};
if (!buffer)
return count;
buf_orig = kstrdup(buffer, GFP_KERNEL);
parse_param_amvecm(buf_orig, (char **)&parm);
if (kstrtoul(parm[0], 16, &val) < 0) {
kfree(buf_orig);
return -EINVAL;
}
addr = val;
if (kstrtoul(parm[1], 16, &val) < 0) {
kfree(buf_orig);
return -EINVAL;
}
value = val;
node = (addr - 0x100) / 8;
reg_node = (addr - 0x100) % 8;
for (i = 0; i < 5; i++) {
if (i == reg_node) {
data[i] = value;
continue;
}
addr = node * 8 + 0x100 + i;
WRITE_VPP_REG(addr_port, addr);
data[i] = READ_VPP_REG(data_port);
}
for (i = 0; i < 5; i++) {
addr = node * 8 + 0x100 + i;
WRITE_VPP_REG(addr_port, addr);
WRITE_VPP_REG(data_port, data[i]);
}
kfree(buf_orig);
return count;
}
static ssize_t amvecm_write_reg_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
pr_info("Usage: echo w addr value > /sys/class/amvecm/pq_reg_rw\n");
pr_info("Usage: echo bw addr value start length > /...\n");
pr_info("Usage: echo r addr > /sys/class/amvecm/pq_reg_rw\n");
pr_info("addr and value must be hex\n");
return 0;
}
static ssize_t amvecm_write_reg_store(struct class *cls,
struct class_attribute *attr,
const char *buffer, size_t count)
{
unsigned int addr, value, bitstart, bitlength;
long val = 0;
char *buf_orig, *parm[5] = {NULL};
if (!buffer)
return count;
buf_orig = kstrdup(buffer, GFP_KERNEL);
parse_param_amvecm(buf_orig, (char **)&parm);
if (!strncmp(parm[0], "r", 1)) {
if (kstrtoul(parm[1], 16, &val) < 0) {
kfree(buf_orig);
return -EINVAL;
}
addr = val;
value = READ_VPP_REG(addr);
pr_info("0x%x=0x%x\n", addr, value);
} else if (!strncmp(parm[0], "w", 1)) {
if (kstrtoul(parm[1], 16, &val) < 0) {
kfree(buf_orig);
return -EINVAL;
}
addr = val;
if (kstrtoul(parm[2], 16, &val) < 0) {
kfree(buf_orig);
return -EINVAL;
}
value = val;
WRITE_VPP_REG(addr, value);
} else if (!strncmp(parm[0], "bw", 2)) {
if (kstrtoul(parm[1], 16, &val) < 0) {
kfree(buf_orig);
return -EINVAL;
}
addr = val;
if (kstrtoul(parm[2], 16, &val) < 0) {
kfree(buf_orig);
return -EINVAL;
}
value = val;
if (kstrtoul(parm[3], 16, &val) < 0) {
kfree(buf_orig);
return -EINVAL;
}
bitstart = val;
if (kstrtoul(parm[4], 16, &val) < 0) {
kfree(buf_orig);
return -EINVAL;
}
bitlength = val;
WRITE_VPP_REG_BITS(addr, value, bitstart, bitlength);
}
kfree(buf_orig);
return count;
}
static ssize_t amvecm_gamma_show(struct class *cls,
struct class_attribute *attr,
char *buf)
{
int i = 0;
char sbuf[GAMMA_SIZE * 3 + 1];
pr_info("Usage:");
pr_info(" echo sgr|sgg|sgb xxx...xx > /sys/class/amvecm/gamma\n");
pr_info("Notes:\n");
pr_info(" if the string xxx......xx is less than 256*3,");
pr_info(" then the remaining will be set value 0\n");
pr_info(" if the string xxx......xx is more than 256*3, ");
pr_info("Usage:");
pr_info(" echo ggr|ggg|ggb xxx > /sys/class/amvecm/gamma\n");
pr_info("Notes:\n");
pr_info(" read all as point......xxx is 'all'.\n");
pr_info(" read all as strings......xxx is 'all_str'.\n");
pr_info(" read one point......xxx is a value '0~255'.\n");
pr_info(" then the remaining will be ignored\n");
for (i = 0; i < GAMMA_SIZE; i++)
snprintf(sbuf + i*3, 4, "%03x", video_gamma_table_r.data[i]);
pr_info("Gamma R: %s\n", sbuf);
for (i = 0; i < GAMMA_SIZE; i++)
snprintf(sbuf + i*3, 4, "%03x", video_gamma_table_g.data[i]);
pr_info("Gamma G: %s\n", sbuf);
for (i = 0; i < GAMMA_SIZE; i++)
snprintf(sbuf + i*3, 4, "%03x", video_gamma_table_b.data[i]);
pr_info("Gamma B: %s\n", sbuf);
return 0;
}
static ssize_t amvecm_gamma_store(struct class *cls,
struct class_attribute *attr,
const char *buffer, size_t count)
{
int n = 0;
char *buf_orig, *ps, *token;
char *parm[4];
unsigned short *gammaR, *gammaG, *gammaB;
unsigned int gamma_count;
char gamma[4];
int i = 0;
long val;
char delim1[3] = " ";
char delim2[2] = "\n";
char *stemp = NULL;
stemp = kmalloc(600, GFP_KERNEL);
gammaR = kmalloc(256 * sizeof(unsigned short), GFP_KERNEL);
gammaG = kmalloc(256 * sizeof(unsigned short), GFP_KERNEL);
gammaB = kmalloc(256 * sizeof(unsigned short), GFP_KERNEL);
buf_orig = kstrdup(buffer, GFP_KERNEL);
ps = buf_orig;
strcat(delim1, delim2);
while (1) {
token = strsep(&ps, delim1);
if (token == NULL)
break;
if (*token == '\0')
continue;
parm[n++] = token;
}
if (!gammaR || !gammaG || !gammaB || !stemp
|| (n == 0))
goto free_buf;
if ((parm[0][0] == 's') && (parm[0][1] == 'g')) {
memset(gammaR, 0, 256 * sizeof(unsigned short));
gamma_count = (strlen(parm[1]) + 2) / 3;
if (gamma_count > 256)
gamma_count = 256;
for (i = 0; i < gamma_count; ++i) {
gamma[0] = parm[1][3 * i + 0];
gamma[1] = parm[1][3 * i + 1];
gamma[2] = parm[1][3 * i + 2];
gamma[3] = '\0';
if (kstrtol(gamma, 16, &val) < 0)
goto free_buf;
gammaR[i] = val;
}
switch (parm[0][2]) {
case 'r':
amve_write_gamma_table(gammaR, H_SEL_R);
break;
case 'g':
amve_write_gamma_table(gammaR, H_SEL_G);
break;
case 'b':
amve_write_gamma_table(gammaR, H_SEL_B);
break;
default:
break;
}
} else if (!strncmp(parm[0], "gg", 2) && strlen(parm[0]) > 2) {
u16 *table = gammaR;
u32 sel = H_SEL_R;
char channel = parm[0][2];
switch (channel) {
case 'r':
sel = H_SEL_R;
break;
case 'g':
sel = H_SEL_G;
break;
case 'b':
sel = H_SEL_B;
break;
default:
channel = 'r';
break;
}
vpp_get_lcd_gamma_table(sel, table);
if (!strcmp(parm[1], "all")) {
for (i = 0; i < GAMMA_SIZE; i++)
pr_info("gamma_%c[%d] = %03x\n",
channel, i, table[i]);
} else if (!strcmp(parm[1], "all_str")) {
stemp = kmalloc(3 * GAMMA_SIZE + 1, GFP_KERNEL);
for (i = 0; i < GAMMA_SIZE; i++)
snprintf(stemp + i*3, 4, "%03x", table[i]);
pr_info("gamma_%c str: %s\n", channel, stemp);
} else {
if (kstrtol(parm[1], 10, &val) < 0) {
pr_info("invalid command\n");
goto free_buf;
}
i = val;
if (i < 0 || i > GAMMA_SIZE) {
pr_info("invalid index\n");
goto free_buf;
}
pr_info("gamma_%c[%d] = %03x\n",
channel, i, table[i]);
}
} else {
pr_info("invalid command\n");
pr_info("please: cat /sys/class/amvecm/gamma");
}
kfree(buf_orig);
kfree(stemp);
kfree(gammaR);
kfree(gammaG);
kfree(gammaB);
return count;
free_buf:
kfree(buf_orig);
kfree(stemp);
kfree(gammaR);
kfree(gammaG);
kfree(gammaB);
return -EINVAL;
}
static ssize_t set_gamma_pattern_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
pr_info("8bit: echo r g b > /sys/class/amvecm/gamma_pattern\n");
pr_info("10bit: echo r g b 0xa > /sys/class/amvecm/gamma_pattern\n");
pr_info(" r g b should be hex\n");
pr_info("disable gamma pattern:\n");
pr_info("echo disable > /sys/class/amvecm/gamma_pattern\n");
return 0;
}
static ssize_t set_gamma_pattern_store(struct class *cls,
struct class_attribute *attr,
const char *buffer, size_t count)
{
unsigned short r_val[256], g_val[256], b_val[256];
int n = 0;
char *buf_orig, *ps, *token;
char *parm[4];
unsigned int gamma[3];
long val, i;
char deliml[3] = " ";
char delim2[2] = "\n";
buf_orig = kstrdup(buffer, GFP_KERNEL);
ps = buf_orig;
strcat(deliml, delim2);
*(parm + 3) = NULL;
while (1) {
token = strsep(&ps, deliml);
if (token == NULL)
break;
if (*token == '\0')
continue;
parm[n++] = token;
}
if (!strcmp(parm[0], "disable")) {
vecm_latch_flag |= FLAG_GAMMA_TABLE_R;
vecm_latch_flag |= FLAG_GAMMA_TABLE_G;
vecm_latch_flag |= FLAG_GAMMA_TABLE_B;
kfree(buf_orig);
return count;
}
if (*(parm + 3) != NULL) {
if (kstrtol(parm[3], 16, &val) < 0) {
kfree(buf_orig);
return -EINVAL;
}
if (val == 10) {
if (kstrtol(parm[0], 16, &val) < 0) {
kfree(buf_orig);
return -EINVAL;
}
gamma[0] = val;
if (kstrtol(parm[1], 16, &val) < 0) {
kfree(buf_orig);
return -EINVAL;
}
gamma[1] = val;
if (kstrtol(parm[2], 16, &val) < 0) {
kfree(buf_orig);
return -EINVAL;
}
gamma[2] = val;
} else {
kfree(buf_orig);
return count;
}
} else {
if (kstrtol(parm[0], 16, &val) < 0) {
kfree(buf_orig);
return -EINVAL;
}
gamma[0] = val << 2;
if (kstrtol(parm[1], 16, &val) < 0) {
kfree(buf_orig);
return -EINVAL;
}
gamma[1] = val << 2;
if (kstrtol(parm[2], 16, &val) < 0) {
kfree(buf_orig);
return -EINVAL;
}
gamma[2] = val << 2;
}
for (i = 0; i < 256; i++) {
r_val[i] = gamma[0];
g_val[i] = gamma[1];
b_val[i] = gamma[2];
}
amve_write_gamma_table(r_val, H_SEL_R);
amve_write_gamma_table(g_val, H_SEL_G);
amve_write_gamma_table(b_val, H_SEL_B);
kfree(buf_orig);
return count;
}
void white_balance_adjust(int sel, int value)
{
switch (sel) {
/*0: en*/
/*1: pre r 2: pre g 3: pre b*/
/*4: gain r 5: gain g 6: gain b*/
/*7: post r 8: post g 9: post b*/
case 0:
video_rgb_ogo.en = value;
break;
case 1:
video_rgb_ogo.r_pre_offset = value;
break;
case 2:
video_rgb_ogo.g_pre_offset = value;
break;
case 3:
video_rgb_ogo.b_pre_offset = value;
break;
case 4:
video_rgb_ogo.r_gain = value;
break;
case 5:
video_rgb_ogo.g_gain = value;
break;
case 6:
video_rgb_ogo.b_gain = value;
break;
case 7:
video_rgb_ogo.r_post_offset = value;
break;
case 8:
video_rgb_ogo.g_post_offset = value;
break;
case 9:
video_rgb_ogo.b_post_offset = value;
break;
default:
break;
}
ve_ogo_param_update();
}
static ssize_t amvecm_wb_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
pr_info("read: echo r gain_r > /sys/class/amvecm/wb\n");
pr_info("read: echo r pre_r > /sys/class/amvecm/wb\n");
pr_info("read: echo r post_r > /sys/class/amvecm/wb\n");
pr_info("write: echo gain_r value > /sys/class/amvecm/wb\n");
pr_info("write: echo preofst_r value > /sys/class/amvecm/wb\n");
pr_info("write: echo postofst_r value > /sys/class/amvecm/wb\n");
return 0;
}
static ssize_t amvecm_wb_store(struct class *cls,
struct class_attribute *attr,
const char *buffer, size_t count)
{
char *buf_orig, *parm[8] = {NULL};
long value;
if (!buffer)
return count;
buf_orig = kstrdup(buffer, GFP_KERNEL);
parse_param_amvecm(buf_orig, (char **)&parm);
if (!strncmp(parm[0], "r", 1)) {
if (!strncmp(parm[1], "pre_r", 5))
pr_info("\t Pre_R = %d\n", video_rgb_ogo.r_pre_offset);
else if (!strncmp(parm[1], "pre_g", 5))
pr_info("\t Pre_G = %d\n", video_rgb_ogo.g_pre_offset);
else if (!strncmp(parm[1], "pre_b", 5))
pr_info("\t Pre_B = %d\n", video_rgb_ogo.b_pre_offset);
else if (!strncmp(parm[1], "gain_r", 6))
pr_info("\t Gain_R = %d\n", video_rgb_ogo.r_gain);
else if (!strncmp(parm[1], "gain_g", 6))
pr_info("\t Gain_G = %d\n", video_rgb_ogo.g_gain);
else if (!strncmp(parm[1], "gain_b", 6))
pr_info("\t Gain_B = %d\n", video_rgb_ogo.b_gain);
else if (!strncmp(parm[1], "post_r", 6))
pr_info("\t Post_R = %d\n",
video_rgb_ogo.r_post_offset);
else if (!strncmp(parm[1], "post_g", 6))
pr_info("\t Post_G = %d\n",
video_rgb_ogo.g_post_offset);
else if (!strncmp(parm[1], "post_b", 6))
pr_info("\t Post_B = %d\n",
video_rgb_ogo.b_post_offset);
else if (!strncmp(parm[1], "en", 2))
pr_info("\t En = %d\n", video_rgb_ogo.en);
} else {
if (kstrtol(parm[1], 10, &value) < 0)
return -EINVAL;
if (!strncmp(parm[0], "wb_en", 5)) {
white_balance_adjust(0, value);
pr_info("\t set wb en\n");
} else if (!strncmp(parm[0], "preofst_r", 9)) {
if ((value > 1023) || (value < -1024))
pr_info("\t preofst r over range\n");
else {
white_balance_adjust(1, value);
pr_info("\t set wb preofst r\n");
}
} else if (!strncmp(parm[0], "preofst_g", 9)) {
if ((value > 1023) || (value < -1024))
pr_info("\t preofst g over range\n");
else {
white_balance_adjust(2, value);
pr_info("\t set wb preofst g\n");
}
} else if (!strncmp(parm[0], "preofst_b", 9)) {
if ((value > 1023) || (value < -1024))
pr_info("\t preofst b over range\n");
else {
white_balance_adjust(3, value);
pr_info("\t set wb preofst b\n");
}
} else if (!strncmp(parm[0], "gain_r", 6)) {
if ((value > 2047) || (value < 0))
pr_info("\t gain r over range\n");
else {
white_balance_adjust(4, value);
pr_info("\t set wb gain r\n");
}
} else if (!strncmp(parm[0], "gain_g", 6)) {
if ((value > 2047) || (value < 0))
pr_info("\t gain g over range\n");
else {
white_balance_adjust(5, value);
pr_info("\t set wb gain g\n");
}
} else if (!strncmp(parm[0], "gain_b", 6)) {
if ((value > 2047) || (value < 0))
pr_info("\t gain b over range\n");
else {
white_balance_adjust(6, value);
pr_info("\t set wb gain b\n");
}
} else if (!strncmp(parm[0], "postofst_r", 10)) {
if ((value > 1023) || (value < -1024))
pr_info("\t postofst r over range\n");
else {
white_balance_adjust(7, value);
pr_info("\t set wb postofst r\n");
}
} else if (!strncmp(parm[0], "postofst_g", 10)) {
if ((value > 1023) || (value < -1024))
pr_info("\t postofst g over range\n");
else {
white_balance_adjust(8, value);
pr_info("\t set wb postofst g\n");
}
} else if (!strncmp(parm[0], "postofst_b", 10)) {
if ((value > 1023) || (value < -1024))
pr_info("\t postofst b over range\n");
else {
white_balance_adjust(9, value);
pr_info("\t set wb postofst b\n");
}
}
}
kfree(buf_orig);
return count;
}
static ssize_t set_hdr_289lut_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
int i;
for (i = 0; i < 289; i++) {
pr_info("0x%-8x\t", lut_289_mapping[i]);
if ((i + 1) % 8 == 0)
pr_info("\n");
}
return 0;
}
static ssize_t set_hdr_289lut_store(struct class *cls,
struct class_attribute *attr,
const char *buffer, size_t count)
{
int n = 0;
char *buf_orig, *ps, *token;
char *parm[4];
unsigned short *Hdr289lut;
unsigned int gamma_count;
char gamma[4];
int i = 0;
long val;
char deliml[3] = " ";
char delim2[2] = "\n";
Hdr289lut = kmalloc(289 * sizeof(unsigned short), GFP_KERNEL);
buf_orig = kstrdup(buffer, GFP_KERNEL);
ps = buf_orig;
strcat(deliml, delim2);
while (1) {
token = strsep(&ps, deliml);
if (token == NULL)
break;
if (*token == '\0')
continue;
parm[n++] = token;
}
if ((n == 0) || !Hdr289lut) {
kfree(buf_orig);
kfree(Hdr289lut);
return -EINVAL;
}
memset(Hdr289lut, 0, 289 * sizeof(unsigned short));
gamma_count = (strlen(parm[0]) + 2) / 3;
if (gamma_count > 289)
gamma_count = 289;
for (i = 0; i < gamma_count; ++i) {
gamma[0] = parm[0][3 * i + 0];
gamma[1] = parm[0][3 * i + 1];
gamma[2] = parm[0][3 * i + 2];
gamma[3] = '\0';
if (kstrtol(gamma, 16, &val) < 0) {
kfree(buf_orig);
kfree(Hdr289lut);
return -EINVAL;
}
Hdr289lut[i] = val;
}
for (i = 0; i < gamma_count; i++)
lut_289_mapping[i] = Hdr289lut[i];
kfree(buf_orig);
kfree(Hdr289lut);
return count;
}
static ssize_t amvecm_set_post_matrix_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
return sprintf(buf, "0x%x\n", (int)(READ_VPP_REG(VPP_MATRIX_CTRL)));
}
static ssize_t amvecm_set_post_matrix_store(struct class *cla,
struct class_attribute *attr,
const char *buf, size_t count)
{
size_t r;
int val;
r = sscanf(buf, "0x%x", &val);
if ((r != 1) || (val & 0xffff0000))
return -EINVAL;
WRITE_VPP_REG(VPP_MATRIX_CTRL, val);
return count;
}
static ssize_t amvecm_post_matrix_pos_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
return sprintf(buf, "0x%x\n",
(int)(READ_VPP_REG(VPP_MATRIX_PROBE_POS)));
}
static ssize_t amvecm_post_matrix_pos_store(struct class *cla,
struct class_attribute *attr,
const char *buf, size_t count)
{
size_t r;
int val;
r = sscanf(buf, "0x%x", &val);
if ((r != 1) || (val & 0xe000e000))
return -EINVAL;
WRITE_VPP_REG(VPP_MATRIX_PROBE_POS, val);
return count;
}
static ssize_t amvecm_post_matrix_data_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
int len = 0, val1 = 0, val2 = 0;
val1 = READ_VPP_REG(VPP_MATRIX_PROBE_COLOR);
/* #if (MESON_CPU_TYPE >= MESON_CPU_TYPE_MESONG9TV) */
val2 = READ_VPP_REG(VPP_MATRIX_PROBE_COLOR1);
/* #endif */
len += sprintf(buf+len,
"VPP_MATRIX_PROBE_COLOR %x, %x, %x\n",
((val2 & 0xf) << 8) | ((val1 >> 24) & 0xff),
(val1 >> 12) & 0xfff, val1 & 0xfff);
return len;
}
static ssize_t amvecm_post_matrix_data_store(struct class *cla,
struct class_attribute *attr,
const char *buf, size_t count)
{
return 0;
}
static ssize_t amvecm_sr1_reg_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
unsigned int addr;
addr = ((sr1_index+0x3280) << 2) | 0xd0100000;
return sprintf(buf, "0x%x = 0x%x\n",
addr, sr1_ret_val[sr1_index]);
}
static ssize_t amvecm_sr1_reg_store(struct class *cla,
struct class_attribute *attr,
const char *buf, size_t count)
{
size_t r;
unsigned int addr, off_addr = 0;
r = sscanf(buf, "0x%x", &addr);
addr = (addr&0xffff) >> 2;
if ((r != 1) || (addr > 0x32e4) || (addr < 0x3280))
return -EINVAL;
off_addr = addr - 0x3280;
sr1_index = off_addr;
sr1_ret_val[off_addr] = sr1_reg_val[off_addr];
return count;
}
static ssize_t amvecm_write_sr1_reg_val_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
return 0;
}
static ssize_t amvecm_write_sr1_reg_val_store(struct class *cla,
struct class_attribute *attr,
const char *buf, size_t count)
{
size_t r;
unsigned int val;
r = sscanf(buf, "0x%x", &val);
if (r != 1)
return -EINVAL;
sr1_reg_val[sr1_index] = val;
return count;
}
static ssize_t amvecm_dump_reg_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
unsigned int addr;
unsigned int value;
unsigned int base_reg;
if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXLX))
base_reg = 0xff900000;
else
base_reg = 0xd0100000;
pr_info("----dump sharpness0 reg----\n");
for (addr = 0x3200;
addr <= 0x3264; addr++)
pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n",
(base_reg + (addr<<2)), addr,
READ_VPP_REG(addr));
if (is_meson_txl_cpu() || is_meson_txlx_cpu()) {
for (addr = 0x3265;
addr <= 0x3272; addr++)
pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n",
(base_reg + (addr<<2)), addr,
READ_VPP_REG(addr));
}
if (is_meson_txlx_cpu()) {
for (addr = 0x3273;
addr <= 0x327f; addr++)
pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n",
(base_reg + (addr<<2)), addr,
READ_VPP_REG(addr));
}
pr_info("----dump sharpness1 reg----\n");
for (addr = (0x3200+0x80);
addr <= (0x3264+0x80); addr++)
pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n",
(base_reg + (addr<<2)), addr,
READ_VPP_REG(addr));
if (is_meson_txl_cpu() || is_meson_txlx_cpu()) {
for (addr = (0x3265+0x80);
addr <= (0x3272+0x80); addr++)
pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n",
(base_reg + (addr<<2)), addr,
READ_VPP_REG(addr));
}
if (is_meson_txlx_cpu()) {
for (addr = (0x3273+0x80);
addr <= (0x327f+0x80); addr++)
pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n",
(base_reg + (addr<<2)), addr,
READ_VPP_REG(addr));
}
pr_info("----dump cm reg----\n");
for (addr = 0x200; addr <= 0x21e; addr++) {
WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, addr);
value = READ_VPP_REG(VPP_CHROMA_DATA_PORT);
pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n",
addr, addr,
value);
}
for (addr = 0x100; addr <= 0x1fc; addr++) {
WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, addr);
value = READ_VPP_REG(VPP_CHROMA_DATA_PORT);
pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n",
addr, addr,
value);
}
pr_info("----dump vd1 IF0 reg----\n");
for (addr = (0x1a50);
addr <= (0x1a69); addr++)
pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n",
(base_reg + (addr<<2)), addr,
READ_VPP_REG(addr));
pr_info("----dump vpp1 part1 reg----\n");
for (addr = (0x1d00);
addr <= (0x1d6e); addr++)
pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n",
(base_reg + (addr<<2)), addr,
READ_VPP_REG(addr));
pr_info("----dump vpp1 part2 reg----\n");
for (addr = (0x1d72);
addr <= (0x1de4); addr++)
pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n",
(base_reg + (addr<<2)), addr,
READ_VPP_REG(addr));
pr_info("----dump ndr reg----\n");
for (addr = (0x2d00);
addr <= (0x2d78); addr++)
pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n",
(base_reg + (addr<<2)), addr,
READ_VPP_REG(addr));
pr_info("----dump nr3 reg----\n");
for (addr = (0x2ff0);
addr <= (0x2ff6); addr++)
pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n",
(base_reg + (addr<<2)), addr,
READ_VPP_REG(addr));
pr_info("----dump vlock reg----\n");
for (addr = (0x3000);
addr <= (0x3020); addr++)
pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n",
(base_reg + (addr<<2)), addr,
READ_VPP_REG(addr));
pr_info("----dump super scaler0 reg----\n");
for (addr = (0x3100);
addr <= (0x3115); addr++)
pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n",
(base_reg + (addr<<2)), addr,
READ_VPP_REG(addr));
pr_info("----dump super scaler1 reg----\n");
for (addr = (0x3118);
addr <= (0x312e); addr++)
pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n",
(base_reg + (addr<<2)), addr,
READ_VPP_REG(addr));
pr_info("----dump xvycc reg----\n");
for (addr = (0x3158);
addr <= (0x3179); addr++)
pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n",
(base_reg + (addr<<2)), addr,
READ_VPP_REG(addr));
pr_info("----dump reg done----\n");
return 0;
}
static ssize_t amvecm_dump_reg_store(struct class *cla,
struct class_attribute *attr,
const char *buf, size_t count)
{
return 0;
}
static ssize_t amvecm_dump_vpp_hist_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
vpp_dump_histgram();
return 0;
}
static ssize_t amvecm_dump_vpp_hist_store(struct class *cla,
struct class_attribute *attr,
const char *buf, size_t count)
{
return 0;
}
static ssize_t amvecm_hdr_dbg_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
int ret;
ret = amvecm_hdr_dbg(0);
return 0;
}
static ssize_t amvecm_hdr_dbg_store(struct class *cla,
struct class_attribute *attr,
const char *buf, size_t count)
{
long val = 0;
char *buf_orig, *parm[5] = {NULL};
if (!buf)
return count;
buf_orig = kstrdup(buf, GFP_KERNEL);
parse_param_amvecm(buf_orig, (char **)&parm);
if (!strncmp(parm[0], "hdr_dbg", 10)) {
if (kstrtoul(parm[1], 16, &val) < 0) {
kfree(buf_orig);
return -EINVAL;
}
debug_hdr = val;
pr_info("debug_hdr=0x%x\n", debug_hdr);
} else
pr_info("error cmd\n");
kfree(buf_orig);
return count;
}
static ssize_t amvecm_hdr_reg_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
int ret;
ret = amvecm_hdr_dbg(1);
return 0;
}
static ssize_t amvecm_hdr_reg_store(struct class *cla,
struct class_attribute *attr,
const char *buf, size_t count)
{
return 0;
}
static ssize_t amvecm_pc_mode_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
pr_info("pc:echo 0x0 > /sys/class/amvecm/pc_mode\n");
pr_info("other:echo 0x1 > /sys/class/amvecm/pc_mode\n");
pr_info("pc_mode:%d,pc_mode_last:%d\n", pc_mode, pc_mode_last);
return 0;
}
static ssize_t amvecm_pc_mode_store(struct class *cla,
struct class_attribute *attr,
const char *buf, size_t count)
{
size_t r;
int val;
r = sscanf(buf, "%x\n", &val);
if ((r != 1))
return -EINVAL;
if (val == 1) {
pc_mode = 1;
pc_mode_last = 0xff;
} else if (val == 0) {
pc_mode = 0;
pc_mode_last = 0xff;
}
return count;
}
void pc_mode_process(void)
{
unsigned int reg_val;
if ((pc_mode == 1) && (pc_mode != pc_mode_last)) {
/* open dnlp clock gate */
dnlp_en = 1;
ve_enable_dnlp();
/* open cm clock gate */
cm_en = 1;
/* sharpness on */
VSYNC_WR_MPEG_REG_BITS(
SRSHARP0_PK_NR_ENABLE + sr_offset[0],
1, 1, 1);
VSYNC_WR_MPEG_REG_BITS(
SRSHARP1_PK_NR_ENABLE + sr_offset[1],
1, 1, 1);
reg_val = VSYNC_RD_MPEG_REG(SRSHARP0_HCTI_FLT_CLP_DC
+ sr_offset[0]);
VSYNC_WR_MPEG_REG(SRSHARP0_HCTI_FLT_CLP_DC + sr_offset[0],
reg_val | 0x10000000);
VSYNC_WR_MPEG_REG(SRSHARP1_HCTI_FLT_CLP_DC + sr_offset[1],
reg_val | 0x10000000);
reg_val = VSYNC_RD_MPEG_REG(SRSHARP0_HLTI_FLT_CLP_DC
+ sr_offset[0]);
VSYNC_WR_MPEG_REG(SRSHARP0_HLTI_FLT_CLP_DC + sr_offset[0],
reg_val | 0x10000000);
VSYNC_WR_MPEG_REG(SRSHARP1_HLTI_FLT_CLP_DC + sr_offset[1],
reg_val | 0x10000000);
reg_val = VSYNC_RD_MPEG_REG(SRSHARP0_VLTI_FLT_CON_CLP
+ sr_offset[0]);
VSYNC_WR_MPEG_REG(SRSHARP0_VLTI_FLT_CON_CLP + sr_offset[0],
reg_val | 0x4000);
VSYNC_WR_MPEG_REG(SRSHARP1_VLTI_FLT_CON_CLP + sr_offset[1],
reg_val | 0x4000);
reg_val = VSYNC_RD_MPEG_REG(SRSHARP0_VCTI_FLT_CON_CLP
+ sr_offset[0]);
VSYNC_WR_MPEG_REG(SRSHARP0_VCTI_FLT_CON_CLP + sr_offset[0],
reg_val | 0x4000);
VSYNC_WR_MPEG_REG(SRSHARP1_VCTI_FLT_CON_CLP + sr_offset[1],
reg_val | 0x4000);
if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) {
VSYNC_WR_MPEG_REG_BITS(SRSHARP0_DEJ_CTRL + sr_offset[0],
1, 0, 1);
VSYNC_WR_MPEG_REG_BITS(SRSHARP0_SR3_DRTLPF_EN
+ sr_offset[0], 7, 0, 3);
VSYNC_WR_MPEG_REG_BITS(SRSHARP0_SR3_DERING_CTRL
+ sr_offset[0], 1, 28, 3);
VSYNC_WR_MPEG_REG_BITS(SRSHARP1_DEJ_CTRL + sr_offset[1],
1, 0, 1);
VSYNC_WR_MPEG_REG_BITS(SRSHARP1_SR3_DRTLPF_EN
+ sr_offset[1], 7, 0, 3);
VSYNC_WR_MPEG_REG_BITS(SRSHARP1_SR3_DERING_CTRL
+ sr_offset[1], 1, 28, 3);
}
VSYNC_WR_MPEG_REG(VPP_VADJ_CTRL, 0xd);
pc_mode_last = pc_mode;
} else if ((pc_mode == 0) && (pc_mode != pc_mode_last)) {
dnlp_en = 0;
ve_disable_dnlp();
cm_en = 0;
VSYNC_WR_MPEG_REG_BITS(
SRSHARP0_PK_NR_ENABLE + sr_offset[0],
0, 1, 1);
VSYNC_WR_MPEG_REG_BITS(
SRSHARP1_PK_NR_ENABLE + sr_offset[1],
0, 1, 1);
reg_val = VSYNC_RD_MPEG_REG(SRSHARP0_HCTI_FLT_CLP_DC
+ sr_offset[0]);
VSYNC_WR_MPEG_REG(SRSHARP0_HCTI_FLT_CLP_DC + sr_offset[0],
reg_val & 0xefffffff);
VSYNC_WR_MPEG_REG(SRSHARP1_HCTI_FLT_CLP_DC + sr_offset[1],
reg_val & 0xefffffff);
reg_val = VSYNC_RD_MPEG_REG(SRSHARP0_HLTI_FLT_CLP_DC
+ sr_offset[0]);
VSYNC_WR_MPEG_REG(SRSHARP0_HLTI_FLT_CLP_DC + sr_offset[0],
reg_val & 0xefffffff);
VSYNC_WR_MPEG_REG(SRSHARP1_HLTI_FLT_CLP_DC + sr_offset[1],
reg_val & 0xefffffff);
reg_val = VSYNC_RD_MPEG_REG(SRSHARP0_VLTI_FLT_CON_CLP
+ sr_offset[0]);
VSYNC_WR_MPEG_REG(SRSHARP0_VLTI_FLT_CON_CLP + sr_offset[0],
reg_val & 0xffffbfff);
VSYNC_WR_MPEG_REG(SRSHARP1_VLTI_FLT_CON_CLP + sr_offset[1],
reg_val & 0xffffbfff);
reg_val = VSYNC_RD_MPEG_REG(SRSHARP0_VCTI_FLT_CON_CLP
+ sr_offset[0]);
VSYNC_WR_MPEG_REG(SRSHARP0_VCTI_FLT_CON_CLP + sr_offset[0],
reg_val & 0xffffbfff);
VSYNC_WR_MPEG_REG(SRSHARP1_VCTI_FLT_CON_CLP + sr_offset[1],
reg_val & 0xffffbfff);
if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) {
VSYNC_WR_MPEG_REG_BITS(SRSHARP0_DEJ_CTRL + sr_offset[0],
0, 0, 1);
VSYNC_WR_MPEG_REG_BITS(SRSHARP0_SR3_DRTLPF_EN
+ sr_offset[0], 0, 0, 3);
VSYNC_WR_MPEG_REG_BITS(SRSHARP0_SR3_DERING_CTRL
+ sr_offset[0], 0, 28, 3);
VSYNC_WR_MPEG_REG_BITS(SRSHARP1_DEJ_CTRL + sr_offset[1],
0, 0, 1);
VSYNC_WR_MPEG_REG_BITS(SRSHARP1_SR3_DRTLPF_EN
+ sr_offset[1], 0, 0, 3);
VSYNC_WR_MPEG_REG_BITS(SRSHARP1_SR3_DERING_CTRL
+ sr_offset[1], 0, 28, 3);
}
VSYNC_WR_MPEG_REG(VPP_VADJ_CTRL, 0x0);
pc_mode_last = pc_mode;
}
}
void amvecm_black_ext_enable(unsigned int enable)
{
if (enable)
WRITE_VPP_REG_BITS(VPP_VE_ENABLE_CTRL, 1, 3, 1);
else
WRITE_VPP_REG_BITS(VPP_VE_ENABLE_CTRL, 0, 3, 1);
}
void amvecm_black_ext_start_adj(unsigned int value)
{
if (value > 255)
return;
WRITE_VPP_REG_BITS(VPP_BLACKEXT_CTRL, value, 24, 8);
}
void amvecm_black_ext_slope_adj(unsigned int value)
{
if (value > 255)
return;
WRITE_VPP_REG_BITS(VPP_BLACKEXT_CTRL, value, 16, 8);
}
void amvecm_sr0_pk_enable(unsigned int enable)
{
if (enable)
WRITE_VPP_REG_BITS(SRSHARP0_PK_NR_ENABLE + sr_offset[0],
1, 1, 1);
else
WRITE_VPP_REG_BITS(SRSHARP0_PK_NR_ENABLE + sr_offset[0],
0, 1, 1);
}
void amvecm_sr1_pk_enable(unsigned int enable)
{
if (enable)
WRITE_VPP_REG_BITS(SRSHARP1_PK_NR_ENABLE + sr_offset[1],
1, 1, 1);
else
WRITE_VPP_REG_BITS(SRSHARP1_PK_NR_ENABLE + sr_offset[1],
0, 1, 1);
}
void amvecm_sr0_dering_enable(unsigned int enable)
{
if (enable)
WRITE_VPP_REG_BITS(SRSHARP0_SR3_DERING_CTRL + sr_offset[0],
1, 28, 3);
else
WRITE_VPP_REG_BITS(SRSHARP0_SR3_DERING_CTRL + sr_offset[0],
0, 28, 3);
}
void amvecm_sr1_dering_enable(unsigned int enable)
{
if (enable)
WRITE_VPP_REG_BITS(SRSHARP1_SR3_DERING_CTRL + sr_offset[1],
1, 28, 3);
else
WRITE_VPP_REG_BITS(SRSHARP1_SR3_DERING_CTRL + sr_offset[1],
0, 28, 3);
}
void amvecm_sr0_dejaggy_enable(unsigned int enable)
{
if (enable)
WRITE_VPP_REG_BITS(SRSHARP0_DEJ_CTRL + sr_offset[0],
1, 0, 1);
else
WRITE_VPP_REG_BITS(SRSHARP0_DEJ_CTRL + sr_offset[0],
0, 0, 1);
}
void amvecm_sr1_dejaggy_enable(unsigned int enable)
{
if (enable)
WRITE_VPP_REG_BITS(SRSHARP1_DEJ_CTRL + sr_offset[1],
1, 0, 1);
else
WRITE_VPP_REG_BITS(SRSHARP1_DEJ_CTRL + sr_offset[1],
0, 0, 1);
}
void amvecm_sr0_derection_enable(unsigned int enable)
{
if (enable)
WRITE_VPP_REG_BITS(SRSHARP0_SR3_DRTLPF_EN + sr_offset[0],
7, 0, 3);
else
WRITE_VPP_REG_BITS(SRSHARP0_SR3_DRTLPF_EN + sr_offset[0],
0, 0, 3);
}
void amvecm_sr1_derection_enable(unsigned int enable)
{
if (enable)
WRITE_VPP_REG_BITS(SRSHARP1_SR3_DRTLPF_EN + sr_offset[1],
7, 0, 3);
else
WRITE_VPP_REG_BITS(SRSHARP1_SR3_DRTLPF_EN + sr_offset[1],
0, 0, 3);
}
void pq_user_latch_process(void)
{
if (pq_user_latch_flag & PQ_USER_BLK_EN) {
pq_user_latch_flag &= ~PQ_USER_BLK_EN;
amvecm_black_ext_enable(true);
} else if (pq_user_latch_flag & PQ_USER_BLK_DIS) {
pq_user_latch_flag &= ~PQ_USER_BLK_DIS;
amvecm_black_ext_enable(false);
} else if (pq_user_latch_flag & PQ_USER_BLK_START) {
pq_user_latch_flag &= ~PQ_USER_BLK_START;
amvecm_black_ext_start_adj(pq_user_value);
} else if (pq_user_latch_flag & PQ_USER_BLK_SLOPE) {
pq_user_latch_flag &= ~PQ_USER_BLK_SLOPE;
amvecm_black_ext_slope_adj(pq_user_value);
} else if (pq_user_latch_flag & PQ_USER_SR0_PK_EN) {
pq_user_latch_flag &= ~PQ_USER_SR0_PK_EN;
amvecm_sr0_pk_enable(true);
} else if (pq_user_latch_flag & PQ_USER_SR0_PK_DIS) {
pq_user_latch_flag &= ~PQ_USER_SR0_PK_DIS;
amvecm_sr0_pk_enable(false);
} else if (pq_user_latch_flag & PQ_USER_SR1_PK_EN) {
pq_user_latch_flag &= ~PQ_USER_SR1_PK_EN;
amvecm_sr1_pk_enable(true);
} else if (pq_user_latch_flag & PQ_USER_SR1_PK_DIS) {
pq_user_latch_flag &= ~PQ_USER_SR1_PK_DIS;
amvecm_sr1_pk_enable(false);
} else if (pq_user_latch_flag & PQ_USER_SR0_DERING_EN) {
pq_user_latch_flag &= ~PQ_USER_SR0_DERING_EN;
amvecm_sr0_dering_enable(true);
} else if (pq_user_latch_flag & PQ_USER_SR0_DERING_DIS) {
pq_user_latch_flag &= ~PQ_USER_SR0_DERING_DIS;
amvecm_sr0_dering_enable(false);
} else if (pq_user_latch_flag & PQ_USER_SR1_DERING_EN) {
pq_user_latch_flag &= ~PQ_USER_SR1_DERING_EN;
amvecm_sr1_dering_enable(true);
} else if (pq_user_latch_flag & PQ_USER_SR1_DERING_DIS) {
pq_user_latch_flag &= ~PQ_USER_SR1_DERING_DIS;
amvecm_sr1_dering_enable(false);
} else if (pq_user_latch_flag & PQ_USER_SR0_DEJAGGY_EN) {
pq_user_latch_flag &= ~PQ_USER_SR0_DEJAGGY_EN;
amvecm_sr0_dejaggy_enable(true);
} else if (pq_user_latch_flag & PQ_USER_SR0_DEJAGGY_DIS) {
pq_user_latch_flag &= ~PQ_USER_SR0_DEJAGGY_DIS;
amvecm_sr0_dejaggy_enable(false);
} else if (pq_user_latch_flag & PQ_USER_SR1_DEJAGGY_EN) {
pq_user_latch_flag &= ~PQ_USER_SR1_DEJAGGY_EN;
amvecm_sr1_dejaggy_enable(true);
} else if (pq_user_latch_flag & PQ_USER_SR1_DEJAGGY_DIS) {
pq_user_latch_flag &= ~PQ_USER_SR1_DEJAGGY_DIS;
amvecm_sr1_dejaggy_enable(false);
} else if (pq_user_latch_flag & PQ_USER_SR0_DERECTION_EN) {
pq_user_latch_flag &= ~PQ_USER_SR0_DERECTION_EN;
amvecm_sr0_derection_enable(true);
} else if (pq_user_latch_flag & PQ_USER_SR0_DERECTION_DIS) {
pq_user_latch_flag &= ~PQ_USER_SR0_DERECTION_DIS;
amvecm_sr0_derection_enable(false);
} else if (pq_user_latch_flag & PQ_USER_SR1_DERECTION_EN) {
pq_user_latch_flag &= ~PQ_USER_SR1_DERECTION_EN;
amvecm_sr1_derection_enable(true);
} else if (pq_user_latch_flag & PQ_USER_SR1_DERECTION_DIS) {
pq_user_latch_flag &= ~PQ_USER_SR1_DERECTION_DIS;
amvecm_sr1_derection_enable(false);
}
}
static const char *amvecm_pq_user_usage_str = {
"Usage:\n"
"echo blk_ext_en > /sys/class/amvecm/pq_user_set: blk ext en\n"
"echo blk_ext_dis > /sys/class/amvecm/pq_user_set: blk ext dis\n"
"echo blk_start val > /sys/class/amvecm/pq_user_set: start adj\n"
"echo blk_slope val > /sys/class/amvecm/pq_user_set: slope adj\n"
"echo sr0_pk_en > /sys/class/amvecm/pq_user_set: sr0 pk en\n"
"echo sr0_pk_dis > /sys/class/amvecm/pq_user_set: sr0 pk dis\n"
"echo sr1_pk_en > /sys/class/amvecm/pq_user_set: sr0 pk en\n"
"echo sr1_pk_dis > /sys/class/amvecm/pq_user_set: sr0 pk dis\n"
"echo sr0_dering_en > /sys/class/amvecm/pq_user_set: sr0 dr en\n"
"echo sr0_dering_dis > /sys/class/amvecm/pq_user_set: sr0 dr dis\n"
"echo sr1_dering_en > /sys/class/amvecm/pq_user_set: sr1 dr en\n"
"echo sr1_dering_dis > /sys/class/amvecm/pq_user_set: sr1 dr dis\n"
"echo sr0_dejaggy_en > /sys/class/amvecm/pq_user_set: sr0 dj en\n"
"echo sr0_dejaggy_dis > /sys/class/amvecm/pq_user_set: sr0 dj dis\n"
"echo sr1_dejaggy_en > /sys/class/amvecm/pq_user_set: sr1 dj en\n"
"echo sr1_dejaggy_dis > /sys/class/amvecm/pq_user_set: sr1 dj dis\n"
"echo sr0_derec_en > /sys/class/amvecm/pq_user_set: sr0 drec en\n"
"echo sr0_derec_dis > /sys/class/amvecm/pq_user_set: sr0 drec dis\n"
"echo sr1_derec_en > /sys/class/amvecm/pq_user_set: sr1 drec en\n"
"echo sr1_derec_dis > /sys/class/amvecm/pq_user_set: sr1 drec dis\n"
};
static ssize_t amvecm_pq_user_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
return sprintf(buf, "%s\n", amvecm_pq_user_usage_str);
}
static ssize_t amvecm_pq_user_store(struct class *cla,
struct class_attribute *attr,
const char *buf, size_t count)
{
char *buf_orig, *parm[8] = {NULL};
long val = 0;
if (!buf)
return count;
buf_orig = kstrdup(buf, GFP_KERNEL);
parse_param_amvecm(buf_orig, (char **)&parm);
if (!strncmp(parm[0], "blk_ext_en", 10))
pq_user_latch_flag |= PQ_USER_BLK_EN;
else if (!strncmp(parm[0], "blk_ext_dis", 11))
pq_user_latch_flag |= PQ_USER_BLK_DIS;
else if (!strncmp(parm[0], "blk_start", 9)) {
if (kstrtoul(parm[1], 10, &val) < 0) {
kfree(buf_orig);
return -EINVAL;
}
pq_user_value = val;
pq_user_latch_flag |= PQ_USER_BLK_START;
} else if (!strncmp(parm[0], "blk_slope", 9)) {
if (kstrtoul(parm[1], 10, &val) < 0) {
kfree(buf_orig);
return -EINVAL;
}
pq_user_value = val;
pq_user_latch_flag |= PQ_USER_BLK_SLOPE;
} else if (!strncmp(parm[0], "sr0_pk_en", 9)) {
pq_user_latch_flag |= PQ_USER_SR0_PK_EN;
} else if (!strncmp(parm[0], "sr0_pk_dis", 10)) {
pq_user_latch_flag |= PQ_USER_SR0_PK_DIS;
} else if (!strncmp(parm[0], "sr1_pk_en", 9)) {
pq_user_latch_flag |= PQ_USER_SR1_PK_EN;
} else if (!strncmp(parm[0], "sr1_pk_dis", 10)) {
pq_user_latch_flag |= PQ_USER_SR1_PK_DIS;
} else if (!strncmp(parm[0], "sr0_dering_en", 13)) {
pq_user_latch_flag |= PQ_USER_SR0_DERING_EN;
} else if (!strncmp(parm[0], "sr0_dering_dis", 14)) {
pq_user_latch_flag |= PQ_USER_SR0_DERING_DIS;
} else if (!strncmp(parm[0], "sr1_dering_en", 13)) {
pq_user_latch_flag |= PQ_USER_SR1_DERING_EN;
} else if (!strncmp(parm[0], "sr1_dering_dis", 14)) {
pq_user_latch_flag |= PQ_USER_SR1_DERING_DIS;
} else if (!strncmp(parm[0], "sr0_dejaggy_en", 14)) {
pq_user_latch_flag |= PQ_USER_SR0_DEJAGGY_EN;
} else if (!strncmp(parm[0], "sr0_dejaggy_dis", 15)) {
pq_user_latch_flag |= PQ_USER_SR0_DEJAGGY_DIS;
} else if (!strncmp(parm[0], "sr1_dejaggy_en", 14)) {
pq_user_latch_flag |= PQ_USER_SR1_DEJAGGY_EN;
} else if (!strncmp(parm[0], "sr1_dejaggy_dis", 15)) {
pq_user_latch_flag |= PQ_USER_SR1_DEJAGGY_DIS;
} else if (!strncmp(parm[0], "sr0_derec_en", 12)) {
pq_user_latch_flag |= PQ_USER_SR0_DERECTION_EN;
} else if (!strncmp(parm[0], "sr0_derec_dis", 13)) {
pq_user_latch_flag |= PQ_USER_SR0_DERECTION_DIS;
} else if (!strncmp(parm[0], "sr1_derec_en", 12)) {
pq_user_latch_flag |= PQ_USER_SR1_DERECTION_EN;
} else if (!strncmp(parm[0], "sr1_derec_dis", 13)) {
pq_user_latch_flag |= PQ_USER_SR1_DERECTION_DIS;
}
kfree(buf_orig);
return count;
}
static const char *dnlp_insmod_debug_usage_str = {
"usage: echo 1 > /sys/class/amvecm/dnlp_insmod\n"
};
static ssize_t amvecm_dnlp_insmod_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
return sprintf(buf, "%s\n", dnlp_insmod_debug_usage_str);
}
static ssize_t amvecm_dnlp_insmod_store(struct class *cla,
struct class_attribute *attr,
const char *buf, size_t count)
{
size_t r;
int val;
r = sscanf(buf, "%x\n", &val);
if ((r != 1))
return -EINVAL;
if (val == 1)
dnlp_alg_param_init();
return count;
}
static ssize_t amvecm_vpp_demo_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
return 0;
}
static ssize_t amvecm_vpp_demo_store(struct class *cla,
struct class_attribute *attr,
const char *buf, size_t count)
{
size_t r;
int val;
r = sscanf(buf, "%x\n", &val);
if ((r != 1))
return -EINVAL;
if (val & VPP_DEMO_CM_EN)
vpp_demo_latch_flag |= VPP_DEMO_CM_EN;
else if (val & VPP_DEMO_CM_DIS)
vpp_demo_latch_flag |= VPP_DEMO_CM_DIS;
if (val & VPP_DEMO_DNLP_EN)
vpp_demo_latch_flag |= VPP_DEMO_DNLP_EN;
else if (val & VPP_DEMO_DNLP_DIS)
vpp_demo_latch_flag |= VPP_DEMO_DNLP_DIS;
return count;
}
static void dump_vpp_size_info(void)
{
unsigned int vpp_input_h, vpp_input_v,
pps_input_length, pps_input_height,
pps_output_hs, pps_output_he, pps_output_vs, pps_output_ve,
vd1_preblend_hs, vd1_preblend_he,
vd1_preblend_vs, vd1_preblend_ve,
vd2_preblend_hs, vd2_preblend_he,
vd2_preblend_vs, vd2_preblend_ve,
prelend_input_hsize,
vd1_postblend_hs, vd1_postblend_he,
vd1_postblend_vs, vd1_postblend_ve,
postblend_hsize,
ve_hsize, ve_vsize, psr_hsize, psr_vsize,
cm_hsize, cm_vsize;
vpp_input_h = READ_VPP_REG_BITS(VPP_IN_H_V_SIZE, 16, 13);
vpp_input_v = READ_VPP_REG_BITS(VPP_IN_H_V_SIZE, 0, 13);
pps_input_length = READ_VPP_REG_BITS(VPP_LINE_IN_LENGTH, 0, 13);
pps_input_height = READ_VPP_REG_BITS(VPP_PIC_IN_HEIGHT, 0, 13);
pps_output_hs = READ_VPP_REG_BITS(VPP_HSC_REGION12_STARTP, 16, 13);
pps_output_he = READ_VPP_REG_BITS(VPP_HSC_REGION4_ENDP, 0, 13);
pps_output_vs = READ_VPP_REG_BITS(VPP_VSC_REGION12_STARTP, 16, 13);
pps_output_ve = READ_VPP_REG_BITS(VPP_VSC_REGION4_ENDP, 0, 13);
vd1_preblend_he = READ_VPP_REG_BITS(VPP_PREBLEND_VD1_H_START_END,
0, 13);
vd1_preblend_hs = READ_VPP_REG_BITS(VPP_PREBLEND_VD1_H_START_END,
16, 13);
vd1_preblend_ve = READ_VPP_REG_BITS(VPP_PREBLEND_VD1_V_START_END,
0, 13);
vd1_preblend_vs = READ_VPP_REG_BITS(VPP_PREBLEND_VD1_V_START_END,
16, 13);
vd2_preblend_he = READ_VPP_REG_BITS(VPP_BLEND_VD2_H_START_END, 0, 13);
vd2_preblend_hs = READ_VPP_REG_BITS(VPP_BLEND_VD2_H_START_END, 16, 13);
vd2_preblend_ve = READ_VPP_REG_BITS(VPP_BLEND_VD2_V_START_END, 0, 13);
vd2_preblend_vs = READ_VPP_REG_BITS(VPP_BLEND_VD2_V_START_END, 16, 13);
prelend_input_hsize = READ_VPP_REG_BITS(VPP_PREBLEND_H_SIZE, 0, 13);
vd1_postblend_he = READ_VPP_REG_BITS(VPP_POSTBLEND_VD1_H_START_END,
0, 13);
vd1_postblend_hs = READ_VPP_REG_BITS(VPP_POSTBLEND_VD1_H_START_END,
16, 13);
vd1_postblend_ve = READ_VPP_REG_BITS(VPP_POSTBLEND_VD1_V_START_END,
0, 13);
vd1_postblend_vs = READ_VPP_REG_BITS(VPP_POSTBLEND_VD1_V_START_END,
16, 13);
postblend_hsize = READ_VPP_REG_BITS(VPP_POSTBLEND_H_SIZE, 0, 13);
ve_hsize = READ_VPP_REG_BITS(VPP_VE_H_V_SIZE, 16, 13);
ve_vsize = READ_VPP_REG_BITS(VPP_VE_H_V_SIZE, 0, 13);
psr_hsize = READ_VPP_REG_BITS(VPP_PSR_H_V_SIZE, 16, 13);
psr_vsize = READ_VPP_REG_BITS(VPP_PSR_H_V_SIZE, 0, 13);
WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, 0x205);
cm_hsize = READ_VPP_REG(VPP_CHROMA_DATA_PORT);
cm_vsize = (cm_hsize >> 16) & 0xffff;
cm_hsize = cm_hsize & 0xffff;
pr_info("\n vpp size info:\n");
pr_info("vpp_input_h:%d, vpp_input_v:%d\n"
"pps_input_length:%d, pps_input_height:%d\n"
"pps_output_hs:%d, pps_output_he:%d\n"
"pps_output_vs:%d, pps_output_ve:%d\n"
"vd1_preblend_hs:%d, vd1_preblend_he:%d\n"
"vd1_preblend_vs:%d, vd1_preblend_ve:%d\n"
"vd2_preblend_hs:%d, vd2_preblend_he:%d\n"
"vd2_preblend_vs:%d, vd2_preblend_ve:%d\n"
"prelend_input_hsize:%d\n"
"vd1_postblend_hs:%d, vd1_postblend_he:%d\n"
"vd1_postblend_vs:%d, vd1_postblend_ve:%d\n"
"postblend_hsize:%d\n"
"ve_hsize:%d, ve_vsize:%d\n"
"psr_hsize:%d, psr_vsize:%d\n"
"cm_hsize:%d, cm_vsize:%d\n",
vpp_input_h, vpp_input_v,
pps_input_length, pps_input_height,
pps_output_hs, pps_output_he,
pps_output_vs, pps_output_ve,
vd1_preblend_hs, vd1_preblend_he,
vd1_preblend_vs, vd1_preblend_ve,
vd2_preblend_hs, vd2_preblend_he,
vd2_preblend_vs, vd2_preblend_ve,
prelend_input_hsize,
vd1_postblend_hs, vd1_postblend_he,
vd1_postblend_vs, vd1_postblend_ve,
postblend_hsize,
ve_hsize, ve_vsize,
psr_hsize, psr_vsize,
cm_hsize, cm_vsize);
}
static void amvecm_wb_enable(int enable)
{
if (enable) {
wb_en = 1;
if (video_rgb_ogo_xvy_mtx)
WRITE_VPP_REG_BITS(VPP_MATRIX_CTRL, 1, 6, 1);
else
WRITE_VPP_REG_BITS(VPP_GAINOFF_CTRL0, 1, 31, 1);
} else {
wb_en = 0;
if (video_rgb_ogo_xvy_mtx)
WRITE_VPP_REG_BITS(VPP_MATRIX_CTRL, 0, 6, 1);
else
WRITE_VPP_REG_BITS(VPP_GAINOFF_CTRL0, 0, 31, 1);
}
}
void amvecm_sharpness_enable(int sel)
{
/*0:peaking enable 1:peaking disable*/
/*2:lti/cti enable 3:lti/cti disable*/
switch (sel) {
case 0:
WRITE_VPP_REG_BITS(SRSHARP0_PK_NR_ENABLE + sr_offset[0],
1, 1, 1);
WRITE_VPP_REG_BITS(SRSHARP1_PK_NR_ENABLE + sr_offset[1],
1, 1, 1);
break;
case 1:
WRITE_VPP_REG_BITS(SRSHARP0_PK_NR_ENABLE + sr_offset[0],
0, 1, 1);
WRITE_VPP_REG_BITS(SRSHARP1_PK_NR_ENABLE + sr_offset[1],
0, 1, 1);
break;
case 2:
WRITE_VPP_REG_BITS(SRSHARP0_HCTI_FLT_CLP_DC + sr_offset[0],
1, 28, 1);
WRITE_VPP_REG_BITS(SRSHARP0_HLTI_FLT_CLP_DC + sr_offset[0],
1, 28, 1);
WRITE_VPP_REG_BITS(SRSHARP0_VLTI_FLT_CON_CLP + sr_offset[0],
1, 14, 1);
WRITE_VPP_REG_BITS(SRSHARP0_VCTI_FLT_CON_CLP + sr_offset[0],
1, 14, 1);
WRITE_VPP_REG_BITS(SRSHARP1_HCTI_FLT_CLP_DC + sr_offset[1],
1, 28, 1);
WRITE_VPP_REG_BITS(SRSHARP1_HLTI_FLT_CLP_DC + sr_offset[1],
1, 28, 1);
WRITE_VPP_REG_BITS(SRSHARP1_VLTI_FLT_CON_CLP + sr_offset[1],
1, 14, 1);
WRITE_VPP_REG_BITS(SRSHARP1_VCTI_FLT_CON_CLP + sr_offset[1],
1, 14, 1);
break;
case 3:
WRITE_VPP_REG_BITS(SRSHARP0_HCTI_FLT_CLP_DC + sr_offset[0],
0, 28, 1);
WRITE_VPP_REG_BITS(SRSHARP0_HLTI_FLT_CLP_DC + sr_offset[0],
0, 28, 1);
WRITE_VPP_REG_BITS(SRSHARP0_VLTI_FLT_CON_CLP + sr_offset[0],
0, 14, 1);
WRITE_VPP_REG_BITS(SRSHARP0_VCTI_FLT_CON_CLP + sr_offset[0],
0, 14, 1);
WRITE_VPP_REG_BITS(SRSHARP1_HCTI_FLT_CLP_DC + sr_offset[1],
0, 28, 1);
WRITE_VPP_REG_BITS(SRSHARP1_HLTI_FLT_CLP_DC + sr_offset[1],
0, 28, 1);
WRITE_VPP_REG_BITS(SRSHARP1_VLTI_FLT_CON_CLP + sr_offset[1],
0, 14, 1);
WRITE_VPP_REG_BITS(SRSHARP1_VCTI_FLT_CON_CLP + sr_offset[1],
0, 14, 1);
break;
/*sr4 drtlpf theta en*/
case 4:
WRITE_VPP_REG_BITS(SRSHARP0_SR3_DRTLPF_EN + sr_offset[0],
7, 4, 3);
WRITE_VPP_REG_BITS(SRSHARP1_SR3_DRTLPF_EN + sr_offset[1],
7, 3, 3);
break;
case 5:
WRITE_VPP_REG_BITS(SRSHARP0_SR3_DRTLPF_EN + sr_offset[0],
0, 4, 3);
WRITE_VPP_REG_BITS(SRSHARP1_SR3_DRTLPF_EN + sr_offset[1],
0, 3, 3);
break;
/*sr4 debanding en*/
case 6:
WRITE_VPP_REG_BITS(SRSHARP0_DB_FLT_CTRL + sr_offset[0],
1, 4, 1);
WRITE_VPP_REG_BITS(SRSHARP0_DB_FLT_CTRL + sr_offset[0],
1, 5, 1);
WRITE_VPP_REG_BITS(SRSHARP0_DB_FLT_CTRL + sr_offset[0],
1, 22, 1);
WRITE_VPP_REG_BITS(SRSHARP0_DB_FLT_CTRL + sr_offset[0],
1, 23, 1);
WRITE_VPP_REG_BITS(SRSHARP1_DB_FLT_CTRL + sr_offset[1],
1, 4, 1);
WRITE_VPP_REG_BITS(SRSHARP1_DB_FLT_CTRL + sr_offset[1],
1, 5, 1);
WRITE_VPP_REG_BITS(SRSHARP1_DB_FLT_CTRL + sr_offset[1],
1, 22, 1);
WRITE_VPP_REG_BITS(SRSHARP1_DB_FLT_CTRL + sr_offset[1],
1, 23, 1);
break;
case 7:
WRITE_VPP_REG_BITS(SRSHARP0_DB_FLT_CTRL + sr_offset[0],
0, 4, 1);
WRITE_VPP_REG_BITS(SRSHARP0_DB_FLT_CTRL + sr_offset[0],
0, 5, 1);
WRITE_VPP_REG_BITS(SRSHARP0_DB_FLT_CTRL + sr_offset[0],
0, 22, 1);
WRITE_VPP_REG_BITS(SRSHARP0_DB_FLT_CTRL + sr_offset[0],
0, 23, 1);
WRITE_VPP_REG_BITS(SRSHARP1_DB_FLT_CTRL + sr_offset[1],
0, 4, 1);
WRITE_VPP_REG_BITS(SRSHARP1_DB_FLT_CTRL + sr_offset[1],
0, 5, 1);
WRITE_VPP_REG_BITS(SRSHARP1_DB_FLT_CTRL + sr_offset[1],
0, 22, 1);
WRITE_VPP_REG_BITS(SRSHARP1_DB_FLT_CTRL + sr_offset[1],
0, 23, 1);
break;
/*sr3 dejaggy en*/
case 8:
WRITE_VPP_REG_BITS(SRSHARP0_DEJ_CTRL + sr_offset[0],
1, 0, 1);
WRITE_VPP_REG_BITS(SRSHARP1_DEJ_CTRL + sr_offset[1],
1, 0, 1);
break;
case 9:
WRITE_VPP_REG_BITS(SRSHARP0_DEJ_CTRL + sr_offset[0],
0, 0, 1);
WRITE_VPP_REG_BITS(SRSHARP1_DEJ_CTRL + sr_offset[1],
0, 0, 1);
break;
/*sr3 dering en*/
case 10:
WRITE_VPP_REG_BITS(SRSHARP0_SR3_DERING_CTRL + sr_offset[0],
1, 28, 3);
WRITE_VPP_REG_BITS(SRSHARP1_SR3_DERING_CTRL + sr_offset[1],
1, 28, 3);
break;
case 11:
WRITE_VPP_REG_BITS(SRSHARP0_SR3_DERING_CTRL + sr_offset[0],
0, 28, 3);
WRITE_VPP_REG_BITS(SRSHARP1_SR3_DERING_CTRL + sr_offset[1],
0, 28, 3);
break;
/*sr3 derection lpf en*/
case 12:
WRITE_VPP_REG_BITS(SRSHARP0_SR3_DRTLPF_EN + sr_offset[0],
7, 0, 3);
WRITE_VPP_REG_BITS(SRSHARP1_SR3_DRTLPF_EN + sr_offset[1],
7, 0, 3);
break;
case 13:
WRITE_VPP_REG_BITS(SRSHARP0_SR3_DRTLPF_EN + sr_offset[0],
0, 0, 3);
WRITE_VPP_REG_BITS(SRSHARP1_SR3_DRTLPF_EN + sr_offset[1],
0, 0, 3);
break;
default:
break;
}
}
void amvecm_clip_range_limit(bool limit_en)
{
/*fix mbox av out flicker black dot*/
if (limit_en) {
/*cvbs output 16-235 16-240 16-240*/
WRITE_VPP_REG(VPP_CLIP_MISC0, 0x3acf03c0);
WRITE_VPP_REG(VPP_CLIP_MISC1, 0x4010040);
} else {
/*retore for other mode*/
WRITE_VPP_REG(VPP_CLIP_MISC0, 0x3fffffff);
WRITE_VPP_REG(VPP_CLIP_MISC1, 0x0);
}
}
EXPORT_SYMBOL(amvecm_clip_range_limit);
static void amvecm_pq_enable(int enable)
{
if (enable) {
vecm_latch_flag |= FLAG_VE_DNLP_EN;
#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
if (!is_dolby_vision_enable())
#endif
amcm_enable();
WRITE_VPP_REG_BITS(SRSHARP0_PK_NR_ENABLE + sr_offset[0],
1, 1, 1);
WRITE_VPP_REG_BITS(SRSHARP1_PK_NR_ENABLE + sr_offset[1],
1, 1, 1);
WRITE_VPP_REG_BITS(SRSHARP0_HCTI_FLT_CLP_DC + sr_offset[0],
1, 28, 1);
WRITE_VPP_REG_BITS(SRSHARP0_HLTI_FLT_CLP_DC + sr_offset[0],
1, 28, 1);
WRITE_VPP_REG_BITS(SRSHARP0_VLTI_FLT_CON_CLP + sr_offset[0],
1, 14, 1);
WRITE_VPP_REG_BITS(SRSHARP0_VCTI_FLT_CON_CLP + sr_offset[0],
1, 14, 1);
WRITE_VPP_REG_BITS(SRSHARP1_HCTI_FLT_CLP_DC + sr_offset[1],
1, 28, 1);
WRITE_VPP_REG_BITS(SRSHARP1_HLTI_FLT_CLP_DC + sr_offset[1],
1, 28, 1);
WRITE_VPP_REG_BITS(SRSHARP1_VLTI_FLT_CON_CLP + sr_offset[1],
1, 14, 1);
WRITE_VPP_REG_BITS(SRSHARP1_VCTI_FLT_CON_CLP + sr_offset[1],
1, 14, 1);
if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) {
WRITE_VPP_REG_BITS(SRSHARP0_DEJ_CTRL + sr_offset[0],
1, 0, 1);
WRITE_VPP_REG_BITS(SRSHARP0_SR3_DRTLPF_EN
+ sr_offset[0], 7, 0, 3);
WRITE_VPP_REG_BITS(SRSHARP0_SR3_DERING_CTRL
+ sr_offset[0], 1, 28, 3);
WRITE_VPP_REG_BITS(SRSHARP1_DEJ_CTRL + sr_offset[1],
1, 0, 1);
WRITE_VPP_REG_BITS(SRSHARP1_SR3_DRTLPF_EN
+ sr_offset[1], 7, 0, 3);
WRITE_VPP_REG_BITS(SRSHARP1_SR3_DERING_CTRL
+ sr_offset[1], 1, 28, 3);
}
/*sr4 drtlpf theta/ debanding en*/
if (is_meson_txlx_cpu() || is_meson_txhd_cpu()) {
WRITE_VPP_REG_BITS(SRSHARP0_SR3_DRTLPF_EN
+ sr_offset[0], 7, 4, 3);
WRITE_VPP_REG_BITS(SRSHARP0_DB_FLT_CTRL + sr_offset[0],
1, 4, 1);
WRITE_VPP_REG_BITS(SRSHARP0_DB_FLT_CTRL + sr_offset[0],
1, 5, 1);
WRITE_VPP_REG_BITS(SRSHARP0_DB_FLT_CTRL + sr_offset[0],
1, 22, 1);
WRITE_VPP_REG_BITS(SRSHARP0_DB_FLT_CTRL + sr_offset[0],
1, 23, 1);
WRITE_VPP_REG_BITS(SRSHARP1_DB_FLT_CTRL + sr_offset[1],
1, 4, 1);
WRITE_VPP_REG_BITS(SRSHARP1_DB_FLT_CTRL + sr_offset[1],
1, 5, 1);
WRITE_VPP_REG_BITS(SRSHARP1_DB_FLT_CTRL + sr_offset[1],
1, 22, 1);
WRITE_VPP_REG_BITS(SRSHARP1_DB_FLT_CTRL + sr_offset[1],
1, 23, 1);
}
amvecm_wb_enable(true);
vecm_latch_flag |= FLAG_GAMMA_TABLE_EN;
WRITE_VPP_REG_BITS(VPP_VADJ_CTRL, 1, 0, 1);
} else {
vecm_latch_flag |= FLAG_VE_DNLP_DIS;
amcm_disable();
WRITE_VPP_REG_BITS(SRSHARP0_PK_NR_ENABLE + sr_offset[0],
0, 1, 1);
WRITE_VPP_REG_BITS(SRSHARP1_PK_NR_ENABLE + sr_offset[1],
0, 1, 1);
WRITE_VPP_REG_BITS(SRSHARP0_HCTI_FLT_CLP_DC + sr_offset[0],
0, 28, 1);
WRITE_VPP_REG_BITS(SRSHARP0_HLTI_FLT_CLP_DC + sr_offset[0],
0, 28, 1);
WRITE_VPP_REG_BITS(SRSHARP0_VLTI_FLT_CON_CLP + sr_offset[0],
0, 14, 1);
WRITE_VPP_REG_BITS(SRSHARP0_VCTI_FLT_CON_CLP + sr_offset[0],
0, 14, 1);
WRITE_VPP_REG_BITS(SRSHARP1_HCTI_FLT_CLP_DC + sr_offset[1],
0, 28, 1);
WRITE_VPP_REG_BITS(SRSHARP1_HLTI_FLT_CLP_DC + sr_offset[1],
0, 28, 1);
WRITE_VPP_REG_BITS(SRSHARP1_VLTI_FLT_CON_CLP + sr_offset[1],
0, 14, 1);
WRITE_VPP_REG_BITS(SRSHARP1_VCTI_FLT_CON_CLP + sr_offset[1],
0, 14, 1);
if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) {
WRITE_VPP_REG_BITS(SRSHARP0_DEJ_CTRL + sr_offset[0],
0, 0, 1);
WRITE_VPP_REG_BITS(SRSHARP0_SR3_DRTLPF_EN
+ sr_offset[0], 0, 0, 3);
WRITE_VPP_REG_BITS(SRSHARP0_SR3_DERING_CTRL
+ sr_offset[0], 0, 28, 3);
WRITE_VPP_REG_BITS(SRSHARP1_DEJ_CTRL + sr_offset[1],
0, 0, 1);
WRITE_VPP_REG_BITS(SRSHARP1_SR3_DRTLPF_EN
+ sr_offset[1], 0, 0, 3);
WRITE_VPP_REG_BITS(SRSHARP1_SR3_DERING_CTRL
+ sr_offset[1], 0, 28, 3);
}
/*sr4 drtlpf theta/ debanding en*/
if (is_meson_txlx_cpu()) {
WRITE_VPP_REG_BITS(SRSHARP0_SR3_DRTLPF_EN
+ sr_offset[0], 0, 4, 3);
WRITE_VPP_REG_BITS(SRSHARP0_DB_FLT_CTRL + sr_offset[0],
0, 4, 1);
WRITE_VPP_REG_BITS(SRSHARP0_DB_FLT_CTRL + sr_offset[0],
0, 5, 1);
WRITE_VPP_REG_BITS(SRSHARP0_DB_FLT_CTRL + sr_offset[0],
0, 22, 1);
WRITE_VPP_REG_BITS(SRSHARP0_DB_FLT_CTRL + sr_offset[0],
0, 23, 1);
WRITE_VPP_REG_BITS(SRSHARP1_DB_FLT_CTRL + sr_offset[1],
0, 4, 1);
WRITE_VPP_REG_BITS(SRSHARP1_DB_FLT_CTRL + sr_offset[1],
0, 5, 1);
WRITE_VPP_REG_BITS(SRSHARP1_DB_FLT_CTRL + sr_offset[1],
0, 22, 1);
WRITE_VPP_REG_BITS(SRSHARP1_DB_FLT_CTRL + sr_offset[1],
0, 23, 1);
}
amvecm_wb_enable(false);
vecm_latch_flag |= FLAG_GAMMA_TABLE_DIS;
WRITE_VPP_REG_BITS(VPP_VADJ_CTRL, 0, 0, 1);
}
}
static void amvecm_dither_enable(int enable)
{
switch (enable) {
/*dither enable*/
case 0:/*disable*/
WRITE_VPP_REG_BITS(VPP_VE_DITHER_CTRL, 0, 0, 1);
break;
case 1:/*enable*/
WRITE_VPP_REG_BITS(VPP_GAINOFF_CTRL0, 1, 0, 1);
break;
/*dither round enable*/
case 2:/*disable*/
WRITE_VPP_REG_BITS(VPP_VE_DITHER_CTRL, 0, 1, 1);
break;
case 3:/*enable*/
WRITE_VPP_REG_BITS(VPP_VE_DITHER_CTRL, 1, 1, 1);
break;
default:
break;
}
}
static void amvecm_vpp_mtx_debug(int mtx_sel, int coef_sel)
{
if (mtx_sel & (1 << VPP_MATRIX_1)) {
WRITE_VPP_REG_BITS(VPP_MATRIX_CTRL, 1, 5, 1);
WRITE_VPP_REG_BITS(VPP_MATRIX_CTRL, 1, 8, 3);
mtx_sel_dbg &= ~(1 << VPP_MATRIX_1);
} else if (mtx_sel & (1 << VPP_MATRIX_2)) {
WRITE_VPP_REG_BITS(VPP_MATRIX_CTRL, 1, 0, 1);
WRITE_VPP_REG_BITS(VPP_MATRIX_CTRL, 0, 8, 3);
mtx_sel_dbg &= ~(1 << VPP_MATRIX_2);
} else if (mtx_sel & (1 << VPP_MATRIX_3)) {
WRITE_VPP_REG_BITS(VPP_MATRIX_CTRL, 1, 6, 1);
WRITE_VPP_REG_BITS(VPP_MATRIX_CTRL, 3, 8, 3);
mtx_sel_dbg &= ~(1 << VPP_MATRIX_3);
}
/*coef_sel 1: 10bit yuvl2rgb 2:rgb2yuvl*/
/*coef_sel 3: 12bit yuvl2rgb 4:rgb2yuvl*/
if (coef_sel == 1) {
WRITE_VPP_REG(VPP_MATRIX_COEF00_01, 0x04A80000);
WRITE_VPP_REG(VPP_MATRIX_COEF02_10, 0x072C04A8);
WRITE_VPP_REG(VPP_MATRIX_COEF11_12, 0x1F261DDD);
WRITE_VPP_REG(VPP_MATRIX_COEF20_21, 0x04A80876);
WRITE_VPP_REG(VPP_MATRIX_COEF22, 0x0);
WRITE_VPP_REG(VPP_MATRIX_OFFSET0_1, 0x0);
WRITE_VPP_REG(VPP_MATRIX_OFFSET2, 0x0);
WRITE_VPP_REG(VPP_MATRIX_PRE_OFFSET0_1, 0xfc00e00);
WRITE_VPP_REG(VPP_MATRIX_PRE_OFFSET2, 0x0e00);
WRITE_VPP_REG_BITS(VPP_MATRIX_CLIP, 0, 5, 3);
} else if (coef_sel == 2) {
WRITE_VPP_REG(VPP_MATRIX_COEF00_01, 0x00bb0275);
WRITE_VPP_REG(VPP_MATRIX_COEF02_10, 0x003f1f99);
WRITE_VPP_REG(VPP_MATRIX_COEF11_12, 0x1ea601c2);
WRITE_VPP_REG(VPP_MATRIX_COEF20_21, 0x01c21e67);
WRITE_VPP_REG(VPP_MATRIX_COEF22, 0x00001fd7);
WRITE_VPP_REG(VPP_MATRIX_OFFSET0_1, 0x00400200);
WRITE_VPP_REG(VPP_MATRIX_OFFSET2, 0x00000200);
WRITE_VPP_REG(VPP_MATRIX_PRE_OFFSET0_1, 0x0);
WRITE_VPP_REG(VPP_MATRIX_PRE_OFFSET2, 0x0);
WRITE_VPP_REG_BITS(VPP_MATRIX_CLIP, 0, 5, 3);
} else if (coef_sel == 3) {
WRITE_VPP_REG(VPP_MATRIX_COEF00_01, 0x04A80000);
WRITE_VPP_REG(VPP_MATRIX_COEF02_10, 0x072C04A8);
WRITE_VPP_REG(VPP_MATRIX_COEF11_12, 0x1F261DDD);
WRITE_VPP_REG(VPP_MATRIX_COEF20_21, 0x04A80876);
WRITE_VPP_REG(VPP_MATRIX_COEF22, 0x0);
WRITE_VPP_REG(VPP_MATRIX_OFFSET0_1, 0x8000800);
WRITE_VPP_REG(VPP_MATRIX_OFFSET2, 0x800);
WRITE_VPP_REG(VPP_MATRIX_PRE_OFFSET0_1, 0x7000000);
WRITE_VPP_REG(VPP_MATRIX_PRE_OFFSET2, 0x0000);
WRITE_VPP_REG_BITS(VPP_MATRIX_CLIP, 0, 5, 3);
} else if (coef_sel == 4) {
WRITE_VPP_REG(VPP_MATRIX_COEF00_01, 0x00bb0275);
WRITE_VPP_REG(VPP_MATRIX_COEF02_10, 0x003f1f99);
WRITE_VPP_REG(VPP_MATRIX_COEF11_12, 0x1ea601c2);
WRITE_VPP_REG(VPP_MATRIX_COEF20_21, 0x01c21e67);
WRITE_VPP_REG(VPP_MATRIX_COEF22, 0x00001fd7);
WRITE_VPP_REG(VPP_MATRIX_OFFSET0_1, 0x01000000);
WRITE_VPP_REG(VPP_MATRIX_OFFSET2, 0x00000000);
WRITE_VPP_REG(VPP_MATRIX_PRE_OFFSET0_1, 0x0);
WRITE_VPP_REG(VPP_MATRIX_PRE_OFFSET2, 0x0);
WRITE_VPP_REG_BITS(VPP_MATRIX_CLIP, 0, 5, 3);
}
}
static void vpp_clip_config(unsigned int mode_sel, unsigned int color,
unsigned int color_mode)
{
unsigned int addr_cliptop, addr_clipbot, value_cliptop, value_clipbot;
if (mode_sel == 0) {/*vd1*/
addr_cliptop = VPP_VD1_CLIP_MISC0;
addr_clipbot = VPP_VD1_CLIP_MISC1;
} else if (mode_sel == 1) {/*vd2*/
addr_cliptop = VPP_VD2_CLIP_MISC0;
addr_clipbot = VPP_VD2_CLIP_MISC1;
} else if (mode_sel == 2) {/*xvycc*/
addr_cliptop = VPP_XVYCC_MISC0;
addr_clipbot = VPP_XVYCC_MISC1;
} else if (mode_sel == 3) {/*final clip*/
addr_cliptop = VPP_CLIP_MISC0;
addr_clipbot = VPP_CLIP_MISC1;
} else {
addr_cliptop = mode_sel;
addr_clipbot = mode_sel + 1;
}
if (color == 0) {/*default*/
value_cliptop = 0x3fffffff;
value_clipbot = 0x0;
} else if (color == 1) {/*Blue*/
if (color_mode == 0) {/*yuv*/
value_cliptop = (0x29 << 22) | (0xf0 << 12) |
(0x6e << 2);
value_clipbot = (0x29 << 22) | (0xf0 << 12) |
(0x6e << 2);
} else {/*RGB*/
value_cliptop = 0xFF << 2;
value_clipbot = 0xFF << 2;
}
} else if (color == 2) {/*Black*/
if (color_mode == 0) {/*yuv*/
value_cliptop = (0x10 << 22) | (0x80 << 12) |
(0x80 << 2);
value_clipbot = (0x10 << 22) | (0x80 << 12) |
(0x80 << 2);
} else {
value_cliptop = 0;
value_clipbot = 0;
}
} else {
value_cliptop = color;
value_clipbot = color;
}
WRITE_VPP_REG(addr_cliptop, value_cliptop);
WRITE_VPP_REG(addr_clipbot, value_clipbot);
}
#define MAX_CLIP_VAL ((1<<30)-1)
static ssize_t amvecm_clamp_color_top_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
return sprintf(buf, "0x%08x\n", READ_VPP_REG(VPP_CLIP_MISC0));
}
static ssize_t amvecm_clamp_color_top_store(struct class *cla,
struct class_attribute *attr,
const char *buf, size_t count)
{
size_t r;
uint32_t val;
r = sscanf(buf, "%x\n", &val);
if ((r != 1) || (val > MAX_CLIP_VAL))
return -EINVAL;
WRITE_VPP_REG(VPP_CLIP_MISC0, val);
return count;
}
static ssize_t amvecm_clamp_color_bottom_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
return sprintf(buf, "0x%08x\n", READ_VPP_REG(VPP_CLIP_MISC1));
}
static ssize_t amvecm_clamp_color_bottom_store(struct class *cla,
struct class_attribute *attr,
const char *buf, size_t count)
{
size_t r;
uint32_t val;
r = sscanf(buf, "%x\n", &val);
if ((r != 1) || (val > MAX_CLIP_VAL))
return -EINVAL;
WRITE_VPP_REG(VPP_CLIP_MISC1, val);
return count;
}
#define color_mode_idx 7
static int cm2_hue_array[color_mode_idx][2];
static int cm2_luma_array[color_mode_idx][2];
static int cm2_sat_array[color_mode_idx][2];
static int cm2_hue_by_hs_array[color_mode_idx][2];
static ssize_t amvecm_cm2_hue_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
int i;
int pos = 0;
for (i = 0; i < color_mode_idx; i++)
pos += sprintf(buf + pos, "%d %d %d\n", i,
cm2_hue_array[i][0], cm2_hue_array[i][1]);
return pos;
}
static ssize_t amvecm_cm2_hue_store(struct class *cla,
struct class_attribute *attr,
const char *buf, size_t count)
{
char *buf_orig, *parm[8] = {NULL};
long val = 0;
unsigned int color_mode;
if (!buf)
return count;
buf_orig = kstrdup(buf, GFP_KERNEL);
if (!buf_orig)
return -ENOMEM;
parse_param_amvecm(buf_orig, (char **)&parm);
if (!strncmp(parm[0], "cm2_hue", 7)) {
if (kstrtoul(parm[1], 10, &val) < 0)
goto kfree_buf;
color_mode = val;
if (kstrtol(parm[2], 10, &val) < 0)
goto kfree_buf;
cm2_hue_array[color_mode][0] = val;
if (kstrtoul(parm[3], 10, &val) < 0)
goto kfree_buf;
cm2_hue_array[color_mode][1] = val;
cm2_hue(color_mode, cm2_hue_array[color_mode][0],
cm2_hue_array[color_mode][1]);
pr_info("cm2_hue ok\n");
}
kfree(buf_orig);
return count;
kfree_buf:
kfree(buf_orig);
return -EINVAL;
}
static ssize_t amvecm_cm2_luma_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
int i;
int pos = 0;
for (i = 0; i < color_mode_idx; i++)
pos += sprintf(buf + pos, "%d %d %d\n", i,
cm2_luma_array[i][0], cm2_luma_array[i][1]);
return pos;
}
static ssize_t amvecm_cm2_luma_store(struct class *cla,
struct class_attribute *attr,
const char *buf, size_t count)
{
char *buf_orig, *parm[8] = {NULL};
long val = 0;
unsigned int color_mode;
if (!buf)
return count;
buf_orig = kstrdup(buf, GFP_KERNEL);
if (!buf_orig)
return -ENOMEM;
parse_param_amvecm(buf_orig, (char **)&parm);
if (!strncmp(parm[0], "cm2_luma", 7)) {
if (kstrtoul(parm[1], 10, &val) < 0)
goto kfree_buf;
color_mode = val;
if (kstrtol(parm[2], 10, &val) < 0)
goto kfree_buf;
cm2_luma_array[color_mode][0] = val;
if (kstrtoul(parm[3], 10, &val) < 0)
goto kfree_buf;
cm2_luma_array[color_mode][1] = val;
cm2_luma(color_mode, cm2_luma_array[color_mode][0],
cm2_luma_array[color_mode][1]);
pr_info("cm2_luma ok\n");
}
kfree(buf_orig);
return count;
kfree_buf:
kfree(buf_orig);
return -EINVAL;
}
static ssize_t amvecm_cm2_sat_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
int i;
int pos = 0;
for (i = 0; i < color_mode_idx; i++)
pos += sprintf(buf + pos, "%d %d %d\n", i,
cm2_sat_array[i][0], cm2_sat_array[i][1]);
return pos;
}
static ssize_t amvecm_cm2_sat_store(struct class *cla,
struct class_attribute *attr,
const char *buf, size_t count)
{
char *buf_orig, *parm[8] = {NULL};
long val = 0;
unsigned int color_mode;
if (!buf)
return count;
buf_orig = kstrdup(buf, GFP_KERNEL);
if (!buf_orig)
return -ENOMEM;
parse_param_amvecm(buf_orig, (char **)&parm);
if (!strncmp(parm[0], "cm2_sat", 7)) {
if (kstrtoul(parm[1], 10, &val) < 0)
goto kfree_buf;
color_mode = val;
if (kstrtol(parm[2], 10, &val) < 0)
goto kfree_buf;
cm2_sat_array[color_mode][0] = val;
if (kstrtoul(parm[3], 10, &val) < 0)
goto kfree_buf;
cm2_sat_array[color_mode][1] = val;
cm2_sat(color_mode, cm2_sat_array[color_mode][0],
cm2_sat_array[color_mode][1]);
pr_info("cm2_sat ok\n");
}
kfree(buf_orig);
return count;
kfree_buf:
kfree(buf_orig);
return -EINVAL;
}
static ssize_t amvecm_cm2_hue_by_hs_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
int i;
int pos = 0;
for (i = 0; i < color_mode_idx; i++)
pos += sprintf(buf + pos, "%d %d %d\n", i,
cm2_hue_by_hs_array[i][0], cm2_hue_by_hs_array[i][1]);
return pos;
}
static ssize_t amvecm_cm2_hue_by_hs_store(struct class *cla,
struct class_attribute *attr,
const char *buf, size_t count)
{
char *buf_orig, *parm[8] = {NULL};
long val = 0;
unsigned int color_mode;
if (!buf)
return count;
buf_orig = kstrdup(buf, GFP_KERNEL);
if (!buf_orig)
return -ENOMEM;
parse_param_amvecm(buf_orig, (char **)&parm);
if (!strncmp(parm[0], "cm2_hue_by_hs", 7)) {
if (kstrtoul(parm[1], 10, &val) < 0)
goto kfree_buf;
color_mode = val;
if (kstrtol(parm[2], 10, &val) < 0)
goto kfree_buf;
cm2_hue_by_hs_array[color_mode][0] = val;
if (kstrtoul(parm[3], 10, &val) < 0)
goto kfree_buf;
cm2_hue_by_hs_array[color_mode][1] = val;
cm2_hue_by_hs(color_mode, cm2_hue_by_hs_array[color_mode][0],
cm2_hue_by_hs_array[color_mode][1]);
pr_info("cm2_hue_by_hs ok\n");
}
kfree(buf_orig);
return count;
kfree_buf:
kfree(buf_orig);
return -EINVAL;
}
static void cm_hist_config(unsigned int en, unsigned int mode,
unsigned int wd0, unsigned int wd1,
unsigned int wd2, unsigned int wd3)
{
unsigned int value;
WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, STA_CFG_REG);
value = READ_VPP_REG(VPP_CHROMA_DATA_PORT);
value = (value & (~0xc0000000)) | (en << 30);
WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, STA_CFG_REG);
WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, value);
WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, LUMA_ADJ1_REG);
value = READ_VPP_REG(VPP_CHROMA_DATA_PORT);
value = (value & (~(0x1fff0000))) | (mode << 16);
WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, LUMA_ADJ1_REG);
WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, value);
WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, STA_WIN_XYXY0_REG);
WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, wd0 | (wd1 << 16));
WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, STA_WIN_XYXY1_REG);
WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, wd2 | (wd3 << 16));
}
static void cm_sta_hist_range_thrd(int r, int ro_frame,
int thrd0, int thrd1)
{
unsigned int value0, value1;
if (r) {
WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, STA_SAT_HIST0_REG);
value0 = READ_VPP_REG(VPP_CHROMA_DATA_PORT);
WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, STA_SAT_HIST1_REG);
value1 = READ_VPP_REG(VPP_CHROMA_DATA_PORT);
pr_info("thrd0 = 0x%x, thrd0 = 0x%x\n", value0, value1);
} else {
WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, STA_SAT_HIST0_REG);
WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, thrd0 | (ro_frame << 24));
WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, STA_SAT_HIST1_REG);
WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, thrd1);
}
}
static void cm_luma_bri_con(int r, int brightness, int contrast,
int blk_lel)
{
int value;
if (r) {
WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, LUMA_ADJ0_REG);
value = READ_VPP_REG(VPP_CHROMA_DATA_PORT);
pr_info("contrast = 0x%x, blklel = 0x%x\n",
value & 0xfff, (value >> 12) & 0x3ff);
WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, LUMA_ADJ1_REG);
value = READ_VPP_REG(VPP_CHROMA_DATA_PORT);
pr_info("bright = 0x%x, hist_mode = 0x%x\n",
value & 0x1fff, (value >> 16) & 0x1fff);
} else {
WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, LUMA_ADJ0_REG);
WRITE_VPP_REG(VPP_CHROMA_DATA_PORT,
(blk_lel << 12) | contrast);
WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, LUMA_ADJ1_REG);
value = READ_VPP_REG(VPP_CHROMA_DATA_PORT);
WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, LUMA_ADJ1_REG);
WRITE_VPP_REG(VPP_CHROMA_DATA_PORT,
(value & (~(0x1fff))) | brightness);
}
}
static void get_cm_hist(enum cm_hist_e hist_sel)
{
unsigned int *hist;
unsigned int i;
hist = kmalloc(64 * sizeof(unsigned int), GFP_KERNEL);
memset(hist, 0, 64 * sizeof(unsigned int));
switch (hist_sel) {
case CM_HUE_HIST:
for (i = 0; i < 64; i++) {
WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT,
RO_CM_HUE_HIST_BIN0 + i);
hist[i] = READ_VPP_REG(VPP_CHROMA_DATA_PORT);
pr_info("hist[%d] = 0x%8x\n", i, hist[i]);
}
break;
case CM_SAT_HIST:
for (i = 0; i < 64; i++) {
WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT,
RO_CM_SAT_HIST_BIN0 + i);
hist[i] = READ_VPP_REG(VPP_CHROMA_DATA_PORT);
pr_info("hist[%d] = 0x%8x\n", i, hist[i]);
}
break;
default:
break;
}
kfree(hist);
}
static void cm_init_config(void)
{
WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, XVYCC_YSCP_REG);
WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, 0x3ff0000);
WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, XVYCC_USCP_REG);
WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, 0x3ff0000);
WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, XVYCC_VSCP_REG);
WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, 0x3ff0000);
WRITE_VPP_REG(VPP_CHROMA_ADDR_PORT, LUMA_ADJ0_REG);
WRITE_VPP_REG(VPP_CHROMA_DATA_PORT, 0x40400);
}
static const char *amvecm_debug_usage_str = {
"Usage:\n"
"echo vpp_size > /sys/class/amvecm/debug; get vpp size config\n"
"echo wb enable > /sys/class/amvecm/debug\n"
"echo wb disable > /sys/class/amvecm/debug\n"
"echo gamma enable > /sys/class/amvecm/debug\n"
"echo gamma disable > /sys/class/amvecm/debug\n"
"echo sr peaking_en > /sys/class/amvecm/debug\n"
"echo sr peaking_dis > /sys/class/amvecm/debug\n"
"echo sr lcti_en > /sys/class/amvecm/debug\n"
"echo sr lcti_dis > /sys/class/amvecm/debug\n"
"echo sr dejaggy_en > /sys/class/amvecm/debug\n"
"echo sr dejaggy_dis > /sys/class/amvecm/debug\n"
"echo sr dering_en > /sys/class/amvecm/debug\n"
"echo sr dering_dis > /sys/class/amvecm/debug\n"
"echo sr derec_en > /sys/class/amvecm/debug\n"
"echo sr derec_dis > /sys/class/amvecm/debug\n"
"echo sr theta_en > /sys/class/amvecm/debug\n"
"echo sr theta_dis > /sys/class/amvecm/debug\n"
"echo sr deband_en > /sys/class/amvecm/debug\n"
"echo sr deband_dis > /sys/class/amvecm/debug\n"
"echo cm enable > /sys/class/amvecm/debug\n"
"echo cm disable > /sys/class/amvecm/debug\n"
"echo dnlp enable > /sys/class/amvecm/debug\n"
"echo dnlp disable > /sys/class/amvecm/debug\n"
"echo vpp_pq enable > /sys/class/amvecm/debug\n"
"echo vpp_pq disable > /sys/class/amvecm/debug\n"
"echo keystone_process > /sys/class/amvecm/debug; keystone init config\n"
"echo keystone_status > /sys/class/amvecm/debug; keystone parameter status\n"
"echo keystone_regs > /sys/class/amvecm/debug; keystone regs value\n"
"echo keystone_config param1(D) param2(D) > /sys/class/amvecm/debug; keystone param config\n"
"echo vpp_mtx xvycc_10 rgb2yuv > /sys/class/amvecm/debug; 10bit xvycc mtx\n"
"echo vpp_mtx xvycc_10 yuv2rgb > /sys/class/amvecm/debug; 10bit xvycc mtx\n"
"echo vpp_mtx post_10 rgb2yuv > /sys/class/amvecm/debug; 10bit post mtx\n"
"echo vpp_mtx post_10 yuv2rgb > /sys/class/amvecm/debug; 10bit post mtx\n"
"echo vpp_mtx vd1_10 rgb2yuv > /sys/class/amvecm/debug; 10bit vd1 mtx\n"
"echo vpp_mtx vd1_10 yuv2rgb > /sys/class/amvecm/debug; 10bit vd1 mtx\n"
"echo vpp_mtx xvycc_12 rgb2yuv > /sys/class/amvecm/debug; 12bit xvycc mtx\n"
"echo vpp_mtx xvycc_12 yuv2rgb > /sys/class/amvecm/debug; 12bit xvycc mtx\n"
"echo vpp_mtx post_12 rgb2yuv > /sys/class/amvecm/debug; 12bit post mtx\n"
"echo vpp_mtx post_12 yuv2rgb > /sys/class/amvecm/debug; 12bit post mtx\n"
"echo vpp_mtx vd1_12 rgb2yuv > /sys/class/amvecm/debug; 12bit vd1 mtx\n"
"echo vpp_mtx vd1_12 yuv2rgb > /sys/class/amvecm/debug; 12bit vd1 mtx\n"
"echo bitdepth 10/12/other-num > /sys/class/amvecm/debug; config data path\n"
"echo datapath_config param1(D) param2(D) > /sys/class/amvecm/debug; config data path\n"
"echo datapath_status > /sys/class/amvecm/debug; data path status\n"
"echo clip_config 0/1/2/.. 0/1/... 0/1 > /sys/class/amvecm/debug; config clip\n"
};
static ssize_t amvecm_debug_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
return sprintf(buf, "%s\n", amvecm_debug_usage_str);
}
static ssize_t amvecm_debug_store(struct class *cla,
struct class_attribute *attr,
const char *buf, size_t count)
{
char *buf_orig, *parm[8] = {NULL};
long val = 0;
unsigned int mode_sel, color, color_mode, i;
if (!buf)
return count;
buf_orig = kstrdup(buf, GFP_KERNEL);
parse_param_amvecm(buf_orig, (char **)&parm);
if (!strncmp(parm[0], "vpp_size", 8))
dump_vpp_size_info();
else if (!strncmp(parm[0], "vpp_state", 9))
pr_info("amvecm driver version : %s\n", AMVECM_VER);
else if (!strncmp(parm[0], "wb", 2)) {
if (!strncmp(parm[1], "enable", 6)) {
amvecm_wb_enable(1);
pr_info("enable wb\n");
} else if (!strncmp(parm[1], "disable", 7)) {
amvecm_wb_enable(0);
pr_info("disable wb\n");
}
} else if (!strncmp(parm[0], "gamma", 5)) {
if (!strncmp(parm[1], "enable", 6)) {
vecm_latch_flag |= FLAG_GAMMA_TABLE_EN; /* gamma off */
pr_info("enable gamma\n");
} else if (!strncmp(parm[1], "disable", 7)) {
vecm_latch_flag |= FLAG_GAMMA_TABLE_DIS;/* gamma off */
pr_info("disable gamma\n");
}
} else if (!strncmp(parm[0], "sr", 2)) {
if (!strncmp(parm[1], "peaking_en", 10)) {
amvecm_sharpness_enable(0);
pr_info("enable peaking\n");
} else if (!strncmp(parm[1], "peaking_dis", 11)) {
amvecm_sharpness_enable(1);
pr_info("disable peaking\n");
} else if (!strncmp(parm[1], "lcti_en", 7)) {
amvecm_sharpness_enable(2);
pr_info("enable lti cti\n");
} else if (!strncmp(parm[1], "lcti_dis", 8)) {
amvecm_sharpness_enable(3);
pr_info("disable lti cti\n");
} else if (!strncmp(parm[1], "theta_en", 8)) {
amvecm_sharpness_enable(4);
pr_info("SR4 enable drtlpf theta\n");
} else if (!strncmp(parm[1], "theta_dis", 9)) {
amvecm_sharpness_enable(5);
pr_info("SR4 disable drtlpf theta\n");
} else if (!strncmp(parm[1], "deband_en", 9)) {
amvecm_sharpness_enable(6);
pr_info("SR4 enable debanding\n");
} else if (!strncmp(parm[1], "deband_dis", 10)) {
amvecm_sharpness_enable(7);
pr_info("SR4 disable debanding\n");
} else if (!strncmp(parm[1], "dejaggy_en", 10)) {
amvecm_sharpness_enable(8);
pr_info("SR3 enable dejaggy\n");
} else if (!strncmp(parm[1], "dejaggy_dis", 11)) {
amvecm_sharpness_enable(9);
pr_info("SR3 disable dejaggy\n");
} else if (!strncmp(parm[1], "dering_en", 9)) {
amvecm_sharpness_enable(10);
pr_info("SR3 enable dering\n");
} else if (!strncmp(parm[1], "dering_dis", 10)) {
amvecm_sharpness_enable(11);
pr_info("SR3 disable dering\n");
} else if (!strncmp(parm[1], "drlpf_en", 8)) {
amvecm_sharpness_enable(12);
pr_info("SR3 enable drlpf\n");
} else if (!strncmp(parm[1], "drlpf_dis", 9)) {
amvecm_sharpness_enable(13);
pr_info("SR3 disable drlpf\n");
} else if (!strncmp(parm[1], "enable", 6)) {
amvecm_sharpness_enable(0);
amvecm_sharpness_enable(2);
amvecm_sharpness_enable(4);
amvecm_sharpness_enable(6);
amvecm_sharpness_enable(8);
amvecm_sharpness_enable(10);
amvecm_sharpness_enable(12);
pr_info("SR enable\n");
} else if (!strncmp(parm[1], "disable", 7)) {
amvecm_sharpness_enable(1);
amvecm_sharpness_enable(3);
amvecm_sharpness_enable(5);
amvecm_sharpness_enable(7);
amvecm_sharpness_enable(9);
amvecm_sharpness_enable(11);
amvecm_sharpness_enable(13);
pr_info("SR disable\n");
}
} else if (!strcmp(parm[0], "cm")) {
if (!strncmp(parm[1], "enable", 6)) {
amcm_enable();
pr_info("enable cm\n");
} else if (!strncmp(parm[1], "disable", 7)) {
amcm_disable();
pr_info("disable cm\n");
}
} else if (!strncmp(parm[0], "dnlp", 4)) {
if (!strncmp(parm[1], "enable", 6)) {
ve_enable_dnlp();
pr_info("enable dnlp\n");
} else if (!strncmp(parm[1], "disable", 7)) {
ve_disable_dnlp();
pr_info("disable dnlp\n");
}
} else if (!strncmp(parm[0], "vpp_pq", 6)) {
if (!strncmp(parm[1], "enable", 6)) {
amvecm_pq_enable(1);
pr_info("enable vpp_pq\n");
} else if (!strncmp(parm[1], "disable", 7)) {
amvecm_pq_enable(0);
pr_info("disable vpp_pq\n");
}
} else if (!strncmp(parm[0], "vpp_mtx", 7)) {
if (!strncmp(parm[1], "vd1_10", 6)) {
mtx_sel_dbg |= 1 << VPP_MATRIX_1;
if (!strncmp(parm[2], "yuv2rgb", 7)) {
amvecm_vpp_mtx_debug(mtx_sel_dbg, 1);
pr_info("10bit vd1 mtx yuv2rgb\n");
} else if (!strncmp(parm[2], "rgb2yuv", 7)) {
amvecm_vpp_mtx_debug(mtx_sel_dbg, 2);
pr_info("10bit vd1 mtx rgb2yuv\n");
}
} else if (!strncmp(parm[1], "post_10", 7)) {
mtx_sel_dbg |= 1 << VPP_MATRIX_2;
if (!strncmp(parm[2], "yuv2rgb", 7)) {
amvecm_vpp_mtx_debug(mtx_sel_dbg, 1);
pr_info("10bit post mtx yuv2rgb\n");
} else if (!strncmp(parm[2], "rgb2yuv", 7)) {
amvecm_vpp_mtx_debug(mtx_sel_dbg, 2);
pr_info("10bit post mtx rgb2yuv\n");
}
} else if (!strncmp(parm[1], "xvycc_10", 8)) {
mtx_sel_dbg |= 1 << VPP_MATRIX_3;
if (!strncmp(parm[2], "yuv2rgb", 7)) {
amvecm_vpp_mtx_debug(mtx_sel_dbg, 1);
pr_info("10bit xvycc mtx yuv2rgb\n");
} else if (!strncmp(parm[2], "rgb2yuv", 7)) {
amvecm_vpp_mtx_debug(mtx_sel_dbg, 2);
pr_info("10bit xvycc mtx rgb2yuv\n");
}
} else if (!strncmp(parm[1], "vd1_12", 6)) {
mtx_sel_dbg |= 1 << VPP_MATRIX_1;
if (!strncmp(parm[2], "yuv2rgb", 7)) {
amvecm_vpp_mtx_debug(mtx_sel_dbg, 3);
pr_info("1wbit vd1 mtx yuv2rgb\n");
} else if (!strncmp(parm[2], "rgb2yuv", 7)) {
amvecm_vpp_mtx_debug(mtx_sel_dbg, 4);
pr_info("1wbit vd1 mtx rgb2yuv\n");
}
} else if (!strncmp(parm[1], "post_12", 7)) {
mtx_sel_dbg |= 1 << VPP_MATRIX_2;
if (!strncmp(parm[2], "yuv2rgb", 7)) {
amvecm_vpp_mtx_debug(mtx_sel_dbg, 3);
pr_info("1wbit post mtx yuv2rgb\n");
} else if (!strncmp(parm[2], "rgb2yuv", 7)) {
amvecm_vpp_mtx_debug(mtx_sel_dbg, 4);
pr_info("1wbit post mtx rgb2yuv\n");
}
} else if (!strncmp(parm[1], "xvycc_12", 8)) {
mtx_sel_dbg |= 1 << VPP_MATRIX_3;
if (!strncmp(parm[2], "yuv2rgb", 7)) {
amvecm_vpp_mtx_debug(mtx_sel_dbg, 3);
pr_info("1wbit xvycc mtx yuv2rgb\n");
} else if (!strncmp(parm[2], "rgb2yuv", 7)) {
amvecm_vpp_mtx_debug(mtx_sel_dbg, 4);
pr_info("1wbit xvycc mtx rgb2yuv\n");
}
}
} else if (!strncmp(parm[0], "ve_dith", 7)) {
if (!strncmp(parm[1], "enable", 6)) {
amvecm_dither_enable(1);
pr_info("enable ve dither\n");
} else if (!strncmp(parm[1], "disable", 7)) {
amvecm_dither_enable(0);
pr_info("disable ve dither\n");
} else if (!strncmp(parm[1], "rd_en", 5)) {
amvecm_dither_enable(3);
pr_info("enable ve round dither\n");
} else if (!strncmp(parm[1], "rd_dis", 6)) {
amvecm_dither_enable(2);
pr_info("disable ve round dither\n");
}
} else if (!strcmp(parm[0], "keystone_process")) {
keystone_correction_process();
pr_info("keystone_correction_process done!\n");
} else if (!strcmp(parm[0], "keystone_status")) {
keystone_correction_status();
} else if (!strcmp(parm[0], "keystone_regs")) {
keystone_correction_regs();
} else if (!strcmp(parm[0], "keystone_config")) {
enum vks_param_e vks_param;
unsigned int vks_param_val;
if (!parm[2]) {
pr_info("misss param\n");
goto free_buf;
}
if (kstrtoul(parm[1], 10, &val) < 0)
goto free_buf;
vks_param = val;
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
vks_param_val = val;
keystone_correction_config(vks_param, vks_param_val);
} else if (!strcmp(parm[0], "bitdepth")) {
unsigned int bitdepth;
if (!parm[1]) {
pr_info("misss param1\n");
goto free_buf;
}
if (kstrtoul(parm[1], 10, &val) < 0)
goto free_buf;
bitdepth = val;
vpp_bitdepth_config(bitdepth);
} else if (!strcmp(parm[0], "datapath_config")) {
unsigned int node, param1, param2;
if (!parm[1]) {
pr_info("misss param1\n");
goto free_buf;
}
if (kstrtoul(parm[1], 10, &val) < 0)
goto free_buf;
node = val;
if (!parm[2]) {
pr_info("misss param2\n");
goto free_buf;
}
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
param1 = val;
if (!parm[3]) {
pr_info("misss param3,default is 0\n");
param2 = 0;
}
if (kstrtoul(parm[3], 10, &val) < 0)
goto free_buf;
param2 = val;
vpp_datapath_config(node, param1, param2);
} else if (!strcmp(parm[0], "datapath_status")) {
vpp_datapath_status();
} else if (!strcmp(parm[0], "clip_config")) {
if (parm[1]) {
if (kstrtoul(parm[1], 16, &val) < 0)
goto free_buf;
mode_sel = val;
} else
mode_sel = 0;
if (parm[2]) {
if (kstrtoul(parm[2], 16, &val) < 0)
goto free_buf;
color = val;
} else
color = 0;
if (parm[3]) {
if (kstrtoul(parm[3], 16, &val) < 0)
goto free_buf;
color_mode = val;
} else
color_mode = 0;
vpp_clip_config(mode_sel, color, color_mode);
pr_info("vpp_clip_config done!\n");
} else if (!strcmp(parm[0], "3dlut_set")) {
int *PLut3D;
unsigned int bitdepth;
PLut3D = kmalloc(14739 * sizeof(int), GFP_KERNEL);
if (PLut3D == NULL) {
kfree(PLut3D);
goto free_buf;
}
if (parm[1]) {
if (kstrtoul(parm[1], 10, &val) < 0) {
kfree(PLut3D);
goto free_buf;
}
bitdepth = val;
} else {
pr_info("unsupport cmd\n");
kfree(PLut3D);
goto free_buf;
}
vpp_lut3d_table_init(PLut3D, bitdepth);
if (!strcmp(parm[2], "enable"))
vpp_set_lut3d(1, 1, PLut3D, 1);
else if (!strcmp(parm[2], "disable"))
vpp_set_lut3d(0, 0, PLut3D, 0);
else
pr_info("unsupprt cmd!\n");
kfree(PLut3D);
} else if (!strcmp(parm[0], "3dlut_dump")) {
if (!strcmp(parm[1], "init_tab"))
dump_plut3d_table();
else if (!strcmp(parm[1], "reg_tab"))
dump_plut3d_reg_table();
else
pr_info("unsupprt cmd!\n");
} else if (!strcmp(parm[0], "cm_hist")) {
if (!parm[1]) {
pr_info("miss param1\n");
goto free_buf;
}
if (!strcmp(parm[1], "hue"))
get_cm_hist(CM_HUE_HIST);
else if (!strcmp(parm[1], "sat"))
get_cm_hist(CM_SAT_HIST);
else
pr_info("unsupport cmd\n");
} else if (!strcmp(parm[0], "cm_hist_config")) {
unsigned int en, mode, wd0, wd1, wd2, wd3;
if (!parm[6]) {
pr_info("miss param1\n");
goto free_buf;
}
if (kstrtoul(parm[1], 10, &val) < 0)
goto free_buf;
en = val;
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
mode = val;
if (kstrtoul(parm[3], 10, &val) < 0)
goto free_buf;
wd0 = val;
if (kstrtoul(parm[4], 10, &val) < 0)
goto free_buf;
wd1 = val;
if (kstrtoul(parm[5], 10, &val) < 0)
goto free_buf;
wd2 = val;
if (kstrtoul(parm[6], 10, &val) < 0)
goto free_buf;
wd3 = val;
cm_hist_config(en, mode, wd0, wd1, wd2, wd3);
pr_info("cm hist config success\n");
} else if (!strcmp(parm[0], "cm_hist_thrd")) {
int rd, ro_frame, thrd0, thrd1;
if (parm[1]) {
if (kstrtoul(parm[1], 16, &val) < 0)
goto free_buf;
rd = val;
} else {
pr_info("unsupport cmd\n");
goto free_buf;
}
if (rd)
cm_sta_hist_range_thrd(rd, 0, 0, 0);
else {
if (!parm[3]) {
pr_info("miss param1\n");
goto free_buf;
}
if (kstrtoul(parm[1], 16, &val) < 0)
goto free_buf;
ro_frame = val;
if (kstrtoul(parm[2], 16, &val) < 0)
goto free_buf;
thrd0 = val;
if (kstrtoul(parm[3], 16, &val) < 0)
goto free_buf;
thrd1 = val;
cm_sta_hist_range_thrd(rd, ro_frame, thrd0, thrd1);
pr_info("cm hist thrd set success\n");
}
} else if (!strcmp(parm[0], "cm_bri_con")) {
int rd, bri, con, blk_lel;
if (parm[1]) {
if (kstrtoul(parm[1], 16, &val) < 0)
goto free_buf;
rd = val;
} else {
pr_info("unsupport cmd\n");
goto free_buf;
}
if (rd)
cm_luma_bri_con(rd, 0, 0, 0);
else {
if (!parm[3]) {
pr_info("miss param1\n");
goto free_buf;
}
if (kstrtoul(parm[1], 16, &val) < 0)
goto free_buf;
bri = val;
if (kstrtoul(parm[2], 16, &val) < 0)
goto free_buf;
con = val;
if (kstrtoul(parm[3], 16, &val) < 0)
goto free_buf;
blk_lel = val;
cm_luma_bri_con(rd, bri, con, blk_lel);
pr_info("cm hist bri_con set success\n");
}
} else if (!strcmp(parm[0], "dump_overscan_table")) {
for (i = 0; i < TIMING_MAX; i++) {
pr_info("*****dump overscan_tab[%d]*****\n", i);
pr_info("hs:%d, he:%d, vs:%d, ve:%d, screen_mode:%d, afd:%d, flag:%d.\n",
overscan_table[i].hs, overscan_table[i].he,
overscan_table[i].vs, overscan_table[i].ve,
overscan_table[i].screen_mode,
overscan_table[i].afd_enable,
overscan_table[i].load_flag);
}
} else
pr_info("unsupport cmd\n");
kfree(buf_orig);
return count;
free_buf:
kfree(buf_orig);
return -EINVAL;
}
static const char *amvecm_reg_usage_str = {
"Usage:\n"
"echo rv addr(H) > /sys/class/amvecm/reg;\n"
"echo rc addr(H) > /sys/class/amvecm/reg;\n"
"echo rh addr(H) > /sys/class/amvecm/reg; read hiu reg\n"
"echo wv addr(H) value(H) > /sys/class/amvecm/reg; write vpu reg\n"
"echo wc addr(H) value(H) > /sys/class/amvecm/reg; write cbus reg\n"
"echo wh addr(H) value(H) > /sys/class/amvecm/reg; write hiu reg\n"
"echo dv|c|h addr(H) num > /sys/class/amvecm/reg; dump reg from addr\n"
};
static ssize_t amvecm_reg_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
return sprintf(buf, "%s\n", amvecm_reg_usage_str);
}
static ssize_t amvecm_reg_store(struct class *cla,
struct class_attribute *attr,
const char *buf, size_t count)
{
char *buf_orig, *parm[8] = {NULL};
long val = 0;
unsigned int reg_addr, reg_val, i;
if (!buf)
return count;
buf_orig = kstrdup(buf, GFP_KERNEL);
parse_param_amvecm(buf_orig, (char **)&parm);
if (!strcmp(parm[0], "rv")) {
if (kstrtoul(parm[1], 16, &val) < 0) {
kfree(buf_orig);
return -EINVAL;
}
reg_addr = val;
reg_val = READ_VPP_REG(reg_addr);
pr_info("VPU[0x%04x]=0x%08x\n", reg_addr, reg_val);
} else if (!strcmp(parm[0], "rc")) {
if (kstrtoul(parm[1], 16, &val) < 0) {
kfree(buf_orig);
return -EINVAL;
}
reg_addr = val;
reg_val = aml_read_cbus(reg_addr);
pr_info("CBUS[0x%04x]=0x%08x\n", reg_addr, reg_val);
} else if (!strcmp(parm[0], "rh")) {
if (kstrtoul(parm[1], 16, &val) < 0) {
kfree(buf_orig);
return -EINVAL;
}
reg_addr = val;
amvecm_hiu_reg_read(reg_addr, &reg_val);
pr_info("HIU[0x%04x]=0x%08x\n", reg_addr, reg_val);
} else if (!strcmp(parm[0], "wv")) {
if (kstrtoul(parm[1], 16, &val) < 0) {
kfree(buf_orig);
return -EINVAL;
}
reg_addr = val;
if (kstrtoul(parm[2], 16, &val) < 0) {
kfree(buf_orig);
return -EINVAL;
}
reg_val = val;
WRITE_VPP_REG(reg_addr, reg_val);
} else if (!strcmp(parm[0], "wc")) {
if (kstrtoul(parm[1], 16, &val) < 0) {
kfree(buf_orig);
return -EINVAL;
}
reg_addr = val;
if (kstrtoul(parm[2], 16, &val) < 0) {
kfree(buf_orig);
return -EINVAL;
}
reg_val = val;
aml_write_cbus(reg_addr, reg_val);
} else if (!strcmp(parm[0], "wh")) {
if (kstrtoul(parm[1], 16, &val) < 0) {
kfree(buf_orig);
return -EINVAL;
}
reg_addr = val;
if (kstrtoul(parm[2], 16, &val) < 0) {
kfree(buf_orig);
return -EINVAL;
}
reg_val = val;
amvecm_hiu_reg_write(reg_addr, reg_val);
} else if (parm[0][0] == 'd') {
if (kstrtoul(parm[1], 16, &val) < 0) {
kfree(buf_orig);
return -EINVAL;
}
reg_addr = val;
if (kstrtoul(parm[2], 16, &val) < 0) {
kfree(buf_orig);
return -EINVAL;
}
for (i = 0; i < val; i++) {
if (parm[0][1] == 'v')
reg_val = READ_VPP_REG(reg_addr+i);
else if (parm[0][1] == 'c')
reg_val = aml_read_cbus(reg_addr+i);
else if (parm[0][1] == 'h')
amvecm_hiu_reg_read((reg_addr+i),
&reg_val);
else {
pr_info("unsupprt cmd!\n");
kfree(buf_orig);
return -EINVAL;
}
pr_info("REG[0x%04x]=0x%08x\n", (reg_addr+i), reg_val);
}
} else
pr_info("unsupprt cmd!\n");
kfree(buf_orig);
return count;
}
static ssize_t amvecm_get_hdr_type_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
return sprintf(buf, "%x\n", hdr_source_type);
}
static ssize_t amvecm_get_hdr_type_store(struct class *cls,
struct class_attribute *attr,
const char *buffer, size_t count)
{
return count;
}
static void lc_rd_reg(enum lc_reg_lut_e reg_sel, int data_type)
{
int i, tmp, tmp1, tmp2;
int lut_data[63] = {0};
char *stemp = NULL;
if (data_type == 1)
goto dump_as_string;
switch (reg_sel) {
case SATUR_LUT:
for (i = 0; i < 31 ; i++) {
tmp = READ_VPP_REG(SRSHARP1_LC_SAT_LUT_0_1 + i);
tmp1 = (tmp >> 16) & 0xfff;
tmp2 = tmp & 0xfff;
pr_info("reg_lc_satur_lut[%d] =%4d.\n",
2*i, tmp1);
pr_info("reg_lc_satur_lut[%d] =%4d.\n",
2*i + 1, tmp2);
}
tmp = READ_VPP_REG(SRSHARP1_LC_SAT_LUT_62);
pr_info("reg_lc_satur_lut[62] =%4d.\n",
tmp & 0xfff);
break;
case YMINVAL_LMT:
for (i = 0; i < 6 ; i++) {
tmp = READ_VPP_REG(LC_CURVE_YMINVAL_LMT_0_1 + i);
tmp1 = (tmp >> 16) & 0x3ff;
tmp2 = tmp & 0x3ff;
pr_info("reg_yminVal_lmt[%d] =%4d.\n",
2*i, tmp1);
pr_info("reg_yminVal_lmt[%d] =%4d.\n",
2*i + 1, tmp2);
}
break;
case YPKBV_YMAXVAL_LMT:
for (i = 0; i < 6 ; i++) {
tmp = READ_VPP_REG(LC_CURVE_YPKBV_YMAXVAL_LMT_0_1 + i);
tmp1 = (tmp >> 16) & 0x3ff;
tmp2 = tmp & 0x3ff;
pr_info("reg_lc_ypkBV_ymaxVal_lmt[%d] =%4d.\n",
2*i, tmp1);
pr_info("reg_lc_ypkBV_ymaxVal_lmt[%d] =%4d.\n",
2*i + 1, tmp2);
}
break;
case YPKBV_RAT:
tmp = READ_VPP_REG(LC_CURVE_YPKBV_RAT);
pr_info("reg_lc_ypkBV_ratio[0] =%4d.\n",
(tmp>>24) & 0xff);
pr_info("reg_lc_ypkBV_ratio[1] =%4d.\n",
(tmp>>16) & 0xff);
pr_info("reg_lc_ypkBV_ratio[2] =%4d.\n",
(tmp>>8) & 0xff);
pr_info("reg_lc_ypkBV_ratio[3] =%4d.\n",
tmp & 0xff);
break;
case YPKBV_SLP_LMT:
tmp = READ_VPP_REG(LC_CURVE_YPKBV_SLP_LMT);
pr_info("reg_lc_ypkBV_slope_lmt[0] =%4d.\n",
(tmp>>8) & 0xff);
pr_info("reg_lc_ypkBV_slope_lmt[1] =%4d.\n",
tmp & 0xff);
break;
case CNTST_LMT:
tmp = READ_VPP_REG(LC_CURVE_CONTRAST__LMT_LH);
pr_info("reg_lc_cntstlmt_low[0] =%4d.\n",
(tmp>>24) & 0xff);
pr_info("reg_lc_cntstlmt_high[0] =%4d.\n",
(tmp>>16) & 0xff);
pr_info("reg_lc_cntstlmt_low[1] =%4d.\n",
(tmp>>8) & 0xff);
pr_info("reg_lc_cntstlmt_high[1] =%4d.\n",
tmp & 0xff);
break;
default:
break;
}
return;
dump_as_string:
stemp = kzalloc(300, GFP_KERNEL);
if (!stemp)
return;
switch (reg_sel) {
case SATUR_LUT:
for (i = 0; i < 31 ; i++) {
tmp = READ_VPP_REG(SRSHARP1_LC_SAT_LUT_0_1 + i);
tmp1 = (tmp >> 16) & 0xfff;
tmp2 = tmp & 0xfff;
lut_data[2*i] = tmp1;
lut_data[2*i + 1] = tmp2;
}
tmp = READ_VPP_REG(SRSHARP1_LC_SAT_LUT_62);
lut_data[62] = tmp & 0xfff;
for (i = 0; i < 63 ; i++)
d_convert_str(lut_data[i],
i, stemp, 4, 10);
pr_info("%s\n", stemp);
break;
case YMINVAL_LMT:
for (i = 0; i < 6 ; i++) {
tmp = READ_VPP_REG(LC_CURVE_YMINVAL_LMT_0_1 + i);
tmp1 = (tmp >> 16) & 0x3ff;
tmp2 = tmp & 0x3ff;
lut_data[2*i] = tmp1;
lut_data[2*i + 1] = tmp2;
}
for (i = 0; i < 12 ; i++)
d_convert_str(lut_data[i],
i, stemp, 4, 10);
pr_info("%s\n", stemp);
break;
case YPKBV_YMAXVAL_LMT:
for (i = 0; i < 6 ; i++) {
tmp = READ_VPP_REG(LC_CURVE_YPKBV_YMAXVAL_LMT_0_1 + i);
tmp1 = (tmp >> 16) & 0x3ff;
tmp2 = tmp & 0x3ff;
lut_data[2*i] = tmp1;
lut_data[2*i + 1] = tmp2;
}
for (i = 0; i < 12 ; i++)
d_convert_str(lut_data[i],
i, stemp, 4, 10);
pr_info("%s\n", stemp);
break;
case YPKBV_RAT:
tmp = READ_VPP_REG(LC_CURVE_YPKBV_RAT);
lut_data[0] = (tmp>>24) & 0xff;
lut_data[1] = (tmp>>16) & 0xff;
lut_data[2] = (tmp>>8) & 0xff;
lut_data[3] = tmp & 0xff;
for (i = 0; i < 4 ; i++)
d_convert_str(lut_data[i],
i, stemp, 4, 10);
pr_info("%s\n", stemp);
break;
default:
break;
}
kfree(stemp);
return;
}
static void lc_wr_reg(int *p, enum lc_reg_lut_e reg_sel)
{
int i, tmp, tmp1, tmp2;
switch (reg_sel) {
case SATUR_LUT:
for (i = 0; i < 31 ; i++) {
tmp1 = *(p + 2*i);
tmp2 = *(p + 2*i + 1);
tmp = ((tmp1 & 0xfff)<<16) | (tmp2 & 0xfff);
WRITE_VPP_REG(SRSHARP1_LC_SAT_LUT_0_1 + i, tmp);
}
tmp = (*(p+62)) & 0xfff;
WRITE_VPP_REG(SRSHARP1_LC_SAT_LUT_62, tmp);
break;
case YMINVAL_LMT:
for (i = 0; i < 6 ; i++) {
tmp1 = *(p + 2*i);
tmp2 = *(p + 2*i + 1);
tmp = ((tmp1&0x3ff) << 16) | (tmp2 & 0x3ff);
WRITE_VPP_REG(LC_CURVE_YMINVAL_LMT_0_1 + i, tmp);
}
break;
case YPKBV_YMAXVAL_LMT:
for (i = 0; i < 6 ; i++) {
tmp1 = *(p + 2*i);
tmp2 = *(p + 2*i + 1);
tmp = ((tmp1&0x3ff) << 16) | (tmp2 & 0x3ff);
WRITE_VPP_REG(LC_CURVE_YPKBV_YMAXVAL_LMT_0_1 + i, tmp);
}
break;
case YPKBV_RAT:
tmp = (*p & 0xff) << 24 | (*(p+1) & 0xff) << 16 |
(*(p+2) & 0xff) << 8 | (*(p+3) & 0xff);
WRITE_VPP_REG(LC_CURVE_YPKBV_RAT, tmp);
break;
case YPKBV_SLP_LMT:
tmp = (*p & 0xff) << 8 | (*(p+1) & 0xff);
WRITE_VPP_REG(LC_CURVE_YPKBV_SLP_LMT, tmp);
break;
case CNTST_LMT:
tmp = (*p & 0xff) << 24 | (*(p+1) & 0xff) << 16 |
(*(p+2) & 0xff) << 8 | (*(p+3) & 0xff);
WRITE_VPP_REG(LC_CURVE_CONTRAST__LMT_LH, tmp);
break;
default:
break;
}
}
unsigned int lc_saturation_curv[63];
unsigned int lc_yminval_lmt_curv[12];
unsigned int lc_ypkbv_ymaxval_lmt_curv[12];
unsigned int lc_ypkbv_ratio_curv[4];
void lc_load_curve(struct ve_lc_curve_parm_s *p)
{
unsigned int i;
/*load lc parms*/
lc_alg_parm.dbg_parm0 = p->param[lc_dbg_parm0];
lc_alg_parm.dbg_parm1 = p->param[lc_dbg_parm1];
lc_alg_parm.dbg_parm2 = p->param[lc_dbg_parm2];
lc_alg_parm.dbg_parm3 = p->param[lc_dbg_parm3];
lc_alg_parm.dbg_parm4 = p->param[lc_dbg_parm4];
/*load lc curve*/
for (i = 0; i < 63; i++)
lc_saturation_curv[i] = p->ve_lc_saturation[i];
for (i = 0; i < 12; i++) {
lc_yminval_lmt_curv[i] =
p->ve_lc_yminval_lmt[i];
lc_ypkbv_ymaxval_lmt_curv[i] =
p->ve_lc_ypkbv_ymaxval_lmt[i];
}
for (i = 0; i < 4; i++)
lc_ypkbv_ratio_curv[i] = p->ve_lc_ypkbv_ratio[i];
/*load lc_staturation curve*/
lc_wr_reg(lc_saturation_curv, 0x1);
/*load lc_yminval_lmt*/
lc_wr_reg(lc_yminval_lmt_curv, 0x2);
/*load lc_ypkbv_ymaxval_lmt*/
lc_wr_reg(lc_ypkbv_ymaxval_lmt_curv, 0x4);
/*load lc_ypkbV_ratio*/
lc_wr_reg(lc_ypkbv_ratio_curv, 0x8);
}
static ssize_t amvecm_lc_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
ssize_t len = 0;
len += sprintf(buf+len,
"echo lc enable > /sys/class/amvecm/lc\n");
len += sprintf(buf+len,
"echo lc disable > /sys/class/amvecm/lc\n");
len += sprintf(buf+len,
"echo lc_dbg value > /sys/class/amvecm/lc\n");
len += sprintf(buf+len,
"echo lc_demo_mode enable/disable > /sys/class/amvecm/lc\n");
len += sprintf(buf+len,
"echo lc_dump_reg parm1 > /sys/class/amvecm/lc\n");
len += sprintf(buf+len,
"echo lc_rd_reg parm1 parm2 > /sys/class/amvecm/lc\n");
len += sprintf(buf+len,
"parm1: 0x1,0x2,0x4,0x8,0x10,0x20...\n");
len += sprintf(buf+len,
"parm2: decimal strings, each data width is 4.\n");
len += sprintf(buf+len,
"echo dump_hist all > /sys/class/amvecm/lc\n");
len += sprintf(buf+len,
"echo dump_hist chosen hs he vs ve cnt > /sys/class/amvecm/lc\n");
len += sprintf(buf+len,
"echo dump_curve cnt > /sys/class/amvecm/lc\n");
len += sprintf(buf+len,
"echo lc_osd_setting show > /sys/class/amvecm/lc\n");
len += sprintf(buf+len,
"echo lc_osd_setting set xxx ... xxx > /sys/class/amvecm/lc\n");
len += sprintf(buf+len,
"echo osd_iir_en val > /sys/class/amvecm/lc\n");
len += sprintf(buf+len,
"echo iir_refresh show > /sys/class/amvecm/lc\n");
len += sprintf(buf+len,
"echo iir_refresh set xxx ... xxx > /sys/class/amvecm/lc\n");
len += sprintf(buf+len,
"echo scene_change_th val > /sys/class/amvecm/lc\n");
len += sprintf(buf+len,
"echo irr_dbg_en val > /sys/class/amvecm/lc\n");
return len;
}
static ssize_t amvecm_lc_store(struct class *cls,
struct class_attribute *attr,
const char *buf, size_t count)
{
char *buf_orig, *parm[8] = {NULL};
int reg_lut[63] = {0};
enum lc_reg_lut_e reg_sel;
int h, v, i, start_point;
long val = 0;
char *stemp = NULL;
int curve_val[6] = {0};
if (!buf)
return count;
stemp = kzalloc(100, GFP_KERNEL);
if (!stemp)
return 0;
buf_orig = kstrdup(buf, GFP_KERNEL);
parse_param_amvecm(buf_orig, (char **)&parm);
if (!strcmp(parm[0], "lc")) {
if (!strcmp(parm[1], "enable"))
lc_en = 1;
else if (!strcmp(parm[1], "disable"))
lc_en = 0;
else
pr_info("unsupprt cmd!\n");
} else if (!strcmp(parm[0], "lc_version")) {
pr_info("lc driver version : %s\n", LC_VER);
} else if (!strcmp(parm[0], "lc_dbg")) {
if (kstrtoul(parm[1], 16, &val) < 0)
goto free_buf;
amlc_debug = val;
} else if (!strcmp(parm[0], "lc_demo_mode")) {
if (!strcmp(parm[1], "enable"))
lc_demo_mode = 1;
else if (!strcmp(parm[1], "disable"))
lc_demo_mode = 0;
else
pr_info("unsupprt cmd!\n");
} else if (!strcmp(parm[0], "dump_lut_data")) {
if (kstrtoul(parm[1], 16, &val) < 0)
goto free_buf;
reg_sel = val;
if (reg_sel == SATUR_LUT)
lc_rd_reg(SATUR_LUT, 0);
else if (reg_sel == YMINVAL_LMT)
lc_rd_reg(YMINVAL_LMT, 0);
else if (reg_sel == YPKBV_YMAXVAL_LMT)
lc_rd_reg(YPKBV_YMAXVAL_LMT, 0);
else if (reg_sel == YPKBV_RAT)
lc_rd_reg(YPKBV_RAT, 0);
else if (reg_sel == YPKBV_SLP_LMT)
lc_rd_reg(YPKBV_SLP_LMT, 0);
else if (reg_sel == CNTST_LMT)
lc_rd_reg(CNTST_LMT, 0);
else
pr_info("unsupprt cmd!\n");
} else if (!strcmp(parm[0], "dump_lut_str")) {
if (kstrtoul(parm[1], 16, &val) < 0)
goto free_buf;
reg_sel = val;
if (reg_sel == SATUR_LUT)
lc_rd_reg(SATUR_LUT, 1);
else if (reg_sel == YMINVAL_LMT)
lc_rd_reg(YMINVAL_LMT, 1);
else if (reg_sel == YPKBV_YMAXVAL_LMT)
lc_rd_reg(YPKBV_YMAXVAL_LMT, 1);
else if (reg_sel == YPKBV_RAT)
lc_rd_reg(YPKBV_RAT, 1);
else
pr_info("unsupprt cmd!\n");
} else if (!strcmp(parm[0], "lc_wr_lut")) {
if (kstrtoul(parm[1], 16, &val) < 0)
goto free_buf;
reg_sel = val;
if (parm[2] == NULL)
goto free_buf;
str_sapr_to_d(parm[2], reg_lut, 5);
if (reg_sel == SATUR_LUT)
lc_wr_reg(reg_lut, SATUR_LUT);
else if (reg_sel == YMINVAL_LMT)
lc_wr_reg(reg_lut, YMINVAL_LMT);
else if (reg_sel == YPKBV_YMAXVAL_LMT)
lc_wr_reg(reg_lut, YPKBV_YMAXVAL_LMT);
else if (reg_sel == YPKBV_RAT)
lc_wr_reg(reg_lut, YPKBV_RAT);
else if (reg_sel == YPKBV_SLP_LMT)
lc_wr_reg(reg_lut, YPKBV_SLP_LMT);
else if (reg_sel == CNTST_LMT)
lc_wr_reg(reg_lut, CNTST_LMT);
else
pr_info("unsupprt cmd!\n");
} else if (!strcmp(parm[0], "dump_hist")) {
if (!strcmp(parm[1], "all")) {
/*dump all hist of one frame*/
lc_hist_prcnt = 1;
amlc_debug = 0x8;
} else if (!strcmp(parm[1], "chosen")) {
/*dump multiple frames in selected area*/
if (parm[6] == NULL)
goto free_buf;
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
lc_hist_hs = val;
if (kstrtoul(parm[3], 10, &val) < 0)
goto free_buf;
lc_hist_he = val;
if (kstrtoul(parm[4], 10, &val) < 0)
goto free_buf;
lc_hist_vs = val;
if (kstrtoul(parm[5], 10, &val) < 0)
goto free_buf;
lc_hist_ve = val;
if (kstrtoul(parm[6], 10, &val) < 0)
goto free_buf;
lc_hist_prcnt = val;
amlc_debug = 0x6;
} else
pr_info("unsupprt cmd!\n");
} else if (!strcmp(parm[0], "dump_curve")) {
if (kstrtoul(parm[1], 10, &val) < 0)
goto free_buf;
lc_curve_prcnt = val;
} else if (!strcmp(parm[0], "lc_osd_setting")) {
if (!strcmp(parm[1], "show")) {
pr_info("VNUM_STRT_BELOW: %d, VNUM_END_BELOW: %d\n",
vnum_start_below, vnum_end_below);
pr_info("VNUM_STRT_ABOVE: %d, VNUM_END_ABOVE: %d\n",
vnum_start_above, vnum_end_above);
pr_info("INVALID_BLK: %d, MIN_BV_PERCENT_TH: %d\n",
invalid_blk, min_bv_percent_th);
} else if (!strcmp(parm[1], "set")) {
if (parm[7] == NULL)
goto free_buf;
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
vnum_start_below = val;
if (kstrtoul(parm[3], 10, &val) < 0)
goto free_buf;
vnum_end_below = val;
if (kstrtoul(parm[4], 10, &val) < 0)
goto free_buf;
vnum_start_above = val;
if (kstrtoul(parm[5], 10, &val) < 0)
goto free_buf;
vnum_end_above = val;
if (kstrtoul(parm[6], 10, &val) < 0)
goto free_buf;
invalid_blk = val;
if (kstrtoul(parm[7], 10, &val) < 0)
goto free_buf;
min_bv_percent_th = val;
} else
pr_info("unsupprt cmd!\n");
} else if (!strcmp(parm[0], "osd_iir_en")) {
if (kstrtoul(parm[1], 10, &val) < 0)
goto free_buf;
osd_iir_en = val;
} else if (!strcmp(parm[0], "iir_refresh")) {
if (!strcmp(parm[1], "show")) {
pr_info("current state: alpha1: %d, alpha2: %d, refresh_bit: %d, ts: %d\n",
alpha1, alpha2, refresh_bit, ts);
} else if (!strcmp(parm[1], "set")) {
if (parm[5] == NULL)
goto free_buf;
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
alpha1 = val;
if (kstrtoul(parm[3], 10, &val) < 0)
goto free_buf;
alpha2 = val;
if (kstrtoul(parm[4], 10, &val) < 0)
goto free_buf;
refresh_bit = val;
if (kstrtoul(parm[5], 10, &val) < 0)
goto free_buf;
ts = val;
pr_info("after setting: alpha1: %d, alpha2: %d, refresh_bit: %d, ts: %d\n",
alpha1, alpha2, refresh_bit, ts);
} else
pr_info("unsupprt cmd!\n");
} else if (!strcmp(parm[0], "scene_change_th")) {
pr_info("current value: %d\n", scene_change_th);
if (kstrtoul(parm[1], 10, &val) < 0)
goto free_buf;
scene_change_th = val;
pr_info("setting value: %d\n", scene_change_th);
} else if (!strcmp(parm[0], "irr_dbg_en")) {
pr_info("current value: %d\n", amlc_iir_debug_en);
if (kstrtoul(parm[1], 10, &val) < 0)
goto free_buf;
amlc_iir_debug_en = val;
pr_info("setting value: %d\n", amlc_iir_debug_en);
} else if (!strcmp(parm[0], "get_blk_region")) {
val = READ_VPP_REG(LC_CURVE_HV_NUM);
h = (val >> 8) & 0x1f;
v = (val) & 0x1f;
if (!strcmp(parm[1], "htotal"))
pr_info("%d\n", h);
else if (!strcmp(parm[1], "vtotal"))
pr_info("%d\n", v);
else
pr_info("unsupprt cmd!\n");
} else if (!strcmp(parm[0], "get_hist")) {
if (kstrtoul(parm[1], 10, &val) < 0)
goto free_buf;
h = val;
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
v = val;
if ((h > 11) || (v > 7))
goto free_buf;
start_point = (12*v+h)*17;
for (i = 0; i < 17; i++)
d_convert_str(lc_hist[start_point + i] >> 4,
i, stemp, 4, 10);
pr_info("%s\n", stemp);
} else if (!strcmp(parm[0], "get_curve")) {
if (kstrtoul(parm[1], 10, &val) < 0)
goto free_buf;
h = val;
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
v = val;
if ((h > 11) || (v > 7))
goto free_buf;
start_point = (12*v+h)*6;
for (i = 0; i < 6; i++)
d_convert_str(curve_nodes_cur[start_point + i],
i, stemp, 4, 10);
pr_info("%s\n", stemp);
} else if (!strcmp(parm[0], "set_curve")) {
if (parm[3] == NULL)
goto free_buf;
if (kstrtoul(parm[1], 10, &val) < 0)
goto free_buf;
h = val;
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
v = val;
if ((h > 11) || (v > 7))
goto free_buf;
start_point = (12*v+h)*6;
str_sapr_to_d(parm[3], curve_val, 5);
for (i = 0; i < 6; i++)
curve_nodes_cur[start_point + i]
= curve_val[i];
} else if (!strcmp(parm[0], "stop_refresh"))
lc_curve_fresh = false;
else if (!strcmp(parm[0], "refresh_curve"))
lc_curve_fresh = true;
else
pr_info("unsupprt cmd!\n");
kfree(buf_orig);
kfree(stemp);
return count;
free_buf:
pr_info("Missing parameters !\n");
kfree(buf_orig);
kfree(stemp);
return -EINVAL;
}
/* #if (MESON_CPU_TYPE == MESON_CPU_TYPE_MESONG9TV) */
void init_pq_setting(void)
{
if (is_meson_gxtvbb_cpu() || is_meson_txl_cpu() ||
is_meson_txlx_cpu() || is_meson_txhd_cpu() ||
is_meson_tl1_cpu())
goto tvchip_pq_setting;
else if (is_meson_g12a_cpu() || is_meson_g12b_cpu()) {
sr_offset[0] = SR0_OFFSET;
/*dnlp off*/
WRITE_VPP_REG_BITS(VPP_VE_ENABLE_CTRL, 0,
DNLP_EN_BIT, DNLP_EN_WID);
/*sr0 chroma filter bypass*/
WRITE_VPP_REG(SRSHARP0_SHARP_SR2_CBIC_HCOEF0 + sr_offset[0],
0x4000);
WRITE_VPP_REG(SRSHARP0_SHARP_SR2_CBIC_VCOEF0 + sr_offset[0],
0x4000);
}
return;
tvchip_pq_setting:
if (get_cpu_type() == MESON_CPU_MAJOR_ID_TL1) {
/*sr0 & sr1 register shfit*/
sr_offset[0] = SR0_OFFSET;
sr_offset[1] = SR1_OFFSET;
/*cm register init*/
cm_init_config();
/*lc init*/
lc_init();
}
/*probe close sr0 peaking for switch on video*/
WRITE_VPP_REG_BITS(VPP_SRSHARP0_CTRL, 1, 0, 1);
if (cpu_after_eq(MESON_CPU_MAJOR_ID_TL1))
WRITE_VPP_REG_BITS(VPP_SRSHARP1_CTRL, 0, 0, 1);
else
WRITE_VPP_REG_BITS(VPP_SRSHARP1_CTRL, 1, 0, 1);
/*default dnlp off*/
WRITE_VPP_REG_BITS(SRSHARP0_PK_NR_ENABLE + sr_offset[0],
0, 1, 1);
WRITE_VPP_REG_BITS(SRSHARP1_PK_NR_ENABLE + sr_offset[1],
0, 1, 1);
WRITE_VPP_REG_BITS(VPP_VE_ENABLE_CTRL, 0, DNLP_EN_BIT, DNLP_EN_WID);
/*end*/
if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) {
WRITE_VPP_REG_BITS(SRSHARP1_PK_FINALGAIN_HP_BP + sr_offset[1],
2, 16, 2);
/*sr0 sr1 chroma filter bypass*/
WRITE_VPP_REG(SRSHARP0_SHARP_SR2_CBIC_HCOEF0 + sr_offset[0],
0x4000);
WRITE_VPP_REG(SRSHARP0_SHARP_SR2_CBIC_VCOEF0 + sr_offset[0],
0x4000);
WRITE_VPP_REG(SRSHARP1_SHARP_SR2_CBIC_HCOEF0 + sr_offset[1],
0x4000);
WRITE_VPP_REG(SRSHARP1_SHARP_SR2_CBIC_VCOEF0 + sr_offset[1],
0x4000);
}
if (is_meson_gxlx_cpu())
amve_sharpness_init();
/*dnlp alg parameters init*/
dnlp_alg_param_init();
}
/* #endif*/
void print_gamma_table(char *name, u16 *table)
{
char buf[3 * GAMMA_SIZE + 1];
u16 i;
for (i = 0; i < GAMMA_SIZE; i++)
snprintf(&buf[3*i], 4, "%03x", table[i]);
pr_info("read gamma channel %s: %s", name, buf);
}
void amvecm_gamma_init(bool en)
{
unsigned int i;
unsigned short data[GAMMA_SIZE];
gamma_working = false;
/* If gamma is already enabled its init was handled by the bootloader */
if (READ_VPP_REG(L_GAMMA_CNTL_PORT) & 0x1) {
/* Dump data for debugging if something goes wrong */
vpp_get_lcd_gamma_table(H_SEL_R, data);
for (i = 0; i < GAMMA_SIZE; i++) {
video_gamma_table_r.data[i] = data[i];
}
print_gamma_table("R", data);
vpp_get_lcd_gamma_table(H_SEL_G, data);
for (i = 0; i < GAMMA_SIZE; i++) {
video_gamma_table_g.data[i] = data[i];
}
print_gamma_table("G", data);
vpp_get_lcd_gamma_table(H_SEL_B, data);
for (i = 0; i < GAMMA_SIZE; i++) {
video_gamma_table_b.data[i] = data[i];
}
print_gamma_table("B", data);
gamma_working = true;
return;
}
if (en) {
for (i = 0; i < GAMMA_SIZE; i++) {
data[i] = i << 2;
video_gamma_table_r.data[i] = data[i];
video_gamma_table_g.data[i] = data[i];
video_gamma_table_b.data[i] = data[i];
}
/* if gamma is already enabled
* its init was handled by the bootloader */
if (READ_VPP_REG(L_GAMMA_CNTL_PORT) & 0x1)
return;
amve_write_gamma_table(
data,
H_SEL_R);
amve_write_gamma_table(
data,
H_SEL_G);
amve_write_gamma_table(
data,
H_SEL_B);
}
}
static void amvecm_wb_init(bool en)
{
if (en) {
if (video_rgb_ogo_xvy_mtx) {
WRITE_VPP_REG_BITS(VPP_MATRIX_CTRL, 3, 8, 3);
WRITE_VPP_REG(VPP_MATRIX_PRE_OFFSET0_1,
((wb_init_bypass_coef[0] & 0xfff) << 16)
| (wb_init_bypass_coef[1] & 0xfff));
WRITE_VPP_REG(VPP_MATRIX_PRE_OFFSET2,
wb_init_bypass_coef[2] & 0xfff);
WRITE_VPP_REG(VPP_MATRIX_COEF00_01,
((wb_init_bypass_coef[3] & 0x1fff) << 16)
| (wb_init_bypass_coef[4] & 0x1fff));
WRITE_VPP_REG(VPP_MATRIX_COEF02_10,
((wb_init_bypass_coef[5] & 0x1fff) << 16)
| (wb_init_bypass_coef[6] & 0x1fff));
WRITE_VPP_REG(VPP_MATRIX_COEF11_12,
((wb_init_bypass_coef[7] & 0x1fff) << 16)
| (wb_init_bypass_coef[8] & 0x1fff));
WRITE_VPP_REG(VPP_MATRIX_COEF20_21,
((wb_init_bypass_coef[9] & 0x1fff) << 16)
| (wb_init_bypass_coef[10] & 0x1fff));
WRITE_VPP_REG(VPP_MATRIX_COEF22,
wb_init_bypass_coef[11] & 0x1fff);
if (wb_init_bypass_coef[21]) {
WRITE_VPP_REG(VPP_MATRIX_COEF13_14,
((wb_init_bypass_coef[12] & 0x1fff) << 16)
| (wb_init_bypass_coef[13] & 0x1fff));
WRITE_VPP_REG(VPP_MATRIX_COEF15_25,
((wb_init_bypass_coef[14] & 0x1fff) << 16)
| (wb_init_bypass_coef[17] & 0x1fff));
WRITE_VPP_REG(VPP_MATRIX_COEF23_24,
((wb_init_bypass_coef[15] & 0x1fff) << 16)
| (wb_init_bypass_coef[16] & 0x1fff));
}
WRITE_VPP_REG(VPP_MATRIX_OFFSET0_1,
((wb_init_bypass_coef[18] & 0xfff) << 16)
| (wb_init_bypass_coef[19] & 0xfff));
WRITE_VPP_REG(VPP_MATRIX_OFFSET2,
wb_init_bypass_coef[20] & 0xfff);
WRITE_VPP_REG_BITS(VPP_MATRIX_CLIP,
wb_init_bypass_coef[21], 3, 2);
WRITE_VPP_REG_BITS(VPP_MATRIX_CLIP,
wb_init_bypass_coef[22], 5, 3);
} else {
WRITE_VPP_REG(VPP_GAINOFF_CTRL0,
(1024 << 16) | 1024);
WRITE_VPP_REG(VPP_GAINOFF_CTRL1,
(1024 << 16));
}
}
if (video_rgb_ogo_xvy_mtx)
WRITE_VPP_REG_BITS(VPP_MATRIX_CTRL, en, 6, 1);
else
WRITE_VPP_REG_BITS(VPP_GAINOFF_CTRL0, en, 31, 1);
}
static struct class_attribute amvecm_class_attrs[] = {
__ATTR(debug, 0644,
amvecm_debug_show, amvecm_debug_store),
__ATTR(dnlp_debug, 0644,
amvecm_dnlp_debug_show,
amvecm_dnlp_debug_store),
__ATTR(cm2_hue, 0644,
amvecm_cm2_hue_show,
amvecm_cm2_hue_store),
__ATTR(cm2_luma, 0644,
amvecm_cm2_luma_show,
amvecm_cm2_luma_store),
__ATTR(cm2_sat, 0644,
amvecm_cm2_sat_show,
amvecm_cm2_sat_store),
__ATTR(cm2_hue_by_hs, 0644,
amvecm_cm2_hue_by_hs_show,
amvecm_cm2_hue_by_hs_store),
__ATTR(brightness, 0644,
amvecm_brightness_show, amvecm_brightness_store),
__ATTR(contrast, 0644,
amvecm_contrast_show, amvecm_contrast_store),
__ATTR(saturation_hue, 0644,
amvecm_saturation_hue_show,
amvecm_saturation_hue_store),
__ATTR(saturation_hue_pre, 0644,
amvecm_saturation_hue_pre_show,
amvecm_saturation_hue_pre_store),
__ATTR(saturation_hue_post, 0644,
amvecm_saturation_hue_post_show,
amvecm_saturation_hue_post_store),
__ATTR(cm2, 0644,
amvecm_cm2_show,
amvecm_cm2_store),
__ATTR(cm_reg, 0644,
amvecm_cm_reg_show,
amvecm_cm_reg_store),
__ATTR(gamma, 0644,
amvecm_gamma_show,
amvecm_gamma_store),
__ATTR(wb, 0644,
amvecm_wb_show,
amvecm_wb_store),
__ATTR(brightness1, 0644,
video_adj1_brightness_show,
video_adj1_brightness_store),
__ATTR(contrast1, 0644,
video_adj1_contrast_show, video_adj1_contrast_store),
__ATTR(brightness2, 0644,
video_adj2_brightness_show, video_adj2_brightness_store),
__ATTR(contrast2, 0644,
video_adj2_contrast_show, video_adj2_contrast_store),
__ATTR(help, 0644,
amvecm_usage_show, NULL),
/* #if (MESON_CPU_TYPE >= MESON_CPU_TYPE_MESONG9TV) */
__ATTR(sync_3d, 0644,
amvecm_3d_sync_show,
amvecm_3d_sync_store),
__ATTR(vlock, 0644,
amvecm_vlock_show,
amvecm_vlock_store),
__ATTR(matrix_set, 0644,
amvecm_set_post_matrix_show, amvecm_set_post_matrix_store),
__ATTR(matrix_pos, 0644,
amvecm_post_matrix_pos_show, amvecm_post_matrix_pos_store),
__ATTR(matrix_data, 0644,
amvecm_post_matrix_data_show, amvecm_post_matrix_data_store),
__ATTR(dump_reg, 0644,
amvecm_dump_reg_show, amvecm_dump_reg_store),
__ATTR(sr1_reg, 0644,
amvecm_sr1_reg_show, amvecm_sr1_reg_store),
__ATTR(write_sr1_reg_val, 0644,
amvecm_write_sr1_reg_val_show, amvecm_write_sr1_reg_val_store),
__ATTR(dump_vpp_hist, 0644,
amvecm_dump_vpp_hist_show, amvecm_dump_vpp_hist_store),
__ATTR(hdr_dbg, 0644,
amvecm_hdr_dbg_show, amvecm_hdr_dbg_store),
__ATTR(hdr_reg, 0644,
amvecm_hdr_reg_show, amvecm_hdr_reg_store),
__ATTR(gamma_pattern, 0644,
set_gamma_pattern_show, set_gamma_pattern_store),
__ATTR(pc_mode, 0644,
amvecm_pc_mode_show, amvecm_pc_mode_store),
__ATTR(set_hdr_289lut, 0644,
set_hdr_289lut_show, set_hdr_289lut_store),
__ATTR(vpp_demo, 0644,
amvecm_vpp_demo_show, amvecm_vpp_demo_store),
__ATTR(reg, 0644,
amvecm_reg_show, amvecm_reg_store),
__ATTR(pq_user_set, 0644,
amvecm_pq_user_show, amvecm_pq_user_store),
__ATTR(pq_reg_rw, 0644,
amvecm_write_reg_show, amvecm_write_reg_store),
__ATTR(get_hdr_type, 0644,
amvecm_get_hdr_type_show, amvecm_get_hdr_type_store),
__ATTR(color_top, 0644,
amvecm_clamp_color_top_show, amvecm_clamp_color_top_store),
__ATTR(color_bottom, 0644,
amvecm_clamp_color_bottom_show,
amvecm_clamp_color_bottom_store),
__ATTR(dnlp_insmod, 0644,
amvecm_dnlp_insmod_show, amvecm_dnlp_insmod_store),
__ATTR(lc, 0644,
amvecm_lc_show,
amvecm_lc_store),
__ATTR_NULL
};
void amvecm_wakeup_queue(void)
{
struct amvecm_dev_s *devp = &amvecm_dev;
wake_up(&devp->hdr_queue);
}
static unsigned int amvecm_poll(struct file *file, poll_table *wait)
{
struct amvecm_dev_s *devp = file->private_data;
unsigned int mask = 0;
poll_wait(file, &devp->hdr_queue, wait);
mask = (POLLIN | POLLRDNORM);
return mask;
}
static const struct file_operations amvecm_fops = {
.owner = THIS_MODULE,
.open = amvecm_open,
.release = amvecm_release,
.unlocked_ioctl = amvecm_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = amvecm_compat_ioctl,
#endif
.poll = amvecm_poll,
};
static const struct vecm_match_data_s vecm_dt_xxx = {
.vlk_support = true,
.vlk_new_fsm = 0,
.vlk_hwver = vlock_hw_org,
.vlk_phlock_en = false,
};
static const struct vecm_match_data_s vecm_dt_tl1 = {
.vlk_support = true,
.vlk_new_fsm = 1,
.vlk_hwver = vlock_hw_ver2,
.vlk_phlock_en = true,
};
static const struct of_device_id aml_vecm_dt_match[] = {
{
.compatible = "amlogic, vecm",
.data = &vecm_dt_xxx,
},
{
.compatible = "amlogic, vecm-tl1",
.data = &vecm_dt_tl1,
},
{},
};
static void aml_vecm_dt_parse(struct platform_device *pdev)
{
struct device_node *node;
unsigned int val;
int ret;
const struct of_device_id *of_id;
struct vecm_match_data_s *matchdata;
node = pdev->dev.of_node;
/* get integer value */
if (node) {
ret = of_property_read_u32(node, "gamma_en", &val);
if (ret)
pr_info("Can't find gamma_en.\n");
else
gamma_en = val;
ret = of_property_read_u32(node, "wb_en", &val);
if (ret)
pr_info("Can't find wb_en.\n");
else
wb_en = val;
ret = of_property_read_u32(node, "cm_en", &val);
if (ret)
pr_info("Can't find cm_en.\n");
else
cm_en = val;
ret = of_property_read_u32(node, "wb_sel", &val);
if (ret)
pr_info("Can't find wb_sel.\n");
else
video_rgb_ogo_xvy_mtx = val;
/*hdr:cfg:osd_100*/
ret = of_property_read_u32(node, "cfg_en_osd_100", &val);
if (ret) {
hdr_set_cfg_osd_100(0);
pr_info("hdr:Can't find cfg_en_osd_100.\n");
} else {
hdr_set_cfg_osd_100((int)val);
}
ret = of_property_read_u32(node, "tx_op_color_primary", &val);
if (ret)
pr_info("Can't find tx_op_color_primary.\n");
else
tx_op_color_primary = val;
/*get compatible matched device, to get chip related data*/
of_id = of_match_device(aml_vecm_dt_match, &pdev->dev);
if (of_id != NULL) {
pr_info("%s", of_id->compatible);
matchdata = (struct vecm_match_data_s *)of_id->data;
} else {
matchdata = (struct vecm_match_data_s *)&vecm_dt_xxx;
pr_info("unable to get matched device\n");
}
vlock_dt_match_init(matchdata);
/*vlock param config*/
vlock_param_config(node);
}
/* init module status */
amvecm_wb_init(wb_en);
#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
if (!is_dolby_vision_enable())
#endif
WRITE_VPP_REG_BITS(VPP_MISC, 1, 28, 1);
if (cm_en) {
#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
if (!is_dolby_vision_enable())
#endif
amcm_enable();
}
else
amcm_disable();
/* WRITE_VPP_REG_BITS(VPP_MISC, cm_en, 28, 1); */
}
#ifdef CONFIG_AMLOGIC_LCD
static int aml_lcd_gamma_notifier(struct notifier_block *nb,
unsigned long event, void *data)
{
if ((event & LCD_EVENT_GAMMA_UPDATE) == 0)
return NOTIFY_DONE;
if (gamma_en == false || gamma_working == false)
return NOTIFY_DONE;
#if 0
vpp_set_lcd_gamma_table(video_gamma_table_r.data, H_SEL_R);
vpp_set_lcd_gamma_table(video_gamma_table_g.data, H_SEL_G);
vpp_set_lcd_gamma_table(video_gamma_table_b.data, H_SEL_B);
#else
pr_info("%s reflash vecm_latch_flag\n", __func__);
vecm_latch_flag |= FLAG_GAMMA_TABLE_R;
vecm_latch_flag |= FLAG_GAMMA_TABLE_G;
vecm_latch_flag |= FLAG_GAMMA_TABLE_B;
#endif
return NOTIFY_OK;
}
static struct notifier_block aml_lcd_gamma_nb = {
.notifier_call = aml_lcd_gamma_notifier,
};
#endif
static struct notifier_block vlock_notifier_nb = {
.notifier_call = vlock_notify_callback,
};
static int aml_vecm_probe(struct platform_device *pdev)
{
int ret = 0;
int i = 0;
struct amvecm_dev_s *devp = &amvecm_dev;
memset(devp, 0, (sizeof(struct amvecm_dev_s)));
pr_info("\n VECM probe start\n");
ret = alloc_chrdev_region(&devp->devno, 0, 1, AMVECM_NAME);
if (ret < 0)
goto fail_alloc_region;
devp->clsp = class_create(THIS_MODULE, AMVECM_CLASS_NAME);
if (IS_ERR(devp->clsp)) {
ret = PTR_ERR(devp->clsp);
goto fail_create_class;
}
for (i = 0; amvecm_class_attrs[i].attr.name; i++) {
if (class_create_file(devp->clsp, &amvecm_class_attrs[i]) < 0)
goto fail_class_create_file;
}
cdev_init(&devp->cdev, &amvecm_fops);
devp->cdev.owner = THIS_MODULE;
ret = cdev_add(&devp->cdev, devp->devno, 1);
if (ret)
goto fail_add_cdev;
devp->dev = device_create(devp->clsp, NULL, devp->devno,
NULL, AMVECM_NAME);
if (IS_ERR(devp->dev)) {
ret = PTR_ERR(devp->dev);
goto fail_create_device;
}
spin_lock_init(&vpp_lcd_gamma_lock);
#ifdef CONFIG_AMLOGIC_LCD
ret = aml_lcd_notifier_register(&aml_lcd_gamma_nb);
if (ret)
pr_info("register aml_lcd_gamma_notifier failed\n");
INIT_WORK(&aml_lcd_vlock_param_work, vlock_lcd_param_work);
#endif
/* register vout client */
vout_register_client(&vlock_notifier_nb);
init_pq_setting();
/* #endif */
vpp_get_hist_en();
if (is_meson_txlx_cpu()) {
vpp_set_12bit_datapath2();
/*post matrix 12bit yuv2rgb*/
/* mtx_sel_dbg |= 1 << VPP_MATRIX_2; */
/* amvecm_vpp_mtx_debug(mtx_sel_dbg, 1);*/
WRITE_VPP_REG(VPP_MATRIX_PROBE_POS, 0x1fff1fff);
} else if (is_meson_txhd_cpu())
vpp_set_10bit_datapath1();
else if (is_meson_g12a_cpu() || is_meson_g12b_cpu())
vpp_set_12bit_datapath_g12a();
memset(&vpp_hist_param.vpp_histgram[0],
0, sizeof(unsigned short) * 64);
/* box sdr_mode:auto, tv sdr_mode:off */
/* disable contrast and saturation adjustment for HDR on TV */
/* disable SDR to HDR convert on TV */
if (is_meson_gxl_cpu() || is_meson_gxm_cpu())
hdr_flag = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3);
else
hdr_flag = (1 << 0) | (1 << 1) | (0 << 2) | (0 << 3);
vlock_status_init();
hdr_init(&amvecm_dev.hdr_d);
aml_vecm_dt_parse(pdev);
probe_ok = 1;
pr_info("%s: ok\n", __func__);
return 0;
fail_create_device:
pr_info("[amvecm.] : amvecm device create error.\n");
cdev_del(&devp->cdev);
fail_add_cdev:
pr_info("[amvecm.] : amvecm add device error.\n");
fail_class_create_file:
pr_info("[amvecm.] : amvecm class create file error.\n");
for (i = 0; amvecm_class_attrs[i].attr.name; i++) {
class_remove_file(devp->clsp,
&amvecm_class_attrs[i]);
}
class_destroy(devp->clsp);
fail_create_class:
pr_info("[amvecm.] : amvecm class create error.\n");
unregister_chrdev_region(devp->devno, 1);
fail_alloc_region:
pr_info("[amvecm.] : amvecm alloc error.\n");
pr_info("[amvecm.] : amvecm_init.\n");
return ret;
}
static int __exit aml_vecm_remove(struct platform_device *pdev)
{
struct amvecm_dev_s *devp = &amvecm_dev;
hdr_exit();
device_destroy(devp->clsp, devp->devno);
cdev_del(&devp->cdev);
class_destroy(devp->clsp);
unregister_chrdev_region(devp->devno, 1);
#ifdef CONFIG_AMLOGIC_LCD
aml_lcd_notifier_unregister(&aml_lcd_gamma_nb);
cancel_work_sync(&aml_lcd_vlock_param_work);
#endif
probe_ok = 0;
lc_free();
pr_info("[amvecm.] : amvecm_exit.\n");
return 0;
}
#ifdef CONFIG_PM
static int amvecm_drv_suspend(struct platform_device *pdev,
pm_message_t state)
{
if (probe_ok == 1)
probe_ok = 0;
pr_info("amvecm: suspend module\n");
return 0;
}
static int amvecm_drv_resume(struct platform_device *pdev)
{
if (probe_ok == 0)
probe_ok = 1;
pr_info("amvecm: resume module\n");
return 0;
}
#endif
static void amvecm_shutdown(struct platform_device *pdev)
{
struct amvecm_dev_s *devp = &amvecm_dev;
hdr_exit();
ve_disable_dnlp();
amcm_disable();
WRITE_VPP_REG(VPP_VADJ_CTRL, 0x0);
amvecm_wb_enable(0);
/*dnlp cm vadj1 wb gate*/
WRITE_VPP_REG(VPP_GCLK_CTRL0, 0x11000400);
WRITE_VPP_REG(VPP_GCLK_CTRL1, 0x14);
pr_info("amvecm: shutdown module\n");
device_destroy(devp->clsp, devp->devno);
cdev_del(&devp->cdev);
class_destroy(devp->clsp);
unregister_chrdev_region(devp->devno, 1);
#ifdef CONFIG_AML_LCD
aml_lcd_notifier_unregister(&aml_lcd_gamma_nb);
#endif
lc_free();
}
static struct platform_driver aml_vecm_driver = {
.driver = {
.name = "aml_vecm",
.owner = THIS_MODULE,
.of_match_table = aml_vecm_dt_match,
},
.probe = aml_vecm_probe,
.shutdown = amvecm_shutdown,
.remove = __exit_p(aml_vecm_remove),
#ifdef CONFIG_PM
.suspend = amvecm_drv_suspend,
.resume = amvecm_drv_resume,
#endif
};
static int __init aml_vecm_init(void)
{
/*unsigned int hiu_reg_base;*/
pr_info("%s:module init\n", __func__);
#if 0
/* remap the hiu bus */
if (is_meson_txlx_cpu() || is_meson_txhd_cpu() ||
is_meson_g12a_cpu() || is_meson_g12b_cpu()
|| is_meson_tl1_cpu())
hiu_reg_base = 0xff63c000;
else
hiu_reg_base = 0xc883c000;
amvecm_hiu_reg_base = ioremap(hiu_reg_base, 0x2000);
#endif
if (platform_driver_register(&aml_vecm_driver)) {
pr_err("failed to register bl driver module\n");
return -ENODEV;
}
return 0;
}
static void __exit aml_vecm_exit(void)
{
pr_info("%s:module exit\n", __func__);
/*iounmap(amvecm_hiu_reg_base);*/
platform_driver_unregister(&aml_vecm_driver);
}
module_init(aml_vecm_init);
module_exit(aml_vecm_exit);
MODULE_VERSION(AMVECM_VER);
MODULE_DESCRIPTION("AMLOGIC amvecm driver");
MODULE_LICENSE("GPL");