1825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari/* 2c89f66f629f0e94806e3ec6f8f77b61a8feed39fAntti Palosaari * Afatech AF9013 demodulator driver 3825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari * 4825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari * Copyright (C) 2007 Antti Palosaari <crope@iki.fi> 5f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari * Copyright (C) 2011 Antti Palosaari <crope@iki.fi> 6825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari * 7825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari * Thanks to Afatech who kindly provided information. 8825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari * 9825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari * This program is free software; you can redistribute it and/or modify 10825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari * it under the terms of the GNU General Public License as published by 11825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari * the Free Software Foundation; either version 2 of the License, or 12825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari * (at your option) any later version. 13825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari * 14825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari * This program is distributed in the hope that it will be useful, 15825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari * but WITHOUT ANY WARRANTY; without even the implied warranty of 16825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari * GNU General Public License for more details. 18825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari * 19825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari * You should have received a copy of the GNU General Public License 20825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari * along with this program; if not, write to the Free Software 21825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari * 23825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari */ 24825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 25825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari#include "af9013_priv.h" 26825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 2737ebaf6891ee81687bb558e8375c0712d8264ed8Mauro Carvalho Chehab/* Max transfer size done by I2C transfer functions */ 2837ebaf6891ee81687bb558e8375c0712d8264ed8Mauro Carvalho Chehab#define MAX_XFER_SIZE 64 2937ebaf6891ee81687bb558e8375c0712d8264ed8Mauro Carvalho Chehab 30825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaaristruct af9013_state { 31825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari struct i2c_adapter *i2c; 32f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari struct dvb_frontend fe; 33825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari struct af9013_config config; 34825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 359e35cd222bc913f34b8f69e2b41daa7aa041d79aAntti Palosaari /* tuner/demod RF and IF AGC limits used for signal strength calc */ 369e35cd222bc913f34b8f69e2b41daa7aa041d79aAntti Palosaari u8 signal_strength_en, rf_50, rf_80, if_50, if_80; 37825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari u16 signal_strength; 38825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari u32 ber; 39825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari u32 ucblocks; 40825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari u16 snr; 41f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari u32 bandwidth_hz; 42f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari fe_status_t fe_status; 43f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari unsigned long set_frontend_jiffies; 44f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari unsigned long read_status_jiffies; 45f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari bool first_tune; 46f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari bool i2c_gate_state; 47f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari unsigned int statistics_step:3; 48f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari struct delayed_work statistics_work; 49825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari}; 50825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 51f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari/* write multiple registers */ 52f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaaristatic int af9013_wr_regs_i2c(struct af9013_state *priv, u8 mbox, u16 reg, 53f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari const u8 *val, int len) 54825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari{ 55f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari int ret; 5637ebaf6891ee81687bb558e8375c0712d8264ed8Mauro Carvalho Chehab u8 buf[MAX_XFER_SIZE]; 57f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari struct i2c_msg msg[1] = { 58f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari { 59f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari .addr = priv->config.i2c_addr, 60f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari .flags = 0, 6137ebaf6891ee81687bb558e8375c0712d8264ed8Mauro Carvalho Chehab .len = 3 + len, 62f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari .buf = buf, 63f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari } 64f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari }; 65f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 6637ebaf6891ee81687bb558e8375c0712d8264ed8Mauro Carvalho Chehab if (3 + len > sizeof(buf)) { 6737ebaf6891ee81687bb558e8375c0712d8264ed8Mauro Carvalho Chehab dev_warn(&priv->i2c->dev, 6837ebaf6891ee81687bb558e8375c0712d8264ed8Mauro Carvalho Chehab "%s: i2c wr reg=%04x: len=%d is too big!\n", 6937ebaf6891ee81687bb558e8375c0712d8264ed8Mauro Carvalho Chehab KBUILD_MODNAME, reg, len); 7037ebaf6891ee81687bb558e8375c0712d8264ed8Mauro Carvalho Chehab return -EINVAL; 7137ebaf6891ee81687bb558e8375c0712d8264ed8Mauro Carvalho Chehab } 7237ebaf6891ee81687bb558e8375c0712d8264ed8Mauro Carvalho Chehab 73f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari buf[0] = (reg >> 8) & 0xff; 74f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari buf[1] = (reg >> 0) & 0xff; 75825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari buf[2] = mbox; 76825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari memcpy(&buf[3], val, len); 77825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 78f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = i2c_transfer(priv->i2c, msg, 1); 79f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret == 1) { 80f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = 0; 81f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari } else { 828df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%04x " \ 838df379c5a425d127216195861b88f981530e7581Antti Palosaari "len=%d\n", KBUILD_MODNAME, ret, reg, len); 84f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = -EREMOTEIO; 85825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } 86f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return ret; 87825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari} 88825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 89f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari/* read multiple registers */ 90f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaaristatic int af9013_rd_regs_i2c(struct af9013_state *priv, u8 mbox, u16 reg, 91f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari u8 *val, int len) 92825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari{ 93f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari int ret; 94f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari u8 buf[3]; 95f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari struct i2c_msg msg[2] = { 96f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari { 97f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari .addr = priv->config.i2c_addr, 98f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari .flags = 0, 99f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari .len = 3, 100f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari .buf = buf, 101f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari }, { 102f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari .addr = priv->config.i2c_addr, 103f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari .flags = I2C_M_RD, 104f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari .len = len, 105f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari .buf = val, 106f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari } 107f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari }; 108f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 109f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari buf[0] = (reg >> 8) & 0xff; 110f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari buf[1] = (reg >> 0) & 0xff; 111f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari buf[2] = mbox; 112f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 113f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = i2c_transfer(priv->i2c, msg, 2); 114f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret == 2) { 115f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = 0; 116f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari } else { 1178df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%04x " \ 1188df379c5a425d127216195861b88f981530e7581Antti Palosaari "len=%d\n", KBUILD_MODNAME, ret, reg, len); 119f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = -EREMOTEIO; 120f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari } 121f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return ret; 122825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari} 123825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 124f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari/* write multiple registers */ 125f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaaristatic int af9013_wr_regs(struct af9013_state *priv, u16 reg, const u8 *val, 126f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari int len) 127825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari{ 128f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari int ret, i; 129f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari u8 mbox = (0 << 7)|(0 << 6)|(1 << 1)|(1 << 0); 130f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 131938ca36ef7914bd013acbff9f15e393fe79d71daDan Carpenter if ((priv->config.ts_mode == AF9013_TS_USB) && 132938ca36ef7914bd013acbff9f15e393fe79d71daDan Carpenter ((reg & 0xff00) != 0xff00) && ((reg & 0xff00) != 0xae00)) { 133f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari mbox |= ((len - 1) << 2); 134f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_regs_i2c(priv, mbox, reg, val, len); 135f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari } else { 136f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari for (i = 0; i < len; i++) { 137f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_regs_i2c(priv, mbox, reg+i, val+i, 1); 138f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret) 139f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 140f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari } 141f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari } 142f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 143f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaarierr: 144f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return 0; 145f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari} 146f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 147f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari/* read multiple registers */ 148f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaaristatic int af9013_rd_regs(struct af9013_state *priv, u16 reg, u8 *val, int len) 149f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari{ 150f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari int ret, i; 151f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari u8 mbox = (0 << 7)|(0 << 6)|(1 << 1)|(0 << 0); 152f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 153938ca36ef7914bd013acbff9f15e393fe79d71daDan Carpenter if ((priv->config.ts_mode == AF9013_TS_USB) && 154938ca36ef7914bd013acbff9f15e393fe79d71daDan Carpenter ((reg & 0xff00) != 0xff00) && ((reg & 0xff00) != 0xae00)) { 155f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari mbox |= ((len - 1) << 2); 156f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_rd_regs_i2c(priv, mbox, reg, val, len); 157f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari } else { 158f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari for (i = 0; i < len; i++) { 159f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_rd_regs_i2c(priv, mbox, reg+i, val+i, 1); 160f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret) 161f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 162f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari } 163f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari } 164f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 165f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaarierr: 166f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return 0; 167825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari} 168825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 169825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari/* write single register */ 170f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaaristatic int af9013_wr_reg(struct af9013_state *priv, u16 reg, u8 val) 171825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari{ 172f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return af9013_wr_regs(priv, reg, &val, 1); 173825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari} 174825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 175825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari/* read single register */ 176f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaaristatic int af9013_rd_reg(struct af9013_state *priv, u16 reg, u8 *val) 177825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari{ 178f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return af9013_rd_regs(priv, reg, val, 1); 179f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari} 180825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 181f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaaristatic int af9013_write_ofsm_regs(struct af9013_state *state, u16 reg, u8 *val, 182f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari u8 len) 183f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari{ 184f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari u8 mbox = (1 << 7)|(1 << 6)|((len - 1) << 2)|(1 << 1)|(1 << 0); 185f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return af9013_wr_regs_i2c(state, mbox, reg, val, len); 186825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari} 187825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 188f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaaristatic int af9013_wr_reg_bits(struct af9013_state *state, u16 reg, int pos, 189f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari int len, u8 val) 190825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari{ 191825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari int ret; 192825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari u8 tmp, mask; 193825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 194f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* no need for read if whole reg is written */ 195f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (len != 8) { 196f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_rd_reg(state, reg, &tmp); 197f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret) 198f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return ret; 199825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 200f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari mask = (0xff >> (8 - len)) << pos; 201f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari val <<= pos; 202f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari tmp &= ~mask; 203f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari val |= tmp; 204f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari } 205825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 206f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return af9013_wr_reg(state, reg, val); 207825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari} 208825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 209f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaaristatic int af9013_rd_reg_bits(struct af9013_state *state, u16 reg, int pos, 210f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari int len, u8 *val) 211825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari{ 212825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari int ret; 213825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari u8 tmp; 214825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 215f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_rd_reg(state, reg, &tmp); 216825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (ret) 217825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari return ret; 218f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 219f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari *val = (tmp >> pos); 220f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari *val &= (0xff >> (8 - len)); 221f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 222825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari return 0; 223825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari} 224825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 225825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaaristatic int af9013_set_gpio(struct af9013_state *state, u8 gpio, u8 gpioval) 226825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari{ 227825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari int ret; 228825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari u8 pos; 229825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari u16 addr; 230825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 2318df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: gpio=%d gpioval=%02x\n", 2328df379c5a425d127216195861b88f981530e7581Antti Palosaari __func__, gpio, gpioval); 233f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 234f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* 235f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari * GPIO0 & GPIO1 0xd735 236f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari * GPIO2 & GPIO3 0xd736 237f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari */ 238825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 239825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari switch (gpio) { 240825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case 0: 241825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case 1: 242825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari addr = 0xd735; 243825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 244825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case 2: 245825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case 3: 246825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari addr = 0xd736; 247825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 248825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 249825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari default: 2508df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_err(&state->i2c->dev, "%s: invalid gpio=%d\n", 2518df379c5a425d127216195861b88f981530e7581Antti Palosaari KBUILD_MODNAME, gpio); 252825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari ret = -EINVAL; 253f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 254c2c1b4156a447f113ef4d167decce29399c2667cPeter Senna Tschudin } 255825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 256825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari switch (gpio) { 257825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case 0: 258825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case 2: 259825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari pos = 0; 260825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 261825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case 1: 262825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case 3: 263825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari default: 264825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari pos = 4; 265825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 266c2c1b4156a447f113ef4d167decce29399c2667cPeter Senna Tschudin } 267825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 268f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg_bits(state, addr, pos, 4, gpioval); 269f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret) 270f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 271825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 272f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return ret; 273f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaarierr: 2748df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret); 275825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari return ret; 276825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari} 277825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 2788df379c5a425d127216195861b88f981530e7581Antti Palosaaristatic u32 af9013_div(struct af9013_state *state, u32 a, u32 b, u32 x) 279825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari{ 280825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari u32 r = 0, c = 0, i; 281f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 2828df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: a=%d b=%d x=%d\n", __func__, a, b, x); 283825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 284825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (a > b) { 285825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari c = a / b; 286825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari a = a - c * b; 287825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } 288825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 289825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari for (i = 0; i < x; i++) { 290825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (a >= b) { 291825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari r += 1; 292825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari a -= b; 293825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } 294825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari a <<= 1; 295825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari r <<= 1; 296825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } 297825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari r = (c << (u32)x) + r; 298825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 2998df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: a=%d b=%d x=%d r=%d r=%x\n", 3008df379c5a425d127216195861b88f981530e7581Antti Palosaari __func__, a, b, x, r, r); 3018df379c5a425d127216195861b88f981530e7581Antti Palosaari 302825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari return r; 303825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari} 304825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 305f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaaristatic int af9013_power_ctrl(struct af9013_state *state, u8 onoff) 306825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari{ 307f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari int ret, i; 308f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari u8 tmp; 3099b22edd4b0f3520bc1279338d52dc63e76852befAntti Palosaari 3108df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: onoff=%d\n", __func__, onoff); 311f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 312f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* enable reset */ 313f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg_bits(state, 0xd417, 4, 1, 1); 314f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret) 315f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 316f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 317f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* start reset mechanism */ 318f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg(state, 0xaeff, 1); 319f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret) 320f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 321f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 322f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* wait reset performs */ 323f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari for (i = 0; i < 150; i++) { 324f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_rd_reg_bits(state, 0xd417, 1, 1, &tmp); 325f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret) 326f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 327f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 328f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (tmp) 329f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari break; /* reset done */ 330f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 331f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari usleep_range(5000, 25000); 332825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } 333825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 334f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (!tmp) 335f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return -ETIMEDOUT; 336825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 337f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (onoff) { 338f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* clear reset */ 339f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg_bits(state, 0xd417, 1, 1, 0); 340825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (ret) 341f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 342f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 343f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* disable reset */ 344f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg_bits(state, 0xd417, 4, 1, 0); 345f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 346f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* power on */ 347f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg_bits(state, 0xd73a, 3, 1, 0); 348f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari } else { 349f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* power off */ 350f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg_bits(state, 0xd73a, 3, 1, 1); 351825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } 352825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 353f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return ret; 354f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaarierr: 3558df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret); 356825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari return ret; 357825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari} 358825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 359f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaaristatic int af9013_statistics_ber_unc_start(struct dvb_frontend *fe) 360825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari{ 361f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari struct af9013_state *state = fe->demodulator_priv; 362825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari int ret; 363825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 3648df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s:\n", __func__); 365825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 366f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* reset and start BER counter */ 367f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg_bits(state, 0xd391, 4, 1, 1); 368f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret) 369f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 370f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 371f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return ret; 372f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaarierr: 3738df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret); 374f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return ret; 375f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari} 376f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 377f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaaristatic int af9013_statistics_ber_unc_result(struct dvb_frontend *fe) 378f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari{ 379f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari struct af9013_state *state = fe->demodulator_priv; 380f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari int ret; 381f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari u8 buf[5]; 382f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 3838df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s:\n", __func__); 384f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 385f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* check if error bit count is ready */ 386f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_rd_reg_bits(state, 0xd391, 4, 1, &buf[0]); 387f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret) 388f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 389f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 390f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (!buf[0]) { 3918df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: not ready\n", __func__); 392f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return 0; 393f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari } 394f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 395f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_rd_regs(state, 0xd387, buf, 5); 396f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret) 397f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 398f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 399f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari state->ber = (buf[2] << 16) | (buf[1] << 8) | buf[0]; 400f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari state->ucblocks += (buf[4] << 8) | buf[3]; 401f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 402f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return ret; 403f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaarierr: 4048df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret); 405f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return ret; 406f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari} 407f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 408f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaaristatic int af9013_statistics_snr_start(struct dvb_frontend *fe) 409f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari{ 410f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari struct af9013_state *state = fe->demodulator_priv; 411f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari int ret; 412f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 4138df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s:\n", __func__); 414f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 415f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* start SNR meas */ 416f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg_bits(state, 0xd2e1, 3, 1, 1); 417f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret) 418f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 419f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 420f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return ret; 421f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaarierr: 4228df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret); 423f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return ret; 424f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari} 425f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 426f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaaristatic int af9013_statistics_snr_result(struct dvb_frontend *fe) 427f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari{ 428f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari struct af9013_state *state = fe->demodulator_priv; 429f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari int ret, i, len; 430f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari u8 buf[3], tmp; 431f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari u32 snr_val; 432f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari const struct af9013_snr *uninitialized_var(snr_lut); 433f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 4348df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s:\n", __func__); 435f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 436f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* check if SNR ready */ 437f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_rd_reg_bits(state, 0xd2e1, 3, 1, &tmp); 438f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret) 439f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 440f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 441f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (!tmp) { 4428df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: not ready\n", __func__); 443f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return 0; 444f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari } 445f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 446f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* read value */ 447f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_rd_regs(state, 0xd2e3, buf, 3); 448f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret) 449f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 450f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 451f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari snr_val = (buf[2] << 16) | (buf[1] << 8) | buf[0]; 452f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 453f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* read current modulation */ 454f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_rd_reg(state, 0xd3c1, &tmp); 455f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret) 456f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 457f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 458f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari switch ((tmp >> 6) & 3) { 459f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari case 0: 460f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari len = ARRAY_SIZE(qpsk_snr_lut); 461f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari snr_lut = qpsk_snr_lut; 462825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 463f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari case 1: 464f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari len = ARRAY_SIZE(qam16_snr_lut); 465f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari snr_lut = qam16_snr_lut; 466825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 467f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari case 2: 468f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari len = ARRAY_SIZE(qam64_snr_lut); 469f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari snr_lut = qam64_snr_lut; 470825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 471825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari default: 472f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 473825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } 474825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 475f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari for (i = 0; i < len; i++) { 476f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari tmp = snr_lut[i].snr; 477825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 478f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (snr_val < snr_lut[i].val) 479f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari break; 480f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari } 481f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari state->snr = tmp * 10; /* dB/10 */ 482825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 483f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return ret; 484f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaarierr: 4858df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret); 486f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return ret; 487f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari} 488825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 489f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaaristatic int af9013_statistics_signal_strength(struct dvb_frontend *fe) 490f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari{ 491f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari struct af9013_state *state = fe->demodulator_priv; 492f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari int ret = 0; 493f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari u8 buf[2], rf_gain, if_gain; 494f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari int signal_strength; 495f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 4968df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s:\n", __func__); 497f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 498f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (!state->signal_strength_en) 499f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return 0; 500f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 501f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_rd_regs(state, 0xd07c, buf, 2); 502f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret) 503f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 504f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 505f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari rf_gain = buf[0]; 506f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if_gain = buf[1]; 507f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 508f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari signal_strength = (0xffff / \ 509f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari (9 * (state->rf_50 + state->if_50) - \ 510f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 11 * (state->rf_80 + state->if_80))) * \ 511f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari (10 * (rf_gain + if_gain) - \ 512f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 11 * (state->rf_80 + state->if_80)); 513f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (signal_strength < 0) 514f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari signal_strength = 0; 515f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari else if (signal_strength > 0xffff) 516f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari signal_strength = 0xffff; 517f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 518f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari state->signal_strength = signal_strength; 519f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 520f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return ret; 521f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaarierr: 5228df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret); 523825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari return ret; 524825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari} 525825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 526f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaaristatic void af9013_statistics_work(struct work_struct *work) 527825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari{ 528f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari struct af9013_state *state = container_of(work, 529f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari struct af9013_state, statistics_work.work); 530f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari unsigned int next_msec; 531f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 532f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* update only signal strength when demod is not locked */ 533f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (!(state->fe_status & FE_HAS_LOCK)) { 534f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari state->statistics_step = 0; 535f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari state->ber = 0; 536f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari state->snr = 0; 537f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari } 538f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 539f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari switch (state->statistics_step) { 540f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari default: 541f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari state->statistics_step = 0; 542f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari case 0: 543fdf07b027b2d3eee9a561898b9c427cc3e457af4Hans Verkuil af9013_statistics_signal_strength(&state->fe); 544f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari state->statistics_step++; 545f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari next_msec = 300; 546f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari break; 547f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari case 1: 548fdf07b027b2d3eee9a561898b9c427cc3e457af4Hans Verkuil af9013_statistics_snr_start(&state->fe); 549f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari state->statistics_step++; 550f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari next_msec = 200; 551f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari break; 552f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari case 2: 553fdf07b027b2d3eee9a561898b9c427cc3e457af4Hans Verkuil af9013_statistics_ber_unc_start(&state->fe); 554f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari state->statistics_step++; 555f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari next_msec = 1000; 556f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari break; 557f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari case 3: 558fdf07b027b2d3eee9a561898b9c427cc3e457af4Hans Verkuil af9013_statistics_snr_result(&state->fe); 559f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari state->statistics_step++; 560f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari next_msec = 400; 561f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari break; 562f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari case 4: 563fdf07b027b2d3eee9a561898b9c427cc3e457af4Hans Verkuil af9013_statistics_ber_unc_result(&state->fe); 564f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari state->statistics_step++; 565f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari next_msec = 100; 566f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari break; 567f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari } 568f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 569f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari schedule_delayed_work(&state->statistics_work, 570f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari msecs_to_jiffies(next_msec)); 571f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari} 572f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 573f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaaristatic int af9013_get_tune_settings(struct dvb_frontend *fe, 574f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari struct dvb_frontend_tune_settings *fesettings) 575f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari{ 576f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari fesettings->min_delay_ms = 800; 577f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari fesettings->step_size = 0; 578f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari fesettings->max_drift = 0; 579f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 580f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return 0; 581f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari} 582f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 58359d3cc1975db3676da707ea7083dc7e15117409dMauro Carvalho Chehabstatic int af9013_set_frontend(struct dvb_frontend *fe) 584f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari{ 585f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari struct af9013_state *state = fe->demodulator_priv; 586f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari struct dtv_frontend_properties *c = &fe->dtv_property_cache; 587f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari int ret, i, sampling_freq; 588f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari bool auto_mode, spec_inv; 589f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari u8 buf[6]; 590f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari u32 if_frequency, freq_cw; 591f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 5928df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: frequency=%d bandwidth_hz=%d\n", 5938df379c5a425d127216195861b88f981530e7581Antti Palosaari __func__, c->frequency, c->bandwidth_hz); 594f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 595f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* program tuner */ 596f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (fe->ops.tuner_ops.set_params) 59714d24d148c7521b2b88b396652e36f55d061e195Mauro Carvalho Chehab fe->ops.tuner_ops.set_params(fe); 598f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 599f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* program CFOE coefficients */ 600f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (c->bandwidth_hz != state->bandwidth_hz) { 601f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari for (i = 0; i < ARRAY_SIZE(coeff_lut); i++) { 602f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (coeff_lut[i].clock == state->config.clock && 603f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari coeff_lut[i].bandwidth_hz == c->bandwidth_hz) { 604f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari break; 605f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari } 606825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } 607825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 608f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_regs(state, 0xae00, coeff_lut[i].val, 609f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari sizeof(coeff_lut[i].val)); 610f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari } 6116d42b218b43f300d0787df7984c8f789de24c6e7Antti Palosaari 612f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* program frequency control */ 613f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (c->bandwidth_hz != state->bandwidth_hz || state->first_tune) { 6146d42b218b43f300d0787df7984c8f789de24c6e7Antti Palosaari /* get used IF frequency */ 6156d42b218b43f300d0787df7984c8f789de24c6e7Antti Palosaari if (fe->ops.tuner_ops.get_if_frequency) 616f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency); 6176d42b218b43f300d0787df7984c8f789de24c6e7Antti Palosaari else 618f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if_frequency = state->config.if_frequency; 619825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 6208df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: if_frequency=%d\n", 6218df379c5a425d127216195861b88f981530e7581Antti Palosaari __func__, if_frequency); 622ab2e06acb4ae0293add73608a49512530758edf6Antti Palosaari 623f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari sampling_freq = if_frequency; 624825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 625f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari while (sampling_freq > (state->config.clock / 2)) 626f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari sampling_freq -= state->config.clock; 627825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 628f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (sampling_freq < 0) { 629f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari sampling_freq *= -1; 630f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari spec_inv = state->config.spec_inv; 631f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari } else { 632f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari spec_inv = !state->config.spec_inv; 633f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari } 634825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 6358df379c5a425d127216195861b88f981530e7581Antti Palosaari freq_cw = af9013_div(state, sampling_freq, state->config.clock, 6368df379c5a425d127216195861b88f981530e7581Antti Palosaari 23); 637825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 638f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (spec_inv) 639f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari freq_cw = 0x800000 - freq_cw; 640825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 641f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari buf[0] = (freq_cw >> 0) & 0xff; 642f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari buf[1] = (freq_cw >> 8) & 0xff; 643f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari buf[2] = (freq_cw >> 16) & 0x7f; 644825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 645f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari freq_cw = 0x800000 - freq_cw; 646825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 647f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari buf[3] = (freq_cw >> 0) & 0xff; 648f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari buf[4] = (freq_cw >> 8) & 0xff; 649f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari buf[5] = (freq_cw >> 16) & 0x7f; 650f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 651f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_regs(state, 0xd140, buf, 3); 652f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret) 653f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 654f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 655f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_regs(state, 0x9be7, buf, 6); 656f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret) 657f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 658825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } 659825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 660f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* clear TPS lock flag */ 661f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg_bits(state, 0xd330, 3, 1, 1); 662f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret) 663f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 664825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 665f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* clear MPEG2 lock flag */ 666f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg_bits(state, 0xd507, 6, 1, 0); 667f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret) 668f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 669a2f5a8117cb185fc347f35e369a6320e6aa9d82dAntti Palosaari 670f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* empty channel function */ 671f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg_bits(state, 0x9bfe, 0, 1, 0); 672f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret) 673f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 674f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 675f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* empty DVB-T channel function */ 676f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg_bits(state, 0x9bc2, 0, 1, 0); 677f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret) 678f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 679f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 680f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* transmission parameters */ 681f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari auto_mode = false; 682f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari memset(buf, 0, 3); 683f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 684f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari switch (c->transmission_mode) { 685825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case TRANSMISSION_MODE_AUTO: 6866a5e7fde3a04ef5134702753f77e9b8aa6aab789Mauro Carvalho Chehab auto_mode = true; 687f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari break; 688825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case TRANSMISSION_MODE_2K: 689825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 690825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case TRANSMISSION_MODE_8K: 691825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari buf[0] |= (1 << 0); 692825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 693825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari default: 6948df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: invalid transmission_mode\n", 6958df379c5a425d127216195861b88f981530e7581Antti Palosaari __func__); 6966a5e7fde3a04ef5134702753f77e9b8aa6aab789Mauro Carvalho Chehab auto_mode = true; 697825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } 698825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 699f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari switch (c->guard_interval) { 700825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case GUARD_INTERVAL_AUTO: 7016a5e7fde3a04ef5134702753f77e9b8aa6aab789Mauro Carvalho Chehab auto_mode = true; 702f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari break; 703825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case GUARD_INTERVAL_1_32: 704825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 705825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case GUARD_INTERVAL_1_16: 706825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari buf[0] |= (1 << 2); 707825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 708825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case GUARD_INTERVAL_1_8: 709825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari buf[0] |= (2 << 2); 710825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 711825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case GUARD_INTERVAL_1_4: 712825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari buf[0] |= (3 << 2); 713825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 714825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari default: 7158df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: invalid guard_interval\n", 7168df379c5a425d127216195861b88f981530e7581Antti Palosaari __func__); 7176a5e7fde3a04ef5134702753f77e9b8aa6aab789Mauro Carvalho Chehab auto_mode = true; 718825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } 719825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 720f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari switch (c->hierarchy) { 721825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case HIERARCHY_AUTO: 7226a5e7fde3a04ef5134702753f77e9b8aa6aab789Mauro Carvalho Chehab auto_mode = true; 723f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari break; 724825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case HIERARCHY_NONE: 725825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 726825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case HIERARCHY_1: 727825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari buf[0] |= (1 << 4); 728825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 729825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case HIERARCHY_2: 730825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari buf[0] |= (2 << 4); 731825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 732825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case HIERARCHY_4: 733825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari buf[0] |= (3 << 4); 734825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 735825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari default: 7368df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: invalid hierarchy\n", __func__); 7376a5e7fde3a04ef5134702753f77e9b8aa6aab789Mauro Carvalho Chehab auto_mode = true; 738c2c1b4156a447f113ef4d167decce29399c2667cPeter Senna Tschudin } 739825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 740f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari switch (c->modulation) { 741825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case QAM_AUTO: 7426a5e7fde3a04ef5134702753f77e9b8aa6aab789Mauro Carvalho Chehab auto_mode = true; 743f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari break; 744825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case QPSK: 745825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 746825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case QAM_16: 747825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari buf[1] |= (1 << 6); 748825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 749825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case QAM_64: 750825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari buf[1] |= (2 << 6); 751825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 752825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari default: 7538df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: invalid modulation\n", __func__); 7546a5e7fde3a04ef5134702753f77e9b8aa6aab789Mauro Carvalho Chehab auto_mode = true; 755825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } 756825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 757825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari /* Use HP. How and which case we can switch to LP? */ 758825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari buf[1] |= (1 << 4); 759825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 760f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari switch (c->code_rate_HP) { 761825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case FEC_AUTO: 7626a5e7fde3a04ef5134702753f77e9b8aa6aab789Mauro Carvalho Chehab auto_mode = true; 763f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari break; 764825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case FEC_1_2: 765825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 766825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case FEC_2_3: 767825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari buf[2] |= (1 << 0); 768825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 769825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case FEC_3_4: 770825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari buf[2] |= (2 << 0); 771825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 772825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case FEC_5_6: 773825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari buf[2] |= (3 << 0); 774825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 775825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case FEC_7_8: 776825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari buf[2] |= (4 << 0); 777825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 778825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari default: 7798df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: invalid code_rate_HP\n", 7808df379c5a425d127216195861b88f981530e7581Antti Palosaari __func__); 7816a5e7fde3a04ef5134702753f77e9b8aa6aab789Mauro Carvalho Chehab auto_mode = true; 782825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } 783825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 784f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari switch (c->code_rate_LP) { 785825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case FEC_AUTO: 7866a5e7fde3a04ef5134702753f77e9b8aa6aab789Mauro Carvalho Chehab auto_mode = true; 787f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari break; 788825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case FEC_1_2: 789825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 790825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case FEC_2_3: 791825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari buf[2] |= (1 << 3); 792825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 793825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case FEC_3_4: 794825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari buf[2] |= (2 << 3); 795825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 796825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case FEC_5_6: 797825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari buf[2] |= (3 << 3); 798825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 799825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case FEC_7_8: 800825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari buf[2] |= (4 << 3); 801825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 802825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case FEC_NONE: 803f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari break; 804825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari default: 8058df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: invalid code_rate_LP\n", 8068df379c5a425d127216195861b88f981530e7581Antti Palosaari __func__); 8076a5e7fde3a04ef5134702753f77e9b8aa6aab789Mauro Carvalho Chehab auto_mode = true; 808825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } 809825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 810f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari switch (c->bandwidth_hz) { 811f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari case 6000000: 812825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 813f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari case 7000000: 814825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari buf[1] |= (1 << 2); 815825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 816f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari case 8000000: 817825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari buf[1] |= (2 << 2); 818825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 819825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari default: 8208df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: invalid bandwidth_hz\n", 8218df379c5a425d127216195861b88f981530e7581Antti Palosaari __func__); 822f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = -EINVAL; 823f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 824825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } 825825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 826f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_regs(state, 0xd3c0, buf, 3); 827825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (ret) 828f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 829825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 830f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (auto_mode) { 831f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* clear easy mode flag */ 832f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg(state, 0xaefd, 0); 833825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (ret) 834f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 835825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 8368df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: auto params\n", __func__); 837825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } else { 838f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* set easy mode flag */ 839f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg(state, 0xaefd, 1); 840825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (ret) 841f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 842825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 843f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg(state, 0xaefe, 0); 844825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (ret) 845f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 846f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 8478df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: manual params\n", __func__); 848825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } 849825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 850f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* tune */ 851f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg(state, 0xffff, 0); 852825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (ret) 853f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 854f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 855f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari state->bandwidth_hz = c->bandwidth_hz; 856f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari state->set_frontend_jiffies = jiffies; 857f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari state->first_tune = false; 858825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 859f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return ret; 860f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaarierr: 8618df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret); 862825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari return ret; 863825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari} 864825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 8657c61d80a9bcfc3fdec8ffd75756cad6a64678229Mauro Carvalho Chehabstatic int af9013_get_frontend(struct dvb_frontend *fe) 866825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari{ 8677c61d80a9bcfc3fdec8ffd75756cad6a64678229Mauro Carvalho Chehab struct dtv_frontend_properties *c = &fe->dtv_property_cache; 868825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari struct af9013_state *state = fe->demodulator_priv; 869825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari int ret; 870f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari u8 buf[3]; 871825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 8728df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s:\n", __func__); 873f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 874f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_rd_regs(state, 0xd3c0, buf, 3); 875f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret) 876f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 877825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 878825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari switch ((buf[1] >> 6) & 3) { 879825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case 0: 880f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari c->modulation = QPSK; 881825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 882825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case 1: 883f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari c->modulation = QAM_16; 884825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 885825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case 2: 886f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari c->modulation = QAM_64; 887825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 888825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } 889825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 890825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari switch ((buf[0] >> 0) & 3) { 891825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case 0: 892f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari c->transmission_mode = TRANSMISSION_MODE_2K; 893825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 894825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case 1: 895f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari c->transmission_mode = TRANSMISSION_MODE_8K; 896825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } 897825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 898825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari switch ((buf[0] >> 2) & 3) { 899825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case 0: 9006a2329ad1cb80b158a75bbf1901b86dc2deb88eeGianluca Gennari c->guard_interval = GUARD_INTERVAL_1_32; 901825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 902825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case 1: 9036a2329ad1cb80b158a75bbf1901b86dc2deb88eeGianluca Gennari c->guard_interval = GUARD_INTERVAL_1_16; 904825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 905825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case 2: 9066a2329ad1cb80b158a75bbf1901b86dc2deb88eeGianluca Gennari c->guard_interval = GUARD_INTERVAL_1_8; 907825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 908825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case 3: 9096a2329ad1cb80b158a75bbf1901b86dc2deb88eeGianluca Gennari c->guard_interval = GUARD_INTERVAL_1_4; 910825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 911825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } 912825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 913825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari switch ((buf[0] >> 4) & 7) { 914825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case 0: 915f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari c->hierarchy = HIERARCHY_NONE; 916825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 917825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case 1: 918f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari c->hierarchy = HIERARCHY_1; 919825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 920825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case 2: 921f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari c->hierarchy = HIERARCHY_2; 922825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 923825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case 3: 924f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari c->hierarchy = HIERARCHY_4; 925825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 926825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } 927825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 928825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari switch ((buf[2] >> 0) & 7) { 929825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case 0: 930f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari c->code_rate_HP = FEC_1_2; 931825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 932825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case 1: 933f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari c->code_rate_HP = FEC_2_3; 934f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari break; 935f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari case 2: 936f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari c->code_rate_HP = FEC_3_4; 937f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari break; 938f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari case 3: 939f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari c->code_rate_HP = FEC_5_6; 940f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari break; 941f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari case 4: 942f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari c->code_rate_HP = FEC_7_8; 943f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari break; 944825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } 945825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 946f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari switch ((buf[2] >> 3) & 7) { 947f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari case 0: 948f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari c->code_rate_LP = FEC_1_2; 949f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari break; 950f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari case 1: 951f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari c->code_rate_LP = FEC_2_3; 952f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari break; 953f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari case 2: 954f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari c->code_rate_LP = FEC_3_4; 955f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari break; 956f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari case 3: 957f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari c->code_rate_LP = FEC_5_6; 958f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari break; 959f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari case 4: 960f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari c->code_rate_LP = FEC_7_8; 961f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari break; 962f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari } 963825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 964f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari switch ((buf[1] >> 2) & 3) { 965f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari case 0: 966f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari c->bandwidth_hz = 6000000; 967f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari break; 968f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari case 1: 969f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari c->bandwidth_hz = 7000000; 970f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari break; 971f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari case 2: 972f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari c->bandwidth_hz = 8000000; 973f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari break; 974825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } 975825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 976825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari return ret; 977f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaarierr: 9788df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret); 979825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari return ret; 980825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari} 981825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 982825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaaristatic int af9013_read_status(struct dvb_frontend *fe, fe_status_t *status) 983825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari{ 984825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari struct af9013_state *state = fe->demodulator_priv; 985f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari int ret; 986825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari u8 tmp; 987f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 988f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* 989f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari * Return status from the cache if it is younger than 2000ms with the 990f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari * exception of last tune is done during 4000ms. 991f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari */ 992f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (time_is_after_jiffies( 993f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari state->read_status_jiffies + msecs_to_jiffies(2000)) && 994f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari time_is_before_jiffies( 995f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari state->set_frontend_jiffies + msecs_to_jiffies(4000)) 996f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ) { 997f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari *status = state->fe_status; 998f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return 0; 999f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari } else { 1000f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari *status = 0; 1001f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari } 1002825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1003825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari /* MPEG2 lock */ 1004f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_rd_reg_bits(state, 0xd507, 6, 1, &tmp); 1005825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (ret) 1006f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1007f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 1008825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (tmp) 10098af5e3813b78e429c1774bfac67033c3948c9c8eAntti Palosaari *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | 10108af5e3813b78e429c1774bfac67033c3948c9c8eAntti Palosaari FE_HAS_SYNC | FE_HAS_LOCK; 1011825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 10128af5e3813b78e429c1774bfac67033c3948c9c8eAntti Palosaari if (!*status) { 10138af5e3813b78e429c1774bfac67033c3948c9c8eAntti Palosaari /* TPS lock */ 1014f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_rd_reg_bits(state, 0xd330, 3, 1, &tmp); 1015825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (ret) 1016f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1017f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 1018825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (tmp) 10198af5e3813b78e429c1774bfac67033c3948c9c8eAntti Palosaari *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | 10208af5e3813b78e429c1774bfac67033c3948c9c8eAntti Palosaari FE_HAS_VITERBI; 1021825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } 1022825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1023f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari state->fe_status = *status; 1024f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari state->read_status_jiffies = jiffies; 1025825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1026f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return ret; 1027f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaarierr: 10288df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret); 1029825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari return ret; 1030825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari} 1031825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1032f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaaristatic int af9013_read_snr(struct dvb_frontend *fe, u16 *snr) 1033825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari{ 1034825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari struct af9013_state *state = fe->demodulator_priv; 1035f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari *snr = state->snr; 1036f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return 0; 1037825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari} 1038825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1039825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaaristatic int af9013_read_signal_strength(struct dvb_frontend *fe, u16 *strength) 1040825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari{ 1041825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari struct af9013_state *state = fe->demodulator_priv; 1042825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari *strength = state->signal_strength; 1043f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return 0; 1044825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari} 1045825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1046f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaaristatic int af9013_read_ber(struct dvb_frontend *fe, u32 *ber) 1047825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari{ 1048825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari struct af9013_state *state = fe->demodulator_priv; 1049f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari *ber = state->ber; 1050f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return 0; 1051825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari} 1052825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1053825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaaristatic int af9013_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) 1054825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari{ 1055825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari struct af9013_state *state = fe->demodulator_priv; 1056825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari *ucblocks = state->ucblocks; 1057f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return 0; 1058825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari} 1059825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1060825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaaristatic int af9013_init(struct dvb_frontend *fe) 1061825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari{ 1062825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari struct af9013_state *state = fe->demodulator_priv; 1063825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari int ret, i, len; 1064f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari u8 buf[3], tmp; 1065f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari u32 adc_cw; 1066f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari const struct af9013_reg_bit *init; 1067825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 10688df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s:\n", __func__); 1069825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1070825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari /* power on */ 1071825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari ret = af9013_power_ctrl(state, 1); 1072825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (ret) 1073f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1074825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1075825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari /* enable ADC */ 1076f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg(state, 0xd73a, 0xa4); 1077825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (ret) 1078f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1079825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1080825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari /* write API version to firmware */ 1081f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_regs(state, 0x9bf2, state->config.api_version, 4); 1082f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret) 1083f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1084825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1085825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari /* program ADC control */ 1086f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari switch (state->config.clock) { 1087f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari case 28800000: /* 28.800 MHz */ 1088f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari tmp = 0; 1089f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari break; 1090f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari case 20480000: /* 20.480 MHz */ 1091f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari tmp = 1; 1092f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari break; 1093f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari case 28000000: /* 28.000 MHz */ 1094f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari tmp = 2; 1095f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari break; 1096f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari case 25000000: /* 25.000 MHz */ 1097f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari tmp = 3; 1098f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari break; 1099f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari default: 11008df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_err(&state->i2c->dev, "%s: invalid clock\n", 11018df379c5a425d127216195861b88f981530e7581Antti Palosaari KBUILD_MODNAME); 1102f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return -EINVAL; 1103f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari } 1104f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 11058df379c5a425d127216195861b88f981530e7581Antti Palosaari adc_cw = af9013_div(state, state->config.clock, 1000000ul, 19); 1106f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari buf[0] = (adc_cw >> 0) & 0xff; 1107f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari buf[1] = (adc_cw >> 8) & 0xff; 1108f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari buf[2] = (adc_cw >> 16) & 0xff; 1109f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 1110f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_regs(state, 0xd180, buf, 3); 1111f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret) 1112f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1113f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 1114f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg_bits(state, 0x9bd2, 0, 4, tmp); 1115825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (ret) 1116f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1117825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1118825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari /* set I2C master clock */ 1119f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg(state, 0xd416, 0x14); 1120825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (ret) 1121f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1122825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1123825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari /* set 16 embx */ 1124f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg_bits(state, 0xd700, 1, 1, 1); 1125825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (ret) 1126f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1127825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1128825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari /* set no trigger */ 1129f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg_bits(state, 0xd700, 2, 1, 0); 1130825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (ret) 1131f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1132825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1133825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari /* set read-update bit for constellation */ 1134f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg_bits(state, 0xd371, 1, 1, 1); 1135825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (ret) 1136f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1137825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1138f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* settings for mp2if */ 1139f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (state->config.ts_mode == AF9013_TS_USB) { 1140f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* AF9015 split PSB to 1.5k + 0.5k */ 1141f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg_bits(state, 0xd50b, 2, 1, 1); 1142f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret) 1143f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1144f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari } else { 1145f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* AF9013 change the output bit to data7 */ 1146f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg_bits(state, 0xd500, 3, 1, 1); 1147f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret) 1148f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1149f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 1150f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* AF9013 set mpeg to full speed */ 1151f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg_bits(state, 0xd502, 4, 1, 1); 1152f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret) 1153f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1154f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari } 1155f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 1156f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg_bits(state, 0xd520, 4, 1, 1); 1157825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (ret) 1158f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1159825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1160825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari /* load OFSM settings */ 11618df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: load ofsm settings\n", __func__); 1162825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari len = ARRAY_SIZE(ofsm_init); 1163825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari init = ofsm_init; 1164825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari for (i = 0; i < len; i++) { 1165f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg_bits(state, init[i].addr, init[i].pos, 1166825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari init[i].len, init[i].val); 1167825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (ret) 1168f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1169825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } 1170825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1171825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari /* load tuner specific settings */ 11728df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: load tuner specific settings\n", 11738df379c5a425d127216195861b88f981530e7581Antti Palosaari __func__); 1174825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari switch (state->config.tuner) { 1175825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case AF9013_TUNER_MXL5003D: 1176825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari len = ARRAY_SIZE(tuner_init_mxl5003d); 1177825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari init = tuner_init_mxl5003d; 1178825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 1179825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case AF9013_TUNER_MXL5005D: 1180825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case AF9013_TUNER_MXL5005R: 1181a4f31d0da5c6807a0f5dfc7d285d8d4bdaa1e36eAntti Palosaari case AF9013_TUNER_MXL5007T: 1182825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari len = ARRAY_SIZE(tuner_init_mxl5005); 1183825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari init = tuner_init_mxl5005; 1184825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 1185825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case AF9013_TUNER_ENV77H11D5: 1186825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari len = ARRAY_SIZE(tuner_init_env77h11d5); 1187825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari init = tuner_init_env77h11d5; 1188825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 1189825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case AF9013_TUNER_MT2060: 1190825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari len = ARRAY_SIZE(tuner_init_mt2060); 1191825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari init = tuner_init_mt2060; 1192825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 1193825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case AF9013_TUNER_MC44S803: 1194825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari len = ARRAY_SIZE(tuner_init_mc44s803); 1195825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari init = tuner_init_mc44s803; 1196825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 1197825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case AF9013_TUNER_QT1010: 1198825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case AF9013_TUNER_QT1010A: 1199825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari len = ARRAY_SIZE(tuner_init_qt1010); 1200825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari init = tuner_init_qt1010; 1201825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 1202825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case AF9013_TUNER_MT2060_2: 1203825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari len = ARRAY_SIZE(tuner_init_mt2060_2); 1204825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari init = tuner_init_mt2060_2; 1205825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 1206825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case AF9013_TUNER_TDA18271: 12072158e5090b5cc99ba05b43657a35d567cf077fe3Antti Palosaari case AF9013_TUNER_TDA18218: 1208825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari len = ARRAY_SIZE(tuner_init_tda18271); 1209825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari init = tuner_init_tda18271; 1210825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 1211825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari case AF9013_TUNER_UNKNOWN: 1212825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari default: 1213825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari len = ARRAY_SIZE(tuner_init_unknown); 1214825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari init = tuner_init_unknown; 1215825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 1216825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } 1217825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1218825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari for (i = 0; i < len; i++) { 1219f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg_bits(state, init[i].addr, init[i].pos, 1220825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari init[i].len, init[i].val); 1221825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (ret) 1222f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1223825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } 1224825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1225f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* TS mode */ 1226f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg_bits(state, 0xd500, 1, 2, state->config.ts_mode); 1227825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (ret) 1228f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1229825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1230825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari /* enable lock led */ 1231f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg_bits(state, 0xd730, 0, 1, 1); 1232825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (ret) 1233f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1234825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1235f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* check if we support signal strength */ 1236f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (!state->signal_strength_en) { 1237f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_rd_reg_bits(state, 0x9bee, 0, 1, 1238f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari &state->signal_strength_en); 1239f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret) 1240f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1241f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari } 12429e35cd222bc913f34b8f69e2b41daa7aa041d79aAntti Palosaari 1243f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* read values needed for signal strength calculation */ 1244f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (state->signal_strength_en && !state->rf_50) { 1245f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_rd_reg(state, 0x9bbd, &state->rf_50); 12469e35cd222bc913f34b8f69e2b41daa7aa041d79aAntti Palosaari if (ret) 1247f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1248f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 1249f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_rd_reg(state, 0x9bd0, &state->rf_80); 12509e35cd222bc913f34b8f69e2b41daa7aa041d79aAntti Palosaari if (ret) 1251f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1252f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 1253f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_rd_reg(state, 0x9be2, &state->if_50); 12549e35cd222bc913f34b8f69e2b41daa7aa041d79aAntti Palosaari if (ret) 1255f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1256f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 1257f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_rd_reg(state, 0x9be4, &state->if_80); 12589e35cd222bc913f34b8f69e2b41daa7aa041d79aAntti Palosaari if (ret) 1259f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 12609e35cd222bc913f34b8f69e2b41daa7aa041d79aAntti Palosaari } 12619e35cd222bc913f34b8f69e2b41daa7aa041d79aAntti Palosaari 1262f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* SNR */ 1263f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg(state, 0xd2e2, 1); 1264f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret) 1265f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1266f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 1267f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* BER / UCB */ 1268f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari buf[0] = (10000 >> 0) & 0xff; 1269f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari buf[1] = (10000 >> 8) & 0xff; 1270f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_regs(state, 0xd385, buf, 2); 1271f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret) 1272f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1273f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 1274f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* enable FEC monitor */ 1275f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg_bits(state, 0xd392, 1, 1, 1); 1276f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret) 1277f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1278f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 1279f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari state->first_tune = true; 1280f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari schedule_delayed_work(&state->statistics_work, msecs_to_jiffies(400)); 1281f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 1282f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return ret; 1283f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaarierr: 12848df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret); 1285f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return ret; 1286f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari} 1287f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 1288f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaaristatic int af9013_sleep(struct dvb_frontend *fe) 1289f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari{ 1290f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari struct af9013_state *state = fe->demodulator_priv; 1291f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari int ret; 1292f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 12938df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s:\n", __func__); 1294f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 1295f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* stop statistics polling */ 1296f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari cancel_delayed_work_sync(&state->statistics_work); 1297f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 1298f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* disable lock led */ 1299f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg_bits(state, 0xd730, 0, 1, 0); 1300f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret) 1301f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1302f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 1303f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* power off */ 1304f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_power_ctrl(state, 0); 1305f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret) 1306f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1307f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 1308f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return ret; 1309f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaarierr: 13108df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret); 1311f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return ret; 1312f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari} 1313f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 1314f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaaristatic int af9013_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) 1315f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari{ 1316f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari int ret; 1317f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari struct af9013_state *state = fe->demodulator_priv; 1318f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 13198df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: enable=%d\n", __func__, enable); 1320f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 1321f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari /* gate already open or close */ 1322f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (state->i2c_gate_state == enable) 1323f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return 0; 1324f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 1325f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (state->config.ts_mode == AF9013_TS_USB) 1326f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg_bits(state, 0xd417, 3, 1, enable); 1327f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari else 1328f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg_bits(state, 0xd607, 2, 1, enable); 1329f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (ret) 1330f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1331f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 1332f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari state->i2c_gate_state = enable; 1333f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 1334f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return ret; 1335f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaarierr: 13368df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret); 1337825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari return ret; 1338825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari} 1339825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1340f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaaristatic void af9013_release(struct dvb_frontend *fe) 1341f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari{ 1342f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari struct af9013_state *state = fe->demodulator_priv; 1343f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari kfree(state); 1344f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari} 1345f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 1346825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaaristatic struct dvb_frontend_ops af9013_ops; 1347825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1348825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaaristatic int af9013_download_firmware(struct af9013_state *state) 1349825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari{ 13506ed9d56086acb3bb4ec003ff6d2f54313774d72bAntti Palosaari int i, len, remaining, ret; 1351825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari const struct firmware *fw; 1352825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari u16 checksum = 0; 1353825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari u8 val; 1354825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari u8 fw_params[4]; 1355a71103a6adc10d7003a09ecf1de5532967d6bee8Antti Palosaari u8 *fw_file = AF9013_FIRMWARE; 1356825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1357825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari msleep(100); 1358825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari /* check whether firmware is already running */ 1359f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_rd_reg(state, 0x98be, &val); 1360825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (ret) 1361f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1362825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari else 13638df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: firmware status=%02x\n", 13648df379c5a425d127216195861b88f981530e7581Antti Palosaari __func__, val); 1365825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1366825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (val == 0x0c) /* fw is running, no need for download */ 1367825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari goto exit; 1368825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 13698df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_info(&state->i2c->dev, "%s: found a '%s' in cold state, will try " \ 13708df379c5a425d127216195861b88f981530e7581Antti Palosaari "to load a firmware\n", 13718df379c5a425d127216195861b88f981530e7581Antti Palosaari KBUILD_MODNAME, af9013_ops.info.name); 1372825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1373825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari /* request the firmware, this will block and timeout */ 1374e9785250ef2eead8bd5e9166679c0be0595df387Jean Delvare ret = request_firmware(&fw, fw_file, state->i2c->dev.parent); 1375825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (ret) { 13768df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_info(&state->i2c->dev, "%s: did not find the firmware " \ 13778df379c5a425d127216195861b88f981530e7581Antti Palosaari "file. (%s) Please see linux/Documentation/dvb/ for " \ 13788df379c5a425d127216195861b88f981530e7581Antti Palosaari "more details on firmware-problems. (%d)\n", 13798df379c5a425d127216195861b88f981530e7581Antti Palosaari KBUILD_MODNAME, fw_file, ret); 1380f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1381825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } 1382825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 13838df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_info(&state->i2c->dev, "%s: downloading firmware from file '%s'\n", 13848df379c5a425d127216195861b88f981530e7581Antti Palosaari KBUILD_MODNAME, fw_file); 1385825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1386825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari /* calc checksum */ 1387825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari for (i = 0; i < fw->size; i++) 1388825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari checksum += fw->data[i]; 1389825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1390825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari fw_params[0] = checksum >> 8; 1391825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari fw_params[1] = checksum & 0xff; 1392825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari fw_params[2] = fw->size >> 8; 1393825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari fw_params[3] = fw->size & 0xff; 1394825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1395825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari /* write fw checksum & size */ 1396825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari ret = af9013_write_ofsm_regs(state, 0x50fc, 1397825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari fw_params, sizeof(fw_params)); 1398825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (ret) 1399f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err_release; 1400825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 14016ed9d56086acb3bb4ec003ff6d2f54313774d72bAntti Palosaari #define FW_ADDR 0x5100 /* firmware start address */ 14026ed9d56086acb3bb4ec003ff6d2f54313774d72bAntti Palosaari #define LEN_MAX 16 /* max packet size */ 14036ed9d56086acb3bb4ec003ff6d2f54313774d72bAntti Palosaari for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) { 14046ed9d56086acb3bb4ec003ff6d2f54313774d72bAntti Palosaari len = remaining; 14056ed9d56086acb3bb4ec003ff6d2f54313774d72bAntti Palosaari if (len > LEN_MAX) 14066ed9d56086acb3bb4ec003ff6d2f54313774d72bAntti Palosaari len = LEN_MAX; 1407825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 14086ed9d56086acb3bb4ec003ff6d2f54313774d72bAntti Palosaari ret = af9013_write_ofsm_regs(state, 14096ed9d56086acb3bb4ec003ff6d2f54313774d72bAntti Palosaari FW_ADDR + fw->size - remaining, 14106ed9d56086acb3bb4ec003ff6d2f54313774d72bAntti Palosaari (u8 *) &fw->data[fw->size - remaining], len); 1411825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (ret) { 14128df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_err(&state->i2c->dev, 14138df379c5a425d127216195861b88f981530e7581Antti Palosaari "%s: firmware download failed=%d\n", 14148df379c5a425d127216195861b88f981530e7581Antti Palosaari KBUILD_MODNAME, ret); 1415f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err_release; 1416825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } 1417825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } 1418825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1419825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari /* request boot firmware */ 1420f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_wr_reg(state, 0xe205, 1); 1421825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (ret) 1422f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err_release; 1423825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1424825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari for (i = 0; i < 15; i++) { 1425825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari msleep(100); 1426825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1427825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari /* check firmware status */ 1428f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_rd_reg(state, 0x98be, &val); 1429825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (ret) 1430f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err_release; 1431825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 14328df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_dbg(&state->i2c->dev, "%s: firmware status=%02x\n", 14338df379c5a425d127216195861b88f981530e7581Antti Palosaari __func__, val); 1434825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1435825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (val == 0x0c || val == 0x04) /* success or fail */ 1436825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari break; 1437825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } 1438825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1439825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (val == 0x04) { 14408df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_err(&state->i2c->dev, "%s: firmware did not run\n", 14418df379c5a425d127216195861b88f981530e7581Antti Palosaari KBUILD_MODNAME); 1442f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = -ENODEV; 1443825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } else if (val != 0x0c) { 14448df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_err(&state->i2c->dev, "%s: firmware boot timeout\n", 14458df379c5a425d127216195861b88f981530e7581Antti Palosaari KBUILD_MODNAME); 1446f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = -ENODEV; 1447825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } 1448825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1449f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaarierr_release: 1450825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari release_firmware(fw); 1451f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaarierr: 1452825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaariexit: 1453825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (!ret) 14548df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_info(&state->i2c->dev, "%s: found a '%s' in warm state\n", 14558df379c5a425d127216195861b88f981530e7581Antti Palosaari KBUILD_MODNAME, af9013_ops.info.name); 1456825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari return ret; 1457825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari} 1458825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1459825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaaristruct dvb_frontend *af9013_attach(const struct af9013_config *config, 1460825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari struct i2c_adapter *i2c) 1461825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari{ 1462825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari int ret; 1463825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari struct af9013_state *state = NULL; 1464ce99efa53ee2e7989b5f44243518f086977760a6Antti Palosaari u8 buf[4], i; 1465825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1466825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari /* allocate memory for the internal state */ 1467825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari state = kzalloc(sizeof(struct af9013_state), GFP_KERNEL); 1468825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (state == NULL) 1469f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1470825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1471825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari /* setup the state */ 1472825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari state->i2c = i2c; 1473825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari memcpy(&state->config, config, sizeof(struct af9013_config)); 1474825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1475825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari /* download firmware */ 1476f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari if (state->config.ts_mode != AF9013_TS_USB) { 1477825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari ret = af9013_download_firmware(state); 1478825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (ret) 1479f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1480825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } 1481825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1482825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari /* firmware version */ 1483f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari ret = af9013_rd_regs(state, 0x5103, buf, 4); 1484109a29900a36b2b1e7b7f83a561c6af7e343461fAntti Palosaari if (ret) 1485f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1486109a29900a36b2b1e7b7f83a561c6af7e343461fAntti Palosaari 14878df379c5a425d127216195861b88f981530e7581Antti Palosaari dev_info(&state->i2c->dev, "%s: firmware version %d.%d.%d.%d\n", 14888df379c5a425d127216195861b88f981530e7581Antti Palosaari KBUILD_MODNAME, buf[0], buf[1], buf[2], buf[3]); 1489825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1490825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari /* set GPIOs */ 1491825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari for (i = 0; i < sizeof(state->config.gpio); i++) { 1492825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari ret = af9013_set_gpio(state, i, state->config.gpio[i]); 1493825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari if (ret) 1494f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari goto err; 1495825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari } 1496825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1497825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari /* create dvb_frontend */ 1498f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari memcpy(&state->fe.ops, &af9013_ops, 1499825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari sizeof(struct dvb_frontend_ops)); 1500f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari state->fe.demodulator_priv = state; 1501f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 1502f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari INIT_DELAYED_WORK(&state->statistics_work, af9013_statistics_work); 1503825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1504f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari return &state->fe; 1505f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaarierr: 1506825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari kfree(state); 1507825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari return NULL; 1508825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari} 1509825b96708054ca16d6e4d56a29326d3b2cdd697dAntti PalosaariEXPORT_SYMBOL(af9013_attach); 1510825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1511825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaaristatic struct dvb_frontend_ops af9013_ops = { 151259d3cc1975db3676da707ea7083dc7e15117409dMauro Carvalho Chehab .delsys = { SYS_DVBT }, 1513825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari .info = { 1514f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari .name = "Afatech AF9013", 1515825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari .frequency_min = 174000000, 1516825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari .frequency_max = 862000000, 1517825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari .frequency_stepsize = 250000, 1518825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari .frequency_tolerance = 0, 1519f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari .caps = FE_CAN_FEC_1_2 | 1520f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari FE_CAN_FEC_2_3 | 1521f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari FE_CAN_FEC_3_4 | 1522f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari FE_CAN_FEC_5_6 | 1523f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari FE_CAN_FEC_7_8 | 1524f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari FE_CAN_FEC_AUTO | 1525f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari FE_CAN_QPSK | 1526f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari FE_CAN_QAM_16 | 1527f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari FE_CAN_QAM_64 | 1528f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari FE_CAN_QAM_AUTO | 1529825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari FE_CAN_TRANSMISSION_MODE_AUTO | 1530825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari FE_CAN_GUARD_INTERVAL_AUTO | 1531825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari FE_CAN_HIERARCHY_AUTO | 1532825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari FE_CAN_RECOVER | 1533825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari FE_CAN_MUTE_TS 1534825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari }, 1535825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1536825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari .release = af9013_release, 1537f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari 1538825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari .init = af9013_init, 1539825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari .sleep = af9013_sleep, 1540825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1541f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari .get_tune_settings = af9013_get_tune_settings, 154259d3cc1975db3676da707ea7083dc7e15117409dMauro Carvalho Chehab .set_frontend = af9013_set_frontend, 154359d3cc1975db3676da707ea7083dc7e15117409dMauro Carvalho Chehab .get_frontend = af9013_get_frontend, 1544825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1545825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari .read_status = af9013_read_status, 1546825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari .read_snr = af9013_read_snr, 1547f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari .read_signal_strength = af9013_read_signal_strength, 1548f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari .read_ber = af9013_read_ber, 1549825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari .read_ucblocks = af9013_read_ucblocks, 1550825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1551f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari .i2c_gate_ctrl = af9013_i2c_gate_ctrl, 1552f571e004c396c2ed8c2ba6bfc8a229b6bd5ab724Antti Palosaari}; 1553825b96708054ca16d6e4d56a29326d3b2cdd697dAntti Palosaari 1554825b96708054ca16d6e4d56a29326d3b2cdd697dAntti PalosaariMODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); 1555825b96708054ca16d6e4d56a29326d3b2cdd697dAntti PalosaariMODULE_DESCRIPTION("Afatech AF9013 DVB-T demodulator driver"); 1556825b96708054ca16d6e4d56a29326d3b2cdd697dAntti PalosaariMODULE_LICENSE("GPL"); 1557a71103a6adc10d7003a09ecf1de5532967d6bee8Antti PalosaariMODULE_FIRMWARE(AF9013_FIRMWARE); 1558