blob: 0bc1372aac18cd1b2f990ec10d48bba8c9f7bed6 [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 Palosaarif0a53102011-04-27 21:11:59 -030040#include "cx24116.h"
Antti Palosaaribedbf3d2011-04-29 13:55:02 -030041#include "stv0900.h"
42#include "stv6110.h"
Antti Palosaarif0a53102011-04-27 21:11:59 -030043#include "isl6423.h"
Antti Palosaari608add82011-08-12 18:29:46 -030044#include "cxd2820r.h"
Antti Palosaaria51e34d2008-05-17 23:05:48 -030045
46/* debug */
47static int dvb_usb_anysee_debug;
48module_param_named(debug, dvb_usb_anysee_debug, int, 0644);
49MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
Mauro Carvalho Chehabffbc5f82009-01-05 01:34:20 -030050static int dvb_usb_anysee_delsys;
Antti Palosaari0f77c3a2008-08-11 10:54:16 -030051module_param_named(delsys, dvb_usb_anysee_delsys, int, 0644);
52MODULE_PARM_DESC(delsys, "select delivery mode (0=DVB-C, 1=DVB-T)");
Antti Palosaaria51e34d2008-05-17 23:05:48 -030053DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
54
Akinobu Mitadec0c462008-10-29 21:16:04 -030055static DEFINE_MUTEX(anysee_usb_mutex);
Antti Palosaaria51e34d2008-05-17 23:05:48 -030056
57static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen,
58 u8 *rbuf, u8 rlen)
59{
60 struct anysee_state *state = d->priv;
61 int act_len, ret;
62 u8 buf[64];
63
Antti Palosaaria51e34d2008-05-17 23:05:48 -030064 memcpy(&buf[0], sbuf, slen);
65 buf[60] = state->seq++;
66
67 if (mutex_lock_interruptible(&anysee_usb_mutex) < 0)
68 return -EAGAIN;
69
70 /* We need receive one message more after dvb_usb_generic_rw due
71 to weird transaction flow, which is 1 x send + 2 x receive. */
72 ret = dvb_usb_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf), 0);
73
74 if (!ret) {
75 /* receive 2nd answer */
76 ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev,
77 d->props.generic_bulk_ctrl_endpoint), buf, sizeof(buf),
78 &act_len, 2000);
79 if (ret)
80 err("%s: recv bulk message failed: %d", __func__, ret);
81 else {
82 deb_xfer("<<< ");
83 debug_dump(buf, act_len, deb_xfer);
84 }
85 }
86
87 /* read request, copy returned data to return buf */
88 if (!ret && rbuf && rlen)
89 memcpy(rbuf, buf, rlen);
90
91 mutex_unlock(&anysee_usb_mutex);
92
93 return ret;
94}
95
96static int anysee_read_reg(struct dvb_usb_device *d, u16 reg, u8 *val)
97{
98 u8 buf[] = {CMD_REG_READ, reg >> 8, reg & 0xff, 0x01};
99 int ret;
100 ret = anysee_ctrl_msg(d, buf, sizeof(buf), val, 1);
101 deb_info("%s: reg:%04x val:%02x\n", __func__, reg, *val);
102 return ret;
103}
104
105static int anysee_write_reg(struct dvb_usb_device *d, u16 reg, u8 val)
106{
107 u8 buf[] = {CMD_REG_WRITE, reg >> 8, reg & 0xff, 0x01, val};
108 deb_info("%s: reg:%04x val:%02x\n", __func__, reg, val);
109 return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
110}
111
Antti Palosaari41f81f62011-04-10 17:53:52 -0300112/* write single register with mask */
113static int anysee_wr_reg_mask(struct dvb_usb_device *d, u16 reg, u8 val,
114 u8 mask)
115{
116 int ret;
117 u8 tmp;
118
119 /* no need for read if whole reg is written */
120 if (mask != 0xff) {
121 ret = anysee_read_reg(d, reg, &tmp);
122 if (ret)
123 return ret;
124
125 val &= mask;
126 tmp &= ~mask;
127 val |= tmp;
128 }
129
130 return anysee_write_reg(d, reg, val);
131}
132
Antti Palosaari05cd37d2011-09-05 23:33:04 -0300133/* read single register with mask */
134static int anysee_rd_reg_mask(struct dvb_usb_device *d, u16 reg, u8 *val,
135 u8 mask)
136{
137 int ret, i;
138 u8 tmp;
139
140 ret = anysee_read_reg(d, reg, &tmp);
141 if (ret)
142 return ret;
143
144 tmp &= mask;
145
146 /* find position of the first bit */
147 for (i = 0; i < 8; i++) {
148 if ((mask >> i) & 0x01)
149 break;
150 }
151 *val = tmp >> i;
152
153 return 0;
154}
155
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300156static int anysee_get_hw_info(struct dvb_usb_device *d, u8 *id)
157{
158 u8 buf[] = {CMD_GET_HW_INFO};
159 return anysee_ctrl_msg(d, buf, sizeof(buf), id, 3);
160}
161
162static int anysee_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
163{
164 u8 buf[] = {CMD_STREAMING_CTRL, (u8)onoff, 0x00};
165 deb_info("%s: onoff:%02x\n", __func__, onoff);
166 return anysee_ctrl_msg(adap->dev, buf, sizeof(buf), NULL, 0);
167}
168
169static int anysee_led_ctrl(struct dvb_usb_device *d, u8 mode, u8 interval)
170{
171 u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x01, mode, interval};
172 deb_info("%s: state:%02x interval:%02x\n", __func__, mode, interval);
173 return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
174}
175
176static int anysee_ir_ctrl(struct dvb_usb_device *d, u8 onoff)
177{
178 u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x02, onoff};
179 deb_info("%s: onoff:%02x\n", __func__, onoff);
180 return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
181}
182
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300183/* I2C */
184static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
185 int num)
186{
187 struct dvb_usb_device *d = i2c_get_adapdata(adap);
Mauro Carvalho Chehab902571a2008-12-29 19:02:24 -0300188 int ret = 0, inc, i = 0;
Antti Palosaari21d2e932011-05-24 06:04:08 -0300189 u8 buf[52]; /* 4 + 48 (I2C WR USB command header + I2C WR max) */
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300190
191 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
192 return -EAGAIN;
193
194 while (i < num) {
195 if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
Antti Palosaari21d2e932011-05-24 06:04:08 -0300196 if (msg[i].len > 2 || msg[i+1].len > 60) {
197 ret = -EOPNOTSUPP;
198 break;
199 }
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300200 buf[0] = CMD_I2C_READ;
Antti Palosaari7ea03d22011-04-09 20:50:07 -0300201 buf[1] = (msg[i].addr << 1) | 0x01;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300202 buf[2] = msg[i].buf[0];
Antti Palosaari882b82c2011-04-12 19:49:25 -0300203 buf[3] = msg[i].buf[1];
204 buf[4] = msg[i].len-1;
Antti Palosaarib3e6a5a2011-04-09 21:00:51 -0300205 buf[5] = msg[i+1].len;
Antti Palosaari21d2e932011-05-24 06:04:08 -0300206 ret = anysee_ctrl_msg(d, buf, 6, msg[i+1].buf,
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300207 msg[i+1].len);
208 inc = 2;
209 } else {
Antti Palosaari21d2e932011-05-24 06:04:08 -0300210 if (msg[i].len > 48) {
211 ret = -EOPNOTSUPP;
212 break;
213 }
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300214 buf[0] = CMD_I2C_WRITE;
Antti Palosaari7ea03d22011-04-09 20:50:07 -0300215 buf[1] = (msg[i].addr << 1);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300216 buf[2] = msg[i].len;
217 buf[3] = 0x01;
218 memcpy(&buf[4], msg[i].buf, msg[i].len);
Antti Palosaari21d2e932011-05-24 06:04:08 -0300219 ret = anysee_ctrl_msg(d, buf, 4 + msg[i].len, NULL, 0);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300220 inc = 1;
221 }
222 if (ret)
Antti Palosaarie613f8f2008-08-11 10:36:43 -0300223 break;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300224
225 i += inc;
226 }
227
228 mutex_unlock(&d->i2c_mutex);
229
Antti Palosaarie613f8f2008-08-11 10:36:43 -0300230 return ret ? ret : i;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300231}
232
233static u32 anysee_i2c_func(struct i2c_adapter *adapter)
234{
235 return I2C_FUNC_I2C;
236}
237
238static struct i2c_algorithm anysee_i2c_algo = {
239 .master_xfer = anysee_master_xfer,
240 .functionality = anysee_i2c_func,
241};
242
243static int anysee_mt352_demod_init(struct dvb_frontend *fe)
244{
Antti Palosaariae3745f2009-09-16 19:50:25 -0300245 static u8 clock_config[] = { CLOCK_CTL, 0x38, 0x28 };
246 static u8 reset[] = { RESET, 0x80 };
247 static u8 adc_ctl_1_cfg[] = { ADC_CTL_1, 0x40 };
248 static u8 agc_cfg[] = { AGC_TARGET, 0x28, 0x20 };
249 static u8 gpp_ctl_cfg[] = { GPP_CTL, 0x33 };
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300250 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
251
252 mt352_write(fe, clock_config, sizeof(clock_config));
253 udelay(200);
254 mt352_write(fe, reset, sizeof(reset));
255 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
256
257 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
258 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
259 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
260
261 return 0;
262}
263
264/* Callbacks for DVB USB */
265static struct tda10023_config anysee_tda10023_config = {
Antti Palosaari7ea03d22011-04-09 20:50:07 -0300266 .demod_address = (0x1a >> 1),
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300267 .invert = 0,
268 .xtal = 16000000,
269 .pll_m = 11,
270 .pll_p = 3,
271 .pll_n = 1,
Antti Palosaari5ae2fca2008-06-09 22:58:22 -0300272 .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_C,
273 .deltaf = 0xfeeb,
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300274};
275
276static struct mt352_config anysee_mt352_config = {
Antti Palosaari7ea03d22011-04-09 20:50:07 -0300277 .demod_address = (0x1e >> 1),
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300278 .demod_init = anysee_mt352_demod_init,
279};
280
281static struct zl10353_config anysee_zl10353_config = {
Antti Palosaari7ea03d22011-04-09 20:50:07 -0300282 .demod_address = (0x1e >> 1),
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300283 .parallel_ts = 1,
284};
285
Antti Palosaari1fd80702011-04-12 17:34:08 -0300286static struct zl10353_config anysee_zl10353_tda18212_config2 = {
287 .demod_address = (0x1e >> 1),
288 .parallel_ts = 1,
289 .disable_i2c_gate_ctrl = 1,
290 .no_tuner = 1,
291 .if2 = 41500,
292};
293
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300294static struct zl10353_config anysee_zl10353_tda18212_config = {
295 .demod_address = (0x18 >> 1),
296 .parallel_ts = 1,
297 .disable_i2c_gate_ctrl = 1,
298 .no_tuner = 1,
299 .if2 = 41500,
300};
301
302static struct tda10023_config anysee_tda10023_tda18212_config = {
303 .demod_address = (0x1a >> 1),
304 .xtal = 16000000,
305 .pll_m = 12,
306 .pll_p = 3,
307 .pll_n = 1,
Antti Palosaari05cd37d2011-09-05 23:33:04 -0300308 .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_B,
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300309 .deltaf = 0xba02,
310};
311
312static struct tda18212_config anysee_tda18212_config = {
313 .i2c_address = (0xc0 >> 1),
314 .if_dvbt_6 = 4150,
315 .if_dvbt_7 = 4150,
316 .if_dvbt_8 = 4150,
317 .if_dvbc = 5000,
318};
319
Antti Palosaari608add82011-08-12 18:29:46 -0300320static struct tda18212_config anysee_tda18212_config2 = {
321 .i2c_address = 0x60 /* (0xc0 >> 1) */,
322 .if_dvbt_6 = 3550,
323 .if_dvbt_7 = 3700,
324 .if_dvbt_8 = 4150,
325 .if_dvbt2_6 = 3250,
326 .if_dvbt2_7 = 4000,
327 .if_dvbt2_8 = 4000,
328 .if_dvbc = 5000,
329};
330
Antti Palosaarif0a53102011-04-27 21:11:59 -0300331static struct cx24116_config anysee_cx24116_config = {
332 .demod_address = (0xaa >> 1),
333 .mpg_clk_pos_pol = 0x00,
334 .i2c_wr_max = 48,
335};
336
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300337static struct stv0900_config anysee_stv0900_config = {
338 .demod_address = (0xd0 >> 1),
339 .demod_mode = 0,
340 .xtal = 8000000,
341 .clkmode = 3,
342 .diseqc_mode = 2,
343 .tun1_maddress = 0,
344 .tun1_adc = 1, /* 1 Vpp */
345 .path1_mode = 3,
346};
347
348static struct stv6110_config anysee_stv6110_config = {
349 .i2c_address = (0xc0 >> 1),
350 .mclk = 16000000,
351 .clk_div = 1,
352};
353
Antti Palosaarif0a53102011-04-27 21:11:59 -0300354static struct isl6423_config anysee_isl6423_config = {
355 .current_max = SEC_CURRENT_800m,
356 .curlim = SEC_CURRENT_LIM_OFF,
357 .mod_extern = 1,
358 .addr = (0x10 >> 1),
359};
360
Antti Palosaari608add82011-08-12 18:29:46 -0300361static struct cxd2820r_config anysee_cxd2820r_config = {
362 .i2c_address = 0x6d, /* (0xda >> 1) */
363 .ts_mode = 0x38,
364 .if_dvbt_6 = 3550,
365 .if_dvbt_7 = 3700,
366 .if_dvbt_8 = 4150,
367 .if_dvbt2_6 = 3250,
368 .if_dvbt2_7 = 4000,
369 .if_dvbt2_8 = 4000,
370 .if_dvbc = 5000,
371};
372
Antti Palosaari41f81f62011-04-10 17:53:52 -0300373/*
374 * New USB device strings: Mfr=1, Product=2, SerialNumber=0
375 * Manufacturer: AMT.CO.KR
376 *
377 * E30 VID=04b4 PID=861f HW=2 FW=2.1 Product=????????
378 * PCB: ?
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300379 * parts: DNOS404ZH102A(MT352, DTT7579(?))
Antti Palosaari41f81f62011-04-10 17:53:52 -0300380 *
Antti Palosaari05c46c02011-05-25 18:30:09 -0300381 * E30 VID=04b4 PID=861f HW=2 FW=2.1 "anysee-T(LP)"
382 * PCB: PCB 507T (rev1.61)
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300383 * parts: DNOS404ZH103A(ZL10353, DTT7579(?))
Antti Palosaari05c46c02011-05-25 18:30:09 -0300384 * OEA=0a OEB=00 OEC=00 OED=ff OEE=00
385 * IOA=45 IOB=ff IOC=00 IOD=ff IOE=00
Antti Palosaari41f81f62011-04-10 17:53:52 -0300386 *
387 * E30 Plus VID=04b4 PID=861f HW=6 FW=1.0 "anysee"
388 * PCB: 507CD (rev1.1)
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300389 * parts: DNOS404ZH103A(ZL10353, DTT7579(?)), CST56I01
Antti Palosaari05c46c02011-05-25 18:30:09 -0300390 * OEA=80 OEB=00 OEC=00 OED=ff OEE=fe
391 * IOA=4f IOB=ff IOC=00 IOD=06 IOE=01
Antti Palosaari41f81f62011-04-10 17:53:52 -0300392 * IOD[0] ZL10353 1=enabled
393 * IOA[7] TS 0=enabled
394 * tuner is not behind ZL10353 I2C-gate (no care if gate disabled or not)
395 *
396 * E30 C Plus VID=04b4 PID=861f HW=10 FW=1.0 "anysee-DC(LP)"
397 * PCB: 507DC (rev0.2)
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300398 * parts: TDA10023, DTOS403IH102B TM, CST56I01
Antti Palosaari05c46c02011-05-25 18:30:09 -0300399 * OEA=80 OEB=00 OEC=00 OED=ff OEE=fe
400 * IOA=4f IOB=ff IOC=00 IOD=26 IOE=01
Antti Palosaari41f81f62011-04-10 17:53:52 -0300401 * IOD[0] TDA10023 1=enabled
402 *
Antti Palosaarif0a53102011-04-27 21:11:59 -0300403 * E30 S2 Plus VID=04b4 PID=861f HW=11 FW=0.1 "anysee-S2(LP)"
404 * PCB: 507SI (rev2.1)
405 * parts: BS2N10WCC01(CX24116, CX24118), ISL6423, TDA8024
Antti Palosaari05c46c02011-05-25 18:30:09 -0300406 * OEA=80 OEB=00 OEC=ff OED=ff OEE=fe
407 * IOA=4d IOB=ff IOC=00 IOD=26 IOE=01
Antti Palosaarif0a53102011-04-27 21:11:59 -0300408 * IOD[0] CX24116 1=enabled
409 *
Antti Palosaari41f81f62011-04-10 17:53:52 -0300410 * E30 C Plus VID=1c73 PID=861f HW=15 FW=1.2 "anysee-FA(LP)"
411 * PCB: 507FA (rev0.4)
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300412 * parts: TDA10023, DTOS403IH102B TM, TDA8024
Antti Palosaari05c46c02011-05-25 18:30:09 -0300413 * OEA=80 OEB=00 OEC=ff OED=ff OEE=ff
414 * IOA=4d IOB=ff IOC=00 IOD=00 IOE=c0
Antti Palosaari41f81f62011-04-10 17:53:52 -0300415 * IOD[5] TDA10023 1=enabled
416 * IOE[0] tuner 1=enabled
417 *
418 * E30 Combo Plus VID=1c73 PID=861f HW=15 FW=1.2 "anysee-FA(LP)"
419 * PCB: 507FA (rev1.1)
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300420 * parts: ZL10353, TDA10023, DTOS403IH102B TM, TDA8024
Antti Palosaari05c46c02011-05-25 18:30:09 -0300421 * OEA=80 OEB=00 OEC=ff OED=ff OEE=ff
422 * IOA=4d IOB=ff IOC=00 IOD=00 IOE=c0
Antti Palosaari41f81f62011-04-10 17:53:52 -0300423 * DVB-C:
424 * IOD[5] TDA10023 1=enabled
425 * IOE[0] tuner 1=enabled
426 * DVB-T:
427 * IOD[0] ZL10353 1=enabled
428 * IOE[0] tuner 0=enabled
429 * tuner is behind ZL10353 I2C-gate
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300430 *
431 * E7 TC VID=1c73 PID=861f HW=18 FW=0.7 AMTCI=0.5 "anysee-E7TC(LP)"
432 * PCB: 508TC (rev0.6)
433 * parts: ZL10353, TDA10023, DNOD44CDH086A(TDA18212)
Antti Palosaari05c46c02011-05-25 18:30:09 -0300434 * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
435 * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300436 * IOA[7] TS 1=enabled
437 * IOE[4] TDA18212 1=enabled
438 * DVB-C:
439 * IOD[6] ZL10353 0=disabled
440 * IOD[5] TDA10023 1=enabled
441 * IOE[0] IF 1=enabled
442 * DVB-T:
443 * IOD[5] TDA10023 0=disabled
444 * IOD[6] ZL10353 1=enabled
445 * IOE[0] IF 0=enabled
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300446 *
447 * E7 S2 VID=1c73 PID=861f HW=19 FW=0.4 AMTCI=0.5 "anysee-E7S2(LP)"
448 * PCB: 508S2 (rev0.7)
449 * parts: DNBU10512IST(STV0903, STV6110), ISL6423
Antti Palosaari05c46c02011-05-25 18:30:09 -0300450 * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
451 * IOA=4d IOB=00 IOC=c4 IOD=08 IOE=e4
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300452 * IOA[7] TS 1=enabled
453 * IOE[5] STV0903 1=enabled
454 *
Antti Palosaari608add82011-08-12 18:29:46 -0300455 * E7 T2C VID=1c73 PID=861f HW=20 FW=0.1 AMTCI=0.5 "anysee-E7T2C(LP)"
456 * PCB: 508T2C (rev0.3)
457 * parts: DNOQ44QCH106A(CXD2820R, TDA18212), TDA8024
458 * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
459 * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4
460 * IOA[7] TS 1=enabled
461 * IOE[5] CXD2820R 1=enabled
462 *
Antti Palosaari8439e0d2011-05-24 07:57:34 -0300463 * E7 PTC VID=1c73 PID=861f HW=21 FW=0.1 AMTCI=?? "anysee-E7PTC(LP)"
464 * PCB: 508PTC (rev0.5)
465 * parts: ZL10353, TDA10023, DNOD44CDH086A(TDA18212)
466 * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
467 * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4
468 * IOA[7] TS 1=enabled
469 * IOE[4] TDA18212 1=enabled
470 * DVB-C:
471 * IOD[6] ZL10353 0=disabled
472 * IOD[5] TDA10023 1=enabled
473 * IOE[0] IF 1=enabled
474 * DVB-T:
475 * IOD[5] TDA10023 0=disabled
476 * IOD[6] ZL10353 1=enabled
477 * IOE[0] IF 0=enabled
Antti Palosaarifea3c392011-05-25 18:21:43 -0300478 *
Antti Palosaari608add82011-08-12 18:29:46 -0300479 * E7 PS2 VID=1c73 PID=861f HW=22 FW=0.1 AMTCI=?? "anysee-E7PS2(LP)"
Antti Palosaarifea3c392011-05-25 18:21:43 -0300480 * PCB: 508PS2 (rev0.4)
481 * parts: DNBU10512IST(STV0903, STV6110), ISL6423
482 * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
483 * IOA=4d IOB=00 IOC=c4 IOD=08 IOE=e4
484 * IOA[7] TS 1=enabled
485 * IOE[5] STV0903 1=enabled
Antti Palosaari41f81f62011-04-10 17:53:52 -0300486 */
487
Antti Palosaaribe943512011-09-05 22:10:05 -0300488
489/* external I2C gate used for DNOD44CDH086A(TDA18212) tuner module */
490static int anysee_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
491{
492 struct dvb_usb_adapter *adap = fe->dvb->priv;
493
494 /* enable / disable tuner access on IOE[4] */
495 return anysee_wr_reg_mask(adap->dev, REG_IOE, (enable << 4), 0x10);
496}
497
Antti Palosaari449d1a02011-07-25 20:25:21 -0300498static int anysee_frontend_ctrl(struct dvb_frontend *fe, int onoff)
499{
500 struct dvb_usb_adapter *adap = fe->dvb->priv;
501 struct anysee_state *state = adap->dev->priv;
502 int ret;
503
504 deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
505
506 /* no frontend sleep control */
507 if (onoff == 0)
508 return 0;
509
510 switch (state->hw) {
511 case ANYSEE_HW_507FA: /* 15 */
512 /* E30 Combo Plus */
513 /* E30 C Plus */
514
515 if ((fe->id ^ dvb_usb_anysee_delsys) == 0) {
516 /* disable DVB-T demod on IOD[0] */
517 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 0),
518 0x01);
519 if (ret)
520 goto error;
521
522 /* enable DVB-C demod on IOD[5] */
523 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5),
524 0x20);
525 if (ret)
526 goto error;
527
528 /* enable DVB-C tuner on IOE[0] */
529 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 0),
530 0x01);
531 if (ret)
532 goto error;
533 } else {
534 /* disable DVB-C demod on IOD[5] */
535 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5),
536 0x20);
537 if (ret)
538 goto error;
539
540 /* enable DVB-T demod on IOD[0] */
541 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0),
542 0x01);
543 if (ret)
544 goto error;
545
546 /* enable DVB-T tuner on IOE[0] */
547 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 0),
548 0x01);
549 if (ret)
550 goto error;
551 }
552
553 break;
554 case ANYSEE_HW_508TC: /* 18 */
555 case ANYSEE_HW_508PTC: /* 21 */
556 /* E7 TC */
557 /* E7 PTC */
558
559 if ((fe->id ^ dvb_usb_anysee_delsys) == 0) {
560 /* disable DVB-T demod on IOD[6] */
561 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 6),
562 0x40);
563 if (ret)
564 goto error;
565
566 /* enable DVB-C demod on IOD[5] */
567 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5),
568 0x20);
569 if (ret)
570 goto error;
571
572 /* enable IF route on IOE[0] */
573 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 0),
574 0x01);
575 if (ret)
576 goto error;
577 } else {
578 /* disable DVB-C demod on IOD[5] */
579 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5),
580 0x20);
581 if (ret)
582 goto error;
583
584 /* enable DVB-T demod on IOD[6] */
585 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 6),
586 0x40);
587 if (ret)
588 goto error;
589
590 /* enable IF route on IOE[0] */
591 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 0),
592 0x01);
593 if (ret)
594 goto error;
595 }
596
597 break;
598 default:
599 ret = 0;
600 }
601
602error:
603 return ret;
604}
605
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300606static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
607{
608 int ret;
609 struct anysee_state *state = adap->dev->priv;
610 u8 hw_info[3];
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300611 u8 tmp;
612 struct i2c_msg msg[2] = {
613 {
614 .addr = anysee_tda18212_config.i2c_address,
615 .flags = 0,
616 .len = 1,
617 .buf = "\x00",
618 }, {
619 .addr = anysee_tda18212_config.i2c_address,
620 .flags = I2C_M_RD,
621 .len = 1,
622 .buf = &tmp,
623 }
624 };
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300625
Antti Palosaari449d1a02011-07-25 20:25:21 -0300626 /* detect hardware only once */
Michael Krufky77eed212011-09-06 09:31:57 -0300627 if (adap->fe_adap[0].fe == NULL) {
Antti Palosaari449d1a02011-07-25 20:25:21 -0300628 /* Check which hardware we have.
629 * We must do this call two times to get reliable values (hw bug).
630 */
631 ret = anysee_get_hw_info(adap->dev, hw_info);
632 if (ret)
633 goto error;
Antti Palosaari41f81f62011-04-10 17:53:52 -0300634
Antti Palosaari449d1a02011-07-25 20:25:21 -0300635 ret = anysee_get_hw_info(adap->dev, hw_info);
636 if (ret)
637 goto error;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300638
Antti Palosaari449d1a02011-07-25 20:25:21 -0300639 /* Meaning of these info bytes are guessed. */
640 info("firmware version:%d.%d hardware id:%d",
641 hw_info[1], hw_info[2], hw_info[0]);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300642
Antti Palosaari449d1a02011-07-25 20:25:21 -0300643 state->hw = hw_info[0];
644 }
645
646 /* set current frondend ID for devices having two frondends */
Michael Krufky77eed212011-09-06 09:31:57 -0300647 if (adap->fe_adap[0].fe)
Antti Palosaari449d1a02011-07-25 20:25:21 -0300648 state->fe_id++;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300649
Antti Palosaari41f81f62011-04-10 17:53:52 -0300650 switch (state->hw) {
Antti Palosaari05c46c02011-05-25 18:30:09 -0300651 case ANYSEE_HW_507T: /* 2 */
Antti Palosaari41f81f62011-04-10 17:53:52 -0300652 /* E30 */
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300653
Antti Palosaari449d1a02011-07-25 20:25:21 -0300654 if (state->fe_id)
655 break;
656
Antti Palosaari41f81f62011-04-10 17:53:52 -0300657 /* attach demod */
Michael Krufky77eed212011-09-06 09:31:57 -0300658 adap->fe_adap[0].fe = dvb_attach(mt352_attach, &anysee_mt352_config,
Antti Palosaari41f81f62011-04-10 17:53:52 -0300659 &adap->dev->i2c_adap);
Michael Krufky77eed212011-09-06 09:31:57 -0300660 if (adap->fe_adap[0].fe)
Antti Palosaari41f81f62011-04-10 17:53:52 -0300661 break;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300662
Antti Palosaari41f81f62011-04-10 17:53:52 -0300663 /* attach demod */
Michael Krufky77eed212011-09-06 09:31:57 -0300664 adap->fe_adap[0].fe = dvb_attach(zl10353_attach, &anysee_zl10353_config,
Antti Palosaari41f81f62011-04-10 17:53:52 -0300665 &adap->dev->i2c_adap);
Antti Palosaari41f81f62011-04-10 17:53:52 -0300666
667 break;
668 case ANYSEE_HW_507CD: /* 6 */
669 /* E30 Plus */
670
Antti Palosaari449d1a02011-07-25 20:25:21 -0300671 if (state->fe_id)
672 break;
673
Antti Palosaari41f81f62011-04-10 17:53:52 -0300674 /* enable DVB-T demod on IOD[0] */
675 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01);
676 if (ret)
677 goto error;
678
679 /* enable transport stream on IOA[7] */
680 ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (0 << 7), 0x80);
681 if (ret)
682 goto error;
683
684 /* attach demod */
Michael Krufky77eed212011-09-06 09:31:57 -0300685 adap->fe_adap[0].fe = dvb_attach(zl10353_attach,
Antti Palosaari449d1a02011-07-25 20:25:21 -0300686 &anysee_zl10353_config, &adap->dev->i2c_adap);
Antti Palosaari41f81f62011-04-10 17:53:52 -0300687
688 break;
689 case ANYSEE_HW_507DC: /* 10 */
690 /* E30 C Plus */
691
Antti Palosaari449d1a02011-07-25 20:25:21 -0300692 if (state->fe_id)
693 break;
694
Antti Palosaari41f81f62011-04-10 17:53:52 -0300695 /* enable DVB-C demod on IOD[0] */
696 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01);
697 if (ret)
698 goto error;
699
700 /* attach demod */
Michael Krufky77eed212011-09-06 09:31:57 -0300701 adap->fe_adap[0].fe = dvb_attach(tda10023_attach,
Antti Palosaari449d1a02011-07-25 20:25:21 -0300702 &anysee_tda10023_config, &adap->dev->i2c_adap, 0x48);
Antti Palosaari41f81f62011-04-10 17:53:52 -0300703
704 break;
Antti Palosaarif0a53102011-04-27 21:11:59 -0300705 case ANYSEE_HW_507SI: /* 11 */
706 /* E30 S2 Plus */
707
Antti Palosaari449d1a02011-07-25 20:25:21 -0300708 if (state->fe_id)
709 break;
710
Antti Palosaarif0a53102011-04-27 21:11:59 -0300711 /* enable DVB-S/S2 demod on IOD[0] */
712 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01);
713 if (ret)
714 goto error;
715
716 /* attach demod */
Michael Krufky77eed212011-09-06 09:31:57 -0300717 adap->fe_adap[0].fe = dvb_attach(cx24116_attach, &anysee_cx24116_config,
Antti Palosaarif0a53102011-04-27 21:11:59 -0300718 &adap->dev->i2c_adap);
719
720 break;
Antti Palosaari41f81f62011-04-10 17:53:52 -0300721 case ANYSEE_HW_507FA: /* 15 */
722 /* E30 Combo Plus */
723 /* E30 C Plus */
724
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300725 /* enable tuner on IOE[4] */
726 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10);
727 if (ret)
728 goto error;
729
730 /* probe TDA18212 */
731 tmp = 0;
732 ret = i2c_transfer(&adap->dev->i2c_adap, msg, 2);
733 if (ret == 2 && tmp == 0xc7)
734 deb_info("%s: TDA18212 found\n", __func__);
735 else
736 tmp = 0;
737
738 /* disable tuner on IOE[4] */
739 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 4), 0x10);
740 if (ret)
741 goto error;
742
Antti Palosaari449d1a02011-07-25 20:25:21 -0300743 if ((state->fe_id ^ dvb_usb_anysee_delsys) == 0) {
Antti Palosaari41f81f62011-04-10 17:53:52 -0300744 /* disable DVB-T demod on IOD[0] */
745 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 0),
746 0x01);
747 if (ret)
748 goto error;
749
750 /* enable DVB-C demod on IOD[5] */
751 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5),
752 0x20);
753 if (ret)
754 goto error;
755
756 /* attach demod */
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300757 if (tmp == 0xc7) {
758 /* TDA18212 config */
Michael Krufky77eed212011-09-06 09:31:57 -0300759 adap->fe_adap[state->fe_id].fe = dvb_attach(
Antti Palosaari449d1a02011-07-25 20:25:21 -0300760 tda10023_attach,
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300761 &anysee_tda10023_tda18212_config,
762 &adap->dev->i2c_adap, 0x48);
763 } else {
764 /* PLL config */
Michael Krufky77eed212011-09-06 09:31:57 -0300765 adap->fe_adap[state->fe_id].fe = dvb_attach(
Antti Palosaari449d1a02011-07-25 20:25:21 -0300766 tda10023_attach,
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300767 &anysee_tda10023_config,
768 &adap->dev->i2c_adap, 0x48);
769 }
Antti Palosaari449d1a02011-07-25 20:25:21 -0300770 } else {
771 /* disable DVB-C demod on IOD[5] */
772 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5),
773 0x20);
774 if (ret)
775 goto error;
776
777 /* enable DVB-T demod on IOD[0] */
778 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0),
779 0x01);
780 if (ret)
781 goto error;
782
783 /* attach demod */
784 if (tmp == 0xc7) {
785 /* TDA18212 config */
Michael Krufky77eed212011-09-06 09:31:57 -0300786 adap->fe_adap[state->fe_id].fe = dvb_attach(
Antti Palosaari449d1a02011-07-25 20:25:21 -0300787 zl10353_attach,
788 &anysee_zl10353_tda18212_config2,
789 &adap->dev->i2c_adap);
790 } else {
791 /* PLL config */
Michael Krufky77eed212011-09-06 09:31:57 -0300792 adap->fe_adap[state->fe_id].fe = dvb_attach(
Antti Palosaari449d1a02011-07-25 20:25:21 -0300793 zl10353_attach,
794 &anysee_zl10353_config,
795 &adap->dev->i2c_adap);
796 }
Antti Palosaari0f77c3a2008-08-11 10:54:16 -0300797 }
Antti Palosaarie82eea72011-04-12 19:43:30 -0300798
Antti Palosaaribe943512011-09-05 22:10:05 -0300799 /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
800 if (tmp == 0xc7) {
801 if (adap->fe_adap[state->fe_id].fe)
802 adap->fe_adap[state->fe_id].fe->ops.i2c_gate_ctrl =
803 anysee_i2c_gate_ctrl;
804 }
805
Antti Palosaari41f81f62011-04-10 17:53:52 -0300806 break;
Antti Palosaaria43be982011-04-10 20:23:02 -0300807 case ANYSEE_HW_508TC: /* 18 */
Antti Palosaari8439e0d2011-05-24 07:57:34 -0300808 case ANYSEE_HW_508PTC: /* 21 */
Antti Palosaaria43be982011-04-10 20:23:02 -0300809 /* E7 TC */
Antti Palosaari8439e0d2011-05-24 07:57:34 -0300810 /* E7 PTC */
Antti Palosaaria43be982011-04-10 20:23:02 -0300811
Antti Palosaari449d1a02011-07-25 20:25:21 -0300812 if ((state->fe_id ^ dvb_usb_anysee_delsys) == 0) {
Antti Palosaaria43be982011-04-10 20:23:02 -0300813 /* disable DVB-T demod on IOD[6] */
814 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 6),
815 0x40);
816 if (ret)
817 goto error;
818
819 /* enable DVB-C demod on IOD[5] */
820 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5),
821 0x20);
822 if (ret)
823 goto error;
824
Antti Palosaari449d1a02011-07-25 20:25:21 -0300825 /* attach demod */
Michael Krufky77eed212011-09-06 09:31:57 -0300826 adap->fe_adap[state->fe_id].fe = dvb_attach(tda10023_attach,
Antti Palosaari449d1a02011-07-25 20:25:21 -0300827 &anysee_tda10023_tda18212_config,
828 &adap->dev->i2c_adap, 0x48);
829 } else {
830 /* disable DVB-C demod on IOD[5] */
831 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5),
832 0x20);
833 if (ret)
834 goto error;
835
836 /* enable DVB-T demod on IOD[6] */
837 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 6),
838 0x40);
Antti Palosaaria43be982011-04-10 20:23:02 -0300839 if (ret)
840 goto error;
841
842 /* attach demod */
Michael Krufky77eed212011-09-06 09:31:57 -0300843 adap->fe_adap[state->fe_id].fe = dvb_attach(zl10353_attach,
Antti Palosaari449d1a02011-07-25 20:25:21 -0300844 &anysee_zl10353_tda18212_config,
845 &adap->dev->i2c_adap);
Antti Palosaaria43be982011-04-10 20:23:02 -0300846 }
Antti Palosaarie82eea72011-04-12 19:43:30 -0300847
Antti Palosaaribe943512011-09-05 22:10:05 -0300848 /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
849 if (adap->fe_adap[state->fe_id].fe)
850 adap->fe_adap[state->fe_id].fe->ops.i2c_gate_ctrl =
851 anysee_i2c_gate_ctrl;
852
Antti Palosaari05cd37d2011-09-05 23:33:04 -0300853 state->has_ci = true;
854
Antti Palosaaria43be982011-04-10 20:23:02 -0300855 break;
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300856 case ANYSEE_HW_508S2: /* 19 */
Antti Palosaarifea3c392011-05-25 18:21:43 -0300857 case ANYSEE_HW_508PS2: /* 22 */
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300858 /* E7 S2 */
Antti Palosaarifea3c392011-05-25 18:21:43 -0300859 /* E7 PS2 */
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300860
Antti Palosaari449d1a02011-07-25 20:25:21 -0300861 if (state->fe_id)
862 break;
863
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300864 /* enable DVB-S/S2 demod on IOE[5] */
865 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20);
866 if (ret)
867 goto error;
868
869 /* attach demod */
Michael Krufky77eed212011-09-06 09:31:57 -0300870 adap->fe_adap[0].fe = dvb_attach(stv0900_attach, &anysee_stv0900_config,
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300871 &adap->dev->i2c_adap, 0);
872
Antti Palosaari05cd37d2011-09-05 23:33:04 -0300873 state->has_ci = true;
874
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300875 break;
Antti Palosaari608add82011-08-12 18:29:46 -0300876 case ANYSEE_HW_508T2C: /* 20 */
877 /* E7 T2C */
878
Antti Palosaari608add82011-08-12 18:29:46 -0300879 /* enable DVB-T/T2/C demod on IOE[5] */
880 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20);
881 if (ret)
882 goto error;
883
884 if (state->fe_id == 0) {
885 /* DVB-T/T2 */
Antti Palosaaribe943512011-09-05 22:10:05 -0300886 adap->fe_adap[state->fe_id].fe = dvb_attach(cxd2820r_attach,
Antti Palosaari608add82011-08-12 18:29:46 -0300887 &anysee_cxd2820r_config,
888 &adap->dev->i2c_adap, NULL);
889 } else {
890 /* DVB-C */
Antti Palosaaribe943512011-09-05 22:10:05 -0300891 adap->fe_adap[state->fe_id].fe = dvb_attach(cxd2820r_attach,
Antti Palosaari608add82011-08-12 18:29:46 -0300892 &anysee_cxd2820r_config,
Antti Palosaaribe943512011-09-05 22:10:05 -0300893 &adap->dev->i2c_adap, adap->fe_adap[0].fe);
Antti Palosaari608add82011-08-12 18:29:46 -0300894 }
895
Antti Palosaari05cd37d2011-09-05 23:33:04 -0300896 state->has_ci = true;
897
Antti Palosaari608add82011-08-12 18:29:46 -0300898 break;
Antti Palosaari0f77c3a2008-08-11 10:54:16 -0300899 }
900
Michael Krufky77eed212011-09-06 09:31:57 -0300901 if (!adap->fe_adap[0].fe) {
Antti Palosaari41f81f62011-04-10 17:53:52 -0300902 /* we have no frontend :-( */
903 ret = -ENODEV;
Antti Palosaarie82eea72011-04-12 19:43:30 -0300904 err("Unsupported Anysee version. " \
905 "Please report the <linux-media@vger.kernel.org>.");
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300906 }
Antti Palosaari41f81f62011-04-10 17:53:52 -0300907error:
908 return ret;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300909}
910
911static int anysee_tuner_attach(struct dvb_usb_adapter *adap)
912{
913 struct anysee_state *state = adap->dev->priv;
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300914 struct dvb_frontend *fe;
Antti Palosaarie82eea72011-04-12 19:43:30 -0300915 int ret;
Antti Palosaari449d1a02011-07-25 20:25:21 -0300916 deb_info("%s: fe=%d\n", __func__, state->fe_id);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300917
Antti Palosaari41f81f62011-04-10 17:53:52 -0300918 switch (state->hw) {
Antti Palosaari05c46c02011-05-25 18:30:09 -0300919 case ANYSEE_HW_507T: /* 2 */
Antti Palosaari41f81f62011-04-10 17:53:52 -0300920 /* E30 */
921
922 /* attach tuner */
Michael Krufky77eed212011-09-06 09:31:57 -0300923 fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, (0xc2 >> 1),
Antti Palosaari7ea03d22011-04-09 20:50:07 -0300924 NULL, DVB_PLL_THOMSON_DTT7579);
Antti Palosaarie82eea72011-04-12 19:43:30 -0300925
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300926 break;
Antti Palosaari41f81f62011-04-10 17:53:52 -0300927 case ANYSEE_HW_507CD: /* 6 */
928 /* E30 Plus */
929
930 /* attach tuner */
Michael Krufky77eed212011-09-06 09:31:57 -0300931 fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, (0xc2 >> 1),
Antti Palosaari41f81f62011-04-10 17:53:52 -0300932 &adap->dev->i2c_adap, DVB_PLL_THOMSON_DTT7579);
933
934 break;
935 case ANYSEE_HW_507DC: /* 10 */
936 /* E30 C Plus */
937
938 /* attach tuner */
Michael Krufky77eed212011-09-06 09:31:57 -0300939 fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, (0xc0 >> 1),
Antti Palosaari7ea03d22011-04-09 20:50:07 -0300940 &adap->dev->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A);
Antti Palosaarie82eea72011-04-12 19:43:30 -0300941
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300942 break;
Antti Palosaarif0a53102011-04-27 21:11:59 -0300943 case ANYSEE_HW_507SI: /* 11 */
944 /* E30 S2 Plus */
945
946 /* attach LNB controller */
Michael Krufky77eed212011-09-06 09:31:57 -0300947 fe = dvb_attach(isl6423_attach, adap->fe_adap[0].fe,
Antti Palosaari449d1a02011-07-25 20:25:21 -0300948 &adap->dev->i2c_adap, &anysee_isl6423_config);
Antti Palosaarif0a53102011-04-27 21:11:59 -0300949
950 break;
Antti Palosaari41f81f62011-04-10 17:53:52 -0300951 case ANYSEE_HW_507FA: /* 15 */
952 /* E30 Combo Plus */
953 /* E30 C Plus */
954
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300955 /* Try first attach TDA18212 silicon tuner on IOE[4], if that
956 * fails attach old simple PLL. */
957
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300958 /* attach tuner */
Michael Krufky77eed212011-09-06 09:31:57 -0300959 fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe,
Antti Palosaari449d1a02011-07-25 20:25:21 -0300960 &adap->dev->i2c_adap, &anysee_tda18212_config);
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300961 if (fe)
962 break;
963
Antti Palosaari41f81f62011-04-10 17:53:52 -0300964 /* attach tuner */
Michael Krufky77eed212011-09-06 09:31:57 -0300965 fe = dvb_attach(dvb_pll_attach, adap->fe_adap[state->fe_id].fe,
Antti Palosaari449d1a02011-07-25 20:25:21 -0300966 (0xc0 >> 1), &adap->dev->i2c_adap,
967 DVB_PLL_SAMSUNG_DTOS403IH102A);
Antti Palosaari41f81f62011-04-10 17:53:52 -0300968
969 break;
Antti Palosaaria43be982011-04-10 20:23:02 -0300970 case ANYSEE_HW_508TC: /* 18 */
Antti Palosaari8439e0d2011-05-24 07:57:34 -0300971 case ANYSEE_HW_508PTC: /* 21 */
Antti Palosaaria43be982011-04-10 20:23:02 -0300972 /* E7 TC */
Antti Palosaari8439e0d2011-05-24 07:57:34 -0300973 /* E7 PTC */
Antti Palosaaria43be982011-04-10 20:23:02 -0300974
Antti Palosaaria43be982011-04-10 20:23:02 -0300975 /* attach tuner */
Michael Krufky77eed212011-09-06 09:31:57 -0300976 fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe,
Antti Palosaari449d1a02011-07-25 20:25:21 -0300977 &adap->dev->i2c_adap, &anysee_tda18212_config);
Antti Palosaaria43be982011-04-10 20:23:02 -0300978
979 break;
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300980 case ANYSEE_HW_508S2: /* 19 */
Antti Palosaarifea3c392011-05-25 18:21:43 -0300981 case ANYSEE_HW_508PS2: /* 22 */
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300982 /* E7 S2 */
Antti Palosaarifea3c392011-05-25 18:21:43 -0300983 /* E7 PS2 */
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300984
985 /* attach tuner */
Michael Krufky77eed212011-09-06 09:31:57 -0300986 fe = dvb_attach(stv6110_attach, adap->fe_adap[0].fe,
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300987 &anysee_stv6110_config, &adap->dev->i2c_adap);
988
989 if (fe) {
990 /* attach LNB controller */
Michael Krufky77eed212011-09-06 09:31:57 -0300991 fe = dvb_attach(isl6423_attach, adap->fe_adap[0].fe,
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300992 &adap->dev->i2c_adap, &anysee_isl6423_config);
993 }
994
995 break;
Antti Palosaari608add82011-08-12 18:29:46 -0300996
997 case ANYSEE_HW_508T2C: /* 20 */
998 /* E7 T2C */
999
1000 /* attach tuner */
Antti Palosaaribe943512011-09-05 22:10:05 -03001001 fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe,
Antti Palosaari608add82011-08-12 18:29:46 -03001002 &adap->dev->i2c_adap, &anysee_tda18212_config2);
1003
1004 break;
Antti Palosaari41f81f62011-04-10 17:53:52 -03001005 default:
Antti Palosaarie82eea72011-04-12 19:43:30 -03001006 fe = NULL;
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001007 }
1008
Antti Palosaarie82eea72011-04-12 19:43:30 -03001009 if (fe)
1010 ret = 0;
1011 else
1012 ret = -ENODEV;
1013
Antti Palosaari41f81f62011-04-10 17:53:52 -03001014 return ret;
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001015}
1016
Antti Palosaaria8494682010-10-17 18:25:10 -03001017static int anysee_rc_query(struct dvb_usb_device *d)
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001018{
1019 u8 buf[] = {CMD_GET_IR_CODE};
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001020 u8 ircode[2];
Antti Palosaaria8494682010-10-17 18:25:10 -03001021 int ret;
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001022
Antti Palosaaria8494682010-10-17 18:25:10 -03001023 /* Remote controller is basic NEC using address byte 0x08.
1024 Anysee device RC query returns only two bytes, status and code,
1025 address byte is dropped. Also it does not return any value for
1026 NEC RCs having address byte other than 0x08. Due to that, we
1027 cannot use that device as standard NEC receiver.
1028 It could be possible make hack which reads whole code directly
1029 from device memory... */
1030
1031 ret = anysee_ctrl_msg(d, buf, sizeof(buf), ircode, sizeof(ircode));
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001032 if (ret)
1033 return ret;
1034
Antti Palosaaria8494682010-10-17 18:25:10 -03001035 if (ircode[0]) {
1036 deb_rc("%s: key pressed %02x\n", __func__, ircode[1]);
Mauro Carvalho Chehabca866742010-11-17 13:53:11 -03001037 rc_keydown(d->rc_dev, 0x08 << 8 | ircode[1], 0);
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001038 }
Antti Palosaaria8494682010-10-17 18:25:10 -03001039
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001040 return 0;
1041}
1042
Antti Palosaari05cd37d2011-09-05 23:33:04 -03001043static int anysee_ci_read_attribute_mem(struct dvb_ca_en50221 *ci, int slot,
1044 int addr)
1045{
1046 struct dvb_usb_device *d = ci->data;
1047 int ret;
1048 u8 buf[] = {CMD_CI, 0x02, 0x40 | addr >> 8, addr & 0xff, 0x00, 1};
1049 u8 val;
1050
1051 ret = anysee_ctrl_msg(d, buf, sizeof(buf), &val, 1);
1052 if (ret)
1053 return ret;
1054
1055 return val;
1056}
1057
1058static int anysee_ci_write_attribute_mem(struct dvb_ca_en50221 *ci, int slot,
1059 int addr, u8 val)
1060{
1061 struct dvb_usb_device *d = ci->data;
1062 int ret;
1063 u8 buf[] = {CMD_CI, 0x03, 0x40 | addr >> 8, addr & 0xff, 0x00, 1, val};
1064
1065 ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
1066 if (ret)
1067 return ret;
1068
1069 return 0;
1070}
1071
1072static int anysee_ci_read_cam_control(struct dvb_ca_en50221 *ci, int slot,
1073 u8 addr)
1074{
1075 struct dvb_usb_device *d = ci->data;
1076 int ret;
1077 u8 buf[] = {CMD_CI, 0x04, 0x40, addr, 0x00, 1};
1078 u8 val;
1079
1080 ret = anysee_ctrl_msg(d, buf, sizeof(buf), &val, 1);
1081 if (ret)
1082 return ret;
1083
1084 return val;
1085}
1086
1087static int anysee_ci_write_cam_control(struct dvb_ca_en50221 *ci, int slot,
1088 u8 addr, u8 val)
1089{
1090 struct dvb_usb_device *d = ci->data;
1091 int ret;
1092 u8 buf[] = {CMD_CI, 0x05, 0x40, addr, 0x00, 1, val};
1093
1094 ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
1095 if (ret)
1096 return ret;
1097
1098 return 0;
1099}
1100
1101static int anysee_ci_slot_reset(struct dvb_ca_en50221 *ci, int slot)
1102{
1103 struct dvb_usb_device *d = ci->data;
1104 int ret;
1105 struct anysee_state *state = d->priv;
1106
1107 state->ci_cam_ready = jiffies + msecs_to_jiffies(1000);
1108
1109 ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80);
1110 if (ret)
1111 return ret;
1112
1113 msleep(300);
1114
1115 ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
1116 if (ret)
1117 return ret;
1118
1119 return 0;
1120}
1121
1122static int anysee_ci_slot_shutdown(struct dvb_ca_en50221 *ci, int slot)
1123{
1124 struct dvb_usb_device *d = ci->data;
1125 int ret;
1126
1127 ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80);
1128 if (ret)
1129 return ret;
1130
1131 msleep(30);
1132
1133 ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
1134 if (ret)
1135 return ret;
1136
1137 return 0;
1138}
1139
1140static int anysee_ci_slot_ts_enable(struct dvb_ca_en50221 *ci, int slot)
1141{
1142 struct dvb_usb_device *d = ci->data;
1143 int ret;
1144
1145 ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 1), 0x02);
1146 if (ret)
1147 return ret;
1148
1149 return 0;
1150}
1151
1152static int anysee_ci_poll_slot_status(struct dvb_ca_en50221 *ci, int slot,
1153 int open)
1154{
1155 struct dvb_usb_device *d = ci->data;
1156 struct anysee_state *state = d->priv;
1157 int ret;
1158 u8 tmp;
1159
1160 ret = anysee_rd_reg_mask(d, REG_IOC, &tmp, 0x40);
1161 if (ret)
1162 return ret;
1163
1164 if (tmp == 0) {
1165 ret = DVB_CA_EN50221_POLL_CAM_PRESENT;
1166 if (time_after(jiffies, state->ci_cam_ready))
1167 ret |= DVB_CA_EN50221_POLL_CAM_READY;
1168 }
1169
1170 return ret;
1171}
1172
1173static int anysee_ci_init(struct dvb_usb_device *d)
1174{
1175 struct anysee_state *state = d->priv;
1176 int ret;
1177
1178 state->ci.owner = THIS_MODULE;
1179 state->ci.read_attribute_mem = anysee_ci_read_attribute_mem;
1180 state->ci.write_attribute_mem = anysee_ci_write_attribute_mem;
1181 state->ci.read_cam_control = anysee_ci_read_cam_control;
1182 state->ci.write_cam_control = anysee_ci_write_cam_control;
1183 state->ci.slot_reset = anysee_ci_slot_reset;
1184 state->ci.slot_shutdown = anysee_ci_slot_shutdown;
1185 state->ci.slot_ts_enable = anysee_ci_slot_ts_enable;
1186 state->ci.poll_slot_status = anysee_ci_poll_slot_status;
1187 state->ci.data = d;
1188
1189 ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
1190 if (ret)
1191 return ret;
1192
1193 ret = dvb_ca_en50221_init(&d->adapter[0].dvb_adap, &state->ci, 0, 1);
1194 if (ret)
1195 return ret;
1196
1197 return 0;
1198}
1199
1200static void anysee_ci_release(struct dvb_usb_device *d)
1201{
1202 struct anysee_state *state = d->priv;
1203
1204 /* detach CI */
1205 if (state->has_ci)
1206 dvb_ca_en50221_release(&state->ci);
1207
1208 return;
1209}
1210
1211static int anysee_init(struct dvb_usb_device *d)
1212{
1213 struct anysee_state *state = d->priv;
1214 int ret;
1215
1216 /* LED light */
1217 ret = anysee_led_ctrl(d, 0x01, 0x03);
1218 if (ret)
1219 return ret;
1220
1221 /* enable IR */
1222 ret = anysee_ir_ctrl(d, 1);
1223 if (ret)
1224 return ret;
1225
1226 /* attach CI */
1227 if (state->has_ci) {
1228 ret = anysee_ci_init(d);
1229 if (ret) {
1230 state->has_ci = false;
1231 return ret;
1232 }
1233 }
1234
1235 return 0;
1236}
1237
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001238/* DVB USB Driver stuff */
1239static struct dvb_usb_device_properties anysee_properties;
1240
1241static int anysee_probe(struct usb_interface *intf,
1242 const struct usb_device_id *id)
1243{
1244 struct dvb_usb_device *d;
1245 struct usb_host_interface *alt;
1246 int ret;
1247
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001248 /* There is one interface with two alternate settings.
1249 Alternate setting 0 is for bulk transfer.
1250 Alternate setting 1 is for isochronous transfer.
1251 We use bulk transfer (alternate setting 0). */
1252 if (intf->num_altsetting < 1)
1253 return -ENODEV;
1254
Dan Carpenter8b0d7042010-05-31 16:27:39 -03001255 /*
1256 * Anysee is always warm (its USB-bridge, Cypress FX2, uploads
1257 * firmware from eeprom). If dvb_usb_device_init() succeeds that
1258 * means d is a valid pointer.
1259 */
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001260 ret = dvb_usb_device_init(intf, &anysee_properties, THIS_MODULE, &d,
1261 adapter_nr);
1262 if (ret)
1263 return ret;
1264
1265 alt = usb_altnum_to_altsetting(intf, 0);
1266 if (alt == NULL) {
1267 deb_info("%s: no alt found!\n", __func__);
1268 return -ENODEV;
1269 }
1270
1271 ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber,
1272 alt->desc.bAlternateSetting);
1273 if (ret)
1274 return ret;
1275
Dan Carpenter8b0d7042010-05-31 16:27:39 -03001276 return anysee_init(d);
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001277}
1278
Antti Palosaari05cd37d2011-09-05 23:33:04 -03001279static void anysee_disconnect(struct usb_interface *intf)
1280{
1281 struct dvb_usb_device *d = usb_get_intfdata(intf);
1282
1283 anysee_ci_release(d);
1284 dvb_usb_device_exit(intf);
1285
1286 return;
1287}
1288
Antti Palosaariae3745f2009-09-16 19:50:25 -03001289static struct usb_device_id anysee_table[] = {
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001290 { USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE) },
1291 { USB_DEVICE(USB_VID_AMT, USB_PID_ANYSEE) },
1292 { } /* Terminating entry */
1293};
1294MODULE_DEVICE_TABLE(usb, anysee_table);
1295
1296static struct dvb_usb_device_properties anysee_properties = {
1297 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1298
1299 .usb_ctrl = DEVICE_SPECIFIC,
1300
1301 .size_of_priv = sizeof(struct anysee_state),
1302
1303 .num_adapters = 1,
1304 .adapter = {
1305 {
Michael Krufky77eed212011-09-06 09:31:57 -03001306 .num_frontends = 2,
1307 .frontend_ctrl = anysee_frontend_ctrl,
1308 .fe = {{
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001309 .streaming_ctrl = anysee_streaming_ctrl,
1310 .frontend_attach = anysee_frontend_attach,
1311 .tuner_attach = anysee_tuner_attach,
1312 .stream = {
1313 .type = USB_BULK,
1314 .count = 8,
1315 .endpoint = 0x82,
1316 .u = {
1317 .bulk = {
Antti Palosaariab693332009-09-16 19:47:01 -03001318 .buffersize = (16*512),
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001319 }
1320 }
1321 },
Michael Krufky77eed212011-09-06 09:31:57 -03001322 }, {
1323 .streaming_ctrl = anysee_streaming_ctrl,
1324 .frontend_attach = anysee_frontend_attach,
1325 .tuner_attach = anysee_tuner_attach,
1326 .stream = {
1327 .type = USB_BULK,
1328 .count = 8,
1329 .endpoint = 0x82,
1330 .u = {
1331 .bulk = {
1332 .buffersize = (16*512),
1333 }
1334 }
1335 },
1336 }},
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001337 }
1338 },
1339
Antti Palosaaria8494682010-10-17 18:25:10 -03001340 .rc.core = {
1341 .rc_codes = RC_MAP_ANYSEE,
Mauro Carvalho Chehab52b66142010-11-17 14:20:52 -03001342 .protocol = RC_TYPE_OTHER,
Antti Palosaaria8494682010-10-17 18:25:10 -03001343 .module_name = "anysee",
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001344 .rc_query = anysee_rc_query,
Antti Palosaaria8494682010-10-17 18:25:10 -03001345 .rc_interval = 250, /* windows driver uses 500ms */
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001346 },
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001347
1348 .i2c_algo = &anysee_i2c_algo,
1349
1350 .generic_bulk_ctrl_endpoint = 1,
1351
1352 .num_device_descs = 1,
1353 .devices = {
1354 {
1355 .name = "Anysee DVB USB2.0",
1356 .cold_ids = {NULL},
1357 .warm_ids = {&anysee_table[0],
1358 &anysee_table[1], NULL},
1359 },
1360 }
1361};
1362
1363static struct usb_driver anysee_driver = {
1364 .name = "dvb_usb_anysee",
1365 .probe = anysee_probe,
Antti Palosaari05cd37d2011-09-05 23:33:04 -03001366 .disconnect = anysee_disconnect,
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001367 .id_table = anysee_table,
1368};
1369
1370/* module stuff */
1371static int __init anysee_module_init(void)
1372{
1373 int ret;
1374
1375 ret = usb_register(&anysee_driver);
1376 if (ret)
1377 err("%s: usb_register failed. Error number %d", __func__, ret);
1378
1379 return ret;
1380}
1381
1382static void __exit anysee_module_exit(void)
1383{
1384 /* deregister this driver from the USB subsystem */
1385 usb_deregister(&anysee_driver);
1386}
1387
1388module_init(anysee_module_init);
1389module_exit(anysee_module_exit);
1390
1391MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
1392MODULE_DESCRIPTION("Driver Anysee E30 DVB-C & DVB-T USB2.0");
1393MODULE_LICENSE("GPL");