^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * E3C EC100 demodulator driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <media/dvb_frontend.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "ec100.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) struct ec100_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) struct i2c_adapter *i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) struct dvb_frontend frontend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) struct ec100_config config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) u16 ber;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /* write single register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static int ec100_write_reg(struct ec100_state *state, u8 reg, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) u8 buf[2] = {reg, val};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct i2c_msg msg[1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) .addr = state->config.demod_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) .len = sizeof(buf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) .buf = buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) ret = i2c_transfer(state->i2c, msg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) if (ret == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) dev_warn(&state->i2c->dev, "%s: i2c wr failed=%d reg=%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) KBUILD_MODNAME, ret, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) ret = -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /* read single register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static int ec100_read_reg(struct ec100_state *state, u8 reg, u8 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct i2c_msg msg[2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) .addr = state->config.demod_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) .len = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) .buf = ®
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .addr = state->config.demod_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) .flags = I2C_M_RD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) .len = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) .buf = val
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) ret = i2c_transfer(state->i2c, msg, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if (ret == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) dev_warn(&state->i2c->dev, "%s: i2c rd failed=%d reg=%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) KBUILD_MODNAME, ret, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) ret = -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) static int ec100_set_frontend(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct ec100_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) u8 tmp, tmp2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) dev_dbg(&state->i2c->dev, "%s: frequency=%d bandwidth_hz=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) __func__, c->frequency, c->bandwidth_hz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /* program tuner */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) if (fe->ops.tuner_ops.set_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) fe->ops.tuner_ops.set_params(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) ret = ec100_write_reg(state, 0x04, 0x06);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) ret = ec100_write_reg(state, 0x67, 0x58);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) ret = ec100_write_reg(state, 0x05, 0x18);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) /* reg/bw | 6 | 7 | 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) -------+------+------+------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) A 0x1b | 0xa1 | 0xe7 | 0x2c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) A 0x1c | 0x55 | 0x63 | 0x72
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) -------+------+------+------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) B 0x1b | 0xb7 | 0x00 | 0x49
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) B 0x1c | 0x55 | 0x64 | 0x72 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) switch (c->bandwidth_hz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) case 6000000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) tmp = 0xb7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) tmp2 = 0x55;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) case 7000000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) tmp = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) tmp2 = 0x64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) case 8000000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) tmp = 0x49;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) tmp2 = 0x72;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) ret = ec100_write_reg(state, 0x1b, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) ret = ec100_write_reg(state, 0x1c, tmp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) ret = ec100_write_reg(state, 0x0c, 0xbb); /* if freq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) ret = ec100_write_reg(state, 0x0d, 0x31); /* if freq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) ret = ec100_write_reg(state, 0x08, 0x24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) ret = ec100_write_reg(state, 0x00, 0x00); /* go */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) ret = ec100_write_reg(state, 0x00, 0x20); /* go */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) static int ec100_get_tune_settings(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) struct dvb_frontend_tune_settings *fesettings)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) fesettings->min_delay_ms = 300;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) fesettings->step_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) fesettings->max_drift = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) static int ec100_read_status(struct dvb_frontend *fe, enum fe_status *status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) struct ec100_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) u8 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) *status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) ret = ec100_read_reg(state, 0x42, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (tmp & 0x80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /* bit7 set - have lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) FE_HAS_SYNC | FE_HAS_LOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) ret = ec100_read_reg(state, 0x01, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (tmp & 0x10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /* bit4 set - have signal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) *status |= FE_HAS_SIGNAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (!(tmp & 0x01)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /* bit0 clear - have ~valid signal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) *status |= FE_HAS_CARRIER | FE_HAS_VITERBI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) static int ec100_read_ber(struct dvb_frontend *fe, u32 *ber)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct ec100_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) u8 tmp, tmp2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) u16 ber2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) *ber = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) ret = ec100_read_reg(state, 0x65, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) ret = ec100_read_reg(state, 0x66, &tmp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) ber2 = (tmp2 << 8) | tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /* if counter overflow or clear */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (ber2 < state->ber)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) *ber = ber2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) *ber = ber2 - state->ber;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) state->ber = ber2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) static int ec100_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) struct ec100_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) u8 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) ret = ec100_read_reg(state, 0x24, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) *strength = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) *strength = ((tmp << 8) | tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) static int ec100_read_snr(struct dvb_frontend *fe, u16 *snr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) *snr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) static int ec100_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) *ucblocks = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static void ec100_release(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) struct ec100_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) kfree(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) static const struct dvb_frontend_ops ec100_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) struct dvb_frontend *ec100_attach(const struct ec100_config *config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) struct i2c_adapter *i2c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) struct ec100_state *state = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) u8 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) /* allocate memory for the internal state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) state = kzalloc(sizeof(struct ec100_state), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (state == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) /* setup the state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) state->i2c = i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) memcpy(&state->config, config, sizeof(struct ec100_config));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) /* check if the demod is there */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) ret = ec100_read_reg(state, 0x33, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (ret || tmp != 0x0b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) /* create dvb_frontend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) memcpy(&state->frontend.ops, &ec100_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) sizeof(struct dvb_frontend_ops));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) state->frontend.demodulator_priv = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return &state->frontend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) kfree(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) EXPORT_SYMBOL(ec100_attach);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) static const struct dvb_frontend_ops ec100_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) .delsys = { SYS_DVBT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) .info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) .name = "E3C EC100 DVB-T",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) .caps =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) FE_CAN_QPSK | FE_CAN_QAM_16 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) FE_CAN_TRANSMISSION_MODE_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) FE_CAN_GUARD_INTERVAL_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) FE_CAN_HIERARCHY_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) FE_CAN_MUTE_TS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) .release = ec100_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) .set_frontend = ec100_set_frontend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) .get_tune_settings = ec100_get_tune_settings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) .read_status = ec100_read_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) .read_ber = ec100_read_ber,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) .read_signal_strength = ec100_read_signal_strength,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) .read_snr = ec100_read_snr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) .read_ucblocks = ec100_read_ucblocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) MODULE_DESCRIPTION("E3C EC100 DVB-T demodulator driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) MODULE_LICENSE("GPL");