Merge branch 'for-linus' of git://git.kernel.dk/linux-block
[deliverable/linux.git] / drivers / media / dvb / dvb-usb / mxl111sf.c
CommitLineData
4c66c920
MK
1/*
2 * Copyright (C) 2010 Michael Krufky (mkrufky@kernellabs.com)
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the Free
6 * Software Foundation, version 2.
7 *
8 * see Documentation/dvb/README.dvb-usb for more information
9 */
10
11#include <linux/vmalloc.h>
12#include <linux/i2c.h>
13
14#include "mxl111sf.h"
15#include "mxl111sf-reg.h"
16#include "mxl111sf-phy.h"
17#include "mxl111sf-i2c.h"
18#include "mxl111sf-gpio.h"
19
4f98480f 20#include "mxl111sf-demod.h"
4c66c920
MK
21#include "mxl111sf-tuner.h"
22
23#include "lgdt3305.h"
24
25int dvb_usb_mxl111sf_debug;
26module_param_named(debug, dvb_usb_mxl111sf_debug, int, 0644);
27MODULE_PARM_DESC(debug, "set debugging level "
28 "(1=info, 2=xfer, 4=i2c, 8=reg, 16=adv (or-able)).");
29
30int dvb_usb_mxl111sf_isoc;
31module_param_named(isoc, dvb_usb_mxl111sf_isoc, int, 0644);
32MODULE_PARM_DESC(isoc, "enable usb isoc xfer (0=bulk, 1=isoc).");
33
34#define ANT_PATH_AUTO 0
35#define ANT_PATH_EXTERNAL 1
36#define ANT_PATH_INTERNAL 2
37
38int dvb_usb_mxl111sf_rfswitch =
39#if 0
40 ANT_PATH_AUTO;
41#else
42 ANT_PATH_EXTERNAL;
43#endif
44
45module_param_named(rfswitch, dvb_usb_mxl111sf_rfswitch, int, 0644);
46MODULE_PARM_DESC(rfswitch, "force rf switch position (0=auto, 1=ext, 2=int).");
47
48DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
49
50#define deb_info(args...) dprintk(dvb_usb_mxl111sf_debug, 0x13, args)
51#define deb_reg(args...) dprintk(dvb_usb_mxl111sf_debug, 0x08, args)
52#define deb_adv(args...) dprintk(dvb_usb_mxl111sf_debug, MXL_ADV_DBG, args)
53
54int mxl111sf_ctrl_msg(struct dvb_usb_device *d,
55 u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
56{
57 int wo = (rbuf == NULL || rlen == 0); /* write-only */
58 int ret;
59 u8 sndbuf[1+wlen];
60
61 deb_adv("%s(wlen = %d, rlen = %d)\n", __func__, wlen, rlen);
62
63 memset(sndbuf, 0, 1+wlen);
64
65 sndbuf[0] = cmd;
66 memcpy(&sndbuf[1], wbuf, wlen);
67
68 ret = (wo) ? dvb_usb_generic_write(d, sndbuf, 1+wlen) :
69 dvb_usb_generic_rw(d, sndbuf, 1+wlen, rbuf, rlen, 0);
70 mxl_fail(ret);
71
72 return ret;
73}
74
75/* ------------------------------------------------------------------------ */
76
77#define MXL_CMD_REG_READ 0xaa
78#define MXL_CMD_REG_WRITE 0x55
79
80int mxl111sf_read_reg(struct mxl111sf_state *state, u8 addr, u8 *data)
81{
82 u8 buf[2];
83 int ret;
84
85 ret = mxl111sf_ctrl_msg(state->d, MXL_CMD_REG_READ, &addr, 1, buf, 2);
86 if (mxl_fail(ret)) {
87 mxl_debug("error reading reg: 0x%02x", addr);
88 goto fail;
89 }
90
91 if (buf[0] == addr)
92 *data = buf[1];
93 else {
94 err("invalid response reading reg: 0x%02x != 0x%02x, 0x%02x",
95 addr, buf[0], buf[1]);
96 ret = -EINVAL;
97 }
98
99 deb_reg("R: (0x%02x, 0x%02x)\n", addr, *data);
100fail:
101 return ret;
102}
103
104int mxl111sf_write_reg(struct mxl111sf_state *state, u8 addr, u8 data)
105{
106 u8 buf[] = { addr, data };
107 int ret;
108
109 deb_reg("W: (0x%02x, 0x%02x)\n", addr, data);
110
111 ret = mxl111sf_ctrl_msg(state->d, MXL_CMD_REG_WRITE, buf, 2, NULL, 0);
112 if (mxl_fail(ret))
113 err("error writing reg: 0x%02x, val: 0x%02x", addr, data);
114 return ret;
115}
116
117/* ------------------------------------------------------------------------ */
118
119int mxl111sf_write_reg_mask(struct mxl111sf_state *state,
120 u8 addr, u8 mask, u8 data)
121{
122 int ret;
123 u8 val;
124
125 if (mask != 0xff) {
126 ret = mxl111sf_read_reg(state, addr, &val);
127#if 1
128 /* dont know why this usually errors out on the first try */
129 if (mxl_fail(ret))
130 err("error writing addr: 0x%02x, mask: 0x%02x, "
131 "data: 0x%02x, retrying...", addr, mask, data);
132
133 ret = mxl111sf_read_reg(state, addr, &val);
134#endif
135 if (mxl_fail(ret))
136 goto fail;
137 }
138 val &= ~mask;
139 val |= data;
140
141 ret = mxl111sf_write_reg(state, addr, val);
142 mxl_fail(ret);
143fail:
144 return ret;
145}
146
147/* ------------------------------------------------------------------------ */
148
149int mxl111sf_ctrl_program_regs(struct mxl111sf_state *state,
150 struct mxl111sf_reg_ctrl_info *ctrl_reg_info)
151{
152 int i, ret = 0;
153
154 for (i = 0; ctrl_reg_info[i].addr |
155 ctrl_reg_info[i].mask |
156 ctrl_reg_info[i].data; i++) {
157
158 ret = mxl111sf_write_reg_mask(state,
159 ctrl_reg_info[i].addr,
160 ctrl_reg_info[i].mask,
161 ctrl_reg_info[i].data);
162 if (mxl_fail(ret)) {
163 err("failed on reg #%d (0x%02x)", i,
164 ctrl_reg_info[i].addr);
165 break;
166 }
167 }
168 return ret;
169}
170
171/* ------------------------------------------------------------------------ */
172
173static int mxl1x1sf_get_chip_info(struct mxl111sf_state *state)
174{
175 int ret;
176 u8 id, ver;
177 char *mxl_chip, *mxl_rev;
178
179 if ((state->chip_id) && (state->chip_ver))
180 return 0;
181
182 ret = mxl111sf_read_reg(state, CHIP_ID_REG, &id);
183 if (mxl_fail(ret))
184 goto fail;
185 state->chip_id = id;
186
187 ret = mxl111sf_read_reg(state, TOP_CHIP_REV_ID_REG, &ver);
188 if (mxl_fail(ret))
189 goto fail;
190 state->chip_ver = ver;
191
192 switch (id) {
193 case 0x61:
194 mxl_chip = "MxL101SF";
195 break;
196 case 0x63:
197 mxl_chip = "MxL111SF";
198 break;
199 default:
200 mxl_chip = "UNKNOWN MxL1X1";
201 break;
202 }
203 switch (ver) {
204 case 0x36:
205 state->chip_rev = MXL111SF_V6;
206 mxl_rev = "v6";
207 break;
208 case 0x08:
209 state->chip_rev = MXL111SF_V8_100;
210 mxl_rev = "v8_100";
211 break;
212 case 0x18:
213 state->chip_rev = MXL111SF_V8_200;
214 mxl_rev = "v8_200";
215 break;
216 default:
217 state->chip_rev = 0;
218 mxl_rev = "UNKNOWN REVISION";
219 break;
220 }
221 info("%s detected, %s (0x%x)", mxl_chip, mxl_rev, ver);
222fail:
223 return ret;
224}
225
226#define get_chip_info(state) \
227({ \
228 int ___ret; \
229 ___ret = mxl1x1sf_get_chip_info(state); \
230 if (mxl_fail(___ret)) { \
231 mxl_debug("failed to get chip info" \
232 " on first probe attempt"); \
233 ___ret = mxl1x1sf_get_chip_info(state); \
234 if (mxl_fail(___ret)) \
235 err("failed to get chip info during probe"); \
236 else \
237 mxl_debug("probe needed a retry " \
238 "in order to succeed."); \
239 } \
240 ___ret; \
241})
242
243/* ------------------------------------------------------------------------ */
244
245static int mxl111sf_power_ctrl(struct dvb_usb_device *d, int onoff)
246{
247 /* power control depends on which adapter is being woken:
248 * save this for init, instead, via mxl111sf_adap_fe_init */
249 return 0;
250}
251
252static int mxl111sf_adap_fe_init(struct dvb_frontend *fe)
253{
254 struct dvb_usb_adapter *adap = fe->dvb->priv;
255 struct dvb_usb_device *d = adap->dev;
256 struct mxl111sf_state *state = d->priv;
77eed219
MK
257 struct mxl111sf_adap_state *adap_state = adap->fe_adap[fe->id].priv;
258
4c66c920
MK
259 int err;
260
261 /* exit if we didnt initialize the driver yet */
262 if (!state->chip_id) {
263 mxl_debug("driver not yet initialized, exit.");
264 goto fail;
265 }
266
267 deb_info("%s()\n", __func__);
268
269 mutex_lock(&state->fe_lock);
270
271 state->alt_mode = adap_state->alt_mode;
272
273 if (usb_set_interface(adap->dev->udev, 0, state->alt_mode) < 0)
274 err("set interface failed");
275
276 err = mxl1x1sf_soft_reset(state);
277 mxl_fail(err);
278 err = mxl111sf_init_tuner_demod(state);
279 mxl_fail(err);
280 err = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
281
282 mxl_fail(err);
283 mxl111sf_enable_usb_output(state);
284 mxl_fail(err);
285 mxl1x1sf_top_master_ctrl(state, 1);
286 mxl_fail(err);
287
288 if ((MXL111SF_GPIO_MOD_DVBT != adap_state->gpio_mode) &&
289 (state->chip_rev > MXL111SF_V6)) {
290 mxl111sf_config_pin_mux_modes(state,
291 PIN_MUX_TS_SPI_IN_MODE_1);
292 mxl_fail(err);
293 }
294 err = mxl111sf_init_port_expander(state);
295 if (!mxl_fail(err)) {
296 state->gpio_mode = adap_state->gpio_mode;
297 err = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
298 mxl_fail(err);
299#if 0
300 err = fe->ops.init(fe);
301#endif
302 msleep(100); /* add short delay after enabling
303 * the demod before touching it */
304 }
305
306 return (adap_state->fe_init) ? adap_state->fe_init(fe) : 0;
307fail:
308 return -ENODEV;
309}
310
311static int mxl111sf_adap_fe_sleep(struct dvb_frontend *fe)
312{
313 struct dvb_usb_adapter *adap = fe->dvb->priv;
314 struct dvb_usb_device *d = adap->dev;
315 struct mxl111sf_state *state = d->priv;
77eed219 316 struct mxl111sf_adap_state *adap_state = adap->fe_adap[fe->id].priv;
4c66c920
MK
317 int err;
318
319 /* exit if we didnt initialize the driver yet */
320 if (!state->chip_id) {
321 mxl_debug("driver not yet initialized, exit.");
322 goto fail;
323 }
324
325 deb_info("%s()\n", __func__);
326
327 err = (adap_state->fe_sleep) ? adap_state->fe_sleep(fe) : 0;
328
329 mutex_unlock(&state->fe_lock);
330
331 return err;
332fail:
333 return -ENODEV;
334}
335
336
337static int mxl111sf_ep6_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
338{
339 struct dvb_usb_device *d = adap->dev;
340 struct mxl111sf_state *state = d->priv;
77eed219 341 struct mxl111sf_adap_state *adap_state = adap->fe_adap[adap->active_fe].priv;
4c66c920
MK
342 int ret = 0;
343 u8 tmp;
344
345 deb_info("%s(%d)\n", __func__, onoff);
346
347 if (onoff) {
348 ret = mxl111sf_enable_usb_output(state);
349 mxl_fail(ret);
350 ret = mxl111sf_config_mpeg_in(state, 1, 1,
351 adap_state->ep6_clockphase,
352 0, 0);
353 mxl_fail(ret);
354 } else {
355 ret = mxl111sf_disable_656_port(state);
356 mxl_fail(ret);
357 }
358
359 mxl111sf_read_reg(state, 0x12, &tmp);
360 tmp &= ~0x04;
361 mxl111sf_write_reg(state, 0x12, tmp);
362
363 return ret;
364}
365
4f98480f
MK
366static int mxl111sf_ep4_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
367{
368 struct dvb_usb_device *d = adap->dev;
369 struct mxl111sf_state *state = d->priv;
370 int ret = 0;
371
372 deb_info("%s(%d)\n", __func__, onoff);
373
374 if (onoff) {
375 ret = mxl111sf_enable_usb_output(state);
376 mxl_fail(ret);
377 }
378
379 return ret;
380}
381
4c66c920
MK
382/* ------------------------------------------------------------------------ */
383
384static struct lgdt3305_config hauppauge_lgdt3305_config = {
385 .i2c_addr = 0xb2 >> 1,
386 .mpeg_mode = LGDT3305_MPEG_SERIAL,
387 .tpclk_edge = LGDT3305_TPCLK_RISING_EDGE,
388 .tpvalid_polarity = LGDT3305_TP_VALID_HIGH,
389 .deny_i2c_rptr = 1,
390 .spectral_inversion = 0,
391 .qam_if_khz = 6000,
392 .vsb_if_khz = 6000,
393};
394
395static int mxl111sf_lgdt3305_frontend_attach(struct dvb_usb_adapter *adap)
396{
397 struct dvb_usb_device *d = adap->dev;
398 struct mxl111sf_state *state = d->priv;
1251312a
MK
399 int fe_id = adap->num_frontends_initialized;
400 struct mxl111sf_adap_state *adap_state = adap->fe_adap[fe_id].priv;
4c66c920
MK
401 int ret;
402
403 deb_adv("%s()\n", __func__);
404
405 /* save a pointer to the dvb_usb_device in device state */
406 state->d = d;
407 adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
408 state->alt_mode = adap_state->alt_mode;
409
410 if (usb_set_interface(adap->dev->udev, 0, state->alt_mode) < 0)
411 err("set interface failed");
412
413 state->gpio_mode = MXL111SF_GPIO_MOD_ATSC;
414 adap_state->gpio_mode = state->gpio_mode;
415 adap_state->device_mode = MXL_TUNER_MODE;
416 adap_state->ep6_clockphase = 1;
417
418 ret = mxl1x1sf_soft_reset(state);
419 if (mxl_fail(ret))
420 goto fail;
421 ret = mxl111sf_init_tuner_demod(state);
422 if (mxl_fail(ret))
423 goto fail;
424
425 ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
426 if (mxl_fail(ret))
427 goto fail;
428
429 ret = mxl111sf_enable_usb_output(state);
430 if (mxl_fail(ret))
431 goto fail;
432 ret = mxl1x1sf_top_master_ctrl(state, 1);
433 if (mxl_fail(ret))
434 goto fail;
435
436 ret = mxl111sf_init_port_expander(state);
437 if (mxl_fail(ret))
438 goto fail;
439 ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
440 if (mxl_fail(ret))
441 goto fail;
442
1251312a 443 adap->fe_adap[fe_id].fe = dvb_attach(lgdt3305_attach,
4c66c920
MK
444 &hauppauge_lgdt3305_config,
445 &adap->dev->i2c_adap);
1251312a
MK
446 if (adap->fe_adap[fe_id].fe) {
447 adap_state->fe_init = adap->fe_adap[fe_id].fe->ops.init;
448 adap->fe_adap[fe_id].fe->ops.init = mxl111sf_adap_fe_init;
449 adap_state->fe_sleep = adap->fe_adap[fe_id].fe->ops.sleep;
450 adap->fe_adap[fe_id].fe->ops.sleep = mxl111sf_adap_fe_sleep;
4c66c920
MK
451 return 0;
452 }
453 ret = -EIO;
454fail:
455 return ret;
456}
457
4f98480f
MK
458static struct mxl111sf_demod_config mxl_demod_config = {
459 .read_reg = mxl111sf_read_reg,
460 .write_reg = mxl111sf_write_reg,
461 .program_regs = mxl111sf_ctrl_program_regs,
462};
463
464static int mxl111sf_attach_demod(struct dvb_usb_adapter *adap)
465{
466 struct dvb_usb_device *d = adap->dev;
467 struct mxl111sf_state *state = d->priv;
468 int fe_id = adap->num_frontends_initialized;
469 struct mxl111sf_adap_state *adap_state = adap->fe_adap[fe_id].priv;
470 int ret;
471
472 deb_adv("%s()\n", __func__);
473
474 /* save a pointer to the dvb_usb_device in device state */
475 state->d = d;
476 adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 1 : 2;
477 state->alt_mode = adap_state->alt_mode;
478
479 if (usb_set_interface(adap->dev->udev, 0, state->alt_mode) < 0)
480 err("set interface failed");
481
482 state->gpio_mode = MXL111SF_GPIO_MOD_DVBT;
483 adap_state->gpio_mode = state->gpio_mode;
484 adap_state->device_mode = MXL_SOC_MODE;
485 adap_state->ep6_clockphase = 1;
486
487 ret = mxl1x1sf_soft_reset(state);
488 if (mxl_fail(ret))
489 goto fail;
490 ret = mxl111sf_init_tuner_demod(state);
491 if (mxl_fail(ret))
492 goto fail;
493
494 ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
495 if (mxl_fail(ret))
496 goto fail;
497
498 ret = mxl111sf_enable_usb_output(state);
499 if (mxl_fail(ret))
500 goto fail;
501 ret = mxl1x1sf_top_master_ctrl(state, 1);
502 if (mxl_fail(ret))
503 goto fail;
504
505 /* dont care if this fails */
506 mxl111sf_init_port_expander(state);
507
508 adap->fe_adap[fe_id].fe = dvb_attach(mxl111sf_demod_attach, state,
509 &mxl_demod_config);
510 if (adap->fe_adap[fe_id].fe) {
511 adap_state->fe_init = adap->fe_adap[fe_id].fe->ops.init;
512 adap->fe_adap[fe_id].fe->ops.init = mxl111sf_adap_fe_init;
513 adap_state->fe_sleep = adap->fe_adap[fe_id].fe->ops.sleep;
514 adap->fe_adap[fe_id].fe->ops.sleep = mxl111sf_adap_fe_sleep;
515 return 0;
516 }
517 ret = -EIO;
518fail:
519 return ret;
520}
521
4c66c920
MK
522static inline int mxl111sf_set_ant_path(struct mxl111sf_state *state,
523 int antpath)
524{
525 return mxl111sf_idac_config(state, 1, 1,
526 (antpath == ANT_PATH_INTERNAL) ?
527 0x3f : 0x00, 0);
528}
529
530#define DbgAntHunt(x, pwr0, pwr1, pwr2, pwr3) \
531 err("%s(%d) FINAL input set to %s rxPwr:%d|%d|%d|%d\n", \
532 __func__, __LINE__, \
533 (ANT_PATH_EXTERNAL == x) ? "EXTERNAL" : "INTERNAL", \
534 pwr0, pwr1, pwr2, pwr3)
535
536#define ANT_HUNT_SLEEP 90
537#define ANT_EXT_TWEAK 0
538
539static int mxl111sf_ant_hunt(struct dvb_frontend *fe)
540{
541 struct dvb_usb_adapter *adap = fe->dvb->priv;
542 struct dvb_usb_device *d = adap->dev;
543 struct mxl111sf_state *state = d->priv;
544
545 int antctrl = dvb_usb_mxl111sf_rfswitch;
546
547 u16 rxPwrA, rxPwr0, rxPwr1, rxPwr2;
548
549 /* FIXME: must force EXTERNAL for QAM - done elsewhere */
550 mxl111sf_set_ant_path(state, antctrl == ANT_PATH_AUTO ?
551 ANT_PATH_EXTERNAL : antctrl);
552
553 if (antctrl == ANT_PATH_AUTO) {
554#if 0
555 msleep(ANT_HUNT_SLEEP);
556#endif
557 fe->ops.tuner_ops.get_rf_strength(fe, &rxPwrA);
558
559 mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
560 msleep(ANT_HUNT_SLEEP);
561 fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr0);
562
563 mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
564 msleep(ANT_HUNT_SLEEP);
565 fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr1);
566
567 mxl111sf_set_ant_path(state, ANT_PATH_INTERNAL);
568 msleep(ANT_HUNT_SLEEP);
569 fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr2);
570
571 if (rxPwr1+ANT_EXT_TWEAK >= rxPwr2) {
572 /* return with EXTERNAL enabled */
573 mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
574 DbgAntHunt(ANT_PATH_EXTERNAL, rxPwrA,
575 rxPwr0, rxPwr1, rxPwr2);
576 } else {
577 /* return with INTERNAL enabled */
578 DbgAntHunt(ANT_PATH_INTERNAL, rxPwrA,
579 rxPwr0, rxPwr1, rxPwr2);
580 }
581 }
582 return 0;
583}
584
585static struct mxl111sf_tuner_config mxl_tuner_config = {
586 .if_freq = MXL_IF_6_0, /* applies to external IF output, only */
587 .invert_spectrum = 0,
588 .read_reg = mxl111sf_read_reg,
589 .write_reg = mxl111sf_write_reg,
590 .program_regs = mxl111sf_ctrl_program_regs,
591 .top_master_ctrl = mxl1x1sf_top_master_ctrl,
592 .ant_hunt = mxl111sf_ant_hunt,
593};
594
595static int mxl111sf_attach_tuner(struct dvb_usb_adapter *adap)
596{
597 struct dvb_usb_device *d = adap->dev;
598 struct mxl111sf_state *state = d->priv;
1251312a 599 int fe_id = adap->num_frontends_initialized;
4c66c920
MK
600
601 deb_adv("%s()\n", __func__);
602
1251312a
MK
603 if (NULL != dvb_attach(mxl111sf_tuner_attach,
604 adap->fe_adap[fe_id].fe, state,
4c66c920
MK
605 &mxl_tuner_config))
606 return 0;
607
608 return -EIO;
609}
610
611static int mxl111sf_fe_ioctl_override(struct dvb_frontend *fe,
612 unsigned int cmd, void *parg,
613 unsigned int stage)
614{
615 int err = 0;
616
617 switch (stage) {
618 case DVB_FE_IOCTL_PRE:
619
620 switch (cmd) {
621 case FE_READ_SIGNAL_STRENGTH:
622 err = fe->ops.tuner_ops.get_rf_strength(fe, parg);
623 /* If no error occurs, prevent dvb-core from handling
624 * this IOCTL, otherwise return the error */
625 if (0 == err)
626 err = 1;
627 break;
628 }
629 break;
630
631 case DVB_FE_IOCTL_POST:
632 /* no post-ioctl handling required */
633 break;
634 }
635 return err;
636};
637
638static u32 mxl111sf_i2c_func(struct i2c_adapter *adapter)
639{
640 return I2C_FUNC_I2C;
641}
642
643struct i2c_algorithm mxl111sf_i2c_algo = {
644 .master_xfer = mxl111sf_i2c_xfer,
645 .functionality = mxl111sf_i2c_func,
646#ifdef NEED_ALGO_CONTROL
647 .algo_control = dummy_algo_control,
648#endif
649};
650
4f98480f
MK
651static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties;
652static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties;
4c66c920
MK
653static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties;
654static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties;
655
656static int mxl111sf_probe(struct usb_interface *intf,
657 const struct usb_device_id *id)
658{
659 struct dvb_usb_device *d = NULL;
660
661 deb_adv("%s()\n", __func__);
662
663 if (((dvb_usb_mxl111sf_isoc) &&
664 (0 == dvb_usb_device_init(intf,
4f98480f
MK
665 &mxl111sf_dvbt_isoc_properties,
666 THIS_MODULE, &d, adapter_nr) ||
667 0 == dvb_usb_device_init(intf,
4c66c920
MK
668 &mxl111sf_atsc_isoc_properties,
669 THIS_MODULE, &d, adapter_nr))) ||
4f98480f
MK
670 0 == dvb_usb_device_init(intf,
671 &mxl111sf_dvbt_bulk_properties,
672 THIS_MODULE, &d, adapter_nr) ||
4c66c920
MK
673 0 == dvb_usb_device_init(intf,
674 &mxl111sf_atsc_bulk_properties,
675 THIS_MODULE, &d, adapter_nr) || 0) {
676
677 struct mxl111sf_state *state = d->priv;
678 static u8 eeprom[256];
679 struct i2c_client c;
680 int ret;
681
682 ret = get_chip_info(state);
683 if (mxl_fail(ret))
684 err("failed to get chip info during probe");
685
686 mutex_init(&state->fe_lock);
687
688 if (state->chip_rev > MXL111SF_V6)
689 mxl111sf_config_pin_mux_modes(state,
690 PIN_MUX_TS_SPI_IN_MODE_1);
691
692 c.adapter = &d->i2c_adap;
693 c.addr = 0xa0 >> 1;
694
695 ret = tveeprom_read(&c, eeprom, sizeof(eeprom));
696 if (mxl_fail(ret))
697 return 0;
698 tveeprom_hauppauge_analog(&c, &state->tv,
699 (0x84 == eeprom[0xa0]) ?
700 eeprom + 0xa0 : eeprom + 0x80);
701#if 0
702 switch (state->tv.model) {
703 case 117001:
704 case 126001:
705 case 138001:
706 break;
707 default:
708 printk(KERN_WARNING "%s: warning: "
709 "unknown hauppauge model #%d\n",
710 __func__, state->tv.model);
711 }
712#endif
713 return 0;
714 }
715 err("Your device is not yet supported by this driver. "
716 "See kernellabs.com for more info");
717 return -EINVAL;
718}
719
720static struct usb_device_id mxl111sf_table[] = {
721/* 0 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc600) }, /* ATSC+ IR */
722 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc601) }, /* ATSC */
723 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc602) }, /* + */
724 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc603) }, /* ATSC+ */
725 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc604) }, /* DVBT */
726/* 5 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc609) }, /* ATSC IR */
727 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60a) }, /* + IR */
728 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60b) }, /* ATSC+ IR */
729 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60c) }, /* DVBT IR */
730 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc653) }, /* ATSC+ */
731/*10 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc65b) }, /* ATSC+ IR */
732 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb700) }, /* ATSC+ sw */
733 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb701) }, /* ATSC sw */
734 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb702) }, /* + sw */
735 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb703) }, /* ATSC+ sw */
736/*15 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb704) }, /* DVBT sw */
737 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb753) }, /* ATSC+ sw */
738 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb763) }, /* ATSC+ no */
739 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb764) }, /* DVBT no */
740 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd853) }, /* ATSC+ sw */
741/*20 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd854) }, /* DVBT sw */
742 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd863) }, /* ATSC+ no */
743 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd864) }, /* DVBT no */
744 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8d3) }, /* ATSC+ sw */
745 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8d4) }, /* DVBT sw */
746/*25 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8e3) }, /* ATSC+ no */
747 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8e4) }, /* DVBT no */
748 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8ff) }, /* ATSC+ */
749 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc612) }, /* + */
750 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc613) }, /* ATSC+ */
751/*30 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc61a) }, /* + IR */
752 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc61b) }, /* ATSC+ IR */
753 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb757) }, /* ATSC+DVBT sw */
754 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb767) }, /* ATSC+DVBT no */
755 {} /* Terminating entry */
756};
757MODULE_DEVICE_TABLE(usb, mxl111sf_table);
758
759
4f98480f 760#define MXL111SF_EP4_BULK_STREAMING_CONFIG \
0d6ac1f8 761 .size_of_priv = sizeof(struct mxl111sf_adap_state), \
4f98480f
MK
762 .streaming_ctrl = mxl111sf_ep4_streaming_ctrl, \
763 .stream = { \
764 .type = USB_BULK, \
765 .count = 5, \
766 .endpoint = 0x04, \
767 .u = { \
768 .bulk = { \
769 .buffersize = 8192, \
770 } \
771 } \
772 }
773
774/* FIXME: works for v6 but not v8 silicon */
775#define MXL111SF_EP4_ISOC_STREAMING_CONFIG \
0d6ac1f8 776 .size_of_priv = sizeof(struct mxl111sf_adap_state), \
4f98480f
MK
777 .streaming_ctrl = mxl111sf_ep4_streaming_ctrl, \
778 .stream = { \
779 .type = USB_ISOC, \
780 .count = 5, \
781 .endpoint = 0x04, \
782 .u = { \
783 .isoc = { \
784 .framesperurb = 96, \
785 /* FIXME: v6 SILICON: */ \
786 .framesize = 564, \
787 .interval = 1, \
788 } \
789 } \
790 }
791
4c66c920 792#define MXL111SF_EP6_BULK_STREAMING_CONFIG \
0d6ac1f8 793 .size_of_priv = sizeof(struct mxl111sf_adap_state), \
4c66c920
MK
794 .streaming_ctrl = mxl111sf_ep6_streaming_ctrl, \
795 .stream = { \
796 .type = USB_BULK, \
797 .count = 5, \
798 .endpoint = 0x06, \
799 .u = { \
800 .bulk = { \
801 .buffersize = 8192, \
802 } \
803 } \
804 }
805
806/* FIXME */
807#define MXL111SF_EP6_ISOC_STREAMING_CONFIG \
0d6ac1f8 808 .size_of_priv = sizeof(struct mxl111sf_adap_state), \
4c66c920
MK
809 .streaming_ctrl = mxl111sf_ep6_streaming_ctrl, \
810 .stream = { \
811 .type = USB_ISOC, \
812 .count = 5, \
813 .endpoint = 0x06, \
814 .u = { \
815 .isoc = { \
816 .framesperurb = 24, \
817 .framesize = 3072, \
818 .interval = 1, \
819 } \
820 } \
821 }
822
823#define MXL111SF_DEFAULT_DEVICE_PROPERTIES \
824 .caps = DVB_USB_IS_AN_I2C_ADAPTER, \
825 .usb_ctrl = DEVICE_SPECIFIC, \
826 /* use usb alt setting 1 for EP4 ISOC transfer (dvb-t), \
827 EP6 BULK transfer (atsc/qam), \
828 use usb alt setting 2 for EP4 BULK transfer (dvb-t), \
829 EP6 ISOC transfer (atsc/qam), \
830 */ \
831 .power_ctrl = mxl111sf_power_ctrl, \
832 .i2c_algo = &mxl111sf_i2c_algo, \
833 .generic_bulk_ctrl_endpoint = MXL_EP2_REG_WRITE, \
834 .generic_bulk_ctrl_endpoint_response = MXL_EP1_REG_READ, \
835 .size_of_priv = sizeof(struct mxl111sf_state)
836
4f98480f 837static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties = {
4c66c920
MK
838 MXL111SF_DEFAULT_DEVICE_PROPERTIES,
839
840 .num_adapters = 1,
841 .adapter = {
842 {
77eed219
MK
843 .fe_ioctl_override = mxl111sf_fe_ioctl_override,
844 .num_frontends = 1,
845 .fe = {{
4f98480f
MK
846 .frontend_attach = mxl111sf_attach_demod,
847 .tuner_attach = mxl111sf_attach_tuner,
848
849 MXL111SF_EP4_BULK_STREAMING_CONFIG,
850 } },
851 },
852 },
853 .num_device_descs = 4,
854 .devices = {
855 { "Hauppauge 126xxx DVBT (bulk)",
856 { NULL },
857 { &mxl111sf_table[4], &mxl111sf_table[8],
858 NULL },
859 },
860 { "Hauppauge 117xxx DVBT (bulk)",
861 { NULL },
862 { &mxl111sf_table[15], &mxl111sf_table[18],
863 NULL },
864 },
865 { "Hauppauge 138xxx DVBT (bulk)",
866 { NULL },
867 { &mxl111sf_table[20], &mxl111sf_table[22],
868 &mxl111sf_table[24], &mxl111sf_table[26],
869 NULL },
870 },
871 { "Hauppauge 126xxx (tp-bulk)",
872 { NULL },
873 { &mxl111sf_table[28], &mxl111sf_table[30],
874 NULL },
875 },
876 }
877};
878
879static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties = {
880 MXL111SF_DEFAULT_DEVICE_PROPERTIES,
881
882 .num_adapters = 1,
883 .adapter = {
884 {
885 .fe_ioctl_override = mxl111sf_fe_ioctl_override,
886 .num_frontends = 1,
887 .fe = {{
4f98480f
MK
888 .frontend_attach = mxl111sf_attach_demod,
889 .tuner_attach = mxl111sf_attach_tuner,
890
891 MXL111SF_EP4_ISOC_STREAMING_CONFIG,
892 } },
893 },
894 },
895 .num_device_descs = 4,
896 .devices = {
897 { "Hauppauge 126xxx DVBT (isoc)",
898 { NULL },
899 { &mxl111sf_table[4], &mxl111sf_table[8],
900 NULL },
901 },
902 { "Hauppauge 117xxx DVBT (isoc)",
903 { NULL },
904 { &mxl111sf_table[15], &mxl111sf_table[18],
905 NULL },
906 },
907 { "Hauppauge 138xxx DVBT (isoc)",
908 { NULL },
909 { &mxl111sf_table[20], &mxl111sf_table[22],
910 &mxl111sf_table[24], &mxl111sf_table[26],
911 NULL },
912 },
913 { "Hauppauge 126xxx (tp-isoc)",
914 { NULL },
915 { &mxl111sf_table[28], &mxl111sf_table[30],
916 NULL },
917 },
918 }
919};
920
921static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties = {
922 MXL111SF_DEFAULT_DEVICE_PROPERTIES,
923
924 .num_adapters = 1,
925 .adapter = {
926 {
927 .fe_ioctl_override = mxl111sf_fe_ioctl_override,
928 .num_frontends = 2,
929 .fe = {{
4c66c920
MK
930 .frontend_attach = mxl111sf_lgdt3305_frontend_attach,
931 .tuner_attach = mxl111sf_attach_tuner,
932
933 MXL111SF_EP6_BULK_STREAMING_CONFIG,
4f98480f
MK
934 },
935 {
4f98480f
MK
936 .frontend_attach = mxl111sf_attach_demod,
937 .tuner_attach = mxl111sf_attach_tuner,
938
939 MXL111SF_EP4_BULK_STREAMING_CONFIG,
77eed219 940 }},
4c66c920
MK
941 },
942 },
943 .num_device_descs = 6,
944 .devices = {
945 { "Hauppauge 126xxx ATSC (bulk)",
946 { NULL },
947 { &mxl111sf_table[1], &mxl111sf_table[5],
948 NULL },
949 },
950 { "Hauppauge 117xxx ATSC (bulk)",
951 { NULL },
952 { &mxl111sf_table[12],
953 NULL },
954 },
955 { "Hauppauge 126xxx ATSC+ (bulk)",
956 { NULL },
957 { &mxl111sf_table[0], &mxl111sf_table[3],
958 &mxl111sf_table[7], &mxl111sf_table[9],
959 &mxl111sf_table[10], NULL },
960 },
961 { "Hauppauge 117xxx ATSC+ (bulk)",
962 { NULL },
963 { &mxl111sf_table[11], &mxl111sf_table[14],
964 &mxl111sf_table[16], &mxl111sf_table[17],
965 &mxl111sf_table[32], &mxl111sf_table[33],
966 NULL },
967 },
968 { "Hauppauge Mercury (tp-bulk)",
969 { NULL },
970 { &mxl111sf_table[19], &mxl111sf_table[21],
971 &mxl111sf_table[23], &mxl111sf_table[25],
972 &mxl111sf_table[27], NULL },
973 },
974 { "Hauppauge WinTV-Aero-M",
975 { NULL },
976 { &mxl111sf_table[29], &mxl111sf_table[31],
977 NULL },
978 },
979 }
980};
981
982static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties = {
983 MXL111SF_DEFAULT_DEVICE_PROPERTIES,
984
985 .num_adapters = 1,
986 .adapter = {
987 {
77eed219 988 .fe_ioctl_override = mxl111sf_fe_ioctl_override,
4f98480f 989 .num_frontends = 2,
77eed219 990 .fe = {{
4c66c920
MK
991 .frontend_attach = mxl111sf_lgdt3305_frontend_attach,
992 .tuner_attach = mxl111sf_attach_tuner,
993
994 MXL111SF_EP6_ISOC_STREAMING_CONFIG,
4f98480f
MK
995 },
996 {
4f98480f
MK
997 .frontend_attach = mxl111sf_attach_demod,
998 .tuner_attach = mxl111sf_attach_tuner,
999
1000 MXL111SF_EP4_ISOC_STREAMING_CONFIG,
77eed219 1001 }},
4c66c920
MK
1002 },
1003 },
1004 .num_device_descs = 6,
1005 .devices = {
1006 { "Hauppauge 126xxx ATSC (isoc)",
1007 { NULL },
1008 { &mxl111sf_table[1], &mxl111sf_table[5],
1009 NULL },
1010 },
1011 { "Hauppauge 117xxx ATSC (isoc)",
1012 { NULL },
1013 { &mxl111sf_table[12],
1014 NULL },
1015 },
1016 { "Hauppauge 126xxx ATSC+ (isoc)",
1017 { NULL },
1018 { &mxl111sf_table[0], &mxl111sf_table[3],
1019 &mxl111sf_table[7], &mxl111sf_table[9],
1020 &mxl111sf_table[10], NULL },
1021 },
1022 { "Hauppauge 117xxx ATSC+ (isoc)",
1023 { NULL },
1024 { &mxl111sf_table[11], &mxl111sf_table[14],
1025 &mxl111sf_table[16], &mxl111sf_table[17],
1026 &mxl111sf_table[32], &mxl111sf_table[33],
1027 NULL },
1028 },
1029 { "Hauppauge Mercury (tp-isoc)",
1030 { NULL },
1031 { &mxl111sf_table[19], &mxl111sf_table[21],
1032 &mxl111sf_table[23], &mxl111sf_table[25],
1033 &mxl111sf_table[27], NULL },
1034 },
1035 { "Hauppauge WinTV-Aero-M (tp-isoc)",
1036 { NULL },
1037 { &mxl111sf_table[29], &mxl111sf_table[31],
1038 NULL },
1039 },
1040 }
1041};
1042
1043static struct usb_driver mxl111sf_driver = {
1044 .name = "dvb_usb_mxl111sf",
1045 .probe = mxl111sf_probe,
1046 .disconnect = dvb_usb_device_exit,
1047 .id_table = mxl111sf_table,
1048};
1049
ecb3b2b3 1050module_usb_driver(mxl111sf_driver);
4c66c920
MK
1051
1052MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>");
1053MODULE_DESCRIPTION("Driver for MaxLinear MxL111SF");
1054MODULE_VERSION("1.0");
1055MODULE_LICENSE("GPL");
1056
1057/*
1058 * Local variables:
1059 * c-basic-offset: 8
1060 * End:
1061 */
This page took 0.090383 seconds and 5 git commands to generate.