linux/drivers/media/dvb/frontends/ec100.c
<<
>>
Prefs
   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 = &reg
  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