Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Sony CXD2820R demodulator driver
0004  *
0005  * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
0006  */
0007 
0008 
0009 #include "cxd2820r_priv.h"
0010 
0011 int cxd2820r_set_frontend_t(struct dvb_frontend *fe)
0012 {
0013     struct cxd2820r_priv *priv = fe->demodulator_priv;
0014     struct i2c_client *client = priv->client[0];
0015     struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0016     int ret, bw_i;
0017     unsigned int utmp;
0018     u32 if_frequency;
0019     u8 buf[3], bw_param;
0020     u8 bw_params1[][5] = {
0021         { 0x17, 0xea, 0xaa, 0xaa, 0xaa }, /* 6 MHz */
0022         { 0x14, 0x80, 0x00, 0x00, 0x00 }, /* 7 MHz */
0023         { 0x11, 0xf0, 0x00, 0x00, 0x00 }, /* 8 MHz */
0024     };
0025     u8 bw_params2[][2] = {
0026         { 0x1f, 0xdc }, /* 6 MHz */
0027         { 0x12, 0xf8 }, /* 7 MHz */
0028         { 0x01, 0xe0 }, /* 8 MHz */
0029     };
0030     struct reg_val_mask tab[] = {
0031         { 0x00080, 0x00, 0xff },
0032         { 0x00081, 0x03, 0xff },
0033         { 0x00085, 0x07, 0xff },
0034         { 0x00088, 0x01, 0xff },
0035 
0036         { 0x00070, priv->ts_mode, 0xff },
0037         { 0x00071, !priv->ts_clk_inv << 4, 0x10 },
0038         { 0x000cb, priv->if_agc_polarity << 6, 0x40 },
0039         { 0x000a5, 0x00, 0x01 },
0040         { 0x00082, 0x20, 0x60 },
0041         { 0x000c2, 0xc3, 0xff },
0042         { 0x0016a, 0x50, 0xff },
0043         { 0x00427, 0x41, 0xff },
0044     };
0045 
0046     dev_dbg(&client->dev,
0047         "delivery_system=%d modulation=%d frequency=%u bandwidth_hz=%u inversion=%d\n",
0048         c->delivery_system, c->modulation, c->frequency,
0049         c->bandwidth_hz, c->inversion);
0050 
0051     switch (c->bandwidth_hz) {
0052     case 6000000:
0053         bw_i = 0;
0054         bw_param = 2;
0055         break;
0056     case 7000000:
0057         bw_i = 1;
0058         bw_param = 1;
0059         break;
0060     case 8000000:
0061         bw_i = 2;
0062         bw_param = 0;
0063         break;
0064     default:
0065         return -EINVAL;
0066     }
0067 
0068     /* program tuner */
0069     if (fe->ops.tuner_ops.set_params)
0070         fe->ops.tuner_ops.set_params(fe);
0071 
0072     if (priv->delivery_system != SYS_DVBT) {
0073         ret = cxd2820r_wr_reg_val_mask_tab(priv, tab, ARRAY_SIZE(tab));
0074         if (ret)
0075             goto error;
0076     }
0077 
0078     priv->delivery_system = SYS_DVBT;
0079     priv->ber_running = false; /* tune stops BER counter */
0080 
0081     /* program IF frequency */
0082     if (fe->ops.tuner_ops.get_if_frequency) {
0083         ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency);
0084         if (ret)
0085             goto error;
0086         dev_dbg(&client->dev, "if_frequency=%u\n", if_frequency);
0087     } else {
0088         ret = -EINVAL;
0089         goto error;
0090     }
0091 
0092     utmp = DIV_ROUND_CLOSEST_ULL((u64)if_frequency * 0x1000000, CXD2820R_CLK);
0093     buf[0] = (utmp >> 16) & 0xff;
0094     buf[1] = (utmp >>  8) & 0xff;
0095     buf[2] = (utmp >>  0) & 0xff;
0096     ret = regmap_bulk_write(priv->regmap[0], 0x00b6, buf, 3);
0097     if (ret)
0098         goto error;
0099 
0100     ret = regmap_bulk_write(priv->regmap[0], 0x009f, bw_params1[bw_i], 5);
0101     if (ret)
0102         goto error;
0103 
0104     ret = regmap_update_bits(priv->regmap[0], 0x00d7, 0xc0, bw_param << 6);
0105     if (ret)
0106         goto error;
0107 
0108     ret = regmap_bulk_write(priv->regmap[0], 0x00d9, bw_params2[bw_i], 2);
0109     if (ret)
0110         goto error;
0111 
0112     ret = regmap_write(priv->regmap[0], 0x00ff, 0x08);
0113     if (ret)
0114         goto error;
0115 
0116     ret = regmap_write(priv->regmap[0], 0x00fe, 0x01);
0117     if (ret)
0118         goto error;
0119 
0120     return ret;
0121 error:
0122     dev_dbg(&client->dev, "failed=%d\n", ret);
0123     return ret;
0124 }
0125 
0126 int cxd2820r_get_frontend_t(struct dvb_frontend *fe,
0127                 struct dtv_frontend_properties *c)
0128 {
0129     struct cxd2820r_priv *priv = fe->demodulator_priv;
0130     struct i2c_client *client = priv->client[0];
0131     int ret;
0132     unsigned int utmp;
0133     u8 buf[2];
0134 
0135     dev_dbg(&client->dev, "\n");
0136 
0137     ret = regmap_bulk_read(priv->regmap[0], 0x002f, buf, sizeof(buf));
0138     if (ret)
0139         goto error;
0140 
0141     switch ((buf[0] >> 6) & 0x03) {
0142     case 0:
0143         c->modulation = QPSK;
0144         break;
0145     case 1:
0146         c->modulation = QAM_16;
0147         break;
0148     case 2:
0149         c->modulation = QAM_64;
0150         break;
0151     }
0152 
0153     switch ((buf[1] >> 1) & 0x03) {
0154     case 0:
0155         c->transmission_mode = TRANSMISSION_MODE_2K;
0156         break;
0157     case 1:
0158         c->transmission_mode = TRANSMISSION_MODE_8K;
0159         break;
0160     }
0161 
0162     switch ((buf[1] >> 3) & 0x03) {
0163     case 0:
0164         c->guard_interval = GUARD_INTERVAL_1_32;
0165         break;
0166     case 1:
0167         c->guard_interval = GUARD_INTERVAL_1_16;
0168         break;
0169     case 2:
0170         c->guard_interval = GUARD_INTERVAL_1_8;
0171         break;
0172     case 3:
0173         c->guard_interval = GUARD_INTERVAL_1_4;
0174         break;
0175     }
0176 
0177     switch ((buf[0] >> 3) & 0x07) {
0178     case 0:
0179         c->hierarchy = HIERARCHY_NONE;
0180         break;
0181     case 1:
0182         c->hierarchy = HIERARCHY_1;
0183         break;
0184     case 2:
0185         c->hierarchy = HIERARCHY_2;
0186         break;
0187     case 3:
0188         c->hierarchy = HIERARCHY_4;
0189         break;
0190     }
0191 
0192     switch ((buf[0] >> 0) & 0x07) {
0193     case 0:
0194         c->code_rate_HP = FEC_1_2;
0195         break;
0196     case 1:
0197         c->code_rate_HP = FEC_2_3;
0198         break;
0199     case 2:
0200         c->code_rate_HP = FEC_3_4;
0201         break;
0202     case 3:
0203         c->code_rate_HP = FEC_5_6;
0204         break;
0205     case 4:
0206         c->code_rate_HP = FEC_7_8;
0207         break;
0208     }
0209 
0210     switch ((buf[1] >> 5) & 0x07) {
0211     case 0:
0212         c->code_rate_LP = FEC_1_2;
0213         break;
0214     case 1:
0215         c->code_rate_LP = FEC_2_3;
0216         break;
0217     case 2:
0218         c->code_rate_LP = FEC_3_4;
0219         break;
0220     case 3:
0221         c->code_rate_LP = FEC_5_6;
0222         break;
0223     case 4:
0224         c->code_rate_LP = FEC_7_8;
0225         break;
0226     }
0227 
0228     ret = regmap_read(priv->regmap[0], 0x07c6, &utmp);
0229     if (ret)
0230         goto error;
0231 
0232     switch ((utmp >> 0) & 0x01) {
0233     case 0:
0234         c->inversion = INVERSION_OFF;
0235         break;
0236     case 1:
0237         c->inversion = INVERSION_ON;
0238         break;
0239     }
0240 
0241     return ret;
0242 error:
0243     dev_dbg(&client->dev, "failed=%d\n", ret);
0244     return ret;
0245 }
0246 
0247 int cxd2820r_read_status_t(struct dvb_frontend *fe, enum fe_status *status)
0248 {
0249     struct cxd2820r_priv *priv = fe->demodulator_priv;
0250     struct i2c_client *client = priv->client[0];
0251     struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0252     int ret;
0253     unsigned int utmp, utmp1, utmp2;
0254     u8 buf[3];
0255 
0256     /* Lock detection */
0257     ret = regmap_bulk_read(priv->regmap[0], 0x0010, &buf[0], 1);
0258     if (ret)
0259         goto error;
0260     ret = regmap_bulk_read(priv->regmap[0], 0x0073, &buf[1], 1);
0261     if (ret)
0262         goto error;
0263 
0264     utmp1 = (buf[0] >> 0) & 0x07;
0265     utmp2 = (buf[1] >> 3) & 0x01;
0266 
0267     if (utmp1 == 6 && utmp2 == 1) {
0268         *status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
0269               FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
0270     } else if (utmp1 == 6 || utmp2 == 1) {
0271         *status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
0272               FE_HAS_VITERBI | FE_HAS_SYNC;
0273     } else {
0274         *status = 0;
0275     }
0276 
0277     dev_dbg(&client->dev, "status=%02x raw=%*ph sync=%u ts=%u\n",
0278         *status, 2, buf, utmp1, utmp2);
0279 
0280     /* Signal strength */
0281     if (*status & FE_HAS_SIGNAL) {
0282         unsigned int strength;
0283 
0284         ret = regmap_bulk_read(priv->regmap[0], 0x0026, buf, 2);
0285         if (ret)
0286             goto error;
0287 
0288         utmp = buf[0] << 8 | buf[1] << 0;
0289         utmp = ~utmp & 0x0fff;
0290         /* Scale value to 0x0000-0xffff */
0291         strength = utmp << 4 | utmp >> 8;
0292 
0293         c->strength.len = 1;
0294         c->strength.stat[0].scale = FE_SCALE_RELATIVE;
0295         c->strength.stat[0].uvalue = strength;
0296     } else {
0297         c->strength.len = 1;
0298         c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
0299     }
0300 
0301     /* CNR */
0302     if (*status & FE_HAS_VITERBI) {
0303         unsigned int cnr;
0304 
0305         ret = regmap_bulk_read(priv->regmap[0], 0x002c, buf, 2);
0306         if (ret)
0307             goto error;
0308 
0309         utmp = buf[0] << 8 | buf[1] << 0;
0310         if (utmp)
0311             cnr = div_u64((u64)(intlog10(utmp)
0312                       - intlog10(32000 - utmp) + 55532585)
0313                       * 10000, (1 << 24));
0314         else
0315             cnr = 0;
0316 
0317         c->cnr.len = 1;
0318         c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
0319         c->cnr.stat[0].svalue = cnr;
0320     } else {
0321         c->cnr.len = 1;
0322         c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
0323     }
0324 
0325     /* BER */
0326     if (*status & FE_HAS_SYNC) {
0327         unsigned int post_bit_error;
0328         bool start_ber;
0329 
0330         if (priv->ber_running) {
0331             ret = regmap_bulk_read(priv->regmap[0], 0x0076, buf, 3);
0332             if (ret)
0333                 goto error;
0334 
0335             if ((buf[2] >> 7) & 0x01) {
0336                 post_bit_error = buf[2] << 16 | buf[1] << 8 |
0337                          buf[0] << 0;
0338                 post_bit_error &= 0x0fffff;
0339                 start_ber = true;
0340             } else {
0341                 post_bit_error = 0;
0342                 start_ber = false;
0343             }
0344         } else {
0345             post_bit_error = 0;
0346             start_ber = true;
0347         }
0348 
0349         if (start_ber) {
0350             ret = regmap_write(priv->regmap[0], 0x0079, 0x01);
0351             if (ret)
0352                 goto error;
0353             priv->ber_running = true;
0354         }
0355 
0356         priv->post_bit_error += post_bit_error;
0357 
0358         c->post_bit_error.len = 1;
0359         c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
0360         c->post_bit_error.stat[0].uvalue = priv->post_bit_error;
0361     } else {
0362         c->post_bit_error.len = 1;
0363         c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
0364     }
0365 
0366     return ret;
0367 error:
0368     dev_dbg(&client->dev, "failed=%d\n", ret);
0369     return ret;
0370 }
0371 
0372 int cxd2820r_init_t(struct dvb_frontend *fe)
0373 {
0374     struct cxd2820r_priv *priv = fe->demodulator_priv;
0375     struct i2c_client *client = priv->client[0];
0376     int ret;
0377 
0378     dev_dbg(&client->dev, "\n");
0379 
0380     ret = regmap_write(priv->regmap[0], 0x0085, 0x07);
0381     if (ret)
0382         goto error;
0383 
0384     return ret;
0385 error:
0386     dev_dbg(&client->dev, "failed=%d\n", ret);
0387     return ret;
0388 }
0389 
0390 int cxd2820r_sleep_t(struct dvb_frontend *fe)
0391 {
0392     struct cxd2820r_priv *priv = fe->demodulator_priv;
0393     struct i2c_client *client = priv->client[0];
0394     int ret;
0395     static struct reg_val_mask tab[] = {
0396         { 0x000ff, 0x1f, 0xff },
0397         { 0x00085, 0x00, 0xff },
0398         { 0x00088, 0x01, 0xff },
0399         { 0x00081, 0x00, 0xff },
0400         { 0x00080, 0x00, 0xff },
0401     };
0402 
0403     dev_dbg(&client->dev, "\n");
0404 
0405     priv->delivery_system = SYS_UNDEFINED;
0406 
0407     ret = cxd2820r_wr_reg_val_mask_tab(priv, tab, ARRAY_SIZE(tab));
0408     if (ret)
0409         goto error;
0410 
0411     return ret;
0412 error:
0413     dev_dbg(&client->dev, "failed=%d\n", ret);
0414     return ret;
0415 }
0416 
0417 int cxd2820r_get_tune_settings_t(struct dvb_frontend *fe,
0418     struct dvb_frontend_tune_settings *s)
0419 {
0420     s->min_delay_ms = 500;
0421     s->step_size = fe->ops.info.frequency_stepsize_hz * 2;
0422     s->max_drift = (fe->ops.info.frequency_stepsize_hz * 2) + 1;
0423 
0424     return 0;
0425 }