blob: 0ced01f1012e4675dc478de4a73c714075f6619e [file] [log] [blame]
Thomas Mair82041c02012-05-18 14:47:40 -03001/*
2 * Realtek RTL2832 DVB-T demodulator driver
3 *
4 * Copyright (C) 2012 Thomas Mair <thomas.mair86@gmail.com>
Antti Palosaari75c24002014-12-16 13:54:23 -03005 * Copyright (C) 2012-2014 Antti Palosaari <crope@iki.fi>
Thomas Mair82041c02012-05-18 14:47:40 -03006 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22#include "rtl2832_priv.h"
Thomas Mair82041c02012-05-18 14:47:40 -030023
Mauro Carvalho Chehab298f18a2012-07-05 12:16:26 -030024#define REG_MASK(b) (BIT(b + 1) - 1)
Thomas Mair82041c02012-05-18 14:47:40 -030025
26static const struct rtl2832_reg_entry registers[] = {
Antti Palosaarieec21be2014-12-15 01:17:25 -030027 [DVBT_SOFT_RST] = {0x101, 2, 2},
28 [DVBT_IIC_REPEAT] = {0x101, 3, 3},
29 [DVBT_TR_WAIT_MIN_8K] = {0x188, 11, 2},
30 [DVBT_RSD_BER_FAIL_VAL] = {0x18f, 15, 0},
31 [DVBT_EN_BK_TRK] = {0x1a6, 7, 7},
32 [DVBT_AD_EN_REG] = {0x008, 7, 7},
33 [DVBT_AD_EN_REG1] = {0x008, 6, 6},
34 [DVBT_EN_BBIN] = {0x1b1, 0, 0},
35 [DVBT_MGD_THD0] = {0x195, 7, 0},
36 [DVBT_MGD_THD1] = {0x196, 7, 0},
37 [DVBT_MGD_THD2] = {0x197, 7, 0},
38 [DVBT_MGD_THD3] = {0x198, 7, 0},
39 [DVBT_MGD_THD4] = {0x199, 7, 0},
40 [DVBT_MGD_THD5] = {0x19a, 7, 0},
41 [DVBT_MGD_THD6] = {0x19b, 7, 0},
42 [DVBT_MGD_THD7] = {0x19c, 7, 0},
43 [DVBT_EN_CACQ_NOTCH] = {0x161, 4, 4},
44 [DVBT_AD_AV_REF] = {0x009, 6, 0},
45 [DVBT_REG_PI] = {0x00a, 2, 0},
46 [DVBT_PIP_ON] = {0x021, 3, 3},
47 [DVBT_SCALE1_B92] = {0x292, 7, 0},
48 [DVBT_SCALE1_B93] = {0x293, 7, 0},
49 [DVBT_SCALE1_BA7] = {0x2a7, 7, 0},
50 [DVBT_SCALE1_BA9] = {0x2a9, 7, 0},
51 [DVBT_SCALE1_BAA] = {0x2aa, 7, 0},
52 [DVBT_SCALE1_BAB] = {0x2ab, 7, 0},
53 [DVBT_SCALE1_BAC] = {0x2ac, 7, 0},
54 [DVBT_SCALE1_BB0] = {0x2b0, 7, 0},
55 [DVBT_SCALE1_BB1] = {0x2b1, 7, 0},
56 [DVBT_KB_P1] = {0x164, 3, 1},
57 [DVBT_KB_P2] = {0x164, 6, 4},
58 [DVBT_KB_P3] = {0x165, 2, 0},
59 [DVBT_OPT_ADC_IQ] = {0x006, 5, 4},
60 [DVBT_AD_AVI] = {0x009, 1, 0},
61 [DVBT_AD_AVQ] = {0x009, 3, 2},
62 [DVBT_K1_CR_STEP12] = {0x2ad, 9, 4},
63 [DVBT_TRK_KS_P2] = {0x16f, 2, 0},
64 [DVBT_TRK_KS_I2] = {0x170, 5, 3},
65 [DVBT_TR_THD_SET2] = {0x172, 3, 0},
66 [DVBT_TRK_KC_P2] = {0x173, 5, 3},
67 [DVBT_TRK_KC_I2] = {0x175, 2, 0},
68 [DVBT_CR_THD_SET2] = {0x176, 7, 6},
69 [DVBT_PSET_IFFREQ] = {0x119, 21, 0},
70 [DVBT_SPEC_INV] = {0x115, 0, 0},
71 [DVBT_RSAMP_RATIO] = {0x19f, 27, 2},
72 [DVBT_CFREQ_OFF_RATIO] = {0x19d, 23, 4},
73 [DVBT_FSM_STAGE] = {0x351, 6, 3},
74 [DVBT_RX_CONSTEL] = {0x33c, 3, 2},
75 [DVBT_RX_HIER] = {0x33c, 6, 4},
76 [DVBT_RX_C_RATE_LP] = {0x33d, 2, 0},
77 [DVBT_RX_C_RATE_HP] = {0x33d, 5, 3},
78 [DVBT_GI_IDX] = {0x351, 1, 0},
79 [DVBT_FFT_MODE_IDX] = {0x351, 2, 2},
80 [DVBT_RSD_BER_EST] = {0x34e, 15, 0},
81 [DVBT_CE_EST_EVM] = {0x40c, 15, 0},
82 [DVBT_RF_AGC_VAL] = {0x35b, 13, 0},
83 [DVBT_IF_AGC_VAL] = {0x359, 13, 0},
84 [DVBT_DAGC_VAL] = {0x305, 7, 0},
85 [DVBT_SFREQ_OFF] = {0x318, 13, 0},
86 [DVBT_CFREQ_OFF] = {0x35f, 17, 0},
87 [DVBT_POLAR_RF_AGC] = {0x00e, 1, 1},
88 [DVBT_POLAR_IF_AGC] = {0x00e, 0, 0},
89 [DVBT_AAGC_HOLD] = {0x104, 5, 5},
90 [DVBT_EN_RF_AGC] = {0x104, 6, 6},
91 [DVBT_EN_IF_AGC] = {0x104, 7, 7},
92 [DVBT_IF_AGC_MIN] = {0x108, 7, 0},
93 [DVBT_IF_AGC_MAX] = {0x109, 7, 0},
94 [DVBT_RF_AGC_MIN] = {0x10a, 7, 0},
95 [DVBT_RF_AGC_MAX] = {0x10b, 7, 0},
96 [DVBT_IF_AGC_MAN] = {0x10c, 6, 6},
97 [DVBT_IF_AGC_MAN_VAL] = {0x10c, 13, 0},
98 [DVBT_RF_AGC_MAN] = {0x10e, 6, 6},
99 [DVBT_RF_AGC_MAN_VAL] = {0x10e, 13, 0},
100 [DVBT_DAGC_TRG_VAL] = {0x112, 7, 0},
101 [DVBT_AGC_TARG_VAL_0] = {0x102, 0, 0},
102 [DVBT_AGC_TARG_VAL_8_1] = {0x103, 7, 0},
103 [DVBT_AAGC_LOOP_GAIN] = {0x1c7, 5, 1},
104 [DVBT_LOOP_GAIN2_3_0] = {0x104, 4, 1},
105 [DVBT_LOOP_GAIN2_4] = {0x105, 7, 7},
106 [DVBT_LOOP_GAIN3] = {0x1c8, 4, 0},
107 [DVBT_VTOP1] = {0x106, 5, 0},
108 [DVBT_VTOP2] = {0x1c9, 5, 0},
109 [DVBT_VTOP3] = {0x1ca, 5, 0},
110 [DVBT_KRF1] = {0x1cb, 7, 0},
111 [DVBT_KRF2] = {0x107, 7, 0},
112 [DVBT_KRF3] = {0x1cd, 7, 0},
113 [DVBT_KRF4] = {0x1ce, 7, 0},
114 [DVBT_EN_GI_PGA] = {0x1e5, 0, 0},
115 [DVBT_THD_LOCK_UP] = {0x1d9, 8, 0},
116 [DVBT_THD_LOCK_DW] = {0x1db, 8, 0},
117 [DVBT_THD_UP1] = {0x1dd, 7, 0},
118 [DVBT_THD_DW1] = {0x1de, 7, 0},
119 [DVBT_INTER_CNT_LEN] = {0x1d8, 3, 0},
120 [DVBT_GI_PGA_STATE] = {0x1e6, 3, 3},
121 [DVBT_EN_AGC_PGA] = {0x1d7, 0, 0},
122 [DVBT_CKOUTPAR] = {0x17b, 5, 5},
123 [DVBT_CKOUT_PWR] = {0x17b, 6, 6},
124 [DVBT_SYNC_DUR] = {0x17b, 7, 7},
125 [DVBT_ERR_DUR] = {0x17c, 0, 0},
126 [DVBT_SYNC_LVL] = {0x17c, 1, 1},
127 [DVBT_ERR_LVL] = {0x17c, 2, 2},
128 [DVBT_VAL_LVL] = {0x17c, 3, 3},
129 [DVBT_SERIAL] = {0x17c, 4, 4},
130 [DVBT_SER_LSB] = {0x17c, 5, 5},
131 [DVBT_CDIV_PH0] = {0x17d, 3, 0},
132 [DVBT_CDIV_PH1] = {0x17d, 7, 4},
133 [DVBT_MPEG_IO_OPT_2_2] = {0x006, 7, 7},
134 [DVBT_MPEG_IO_OPT_1_0] = {0x007, 7, 6},
135 [DVBT_CKOUTPAR_PIP] = {0x0b7, 4, 4},
136 [DVBT_CKOUT_PWR_PIP] = {0x0b7, 3, 3},
137 [DVBT_SYNC_LVL_PIP] = {0x0b7, 2, 2},
138 [DVBT_ERR_LVL_PIP] = {0x0b7, 1, 1},
139 [DVBT_VAL_LVL_PIP] = {0x0b7, 0, 0},
140 [DVBT_CKOUTPAR_PID] = {0x0b9, 4, 4},
141 [DVBT_CKOUT_PWR_PID] = {0x0b9, 3, 3},
142 [DVBT_SYNC_LVL_PID] = {0x0b9, 2, 2},
143 [DVBT_ERR_LVL_PID] = {0x0b9, 1, 1},
144 [DVBT_VAL_LVL_PID] = {0x0b9, 0, 0},
145 [DVBT_SM_PASS] = {0x193, 11, 0},
146 [DVBT_AD7_SETTING] = {0x011, 15, 0},
147 [DVBT_RSSI_R] = {0x301, 6, 0},
148 [DVBT_ACI_DET_IND] = {0x312, 0, 0},
149 [DVBT_REG_MON] = {0x00d, 1, 0},
150 [DVBT_REG_MONSEL] = {0x00d, 2, 2},
151 [DVBT_REG_GPE] = {0x00d, 7, 7},
152 [DVBT_REG_GPO] = {0x010, 0, 0},
153 [DVBT_REG_4MSEL] = {0x013, 0, 0},
Thomas Mair82041c02012-05-18 14:47:40 -0300154};
155
Antti Palosaari038c6f22014-12-13 00:37:43 -0300156static int rtl2832_rd_demod_reg(struct rtl2832_dev *dev, int reg, u32 *val)
Thomas Mair82041c02012-05-18 14:47:40 -0300157{
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300158 struct i2c_client *client = dev->client;
Antti Palosaaricd559e02014-12-16 13:37:18 -0300159 int ret, i;
Antti Palosaarieec21be2014-12-15 01:17:25 -0300160 u16 reg_start_addr;
Antti Palosaaricd559e02014-12-16 13:37:18 -0300161 u8 msb, lsb, reading[4], len;
162 u32 reading_tmp, mask;
Thomas Mair82041c02012-05-18 14:47:40 -0300163
164 reg_start_addr = registers[reg].start_address;
165 msb = registers[reg].msb;
166 lsb = registers[reg].lsb;
Thomas Mair82041c02012-05-18 14:47:40 -0300167 len = (msb >> 3) + 1;
Mauro Carvalho Chehab298f18a2012-07-05 12:16:26 -0300168 mask = REG_MASK(msb - lsb);
Thomas Mair82041c02012-05-18 14:47:40 -0300169
Peter Rosin1cf79db2016-05-04 22:15:33 +0200170 ret = regmap_bulk_read(dev->regmap, reg_start_addr, reading, len);
Thomas Mair82041c02012-05-18 14:47:40 -0300171 if (ret)
172 goto err;
173
174 reading_tmp = 0;
175 for (i = 0; i < len; i++)
176 reading_tmp |= reading[i] << ((len - 1 - i) * 8);
177
178 *val = (reading_tmp >> lsb) & mask;
179
Antti Palosaaricd559e02014-12-16 13:37:18 -0300180 return 0;
Thomas Mair82041c02012-05-18 14:47:40 -0300181err:
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300182 dev_dbg(&client->dev, "failed=%d\n", ret);
Thomas Mair82041c02012-05-18 14:47:40 -0300183 return ret;
Thomas Mair82041c02012-05-18 14:47:40 -0300184}
185
Antti Palosaari038c6f22014-12-13 00:37:43 -0300186static int rtl2832_wr_demod_reg(struct rtl2832_dev *dev, int reg, u32 val)
Thomas Mair82041c02012-05-18 14:47:40 -0300187{
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300188 struct i2c_client *client = dev->client;
Thomas Mair82041c02012-05-18 14:47:40 -0300189 int ret, i;
Antti Palosaarieec21be2014-12-15 01:17:25 -0300190 u16 reg_start_addr;
Antti Palosaaricd559e02014-12-16 13:37:18 -0300191 u8 msb, lsb, reading[4], writing[4], len;
192 u32 reading_tmp, writing_tmp, mask;
Thomas Mair82041c02012-05-18 14:47:40 -0300193
194 reg_start_addr = registers[reg].start_address;
195 msb = registers[reg].msb;
196 lsb = registers[reg].lsb;
Thomas Mair82041c02012-05-18 14:47:40 -0300197 len = (msb >> 3) + 1;
Mauro Carvalho Chehab298f18a2012-07-05 12:16:26 -0300198 mask = REG_MASK(msb - lsb);
Thomas Mair82041c02012-05-18 14:47:40 -0300199
Peter Rosin1cf79db2016-05-04 22:15:33 +0200200 ret = regmap_bulk_read(dev->regmap, reg_start_addr, reading, len);
Thomas Mair82041c02012-05-18 14:47:40 -0300201 if (ret)
202 goto err;
203
204 reading_tmp = 0;
205 for (i = 0; i < len; i++)
206 reading_tmp |= reading[i] << ((len - 1 - i) * 8);
207
208 writing_tmp = reading_tmp & ~(mask << lsb);
209 writing_tmp |= ((val & mask) << lsb);
210
Thomas Mair82041c02012-05-18 14:47:40 -0300211 for (i = 0; i < len; i++)
212 writing[i] = (writing_tmp >> ((len - 1 - i) * 8)) & 0xff;
213
Peter Rosin1cf79db2016-05-04 22:15:33 +0200214 ret = regmap_bulk_write(dev->regmap, reg_start_addr, writing, len);
Thomas Mair82041c02012-05-18 14:47:40 -0300215 if (ret)
216 goto err;
217
Antti Palosaaricd559e02014-12-16 13:37:18 -0300218 return 0;
Thomas Mair82041c02012-05-18 14:47:40 -0300219err:
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300220 dev_dbg(&client->dev, "failed=%d\n", ret);
Thomas Mair82041c02012-05-18 14:47:40 -0300221 return ret;
Thomas Mair82041c02012-05-18 14:47:40 -0300222}
223
Mauro Carvalho Chehab884655a2013-04-09 22:16:52 -0300224static int rtl2832_set_if(struct dvb_frontend *fe, u32 if_freq)
225{
Antti Palosaari038c6f22014-12-13 00:37:43 -0300226 struct rtl2832_dev *dev = fe->demodulator_priv;
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300227 struct i2c_client *client = dev->client;
Mauro Carvalho Chehab884655a2013-04-09 22:16:52 -0300228 int ret;
229 u64 pset_iffreq;
230 u8 en_bbin = (if_freq == 0 ? 0x1 : 0x0);
231
232 /*
233 * PSET_IFFREQ = - floor((IfFreqHz % CrystalFreqHz) * pow(2, 22)
234 * / CrystalFreqHz)
235 */
Antti Palosaarie1174d72014-12-13 05:26:27 -0300236 pset_iffreq = if_freq % dev->pdata->clk;
Mauro Carvalho Chehab884655a2013-04-09 22:16:52 -0300237 pset_iffreq *= 0x400000;
Antti Palosaarie1174d72014-12-13 05:26:27 -0300238 pset_iffreq = div_u64(pset_iffreq, dev->pdata->clk);
Mauro Carvalho Chehabc8832e82013-04-15 19:44:39 -0300239 pset_iffreq = -pset_iffreq;
Mauro Carvalho Chehab884655a2013-04-09 22:16:52 -0300240 pset_iffreq = pset_iffreq & 0x3fffff;
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300241 dev_dbg(&client->dev, "if_frequency=%d pset_iffreq=%08x\n",
242 if_freq, (unsigned)pset_iffreq);
Mauro Carvalho Chehabc8832e82013-04-15 19:44:39 -0300243
Antti Palosaari038c6f22014-12-13 00:37:43 -0300244 ret = rtl2832_wr_demod_reg(dev, DVBT_EN_BBIN, en_bbin);
Mauro Carvalho Chehab884655a2013-04-09 22:16:52 -0300245 if (ret)
Antti Palosaaricd559e02014-12-16 13:37:18 -0300246 goto err;
Mauro Carvalho Chehab884655a2013-04-09 22:16:52 -0300247
Antti Palosaari038c6f22014-12-13 00:37:43 -0300248 ret = rtl2832_wr_demod_reg(dev, DVBT_PSET_IFFREQ, pset_iffreq);
Antti Palosaaricd559e02014-12-16 13:37:18 -0300249 if (ret)
250 goto err;
Mauro Carvalho Chehab884655a2013-04-09 22:16:52 -0300251
Antti Palosaaricd559e02014-12-16 13:37:18 -0300252 return 0;
253err:
254 dev_dbg(&client->dev, "failed=%d\n", ret);
Antti Palosaari3ca24182013-10-13 00:06:44 -0300255 return ret;
Mauro Carvalho Chehab884655a2013-04-09 22:16:52 -0300256}
257
Thomas Mair82041c02012-05-18 14:47:40 -0300258static int rtl2832_init(struct dvb_frontend *fe)
259{
Antti Palosaari038c6f22014-12-13 00:37:43 -0300260 struct rtl2832_dev *dev = fe->demodulator_priv;
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300261 struct i2c_client *client = dev->client;
Antti Palosaari19d273d2014-12-14 06:55:43 -0300262 struct dtv_frontend_properties *c = &dev->fe.dtv_property_cache;
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300263 const struct rtl2832_reg_value *init;
Mauro Carvalho Chehab884655a2013-04-09 22:16:52 -0300264 int i, ret, len;
Thomas Mair82041c02012-05-18 14:47:40 -0300265 /* initialization values for the demodulator registers */
266 struct rtl2832_reg_value rtl2832_initial_regs[] = {
267 {DVBT_AD_EN_REG, 0x1},
268 {DVBT_AD_EN_REG1, 0x1},
269 {DVBT_RSD_BER_FAIL_VAL, 0x2800},
270 {DVBT_MGD_THD0, 0x10},
271 {DVBT_MGD_THD1, 0x20},
272 {DVBT_MGD_THD2, 0x20},
273 {DVBT_MGD_THD3, 0x40},
274 {DVBT_MGD_THD4, 0x22},
275 {DVBT_MGD_THD5, 0x32},
276 {DVBT_MGD_THD6, 0x37},
277 {DVBT_MGD_THD7, 0x39},
278 {DVBT_EN_BK_TRK, 0x0},
279 {DVBT_EN_CACQ_NOTCH, 0x0},
280 {DVBT_AD_AV_REF, 0x2a},
281 {DVBT_REG_PI, 0x6},
282 {DVBT_PIP_ON, 0x0},
283 {DVBT_CDIV_PH0, 0x8},
284 {DVBT_CDIV_PH1, 0x8},
285 {DVBT_SCALE1_B92, 0x4},
286 {DVBT_SCALE1_B93, 0xb0},
287 {DVBT_SCALE1_BA7, 0x78},
288 {DVBT_SCALE1_BA9, 0x28},
289 {DVBT_SCALE1_BAA, 0x59},
290 {DVBT_SCALE1_BAB, 0x83},
291 {DVBT_SCALE1_BAC, 0xd4},
292 {DVBT_SCALE1_BB0, 0x65},
293 {DVBT_SCALE1_BB1, 0x43},
294 {DVBT_KB_P1, 0x1},
295 {DVBT_KB_P2, 0x4},
296 {DVBT_KB_P3, 0x7},
297 {DVBT_K1_CR_STEP12, 0xa},
298 {DVBT_REG_GPE, 0x1},
299 {DVBT_SERIAL, 0x0},
300 {DVBT_CDIV_PH0, 0x9},
301 {DVBT_CDIV_PH1, 0x9},
302 {DVBT_MPEG_IO_OPT_2_2, 0x0},
303 {DVBT_MPEG_IO_OPT_1_0, 0x0},
304 {DVBT_TRK_KS_P2, 0x4},
305 {DVBT_TRK_KS_I2, 0x7},
306 {DVBT_TR_THD_SET2, 0x6},
307 {DVBT_TRK_KC_I2, 0x5},
308 {DVBT_CR_THD_SET2, 0x1},
Thomas Mair82041c02012-05-18 14:47:40 -0300309 };
310
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300311 dev_dbg(&client->dev, "\n");
Thomas Mair82041c02012-05-18 14:47:40 -0300312
Antti Palosaarid884aca2016-02-05 18:26:30 -0200313 ret = rtl2832_wr_demod_reg(dev, DVBT_SOFT_RST, 0x0);
314 if (ret)
315 goto err;
316
Thomas Mair82041c02012-05-18 14:47:40 -0300317 for (i = 0; i < ARRAY_SIZE(rtl2832_initial_regs); i++) {
Antti Palosaari038c6f22014-12-13 00:37:43 -0300318 ret = rtl2832_wr_demod_reg(dev, rtl2832_initial_regs[i].reg,
Thomas Mair82041c02012-05-18 14:47:40 -0300319 rtl2832_initial_regs[i].value);
320 if (ret)
321 goto err;
322 }
323
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300324 /* load tuner specific settings */
Antti Palosaarie1174d72014-12-13 05:26:27 -0300325 dev_dbg(&client->dev, "load settings for tuner=%02x\n",
326 dev->pdata->tuner);
327 switch (dev->pdata->tuner) {
Antti Palosaarif88aae92015-04-23 22:52:07 -0300328 case RTL2832_TUNER_FC2580:
329 len = ARRAY_SIZE(rtl2832_tuner_init_fc2580);
330 init = rtl2832_tuner_init_fc2580;
331 break;
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300332 case RTL2832_TUNER_FC0012:
333 case RTL2832_TUNER_FC0013:
334 len = ARRAY_SIZE(rtl2832_tuner_init_fc0012);
335 init = rtl2832_tuner_init_fc0012;
336 break;
Antti Palosaari5db41872012-09-11 22:27:08 -0300337 case RTL2832_TUNER_TUA9001:
338 len = ARRAY_SIZE(rtl2832_tuner_init_tua9001);
339 init = rtl2832_tuner_init_tua9001;
340 break;
Antti Palosaari7e688de2012-09-17 17:53:04 -0300341 case RTL2832_TUNER_E4000:
342 len = ARRAY_SIZE(rtl2832_tuner_init_e4000);
343 init = rtl2832_tuner_init_e4000;
344 break;
Mauro Carvalho Chehabfa4bfd22013-04-09 18:19:50 -0300345 case RTL2832_TUNER_R820T:
Antti Palosaaria26758e2013-10-30 00:36:38 -0300346 case RTL2832_TUNER_R828D:
Mauro Carvalho Chehabfa4bfd22013-04-09 18:19:50 -0300347 len = ARRAY_SIZE(rtl2832_tuner_init_r820t);
348 init = rtl2832_tuner_init_r820t;
349 break;
Olli Salonen699dcff2015-05-05 13:54:19 -0300350 case RTL2832_TUNER_SI2157:
351 len = ARRAY_SIZE(rtl2832_tuner_init_si2157);
352 init = rtl2832_tuner_init_si2157;
353 break;
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300354 default:
355 ret = -EINVAL;
356 goto err;
357 }
358
359 for (i = 0; i < len; i++) {
Antti Palosaari038c6f22014-12-13 00:37:43 -0300360 ret = rtl2832_wr_demod_reg(dev, init[i].reg, init[i].value);
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300361 if (ret)
362 goto err;
363 }
364
Antti Palosaari19d273d2014-12-14 06:55:43 -0300365 /* init stats here in order signal app which stats are supported */
Antti Palosaari25ef9f52014-12-14 11:00:50 -0300366 c->strength.len = 1;
367 c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
Antti Palosaari19d273d2014-12-14 06:55:43 -0300368 c->cnr.len = 1;
369 c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
Antti Palosaari6b4fd012014-12-14 09:59:20 -0300370 c->post_bit_error.len = 1;
371 c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
372 c->post_bit_count.len = 1;
373 c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
Antti Palosaari038c6f22014-12-13 00:37:43 -0300374 dev->sleeping = false;
Thomas Mair82041c02012-05-18 14:47:40 -0300375
Antti Palosaaricd559e02014-12-16 13:37:18 -0300376 return 0;
Thomas Mair82041c02012-05-18 14:47:40 -0300377err:
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300378 dev_dbg(&client->dev, "failed=%d\n", ret);
Thomas Mair82041c02012-05-18 14:47:40 -0300379 return ret;
380}
381
382static int rtl2832_sleep(struct dvb_frontend *fe)
383{
Antti Palosaari038c6f22014-12-13 00:37:43 -0300384 struct rtl2832_dev *dev = fe->demodulator_priv;
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300385 struct i2c_client *client = dev->client;
Antti Palosaaria08c3782014-12-16 14:51:33 -0300386 int ret;
Thomas Mair82041c02012-05-18 14:47:40 -0300387
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300388 dev_dbg(&client->dev, "\n");
Antti Palosaaria08c3782014-12-16 14:51:33 -0300389
Antti Palosaari038c6f22014-12-13 00:37:43 -0300390 dev->sleeping = true;
Antti Palosaari19d273d2014-12-14 06:55:43 -0300391 dev->fe_status = 0;
Antti Palosaaria08c3782014-12-16 14:51:33 -0300392
393 ret = rtl2832_wr_demod_reg(dev, DVBT_SOFT_RST, 0x1);
394 if (ret)
395 goto err;
396
Thomas Mair82041c02012-05-18 14:47:40 -0300397 return 0;
Antti Palosaaria08c3782014-12-16 14:51:33 -0300398err:
399 dev_dbg(&client->dev, "failed=%d\n", ret);
400 return ret;
Thomas Mair82041c02012-05-18 14:47:40 -0300401}
402
Mauro Carvalho Chehabb0944ea2012-10-27 11:24:37 -0300403static int rtl2832_get_tune_settings(struct dvb_frontend *fe,
Thomas Mair82041c02012-05-18 14:47:40 -0300404 struct dvb_frontend_tune_settings *s)
405{
Antti Palosaari038c6f22014-12-13 00:37:43 -0300406 struct rtl2832_dev *dev = fe->demodulator_priv;
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300407 struct i2c_client *client = dev->client;
Antti Palosaari298efdd2012-09-11 22:27:11 -0300408
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300409 dev_dbg(&client->dev, "\n");
Thomas Mair82041c02012-05-18 14:47:40 -0300410 s->min_delay_ms = 1000;
411 s->step_size = fe->ops.info.frequency_stepsize * 2;
412 s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
413 return 0;
414}
415
416static int rtl2832_set_frontend(struct dvb_frontend *fe)
417{
Antti Palosaari038c6f22014-12-13 00:37:43 -0300418 struct rtl2832_dev *dev = fe->demodulator_priv;
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300419 struct i2c_client *client = dev->client;
Thomas Mair82041c02012-05-18 14:47:40 -0300420 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
421 int ret, i, j;
422 u64 bw_mode, num, num2;
423 u32 resamp_ratio, cfreq_off_ratio;
Thomas Mair82041c02012-05-18 14:47:40 -0300424 static u8 bw_params[3][32] = {
425 /* 6 MHz bandwidth */
426 {
427 0xf5, 0xff, 0x15, 0x38, 0x5d, 0x6d, 0x52, 0x07, 0xfa, 0x2f,
428 0x53, 0xf5, 0x3f, 0xca, 0x0b, 0x91, 0xea, 0x30, 0x63, 0xb2,
429 0x13, 0xda, 0x0b, 0xc4, 0x18, 0x7e, 0x16, 0x66, 0x08, 0x67,
430 0x19, 0xe0,
431 },
432
433 /* 7 MHz bandwidth */
434 {
435 0xe7, 0xcc, 0xb5, 0xba, 0xe8, 0x2f, 0x67, 0x61, 0x00, 0xaf,
436 0x86, 0xf2, 0xbf, 0x59, 0x04, 0x11, 0xb6, 0x33, 0xa4, 0x30,
437 0x15, 0x10, 0x0a, 0x42, 0x18, 0xf8, 0x17, 0xd9, 0x07, 0x22,
438 0x19, 0x10,
439 },
440
441 /* 8 MHz bandwidth */
442 {
443 0x09, 0xf6, 0xd2, 0xa7, 0x9a, 0xc9, 0x27, 0x77, 0x06, 0xbf,
444 0xec, 0xf4, 0x4f, 0x0b, 0xfc, 0x01, 0x63, 0x35, 0x54, 0xa7,
445 0x16, 0x66, 0x08, 0xb4, 0x19, 0x6e, 0x19, 0x65, 0x05, 0xc8,
446 0x19, 0xe0,
447 },
448 };
449
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300450 dev_dbg(&client->dev, "frequency=%u bandwidth_hz=%u inversion=%u\n",
451 c->frequency, c->bandwidth_hz, c->inversion);
Thomas Mair82041c02012-05-18 14:47:40 -0300452
453 /* program tuner */
454 if (fe->ops.tuner_ops.set_params)
455 fe->ops.tuner_ops.set_params(fe);
456
Mauro Carvalho Chehabfa4bfd22013-04-09 18:19:50 -0300457 /* If the frontend has get_if_frequency(), use it */
458 if (fe->ops.tuner_ops.get_if_frequency) {
459 u32 if_freq;
Mauro Carvalho Chehabfa4bfd22013-04-09 18:19:50 -0300460
461 ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_freq);
462 if (ret)
463 goto err;
464
Mauro Carvalho Chehab884655a2013-04-09 22:16:52 -0300465 ret = rtl2832_set_if(fe, if_freq);
Mauro Carvalho Chehabfa4bfd22013-04-09 18:19:50 -0300466 if (ret)
467 goto err;
468 }
469
Thomas Mair82041c02012-05-18 14:47:40 -0300470 switch (c->bandwidth_hz) {
471 case 6000000:
472 i = 0;
473 bw_mode = 48000000;
474 break;
475 case 7000000:
476 i = 1;
477 bw_mode = 56000000;
478 break;
479 case 8000000:
480 i = 2;
481 bw_mode = 64000000;
482 break;
483 default:
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300484 dev_err(&client->dev, "invalid bandwidth_hz %u\n",
485 c->bandwidth_hz);
486 ret = -EINVAL;
487 goto err;
Thomas Mair82041c02012-05-18 14:47:40 -0300488 }
489
Hans-Frieder Vogtfc4b3fa2012-07-15 13:56:47 -0300490 for (j = 0; j < sizeof(bw_params[0]); j++) {
Peter Rosin1cf79db2016-05-04 22:15:33 +0200491 ret = regmap_bulk_write(dev->regmap,
492 0x11c + j, &bw_params[i][j], 1);
Thomas Mair82041c02012-05-18 14:47:40 -0300493 if (ret)
494 goto err;
495 }
496
497 /* calculate and set resample ratio
498 * RSAMP_RATIO = floor(CrystalFreqHz * 7 * pow(2, 22)
499 * / ConstWithBandwidthMode)
500 */
Antti Palosaarie1174d72014-12-13 05:26:27 -0300501 num = dev->pdata->clk * 7;
Thomas Mair82041c02012-05-18 14:47:40 -0300502 num *= 0x400000;
503 num = div_u64(num, bw_mode);
504 resamp_ratio = num & 0x3ffffff;
Antti Palosaari038c6f22014-12-13 00:37:43 -0300505 ret = rtl2832_wr_demod_reg(dev, DVBT_RSAMP_RATIO, resamp_ratio);
Thomas Mair82041c02012-05-18 14:47:40 -0300506 if (ret)
507 goto err;
508
509 /* calculate and set cfreq off ratio
510 * CFREQ_OFF_RATIO = - floor(ConstWithBandwidthMode * pow(2, 20)
511 * / (CrystalFreqHz * 7))
512 */
513 num = bw_mode << 20;
Antti Palosaarie1174d72014-12-13 05:26:27 -0300514 num2 = dev->pdata->clk * 7;
Thomas Mair82041c02012-05-18 14:47:40 -0300515 num = div_u64(num, num2);
516 num = -num;
517 cfreq_off_ratio = num & 0xfffff;
Antti Palosaari038c6f22014-12-13 00:37:43 -0300518 ret = rtl2832_wr_demod_reg(dev, DVBT_CFREQ_OFF_RATIO, cfreq_off_ratio);
Thomas Mair82041c02012-05-18 14:47:40 -0300519 if (ret)
520 goto err;
521
Thomas Mair82041c02012-05-18 14:47:40 -0300522 /* soft reset */
Antti Palosaari038c6f22014-12-13 00:37:43 -0300523 ret = rtl2832_wr_demod_reg(dev, DVBT_SOFT_RST, 0x1);
Thomas Mair82041c02012-05-18 14:47:40 -0300524 if (ret)
525 goto err;
526
Antti Palosaari038c6f22014-12-13 00:37:43 -0300527 ret = rtl2832_wr_demod_reg(dev, DVBT_SOFT_RST, 0x0);
Thomas Mair82041c02012-05-18 14:47:40 -0300528 if (ret)
529 goto err;
530
Antti Palosaaricd559e02014-12-16 13:37:18 -0300531 return 0;
Thomas Mair82041c02012-05-18 14:47:40 -0300532err:
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300533 dev_dbg(&client->dev, "failed=%d\n", ret);
Thomas Mair82041c02012-05-18 14:47:40 -0300534 return ret;
535}
536
Mauro Carvalho Chehab7e3e68b2016-02-04 12:58:30 -0200537static int rtl2832_get_frontend(struct dvb_frontend *fe,
538 struct dtv_frontend_properties *c)
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300539{
Antti Palosaari038c6f22014-12-13 00:37:43 -0300540 struct rtl2832_dev *dev = fe->demodulator_priv;
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300541 struct i2c_client *client = dev->client;
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300542 int ret;
543 u8 buf[3];
544
Antti Palosaari038c6f22014-12-13 00:37:43 -0300545 if (dev->sleeping)
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300546 return 0;
547
Peter Rosin1cf79db2016-05-04 22:15:33 +0200548 ret = regmap_bulk_read(dev->regmap, 0x33c, buf, 2);
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300549 if (ret)
550 goto err;
551
Peter Rosin1cf79db2016-05-04 22:15:33 +0200552 ret = regmap_bulk_read(dev->regmap, 0x351, &buf[2], 1);
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300553 if (ret)
554 goto err;
555
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300556 dev_dbg(&client->dev, "TPS=%*ph\n", 3, buf);
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300557
558 switch ((buf[0] >> 2) & 3) {
559 case 0:
560 c->modulation = QPSK;
561 break;
562 case 1:
563 c->modulation = QAM_16;
564 break;
565 case 2:
566 c->modulation = QAM_64;
567 break;
568 }
569
570 switch ((buf[2] >> 2) & 1) {
571 case 0:
572 c->transmission_mode = TRANSMISSION_MODE_2K;
573 break;
574 case 1:
575 c->transmission_mode = TRANSMISSION_MODE_8K;
576 }
577
578 switch ((buf[2] >> 0) & 3) {
579 case 0:
580 c->guard_interval = GUARD_INTERVAL_1_32;
581 break;
582 case 1:
583 c->guard_interval = GUARD_INTERVAL_1_16;
584 break;
585 case 2:
586 c->guard_interval = GUARD_INTERVAL_1_8;
587 break;
588 case 3:
589 c->guard_interval = GUARD_INTERVAL_1_4;
590 break;
591 }
592
593 switch ((buf[0] >> 4) & 7) {
594 case 0:
595 c->hierarchy = HIERARCHY_NONE;
596 break;
597 case 1:
598 c->hierarchy = HIERARCHY_1;
599 break;
600 case 2:
601 c->hierarchy = HIERARCHY_2;
602 break;
603 case 3:
604 c->hierarchy = HIERARCHY_4;
605 break;
606 }
607
608 switch ((buf[1] >> 3) & 7) {
609 case 0:
610 c->code_rate_HP = FEC_1_2;
611 break;
612 case 1:
613 c->code_rate_HP = FEC_2_3;
614 break;
615 case 2:
616 c->code_rate_HP = FEC_3_4;
617 break;
618 case 3:
619 c->code_rate_HP = FEC_5_6;
620 break;
621 case 4:
622 c->code_rate_HP = FEC_7_8;
623 break;
624 }
625
626 switch ((buf[1] >> 0) & 7) {
627 case 0:
628 c->code_rate_LP = FEC_1_2;
629 break;
630 case 1:
631 c->code_rate_LP = FEC_2_3;
632 break;
633 case 2:
634 c->code_rate_LP = FEC_3_4;
635 break;
636 case 3:
637 c->code_rate_LP = FEC_5_6;
638 break;
639 case 4:
640 c->code_rate_LP = FEC_7_8;
641 break;
642 }
643
644 return 0;
645err:
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300646 dev_dbg(&client->dev, "failed=%d\n", ret);
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300647 return ret;
648}
649
Mauro Carvalho Chehab0df289a2015-06-07 14:53:52 -0300650static int rtl2832_read_status(struct dvb_frontend *fe, enum fe_status *status)
Thomas Mair82041c02012-05-18 14:47:40 -0300651{
Antti Palosaari038c6f22014-12-13 00:37:43 -0300652 struct rtl2832_dev *dev = fe->demodulator_priv;
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300653 struct i2c_client *client = dev->client;
Antti Palosaari426508e2016-02-06 20:12:05 -0200654 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
Thomas Mair82041c02012-05-18 14:47:40 -0300655 int ret;
Luis de Bethencourt20357752015-02-11 08:08:51 -0300656 u32 uninitialized_var(tmp);
Antti Palosaari426508e2016-02-06 20:12:05 -0200657 u8 u8tmp, buf[2];
658 u16 u16tmp;
Thomas Mair82041c02012-05-18 14:47:40 -0300659
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300660 dev_dbg(&client->dev, "\n");
661
662 *status = 0;
Antti Palosaari038c6f22014-12-13 00:37:43 -0300663 if (dev->sleeping)
Thomas Mair82041c02012-05-18 14:47:40 -0300664 return 0;
665
Antti Palosaari038c6f22014-12-13 00:37:43 -0300666 ret = rtl2832_rd_demod_reg(dev, DVBT_FSM_STAGE, &tmp);
Thomas Mair82041c02012-05-18 14:47:40 -0300667 if (ret)
668 goto err;
669
670 if (tmp == 11) {
671 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
672 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
Antti Palosaari1c7da402014-12-14 12:15:55 -0300673 } else if (tmp == 10) {
Thomas Mair82041c02012-05-18 14:47:40 -0300674 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
675 FE_HAS_VITERBI;
Antti Palosaari1c7da402014-12-14 12:15:55 -0300676 }
Thomas Mair82041c02012-05-18 14:47:40 -0300677
Antti Palosaari19d273d2014-12-14 06:55:43 -0300678 dev->fe_status = *status;
Antti Palosaari19d273d2014-12-14 06:55:43 -0300679
Antti Palosaari25ef9f52014-12-14 11:00:50 -0300680 /* signal strength */
681 if (dev->fe_status & FE_HAS_SIGNAL) {
682 /* read digital AGC */
Peter Rosin1cf79db2016-05-04 22:15:33 +0200683 ret = regmap_bulk_read(dev->regmap, 0x305, &u8tmp, 1);
Antti Palosaari25ef9f52014-12-14 11:00:50 -0300684 if (ret)
685 goto err;
686
687 dev_dbg(&client->dev, "digital agc=%02x", u8tmp);
688
689 u8tmp = ~u8tmp;
690 u16tmp = u8tmp << 8 | u8tmp << 0;
691
692 c->strength.stat[0].scale = FE_SCALE_RELATIVE;
693 c->strength.stat[0].uvalue = u16tmp;
694 } else {
695 c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
696 }
697
Antti Palosaari19d273d2014-12-14 06:55:43 -0300698 /* CNR */
699 if (dev->fe_status & FE_HAS_VITERBI) {
700 unsigned hierarchy, constellation;
701 #define CONSTELLATION_NUM 3
702 #define HIERARCHY_NUM 4
703 static const u32 constant[CONSTELLATION_NUM][HIERARCHY_NUM] = {
704 {85387325, 85387325, 85387325, 85387325},
705 {86676178, 86676178, 87167949, 87795660},
706 {87659938, 87659938, 87885178, 88241743},
707 };
708
Peter Rosin1cf79db2016-05-04 22:15:33 +0200709 ret = regmap_bulk_read(dev->regmap, 0x33c, &u8tmp, 1);
Antti Palosaari19d273d2014-12-14 06:55:43 -0300710 if (ret)
711 goto err;
712
713 constellation = (u8tmp >> 2) & 0x03; /* [3:2] */
714 if (constellation > CONSTELLATION_NUM - 1)
Antti Palosaari426508e2016-02-06 20:12:05 -0200715 goto err;
Antti Palosaari19d273d2014-12-14 06:55:43 -0300716
717 hierarchy = (u8tmp >> 4) & 0x07; /* [6:4] */
718 if (hierarchy > HIERARCHY_NUM - 1)
Antti Palosaari426508e2016-02-06 20:12:05 -0200719 goto err;
Antti Palosaari19d273d2014-12-14 06:55:43 -0300720
Peter Rosin1cf79db2016-05-04 22:15:33 +0200721 ret = regmap_bulk_read(dev->regmap, 0x40c, buf, 2);
Antti Palosaari19d273d2014-12-14 06:55:43 -0300722 if (ret)
723 goto err;
724
725 u16tmp = buf[0] << 8 | buf[1] << 0;
726 if (u16tmp)
727 tmp = (constant[constellation][hierarchy] -
728 intlog10(u16tmp)) / ((1 << 24) / 10000);
729 else
730 tmp = 0;
731
732 dev_dbg(&client->dev, "cnr raw=%u\n", u16tmp);
733
734 c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
735 c->cnr.stat[0].svalue = tmp;
736 } else {
737 c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
738 }
739
Antti Palosaari6b4fd012014-12-14 09:59:20 -0300740 /* BER */
741 if (dev->fe_status & FE_HAS_LOCK) {
Peter Rosin1cf79db2016-05-04 22:15:33 +0200742 ret = regmap_bulk_read(dev->regmap, 0x34e, buf, 2);
Antti Palosaari6b4fd012014-12-14 09:59:20 -0300743 if (ret)
744 goto err;
745
746 u16tmp = buf[0] << 8 | buf[1] << 0;
747 dev->post_bit_error += u16tmp;
748 dev->post_bit_count += 1000000;
749
750 dev_dbg(&client->dev, "ber errors=%u total=1000000\n", u16tmp);
751
752 c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
753 c->post_bit_error.stat[0].uvalue = dev->post_bit_error;
754 c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
755 c->post_bit_count.stat[0].uvalue = dev->post_bit_count;
756 } else {
757 c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
758 c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
759 }
760
Antti Palosaari426508e2016-02-06 20:12:05 -0200761 return 0;
Antti Palosaari19d273d2014-12-14 06:55:43 -0300762err:
763 dev_dbg(&client->dev, "failed=%d\n", ret);
Antti Palosaari426508e2016-02-06 20:12:05 -0200764 return ret;
765}
766
767static int rtl2832_read_snr(struct dvb_frontend *fe, u16 *snr)
768{
769 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
770
771 /* report SNR in resolution of 0.1 dB */
772 if (c->cnr.stat[0].scale == FE_SCALE_DECIBEL)
773 *snr = div_s64(c->cnr.stat[0].svalue, 100);
774 else
775 *snr = 0;
776
777 return 0;
778}
779
780static int rtl2832_read_ber(struct dvb_frontend *fe, u32 *ber)
781{
782 struct rtl2832_dev *dev = fe->demodulator_priv;
783
784 *ber = (dev->post_bit_error - dev->post_bit_error_prev);
785 dev->post_bit_error_prev = dev->post_bit_error;
786
787 return 0;
Antti Palosaari19d273d2014-12-14 06:55:43 -0300788}
789
Antti Palosaari92d20d92014-02-08 03:50:04 -0300790/*
Antti Palosaarid1016582014-12-14 04:45:57 -0300791 * I2C gate/mux/repeater logic
Antti Palosaarid1016582014-12-14 04:45:57 -0300792 * There is delay mechanism to avoid unneeded I2C gate open / close. Gate close
793 * is delayed here a little bit in order to see if there is sequence of I2C
Antti Palosaari92d20d92014-02-08 03:50:04 -0300794 * messages sent to same I2C bus.
Antti Palosaari92d20d92014-02-08 03:50:04 -0300795 */
796static void rtl2832_i2c_gate_work(struct work_struct *work)
Antti Palosaari8823f022013-11-26 12:53:46 -0300797{
Antti Palosaarid1016582014-12-14 04:45:57 -0300798 struct rtl2832_dev *dev = container_of(work, struct rtl2832_dev, i2c_gate_work.work);
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300799 struct i2c_client *client = dev->client;
Antti Palosaari0ea872d2013-12-03 18:19:39 -0300800 int ret;
Antti Palosaari8823f022013-11-26 12:53:46 -0300801
Antti Palosaarid1016582014-12-14 04:45:57 -0300802 /* close gate */
Peter Rosin1cf79db2016-05-04 22:15:33 +0200803 ret = regmap_update_bits(dev->regmap, 0x101, 0x08, 0x00);
Antti Palosaarid1016582014-12-14 04:45:57 -0300804 if (ret)
Antti Palosaari92d20d92014-02-08 03:50:04 -0300805 goto err;
806
Antti Palosaari92d20d92014-02-08 03:50:04 -0300807 return;
808err:
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300809 dev_dbg(&client->dev, "failed=%d\n", ret);
Antti Palosaari92d20d92014-02-08 03:50:04 -0300810}
811
Peter Rosincddcc402016-04-20 08:41:25 +0200812static int rtl2832_select(struct i2c_mux_core *muxc, u32 chan_id)
Antti Palosaari92d20d92014-02-08 03:50:04 -0300813{
Peter Rosincddcc402016-04-20 08:41:25 +0200814 struct rtl2832_dev *dev = i2c_mux_priv(muxc);
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300815 struct i2c_client *client = dev->client;
Antti Palosaari92d20d92014-02-08 03:50:04 -0300816 int ret;
Antti Palosaari92d20d92014-02-08 03:50:04 -0300817
818 /* terminate possible gate closing */
Antti Palosaarid1016582014-12-14 04:45:57 -0300819 cancel_delayed_work(&dev->i2c_gate_work);
Antti Palosaari92d20d92014-02-08 03:50:04 -0300820
Peter Rosin1cf79db2016-05-04 22:15:33 +0200821 /* open gate */
Antti Palosaari0d117902014-12-18 06:30:32 -0300822 ret = regmap_update_bits(dev->regmap, 0x101, 0x08, 0x08);
Antti Palosaarid1016582014-12-14 04:45:57 -0300823 if (ret)
Antti Palosaari0ea872d2013-12-03 18:19:39 -0300824 goto err;
825
Antti Palosaari0ea872d2013-12-03 18:19:39 -0300826 return 0;
827err:
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300828 dev_dbg(&client->dev, "failed=%d\n", ret);
Antti Palosaarid1016582014-12-14 04:45:57 -0300829 return ret;
Antti Palosaari8823f022013-11-26 12:53:46 -0300830}
831
Peter Rosincddcc402016-04-20 08:41:25 +0200832static int rtl2832_deselect(struct i2c_mux_core *muxc, u32 chan_id)
Antti Palosaari92d20d92014-02-08 03:50:04 -0300833{
Peter Rosincddcc402016-04-20 08:41:25 +0200834 struct rtl2832_dev *dev = i2c_mux_priv(muxc);
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300835
Antti Palosaari038c6f22014-12-13 00:37:43 -0300836 schedule_delayed_work(&dev->i2c_gate_work, usecs_to_jiffies(100));
Antti Palosaari92d20d92014-02-08 03:50:04 -0300837 return 0;
838}
839
Thomas Mair82041c02012-05-18 14:47:40 -0300840static struct dvb_frontend_ops rtl2832_ops = {
841 .delsys = { SYS_DVBT },
842 .info = {
843 .name = "Realtek RTL2832 (DVB-T)",
844 .frequency_min = 174000000,
845 .frequency_max = 862000000,
846 .frequency_stepsize = 166667,
847 .caps = FE_CAN_FEC_1_2 |
848 FE_CAN_FEC_2_3 |
849 FE_CAN_FEC_3_4 |
850 FE_CAN_FEC_5_6 |
851 FE_CAN_FEC_7_8 |
852 FE_CAN_FEC_AUTO |
853 FE_CAN_QPSK |
854 FE_CAN_QAM_16 |
855 FE_CAN_QAM_64 |
856 FE_CAN_QAM_AUTO |
857 FE_CAN_TRANSMISSION_MODE_AUTO |
858 FE_CAN_GUARD_INTERVAL_AUTO |
859 FE_CAN_HIERARCHY_AUTO |
860 FE_CAN_RECOVER |
861 FE_CAN_MUTE_TS
862 },
863
Thomas Mair82041c02012-05-18 14:47:40 -0300864 .init = rtl2832_init,
865 .sleep = rtl2832_sleep,
866
867 .get_tune_settings = rtl2832_get_tune_settings,
868
869 .set_frontend = rtl2832_set_frontend,
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300870 .get_frontend = rtl2832_get_frontend,
Thomas Mair82041c02012-05-18 14:47:40 -0300871
872 .read_status = rtl2832_read_status,
Antti Palosaari73983492012-08-21 19:56:21 -0300873 .read_snr = rtl2832_read_snr,
Antti Palosaaridb32d742012-08-21 19:56:22 -0300874 .read_ber = rtl2832_read_ber,
Thomas Mair82041c02012-05-18 14:47:40 -0300875};
876
Antti Palosaaridcadb822014-12-14 16:23:28 -0300877static bool rtl2832_volatile_reg(struct device *dev, unsigned int reg)
878{
879 switch (reg) {
880 case 0x305:
881 case 0x33c:
882 case 0x34e:
883 case 0x351:
884 case 0x40c ... 0x40d:
885 return true;
886 default:
887 break;
888 }
889
890 return false;
891}
892
Antti Palosaari6f5f6ee2014-12-12 23:16:19 -0300893static struct dvb_frontend *rtl2832_get_dvb_frontend(struct i2c_client *client)
894{
Antti Palosaari038c6f22014-12-13 00:37:43 -0300895 struct rtl2832_dev *dev = i2c_get_clientdata(client);
Antti Palosaari6f5f6ee2014-12-12 23:16:19 -0300896
897 dev_dbg(&client->dev, "\n");
898 return &dev->fe;
899}
900
Antti Palosaaricd559e02014-12-16 13:37:18 -0300901static struct i2c_adapter *rtl2832_get_i2c_adapter(struct i2c_client *client)
Antti Palosaari6f5f6ee2014-12-12 23:16:19 -0300902{
Antti Palosaari038c6f22014-12-13 00:37:43 -0300903 struct rtl2832_dev *dev = i2c_get_clientdata(client);
Antti Palosaari6f5f6ee2014-12-12 23:16:19 -0300904
905 dev_dbg(&client->dev, "\n");
Peter Rosincddcc402016-04-20 08:41:25 +0200906 return dev->muxc->adapter[0];
Antti Palosaari6f5f6ee2014-12-12 23:16:19 -0300907}
908
Antti Palosaarid884aca2016-02-05 18:26:30 -0200909static int rtl2832_slave_ts_ctrl(struct i2c_client *client, bool enable)
Antti Palosaari6f5f6ee2014-12-12 23:16:19 -0300910{
Antti Palosaari038c6f22014-12-13 00:37:43 -0300911 struct rtl2832_dev *dev = i2c_get_clientdata(client);
Antti Palosaari6f5f6ee2014-12-12 23:16:19 -0300912 int ret;
913
Antti Palosaarid884aca2016-02-05 18:26:30 -0200914 dev_dbg(&client->dev, "enable=%d\n", enable);
Antti Palosaari6f5f6ee2014-12-12 23:16:19 -0300915
Antti Palosaarid884aca2016-02-05 18:26:30 -0200916 if (enable) {
917 ret = rtl2832_wr_demod_reg(dev, DVBT_SOFT_RST, 0x0);
918 if (ret)
919 goto err;
Peter Rosin1cf79db2016-05-04 22:15:33 +0200920 ret = regmap_bulk_write(dev->regmap, 0x10c, "\x5f\xff", 2);
Antti Palosaarid884aca2016-02-05 18:26:30 -0200921 if (ret)
922 goto err;
923 ret = rtl2832_wr_demod_reg(dev, DVBT_PIP_ON, 0x1);
924 if (ret)
925 goto err;
Peter Rosin1cf79db2016-05-04 22:15:33 +0200926 ret = regmap_bulk_write(dev->regmap, 0x0bc, "\x18", 1);
Antti Palosaarid884aca2016-02-05 18:26:30 -0200927 if (ret)
928 goto err;
Peter Rosin1cf79db2016-05-04 22:15:33 +0200929 ret = regmap_bulk_write(dev->regmap, 0x192, "\x7f\xf7\xff", 3);
Antti Palosaarid884aca2016-02-05 18:26:30 -0200930 if (ret)
931 goto err;
932 } else {
Peter Rosin1cf79db2016-05-04 22:15:33 +0200933 ret = regmap_bulk_write(dev->regmap, 0x192, "\x00\x0f\xff", 3);
Antti Palosaarid884aca2016-02-05 18:26:30 -0200934 if (ret)
935 goto err;
Peter Rosin1cf79db2016-05-04 22:15:33 +0200936 ret = regmap_bulk_write(dev->regmap, 0x0bc, "\x08", 1);
Antti Palosaarid884aca2016-02-05 18:26:30 -0200937 if (ret)
938 goto err;
939 ret = rtl2832_wr_demod_reg(dev, DVBT_PIP_ON, 0x0);
940 if (ret)
941 goto err;
Peter Rosin1cf79db2016-05-04 22:15:33 +0200942 ret = regmap_bulk_write(dev->regmap, 0x10c, "\x00\x00", 2);
Antti Palosaarid884aca2016-02-05 18:26:30 -0200943 if (ret)
944 goto err;
945 ret = rtl2832_wr_demod_reg(dev, DVBT_SOFT_RST, 0x1);
946 if (ret)
947 goto err;
948 }
Antti Palosaari6f5f6ee2014-12-12 23:16:19 -0300949
Martin Blumenstingld10f89c2016-06-07 18:31:47 -0300950 dev->slave_ts = enable;
951
Antti Palosaari6f5f6ee2014-12-12 23:16:19 -0300952 return 0;
953err:
954 dev_dbg(&client->dev, "failed=%d\n", ret);
955 return ret;
956}
957
Antti Palosaari4b01e012014-12-14 14:07:35 -0300958static int rtl2832_pid_filter_ctrl(struct dvb_frontend *fe, int onoff)
959{
960 struct rtl2832_dev *dev = fe->demodulator_priv;
961 struct i2c_client *client = dev->client;
962 int ret;
963 u8 u8tmp;
964
Martin Blumenstingld10f89c2016-06-07 18:31:47 -0300965 dev_dbg(&client->dev, "onoff=%d, slave_ts=%d\n", onoff, dev->slave_ts);
Antti Palosaari4b01e012014-12-14 14:07:35 -0300966
967 /* enable / disable PID filter */
968 if (onoff)
969 u8tmp = 0x80;
970 else
971 u8tmp = 0x00;
972
Martin Blumenstingld10f89c2016-06-07 18:31:47 -0300973 if (dev->slave_ts)
974 ret = regmap_update_bits(dev->regmap, 0x021, 0xc0, u8tmp);
975 else
976 ret = regmap_update_bits(dev->regmap, 0x061, 0xc0, u8tmp);
Antti Palosaari4b01e012014-12-14 14:07:35 -0300977 if (ret)
978 goto err;
979
980 return 0;
981err:
982 dev_dbg(&client->dev, "failed=%d\n", ret);
983 return ret;
984}
985
986static int rtl2832_pid_filter(struct dvb_frontend *fe, u8 index, u16 pid,
987 int onoff)
988{
989 struct rtl2832_dev *dev = fe->demodulator_priv;
990 struct i2c_client *client = dev->client;
991 int ret;
992 u8 buf[4];
993
Martin Blumenstingld10f89c2016-06-07 18:31:47 -0300994 dev_dbg(&client->dev, "index=%d pid=%04x onoff=%d slave_ts=%d\n",
995 index, pid, onoff, dev->slave_ts);
Antti Palosaari4b01e012014-12-14 14:07:35 -0300996
997 /* skip invalid PIDs (0x2000) */
998 if (pid > 0x1fff || index > 32)
999 return 0;
1000
1001 if (onoff)
1002 set_bit(index, &dev->filters);
1003 else
1004 clear_bit(index, &dev->filters);
1005
1006 /* enable / disable PIDs */
1007 buf[0] = (dev->filters >> 0) & 0xff;
1008 buf[1] = (dev->filters >> 8) & 0xff;
1009 buf[2] = (dev->filters >> 16) & 0xff;
1010 buf[3] = (dev->filters >> 24) & 0xff;
Martin Blumenstingld10f89c2016-06-07 18:31:47 -03001011
1012 if (dev->slave_ts)
1013 ret = regmap_bulk_write(dev->regmap, 0x022, buf, 4);
1014 else
1015 ret = regmap_bulk_write(dev->regmap, 0x062, buf, 4);
Antti Palosaari4b01e012014-12-14 14:07:35 -03001016 if (ret)
1017 goto err;
1018
1019 /* add PID */
1020 buf[0] = (pid >> 8) & 0xff;
1021 buf[1] = (pid >> 0) & 0xff;
Martin Blumenstingld10f89c2016-06-07 18:31:47 -03001022
1023 if (dev->slave_ts)
1024 ret = regmap_bulk_write(dev->regmap, 0x026 + 2 * index, buf, 2);
1025 else
1026 ret = regmap_bulk_write(dev->regmap, 0x066 + 2 * index, buf, 2);
Antti Palosaari4b01e012014-12-14 14:07:35 -03001027 if (ret)
1028 goto err;
1029
1030 return 0;
1031err:
1032 dev_dbg(&client->dev, "failed=%d\n", ret);
1033 return ret;
1034}
1035
Antti Palosaaric2c83862014-12-02 10:55:17 -03001036static int rtl2832_probe(struct i2c_client *client,
1037 const struct i2c_device_id *id)
1038{
1039 struct rtl2832_platform_data *pdata = client->dev.platform_data;
Antti Palosaaric2c83862014-12-02 10:55:17 -03001040 struct i2c_adapter *i2c = client->adapter;
Antti Palosaari038c6f22014-12-13 00:37:43 -03001041 struct rtl2832_dev *dev;
Antti Palosaaric2c83862014-12-02 10:55:17 -03001042 int ret;
1043 u8 tmp;
Antti Palosaarid1016582014-12-14 04:45:57 -03001044 static const struct regmap_range_cfg regmap_range_cfg[] = {
1045 {
1046 .selector_reg = 0x00,
1047 .selector_mask = 0xff,
1048 .selector_shift = 0,
1049 .window_start = 0,
1050 .window_len = 0x100,
1051 .range_min = 0 * 0x100,
1052 .range_max = 5 * 0x100,
1053 },
1054 };
Antti Palosaaric2c83862014-12-02 10:55:17 -03001055
1056 dev_dbg(&client->dev, "\n");
1057
Antti Palosaaric2c83862014-12-02 10:55:17 -03001058 /* allocate memory for the internal state */
Antti Palosaari038c6f22014-12-13 00:37:43 -03001059 dev = kzalloc(sizeof(struct rtl2832_dev), GFP_KERNEL);
1060 if (dev == NULL) {
Antti Palosaaric2c83862014-12-02 10:55:17 -03001061 ret = -ENOMEM;
1062 goto err;
1063 }
1064
Antti Palosaari038c6f22014-12-13 00:37:43 -03001065 /* setup the state */
Antti Palosaarid1016582014-12-14 04:45:57 -03001066 i2c_set_clientdata(client, dev);
Antti Palosaari038c6f22014-12-13 00:37:43 -03001067 dev->client = client;
Antti Palosaarie1174d72014-12-13 05:26:27 -03001068 dev->pdata = client->dev.platform_data;
Antti Palosaari038c6f22014-12-13 00:37:43 -03001069 dev->sleeping = true;
Antti Palosaari038c6f22014-12-13 00:37:43 -03001070 INIT_DELAYED_WORK(&dev->i2c_gate_work, rtl2832_i2c_gate_work);
Antti Palosaarid1016582014-12-14 04:45:57 -03001071 /* create regmap */
Antti Palosaarib410dae2014-12-18 07:22:46 -03001072 dev->regmap_config.reg_bits = 8,
1073 dev->regmap_config.val_bits = 8,
Antti Palosaarib410dae2014-12-18 07:22:46 -03001074 dev->regmap_config.volatile_reg = rtl2832_volatile_reg,
1075 dev->regmap_config.max_register = 5 * 0x100,
1076 dev->regmap_config.ranges = regmap_range_cfg,
1077 dev->regmap_config.num_ranges = ARRAY_SIZE(regmap_range_cfg),
Antti Palosaarib3b2bf82015-03-14 11:13:07 -03001078 dev->regmap_config.cache_type = REGCACHE_NONE,
Peter Rosin1cf79db2016-05-04 22:15:33 +02001079 dev->regmap = regmap_init_i2c(client, &dev->regmap_config);
Antti Palosaarid1016582014-12-14 04:45:57 -03001080 if (IS_ERR(dev->regmap)) {
1081 ret = PTR_ERR(dev->regmap);
1082 goto err_kfree;
1083 }
Antti Palosaaric2c83862014-12-02 10:55:17 -03001084
1085 /* check if the demod is there */
Peter Rosin1cf79db2016-05-04 22:15:33 +02001086 ret = regmap_bulk_read(dev->regmap, 0x000, &tmp, 1);
Antti Palosaaric2c83862014-12-02 10:55:17 -03001087 if (ret)
Antti Palosaari0d117902014-12-18 06:30:32 -03001088 goto err_regmap_exit;
Antti Palosaaric2c83862014-12-02 10:55:17 -03001089
1090 /* create muxed i2c adapter for demod tuner bus */
Peter Rosin1cf79db2016-05-04 22:15:33 +02001091 dev->muxc = i2c_mux_alloc(i2c, &i2c->dev, 1, 0, I2C_MUX_LOCKED,
Peter Rosincddcc402016-04-20 08:41:25 +02001092 rtl2832_select, rtl2832_deselect);
1093 if (!dev->muxc) {
1094 ret = -ENOMEM;
Antti Palosaari0d117902014-12-18 06:30:32 -03001095 goto err_regmap_exit;
Antti Palosaaric2c83862014-12-02 10:55:17 -03001096 }
Peter Rosincddcc402016-04-20 08:41:25 +02001097 dev->muxc->priv = dev;
1098 ret = i2c_mux_add_adapter(dev->muxc, 0, 0, 0);
1099 if (ret)
1100 goto err_regmap_exit;
Antti Palosaaric2c83862014-12-02 10:55:17 -03001101
1102 /* create dvb_frontend */
Antti Palosaari038c6f22014-12-13 00:37:43 -03001103 memcpy(&dev->fe.ops, &rtl2832_ops, sizeof(struct dvb_frontend_ops));
1104 dev->fe.demodulator_priv = dev;
Antti Palosaari6f5f6ee2014-12-12 23:16:19 -03001105
1106 /* setup callbacks */
1107 pdata->get_dvb_frontend = rtl2832_get_dvb_frontend;
Antti Palosaaricd559e02014-12-16 13:37:18 -03001108 pdata->get_i2c_adapter = rtl2832_get_i2c_adapter;
Antti Palosaarid884aca2016-02-05 18:26:30 -02001109 pdata->slave_ts_ctrl = rtl2832_slave_ts_ctrl;
Antti Palosaari4b01e012014-12-14 14:07:35 -03001110 pdata->pid_filter = rtl2832_pid_filter;
1111 pdata->pid_filter_ctrl = rtl2832_pid_filter_ctrl;
Peter Rosin1cf79db2016-05-04 22:15:33 +02001112 pdata->regmap = dev->regmap;
Antti Palosaaric2c83862014-12-02 10:55:17 -03001113
1114 dev_info(&client->dev, "Realtek RTL2832 successfully attached\n");
1115 return 0;
Antti Palosaarid1016582014-12-14 04:45:57 -03001116err_regmap_exit:
1117 regmap_exit(dev->regmap);
Antti Palosaaric2c83862014-12-02 10:55:17 -03001118err_kfree:
Antti Palosaari038c6f22014-12-13 00:37:43 -03001119 kfree(dev);
Antti Palosaaric2c83862014-12-02 10:55:17 -03001120err:
1121 dev_dbg(&client->dev, "failed=%d\n", ret);
1122 return ret;
1123}
1124
1125static int rtl2832_remove(struct i2c_client *client)
1126{
Antti Palosaari038c6f22014-12-13 00:37:43 -03001127 struct rtl2832_dev *dev = i2c_get_clientdata(client);
Antti Palosaaric2c83862014-12-02 10:55:17 -03001128
1129 dev_dbg(&client->dev, "\n");
1130
Antti Palosaari038c6f22014-12-13 00:37:43 -03001131 cancel_delayed_work_sync(&dev->i2c_gate_work);
Antti Palosaaric2c83862014-12-02 10:55:17 -03001132
Peter Rosincddcc402016-04-20 08:41:25 +02001133 i2c_mux_del_adapters(dev->muxc);
Antti Palosaaric2c83862014-12-02 10:55:17 -03001134
Antti Palosaarid1016582014-12-14 04:45:57 -03001135 regmap_exit(dev->regmap);
1136
Antti Palosaari038c6f22014-12-13 00:37:43 -03001137 kfree(dev);
Antti Palosaaric2c83862014-12-02 10:55:17 -03001138
1139 return 0;
1140}
1141
1142static const struct i2c_device_id rtl2832_id_table[] = {
1143 {"rtl2832", 0},
1144 {}
1145};
1146MODULE_DEVICE_TABLE(i2c, rtl2832_id_table);
1147
1148static struct i2c_driver rtl2832_driver = {
1149 .driver = {
Antti Palosaaric2c83862014-12-02 10:55:17 -03001150 .name = "rtl2832",
Antti Palosaari678fdb62016-06-29 20:40:57 -03001151 .suppress_bind_attrs = true,
Antti Palosaaric2c83862014-12-02 10:55:17 -03001152 },
1153 .probe = rtl2832_probe,
1154 .remove = rtl2832_remove,
1155 .id_table = rtl2832_id_table,
1156};
1157
1158module_i2c_driver(rtl2832_driver);
1159
Thomas Mair82041c02012-05-18 14:47:40 -03001160MODULE_AUTHOR("Thomas Mair <mair.thomas86@gmail.com>");
Antti Palosaari75c24002014-12-16 13:54:23 -03001161MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
Thomas Mair82041c02012-05-18 14:47:40 -03001162MODULE_DESCRIPTION("Realtek RTL2832 DVB-T demodulator driver");
1163MODULE_LICENSE("GPL");