blob: 41e1f5537f44b5b67d31140f52fec2f9cc25224b [file] [log] [blame]
Antti Palosaari831e0b72011-07-08 23:36:07 -03001/*
2 * Realtek RTL28xxU DVB USB driver
3 *
4 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
5 * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
6 *
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 "rtl28xxu.h"
23
24#include "rtl2830.h"
25
26#include "qt1010.h"
27#include "mt2060.h"
28#include "mxl5005s.h"
29
30/* debug */
31static int dvb_usb_rtl28xxu_debug;
32module_param_named(debug, dvb_usb_rtl28xxu_debug, int, 0644);
33MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
34DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
35
36static int rtl28xxu_ctrl_msg(struct dvb_usb_device *d, struct rtl28xxu_req *req)
37{
38 int ret;
39 unsigned int pipe;
40 u8 requesttype;
41 u8 *buf;
42
43 buf = kmalloc(req->size, GFP_KERNEL);
44 if (!buf) {
45 ret = -ENOMEM;
46 goto err;
47 }
48
49 if (req->index & CMD_WR_FLAG) {
50 /* write */
51 memcpy(buf, req->data, req->size);
52 requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
53 pipe = usb_sndctrlpipe(d->udev, 0);
54 } else {
55 /* read */
56 requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
57 pipe = usb_rcvctrlpipe(d->udev, 0);
58 }
59
60 ret = usb_control_msg(d->udev, pipe, 0, requesttype, req->value,
Antti Palosaari9935eea2012-01-21 22:26:52 -030061 req->index, buf, req->size, 1000);
62 if (ret > 0)
63 ret = 0;
Antti Palosaari831e0b72011-07-08 23:36:07 -030064
65 deb_dump(0, requesttype, req->value, req->index, buf, req->size,
Antti Palosaari9935eea2012-01-21 22:26:52 -030066 deb_xfer);
Antti Palosaari831e0b72011-07-08 23:36:07 -030067
68 /* read request, copy returned data to return buf */
69 if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
70 memcpy(req->data, buf, req->size);
71
72 kfree(buf);
Antti Palosaari831e0b72011-07-08 23:36:07 -030073
Antti Palosaari9935eea2012-01-21 22:26:52 -030074 if (ret)
75 goto err;
76
77 return ret;
Antti Palosaari831e0b72011-07-08 23:36:07 -030078err:
79 deb_info("%s: failed=%d\n", __func__, ret);
80 return ret;
81}
82
83static int rtl2831_wr_regs(struct dvb_usb_device *d, u16 reg, u8 *val, int len)
84{
85 struct rtl28xxu_req req;
86
87 if (reg < 0x3000)
88 req.index = CMD_USB_WR;
Antti Palosaarib5cbaa42011-08-04 13:26:10 -030089 else if (reg < 0x4000)
Antti Palosaari831e0b72011-07-08 23:36:07 -030090 req.index = CMD_SYS_WR;
Antti Palosaarib5cbaa42011-08-04 13:26:10 -030091 else
92 req.index = CMD_IR_WR;
Antti Palosaari831e0b72011-07-08 23:36:07 -030093
94 req.value = reg;
95 req.size = len;
96 req.data = val;
97
98 return rtl28xxu_ctrl_msg(d, &req);
99}
100
101static int rtl2831_rd_regs(struct dvb_usb_device *d, u16 reg, u8 *val, int len)
102{
103 struct rtl28xxu_req req;
104
105 if (reg < 0x3000)
106 req.index = CMD_USB_RD;
Antti Palosaarib5cbaa42011-08-04 13:26:10 -0300107 else if (reg < 0x4000)
Antti Palosaari831e0b72011-07-08 23:36:07 -0300108 req.index = CMD_SYS_RD;
Antti Palosaarib5cbaa42011-08-04 13:26:10 -0300109 else
110 req.index = CMD_IR_RD;
Antti Palosaari831e0b72011-07-08 23:36:07 -0300111
112 req.value = reg;
113 req.size = len;
114 req.data = val;
115
116 return rtl28xxu_ctrl_msg(d, &req);
117}
118
119static int rtl2831_wr_reg(struct dvb_usb_device *d, u16 reg, u8 val)
120{
121 return rtl2831_wr_regs(d, reg, &val, 1);
122}
123
124static int rtl2831_rd_reg(struct dvb_usb_device *d, u16 reg, u8 *val)
125{
126 return rtl2831_rd_regs(d, reg, val, 1);
127}
128
129/* I2C */
130static int rtl28xxu_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
131 int num)
132{
133 int ret;
134 struct dvb_usb_device *d = i2c_get_adapdata(adap);
Antti Palosaari34ec2932011-08-04 20:21:16 -0300135 struct rtl28xxu_priv *priv = d->priv;
Antti Palosaari831e0b72011-07-08 23:36:07 -0300136 struct rtl28xxu_req req;
137
138 /*
139 * It is not known which are real I2C bus xfer limits, but testing
140 * with RTL2831U + MT2060 gives max RD 24 and max WR 22 bytes.
Antti Palosaari34ec2932011-08-04 20:21:16 -0300141 * TODO: find out RTL2832U lens
142 */
143
144 /*
145 * I2C adapter logic looks rather complicated due to fact it handles
146 * three different access methods. Those methods are;
147 * 1) integrated demod access
148 * 2) old I2C access
149 * 3) new I2C access
150 *
151 * Used method is selected in order 1, 2, 3. Method 3 can handle all
152 * requests but there is two reasons why not use it always;
153 * 1) It is most expensive, usually two USB messages are needed
154 * 2) At least RTL2831U does not support it
155 *
156 * Method 3 is needed in case of I2C write+read (typical register read)
157 * where write is more than one byte.
Antti Palosaari831e0b72011-07-08 23:36:07 -0300158 */
159
160 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
161 return -EAGAIN;
162
163 if (num == 2 && !(msg[0].flags & I2C_M_RD) &&
164 (msg[1].flags & I2C_M_RD)) {
Antti Palosaari34ec2932011-08-04 20:21:16 -0300165 if (msg[0].len > 24 || msg[1].len > 24) {
166 /* TODO: check msg[0].len max */
Antti Palosaari831e0b72011-07-08 23:36:07 -0300167 ret = -EOPNOTSUPP;
Antti Palosaari9935eea2012-01-21 22:26:52 -0300168 goto err_mutex_unlock;
Antti Palosaari34ec2932011-08-04 20:21:16 -0300169 } else if (msg[0].addr == 0x10) {
170 /* method 1 - integrated demod */
171 req.value = (msg[0].buf[0] << 8) | (msg[0].addr << 1);
172 req.index = CMD_DEMOD_RD | priv->page;
Antti Palosaari831e0b72011-07-08 23:36:07 -0300173 req.size = msg[1].len;
174 req.data = &msg[1].buf[0];
175 ret = rtl28xxu_ctrl_msg(d, &req);
Antti Palosaari34ec2932011-08-04 20:21:16 -0300176 } else if (msg[0].len < 2) {
177 /* method 2 - old I2C */
Antti Palosaari831e0b72011-07-08 23:36:07 -0300178 req.value = (msg[0].buf[0] << 8) | (msg[0].addr << 1);
179 req.index = CMD_I2C_RD;
180 req.size = msg[1].len;
181 req.data = &msg[1].buf[0];
182 ret = rtl28xxu_ctrl_msg(d, &req);
Antti Palosaari34ec2932011-08-04 20:21:16 -0300183 } else {
184 /* method 3 - new I2C */
185 req.value = (msg[0].addr << 1);
186 req.index = CMD_I2C_DA_WR;
187 req.size = msg[0].len;
188 req.data = msg[0].buf;
189 ret = rtl28xxu_ctrl_msg(d, &req);
190 if (ret)
Antti Palosaari9935eea2012-01-21 22:26:52 -0300191 goto err_mutex_unlock;
Antti Palosaari34ec2932011-08-04 20:21:16 -0300192
193 req.value = (msg[0].addr << 1);
194 req.index = CMD_I2C_DA_RD;
195 req.size = msg[1].len;
196 req.data = msg[1].buf;
197 ret = rtl28xxu_ctrl_msg(d, &req);
Antti Palosaari831e0b72011-07-08 23:36:07 -0300198 }
199 } else if (num == 1 && !(msg[0].flags & I2C_M_RD)) {
200 if (msg[0].len > 22) {
Antti Palosaari34ec2932011-08-04 20:21:16 -0300201 /* TODO: check msg[0].len max */
Antti Palosaari831e0b72011-07-08 23:36:07 -0300202 ret = -EOPNOTSUPP;
Antti Palosaari9935eea2012-01-21 22:26:52 -0300203 goto err_mutex_unlock;
Antti Palosaari34ec2932011-08-04 20:21:16 -0300204 } else if (msg[0].addr == 0x10) {
205 /* method 1 - integrated demod */
206 if (msg[0].buf[0] == 0x00) {
207 /* save demod page for later demod access */
208 priv->page = msg[0].buf[1];
209 ret = 0;
210 } else {
211 req.value = (msg[0].buf[0] << 8) |
212 (msg[0].addr << 1);
213 req.index = CMD_DEMOD_WR | priv->page;
214 req.size = msg[0].len-1;
215 req.data = &msg[0].buf[1];
216 ret = rtl28xxu_ctrl_msg(d, &req);
217 }
218 } else if (msg[0].len < 23) {
219 /* method 2 - old I2C */
Antti Palosaari831e0b72011-07-08 23:36:07 -0300220 req.value = (msg[0].buf[0] << 8) | (msg[0].addr << 1);
221 req.index = CMD_I2C_WR;
222 req.size = msg[0].len-1;
223 req.data = &msg[0].buf[1];
224 ret = rtl28xxu_ctrl_msg(d, &req);
Antti Palosaari34ec2932011-08-04 20:21:16 -0300225 } else {
226 /* method 3 - new I2C */
227 req.value = (msg[0].addr << 1);
228 req.index = CMD_I2C_DA_WR;
229 req.size = msg[0].len;
230 req.data = msg[0].buf;
231 ret = rtl28xxu_ctrl_msg(d, &req);
Antti Palosaari831e0b72011-07-08 23:36:07 -0300232 }
233 } else {
234 ret = -EINVAL;
235 }
236
Antti Palosaari9935eea2012-01-21 22:26:52 -0300237err_mutex_unlock:
Antti Palosaari831e0b72011-07-08 23:36:07 -0300238 mutex_unlock(&d->i2c_mutex);
239
240 return ret ? ret : num;
241}
242
243static u32 rtl28xxu_i2c_func(struct i2c_adapter *adapter)
244{
245 return I2C_FUNC_I2C;
246}
247
248static struct i2c_algorithm rtl28xxu_i2c_algo = {
249 .master_xfer = rtl28xxu_i2c_xfer,
250 .functionality = rtl28xxu_i2c_func,
251};
252
253static struct rtl2830_config rtl28xxu_rtl2830_mt2060_config = {
254 .i2c_addr = 0x10, /* 0x20 */
255 .xtal = 28800000,
256 .ts_mode = 0,
257 .spec_inv = 1,
258 .if_dvbt = 36150000,
259 .vtop = 0x20,
260 .krf = 0x04,
261 .agc_targ_val = 0x2d,
262
263};
264
265static struct rtl2830_config rtl28xxu_rtl2830_qt1010_config = {
266 .i2c_addr = 0x10, /* 0x20 */
267 .xtal = 28800000,
268 .ts_mode = 0,
269 .spec_inv = 1,
270 .if_dvbt = 36125000,
271 .vtop = 0x20,
272 .krf = 0x04,
273 .agc_targ_val = 0x2d,
274};
275
276static struct rtl2830_config rtl28xxu_rtl2830_mxl5005s_config = {
277 .i2c_addr = 0x10, /* 0x20 */
278 .xtal = 28800000,
279 .ts_mode = 0,
280 .spec_inv = 0,
281 .if_dvbt = 4570000,
282 .vtop = 0x3f,
283 .krf = 0x04,
284 .agc_targ_val = 0x3e,
285};
286
Antti Palosaarib5cbaa42011-08-04 13:26:10 -0300287static int rtl2831u_frontend_attach(struct dvb_usb_adapter *adap)
Antti Palosaari831e0b72011-07-08 23:36:07 -0300288{
289 int ret;
290 struct rtl28xxu_priv *priv = adap->dev->priv;
291 u8 buf[1];
292 struct rtl2830_config *rtl2830_config;
Antti Palosaarib5cbaa42011-08-04 13:26:10 -0300293 /* open RTL2831U/RTL2830 I2C gate */
Antti Palosaari9935eea2012-01-21 22:26:52 -0300294 struct rtl28xxu_req req_gate = { 0x0120, 0x0011, 0x0001, "\x08" };
Antti Palosaari831e0b72011-07-08 23:36:07 -0300295 /* for MT2060 tuner probe */
Antti Palosaari9935eea2012-01-21 22:26:52 -0300296 struct rtl28xxu_req req_mt2060 = { 0x00c0, CMD_I2C_RD, 1, buf };
Antti Palosaari831e0b72011-07-08 23:36:07 -0300297 /* for QT1010 tuner probe */
Antti Palosaari9935eea2012-01-21 22:26:52 -0300298 struct rtl28xxu_req req_qt1010 = { 0x0fc4, CMD_I2C_RD, 1, buf };
Antti Palosaari831e0b72011-07-08 23:36:07 -0300299
300 deb_info("%s:\n", __func__);
301
302 /*
303 * RTL2831U GPIOs
304 * =========================================================
305 * GPIO0 | tuner#0 | 0 off | 1 on | MXL5005S (?)
306 * GPIO2 | LED | 0 off | 1 on |
307 * GPIO4 | tuner#1 | 0 on | 1 off | MT2060
308 */
309
310 /* GPIO direction */
311 ret = rtl2831_wr_reg(adap->dev, SYS_GPIO_DIR, 0x0a);
312 if (ret)
313 goto err;
314
315 /* enable as output GPIO0, GPIO2, GPIO4 */
316 ret = rtl2831_wr_reg(adap->dev, SYS_GPIO_OUT_EN, 0x15);
317 if (ret)
318 goto err;
319
320 /*
321 * Probe used tuner. We need to know used tuner before demod attach
322 * since there is some demod params needed to set according to tuner.
323 */
324
Antti Palosaariccb5cf92012-05-18 16:07:46 -0300325 /* demod needs some time to wake up */
326 msleep(20);
327
Antti Palosaari831e0b72011-07-08 23:36:07 -0300328 /* open demod I2C gate */
329 ret = rtl28xxu_ctrl_msg(adap->dev, &req_gate);
330 if (ret)
331 goto err;
332
333 /* check QT1010 ID(?) register; reg=0f val=2c */
334 ret = rtl28xxu_ctrl_msg(adap->dev, &req_qt1010);
335 if (ret == 0 && buf[0] == 0x2c) {
336 priv->tuner = TUNER_RTL2830_QT1010;
337 rtl2830_config = &rtl28xxu_rtl2830_qt1010_config;
338 deb_info("%s: QT1010\n", __func__);
339 goto found;
340 } else {
341 deb_info("%s: QT1010 probe failed=%d - %02x\n",
342 __func__, ret, buf[0]);
343 }
344
345 /* open demod I2C gate */
346 ret = rtl28xxu_ctrl_msg(adap->dev, &req_gate);
347 if (ret)
348 goto err;
349
350 /* check MT2060 ID register; reg=00 val=63 */
351 ret = rtl28xxu_ctrl_msg(adap->dev, &req_mt2060);
352 if (ret == 0 && buf[0] == 0x63) {
353 priv->tuner = TUNER_RTL2830_MT2060;
354 rtl2830_config = &rtl28xxu_rtl2830_mt2060_config;
355 deb_info("%s: MT2060\n", __func__);
356 goto found;
357 } else {
358 deb_info("%s: MT2060 probe failed=%d - %02x\n",
359 __func__, ret, buf[0]);
360 }
361
362 /* assume MXL5005S */
Antti Palosaarie9320ec2011-08-03 04:35:30 -0300363 ret = 0;
Antti Palosaari831e0b72011-07-08 23:36:07 -0300364 priv->tuner = TUNER_RTL2830_MXL5005S;
365 rtl2830_config = &rtl28xxu_rtl2830_mxl5005s_config;
366 deb_info("%s: MXL5005S\n", __func__);
367 goto found;
368
369found:
370 /* attach demodulator */
Antti Palosaarifba16b12012-01-21 20:28:38 -0300371 adap->fe_adap[0].fe = dvb_attach(rtl2830_attach, rtl2830_config,
Antti Palosaari831e0b72011-07-08 23:36:07 -0300372 &adap->dev->i2c_adap);
Antti Palosaarifba16b12012-01-21 20:28:38 -0300373 if (adap->fe_adap[0].fe == NULL) {
Antti Palosaari831e0b72011-07-08 23:36:07 -0300374 ret = -ENODEV;
375 goto err;
376 }
377
378 return ret;
379err:
380 deb_info("%s: failed=%d\n", __func__, ret);
381 return ret;
382}
383
Antti Palosaarib5cbaa42011-08-04 13:26:10 -0300384static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
385{
386 int ret;
387 struct rtl28xxu_priv *priv = adap->dev->priv;
388 u8 buf[1];
389 /* open RTL2832U/RTL2832 I2C gate */
390 struct rtl28xxu_req req_gate_open = {0x0120, 0x0011, 0x0001, "\x18"};
391 /* close RTL2832U/RTL2832 I2C gate */
392 struct rtl28xxu_req req_gate_close = {0x0120, 0x0011, 0x0001, "\x10"};
393 /* for FC2580 tuner probe */
394 struct rtl28xxu_req req_fc2580 = {0x01ac, CMD_I2C_RD, 1, buf};
395
396 deb_info("%s:\n", __func__);
397
398 /* GPIO direction */
399 ret = rtl2831_wr_reg(adap->dev, SYS_GPIO_DIR, 0x0a);
400 if (ret)
401 goto err;
402
403 /* enable as output GPIO0, GPIO2, GPIO4 */
404 ret = rtl2831_wr_reg(adap->dev, SYS_GPIO_OUT_EN, 0x15);
405 if (ret)
406 goto err;
407
408 ret = rtl2831_wr_reg(adap->dev, SYS_DEMOD_CTL, 0xe8);
409 if (ret)
410 goto err;
411
412 /*
413 * Probe used tuner. We need to know used tuner before demod attach
414 * since there is some demod params needed to set according to tuner.
415 */
416
417 /* open demod I2C gate */
418 ret = rtl28xxu_ctrl_msg(adap->dev, &req_gate_open);
419 if (ret)
420 goto err;
421
422 /* check FC2580 ID register; reg=01 val=56 */
423 ret = rtl28xxu_ctrl_msg(adap->dev, &req_fc2580);
424 if (ret == 0 && buf[0] == 0x56) {
425 priv->tuner = TUNER_RTL2832_FC2580;
426 deb_info("%s: FC2580\n", __func__);
427 goto found;
428 } else {
429 deb_info("%s: FC2580 probe failed=%d - %02x\n",
430 __func__, ret, buf[0]);
431 }
432
433 /* close demod I2C gate */
434 ret = rtl28xxu_ctrl_msg(adap->dev, &req_gate_close);
435 if (ret)
436 goto err;
437
438 /* tuner not found */
439 ret = -ENODEV;
440 goto err;
441
442found:
443 /* close demod I2C gate */
444 ret = rtl28xxu_ctrl_msg(adap->dev, &req_gate_close);
445 if (ret)
446 goto err;
447
448 /* attach demodulator */
449 /* TODO: */
450
451 return ret;
452err:
453 deb_info("%s: failed=%d\n", __func__, ret);
454 return ret;
455}
456
Antti Palosaari831e0b72011-07-08 23:36:07 -0300457static struct qt1010_config rtl28xxu_qt1010_config = {
458 .i2c_address = 0x62, /* 0xc4 */
459};
460
461static struct mt2060_config rtl28xxu_mt2060_config = {
462 .i2c_address = 0x60, /* 0xc0 */
463 .clock_out = 0,
464};
465
466static struct mxl5005s_config rtl28xxu_mxl5005s_config = {
467 .i2c_address = 0x63, /* 0xc6 */
468 .if_freq = IF_FREQ_4570000HZ,
469 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
470 .agc_mode = MXL_SINGLE_AGC,
471 .tracking_filter = MXL_TF_C_H,
472 .rssi_enable = MXL_RSSI_ENABLE,
473 .cap_select = MXL_CAP_SEL_ENABLE,
474 .div_out = MXL_DIV_OUT_4,
475 .clock_out = MXL_CLOCK_OUT_DISABLE,
476 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
477 .top = MXL5005S_TOP_25P2,
478 .mod_mode = MXL_DIGITAL_MODE,
479 .if_mode = MXL_ZERO_IF,
480 .AgcMasterByte = 0x00,
481};
482
Antti Palosaarib5cbaa42011-08-04 13:26:10 -0300483static int rtl2831u_tuner_attach(struct dvb_usb_adapter *adap)
Antti Palosaari831e0b72011-07-08 23:36:07 -0300484{
485 int ret;
486 struct rtl28xxu_priv *priv = adap->dev->priv;
487 struct i2c_adapter *rtl2830_tuner_i2c;
Antti Palosaari9935eea2012-01-21 22:26:52 -0300488 struct dvb_frontend *fe;
Antti Palosaari831e0b72011-07-08 23:36:07 -0300489
490 deb_info("%s:\n", __func__);
491
492 /* use rtl2830 driver I2C adapter, for more info see rtl2830 driver */
Antti Palosaarifba16b12012-01-21 20:28:38 -0300493 rtl2830_tuner_i2c = rtl2830_get_tuner_i2c_adapter(adap->fe_adap[0].fe);
Antti Palosaari831e0b72011-07-08 23:36:07 -0300494
495 switch (priv->tuner) {
496 case TUNER_RTL2830_QT1010:
Antti Palosaarifba16b12012-01-21 20:28:38 -0300497 fe = dvb_attach(qt1010_attach, adap->fe_adap[0].fe,
498 rtl2830_tuner_i2c, &rtl28xxu_qt1010_config);
Antti Palosaari831e0b72011-07-08 23:36:07 -0300499 break;
500 case TUNER_RTL2830_MT2060:
Antti Palosaarifba16b12012-01-21 20:28:38 -0300501 fe = dvb_attach(mt2060_attach, adap->fe_adap[0].fe,
502 rtl2830_tuner_i2c, &rtl28xxu_mt2060_config,
503 1220);
Antti Palosaari831e0b72011-07-08 23:36:07 -0300504 break;
505 case TUNER_RTL2830_MXL5005S:
Antti Palosaarifba16b12012-01-21 20:28:38 -0300506 fe = dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe,
Antti Palosaari9935eea2012-01-21 22:26:52 -0300507 rtl2830_tuner_i2c, &rtl28xxu_mxl5005s_config);
Antti Palosaari831e0b72011-07-08 23:36:07 -0300508 break;
509 default:
Antti Palosaari9935eea2012-01-21 22:26:52 -0300510 fe = NULL;
Antti Palosaari831e0b72011-07-08 23:36:07 -0300511 err("unknown tuner=%d", priv->tuner);
512 }
513
514 if (fe == NULL) {
515 ret = -ENODEV;
516 goto err;
517 }
518
519 return 0;
520err:
521 deb_info("%s: failed=%d\n", __func__, ret);
522 return ret;
523}
524
Antti Palosaarib5cbaa42011-08-04 13:26:10 -0300525static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap)
526{
527 int ret;
528 struct rtl28xxu_priv *priv = adap->dev->priv;
Antti Palosaari9935eea2012-01-21 22:26:52 -0300529 struct dvb_frontend *fe;
Antti Palosaarib5cbaa42011-08-04 13:26:10 -0300530
531 deb_info("%s:\n", __func__);
532
533 switch (priv->tuner) {
534 case TUNER_RTL2832_FC2580:
535 /* TODO: */
Antti Palosaari9935eea2012-01-21 22:26:52 -0300536 fe = NULL;
Antti Palosaarib5cbaa42011-08-04 13:26:10 -0300537 break;
538 default:
Antti Palosaari9935eea2012-01-21 22:26:52 -0300539 fe = NULL;
Antti Palosaarib5cbaa42011-08-04 13:26:10 -0300540 err("unknown tuner=%d", priv->tuner);
541 }
542
543 if (fe == NULL) {
544 ret = -ENODEV;
545 goto err;
546 }
547
548 return 0;
549err:
550 deb_info("%s: failed=%d\n", __func__, ret);
551 return ret;
552}
553
Antti Palosaari831e0b72011-07-08 23:36:07 -0300554static int rtl28xxu_streaming_ctrl(struct dvb_usb_adapter *adap , int onoff)
555{
556 int ret;
557 u8 buf[2], gpio;
558
559 deb_info("%s: onoff=%d\n", __func__, onoff);
560
561 ret = rtl2831_rd_reg(adap->dev, SYS_GPIO_OUT_VAL, &gpio);
562 if (ret)
563 goto err;
564
565 if (onoff) {
566 buf[0] = 0x00;
567 buf[1] = 0x00;
568 gpio |= 0x04; /* LED on */
569 } else {
570 buf[0] = 0x10; /* stall EPA */
571 buf[1] = 0x02; /* reset EPA */
572 gpio &= (~0x04); /* LED off */
573 }
574
575 ret = rtl2831_wr_reg(adap->dev, SYS_GPIO_OUT_VAL, gpio);
576 if (ret)
577 goto err;
578
579 ret = rtl2831_wr_regs(adap->dev, USB_EPA_CTL, buf, 2);
580 if (ret)
581 goto err;
582
583 return ret;
584err:
585 deb_info("%s: failed=%d\n", __func__, ret);
586 return ret;
587}
588
589static int rtl28xxu_power_ctrl(struct dvb_usb_device *d, int onoff)
590{
591 int ret;
592 u8 gpio, sys0;
593
594 deb_info("%s: onoff=%d\n", __func__, onoff);
595
596 /* demod adc */
597 ret = rtl2831_rd_reg(d, SYS_SYS0, &sys0);
598 if (ret)
599 goto err;
600
601 /* tuner power, read GPIOs */
602 ret = rtl2831_rd_reg(d, SYS_GPIO_OUT_VAL, &gpio);
603 if (ret)
604 goto err;
605
606 deb_info("%s: RD SYS0=%02x GPIO_OUT_VAL=%02x\n", __func__, sys0, gpio);
607
608 if (onoff) {
609 gpio |= 0x01; /* GPIO0 = 1 */
610 gpio &= (~0x10); /* GPIO4 = 0 */
611 sys0 = sys0 & 0x0f;
612 sys0 |= 0xe0;
613 } else {
Antti Palosaari831e0b72011-07-08 23:36:07 -0300614 gpio &= (~0x01); /* GPIO0 = 0 */
615 gpio |= 0x10; /* GPIO4 = 1 */
616 sys0 = sys0 & (~0xc0);
Antti Palosaari831e0b72011-07-08 23:36:07 -0300617 }
618
619 deb_info("%s: WR SYS0=%02x GPIO_OUT_VAL=%02x\n", __func__, sys0, gpio);
620
621 /* demod adc */
622 ret = rtl2831_wr_reg(d, SYS_SYS0, sys0);
623 if (ret)
624 goto err;
625
626 /* tuner power, write GPIOs */
627 ret = rtl2831_wr_reg(d, SYS_GPIO_OUT_VAL, gpio);
628 if (ret)
629 goto err;
630
631 return ret;
632err:
633 deb_info("%s: failed=%d\n", __func__, ret);
634 return ret;
635}
636
Antti Palosaarib5cbaa42011-08-04 13:26:10 -0300637static int rtl2831u_rc_query(struct dvb_usb_device *d)
Antti Palosaari831e0b72011-07-08 23:36:07 -0300638{
Antti Palosaarib5cbaa42011-08-04 13:26:10 -0300639 int ret, i;
640 struct rtl28xxu_priv *priv = d->priv;
Antti Palosaari831e0b72011-07-08 23:36:07 -0300641 u8 buf[5];
642 u32 rc_code;
Antti Palosaarib5cbaa42011-08-04 13:26:10 -0300643 struct rtl28xxu_reg_val rc_nec_tab[] = {
644 { 0x3033, 0x80 },
645 { 0x3020, 0x43 },
646 { 0x3021, 0x16 },
647 { 0x3022, 0x16 },
648 { 0x3023, 0x5a },
649 { 0x3024, 0x2d },
650 { 0x3025, 0x16 },
651 { 0x3026, 0x01 },
652 { 0x3028, 0xb0 },
653 { 0x3029, 0x04 },
654 { 0x302c, 0x88 },
655 { 0x302e, 0x13 },
656 { 0x3030, 0xdf },
657 { 0x3031, 0x05 },
658 };
659
660 /* init remote controller */
661 if (!priv->rc_active) {
662 for (i = 0; i < ARRAY_SIZE(rc_nec_tab); i++) {
663 ret = rtl2831_wr_reg(d, rc_nec_tab[i].reg,
Antti Palosaari9935eea2012-01-21 22:26:52 -0300664 rc_nec_tab[i].val);
Antti Palosaarib5cbaa42011-08-04 13:26:10 -0300665 if (ret)
666 goto err;
667 }
668 priv->rc_active = true;
669 }
Antti Palosaari831e0b72011-07-08 23:36:07 -0300670
671 ret = rtl2831_rd_regs(d, SYS_IRRC_RP, buf, 5);
672 if (ret)
673 goto err;
674
675 if (buf[4] & 0x01) {
676 if (buf[2] == (u8) ~buf[3]) {
677 if (buf[0] == (u8) ~buf[1]) {
678 /* NEC standard (16 bit) */
679 rc_code = buf[0] << 8 | buf[2];
680 } else {
681 /* NEC extended (24 bit) */
682 rc_code = buf[0] << 16 |
Antti Palosaari9935eea2012-01-21 22:26:52 -0300683 buf[1] << 8 | buf[2];
Antti Palosaari831e0b72011-07-08 23:36:07 -0300684 }
685 } else {
686 /* NEC full (32 bit) */
687 rc_code = buf[0] << 24 | buf[1] << 16 |
688 buf[2] << 8 | buf[3];
689 }
690
691 rc_keydown(d->rc_dev, rc_code, 0);
692
693 ret = rtl2831_wr_reg(d, SYS_IRRC_SR, 1);
694 if (ret)
695 goto err;
696
697 /* repeated intentionally to avoid extra keypress */
698 ret = rtl2831_wr_reg(d, SYS_IRRC_SR, 1);
699 if (ret)
700 goto err;
701 }
702
703 return ret;
704err:
705 deb_info("%s: failed=%d\n", __func__, ret);
706 return ret;
707}
708
Antti Palosaarib5cbaa42011-08-04 13:26:10 -0300709static int rtl2832u_rc_query(struct dvb_usb_device *d)
710{
711 int ret, i;
712 struct rtl28xxu_priv *priv = d->priv;
713 u8 buf[128];
714 int len;
715 struct rtl28xxu_reg_val rc_nec_tab[] = {
Antti Palosaari9935eea2012-01-21 22:26:52 -0300716 { IR_RX_CTRL, 0x20 },
717 { IR_RX_BUF_CTRL, 0x80 },
718 { IR_RX_IF, 0xff },
719 { IR_RX_IE, 0xff },
720 { IR_MAX_DURATION0, 0xd0 },
721 { IR_MAX_DURATION1, 0x07 },
722 { IR_IDLE_LEN0, 0xc0 },
723 { IR_IDLE_LEN1, 0x00 },
724 { IR_GLITCH_LEN, 0x03 },
725 { IR_RX_CLK, 0x09 },
726 { IR_RX_CFG, 0x1c },
727 { IR_MAX_H_TOL_LEN, 0x1e },
728 { IR_MAX_L_TOL_LEN, 0x1e },
729 { IR_RX_CTRL, 0x80 },
Antti Palosaarib5cbaa42011-08-04 13:26:10 -0300730 };
731
732 /* init remote controller */
733 if (!priv->rc_active) {
734 for (i = 0; i < ARRAY_SIZE(rc_nec_tab); i++) {
735 ret = rtl2831_wr_reg(d, rc_nec_tab[i].reg,
Antti Palosaari9935eea2012-01-21 22:26:52 -0300736 rc_nec_tab[i].val);
Antti Palosaarib5cbaa42011-08-04 13:26:10 -0300737 if (ret)
738 goto err;
739 }
740 priv->rc_active = true;
741 }
742
743 ret = rtl2831_rd_reg(d, IR_RX_IF, &buf[0]);
744 if (ret)
745 goto err;
746
747 if (buf[0] != 0x83)
748 goto exit;
749
750 ret = rtl2831_rd_reg(d, IR_RX_BC, &buf[0]);
751 if (ret)
752 goto err;
753
754 len = buf[0];
755 ret = rtl2831_rd_regs(d, IR_RX_BUF, buf, len);
756
757 /* TODO: pass raw IR to Kernel IR decoder */
758
759 ret = rtl2831_wr_reg(d, IR_RX_IF, 0x03);
760 ret = rtl2831_wr_reg(d, IR_RX_BUF_CTRL, 0x80);
761 ret = rtl2831_wr_reg(d, IR_RX_CTRL, 0x80);
762
763exit:
764 return ret;
765err:
766 deb_info("%s: failed=%d\n", __func__, ret);
767 return ret;
768}
769
Antti Palosaari9935eea2012-01-21 22:26:52 -0300770enum rtl28xxu_usb_table_entry {
771 RTL2831U_0BDA_2831,
772 RTL2831U_14AA_0160,
Paolo Pantò9d176002012-02-21 12:26:29 -0300773 RTL2831U_14AA_0161,
Antti Palosaari9935eea2012-01-21 22:26:52 -0300774};
Antti Palosaarib5cbaa42011-08-04 13:26:10 -0300775
Antti Palosaari831e0b72011-07-08 23:36:07 -0300776static struct usb_device_id rtl28xxu_table[] = {
Antti Palosaari9935eea2012-01-21 22:26:52 -0300777 /* RTL2831U */
Antti Palosaari831e0b72011-07-08 23:36:07 -0300778 [RTL2831U_0BDA_2831] = {
Antti Palosaari9935eea2012-01-21 22:26:52 -0300779 USB_DEVICE(USB_VID_REALTEK, USB_PID_REALTEK_RTL2831U)},
Antti Palosaari831e0b72011-07-08 23:36:07 -0300780 [RTL2831U_14AA_0160] = {
Antti Palosaari9935eea2012-01-21 22:26:52 -0300781 USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_FREECOM_DVBT)},
Paolo Pantò9d176002012-02-21 12:26:29 -0300782 [RTL2831U_14AA_0161] = {
783 USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_FREECOM_DVBT_2)},
Antti Palosaarib5cbaa42011-08-04 13:26:10 -0300784
Antti Palosaari9935eea2012-01-21 22:26:52 -0300785 /* RTL2832U */
Antti Palosaari831e0b72011-07-08 23:36:07 -0300786 {} /* terminating entry */
787};
788
789MODULE_DEVICE_TABLE(usb, rtl28xxu_table);
790
791static struct dvb_usb_device_properties rtl28xxu_properties[] = {
792 {
793 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
794
795 .usb_ctrl = DEVICE_SPECIFIC,
796 .no_reconnect = 1,
797
798 .size_of_priv = sizeof(struct rtl28xxu_priv),
799
800 .num_adapters = 1,
801 .adapter = {
802 {
Antti Palosaarifba16b12012-01-21 20:28:38 -0300803 .num_frontends = 1,
804 .fe = {
805 {
806 .frontend_attach = rtl2831u_frontend_attach,
807 .tuner_attach = rtl2831u_tuner_attach,
808 .streaming_ctrl = rtl28xxu_streaming_ctrl,
809 .stream = {
810 .type = USB_BULK,
811 .count = 6,
812 .endpoint = 0x81,
813 .u = {
814 .bulk = {
Antti Palosaari9935eea2012-01-21 22:26:52 -0300815 .buffersize = 8*512,
Antti Palosaarifba16b12012-01-21 20:28:38 -0300816 }
817 }
Antti Palosaari831e0b72011-07-08 23:36:07 -0300818 }
819 }
Antti Palosaarifba16b12012-01-21 20:28:38 -0300820 }
Antti Palosaari831e0b72011-07-08 23:36:07 -0300821 }
822 },
823
824 .power_ctrl = rtl28xxu_power_ctrl,
825
826 .rc.core = {
827 .protocol = RC_TYPE_NEC,
828 .module_name = "rtl28xxu",
Antti Palosaarib5cbaa42011-08-04 13:26:10 -0300829 .rc_query = rtl2831u_rc_query,
Antti Palosaari831e0b72011-07-08 23:36:07 -0300830 .rc_interval = 400,
831 .allowed_protos = RC_TYPE_NEC,
832 .rc_codes = RC_MAP_EMPTY,
833 },
834
835 .i2c_algo = &rtl28xxu_i2c_algo,
836
837 .num_device_descs = 2,
838 .devices = {
839 {
840 .name = "Realtek RTL2831U reference design",
Antti Palosaari831e0b72011-07-08 23:36:07 -0300841 .warm_ids = {
Antti Palosaari9935eea2012-01-21 22:26:52 -0300842 &rtl28xxu_table[RTL2831U_0BDA_2831],
843 },
Antti Palosaari831e0b72011-07-08 23:36:07 -0300844 },
845 {
846 .name = "Freecom USB2.0 DVB-T",
Antti Palosaari831e0b72011-07-08 23:36:07 -0300847 .warm_ids = {
Antti Palosaari9935eea2012-01-21 22:26:52 -0300848 &rtl28xxu_table[RTL2831U_14AA_0160],
Paolo Pantò9d176002012-02-21 12:26:29 -0300849 &rtl28xxu_table[RTL2831U_14AA_0161],
Antti Palosaari9935eea2012-01-21 22:26:52 -0300850 },
Antti Palosaari831e0b72011-07-08 23:36:07 -0300851 },
852 }
853 },
Antti Palosaarib5cbaa42011-08-04 13:26:10 -0300854 {
855 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
856
857 .usb_ctrl = DEVICE_SPECIFIC,
858 .no_reconnect = 1,
859
860 .size_of_priv = sizeof(struct rtl28xxu_priv),
861
862 .num_adapters = 1,
863 .adapter = {
864 {
Antti Palosaarifba16b12012-01-21 20:28:38 -0300865 .num_frontends = 1,
866 .fe = {
867 {
868 .frontend_attach = rtl2832u_frontend_attach,
869 .tuner_attach = rtl2832u_tuner_attach,
870 .streaming_ctrl = rtl28xxu_streaming_ctrl,
871 .stream = {
872 .type = USB_BULK,
873 .count = 6,
874 .endpoint = 0x81,
875 .u = {
876 .bulk = {
Antti Palosaari9935eea2012-01-21 22:26:52 -0300877 .buffersize = 8*512,
Antti Palosaarifba16b12012-01-21 20:28:38 -0300878 }
879 }
Antti Palosaarib5cbaa42011-08-04 13:26:10 -0300880 }
881 }
Antti Palosaarifba16b12012-01-21 20:28:38 -0300882 }
Antti Palosaarib5cbaa42011-08-04 13:26:10 -0300883 }
884 },
885
886 .power_ctrl = rtl28xxu_power_ctrl,
887
888 .rc.core = {
889 .protocol = RC_TYPE_NEC,
890 .module_name = "rtl28xxu",
891 .rc_query = rtl2832u_rc_query,
892 .rc_interval = 400,
893 .allowed_protos = RC_TYPE_NEC,
894 .rc_codes = RC_MAP_EMPTY,
895 },
896
897 .i2c_algo = &rtl28xxu_i2c_algo,
898
Antti Palosaari9935eea2012-01-21 22:26:52 -0300899 .num_device_descs = 0, /* disabled as no support for RTL2832 */
Antti Palosaarib5cbaa42011-08-04 13:26:10 -0300900 .devices = {
901 {
902 .name = "Realtek RTL2832U reference design",
Antti Palosaarib5cbaa42011-08-04 13:26:10 -0300903 },
904 }
905 },
906
Antti Palosaari831e0b72011-07-08 23:36:07 -0300907};
908
909static int rtl28xxu_probe(struct usb_interface *intf,
Antti Palosaari9935eea2012-01-21 22:26:52 -0300910 const struct usb_device_id *id)
Antti Palosaari831e0b72011-07-08 23:36:07 -0300911{
912 int ret, i;
913 int properties_count = ARRAY_SIZE(rtl28xxu_properties);
Antti Palosaari9935eea2012-01-21 22:26:52 -0300914 struct dvb_usb_device *d;
Antti Palosaari943a9032012-03-19 16:27:47 -0300915 struct usb_device *udev;
916 bool found;
Antti Palosaari831e0b72011-07-08 23:36:07 -0300917
918 deb_info("%s: interface=%d\n", __func__,
919 intf->cur_altsetting->desc.bInterfaceNumber);
920
921 if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
922 return 0;
923
Antti Palosaari943a9032012-03-19 16:27:47 -0300924 /* Dynamic USB ID support. Replaces first device ID with current one .*/
925 udev = interface_to_usbdev(intf);
926
927 for (i = 0, found = false; i < ARRAY_SIZE(rtl28xxu_table) - 1; i++) {
928 if (rtl28xxu_table[i].idVendor ==
929 le16_to_cpu(udev->descriptor.idVendor) &&
930 rtl28xxu_table[i].idProduct ==
931 le16_to_cpu(udev->descriptor.idProduct)) {
932 found = true;
933 break;
934 }
935 }
936
937 if (!found) {
938 deb_info("%s: using dynamic ID %04x:%04x\n", __func__,
939 le16_to_cpu(udev->descriptor.idVendor),
940 le16_to_cpu(udev->descriptor.idProduct));
941 rtl28xxu_properties[0].devices[0].warm_ids[0]->idVendor =
942 le16_to_cpu(udev->descriptor.idVendor);
943 rtl28xxu_properties[0].devices[0].warm_ids[0]->idProduct =
944 le16_to_cpu(udev->descriptor.idProduct);
945 }
946
Antti Palosaari831e0b72011-07-08 23:36:07 -0300947 for (i = 0; i < properties_count; i++) {
948 ret = dvb_usb_device_init(intf, &rtl28xxu_properties[i],
Antti Palosaari9935eea2012-01-21 22:26:52 -0300949 THIS_MODULE, &d, adapter_nr);
Antti Palosaari831e0b72011-07-08 23:36:07 -0300950 if (ret == 0 || ret != -ENODEV)
951 break;
952 }
953
954 if (ret)
955 goto err;
956
957 /* init USB endpoints */
958 ret = rtl2831_wr_reg(d, USB_SYSCTL_0, 0x09);
959 if (ret)
960 goto err;
961
962 ret = rtl2831_wr_regs(d, USB_EPA_MAXPKT, "\x00\x02\x00\x00", 4);
963 if (ret)
964 goto err;
965
966 ret = rtl2831_wr_regs(d, USB_EPA_FIFO_CFG, "\x14\x00\x00\x00", 4);
967 if (ret)
968 goto err;
969
Antti Palosaari831e0b72011-07-08 23:36:07 -0300970 return ret;
971err:
972 deb_info("%s: failed=%d\n", __func__, ret);
973 return ret;
974}
975
976static struct usb_driver rtl28xxu_driver = {
977 .name = "dvb_usb_rtl28xxu",
978 .probe = rtl28xxu_probe,
979 .disconnect = dvb_usb_device_exit,
980 .id_table = rtl28xxu_table,
981};
982
983/* module stuff */
984static int __init rtl28xxu_module_init(void)
985{
986 int ret;
Antti Palosaari9935eea2012-01-21 22:26:52 -0300987
Antti Palosaari831e0b72011-07-08 23:36:07 -0300988 deb_info("%s:\n", __func__);
Antti Palosaari9935eea2012-01-21 22:26:52 -0300989
Antti Palosaari831e0b72011-07-08 23:36:07 -0300990 ret = usb_register(&rtl28xxu_driver);
991 if (ret)
992 err("usb_register failed=%d", ret);
993
994 return ret;
995}
996
997static void __exit rtl28xxu_module_exit(void)
998{
999 deb_info("%s:\n", __func__);
Antti Palosaari9935eea2012-01-21 22:26:52 -03001000
Antti Palosaari831e0b72011-07-08 23:36:07 -03001001 /* deregister this driver from the USB subsystem */
1002 usb_deregister(&rtl28xxu_driver);
1003}
1004
1005module_init(rtl28xxu_module_init);
1006module_exit(rtl28xxu_module_exit);
1007
1008MODULE_DESCRIPTION("Realtek RTL28xxU DVB USB driver");
1009MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
1010MODULE_LICENSE("GPL");