blob: 6bcec750606427494f82fccc897eda588aeabe8f [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>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21#include "rtl2832_priv.h"
Antti Palosaari73983492012-08-21 19:56:21 -030022#include "dvb_math.h"
Mauro Carvalho Chehab298f18a2012-07-05 12:16:26 -030023#include <linux/bitops.h>
Thomas Mair82041c02012-05-18 14:47:40 -030024
Mauro Carvalho Chehab298f18a2012-07-05 12:16:26 -030025#define REG_MASK(b) (BIT(b + 1) - 1)
Thomas Mair82041c02012-05-18 14:47:40 -030026
27static const struct rtl2832_reg_entry registers[] = {
28 [DVBT_SOFT_RST] = {0x1, 0x1, 2, 2},
29 [DVBT_IIC_REPEAT] = {0x1, 0x1, 3, 3},
30 [DVBT_TR_WAIT_MIN_8K] = {0x1, 0x88, 11, 2},
31 [DVBT_RSD_BER_FAIL_VAL] = {0x1, 0x8f, 15, 0},
32 [DVBT_EN_BK_TRK] = {0x1, 0xa6, 7, 7},
33 [DVBT_AD_EN_REG] = {0x0, 0x8, 7, 7},
34 [DVBT_AD_EN_REG1] = {0x0, 0x8, 6, 6},
35 [DVBT_EN_BBIN] = {0x1, 0xb1, 0, 0},
36 [DVBT_MGD_THD0] = {0x1, 0x95, 7, 0},
37 [DVBT_MGD_THD1] = {0x1, 0x96, 7, 0},
38 [DVBT_MGD_THD2] = {0x1, 0x97, 7, 0},
39 [DVBT_MGD_THD3] = {0x1, 0x98, 7, 0},
40 [DVBT_MGD_THD4] = {0x1, 0x99, 7, 0},
41 [DVBT_MGD_THD5] = {0x1, 0x9a, 7, 0},
42 [DVBT_MGD_THD6] = {0x1, 0x9b, 7, 0},
43 [DVBT_MGD_THD7] = {0x1, 0x9c, 7, 0},
44 [DVBT_EN_CACQ_NOTCH] = {0x1, 0x61, 4, 4},
45 [DVBT_AD_AV_REF] = {0x0, 0x9, 6, 0},
46 [DVBT_REG_PI] = {0x0, 0xa, 2, 0},
47 [DVBT_PIP_ON] = {0x0, 0x21, 3, 3},
48 [DVBT_SCALE1_B92] = {0x2, 0x92, 7, 0},
49 [DVBT_SCALE1_B93] = {0x2, 0x93, 7, 0},
50 [DVBT_SCALE1_BA7] = {0x2, 0xa7, 7, 0},
51 [DVBT_SCALE1_BA9] = {0x2, 0xa9, 7, 0},
52 [DVBT_SCALE1_BAA] = {0x2, 0xaa, 7, 0},
53 [DVBT_SCALE1_BAB] = {0x2, 0xab, 7, 0},
54 [DVBT_SCALE1_BAC] = {0x2, 0xac, 7, 0},
55 [DVBT_SCALE1_BB0] = {0x2, 0xb0, 7, 0},
56 [DVBT_SCALE1_BB1] = {0x2, 0xb1, 7, 0},
57 [DVBT_KB_P1] = {0x1, 0x64, 3, 1},
58 [DVBT_KB_P2] = {0x1, 0x64, 6, 4},
59 [DVBT_KB_P3] = {0x1, 0x65, 2, 0},
60 [DVBT_OPT_ADC_IQ] = {0x0, 0x6, 5, 4},
61 [DVBT_AD_AVI] = {0x0, 0x9, 1, 0},
62 [DVBT_AD_AVQ] = {0x0, 0x9, 3, 2},
63 [DVBT_K1_CR_STEP12] = {0x2, 0xad, 9, 4},
64 [DVBT_TRK_KS_P2] = {0x1, 0x6f, 2, 0},
65 [DVBT_TRK_KS_I2] = {0x1, 0x70, 5, 3},
66 [DVBT_TR_THD_SET2] = {0x1, 0x72, 3, 0},
67 [DVBT_TRK_KC_P2] = {0x1, 0x73, 5, 3},
68 [DVBT_TRK_KC_I2] = {0x1, 0x75, 2, 0},
69 [DVBT_CR_THD_SET2] = {0x1, 0x76, 7, 6},
70 [DVBT_PSET_IFFREQ] = {0x1, 0x19, 21, 0},
71 [DVBT_SPEC_INV] = {0x1, 0x15, 0, 0},
72 [DVBT_RSAMP_RATIO] = {0x1, 0x9f, 27, 2},
73 [DVBT_CFREQ_OFF_RATIO] = {0x1, 0x9d, 23, 4},
74 [DVBT_FSM_STAGE] = {0x3, 0x51, 6, 3},
75 [DVBT_RX_CONSTEL] = {0x3, 0x3c, 3, 2},
76 [DVBT_RX_HIER] = {0x3, 0x3c, 6, 4},
77 [DVBT_RX_C_RATE_LP] = {0x3, 0x3d, 2, 0},
78 [DVBT_RX_C_RATE_HP] = {0x3, 0x3d, 5, 3},
79 [DVBT_GI_IDX] = {0x3, 0x51, 1, 0},
80 [DVBT_FFT_MODE_IDX] = {0x3, 0x51, 2, 2},
81 [DVBT_RSD_BER_EST] = {0x3, 0x4e, 15, 0},
82 [DVBT_CE_EST_EVM] = {0x4, 0xc, 15, 0},
83 [DVBT_RF_AGC_VAL] = {0x3, 0x5b, 13, 0},
84 [DVBT_IF_AGC_VAL] = {0x3, 0x59, 13, 0},
85 [DVBT_DAGC_VAL] = {0x3, 0x5, 7, 0},
86 [DVBT_SFREQ_OFF] = {0x3, 0x18, 13, 0},
87 [DVBT_CFREQ_OFF] = {0x3, 0x5f, 17, 0},
88 [DVBT_POLAR_RF_AGC] = {0x0, 0xe, 1, 1},
89 [DVBT_POLAR_IF_AGC] = {0x0, 0xe, 0, 0},
90 [DVBT_AAGC_HOLD] = {0x1, 0x4, 5, 5},
91 [DVBT_EN_RF_AGC] = {0x1, 0x4, 6, 6},
92 [DVBT_EN_IF_AGC] = {0x1, 0x4, 7, 7},
93 [DVBT_IF_AGC_MIN] = {0x1, 0x8, 7, 0},
94 [DVBT_IF_AGC_MAX] = {0x1, 0x9, 7, 0},
95 [DVBT_RF_AGC_MIN] = {0x1, 0xa, 7, 0},
96 [DVBT_RF_AGC_MAX] = {0x1, 0xb, 7, 0},
97 [DVBT_IF_AGC_MAN] = {0x1, 0xc, 6, 6},
98 [DVBT_IF_AGC_MAN_VAL] = {0x1, 0xc, 13, 0},
99 [DVBT_RF_AGC_MAN] = {0x1, 0xe, 6, 6},
100 [DVBT_RF_AGC_MAN_VAL] = {0x1, 0xe, 13, 0},
101 [DVBT_DAGC_TRG_VAL] = {0x1, 0x12, 7, 0},
102 [DVBT_AGC_TARG_VAL_0] = {0x1, 0x2, 0, 0},
103 [DVBT_AGC_TARG_VAL_8_1] = {0x1, 0x3, 7, 0},
104 [DVBT_AAGC_LOOP_GAIN] = {0x1, 0xc7, 5, 1},
105 [DVBT_LOOP_GAIN2_3_0] = {0x1, 0x4, 4, 1},
106 [DVBT_LOOP_GAIN2_4] = {0x1, 0x5, 7, 7},
107 [DVBT_LOOP_GAIN3] = {0x1, 0xc8, 4, 0},
108 [DVBT_VTOP1] = {0x1, 0x6, 5, 0},
109 [DVBT_VTOP2] = {0x1, 0xc9, 5, 0},
110 [DVBT_VTOP3] = {0x1, 0xca, 5, 0},
111 [DVBT_KRF1] = {0x1, 0xcb, 7, 0},
112 [DVBT_KRF2] = {0x1, 0x7, 7, 0},
113 [DVBT_KRF3] = {0x1, 0xcd, 7, 0},
114 [DVBT_KRF4] = {0x1, 0xce, 7, 0},
115 [DVBT_EN_GI_PGA] = {0x1, 0xe5, 0, 0},
116 [DVBT_THD_LOCK_UP] = {0x1, 0xd9, 8, 0},
117 [DVBT_THD_LOCK_DW] = {0x1, 0xdb, 8, 0},
118 [DVBT_THD_UP1] = {0x1, 0xdd, 7, 0},
119 [DVBT_THD_DW1] = {0x1, 0xde, 7, 0},
120 [DVBT_INTER_CNT_LEN] = {0x1, 0xd8, 3, 0},
121 [DVBT_GI_PGA_STATE] = {0x1, 0xe6, 3, 3},
122 [DVBT_EN_AGC_PGA] = {0x1, 0xd7, 0, 0},
123 [DVBT_CKOUTPAR] = {0x1, 0x7b, 5, 5},
124 [DVBT_CKOUT_PWR] = {0x1, 0x7b, 6, 6},
125 [DVBT_SYNC_DUR] = {0x1, 0x7b, 7, 7},
126 [DVBT_ERR_DUR] = {0x1, 0x7c, 0, 0},
127 [DVBT_SYNC_LVL] = {0x1, 0x7c, 1, 1},
128 [DVBT_ERR_LVL] = {0x1, 0x7c, 2, 2},
129 [DVBT_VAL_LVL] = {0x1, 0x7c, 3, 3},
130 [DVBT_SERIAL] = {0x1, 0x7c, 4, 4},
131 [DVBT_SER_LSB] = {0x1, 0x7c, 5, 5},
132 [DVBT_CDIV_PH0] = {0x1, 0x7d, 3, 0},
133 [DVBT_CDIV_PH1] = {0x1, 0x7d, 7, 4},
134 [DVBT_MPEG_IO_OPT_2_2] = {0x0, 0x6, 7, 7},
135 [DVBT_MPEG_IO_OPT_1_0] = {0x0, 0x7, 7, 6},
136 [DVBT_CKOUTPAR_PIP] = {0x0, 0xb7, 4, 4},
137 [DVBT_CKOUT_PWR_PIP] = {0x0, 0xb7, 3, 3},
138 [DVBT_SYNC_LVL_PIP] = {0x0, 0xb7, 2, 2},
139 [DVBT_ERR_LVL_PIP] = {0x0, 0xb7, 1, 1},
140 [DVBT_VAL_LVL_PIP] = {0x0, 0xb7, 0, 0},
141 [DVBT_CKOUTPAR_PID] = {0x0, 0xb9, 4, 4},
142 [DVBT_CKOUT_PWR_PID] = {0x0, 0xb9, 3, 3},
143 [DVBT_SYNC_LVL_PID] = {0x0, 0xb9, 2, 2},
144 [DVBT_ERR_LVL_PID] = {0x0, 0xb9, 1, 1},
145 [DVBT_VAL_LVL_PID] = {0x0, 0xb9, 0, 0},
146 [DVBT_SM_PASS] = {0x1, 0x93, 11, 0},
147 [DVBT_AD7_SETTING] = {0x0, 0x11, 15, 0},
148 [DVBT_RSSI_R] = {0x3, 0x1, 6, 0},
149 [DVBT_ACI_DET_IND] = {0x3, 0x12, 0, 0},
150 [DVBT_REG_MON] = {0x0, 0xd, 1, 0},
151 [DVBT_REG_MONSEL] = {0x0, 0xd, 2, 2},
152 [DVBT_REG_GPE] = {0x0, 0xd, 7, 7},
153 [DVBT_REG_GPO] = {0x0, 0x10, 0, 0},
154 [DVBT_REG_4MSEL] = {0x0, 0x13, 0, 0},
155};
156
Antti Palosaarid1016582014-12-14 04:45:57 -0300157/* Our regmap is bypassing I2C adapter lock, thus we do it! */
158int rtl2832_bulk_write(struct i2c_client *client, unsigned int reg,
159 const void *val, size_t val_count)
Thomas Mair82041c02012-05-18 14:47:40 -0300160{
Antti Palosaarid1016582014-12-14 04:45:57 -0300161 struct rtl2832_dev *dev = i2c_get_clientdata(client);
Thomas Mair82041c02012-05-18 14:47:40 -0300162 int ret;
Thomas Mair82041c02012-05-18 14:47:40 -0300163
Antti Palosaarid1016582014-12-14 04:45:57 -0300164 i2c_lock_adapter(client->adapter);
165 ret = regmap_bulk_write(dev->regmap, reg, val, val_count);
166 i2c_unlock_adapter(client->adapter);
Thomas Mair82041c02012-05-18 14:47:40 -0300167 return ret;
168}
169
Antti Palosaarid1016582014-12-14 04:45:57 -0300170int rtl2832_update_bits(struct i2c_client *client, unsigned int reg,
171 unsigned int mask, unsigned int val)
Thomas Mair82041c02012-05-18 14:47:40 -0300172{
Antti Palosaarid1016582014-12-14 04:45:57 -0300173 struct rtl2832_dev *dev = i2c_get_clientdata(client);
Thomas Mair82041c02012-05-18 14:47:40 -0300174 int ret;
Thomas Mair82041c02012-05-18 14:47:40 -0300175
Antti Palosaarid1016582014-12-14 04:45:57 -0300176 i2c_lock_adapter(client->adapter);
177 ret = regmap_update_bits(dev->regmap, reg, mask, val);
178 i2c_unlock_adapter(client->adapter);
179 return ret;
180}
181
182int rtl2832_bulk_read(struct i2c_client *client, unsigned int reg, void *val,
183 size_t val_count)
184{
185 struct rtl2832_dev *dev = i2c_get_clientdata(client);
186 int ret;
187
188 i2c_lock_adapter(client->adapter);
189 ret = regmap_bulk_read(dev->regmap, reg, val, val_count);
190 i2c_unlock_adapter(client->adapter);
Antti Palosaari298efdd2012-09-11 22:27:11 -0300191 return ret;
Thomas Mair82041c02012-05-18 14:47:40 -0300192}
193
194/* write multiple registers */
Antti Palosaarid1016582014-12-14 04:45:57 -0300195static int rtl2832_wr_regs(struct rtl2832_dev *dev, u8 reg, u8 page, u8 *val, int len)
Thomas Mair82041c02012-05-18 14:47:40 -0300196{
Antti Palosaarid1016582014-12-14 04:45:57 -0300197 return rtl2832_bulk_write(dev->client, page << 8 | reg, val, len);
Thomas Mair82041c02012-05-18 14:47:40 -0300198}
199
200/* read multiple registers */
Antti Palosaarid1016582014-12-14 04:45:57 -0300201static int rtl2832_rd_regs(struct rtl2832_dev *dev, u8 reg, u8 page, u8 *val, int len)
Thomas Mair82041c02012-05-18 14:47:40 -0300202{
Antti Palosaarid1016582014-12-14 04:45:57 -0300203 return rtl2832_bulk_read(dev->client, page << 8 | reg, val, len);
Thomas Mair82041c02012-05-18 14:47:40 -0300204}
205
Thomas Mair82041c02012-05-18 14:47:40 -0300206/* write single register */
Antti Palosaari038c6f22014-12-13 00:37:43 -0300207static int rtl2832_wr_reg(struct rtl2832_dev *dev, u8 reg, u8 page, u8 val)
Thomas Mair82041c02012-05-18 14:47:40 -0300208{
Antti Palosaari038c6f22014-12-13 00:37:43 -0300209 return rtl2832_wr_regs(dev, reg, page, &val, 1);
Thomas Mair82041c02012-05-18 14:47:40 -0300210}
Thomas Mair82041c02012-05-18 14:47:40 -0300211
212/* read single register */
Antti Palosaari038c6f22014-12-13 00:37:43 -0300213static int rtl2832_rd_reg(struct rtl2832_dev *dev, u8 reg, u8 page, u8 *val)
Thomas Mair82041c02012-05-18 14:47:40 -0300214{
Antti Palosaari038c6f22014-12-13 00:37:43 -0300215 return rtl2832_rd_regs(dev, reg, page, val, 1);
Thomas Mair82041c02012-05-18 14:47:40 -0300216}
217
Antti Palosaari038c6f22014-12-13 00:37:43 -0300218static int rtl2832_rd_demod_reg(struct rtl2832_dev *dev, int reg, u32 *val)
Thomas Mair82041c02012-05-18 14:47:40 -0300219{
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300220 struct i2c_client *client = dev->client;
Thomas Mair82041c02012-05-18 14:47:40 -0300221 int ret;
222
223 u8 reg_start_addr;
224 u8 msb, lsb;
225 u8 page;
226 u8 reading[4];
227 u32 reading_tmp;
228 int i;
229
230 u8 len;
231 u32 mask;
232
233 reg_start_addr = registers[reg].start_address;
234 msb = registers[reg].msb;
235 lsb = registers[reg].lsb;
236 page = registers[reg].page;
237
238 len = (msb >> 3) + 1;
Mauro Carvalho Chehab298f18a2012-07-05 12:16:26 -0300239 mask = REG_MASK(msb - lsb);
Thomas Mair82041c02012-05-18 14:47:40 -0300240
Antti Palosaari038c6f22014-12-13 00:37:43 -0300241 ret = rtl2832_rd_regs(dev, reg_start_addr, page, &reading[0], len);
Thomas Mair82041c02012-05-18 14:47:40 -0300242 if (ret)
243 goto err;
244
245 reading_tmp = 0;
246 for (i = 0; i < len; i++)
247 reading_tmp |= reading[i] << ((len - 1 - i) * 8);
248
249 *val = (reading_tmp >> lsb) & mask;
250
251 return ret;
252
253err:
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300254 dev_dbg(&client->dev, "failed=%d\n", ret);
Thomas Mair82041c02012-05-18 14:47:40 -0300255 return ret;
256
257}
258
Antti Palosaari038c6f22014-12-13 00:37:43 -0300259static int rtl2832_wr_demod_reg(struct rtl2832_dev *dev, int reg, u32 val)
Thomas Mair82041c02012-05-18 14:47:40 -0300260{
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300261 struct i2c_client *client = dev->client;
Thomas Mair82041c02012-05-18 14:47:40 -0300262 int ret, i;
263 u8 len;
264 u8 reg_start_addr;
265 u8 msb, lsb;
266 u8 page;
267 u32 mask;
268
269
270 u8 reading[4];
271 u8 writing[4];
272 u32 reading_tmp;
273 u32 writing_tmp;
274
275
276 reg_start_addr = registers[reg].start_address;
277 msb = registers[reg].msb;
278 lsb = registers[reg].lsb;
279 page = registers[reg].page;
280
281 len = (msb >> 3) + 1;
Mauro Carvalho Chehab298f18a2012-07-05 12:16:26 -0300282 mask = REG_MASK(msb - lsb);
Thomas Mair82041c02012-05-18 14:47:40 -0300283
284
Antti Palosaari038c6f22014-12-13 00:37:43 -0300285 ret = rtl2832_rd_regs(dev, reg_start_addr, page, &reading[0], len);
Thomas Mair82041c02012-05-18 14:47:40 -0300286 if (ret)
287 goto err;
288
289 reading_tmp = 0;
290 for (i = 0; i < len; i++)
291 reading_tmp |= reading[i] << ((len - 1 - i) * 8);
292
293 writing_tmp = reading_tmp & ~(mask << lsb);
294 writing_tmp |= ((val & mask) << lsb);
295
296
297 for (i = 0; i < len; i++)
298 writing[i] = (writing_tmp >> ((len - 1 - i) * 8)) & 0xff;
299
Antti Palosaari038c6f22014-12-13 00:37:43 -0300300 ret = rtl2832_wr_regs(dev, reg_start_addr, page, &writing[0], len);
Thomas Mair82041c02012-05-18 14:47:40 -0300301 if (ret)
302 goto err;
303
304 return ret;
305
306err:
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300307 dev_dbg(&client->dev, "failed=%d\n", ret);
Thomas Mair82041c02012-05-18 14:47:40 -0300308 return ret;
309
310}
311
Mauro Carvalho Chehab884655a2013-04-09 22:16:52 -0300312static int rtl2832_set_if(struct dvb_frontend *fe, u32 if_freq)
313{
Antti Palosaari038c6f22014-12-13 00:37:43 -0300314 struct rtl2832_dev *dev = fe->demodulator_priv;
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300315 struct i2c_client *client = dev->client;
Mauro Carvalho Chehab884655a2013-04-09 22:16:52 -0300316 int ret;
317 u64 pset_iffreq;
318 u8 en_bbin = (if_freq == 0 ? 0x1 : 0x0);
319
320 /*
321 * PSET_IFFREQ = - floor((IfFreqHz % CrystalFreqHz) * pow(2, 22)
322 * / CrystalFreqHz)
323 */
324
Antti Palosaarie1174d72014-12-13 05:26:27 -0300325 pset_iffreq = if_freq % dev->pdata->clk;
Mauro Carvalho Chehab884655a2013-04-09 22:16:52 -0300326 pset_iffreq *= 0x400000;
Antti Palosaarie1174d72014-12-13 05:26:27 -0300327 pset_iffreq = div_u64(pset_iffreq, dev->pdata->clk);
Mauro Carvalho Chehabc8832e82013-04-15 19:44:39 -0300328 pset_iffreq = -pset_iffreq;
Mauro Carvalho Chehab884655a2013-04-09 22:16:52 -0300329 pset_iffreq = pset_iffreq & 0x3fffff;
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300330 dev_dbg(&client->dev, "if_frequency=%d pset_iffreq=%08x\n",
331 if_freq, (unsigned)pset_iffreq);
Mauro Carvalho Chehabc8832e82013-04-15 19:44:39 -0300332
Antti Palosaari038c6f22014-12-13 00:37:43 -0300333 ret = rtl2832_wr_demod_reg(dev, DVBT_EN_BBIN, en_bbin);
Mauro Carvalho Chehab884655a2013-04-09 22:16:52 -0300334 if (ret)
335 return ret;
336
Antti Palosaari038c6f22014-12-13 00:37:43 -0300337 ret = rtl2832_wr_demod_reg(dev, DVBT_PSET_IFFREQ, pset_iffreq);
Mauro Carvalho Chehab884655a2013-04-09 22:16:52 -0300338
Antti Palosaari3ca24182013-10-13 00:06:44 -0300339 return ret;
Mauro Carvalho Chehab884655a2013-04-09 22:16:52 -0300340}
341
Thomas Mair82041c02012-05-18 14:47:40 -0300342static int rtl2832_init(struct dvb_frontend *fe)
343{
Antti Palosaari038c6f22014-12-13 00:37:43 -0300344 struct rtl2832_dev *dev = fe->demodulator_priv;
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300345 struct i2c_client *client = dev->client;
Antti Palosaari19d273d2014-12-14 06:55:43 -0300346 struct dtv_frontend_properties *c = &dev->fe.dtv_property_cache;
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300347 const struct rtl2832_reg_value *init;
Mauro Carvalho Chehab884655a2013-04-09 22:16:52 -0300348 int i, ret, len;
Thomas Mair82041c02012-05-18 14:47:40 -0300349 /* initialization values for the demodulator registers */
350 struct rtl2832_reg_value rtl2832_initial_regs[] = {
351 {DVBT_AD_EN_REG, 0x1},
352 {DVBT_AD_EN_REG1, 0x1},
353 {DVBT_RSD_BER_FAIL_VAL, 0x2800},
354 {DVBT_MGD_THD0, 0x10},
355 {DVBT_MGD_THD1, 0x20},
356 {DVBT_MGD_THD2, 0x20},
357 {DVBT_MGD_THD3, 0x40},
358 {DVBT_MGD_THD4, 0x22},
359 {DVBT_MGD_THD5, 0x32},
360 {DVBT_MGD_THD6, 0x37},
361 {DVBT_MGD_THD7, 0x39},
362 {DVBT_EN_BK_TRK, 0x0},
363 {DVBT_EN_CACQ_NOTCH, 0x0},
364 {DVBT_AD_AV_REF, 0x2a},
365 {DVBT_REG_PI, 0x6},
366 {DVBT_PIP_ON, 0x0},
367 {DVBT_CDIV_PH0, 0x8},
368 {DVBT_CDIV_PH1, 0x8},
369 {DVBT_SCALE1_B92, 0x4},
370 {DVBT_SCALE1_B93, 0xb0},
371 {DVBT_SCALE1_BA7, 0x78},
372 {DVBT_SCALE1_BA9, 0x28},
373 {DVBT_SCALE1_BAA, 0x59},
374 {DVBT_SCALE1_BAB, 0x83},
375 {DVBT_SCALE1_BAC, 0xd4},
376 {DVBT_SCALE1_BB0, 0x65},
377 {DVBT_SCALE1_BB1, 0x43},
378 {DVBT_KB_P1, 0x1},
379 {DVBT_KB_P2, 0x4},
380 {DVBT_KB_P3, 0x7},
381 {DVBT_K1_CR_STEP12, 0xa},
382 {DVBT_REG_GPE, 0x1},
383 {DVBT_SERIAL, 0x0},
384 {DVBT_CDIV_PH0, 0x9},
385 {DVBT_CDIV_PH1, 0x9},
386 {DVBT_MPEG_IO_OPT_2_2, 0x0},
387 {DVBT_MPEG_IO_OPT_1_0, 0x0},
388 {DVBT_TRK_KS_P2, 0x4},
389 {DVBT_TRK_KS_I2, 0x7},
390 {DVBT_TR_THD_SET2, 0x6},
391 {DVBT_TRK_KC_I2, 0x5},
392 {DVBT_CR_THD_SET2, 0x1},
Thomas Mair82041c02012-05-18 14:47:40 -0300393 };
394
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300395 dev_dbg(&client->dev, "\n");
Thomas Mair82041c02012-05-18 14:47:40 -0300396
Thomas Mair82041c02012-05-18 14:47:40 -0300397 for (i = 0; i < ARRAY_SIZE(rtl2832_initial_regs); i++) {
Antti Palosaari038c6f22014-12-13 00:37:43 -0300398 ret = rtl2832_wr_demod_reg(dev, rtl2832_initial_regs[i].reg,
Thomas Mair82041c02012-05-18 14:47:40 -0300399 rtl2832_initial_regs[i].value);
400 if (ret)
401 goto err;
402 }
403
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300404 /* load tuner specific settings */
Antti Palosaarie1174d72014-12-13 05:26:27 -0300405 dev_dbg(&client->dev, "load settings for tuner=%02x\n",
406 dev->pdata->tuner);
407 switch (dev->pdata->tuner) {
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300408 case RTL2832_TUNER_FC0012:
409 case RTL2832_TUNER_FC0013:
410 len = ARRAY_SIZE(rtl2832_tuner_init_fc0012);
411 init = rtl2832_tuner_init_fc0012;
412 break;
Antti Palosaari5db41872012-09-11 22:27:08 -0300413 case RTL2832_TUNER_TUA9001:
414 len = ARRAY_SIZE(rtl2832_tuner_init_tua9001);
415 init = rtl2832_tuner_init_tua9001;
416 break;
Antti Palosaari7e688de2012-09-17 17:53:04 -0300417 case RTL2832_TUNER_E4000:
418 len = ARRAY_SIZE(rtl2832_tuner_init_e4000);
419 init = rtl2832_tuner_init_e4000;
420 break;
Mauro Carvalho Chehabfa4bfd22013-04-09 18:19:50 -0300421 case RTL2832_TUNER_R820T:
Antti Palosaaria26758e2013-10-30 00:36:38 -0300422 case RTL2832_TUNER_R828D:
Mauro Carvalho Chehabfa4bfd22013-04-09 18:19:50 -0300423 len = ARRAY_SIZE(rtl2832_tuner_init_r820t);
424 init = rtl2832_tuner_init_r820t;
425 break;
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300426 default:
427 ret = -EINVAL;
428 goto err;
429 }
430
431 for (i = 0; i < len; i++) {
Antti Palosaari038c6f22014-12-13 00:37:43 -0300432 ret = rtl2832_wr_demod_reg(dev, init[i].reg, init[i].value);
Antti Palosaari832cc7c2012-09-11 22:27:04 -0300433 if (ret)
434 goto err;
435 }
436
Mauro Carvalho Chehabfa4bfd22013-04-09 18:19:50 -0300437 /*
438 * r820t NIM code does a software reset here at the demod -
Antti Palosaari3ca24182013-10-13 00:06:44 -0300439 * may not be needed, as there's already a software reset at
440 * set_params()
Mauro Carvalho Chehabfa4bfd22013-04-09 18:19:50 -0300441 */
442#if 1
443 /* soft reset */
Antti Palosaari038c6f22014-12-13 00:37:43 -0300444 ret = rtl2832_wr_demod_reg(dev, DVBT_SOFT_RST, 0x1);
Mauro Carvalho Chehabfa4bfd22013-04-09 18:19:50 -0300445 if (ret)
446 goto err;
447
Antti Palosaari038c6f22014-12-13 00:37:43 -0300448 ret = rtl2832_wr_demod_reg(dev, DVBT_SOFT_RST, 0x0);
Mauro Carvalho Chehabfa4bfd22013-04-09 18:19:50 -0300449 if (ret)
450 goto err;
451#endif
Antti Palosaari19d273d2014-12-14 06:55:43 -0300452 /* init stats here in order signal app which stats are supported */
Antti Palosaari25ef9f52014-12-14 11:00:50 -0300453 c->strength.len = 1;
454 c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
Antti Palosaari19d273d2014-12-14 06:55:43 -0300455 c->cnr.len = 1;
456 c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
Antti Palosaari6b4fd012014-12-14 09:59:20 -0300457 c->post_bit_error.len = 1;
458 c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
459 c->post_bit_count.len = 1;
460 c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
Antti Palosaari19d273d2014-12-14 06:55:43 -0300461 /* start statistics polling */
462 schedule_delayed_work(&dev->stat_work, msecs_to_jiffies(2000));
Antti Palosaari038c6f22014-12-13 00:37:43 -0300463 dev->sleeping = false;
Thomas Mair82041c02012-05-18 14:47:40 -0300464
465 return ret;
Thomas Mair82041c02012-05-18 14:47:40 -0300466err:
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300467 dev_dbg(&client->dev, "failed=%d\n", ret);
Thomas Mair82041c02012-05-18 14:47:40 -0300468 return ret;
469}
470
471static int rtl2832_sleep(struct dvb_frontend *fe)
472{
Antti Palosaari038c6f22014-12-13 00:37:43 -0300473 struct rtl2832_dev *dev = fe->demodulator_priv;
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300474 struct i2c_client *client = dev->client;
Thomas Mair82041c02012-05-18 14:47:40 -0300475
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300476 dev_dbg(&client->dev, "\n");
Antti Palosaari038c6f22014-12-13 00:37:43 -0300477 dev->sleeping = true;
Antti Palosaari19d273d2014-12-14 06:55:43 -0300478 /* stop statistics polling */
479 cancel_delayed_work_sync(&dev->stat_work);
480 dev->fe_status = 0;
Thomas Mair82041c02012-05-18 14:47:40 -0300481 return 0;
482}
483
Mauro Carvalho Chehabb0944ea2012-10-27 11:24:37 -0300484static int rtl2832_get_tune_settings(struct dvb_frontend *fe,
Thomas Mair82041c02012-05-18 14:47:40 -0300485 struct dvb_frontend_tune_settings *s)
486{
Antti Palosaari038c6f22014-12-13 00:37:43 -0300487 struct rtl2832_dev *dev = fe->demodulator_priv;
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300488 struct i2c_client *client = dev->client;
Antti Palosaari298efdd2012-09-11 22:27:11 -0300489
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300490 dev_dbg(&client->dev, "\n");
Thomas Mair82041c02012-05-18 14:47:40 -0300491 s->min_delay_ms = 1000;
492 s->step_size = fe->ops.info.frequency_stepsize * 2;
493 s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
494 return 0;
495}
496
497static int rtl2832_set_frontend(struct dvb_frontend *fe)
498{
Antti Palosaari038c6f22014-12-13 00:37:43 -0300499 struct rtl2832_dev *dev = fe->demodulator_priv;
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300500 struct i2c_client *client = dev->client;
Thomas Mair82041c02012-05-18 14:47:40 -0300501 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
502 int ret, i, j;
503 u64 bw_mode, num, num2;
504 u32 resamp_ratio, cfreq_off_ratio;
Thomas Mair82041c02012-05-18 14:47:40 -0300505 static u8 bw_params[3][32] = {
506 /* 6 MHz bandwidth */
507 {
508 0xf5, 0xff, 0x15, 0x38, 0x5d, 0x6d, 0x52, 0x07, 0xfa, 0x2f,
509 0x53, 0xf5, 0x3f, 0xca, 0x0b, 0x91, 0xea, 0x30, 0x63, 0xb2,
510 0x13, 0xda, 0x0b, 0xc4, 0x18, 0x7e, 0x16, 0x66, 0x08, 0x67,
511 0x19, 0xe0,
512 },
513
514 /* 7 MHz bandwidth */
515 {
516 0xe7, 0xcc, 0xb5, 0xba, 0xe8, 0x2f, 0x67, 0x61, 0x00, 0xaf,
517 0x86, 0xf2, 0xbf, 0x59, 0x04, 0x11, 0xb6, 0x33, 0xa4, 0x30,
518 0x15, 0x10, 0x0a, 0x42, 0x18, 0xf8, 0x17, 0xd9, 0x07, 0x22,
519 0x19, 0x10,
520 },
521
522 /* 8 MHz bandwidth */
523 {
524 0x09, 0xf6, 0xd2, 0xa7, 0x9a, 0xc9, 0x27, 0x77, 0x06, 0xbf,
525 0xec, 0xf4, 0x4f, 0x0b, 0xfc, 0x01, 0x63, 0x35, 0x54, 0xa7,
526 0x16, 0x66, 0x08, 0xb4, 0x19, 0x6e, 0x19, 0x65, 0x05, 0xc8,
527 0x19, 0xe0,
528 },
529 };
530
531
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300532 dev_dbg(&client->dev, "frequency=%u bandwidth_hz=%u inversion=%u\n",
533 c->frequency, c->bandwidth_hz, c->inversion);
Thomas Mair82041c02012-05-18 14:47:40 -0300534
535 /* program tuner */
536 if (fe->ops.tuner_ops.set_params)
537 fe->ops.tuner_ops.set_params(fe);
538
Antti Palosaarife37b382013-11-28 19:15:19 -0300539 /* PIP mode related */
Antti Palosaari038c6f22014-12-13 00:37:43 -0300540 ret = rtl2832_wr_regs(dev, 0x92, 1, "\x00\x0f\xff", 3);
Antti Palosaarife37b382013-11-28 19:15:19 -0300541 if (ret)
542 goto err;
543
Mauro Carvalho Chehabfa4bfd22013-04-09 18:19:50 -0300544 /* If the frontend has get_if_frequency(), use it */
545 if (fe->ops.tuner_ops.get_if_frequency) {
546 u32 if_freq;
Mauro Carvalho Chehabfa4bfd22013-04-09 18:19:50 -0300547
548 ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_freq);
549 if (ret)
550 goto err;
551
Mauro Carvalho Chehab884655a2013-04-09 22:16:52 -0300552 ret = rtl2832_set_if(fe, if_freq);
Mauro Carvalho Chehabfa4bfd22013-04-09 18:19:50 -0300553 if (ret)
554 goto err;
555 }
556
Thomas Mair82041c02012-05-18 14:47:40 -0300557 switch (c->bandwidth_hz) {
558 case 6000000:
559 i = 0;
560 bw_mode = 48000000;
561 break;
562 case 7000000:
563 i = 1;
564 bw_mode = 56000000;
565 break;
566 case 8000000:
567 i = 2;
568 bw_mode = 64000000;
569 break;
570 default:
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300571 dev_err(&client->dev, "invalid bandwidth_hz %u\n",
572 c->bandwidth_hz);
573 ret = -EINVAL;
574 goto err;
Thomas Mair82041c02012-05-18 14:47:40 -0300575 }
576
Hans-Frieder Vogtfc4b3fa2012-07-15 13:56:47 -0300577 for (j = 0; j < sizeof(bw_params[0]); j++) {
Antti Palosaari038c6f22014-12-13 00:37:43 -0300578 ret = rtl2832_wr_regs(dev, 0x1c+j, 1, &bw_params[i][j], 1);
Thomas Mair82041c02012-05-18 14:47:40 -0300579 if (ret)
580 goto err;
581 }
582
583 /* calculate and set resample ratio
584 * RSAMP_RATIO = floor(CrystalFreqHz * 7 * pow(2, 22)
585 * / ConstWithBandwidthMode)
586 */
Antti Palosaarie1174d72014-12-13 05:26:27 -0300587 num = dev->pdata->clk * 7;
Thomas Mair82041c02012-05-18 14:47:40 -0300588 num *= 0x400000;
589 num = div_u64(num, bw_mode);
590 resamp_ratio = num & 0x3ffffff;
Antti Palosaari038c6f22014-12-13 00:37:43 -0300591 ret = rtl2832_wr_demod_reg(dev, DVBT_RSAMP_RATIO, resamp_ratio);
Thomas Mair82041c02012-05-18 14:47:40 -0300592 if (ret)
593 goto err;
594
595 /* calculate and set cfreq off ratio
596 * CFREQ_OFF_RATIO = - floor(ConstWithBandwidthMode * pow(2, 20)
597 * / (CrystalFreqHz * 7))
598 */
599 num = bw_mode << 20;
Antti Palosaarie1174d72014-12-13 05:26:27 -0300600 num2 = dev->pdata->clk * 7;
Thomas Mair82041c02012-05-18 14:47:40 -0300601 num = div_u64(num, num2);
602 num = -num;
603 cfreq_off_ratio = num & 0xfffff;
Antti Palosaari038c6f22014-12-13 00:37:43 -0300604 ret = rtl2832_wr_demod_reg(dev, DVBT_CFREQ_OFF_RATIO, cfreq_off_ratio);
Thomas Mair82041c02012-05-18 14:47:40 -0300605 if (ret)
606 goto err;
607
Thomas Mair82041c02012-05-18 14:47:40 -0300608 /* soft reset */
Antti Palosaari038c6f22014-12-13 00:37:43 -0300609 ret = rtl2832_wr_demod_reg(dev, DVBT_SOFT_RST, 0x1);
Thomas Mair82041c02012-05-18 14:47:40 -0300610 if (ret)
611 goto err;
612
Antti Palosaari038c6f22014-12-13 00:37:43 -0300613 ret = rtl2832_wr_demod_reg(dev, DVBT_SOFT_RST, 0x0);
Thomas Mair82041c02012-05-18 14:47:40 -0300614 if (ret)
615 goto err;
616
617 return ret;
618err:
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300619 dev_dbg(&client->dev, "failed=%d\n", ret);
Thomas Mair82041c02012-05-18 14:47:40 -0300620 return ret;
621}
622
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300623static int rtl2832_get_frontend(struct dvb_frontend *fe)
624{
Antti Palosaari038c6f22014-12-13 00:37:43 -0300625 struct rtl2832_dev *dev = fe->demodulator_priv;
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300626 struct i2c_client *client = dev->client;
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300627 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
628 int ret;
629 u8 buf[3];
630
Antti Palosaari038c6f22014-12-13 00:37:43 -0300631 if (dev->sleeping)
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300632 return 0;
633
Antti Palosaari038c6f22014-12-13 00:37:43 -0300634 ret = rtl2832_rd_regs(dev, 0x3c, 3, buf, 2);
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300635 if (ret)
636 goto err;
637
Antti Palosaari038c6f22014-12-13 00:37:43 -0300638 ret = rtl2832_rd_reg(dev, 0x51, 3, &buf[2]);
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300639 if (ret)
640 goto err;
641
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300642 dev_dbg(&client->dev, "TPS=%*ph\n", 3, buf);
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300643
644 switch ((buf[0] >> 2) & 3) {
645 case 0:
646 c->modulation = QPSK;
647 break;
648 case 1:
649 c->modulation = QAM_16;
650 break;
651 case 2:
652 c->modulation = QAM_64;
653 break;
654 }
655
656 switch ((buf[2] >> 2) & 1) {
657 case 0:
658 c->transmission_mode = TRANSMISSION_MODE_2K;
659 break;
660 case 1:
661 c->transmission_mode = TRANSMISSION_MODE_8K;
662 }
663
664 switch ((buf[2] >> 0) & 3) {
665 case 0:
666 c->guard_interval = GUARD_INTERVAL_1_32;
667 break;
668 case 1:
669 c->guard_interval = GUARD_INTERVAL_1_16;
670 break;
671 case 2:
672 c->guard_interval = GUARD_INTERVAL_1_8;
673 break;
674 case 3:
675 c->guard_interval = GUARD_INTERVAL_1_4;
676 break;
677 }
678
679 switch ((buf[0] >> 4) & 7) {
680 case 0:
681 c->hierarchy = HIERARCHY_NONE;
682 break;
683 case 1:
684 c->hierarchy = HIERARCHY_1;
685 break;
686 case 2:
687 c->hierarchy = HIERARCHY_2;
688 break;
689 case 3:
690 c->hierarchy = HIERARCHY_4;
691 break;
692 }
693
694 switch ((buf[1] >> 3) & 7) {
695 case 0:
696 c->code_rate_HP = FEC_1_2;
697 break;
698 case 1:
699 c->code_rate_HP = FEC_2_3;
700 break;
701 case 2:
702 c->code_rate_HP = FEC_3_4;
703 break;
704 case 3:
705 c->code_rate_HP = FEC_5_6;
706 break;
707 case 4:
708 c->code_rate_HP = FEC_7_8;
709 break;
710 }
711
712 switch ((buf[1] >> 0) & 7) {
713 case 0:
714 c->code_rate_LP = FEC_1_2;
715 break;
716 case 1:
717 c->code_rate_LP = FEC_2_3;
718 break;
719 case 2:
720 c->code_rate_LP = FEC_3_4;
721 break;
722 case 3:
723 c->code_rate_LP = FEC_5_6;
724 break;
725 case 4:
726 c->code_rate_LP = FEC_7_8;
727 break;
728 }
729
730 return 0;
731err:
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300732 dev_dbg(&client->dev, "failed=%d\n", ret);
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300733 return ret;
734}
735
Thomas Mair82041c02012-05-18 14:47:40 -0300736static int rtl2832_read_status(struct dvb_frontend *fe, fe_status_t *status)
737{
Antti Palosaari038c6f22014-12-13 00:37:43 -0300738 struct rtl2832_dev *dev = fe->demodulator_priv;
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300739 struct i2c_client *client = dev->client;
Thomas Mair82041c02012-05-18 14:47:40 -0300740 int ret;
741 u32 tmp;
Thomas Mair82041c02012-05-18 14:47:40 -0300742
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300743 dev_dbg(&client->dev, "\n");
744
745 *status = 0;
Antti Palosaari038c6f22014-12-13 00:37:43 -0300746 if (dev->sleeping)
Thomas Mair82041c02012-05-18 14:47:40 -0300747 return 0;
748
Antti Palosaari038c6f22014-12-13 00:37:43 -0300749 ret = rtl2832_rd_demod_reg(dev, DVBT_FSM_STAGE, &tmp);
Thomas Mair82041c02012-05-18 14:47:40 -0300750 if (ret)
751 goto err;
752
753 if (tmp == 11) {
754 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
755 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
Antti Palosaari1c7da402014-12-14 12:15:55 -0300756 } else if (tmp == 10) {
Thomas Mair82041c02012-05-18 14:47:40 -0300757 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
758 FE_HAS_VITERBI;
Antti Palosaari1c7da402014-12-14 12:15:55 -0300759 }
Thomas Mair82041c02012-05-18 14:47:40 -0300760
Antti Palosaari19d273d2014-12-14 06:55:43 -0300761 dev->fe_status = *status;
Thomas Mair82041c02012-05-18 14:47:40 -0300762 return ret;
763err:
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300764 dev_dbg(&client->dev, "failed=%d\n", ret);
Thomas Mair82041c02012-05-18 14:47:40 -0300765 return ret;
766}
767
Antti Palosaari73983492012-08-21 19:56:21 -0300768static int rtl2832_read_snr(struct dvb_frontend *fe, u16 *snr)
769{
Antti Palosaarif7caf932014-12-14 10:05:49 -0300770 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
Antti Palosaari73983492012-08-21 19:56:21 -0300771
Antti Palosaarif7caf932014-12-14 10:05:49 -0300772 /* report SNR in resolution of 0.1 dB */
773 if (c->cnr.stat[0].scale == FE_SCALE_DECIBEL)
774 *snr = div_s64(c->cnr.stat[0].svalue, 100);
Antti Palosaari73983492012-08-21 19:56:21 -0300775 else
776 *snr = 0;
777
778 return 0;
Antti Palosaari73983492012-08-21 19:56:21 -0300779}
780
Antti Palosaaridb32d742012-08-21 19:56:22 -0300781static int rtl2832_read_ber(struct dvb_frontend *fe, u32 *ber)
782{
Antti Palosaari038c6f22014-12-13 00:37:43 -0300783 struct rtl2832_dev *dev = fe->demodulator_priv;
Antti Palosaaridb32d742012-08-21 19:56:22 -0300784
Antti Palosaari084330b2014-12-14 10:10:22 -0300785 *ber = (dev->post_bit_error - dev->post_bit_error_prev);
786 dev->post_bit_error_prev = dev->post_bit_error;
Antti Palosaaridb32d742012-08-21 19:56:22 -0300787
788 return 0;
Antti Palosaaridb32d742012-08-21 19:56:22 -0300789}
790
Antti Palosaari19d273d2014-12-14 06:55:43 -0300791static void rtl2832_stat_work(struct work_struct *work)
792{
793 struct rtl2832_dev *dev = container_of(work, struct rtl2832_dev, stat_work.work);
794 struct i2c_client *client = dev->client;
795 struct dtv_frontend_properties *c = &dev->fe.dtv_property_cache;
796 int ret, tmp;
797 u8 u8tmp, buf[2];
798 u16 u16tmp;
799
800 dev_dbg(&client->dev, "\n");
801
Antti Palosaari25ef9f52014-12-14 11:00:50 -0300802 /* signal strength */
803 if (dev->fe_status & FE_HAS_SIGNAL) {
804 /* read digital AGC */
805 ret = rtl2832_bulk_read(client, 0x305, &u8tmp, 1);
806 if (ret)
807 goto err;
808
809 dev_dbg(&client->dev, "digital agc=%02x", u8tmp);
810
811 u8tmp = ~u8tmp;
812 u16tmp = u8tmp << 8 | u8tmp << 0;
813
814 c->strength.stat[0].scale = FE_SCALE_RELATIVE;
815 c->strength.stat[0].uvalue = u16tmp;
816 } else {
817 c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
818 }
819
Antti Palosaari19d273d2014-12-14 06:55:43 -0300820 /* CNR */
821 if (dev->fe_status & FE_HAS_VITERBI) {
822 unsigned hierarchy, constellation;
823 #define CONSTELLATION_NUM 3
824 #define HIERARCHY_NUM 4
825 static const u32 constant[CONSTELLATION_NUM][HIERARCHY_NUM] = {
826 {85387325, 85387325, 85387325, 85387325},
827 {86676178, 86676178, 87167949, 87795660},
828 {87659938, 87659938, 87885178, 88241743},
829 };
830
831 ret = rtl2832_bulk_read(client, 0x33c, &u8tmp, 1);
832 if (ret)
833 goto err;
834
835 constellation = (u8tmp >> 2) & 0x03; /* [3:2] */
836 if (constellation > CONSTELLATION_NUM - 1)
837 goto err_schedule_delayed_work;
838
839 hierarchy = (u8tmp >> 4) & 0x07; /* [6:4] */
840 if (hierarchy > HIERARCHY_NUM - 1)
841 goto err_schedule_delayed_work;
842
843 ret = rtl2832_bulk_read(client, 0x40c, buf, 2);
844 if (ret)
845 goto err;
846
847 u16tmp = buf[0] << 8 | buf[1] << 0;
848 if (u16tmp)
849 tmp = (constant[constellation][hierarchy] -
850 intlog10(u16tmp)) / ((1 << 24) / 10000);
851 else
852 tmp = 0;
853
854 dev_dbg(&client->dev, "cnr raw=%u\n", u16tmp);
855
856 c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
857 c->cnr.stat[0].svalue = tmp;
858 } else {
859 c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
860 }
861
Antti Palosaari6b4fd012014-12-14 09:59:20 -0300862 /* BER */
863 if (dev->fe_status & FE_HAS_LOCK) {
864 ret = rtl2832_bulk_read(client, 0x34e, buf, 2);
865 if (ret)
866 goto err;
867
868 u16tmp = buf[0] << 8 | buf[1] << 0;
869 dev->post_bit_error += u16tmp;
870 dev->post_bit_count += 1000000;
871
872 dev_dbg(&client->dev, "ber errors=%u total=1000000\n", u16tmp);
873
874 c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
875 c->post_bit_error.stat[0].uvalue = dev->post_bit_error;
876 c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
877 c->post_bit_count.stat[0].uvalue = dev->post_bit_count;
878 } else {
879 c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
880 c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
881 }
882
Antti Palosaari19d273d2014-12-14 06:55:43 -0300883err_schedule_delayed_work:
884 schedule_delayed_work(&dev->stat_work, msecs_to_jiffies(2000));
885 return;
886err:
887 dev_dbg(&client->dev, "failed=%d\n", ret);
888}
889
Antti Palosaari92d20d92014-02-08 03:50:04 -0300890/*
Antti Palosaarid1016582014-12-14 04:45:57 -0300891 * I2C gate/mux/repeater logic
892 * We must use unlocked __i2c_transfer() here (through regmap) because of I2C
893 * adapter lock is already taken by tuner driver.
894 * There is delay mechanism to avoid unneeded I2C gate open / close. Gate close
895 * is delayed here a little bit in order to see if there is sequence of I2C
Antti Palosaari92d20d92014-02-08 03:50:04 -0300896 * messages sent to same I2C bus.
Antti Palosaari92d20d92014-02-08 03:50:04 -0300897 */
898static void rtl2832_i2c_gate_work(struct work_struct *work)
Antti Palosaari8823f022013-11-26 12:53:46 -0300899{
Antti Palosaarid1016582014-12-14 04:45:57 -0300900 struct rtl2832_dev *dev = container_of(work, struct rtl2832_dev, i2c_gate_work.work);
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300901 struct i2c_client *client = dev->client;
Antti Palosaari0ea872d2013-12-03 18:19:39 -0300902 int ret;
Antti Palosaari8823f022013-11-26 12:53:46 -0300903
Antti Palosaarid1016582014-12-14 04:45:57 -0300904 /* close gate */
905 ret = rtl2832_update_bits(dev->client, 0x101, 0x08, 0x00);
906 if (ret)
Antti Palosaari92d20d92014-02-08 03:50:04 -0300907 goto err;
908
Antti Palosaari92d20d92014-02-08 03:50:04 -0300909 return;
910err:
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300911 dev_dbg(&client->dev, "failed=%d\n", ret);
Antti Palosaari92d20d92014-02-08 03:50:04 -0300912 return;
913}
914
915static int rtl2832_select(struct i2c_adapter *adap, void *mux_priv, u32 chan_id)
916{
Antti Palosaari038c6f22014-12-13 00:37:43 -0300917 struct rtl2832_dev *dev = mux_priv;
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300918 struct i2c_client *client = dev->client;
Antti Palosaari92d20d92014-02-08 03:50:04 -0300919 int ret;
Antti Palosaari92d20d92014-02-08 03:50:04 -0300920
921 /* terminate possible gate closing */
Antti Palosaarid1016582014-12-14 04:45:57 -0300922 cancel_delayed_work(&dev->i2c_gate_work);
Antti Palosaari92d20d92014-02-08 03:50:04 -0300923
Antti Palosaarid1016582014-12-14 04:45:57 -0300924 /*
925 * chan_id 1 is muxed adapter demod provides and chan_id 0 is demod
926 * itself. We need open gate when request is for chan_id 1. On that case
927 * I2C adapter lock is already taken and due to that we will use
928 * regmap_update_bits() which does not lock again I2C adapter.
929 */
Antti Palosaari0ea872d2013-12-03 18:19:39 -0300930 if (chan_id == 1)
Antti Palosaarid1016582014-12-14 04:45:57 -0300931 ret = regmap_update_bits(dev->regmap, 0x101, 0x08, 0x08);
Antti Palosaari0ea872d2013-12-03 18:19:39 -0300932 else
Antti Palosaarid1016582014-12-14 04:45:57 -0300933 ret = rtl2832_update_bits(dev->client, 0x101, 0x08, 0x00);
934 if (ret)
Antti Palosaari0ea872d2013-12-03 18:19:39 -0300935 goto err;
936
Antti Palosaari0ea872d2013-12-03 18:19:39 -0300937 return 0;
938err:
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300939 dev_dbg(&client->dev, "failed=%d\n", ret);
Antti Palosaarid1016582014-12-14 04:45:57 -0300940 return ret;
Antti Palosaari8823f022013-11-26 12:53:46 -0300941}
942
Antti Palosaari92d20d92014-02-08 03:50:04 -0300943static int rtl2832_deselect(struct i2c_adapter *adap, void *mux_priv,
Antti Palosaarid1016582014-12-14 04:45:57 -0300944 u32 chan_id)
Antti Palosaari92d20d92014-02-08 03:50:04 -0300945{
Antti Palosaari038c6f22014-12-13 00:37:43 -0300946 struct rtl2832_dev *dev = mux_priv;
Antti Palosaari6e6aac62014-12-13 02:28:33 -0300947
Antti Palosaari038c6f22014-12-13 00:37:43 -0300948 schedule_delayed_work(&dev->i2c_gate_work, usecs_to_jiffies(100));
Antti Palosaari92d20d92014-02-08 03:50:04 -0300949 return 0;
950}
951
Thomas Mair82041c02012-05-18 14:47:40 -0300952static struct dvb_frontend_ops rtl2832_ops = {
953 .delsys = { SYS_DVBT },
954 .info = {
955 .name = "Realtek RTL2832 (DVB-T)",
956 .frequency_min = 174000000,
957 .frequency_max = 862000000,
958 .frequency_stepsize = 166667,
959 .caps = FE_CAN_FEC_1_2 |
960 FE_CAN_FEC_2_3 |
961 FE_CAN_FEC_3_4 |
962 FE_CAN_FEC_5_6 |
963 FE_CAN_FEC_7_8 |
964 FE_CAN_FEC_AUTO |
965 FE_CAN_QPSK |
966 FE_CAN_QAM_16 |
967 FE_CAN_QAM_64 |
968 FE_CAN_QAM_AUTO |
969 FE_CAN_TRANSMISSION_MODE_AUTO |
970 FE_CAN_GUARD_INTERVAL_AUTO |
971 FE_CAN_HIERARCHY_AUTO |
972 FE_CAN_RECOVER |
973 FE_CAN_MUTE_TS
974 },
975
Thomas Mair82041c02012-05-18 14:47:40 -0300976 .init = rtl2832_init,
977 .sleep = rtl2832_sleep,
978
979 .get_tune_settings = rtl2832_get_tune_settings,
980
981 .set_frontend = rtl2832_set_frontend,
Antti Palosaari0ce67a22012-08-21 19:56:20 -0300982 .get_frontend = rtl2832_get_frontend,
Thomas Mair82041c02012-05-18 14:47:40 -0300983
984 .read_status = rtl2832_read_status,
Antti Palosaari73983492012-08-21 19:56:21 -0300985 .read_snr = rtl2832_read_snr,
Antti Palosaaridb32d742012-08-21 19:56:22 -0300986 .read_ber = rtl2832_read_ber,
Thomas Mair82041c02012-05-18 14:47:40 -0300987};
988
Antti Palosaarid1016582014-12-14 04:45:57 -0300989/*
990 * We implement own I2C access routines for regmap in order to get manual access
991 * to I2C adapter lock, which is needed for I2C mux adapter.
992 */
993static int rtl2832_regmap_read(void *context, const void *reg_buf,
994 size_t reg_size, void *val_buf, size_t val_size)
995{
996 struct i2c_client *client = context;
997 int ret;
998 struct i2c_msg msg[2] = {
999 {
1000 .addr = client->addr,
1001 .flags = 0,
1002 .len = reg_size,
1003 .buf = (u8 *)reg_buf,
1004 }, {
1005 .addr = client->addr,
1006 .flags = I2C_M_RD,
1007 .len = val_size,
1008 .buf = val_buf,
1009 }
1010 };
1011
1012 ret = __i2c_transfer(client->adapter, msg, 2);
1013 if (ret != 2) {
1014 dev_warn(&client->dev, "i2c reg read failed %d\n", ret);
1015 if (ret >= 0)
1016 ret = -EREMOTEIO;
1017 return ret;
1018 }
1019 return 0;
1020}
1021
1022static int rtl2832_regmap_write(void *context, const void *data, size_t count)
1023{
1024 struct i2c_client *client = context;
1025 int ret;
1026 struct i2c_msg msg[1] = {
1027 {
1028 .addr = client->addr,
1029 .flags = 0,
1030 .len = count,
1031 .buf = (u8 *)data,
1032 }
1033 };
1034
1035 ret = __i2c_transfer(client->adapter, msg, 1);
1036 if (ret != 1) {
1037 dev_warn(&client->dev, "i2c reg write failed %d\n", ret);
1038 if (ret >= 0)
1039 ret = -EREMOTEIO;
1040 return ret;
1041 }
1042 return 0;
1043}
1044
1045static int rtl2832_regmap_gather_write(void *context, const void *reg,
1046 size_t reg_len, const void *val,
1047 size_t val_len)
1048{
1049 struct i2c_client *client = context;
1050 int ret;
1051 u8 buf[256];
1052 struct i2c_msg msg[1] = {
1053 {
1054 .addr = client->addr,
1055 .flags = 0,
1056 .len = 1 + val_len,
1057 .buf = buf,
1058 }
1059 };
1060
1061 buf[0] = *(u8 const *)reg;
1062 memcpy(&buf[1], val, val_len);
1063
1064 ret = __i2c_transfer(client->adapter, msg, 1);
1065 if (ret != 1) {
1066 dev_warn(&client->dev, "i2c reg write failed %d\n", ret);
1067 if (ret >= 0)
1068 ret = -EREMOTEIO;
1069 return ret;
1070 }
1071 return 0;
1072}
1073
Antti Palosaari6f5f6ee2014-12-12 23:16:19 -03001074static struct dvb_frontend *rtl2832_get_dvb_frontend(struct i2c_client *client)
1075{
Antti Palosaari038c6f22014-12-13 00:37:43 -03001076 struct rtl2832_dev *dev = i2c_get_clientdata(client);
Antti Palosaari6f5f6ee2014-12-12 23:16:19 -03001077
1078 dev_dbg(&client->dev, "\n");
1079 return &dev->fe;
1080}
1081
1082static struct i2c_adapter *rtl2832_get_i2c_adapter_(struct i2c_client *client)
1083{
Antti Palosaari038c6f22014-12-13 00:37:43 -03001084 struct rtl2832_dev *dev = i2c_get_clientdata(client);
Antti Palosaari6f5f6ee2014-12-12 23:16:19 -03001085
1086 dev_dbg(&client->dev, "\n");
1087 return dev->i2c_adapter_tuner;
1088}
1089
1090static struct i2c_adapter *rtl2832_get_private_i2c_adapter_(struct i2c_client *client)
1091{
Antti Palosaari038c6f22014-12-13 00:37:43 -03001092 struct rtl2832_dev *dev = i2c_get_clientdata(client);
Antti Palosaari6f5f6ee2014-12-12 23:16:19 -03001093
1094 dev_dbg(&client->dev, "\n");
1095 return dev->i2c_adapter;
1096}
1097
1098static int rtl2832_enable_slave_ts(struct i2c_client *client)
1099{
Antti Palosaari038c6f22014-12-13 00:37:43 -03001100 struct rtl2832_dev *dev = i2c_get_clientdata(client);
Antti Palosaari6f5f6ee2014-12-12 23:16:19 -03001101 int ret;
1102
Antti Palosaari6e6aac62014-12-13 02:28:33 -03001103 dev_dbg(&client->dev, "\n");
Antti Palosaari6f5f6ee2014-12-12 23:16:19 -03001104
1105 ret = rtl2832_wr_regs(dev, 0x0c, 1, "\x5f\xff", 2);
1106 if (ret)
1107 goto err;
1108
1109 ret = rtl2832_wr_demod_reg(dev, DVBT_PIP_ON, 0x1);
1110 if (ret)
1111 goto err;
1112
1113 ret = rtl2832_wr_reg(dev, 0xbc, 0, 0x18);
1114 if (ret)
1115 goto err;
1116
1117 ret = rtl2832_wr_reg(dev, 0x22, 0, 0x01);
1118 if (ret)
1119 goto err;
1120
1121 ret = rtl2832_wr_reg(dev, 0x26, 0, 0x1f);
1122 if (ret)
1123 goto err;
1124
1125 ret = rtl2832_wr_reg(dev, 0x27, 0, 0xff);
1126 if (ret)
1127 goto err;
1128
1129 ret = rtl2832_wr_regs(dev, 0x92, 1, "\x7f\xf7\xff", 3);
1130 if (ret)
1131 goto err;
1132
1133 /* soft reset */
1134 ret = rtl2832_wr_demod_reg(dev, DVBT_SOFT_RST, 0x1);
1135 if (ret)
1136 goto err;
1137
1138 ret = rtl2832_wr_demod_reg(dev, DVBT_SOFT_RST, 0x0);
1139 if (ret)
1140 goto err;
1141
1142 return 0;
1143err:
1144 dev_dbg(&client->dev, "failed=%d\n", ret);
1145 return ret;
1146}
1147
Antti Palosaaric2c83862014-12-02 10:55:17 -03001148static int rtl2832_probe(struct i2c_client *client,
1149 const struct i2c_device_id *id)
1150{
1151 struct rtl2832_platform_data *pdata = client->dev.platform_data;
Antti Palosaaric2c83862014-12-02 10:55:17 -03001152 struct i2c_adapter *i2c = client->adapter;
Antti Palosaari038c6f22014-12-13 00:37:43 -03001153 struct rtl2832_dev *dev;
Antti Palosaaric2c83862014-12-02 10:55:17 -03001154 int ret;
1155 u8 tmp;
Antti Palosaarid1016582014-12-14 04:45:57 -03001156 static const struct regmap_bus regmap_bus = {
1157 .read = rtl2832_regmap_read,
1158 .write = rtl2832_regmap_write,
1159 .gather_write = rtl2832_regmap_gather_write,
1160 .val_format_endian_default = REGMAP_ENDIAN_NATIVE,
1161 };
1162 static const struct regmap_range_cfg regmap_range_cfg[] = {
1163 {
1164 .selector_reg = 0x00,
1165 .selector_mask = 0xff,
1166 .selector_shift = 0,
1167 .window_start = 0,
1168 .window_len = 0x100,
1169 .range_min = 0 * 0x100,
1170 .range_max = 5 * 0x100,
1171 },
1172 };
1173 static const struct regmap_config regmap_config = {
1174 .reg_bits = 8,
1175 .val_bits = 8,
1176 .max_register = 5 * 0x100,
1177 .ranges = regmap_range_cfg,
1178 .num_ranges = ARRAY_SIZE(regmap_range_cfg),
1179 };
Antti Palosaaric2c83862014-12-02 10:55:17 -03001180
1181 dev_dbg(&client->dev, "\n");
1182
Antti Palosaaric2c83862014-12-02 10:55:17 -03001183 /* allocate memory for the internal state */
Antti Palosaari038c6f22014-12-13 00:37:43 -03001184 dev = kzalloc(sizeof(struct rtl2832_dev), GFP_KERNEL);
1185 if (dev == NULL) {
Antti Palosaaric2c83862014-12-02 10:55:17 -03001186 ret = -ENOMEM;
1187 goto err;
1188 }
1189
Antti Palosaari038c6f22014-12-13 00:37:43 -03001190 /* setup the state */
Antti Palosaarid1016582014-12-14 04:45:57 -03001191 i2c_set_clientdata(client, dev);
Antti Palosaari038c6f22014-12-13 00:37:43 -03001192 dev->client = client;
Antti Palosaarie1174d72014-12-13 05:26:27 -03001193 dev->pdata = client->dev.platform_data;
1194 if (pdata->config) {
1195 dev->pdata->clk = pdata->config->xtal;
1196 dev->pdata->tuner = pdata->config->tuner;
1197 }
Antti Palosaari038c6f22014-12-13 00:37:43 -03001198 dev->sleeping = true;
Antti Palosaari038c6f22014-12-13 00:37:43 -03001199 INIT_DELAYED_WORK(&dev->i2c_gate_work, rtl2832_i2c_gate_work);
Antti Palosaari19d273d2014-12-14 06:55:43 -03001200 INIT_DELAYED_WORK(&dev->stat_work, rtl2832_stat_work);
Antti Palosaarid1016582014-12-14 04:45:57 -03001201 /* create regmap */
1202 dev->regmap = regmap_init(&client->dev, &regmap_bus, client,
1203 &regmap_config);
1204 if (IS_ERR(dev->regmap)) {
1205 ret = PTR_ERR(dev->regmap);
1206 goto err_kfree;
1207 }
Antti Palosaaric2c83862014-12-02 10:55:17 -03001208 /* create muxed i2c adapter for demod itself */
Antti Palosaari038c6f22014-12-13 00:37:43 -03001209 dev->i2c_adapter = i2c_add_mux_adapter(i2c, &i2c->dev, dev, 0, 0, 0,
Antti Palosaaric2c83862014-12-02 10:55:17 -03001210 rtl2832_select, NULL);
Antti Palosaari038c6f22014-12-13 00:37:43 -03001211 if (dev->i2c_adapter == NULL) {
Antti Palosaaric2c83862014-12-02 10:55:17 -03001212 ret = -ENODEV;
Antti Palosaarid1016582014-12-14 04:45:57 -03001213 goto err_regmap_exit;
Antti Palosaaric2c83862014-12-02 10:55:17 -03001214 }
1215
1216 /* check if the demod is there */
Antti Palosaari038c6f22014-12-13 00:37:43 -03001217 ret = rtl2832_rd_reg(dev, 0x00, 0x0, &tmp);
Antti Palosaaric2c83862014-12-02 10:55:17 -03001218 if (ret)
1219 goto err_i2c_del_mux_adapter;
1220
1221 /* create muxed i2c adapter for demod tuner bus */
Antti Palosaari038c6f22014-12-13 00:37:43 -03001222 dev->i2c_adapter_tuner = i2c_add_mux_adapter(i2c, &i2c->dev, dev,
Antti Palosaaric2c83862014-12-02 10:55:17 -03001223 0, 1, 0, rtl2832_select, rtl2832_deselect);
Antti Palosaari038c6f22014-12-13 00:37:43 -03001224 if (dev->i2c_adapter_tuner == NULL) {
Antti Palosaaric2c83862014-12-02 10:55:17 -03001225 ret = -ENODEV;
1226 goto err_i2c_del_mux_adapter;
1227 }
1228
1229 /* create dvb_frontend */
Antti Palosaari038c6f22014-12-13 00:37:43 -03001230 memcpy(&dev->fe.ops, &rtl2832_ops, sizeof(struct dvb_frontend_ops));
1231 dev->fe.demodulator_priv = dev;
Antti Palosaari6f5f6ee2014-12-12 23:16:19 -03001232
1233 /* setup callbacks */
1234 pdata->get_dvb_frontend = rtl2832_get_dvb_frontend;
1235 pdata->get_i2c_adapter = rtl2832_get_i2c_adapter_;
1236 pdata->get_private_i2c_adapter = rtl2832_get_private_i2c_adapter_;
1237 pdata->enable_slave_ts = rtl2832_enable_slave_ts;
Antti Palosaaric2c83862014-12-02 10:55:17 -03001238
1239 dev_info(&client->dev, "Realtek RTL2832 successfully attached\n");
1240 return 0;
1241err_i2c_del_mux_adapter:
Antti Palosaari038c6f22014-12-13 00:37:43 -03001242 i2c_del_mux_adapter(dev->i2c_adapter);
Antti Palosaarid1016582014-12-14 04:45:57 -03001243err_regmap_exit:
1244 regmap_exit(dev->regmap);
Antti Palosaaric2c83862014-12-02 10:55:17 -03001245err_kfree:
Antti Palosaari038c6f22014-12-13 00:37:43 -03001246 kfree(dev);
Antti Palosaaric2c83862014-12-02 10:55:17 -03001247err:
1248 dev_dbg(&client->dev, "failed=%d\n", ret);
1249 return ret;
1250}
1251
1252static int rtl2832_remove(struct i2c_client *client)
1253{
Antti Palosaari038c6f22014-12-13 00:37:43 -03001254 struct rtl2832_dev *dev = i2c_get_clientdata(client);
Antti Palosaaric2c83862014-12-02 10:55:17 -03001255
1256 dev_dbg(&client->dev, "\n");
1257
Antti Palosaari038c6f22014-12-13 00:37:43 -03001258 cancel_delayed_work_sync(&dev->i2c_gate_work);
Antti Palosaaric2c83862014-12-02 10:55:17 -03001259
Antti Palosaari038c6f22014-12-13 00:37:43 -03001260 i2c_del_mux_adapter(dev->i2c_adapter_tuner);
Antti Palosaaric2c83862014-12-02 10:55:17 -03001261
Antti Palosaari038c6f22014-12-13 00:37:43 -03001262 i2c_del_mux_adapter(dev->i2c_adapter);
Antti Palosaaric2c83862014-12-02 10:55:17 -03001263
Antti Palosaarid1016582014-12-14 04:45:57 -03001264 regmap_exit(dev->regmap);
1265
Antti Palosaari038c6f22014-12-13 00:37:43 -03001266 kfree(dev);
Antti Palosaaric2c83862014-12-02 10:55:17 -03001267
1268 return 0;
1269}
1270
1271static const struct i2c_device_id rtl2832_id_table[] = {
1272 {"rtl2832", 0},
1273 {}
1274};
1275MODULE_DEVICE_TABLE(i2c, rtl2832_id_table);
1276
1277static struct i2c_driver rtl2832_driver = {
1278 .driver = {
1279 .owner = THIS_MODULE,
1280 .name = "rtl2832",
1281 },
1282 .probe = rtl2832_probe,
1283 .remove = rtl2832_remove,
1284 .id_table = rtl2832_id_table,
1285};
1286
1287module_i2c_driver(rtl2832_driver);
1288
Thomas Mair82041c02012-05-18 14:47:40 -03001289MODULE_AUTHOR("Thomas Mair <mair.thomas86@gmail.com>");
1290MODULE_DESCRIPTION("Realtek RTL2832 DVB-T demodulator driver");
1291MODULE_LICENSE("GPL");
1292MODULE_VERSION("0.5");