blob: fa5acd040e93937a1d123f3c3367ff5e8263a17b [file] [log] [blame]
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001/*
2 * DVB USB Linux driver for Anysee E30 DVB-C & DVB-T USB2.0 receiver
3 *
4 * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
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
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * TODO:
21 * - add smart card reader support for Conditional Access (CA)
22 *
23 * Card reader in Anysee is nothing more than ISO 7816 card reader.
24 * There is no hardware CAM in any Anysee device sold.
25 * In my understanding it should be implemented by making own module
Antti Palosaari9fdd9ca2008-06-11 11:43:19 -030026 * for ISO 7816 card reader, like dvb_ca_en50221 is implemented. This
27 * module registers serial interface that can be used to communicate
Antti Palosaaria51e34d2008-05-17 23:05:48 -030028 * with any ISO 7816 smart card.
29 *
30 * Any help according to implement serial smart card reader support
31 * is highly welcome!
32 */
33
34#include "anysee.h"
35#include "tda1002x.h"
36#include "mt352.h"
37#include "mt352_priv.h"
38#include "zl10353.h"
Antti Palosaari72ffd2b2011-04-10 20:14:50 -030039#include "tda18212.h"
Antti Palosaaria51e34d2008-05-17 23:05:48 -030040
41/* debug */
42static int dvb_usb_anysee_debug;
43module_param_named(debug, dvb_usb_anysee_debug, int, 0644);
44MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
Mauro Carvalho Chehabffbc5f82009-01-05 01:34:20 -030045static int dvb_usb_anysee_delsys;
Antti Palosaari0f77c3a2008-08-11 10:54:16 -030046module_param_named(delsys, dvb_usb_anysee_delsys, int, 0644);
47MODULE_PARM_DESC(delsys, "select delivery mode (0=DVB-C, 1=DVB-T)");
Antti Palosaaria51e34d2008-05-17 23:05:48 -030048DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
49
Akinobu Mitadec0c462008-10-29 21:16:04 -030050static DEFINE_MUTEX(anysee_usb_mutex);
Antti Palosaaria51e34d2008-05-17 23:05:48 -030051
52static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen,
53 u8 *rbuf, u8 rlen)
54{
55 struct anysee_state *state = d->priv;
56 int act_len, ret;
57 u8 buf[64];
58
59 if (slen > sizeof(buf))
60 slen = sizeof(buf);
61 memcpy(&buf[0], sbuf, slen);
62 buf[60] = state->seq++;
63
64 if (mutex_lock_interruptible(&anysee_usb_mutex) < 0)
65 return -EAGAIN;
66
67 /* We need receive one message more after dvb_usb_generic_rw due
68 to weird transaction flow, which is 1 x send + 2 x receive. */
69 ret = dvb_usb_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf), 0);
70
71 if (!ret) {
72 /* receive 2nd answer */
73 ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev,
74 d->props.generic_bulk_ctrl_endpoint), buf, sizeof(buf),
75 &act_len, 2000);
76 if (ret)
77 err("%s: recv bulk message failed: %d", __func__, ret);
78 else {
79 deb_xfer("<<< ");
80 debug_dump(buf, act_len, deb_xfer);
81 }
82 }
83
84 /* read request, copy returned data to return buf */
85 if (!ret && rbuf && rlen)
86 memcpy(rbuf, buf, rlen);
87
88 mutex_unlock(&anysee_usb_mutex);
89
90 return ret;
91}
92
93static int anysee_read_reg(struct dvb_usb_device *d, u16 reg, u8 *val)
94{
95 u8 buf[] = {CMD_REG_READ, reg >> 8, reg & 0xff, 0x01};
96 int ret;
97 ret = anysee_ctrl_msg(d, buf, sizeof(buf), val, 1);
98 deb_info("%s: reg:%04x val:%02x\n", __func__, reg, *val);
99 return ret;
100}
101
102static int anysee_write_reg(struct dvb_usb_device *d, u16 reg, u8 val)
103{
104 u8 buf[] = {CMD_REG_WRITE, reg >> 8, reg & 0xff, 0x01, val};
105 deb_info("%s: reg:%04x val:%02x\n", __func__, reg, val);
106 return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
107}
108
Antti Palosaari41f81f62011-04-10 17:53:52 -0300109/* write single register with mask */
110static int anysee_wr_reg_mask(struct dvb_usb_device *d, u16 reg, u8 val,
111 u8 mask)
112{
113 int ret;
114 u8 tmp;
115
116 /* no need for read if whole reg is written */
117 if (mask != 0xff) {
118 ret = anysee_read_reg(d, reg, &tmp);
119 if (ret)
120 return ret;
121
122 val &= mask;
123 tmp &= ~mask;
124 val |= tmp;
125 }
126
127 return anysee_write_reg(d, reg, val);
128}
129
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300130static int anysee_get_hw_info(struct dvb_usb_device *d, u8 *id)
131{
132 u8 buf[] = {CMD_GET_HW_INFO};
133 return anysee_ctrl_msg(d, buf, sizeof(buf), id, 3);
134}
135
136static int anysee_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
137{
138 u8 buf[] = {CMD_STREAMING_CTRL, (u8)onoff, 0x00};
139 deb_info("%s: onoff:%02x\n", __func__, onoff);
140 return anysee_ctrl_msg(adap->dev, buf, sizeof(buf), NULL, 0);
141}
142
143static int anysee_led_ctrl(struct dvb_usb_device *d, u8 mode, u8 interval)
144{
145 u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x01, mode, interval};
146 deb_info("%s: state:%02x interval:%02x\n", __func__, mode, interval);
147 return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
148}
149
150static int anysee_ir_ctrl(struct dvb_usb_device *d, u8 onoff)
151{
152 u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x02, onoff};
153 deb_info("%s: onoff:%02x\n", __func__, onoff);
154 return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
155}
156
157static int anysee_init(struct dvb_usb_device *d)
158{
159 int ret;
160 /* LED light */
161 ret = anysee_led_ctrl(d, 0x01, 0x03);
162 if (ret)
163 return ret;
164
165 /* enable IR */
166 ret = anysee_ir_ctrl(d, 1);
167 if (ret)
168 return ret;
169
170 return 0;
171}
172
173/* I2C */
174static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
175 int num)
176{
177 struct dvb_usb_device *d = i2c_get_adapdata(adap);
Mauro Carvalho Chehab902571a2008-12-29 19:02:24 -0300178 int ret = 0, inc, i = 0;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300179
180 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
181 return -EAGAIN;
182
183 while (i < num) {
184 if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
185 u8 buf[6];
186 buf[0] = CMD_I2C_READ;
Antti Palosaari7ea03d22011-04-09 20:50:07 -0300187 buf[1] = (msg[i].addr << 1) | 0x01;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300188 buf[2] = msg[i].buf[0];
189 buf[3] = 0x00;
190 buf[4] = 0x00;
Antti Palosaarib3e6a5a2011-04-09 21:00:51 -0300191 buf[5] = msg[i+1].len;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300192 ret = anysee_ctrl_msg(d, buf, sizeof(buf), msg[i+1].buf,
193 msg[i+1].len);
194 inc = 2;
195 } else {
196 u8 buf[4+msg[i].len];
197 buf[0] = CMD_I2C_WRITE;
Antti Palosaari7ea03d22011-04-09 20:50:07 -0300198 buf[1] = (msg[i].addr << 1);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300199 buf[2] = msg[i].len;
200 buf[3] = 0x01;
201 memcpy(&buf[4], msg[i].buf, msg[i].len);
202 ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
203 inc = 1;
204 }
205 if (ret)
Antti Palosaarie613f8f2008-08-11 10:36:43 -0300206 break;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300207
208 i += inc;
209 }
210
211 mutex_unlock(&d->i2c_mutex);
212
Antti Palosaarie613f8f2008-08-11 10:36:43 -0300213 return ret ? ret : i;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300214}
215
216static u32 anysee_i2c_func(struct i2c_adapter *adapter)
217{
218 return I2C_FUNC_I2C;
219}
220
221static struct i2c_algorithm anysee_i2c_algo = {
222 .master_xfer = anysee_master_xfer,
223 .functionality = anysee_i2c_func,
224};
225
226static int anysee_mt352_demod_init(struct dvb_frontend *fe)
227{
Antti Palosaariae3745f2009-09-16 19:50:25 -0300228 static u8 clock_config[] = { CLOCK_CTL, 0x38, 0x28 };
229 static u8 reset[] = { RESET, 0x80 };
230 static u8 adc_ctl_1_cfg[] = { ADC_CTL_1, 0x40 };
231 static u8 agc_cfg[] = { AGC_TARGET, 0x28, 0x20 };
232 static u8 gpp_ctl_cfg[] = { GPP_CTL, 0x33 };
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300233 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
234
235 mt352_write(fe, clock_config, sizeof(clock_config));
236 udelay(200);
237 mt352_write(fe, reset, sizeof(reset));
238 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
239
240 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
241 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
242 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
243
244 return 0;
245}
246
247/* Callbacks for DVB USB */
248static struct tda10023_config anysee_tda10023_config = {
Antti Palosaari7ea03d22011-04-09 20:50:07 -0300249 .demod_address = (0x1a >> 1),
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300250 .invert = 0,
251 .xtal = 16000000,
252 .pll_m = 11,
253 .pll_p = 3,
254 .pll_n = 1,
Antti Palosaari5ae2fca2008-06-09 22:58:22 -0300255 .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_C,
256 .deltaf = 0xfeeb,
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300257};
258
259static struct mt352_config anysee_mt352_config = {
Antti Palosaari7ea03d22011-04-09 20:50:07 -0300260 .demod_address = (0x1e >> 1),
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300261 .demod_init = anysee_mt352_demod_init,
262};
263
264static struct zl10353_config anysee_zl10353_config = {
Antti Palosaari7ea03d22011-04-09 20:50:07 -0300265 .demod_address = (0x1e >> 1),
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300266 .parallel_ts = 1,
267};
268
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300269static struct zl10353_config anysee_zl10353_tda18212_config = {
270 .demod_address = (0x18 >> 1),
271 .parallel_ts = 1,
272 .disable_i2c_gate_ctrl = 1,
273 .no_tuner = 1,
274 .if2 = 41500,
275};
276
277static struct tda10023_config anysee_tda10023_tda18212_config = {
278 .demod_address = (0x1a >> 1),
279 .xtal = 16000000,
280 .pll_m = 12,
281 .pll_p = 3,
282 .pll_n = 1,
283 .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_C,
284 .deltaf = 0xba02,
285};
286
287static struct tda18212_config anysee_tda18212_config = {
288 .i2c_address = (0xc0 >> 1),
289 .if_dvbt_6 = 4150,
290 .if_dvbt_7 = 4150,
291 .if_dvbt_8 = 4150,
292 .if_dvbc = 5000,
293};
294
Antti Palosaari41f81f62011-04-10 17:53:52 -0300295/*
296 * New USB device strings: Mfr=1, Product=2, SerialNumber=0
297 * Manufacturer: AMT.CO.KR
298 *
299 * E30 VID=04b4 PID=861f HW=2 FW=2.1 Product=????????
300 * PCB: ?
301 * parts: MT352, DTT7579(?), DNOS404ZH102A NIM
302 *
303 * E30 VID=04b4 PID=861f HW=2 FW=2.1 Product=????????
304 * PCB: ?
305 * parts: ZL10353, DTT7579(?), DNOS404ZH103A NIM
306 *
307 * E30 Plus VID=04b4 PID=861f HW=6 FW=1.0 "anysee"
308 * PCB: 507CD (rev1.1)
309 * parts: ZL10353, DTT7579(?), CST56I01, DNOS404ZH103A NIM
310 * OEA=80 OEB=00 OEC=00 OED=ff OEF=fe
311 * IOD[0] ZL10353 1=enabled
312 * IOA[7] TS 0=enabled
313 * tuner is not behind ZL10353 I2C-gate (no care if gate disabled or not)
314 *
315 * E30 C Plus VID=04b4 PID=861f HW=10 FW=1.0 "anysee-DC(LP)"
316 * PCB: 507DC (rev0.2)
317 * parts: TDA10023, CST56I01, DTOS403IH102B TM
318 * OEA=80 OEB=00 OEC=00 OED=ff OEF=fe
319 * IOD[0] TDA10023 1=enabled
320 *
321 * E30 C Plus VID=1c73 PID=861f HW=15 FW=1.2 "anysee-FA(LP)"
322 * PCB: 507FA (rev0.4)
323 * parts: TDA10023, TDA8024, DTOS403IH102B TM
324 * OEA=80 OEB=00 OEC=ff OED=ff OEF=ff
325 * IOD[5] TDA10023 1=enabled
326 * IOE[0] tuner 1=enabled
327 *
328 * E30 Combo Plus VID=1c73 PID=861f HW=15 FW=1.2 "anysee-FA(LP)"
329 * PCB: 507FA (rev1.1)
330 * parts: ZL10353, TDA10023, TDA8024, DTOS403IH102B TM
331 * OEA=80 OEB=00 OEC=ff OED=ff OEF=ff
332 * DVB-C:
333 * IOD[5] TDA10023 1=enabled
334 * IOE[0] tuner 1=enabled
335 * DVB-T:
336 * IOD[0] ZL10353 1=enabled
337 * IOE[0] tuner 0=enabled
338 * tuner is behind ZL10353 I2C-gate
339 */
340
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300341static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
342{
343 int ret;
344 struct anysee_state *state = adap->dev->priv;
345 u8 hw_info[3];
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300346 u8 tmp;
347 struct i2c_msg msg[2] = {
348 {
349 .addr = anysee_tda18212_config.i2c_address,
350 .flags = 0,
351 .len = 1,
352 .buf = "\x00",
353 }, {
354 .addr = anysee_tda18212_config.i2c_address,
355 .flags = I2C_M_RD,
356 .len = 1,
357 .buf = &tmp,
358 }
359 };
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300360
Antti Palosaari41f81f62011-04-10 17:53:52 -0300361 /* Check which hardware we have.
362 * We must do this call two times to get reliable values (hw bug).
363 */
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300364 ret = anysee_get_hw_info(adap->dev, hw_info);
365 if (ret)
Antti Palosaari41f81f62011-04-10 17:53:52 -0300366 goto error;
367
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300368 ret = anysee_get_hw_info(adap->dev, hw_info);
369 if (ret)
Antti Palosaari41f81f62011-04-10 17:53:52 -0300370 goto error;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300371
372 /* Meaning of these info bytes are guessed. */
Antti Palosaari592d9e22011-04-09 21:13:33 -0300373 info("firmware version:%d.%d hardware id:%d",
374 hw_info[1], hw_info[2], hw_info[0]);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300375
Antti Palosaari41f81f62011-04-10 17:53:52 -0300376 state->hw = hw_info[0];
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300377
Antti Palosaari41f81f62011-04-10 17:53:52 -0300378 switch (state->hw) {
379 case ANYSEE_HW_02: /* 2 */
380 /* E30 */
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300381
Antti Palosaari41f81f62011-04-10 17:53:52 -0300382 /* attach demod */
383 adap->fe = dvb_attach(mt352_attach, &anysee_mt352_config,
384 &adap->dev->i2c_adap);
385 if (adap->fe)
386 break;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300387
Antti Palosaari41f81f62011-04-10 17:53:52 -0300388 /* attach demod */
Antti Palosaari0f77c3a2008-08-11 10:54:16 -0300389 adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config,
Antti Palosaari41f81f62011-04-10 17:53:52 -0300390 &adap->dev->i2c_adap);
391 if (adap->fe)
392 break;
393
394 break;
395 case ANYSEE_HW_507CD: /* 6 */
396 /* E30 Plus */
397
398 /* enable DVB-T demod on IOD[0] */
399 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01);
400 if (ret)
401 goto error;
402
403 /* enable transport stream on IOA[7] */
404 ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (0 << 7), 0x80);
405 if (ret)
406 goto error;
407
408 /* attach demod */
409 adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config,
410 &adap->dev->i2c_adap);
411 if (adap->fe)
412 break;
413
414 break;
415 case ANYSEE_HW_507DC: /* 10 */
416 /* E30 C Plus */
417
418 /* enable DVB-C demod on IOD[0] */
419 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01);
420 if (ret)
421 goto error;
422
423 /* attach demod */
424 adap->fe = dvb_attach(tda10023_attach, &anysee_tda10023_config,
425 &adap->dev->i2c_adap, 0x48);
426 if (adap->fe)
427 break;
428
429 break;
430 case ANYSEE_HW_507FA: /* 15 */
431 /* E30 Combo Plus */
432 /* E30 C Plus */
433
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300434 /* enable tuner on IOE[4] */
435 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10);
436 if (ret)
437 goto error;
438
439 /* probe TDA18212 */
440 tmp = 0;
441 ret = i2c_transfer(&adap->dev->i2c_adap, msg, 2);
442 if (ret == 2 && tmp == 0xc7)
443 deb_info("%s: TDA18212 found\n", __func__);
444 else
445 tmp = 0;
446
447 /* disable tuner on IOE[4] */
448 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 4), 0x10);
449 if (ret)
450 goto error;
451
Antti Palosaari41f81f62011-04-10 17:53:52 -0300452 if (dvb_usb_anysee_delsys) {
453 /* disable DVB-C demod on IOD[5] */
454 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5),
455 0x20);
456 if (ret)
457 goto error;
458
459 /* enable DVB-T demod on IOD[0] */
460 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0),
461 0x01);
462 if (ret)
463 goto error;
464
465 /* attach demod */
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300466 if (tmp == 0xc7) {
467 /* TDA18212 config */
468 adap->fe = dvb_attach(zl10353_attach,
469 &anysee_zl10353_tda18212_config,
470 &adap->dev->i2c_adap);
471 } else {
472 /* PLL config */
473 adap->fe = dvb_attach(zl10353_attach,
474 &anysee_zl10353_config,
475 &adap->dev->i2c_adap);
476 }
Antti Palosaari41f81f62011-04-10 17:53:52 -0300477 if (adap->fe)
478 break;
479 } else {
480 /* disable DVB-T demod on IOD[0] */
481 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 0),
482 0x01);
483 if (ret)
484 goto error;
485
486 /* enable DVB-C demod on IOD[5] */
487 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5),
488 0x20);
489 if (ret)
490 goto error;
491
492 /* attach demod */
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300493 if (tmp == 0xc7) {
494 /* TDA18212 config */
495 adap->fe = dvb_attach(tda10023_attach,
496 &anysee_tda10023_tda18212_config,
497 &adap->dev->i2c_adap, 0x48);
498 } else {
499 /* PLL config */
500 adap->fe = dvb_attach(tda10023_attach,
501 &anysee_tda10023_config,
502 &adap->dev->i2c_adap, 0x48);
503 }
Antti Palosaari41f81f62011-04-10 17:53:52 -0300504 if (adap->fe)
505 break;
Antti Palosaari0f77c3a2008-08-11 10:54:16 -0300506 }
Antti Palosaari41f81f62011-04-10 17:53:52 -0300507 break;
Antti Palosaaria43be982011-04-10 20:23:02 -0300508 case ANYSEE_HW_508TC: /* 18 */
509 /* E7 TC */
510
511 /* enable transport stream on IOA[7] */
512 ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (1 << 7), 0x80);
513 if (ret)
514 goto error;
515
516 if (dvb_usb_anysee_delsys) {
517 /* disable DVB-C demod on IOD[5] */
518 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5),
519 0x20);
520 if (ret)
521 goto error;
522
523 /* enable DVB-T demod on IOD[6] */
524 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 6),
525 0x40);
526 if (ret)
527 goto error;
528
529 /* enable IF route on IOE[0] */
530 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 0),
531 0x01);
532 if (ret)
533 goto error;
534
535 /* attach demod */
536 adap->fe = dvb_attach(zl10353_attach,
537 &anysee_zl10353_tda18212_config,
538 &adap->dev->i2c_adap);
539 if (adap->fe)
540 break;
541 } else {
542 /* disable DVB-T demod on IOD[6] */
543 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 6),
544 0x40);
545 if (ret)
546 goto error;
547
548 /* enable DVB-C demod on IOD[5] */
549 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5),
550 0x20);
551 if (ret)
552 goto error;
553
554 /* enable IF route on IOE[0] */
555 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 0),
556 0x01);
557 if (ret)
558 goto error;
559
560 /* attach demod */
561 adap->fe = dvb_attach(tda10023_attach,
562 &anysee_tda10023_tda18212_config,
563 &adap->dev->i2c_adap, 0x48);
564 if (adap->fe)
565 break;
566 }
567 break;
Antti Palosaari0f77c3a2008-08-11 10:54:16 -0300568 }
569
Antti Palosaari41f81f62011-04-10 17:53:52 -0300570 if (!adap->fe) {
571 /* we have no frontend :-( */
572 ret = -ENODEV;
573 err("Unknown Anysee version: %02x %02x %02x. " \
574 "Please report the <linux-media@vger.kernel.org>.",
575 hw_info[0], hw_info[1], hw_info[2]);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300576 }
Antti Palosaari41f81f62011-04-10 17:53:52 -0300577error:
578 return ret;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300579}
580
581static int anysee_tuner_attach(struct dvb_usb_adapter *adap)
582{
583 struct anysee_state *state = adap->dev->priv;
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300584 struct dvb_frontend *fe;
Antti Palosaari41f81f62011-04-10 17:53:52 -0300585 int ret = 0;
Antti Palosaaria8494682010-10-17 18:25:10 -0300586 deb_info("%s:\n", __func__);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300587
Antti Palosaari41f81f62011-04-10 17:53:52 -0300588 switch (state->hw) {
589 case ANYSEE_HW_02: /* 2 */
590 /* E30 */
591
592 /* attach tuner */
Antti Palosaari7ea03d22011-04-09 20:50:07 -0300593 dvb_attach(dvb_pll_attach, adap->fe, (0xc2 >> 1),
594 NULL, DVB_PLL_THOMSON_DTT7579);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300595 break;
Antti Palosaari41f81f62011-04-10 17:53:52 -0300596 case ANYSEE_HW_507CD: /* 6 */
597 /* E30 Plus */
598
599 /* attach tuner */
600 dvb_attach(dvb_pll_attach, adap->fe, (0xc2 >> 1),
601 &adap->dev->i2c_adap, DVB_PLL_THOMSON_DTT7579);
602
603 break;
604 case ANYSEE_HW_507DC: /* 10 */
605 /* E30 C Plus */
606
607 /* attach tuner */
Antti Palosaari7ea03d22011-04-09 20:50:07 -0300608 dvb_attach(dvb_pll_attach, adap->fe, (0xc0 >> 1),
609 &adap->dev->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300610 break;
Antti Palosaari41f81f62011-04-10 17:53:52 -0300611 case ANYSEE_HW_507FA: /* 15 */
612 /* E30 Combo Plus */
613 /* E30 C Plus */
614
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300615 /* Try first attach TDA18212 silicon tuner on IOE[4], if that
616 * fails attach old simple PLL. */
617
618 /* enable tuner on IOE[4] */
619 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10);
620 if (ret)
621 goto error;
622
623 /* attach tuner */
624 fe = dvb_attach(tda18212_attach, adap->fe, &adap->dev->i2c_adap,
625 &anysee_tda18212_config);
626 if (fe)
627 break;
628
629 /* disable tuner on IOE[4] */
630 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 4), 0x10);
631 if (ret)
632 goto error;
633
Antti Palosaari41f81f62011-04-10 17:53:52 -0300634 if (dvb_usb_anysee_delsys) {
635 /* enable DVB-T tuner on IOE[0] */
636 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 0),
637 0x01);
638 if (ret)
639 goto error;
640 } else {
641 /* enable DVB-C tuner on IOE[0] */
642 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 0),
643 0x01);
644 if (ret)
645 goto error;
646 }
647
648 /* attach tuner */
649 dvb_attach(dvb_pll_attach, adap->fe, (0xc0 >> 1),
650 &adap->dev->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A);
651
652 break;
Antti Palosaaria43be982011-04-10 20:23:02 -0300653 case ANYSEE_HW_508TC: /* 18 */
654 /* E7 TC */
655
656 /* enable tuner on IOE[4] */
657 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10);
658 if (ret)
659 goto error;
660
661 /* attach tuner */
662 fe = dvb_attach(tda18212_attach, adap->fe, &adap->dev->i2c_adap,
663 &anysee_tda18212_config);
664 if (!fe)
665 ret = -ENODEV;
666
667 break;
668
Antti Palosaari41f81f62011-04-10 17:53:52 -0300669 default:
670 ret = -ENODEV;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300671 }
672
Antti Palosaari41f81f62011-04-10 17:53:52 -0300673error:
674 return ret;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300675}
676
Antti Palosaaria8494682010-10-17 18:25:10 -0300677static int anysee_rc_query(struct dvb_usb_device *d)
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300678{
679 u8 buf[] = {CMD_GET_IR_CODE};
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300680 u8 ircode[2];
Antti Palosaaria8494682010-10-17 18:25:10 -0300681 int ret;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300682
Antti Palosaaria8494682010-10-17 18:25:10 -0300683 /* Remote controller is basic NEC using address byte 0x08.
684 Anysee device RC query returns only two bytes, status and code,
685 address byte is dropped. Also it does not return any value for
686 NEC RCs having address byte other than 0x08. Due to that, we
687 cannot use that device as standard NEC receiver.
688 It could be possible make hack which reads whole code directly
689 from device memory... */
690
691 ret = anysee_ctrl_msg(d, buf, sizeof(buf), ircode, sizeof(ircode));
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300692 if (ret)
693 return ret;
694
Antti Palosaaria8494682010-10-17 18:25:10 -0300695 if (ircode[0]) {
696 deb_rc("%s: key pressed %02x\n", __func__, ircode[1]);
Mauro Carvalho Chehabca866742010-11-17 13:53:11 -0300697 rc_keydown(d->rc_dev, 0x08 << 8 | ircode[1], 0);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300698 }
Antti Palosaaria8494682010-10-17 18:25:10 -0300699
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300700 return 0;
701}
702
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300703/* DVB USB Driver stuff */
704static struct dvb_usb_device_properties anysee_properties;
705
706static int anysee_probe(struct usb_interface *intf,
707 const struct usb_device_id *id)
708{
709 struct dvb_usb_device *d;
710 struct usb_host_interface *alt;
711 int ret;
712
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300713 /* There is one interface with two alternate settings.
714 Alternate setting 0 is for bulk transfer.
715 Alternate setting 1 is for isochronous transfer.
716 We use bulk transfer (alternate setting 0). */
717 if (intf->num_altsetting < 1)
718 return -ENODEV;
719
Dan Carpenter8b0d7042010-05-31 16:27:39 -0300720 /*
721 * Anysee is always warm (its USB-bridge, Cypress FX2, uploads
722 * firmware from eeprom). If dvb_usb_device_init() succeeds that
723 * means d is a valid pointer.
724 */
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300725 ret = dvb_usb_device_init(intf, &anysee_properties, THIS_MODULE, &d,
726 adapter_nr);
727 if (ret)
728 return ret;
729
730 alt = usb_altnum_to_altsetting(intf, 0);
731 if (alt == NULL) {
732 deb_info("%s: no alt found!\n", __func__);
733 return -ENODEV;
734 }
735
736 ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber,
737 alt->desc.bAlternateSetting);
738 if (ret)
739 return ret;
740
Dan Carpenter8b0d7042010-05-31 16:27:39 -0300741 return anysee_init(d);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300742}
743
Antti Palosaariae3745f2009-09-16 19:50:25 -0300744static struct usb_device_id anysee_table[] = {
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300745 { USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE) },
746 { USB_DEVICE(USB_VID_AMT, USB_PID_ANYSEE) },
747 { } /* Terminating entry */
748};
749MODULE_DEVICE_TABLE(usb, anysee_table);
750
751static struct dvb_usb_device_properties anysee_properties = {
752 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
753
754 .usb_ctrl = DEVICE_SPECIFIC,
755
756 .size_of_priv = sizeof(struct anysee_state),
757
758 .num_adapters = 1,
759 .adapter = {
760 {
761 .streaming_ctrl = anysee_streaming_ctrl,
762 .frontend_attach = anysee_frontend_attach,
763 .tuner_attach = anysee_tuner_attach,
764 .stream = {
765 .type = USB_BULK,
766 .count = 8,
767 .endpoint = 0x82,
768 .u = {
769 .bulk = {
Antti Palosaariab693332009-09-16 19:47:01 -0300770 .buffersize = (16*512),
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300771 }
772 }
773 },
774 }
775 },
776
Antti Palosaaria8494682010-10-17 18:25:10 -0300777 .rc.core = {
778 .rc_codes = RC_MAP_ANYSEE,
Mauro Carvalho Chehab52b66142010-11-17 14:20:52 -0300779 .protocol = RC_TYPE_OTHER,
Antti Palosaaria8494682010-10-17 18:25:10 -0300780 .module_name = "anysee",
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -0300781 .rc_query = anysee_rc_query,
Antti Palosaaria8494682010-10-17 18:25:10 -0300782 .rc_interval = 250, /* windows driver uses 500ms */
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -0300783 },
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300784
785 .i2c_algo = &anysee_i2c_algo,
786
787 .generic_bulk_ctrl_endpoint = 1,
788
789 .num_device_descs = 1,
790 .devices = {
791 {
792 .name = "Anysee DVB USB2.0",
793 .cold_ids = {NULL},
794 .warm_ids = {&anysee_table[0],
795 &anysee_table[1], NULL},
796 },
797 }
798};
799
800static struct usb_driver anysee_driver = {
801 .name = "dvb_usb_anysee",
802 .probe = anysee_probe,
803 .disconnect = dvb_usb_device_exit,
804 .id_table = anysee_table,
805};
806
807/* module stuff */
808static int __init anysee_module_init(void)
809{
810 int ret;
811
812 ret = usb_register(&anysee_driver);
813 if (ret)
814 err("%s: usb_register failed. Error number %d", __func__, ret);
815
816 return ret;
817}
818
819static void __exit anysee_module_exit(void)
820{
821 /* deregister this driver from the USB subsystem */
822 usb_deregister(&anysee_driver);
823}
824
825module_init(anysee_module_init);
826module_exit(anysee_module_exit);
827
828MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
829MODULE_DESCRIPTION("Driver Anysee E30 DVB-C & DVB-T USB2.0");
830MODULE_LICENSE("GPL");