/*
 *  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 "cx18-i2c.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_devicenames[] = {
	"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.type, hw_devicenames[idx], sizeof(info.type));
	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_devicenames[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_devicenames[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
   */
