blob: c64eb56204dedc6c455fc013d56b3993260f834f [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
Antti Palosaari4048da22011-09-29 20:28:53 -030070 deb_xfer(">>> ");
71 debug_dump(buf, slen, deb_xfer);
72
Antti Palosaaria51e34d2008-05-17 23:05:48 -030073 /* We need receive one message more after dvb_usb_generic_rw due
74 to weird transaction flow, which is 1 x send + 2 x receive. */
75 ret = dvb_usb_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf), 0);
Antti Palosaaria51e34d2008-05-17 23:05:48 -030076 if (!ret) {
77 /* receive 2nd answer */
78 ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev,
79 d->props.generic_bulk_ctrl_endpoint), buf, sizeof(buf),
80 &act_len, 2000);
81 if (ret)
82 err("%s: recv bulk message failed: %d", __func__, ret);
83 else {
84 deb_xfer("<<< ");
Antti Palosaari4048da22011-09-29 20:28:53 -030085 debug_dump(buf, rlen, deb_xfer);
86
87 if (buf[63] != 0x4f)
88 deb_info("%s: cmd failed\n", __func__);
Antti Palosaaria51e34d2008-05-17 23:05:48 -030089 }
90 }
91
92 /* read request, copy returned data to return buf */
93 if (!ret && rbuf && rlen)
94 memcpy(rbuf, buf, rlen);
95
96 mutex_unlock(&anysee_usb_mutex);
97
98 return ret;
99}
100
101static int anysee_read_reg(struct dvb_usb_device *d, u16 reg, u8 *val)
102{
103 u8 buf[] = {CMD_REG_READ, reg >> 8, reg & 0xff, 0x01};
104 int ret;
105 ret = anysee_ctrl_msg(d, buf, sizeof(buf), val, 1);
106 deb_info("%s: reg:%04x val:%02x\n", __func__, reg, *val);
107 return ret;
108}
109
110static int anysee_write_reg(struct dvb_usb_device *d, u16 reg, u8 val)
111{
112 u8 buf[] = {CMD_REG_WRITE, reg >> 8, reg & 0xff, 0x01, val};
113 deb_info("%s: reg:%04x val:%02x\n", __func__, reg, val);
114 return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
115}
116
Antti Palosaari41f81f62011-04-10 17:53:52 -0300117/* write single register with mask */
118static int anysee_wr_reg_mask(struct dvb_usb_device *d, u16 reg, u8 val,
119 u8 mask)
120{
121 int ret;
122 u8 tmp;
123
124 /* no need for read if whole reg is written */
125 if (mask != 0xff) {
126 ret = anysee_read_reg(d, reg, &tmp);
127 if (ret)
128 return ret;
129
130 val &= mask;
131 tmp &= ~mask;
132 val |= tmp;
133 }
134
135 return anysee_write_reg(d, reg, val);
136}
137
Antti Palosaari05cd37d2011-09-05 23:33:04 -0300138/* read single register with mask */
139static int anysee_rd_reg_mask(struct dvb_usb_device *d, u16 reg, u8 *val,
140 u8 mask)
141{
142 int ret, i;
143 u8 tmp;
144
145 ret = anysee_read_reg(d, reg, &tmp);
146 if (ret)
147 return ret;
148
149 tmp &= mask;
150
151 /* find position of the first bit */
152 for (i = 0; i < 8; i++) {
153 if ((mask >> i) & 0x01)
154 break;
155 }
156 *val = tmp >> i;
157
158 return 0;
159}
160
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300161static int anysee_get_hw_info(struct dvb_usb_device *d, u8 *id)
162{
163 u8 buf[] = {CMD_GET_HW_INFO};
164 return anysee_ctrl_msg(d, buf, sizeof(buf), id, 3);
165}
166
167static int anysee_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
168{
169 u8 buf[] = {CMD_STREAMING_CTRL, (u8)onoff, 0x00};
170 deb_info("%s: onoff:%02x\n", __func__, onoff);
171 return anysee_ctrl_msg(adap->dev, buf, sizeof(buf), NULL, 0);
172}
173
174static int anysee_led_ctrl(struct dvb_usb_device *d, u8 mode, u8 interval)
175{
176 u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x01, mode, interval};
177 deb_info("%s: state:%02x interval:%02x\n", __func__, mode, interval);
178 return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
179}
180
181static int anysee_ir_ctrl(struct dvb_usb_device *d, u8 onoff)
182{
183 u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x02, onoff};
184 deb_info("%s: onoff:%02x\n", __func__, onoff);
185 return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
186}
187
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300188/* I2C */
189static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
190 int num)
191{
192 struct dvb_usb_device *d = i2c_get_adapdata(adap);
Mauro Carvalho Chehab902571a2008-12-29 19:02:24 -0300193 int ret = 0, inc, i = 0;
Antti Palosaari21d2e932011-05-24 06:04:08 -0300194 u8 buf[52]; /* 4 + 48 (I2C WR USB command header + I2C WR max) */
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300195
196 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
197 return -EAGAIN;
198
199 while (i < num) {
200 if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
Antti Palosaari21d2e932011-05-24 06:04:08 -0300201 if (msg[i].len > 2 || msg[i+1].len > 60) {
202 ret = -EOPNOTSUPP;
203 break;
204 }
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300205 buf[0] = CMD_I2C_READ;
Antti Palosaari7ea03d22011-04-09 20:50:07 -0300206 buf[1] = (msg[i].addr << 1) | 0x01;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300207 buf[2] = msg[i].buf[0];
Antti Palosaari882b82c2011-04-12 19:49:25 -0300208 buf[3] = msg[i].buf[1];
209 buf[4] = msg[i].len-1;
Antti Palosaarib3e6a5a2011-04-09 21:00:51 -0300210 buf[5] = msg[i+1].len;
Antti Palosaari21d2e932011-05-24 06:04:08 -0300211 ret = anysee_ctrl_msg(d, buf, 6, msg[i+1].buf,
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300212 msg[i+1].len);
213 inc = 2;
214 } else {
Antti Palosaari21d2e932011-05-24 06:04:08 -0300215 if (msg[i].len > 48) {
216 ret = -EOPNOTSUPP;
217 break;
218 }
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300219 buf[0] = CMD_I2C_WRITE;
Antti Palosaari7ea03d22011-04-09 20:50:07 -0300220 buf[1] = (msg[i].addr << 1);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300221 buf[2] = msg[i].len;
222 buf[3] = 0x01;
223 memcpy(&buf[4], msg[i].buf, msg[i].len);
Antti Palosaari21d2e932011-05-24 06:04:08 -0300224 ret = anysee_ctrl_msg(d, buf, 4 + msg[i].len, NULL, 0);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300225 inc = 1;
226 }
227 if (ret)
Antti Palosaarie613f8f2008-08-11 10:36:43 -0300228 break;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300229
230 i += inc;
231 }
232
233 mutex_unlock(&d->i2c_mutex);
234
Antti Palosaarie613f8f2008-08-11 10:36:43 -0300235 return ret ? ret : i;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300236}
237
238static u32 anysee_i2c_func(struct i2c_adapter *adapter)
239{
240 return I2C_FUNC_I2C;
241}
242
243static struct i2c_algorithm anysee_i2c_algo = {
244 .master_xfer = anysee_master_xfer,
245 .functionality = anysee_i2c_func,
246};
247
248static int anysee_mt352_demod_init(struct dvb_frontend *fe)
249{
Antti Palosaariae3745f2009-09-16 19:50:25 -0300250 static u8 clock_config[] = { CLOCK_CTL, 0x38, 0x28 };
251 static u8 reset[] = { RESET, 0x80 };
252 static u8 adc_ctl_1_cfg[] = { ADC_CTL_1, 0x40 };
253 static u8 agc_cfg[] = { AGC_TARGET, 0x28, 0x20 };
254 static u8 gpp_ctl_cfg[] = { GPP_CTL, 0x33 };
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300255 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
256
257 mt352_write(fe, clock_config, sizeof(clock_config));
258 udelay(200);
259 mt352_write(fe, reset, sizeof(reset));
260 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
261
262 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
263 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
264 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
265
266 return 0;
267}
268
269/* Callbacks for DVB USB */
270static struct tda10023_config anysee_tda10023_config = {
Antti Palosaari7ea03d22011-04-09 20:50:07 -0300271 .demod_address = (0x1a >> 1),
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300272 .invert = 0,
273 .xtal = 16000000,
274 .pll_m = 11,
275 .pll_p = 3,
276 .pll_n = 1,
Antti Palosaari5ae2fca2008-06-09 22:58:22 -0300277 .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_C,
278 .deltaf = 0xfeeb,
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300279};
280
281static struct mt352_config anysee_mt352_config = {
Antti Palosaari7ea03d22011-04-09 20:50:07 -0300282 .demod_address = (0x1e >> 1),
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300283 .demod_init = anysee_mt352_demod_init,
284};
285
286static struct zl10353_config anysee_zl10353_config = {
Antti Palosaari7ea03d22011-04-09 20:50:07 -0300287 .demod_address = (0x1e >> 1),
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300288 .parallel_ts = 1,
289};
290
Antti Palosaari1fd80702011-04-12 17:34:08 -0300291static struct zl10353_config anysee_zl10353_tda18212_config2 = {
292 .demod_address = (0x1e >> 1),
293 .parallel_ts = 1,
294 .disable_i2c_gate_ctrl = 1,
295 .no_tuner = 1,
296 .if2 = 41500,
297};
298
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300299static struct zl10353_config anysee_zl10353_tda18212_config = {
300 .demod_address = (0x18 >> 1),
301 .parallel_ts = 1,
302 .disable_i2c_gate_ctrl = 1,
303 .no_tuner = 1,
304 .if2 = 41500,
305};
306
307static struct tda10023_config anysee_tda10023_tda18212_config = {
308 .demod_address = (0x1a >> 1),
309 .xtal = 16000000,
310 .pll_m = 12,
311 .pll_p = 3,
312 .pll_n = 1,
Antti Palosaari05cd37d2011-09-05 23:33:04 -0300313 .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_B,
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300314 .deltaf = 0xba02,
315};
316
317static struct tda18212_config anysee_tda18212_config = {
318 .i2c_address = (0xc0 >> 1),
319 .if_dvbt_6 = 4150,
320 .if_dvbt_7 = 4150,
321 .if_dvbt_8 = 4150,
322 .if_dvbc = 5000,
323};
324
Antti Palosaari608add82011-08-12 18:29:46 -0300325static struct tda18212_config anysee_tda18212_config2 = {
326 .i2c_address = 0x60 /* (0xc0 >> 1) */,
327 .if_dvbt_6 = 3550,
328 .if_dvbt_7 = 3700,
329 .if_dvbt_8 = 4150,
330 .if_dvbt2_6 = 3250,
331 .if_dvbt2_7 = 4000,
332 .if_dvbt2_8 = 4000,
333 .if_dvbc = 5000,
334};
335
Antti Palosaarif0a53102011-04-27 21:11:59 -0300336static struct cx24116_config anysee_cx24116_config = {
337 .demod_address = (0xaa >> 1),
338 .mpg_clk_pos_pol = 0x00,
339 .i2c_wr_max = 48,
340};
341
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300342static struct stv0900_config anysee_stv0900_config = {
343 .demod_address = (0xd0 >> 1),
344 .demod_mode = 0,
345 .xtal = 8000000,
346 .clkmode = 3,
347 .diseqc_mode = 2,
348 .tun1_maddress = 0,
349 .tun1_adc = 1, /* 1 Vpp */
350 .path1_mode = 3,
351};
352
353static struct stv6110_config anysee_stv6110_config = {
354 .i2c_address = (0xc0 >> 1),
355 .mclk = 16000000,
356 .clk_div = 1,
357};
358
Antti Palosaarif0a53102011-04-27 21:11:59 -0300359static struct isl6423_config anysee_isl6423_config = {
360 .current_max = SEC_CURRENT_800m,
361 .curlim = SEC_CURRENT_LIM_OFF,
362 .mod_extern = 1,
363 .addr = (0x10 >> 1),
364};
365
Antti Palosaari608add82011-08-12 18:29:46 -0300366static struct cxd2820r_config anysee_cxd2820r_config = {
367 .i2c_address = 0x6d, /* (0xda >> 1) */
368 .ts_mode = 0x38,
369 .if_dvbt_6 = 3550,
370 .if_dvbt_7 = 3700,
371 .if_dvbt_8 = 4150,
372 .if_dvbt2_6 = 3250,
373 .if_dvbt2_7 = 4000,
374 .if_dvbt2_8 = 4000,
375 .if_dvbc = 5000,
376};
377
Antti Palosaari41f81f62011-04-10 17:53:52 -0300378/*
379 * New USB device strings: Mfr=1, Product=2, SerialNumber=0
380 * Manufacturer: AMT.CO.KR
381 *
382 * E30 VID=04b4 PID=861f HW=2 FW=2.1 Product=????????
383 * PCB: ?
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300384 * parts: DNOS404ZH102A(MT352, DTT7579(?))
Antti Palosaari41f81f62011-04-10 17:53:52 -0300385 *
Antti Palosaari05c46c02011-05-25 18:30:09 -0300386 * E30 VID=04b4 PID=861f HW=2 FW=2.1 "anysee-T(LP)"
387 * PCB: PCB 507T (rev1.61)
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300388 * parts: DNOS404ZH103A(ZL10353, DTT7579(?))
Antti Palosaari05c46c02011-05-25 18:30:09 -0300389 * OEA=0a OEB=00 OEC=00 OED=ff OEE=00
390 * IOA=45 IOB=ff IOC=00 IOD=ff IOE=00
Antti Palosaari41f81f62011-04-10 17:53:52 -0300391 *
392 * E30 Plus VID=04b4 PID=861f HW=6 FW=1.0 "anysee"
393 * PCB: 507CD (rev1.1)
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300394 * parts: DNOS404ZH103A(ZL10353, DTT7579(?)), CST56I01
Antti Palosaari05c46c02011-05-25 18:30:09 -0300395 * OEA=80 OEB=00 OEC=00 OED=ff OEE=fe
396 * IOA=4f IOB=ff IOC=00 IOD=06 IOE=01
Antti Palosaari41f81f62011-04-10 17:53:52 -0300397 * IOD[0] ZL10353 1=enabled
398 * IOA[7] TS 0=enabled
399 * tuner is not behind ZL10353 I2C-gate (no care if gate disabled or not)
400 *
401 * E30 C Plus VID=04b4 PID=861f HW=10 FW=1.0 "anysee-DC(LP)"
402 * PCB: 507DC (rev0.2)
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300403 * parts: TDA10023, DTOS403IH102B TM, CST56I01
Antti Palosaari05c46c02011-05-25 18:30:09 -0300404 * OEA=80 OEB=00 OEC=00 OED=ff OEE=fe
405 * IOA=4f IOB=ff IOC=00 IOD=26 IOE=01
Antti Palosaari41f81f62011-04-10 17:53:52 -0300406 * IOD[0] TDA10023 1=enabled
407 *
Antti Palosaarif0a53102011-04-27 21:11:59 -0300408 * E30 S2 Plus VID=04b4 PID=861f HW=11 FW=0.1 "anysee-S2(LP)"
409 * PCB: 507SI (rev2.1)
410 * parts: BS2N10WCC01(CX24116, CX24118), ISL6423, TDA8024
Antti Palosaari05c46c02011-05-25 18:30:09 -0300411 * OEA=80 OEB=00 OEC=ff OED=ff OEE=fe
412 * IOA=4d IOB=ff IOC=00 IOD=26 IOE=01
Antti Palosaarif0a53102011-04-27 21:11:59 -0300413 * IOD[0] CX24116 1=enabled
414 *
Antti Palosaari41f81f62011-04-10 17:53:52 -0300415 * E30 C Plus VID=1c73 PID=861f HW=15 FW=1.2 "anysee-FA(LP)"
416 * PCB: 507FA (rev0.4)
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300417 * parts: TDA10023, DTOS403IH102B TM, TDA8024
Antti Palosaari05c46c02011-05-25 18:30:09 -0300418 * OEA=80 OEB=00 OEC=ff OED=ff OEE=ff
419 * IOA=4d IOB=ff IOC=00 IOD=00 IOE=c0
Antti Palosaari41f81f62011-04-10 17:53:52 -0300420 * IOD[5] TDA10023 1=enabled
421 * IOE[0] tuner 1=enabled
422 *
423 * E30 Combo Plus VID=1c73 PID=861f HW=15 FW=1.2 "anysee-FA(LP)"
424 * PCB: 507FA (rev1.1)
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300425 * parts: ZL10353, TDA10023, DTOS403IH102B TM, TDA8024
Antti Palosaari05c46c02011-05-25 18:30:09 -0300426 * OEA=80 OEB=00 OEC=ff OED=ff OEE=ff
427 * IOA=4d IOB=ff IOC=00 IOD=00 IOE=c0
Antti Palosaari41f81f62011-04-10 17:53:52 -0300428 * DVB-C:
429 * IOD[5] TDA10023 1=enabled
430 * IOE[0] tuner 1=enabled
431 * DVB-T:
432 * IOD[0] ZL10353 1=enabled
433 * IOE[0] tuner 0=enabled
434 * tuner is behind ZL10353 I2C-gate
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300435 *
436 * E7 TC VID=1c73 PID=861f HW=18 FW=0.7 AMTCI=0.5 "anysee-E7TC(LP)"
437 * PCB: 508TC (rev0.6)
438 * parts: ZL10353, TDA10023, DNOD44CDH086A(TDA18212)
Antti Palosaari05c46c02011-05-25 18:30:09 -0300439 * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
440 * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300441 * IOA[7] TS 1=enabled
442 * IOE[4] TDA18212 1=enabled
443 * DVB-C:
444 * IOD[6] ZL10353 0=disabled
445 * IOD[5] TDA10023 1=enabled
446 * IOE[0] IF 1=enabled
447 * DVB-T:
448 * IOD[5] TDA10023 0=disabled
449 * IOD[6] ZL10353 1=enabled
450 * IOE[0] IF 0=enabled
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300451 *
452 * E7 S2 VID=1c73 PID=861f HW=19 FW=0.4 AMTCI=0.5 "anysee-E7S2(LP)"
453 * PCB: 508S2 (rev0.7)
454 * parts: DNBU10512IST(STV0903, STV6110), ISL6423
Antti Palosaari05c46c02011-05-25 18:30:09 -0300455 * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
456 * IOA=4d IOB=00 IOC=c4 IOD=08 IOE=e4
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300457 * IOA[7] TS 1=enabled
458 * IOE[5] STV0903 1=enabled
459 *
Antti Palosaari608add82011-08-12 18:29:46 -0300460 * E7 T2C VID=1c73 PID=861f HW=20 FW=0.1 AMTCI=0.5 "anysee-E7T2C(LP)"
461 * PCB: 508T2C (rev0.3)
462 * parts: DNOQ44QCH106A(CXD2820R, TDA18212), TDA8024
463 * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
464 * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4
465 * IOA[7] TS 1=enabled
466 * IOE[5] CXD2820R 1=enabled
467 *
Antti Palosaari8439e0d2011-05-24 07:57:34 -0300468 * E7 PTC VID=1c73 PID=861f HW=21 FW=0.1 AMTCI=?? "anysee-E7PTC(LP)"
469 * PCB: 508PTC (rev0.5)
470 * parts: ZL10353, TDA10023, DNOD44CDH086A(TDA18212)
471 * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
472 * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4
473 * IOA[7] TS 1=enabled
474 * IOE[4] TDA18212 1=enabled
475 * DVB-C:
476 * IOD[6] ZL10353 0=disabled
477 * IOD[5] TDA10023 1=enabled
478 * IOE[0] IF 1=enabled
479 * DVB-T:
480 * IOD[5] TDA10023 0=disabled
481 * IOD[6] ZL10353 1=enabled
482 * IOE[0] IF 0=enabled
Antti Palosaarifea3c392011-05-25 18:21:43 -0300483 *
Antti Palosaari608add82011-08-12 18:29:46 -0300484 * E7 PS2 VID=1c73 PID=861f HW=22 FW=0.1 AMTCI=?? "anysee-E7PS2(LP)"
Antti Palosaarifea3c392011-05-25 18:21:43 -0300485 * PCB: 508PS2 (rev0.4)
486 * parts: DNBU10512IST(STV0903, STV6110), ISL6423
487 * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
488 * IOA=4d IOB=00 IOC=c4 IOD=08 IOE=e4
489 * IOA[7] TS 1=enabled
490 * IOE[5] STV0903 1=enabled
Antti Palosaari41f81f62011-04-10 17:53:52 -0300491 */
492
Antti Palosaaribe943512011-09-05 22:10:05 -0300493
494/* external I2C gate used for DNOD44CDH086A(TDA18212) tuner module */
495static int anysee_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
496{
497 struct dvb_usb_adapter *adap = fe->dvb->priv;
498
499 /* enable / disable tuner access on IOE[4] */
500 return anysee_wr_reg_mask(adap->dev, REG_IOE, (enable << 4), 0x10);
501}
502
Antti Palosaari449d1a02011-07-25 20:25:21 -0300503static int anysee_frontend_ctrl(struct dvb_frontend *fe, int onoff)
504{
505 struct dvb_usb_adapter *adap = fe->dvb->priv;
506 struct anysee_state *state = adap->dev->priv;
507 int ret;
508
509 deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
510
511 /* no frontend sleep control */
512 if (onoff == 0)
513 return 0;
514
515 switch (state->hw) {
516 case ANYSEE_HW_507FA: /* 15 */
517 /* E30 Combo Plus */
518 /* E30 C Plus */
519
520 if ((fe->id ^ dvb_usb_anysee_delsys) == 0) {
521 /* disable DVB-T demod on IOD[0] */
522 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 0),
523 0x01);
524 if (ret)
525 goto error;
526
527 /* enable DVB-C demod on IOD[5] */
528 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5),
529 0x20);
530 if (ret)
531 goto error;
532
533 /* enable DVB-C tuner on IOE[0] */
534 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 0),
535 0x01);
536 if (ret)
537 goto error;
538 } else {
539 /* disable DVB-C demod on IOD[5] */
540 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5),
541 0x20);
542 if (ret)
543 goto error;
544
545 /* enable DVB-T demod on IOD[0] */
546 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0),
547 0x01);
548 if (ret)
549 goto error;
550
551 /* enable DVB-T tuner on IOE[0] */
552 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 0),
553 0x01);
554 if (ret)
555 goto error;
556 }
557
558 break;
559 case ANYSEE_HW_508TC: /* 18 */
560 case ANYSEE_HW_508PTC: /* 21 */
561 /* E7 TC */
562 /* E7 PTC */
563
564 if ((fe->id ^ dvb_usb_anysee_delsys) == 0) {
565 /* disable DVB-T demod on IOD[6] */
566 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 6),
567 0x40);
568 if (ret)
569 goto error;
570
571 /* enable DVB-C demod on IOD[5] */
572 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5),
573 0x20);
574 if (ret)
575 goto error;
576
577 /* enable IF route on IOE[0] */
578 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 0),
579 0x01);
580 if (ret)
581 goto error;
582 } else {
583 /* disable DVB-C demod on IOD[5] */
584 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5),
585 0x20);
586 if (ret)
587 goto error;
588
589 /* enable DVB-T demod on IOD[6] */
590 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 6),
591 0x40);
592 if (ret)
593 goto error;
594
595 /* enable IF route on IOE[0] */
596 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 0),
597 0x01);
598 if (ret)
599 goto error;
600 }
601
602 break;
603 default:
604 ret = 0;
605 }
606
607error:
608 return ret;
609}
610
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300611static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
612{
613 int ret;
614 struct anysee_state *state = adap->dev->priv;
615 u8 hw_info[3];
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300616 u8 tmp;
617 struct i2c_msg msg[2] = {
618 {
619 .addr = anysee_tda18212_config.i2c_address,
620 .flags = 0,
621 .len = 1,
622 .buf = "\x00",
623 }, {
624 .addr = anysee_tda18212_config.i2c_address,
625 .flags = I2C_M_RD,
626 .len = 1,
627 .buf = &tmp,
628 }
629 };
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300630
Antti Palosaari449d1a02011-07-25 20:25:21 -0300631 /* detect hardware only once */
Michael Krufky77eed212011-09-06 09:31:57 -0300632 if (adap->fe_adap[0].fe == NULL) {
Antti Palosaari449d1a02011-07-25 20:25:21 -0300633 /* Check which hardware we have.
Antti Palosaari8f4ffb12011-09-29 20:36:33 -0300634 * We must do this call two times to get reliable values
635 * (hw/fw bug).
Antti Palosaari449d1a02011-07-25 20:25:21 -0300636 */
637 ret = anysee_get_hw_info(adap->dev, hw_info);
638 if (ret)
639 goto error;
Antti Palosaari41f81f62011-04-10 17:53:52 -0300640
Antti Palosaari449d1a02011-07-25 20:25:21 -0300641 ret = anysee_get_hw_info(adap->dev, hw_info);
642 if (ret)
643 goto error;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300644
Antti Palosaari449d1a02011-07-25 20:25:21 -0300645 /* Meaning of these info bytes are guessed. */
646 info("firmware version:%d.%d hardware id:%d",
647 hw_info[1], hw_info[2], hw_info[0]);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300648
Antti Palosaari449d1a02011-07-25 20:25:21 -0300649 state->hw = hw_info[0];
650 }
651
652 /* set current frondend ID for devices having two frondends */
Michael Krufky77eed212011-09-06 09:31:57 -0300653 if (adap->fe_adap[0].fe)
Antti Palosaari449d1a02011-07-25 20:25:21 -0300654 state->fe_id++;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300655
Antti Palosaari41f81f62011-04-10 17:53:52 -0300656 switch (state->hw) {
Antti Palosaari05c46c02011-05-25 18:30:09 -0300657 case ANYSEE_HW_507T: /* 2 */
Antti Palosaari41f81f62011-04-10 17:53:52 -0300658 /* E30 */
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300659
Antti Palosaari449d1a02011-07-25 20:25:21 -0300660 if (state->fe_id)
661 break;
662
Antti Palosaari41f81f62011-04-10 17:53:52 -0300663 /* attach demod */
Antti Palosaari8f4ffb12011-09-29 20:36:33 -0300664 adap->fe_adap[0].fe = dvb_attach(mt352_attach,
665 &anysee_mt352_config, &adap->dev->i2c_adap);
Michael Krufky77eed212011-09-06 09:31:57 -0300666 if (adap->fe_adap[0].fe)
Antti Palosaari41f81f62011-04-10 17:53:52 -0300667 break;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300668
Antti Palosaari41f81f62011-04-10 17:53:52 -0300669 /* attach demod */
Antti Palosaari8f4ffb12011-09-29 20:36:33 -0300670 adap->fe_adap[0].fe = dvb_attach(zl10353_attach,
671 &anysee_zl10353_config, &adap->dev->i2c_adap);
Antti Palosaari41f81f62011-04-10 17:53:52 -0300672
673 break;
674 case ANYSEE_HW_507CD: /* 6 */
675 /* E30 Plus */
676
Antti Palosaari449d1a02011-07-25 20:25:21 -0300677 if (state->fe_id)
678 break;
679
Antti Palosaari41f81f62011-04-10 17:53:52 -0300680 /* enable DVB-T demod on IOD[0] */
681 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01);
682 if (ret)
683 goto error;
684
685 /* enable transport stream on IOA[7] */
686 ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (0 << 7), 0x80);
687 if (ret)
688 goto error;
689
690 /* attach demod */
Michael Krufky77eed212011-09-06 09:31:57 -0300691 adap->fe_adap[0].fe = dvb_attach(zl10353_attach,
Antti Palosaari449d1a02011-07-25 20:25:21 -0300692 &anysee_zl10353_config, &adap->dev->i2c_adap);
Antti Palosaari41f81f62011-04-10 17:53:52 -0300693
694 break;
695 case ANYSEE_HW_507DC: /* 10 */
696 /* E30 C Plus */
697
Antti Palosaari449d1a02011-07-25 20:25:21 -0300698 if (state->fe_id)
699 break;
700
Antti Palosaari41f81f62011-04-10 17:53:52 -0300701 /* enable DVB-C demod on IOD[0] */
702 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01);
703 if (ret)
704 goto error;
705
706 /* attach demod */
Michael Krufky77eed212011-09-06 09:31:57 -0300707 adap->fe_adap[0].fe = dvb_attach(tda10023_attach,
Antti Palosaari449d1a02011-07-25 20:25:21 -0300708 &anysee_tda10023_config, &adap->dev->i2c_adap, 0x48);
Antti Palosaari41f81f62011-04-10 17:53:52 -0300709
710 break;
Antti Palosaarif0a53102011-04-27 21:11:59 -0300711 case ANYSEE_HW_507SI: /* 11 */
712 /* E30 S2 Plus */
713
Antti Palosaari449d1a02011-07-25 20:25:21 -0300714 if (state->fe_id)
715 break;
716
Antti Palosaarif0a53102011-04-27 21:11:59 -0300717 /* enable DVB-S/S2 demod on IOD[0] */
718 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01);
719 if (ret)
720 goto error;
721
722 /* attach demod */
Antti Palosaari8f4ffb12011-09-29 20:36:33 -0300723 adap->fe_adap[0].fe = dvb_attach(cx24116_attach,
724 &anysee_cx24116_config, &adap->dev->i2c_adap);
Antti Palosaarif0a53102011-04-27 21:11:59 -0300725
726 break;
Antti Palosaari41f81f62011-04-10 17:53:52 -0300727 case ANYSEE_HW_507FA: /* 15 */
728 /* E30 Combo Plus */
729 /* E30 C Plus */
730
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300731 /* enable tuner on IOE[4] */
732 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10);
733 if (ret)
734 goto error;
735
736 /* probe TDA18212 */
737 tmp = 0;
738 ret = i2c_transfer(&adap->dev->i2c_adap, msg, 2);
739 if (ret == 2 && tmp == 0xc7)
740 deb_info("%s: TDA18212 found\n", __func__);
741 else
742 tmp = 0;
743
744 /* disable tuner on IOE[4] */
745 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 4), 0x10);
746 if (ret)
747 goto error;
748
Antti Palosaari449d1a02011-07-25 20:25:21 -0300749 if ((state->fe_id ^ dvb_usb_anysee_delsys) == 0) {
Antti Palosaari41f81f62011-04-10 17:53:52 -0300750 /* disable DVB-T demod on IOD[0] */
751 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 0),
752 0x01);
753 if (ret)
754 goto error;
755
756 /* enable DVB-C demod on IOD[5] */
757 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5),
758 0x20);
759 if (ret)
760 goto error;
761
762 /* attach demod */
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300763 if (tmp == 0xc7) {
764 /* TDA18212 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_tda18212_config,
768 &adap->dev->i2c_adap, 0x48);
769 } else {
770 /* PLL config */
Michael Krufky77eed212011-09-06 09:31:57 -0300771 adap->fe_adap[state->fe_id].fe = dvb_attach(
Antti Palosaari449d1a02011-07-25 20:25:21 -0300772 tda10023_attach,
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300773 &anysee_tda10023_config,
774 &adap->dev->i2c_adap, 0x48);
775 }
Antti Palosaari449d1a02011-07-25 20:25:21 -0300776 } else {
777 /* disable DVB-C demod on IOD[5] */
778 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5),
779 0x20);
780 if (ret)
781 goto error;
782
783 /* enable DVB-T demod on IOD[0] */
784 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0),
785 0x01);
786 if (ret)
787 goto error;
788
789 /* attach demod */
790 if (tmp == 0xc7) {
791 /* TDA18212 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_tda18212_config2,
795 &adap->dev->i2c_adap);
796 } else {
797 /* PLL config */
Michael Krufky77eed212011-09-06 09:31:57 -0300798 adap->fe_adap[state->fe_id].fe = dvb_attach(
Antti Palosaari449d1a02011-07-25 20:25:21 -0300799 zl10353_attach,
800 &anysee_zl10353_config,
801 &adap->dev->i2c_adap);
802 }
Antti Palosaari0f77c3a2008-08-11 10:54:16 -0300803 }
Antti Palosaarie82eea72011-04-12 19:43:30 -0300804
Antti Palosaaribe943512011-09-05 22:10:05 -0300805 /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
806 if (tmp == 0xc7) {
807 if (adap->fe_adap[state->fe_id].fe)
808 adap->fe_adap[state->fe_id].fe->ops.i2c_gate_ctrl =
809 anysee_i2c_gate_ctrl;
810 }
811
Antti Palosaari41f81f62011-04-10 17:53:52 -0300812 break;
Antti Palosaaria43be982011-04-10 20:23:02 -0300813 case ANYSEE_HW_508TC: /* 18 */
Antti Palosaari8439e0d2011-05-24 07:57:34 -0300814 case ANYSEE_HW_508PTC: /* 21 */
Antti Palosaaria43be982011-04-10 20:23:02 -0300815 /* E7 TC */
Antti Palosaari8439e0d2011-05-24 07:57:34 -0300816 /* E7 PTC */
Antti Palosaaria43be982011-04-10 20:23:02 -0300817
Antti Palosaari449d1a02011-07-25 20:25:21 -0300818 if ((state->fe_id ^ dvb_usb_anysee_delsys) == 0) {
Antti Palosaaria43be982011-04-10 20:23:02 -0300819 /* disable DVB-T demod on IOD[6] */
820 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 6),
821 0x40);
822 if (ret)
823 goto error;
824
825 /* enable DVB-C demod on IOD[5] */
826 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5),
827 0x20);
828 if (ret)
829 goto error;
830
Antti Palosaari449d1a02011-07-25 20:25:21 -0300831 /* attach demod */
Antti Palosaari8f4ffb12011-09-29 20:36:33 -0300832 adap->fe_adap[state->fe_id].fe =
833 dvb_attach(tda10023_attach,
Antti Palosaari449d1a02011-07-25 20:25:21 -0300834 &anysee_tda10023_tda18212_config,
835 &adap->dev->i2c_adap, 0x48);
836 } else {
837 /* disable DVB-C demod on IOD[5] */
838 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5),
839 0x20);
840 if (ret)
841 goto error;
842
843 /* enable DVB-T demod on IOD[6] */
844 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 6),
845 0x40);
Antti Palosaaria43be982011-04-10 20:23:02 -0300846 if (ret)
847 goto error;
848
849 /* attach demod */
Antti Palosaari8f4ffb12011-09-29 20:36:33 -0300850 adap->fe_adap[state->fe_id].fe =
851 dvb_attach(zl10353_attach,
Antti Palosaari449d1a02011-07-25 20:25:21 -0300852 &anysee_zl10353_tda18212_config,
853 &adap->dev->i2c_adap);
Antti Palosaaria43be982011-04-10 20:23:02 -0300854 }
Antti Palosaarie82eea72011-04-12 19:43:30 -0300855
Antti Palosaaribe943512011-09-05 22:10:05 -0300856 /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
857 if (adap->fe_adap[state->fe_id].fe)
858 adap->fe_adap[state->fe_id].fe->ops.i2c_gate_ctrl =
859 anysee_i2c_gate_ctrl;
860
Antti Palosaari05cd37d2011-09-05 23:33:04 -0300861 state->has_ci = true;
862
Antti Palosaaria43be982011-04-10 20:23:02 -0300863 break;
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300864 case ANYSEE_HW_508S2: /* 19 */
Antti Palosaarifea3c392011-05-25 18:21:43 -0300865 case ANYSEE_HW_508PS2: /* 22 */
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300866 /* E7 S2 */
Antti Palosaarifea3c392011-05-25 18:21:43 -0300867 /* E7 PS2 */
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300868
Antti Palosaari449d1a02011-07-25 20:25:21 -0300869 if (state->fe_id)
870 break;
871
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300872 /* enable DVB-S/S2 demod on IOE[5] */
873 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20);
874 if (ret)
875 goto error;
876
877 /* attach demod */
Antti Palosaari8f4ffb12011-09-29 20:36:33 -0300878 adap->fe_adap[0].fe = dvb_attach(stv0900_attach,
879 &anysee_stv0900_config, &adap->dev->i2c_adap, 0);
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300880
Antti Palosaari05cd37d2011-09-05 23:33:04 -0300881 state->has_ci = true;
882
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300883 break;
Antti Palosaari608add82011-08-12 18:29:46 -0300884 case ANYSEE_HW_508T2C: /* 20 */
885 /* E7 T2C */
886
Antti Palosaari608add82011-08-12 18:29:46 -0300887 /* enable DVB-T/T2/C demod on IOE[5] */
888 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20);
889 if (ret)
890 goto error;
891
892 if (state->fe_id == 0) {
893 /* DVB-T/T2 */
Antti Palosaari8f4ffb12011-09-29 20:36:33 -0300894 adap->fe_adap[state->fe_id].fe =
895 dvb_attach(cxd2820r_attach,
Antti Palosaari608add82011-08-12 18:29:46 -0300896 &anysee_cxd2820r_config,
897 &adap->dev->i2c_adap, NULL);
898 } else {
899 /* DVB-C */
Antti Palosaari8f4ffb12011-09-29 20:36:33 -0300900 adap->fe_adap[state->fe_id].fe =
901 dvb_attach(cxd2820r_attach,
Antti Palosaari608add82011-08-12 18:29:46 -0300902 &anysee_cxd2820r_config,
Antti Palosaaribe943512011-09-05 22:10:05 -0300903 &adap->dev->i2c_adap, adap->fe_adap[0].fe);
Antti Palosaari608add82011-08-12 18:29:46 -0300904 }
905
Antti Palosaari05cd37d2011-09-05 23:33:04 -0300906 state->has_ci = true;
907
Antti Palosaari608add82011-08-12 18:29:46 -0300908 break;
Antti Palosaari0f77c3a2008-08-11 10:54:16 -0300909 }
910
Michael Krufky77eed212011-09-06 09:31:57 -0300911 if (!adap->fe_adap[0].fe) {
Antti Palosaari41f81f62011-04-10 17:53:52 -0300912 /* we have no frontend :-( */
913 ret = -ENODEV;
Antti Palosaarie82eea72011-04-12 19:43:30 -0300914 err("Unsupported Anysee version. " \
915 "Please report the <linux-media@vger.kernel.org>.");
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300916 }
Antti Palosaari41f81f62011-04-10 17:53:52 -0300917error:
918 return ret;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300919}
920
921static int anysee_tuner_attach(struct dvb_usb_adapter *adap)
922{
923 struct anysee_state *state = adap->dev->priv;
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300924 struct dvb_frontend *fe;
Antti Palosaarie82eea72011-04-12 19:43:30 -0300925 int ret;
Antti Palosaari449d1a02011-07-25 20:25:21 -0300926 deb_info("%s: fe=%d\n", __func__, state->fe_id);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300927
Antti Palosaari41f81f62011-04-10 17:53:52 -0300928 switch (state->hw) {
Antti Palosaari05c46c02011-05-25 18:30:09 -0300929 case ANYSEE_HW_507T: /* 2 */
Antti Palosaari41f81f62011-04-10 17:53:52 -0300930 /* E30 */
931
932 /* attach tuner */
Antti Palosaari8f4ffb12011-09-29 20:36:33 -0300933 fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe,
934 (0xc2 >> 1), NULL, DVB_PLL_THOMSON_DTT7579);
Antti Palosaarie82eea72011-04-12 19:43:30 -0300935
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300936 break;
Antti Palosaari41f81f62011-04-10 17:53:52 -0300937 case ANYSEE_HW_507CD: /* 6 */
938 /* E30 Plus */
939
940 /* attach tuner */
Antti Palosaari8f4ffb12011-09-29 20:36:33 -0300941 fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe,
942 (0xc2 >> 1), &adap->dev->i2c_adap,
943 DVB_PLL_THOMSON_DTT7579);
Antti Palosaari41f81f62011-04-10 17:53:52 -0300944
945 break;
946 case ANYSEE_HW_507DC: /* 10 */
947 /* E30 C Plus */
948
949 /* attach tuner */
Antti Palosaari8f4ffb12011-09-29 20:36:33 -0300950 fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe,
951 (0xc0 >> 1), &adap->dev->i2c_adap,
952 DVB_PLL_SAMSUNG_DTOS403IH102A);
Antti Palosaarie82eea72011-04-12 19:43:30 -0300953
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300954 break;
Antti Palosaarif0a53102011-04-27 21:11:59 -0300955 case ANYSEE_HW_507SI: /* 11 */
956 /* E30 S2 Plus */
957
958 /* attach LNB controller */
Michael Krufky77eed212011-09-06 09:31:57 -0300959 fe = dvb_attach(isl6423_attach, adap->fe_adap[0].fe,
Antti Palosaari449d1a02011-07-25 20:25:21 -0300960 &adap->dev->i2c_adap, &anysee_isl6423_config);
Antti Palosaarif0a53102011-04-27 21:11:59 -0300961
962 break;
Antti Palosaari41f81f62011-04-10 17:53:52 -0300963 case ANYSEE_HW_507FA: /* 15 */
964 /* E30 Combo Plus */
965 /* E30 C Plus */
966
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300967 /* Try first attach TDA18212 silicon tuner on IOE[4], if that
968 * fails attach old simple PLL. */
969
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300970 /* attach tuner */
Michael Krufky77eed212011-09-06 09:31:57 -0300971 fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe,
Antti Palosaari449d1a02011-07-25 20:25:21 -0300972 &adap->dev->i2c_adap, &anysee_tda18212_config);
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300973 if (fe)
974 break;
975
Antti Palosaari41f81f62011-04-10 17:53:52 -0300976 /* attach tuner */
Michael Krufky77eed212011-09-06 09:31:57 -0300977 fe = dvb_attach(dvb_pll_attach, adap->fe_adap[state->fe_id].fe,
Antti Palosaari449d1a02011-07-25 20:25:21 -0300978 (0xc0 >> 1), &adap->dev->i2c_adap,
979 DVB_PLL_SAMSUNG_DTOS403IH102A);
Antti Palosaari41f81f62011-04-10 17:53:52 -0300980
981 break;
Antti Palosaaria43be982011-04-10 20:23:02 -0300982 case ANYSEE_HW_508TC: /* 18 */
Antti Palosaari8439e0d2011-05-24 07:57:34 -0300983 case ANYSEE_HW_508PTC: /* 21 */
Antti Palosaaria43be982011-04-10 20:23:02 -0300984 /* E7 TC */
Antti Palosaari8439e0d2011-05-24 07:57:34 -0300985 /* E7 PTC */
Antti Palosaaria43be982011-04-10 20:23:02 -0300986
Antti Palosaaria43be982011-04-10 20:23:02 -0300987 /* attach tuner */
Michael Krufky77eed212011-09-06 09:31:57 -0300988 fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe,
Antti Palosaari449d1a02011-07-25 20:25:21 -0300989 &adap->dev->i2c_adap, &anysee_tda18212_config);
Antti Palosaaria43be982011-04-10 20:23:02 -0300990
991 break;
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300992 case ANYSEE_HW_508S2: /* 19 */
Antti Palosaarifea3c392011-05-25 18:21:43 -0300993 case ANYSEE_HW_508PS2: /* 22 */
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300994 /* E7 S2 */
Antti Palosaarifea3c392011-05-25 18:21:43 -0300995 /* E7 PS2 */
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300996
997 /* attach tuner */
Michael Krufky77eed212011-09-06 09:31:57 -0300998 fe = dvb_attach(stv6110_attach, adap->fe_adap[0].fe,
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300999 &anysee_stv6110_config, &adap->dev->i2c_adap);
1000
1001 if (fe) {
1002 /* attach LNB controller */
Michael Krufky77eed212011-09-06 09:31:57 -03001003 fe = dvb_attach(isl6423_attach, adap->fe_adap[0].fe,
Antti Palosaaribedbf3d2011-04-29 13:55:02 -03001004 &adap->dev->i2c_adap, &anysee_isl6423_config);
1005 }
1006
1007 break;
Antti Palosaari608add82011-08-12 18:29:46 -03001008
1009 case ANYSEE_HW_508T2C: /* 20 */
1010 /* E7 T2C */
1011
1012 /* attach tuner */
Antti Palosaaribe943512011-09-05 22:10:05 -03001013 fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe,
Antti Palosaari608add82011-08-12 18:29:46 -03001014 &adap->dev->i2c_adap, &anysee_tda18212_config2);
1015
1016 break;
Antti Palosaari41f81f62011-04-10 17:53:52 -03001017 default:
Antti Palosaarie82eea72011-04-12 19:43:30 -03001018 fe = NULL;
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001019 }
1020
Antti Palosaarie82eea72011-04-12 19:43:30 -03001021 if (fe)
1022 ret = 0;
1023 else
1024 ret = -ENODEV;
1025
Antti Palosaari41f81f62011-04-10 17:53:52 -03001026 return ret;
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001027}
1028
Antti Palosaaria8494682010-10-17 18:25:10 -03001029static int anysee_rc_query(struct dvb_usb_device *d)
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001030{
1031 u8 buf[] = {CMD_GET_IR_CODE};
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001032 u8 ircode[2];
Antti Palosaaria8494682010-10-17 18:25:10 -03001033 int ret;
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001034
Antti Palosaaria8494682010-10-17 18:25:10 -03001035 /* Remote controller is basic NEC using address byte 0x08.
1036 Anysee device RC query returns only two bytes, status and code,
1037 address byte is dropped. Also it does not return any value for
1038 NEC RCs having address byte other than 0x08. Due to that, we
1039 cannot use that device as standard NEC receiver.
1040 It could be possible make hack which reads whole code directly
1041 from device memory... */
1042
1043 ret = anysee_ctrl_msg(d, buf, sizeof(buf), ircode, sizeof(ircode));
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001044 if (ret)
1045 return ret;
1046
Antti Palosaaria8494682010-10-17 18:25:10 -03001047 if (ircode[0]) {
1048 deb_rc("%s: key pressed %02x\n", __func__, ircode[1]);
Mauro Carvalho Chehabca866742010-11-17 13:53:11 -03001049 rc_keydown(d->rc_dev, 0x08 << 8 | ircode[1], 0);
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001050 }
Antti Palosaaria8494682010-10-17 18:25:10 -03001051
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001052 return 0;
1053}
1054
Antti Palosaari05cd37d2011-09-05 23:33:04 -03001055static int anysee_ci_read_attribute_mem(struct dvb_ca_en50221 *ci, int slot,
1056 int addr)
1057{
1058 struct dvb_usb_device *d = ci->data;
1059 int ret;
1060 u8 buf[] = {CMD_CI, 0x02, 0x40 | addr >> 8, addr & 0xff, 0x00, 1};
1061 u8 val;
1062
1063 ret = anysee_ctrl_msg(d, buf, sizeof(buf), &val, 1);
1064 if (ret)
1065 return ret;
1066
1067 return val;
1068}
1069
1070static int anysee_ci_write_attribute_mem(struct dvb_ca_en50221 *ci, int slot,
1071 int addr, u8 val)
1072{
1073 struct dvb_usb_device *d = ci->data;
1074 int ret;
1075 u8 buf[] = {CMD_CI, 0x03, 0x40 | addr >> 8, addr & 0xff, 0x00, 1, val};
1076
1077 ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
1078 if (ret)
1079 return ret;
1080
1081 return 0;
1082}
1083
1084static int anysee_ci_read_cam_control(struct dvb_ca_en50221 *ci, int slot,
1085 u8 addr)
1086{
1087 struct dvb_usb_device *d = ci->data;
1088 int ret;
1089 u8 buf[] = {CMD_CI, 0x04, 0x40, addr, 0x00, 1};
1090 u8 val;
1091
1092 ret = anysee_ctrl_msg(d, buf, sizeof(buf), &val, 1);
1093 if (ret)
1094 return ret;
1095
1096 return val;
1097}
1098
1099static int anysee_ci_write_cam_control(struct dvb_ca_en50221 *ci, int slot,
1100 u8 addr, u8 val)
1101{
1102 struct dvb_usb_device *d = ci->data;
1103 int ret;
1104 u8 buf[] = {CMD_CI, 0x05, 0x40, addr, 0x00, 1, val};
1105
1106 ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
1107 if (ret)
1108 return ret;
1109
1110 return 0;
1111}
1112
1113static int anysee_ci_slot_reset(struct dvb_ca_en50221 *ci, int slot)
1114{
1115 struct dvb_usb_device *d = ci->data;
1116 int ret;
1117 struct anysee_state *state = d->priv;
1118
1119 state->ci_cam_ready = jiffies + msecs_to_jiffies(1000);
1120
1121 ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80);
1122 if (ret)
1123 return ret;
1124
1125 msleep(300);
1126
1127 ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
1128 if (ret)
1129 return ret;
1130
1131 return 0;
1132}
1133
1134static int anysee_ci_slot_shutdown(struct dvb_ca_en50221 *ci, int slot)
1135{
1136 struct dvb_usb_device *d = ci->data;
1137 int ret;
1138
1139 ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80);
1140 if (ret)
1141 return ret;
1142
1143 msleep(30);
1144
1145 ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
1146 if (ret)
1147 return ret;
1148
1149 return 0;
1150}
1151
1152static int anysee_ci_slot_ts_enable(struct dvb_ca_en50221 *ci, int slot)
1153{
1154 struct dvb_usb_device *d = ci->data;
1155 int ret;
1156
1157 ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 1), 0x02);
1158 if (ret)
1159 return ret;
1160
1161 return 0;
1162}
1163
1164static int anysee_ci_poll_slot_status(struct dvb_ca_en50221 *ci, int slot,
1165 int open)
1166{
1167 struct dvb_usb_device *d = ci->data;
1168 struct anysee_state *state = d->priv;
1169 int ret;
1170 u8 tmp;
1171
1172 ret = anysee_rd_reg_mask(d, REG_IOC, &tmp, 0x40);
1173 if (ret)
1174 return ret;
1175
1176 if (tmp == 0) {
1177 ret = DVB_CA_EN50221_POLL_CAM_PRESENT;
1178 if (time_after(jiffies, state->ci_cam_ready))
1179 ret |= DVB_CA_EN50221_POLL_CAM_READY;
1180 }
1181
1182 return ret;
1183}
1184
1185static int anysee_ci_init(struct dvb_usb_device *d)
1186{
1187 struct anysee_state *state = d->priv;
1188 int ret;
1189
1190 state->ci.owner = THIS_MODULE;
1191 state->ci.read_attribute_mem = anysee_ci_read_attribute_mem;
1192 state->ci.write_attribute_mem = anysee_ci_write_attribute_mem;
1193 state->ci.read_cam_control = anysee_ci_read_cam_control;
1194 state->ci.write_cam_control = anysee_ci_write_cam_control;
1195 state->ci.slot_reset = anysee_ci_slot_reset;
1196 state->ci.slot_shutdown = anysee_ci_slot_shutdown;
1197 state->ci.slot_ts_enable = anysee_ci_slot_ts_enable;
1198 state->ci.poll_slot_status = anysee_ci_poll_slot_status;
1199 state->ci.data = d;
1200
1201 ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
1202 if (ret)
1203 return ret;
1204
1205 ret = dvb_ca_en50221_init(&d->adapter[0].dvb_adap, &state->ci, 0, 1);
1206 if (ret)
1207 return ret;
1208
1209 return 0;
1210}
1211
1212static void anysee_ci_release(struct dvb_usb_device *d)
1213{
1214 struct anysee_state *state = d->priv;
1215
1216 /* detach CI */
1217 if (state->has_ci)
1218 dvb_ca_en50221_release(&state->ci);
1219
1220 return;
1221}
1222
1223static int anysee_init(struct dvb_usb_device *d)
1224{
1225 struct anysee_state *state = d->priv;
1226 int ret;
1227
1228 /* LED light */
1229 ret = anysee_led_ctrl(d, 0x01, 0x03);
1230 if (ret)
1231 return ret;
1232
1233 /* enable IR */
1234 ret = anysee_ir_ctrl(d, 1);
1235 if (ret)
1236 return ret;
1237
1238 /* attach CI */
1239 if (state->has_ci) {
1240 ret = anysee_ci_init(d);
1241 if (ret) {
1242 state->has_ci = false;
1243 return ret;
1244 }
1245 }
1246
1247 return 0;
1248}
1249
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001250/* DVB USB Driver stuff */
1251static struct dvb_usb_device_properties anysee_properties;
1252
1253static int anysee_probe(struct usb_interface *intf,
1254 const struct usb_device_id *id)
1255{
1256 struct dvb_usb_device *d;
1257 struct usb_host_interface *alt;
1258 int ret;
1259
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001260 /* There is one interface with two alternate settings.
1261 Alternate setting 0 is for bulk transfer.
1262 Alternate setting 1 is for isochronous transfer.
1263 We use bulk transfer (alternate setting 0). */
1264 if (intf->num_altsetting < 1)
1265 return -ENODEV;
1266
Dan Carpenter8b0d7042010-05-31 16:27:39 -03001267 /*
1268 * Anysee is always warm (its USB-bridge, Cypress FX2, uploads
1269 * firmware from eeprom). If dvb_usb_device_init() succeeds that
1270 * means d is a valid pointer.
1271 */
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001272 ret = dvb_usb_device_init(intf, &anysee_properties, THIS_MODULE, &d,
1273 adapter_nr);
1274 if (ret)
1275 return ret;
1276
1277 alt = usb_altnum_to_altsetting(intf, 0);
1278 if (alt == NULL) {
1279 deb_info("%s: no alt found!\n", __func__);
1280 return -ENODEV;
1281 }
1282
1283 ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber,
1284 alt->desc.bAlternateSetting);
1285 if (ret)
1286 return ret;
1287
Dan Carpenter8b0d7042010-05-31 16:27:39 -03001288 return anysee_init(d);
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001289}
1290
Antti Palosaari05cd37d2011-09-05 23:33:04 -03001291static void anysee_disconnect(struct usb_interface *intf)
1292{
1293 struct dvb_usb_device *d = usb_get_intfdata(intf);
1294
1295 anysee_ci_release(d);
1296 dvb_usb_device_exit(intf);
1297
1298 return;
1299}
1300
Antti Palosaariae3745f2009-09-16 19:50:25 -03001301static struct usb_device_id anysee_table[] = {
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001302 { USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE) },
1303 { USB_DEVICE(USB_VID_AMT, USB_PID_ANYSEE) },
1304 { } /* Terminating entry */
1305};
1306MODULE_DEVICE_TABLE(usb, anysee_table);
1307
1308static struct dvb_usb_device_properties anysee_properties = {
1309 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1310
1311 .usb_ctrl = DEVICE_SPECIFIC,
1312
1313 .size_of_priv = sizeof(struct anysee_state),
1314
1315 .num_adapters = 1,
1316 .adapter = {
1317 {
Michael Krufky77eed212011-09-06 09:31:57 -03001318 .num_frontends = 2,
1319 .frontend_ctrl = anysee_frontend_ctrl,
Antti Palosaari8f4ffb12011-09-29 20:36:33 -03001320 .fe = { {
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001321 .streaming_ctrl = anysee_streaming_ctrl,
1322 .frontend_attach = anysee_frontend_attach,
1323 .tuner_attach = anysee_tuner_attach,
1324 .stream = {
1325 .type = USB_BULK,
1326 .count = 8,
1327 .endpoint = 0x82,
1328 .u = {
1329 .bulk = {
Antti Palosaariab693332009-09-16 19:47:01 -03001330 .buffersize = (16*512),
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001331 }
1332 }
1333 },
Michael Krufky77eed212011-09-06 09:31:57 -03001334 }, {
1335 .streaming_ctrl = anysee_streaming_ctrl,
1336 .frontend_attach = anysee_frontend_attach,
1337 .tuner_attach = anysee_tuner_attach,
1338 .stream = {
1339 .type = USB_BULK,
1340 .count = 8,
1341 .endpoint = 0x82,
1342 .u = {
1343 .bulk = {
1344 .buffersize = (16*512),
1345 }
1346 }
1347 },
Antti Palosaari8f4ffb12011-09-29 20:36:33 -03001348 } },
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001349 }
1350 },
1351
Antti Palosaaria8494682010-10-17 18:25:10 -03001352 .rc.core = {
1353 .rc_codes = RC_MAP_ANYSEE,
Mauro Carvalho Chehab52b66142010-11-17 14:20:52 -03001354 .protocol = RC_TYPE_OTHER,
Antti Palosaaria8494682010-10-17 18:25:10 -03001355 .module_name = "anysee",
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001356 .rc_query = anysee_rc_query,
Antti Palosaaria8494682010-10-17 18:25:10 -03001357 .rc_interval = 250, /* windows driver uses 500ms */
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001358 },
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001359
1360 .i2c_algo = &anysee_i2c_algo,
1361
1362 .generic_bulk_ctrl_endpoint = 1,
1363
1364 .num_device_descs = 1,
1365 .devices = {
1366 {
1367 .name = "Anysee DVB USB2.0",
1368 .cold_ids = {NULL},
1369 .warm_ids = {&anysee_table[0],
1370 &anysee_table[1], NULL},
1371 },
1372 }
1373};
1374
1375static struct usb_driver anysee_driver = {
1376 .name = "dvb_usb_anysee",
1377 .probe = anysee_probe,
Antti Palosaari05cd37d2011-09-05 23:33:04 -03001378 .disconnect = anysee_disconnect,
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001379 .id_table = anysee_table,
1380};
1381
1382/* module stuff */
1383static int __init anysee_module_init(void)
1384{
1385 int ret;
1386
1387 ret = usb_register(&anysee_driver);
1388 if (ret)
1389 err("%s: usb_register failed. Error number %d", __func__, ret);
1390
1391 return ret;
1392}
1393
1394static void __exit anysee_module_exit(void)
1395{
1396 /* deregister this driver from the USB subsystem */
1397 usb_deregister(&anysee_driver);
1398}
1399
1400module_init(anysee_module_init);
1401module_exit(anysee_module_exit);
1402
1403MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
1404MODULE_DESCRIPTION("Driver Anysee E30 DVB-C & DVB-T USB2.0");
1405MODULE_LICENSE("GPL");