• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/media/dvb/ttpci/
1/*
2 * budget-ci.c: driver for the SAA7146 based Budget DVB cards
3 *
4 * Compiled from various sources by Michael Hunold <michael@mihu.de>
5 *
6 *     msp430 IR support contributed by Jack Thomasson <jkt@Helius.COM>
7 *     partially based on the Siemens DVB driver by Ralph+Marcus Metzler
8 *
9 * CI interface support (c) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
27 *
28 *
29 * the project's page is at http://www.linuxtv.org/dvb/
30 */
31
32#include <linux/module.h>
33#include <linux/errno.h>
34#include <linux/slab.h>
35#include <linux/interrupt.h>
36#include <linux/input.h>
37#include <linux/spinlock.h>
38#include <media/ir-core.h>
39
40#include "budget.h"
41
42#include "dvb_ca_en50221.h"
43#include "stv0299.h"
44#include "stv0297.h"
45#include "tda1004x.h"
46#include "stb0899_drv.h"
47#include "stb0899_reg.h"
48#include "stb0899_cfg.h"
49#include "stb6100.h"
50#include "stb6100_cfg.h"
51#include "lnbp21.h"
52#include "bsbe1.h"
53#include "bsru6.h"
54#include "tda1002x.h"
55#include "tda827x.h"
56
57#define MODULE_NAME "budget_ci"
58
59/*
60 * Regarding DEBIADDR_IR:
61 * Some CI modules hang if random addresses are read.
62 * Using address 0x4000 for the IR read means that we
63 * use the same address as for CI version, which should
64 * be a safe default.
65 */
66#define DEBIADDR_IR		0x4000
67#define DEBIADDR_CICONTROL	0x0000
68#define DEBIADDR_CIVERSION	0x4000
69#define DEBIADDR_IO		0x1000
70#define DEBIADDR_ATTR		0x3000
71
72#define CICONTROL_RESET		0x01
73#define CICONTROL_ENABLETS	0x02
74#define CICONTROL_CAMDETECT	0x08
75
76#define DEBICICTL		0x00420000
77#define DEBICICAM		0x02420000
78
79#define SLOTSTATUS_NONE		1
80#define SLOTSTATUS_PRESENT	2
81#define SLOTSTATUS_RESET	4
82#define SLOTSTATUS_READY	8
83#define SLOTSTATUS_OCCUPIED	(SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)
84
85/* RC5 device wildcard */
86#define IR_DEVICE_ANY		255
87
88static int rc5_device = -1;
89module_param(rc5_device, int, 0644);
90MODULE_PARM_DESC(rc5_device, "only IR commands to given RC5 device (device = 0 - 31, any device = 255, default: autodetect)");
91
92static int ir_debug;
93module_param(ir_debug, int, 0644);
94MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding");
95
96DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
97
98struct budget_ci_ir {
99	struct input_dev *dev;
100	struct tasklet_struct msp430_irq_tasklet;
101	char name[72]; /* 40 + 32 for (struct saa7146_dev).name */
102	char phys[32];
103	int rc5_device;
104	u32 ir_key;
105	bool have_command;
106};
107
108struct budget_ci {
109	struct budget budget;
110	struct tasklet_struct ciintf_irq_tasklet;
111	int slot_status;
112	int ci_irq;
113	struct dvb_ca_en50221 ca;
114	struct budget_ci_ir ir;
115	u8 tuner_pll_address; /* used for philips_tdm1316l configs */
116};
117
118static void msp430_ir_interrupt(unsigned long data)
119{
120	struct budget_ci *budget_ci = (struct budget_ci *) data;
121	struct input_dev *dev = budget_ci->ir.dev;
122	u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;
123
124	/*
125	 * The msp430 chip can generate two different bytes, command and device
126	 *
127	 * type1: X1CCCCCC, C = command bits (0 - 63)
128	 * type2: X0TDDDDD, D = device bits (0 - 31), T = RC5 toggle bit
129	 *
130	 * Each signal from the remote control can generate one or more command
131	 * bytes and one or more device bytes. For the repeated bytes, the
132	 * highest bit (X) is set. The first command byte is always generated
133	 * before the first device byte. Other than that, no specific order
134	 * seems to apply. To make life interesting, bytes can also be lost.
135	 *
136	 * Only when we have a command and device byte, a keypress is
137	 * generated.
138	 */
139
140	if (ir_debug)
141		printk("budget_ci: received byte 0x%02x\n", command);
142
143	/* Remove repeat bit, we use every command */
144	command = command & 0x7f;
145
146	/* Is this a RC5 command byte? */
147	if (command & 0x40) {
148		budget_ci->ir.have_command = true;
149		budget_ci->ir.ir_key = command & 0x3f;
150		return;
151	}
152
153	/* It's a RC5 device byte */
154	if (!budget_ci->ir.have_command)
155		return;
156	budget_ci->ir.have_command = false;
157
158	if (budget_ci->ir.rc5_device != IR_DEVICE_ANY &&
159	    budget_ci->ir.rc5_device != (command & 0x1f))
160		return;
161
162	ir_keydown(dev, budget_ci->ir.ir_key, (command & 0x20) ? 1 : 0);
163}
164
165static int msp430_ir_init(struct budget_ci *budget_ci)
166{
167	struct saa7146_dev *saa = budget_ci->budget.dev;
168	struct input_dev *input_dev = budget_ci->ir.dev;
169	int error;
170	char *ir_codes = NULL;
171
172
173	budget_ci->ir.dev = input_dev = input_allocate_device();
174	if (!input_dev) {
175		printk(KERN_ERR "budget_ci: IR interface initialisation failed\n");
176		return -ENOMEM;
177	}
178
179	snprintf(budget_ci->ir.name, sizeof(budget_ci->ir.name),
180		 "Budget-CI dvb ir receiver %s", saa->name);
181	snprintf(budget_ci->ir.phys, sizeof(budget_ci->ir.phys),
182		 "pci-%s/ir0", pci_name(saa->pci));
183
184	input_dev->name = budget_ci->ir.name;
185
186	input_dev->phys = budget_ci->ir.phys;
187	input_dev->id.bustype = BUS_PCI;
188	input_dev->id.version = 1;
189	if (saa->pci->subsystem_vendor) {
190		input_dev->id.vendor = saa->pci->subsystem_vendor;
191		input_dev->id.product = saa->pci->subsystem_device;
192	} else {
193		input_dev->id.vendor = saa->pci->vendor;
194		input_dev->id.product = saa->pci->device;
195	}
196	input_dev->dev.parent = &saa->pci->dev;
197
198	if (rc5_device < 0)
199		budget_ci->ir.rc5_device = IR_DEVICE_ANY;
200	else
201		budget_ci->ir.rc5_device = rc5_device;
202
203	/* Select keymap and address */
204	switch (budget_ci->budget.dev->pci->subsystem_device) {
205	case 0x100c:
206	case 0x100f:
207	case 0x1011:
208	case 0x1012:
209		/* The hauppauge keymap is a superset of these remotes */
210		ir_codes = RC_MAP_HAUPPAUGE_NEW;
211
212		if (rc5_device < 0)
213			budget_ci->ir.rc5_device = 0x1f;
214		break;
215	case 0x1010:
216	case 0x1017:
217	case 0x1019:
218	case 0x101a:
219		/* for the Technotrend 1500 bundled remote */
220		ir_codes = RC_MAP_TT_1500;
221		break;
222	default:
223		/* unknown remote */
224		ir_codes = RC_MAP_BUDGET_CI_OLD;
225		break;
226	}
227
228	error = ir_input_register(input_dev, ir_codes, NULL, MODULE_NAME);
229	if (error) {
230		printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error);
231		return error;
232	}
233
234	/* note: these must be after input_register_device */
235	input_dev->rep[REP_DELAY] = 400;
236	input_dev->rep[REP_PERIOD] = 250;
237
238	tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt,
239		     (unsigned long) budget_ci);
240
241	SAA7146_IER_ENABLE(saa, MASK_06);
242	saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI);
243
244	return 0;
245}
246
247static void msp430_ir_deinit(struct budget_ci *budget_ci)
248{
249	struct saa7146_dev *saa = budget_ci->budget.dev;
250	struct input_dev *dev = budget_ci->ir.dev;
251
252	SAA7146_IER_DISABLE(saa, MASK_06);
253	saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
254	tasklet_kill(&budget_ci->ir.msp430_irq_tasklet);
255
256	ir_input_unregister(dev);
257}
258
259static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
260{
261	struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
262
263	if (slot != 0)
264		return -EINVAL;
265
266	return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM,
267				     DEBIADDR_ATTR | (address & 0xfff), 1, 1, 0);
268}
269
270static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
271{
272	struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
273
274	if (slot != 0)
275		return -EINVAL;
276
277	return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM,
278				      DEBIADDR_ATTR | (address & 0xfff), 1, value, 1, 0);
279}
280
281static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
282{
283	struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
284
285	if (slot != 0)
286		return -EINVAL;
287
288	return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM,
289				     DEBIADDR_IO | (address & 3), 1, 1, 0);
290}
291
292static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
293{
294	struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
295
296	if (slot != 0)
297		return -EINVAL;
298
299	return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM,
300				      DEBIADDR_IO | (address & 3), 1, value, 1, 0);
301}
302
303static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
304{
305	struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
306	struct saa7146_dev *saa = budget_ci->budget.dev;
307
308	if (slot != 0)
309		return -EINVAL;
310
311	if (budget_ci->ci_irq) {
312		// trigger on RISING edge during reset so we know when READY is re-asserted
313		saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
314	}
315	budget_ci->slot_status = SLOTSTATUS_RESET;
316	ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
317	msleep(1);
318	ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
319			       CICONTROL_RESET, 1, 0);
320
321	saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
322	ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
323	return 0;
324}
325
326static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
327{
328	struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
329	struct saa7146_dev *saa = budget_ci->budget.dev;
330
331	if (slot != 0)
332		return -EINVAL;
333
334	saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
335	ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
336	return 0;
337}
338
339static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
340{
341	struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
342	struct saa7146_dev *saa = budget_ci->budget.dev;
343	int tmp;
344
345	if (slot != 0)
346		return -EINVAL;
347
348	saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO);
349
350	tmp = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
351	ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
352			       tmp | CICONTROL_ENABLETS, 1, 0);
353
354	ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
355	return 0;
356}
357
358static void ciintf_interrupt(unsigned long data)
359{
360	struct budget_ci *budget_ci = (struct budget_ci *) data;
361	struct saa7146_dev *saa = budget_ci->budget.dev;
362	unsigned int flags;
363
364	// ensure we don't get spurious IRQs during initialisation
365	if (!budget_ci->budget.ci_present)
366		return;
367
368	// read the CAM status
369	flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
370	if (flags & CICONTROL_CAMDETECT) {
371
372		// GPIO should be set to trigger on falling edge if a CAM is present
373		saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
374
375		if (budget_ci->slot_status & SLOTSTATUS_NONE) {
376			// CAM insertion IRQ
377			budget_ci->slot_status = SLOTSTATUS_PRESENT;
378			dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0,
379						     DVB_CA_EN50221_CAMCHANGE_INSERTED);
380
381		} else if (budget_ci->slot_status & SLOTSTATUS_RESET) {
382			// CAM ready (reset completed)
383			budget_ci->slot_status = SLOTSTATUS_READY;
384			dvb_ca_en50221_camready_irq(&budget_ci->ca, 0);
385
386		} else if (budget_ci->slot_status & SLOTSTATUS_READY) {
387			// FR/DA IRQ
388			dvb_ca_en50221_frda_irq(&budget_ci->ca, 0);
389		}
390	} else {
391
392		// trigger on rising edge if a CAM is not present - when a CAM is inserted, we
393		// only want to get the IRQ when it sets READY. If we trigger on the falling edge,
394		// the CAM might not actually be ready yet.
395		saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
396
397		// generate a CAM removal IRQ if we haven't already
398		if (budget_ci->slot_status & SLOTSTATUS_OCCUPIED) {
399			// CAM removal IRQ
400			budget_ci->slot_status = SLOTSTATUS_NONE;
401			dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0,
402						     DVB_CA_EN50221_CAMCHANGE_REMOVED);
403		}
404	}
405}
406
407static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
408{
409	struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
410	unsigned int flags;
411
412	// ensure we don't get spurious IRQs during initialisation
413	if (!budget_ci->budget.ci_present)
414		return -EINVAL;
415
416	// read the CAM status
417	flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
418	if (flags & CICONTROL_CAMDETECT) {
419		// mark it as present if it wasn't before
420		if (budget_ci->slot_status & SLOTSTATUS_NONE) {
421			budget_ci->slot_status = SLOTSTATUS_PRESENT;
422		}
423
424		// during a RESET, we check if we can read from IO memory to see when CAM is ready
425		if (budget_ci->slot_status & SLOTSTATUS_RESET) {
426			if (ciintf_read_attribute_mem(ca, slot, 0) == 0x1d) {
427				budget_ci->slot_status = SLOTSTATUS_READY;
428			}
429		}
430	} else {
431		budget_ci->slot_status = SLOTSTATUS_NONE;
432	}
433
434	if (budget_ci->slot_status != SLOTSTATUS_NONE) {
435		if (budget_ci->slot_status & SLOTSTATUS_READY) {
436			return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
437		}
438		return DVB_CA_EN50221_POLL_CAM_PRESENT;
439	}
440
441	return 0;
442}
443
444static int ciintf_init(struct budget_ci *budget_ci)
445{
446	struct saa7146_dev *saa = budget_ci->budget.dev;
447	int flags;
448	int result;
449	int ci_version;
450	int ca_flags;
451
452	memset(&budget_ci->ca, 0, sizeof(struct dvb_ca_en50221));
453
454	// enable DEBI pins
455	saa7146_write(saa, MC1, MASK_27 | MASK_11);
456
457	// test if it is there
458	ci_version = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CIVERSION, 1, 1, 0);
459	if ((ci_version & 0xa0) != 0xa0) {
460		result = -ENODEV;
461		goto error;
462	}
463
464	// determine whether a CAM is present or not
465	flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
466	budget_ci->slot_status = SLOTSTATUS_NONE;
467	if (flags & CICONTROL_CAMDETECT)
468		budget_ci->slot_status = SLOTSTATUS_PRESENT;
469
470	// version 0xa2 of the CI firmware doesn't generate interrupts
471	if (ci_version == 0xa2) {
472		ca_flags = 0;
473		budget_ci->ci_irq = 0;
474	} else {
475		ca_flags = DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE |
476				DVB_CA_EN50221_FLAG_IRQ_FR |
477				DVB_CA_EN50221_FLAG_IRQ_DA;
478		budget_ci->ci_irq = 1;
479	}
480
481	// register CI interface
482	budget_ci->ca.owner = THIS_MODULE;
483	budget_ci->ca.read_attribute_mem = ciintf_read_attribute_mem;
484	budget_ci->ca.write_attribute_mem = ciintf_write_attribute_mem;
485	budget_ci->ca.read_cam_control = ciintf_read_cam_control;
486	budget_ci->ca.write_cam_control = ciintf_write_cam_control;
487	budget_ci->ca.slot_reset = ciintf_slot_reset;
488	budget_ci->ca.slot_shutdown = ciintf_slot_shutdown;
489	budget_ci->ca.slot_ts_enable = ciintf_slot_ts_enable;
490	budget_ci->ca.poll_slot_status = ciintf_poll_slot_status;
491	budget_ci->ca.data = budget_ci;
492	if ((result = dvb_ca_en50221_init(&budget_ci->budget.dvb_adapter,
493					  &budget_ci->ca,
494					  ca_flags, 1)) != 0) {
495		printk("budget_ci: CI interface detected, but initialisation failed.\n");
496		goto error;
497	}
498
499	// Setup CI slot IRQ
500	if (budget_ci->ci_irq) {
501		tasklet_init(&budget_ci->ciintf_irq_tasklet, ciintf_interrupt, (unsigned long) budget_ci);
502		if (budget_ci->slot_status != SLOTSTATUS_NONE) {
503			saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
504		} else {
505			saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
506		}
507		SAA7146_IER_ENABLE(saa, MASK_03);
508	}
509
510	// enable interface
511	ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
512			       CICONTROL_RESET, 1, 0);
513
514	// success!
515	printk("budget_ci: CI interface initialised\n");
516	budget_ci->budget.ci_present = 1;
517
518	// forge a fake CI IRQ so the CAM state is setup correctly
519	if (budget_ci->ci_irq) {
520		flags = DVB_CA_EN50221_CAMCHANGE_REMOVED;
521		if (budget_ci->slot_status != SLOTSTATUS_NONE)
522			flags = DVB_CA_EN50221_CAMCHANGE_INSERTED;
523		dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, flags);
524	}
525
526	return 0;
527
528error:
529	saa7146_write(saa, MC1, MASK_27);
530	return result;
531}
532
533static void ciintf_deinit(struct budget_ci *budget_ci)
534{
535	struct saa7146_dev *saa = budget_ci->budget.dev;
536
537	// disable CI interrupts
538	if (budget_ci->ci_irq) {
539		SAA7146_IER_DISABLE(saa, MASK_03);
540		saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
541		tasklet_kill(&budget_ci->ciintf_irq_tasklet);
542	}
543
544	// reset interface
545	ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
546	msleep(1);
547	ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
548			       CICONTROL_RESET, 1, 0);
549
550	// disable TS data stream to CI interface
551	saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT);
552
553	// release the CA device
554	dvb_ca_en50221_release(&budget_ci->ca);
555
556	// disable DEBI pins
557	saa7146_write(saa, MC1, MASK_27);
558}
559
560static void budget_ci_irq(struct saa7146_dev *dev, u32 * isr)
561{
562	struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv;
563
564	dprintk(8, "dev: %p, budget_ci: %p\n", dev, budget_ci);
565
566	if (*isr & MASK_06)
567		tasklet_schedule(&budget_ci->ir.msp430_irq_tasklet);
568
569	if (*isr & MASK_10)
570		ttpci_budget_irq10_handler(dev, isr);
571
572	if ((*isr & MASK_03) && (budget_ci->budget.ci_present) && (budget_ci->ci_irq))
573		tasklet_schedule(&budget_ci->ciintf_irq_tasklet);
574}
575
576static u8 philips_su1278_tt_inittab[] = {
577	0x01, 0x0f,
578	0x02, 0x30,
579	0x03, 0x00,
580	0x04, 0x5b,
581	0x05, 0x85,
582	0x06, 0x02,
583	0x07, 0x00,
584	0x08, 0x02,
585	0x09, 0x00,
586	0x0C, 0x01,
587	0x0D, 0x81,
588	0x0E, 0x44,
589	0x0f, 0x14,
590	0x10, 0x3c,
591	0x11, 0x84,
592	0x12, 0xda,
593	0x13, 0x97,
594	0x14, 0x95,
595	0x15, 0xc9,
596	0x16, 0x19,
597	0x17, 0x8c,
598	0x18, 0x59,
599	0x19, 0xf8,
600	0x1a, 0xfe,
601	0x1c, 0x7f,
602	0x1d, 0x00,
603	0x1e, 0x00,
604	0x1f, 0x50,
605	0x20, 0x00,
606	0x21, 0x00,
607	0x22, 0x00,
608	0x23, 0x00,
609	0x28, 0x00,
610	0x29, 0x28,
611	0x2a, 0x14,
612	0x2b, 0x0f,
613	0x2c, 0x09,
614	0x2d, 0x09,
615	0x31, 0x1f,
616	0x32, 0x19,
617	0x33, 0xfc,
618	0x34, 0x93,
619	0xff, 0xff
620};
621
622static int philips_su1278_tt_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
623{
624	stv0299_writereg(fe, 0x0e, 0x44);
625	if (srate >= 10000000) {
626		stv0299_writereg(fe, 0x13, 0x97);
627		stv0299_writereg(fe, 0x14, 0x95);
628		stv0299_writereg(fe, 0x15, 0xc9);
629		stv0299_writereg(fe, 0x17, 0x8c);
630		stv0299_writereg(fe, 0x1a, 0xfe);
631		stv0299_writereg(fe, 0x1c, 0x7f);
632		stv0299_writereg(fe, 0x2d, 0x09);
633	} else {
634		stv0299_writereg(fe, 0x13, 0x99);
635		stv0299_writereg(fe, 0x14, 0x8d);
636		stv0299_writereg(fe, 0x15, 0xce);
637		stv0299_writereg(fe, 0x17, 0x43);
638		stv0299_writereg(fe, 0x1a, 0x1d);
639		stv0299_writereg(fe, 0x1c, 0x12);
640		stv0299_writereg(fe, 0x2d, 0x05);
641	}
642	stv0299_writereg(fe, 0x0e, 0x23);
643	stv0299_writereg(fe, 0x0f, 0x94);
644	stv0299_writereg(fe, 0x10, 0x39);
645	stv0299_writereg(fe, 0x15, 0xc9);
646
647	stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
648	stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
649	stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
650
651	return 0;
652}
653
654static int philips_su1278_tt_tuner_set_params(struct dvb_frontend *fe,
655					   struct dvb_frontend_parameters *params)
656{
657	struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
658	u32 div;
659	u8 buf[4];
660	struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
661
662	if ((params->frequency < 950000) || (params->frequency > 2150000))
663		return -EINVAL;
664
665	div = (params->frequency + (500 - 1)) / 500;	// round correctly
666	buf[0] = (div >> 8) & 0x7f;
667	buf[1] = div & 0xff;
668	buf[2] = 0x80 | ((div & 0x18000) >> 10) | 2;
669	buf[3] = 0x20;
670
671	if (params->u.qpsk.symbol_rate < 4000000)
672		buf[3] |= 1;
673
674	if (params->frequency < 1250000)
675		buf[3] |= 0;
676	else if (params->frequency < 1550000)
677		buf[3] |= 0x40;
678	else if (params->frequency < 2050000)
679		buf[3] |= 0x80;
680	else if (params->frequency < 2150000)
681		buf[3] |= 0xC0;
682
683	if (fe->ops.i2c_gate_ctrl)
684		fe->ops.i2c_gate_ctrl(fe, 1);
685	if (i2c_transfer(&budget_ci->budget.i2c_adap, &msg, 1) != 1)
686		return -EIO;
687	return 0;
688}
689
690static struct stv0299_config philips_su1278_tt_config = {
691
692	.demod_address = 0x68,
693	.inittab = philips_su1278_tt_inittab,
694	.mclk = 64000000UL,
695	.invert = 0,
696	.skip_reinit = 1,
697	.lock_output = STV0299_LOCKOUTPUT_1,
698	.volt13_op0_op1 = STV0299_VOLT13_OP1,
699	.min_delay_ms = 50,
700	.set_symbol_rate = philips_su1278_tt_set_symbol_rate,
701};
702
703
704
705static int philips_tdm1316l_tuner_init(struct dvb_frontend *fe)
706{
707	struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
708	static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab };
709	static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 };
710	struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = td1316_init,.len =
711			sizeof(td1316_init) };
712
713	// setup PLL configuration
714	if (fe->ops.i2c_gate_ctrl)
715		fe->ops.i2c_gate_ctrl(fe, 1);
716	if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
717		return -EIO;
718	msleep(1);
719
720	// disable the mc44BC374c (do not check for errors)
721	tuner_msg.addr = 0x65;
722	tuner_msg.buf = disable_mc44BC374c;
723	tuner_msg.len = sizeof(disable_mc44BC374c);
724	if (fe->ops.i2c_gate_ctrl)
725		fe->ops.i2c_gate_ctrl(fe, 1);
726	if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) {
727		if (fe->ops.i2c_gate_ctrl)
728			fe->ops.i2c_gate_ctrl(fe, 1);
729		i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1);
730	}
731
732	return 0;
733}
734
735static int philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
736{
737	struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
738	u8 tuner_buf[4];
739	struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = tuner_buf,.len = sizeof(tuner_buf) };
740	int tuner_frequency = 0;
741	u8 band, cp, filter;
742
743	// determine charge pump
744	tuner_frequency = params->frequency + 36130000;
745	if (tuner_frequency < 87000000)
746		return -EINVAL;
747	else if (tuner_frequency < 130000000)
748		cp = 3;
749	else if (tuner_frequency < 160000000)
750		cp = 5;
751	else if (tuner_frequency < 200000000)
752		cp = 6;
753	else if (tuner_frequency < 290000000)
754		cp = 3;
755	else if (tuner_frequency < 420000000)
756		cp = 5;
757	else if (tuner_frequency < 480000000)
758		cp = 6;
759	else if (tuner_frequency < 620000000)
760		cp = 3;
761	else if (tuner_frequency < 830000000)
762		cp = 5;
763	else if (tuner_frequency < 895000000)
764		cp = 7;
765	else
766		return -EINVAL;
767
768	// determine band
769	if (params->frequency < 49000000)
770		return -EINVAL;
771	else if (params->frequency < 159000000)
772		band = 1;
773	else if (params->frequency < 444000000)
774		band = 2;
775	else if (params->frequency < 861000000)
776		band = 4;
777	else
778		return -EINVAL;
779
780	// setup PLL filter and TDA9889
781	switch (params->u.ofdm.bandwidth) {
782	case BANDWIDTH_6_MHZ:
783		tda1004x_writereg(fe, 0x0C, 0x14);
784		filter = 0;
785		break;
786
787	case BANDWIDTH_7_MHZ:
788		tda1004x_writereg(fe, 0x0C, 0x80);
789		filter = 0;
790		break;
791
792	case BANDWIDTH_8_MHZ:
793		tda1004x_writereg(fe, 0x0C, 0x14);
794		filter = 1;
795		break;
796
797	default:
798		return -EINVAL;
799	}
800
801	// calculate divisor
802	// ((36130000+((1000000/6)/2)) + Finput)/(1000000/6)
803	tuner_frequency = (((params->frequency / 1000) * 6) + 217280) / 1000;
804
805	// setup tuner buffer
806	tuner_buf[0] = tuner_frequency >> 8;
807	tuner_buf[1] = tuner_frequency & 0xff;
808	tuner_buf[2] = 0xca;
809	tuner_buf[3] = (cp << 5) | (filter << 3) | band;
810
811	if (fe->ops.i2c_gate_ctrl)
812		fe->ops.i2c_gate_ctrl(fe, 1);
813	if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
814		return -EIO;
815
816	msleep(1);
817	return 0;
818}
819
820static int philips_tdm1316l_request_firmware(struct dvb_frontend *fe,
821					     const struct firmware **fw, char *name)
822{
823	struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
824
825	return request_firmware(fw, name, &budget_ci->budget.dev->pci->dev);
826}
827
828static struct tda1004x_config philips_tdm1316l_config = {
829
830	.demod_address = 0x8,
831	.invert = 0,
832	.invert_oclk = 0,
833	.xtal_freq = TDA10046_XTAL_4M,
834	.agc_config = TDA10046_AGC_DEFAULT,
835	.if_freq = TDA10046_FREQ_3617,
836	.request_firmware = philips_tdm1316l_request_firmware,
837};
838
839static struct tda1004x_config philips_tdm1316l_config_invert = {
840
841	.demod_address = 0x8,
842	.invert = 1,
843	.invert_oclk = 0,
844	.xtal_freq = TDA10046_XTAL_4M,
845	.agc_config = TDA10046_AGC_DEFAULT,
846	.if_freq = TDA10046_FREQ_3617,
847	.request_firmware = philips_tdm1316l_request_firmware,
848};
849
850static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
851{
852	struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
853	u8 tuner_buf[5];
854	struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,
855				    .flags = 0,
856				    .buf = tuner_buf,
857				    .len = sizeof(tuner_buf) };
858	int tuner_frequency = 0;
859	u8 band, cp, filter;
860
861	// determine charge pump
862	tuner_frequency = params->frequency + 36125000;
863	if (tuner_frequency < 87000000)
864		return -EINVAL;
865	else if (tuner_frequency < 130000000) {
866		cp = 3;
867		band = 1;
868	} else if (tuner_frequency < 160000000) {
869		cp = 5;
870		band = 1;
871	} else if (tuner_frequency < 200000000) {
872		cp = 6;
873		band = 1;
874	} else if (tuner_frequency < 290000000) {
875		cp = 3;
876		band = 2;
877	} else if (tuner_frequency < 420000000) {
878		cp = 5;
879		band = 2;
880	} else if (tuner_frequency < 480000000) {
881		cp = 6;
882		band = 2;
883	} else if (tuner_frequency < 620000000) {
884		cp = 3;
885		band = 4;
886	} else if (tuner_frequency < 830000000) {
887		cp = 5;
888		band = 4;
889	} else if (tuner_frequency < 895000000) {
890		cp = 7;
891		band = 4;
892	} else
893		return -EINVAL;
894
895	// assume PLL filter should always be 8MHz for the moment.
896	filter = 1;
897
898	// calculate divisor
899	tuner_frequency = (params->frequency + 36125000 + (62500/2)) / 62500;
900
901	// setup tuner buffer
902	tuner_buf[0] = tuner_frequency >> 8;
903	tuner_buf[1] = tuner_frequency & 0xff;
904	tuner_buf[2] = 0xc8;
905	tuner_buf[3] = (cp << 5) | (filter << 3) | band;
906	tuner_buf[4] = 0x80;
907
908	if (fe->ops.i2c_gate_ctrl)
909		fe->ops.i2c_gate_ctrl(fe, 1);
910	if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
911		return -EIO;
912
913	msleep(50);
914
915	if (fe->ops.i2c_gate_ctrl)
916		fe->ops.i2c_gate_ctrl(fe, 1);
917	if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
918		return -EIO;
919
920	msleep(1);
921
922	return 0;
923}
924
925static u8 dvbc_philips_tdm1316l_inittab[] = {
926	0x80, 0x01,
927	0x80, 0x00,
928	0x81, 0x01,
929	0x81, 0x00,
930	0x00, 0x09,
931	0x01, 0x69,
932	0x03, 0x00,
933	0x04, 0x00,
934	0x07, 0x00,
935	0x08, 0x00,
936	0x20, 0x00,
937	0x21, 0x40,
938	0x22, 0x00,
939	0x23, 0x00,
940	0x24, 0x40,
941	0x25, 0x88,
942	0x30, 0xff,
943	0x31, 0x00,
944	0x32, 0xff,
945	0x33, 0x00,
946	0x34, 0x50,
947	0x35, 0x7f,
948	0x36, 0x00,
949	0x37, 0x20,
950	0x38, 0x00,
951	0x40, 0x1c,
952	0x41, 0xff,
953	0x42, 0x29,
954	0x43, 0x20,
955	0x44, 0xff,
956	0x45, 0x00,
957	0x46, 0x00,
958	0x49, 0x04,
959	0x4a, 0x00,
960	0x4b, 0x7b,
961	0x52, 0x30,
962	0x55, 0xae,
963	0x56, 0x47,
964	0x57, 0xe1,
965	0x58, 0x3a,
966	0x5a, 0x1e,
967	0x5b, 0x34,
968	0x60, 0x00,
969	0x63, 0x00,
970	0x64, 0x00,
971	0x65, 0x00,
972	0x66, 0x00,
973	0x67, 0x00,
974	0x68, 0x00,
975	0x69, 0x00,
976	0x6a, 0x02,
977	0x6b, 0x00,
978	0x70, 0xff,
979	0x71, 0x00,
980	0x72, 0x00,
981	0x73, 0x00,
982	0x74, 0x0c,
983	0x80, 0x00,
984	0x81, 0x00,
985	0x82, 0x00,
986	0x83, 0x00,
987	0x84, 0x04,
988	0x85, 0x80,
989	0x86, 0x24,
990	0x87, 0x78,
991	0x88, 0x10,
992	0x89, 0x00,
993	0x90, 0x01,
994	0x91, 0x01,
995	0xa0, 0x04,
996	0xa1, 0x00,
997	0xa2, 0x00,
998	0xb0, 0x91,
999	0xb1, 0x0b,
1000	0xc0, 0x53,
1001	0xc1, 0x70,
1002	0xc2, 0x12,
1003	0xd0, 0x00,
1004	0xd1, 0x00,
1005	0xd2, 0x00,
1006	0xd3, 0x00,
1007	0xd4, 0x00,
1008	0xd5, 0x00,
1009	0xde, 0x00,
1010	0xdf, 0x00,
1011	0x61, 0x38,
1012	0x62, 0x0a,
1013	0x53, 0x13,
1014	0x59, 0x08,
1015	0xff, 0xff,
1016};
1017
1018static struct stv0297_config dvbc_philips_tdm1316l_config = {
1019	.demod_address = 0x1c,
1020	.inittab = dvbc_philips_tdm1316l_inittab,
1021	.invert = 0,
1022	.stop_during_read = 1,
1023};
1024
1025static struct tda10023_config tda10023_config = {
1026	.demod_address = 0xc,
1027	.invert = 0,
1028	.xtal = 16000000,
1029	.pll_m = 11,
1030	.pll_p = 3,
1031	.pll_n = 1,
1032	.deltaf = 0xa511,
1033};
1034
1035static struct tda827x_config tda827x_config = {
1036	.config = 0,
1037};
1038
1039/* TT S2-3200 DVB-S (STB0899) Inittab */
1040static const struct stb0899_s1_reg tt3200_stb0899_s1_init_1[] = {
1041
1042	{ STB0899_DEV_ID		, 0x81 },
1043	{ STB0899_DISCNTRL1		, 0x32 },
1044	{ STB0899_DISCNTRL2     	, 0x80 },
1045	{ STB0899_DISRX_ST0     	, 0x04 },
1046	{ STB0899_DISRX_ST1     	, 0x00 },
1047	{ STB0899_DISPARITY     	, 0x00 },
1048	{ STB0899_DISFIFO       	, 0x00 },
1049	{ STB0899_DISSTATUS		, 0x20 },
1050	{ STB0899_DISF22        	, 0x8c },
1051	{ STB0899_DISF22RX      	, 0x9a },
1052	{ STB0899_SYSREG		, 0x0b },
1053	{ STB0899_ACRPRESC      	, 0x11 },
1054	{ STB0899_ACRDIV1       	, 0x0a },
1055	{ STB0899_ACRDIV2       	, 0x05 },
1056	{ STB0899_DACR1         	, 0x00 },
1057	{ STB0899_DACR2         	, 0x00 },
1058	{ STB0899_OUTCFG        	, 0x00 },
1059	{ STB0899_MODECFG       	, 0x00 },
1060	{ STB0899_IRQSTATUS_3		, 0x30 },
1061	{ STB0899_IRQSTATUS_2		, 0x00 },
1062	{ STB0899_IRQSTATUS_1		, 0x00 },
1063	{ STB0899_IRQSTATUS_0		, 0x00 },
1064	{ STB0899_IRQMSK_3      	, 0xf3 },
1065	{ STB0899_IRQMSK_2      	, 0xfc },
1066	{ STB0899_IRQMSK_1      	, 0xff },
1067	{ STB0899_IRQMSK_0		, 0xff },
1068	{ STB0899_IRQCFG		, 0x00 },
1069	{ STB0899_I2CCFG        	, 0x88 },
1070	{ STB0899_I2CRPT        	, 0x48 }, /* 12k Pullup, Repeater=16, Stop=disabled */
1071	{ STB0899_IOPVALUE5		, 0x00 },
1072	{ STB0899_IOPVALUE4		, 0x20 },
1073	{ STB0899_IOPVALUE3		, 0xc9 },
1074	{ STB0899_IOPVALUE2		, 0x90 },
1075	{ STB0899_IOPVALUE1		, 0x40 },
1076	{ STB0899_IOPVALUE0		, 0x00 },
1077	{ STB0899_GPIO00CFG     	, 0x82 },
1078	{ STB0899_GPIO01CFG     	, 0x82 },
1079	{ STB0899_GPIO02CFG     	, 0x82 },
1080	{ STB0899_GPIO03CFG     	, 0x82 },
1081	{ STB0899_GPIO04CFG     	, 0x82 },
1082	{ STB0899_GPIO05CFG     	, 0x82 },
1083	{ STB0899_GPIO06CFG     	, 0x82 },
1084	{ STB0899_GPIO07CFG     	, 0x82 },
1085	{ STB0899_GPIO08CFG     	, 0x82 },
1086	{ STB0899_GPIO09CFG     	, 0x82 },
1087	{ STB0899_GPIO10CFG     	, 0x82 },
1088	{ STB0899_GPIO11CFG     	, 0x82 },
1089	{ STB0899_GPIO12CFG     	, 0x82 },
1090	{ STB0899_GPIO13CFG     	, 0x82 },
1091	{ STB0899_GPIO14CFG     	, 0x82 },
1092	{ STB0899_GPIO15CFG     	, 0x82 },
1093	{ STB0899_GPIO16CFG     	, 0x82 },
1094	{ STB0899_GPIO17CFG     	, 0x82 },
1095	{ STB0899_GPIO18CFG     	, 0x82 },
1096	{ STB0899_GPIO19CFG     	, 0x82 },
1097	{ STB0899_GPIO20CFG     	, 0x82 },
1098	{ STB0899_SDATCFG       	, 0xb8 },
1099	{ STB0899_SCLTCFG       	, 0xba },
1100	{ STB0899_AGCRFCFG      	, 0x1c }, /* 0x11 */
1101	{ STB0899_GPIO22        	, 0x82 }, /* AGCBB2CFG */
1102	{ STB0899_GPIO21        	, 0x91 }, /* AGCBB1CFG */
1103	{ STB0899_DIRCLKCFG     	, 0x82 },
1104	{ STB0899_CLKOUT27CFG   	, 0x7e },
1105	{ STB0899_STDBYCFG      	, 0x82 },
1106	{ STB0899_CS0CFG        	, 0x82 },
1107	{ STB0899_CS1CFG        	, 0x82 },
1108	{ STB0899_DISEQCOCFG    	, 0x20 },
1109	{ STB0899_GPIO32CFG		, 0x82 },
1110	{ STB0899_GPIO33CFG		, 0x82 },
1111	{ STB0899_GPIO34CFG		, 0x82 },
1112	{ STB0899_GPIO35CFG		, 0x82 },
1113	{ STB0899_GPIO36CFG		, 0x82 },
1114	{ STB0899_GPIO37CFG		, 0x82 },
1115	{ STB0899_GPIO38CFG		, 0x82 },
1116	{ STB0899_GPIO39CFG		, 0x82 },
1117	{ STB0899_NCOARSE       	, 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
1118	{ STB0899_SYNTCTRL      	, 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
1119	{ STB0899_FILTCTRL      	, 0x00 },
1120	{ STB0899_SYSCTRL       	, 0x00 },
1121	{ STB0899_STOPCLK1      	, 0x20 },
1122	{ STB0899_STOPCLK2      	, 0x00 },
1123	{ STB0899_INTBUFSTATUS		, 0x00 },
1124	{ STB0899_INTBUFCTRL    	, 0x0a },
1125	{ 0xffff			, 0xff },
1126};
1127
1128static const struct stb0899_s1_reg tt3200_stb0899_s1_init_3[] = {
1129	{ STB0899_DEMOD         	, 0x00 },
1130	{ STB0899_RCOMPC        	, 0xc9 },
1131	{ STB0899_AGC1CN        	, 0x41 },
1132	{ STB0899_AGC1REF       	, 0x10 },
1133	{ STB0899_RTC			, 0x7a },
1134	{ STB0899_TMGCFG        	, 0x4e },
1135	{ STB0899_AGC2REF       	, 0x34 },
1136	{ STB0899_TLSR          	, 0x84 },
1137	{ STB0899_CFD           	, 0xc7 },
1138	{ STB0899_ACLC			, 0x87 },
1139	{ STB0899_BCLC          	, 0x94 },
1140	{ STB0899_EQON          	, 0x41 },
1141	{ STB0899_LDT           	, 0xdd },
1142	{ STB0899_LDT2          	, 0xc9 },
1143	{ STB0899_EQUALREF      	, 0xb4 },
1144	{ STB0899_TMGRAMP       	, 0x10 },
1145	{ STB0899_TMGTHD        	, 0x30 },
1146	{ STB0899_IDCCOMP		, 0xfb },
1147	{ STB0899_QDCCOMP		, 0x03 },
1148	{ STB0899_POWERI		, 0x3b },
1149	{ STB0899_POWERQ		, 0x3d },
1150	{ STB0899_RCOMP			, 0x81 },
1151	{ STB0899_AGCIQIN		, 0x80 },
1152	{ STB0899_AGC2I1		, 0x04 },
1153	{ STB0899_AGC2I2		, 0xf5 },
1154	{ STB0899_TLIR			, 0x25 },
1155	{ STB0899_RTF			, 0x80 },
1156	{ STB0899_DSTATUS		, 0x00 },
1157	{ STB0899_LDI			, 0xca },
1158	{ STB0899_CFRM			, 0xf1 },
1159	{ STB0899_CFRL			, 0xf3 },
1160	{ STB0899_NIRM			, 0x2a },
1161	{ STB0899_NIRL			, 0x05 },
1162	{ STB0899_ISYMB			, 0x17 },
1163	{ STB0899_QSYMB			, 0xfa },
1164	{ STB0899_SFRH          	, 0x2f },
1165	{ STB0899_SFRM          	, 0x68 },
1166	{ STB0899_SFRL          	, 0x40 },
1167	{ STB0899_SFRUPH        	, 0x2f },
1168	{ STB0899_SFRUPM        	, 0x68 },
1169	{ STB0899_SFRUPL        	, 0x40 },
1170	{ STB0899_EQUAI1		, 0xfd },
1171	{ STB0899_EQUAQ1		, 0x04 },
1172	{ STB0899_EQUAI2		, 0x0f },
1173	{ STB0899_EQUAQ2		, 0xff },
1174	{ STB0899_EQUAI3		, 0xdf },
1175	{ STB0899_EQUAQ3		, 0xfa },
1176	{ STB0899_EQUAI4		, 0x37 },
1177	{ STB0899_EQUAQ4		, 0x0d },
1178	{ STB0899_EQUAI5		, 0xbd },
1179	{ STB0899_EQUAQ5		, 0xf7 },
1180	{ STB0899_DSTATUS2		, 0x00 },
1181	{ STB0899_VSTATUS       	, 0x00 },
1182	{ STB0899_VERROR		, 0xff },
1183	{ STB0899_IQSWAP		, 0x2a },
1184	{ STB0899_ECNT1M		, 0x00 },
1185	{ STB0899_ECNT1L		, 0x00 },
1186	{ STB0899_ECNT2M		, 0x00 },
1187	{ STB0899_ECNT2L		, 0x00 },
1188	{ STB0899_ECNT3M		, 0x00 },
1189	{ STB0899_ECNT3L		, 0x00 },
1190	{ STB0899_FECAUTO1      	, 0x06 },
1191	{ STB0899_FECM			, 0x01 },
1192	{ STB0899_VTH12         	, 0xf0 },
1193	{ STB0899_VTH23         	, 0xa0 },
1194	{ STB0899_VTH34			, 0x78 },
1195	{ STB0899_VTH56         	, 0x4e },
1196	{ STB0899_VTH67         	, 0x48 },
1197	{ STB0899_VTH78         	, 0x38 },
1198	{ STB0899_PRVIT         	, 0xff },
1199	{ STB0899_VITSYNC       	, 0x19 },
1200	{ STB0899_RSULC         	, 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
1201	{ STB0899_TSULC         	, 0x42 },
1202	{ STB0899_RSLLC         	, 0x40 },
1203	{ STB0899_TSLPL			, 0x12 },
1204	{ STB0899_TSCFGH        	, 0x0c },
1205	{ STB0899_TSCFGM        	, 0x00 },
1206	{ STB0899_TSCFGL        	, 0x0c },
1207	{ STB0899_TSOUT			, 0x4d }, /* 0x0d for CAM */
1208	{ STB0899_RSSYNCDEL     	, 0x00 },
1209	{ STB0899_TSINHDELH     	, 0x02 },
1210	{ STB0899_TSINHDELM		, 0x00 },
1211	{ STB0899_TSINHDELL		, 0x00 },
1212	{ STB0899_TSLLSTKM		, 0x00 },
1213	{ STB0899_TSLLSTKL		, 0x00 },
1214	{ STB0899_TSULSTKM		, 0x00 },
1215	{ STB0899_TSULSTKL		, 0xab },
1216	{ STB0899_PCKLENUL		, 0x00 },
1217	{ STB0899_PCKLENLL		, 0xcc },
1218	{ STB0899_RSPCKLEN		, 0xcc },
1219	{ STB0899_TSSTATUS		, 0x80 },
1220	{ STB0899_ERRCTRL1      	, 0xb6 },
1221	{ STB0899_ERRCTRL2      	, 0x96 },
1222	{ STB0899_ERRCTRL3      	, 0x89 },
1223	{ STB0899_DMONMSK1		, 0x27 },
1224	{ STB0899_DMONMSK0		, 0x03 },
1225	{ STB0899_DEMAPVIT      	, 0x5c },
1226	{ STB0899_PLPARM		, 0x1f },
1227	{ STB0899_PDELCTRL      	, 0x48 },
1228	{ STB0899_PDELCTRL2     	, 0x00 },
1229	{ STB0899_BBHCTRL1      	, 0x00 },
1230	{ STB0899_BBHCTRL2      	, 0x00 },
1231	{ STB0899_HYSTTHRESH    	, 0x77 },
1232	{ STB0899_MATCSTM		, 0x00 },
1233	{ STB0899_MATCSTL		, 0x00 },
1234	{ STB0899_UPLCSTM		, 0x00 },
1235	{ STB0899_UPLCSTL		, 0x00 },
1236	{ STB0899_DFLCSTM		, 0x00 },
1237	{ STB0899_DFLCSTL		, 0x00 },
1238	{ STB0899_SYNCCST		, 0x00 },
1239	{ STB0899_SYNCDCSTM		, 0x00 },
1240	{ STB0899_SYNCDCSTL		, 0x00 },
1241	{ STB0899_ISI_ENTRY		, 0x00 },
1242	{ STB0899_ISI_BIT_EN		, 0x00 },
1243	{ STB0899_MATSTRM		, 0x00 },
1244	{ STB0899_MATSTRL		, 0x00 },
1245	{ STB0899_UPLSTRM		, 0x00 },
1246	{ STB0899_UPLSTRL		, 0x00 },
1247	{ STB0899_DFLSTRM		, 0x00 },
1248	{ STB0899_DFLSTRL		, 0x00 },
1249	{ STB0899_SYNCSTR		, 0x00 },
1250	{ STB0899_SYNCDSTRM		, 0x00 },
1251	{ STB0899_SYNCDSTRL		, 0x00 },
1252	{ STB0899_CFGPDELSTATUS1	, 0x10 },
1253	{ STB0899_CFGPDELSTATUS2	, 0x00 },
1254	{ STB0899_BBFERRORM		, 0x00 },
1255	{ STB0899_BBFERRORL		, 0x00 },
1256	{ STB0899_UPKTERRORM		, 0x00 },
1257	{ STB0899_UPKTERRORL		, 0x00 },
1258	{ 0xffff			, 0xff },
1259};
1260
1261static struct stb0899_config tt3200_config = {
1262	.init_dev		= tt3200_stb0899_s1_init_1,
1263	.init_s2_demod		= stb0899_s2_init_2,
1264	.init_s1_demod		= tt3200_stb0899_s1_init_3,
1265	.init_s2_fec		= stb0899_s2_init_4,
1266	.init_tst		= stb0899_s1_init_5,
1267
1268	.postproc		= NULL,
1269
1270	.demod_address 		= 0x68,
1271
1272	.xtal_freq		= 27000000,
1273	.inversion		= IQ_SWAP_ON, /* 1 */
1274
1275	.lo_clk			= 76500000,
1276	.hi_clk			= 99000000,
1277
1278	.esno_ave		= STB0899_DVBS2_ESNO_AVE,
1279	.esno_quant		= STB0899_DVBS2_ESNO_QUANT,
1280	.avframes_coarse	= STB0899_DVBS2_AVFRAMES_COARSE,
1281	.avframes_fine		= STB0899_DVBS2_AVFRAMES_FINE,
1282	.miss_threshold		= STB0899_DVBS2_MISS_THRESHOLD,
1283	.uwp_threshold_acq	= STB0899_DVBS2_UWP_THRESHOLD_ACQ,
1284	.uwp_threshold_track	= STB0899_DVBS2_UWP_THRESHOLD_TRACK,
1285	.uwp_threshold_sof	= STB0899_DVBS2_UWP_THRESHOLD_SOF,
1286	.sof_search_timeout	= STB0899_DVBS2_SOF_SEARCH_TIMEOUT,
1287
1288	.btr_nco_bits		= STB0899_DVBS2_BTR_NCO_BITS,
1289	.btr_gain_shift_offset	= STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET,
1290	.crl_nco_bits		= STB0899_DVBS2_CRL_NCO_BITS,
1291	.ldpc_max_iter		= STB0899_DVBS2_LDPC_MAX_ITER,
1292
1293	.tuner_get_frequency	= stb6100_get_frequency,
1294	.tuner_set_frequency	= stb6100_set_frequency,
1295	.tuner_set_bandwidth	= stb6100_set_bandwidth,
1296	.tuner_get_bandwidth	= stb6100_get_bandwidth,
1297	.tuner_set_rfsiggain	= NULL
1298};
1299
1300static struct stb6100_config tt3200_stb6100_config = {
1301	.tuner_address	= 0x60,
1302	.refclock	= 27000000,
1303};
1304
1305static void frontend_init(struct budget_ci *budget_ci)
1306{
1307	switch (budget_ci->budget.dev->pci->subsystem_device) {
1308	case 0x100c:		// Hauppauge/TT Nova-CI budget (stv0299/ALPS BSRU6(tsa5059))
1309		budget_ci->budget.dvb_frontend =
1310			dvb_attach(stv0299_attach, &alps_bsru6_config, &budget_ci->budget.i2c_adap);
1311		if (budget_ci->budget.dvb_frontend) {
1312			budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
1313			budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap;
1314			break;
1315		}
1316		break;
1317
1318	case 0x100f:		// Hauppauge/TT Nova-CI budget (stv0299b/Philips su1278(tsa5059))
1319		budget_ci->budget.dvb_frontend =
1320			dvb_attach(stv0299_attach, &philips_su1278_tt_config, &budget_ci->budget.i2c_adap);
1321		if (budget_ci->budget.dvb_frontend) {
1322			budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_su1278_tt_tuner_set_params;
1323			break;
1324		}
1325		break;
1326
1327	case 0x1010:		// TT DVB-C CI budget (stv0297/Philips tdm1316l(tda6651tt))
1328		budget_ci->tuner_pll_address = 0x61;
1329		budget_ci->budget.dvb_frontend =
1330			dvb_attach(stv0297_attach, &dvbc_philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
1331		if (budget_ci->budget.dvb_frontend) {
1332			budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params;
1333			break;
1334		}
1335		break;
1336
1337	case 0x1011:		// Hauppauge/TT Nova-T budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889)
1338		budget_ci->tuner_pll_address = 0x63;
1339		budget_ci->budget.dvb_frontend =
1340			dvb_attach(tda10045_attach, &philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
1341		if (budget_ci->budget.dvb_frontend) {
1342			budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
1343			budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
1344			break;
1345		}
1346		break;
1347
1348	case 0x1012:		// TT DVB-T CI budget (tda10046/Philips tdm1316l(tda6651tt))
1349		budget_ci->tuner_pll_address = 0x60;
1350		budget_ci->budget.dvb_frontend =
1351			dvb_attach(tda10046_attach, &philips_tdm1316l_config_invert, &budget_ci->budget.i2c_adap);
1352		if (budget_ci->budget.dvb_frontend) {
1353			budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
1354			budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
1355			break;
1356		}
1357		break;
1358
1359	case 0x1017:		// TT S-1500 PCI
1360		budget_ci->budget.dvb_frontend = dvb_attach(stv0299_attach, &alps_bsbe1_config, &budget_ci->budget.i2c_adap);
1361		if (budget_ci->budget.dvb_frontend) {
1362			budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params;
1363			budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap;
1364
1365			budget_ci->budget.dvb_frontend->ops.dishnetwork_send_legacy_command = NULL;
1366			if (dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0) == NULL) {
1367				printk("%s: No LNBP21 found!\n", __func__);
1368				dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1369				budget_ci->budget.dvb_frontend = NULL;
1370			}
1371		}
1372		break;
1373
1374	case 0x101a: /* TT Budget-C-1501 (philips tda10023/philips tda8274A) */
1375		budget_ci->budget.dvb_frontend = dvb_attach(tda10023_attach, &tda10023_config, &budget_ci->budget.i2c_adap, 0x48);
1376		if (budget_ci->budget.dvb_frontend) {
1377			if (dvb_attach(tda827x_attach, budget_ci->budget.dvb_frontend, 0x61, &budget_ci->budget.i2c_adap, &tda827x_config) == NULL) {
1378				printk(KERN_ERR "%s: No tda827x found!\n", __func__);
1379				dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1380				budget_ci->budget.dvb_frontend = NULL;
1381			}
1382		}
1383		break;
1384
1385	case 0x1019:		// TT S2-3200 PCI
1386		/*
1387		 * NOTE! on some STB0899 versions, the internal PLL takes a longer time
1388		 * to settle, aka LOCK. On the older revisions of the chip, we don't see
1389		 * this, as a result on the newer chips the entire clock tree, will not
1390		 * be stable after a freshly POWER 'ed up situation.
1391		 * In this case, we should RESET the STB0899 (Active LOW) and wait for
1392		 * PLL stabilization.
1393		 *
1394		 * On the TT S2 3200 and clones, the STB0899 demodulator's RESETB is
1395		 * connected to the SAA7146 GPIO, GPIO2, Pin 142
1396		 */
1397		/* Reset Demodulator */
1398		saa7146_setgpio(budget_ci->budget.dev, 2, SAA7146_GPIO_OUTLO);
1399		/* Wait for everything to die */
1400		msleep(50);
1401		/* Pull it up out of Reset state */
1402		saa7146_setgpio(budget_ci->budget.dev, 2, SAA7146_GPIO_OUTHI);
1403		/* Wait for PLL to stabilize */
1404		msleep(250);
1405		/*
1406		 * PLL state should be stable now. Ideally, we should check
1407		 * for PLL LOCK status. But well, never mind!
1408		 */
1409		budget_ci->budget.dvb_frontend = dvb_attach(stb0899_attach, &tt3200_config, &budget_ci->budget.i2c_adap);
1410		if (budget_ci->budget.dvb_frontend) {
1411			if (dvb_attach(stb6100_attach, budget_ci->budget.dvb_frontend, &tt3200_stb6100_config, &budget_ci->budget.i2c_adap)) {
1412				if (!dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, 0, 0)) {
1413					printk("%s: No LNBP21 found!\n", __func__);
1414					dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1415					budget_ci->budget.dvb_frontend = NULL;
1416				}
1417			} else {
1418					dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1419					budget_ci->budget.dvb_frontend = NULL;
1420			}
1421		}
1422		break;
1423
1424	}
1425
1426	if (budget_ci->budget.dvb_frontend == NULL) {
1427		printk("budget-ci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
1428		       budget_ci->budget.dev->pci->vendor,
1429		       budget_ci->budget.dev->pci->device,
1430		       budget_ci->budget.dev->pci->subsystem_vendor,
1431		       budget_ci->budget.dev->pci->subsystem_device);
1432	} else {
1433		if (dvb_register_frontend
1434		    (&budget_ci->budget.dvb_adapter, budget_ci->budget.dvb_frontend)) {
1435			printk("budget-ci: Frontend registration failed!\n");
1436			dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1437			budget_ci->budget.dvb_frontend = NULL;
1438		}
1439	}
1440}
1441
1442static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
1443{
1444	struct budget_ci *budget_ci;
1445	int err;
1446
1447	budget_ci = kzalloc(sizeof(struct budget_ci), GFP_KERNEL);
1448	if (!budget_ci) {
1449		err = -ENOMEM;
1450		goto out1;
1451	}
1452
1453	dprintk(2, "budget_ci: %p\n", budget_ci);
1454
1455	dev->ext_priv = budget_ci;
1456
1457	err = ttpci_budget_init(&budget_ci->budget, dev, info, THIS_MODULE,
1458				adapter_nr);
1459	if (err)
1460		goto out2;
1461
1462	err = msp430_ir_init(budget_ci);
1463	if (err)
1464		goto out3;
1465
1466	ciintf_init(budget_ci);
1467
1468	budget_ci->budget.dvb_adapter.priv = budget_ci;
1469	frontend_init(budget_ci);
1470
1471	ttpci_budget_init_hooks(&budget_ci->budget);
1472
1473	return 0;
1474
1475out3:
1476	ttpci_budget_deinit(&budget_ci->budget);
1477out2:
1478	kfree(budget_ci);
1479out1:
1480	return err;
1481}
1482
1483static int budget_ci_detach(struct saa7146_dev *dev)
1484{
1485	struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv;
1486	struct saa7146_dev *saa = budget_ci->budget.dev;
1487	int err;
1488
1489	if (budget_ci->budget.ci_present)
1490		ciintf_deinit(budget_ci);
1491	msp430_ir_deinit(budget_ci);
1492	if (budget_ci->budget.dvb_frontend) {
1493		dvb_unregister_frontend(budget_ci->budget.dvb_frontend);
1494		dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1495	}
1496	err = ttpci_budget_deinit(&budget_ci->budget);
1497
1498	// disable frontend and CI interface
1499	saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
1500
1501	kfree(budget_ci);
1502
1503	return err;
1504}
1505
1506static struct saa7146_extension budget_extension;
1507
1508MAKE_BUDGET_INFO(ttbs2, "TT-Budget/S-1500 PCI", BUDGET_TT);
1509MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC);
1510MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T	 PCI", BUDGET_TT);
1511MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT);
1512MAKE_BUDGET_INFO(ttbcci, "TT-Budget-C-CI PCI", BUDGET_TT);
1513MAKE_BUDGET_INFO(ttc1501, "TT-Budget C-1501 PCI", BUDGET_TT);
1514MAKE_BUDGET_INFO(tt3200, "TT-Budget S2-3200 PCI", BUDGET_TT);
1515
1516static struct pci_device_id pci_tbl[] = {
1517	MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c),
1518	MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100f),
1519	MAKE_EXTENSION_PCI(ttbcci, 0x13c2, 0x1010),
1520	MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011),
1521	MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012),
1522	MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017),
1523	MAKE_EXTENSION_PCI(ttc1501, 0x13c2, 0x101a),
1524	MAKE_EXTENSION_PCI(tt3200, 0x13c2, 0x1019),
1525	{
1526	 .vendor = 0,
1527	 }
1528};
1529
1530MODULE_DEVICE_TABLE(pci, pci_tbl);
1531
1532static struct saa7146_extension budget_extension = {
1533	.name = "budget_ci dvb",
1534	.flags = SAA7146_USE_I2C_IRQ,
1535
1536	.module = THIS_MODULE,
1537	.pci_tbl = &pci_tbl[0],
1538	.attach = budget_ci_attach,
1539	.detach = budget_ci_detach,
1540
1541	.irq_mask = MASK_03 | MASK_06 | MASK_10,
1542	.irq_func = budget_ci_irq,
1543};
1544
1545static int __init budget_ci_init(void)
1546{
1547	return saa7146_register_extension(&budget_extension);
1548}
1549
1550static void __exit budget_ci_exit(void)
1551{
1552	saa7146_unregister_extension(&budget_extension);
1553}
1554
1555module_init(budget_ci_init);
1556module_exit(budget_ci_exit);
1557
1558MODULE_LICENSE("GPL");
1559MODULE_AUTHOR("Michael Hunold, Jack Thomasson, Andrew de Quincey, others");
1560MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
1561		   "budget PCI DVB cards w/ CI-module produced by "
1562		   "Siemens, Technotrend, Hauppauge");
1563