^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) * Driver for the internal tuner of Montage M88RS6000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2014 Max nibble <nibble.max@gmail.com>
^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 "m88rs6000t.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) struct m88rs6000t_dev {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) struct m88rs6000t_config cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) u32 frequency_khz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) struct m88rs6000t_reg_val {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) /* set demod main mclk and ts mclk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) static int m88rs6000t_set_demod_mclk(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) struct m88rs6000t_dev *dev = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) u8 reg11, reg15, reg16, reg1D, reg1E, reg1F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) u8 N, f0 = 0, f1 = 0, f2 = 0, f3 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) u16 pll_div_fb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) u32 div, ts_mclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) unsigned int utmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /* select demod main mclk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) ret = regmap_read(dev->regmap, 0x15, &utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) reg15 = utmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) if (c->symbol_rate > 45010000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) reg11 = 0x0E;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) reg15 |= 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) reg16 = 115; /* mclk = 110.25MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) reg11 = 0x0A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) reg15 &= ~0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) reg16 = 96; /* mclk = 96MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /* set ts mclk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) if (c->delivery_system == SYS_DVBS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) ts_mclk = 96000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) ts_mclk = 144000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) pll_div_fb = (reg15 & 0x01) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) pll_div_fb += reg16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) pll_div_fb += 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) div = 36000 * pll_div_fb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) div /= ts_mclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) if (div <= 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) N = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) f0 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) f1 = div / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) f2 = div - f1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) f3 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) } else if (div <= 48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) N = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) f0 = div / 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) f1 = (div - f0) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) f2 = div - f0 - f1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) f3 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) } else if (div <= 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) N = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) f0 = div / 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) f1 = (div - f0) / 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) f2 = (div - f0 - f1) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) f3 = div - f0 - f1 - f2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) N = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) f0 = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) f1 = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) f2 = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) f3 = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (f0 == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) f0 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (f1 == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) f1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (f2 == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) f2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (f3 == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) f3 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) ret = regmap_read(dev->regmap, 0x1D, &utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) reg1D = utmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) reg1D &= ~0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) reg1D |= N - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) reg1E = ((f3 << 4) + f2) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) reg1F = ((f1 << 4) + f0) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /* program and recalibrate demod PLL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) ret = regmap_write(dev->regmap, 0x05, 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) ret = regmap_write(dev->regmap, 0x11, 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) ret = regmap_write(dev->regmap, 0x15, reg15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) ret = regmap_write(dev->regmap, 0x16, reg16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) ret = regmap_write(dev->regmap, 0x1D, reg1D);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) ret = regmap_write(dev->regmap, 0x1E, reg1E);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) ret = regmap_write(dev->regmap, 0x1F, reg1F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) ret = regmap_write(dev->regmap, 0x17, 0xc1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) ret = regmap_write(dev->regmap, 0x17, 0x81);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) usleep_range(5000, 50000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) ret = regmap_write(dev->regmap, 0x05, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) ret = regmap_write(dev->regmap, 0x11, reg11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) usleep_range(5000, 50000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) dev_dbg(&dev->client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) static int m88rs6000t_set_pll_freq(struct m88rs6000t_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) u32 tuner_freq_MHz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) u32 fcry_KHz, ulNDiv1, ulNDiv2, ulNDiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) u8 refDiv, ucLoDiv1, ucLomod1, ucLoDiv2, ucLomod2, ucLoDiv, ucLomod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) u8 reg27, reg29, reg42, reg42buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) unsigned int utmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) fcry_KHz = 27000; /* in kHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) refDiv = 27;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) ret = regmap_write(dev->regmap, 0x36, (refDiv - 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) ret = regmap_write(dev->regmap, 0x31, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) ret = regmap_write(dev->regmap, 0x2c, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (tuner_freq_MHz >= 1550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) ucLoDiv1 = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) ucLomod1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) ucLoDiv2 = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) ucLomod2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) } else if (tuner_freq_MHz >= 1380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) ucLoDiv1 = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) ucLomod1 = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) ucLoDiv2 = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) ucLomod2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) } else if (tuner_freq_MHz >= 1070) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) ucLoDiv1 = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) ucLomod1 = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) ucLoDiv2 = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) ucLomod2 = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) } else if (tuner_freq_MHz >= 1000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) ucLoDiv1 = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) ucLomod1 = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) ucLoDiv2 = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) ucLomod2 = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) } else if (tuner_freq_MHz >= 775) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) ucLoDiv1 = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) ucLomod1 = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) ucLoDiv2 = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) ucLomod2 = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) } else if (tuner_freq_MHz >= 700) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) ucLoDiv1 = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) ucLomod1 = 48;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) ucLoDiv2 = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) ucLomod2 = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) } else if (tuner_freq_MHz >= 520) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) ucLoDiv1 = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) ucLomod1 = 48;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) ucLoDiv2 = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) ucLomod2 = 48;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) ucLoDiv1 = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) ucLomod1 = 96;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) ucLoDiv2 = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) ucLomod2 = 96;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) ulNDiv1 = ((tuner_freq_MHz * ucLoDiv1 * 1000) * refDiv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) / fcry_KHz - 1024) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) ulNDiv2 = ((tuner_freq_MHz * ucLoDiv2 * 1000) * refDiv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) / fcry_KHz - 1024) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) reg27 = (((ulNDiv1 >> 8) & 0x0F) + ucLomod1) & 0x7F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) ret = regmap_write(dev->regmap, 0x27, reg27);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) ret = regmap_write(dev->regmap, 0x28, (u8)(ulNDiv1 & 0xFF));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) reg29 = (((ulNDiv2 >> 8) & 0x0F) + ucLomod2) & 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) ret = regmap_write(dev->regmap, 0x29, reg29);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) ret = regmap_write(dev->regmap, 0x2a, (u8)(ulNDiv2 & 0xFF));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) ret = regmap_write(dev->regmap, 0x2F, 0xf5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) ret = regmap_write(dev->regmap, 0x30, 0x05);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) ret = regmap_write(dev->regmap, 0x08, 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) ret = regmap_write(dev->regmap, 0x08, 0x3f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) ret = regmap_write(dev->regmap, 0x09, 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) ret = regmap_write(dev->regmap, 0x09, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) ret = regmap_write(dev->regmap, 0x3e, 0x11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) ret = regmap_write(dev->regmap, 0x08, 0x2f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) ret = regmap_write(dev->regmap, 0x08, 0x3f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) ret = regmap_write(dev->regmap, 0x09, 0x10);
^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) ret = regmap_write(dev->regmap, 0x09, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) usleep_range(2000, 50000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) ret = regmap_read(dev->regmap, 0x42, &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) reg42 = utmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) ret = regmap_write(dev->regmap, 0x3e, 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) ret = regmap_write(dev->regmap, 0x08, 0x2f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) ret = regmap_write(dev->regmap, 0x08, 0x3f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) ret = regmap_write(dev->regmap, 0x09, 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) ret = regmap_write(dev->regmap, 0x09, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) usleep_range(2000, 50000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) ret = regmap_read(dev->regmap, 0x42, &utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) reg42buf = utmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (reg42buf < reg42) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) ret = regmap_write(dev->regmap, 0x3e, 0x11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) usleep_range(5000, 50000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) ret = regmap_read(dev->regmap, 0x2d, &utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) ret = regmap_write(dev->regmap, 0x2d, utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) ret = regmap_read(dev->regmap, 0x2e, &utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) ret = regmap_write(dev->regmap, 0x2e, utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) ret = regmap_read(dev->regmap, 0x27, &utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) reg27 = utmp & 0x70;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) ret = regmap_read(dev->regmap, 0x83, &utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (reg27 == (utmp & 0x70)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) ucLoDiv = ucLoDiv1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) ulNDiv = ulNDiv1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) ucLomod = ucLomod1 / 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) ucLoDiv = ucLoDiv2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) ulNDiv = ulNDiv2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) ucLomod = ucLomod2 / 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if ((ucLoDiv == 3) || (ucLoDiv == 6)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) refDiv = 18;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) ret = regmap_write(dev->regmap, 0x36, (refDiv - 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) ulNDiv = ((tuner_freq_MHz * ucLoDiv * 1000) * refDiv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) / fcry_KHz - 1024) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) reg27 = (0x80 + ((ucLomod << 4) & 0x70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) + ((ulNDiv >> 8) & 0x0F)) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) ret = regmap_write(dev->regmap, 0x27, reg27);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) ret = regmap_write(dev->regmap, 0x28, (u8)(ulNDiv & 0xFF));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) ret = regmap_write(dev->regmap, 0x29, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) ret = regmap_write(dev->regmap, 0x31, 0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (ucLoDiv == 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) utmp = 0xCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) utmp = 0x8A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) ret = regmap_write(dev->regmap, 0x3b, utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) dev->frequency_khz = fcry_KHz * (ulNDiv * 2 + 1024) / refDiv / ucLoDiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) dev_dbg(&dev->client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) "actual tune frequency=%d\n", dev->frequency_khz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) dev_dbg(&dev->client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) static int m88rs6000t_set_bb(struct m88rs6000t_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) u32 symbol_rate_KSs, s32 lpf_offset_KHz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) u32 f3dB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) u8 reg40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) f3dB = symbol_rate_KSs * 9 / 14 + 2000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) f3dB += lpf_offset_KHz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) f3dB = clamp_val(f3dB, 6000U, 43000U);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) reg40 = f3dB / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) return regmap_write(dev->regmap, 0x40, reg40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) static int m88rs6000t_set_params(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) struct m88rs6000t_dev *dev = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) s32 lpf_offset_KHz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) u32 realFreq, freq_MHz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) dev_dbg(&dev->client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) "frequency=%d symbol_rate=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) c->frequency, c->symbol_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (c->symbol_rate < 5000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) lpf_offset_KHz = 3000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) lpf_offset_KHz = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) realFreq = c->frequency + lpf_offset_KHz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) /* set tuner pll.*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) freq_MHz = (realFreq + 500) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) ret = m88rs6000t_set_pll_freq(dev, freq_MHz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) ret = m88rs6000t_set_bb(dev, c->symbol_rate / 1000, lpf_offset_KHz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) ret = regmap_write(dev->regmap, 0x00, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) ret = regmap_write(dev->regmap, 0x00, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) /* set demod mlck */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) ret = m88rs6000t_set_demod_mclk(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) dev_dbg(&dev->client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) static int m88rs6000t_init(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) struct m88rs6000t_dev *dev = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) dev_dbg(&dev->client->dev, "%s:\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) ret = regmap_update_bits(dev->regmap, 0x11, 0x08, 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) usleep_range(5000, 50000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) ret = regmap_update_bits(dev->regmap, 0x10, 0x01, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) usleep_range(10000, 50000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) ret = regmap_write(dev->regmap, 0x07, 0x7d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) dev_dbg(&dev->client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) static int m88rs6000t_sleep(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) struct m88rs6000t_dev *dev = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) dev_dbg(&dev->client->dev, "%s:\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) ret = regmap_write(dev->regmap, 0x07, 0x6d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) dev_dbg(&dev->client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) usleep_range(5000, 10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) static int m88rs6000t_get_frequency(struct dvb_frontend *fe, u32 *frequency)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) struct m88rs6000t_dev *dev = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) dev_dbg(&dev->client->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) *frequency = dev->frequency_khz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) static int m88rs6000t_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) struct m88rs6000t_dev *dev = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) dev_dbg(&dev->client->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) *frequency = 0; /* Zero-IF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) static int m88rs6000t_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) struct m88rs6000t_dev *dev = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) unsigned int val, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) u16 gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) u32 PGA2_cri_GS = 46, PGA2_crf_GS = 290, TIA_GS = 290;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) u32 RF_GC = 1200, IF_GC = 1100, BB_GC = 300;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) u32 PGA2_GC = 300, TIA_GC = 300, PGA2_cri = 0, PGA2_crf = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) u32 RFG = 0, IFG = 0, BBG = 0, PGA2G = 0, TIAG = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) u32 RFGS[13] = {0, 245, 266, 268, 270, 285,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 298, 295, 283, 285, 285, 300, 300};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) u32 IFGS[12] = {0, 300, 230, 270, 270, 285,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 295, 285, 290, 295, 295, 310};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) u32 BBGS[14] = {0, 286, 275, 290, 294, 300, 290,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 290, 285, 283, 260, 295, 290, 260};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) ret = regmap_read(dev->regmap, 0x5A, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) RF_GC = val & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) ret = regmap_read(dev->regmap, 0x5F, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) IF_GC = val & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) ret = regmap_read(dev->regmap, 0x3F, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) TIA_GC = (val >> 4) & 0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) ret = regmap_read(dev->regmap, 0x77, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) BB_GC = (val >> 4) & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) ret = regmap_read(dev->regmap, 0x76, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) PGA2_GC = val & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) PGA2_cri = PGA2_GC >> 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) PGA2_crf = PGA2_GC & 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) for (i = 0; i <= RF_GC && i < ARRAY_SIZE(RFGS); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) RFG += RFGS[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) if (RF_GC == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) RFG += 400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (RF_GC == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) RFG += 300;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if (RF_GC == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) RFG += 200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) if (RF_GC == 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) RFG += 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) for (i = 0; i <= IF_GC && i < ARRAY_SIZE(IFGS); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) IFG += IFGS[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) TIAG = TIA_GC * TIA_GS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) for (i = 0; i <= BB_GC && i < ARRAY_SIZE(BBGS); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) BBG += BBGS[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) PGA2G = PGA2_cri * PGA2_cri_GS + PGA2_crf * PGA2_crf_GS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) gain = RFG + IFG - TIAG + BBG + PGA2G;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) /* scale value to 0x0000-0xffff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) gain = clamp_val(gain, 1000U, 10500U);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) *strength = (10500 - gain) * 0xffff / (10500 - 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) dev_dbg(&dev->client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) static const struct dvb_tuner_ops m88rs6000t_tuner_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) .info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) .name = "Montage M88RS6000 Internal Tuner",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) .frequency_min_hz = 950 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) .frequency_max_hz = 2150 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) .init = m88rs6000t_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) .sleep = m88rs6000t_sleep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) .set_params = m88rs6000t_set_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) .get_frequency = m88rs6000t_get_frequency,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) .get_if_frequency = m88rs6000t_get_if_frequency,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) .get_rf_strength = m88rs6000t_get_rf_strength,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) static int m88rs6000t_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) struct m88rs6000t_config *cfg = client->dev.platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) struct dvb_frontend *fe = cfg->fe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) struct m88rs6000t_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) unsigned int utmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) static const struct regmap_config regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) .reg_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) .val_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) static const struct m88rs6000t_reg_val reg_vals[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) {0x10, 0xfb},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) {0x24, 0x38},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) {0x11, 0x0a},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) {0x12, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) {0x2b, 0x1c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) {0x44, 0x48},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) {0x54, 0x24},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) {0x55, 0x06},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) {0x59, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) {0x5b, 0x4c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) {0x60, 0x8b},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) {0x61, 0xf4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) {0x65, 0x07},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) {0x6d, 0x6f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) {0x6e, 0x31},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) {0x3c, 0xf3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) {0x37, 0x0f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) {0x48, 0x28},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) {0x49, 0xd8},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) {0x70, 0x66},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) {0x71, 0xCF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) {0x72, 0x81},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) {0x73, 0xA7},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) {0x74, 0x4F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) {0x75, 0xFC},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) dev = kzalloc(sizeof(*dev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) if (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) dev_err(&client->dev, "kzalloc() failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) memcpy(&dev->cfg, cfg, sizeof(struct m88rs6000t_config));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) dev->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) dev->regmap = devm_regmap_init_i2c(client, ®map_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) if (IS_ERR(dev->regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) ret = PTR_ERR(dev->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) ret = regmap_update_bits(dev->regmap, 0x11, 0x08, 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) usleep_range(5000, 50000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) ret = regmap_update_bits(dev->regmap, 0x10, 0x01, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) usleep_range(10000, 50000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) ret = regmap_write(dev->regmap, 0x07, 0x7d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) ret = regmap_write(dev->regmap, 0x04, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) /* check tuner chip id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) ret = regmap_read(dev->regmap, 0x01, &utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) dev_info(&dev->client->dev, "chip_id=%02x\n", utmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) if (utmp != 0x64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) ret = -ENODEV;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) /* tuner init. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) ret = regmap_write(dev->regmap, 0x05, 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) ret = regmap_write(dev->regmap, 0x11, 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) ret = regmap_write(dev->regmap, 0x15, 0x6c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) ret = regmap_write(dev->regmap, 0x17, 0xc1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) ret = regmap_write(dev->regmap, 0x17, 0x81);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) usleep_range(10000, 50000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) ret = regmap_write(dev->regmap, 0x05, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) ret = regmap_write(dev->regmap, 0x11, 0x0a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) for (i = 0; i < ARRAY_SIZE(reg_vals); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) ret = regmap_write(dev->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) reg_vals[i].reg, reg_vals[i].val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) dev_info(&dev->client->dev, "Montage M88RS6000 internal tuner successfully identified\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) fe->tuner_priv = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) memcpy(&fe->ops.tuner_ops, &m88rs6000t_tuner_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) sizeof(struct dvb_tuner_ops));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) i2c_set_clientdata(client, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) dev_dbg(&client->dev, "failed=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) kfree(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) static int m88rs6000t_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) struct m88rs6000t_dev *dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) struct dvb_frontend *fe = dev->cfg.fe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) dev_dbg(&client->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) memset(&fe->ops.tuner_ops, 0, sizeof(struct dvb_tuner_ops));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) fe->tuner_priv = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) kfree(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) static const struct i2c_device_id m88rs6000t_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) {"m88rs6000t", 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) MODULE_DEVICE_TABLE(i2c, m88rs6000t_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) static struct i2c_driver m88rs6000t_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) .name = "m88rs6000t",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) .probe = m88rs6000t_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) .remove = m88rs6000t_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) .id_table = m88rs6000t_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) module_i2c_driver(m88rs6000t_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) MODULE_AUTHOR("Max nibble <nibble.max@gmail.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) MODULE_DESCRIPTION("Montage M88RS6000 internal tuner driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) MODULE_LICENSE("GPL");