^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) * NXP TDA10071 + Conexant CX24118A DVB-S/S2 demodulator + tuner driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2011 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 "tda10071_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 tda10071_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * XXX: regmap_update_bits() does not fit our needs as it does not support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * partially volatile registers. Also it performs register read even mask is as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * wide as register value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /* write single register with mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) static int tda10071_wr_reg_mask(struct tda10071_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) u8 reg, u8 val, u8 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) u8 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /* no need for read if whole reg is written */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) if (mask != 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) ret = regmap_bulk_read(dev->regmap, reg, &tmp, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) val &= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) tmp &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) val |= tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) return regmap_bulk_write(dev->regmap, reg, &val, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /* execute firmware command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static int tda10071_cmd_execute(struct tda10071_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct tda10071_cmd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct i2c_client *client = dev->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) unsigned int uitmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) if (!dev->warm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) mutex_lock(&dev->cmd_execute_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) /* write cmd and args for firmware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) ret = regmap_bulk_write(dev->regmap, 0x00, cmd->args, cmd->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) goto error_mutex_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /* start cmd execution */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) ret = regmap_write(dev->regmap, 0x1f, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) goto error_mutex_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /* wait cmd execution terminate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) for (i = 1000, uitmp = 1; i && uitmp; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) ret = regmap_read(dev->regmap, 0x1f, &uitmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) goto error_mutex_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) usleep_range(200, 5000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) mutex_unlock(&dev->cmd_execute_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) dev_dbg(&client->dev, "loop=%d\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (i == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) ret = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) error_mutex_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) mutex_unlock(&dev->cmd_execute_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) static int tda10071_set_tone(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) enum fe_sec_tone_mode fe_sec_tone_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct tda10071_dev *dev = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct i2c_client *client = dev->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) struct tda10071_cmd cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) u8 tone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (!dev->warm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) dev_dbg(&client->dev, "tone_mode=%d\n", fe_sec_tone_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) switch (fe_sec_tone_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) case SEC_TONE_ON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) tone = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) case SEC_TONE_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) tone = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) dev_dbg(&client->dev, "invalid fe_sec_tone_mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) cmd.args[0] = CMD_LNB_PCB_CONFIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) cmd.args[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) cmd.args[2] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) cmd.args[3] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) cmd.args[4] = tone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) cmd.len = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) ret = tda10071_cmd_execute(dev, &cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static int tda10071_set_voltage(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) enum fe_sec_voltage fe_sec_voltage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) struct tda10071_dev *dev = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) struct i2c_client *client = dev->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct tda10071_cmd cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) u8 voltage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if (!dev->warm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) dev_dbg(&client->dev, "voltage=%d\n", fe_sec_voltage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) switch (fe_sec_voltage) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) case SEC_VOLTAGE_13:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) voltage = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) case SEC_VOLTAGE_18:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) voltage = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) case SEC_VOLTAGE_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) voltage = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) dev_dbg(&client->dev, "invalid fe_sec_voltage\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) cmd.args[0] = CMD_LNB_SET_DC_LEVEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) cmd.args[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) cmd.args[2] = voltage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) cmd.len = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) ret = tda10071_cmd_execute(dev, &cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static int tda10071_diseqc_send_master_cmd(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct dvb_diseqc_master_cmd *diseqc_cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) struct tda10071_dev *dev = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct i2c_client *client = dev->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct tda10071_cmd cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) unsigned int uitmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (!dev->warm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) dev_dbg(&client->dev, "msg_len=%d\n", diseqc_cmd->msg_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (diseqc_cmd->msg_len < 3 || diseqc_cmd->msg_len > 6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) /* wait LNB TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) for (i = 500, uitmp = 0; i && !uitmp; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) ret = regmap_read(dev->regmap, 0x47, &uitmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) uitmp = (uitmp >> 0) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) usleep_range(10000, 20000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) dev_dbg(&client->dev, "loop=%d\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (i == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) ret = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) ret = regmap_update_bits(dev->regmap, 0x47, 0x01, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) cmd.args[0] = CMD_LNB_SEND_DISEQC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) cmd.args[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) cmd.args[2] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) cmd.args[3] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) cmd.args[4] = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) cmd.args[5] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) cmd.args[6] = diseqc_cmd->msg_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) memcpy(&cmd.args[7], diseqc_cmd->msg, diseqc_cmd->msg_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) cmd.len = 7 + diseqc_cmd->msg_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) ret = tda10071_cmd_execute(dev, &cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) static int tda10071_diseqc_recv_slave_reply(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) struct dvb_diseqc_slave_reply *reply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) struct tda10071_dev *dev = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct i2c_client *client = dev->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) struct tda10071_cmd cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) unsigned int uitmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (!dev->warm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) dev_dbg(&client->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) /* wait LNB RX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) for (i = 500, uitmp = 0; i && !uitmp; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) ret = regmap_read(dev->regmap, 0x47, &uitmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) uitmp = (uitmp >> 1) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) usleep_range(10000, 20000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) dev_dbg(&client->dev, "loop=%d\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) if (i == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) ret = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /* reply len */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) ret = regmap_read(dev->regmap, 0x46, &uitmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) reply->msg_len = uitmp & 0x1f; /* [4:0] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (reply->msg_len > sizeof(reply->msg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) reply->msg_len = sizeof(reply->msg); /* truncate API max */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) /* read reply */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) cmd.args[0] = CMD_LNB_UPDATE_REPLY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) cmd.args[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) cmd.len = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) ret = tda10071_cmd_execute(dev, &cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) ret = regmap_bulk_read(dev->regmap, cmd.len, reply->msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) reply->msg_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) static int tda10071_diseqc_send_burst(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) enum fe_sec_mini_cmd fe_sec_mini_cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) struct tda10071_dev *dev = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) struct i2c_client *client = dev->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) struct tda10071_cmd cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) unsigned int uitmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) u8 burst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if (!dev->warm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) dev_dbg(&client->dev, "fe_sec_mini_cmd=%d\n", fe_sec_mini_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) switch (fe_sec_mini_cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) case SEC_MINI_A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) burst = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) case SEC_MINI_B:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) burst = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) dev_dbg(&client->dev, "invalid fe_sec_mini_cmd\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) /* wait LNB TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) for (i = 500, uitmp = 0; i && !uitmp; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) ret = regmap_read(dev->regmap, 0x47, &uitmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) uitmp = (uitmp >> 0) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) usleep_range(10000, 20000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) dev_dbg(&client->dev, "loop=%d\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) if (i == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) ret = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) ret = regmap_update_bits(dev->regmap, 0x47, 0x01, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) cmd.args[0] = CMD_LNB_SEND_TONEBURST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) cmd.args[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) cmd.args[2] = burst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) cmd.len = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) ret = tda10071_cmd_execute(dev, &cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) static int tda10071_read_status(struct dvb_frontend *fe, enum fe_status *status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) struct tda10071_dev *dev = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) struct i2c_client *client = dev->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) struct tda10071_cmd cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) unsigned int uitmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) u8 buf[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) *status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (!dev->warm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) ret = regmap_read(dev->regmap, 0x39, &uitmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) /* 0x39[0] tuner PLL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (uitmp & 0x02) /* demod PLL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (uitmp & 0x04) /* viterbi or LDPC*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) *status |= FE_HAS_VITERBI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (uitmp & 0x08) /* RS or BCH */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) *status |= FE_HAS_SYNC | FE_HAS_LOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) dev->fe_status = *status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) /* signal strength */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (dev->fe_status & FE_HAS_SIGNAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) cmd.args[0] = CMD_GET_AGCACC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) cmd.args[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) cmd.len = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) ret = tda10071_cmd_execute(dev, &cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) /* input power estimate dBm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) ret = regmap_read(dev->regmap, 0x50, &uitmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) c->strength.stat[0].scale = FE_SCALE_DECIBEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) c->strength.stat[0].svalue = (int) (uitmp - 256) * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) /* CNR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (dev->fe_status & FE_HAS_VITERBI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /* Es/No */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) ret = regmap_bulk_read(dev->regmap, 0x3a, buf, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) c->cnr.stat[0].svalue = (buf[0] << 8 | buf[1] << 0) * 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) /* UCB/PER/BER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (dev->fe_status & FE_HAS_LOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) /* TODO: report total bits/packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) u8 delivery_system, reg, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) switch (dev->delivery_system) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) case SYS_DVBS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) reg = 0x4c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) len = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) delivery_system = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) case SYS_DVBS2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) reg = 0x4d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) len = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) delivery_system = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) ret = regmap_read(dev->regmap, reg, &uitmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) if (dev->meas_count == uitmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) dev_dbg(&client->dev, "meas not ready=%02x\n", uitmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) dev->meas_count = uitmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) cmd.args[0] = CMD_BER_UPDATE_COUNTERS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) cmd.args[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) cmd.args[2] = delivery_system;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) cmd.len = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) ret = tda10071_cmd_execute(dev, &cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) ret = regmap_bulk_read(dev->regmap, cmd.len, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) if (dev->delivery_system == SYS_DVBS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) u32 bit_error = buf[0] << 24 | buf[1] << 16 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) buf[2] << 8 | buf[3] << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) dev->dvbv3_ber = bit_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) dev->post_bit_error += bit_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) c->post_bit_error.stat[0].uvalue = dev->post_bit_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) dev->block_error += buf[4] << 8 | buf[5] << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) c->block_error.stat[0].scale = FE_SCALE_COUNTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) c->block_error.stat[0].uvalue = dev->block_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) dev->dvbv3_ber = buf[0] << 8 | buf[1] << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) dev->post_bit_error += buf[0] << 8 | buf[1] << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) c->post_bit_error.stat[0].uvalue = dev->post_bit_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) static int tda10071_read_snr(struct dvb_frontend *fe, u16 *snr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (c->cnr.stat[0].scale == FE_SCALE_DECIBEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) *snr = div_s64(c->cnr.stat[0].svalue, 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) *snr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) static int tda10071_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) unsigned int uitmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (c->strength.stat[0].scale == FE_SCALE_DECIBEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) uitmp = div_s64(c->strength.stat[0].svalue, 1000) + 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) uitmp = clamp(uitmp, 181U, 236U); /* -75dBm - -20dBm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) /* scale value to 0x0000-0xffff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) *strength = (uitmp-181) * 0xffff / (236-181);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) *strength = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) static int tda10071_read_ber(struct dvb_frontend *fe, u32 *ber)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) struct tda10071_dev *dev = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) *ber = dev->dvbv3_ber;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) static int tda10071_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if (c->block_error.stat[0].scale == FE_SCALE_COUNTER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) *ucblocks = c->block_error.stat[0].uvalue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) *ucblocks = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) static int tda10071_set_frontend(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) struct tda10071_dev *dev = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) struct i2c_client *client = dev->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) struct tda10071_cmd cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) u8 mode, rolloff, pilot, inversion, div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) enum fe_modulation modulation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) dev_dbg(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) "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 559) c->delivery_system, c->modulation, c->frequency, c->symbol_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) c->inversion, c->pilot, c->rolloff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) dev->delivery_system = SYS_UNDEFINED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) if (!dev->warm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) switch (c->inversion) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) case INVERSION_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) inversion = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) case INVERSION_ON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) inversion = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) case INVERSION_AUTO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) /* 2 = auto; try first on then off
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) * 3 = auto; try first off then on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) inversion = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) dev_dbg(&client->dev, "invalid inversion\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) switch (c->delivery_system) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) case SYS_DVBS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) modulation = QPSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) rolloff = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) pilot = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) case SYS_DVBS2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) modulation = c->modulation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) switch (c->rolloff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) case ROLLOFF_20:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) rolloff = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) case ROLLOFF_25:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) rolloff = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) case ROLLOFF_35:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) rolloff = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) case ROLLOFF_AUTO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) dev_dbg(&client->dev, "invalid rolloff\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) switch (c->pilot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) case PILOT_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) pilot = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) case PILOT_ON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) pilot = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) case PILOT_AUTO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) pilot = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) dev_dbg(&client->dev, "invalid pilot\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) dev_dbg(&client->dev, "invalid delivery_system\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) for (i = 0, mode = 0xff; i < ARRAY_SIZE(TDA10071_MODCOD); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) if (c->delivery_system == TDA10071_MODCOD[i].delivery_system &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) modulation == TDA10071_MODCOD[i].modulation &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) c->fec_inner == TDA10071_MODCOD[i].fec) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) mode = TDA10071_MODCOD[i].val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) dev_dbg(&client->dev, "mode found=%02x\n", mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) if (mode == 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) dev_dbg(&client->dev, "invalid parameter combination\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) if (c->symbol_rate <= 5000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) div = 14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) div = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) ret = regmap_write(dev->regmap, 0x81, div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) ret = regmap_write(dev->regmap, 0xe3, div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) cmd.args[0] = CMD_CHANGE_CHANNEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) cmd.args[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) cmd.args[2] = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) cmd.args[3] = (c->frequency >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) cmd.args[4] = (c->frequency >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) cmd.args[5] = (c->frequency >> 0) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) cmd.args[6] = ((c->symbol_rate / 1000) >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) cmd.args[7] = ((c->symbol_rate / 1000) >> 0) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) cmd.args[8] = ((tda10071_ops.info.frequency_tolerance_hz / 1000) >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) cmd.args[9] = ((tda10071_ops.info.frequency_tolerance_hz / 1000) >> 0) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) cmd.args[10] = rolloff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) cmd.args[11] = inversion;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) cmd.args[12] = pilot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) cmd.args[13] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) cmd.args[14] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) cmd.len = 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) ret = tda10071_cmd_execute(dev, &cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) dev->delivery_system = c->delivery_system;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) static int tda10071_get_frontend(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) struct dtv_frontend_properties *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) struct tda10071_dev *dev = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) struct i2c_client *client = dev->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) u8 buf[5], tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (!dev->warm || !(dev->fe_status & FE_HAS_LOCK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) ret = regmap_bulk_read(dev->regmap, 0x30, buf, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) tmp = buf[0] & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) for (i = 0; i < ARRAY_SIZE(TDA10071_MODCOD); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) if (tmp == TDA10071_MODCOD[i].val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) c->modulation = TDA10071_MODCOD[i].modulation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) c->fec_inner = TDA10071_MODCOD[i].fec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) c->delivery_system = TDA10071_MODCOD[i].delivery_system;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) switch ((buf[1] >> 0) & 0x01) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) c->inversion = INVERSION_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) c->inversion = INVERSION_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) switch ((buf[1] >> 7) & 0x01) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) c->pilot = PILOT_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) c->pilot = PILOT_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) c->frequency = (buf[2] << 16) | (buf[3] << 8) | (buf[4] << 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) ret = regmap_bulk_read(dev->regmap, 0x52, buf, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) c->symbol_rate = ((buf[0] << 16) | (buf[1] << 8) | (buf[2] << 0)) * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) static int tda10071_init(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) struct tda10071_dev *dev = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) struct i2c_client *client = dev->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) struct tda10071_cmd cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) int ret, i, len, remaining, fw_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) unsigned int uitmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) const struct firmware *fw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) u8 *fw_file = TDA10071_FIRMWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) u8 tmp, buf[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) struct tda10071_reg_val_mask tab[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) { 0xcd, 0x00, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) { 0x80, 0x00, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) { 0xcd, 0x00, 0xc0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) { 0xce, 0x00, 0x1b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) { 0x9d, 0x00, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) { 0x9d, 0x00, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) { 0x9e, 0x00, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) { 0x87, 0x00, 0x80 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) { 0xce, 0x00, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) { 0xce, 0x00, 0x10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) struct tda10071_reg_val_mask tab2[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) { 0xf1, 0x70, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) { 0x88, dev->pll_multiplier, 0x3f },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) { 0x89, 0x00, 0x10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) { 0x89, 0x10, 0x10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) { 0xc0, 0x01, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) { 0xc0, 0x00, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) { 0xe0, 0xff, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) { 0xe0, 0x00, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) { 0x96, 0x1e, 0x7e },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) { 0x8b, 0x08, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) { 0x8b, 0x00, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) { 0x8f, 0x1a, 0x7e },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) { 0x8c, 0x68, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) { 0x8d, 0x08, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) { 0x8e, 0x4c, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) { 0x8f, 0x01, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) { 0x8b, 0x04, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) { 0x8b, 0x00, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) { 0x87, 0x05, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) { 0x80, 0x00, 0x20 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) { 0xc8, 0x01, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) { 0xb4, 0x47, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) { 0xb5, 0x9c, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) { 0xb6, 0x7d, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) { 0xba, 0x00, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) { 0xb7, 0x47, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) { 0xb8, 0x9c, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) { 0xb9, 0x7d, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) { 0xba, 0x00, 0x0c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) { 0xc8, 0x00, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) { 0xcd, 0x00, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) { 0xcd, 0x00, 0x20 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) { 0xe8, 0x02, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) { 0xcf, 0x20, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) { 0x9b, 0xd7, 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) { 0x9a, 0x01, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) { 0xa8, 0x05, 0x0f },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) { 0xa8, 0x65, 0xf0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) { 0xa6, 0xa0, 0xf0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) { 0x9d, 0x50, 0xfc },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) { 0x9e, 0x20, 0xe0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) { 0xa3, 0x1c, 0x7c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) { 0xd5, 0x03, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) if (dev->warm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) /* warm state - wake up device from sleep */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) for (i = 0; i < ARRAY_SIZE(tab); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) ret = tda10071_wr_reg_mask(dev, tab[i].reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) tab[i].val, tab[i].mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) cmd.args[0] = CMD_SET_SLEEP_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) cmd.args[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) cmd.args[2] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) cmd.len = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) ret = tda10071_cmd_execute(dev, &cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) /* cold state - try to download firmware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) /* request the firmware, this will block and timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) ret = request_firmware(&fw, fw_file, &client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) "did not find the firmware file '%s' (status %d). You can use <kernel_dir>/scripts/get_dvb_firmware to get the firmware\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) fw_file, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) /* init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) for (i = 0; i < ARRAY_SIZE(tab2); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) ret = tda10071_wr_reg_mask(dev, tab2[i].reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) tab2[i].val, tab2[i].mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) goto error_release_firmware;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) /* download firmware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) ret = regmap_write(dev->regmap, 0xe0, 0x7f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) goto error_release_firmware;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) ret = regmap_write(dev->regmap, 0xf7, 0x81);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) goto error_release_firmware;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) ret = regmap_write(dev->regmap, 0xf8, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) goto error_release_firmware;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) ret = regmap_write(dev->regmap, 0xf9, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) goto error_release_firmware;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) dev_info(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) "found a '%s' in cold state, will try to load a firmware\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) tda10071_ops.info.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) dev_info(&client->dev, "downloading firmware from file '%s'\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) fw_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) /* do not download last byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) fw_size = fw->size - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) for (remaining = fw_size; remaining > 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) remaining -= (dev->i2c_wr_max - 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) len = remaining;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) if (len > (dev->i2c_wr_max - 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) len = (dev->i2c_wr_max - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) ret = regmap_bulk_write(dev->regmap, 0xfa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) (u8 *) &fw->data[fw_size - remaining], len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) "firmware download failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) goto error_release_firmware;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) release_firmware(fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) ret = regmap_write(dev->regmap, 0xf7, 0x0c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) ret = regmap_write(dev->regmap, 0xe0, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) /* wait firmware start */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) msleep(250);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) /* firmware status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) ret = regmap_read(dev->regmap, 0x51, &uitmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) if (uitmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) dev_info(&client->dev, "firmware did not run\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) dev->warm = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) cmd.args[0] = CMD_GET_FW_VERSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) cmd.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) ret = tda10071_cmd_execute(dev, &cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) ret = regmap_bulk_read(dev->regmap, cmd.len, buf, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) dev_info(&client->dev, "firmware version %d.%d.%d.%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) buf[0], buf[1], buf[2], buf[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) dev_info(&client->dev, "found a '%s' in warm state\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) tda10071_ops.info.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) ret = regmap_bulk_read(dev->regmap, 0x81, buf, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) cmd.args[0] = CMD_DEMOD_INIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) cmd.args[1] = ((dev->clk / 1000) >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) cmd.args[2] = ((dev->clk / 1000) >> 0) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) cmd.args[3] = buf[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) cmd.args[4] = buf[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) cmd.args[5] = dev->pll_multiplier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) cmd.args[6] = dev->spec_inv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) cmd.args[7] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) cmd.len = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) ret = tda10071_cmd_execute(dev, &cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) if (dev->tuner_i2c_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) tmp = dev->tuner_i2c_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) tmp = 0x14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) cmd.args[0] = CMD_TUNER_INIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) cmd.args[1] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) cmd.args[2] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) cmd.args[3] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) cmd.args[4] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) cmd.args[5] = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) cmd.args[6] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) cmd.args[7] = 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) cmd.args[8] = 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) cmd.args[9] = 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) cmd.args[10] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) cmd.args[11] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) cmd.args[12] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) cmd.args[13] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) cmd.args[14] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) cmd.len = 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) ret = tda10071_cmd_execute(dev, &cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) cmd.args[0] = CMD_MPEG_CONFIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) cmd.args[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) cmd.args[2] = dev->ts_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) cmd.args[3] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) cmd.args[4] = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) cmd.args[5] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) cmd.len = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) ret = tda10071_cmd_execute(dev, &cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) ret = regmap_update_bits(dev->regmap, 0xf0, 0x01, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) cmd.args[0] = CMD_LNB_CONFIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) cmd.args[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) cmd.args[2] = 150;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) cmd.args[3] = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) cmd.args[4] = 22;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) cmd.args[5] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) cmd.args[6] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) cmd.args[7] = 30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) cmd.args[8] = 30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) cmd.args[9] = 30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) cmd.args[10] = 30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) cmd.len = 11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) ret = tda10071_cmd_execute(dev, &cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) cmd.args[0] = CMD_BER_CONTROL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) cmd.args[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) cmd.args[2] = 14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) cmd.args[3] = 14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) cmd.len = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) ret = tda10071_cmd_execute(dev, &cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) /* init stats here in order signal app which stats are supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) c->strength.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) c->cnr.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) c->post_bit_error.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) c->block_error.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) error_release_firmware:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) release_firmware(fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) static int tda10071_sleep(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) struct tda10071_dev *dev = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) struct i2c_client *client = dev->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) struct tda10071_cmd cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) struct tda10071_reg_val_mask tab[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) { 0xcd, 0x07, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) { 0x80, 0x02, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) { 0xcd, 0xc0, 0xc0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) { 0xce, 0x1b, 0x1b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) { 0x9d, 0x01, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) { 0x9d, 0x02, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) { 0x9e, 0x01, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) { 0x87, 0x80, 0x80 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) { 0xce, 0x08, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) { 0xce, 0x10, 0x10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) if (!dev->warm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) cmd.args[0] = CMD_SET_SLEEP_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) cmd.args[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) cmd.args[2] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) cmd.len = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) ret = tda10071_cmd_execute(dev, &cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) for (i = 0; i < ARRAY_SIZE(tab); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) ret = tda10071_wr_reg_mask(dev, tab[i].reg, tab[i].val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) tab[i].mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) goto error;
^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) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) static int tda10071_get_tune_settings(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) struct dvb_frontend_tune_settings *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) s->min_delay_ms = 8000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) s->step_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) s->max_drift = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) static const struct dvb_frontend_ops tda10071_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) .delsys = { SYS_DVBS, SYS_DVBS2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) .info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) .name = "NXP TDA10071",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) .frequency_min_hz = 950 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) .frequency_max_hz = 2150 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) .frequency_tolerance_hz = 5 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) .symbol_rate_min = 1000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) .symbol_rate_max = 45000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) .caps = FE_CAN_INVERSION_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) FE_CAN_FEC_1_2 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) FE_CAN_FEC_2_3 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) FE_CAN_FEC_3_4 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) FE_CAN_FEC_4_5 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) FE_CAN_FEC_5_6 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) FE_CAN_FEC_6_7 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) FE_CAN_FEC_7_8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) FE_CAN_FEC_8_9 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) FE_CAN_FEC_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) FE_CAN_QPSK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) FE_CAN_RECOVER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) FE_CAN_2G_MODULATION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) .get_tune_settings = tda10071_get_tune_settings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) .init = tda10071_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) .sleep = tda10071_sleep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) .set_frontend = tda10071_set_frontend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) .get_frontend = tda10071_get_frontend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) .read_status = tda10071_read_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) .read_snr = tda10071_read_snr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) .read_signal_strength = tda10071_read_signal_strength,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) .read_ber = tda10071_read_ber,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) .read_ucblocks = tda10071_read_ucblocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) .diseqc_send_master_cmd = tda10071_diseqc_send_master_cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) .diseqc_recv_slave_reply = tda10071_diseqc_recv_slave_reply,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) .diseqc_send_burst = tda10071_diseqc_send_burst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) .set_tone = tda10071_set_tone,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) .set_voltage = tda10071_set_voltage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) static struct dvb_frontend *tda10071_get_dvb_frontend(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) struct tda10071_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) dev_dbg(&client->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) return &dev->fe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) static int tda10071_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) struct tda10071_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) struct tda10071_platform_data *pdata = client->dev.platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) unsigned int uitmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) static const struct regmap_config regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) .reg_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) .val_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) dev = kzalloc(sizeof(*dev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) if (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) dev->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) mutex_init(&dev->cmd_execute_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) dev->clk = pdata->clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) dev->i2c_wr_max = pdata->i2c_wr_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) dev->ts_mode = pdata->ts_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) dev->spec_inv = pdata->spec_inv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) dev->pll_multiplier = pdata->pll_multiplier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) dev->tuner_i2c_addr = pdata->tuner_i2c_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) dev->regmap = devm_regmap_init_i2c(client, ®map_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) if (IS_ERR(dev->regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) ret = PTR_ERR(dev->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) goto err_kfree;
^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) /* chip ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) ret = regmap_read(dev->regmap, 0xff, &uitmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) goto err_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) if (uitmp != 0x0f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) goto err_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) /* chip type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) ret = regmap_read(dev->regmap, 0xdd, &uitmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) goto err_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) if (uitmp != 0x00) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) goto err_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) /* chip version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) ret = regmap_read(dev->regmap, 0xfe, &uitmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) goto err_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) if (uitmp != 0x01) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) goto err_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) /* create dvb_frontend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) memcpy(&dev->fe.ops, &tda10071_ops, sizeof(struct dvb_frontend_ops));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) dev->fe.demodulator_priv = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) i2c_set_clientdata(client, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) /* setup callbacks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) pdata->get_dvb_frontend = tda10071_get_dvb_frontend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) dev_info(&client->dev, "NXP TDA10071 successfully identified\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) err_kfree:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) kfree(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) static int tda10071_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) struct tda10071_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) dev_dbg(&client->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) kfree(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) return 0;
^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) static const struct i2c_device_id tda10071_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) {"tda10071_cx24118", 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) MODULE_DEVICE_TABLE(i2c, tda10071_id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) static struct i2c_driver tda10071_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) .name = "tda10071",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) .suppress_bind_attrs = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) .probe = tda10071_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) .remove = tda10071_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) .id_table = tda10071_id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) module_i2c_driver(tda10071_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) MODULE_DESCRIPTION("NXP TDA10071 DVB-S/S2 demodulator driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) MODULE_FIRMWARE(TDA10071_FIRMWARE);