162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci tda18271-common.c - driver for the Philips / NXP TDA18271 silicon tuner 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci Copyright (C) 2007, 2008 Michael Krufky <mkrufky@linuxtv.org> 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci*/ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include "tda18271-priv.h" 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_cistatic int tda18271_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) 1262306a36Sopenharmony_ci{ 1362306a36Sopenharmony_ci struct tda18271_priv *priv = fe->tuner_priv; 1462306a36Sopenharmony_ci enum tda18271_i2c_gate gate; 1562306a36Sopenharmony_ci int ret = 0; 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci switch (priv->gate) { 1862306a36Sopenharmony_ci case TDA18271_GATE_DIGITAL: 1962306a36Sopenharmony_ci case TDA18271_GATE_ANALOG: 2062306a36Sopenharmony_ci gate = priv->gate; 2162306a36Sopenharmony_ci break; 2262306a36Sopenharmony_ci case TDA18271_GATE_AUTO: 2362306a36Sopenharmony_ci default: 2462306a36Sopenharmony_ci switch (priv->mode) { 2562306a36Sopenharmony_ci case TDA18271_DIGITAL: 2662306a36Sopenharmony_ci gate = TDA18271_GATE_DIGITAL; 2762306a36Sopenharmony_ci break; 2862306a36Sopenharmony_ci case TDA18271_ANALOG: 2962306a36Sopenharmony_ci default: 3062306a36Sopenharmony_ci gate = TDA18271_GATE_ANALOG; 3162306a36Sopenharmony_ci break; 3262306a36Sopenharmony_ci } 3362306a36Sopenharmony_ci } 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci switch (gate) { 3662306a36Sopenharmony_ci case TDA18271_GATE_ANALOG: 3762306a36Sopenharmony_ci if (fe->ops.analog_ops.i2c_gate_ctrl) 3862306a36Sopenharmony_ci ret = fe->ops.analog_ops.i2c_gate_ctrl(fe, enable); 3962306a36Sopenharmony_ci break; 4062306a36Sopenharmony_ci case TDA18271_GATE_DIGITAL: 4162306a36Sopenharmony_ci if (fe->ops.i2c_gate_ctrl) 4262306a36Sopenharmony_ci ret = fe->ops.i2c_gate_ctrl(fe, enable); 4362306a36Sopenharmony_ci break; 4462306a36Sopenharmony_ci default: 4562306a36Sopenharmony_ci ret = -EINVAL; 4662306a36Sopenharmony_ci break; 4762306a36Sopenharmony_ci } 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci return ret; 5062306a36Sopenharmony_ci}; 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci/*---------------------------------------------------------------------*/ 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_cistatic void tda18271_dump_regs(struct dvb_frontend *fe, int extended) 5562306a36Sopenharmony_ci{ 5662306a36Sopenharmony_ci struct tda18271_priv *priv = fe->tuner_priv; 5762306a36Sopenharmony_ci unsigned char *regs = priv->tda18271_regs; 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci tda_reg("=== TDA18271 REG DUMP ===\n"); 6062306a36Sopenharmony_ci tda_reg("ID_BYTE = 0x%02x\n", 0xff & regs[R_ID]); 6162306a36Sopenharmony_ci tda_reg("THERMO_BYTE = 0x%02x\n", 0xff & regs[R_TM]); 6262306a36Sopenharmony_ci tda_reg("POWER_LEVEL_BYTE = 0x%02x\n", 0xff & regs[R_PL]); 6362306a36Sopenharmony_ci tda_reg("EASY_PROG_BYTE_1 = 0x%02x\n", 0xff & regs[R_EP1]); 6462306a36Sopenharmony_ci tda_reg("EASY_PROG_BYTE_2 = 0x%02x\n", 0xff & regs[R_EP2]); 6562306a36Sopenharmony_ci tda_reg("EASY_PROG_BYTE_3 = 0x%02x\n", 0xff & regs[R_EP3]); 6662306a36Sopenharmony_ci tda_reg("EASY_PROG_BYTE_4 = 0x%02x\n", 0xff & regs[R_EP4]); 6762306a36Sopenharmony_ci tda_reg("EASY_PROG_BYTE_5 = 0x%02x\n", 0xff & regs[R_EP5]); 6862306a36Sopenharmony_ci tda_reg("CAL_POST_DIV_BYTE = 0x%02x\n", 0xff & regs[R_CPD]); 6962306a36Sopenharmony_ci tda_reg("CAL_DIV_BYTE_1 = 0x%02x\n", 0xff & regs[R_CD1]); 7062306a36Sopenharmony_ci tda_reg("CAL_DIV_BYTE_2 = 0x%02x\n", 0xff & regs[R_CD2]); 7162306a36Sopenharmony_ci tda_reg("CAL_DIV_BYTE_3 = 0x%02x\n", 0xff & regs[R_CD3]); 7262306a36Sopenharmony_ci tda_reg("MAIN_POST_DIV_BYTE = 0x%02x\n", 0xff & regs[R_MPD]); 7362306a36Sopenharmony_ci tda_reg("MAIN_DIV_BYTE_1 = 0x%02x\n", 0xff & regs[R_MD1]); 7462306a36Sopenharmony_ci tda_reg("MAIN_DIV_BYTE_2 = 0x%02x\n", 0xff & regs[R_MD2]); 7562306a36Sopenharmony_ci tda_reg("MAIN_DIV_BYTE_3 = 0x%02x\n", 0xff & regs[R_MD3]); 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci /* only dump extended regs if DBG_ADV is set */ 7862306a36Sopenharmony_ci if (!(tda18271_debug & DBG_ADV)) 7962306a36Sopenharmony_ci return; 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci /* W indicates write-only registers. 8262306a36Sopenharmony_ci * Register dump for write-only registers shows last value written. */ 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci tda_reg("EXTENDED_BYTE_1 = 0x%02x\n", 0xff & regs[R_EB1]); 8562306a36Sopenharmony_ci tda_reg("EXTENDED_BYTE_2 = 0x%02x\n", 0xff & regs[R_EB2]); 8662306a36Sopenharmony_ci tda_reg("EXTENDED_BYTE_3 = 0x%02x\n", 0xff & regs[R_EB3]); 8762306a36Sopenharmony_ci tda_reg("EXTENDED_BYTE_4 = 0x%02x\n", 0xff & regs[R_EB4]); 8862306a36Sopenharmony_ci tda_reg("EXTENDED_BYTE_5 = 0x%02x\n", 0xff & regs[R_EB5]); 8962306a36Sopenharmony_ci tda_reg("EXTENDED_BYTE_6 = 0x%02x\n", 0xff & regs[R_EB6]); 9062306a36Sopenharmony_ci tda_reg("EXTENDED_BYTE_7 = 0x%02x\n", 0xff & regs[R_EB7]); 9162306a36Sopenharmony_ci tda_reg("EXTENDED_BYTE_8 = 0x%02x\n", 0xff & regs[R_EB8]); 9262306a36Sopenharmony_ci tda_reg("EXTENDED_BYTE_9 W = 0x%02x\n", 0xff & regs[R_EB9]); 9362306a36Sopenharmony_ci tda_reg("EXTENDED_BYTE_10 = 0x%02x\n", 0xff & regs[R_EB10]); 9462306a36Sopenharmony_ci tda_reg("EXTENDED_BYTE_11 = 0x%02x\n", 0xff & regs[R_EB11]); 9562306a36Sopenharmony_ci tda_reg("EXTENDED_BYTE_12 = 0x%02x\n", 0xff & regs[R_EB12]); 9662306a36Sopenharmony_ci tda_reg("EXTENDED_BYTE_13 = 0x%02x\n", 0xff & regs[R_EB13]); 9762306a36Sopenharmony_ci tda_reg("EXTENDED_BYTE_14 = 0x%02x\n", 0xff & regs[R_EB14]); 9862306a36Sopenharmony_ci tda_reg("EXTENDED_BYTE_15 = 0x%02x\n", 0xff & regs[R_EB15]); 9962306a36Sopenharmony_ci tda_reg("EXTENDED_BYTE_16 W = 0x%02x\n", 0xff & regs[R_EB16]); 10062306a36Sopenharmony_ci tda_reg("EXTENDED_BYTE_17 W = 0x%02x\n", 0xff & regs[R_EB17]); 10162306a36Sopenharmony_ci tda_reg("EXTENDED_BYTE_18 = 0x%02x\n", 0xff & regs[R_EB18]); 10262306a36Sopenharmony_ci tda_reg("EXTENDED_BYTE_19 W = 0x%02x\n", 0xff & regs[R_EB19]); 10362306a36Sopenharmony_ci tda_reg("EXTENDED_BYTE_20 W = 0x%02x\n", 0xff & regs[R_EB20]); 10462306a36Sopenharmony_ci tda_reg("EXTENDED_BYTE_21 = 0x%02x\n", 0xff & regs[R_EB21]); 10562306a36Sopenharmony_ci tda_reg("EXTENDED_BYTE_22 = 0x%02x\n", 0xff & regs[R_EB22]); 10662306a36Sopenharmony_ci tda_reg("EXTENDED_BYTE_23 = 0x%02x\n", 0xff & regs[R_EB23]); 10762306a36Sopenharmony_ci} 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ciint tda18271_read_regs(struct dvb_frontend *fe) 11062306a36Sopenharmony_ci{ 11162306a36Sopenharmony_ci struct tda18271_priv *priv = fe->tuner_priv; 11262306a36Sopenharmony_ci unsigned char *regs = priv->tda18271_regs; 11362306a36Sopenharmony_ci unsigned char buf = 0x00; 11462306a36Sopenharmony_ci int ret; 11562306a36Sopenharmony_ci struct i2c_msg msg[] = { 11662306a36Sopenharmony_ci { .addr = priv->i2c_props.addr, .flags = 0, 11762306a36Sopenharmony_ci .buf = &buf, .len = 1 }, 11862306a36Sopenharmony_ci { .addr = priv->i2c_props.addr, .flags = I2C_M_RD, 11962306a36Sopenharmony_ci .buf = regs, .len = 16 } 12062306a36Sopenharmony_ci }; 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci tda18271_i2c_gate_ctrl(fe, 1); 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci /* read all registers */ 12562306a36Sopenharmony_ci ret = i2c_transfer(priv->i2c_props.adap, msg, 2); 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci tda18271_i2c_gate_ctrl(fe, 0); 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci if (ret != 2) 13062306a36Sopenharmony_ci tda_err("ERROR: i2c_transfer returned: %d\n", ret); 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci if (tda18271_debug & DBG_REG) 13362306a36Sopenharmony_ci tda18271_dump_regs(fe, 0); 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci return (ret == 2 ? 0 : ret); 13662306a36Sopenharmony_ci} 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ciint tda18271_read_extended(struct dvb_frontend *fe) 13962306a36Sopenharmony_ci{ 14062306a36Sopenharmony_ci struct tda18271_priv *priv = fe->tuner_priv; 14162306a36Sopenharmony_ci unsigned char *regs = priv->tda18271_regs; 14262306a36Sopenharmony_ci unsigned char regdump[TDA18271_NUM_REGS]; 14362306a36Sopenharmony_ci unsigned char buf = 0x00; 14462306a36Sopenharmony_ci int ret, i; 14562306a36Sopenharmony_ci struct i2c_msg msg[] = { 14662306a36Sopenharmony_ci { .addr = priv->i2c_props.addr, .flags = 0, 14762306a36Sopenharmony_ci .buf = &buf, .len = 1 }, 14862306a36Sopenharmony_ci { .addr = priv->i2c_props.addr, .flags = I2C_M_RD, 14962306a36Sopenharmony_ci .buf = regdump, .len = TDA18271_NUM_REGS } 15062306a36Sopenharmony_ci }; 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci tda18271_i2c_gate_ctrl(fe, 1); 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci /* read all registers */ 15562306a36Sopenharmony_ci ret = i2c_transfer(priv->i2c_props.adap, msg, 2); 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci tda18271_i2c_gate_ctrl(fe, 0); 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci if (ret != 2) 16062306a36Sopenharmony_ci tda_err("ERROR: i2c_transfer returned: %d\n", ret); 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci for (i = 0; i < TDA18271_NUM_REGS; i++) { 16362306a36Sopenharmony_ci /* don't update write-only registers */ 16462306a36Sopenharmony_ci if ((i != R_EB9) && 16562306a36Sopenharmony_ci (i != R_EB16) && 16662306a36Sopenharmony_ci (i != R_EB17) && 16762306a36Sopenharmony_ci (i != R_EB19) && 16862306a36Sopenharmony_ci (i != R_EB20)) 16962306a36Sopenharmony_ci regs[i] = regdump[i]; 17062306a36Sopenharmony_ci } 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci if (tda18271_debug & DBG_REG) 17362306a36Sopenharmony_ci tda18271_dump_regs(fe, 1); 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci return (ret == 2 ? 0 : ret); 17662306a36Sopenharmony_ci} 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_cistatic int __tda18271_write_regs(struct dvb_frontend *fe, int idx, int len, 17962306a36Sopenharmony_ci bool lock_i2c) 18062306a36Sopenharmony_ci{ 18162306a36Sopenharmony_ci struct tda18271_priv *priv = fe->tuner_priv; 18262306a36Sopenharmony_ci unsigned char *regs = priv->tda18271_regs; 18362306a36Sopenharmony_ci unsigned char buf[TDA18271_NUM_REGS + 1]; 18462306a36Sopenharmony_ci struct i2c_msg msg = { .addr = priv->i2c_props.addr, .flags = 0, 18562306a36Sopenharmony_ci .buf = buf }; 18662306a36Sopenharmony_ci int i, ret = 1, max; 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ci BUG_ON((len == 0) || (idx + len > sizeof(buf))); 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci switch (priv->small_i2c) { 19162306a36Sopenharmony_ci case TDA18271_03_BYTE_CHUNK_INIT: 19262306a36Sopenharmony_ci max = 3; 19362306a36Sopenharmony_ci break; 19462306a36Sopenharmony_ci case TDA18271_08_BYTE_CHUNK_INIT: 19562306a36Sopenharmony_ci max = 8; 19662306a36Sopenharmony_ci break; 19762306a36Sopenharmony_ci case TDA18271_16_BYTE_CHUNK_INIT: 19862306a36Sopenharmony_ci max = 16; 19962306a36Sopenharmony_ci break; 20062306a36Sopenharmony_ci case TDA18271_39_BYTE_CHUNK_INIT: 20162306a36Sopenharmony_ci default: 20262306a36Sopenharmony_ci max = 39; 20362306a36Sopenharmony_ci } 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ci /* 20762306a36Sopenharmony_ci * If lock_i2c is true, it will take the I2C bus for tda18271 private 20862306a36Sopenharmony_ci * usage during the entire write ops, as otherwise, bad things could 20962306a36Sopenharmony_ci * happen. 21062306a36Sopenharmony_ci * During device init, several write operations will happen. So, 21162306a36Sopenharmony_ci * tda18271_init_regs controls the I2C lock directly, 21262306a36Sopenharmony_ci * disabling lock_i2c here. 21362306a36Sopenharmony_ci */ 21462306a36Sopenharmony_ci if (lock_i2c) { 21562306a36Sopenharmony_ci tda18271_i2c_gate_ctrl(fe, 1); 21662306a36Sopenharmony_ci i2c_lock_bus(priv->i2c_props.adap, I2C_LOCK_SEGMENT); 21762306a36Sopenharmony_ci } 21862306a36Sopenharmony_ci while (len) { 21962306a36Sopenharmony_ci if (max > len) 22062306a36Sopenharmony_ci max = len; 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ci buf[0] = idx; 22362306a36Sopenharmony_ci for (i = 1; i <= max; i++) 22462306a36Sopenharmony_ci buf[i] = regs[idx - 1 + i]; 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci msg.len = max + 1; 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ci /* write registers */ 22962306a36Sopenharmony_ci ret = __i2c_transfer(priv->i2c_props.adap, &msg, 1); 23062306a36Sopenharmony_ci if (ret != 1) 23162306a36Sopenharmony_ci break; 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_ci idx += max; 23462306a36Sopenharmony_ci len -= max; 23562306a36Sopenharmony_ci } 23662306a36Sopenharmony_ci if (lock_i2c) { 23762306a36Sopenharmony_ci i2c_unlock_bus(priv->i2c_props.adap, I2C_LOCK_SEGMENT); 23862306a36Sopenharmony_ci tda18271_i2c_gate_ctrl(fe, 0); 23962306a36Sopenharmony_ci } 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ci if (ret != 1) 24262306a36Sopenharmony_ci tda_err("ERROR: idx = 0x%x, len = %d, i2c_transfer returned: %d\n", 24362306a36Sopenharmony_ci idx, max, ret); 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_ci return (ret == 1 ? 0 : ret); 24662306a36Sopenharmony_ci} 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ciint tda18271_write_regs(struct dvb_frontend *fe, int idx, int len) 24962306a36Sopenharmony_ci{ 25062306a36Sopenharmony_ci return __tda18271_write_regs(fe, idx, len, true); 25162306a36Sopenharmony_ci} 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci/*---------------------------------------------------------------------*/ 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_cistatic int __tda18271_charge_pump_source(struct dvb_frontend *fe, 25662306a36Sopenharmony_ci enum tda18271_pll pll, int force, 25762306a36Sopenharmony_ci bool lock_i2c) 25862306a36Sopenharmony_ci{ 25962306a36Sopenharmony_ci struct tda18271_priv *priv = fe->tuner_priv; 26062306a36Sopenharmony_ci unsigned char *regs = priv->tda18271_regs; 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ci int r_cp = (pll == TDA18271_CAL_PLL) ? R_EB7 : R_EB4; 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_ci regs[r_cp] &= ~0x20; 26562306a36Sopenharmony_ci regs[r_cp] |= ((force & 1) << 5); 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci return __tda18271_write_regs(fe, r_cp, 1, lock_i2c); 26862306a36Sopenharmony_ci} 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ciint tda18271_charge_pump_source(struct dvb_frontend *fe, 27162306a36Sopenharmony_ci enum tda18271_pll pll, int force) 27262306a36Sopenharmony_ci{ 27362306a36Sopenharmony_ci return __tda18271_charge_pump_source(fe, pll, force, true); 27462306a36Sopenharmony_ci} 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ciint tda18271_init_regs(struct dvb_frontend *fe) 27862306a36Sopenharmony_ci{ 27962306a36Sopenharmony_ci struct tda18271_priv *priv = fe->tuner_priv; 28062306a36Sopenharmony_ci unsigned char *regs = priv->tda18271_regs; 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ci tda_dbg("initializing registers for device @ %d-%04x\n", 28362306a36Sopenharmony_ci i2c_adapter_id(priv->i2c_props.adap), 28462306a36Sopenharmony_ci priv->i2c_props.addr); 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci /* 28762306a36Sopenharmony_ci * Don't let any other I2C transfer to happen at adapter during init, 28862306a36Sopenharmony_ci * as those could cause bad things 28962306a36Sopenharmony_ci */ 29062306a36Sopenharmony_ci tda18271_i2c_gate_ctrl(fe, 1); 29162306a36Sopenharmony_ci i2c_lock_bus(priv->i2c_props.adap, I2C_LOCK_SEGMENT); 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci /* initialize registers */ 29462306a36Sopenharmony_ci switch (priv->id) { 29562306a36Sopenharmony_ci case TDA18271HDC1: 29662306a36Sopenharmony_ci regs[R_ID] = 0x83; 29762306a36Sopenharmony_ci break; 29862306a36Sopenharmony_ci case TDA18271HDC2: 29962306a36Sopenharmony_ci regs[R_ID] = 0x84; 30062306a36Sopenharmony_ci break; 30162306a36Sopenharmony_ci } 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_ci regs[R_TM] = 0x08; 30462306a36Sopenharmony_ci regs[R_PL] = 0x80; 30562306a36Sopenharmony_ci regs[R_EP1] = 0xc6; 30662306a36Sopenharmony_ci regs[R_EP2] = 0xdf; 30762306a36Sopenharmony_ci regs[R_EP3] = 0x16; 30862306a36Sopenharmony_ci regs[R_EP4] = 0x60; 30962306a36Sopenharmony_ci regs[R_EP5] = 0x80; 31062306a36Sopenharmony_ci regs[R_CPD] = 0x80; 31162306a36Sopenharmony_ci regs[R_CD1] = 0x00; 31262306a36Sopenharmony_ci regs[R_CD2] = 0x00; 31362306a36Sopenharmony_ci regs[R_CD3] = 0x00; 31462306a36Sopenharmony_ci regs[R_MPD] = 0x00; 31562306a36Sopenharmony_ci regs[R_MD1] = 0x00; 31662306a36Sopenharmony_ci regs[R_MD2] = 0x00; 31762306a36Sopenharmony_ci regs[R_MD3] = 0x00; 31862306a36Sopenharmony_ci 31962306a36Sopenharmony_ci switch (priv->id) { 32062306a36Sopenharmony_ci case TDA18271HDC1: 32162306a36Sopenharmony_ci regs[R_EB1] = 0xff; 32262306a36Sopenharmony_ci break; 32362306a36Sopenharmony_ci case TDA18271HDC2: 32462306a36Sopenharmony_ci regs[R_EB1] = 0xfc; 32562306a36Sopenharmony_ci break; 32662306a36Sopenharmony_ci } 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_ci regs[R_EB2] = 0x01; 32962306a36Sopenharmony_ci regs[R_EB3] = 0x84; 33062306a36Sopenharmony_ci regs[R_EB4] = 0x41; 33162306a36Sopenharmony_ci regs[R_EB5] = 0x01; 33262306a36Sopenharmony_ci regs[R_EB6] = 0x84; 33362306a36Sopenharmony_ci regs[R_EB7] = 0x40; 33462306a36Sopenharmony_ci regs[R_EB8] = 0x07; 33562306a36Sopenharmony_ci regs[R_EB9] = 0x00; 33662306a36Sopenharmony_ci regs[R_EB10] = 0x00; 33762306a36Sopenharmony_ci regs[R_EB11] = 0x96; 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_ci switch (priv->id) { 34062306a36Sopenharmony_ci case TDA18271HDC1: 34162306a36Sopenharmony_ci regs[R_EB12] = 0x0f; 34262306a36Sopenharmony_ci break; 34362306a36Sopenharmony_ci case TDA18271HDC2: 34462306a36Sopenharmony_ci regs[R_EB12] = 0x33; 34562306a36Sopenharmony_ci break; 34662306a36Sopenharmony_ci } 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci regs[R_EB13] = 0xc1; 34962306a36Sopenharmony_ci regs[R_EB14] = 0x00; 35062306a36Sopenharmony_ci regs[R_EB15] = 0x8f; 35162306a36Sopenharmony_ci regs[R_EB16] = 0x00; 35262306a36Sopenharmony_ci regs[R_EB17] = 0x00; 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_ci switch (priv->id) { 35562306a36Sopenharmony_ci case TDA18271HDC1: 35662306a36Sopenharmony_ci regs[R_EB18] = 0x00; 35762306a36Sopenharmony_ci break; 35862306a36Sopenharmony_ci case TDA18271HDC2: 35962306a36Sopenharmony_ci regs[R_EB18] = 0x8c; 36062306a36Sopenharmony_ci break; 36162306a36Sopenharmony_ci } 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_ci regs[R_EB19] = 0x00; 36462306a36Sopenharmony_ci regs[R_EB20] = 0x20; 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci switch (priv->id) { 36762306a36Sopenharmony_ci case TDA18271HDC1: 36862306a36Sopenharmony_ci regs[R_EB21] = 0x33; 36962306a36Sopenharmony_ci break; 37062306a36Sopenharmony_ci case TDA18271HDC2: 37162306a36Sopenharmony_ci regs[R_EB21] = 0xb3; 37262306a36Sopenharmony_ci break; 37362306a36Sopenharmony_ci } 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_ci regs[R_EB22] = 0x48; 37662306a36Sopenharmony_ci regs[R_EB23] = 0xb0; 37762306a36Sopenharmony_ci 37862306a36Sopenharmony_ci __tda18271_write_regs(fe, 0x00, TDA18271_NUM_REGS, false); 37962306a36Sopenharmony_ci 38062306a36Sopenharmony_ci /* setup agc1 gain */ 38162306a36Sopenharmony_ci regs[R_EB17] = 0x00; 38262306a36Sopenharmony_ci __tda18271_write_regs(fe, R_EB17, 1, false); 38362306a36Sopenharmony_ci regs[R_EB17] = 0x03; 38462306a36Sopenharmony_ci __tda18271_write_regs(fe, R_EB17, 1, false); 38562306a36Sopenharmony_ci regs[R_EB17] = 0x43; 38662306a36Sopenharmony_ci __tda18271_write_regs(fe, R_EB17, 1, false); 38762306a36Sopenharmony_ci regs[R_EB17] = 0x4c; 38862306a36Sopenharmony_ci __tda18271_write_regs(fe, R_EB17, 1, false); 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_ci /* setup agc2 gain */ 39162306a36Sopenharmony_ci if ((priv->id) == TDA18271HDC1) { 39262306a36Sopenharmony_ci regs[R_EB20] = 0xa0; 39362306a36Sopenharmony_ci __tda18271_write_regs(fe, R_EB20, 1, false); 39462306a36Sopenharmony_ci regs[R_EB20] = 0xa7; 39562306a36Sopenharmony_ci __tda18271_write_regs(fe, R_EB20, 1, false); 39662306a36Sopenharmony_ci regs[R_EB20] = 0xe7; 39762306a36Sopenharmony_ci __tda18271_write_regs(fe, R_EB20, 1, false); 39862306a36Sopenharmony_ci regs[R_EB20] = 0xec; 39962306a36Sopenharmony_ci __tda18271_write_regs(fe, R_EB20, 1, false); 40062306a36Sopenharmony_ci } 40162306a36Sopenharmony_ci 40262306a36Sopenharmony_ci /* image rejection calibration */ 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_ci /* low-band */ 40562306a36Sopenharmony_ci regs[R_EP3] = 0x1f; 40662306a36Sopenharmony_ci regs[R_EP4] = 0x66; 40762306a36Sopenharmony_ci regs[R_EP5] = 0x81; 40862306a36Sopenharmony_ci regs[R_CPD] = 0xcc; 40962306a36Sopenharmony_ci regs[R_CD1] = 0x6c; 41062306a36Sopenharmony_ci regs[R_CD2] = 0x00; 41162306a36Sopenharmony_ci regs[R_CD3] = 0x00; 41262306a36Sopenharmony_ci regs[R_MPD] = 0xcd; 41362306a36Sopenharmony_ci regs[R_MD1] = 0x77; 41462306a36Sopenharmony_ci regs[R_MD2] = 0x08; 41562306a36Sopenharmony_ci regs[R_MD3] = 0x00; 41662306a36Sopenharmony_ci 41762306a36Sopenharmony_ci __tda18271_write_regs(fe, R_EP3, 11, false); 41862306a36Sopenharmony_ci 41962306a36Sopenharmony_ci if ((priv->id) == TDA18271HDC2) { 42062306a36Sopenharmony_ci /* main pll cp source on */ 42162306a36Sopenharmony_ci __tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 1, false); 42262306a36Sopenharmony_ci msleep(1); 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_ci /* main pll cp source off */ 42562306a36Sopenharmony_ci __tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 0, false); 42662306a36Sopenharmony_ci } 42762306a36Sopenharmony_ci 42862306a36Sopenharmony_ci msleep(5); /* pll locking */ 42962306a36Sopenharmony_ci 43062306a36Sopenharmony_ci /* launch detector */ 43162306a36Sopenharmony_ci __tda18271_write_regs(fe, R_EP1, 1, false); 43262306a36Sopenharmony_ci msleep(5); /* wanted low measurement */ 43362306a36Sopenharmony_ci 43462306a36Sopenharmony_ci regs[R_EP5] = 0x85; 43562306a36Sopenharmony_ci regs[R_CPD] = 0xcb; 43662306a36Sopenharmony_ci regs[R_CD1] = 0x66; 43762306a36Sopenharmony_ci regs[R_CD2] = 0x70; 43862306a36Sopenharmony_ci 43962306a36Sopenharmony_ci __tda18271_write_regs(fe, R_EP3, 7, false); 44062306a36Sopenharmony_ci msleep(5); /* pll locking */ 44162306a36Sopenharmony_ci 44262306a36Sopenharmony_ci /* launch optimization algorithm */ 44362306a36Sopenharmony_ci __tda18271_write_regs(fe, R_EP2, 1, false); 44462306a36Sopenharmony_ci msleep(30); /* image low optimization completion */ 44562306a36Sopenharmony_ci 44662306a36Sopenharmony_ci /* mid-band */ 44762306a36Sopenharmony_ci regs[R_EP5] = 0x82; 44862306a36Sopenharmony_ci regs[R_CPD] = 0xa8; 44962306a36Sopenharmony_ci regs[R_CD2] = 0x00; 45062306a36Sopenharmony_ci regs[R_MPD] = 0xa9; 45162306a36Sopenharmony_ci regs[R_MD1] = 0x73; 45262306a36Sopenharmony_ci regs[R_MD2] = 0x1a; 45362306a36Sopenharmony_ci 45462306a36Sopenharmony_ci __tda18271_write_regs(fe, R_EP3, 11, false); 45562306a36Sopenharmony_ci msleep(5); /* pll locking */ 45662306a36Sopenharmony_ci 45762306a36Sopenharmony_ci /* launch detector */ 45862306a36Sopenharmony_ci __tda18271_write_regs(fe, R_EP1, 1, false); 45962306a36Sopenharmony_ci msleep(5); /* wanted mid measurement */ 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_ci regs[R_EP5] = 0x86; 46262306a36Sopenharmony_ci regs[R_CPD] = 0xa8; 46362306a36Sopenharmony_ci regs[R_CD1] = 0x66; 46462306a36Sopenharmony_ci regs[R_CD2] = 0xa0; 46562306a36Sopenharmony_ci 46662306a36Sopenharmony_ci __tda18271_write_regs(fe, R_EP3, 7, false); 46762306a36Sopenharmony_ci msleep(5); /* pll locking */ 46862306a36Sopenharmony_ci 46962306a36Sopenharmony_ci /* launch optimization algorithm */ 47062306a36Sopenharmony_ci __tda18271_write_regs(fe, R_EP2, 1, false); 47162306a36Sopenharmony_ci msleep(30); /* image mid optimization completion */ 47262306a36Sopenharmony_ci 47362306a36Sopenharmony_ci /* high-band */ 47462306a36Sopenharmony_ci regs[R_EP5] = 0x83; 47562306a36Sopenharmony_ci regs[R_CPD] = 0x98; 47662306a36Sopenharmony_ci regs[R_CD1] = 0x65; 47762306a36Sopenharmony_ci regs[R_CD2] = 0x00; 47862306a36Sopenharmony_ci regs[R_MPD] = 0x99; 47962306a36Sopenharmony_ci regs[R_MD1] = 0x71; 48062306a36Sopenharmony_ci regs[R_MD2] = 0xcd; 48162306a36Sopenharmony_ci 48262306a36Sopenharmony_ci __tda18271_write_regs(fe, R_EP3, 11, false); 48362306a36Sopenharmony_ci msleep(5); /* pll locking */ 48462306a36Sopenharmony_ci 48562306a36Sopenharmony_ci /* launch detector */ 48662306a36Sopenharmony_ci __tda18271_write_regs(fe, R_EP1, 1, false); 48762306a36Sopenharmony_ci msleep(5); /* wanted high measurement */ 48862306a36Sopenharmony_ci 48962306a36Sopenharmony_ci regs[R_EP5] = 0x87; 49062306a36Sopenharmony_ci regs[R_CD1] = 0x65; 49162306a36Sopenharmony_ci regs[R_CD2] = 0x50; 49262306a36Sopenharmony_ci 49362306a36Sopenharmony_ci __tda18271_write_regs(fe, R_EP3, 7, false); 49462306a36Sopenharmony_ci msleep(5); /* pll locking */ 49562306a36Sopenharmony_ci 49662306a36Sopenharmony_ci /* launch optimization algorithm */ 49762306a36Sopenharmony_ci __tda18271_write_regs(fe, R_EP2, 1, false); 49862306a36Sopenharmony_ci msleep(30); /* image high optimization completion */ 49962306a36Sopenharmony_ci 50062306a36Sopenharmony_ci /* return to normal mode */ 50162306a36Sopenharmony_ci regs[R_EP4] = 0x64; 50262306a36Sopenharmony_ci __tda18271_write_regs(fe, R_EP4, 1, false); 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_ci /* synchronize */ 50562306a36Sopenharmony_ci __tda18271_write_regs(fe, R_EP1, 1, false); 50662306a36Sopenharmony_ci 50762306a36Sopenharmony_ci i2c_unlock_bus(priv->i2c_props.adap, I2C_LOCK_SEGMENT); 50862306a36Sopenharmony_ci tda18271_i2c_gate_ctrl(fe, 0); 50962306a36Sopenharmony_ci 51062306a36Sopenharmony_ci return 0; 51162306a36Sopenharmony_ci} 51262306a36Sopenharmony_ci 51362306a36Sopenharmony_ci/*---------------------------------------------------------------------*/ 51462306a36Sopenharmony_ci 51562306a36Sopenharmony_ci/* 51662306a36Sopenharmony_ci * Standby modes, EP3 [7:5] 51762306a36Sopenharmony_ci * 51862306a36Sopenharmony_ci * | SM || SM_LT || SM_XT || mode description 51962306a36Sopenharmony_ci * |=====\\=======\\=======\\==================================== 52062306a36Sopenharmony_ci * | 0 || 0 || 0 || normal mode 52162306a36Sopenharmony_ci * |-----||-------||-------||------------------------------------ 52262306a36Sopenharmony_ci * | || || || standby mode w/ slave tuner output 52362306a36Sopenharmony_ci * | 1 || 0 || 0 || & loop through & xtal oscillator on 52462306a36Sopenharmony_ci * |-----||-------||-------||------------------------------------ 52562306a36Sopenharmony_ci * | 1 || 1 || 0 || standby mode w/ xtal oscillator on 52662306a36Sopenharmony_ci * |-----||-------||-------||------------------------------------ 52762306a36Sopenharmony_ci * | 1 || 1 || 1 || power off 52862306a36Sopenharmony_ci * 52962306a36Sopenharmony_ci */ 53062306a36Sopenharmony_ci 53162306a36Sopenharmony_ciint tda18271_set_standby_mode(struct dvb_frontend *fe, 53262306a36Sopenharmony_ci int sm, int sm_lt, int sm_xt) 53362306a36Sopenharmony_ci{ 53462306a36Sopenharmony_ci struct tda18271_priv *priv = fe->tuner_priv; 53562306a36Sopenharmony_ci unsigned char *regs = priv->tda18271_regs; 53662306a36Sopenharmony_ci 53762306a36Sopenharmony_ci if (tda18271_debug & DBG_ADV) 53862306a36Sopenharmony_ci tda_dbg("sm = %d, sm_lt = %d, sm_xt = %d\n", sm, sm_lt, sm_xt); 53962306a36Sopenharmony_ci 54062306a36Sopenharmony_ci regs[R_EP3] &= ~0xe0; /* clear sm, sm_lt, sm_xt */ 54162306a36Sopenharmony_ci regs[R_EP3] |= (sm ? (1 << 7) : 0) | 54262306a36Sopenharmony_ci (sm_lt ? (1 << 6) : 0) | 54362306a36Sopenharmony_ci (sm_xt ? (1 << 5) : 0); 54462306a36Sopenharmony_ci 54562306a36Sopenharmony_ci return tda18271_write_regs(fe, R_EP3, 1); 54662306a36Sopenharmony_ci} 54762306a36Sopenharmony_ci 54862306a36Sopenharmony_ci/*---------------------------------------------------------------------*/ 54962306a36Sopenharmony_ci 55062306a36Sopenharmony_ciint tda18271_calc_main_pll(struct dvb_frontend *fe, u32 freq) 55162306a36Sopenharmony_ci{ 55262306a36Sopenharmony_ci /* sets main post divider & divider bytes, but does not write them */ 55362306a36Sopenharmony_ci struct tda18271_priv *priv = fe->tuner_priv; 55462306a36Sopenharmony_ci unsigned char *regs = priv->tda18271_regs; 55562306a36Sopenharmony_ci u8 d, pd; 55662306a36Sopenharmony_ci u32 div; 55762306a36Sopenharmony_ci 55862306a36Sopenharmony_ci int ret = tda18271_lookup_pll_map(fe, MAIN_PLL, &freq, &pd, &d); 55962306a36Sopenharmony_ci if (tda_fail(ret)) 56062306a36Sopenharmony_ci goto fail; 56162306a36Sopenharmony_ci 56262306a36Sopenharmony_ci regs[R_MPD] = (0x7f & pd); 56362306a36Sopenharmony_ci 56462306a36Sopenharmony_ci div = ((d * (freq / 1000)) << 7) / 125; 56562306a36Sopenharmony_ci 56662306a36Sopenharmony_ci regs[R_MD1] = 0x7f & (div >> 16); 56762306a36Sopenharmony_ci regs[R_MD2] = 0xff & (div >> 8); 56862306a36Sopenharmony_ci regs[R_MD3] = 0xff & div; 56962306a36Sopenharmony_cifail: 57062306a36Sopenharmony_ci return ret; 57162306a36Sopenharmony_ci} 57262306a36Sopenharmony_ci 57362306a36Sopenharmony_ciint tda18271_calc_cal_pll(struct dvb_frontend *fe, u32 freq) 57462306a36Sopenharmony_ci{ 57562306a36Sopenharmony_ci /* sets cal post divider & divider bytes, but does not write them */ 57662306a36Sopenharmony_ci struct tda18271_priv *priv = fe->tuner_priv; 57762306a36Sopenharmony_ci unsigned char *regs = priv->tda18271_regs; 57862306a36Sopenharmony_ci u8 d, pd; 57962306a36Sopenharmony_ci u32 div; 58062306a36Sopenharmony_ci 58162306a36Sopenharmony_ci int ret = tda18271_lookup_pll_map(fe, CAL_PLL, &freq, &pd, &d); 58262306a36Sopenharmony_ci if (tda_fail(ret)) 58362306a36Sopenharmony_ci goto fail; 58462306a36Sopenharmony_ci 58562306a36Sopenharmony_ci regs[R_CPD] = pd; 58662306a36Sopenharmony_ci 58762306a36Sopenharmony_ci div = ((d * (freq / 1000)) << 7) / 125; 58862306a36Sopenharmony_ci 58962306a36Sopenharmony_ci regs[R_CD1] = 0x7f & (div >> 16); 59062306a36Sopenharmony_ci regs[R_CD2] = 0xff & (div >> 8); 59162306a36Sopenharmony_ci regs[R_CD3] = 0xff & div; 59262306a36Sopenharmony_cifail: 59362306a36Sopenharmony_ci return ret; 59462306a36Sopenharmony_ci} 59562306a36Sopenharmony_ci 59662306a36Sopenharmony_ci/*---------------------------------------------------------------------*/ 59762306a36Sopenharmony_ci 59862306a36Sopenharmony_ciint tda18271_calc_bp_filter(struct dvb_frontend *fe, u32 *freq) 59962306a36Sopenharmony_ci{ 60062306a36Sopenharmony_ci /* sets bp filter bits, but does not write them */ 60162306a36Sopenharmony_ci struct tda18271_priv *priv = fe->tuner_priv; 60262306a36Sopenharmony_ci unsigned char *regs = priv->tda18271_regs; 60362306a36Sopenharmony_ci u8 val; 60462306a36Sopenharmony_ci 60562306a36Sopenharmony_ci int ret = tda18271_lookup_map(fe, BP_FILTER, freq, &val); 60662306a36Sopenharmony_ci if (tda_fail(ret)) 60762306a36Sopenharmony_ci goto fail; 60862306a36Sopenharmony_ci 60962306a36Sopenharmony_ci regs[R_EP1] &= ~0x07; /* clear bp filter bits */ 61062306a36Sopenharmony_ci regs[R_EP1] |= (0x07 & val); 61162306a36Sopenharmony_cifail: 61262306a36Sopenharmony_ci return ret; 61362306a36Sopenharmony_ci} 61462306a36Sopenharmony_ci 61562306a36Sopenharmony_ciint tda18271_calc_km(struct dvb_frontend *fe, u32 *freq) 61662306a36Sopenharmony_ci{ 61762306a36Sopenharmony_ci /* sets K & M bits, but does not write them */ 61862306a36Sopenharmony_ci struct tda18271_priv *priv = fe->tuner_priv; 61962306a36Sopenharmony_ci unsigned char *regs = priv->tda18271_regs; 62062306a36Sopenharmony_ci u8 val; 62162306a36Sopenharmony_ci 62262306a36Sopenharmony_ci int ret = tda18271_lookup_map(fe, RF_CAL_KMCO, freq, &val); 62362306a36Sopenharmony_ci if (tda_fail(ret)) 62462306a36Sopenharmony_ci goto fail; 62562306a36Sopenharmony_ci 62662306a36Sopenharmony_ci regs[R_EB13] &= ~0x7c; /* clear k & m bits */ 62762306a36Sopenharmony_ci regs[R_EB13] |= (0x7c & val); 62862306a36Sopenharmony_cifail: 62962306a36Sopenharmony_ci return ret; 63062306a36Sopenharmony_ci} 63162306a36Sopenharmony_ci 63262306a36Sopenharmony_ciint tda18271_calc_rf_band(struct dvb_frontend *fe, u32 *freq) 63362306a36Sopenharmony_ci{ 63462306a36Sopenharmony_ci /* sets rf band bits, but does not write them */ 63562306a36Sopenharmony_ci struct tda18271_priv *priv = fe->tuner_priv; 63662306a36Sopenharmony_ci unsigned char *regs = priv->tda18271_regs; 63762306a36Sopenharmony_ci u8 val; 63862306a36Sopenharmony_ci 63962306a36Sopenharmony_ci int ret = tda18271_lookup_map(fe, RF_BAND, freq, &val); 64062306a36Sopenharmony_ci if (tda_fail(ret)) 64162306a36Sopenharmony_ci goto fail; 64262306a36Sopenharmony_ci 64362306a36Sopenharmony_ci regs[R_EP2] &= ~0xe0; /* clear rf band bits */ 64462306a36Sopenharmony_ci regs[R_EP2] |= (0xe0 & (val << 5)); 64562306a36Sopenharmony_cifail: 64662306a36Sopenharmony_ci return ret; 64762306a36Sopenharmony_ci} 64862306a36Sopenharmony_ci 64962306a36Sopenharmony_ciint tda18271_calc_gain_taper(struct dvb_frontend *fe, u32 *freq) 65062306a36Sopenharmony_ci{ 65162306a36Sopenharmony_ci /* sets gain taper bits, but does not write them */ 65262306a36Sopenharmony_ci struct tda18271_priv *priv = fe->tuner_priv; 65362306a36Sopenharmony_ci unsigned char *regs = priv->tda18271_regs; 65462306a36Sopenharmony_ci u8 val; 65562306a36Sopenharmony_ci 65662306a36Sopenharmony_ci int ret = tda18271_lookup_map(fe, GAIN_TAPER, freq, &val); 65762306a36Sopenharmony_ci if (tda_fail(ret)) 65862306a36Sopenharmony_ci goto fail; 65962306a36Sopenharmony_ci 66062306a36Sopenharmony_ci regs[R_EP2] &= ~0x1f; /* clear gain taper bits */ 66162306a36Sopenharmony_ci regs[R_EP2] |= (0x1f & val); 66262306a36Sopenharmony_cifail: 66362306a36Sopenharmony_ci return ret; 66462306a36Sopenharmony_ci} 66562306a36Sopenharmony_ci 66662306a36Sopenharmony_ciint tda18271_calc_ir_measure(struct dvb_frontend *fe, u32 *freq) 66762306a36Sopenharmony_ci{ 66862306a36Sopenharmony_ci /* sets IR Meas bits, but does not write them */ 66962306a36Sopenharmony_ci struct tda18271_priv *priv = fe->tuner_priv; 67062306a36Sopenharmony_ci unsigned char *regs = priv->tda18271_regs; 67162306a36Sopenharmony_ci u8 val; 67262306a36Sopenharmony_ci 67362306a36Sopenharmony_ci int ret = tda18271_lookup_map(fe, IR_MEASURE, freq, &val); 67462306a36Sopenharmony_ci if (tda_fail(ret)) 67562306a36Sopenharmony_ci goto fail; 67662306a36Sopenharmony_ci 67762306a36Sopenharmony_ci regs[R_EP5] &= ~0x07; 67862306a36Sopenharmony_ci regs[R_EP5] |= (0x07 & val); 67962306a36Sopenharmony_cifail: 68062306a36Sopenharmony_ci return ret; 68162306a36Sopenharmony_ci} 68262306a36Sopenharmony_ci 68362306a36Sopenharmony_ciint tda18271_calc_rf_cal(struct dvb_frontend *fe, u32 *freq) 68462306a36Sopenharmony_ci{ 68562306a36Sopenharmony_ci /* sets rf cal byte (RFC_Cprog), but does not write it */ 68662306a36Sopenharmony_ci struct tda18271_priv *priv = fe->tuner_priv; 68762306a36Sopenharmony_ci unsigned char *regs = priv->tda18271_regs; 68862306a36Sopenharmony_ci u8 val; 68962306a36Sopenharmony_ci 69062306a36Sopenharmony_ci int ret = tda18271_lookup_map(fe, RF_CAL, freq, &val); 69162306a36Sopenharmony_ci /* The TDA18271HD/C1 rf_cal map lookup is expected to go out of range 69262306a36Sopenharmony_ci * for frequencies above 61.1 MHz. In these cases, the internal RF 69362306a36Sopenharmony_ci * tracking filters calibration mechanism is used. 69462306a36Sopenharmony_ci * 69562306a36Sopenharmony_ci * There is no need to warn the user about this. 69662306a36Sopenharmony_ci */ 69762306a36Sopenharmony_ci if (ret < 0) 69862306a36Sopenharmony_ci goto fail; 69962306a36Sopenharmony_ci 70062306a36Sopenharmony_ci regs[R_EB14] = val; 70162306a36Sopenharmony_cifail: 70262306a36Sopenharmony_ci return ret; 70362306a36Sopenharmony_ci} 70462306a36Sopenharmony_ci 70562306a36Sopenharmony_civoid _tda_printk(struct tda18271_priv *state, const char *level, 70662306a36Sopenharmony_ci const char *func, const char *fmt, ...) 70762306a36Sopenharmony_ci{ 70862306a36Sopenharmony_ci struct va_format vaf; 70962306a36Sopenharmony_ci va_list args; 71062306a36Sopenharmony_ci 71162306a36Sopenharmony_ci va_start(args, fmt); 71262306a36Sopenharmony_ci 71362306a36Sopenharmony_ci vaf.fmt = fmt; 71462306a36Sopenharmony_ci vaf.va = &args; 71562306a36Sopenharmony_ci 71662306a36Sopenharmony_ci if (state) 71762306a36Sopenharmony_ci printk("%s%s: [%d-%04x|%c] %pV", 71862306a36Sopenharmony_ci level, func, i2c_adapter_id(state->i2c_props.adap), 71962306a36Sopenharmony_ci state->i2c_props.addr, 72062306a36Sopenharmony_ci (state->role == TDA18271_MASTER) ? 'M' : 'S', 72162306a36Sopenharmony_ci &vaf); 72262306a36Sopenharmony_ci else 72362306a36Sopenharmony_ci printk("%s%s: %pV", level, func, &vaf); 72462306a36Sopenharmony_ci 72562306a36Sopenharmony_ci va_end(args); 72662306a36Sopenharmony_ci} 727