/*
 * Support for Intel Camera Imaging ISP subsystem.
 * Copyright (c) 2015, Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 */

#include "ia_css_types.h"
#include "sh_css_defs.h"
#include "ia_css_debug.h"
#include "sh_css_frac.h"

#include "bnr/bnr_1.0/ia_css_bnr.host.h"
#include "ia_css_ynr.host.h"

const struct ia_css_nr_config default_nr_config = {
	16384,
	8192,
	1280,
	0,
	0
};

const struct ia_css_ee_config default_ee_config = {
	8192,
	128,
	2048
};

void
ia_css_nr_encode(
    struct sh_css_isp_ynr_params *to,
    const struct ia_css_nr_config *from,
    unsigned int size)
{
	(void)size;
	/* YNR (Y Noise Reduction) */
	to->threshold =
	    uDIGIT_FITTING(8192U, 16, SH_CSS_BAYER_BITS);
	to->gain_all =
	    uDIGIT_FITTING(from->ynr_gain, 16, SH_CSS_YNR_GAIN_SHIFT);
	to->gain_dir =
	    uDIGIT_FITTING(from->ynr_gain, 16, SH_CSS_YNR_GAIN_SHIFT);
	to->threshold_cb =
	    uDIGIT_FITTING(from->threshold_cb, 16, SH_CSS_BAYER_BITS);
	to->threshold_cr =
	    uDIGIT_FITTING(from->threshold_cr, 16, SH_CSS_BAYER_BITS);
}

void
ia_css_yee_encode(
    struct sh_css_isp_yee_params *to,
    const struct ia_css_yee_config *from,
    unsigned int size)
{
	int asiWk1 = (int)from->ee.gain;
	int asiWk2 = asiWk1 / 8;
	int asiWk3 = asiWk1 / 4;

	(void)size;
	/* YEE (Y Edge Enhancement) */
	to->dirthreshold_s =
	    min((uDIGIT_FITTING(from->nr.direction, 16, SH_CSS_BAYER_BITS)
		 << 1),
		SH_CSS_BAYER_MAXVAL);
	to->dirthreshold_g =
	    min((uDIGIT_FITTING(from->nr.direction, 16, SH_CSS_BAYER_BITS)
		 << 4),
		SH_CSS_BAYER_MAXVAL);
	to->dirthreshold_width_log2 =
	    uFRACTION_BITS_FITTING(8);
	to->dirthreshold_width =
	    1 << to->dirthreshold_width_log2;
	to->detailgain =
	    uDIGIT_FITTING(from->ee.detail_gain, 11,
			   SH_CSS_YEE_DETAIL_GAIN_SHIFT);
	to->coring_s =
	    (uDIGIT_FITTING(56U, 16, SH_CSS_BAYER_BITS) *
	     from->ee.threshold) >> 8;
	to->coring_g =
	    (uDIGIT_FITTING(224U, 16, SH_CSS_BAYER_BITS) *
	     from->ee.threshold) >> 8;
	/* 8; // *1.125 ->[s4.8] */
	to->scale_plus_s =
	    (asiWk1 + asiWk2) >> (11 - SH_CSS_YEE_SCALE_SHIFT);
	/* 8; // ( * -.25)->[s4.8] */
	to->scale_plus_g =
	    (0 - asiWk3) >> (11 - SH_CSS_YEE_SCALE_SHIFT);
	/* 8; // *0.875 ->[s4.8] */
	to->scale_minus_s =
	    (asiWk1 - asiWk2) >> (11 - SH_CSS_YEE_SCALE_SHIFT);
	/* 8; // ( *.25 ) ->[s4.8] */
	to->scale_minus_g =
	    (asiWk3) >> (11 - SH_CSS_YEE_SCALE_SHIFT);
	to->clip_plus_s =
	    uDIGIT_FITTING(32760U, 16, SH_CSS_BAYER_BITS);
	to->clip_plus_g = 0;
	to->clip_minus_s =
	    uDIGIT_FITTING(504U, 16, SH_CSS_BAYER_BITS);
	to->clip_minus_g =
	    uDIGIT_FITTING(32256U, 16, SH_CSS_BAYER_BITS);
	to->Yclip = SH_CSS_BAYER_MAXVAL;
}

void
ia_css_nr_dump(
    const struct sh_css_isp_ynr_params *ynr,
    unsigned int level)
{
	if (!ynr) return;
	ia_css_debug_dtrace(level,
			    "Y Noise Reduction:\n");
	ia_css_debug_dtrace(level, "\t%-32s = %d\n",
			    "ynr_threshold", ynr->threshold);
	ia_css_debug_dtrace(level, "\t%-32s = %d\n",
			    "ynr_gain_all", ynr->gain_all);
	ia_css_debug_dtrace(level, "\t%-32s = %d\n",
			    "ynr_gain_dir", ynr->gain_dir);
	ia_css_debug_dtrace(level, "\t%-32s = %d\n",
			    "ynr_threshold_cb", ynr->threshold_cb);
	ia_css_debug_dtrace(level, "\t%-32s = %d\n",
			    "ynr_threshold_cr", ynr->threshold_cr);
}

void
ia_css_yee_dump(
    const struct sh_css_isp_yee_params *yee,
    unsigned int level)
{
	ia_css_debug_dtrace(level,
			    "Y Edge Enhancement:\n");
	ia_css_debug_dtrace(level, "\t%-32s = %d\n",
			    "ynryee_dirthreshold_s",
			    yee->dirthreshold_s);
	ia_css_debug_dtrace(level, "\t%-32s = %d\n",
			    "ynryee_dirthreshold_g",
			    yee->dirthreshold_g);
	ia_css_debug_dtrace(level, "\t%-32s = %d\n",
			    "ynryee_dirthreshold_width_log2",
			    yee->dirthreshold_width_log2);
	ia_css_debug_dtrace(level, "\t%-32s = %d\n",
			    "ynryee_dirthreshold_width",
			    yee->dirthreshold_width);
	ia_css_debug_dtrace(level, "\t%-32s = %d\n",
			    "yee_detailgain",
			    yee->detailgain);
	ia_css_debug_dtrace(level, "\t%-32s = %d\n",
			    "yee_coring_s",
			    yee->coring_s);
	ia_css_debug_dtrace(level, "\t%-32s = %d\n",
			    "yee_coring_g",
			    yee->coring_g);
	ia_css_debug_dtrace(level, "\t%-32s = %d\n",
			    "yee_scale_plus_s",
			    yee->scale_plus_s);
	ia_css_debug_dtrace(level, "\t%-32s = %d\n",
			    "yee_scale_plus_g",
			    yee->scale_plus_g);
	ia_css_debug_dtrace(level, "\t%-32s = %d\n",
			    "yee_scale_minus_s",
			    yee->scale_minus_s);
	ia_css_debug_dtrace(level, "\t%-32s = %d\n",
			    "yee_scale_minus_g",
			    yee->scale_minus_g);
	ia_css_debug_dtrace(level, "\t%-32s = %d\n",
			    "yee_clip_plus_s",
			    yee->clip_plus_s);
	ia_css_debug_dtrace(level, "\t%-32s = %d\n",
			    "yee_clip_plus_g",
			    yee->clip_plus_g);
	ia_css_debug_dtrace(level, "\t%-32s = %d\n",
			    "yee_clip_minus_s",
			    yee->clip_minus_s);
	ia_css_debug_dtrace(level, "\t%-32s = %d\n",
			    "yee_clip_minus_g",
			    yee->clip_minus_g);
	ia_css_debug_dtrace(level, "\t%-32s = %d\n",
			    "ynryee_Yclip",
			    yee->Yclip);
}

void
ia_css_nr_debug_dtrace(
    const struct ia_css_nr_config *config,
    unsigned int level)
{
	ia_css_debug_dtrace(level,
			    "config.direction=%d, config.bnr_gain=%d, config.ynr_gain=%d, config.threshold_cb=%d, config.threshold_cr=%d\n",
			    config->direction,
			    config->bnr_gain, config->ynr_gain,
			    config->threshold_cb, config->threshold_cr);
}

void
ia_css_ee_debug_dtrace(
    const struct ia_css_ee_config *config,
    unsigned int level)
{
	ia_css_debug_dtrace(level,
			    "config.threshold=%d, config.gain=%d, config.detail_gain=%d\n",
			    config->threshold, config->gain, config->detail_gain);
}

void
ia_css_init_ynr_state(
    void/*struct sh_css_isp_ynr_vmem_state*/ * state,
    size_t size)
{
	memset(state, 0, size);
}
