root/drivers/media/dvb-frontends/ec100.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ec100_write_reg
  2. ec100_read_reg
  3. ec100_set_frontend
  4. ec100_get_tune_settings
  5. ec100_read_status
  6. ec100_read_ber
  7. ec100_read_signal_strength
  8. ec100_read_snr
  9. ec100_read_ucblocks
  10. ec100_release
  11. ec100_attach

   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 
  11 struct 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 */
  20 static 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 */
  46 static 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 = &reg
  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 
  75 static 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;
 148 error:
 149         dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
 150         return ret;
 151 }
 152 
 153 static 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 
 163 static 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;
 194 error:
 195         dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
 196         return ret;
 197 }
 198 
 199 static 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;
 226 error:
 227         dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
 228         return ret;
 229 }
 230 
 231 static 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;
 246 error:
 247         dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
 248         return ret;
 249 }
 250 
 251 static int ec100_read_snr(struct dvb_frontend *fe, u16 *snr)
 252 {
 253         *snr = 0;
 254         return 0;
 255 }
 256 
 257 static int ec100_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
 258 {
 259         *ucblocks = 0;
 260         return 0;
 261 }
 262 
 263 static void ec100_release(struct dvb_frontend *fe)
 264 {
 265         struct ec100_state *state = fe->demodulator_priv;
 266         kfree(state);
 267 }
 268 
 269 static const struct dvb_frontend_ops ec100_ops;
 270 
 271 struct 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;
 298 error:
 299         kfree(state);
 300         return NULL;
 301 }
 302 EXPORT_SYMBOL(ec100_attach);
 303 
 304 static 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 
 329 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
 330 MODULE_DESCRIPTION("E3C EC100 DVB-T demodulator driver");
 331 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */