  /*
     Driver for Philips tda8262/tda8263 DVBS Silicon tuners

     (c) 2006 Andrew de Quincey

     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/slab.h>
#include <linux/module.h>
#include <linux/dvb/frontend.h>
#include <asm/types.h>

#include "tda826x.h"

static int debug;
#define dprintk(args...) \
	do { \
		if (debug) printk(KERN_DEBUG "tda826x: " args); \
	} while (0)

struct tda826x_priv {
	/* i2c details */
	int i2c_address;
	struct i2c_adapter *i2c;
	u8 has_loopthrough:1;
	u32 frequency;
};

static void tda826x_release(struct dvb_frontend *fe)
{
	kfree(fe->tuner_priv);
	fe->tuner_priv = NULL;
}

static int tda826x_sleep(struct dvb_frontend *fe)
{
	struct tda826x_priv *priv = fe->tuner_priv;
	int ret;
	u8 buf [] = { 0x00, 0x8d };
	struct i2c_msg msg = { .addr = priv->i2c_address, .flags = 0, .buf = buf, .len = 2 };

	dprintk("%s:\n", __func__);

	if (!priv->has_loopthrough)
		buf[1] = 0xad;

	if (fe->ops.i2c_gate_ctrl)
		fe->ops.i2c_gate_ctrl(fe, 1);
	if ((ret = i2c_transfer (priv->i2c, &msg, 1)) != 1) {
		dprintk("%s: i2c error\n", __func__);
	}
	if (fe->ops.i2c_gate_ctrl)
		fe->ops.i2c_gate_ctrl(fe, 0);

	return (ret == 1) ? 0 : ret;
}

static int tda826x_set_params(struct dvb_frontend *fe)
{
	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
	struct tda826x_priv *priv = fe->tuner_priv;
	int ret;
	u32 div;
	u32 ksyms;
	u32 bandwidth;
	u8 buf [11];
	struct i2c_msg msg = { .addr = priv->i2c_address, .flags = 0, .buf = buf, .len = 11 };

	dprintk("%s:\n", __func__);

	div = (p->frequency + (1000-1)) / 1000;

	/* BW = ((1 + RO) * SR/2 + 5) * 1.3      [SR in MSPS, BW in MHz] */
	/* with R0 = 0.35 and some transformations: */
	ksyms = p->symbol_rate / 1000;
	bandwidth = (878 * ksyms + 6500000) / 1000000 + 1;
	if (bandwidth < 5)
		bandwidth = 5;
	else if (bandwidth > 36)
		bandwidth = 36;

	buf[0] = 0x00; // subaddress
	buf[1] = 0x09; // powerdown RSSI + the magic value 1
	if (!priv->has_loopthrough)
		buf[1] |= 0x20; // power down loopthrough if not needed
	buf[2] = (1<<5) | 0x0b; // 1Mhz + 0.45 VCO
	buf[3] = div >> 7;
	buf[4] = div << 1;
	buf[5] = ((bandwidth - 5) << 3) | 7; /* baseband cut-off */
	buf[6] = 0xfe; // baseband gain 9 db + no RF attenuation
	buf[7] = 0x83; // charge pumps at high, tests off
	buf[8] = 0x80; // recommended value 4 for AMPVCO + disable ports.
	buf[9] = 0x1a; // normal caltime + recommended values for SELTH + SELVTL
	buf[10] = 0xd4; // recommended value 13 for BBIAS + unknown bit set on

	if (fe->ops.i2c_gate_ctrl)
		fe->ops.i2c_gate_ctrl(fe, 1);
	if ((ret = i2c_transfer (priv->i2c, &msg, 1)) != 1) {
		dprintk("%s: i2c error\n", __func__);
	}
	if (fe->ops.i2c_gate_ctrl)
		fe->ops.i2c_gate_ctrl(fe, 0);

	priv->frequency = div * 1000;

	return (ret == 1) ? 0 : ret;
}

static int tda826x_get_frequency(struct dvb_frontend *fe, u32 *frequency)
{
	struct tda826x_priv *priv = fe->tuner_priv;
	*frequency = priv->frequency;
	return 0;
}

static const struct dvb_tuner_ops tda826x_tuner_ops = {
	.info = {
		.name = "Philips TDA826X",
		.frequency_min = 950000,
		.frequency_max = 2175000
	},
	.release = tda826x_release,
	.sleep = tda826x_sleep,
	.set_params = tda826x_set_params,
	.get_frequency = tda826x_get_frequency,
};

struct dvb_frontend *tda826x_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c, int has_loopthrough)
{
	struct tda826x_priv *priv = NULL;
	u8 b1 [] = { 0, 0 };
	struct i2c_msg msg[2] = {
		{ .addr = addr, .flags = 0,        .buf = NULL, .len = 0 },
		{ .addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 2 }
	};
	int ret;

	dprintk("%s:\n", __func__);

	if (fe->ops.i2c_gate_ctrl)
		fe->ops.i2c_gate_ctrl(fe, 1);
	ret = i2c_transfer (i2c, msg, 2);
	if (fe->ops.i2c_gate_ctrl)
		fe->ops.i2c_gate_ctrl(fe, 0);

	if (ret != 2)
		return NULL;
	if (!(b1[1] & 0x80))
		return NULL;

	priv = kzalloc(sizeof(struct tda826x_priv), GFP_KERNEL);
	if (priv == NULL)
		return NULL;

	priv->i2c_address = addr;
	priv->i2c = i2c;
	priv->has_loopthrough = has_loopthrough;

	memcpy(&fe->ops.tuner_ops, &tda826x_tuner_ops, sizeof(struct dvb_tuner_ops));

	fe->tuner_priv = priv;

	return fe;
}
EXPORT_SYMBOL_GPL(tda826x_attach);

module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");

MODULE_DESCRIPTION("DVB TDA826x driver");
MODULE_AUTHOR("Andrew de Quincey");
MODULE_LICENSE("GPL");
