^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * NXP TDA18250 silicon tuner driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2017 Olli Salonen <olli.salonen@iki.fi>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "tda18250_priv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) static const struct dvb_tuner_ops tda18250_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) static int tda18250_power_control(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) unsigned int power_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) struct i2c_client *client = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) struct tda18250_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) unsigned int utmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) dev_dbg(&client->dev, "power state: %d", power_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) switch (power_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) case TDA18250_POWER_NORMAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) ret = regmap_write_bits(dev->regmap, R06_POWER2, 0x07, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) ret = regmap_write_bits(dev->regmap, R25_REF, 0xc0, 0xc0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) case TDA18250_POWER_STANDBY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) if (dev->loopthrough) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) ret = regmap_write_bits(dev->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) R25_REF, 0xc0, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) ret = regmap_write_bits(dev->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) R06_POWER2, 0x07, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) ret = regmap_write_bits(dev->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) R10_LT1, 0x80, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) ret = regmap_write_bits(dev->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) R25_REF, 0xc0, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) ret = regmap_write_bits(dev->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) R06_POWER2, 0x07, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) ret = regmap_read(dev->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) R0D_AGC12, &utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) ret = regmap_write_bits(dev->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) R0D_AGC12, 0x03, 0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) ret = regmap_write_bits(dev->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) R10_LT1, 0x80, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) ret = regmap_write_bits(dev->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) R0D_AGC12, 0x03, utmp & 0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static int tda18250_wait_for_irq(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) int maxwait, int step, u8 irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct i2c_client *client = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct tda18250_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) unsigned long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) bool triggered;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) unsigned int utmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) triggered = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) timeout = jiffies + msecs_to_jiffies(maxwait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) while (!time_after(jiffies, timeout)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) // check for the IRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) ret = regmap_read(dev->regmap, R08_IRQ1, &utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if ((utmp & irq) == irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) triggered = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) msleep(step);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) dev_dbg(&client->dev, "waited IRQ (0x%02x) %d ms, triggered: %s", irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) jiffies_to_msecs(jiffies) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) (jiffies_to_msecs(timeout) - maxwait),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) triggered ? "true" : "false");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (!triggered)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static int tda18250_init(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct i2c_client *client = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct tda18250_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /* default values for various regs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static const u8 init_regs[][2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) { R0C_AGC11, 0xc7 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) { R0D_AGC12, 0x5d },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) { R0E_AGC13, 0x40 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) { R0F_AGC14, 0x0e },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) { R10_LT1, 0x47 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) { R11_LT2, 0x4e },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) { R12_AGC21, 0x26 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) { R13_AGC22, 0x60 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) { R18_AGC32, 0x37 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) { R19_AGC33, 0x09 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) { R1A_AGCK, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) { R1E_WI_FI, 0x29 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) { R1F_RF_BPF, 0x06 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) { R20_IR_MIX, 0xc6 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) { R21_IF_AGC, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) { R2C_PS1, 0x75 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) { R2D_PS2, 0x06 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) { R2E_PS3, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) { R30_RSSI2, 0x0e },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) { R31_IRQ_CTRL, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) { R39_SD5, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) { R3B_REGU, 0x55 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) { R3C_RCCAL1, 0xa7 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) { R3F_IRCAL2, 0x85 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) { R40_IRCAL3, 0x87 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) { R41_IRCAL4, 0xc0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) { R43_PD1, 0x40 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) { R44_PD2, 0xc0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) { R46_CPUMP, 0x0c },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) { R47_LNAPOL, 0x64 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) { R4B_XTALOSC1, 0x30 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) { R59_AGC2_UP2, 0x05 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) { R5B_AGC_AUTO, 0x07 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) { R5C_AGC_DEBUG, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /* crystal related regs depend on frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static const u8 xtal_regs[][5] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /* reg: 4d 4e 4f 50 51 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) [TDA18250_XTAL_FREQ_16MHZ] = { 0x3e, 0x80, 0x50, 0x00, 0x20 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) [TDA18250_XTAL_FREQ_24MHZ] = { 0x5d, 0xc0, 0xec, 0x00, 0x18 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) [TDA18250_XTAL_FREQ_25MHZ] = { 0x61, 0xa8, 0xec, 0x80, 0x19 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) [TDA18250_XTAL_FREQ_27MHZ] = { 0x69, 0x78, 0x8d, 0x80, 0x1b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) [TDA18250_XTAL_FREQ_30MHZ] = { 0x75, 0x30, 0x8f, 0x00, 0x1e },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) dev_dbg(&client->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) ret = tda18250_power_control(fe, TDA18250_POWER_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (dev->warm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) goto warm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) /* set initial register values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) for (i = 0; i < ARRAY_SIZE(init_regs); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) ret = regmap_write(dev->regmap, init_regs[i][0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) init_regs[i][1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) /* set xtal related regs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) ret = regmap_bulk_write(dev->regmap, R4D_XTALFLX1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) xtal_regs[dev->xtal_freq], 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) ret = regmap_write_bits(dev->regmap, R10_LT1, 0x80,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) dev->loopthrough ? 0x00 : 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /* clear IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) ret = regmap_write(dev->regmap, R0A_IRQ3, TDA18250_IRQ_HW_INIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /* start HW init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) ret = regmap_write(dev->regmap, R2A_MSM1, 0x70);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) ret = regmap_write(dev->regmap, R2B_MSM2, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) ret = tda18250_wait_for_irq(fe, 500, 10, TDA18250_IRQ_HW_INIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) /* tuner calibration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) ret = regmap_write(dev->regmap, R2A_MSM1, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) ret = regmap_write(dev->regmap, R2B_MSM2, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) ret = tda18250_wait_for_irq(fe, 500, 10, TDA18250_IRQ_CAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) dev->warm = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) warm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) /* power up LNA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) ret = regmap_write_bits(dev->regmap, R0C_AGC11, 0x80, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) dev_dbg(&client->dev, "failed=%d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) static int tda18250_set_agc(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) struct i2c_client *client = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct tda18250_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) u8 utmp, utmp2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) dev_dbg(&client->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) ret = regmap_write_bits(dev->regmap, R1F_RF_BPF, 0x87, 0x06);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) utmp = ((c->frequency < 100000000) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) ((c->delivery_system == SYS_DVBC_ANNEX_A) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) (c->delivery_system == SYS_DVBC_ANNEX_C)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) (c->bandwidth_hz == 6000000)) ? 0x80 : 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) ret = regmap_write(dev->regmap, R5A_H3H5, utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /* AGC1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) switch (c->delivery_system) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) case SYS_ATSC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) case SYS_DVBT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) case SYS_DVBT2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) utmp = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) default: /* DVB-C/QAM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) switch (c->bandwidth_hz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) case 6000000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) utmp = (c->frequency < 800000000) ? 6 : 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) default: /* 7.935 and 8 MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) utmp = (c->frequency < 100000000) ? 2 : 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) ret = regmap_write_bits(dev->regmap, R0C_AGC11, 0x07, utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) /* AGC2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) switch (c->delivery_system) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) case SYS_ATSC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) case SYS_DVBT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) case SYS_DVBT2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) utmp = (c->frequency < 320000000) ? 20 : 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) utmp2 = (c->frequency < 320000000) ? 22 : 18;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) default: /* DVB-C/QAM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) switch (c->bandwidth_hz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) case 6000000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (c->frequency < 600000000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) utmp = 18;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) utmp2 = 22;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) } else if (c->frequency < 800000000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) utmp = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) utmp2 = 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) utmp = 14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) utmp2 = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) default: /* 7.935 and 8 MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) utmp = (c->frequency < 320000000) ? 16 : 18;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) utmp2 = (c->frequency < 320000000) ? 18 : 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) ret = regmap_write_bits(dev->regmap, R58_AGC2_UP1, 0x1f, utmp2+8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) ret = regmap_write_bits(dev->regmap, R13_AGC22, 0x1f, utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) ret = regmap_write_bits(dev->regmap, R14_AGC23, 0x1f, utmp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) switch (c->delivery_system) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) case SYS_ATSC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) case SYS_DVBT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) case SYS_DVBT2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) utmp = 98;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) default: /* DVB-C/QAM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) utmp = 90;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) ret = regmap_write_bits(dev->regmap, R16_AGC25, 0xf8, utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) ret = regmap_write_bits(dev->regmap, R12_AGC21, 0x60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) (c->frequency > 800000000) ? 0x40 : 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) /* AGC3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) switch (c->delivery_system) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) case SYS_ATSC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) case SYS_DVBT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) case SYS_DVBT2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) utmp = (c->frequency < 320000000) ? 5 : 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) utmp2 = (c->frequency < 320000000) ? 10 : 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) default: /* DVB-C/QAM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) utmp = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) utmp2 = 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) ret = regmap_write(dev->regmap, R17_AGC31, (utmp << 4) | utmp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) /* S2D */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) switch (c->delivery_system) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) case SYS_ATSC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) case SYS_DVBT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) case SYS_DVBT2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (c->bandwidth_hz == 8000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) utmp = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) utmp = (c->frequency < 320000000) ? 0x04 : 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) default: /* DVB-C/QAM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (c->bandwidth_hz == 6000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) utmp = ((c->frequency > 172544000) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) (c->frequency < 320000000)) ? 0x04 : 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) else /* 7.935 and 8 MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) utmp = ((c->frequency > 320000000) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) (c->frequency < 600000000)) ? 0x02 : 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) ret = regmap_write_bits(dev->regmap, R20_IR_MIX, 0x06, utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) switch (c->delivery_system) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) case SYS_ATSC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) case SYS_DVBT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) case SYS_DVBT2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) utmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) default: /* DVB-C/QAM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) utmp = (c->frequency < 600000000) ? 0 : 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) ret = regmap_write_bits(dev->regmap, R16_AGC25, 0x03, utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) utmp = 0x09;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) switch (c->delivery_system) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) case SYS_ATSC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) case SYS_DVBT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) case SYS_DVBT2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (c->bandwidth_hz == 8000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) utmp = 0x0c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) default: /* DVB-C/QAM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) utmp = 0x0c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) ret = regmap_write_bits(dev->regmap, R0F_AGC14, 0x3f, utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) dev_dbg(&client->dev, "failed=%d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) static int tda18250_pll_calc(struct dvb_frontend *fe, u8 *rdiv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) u8 *ndiv, u8 *icp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) struct i2c_client *client = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) struct tda18250_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) unsigned int uval, exp, lopd, scale;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) unsigned long fvco;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) ret = regmap_read(dev->regmap, R34_MD1, &uval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) exp = (uval & 0x70) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) if (exp > 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) exp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) lopd = 1 << (exp - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) scale = uval & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) fvco = lopd * scale * ((c->frequency / 1000) + dev->if_frequency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) switch (dev->xtal_freq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) case TDA18250_XTAL_FREQ_16MHZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) *rdiv = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) *ndiv = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) *icp = (fvco < 6622000) ? 0x05 : 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) case TDA18250_XTAL_FREQ_24MHZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) case TDA18250_XTAL_FREQ_25MHZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) *rdiv = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) *ndiv = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) *icp = (fvco < 6622000) ? 0x05 : 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) case TDA18250_XTAL_FREQ_27MHZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (fvco < 6643000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) *rdiv = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) *ndiv = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) *icp = 0x05;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) } else if (fvco < 6811000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) *rdiv = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) *ndiv = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) *icp = 0x06;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) *rdiv = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) *ndiv = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) *icp = 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) case TDA18250_XTAL_FREQ_30MHZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) *rdiv = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) *ndiv = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) *icp = (fvco < 6811000) ? 0x05 : 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) dev_dbg(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) "lopd=%d scale=%u fvco=%lu, rdiv=%d ndiv=%d icp=%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) lopd, scale, fvco, *rdiv, *ndiv, *icp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) static int tda18250_set_params(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) struct i2c_client *client = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) struct tda18250_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) u32 if_khz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) unsigned int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) u8 utmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) u8 buf[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) #define REG 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) #define MASK 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) #define DVBT_6 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) #define DVBT_7 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) #define DVBT_8 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) #define DVBC_6 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) #define DVBC_8 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) #define ATSC 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) static const u8 delsys_params[][16] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) [REG] = { 0x22, 0x23, 0x24, 0x21, 0x0d, 0x0c, 0x0f, 0x14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 0x0e, 0x12, 0x58, 0x59, 0x1a, 0x19, 0x1e, 0x30 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) [MASK] = { 0x77, 0xff, 0xff, 0x87, 0xf0, 0x78, 0x07, 0xe0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 0x60, 0x0f, 0x60, 0x0f, 0x33, 0x30, 0x80, 0x06 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) [DVBT_6] = { 0x51, 0x03, 0x83, 0x82, 0x40, 0x48, 0x01, 0xe0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 0x60, 0x0f, 0x60, 0x05, 0x03, 0x10, 0x00, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) [DVBT_7] = { 0x52, 0x03, 0x85, 0x82, 0x40, 0x48, 0x01, 0xe0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 0x60, 0x0f, 0x60, 0x05, 0x03, 0x10, 0x00, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) [DVBT_8] = { 0x53, 0x03, 0x87, 0x82, 0x40, 0x48, 0x06, 0xe0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 0x60, 0x07, 0x60, 0x05, 0x03, 0x10, 0x00, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) [DVBC_6] = { 0x32, 0x05, 0x86, 0x82, 0x50, 0x00, 0x06, 0x60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 0x40, 0x0e, 0x60, 0x05, 0x33, 0x10, 0x00, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) [DVBC_8] = { 0x53, 0x03, 0x88, 0x82, 0x50, 0x00, 0x06, 0x60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 0x40, 0x0e, 0x60, 0x05, 0x33, 0x10, 0x00, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) [ATSC] = { 0x51, 0x03, 0x83, 0x82, 0x40, 0x48, 0x01, 0xe0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 0x40, 0x0e, 0x60, 0x05, 0x03, 0x00, 0x80, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) dev_dbg(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) "delivery_system=%d frequency=%u bandwidth_hz=%u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) c->delivery_system, c->frequency, c->bandwidth_hz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) switch (c->delivery_system) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) case SYS_ATSC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) j = ATSC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if_khz = dev->if_atsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) case SYS_DVBT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) case SYS_DVBT2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (c->bandwidth_hz == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) } else if (c->bandwidth_hz <= 6000000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) j = DVBT_6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) if_khz = dev->if_dvbt_6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) } else if (c->bandwidth_hz <= 7000000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) j = DVBT_7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if_khz = dev->if_dvbt_7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) } else if (c->bandwidth_hz <= 8000000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) j = DVBT_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) if_khz = dev->if_dvbt_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) case SYS_DVBC_ANNEX_A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) case SYS_DVBC_ANNEX_C:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) if (c->bandwidth_hz == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) } else if (c->bandwidth_hz <= 6000000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) j = DVBC_6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if_khz = dev->if_dvbc_6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) } else if (c->bandwidth_hz <= 8000000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) j = DVBC_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) if_khz = dev->if_dvbc_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) dev_err(&client->dev, "unsupported delivery system=%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) c->delivery_system);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) /* set delivery system dependent registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) for (i = 0; i < 16; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) ret = regmap_write_bits(dev->regmap, delsys_params[REG][i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) delsys_params[MASK][i], delsys_params[j][i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) /* set IF if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) if (dev->if_frequency != if_khz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) utmp = DIV_ROUND_CLOSEST(if_khz, 50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) ret = regmap_write(dev->regmap, R26_IF, utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) dev->if_frequency = if_khz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) dev_dbg(&client->dev, "set IF=%u kHz", if_khz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) ret = tda18250_set_agc(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) ret = regmap_write_bits(dev->regmap, R1A_AGCK, 0x03, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) ret = regmap_write_bits(dev->regmap, R14_AGC23, 0x40, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) /* set frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) buf[0] = ((c->frequency / 1000) >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) buf[1] = ((c->frequency / 1000) >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) buf[2] = ((c->frequency / 1000) >> 0) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) ret = regmap_bulk_write(dev->regmap, R27_RF1, buf, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) ret = regmap_write(dev->regmap, R0A_IRQ3, TDA18250_IRQ_TUNE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) /* initial tune */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) ret = regmap_write(dev->regmap, R2A_MSM1, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) ret = regmap_write(dev->regmap, R2B_MSM2, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) ret = tda18250_wait_for_irq(fe, 500, 10, TDA18250_IRQ_TUNE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) /* calc ndiv and rdiv */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) ret = tda18250_pll_calc(fe, &buf[0], &buf[1], &buf[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) ret = regmap_write_bits(dev->regmap, R4F_XTALFLX3, 0xe0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) (buf[0] << 6) | (buf[1] << 5));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) /* clear IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) ret = regmap_write(dev->regmap, R0A_IRQ3, TDA18250_IRQ_TUNE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) ret = regmap_write_bits(dev->regmap, R46_CPUMP, 0x07, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) ret = regmap_write_bits(dev->regmap, R39_SD5, 0x03, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) /* tune again */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) ret = regmap_write(dev->regmap, R2A_MSM1, 0x01); /* tune */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) ret = regmap_write(dev->regmap, R2B_MSM2, 0x01); /* go */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) ret = tda18250_wait_for_irq(fe, 500, 10, TDA18250_IRQ_TUNE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) /* pll locking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) ret = regmap_write_bits(dev->regmap, R2B_MSM2, 0x04, 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) /* restore AGCK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) ret = regmap_write_bits(dev->regmap, R1A_AGCK, 0x03, 0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) ret = regmap_write_bits(dev->regmap, R14_AGC23, 0x40, 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) /* charge pump */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) ret = regmap_write_bits(dev->regmap, R46_CPUMP, 0x07, buf[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) static int tda18250_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) struct i2c_client *client = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) struct tda18250_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) *frequency = dev->if_frequency * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) static int tda18250_sleep(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) struct i2c_client *client = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) struct tda18250_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) dev_dbg(&client->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) /* power down LNA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) ret = regmap_write_bits(dev->regmap, R0C_AGC11, 0x80, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) /* set if freq to 0 in order to make sure it's set after wake up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) dev->if_frequency = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) ret = tda18250_power_control(fe, TDA18250_POWER_STANDBY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) static const struct dvb_tuner_ops tda18250_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) .info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) .name = "NXP TDA18250",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) .frequency_min_hz = 42 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) .frequency_max_hz = 870 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) .init = tda18250_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) .set_params = tda18250_set_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) .get_if_frequency = tda18250_get_if_frequency,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) .sleep = tda18250_sleep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) static int tda18250_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) struct tda18250_config *cfg = client->dev.platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) struct dvb_frontend *fe = cfg->fe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) struct tda18250_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) unsigned char chip_id[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) /* some registers are always read from HW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) static const struct regmap_range tda18250_yes_ranges[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) regmap_reg_range(R05_POWER1, R0B_IRQ4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) regmap_reg_range(R21_IF_AGC, R21_IF_AGC),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) regmap_reg_range(R2A_MSM1, R2B_MSM2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) regmap_reg_range(R2F_RSSI1, R31_IRQ_CTRL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) static const struct regmap_access_table tda18250_volatile_table = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) .yes_ranges = tda18250_yes_ranges,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) .n_yes_ranges = ARRAY_SIZE(tda18250_yes_ranges),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) static const struct regmap_config tda18250_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) .reg_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) .val_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) .max_register = TDA18250_NUM_REGS - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) .volatile_table = &tda18250_volatile_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) dev = kzalloc(sizeof(*dev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) i2c_set_clientdata(client, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) dev->fe = cfg->fe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) dev->loopthrough = cfg->loopthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) if (cfg->xtal_freq < TDA18250_XTAL_FREQ_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) dev->xtal_freq = cfg->xtal_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) dev_err(&client->dev, "xtal_freq invalid=%d", cfg->xtal_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) goto err_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) dev->if_dvbt_6 = cfg->if_dvbt_6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) dev->if_dvbt_7 = cfg->if_dvbt_7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) dev->if_dvbt_8 = cfg->if_dvbt_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) dev->if_dvbc_6 = cfg->if_dvbc_6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) dev->if_dvbc_8 = cfg->if_dvbc_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) dev->if_atsc = cfg->if_atsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) dev->if_frequency = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) dev->warm = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) dev->regmap = devm_regmap_init_i2c(client, &tda18250_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (IS_ERR(dev->regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) ret = PTR_ERR(dev->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) goto err_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) /* read the three chip ID registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) regmap_bulk_read(dev->regmap, R00_ID1, &chip_id, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) dev_dbg(&client->dev, "chip_id=%02x:%02x:%02x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) chip_id[0], chip_id[1], chip_id[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) switch (chip_id[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) case 0xc7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) dev->slave = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) case 0x47:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) dev->slave = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) goto err_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) if (chip_id[1] != 0x4a) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) goto err_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) switch (chip_id[2]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) case 0x20:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) dev_info(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) "NXP TDA18250AHN/%s successfully identified",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) dev->slave ? "S" : "M");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) case 0x21:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) dev_info(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) "NXP TDA18250BHN/%s successfully identified",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) dev->slave ? "S" : "M");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) goto err_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) fe->tuner_priv = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) memcpy(&fe->ops.tuner_ops, &tda18250_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) sizeof(struct dvb_tuner_ops));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) /* put the tuner in standby */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) tda18250_power_control(fe, TDA18250_POWER_STANDBY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) err_kfree:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) kfree(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) dev_dbg(&client->dev, "failed=%d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) static int tda18250_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) struct tda18250_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) struct dvb_frontend *fe = dev->fe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) dev_dbg(&client->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) memset(&fe->ops.tuner_ops, 0, sizeof(struct dvb_tuner_ops));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) fe->tuner_priv = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) kfree(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) static const struct i2c_device_id tda18250_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) {"tda18250", 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) MODULE_DEVICE_TABLE(i2c, tda18250_id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) static struct i2c_driver tda18250_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) .name = "tda18250",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) .probe = tda18250_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) .remove = tda18250_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) .id_table = tda18250_id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) module_i2c_driver(tda18250_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) MODULE_DESCRIPTION("NXP TDA18250 silicon tuner driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) MODULE_AUTHOR("Olli Salonen <olli.salonen@iki.fi>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) MODULE_LICENSE("GPL");