^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Sony CXD2820R demodulator driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "cxd2820r_priv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) int cxd2820r_set_frontend_c(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) struct cxd2820r_priv *priv = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) struct i2c_client *client = priv->client[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) unsigned int utmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) u8 buf[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) u32 if_frequency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) struct reg_val_mask tab[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) { 0x00080, 0x01, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) { 0x00081, 0x05, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) { 0x00085, 0x07, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) { 0x00088, 0x01, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) { 0x00082, 0x20, 0x60 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) { 0x1016a, 0x48, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) { 0x100a5, 0x00, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) { 0x10020, 0x06, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) { 0x10059, 0x50, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) { 0x10087, 0x0c, 0x3c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) { 0x1008b, 0x07, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) { 0x1001f, priv->if_agc_polarity << 7, 0x80 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) { 0x10070, priv->ts_mode, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) { 0x10071, !priv->ts_clk_inv << 4, 0x10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) dev_dbg(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) "delivery_system=%d modulation=%d frequency=%u symbol_rate=%u inversion=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) c->delivery_system, c->modulation, c->frequency,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) c->symbol_rate, c->inversion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /* program tuner */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) if (fe->ops.tuner_ops.set_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) fe->ops.tuner_ops.set_params(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) if (priv->delivery_system != SYS_DVBC_ANNEX_A) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) ret = cxd2820r_wr_reg_val_mask_tab(priv, tab, ARRAY_SIZE(tab));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) priv->delivery_system = SYS_DVBC_ANNEX_A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) priv->ber_running = false; /* tune stops BER counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /* program IF frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if (fe->ops.tuner_ops.get_if_frequency) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) dev_dbg(&client->dev, "if_frequency=%u\n", if_frequency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) utmp = 0x4000 - DIV_ROUND_CLOSEST_ULL((u64)if_frequency * 0x4000, CXD2820R_CLK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) buf[0] = (utmp >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) buf[1] = (utmp >> 0) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) ret = regmap_bulk_write(priv->regmap[1], 0x0042, buf, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) ret = regmap_write(priv->regmap[0], 0x00ff, 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) ret = regmap_write(priv->regmap[0], 0x00fe, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) int cxd2820r_get_frontend_c(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) struct dtv_frontend_properties *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct cxd2820r_priv *priv = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct i2c_client *client = priv->client[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) unsigned int utmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) u8 buf[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) dev_dbg(&client->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) ret = regmap_bulk_read(priv->regmap[1], 0x001a, buf, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) c->symbol_rate = 2500 * ((buf[0] & 0x0f) << 8 | buf[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) ret = regmap_read(priv->regmap[1], 0x0019, &utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) switch ((utmp >> 0) & 0x07) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) c->modulation = QAM_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) c->modulation = QAM_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) c->modulation = QAM_64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) c->modulation = QAM_128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) c->modulation = QAM_256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) switch ((utmp >> 7) & 0x01) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) c->inversion = INVERSION_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) c->inversion = INVERSION_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) int cxd2820r_read_status_c(struct dvb_frontend *fe, enum fe_status *status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) struct cxd2820r_priv *priv = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) struct i2c_client *client = priv->client[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) unsigned int utmp, utmp1, utmp2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) u8 buf[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /* Lock detection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) ret = regmap_bulk_read(priv->regmap[1], 0x0088, &buf[0], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) ret = regmap_bulk_read(priv->regmap[1], 0x0073, &buf[1], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) utmp1 = (buf[0] >> 0) & 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) utmp2 = (buf[1] >> 3) & 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (utmp1 == 1 && utmp2 == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) *status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) } else if (utmp1 == 1 || utmp2 == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) *status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) FE_HAS_VITERBI | FE_HAS_SYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) *status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) dev_dbg(&client->dev, "status=%02x raw=%*ph sync=%u ts=%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) *status, 2, buf, utmp1, utmp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /* Signal strength */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) if (*status & FE_HAS_SIGNAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) unsigned int strength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) ret = regmap_bulk_read(priv->regmap[1], 0x0049, buf, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) utmp = buf[0] << 8 | buf[1] << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) utmp = 511 - sign_extend32(utmp, 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) /* Scale value to 0x0000-0xffff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) strength = utmp << 6 | utmp >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) c->strength.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) c->strength.stat[0].scale = FE_SCALE_RELATIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) c->strength.stat[0].uvalue = strength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) c->strength.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) /* CNR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (*status & FE_HAS_VITERBI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) unsigned int cnr, const_a, const_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) ret = regmap_read(priv->regmap[1], 0x0019, &utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (((utmp >> 0) & 0x03) % 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) const_a = 8750;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) const_b = 650;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) const_a = 9500;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) const_b = 760;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) ret = regmap_read(priv->regmap[1], 0x004d, &utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) #define CXD2820R_LOG2_E_24 24204406 /* log2(e) << 24 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (utmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) cnr = div_u64((u64)(intlog2(const_b) - intlog2(utmp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * const_a, CXD2820R_LOG2_E_24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) cnr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) c->cnr.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) c->cnr.stat[0].svalue = cnr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) c->cnr.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) /* BER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (*status & FE_HAS_SYNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) unsigned int post_bit_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) bool start_ber;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (priv->ber_running) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) ret = regmap_bulk_read(priv->regmap[1], 0x0076, buf, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if ((buf[2] >> 7) & 0x01) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) post_bit_error = buf[2] << 16 | buf[1] << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) buf[0] << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) post_bit_error &= 0x0fffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) start_ber = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) post_bit_error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) start_ber = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) post_bit_error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) start_ber = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (start_ber) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) ret = regmap_write(priv->regmap[1], 0x0079, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) priv->ber_running = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) priv->post_bit_error += post_bit_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) c->post_bit_error.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) c->post_bit_error.stat[0].uvalue = priv->post_bit_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) c->post_bit_error.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) int cxd2820r_init_c(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) struct cxd2820r_priv *priv = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct i2c_client *client = priv->client[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) dev_dbg(&client->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) ret = regmap_write(priv->regmap[0], 0x0085, 0x07);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) int cxd2820r_sleep_c(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) struct cxd2820r_priv *priv = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) struct i2c_client *client = priv->client[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) static const struct reg_val_mask tab[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) { 0x000ff, 0x1f, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) { 0x00085, 0x00, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) { 0x00088, 0x01, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) { 0x00081, 0x00, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) { 0x00080, 0x00, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) dev_dbg(&client->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) priv->delivery_system = SYS_UNDEFINED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) ret = cxd2820r_wr_reg_val_mask_tab(priv, tab, ARRAY_SIZE(tab));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) int cxd2820r_get_tune_settings_c(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) struct dvb_frontend_tune_settings *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) s->min_delay_ms = 500;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) s->step_size = 0; /* no zigzag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) s->max_drift = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }