/*
 * HDIC HD29L2 DMB-TH demodulator driver
 *
 * Copyright (C) 2011 Metropolia University of Applied Sciences, Electria R&D
 *
 * Author: Antti Palosaari <crope@iki.fi>
 *
 *    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 "hd29l2_priv.h"

#define HD29L2_MAX_LEN (3)

/* write multiple registers */
static int hd29l2_wr_regs(struct hd29l2_priv *priv, u8 reg, u8 *val, int len)
{
	int ret;
	u8 buf[2 + HD29L2_MAX_LEN];
	struct i2c_msg msg[1] = {
		{
			.addr = priv->cfg.i2c_addr,
			.flags = 0,
			.len = 2 + len,
			.buf = buf,
		}
	};

	if (len > HD29L2_MAX_LEN)
		return -EINVAL;
	buf[0] = 0x00;
	buf[1] = reg;
	memcpy(&buf[2], val, len);

	ret = i2c_transfer(priv->i2c, msg, 1);
	if (ret == 1) {
		ret = 0;
	} else {
		dev_warn(&priv->i2c->dev,
				"%s: i2c wr failed=%d reg=%02x len=%d\n",
				KBUILD_MODNAME, ret, reg, len);
		ret = -EREMOTEIO;
	}

	return ret;
}

/* read multiple registers */
static int hd29l2_rd_regs(struct hd29l2_priv *priv, u8 reg, u8 *val, int len)
{
	int ret;
	u8 buf[2] = { 0x00, reg };
	struct i2c_msg msg[2] = {
		{
			.addr = priv->cfg.i2c_addr,
			.flags = 0,
			.len = 2,
			.buf = buf,
		}, {
			.addr = priv->cfg.i2c_addr,
			.flags = I2C_M_RD,
			.len = len,
			.buf = val,
		}
	};

	ret = i2c_transfer(priv->i2c, msg, 2);
	if (ret == 2) {
		ret = 0;
	} else {
		dev_warn(&priv->i2c->dev,
				"%s: i2c rd failed=%d reg=%02x len=%d\n",
				KBUILD_MODNAME, ret, reg, len);
		ret = -EREMOTEIO;
	}

	return ret;
}

/* write single register */
static int hd29l2_wr_reg(struct hd29l2_priv *priv, u8 reg, u8 val)
{
	return hd29l2_wr_regs(priv, reg, &val, 1);
}

/* read single register */
static int hd29l2_rd_reg(struct hd29l2_priv *priv, u8 reg, u8 *val)
{
	return hd29l2_rd_regs(priv, reg, val, 1);
}

/* write single register with mask */
static int hd29l2_wr_reg_mask(struct hd29l2_priv *priv, u8 reg, u8 val, u8 mask)
{
	int ret;
	u8 tmp;

	/* no need for read if whole reg is written */
	if (mask != 0xff) {
		ret = hd29l2_rd_regs(priv, reg, &tmp, 1);
		if (ret)
			return ret;

		val &= mask;
		tmp &= ~mask;
		val |= tmp;
	}

	return hd29l2_wr_regs(priv, reg, &val, 1);
}

/* read single register with mask */
static int hd29l2_rd_reg_mask(struct hd29l2_priv *priv, u8 reg, u8 *val, u8 mask)
{
	int ret, i;
	u8 tmp;

	ret = hd29l2_rd_regs(priv, reg, &tmp, 1);
	if (ret)
		return ret;

	tmp &= mask;

	/* find position of the first bit */
	for (i = 0; i < 8; i++) {
		if ((mask >> i) & 0x01)
			break;
	}
	*val = tmp >> i;

	return 0;
}

static int hd29l2_soft_reset(struct hd29l2_priv *priv)
{
	int ret;
	u8 tmp;

	ret = hd29l2_rd_reg(priv, 0x26, &tmp);
	if (ret)
		goto err;

	ret = hd29l2_wr_reg(priv, 0x26, 0x0d);
	if (ret)
		goto err;

	usleep_range(10000, 20000);

	ret = hd29l2_wr_reg(priv, 0x26, tmp);
	if (ret)
		goto err;

	return 0;
err:
	dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
	return ret;
}

static int hd29l2_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
{
	int ret, i;
	struct hd29l2_priv *priv = fe->demodulator_priv;
	u8 tmp;

	dev_dbg(&priv->i2c->dev, "%s: enable=%d\n", __func__, enable);

	/* set tuner address for demod */
	if (!priv->tuner_i2c_addr_programmed && enable) {
		/* no need to set tuner address every time, once is enough */
		ret = hd29l2_wr_reg(priv, 0x9d, priv->cfg.tuner_i2c_addr << 1);
		if (ret)
			goto err;

		priv->tuner_i2c_addr_programmed = true;
	}

	/* open / close gate */
	ret = hd29l2_wr_reg(priv, 0x9f, enable);
	if (ret)
		goto err;

	/* wait demod ready */
	for (i = 10; i; i--) {
		ret = hd29l2_rd_reg(priv, 0x9e, &tmp);
		if (ret)
			goto err;

		if (tmp == enable)
			break;

		usleep_range(5000, 10000);
	}

	dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i);

	return ret;
err:
	dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
	return ret;
}

static int hd29l2_read_status(struct dvb_frontend *fe, enum fe_status *status)
{
	int ret;
	struct hd29l2_priv *priv = fe->demodulator_priv;
	u8 buf[2];

	*status = 0;

	ret = hd29l2_rd_reg(priv, 0x05, &buf[0]);
	if (ret)
		goto err;

	if (buf[0] & 0x01) {
		/* full lock */
		*status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
			FE_HAS_SYNC | FE_HAS_LOCK;
	} else {
		ret = hd29l2_rd_reg(priv, 0x0d, &buf[1]);
		if (ret)
			goto err;

		if ((buf[1] & 0xfe) == 0x78)
			/* partial lock */
			*status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
				FE_HAS_VITERBI | FE_HAS_SYNC;
	}

	priv->fe_status = *status;

	return 0;
err:
	dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
	return ret;
}

static int hd29l2_read_snr(struct dvb_frontend *fe, u16 *snr)
{
	int ret;
	struct hd29l2_priv *priv = fe->demodulator_priv;
	u8 buf[2];
	u16 tmp;

	if (!(priv->fe_status & FE_HAS_LOCK)) {
		*snr = 0;
		ret = 0;
		goto err;
	}

	ret = hd29l2_rd_regs(priv, 0x0b, buf, 2);
	if (ret)
		goto err;

	tmp = (buf[0] << 8) | buf[1];

	/* report SNR in dB * 10 */
	#define LOG10_20736_24 72422627 /* log10(20736) << 24 */
	if (tmp)
		*snr = (LOG10_20736_24 - intlog10(tmp)) / ((1 << 24) / 100);
	else
		*snr = 0;

	return 0;
err:
	dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
	return ret;
}

static int hd29l2_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
{
	int ret;
	struct hd29l2_priv *priv = fe->demodulator_priv;
	u8 buf[2];
	u16 tmp;

	*strength = 0;

	ret = hd29l2_rd_regs(priv, 0xd5, buf, 2);
	if (ret)
		goto err;

	tmp = buf[0] << 8 | buf[1];
	tmp = ~tmp & 0x0fff;

	/* scale value to 0x0000-0xffff from 0x0000-0x0fff */
	*strength = tmp * 0xffff / 0x0fff;

	return 0;
err:
	dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
	return ret;
}

static int hd29l2_read_ber(struct dvb_frontend *fe, u32 *ber)
{
	int ret;
	struct hd29l2_priv *priv = fe->demodulator_priv;
	u8 buf[2];

	if (!(priv->fe_status & FE_HAS_SYNC)) {
		*ber = 0;
		ret = 0;
		goto err;
	}

	ret = hd29l2_rd_regs(priv, 0xd9, buf, 2);
	if (ret) {
		*ber = 0;
		goto err;
	}

	/* LDPC BER */
	*ber = ((buf[0] & 0x0f) << 8) | buf[1];

	return 0;
err:
	dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
	return ret;
}

static int hd29l2_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
{
	/* no way to read? */
	*ucblocks = 0;
	return 0;
}

static enum dvbfe_search hd29l2_search(struct dvb_frontend *fe)
{
	int ret, i;
	struct hd29l2_priv *priv = fe->demodulator_priv;
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
	u8 tmp, buf[3];
	u8 modulation, carrier, guard_interval, interleave, code_rate;
	u64 num64;
	u32 if_freq, if_ctl;
	bool auto_mode;

	dev_dbg(&priv->i2c->dev, "%s: delivery_system=%d frequency=%d " \
			"bandwidth_hz=%d modulation=%d inversion=%d " \
			"fec_inner=%d guard_interval=%d\n", __func__,
			c->delivery_system, c->frequency, c->bandwidth_hz,
			c->modulation, c->inversion, c->fec_inner,
			c->guard_interval);

	/* as for now we detect always params automatically */
	auto_mode = true;

	/* program tuner */
	if (fe->ops.tuner_ops.set_params)
		fe->ops.tuner_ops.set_params(fe);

	/* get and program IF */
	if (fe->ops.tuner_ops.get_if_frequency)
		fe->ops.tuner_ops.get_if_frequency(fe, &if_freq);
	else
		if_freq = 0;

	if (if_freq) {
		/* normal IF */

		/* calc IF control value */
		num64 = if_freq;
		num64 *= 0x800000;
		num64 = div_u64(num64, HD29L2_XTAL);
		num64 -= 0x800000;
		if_ctl = num64;

		tmp = 0xfc; /* tuner type normal */
	} else {
		/* zero IF */
		if_ctl = 0;
		tmp = 0xfe; /* tuner type Zero-IF */
	}

	buf[0] = ((if_ctl >>  0) & 0xff);
	buf[1] = ((if_ctl >>  8) & 0xff);
	buf[2] = ((if_ctl >> 16) & 0xff);

	/* program IF control */
	ret = hd29l2_wr_regs(priv, 0x14, buf, 3);
	if (ret)
		goto err;

	/* program tuner type */
	ret = hd29l2_wr_reg(priv, 0xab, tmp);
	if (ret)
		goto err;

	dev_dbg(&priv->i2c->dev, "%s: if_freq=%d if_ctl=%x\n",
			__func__, if_freq, if_ctl);

	if (auto_mode) {
		/*
		 * use auto mode
		 */

		/* disable quick mode */
		ret = hd29l2_wr_reg_mask(priv, 0xac, 0 << 7, 0x80);
		if (ret)
			goto err;

		ret = hd29l2_wr_reg_mask(priv, 0x82, 1 << 1, 0x02);
		if (ret)
			goto err;

		/* enable auto mode */
		ret = hd29l2_wr_reg_mask(priv, 0x7d, 1 << 6, 0x40);
		if (ret)
			goto err;

		ret = hd29l2_wr_reg_mask(priv, 0x81, 1 << 3, 0x08);
		if (ret)
			goto err;

		/* soft reset */
		ret = hd29l2_soft_reset(priv);
		if (ret)
			goto err;

		/* detect modulation */
		for (i = 30; i; i--) {
			msleep(100);

			ret = hd29l2_rd_reg(priv, 0x0d, &tmp);
			if (ret)
				goto err;

			if ((((tmp & 0xf0) >= 0x10) &&
				((tmp & 0x0f) == 0x08)) || (tmp >= 0x2c))
				break;
		}

		dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i);

		if (i == 0)
			/* detection failed */
			return DVBFE_ALGO_SEARCH_FAILED;

		/* read modulation */
		ret = hd29l2_rd_reg_mask(priv, 0x7d, &modulation, 0x07);
		if (ret)
			goto err;
	} else {
		/*
		 * use manual mode
		 */

		modulation = HD29L2_QAM64;
		carrier = HD29L2_CARRIER_MULTI;
		guard_interval = HD29L2_PN945;
		interleave = HD29L2_INTERLEAVER_420;
		code_rate = HD29L2_CODE_RATE_08;

		tmp = (code_rate << 3) | modulation;
		ret = hd29l2_wr_reg_mask(priv, 0x7d, tmp, 0x5f);
		if (ret)
			goto err;

		tmp = (carrier << 2) | guard_interval;
		ret = hd29l2_wr_reg_mask(priv, 0x81, tmp, 0x0f);
		if (ret)
			goto err;

		tmp = interleave;
		ret = hd29l2_wr_reg_mask(priv, 0x82, tmp, 0x03);
		if (ret)
			goto err;
	}

	/* ensure modulation validy */
	/* 0=QAM4_NR, 1=QAM4, 2=QAM16, 3=QAM32, 4=QAM64 */
	if (modulation > (ARRAY_SIZE(reg_mod_vals_tab[0].val) - 1)) {
		dev_dbg(&priv->i2c->dev, "%s: modulation=%d not valid\n",
				__func__, modulation);
		goto err;
	}

	/* program registers according to modulation */
	for (i = 0; i < ARRAY_SIZE(reg_mod_vals_tab); i++) {
		ret = hd29l2_wr_reg(priv, reg_mod_vals_tab[i].reg,
			reg_mod_vals_tab[i].val[modulation]);
		if (ret)
			goto err;
	}

	/* read guard interval */
	ret = hd29l2_rd_reg_mask(priv, 0x81, &guard_interval, 0x03);
	if (ret)
		goto err;

	/* read carrier mode */
	ret = hd29l2_rd_reg_mask(priv, 0x81, &carrier, 0x04);
	if (ret)
		goto err;

	dev_dbg(&priv->i2c->dev,
			"%s: modulation=%d guard_interval=%d carrier=%d\n",
			__func__, modulation, guard_interval, carrier);

	if ((carrier == HD29L2_CARRIER_MULTI) && (modulation == HD29L2_QAM64) &&
		(guard_interval == HD29L2_PN945)) {
		dev_dbg(&priv->i2c->dev, "%s: C=3780 && QAM64 && PN945\n",
				__func__);

		ret = hd29l2_wr_reg(priv, 0x42, 0x33);
		if (ret)
			goto err;

		ret = hd29l2_wr_reg(priv, 0xdd, 0x01);
		if (ret)
			goto err;
	}

	usleep_range(10000, 20000);

	/* soft reset */
	ret = hd29l2_soft_reset(priv);
	if (ret)
		goto err;

	/* wait demod lock */
	for (i = 30; i; i--) {
		msleep(100);

		/* read lock bit */
		ret = hd29l2_rd_reg_mask(priv, 0x05, &tmp, 0x01);
		if (ret)
			goto err;

		if (tmp)
			break;
	}

	dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i);

	if (i == 0)
		return DVBFE_ALGO_SEARCH_AGAIN;

	return DVBFE_ALGO_SEARCH_SUCCESS;
err:
	dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
	return DVBFE_ALGO_SEARCH_ERROR;
}

static int hd29l2_get_frontend_algo(struct dvb_frontend *fe)
{
	return DVBFE_ALGO_CUSTOM;
}

static int hd29l2_get_frontend(struct dvb_frontend *fe,
			       struct dtv_frontend_properties *c)
{
	int ret;
	struct hd29l2_priv *priv = fe->demodulator_priv;
	u8 buf[3];
	u32 if_ctl;
	char *str_constellation, *str_code_rate, *str_constellation_code_rate,
		*str_guard_interval, *str_carrier, *str_guard_interval_carrier,
		*str_interleave, *str_interleave_;

	ret = hd29l2_rd_reg(priv, 0x7d, &buf[0]);
	if (ret)
		goto err;

	ret = hd29l2_rd_regs(priv, 0x81, &buf[1], 2);
	if (ret)
		goto err;

	/* constellation, 0x7d[2:0] */
	switch ((buf[0] >> 0) & 0x07) {
	case 0: /* QAM4NR */
		str_constellation = "QAM4NR";
		c->modulation = QAM_AUTO; /* FIXME */
		break;
	case 1: /* QAM4 */
		str_constellation = "QAM4";
		c->modulation = QPSK; /* FIXME */
		break;
	case 2:
		str_constellation = "QAM16";
		c->modulation = QAM_16;
		break;
	case 3:
		str_constellation = "QAM32";
		c->modulation = QAM_32;
		break;
	case 4:
		str_constellation = "QAM64";
		c->modulation = QAM_64;
		break;
	default:
		str_constellation = "?";
	}

	/* LDPC code rate, 0x7d[4:3] */
	switch ((buf[0] >> 3) & 0x03) {
	case 0: /* 0.4 */
		str_code_rate = "0.4";
		c->fec_inner = FEC_AUTO; /* FIXME */
		break;
	case 1: /* 0.6 */
		str_code_rate = "0.6";
		c->fec_inner = FEC_3_5;
		break;
	case 2: /* 0.8 */
		str_code_rate = "0.8";
		c->fec_inner = FEC_4_5;
		break;
	default:
		str_code_rate = "?";
	}

	/* constellation & code rate set, 0x7d[6] */
	switch ((buf[0] >> 6) & 0x01) {
	case 0:
		str_constellation_code_rate = "manual";
		break;
	case 1:
		str_constellation_code_rate = "auto";
		break;
	default:
		str_constellation_code_rate = "?";
	}

	/* frame header, 0x81[1:0] */
	switch ((buf[1] >> 0) & 0x03) {
	case 0: /* PN945 */
		str_guard_interval = "PN945";
		c->guard_interval = GUARD_INTERVAL_AUTO; /* FIXME */
		break;
	case 1: /* PN595 */
		str_guard_interval = "PN595";
		c->guard_interval = GUARD_INTERVAL_AUTO; /* FIXME */
		break;
	case 2: /* PN420 */
		str_guard_interval = "PN420";
		c->guard_interval = GUARD_INTERVAL_AUTO; /* FIXME */
		break;
	default:
		str_guard_interval = "?";
	}

	/* carrier, 0x81[2] */
	switch ((buf[1] >> 2) & 0x01) {
	case 0:
		str_carrier = "C=1";
		break;
	case 1:
		str_carrier = "C=3780";
		break;
	default:
		str_carrier = "?";
	}

	/* frame header & carrier set, 0x81[3] */
	switch ((buf[1] >> 3) & 0x01) {
	case 0:
		str_guard_interval_carrier = "manual";
		break;
	case 1:
		str_guard_interval_carrier = "auto";
		break;
	default:
		str_guard_interval_carrier = "?";
	}

	/* interleave, 0x82[0] */
	switch ((buf[2] >> 0) & 0x01) {
	case 0:
		str_interleave = "M=720";
		break;
	case 1:
		str_interleave = "M=240";
		break;
	default:
		str_interleave = "?";
	}

	/* interleave set, 0x82[1] */
	switch ((buf[2] >> 1) & 0x01) {
	case 0:
		str_interleave_ = "manual";
		break;
	case 1:
		str_interleave_ = "auto";
		break;
	default:
		str_interleave_ = "?";
	}

	/*
	 * We can read out current detected NCO and use that value next
	 * time instead of calculating new value from targed IF.
	 * I think it will not effect receiver sensitivity but gaining lock
	 * after tune could be easier...
	 */
	ret = hd29l2_rd_regs(priv, 0xb1, &buf[0], 3);
	if (ret)
		goto err;

	if_ctl = (buf[0] << 16) | ((buf[1] - 7) << 8) | buf[2];

	dev_dbg(&priv->i2c->dev, "%s: %s %s %s | %s %s %s | %s %s | NCO=%06x\n",
			__func__, str_constellation, str_code_rate,
			str_constellation_code_rate, str_guard_interval,
			str_carrier, str_guard_interval_carrier, str_interleave,
			str_interleave_, if_ctl);
	return 0;
err:
	dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
	return ret;
}

static int hd29l2_init(struct dvb_frontend *fe)
{
	int ret, i;
	struct hd29l2_priv *priv = fe->demodulator_priv;
	u8 tmp;
	static const struct reg_val tab[] = {
		{ 0x3a, 0x06 },
		{ 0x3b, 0x03 },
		{ 0x3c, 0x04 },
		{ 0xaf, 0x06 },
		{ 0xb0, 0x1b },
		{ 0x80, 0x64 },
		{ 0x10, 0x38 },
	};

	dev_dbg(&priv->i2c->dev, "%s:\n", __func__);

	/* reset demod */
	/* it is recommended to HW reset chip using RST_N pin */
	if (fe->callback) {
		ret = fe->callback(fe, DVB_FRONTEND_COMPONENT_DEMOD, 0, 0);
		if (ret)
			goto err;

		/* reprogramming needed because HW reset clears registers */
		priv->tuner_i2c_addr_programmed = false;
	}

	/* init */
	for (i = 0; i < ARRAY_SIZE(tab); i++) {
		ret = hd29l2_wr_reg(priv, tab[i].reg, tab[i].val);
		if (ret)
			goto err;
	}

	/* TS params */
	ret = hd29l2_rd_reg(priv, 0x36, &tmp);
	if (ret)
		goto err;

	tmp &= 0x1b;
	tmp |= priv->cfg.ts_mode;
	ret = hd29l2_wr_reg(priv, 0x36, tmp);
	if (ret)
		goto err;

	ret = hd29l2_rd_reg(priv, 0x31, &tmp);
	tmp &= 0xef;

	if (!(priv->cfg.ts_mode >> 7))
		/* set b4 for serial TS */
		tmp |= 0x10;

	ret = hd29l2_wr_reg(priv, 0x31, tmp);
	if (ret)
		goto err;

	return ret;
err:
	dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
	return ret;
}

static void hd29l2_release(struct dvb_frontend *fe)
{
	struct hd29l2_priv *priv = fe->demodulator_priv;
	kfree(priv);
}

static struct dvb_frontend_ops hd29l2_ops;

struct dvb_frontend *hd29l2_attach(const struct hd29l2_config *config,
	struct i2c_adapter *i2c)
{
	int ret;
	struct hd29l2_priv *priv = NULL;
	u8 tmp;

	/* allocate memory for the internal state */
	priv = kzalloc(sizeof(struct hd29l2_priv), GFP_KERNEL);
	if (priv == NULL)
		goto err;

	/* setup the state */
	priv->i2c = i2c;
	memcpy(&priv->cfg, config, sizeof(struct hd29l2_config));


	/* check if the demod is there */
	ret = hd29l2_rd_reg(priv, 0x00, &tmp);
	if (ret)
		goto err;

	/* create dvb_frontend */
	memcpy(&priv->fe.ops, &hd29l2_ops, sizeof(struct dvb_frontend_ops));
	priv->fe.demodulator_priv = priv;

	return &priv->fe;
err:
	kfree(priv);
	return NULL;
}
EXPORT_SYMBOL(hd29l2_attach);

static struct dvb_frontend_ops hd29l2_ops = {
	.delsys = { SYS_DVBT },
	.info = {
		.name = "HDIC HD29L2 DMB-TH",
		.frequency_min = 474000000,
		.frequency_max = 858000000,
		.frequency_stepsize = 10000,
		.caps = FE_CAN_FEC_AUTO |
			FE_CAN_QPSK |
			FE_CAN_QAM_16 |
			FE_CAN_QAM_32 |
			FE_CAN_QAM_64 |
			FE_CAN_QAM_AUTO |
			FE_CAN_TRANSMISSION_MODE_AUTO |
			FE_CAN_BANDWIDTH_AUTO |
			FE_CAN_GUARD_INTERVAL_AUTO |
			FE_CAN_HIERARCHY_AUTO |
			FE_CAN_RECOVER
	},

	.release = hd29l2_release,

	.init = hd29l2_init,

	.get_frontend_algo = hd29l2_get_frontend_algo,
	.search = hd29l2_search,
	.get_frontend = hd29l2_get_frontend,

	.read_status = hd29l2_read_status,
	.read_snr = hd29l2_read_snr,
	.read_signal_strength = hd29l2_read_signal_strength,
	.read_ber = hd29l2_read_ber,
	.read_ucblocks = hd29l2_read_ucblocks,

	.i2c_gate_ctrl = hd29l2_i2c_gate_ctrl,
};

MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
MODULE_DESCRIPTION("HDIC HD29L2 DMB-TH demodulator driver");
MODULE_LICENSE("GPL");
