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