^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) * Panasonic MN88472 DVB-T/T2/C demodulator driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2013 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) #include "mn88472_priv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) static int mn88472_get_tune_settings(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) struct dvb_frontend_tune_settings *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) s->min_delay_ms = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) static int mn88472_read_status(struct dvb_frontend *fe, enum fe_status *status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) struct i2c_client *client = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) struct mn88472_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) int ret, i, stmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) unsigned int utmp, utmp1, utmp2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) u8 buf[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) if (!dev->active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) ret = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) switch (c->delivery_system) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) case SYS_DVBT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) ret = regmap_read(dev->regmap[0], 0x7f, &utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) if ((utmp & 0x0f) >= 0x09)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) *status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) *status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) case SYS_DVBT2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) ret = regmap_read(dev->regmap[2], 0x92, &utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) if ((utmp & 0x0f) >= 0x0d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) *status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) else if ((utmp & 0x0f) >= 0x0a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) *status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) FE_HAS_VITERBI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) else if ((utmp & 0x0f) >= 0x07)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) *status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) *status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) case SYS_DVBC_ANNEX_A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) ret = regmap_read(dev->regmap[1], 0x84, &utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) if ((utmp & 0x0f) >= 0x08)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) *status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) *status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /* Signal strength */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (*status & FE_HAS_SIGNAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) ret = regmap_bulk_read(dev->regmap[2], 0x8e + i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) &buf[i], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) utmp1 = buf[0] << 8 | buf[1] << 0 | buf[0] >> 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) dev_dbg(&client->dev, "strength=%u\n", utmp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) c->strength.stat[0].scale = FE_SCALE_RELATIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) c->strength.stat[0].uvalue = utmp1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /* CNR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (*status & FE_HAS_VITERBI && c->delivery_system == SYS_DVBT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /* DVB-T CNR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) ret = regmap_bulk_read(dev->regmap[0], 0x9c, buf, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) utmp = buf[0] << 8 | buf[1] << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if (utmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) /* CNR[dB]: 10 * log10(65536 / value) + 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /* log10(65536) = 80807124, 0.2 = 3355443 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) stmp = ((u64)80807124 - intlog10(utmp) + 3355443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * 10000 >> 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) dev_dbg(&client->dev, "cnr=%d value=%u\n", stmp, utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) stmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) c->cnr.stat[0].svalue = stmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) } else if (*status & FE_HAS_VITERBI &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) c->delivery_system == SYS_DVBT2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /* DVB-T2 CNR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) for (i = 0; i < 3; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) ret = regmap_bulk_read(dev->regmap[2], 0xbc + i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) &buf[i], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) utmp = buf[1] << 8 | buf[2] << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) utmp1 = (buf[0] >> 2) & 0x01; /* 0=SISO, 1=MISO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (utmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (utmp1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /* CNR[dB]: 10 * log10(16384 / value) - 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /* log10(16384) = 70706234, 0.6 = 10066330 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) stmp = ((u64)70706234 - intlog10(utmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) - 10066330) * 10000 >> 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) dev_dbg(&client->dev, "cnr=%d value=%u MISO\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) stmp, utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /* CNR[dB]: 10 * log10(65536 / value) + 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /* log10(65536) = 80807124, 0.2 = 3355443 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) stmp = ((u64)80807124 - intlog10(utmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) + 3355443) * 10000 >> 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) dev_dbg(&client->dev, "cnr=%d value=%u SISO\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) stmp, utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) stmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) c->cnr.stat[0].svalue = stmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) } else if (*status & FE_HAS_VITERBI &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) c->delivery_system == SYS_DVBC_ANNEX_A) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) /* DVB-C CNR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) ret = regmap_bulk_read(dev->regmap[1], 0xa1, buf, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) utmp1 = buf[0] << 8 | buf[1] << 0; /* signal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) utmp2 = buf[2] << 8 | buf[3] << 0; /* noise */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (utmp1 && utmp2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) /* CNR[dB]: 10 * log10(8 * (signal / noise)) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) /* log10(8) = 15151336 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) stmp = ((u64)15151336 + intlog10(utmp1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) - intlog10(utmp2)) * 10000 >> 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) dev_dbg(&client->dev, "cnr=%d signal=%u noise=%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) stmp, utmp1, utmp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) stmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) c->cnr.stat[0].svalue = stmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /* PER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (*status & FE_HAS_SYNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) ret = regmap_bulk_read(dev->regmap[0], 0xe1, buf, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) utmp1 = buf[0] << 8 | buf[1] << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) utmp2 = buf[2] << 8 | buf[3] << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) dev_dbg(&client->dev, "block_error=%u block_count=%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) utmp1, utmp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) c->block_error.stat[0].scale = FE_SCALE_COUNTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) c->block_error.stat[0].uvalue += utmp1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) c->block_count.stat[0].scale = FE_SCALE_COUNTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) c->block_count.stat[0].uvalue += utmp2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) static int mn88472_set_frontend(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct i2c_client *client = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct mn88472_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) unsigned int utmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) u32 if_frequency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) u8 buf[3], delivery_system_val, bandwidth_val, *bandwidth_vals_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) u8 reg_bank0_b4_val, reg_bank0_cd_val, reg_bank0_d4_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) u8 reg_bank0_d6_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) dev_dbg(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) "delivery_system=%u modulation=%u frequency=%u bandwidth_hz=%u symbol_rate=%u inversion=%d stream_id=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) c->delivery_system, c->modulation, c->frequency,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) c->bandwidth_hz, c->symbol_rate, c->inversion, c->stream_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (!dev->active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) ret = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) switch (c->delivery_system) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) case SYS_DVBT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) delivery_system_val = 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) reg_bank0_b4_val = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) reg_bank0_cd_val = 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) reg_bank0_d4_val = 0x0a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) reg_bank0_d6_val = 0x48;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) case SYS_DVBT2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) delivery_system_val = 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) reg_bank0_b4_val = 0xf6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) reg_bank0_cd_val = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) reg_bank0_d4_val = 0x09;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) reg_bank0_d6_val = 0x46;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) case SYS_DVBC_ANNEX_A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) delivery_system_val = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) reg_bank0_b4_val = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) reg_bank0_cd_val = 0x17;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) reg_bank0_d4_val = 0x09;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) reg_bank0_d6_val = 0x48;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) switch (c->delivery_system) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) case SYS_DVBT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) case SYS_DVBT2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) switch (c->bandwidth_hz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) case 5000000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) bandwidth_vals_ptr = "\xe5\x99\x9a\x1b\xa9\x1b\xa9";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) bandwidth_val = 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) case 6000000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) bandwidth_vals_ptr = "\xbf\x55\x55\x15\x6b\x15\x6b";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) bandwidth_val = 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) case 7000000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) bandwidth_vals_ptr = "\xa4\x00\x00\x0f\x2c\x0f\x2c";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) bandwidth_val = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) case 8000000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) bandwidth_vals_ptr = "\x8f\x80\x00\x08\xee\x08\xee";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) bandwidth_val = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) case SYS_DVBC_ANNEX_A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) bandwidth_vals_ptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) bandwidth_val = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /* Program tuner */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (fe->ops.tuner_ops.set_params) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) ret = fe->ops.tuner_ops.set_params(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (fe->ops.tuner_ops.get_if_frequency) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) dev_dbg(&client->dev, "get_if_frequency=%d\n", if_frequency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) ret = regmap_write(dev->regmap[2], 0x00, 0x66);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) ret = regmap_write(dev->regmap[2], 0x01, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) ret = regmap_write(dev->regmap[2], 0x02, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) ret = regmap_write(dev->regmap[2], 0x03, delivery_system_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) ret = regmap_write(dev->regmap[2], 0x04, bandwidth_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) /* IF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) utmp = DIV_ROUND_CLOSEST_ULL((u64)if_frequency * 0x1000000, dev->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) buf[0] = (utmp >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) buf[1] = (utmp >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) buf[2] = (utmp >> 0) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) for (i = 0; i < 3; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) ret = regmap_write(dev->regmap[2], 0x10 + i, buf[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) /* Bandwidth */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (bandwidth_vals_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) for (i = 0; i < 7; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) ret = regmap_write(dev->regmap[2], 0x13 + i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) bandwidth_vals_ptr[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) ret = regmap_write(dev->regmap[0], 0xb4, reg_bank0_b4_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) ret = regmap_write(dev->regmap[0], 0xcd, reg_bank0_cd_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) ret = regmap_write(dev->regmap[0], 0xd4, reg_bank0_d4_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) ret = regmap_write(dev->regmap[0], 0xd6, reg_bank0_d6_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) switch (c->delivery_system) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) case SYS_DVBT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) ret = regmap_write(dev->regmap[0], 0x07, 0x26);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) ret = regmap_write(dev->regmap[0], 0x00, 0xba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) ret = regmap_write(dev->regmap[0], 0x01, 0x13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) case SYS_DVBT2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) ret = regmap_write(dev->regmap[2], 0x2b, 0x13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) ret = regmap_write(dev->regmap[2], 0x4f, 0x05);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) ret = regmap_write(dev->regmap[1], 0xf6, 0x05);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) ret = regmap_write(dev->regmap[2], 0x32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) (c->stream_id == NO_STREAM_ID_FILTER) ? 0 :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) c->stream_id );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) case SYS_DVBC_ANNEX_A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /* Reset FSM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) ret = regmap_write(dev->regmap[2], 0xf8, 0x9f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) static int mn88472_init(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) struct i2c_client *client = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) struct mn88472_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) int ret, len, rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) unsigned int utmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) const struct firmware *firmware;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) const char *name = MN88472_FIRMWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) dev_dbg(&client->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) /* Power up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) ret = regmap_write(dev->regmap[2], 0x05, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) ret = regmap_write(dev->regmap[2], 0x0b, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) ret = regmap_write(dev->regmap[2], 0x0c, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /* Check if firmware is already running */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) ret = regmap_read(dev->regmap[0], 0xf5, &utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) if (!(utmp & 0x01))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) goto warm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) ret = request_firmware(&firmware, name, &client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) dev_err(&client->dev, "firmware file '%s' not found\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) dev_info(&client->dev, "downloading firmware from file '%s'\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) ret = regmap_write(dev->regmap[0], 0xf5, 0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) goto err_release_firmware;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) for (rem = firmware->size; rem > 0; rem -= (dev->i2c_write_max - 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) len = min(dev->i2c_write_max - 1, rem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) ret = regmap_bulk_write(dev->regmap[0], 0xf6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) &firmware->data[firmware->size - rem],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) dev_err(&client->dev, "firmware download failed %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) goto err_release_firmware;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) /* Parity check of firmware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) ret = regmap_read(dev->regmap[0], 0xf8, &utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) goto err_release_firmware;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (utmp & 0x10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) dev_err(&client->dev, "firmware did not run\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) goto err_release_firmware;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) ret = regmap_write(dev->regmap[0], 0xf5, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) goto err_release_firmware;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) release_firmware(firmware);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) warm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) /* TS config */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) switch (dev->ts_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) case SERIAL_TS_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) utmp = 0x1d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) case PARALLEL_TS_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) utmp = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) ret = regmap_write(dev->regmap[2], 0x08, utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) switch (dev->ts_clk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) case VARIABLE_TS_CLOCK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) utmp = 0xe3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) case FIXED_TS_CLOCK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) utmp = 0xe1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) ret = regmap_write(dev->regmap[0], 0xd9, utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) dev->active = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) err_release_firmware:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) release_firmware(firmware);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) static int mn88472_sleep(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) struct i2c_client *client = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) struct mn88472_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) dev_dbg(&client->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) /* Power down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) ret = regmap_write(dev->regmap[2], 0x0c, 0x30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) ret = regmap_write(dev->regmap[2], 0x0b, 0x30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) ret = regmap_write(dev->regmap[2], 0x05, 0x3e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) static const struct dvb_frontend_ops mn88472_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) .delsys = {SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) .info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) .name = "Panasonic MN88472",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) .symbol_rate_min = 1000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) .symbol_rate_max = 7200000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) .caps = FE_CAN_FEC_1_2 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) FE_CAN_FEC_2_3 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) FE_CAN_FEC_3_4 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) FE_CAN_FEC_5_6 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) FE_CAN_FEC_7_8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) FE_CAN_FEC_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) FE_CAN_QPSK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) FE_CAN_QAM_16 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) FE_CAN_QAM_32 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) FE_CAN_QAM_64 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) FE_CAN_QAM_128 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) FE_CAN_QAM_256 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) FE_CAN_QAM_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) FE_CAN_TRANSMISSION_MODE_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) FE_CAN_GUARD_INTERVAL_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) FE_CAN_HIERARCHY_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) FE_CAN_MUTE_TS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) FE_CAN_2G_MODULATION |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) FE_CAN_MULTISTREAM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) .get_tune_settings = mn88472_get_tune_settings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) .init = mn88472_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) .sleep = mn88472_sleep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) .set_frontend = mn88472_set_frontend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) .read_status = mn88472_read_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) static struct dvb_frontend *mn88472_get_dvb_frontend(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) struct mn88472_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) dev_dbg(&client->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return &dev->fe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) static int mn88472_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) struct mn88472_config *pdata = client->dev.platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) struct mn88472_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) struct dtv_frontend_properties *c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) unsigned int utmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) static const struct regmap_config regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) .reg_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) .val_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) dev_dbg(&client->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) dev = kzalloc(sizeof(*dev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) if (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) dev->i2c_write_max = pdata->i2c_wr_max ? pdata->i2c_wr_max : ~0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) dev->clk = pdata->xtal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) dev->ts_mode = pdata->ts_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) dev->ts_clk = pdata->ts_clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) dev->client[0] = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) dev->regmap[0] = regmap_init_i2c(dev->client[0], ®map_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) if (IS_ERR(dev->regmap[0])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) ret = PTR_ERR(dev->regmap[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) goto err_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) * Chip has three I2C addresses for different register banks. Used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) * addresses are 0x18, 0x1a and 0x1c. We register two dummy clients,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) * 0x1a and 0x1c, in order to get own I2C client for each register bank.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) * Also, register bank 2 do not support sequential I/O. Only single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) * register write or read is allowed to that bank.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) dev->client[1] = i2c_new_dummy_device(client->adapter, 0x1a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) if (IS_ERR(dev->client[1])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) ret = PTR_ERR(dev->client[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) dev_err(&client->dev, "I2C registration failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) goto err_regmap_0_regmap_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) dev->regmap[1] = regmap_init_i2c(dev->client[1], ®map_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) if (IS_ERR(dev->regmap[1])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) ret = PTR_ERR(dev->regmap[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) goto err_client_1_i2c_unregister_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) i2c_set_clientdata(dev->client[1], dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) dev->client[2] = i2c_new_dummy_device(client->adapter, 0x1c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) if (IS_ERR(dev->client[2])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) ret = PTR_ERR(dev->client[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) dev_err(&client->dev, "2nd I2C registration failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) goto err_regmap_1_regmap_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) dev->regmap[2] = regmap_init_i2c(dev->client[2], ®map_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) if (IS_ERR(dev->regmap[2])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) ret = PTR_ERR(dev->regmap[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) goto err_client_2_i2c_unregister_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) i2c_set_clientdata(dev->client[2], dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) /* Check demod answers with correct chip id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) ret = regmap_read(dev->regmap[2], 0xff, &utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) goto err_regmap_2_regmap_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) dev_dbg(&client->dev, "chip id=%02x\n", utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) if (utmp != 0x02) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) goto err_regmap_2_regmap_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) /* Sleep because chip is active by default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) ret = regmap_write(dev->regmap[2], 0x05, 0x3e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) goto err_regmap_2_regmap_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) /* Create dvb frontend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) memcpy(&dev->fe.ops, &mn88472_ops, sizeof(struct dvb_frontend_ops));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) dev->fe.demodulator_priv = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) *pdata->fe = &dev->fe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) i2c_set_clientdata(client, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) /* Init stats to indicate which stats are supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) c = &dev->fe.dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) c->strength.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) c->cnr.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) c->block_error.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) c->block_count.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) /* Setup callbacks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) pdata->get_dvb_frontend = mn88472_get_dvb_frontend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) dev_info(&client->dev, "Panasonic MN88472 successfully identified\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) err_regmap_2_regmap_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) regmap_exit(dev->regmap[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) err_client_2_i2c_unregister_device:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) i2c_unregister_device(dev->client[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) err_regmap_1_regmap_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) regmap_exit(dev->regmap[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) err_client_1_i2c_unregister_device:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) i2c_unregister_device(dev->client[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) err_regmap_0_regmap_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) regmap_exit(dev->regmap[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) err_kfree:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) kfree(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) static int mn88472_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) struct mn88472_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) dev_dbg(&client->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) regmap_exit(dev->regmap[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) i2c_unregister_device(dev->client[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) regmap_exit(dev->regmap[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) i2c_unregister_device(dev->client[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) regmap_exit(dev->regmap[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) kfree(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) static const struct i2c_device_id mn88472_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) {"mn88472", 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) MODULE_DEVICE_TABLE(i2c, mn88472_id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) static struct i2c_driver mn88472_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) .name = "mn88472",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) .suppress_bind_attrs = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) .probe = mn88472_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) .remove = mn88472_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) .id_table = mn88472_id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) module_i2c_driver(mn88472_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) MODULE_DESCRIPTION("Panasonic MN88472 DVB-T/T2/C demodulator driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) MODULE_FIRMWARE(MN88472_FIRMWARE);