1c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
29a0bf528SMauro Carvalho Chehab /*
39a0bf528SMauro Carvalho Chehab  * E3C EC100 demodulator driver
49a0bf528SMauro Carvalho Chehab  *
59a0bf528SMauro Carvalho Chehab  * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
69a0bf528SMauro Carvalho Chehab  */
79a0bf528SMauro Carvalho Chehab 
8fada1935SMauro Carvalho Chehab #include <media/dvb_frontend.h>
99a0bf528SMauro Carvalho Chehab #include "ec100.h"
109a0bf528SMauro Carvalho Chehab 
119a0bf528SMauro Carvalho Chehab struct ec100_state {
129a0bf528SMauro Carvalho Chehab 	struct i2c_adapter *i2c;
139a0bf528SMauro Carvalho Chehab 	struct dvb_frontend frontend;
149a0bf528SMauro Carvalho Chehab 	struct ec100_config config;
159a0bf528SMauro Carvalho Chehab 
169a0bf528SMauro Carvalho Chehab 	u16 ber;
179a0bf528SMauro Carvalho Chehab };
189a0bf528SMauro Carvalho Chehab 
199a0bf528SMauro Carvalho Chehab /* write single register */
ec100_write_reg(struct ec100_state * state,u8 reg,u8 val)209a0bf528SMauro Carvalho Chehab static int ec100_write_reg(struct ec100_state *state, u8 reg, u8 val)
219a0bf528SMauro Carvalho Chehab {
220d2d6031SAntti Palosaari 	int ret;
239a0bf528SMauro Carvalho Chehab 	u8 buf[2] = {reg, val};
240d2d6031SAntti Palosaari 	struct i2c_msg msg[1] = {
250d2d6031SAntti Palosaari 		{
269a0bf528SMauro Carvalho Chehab 			.addr = state->config.demod_address,
279a0bf528SMauro Carvalho Chehab 			.flags = 0,
280d2d6031SAntti Palosaari 			.len = sizeof(buf),
290d2d6031SAntti Palosaari 			.buf = buf,
309a0bf528SMauro Carvalho Chehab 		}
310d2d6031SAntti Palosaari 	};
320d2d6031SAntti Palosaari 
330d2d6031SAntti Palosaari 	ret = i2c_transfer(state->i2c, msg, 1);
340d2d6031SAntti Palosaari 	if (ret == 1) {
350d2d6031SAntti Palosaari 		ret = 0;
360d2d6031SAntti Palosaari 	} else {
370d2d6031SAntti Palosaari 		dev_warn(&state->i2c->dev, "%s: i2c wr failed=%d reg=%02x\n",
380d2d6031SAntti Palosaari 				KBUILD_MODNAME, ret, reg);
390d2d6031SAntti Palosaari 		ret = -EREMOTEIO;
400d2d6031SAntti Palosaari 	}
410d2d6031SAntti Palosaari 
420d2d6031SAntti Palosaari 	return ret;
439a0bf528SMauro Carvalho Chehab }
449a0bf528SMauro Carvalho Chehab 
459a0bf528SMauro Carvalho Chehab /* read single register */
ec100_read_reg(struct ec100_state * state,u8 reg,u8 * val)469a0bf528SMauro Carvalho Chehab static int ec100_read_reg(struct ec100_state *state, u8 reg, u8 *val)
479a0bf528SMauro Carvalho Chehab {
480d2d6031SAntti Palosaari 	int ret;
499a0bf528SMauro Carvalho Chehab 	struct i2c_msg msg[2] = {
509a0bf528SMauro Carvalho Chehab 		{
519a0bf528SMauro Carvalho Chehab 			.addr = state->config.demod_address,
529a0bf528SMauro Carvalho Chehab 			.flags = 0,
539a0bf528SMauro Carvalho Chehab 			.len = 1,
549a0bf528SMauro Carvalho Chehab 			.buf = &reg
559a0bf528SMauro Carvalho Chehab 		}, {
569a0bf528SMauro Carvalho Chehab 			.addr = state->config.demod_address,
579a0bf528SMauro Carvalho Chehab 			.flags = I2C_M_RD,
589a0bf528SMauro Carvalho Chehab 			.len = 1,
599a0bf528SMauro Carvalho Chehab 			.buf = val
609a0bf528SMauro Carvalho Chehab 		}
619a0bf528SMauro Carvalho Chehab 	};
629a0bf528SMauro Carvalho Chehab 
630d2d6031SAntti Palosaari 	ret = i2c_transfer(state->i2c, msg, 2);
640d2d6031SAntti Palosaari 	if (ret == 2) {
650d2d6031SAntti Palosaari 		ret = 0;
660d2d6031SAntti Palosaari 	} else {
670d2d6031SAntti Palosaari 		dev_warn(&state->i2c->dev, "%s: i2c rd failed=%d reg=%02x\n",
680d2d6031SAntti Palosaari 				KBUILD_MODNAME, ret, reg);
690d2d6031SAntti Palosaari 		ret = -EREMOTEIO;
709a0bf528SMauro Carvalho Chehab 	}
710d2d6031SAntti Palosaari 
720d2d6031SAntti Palosaari 	return ret;
739a0bf528SMauro Carvalho Chehab }
749a0bf528SMauro Carvalho Chehab 
ec100_set_frontend(struct dvb_frontend * fe)759a0bf528SMauro Carvalho Chehab static int ec100_set_frontend(struct dvb_frontend *fe)
769a0bf528SMauro Carvalho Chehab {
779a0bf528SMauro Carvalho Chehab 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
789a0bf528SMauro Carvalho Chehab 	struct ec100_state *state = fe->demodulator_priv;
799a0bf528SMauro Carvalho Chehab 	int ret;
809a0bf528SMauro Carvalho Chehab 	u8 tmp, tmp2;
819a0bf528SMauro Carvalho Chehab 
8220399b3bSAntti Palosaari 	dev_dbg(&state->i2c->dev, "%s: frequency=%d bandwidth_hz=%d\n",
8320399b3bSAntti Palosaari 			__func__, c->frequency, c->bandwidth_hz);
849a0bf528SMauro Carvalho Chehab 
859a0bf528SMauro Carvalho Chehab 	/* program tuner */
869a0bf528SMauro Carvalho Chehab 	if (fe->ops.tuner_ops.set_params)
879a0bf528SMauro Carvalho Chehab 		fe->ops.tuner_ops.set_params(fe);
889a0bf528SMauro Carvalho Chehab 
899a0bf528SMauro Carvalho Chehab 	ret = ec100_write_reg(state, 0x04, 0x06);
909a0bf528SMauro Carvalho Chehab 	if (ret)
919a0bf528SMauro Carvalho Chehab 		goto error;
929a0bf528SMauro Carvalho Chehab 	ret = ec100_write_reg(state, 0x67, 0x58);
939a0bf528SMauro Carvalho Chehab 	if (ret)
949a0bf528SMauro Carvalho Chehab 		goto error;
959a0bf528SMauro Carvalho Chehab 	ret = ec100_write_reg(state, 0x05, 0x18);
969a0bf528SMauro Carvalho Chehab 	if (ret)
979a0bf528SMauro Carvalho Chehab 		goto error;
989a0bf528SMauro Carvalho Chehab 
999a0bf528SMauro Carvalho Chehab 	/* reg/bw |   6  |   7  |   8
1009a0bf528SMauro Carvalho Chehab 	   -------+------+------+------
1019a0bf528SMauro Carvalho Chehab 	   A 0x1b | 0xa1 | 0xe7 | 0x2c
1029a0bf528SMauro Carvalho Chehab 	   A 0x1c | 0x55 | 0x63 | 0x72
1039a0bf528SMauro Carvalho Chehab 	   -------+------+------+------
1049a0bf528SMauro Carvalho Chehab 	   B 0x1b | 0xb7 | 0x00 | 0x49
1059a0bf528SMauro Carvalho Chehab 	   B 0x1c | 0x55 | 0x64 | 0x72 */
1069a0bf528SMauro Carvalho Chehab 
1079a0bf528SMauro Carvalho Chehab 	switch (c->bandwidth_hz) {
1089a0bf528SMauro Carvalho Chehab 	case 6000000:
1099a0bf528SMauro Carvalho Chehab 		tmp = 0xb7;
1109a0bf528SMauro Carvalho Chehab 		tmp2 = 0x55;
1119a0bf528SMauro Carvalho Chehab 		break;
1129a0bf528SMauro Carvalho Chehab 	case 7000000:
1139a0bf528SMauro Carvalho Chehab 		tmp = 0x00;
1149a0bf528SMauro Carvalho Chehab 		tmp2 = 0x64;
1159a0bf528SMauro Carvalho Chehab 		break;
1169a0bf528SMauro Carvalho Chehab 	case 8000000:
1179a0bf528SMauro Carvalho Chehab 	default:
1189a0bf528SMauro Carvalho Chehab 		tmp = 0x49;
1199a0bf528SMauro Carvalho Chehab 		tmp2 = 0x72;
1209a0bf528SMauro Carvalho Chehab 	}
1219a0bf528SMauro Carvalho Chehab 
1229a0bf528SMauro Carvalho Chehab 	ret = ec100_write_reg(state, 0x1b, tmp);
1239a0bf528SMauro Carvalho Chehab 	if (ret)
1249a0bf528SMauro Carvalho Chehab 		goto error;
1259a0bf528SMauro Carvalho Chehab 	ret = ec100_write_reg(state, 0x1c, tmp2);
1269a0bf528SMauro Carvalho Chehab 	if (ret)
1279a0bf528SMauro Carvalho Chehab 		goto error;
1289a0bf528SMauro Carvalho Chehab 
1299a0bf528SMauro Carvalho Chehab 	ret = ec100_write_reg(state, 0x0c, 0xbb); /* if freq */
1309a0bf528SMauro Carvalho Chehab 	if (ret)
1319a0bf528SMauro Carvalho Chehab 		goto error;
1329a0bf528SMauro Carvalho Chehab 	ret = ec100_write_reg(state, 0x0d, 0x31); /* if freq */
1339a0bf528SMauro Carvalho Chehab 	if (ret)
1349a0bf528SMauro Carvalho Chehab 		goto error;
1359a0bf528SMauro Carvalho Chehab 
1369a0bf528SMauro Carvalho Chehab 	ret = ec100_write_reg(state, 0x08, 0x24);
1379a0bf528SMauro Carvalho Chehab 	if (ret)
1389a0bf528SMauro Carvalho Chehab 		goto error;
1399a0bf528SMauro Carvalho Chehab 
1409a0bf528SMauro Carvalho Chehab 	ret = ec100_write_reg(state, 0x00, 0x00); /* go */
1419a0bf528SMauro Carvalho Chehab 	if (ret)
1429a0bf528SMauro Carvalho Chehab 		goto error;
1439a0bf528SMauro Carvalho Chehab 	ret = ec100_write_reg(state, 0x00, 0x20); /* go */
1449a0bf528SMauro Carvalho Chehab 	if (ret)
1459a0bf528SMauro Carvalho Chehab 		goto error;
1469a0bf528SMauro Carvalho Chehab 
1479a0bf528SMauro Carvalho Chehab 	return ret;
1489a0bf528SMauro Carvalho Chehab error:
14920399b3bSAntti Palosaari 	dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
1509a0bf528SMauro Carvalho Chehab 	return ret;
1519a0bf528SMauro Carvalho Chehab }
1529a0bf528SMauro Carvalho Chehab 
ec100_get_tune_settings(struct dvb_frontend * fe,struct dvb_frontend_tune_settings * fesettings)1539a0bf528SMauro Carvalho Chehab static int ec100_get_tune_settings(struct dvb_frontend *fe,
1549a0bf528SMauro Carvalho Chehab 	struct dvb_frontend_tune_settings *fesettings)
1559a0bf528SMauro Carvalho Chehab {
1569a0bf528SMauro Carvalho Chehab 	fesettings->min_delay_ms = 300;
1579a0bf528SMauro Carvalho Chehab 	fesettings->step_size = 0;
1589a0bf528SMauro Carvalho Chehab 	fesettings->max_drift = 0;
1599a0bf528SMauro Carvalho Chehab 
1609a0bf528SMauro Carvalho Chehab 	return 0;
1619a0bf528SMauro Carvalho Chehab }
1629a0bf528SMauro Carvalho Chehab 
ec100_read_status(struct dvb_frontend * fe,enum fe_status * status)1630df289a2SMauro Carvalho Chehab static int ec100_read_status(struct dvb_frontend *fe, enum fe_status *status)
1649a0bf528SMauro Carvalho Chehab {
1659a0bf528SMauro Carvalho Chehab 	struct ec100_state *state = fe->demodulator_priv;
1669a0bf528SMauro Carvalho Chehab 	int ret;
1679a0bf528SMauro Carvalho Chehab 	u8 tmp;
1689a0bf528SMauro Carvalho Chehab 	*status = 0;
1699a0bf528SMauro Carvalho Chehab 
1709a0bf528SMauro Carvalho Chehab 	ret = ec100_read_reg(state, 0x42, &tmp);
1719a0bf528SMauro Carvalho Chehab 	if (ret)
1729a0bf528SMauro Carvalho Chehab 		goto error;
1739a0bf528SMauro Carvalho Chehab 
1749a0bf528SMauro Carvalho Chehab 	if (tmp & 0x80) {
1759a0bf528SMauro Carvalho Chehab 		/* bit7 set - have lock */
1769a0bf528SMauro Carvalho Chehab 		*status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
1779a0bf528SMauro Carvalho Chehab 			FE_HAS_SYNC | FE_HAS_LOCK;
1789a0bf528SMauro Carvalho Chehab 	} else {
1799a0bf528SMauro Carvalho Chehab 		ret = ec100_read_reg(state, 0x01, &tmp);
1809a0bf528SMauro Carvalho Chehab 		if (ret)
1819a0bf528SMauro Carvalho Chehab 			goto error;
1829a0bf528SMauro Carvalho Chehab 
1839a0bf528SMauro Carvalho Chehab 		if (tmp & 0x10) {
1849a0bf528SMauro Carvalho Chehab 			/* bit4 set - have signal */
1859a0bf528SMauro Carvalho Chehab 			*status |= FE_HAS_SIGNAL;
1869a0bf528SMauro Carvalho Chehab 			if (!(tmp & 0x01)) {
1879a0bf528SMauro Carvalho Chehab 				/* bit0 clear - have ~valid signal */
1889a0bf528SMauro Carvalho Chehab 				*status |= FE_HAS_CARRIER |  FE_HAS_VITERBI;
1899a0bf528SMauro Carvalho Chehab 			}
1909a0bf528SMauro Carvalho Chehab 		}
1919a0bf528SMauro Carvalho Chehab 	}
1929a0bf528SMauro Carvalho Chehab 
1939a0bf528SMauro Carvalho Chehab 	return ret;
1949a0bf528SMauro Carvalho Chehab error:
19520399b3bSAntti Palosaari 	dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
1969a0bf528SMauro Carvalho Chehab 	return ret;
1979a0bf528SMauro Carvalho Chehab }
1989a0bf528SMauro Carvalho Chehab 
ec100_read_ber(struct dvb_frontend * fe,u32 * ber)1999a0bf528SMauro Carvalho Chehab static int ec100_read_ber(struct dvb_frontend *fe, u32 *ber)
2009a0bf528SMauro Carvalho Chehab {
2019a0bf528SMauro Carvalho Chehab 	struct ec100_state *state = fe->demodulator_priv;
2029a0bf528SMauro Carvalho Chehab 	int ret;
2039a0bf528SMauro Carvalho Chehab 	u8 tmp, tmp2;
2049a0bf528SMauro Carvalho Chehab 	u16 ber2;
2059a0bf528SMauro Carvalho Chehab 
2069a0bf528SMauro Carvalho Chehab 	*ber = 0;
2079a0bf528SMauro Carvalho Chehab 
2089a0bf528SMauro Carvalho Chehab 	ret = ec100_read_reg(state, 0x65, &tmp);
2099a0bf528SMauro Carvalho Chehab 	if (ret)
2109a0bf528SMauro Carvalho Chehab 		goto error;
2119a0bf528SMauro Carvalho Chehab 	ret = ec100_read_reg(state, 0x66, &tmp2);
2129a0bf528SMauro Carvalho Chehab 	if (ret)
2139a0bf528SMauro Carvalho Chehab 		goto error;
2149a0bf528SMauro Carvalho Chehab 
2159a0bf528SMauro Carvalho Chehab 	ber2 = (tmp2 << 8) | tmp;
2169a0bf528SMauro Carvalho Chehab 
2179a0bf528SMauro Carvalho Chehab 	/* if counter overflow or clear */
2189a0bf528SMauro Carvalho Chehab 	if (ber2 < state->ber)
2199a0bf528SMauro Carvalho Chehab 		*ber = ber2;
2209a0bf528SMauro Carvalho Chehab 	else
2219a0bf528SMauro Carvalho Chehab 		*ber = ber2 - state->ber;
2229a0bf528SMauro Carvalho Chehab 
2239a0bf528SMauro Carvalho Chehab 	state->ber = ber2;
2249a0bf528SMauro Carvalho Chehab 
2259a0bf528SMauro Carvalho Chehab 	return ret;
2269a0bf528SMauro Carvalho Chehab error:
22720399b3bSAntti Palosaari 	dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
2289a0bf528SMauro Carvalho Chehab 	return ret;
2299a0bf528SMauro Carvalho Chehab }
2309a0bf528SMauro Carvalho Chehab 
ec100_read_signal_strength(struct dvb_frontend * fe,u16 * strength)2319a0bf528SMauro Carvalho Chehab static int ec100_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
2329a0bf528SMauro Carvalho Chehab {
2339a0bf528SMauro Carvalho Chehab 	struct ec100_state *state = fe->demodulator_priv;
2349a0bf528SMauro Carvalho Chehab 	int ret;
2359a0bf528SMauro Carvalho Chehab 	u8 tmp;
2369a0bf528SMauro Carvalho Chehab 
2379a0bf528SMauro Carvalho Chehab 	ret = ec100_read_reg(state, 0x24, &tmp);
2389a0bf528SMauro Carvalho Chehab 	if (ret) {
2399a0bf528SMauro Carvalho Chehab 		*strength = 0;
2409a0bf528SMauro Carvalho Chehab 		goto error;
2419a0bf528SMauro Carvalho Chehab 	}
2429a0bf528SMauro Carvalho Chehab 
2439a0bf528SMauro Carvalho Chehab 	*strength = ((tmp << 8) | tmp);
2449a0bf528SMauro Carvalho Chehab 
2459a0bf528SMauro Carvalho Chehab 	return ret;
2469a0bf528SMauro Carvalho Chehab error:
24720399b3bSAntti Palosaari 	dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
2489a0bf528SMauro Carvalho Chehab 	return ret;
2499a0bf528SMauro Carvalho Chehab }
2509a0bf528SMauro Carvalho Chehab 
ec100_read_snr(struct dvb_frontend * fe,u16 * snr)2519a0bf528SMauro Carvalho Chehab static int ec100_read_snr(struct dvb_frontend *fe, u16 *snr)
2529a0bf528SMauro Carvalho Chehab {
2539a0bf528SMauro Carvalho Chehab 	*snr = 0;
2549a0bf528SMauro Carvalho Chehab 	return 0;
2559a0bf528SMauro Carvalho Chehab }
2569a0bf528SMauro Carvalho Chehab 
ec100_read_ucblocks(struct dvb_frontend * fe,u32 * ucblocks)2579a0bf528SMauro Carvalho Chehab static int ec100_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
2589a0bf528SMauro Carvalho Chehab {
2599a0bf528SMauro Carvalho Chehab 	*ucblocks = 0;
2609a0bf528SMauro Carvalho Chehab 	return 0;
2619a0bf528SMauro Carvalho Chehab }
2629a0bf528SMauro Carvalho Chehab 
ec100_release(struct dvb_frontend * fe)2639a0bf528SMauro Carvalho Chehab static void ec100_release(struct dvb_frontend *fe)
2649a0bf528SMauro Carvalho Chehab {
2659a0bf528SMauro Carvalho Chehab 	struct ec100_state *state = fe->demodulator_priv;
2669a0bf528SMauro Carvalho Chehab 	kfree(state);
2679a0bf528SMauro Carvalho Chehab }
2689a0bf528SMauro Carvalho Chehab 
269bd336e63SMax Kellermann static const struct dvb_frontend_ops ec100_ops;
2709a0bf528SMauro Carvalho Chehab 
ec100_attach(const struct ec100_config * config,struct i2c_adapter * i2c)2719a0bf528SMauro Carvalho Chehab struct dvb_frontend *ec100_attach(const struct ec100_config *config,
2729a0bf528SMauro Carvalho Chehab 	struct i2c_adapter *i2c)
2739a0bf528SMauro Carvalho Chehab {
2749a0bf528SMauro Carvalho Chehab 	int ret;
2759a0bf528SMauro Carvalho Chehab 	struct ec100_state *state = NULL;
2769a0bf528SMauro Carvalho Chehab 	u8 tmp;
2779a0bf528SMauro Carvalho Chehab 
2789a0bf528SMauro Carvalho Chehab 	/* allocate memory for the internal state */
2799a0bf528SMauro Carvalho Chehab 	state = kzalloc(sizeof(struct ec100_state), GFP_KERNEL);
2809a0bf528SMauro Carvalho Chehab 	if (state == NULL)
2819a0bf528SMauro Carvalho Chehab 		goto error;
2829a0bf528SMauro Carvalho Chehab 
2839a0bf528SMauro Carvalho Chehab 	/* setup the state */
2849a0bf528SMauro Carvalho Chehab 	state->i2c = i2c;
2859a0bf528SMauro Carvalho Chehab 	memcpy(&state->config, config, sizeof(struct ec100_config));
2869a0bf528SMauro Carvalho Chehab 
2879a0bf528SMauro Carvalho Chehab 	/* check if the demod is there */
2889a0bf528SMauro Carvalho Chehab 	ret = ec100_read_reg(state, 0x33, &tmp);
2899a0bf528SMauro Carvalho Chehab 	if (ret || tmp != 0x0b)
2909a0bf528SMauro Carvalho Chehab 		goto error;
2919a0bf528SMauro Carvalho Chehab 
2929a0bf528SMauro Carvalho Chehab 	/* create dvb_frontend */
2939a0bf528SMauro Carvalho Chehab 	memcpy(&state->frontend.ops, &ec100_ops,
2949a0bf528SMauro Carvalho Chehab 		sizeof(struct dvb_frontend_ops));
2959a0bf528SMauro Carvalho Chehab 	state->frontend.demodulator_priv = state;
2969a0bf528SMauro Carvalho Chehab 
2979a0bf528SMauro Carvalho Chehab 	return &state->frontend;
2989a0bf528SMauro Carvalho Chehab error:
2999a0bf528SMauro Carvalho Chehab 	kfree(state);
3009a0bf528SMauro Carvalho Chehab 	return NULL;
3019a0bf528SMauro Carvalho Chehab }
302*86495af1SGreg Kroah-Hartman EXPORT_SYMBOL_GPL(ec100_attach);
3039a0bf528SMauro Carvalho Chehab 
304bd336e63SMax Kellermann static const struct dvb_frontend_ops ec100_ops = {
3059a0bf528SMauro Carvalho Chehab 	.delsys = { SYS_DVBT },
3069a0bf528SMauro Carvalho Chehab 	.info = {
3079a0bf528SMauro Carvalho Chehab 		.name = "E3C EC100 DVB-T",
3089a0bf528SMauro Carvalho Chehab 		.caps =
3099a0bf528SMauro Carvalho Chehab 			FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
3109a0bf528SMauro Carvalho Chehab 			FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
3119a0bf528SMauro Carvalho Chehab 			FE_CAN_QPSK | FE_CAN_QAM_16 |
3129a0bf528SMauro Carvalho Chehab 			FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
3139a0bf528SMauro Carvalho Chehab 			FE_CAN_TRANSMISSION_MODE_AUTO |
3149a0bf528SMauro Carvalho Chehab 			FE_CAN_GUARD_INTERVAL_AUTO |
3159a0bf528SMauro Carvalho Chehab 			FE_CAN_HIERARCHY_AUTO |
3169a0bf528SMauro Carvalho Chehab 			FE_CAN_MUTE_TS
3179a0bf528SMauro Carvalho Chehab 	},
3189a0bf528SMauro Carvalho Chehab 
3199a0bf528SMauro Carvalho Chehab 	.release = ec100_release,
3209a0bf528SMauro Carvalho Chehab 	.set_frontend = ec100_set_frontend,
3219a0bf528SMauro Carvalho Chehab 	.get_tune_settings = ec100_get_tune_settings,
3229a0bf528SMauro Carvalho Chehab 	.read_status = ec100_read_status,
3239a0bf528SMauro Carvalho Chehab 	.read_ber = ec100_read_ber,
3249a0bf528SMauro Carvalho Chehab 	.read_signal_strength = ec100_read_signal_strength,
3259a0bf528SMauro Carvalho Chehab 	.read_snr = ec100_read_snr,
3269a0bf528SMauro Carvalho Chehab 	.read_ucblocks = ec100_read_ucblocks,
3279a0bf528SMauro Carvalho Chehab };
3289a0bf528SMauro Carvalho Chehab 
3299a0bf528SMauro Carvalho Chehab MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
3309a0bf528SMauro Carvalho Chehab MODULE_DESCRIPTION("E3C EC100 DVB-T demodulator driver");
3319a0bf528SMauro Carvalho Chehab MODULE_LICENSE("GPL");
332