Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 1 | /* |
| 2 | tda18271-common.c - driver for the Philips / NXP TDA18271 silicon tuner |
| 3 | |
| 4 | Copyright (C) 2007, 2008 Michael Krufky <mkrufky@linuxtv.org> |
| 5 | |
| 6 | This program is free software; you can redistribute it and/or modify |
| 7 | it under the terms of the GNU General Public License as published by |
| 8 | the Free Software Foundation; either version 2 of the License, or |
| 9 | (at your option) any later version. |
| 10 | |
| 11 | This program is distributed in the hope that it will be useful, |
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | GNU General Public License for more details. |
| 15 | |
| 16 | You should have received a copy of the GNU General Public License |
| 17 | along with this program; if not, write to the Free Software |
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| 19 | */ |
| 20 | |
| 21 | #include "tda18271-priv.h" |
| 22 | |
| 23 | static int tda18271_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) |
| 24 | { |
| 25 | struct tda18271_priv *priv = fe->tuner_priv; |
| 26 | enum tda18271_i2c_gate gate; |
| 27 | int ret = 0; |
| 28 | |
| 29 | switch (priv->gate) { |
| 30 | case TDA18271_GATE_DIGITAL: |
| 31 | case TDA18271_GATE_ANALOG: |
| 32 | gate = priv->gate; |
| 33 | break; |
| 34 | case TDA18271_GATE_AUTO: |
| 35 | default: |
| 36 | switch (priv->mode) { |
| 37 | case TDA18271_DIGITAL: |
| 38 | gate = TDA18271_GATE_DIGITAL; |
| 39 | break; |
| 40 | case TDA18271_ANALOG: |
| 41 | default: |
| 42 | gate = TDA18271_GATE_ANALOG; |
| 43 | break; |
| 44 | } |
| 45 | } |
| 46 | |
| 47 | switch (gate) { |
| 48 | case TDA18271_GATE_ANALOG: |
| 49 | if (fe->ops.analog_ops.i2c_gate_ctrl) |
| 50 | ret = fe->ops.analog_ops.i2c_gate_ctrl(fe, enable); |
| 51 | break; |
| 52 | case TDA18271_GATE_DIGITAL: |
| 53 | if (fe->ops.i2c_gate_ctrl) |
| 54 | ret = fe->ops.i2c_gate_ctrl(fe, enable); |
| 55 | break; |
| 56 | default: |
| 57 | ret = -EINVAL; |
| 58 | break; |
| 59 | } |
| 60 | |
| 61 | return ret; |
| 62 | }; |
| 63 | |
| 64 | /*---------------------------------------------------------------------*/ |
| 65 | |
| 66 | static void tda18271_dump_regs(struct dvb_frontend *fe, int extended) |
| 67 | { |
| 68 | struct tda18271_priv *priv = fe->tuner_priv; |
| 69 | unsigned char *regs = priv->tda18271_regs; |
| 70 | |
| 71 | tda_reg("=== TDA18271 REG DUMP ===\n"); |
| 72 | tda_reg("ID_BYTE = 0x%02x\n", 0xff & regs[R_ID]); |
| 73 | tda_reg("THERMO_BYTE = 0x%02x\n", 0xff & regs[R_TM]); |
| 74 | tda_reg("POWER_LEVEL_BYTE = 0x%02x\n", 0xff & regs[R_PL]); |
| 75 | tda_reg("EASY_PROG_BYTE_1 = 0x%02x\n", 0xff & regs[R_EP1]); |
| 76 | tda_reg("EASY_PROG_BYTE_2 = 0x%02x\n", 0xff & regs[R_EP2]); |
| 77 | tda_reg("EASY_PROG_BYTE_3 = 0x%02x\n", 0xff & regs[R_EP3]); |
| 78 | tda_reg("EASY_PROG_BYTE_4 = 0x%02x\n", 0xff & regs[R_EP4]); |
| 79 | tda_reg("EASY_PROG_BYTE_5 = 0x%02x\n", 0xff & regs[R_EP5]); |
| 80 | tda_reg("CAL_POST_DIV_BYTE = 0x%02x\n", 0xff & regs[R_CPD]); |
| 81 | tda_reg("CAL_DIV_BYTE_1 = 0x%02x\n", 0xff & regs[R_CD1]); |
| 82 | tda_reg("CAL_DIV_BYTE_2 = 0x%02x\n", 0xff & regs[R_CD2]); |
| 83 | tda_reg("CAL_DIV_BYTE_3 = 0x%02x\n", 0xff & regs[R_CD3]); |
| 84 | tda_reg("MAIN_POST_DIV_BYTE = 0x%02x\n", 0xff & regs[R_MPD]); |
| 85 | tda_reg("MAIN_DIV_BYTE_1 = 0x%02x\n", 0xff & regs[R_MD1]); |
| 86 | tda_reg("MAIN_DIV_BYTE_2 = 0x%02x\n", 0xff & regs[R_MD2]); |
| 87 | tda_reg("MAIN_DIV_BYTE_3 = 0x%02x\n", 0xff & regs[R_MD3]); |
| 88 | |
| 89 | /* only dump extended regs if DBG_ADV is set */ |
| 90 | if (!(tda18271_debug & DBG_ADV)) |
| 91 | return; |
| 92 | |
| 93 | /* W indicates write-only registers. |
| 94 | * Register dump for write-only registers shows last value written. */ |
| 95 | |
| 96 | tda_reg("EXTENDED_BYTE_1 = 0x%02x\n", 0xff & regs[R_EB1]); |
| 97 | tda_reg("EXTENDED_BYTE_2 = 0x%02x\n", 0xff & regs[R_EB2]); |
| 98 | tda_reg("EXTENDED_BYTE_3 = 0x%02x\n", 0xff & regs[R_EB3]); |
| 99 | tda_reg("EXTENDED_BYTE_4 = 0x%02x\n", 0xff & regs[R_EB4]); |
| 100 | tda_reg("EXTENDED_BYTE_5 = 0x%02x\n", 0xff & regs[R_EB5]); |
| 101 | tda_reg("EXTENDED_BYTE_6 = 0x%02x\n", 0xff & regs[R_EB6]); |
| 102 | tda_reg("EXTENDED_BYTE_7 = 0x%02x\n", 0xff & regs[R_EB7]); |
| 103 | tda_reg("EXTENDED_BYTE_8 = 0x%02x\n", 0xff & regs[R_EB8]); |
| 104 | tda_reg("EXTENDED_BYTE_9 W = 0x%02x\n", 0xff & regs[R_EB9]); |
| 105 | tda_reg("EXTENDED_BYTE_10 = 0x%02x\n", 0xff & regs[R_EB10]); |
| 106 | tda_reg("EXTENDED_BYTE_11 = 0x%02x\n", 0xff & regs[R_EB11]); |
| 107 | tda_reg("EXTENDED_BYTE_12 = 0x%02x\n", 0xff & regs[R_EB12]); |
| 108 | tda_reg("EXTENDED_BYTE_13 = 0x%02x\n", 0xff & regs[R_EB13]); |
| 109 | tda_reg("EXTENDED_BYTE_14 = 0x%02x\n", 0xff & regs[R_EB14]); |
| 110 | tda_reg("EXTENDED_BYTE_15 = 0x%02x\n", 0xff & regs[R_EB15]); |
| 111 | tda_reg("EXTENDED_BYTE_16 W = 0x%02x\n", 0xff & regs[R_EB16]); |
| 112 | tda_reg("EXTENDED_BYTE_17 W = 0x%02x\n", 0xff & regs[R_EB17]); |
| 113 | tda_reg("EXTENDED_BYTE_18 = 0x%02x\n", 0xff & regs[R_EB18]); |
| 114 | tda_reg("EXTENDED_BYTE_19 W = 0x%02x\n", 0xff & regs[R_EB19]); |
| 115 | tda_reg("EXTENDED_BYTE_20 W = 0x%02x\n", 0xff & regs[R_EB20]); |
| 116 | tda_reg("EXTENDED_BYTE_21 = 0x%02x\n", 0xff & regs[R_EB21]); |
| 117 | tda_reg("EXTENDED_BYTE_22 = 0x%02x\n", 0xff & regs[R_EB22]); |
| 118 | tda_reg("EXTENDED_BYTE_23 = 0x%02x\n", 0xff & regs[R_EB23]); |
| 119 | } |
| 120 | |
| 121 | int tda18271_read_regs(struct dvb_frontend *fe) |
| 122 | { |
| 123 | struct tda18271_priv *priv = fe->tuner_priv; |
| 124 | unsigned char *regs = priv->tda18271_regs; |
| 125 | unsigned char buf = 0x00; |
| 126 | int ret; |
| 127 | struct i2c_msg msg[] = { |
Michael Krufky | f9e315a | 2008-04-22 14:41:54 -0300 | [diff] [blame] | 128 | { .addr = priv->i2c_props.addr, .flags = 0, |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 129 | .buf = &buf, .len = 1 }, |
Michael Krufky | f9e315a | 2008-04-22 14:41:54 -0300 | [diff] [blame] | 130 | { .addr = priv->i2c_props.addr, .flags = I2C_M_RD, |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 131 | .buf = regs, .len = 16 } |
| 132 | }; |
| 133 | |
| 134 | tda18271_i2c_gate_ctrl(fe, 1); |
| 135 | |
| 136 | /* read all registers */ |
Michael Krufky | f9e315a | 2008-04-22 14:41:54 -0300 | [diff] [blame] | 137 | ret = i2c_transfer(priv->i2c_props.adap, msg, 2); |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 138 | |
| 139 | tda18271_i2c_gate_ctrl(fe, 0); |
| 140 | |
| 141 | if (ret != 2) |
| 142 | tda_err("ERROR: i2c_transfer returned: %d\n", ret); |
| 143 | |
| 144 | if (tda18271_debug & DBG_REG) |
| 145 | tda18271_dump_regs(fe, 0); |
| 146 | |
| 147 | return (ret == 2 ? 0 : ret); |
| 148 | } |
| 149 | |
| 150 | int tda18271_read_extended(struct dvb_frontend *fe) |
| 151 | { |
| 152 | struct tda18271_priv *priv = fe->tuner_priv; |
| 153 | unsigned char *regs = priv->tda18271_regs; |
| 154 | unsigned char regdump[TDA18271_NUM_REGS]; |
| 155 | unsigned char buf = 0x00; |
| 156 | int ret, i; |
| 157 | struct i2c_msg msg[] = { |
Michael Krufky | f9e315a | 2008-04-22 14:41:54 -0300 | [diff] [blame] | 158 | { .addr = priv->i2c_props.addr, .flags = 0, |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 159 | .buf = &buf, .len = 1 }, |
Michael Krufky | f9e315a | 2008-04-22 14:41:54 -0300 | [diff] [blame] | 160 | { .addr = priv->i2c_props.addr, .flags = I2C_M_RD, |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 161 | .buf = regdump, .len = TDA18271_NUM_REGS } |
| 162 | }; |
| 163 | |
| 164 | tda18271_i2c_gate_ctrl(fe, 1); |
| 165 | |
| 166 | /* read all registers */ |
Michael Krufky | f9e315a | 2008-04-22 14:41:54 -0300 | [diff] [blame] | 167 | ret = i2c_transfer(priv->i2c_props.adap, msg, 2); |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 168 | |
| 169 | tda18271_i2c_gate_ctrl(fe, 0); |
| 170 | |
| 171 | if (ret != 2) |
| 172 | tda_err("ERROR: i2c_transfer returned: %d\n", ret); |
| 173 | |
Adrian Bunk | 805d92d | 2008-01-28 22:12:41 -0300 | [diff] [blame] | 174 | for (i = 0; i < TDA18271_NUM_REGS; i++) { |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 175 | /* don't update write-only registers */ |
| 176 | if ((i != R_EB9) && |
| 177 | (i != R_EB16) && |
| 178 | (i != R_EB17) && |
| 179 | (i != R_EB19) && |
| 180 | (i != R_EB20)) |
| 181 | regs[i] = regdump[i]; |
| 182 | } |
| 183 | |
| 184 | if (tda18271_debug & DBG_REG) |
| 185 | tda18271_dump_regs(fe, 1); |
| 186 | |
| 187 | return (ret == 2 ? 0 : ret); |
| 188 | } |
| 189 | |
Mauro Carvalho Chehab | 78ef81f | 2012-09-28 11:04:21 -0300 | [diff] [blame] | 190 | static int __tda18271_write_regs(struct dvb_frontend *fe, int idx, int len, |
| 191 | bool lock_i2c) |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 192 | { |
| 193 | struct tda18271_priv *priv = fe->tuner_priv; |
| 194 | unsigned char *regs = priv->tda18271_regs; |
| 195 | unsigned char buf[TDA18271_NUM_REGS + 1]; |
Michael Krufky | f9e315a | 2008-04-22 14:41:54 -0300 | [diff] [blame] | 196 | struct i2c_msg msg = { .addr = priv->i2c_props.addr, .flags = 0, |
Mauro Carvalho Chehab | e350d44 | 2010-09-26 22:58:28 -0300 | [diff] [blame] | 197 | .buf = buf }; |
| 198 | int i, ret = 1, max; |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 199 | |
| 200 | BUG_ON((len == 0) || (idx + len > sizeof(buf))); |
| 201 | |
Mauro Carvalho Chehab | e350d44 | 2010-09-26 22:58:28 -0300 | [diff] [blame] | 202 | switch (priv->small_i2c) { |
| 203 | case TDA18271_03_BYTE_CHUNK_INIT: |
| 204 | max = 3; |
| 205 | break; |
| 206 | case TDA18271_08_BYTE_CHUNK_INIT: |
| 207 | max = 8; |
| 208 | break; |
| 209 | case TDA18271_16_BYTE_CHUNK_INIT: |
| 210 | max = 16; |
| 211 | break; |
| 212 | case TDA18271_39_BYTE_CHUNK_INIT: |
| 213 | default: |
| 214 | max = 39; |
| 215 | } |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 216 | |
Mauro Carvalho Chehab | 78ef81f | 2012-09-28 11:04:21 -0300 | [diff] [blame] | 217 | |
| 218 | /* |
| 219 | * If lock_i2c is true, it will take the I2C bus for tda18271 private |
| 220 | * usage during the entire write ops, as otherwise, bad things could |
| 221 | * happen. |
| 222 | * During device init, several write operations will happen. So, |
| 223 | * tda18271_init_regs controls the I2C lock directly, |
| 224 | * disabling lock_i2c here. |
| 225 | */ |
| 226 | if (lock_i2c) { |
| 227 | tda18271_i2c_gate_ctrl(fe, 1); |
| 228 | i2c_lock_adapter(priv->i2c_props.adap); |
| 229 | } |
Mauro Carvalho Chehab | e350d44 | 2010-09-26 22:58:28 -0300 | [diff] [blame] | 230 | while (len) { |
| 231 | if (max > len) |
| 232 | max = len; |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 233 | |
Mauro Carvalho Chehab | e350d44 | 2010-09-26 22:58:28 -0300 | [diff] [blame] | 234 | buf[0] = idx; |
| 235 | for (i = 1; i <= max; i++) |
| 236 | buf[i] = regs[idx - 1 + i]; |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 237 | |
Mauro Carvalho Chehab | e350d44 | 2010-09-26 22:58:28 -0300 | [diff] [blame] | 238 | msg.len = max + 1; |
| 239 | |
| 240 | /* write registers */ |
Mauro Carvalho Chehab | 78ef81f | 2012-09-28 11:04:21 -0300 | [diff] [blame] | 241 | ret = __i2c_transfer(priv->i2c_props.adap, &msg, 1); |
Mauro Carvalho Chehab | e350d44 | 2010-09-26 22:58:28 -0300 | [diff] [blame] | 242 | if (ret != 1) |
| 243 | break; |
| 244 | |
| 245 | idx += max; |
| 246 | len -= max; |
| 247 | } |
Mauro Carvalho Chehab | 78ef81f | 2012-09-28 11:04:21 -0300 | [diff] [blame] | 248 | if (lock_i2c) { |
| 249 | i2c_unlock_adapter(priv->i2c_props.adap); |
| 250 | tda18271_i2c_gate_ctrl(fe, 0); |
| 251 | } |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 252 | |
| 253 | if (ret != 1) |
Michael Krufky | 650901c | 2009-09-05 19:01:56 -0300 | [diff] [blame] | 254 | tda_err("ERROR: idx = 0x%x, len = %d, " |
Mauro Carvalho Chehab | 7655e59 | 2010-10-27 14:55:34 -0200 | [diff] [blame] | 255 | "i2c_transfer returned: %d\n", idx, max, ret); |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 256 | |
| 257 | return (ret == 1 ? 0 : ret); |
| 258 | } |
| 259 | |
Mauro Carvalho Chehab | 78ef81f | 2012-09-28 11:04:21 -0300 | [diff] [blame] | 260 | int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len) |
| 261 | { |
| 262 | return __tda18271_write_regs(fe, idx, len, true); |
| 263 | } |
| 264 | |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 265 | /*---------------------------------------------------------------------*/ |
| 266 | |
Mauro Carvalho Chehab | 78ef81f | 2012-09-28 11:04:21 -0300 | [diff] [blame] | 267 | static int __tda18271_charge_pump_source(struct dvb_frontend *fe, |
| 268 | enum tda18271_pll pll, int force, |
| 269 | bool lock_i2c) |
Michael Krufky | 4efb0ca | 2008-04-22 14:46:23 -0300 | [diff] [blame] | 270 | { |
| 271 | struct tda18271_priv *priv = fe->tuner_priv; |
| 272 | unsigned char *regs = priv->tda18271_regs; |
| 273 | |
| 274 | int r_cp = (pll == TDA18271_CAL_PLL) ? R_EB7 : R_EB4; |
| 275 | |
| 276 | regs[r_cp] &= ~0x20; |
| 277 | regs[r_cp] |= ((force & 1) << 5); |
Michael Krufky | 4efb0ca | 2008-04-22 14:46:23 -0300 | [diff] [blame] | 278 | |
Mauro Carvalho Chehab | 78ef81f | 2012-09-28 11:04:21 -0300 | [diff] [blame] | 279 | return __tda18271_write_regs(fe, r_cp, 1, lock_i2c); |
Michael Krufky | 4efb0ca | 2008-04-22 14:46:23 -0300 | [diff] [blame] | 280 | } |
| 281 | |
Mauro Carvalho Chehab | 78ef81f | 2012-09-28 11:04:21 -0300 | [diff] [blame] | 282 | int tda18271_charge_pump_source(struct dvb_frontend *fe, |
| 283 | enum tda18271_pll pll, int force) |
| 284 | { |
| 285 | return __tda18271_charge_pump_source(fe, pll, force, true); |
| 286 | } |
| 287 | |
| 288 | |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 289 | int tda18271_init_regs(struct dvb_frontend *fe) |
| 290 | { |
| 291 | struct tda18271_priv *priv = fe->tuner_priv; |
| 292 | unsigned char *regs = priv->tda18271_regs; |
| 293 | |
| 294 | tda_dbg("initializing registers for device @ %d-%04x\n", |
Michael Krufky | f9e315a | 2008-04-22 14:41:54 -0300 | [diff] [blame] | 295 | i2c_adapter_id(priv->i2c_props.adap), |
| 296 | priv->i2c_props.addr); |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 297 | |
Mauro Carvalho Chehab | 78ef81f | 2012-09-28 11:04:21 -0300 | [diff] [blame] | 298 | /* |
| 299 | * Don't let any other I2C transfer to happen at adapter during init, |
| 300 | * as those could cause bad things |
| 301 | */ |
| 302 | tda18271_i2c_gate_ctrl(fe, 1); |
| 303 | i2c_lock_adapter(priv->i2c_props.adap); |
| 304 | |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 305 | /* initialize registers */ |
| 306 | switch (priv->id) { |
| 307 | case TDA18271HDC1: |
| 308 | regs[R_ID] = 0x83; |
| 309 | break; |
| 310 | case TDA18271HDC2: |
| 311 | regs[R_ID] = 0x84; |
| 312 | break; |
Peter Senna Tschudin | a719d69 | 2012-09-07 11:24:45 -0300 | [diff] [blame] | 313 | } |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 314 | |
| 315 | regs[R_TM] = 0x08; |
| 316 | regs[R_PL] = 0x80; |
| 317 | regs[R_EP1] = 0xc6; |
| 318 | regs[R_EP2] = 0xdf; |
| 319 | regs[R_EP3] = 0x16; |
| 320 | regs[R_EP4] = 0x60; |
| 321 | regs[R_EP5] = 0x80; |
| 322 | regs[R_CPD] = 0x80; |
| 323 | regs[R_CD1] = 0x00; |
| 324 | regs[R_CD2] = 0x00; |
| 325 | regs[R_CD3] = 0x00; |
| 326 | regs[R_MPD] = 0x00; |
| 327 | regs[R_MD1] = 0x00; |
| 328 | regs[R_MD2] = 0x00; |
| 329 | regs[R_MD3] = 0x00; |
| 330 | |
| 331 | switch (priv->id) { |
| 332 | case TDA18271HDC1: |
| 333 | regs[R_EB1] = 0xff; |
| 334 | break; |
| 335 | case TDA18271HDC2: |
| 336 | regs[R_EB1] = 0xfc; |
| 337 | break; |
Peter Senna Tschudin | a719d69 | 2012-09-07 11:24:45 -0300 | [diff] [blame] | 338 | } |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 339 | |
| 340 | regs[R_EB2] = 0x01; |
| 341 | regs[R_EB3] = 0x84; |
| 342 | regs[R_EB4] = 0x41; |
| 343 | regs[R_EB5] = 0x01; |
| 344 | regs[R_EB6] = 0x84; |
| 345 | regs[R_EB7] = 0x40; |
| 346 | regs[R_EB8] = 0x07; |
| 347 | regs[R_EB9] = 0x00; |
| 348 | regs[R_EB10] = 0x00; |
| 349 | regs[R_EB11] = 0x96; |
| 350 | |
| 351 | switch (priv->id) { |
| 352 | case TDA18271HDC1: |
| 353 | regs[R_EB12] = 0x0f; |
| 354 | break; |
| 355 | case TDA18271HDC2: |
| 356 | regs[R_EB12] = 0x33; |
| 357 | break; |
Peter Senna Tschudin | a719d69 | 2012-09-07 11:24:45 -0300 | [diff] [blame] | 358 | } |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 359 | |
| 360 | regs[R_EB13] = 0xc1; |
| 361 | regs[R_EB14] = 0x00; |
| 362 | regs[R_EB15] = 0x8f; |
| 363 | regs[R_EB16] = 0x00; |
| 364 | regs[R_EB17] = 0x00; |
| 365 | |
| 366 | switch (priv->id) { |
| 367 | case TDA18271HDC1: |
| 368 | regs[R_EB18] = 0x00; |
| 369 | break; |
| 370 | case TDA18271HDC2: |
| 371 | regs[R_EB18] = 0x8c; |
| 372 | break; |
Peter Senna Tschudin | a719d69 | 2012-09-07 11:24:45 -0300 | [diff] [blame] | 373 | } |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 374 | |
| 375 | regs[R_EB19] = 0x00; |
| 376 | regs[R_EB20] = 0x20; |
| 377 | |
| 378 | switch (priv->id) { |
| 379 | case TDA18271HDC1: |
| 380 | regs[R_EB21] = 0x33; |
| 381 | break; |
| 382 | case TDA18271HDC2: |
| 383 | regs[R_EB21] = 0xb3; |
| 384 | break; |
Peter Senna Tschudin | a719d69 | 2012-09-07 11:24:45 -0300 | [diff] [blame] | 385 | } |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 386 | |
| 387 | regs[R_EB22] = 0x48; |
| 388 | regs[R_EB23] = 0xb0; |
| 389 | |
Mauro Carvalho Chehab | 78ef81f | 2012-09-28 11:04:21 -0300 | [diff] [blame] | 390 | __tda18271_write_regs(fe, 0x00, TDA18271_NUM_REGS, false); |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 391 | |
| 392 | /* setup agc1 gain */ |
| 393 | regs[R_EB17] = 0x00; |
Mauro Carvalho Chehab | 78ef81f | 2012-09-28 11:04:21 -0300 | [diff] [blame] | 394 | __tda18271_write_regs(fe, R_EB17, 1, false); |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 395 | regs[R_EB17] = 0x03; |
Mauro Carvalho Chehab | 78ef81f | 2012-09-28 11:04:21 -0300 | [diff] [blame] | 396 | __tda18271_write_regs(fe, R_EB17, 1, false); |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 397 | regs[R_EB17] = 0x43; |
Mauro Carvalho Chehab | 78ef81f | 2012-09-28 11:04:21 -0300 | [diff] [blame] | 398 | __tda18271_write_regs(fe, R_EB17, 1, false); |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 399 | regs[R_EB17] = 0x4c; |
Mauro Carvalho Chehab | 78ef81f | 2012-09-28 11:04:21 -0300 | [diff] [blame] | 400 | __tda18271_write_regs(fe, R_EB17, 1, false); |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 401 | |
| 402 | /* setup agc2 gain */ |
| 403 | if ((priv->id) == TDA18271HDC1) { |
| 404 | regs[R_EB20] = 0xa0; |
Mauro Carvalho Chehab | 78ef81f | 2012-09-28 11:04:21 -0300 | [diff] [blame] | 405 | __tda18271_write_regs(fe, R_EB20, 1, false); |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 406 | regs[R_EB20] = 0xa7; |
Mauro Carvalho Chehab | 78ef81f | 2012-09-28 11:04:21 -0300 | [diff] [blame] | 407 | __tda18271_write_regs(fe, R_EB20, 1, false); |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 408 | regs[R_EB20] = 0xe7; |
Mauro Carvalho Chehab | 78ef81f | 2012-09-28 11:04:21 -0300 | [diff] [blame] | 409 | __tda18271_write_regs(fe, R_EB20, 1, false); |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 410 | regs[R_EB20] = 0xec; |
Mauro Carvalho Chehab | 78ef81f | 2012-09-28 11:04:21 -0300 | [diff] [blame] | 411 | __tda18271_write_regs(fe, R_EB20, 1, false); |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 412 | } |
| 413 | |
| 414 | /* image rejection calibration */ |
| 415 | |
| 416 | /* low-band */ |
| 417 | regs[R_EP3] = 0x1f; |
| 418 | regs[R_EP4] = 0x66; |
| 419 | regs[R_EP5] = 0x81; |
| 420 | regs[R_CPD] = 0xcc; |
| 421 | regs[R_CD1] = 0x6c; |
| 422 | regs[R_CD2] = 0x00; |
| 423 | regs[R_CD3] = 0x00; |
| 424 | regs[R_MPD] = 0xcd; |
| 425 | regs[R_MD1] = 0x77; |
| 426 | regs[R_MD2] = 0x08; |
| 427 | regs[R_MD3] = 0x00; |
| 428 | |
Mauro Carvalho Chehab | 78ef81f | 2012-09-28 11:04:21 -0300 | [diff] [blame] | 429 | __tda18271_write_regs(fe, R_EP3, 11, false); |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 430 | |
| 431 | if ((priv->id) == TDA18271HDC2) { |
| 432 | /* main pll cp source on */ |
Mauro Carvalho Chehab | 78ef81f | 2012-09-28 11:04:21 -0300 | [diff] [blame] | 433 | __tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 1, false); |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 434 | msleep(1); |
| 435 | |
| 436 | /* main pll cp source off */ |
Mauro Carvalho Chehab | 78ef81f | 2012-09-28 11:04:21 -0300 | [diff] [blame] | 437 | __tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 0, false); |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 438 | } |
| 439 | |
| 440 | msleep(5); /* pll locking */ |
| 441 | |
| 442 | /* launch detector */ |
Mauro Carvalho Chehab | 78ef81f | 2012-09-28 11:04:21 -0300 | [diff] [blame] | 443 | __tda18271_write_regs(fe, R_EP1, 1, false); |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 444 | msleep(5); /* wanted low measurement */ |
| 445 | |
| 446 | regs[R_EP5] = 0x85; |
| 447 | regs[R_CPD] = 0xcb; |
| 448 | regs[R_CD1] = 0x66; |
| 449 | regs[R_CD2] = 0x70; |
| 450 | |
Mauro Carvalho Chehab | 78ef81f | 2012-09-28 11:04:21 -0300 | [diff] [blame] | 451 | __tda18271_write_regs(fe, R_EP3, 7, false); |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 452 | msleep(5); /* pll locking */ |
| 453 | |
| 454 | /* launch optimization algorithm */ |
Mauro Carvalho Chehab | 78ef81f | 2012-09-28 11:04:21 -0300 | [diff] [blame] | 455 | __tda18271_write_regs(fe, R_EP2, 1, false); |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 456 | msleep(30); /* image low optimization completion */ |
| 457 | |
| 458 | /* mid-band */ |
| 459 | regs[R_EP5] = 0x82; |
| 460 | regs[R_CPD] = 0xa8; |
| 461 | regs[R_CD2] = 0x00; |
| 462 | regs[R_MPD] = 0xa9; |
| 463 | regs[R_MD1] = 0x73; |
| 464 | regs[R_MD2] = 0x1a; |
| 465 | |
Mauro Carvalho Chehab | 78ef81f | 2012-09-28 11:04:21 -0300 | [diff] [blame] | 466 | __tda18271_write_regs(fe, R_EP3, 11, false); |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 467 | msleep(5); /* pll locking */ |
| 468 | |
Michael Krufky | e83ebb6 | 2008-04-22 14:46:21 -0300 | [diff] [blame] | 469 | /* launch detector */ |
Mauro Carvalho Chehab | 78ef81f | 2012-09-28 11:04:21 -0300 | [diff] [blame] | 470 | __tda18271_write_regs(fe, R_EP1, 1, false); |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 471 | msleep(5); /* wanted mid measurement */ |
| 472 | |
| 473 | regs[R_EP5] = 0x86; |
| 474 | regs[R_CPD] = 0xa8; |
| 475 | regs[R_CD1] = 0x66; |
| 476 | regs[R_CD2] = 0xa0; |
| 477 | |
Mauro Carvalho Chehab | 78ef81f | 2012-09-28 11:04:21 -0300 | [diff] [blame] | 478 | __tda18271_write_regs(fe, R_EP3, 7, false); |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 479 | msleep(5); /* pll locking */ |
| 480 | |
| 481 | /* launch optimization algorithm */ |
Mauro Carvalho Chehab | 78ef81f | 2012-09-28 11:04:21 -0300 | [diff] [blame] | 482 | __tda18271_write_regs(fe, R_EP2, 1, false); |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 483 | msleep(30); /* image mid optimization completion */ |
| 484 | |
| 485 | /* high-band */ |
| 486 | regs[R_EP5] = 0x83; |
| 487 | regs[R_CPD] = 0x98; |
| 488 | regs[R_CD1] = 0x65; |
| 489 | regs[R_CD2] = 0x00; |
| 490 | regs[R_MPD] = 0x99; |
| 491 | regs[R_MD1] = 0x71; |
| 492 | regs[R_MD2] = 0xcd; |
| 493 | |
Mauro Carvalho Chehab | 78ef81f | 2012-09-28 11:04:21 -0300 | [diff] [blame] | 494 | __tda18271_write_regs(fe, R_EP3, 11, false); |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 495 | msleep(5); /* pll locking */ |
| 496 | |
| 497 | /* launch detector */ |
Mauro Carvalho Chehab | 78ef81f | 2012-09-28 11:04:21 -0300 | [diff] [blame] | 498 | __tda18271_write_regs(fe, R_EP1, 1, false); |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 499 | msleep(5); /* wanted high measurement */ |
| 500 | |
| 501 | regs[R_EP5] = 0x87; |
| 502 | regs[R_CD1] = 0x65; |
| 503 | regs[R_CD2] = 0x50; |
| 504 | |
Mauro Carvalho Chehab | 78ef81f | 2012-09-28 11:04:21 -0300 | [diff] [blame] | 505 | __tda18271_write_regs(fe, R_EP3, 7, false); |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 506 | msleep(5); /* pll locking */ |
| 507 | |
| 508 | /* launch optimization algorithm */ |
Mauro Carvalho Chehab | 78ef81f | 2012-09-28 11:04:21 -0300 | [diff] [blame] | 509 | __tda18271_write_regs(fe, R_EP2, 1, false); |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 510 | msleep(30); /* image high optimization completion */ |
| 511 | |
| 512 | /* return to normal mode */ |
| 513 | regs[R_EP4] = 0x64; |
Mauro Carvalho Chehab | 78ef81f | 2012-09-28 11:04:21 -0300 | [diff] [blame] | 514 | __tda18271_write_regs(fe, R_EP4, 1, false); |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 515 | |
| 516 | /* synchronize */ |
Mauro Carvalho Chehab | 78ef81f | 2012-09-28 11:04:21 -0300 | [diff] [blame] | 517 | __tda18271_write_regs(fe, R_EP1, 1, false); |
| 518 | |
| 519 | i2c_unlock_adapter(priv->i2c_props.adap); |
| 520 | tda18271_i2c_gate_ctrl(fe, 0); |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 521 | |
| 522 | return 0; |
| 523 | } |
| 524 | |
| 525 | /*---------------------------------------------------------------------*/ |
| 526 | |
Michael Krufky | 518d873 | 2008-01-13 17:01:01 -0300 | [diff] [blame] | 527 | /* |
| 528 | * Standby modes, EP3 [7:5] |
| 529 | * |
| 530 | * | SM || SM_LT || SM_XT || mode description |
| 531 | * |=====\\=======\\=======\\=================================== |
| 532 | * | 0 || 0 || 0 || normal mode |
| 533 | * |-----||-------||-------||----------------------------------- |
| 534 | * | || || || standby mode w/ slave tuner output |
| 535 | * | 1 || 0 || 0 || & loop thru & xtal oscillator on |
| 536 | * |-----||-------||-------||----------------------------------- |
| 537 | * | 1 || 1 || 0 || standby mode w/ xtal oscillator on |
| 538 | * |-----||-------||-------||----------------------------------- |
| 539 | * | 1 || 1 || 1 || power off |
| 540 | * |
| 541 | */ |
| 542 | |
| 543 | int tda18271_set_standby_mode(struct dvb_frontend *fe, |
| 544 | int sm, int sm_lt, int sm_xt) |
| 545 | { |
| 546 | struct tda18271_priv *priv = fe->tuner_priv; |
| 547 | unsigned char *regs = priv->tda18271_regs; |
| 548 | |
Michael Krufky | 9c41d45 | 2008-05-04 18:18:48 -0300 | [diff] [blame] | 549 | if (tda18271_debug & DBG_ADV) |
| 550 | tda_dbg("sm = %d, sm_lt = %d, sm_xt = %d\n", sm, sm_lt, sm_xt); |
Michael Krufky | 518d873 | 2008-01-13 17:01:01 -0300 | [diff] [blame] | 551 | |
| 552 | regs[R_EP3] &= ~0xe0; /* clear sm, sm_lt, sm_xt */ |
Roel Kluin | 51ca3bd | 2009-02-18 06:11:10 -0300 | [diff] [blame] | 553 | regs[R_EP3] |= (sm ? (1 << 7) : 0) | |
| 554 | (sm_lt ? (1 << 6) : 0) | |
| 555 | (sm_xt ? (1 << 5) : 0); |
Michael Krufky | 518d873 | 2008-01-13 17:01:01 -0300 | [diff] [blame] | 556 | |
Michael Krufky | d35fcca | 2008-05-03 18:20:21 -0300 | [diff] [blame] | 557 | return tda18271_write_regs(fe, R_EP3, 1); |
Michael Krufky | 518d873 | 2008-01-13 17:01:01 -0300 | [diff] [blame] | 558 | } |
| 559 | |
| 560 | /*---------------------------------------------------------------------*/ |
| 561 | |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 562 | int tda18271_calc_main_pll(struct dvb_frontend *fe, u32 freq) |
| 563 | { |
| 564 | /* sets main post divider & divider bytes, but does not write them */ |
| 565 | struct tda18271_priv *priv = fe->tuner_priv; |
| 566 | unsigned char *regs = priv->tda18271_regs; |
| 567 | u8 d, pd; |
| 568 | u32 div; |
| 569 | |
| 570 | int ret = tda18271_lookup_pll_map(fe, MAIN_PLL, &freq, &pd, &d); |
Michael Krufky | 4bd5d10 | 2008-05-04 21:32:21 -0300 | [diff] [blame] | 571 | if (tda_fail(ret)) |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 572 | goto fail; |
| 573 | |
Michael Krufky | 3f688e8 | 2011-04-16 13:22:10 -0300 | [diff] [blame] | 574 | regs[R_MPD] = (0x7f & pd); |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 575 | |
| 576 | div = ((d * (freq / 1000)) << 7) / 125; |
| 577 | |
| 578 | regs[R_MD1] = 0x7f & (div >> 16); |
| 579 | regs[R_MD2] = 0xff & (div >> 8); |
| 580 | regs[R_MD3] = 0xff & div; |
| 581 | fail: |
| 582 | return ret; |
| 583 | } |
| 584 | |
| 585 | int tda18271_calc_cal_pll(struct dvb_frontend *fe, u32 freq) |
| 586 | { |
| 587 | /* sets cal post divider & divider bytes, but does not write them */ |
| 588 | struct tda18271_priv *priv = fe->tuner_priv; |
| 589 | unsigned char *regs = priv->tda18271_regs; |
| 590 | u8 d, pd; |
| 591 | u32 div; |
| 592 | |
| 593 | int ret = tda18271_lookup_pll_map(fe, CAL_PLL, &freq, &pd, &d); |
Michael Krufky | 4bd5d10 | 2008-05-04 21:32:21 -0300 | [diff] [blame] | 594 | if (tda_fail(ret)) |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 595 | goto fail; |
| 596 | |
| 597 | regs[R_CPD] = pd; |
| 598 | |
| 599 | div = ((d * (freq / 1000)) << 7) / 125; |
| 600 | |
| 601 | regs[R_CD1] = 0x7f & (div >> 16); |
| 602 | regs[R_CD2] = 0xff & (div >> 8); |
| 603 | regs[R_CD3] = 0xff & div; |
| 604 | fail: |
| 605 | return ret; |
| 606 | } |
| 607 | |
| 608 | /*---------------------------------------------------------------------*/ |
| 609 | |
| 610 | int tda18271_calc_bp_filter(struct dvb_frontend *fe, u32 *freq) |
| 611 | { |
| 612 | /* sets bp filter bits, but does not write them */ |
| 613 | struct tda18271_priv *priv = fe->tuner_priv; |
| 614 | unsigned char *regs = priv->tda18271_regs; |
| 615 | u8 val; |
| 616 | |
| 617 | int ret = tda18271_lookup_map(fe, BP_FILTER, freq, &val); |
Michael Krufky | 4bd5d10 | 2008-05-04 21:32:21 -0300 | [diff] [blame] | 618 | if (tda_fail(ret)) |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 619 | goto fail; |
| 620 | |
| 621 | regs[R_EP1] &= ~0x07; /* clear bp filter bits */ |
| 622 | regs[R_EP1] |= (0x07 & val); |
| 623 | fail: |
| 624 | return ret; |
| 625 | } |
| 626 | |
| 627 | int tda18271_calc_km(struct dvb_frontend *fe, u32 *freq) |
| 628 | { |
| 629 | /* sets K & M bits, but does not write them */ |
| 630 | struct tda18271_priv *priv = fe->tuner_priv; |
| 631 | unsigned char *regs = priv->tda18271_regs; |
| 632 | u8 val; |
| 633 | |
| 634 | int ret = tda18271_lookup_map(fe, RF_CAL_KMCO, freq, &val); |
Michael Krufky | 4bd5d10 | 2008-05-04 21:32:21 -0300 | [diff] [blame] | 635 | if (tda_fail(ret)) |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 636 | goto fail; |
| 637 | |
| 638 | regs[R_EB13] &= ~0x7c; /* clear k & m bits */ |
| 639 | regs[R_EB13] |= (0x7c & val); |
| 640 | fail: |
| 641 | return ret; |
| 642 | } |
| 643 | |
| 644 | int tda18271_calc_rf_band(struct dvb_frontend *fe, u32 *freq) |
| 645 | { |
| 646 | /* sets rf band bits, but does not write them */ |
| 647 | struct tda18271_priv *priv = fe->tuner_priv; |
| 648 | unsigned char *regs = priv->tda18271_regs; |
| 649 | u8 val; |
| 650 | |
| 651 | int ret = tda18271_lookup_map(fe, RF_BAND, freq, &val); |
Michael Krufky | 4bd5d10 | 2008-05-04 21:32:21 -0300 | [diff] [blame] | 652 | if (tda_fail(ret)) |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 653 | goto fail; |
| 654 | |
| 655 | regs[R_EP2] &= ~0xe0; /* clear rf band bits */ |
| 656 | regs[R_EP2] |= (0xe0 & (val << 5)); |
| 657 | fail: |
| 658 | return ret; |
| 659 | } |
| 660 | |
| 661 | int tda18271_calc_gain_taper(struct dvb_frontend *fe, u32 *freq) |
| 662 | { |
| 663 | /* sets gain taper bits, but does not write them */ |
| 664 | struct tda18271_priv *priv = fe->tuner_priv; |
| 665 | unsigned char *regs = priv->tda18271_regs; |
| 666 | u8 val; |
| 667 | |
| 668 | int ret = tda18271_lookup_map(fe, GAIN_TAPER, freq, &val); |
Michael Krufky | 4bd5d10 | 2008-05-04 21:32:21 -0300 | [diff] [blame] | 669 | if (tda_fail(ret)) |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 670 | goto fail; |
| 671 | |
| 672 | regs[R_EP2] &= ~0x1f; /* clear gain taper bits */ |
| 673 | regs[R_EP2] |= (0x1f & val); |
| 674 | fail: |
| 675 | return ret; |
| 676 | } |
| 677 | |
| 678 | int tda18271_calc_ir_measure(struct dvb_frontend *fe, u32 *freq) |
| 679 | { |
| 680 | /* sets IR Meas bits, but does not write them */ |
| 681 | struct tda18271_priv *priv = fe->tuner_priv; |
| 682 | unsigned char *regs = priv->tda18271_regs; |
| 683 | u8 val; |
| 684 | |
| 685 | int ret = tda18271_lookup_map(fe, IR_MEASURE, freq, &val); |
Michael Krufky | 4bd5d10 | 2008-05-04 21:32:21 -0300 | [diff] [blame] | 686 | if (tda_fail(ret)) |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 687 | goto fail; |
| 688 | |
| 689 | regs[R_EP5] &= ~0x07; |
| 690 | regs[R_EP5] |= (0x07 & val); |
| 691 | fail: |
| 692 | return ret; |
| 693 | } |
| 694 | |
| 695 | int tda18271_calc_rf_cal(struct dvb_frontend *fe, u32 *freq) |
| 696 | { |
| 697 | /* sets rf cal byte (RFC_Cprog), but does not write it */ |
| 698 | struct tda18271_priv *priv = fe->tuner_priv; |
| 699 | unsigned char *regs = priv->tda18271_regs; |
| 700 | u8 val; |
| 701 | |
Michael Krufky | fc60d6e | 2008-05-31 18:18:55 -0300 | [diff] [blame] | 702 | int ret = tda18271_lookup_map(fe, RF_CAL, freq, &val); |
Michael Krufky | 119a7c7 | 2008-06-08 22:12:37 -0300 | [diff] [blame] | 703 | /* The TDA18271HD/C1 rf_cal map lookup is expected to go out of range |
| 704 | * for frequencies above 61.1 MHz. In these cases, the internal RF |
| 705 | * tracking filters calibration mechanism is used. |
| 706 | * |
| 707 | * There is no need to warn the user about this. |
| 708 | */ |
| 709 | if (ret < 0) |
| 710 | goto fail; |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 711 | |
| 712 | regs[R_EB14] = val; |
Michael Krufky | 119a7c7 | 2008-06-08 22:12:37 -0300 | [diff] [blame] | 713 | fail: |
Michael Krufky | fc60d6e | 2008-05-31 18:18:55 -0300 | [diff] [blame] | 714 | return ret; |
Michael Krufky | 59067f7 | 2008-01-02 01:58:26 -0300 | [diff] [blame] | 715 | } |
| 716 | |
Joe Perches | be85fef | 2011-07-31 01:37:10 -0300 | [diff] [blame] | 717 | int _tda_printk(struct tda18271_priv *state, const char *level, |
| 718 | const char *func, const char *fmt, ...) |
| 719 | { |
| 720 | struct va_format vaf; |
| 721 | va_list args; |
| 722 | int rtn; |
| 723 | |
| 724 | va_start(args, fmt); |
| 725 | |
| 726 | vaf.fmt = fmt; |
| 727 | vaf.va = &args; |
| 728 | |
| 729 | if (state) |
| 730 | rtn = printk("%s%s: [%d-%04x|%c] %pV", |
| 731 | level, func, i2c_adapter_id(state->i2c_props.adap), |
| 732 | state->i2c_props.addr, |
| 733 | (state->role == TDA18271_MASTER) ? 'M' : 'S', |
| 734 | &vaf); |
| 735 | else |
| 736 | rtn = printk("%s%s: %pV", level, func, &vaf); |
| 737 | |
| 738 | va_end(args); |
| 739 | |
| 740 | return rtn; |
| 741 | } |