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