/*
 * Samsung LSI S5C73M3 8M pixel camera driver
 *
 * Copyright (C) 2012, Samsung Electronics, Co., Ltd.
 * Sylwester Nawrocki <s.nawrocki@samsung.com>
 * Andrzej Hajda <a.hajda@samsung.com>
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/sizes.h>
#include <linux/delay.h>
#include <linux/firmware.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/media.h>
#include <linux/module.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/spi/spi.h>
#include <linux/videodev2.h>
#include <media/media-entity.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-subdev.h>
#include <media/v4l2-mediabus.h>
#include <media/s5c73m3.h>

#include "s5c73m3.h"

static int s5c73m3_get_af_status(struct s5c73m3 *state, struct v4l2_ctrl *ctrl)
{
	u16 reg = REG_AF_STATUS_UNFOCUSED;

	int ret = s5c73m3_read(state, REG_AF_STATUS, &reg);

	switch (reg) {
	case REG_CAF_STATUS_FIND_SEARCH_DIR:
	case REG_AF_STATUS_FOCUSING:
	case REG_CAF_STATUS_FOCUSING:
		ctrl->val = V4L2_AUTO_FOCUS_STATUS_BUSY;
		break;
	case REG_CAF_STATUS_FOCUSED:
	case REG_AF_STATUS_FOCUSED:
		ctrl->val = V4L2_AUTO_FOCUS_STATUS_REACHED;
		break;
	default:
		v4l2_info(&state->sensor_sd, "Unknown AF status %#x\n", reg);
		/* Fall through */
	case REG_CAF_STATUS_UNFOCUSED:
	case REG_AF_STATUS_UNFOCUSED:
	case REG_AF_STATUS_INVALID:
		ctrl->val = V4L2_AUTO_FOCUS_STATUS_FAILED;
		break;
	}

	return ret;
}

static int s5c73m3_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
{
	struct v4l2_subdev *sd = ctrl_to_sensor_sd(ctrl);
	struct s5c73m3 *state = sensor_sd_to_s5c73m3(sd);
	int ret;

	if (state->power == 0)
		return -EBUSY;

	switch (ctrl->id) {
	case V4L2_CID_FOCUS_AUTO:
		ret = s5c73m3_get_af_status(state, state->ctrls.af_status);
		if (ret)
			return ret;
		break;
	}

	return 0;
}

static int s5c73m3_set_colorfx(struct s5c73m3 *state, int val)
{
	static const unsigned short colorfx[][2] = {
		{ V4L2_COLORFX_NONE,	 COMM_IMAGE_EFFECT_NONE },
		{ V4L2_COLORFX_BW,	 COMM_IMAGE_EFFECT_MONO },
		{ V4L2_COLORFX_SEPIA,	 COMM_IMAGE_EFFECT_SEPIA },
		{ V4L2_COLORFX_NEGATIVE, COMM_IMAGE_EFFECT_NEGATIVE },
		{ V4L2_COLORFX_AQUA,	 COMM_IMAGE_EFFECT_AQUA },
	};
	int i;

	for (i = 0; i < ARRAY_SIZE(colorfx); i++) {
		if (colorfx[i][0] != val)
			continue;

		v4l2_dbg(1, s5c73m3_dbg, &state->sensor_sd,
			 "Setting %s color effect\n",
			 v4l2_ctrl_get_menu(state->ctrls.colorfx->id)[i]);

		return s5c73m3_isp_command(state, COMM_IMAGE_EFFECT,
					 colorfx[i][1]);
	}
	return -EINVAL;
}

/* Set exposure metering/exposure bias */
static int s5c73m3_set_exposure(struct s5c73m3 *state, int auto_exp)
{
	struct v4l2_subdev *sd = &state->sensor_sd;
	struct s5c73m3_ctrls *ctrls = &state->ctrls;
	int ret = 0;

	if (ctrls->exposure_metering->is_new) {
		u16 metering;

		switch (ctrls->exposure_metering->val) {
		case V4L2_EXPOSURE_METERING_CENTER_WEIGHTED:
			metering = COMM_METERING_CENTER;
			break;
		case V4L2_EXPOSURE_METERING_SPOT:
			metering = COMM_METERING_SPOT;
			break;
		default:
			metering = COMM_METERING_AVERAGE;
			break;
		}

		ret = s5c73m3_isp_command(state, COMM_METERING, metering);
	}

	if (!ret && ctrls->exposure_bias->is_new) {
		u16 exp_bias = ctrls->exposure_bias->val;
		ret = s5c73m3_isp_command(state, COMM_EV, exp_bias);
	}

	v4l2_dbg(1, s5c73m3_dbg, sd,
		 "%s: exposure bias: %#x, metering: %#x (%d)\n",  __func__,
		 ctrls->exposure_bias->val, ctrls->exposure_metering->val, ret);

	return ret;
}

static int s5c73m3_set_white_balance(struct s5c73m3 *state, int val)
{
	static const unsigned short wb[][2] = {
		{ V4L2_WHITE_BALANCE_INCANDESCENT,  COMM_AWB_MODE_INCANDESCENT},
		{ V4L2_WHITE_BALANCE_FLUORESCENT,   COMM_AWB_MODE_FLUORESCENT1},
		{ V4L2_WHITE_BALANCE_FLUORESCENT_H, COMM_AWB_MODE_FLUORESCENT2},
		{ V4L2_WHITE_BALANCE_CLOUDY,        COMM_AWB_MODE_CLOUDY},
		{ V4L2_WHITE_BALANCE_DAYLIGHT,      COMM_AWB_MODE_DAYLIGHT},
		{ V4L2_WHITE_BALANCE_AUTO,          COMM_AWB_MODE_AUTO},
	};
	int i;

	for (i = 0; i < ARRAY_SIZE(wb); i++) {
		if (wb[i][0] != val)
			continue;

		v4l2_dbg(1, s5c73m3_dbg, &state->sensor_sd,
			 "Setting white balance to: %s\n",
			 v4l2_ctrl_get_menu(state->ctrls.auto_wb->id)[i]);

		return s5c73m3_isp_command(state, COMM_AWB_MODE, wb[i][1]);
	}

	return -EINVAL;
}

static int s5c73m3_af_run(struct s5c73m3 *state, bool on)
{
	struct s5c73m3_ctrls *c = &state->ctrls;

	if (!on)
		return s5c73m3_isp_command(state, COMM_AF_CON,
							COMM_AF_CON_STOP);

	if (c->focus_auto->val)
		return s5c73m3_isp_command(state, COMM_AF_MODE,
					   COMM_AF_MODE_PREVIEW_CAF_START);

	return s5c73m3_isp_command(state, COMM_AF_CON, COMM_AF_CON_START);
}

static int s5c73m3_3a_lock(struct s5c73m3 *state, struct v4l2_ctrl *ctrl)
{
	bool awb_lock = ctrl->val & V4L2_LOCK_WHITE_BALANCE;
	bool ae_lock = ctrl->val & V4L2_LOCK_EXPOSURE;
	bool af_lock = ctrl->val & V4L2_LOCK_FOCUS;
	int ret = 0;

	if ((ctrl->val ^ ctrl->cur.val) & V4L2_LOCK_EXPOSURE) {
		ret = s5c73m3_isp_command(state, COMM_AE_CON,
				ae_lock ? COMM_AE_STOP : COMM_AE_START);
		if (ret)
			return ret;
	}

	if (((ctrl->val ^ ctrl->cur.val) & V4L2_LOCK_WHITE_BALANCE)
	    && state->ctrls.auto_wb->val) {
		ret = s5c73m3_isp_command(state, COMM_AWB_CON,
			awb_lock ? COMM_AWB_STOP : COMM_AWB_START);
		if (ret)
			return ret;
	}

	if ((ctrl->val ^ ctrl->cur.val) & V4L2_LOCK_FOCUS)
		ret = s5c73m3_af_run(state, ~af_lock);

	return ret;
}

static int s5c73m3_set_auto_focus(struct s5c73m3 *state, int caf)
{
	struct s5c73m3_ctrls *c = &state->ctrls;
	int ret = 1;

	if (c->af_distance->is_new) {
		u16 mode = (c->af_distance->val == V4L2_AUTO_FOCUS_RANGE_MACRO)
				? COMM_AF_MODE_MACRO : COMM_AF_MODE_NORMAL;
		ret = s5c73m3_isp_command(state, COMM_AF_MODE, mode);
		if (ret != 0)
			return ret;
	}

	if (!ret || (c->focus_auto->is_new && c->focus_auto->val) ||
							c->af_start->is_new)
		ret = s5c73m3_af_run(state, 1);
	else if ((c->focus_auto->is_new && !c->focus_auto->val) ||
							c->af_stop->is_new)
		ret = s5c73m3_af_run(state, 0);
	else
		ret = 0;

	return ret;
}

static int s5c73m3_set_contrast(struct s5c73m3 *state, int val)
{
	u16 reg = (val < 0) ? -val + 2 : val;
	return s5c73m3_isp_command(state, COMM_CONTRAST, reg);
}

static int s5c73m3_set_saturation(struct s5c73m3 *state, int val)
{
	u16 reg = (val < 0) ? -val + 2 : val;
	return s5c73m3_isp_command(state, COMM_SATURATION, reg);
}

static int s5c73m3_set_sharpness(struct s5c73m3 *state, int val)
{
	u16 reg = (val < 0) ? -val + 2 : val;
	return s5c73m3_isp_command(state, COMM_SHARPNESS, reg);
}

static int s5c73m3_set_iso(struct s5c73m3 *state, int val)
{
	u32 iso;

	if (val == V4L2_ISO_SENSITIVITY_MANUAL)
		iso = state->ctrls.iso->val + 1;
	else
		iso = 0;

	return s5c73m3_isp_command(state, COMM_ISO, iso);
}

static int s5c73m3_set_stabilization(struct s5c73m3 *state, int val)
{
	struct v4l2_subdev *sd = &state->sensor_sd;

	v4l2_dbg(1, s5c73m3_dbg, sd, "Image stabilization: %d\n", val);

	return s5c73m3_isp_command(state, COMM_FRAME_RATE, val ?
			COMM_FRAME_RATE_ANTI_SHAKE : COMM_FRAME_RATE_AUTO_SET);
}

static int s5c73m3_set_jpeg_quality(struct s5c73m3 *state, int quality)
{
	int reg;

	if (quality <= 65)
		reg = COMM_IMAGE_QUALITY_NORMAL;
	else if (quality <= 75)
		reg = COMM_IMAGE_QUALITY_FINE;
	else
		reg = COMM_IMAGE_QUALITY_SUPERFINE;

	return s5c73m3_isp_command(state, COMM_IMAGE_QUALITY, reg);
}

static int s5c73m3_set_scene_program(struct s5c73m3 *state, int val)
{
	static const unsigned short scene_lookup[] = {
		COMM_SCENE_MODE_NONE,	     /* V4L2_SCENE_MODE_NONE */
		COMM_SCENE_MODE_AGAINST_LIGHT,/* V4L2_SCENE_MODE_BACKLIGHT */
		COMM_SCENE_MODE_BEACH,	     /* V4L2_SCENE_MODE_BEACH_SNOW */
		COMM_SCENE_MODE_CANDLE,	     /* V4L2_SCENE_MODE_CANDLE_LIGHT */
		COMM_SCENE_MODE_DAWN,	     /* V4L2_SCENE_MODE_DAWN_DUSK */
		COMM_SCENE_MODE_FALL,	     /* V4L2_SCENE_MODE_FALL_COLORS */
		COMM_SCENE_MODE_FIRE,	     /* V4L2_SCENE_MODE_FIREWORKS */
		COMM_SCENE_MODE_LANDSCAPE,    /* V4L2_SCENE_MODE_LANDSCAPE */
		COMM_SCENE_MODE_NIGHT,	     /* V4L2_SCENE_MODE_NIGHT */
		COMM_SCENE_MODE_INDOOR,	     /* V4L2_SCENE_MODE_PARTY_INDOOR */
		COMM_SCENE_MODE_PORTRAIT,     /* V4L2_SCENE_MODE_PORTRAIT */
		COMM_SCENE_MODE_SPORTS,	     /* V4L2_SCENE_MODE_SPORTS */
		COMM_SCENE_MODE_SUNSET,	     /* V4L2_SCENE_MODE_SUNSET */
		COMM_SCENE_MODE_TEXT,	     /* V4L2_SCENE_MODE_TEXT */
	};

	v4l2_dbg(1, s5c73m3_dbg, &state->sensor_sd, "Setting %s scene mode\n",
		 v4l2_ctrl_get_menu(state->ctrls.scene_mode->id)[val]);

	return s5c73m3_isp_command(state, COMM_SCENE_MODE, scene_lookup[val]);
}

static int s5c73m3_set_power_line_freq(struct s5c73m3 *state, int val)
{
	unsigned int pwr_line_freq = COMM_FLICKER_NONE;

	switch (val) {
	case V4L2_CID_POWER_LINE_FREQUENCY_DISABLED:
		pwr_line_freq = COMM_FLICKER_NONE;
		break;
	case V4L2_CID_POWER_LINE_FREQUENCY_50HZ:
		pwr_line_freq = COMM_FLICKER_AUTO_50HZ;
		break;
	case V4L2_CID_POWER_LINE_FREQUENCY_60HZ:
		pwr_line_freq = COMM_FLICKER_AUTO_60HZ;
		break;
	default:
	case V4L2_CID_POWER_LINE_FREQUENCY_AUTO:
		pwr_line_freq = COMM_FLICKER_NONE;
	}

	return s5c73m3_isp_command(state, COMM_FLICKER_MODE, pwr_line_freq);
}

static int s5c73m3_s_ctrl(struct v4l2_ctrl *ctrl)
{
	struct v4l2_subdev *sd = ctrl_to_sensor_sd(ctrl);
	struct s5c73m3 *state = sensor_sd_to_s5c73m3(sd);
	int ret = 0;

	v4l2_dbg(1, s5c73m3_dbg, sd, "set_ctrl: %s, value: %d\n",
		 ctrl->name, ctrl->val);

	mutex_lock(&state->lock);
	/*
	 * If the device is not powered up by the host driver do
	 * not apply any controls to H/W at this time. Instead
	 * the controls will be restored right after power-up.
	 */
	if (state->power == 0)
		goto unlock;

	if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE) {
		ret = -EINVAL;
		goto unlock;
	}

	switch (ctrl->id) {
	case V4L2_CID_3A_LOCK:
		ret = s5c73m3_3a_lock(state, ctrl);
		break;

	case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
		ret = s5c73m3_set_white_balance(state, ctrl->val);
		break;

	case V4L2_CID_CONTRAST:
		ret = s5c73m3_set_contrast(state, ctrl->val);
		break;

	case V4L2_CID_COLORFX:
		ret = s5c73m3_set_colorfx(state, ctrl->val);
		break;

	case V4L2_CID_EXPOSURE_AUTO:
		ret = s5c73m3_set_exposure(state, ctrl->val);
		break;

	case V4L2_CID_FOCUS_AUTO:
		ret = s5c73m3_set_auto_focus(state, ctrl->val);
		break;

	case V4L2_CID_IMAGE_STABILIZATION:
		ret = s5c73m3_set_stabilization(state, ctrl->val);
		break;

	case V4L2_CID_ISO_SENSITIVITY:
		ret = s5c73m3_set_iso(state, ctrl->val);
		break;

	case V4L2_CID_JPEG_COMPRESSION_QUALITY:
		ret = s5c73m3_set_jpeg_quality(state, ctrl->val);
		break;

	case V4L2_CID_POWER_LINE_FREQUENCY:
		ret = s5c73m3_set_power_line_freq(state, ctrl->val);
		break;

	case V4L2_CID_SATURATION:
		ret = s5c73m3_set_saturation(state, ctrl->val);
		break;

	case V4L2_CID_SCENE_MODE:
		ret = s5c73m3_set_scene_program(state, ctrl->val);
		break;

	case V4L2_CID_SHARPNESS:
		ret = s5c73m3_set_sharpness(state, ctrl->val);
		break;

	case V4L2_CID_WIDE_DYNAMIC_RANGE:
		ret = s5c73m3_isp_command(state, COMM_WDR, !!ctrl->val);
		break;

	case V4L2_CID_ZOOM_ABSOLUTE:
		ret = s5c73m3_isp_command(state, COMM_ZOOM_STEP, ctrl->val);
		break;
	}
unlock:
	mutex_unlock(&state->lock);
	return ret;
}

static const struct v4l2_ctrl_ops s5c73m3_ctrl_ops = {
	.g_volatile_ctrl	= s5c73m3_g_volatile_ctrl,
	.s_ctrl			= s5c73m3_s_ctrl,
};

/* Supported manual ISO values */
static const s64 iso_qmenu[] = {
	/* COMM_ISO: 0x0001...0x0004 */
	100, 200, 400, 800,
};

/* Supported exposure bias values (-2.0EV...+2.0EV) */
static const s64 ev_bias_qmenu[] = {
	/* COMM_EV: 0x0000...0x0008 */
	-2000, -1500, -1000, -500, 0, 500, 1000, 1500, 2000
};

int s5c73m3_init_controls(struct s5c73m3 *state)
{
	const struct v4l2_ctrl_ops *ops = &s5c73m3_ctrl_ops;
	struct s5c73m3_ctrls *ctrls = &state->ctrls;
	struct v4l2_ctrl_handler *hdl = &ctrls->handler;

	int ret = v4l2_ctrl_handler_init(hdl, 22);
	if (ret)
		return ret;

	/* White balance */
	ctrls->auto_wb = v4l2_ctrl_new_std_menu(hdl, ops,
			V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE,
			9, ~0x15e, V4L2_WHITE_BALANCE_AUTO);

	/* Exposure (only automatic exposure) */
	ctrls->auto_exposure = v4l2_ctrl_new_std_menu(hdl, ops,
			V4L2_CID_EXPOSURE_AUTO, 0, ~0x01, V4L2_EXPOSURE_AUTO);

	ctrls->exposure_bias = v4l2_ctrl_new_int_menu(hdl, ops,
			V4L2_CID_AUTO_EXPOSURE_BIAS,
			ARRAY_SIZE(ev_bias_qmenu) - 1,
			ARRAY_SIZE(ev_bias_qmenu)/2 - 1,
			ev_bias_qmenu);

	ctrls->exposure_metering = v4l2_ctrl_new_std_menu(hdl, ops,
			V4L2_CID_EXPOSURE_METERING,
			2, ~0x7, V4L2_EXPOSURE_METERING_AVERAGE);

	/* Auto focus */
	ctrls->focus_auto = v4l2_ctrl_new_std(hdl, ops,
			V4L2_CID_FOCUS_AUTO, 0, 1, 1, 0);

	ctrls->af_start = v4l2_ctrl_new_std(hdl, ops,
			V4L2_CID_AUTO_FOCUS_START, 0, 1, 1, 0);

	ctrls->af_stop = v4l2_ctrl_new_std(hdl, ops,
			V4L2_CID_AUTO_FOCUS_STOP, 0, 1, 1, 0);

	ctrls->af_status = v4l2_ctrl_new_std(hdl, ops,
			V4L2_CID_AUTO_FOCUS_STATUS, 0,
			(V4L2_AUTO_FOCUS_STATUS_BUSY |
			 V4L2_AUTO_FOCUS_STATUS_REACHED |
			 V4L2_AUTO_FOCUS_STATUS_FAILED),
			0, V4L2_AUTO_FOCUS_STATUS_IDLE);

	ctrls->af_distance = v4l2_ctrl_new_std_menu(hdl, ops,
			V4L2_CID_AUTO_FOCUS_RANGE,
			V4L2_AUTO_FOCUS_RANGE_MACRO,
			~(1 << V4L2_AUTO_FOCUS_RANGE_NORMAL |
			  1 << V4L2_AUTO_FOCUS_RANGE_MACRO),
			V4L2_AUTO_FOCUS_RANGE_NORMAL);
	/* ISO sensitivity */
	ctrls->auto_iso = v4l2_ctrl_new_std_menu(hdl, ops,
			V4L2_CID_ISO_SENSITIVITY_AUTO, 1, 0,
			V4L2_ISO_SENSITIVITY_AUTO);

	ctrls->iso = v4l2_ctrl_new_int_menu(hdl, ops,
			V4L2_CID_ISO_SENSITIVITY, ARRAY_SIZE(iso_qmenu) - 1,
			ARRAY_SIZE(iso_qmenu)/2 - 1, iso_qmenu);

	ctrls->contrast = v4l2_ctrl_new_std(hdl, ops,
			V4L2_CID_CONTRAST, -2, 2, 1, 0);

	ctrls->saturation = v4l2_ctrl_new_std(hdl, ops,
			V4L2_CID_SATURATION, -2, 2, 1, 0);

	ctrls->sharpness = v4l2_ctrl_new_std(hdl, ops,
			V4L2_CID_SHARPNESS, -2, 2, 1, 0);

	ctrls->zoom = v4l2_ctrl_new_std(hdl, ops,
			V4L2_CID_ZOOM_ABSOLUTE, 0, 30, 1, 0);

	ctrls->colorfx = v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_COLORFX,
			V4L2_COLORFX_AQUA, ~0x40f, V4L2_COLORFX_NONE);

	ctrls->wdr = v4l2_ctrl_new_std(hdl, ops,
			V4L2_CID_WIDE_DYNAMIC_RANGE, 0, 1, 1, 0);

	ctrls->stabilization = v4l2_ctrl_new_std(hdl, ops,
			V4L2_CID_IMAGE_STABILIZATION, 0, 1, 1, 0);

	v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_POWER_LINE_FREQUENCY,
			       V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0,
			       V4L2_CID_POWER_LINE_FREQUENCY_AUTO);

	ctrls->jpeg_quality = v4l2_ctrl_new_std(hdl, ops,
			V4L2_CID_JPEG_COMPRESSION_QUALITY, 1, 100, 1, 80);

	ctrls->scene_mode = v4l2_ctrl_new_std_menu(hdl, ops,
			V4L2_CID_SCENE_MODE, V4L2_SCENE_MODE_TEXT, ~0x3fff,
			V4L2_SCENE_MODE_NONE);

	ctrls->aaa_lock = v4l2_ctrl_new_std(hdl, ops,
			V4L2_CID_3A_LOCK, 0, 0x7, 0, 0);

	if (hdl->error) {
		ret = hdl->error;
		v4l2_ctrl_handler_free(hdl);
		return ret;
	}

	v4l2_ctrl_auto_cluster(3, &ctrls->auto_exposure, 0, false);
	ctrls->auto_iso->flags |= V4L2_CTRL_FLAG_VOLATILE |
				V4L2_CTRL_FLAG_UPDATE;
	v4l2_ctrl_auto_cluster(2, &ctrls->auto_iso, 0, false);
	ctrls->af_status->flags |= V4L2_CTRL_FLAG_VOLATILE;
	v4l2_ctrl_cluster(6, &ctrls->focus_auto);

	state->sensor_sd.ctrl_handler = hdl;

	return 0;
}
