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 
25 int dvb_usb_mxl111sf_debug;
26 module_param_named(debug, dvb_usb_mxl111sf_debug, int, 0644);
27 MODULE_PARM_DESC(debug, "set debugging level "
28 		 "(1=info, 2=xfer, 4=i2c, 8=reg, 16=adv (or-able)).");
29 
30 int dvb_usb_mxl111sf_isoc;
31 module_param_named(isoc, dvb_usb_mxl111sf_isoc, int, 0644);
32 MODULE_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 
38 int dvb_usb_mxl111sf_rfswitch =
39 #if 0
40 		ANT_PATH_AUTO;
41 #else
42 		ANT_PATH_EXTERNAL;
43 #endif
44 
45 module_param_named(rfswitch, dvb_usb_mxl111sf_rfswitch, int, 0644);
46 MODULE_PARM_DESC(rfswitch, "force rf switch position (0=auto, 1=ext, 2=int).");
47 
48 DVB_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 
mxl111sf_ctrl_msg(struct dvb_usb_device * d,u8 cmd,u8 * wbuf,int wlen,u8 * rbuf,int rlen)54 int 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 
mxl111sf_read_reg(struct mxl111sf_state * state,u8 addr,u8 * data)80 int 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);
100 fail:
101 	return ret;
102 }
103 
mxl111sf_write_reg(struct mxl111sf_state * state,u8 addr,u8 data)104 int 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 
mxl111sf_write_reg_mask(struct mxl111sf_state * state,u8 addr,u8 mask,u8 data)119 int 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);
143 fail:
144 	return ret;
145 }
146 
147 /* ------------------------------------------------------------------------ */
148 
mxl111sf_ctrl_program_regs(struct mxl111sf_state * state,struct mxl111sf_reg_ctrl_info * ctrl_reg_info)149 int 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 
mxl1x1sf_get_chip_info(struct mxl111sf_state * state)173 static 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);
222 fail:
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 
mxl111sf_power_ctrl(struct dvb_usb_device * d,int onoff)245 static 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 
mxl111sf_adap_fe_init(struct dvb_frontend * fe)252 static 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;
307 fail:
308 	return -ENODEV;
309 }
310 
mxl111sf_adap_fe_sleep(struct dvb_frontend * fe)311 static 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;
332 fail:
333 	return -ENODEV;
334 }
335 
336 
mxl111sf_ep6_streaming_ctrl(struct dvb_usb_adapter * adap,int onoff)337 static 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 
mxl111sf_ep4_streaming_ctrl(struct dvb_usb_adapter * adap,int onoff)366 static 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 
384 static 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 
mxl111sf_lgdt3305_frontend_attach(struct dvb_usb_adapter * adap)395 static 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;
454 fail:
455 	return ret;
456 }
457 
458 static 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 
mxl111sf_attach_demod(struct dvb_usb_adapter * adap)464 static 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;
518 fail:
519 	return ret;
520 }
521 
mxl111sf_set_ant_path(struct mxl111sf_state * state,int antpath)522 static 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 
mxl111sf_ant_hunt(struct dvb_frontend * fe)539 static 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 
585 static 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 
mxl111sf_attach_tuner(struct dvb_usb_adapter * adap)595 static 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 
mxl111sf_fe_ioctl_override(struct dvb_frontend * fe,unsigned int cmd,void * parg,unsigned int stage)611 static 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 
mxl111sf_i2c_func(struct i2c_adapter * adapter)638 static u32 mxl111sf_i2c_func(struct i2c_adapter *adapter)
639 {
640 	return I2C_FUNC_I2C;
641 }
642 
643 struct 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 
651 static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties;
652 static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties;
653 static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties;
654 static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties;
655 
mxl111sf_probe(struct usb_interface * intf,const struct usb_device_id * id)656 static 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 
720 static 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 };
757 MODULE_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 
837 static 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 
879 static 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 
921 static 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 
982 static 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 
1043 static 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 
1050 module_usb_driver(mxl111sf_driver);
1051 
1052 MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>");
1053 MODULE_DESCRIPTION("Driver for MaxLinear MxL111SF");
1054 MODULE_VERSION("1.0");
1055 MODULE_LICENSE("GPL");
1056 
1057 /*
1058  * Local variables:
1059  * c-basic-offset: 8
1060  * End:
1061  */
1062