Commit | Line | Data |
---|---|---|
04b8b21d MP |
1 | /* |
2 | * DVB USB compliant linux driver for ITE IT9135 and IT9137 | |
3 | * | |
4 | * Copyright (C) 2011 Malcolm Priestley (tvboxspy@gmail.com) | |
5 | * IT9135 (C) ITE Tech Inc. | |
6 | * IT9137 (C) ITE Tech Inc. | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or modify | |
9 | * it under the terms of the GNU General Public License Version 2, as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This program is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with this program; if not, write to the Free Software | |
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
20 | * | |
21 | * | |
22 | * see Documentation/dvb/README.dvb-usb for more information | |
23 | * see Documentation/dvb/it9137.txt for firmware information | |
24 | * | |
25 | */ | |
26 | #define DVB_USB_LOG_PREFIX "it913x" | |
27 | ||
28 | #include <linux/usb.h> | |
29 | #include <linux/usb/input.h> | |
30 | #include <media/rc-core.h> | |
31 | ||
32 | #include "dvb_usb.h" | |
33 | #include "it913x-fe.h" | |
34 | ||
35 | /* debug */ | |
36 | static int dvb_usb_it913x_debug; | |
37 | #define it_debug(var, level, args...) \ | |
38 | do { if ((var & level)) pr_debug(DVB_USB_LOG_PREFIX": " args); \ | |
39 | } while (0) | |
40 | #define deb_info(level, args...) it_debug(dvb_usb_it913x_debug, level, args) | |
41 | #define info(args...) pr_info(DVB_USB_LOG_PREFIX": " args) | |
42 | ||
43 | module_param_named(debug, dvb_usb_it913x_debug, int, 0644); | |
44 | MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able))."); | |
45 | ||
46 | static int dvb_usb_it913x_firmware; | |
47 | module_param_named(firmware, dvb_usb_it913x_firmware, int, 0644); | |
a7fab851 | 48 | MODULE_PARM_DESC(firmware, "set firmware 0=auto "\ |
04b8b21d MP |
49 | "1=IT9137 2=IT9135 V1 3=IT9135 V2"); |
50 | #define FW_IT9137 "dvb-usb-it9137-01.fw" | |
51 | #define FW_IT9135_V1 "dvb-usb-it9135-01.fw" | |
52 | #define FW_IT9135_V2 "dvb-usb-it9135-02.fw" | |
53 | ||
54 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | |
55 | ||
56 | struct it913x_state { | |
57 | struct ite_config it913x_config; | |
58 | u8 pid_filter_onoff; | |
59 | bool proprietary_ir; | |
60 | int cmd_counter; | |
61 | }; | |
62 | ||
63 | static u16 check_sum(u8 *p, u8 len) | |
64 | { | |
65 | u16 sum = 0; | |
66 | u8 i = 1; | |
67 | while (i < len) | |
68 | sum += (i++ & 1) ? (*p++) << 8 : *p++; | |
69 | return ~sum; | |
70 | } | |
71 | ||
72 | static int it913x_io(struct dvb_usb_device *d, u8 mode, u8 pro, | |
73 | u8 cmd, u32 reg, u8 addr, u8 *data, u8 len) | |
74 | { | |
75 | struct it913x_state *st = d->priv; | |
76 | int ret = 0, i, buf_size = 1; | |
77 | u8 *buff; | |
78 | u8 rlen; | |
79 | u16 chk_sum; | |
80 | ||
81 | buff = kzalloc(256, GFP_KERNEL); | |
82 | if (!buff) { | |
83 | info("USB Buffer Failed"); | |
84 | return -ENOMEM; | |
85 | } | |
86 | ||
87 | buff[buf_size++] = pro; | |
88 | buff[buf_size++] = cmd; | |
89 | buff[buf_size++] = st->cmd_counter; | |
90 | ||
91 | switch (mode) { | |
92 | case READ_LONG: | |
93 | case WRITE_LONG: | |
94 | buff[buf_size++] = len; | |
95 | buff[buf_size++] = 2; | |
96 | buff[buf_size++] = (reg >> 24); | |
97 | buff[buf_size++] = (reg >> 16) & 0xff; | |
98 | buff[buf_size++] = (reg >> 8) & 0xff; | |
99 | buff[buf_size++] = reg & 0xff; | |
100 | break; | |
101 | case READ_SHORT: | |
102 | buff[buf_size++] = addr; | |
103 | break; | |
104 | case WRITE_SHORT: | |
105 | buff[buf_size++] = len; | |
106 | buff[buf_size++] = addr; | |
107 | buff[buf_size++] = (reg >> 8) & 0xff; | |
108 | buff[buf_size++] = reg & 0xff; | |
109 | break; | |
110 | case READ_DATA: | |
111 | case WRITE_DATA: | |
112 | break; | |
113 | case WRITE_CMD: | |
114 | mode = 7; | |
115 | break; | |
116 | default: | |
117 | kfree(buff); | |
118 | return -EINVAL; | |
119 | } | |
120 | ||
121 | if (mode & 1) { | |
122 | for (i = 0; i < len ; i++) | |
123 | buff[buf_size++] = data[i]; | |
124 | } | |
125 | chk_sum = check_sum(&buff[1], buf_size); | |
126 | ||
127 | buff[buf_size++] = chk_sum >> 8; | |
128 | buff[0] = buf_size; | |
129 | buff[buf_size++] = (chk_sum & 0xff); | |
130 | ||
131 | ret = dvb_usbv2_generic_rw(d, buff, buf_size, buff, (mode & 1) ? | |
132 | 5 : len + 5); | |
133 | if (ret < 0) | |
134 | goto error; | |
135 | ||
136 | rlen = (mode & 0x1) ? 0x1 : len; | |
137 | ||
138 | if (mode & 1) | |
139 | ret = buff[2]; | |
140 | else | |
141 | memcpy(data, &buff[3], rlen); | |
142 | ||
143 | st->cmd_counter++; | |
144 | ||
145 | error: kfree(buff); | |
146 | ||
147 | return ret; | |
148 | } | |
149 | ||
150 | static int it913x_wr_reg(struct dvb_usb_device *d, u8 pro, u32 reg , u8 data) | |
151 | { | |
152 | int ret; | |
153 | u8 b[1]; | |
154 | b[0] = data; | |
155 | ret = it913x_io(d, WRITE_LONG, pro, | |
156 | CMD_DEMOD_WRITE, reg, 0, b, sizeof(b)); | |
157 | ||
158 | return ret; | |
159 | } | |
160 | ||
161 | static int it913x_read_reg(struct dvb_usb_device *d, u32 reg) | |
162 | { | |
163 | int ret; | |
164 | u8 data[1]; | |
165 | ||
166 | ret = it913x_io(d, READ_LONG, DEV_0, | |
167 | CMD_DEMOD_READ, reg, 0, &data[0], sizeof(data)); | |
168 | ||
169 | return (ret < 0) ? ret : data[0]; | |
170 | } | |
171 | ||
172 | static int it913x_query(struct dvb_usb_device *d, u8 pro) | |
173 | { | |
174 | struct it913x_state *st = d->priv; | |
175 | int ret, i; | |
176 | u8 data[4]; | |
177 | u8 ver; | |
178 | ||
179 | for (i = 0; i < 5; i++) { | |
180 | ret = it913x_io(d, READ_LONG, pro, CMD_DEMOD_READ, | |
181 | 0x1222, 0, &data[0], 3); | |
182 | ver = data[0]; | |
183 | if (ver > 0 && ver < 3) | |
184 | break; | |
185 | msleep(100); | |
186 | } | |
187 | ||
188 | if (ver < 1 || ver > 2) { | |
189 | info("Failed to identify chip version applying 1"); | |
190 | st->it913x_config.chip_ver = 0x1; | |
191 | st->it913x_config.chip_type = 0x9135; | |
192 | return 0; | |
193 | } | |
194 | ||
195 | st->it913x_config.chip_ver = ver; | |
196 | st->it913x_config.chip_type = (u16)(data[2] << 8) + data[1]; | |
197 | ||
198 | info("Chip Version=%02x Chip Type=%04x", st->it913x_config.chip_ver, | |
199 | st->it913x_config.chip_type); | |
200 | ||
201 | ret = it913x_io(d, READ_SHORT, pro, | |
202 | CMD_QUERYINFO, 0, 0x1, &data[0], 4); | |
203 | ||
204 | st->it913x_config.firmware = (data[0] << 24) | (data[1] << 16) | | |
205 | (data[2] << 8) | data[3]; | |
206 | ||
207 | return ret; | |
208 | } | |
209 | ||
210 | static int it913x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff) | |
211 | { | |
212 | struct dvb_usb_device *d = adap_to_d(adap); | |
213 | struct it913x_state *st = adap_to_priv(adap); | |
214 | int ret; | |
215 | u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD; | |
216 | ||
217 | mutex_lock(&d->i2c_mutex); | |
218 | ||
219 | deb_info(1, "PID_C (%02x)", onoff); | |
220 | ||
b09e71a8 | 221 | st->pid_filter_onoff = adap->pid_filtering; |
04b8b21d MP |
222 | ret = it913x_wr_reg(d, pro, PID_EN, st->pid_filter_onoff); |
223 | ||
224 | mutex_unlock(&d->i2c_mutex); | |
225 | return ret; | |
226 | } | |
227 | ||
228 | static int it913x_pid_filter(struct dvb_usb_adapter *adap, | |
229 | int index, u16 pid, int onoff) | |
230 | { | |
231 | struct dvb_usb_device *d = adap_to_d(adap); | |
232 | struct it913x_state *st = adap_to_priv(adap); | |
233 | int ret; | |
234 | u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD; | |
235 | ||
236 | mutex_lock(&d->i2c_mutex); | |
237 | ||
238 | deb_info(1, "PID_F (%02x)", onoff); | |
239 | ||
240 | ret = it913x_wr_reg(d, pro, PID_LSB, (u8)(pid & 0xff)); | |
241 | ||
242 | ret |= it913x_wr_reg(d, pro, PID_MSB, (u8)(pid >> 8)); | |
243 | ||
244 | ret |= it913x_wr_reg(d, pro, PID_INX_EN, (u8)onoff); | |
245 | ||
246 | ret |= it913x_wr_reg(d, pro, PID_INX, (u8)(index & 0x1f)); | |
247 | ||
248 | if (d->udev->speed == USB_SPEED_HIGH && pid == 0x2000) { | |
249 | ret |= it913x_wr_reg(d , pro, PID_EN, !onoff); | |
250 | st->pid_filter_onoff = !onoff; | |
251 | } else | |
252 | st->pid_filter_onoff = | |
253 | adap->pid_filtering; | |
254 | ||
255 | mutex_unlock(&d->i2c_mutex); | |
256 | return 0; | |
257 | } | |
258 | ||
259 | ||
260 | static int it913x_return_status(struct dvb_usb_device *d) | |
261 | { | |
262 | struct it913x_state *st = d->priv; | |
263 | int ret = it913x_query(d, DEV_0); | |
264 | if (st->it913x_config.firmware > 0) | |
265 | info("Firmware Version %d", st->it913x_config.firmware); | |
266 | ||
267 | return ret; | |
268 | } | |
269 | ||
270 | static int it913x_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], | |
271 | int num) | |
272 | { | |
273 | struct dvb_usb_device *d = i2c_get_adapdata(adap); | |
274 | static u8 data[256]; | |
275 | int ret; | |
276 | u32 reg; | |
277 | u8 pro; | |
278 | ||
279 | mutex_lock(&d->i2c_mutex); | |
280 | ||
281 | deb_info(2, "num of messages %d address %02x", num, msg[0].addr); | |
282 | ||
283 | pro = (msg[0].addr & 0x2) ? DEV_0_DMOD : 0x0; | |
284 | pro |= (msg[0].addr & 0x20) ? DEV_1 : DEV_0; | |
285 | memcpy(data, msg[0].buf, msg[0].len); | |
286 | reg = (data[0] << 24) + (data[1] << 16) + | |
287 | (data[2] << 8) + data[3]; | |
288 | if (num == 2) { | |
289 | ret = it913x_io(d, READ_LONG, pro, | |
290 | CMD_DEMOD_READ, reg, 0, data, msg[1].len); | |
291 | memcpy(msg[1].buf, data, msg[1].len); | |
292 | } else | |
293 | ret = it913x_io(d, WRITE_LONG, pro, CMD_DEMOD_WRITE, | |
294 | reg, 0, &data[4], msg[0].len - 4); | |
295 | ||
296 | mutex_unlock(&d->i2c_mutex); | |
297 | ||
298 | return ret; | |
299 | } | |
300 | ||
301 | static u32 it913x_i2c_func(struct i2c_adapter *adapter) | |
302 | { | |
303 | return I2C_FUNC_I2C; | |
304 | } | |
305 | ||
306 | static struct i2c_algorithm it913x_i2c_algo = { | |
307 | .master_xfer = it913x_i2c_xfer, | |
308 | .functionality = it913x_i2c_func, | |
309 | }; | |
310 | ||
311 | /* Callbacks for DVB USB */ | |
37b44a0f | 312 | #if IS_ENABLED(CONFIG_RC_CORE) |
04b8b21d MP |
313 | static int it913x_rc_query(struct dvb_usb_device *d) |
314 | { | |
315 | u8 ibuf[4]; | |
316 | int ret; | |
317 | u32 key; | |
318 | /* Avoid conflict with frontends*/ | |
319 | mutex_lock(&d->i2c_mutex); | |
320 | ||
321 | ret = it913x_io(d, READ_LONG, PRO_LINK, CMD_IR_GET, | |
322 | 0, 0, &ibuf[0], sizeof(ibuf)); | |
323 | ||
324 | if ((ibuf[2] + ibuf[3]) == 0xff) { | |
325 | key = ibuf[2]; | |
326 | key += ibuf[0] << 16; | |
327 | key += ibuf[1] << 8; | |
328 | deb_info(1, "NEC Extended Key =%08x", key); | |
329 | if (d->rc_dev != NULL) | |
330 | rc_keydown(d->rc_dev, key, 0); | |
331 | } | |
332 | ||
333 | mutex_unlock(&d->i2c_mutex); | |
334 | ||
335 | return ret; | |
336 | } | |
337 | ||
b963c208 AP |
338 | static int it913x_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc) |
339 | { | |
340 | struct it913x_state *st = d->priv; | |
341 | ||
342 | if (st->proprietary_ir == false) { | |
343 | rc->map_name = NULL; | |
344 | return 0; | |
345 | } | |
346 | ||
347 | rc->allowed_protos = RC_BIT_NEC; | |
348 | rc->query = it913x_rc_query; | |
349 | rc->interval = 250; | |
350 | ||
351 | return 0; | |
352 | } | |
353 | #else | |
354 | #define it913x_get_rc_config NULL | |
355 | #endif | |
356 | ||
04b8b21d MP |
357 | /* Firmware sets raw */ |
358 | static const char fw_it9135_v1[] = FW_IT9135_V1; | |
359 | static const char fw_it9135_v2[] = FW_IT9135_V2; | |
360 | static const char fw_it9137[] = FW_IT9137; | |
361 | ||
362 | static void ite_get_firmware_name(struct dvb_usb_device *d, | |
363 | const char **name) | |
364 | { | |
365 | struct it913x_state *st = d->priv; | |
366 | int sw; | |
367 | /* auto switch */ | |
368 | if (le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_KWORLD_2) | |
369 | sw = IT9137_FW; | |
370 | else if (st->it913x_config.chip_ver == 1) | |
371 | sw = IT9135_V1_FW; | |
372 | else | |
373 | sw = IT9135_V2_FW; | |
374 | ||
375 | /* force switch */ | |
376 | if (dvb_usb_it913x_firmware != IT9135_AUTO) | |
377 | sw = dvb_usb_it913x_firmware; | |
378 | ||
379 | switch (sw) { | |
380 | case IT9135_V1_FW: | |
381 | st->it913x_config.firmware_ver = 1; | |
382 | st->it913x_config.adc_x2 = 1; | |
383 | st->it913x_config.read_slevel = false; | |
384 | *name = fw_it9135_v1; | |
385 | break; | |
386 | case IT9135_V2_FW: | |
387 | st->it913x_config.firmware_ver = 1; | |
388 | st->it913x_config.adc_x2 = 1; | |
389 | st->it913x_config.read_slevel = false; | |
390 | *name = fw_it9135_v2; | |
391 | switch (st->it913x_config.tuner_id_0) { | |
392 | case IT9135_61: | |
393 | case IT9135_62: | |
394 | break; | |
395 | default: | |
396 | info("Unknown tuner ID applying default 0x60"); | |
397 | case IT9135_60: | |
398 | st->it913x_config.tuner_id_0 = IT9135_60; | |
399 | } | |
400 | break; | |
401 | case IT9137_FW: | |
402 | default: | |
403 | st->it913x_config.firmware_ver = 0; | |
404 | st->it913x_config.adc_x2 = 0; | |
405 | st->it913x_config.read_slevel = true; | |
406 | *name = fw_it9137; | |
407 | } | |
408 | ||
409 | return; | |
410 | } | |
411 | ||
412 | #define TS_MPEG_PKT_SIZE 188 | |
413 | #define EP_LOW 21 | |
414 | #define TS_BUFFER_SIZE_PID (EP_LOW*TS_MPEG_PKT_SIZE) | |
415 | #define EP_HIGH 348 | |
416 | #define TS_BUFFER_SIZE_MAX (EP_HIGH*TS_MPEG_PKT_SIZE) | |
417 | ||
418 | static int it913x_get_stream_config(struct dvb_frontend *fe, u8 *ts_type, | |
419 | struct usb_data_stream_properties *stream) | |
420 | { | |
421 | struct dvb_usb_adapter *adap = fe_to_adap(fe); | |
422 | if (adap->pid_filtering) | |
423 | stream->u.bulk.buffersize = TS_BUFFER_SIZE_PID; | |
424 | else | |
425 | stream->u.bulk.buffersize = TS_BUFFER_SIZE_MAX; | |
426 | ||
427 | return 0; | |
428 | } | |
429 | ||
430 | static int it913x_select_config(struct dvb_usb_device *d) | |
431 | { | |
432 | struct it913x_state *st = d->priv; | |
433 | int ret, reg; | |
434 | ||
435 | ret = it913x_return_status(d); | |
436 | if (ret < 0) | |
437 | return ret; | |
438 | ||
439 | if (st->it913x_config.chip_ver == 0x02 | |
440 | && st->it913x_config.chip_type == 0x9135) | |
441 | reg = it913x_read_reg(d, 0x461d); | |
442 | else | |
443 | reg = it913x_read_reg(d, 0x461b); | |
444 | ||
445 | if (reg < 0) | |
446 | return reg; | |
447 | ||
448 | if (reg == 0) { | |
449 | st->it913x_config.dual_mode = 0; | |
450 | st->it913x_config.tuner_id_0 = IT9135_38; | |
451 | st->proprietary_ir = true; | |
452 | } else { | |
453 | /* TS mode */ | |
454 | reg = it913x_read_reg(d, 0x49c5); | |
455 | if (reg < 0) | |
456 | return reg; | |
457 | st->it913x_config.dual_mode = reg; | |
458 | ||
459 | /* IR mode type */ | |
460 | reg = it913x_read_reg(d, 0x49ac); | |
461 | if (reg < 0) | |
462 | return reg; | |
463 | if (reg == 5) { | |
464 | info("Remote propriety (raw) mode"); | |
465 | st->proprietary_ir = true; | |
466 | } else if (reg == 1) { | |
467 | info("Remote HID mode NOT SUPPORTED"); | |
468 | st->proprietary_ir = false; | |
469 | } | |
470 | ||
471 | /* Tuner_id */ | |
472 | reg = it913x_read_reg(d, 0x49d0); | |
473 | if (reg < 0) | |
474 | return reg; | |
475 | st->it913x_config.tuner_id_0 = reg; | |
476 | } | |
477 | ||
478 | info("Dual mode=%x Tuner Type=%x", st->it913x_config.dual_mode, | |
479 | st->it913x_config.tuner_id_0); | |
480 | ||
481 | return ret; | |
482 | } | |
483 | ||
484 | static int it913x_streaming_ctrl(struct dvb_frontend *fe, int onoff) | |
485 | { | |
486 | struct dvb_usb_adapter *adap = fe_to_adap(fe); | |
487 | struct dvb_usb_device *d = adap_to_d(adap); | |
488 | struct it913x_state *st = fe_to_priv(fe); | |
489 | int ret = 0; | |
490 | u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD; | |
491 | ||
492 | deb_info(1, "STM (%02x)", onoff); | |
493 | ||
494 | if (!onoff) { | |
495 | mutex_lock(&d->i2c_mutex); | |
496 | ||
497 | ret = it913x_wr_reg(d, pro, PID_RST, 0x1); | |
498 | ||
499 | mutex_unlock(&d->i2c_mutex); | |
500 | st->pid_filter_onoff = | |
501 | adap->pid_filtering; | |
502 | ||
503 | } | |
504 | ||
505 | return ret; | |
506 | } | |
507 | ||
508 | static int it913x_identify_state(struct dvb_usb_device *d, const char **name) | |
509 | { | |
510 | struct it913x_state *st = d->priv; | |
511 | int ret; | |
512 | u8 reg; | |
513 | ||
514 | /* Read and select config */ | |
515 | ret = it913x_select_config(d); | |
516 | if (ret < 0) | |
517 | return ret; | |
518 | ||
519 | ite_get_firmware_name(d, name); | |
520 | ||
521 | if (st->it913x_config.firmware > 0) | |
522 | return WARM; | |
523 | ||
524 | if (st->it913x_config.dual_mode) { | |
525 | st->it913x_config.tuner_id_1 = it913x_read_reg(d, 0x49e0); | |
526 | ret = it913x_wr_reg(d, DEV_0, GPIOH1_EN, 0x1); | |
527 | ret |= it913x_wr_reg(d, DEV_0, GPIOH1_ON, 0x1); | |
528 | ret |= it913x_wr_reg(d, DEV_0, GPIOH1_O, 0x1); | |
529 | msleep(50); | |
530 | ret |= it913x_wr_reg(d, DEV_0, GPIOH1_O, 0x0); | |
531 | msleep(50); | |
532 | reg = it913x_read_reg(d, GPIOH1_O); | |
533 | if (reg == 0) { | |
534 | ret |= it913x_wr_reg(d, DEV_0, GPIOH1_O, 0x1); | |
535 | ret |= it913x_return_status(d); | |
536 | if (ret != 0) | |
537 | ret = it913x_wr_reg(d, DEV_0, | |
538 | GPIOH1_O, 0x0); | |
539 | } | |
540 | } | |
541 | ||
542 | reg = it913x_read_reg(d, IO_MUX_POWER_CLK); | |
543 | ||
544 | if (st->it913x_config.dual_mode) { | |
545 | ret |= it913x_wr_reg(d, DEV_0, 0x4bfb, CHIP2_I2C_ADDR); | |
546 | if (st->it913x_config.firmware_ver == 1) | |
547 | ret |= it913x_wr_reg(d, DEV_0, 0xcfff, 0x1); | |
548 | else | |
549 | ret |= it913x_wr_reg(d, DEV_0, CLK_O_EN, 0x1); | |
550 | } else { | |
551 | ret |= it913x_wr_reg(d, DEV_0, 0x4bfb, 0x0); | |
552 | if (st->it913x_config.firmware_ver == 1) | |
553 | ret |= it913x_wr_reg(d, DEV_0, 0xcfff, 0x0); | |
554 | else | |
555 | ret |= it913x_wr_reg(d, DEV_0, CLK_O_EN, 0x0); | |
556 | } | |
557 | ||
558 | ret |= it913x_wr_reg(d, DEV_0, I2C_CLK, I2C_CLK_100); | |
559 | ||
560 | return (ret < 0) ? ret : COLD; | |
561 | } | |
562 | ||
563 | static int it913x_download_firmware(struct dvb_usb_device *d, | |
564 | const struct firmware *fw) | |
565 | { | |
566 | struct it913x_state *st = d->priv; | |
567 | int ret = 0, i = 0, pos = 0; | |
568 | u8 packet_size, min_pkt; | |
569 | u8 *fw_data; | |
570 | ||
571 | ret = it913x_wr_reg(d, DEV_0, I2C_CLK, I2C_CLK_100); | |
572 | ||
573 | info("FRM Starting Firmware Download"); | |
574 | ||
575 | /* Multi firmware loader */ | |
576 | /* This uses scatter write firmware headers */ | |
577 | /* The firmware must start with 03 XX 00 */ | |
578 | /* and be the extact firmware length */ | |
579 | ||
580 | if (st->it913x_config.chip_ver == 2) | |
581 | min_pkt = 0x11; | |
582 | else | |
583 | min_pkt = 0x19; | |
584 | ||
585 | while (i <= fw->size) { | |
586 | if (((fw->data[i] == 0x3) && (fw->data[i + 2] == 0x0)) | |
587 | || (i == fw->size)) { | |
588 | packet_size = i - pos; | |
589 | if ((packet_size > min_pkt) || (i == fw->size)) { | |
590 | fw_data = (u8 *)(fw->data + pos); | |
591 | pos += packet_size; | |
592 | if (packet_size > 0) { | |
593 | ret = it913x_io(d, WRITE_DATA, | |
594 | DEV_0, CMD_SCATTER_WRITE, 0, | |
595 | 0, fw_data, packet_size); | |
596 | if (ret < 0) | |
597 | break; | |
598 | } | |
599 | udelay(1000); | |
600 | } | |
601 | } | |
602 | i++; | |
603 | } | |
604 | ||
605 | if (ret < 0) | |
606 | info("FRM Firmware Download Failed (%d)" , ret); | |
607 | else | |
608 | info("FRM Firmware Download Completed - Resetting Device"); | |
609 | ||
610 | msleep(30); | |
611 | ||
612 | ret = it913x_io(d, WRITE_CMD, DEV_0, CMD_BOOT, 0, 0, NULL, 0); | |
613 | if (ret < 0) | |
614 | info("FRM Device not responding to reboot"); | |
615 | ||
616 | ret = it913x_return_status(d); | |
617 | if (st->it913x_config.firmware == 0) { | |
618 | info("FRM Failed to reboot device"); | |
619 | return -ENODEV; | |
620 | } | |
621 | ||
622 | msleep(30); | |
623 | ||
624 | ret = it913x_wr_reg(d, DEV_0, I2C_CLK, I2C_CLK_400); | |
625 | ||
626 | msleep(30); | |
627 | ||
628 | /* Tuner function */ | |
629 | if (st->it913x_config.dual_mode) | |
630 | ret |= it913x_wr_reg(d, DEV_0_DMOD , 0xec4c, 0xa0); | |
631 | else | |
632 | ret |= it913x_wr_reg(d, DEV_0_DMOD , 0xec4c, 0x68); | |
633 | ||
634 | if ((st->it913x_config.chip_ver == 1) && | |
635 | (st->it913x_config.chip_type == 0x9135)) { | |
636 | ret |= it913x_wr_reg(d, DEV_0, PADODPU, 0x0); | |
637 | ret |= it913x_wr_reg(d, DEV_0, AGC_O_D, 0x0); | |
638 | if (st->it913x_config.dual_mode) { | |
639 | ret |= it913x_wr_reg(d, DEV_1, PADODPU, 0x0); | |
640 | ret |= it913x_wr_reg(d, DEV_1, AGC_O_D, 0x0); | |
641 | } | |
642 | } | |
643 | ||
644 | return (ret < 0) ? -ENODEV : 0; | |
645 | } | |
646 | ||
647 | static int it913x_name(struct dvb_usb_adapter *adap) | |
648 | { | |
649 | struct dvb_usb_device *d = adap_to_d(adap); | |
650 | const char *desc = d->name; | |
651 | char *fe_name[] = {"_1", "_2", "_3", "_4"}; | |
652 | char *name = adap->fe[0]->ops.info.name; | |
653 | ||
654 | strlcpy(name, desc, 128); | |
655 | strlcat(name, fe_name[adap->id], 128); | |
656 | ||
657 | return 0; | |
658 | } | |
659 | ||
660 | static int it913x_frontend_attach(struct dvb_usb_adapter *adap) | |
661 | { | |
662 | struct dvb_usb_device *d = adap_to_d(adap); | |
663 | struct it913x_state *st = d->priv; | |
664 | int ret = 0; | |
665 | u8 adap_addr = I2C_BASE_ADDR + (adap->id << 5); | |
341068fc MP |
666 | u16 ep_size = (adap->pid_filtering) ? TS_BUFFER_SIZE_PID / 4 : |
667 | TS_BUFFER_SIZE_MAX / 4; | |
04b8b21d MP |
668 | u8 pkt_size = 0x80; |
669 | ||
670 | if (d->udev->speed != USB_SPEED_HIGH) | |
671 | pkt_size = 0x10; | |
672 | ||
673 | st->it913x_config.adf = it913x_read_reg(d, IO_MUX_POWER_CLK); | |
674 | ||
675 | adap->fe[0] = dvb_attach(it913x_fe_attach, | |
676 | &d->i2c_adap, adap_addr, &st->it913x_config); | |
677 | ||
678 | if (adap->id == 0 && adap->fe[0]) { | |
679 | it913x_wr_reg(d, DEV_0_DMOD, MP2_SW_RST, 0x1); | |
680 | it913x_wr_reg(d, DEV_0_DMOD, MP2IF2_SW_RST, 0x1); | |
681 | it913x_wr_reg(d, DEV_0, EP0_TX_EN, 0x0f); | |
682 | it913x_wr_reg(d, DEV_0, EP0_TX_NAK, 0x1b); | |
8e216e50 MP |
683 | if (st->proprietary_ir == false) /* Enable endpoint 3 */ |
684 | it913x_wr_reg(d, DEV_0, EP0_TX_EN, 0x3f); | |
685 | else | |
686 | it913x_wr_reg(d, DEV_0, EP0_TX_EN, 0x2f); | |
04b8b21d MP |
687 | it913x_wr_reg(d, DEV_0, EP4_TX_LEN_LSB, |
688 | ep_size & 0xff); | |
689 | it913x_wr_reg(d, DEV_0, EP4_TX_LEN_MSB, ep_size >> 8); | |
690 | ret = it913x_wr_reg(d, DEV_0, EP4_MAX_PKT, pkt_size); | |
691 | } else if (adap->id == 1 && adap->fe[0]) { | |
8e216e50 MP |
692 | if (st->proprietary_ir == false) |
693 | it913x_wr_reg(d, DEV_0, EP0_TX_EN, 0x7f); | |
694 | else | |
695 | it913x_wr_reg(d, DEV_0, EP0_TX_EN, 0x6f); | |
04b8b21d MP |
696 | it913x_wr_reg(d, DEV_0, EP5_TX_LEN_LSB, |
697 | ep_size & 0xff); | |
698 | it913x_wr_reg(d, DEV_0, EP5_TX_LEN_MSB, ep_size >> 8); | |
699 | it913x_wr_reg(d, DEV_0, EP5_MAX_PKT, pkt_size); | |
700 | it913x_wr_reg(d, DEV_0_DMOD, MP2IF2_EN, 0x1); | |
701 | it913x_wr_reg(d, DEV_1_DMOD, MP2IF_SERIAL, 0x1); | |
702 | it913x_wr_reg(d, DEV_1, TOP_HOSTB_SER_MODE, 0x1); | |
703 | it913x_wr_reg(d, DEV_0_DMOD, TSIS_ENABLE, 0x1); | |
704 | it913x_wr_reg(d, DEV_0_DMOD, MP2_SW_RST, 0x0); | |
705 | it913x_wr_reg(d, DEV_0_DMOD, MP2IF2_SW_RST, 0x0); | |
706 | it913x_wr_reg(d, DEV_0_DMOD, MP2IF2_HALF_PSB, 0x0); | |
707 | it913x_wr_reg(d, DEV_0_DMOD, MP2IF_STOP_EN, 0x1); | |
708 | it913x_wr_reg(d, DEV_1_DMOD, MPEG_FULL_SPEED, 0x0); | |
709 | ret = it913x_wr_reg(d, DEV_1_DMOD, MP2IF_STOP_EN, 0x0); | |
710 | } else | |
711 | return -ENODEV; | |
712 | ||
713 | ret |= it913x_name(adap); | |
714 | ||
715 | return ret; | |
716 | } | |
717 | ||
718 | /* DVB USB Driver */ | |
04b8b21d MP |
719 | static int it913x_get_adapter_count(struct dvb_usb_device *d) |
720 | { | |
721 | struct it913x_state *st = d->priv; | |
722 | if (st->it913x_config.dual_mode) | |
723 | return 2; | |
724 | return 1; | |
725 | } | |
726 | ||
727 | static struct dvb_usb_device_properties it913x_properties = { | |
728 | .driver_name = KBUILD_MODNAME, | |
729 | .owner = THIS_MODULE, | |
730 | .bInterfaceNumber = 0, | |
731 | .generic_bulk_ctrl_endpoint = 0x02, | |
732 | .generic_bulk_ctrl_endpoint_response = 0x81, | |
733 | ||
734 | .adapter_nr = adapter_nr, | |
735 | .size_of_priv = sizeof(struct it913x_state), | |
736 | ||
737 | .identify_state = it913x_identify_state, | |
738 | .i2c_algo = &it913x_i2c_algo, | |
739 | ||
740 | .download_firmware = it913x_download_firmware, | |
741 | ||
742 | .frontend_attach = it913x_frontend_attach, | |
743 | .get_rc_config = it913x_get_rc_config, | |
744 | .get_stream_config = it913x_get_stream_config, | |
745 | .get_adapter_count = it913x_get_adapter_count, | |
746 | .streaming_ctrl = it913x_streaming_ctrl, | |
747 | ||
748 | ||
749 | .adapter = { | |
750 | { | |
751 | .caps = DVB_USB_ADAP_HAS_PID_FILTER| | |
752 | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, | |
753 | .pid_filter_count = 32, | |
754 | .pid_filter = it913x_pid_filter, | |
755 | .pid_filter_ctrl = it913x_pid_filter_ctrl, | |
756 | .stream = | |
757 | DVB_USB_STREAM_BULK(0x84, 10, TS_BUFFER_SIZE_MAX), | |
758 | }, | |
759 | { | |
760 | .caps = DVB_USB_ADAP_HAS_PID_FILTER| | |
761 | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, | |
762 | .pid_filter_count = 32, | |
763 | .pid_filter = it913x_pid_filter, | |
764 | .pid_filter_ctrl = it913x_pid_filter_ctrl, | |
765 | .stream = | |
766 | DVB_USB_STREAM_BULK(0x85, 10, TS_BUFFER_SIZE_MAX), | |
767 | } | |
768 | } | |
769 | }; | |
770 | ||
771 | static const struct usb_device_id it913x_id_table[] = { | |
772 | { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB499_2T_T09, | |
773 | &it913x_properties, "Kworld UB499-2T T09(IT9137)", | |
774 | RC_MAP_IT913X_V1) }, | |
04b8b21d MP |
775 | { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22_IT9137, |
776 | &it913x_properties, "Sveon STV22 Dual DVB-T HDTV(IT9137)", | |
777 | RC_MAP_IT913X_V1) }, | |
a7fab851 AM |
778 | { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CTVDIGDUAL_V2, |
779 | &it913x_properties, "Digital Dual TV Receiver CTVDIGDUAL_V2", | |
780 | RC_MAP_IT913X_V1) }, | |
04b8b21d MP |
781 | {} /* Terminating entry */ |
782 | }; | |
783 | ||
37973e01 MP |
784 | #if 0 |
785 | ||
04b8b21d MP |
786 | MODULE_DEVICE_TABLE(usb, it913x_id_table); |
787 | ||
788 | static struct usb_driver it913x_driver = { | |
789 | .name = KBUILD_MODNAME, | |
790 | .probe = dvb_usbv2_probe, | |
791 | .disconnect = dvb_usbv2_disconnect, | |
792 | .suspend = dvb_usbv2_suspend, | |
793 | .resume = dvb_usbv2_resume, | |
794 | .id_table = it913x_id_table, | |
795 | }; | |
796 | ||
37973e01 | 797 | |
04b8b21d MP |
798 | module_usb_driver(it913x_driver); |
799 | ||
37973e01 MP |
800 | #endif |
801 | ||
04b8b21d MP |
802 | MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>"); |
803 | MODULE_DESCRIPTION("it913x USB 2 Driver"); | |
21ca2030 | 804 | MODULE_VERSION("1.33"); |
04b8b21d MP |
805 | MODULE_LICENSE("GPL"); |
806 | MODULE_FIRMWARE(FW_IT9135_V1); | |
807 | MODULE_FIRMWARE(FW_IT9135_V2); | |
808 | MODULE_FIRMWARE(FW_IT9137); | |
809 |