1/*
2 * ngene-cards.c: nGene PCIe bridge driver - card specific info
3 *
4 * Copyright (C) 2005-2007 Micronas
5 *
6 * Copyright (C) 2008-2009 Ralph Metzler <rjkm@metzlerbros.de>
7 *                         Modifications for new nGene firmware,
8 *                         support for EEPROM-copying,
9 *                         support for new dual DVB-S2 card prototype
10 *
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * version 2 only, as published by the Free Software Foundation.
15 *
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 * GNU General Public License for more details.
21 *
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 * 02110-1301, USA
27 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
28 */
29
30#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/pci.h>
33#include <linux/pci_ids.h>
34
35#include "ngene.h"
36
37/* demods/tuners */
38#include "stv6110x.h"
39#include "stv090x.h"
40#include "lnbh24.h"
41#include "lgdt330x.h"
42#include "mt2131.h"
43#include "tda18271c2dd.h"
44#include "drxk.h"
45#include "drxd.h"
46#include "dvb-pll.h"
47
48
49/****************************************************************************/
50/* Demod/tuner attachment ***************************************************/
51/****************************************************************************/
52
53static int tuner_attach_stv6110(struct ngene_channel *chan)
54{
55	struct i2c_adapter *i2c;
56	struct stv090x_config *feconf = (struct stv090x_config *)
57		chan->dev->card_info->fe_config[chan->number];
58	struct stv6110x_config *tunerconf = (struct stv6110x_config *)
59		chan->dev->card_info->tuner_config[chan->number];
60	struct stv6110x_devctl *ctl;
61
62	/* tuner 1+2: i2c adapter #0, tuner 3+4: i2c adapter #1 */
63	if (chan->number < 2)
64		i2c = &chan->dev->channel[0].i2c_adapter;
65	else
66		i2c = &chan->dev->channel[1].i2c_adapter;
67
68	ctl = dvb_attach(stv6110x_attach, chan->fe, tunerconf, i2c);
69	if (ctl == NULL) {
70		printk(KERN_ERR	DEVICE_NAME ": No STV6110X found!\n");
71		return -ENODEV;
72	}
73
74	feconf->tuner_init          = ctl->tuner_init;
75	feconf->tuner_sleep         = ctl->tuner_sleep;
76	feconf->tuner_set_mode      = ctl->tuner_set_mode;
77	feconf->tuner_set_frequency = ctl->tuner_set_frequency;
78	feconf->tuner_get_frequency = ctl->tuner_get_frequency;
79	feconf->tuner_set_bandwidth = ctl->tuner_set_bandwidth;
80	feconf->tuner_get_bandwidth = ctl->tuner_get_bandwidth;
81	feconf->tuner_set_bbgain    = ctl->tuner_set_bbgain;
82	feconf->tuner_get_bbgain    = ctl->tuner_get_bbgain;
83	feconf->tuner_set_refclk    = ctl->tuner_set_refclk;
84	feconf->tuner_get_status    = ctl->tuner_get_status;
85
86	return 0;
87}
88
89
90static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
91{
92	struct ngene_channel *chan = fe->sec_priv;
93	int status;
94
95	if (enable) {
96		down(&chan->dev->pll_mutex);
97		status = chan->gate_ctrl(fe, 1);
98	} else {
99		status = chan->gate_ctrl(fe, 0);
100		up(&chan->dev->pll_mutex);
101	}
102	return status;
103}
104
105static int tuner_attach_tda18271(struct ngene_channel *chan)
106{
107	struct i2c_adapter *i2c;
108	struct dvb_frontend *fe;
109
110	i2c = &chan->dev->channel[0].i2c_adapter;
111	if (chan->fe->ops.i2c_gate_ctrl)
112		chan->fe->ops.i2c_gate_ctrl(chan->fe, 1);
113	fe = dvb_attach(tda18271c2dd_attach, chan->fe, i2c, 0x60);
114	if (chan->fe->ops.i2c_gate_ctrl)
115		chan->fe->ops.i2c_gate_ctrl(chan->fe, 0);
116	if (!fe) {
117		printk(KERN_ERR "No TDA18271 found!\n");
118		return -ENODEV;
119	}
120
121	return 0;
122}
123
124static int tuner_attach_probe(struct ngene_channel *chan)
125{
126	if (chan->demod_type == 0)
127		return tuner_attach_stv6110(chan);
128	if (chan->demod_type == 1)
129		return tuner_attach_tda18271(chan);
130	return -EINVAL;
131}
132
133static int demod_attach_stv0900(struct ngene_channel *chan)
134{
135	struct i2c_adapter *i2c;
136	struct stv090x_config *feconf = (struct stv090x_config *)
137		chan->dev->card_info->fe_config[chan->number];
138
139	/* tuner 1+2: i2c adapter #0, tuner 3+4: i2c adapter #1 */
140	/* Note: Both adapters share the same i2c bus, but the demod     */
141	/*       driver requires that each demod has its own i2c adapter */
142	if (chan->number < 2)
143		i2c = &chan->dev->channel[0].i2c_adapter;
144	else
145		i2c = &chan->dev->channel[1].i2c_adapter;
146
147	chan->fe = dvb_attach(stv090x_attach, feconf, i2c,
148			(chan->number & 1) == 0 ? STV090x_DEMODULATOR_0
149						: STV090x_DEMODULATOR_1);
150	if (chan->fe == NULL) {
151		printk(KERN_ERR	DEVICE_NAME ": No STV0900 found!\n");
152		return -ENODEV;
153	}
154
155	/* store channel info */
156	if (feconf->tuner_i2c_lock)
157		chan->fe->analog_demod_priv = chan;
158
159	if (!dvb_attach(lnbh24_attach, chan->fe, i2c, 0,
160			0, chan->dev->card_info->lnb[chan->number])) {
161		printk(KERN_ERR DEVICE_NAME ": No LNBH24 found!\n");
162		dvb_frontend_detach(chan->fe);
163		chan->fe = NULL;
164		return -ENODEV;
165	}
166
167	return 0;
168}
169
170static void cineS2_tuner_i2c_lock(struct dvb_frontend *fe, int lock)
171{
172	struct ngene_channel *chan = fe->analog_demod_priv;
173
174	if (lock)
175		down(&chan->dev->pll_mutex);
176	else
177		up(&chan->dev->pll_mutex);
178}
179
180static int i2c_read(struct i2c_adapter *adapter, u8 adr, u8 *val)
181{
182	struct i2c_msg msgs[1] = {{.addr = adr,  .flags = I2C_M_RD,
183				   .buf  = val,  .len   = 1 } };
184	return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1;
185}
186
187static int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr,
188			  u16 reg, u8 *val)
189{
190	u8 msg[2] = {reg>>8, reg&0xff};
191	struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
192				   .buf  = msg, .len   = 2},
193				  {.addr = adr, .flags = I2C_M_RD,
194				   .buf  = val, .len   = 1} };
195	return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1;
196}
197
198static int port_has_stv0900(struct i2c_adapter *i2c, int port)
199{
200	u8 val;
201	if (i2c_read_reg16(i2c, 0x68+port/2, 0xf100, &val) < 0)
202		return 0;
203	return 1;
204}
205
206static int port_has_drxk(struct i2c_adapter *i2c, int port)
207{
208	u8 val;
209
210	if (i2c_read(i2c, 0x29+port, &val) < 0)
211		return 0;
212	return 1;
213}
214
215static int demod_attach_drxk(struct ngene_channel *chan,
216			     struct i2c_adapter *i2c)
217{
218	struct drxk_config config;
219
220	memset(&config, 0, sizeof(config));
221	config.microcode_name = "drxk_a3.mc";
222	config.qam_demod_parameter_count = 4;
223	config.adr = 0x29 + (chan->number ^ 2);
224
225	chan->fe = dvb_attach(drxk_attach, &config, i2c);
226	if (!chan->fe) {
227		printk(KERN_ERR "No DRXK found!\n");
228		return -ENODEV;
229	}
230	chan->fe->sec_priv = chan;
231	chan->gate_ctrl = chan->fe->ops.i2c_gate_ctrl;
232	chan->fe->ops.i2c_gate_ctrl = drxk_gate_ctrl;
233	return 0;
234}
235
236static int cineS2_probe(struct ngene_channel *chan)
237{
238	struct i2c_adapter *i2c;
239	struct stv090x_config *fe_conf;
240	u8 buf[3];
241	struct i2c_msg i2c_msg = { .flags = 0, .buf = buf };
242	int rc;
243
244	/* tuner 1+2: i2c adapter #0, tuner 3+4: i2c adapter #1 */
245	if (chan->number < 2)
246		i2c = &chan->dev->channel[0].i2c_adapter;
247	else
248		i2c = &chan->dev->channel[1].i2c_adapter;
249
250	if (port_has_stv0900(i2c, chan->number)) {
251		chan->demod_type = 0;
252		fe_conf = chan->dev->card_info->fe_config[chan->number];
253		/* demod found, attach it */
254		rc = demod_attach_stv0900(chan);
255		if (rc < 0 || chan->number < 2)
256			return rc;
257
258		/* demod #2: reprogram outputs DPN1 & DPN2 */
259		i2c_msg.addr = fe_conf->address;
260		i2c_msg.len = 3;
261		buf[0] = 0xf1;
262		switch (chan->number) {
263		case 2:
264			buf[1] = 0x5c;
265			buf[2] = 0xc2;
266			break;
267		case 3:
268			buf[1] = 0x61;
269			buf[2] = 0xcc;
270			break;
271		default:
272			return -ENODEV;
273		}
274		rc = i2c_transfer(i2c, &i2c_msg, 1);
275		if (rc != 1) {
276			printk(KERN_ERR DEVICE_NAME ": could not setup DPNx\n");
277			return -EIO;
278		}
279	} else if (port_has_drxk(i2c, chan->number^2)) {
280		chan->demod_type = 1;
281		demod_attach_drxk(chan, i2c);
282	} else {
283		printk(KERN_ERR "No demod found on chan %d\n", chan->number);
284		return -ENODEV;
285	}
286	return 0;
287}
288
289
290static struct lgdt330x_config aver_m780 = {
291	.demod_address = 0xb2 >> 1,
292	.demod_chip    = LGDT3303,
293	.serial_mpeg   = 0x00, /* PARALLEL */
294	.clock_polarity_flip = 1,
295};
296
297static struct mt2131_config m780_tunerconfig = {
298	0xc0 >> 1
299};
300
301/* A single func to attach the demo and tuner, rather than
302 * use two sep funcs like the current design mandates.
303 */
304static int demod_attach_lg330x(struct ngene_channel *chan)
305{
306	chan->fe = dvb_attach(lgdt330x_attach, &aver_m780, &chan->i2c_adapter);
307	if (chan->fe == NULL) {
308		printk(KERN_ERR	DEVICE_NAME ": No LGDT330x found!\n");
309		return -ENODEV;
310	}
311
312	dvb_attach(mt2131_attach, chan->fe, &chan->i2c_adapter,
313		   &m780_tunerconfig, 0);
314
315	return (chan->fe) ? 0 : -ENODEV;
316}
317
318static int demod_attach_drxd(struct ngene_channel *chan)
319{
320	struct drxd_config *feconf;
321
322	feconf = chan->dev->card_info->fe_config[chan->number];
323
324	chan->fe = dvb_attach(drxd_attach, feconf, chan,
325			&chan->i2c_adapter, &chan->dev->pci_dev->dev);
326	if (!chan->fe) {
327		pr_err("No DRXD found!\n");
328		return -ENODEV;
329	}
330	return 0;
331}
332
333static int tuner_attach_dtt7520x(struct ngene_channel *chan)
334{
335	struct drxd_config *feconf;
336
337	feconf = chan->dev->card_info->fe_config[chan->number];
338
339	if (!dvb_attach(dvb_pll_attach, chan->fe, feconf->pll_address,
340			&chan->i2c_adapter,
341			feconf->pll_type)) {
342		pr_err("No pll(%d) found!\n", feconf->pll_type);
343		return -ENODEV;
344	}
345	return 0;
346}
347
348/****************************************************************************/
349/* EEPROM TAGS **************************************************************/
350/****************************************************************************/
351
352#define MICNG_EE_START      0x0100
353#define MICNG_EE_END        0x0FF0
354
355#define MICNG_EETAG_END0    0x0000
356#define MICNG_EETAG_END1    0xFFFF
357
358/* 0x0001 - 0x000F reserved for housekeeping */
359/* 0xFFFF - 0xFFFE reserved for housekeeping */
360
361/* Micronas assigned tags
362   EEProm tags for hardware support */
363
364#define MICNG_EETAG_DRXD1_OSCDEVIATION  0x1000  /* 2 Bytes data */
365#define MICNG_EETAG_DRXD2_OSCDEVIATION  0x1001  /* 2 Bytes data */
366
367#define MICNG_EETAG_MT2060_1_1STIF      0x1100  /* 2 Bytes data */
368#define MICNG_EETAG_MT2060_2_1STIF      0x1101  /* 2 Bytes data */
369
370/* Tag range for OEMs */
371
372#define MICNG_EETAG_OEM_FIRST  0xC000
373#define MICNG_EETAG_OEM_LAST   0xFFEF
374
375static int i2c_write_eeprom(struct i2c_adapter *adapter,
376			    u8 adr, u16 reg, u8 data)
377{
378	u8 m[3] = {(reg >> 8), (reg & 0xff), data};
379	struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = m,
380			      .len = sizeof(m)};
381
382	if (i2c_transfer(adapter, &msg, 1) != 1) {
383		pr_err(DEVICE_NAME ": Error writing EEPROM!\n");
384		return -EIO;
385	}
386	return 0;
387}
388
389static int i2c_read_eeprom(struct i2c_adapter *adapter,
390			   u8 adr, u16 reg, u8 *data, int len)
391{
392	u8 msg[2] = {(reg >> 8), (reg & 0xff)};
393	struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
394				   .buf = msg, .len = 2 },
395				  {.addr = adr, .flags = I2C_M_RD,
396				   .buf = data, .len = len} };
397
398	if (i2c_transfer(adapter, msgs, 2) != 2) {
399		pr_err(DEVICE_NAME ": Error reading EEPROM\n");
400		return -EIO;
401	}
402	return 0;
403}
404
405static int ReadEEProm(struct i2c_adapter *adapter,
406		      u16 Tag, u32 MaxLen, u8 *data, u32 *pLength)
407{
408	int status = 0;
409	u16 Addr = MICNG_EE_START, Length, tag = 0;
410	u8  EETag[3];
411
412	while (Addr + sizeof(u16) + 1 < MICNG_EE_END) {
413		if (i2c_read_eeprom(adapter, 0x50, Addr, EETag, sizeof(EETag)))
414			return -1;
415		tag = (EETag[0] << 8) | EETag[1];
416		if (tag == MICNG_EETAG_END0 || tag == MICNG_EETAG_END1)
417			return -1;
418		if (tag == Tag)
419			break;
420		Addr += sizeof(u16) + 1 + EETag[2];
421	}
422	if (Addr + sizeof(u16) + 1 + EETag[2] > MICNG_EE_END) {
423		pr_err(DEVICE_NAME
424		       ": Reached EOEE @ Tag = %04x Length = %3d\n",
425		       tag, EETag[2]);
426		return -1;
427	}
428	Length = EETag[2];
429	if (Length > MaxLen)
430		Length = (u16) MaxLen;
431	if (Length > 0) {
432		Addr += sizeof(u16) + 1;
433		status = i2c_read_eeprom(adapter, 0x50, Addr, data, Length);
434		if (!status) {
435			*pLength = EETag[2];
436#if 0
437			if (Length < EETag[2])
438				status = STATUS_BUFFER_OVERFLOW;
439#endif
440		}
441	}
442	return status;
443}
444
445static int WriteEEProm(struct i2c_adapter *adapter,
446		       u16 Tag, u32 Length, u8 *data)
447{
448	int status = 0;
449	u16 Addr = MICNG_EE_START;
450	u8 EETag[3];
451	u16 tag = 0;
452	int retry, i;
453
454	while (Addr + sizeof(u16) + 1 < MICNG_EE_END) {
455		if (i2c_read_eeprom(adapter, 0x50, Addr, EETag, sizeof(EETag)))
456			return -1;
457		tag = (EETag[0] << 8) | EETag[1];
458		if (tag == MICNG_EETAG_END0 || tag == MICNG_EETAG_END1)
459			return -1;
460		if (tag == Tag)
461			break;
462		Addr += sizeof(u16) + 1 + EETag[2];
463	}
464	if (Addr + sizeof(u16) + 1 + EETag[2] > MICNG_EE_END) {
465		pr_err(DEVICE_NAME
466		       ": Reached EOEE @ Tag = %04x Length = %3d\n",
467		       tag, EETag[2]);
468		return -1;
469	}
470
471	if (Length > EETag[2])
472		return -EINVAL;
473	/* Note: We write the data one byte at a time to avoid
474	   issues with page sizes. (which are different for
475	   each manufacture and eeprom size)
476	 */
477	Addr += sizeof(u16) + 1;
478	for (i = 0; i < Length; i++, Addr++) {
479		status = i2c_write_eeprom(adapter, 0x50, Addr, data[i]);
480
481		if (status)
482			break;
483
484		/* Poll for finishing write cycle */
485		retry = 10;
486		while (retry) {
487			u8 Tmp;
488
489			msleep(50);
490			status = i2c_read_eeprom(adapter, 0x50, Addr, &Tmp, 1);
491			if (status)
492				break;
493			if (Tmp != data[i])
494				pr_err(DEVICE_NAME
495				       "eeprom write error\n");
496			retry -= 1;
497		}
498		if (status) {
499			pr_err(DEVICE_NAME
500			       ": Timeout polling eeprom\n");
501			break;
502		}
503	}
504	return status;
505}
506
507static int eeprom_read_ushort(struct i2c_adapter *adapter, u16 tag, u16 *data)
508{
509	int stat;
510	u8 buf[2];
511	u32 len = 0;
512
513	stat = ReadEEProm(adapter, tag, 2, buf, &len);
514	if (stat)
515		return stat;
516	if (len != 2)
517		return -EINVAL;
518
519	*data = (buf[0] << 8) | buf[1];
520	return 0;
521}
522
523static int eeprom_write_ushort(struct i2c_adapter *adapter, u16 tag, u16 data)
524{
525	int stat;
526	u8 buf[2];
527
528	buf[0] = data >> 8;
529	buf[1] = data & 0xff;
530	stat = WriteEEProm(adapter, tag, 2, buf);
531	if (stat)
532		return stat;
533	return 0;
534}
535
536static s16 osc_deviation(void *priv, s16 deviation, int flag)
537{
538	struct ngene_channel *chan = priv;
539	struct i2c_adapter *adap = &chan->i2c_adapter;
540	u16 data = 0;
541
542	if (flag) {
543		data = (u16) deviation;
544		pr_info(DEVICE_NAME ": write deviation %d\n",
545		       deviation);
546		eeprom_write_ushort(adap, 0x1000 + chan->number, data);
547	} else {
548		if (eeprom_read_ushort(adap, 0x1000 + chan->number, &data))
549			data = 0;
550		pr_info(DEVICE_NAME ": read deviation %d\n",
551		       (s16) data);
552	}
553
554	return (s16) data;
555}
556
557/****************************************************************************/
558/* Switch control (I2C gates, etc.) *****************************************/
559/****************************************************************************/
560
561
562static struct stv090x_config fe_cineS2 = {
563	.device         = STV0900,
564	.demod_mode     = STV090x_DUAL,
565	.clk_mode       = STV090x_CLK_EXT,
566
567	.xtal           = 27000000,
568	.address        = 0x68,
569
570	.ts1_mode       = STV090x_TSMODE_SERIAL_PUNCTURED,
571	.ts2_mode       = STV090x_TSMODE_SERIAL_PUNCTURED,
572
573	.repeater_level = STV090x_RPTLEVEL_16,
574
575	.adc1_range	= STV090x_ADC_1Vpp,
576	.adc2_range	= STV090x_ADC_1Vpp,
577
578	.diseqc_envelope_mode = true,
579
580	.tuner_i2c_lock = cineS2_tuner_i2c_lock,
581};
582
583static struct stv090x_config fe_cineS2_2 = {
584	.device         = STV0900,
585	.demod_mode     = STV090x_DUAL,
586	.clk_mode       = STV090x_CLK_EXT,
587
588	.xtal           = 27000000,
589	.address        = 0x69,
590
591	.ts1_mode       = STV090x_TSMODE_SERIAL_PUNCTURED,
592	.ts2_mode       = STV090x_TSMODE_SERIAL_PUNCTURED,
593
594	.repeater_level = STV090x_RPTLEVEL_16,
595
596	.adc1_range	= STV090x_ADC_1Vpp,
597	.adc2_range	= STV090x_ADC_1Vpp,
598
599	.diseqc_envelope_mode = true,
600
601	.tuner_i2c_lock = cineS2_tuner_i2c_lock,
602};
603
604static struct stv6110x_config tuner_cineS2_0 = {
605	.addr	= 0x60,
606	.refclk	= 27000000,
607	.clk_div = 1,
608};
609
610static struct stv6110x_config tuner_cineS2_1 = {
611	.addr	= 0x63,
612	.refclk	= 27000000,
613	.clk_div = 1,
614};
615
616static struct ngene_info ngene_info_cineS2 = {
617	.type		= NGENE_SIDEWINDER,
618	.name		= "Linux4Media cineS2 DVB-S2 Twin Tuner",
619	.io_type	= {NGENE_IO_TSIN, NGENE_IO_TSIN},
620	.demod_attach	= {demod_attach_stv0900, demod_attach_stv0900},
621	.tuner_attach	= {tuner_attach_stv6110, tuner_attach_stv6110},
622	.fe_config	= {&fe_cineS2, &fe_cineS2},
623	.tuner_config	= {&tuner_cineS2_0, &tuner_cineS2_1},
624	.lnb		= {0x0b, 0x08},
625	.tsf		= {3, 3},
626	.fw_version	= 18,
627	.msi_supported	= true,
628};
629
630static struct ngene_info ngene_info_satixS2 = {
631	.type		= NGENE_SIDEWINDER,
632	.name		= "Mystique SaTiX-S2 Dual",
633	.io_type	= {NGENE_IO_TSIN, NGENE_IO_TSIN},
634	.demod_attach	= {demod_attach_stv0900, demod_attach_stv0900},
635	.tuner_attach	= {tuner_attach_stv6110, tuner_attach_stv6110},
636	.fe_config	= {&fe_cineS2, &fe_cineS2},
637	.tuner_config	= {&tuner_cineS2_0, &tuner_cineS2_1},
638	.lnb		= {0x0b, 0x08},
639	.tsf		= {3, 3},
640	.fw_version	= 18,
641	.msi_supported	= true,
642};
643
644static struct ngene_info ngene_info_satixS2v2 = {
645	.type		= NGENE_SIDEWINDER,
646	.name		= "Mystique SaTiX-S2 Dual (v2)",
647	.io_type	= {NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN,
648			   NGENE_IO_TSOUT},
649	.demod_attach	= {demod_attach_stv0900, demod_attach_stv0900, cineS2_probe, cineS2_probe},
650	.tuner_attach	= {tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_probe, tuner_attach_probe},
651	.fe_config	= {&fe_cineS2, &fe_cineS2, &fe_cineS2_2, &fe_cineS2_2},
652	.tuner_config	= {&tuner_cineS2_0, &tuner_cineS2_1, &tuner_cineS2_0, &tuner_cineS2_1},
653	.lnb		= {0x0a, 0x08, 0x0b, 0x09},
654	.tsf		= {3, 3},
655	.fw_version	= 18,
656	.msi_supported	= true,
657};
658
659static struct ngene_info ngene_info_cineS2v5 = {
660	.type		= NGENE_SIDEWINDER,
661	.name		= "Linux4Media cineS2 DVB-S2 Twin Tuner (v5)",
662	.io_type	= {NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN,
663			   NGENE_IO_TSOUT},
664	.demod_attach	= {demod_attach_stv0900, demod_attach_stv0900, cineS2_probe, cineS2_probe},
665	.tuner_attach	= {tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_probe, tuner_attach_probe},
666	.fe_config	= {&fe_cineS2, &fe_cineS2, &fe_cineS2_2, &fe_cineS2_2},
667	.tuner_config	= {&tuner_cineS2_0, &tuner_cineS2_1, &tuner_cineS2_0, &tuner_cineS2_1},
668	.lnb		= {0x0a, 0x08, 0x0b, 0x09},
669	.tsf		= {3, 3},
670	.fw_version	= 18,
671	.msi_supported	= true,
672};
673
674
675static struct ngene_info ngene_info_duoFlex = {
676	.type           = NGENE_SIDEWINDER,
677	.name           = "Digital Devices DuoFlex PCIe or miniPCIe",
678	.io_type        = {NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN,
679			   NGENE_IO_TSOUT},
680	.demod_attach   = {cineS2_probe, cineS2_probe, cineS2_probe, cineS2_probe},
681	.tuner_attach   = {tuner_attach_probe, tuner_attach_probe, tuner_attach_probe, tuner_attach_probe},
682	.fe_config      = {&fe_cineS2, &fe_cineS2, &fe_cineS2_2, &fe_cineS2_2},
683	.tuner_config   = {&tuner_cineS2_0, &tuner_cineS2_1, &tuner_cineS2_0, &tuner_cineS2_1},
684	.lnb            = {0x0a, 0x08, 0x0b, 0x09},
685	.tsf            = {3, 3},
686	.fw_version     = 18,
687	.msi_supported	= true,
688};
689
690static struct ngene_info ngene_info_m780 = {
691	.type           = NGENE_APP,
692	.name           = "Aver M780 ATSC/QAM-B",
693
694	/* Channel 0 is analog, which is currently unsupported */
695	.io_type        = { NGENE_IO_NONE, NGENE_IO_TSIN },
696	.demod_attach   = { NULL, demod_attach_lg330x },
697
698	/* Ensure these are NULL else the frame will call them (as funcs) */
699	.tuner_attach   = { NULL, NULL, NULL, NULL },
700	.fe_config      = { NULL, &aver_m780 },
701	.avf            = { 0 },
702
703	/* A custom electrical interface config for the demod to bridge */
704	.tsf		= { 4, 4 },
705	.fw_version	= 15,
706};
707
708static struct drxd_config fe_terratec_dvbt_0 = {
709	.index          = 0,
710	.demod_address  = 0x70,
711	.demod_revision = 0xa2,
712	.demoda_address = 0x00,
713	.pll_address    = 0x60,
714	.pll_type       = DVB_PLL_THOMSON_DTT7520X,
715	.clock          = 20000,
716	.osc_deviation  = osc_deviation,
717};
718
719static struct drxd_config fe_terratec_dvbt_1 = {
720	.index          = 1,
721	.demod_address  = 0x71,
722	.demod_revision = 0xa2,
723	.demoda_address = 0x00,
724	.pll_address    = 0x60,
725	.pll_type       = DVB_PLL_THOMSON_DTT7520X,
726	.clock          = 20000,
727	.osc_deviation  = osc_deviation,
728};
729
730static struct ngene_info ngene_info_terratec = {
731	.type           = NGENE_TERRATEC,
732	.name           = "Terratec Integra/Cinergy2400i Dual DVB-T",
733	.io_type        = {NGENE_IO_TSIN, NGENE_IO_TSIN},
734	.demod_attach   = {demod_attach_drxd, demod_attach_drxd},
735	.tuner_attach	= {tuner_attach_dtt7520x, tuner_attach_dtt7520x},
736	.fe_config      = {&fe_terratec_dvbt_0, &fe_terratec_dvbt_1},
737	.i2c_access     = 1,
738};
739
740/****************************************************************************/
741
742
743
744/****************************************************************************/
745/* PCI Subsystem ID *********************************************************/
746/****************************************************************************/
747
748#define NGENE_ID(_subvend, _subdev, _driverdata) { \
749	.vendor = NGENE_VID, .device = NGENE_PID, \
750	.subvendor = _subvend, .subdevice = _subdev, \
751	.driver_data = (unsigned long) &_driverdata }
752
753/****************************************************************************/
754
755static const struct pci_device_id ngene_id_tbl[] = {
756	NGENE_ID(0x18c3, 0xabc3, ngene_info_cineS2),
757	NGENE_ID(0x18c3, 0xabc4, ngene_info_cineS2),
758	NGENE_ID(0x18c3, 0xdb01, ngene_info_satixS2),
759	NGENE_ID(0x18c3, 0xdb02, ngene_info_satixS2v2),
760	NGENE_ID(0x18c3, 0xdd00, ngene_info_cineS2v5),
761	NGENE_ID(0x18c3, 0xdd10, ngene_info_duoFlex),
762	NGENE_ID(0x18c3, 0xdd20, ngene_info_duoFlex),
763	NGENE_ID(0x1461, 0x062e, ngene_info_m780),
764	NGENE_ID(0x153b, 0x1167, ngene_info_terratec),
765	{0}
766};
767MODULE_DEVICE_TABLE(pci, ngene_id_tbl);
768
769/****************************************************************************/
770/* Init/Exit ****************************************************************/
771/****************************************************************************/
772
773static pci_ers_result_t ngene_error_detected(struct pci_dev *dev,
774					     enum pci_channel_state state)
775{
776	printk(KERN_ERR DEVICE_NAME ": PCI error\n");
777	if (state == pci_channel_io_perm_failure)
778		return PCI_ERS_RESULT_DISCONNECT;
779	if (state == pci_channel_io_frozen)
780		return PCI_ERS_RESULT_NEED_RESET;
781	return PCI_ERS_RESULT_CAN_RECOVER;
782}
783
784static pci_ers_result_t ngene_link_reset(struct pci_dev *dev)
785{
786	printk(KERN_INFO DEVICE_NAME ": link reset\n");
787	return 0;
788}
789
790static pci_ers_result_t ngene_slot_reset(struct pci_dev *dev)
791{
792	printk(KERN_INFO DEVICE_NAME ": slot reset\n");
793	return 0;
794}
795
796static void ngene_resume(struct pci_dev *dev)
797{
798	printk(KERN_INFO DEVICE_NAME ": resume\n");
799}
800
801static const struct pci_error_handlers ngene_errors = {
802	.error_detected = ngene_error_detected,
803	.link_reset = ngene_link_reset,
804	.slot_reset = ngene_slot_reset,
805	.resume = ngene_resume,
806};
807
808static struct pci_driver ngene_pci_driver = {
809	.name        = "ngene",
810	.id_table    = ngene_id_tbl,
811	.probe       = ngene_probe,
812	.remove      = ngene_remove,
813	.err_handler = &ngene_errors,
814	.shutdown    = ngene_shutdown,
815};
816
817static __init int module_init_ngene(void)
818{
819	printk(KERN_INFO
820	       "nGene PCIE bridge driver, Copyright (C) 2005-2007 Micronas\n");
821	return pci_register_driver(&ngene_pci_driver);
822}
823
824static __exit void module_exit_ngene(void)
825{
826	pci_unregister_driver(&ngene_pci_driver);
827}
828
829module_init(module_init_ngene);
830module_exit(module_exit_ngene);
831
832MODULE_DESCRIPTION("nGene");
833MODULE_AUTHOR("Micronas, Ralph Metzler, Manfred Voelkel");
834MODULE_LICENSE("GPL");
835