blob: ecc3addc77ec1c54230a5ccbe8c7ec0463995915 [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,
Antti Palosaari608add82011-08-12 18:29:46 -0300369};
370
Antti Palosaari41f81f62011-04-10 17:53:52 -0300371/*
372 * New USB device strings: Mfr=1, Product=2, SerialNumber=0
373 * Manufacturer: AMT.CO.KR
374 *
375 * E30 VID=04b4 PID=861f HW=2 FW=2.1 Product=????????
376 * PCB: ?
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300377 * parts: DNOS404ZH102A(MT352, DTT7579(?))
Antti Palosaari41f81f62011-04-10 17:53:52 -0300378 *
Antti Palosaari05c46c02011-05-25 18:30:09 -0300379 * E30 VID=04b4 PID=861f HW=2 FW=2.1 "anysee-T(LP)"
380 * PCB: PCB 507T (rev1.61)
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300381 * parts: DNOS404ZH103A(ZL10353, DTT7579(?))
Antti Palosaari05c46c02011-05-25 18:30:09 -0300382 * OEA=0a OEB=00 OEC=00 OED=ff OEE=00
383 * IOA=45 IOB=ff IOC=00 IOD=ff IOE=00
Antti Palosaari41f81f62011-04-10 17:53:52 -0300384 *
385 * E30 Plus VID=04b4 PID=861f HW=6 FW=1.0 "anysee"
386 * PCB: 507CD (rev1.1)
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300387 * parts: DNOS404ZH103A(ZL10353, DTT7579(?)), CST56I01
Antti Palosaari05c46c02011-05-25 18:30:09 -0300388 * OEA=80 OEB=00 OEC=00 OED=ff OEE=fe
389 * IOA=4f IOB=ff IOC=00 IOD=06 IOE=01
Antti Palosaari41f81f62011-04-10 17:53:52 -0300390 * IOD[0] ZL10353 1=enabled
391 * IOA[7] TS 0=enabled
392 * tuner is not behind ZL10353 I2C-gate (no care if gate disabled or not)
393 *
394 * E30 C Plus VID=04b4 PID=861f HW=10 FW=1.0 "anysee-DC(LP)"
395 * PCB: 507DC (rev0.2)
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300396 * parts: TDA10023, DTOS403IH102B TM, CST56I01
Antti Palosaari05c46c02011-05-25 18:30:09 -0300397 * OEA=80 OEB=00 OEC=00 OED=ff OEE=fe
398 * IOA=4f IOB=ff IOC=00 IOD=26 IOE=01
Antti Palosaari41f81f62011-04-10 17:53:52 -0300399 * IOD[0] TDA10023 1=enabled
400 *
Antti Palosaarif0a53102011-04-27 21:11:59 -0300401 * E30 S2 Plus VID=04b4 PID=861f HW=11 FW=0.1 "anysee-S2(LP)"
402 * PCB: 507SI (rev2.1)
403 * parts: BS2N10WCC01(CX24116, CX24118), ISL6423, TDA8024
Antti Palosaari05c46c02011-05-25 18:30:09 -0300404 * OEA=80 OEB=00 OEC=ff OED=ff OEE=fe
405 * IOA=4d IOB=ff IOC=00 IOD=26 IOE=01
Antti Palosaarif0a53102011-04-27 21:11:59 -0300406 * IOD[0] CX24116 1=enabled
407 *
Antti Palosaari41f81f62011-04-10 17:53:52 -0300408 * E30 C Plus VID=1c73 PID=861f HW=15 FW=1.2 "anysee-FA(LP)"
409 * PCB: 507FA (rev0.4)
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300410 * parts: TDA10023, DTOS403IH102B TM, TDA8024
Antti Palosaari05c46c02011-05-25 18:30:09 -0300411 * OEA=80 OEB=00 OEC=ff OED=ff OEE=ff
412 * IOA=4d IOB=ff IOC=00 IOD=00 IOE=c0
Antti Palosaari41f81f62011-04-10 17:53:52 -0300413 * IOD[5] TDA10023 1=enabled
414 * IOE[0] tuner 1=enabled
415 *
416 * E30 Combo Plus VID=1c73 PID=861f HW=15 FW=1.2 "anysee-FA(LP)"
417 * PCB: 507FA (rev1.1)
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300418 * parts: ZL10353, TDA10023, DTOS403IH102B TM, TDA8024
Antti Palosaari05c46c02011-05-25 18:30:09 -0300419 * OEA=80 OEB=00 OEC=ff OED=ff OEE=ff
420 * IOA=4d IOB=ff IOC=00 IOD=00 IOE=c0
Antti Palosaari41f81f62011-04-10 17:53:52 -0300421 * DVB-C:
422 * IOD[5] TDA10023 1=enabled
423 * IOE[0] tuner 1=enabled
424 * DVB-T:
425 * IOD[0] ZL10353 1=enabled
426 * IOE[0] tuner 0=enabled
427 * tuner is behind ZL10353 I2C-gate
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300428 *
429 * E7 TC VID=1c73 PID=861f HW=18 FW=0.7 AMTCI=0.5 "anysee-E7TC(LP)"
430 * PCB: 508TC (rev0.6)
431 * parts: ZL10353, TDA10023, DNOD44CDH086A(TDA18212)
Antti Palosaari05c46c02011-05-25 18:30:09 -0300432 * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
433 * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300434 * IOA[7] TS 1=enabled
435 * IOE[4] TDA18212 1=enabled
436 * DVB-C:
437 * IOD[6] ZL10353 0=disabled
438 * IOD[5] TDA10023 1=enabled
439 * IOE[0] IF 1=enabled
440 * DVB-T:
441 * IOD[5] TDA10023 0=disabled
442 * IOD[6] ZL10353 1=enabled
443 * IOE[0] IF 0=enabled
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300444 *
445 * E7 S2 VID=1c73 PID=861f HW=19 FW=0.4 AMTCI=0.5 "anysee-E7S2(LP)"
446 * PCB: 508S2 (rev0.7)
447 * parts: DNBU10512IST(STV0903, STV6110), ISL6423
Antti Palosaari05c46c02011-05-25 18:30:09 -0300448 * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
449 * IOA=4d IOB=00 IOC=c4 IOD=08 IOE=e4
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300450 * IOA[7] TS 1=enabled
451 * IOE[5] STV0903 1=enabled
452 *
Antti Palosaari608add82011-08-12 18:29:46 -0300453 * E7 T2C VID=1c73 PID=861f HW=20 FW=0.1 AMTCI=0.5 "anysee-E7T2C(LP)"
454 * PCB: 508T2C (rev0.3)
455 * parts: DNOQ44QCH106A(CXD2820R, TDA18212), TDA8024
456 * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
457 * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4
458 * IOA[7] TS 1=enabled
459 * IOE[5] CXD2820R 1=enabled
460 *
Antti Palosaari8439e0d2011-05-24 07:57:34 -0300461 * E7 PTC VID=1c73 PID=861f HW=21 FW=0.1 AMTCI=?? "anysee-E7PTC(LP)"
462 * PCB: 508PTC (rev0.5)
463 * parts: ZL10353, TDA10023, DNOD44CDH086A(TDA18212)
464 * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
465 * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4
466 * IOA[7] TS 1=enabled
467 * IOE[4] TDA18212 1=enabled
468 * DVB-C:
469 * IOD[6] ZL10353 0=disabled
470 * IOD[5] TDA10023 1=enabled
471 * IOE[0] IF 1=enabled
472 * DVB-T:
473 * IOD[5] TDA10023 0=disabled
474 * IOD[6] ZL10353 1=enabled
475 * IOE[0] IF 0=enabled
Antti Palosaarifea3c392011-05-25 18:21:43 -0300476 *
Antti Palosaari608add82011-08-12 18:29:46 -0300477 * E7 PS2 VID=1c73 PID=861f HW=22 FW=0.1 AMTCI=?? "anysee-E7PS2(LP)"
Antti Palosaarifea3c392011-05-25 18:21:43 -0300478 * PCB: 508PS2 (rev0.4)
479 * parts: DNBU10512IST(STV0903, STV6110), ISL6423
480 * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
481 * IOA=4d IOB=00 IOC=c4 IOD=08 IOE=e4
482 * IOA[7] TS 1=enabled
483 * IOE[5] STV0903 1=enabled
Antti Palosaari41f81f62011-04-10 17:53:52 -0300484 */
485
Antti Palosaaribe943512011-09-05 22:10:05 -0300486
487/* external I2C gate used for DNOD44CDH086A(TDA18212) tuner module */
488static int anysee_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
489{
490 struct dvb_usb_adapter *adap = fe->dvb->priv;
491
492 /* enable / disable tuner access on IOE[4] */
493 return anysee_wr_reg_mask(adap->dev, REG_IOE, (enable << 4), 0x10);
494}
495
Antti Palosaari449d1a02011-07-25 20:25:21 -0300496static int anysee_frontend_ctrl(struct dvb_frontend *fe, int onoff)
497{
498 struct dvb_usb_adapter *adap = fe->dvb->priv;
499 struct anysee_state *state = adap->dev->priv;
500 int ret;
501
502 deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
503
504 /* no frontend sleep control */
505 if (onoff == 0)
506 return 0;
507
508 switch (state->hw) {
509 case ANYSEE_HW_507FA: /* 15 */
510 /* E30 Combo Plus */
511 /* E30 C Plus */
512
513 if ((fe->id ^ dvb_usb_anysee_delsys) == 0) {
514 /* disable DVB-T demod on IOD[0] */
515 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 0),
516 0x01);
517 if (ret)
518 goto error;
519
520 /* enable DVB-C demod on IOD[5] */
521 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5),
522 0x20);
523 if (ret)
524 goto error;
525
526 /* enable DVB-C tuner on IOE[0] */
527 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 0),
528 0x01);
529 if (ret)
530 goto error;
531 } else {
532 /* disable DVB-C demod on IOD[5] */
533 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5),
534 0x20);
535 if (ret)
536 goto error;
537
538 /* enable DVB-T demod on IOD[0] */
539 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0),
540 0x01);
541 if (ret)
542 goto error;
543
544 /* enable DVB-T tuner on IOE[0] */
545 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 0),
546 0x01);
547 if (ret)
548 goto error;
549 }
550
551 break;
552 case ANYSEE_HW_508TC: /* 18 */
553 case ANYSEE_HW_508PTC: /* 21 */
554 /* E7 TC */
555 /* E7 PTC */
556
557 if ((fe->id ^ dvb_usb_anysee_delsys) == 0) {
558 /* disable DVB-T demod on IOD[6] */
559 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 6),
560 0x40);
561 if (ret)
562 goto error;
563
564 /* enable DVB-C demod on IOD[5] */
565 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5),
566 0x20);
567 if (ret)
568 goto error;
569
570 /* enable IF route on IOE[0] */
571 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 0),
572 0x01);
573 if (ret)
574 goto error;
575 } else {
576 /* disable DVB-C demod on IOD[5] */
577 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5),
578 0x20);
579 if (ret)
580 goto error;
581
582 /* enable DVB-T demod on IOD[6] */
583 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 6),
584 0x40);
585 if (ret)
586 goto error;
587
588 /* enable IF route on IOE[0] */
589 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 0),
590 0x01);
591 if (ret)
592 goto error;
593 }
594
595 break;
596 default:
597 ret = 0;
598 }
599
600error:
601 return ret;
602}
603
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300604static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
605{
606 int ret;
607 struct anysee_state *state = adap->dev->priv;
608 u8 hw_info[3];
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300609 u8 tmp;
610 struct i2c_msg msg[2] = {
611 {
612 .addr = anysee_tda18212_config.i2c_address,
613 .flags = 0,
614 .len = 1,
615 .buf = "\x00",
616 }, {
617 .addr = anysee_tda18212_config.i2c_address,
618 .flags = I2C_M_RD,
619 .len = 1,
620 .buf = &tmp,
621 }
622 };
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300623
Antti Palosaari449d1a02011-07-25 20:25:21 -0300624 /* detect hardware only once */
Michael Krufky77eed212011-09-06 09:31:57 -0300625 if (adap->fe_adap[0].fe == NULL) {
Antti Palosaari449d1a02011-07-25 20:25:21 -0300626 /* Check which hardware we have.
Antti Palosaari8f4ffb12011-09-29 20:36:33 -0300627 * We must do this call two times to get reliable values
628 * (hw/fw bug).
Antti Palosaari449d1a02011-07-25 20:25:21 -0300629 */
630 ret = anysee_get_hw_info(adap->dev, hw_info);
631 if (ret)
632 goto error;
Antti Palosaari41f81f62011-04-10 17:53:52 -0300633
Antti Palosaari449d1a02011-07-25 20:25:21 -0300634 ret = anysee_get_hw_info(adap->dev, hw_info);
635 if (ret)
636 goto error;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300637
Antti Palosaari449d1a02011-07-25 20:25:21 -0300638 /* Meaning of these info bytes are guessed. */
639 info("firmware version:%d.%d hardware id:%d",
640 hw_info[1], hw_info[2], hw_info[0]);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300641
Antti Palosaari449d1a02011-07-25 20:25:21 -0300642 state->hw = hw_info[0];
643 }
644
645 /* set current frondend ID for devices having two frondends */
Michael Krufky77eed212011-09-06 09:31:57 -0300646 if (adap->fe_adap[0].fe)
Antti Palosaari449d1a02011-07-25 20:25:21 -0300647 state->fe_id++;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300648
Antti Palosaari41f81f62011-04-10 17:53:52 -0300649 switch (state->hw) {
Antti Palosaari05c46c02011-05-25 18:30:09 -0300650 case ANYSEE_HW_507T: /* 2 */
Antti Palosaari41f81f62011-04-10 17:53:52 -0300651 /* E30 */
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300652
Antti Palosaari449d1a02011-07-25 20:25:21 -0300653 if (state->fe_id)
654 break;
655
Antti Palosaari41f81f62011-04-10 17:53:52 -0300656 /* attach demod */
Antti Palosaari8f4ffb12011-09-29 20:36:33 -0300657 adap->fe_adap[0].fe = dvb_attach(mt352_attach,
658 &anysee_mt352_config, &adap->dev->i2c_adap);
Michael Krufky77eed212011-09-06 09:31:57 -0300659 if (adap->fe_adap[0].fe)
Antti Palosaari41f81f62011-04-10 17:53:52 -0300660 break;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300661
Antti Palosaari41f81f62011-04-10 17:53:52 -0300662 /* attach demod */
Antti Palosaari8f4ffb12011-09-29 20:36:33 -0300663 adap->fe_adap[0].fe = dvb_attach(zl10353_attach,
664 &anysee_zl10353_config, &adap->dev->i2c_adap);
Antti Palosaari41f81f62011-04-10 17:53:52 -0300665
666 break;
667 case ANYSEE_HW_507CD: /* 6 */
668 /* E30 Plus */
669
Antti Palosaari449d1a02011-07-25 20:25:21 -0300670 if (state->fe_id)
671 break;
672
Antti Palosaari41f81f62011-04-10 17:53:52 -0300673 /* enable DVB-T demod on IOD[0] */
674 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01);
675 if (ret)
676 goto error;
677
678 /* enable transport stream on IOA[7] */
679 ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (0 << 7), 0x80);
680 if (ret)
681 goto error;
682
683 /* attach demod */
Michael Krufky77eed212011-09-06 09:31:57 -0300684 adap->fe_adap[0].fe = dvb_attach(zl10353_attach,
Antti Palosaari449d1a02011-07-25 20:25:21 -0300685 &anysee_zl10353_config, &adap->dev->i2c_adap);
Antti Palosaari41f81f62011-04-10 17:53:52 -0300686
687 break;
688 case ANYSEE_HW_507DC: /* 10 */
689 /* E30 C Plus */
690
Antti Palosaari449d1a02011-07-25 20:25:21 -0300691 if (state->fe_id)
692 break;
693
Antti Palosaari41f81f62011-04-10 17:53:52 -0300694 /* enable DVB-C demod on IOD[0] */
695 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01);
696 if (ret)
697 goto error;
698
699 /* attach demod */
Michael Krufky77eed212011-09-06 09:31:57 -0300700 adap->fe_adap[0].fe = dvb_attach(tda10023_attach,
Antti Palosaari449d1a02011-07-25 20:25:21 -0300701 &anysee_tda10023_config, &adap->dev->i2c_adap, 0x48);
Antti Palosaari41f81f62011-04-10 17:53:52 -0300702
703 break;
Antti Palosaarif0a53102011-04-27 21:11:59 -0300704 case ANYSEE_HW_507SI: /* 11 */
705 /* E30 S2 Plus */
706
Antti Palosaari449d1a02011-07-25 20:25:21 -0300707 if (state->fe_id)
708 break;
709
Antti Palosaarif0a53102011-04-27 21:11:59 -0300710 /* enable DVB-S/S2 demod on IOD[0] */
711 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01);
712 if (ret)
713 goto error;
714
715 /* attach demod */
Antti Palosaari8f4ffb12011-09-29 20:36:33 -0300716 adap->fe_adap[0].fe = dvb_attach(cx24116_attach,
717 &anysee_cx24116_config, &adap->dev->i2c_adap);
Antti Palosaarif0a53102011-04-27 21:11:59 -0300718
719 break;
Antti Palosaari41f81f62011-04-10 17:53:52 -0300720 case ANYSEE_HW_507FA: /* 15 */
721 /* E30 Combo Plus */
722 /* E30 C Plus */
723
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300724 /* enable tuner on IOE[4] */
725 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10);
726 if (ret)
727 goto error;
728
729 /* probe TDA18212 */
730 tmp = 0;
731 ret = i2c_transfer(&adap->dev->i2c_adap, msg, 2);
732 if (ret == 2 && tmp == 0xc7)
733 deb_info("%s: TDA18212 found\n", __func__);
734 else
735 tmp = 0;
736
737 /* disable tuner on IOE[4] */
738 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 4), 0x10);
739 if (ret)
740 goto error;
741
Antti Palosaari449d1a02011-07-25 20:25:21 -0300742 if ((state->fe_id ^ dvb_usb_anysee_delsys) == 0) {
Antti Palosaari41f81f62011-04-10 17:53:52 -0300743 /* disable DVB-T demod on IOD[0] */
744 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 0),
745 0x01);
746 if (ret)
747 goto error;
748
749 /* enable DVB-C demod on IOD[5] */
750 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5),
751 0x20);
752 if (ret)
753 goto error;
754
755 /* attach demod */
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300756 if (tmp == 0xc7) {
757 /* TDA18212 config */
Michael Krufky77eed212011-09-06 09:31:57 -0300758 adap->fe_adap[state->fe_id].fe = dvb_attach(
Antti Palosaari449d1a02011-07-25 20:25:21 -0300759 tda10023_attach,
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300760 &anysee_tda10023_tda18212_config,
761 &adap->dev->i2c_adap, 0x48);
762 } else {
763 /* PLL config */
Michael Krufky77eed212011-09-06 09:31:57 -0300764 adap->fe_adap[state->fe_id].fe = dvb_attach(
Antti Palosaari449d1a02011-07-25 20:25:21 -0300765 tda10023_attach,
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300766 &anysee_tda10023_config,
767 &adap->dev->i2c_adap, 0x48);
768 }
Antti Palosaari449d1a02011-07-25 20:25:21 -0300769 } else {
770 /* disable DVB-C demod on IOD[5] */
771 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5),
772 0x20);
773 if (ret)
774 goto error;
775
776 /* enable DVB-T demod on IOD[0] */
777 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0),
778 0x01);
779 if (ret)
780 goto error;
781
782 /* attach demod */
783 if (tmp == 0xc7) {
784 /* TDA18212 config */
Michael Krufky77eed212011-09-06 09:31:57 -0300785 adap->fe_adap[state->fe_id].fe = dvb_attach(
Antti Palosaari449d1a02011-07-25 20:25:21 -0300786 zl10353_attach,
787 &anysee_zl10353_tda18212_config2,
788 &adap->dev->i2c_adap);
789 } else {
790 /* PLL config */
Michael Krufky77eed212011-09-06 09:31:57 -0300791 adap->fe_adap[state->fe_id].fe = dvb_attach(
Antti Palosaari449d1a02011-07-25 20:25:21 -0300792 zl10353_attach,
793 &anysee_zl10353_config,
794 &adap->dev->i2c_adap);
795 }
Antti Palosaari0f77c3a2008-08-11 10:54:16 -0300796 }
Antti Palosaarie82eea72011-04-12 19:43:30 -0300797
Antti Palosaaribe943512011-09-05 22:10:05 -0300798 /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
799 if (tmp == 0xc7) {
800 if (adap->fe_adap[state->fe_id].fe)
801 adap->fe_adap[state->fe_id].fe->ops.i2c_gate_ctrl =
802 anysee_i2c_gate_ctrl;
803 }
804
Antti Palosaari41f81f62011-04-10 17:53:52 -0300805 break;
Antti Palosaaria43be982011-04-10 20:23:02 -0300806 case ANYSEE_HW_508TC: /* 18 */
Antti Palosaari8439e0d2011-05-24 07:57:34 -0300807 case ANYSEE_HW_508PTC: /* 21 */
Antti Palosaaria43be982011-04-10 20:23:02 -0300808 /* E7 TC */
Antti Palosaari8439e0d2011-05-24 07:57:34 -0300809 /* E7 PTC */
Antti Palosaaria43be982011-04-10 20:23:02 -0300810
Antti Palosaari449d1a02011-07-25 20:25:21 -0300811 if ((state->fe_id ^ dvb_usb_anysee_delsys) == 0) {
Antti Palosaaria43be982011-04-10 20:23:02 -0300812 /* disable DVB-T demod on IOD[6] */
813 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 6),
814 0x40);
815 if (ret)
816 goto error;
817
818 /* enable DVB-C demod on IOD[5] */
819 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5),
820 0x20);
821 if (ret)
822 goto error;
823
Antti Palosaari449d1a02011-07-25 20:25:21 -0300824 /* attach demod */
Antti Palosaari8f4ffb12011-09-29 20:36:33 -0300825 adap->fe_adap[state->fe_id].fe =
826 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 */
Antti Palosaari8f4ffb12011-09-29 20:36:33 -0300843 adap->fe_adap[state->fe_id].fe =
844 dvb_attach(zl10353_attach,
Antti Palosaari449d1a02011-07-25 20:25:21 -0300845 &anysee_zl10353_tda18212_config,
846 &adap->dev->i2c_adap);
Antti Palosaaria43be982011-04-10 20:23:02 -0300847 }
Antti Palosaarie82eea72011-04-12 19:43:30 -0300848
Antti Palosaaribe943512011-09-05 22:10:05 -0300849 /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
850 if (adap->fe_adap[state->fe_id].fe)
851 adap->fe_adap[state->fe_id].fe->ops.i2c_gate_ctrl =
852 anysee_i2c_gate_ctrl;
853
Antti Palosaari05cd37d2011-09-05 23:33:04 -0300854 state->has_ci = true;
855
Antti Palosaaria43be982011-04-10 20:23:02 -0300856 break;
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300857 case ANYSEE_HW_508S2: /* 19 */
Antti Palosaarifea3c392011-05-25 18:21:43 -0300858 case ANYSEE_HW_508PS2: /* 22 */
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300859 /* E7 S2 */
Antti Palosaarifea3c392011-05-25 18:21:43 -0300860 /* E7 PS2 */
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300861
Antti Palosaari449d1a02011-07-25 20:25:21 -0300862 if (state->fe_id)
863 break;
864
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300865 /* enable DVB-S/S2 demod on IOE[5] */
866 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20);
867 if (ret)
868 goto error;
869
870 /* attach demod */
Antti Palosaari8f4ffb12011-09-29 20:36:33 -0300871 adap->fe_adap[0].fe = dvb_attach(stv0900_attach,
872 &anysee_stv0900_config, &adap->dev->i2c_adap, 0);
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300873
Antti Palosaari05cd37d2011-09-05 23:33:04 -0300874 state->has_ci = true;
875
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300876 break;
Antti Palosaari608add82011-08-12 18:29:46 -0300877 case ANYSEE_HW_508T2C: /* 20 */
878 /* E7 T2C */
879
Antti Palosaarifaf27972012-01-15 14:20:50 -0300880 if (state->fe_id)
881 break;
882
Antti Palosaari608add82011-08-12 18:29:46 -0300883 /* enable DVB-T/T2/C demod on IOE[5] */
884 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20);
885 if (ret)
886 goto error;
887
Antti Palosaarifaf27972012-01-15 14:20:50 -0300888 /* attach demod */
889 adap->fe_adap[state->fe_id].fe = dvb_attach(cxd2820r_attach,
890 &anysee_cxd2820r_config, &adap->dev->i2c_adap,
891 NULL);
Antti Palosaari608add82011-08-12 18:29:46 -0300892
Antti Palosaari05cd37d2011-09-05 23:33:04 -0300893 state->has_ci = true;
894
Antti Palosaari608add82011-08-12 18:29:46 -0300895 break;
Antti Palosaari0f77c3a2008-08-11 10:54:16 -0300896 }
897
Michael Krufky77eed212011-09-06 09:31:57 -0300898 if (!adap->fe_adap[0].fe) {
Antti Palosaari41f81f62011-04-10 17:53:52 -0300899 /* we have no frontend :-( */
900 ret = -ENODEV;
Antti Palosaarie82eea72011-04-12 19:43:30 -0300901 err("Unsupported Anysee version. " \
902 "Please report the <linux-media@vger.kernel.org>.");
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300903 }
Antti Palosaari41f81f62011-04-10 17:53:52 -0300904error:
905 return ret;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300906}
907
908static int anysee_tuner_attach(struct dvb_usb_adapter *adap)
909{
910 struct anysee_state *state = adap->dev->priv;
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300911 struct dvb_frontend *fe;
Antti Palosaarie82eea72011-04-12 19:43:30 -0300912 int ret;
Antti Palosaari449d1a02011-07-25 20:25:21 -0300913 deb_info("%s: fe=%d\n", __func__, state->fe_id);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300914
Antti Palosaari41f81f62011-04-10 17:53:52 -0300915 switch (state->hw) {
Antti Palosaari05c46c02011-05-25 18:30:09 -0300916 case ANYSEE_HW_507T: /* 2 */
Antti Palosaari41f81f62011-04-10 17:53:52 -0300917 /* E30 */
918
919 /* attach tuner */
Antti Palosaari8f4ffb12011-09-29 20:36:33 -0300920 fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe,
921 (0xc2 >> 1), NULL, DVB_PLL_THOMSON_DTT7579);
Antti Palosaarie82eea72011-04-12 19:43:30 -0300922
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300923 break;
Antti Palosaari41f81f62011-04-10 17:53:52 -0300924 case ANYSEE_HW_507CD: /* 6 */
925 /* E30 Plus */
926
927 /* attach tuner */
Antti Palosaari8f4ffb12011-09-29 20:36:33 -0300928 fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe,
929 (0xc2 >> 1), &adap->dev->i2c_adap,
930 DVB_PLL_THOMSON_DTT7579);
Antti Palosaari41f81f62011-04-10 17:53:52 -0300931
932 break;
933 case ANYSEE_HW_507DC: /* 10 */
934 /* E30 C Plus */
935
936 /* attach tuner */
Antti Palosaari8f4ffb12011-09-29 20:36:33 -0300937 fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe,
938 (0xc0 >> 1), &adap->dev->i2c_adap,
939 DVB_PLL_SAMSUNG_DTOS403IH102A);
Antti Palosaarie82eea72011-04-12 19:43:30 -0300940
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300941 break;
Antti Palosaarif0a53102011-04-27 21:11:59 -0300942 case ANYSEE_HW_507SI: /* 11 */
943 /* E30 S2 Plus */
944
945 /* attach LNB controller */
Michael Krufky77eed212011-09-06 09:31:57 -0300946 fe = dvb_attach(isl6423_attach, adap->fe_adap[0].fe,
Antti Palosaari449d1a02011-07-25 20:25:21 -0300947 &adap->dev->i2c_adap, &anysee_isl6423_config);
Antti Palosaarif0a53102011-04-27 21:11:59 -0300948
949 break;
Antti Palosaari41f81f62011-04-10 17:53:52 -0300950 case ANYSEE_HW_507FA: /* 15 */
951 /* E30 Combo Plus */
952 /* E30 C Plus */
953
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300954 /* Try first attach TDA18212 silicon tuner on IOE[4], if that
955 * fails attach old simple PLL. */
956
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300957 /* attach tuner */
Michael Krufky77eed212011-09-06 09:31:57 -0300958 fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe,
Antti Palosaari449d1a02011-07-25 20:25:21 -0300959 &adap->dev->i2c_adap, &anysee_tda18212_config);
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300960 if (fe)
961 break;
962
Antti Palosaari41f81f62011-04-10 17:53:52 -0300963 /* attach tuner */
Michael Krufky77eed212011-09-06 09:31:57 -0300964 fe = dvb_attach(dvb_pll_attach, adap->fe_adap[state->fe_id].fe,
Antti Palosaari449d1a02011-07-25 20:25:21 -0300965 (0xc0 >> 1), &adap->dev->i2c_adap,
966 DVB_PLL_SAMSUNG_DTOS403IH102A);
Antti Palosaari41f81f62011-04-10 17:53:52 -0300967
968 break;
Antti Palosaaria43be982011-04-10 20:23:02 -0300969 case ANYSEE_HW_508TC: /* 18 */
Antti Palosaari8439e0d2011-05-24 07:57:34 -0300970 case ANYSEE_HW_508PTC: /* 21 */
Antti Palosaaria43be982011-04-10 20:23:02 -0300971 /* E7 TC */
Antti Palosaari8439e0d2011-05-24 07:57:34 -0300972 /* E7 PTC */
Antti Palosaaria43be982011-04-10 20:23:02 -0300973
Antti Palosaaria43be982011-04-10 20:23:02 -0300974 /* attach tuner */
Michael Krufky77eed212011-09-06 09:31:57 -0300975 fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe,
Antti Palosaari449d1a02011-07-25 20:25:21 -0300976 &adap->dev->i2c_adap, &anysee_tda18212_config);
Antti Palosaaria43be982011-04-10 20:23:02 -0300977
978 break;
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300979 case ANYSEE_HW_508S2: /* 19 */
Antti Palosaarifea3c392011-05-25 18:21:43 -0300980 case ANYSEE_HW_508PS2: /* 22 */
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300981 /* E7 S2 */
Antti Palosaarifea3c392011-05-25 18:21:43 -0300982 /* E7 PS2 */
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300983
984 /* attach tuner */
Michael Krufky77eed212011-09-06 09:31:57 -0300985 fe = dvb_attach(stv6110_attach, adap->fe_adap[0].fe,
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300986 &anysee_stv6110_config, &adap->dev->i2c_adap);
987
988 if (fe) {
989 /* attach LNB controller */
Michael Krufky77eed212011-09-06 09:31:57 -0300990 fe = dvb_attach(isl6423_attach, adap->fe_adap[0].fe,
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300991 &adap->dev->i2c_adap, &anysee_isl6423_config);
992 }
993
994 break;
Antti Palosaari608add82011-08-12 18:29:46 -0300995
996 case ANYSEE_HW_508T2C: /* 20 */
997 /* E7 T2C */
998
999 /* attach tuner */
Antti Palosaaribe943512011-09-05 22:10:05 -03001000 fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe,
Antti Palosaari608add82011-08-12 18:29:46 -03001001 &adap->dev->i2c_adap, &anysee_tda18212_config2);
1002
1003 break;
Antti Palosaari41f81f62011-04-10 17:53:52 -03001004 default:
Antti Palosaarie82eea72011-04-12 19:43:30 -03001005 fe = NULL;
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001006 }
1007
Antti Palosaarie82eea72011-04-12 19:43:30 -03001008 if (fe)
1009 ret = 0;
1010 else
1011 ret = -ENODEV;
1012
Antti Palosaari41f81f62011-04-10 17:53:52 -03001013 return ret;
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001014}
1015
Antti Palosaaria8494682010-10-17 18:25:10 -03001016static int anysee_rc_query(struct dvb_usb_device *d)
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001017{
1018 u8 buf[] = {CMD_GET_IR_CODE};
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001019 u8 ircode[2];
Antti Palosaaria8494682010-10-17 18:25:10 -03001020 int ret;
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001021
Antti Palosaaria8494682010-10-17 18:25:10 -03001022 /* Remote controller is basic NEC using address byte 0x08.
1023 Anysee device RC query returns only two bytes, status and code,
1024 address byte is dropped. Also it does not return any value for
1025 NEC RCs having address byte other than 0x08. Due to that, we
1026 cannot use that device as standard NEC receiver.
1027 It could be possible make hack which reads whole code directly
1028 from device memory... */
1029
1030 ret = anysee_ctrl_msg(d, buf, sizeof(buf), ircode, sizeof(ircode));
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001031 if (ret)
1032 return ret;
1033
Antti Palosaaria8494682010-10-17 18:25:10 -03001034 if (ircode[0]) {
1035 deb_rc("%s: key pressed %02x\n", __func__, ircode[1]);
Mauro Carvalho Chehabca866742010-11-17 13:53:11 -03001036 rc_keydown(d->rc_dev, 0x08 << 8 | ircode[1], 0);
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001037 }
Antti Palosaaria8494682010-10-17 18:25:10 -03001038
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001039 return 0;
1040}
1041
Antti Palosaari05cd37d2011-09-05 23:33:04 -03001042static int anysee_ci_read_attribute_mem(struct dvb_ca_en50221 *ci, int slot,
1043 int addr)
1044{
1045 struct dvb_usb_device *d = ci->data;
1046 int ret;
1047 u8 buf[] = {CMD_CI, 0x02, 0x40 | addr >> 8, addr & 0xff, 0x00, 1};
1048 u8 val;
1049
1050 ret = anysee_ctrl_msg(d, buf, sizeof(buf), &val, 1);
1051 if (ret)
1052 return ret;
1053
1054 return val;
1055}
1056
1057static int anysee_ci_write_attribute_mem(struct dvb_ca_en50221 *ci, int slot,
1058 int addr, u8 val)
1059{
1060 struct dvb_usb_device *d = ci->data;
1061 int ret;
1062 u8 buf[] = {CMD_CI, 0x03, 0x40 | addr >> 8, addr & 0xff, 0x00, 1, val};
1063
1064 ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
1065 if (ret)
1066 return ret;
1067
1068 return 0;
1069}
1070
1071static int anysee_ci_read_cam_control(struct dvb_ca_en50221 *ci, int slot,
1072 u8 addr)
1073{
1074 struct dvb_usb_device *d = ci->data;
1075 int ret;
1076 u8 buf[] = {CMD_CI, 0x04, 0x40, addr, 0x00, 1};
1077 u8 val;
1078
1079 ret = anysee_ctrl_msg(d, buf, sizeof(buf), &val, 1);
1080 if (ret)
1081 return ret;
1082
1083 return val;
1084}
1085
1086static int anysee_ci_write_cam_control(struct dvb_ca_en50221 *ci, int slot,
1087 u8 addr, u8 val)
1088{
1089 struct dvb_usb_device *d = ci->data;
1090 int ret;
1091 u8 buf[] = {CMD_CI, 0x05, 0x40, addr, 0x00, 1, val};
1092
1093 ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
1094 if (ret)
1095 return ret;
1096
1097 return 0;
1098}
1099
1100static int anysee_ci_slot_reset(struct dvb_ca_en50221 *ci, int slot)
1101{
1102 struct dvb_usb_device *d = ci->data;
1103 int ret;
1104 struct anysee_state *state = d->priv;
1105
1106 state->ci_cam_ready = jiffies + msecs_to_jiffies(1000);
1107
1108 ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80);
1109 if (ret)
1110 return ret;
1111
1112 msleep(300);
1113
1114 ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
1115 if (ret)
1116 return ret;
1117
1118 return 0;
1119}
1120
1121static int anysee_ci_slot_shutdown(struct dvb_ca_en50221 *ci, int slot)
1122{
1123 struct dvb_usb_device *d = ci->data;
1124 int ret;
1125
1126 ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80);
1127 if (ret)
1128 return ret;
1129
1130 msleep(30);
1131
1132 ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
1133 if (ret)
1134 return ret;
1135
1136 return 0;
1137}
1138
1139static int anysee_ci_slot_ts_enable(struct dvb_ca_en50221 *ci, int slot)
1140{
1141 struct dvb_usb_device *d = ci->data;
1142 int ret;
1143
1144 ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 1), 0x02);
1145 if (ret)
1146 return ret;
1147
1148 return 0;
1149}
1150
1151static int anysee_ci_poll_slot_status(struct dvb_ca_en50221 *ci, int slot,
1152 int open)
1153{
1154 struct dvb_usb_device *d = ci->data;
1155 struct anysee_state *state = d->priv;
1156 int ret;
1157 u8 tmp;
1158
1159 ret = anysee_rd_reg_mask(d, REG_IOC, &tmp, 0x40);
1160 if (ret)
1161 return ret;
1162
1163 if (tmp == 0) {
1164 ret = DVB_CA_EN50221_POLL_CAM_PRESENT;
1165 if (time_after(jiffies, state->ci_cam_ready))
1166 ret |= DVB_CA_EN50221_POLL_CAM_READY;
1167 }
1168
1169 return ret;
1170}
1171
1172static int anysee_ci_init(struct dvb_usb_device *d)
1173{
1174 struct anysee_state *state = d->priv;
1175 int ret;
1176
1177 state->ci.owner = THIS_MODULE;
1178 state->ci.read_attribute_mem = anysee_ci_read_attribute_mem;
1179 state->ci.write_attribute_mem = anysee_ci_write_attribute_mem;
1180 state->ci.read_cam_control = anysee_ci_read_cam_control;
1181 state->ci.write_cam_control = anysee_ci_write_cam_control;
1182 state->ci.slot_reset = anysee_ci_slot_reset;
1183 state->ci.slot_shutdown = anysee_ci_slot_shutdown;
1184 state->ci.slot_ts_enable = anysee_ci_slot_ts_enable;
1185 state->ci.poll_slot_status = anysee_ci_poll_slot_status;
1186 state->ci.data = d;
1187
1188 ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
1189 if (ret)
1190 return ret;
1191
1192 ret = dvb_ca_en50221_init(&d->adapter[0].dvb_adap, &state->ci, 0, 1);
1193 if (ret)
1194 return ret;
1195
1196 return 0;
1197}
1198
1199static void anysee_ci_release(struct dvb_usb_device *d)
1200{
1201 struct anysee_state *state = d->priv;
1202
1203 /* detach CI */
1204 if (state->has_ci)
1205 dvb_ca_en50221_release(&state->ci);
1206
1207 return;
1208}
1209
1210static int anysee_init(struct dvb_usb_device *d)
1211{
1212 struct anysee_state *state = d->priv;
1213 int ret;
1214
1215 /* LED light */
1216 ret = anysee_led_ctrl(d, 0x01, 0x03);
1217 if (ret)
1218 return ret;
1219
1220 /* enable IR */
1221 ret = anysee_ir_ctrl(d, 1);
1222 if (ret)
1223 return ret;
1224
1225 /* attach CI */
1226 if (state->has_ci) {
1227 ret = anysee_ci_init(d);
1228 if (ret) {
1229 state->has_ci = false;
1230 return ret;
1231 }
1232 }
1233
1234 return 0;
1235}
1236
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001237/* DVB USB Driver stuff */
1238static struct dvb_usb_device_properties anysee_properties;
1239
1240static int anysee_probe(struct usb_interface *intf,
1241 const struct usb_device_id *id)
1242{
1243 struct dvb_usb_device *d;
1244 struct usb_host_interface *alt;
1245 int ret;
1246
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001247 /* There is one interface with two alternate settings.
1248 Alternate setting 0 is for bulk transfer.
1249 Alternate setting 1 is for isochronous transfer.
1250 We use bulk transfer (alternate setting 0). */
1251 if (intf->num_altsetting < 1)
1252 return -ENODEV;
1253
Dan Carpenter8b0d7042010-05-31 16:27:39 -03001254 /*
1255 * Anysee is always warm (its USB-bridge, Cypress FX2, uploads
1256 * firmware from eeprom). If dvb_usb_device_init() succeeds that
1257 * means d is a valid pointer.
1258 */
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001259 ret = dvb_usb_device_init(intf, &anysee_properties, THIS_MODULE, &d,
1260 adapter_nr);
1261 if (ret)
1262 return ret;
1263
1264 alt = usb_altnum_to_altsetting(intf, 0);
1265 if (alt == NULL) {
1266 deb_info("%s: no alt found!\n", __func__);
1267 return -ENODEV;
1268 }
1269
1270 ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber,
1271 alt->desc.bAlternateSetting);
1272 if (ret)
1273 return ret;
1274
Dan Carpenter8b0d7042010-05-31 16:27:39 -03001275 return anysee_init(d);
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001276}
1277
Antti Palosaari05cd37d2011-09-05 23:33:04 -03001278static void anysee_disconnect(struct usb_interface *intf)
1279{
1280 struct dvb_usb_device *d = usb_get_intfdata(intf);
1281
1282 anysee_ci_release(d);
1283 dvb_usb_device_exit(intf);
1284
1285 return;
1286}
1287
Antti Palosaariae3745f2009-09-16 19:50:25 -03001288static struct usb_device_id anysee_table[] = {
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001289 { USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE) },
1290 { USB_DEVICE(USB_VID_AMT, USB_PID_ANYSEE) },
1291 { } /* Terminating entry */
1292};
1293MODULE_DEVICE_TABLE(usb, anysee_table);
1294
1295static struct dvb_usb_device_properties anysee_properties = {
1296 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1297
1298 .usb_ctrl = DEVICE_SPECIFIC,
1299
1300 .size_of_priv = sizeof(struct anysee_state),
1301
1302 .num_adapters = 1,
1303 .adapter = {
1304 {
Michael Krufky77eed212011-09-06 09:31:57 -03001305 .num_frontends = 2,
1306 .frontend_ctrl = anysee_frontend_ctrl,
Antti Palosaari8f4ffb12011-09-29 20:36:33 -03001307 .fe = { {
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001308 .streaming_ctrl = anysee_streaming_ctrl,
1309 .frontend_attach = anysee_frontend_attach,
1310 .tuner_attach = anysee_tuner_attach,
1311 .stream = {
1312 .type = USB_BULK,
1313 .count = 8,
1314 .endpoint = 0x82,
1315 .u = {
1316 .bulk = {
Antti Palosaariab693332009-09-16 19:47:01 -03001317 .buffersize = (16*512),
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001318 }
1319 }
1320 },
Michael Krufky77eed212011-09-06 09:31:57 -03001321 }, {
1322 .streaming_ctrl = anysee_streaming_ctrl,
1323 .frontend_attach = anysee_frontend_attach,
1324 .tuner_attach = anysee_tuner_attach,
1325 .stream = {
1326 .type = USB_BULK,
1327 .count = 8,
1328 .endpoint = 0x82,
1329 .u = {
1330 .bulk = {
1331 .buffersize = (16*512),
1332 }
1333 }
1334 },
Antti Palosaari8f4ffb12011-09-29 20:36:33 -03001335 } },
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001336 }
1337 },
1338
Antti Palosaaria8494682010-10-17 18:25:10 -03001339 .rc.core = {
1340 .rc_codes = RC_MAP_ANYSEE,
Mauro Carvalho Chehab52b66142010-11-17 14:20:52 -03001341 .protocol = RC_TYPE_OTHER,
Antti Palosaaria8494682010-10-17 18:25:10 -03001342 .module_name = "anysee",
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001343 .rc_query = anysee_rc_query,
Antti Palosaaria8494682010-10-17 18:25:10 -03001344 .rc_interval = 250, /* windows driver uses 500ms */
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001345 },
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001346
1347 .i2c_algo = &anysee_i2c_algo,
1348
1349 .generic_bulk_ctrl_endpoint = 1,
1350
1351 .num_device_descs = 1,
1352 .devices = {
1353 {
1354 .name = "Anysee DVB USB2.0",
1355 .cold_ids = {NULL},
1356 .warm_ids = {&anysee_table[0],
1357 &anysee_table[1], NULL},
1358 },
1359 }
1360};
1361
1362static struct usb_driver anysee_driver = {
1363 .name = "dvb_usb_anysee",
1364 .probe = anysee_probe,
Antti Palosaari05cd37d2011-09-05 23:33:04 -03001365 .disconnect = anysee_disconnect,
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001366 .id_table = anysee_table,
1367};
1368
1369/* module stuff */
1370static int __init anysee_module_init(void)
1371{
1372 int ret;
1373
1374 ret = usb_register(&anysee_driver);
1375 if (ret)
1376 err("%s: usb_register failed. Error number %d", __func__, ret);
1377
1378 return ret;
1379}
1380
1381static void __exit anysee_module_exit(void)
1382{
1383 /* deregister this driver from the USB subsystem */
1384 usb_deregister(&anysee_driver);
1385}
1386
1387module_init(anysee_module_init);
1388module_exit(anysee_module_exit);
1389
1390MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
1391MODULE_DESCRIPTION("Driver Anysee E30 DVB-C & DVB-T USB2.0");
1392MODULE_LICENSE("GPL");