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-demod.h"
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;
257	struct mxl111sf_adap_state *adap_state = adap->fe_adap[fe->id].priv;
258
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;
316	struct mxl111sf_adap_state *adap_state = adap->fe_adap[fe->id].priv;
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;
341	struct mxl111sf_adap_state *adap_state = adap->fe_adap[adap->active_fe].priv;
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
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
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;
399	int fe_id = adap->num_frontends_initialized;
400	struct mxl111sf_adap_state *adap_state = adap->fe_adap[fe_id].priv;
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
443	adap->fe_adap[fe_id].fe = dvb_attach(lgdt3305_attach,
444				 &hauppauge_lgdt3305_config,
445				 &adap->dev->i2c_adap);
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;
451		return 0;
452	}
453	ret = -EIO;
454fail:
455	return ret;
456}
457
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
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;
599	int fe_id = adap->num_frontends_initialized;
600
601	deb_adv("%s()\n", __func__);
602
603	if (NULL != dvb_attach(mxl111sf_tuner_attach,
604			       adap->fe_adap[fe_id].fe, state,
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
651static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties;
652static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties;
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,
665				       &mxl111sf_dvbt_isoc_properties,
666				       THIS_MODULE, &d, adapter_nr) ||
667	      0 == dvb_usb_device_init(intf,
668				       &mxl111sf_atsc_isoc_properties,
669				       THIS_MODULE, &d, adapter_nr))) ||
670	    0 == dvb_usb_device_init(intf,
671				     &mxl111sf_dvbt_bulk_properties,
672				     THIS_MODULE, &d, adapter_nr) ||
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
760#define MXL111SF_EP4_BULK_STREAMING_CONFIG		\
761	.size_of_priv = sizeof(struct mxl111sf_adap_state), \
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		\
776	.size_of_priv = sizeof(struct mxl111sf_adap_state), \
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
792#define MXL111SF_EP6_BULK_STREAMING_CONFIG		\
793	.size_of_priv = sizeof(struct mxl111sf_adap_state), \
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		\
808	.size_of_priv = sizeof(struct mxl111sf_adap_state), \
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
837static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties = {
838	MXL111SF_DEFAULT_DEVICE_PROPERTIES,
839
840	.num_adapters = 1,
841	.adapter = {
842		{
843		.fe_ioctl_override = mxl111sf_fe_ioctl_override,
844		.num_frontends = 1,
845		.fe = {{
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 = {{
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 = {{
930			.frontend_attach  = mxl111sf_lgdt3305_frontend_attach,
931			.tuner_attach     = mxl111sf_attach_tuner,
932
933			MXL111SF_EP6_BULK_STREAMING_CONFIG,
934		},
935		{
936			.frontend_attach  = mxl111sf_attach_demod,
937			.tuner_attach     = mxl111sf_attach_tuner,
938
939			MXL111SF_EP4_BULK_STREAMING_CONFIG,
940		}},
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		{
988		.fe_ioctl_override = mxl111sf_fe_ioctl_override,
989		.num_frontends = 2,
990		.fe = {{
991			.frontend_attach  = mxl111sf_lgdt3305_frontend_attach,
992			.tuner_attach     = mxl111sf_attach_tuner,
993
994			MXL111SF_EP6_ISOC_STREAMING_CONFIG,
995		},
996		{
997			.frontend_attach  = mxl111sf_attach_demod,
998			.tuner_attach     = mxl111sf_attach_tuner,
999
1000			MXL111SF_EP4_ISOC_STREAMING_CONFIG,
1001		}},
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
1050module_usb_driver(mxl111sf_driver);
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 */
1062