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 = ®
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