blob: f365c2068e0f4d9c0c10219fc7cadb47c1e48648 [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];
Antti Palosaari882b82c2011-04-12 19:49:25 -0300189 buf[3] = msg[i].buf[1];
190 buf[4] = msg[i].len-1;
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 Palosaari1fd80702011-04-12 17:34:08 -0300269static struct zl10353_config anysee_zl10353_tda18212_config2 = {
270 .demod_address = (0x1e >> 1),
271 .parallel_ts = 1,
272 .disable_i2c_gate_ctrl = 1,
273 .no_tuner = 1,
274 .if2 = 41500,
275};
276
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300277static struct zl10353_config anysee_zl10353_tda18212_config = {
278 .demod_address = (0x18 >> 1),
279 .parallel_ts = 1,
280 .disable_i2c_gate_ctrl = 1,
281 .no_tuner = 1,
282 .if2 = 41500,
283};
284
285static struct tda10023_config anysee_tda10023_tda18212_config = {
286 .demod_address = (0x1a >> 1),
287 .xtal = 16000000,
288 .pll_m = 12,
289 .pll_p = 3,
290 .pll_n = 1,
291 .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_C,
292 .deltaf = 0xba02,
293};
294
295static struct tda18212_config anysee_tda18212_config = {
296 .i2c_address = (0xc0 >> 1),
297 .if_dvbt_6 = 4150,
298 .if_dvbt_7 = 4150,
299 .if_dvbt_8 = 4150,
300 .if_dvbc = 5000,
301};
302
Antti Palosaari41f81f62011-04-10 17:53:52 -0300303/*
304 * New USB device strings: Mfr=1, Product=2, SerialNumber=0
305 * Manufacturer: AMT.CO.KR
306 *
307 * E30 VID=04b4 PID=861f HW=2 FW=2.1 Product=????????
308 * PCB: ?
309 * parts: MT352, DTT7579(?), DNOS404ZH102A NIM
310 *
311 * E30 VID=04b4 PID=861f HW=2 FW=2.1 Product=????????
312 * PCB: ?
313 * parts: ZL10353, DTT7579(?), DNOS404ZH103A NIM
314 *
315 * E30 Plus VID=04b4 PID=861f HW=6 FW=1.0 "anysee"
316 * PCB: 507CD (rev1.1)
317 * parts: ZL10353, DTT7579(?), CST56I01, DNOS404ZH103A NIM
318 * OEA=80 OEB=00 OEC=00 OED=ff OEF=fe
319 * IOD[0] ZL10353 1=enabled
320 * IOA[7] TS 0=enabled
321 * tuner is not behind ZL10353 I2C-gate (no care if gate disabled or not)
322 *
323 * E30 C Plus VID=04b4 PID=861f HW=10 FW=1.0 "anysee-DC(LP)"
324 * PCB: 507DC (rev0.2)
325 * parts: TDA10023, CST56I01, DTOS403IH102B TM
326 * OEA=80 OEB=00 OEC=00 OED=ff OEF=fe
327 * IOD[0] TDA10023 1=enabled
328 *
329 * E30 C Plus VID=1c73 PID=861f HW=15 FW=1.2 "anysee-FA(LP)"
330 * PCB: 507FA (rev0.4)
331 * parts: TDA10023, TDA8024, DTOS403IH102B TM
332 * OEA=80 OEB=00 OEC=ff OED=ff OEF=ff
333 * IOD[5] TDA10023 1=enabled
334 * IOE[0] tuner 1=enabled
335 *
336 * E30 Combo Plus VID=1c73 PID=861f HW=15 FW=1.2 "anysee-FA(LP)"
337 * PCB: 507FA (rev1.1)
338 * parts: ZL10353, TDA10023, TDA8024, DTOS403IH102B TM
339 * OEA=80 OEB=00 OEC=ff OED=ff OEF=ff
340 * DVB-C:
341 * IOD[5] TDA10023 1=enabled
342 * IOE[0] tuner 1=enabled
343 * DVB-T:
344 * IOD[0] ZL10353 1=enabled
345 * IOE[0] tuner 0=enabled
346 * tuner is behind ZL10353 I2C-gate
347 */
348
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300349static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
350{
351 int ret;
352 struct anysee_state *state = adap->dev->priv;
353 u8 hw_info[3];
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300354 u8 tmp;
355 struct i2c_msg msg[2] = {
356 {
357 .addr = anysee_tda18212_config.i2c_address,
358 .flags = 0,
359 .len = 1,
360 .buf = "\x00",
361 }, {
362 .addr = anysee_tda18212_config.i2c_address,
363 .flags = I2C_M_RD,
364 .len = 1,
365 .buf = &tmp,
366 }
367 };
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300368
Antti Palosaari41f81f62011-04-10 17:53:52 -0300369 /* Check which hardware we have.
370 * We must do this call two times to get reliable values (hw bug).
371 */
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300372 ret = anysee_get_hw_info(adap->dev, hw_info);
373 if (ret)
Antti Palosaari41f81f62011-04-10 17:53:52 -0300374 goto error;
375
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300376 ret = anysee_get_hw_info(adap->dev, hw_info);
377 if (ret)
Antti Palosaari41f81f62011-04-10 17:53:52 -0300378 goto error;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300379
380 /* Meaning of these info bytes are guessed. */
Antti Palosaari592d9e22011-04-09 21:13:33 -0300381 info("firmware version:%d.%d hardware id:%d",
382 hw_info[1], hw_info[2], hw_info[0]);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300383
Antti Palosaari41f81f62011-04-10 17:53:52 -0300384 state->hw = hw_info[0];
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300385
Antti Palosaari41f81f62011-04-10 17:53:52 -0300386 switch (state->hw) {
387 case ANYSEE_HW_02: /* 2 */
388 /* E30 */
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300389
Antti Palosaari41f81f62011-04-10 17:53:52 -0300390 /* attach demod */
391 adap->fe = dvb_attach(mt352_attach, &anysee_mt352_config,
392 &adap->dev->i2c_adap);
393 if (adap->fe)
394 break;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300395
Antti Palosaari41f81f62011-04-10 17:53:52 -0300396 /* attach demod */
Antti Palosaari0f77c3a2008-08-11 10:54:16 -0300397 adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config,
Antti Palosaari41f81f62011-04-10 17:53:52 -0300398 &adap->dev->i2c_adap);
Antti Palosaari41f81f62011-04-10 17:53:52 -0300399
400 break;
401 case ANYSEE_HW_507CD: /* 6 */
402 /* E30 Plus */
403
404 /* enable DVB-T demod on IOD[0] */
405 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01);
406 if (ret)
407 goto error;
408
409 /* enable transport stream on IOA[7] */
410 ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (0 << 7), 0x80);
411 if (ret)
412 goto error;
413
414 /* attach demod */
415 adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config,
416 &adap->dev->i2c_adap);
Antti Palosaari41f81f62011-04-10 17:53:52 -0300417
418 break;
419 case ANYSEE_HW_507DC: /* 10 */
420 /* E30 C Plus */
421
422 /* enable DVB-C demod on IOD[0] */
423 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01);
424 if (ret)
425 goto error;
426
427 /* attach demod */
428 adap->fe = dvb_attach(tda10023_attach, &anysee_tda10023_config,
429 &adap->dev->i2c_adap, 0x48);
Antti Palosaari41f81f62011-04-10 17:53:52 -0300430
431 break;
432 case ANYSEE_HW_507FA: /* 15 */
433 /* E30 Combo Plus */
434 /* E30 C Plus */
435
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300436 /* enable tuner on IOE[4] */
437 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10);
438 if (ret)
439 goto error;
440
441 /* probe TDA18212 */
442 tmp = 0;
443 ret = i2c_transfer(&adap->dev->i2c_adap, msg, 2);
444 if (ret == 2 && tmp == 0xc7)
445 deb_info("%s: TDA18212 found\n", __func__);
446 else
447 tmp = 0;
448
449 /* disable tuner on IOE[4] */
450 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 4), 0x10);
451 if (ret)
452 goto error;
453
Antti Palosaari41f81f62011-04-10 17:53:52 -0300454 if (dvb_usb_anysee_delsys) {
455 /* disable DVB-C demod on IOD[5] */
456 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5),
457 0x20);
458 if (ret)
459 goto error;
460
461 /* enable DVB-T demod on IOD[0] */
462 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0),
463 0x01);
464 if (ret)
465 goto error;
466
467 /* attach demod */
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300468 if (tmp == 0xc7) {
469 /* TDA18212 config */
470 adap->fe = dvb_attach(zl10353_attach,
Antti Palosaari1fd80702011-04-12 17:34:08 -0300471 &anysee_zl10353_tda18212_config2,
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300472 &adap->dev->i2c_adap);
473 } else {
474 /* PLL config */
475 adap->fe = dvb_attach(zl10353_attach,
476 &anysee_zl10353_config,
477 &adap->dev->i2c_adap);
478 }
Antti Palosaari41f81f62011-04-10 17:53:52 -0300479 } 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 Palosaari0f77c3a2008-08-11 10:54:16 -0300504 }
Antti Palosaarie82eea72011-04-12 19:43:30 -0300505
Antti Palosaari41f81f62011-04-10 17:53:52 -0300506 break;
Antti Palosaaria43be982011-04-10 20:23:02 -0300507 case ANYSEE_HW_508TC: /* 18 */
508 /* E7 TC */
509
510 /* enable transport stream on IOA[7] */
511 ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (1 << 7), 0x80);
512 if (ret)
513 goto error;
514
515 if (dvb_usb_anysee_delsys) {
516 /* disable DVB-C demod on IOD[5] */
517 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5),
518 0x20);
519 if (ret)
520 goto error;
521
522 /* enable DVB-T demod on IOD[6] */
523 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 6),
524 0x40);
525 if (ret)
526 goto error;
527
528 /* enable IF route on IOE[0] */
529 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 0),
530 0x01);
531 if (ret)
532 goto error;
533
534 /* attach demod */
535 adap->fe = dvb_attach(zl10353_attach,
536 &anysee_zl10353_tda18212_config,
537 &adap->dev->i2c_adap);
Antti Palosaaria43be982011-04-10 20:23:02 -0300538 } else {
539 /* disable DVB-T demod on IOD[6] */
540 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 6),
541 0x40);
542 if (ret)
543 goto error;
544
545 /* enable DVB-C demod on IOD[5] */
546 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5),
547 0x20);
548 if (ret)
549 goto error;
550
551 /* enable IF route on IOE[0] */
552 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 0),
553 0x01);
554 if (ret)
555 goto error;
556
557 /* attach demod */
558 adap->fe = dvb_attach(tda10023_attach,
559 &anysee_tda10023_tda18212_config,
560 &adap->dev->i2c_adap, 0x48);
Antti Palosaaria43be982011-04-10 20:23:02 -0300561 }
Antti Palosaarie82eea72011-04-12 19:43:30 -0300562
Antti Palosaaria43be982011-04-10 20:23:02 -0300563 break;
Antti Palosaari0f77c3a2008-08-11 10:54:16 -0300564 }
565
Antti Palosaari41f81f62011-04-10 17:53:52 -0300566 if (!adap->fe) {
567 /* we have no frontend :-( */
568 ret = -ENODEV;
Antti Palosaarie82eea72011-04-12 19:43:30 -0300569 err("Unsupported Anysee version. " \
570 "Please report the <linux-media@vger.kernel.org>.");
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300571 }
Antti Palosaari41f81f62011-04-10 17:53:52 -0300572error:
573 return ret;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300574}
575
576static int anysee_tuner_attach(struct dvb_usb_adapter *adap)
577{
578 struct anysee_state *state = adap->dev->priv;
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300579 struct dvb_frontend *fe;
Antti Palosaarie82eea72011-04-12 19:43:30 -0300580 int ret;
Antti Palosaaria8494682010-10-17 18:25:10 -0300581 deb_info("%s:\n", __func__);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300582
Antti Palosaari41f81f62011-04-10 17:53:52 -0300583 switch (state->hw) {
584 case ANYSEE_HW_02: /* 2 */
585 /* E30 */
586
587 /* attach tuner */
Antti Palosaarie82eea72011-04-12 19:43:30 -0300588 fe = dvb_attach(dvb_pll_attach, adap->fe, (0xc2 >> 1),
Antti Palosaari7ea03d22011-04-09 20:50:07 -0300589 NULL, DVB_PLL_THOMSON_DTT7579);
Antti Palosaarie82eea72011-04-12 19:43:30 -0300590
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300591 break;
Antti Palosaari41f81f62011-04-10 17:53:52 -0300592 case ANYSEE_HW_507CD: /* 6 */
593 /* E30 Plus */
594
595 /* attach tuner */
Antti Palosaarie82eea72011-04-12 19:43:30 -0300596 fe = dvb_attach(dvb_pll_attach, adap->fe, (0xc2 >> 1),
Antti Palosaari41f81f62011-04-10 17:53:52 -0300597 &adap->dev->i2c_adap, DVB_PLL_THOMSON_DTT7579);
598
599 break;
600 case ANYSEE_HW_507DC: /* 10 */
601 /* E30 C Plus */
602
603 /* attach tuner */
Antti Palosaarie82eea72011-04-12 19:43:30 -0300604 fe = dvb_attach(dvb_pll_attach, adap->fe, (0xc0 >> 1),
Antti Palosaari7ea03d22011-04-09 20:50:07 -0300605 &adap->dev->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A);
Antti Palosaarie82eea72011-04-12 19:43:30 -0300606
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300607 break;
Antti Palosaari41f81f62011-04-10 17:53:52 -0300608 case ANYSEE_HW_507FA: /* 15 */
609 /* E30 Combo Plus */
610 /* E30 C Plus */
611
Antti Palosaari59fb4142011-04-12 10:22:47 -0300612 if (dvb_usb_anysee_delsys) {
613 /* enable DVB-T tuner on IOE[0] */
614 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 0),
615 0x01);
616 if (ret)
617 goto error;
618 } else {
619 /* enable DVB-C tuner on IOE[0] */
620 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 0),
621 0x01);
622 if (ret)
623 goto error;
624 }
625
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300626 /* Try first attach TDA18212 silicon tuner on IOE[4], if that
627 * fails attach old simple PLL. */
628
629 /* enable tuner on IOE[4] */
630 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10);
631 if (ret)
632 goto error;
633
634 /* attach tuner */
635 fe = dvb_attach(tda18212_attach, adap->fe, &adap->dev->i2c_adap,
636 &anysee_tda18212_config);
637 if (fe)
638 break;
639
640 /* disable tuner on IOE[4] */
641 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 4), 0x10);
642 if (ret)
643 goto error;
644
Antti Palosaari41f81f62011-04-10 17:53:52 -0300645 /* attach tuner */
Antti Palosaarie82eea72011-04-12 19:43:30 -0300646 fe = dvb_attach(dvb_pll_attach, adap->fe, (0xc0 >> 1),
Antti Palosaari41f81f62011-04-10 17:53:52 -0300647 &adap->dev->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A);
648
649 break;
Antti Palosaaria43be982011-04-10 20:23:02 -0300650 case ANYSEE_HW_508TC: /* 18 */
651 /* E7 TC */
652
653 /* enable tuner on IOE[4] */
654 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10);
655 if (ret)
656 goto error;
657
658 /* attach tuner */
659 fe = dvb_attach(tda18212_attach, adap->fe, &adap->dev->i2c_adap,
660 &anysee_tda18212_config);
Antti Palosaaria43be982011-04-10 20:23:02 -0300661
662 break;
Antti Palosaari41f81f62011-04-10 17:53:52 -0300663 default:
Antti Palosaarie82eea72011-04-12 19:43:30 -0300664 fe = NULL;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300665 }
666
Antti Palosaarie82eea72011-04-12 19:43:30 -0300667 if (fe)
668 ret = 0;
669 else
670 ret = -ENODEV;
671
Antti Palosaari41f81f62011-04-10 17:53:52 -0300672error:
673 return ret;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300674}
675
Antti Palosaaria8494682010-10-17 18:25:10 -0300676static int anysee_rc_query(struct dvb_usb_device *d)
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300677{
678 u8 buf[] = {CMD_GET_IR_CODE};
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300679 u8 ircode[2];
Antti Palosaaria8494682010-10-17 18:25:10 -0300680 int ret;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300681
Antti Palosaaria8494682010-10-17 18:25:10 -0300682 /* Remote controller is basic NEC using address byte 0x08.
683 Anysee device RC query returns only two bytes, status and code,
684 address byte is dropped. Also it does not return any value for
685 NEC RCs having address byte other than 0x08. Due to that, we
686 cannot use that device as standard NEC receiver.
687 It could be possible make hack which reads whole code directly
688 from device memory... */
689
690 ret = anysee_ctrl_msg(d, buf, sizeof(buf), ircode, sizeof(ircode));
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300691 if (ret)
692 return ret;
693
Antti Palosaaria8494682010-10-17 18:25:10 -0300694 if (ircode[0]) {
695 deb_rc("%s: key pressed %02x\n", __func__, ircode[1]);
Mauro Carvalho Chehabca866742010-11-17 13:53:11 -0300696 rc_keydown(d->rc_dev, 0x08 << 8 | ircode[1], 0);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300697 }
Antti Palosaaria8494682010-10-17 18:25:10 -0300698
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300699 return 0;
700}
701
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300702/* DVB USB Driver stuff */
703static struct dvb_usb_device_properties anysee_properties;
704
705static int anysee_probe(struct usb_interface *intf,
706 const struct usb_device_id *id)
707{
708 struct dvb_usb_device *d;
709 struct usb_host_interface *alt;
710 int ret;
711
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300712 /* There is one interface with two alternate settings.
713 Alternate setting 0 is for bulk transfer.
714 Alternate setting 1 is for isochronous transfer.
715 We use bulk transfer (alternate setting 0). */
716 if (intf->num_altsetting < 1)
717 return -ENODEV;
718
Dan Carpenter8b0d7042010-05-31 16:27:39 -0300719 /*
720 * Anysee is always warm (its USB-bridge, Cypress FX2, uploads
721 * firmware from eeprom). If dvb_usb_device_init() succeeds that
722 * means d is a valid pointer.
723 */
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300724 ret = dvb_usb_device_init(intf, &anysee_properties, THIS_MODULE, &d,
725 adapter_nr);
726 if (ret)
727 return ret;
728
729 alt = usb_altnum_to_altsetting(intf, 0);
730 if (alt == NULL) {
731 deb_info("%s: no alt found!\n", __func__);
732 return -ENODEV;
733 }
734
735 ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber,
736 alt->desc.bAlternateSetting);
737 if (ret)
738 return ret;
739
Dan Carpenter8b0d7042010-05-31 16:27:39 -0300740 return anysee_init(d);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300741}
742
Antti Palosaariae3745f2009-09-16 19:50:25 -0300743static struct usb_device_id anysee_table[] = {
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300744 { USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE) },
745 { USB_DEVICE(USB_VID_AMT, USB_PID_ANYSEE) },
746 { } /* Terminating entry */
747};
748MODULE_DEVICE_TABLE(usb, anysee_table);
749
750static struct dvb_usb_device_properties anysee_properties = {
751 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
752
753 .usb_ctrl = DEVICE_SPECIFIC,
754
755 .size_of_priv = sizeof(struct anysee_state),
756
757 .num_adapters = 1,
758 .adapter = {
759 {
760 .streaming_ctrl = anysee_streaming_ctrl,
761 .frontend_attach = anysee_frontend_attach,
762 .tuner_attach = anysee_tuner_attach,
763 .stream = {
764 .type = USB_BULK,
765 .count = 8,
766 .endpoint = 0x82,
767 .u = {
768 .bulk = {
Antti Palosaariab693332009-09-16 19:47:01 -0300769 .buffersize = (16*512),
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300770 }
771 }
772 },
773 }
774 },
775
Antti Palosaaria8494682010-10-17 18:25:10 -0300776 .rc.core = {
777 .rc_codes = RC_MAP_ANYSEE,
Mauro Carvalho Chehab52b66142010-11-17 14:20:52 -0300778 .protocol = RC_TYPE_OTHER,
Antti Palosaaria8494682010-10-17 18:25:10 -0300779 .module_name = "anysee",
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -0300780 .rc_query = anysee_rc_query,
Antti Palosaaria8494682010-10-17 18:25:10 -0300781 .rc_interval = 250, /* windows driver uses 500ms */
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -0300782 },
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300783
784 .i2c_algo = &anysee_i2c_algo,
785
786 .generic_bulk_ctrl_endpoint = 1,
787
788 .num_device_descs = 1,
789 .devices = {
790 {
791 .name = "Anysee DVB USB2.0",
792 .cold_ids = {NULL},
793 .warm_ids = {&anysee_table[0],
794 &anysee_table[1], NULL},
795 },
796 }
797};
798
799static struct usb_driver anysee_driver = {
800 .name = "dvb_usb_anysee",
801 .probe = anysee_probe,
802 .disconnect = dvb_usb_device_exit,
803 .id_table = anysee_table,
804};
805
806/* module stuff */
807static int __init anysee_module_init(void)
808{
809 int ret;
810
811 ret = usb_register(&anysee_driver);
812 if (ret)
813 err("%s: usb_register failed. Error number %d", __func__, ret);
814
815 return ret;
816}
817
818static void __exit anysee_module_exit(void)
819{
820 /* deregister this driver from the USB subsystem */
821 usb_deregister(&anysee_driver);
822}
823
824module_init(anysee_module_init);
825module_exit(anysee_module_exit);
826
827MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
828MODULE_DESCRIPTION("Driver Anysee E30 DVB-C & DVB-T USB2.0");
829MODULE_LICENSE("GPL");