/*
 * Toshiba TC90522 Demodulator
 *
 * Copyright (C) 2014 Akihiro Tsukada <tskd08@gmail.com>
 *
 * 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 version 2.
 *
 *
 * 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.
 */

/*
 * NOTICE:
 * This driver is incomplete and lacks init/config of the chips,
 * as the necessary info is not disclosed.
 * It assumes that users of this driver (such as a PCI bridge of
 * DTV receiver cards) properly init and configure the chip
 * via I2C *before* calling this driver's init() function.
 *
 * Currently, PT3 driver is the only one that uses this driver,
 * and contains init/config code in its firmware.
 * Thus some part of the code might be dependent on PT3 specific config.
 */

#include <linux/kernel.h>
#include <linux/dvb/frontend.h>
#include "dvb_math.h"
#include "tc90522.h"

#define TC90522_I2C_THRU_REG 0xfe

#define TC90522_MODULE_IDX(addr) (((u8)(addr) & 0x02U) >> 1)

struct tc90522_state {
	struct tc90522_config cfg;
	struct dvb_frontend fe;
	struct i2c_client *i2c_client;
	struct i2c_adapter tuner_i2c;

	bool lna;
};

struct reg_val {
	u8 reg;
	u8 val;
};

static int
reg_write(struct tc90522_state *state, const struct reg_val *regs, int num)
{
	int i, ret;
	struct i2c_msg msg;

	ret = 0;
	msg.addr = state->i2c_client->addr;
	msg.flags = 0;
	msg.len = 2;
	for (i = 0; i < num; i++) {
		msg.buf = (u8 *)&regs[i];
		ret = i2c_transfer(state->i2c_client->adapter, &msg, 1);
		if (ret == 0)
			ret = -EIO;
		if (ret < 0)
			return ret;
	}
	return 0;
}

static int reg_read(struct tc90522_state *state, u8 reg, u8 *val, u8 len)
{
	struct i2c_msg msgs[2] = {
		{
			.addr = state->i2c_client->addr,
			.flags = 0,
			.buf = &reg,
			.len = 1,
		},
		{
			.addr = state->i2c_client->addr,
			.flags = I2C_M_RD,
			.buf = val,
			.len = len,
		},
	};
	int ret;

	ret = i2c_transfer(state->i2c_client->adapter, msgs, ARRAY_SIZE(msgs));
	if (ret == ARRAY_SIZE(msgs))
		ret = 0;
	else if (ret >= 0)
		ret = -EIO;
	return ret;
}

static struct tc90522_state *cfg_to_state(struct tc90522_config *c)
{
	return container_of(c, struct tc90522_state, cfg);
}


static int tc90522s_set_tsid(struct dvb_frontend *fe)
{
	struct reg_val set_tsid[] = {
		{ 0x8f, 00 },
		{ 0x90, 00 }
	};

	set_tsid[0].val = (fe->dtv_property_cache.stream_id & 0xff00) >> 8;
	set_tsid[1].val = fe->dtv_property_cache.stream_id & 0xff;
	return reg_write(fe->demodulator_priv, set_tsid, ARRAY_SIZE(set_tsid));
}

static int tc90522t_set_layers(struct dvb_frontend *fe)
{
	struct reg_val rv;
	u8 laysel;

	laysel = ~fe->dtv_property_cache.isdbt_layer_enabled & 0x07;
	laysel = (laysel & 0x01) << 2 | (laysel & 0x02) | (laysel & 0x04) >> 2;
	rv.reg = 0x71;
	rv.val = laysel;
	return reg_write(fe->demodulator_priv, &rv, 1);
}

/* frontend ops */

static int tc90522s_read_status(struct dvb_frontend *fe, fe_status_t *status)
{
	struct tc90522_state *state;
	int ret;
	u8 reg;

	state = fe->demodulator_priv;
	ret = reg_read(state, 0xc3, &reg, 1);
	if (ret < 0)
		return ret;

	*status = 0;
	if (reg & 0x80) /* input level under min ? */
		return 0;
	*status |= FE_HAS_SIGNAL;

	if (reg & 0x60) /* carrier? */
		return 0;
	*status |= FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC;

	if (reg & 0x10)
		return 0;
	if (reg_read(state, 0xc5, &reg, 1) < 0 || !(reg & 0x03))
		return 0;
	*status |= FE_HAS_LOCK;
	return 0;
}

static int tc90522t_read_status(struct dvb_frontend *fe, fe_status_t *status)
{
	struct tc90522_state *state;
	int ret;
	u8 reg;

	state = fe->demodulator_priv;
	ret = reg_read(state, 0x96, &reg, 1);
	if (ret < 0)
		return ret;

	*status = 0;
	if (reg & 0xe0) {
		*status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI
				| FE_HAS_SYNC | FE_HAS_LOCK;
		return 0;
	}

	ret = reg_read(state, 0x80, &reg, 1);
	if (ret < 0)
		return ret;

	if (reg & 0xf0)
		return 0;
	*status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;

	if (reg & 0x0c)
		return 0;
	*status |= FE_HAS_SYNC | FE_HAS_VITERBI;

	if (reg & 0x02)
		return 0;
	*status |= FE_HAS_LOCK;
	return 0;
}

static const fe_code_rate_t fec_conv_sat[] = {
	FEC_NONE, /* unused */
	FEC_1_2, /* for BPSK */
	FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, /* for QPSK */
	FEC_2_3, /* for 8PSK. (trellis code) */
};

static int tc90522s_get_frontend(struct dvb_frontend *fe)
{
	struct tc90522_state *state;
	struct dtv_frontend_properties *c;
	struct dtv_fe_stats *stats;
	int ret, i;
	int layers;
	u8 val[10];
	u32 cndat;

	state = fe->demodulator_priv;
	c = &fe->dtv_property_cache;
	c->delivery_system = SYS_ISDBS;

	layers = 0;
	ret = reg_read(state, 0xe8, val, 3);
	if (ret == 0) {
		int slots;
		u8 v;

		/* high/single layer */
		v = (val[0] & 0x70) >> 4;
		c->modulation = (v == 7) ? PSK_8 : QPSK;
		c->fec_inner = fec_conv_sat[v];
		c->layer[0].fec = c->fec_inner;
		c->layer[0].modulation = c->modulation;
		c->layer[0].segment_count = val[1] & 0x3f; /* slots */

		/* low layer */
		v = (val[0] & 0x07);
		c->layer[1].fec = fec_conv_sat[v];
		if (v == 0)  /* no low layer */
			c->layer[1].segment_count = 0;
		else
			c->layer[1].segment_count = val[2] & 0x3f; /* slots */
		/* actually, BPSK if v==1, but not defined in fe_modulation_t */
		c->layer[1].modulation = QPSK;
		layers = (v > 0) ? 2 : 1;

		slots =  c->layer[0].segment_count +  c->layer[1].segment_count;
		c->symbol_rate = 28860000 * slots / 48;
	}

	/* statistics */

	stats = &c->strength;
	stats->len = 0;
	/* let the connected tuner set RSSI property cache */
	if (fe->ops.tuner_ops.get_rf_strength) {
		u16 dummy;

		fe->ops.tuner_ops.get_rf_strength(fe, &dummy);
	}

	stats = &c->cnr;
	stats->len = 1;
	stats->stat[0].scale = FE_SCALE_NOT_AVAILABLE;
	cndat = 0;
	ret = reg_read(state, 0xbc, val, 2);
	if (ret == 0)
		cndat = val[0] << 8 | val[1];
	if (cndat >= 3000) {
		u32 p, p4;
		s64 cn;

		cndat -= 3000;  /* cndat: 4.12 fixed point float */
		/*
		 * cnr[mdB] = -1634.6 * P^5 + 14341 * P^4 - 50259 * P^3
		 *                 + 88977 * P^2 - 89565 * P + 58857
		 *  (P = sqrt(cndat) / 64)
		 */
		/* p := sqrt(cndat) << 8 = P << 14, 2.14 fixed  point float */
		/* cn = cnr << 3 */
		p = int_sqrt(cndat << 16);
		p4 = cndat * cndat;
		cn = (-16346LL * p4 * p / 10) >> 35;
		cn += (14341LL * p4) >> 21;
		cn -= (50259LL * cndat * p) >> 23;
		cn += (88977LL * cndat) >> 9;
		cn -= (89565LL * p) >> 11;
		cn += 58857  << 3;
		stats->stat[0].svalue = cn >> 3;
		stats->stat[0].scale = FE_SCALE_DECIBEL;
	}

	/* per-layer post viterbi BER (or PER? config dependent?) */
	stats = &c->post_bit_error;
	memset(stats, 0, sizeof(*stats));
	stats->len = layers;
	ret = reg_read(state, 0xeb, val, 10);
	if (ret < 0)
		for (i = 0; i < layers; i++)
			stats->stat[i].scale = FE_SCALE_NOT_AVAILABLE;
	else {
		for (i = 0; i < layers; i++) {
			stats->stat[i].scale = FE_SCALE_COUNTER;
			stats->stat[i].uvalue = val[i * 5] << 16
				| val[i * 5 + 1] << 8 | val[i * 5 + 2];
		}
	}
	stats = &c->post_bit_count;
	memset(stats, 0, sizeof(*stats));
	stats->len = layers;
	if (ret < 0)
		for (i = 0; i < layers; i++)
			stats->stat[i].scale = FE_SCALE_NOT_AVAILABLE;
	else {
		for (i = 0; i < layers; i++) {
			stats->stat[i].scale = FE_SCALE_COUNTER;
			stats->stat[i].uvalue =
				val[i * 5 + 3] << 8 | val[i * 5 + 4];
			stats->stat[i].uvalue *= 204 * 8;
		}
	}

	return 0;
}


static const fe_transmit_mode_t tm_conv[] = {
	TRANSMISSION_MODE_2K,
	TRANSMISSION_MODE_4K,
	TRANSMISSION_MODE_8K,
	0
};

static const fe_code_rate_t fec_conv_ter[] = {
	FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, 0, 0, 0
};

static const fe_modulation_t mod_conv[] = {
	DQPSK, QPSK, QAM_16, QAM_64, 0, 0, 0, 0
};

static int tc90522t_get_frontend(struct dvb_frontend *fe)
{
	struct tc90522_state *state;
	struct dtv_frontend_properties *c;
	struct dtv_fe_stats *stats;
	int ret, i;
	int layers;
	u8 val[15], mode;
	u32 cndat;

	state = fe->demodulator_priv;
	c = &fe->dtv_property_cache;
	c->delivery_system = SYS_ISDBT;
	c->bandwidth_hz = 6000000;
	mode = 1;
	ret = reg_read(state, 0xb0, val, 1);
	if (ret == 0) {
		mode = (val[0] & 0xc0) >> 2;
		c->transmission_mode = tm_conv[mode];
		c->guard_interval = (val[0] & 0x30) >> 4;
	}

	ret = reg_read(state, 0xb2, val, 6);
	layers = 0;
	if (ret == 0) {
		u8 v;

		c->isdbt_partial_reception = val[0] & 0x01;
		c->isdbt_sb_mode = (val[0] & 0xc0) == 0x01;

		/* layer A */
		v = (val[2] & 0x78) >> 3;
		if (v == 0x0f)
			c->layer[0].segment_count = 0;
		else {
			layers++;
			c->layer[0].segment_count = v;
			c->layer[0].fec = fec_conv_ter[(val[1] & 0x1c) >> 2];
			c->layer[0].modulation = mod_conv[(val[1] & 0xe0) >> 5];
			v = (val[1] & 0x03) << 1 | (val[2] & 0x80) >> 7;
			c->layer[0].interleaving = v;
		}

		/* layer B */
		v = (val[3] & 0x03) << 1 | (val[4] & 0xc0) >> 6;
		if (v == 0x0f)
			c->layer[1].segment_count = 0;
		else {
			layers++;
			c->layer[1].segment_count = v;
			c->layer[1].fec = fec_conv_ter[(val[3] & 0xe0) >> 5];
			c->layer[1].modulation = mod_conv[(val[2] & 0x07)];
			c->layer[1].interleaving = (val[3] & 0x1c) >> 2;
		}

		/* layer C */
		v = (val[5] & 0x1e) >> 1;
		if (v == 0x0f)
			c->layer[2].segment_count = 0;
		else {
			layers++;
			c->layer[2].segment_count = v;
			c->layer[2].fec = fec_conv_ter[(val[4] & 0x07)];
			c->layer[2].modulation = mod_conv[(val[4] & 0x38) >> 3];
			c->layer[2].interleaving = (val[5] & 0xe0) >> 5;
		}
	}

	/* statistics */

	stats = &c->strength;
	stats->len = 0;
	/* let the connected tuner set RSSI property cache */
	if (fe->ops.tuner_ops.get_rf_strength) {
		u16 dummy;

		fe->ops.tuner_ops.get_rf_strength(fe, &dummy);
	}

	stats = &c->cnr;
	stats->len = 1;
	stats->stat[0].scale = FE_SCALE_NOT_AVAILABLE;
	cndat = 0;
	ret = reg_read(state, 0x8b, val, 3);
	if (ret == 0)
		cndat = val[0] << 16 | val[1] << 8 | val[2];
	if (cndat != 0) {
		u32 p, tmp;
		s64 cn;

		/*
		 * cnr[mdB] = 0.024 P^4 - 1.6 P^3 + 39.8 P^2 + 549.1 P + 3096.5
		 * (P = 10log10(5505024/cndat))
		 */
		/* cn = cnr << 3 (61.3 fixed point float */
		/* p = 10log10(5505024/cndat) << 24  (8.24 fixed point float)*/
		p = intlog10(5505024) - intlog10(cndat);
		p *= 10;

		cn = 24772;
		cn += ((43827LL * p) / 10) >> 24;
		tmp = p >> 8;
		cn += ((3184LL * tmp * tmp) / 10) >> 32;
		tmp = p >> 13;
		cn -= ((128LL * tmp * tmp * tmp) / 10) >> 33;
		tmp = p >> 18;
		cn += ((192LL * tmp * tmp * tmp * tmp) / 1000) >> 24;

		stats->stat[0].svalue = cn >> 3;
		stats->stat[0].scale = FE_SCALE_DECIBEL;
	}

	/* per-layer post viterbi BER (or PER? config dependent?) */
	stats = &c->post_bit_error;
	memset(stats, 0, sizeof(*stats));
	stats->len = layers;
	ret = reg_read(state, 0x9d, val, 15);
	if (ret < 0)
		for (i = 0; i < layers; i++)
			stats->stat[i].scale = FE_SCALE_NOT_AVAILABLE;
	else {
		for (i = 0; i < layers; i++) {
			stats->stat[i].scale = FE_SCALE_COUNTER;
			stats->stat[i].uvalue = val[i * 3] << 16
				| val[i * 3 + 1] << 8 | val[i * 3 + 2];
		}
	}
	stats = &c->post_bit_count;
	memset(stats, 0, sizeof(*stats));
	stats->len = layers;
	if (ret < 0)
		for (i = 0; i < layers; i++)
			stats->stat[i].scale = FE_SCALE_NOT_AVAILABLE;
	else {
		for (i = 0; i < layers; i++) {
			stats->stat[i].scale = FE_SCALE_COUNTER;
			stats->stat[i].uvalue =
				val[9 + i * 2] << 8 | val[9 + i * 2 + 1];
			stats->stat[i].uvalue *= 204 * 8;
		}
	}

	return 0;
}

static const struct reg_val reset_sat = { 0x03, 0x01 };
static const struct reg_val reset_ter = { 0x01, 0x40 };

static int tc90522_set_frontend(struct dvb_frontend *fe)
{
	struct tc90522_state *state;
	int ret;

	state = fe->demodulator_priv;

	if (fe->ops.tuner_ops.set_params)
		ret = fe->ops.tuner_ops.set_params(fe);
	else
		ret = -ENODEV;
	if (ret < 0)
		goto failed;

	if (fe->ops.delsys[0] == SYS_ISDBS) {
		ret = tc90522s_set_tsid(fe);
		if (ret < 0)
			goto failed;
		ret = reg_write(state, &reset_sat, 1);
	} else {
		ret = tc90522t_set_layers(fe);
		if (ret < 0)
			goto failed;
		ret = reg_write(state, &reset_ter, 1);
	}
	if (ret < 0)
		goto failed;

	return 0;

failed:
	dev_warn(&state->tuner_i2c.dev, "(%s) failed. [adap%d-fe%d]\n",
			__func__, fe->dvb->num, fe->id);
	return ret;
}

static int tc90522_get_tune_settings(struct dvb_frontend *fe,
	struct dvb_frontend_tune_settings *settings)
{
	if (fe->ops.delsys[0] == SYS_ISDBS) {
		settings->min_delay_ms = 250;
		settings->step_size = 1000;
		settings->max_drift = settings->step_size * 2;
	} else {
		settings->min_delay_ms = 400;
		settings->step_size = 142857;
		settings->max_drift = settings->step_size;
	}
	return 0;
}

static int tc90522_set_if_agc(struct dvb_frontend *fe, bool on)
{
	struct reg_val agc_sat[] = {
		{ 0x0a, 0x00 },
		{ 0x10, 0x30 },
		{ 0x11, 0x00 },
		{ 0x03, 0x01 },
	};
	struct reg_val agc_ter[] = {
		{ 0x25, 0x00 },
		{ 0x23, 0x4c },
		{ 0x01, 0x40 },
	};
	struct tc90522_state *state;
	struct reg_val *rv;
	int num;

	state = fe->demodulator_priv;
	if (fe->ops.delsys[0] == SYS_ISDBS) {
		agc_sat[0].val = on ? 0xff : 0x00;
		agc_sat[1].val |= 0x80;
		agc_sat[1].val |= on ? 0x01 : 0x00;
		agc_sat[2].val |= on ? 0x40 : 0x00;
		rv = agc_sat;
		num = ARRAY_SIZE(agc_sat);
	} else {
		agc_ter[0].val = on ? 0x40 : 0x00;
		agc_ter[1].val |= on ? 0x00 : 0x01;
		rv = agc_ter;
		num = ARRAY_SIZE(agc_ter);
	}
	return reg_write(state, rv, num);
}

static const struct reg_val sleep_sat = { 0x17, 0x01 };
static const struct reg_val sleep_ter = { 0x03, 0x90 };

static int tc90522_sleep(struct dvb_frontend *fe)
{
	struct tc90522_state *state;
	int ret;

	state = fe->demodulator_priv;
	if (fe->ops.delsys[0] == SYS_ISDBS)
		ret = reg_write(state, &sleep_sat, 1);
	else {
		ret = reg_write(state, &sleep_ter, 1);
		if (ret == 0 && fe->ops.set_lna &&
		    fe->dtv_property_cache.lna == LNA_AUTO) {
			fe->dtv_property_cache.lna = 0;
			ret = fe->ops.set_lna(fe);
			fe->dtv_property_cache.lna = LNA_AUTO;
		}
	}
	if (ret < 0)
		dev_warn(&state->tuner_i2c.dev,
			"(%s) failed. [adap%d-fe%d]\n",
			__func__, fe->dvb->num, fe->id);
	return ret;
}

static const struct reg_val wakeup_sat = { 0x17, 0x00 };
static const struct reg_val wakeup_ter = { 0x03, 0x80 };

static int tc90522_init(struct dvb_frontend *fe)
{
	struct tc90522_state *state;
	int ret;

	/*
	 * Because the init sequence is not public,
	 * the parent device/driver should have init'ed the device before.
	 * just wake up the device here.
	 */

	state = fe->demodulator_priv;
	if (fe->ops.delsys[0] == SYS_ISDBS)
		ret = reg_write(state, &wakeup_sat, 1);
	else {
		ret = reg_write(state, &wakeup_ter, 1);
		if (ret == 0 && fe->ops.set_lna &&
		    fe->dtv_property_cache.lna == LNA_AUTO) {
			fe->dtv_property_cache.lna = 1;
			ret = fe->ops.set_lna(fe);
			fe->dtv_property_cache.lna = LNA_AUTO;
		}
	}
	if (ret < 0) {
		dev_warn(&state->tuner_i2c.dev,
			"(%s) failed. [adap%d-fe%d]\n",
			__func__, fe->dvb->num, fe->id);
		return ret;
	}

	/* prefer 'all-layers' to 'none' as a default */
	if (fe->dtv_property_cache.isdbt_layer_enabled == 0)
		fe->dtv_property_cache.isdbt_layer_enabled = 7;
	return tc90522_set_if_agc(fe, true);
}


/*
 * tuner I2C adapter functions
 */

static int
tc90522_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
{
	struct tc90522_state *state;
	struct i2c_msg *new_msgs;
	int i, j;
	int ret, rd_num;
	u8 wbuf[256];
	u8 *p, *bufend;

	if (num <= 0)
		return -EINVAL;

	rd_num = 0;
	for (i = 0; i < num; i++)
		if (msgs[i].flags & I2C_M_RD)
			rd_num++;
	new_msgs = kmalloc(sizeof(*new_msgs) * (num + rd_num), GFP_KERNEL);
	if (!new_msgs)
		return -ENOMEM;

	state = i2c_get_adapdata(adap);
	p = wbuf;
	bufend = wbuf + sizeof(wbuf);
	for (i = 0, j = 0; i < num; i++, j++) {
		new_msgs[j].addr = state->i2c_client->addr;
		new_msgs[j].flags = msgs[i].flags;

		if (msgs[i].flags & I2C_M_RD) {
			new_msgs[j].flags &= ~I2C_M_RD;
			if (p + 2 > bufend)
				break;
			p[0] = TC90522_I2C_THRU_REG;
			p[1] = msgs[i].addr << 1 | 0x01;
			new_msgs[j].buf = p;
			new_msgs[j].len = 2;
			p += 2;
			j++;
			new_msgs[j].addr = state->i2c_client->addr;
			new_msgs[j].flags = msgs[i].flags;
			new_msgs[j].buf = msgs[i].buf;
			new_msgs[j].len = msgs[i].len;
			continue;
		}

		if (p + msgs[i].len + 2 > bufend)
			break;
		p[0] = TC90522_I2C_THRU_REG;
		p[1] = msgs[i].addr << 1;
		memcpy(p + 2, msgs[i].buf, msgs[i].len);
		new_msgs[j].buf = p;
		new_msgs[j].len = msgs[i].len + 2;
		p += new_msgs[j].len;
	}

	if (i < num)
		ret = -ENOMEM;
	else
		ret = i2c_transfer(state->i2c_client->adapter, new_msgs, j);
	if (ret >= 0 && ret < j)
		ret = -EIO;
	kfree(new_msgs);
	return (ret == j) ? num : ret;
}

u32 tc90522_functionality(struct i2c_adapter *adap)
{
	return I2C_FUNC_I2C;
}

static const struct i2c_algorithm tc90522_tuner_i2c_algo = {
	.master_xfer   = &tc90522_master_xfer,
	.functionality = &tc90522_functionality,
};


/*
 * I2C driver functions
 */

static const struct dvb_frontend_ops tc90522_ops_sat = {
	.delsys = { SYS_ISDBS },
	.info = {
		.name = "Toshiba TC90522 ISDB-S module",
		.frequency_min =  950000,
		.frequency_max = 2150000,
		.caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_AUTO |
			FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
			FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO,
	},

	.init = tc90522_init,
	.sleep = tc90522_sleep,
	.set_frontend = tc90522_set_frontend,
	.get_tune_settings = tc90522_get_tune_settings,

	.get_frontend = tc90522s_get_frontend,
	.read_status = tc90522s_read_status,
};

static const struct dvb_frontend_ops tc90522_ops_ter = {
	.delsys = { SYS_ISDBT },
	.info = {
		.name = "Toshiba TC90522 ISDB-T module",
		.frequency_min = 470000000,
		.frequency_max = 770000000,
		.frequency_stepsize = 142857,
		.caps = FE_CAN_INVERSION_AUTO |
			FE_CAN_FEC_1_2  | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
			FE_CAN_FEC_5_6  | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
			FE_CAN_QPSK     | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
			FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
			FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER |
			FE_CAN_HIERARCHY_AUTO,
	},

	.init = tc90522_init,
	.sleep = tc90522_sleep,
	.set_frontend = tc90522_set_frontend,
	.get_tune_settings = tc90522_get_tune_settings,

	.get_frontend = tc90522t_get_frontend,
	.read_status = tc90522t_read_status,
};


static int tc90522_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	struct tc90522_state *state;
	struct tc90522_config *cfg;
	const struct dvb_frontend_ops *ops;
	struct i2c_adapter *adap;
	int ret;

	state = kzalloc(sizeof(*state), GFP_KERNEL);
	if (!state)
		return -ENOMEM;
	state->i2c_client = client;

	cfg = client->dev.platform_data;
	memcpy(&state->cfg, cfg, sizeof(state->cfg));
	cfg->fe = state->cfg.fe = &state->fe;
	ops =  id->driver_data == 0 ? &tc90522_ops_sat : &tc90522_ops_ter;
	memcpy(&state->fe.ops, ops, sizeof(*ops));
	state->fe.demodulator_priv = state;

	adap = &state->tuner_i2c;
	adap->owner = THIS_MODULE;
	adap->algo = &tc90522_tuner_i2c_algo;
	adap->dev.parent = &client->dev;
	strlcpy(adap->name, "tc90522_sub", sizeof(adap->name));
	i2c_set_adapdata(adap, state);
	ret = i2c_add_adapter(adap);
	if (ret < 0)
		goto err;
	cfg->tuner_i2c = state->cfg.tuner_i2c = adap;

	i2c_set_clientdata(client, &state->cfg);
	dev_info(&client->dev, "Toshiba TC90522 attached.\n");
	return 0;

err:
	kfree(state);
	return ret;
}

static int tc90522_remove(struct i2c_client *client)
{
	struct tc90522_state *state;

	state = cfg_to_state(i2c_get_clientdata(client));
	i2c_del_adapter(&state->tuner_i2c);
	kfree(state);
	return 0;
}


static const struct i2c_device_id tc90522_id[] = {
	{ TC90522_I2C_DEV_SAT, 0 },
	{ TC90522_I2C_DEV_TER, 1 },
	{}
};
MODULE_DEVICE_TABLE(i2c, tc90522_id);

static struct i2c_driver tc90522_driver = {
	.driver = {
		.name	= "tc90522",
	},
	.probe		= tc90522_probe,
	.remove		= tc90522_remove,
	.id_table	= tc90522_id,
};

module_i2c_driver(tc90522_driver);

MODULE_DESCRIPTION("Toshiba TC90522 frontend");
MODULE_AUTHOR("Akihiro TSUKADA");
MODULE_LICENSE("GPL");
