/*
 * isph3a_af.c
 *
 * TI OMAP3 ISP - H3A AF module
 *
 * Copyright (C) 2010 Nokia Corporation
 * Copyright (C) 2009 Texas Instruments, Inc.
 *
 * Contacts: David Cohen <dacohen@gmail.com>
 *	     Laurent Pinchart <laurent.pinchart@ideasonboard.com>
 *	     Sakari Ailus <sakari.ailus@iki.fi>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

/* Linux specific include files */
#include <linux/device.h>
#include <linux/slab.h>

#include "isp.h"
#include "isph3a.h"
#include "ispstat.h"

#define IS_OUT_OF_BOUNDS(value, min, max)		\
	(((value) < (min)) || ((value) > (max)))

static void h3a_af_setup_regs(struct ispstat *af, void *priv)
{
	struct omap3isp_h3a_af_config *conf = priv;
	u32 pcr;
	u32 pax1;
	u32 pax2;
	u32 paxstart;
	u32 coef;
	u32 base_coef_set0;
	u32 base_coef_set1;
	int index;

	if (af->state == ISPSTAT_DISABLED)
		return;

	isp_reg_writel(af->isp, af->active_buf->dma_addr, OMAP3_ISP_IOMEM_H3A,
		       ISPH3A_AFBUFST);

	if (!af->update)
		return;

	/* Configure Hardware Registers */
	pax1 = ((conf->paxel.width >> 1) - 1) << AF_PAXW_SHIFT;
	/* Set height in AFPAX1 */
	pax1 |= (conf->paxel.height >> 1) - 1;
	isp_reg_writel(af->isp, pax1, OMAP3_ISP_IOMEM_H3A, ISPH3A_AFPAX1);

	/* Configure AFPAX2 Register */
	/* Set Line Increment in AFPAX2 Register */
	pax2 = ((conf->paxel.line_inc >> 1) - 1) << AF_LINE_INCR_SHIFT;
	/* Set Vertical Count */
	pax2 |= (conf->paxel.v_cnt - 1) << AF_VT_COUNT_SHIFT;
	/* Set Horizontal Count */
	pax2 |= (conf->paxel.h_cnt - 1);
	isp_reg_writel(af->isp, pax2, OMAP3_ISP_IOMEM_H3A, ISPH3A_AFPAX2);

	/* Configure PAXSTART Register */
	/*Configure Horizontal Start */
	paxstart = conf->paxel.h_start << AF_HZ_START_SHIFT;
	/* Configure Vertical Start */
	paxstart |= conf->paxel.v_start;
	isp_reg_writel(af->isp, paxstart, OMAP3_ISP_IOMEM_H3A,
		       ISPH3A_AFPAXSTART);

	/*SetIIRSH Register */
	isp_reg_writel(af->isp, conf->iir.h_start,
		       OMAP3_ISP_IOMEM_H3A, ISPH3A_AFIIRSH);

	base_coef_set0 = ISPH3A_AFCOEF010;
	base_coef_set1 = ISPH3A_AFCOEF110;
	for (index = 0; index <= 8; index += 2) {
		/*Set IIR Filter0 Coefficients */
		coef = 0;
		coef |= conf->iir.coeff_set0[index];
		coef |= conf->iir.coeff_set0[index + 1] <<
			AF_COEF_SHIFT;
		isp_reg_writel(af->isp, coef, OMAP3_ISP_IOMEM_H3A,
			       base_coef_set0);
		base_coef_set0 += AFCOEF_OFFSET;

		/*Set IIR Filter1 Coefficients */
		coef = 0;
		coef |= conf->iir.coeff_set1[index];
		coef |= conf->iir.coeff_set1[index + 1] <<
			AF_COEF_SHIFT;
		isp_reg_writel(af->isp, coef, OMAP3_ISP_IOMEM_H3A,
			       base_coef_set1);
		base_coef_set1 += AFCOEF_OFFSET;
	}
	/* set AFCOEF0010 Register */
	isp_reg_writel(af->isp, conf->iir.coeff_set0[10],
		       OMAP3_ISP_IOMEM_H3A, ISPH3A_AFCOEF0010);
	/* set AFCOEF1010 Register */
	isp_reg_writel(af->isp, conf->iir.coeff_set1[10],
		       OMAP3_ISP_IOMEM_H3A, ISPH3A_AFCOEF1010);

	/* PCR Register */
	/* Set RGB Position */
	pcr = conf->rgb_pos << AF_RGBPOS_SHIFT;
	/* Set Accumulator Mode */
	if (conf->fvmode == OMAP3ISP_AF_MODE_PEAK)
		pcr |= AF_FVMODE;
	/* Set A-law */
	if (conf->alaw_enable)
		pcr |= AF_ALAW_EN;
	/* HMF Configurations */
	if (conf->hmf.enable) {
		/* Enable HMF */
		pcr |= AF_MED_EN;
		/* Set Median Threshold */
		pcr |= conf->hmf.threshold << AF_MED_TH_SHIFT;
	}
	/* Set PCR Register */
	isp_reg_clr_set(af->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR,
			AF_PCR_MASK, pcr);

	af->update = 0;
	af->config_counter += af->inc_config;
	af->inc_config = 0;
	af->buf_size = conf->buf_size;
}

static void h3a_af_enable(struct ispstat *af, int enable)
{
	if (enable) {
		isp_reg_set(af->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR,
			    ISPH3A_PCR_AF_EN);
		omap3isp_subclk_enable(af->isp, OMAP3_ISP_SUBCLK_AF);
	} else {
		isp_reg_clr(af->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR,
			    ISPH3A_PCR_AF_EN);
		omap3isp_subclk_disable(af->isp, OMAP3_ISP_SUBCLK_AF);
	}
}

static int h3a_af_busy(struct ispstat *af)
{
	return isp_reg_readl(af->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR)
						& ISPH3A_PCR_BUSYAF;
}

static u32 h3a_af_get_buf_size(struct omap3isp_h3a_af_config *conf)
{
	return conf->paxel.h_cnt * conf->paxel.v_cnt * OMAP3ISP_AF_PAXEL_SIZE;
}

/* Function to check paxel parameters */
static int h3a_af_validate_params(struct ispstat *af, void *new_conf)
{
	struct omap3isp_h3a_af_config *user_cfg = new_conf;
	struct omap3isp_h3a_af_paxel *paxel_cfg = &user_cfg->paxel;
	struct omap3isp_h3a_af_iir *iir_cfg = &user_cfg->iir;
	int index;
	u32 buf_size;

	/* Check horizontal Count */
	if (IS_OUT_OF_BOUNDS(paxel_cfg->h_cnt,
			     OMAP3ISP_AF_PAXEL_HORIZONTAL_COUNT_MIN,
			     OMAP3ISP_AF_PAXEL_HORIZONTAL_COUNT_MAX))
		return -EINVAL;

	/* Check Vertical Count */
	if (IS_OUT_OF_BOUNDS(paxel_cfg->v_cnt,
			     OMAP3ISP_AF_PAXEL_VERTICAL_COUNT_MIN,
			     OMAP3ISP_AF_PAXEL_VERTICAL_COUNT_MAX))
		return -EINVAL;

	if (IS_OUT_OF_BOUNDS(paxel_cfg->height, OMAP3ISP_AF_PAXEL_HEIGHT_MIN,
			     OMAP3ISP_AF_PAXEL_HEIGHT_MAX) ||
	    paxel_cfg->height % 2)
		return -EINVAL;

	/* Check width */
	if (IS_OUT_OF_BOUNDS(paxel_cfg->width, OMAP3ISP_AF_PAXEL_WIDTH_MIN,
			     OMAP3ISP_AF_PAXEL_WIDTH_MAX) ||
	    paxel_cfg->width % 2)
		return -EINVAL;

	/* Check Line Increment */
	if (IS_OUT_OF_BOUNDS(paxel_cfg->line_inc,
			     OMAP3ISP_AF_PAXEL_INCREMENT_MIN,
			     OMAP3ISP_AF_PAXEL_INCREMENT_MAX) ||
	    paxel_cfg->line_inc % 2)
		return -EINVAL;

	/* Check Horizontal Start */
	if ((paxel_cfg->h_start < iir_cfg->h_start) ||
	    IS_OUT_OF_BOUNDS(paxel_cfg->h_start,
			     OMAP3ISP_AF_PAXEL_HZSTART_MIN,
			     OMAP3ISP_AF_PAXEL_HZSTART_MAX))
		return -EINVAL;

	/* Check IIR */
	for (index = 0; index < OMAP3ISP_AF_NUM_COEF; index++) {
		if ((iir_cfg->coeff_set0[index]) > OMAP3ISP_AF_COEF_MAX)
			return -EINVAL;

		if ((iir_cfg->coeff_set1[index]) > OMAP3ISP_AF_COEF_MAX)
			return -EINVAL;
	}

	if (IS_OUT_OF_BOUNDS(iir_cfg->h_start, OMAP3ISP_AF_IIRSH_MIN,
			     OMAP3ISP_AF_IIRSH_MAX))
		return -EINVAL;

	/* Hack: If paxel size is 12, the 10th AF window may be corrupted */
	if ((paxel_cfg->h_cnt * paxel_cfg->v_cnt > 9) &&
	    (paxel_cfg->width * paxel_cfg->height == 12))
		return -EINVAL;

	buf_size = h3a_af_get_buf_size(user_cfg);
	if (buf_size > user_cfg->buf_size)
		/* User buf_size request wasn't enough */
		user_cfg->buf_size = buf_size;
	else if (user_cfg->buf_size > OMAP3ISP_AF_MAX_BUF_SIZE)
		user_cfg->buf_size = OMAP3ISP_AF_MAX_BUF_SIZE;

	return 0;
}

/* Update local parameters */
static void h3a_af_set_params(struct ispstat *af, void *new_conf)
{
	struct omap3isp_h3a_af_config *user_cfg = new_conf;
	struct omap3isp_h3a_af_config *cur_cfg = af->priv;
	int update = 0;
	int index;

	/* alaw */
	if (cur_cfg->alaw_enable != user_cfg->alaw_enable) {
		update = 1;
		goto out;
	}

	/* hmf */
	if (cur_cfg->hmf.enable != user_cfg->hmf.enable) {
		update = 1;
		goto out;
	}
	if (cur_cfg->hmf.threshold != user_cfg->hmf.threshold) {
		update = 1;
		goto out;
	}

	/* rgbpos */
	if (cur_cfg->rgb_pos != user_cfg->rgb_pos) {
		update = 1;
		goto out;
	}

	/* iir */
	if (cur_cfg->iir.h_start != user_cfg->iir.h_start) {
		update = 1;
		goto out;
	}
	for (index = 0; index < OMAP3ISP_AF_NUM_COEF; index++) {
		if (cur_cfg->iir.coeff_set0[index] !=
				user_cfg->iir.coeff_set0[index]) {
			update = 1;
			goto out;
		}
		if (cur_cfg->iir.coeff_set1[index] !=
				user_cfg->iir.coeff_set1[index]) {
			update = 1;
			goto out;
		}
	}

	/* paxel */
	if ((cur_cfg->paxel.width != user_cfg->paxel.width) ||
	    (cur_cfg->paxel.height != user_cfg->paxel.height) ||
	    (cur_cfg->paxel.h_start != user_cfg->paxel.h_start) ||
	    (cur_cfg->paxel.v_start != user_cfg->paxel.v_start) ||
	    (cur_cfg->paxel.h_cnt != user_cfg->paxel.h_cnt) ||
	    (cur_cfg->paxel.v_cnt != user_cfg->paxel.v_cnt) ||
	    (cur_cfg->paxel.line_inc != user_cfg->paxel.line_inc)) {
		update = 1;
		goto out;
	}

	/* af_mode */
	if (cur_cfg->fvmode != user_cfg->fvmode)
		update = 1;

out:
	if (update || !af->configured) {
		memcpy(cur_cfg, user_cfg, sizeof(*cur_cfg));
		af->inc_config++;
		af->update = 1;
		/*
		 * User might be asked for a bigger buffer than necessary for
		 * this configuration. In order to return the right amount of
		 * data during buffer request, let's calculate the size here
		 * instead of stick with user_cfg->buf_size.
		 */
		cur_cfg->buf_size = h3a_af_get_buf_size(cur_cfg);
	}
}

static long h3a_af_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
{
	struct ispstat *stat = v4l2_get_subdevdata(sd);

	switch (cmd) {
	case VIDIOC_OMAP3ISP_AF_CFG:
		return omap3isp_stat_config(stat, arg);
	case VIDIOC_OMAP3ISP_STAT_REQ:
		return omap3isp_stat_request_statistics(stat, arg);
	case VIDIOC_OMAP3ISP_STAT_EN: {
		int *en = arg;
		return omap3isp_stat_enable(stat, !!*en);
	}
	}

	return -ENOIOCTLCMD;

}

static const struct ispstat_ops h3a_af_ops = {
	.validate_params	= h3a_af_validate_params,
	.set_params		= h3a_af_set_params,
	.setup_regs		= h3a_af_setup_regs,
	.enable			= h3a_af_enable,
	.busy			= h3a_af_busy,
};

static const struct v4l2_subdev_core_ops h3a_af_subdev_core_ops = {
	.ioctl = h3a_af_ioctl,
	.subscribe_event = omap3isp_stat_subscribe_event,
	.unsubscribe_event = omap3isp_stat_unsubscribe_event,
};

static const struct v4l2_subdev_video_ops h3a_af_subdev_video_ops = {
	.s_stream = omap3isp_stat_s_stream,
};

static const struct v4l2_subdev_ops h3a_af_subdev_ops = {
	.core = &h3a_af_subdev_core_ops,
	.video = &h3a_af_subdev_video_ops,
};

/* Function to register the AF character device driver. */
int omap3isp_h3a_af_init(struct isp_device *isp)
{
	struct ispstat *af = &isp->isp_af;
	struct omap3isp_h3a_af_config *af_cfg;
	struct omap3isp_h3a_af_config *af_recover_cfg;

	af_cfg = devm_kzalloc(isp->dev, sizeof(*af_cfg), GFP_KERNEL);
	if (af_cfg == NULL)
		return -ENOMEM;

	af->ops = &h3a_af_ops;
	af->priv = af_cfg;
	af->event_type = V4L2_EVENT_OMAP3ISP_AF;
	af->isp = isp;

	/* Set recover state configuration */
	af_recover_cfg = devm_kzalloc(isp->dev, sizeof(*af_recover_cfg),
				      GFP_KERNEL);
	if (!af_recover_cfg) {
		dev_err(af->isp->dev, "AF: cannot allocate memory for recover "
				      "configuration.\n");
		return -ENOMEM;
	}

	af_recover_cfg->paxel.h_start = OMAP3ISP_AF_PAXEL_HZSTART_MIN;
	af_recover_cfg->paxel.width = OMAP3ISP_AF_PAXEL_WIDTH_MIN;
	af_recover_cfg->paxel.height = OMAP3ISP_AF_PAXEL_HEIGHT_MIN;
	af_recover_cfg->paxel.h_cnt = OMAP3ISP_AF_PAXEL_HORIZONTAL_COUNT_MIN;
	af_recover_cfg->paxel.v_cnt = OMAP3ISP_AF_PAXEL_VERTICAL_COUNT_MIN;
	af_recover_cfg->paxel.line_inc = OMAP3ISP_AF_PAXEL_INCREMENT_MIN;
	if (h3a_af_validate_params(af, af_recover_cfg)) {
		dev_err(af->isp->dev, "AF: recover configuration is "
				      "invalid.\n");
		return -EINVAL;
	}

	af_recover_cfg->buf_size = h3a_af_get_buf_size(af_recover_cfg);
	af->recover_priv = af_recover_cfg;

	return omap3isp_stat_init(af, "AF", &h3a_af_subdev_ops);
}

void omap3isp_h3a_af_cleanup(struct isp_device *isp)
{
	omap3isp_stat_cleanup(&isp->isp_af);
}
