blob: ae917c042a52e7737a74e536328906014dbe34aa [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"
Antti Palosaaria4e7c512012-06-14 04:56:09 -030035#include "dvb-pll.h"
Antti Palosaaria51e34d2008-05-17 23:05:48 -030036#include "tda1002x.h"
37#include "mt352.h"
38#include "mt352_priv.h"
39#include "zl10353.h"
Antti Palosaari72ffd2b2011-04-10 20:14:50 -030040#include "tda18212.h"
Antti Palosaarif0a53102011-04-27 21:11:59 -030041#include "cx24116.h"
Antti Palosaaribedbf3d2011-04-29 13:55:02 -030042#include "stv0900.h"
43#include "stv6110.h"
Antti Palosaarif0a53102011-04-27 21:11:59 -030044#include "isl6423.h"
Antti Palosaari608add82011-08-12 18:29:46 -030045#include "cxd2820r.h"
Antti Palosaaria51e34d2008-05-17 23:05:48 -030046
Antti Palosaaria51e34d2008-05-17 23:05:48 -030047DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
Antti Palosaaria51e34d2008-05-17 23:05:48 -030048
Antti Palosaari4458a54c2013-02-26 14:18:13 -030049static int anysee_ctrl_msg(struct dvb_usb_device *d,
50 u8 *sbuf, u8 slen, u8 *rbuf, u8 rlen)
Antti Palosaaria51e34d2008-05-17 23:05:48 -030051{
Antti Palosaari05cd62e2012-06-18 19:39:02 -030052 struct anysee_state *state = d_to_priv(d);
Antti Palosaaricf427952012-01-21 11:19:29 -030053 int act_len, ret, i;
Antti Palosaaria51e34d2008-05-17 23:05:48 -030054
Antti Palosaari6c604e82013-02-26 14:13:41 -030055 mutex_lock(&d->usb_mutex);
Antti Palosaaria51e34d2008-05-17 23:05:48 -030056
Antti Palosaari6c604e82013-02-26 14:13:41 -030057 memcpy(&state->buf[0], sbuf, slen);
58 state->buf[60] = state->seq++;
Antti Palosaaria51e34d2008-05-17 23:05:48 -030059
Antti Palosaari6c604e82013-02-26 14:13:41 -030060 dev_dbg(&d->udev->dev, "%s: >>> %*ph\n", __func__, slen, state->buf);
Antti Palosaari4048da22011-09-29 20:28:53 -030061
Antti Palosaaria51e34d2008-05-17 23:05:48 -030062 /* We need receive one message more after dvb_usb_generic_rw due
63 to weird transaction flow, which is 1 x send + 2 x receive. */
Antti Palosaari6c604e82013-02-26 14:13:41 -030064 ret = dvb_usbv2_generic_rw_locked(d, state->buf, sizeof(state->buf),
65 state->buf, sizeof(state->buf));
Antti Palosaaricf427952012-01-21 11:19:29 -030066 if (ret)
67 goto error_unlock;
68
69 /* TODO FIXME: dvb_usb_generic_rw() fails rarely with error code -32
70 * (EPIPE, Broken pipe). Function supports currently msleep() as a
71 * parameter but I would not like to use it, since according to
72 * Documentation/timers/timers-howto.txt it should not be used such
73 * short, under < 20ms, sleeps. Repeating failed message would be
74 * better choice as not to add unwanted delays...
75 * Fixing that correctly is one of those or both;
76 * 1) use repeat if possible
77 * 2) add suitable delay
78 */
79
80 /* get answer, retry few times if error returned */
81 for (i = 0; i < 3; i++) {
Antti Palosaaria51e34d2008-05-17 23:05:48 -030082 /* receive 2nd answer */
83 ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev,
Antti Palosaari6c604e82013-02-26 14:13:41 -030084 d->props->generic_bulk_ctrl_endpoint),
85 state->buf, sizeof(state->buf), &act_len, 2000);
Antti Palosaaricf427952012-01-21 11:19:29 -030086 if (ret) {
Antti Palosaari4458a54c2013-02-26 14:18:13 -030087 dev_dbg(&d->udev->dev,
88 "%s: recv bulk message failed=%d\n",
89 __func__, ret);
Antti Palosaaricf427952012-01-21 11:19:29 -030090 } else {
Antti Palosaari82026f92012-08-14 15:56:20 -030091 dev_dbg(&d->udev->dev, "%s: <<< %*ph\n", __func__,
Antti Palosaari6c604e82013-02-26 14:13:41 -030092 rlen, state->buf);
Antti Palosaari4048da22011-09-29 20:28:53 -030093
Antti Palosaari6c604e82013-02-26 14:13:41 -030094 if (state->buf[63] != 0x4f)
Antti Palosaari4458a54c2013-02-26 14:18:13 -030095 dev_dbg(&d->udev->dev,
96 "%s: cmd failed\n", __func__);
Antti Palosaaricf427952012-01-21 11:19:29 -030097 break;
Antti Palosaaria51e34d2008-05-17 23:05:48 -030098 }
99 }
100
Antti Palosaaricf427952012-01-21 11:19:29 -0300101 if (ret) {
102 /* all retries failed, it is fatal */
Antti Palosaari82026f92012-08-14 15:56:20 -0300103 dev_err(&d->udev->dev, "%s: recv bulk message failed=%d\n",
104 KBUILD_MODNAME, ret);
Antti Palosaaricf427952012-01-21 11:19:29 -0300105 goto error_unlock;
106 }
107
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300108 /* read request, copy returned data to return buf */
Antti Palosaaricf427952012-01-21 11:19:29 -0300109 if (rbuf && rlen)
Antti Palosaari6c604e82013-02-26 14:13:41 -0300110 memcpy(rbuf, state->buf, rlen);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300111
Antti Palosaaricf427952012-01-21 11:19:29 -0300112error_unlock:
Antti Palosaari6c604e82013-02-26 14:13:41 -0300113 mutex_unlock(&d->usb_mutex);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300114 return ret;
115}
116
117static int anysee_read_reg(struct dvb_usb_device *d, u16 reg, u8 *val)
118{
119 u8 buf[] = {CMD_REG_READ, reg >> 8, reg & 0xff, 0x01};
120 int ret;
121 ret = anysee_ctrl_msg(d, buf, sizeof(buf), val, 1);
Antti Palosaari82026f92012-08-14 15:56:20 -0300122 dev_dbg(&d->udev->dev, "%s: reg=%04x val=%02x\n", __func__, reg, *val);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300123 return ret;
124}
125
126static int anysee_write_reg(struct dvb_usb_device *d, u16 reg, u8 val)
127{
128 u8 buf[] = {CMD_REG_WRITE, reg >> 8, reg & 0xff, 0x01, val};
Antti Palosaari82026f92012-08-14 15:56:20 -0300129 dev_dbg(&d->udev->dev, "%s: reg=%04x val=%02x\n", __func__, reg, val);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300130 return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
131}
132
Antti Palosaari41f81f62011-04-10 17:53:52 -0300133/* write single register with mask */
134static int anysee_wr_reg_mask(struct dvb_usb_device *d, u16 reg, u8 val,
135 u8 mask)
136{
137 int ret;
138 u8 tmp;
139
140 /* no need for read if whole reg is written */
141 if (mask != 0xff) {
142 ret = anysee_read_reg(d, reg, &tmp);
143 if (ret)
144 return ret;
145
146 val &= mask;
147 tmp &= ~mask;
148 val |= tmp;
149 }
150
151 return anysee_write_reg(d, reg, val);
152}
153
Antti Palosaari05cd37d2011-09-05 23:33:04 -0300154/* read single register with mask */
155static int anysee_rd_reg_mask(struct dvb_usb_device *d, u16 reg, u8 *val,
156 u8 mask)
157{
158 int ret, i;
159 u8 tmp;
160
161 ret = anysee_read_reg(d, reg, &tmp);
162 if (ret)
163 return ret;
164
165 tmp &= mask;
166
167 /* find position of the first bit */
168 for (i = 0; i < 8; i++) {
169 if ((mask >> i) & 0x01)
170 break;
171 }
172 *val = tmp >> i;
173
174 return 0;
175}
176
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300177static int anysee_get_hw_info(struct dvb_usb_device *d, u8 *id)
178{
179 u8 buf[] = {CMD_GET_HW_INFO};
180 return anysee_ctrl_msg(d, buf, sizeof(buf), id, 3);
181}
182
Antti Palosaaria13a6e12012-06-26 00:04:33 -0300183static int anysee_streaming_ctrl(struct dvb_frontend *fe, int onoff)
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300184{
185 u8 buf[] = {CMD_STREAMING_CTRL, (u8)onoff, 0x00};
Antti Palosaari82026f92012-08-14 15:56:20 -0300186 dev_dbg(&fe_to_d(fe)->udev->dev, "%s: onoff=%d\n", __func__, onoff);
Antti Palosaaria13a6e12012-06-26 00:04:33 -0300187 return anysee_ctrl_msg(fe_to_d(fe), buf, sizeof(buf), NULL, 0);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300188}
189
190static int anysee_led_ctrl(struct dvb_usb_device *d, u8 mode, u8 interval)
191{
192 u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x01, mode, interval};
Antti Palosaari82026f92012-08-14 15:56:20 -0300193 dev_dbg(&d->udev->dev, "%s: state=%d interval=%d\n", __func__,
194 mode, interval);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300195 return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
196}
197
198static int anysee_ir_ctrl(struct dvb_usb_device *d, u8 onoff)
199{
200 u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x02, onoff};
Antti Palosaari82026f92012-08-14 15:56:20 -0300201 dev_dbg(&d->udev->dev, "%s: onoff=%d\n", __func__, onoff);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300202 return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
203}
204
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300205/* I2C */
206static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
207 int num)
208{
209 struct dvb_usb_device *d = i2c_get_adapdata(adap);
Mauro Carvalho Chehab902571a2008-12-29 19:02:24 -0300210 int ret = 0, inc, i = 0;
Antti Palosaari21d2e932011-05-24 06:04:08 -0300211 u8 buf[52]; /* 4 + 48 (I2C WR USB command header + I2C WR max) */
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300212
213 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
214 return -EAGAIN;
215
216 while (i < num) {
217 if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
Antti Palosaari21d2e932011-05-24 06:04:08 -0300218 if (msg[i].len > 2 || msg[i+1].len > 60) {
219 ret = -EOPNOTSUPP;
220 break;
221 }
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300222 buf[0] = CMD_I2C_READ;
Antti Palosaari7ea03d22011-04-09 20:50:07 -0300223 buf[1] = (msg[i].addr << 1) | 0x01;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300224 buf[2] = msg[i].buf[0];
Antti Palosaari882b82c2011-04-12 19:49:25 -0300225 buf[3] = msg[i].buf[1];
226 buf[4] = msg[i].len-1;
Antti Palosaarib3e6a5a2011-04-09 21:00:51 -0300227 buf[5] = msg[i+1].len;
Antti Palosaari21d2e932011-05-24 06:04:08 -0300228 ret = anysee_ctrl_msg(d, buf, 6, msg[i+1].buf,
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300229 msg[i+1].len);
230 inc = 2;
231 } else {
Antti Palosaari21d2e932011-05-24 06:04:08 -0300232 if (msg[i].len > 48) {
233 ret = -EOPNOTSUPP;
234 break;
235 }
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300236 buf[0] = CMD_I2C_WRITE;
Antti Palosaari7ea03d22011-04-09 20:50:07 -0300237 buf[1] = (msg[i].addr << 1);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300238 buf[2] = msg[i].len;
239 buf[3] = 0x01;
240 memcpy(&buf[4], msg[i].buf, msg[i].len);
Antti Palosaari21d2e932011-05-24 06:04:08 -0300241 ret = anysee_ctrl_msg(d, buf, 4 + msg[i].len, NULL, 0);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300242 inc = 1;
243 }
244 if (ret)
Antti Palosaarie613f8f2008-08-11 10:36:43 -0300245 break;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300246
247 i += inc;
248 }
249
250 mutex_unlock(&d->i2c_mutex);
251
Antti Palosaarie613f8f2008-08-11 10:36:43 -0300252 return ret ? ret : i;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300253}
254
255static u32 anysee_i2c_func(struct i2c_adapter *adapter)
256{
257 return I2C_FUNC_I2C;
258}
259
260static struct i2c_algorithm anysee_i2c_algo = {
261 .master_xfer = anysee_master_xfer,
262 .functionality = anysee_i2c_func,
263};
264
265static int anysee_mt352_demod_init(struct dvb_frontend *fe)
266{
Antti Palosaariae3745f2009-09-16 19:50:25 -0300267 static u8 clock_config[] = { CLOCK_CTL, 0x38, 0x28 };
268 static u8 reset[] = { RESET, 0x80 };
269 static u8 adc_ctl_1_cfg[] = { ADC_CTL_1, 0x40 };
270 static u8 agc_cfg[] = { AGC_TARGET, 0x28, 0x20 };
271 static u8 gpp_ctl_cfg[] = { GPP_CTL, 0x33 };
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300272 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
273
274 mt352_write(fe, clock_config, sizeof(clock_config));
275 udelay(200);
276 mt352_write(fe, reset, sizeof(reset));
277 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
278
279 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
280 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
281 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
282
283 return 0;
284}
285
286/* Callbacks for DVB USB */
287static struct tda10023_config anysee_tda10023_config = {
Antti Palosaari7ea03d22011-04-09 20:50:07 -0300288 .demod_address = (0x1a >> 1),
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300289 .invert = 0,
290 .xtal = 16000000,
291 .pll_m = 11,
292 .pll_p = 3,
293 .pll_n = 1,
Antti Palosaari5ae2fca2008-06-09 22:58:22 -0300294 .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_C,
295 .deltaf = 0xfeeb,
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300296};
297
298static struct mt352_config anysee_mt352_config = {
Antti Palosaari7ea03d22011-04-09 20:50:07 -0300299 .demod_address = (0x1e >> 1),
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300300 .demod_init = anysee_mt352_demod_init,
301};
302
303static struct zl10353_config anysee_zl10353_config = {
Antti Palosaari7ea03d22011-04-09 20:50:07 -0300304 .demod_address = (0x1e >> 1),
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300305 .parallel_ts = 1,
306};
307
Antti Palosaari1fd80702011-04-12 17:34:08 -0300308static struct zl10353_config anysee_zl10353_tda18212_config2 = {
309 .demod_address = (0x1e >> 1),
310 .parallel_ts = 1,
311 .disable_i2c_gate_ctrl = 1,
312 .no_tuner = 1,
313 .if2 = 41500,
314};
315
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300316static struct zl10353_config anysee_zl10353_tda18212_config = {
317 .demod_address = (0x18 >> 1),
318 .parallel_ts = 1,
319 .disable_i2c_gate_ctrl = 1,
320 .no_tuner = 1,
321 .if2 = 41500,
322};
323
324static struct tda10023_config anysee_tda10023_tda18212_config = {
325 .demod_address = (0x1a >> 1),
326 .xtal = 16000000,
327 .pll_m = 12,
328 .pll_p = 3,
329 .pll_n = 1,
Antti Palosaari05cd37d2011-09-05 23:33:04 -0300330 .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_B,
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300331 .deltaf = 0xba02,
332};
333
334static struct tda18212_config anysee_tda18212_config = {
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300335 .if_dvbt_6 = 4150,
336 .if_dvbt_7 = 4150,
337 .if_dvbt_8 = 4150,
338 .if_dvbc = 5000,
339};
340
Antti Palosaari608add82011-08-12 18:29:46 -0300341static struct tda18212_config anysee_tda18212_config2 = {
Antti Palosaari608add82011-08-12 18:29:46 -0300342 .if_dvbt_6 = 3550,
343 .if_dvbt_7 = 3700,
344 .if_dvbt_8 = 4150,
345 .if_dvbt2_6 = 3250,
346 .if_dvbt2_7 = 4000,
347 .if_dvbt2_8 = 4000,
348 .if_dvbc = 5000,
349};
350
Antti Palosaarif0a53102011-04-27 21:11:59 -0300351static struct cx24116_config anysee_cx24116_config = {
352 .demod_address = (0xaa >> 1),
353 .mpg_clk_pos_pol = 0x00,
354 .i2c_wr_max = 48,
355};
356
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300357static struct stv0900_config anysee_stv0900_config = {
358 .demod_address = (0xd0 >> 1),
359 .demod_mode = 0,
360 .xtal = 8000000,
361 .clkmode = 3,
362 .diseqc_mode = 2,
363 .tun1_maddress = 0,
364 .tun1_adc = 1, /* 1 Vpp */
365 .path1_mode = 3,
366};
367
368static struct stv6110_config anysee_stv6110_config = {
369 .i2c_address = (0xc0 >> 1),
370 .mclk = 16000000,
371 .clk_div = 1,
372};
373
Antti Palosaarif0a53102011-04-27 21:11:59 -0300374static struct isl6423_config anysee_isl6423_config = {
375 .current_max = SEC_CURRENT_800m,
376 .curlim = SEC_CURRENT_LIM_OFF,
377 .mod_extern = 1,
378 .addr = (0x10 >> 1),
379};
380
Antti Palosaari608add82011-08-12 18:29:46 -0300381static struct cxd2820r_config anysee_cxd2820r_config = {
382 .i2c_address = 0x6d, /* (0xda >> 1) */
383 .ts_mode = 0x38,
Antti Palosaari608add82011-08-12 18:29:46 -0300384};
385
Antti Palosaari41f81f62011-04-10 17:53:52 -0300386/*
387 * New USB device strings: Mfr=1, Product=2, SerialNumber=0
388 * Manufacturer: AMT.CO.KR
389 *
390 * E30 VID=04b4 PID=861f HW=2 FW=2.1 Product=????????
391 * PCB: ?
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300392 * parts: DNOS404ZH102A(MT352, DTT7579(?))
Antti Palosaari41f81f62011-04-10 17:53:52 -0300393 *
Antti Palosaari05c46c02011-05-25 18:30:09 -0300394 * E30 VID=04b4 PID=861f HW=2 FW=2.1 "anysee-T(LP)"
395 * PCB: PCB 507T (rev1.61)
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300396 * parts: DNOS404ZH103A(ZL10353, DTT7579(?))
Antti Palosaari05c46c02011-05-25 18:30:09 -0300397 * OEA=0a OEB=00 OEC=00 OED=ff OEE=00
398 * IOA=45 IOB=ff IOC=00 IOD=ff IOE=00
Antti Palosaari41f81f62011-04-10 17:53:52 -0300399 *
400 * E30 Plus VID=04b4 PID=861f HW=6 FW=1.0 "anysee"
401 * PCB: 507CD (rev1.1)
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300402 * parts: DNOS404ZH103A(ZL10353, DTT7579(?)), CST56I01
Antti Palosaari05c46c02011-05-25 18:30:09 -0300403 * OEA=80 OEB=00 OEC=00 OED=ff OEE=fe
404 * IOA=4f IOB=ff IOC=00 IOD=06 IOE=01
Antti Palosaari41f81f62011-04-10 17:53:52 -0300405 * IOD[0] ZL10353 1=enabled
406 * IOA[7] TS 0=enabled
407 * tuner is not behind ZL10353 I2C-gate (no care if gate disabled or not)
408 *
409 * E30 C Plus VID=04b4 PID=861f HW=10 FW=1.0 "anysee-DC(LP)"
410 * PCB: 507DC (rev0.2)
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300411 * parts: TDA10023, DTOS403IH102B TM, CST56I01
Antti Palosaari05c46c02011-05-25 18:30:09 -0300412 * OEA=80 OEB=00 OEC=00 OED=ff OEE=fe
413 * IOA=4f IOB=ff IOC=00 IOD=26 IOE=01
Antti Palosaari41f81f62011-04-10 17:53:52 -0300414 * IOD[0] TDA10023 1=enabled
415 *
Antti Palosaarif0a53102011-04-27 21:11:59 -0300416 * E30 S2 Plus VID=04b4 PID=861f HW=11 FW=0.1 "anysee-S2(LP)"
417 * PCB: 507SI (rev2.1)
418 * parts: BS2N10WCC01(CX24116, CX24118), ISL6423, TDA8024
Antti Palosaari05c46c02011-05-25 18:30:09 -0300419 * OEA=80 OEB=00 OEC=ff OED=ff OEE=fe
420 * IOA=4d IOB=ff IOC=00 IOD=26 IOE=01
Antti Palosaarif0a53102011-04-27 21:11:59 -0300421 * IOD[0] CX24116 1=enabled
422 *
Antti Palosaari41f81f62011-04-10 17:53:52 -0300423 * E30 C Plus VID=1c73 PID=861f HW=15 FW=1.2 "anysee-FA(LP)"
424 * PCB: 507FA (rev0.4)
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300425 * parts: 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 * IOD[5] TDA10023 1=enabled
429 * IOE[0] tuner 1=enabled
430 *
431 * E30 Combo Plus VID=1c73 PID=861f HW=15 FW=1.2 "anysee-FA(LP)"
432 * PCB: 507FA (rev1.1)
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300433 * parts: ZL10353, TDA10023, DTOS403IH102B TM, TDA8024
Antti Palosaari05c46c02011-05-25 18:30:09 -0300434 * OEA=80 OEB=00 OEC=ff OED=ff OEE=ff
435 * IOA=4d IOB=ff IOC=00 IOD=00 IOE=c0
Antti Palosaari41f81f62011-04-10 17:53:52 -0300436 * DVB-C:
437 * IOD[5] TDA10023 1=enabled
438 * IOE[0] tuner 1=enabled
439 * DVB-T:
440 * IOD[0] ZL10353 1=enabled
441 * IOE[0] tuner 0=enabled
442 * tuner is behind ZL10353 I2C-gate
Antti Palosaaric57f87e2013-12-16 21:08:04 -0300443 * tuner is behind TDA10023 I2C-gate
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300444 *
445 * E7 TC VID=1c73 PID=861f HW=18 FW=0.7 AMTCI=0.5 "anysee-E7TC(LP)"
446 * PCB: 508TC (rev0.6)
447 * parts: ZL10353, TDA10023, DNOD44CDH086A(TDA18212)
Antti Palosaari05c46c02011-05-25 18:30:09 -0300448 * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
449 * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4
Antti Palosaari70fc26f2011-04-12 20:17:11 -0300450 * IOA[7] TS 1=enabled
451 * IOE[4] TDA18212 1=enabled
452 * DVB-C:
453 * IOD[6] ZL10353 0=disabled
454 * IOD[5] TDA10023 1=enabled
455 * IOE[0] IF 1=enabled
456 * DVB-T:
457 * IOD[5] TDA10023 0=disabled
458 * IOD[6] ZL10353 1=enabled
459 * IOE[0] IF 0=enabled
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300460 *
461 * E7 S2 VID=1c73 PID=861f HW=19 FW=0.4 AMTCI=0.5 "anysee-E7S2(LP)"
462 * PCB: 508S2 (rev0.7)
463 * parts: DNBU10512IST(STV0903, STV6110), ISL6423
Antti Palosaari05c46c02011-05-25 18:30:09 -0300464 * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
465 * IOA=4d IOB=00 IOC=c4 IOD=08 IOE=e4
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300466 * IOA[7] TS 1=enabled
467 * IOE[5] STV0903 1=enabled
468 *
Antti Palosaari608add82011-08-12 18:29:46 -0300469 * E7 T2C VID=1c73 PID=861f HW=20 FW=0.1 AMTCI=0.5 "anysee-E7T2C(LP)"
470 * PCB: 508T2C (rev0.3)
471 * parts: DNOQ44QCH106A(CXD2820R, TDA18212), TDA8024
472 * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
473 * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4
474 * IOA[7] TS 1=enabled
475 * IOE[5] CXD2820R 1=enabled
476 *
Antti Palosaari8439e0d2011-05-24 07:57:34 -0300477 * E7 PTC VID=1c73 PID=861f HW=21 FW=0.1 AMTCI=?? "anysee-E7PTC(LP)"
478 * PCB: 508PTC (rev0.5)
479 * parts: ZL10353, TDA10023, DNOD44CDH086A(TDA18212)
480 * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
481 * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4
482 * IOA[7] TS 1=enabled
483 * IOE[4] TDA18212 1=enabled
484 * DVB-C:
485 * IOD[6] ZL10353 0=disabled
486 * IOD[5] TDA10023 1=enabled
487 * IOE[0] IF 1=enabled
488 * DVB-T:
489 * IOD[5] TDA10023 0=disabled
490 * IOD[6] ZL10353 1=enabled
491 * IOE[0] IF 0=enabled
Antti Palosaarifea3c392011-05-25 18:21:43 -0300492 *
Antti Palosaari608add82011-08-12 18:29:46 -0300493 * E7 PS2 VID=1c73 PID=861f HW=22 FW=0.1 AMTCI=?? "anysee-E7PS2(LP)"
Antti Palosaarifea3c392011-05-25 18:21:43 -0300494 * PCB: 508PS2 (rev0.4)
495 * parts: DNBU10512IST(STV0903, STV6110), ISL6423
496 * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
497 * IOA=4d IOB=00 IOC=c4 IOD=08 IOE=e4
498 * IOA[7] TS 1=enabled
499 * IOE[5] STV0903 1=enabled
Antti Palosaari41f81f62011-04-10 17:53:52 -0300500 */
501
Antti Palosaaria4e7c512012-06-14 04:56:09 -0300502static int anysee_read_config(struct dvb_usb_device *d)
503{
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300504 struct anysee_state *state = d_to_priv(d);
Antti Palosaaria4e7c512012-06-14 04:56:09 -0300505 int ret;
506 u8 hw_info[3];
507
508 /*
509 * Check which hardware we have.
510 * We must do this call two times to get reliable values (hw/fw bug).
511 */
512 ret = anysee_get_hw_info(d, hw_info);
513 if (ret)
514 goto error;
515
516 ret = anysee_get_hw_info(d, hw_info);
517 if (ret)
518 goto error;
519
Antti Palosaari82026f92012-08-14 15:56:20 -0300520 /*
521 * Meaning of these info bytes are guessed.
522 */
523 dev_info(&d->udev->dev, "%s: firmware version %d.%d hardware id %d\n",
524 KBUILD_MODNAME, hw_info[1], hw_info[2], hw_info[0]);
Antti Palosaaria4e7c512012-06-14 04:56:09 -0300525
526 state->hw = hw_info[0];
527error:
528 return ret;
529}
Antti Palosaaribe943512011-09-05 22:10:05 -0300530
531/* external I2C gate used for DNOD44CDH086A(TDA18212) tuner module */
532static int anysee_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
533{
Antti Palosaaribe943512011-09-05 22:10:05 -0300534 /* enable / disable tuner access on IOE[4] */
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300535 return anysee_wr_reg_mask(fe_to_d(fe), REG_IOE, (enable << 4), 0x10);
Antti Palosaaribe943512011-09-05 22:10:05 -0300536}
537
Antti Palosaari449d1a02011-07-25 20:25:21 -0300538static int anysee_frontend_ctrl(struct dvb_frontend *fe, int onoff)
539{
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300540 struct anysee_state *state = fe_to_priv(fe);
541 struct dvb_usb_device *d = fe_to_d(fe);
Antti Palosaari449d1a02011-07-25 20:25:21 -0300542 int ret;
Antti Palosaari82026f92012-08-14 15:56:20 -0300543 dev_dbg(&d->udev->dev, "%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
Antti Palosaari449d1a02011-07-25 20:25:21 -0300544
545 /* no frontend sleep control */
546 if (onoff == 0)
547 return 0;
548
549 switch (state->hw) {
550 case ANYSEE_HW_507FA: /* 15 */
551 /* E30 Combo Plus */
552 /* E30 C Plus */
553
Antti Palosaaria4e7c512012-06-14 04:56:09 -0300554 if (fe->id == 0) {
Antti Palosaari449d1a02011-07-25 20:25:21 -0300555 /* disable DVB-T demod on IOD[0] */
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300556 ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 0), 0x01);
Antti Palosaari449d1a02011-07-25 20:25:21 -0300557 if (ret)
558 goto error;
559
560 /* enable DVB-C demod on IOD[5] */
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300561 ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 5), 0x20);
Antti Palosaari449d1a02011-07-25 20:25:21 -0300562 if (ret)
563 goto error;
564
565 /* enable DVB-C tuner on IOE[0] */
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300566 ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 0), 0x01);
Antti Palosaari449d1a02011-07-25 20:25:21 -0300567 if (ret)
568 goto error;
569 } else {
570 /* disable DVB-C demod on IOD[5] */
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300571 ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 5), 0x20);
Antti Palosaari449d1a02011-07-25 20:25:21 -0300572 if (ret)
573 goto error;
574
575 /* enable DVB-T demod on IOD[0] */
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300576 ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
Antti Palosaari449d1a02011-07-25 20:25:21 -0300577 if (ret)
578 goto error;
579
580 /* enable DVB-T tuner on IOE[0] */
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300581 ret = anysee_wr_reg_mask(d, REG_IOE, (0 << 0), 0x01);
Antti Palosaari449d1a02011-07-25 20:25:21 -0300582 if (ret)
583 goto error;
584 }
585
586 break;
587 case ANYSEE_HW_508TC: /* 18 */
588 case ANYSEE_HW_508PTC: /* 21 */
589 /* E7 TC */
590 /* E7 PTC */
591
Antti Palosaaria4e7c512012-06-14 04:56:09 -0300592 if (fe->id == 0) {
Antti Palosaari449d1a02011-07-25 20:25:21 -0300593 /* disable DVB-T demod on IOD[6] */
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300594 ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 6), 0x40);
Antti Palosaari449d1a02011-07-25 20:25:21 -0300595 if (ret)
596 goto error;
597
598 /* enable DVB-C demod on IOD[5] */
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300599 ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 5), 0x20);
Antti Palosaari449d1a02011-07-25 20:25:21 -0300600 if (ret)
601 goto error;
602
603 /* enable IF route on IOE[0] */
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300604 ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 0), 0x01);
Antti Palosaari449d1a02011-07-25 20:25:21 -0300605 if (ret)
606 goto error;
607 } else {
608 /* disable DVB-C demod on IOD[5] */
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300609 ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 5), 0x20);
Antti Palosaari449d1a02011-07-25 20:25:21 -0300610 if (ret)
611 goto error;
612
613 /* enable DVB-T demod on IOD[6] */
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300614 ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 6), 0x40);
Antti Palosaari449d1a02011-07-25 20:25:21 -0300615 if (ret)
616 goto error;
617
618 /* enable IF route on IOE[0] */
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300619 ret = anysee_wr_reg_mask(d, REG_IOE, (0 << 0), 0x01);
Antti Palosaari449d1a02011-07-25 20:25:21 -0300620 if (ret)
621 goto error;
622 }
623
624 break;
625 default:
626 ret = 0;
627 }
628
629error:
630 return ret;
631}
632
Kees Cook73831592014-10-20 18:49:04 -0300633static int anysee_add_i2c_dev(struct dvb_usb_device *d, const char *type,
634 u8 addr, void *platform_data)
Antti Palosaarif80f2ae2014-08-03 21:47:10 -0300635{
636 int ret, num;
637 struct anysee_state *state = d_to_priv(d);
638 struct i2c_client *client;
639 struct i2c_adapter *adapter = &d->i2c_adap;
640 struct i2c_board_info board_info = {
641 .addr = addr,
642 .platform_data = platform_data,
643 };
644
645 strlcpy(board_info.type, type, I2C_NAME_SIZE);
646
647 /* find first free client */
648 for (num = 0; num < ANYSEE_I2C_CLIENT_MAX; num++) {
649 if (state->i2c_client[num] == NULL)
650 break;
651 }
652
653 dev_dbg(&d->udev->dev, "%s: num=%d\n", __func__, num);
654
655 if (num == ANYSEE_I2C_CLIENT_MAX) {
656 dev_err(&d->udev->dev, "%s: I2C client out of index\n",
657 KBUILD_MODNAME);
658 ret = -ENODEV;
659 goto err;
660 }
661
Kees Cook73831592014-10-20 18:49:04 -0300662 request_module("%s", board_info.type);
Antti Palosaarif80f2ae2014-08-03 21:47:10 -0300663
664 /* register I2C device */
665 client = i2c_new_device(adapter, &board_info);
666 if (client == NULL || client->dev.driver == NULL) {
667 ret = -ENODEV;
668 goto err;
669 }
670
671 /* increase I2C driver usage count */
672 if (!try_module_get(client->dev.driver->owner)) {
673 i2c_unregister_device(client);
674 ret = -ENODEV;
675 goto err;
676 }
677
678 state->i2c_client[num] = client;
679 return 0;
680err:
681 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
682 return ret;
683}
684
685static void anysee_del_i2c_dev(struct dvb_usb_device *d)
686{
687 int num;
688 struct anysee_state *state = d_to_priv(d);
689 struct i2c_client *client;
690
691 /* find last used client */
692 num = ANYSEE_I2C_CLIENT_MAX;
693 while (num--) {
694 if (state->i2c_client[num] != NULL)
695 break;
696 }
697
698 dev_dbg(&d->udev->dev, "%s: num=%d\n", __func__, num);
699
700 if (num == -1) {
701 dev_err(&d->udev->dev, "%s: I2C client out of index\n",
702 KBUILD_MODNAME);
703 goto err;
704 }
705
706 client = state->i2c_client[num];
707
708 /* decrease I2C driver usage count */
709 module_put(client->dev.driver->owner);
710
711 /* unregister I2C device */
712 i2c_unregister_device(client);
713
714 state->i2c_client[num] = NULL;
715err:
716 dev_dbg(&d->udev->dev, "%s: failed\n", __func__);
717}
718
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300719static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
720{
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300721 struct anysee_state *state = adap_to_priv(adap);
722 struct dvb_usb_device *d = adap_to_d(adap);
Geert Uytterhoevenecb52ab2013-04-24 07:36:45 -0300723 int ret = 0;
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300724 u8 tmp;
725 struct i2c_msg msg[2] = {
726 {
Antti Palosaarif80f2ae2014-08-03 21:47:10 -0300727 .addr = 0x60,
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300728 .flags = 0,
729 .len = 1,
730 .buf = "\x00",
731 }, {
Antti Palosaarif80f2ae2014-08-03 21:47:10 -0300732 .addr = 0x60,
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300733 .flags = I2C_M_RD,
734 .len = 1,
735 .buf = &tmp,
736 }
737 };
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300738
Antti Palosaari41f81f62011-04-10 17:53:52 -0300739 switch (state->hw) {
Antti Palosaari05c46c02011-05-25 18:30:09 -0300740 case ANYSEE_HW_507T: /* 2 */
Antti Palosaari41f81f62011-04-10 17:53:52 -0300741 /* E30 */
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300742
Antti Palosaari41f81f62011-04-10 17:53:52 -0300743 /* attach demod */
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300744 adap->fe[0] = dvb_attach(mt352_attach, &anysee_mt352_config,
745 &d->i2c_adap);
Antti Palosaaria4e7c512012-06-14 04:56:09 -0300746 if (adap->fe[0])
Antti Palosaari41f81f62011-04-10 17:53:52 -0300747 break;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300748
Antti Palosaari41f81f62011-04-10 17:53:52 -0300749 /* attach demod */
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300750 adap->fe[0] = dvb_attach(zl10353_attach, &anysee_zl10353_config,
751 &d->i2c_adap);
Antti Palosaari41f81f62011-04-10 17:53:52 -0300752
753 break;
754 case ANYSEE_HW_507CD: /* 6 */
755 /* E30 Plus */
756
757 /* enable DVB-T demod on IOD[0] */
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300758 ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
Antti Palosaari41f81f62011-04-10 17:53:52 -0300759 if (ret)
760 goto error;
761
762 /* enable transport stream on IOA[7] */
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300763 ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80);
Antti Palosaari41f81f62011-04-10 17:53:52 -0300764 if (ret)
765 goto error;
766
767 /* attach demod */
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300768 adap->fe[0] = dvb_attach(zl10353_attach, &anysee_zl10353_config,
769 &d->i2c_adap);
Antti Palosaari41f81f62011-04-10 17:53:52 -0300770
771 break;
772 case ANYSEE_HW_507DC: /* 10 */
773 /* E30 C Plus */
774
775 /* enable DVB-C demod on IOD[0] */
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300776 ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
Antti Palosaari41f81f62011-04-10 17:53:52 -0300777 if (ret)
778 goto error;
779
780 /* attach demod */
Antti Palosaaria4e7c512012-06-14 04:56:09 -0300781 adap->fe[0] = dvb_attach(tda10023_attach,
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300782 &anysee_tda10023_config, &d->i2c_adap, 0x48);
Antti Palosaari41f81f62011-04-10 17:53:52 -0300783
784 break;
Antti Palosaarif0a53102011-04-27 21:11:59 -0300785 case ANYSEE_HW_507SI: /* 11 */
786 /* E30 S2 Plus */
787
788 /* enable DVB-S/S2 demod on IOD[0] */
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300789 ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
Antti Palosaarif0a53102011-04-27 21:11:59 -0300790 if (ret)
791 goto error;
792
793 /* attach demod */
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300794 adap->fe[0] = dvb_attach(cx24116_attach, &anysee_cx24116_config,
795 &d->i2c_adap);
Antti Palosaarif0a53102011-04-27 21:11:59 -0300796
797 break;
Antti Palosaari41f81f62011-04-10 17:53:52 -0300798 case ANYSEE_HW_507FA: /* 15 */
799 /* E30 Combo Plus */
800 /* E30 C Plus */
801
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300802 /* enable tuner on IOE[4] */
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300803 ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 4), 0x10);
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300804 if (ret)
805 goto error;
806
807 /* probe TDA18212 */
808 tmp = 0;
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300809 ret = i2c_transfer(&d->i2c_adap, msg, 2);
Antti Palosaarif80f2ae2014-08-03 21:47:10 -0300810 if (ret == 2 && tmp == 0xc7) {
Antti Palosaari82026f92012-08-14 15:56:20 -0300811 dev_dbg(&d->udev->dev, "%s: TDA18212 found\n",
812 __func__);
Antti Palosaarif80f2ae2014-08-03 21:47:10 -0300813 state->has_tda18212 = true;
814 }
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300815 else
816 tmp = 0;
817
818 /* disable tuner on IOE[4] */
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300819 ret = anysee_wr_reg_mask(d, REG_IOE, (0 << 4), 0x10);
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300820 if (ret)
821 goto error;
822
Antti Palosaaria4e7c512012-06-14 04:56:09 -0300823 /* disable DVB-T demod on IOD[0] */
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300824 ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 0), 0x01);
Antti Palosaaria4e7c512012-06-14 04:56:09 -0300825 if (ret)
826 goto error;
Antti Palosaari41f81f62011-04-10 17:53:52 -0300827
Antti Palosaaria4e7c512012-06-14 04:56:09 -0300828 /* enable DVB-C demod on IOD[5] */
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300829 ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 5), 0x20);
Antti Palosaaria4e7c512012-06-14 04:56:09 -0300830 if (ret)
831 goto error;
Antti Palosaari41f81f62011-04-10 17:53:52 -0300832
Antti Palosaaria4e7c512012-06-14 04:56:09 -0300833 /* attach demod */
834 if (tmp == 0xc7) {
835 /* TDA18212 config */
836 adap->fe[0] = dvb_attach(tda10023_attach,
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300837 &anysee_tda10023_tda18212_config,
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300838 &d->i2c_adap, 0x48);
Antti Palosaaria4e7c512012-06-14 04:56:09 -0300839
840 /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
841 if (adap->fe[0])
842 adap->fe[0]->ops.i2c_gate_ctrl =
843 anysee_i2c_gate_ctrl;
844 } else {
845 /* PLL config */
846 adap->fe[0] = dvb_attach(tda10023_attach,
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300847 &anysee_tda10023_config,
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300848 &d->i2c_adap, 0x48);
Antti Palosaari0f77c3a2008-08-11 10:54:16 -0300849 }
Antti Palosaarie82eea72011-04-12 19:43:30 -0300850
Antti Palosaaria4e7c512012-06-14 04:56:09 -0300851 /* break out if first frontend attaching fails */
852 if (!adap->fe[0])
853 break;
854
855 /* disable DVB-C demod on IOD[5] */
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300856 ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 5), 0x20);
Antti Palosaaria4e7c512012-06-14 04:56:09 -0300857 if (ret)
858 goto error;
859
860 /* enable DVB-T demod on IOD[0] */
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300861 ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
Antti Palosaaria4e7c512012-06-14 04:56:09 -0300862 if (ret)
863 goto error;
864
865 /* attach demod */
Antti Palosaaribe943512011-09-05 22:10:05 -0300866 if (tmp == 0xc7) {
Antti Palosaaria4e7c512012-06-14 04:56:09 -0300867 /* TDA18212 config */
868 adap->fe[1] = dvb_attach(zl10353_attach,
869 &anysee_zl10353_tda18212_config2,
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300870 &d->i2c_adap);
Antti Palosaaria4e7c512012-06-14 04:56:09 -0300871
872 /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
873 if (adap->fe[1])
874 adap->fe[1]->ops.i2c_gate_ctrl =
875 anysee_i2c_gate_ctrl;
876 } else {
877 /* PLL config */
878 adap->fe[1] = dvb_attach(zl10353_attach,
879 &anysee_zl10353_config,
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300880 &d->i2c_adap);
Antti Palosaaribe943512011-09-05 22:10:05 -0300881 }
882
Antti Palosaari41f81f62011-04-10 17:53:52 -0300883 break;
Antti Palosaaria43be982011-04-10 20:23:02 -0300884 case ANYSEE_HW_508TC: /* 18 */
Antti Palosaari8439e0d2011-05-24 07:57:34 -0300885 case ANYSEE_HW_508PTC: /* 21 */
Antti Palosaaria43be982011-04-10 20:23:02 -0300886 /* E7 TC */
Antti Palosaari8439e0d2011-05-24 07:57:34 -0300887 /* E7 PTC */
Antti Palosaaria43be982011-04-10 20:23:02 -0300888
Antti Palosaaria4e7c512012-06-14 04:56:09 -0300889 /* disable DVB-T demod on IOD[6] */
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300890 ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 6), 0x40);
Antti Palosaaria4e7c512012-06-14 04:56:09 -0300891 if (ret)
892 goto error;
Antti Palosaaria43be982011-04-10 20:23:02 -0300893
Antti Palosaaria4e7c512012-06-14 04:56:09 -0300894 /* enable DVB-C demod on IOD[5] */
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300895 ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 5), 0x20);
Antti Palosaaria4e7c512012-06-14 04:56:09 -0300896 if (ret)
897 goto error;
Antti Palosaaria43be982011-04-10 20:23:02 -0300898
Antti Palosaaria4e7c512012-06-14 04:56:09 -0300899 /* attach demod */
900 adap->fe[0] = dvb_attach(tda10023_attach,
Antti Palosaari449d1a02011-07-25 20:25:21 -0300901 &anysee_tda10023_tda18212_config,
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300902 &d->i2c_adap, 0x48);
Antti Palosaarie82eea72011-04-12 19:43:30 -0300903
Antti Palosaaribe943512011-09-05 22:10:05 -0300904 /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
Antti Palosaaria4e7c512012-06-14 04:56:09 -0300905 if (adap->fe[0])
906 adap->fe[0]->ops.i2c_gate_ctrl = anysee_i2c_gate_ctrl;
907
908 /* break out if first frontend attaching fails */
909 if (!adap->fe[0])
910 break;
911
912 /* disable DVB-C demod on IOD[5] */
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300913 ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 5), 0x20);
Antti Palosaaria4e7c512012-06-14 04:56:09 -0300914 if (ret)
915 goto error;
916
917 /* enable DVB-T demod on IOD[6] */
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300918 ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 6), 0x40);
Antti Palosaaria4e7c512012-06-14 04:56:09 -0300919 if (ret)
920 goto error;
921
922 /* attach demod */
923 adap->fe[1] = dvb_attach(zl10353_attach,
924 &anysee_zl10353_tda18212_config,
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300925 &d->i2c_adap);
Antti Palosaaria4e7c512012-06-14 04:56:09 -0300926
927 /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
928 if (adap->fe[1])
929 adap->fe[1]->ops.i2c_gate_ctrl = anysee_i2c_gate_ctrl;
Antti Palosaaribe943512011-09-05 22:10:05 -0300930
Antti Palosaari05cd37d2011-09-05 23:33:04 -0300931 state->has_ci = true;
932
Antti Palosaaria43be982011-04-10 20:23:02 -0300933 break;
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300934 case ANYSEE_HW_508S2: /* 19 */
Antti Palosaarifea3c392011-05-25 18:21:43 -0300935 case ANYSEE_HW_508PS2: /* 22 */
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300936 /* E7 S2 */
Antti Palosaarifea3c392011-05-25 18:21:43 -0300937 /* E7 PS2 */
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300938
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300939 /* enable DVB-S/S2 demod on IOE[5] */
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300940 ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 5), 0x20);
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300941 if (ret)
942 goto error;
943
944 /* attach demod */
Antti Palosaaria4e7c512012-06-14 04:56:09 -0300945 adap->fe[0] = dvb_attach(stv0900_attach,
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300946 &anysee_stv0900_config, &d->i2c_adap, 0);
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300947
Antti Palosaari05cd37d2011-09-05 23:33:04 -0300948 state->has_ci = true;
949
Antti Palosaaribedbf3d2011-04-29 13:55:02 -0300950 break;
Antti Palosaari608add82011-08-12 18:29:46 -0300951 case ANYSEE_HW_508T2C: /* 20 */
952 /* E7 T2C */
953
Antti Palosaari608add82011-08-12 18:29:46 -0300954 /* enable DVB-T/T2/C demod on IOE[5] */
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300955 ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 5), 0x20);
Antti Palosaari608add82011-08-12 18:29:46 -0300956 if (ret)
957 goto error;
958
Antti Palosaarifaf27972012-01-15 14:20:50 -0300959 /* attach demod */
Antti Palosaaria4e7c512012-06-14 04:56:09 -0300960 adap->fe[0] = dvb_attach(cxd2820r_attach,
Antti Palosaari1e8f31f2012-07-19 21:10:36 -0300961 &anysee_cxd2820r_config, &d->i2c_adap, NULL);
Antti Palosaari608add82011-08-12 18:29:46 -0300962
Antti Palosaari05cd37d2011-09-05 23:33:04 -0300963 state->has_ci = true;
Antti Palosaari0f77c3a2008-08-11 10:54:16 -0300964
965 break;
966 }
967
Antti Palosaaria4e7c512012-06-14 04:56:09 -0300968 if (!adap->fe[0]) {
Antti Palosaari41f81f62011-04-10 17:53:52 -0300969 /* we have no frontend :-( */
970 ret = -ENODEV;
Antti Palosaari4458a54c2013-02-26 14:18:13 -0300971 dev_err(&d->udev->dev,
Geert Uytterhoeven542b3292013-04-24 07:36:46 -0300972 "%s: Unsupported Anysee version. Please report to <linux-media@vger.kernel.org>.\n",
Antti Palosaari82026f92012-08-14 15:56:20 -0300973 KBUILD_MODNAME);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300974 }
Antti Palosaari41f81f62011-04-10 17:53:52 -0300975error:
976 return ret;
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300977}
978
979static int anysee_tuner_attach(struct dvb_usb_adapter *adap)
980{
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300981 struct anysee_state *state = adap_to_priv(adap);
982 struct dvb_usb_device *d = adap_to_d(adap);
Antti Palosaari72ffd2b2011-04-10 20:14:50 -0300983 struct dvb_frontend *fe;
Antti Palosaarie82eea72011-04-12 19:43:30 -0300984 int ret;
Antti Palosaari82026f92012-08-14 15:56:20 -0300985 dev_dbg(&d->udev->dev, "%s:\n", __func__);
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300986
Antti Palosaari41f81f62011-04-10 17:53:52 -0300987 switch (state->hw) {
Antti Palosaari05c46c02011-05-25 18:30:09 -0300988 case ANYSEE_HW_507T: /* 2 */
Antti Palosaari41f81f62011-04-10 17:53:52 -0300989 /* E30 */
990
991 /* attach tuner */
Antti Palosaari05cd62e2012-06-18 19:39:02 -0300992 fe = dvb_attach(dvb_pll_attach, adap->fe[0], (0xc2 >> 1), NULL,
993 DVB_PLL_THOMSON_DTT7579);
Antti Palosaarie82eea72011-04-12 19:43:30 -0300994
Antti Palosaaria51e34d2008-05-17 23:05:48 -0300995 break;
Antti Palosaari41f81f62011-04-10 17:53:52 -0300996 case ANYSEE_HW_507CD: /* 6 */
997 /* E30 Plus */
998
999 /* attach tuner */
Antti Palosaari05cd62e2012-06-18 19:39:02 -03001000 fe = dvb_attach(dvb_pll_attach, adap->fe[0], (0xc2 >> 1),
1001 &d->i2c_adap, DVB_PLL_THOMSON_DTT7579);
Antti Palosaari41f81f62011-04-10 17:53:52 -03001002
1003 break;
1004 case ANYSEE_HW_507DC: /* 10 */
1005 /* E30 C Plus */
1006
1007 /* attach tuner */
Antti Palosaari05cd62e2012-06-18 19:39:02 -03001008 fe = dvb_attach(dvb_pll_attach, adap->fe[0], (0xc0 >> 1),
1009 &d->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A);
Antti Palosaarie82eea72011-04-12 19:43:30 -03001010
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001011 break;
Antti Palosaarif0a53102011-04-27 21:11:59 -03001012 case ANYSEE_HW_507SI: /* 11 */
1013 /* E30 S2 Plus */
1014
1015 /* attach LNB controller */
Antti Palosaari05cd62e2012-06-18 19:39:02 -03001016 fe = dvb_attach(isl6423_attach, adap->fe[0], &d->i2c_adap,
1017 &anysee_isl6423_config);
Antti Palosaarif0a53102011-04-27 21:11:59 -03001018
1019 break;
Antti Palosaari41f81f62011-04-10 17:53:52 -03001020 case ANYSEE_HW_507FA: /* 15 */
1021 /* E30 Combo Plus */
1022 /* E30 C Plus */
1023
Antti Palosaari72ffd2b2011-04-10 20:14:50 -03001024 /* Try first attach TDA18212 silicon tuner on IOE[4], if that
1025 * fails attach old simple PLL. */
1026
Antti Palosaari72ffd2b2011-04-10 20:14:50 -03001027 /* attach tuner */
Antti Palosaarif80f2ae2014-08-03 21:47:10 -03001028 if (state->has_tda18212) {
1029 struct tda18212_config tda18212_config =
1030 anysee_tda18212_config;
Antti Palosaaria4e7c512012-06-14 04:56:09 -03001031
Antti Palosaarif80f2ae2014-08-03 21:47:10 -03001032 tda18212_config.fe = adap->fe[0];
1033 ret = anysee_add_i2c_dev(d, "tda18212", 0x60,
1034 &tda18212_config);
1035 if (ret)
1036 goto err;
Antti Palosaari72ffd2b2011-04-10 20:14:50 -03001037
Antti Palosaarif80f2ae2014-08-03 21:47:10 -03001038 /* copy tuner ops for 2nd FE as tuner is shared */
1039 if (adap->fe[1]) {
1040 adap->fe[1]->tuner_priv =
1041 adap->fe[0]->tuner_priv;
1042 memcpy(&adap->fe[1]->ops.tuner_ops,
1043 &adap->fe[0]->ops.tuner_ops,
1044 sizeof(struct dvb_tuner_ops));
1045 }
Antti Palosaaria4e7c512012-06-14 04:56:09 -03001046
Antti Palosaarif80f2ae2014-08-03 21:47:10 -03001047 return 0;
1048 } else {
1049 /* attach tuner */
1050 fe = dvb_attach(dvb_pll_attach, adap->fe[0],
Antti Palosaari05cd62e2012-06-18 19:39:02 -03001051 (0xc0 >> 1), &d->i2c_adap,
Antti Palosaaria4e7c512012-06-14 04:56:09 -03001052 DVB_PLL_SAMSUNG_DTOS403IH102A);
Antti Palosaarif80f2ae2014-08-03 21:47:10 -03001053
1054 if (fe && adap->fe[1]) {
1055 /* attach tuner for 2nd FE */
1056 fe = dvb_attach(dvb_pll_attach, adap->fe[1],
1057 (0xc0 >> 1), &d->i2c_adap,
1058 DVB_PLL_SAMSUNG_DTOS403IH102A);
1059 }
Antti Palosaaria4e7c512012-06-14 04:56:09 -03001060 }
Antti Palosaari41f81f62011-04-10 17:53:52 -03001061
1062 break;
Antti Palosaaria43be982011-04-10 20:23:02 -03001063 case ANYSEE_HW_508TC: /* 18 */
Antti Palosaari8439e0d2011-05-24 07:57:34 -03001064 case ANYSEE_HW_508PTC: /* 21 */
Antti Palosaarif80f2ae2014-08-03 21:47:10 -03001065 {
Antti Palosaaria43be982011-04-10 20:23:02 -03001066 /* E7 TC */
Antti Palosaari8439e0d2011-05-24 07:57:34 -03001067 /* E7 PTC */
Antti Palosaarif80f2ae2014-08-03 21:47:10 -03001068 struct tda18212_config tda18212_config = anysee_tda18212_config;
Antti Palosaaria43be982011-04-10 20:23:02 -03001069
Antti Palosaarif80f2ae2014-08-03 21:47:10 -03001070 tda18212_config.fe = adap->fe[0];
1071 ret = anysee_add_i2c_dev(d, "tda18212", 0x60, &tda18212_config);
1072 if (ret)
1073 goto err;
Antti Palosaaria43be982011-04-10 20:23:02 -03001074
Antti Palosaarif80f2ae2014-08-03 21:47:10 -03001075 /* copy tuner ops for 2nd FE as tuner is shared */
1076 if (adap->fe[1]) {
1077 adap->fe[1]->tuner_priv = adap->fe[0]->tuner_priv;
1078 memcpy(&adap->fe[1]->ops.tuner_ops,
1079 &adap->fe[0]->ops.tuner_ops,
1080 sizeof(struct dvb_tuner_ops));
Antti Palosaaria4e7c512012-06-14 04:56:09 -03001081 }
1082
Antti Palosaarif80f2ae2014-08-03 21:47:10 -03001083 return 0;
1084 }
Antti Palosaaribedbf3d2011-04-29 13:55:02 -03001085 case ANYSEE_HW_508S2: /* 19 */
Antti Palosaarifea3c392011-05-25 18:21:43 -03001086 case ANYSEE_HW_508PS2: /* 22 */
Antti Palosaaribedbf3d2011-04-29 13:55:02 -03001087 /* E7 S2 */
Antti Palosaarifea3c392011-05-25 18:21:43 -03001088 /* E7 PS2 */
Antti Palosaaribedbf3d2011-04-29 13:55:02 -03001089
1090 /* attach tuner */
Antti Palosaaria4e7c512012-06-14 04:56:09 -03001091 fe = dvb_attach(stv6110_attach, adap->fe[0],
Antti Palosaari05cd62e2012-06-18 19:39:02 -03001092 &anysee_stv6110_config, &d->i2c_adap);
Antti Palosaaribedbf3d2011-04-29 13:55:02 -03001093
1094 if (fe) {
1095 /* attach LNB controller */
Antti Palosaaria4e7c512012-06-14 04:56:09 -03001096 fe = dvb_attach(isl6423_attach, adap->fe[0],
Antti Palosaari05cd62e2012-06-18 19:39:02 -03001097 &d->i2c_adap, &anysee_isl6423_config);
Antti Palosaaribedbf3d2011-04-29 13:55:02 -03001098 }
1099
1100 break;
Antti Palosaari608add82011-08-12 18:29:46 -03001101
1102 case ANYSEE_HW_508T2C: /* 20 */
Antti Palosaarif80f2ae2014-08-03 21:47:10 -03001103 {
Antti Palosaari608add82011-08-12 18:29:46 -03001104 /* E7 T2C */
Antti Palosaarif80f2ae2014-08-03 21:47:10 -03001105 struct tda18212_config tda18212_config =
1106 anysee_tda18212_config2;
Antti Palosaari608add82011-08-12 18:29:46 -03001107
Antti Palosaarif80f2ae2014-08-03 21:47:10 -03001108 tda18212_config.fe = adap->fe[0];
1109 ret = anysee_add_i2c_dev(d, "tda18212", 0x60, &tda18212_config);
1110 if (ret)
1111 goto err;
Antti Palosaari608add82011-08-12 18:29:46 -03001112
Antti Palosaarif80f2ae2014-08-03 21:47:10 -03001113 return 0;
1114 }
Antti Palosaari41f81f62011-04-10 17:53:52 -03001115 default:
Antti Palosaarie82eea72011-04-12 19:43:30 -03001116 fe = NULL;
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001117 }
1118
Antti Palosaarie82eea72011-04-12 19:43:30 -03001119 if (fe)
1120 ret = 0;
1121 else
1122 ret = -ENODEV;
Antti Palosaarif80f2ae2014-08-03 21:47:10 -03001123err:
Antti Palosaari41f81f62011-04-10 17:53:52 -03001124 return ret;
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001125}
1126
Antti Palosaari37b44a02013-01-04 15:21:26 -03001127#if IS_ENABLED(CONFIG_RC_CORE)
Antti Palosaaria8494682010-10-17 18:25:10 -03001128static int anysee_rc_query(struct dvb_usb_device *d)
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001129{
1130 u8 buf[] = {CMD_GET_IR_CODE};
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001131 u8 ircode[2];
Antti Palosaaria8494682010-10-17 18:25:10 -03001132 int ret;
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001133
Antti Palosaaria8494682010-10-17 18:25:10 -03001134 /* Remote controller is basic NEC using address byte 0x08.
1135 Anysee device RC query returns only two bytes, status and code,
1136 address byte is dropped. Also it does not return any value for
1137 NEC RCs having address byte other than 0x08. Due to that, we
1138 cannot use that device as standard NEC receiver.
1139 It could be possible make hack which reads whole code directly
1140 from device memory... */
1141
1142 ret = anysee_ctrl_msg(d, buf, sizeof(buf), ircode, sizeof(ircode));
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001143 if (ret)
1144 return ret;
1145
Antti Palosaaria8494682010-10-17 18:25:10 -03001146 if (ircode[0]) {
Antti Palosaari82026f92012-08-14 15:56:20 -03001147 dev_dbg(&d->udev->dev, "%s: key pressed %02x\n", __func__,
1148 ircode[1]);
David Härdeman120703f2014-04-03 20:31:30 -03001149 rc_keydown(d->rc_dev, RC_TYPE_NEC,
1150 RC_SCANCODE_NEC(0x08, ircode[1]), 0);
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001151 }
Antti Palosaaria8494682010-10-17 18:25:10 -03001152
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001153 return 0;
1154}
1155
Antti Palosaaria4e7c512012-06-14 04:56:09 -03001156static int anysee_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
1157{
David Härdemanc003ab12012-10-11 19:11:54 -03001158 rc->allowed_protos = RC_BIT_NEC;
Antti Palosaaria4e7c512012-06-14 04:56:09 -03001159 rc->query = anysee_rc_query;
1160 rc->interval = 250; /* windows driver uses 500ms */
1161
1162 return 0;
1163}
Antti Palosaarid5c62092012-12-09 20:12:07 -03001164#else
1165 #define anysee_get_rc_config NULL
1166#endif
Antti Palosaaria4e7c512012-06-14 04:56:09 -03001167
Antti Palosaari05cd37d2011-09-05 23:33:04 -03001168static int anysee_ci_read_attribute_mem(struct dvb_ca_en50221 *ci, int slot,
1169 int addr)
1170{
1171 struct dvb_usb_device *d = ci->data;
1172 int ret;
1173 u8 buf[] = {CMD_CI, 0x02, 0x40 | addr >> 8, addr & 0xff, 0x00, 1};
1174 u8 val;
1175
1176 ret = anysee_ctrl_msg(d, buf, sizeof(buf), &val, 1);
1177 if (ret)
1178 return ret;
1179
1180 return val;
1181}
1182
1183static int anysee_ci_write_attribute_mem(struct dvb_ca_en50221 *ci, int slot,
1184 int addr, u8 val)
1185{
1186 struct dvb_usb_device *d = ci->data;
1187 int ret;
1188 u8 buf[] = {CMD_CI, 0x03, 0x40 | addr >> 8, addr & 0xff, 0x00, 1, val};
1189
1190 ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
1191 if (ret)
1192 return ret;
1193
1194 return 0;
1195}
1196
1197static int anysee_ci_read_cam_control(struct dvb_ca_en50221 *ci, int slot,
1198 u8 addr)
1199{
1200 struct dvb_usb_device *d = ci->data;
1201 int ret;
1202 u8 buf[] = {CMD_CI, 0x04, 0x40, addr, 0x00, 1};
1203 u8 val;
1204
1205 ret = anysee_ctrl_msg(d, buf, sizeof(buf), &val, 1);
1206 if (ret)
1207 return ret;
1208
1209 return val;
1210}
1211
1212static int anysee_ci_write_cam_control(struct dvb_ca_en50221 *ci, int slot,
1213 u8 addr, u8 val)
1214{
1215 struct dvb_usb_device *d = ci->data;
1216 int ret;
1217 u8 buf[] = {CMD_CI, 0x05, 0x40, addr, 0x00, 1, val};
1218
1219 ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
1220 if (ret)
1221 return ret;
1222
1223 return 0;
1224}
1225
1226static int anysee_ci_slot_reset(struct dvb_ca_en50221 *ci, int slot)
1227{
1228 struct dvb_usb_device *d = ci->data;
1229 int ret;
Antti Palosaari05cd62e2012-06-18 19:39:02 -03001230 struct anysee_state *state = d_to_priv(d);
Antti Palosaari05cd37d2011-09-05 23:33:04 -03001231
1232 state->ci_cam_ready = jiffies + msecs_to_jiffies(1000);
1233
1234 ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80);
1235 if (ret)
1236 return ret;
1237
1238 msleep(300);
1239
1240 ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
1241 if (ret)
1242 return ret;
1243
1244 return 0;
1245}
1246
1247static int anysee_ci_slot_shutdown(struct dvb_ca_en50221 *ci, int slot)
1248{
1249 struct dvb_usb_device *d = ci->data;
1250 int ret;
1251
1252 ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80);
1253 if (ret)
1254 return ret;
1255
1256 msleep(30);
1257
1258 ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
1259 if (ret)
1260 return ret;
1261
1262 return 0;
1263}
1264
1265static int anysee_ci_slot_ts_enable(struct dvb_ca_en50221 *ci, int slot)
1266{
1267 struct dvb_usb_device *d = ci->data;
1268 int ret;
1269
1270 ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 1), 0x02);
1271 if (ret)
1272 return ret;
1273
1274 return 0;
1275}
1276
1277static int anysee_ci_poll_slot_status(struct dvb_ca_en50221 *ci, int slot,
1278 int open)
1279{
1280 struct dvb_usb_device *d = ci->data;
Antti Palosaari05cd62e2012-06-18 19:39:02 -03001281 struct anysee_state *state = d_to_priv(d);
Antti Palosaari05cd37d2011-09-05 23:33:04 -03001282 int ret;
Mauro Carvalho Chehab03ad9fe2012-10-27 16:28:00 -03001283 u8 tmp = 0;
Antti Palosaari05cd37d2011-09-05 23:33:04 -03001284
1285 ret = anysee_rd_reg_mask(d, REG_IOC, &tmp, 0x40);
1286 if (ret)
1287 return ret;
1288
1289 if (tmp == 0) {
1290 ret = DVB_CA_EN50221_POLL_CAM_PRESENT;
1291 if (time_after(jiffies, state->ci_cam_ready))
1292 ret |= DVB_CA_EN50221_POLL_CAM_READY;
1293 }
1294
1295 return ret;
1296}
1297
1298static int anysee_ci_init(struct dvb_usb_device *d)
1299{
Antti Palosaari05cd62e2012-06-18 19:39:02 -03001300 struct anysee_state *state = d_to_priv(d);
Antti Palosaari05cd37d2011-09-05 23:33:04 -03001301 int ret;
1302
1303 state->ci.owner = THIS_MODULE;
1304 state->ci.read_attribute_mem = anysee_ci_read_attribute_mem;
1305 state->ci.write_attribute_mem = anysee_ci_write_attribute_mem;
1306 state->ci.read_cam_control = anysee_ci_read_cam_control;
1307 state->ci.write_cam_control = anysee_ci_write_cam_control;
1308 state->ci.slot_reset = anysee_ci_slot_reset;
1309 state->ci.slot_shutdown = anysee_ci_slot_shutdown;
1310 state->ci.slot_ts_enable = anysee_ci_slot_ts_enable;
1311 state->ci.poll_slot_status = anysee_ci_poll_slot_status;
1312 state->ci.data = d;
1313
1314 ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
1315 if (ret)
1316 return ret;
1317
Antti Palosaari46de20a2012-01-20 17:39:17 -03001318 ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 2)|(0 << 1)|(0 << 0), 0x07);
1319 if (ret)
1320 return ret;
1321
1322 ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 2)|(1 << 1)|(1 << 0), 0x07);
1323 if (ret)
1324 return ret;
1325
Antti Palosaari05cd37d2011-09-05 23:33:04 -03001326 ret = dvb_ca_en50221_init(&d->adapter[0].dvb_adap, &state->ci, 0, 1);
1327 if (ret)
1328 return ret;
1329
Antti Palosaarif6068762012-09-22 13:46:24 -03001330 state->ci_attached = true;
1331
Antti Palosaari05cd37d2011-09-05 23:33:04 -03001332 return 0;
1333}
1334
1335static void anysee_ci_release(struct dvb_usb_device *d)
1336{
Antti Palosaari05cd62e2012-06-18 19:39:02 -03001337 struct anysee_state *state = d_to_priv(d);
Antti Palosaari05cd37d2011-09-05 23:33:04 -03001338
1339 /* detach CI */
Antti Palosaarif6068762012-09-22 13:46:24 -03001340 if (state->ci_attached)
Antti Palosaari05cd37d2011-09-05 23:33:04 -03001341 dvb_ca_en50221_release(&state->ci);
1342
1343 return;
1344}
1345
1346static int anysee_init(struct dvb_usb_device *d)
1347{
Antti Palosaari05cd62e2012-06-18 19:39:02 -03001348 struct anysee_state *state = d_to_priv(d);
Antti Palosaari05cd37d2011-09-05 23:33:04 -03001349 int ret;
1350
Antti Palosaaria4e7c512012-06-14 04:56:09 -03001351 /* There is one interface with two alternate settings.
1352 Alternate setting 0 is for bulk transfer.
1353 Alternate setting 1 is for isochronous transfer.
1354 We use bulk transfer (alternate setting 0). */
1355 ret = usb_set_interface(d->udev, 0, 0);
1356 if (ret)
1357 return ret;
1358
Antti Palosaari05cd37d2011-09-05 23:33:04 -03001359 /* LED light */
1360 ret = anysee_led_ctrl(d, 0x01, 0x03);
1361 if (ret)
1362 return ret;
1363
1364 /* enable IR */
1365 ret = anysee_ir_ctrl(d, 1);
1366 if (ret)
1367 return ret;
1368
1369 /* attach CI */
1370 if (state->has_ci) {
1371 ret = anysee_ci_init(d);
Antti Palosaarif6068762012-09-22 13:46:24 -03001372 if (ret)
Antti Palosaari05cd37d2011-09-05 23:33:04 -03001373 return ret;
Antti Palosaari05cd37d2011-09-05 23:33:04 -03001374 }
1375
1376 return 0;
1377}
1378
Antti Palosaari831511b2012-06-20 00:32:53 -03001379static void anysee_exit(struct dvb_usb_device *d)
Antti Palosaaria4e7c512012-06-14 04:56:09 -03001380{
Antti Palosaarif80f2ae2014-08-03 21:47:10 -03001381 struct anysee_state *state = d_to_priv(d);
1382
1383 if (state->i2c_client[0])
1384 anysee_del_i2c_dev(d);
1385
Antti Palosaaria4e7c512012-06-14 04:56:09 -03001386 return anysee_ci_release(d);
1387}
1388
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001389/* DVB USB Driver stuff */
Antti Palosaaria4e7c512012-06-14 04:56:09 -03001390static struct dvb_usb_device_properties anysee_props = {
1391 .driver_name = KBUILD_MODNAME,
1392 .owner = THIS_MODULE,
1393 .adapter_nr = adapter_nr,
1394 .size_of_priv = sizeof(struct anysee_state),
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001395
Antti Palosaaria4e7c512012-06-14 04:56:09 -03001396 .generic_bulk_ctrl_endpoint = 0x01,
1397 .generic_bulk_ctrl_endpoint_response = 0x81,
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001398
Antti Palosaaria4e7c512012-06-14 04:56:09 -03001399 .i2c_algo = &anysee_i2c_algo,
1400 .read_config = anysee_read_config,
1401 .frontend_attach = anysee_frontend_attach,
1402 .tuner_attach = anysee_tuner_attach,
1403 .init = anysee_init,
1404 .get_rc_config = anysee_get_rc_config,
1405 .frontend_ctrl = anysee_frontend_ctrl,
1406 .streaming_ctrl = anysee_streaming_ctrl,
Antti Palosaari831511b2012-06-20 00:32:53 -03001407 .exit = anysee_exit,
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001408
1409 .num_adapters = 1,
1410 .adapter = {
1411 {
Antti Palosaari05cd62e2012-06-18 19:39:02 -03001412 .stream = DVB_USB_STREAM_BULK(0x82, 8, 16 * 512),
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001413 }
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001414 }
1415};
1416
Antti Palosaaria4e7c512012-06-14 04:56:09 -03001417static const struct usb_device_id anysee_id_table[] = {
1418 { DVB_USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE,
1419 &anysee_props, "Anysee", RC_MAP_ANYSEE) },
1420 { DVB_USB_DEVICE(USB_VID_AMT, USB_PID_ANYSEE,
1421 &anysee_props, "Anysee", RC_MAP_ANYSEE) },
1422 { }
1423};
1424MODULE_DEVICE_TABLE(usb, anysee_id_table);
1425
1426static struct usb_driver anysee_usb_driver = {
1427 .name = KBUILD_MODNAME,
1428 .id_table = anysee_id_table,
1429 .probe = dvb_usbv2_probe,
1430 .disconnect = dvb_usbv2_disconnect,
1431 .suspend = dvb_usbv2_suspend,
1432 .resume = dvb_usbv2_resume,
Antti Palosaari04966aa2012-08-14 22:21:08 -03001433 .reset_resume = dvb_usbv2_reset_resume,
Antti Palosaaria4e7c512012-06-14 04:56:09 -03001434 .no_dynamic_id = 1,
1435 .soft_unbind = 1,
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001436};
1437
Antti Palosaaria4e7c512012-06-14 04:56:09 -03001438module_usb_driver(anysee_usb_driver);
Antti Palosaaria51e34d2008-05-17 23:05:48 -03001439
1440MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
1441MODULE_DESCRIPTION("Driver Anysee E30 DVB-C & DVB-T USB2.0");
1442MODULE_LICENSE("GPL");