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