m920x.c 22.3 KB
Newer Older
1 2 3 4 5
/* DVB USB compliant linux driver for MSI Mega Sky 580 DVB-T USB2.0 receiver
 *
 * Copyright (C) 2006 Aapo Tahkola (aet@rasterburn.org)
 *
 *	This program is free software; you can redistribute it and/or modify it
6 7
 *	under the terms of the GNU General Public License as published by the
 *	Free Software Foundation, version 2.
8 9 10
 *
 * see Documentation/dvb/README.dvb-usb for more information
 */
11

12
#include "m920x.h"
13 14 15

#include "mt352.h"
#include "mt352_priv.h"
16
#include "qt1010.h"
17 18
#include "tda1004x.h"
#include "tda827x.h"
19 20

/* debug */
21
static int dvb_usb_m920x_debug;
22
module_param_named(debug,dvb_usb_m920x_debug, int, 0644);
23 24
MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);

25 26
static int m920x_set_filter(struct dvb_usb_device *d, int type, int idx, int pid);

27
static inline int m920x_read(struct usb_device *udev, u8 request, u16 value,
28
			     u16 index, void *data, int size)
29 30 31 32 33 34
{
	int ret;

	ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
			      request, USB_TYPE_VENDOR | USB_DIR_IN,
			      value, index, data, size, 2000);
35 36
	if (ret < 0) {
		printk(KERN_INFO "m920x_read = error: %d\n", ret);
37
		return ret;
38
	}
39

40
	if (ret != size) {
41
		deb("m920x_read = no data\n");
42
		return -EIO;
43
	}
44 45 46 47

	return 0;
}

48
static inline int m920x_write(struct usb_device *udev, u8 request,
49
			      u16 value, u16 index)
50 51 52 53 54 55
{
	int ret;

	ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
			      request, USB_TYPE_VENDOR | USB_DIR_OUT,
			      value, index, NULL, 0, 2000);
56

57 58 59
	return ret;
}

60
static int m920x_init(struct dvb_usb_device *d, struct m920x_inits *rc_seq)
61
{
62
	int ret = 0, i, epi, flags = 0;
63
	int adap_enabled[M9206_MAX_ADAPTERS] = { 0 };
64 65

	/* Remote controller init. */
66
	if (d->props.rc_query) {
67
		deb("Initialising remote control\n");
68
		while (rc_seq->address) {
69
			if ((ret = m920x_write(d->udev, M9206_CORE,
70 71
					       rc_seq->data,
					       rc_seq->address)) != 0) {
72
				deb("Initialising remote control failed\n");
73 74
				return ret;
			}
75

76 77 78
			rc_seq++;
		}

79
		deb("Initialising remote control success\n");
80
	}
81

82 83
	for (i = 0; i < d->props.num_adapters; i++)
		flags |= d->adapter[i].props.caps;
84

85 86 87 88
	/* Some devices(Dposh) might crash if we attempt touch at all. */
	if (flags & DVB_USB_ADAP_HAS_PID_FILTER) {
		for (i = 0; i < d->props.num_adapters; i++) {
			epi = d->adapter[i].props.stream.endpoint - 0x81;
89

90 91 92 93 94 95 96
			if (epi < 0 || epi >= M9206_MAX_ADAPTERS) {
				printk(KERN_INFO "m920x: Unexpected adapter endpoint!\n");
				return -EINVAL;
			}

			adap_enabled[epi] = 1;
		}
97

98 99 100
		for (i = 0; i < M9206_MAX_ADAPTERS; i++) {
			if (adap_enabled[i])
				continue;
101

102 103
			if ((ret = m920x_set_filter(d, 0x81 + i, 0, 0x0)) != 0)
				return ret;
104

105 106 107
			if ((ret = m920x_set_filter(d, 0x81 + i, 0, 0x02f5)) != 0)
				return ret;
		}
108 109
	}

110 111 112
	return ret;
}

113 114 115 116 117 118 119 120 121 122 123 124 125 126
static int m920x_init_ep(struct usb_interface *intf)
{
	struct usb_device *udev = interface_to_usbdev(intf);
	struct usb_host_interface *alt;

	if ((alt = usb_altnum_to_altsetting(intf, 1)) == NULL) {
		deb("No alt found!\n");
		return -ENODEV;
	}

	return usb_set_interface(udev, alt->desc.bInterfaceNumber,
				 alt->desc.bAlternateSetting);
}

127
static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
128
{
129
	struct m920x_state *m = d->priv;
130 131 132
	int i, ret = 0;
	u8 rc_state[2];

133
	if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_STATE, rc_state, 1)) != 0)
134 135
		goto unlock;

136
	if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_KEY, rc_state + 1, 1)) != 0)
137 138
		goto unlock;

139 140 141
	for (i = 0; i < d->props.rc_key_map_size; i++)
		if (d->props.rc_key_map[i].data == rc_state[1]) {
			*event = d->props.rc_key_map[i].event;
142 143 144 145 146 147

			switch(rc_state[0]) {
			case 0x80:
				*state = REMOTE_NO_KEY_PRESSED;
				goto unlock;

148 149 150 151 152 153 154 155
			case 0x88: /* framing error or "invalid code" */
			case 0x99:
			case 0xc0:
			case 0xd8:
				*state = REMOTE_NO_KEY_PRESSED;
				m->rep_count = 0;
				goto unlock;

156 157
			case 0x93:
			case 0x92:
158
				m->rep_count = 0;
159 160 161 162
				*state = REMOTE_KEY_PRESSED;
				goto unlock;

			case 0x91:
163
				/* prevent immediate auto-repeat */
164 165
				if (++m->rep_count > 2)
					*state = REMOTE_KEY_REPEAT;
166 167
				else
					*state = REMOTE_NO_KEY_PRESSED;
168 169 170
				goto unlock;

			default:
171
				deb("Unexpected rc state %02x\n", rc_state[0]);
172 173 174 175 176 177
				*state = REMOTE_NO_KEY_PRESSED;
				goto unlock;
			}
		}

	if (rc_state[1] != 0)
178
		deb("Unknown rc key %02x\n", rc_state[1]);
179 180 181

	*state = REMOTE_NO_KEY_PRESSED;

182
 unlock:
183 184 185 186 187

	return ret;
}

/* I2C */
188
static int m920x_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
189 190
{
	struct dvb_usb_device *d = i2c_get_adapdata(adap);
191
	int i, j;
192 193
	int ret = 0;

194 195 196
	if (!num)
		return -EINVAL;

197 198 199 200
	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
		return -EAGAIN;

	for (i = 0; i < num; i++) {
201
		if (msg[i].flags & (I2C_M_NO_RD_ACK | I2C_M_IGNORE_NAK | I2C_M_TEN) || msg[i].len == 0) {
202 203 204 205 206
			/* For a 0 byte message, I think sending the address
			 * to index 0x80|0x40 would be the correct thing to
			 * do.  However, zero byte messages are only used for
			 * probing, and since we don't know how to get the
			 * slave's ack, we can't probe. */
207 208 209 210 211
			ret = -ENOTSUPP;
			goto unlock;
		}
		/* Send START & address/RW bit */
		if (!(msg[i].flags & I2C_M_NOSTART)) {
212
			if ((ret = m920x_write(d->udev, M9206_I2C,
213
					(msg[i].addr << 1) |
214
					(msg[i].flags & I2C_M_RD ? 0x01 : 0), 0x80)) != 0)
215
				goto unlock;
216 217 218 219
			/* Should check for ack here, if we knew how. */
		}
		if (msg[i].flags & I2C_M_RD) {
			for (j = 0; j < msg[i].len; j++) {
220 221
				/* Last byte of transaction?
				 * Send STOP, otherwise send ACK. */
222
				int stop = (i+1 == num && j+1 == msg[i].len) ? 0x40 : 0x01;
223

224
				if ((ret = m920x_read(d->udev, M9206_I2C, 0x0,
225
						      0x20 | stop,
226
						      &msg[i].buf[j], 1)) != 0)
227
					goto unlock;
228
			}
229
		} else {
230 231
			for (j = 0; j < msg[i].len; j++) {
				/* Last byte of transaction? Then send STOP. */
232
				int stop = (i+1 == num && j+1 == msg[i].len) ? 0x40 : 0x00;
233

234
				if ((ret = m920x_write(d->udev, M9206_I2C, msg[i].buf[j], stop)) != 0)
235 236
					goto unlock;
				/* Should check for ack here too. */
237
			}
238 239
		}
	}
240
	ret = num;
241

242
 unlock:
243 244 245 246 247
	mutex_unlock(&d->i2c_mutex);

	return ret;
}

248
static u32 m920x_i2c_func(struct i2c_adapter *adapter)
249 250 251 252
{
	return I2C_FUNC_I2C;
}

253 254 255
static struct i2c_algorithm m920x_i2c_algo = {
	.master_xfer   = m920x_i2c_xfer,
	.functionality = m920x_i2c_func,
256 257
};

258
/* pid filter */
259
static int m920x_set_filter(struct dvb_usb_device *d, int type, int idx, int pid)
260 261 262 263 264 265 266 267
{
	int ret = 0;

	if (pid >= 0x8000)
		return -EINVAL;

	pid |= 0x8000;

268
	if ((ret = m920x_write(d->udev, M9206_FILTER, pid, (type << 8) | (idx * 4) )) != 0)
269 270
		return ret;

271
	if ((ret = m920x_write(d->udev, M9206_FILTER, 0, (type << 8) | (idx * 4) )) != 0)
272 273 274 275 276
		return ret;

	return ret;
}

277
static int m920x_update_filters(struct dvb_usb_adapter *adap)
278
{
279
	struct m920x_state *m = adap->dev->priv;
280
	int enabled = m->filtering_enabled[adap->id];
281
	int i, ret = 0, filter = 0;
282
	int ep = adap->props.stream.endpoint;
283

284
	for (i = 0; i < M9206_MAX_FILTERS; i++)
285
		if (m->filters[adap->id][i] == 8192)
286
			enabled = 0;
287

288
	/* Disable all filters */
289
	if ((ret = m920x_set_filter(adap->dev, ep, 1, enabled)) != 0)
290
		return ret;
291

292
	for (i = 0; i < M9206_MAX_FILTERS; i++)
293
		if ((ret = m920x_set_filter(adap->dev, ep, i + 2, 0)) != 0)
294 295 296 297 298
			return ret;

	/* Set */
	if (enabled) {
		for (i = 0; i < M9206_MAX_FILTERS; i++) {
299
			if (m->filters[adap->id][i] == 0)
300 301
				continue;

302
			if ((ret = m920x_set_filter(adap->dev, ep, filter + 2, m->filters[adap->id][i])) != 0)
303 304 305 306
				return ret;

			filter++;
		}
307
	}
308

309 310 311
	return ret;
}

312
static int m920x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
313
{
314
	struct m920x_state *m = adap->dev->priv;
315

316
	m->filtering_enabled[adap->id] = onoff ? 1 : 0;
317

318
	return m920x_update_filters(adap);
319
}
320

321
static int m920x_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff)
322
{
323
	struct m920x_state *m = adap->dev->priv;
324

325
	m->filters[adap->id][index] = onoff ? pid : 0;
326

327
	return m920x_update_filters(adap);
328 329
}

330
static int m920x_firmware_download(struct usb_device *udev, const struct firmware *fw)
331 332 333 334 335 336 337
{
	u16 value, index, size;
	u8 read[4], *buff;
	int i, pass, ret = 0;

	buff = kmalloc(65536, GFP_KERNEL);

338
	if ((ret = m920x_read(udev, M9206_FILTER, 0x0, 0x8000, read, 4)) != 0)
339
		goto done;
340
	deb("%x %x %x %x\n", read[0], read[1], read[2], read[3]);
341

342
	if ((ret = m920x_read(udev, M9206_FW, 0x0, 0x0, read, 1)) != 0)
343
		goto done;
344
	deb("%x\n", read[0]);
345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361

	for (pass = 0; pass < 2; pass++) {
		for (i = 0; i + (sizeof(u16) * 3) < fw->size;) {
			value = le16_to_cpu(*(u16 *)(fw->data + i));
			i += sizeof(u16);

			index = le16_to_cpu(*(u16 *)(fw->data + i));
			i += sizeof(u16);

			size = le16_to_cpu(*(u16 *)(fw->data + i));
			i += sizeof(u16);

			if (pass == 1) {
				/* Will stall if using fw->data ... */
				memcpy(buff, fw->data + i, size);

				ret = usb_control_msg(udev, usb_sndctrlpipe(udev,0),
362 363 364
						      M9206_FW,
						      USB_TYPE_VENDOR | USB_DIR_OUT,
						      value, index, buff, size, 20);
365
				if (ret != size) {
366
					deb("error while uploading fw!\n");
367 368 369 370 371 372 373 374
					ret = -EIO;
					goto done;
				}
				msleep(3);
			}
			i += size;
		}
		if (i != fw->size) {
375
			deb("bad firmware file!\n");
376 377 378 379 380 381 382
			ret = -EINVAL;
			goto done;
		}
	}

	msleep(36);

383 384
	/* m920x will disconnect itself from the bus after this. */
	(void) m920x_write(udev, M9206_CORE, 0x01, M9206_FW_GO);
385
	deb("firmware uploaded!\n");
386

387
 done:
388 389 390 391 392
	kfree(buff);

	return ret;
}

393
/* Callbacks for DVB USB */
394 395 396 397
static int m920x_identify_state(struct usb_device *udev,
				struct dvb_usb_device_properties *props,
				struct dvb_usb_device_description **desc,
				int *cold)
398 399 400 401 402 403 404 405 406
{
	struct usb_host_interface *alt;

	alt = usb_altnum_to_altsetting(usb_ifnum_to_if(udev, 0), 1);
	*cold = (alt == NULL) ? 1 : 0;

	return 0;
}

407
/* demod configurations */
408
static int m920x_mt352_demod_init(struct dvb_frontend *fe)
409
{
410
	int ret;
411 412 413 414 415 416 417 418 419
	u8 config[] = { CONFIG, 0x3d };
	u8 clock[] = { CLOCK_CTL, 0x30 };
	u8 reset[] = { RESET, 0x80 };
	u8 adc_ctl[] = { ADC_CTL_1, 0x40 };
	u8 agc[] = { AGC_TARGET, 0x1c, 0x20 };
	u8 sec_agc[] = { 0x69, 0x00, 0xff, 0xff, 0x40, 0xff, 0x00, 0x40, 0x40 };
	u8 unk1[] = { 0x93, 0x1a };
	u8 unk2[] = { 0xb5, 0x7a };

420
	deb("Demod init!\n");
421

422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438
	if ((ret = mt352_write(fe, config, ARRAY_SIZE(config))) != 0)
		return ret;
	if ((ret = mt352_write(fe, clock, ARRAY_SIZE(clock))) != 0)
		return ret;
	if ((ret = mt352_write(fe, reset, ARRAY_SIZE(reset))) != 0)
		return ret;
	if ((ret = mt352_write(fe, adc_ctl, ARRAY_SIZE(adc_ctl))) != 0)
		return ret;
	if ((ret = mt352_write(fe, agc, ARRAY_SIZE(agc))) != 0)
		return ret;
	if ((ret = mt352_write(fe, sec_agc, ARRAY_SIZE(sec_agc))) != 0)
		return ret;
	if ((ret = mt352_write(fe, unk1, ARRAY_SIZE(unk1))) != 0)
		return ret;
	if ((ret = mt352_write(fe, unk2, ARRAY_SIZE(unk2))) != 0)
		return ret;

439 440 441
	return 0;
}

442
static struct mt352_config m920x_mt352_config = {
443
	.demod_address = 0x0f,
444
	.no_tuner = 1,
445
	.demod_init = m920x_mt352_demod_init,
446 447
};

448
static struct tda1004x_config m920x_tda10046_08_config = {
449 450 451 452 453 454 455 456 457 458 459
	.demod_address = 0x08,
	.invert = 0,
	.invert_oclk = 0,
	.ts_mode = TDA10046_TS_SERIAL,
	.xtal_freq = TDA10046_XTAL_16M,
	.if_freq = TDA10046_FREQ_045,
	.agc_config = TDA10046_AGC_TDA827X,
	.gpio_config = TDA10046_GPTRI,
	.request_firmware = NULL,
};

460
static struct tda1004x_config m920x_tda10046_0b_config = {
461 462 463 464 465 466 467 468 469 470 471
	.demod_address = 0x0b,
	.invert = 0,
	.invert_oclk = 0,
	.ts_mode = TDA10046_TS_SERIAL,
	.xtal_freq = TDA10046_XTAL_16M,
	.if_freq = TDA10046_FREQ_045,
	.agc_config = TDA10046_AGC_TDA827X,
	.gpio_config = TDA10046_GPTRI,
	.request_firmware = NULL, /* uses firmware EEPROM */
};

472
/* tuner configurations */
473
static struct qt1010_config m920x_qt1010_config = {
474 475 476 477
	.i2c_address = 0x62
};

/* Callbacks for DVB USB */
478
static int m920x_mt352_frontend_attach(struct dvb_usb_adapter *adap)
479
{
480
	deb("%s\n",__FUNCTION__);
481

482 483
	if ((adap->fe = dvb_attach(mt352_attach,
				   &m920x_mt352_config,
484 485 486 487 488 489
				   &adap->dev->i2c_adap)) == NULL)
		return -EIO;

	return 0;
}

490
static int m920x_tda10046_08_frontend_attach(struct dvb_usb_adapter *adap)
491
{
492
	deb("%s\n",__FUNCTION__);
493

494
	if ((adap->fe = dvb_attach(tda10046_attach,
495
				   &m920x_tda10046_08_config,
496
				   &adap->dev->i2c_adap)) == NULL)
497 498 499 500 501
		return -EIO;

	return 0;
}

502
static int m920x_tda10046_0b_frontend_attach(struct dvb_usb_adapter *adap)
503
{
504
	deb("%s\n",__FUNCTION__);
505

506
	if ((adap->fe = dvb_attach(tda10046_attach,
507
				   &m920x_tda10046_0b_config,
508
				   &adap->dev->i2c_adap)) == NULL)
509 510 511 512 513
		return -EIO;

	return 0;
}

514
static int m920x_qt1010_tuner_attach(struct dvb_usb_adapter *adap)
515
{
516
	deb("%s\n",__FUNCTION__);
517

518
	if (dvb_attach(qt1010_attach, adap->fe, &adap->dev->i2c_adap, &m920x_qt1010_config) == NULL)
519 520 521 522 523
		return -ENODEV;

	return 0;
}

524
static int m920x_tda8275_60_tuner_attach(struct dvb_usb_adapter *adap)
525
{
526
	deb("%s\n",__FUNCTION__);
527

528
	if (dvb_attach(tda827x_attach, adap->fe, 0x60, &adap->dev->i2c_adap, NULL) == NULL)
529 530 531 532 533
		return -ENODEV;

	return 0;
}

534
static int m920x_tda8275_61_tuner_attach(struct dvb_usb_adapter *adap)
535
{
536
	deb("%s\n",__FUNCTION__);
537

538
	if (dvb_attach(tda827x_attach, adap->fe, 0x61, &adap->dev->i2c_adap, NULL) == NULL)
539 540 541 542 543
		return -ENODEV;

	return 0;
}

544
/* device-specific initialization */
545
static struct m920x_inits megasky_rc_init [] = {
546 547 548 549 550
	{ M9206_RC_INIT2, 0xa8 },
	{ M9206_RC_INIT1, 0x51 },
	{ } /* terminating entry */
};

551
static struct m920x_inits tvwalkertwin_rc_init [] = {
552 553 554 555 556 557 558 559
	{ M9206_RC_INIT2, 0x00 },
	{ M9206_RC_INIT1, 0xef },
	{ 0xff28,         0x00 },
	{ 0xff23,         0x00 },
	{ 0xff21,         0x30 },
	{ } /* terminating entry */
};

560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599
/* ir keymaps */
static struct dvb_usb_rc_key megasky_rc_keys [] = {
	{ 0x0, 0x12, KEY_POWER },
	{ 0x0, 0x1e, KEY_CYCLEWINDOWS }, /* min/max */
	{ 0x0, 0x02, KEY_CHANNELUP },
	{ 0x0, 0x05, KEY_CHANNELDOWN },
	{ 0x0, 0x03, KEY_VOLUMEUP },
	{ 0x0, 0x06, KEY_VOLUMEDOWN },
	{ 0x0, 0x04, KEY_MUTE },
	{ 0x0, 0x07, KEY_OK }, /* TS */
	{ 0x0, 0x08, KEY_STOP },
	{ 0x0, 0x09, KEY_MENU }, /* swap */
	{ 0x0, 0x0a, KEY_REWIND },
	{ 0x0, 0x1b, KEY_PAUSE },
	{ 0x0, 0x1f, KEY_FASTFORWARD },
	{ 0x0, 0x0c, KEY_RECORD },
	{ 0x0, 0x0d, KEY_CAMERA }, /* screenshot */
	{ 0x0, 0x0e, KEY_COFFEE }, /* "MTS" */
};

static struct dvb_usb_rc_key tvwalkertwin_rc_keys [] = {
	{ 0x0, 0x01, KEY_ZOOM }, /* Full Screen */
	{ 0x0, 0x02, KEY_CAMERA }, /* snapshot */
	{ 0x0, 0x03, KEY_MUTE },
	{ 0x0, 0x04, KEY_REWIND },
	{ 0x0, 0x05, KEY_PLAYPAUSE }, /* Play/Pause */
	{ 0x0, 0x06, KEY_FASTFORWARD },
	{ 0x0, 0x07, KEY_RECORD },
	{ 0x0, 0x08, KEY_STOP },
	{ 0x0, 0x09, KEY_TIME }, /* Timeshift */
	{ 0x0, 0x0c, KEY_COFFEE }, /* Recall */
	{ 0x0, 0x0e, KEY_CHANNELUP },
	{ 0x0, 0x12, KEY_POWER },
	{ 0x0, 0x15, KEY_MENU }, /* source */
	{ 0x0, 0x18, KEY_CYCLEWINDOWS }, /* TWIN PIP */
	{ 0x0, 0x1a, KEY_CHANNELDOWN },
	{ 0x0, 0x1b, KEY_VOLUMEDOWN },
	{ 0x0, 0x1e, KEY_VOLUMEUP },
};

600 601
/* DVB USB Driver stuff */
static struct dvb_usb_device_properties megasky_properties;
602
static struct dvb_usb_device_properties digivox_mini_ii_properties;
603
static struct dvb_usb_device_properties tvwalkertwin_properties;
604
static struct dvb_usb_device_properties dposh_properties;
605

606 607
static int m920x_probe(struct usb_interface *intf,
		       const struct usb_device_id *id)
608
{
609
	struct dvb_usb_device *d = NULL;
610
	int ret;
611
	struct m920x_inits *rc_init_seq = NULL;
612
	int bInterfaceNumber = intf->cur_altsetting->desc.bInterfaceNumber;
613

614
	deb("Probing for m920x device at interface %d\n", bInterfaceNumber);
615

616 617 618 619
	if (bInterfaceNumber == 0) {
		/* Single-tuner device, or first interface on
		 * multi-tuner device
		 */
620

621
		if ((ret = dvb_usb_device_init(intf, &megasky_properties,
622
					       THIS_MODULE, &d)) == 0) {
623 624 625 626
			rc_init_seq = megasky_rc_init;
			goto found;
		}

627
		if ((ret = dvb_usb_device_init(intf, &digivox_mini_ii_properties,
628
					       THIS_MODULE, &d)) == 0) {
629 630 631 632 633 634
			/* No remote control, so no rc_init_seq */
			goto found;
		}

		/* This configures both tuners on the TV Walker Twin */
		if ((ret = dvb_usb_device_init(intf, &tvwalkertwin_properties,
635
					       THIS_MODULE, &d)) == 0) {
636 637 638 639
			rc_init_seq = tvwalkertwin_rc_init;
			goto found;
		}

640 641
		if ((ret = dvb_usb_device_init(intf, &dposh_properties,
					       THIS_MODULE, &d)) == 0) {
642 643 644 645
			/* Remote controller not supported yet. */
			goto found;
		}

646 647 648 649 650 651 652 653 654
		return ret;
	} else {
		/* Another interface on a multi-tuner device */

		/* The LifeView TV Walker Twin gets here, but struct
		 * tvwalkertwin_properties already configured both
		 * tuners, so there is nothing for us to do here
		 */
	}
655

656
 found:
657
	if ((ret = m920x_init_ep(intf)) < 0)
658 659
		return ret;

660
	if (d && (ret = m920x_init(d, rc_init_seq)) != 0)
661 662
		return ret;

663 664 665 666 667
	return ret;
}

static struct usb_device_id m920x_table [] = {
		{ USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580) },
668 669
		{ USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC,
			     USB_PID_MSI_DIGI_VOX_MINI_II) },
670 671 672 673
		{ USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC,
			     USB_PID_LIFEVIEW_TV_WALKER_TWIN_COLD) },
		{ USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC,
			     USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM) },
674 675
		{ USB_DEVICE(USB_VID_DPOSH, USB_PID_DPOSH_M9206_COLD) },
		{ USB_DEVICE(USB_VID_DPOSH, USB_PID_DPOSH_M9206_WARM) },
676 677 678 679
		{ }		/* Terminating entry */
};
MODULE_DEVICE_TABLE (usb, m920x_table);

680
static struct dvb_usb_device_properties megasky_properties = {
681
	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
682

683 684
	.usb_ctrl = DEVICE_SPECIFIC,
	.firmware = "dvb-usb-megasky-02.fw",
685
	.download_firmware = m920x_firmware_download,
686

687
	.rc_interval      = 100,
688 689
	.rc_key_map       = megasky_rc_keys,
	.rc_key_map_size  = ARRAY_SIZE(megasky_rc_keys),
690
	.rc_query         = m920x_rc_query,
691

692
	.size_of_priv     = sizeof(struct m920x_state),
693

694
	.identify_state   = m920x_identify_state,
695 696
	.num_adapters = 1,
	.adapter = {{
697 698 699
		.caps = DVB_USB_ADAP_HAS_PID_FILTER |
			DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,

700
		.pid_filter_count = 8,
701 702
		.pid_filter       = m920x_pid_filter,
		.pid_filter_ctrl  = m920x_pid_filter_ctrl,
703

704 705
		.frontend_attach  = m920x_mt352_frontend_attach,
		.tuner_attach     = m920x_qt1010_tuner_attach,
706 707 708 709 710 711 712 713 714 715 716 717

		.stream = {
			.type = USB_BULK,
			.count = 8,
			.endpoint = 0x81,
			.u = {
				.bulk = {
					.buffersize = 512,
				}
			}
		},
	}},
718
	.i2c_algo         = &m920x_i2c_algo,
719 720 721 722

	.num_device_descs = 1,
	.devices = {
		{   "MSI Mega Sky 580 DVB-T USB2.0",
723
			{ &m920x_table[0], NULL },
724
			{ NULL },
725 726 727 728 729 730 731 732 733
		}
	}
};

static struct dvb_usb_device_properties digivox_mini_ii_properties = {
	.caps = DVB_USB_IS_AN_I2C_ADAPTER,

	.usb_ctrl = DEVICE_SPECIFIC,
	.firmware = "dvb-usb-digivox-02.fw",
734
	.download_firmware = m920x_firmware_download,
735

736
	.size_of_priv     = sizeof(struct m920x_state),
737 738 739 740 741

	.identify_state   = m920x_identify_state,
	.num_adapters = 1,
	.adapter = {{
		.caps = DVB_USB_ADAP_HAS_PID_FILTER |
742
			DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
743 744

		.pid_filter_count = 8,
745 746
		.pid_filter       = m920x_pid_filter,
		.pid_filter_ctrl  = m920x_pid_filter_ctrl,
747

748 749
		.frontend_attach  = m920x_tda10046_08_frontend_attach,
		.tuner_attach     = m920x_tda8275_60_tuner_attach,
750 751 752 753 754 755 756 757 758 759 760 761

		.stream = {
			.type = USB_BULK,
			.count = 8,
			.endpoint = 0x81,
			.u = {
				.bulk = {
					.buffersize = 0x4000,
				}
			}
		},
	}},
762
	.i2c_algo         = &m920x_i2c_algo,
763 764 765 766 767 768

	.num_device_descs = 1,
	.devices = {
		{   "MSI DIGI VOX mini II DVB-T USB2.0",
			{ &m920x_table[1], NULL },
			{ NULL },
769 770 771 772
		},
	}
};

773 774 775 776
/* LifeView TV Walker Twin support by Nick Andrew <nick@nick-andrew.net>
 *
 * LifeView TV Walker Twin has 1 x M9206, 2 x TDA10046, 2 x TDA8275A
 * TDA10046 #0 is located at i2c address 0x08
777
 * TDA10046 #1 is located at i2c address 0x0b
778
 * TDA8275A #0 is located at i2c address 0x60
779
 * TDA8275A #1 is located at i2c address 0x61
780
 */
781 782 783 784 785
static struct dvb_usb_device_properties tvwalkertwin_properties = {
	.caps = DVB_USB_IS_AN_I2C_ADAPTER,

	.usb_ctrl = DEVICE_SPECIFIC,
	.firmware = "dvb-usb-tvwalkert.fw",
786
	.download_firmware = m920x_firmware_download,
787 788 789 790

	.rc_interval      = 100,
	.rc_key_map       = tvwalkertwin_rc_keys,
	.rc_key_map_size  = ARRAY_SIZE(tvwalkertwin_rc_keys),
791
	.rc_query         = m920x_rc_query,
792

793
	.size_of_priv     = sizeof(struct m920x_state),
794 795

	.identify_state   = m920x_identify_state,
796
	.num_adapters = 2,
797 798 799 800 801
	.adapter = {{
		.caps = DVB_USB_ADAP_HAS_PID_FILTER |
			DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,

		.pid_filter_count = 8,
802 803
		.pid_filter       = m920x_pid_filter,
		.pid_filter_ctrl  = m920x_pid_filter_ctrl,
804

805 806
		.frontend_attach  = m920x_tda10046_08_frontend_attach,
		.tuner_attach     = m920x_tda8275_60_tuner_attach,
807 808 809 810 811 812 813 814 815 816 817 818 819 820 821

		.stream = {
			.type = USB_BULK,
			.count = 8,
			.endpoint = 0x81,
			.u = {
				 .bulk = {
					 .buffersize = 512,
				 }
			}
		}},{
		.caps = DVB_USB_ADAP_HAS_PID_FILTER |
			DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,

		.pid_filter_count = 8,
822 823
		.pid_filter       = m920x_pid_filter,
		.pid_filter_ctrl  = m920x_pid_filter_ctrl,
824

825 826
		.frontend_attach  = m920x_tda10046_0b_frontend_attach,
		.tuner_attach     = m920x_tda8275_61_tuner_attach,
827 828 829 830 831 832 833 834 835 836

		.stream = {
			.type = USB_BULK,
			.count = 8,
			.endpoint = 0x82,
			.u = {
				 .bulk = {
					 .buffersize = 512,
				 }
			}
837
		},
838
	}},
839
	.i2c_algo         = &m920x_i2c_algo,
840 841 842 843 844 845 846 847 848 849

	.num_device_descs = 1,
	.devices = {
		{   .name = "LifeView TV Walker Twin DVB-T USB2.0",
		    .cold_ids = { &m920x_table[2], NULL },
		    .warm_ids = { &m920x_table[3], NULL },
		},
	}
};

850 851 852 853 854
static struct dvb_usb_device_properties dposh_properties = {
	.caps = DVB_USB_IS_AN_I2C_ADAPTER,

	.usb_ctrl = DEVICE_SPECIFIC,
	.firmware = "dvb-usb-dposh-01.fw",
855
	.download_firmware = m920x_firmware_download,
856

857
	.size_of_priv     = sizeof(struct m920x_state),
858 859 860 861

	.identify_state   = m920x_identify_state,
	.num_adapters = 1,
	.adapter = {{
862 863
		/* Hardware pid filters don't work with this device/firmware */

864 865
		.frontend_attach  = m920x_mt352_frontend_attach,
		.tuner_attach     = m920x_qt1010_tuner_attach,
866 867 868 869 870 871 872 873 874 875 876 877

		.stream = {
			.type = USB_BULK,
			.count = 8,
			.endpoint = 0x81,
			.u = {
				 .bulk = {
					 .buffersize = 512,
				 }
			}
		},
	}},
878
	.i2c_algo         = &m920x_i2c_algo,
879 880 881 882 883 884 885 886 887 888

	.num_device_descs = 1,
	.devices = {
		 {   .name = "Dposh DVB-T USB2.0",
		     .cold_ids = { &m920x_table[4], NULL },
		     .warm_ids = { &m920x_table[5], NULL },
		 },
	 }
};

889 890
static struct usb_driver m920x_driver = {
	.name		= "dvb_usb_m920x",
891
	.probe		= m920x_probe,
892
	.disconnect	= dvb_usb_device_exit,
893
	.id_table	= m920x_table,
894 895 896
};

/* module stuff */
897
static int __init m920x_module_init(void)
898 899 900
{
	int ret;

901
	if ((ret = usb_register(&m920x_driver))) {
902 903 904 905 906 907 908
		err("usb_register failed. Error number %d", ret);
		return ret;
	}

	return 0;
}

909
static void __exit m920x_module_exit(void)
910 911
{
	/* deregister this driver from the USB subsystem */
912
	usb_deregister(&m920x_driver);
913 914
}

915 916
module_init (m920x_module_init);
module_exit (m920x_module_exit);
917 918

MODULE_AUTHOR("Aapo Tahkola <aet@rasterburn.org>");
919
MODULE_DESCRIPTION("DVB Driver for ULI M920x");
920 921
MODULE_VERSION("0.1");
MODULE_LICENSE("GPL");
922 923 924 925 926

/*
 * Local variables:
 * c-basic-offset: 8
 */