brintos

brintos / linux-shallow public Read only

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