/*
 *  cx18 I2C functions
 *
 *  Derived from ivtv-i2c.c
 *
 *  Copyright (C) 2007  Hans Verkuil <hverkuil@xs4all.nl>
 *
 *  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., 59 Temple Place, Suite 330, Boston, MA
 *  02111-1307  USA
 */

#include "cx18-driver.h"
#include "cx18-cards.h"
#include "cx18-gpio.h"
#include "cx18-av-core.h"

#include <media/ir-kbd-i2c.h>

#define CX18_REG_I2C_1_WR   0xf15000
#define CX18_REG_I2C_1_RD   0xf15008
#define CX18_REG_I2C_2_WR   0xf25100
#define CX18_REG_I2C_2_RD   0xf25108

#define SETSCL_BIT      0x0001
#define SETSDL_BIT      0x0002
#define GETSCL_BIT      0x0004
#define GETSDL_BIT      0x0008

#ifndef I2C_ADAP_CLASS_TV_ANALOG
#define I2C_ADAP_CLASS_TV_ANALOG I2C_CLASS_TV_ANALOG
#endif

#define CX18_CS5345_I2C_ADDR		0x4c

/* This array should match the CX18_HW_ defines */
static const u8 hw_driverids[] = {
	I2C_DRIVERID_TUNER,
	I2C_DRIVERID_TVEEPROM,
	I2C_DRIVERID_CS5345,
	0, 		/* CX18_HW_GPIO dummy driver ID */
	0 		/* CX18_HW_CX23418 dummy driver ID */
};

/* This array should match the CX18_HW_ defines */
static const u8 hw_addrs[] = {
	0,
	0,
	CX18_CS5345_I2C_ADDR,
	0, 		/* CX18_HW_GPIO dummy driver ID */
	0,		/* CX18_HW_CX23418 dummy driver ID */
};

/* This array should match the CX18_HW_ defines */
/* This might well become a card-specific array */
static const u8 hw_bus[] = {
	0,
	0,
	0,
	0, 		/* CX18_HW_GPIO dummy driver ID */
	0,		/* CX18_HW_CX23418 dummy driver ID */
};

/* This array should match the CX18_HW_ defines */
static const char * const hw_drivernames[] = {
	"tuner",
	"tveeprom",
	"cs5345",
	"gpio",
	"cx23418",
};

int cx18_i2c_register(struct cx18 *cx, unsigned idx)
{
	struct i2c_board_info info;
	struct i2c_client *c;
	u8 id, bus;
	int i;

	CX18_DEBUG_I2C("i2c client register\n");
	if (idx >= ARRAY_SIZE(hw_driverids) || hw_driverids[idx] == 0)
		return -1;
	id = hw_driverids[idx];
	bus = hw_bus[idx];
	memset(&info, 0, sizeof(info));
	strlcpy(info.driver_name, hw_drivernames[idx],
			sizeof(info.driver_name));
	info.addr = hw_addrs[idx];
	for (i = 0; i < I2C_CLIENTS_MAX; i++)
		if (cx->i2c_clients[i] == NULL)
			break;

	if (i == I2C_CLIENTS_MAX) {
		CX18_ERR("insufficient room for new I2C client!\n");
		return -ENOMEM;
	}

	if (id != I2C_DRIVERID_TUNER) {
		c = i2c_new_device(&cx->i2c_adap[bus], &info);
		if (c->driver == NULL)
			i2c_unregister_device(c);
		else
			cx->i2c_clients[i] = c;
		return cx->i2c_clients[i] ? 0 : -ENODEV;
	}

	/* special tuner handling */
	c = i2c_new_probed_device(&cx->i2c_adap[1], &info, cx->card_i2c->radio);
	if (c && c->driver == NULL)
		i2c_unregister_device(c);
	else if (c)
		cx->i2c_clients[i++] = c;
	c = i2c_new_probed_device(&cx->i2c_adap[1], &info, cx->card_i2c->demod);
	if (c && c->driver == NULL)
		i2c_unregister_device(c);
	else if (c)
		cx->i2c_clients[i++] = c;
	c = i2c_new_probed_device(&cx->i2c_adap[1], &info, cx->card_i2c->tv);
	if (c && c->driver == NULL)
		i2c_unregister_device(c);
	else if (c)
		cx->i2c_clients[i++] = c;
	return 0;
}

static int attach_inform(struct i2c_client *client)
{
	return 0;
}

static int detach_inform(struct i2c_client *client)
{
	int i;
	struct cx18 *cx = (struct cx18 *)i2c_get_adapdata(client->adapter);

	CX18_DEBUG_I2C("i2c client detach\n");
	for (i = 0; i < I2C_CLIENTS_MAX; i++) {
		if (cx->i2c_clients[i] == client) {
			cx->i2c_clients[i] = NULL;
			break;
		}
	}
	CX18_DEBUG_I2C("i2c detach [client=%s,%s]\n",
		   client->name, (i < I2C_CLIENTS_MAX) ? "ok" : "failed");

	return 0;
}

static void cx18_setscl(void *data, int state)
{
	struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
	int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
	u32 addr = bus_index ? CX18_REG_I2C_2_WR : CX18_REG_I2C_1_WR;
	u32 r = read_reg(addr);

	if (state)
		write_reg_sync(r | SETSCL_BIT, addr);
	else
		write_reg_sync(r & ~SETSCL_BIT, addr);
}

static void cx18_setsda(void *data, int state)
{
	struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
	int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
	u32 addr = bus_index ? CX18_REG_I2C_2_WR : CX18_REG_I2C_1_WR;
	u32 r = read_reg(addr);

	if (state)
		write_reg_sync(r | SETSDL_BIT, addr);
	else
		write_reg_sync(r & ~SETSDL_BIT, addr);
}

static int cx18_getscl(void *data)
{
	struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
	int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
	u32 addr = bus_index ? CX18_REG_I2C_2_RD : CX18_REG_I2C_1_RD;

	return read_reg(addr) & GETSCL_BIT;
}

static int cx18_getsda(void *data)
{
	struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
	int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
	u32 addr = bus_index ? CX18_REG_I2C_2_RD : CX18_REG_I2C_1_RD;

	return read_reg(addr) & GETSDL_BIT;
}

/* template for i2c-bit-algo */
static struct i2c_adapter cx18_i2c_adap_template = {
	.name = "cx18 i2c driver",
	.id = I2C_HW_B_CX2341X,
	.algo = NULL,                   /* set by i2c-algo-bit */
	.algo_data = NULL,              /* filled from template */
	.client_register = attach_inform,
	.client_unregister = detach_inform,
	.owner = THIS_MODULE,
};

#define CX18_SCL_PERIOD (10) /* usecs. 10 usec is period for a 100 KHz clock */
#define CX18_ALGO_BIT_TIMEOUT (2) /* seconds */

static struct i2c_algo_bit_data cx18_i2c_algo_template = {
	.setsda		= cx18_setsda,
	.setscl		= cx18_setscl,
	.getsda		= cx18_getsda,
	.getscl		= cx18_getscl,
	.udelay		= CX18_SCL_PERIOD/2,       /* 1/2 clock period in usec*/
	.timeout	= CX18_ALGO_BIT_TIMEOUT*HZ /* jiffies */
};

static struct i2c_client cx18_i2c_client_template = {
	.name = "cx18 internal",
};

int cx18_call_i2c_client(struct cx18 *cx, int addr, unsigned cmd, void *arg)
{
	struct i2c_client *client;
	int retval;
	int i;

	CX18_DEBUG_I2C("call_i2c_client addr=%02x\n", addr);
	for (i = 0; i < I2C_CLIENTS_MAX; i++) {
		client = cx->i2c_clients[i];
		if (client == NULL || client->driver == NULL ||
				client->driver->command == NULL)
			continue;
		if (addr == client->addr) {
			retval = client->driver->command(client, cmd, arg);
			return retval;
		}
	}
	if (cmd != VIDIOC_G_CHIP_IDENT)
		CX18_ERR("i2c addr 0x%02x not found for cmd 0x%x!\n",
			       addr, cmd);
	return -ENODEV;
}

/* Find the i2c device based on the driver ID and return
   its i2c address or -ENODEV if no matching device was found. */
static int cx18_i2c_id_addr(struct cx18 *cx, u32 id)
{
	struct i2c_client *client;
	int retval = -ENODEV;
	int i;

	for (i = 0; i < I2C_CLIENTS_MAX; i++) {
		client = cx->i2c_clients[i];
		if (client == NULL || client->driver == NULL)
			continue;
		if (id == client->driver->id) {
			retval = client->addr;
			break;
		}
	}
	return retval;
}

/* Find the i2c device name matching the DRIVERID */
static const char *cx18_i2c_id_name(u32 id)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(hw_driverids); i++)
		if (hw_driverids[i] == id)
			return hw_drivernames[i];
	return "unknown device";
}

/* Find the i2c device name matching the CX18_HW_ flag */
static const char *cx18_i2c_hw_name(u32 hw)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(hw_driverids); i++)
		if (1 << i == hw)
			return hw_drivernames[i];
	return "unknown device";
}

/* Find the i2c device matching the CX18_HW_ flag and return
   its i2c address or -ENODEV if no matching device was found. */
int cx18_i2c_hw_addr(struct cx18 *cx, u32 hw)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(hw_driverids); i++)
		if (1 << i == hw)
			return cx18_i2c_id_addr(cx, hw_driverids[i]);
	return -ENODEV;
}

/* Calls i2c device based on CX18_HW_ flag. If hw == 0, then do nothing.
   If hw == CX18_HW_GPIO then call the gpio handler. */
int cx18_i2c_hw(struct cx18 *cx, u32 hw, unsigned int cmd, void *arg)
{
	int addr;

	if (hw == CX18_HW_GPIO || hw == 0)
		return 0;
	if (hw == CX18_HW_CX23418)
		return cx18_av_cmd(cx, cmd, arg);

	addr = cx18_i2c_hw_addr(cx, hw);
	if (addr < 0) {
		CX18_ERR("i2c hardware 0x%08x (%s) not found for cmd 0x%x!\n",
			       hw, cx18_i2c_hw_name(hw), cmd);
		return addr;
	}
	return cx18_call_i2c_client(cx, addr, cmd, arg);
}

/* Calls i2c device based on I2C driver ID. */
int cx18_i2c_id(struct cx18 *cx, u32 id, unsigned int cmd, void *arg)
{
	int addr;

	addr = cx18_i2c_id_addr(cx, id);
	if (addr < 0) {
		if (cmd != VIDIOC_G_CHIP_IDENT)
			CX18_ERR("i2c ID 0x%08x (%s) not found for cmd 0x%x!\n",
				id, cx18_i2c_id_name(id), cmd);
		return addr;
	}
	return cx18_call_i2c_client(cx, addr, cmd, arg);
}

/* broadcast cmd for all I2C clients and for the gpio subsystem */
void cx18_call_i2c_clients(struct cx18 *cx, unsigned int cmd, void *arg)
{
	if (cx->i2c_adap[0].algo == NULL || cx->i2c_adap[1].algo == NULL) {
		CX18_ERR("adapter is not set\n");
		return;
	}
	cx18_av_cmd(cx, cmd, arg);
	i2c_clients_command(&cx->i2c_adap[0], cmd, arg);
	i2c_clients_command(&cx->i2c_adap[1], cmd, arg);
}

/* init + register i2c algo-bit adapter */
int init_cx18_i2c(struct cx18 *cx)
{
	int i;
	CX18_DEBUG_I2C("i2c init\n");

	for (i = 0; i < 2; i++) {
		memcpy(&cx->i2c_adap[i], &cx18_i2c_adap_template,
			sizeof(struct i2c_adapter));
		memcpy(&cx->i2c_algo[i], &cx18_i2c_algo_template,
			sizeof(struct i2c_algo_bit_data));
		cx->i2c_algo_cb_data[i].cx = cx;
		cx->i2c_algo_cb_data[i].bus_index = i;
		cx->i2c_algo[i].data = &cx->i2c_algo_cb_data[i];
		cx->i2c_adap[i].algo_data = &cx->i2c_algo[i];

		sprintf(cx->i2c_adap[i].name + strlen(cx->i2c_adap[i].name),
				" #%d-%d", cx->num, i);
		i2c_set_adapdata(&cx->i2c_adap[i], cx);

		memcpy(&cx->i2c_client[i], &cx18_i2c_client_template,
			sizeof(struct i2c_client));
		sprintf(cx->i2c_client[i].name +
				strlen(cx->i2c_client[i].name), "%d", i);
		cx->i2c_client[i].adapter = &cx->i2c_adap[i];
		cx->i2c_adap[i].dev.parent = &cx->dev->dev;
	}

	if (read_reg(CX18_REG_I2C_2_WR) != 0x0003c02f) {
		/* Reset/Unreset I2C hardware block */
		write_reg(0x10000000, 0xc71004); /* Clock select 220MHz */
		write_reg_sync(0x10001000, 0xc71024); /* Clock Enable */
	}
	/* courtesy of Steven Toth <stoth@hauppauge.com> */
	write_reg_sync(0x00c00000, 0xc7001c);
	mdelay(10);
	write_reg_sync(0x00c000c0, 0xc7001c);
	mdelay(10);
	write_reg_sync(0x00c00000, 0xc7001c);

	write_reg_sync(0x00c00000, 0xc730c8); /* Set to edge-triggered intrs. */
	write_reg_sync(0x00c00000, 0xc730c4); /* Clear any stale intrs */

	/* Hw I2C1 Clock Freq ~100kHz */
	write_reg_sync(0x00021c0f & ~4, CX18_REG_I2C_1_WR);
	cx18_setscl(&cx->i2c_algo_cb_data[0], 1);
	cx18_setsda(&cx->i2c_algo_cb_data[0], 1);

	/* Hw I2C2 Clock Freq ~100kHz */
	write_reg_sync(0x00021c0f & ~4, CX18_REG_I2C_2_WR);
	cx18_setscl(&cx->i2c_algo_cb_data[1], 1);
	cx18_setsda(&cx->i2c_algo_cb_data[1], 1);

	return i2c_bit_add_bus(&cx->i2c_adap[0]) ||
		i2c_bit_add_bus(&cx->i2c_adap[1]);
}

void exit_cx18_i2c(struct cx18 *cx)
{
	int i;
	CX18_DEBUG_I2C("i2c exit\n");
	write_reg(read_reg(CX18_REG_I2C_1_WR) | 4, CX18_REG_I2C_1_WR);
	write_reg(read_reg(CX18_REG_I2C_2_WR) | 4, CX18_REG_I2C_2_WR);

	for (i = 0; i < 2; i++) {
		i2c_del_adapter(&cx->i2c_adap[i]);
	}
}

/*
   Hauppauge HVR1600 should have:
   32 cx24227
   98 unknown
   a0 eeprom
   c2 tuner
   e? zilog ir
   */
