blob: 005c4596343d32f934bd445ae585afb8b73c36df [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
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
Linus Torvalds1da177e2005-04-16 15:20:36 -070032#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>
David Hardeman2520fff2006-12-02 21:16:05 -020038#include <media/ir-common.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070039
Trent Piepho68277092007-01-30 23:25:46 -030040#include "budget.h"
41
Linus Torvalds1da177e2005-04-16 15:20:36 -070042#include "dvb_ca_en50221.h"
43#include "stv0299.h"
Andrew de Quinceydc27a162005-09-09 13:03:07 -070044#include "stv0297.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070045#include "tda1004x.h"
Marko Schluessler9e0dc662008-10-23 18:16:40 -030046#include "stb0899_drv.h"
47#include "stb0899_reg.h"
48#include "stb6100.h"
Perceval Anichini8cc2e372006-02-28 09:52:44 -030049#include "lnbp21.h"
50#include "bsbe1.h"
Perceval Anichini265366e2006-03-16 11:22:47 -030051#include "bsru6.h"
Sigmund Augdal11417da2008-06-15 17:25:46 -030052#include "tda1002x.h"
53#include "tda827x.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070054
David Härdemanecba77f2006-10-27 20:56:51 -030055/*
56 * Regarding DEBIADDR_IR:
57 * Some CI modules hang if random addresses are read.
58 * Using address 0x4000 for the IR read means that we
59 * use the same address as for CI version, which should
60 * be a safe default.
61 */
62#define DEBIADDR_IR 0x4000
Linus Torvalds1da177e2005-04-16 15:20:36 -070063#define DEBIADDR_CICONTROL 0x0000
64#define DEBIADDR_CIVERSION 0x4000
65#define DEBIADDR_IO 0x1000
66#define DEBIADDR_ATTR 0x3000
67
68#define CICONTROL_RESET 0x01
69#define CICONTROL_ENABLETS 0x02
70#define CICONTROL_CAMDETECT 0x08
71
72#define DEBICICTL 0x00420000
73#define DEBICICAM 0x02420000
74
75#define SLOTSTATUS_NONE 1
76#define SLOTSTATUS_PRESENT 2
77#define SLOTSTATUS_RESET 4
78#define SLOTSTATUS_READY 8
79#define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)
80
David Härdeman145859c2007-04-27 12:31:22 -030081/*
82 * Milliseconds during which a key is regarded as pressed.
83 * If an identical command arrives within this time, the timer will start over.
David Hardeman2520fff2006-12-02 21:16:05 -020084 */
David Härdeman145859c2007-04-27 12:31:22 -030085#define IR_KEYPRESS_TIMEOUT 250
David Hardeman2520fff2006-12-02 21:16:05 -020086
David Hardeman64741b72006-12-02 21:16:05 -020087/* RC5 device wildcard */
88#define IR_DEVICE_ANY 255
89
David Hardeman64741b72006-12-02 21:16:05 -020090static int rc5_device = -1;
91module_param(rc5_device, int, 0644);
92MODULE_PARM_DESC(rc5_device, "only IR commands to given RC5 device (device = 0 - 31, any device = 255, default: autodetect)");
93
Douglas Schilling Landgrafff699e62008-04-22 14:41:48 -030094static int ir_debug;
David Hardemanb5471a22006-12-02 21:16:05 -020095module_param(ir_debug, int, 0644);
96MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding");
97
Janne Grunau26dc4d02008-09-21 20:50:11 -030098DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
99
David Hardemandd2f3982006-12-02 21:16:05 -0200100struct budget_ci_ir {
101 struct input_dev *dev;
102 struct tasklet_struct msp430_irq_tasklet;
David Härdeman145859c2007-04-27 12:31:22 -0300103 struct timer_list timer_keyup;
David Hardemandd2f3982006-12-02 21:16:05 -0200104 char name[72]; /* 40 + 32 for (struct saa7146_dev).name */
David Hardeman5cc8ae02006-12-02 21:16:05 -0200105 char phys[32];
David Hardeman2520fff2006-12-02 21:16:05 -0200106 struct ir_input_state state;
David Hardeman64741b72006-12-02 21:16:05 -0200107 int rc5_device;
David Härdeman145859c2007-04-27 12:31:22 -0300108 u32 last_raw;
109 u32 ir_key;
110 bool have_command;
David Hardemandd2f3982006-12-02 21:16:05 -0200111};
112
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113struct budget_ci {
114 struct budget budget;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115 struct tasklet_struct ciintf_irq_tasklet;
116 int slot_status;
Andrew de Quincey96b194c2006-04-05 14:09:45 -0300117 int ci_irq;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118 struct dvb_ca_en50221 ca;
David Hardemandd2f3982006-12-02 21:16:05 -0200119 struct budget_ci_ir ir;
Andrew de Quinceydd2bbb12005-07-07 17:57:54 -0700120 u8 tuner_pll_address; /* used for philips_tdm1316l configs */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121};
122
David Hardeman2520fff2006-12-02 21:16:05 -0200123static void msp430_ir_keyup(unsigned long data)
124{
125 struct budget_ci_ir *ir = (struct budget_ci_ir *) data;
126 ir_input_nokey(ir->dev, &ir->state);
127}
128
129static void msp430_ir_interrupt(unsigned long data)
130{
131 struct budget_ci *budget_ci = (struct budget_ci *) data;
132 struct input_dev *dev = budget_ci->ir.dev;
David Hardeman2520fff2006-12-02 21:16:05 -0200133 u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;
David Härdeman145859c2007-04-27 12:31:22 -0300134 u32 raw;
David Hardeman2520fff2006-12-02 21:16:05 -0200135
David Hardeman64741b72006-12-02 21:16:05 -0200136 /*
137 * The msp430 chip can generate two different bytes, command and device
138 *
139 * type1: X1CCCCCC, C = command bits (0 - 63)
140 * type2: X0TDDDDD, D = device bits (0 - 31), T = RC5 toggle bit
141 *
David Härdeman59327a42007-02-13 09:39:58 -0300142 * Each signal from the remote control can generate one or more command
143 * bytes and one or more device bytes. For the repeated bytes, the
144 * highest bit (X) is set. The first command byte is always generated
145 * before the first device byte. Other than that, no specific order
David Härdeman145859c2007-04-27 12:31:22 -0300146 * seems to apply. To make life interesting, bytes can also be lost.
David Härdeman59327a42007-02-13 09:39:58 -0300147 *
148 * Only when we have a command and device byte, a keypress is
149 * generated.
David Hardeman64741b72006-12-02 21:16:05 -0200150 */
151
David Härdeman59327a42007-02-13 09:39:58 -0300152 if (ir_debug)
153 printk("budget_ci: received byte 0x%02x\n", command);
154
David Härdeman145859c2007-04-27 12:31:22 -0300155 /* Remove repeat bit, we use every command */
156 command = command & 0x7f;
David Härdeman59327a42007-02-13 09:39:58 -0300157
David Hardeman64741b72006-12-02 21:16:05 -0200158 /* Is this a RC5 command byte? */
David Hardeman2520fff2006-12-02 21:16:05 -0200159 if (command & 0x40) {
David Härdeman145859c2007-04-27 12:31:22 -0300160 budget_ci->ir.have_command = true;
161 budget_ci->ir.ir_key = command & 0x3f;
David Hardeman64741b72006-12-02 21:16:05 -0200162 return;
David Hardeman2520fff2006-12-02 21:16:05 -0200163 }
David Hardeman64741b72006-12-02 21:16:05 -0200164
165 /* It's a RC5 device byte */
David Härdeman145859c2007-04-27 12:31:22 -0300166 if (!budget_ci->ir.have_command)
David Härdeman59327a42007-02-13 09:39:58 -0300167 return;
David Härdeman145859c2007-04-27 12:31:22 -0300168 budget_ci->ir.have_command = false;
David Hardeman64741b72006-12-02 21:16:05 -0200169
David Härdeman145859c2007-04-27 12:31:22 -0300170 if (budget_ci->ir.rc5_device != IR_DEVICE_ANY &&
171 budget_ci->ir.rc5_device != (command & 0x1f))
David Hardeman64741b72006-12-02 21:16:05 -0200172 return;
173
David Härdeman145859c2007-04-27 12:31:22 -0300174 /* Is this a repeated key sequence? (same device, command, toggle) */
175 raw = budget_ci->ir.ir_key | (command << 8);
176 if (budget_ci->ir.last_raw != raw || !timer_pending(&budget_ci->ir.timer_keyup)) {
David Hardeman59236d42006-12-02 21:16:06 -0200177 ir_input_nokey(dev, &budget_ci->ir.state);
David Härdeman145859c2007-04-27 12:31:22 -0300178 ir_input_keydown(dev, &budget_ci->ir.state,
179 budget_ci->ir.ir_key, raw);
180 budget_ci->ir.last_raw = raw;
David Hardeman59236d42006-12-02 21:16:06 -0200181 }
David Härdeman145859c2007-04-27 12:31:22 -0300182
183 mod_timer(&budget_ci->ir.timer_keyup, jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT));
David Hardeman2520fff2006-12-02 21:16:05 -0200184}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186static int msp430_ir_init(struct budget_ci *budget_ci)
187{
188 struct saa7146_dev *saa = budget_ci->budget.dev;
David Hardemandd2f3982006-12-02 21:16:05 -0200189 struct input_dev *input_dev = budget_ci->ir.dev;
David Hardeman8cc532e2006-12-02 21:16:05 -0200190 int error;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191
David Hardemandd2f3982006-12-02 21:16:05 -0200192 budget_ci->ir.dev = input_dev = input_allocate_device();
David Hardeman8cc532e2006-12-02 21:16:05 -0200193 if (!input_dev) {
David Hardemanee579bc2006-12-02 21:16:05 -0200194 printk(KERN_ERR "budget_ci: IR interface initialisation failed\n");
David Hardeman8cc532e2006-12-02 21:16:05 -0200195 error = -ENOMEM;
196 goto out1;
197 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198
David Hardemandd2f3982006-12-02 21:16:05 -0200199 snprintf(budget_ci->ir.name, sizeof(budget_ci->ir.name),
200 "Budget-CI dvb ir receiver %s", saa->name);
David Hardeman5cc8ae02006-12-02 21:16:05 -0200201 snprintf(budget_ci->ir.phys, sizeof(budget_ci->ir.phys),
202 "pci-%s/ir0", pci_name(saa->pci));
203
David Hardemandd2f3982006-12-02 21:16:05 -0200204 input_dev->name = budget_ci->ir.name;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205
David Hardeman5cc8ae02006-12-02 21:16:05 -0200206 input_dev->phys = budget_ci->ir.phys;
207 input_dev->id.bustype = BUS_PCI;
208 input_dev->id.version = 1;
209 if (saa->pci->subsystem_vendor) {
210 input_dev->id.vendor = saa->pci->subsystem_vendor;
211 input_dev->id.product = saa->pci->subsystem_device;
212 } else {
213 input_dev->id.vendor = saa->pci->vendor;
214 input_dev->id.product = saa->pci->device;
215 }
Dmitry Torokhov2c8a3a32007-07-16 09:28:15 -0300216 input_dev->dev.parent = &saa->pci->dev;
David Hardeman5cc8ae02006-12-02 21:16:05 -0200217
David Hardeman64741b72006-12-02 21:16:05 -0200218 /* Select keymap and address */
David Hardeman2520fff2006-12-02 21:16:05 -0200219 switch (budget_ci->budget.dev->pci->subsystem_device) {
220 case 0x100c:
221 case 0x100f:
David Hardeman2520fff2006-12-02 21:16:05 -0200222 case 0x1011:
223 case 0x1012:
David Hardeman2520fff2006-12-02 21:16:05 -0200224 /* The hauppauge keymap is a superset of these remotes */
225 ir_input_init(input_dev, &budget_ci->ir.state,
226 IR_TYPE_RC5, ir_codes_hauppauge_new);
David Hardeman64741b72006-12-02 21:16:05 -0200227
228 if (rc5_device < 0)
229 budget_ci->ir.rc5_device = 0x1f;
230 else
231 budget_ci->ir.rc5_device = rc5_device;
David Hardeman2520fff2006-12-02 21:16:05 -0200232 break;
Ville-Pekka Vainioae1942c2007-01-12 14:06:21 -0300233 case 0x1010:
Oliver Endrissf64899c2007-09-17 22:17:12 -0300234 case 0x1017:
Oliver Endrissbbfc4c22008-06-19 23:36:45 -0300235 case 0x101a:
Ville-Pekka Vainioae1942c2007-01-12 14:06:21 -0300236 /* for the Technotrend 1500 bundled remote */
237 ir_input_init(input_dev, &budget_ci->ir.state,
238 IR_TYPE_RC5, ir_codes_tt_1500);
239
240 if (rc5_device < 0)
241 budget_ci->ir.rc5_device = IR_DEVICE_ANY;
242 else
243 budget_ci->ir.rc5_device = rc5_device;
244 break;
David Hardeman2520fff2006-12-02 21:16:05 -0200245 default:
246 /* unknown remote */
247 ir_input_init(input_dev, &budget_ci->ir.state,
248 IR_TYPE_RC5, ir_codes_budget_ci_old);
David Hardeman64741b72006-12-02 21:16:05 -0200249
250 if (rc5_device < 0)
251 budget_ci->ir.rc5_device = IR_DEVICE_ANY;
252 else
253 budget_ci->ir.rc5_device = rc5_device;
David Hardeman2520fff2006-12-02 21:16:05 -0200254 break;
255 }
256
David Härdeman145859c2007-04-27 12:31:22 -0300257 /* initialise the key-up timeout handler */
258 init_timer(&budget_ci->ir.timer_keyup);
259 budget_ci->ir.timer_keyup.function = msp430_ir_keyup;
260 budget_ci->ir.timer_keyup.data = (unsigned long) &budget_ci->ir;
261 budget_ci->ir.last_raw = 0xffff; /* An impossible value */
David Hardeman8cc532e2006-12-02 21:16:05 -0200262 error = input_register_device(input_dev);
263 if (error) {
264 printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error);
265 goto out2;
Dmitry Torokhovb07b4782006-11-20 10:23:04 -0300266 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267
David Härdeman145859c2007-04-27 12:31:22 -0300268 /* note: these must be after input_register_device */
269 input_dev->rep[REP_DELAY] = 400;
270 input_dev->rep[REP_PERIOD] = 250;
271
David Hardeman8cc532e2006-12-02 21:16:05 -0200272 tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt,
273 (unsigned long) budget_ci);
274
Hartmut Birr97a2cf02006-12-03 10:49:47 -0300275 SAA7146_IER_ENABLE(saa, MASK_06);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276 saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI);
277
278 return 0;
David Hardeman8cc532e2006-12-02 21:16:05 -0200279
280out2:
281 input_free_device(input_dev);
282out1:
283 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700284}
285
286static void msp430_ir_deinit(struct budget_ci *budget_ci)
287{
288 struct saa7146_dev *saa = budget_ci->budget.dev;
David Hardemandd2f3982006-12-02 21:16:05 -0200289 struct input_dev *dev = budget_ci->ir.dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700290
Hartmut Birr97a2cf02006-12-03 10:49:47 -0300291 SAA7146_IER_DISABLE(saa, MASK_06);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
David Hardeman8cc532e2006-12-02 21:16:05 -0200293 tasklet_kill(&budget_ci->ir.msp430_irq_tasklet);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700294
David Härdeman145859c2007-04-27 12:31:22 -0300295 del_timer_sync(&dev->timer);
296 ir_input_nokey(dev, &budget_ci->ir.state);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700297
298 input_unregister_device(dev);
299}
300
301static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
302{
303 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
304
305 if (slot != 0)
306 return -EINVAL;
307
308 return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM,
309 DEBIADDR_ATTR | (address & 0xfff), 1, 1, 0);
310}
311
312static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
313{
314 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
315
316 if (slot != 0)
317 return -EINVAL;
318
319 return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM,
320 DEBIADDR_ATTR | (address & 0xfff), 1, value, 1, 0);
321}
322
323static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
324{
325 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
326
327 if (slot != 0)
328 return -EINVAL;
329
330 return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM,
331 DEBIADDR_IO | (address & 3), 1, 1, 0);
332}
333
334static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
335{
336 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
337
338 if (slot != 0)
339 return -EINVAL;
340
341 return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM,
342 DEBIADDR_IO | (address & 3), 1, value, 1, 0);
343}
344
345static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
346{
347 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
348 struct saa7146_dev *saa = budget_ci->budget.dev;
349
350 if (slot != 0)
351 return -EINVAL;
352
Andrew de Quincey96b194c2006-04-05 14:09:45 -0300353 if (budget_ci->ci_irq) {
354 // trigger on RISING edge during reset so we know when READY is re-asserted
355 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
356 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700357 budget_ci->slot_status = SLOTSTATUS_RESET;
358 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
359 msleep(1);
360 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
361 CICONTROL_RESET, 1, 0);
362
363 saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
364 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
365 return 0;
366}
367
368static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
369{
370 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
371 struct saa7146_dev *saa = budget_ci->budget.dev;
372
373 if (slot != 0)
374 return -EINVAL;
375
376 saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
377 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
378 return 0;
379}
380
381static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
382{
383 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
384 struct saa7146_dev *saa = budget_ci->budget.dev;
385 int tmp;
386
387 if (slot != 0)
388 return -EINVAL;
389
390 saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO);
391
392 tmp = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
393 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
394 tmp | CICONTROL_ENABLETS, 1, 0);
395
396 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
397 return 0;
398}
399
400static void ciintf_interrupt(unsigned long data)
401{
402 struct budget_ci *budget_ci = (struct budget_ci *) data;
403 struct saa7146_dev *saa = budget_ci->budget.dev;
404 unsigned int flags;
405
406 // ensure we don't get spurious IRQs during initialisation
407 if (!budget_ci->budget.ci_present)
408 return;
409
410 // read the CAM status
411 flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
412 if (flags & CICONTROL_CAMDETECT) {
413
414 // GPIO should be set to trigger on falling edge if a CAM is present
415 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
416
417 if (budget_ci->slot_status & SLOTSTATUS_NONE) {
418 // CAM insertion IRQ
419 budget_ci->slot_status = SLOTSTATUS_PRESENT;
420 dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0,
421 DVB_CA_EN50221_CAMCHANGE_INSERTED);
422
423 } else if (budget_ci->slot_status & SLOTSTATUS_RESET) {
424 // CAM ready (reset completed)
425 budget_ci->slot_status = SLOTSTATUS_READY;
426 dvb_ca_en50221_camready_irq(&budget_ci->ca, 0);
427
428 } else if (budget_ci->slot_status & SLOTSTATUS_READY) {
429 // FR/DA IRQ
430 dvb_ca_en50221_frda_irq(&budget_ci->ca, 0);
431 }
432 } else {
433
434 // trigger on rising edge if a CAM is not present - when a CAM is inserted, we
435 // only want to get the IRQ when it sets READY. If we trigger on the falling edge,
436 // the CAM might not actually be ready yet.
437 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
438
439 // generate a CAM removal IRQ if we haven't already
440 if (budget_ci->slot_status & SLOTSTATUS_OCCUPIED) {
441 // CAM removal IRQ
442 budget_ci->slot_status = SLOTSTATUS_NONE;
443 dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0,
444 DVB_CA_EN50221_CAMCHANGE_REMOVED);
445 }
446 }
447}
448
Andrew de Quincey96b194c2006-04-05 14:09:45 -0300449static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
450{
451 struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
452 unsigned int flags;
453
454 // ensure we don't get spurious IRQs during initialisation
455 if (!budget_ci->budget.ci_present)
456 return -EINVAL;
457
458 // read the CAM status
459 flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
460 if (flags & CICONTROL_CAMDETECT) {
461 // mark it as present if it wasn't before
462 if (budget_ci->slot_status & SLOTSTATUS_NONE) {
463 budget_ci->slot_status = SLOTSTATUS_PRESENT;
464 }
465
466 // during a RESET, we check if we can read from IO memory to see when CAM is ready
467 if (budget_ci->slot_status & SLOTSTATUS_RESET) {
468 if (ciintf_read_attribute_mem(ca, slot, 0) == 0x1d) {
469 budget_ci->slot_status = SLOTSTATUS_READY;
470 }
471 }
472 } else {
473 budget_ci->slot_status = SLOTSTATUS_NONE;
474 }
475
476 if (budget_ci->slot_status != SLOTSTATUS_NONE) {
477 if (budget_ci->slot_status & SLOTSTATUS_READY) {
478 return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
479 }
480 return DVB_CA_EN50221_POLL_CAM_PRESENT;
481 }
482
483 return 0;
484}
485
Linus Torvalds1da177e2005-04-16 15:20:36 -0700486static int ciintf_init(struct budget_ci *budget_ci)
487{
488 struct saa7146_dev *saa = budget_ci->budget.dev;
489 int flags;
490 int result;
Andrew de Quincey96b194c2006-04-05 14:09:45 -0300491 int ci_version;
492 int ca_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700493
494 memset(&budget_ci->ca, 0, sizeof(struct dvb_ca_en50221));
495
496 // enable DEBI pins
Hartmut Birr2a893de2006-12-03 21:08:08 -0300497 saa7146_write(saa, MC1, MASK_27 | MASK_11);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700498
499 // test if it is there
Andrew de Quincey96b194c2006-04-05 14:09:45 -0300500 ci_version = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CIVERSION, 1, 1, 0);
501 if ((ci_version & 0xa0) != 0xa0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700502 result = -ENODEV;
503 goto error;
504 }
Andrew de Quincey96b194c2006-04-05 14:09:45 -0300505
Linus Torvalds1da177e2005-04-16 15:20:36 -0700506 // determine whether a CAM is present or not
507 flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
508 budget_ci->slot_status = SLOTSTATUS_NONE;
509 if (flags & CICONTROL_CAMDETECT)
510 budget_ci->slot_status = SLOTSTATUS_PRESENT;
511
Andrew de Quincey96b194c2006-04-05 14:09:45 -0300512 // version 0xa2 of the CI firmware doesn't generate interrupts
513 if (ci_version == 0xa2) {
514 ca_flags = 0;
515 budget_ci->ci_irq = 0;
516 } else {
517 ca_flags = DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE |
518 DVB_CA_EN50221_FLAG_IRQ_FR |
519 DVB_CA_EN50221_FLAG_IRQ_DA;
520 budget_ci->ci_irq = 1;
521 }
522
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523 // register CI interface
524 budget_ci->ca.owner = THIS_MODULE;
525 budget_ci->ca.read_attribute_mem = ciintf_read_attribute_mem;
526 budget_ci->ca.write_attribute_mem = ciintf_write_attribute_mem;
527 budget_ci->ca.read_cam_control = ciintf_read_cam_control;
528 budget_ci->ca.write_cam_control = ciintf_write_cam_control;
529 budget_ci->ca.slot_reset = ciintf_slot_reset;
530 budget_ci->ca.slot_shutdown = ciintf_slot_shutdown;
531 budget_ci->ca.slot_ts_enable = ciintf_slot_ts_enable;
Andrew de Quincey96b194c2006-04-05 14:09:45 -0300532 budget_ci->ca.poll_slot_status = ciintf_poll_slot_status;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700533 budget_ci->ca.data = budget_ci;
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -0700534 if ((result = dvb_ca_en50221_init(&budget_ci->budget.dvb_adapter,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700535 &budget_ci->ca,
Andrew de Quincey96b194c2006-04-05 14:09:45 -0300536 ca_flags, 1)) != 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700537 printk("budget_ci: CI interface detected, but initialisation failed.\n");
538 goto error;
539 }
Andrew de Quincey96b194c2006-04-05 14:09:45 -0300540
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541 // Setup CI slot IRQ
Andrew de Quincey96b194c2006-04-05 14:09:45 -0300542 if (budget_ci->ci_irq) {
543 tasklet_init(&budget_ci->ciintf_irq_tasklet, ciintf_interrupt, (unsigned long) budget_ci);
544 if (budget_ci->slot_status != SLOTSTATUS_NONE) {
545 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
546 } else {
547 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
548 }
Hartmut Birr97a2cf02006-12-03 10:49:47 -0300549 SAA7146_IER_ENABLE(saa, MASK_03);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700550 }
Andrew de Quincey96b194c2006-04-05 14:09:45 -0300551
552 // enable interface
Linus Torvalds1da177e2005-04-16 15:20:36 -0700553 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
554 CICONTROL_RESET, 1, 0);
555
556 // success!
557 printk("budget_ci: CI interface initialised\n");
558 budget_ci->budget.ci_present = 1;
559
560 // forge a fake CI IRQ so the CAM state is setup correctly
Andrew de Quincey96b194c2006-04-05 14:09:45 -0300561 if (budget_ci->ci_irq) {
562 flags = DVB_CA_EN50221_CAMCHANGE_REMOVED;
563 if (budget_ci->slot_status != SLOTSTATUS_NONE)
564 flags = DVB_CA_EN50221_CAMCHANGE_INSERTED;
565 dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, flags);
566 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567
568 return 0;
569
570error:
Hartmut Birr2a893de2006-12-03 21:08:08 -0300571 saa7146_write(saa, MC1, MASK_27);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700572 return result;
573}
574
575static void ciintf_deinit(struct budget_ci *budget_ci)
576{
577 struct saa7146_dev *saa = budget_ci->budget.dev;
578
579 // disable CI interrupts
Andrew de Quincey96b194c2006-04-05 14:09:45 -0300580 if (budget_ci->ci_irq) {
Hartmut Birr97a2cf02006-12-03 10:49:47 -0300581 SAA7146_IER_DISABLE(saa, MASK_03);
Andrew de Quincey96b194c2006-04-05 14:09:45 -0300582 saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
583 tasklet_kill(&budget_ci->ciintf_irq_tasklet);
584 }
585
586 // reset interface
Linus Torvalds1da177e2005-04-16 15:20:36 -0700587 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
588 msleep(1);
589 ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
590 CICONTROL_RESET, 1, 0);
591
592 // disable TS data stream to CI interface
593 saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT);
594
595 // release the CA device
596 dvb_ca_en50221_release(&budget_ci->ca);
597
598 // disable DEBI pins
Hartmut Birr2a893de2006-12-03 21:08:08 -0300599 saa7146_write(saa, MC1, MASK_27);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600}
601
602static void budget_ci_irq(struct saa7146_dev *dev, u32 * isr)
603{
604 struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv;
605
606 dprintk(8, "dev: %p, budget_ci: %p\n", dev, budget_ci);
607
608 if (*isr & MASK_06)
David Hardemandd2f3982006-12-02 21:16:05 -0200609 tasklet_schedule(&budget_ci->ir.msp430_irq_tasklet);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610
611 if (*isr & MASK_10)
612 ttpci_budget_irq10_handler(dev, isr);
613
Andrew de Quincey96b194c2006-04-05 14:09:45 -0300614 if ((*isr & MASK_03) && (budget_ci->budget.ci_present) && (budget_ci->ci_irq))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700615 tasklet_schedule(&budget_ci->ciintf_irq_tasklet);
616}
617
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618static u8 philips_su1278_tt_inittab[] = {
619 0x01, 0x0f,
620 0x02, 0x30,
621 0x03, 0x00,
622 0x04, 0x5b,
623 0x05, 0x85,
624 0x06, 0x02,
625 0x07, 0x00,
626 0x08, 0x02,
627 0x09, 0x00,
628 0x0C, 0x01,
629 0x0D, 0x81,
630 0x0E, 0x44,
631 0x0f, 0x14,
632 0x10, 0x3c,
633 0x11, 0x84,
634 0x12, 0xda,
635 0x13, 0x97,
636 0x14, 0x95,
637 0x15, 0xc9,
638 0x16, 0x19,
639 0x17, 0x8c,
640 0x18, 0x59,
641 0x19, 0xf8,
642 0x1a, 0xfe,
643 0x1c, 0x7f,
644 0x1d, 0x00,
645 0x1e, 0x00,
646 0x1f, 0x50,
647 0x20, 0x00,
648 0x21, 0x00,
649 0x22, 0x00,
650 0x23, 0x00,
651 0x28, 0x00,
652 0x29, 0x28,
653 0x2a, 0x14,
654 0x2b, 0x0f,
655 0x2c, 0x09,
656 0x2d, 0x09,
657 0x31, 0x1f,
658 0x32, 0x19,
659 0x33, 0xfc,
660 0x34, 0x93,
661 0xff, 0xff
662};
663
664static int philips_su1278_tt_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
665{
666 stv0299_writereg(fe, 0x0e, 0x44);
667 if (srate >= 10000000) {
668 stv0299_writereg(fe, 0x13, 0x97);
669 stv0299_writereg(fe, 0x14, 0x95);
670 stv0299_writereg(fe, 0x15, 0xc9);
671 stv0299_writereg(fe, 0x17, 0x8c);
672 stv0299_writereg(fe, 0x1a, 0xfe);
673 stv0299_writereg(fe, 0x1c, 0x7f);
674 stv0299_writereg(fe, 0x2d, 0x09);
675 } else {
676 stv0299_writereg(fe, 0x13, 0x99);
677 stv0299_writereg(fe, 0x14, 0x8d);
678 stv0299_writereg(fe, 0x15, 0xce);
679 stv0299_writereg(fe, 0x17, 0x43);
680 stv0299_writereg(fe, 0x1a, 0x1d);
681 stv0299_writereg(fe, 0x1c, 0x12);
682 stv0299_writereg(fe, 0x2d, 0x05);
683 }
684 stv0299_writereg(fe, 0x0e, 0x23);
685 stv0299_writereg(fe, 0x0f, 0x94);
686 stv0299_writereg(fe, 0x10, 0x39);
687 stv0299_writereg(fe, 0x15, 0xc9);
688
689 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
690 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
691 stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
692
693 return 0;
694}
695
Andrew de Quincey0f591d42006-04-18 17:47:11 -0300696static int philips_su1278_tt_tuner_set_params(struct dvb_frontend *fe,
697 struct dvb_frontend_parameters *params)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700698{
Andrew de Quincey0f591d42006-04-18 17:47:11 -0300699 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700 u32 div;
701 u8 buf[4];
702 struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
703
704 if ((params->frequency < 950000) || (params->frequency > 2150000))
705 return -EINVAL;
706
707 div = (params->frequency + (500 - 1)) / 500; // round correctly
708 buf[0] = (div >> 8) & 0x7f;
709 buf[1] = div & 0xff;
710 buf[2] = 0x80 | ((div & 0x18000) >> 10) | 2;
711 buf[3] = 0x20;
712
713 if (params->u.qpsk.symbol_rate < 4000000)
714 buf[3] |= 1;
715
716 if (params->frequency < 1250000)
717 buf[3] |= 0;
718 else if (params->frequency < 1550000)
719 buf[3] |= 0x40;
720 else if (params->frequency < 2050000)
721 buf[3] |= 0x80;
722 else if (params->frequency < 2150000)
723 buf[3] |= 0xC0;
724
Patrick Boettcherdea74862006-05-14 05:01:31 -0300725 if (fe->ops.i2c_gate_ctrl)
726 fe->ops.i2c_gate_ctrl(fe, 1);
Andrew de Quincey0f591d42006-04-18 17:47:11 -0300727 if (i2c_transfer(&budget_ci->budget.i2c_adap, &msg, 1) != 1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700728 return -EIO;
729 return 0;
730}
731
732static struct stv0299_config philips_su1278_tt_config = {
733
734 .demod_address = 0x68,
735 .inittab = philips_su1278_tt_inittab,
736 .mclk = 64000000UL,
737 .invert = 0,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700738 .skip_reinit = 1,
Oliver Endrissda2c7f62008-04-20 22:13:37 -0300739 .lock_output = STV0299_LOCKOUTPUT_1,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700740 .volt13_op0_op1 = STV0299_VOLT13_OP1,
741 .min_delay_ms = 50,
742 .set_symbol_rate = philips_su1278_tt_set_symbol_rate,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700743};
744
745
746
Andrew de Quincey0f591d42006-04-18 17:47:11 -0300747static int philips_tdm1316l_tuner_init(struct dvb_frontend *fe)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700748{
749 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
750 static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab };
751 static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 };
Andrew de Quinceydd2bbb12005-07-07 17:57:54 -0700752 struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = td1316_init,.len =
Linus Torvalds1da177e2005-04-16 15:20:36 -0700753 sizeof(td1316_init) };
754
755 // setup PLL configuration
Patrick Boettcherdea74862006-05-14 05:01:31 -0300756 if (fe->ops.i2c_gate_ctrl)
757 fe->ops.i2c_gate_ctrl(fe, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700758 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
759 return -EIO;
760 msleep(1);
761
762 // disable the mc44BC374c (do not check for errors)
763 tuner_msg.addr = 0x65;
764 tuner_msg.buf = disable_mc44BC374c;
765 tuner_msg.len = sizeof(disable_mc44BC374c);
Patrick Boettcherdea74862006-05-14 05:01:31 -0300766 if (fe->ops.i2c_gate_ctrl)
767 fe->ops.i2c_gate_ctrl(fe, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) {
Patrick Boettcherdea74862006-05-14 05:01:31 -0300769 if (fe->ops.i2c_gate_ctrl)
770 fe->ops.i2c_gate_ctrl(fe, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771 i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1);
772 }
773
774 return 0;
775}
776
Andrew de Quincey0f591d42006-04-18 17:47:11 -0300777static int philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700778{
779 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
780 u8 tuner_buf[4];
Andrew de Quinceydd2bbb12005-07-07 17:57:54 -0700781 struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = tuner_buf,.len = sizeof(tuner_buf) };
Linus Torvalds1da177e2005-04-16 15:20:36 -0700782 int tuner_frequency = 0;
783 u8 band, cp, filter;
784
785 // determine charge pump
786 tuner_frequency = params->frequency + 36130000;
787 if (tuner_frequency < 87000000)
788 return -EINVAL;
789 else if (tuner_frequency < 130000000)
790 cp = 3;
791 else if (tuner_frequency < 160000000)
792 cp = 5;
793 else if (tuner_frequency < 200000000)
794 cp = 6;
795 else if (tuner_frequency < 290000000)
796 cp = 3;
797 else if (tuner_frequency < 420000000)
798 cp = 5;
799 else if (tuner_frequency < 480000000)
800 cp = 6;
801 else if (tuner_frequency < 620000000)
802 cp = 3;
803 else if (tuner_frequency < 830000000)
804 cp = 5;
805 else if (tuner_frequency < 895000000)
806 cp = 7;
807 else
808 return -EINVAL;
809
810 // determine band
811 if (params->frequency < 49000000)
812 return -EINVAL;
813 else if (params->frequency < 159000000)
814 band = 1;
815 else if (params->frequency < 444000000)
816 band = 2;
817 else if (params->frequency < 861000000)
818 band = 4;
819 else
820 return -EINVAL;
821
822 // setup PLL filter and TDA9889
823 switch (params->u.ofdm.bandwidth) {
824 case BANDWIDTH_6_MHZ:
Andrew de Quinceyc10d14d2006-08-08 09:10:08 -0300825 tda1004x_writereg(fe, 0x0C, 0x14);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700826 filter = 0;
827 break;
828
829 case BANDWIDTH_7_MHZ:
Andrew de Quinceyc10d14d2006-08-08 09:10:08 -0300830 tda1004x_writereg(fe, 0x0C, 0x80);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700831 filter = 0;
832 break;
833
834 case BANDWIDTH_8_MHZ:
Andrew de Quinceyc10d14d2006-08-08 09:10:08 -0300835 tda1004x_writereg(fe, 0x0C, 0x14);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700836 filter = 1;
837 break;
838
839 default:
840 return -EINVAL;
841 }
842
843 // calculate divisor
844 // ((36130000+((1000000/6)/2)) + Finput)/(1000000/6)
845 tuner_frequency = (((params->frequency / 1000) * 6) + 217280) / 1000;
846
847 // setup tuner buffer
848 tuner_buf[0] = tuner_frequency >> 8;
849 tuner_buf[1] = tuner_frequency & 0xff;
850 tuner_buf[2] = 0xca;
851 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
852
Patrick Boettcherdea74862006-05-14 05:01:31 -0300853 if (fe->ops.i2c_gate_ctrl)
854 fe->ops.i2c_gate_ctrl(fe, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
856 return -EIO;
857
858 msleep(1);
859 return 0;
860}
861
862static int philips_tdm1316l_request_firmware(struct dvb_frontend *fe,
863 const struct firmware **fw, char *name)
864{
865 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
866
867 return request_firmware(fw, name, &budget_ci->budget.dev->pci->dev);
868}
869
870static struct tda1004x_config philips_tdm1316l_config = {
871
872 .demod_address = 0x8,
873 .invert = 0,
874 .invert_oclk = 0,
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700875 .xtal_freq = TDA10046_XTAL_4M,
876 .agc_config = TDA10046_AGC_DEFAULT,
877 .if_freq = TDA10046_FREQ_3617,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700878 .request_firmware = philips_tdm1316l_request_firmware,
879};
880
Oliver Endriss6c914492007-02-02 19:12:53 -0300881static struct tda1004x_config philips_tdm1316l_config_invert = {
882
883 .demod_address = 0x8,
884 .invert = 1,
885 .invert_oclk = 0,
886 .xtal_freq = TDA10046_XTAL_4M,
887 .agc_config = TDA10046_AGC_DEFAULT,
888 .if_freq = TDA10046_FREQ_3617,
889 .request_firmware = philips_tdm1316l_request_firmware,
890};
891
Andrew de Quincey0f591d42006-04-18 17:47:11 -0300892static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700893{
894 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
895 u8 tuner_buf[5];
896 struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,
897 .flags = 0,
898 .buf = tuner_buf,
899 .len = sizeof(tuner_buf) };
900 int tuner_frequency = 0;
901 u8 band, cp, filter;
902
903 // determine charge pump
904 tuner_frequency = params->frequency + 36125000;
905 if (tuner_frequency < 87000000)
906 return -EINVAL;
907 else if (tuner_frequency < 130000000) {
908 cp = 3;
909 band = 1;
910 } else if (tuner_frequency < 160000000) {
911 cp = 5;
912 band = 1;
913 } else if (tuner_frequency < 200000000) {
914 cp = 6;
Oliver Endriss910a7b62007-05-03 13:16:12 -0300915 band = 1;
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700916 } else if (tuner_frequency < 290000000) {
917 cp = 3;
918 band = 2;
919 } else if (tuner_frequency < 420000000) {
920 cp = 5;
921 band = 2;
922 } else if (tuner_frequency < 480000000) {
923 cp = 6;
924 band = 2;
925 } else if (tuner_frequency < 620000000) {
926 cp = 3;
927 band = 4;
928 } else if (tuner_frequency < 830000000) {
929 cp = 5;
930 band = 4;
931 } else if (tuner_frequency < 895000000) {
932 cp = 7;
933 band = 4;
934 } else
935 return -EINVAL;
936
937 // assume PLL filter should always be 8MHz for the moment.
938 filter = 1;
939
940 // calculate divisor
941 tuner_frequency = (params->frequency + 36125000 + (62500/2)) / 62500;
942
943 // setup tuner buffer
944 tuner_buf[0] = tuner_frequency >> 8;
945 tuner_buf[1] = tuner_frequency & 0xff;
946 tuner_buf[2] = 0xc8;
947 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
948 tuner_buf[4] = 0x80;
949
Patrick Boettcherdea74862006-05-14 05:01:31 -0300950 if (fe->ops.i2c_gate_ctrl)
951 fe->ops.i2c_gate_ctrl(fe, 1);
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700952 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
953 return -EIO;
954
955 msleep(50);
956
Patrick Boettcherdea74862006-05-14 05:01:31 -0300957 if (fe->ops.i2c_gate_ctrl)
958 fe->ops.i2c_gate_ctrl(fe, 1);
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700959 if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
960 return -EIO;
961
962 msleep(1);
963
964 return 0;
965}
966
967static u8 dvbc_philips_tdm1316l_inittab[] = {
968 0x80, 0x01,
969 0x80, 0x00,
970 0x81, 0x01,
971 0x81, 0x00,
972 0x00, 0x09,
973 0x01, 0x69,
974 0x03, 0x00,
975 0x04, 0x00,
976 0x07, 0x00,
977 0x08, 0x00,
978 0x20, 0x00,
979 0x21, 0x40,
980 0x22, 0x00,
981 0x23, 0x00,
982 0x24, 0x40,
983 0x25, 0x88,
984 0x30, 0xff,
985 0x31, 0x00,
986 0x32, 0xff,
987 0x33, 0x00,
988 0x34, 0x50,
989 0x35, 0x7f,
990 0x36, 0x00,
991 0x37, 0x20,
992 0x38, 0x00,
993 0x40, 0x1c,
994 0x41, 0xff,
995 0x42, 0x29,
996 0x43, 0x20,
997 0x44, 0xff,
998 0x45, 0x00,
999 0x46, 0x00,
1000 0x49, 0x04,
1001 0x4a, 0x00,
1002 0x4b, 0x7b,
1003 0x52, 0x30,
1004 0x55, 0xae,
1005 0x56, 0x47,
1006 0x57, 0xe1,
1007 0x58, 0x3a,
1008 0x5a, 0x1e,
1009 0x5b, 0x34,
1010 0x60, 0x00,
1011 0x63, 0x00,
1012 0x64, 0x00,
1013 0x65, 0x00,
1014 0x66, 0x00,
1015 0x67, 0x00,
1016 0x68, 0x00,
1017 0x69, 0x00,
1018 0x6a, 0x02,
1019 0x6b, 0x00,
1020 0x70, 0xff,
1021 0x71, 0x00,
1022 0x72, 0x00,
1023 0x73, 0x00,
1024 0x74, 0x0c,
1025 0x80, 0x00,
1026 0x81, 0x00,
1027 0x82, 0x00,
1028 0x83, 0x00,
1029 0x84, 0x04,
1030 0x85, 0x80,
1031 0x86, 0x24,
1032 0x87, 0x78,
1033 0x88, 0x10,
1034 0x89, 0x00,
1035 0x90, 0x01,
1036 0x91, 0x01,
1037 0xa0, 0x04,
1038 0xa1, 0x00,
1039 0xa2, 0x00,
1040 0xb0, 0x91,
1041 0xb1, 0x0b,
1042 0xc0, 0x53,
1043 0xc1, 0x70,
1044 0xc2, 0x12,
1045 0xd0, 0x00,
1046 0xd1, 0x00,
1047 0xd2, 0x00,
1048 0xd3, 0x00,
1049 0xd4, 0x00,
1050 0xd5, 0x00,
1051 0xde, 0x00,
1052 0xdf, 0x00,
1053 0x61, 0x38,
1054 0x62, 0x0a,
1055 0x53, 0x13,
1056 0x59, 0x08,
1057 0xff, 0xff,
1058};
1059
1060static struct stv0297_config dvbc_philips_tdm1316l_config = {
1061 .demod_address = 0x1c,
1062 .inittab = dvbc_philips_tdm1316l_inittab,
1063 .invert = 0,
Thomas Kaiserb8d4c232006-04-27 21:45:20 -03001064 .stop_during_read = 1,
Andrew de Quinceydc27a162005-09-09 13:03:07 -07001065};
1066
Sigmund Augdal11417da2008-06-15 17:25:46 -03001067static struct tda10023_config tda10023_config = {
1068 .demod_address = 0xc,
1069 .invert = 0,
1070 .xtal = 16000000,
1071 .pll_m = 11,
1072 .pll_p = 3,
1073 .pll_n = 1,
1074 .deltaf = 0xa511,
1075};
Andrew de Quinceydc27a162005-09-09 13:03:07 -07001076
Manu Abrahama55bc842008-10-23 18:32:50 -03001077/* TT S2-3200 DVB-S (STB0899) Inittab */
Marko Schluessler9e0dc662008-10-23 18:16:40 -03001078static const struct stb0899_s1_reg tt3200_stb0899_s1_init_1[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001079
Marko Schluessler9e0dc662008-10-23 18:16:40 -03001080// 0x0000000b , /* SYSREG */
1081 { STB0899_DEV_ID , 0x81 },
1082 { STB0899_DISCNTRL1 , 0x32 },
1083 { STB0899_DISCNTRL2 , 0x80 },
1084 { STB0899_DISRX_ST0 , 0x04 },
1085 { STB0899_DISRX_ST1 , 0x00 },
1086 { STB0899_DISPARITY , 0x00 },
1087 { STB0899_DISFIFO , 0x00 },
1088 { STB0899_DISSTATUS , 0x20 },
1089 { STB0899_DISF22 , 0x8c },
1090 { STB0899_DISF22RX , 0x9a },
1091 //SYSREG ?
1092 { STB0899_ACRPRESC , 0x11 },
1093 { STB0899_ACRDIV1 , 0x0a },
1094 { STB0899_ACRDIV2 , 0x05 },
1095 { STB0899_DACR1 , 0x00 },
1096 { STB0899_DACR2 , 0x00 },
1097 { STB0899_OUTCFG , 0x00 },
1098 { STB0899_MODECFG , 0x00 },
1099 { STB0899_IRQSTATUS_3 , 0x30 },
1100 { STB0899_IRQSTATUS_2 , 0x00 },
1101 { STB0899_IRQSTATUS_1 , 0x00 },
1102 { STB0899_IRQSTATUS_0 , 0x00 },
1103 { STB0899_IRQMSK_3 , 0xf3 },
1104 { STB0899_IRQMSK_2 , 0xfc },
1105 { STB0899_IRQMSK_1 , 0xff },
1106 { STB0899_IRQMSK_0 , 0xff },
1107 { STB0899_IRQCFG , 0x00 },
1108 { STB0899_I2CCFG , 0x88 },
1109 { STB0899_I2CRPT , 0x5c },
1110 { STB0899_IOPVALUE5 , 0x00 },
1111 { STB0899_IOPVALUE4 , 0x20 },
1112 { STB0899_IOPVALUE3 , 0xc9 },
1113 { STB0899_IOPVALUE2 , 0x90 },
1114 { STB0899_IOPVALUE1 , 0x40 },
1115 { STB0899_IOPVALUE0 , 0x00 },
1116 { STB0899_GPIO00CFG , 0x82 },
1117 { STB0899_GPIO01CFG , 0x82 },
1118 { STB0899_GPIO02CFG , 0x82 },
1119 { STB0899_GPIO03CFG , 0x82 },
1120 { STB0899_GPIO04CFG , 0x82 },
1121 { STB0899_GPIO05CFG , 0x82 },
1122 { STB0899_GPIO06CFG , 0x82 },
1123 { STB0899_GPIO07CFG , 0x82 },
1124 { STB0899_GPIO08CFG , 0x82 },
1125 { STB0899_GPIO09CFG , 0x82 },
1126 { STB0899_GPIO10CFG , 0x82 },
1127 { STB0899_GPIO11CFG , 0x82 },
1128 { STB0899_GPIO12CFG , 0x82 },
1129 { STB0899_GPIO13CFG , 0x82 },
1130 { STB0899_GPIO14CFG , 0x82 },
1131 { STB0899_GPIO15CFG , 0x82 },
1132 { STB0899_GPIO16CFG , 0x82 },
1133 { STB0899_GPIO17CFG , 0x82 },
1134 { STB0899_GPIO18CFG , 0x82 },
1135 { STB0899_GPIO19CFG , 0x82 },
1136 { STB0899_GPIO20CFG , 0x82 },
1137 { STB0899_SDATCFG , 0xb8 },
1138 { STB0899_SCLTCFG , 0xba },
Manu Abrahama55bc842008-10-23 18:32:50 -03001139 { STB0899_AGCRFCFG , 0x1c }, /* 0x11 */
1140 { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */
1141 { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */
Marko Schluessler9e0dc662008-10-23 18:16:40 -03001142 { STB0899_DIRCLKCFG , 0x82 },
1143 { STB0899_CLKOUT27CFG , 0x7e },
1144 { STB0899_STDBYCFG , 0x82 },
1145 { STB0899_CS0CFG , 0x82 },
1146 { STB0899_CS1CFG , 0x82 },
1147 { STB0899_DISEQCOCFG , 0x20 },
1148 { STB0899_GPIO32CFG , 0x82 },
1149 { STB0899_GPIO33CFG , 0x82 },
1150 { STB0899_GPIO34CFG , 0x82 },
1151 { STB0899_GPIO35CFG , 0x82 },
1152 { STB0899_GPIO36CFG , 0x82 },
1153 { STB0899_GPIO37CFG , 0x82 },
1154 { STB0899_GPIO38CFG , 0x82 },
1155 { STB0899_GPIO39CFG , 0x82 },
Manu Abrahama55bc842008-10-23 18:32:50 -03001156 { STB0899_NCOARSE , 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
1157 { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
Marko Schluessler9e0dc662008-10-23 18:16:40 -03001158 { STB0899_FILTCTRL , 0x00 },
1159 { STB0899_SYSCTRL , 0x00 },
1160 { STB0899_STOPCLK1 , 0x20 },
1161 { STB0899_STOPCLK2 , 0x00 },
1162 { STB0899_INTBUFSTATUS , 0x00 },
1163 { STB0899_INTBUFCTRL , 0x0a },
1164 { 0xffff , 0xff },
1165};
1166
1167static const struct stb0899_s2_reg tt3200_stb0899_s2_init_2[] = {
1168
1169 { STB0899_OFF0_DMD_STATUS , STB0899_BASE_DMD_STATUS , 0x00000103 }, /* DMDSTATUS */
1170 { STB0899_OFF0_CRL_FREQ , STB0899_BASE_CRL_FREQ , 0x3ed1da56 }, /* CRLFREQ */
1171 { STB0899_OFF0_BTR_FREQ , STB0899_BASE_BTR_FREQ , 0x00004000 }, /* BTRFREQ */
1172 { STB0899_OFF0_IF_AGC_GAIN , STB0899_BASE_IF_AGC_GAIN , 0x00002ade }, /* IFAGCGAIN */
1173 { STB0899_OFF0_BB_AGC_GAIN , STB0899_BASE_BB_AGC_GAIN , 0x000001bc }, /* BBAGCGAIN */
1174 { STB0899_OFF0_DC_OFFSET , STB0899_BASE_DC_OFFSET , 0x00000200 }, /* DCOFFSET */
1175 { STB0899_OFF0_DMD_CNTRL , STB0899_BASE_DMD_CNTRL , 0x0000000f }, /* DMDCNTRL */
1176
1177 { STB0899_OFF0_IF_AGC_CNTRL , STB0899_BASE_IF_AGC_CNTRL , 0x03fb4a20 }, /* IFAGCCNTRL */
1178 { STB0899_OFF0_BB_AGC_CNTRL , STB0899_BASE_BB_AGC_CNTRL , 0x00200c97 }, /* BBAGCCNTRL */
1179
1180 { STB0899_OFF0_CRL_CNTRL , STB0899_BASE_CRL_CNTRL , 0x00000016 }, /* CRLCNTRL */
1181 { STB0899_OFF0_CRL_PHS_INIT , STB0899_BASE_CRL_PHS_INIT , 0x00000000 }, /* CRLPHSINIT */
1182 { STB0899_OFF0_CRL_FREQ_INIT , STB0899_BASE_CRL_FREQ_INIT , 0x00000000 }, /* CRLFREQINIT */
1183 { STB0899_OFF0_CRL_LOOP_GAIN , STB0899_BASE_CRL_LOOP_GAIN , 0x00000000 }, /* CRLLOOPGAIN */
1184 { STB0899_OFF0_CRL_NOM_FREQ , STB0899_BASE_CRL_NOM_FREQ , 0x3ed097b6 }, /* CRLNOMFREQ */
1185 { STB0899_OFF0_CRL_SWP_RATE , STB0899_BASE_CRL_SWP_RATE , 0x00000000 }, /* CRLSWPRATE */
1186 { STB0899_OFF0_CRL_MAX_SWP , STB0899_BASE_CRL_MAX_SWP , 0x00000000 }, /* CRLMAXSWP */
1187 { STB0899_OFF0_CRL_LK_CNTRL , STB0899_BASE_CRL_LK_CNTRL , 0x0f6cdc01 }, /* CRLLKCNTRL */
1188 { STB0899_OFF0_DECIM_CNTRL , STB0899_BASE_DECIM_CNTRL , 0x00000000 }, /* DECIMCNTRL */
1189 { STB0899_OFF0_BTR_CNTRL , STB0899_BASE_BTR_CNTRL , 0x00003993 }, /* BTRCNTRL */
1190 { STB0899_OFF0_BTR_LOOP_GAIN , STB0899_BASE_BTR_LOOP_GAIN , 0x000d3c6f }, /* BTRLOOPGAIN */
1191 { STB0899_OFF0_BTR_PHS_INIT , STB0899_BASE_BTR_PHS_INIT , 0x00000000 }, /* BTRPHSINIT */
1192 { STB0899_OFF0_BTR_FREQ_INIT , STB0899_BASE_BTR_FREQ_INIT , 0x00000000 }, /* BTRFREQINIT */
1193 { STB0899_OFF0_BTR_NOM_FREQ , STB0899_BASE_BTR_NOM_FREQ , 0x0238e38e }, /* BTRNOMFREQ */
1194 { STB0899_OFF0_BTR_LK_CNTRL , STB0899_BASE_BTR_LK_CNTRL , 0x00000000 }, /* BTRLKCNTRL */
1195 { STB0899_OFF0_DECN_CNTRL , STB0899_BASE_DECN_CNTRL , 0x00000000 }, /* DECNCNTRL */
1196 { STB0899_OFF0_TP_CNTRL , STB0899_BASE_TP_CNTRL , 0x00000000 }, /* TPCNTRL */
1197 { STB0899_OFF0_TP_BUF_STATUS , STB0899_BASE_TP_BUF_STATUS , 0x00000000 }, /* TPBUFSTATUS */
1198 { STB0899_OFF0_DC_ESTIM , STB0899_BASE_DC_ESTIM , 0x00000000 }, /* DCESTIM */
1199 { STB0899_OFF0_FLL_CNTRL , STB0899_BASE_FLL_CNTRL , 0x00000000 }, /* FLLCNTRL */
1200 { STB0899_OFF0_FLL_FREQ_WD , STB0899_BASE_FLL_FREQ_WD , 0x40070000 }, /* FLLFREQWD */
1201 { STB0899_OFF0_ANTI_ALIAS_SEL , STB0899_BASE_ANTI_ALIAS_SEL , 0x00000001 }, /* ANTIALIASSEL */
1202 { STB0899_OFF0_RRC_ALPHA , STB0899_BASE_RRC_ALPHA , 0x00000002 }, /* RRCALPHA */
1203 { STB0899_OFF0_DC_ADAPT_LSHFT , STB0899_BASE_DC_ADAPT_LSHFT , 0x00000000 }, /* DCADAPTISHFT */
1204 { STB0899_OFF0_IMB_OFFSET , STB0899_BASE_IMB_OFFSET , 0x0000fe01 }, /* IMBOFFSET */
1205 { STB0899_OFF0_IMB_ESTIMATE , STB0899_BASE_IMB_ESTIMATE , 0x00000000 }, /* IMBESTIMATE */
1206 { STB0899_OFF0_IMB_CNTRL , STB0899_BASE_IMB_CNTRL , 0x00000001 }, /* IMBCNTRL */
1207 { STB0899_OFF0_IF_AGC_CNTRL2 , STB0899_BASE_IF_AGC_CNTRL2 , 0x00005007 }, /* IFAGCCNTRL2 */
1208 { STB0899_OFF0_DMD_CNTRL2 , STB0899_BASE_DMD_CNTRL2 , 0x00000002 }, /* DMDCNTRL2 */
1209 { STB0899_OFF0_TP_BUFFER , STB0899_BASE_TP_BUFFER , 0x00000000 }, /* TPBUFFER */
1210 { STB0899_OFF0_TP_BUFFER1 , STB0899_BASE_TP_BUFFER1 , 0x00000000 }, /* TPBUFFER1 */
1211 { STB0899_OFF0_TP_BUFFER2 , STB0899_BASE_TP_BUFFER2 , 0x00000000 }, /* TPBUFFER2 */
1212 { STB0899_OFF0_TP_BUFFER3 , STB0899_BASE_TP_BUFFER3 , 0x00000000 }, /* TPBUFFER3 */
1213 { STB0899_OFF0_TP_BUFFER4 , STB0899_BASE_TP_BUFFER4 , 0x00000000 }, /* TPBUFFER4 */
1214 { STB0899_OFF0_TP_BUFFER5 , STB0899_BASE_TP_BUFFER5 , 0x00000000 }, /* TPBUFFER5 */
1215 { STB0899_OFF0_TP_BUFFER6 , STB0899_BASE_TP_BUFFER6 , 0x00000000 }, /* TPBUFFER6 */
1216 { STB0899_OFF0_TP_BUFFER7 , STB0899_BASE_TP_BUFFER7 , 0x00000000 }, /* TPBUFFER7 */
1217 { STB0899_OFF0_TP_BUFFER8 , STB0899_BASE_TP_BUFFER8 , 0x00000000 }, /* TPBUFFER8 */
1218 { STB0899_OFF0_TP_BUFFER9 , STB0899_BASE_TP_BUFFER9 , 0x00000000 }, /* TPBUFFER9 */
1219 { STB0899_OFF0_TP_BUFFER10 , STB0899_BASE_TP_BUFFER10 , 0x00000000 }, /* TPBUFFER10 */
1220 { STB0899_OFF0_TP_BUFFER11 , STB0899_BASE_TP_BUFFER11 , 0x00000000 }, /* TPBUFFER11 */
1221 { STB0899_OFF0_TP_BUFFER12 , STB0899_BASE_TP_BUFFER12 , 0x00000000 }, /* TPBUFFER12 */
1222 { STB0899_OFF0_TP_BUFFER13 , STB0899_BASE_TP_BUFFER13 , 0x00000000 }, /* TPBUFFER13 */
1223 { STB0899_OFF0_TP_BUFFER14 , STB0899_BASE_TP_BUFFER14 , 0x00000000 }, /* TPBUFFER14 */
1224 { STB0899_OFF0_TP_BUFFER15 , STB0899_BASE_TP_BUFFER15 , 0x00000000 }, /* TPBUFFER15 */
1225 { STB0899_OFF0_TP_BUFFER16 , STB0899_BASE_TP_BUFFER16 , 0x0000ff00 }, /* TPBUFFER16 */
1226 { STB0899_OFF0_TP_BUFFER17 , STB0899_BASE_TP_BUFFER17 , 0x00000100 }, /* TPBUFFER17 */
1227 { STB0899_OFF0_TP_BUFFER18 , STB0899_BASE_TP_BUFFER18 , 0x0000fe01 }, /* TPBUFFER18 */
1228 { STB0899_OFF0_TP_BUFFER19 , STB0899_BASE_TP_BUFFER19 , 0x000004fe }, /* TPBUFFER19 */
1229 { STB0899_OFF0_TP_BUFFER20 , STB0899_BASE_TP_BUFFER20 , 0x0000cfe7 }, /* TPBUFFER20 */
1230 { STB0899_OFF0_TP_BUFFER21 , STB0899_BASE_TP_BUFFER21 , 0x0000bec6 }, /* TPBUFFER21 */
1231 { STB0899_OFF0_TP_BUFFER22 , STB0899_BASE_TP_BUFFER22 , 0x0000c2bf }, /* TPBUFFER22 */
1232 { STB0899_OFF0_TP_BUFFER23 , STB0899_BASE_TP_BUFFER23 , 0x0000c1c1 }, /* TPBUFFER23 */
1233 { STB0899_OFF0_TP_BUFFER24 , STB0899_BASE_TP_BUFFER24 , 0x0000c1c1 }, /* TPBUFFER24 */
1234 { STB0899_OFF0_TP_BUFFER25 , STB0899_BASE_TP_BUFFER25 , 0x0000c1c1 }, /* TPBUFFER25 */
1235 { STB0899_OFF0_TP_BUFFER26 , STB0899_BASE_TP_BUFFER26 , 0x0000c1c1 }, /* TPBUFFER26 */
1236 { STB0899_OFF0_TP_BUFFER27 , STB0899_BASE_TP_BUFFER27 , 0x0000c1c0 }, /* TPBUFFER27 */
1237 { STB0899_OFF0_TP_BUFFER28 , STB0899_BASE_TP_BUFFER28 , 0x0000c0c0 }, /* TPBUFFER28 */
1238 { STB0899_OFF0_TP_BUFFER29 , STB0899_BASE_TP_BUFFER29 , 0x0000c1c1 }, /* TPBUFFER29 */
1239 { STB0899_OFF0_TP_BUFFER30 , STB0899_BASE_TP_BUFFER30 , 0x0000c1c1 }, /* TPBUFFER30 */
1240 { STB0899_OFF0_TP_BUFFER31 , STB0899_BASE_TP_BUFFER31 , 0x0000c0c1 }, /* TPBUFFER31 */
1241 { STB0899_OFF0_TP_BUFFER32 , STB0899_BASE_TP_BUFFER32 , 0x0000c0c1 }, /* TPBUFFER32 */
1242 { STB0899_OFF0_TP_BUFFER33 , STB0899_BASE_TP_BUFFER33 , 0x0000c1c1 }, /* TPBUFFER33 */
1243 { STB0899_OFF0_TP_BUFFER34 , STB0899_BASE_TP_BUFFER34 , 0x0000c1c1 }, /* TPBUFFER34 */
1244 { STB0899_OFF0_TP_BUFFER35 , STB0899_BASE_TP_BUFFER35 , 0x0000c0c1 }, /* TPBUFFER35 */
1245 { STB0899_OFF0_TP_BUFFER36 , STB0899_BASE_TP_BUFFER36 , 0x0000c1c1 }, /* TPBUFFER36 */
1246 { STB0899_OFF0_TP_BUFFER37 , STB0899_BASE_TP_BUFFER37 , 0x0000c0c1 }, /* TPBUFFER37 */
1247 { STB0899_OFF0_TP_BUFFER38 , STB0899_BASE_TP_BUFFER38 , 0x0000c1c1 }, /* TPBUFFER38 */
1248 { STB0899_OFF0_TP_BUFFER39 , STB0899_BASE_TP_BUFFER39 , 0x0000c0c0 }, /* TPBUFFER39 */
1249 { STB0899_OFF0_TP_BUFFER40 , STB0899_BASE_TP_BUFFER40 , 0x0000c1c0 }, /* TPBUFFER40 */
1250 { STB0899_OFF0_TP_BUFFER41 , STB0899_BASE_TP_BUFFER41 , 0x0000c1c1 }, /* TPBUFFER41 */
1251 { STB0899_OFF0_TP_BUFFER42 , STB0899_BASE_TP_BUFFER42 , 0x0000c0c0 }, /* TPBUFFER42 */
1252 { STB0899_OFF0_TP_BUFFER43 , STB0899_BASE_TP_BUFFER43 , 0x0000c1c0 }, /* TPBUFFER43 */
1253 { STB0899_OFF0_TP_BUFFER44 , STB0899_BASE_TP_BUFFER44 , 0x0000c0c1 }, /* TPBUFFER44 */
1254 { STB0899_OFF0_TP_BUFFER45 , STB0899_BASE_TP_BUFFER45 , 0x0000c1be }, /* TPBUFFER45 */
1255 { STB0899_OFF0_TP_BUFFER46 , STB0899_BASE_TP_BUFFER46 , 0x0000c1c9 }, /* TPBUFFER46 */
1256 { STB0899_OFF0_TP_BUFFER47 , STB0899_BASE_TP_BUFFER47 , 0x0000c0da }, /* TPBUFFER47 */
1257 { STB0899_OFF0_TP_BUFFER48 , STB0899_BASE_TP_BUFFER48 , 0x0000c0ba }, /* TPBUFFER48 */
1258 { STB0899_OFF0_TP_BUFFER49 , STB0899_BASE_TP_BUFFER49 , 0x0000c1c4 }, /* TPBUFFER49 */
1259 { STB0899_OFF0_TP_BUFFER50 , STB0899_BASE_TP_BUFFER50 , 0x0000c1bf }, /* TPBUFFER50 */
1260 { STB0899_OFF0_TP_BUFFER51 , STB0899_BASE_TP_BUFFER51 , 0x0000c0c1 }, /* TPBUFFER51 */
1261 { STB0899_OFF0_TP_BUFFER52 , STB0899_BASE_TP_BUFFER52 , 0x0000c1c0 }, /* TPBUFFER52 */
1262 { STB0899_OFF0_TP_BUFFER53 , STB0899_BASE_TP_BUFFER53 , 0x0000c0c1 }, /* TPBUFFER53 */
1263 { STB0899_OFF0_TP_BUFFER54 , STB0899_BASE_TP_BUFFER54 , 0x0000c1c1 }, /* TPBUFFER54 */
1264 { STB0899_OFF0_TP_BUFFER55 , STB0899_BASE_TP_BUFFER55 , 0x0000c1c1 }, /* TPBUFFER55 */
1265 { STB0899_OFF0_TP_BUFFER56 , STB0899_BASE_TP_BUFFER56 , 0x0000c1c1 }, /* TPBUFFER56 */
1266 { STB0899_OFF0_TP_BUFFER57 , STB0899_BASE_TP_BUFFER57 , 0x0000c1c1 }, /* TPBUFFER57 */
1267 { STB0899_OFF0_TP_BUFFER58 , STB0899_BASE_TP_BUFFER58 , 0x0000c1c1 }, /* TPBUFFER58 */
1268 { STB0899_OFF0_TP_BUFFER59 , STB0899_BASE_TP_BUFFER59 , 0x0000c1c1 }, /* TPBUFFER59 */
1269 { STB0899_OFF0_TP_BUFFER60 , STB0899_BASE_TP_BUFFER60 , 0x0000c1c1 }, /* TPBUFFER60 */
1270 { STB0899_OFF0_TP_BUFFER61 , STB0899_BASE_TP_BUFFER61 , 0x0000c1c1 }, /* TPBUFFER61 */
1271 { STB0899_OFF0_TP_BUFFER62 , STB0899_BASE_TP_BUFFER62 , 0x0000c1c1 }, /* TPBUFFER62 */
1272 { STB0899_OFF0_TP_BUFFER63 , STB0899_BASE_TP_BUFFER63 , 0x0000c1c0 }, /* TPBUFFER63 */
1273 { STB0899_OFF0_RESET_CNTRL , STB0899_BASE_RESET_CNTRL , 0x00000001 }, /* RESETCNTRL */
1274 { STB0899_OFF0_ACM_ENABLE , STB0899_BASE_ACM_ENABLE , 0x00005654 }, /* ACMENABLE */
1275 { STB0899_OFF0_DESCR_CNTRL , STB0899_BASE_DESCR_CNTRL , 0x00000000 }, /* DESCRCNTRL */
1276 { STB0899_OFF0_CSM_CNTRL1 , STB0899_BASE_CSM_CNTRL1 , 0x00020019 }, /* CSMCNTRL1 */
1277 { STB0899_OFF0_CSM_CNTRL2 , STB0899_BASE_CSM_CNTRL2 , 0x004b3237 }, /* CSMCNTRL2 */
1278 { STB0899_OFF0_CSM_CNTRL3 , STB0899_BASE_CSM_CNTRL3 , 0x0003dd17 }, /* CSMCNTRL3 */
1279 { STB0899_OFF0_CSM_CNTRL4 , STB0899_BASE_CSM_CNTRL4 , 0x00008008 }, /* CSMCNTRL4 */
1280 { STB0899_OFF0_UWP_CNTRL1 , STB0899_BASE_UWP_CNTRL1 , 0x002a3106 }, /* UWPCNTRL1 */
1281 { STB0899_OFF0_UWP_CNTRL2 , STB0899_BASE_UWP_CNTRL2 , 0x0006140a }, /* UWPCNTRL2 */
1282 { STB0899_OFF0_UWP_STAT1 , STB0899_BASE_UWP_STAT1 , 0x00008000 }, /* UWPSTAT1 */
1283 { STB0899_OFF0_UWP_STAT2 , STB0899_BASE_UWP_STAT2 , 0x00000000 }, /* UWPSTAT2 */
1284 { STB0899_OFF0_DMD_STAT2 , STB0899_BASE_DMD_STAT2 , 0x00000000 }, /* DMDSTAT2 */
1285 { STB0899_OFF0_FREQ_ADJ_SCALE , STB0899_BASE_FREQ_ADJ_SCALE , 0x00000471 }, /* FREQADJSCALE */
1286 { STB0899_OFF0_UWP_CNTRL3 , STB0899_BASE_UWP_CNTRL3 , 0x017b0465 }, /* UWPCNTRL3 */
1287 { STB0899_OFF0_SYM_CLK_SEL , STB0899_BASE_SYM_CLK_SEL , 0x00000002 }, /* SYMCLKSEL */
1288 { STB0899_OFF0_SOF_SRCH_TO , STB0899_BASE_SOF_SRCH_TO , 0x00196464 }, /* SOFSRCHTO */
1289 { STB0899_OFF0_ACQ_CNTRL1 , STB0899_BASE_ACQ_CNTRL1 , 0x00000603 }, /* ACQCNTRL1 */
1290 { STB0899_OFF0_ACQ_CNTRL2 , STB0899_BASE_ACQ_CNTRL2 , 0x02046666 }, /* ACQCNTRL2 */
1291 { STB0899_OFF0_ACQ_CNTRL3 , STB0899_BASE_ACQ_CNTRL3 , 0x10046583 }, /* ACQCNTRL3 */
1292 { STB0899_OFF0_FE_SETTLE , STB0899_BASE_FE_SETTLE , 0x00010404 }, /* FESETTLE */
1293 { STB0899_OFF0_AC_DWELL , STB0899_BASE_AC_DWELL , 0x0002aa8a }, /* ACDWELL */
1294 { STB0899_OFF0_ACQUIRE_TRIG , STB0899_BASE_ACQUIRE_TRIG , 0x00000000 }, /* ACQUIRETRIG */
1295 { STB0899_OFF0_LOCK_LOST , STB0899_BASE_LOCK_LOST , 0x00000001 }, /* LOCKLOST */
1296 { STB0899_OFF0_ACQ_STAT1 , STB0899_BASE_ACQ_STAT1 , 0x00000500 }, /* ACQSTAT1 */
1297 { STB0899_OFF0_ACQ_TIMEOUT , STB0899_BASE_ACQ_TIMEOUT , 0x0028a0a0 }, /* ACQTIMEOUT */
1298 { STB0899_OFF0_ACQ_TIME , STB0899_BASE_ACQ_TIME , 0x00000000 }, /* ACQTIME */
1299 { STB0899_OFF0_FINAL_AGC_CNTRL , STB0899_BASE_FINAL_AGC_CNTRL , 0x00800c17 }, /* FINALAGCCNTRL*/
1300 { STB0899_OFF0_FINAL_AGC_GAIN , STB0899_BASE_FINAL_AGC_GAIN , 0x00000000 }, /* FINALAGCCGAIN*/
1301 { STB0899_OFF0_EQUALIZER_INIT , STB0899_BASE_EQUALIZER_INIT , 0x00000000 }, /* EQUILIZERINIT*/
1302 { STB0899_OFF0_EQ_CNTRL , STB0899_BASE_EQ_CNTRL , 0x00054802 }, /* EQCNTL */
1303 { STB0899_OFF0_EQ_I_INIT_COEFF_0, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF0 */
1304 { STB0899_OFF1_EQ_I_INIT_COEFF_1, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF1 */
1305 { STB0899_OFF2_EQ_I_INIT_COEFF_2, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF2 */
1306 { STB0899_OFF3_EQ_I_INIT_COEFF_3, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF3 */
1307 { STB0899_OFF4_EQ_I_INIT_COEFF_4, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF4 */
1308 { STB0899_OFF5_EQ_I_INIT_COEFF_5, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000400 }, /* EQIINITCOEFF5 */
1309 { STB0899_OFF6_EQ_I_INIT_COEFF_6, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF6 */
1310 { STB0899_OFF7_EQ_I_INIT_COEFF_7, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF7 */
1311 { STB0899_OFF8_EQ_I_INIT_COEFF_8, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF8 */
1312 { STB0899_OFF9_EQ_I_INIT_COEFF_9, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF9 */
1313 { STB0899_OFFa_EQ_I_INIT_COEFF_10,STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF10*/
1314 { STB0899_OFF0_EQ_Q_INIT_COEFF_0, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF0 */
1315 { STB0899_OFF1_EQ_Q_INIT_COEFF_1, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF1 */
1316 { STB0899_OFF2_EQ_Q_INIT_COEFF_2, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF2 */
1317 { STB0899_OFF3_EQ_Q_INIT_COEFF_3, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF3 */
1318 { STB0899_OFF4_EQ_Q_INIT_COEFF_4, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF4 */
1319 { STB0899_OFF5_EQ_Q_INIT_COEFF_5, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF5 */
1320 { STB0899_OFF6_EQ_Q_INIT_COEFF_6, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF6 */
1321 { STB0899_OFF7_EQ_Q_INIT_COEFF_7, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF7 */
1322 { STB0899_OFF8_EQ_Q_INIT_COEFF_8, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF8 */
1323 { STB0899_OFF9_EQ_Q_INIT_COEFF_9, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF9 */
1324 { STB0899_OFFa_EQ_Q_INIT_COEFF_10,STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF10*/
1325 { STB0899_OFF0_EQ_I_OUT_COEFF_0 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT0 */
1326 { STB0899_OFF1_EQ_I_OUT_COEFF_1 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT1 */
1327 { STB0899_OFF2_EQ_I_OUT_COEFF_2 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT2 */
1328 { STB0899_OFF3_EQ_I_OUT_COEFF_3 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT3 */
1329 { STB0899_OFF4_EQ_I_OUT_COEFF_4 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT4 */
1330 { STB0899_OFF5_EQ_I_OUT_COEFF_5 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT5 */
1331 { STB0899_OFF6_EQ_I_OUT_COEFF_6 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT6 */
1332 { STB0899_OFF7_EQ_I_OUT_COEFF_7 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT7 */
1333 { STB0899_OFF8_EQ_I_OUT_COEFF_8 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT8 */
1334 { STB0899_OFF9_EQ_I_OUT_COEFF_9 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT9 */
1335 { STB0899_OFFa_EQ_I_OUT_COEFF_10,STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT10*/
1336 { STB0899_OFF0_EQ_Q_OUT_COEFF_0 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT0 */
1337 { STB0899_OFF1_EQ_Q_OUT_COEFF_1 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT1 */
1338 { STB0899_OFF2_EQ_Q_OUT_COEFF_2 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT2 */
1339 { STB0899_OFF3_EQ_Q_OUT_COEFF_3 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT3 */
1340 { STB0899_OFF4_EQ_Q_OUT_COEFF_4 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT4 */
1341 { STB0899_OFF5_EQ_Q_OUT_COEFF_5 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT5 */
1342 { STB0899_OFF6_EQ_Q_OUT_COEFF_6 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT6 */
1343 { STB0899_OFF7_EQ_Q_OUT_COEFF_7 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT7 */
1344 { STB0899_OFF8_EQ_Q_OUT_COEFF_8 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT8 */
1345 { STB0899_OFF9_EQ_Q_OUT_COEFF_9 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT9 */
1346 { STB0899_OFFa_EQ_Q_OUT_COEFF_10, STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT10*/
1347 { 0xffff , 0xffffffff , 0xffffffff },
1348};
1349
1350static const struct stb0899_s1_reg tt3200_stb0899_s1_init_3[] = {
1351 { STB0899_DEMOD , 0x00 },
1352 { STB0899_RCOMPC , 0xc9 },
1353 { STB0899_AGC1CN , 0x41 },
1354 { STB0899_AGC1REF , 0x10 },
1355 { STB0899_RTC , 0x7a },
1356 { STB0899_TMGCFG , 0x4e },
1357 { STB0899_AGC2REF , 0x34 },
1358 { STB0899_TLSR , 0x84 },
1359 { STB0899_CFD , 0xc7 },
1360 { STB0899_ACLC , 0x87 },
1361 { STB0899_BCLC , 0x94 },
1362 { STB0899_EQON , 0x41 },
1363 { STB0899_LDT , 0xdd },
1364 { STB0899_LDT2 , 0xc9 },
1365 { STB0899_EQUALREF , 0xb4 },
1366 { STB0899_TMGRAMP , 0x10 },
1367 { STB0899_TMGTHD , 0x30 },
1368 { STB0899_IDCCOMP , 0xfb },
1369 { STB0899_QDCCOMP , 0x03 },
1370 { STB0899_POWERI , 0x3b },
1371 { STB0899_POWERQ , 0x3d },
1372 { STB0899_RCOMP , 0x81 },
1373 { STB0899_AGCIQIN , 0x80 },
1374 { STB0899_AGC2I1 , 0x04 },
1375 { STB0899_AGC2I2 , 0xf5 },
1376 { STB0899_TLIR , 0x25 },
1377 { STB0899_RTF , 0x80 },
1378 { STB0899_DSTATUS , 0x00 },
1379 { STB0899_LDI , 0xca },
1380 { STB0899_CFRM , 0xf1 },
1381 { STB0899_CFRL , 0xf3 },
1382 { STB0899_NIRM , 0x2a },
1383 { STB0899_NIRL , 0x05 },
1384 { STB0899_ISYMB , 0x17 },
1385 { STB0899_QSYMB , 0xfa },
1386 { STB0899_SFRH , 0x2f },
1387 { STB0899_SFRM , 0x68 },
1388 { STB0899_SFRL , 0x40 },
1389 { STB0899_SFRUPH , 0x2f },
1390 { STB0899_SFRUPM , 0x68 },
1391 { STB0899_SFRUPL , 0x40 },
1392 { STB0899_EQUAI1 , 0xfd },
1393 { STB0899_EQUAQ1 , 0x04 },
1394 { STB0899_EQUAI2 , 0x0f },
1395 { STB0899_EQUAQ2 , 0xff },
1396 { STB0899_EQUAI3 , 0xdf },
1397 { STB0899_EQUAQ3 , 0xfa },
1398 { STB0899_EQUAI4 , 0x37 },
1399 { STB0899_EQUAQ4 , 0x0d },
1400 { STB0899_EQUAI5 , 0xbd },
1401 { STB0899_EQUAQ5 , 0xf7 },
1402 { STB0899_DSTATUS2 , 0x00 },
1403 { STB0899_VSTATUS , 0x00 },
1404 { STB0899_VERROR , 0xff },
1405 { STB0899_IQSWAP , 0x2a },
1406 { STB0899_ECNT1M , 0x00 },
1407 { STB0899_ECNT1L , 0x00 },
1408 { STB0899_ECNT2M , 0x00 },
1409 { STB0899_ECNT2L , 0x00 },
1410 { STB0899_ECNT3M , 0x00 },
1411 { STB0899_ECNT3L , 0x00 },
1412 { STB0899_FECAUTO1 , 0x06 },
1413 { STB0899_FECM , 0x01 },
1414 { STB0899_VTH12 , 0xf0 },
1415 { STB0899_VTH23 , 0xa0 },
1416 { STB0899_VTH34 , 0x78 },
1417 { STB0899_VTH56 , 0x4e },
1418 { STB0899_VTH67 , 0x48 },
1419 { STB0899_VTH78 , 0x38 },
1420 { STB0899_PRVIT , 0xff },
1421 { STB0899_VITSYNC , 0x19 },
Manu Abrahama55bc842008-10-23 18:32:50 -03001422 { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
Marko Schluessler9e0dc662008-10-23 18:16:40 -03001423 { STB0899_TSULC , 0x42 },
1424 { STB0899_RSLLC , 0x40 },
1425 { STB0899_TSLPL , 0x12 },
1426 { STB0899_TSCFGH , 0x0c },
1427 { STB0899_TSCFGM , 0x00 },
1428 { STB0899_TSCFGL , 0x0c },
1429 { STB0899_TSOUT , 0x07 },
1430 { STB0899_RSSYNCDEL , 0x00 },
1431 { STB0899_TSINHDELH , 0x02 },
1432 { STB0899_TSINHDELM , 0x00 },
1433 { STB0899_TSINHDELL , 0x00 },
1434 { STB0899_TSLLSTKM , 0x00 },
1435 { STB0899_TSLLSTKL , 0x00 },
1436 { STB0899_TSULSTKM , 0x00 },
1437 { STB0899_TSULSTKL , 0xab },
1438 { STB0899_PCKLENUL , 0x00 },
1439 { STB0899_PCKLENLL , 0xcc },
1440 { STB0899_RSPCKLEN , 0xcc },
1441 { STB0899_TSSTATUS , 0x80 },
1442 { STB0899_ERRCTRL1 , 0xb6 },
1443 { STB0899_ERRCTRL2 , 0x96 },
1444 { STB0899_ERRCTRL3 , 0x89 },
1445 { STB0899_DMONMSK1 , 0x27 },
1446 { STB0899_DMONMSK0 , 0x03 },
1447 { STB0899_DEMAPVIT , 0x5c },
1448 { STB0899_PLPARM , 0x1f },
1449 { STB0899_PDELCTRL , 0x48 },
1450 { STB0899_PDELCTRL2 , 0x00 },
1451 { STB0899_BBHCTRL1 , 0x00 },
1452 { STB0899_BBHCTRL2 , 0x00 },
1453 { STB0899_HYSTTHRESH , 0x77 },
1454 { STB0899_MATCSTM , 0x00 },
1455 { STB0899_MATCSTL , 0x00 },
1456 { STB0899_UPLCSTM , 0x00 },
1457 { STB0899_UPLCSTL , 0x00 },
1458 { STB0899_DFLCSTM , 0x00 },
1459 { STB0899_DFLCSTL , 0x00 },
1460 { STB0899_SYNCCST , 0x00 },
1461 { STB0899_SYNCDCSTM , 0x00 },
1462 { STB0899_SYNCDCSTL , 0x00 },
1463 { STB0899_ISI_ENTRY , 0x00 },
1464 { STB0899_ISI_BIT_EN , 0x00 },
1465 { STB0899_MATSTRM , 0x00 },
1466 { STB0899_MATSTRL , 0x00 },
1467 { STB0899_UPLSTRM , 0x00 },
1468 { STB0899_UPLSTRL , 0x00 },
1469 { STB0899_DFLSTRM , 0x00 },
1470 { STB0899_DFLSTRL , 0x00 },
1471 { STB0899_SYNCSTR , 0x00 },
1472 { STB0899_SYNCDSTRM , 0x00 },
1473 { STB0899_SYNCDSTRL , 0x00 },
1474 { STB0899_CFGPDELSTATUS1 , 0x10 },
1475 { STB0899_CFGPDELSTATUS2 , 0x00 },
1476 { STB0899_BBFERRORM , 0x00 },
1477 { STB0899_BBFERRORL , 0x00 },
1478 { STB0899_UPKTERRORM , 0x00 },
1479 { STB0899_UPKTERRORL , 0x00 },
1480 { 0xffff , 0xff },
1481};
1482
1483static const struct stb0899_s2_reg tt3200_stb0899_s2_init_4[] = {
1484 { STB0899_OFF0_BLOCK_LNGTH , STB0899_BASE_BLOCK_LNGTH , 0x00000008 }, /* BLOCKLNGTH */
1485 { STB0899_OFF0_ROW_STR , STB0899_BASE_ROW_STR , 0x000000b4 }, /* ROWSTR */
1486 { STB0899_OFF0_BN_END_ADDR , STB0899_BASE_BN_END_ADDR , 0x000004b5 }, /* BNANDADDR */
1487 { STB0899_OFF0_CN_END_ADDR , STB0899_BASE_CN_END_ADDR , 0x00000b4b }, /* CNANDADDR */
1488 { STB0899_OFF0_INFO_LENGTH , STB0899_BASE_INFO_LENGTH , 0x00000078 }, /* INFOLENGTH */
1489 { STB0899_OFF0_BOT_ADDR , STB0899_BASE_BOT_ADDR , 0x000001e0 }, /* BOT_ADDR */
1490 { STB0899_OFF0_BCH_BLK_LN , STB0899_BASE_BCH_BLK_LN , 0x0000a8c0 }, /* BCHBLKLN */
1491 { STB0899_OFF0_BCH_T , STB0899_BASE_BCH_T , 0x0000000c }, /* BCHT */
1492 { STB0899_OFF0_CNFG_MODE , STB0899_BASE_CNFG_MODE , 0x00000001 }, /* CNFGMODE */
1493 { STB0899_OFF0_LDPC_STAT , STB0899_BASE_LDPC_STAT , 0x0000000d }, /* LDPCSTAT */
1494 { STB0899_OFF0_ITER_SCALE , STB0899_BASE_ITER_SCALE , 0x00000040 }, /* ITERSCALE */
1495 { STB0899_OFF0_INPUT_MODE , STB0899_BASE_INPUT_MODE , 0x00000000 }, /* INPUTMODE */
1496 { STB0899_OFF0_LDPCDECRST , STB0899_BASE_LDPCDECRST , 0x00000000 }, /* LDPCDECRST */
1497 { STB0899_OFF0_CLK_PER_BYTE_RW , STB0899_BASE_CLK_PER_BYTE_RW , 0x00000008 }, /* CLKPERBYTE */
1498 { STB0899_OFF0_BCH_ERRORS , STB0899_BASE_BCH_ERRORS , 0x00000000 }, /* BCHERRORS */
1499 { STB0899_OFF0_LDPC_ERRORS , STB0899_BASE_LDPC_ERRORS , 0x00000000 }, /* LDPCERRORS */
1500 { STB0899_OFF0_BCH_MODE , STB0899_BASE_BCH_MODE , 0x00000000 }, /* BCHMODE */
1501 { STB0899_OFF0_ERR_ACC_PER , STB0899_BASE_ERR_ACC_PER , 0x00000008 }, /* ERRACCPER */
1502 { STB0899_OFF0_BCH_ERR_ACC , STB0899_BASE_BCH_ERR_ACC , 0x00000000 }, /* BCHERRACC */
1503 { STB0899_OFF0_FEC_TP_SEL , STB0899_BASE_FEC_TP_SEL , 0x00000000 }, /* FECTPSEL */
1504 { 0xffff , 0xffffffff , 0xffffffff },
1505};
1506
1507static const struct stb0899_s1_reg tt3200_stb0899_s1_init_5[] = {
1508 { STB0899_TSTCK , 0x00 },
1509 { STB0899_TSTRES , 0x00 },
1510 { STB0899_TSTOUT , 0x00 },
1511 { STB0899_TSTIN , 0x00 },
1512 { STB0899_TSTSYS , 0x00 },
1513 { STB0899_TSTCHIP , 0x00 },
1514 { STB0899_TSTFREE , 0x00 },
1515 { STB0899_TSTI2C , 0x00 },
1516 { STB0899_BITSPEEDM , 0x00 },
1517 { STB0899_BITSPEEDL , 0x00 },
1518 { STB0899_TBUSBIT , 0x00 },
1519 { STB0899_TSTDIS , 0x00 },
1520 { STB0899_TSTDISRX , 0x00 },
1521 { STB0899_TSTJETON , 0x00 },
1522 { STB0899_TSTDCADJ , 0x00 },
1523 { STB0899_TSTAGC1 , 0x00 },
1524 { STB0899_TSTAGC1N , 0x00 },
1525 { STB0899_TSTPOLYPH , 0x00 },
1526 { STB0899_TSTR , 0x00 },
1527 { STB0899_TSTAGC2 , 0x00 },
1528 { STB0899_TSTCTL1 , 0x00 },
1529 { STB0899_TSTCTL2 , 0x00 },
1530 { STB0899_TSTCTL3 , 0x00 },
1531 { STB0899_TSTDEMAP , 0x00 },
1532 { STB0899_TSTDEMAP2 , 0x00 },
1533 { STB0899_TSTDEMMON , 0x00 },
1534 { STB0899_TSTRATE , 0x00 },
1535 { STB0899_TSTSELOUT , 0x00 },
1536 { STB0899_TSYNC , 0x00 },
1537 { STB0899_TSTERR , 0x00 },
1538 { STB0899_TSTRAM1 , 0x00 },
1539 { STB0899_TSTVSELOUT , 0x00 },
1540 { STB0899_TSTFORCEIN , 0x00 },
1541 { STB0899_TSTRS1 , 0x00 },
1542 { STB0899_TSTRS2 , 0x00 },
1543 { STB0899_TSTRS3 , 0x00 },
1544 { STB0899_GHOSTREG , 0x81 },
1545 { 0xffff , 0xff },
1546};
1547
Manu Abrahama55bc842008-10-23 18:32:50 -03001548#define TT3200_DVBS2_ESNO_AVE 3
1549#define TT3200_DVBS2_ESNO_QUANT 32
1550#define TT3200_DVBS2_AVFRAMES_COARSE 10
1551#define TT3200_DVBS2_AVFRAMES_FINE 20
1552#define TT3200_DVBS2_MISS_THRESHOLD 6
1553#define TT3200_DVBS2_UWP_THRESHOLD_ACQ 1125
1554#define TT3200_DVBS2_UWP_THRESHOLD_TRACK 758
1555#define TT3200_DVBS2_UWP_THRESHOLD_SOF 1350
1556#define TT3200_DVBS2_SOF_SEARCH_TIMEOUT 1664100
1557
1558#define TT3200_DVBS2_BTR_NCO_BITS 28
1559#define TT3200_DVBS2_BTR_GAIN_SHIFT_OFFSET 15
1560#define TT3200_DVBS2_CRL_NCO_BITS 30
1561#define TT3200_DVBS2_LDPC_MAX_ITER 70
1562
1563static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency)
1564{
1565 struct dvb_frontend_ops *frontend_ops = NULL;
1566 struct dvb_tuner_ops *tuner_ops = NULL;
1567 struct tuner_state t_state;
1568 int err = 0;
1569
1570 if (&fe->ops)
1571 frontend_ops = &fe->ops;
1572 if (&frontend_ops->tuner_ops)
1573 tuner_ops = &frontend_ops->tuner_ops;
1574 if (tuner_ops->get_state) {
1575 if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
1576 printk("%s: Invalid parameter\n", __func__);
1577 return err;
1578 }
1579 *frequency = t_state.frequency;
1580 printk("%s: Frequency=%d\n", __func__, t_state.frequency);
1581 }
1582 return 0;
1583}
1584
1585static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency)
1586{
1587 struct dvb_frontend_ops *frontend_ops = NULL;
1588 struct dvb_tuner_ops *tuner_ops = NULL;
1589 struct tuner_state t_state;
1590 int err = 0;
1591
1592 t_state.frequency = frequency;
1593 if (&fe->ops)
1594 frontend_ops = &fe->ops;
1595 if (&frontend_ops->tuner_ops)
1596 tuner_ops = &frontend_ops->tuner_ops;
1597 if (tuner_ops->set_state) {
1598 if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
1599 printk("%s: Invalid parameter\n", __func__);
1600 return err;
1601 }
1602 }
1603 printk("%s: Frequency=%d\n", __func__, t_state.frequency);
1604 return 0;
1605}
1606
1607static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
1608{
1609 struct dvb_frontend_ops *frontend_ops = &fe->ops;
1610 struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
1611 struct tuner_state t_state;
1612 int err = 0;
1613
1614 if (&fe->ops)
1615 frontend_ops = &fe->ops;
1616 if (&frontend_ops->tuner_ops)
1617 tuner_ops = &frontend_ops->tuner_ops;
1618 if (tuner_ops->get_state) {
1619 if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state)) < 0) {
1620 printk("%s: Invalid parameter\n", __func__);
1621 return err;
1622 }
1623 *bandwidth = t_state.bandwidth;
1624 }
1625 printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth);
1626 return 0;
1627}
1628
1629static int stb6100_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
1630{
1631 struct dvb_frontend_ops *frontend_ops = NULL;
1632 struct dvb_tuner_ops *tuner_ops = NULL;
1633 struct tuner_state t_state;
1634 int err = 0;
1635
1636 t_state.frequency = bandwidth;
1637 if (&fe->ops)
1638 frontend_ops = &fe->ops;
1639 if (&frontend_ops->tuner_ops)
1640 tuner_ops = &frontend_ops->tuner_ops;
1641 if (tuner_ops->set_state) {
1642 if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state)) < 0) {
1643 printk("%s: Invalid parameter\n", __func__);
1644 return err;
1645 }
1646 }
1647 printk("%s: Bandwidth=%d\n", __func__, t_state.frequency);
1648 return 0;
1649}
1650
Marko Schluessler9e0dc662008-10-23 18:16:40 -03001651static struct stb0899_config tt3200_config = {
1652 .init_dev = tt3200_stb0899_s1_init_1,
Manu Abrahama55bc842008-10-23 18:32:50 -03001653 .init_s2_demod = tt3200_stb0899_s2_init_2,
1654 .init_s1_demod = tt3200_stb0899_s1_init_3,
1655 .init_s2_fec = tt3200_stb0899_s2_init_4,
Marko Schluessler9e0dc662008-10-23 18:16:40 -03001656 .init_tst = tt3200_stb0899_s1_init_5,
1657
Manu Abrahama55bc842008-10-23 18:32:50 -03001658 .demod_address = 0x68,
Marko Schluessler9e0dc662008-10-23 18:16:40 -03001659
1660 .xtal_freq = 27000000,
1661 .inversion = 1,
Manu Abrahama55bc842008-10-23 18:32:50 -03001662
1663 .esno_ave = TT3200_DVBS2_ESNO_AVE,
1664 .esno_quant = TT3200_DVBS2_ESNO_QUANT,
1665 .avframes_coarse = TT3200_DVBS2_AVFRAMES_COARSE,
1666 .avframes_fine = TT3200_DVBS2_AVFRAMES_FINE,
1667 .miss_threshold = TT3200_DVBS2_MISS_THRESHOLD,
1668 .uwp_threshold_acq = TT3200_DVBS2_UWP_THRESHOLD_ACQ,
1669 .uwp_threshold_track = TT3200_DVBS2_UWP_THRESHOLD_TRACK,
1670 .uwp_threshold_sof = TT3200_DVBS2_UWP_THRESHOLD_SOF,
1671 .sof_search_timeout = TT3200_DVBS2_SOF_SEARCH_TIMEOUT,
1672
1673 .btr_nco_bits = TT3200_DVBS2_BTR_NCO_BITS,
1674 .btr_gain_shift_offset = TT3200_DVBS2_BTR_GAIN_SHIFT_OFFSET,
1675 .crl_nco_bits = TT3200_DVBS2_CRL_NCO_BITS,
1676 .ldpc_max_iter = TT3200_DVBS2_LDPC_MAX_ITER,
1677
1678 .tuner_get_frequency = stb6100_get_frequency,
1679 .tuner_set_frequency = stb6100_set_frequency,
1680 .tuner_set_bandwidth = stb6100_set_bandwidth,
1681 .tuner_get_bandwidth = stb6100_get_bandwidth,
1682 .tuner_set_rfsiggain = NULL,
Marko Schluessler9e0dc662008-10-23 18:16:40 -03001683};
1684
1685struct stb6100_config tt3200_stb6100_config = {
1686 .tuner_address = 0x60
1687};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001688
1689static void frontend_init(struct budget_ci *budget_ci)
1690{
1691 switch (budget_ci->budget.dev->pci->subsystem_device) {
1692 case 0x100c: // Hauppauge/TT Nova-CI budget (stv0299/ALPS BSRU6(tsa5059))
1693 budget_ci->budget.dvb_frontend =
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001694 dvb_attach(stv0299_attach, &alps_bsru6_config, &budget_ci->budget.i2c_adap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001695 if (budget_ci->budget.dvb_frontend) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001696 budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
Andrew de Quincey0f591d42006-04-18 17:47:11 -03001697 budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698 break;
1699 }
1700 break;
1701
1702 case 0x100f: // Hauppauge/TT Nova-CI budget (stv0299b/Philips su1278(tsa5059))
1703 budget_ci->budget.dvb_frontend =
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001704 dvb_attach(stv0299_attach, &philips_su1278_tt_config, &budget_ci->budget.i2c_adap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001705 if (budget_ci->budget.dvb_frontend) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001706 budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_su1278_tt_tuner_set_params;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707 break;
1708 }
1709 break;
1710
Andrew de Quinceydc27a162005-09-09 13:03:07 -07001711 case 0x1010: // TT DVB-C CI budget (stv0297/Philips tdm1316l(tda6651tt))
1712 budget_ci->tuner_pll_address = 0x61;
1713 budget_ci->budget.dvb_frontend =
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001714 dvb_attach(stv0297_attach, &dvbc_philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
Andrew de Quinceydc27a162005-09-09 13:03:07 -07001715 if (budget_ci->budget.dvb_frontend) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001716 budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params;
Andrew de Quinceydc27a162005-09-09 13:03:07 -07001717 break;
1718 }
1719 break;
1720
Linus Torvalds1da177e2005-04-16 15:20:36 -07001721 case 0x1011: // Hauppauge/TT Nova-T budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889)
Andrew de Quinceydd2bbb12005-07-07 17:57:54 -07001722 budget_ci->tuner_pll_address = 0x63;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723 budget_ci->budget.dvb_frontend =
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001724 dvb_attach(tda10045_attach, &philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001725 if (budget_ci->budget.dvb_frontend) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001726 budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
1727 budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001728 break;
1729 }
1730 break;
Andrew de Quinceydd2bbb12005-07-07 17:57:54 -07001731
Andrew de Quinceydc27a162005-09-09 13:03:07 -07001732 case 0x1012: // TT DVB-T CI budget (tda10046/Philips tdm1316l(tda6651tt))
Andrew de Quinceydd2bbb12005-07-07 17:57:54 -07001733 budget_ci->tuner_pll_address = 0x60;
1734 budget_ci->budget.dvb_frontend =
Oliver Endriss6c914492007-02-02 19:12:53 -03001735 dvb_attach(tda10046_attach, &philips_tdm1316l_config_invert, &budget_ci->budget.i2c_adap);
Andrew de Quinceydd2bbb12005-07-07 17:57:54 -07001736 if (budget_ci->budget.dvb_frontend) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001737 budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
1738 budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
Andrew de Quinceydd2bbb12005-07-07 17:57:54 -07001739 break;
1740 }
1741 break;
Perceval Anichini8cc2e372006-02-28 09:52:44 -03001742
1743 case 0x1017: // TT S-1500 PCI
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001744 budget_ci->budget.dvb_frontend = dvb_attach(stv0299_attach, &alps_bsbe1_config, &budget_ci->budget.i2c_adap);
Perceval Anichini8cc2e372006-02-28 09:52:44 -03001745 if (budget_ci->budget.dvb_frontend) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001746 budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params;
Andrew de Quincey0f591d42006-04-18 17:47:11 -03001747 budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap;
1748
Patrick Boettcherdea74862006-05-14 05:01:31 -03001749 budget_ci->budget.dvb_frontend->ops.dishnetwork_send_legacy_command = NULL;
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001750 if (dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0) == NULL) {
Harvey Harrison3ca7fc82008-04-08 23:20:00 -03001751 printk("%s: No LNBP21 found!\n", __func__);
Andrew de Quincey2b100e72006-08-08 09:10:11 -03001752 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
Perceval Anichini8cc2e372006-02-28 09:52:44 -03001753 budget_ci->budget.dvb_frontend = NULL;
1754 }
1755 }
Sigmund Augdal11417da2008-06-15 17:25:46 -03001756 break;
Perceval Anichini8cc2e372006-02-28 09:52:44 -03001757
Sigmund Augdal11417da2008-06-15 17:25:46 -03001758 case 0x101a: /* TT Budget-C-1501 (philips tda10023/philips tda8274A) */
1759 budget_ci->budget.dvb_frontend = dvb_attach(tda10023_attach, &tda10023_config, &budget_ci->budget.i2c_adap, 0x48);
1760 if (budget_ci->budget.dvb_frontend) {
1761 if (dvb_attach(tda827x_attach, budget_ci->budget.dvb_frontend, 0x61, &budget_ci->budget.i2c_adap, NULL) == NULL) {
1762 printk(KERN_ERR "%s: No tda827x found!\n", __func__);
1763 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1764 budget_ci->budget.dvb_frontend = NULL;
1765 }
1766 }
Perceval Anichini8cc2e372006-02-28 09:52:44 -03001767 break;
Marko Schluessler9e0dc662008-10-23 18:16:40 -03001768
1769 case 0x1019: // TT S2-3200 PCI
1770 budget_ci->budget.dvb_frontend = stb0899_attach(&tt3200_config, &budget_ci->budget.i2c_adap);
1771 if (budget_ci->budget.dvb_frontend) {
1772 if (stb6100_attach(budget_ci->budget.dvb_frontend, &tt3200_stb6100_config, &budget_ci->budget.i2c_adap)) {
1773 if (lnbp21_attach(budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, 0, 0)) {
1774 printk("%s: No LNBP21 found!\n", __FUNCTION__);
1775 if (budget_ci->budget.dvb_frontend->ops.tuner_ops.release)
1776 budget_ci->budget.dvb_frontend->ops.tuner_ops.release(budget_ci->budget.dvb_frontend);
1777 if (budget_ci->budget.dvb_frontend->ops.release)
1778 budget_ci->budget.dvb_frontend->ops.release(budget_ci->budget.dvb_frontend);
1779 budget_ci->budget.dvb_frontend = NULL;
1780 }
1781 } else {
1782 if (budget_ci->budget.dvb_frontend->ops.release)
1783 budget_ci->budget.dvb_frontend->ops.release(budget_ci->budget.dvb_frontend);
1784 }
1785 }
1786 break;
1787
Linus Torvalds1da177e2005-04-16 15:20:36 -07001788 }
1789
1790 if (budget_ci->budget.dvb_frontend == NULL) {
Bjorn Helgaas29e66a62008-09-04 17:24:51 -03001791 printk("budget-ci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001792 budget_ci->budget.dev->pci->vendor,
1793 budget_ci->budget.dev->pci->device,
1794 budget_ci->budget.dev->pci->subsystem_vendor,
1795 budget_ci->budget.dev->pci->subsystem_device);
1796 } else {
1797 if (dvb_register_frontend
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001798 (&budget_ci->budget.dvb_adapter, budget_ci->budget.dvb_frontend)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001799 printk("budget-ci: Frontend registration failed!\n");
Andrew de Quinceyf52a8382006-08-08 09:10:09 -03001800 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001801 budget_ci->budget.dvb_frontend = NULL;
1802 }
1803 }
1804}
1805
1806static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
1807{
1808 struct budget_ci *budget_ci;
1809 int err;
1810
David Hardemanee579bc2006-12-02 21:16:05 -02001811 budget_ci = kzalloc(sizeof(struct budget_ci), GFP_KERNEL);
David Hardeman8cc532e2006-12-02 21:16:05 -02001812 if (!budget_ci) {
1813 err = -ENOMEM;
1814 goto out1;
1815 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816
1817 dprintk(2, "budget_ci: %p\n", budget_ci);
1818
Linus Torvalds1da177e2005-04-16 15:20:36 -07001819 dev->ext_priv = budget_ci;
1820
Janne Grunau26dc4d02008-09-21 20:50:11 -03001821 err = ttpci_budget_init(&budget_ci->budget, dev, info, THIS_MODULE,
1822 adapter_nr);
David Hardeman8cc532e2006-12-02 21:16:05 -02001823 if (err)
1824 goto out2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001825
David Hardeman8cc532e2006-12-02 21:16:05 -02001826 err = msp430_ir_init(budget_ci);
1827 if (err)
1828 goto out3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001829
1830 ciintf_init(budget_ci);
1831
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001832 budget_ci->budget.dvb_adapter.priv = budget_ci;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001833 frontend_init(budget_ci);
1834
Oliver Endriss32e4c3a2006-07-18 22:55:23 -03001835 ttpci_budget_init_hooks(&budget_ci->budget);
1836
Linus Torvalds1da177e2005-04-16 15:20:36 -07001837 return 0;
David Hardeman8cc532e2006-12-02 21:16:05 -02001838
1839out3:
1840 ttpci_budget_deinit(&budget_ci->budget);
1841out2:
1842 kfree(budget_ci);
1843out1:
1844 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001845}
1846
1847static int budget_ci_detach(struct saa7146_dev *dev)
1848{
1849 struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv;
1850 struct saa7146_dev *saa = budget_ci->budget.dev;
1851 int err;
1852
1853 if (budget_ci->budget.ci_present)
1854 ciintf_deinit(budget_ci);
David Hardeman8cc532e2006-12-02 21:16:05 -02001855 msp430_ir_deinit(budget_ci);
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001856 if (budget_ci->budget.dvb_frontend) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001857 dvb_unregister_frontend(budget_ci->budget.dvb_frontend);
Andrew de Quinceyf52a8382006-08-08 09:10:09 -03001858 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001859 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001860 err = ttpci_budget_deinit(&budget_ci->budget);
1861
Linus Torvalds1da177e2005-04-16 15:20:36 -07001862 // disable frontend and CI interface
1863 saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
1864
1865 kfree(budget_ci);
1866
1867 return err;
1868}
1869
1870static struct saa7146_extension budget_extension;
1871
Perceval Anichini8cc2e372006-02-28 09:52:44 -03001872MAKE_BUDGET_INFO(ttbs2, "TT-Budget/S-1500 PCI", BUDGET_TT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001873MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC);
1874MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT);
Andrew de Quinceydd2bbb12005-07-07 17:57:54 -07001875MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT);
Andrew de Quinceydc27a162005-09-09 13:03:07 -07001876MAKE_BUDGET_INFO(ttbcci, "TT-Budget-C-CI PCI", BUDGET_TT);
Sigmund Augdal11417da2008-06-15 17:25:46 -03001877MAKE_BUDGET_INFO(ttc1501, "TT-Budget C-1501 PCI", BUDGET_TT);
Marko Schluessler9e0dc662008-10-23 18:16:40 -03001878MAKE_BUDGET_INFO(tt3200, "TT-Budget S2-3200 PCI", BUDGET_TT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001879
1880static struct pci_device_id pci_tbl[] = {
1881 MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c),
1882 MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100f),
Andrew de Quinceydc27a162005-09-09 13:03:07 -07001883 MAKE_EXTENSION_PCI(ttbcci, 0x13c2, 0x1010),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001884 MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011),
Andrew de Quinceydd2bbb12005-07-07 17:57:54 -07001885 MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012),
Perceval Anichini8cc2e372006-02-28 09:52:44 -03001886 MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017),
Sigmund Augdal11417da2008-06-15 17:25:46 -03001887 MAKE_EXTENSION_PCI(ttc1501, 0x13c2, 0x101a),
Marko Schluessler9e0dc662008-10-23 18:16:40 -03001888 MAKE_EXTENSION_PCI(tt3200, 0x13c2, 0x1019),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001889 {
1890 .vendor = 0,
1891 }
1892};
1893
1894MODULE_DEVICE_TABLE(pci, pci_tbl);
1895
1896static struct saa7146_extension budget_extension = {
Dave Jones0e367a12006-08-07 13:18:56 -03001897 .name = "budget_ci dvb",
Oliver Endriss00c4cc62006-11-01 13:09:51 -03001898 .flags = SAA7146_USE_I2C_IRQ,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001899
1900 .module = THIS_MODULE,
1901 .pci_tbl = &pci_tbl[0],
1902 .attach = budget_ci_attach,
1903 .detach = budget_ci_detach,
1904
1905 .irq_mask = MASK_03 | MASK_06 | MASK_10,
1906 .irq_func = budget_ci_irq,
1907};
1908
1909static int __init budget_ci_init(void)
1910{
1911 return saa7146_register_extension(&budget_extension);
1912}
1913
1914static void __exit budget_ci_exit(void)
1915{
1916 saa7146_unregister_extension(&budget_extension);
1917}
1918
1919module_init(budget_ci_init);
1920module_exit(budget_ci_exit);
1921
1922MODULE_LICENSE("GPL");
1923MODULE_AUTHOR("Michael Hunold, Jack Thomasson, Andrew de Quincey, others");
1924MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
1925 "budget PCI DVB cards w/ CI-module produced by "
1926 "Siemens, Technotrend, Hauppauge");