blob: 0e94541ffcffcf8c490bd583293cb184e91fa611 [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: ?
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300309 * parts: DNOS404ZH102A(MT352, DTT7579(?))
Antti Palosaari41f81f62011-04-10 17:53:52 -0300310 *
311 * E30 VID=04b4 PID=861f HW=2 FW=2.1 Product=????????
312 * PCB: ?
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300313 * parts: DNOS404ZH103A(ZL10353, DTT7579(?))
Antti Palosaari41f81f62011-04-10 17:53:52 -0300314 *
315 * E30 Plus VID=04b4 PID=861f HW=6 FW=1.0 "anysee"
316 * PCB: 507CD (rev1.1)
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300317 * parts: DNOS404ZH103A(ZL10353, DTT7579(?)), CST56I01
Antti Palosaari41f81f62011-04-10 17:53:52 -0300318 * OEA=80 OEB=00 OEC=00 OED=ff OEF=fe
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300319 * IOA=4f IOB=ff IOC=00 IOD=06 IOF=01
Antti Palosaari41f81f62011-04-10 17:53:52 -0300320 * IOD[0] ZL10353 1=enabled
321 * IOA[7] TS 0=enabled
322 * tuner is not behind ZL10353 I2C-gate (no care if gate disabled or not)
323 *
324 * E30 C Plus VID=04b4 PID=861f HW=10 FW=1.0 "anysee-DC(LP)"
325 * PCB: 507DC (rev0.2)
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300326 * parts: TDA10023, DTOS403IH102B TM, CST56I01
Antti Palosaari41f81f62011-04-10 17:53:52 -0300327 * OEA=80 OEB=00 OEC=00 OED=ff OEF=fe
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300328 * IOA=4f IOB=ff IOC=00 IOD=26 IOF=01
Antti Palosaari41f81f62011-04-10 17:53:52 -0300329 * IOD[0] TDA10023 1=enabled
330 *
331 * E30 C Plus VID=1c73 PID=861f HW=15 FW=1.2 "anysee-FA(LP)"
332 * PCB: 507FA (rev0.4)
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300333 * parts: TDA10023, DTOS403IH102B TM, TDA8024
Antti Palosaari41f81f62011-04-10 17:53:52 -0300334 * OEA=80 OEB=00 OEC=ff OED=ff OEF=ff
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300335 * IOA=4d IOB=ff IOC=00 IOD=00 IOF=c0
Antti Palosaari41f81f62011-04-10 17:53:52 -0300336 * IOD[5] TDA10023 1=enabled
337 * IOE[0] tuner 1=enabled
338 *
339 * E30 Combo Plus VID=1c73 PID=861f HW=15 FW=1.2 "anysee-FA(LP)"
340 * PCB: 507FA (rev1.1)
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300341 * parts: ZL10353, TDA10023, DTOS403IH102B TM, TDA8024
Antti Palosaari41f81f62011-04-10 17:53:52 -0300342 * OEA=80 OEB=00 OEC=ff OED=ff OEF=ff
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300343 * IOA=4d IOB=ff IOC=00 IOD=00 IOF=c0
Antti Palosaari41f81f62011-04-10 17:53:52 -0300344 * DVB-C:
345 * IOD[5] TDA10023 1=enabled
346 * IOE[0] tuner 1=enabled
347 * DVB-T:
348 * IOD[0] ZL10353 1=enabled
349 * IOE[0] tuner 0=enabled
350 * tuner is behind ZL10353 I2C-gate
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300351 *
352 * E7 TC VID=1c73 PID=861f HW=18 FW=0.7 AMTCI=0.5 "anysee-E7TC(LP)"
353 * PCB: 508TC (rev0.6)
354 * parts: ZL10353, TDA10023, DNOD44CDH086A(TDA18212)
355 * OEA=80 OEB=00 OEC=03 OED=f7 OEF=ff
356 * IOA=4d IOB=00 IOC=cc IOD=48 IOF=e4
357 * IOA[7] TS 1=enabled
358 * IOE[4] TDA18212 1=enabled
359 * DVB-C:
360 * IOD[6] ZL10353 0=disabled
361 * IOD[5] TDA10023 1=enabled
362 * IOE[0] IF 1=enabled
363 * DVB-T:
364 * IOD[5] TDA10023 0=disabled
365 * IOD[6] ZL10353 1=enabled
366 * IOE[0] IF 0=enabled
Antti Palosaari41f81f62011-04-10 17:53:52 -0300367 */
368
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300369static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
370{
371 int ret;
372 struct anysee_state *state = adap->dev->priv;
373 u8 hw_info[3];
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300374 u8 tmp;
375 struct i2c_msg msg[2] = {
376 {
377 .addr = anysee_tda18212_config.i2c_address,
378 .flags = 0,
379 .len = 1,
380 .buf = "\x00",
381 }, {
382 .addr = anysee_tda18212_config.i2c_address,
383 .flags = I2C_M_RD,
384 .len = 1,
385 .buf = &tmp,
386 }
387 };
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300388
Antti Palosaari41f81f62011-04-10 17:53:52 -0300389 /* Check which hardware we have.
390 * We must do this call two times to get reliable values (hw bug).
391 */
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300392 ret = anysee_get_hw_info(adap->dev, hw_info);
393 if (ret)
Antti Palosaari41f81f62011-04-10 17:53:52 -0300394 goto error;
395
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300396 ret = anysee_get_hw_info(adap->dev, hw_info);
397 if (ret)
Antti Palosaari41f81f62011-04-10 17:53:52 -0300398 goto error;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300399
400 /* Meaning of these info bytes are guessed. */
Antti Palosaari592d9e22011-04-09 21:13:33 -0300401 info("firmware version:%d.%d hardware id:%d",
402 hw_info[1], hw_info[2], hw_info[0]);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300403
Antti Palosaari41f81f62011-04-10 17:53:52 -0300404 state->hw = hw_info[0];
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300405
Antti Palosaari41f81f62011-04-10 17:53:52 -0300406 switch (state->hw) {
407 case ANYSEE_HW_02: /* 2 */
408 /* E30 */
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300409
Antti Palosaari41f81f62011-04-10 17:53:52 -0300410 /* attach demod */
411 adap->fe = dvb_attach(mt352_attach, &anysee_mt352_config,
412 &adap->dev->i2c_adap);
413 if (adap->fe)
414 break;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300415
Antti Palosaari41f81f62011-04-10 17:53:52 -0300416 /* attach demod */
Antti Palosaari0f77c3a2008-08-11 10:54:16 -0300417 adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config,
Antti Palosaari41f81f62011-04-10 17:53:52 -0300418 &adap->dev->i2c_adap);
Antti Palosaari41f81f62011-04-10 17:53:52 -0300419
420 break;
421 case ANYSEE_HW_507CD: /* 6 */
422 /* E30 Plus */
423
424 /* enable DVB-T demod on IOD[0] */
425 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01);
426 if (ret)
427 goto error;
428
429 /* enable transport stream on IOA[7] */
430 ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (0 << 7), 0x80);
431 if (ret)
432 goto error;
433
434 /* attach demod */
435 adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config,
436 &adap->dev->i2c_adap);
Antti Palosaari41f81f62011-04-10 17:53:52 -0300437
438 break;
439 case ANYSEE_HW_507DC: /* 10 */
440 /* E30 C Plus */
441
442 /* enable DVB-C demod on IOD[0] */
443 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01);
444 if (ret)
445 goto error;
446
447 /* attach demod */
448 adap->fe = dvb_attach(tda10023_attach, &anysee_tda10023_config,
449 &adap->dev->i2c_adap, 0x48);
Antti Palosaari41f81f62011-04-10 17:53:52 -0300450
451 break;
452 case ANYSEE_HW_507FA: /* 15 */
453 /* E30 Combo Plus */
454 /* E30 C Plus */
455
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300456 /* enable tuner on IOE[4] */
457 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10);
458 if (ret)
459 goto error;
460
461 /* probe TDA18212 */
462 tmp = 0;
463 ret = i2c_transfer(&adap->dev->i2c_adap, msg, 2);
464 if (ret == 2 && tmp == 0xc7)
465 deb_info("%s: TDA18212 found\n", __func__);
466 else
467 tmp = 0;
468
469 /* disable tuner on IOE[4] */
470 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 4), 0x10);
471 if (ret)
472 goto error;
473
Antti Palosaari41f81f62011-04-10 17:53:52 -0300474 if (dvb_usb_anysee_delsys) {
475 /* disable DVB-C demod on IOD[5] */
476 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5),
477 0x20);
478 if (ret)
479 goto error;
480
481 /* enable DVB-T demod on IOD[0] */
482 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0),
483 0x01);
484 if (ret)
485 goto error;
486
487 /* attach demod */
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300488 if (tmp == 0xc7) {
489 /* TDA18212 config */
490 adap->fe = dvb_attach(zl10353_attach,
Antti Palosaari1fd80702011-04-12 17:34:08 -0300491 &anysee_zl10353_tda18212_config2,
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300492 &adap->dev->i2c_adap);
493 } else {
494 /* PLL config */
495 adap->fe = dvb_attach(zl10353_attach,
496 &anysee_zl10353_config,
497 &adap->dev->i2c_adap);
498 }
Antti Palosaari41f81f62011-04-10 17:53:52 -0300499 } else {
500 /* disable DVB-T demod on IOD[0] */
501 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 0),
502 0x01);
503 if (ret)
504 goto error;
505
506 /* enable DVB-C demod on IOD[5] */
507 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5),
508 0x20);
509 if (ret)
510 goto error;
511
512 /* attach demod */
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300513 if (tmp == 0xc7) {
514 /* TDA18212 config */
515 adap->fe = dvb_attach(tda10023_attach,
516 &anysee_tda10023_tda18212_config,
517 &adap->dev->i2c_adap, 0x48);
518 } else {
519 /* PLL config */
520 adap->fe = dvb_attach(tda10023_attach,
521 &anysee_tda10023_config,
522 &adap->dev->i2c_adap, 0x48);
523 }
Antti Palosaari0f77c3a2008-08-11 10:54:16 -0300524 }
Antti Palosaarie82eea72011-04-12 19:43:30 -0300525
Antti Palosaari41f81f62011-04-10 17:53:52 -0300526 break;
Antti Palosaaria43be982011-04-10 20:23:02 -0300527 case ANYSEE_HW_508TC: /* 18 */
528 /* E7 TC */
529
530 /* enable transport stream on IOA[7] */
531 ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (1 << 7), 0x80);
532 if (ret)
533 goto error;
534
535 if (dvb_usb_anysee_delsys) {
536 /* disable DVB-C demod on IOD[5] */
537 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5),
538 0x20);
539 if (ret)
540 goto error;
541
542 /* enable DVB-T demod on IOD[6] */
543 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 6),
544 0x40);
545 if (ret)
546 goto error;
547
548 /* enable IF route on IOE[0] */
549 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 0),
550 0x01);
551 if (ret)
552 goto error;
553
554 /* attach demod */
555 adap->fe = dvb_attach(zl10353_attach,
556 &anysee_zl10353_tda18212_config,
557 &adap->dev->i2c_adap);
Antti Palosaaria43be982011-04-10 20:23:02 -0300558 } else {
559 /* disable DVB-T demod on IOD[6] */
560 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 6),
561 0x40);
562 if (ret)
563 goto error;
564
565 /* enable DVB-C demod on IOD[5] */
566 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5),
567 0x20);
568 if (ret)
569 goto error;
570
571 /* enable IF route on IOE[0] */
572 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 0),
573 0x01);
574 if (ret)
575 goto error;
576
577 /* attach demod */
578 adap->fe = dvb_attach(tda10023_attach,
579 &anysee_tda10023_tda18212_config,
580 &adap->dev->i2c_adap, 0x48);
Antti Palosaaria43be982011-04-10 20:23:02 -0300581 }
Antti Palosaarie82eea72011-04-12 19:43:30 -0300582
Antti Palosaaria43be982011-04-10 20:23:02 -0300583 break;
Antti Palosaari0f77c3a2008-08-11 10:54:16 -0300584 }
585
Antti Palosaari41f81f62011-04-10 17:53:52 -0300586 if (!adap->fe) {
587 /* we have no frontend :-( */
588 ret = -ENODEV;
Antti Palosaarie82eea72011-04-12 19:43:30 -0300589 err("Unsupported Anysee version. " \
590 "Please report the <linux-media@vger.kernel.org>.");
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300591 }
Antti Palosaari41f81f62011-04-10 17:53:52 -0300592error:
593 return ret;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300594}
595
596static int anysee_tuner_attach(struct dvb_usb_adapter *adap)
597{
598 struct anysee_state *state = adap->dev->priv;
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300599 struct dvb_frontend *fe;
Antti Palosaarie82eea72011-04-12 19:43:30 -0300600 int ret;
Antti Palosaaria8494682010-10-17 18:25:10 -0300601 deb_info("%s:\n", __func__);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300602
Antti Palosaari41f81f62011-04-10 17:53:52 -0300603 switch (state->hw) {
604 case ANYSEE_HW_02: /* 2 */
605 /* E30 */
606
607 /* attach tuner */
Antti Palosaarie82eea72011-04-12 19:43:30 -0300608 fe = dvb_attach(dvb_pll_attach, adap->fe, (0xc2 >> 1),
Antti Palosaari7ea03d22011-04-09 20:50:07 -0300609 NULL, DVB_PLL_THOMSON_DTT7579);
Antti Palosaarie82eea72011-04-12 19:43:30 -0300610
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300611 break;
Antti Palosaari41f81f62011-04-10 17:53:52 -0300612 case ANYSEE_HW_507CD: /* 6 */
613 /* E30 Plus */
614
615 /* attach tuner */
Antti Palosaarie82eea72011-04-12 19:43:30 -0300616 fe = dvb_attach(dvb_pll_attach, adap->fe, (0xc2 >> 1),
Antti Palosaari41f81f62011-04-10 17:53:52 -0300617 &adap->dev->i2c_adap, DVB_PLL_THOMSON_DTT7579);
618
619 break;
620 case ANYSEE_HW_507DC: /* 10 */
621 /* E30 C Plus */
622
623 /* attach tuner */
Antti Palosaarie82eea72011-04-12 19:43:30 -0300624 fe = dvb_attach(dvb_pll_attach, adap->fe, (0xc0 >> 1),
Antti Palosaari7ea03d22011-04-09 20:50:07 -0300625 &adap->dev->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A);
Antti Palosaarie82eea72011-04-12 19:43:30 -0300626
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300627 break;
Antti Palosaari41f81f62011-04-10 17:53:52 -0300628 case ANYSEE_HW_507FA: /* 15 */
629 /* E30 Combo Plus */
630 /* E30 C Plus */
631
Antti Palosaari59fb4142011-04-12 10:22:47 -0300632 if (dvb_usb_anysee_delsys) {
633 /* enable DVB-T tuner on IOE[0] */
634 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 0),
635 0x01);
636 if (ret)
637 goto error;
638 } else {
639 /* enable DVB-C tuner on IOE[0] */
640 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 0),
641 0x01);
642 if (ret)
643 goto error;
644 }
645
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300646 /* Try first attach TDA18212 silicon tuner on IOE[4], if that
647 * fails attach old simple PLL. */
648
649 /* enable tuner on IOE[4] */
650 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10);
651 if (ret)
652 goto error;
653
654 /* attach tuner */
655 fe = dvb_attach(tda18212_attach, adap->fe, &adap->dev->i2c_adap,
656 &anysee_tda18212_config);
657 if (fe)
658 break;
659
660 /* disable tuner on IOE[4] */
661 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 4), 0x10);
662 if (ret)
663 goto error;
664
Antti Palosaari41f81f62011-04-10 17:53:52 -0300665 /* attach tuner */
Antti Palosaarie82eea72011-04-12 19:43:30 -0300666 fe = dvb_attach(dvb_pll_attach, adap->fe, (0xc0 >> 1),
Antti Palosaari41f81f62011-04-10 17:53:52 -0300667 &adap->dev->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A);
668
669 break;
Antti Palosaaria43be982011-04-10 20:23:02 -0300670 case ANYSEE_HW_508TC: /* 18 */
671 /* E7 TC */
672
673 /* enable tuner on IOE[4] */
674 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10);
675 if (ret)
676 goto error;
677
678 /* attach tuner */
679 fe = dvb_attach(tda18212_attach, adap->fe, &adap->dev->i2c_adap,
680 &anysee_tda18212_config);
Antti Palosaaria43be982011-04-10 20:23:02 -0300681
682 break;
Antti Palosaari41f81f62011-04-10 17:53:52 -0300683 default:
Antti Palosaarie82eea72011-04-12 19:43:30 -0300684 fe = NULL;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300685 }
686
Antti Palosaarie82eea72011-04-12 19:43:30 -0300687 if (fe)
688 ret = 0;
689 else
690 ret = -ENODEV;
691
Antti Palosaari41f81f62011-04-10 17:53:52 -0300692error:
693 return ret;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300694}
695
Antti Palosaaria8494682010-10-17 18:25:10 -0300696static int anysee_rc_query(struct dvb_usb_device *d)
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300697{
698 u8 buf[] = {CMD_GET_IR_CODE};
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300699 u8 ircode[2];
Antti Palosaaria8494682010-10-17 18:25:10 -0300700 int ret;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300701
Antti Palosaaria8494682010-10-17 18:25:10 -0300702 /* Remote controller is basic NEC using address byte 0x08.
703 Anysee device RC query returns only two bytes, status and code,
704 address byte is dropped. Also it does not return any value for
705 NEC RCs having address byte other than 0x08. Due to that, we
706 cannot use that device as standard NEC receiver.
707 It could be possible make hack which reads whole code directly
708 from device memory... */
709
710 ret = anysee_ctrl_msg(d, buf, sizeof(buf), ircode, sizeof(ircode));
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300711 if (ret)
712 return ret;
713
Antti Palosaaria8494682010-10-17 18:25:10 -0300714 if (ircode[0]) {
715 deb_rc("%s: key pressed %02x\n", __func__, ircode[1]);
Mauro Carvalho Chehabca866742010-11-17 13:53:11 -0300716 rc_keydown(d->rc_dev, 0x08 << 8 | ircode[1], 0);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300717 }
Antti Palosaaria8494682010-10-17 18:25:10 -0300718
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300719 return 0;
720}
721
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300722/* DVB USB Driver stuff */
723static struct dvb_usb_device_properties anysee_properties;
724
725static int anysee_probe(struct usb_interface *intf,
726 const struct usb_device_id *id)
727{
728 struct dvb_usb_device *d;
729 struct usb_host_interface *alt;
730 int ret;
731
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300732 /* There is one interface with two alternate settings.
733 Alternate setting 0 is for bulk transfer.
734 Alternate setting 1 is for isochronous transfer.
735 We use bulk transfer (alternate setting 0). */
736 if (intf->num_altsetting < 1)
737 return -ENODEV;
738
Dan Carpenter8b0d7042010-05-31 16:27:39 -0300739 /*
740 * Anysee is always warm (its USB-bridge, Cypress FX2, uploads
741 * firmware from eeprom). If dvb_usb_device_init() succeeds that
742 * means d is a valid pointer.
743 */
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300744 ret = dvb_usb_device_init(intf, &anysee_properties, THIS_MODULE, &d,
745 adapter_nr);
746 if (ret)
747 return ret;
748
749 alt = usb_altnum_to_altsetting(intf, 0);
750 if (alt == NULL) {
751 deb_info("%s: no alt found!\n", __func__);
752 return -ENODEV;
753 }
754
755 ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber,
756 alt->desc.bAlternateSetting);
757 if (ret)
758 return ret;
759
Dan Carpenter8b0d7042010-05-31 16:27:39 -0300760 return anysee_init(d);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300761}
762
Antti Palosaariae3745f2009-09-16 19:50:25 -0300763static struct usb_device_id anysee_table[] = {
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300764 { USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE) },
765 { USB_DEVICE(USB_VID_AMT, USB_PID_ANYSEE) },
766 { } /* Terminating entry */
767};
768MODULE_DEVICE_TABLE(usb, anysee_table);
769
770static struct dvb_usb_device_properties anysee_properties = {
771 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
772
773 .usb_ctrl = DEVICE_SPECIFIC,
774
775 .size_of_priv = sizeof(struct anysee_state),
776
777 .num_adapters = 1,
778 .adapter = {
779 {
780 .streaming_ctrl = anysee_streaming_ctrl,
781 .frontend_attach = anysee_frontend_attach,
782 .tuner_attach = anysee_tuner_attach,
783 .stream = {
784 .type = USB_BULK,
785 .count = 8,
786 .endpoint = 0x82,
787 .u = {
788 .bulk = {
Antti Palosaariab693332009-09-16 19:47:01 -0300789 .buffersize = (16*512),
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300790 }
791 }
792 },
793 }
794 },
795
Antti Palosaaria8494682010-10-17 18:25:10 -0300796 .rc.core = {
797 .rc_codes = RC_MAP_ANYSEE,
Mauro Carvalho Chehab52b66142010-11-17 14:20:52 -0300798 .protocol = RC_TYPE_OTHER,
Antti Palosaaria8494682010-10-17 18:25:10 -0300799 .module_name = "anysee",
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -0300800 .rc_query = anysee_rc_query,
Antti Palosaaria8494682010-10-17 18:25:10 -0300801 .rc_interval = 250, /* windows driver uses 500ms */
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -0300802 },
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300803
804 .i2c_algo = &anysee_i2c_algo,
805
806 .generic_bulk_ctrl_endpoint = 1,
807
808 .num_device_descs = 1,
809 .devices = {
810 {
811 .name = "Anysee DVB USB2.0",
812 .cold_ids = {NULL},
813 .warm_ids = {&anysee_table[0],
814 &anysee_table[1], NULL},
815 },
816 }
817};
818
819static struct usb_driver anysee_driver = {
820 .name = "dvb_usb_anysee",
821 .probe = anysee_probe,
822 .disconnect = dvb_usb_device_exit,
823 .id_table = anysee_table,
824};
825
826/* module stuff */
827static int __init anysee_module_init(void)
828{
829 int ret;
830
831 ret = usb_register(&anysee_driver);
832 if (ret)
833 err("%s: usb_register failed. Error number %d", __func__, ret);
834
835 return ret;
836}
837
838static void __exit anysee_module_exit(void)
839{
840 /* deregister this driver from the USB subsystem */
841 usb_deregister(&anysee_driver);
842}
843
844module_init(anysee_module_init);
845module_exit(anysee_module_exit);
846
847MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
848MODULE_DESCRIPTION("Driver Anysee E30 DVB-C & DVB-T USB2.0");
849MODULE_LICENSE("GPL");