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