^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) * Montage Technology M88DS3103/M88RS6000 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 "m88ds3103_priv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) static const struct dvb_frontend_ops m88ds3103_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) /* write single register with mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) static int m88ds3103_update_bits(struct m88ds3103_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) u8 reg, u8 mask, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) u8 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /* no need for read if whole reg is written */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) if (mask != 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) ret = regmap_bulk_read(dev->regmap, reg, &tmp, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) val &= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) tmp &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) val |= tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) return regmap_bulk_write(dev->regmap, reg, &val, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /* write reg val table using reg addr auto increment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) static int m88ds3103_wr_reg_val_tab(struct m88ds3103_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) const struct m88ds3103_reg_val *tab, int tab_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct i2c_client *client = dev->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) int ret, i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) u8 buf[83];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) dev_dbg(&client->dev, "tab_len=%d\n", tab_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if (tab_len > 86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) for (i = 0, j = 0; i < tab_len; i++, j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) buf[j] = tab[i].val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) if (i == tab_len - 1 || tab[i].reg != tab[i + 1].reg - 1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) !((j + 1) % (dev->cfg->i2c_wr_max - 1))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) ret = regmap_bulk_write(dev->regmap, tab[i].reg - j, buf, j + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) j = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) return ret;
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * m88ds3103b demod has an internal device related to clocking. First the i2c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * gate must be opened, for one transaction, then writes will be allowed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static int m88ds3103b_dt_write(struct m88ds3103_dev *dev, int reg, int data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct i2c_client *client = dev->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) u8 buf[] = {reg, data};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct i2c_msg msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) .addr = dev->dt_addr, .flags = 0, .buf = buf, .len = 2
^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) m88ds3103_update_bits(dev, 0x11, 0x01, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) val = 0x11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) ret = regmap_write(dev->regmap, 0x03, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) dev_dbg(&client->dev, "fail=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) ret = i2c_transfer(dev->dt_client->adapter, &msg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (ret != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) dev_err(&client->dev, "0x%02x (ret=%i, reg=0x%02x, value=0x%02x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) dev->dt_addr, ret, reg, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) m88ds3103_update_bits(dev, 0x11, 0x01, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) return -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) m88ds3103_update_bits(dev, 0x11, 0x01, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) dev_dbg(&client->dev, "0x%02x reg 0x%02x, value 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) dev->dt_addr, reg, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * m88ds3103b demod has an internal device related to clocking. First the i2c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * gate must be opened, for two transactions, then reads will be allowed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static int m88ds3103b_dt_read(struct m88ds3103_dev *dev, u8 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct i2c_client *client = dev->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) u8 b0[] = { reg };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) u8 b1[] = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct i2c_msg msg[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) .addr = dev->dt_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) .buf = b0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) .len = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) .addr = dev->dt_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) .flags = I2C_M_RD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) .buf = b1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) .len = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) m88ds3103_update_bits(dev, 0x11, 0x01, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) val = 0x12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) ret = regmap_write(dev->regmap, 0x03, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) dev_dbg(&client->dev, "fail=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) ret = i2c_transfer(dev->dt_client->adapter, msg, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (ret != 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) dev_err(&client->dev, "0x%02x (ret=%d, reg=0x%02x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) dev->dt_addr, ret, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) m88ds3103_update_bits(dev, 0x11, 0x01, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) return -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) m88ds3103_update_bits(dev, 0x11, 0x01, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) dev_dbg(&client->dev, "0x%02x reg 0x%02x, value 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) dev->dt_addr, reg, b1[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return b1[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * Get the demodulator AGC PWM voltage setting supplied to the tuner.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) int m88ds3103_get_agc_pwm(struct dvb_frontend *fe, u8 *_agc_pwm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct m88ds3103_dev *dev = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) unsigned tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) ret = regmap_read(dev->regmap, 0x3f, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) *_agc_pwm = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) EXPORT_SYMBOL(m88ds3103_get_agc_pwm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static int m88ds3103_read_status(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) enum fe_status *status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct m88ds3103_dev *dev = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) struct i2c_client *client = dev->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) int ret, i, itmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) unsigned int utmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) u8 buf[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) *status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (!dev->warm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) ret = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) switch (c->delivery_system) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) case SYS_DVBS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) ret = regmap_read(dev->regmap, 0xd1, &utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if ((utmp & 0x07) == 0x07)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) *status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) FE_HAS_VITERBI | FE_HAS_SYNC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) FE_HAS_LOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) case SYS_DVBS2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) ret = regmap_read(dev->regmap, 0x0d, &utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if ((utmp & 0x8f) == 0x8f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) *status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) FE_HAS_VITERBI | FE_HAS_SYNC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) FE_HAS_LOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) dev_dbg(&client->dev, "invalid delivery_system\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) dev->fe_status = *status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) dev_dbg(&client->dev, "lock=%02x status=%02x\n", utmp, *status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) /* CNR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (dev->fe_status & FE_HAS_VITERBI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) unsigned int cnr, noise, signal, noise_tot, signal_tot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) cnr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) /* more iterations for more accurate estimation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) #define M88DS3103_SNR_ITERATIONS 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) switch (c->delivery_system) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) case SYS_DVBS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) itmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) for (i = 0; i < M88DS3103_SNR_ITERATIONS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) ret = regmap_read(dev->regmap, 0xff, &utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) itmp += utmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) /* use of single register limits max value to 15 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) /* SNR(X) dB = 10 * ln(X) / ln(10) dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) itmp = DIV_ROUND_CLOSEST(itmp, 8 * M88DS3103_SNR_ITERATIONS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (itmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) cnr = div_u64((u64) 10000 * intlog2(itmp), intlog2(10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) case SYS_DVBS2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) noise_tot = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) signal_tot = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) for (i = 0; i < M88DS3103_SNR_ITERATIONS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) ret = regmap_bulk_read(dev->regmap, 0x8c, buf, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) noise = buf[1] << 6; /* [13:6] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) noise |= buf[0] & 0x3f; /* [5:0] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) noise >>= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) signal = buf[2] * buf[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) signal >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) noise_tot += noise;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) signal_tot += signal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) noise = noise_tot / M88DS3103_SNR_ITERATIONS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) signal = signal_tot / M88DS3103_SNR_ITERATIONS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) /* SNR(X) dB = 10 * log10(X) dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (signal > noise) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) itmp = signal / noise;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) cnr = div_u64((u64) 10000 * intlog10(itmp), (1 << 24));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) dev_dbg(&client->dev, "invalid delivery_system\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (cnr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) c->cnr.stat[0].svalue = cnr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /* BER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) if (dev->fe_status & FE_HAS_LOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) unsigned int utmp, post_bit_error, post_bit_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) switch (c->delivery_system) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) case SYS_DVBS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) ret = regmap_write(dev->regmap, 0xf9, 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) ret = regmap_read(dev->regmap, 0xf8, &utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) /* measurement ready? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (!(utmp & 0x10)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) ret = regmap_bulk_read(dev->regmap, 0xf6, buf, 2);
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) post_bit_error = buf[1] << 8 | buf[0] << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) post_bit_count = 0x800000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) dev->post_bit_error += post_bit_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) dev->post_bit_count += post_bit_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) dev->dvbv3_ber = post_bit_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) /* restart measurement */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) utmp |= 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) ret = regmap_write(dev->regmap, 0xf8, utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) case SYS_DVBS2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) ret = regmap_bulk_read(dev->regmap, 0xd5, buf, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) utmp = buf[2] << 16 | buf[1] << 8 | buf[0] << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) /* enough data? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (utmp > 4000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) ret = regmap_bulk_read(dev->regmap, 0xf7, buf, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) post_bit_error = buf[1] << 8 | buf[0] << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) post_bit_count = 32 * utmp; /* TODO: FEC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) dev->post_bit_error += post_bit_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) dev->post_bit_count += post_bit_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) dev->dvbv3_ber = post_bit_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) /* restart measurement */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) ret = regmap_write(dev->regmap, 0xd1, 0x01);
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) ret = regmap_write(dev->regmap, 0xf9, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) ret = regmap_write(dev->regmap, 0xf9, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) ret = regmap_write(dev->regmap, 0xd1, 0x00);
^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) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) dev_dbg(&client->dev, "invalid delivery_system\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) c->post_bit_error.stat[0].uvalue = dev->post_bit_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) c->post_bit_count.stat[0].uvalue = dev->post_bit_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) static int m88ds3103b_select_mclk(struct m88ds3103_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) struct i2c_client *client = dev->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) struct dtv_frontend_properties *c = &dev->fe.dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) u32 adc_Freq_MHz[3] = {96, 93, 99};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) u8 reg16_list[3] = {96, 92, 100}, reg16, reg15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) u32 offset_MHz[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) u32 max_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) u32 old_setting = dev->mclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) u32 tuner_freq_MHz = c->frequency / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) u8 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) char big_symbol = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) big_symbol = (c->symbol_rate > 45010000) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (big_symbol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) reg16 = 115;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) reg16 = 96;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) /* TODO: IS THIS NECESSARY ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) for (i = 0; i < 3; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) offset_MHz[i] = tuner_freq_MHz % adc_Freq_MHz[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (offset_MHz[i] > (adc_Freq_MHz[i] / 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) offset_MHz[i] = adc_Freq_MHz[i] - offset_MHz[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (offset_MHz[i] > max_offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) max_offset = offset_MHz[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) reg16 = reg16_list[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) dev->mclk = adc_Freq_MHz[i] * 1000 * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (big_symbol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) dev->mclk /= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) dev_dbg(&client->dev, "modifying mclk %u -> %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) old_setting, dev->mclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (dev->mclk == 93000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) regmap_write(dev->regmap, 0xA0, 0x42);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) else if (dev->mclk == 96000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) regmap_write(dev->regmap, 0xA0, 0x44);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) else if (dev->mclk == 99000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) regmap_write(dev->regmap, 0xA0, 0x46);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) else if (dev->mclk == 110250000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) regmap_write(dev->regmap, 0xA0, 0x4E);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) regmap_write(dev->regmap, 0xA0, 0x44);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) reg15 = m88ds3103b_dt_read(dev, 0x15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) m88ds3103b_dt_write(dev, 0x05, 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) m88ds3103b_dt_write(dev, 0x11, 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (big_symbol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) reg15 |= 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) reg15 &= ~0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) m88ds3103b_dt_write(dev, 0x15, reg15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) m88ds3103b_dt_write(dev, 0x16, reg16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) usleep_range(5000, 5500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) m88ds3103b_dt_write(dev, 0x05, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) m88ds3103b_dt_write(dev, 0x11, (u8)(big_symbol ? 0x0E : 0x0A));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) usleep_range(5000, 5500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) static int m88ds3103b_set_mclk(struct m88ds3103_dev *dev, u32 mclk_khz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) u8 reg11 = 0x0A, reg15, reg16, reg1D, reg1E, reg1F, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) u8 sm, f0 = 0, f1 = 0, f2 = 0, f3 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) u16 pll_div_fb, N;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) u32 div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) reg15 = m88ds3103b_dt_read(dev, 0x15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) reg16 = m88ds3103b_dt_read(dev, 0x16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) reg1D = m88ds3103b_dt_read(dev, 0x1D);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (dev->cfg->ts_mode != M88DS3103_TS_SERIAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) if (reg16 == 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) tmp = 93;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) else if (reg16 == 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) tmp = 99;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) tmp = 96;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) mclk_khz *= tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) mclk_khz /= 96;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) pll_div_fb = (reg15 & 0x01) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) pll_div_fb += reg16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) pll_div_fb += 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) div = 9000 * pll_div_fb * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) div /= mclk_khz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (dev->cfg->ts_mode == M88DS3103_TS_SERIAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) reg11 |= 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) if (div <= 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) N = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) f0 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) f1 = div / N;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) f2 = div - f1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) f3 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) } else if (div <= 34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) N = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) f0 = div / N;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) f1 = (div - f0) / (N - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) f2 = div - f0 - f1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) f3 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) } else if (div <= 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) N = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) f0 = div / N;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) f1 = (div - f0) / (N - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) f2 = (div - f0 - f1) / (N - 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) f3 = div - f0 - f1 - f2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) N = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) f0 = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) f1 = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) f2 = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) f3 = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) if (f0 == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) f0 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) else if ((f0 < 8) && (f0 != 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) f0 = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if (f1 == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) f1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) else if ((f1 < 8) && (f1 != 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) f1 = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (f2 == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) f2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) else if ((f2 < 8) && (f2 != 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) f2 = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if (f3 == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) f3 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) else if ((f3 < 8) && (f3 != 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) f3 = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) reg11 &= ~0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) if (div <= 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) N = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) f0 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) f1 = div / N;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) f2 = div - f1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) f3 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) } else if (div <= 48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) N = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) f0 = div / N;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) f1 = (div - f0) / (N - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) f2 = div - f0 - f1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) f3 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) } else if (div <= 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) N = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) f0 = div / N;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) f1 = (div - f0) / (N - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) f2 = (div - f0 - f1) / (N - 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) f3 = div - f0 - f1 - f2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) N = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) f0 = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) f1 = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) f2 = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) f3 = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) if (f0 == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) f0 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) else if ((f0 < 9) && (f0 != 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) f0 = 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) if (f1 == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) f1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) else if ((f1 < 9) && (f1 != 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) f1 = 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) if (f2 == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) f2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) else if ((f2 < 9) && (f2 != 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) f2 = 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) if (f3 == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) f3 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) else if ((f3 < 9) && (f3 != 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) f3 = 9;
^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) sm = N - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) /* Write to registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) //reg15 &= 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) //reg15 |= (pll_div_fb >> 8) & 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) //reg16 = pll_div_fb & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) reg1D &= ~0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) reg1D |= sm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) reg1D |= 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) reg1E = ((f3 << 4) + f2) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) reg1F = ((f1 << 4) + f0) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) m88ds3103b_dt_write(dev, 0x05, 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) m88ds3103b_dt_write(dev, 0x11, 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) m88ds3103b_dt_write(dev, 0x1D, reg1D);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) m88ds3103b_dt_write(dev, 0x1E, reg1E);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) m88ds3103b_dt_write(dev, 0x1F, reg1F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) m88ds3103b_dt_write(dev, 0x17, 0xc1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) m88ds3103b_dt_write(dev, 0x17, 0x81);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) usleep_range(5000, 5500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) m88ds3103b_dt_write(dev, 0x05, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) m88ds3103b_dt_write(dev, 0x11, 0x0A);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) usleep_range(5000, 5500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) static int m88ds3103_set_frontend(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) struct m88ds3103_dev *dev = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) struct i2c_client *client = dev->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) int ret, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) const struct m88ds3103_reg_val *init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) u8 u8tmp, u8tmp1 = 0, u8tmp2 = 0; /* silence compiler warning */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) u8 buf[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) u16 u16tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) u32 tuner_frequency_khz, target_mclk, u32tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) s32 s32tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) static const struct reg_sequence reset_buf[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) {0x07, 0x80}, {0x07, 0x00}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) dev_dbg(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) "delivery_system=%d modulation=%d frequency=%u symbol_rate=%d inversion=%d pilot=%d rolloff=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) c->delivery_system, c->modulation, c->frequency, c->symbol_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) c->inversion, c->pilot, c->rolloff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) if (!dev->warm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) ret = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) /* reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) ret = regmap_multi_reg_write(dev->regmap, reset_buf, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) /* Disable demod clock path */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) if (dev->chip_id == M88RS6000_CHIP_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) if (dev->chiptype == M88DS3103_CHIPTYPE_3103B) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) ret = regmap_read(dev->regmap, 0xb2, &u32tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) if (u32tmp == 0x01) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) ret = regmap_write(dev->regmap, 0x00, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) ret = regmap_write(dev->regmap, 0xb2, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) ret = regmap_write(dev->regmap, 0x06, 0xe0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) /* program tuner */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) if (fe->ops.tuner_ops.set_params) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) ret = fe->ops.tuner_ops.set_params(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) if (fe->ops.tuner_ops.get_frequency) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) ret = fe->ops.tuner_ops.get_frequency(fe, &tuner_frequency_khz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) * Use nominal target frequency as tuner driver does not provide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) * actual frequency used. Carrier offset calculation is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) * valid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) tuner_frequency_khz = c->frequency;
^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) /* set M88RS6000/DS3103B demod main mclk and ts mclk from tuner die */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) if (dev->chip_id == M88RS6000_CHIP_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) if (c->symbol_rate > 45010000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) dev->mclk = 110250000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) dev->mclk = 96000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) if (c->delivery_system == SYS_DVBS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) target_mclk = 96000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) target_mclk = 144000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) if (dev->chiptype == M88DS3103_CHIPTYPE_3103B) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) m88ds3103b_select_mclk(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) m88ds3103b_set_mclk(dev, target_mclk / 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) /* Enable demod clock path */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) ret = regmap_write(dev->regmap, 0x06, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) usleep_range(10000, 20000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) /* set M88DS3103 mclk and ts mclk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) dev->mclk = 96000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) switch (dev->cfg->ts_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) case M88DS3103_TS_SERIAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) case M88DS3103_TS_SERIAL_D7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) target_mclk = dev->cfg->ts_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) case M88DS3103_TS_PARALLEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) case M88DS3103_TS_CI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (c->delivery_system == SYS_DVBS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) target_mclk = 96000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) if (c->symbol_rate < 18000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) target_mclk = 96000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) else if (c->symbol_rate < 28000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) target_mclk = 144000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) target_mclk = 192000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) dev_dbg(&client->dev, "invalid ts_mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) switch (target_mclk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) case 96000000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) u8tmp1 = 0x02; /* 0b10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) u8tmp2 = 0x01; /* 0b01 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) case 144000000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) u8tmp1 = 0x00; /* 0b00 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) u8tmp2 = 0x01; /* 0b01 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) case 192000000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) u8tmp1 = 0x03; /* 0b11 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) u8tmp2 = 0x00; /* 0b00 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) ret = m88ds3103_update_bits(dev, 0x22, 0xc0, u8tmp1 << 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) ret = m88ds3103_update_bits(dev, 0x24, 0xc0, u8tmp2 << 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) ret = regmap_write(dev->regmap, 0xb2, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) ret = regmap_write(dev->regmap, 0x00, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) switch (c->delivery_system) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) case SYS_DVBS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) if (dev->chip_id == M88RS6000_CHIP_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) len = ARRAY_SIZE(m88rs6000_dvbs_init_reg_vals);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) init = m88rs6000_dvbs_init_reg_vals;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) len = ARRAY_SIZE(m88ds3103_dvbs_init_reg_vals);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) init = m88ds3103_dvbs_init_reg_vals;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) case SYS_DVBS2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (dev->chip_id == M88RS6000_CHIP_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) len = ARRAY_SIZE(m88rs6000_dvbs2_init_reg_vals);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) init = m88rs6000_dvbs2_init_reg_vals;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) len = ARRAY_SIZE(m88ds3103_dvbs2_init_reg_vals);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) init = m88ds3103_dvbs2_init_reg_vals;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) dev_dbg(&client->dev, "invalid delivery_system\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) /* program init table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) if (c->delivery_system != dev->delivery_system) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) ret = m88ds3103_wr_reg_val_tab(dev, init, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if (dev->chip_id == M88RS6000_CHIP_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) if (c->delivery_system == SYS_DVBS2 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) c->symbol_rate <= 5000000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) ret = regmap_write(dev->regmap, 0xc0, 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) buf[0] = 0x09;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) buf[1] = 0x22;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) buf[2] = 0x88;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) ret = regmap_bulk_write(dev->regmap, 0x8a, buf, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) ret = m88ds3103_update_bits(dev, 0x9d, 0x08, 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) if (dev->chiptype == M88DS3103_CHIPTYPE_3103B) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) buf[0] = m88ds3103b_dt_read(dev, 0x15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) buf[1] = m88ds3103b_dt_read(dev, 0x16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) if (c->symbol_rate > 45010000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) buf[0] &= ~0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) buf[0] |= 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) buf[0] |= ((147 - 32) >> 8) & 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) buf[1] = (147 - 32) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) dev->mclk = 110250 * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) buf[0] &= ~0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) buf[0] |= ((128 - 32) >> 8) & 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) buf[1] = (128 - 32) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) dev->mclk = 96000 * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) m88ds3103b_dt_write(dev, 0x15, buf[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) m88ds3103b_dt_write(dev, 0x16, buf[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) regmap_read(dev->regmap, 0x30, &u32tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) u32tmp &= ~0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) regmap_write(dev->regmap, 0x30, u32tmp & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) ret = regmap_write(dev->regmap, 0xf1, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) if (dev->chiptype != M88DS3103_CHIPTYPE_3103B) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) ret = m88ds3103_update_bits(dev, 0x30, 0x80, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) switch (dev->cfg->ts_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) case M88DS3103_TS_SERIAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) u8tmp1 = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) u8tmp = 0x06;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) case M88DS3103_TS_SERIAL_D7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) u8tmp1 = 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) u8tmp = 0x06;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) case M88DS3103_TS_PARALLEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) u8tmp = 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) if (dev->chiptype == M88DS3103_CHIPTYPE_3103B) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) u8tmp = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) u8tmp1 = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) case M88DS3103_TS_CI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) u8tmp = 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) dev_dbg(&client->dev, "invalid ts_mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) if (dev->cfg->ts_clk_pol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) u8tmp |= 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) /* TS mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) ret = regmap_write(dev->regmap, 0xfd, u8tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) switch (dev->cfg->ts_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) case M88DS3103_TS_SERIAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) case M88DS3103_TS_SERIAL_D7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) ret = m88ds3103_update_bits(dev, 0x29, 0x20, u8tmp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) u16tmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) u8tmp1 = 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) u8tmp2 = 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) case M88DS3103_TS_PARALLEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) if (dev->chiptype == M88DS3103_CHIPTYPE_3103B) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) ret = m88ds3103_update_bits(dev, 0x29, 0x01, u8tmp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) u16tmp = DIV_ROUND_UP(target_mclk, dev->cfg->ts_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) u8tmp1 = u16tmp / 2 - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) u8tmp2 = DIV_ROUND_UP(u16tmp, 2) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) dev_dbg(&client->dev, "target_mclk=%u ts_clk=%u ts_clk_divide_ratio=%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) target_mclk, dev->cfg->ts_clk, u16tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) /* u8tmp1[5:2] => fe[3:0], u8tmp1[1:0] => ea[7:6] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) /* u8tmp2[5:0] => ea[5:0] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) u8tmp = (u8tmp1 >> 2) & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) ret = regmap_update_bits(dev->regmap, 0xfe, 0x0f, u8tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) u8tmp = ((u8tmp1 & 0x03) << 6) | u8tmp2 >> 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) ret = regmap_write(dev->regmap, 0xea, u8tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) if (c->symbol_rate <= 3000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) u8tmp = 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) else if (c->symbol_rate <= 10000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) u8tmp = 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) u8tmp = 0x06;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) if (dev->chiptype == M88DS3103_CHIPTYPE_3103B)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) m88ds3103b_set_mclk(dev, target_mclk / 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) ret = regmap_write(dev->regmap, 0xc3, 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) ret = regmap_write(dev->regmap, 0xc8, u8tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) ret = regmap_write(dev->regmap, 0xc4, 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) ret = regmap_write(dev->regmap, 0xc7, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) u16tmp = DIV_ROUND_CLOSEST_ULL((u64)c->symbol_rate * 0x10000, dev->mclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) buf[0] = (u16tmp >> 0) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) buf[1] = (u16tmp >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) ret = regmap_bulk_write(dev->regmap, 0x61, buf, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) ret = m88ds3103_update_bits(dev, 0x4d, 0x02, dev->cfg->spec_inv << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) ret = m88ds3103_update_bits(dev, 0x30, 0x10, dev->cfg->agc_inv << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) ret = regmap_write(dev->regmap, 0x33, dev->cfg->agc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) if (dev->chiptype == M88DS3103_CHIPTYPE_3103B) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) /* enable/disable 192M LDPC clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) ret = m88ds3103_update_bits(dev, 0x29, 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) (c->delivery_system == SYS_DVBS) ? 0x10 : 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) ret = m88ds3103_update_bits(dev, 0xc9, 0x08, 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) dev_dbg(&client->dev, "carrier offset=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) (tuner_frequency_khz - c->frequency));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) /* Use 32-bit calc as there is no s64 version of DIV_ROUND_CLOSEST() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) s32tmp = 0x10000 * (tuner_frequency_khz - c->frequency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) s32tmp = DIV_ROUND_CLOSEST(s32tmp, dev->mclk / 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) buf[0] = (s32tmp >> 0) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) buf[1] = (s32tmp >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) ret = regmap_bulk_write(dev->regmap, 0x5e, buf, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) ret = regmap_write(dev->regmap, 0x00, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) ret = regmap_write(dev->regmap, 0xb2, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) dev->delivery_system = c->delivery_system;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) static int m88ds3103_init(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) struct m88ds3103_dev *dev = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) struct i2c_client *client = dev->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) int ret, len, rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) unsigned int utmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) const struct firmware *firmware;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) dev_dbg(&client->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) /* set cold state by default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) dev->warm = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) /* wake up device from sleep */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) ret = m88ds3103_update_bits(dev, 0x08, 0x01, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) ret = m88ds3103_update_bits(dev, 0x04, 0x01, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) ret = m88ds3103_update_bits(dev, 0x23, 0x10, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) /* firmware status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) ret = regmap_read(dev->regmap, 0xb9, &utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) dev_dbg(&client->dev, "firmware=%02x\n", utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) if (utmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) goto warm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) /* global reset, global diseqc reset, global fec reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) ret = regmap_write(dev->regmap, 0x07, 0xe0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) ret = regmap_write(dev->regmap, 0x07, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) /* cold state - try to download firmware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) dev_info(&client->dev, "found a '%s' in cold state\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) dev->fe.ops.info.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) if (dev->chiptype == M88DS3103_CHIPTYPE_3103B)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) name = M88DS3103B_FIRMWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) else if (dev->chip_id == M88RS6000_CHIP_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) name = M88RS6000_FIRMWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) name = M88DS3103_FIRMWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) /* request the firmware, this will block and timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) ret = request_firmware(&firmware, name, &client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) dev_err(&client->dev, "firmware file '%s' not found\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) dev_info(&client->dev, "downloading firmware from file '%s'\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) ret = regmap_write(dev->regmap, 0xb2, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) goto err_release_firmware;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) for (rem = firmware->size; rem > 0; rem -= (dev->cfg->i2c_wr_max - 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) len = min(dev->cfg->i2c_wr_max - 1, rem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) ret = regmap_bulk_write(dev->regmap, 0xb0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) &firmware->data[firmware->size - rem],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) dev_err(&client->dev, "firmware download failed %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) goto err_release_firmware;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) ret = regmap_write(dev->regmap, 0xb2, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) goto err_release_firmware;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) release_firmware(firmware);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) ret = regmap_read(dev->regmap, 0xb9, &utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) if (!utmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) dev_info(&client->dev, "firmware did not run\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) dev_info(&client->dev, "found a '%s' in warm state\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) dev->fe.ops.info.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) dev_info(&client->dev, "firmware version: %X.%X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) (utmp >> 4) & 0xf, (utmp >> 0 & 0xf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) if (dev->chiptype == M88DS3103_CHIPTYPE_3103B) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) m88ds3103b_dt_write(dev, 0x21, 0x92);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) m88ds3103b_dt_write(dev, 0x15, 0x6C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) m88ds3103b_dt_write(dev, 0x17, 0xC1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) m88ds3103b_dt_write(dev, 0x17, 0x81);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) warm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) /* warm state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) dev->warm = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) /* init stats here in order signal app which stats are supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) c->cnr.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) c->post_bit_error.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) c->post_bit_count.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) err_release_firmware:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) release_firmware(firmware);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) static int m88ds3103_sleep(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) struct m88ds3103_dev *dev = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) struct i2c_client *client = dev->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) unsigned int utmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) dev_dbg(&client->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) dev->fe_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) dev->delivery_system = SYS_UNDEFINED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) /* TS Hi-Z */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) if (dev->chip_id == M88RS6000_CHIP_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) utmp = 0x29;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) utmp = 0x27;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) ret = m88ds3103_update_bits(dev, utmp, 0x01, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) /* sleep */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) ret = m88ds3103_update_bits(dev, 0x08, 0x01, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) ret = m88ds3103_update_bits(dev, 0x04, 0x01, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) ret = m88ds3103_update_bits(dev, 0x23, 0x10, 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) static int m88ds3103_get_frontend(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) struct dtv_frontend_properties *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) struct m88ds3103_dev *dev = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) struct i2c_client *client = dev->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) u8 buf[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) dev_dbg(&client->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) if (!dev->warm || !(dev->fe_status & FE_HAS_LOCK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) switch (c->delivery_system) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) case SYS_DVBS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) ret = regmap_bulk_read(dev->regmap, 0xe0, &buf[0], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) ret = regmap_bulk_read(dev->regmap, 0xe6, &buf[1], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) switch ((buf[0] >> 2) & 0x01) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) c->inversion = INVERSION_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) c->inversion = INVERSION_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) switch ((buf[1] >> 5) & 0x07) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) c->fec_inner = FEC_7_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) c->fec_inner = FEC_5_6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) c->fec_inner = FEC_3_4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) c->fec_inner = FEC_2_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) c->fec_inner = FEC_1_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) dev_dbg(&client->dev, "invalid fec_inner\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) c->modulation = QPSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) case SYS_DVBS2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) ret = regmap_bulk_read(dev->regmap, 0x7e, &buf[0], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) ret = regmap_bulk_read(dev->regmap, 0x89, &buf[1], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) ret = regmap_bulk_read(dev->regmap, 0xf2, &buf[2], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) switch ((buf[0] >> 0) & 0x0f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) c->fec_inner = FEC_2_5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) c->fec_inner = FEC_1_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) c->fec_inner = FEC_3_5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) c->fec_inner = FEC_2_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) c->fec_inner = FEC_3_4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) c->fec_inner = FEC_4_5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) c->fec_inner = FEC_5_6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) case 9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) c->fec_inner = FEC_8_9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) case 10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) c->fec_inner = FEC_9_10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) dev_dbg(&client->dev, "invalid fec_inner\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) switch ((buf[0] >> 5) & 0x01) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) c->pilot = PILOT_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) c->pilot = PILOT_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) switch ((buf[0] >> 6) & 0x07) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) c->modulation = QPSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) c->modulation = PSK_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) c->modulation = APSK_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) c->modulation = APSK_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) dev_dbg(&client->dev, "invalid modulation\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) switch ((buf[1] >> 7) & 0x01) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) c->inversion = INVERSION_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) c->inversion = INVERSION_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) switch ((buf[2] >> 0) & 0x03) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) c->rolloff = ROLLOFF_35;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) c->rolloff = ROLLOFF_25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) c->rolloff = ROLLOFF_20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) dev_dbg(&client->dev, "invalid rolloff\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) dev_dbg(&client->dev, "invalid delivery_system\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) ret = regmap_bulk_read(dev->regmap, 0x6d, buf, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) c->symbol_rate = DIV_ROUND_CLOSEST_ULL((u64)(buf[1] << 8 | buf[0] << 0) * dev->mclk, 0x10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) static int m88ds3103_read_snr(struct dvb_frontend *fe, u16 *snr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) if (c->cnr.stat[0].scale == FE_SCALE_DECIBEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) *snr = div_s64(c->cnr.stat[0].svalue, 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) *snr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) static int m88ds3103_read_ber(struct dvb_frontend *fe, u32 *ber)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) struct m88ds3103_dev *dev = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) *ber = dev->dvbv3_ber;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) static int m88ds3103_set_tone(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) enum fe_sec_tone_mode fe_sec_tone_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) struct m88ds3103_dev *dev = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) struct i2c_client *client = dev->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) unsigned int utmp, tone, reg_a1_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) dev_dbg(&client->dev, "fe_sec_tone_mode=%d\n", fe_sec_tone_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) if (!dev->warm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) ret = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) switch (fe_sec_tone_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) case SEC_TONE_ON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) tone = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) reg_a1_mask = 0x47;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) case SEC_TONE_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) tone = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) reg_a1_mask = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) dev_dbg(&client->dev, "invalid fe_sec_tone_mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) utmp = tone << 7 | dev->cfg->envelope_mode << 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) ret = m88ds3103_update_bits(dev, 0xa2, 0xe0, utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) utmp = 1 << 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) ret = m88ds3103_update_bits(dev, 0xa1, reg_a1_mask, utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) static int m88ds3103_set_voltage(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) enum fe_sec_voltage fe_sec_voltage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) struct m88ds3103_dev *dev = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) struct i2c_client *client = dev->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) unsigned int utmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) bool voltage_sel, voltage_dis;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) dev_dbg(&client->dev, "fe_sec_voltage=%d\n", fe_sec_voltage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) if (!dev->warm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) ret = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) switch (fe_sec_voltage) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) case SEC_VOLTAGE_18:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) voltage_sel = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) voltage_dis = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) case SEC_VOLTAGE_13:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) voltage_sel = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) voltage_dis = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) case SEC_VOLTAGE_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) voltage_sel = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) voltage_dis = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) dev_dbg(&client->dev, "invalid fe_sec_voltage\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) /* output pin polarity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) voltage_sel ^= dev->cfg->lnb_hv_pol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) voltage_dis ^= dev->cfg->lnb_en_pol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) utmp = voltage_dis << 1 | voltage_sel << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) ret = m88ds3103_update_bits(dev, 0xa2, 0x03, utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) static int m88ds3103_diseqc_send_master_cmd(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) struct dvb_diseqc_master_cmd *diseqc_cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) struct m88ds3103_dev *dev = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) struct i2c_client *client = dev->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) unsigned int utmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) unsigned long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) dev_dbg(&client->dev, "msg=%*ph\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) diseqc_cmd->msg_len, diseqc_cmd->msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) if (!dev->warm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) ret = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) if (diseqc_cmd->msg_len < 3 || diseqc_cmd->msg_len > 6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) utmp = dev->cfg->envelope_mode << 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) ret = m88ds3103_update_bits(dev, 0xa2, 0xe0, utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) ret = regmap_bulk_write(dev->regmap, 0xa3, diseqc_cmd->msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) diseqc_cmd->msg_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) ret = regmap_write(dev->regmap, 0xa1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) (diseqc_cmd->msg_len - 1) << 3 | 0x07);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) /* wait DiSEqC TX ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) #define SEND_MASTER_CMD_TIMEOUT 120
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) timeout = jiffies + msecs_to_jiffies(SEND_MASTER_CMD_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) /* DiSEqC message period is 13.5 ms per byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) utmp = diseqc_cmd->msg_len * 13500;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) usleep_range(utmp - 4000, utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) for (utmp = 1; !time_after(jiffies, timeout) && utmp;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) ret = regmap_read(dev->regmap, 0xa1, &utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) utmp = (utmp >> 6) & 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) if (utmp == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) dev_dbg(&client->dev, "diseqc tx took %u ms\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) jiffies_to_msecs(jiffies) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) (jiffies_to_msecs(timeout) - SEND_MASTER_CMD_TIMEOUT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) dev_dbg(&client->dev, "diseqc tx timeout\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) ret = m88ds3103_update_bits(dev, 0xa1, 0xc0, 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) ret = m88ds3103_update_bits(dev, 0xa2, 0xc0, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) if (utmp == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) ret = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) static int m88ds3103_diseqc_send_burst(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) enum fe_sec_mini_cmd fe_sec_mini_cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) struct m88ds3103_dev *dev = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) struct i2c_client *client = dev->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) unsigned int utmp, burst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) unsigned long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) dev_dbg(&client->dev, "fe_sec_mini_cmd=%d\n", fe_sec_mini_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) if (!dev->warm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) ret = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) utmp = dev->cfg->envelope_mode << 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) ret = m88ds3103_update_bits(dev, 0xa2, 0xe0, utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) switch (fe_sec_mini_cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) case SEC_MINI_A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) burst = 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) case SEC_MINI_B:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) burst = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) dev_dbg(&client->dev, "invalid fe_sec_mini_cmd\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) ret = regmap_write(dev->regmap, 0xa1, burst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) /* wait DiSEqC TX ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) #define SEND_BURST_TIMEOUT 40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) timeout = jiffies + msecs_to_jiffies(SEND_BURST_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) /* DiSEqC ToneBurst period is 12.5 ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) usleep_range(8500, 12500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) for (utmp = 1; !time_after(jiffies, timeout) && utmp;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) ret = regmap_read(dev->regmap, 0xa1, &utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) utmp = (utmp >> 6) & 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) if (utmp == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) dev_dbg(&client->dev, "diseqc tx took %u ms\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) jiffies_to_msecs(jiffies) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) (jiffies_to_msecs(timeout) - SEND_BURST_TIMEOUT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) dev_dbg(&client->dev, "diseqc tx timeout\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) ret = m88ds3103_update_bits(dev, 0xa1, 0xc0, 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) ret = m88ds3103_update_bits(dev, 0xa2, 0xc0, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) if (utmp == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) ret = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) static int m88ds3103_get_tune_settings(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) struct dvb_frontend_tune_settings *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) s->min_delay_ms = 3000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) static void m88ds3103_release(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) struct m88ds3103_dev *dev = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) struct i2c_client *client = dev->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) i2c_unregister_device(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) static int m88ds3103_select(struct i2c_mux_core *muxc, u32 chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) struct m88ds3103_dev *dev = i2c_mux_priv(muxc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) struct i2c_client *client = dev->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) struct i2c_msg msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) .addr = client->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) .len = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) .buf = "\x03\x11",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) /* Open tuner I2C repeater for 1 xfer, closes automatically */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) ret = __i2c_transfer(client->adapter, &msg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) if (ret != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) dev_warn(&client->dev, "i2c wr failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) ret = -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) * XXX: That is wrapper to m88ds3103_probe() via driver core in order to provide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) * proper I2C client for legacy media attach binding.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) * New users must use I2C client binding directly!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) struct i2c_adapter *i2c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) struct i2c_adapter **tuner_i2c_adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) struct i2c_board_info board_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) struct m88ds3103_platform_data pdata = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) pdata.clk = cfg->clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) pdata.i2c_wr_max = cfg->i2c_wr_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) pdata.ts_mode = cfg->ts_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) pdata.ts_clk = cfg->ts_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) pdata.ts_clk_pol = cfg->ts_clk_pol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) pdata.spec_inv = cfg->spec_inv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) pdata.agc = cfg->agc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) pdata.agc_inv = cfg->agc_inv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) pdata.clk_out = cfg->clock_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) pdata.envelope_mode = cfg->envelope_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) pdata.lnb_hv_pol = cfg->lnb_hv_pol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) pdata.lnb_en_pol = cfg->lnb_en_pol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) pdata.attach_in_use = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) memset(&board_info, 0, sizeof(board_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) strscpy(board_info.type, "m88ds3103", I2C_NAME_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) board_info.addr = cfg->i2c_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) board_info.platform_data = &pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) client = i2c_new_client_device(i2c, &board_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) if (!i2c_client_has_driver(client))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) *tuner_i2c_adapter = pdata.get_i2c_adapter(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) return pdata.get_dvb_frontend(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) EXPORT_SYMBOL(m88ds3103_attach);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) static const struct dvb_frontend_ops m88ds3103_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) .delsys = {SYS_DVBS, SYS_DVBS2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) .info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) .name = "Montage Technology M88DS3103",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) .frequency_min_hz = 950 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) .frequency_max_hz = 2150 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) .frequency_tolerance_hz = 5 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) .symbol_rate_min = 1000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) .symbol_rate_max = 45000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) .caps = FE_CAN_INVERSION_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) FE_CAN_FEC_1_2 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) FE_CAN_FEC_2_3 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) FE_CAN_FEC_3_4 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) FE_CAN_FEC_4_5 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) FE_CAN_FEC_5_6 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) FE_CAN_FEC_6_7 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) FE_CAN_FEC_7_8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) FE_CAN_FEC_8_9 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) FE_CAN_FEC_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) FE_CAN_QPSK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) FE_CAN_RECOVER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) FE_CAN_2G_MODULATION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) .release = m88ds3103_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) .get_tune_settings = m88ds3103_get_tune_settings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) .init = m88ds3103_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) .sleep = m88ds3103_sleep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) .set_frontend = m88ds3103_set_frontend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) .get_frontend = m88ds3103_get_frontend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) .read_status = m88ds3103_read_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) .read_snr = m88ds3103_read_snr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) .read_ber = m88ds3103_read_ber,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) .diseqc_send_master_cmd = m88ds3103_diseqc_send_master_cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) .diseqc_send_burst = m88ds3103_diseqc_send_burst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) .set_tone = m88ds3103_set_tone,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) .set_voltage = m88ds3103_set_voltage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) static struct dvb_frontend *m88ds3103_get_dvb_frontend(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) struct m88ds3103_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) dev_dbg(&client->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) return &dev->fe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) static struct i2c_adapter *m88ds3103_get_i2c_adapter(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) struct m88ds3103_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) dev_dbg(&client->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) return dev->muxc->adapter[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) static int m88ds3103_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) struct m88ds3103_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) struct m88ds3103_platform_data *pdata = client->dev.platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) unsigned int utmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) dev = kzalloc(sizeof(*dev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) if (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) dev->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) dev->config.clock = pdata->clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) dev->config.i2c_wr_max = pdata->i2c_wr_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) dev->config.ts_mode = pdata->ts_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) dev->config.ts_clk = pdata->ts_clk * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) dev->config.ts_clk_pol = pdata->ts_clk_pol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) dev->config.spec_inv = pdata->spec_inv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) dev->config.agc_inv = pdata->agc_inv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) dev->config.clock_out = pdata->clk_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) dev->config.envelope_mode = pdata->envelope_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) dev->config.agc = pdata->agc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) dev->config.lnb_hv_pol = pdata->lnb_hv_pol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) dev->config.lnb_en_pol = pdata->lnb_en_pol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) dev->cfg = &dev->config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) /* create regmap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) dev->regmap_config.reg_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) dev->regmap_config.val_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) dev->regmap_config.lock_arg = dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) dev->regmap = devm_regmap_init_i2c(client, &dev->regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) if (IS_ERR(dev->regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) ret = PTR_ERR(dev->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) goto err_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) /* 0x00: chip id[6:0], 0x01: chip ver[7:0], 0x02: chip ver[15:8] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) ret = regmap_read(dev->regmap, 0x00, &utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) goto err_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) dev->chip_id = utmp >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) dev->chiptype = (u8)id->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) dev_dbg(&client->dev, "chip_id=%02x\n", dev->chip_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) switch (dev->chip_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) case M88RS6000_CHIP_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) case M88DS3103_CHIP_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) dev_err(&client->dev, "Unknown device. Chip_id=%02x\n", dev->chip_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) goto err_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) switch (dev->cfg->clock_out) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) case M88DS3103_CLOCK_OUT_DISABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) utmp = 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) case M88DS3103_CLOCK_OUT_ENABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) utmp = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) case M88DS3103_CLOCK_OUT_ENABLED_DIV2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) utmp = 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) goto err_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) if (!pdata->ts_clk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) goto err_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) /* 0x29 register is defined differently for m88rs6000. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) /* set internal tuner address to 0x21 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) if (dev->chip_id == M88RS6000_CHIP_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) utmp = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) ret = regmap_write(dev->regmap, 0x29, utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) goto err_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) /* sleep */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) ret = m88ds3103_update_bits(dev, 0x08, 0x01, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) goto err_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) ret = m88ds3103_update_bits(dev, 0x04, 0x01, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) goto err_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) ret = m88ds3103_update_bits(dev, 0x23, 0x10, 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) goto err_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) /* create mux i2c adapter for tuner */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) dev->muxc = i2c_mux_alloc(client->adapter, &client->dev, 1, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) m88ds3103_select, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) if (!dev->muxc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) goto err_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) dev->muxc->priv = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) ret = i2c_mux_add_adapter(dev->muxc, 0, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) goto err_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) /* create dvb_frontend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) memcpy(&dev->fe.ops, &m88ds3103_ops, sizeof(struct dvb_frontend_ops));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) if (dev->chiptype == M88DS3103_CHIPTYPE_3103B)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) strscpy(dev->fe.ops.info.name, "Montage Technology M88DS3103B",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) sizeof(dev->fe.ops.info.name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) else if (dev->chip_id == M88RS6000_CHIP_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) strscpy(dev->fe.ops.info.name, "Montage Technology M88RS6000",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) sizeof(dev->fe.ops.info.name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) if (!pdata->attach_in_use)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) dev->fe.ops.release = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) dev->fe.demodulator_priv = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) i2c_set_clientdata(client, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) /* setup callbacks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) pdata->get_dvb_frontend = m88ds3103_get_dvb_frontend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) pdata->get_i2c_adapter = m88ds3103_get_i2c_adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) if (dev->chiptype == M88DS3103_CHIPTYPE_3103B) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) /* enable i2c repeater for tuner */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) m88ds3103_update_bits(dev, 0x11, 0x01, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) /* get frontend address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) ret = regmap_read(dev->regmap, 0x29, &utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) goto err_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) dev->dt_addr = ((utmp & 0x80) == 0) ? 0x42 >> 1 : 0x40 >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) dev_dbg(&client->dev, "dt addr is 0x%02x\n", dev->dt_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) dev->dt_client = i2c_new_dummy_device(client->adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) dev->dt_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) if (IS_ERR(dev->dt_client)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) ret = PTR_ERR(dev->dt_client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) goto err_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) err_kfree:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) kfree(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) static int m88ds3103_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) struct m88ds3103_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) dev_dbg(&client->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) if (dev->dt_client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) i2c_unregister_device(dev->dt_client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) i2c_mux_del_adapters(dev->muxc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) kfree(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) static const struct i2c_device_id m88ds3103_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) {"m88ds3103", M88DS3103_CHIPTYPE_3103},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) {"m88rs6000", M88DS3103_CHIPTYPE_RS6000},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) {"m88ds3103b", M88DS3103_CHIPTYPE_3103B},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) MODULE_DEVICE_TABLE(i2c, m88ds3103_id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) static struct i2c_driver m88ds3103_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) .name = "m88ds3103",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) .suppress_bind_attrs = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) .probe = m88ds3103_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) .remove = m88ds3103_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) .id_table = m88ds3103_id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) module_i2c_driver(m88ds3103_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) MODULE_DESCRIPTION("Montage Technology M88DS3103 DVB-S/S2 demodulator driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) MODULE_FIRMWARE(M88DS3103_FIRMWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) MODULE_FIRMWARE(M88RS6000_FIRMWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) MODULE_FIRMWARE(M88DS3103B_FIRMWARE);