blob: 2ce36765ebd35a81ff0f2e5f1653ee5357f04121 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * budget-av.c: driver for the SAA7146 based Budget DVB cards
3 * with analog video in
4 *
5 * Compiled from various sources by Michael Hunold <michael@mihu.de>
6 *
7 * CI interface support (c) 2004 Olivier Gournet <ogournet@anevia.com> &
8 * Andrew de Quincey <adq_dvb@lidskialf.net>
9 *
10 * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
11 *
12 * Copyright (C) 1999-2002 Ralph Metzler
13 * & Marcus Metzler for convergence integrated media GmbH
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
31 *
32 *
33 * the project's page is at http://www.linuxtv.org/dvb/
34 */
35
36#include "budget.h"
37#include "stv0299.h"
Manu Abraham41e11512007-09-22 21:28:11 -030038#include "stb0899_drv.h"
39#include "stb0899_reg.h"
40#include "tda8261.h"
Hartmut Birraa323ac2007-04-21 19:37:17 -030041#include "tda1002x.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070042#include "tda1004x.h"
Andrew de Quincey1c72cfdce2006-09-05 17:58:20 -030043#include "tua6100.h"
Regis Prevotf8bf1342006-01-11 23:31:53 -020044#include "dvb-pll.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070045#include <media/saa7146_vv.h>
46#include <linux/module.h>
47#include <linux/errno.h>
48#include <linux/slab.h>
49#include <linux/interrupt.h>
50#include <linux/input.h>
51#include <linux/spinlock.h>
52
53#include "dvb_ca_en50221.h"
54
55#define DEBICICAM 0x02420000
56
Andrew de Quincey5c1208b2006-05-22 10:32:02 -030057#define SLOTSTATUS_NONE 1
58#define SLOTSTATUS_PRESENT 2
59#define SLOTSTATUS_RESET 4
60#define SLOTSTATUS_READY 8
61#define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)
62
Janne Grunau26dc4d02008-09-21 20:50:11 -030063DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
64
Linus Torvalds1da177e2005-04-16 15:20:36 -070065struct budget_av {
66 struct budget budget;
67 struct video_device *vd;
68 int cur_input;
69 int has_saa7113;
70 struct tasklet_struct ciintf_irq_tasklet;
71 int slot_status;
72 struct dvb_ca_en50221 ca;
Andrew de Quincey5c1208b2006-05-22 10:32:02 -030073 u8 reinitialise_demod:1;
Linus Torvalds1da177e2005-04-16 15:20:36 -070074};
75
Andrew de Quincey5c1208b2006-05-22 10:32:02 -030076static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot);
77
78
Andrew de Quincey86f40cc2006-03-30 15:53:35 -030079/* GPIO Connections:
80 * 0 - Vcc/Reset (Reset is controlled by capacitor). Resets the frontend *AS WELL*!
81 * 1 - CI memory select 0=>IO memory, 1=>Attribute Memory
82 * 2 - CI Card Enable (Active Low)
83 * 3 - CI Card Detect
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -070084 */
Linus Torvalds1da177e2005-04-16 15:20:36 -070085
86/****************************************************************************
87 * INITIALIZATION
88 ****************************************************************************/
89
90static u8 i2c_readreg(struct i2c_adapter *i2c, u8 id, u8 reg)
91{
92 u8 mm1[] = { 0x00 };
93 u8 mm2[] = { 0x00 };
94 struct i2c_msg msgs[2];
95
96 msgs[0].flags = 0;
97 msgs[1].flags = I2C_M_RD;
98 msgs[0].addr = msgs[1].addr = id / 2;
99 mm1[0] = reg;
100 msgs[0].len = 1;
101 msgs[1].len = 1;
102 msgs[0].buf = mm1;
103 msgs[1].buf = mm2;
104
105 i2c_transfer(i2c, msgs, 2);
106
107 return mm2[0];
108}
109
110static int i2c_readregs(struct i2c_adapter *i2c, u8 id, u8 reg, u8 * buf, u8 len)
111{
112 u8 mm1[] = { reg };
113 struct i2c_msg msgs[2] = {
114 {.addr = id / 2,.flags = 0,.buf = mm1,.len = 1},
115 {.addr = id / 2,.flags = I2C_M_RD,.buf = buf,.len = len}
116 };
117
118 if (i2c_transfer(i2c, msgs, 2) != 2)
119 return -EIO;
120
121 return 0;
122}
123
124static int i2c_writereg(struct i2c_adapter *i2c, u8 id, u8 reg, u8 val)
125{
126 u8 msg[2] = { reg, val };
127 struct i2c_msg msgs;
128
129 msgs.flags = 0;
130 msgs.addr = id / 2;
131 msgs.len = 2;
132 msgs.buf = msg;
133 return i2c_transfer(i2c, &msgs, 1);
134}
135
136static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
137{
138 struct budget_av *budget_av = (struct budget_av *) ca->data;
139 int result;
140
141 if (slot != 0)
142 return -EINVAL;
143
144 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
145 udelay(1);
146
Andrew de Quincey2d0235d2006-01-09 15:25:05 -0200147 result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 1);
Andrew de Quincey5c1208b2006-05-22 10:32:02 -0300148 if (result == -ETIMEDOUT) {
149 ciintf_slot_shutdown(ca, slot);
150 printk(KERN_INFO "budget-av: cam ejected 1\n");
151 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700152 return result;
153}
154
155static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
156{
157 struct budget_av *budget_av = (struct budget_av *) ca->data;
158 int result;
159
160 if (slot != 0)
161 return -EINVAL;
162
163 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
164 udelay(1);
165
Andrew de Quincey2d0235d2006-01-09 15:25:05 -0200166 result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 1);
Andrew de Quincey5c1208b2006-05-22 10:32:02 -0300167 if (result == -ETIMEDOUT) {
168 ciintf_slot_shutdown(ca, slot);
169 printk(KERN_INFO "budget-av: cam ejected 2\n");
170 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700171 return result;
172}
173
174static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
175{
176 struct budget_av *budget_av = (struct budget_av *) ca->data;
177 int result;
178
179 if (slot != 0)
180 return -EINVAL;
181
182 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
183 udelay(1);
184
185 result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 3, 1, 0, 0);
Christoph Pfister87270732008-04-09 17:34:09 -0300186 if (result == -ETIMEDOUT) {
Andrew de Quincey5c1208b2006-05-22 10:32:02 -0300187 ciintf_slot_shutdown(ca, slot);
188 printk(KERN_INFO "budget-av: cam ejected 3\n");
189 return -ETIMEDOUT;
190 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191 return result;
192}
193
194static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
195{
196 struct budget_av *budget_av = (struct budget_av *) ca->data;
197 int result;
198
199 if (slot != 0)
200 return -EINVAL;
201
202 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
203 udelay(1);
204
205 result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 3, 1, value, 0, 0);
Andrew de Quincey5c1208b2006-05-22 10:32:02 -0300206 if (result == -ETIMEDOUT) {
207 ciintf_slot_shutdown(ca, slot);
208 printk(KERN_INFO "budget-av: cam ejected 5\n");
209 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210 return result;
211}
212
213static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
214{
215 struct budget_av *budget_av = (struct budget_av *) ca->data;
216 struct saa7146_dev *saa = budget_av->budget.dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700217
218 if (slot != 0)
219 return -EINVAL;
220
221 dprintk(1, "ciintf_slot_reset\n");
Andrew de Quincey5c1208b2006-05-22 10:32:02 -0300222 budget_av->slot_status = SLOTSTATUS_RESET;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700223
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -0700224 saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700225
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -0700226 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); /* Vcc off */
227 msleep(2);
228 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); /* Vcc on */
229 msleep(20); /* 20 ms Vcc settling time */
230
231 saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO); /* enable card */
Andrew de Quincey5c1208b2006-05-22 10:32:02 -0300232 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
233 msleep(20);
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -0700234
Andrew de Quincey5c1208b2006-05-22 10:32:02 -0300235 /* reinitialise the frontend if necessary */
236 if (budget_av->reinitialise_demod)
237 dvb_frontend_reinitialise(budget_av->budget.dvb_frontend);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700238
Linus Torvalds1da177e2005-04-16 15:20:36 -0700239 return 0;
240}
241
242static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
243{
244 struct budget_av *budget_av = (struct budget_av *) ca->data;
245 struct saa7146_dev *saa = budget_av->budget.dev;
246
247 if (slot != 0)
248 return -EINVAL;
249
250 dprintk(1, "ciintf_slot_shutdown\n");
251
252 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
Andrew de Quincey5c1208b2006-05-22 10:32:02 -0300253 budget_av->slot_status = SLOTSTATUS_NONE;
254
Linus Torvalds1da177e2005-04-16 15:20:36 -0700255 return 0;
256}
257
258static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
259{
260 struct budget_av *budget_av = (struct budget_av *) ca->data;
261 struct saa7146_dev *saa = budget_av->budget.dev;
262
263 if (slot != 0)
264 return -EINVAL;
265
266 dprintk(1, "ciintf_slot_ts_enable: %d\n", budget_av->slot_status);
267
268 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
Andrew de Quincey5c1208b2006-05-22 10:32:02 -0300269
Linus Torvalds1da177e2005-04-16 15:20:36 -0700270 return 0;
271}
272
273static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
274{
275 struct budget_av *budget_av = (struct budget_av *) ca->data;
276 struct saa7146_dev *saa = budget_av->budget.dev;
Andrew de Quincey5c1208b2006-05-22 10:32:02 -0300277 int result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278
279 if (slot != 0)
280 return -EINVAL;
281
Andrew de Quincey5c1208b2006-05-22 10:32:02 -0300282 /* test the card detect line - needs to be done carefully
283 * since it never goes high for some CAMs on this interface (e.g. topuptv) */
284 if (budget_av->slot_status == SLOTSTATUS_NONE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700285 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
286 udelay(1);
Andrew de Quincey5c1208b2006-05-22 10:32:02 -0300287 if (saa7146_read(saa, PSR) & MASK_06) {
288 if (budget_av->slot_status == SLOTSTATUS_NONE) {
289 budget_av->slot_status = SLOTSTATUS_PRESENT;
290 printk(KERN_INFO "budget-av: cam inserted A\n");
Andrew de Quincey2d0235d2006-01-09 15:25:05 -0200291 }
292 }
Andrew de Quincey5c1208b2006-05-22 10:32:02 -0300293 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
294 }
Andrew de Quincey2d0235d2006-01-09 15:25:05 -0200295
Andrew de Quincey5c1208b2006-05-22 10:32:02 -0300296 /* We also try and read from IO memory to work round the above detection bug. If
297 * there is no CAM, we will get a timeout. Only done if there is no cam
298 * present, since this test actually breaks some cams :(
299 *
300 * if the CI interface is not open, we also do the above test since we
301 * don't care if the cam has problems - we'll be resetting it on open() anyway */
302 if ((budget_av->slot_status == SLOTSTATUS_NONE) || (!open)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700303 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
Andrew de Quincey5c1208b2006-05-22 10:32:02 -0300304 result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1);
305 if ((result >= 0) && (budget_av->slot_status == SLOTSTATUS_NONE)) {
306 budget_av->slot_status = SLOTSTATUS_PRESENT;
307 printk(KERN_INFO "budget-av: cam inserted B\n");
308 } else if (result < 0) {
309 if (budget_av->slot_status != SLOTSTATUS_NONE) {
310 ciintf_slot_shutdown(ca, slot);
311 printk(KERN_INFO "budget-av: cam ejected 5\n");
312 return 0;
313 }
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -0700314 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700315 }
316
Andrew de Quincey5c1208b2006-05-22 10:32:02 -0300317 /* read from attribute memory in reset/ready state to know when the CAM is ready */
318 if (budget_av->slot_status == SLOTSTATUS_RESET) {
319 result = ciintf_read_attribute_mem(ca, slot, 0);
320 if (result == 0x1d) {
321 budget_av->slot_status = SLOTSTATUS_READY;
322 }
323 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324
Andrew de Quincey5c1208b2006-05-22 10:32:02 -0300325 /* work out correct return code */
326 if (budget_av->slot_status != SLOTSTATUS_NONE) {
327 if (budget_av->slot_status & SLOTSTATUS_READY) {
328 return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
329 }
330 return DVB_CA_EN50221_POLL_CAM_PRESENT;
331 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332 return 0;
333}
334
335static int ciintf_init(struct budget_av *budget_av)
336{
337 struct saa7146_dev *saa = budget_av->budget.dev;
338 int result;
339
340 memset(&budget_av->ca, 0, sizeof(struct dvb_ca_en50221));
341
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -0700342 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
343 saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344 saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO);
345 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
346
Linus Torvalds1da177e2005-04-16 15:20:36 -0700347 /* Enable DEBI pins */
Hartmut Birr2a893de2006-12-03 21:08:08 -0300348 saa7146_write(saa, MC1, MASK_27 | MASK_11);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349
350 /* register CI interface */
351 budget_av->ca.owner = THIS_MODULE;
352 budget_av->ca.read_attribute_mem = ciintf_read_attribute_mem;
353 budget_av->ca.write_attribute_mem = ciintf_write_attribute_mem;
354 budget_av->ca.read_cam_control = ciintf_read_cam_control;
355 budget_av->ca.write_cam_control = ciintf_write_cam_control;
356 budget_av->ca.slot_reset = ciintf_slot_reset;
357 budget_av->ca.slot_shutdown = ciintf_slot_shutdown;
358 budget_av->ca.slot_ts_enable = ciintf_slot_ts_enable;
359 budget_av->ca.poll_slot_status = ciintf_poll_slot_status;
360 budget_av->ca.data = budget_av;
Andrew de Quincey5c1208b2006-05-22 10:32:02 -0300361 budget_av->budget.ci_present = 1;
362 budget_av->slot_status = SLOTSTATUS_NONE;
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -0700363
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -0700364 if ((result = dvb_ca_en50221_init(&budget_av->budget.dvb_adapter,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365 &budget_av->ca, 0, 1)) != 0) {
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -0700366 printk(KERN_ERR "budget-av: ci initialisation failed.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367 goto error;
368 }
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -0700369
370 printk(KERN_INFO "budget-av: ci interface initialised.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371 return 0;
372
373error:
Hartmut Birr2a893de2006-12-03 21:08:08 -0300374 saa7146_write(saa, MC1, MASK_27);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375 return result;
376}
377
378static void ciintf_deinit(struct budget_av *budget_av)
379{
380 struct saa7146_dev *saa = budget_av->budget.dev;
381
382 saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
383 saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT);
384 saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
385 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
386
387 /* release the CA device */
388 dvb_ca_en50221_release(&budget_av->ca);
389
390 /* disable DEBI pins */
Hartmut Birr2a893de2006-12-03 21:08:08 -0300391 saa7146_write(saa, MC1, MASK_27);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392}
393
394
395static const u8 saa7113_tab[] = {
396 0x01, 0x08,
397 0x02, 0xc0,
398 0x03, 0x33,
399 0x04, 0x00,
400 0x05, 0x00,
401 0x06, 0xeb,
402 0x07, 0xe0,
403 0x08, 0x28,
404 0x09, 0x00,
405 0x0a, 0x80,
406 0x0b, 0x47,
407 0x0c, 0x40,
408 0x0d, 0x00,
409 0x0e, 0x01,
410 0x0f, 0x44,
411
412 0x10, 0x08,
413 0x11, 0x0c,
414 0x12, 0x7b,
415 0x13, 0x00,
416 0x15, 0x00, 0x16, 0x00, 0x17, 0x00,
417
418 0x57, 0xff,
419 0x40, 0x82, 0x58, 0x00, 0x59, 0x54, 0x5a, 0x07,
420 0x5b, 0x83, 0x5e, 0x00,
421 0xff
422};
423
424static int saa7113_init(struct budget_av *budget_av)
425{
426 struct budget *budget = &budget_av->budget;
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -0700427 struct saa7146_dev *saa = budget->dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428 const u8 *data = saa7113_tab;
429
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -0700430 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI);
431 msleep(200);
432
Linus Torvalds1da177e2005-04-16 15:20:36 -0700433 if (i2c_writereg(&budget->i2c_adap, 0x4a, 0x01, 0x08) != 1) {
434 dprintk(1, "saa7113 not found on KNC card\n");
435 return -ENODEV;
436 }
437
438 dprintk(1, "saa7113 detected and initializing\n");
439
440 while (*data != 0xff) {
441 i2c_writereg(&budget->i2c_adap, 0x4a, *data, *(data + 1));
442 data += 2;
443 }
444
445 dprintk(1, "saa7113 status=%02x\n", i2c_readreg(&budget->i2c_adap, 0x4a, 0x1f));
446
447 return 0;
448}
449
450static int saa7113_setinput(struct budget_av *budget_av, int input)
451{
452 struct budget *budget = &budget_av->budget;
453
454 if (1 != budget_av->has_saa7113)
455 return -ENODEV;
456
457 if (input == 1) {
458 i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc7);
459 i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x80);
460 } else if (input == 0) {
461 i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc0);
462 i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x00);
463 } else
464 return -EINVAL;
465
466 budget_av->cur_input = input;
467 return 0;
468}
469
470
471static int philips_su1278_ty_ci_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
472{
473 u8 aclk = 0;
474 u8 bclk = 0;
475 u8 m1;
476
477 aclk = 0xb5;
478 if (srate < 2000000)
479 bclk = 0x86;
480 else if (srate < 5000000)
481 bclk = 0x89;
482 else if (srate < 15000000)
483 bclk = 0x8f;
484 else if (srate < 45000000)
485 bclk = 0x95;
486
487 m1 = 0x14;
488 if (srate < 4000000)
489 m1 = 0x10;
490
491 stv0299_writereg(fe, 0x13, aclk);
492 stv0299_writereg(fe, 0x14, bclk);
493 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
494 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
495 stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
496 stv0299_writereg(fe, 0x0f, 0x80 | m1);
497
498 return 0;
499}
500
Andrew de Quinceye87d41c2006-04-18 17:47:11 -0300501static int philips_su1278_ty_ci_tuner_set_params(struct dvb_frontend *fe,
502 struct dvb_frontend_parameters *params)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700503{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700504 u32 div;
505 u8 buf[4];
Andrew de Quinceye87d41c2006-04-18 17:47:11 -0300506 struct budget *budget = (struct budget *) fe->dvb->priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507 struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
508
509 if ((params->frequency < 950000) || (params->frequency > 2150000))
510 return -EINVAL;
511
512 div = (params->frequency + (125 - 1)) / 125; // round correctly
513 buf[0] = (div >> 8) & 0x7f;
514 buf[1] = div & 0xff;
515 buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
516 buf[3] = 0x20;
517
518 if (params->u.qpsk.symbol_rate < 4000000)
519 buf[3] |= 1;
520
521 if (params->frequency < 1250000)
522 buf[3] |= 0;
523 else if (params->frequency < 1550000)
524 buf[3] |= 0x40;
525 else if (params->frequency < 2050000)
526 buf[3] |= 0x80;
527 else if (params->frequency < 2150000)
528 buf[3] |= 0xC0;
529
Patrick Boettcherdea74862006-05-14 05:01:31 -0300530 if (fe->ops.i2c_gate_ctrl)
531 fe->ops.i2c_gate_ctrl(fe, 1);
Andrew de Quinceye87d41c2006-04-18 17:47:11 -0300532 if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700533 return -EIO;
534 return 0;
535}
536
537static u8 typhoon_cinergy1200s_inittab[] = {
538 0x01, 0x15,
539 0x02, 0x30,
540 0x03, 0x00,
541 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
542 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
543 0x06, 0x40, /* DAC not used, set to high impendance mode */
544 0x07, 0x00, /* DAC LSB */
545 0x08, 0x40, /* DiSEqC off */
546 0x09, 0x00, /* FIFO */
547 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
548 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
549 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
550 0x10, 0x3f, // AGC2 0x3d
551 0x11, 0x84,
Oliver Endrissff29d062005-11-08 21:35:43 -0800552 0x12, 0xb9,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700553 0x15, 0xc9, // lock detector threshold
554 0x16, 0x00,
555 0x17, 0x00,
556 0x18, 0x00,
557 0x19, 0x00,
558 0x1a, 0x00,
559 0x1f, 0x50,
560 0x20, 0x00,
561 0x21, 0x00,
562 0x22, 0x00,
563 0x23, 0x00,
564 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
565 0x29, 0x1e, // 1/2 threshold
566 0x2a, 0x14, // 2/3 threshold
567 0x2b, 0x0f, // 3/4 threshold
568 0x2c, 0x09, // 5/6 threshold
569 0x2d, 0x05, // 7/8 threshold
570 0x2e, 0x01,
571 0x31, 0x1f, // test all FECs
572 0x32, 0x19, // viterbi and synchro search
573 0x33, 0xfc, // rs control
574 0x34, 0x93, // error control
575 0x0f, 0x92,
576 0xff, 0xff
577};
578
579static struct stv0299_config typhoon_config = {
580 .demod_address = 0x68,
581 .inittab = typhoon_cinergy1200s_inittab,
582 .mclk = 88000000UL,
583 .invert = 0,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584 .skip_reinit = 0,
Oliver Endrissda2c7f62008-04-20 22:13:37 -0300585 .lock_output = STV0299_LOCKOUTPUT_1,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700586 .volt13_op0_op1 = STV0299_VOLT13_OP0,
587 .min_delay_ms = 100,
588 .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589};
590
591
592static struct stv0299_config cinergy_1200s_config = {
593 .demod_address = 0x68,
594 .inittab = typhoon_cinergy1200s_inittab,
595 .mclk = 88000000UL,
596 .invert = 0,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597 .skip_reinit = 0,
Oliver Endrissda2c7f62008-04-20 22:13:37 -0300598 .lock_output = STV0299_LOCKOUTPUT_0,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700599 .volt13_op0_op1 = STV0299_VOLT13_OP0,
600 .min_delay_ms = 100,
601 .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602};
603
Andrew de Quinceyeffa7912006-01-09 15:25:09 -0200604static struct stv0299_config cinergy_1200s_1894_0010_config = {
605 .demod_address = 0x68,
606 .inittab = typhoon_cinergy1200s_inittab,
607 .mclk = 88000000UL,
608 .invert = 1,
609 .skip_reinit = 0,
Oliver Endrissda2c7f62008-04-20 22:13:37 -0300610 .lock_output = STV0299_LOCKOUTPUT_1,
Andrew de Quinceyeffa7912006-01-09 15:25:09 -0200611 .volt13_op0_op1 = STV0299_VOLT13_OP0,
612 .min_delay_ms = 100,
613 .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
Andrew de Quinceyeffa7912006-01-09 15:25:09 -0200614};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700615
Andrew de Quinceye87d41c2006-04-18 17:47:11 -0300616static int philips_cu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700617{
618 struct budget *budget = (struct budget *) fe->dvb->priv;
Hartmut Birraa323ac2007-04-21 19:37:17 -0300619 u8 buf[6];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700620 struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
Hartmut Birraa323ac2007-04-21 19:37:17 -0300621 int i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622
Hartmut Birraa323ac2007-04-21 19:37:17 -0300623#define CU1216_IF 36125000
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624#define TUNER_MUL 62500
625
Hartmut Birraa323ac2007-04-21 19:37:17 -0300626 u32 div = (params->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700627
628 buf[0] = (div >> 8) & 0x7f;
629 buf[1] = div & 0xff;
Hartmut Birraa323ac2007-04-21 19:37:17 -0300630 buf[2] = 0xce;
Johannes Stezenbacheef57642005-07-07 17:57:58 -0700631 buf[3] = (params->frequency < 150000000 ? 0x01 :
632 params->frequency < 445000000 ? 0x02 : 0x04);
Hartmut Birraa323ac2007-04-21 19:37:17 -0300633 buf[4] = 0xde;
634 buf[5] = 0x20;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635
Patrick Boettcherdea74862006-05-14 05:01:31 -0300636 if (fe->ops.i2c_gate_ctrl)
637 fe->ops.i2c_gate_ctrl(fe, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700638 if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
639 return -EIO;
Hartmut Birraa323ac2007-04-21 19:37:17 -0300640
641 /* wait for the pll lock */
642 msg.flags = I2C_M_RD;
643 msg.len = 1;
644 for (i = 0; i < 20; i++) {
645 if (fe->ops.i2c_gate_ctrl)
646 fe->ops.i2c_gate_ctrl(fe, 1);
647 if (i2c_transfer(&budget->i2c_adap, &msg, 1) == 1 && (buf[0] & 0x40))
648 break;
649 msleep(10);
650 }
651
652 /* switch the charge pump to the lower current */
653 msg.flags = 0;
654 msg.len = 2;
655 msg.buf = &buf[2];
656 buf[2] &= ~0x40;
657 if (fe->ops.i2c_gate_ctrl)
658 fe->ops.i2c_gate_ctrl(fe, 1);
659 if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
660 return -EIO;
661
Linus Torvalds1da177e2005-04-16 15:20:36 -0700662 return 0;
663}
664
Hartmut Birraa323ac2007-04-21 19:37:17 -0300665static struct tda1002x_config philips_cu1216_config = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700666 .demod_address = 0x0c,
Hartmut Birrdc120b02007-04-21 19:44:10 -0300667 .invert = 1,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700668};
669
Hartmut Birraa323ac2007-04-21 19:37:17 -0300670static struct tda1002x_config philips_cu1216_config_altaddress = {
Andrew de Quincey61cebe92006-11-19 14:10:59 -0300671 .demod_address = 0x0d,
Hartmut Birrdc120b02007-04-21 19:44:10 -0300672 .invert = 0,
Andrew de Quincey61cebe92006-11-19 14:10:59 -0300673};
674
Antti Palosaari4388c3b2008-05-17 22:58:04 -0300675static struct tda10023_config philips_cu1216_tda10023_config = {
676 .demod_address = 0x0c,
677 .invert = 1,
678};
679
Andrew de Quinceye87d41c2006-04-18 17:47:11 -0300680static int philips_tu1216_tuner_init(struct dvb_frontend *fe)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700681{
682 struct budget *budget = (struct budget *) fe->dvb->priv;
683 static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab };
684 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) };
685
686 // setup PLL configuration
Patrick Boettcherdea74862006-05-14 05:01:31 -0300687 if (fe->ops.i2c_gate_ctrl)
688 fe->ops.i2c_gate_ctrl(fe, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700689 if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
690 return -EIO;
691 msleep(1);
692
693 return 0;
694}
695
Andrew de Quinceye87d41c2006-04-18 17:47:11 -0300696static int philips_tu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700697{
698 struct budget *budget = (struct budget *) fe->dvb->priv;
699 u8 tuner_buf[4];
700 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,.len =
701 sizeof(tuner_buf) };
702 int tuner_frequency = 0;
703 u8 band, cp, filter;
704
705 // determine charge pump
706 tuner_frequency = params->frequency + 36166000;
707 if (tuner_frequency < 87000000)
708 return -EINVAL;
709 else if (tuner_frequency < 130000000)
710 cp = 3;
711 else if (tuner_frequency < 160000000)
712 cp = 5;
713 else if (tuner_frequency < 200000000)
714 cp = 6;
715 else if (tuner_frequency < 290000000)
716 cp = 3;
717 else if (tuner_frequency < 420000000)
718 cp = 5;
719 else if (tuner_frequency < 480000000)
720 cp = 6;
721 else if (tuner_frequency < 620000000)
722 cp = 3;
723 else if (tuner_frequency < 830000000)
724 cp = 5;
725 else if (tuner_frequency < 895000000)
726 cp = 7;
727 else
728 return -EINVAL;
729
730 // determine band
731 if (params->frequency < 49000000)
732 return -EINVAL;
733 else if (params->frequency < 161000000)
734 band = 1;
735 else if (params->frequency < 444000000)
736 band = 2;
737 else if (params->frequency < 861000000)
738 band = 4;
739 else
740 return -EINVAL;
741
742 // setup PLL filter
743 switch (params->u.ofdm.bandwidth) {
744 case BANDWIDTH_6_MHZ:
745 filter = 0;
746 break;
747
748 case BANDWIDTH_7_MHZ:
749 filter = 0;
750 break;
751
752 case BANDWIDTH_8_MHZ:
753 filter = 1;
754 break;
755
756 default:
757 return -EINVAL;
758 }
759
760 // calculate divisor
761 // ((36166000+((1000000/6)/2)) + Finput)/(1000000/6)
762 tuner_frequency = (((params->frequency / 1000) * 6) + 217496) / 1000;
763
764 // setup tuner buffer
765 tuner_buf[0] = (tuner_frequency >> 8) & 0x7f;
766 tuner_buf[1] = tuner_frequency & 0xff;
767 tuner_buf[2] = 0xca;
768 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
769
Patrick Boettcherdea74862006-05-14 05:01:31 -0300770 if (fe->ops.i2c_gate_ctrl)
771 fe->ops.i2c_gate_ctrl(fe, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700772 if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
773 return -EIO;
774
775 msleep(1);
776 return 0;
777}
778
779static int philips_tu1216_request_firmware(struct dvb_frontend *fe,
780 const struct firmware **fw, char *name)
781{
782 struct budget *budget = (struct budget *) fe->dvb->priv;
783
784 return request_firmware(fw, name, &budget->dev->pci->dev);
785}
786
787static struct tda1004x_config philips_tu1216_config = {
788
789 .demod_address = 0x8,
790 .invert = 1,
791 .invert_oclk = 1,
Hartmut Hackmannecb60de2005-07-07 17:57:40 -0700792 .xtal_freq = TDA10046_XTAL_4M,
793 .agc_config = TDA10046_AGC_DEFAULT,
794 .if_freq = TDA10046_FREQ_3617,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700795 .request_firmware = philips_tu1216_request_firmware,
796};
797
Regis Prevotf8bf1342006-01-11 23:31:53 -0200798static u8 philips_sd1878_inittab[] = {
799 0x01, 0x15,
800 0x02, 0x30,
801 0x03, 0x00,
802 0x04, 0x7d,
803 0x05, 0x35,
804 0x06, 0x40,
805 0x07, 0x00,
806 0x08, 0x43,
807 0x09, 0x02,
808 0x0C, 0x51,
809 0x0D, 0x82,
810 0x0E, 0x23,
811 0x10, 0x3f,
812 0x11, 0x84,
813 0x12, 0xb9,
814 0x15, 0xc9,
815 0x16, 0x19,
816 0x17, 0x8c,
817 0x18, 0x59,
818 0x19, 0xf8,
819 0x1a, 0xfe,
820 0x1c, 0x7f,
821 0x1d, 0x00,
822 0x1e, 0x00,
823 0x1f, 0x50,
824 0x20, 0x00,
825 0x21, 0x00,
826 0x22, 0x00,
827 0x23, 0x00,
828 0x28, 0x00,
829 0x29, 0x28,
830 0x2a, 0x14,
831 0x2b, 0x0f,
832 0x2c, 0x09,
833 0x2d, 0x09,
834 0x31, 0x1f,
835 0x32, 0x19,
836 0x33, 0xfc,
837 0x34, 0x93,
838 0xff, 0xff
839};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700840
Regis Prevotf8bf1342006-01-11 23:31:53 -0200841static int philips_sd1878_ci_set_symbol_rate(struct dvb_frontend *fe,
842 u32 srate, u32 ratio)
843{
844 u8 aclk = 0;
845 u8 bclk = 0;
846 u8 m1;
847
848 aclk = 0xb5;
849 if (srate < 2000000)
850 bclk = 0x86;
851 else if (srate < 5000000)
852 bclk = 0x89;
853 else if (srate < 15000000)
854 bclk = 0x8f;
855 else if (srate < 45000000)
856 bclk = 0x95;
857
858 m1 = 0x14;
859 if (srate < 4000000)
860 m1 = 0x10;
861
862 stv0299_writereg(fe, 0x0e, 0x23);
863 stv0299_writereg(fe, 0x0f, 0x94);
864 stv0299_writereg(fe, 0x10, 0x39);
865 stv0299_writereg(fe, 0x13, aclk);
866 stv0299_writereg(fe, 0x14, bclk);
867 stv0299_writereg(fe, 0x15, 0xc9);
868 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
869 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
870 stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
871 stv0299_writereg(fe, 0x0f, 0x80 | m1);
872
873 return 0;
874}
875
876static struct stv0299_config philips_sd1878_config = {
877 .demod_address = 0x68,
Andrew de Quincey5c1208b2006-05-22 10:32:02 -0300878 .inittab = philips_sd1878_inittab,
Regis Prevotf8bf1342006-01-11 23:31:53 -0200879 .mclk = 88000000UL,
880 .invert = 0,
881 .skip_reinit = 0,
Oliver Endrissda2c7f62008-04-20 22:13:37 -0300882 .lock_output = STV0299_LOCKOUTPUT_1,
Regis Prevotf8bf1342006-01-11 23:31:53 -0200883 .volt13_op0_op1 = STV0299_VOLT13_OP0,
884 .min_delay_ms = 100,
885 .set_symbol_rate = philips_sd1878_ci_set_symbol_rate,
Regis Prevotf8bf1342006-01-11 23:31:53 -0200886};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700887
Manu Abraham41e11512007-09-22 21:28:11 -0300888/* KNC1 DVB-S (STB0899) Inittab */
889static const struct stb0899_s1_reg knc1_stb0899_s1_init_1[] = {
890
891// 0x0000000b , /* SYSREG */
892 { STB0899_DEV_ID , 0x81 },
893 { STB0899_DISCNTRL1 , 0x32 },
894 { STB0899_DISCNTRL2 , 0x80 },
895 { STB0899_DISRX_ST0 , 0x04 },
896 { STB0899_DISRX_ST1 , 0x00 },
897 { STB0899_DISPARITY , 0x00 },
898 { STB0899_DISFIFO , 0x00 },
899 { STB0899_DISSTATUS , 0x20 },
900 { STB0899_DISF22 , 0x8c },
901 { STB0899_DISF22RX , 0x9a },
902 //SYSREG ?
903 { STB0899_ACRPRESC , 0x11 },
904 { STB0899_ACRDIV1 , 0x0a },
905 { STB0899_ACRDIV2 , 0x05 },
906 { STB0899_DACR1 , 0x00 },
907 { STB0899_DACR2 , 0x00 },
908 { STB0899_OUTCFG , 0x00 },
909 { STB0899_MODECFG , 0x00 },
910 { STB0899_IRQSTATUS_3 , 0x30 },
911 { STB0899_IRQSTATUS_2 , 0x00 },
912 { STB0899_IRQSTATUS_1 , 0x00 },
913 { STB0899_IRQSTATUS_0 , 0x00 },
914 { STB0899_IRQMSK_3 , 0xf3 },
915 { STB0899_IRQMSK_2 , 0xfc },
916 { STB0899_IRQMSK_1 , 0xff },
917 { STB0899_IRQMSK_0 , 0xff },
918 { STB0899_IRQCFG , 0x00 },
919 { STB0899_I2CCFG , 0x88 },
920 { STB0899_I2CRPT , 0x5c },
921 { STB0899_IOPVALUE5 , 0x00 },
922 { STB0899_IOPVALUE4 , 0x20 },
923 { STB0899_IOPVALUE3 , 0xc9 },
924 { STB0899_IOPVALUE2 , 0x90 },
925 { STB0899_IOPVALUE1 , 0x40 },
926 { STB0899_IOPVALUE0 , 0x00 },
927 { STB0899_GPIO00CFG , 0x82 },
928 { STB0899_GPIO01CFG , 0x82 },
929 { STB0899_GPIO02CFG , 0x82 },
930 { STB0899_GPIO03CFG , 0x82 },
931 { STB0899_GPIO04CFG , 0x82 },
932 { STB0899_GPIO05CFG , 0x82 },
933 { STB0899_GPIO06CFG , 0x82 },
934 { STB0899_GPIO07CFG , 0x82 },
935 { STB0899_GPIO08CFG , 0x82 },
936 { STB0899_GPIO09CFG , 0x82 },
937 { STB0899_GPIO10CFG , 0x82 },
938 { STB0899_GPIO11CFG , 0x82 },
939 { STB0899_GPIO12CFG , 0x82 },
940 { STB0899_GPIO13CFG , 0x82 },
941 { STB0899_GPIO14CFG , 0x82 },
942 { STB0899_GPIO15CFG , 0x82 },
943 { STB0899_GPIO16CFG , 0x82 },
944 { STB0899_GPIO17CFG , 0x82 },
945 { STB0899_GPIO18CFG , 0x82 },
946 { STB0899_GPIO19CFG , 0x82 },
947 { STB0899_GPIO20CFG , 0x82 },
948 { STB0899_SDATCFG , 0xb8 },
949 { STB0899_SCLTCFG , 0xba },
950 { STB0899_AGCRFCFG , 0x1c }, /* 0x11 */
951 { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */
952 { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */
953 { STB0899_DIRCLKCFG , 0x82 },
954 { STB0899_CLKOUT27CFG , 0x7e },
955 { STB0899_STDBYCFG , 0x82 },
956 { STB0899_CS0CFG , 0x82 },
957 { STB0899_CS1CFG , 0x82 },
958 { STB0899_DISEQCOCFG , 0x20 },
959 { STB0899_GPIO32CFG , 0x82 },
960 { STB0899_GPIO33CFG , 0x82 },
961 { STB0899_GPIO34CFG , 0x82 },
962 { STB0899_GPIO35CFG , 0x82 },
963 { STB0899_GPIO36CFG , 0x82 },
964 { STB0899_GPIO37CFG , 0x82 },
965 { STB0899_GPIO38CFG , 0x82 },
966 { STB0899_GPIO39CFG , 0x82 },
967 { STB0899_NCOARSE , 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
968 { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
969 { STB0899_FILTCTRL , 0x00 },
970 { STB0899_SYSCTRL , 0x00 },
971 { STB0899_STOPCLK1 , 0x20 },
972 { STB0899_STOPCLK2 , 0x00 },
973 { STB0899_INTBUFSTATUS , 0x00 },
974 { STB0899_INTBUFCTRL , 0x0a },
975 { 0xffff , 0xff },
976};
977
978static const struct stb0899_s2_reg knc1_stb0899_s2_init_2[] = {
979
980 { STB0899_OFF0_DMD_STATUS , STB0899_BASE_DMD_STATUS , 0x00000103 }, /* DMDSTATUS */
981 { STB0899_OFF0_CRL_FREQ , STB0899_BASE_CRL_FREQ , 0x3ed1da56 }, /* CRLFREQ */
982 { STB0899_OFF0_BTR_FREQ , STB0899_BASE_BTR_FREQ , 0x00004000 }, /* BTRFREQ */
983 { STB0899_OFF0_IF_AGC_GAIN , STB0899_BASE_IF_AGC_GAIN , 0x00002ade }, /* IFAGCGAIN */
984 { STB0899_OFF0_BB_AGC_GAIN , STB0899_BASE_BB_AGC_GAIN , 0x000001bc }, /* BBAGCGAIN */
985 { STB0899_OFF0_DC_OFFSET , STB0899_BASE_DC_OFFSET , 0x00000200 }, /* DCOFFSET */
986 { STB0899_OFF0_DMD_CNTRL , STB0899_BASE_DMD_CNTRL , 0x0000000f }, /* DMDCNTRL */
987
988 { STB0899_OFF0_IF_AGC_CNTRL , STB0899_BASE_IF_AGC_CNTRL , 0x03fb4a20 }, /* IFAGCCNTRL */
989 { STB0899_OFF0_BB_AGC_CNTRL , STB0899_BASE_BB_AGC_CNTRL , 0x00200c97 }, /* BBAGCCNTRL */
990
991 { STB0899_OFF0_CRL_CNTRL , STB0899_BASE_CRL_CNTRL , 0x00000016 }, /* CRLCNTRL */
992 { STB0899_OFF0_CRL_PHS_INIT , STB0899_BASE_CRL_PHS_INIT , 0x00000000 }, /* CRLPHSINIT */
993 { STB0899_OFF0_CRL_FREQ_INIT , STB0899_BASE_CRL_FREQ_INIT , 0x00000000 }, /* CRLFREQINIT */
994 { STB0899_OFF0_CRL_LOOP_GAIN , STB0899_BASE_CRL_LOOP_GAIN , 0x00000000 }, /* CRLLOOPGAIN */
995 { STB0899_OFF0_CRL_NOM_FREQ , STB0899_BASE_CRL_NOM_FREQ , 0x3ed097b6 }, /* CRLNOMFREQ */
996 { STB0899_OFF0_CRL_SWP_RATE , STB0899_BASE_CRL_SWP_RATE , 0x00000000 }, /* CRLSWPRATE */
997 { STB0899_OFF0_CRL_MAX_SWP , STB0899_BASE_CRL_MAX_SWP , 0x00000000 }, /* CRLMAXSWP */
998 { STB0899_OFF0_CRL_LK_CNTRL , STB0899_BASE_CRL_LK_CNTRL , 0x0f6cdc01 }, /* CRLLKCNTRL */
999 { STB0899_OFF0_DECIM_CNTRL , STB0899_BASE_DECIM_CNTRL , 0x00000000 }, /* DECIMCNTRL */
1000 { STB0899_OFF0_BTR_CNTRL , STB0899_BASE_BTR_CNTRL , 0x00003993 }, /* BTRCNTRL */
1001 { STB0899_OFF0_BTR_LOOP_GAIN , STB0899_BASE_BTR_LOOP_GAIN , 0x000d3c6f }, /* BTRLOOPGAIN */
1002 { STB0899_OFF0_BTR_PHS_INIT , STB0899_BASE_BTR_PHS_INIT , 0x00000000 }, /* BTRPHSINIT */
1003 { STB0899_OFF0_BTR_FREQ_INIT , STB0899_BASE_BTR_FREQ_INIT , 0x00000000 }, /* BTRFREQINIT */
1004 { STB0899_OFF0_BTR_NOM_FREQ , STB0899_BASE_BTR_NOM_FREQ , 0x0238e38e }, /* BTRNOMFREQ */
1005 { STB0899_OFF0_BTR_LK_CNTRL , STB0899_BASE_BTR_LK_CNTRL , 0x00000000 }, /* BTRLKCNTRL */
1006 { STB0899_OFF0_DECN_CNTRL , STB0899_BASE_DECN_CNTRL , 0x00000000 }, /* DECNCNTRL */
1007 { STB0899_OFF0_TP_CNTRL , STB0899_BASE_TP_CNTRL , 0x00000000 }, /* TPCNTRL */
1008 { STB0899_OFF0_TP_BUF_STATUS , STB0899_BASE_TP_BUF_STATUS , 0x00000000 }, /* TPBUFSTATUS */
1009 { STB0899_OFF0_DC_ESTIM , STB0899_BASE_DC_ESTIM , 0x00000000 }, /* DCESTIM */
1010 { STB0899_OFF0_FLL_CNTRL , STB0899_BASE_FLL_CNTRL , 0x00000000 }, /* FLLCNTRL */
1011 { STB0899_OFF0_FLL_FREQ_WD , STB0899_BASE_FLL_FREQ_WD , 0x40070000 }, /* FLLFREQWD */
1012 { STB0899_OFF0_ANTI_ALIAS_SEL , STB0899_BASE_ANTI_ALIAS_SEL , 0x00000001 }, /* ANTIALIASSEL */
1013 { STB0899_OFF0_RRC_ALPHA , STB0899_BASE_RRC_ALPHA , 0x00000002 }, /* RRCALPHA */
1014 { STB0899_OFF0_DC_ADAPT_LSHFT , STB0899_BASE_DC_ADAPT_LSHFT , 0x00000000 }, /* DCADAPTISHFT */
1015 { STB0899_OFF0_IMB_OFFSET , STB0899_BASE_IMB_OFFSET , 0x0000fe01 }, /* IMBOFFSET */
1016 { STB0899_OFF0_IMB_ESTIMATE , STB0899_BASE_IMB_ESTIMATE , 0x00000000 }, /* IMBESTIMATE */
1017 { STB0899_OFF0_IMB_CNTRL , STB0899_BASE_IMB_CNTRL , 0x00000001 }, /* IMBCNTRL */
1018 { STB0899_OFF0_IF_AGC_CNTRL2 , STB0899_BASE_IF_AGC_CNTRL2 , 0x00005007 }, /* IFAGCCNTRL2 */
1019 { STB0899_OFF0_DMD_CNTRL2 , STB0899_BASE_DMD_CNTRL2 , 0x00000002 }, /* DMDCNTRL2 */
1020 { STB0899_OFF0_TP_BUFFER , STB0899_BASE_TP_BUFFER , 0x00000000 }, /* TPBUFFER */
1021 { STB0899_OFF0_TP_BUFFER1 , STB0899_BASE_TP_BUFFER1 , 0x00000000 }, /* TPBUFFER1 */
1022 { STB0899_OFF0_TP_BUFFER2 , STB0899_BASE_TP_BUFFER2 , 0x00000000 }, /* TPBUFFER2 */
1023 { STB0899_OFF0_TP_BUFFER3 , STB0899_BASE_TP_BUFFER3 , 0x00000000 }, /* TPBUFFER3 */
1024 { STB0899_OFF0_TP_BUFFER4 , STB0899_BASE_TP_BUFFER4 , 0x00000000 }, /* TPBUFFER4 */
1025 { STB0899_OFF0_TP_BUFFER5 , STB0899_BASE_TP_BUFFER5 , 0x00000000 }, /* TPBUFFER5 */
1026 { STB0899_OFF0_TP_BUFFER6 , STB0899_BASE_TP_BUFFER6 , 0x00000000 }, /* TPBUFFER6 */
1027 { STB0899_OFF0_TP_BUFFER7 , STB0899_BASE_TP_BUFFER7 , 0x00000000 }, /* TPBUFFER7 */
1028 { STB0899_OFF0_TP_BUFFER8 , STB0899_BASE_TP_BUFFER8 , 0x00000000 }, /* TPBUFFER8 */
1029 { STB0899_OFF0_TP_BUFFER9 , STB0899_BASE_TP_BUFFER9 , 0x00000000 }, /* TPBUFFER9 */
1030 { STB0899_OFF0_TP_BUFFER10 , STB0899_BASE_TP_BUFFER10 , 0x00000000 }, /* TPBUFFER10 */
1031 { STB0899_OFF0_TP_BUFFER11 , STB0899_BASE_TP_BUFFER11 , 0x00000000 }, /* TPBUFFER11 */
1032 { STB0899_OFF0_TP_BUFFER12 , STB0899_BASE_TP_BUFFER12 , 0x00000000 }, /* TPBUFFER12 */
1033 { STB0899_OFF0_TP_BUFFER13 , STB0899_BASE_TP_BUFFER13 , 0x00000000 }, /* TPBUFFER13 */
1034 { STB0899_OFF0_TP_BUFFER14 , STB0899_BASE_TP_BUFFER14 , 0x00000000 }, /* TPBUFFER14 */
1035 { STB0899_OFF0_TP_BUFFER15 , STB0899_BASE_TP_BUFFER15 , 0x00000000 }, /* TPBUFFER15 */
1036 { STB0899_OFF0_TP_BUFFER16 , STB0899_BASE_TP_BUFFER16 , 0x0000ff00 }, /* TPBUFFER16 */
1037 { STB0899_OFF0_TP_BUFFER17 , STB0899_BASE_TP_BUFFER17 , 0x00000100 }, /* TPBUFFER17 */
1038 { STB0899_OFF0_TP_BUFFER18 , STB0899_BASE_TP_BUFFER18 , 0x0000fe01 }, /* TPBUFFER18 */
1039 { STB0899_OFF0_TP_BUFFER19 , STB0899_BASE_TP_BUFFER19 , 0x000004fe }, /* TPBUFFER19 */
1040 { STB0899_OFF0_TP_BUFFER20 , STB0899_BASE_TP_BUFFER20 , 0x0000cfe7 }, /* TPBUFFER20 */
1041 { STB0899_OFF0_TP_BUFFER21 , STB0899_BASE_TP_BUFFER21 , 0x0000bec6 }, /* TPBUFFER21 */
1042 { STB0899_OFF0_TP_BUFFER22 , STB0899_BASE_TP_BUFFER22 , 0x0000c2bf }, /* TPBUFFER22 */
1043 { STB0899_OFF0_TP_BUFFER23 , STB0899_BASE_TP_BUFFER23 , 0x0000c1c1 }, /* TPBUFFER23 */
1044 { STB0899_OFF0_TP_BUFFER24 , STB0899_BASE_TP_BUFFER24 , 0x0000c1c1 }, /* TPBUFFER24 */
1045 { STB0899_OFF0_TP_BUFFER25 , STB0899_BASE_TP_BUFFER25 , 0x0000c1c1 }, /* TPBUFFER25 */
1046 { STB0899_OFF0_TP_BUFFER26 , STB0899_BASE_TP_BUFFER26 , 0x0000c1c1 }, /* TPBUFFER26 */
1047 { STB0899_OFF0_TP_BUFFER27 , STB0899_BASE_TP_BUFFER27 , 0x0000c1c0 }, /* TPBUFFER27 */
1048 { STB0899_OFF0_TP_BUFFER28 , STB0899_BASE_TP_BUFFER28 , 0x0000c0c0 }, /* TPBUFFER28 */
1049 { STB0899_OFF0_TP_BUFFER29 , STB0899_BASE_TP_BUFFER29 , 0x0000c1c1 }, /* TPBUFFER29 */
1050 { STB0899_OFF0_TP_BUFFER30 , STB0899_BASE_TP_BUFFER30 , 0x0000c1c1 }, /* TPBUFFER30 */
1051 { STB0899_OFF0_TP_BUFFER31 , STB0899_BASE_TP_BUFFER31 , 0x0000c0c1 }, /* TPBUFFER31 */
1052 { STB0899_OFF0_TP_BUFFER32 , STB0899_BASE_TP_BUFFER32 , 0x0000c0c1 }, /* TPBUFFER32 */
1053 { STB0899_OFF0_TP_BUFFER33 , STB0899_BASE_TP_BUFFER33 , 0x0000c1c1 }, /* TPBUFFER33 */
1054 { STB0899_OFF0_TP_BUFFER34 , STB0899_BASE_TP_BUFFER34 , 0x0000c1c1 }, /* TPBUFFER34 */
1055 { STB0899_OFF0_TP_BUFFER35 , STB0899_BASE_TP_BUFFER35 , 0x0000c0c1 }, /* TPBUFFER35 */
1056 { STB0899_OFF0_TP_BUFFER36 , STB0899_BASE_TP_BUFFER36 , 0x0000c1c1 }, /* TPBUFFER36 */
1057 { STB0899_OFF0_TP_BUFFER37 , STB0899_BASE_TP_BUFFER37 , 0x0000c0c1 }, /* TPBUFFER37 */
1058 { STB0899_OFF0_TP_BUFFER38 , STB0899_BASE_TP_BUFFER38 , 0x0000c1c1 }, /* TPBUFFER38 */
1059 { STB0899_OFF0_TP_BUFFER39 , STB0899_BASE_TP_BUFFER39 , 0x0000c0c0 }, /* TPBUFFER39 */
1060 { STB0899_OFF0_TP_BUFFER40 , STB0899_BASE_TP_BUFFER40 , 0x0000c1c0 }, /* TPBUFFER40 */
1061 { STB0899_OFF0_TP_BUFFER41 , STB0899_BASE_TP_BUFFER41 , 0x0000c1c1 }, /* TPBUFFER41 */
1062 { STB0899_OFF0_TP_BUFFER42 , STB0899_BASE_TP_BUFFER42 , 0x0000c0c0 }, /* TPBUFFER42 */
1063 { STB0899_OFF0_TP_BUFFER43 , STB0899_BASE_TP_BUFFER43 , 0x0000c1c0 }, /* TPBUFFER43 */
1064 { STB0899_OFF0_TP_BUFFER44 , STB0899_BASE_TP_BUFFER44 , 0x0000c0c1 }, /* TPBUFFER44 */
1065 { STB0899_OFF0_TP_BUFFER45 , STB0899_BASE_TP_BUFFER45 , 0x0000c1be }, /* TPBUFFER45 */
1066 { STB0899_OFF0_TP_BUFFER46 , STB0899_BASE_TP_BUFFER46 , 0x0000c1c9 }, /* TPBUFFER46 */
1067 { STB0899_OFF0_TP_BUFFER47 , STB0899_BASE_TP_BUFFER47 , 0x0000c0da }, /* TPBUFFER47 */
1068 { STB0899_OFF0_TP_BUFFER48 , STB0899_BASE_TP_BUFFER48 , 0x0000c0ba }, /* TPBUFFER48 */
1069 { STB0899_OFF0_TP_BUFFER49 , STB0899_BASE_TP_BUFFER49 , 0x0000c1c4 }, /* TPBUFFER49 */
1070 { STB0899_OFF0_TP_BUFFER50 , STB0899_BASE_TP_BUFFER50 , 0x0000c1bf }, /* TPBUFFER50 */
1071 { STB0899_OFF0_TP_BUFFER51 , STB0899_BASE_TP_BUFFER51 , 0x0000c0c1 }, /* TPBUFFER51 */
1072 { STB0899_OFF0_TP_BUFFER52 , STB0899_BASE_TP_BUFFER52 , 0x0000c1c0 }, /* TPBUFFER52 */
1073 { STB0899_OFF0_TP_BUFFER53 , STB0899_BASE_TP_BUFFER53 , 0x0000c0c1 }, /* TPBUFFER53 */
1074 { STB0899_OFF0_TP_BUFFER54 , STB0899_BASE_TP_BUFFER54 , 0x0000c1c1 }, /* TPBUFFER54 */
1075 { STB0899_OFF0_TP_BUFFER55 , STB0899_BASE_TP_BUFFER55 , 0x0000c1c1 }, /* TPBUFFER55 */
1076 { STB0899_OFF0_TP_BUFFER56 , STB0899_BASE_TP_BUFFER56 , 0x0000c1c1 }, /* TPBUFFER56 */
1077 { STB0899_OFF0_TP_BUFFER57 , STB0899_BASE_TP_BUFFER57 , 0x0000c1c1 }, /* TPBUFFER57 */
1078 { STB0899_OFF0_TP_BUFFER58 , STB0899_BASE_TP_BUFFER58 , 0x0000c1c1 }, /* TPBUFFER58 */
1079 { STB0899_OFF0_TP_BUFFER59 , STB0899_BASE_TP_BUFFER59 , 0x0000c1c1 }, /* TPBUFFER59 */
1080 { STB0899_OFF0_TP_BUFFER60 , STB0899_BASE_TP_BUFFER60 , 0x0000c1c1 }, /* TPBUFFER60 */
1081 { STB0899_OFF0_TP_BUFFER61 , STB0899_BASE_TP_BUFFER61 , 0x0000c1c1 }, /* TPBUFFER61 */
1082 { STB0899_OFF0_TP_BUFFER62 , STB0899_BASE_TP_BUFFER62 , 0x0000c1c1 }, /* TPBUFFER62 */
1083 { STB0899_OFF0_TP_BUFFER63 , STB0899_BASE_TP_BUFFER63 , 0x0000c1c0 }, /* TPBUFFER63 */
1084 { STB0899_OFF0_RESET_CNTRL , STB0899_BASE_RESET_CNTRL , 0x00000001 }, /* RESETCNTRL */
1085 { STB0899_OFF0_ACM_ENABLE , STB0899_BASE_ACM_ENABLE , 0x00005654 }, /* ACMENABLE */
1086 { STB0899_OFF0_DESCR_CNTRL , STB0899_BASE_DESCR_CNTRL , 0x00000000 }, /* DESCRCNTRL */
1087 { STB0899_OFF0_CSM_CNTRL1 , STB0899_BASE_CSM_CNTRL1 , 0x00020019 }, /* CSMCNTRL1 */
1088 { STB0899_OFF0_CSM_CNTRL2 , STB0899_BASE_CSM_CNTRL2 , 0x004b3237 }, /* CSMCNTRL2 */
1089 { STB0899_OFF0_CSM_CNTRL3 , STB0899_BASE_CSM_CNTRL3 , 0x0003dd17 }, /* CSMCNTRL3 */
1090 { STB0899_OFF0_CSM_CNTRL4 , STB0899_BASE_CSM_CNTRL4 , 0x00008008 }, /* CSMCNTRL4 */
1091 { STB0899_OFF0_UWP_CNTRL1 , STB0899_BASE_UWP_CNTRL1 , 0x002a3106 }, /* UWPCNTRL1 */
1092 { STB0899_OFF0_UWP_CNTRL2 , STB0899_BASE_UWP_CNTRL2 , 0x0006140a }, /* UWPCNTRL2 */
1093 { STB0899_OFF0_UWP_STAT1 , STB0899_BASE_UWP_STAT1 , 0x00008000 }, /* UWPSTAT1 */
1094 { STB0899_OFF0_UWP_STAT2 , STB0899_BASE_UWP_STAT2 , 0x00000000 }, /* UWPSTAT2 */
1095 { STB0899_OFF0_DMD_STAT2 , STB0899_BASE_DMD_STAT2 , 0x00000000 }, /* DMDSTAT2 */
1096 { STB0899_OFF0_FREQ_ADJ_SCALE , STB0899_BASE_FREQ_ADJ_SCALE , 0x00000471 }, /* FREQADJSCALE */
1097 { STB0899_OFF0_UWP_CNTRL3 , STB0899_BASE_UWP_CNTRL3 , 0x017b0465 }, /* UWPCNTRL3 */
1098 { STB0899_OFF0_SYM_CLK_SEL , STB0899_BASE_SYM_CLK_SEL , 0x00000002 }, /* SYMCLKSEL */
1099 { STB0899_OFF0_SOF_SRCH_TO , STB0899_BASE_SOF_SRCH_TO , 0x00196464 }, /* SOFSRCHTO */
1100 { STB0899_OFF0_ACQ_CNTRL1 , STB0899_BASE_ACQ_CNTRL1 , 0x00000603 }, /* ACQCNTRL1 */
1101 { STB0899_OFF0_ACQ_CNTRL2 , STB0899_BASE_ACQ_CNTRL2 , 0x02046666 }, /* ACQCNTRL2 */
1102 { STB0899_OFF0_ACQ_CNTRL3 , STB0899_BASE_ACQ_CNTRL3 , 0x10046583 }, /* ACQCNTRL3 */
1103 { STB0899_OFF0_FE_SETTLE , STB0899_BASE_FE_SETTLE , 0x00010404 }, /* FESETTLE */
1104 { STB0899_OFF0_AC_DWELL , STB0899_BASE_AC_DWELL , 0x0002aa8a }, /* ACDWELL */
1105 { STB0899_OFF0_ACQUIRE_TRIG , STB0899_BASE_ACQUIRE_TRIG , 0x00000000 }, /* ACQUIRETRIG */
1106 { STB0899_OFF0_LOCK_LOST , STB0899_BASE_LOCK_LOST , 0x00000001 }, /* LOCKLOST */
1107 { STB0899_OFF0_ACQ_STAT1 , STB0899_BASE_ACQ_STAT1 , 0x00000500 }, /* ACQSTAT1 */
1108 { STB0899_OFF0_ACQ_TIMEOUT , STB0899_BASE_ACQ_TIMEOUT , 0x0028a0a0 }, /* ACQTIMEOUT */
1109 { STB0899_OFF0_ACQ_TIME , STB0899_BASE_ACQ_TIME , 0x00000000 }, /* ACQTIME */
1110 { STB0899_OFF0_FINAL_AGC_CNTRL , STB0899_BASE_FINAL_AGC_CNTRL , 0x00800c17 }, /* FINALAGCCNTRL*/
1111 { STB0899_OFF0_FINAL_AGC_GAIN , STB0899_BASE_FINAL_AGC_GAIN , 0x00000000 }, /* FINALAGCCGAIN*/
1112 { STB0899_OFF0_EQUALIZER_INIT , STB0899_BASE_EQUALIZER_INIT , 0x00000000 }, /* EQUILIZERINIT*/
1113 { STB0899_OFF0_EQ_CNTRL , STB0899_BASE_EQ_CNTRL , 0x00054802 }, /* EQCNTL */
1114 { STB0899_OFF0_EQ_I_INIT_COEFF_0, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF0 */
1115 { STB0899_OFF1_EQ_I_INIT_COEFF_1, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF1 */
1116 { STB0899_OFF2_EQ_I_INIT_COEFF_2, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF2 */
1117 { STB0899_OFF3_EQ_I_INIT_COEFF_3, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF3 */
1118 { STB0899_OFF4_EQ_I_INIT_COEFF_4, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF4 */
1119 { STB0899_OFF5_EQ_I_INIT_COEFF_5, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000400 }, /* EQIINITCOEFF5 */
1120 { STB0899_OFF6_EQ_I_INIT_COEFF_6, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF6 */
1121 { STB0899_OFF7_EQ_I_INIT_COEFF_7, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF7 */
1122 { STB0899_OFF8_EQ_I_INIT_COEFF_8, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF8 */
1123 { STB0899_OFF9_EQ_I_INIT_COEFF_9, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF9 */
1124 { STB0899_OFFa_EQ_I_INIT_COEFF_10,STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF10*/
1125 { STB0899_OFF0_EQ_Q_INIT_COEFF_0, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF0 */
1126 { STB0899_OFF1_EQ_Q_INIT_COEFF_1, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF1 */
1127 { STB0899_OFF2_EQ_Q_INIT_COEFF_2, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF2 */
1128 { STB0899_OFF3_EQ_Q_INIT_COEFF_3, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF3 */
1129 { STB0899_OFF4_EQ_Q_INIT_COEFF_4, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF4 */
1130 { STB0899_OFF5_EQ_Q_INIT_COEFF_5, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF5 */
1131 { STB0899_OFF6_EQ_Q_INIT_COEFF_6, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF6 */
1132 { STB0899_OFF7_EQ_Q_INIT_COEFF_7, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF7 */
1133 { STB0899_OFF8_EQ_Q_INIT_COEFF_8, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF8 */
1134 { STB0899_OFF9_EQ_Q_INIT_COEFF_9, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF9 */
1135 { STB0899_OFFa_EQ_Q_INIT_COEFF_10,STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF10*/
1136 { STB0899_OFF0_EQ_I_OUT_COEFF_0 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT0 */
1137 { STB0899_OFF1_EQ_I_OUT_COEFF_1 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT1 */
1138 { STB0899_OFF2_EQ_I_OUT_COEFF_2 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT2 */
1139 { STB0899_OFF3_EQ_I_OUT_COEFF_3 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT3 */
1140 { STB0899_OFF4_EQ_I_OUT_COEFF_4 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT4 */
1141 { STB0899_OFF5_EQ_I_OUT_COEFF_5 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT5 */
1142 { STB0899_OFF6_EQ_I_OUT_COEFF_6 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT6 */
1143 { STB0899_OFF7_EQ_I_OUT_COEFF_7 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT7 */
1144 { STB0899_OFF8_EQ_I_OUT_COEFF_8 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT8 */
1145 { STB0899_OFF9_EQ_I_OUT_COEFF_9 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT9 */
1146 { STB0899_OFFa_EQ_I_OUT_COEFF_10,STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT10*/
1147 { STB0899_OFF0_EQ_Q_OUT_COEFF_0 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT0 */
1148 { STB0899_OFF1_EQ_Q_OUT_COEFF_1 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT1 */
1149 { STB0899_OFF2_EQ_Q_OUT_COEFF_2 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT2 */
1150 { STB0899_OFF3_EQ_Q_OUT_COEFF_3 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT3 */
1151 { STB0899_OFF4_EQ_Q_OUT_COEFF_4 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT4 */
1152 { STB0899_OFF5_EQ_Q_OUT_COEFF_5 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT5 */
1153 { STB0899_OFF6_EQ_Q_OUT_COEFF_6 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT6 */
1154 { STB0899_OFF7_EQ_Q_OUT_COEFF_7 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT7 */
1155 { STB0899_OFF8_EQ_Q_OUT_COEFF_8 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT8 */
1156 { STB0899_OFF9_EQ_Q_OUT_COEFF_9 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT9 */
1157 { STB0899_OFFa_EQ_Q_OUT_COEFF_10, STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT10*/
1158 { 0xffff , 0xffffffff , 0xffffffff },
1159};
1160
1161static const struct stb0899_s1_reg knc1_stb0899_s1_init_3[] = {
1162 { STB0899_DEMOD , 0x00 },
1163 { STB0899_RCOMPC , 0xc9 },
1164 { STB0899_AGC1CN , 0x41 },
1165 { STB0899_AGC1REF , 0x10 },
1166 { STB0899_RTC , 0x7a },
1167 { STB0899_TMGCFG , 0x4e },
1168 { STB0899_AGC2REF , 0x34 },
1169 { STB0899_TLSR , 0x84 },
1170 { STB0899_CFD , 0xee },
1171 { STB0899_ACLC , 0x87 },
1172 { STB0899_BCLC , 0x94 },
1173 { STB0899_EQON , 0x41 },
1174 { STB0899_LDT , 0xdd },
1175 { STB0899_LDT2 , 0xc9 },
1176 { STB0899_EQUALREF , 0xb4 },
1177 { STB0899_TMGRAMP , 0x10 },
1178 { STB0899_TMGTHD , 0x30 },
1179 { STB0899_IDCCOMP , 0xfb },
1180 { STB0899_QDCCOMP , 0x03 },
1181 { STB0899_POWERI , 0x3b },
1182 { STB0899_POWERQ , 0x3d },
1183 { STB0899_RCOMP , 0x81 },
1184 { STB0899_AGCIQIN , 0x80 },
1185 { STB0899_AGC2I1 , 0x04 },
1186 { STB0899_AGC2I2 , 0xf5 },
1187 { STB0899_TLIR , 0x25 },
1188 { STB0899_RTF , 0x80 },
1189 { STB0899_DSTATUS , 0x00 },
1190 { STB0899_LDI , 0xca },
1191 { STB0899_CFRM , 0xf1 },
1192 { STB0899_CFRL , 0xf3 },
1193 { STB0899_NIRM , 0x2a },
1194 { STB0899_NIRL , 0x05 },
1195 { STB0899_ISYMB , 0x17 },
1196 { STB0899_QSYMB , 0xfa },
1197 { STB0899_SFRH , 0x2f },
1198 { STB0899_SFRM , 0x68 },
1199 { STB0899_SFRL , 0x40 },
1200 { STB0899_SFRUPH , 0x2f },
1201 { STB0899_SFRUPM , 0x68 },
1202 { STB0899_SFRUPL , 0x40 },
1203 { STB0899_EQUAI1 , 0xfd },
1204 { STB0899_EQUAQ1 , 0x04 },
1205 { STB0899_EQUAI2 , 0x0f },
1206 { STB0899_EQUAQ2 , 0xff },
1207 { STB0899_EQUAI3 , 0xdf },
1208 { STB0899_EQUAQ3 , 0xfa },
1209 { STB0899_EQUAI4 , 0x37 },
1210 { STB0899_EQUAQ4 , 0x0d },
1211 { STB0899_EQUAI5 , 0xbd },
1212 { STB0899_EQUAQ5 , 0xf7 },
1213 { STB0899_DSTATUS2 , 0x00 },
1214 { STB0899_VSTATUS , 0x00 },
1215 { STB0899_VERROR , 0xff },
1216 { STB0899_IQSWAP , 0x2a },
1217 { STB0899_ECNT1M , 0x00 },
1218 { STB0899_ECNT1L , 0x00 },
1219 { STB0899_ECNT2M , 0x00 },
1220 { STB0899_ECNT2L , 0x00 },
1221 { STB0899_ECNT3M , 0x00 },
1222 { STB0899_ECNT3L , 0x00 },
1223 { STB0899_FECAUTO1 , 0x06 },
1224 { STB0899_FECM , 0x01 },
1225 { STB0899_VTH12 , 0xf0 },
1226 { STB0899_VTH23 , 0xa0 },
1227 { STB0899_VTH34 , 0x78 },
1228 { STB0899_VTH56 , 0x4e },
1229 { STB0899_VTH67 , 0x48 },
1230 { STB0899_VTH78 , 0x38 },
1231 { STB0899_PRVIT , 0xff },
1232 { STB0899_VITSYNC , 0x19 },
1233 { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
1234 { STB0899_TSULC , 0x42 },
1235 { STB0899_RSLLC , 0x40 },
1236 { STB0899_TSLPL , 0x12 },
1237 { STB0899_TSCFGH , 0x0c },
1238 { STB0899_TSCFGM , 0x00 },
1239 { STB0899_TSCFGL , 0x0c },
1240 { STB0899_TSOUT , 0x0d }, /* 0x0d for CAM */
1241 { STB0899_RSSYNCDEL , 0x00 },
1242 { STB0899_TSINHDELH , 0x02 },
1243 { STB0899_TSINHDELM , 0x00 },
1244 { STB0899_TSINHDELL , 0x00 },
1245 { STB0899_TSLLSTKM , 0x00 },
1246 { STB0899_TSLLSTKL , 0x00 },
1247 { STB0899_TSULSTKM , 0x00 },
1248 { STB0899_TSULSTKL , 0xab },
1249 { STB0899_PCKLENUL , 0x00 },
1250 { STB0899_PCKLENLL , 0xcc },
1251 { STB0899_RSPCKLEN , 0xcc },
1252 { STB0899_TSSTATUS , 0x80 },
1253 { STB0899_ERRCTRL1 , 0xb6 },
1254 { STB0899_ERRCTRL2 , 0x96 },
1255 { STB0899_ERRCTRL3 , 0x89 },
1256 { STB0899_DMONMSK1 , 0x27 },
1257 { STB0899_DMONMSK0 , 0x03 },
1258 { STB0899_DEMAPVIT , 0x5c },
1259 { STB0899_PLPARM , 0x1f },
1260 { STB0899_PDELCTRL , 0x48 },
1261 { STB0899_PDELCTRL2 , 0x00 },
1262 { STB0899_BBHCTRL1 , 0x00 },
1263 { STB0899_BBHCTRL2 , 0x00 },
1264 { STB0899_HYSTTHRESH , 0x77 },
1265 { STB0899_MATCSTM , 0x00 },
1266 { STB0899_MATCSTL , 0x00 },
1267 { STB0899_UPLCSTM , 0x00 },
1268 { STB0899_UPLCSTL , 0x00 },
1269 { STB0899_DFLCSTM , 0x00 },
1270 { STB0899_DFLCSTL , 0x00 },
1271 { STB0899_SYNCCST , 0x00 },
1272 { STB0899_SYNCDCSTM , 0x00 },
1273 { STB0899_SYNCDCSTL , 0x00 },
1274 { STB0899_ISI_ENTRY , 0x00 },
1275 { STB0899_ISI_BIT_EN , 0x00 },
1276 { STB0899_MATSTRM , 0x00 },
1277 { STB0899_MATSTRL , 0x00 },
1278 { STB0899_UPLSTRM , 0x00 },
1279 { STB0899_UPLSTRL , 0x00 },
1280 { STB0899_DFLSTRM , 0x00 },
1281 { STB0899_DFLSTRL , 0x00 },
1282 { STB0899_SYNCSTR , 0x00 },
1283 { STB0899_SYNCDSTRM , 0x00 },
1284 { STB0899_SYNCDSTRL , 0x00 },
1285 { STB0899_CFGPDELSTATUS1 , 0x10 },
1286 { STB0899_CFGPDELSTATUS2 , 0x00 },
1287 { STB0899_BBFERRORM , 0x00 },
1288 { STB0899_BBFERRORL , 0x00 },
1289 { STB0899_UPKTERRORM , 0x00 },
1290 { STB0899_UPKTERRORL , 0x00 },
1291 { 0xffff , 0xff },
1292};
1293
1294static const struct stb0899_s2_reg knc1_stb0899_s2_init_4[] = {
1295 { STB0899_OFF0_BLOCK_LNGTH , STB0899_BASE_BLOCK_LNGTH , 0x00000008 }, /* BLOCKLNGTH */
1296 { STB0899_OFF0_ROW_STR , STB0899_BASE_ROW_STR , 0x000000b4 }, /* ROWSTR */
1297 { STB0899_OFF0_BN_END_ADDR , STB0899_BASE_BN_END_ADDR , 0x000004b5 }, /* BNANDADDR */
1298 { STB0899_OFF0_CN_END_ADDR , STB0899_BASE_CN_END_ADDR , 0x00000b4b }, /* CNANDADDR */
1299 { STB0899_OFF0_INFO_LENGTH , STB0899_BASE_INFO_LENGTH , 0x00000078 }, /* INFOLENGTH */
1300 { STB0899_OFF0_BOT_ADDR , STB0899_BASE_BOT_ADDR , 0x000001e0 }, /* BOT_ADDR */
1301 { STB0899_OFF0_BCH_BLK_LN , STB0899_BASE_BCH_BLK_LN , 0x0000a8c0 }, /* BCHBLKLN */
1302 { STB0899_OFF0_BCH_T , STB0899_BASE_BCH_T , 0x0000000c }, /* BCHT */
1303 { STB0899_OFF0_CNFG_MODE , STB0899_BASE_CNFG_MODE , 0x00000001 }, /* CNFGMODE */
1304 { STB0899_OFF0_LDPC_STAT , STB0899_BASE_LDPC_STAT , 0x0000000d }, /* LDPCSTAT */
1305 { STB0899_OFF0_ITER_SCALE , STB0899_BASE_ITER_SCALE , 0x00000040 }, /* ITERSCALE */
1306 { STB0899_OFF0_INPUT_MODE , STB0899_BASE_INPUT_MODE , 0x00000000 }, /* INPUTMODE */
1307 { STB0899_OFF0_LDPCDECRST , STB0899_BASE_LDPCDECRST , 0x00000000 }, /* LDPCDECRST */
1308 { STB0899_OFF0_CLK_PER_BYTE_RW , STB0899_BASE_CLK_PER_BYTE_RW , 0x00000008 }, /* CLKPERBYTE */
1309 { STB0899_OFF0_BCH_ERRORS , STB0899_BASE_BCH_ERRORS , 0x00000000 }, /* BCHERRORS */
1310 { STB0899_OFF0_LDPC_ERRORS , STB0899_BASE_LDPC_ERRORS , 0x00000000 }, /* LDPCERRORS */
1311 { STB0899_OFF0_BCH_MODE , STB0899_BASE_BCH_MODE , 0x00000000 }, /* BCHMODE */
1312 { STB0899_OFF0_ERR_ACC_PER , STB0899_BASE_ERR_ACC_PER , 0x00000008 }, /* ERRACCPER */
1313 { STB0899_OFF0_BCH_ERR_ACC , STB0899_BASE_BCH_ERR_ACC , 0x00000000 }, /* BCHERRACC */
1314 { STB0899_OFF0_FEC_TP_SEL , STB0899_BASE_FEC_TP_SEL , 0x00000000 }, /* FECTPSEL */
1315 { 0xffff , 0xffffffff , 0xffffffff },
1316};
1317
1318static const struct stb0899_s1_reg knc1_stb0899_s1_init_5[] = {
1319 { STB0899_TSTCK , 0x00 },
1320 { STB0899_TSTRES , 0x00 },
1321 { STB0899_TSTOUT , 0x00 },
1322 { STB0899_TSTIN , 0x00 },
1323 { STB0899_TSTSYS , 0x00 },
1324 { STB0899_TSTCHIP , 0x00 },
1325 { STB0899_TSTFREE , 0x00 },
1326 { STB0899_TSTI2C , 0x00 },
1327 { STB0899_BITSPEEDM , 0x00 },
1328 { STB0899_BITSPEEDL , 0x00 },
1329 { STB0899_TBUSBIT , 0x00 },
1330 { STB0899_TSTDIS , 0x00 },
1331 { STB0899_TSTDISRX , 0x00 },
1332 { STB0899_TSTJETON , 0x00 },
1333 { STB0899_TSTDCADJ , 0x00 },
1334 { STB0899_TSTAGC1 , 0x00 },
1335 { STB0899_TSTAGC1N , 0x00 },
1336 { STB0899_TSTPOLYPH , 0x00 },
1337 { STB0899_TSTR , 0x00 },
1338 { STB0899_TSTAGC2 , 0x00 },
1339 { STB0899_TSTCTL1 , 0x00 },
1340 { STB0899_TSTCTL2 , 0x00 },
1341 { STB0899_TSTCTL3 , 0x00 },
1342 { STB0899_TSTDEMAP , 0x00 },
1343 { STB0899_TSTDEMAP2 , 0x00 },
1344 { STB0899_TSTDEMMON , 0x00 },
1345 { STB0899_TSTRATE , 0x00 },
1346 { STB0899_TSTSELOUT , 0x00 },
1347 { STB0899_TSYNC , 0x00 },
1348 { STB0899_TSTERR , 0x00 },
1349 { STB0899_TSTRAM1 , 0x00 },
1350 { STB0899_TSTVSELOUT , 0x00 },
1351 { STB0899_TSTFORCEIN , 0x00 },
1352 { STB0899_TSTRS1 , 0x00 },
1353 { STB0899_TSTRS2 , 0x00 },
1354 { STB0899_TSTRS3 , 0x00 },
1355 { STB0899_GHOSTREG , 0x81 },
1356 { 0xffff , 0xff },
1357};
1358
1359#define KNC1_DVBS2_ESNO_AVE 3
1360#define KNC1_DVBS2_ESNO_QUANT 32
1361#define KNC1_DVBS2_AVFRAMES_COARSE 10
1362#define KNC1_DVBS2_AVFRAMES_FINE 20
1363#define KNC1_DVBS2_MISS_THRESHOLD 6
1364#define KNC1_DVBS2_UWP_THRESHOLD_ACQ 1125
1365#define KNC1_DVBS2_UWP_THRESHOLD_TRACK 758
1366#define KNC1_DVBS2_UWP_THRESHOLD_SOF 1350
1367#define KNC1_DVBS2_SOF_SEARCH_TIMEOUT 1664100
1368
1369#define KNC1_DVBS2_BTR_NCO_BITS 28
1370#define KNC1_DVBS2_BTR_GAIN_SHIFT_OFFSET 15
1371#define KNC1_DVBS2_CRL_NCO_BITS 30
1372#define KNC1_DVBS2_LDPC_MAX_ITER 70
1373
1374static int tda8261_get_frequency(struct dvb_frontend *fe, u32 *frequency)
1375{
1376 struct dvb_frontend_ops *frontend_ops = NULL;
1377 struct dvb_tuner_ops *tuner_ops = NULL;
1378 struct tuner_state t_state;
1379 int err = 0;
1380
1381 if (&fe->ops)
1382 frontend_ops = &fe->ops;
1383 if (&frontend_ops->tuner_ops)
1384 tuner_ops = &frontend_ops->tuner_ops;
1385 if (tuner_ops->get_state) {
1386 if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
1387 printk("%s: Invalid parameter\n", __func__);
1388 return err;
1389 }
1390 *frequency = t_state.frequency;
1391 printk("%s: Frequency=%d\n", __func__, t_state.frequency);
1392 }
1393 return 0;
1394}
1395
1396static int tda8261_set_frequency(struct dvb_frontend *fe, u32 frequency)
1397{
1398 struct dvb_frontend_ops *frontend_ops = NULL;
1399 struct dvb_tuner_ops *tuner_ops = NULL;
1400 struct tuner_state t_state;
1401 int err = 0;
1402
1403 t_state.frequency = frequency;
1404 if (&fe->ops)
1405 frontend_ops = &fe->ops;
1406 if (&frontend_ops->tuner_ops)
1407 tuner_ops = &frontend_ops->tuner_ops;
1408 if (tuner_ops->set_state) {
1409 if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
1410 printk("%s: Invalid parameter\n", __func__);
1411 return err;
1412 }
1413 }
1414 printk("%s: Frequency=%d\n", __func__, t_state.frequency);
1415 return 0;
1416}
1417
1418static int tda8261_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
1419{
1420 struct dvb_frontend_ops *frontend_ops = &fe->ops;
1421 struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
1422 struct tuner_state t_state;
1423 int err = 0;
1424
1425 if (&fe->ops)
1426 frontend_ops = &fe->ops;
1427 if (&frontend_ops->tuner_ops)
1428 tuner_ops = &frontend_ops->tuner_ops;
1429 if (tuner_ops->get_state) {
1430 if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state)) < 0) {
1431 printk("%s: Invalid parameter\n", __func__);
1432 return err;
1433 }
1434 *bandwidth = t_state.bandwidth;
1435 }
1436 printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth);
1437 return 0;
1438}
1439
1440/* STB0899 demodulator config for the KNC1 and clones */
1441static struct stb0899_config knc1_dvbs2_config = {
1442 .init_dev = knc1_stb0899_s1_init_1,
1443 .init_s2_demod = knc1_stb0899_s2_init_2,
1444 .init_s1_demod = knc1_stb0899_s1_init_3,
1445 .init_s2_fec = knc1_stb0899_s2_init_4,
1446 .init_tst = knc1_stb0899_s1_init_5,
1447
1448 .demod_address = 0x68,
1449// .ts_output_mode = STB0899_OUT_PARALLEL, /* types = SERIAL/PARALLEL */
1450 .block_sync_mode = STB0899_SYNC_FORCED, /* DSS, SYNC_FORCED/UNSYNCED */
1451// .ts_pfbit_toggle = STB0899_MPEG_NORMAL, /* DirecTV, MPEG toggling seq */
1452
1453 .xtal_freq = 27000000,
Manu Abraham7dd82f72007-09-25 14:57:19 -03001454 .inversion = IQ_SWAP_OFF, /* 1 */
Manu Abraham41e11512007-09-22 21:28:11 -03001455
1456 .esno_ave = KNC1_DVBS2_ESNO_AVE,
1457 .esno_quant = KNC1_DVBS2_ESNO_QUANT,
1458 .avframes_coarse = KNC1_DVBS2_AVFRAMES_COARSE,
1459 .avframes_fine = KNC1_DVBS2_AVFRAMES_FINE,
1460 .miss_threshold = KNC1_DVBS2_MISS_THRESHOLD,
1461 .uwp_threshold_acq = KNC1_DVBS2_UWP_THRESHOLD_ACQ,
1462 .uwp_threshold_track = KNC1_DVBS2_UWP_THRESHOLD_TRACK,
1463 .uwp_threshold_sof = KNC1_DVBS2_UWP_THRESHOLD_SOF,
1464 .sof_search_timeout = KNC1_DVBS2_SOF_SEARCH_TIMEOUT,
1465
1466 .btr_nco_bits = KNC1_DVBS2_BTR_NCO_BITS,
1467 .btr_gain_shift_offset = KNC1_DVBS2_BTR_GAIN_SHIFT_OFFSET,
1468 .crl_nco_bits = KNC1_DVBS2_CRL_NCO_BITS,
1469 .ldpc_max_iter = KNC1_DVBS2_LDPC_MAX_ITER,
1470
1471 .tuner_get_frequency = tda8261_get_frequency,
1472 .tuner_set_frequency = tda8261_set_frequency,
1473 .tuner_set_bandwidth = NULL,
1474 .tuner_get_bandwidth = tda8261_get_bandwidth,
1475 .tuner_set_rfsiggain = NULL,
1476};
1477
1478/* SD1878 tuner config */
1479static const struct tda8261_config sd1878c_config = {
1480// .name = "SD1878C",
1481 .addr = 0x60,
1482 .step_size = TDA8261_STEP_1000 /* kHz */
1483};
1484
Linus Torvalds1da177e2005-04-16 15:20:36 -07001485static u8 read_pwm(struct budget_av *budget_av)
1486{
1487 u8 b = 0xff;
1488 u8 pwm;
1489 struct i2c_msg msg[] = { {.addr = 0x50,.flags = 0,.buf = &b,.len = 1},
1490 {.addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1}
1491 };
1492
1493 if ((i2c_transfer(&budget_av->budget.i2c_adap, msg, 2) != 2)
1494 || (pwm == 0xff))
1495 pwm = 0x48;
1496
1497 return pwm;
1498}
1499
Hartmut Birraa323ac2007-04-21 19:37:17 -03001500#define SUBID_DVBS_KNC1 0x0010
1501#define SUBID_DVBS_KNC1_PLUS 0x0011
1502#define SUBID_DVBS_TYPHOON 0x4f56
1503#define SUBID_DVBS_CINERGY1200 0x1154
1504#define SUBID_DVBS_CYNERGY1200N 0x1155
1505#define SUBID_DVBS_TV_STAR 0x0014
Oliver Endriss03aa73c2008-01-29 23:56:51 -03001506#define SUBID_DVBS_TV_STAR_PLUS_X4 0x0015
Hartmut Birraa323ac2007-04-21 19:37:17 -03001507#define SUBID_DVBS_TV_STAR_CI 0x0016
Manu Abraham41e11512007-09-22 21:28:11 -03001508#define SUBID_DVBS2_KNC1 0x0018
1509#define SUBID_DVBS2_KNC1_OEM 0x0019
Hartmut Birraa323ac2007-04-21 19:37:17 -03001510#define SUBID_DVBS_EASYWATCH_1 0x001a
Oliver Endrissf72ce642007-05-13 23:25:57 -03001511#define SUBID_DVBS_EASYWATCH_2 0x001b
Hartmut Birraa323ac2007-04-21 19:37:17 -03001512#define SUBID_DVBS_EASYWATCH 0x001e
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001513
Hartmut Birraa323ac2007-04-21 19:37:17 -03001514#define SUBID_DVBC_EASYWATCH 0x002a
1515#define SUBID_DVBC_EASYWATCH_MK3 0x002c
1516#define SUBID_DVBC_KNC1 0x0020
1517#define SUBID_DVBC_KNC1_PLUS 0x0021
1518#define SUBID_DVBC_KNC1_MK3 0x0022
1519#define SUBID_DVBC_KNC1_PLUS_MK3 0x0023
1520#define SUBID_DVBC_CINERGY1200 0x1156
1521#define SUBID_DVBC_CINERGY1200_MK3 0x1176
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001522
Kim Sandberg251130b2008-01-30 00:42:01 -03001523#define SUBID_DVBT_EASYWATCH 0x003a
Hartmut Birraa323ac2007-04-21 19:37:17 -03001524#define SUBID_DVBT_KNC1_PLUS 0x0031
1525#define SUBID_DVBT_KNC1 0x0030
1526#define SUBID_DVBT_CINERGY1200 0x1157
Linus Torvalds1da177e2005-04-16 15:20:36 -07001527
1528static void frontend_init(struct budget_av *budget_av)
1529{
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001530 struct saa7146_dev * saa = budget_av->budget.dev;
1531 struct dvb_frontend * fe = NULL;
1532
Andrew de Quincey473f5422006-04-13 17:29:07 -03001533 /* Enable / PowerON Frontend */
1534 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
1535
Hartmut Birr740cf9e2006-11-03 15:34:18 -03001536 /* Wait for PowerON */
1537 msleep(100);
1538
Andrew de Quincey473f5422006-04-13 17:29:07 -03001539 /* additional setup necessary for the PLUS cards */
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001540 switch (saa->pci->subsystem_device) {
1541 case SUBID_DVBS_KNC1_PLUS:
1542 case SUBID_DVBC_KNC1_PLUS:
1543 case SUBID_DVBT_KNC1_PLUS:
Thomas Hammc01d1e42006-11-17 07:12:58 -03001544 case SUBID_DVBC_EASYWATCH:
Hartmut Birraa323ac2007-04-21 19:37:17 -03001545 case SUBID_DVBC_KNC1_PLUS_MK3:
Manu Abraham41e11512007-09-22 21:28:11 -03001546 case SUBID_DVBS2_KNC1:
1547 case SUBID_DVBS2_KNC1_OEM:
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001548 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001549 break;
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001550 }
1551
1552 switch (saa->pci->subsystem_device) {
1553
1554 case SUBID_DVBS_KNC1:
Christoph Pfisterc4e3bcb2008-04-09 17:37:36 -03001555 /*
1556 * maybe that setting is needed for other dvb-s cards as well,
1557 * but so far it has been only confirmed for this type
1558 */
1559 budget_av->reinitialise_demod = 1;
1560 /* fall through */
Christoph Pfister4e318be2006-08-12 09:13:35 -03001561 case SUBID_DVBS_KNC1_PLUS:
Lothar Englisch60110ce2006-06-06 16:13:46 -03001562 case SUBID_DVBS_EASYWATCH_1:
Andrew de Quinceyeffa7912006-01-09 15:25:09 -02001563 if (saa->pci->subsystem_vendor == 0x1894) {
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001564 fe = dvb_attach(stv0299_attach, &cinergy_1200s_1894_0010_config,
Andrew de Quinceyeffa7912006-01-09 15:25:09 -02001565 &budget_av->budget.i2c_adap);
Andrew de Quinceye87d41c2006-04-18 17:47:11 -03001566 if (fe) {
Andrew de Quincey1c72cfdce2006-09-05 17:58:20 -03001567 dvb_attach(tua6100_attach, fe, 0x60, &budget_av->budget.i2c_adap);
Andrew de Quinceye87d41c2006-04-18 17:47:11 -03001568 }
Andrew de Quinceyeffa7912006-01-09 15:25:09 -02001569 } else {
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001570 fe = dvb_attach(stv0299_attach, &typhoon_config,
Andrew de Quinceyeffa7912006-01-09 15:25:09 -02001571 &budget_av->budget.i2c_adap);
Andrew de Quinceye87d41c2006-04-18 17:47:11 -03001572 if (fe) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001573 fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
Andrew de Quinceye87d41c2006-04-18 17:47:11 -03001574 }
Andrew de Quinceyeffa7912006-01-09 15:25:09 -02001575 }
1576 break;
1577
Regis Prevotf8bf1342006-01-11 23:31:53 -02001578 case SUBID_DVBS_TV_STAR:
Oliver Endriss03aa73c2008-01-29 23:56:51 -03001579 case SUBID_DVBS_TV_STAR_PLUS_X4:
Regis Prevotf8bf1342006-01-11 23:31:53 -02001580 case SUBID_DVBS_TV_STAR_CI:
1581 case SUBID_DVBS_CYNERGY1200N:
Thilo Berger36f4f332006-02-27 00:09:08 -03001582 case SUBID_DVBS_EASYWATCH:
Oliver Endrissf72ce642007-05-13 23:25:57 -03001583 case SUBID_DVBS_EASYWATCH_2:
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001584 fe = dvb_attach(stv0299_attach, &philips_sd1878_config,
Regis Prevotf8bf1342006-01-11 23:31:53 -02001585 &budget_av->budget.i2c_adap);
Andrew de Quinceye87d41c2006-04-18 17:47:11 -03001586 if (fe) {
Michael Krufky9b98fd22007-05-07 01:48:56 -03001587 dvb_attach(dvb_pll_attach, fe, 0x60,
1588 &budget_av->budget.i2c_adap,
Michael Krufky47a99912007-06-12 16:10:51 -03001589 DVB_PLL_PHILIPS_SD1878_TDA8261);
Andrew de Quinceye87d41c2006-04-18 17:47:11 -03001590 }
Regis Prevotf8bf1342006-01-11 23:31:53 -02001591 break;
1592
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001593 case SUBID_DVBS_TYPHOON:
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001594 fe = dvb_attach(stv0299_attach, &typhoon_config,
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001595 &budget_av->budget.i2c_adap);
Andrew de Quinceye87d41c2006-04-18 17:47:11 -03001596 if (fe) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001597 fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
Andrew de Quinceye87d41c2006-04-18 17:47:11 -03001598 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001599 break;
Manu Abraham41e11512007-09-22 21:28:11 -03001600 case SUBID_DVBS2_KNC1:
1601 case SUBID_DVBS2_KNC1_OEM:
1602 budget_av->reinitialise_demod = 1;
1603 if ((fe = stb0899_attach(&knc1_dvbs2_config, &budget_av->budget.i2c_adap)))
1604 tda8261_attach(fe, &sd1878c_config, &budget_av->budget.i2c_adap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001605
Manu Abraham41e11512007-09-22 21:28:11 -03001606 break;
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001607 case SUBID_DVBS_CINERGY1200:
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001608 fe = dvb_attach(stv0299_attach, &cinergy_1200s_config,
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001609 &budget_av->budget.i2c_adap);
Andrew de Quinceye87d41c2006-04-18 17:47:11 -03001610 if (fe) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001611 fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
Andrew de Quinceye87d41c2006-04-18 17:47:11 -03001612 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001613 break;
1614
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001615 case SUBID_DVBC_KNC1:
1616 case SUBID_DVBC_KNC1_PLUS:
Andrew de Quincey5c1208b2006-05-22 10:32:02 -03001617 case SUBID_DVBC_CINERGY1200:
Thomas Hammc01d1e42006-11-17 07:12:58 -03001618 case SUBID_DVBC_EASYWATCH:
Andrew de Quincey5c1208b2006-05-22 10:32:02 -03001619 budget_av->reinitialise_demod = 1;
Hartmut Birraa323ac2007-04-21 19:37:17 -03001620 budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001621 fe = dvb_attach(tda10021_attach, &philips_cu1216_config,
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001622 &budget_av->budget.i2c_adap,
1623 read_pwm(budget_av));
Andrew de Quincey61cebe92006-11-19 14:10:59 -03001624 if (fe == NULL)
1625 fe = dvb_attach(tda10021_attach, &philips_cu1216_config_altaddress,
1626 &budget_av->budget.i2c_adap,
1627 read_pwm(budget_av));
Andrew de Quinceye87d41c2006-04-18 17:47:11 -03001628 if (fe) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001629 fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params;
Andrew de Quinceye87d41c2006-04-18 17:47:11 -03001630 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001631 break;
1632
Hartmut Birraa323ac2007-04-21 19:37:17 -03001633 case SUBID_DVBC_EASYWATCH_MK3:
1634 case SUBID_DVBC_CINERGY1200_MK3:
1635 case SUBID_DVBC_KNC1_MK3:
1636 case SUBID_DVBC_KNC1_PLUS_MK3:
1637 budget_av->reinitialise_demod = 1;
1638 budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
Antti Palosaari4388c3b2008-05-17 22:58:04 -03001639 fe = dvb_attach(tda10023_attach,
1640 &philips_cu1216_tda10023_config,
1641 &budget_av->budget.i2c_adap,
1642 read_pwm(budget_av));
Hartmut Birraa323ac2007-04-21 19:37:17 -03001643 if (fe) {
1644 fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params;
1645 }
1646 break;
1647
Kim Sandberg251130b2008-01-30 00:42:01 -03001648 case SUBID_DVBT_EASYWATCH:
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001649 case SUBID_DVBT_KNC1:
1650 case SUBID_DVBT_KNC1_PLUS:
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001651 case SUBID_DVBT_CINERGY1200:
Andrew de Quincey5c1208b2006-05-22 10:32:02 -03001652 budget_av->reinitialise_demod = 1;
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001653 fe = dvb_attach(tda10046_attach, &philips_tu1216_config,
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001654 &budget_av->budget.i2c_adap);
Andrew de Quincey6b3ccab2006-04-20 12:01:47 -03001655 if (fe) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001656 fe->ops.tuner_ops.init = philips_tu1216_tuner_init;
1657 fe->ops.tuner_ops.set_params = philips_tu1216_tuner_set_params;
Andrew de Quincey6b3ccab2006-04-20 12:01:47 -03001658 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001659 break;
1660 }
1661
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001662 if (fe == NULL) {
1663 printk(KERN_ERR "budget-av: A frontend driver was not found "
Bjorn Helgaas29e66a62008-09-04 17:24:51 -03001664 "for device [%04x:%04x] subsystem [%04x:%04x]\n",
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001665 saa->pci->vendor,
1666 saa->pci->device,
1667 saa->pci->subsystem_vendor,
1668 saa->pci->subsystem_device);
1669 return;
1670 }
1671
1672 budget_av->budget.dvb_frontend = fe;
1673
1674 if (dvb_register_frontend(&budget_av->budget.dvb_adapter,
1675 budget_av->budget.dvb_frontend)) {
1676 printk(KERN_ERR "budget-av: Frontend registration failed!\n");
Andrew de Quinceyf52a8382006-08-08 09:10:09 -03001677 dvb_frontend_detach(budget_av->budget.dvb_frontend);
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001678 budget_av->budget.dvb_frontend = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679 }
1680}
1681
1682
1683static void budget_av_irq(struct saa7146_dev *dev, u32 * isr)
1684{
1685 struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
1686
1687 dprintk(8, "dev: %p, budget_av: %p\n", dev, budget_av);
1688
1689 if (*isr & MASK_10)
1690 ttpci_budget_irq10_handler(dev, isr);
1691}
1692
1693static int budget_av_detach(struct saa7146_dev *dev)
1694{
1695 struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
1696 int err;
1697
1698 dprintk(2, "dev: %p\n", dev);
1699
1700 if (1 == budget_av->has_saa7113) {
1701 saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO);
1702
1703 msleep(200);
1704
1705 saa7146_unregister_device(&budget_av->vd, dev);
Marco Schluessler716a4e32007-02-03 14:47:14 -03001706
1707 saa7146_vv_release(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001708 }
1709
1710 if (budget_av->budget.ci_present)
1711 ciintf_deinit(budget_av);
1712
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001713 if (budget_av->budget.dvb_frontend != NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714 dvb_unregister_frontend(budget_av->budget.dvb_frontend);
Andrew de Quinceyf52a8382006-08-08 09:10:09 -03001715 dvb_frontend_detach(budget_av->budget.dvb_frontend);
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001716 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001717 err = ttpci_budget_deinit(&budget_av->budget);
1718
1719 kfree(budget_av);
1720
1721 return err;
1722}
1723
1724static struct saa7146_ext_vv vv_data;
1725
1726static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
1727{
1728 struct budget_av *budget_av;
1729 u8 *mac;
1730 int err;
1731
1732 dprintk(2, "dev: %p\n", dev);
1733
Panagiotis Issaris74081872006-01-11 19:40:56 -02001734 if (!(budget_av = kzalloc(sizeof(struct budget_av), GFP_KERNEL)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001735 return -ENOMEM;
1736
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001737 budget_av->has_saa7113 = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738 budget_av->budget.ci_present = 0;
1739
1740 dev->ext_priv = budget_av;
1741
Janne Grunau26dc4d02008-09-21 20:50:11 -03001742 err = ttpci_budget_init(&budget_av->budget, dev, info, THIS_MODULE,
1743 adapter_nr);
1744 if (err) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001745 kfree(budget_av);
1746 return err;
1747 }
1748
1749 /* knc1 initialization */
1750 saa7146_write(dev, DD1_STREAM_B, 0x04000000);
1751 saa7146_write(dev, DD1_INIT, 0x07000600);
1752 saa7146_write(dev, MC2, MASK_09 | MASK_25 | MASK_10 | MASK_26);
1753
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001754 if (saa7113_init(budget_av) == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001755 budget_av->has_saa7113 = 1;
1756
1757 if (0 != saa7146_vv_init(dev, &vv_data)) {
1758 /* fixme: proper cleanup here */
1759 ERR(("cannot init vv subsystem.\n"));
1760 return err;
1761 }
1762
1763 if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) {
1764 /* fixme: proper cleanup here */
1765 ERR(("cannot register capture v4l2 device.\n"));
Marco Schluessler716a4e32007-02-03 14:47:14 -03001766 saa7146_vv_release(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001767 return err;
1768 }
1769
1770 /* beware: this modifies dev->vv ... */
1771 saa7146_set_hps_source_and_sync(dev, SAA7146_HPS_SOURCE_PORT_A,
1772 SAA7146_HPS_SYNC_PORT_A);
1773
1774 saa7113_setinput(budget_av, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001775 }
1776
1777 /* fixme: find some sane values here... */
1778 saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
1779
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001780 mac = budget_av->budget.dvb_adapter.proposed_mac;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001781 if (i2c_readregs(&budget_av->budget.i2c_adap, 0xa0, 0x30, mac, 6)) {
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001782 printk(KERN_ERR "KNC1-%d: Could not read MAC from KNC1 card\n",
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001783 budget_av->budget.dvb_adapter.num);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001784 memset(mac, 0, 6);
1785 } else {
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001786 printk(KERN_INFO "KNC1-%d: MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001787 budget_av->budget.dvb_adapter.num,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001788 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
1789 }
1790
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001791 budget_av->budget.dvb_adapter.priv = budget_av;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001792 frontend_init(budget_av);
Andrew de Quinceyc5e768a2006-06-29 13:16:11 -03001793 ciintf_init(budget_av);
Oliver Endriss32e4c3a2006-07-18 22:55:23 -03001794
1795 ttpci_budget_init_hooks(&budget_av->budget);
1796
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797 return 0;
1798}
1799
1800#define KNC1_INPUTS 2
1801static struct v4l2_input knc1_inputs[KNC1_INPUTS] = {
1802 {0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
1803 {1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
1804};
1805
1806static struct saa7146_extension_ioctls ioctls[] = {
1807 {VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE},
1808 {VIDIOC_G_INPUT, SAA7146_EXCLUSIVE},
1809 {VIDIOC_S_INPUT, SAA7146_EXCLUSIVE},
1810 {0, 0}
1811};
1812
1813static int av_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
1814{
1815 struct saa7146_dev *dev = fh->dev;
1816 struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
1817
1818 switch (cmd) {
1819 case VIDIOC_ENUMINPUT:{
1820 struct v4l2_input *i = arg;
1821
1822 dprintk(1, "VIDIOC_ENUMINPUT %d.\n", i->index);
1823 if (i->index < 0 || i->index >= KNC1_INPUTS) {
1824 return -EINVAL;
1825 }
1826 memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input));
1827 return 0;
1828 }
1829 case VIDIOC_G_INPUT:{
1830 int *input = (int *) arg;
1831
1832 *input = budget_av->cur_input;
1833
1834 dprintk(1, "VIDIOC_G_INPUT %d.\n", *input);
1835 return 0;
1836 }
1837 case VIDIOC_S_INPUT:{
1838 int input = *(int *) arg;
1839 dprintk(1, "VIDIOC_S_INPUT %d.\n", input);
1840 return saa7113_setinput(budget_av, input);
1841 }
1842 default:
1843 return -ENOIOCTLCMD;
1844 }
1845 return 0;
1846}
1847
1848static struct saa7146_standard standard[] = {
1849 {.name = "PAL",.id = V4L2_STD_PAL,
1850 .v_offset = 0x17,.v_field = 288,
1851 .h_offset = 0x14,.h_pixels = 680,
1852 .v_max_out = 576,.h_max_out = 768 },
1853
1854 {.name = "NTSC",.id = V4L2_STD_NTSC,
1855 .v_offset = 0x16,.v_field = 240,
1856 .h_offset = 0x06,.h_pixels = 708,
1857 .v_max_out = 480,.h_max_out = 640, },
1858};
1859
1860static struct saa7146_ext_vv vv_data = {
1861 .inputs = 2,
1862 .capabilities = 0, // perhaps later: V4L2_CAP_VBI_CAPTURE, but that need tweaking with the saa7113
1863 .flags = 0,
1864 .stds = &standard[0],
Andi Drebesaf520a32007-07-30 11:48:10 -03001865 .num_stds = ARRAY_SIZE(standard),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001866 .ioctls = &ioctls[0],
1867 .ioctl = av_ioctl,
1868};
1869
1870static struct saa7146_extension budget_extension;
1871
1872MAKE_BUDGET_INFO(knc1s, "KNC1 DVB-S", BUDGET_KNC1S);
Manu Abraham41e11512007-09-22 21:28:11 -03001873MAKE_BUDGET_INFO(knc1s2,"KNC1 DVB-S2", BUDGET_KNC1S2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001874MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C);
1875MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T);
Regis Prevotf8bf1342006-01-11 23:31:53 -02001876MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR);
Thilo Berger36f4f332006-02-27 00:09:08 -03001877MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR);
Lothar Englisch60110ce2006-06-06 16:13:46 -03001878MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S);
Oliver Endrissf72ce642007-05-13 23:25:57 -03001879MAKE_BUDGET_INFO(satewps, "Satelco EasyWatch DVB-S", BUDGET_KNC1S);
Thomas Hammc01d1e42006-11-17 07:12:58 -03001880MAKE_BUDGET_INFO(satewplc, "Satelco EasyWatch DVB-C", BUDGET_KNC1CP);
Hartmut Birraa323ac2007-04-21 19:37:17 -03001881MAKE_BUDGET_INFO(satewcmk3, "Satelco EasyWatch DVB-C MK3", BUDGET_KNC1C_MK3);
Kim Sandberg251130b2008-01-30 00:42:01 -03001882MAKE_BUDGET_INFO(satewt, "Satelco EasyWatch DVB-T", BUDGET_KNC1T);
Johannes Stezenbach2d4f2c22005-05-16 21:54:23 -07001883MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP);
Oliver Endriss03aa73c2008-01-29 23:56:51 -03001884MAKE_BUDGET_INFO(knc1spx4, "KNC1 DVB-S Plus X4", BUDGET_KNC1SP);
Johannes Stezenbach2d4f2c22005-05-16 21:54:23 -07001885MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP);
Hartmut Birraa323ac2007-04-21 19:37:17 -03001886MAKE_BUDGET_INFO(knc1cmk3, "KNC1 DVB-C MK3", BUDGET_KNC1C_MK3);
1887MAKE_BUDGET_INFO(knc1cpmk3, "KNC1 DVB-C Plus MK3", BUDGET_KNC1CP_MK3);
Johannes Stezenbach2d4f2c22005-05-16 21:54:23 -07001888MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001889MAKE_BUDGET_INFO(cin1200s, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
Regis Prevotf8bf1342006-01-11 23:31:53 -02001890MAKE_BUDGET_INFO(cin1200sn, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001891MAKE_BUDGET_INFO(cin1200c, "Terratec Cinergy 1200 DVB-C", BUDGET_CIN1200C);
Hartmut Birraa323ac2007-04-21 19:37:17 -03001892MAKE_BUDGET_INFO(cin1200cmk3, "Terratec Cinergy 1200 DVB-C MK3", BUDGET_CIN1200C_MK3);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001893MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T);
1894
1895static struct pci_device_id pci_tbl[] = {
1896 MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x4f56),
Johannes Stezenbach2d4f2c22005-05-16 21:54:23 -07001897 MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x0010),
Andrew de Quinceyeffa7912006-01-09 15:25:09 -02001898 MAKE_EXTENSION_PCI(knc1s, 0x1894, 0x0010),
Johannes Stezenbach2d4f2c22005-05-16 21:54:23 -07001899 MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011),
Christoph Pfister4e318be2006-08-12 09:13:35 -03001900 MAKE_EXTENSION_PCI(knc1sp, 0x1894, 0x0011),
Regis Prevotf8bf1342006-01-11 23:31:53 -02001901 MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014),
Oliver Endriss03aa73c2008-01-29 23:56:51 -03001902 MAKE_EXTENSION_PCI(knc1spx4, 0x1894, 0x0015),
Regis Prevotf8bf1342006-01-11 23:31:53 -02001903 MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016),
Manu Abraham41e11512007-09-22 21:28:11 -03001904 MAKE_EXTENSION_PCI(knc1s2, 0x1894, 0x0018),
1905 MAKE_EXTENSION_PCI(knc1s2, 0x1894, 0x0019),
Thilo Berger36f4f332006-02-27 00:09:08 -03001906 MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e),
Lothar Englisch60110ce2006-06-06 16:13:46 -03001907 MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a),
Oliver Endrissf72ce642007-05-13 23:25:57 -03001908 MAKE_EXTENSION_PCI(satewps, 0x1894, 0x001b),
Thomas Hammc01d1e42006-11-17 07:12:58 -03001909 MAKE_EXTENSION_PCI(satewplc, 0x1894, 0x002a),
Hartmut Birraa323ac2007-04-21 19:37:17 -03001910 MAKE_EXTENSION_PCI(satewcmk3, 0x1894, 0x002c),
Kim Sandberg251130b2008-01-30 00:42:01 -03001911 MAKE_EXTENSION_PCI(satewt, 0x1894, 0x003a),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001912 MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020),
Johannes Stezenbach2d4f2c22005-05-16 21:54:23 -07001913 MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021),
Hartmut Birraa323ac2007-04-21 19:37:17 -03001914 MAKE_EXTENSION_PCI(knc1cmk3, 0x1894, 0x0022),
1915 MAKE_EXTENSION_PCI(knc1cpmk3, 0x1894, 0x0023),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001916 MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030),
Johannes Stezenbach2d4f2c22005-05-16 21:54:23 -07001917 MAKE_EXTENSION_PCI(knc1tp, 0x1894, 0x0031),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001918 MAKE_EXTENSION_PCI(cin1200s, 0x153b, 0x1154),
Regis Prevotf8bf1342006-01-11 23:31:53 -02001919 MAKE_EXTENSION_PCI(cin1200sn, 0x153b, 0x1155),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001920 MAKE_EXTENSION_PCI(cin1200c, 0x153b, 0x1156),
Hartmut Birraa323ac2007-04-21 19:37:17 -03001921 MAKE_EXTENSION_PCI(cin1200cmk3, 0x153b, 0x1176),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001922 MAKE_EXTENSION_PCI(cin1200t, 0x153b, 0x1157),
1923 {
1924 .vendor = 0,
1925 }
1926};
1927
1928MODULE_DEVICE_TABLE(pci, pci_tbl);
1929
1930static struct saa7146_extension budget_extension = {
Julian Scheel27b05fd2005-07-12 13:58:39 -07001931 .name = "budget_av",
Oliver Endriss00c4cc62006-11-01 13:09:51 -03001932 .flags = SAA7146_USE_I2C_IRQ,
Oliver Endriss69459f3d2005-12-01 00:51:48 -08001933
Linus Torvalds1da177e2005-04-16 15:20:36 -07001934 .pci_tbl = pci_tbl,
1935
1936 .module = THIS_MODULE,
1937 .attach = budget_av_attach,
1938 .detach = budget_av_detach,
1939
1940 .irq_mask = MASK_10,
1941 .irq_func = budget_av_irq,
1942};
1943
1944static int __init budget_av_init(void)
1945{
1946 return saa7146_register_extension(&budget_extension);
1947}
1948
1949static void __exit budget_av_exit(void)
1950{
1951 saa7146_unregister_extension(&budget_extension);
1952}
1953
1954module_init(budget_av_init);
1955module_exit(budget_av_exit);
1956
1957MODULE_LICENSE("GPL");
1958MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others");
1959MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
1960 "budget PCI DVB w/ analog input and CI-module (e.g. the KNC cards)");