/*
 * wm8739
 *
 * Copyright (C) 2005 T. Adachi <tadachi@tadachi-net.com>
 *
 * Copyright (C) 2005 Hans Verkuil <hverkuil@xs4all.nl>
 * - Cleanup
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <linux/module.h>
#include <linux/types.h>
#include <linux/ioctl.h>
#include <asm/uaccess.h>
#include <linux/i2c.h>
#include <linux/i2c-id.h>
#include <linux/videodev.h>
#include <media/v4l2-common.h>
#include <media/v4l2-chip-ident.h>
#include <media/v4l2-i2c-drv.h>

MODULE_DESCRIPTION("wm8739 driver");
MODULE_AUTHOR("T. Adachi, Hans Verkuil");
MODULE_LICENSE("GPL");

static int debug;

module_param(debug, int, 0644);

MODULE_PARM_DESC(debug, "Debug level (0-1)");


/* ------------------------------------------------------------------------ */

enum {
	R0 = 0, R1,
	R5 = 5, R6, R7, R8, R9, R15 = 15,
	TOT_REGS
};

struct wm8739_state {
	u32 clock_freq;
	u8 muted;
	u16 volume;
	u16 balance;
	u8 vol_l; 		/* +12dB to -34.5dB 1.5dB step (5bit) def:0dB */
	u8 vol_r; 		/* +12dB to -34.5dB 1.5dB step (5bit) def:0dB */
};

/* ------------------------------------------------------------------------ */

static int wm8739_write(struct i2c_client *client, int reg, u16 val)
{
	int i;

	if (reg < 0 || reg >= TOT_REGS) {
		v4l_err(client, "Invalid register R%d\n", reg);
		return -1;
	}

	v4l_dbg(1, debug, client, "write: %02x %02x\n", reg, val);

	for (i = 0; i < 3; i++)
		if (i2c_smbus_write_byte_data(client,
				(reg << 1) | (val >> 8), val & 0xff) == 0)
			return 0;
	v4l_err(client, "I2C: cannot write %03x to register R%d\n", val, reg);
	return -1;
}

/* write regs to set audio volume etc */
static void wm8739_set_audio(struct i2c_client *client)
{
	struct wm8739_state *state = i2c_get_clientdata(client);
	u16 mute = state->muted ? 0x80 : 0;

	/* Volume setting: bits 0-4, 0x1f = 12 dB, 0x00 = -34.5 dB
	 * Default setting: 0x17 = 0 dB
	 */
	wm8739_write(client, R0, (state->vol_l & 0x1f) | mute);
	wm8739_write(client, R1, (state->vol_r & 0x1f) | mute);
}

static int wm8739_get_ctrl(struct i2c_client *client, struct v4l2_control *ctrl)
{
	struct wm8739_state *state = i2c_get_clientdata(client);

	switch (ctrl->id) {
	case V4L2_CID_AUDIO_MUTE:
		ctrl->value = state->muted;
		break;

	case V4L2_CID_AUDIO_VOLUME:
		ctrl->value = state->volume;
		break;

	case V4L2_CID_AUDIO_BALANCE:
		ctrl->value = state->balance;
		break;

	default:
		return -EINVAL;
	}
	return 0;
}

static int wm8739_set_ctrl(struct i2c_client *client, struct v4l2_control *ctrl)
{
	struct wm8739_state *state = i2c_get_clientdata(client);
	unsigned int work_l, work_r;

	switch (ctrl->id) {
	case V4L2_CID_AUDIO_MUTE:
		state->muted = ctrl->value;
		break;

	case V4L2_CID_AUDIO_VOLUME:
		state->volume = ctrl->value;
		break;

	case V4L2_CID_AUDIO_BALANCE:
		state->balance = ctrl->value;
		break;

	default:
		return -EINVAL;
	}

	/* normalize ( 65535 to 0 -> 31 to 0 (12dB to -34.5dB) ) */
	work_l = (min(65536 - state->balance, 32768) * state->volume) / 32768;
	work_r = (min(state->balance, (u16)32768) * state->volume) / 32768;

	state->vol_l = (long)work_l * 31 / 65535;
	state->vol_r = (long)work_r * 31 / 65535;

	/* set audio volume etc. */
	wm8739_set_audio(client);
	return 0;
}

/* ------------------------------------------------------------------------ */

static struct v4l2_queryctrl wm8739_qctrl[] = {
	{
		.id            = V4L2_CID_AUDIO_VOLUME,
		.name          = "Volume",
		.minimum       = 0,
		.maximum       = 65535,
		.step          = 65535/100,
		.default_value = 58880,
		.flags         = 0,
		.type          = V4L2_CTRL_TYPE_INTEGER,
	}, {
		.id            = V4L2_CID_AUDIO_MUTE,
		.name          = "Mute",
		.minimum       = 0,
		.maximum       = 1,
		.step          = 1,
		.default_value = 1,
		.flags         = 0,
		.type          = V4L2_CTRL_TYPE_BOOLEAN,
	}, {
		.id            = V4L2_CID_AUDIO_BALANCE,
		.name          = "Balance",
		.minimum       = 0,
		.maximum       = 65535,
		.step          = 65535/100,
		.default_value = 32768,
		.flags         = 0,
		.type          = V4L2_CTRL_TYPE_INTEGER,
	}
};

/* ------------------------------------------------------------------------ */

static int wm8739_command(struct i2c_client *client, unsigned cmd, void *arg)
{
	struct wm8739_state *state = i2c_get_clientdata(client);

	switch (cmd) {
	case VIDIOC_INT_AUDIO_CLOCK_FREQ:
	{
		u32 audiofreq = *(u32 *)arg;

		state->clock_freq = audiofreq;
		/* de-activate */
		wm8739_write(client, R9, 0x000);
		switch (audiofreq) {
		case 44100:
			/* 256fps, fs=44.1k */
			wm8739_write(client, R8, 0x020);
			break;
		case 48000:
			/* 256fps, fs=48k */
			wm8739_write(client, R8, 0x000);
			break;
		case 32000:
			/* 256fps, fs=32k */
			wm8739_write(client, R8, 0x018);
			break;
		default:
			break;
		}
		/* activate */
		wm8739_write(client, R9, 0x001);
		break;
	}

	case VIDIOC_G_CTRL:
		return wm8739_get_ctrl(client, arg);

	case VIDIOC_S_CTRL:
		return wm8739_set_ctrl(client, arg);

	case VIDIOC_QUERYCTRL:
	{
		struct v4l2_queryctrl *qc = arg;
		int i;

		for (i = 0; i < ARRAY_SIZE(wm8739_qctrl); i++)
			if (qc->id && qc->id == wm8739_qctrl[i].id) {
				memcpy(qc, &wm8739_qctrl[i], sizeof(*qc));
				return 0;
			}
		return -EINVAL;
	}

	case VIDIOC_G_CHIP_IDENT:
		return v4l2_chip_ident_i2c_client(client,
				arg, V4L2_IDENT_WM8739, 0);

	case VIDIOC_LOG_STATUS:
		v4l_info(client, "Frequency: %u Hz\n", state->clock_freq);
		v4l_info(client, "Volume L:  %02x%s\n", state->vol_l & 0x1f,
				state->muted ? " (muted)" : "");
		v4l_info(client, "Volume R:  %02x%s\n", state->vol_r & 0x1f,
				state->muted ? " (muted)" : "");
		break;

	default:
		return -EINVAL;
	}

	return 0;
}

/* ------------------------------------------------------------------------ */

/* i2c implementation */

static int wm8739_probe(struct i2c_client *client)
{
	struct wm8739_state *state;

	/* Check if the adapter supports the needed features */
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
		return -EIO;

	v4l_info(client, "chip found @ 0x%x (%s)\n",
			client->addr << 1, client->adapter->name);

	state = kmalloc(sizeof(struct wm8739_state), GFP_KERNEL);
	if (state == NULL) {
		kfree(client);
		return -ENOMEM;
	}
	state->vol_l = 0x17; /* 0dB */
	state->vol_r = 0x17; /* 0dB */
	state->muted = 0;
	state->balance = 32768;
	/* normalize (12dB(31) to -34.5dB(0) [0dB(23)] -> 65535 to 0) */
	state->volume = ((long)state->vol_l + 1) * 65535 / 31;
	state->clock_freq = 48000;
	i2c_set_clientdata(client, state);

	/* Initialize wm8739 */

	/* reset */
	wm8739_write(client, R15, 0x00);
	/* filter setting, high path, offet clear */
	wm8739_write(client, R5, 0x000);
	/* ADC, OSC, Power Off mode Disable */
	wm8739_write(client, R6, 0x000);
	/* Digital Audio interface format:
	   Enable Master mode, 24 bit, MSB first/left justified */
	wm8739_write(client, R7, 0x049);
	/* sampling control: normal, 256fs, 48KHz sampling rate */
	wm8739_write(client, R8, 0x000);
	/* activate */
	wm8739_write(client, R9, 0x001);
	/* set volume/mute */
	wm8739_set_audio(client);
	return 0;
}

static int wm8739_remove(struct i2c_client *client)
{
	kfree(i2c_get_clientdata(client));
	return 0;
}

static struct v4l2_i2c_driver_data v4l2_i2c_data = {
	.name = "wm8739",
	.driverid = I2C_DRIVERID_WM8739,
	.command = wm8739_command,
	.probe = wm8739_probe,
	.remove = wm8739_remove,
};

