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