blob: 55fe5bb9c01385033adbe711395545e609bda27d [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
Manu Abrahamb11eb462007-10-05 01:57:59 -03001478/*
1479 * SD1878/SHA tuner config
1480 * 1F, Single I/P, Horizontal mount, High Sensitivity
1481 */
Manu Abraham41e11512007-09-22 21:28:11 -03001482static const struct tda8261_config sd1878c_config = {
Manu Abrahamb11eb462007-10-05 01:57:59 -03001483// .name = "SD1878/SHA",
Manu Abraham41e11512007-09-22 21:28:11 -03001484 .addr = 0x60,
1485 .step_size = TDA8261_STEP_1000 /* kHz */
1486};
1487
Linus Torvalds1da177e2005-04-16 15:20:36 -07001488static u8 read_pwm(struct budget_av *budget_av)
1489{
1490 u8 b = 0xff;
1491 u8 pwm;
1492 struct i2c_msg msg[] = { {.addr = 0x50,.flags = 0,.buf = &b,.len = 1},
1493 {.addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1}
1494 };
1495
1496 if ((i2c_transfer(&budget_av->budget.i2c_adap, msg, 2) != 2)
1497 || (pwm == 0xff))
1498 pwm = 0x48;
1499
1500 return pwm;
1501}
1502
Hartmut Birraa323ac2007-04-21 19:37:17 -03001503#define SUBID_DVBS_KNC1 0x0010
1504#define SUBID_DVBS_KNC1_PLUS 0x0011
1505#define SUBID_DVBS_TYPHOON 0x4f56
1506#define SUBID_DVBS_CINERGY1200 0x1154
1507#define SUBID_DVBS_CYNERGY1200N 0x1155
1508#define SUBID_DVBS_TV_STAR 0x0014
Oliver Endriss03aa73c2008-01-29 23:56:51 -03001509#define SUBID_DVBS_TV_STAR_PLUS_X4 0x0015
Hartmut Birraa323ac2007-04-21 19:37:17 -03001510#define SUBID_DVBS_TV_STAR_CI 0x0016
Manu Abraham41e11512007-09-22 21:28:11 -03001511#define SUBID_DVBS2_KNC1 0x0018
1512#define SUBID_DVBS2_KNC1_OEM 0x0019
Hartmut Birraa323ac2007-04-21 19:37:17 -03001513#define SUBID_DVBS_EASYWATCH_1 0x001a
Oliver Endrissf72ce642007-05-13 23:25:57 -03001514#define SUBID_DVBS_EASYWATCH_2 0x001b
Arvo Jarve5dc16112007-10-25 13:25:23 -03001515#define SUBID_DVBS2_EASYWATCH 0x001d
Hartmut Birraa323ac2007-04-21 19:37:17 -03001516#define SUBID_DVBS_EASYWATCH 0x001e
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001517
Hartmut Birraa323ac2007-04-21 19:37:17 -03001518#define SUBID_DVBC_EASYWATCH 0x002a
1519#define SUBID_DVBC_EASYWATCH_MK3 0x002c
1520#define SUBID_DVBC_KNC1 0x0020
1521#define SUBID_DVBC_KNC1_PLUS 0x0021
1522#define SUBID_DVBC_KNC1_MK3 0x0022
1523#define SUBID_DVBC_KNC1_PLUS_MK3 0x0023
1524#define SUBID_DVBC_CINERGY1200 0x1156
1525#define SUBID_DVBC_CINERGY1200_MK3 0x1176
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001526
Kim Sandberg251130b2008-01-30 00:42:01 -03001527#define SUBID_DVBT_EASYWATCH 0x003a
Hartmut Birraa323ac2007-04-21 19:37:17 -03001528#define SUBID_DVBT_KNC1_PLUS 0x0031
1529#define SUBID_DVBT_KNC1 0x0030
1530#define SUBID_DVBT_CINERGY1200 0x1157
Linus Torvalds1da177e2005-04-16 15:20:36 -07001531
1532static void frontend_init(struct budget_av *budget_av)
1533{
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001534 struct saa7146_dev * saa = budget_av->budget.dev;
1535 struct dvb_frontend * fe = NULL;
1536
Andrew de Quincey473f5422006-04-13 17:29:07 -03001537 /* Enable / PowerON Frontend */
1538 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
1539
Hartmut Birr740cf9e2006-11-03 15:34:18 -03001540 /* Wait for PowerON */
1541 msleep(100);
1542
Andrew de Quincey473f5422006-04-13 17:29:07 -03001543 /* additional setup necessary for the PLUS cards */
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001544 switch (saa->pci->subsystem_device) {
1545 case SUBID_DVBS_KNC1_PLUS:
1546 case SUBID_DVBC_KNC1_PLUS:
1547 case SUBID_DVBT_KNC1_PLUS:
Thomas Hammc01d1e42006-11-17 07:12:58 -03001548 case SUBID_DVBC_EASYWATCH:
Hartmut Birraa323ac2007-04-21 19:37:17 -03001549 case SUBID_DVBC_KNC1_PLUS_MK3:
Manu Abraham41e11512007-09-22 21:28:11 -03001550 case SUBID_DVBS2_KNC1:
1551 case SUBID_DVBS2_KNC1_OEM:
Arvo Jarve5dc16112007-10-25 13:25:23 -03001552 case SUBID_DVBS2_EASYWATCH:
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001553 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001554 break;
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001555 }
1556
1557 switch (saa->pci->subsystem_device) {
1558
1559 case SUBID_DVBS_KNC1:
Christoph Pfisterc4e3bcb2008-04-09 17:37:36 -03001560 /*
1561 * maybe that setting is needed for other dvb-s cards as well,
1562 * but so far it has been only confirmed for this type
1563 */
1564 budget_av->reinitialise_demod = 1;
1565 /* fall through */
Christoph Pfister4e318be2006-08-12 09:13:35 -03001566 case SUBID_DVBS_KNC1_PLUS:
Lothar Englisch60110ce2006-06-06 16:13:46 -03001567 case SUBID_DVBS_EASYWATCH_1:
Andrew de Quinceyeffa7912006-01-09 15:25:09 -02001568 if (saa->pci->subsystem_vendor == 0x1894) {
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001569 fe = dvb_attach(stv0299_attach, &cinergy_1200s_1894_0010_config,
Andrew de Quinceyeffa7912006-01-09 15:25:09 -02001570 &budget_av->budget.i2c_adap);
Andrew de Quinceye87d41c2006-04-18 17:47:11 -03001571 if (fe) {
Andrew de Quincey1c72cfdce2006-09-05 17:58:20 -03001572 dvb_attach(tua6100_attach, fe, 0x60, &budget_av->budget.i2c_adap);
Andrew de Quinceye87d41c2006-04-18 17:47:11 -03001573 }
Andrew de Quinceyeffa7912006-01-09 15:25:09 -02001574 } else {
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001575 fe = dvb_attach(stv0299_attach, &typhoon_config,
Andrew de Quinceyeffa7912006-01-09 15:25:09 -02001576 &budget_av->budget.i2c_adap);
Andrew de Quinceye87d41c2006-04-18 17:47:11 -03001577 if (fe) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001578 fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
Andrew de Quinceye87d41c2006-04-18 17:47:11 -03001579 }
Andrew de Quinceyeffa7912006-01-09 15:25:09 -02001580 }
1581 break;
1582
Regis Prevotf8bf1342006-01-11 23:31:53 -02001583 case SUBID_DVBS_TV_STAR:
Oliver Endriss03aa73c2008-01-29 23:56:51 -03001584 case SUBID_DVBS_TV_STAR_PLUS_X4:
Regis Prevotf8bf1342006-01-11 23:31:53 -02001585 case SUBID_DVBS_TV_STAR_CI:
1586 case SUBID_DVBS_CYNERGY1200N:
Thilo Berger36f4f332006-02-27 00:09:08 -03001587 case SUBID_DVBS_EASYWATCH:
Oliver Endrissf72ce642007-05-13 23:25:57 -03001588 case SUBID_DVBS_EASYWATCH_2:
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001589 fe = dvb_attach(stv0299_attach, &philips_sd1878_config,
Regis Prevotf8bf1342006-01-11 23:31:53 -02001590 &budget_av->budget.i2c_adap);
Andrew de Quinceye87d41c2006-04-18 17:47:11 -03001591 if (fe) {
Michael Krufky9b98fd22007-05-07 01:48:56 -03001592 dvb_attach(dvb_pll_attach, fe, 0x60,
1593 &budget_av->budget.i2c_adap,
Michael Krufky47a99912007-06-12 16:10:51 -03001594 DVB_PLL_PHILIPS_SD1878_TDA8261);
Andrew de Quinceye87d41c2006-04-18 17:47:11 -03001595 }
Regis Prevotf8bf1342006-01-11 23:31:53 -02001596 break;
1597
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001598 case SUBID_DVBS_TYPHOON:
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001599 fe = dvb_attach(stv0299_attach, &typhoon_config,
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001600 &budget_av->budget.i2c_adap);
Andrew de Quinceye87d41c2006-04-18 17:47:11 -03001601 if (fe) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001602 fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
Andrew de Quinceye87d41c2006-04-18 17:47:11 -03001603 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001604 break;
Manu Abraham41e11512007-09-22 21:28:11 -03001605 case SUBID_DVBS2_KNC1:
1606 case SUBID_DVBS2_KNC1_OEM:
Arvo Jarve5dc16112007-10-25 13:25:23 -03001607 case SUBID_DVBS2_EASYWATCH:
Manu Abraham41e11512007-09-22 21:28:11 -03001608 budget_av->reinitialise_demod = 1;
Manu Abrahamae9902d2007-10-08 18:51:54 -03001609 if ((fe = dvb_attach(stb0899_attach, &knc1_dvbs2_config, &budget_av->budget.i2c_adap)))
1610 dvb_attach(tda8261_attach, fe, &sd1878c_config, &budget_av->budget.i2c_adap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611
Manu Abraham41e11512007-09-22 21:28:11 -03001612 break;
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001613 case SUBID_DVBS_CINERGY1200:
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001614 fe = dvb_attach(stv0299_attach, &cinergy_1200s_config,
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001615 &budget_av->budget.i2c_adap);
Andrew de Quinceye87d41c2006-04-18 17:47:11 -03001616 if (fe) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001617 fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
Andrew de Quinceye87d41c2006-04-18 17:47:11 -03001618 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001619 break;
1620
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001621 case SUBID_DVBC_KNC1:
1622 case SUBID_DVBC_KNC1_PLUS:
Andrew de Quincey5c1208b2006-05-22 10:32:02 -03001623 case SUBID_DVBC_CINERGY1200:
Thomas Hammc01d1e42006-11-17 07:12:58 -03001624 case SUBID_DVBC_EASYWATCH:
Andrew de Quincey5c1208b2006-05-22 10:32:02 -03001625 budget_av->reinitialise_demod = 1;
Hartmut Birraa323ac2007-04-21 19:37:17 -03001626 budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001627 fe = dvb_attach(tda10021_attach, &philips_cu1216_config,
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001628 &budget_av->budget.i2c_adap,
1629 read_pwm(budget_av));
Andrew de Quincey61cebe92006-11-19 14:10:59 -03001630 if (fe == NULL)
1631 fe = dvb_attach(tda10021_attach, &philips_cu1216_config_altaddress,
1632 &budget_av->budget.i2c_adap,
1633 read_pwm(budget_av));
Andrew de Quinceye87d41c2006-04-18 17:47:11 -03001634 if (fe) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001635 fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params;
Andrew de Quinceye87d41c2006-04-18 17:47:11 -03001636 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001637 break;
1638
Hartmut Birraa323ac2007-04-21 19:37:17 -03001639 case SUBID_DVBC_EASYWATCH_MK3:
1640 case SUBID_DVBC_CINERGY1200_MK3:
1641 case SUBID_DVBC_KNC1_MK3:
1642 case SUBID_DVBC_KNC1_PLUS_MK3:
1643 budget_av->reinitialise_demod = 1;
1644 budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
Antti Palosaari4388c3b2008-05-17 22:58:04 -03001645 fe = dvb_attach(tda10023_attach,
1646 &philips_cu1216_tda10023_config,
1647 &budget_av->budget.i2c_adap,
1648 read_pwm(budget_av));
Hartmut Birraa323ac2007-04-21 19:37:17 -03001649 if (fe) {
1650 fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params;
1651 }
1652 break;
1653
Kim Sandberg251130b2008-01-30 00:42:01 -03001654 case SUBID_DVBT_EASYWATCH:
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001655 case SUBID_DVBT_KNC1:
1656 case SUBID_DVBT_KNC1_PLUS:
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001657 case SUBID_DVBT_CINERGY1200:
Andrew de Quincey5c1208b2006-05-22 10:32:02 -03001658 budget_av->reinitialise_demod = 1;
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001659 fe = dvb_attach(tda10046_attach, &philips_tu1216_config,
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001660 &budget_av->budget.i2c_adap);
Andrew de Quincey6b3ccab2006-04-20 12:01:47 -03001661 if (fe) {
Patrick Boettcherdea74862006-05-14 05:01:31 -03001662 fe->ops.tuner_ops.init = philips_tu1216_tuner_init;
1663 fe->ops.tuner_ops.set_params = philips_tu1216_tuner_set_params;
Andrew de Quincey6b3ccab2006-04-20 12:01:47 -03001664 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001665 break;
1666 }
1667
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001668 if (fe == NULL) {
1669 printk(KERN_ERR "budget-av: A frontend driver was not found "
Bjorn Helgaas29e66a62008-09-04 17:24:51 -03001670 "for device [%04x:%04x] subsystem [%04x:%04x]\n",
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001671 saa->pci->vendor,
1672 saa->pci->device,
1673 saa->pci->subsystem_vendor,
1674 saa->pci->subsystem_device);
1675 return;
1676 }
1677
1678 budget_av->budget.dvb_frontend = fe;
1679
1680 if (dvb_register_frontend(&budget_av->budget.dvb_adapter,
1681 budget_av->budget.dvb_frontend)) {
1682 printk(KERN_ERR "budget-av: Frontend registration failed!\n");
Andrew de Quinceyf52a8382006-08-08 09:10:09 -03001683 dvb_frontend_detach(budget_av->budget.dvb_frontend);
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001684 budget_av->budget.dvb_frontend = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001685 }
1686}
1687
1688
1689static void budget_av_irq(struct saa7146_dev *dev, u32 * isr)
1690{
1691 struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
1692
1693 dprintk(8, "dev: %p, budget_av: %p\n", dev, budget_av);
1694
1695 if (*isr & MASK_10)
1696 ttpci_budget_irq10_handler(dev, isr);
1697}
1698
1699static int budget_av_detach(struct saa7146_dev *dev)
1700{
1701 struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
1702 int err;
1703
1704 dprintk(2, "dev: %p\n", dev);
1705
1706 if (1 == budget_av->has_saa7113) {
1707 saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO);
1708
1709 msleep(200);
1710
1711 saa7146_unregister_device(&budget_av->vd, dev);
Marco Schluessler716a4e32007-02-03 14:47:14 -03001712
1713 saa7146_vv_release(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714 }
1715
1716 if (budget_av->budget.ci_present)
1717 ciintf_deinit(budget_av);
1718
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001719 if (budget_av->budget.dvb_frontend != NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720 dvb_unregister_frontend(budget_av->budget.dvb_frontend);
Andrew de Quinceyf52a8382006-08-08 09:10:09 -03001721 dvb_frontend_detach(budget_av->budget.dvb_frontend);
Andrew de Quincey2bfe0312006-08-08 09:10:08 -03001722 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723 err = ttpci_budget_deinit(&budget_av->budget);
1724
1725 kfree(budget_av);
1726
1727 return err;
1728}
1729
1730static struct saa7146_ext_vv vv_data;
1731
1732static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
1733{
1734 struct budget_av *budget_av;
1735 u8 *mac;
1736 int err;
1737
1738 dprintk(2, "dev: %p\n", dev);
1739
Panagiotis Issaris74081872006-01-11 19:40:56 -02001740 if (!(budget_av = kzalloc(sizeof(struct budget_av), GFP_KERNEL)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741 return -ENOMEM;
1742
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001743 budget_av->has_saa7113 = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001744 budget_av->budget.ci_present = 0;
1745
1746 dev->ext_priv = budget_av;
1747
Janne Grunau26dc4d02008-09-21 20:50:11 -03001748 err = ttpci_budget_init(&budget_av->budget, dev, info, THIS_MODULE,
1749 adapter_nr);
1750 if (err) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001751 kfree(budget_av);
1752 return err;
1753 }
1754
1755 /* knc1 initialization */
1756 saa7146_write(dev, DD1_STREAM_B, 0x04000000);
1757 saa7146_write(dev, DD1_INIT, 0x07000600);
1758 saa7146_write(dev, MC2, MASK_09 | MASK_25 | MASK_10 | MASK_26);
1759
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001760 if (saa7113_init(budget_av) == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001761 budget_av->has_saa7113 = 1;
1762
1763 if (0 != saa7146_vv_init(dev, &vv_data)) {
1764 /* fixme: proper cleanup here */
1765 ERR(("cannot init vv subsystem.\n"));
1766 return err;
1767 }
1768
1769 if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) {
1770 /* fixme: proper cleanup here */
1771 ERR(("cannot register capture v4l2 device.\n"));
Marco Schluessler716a4e32007-02-03 14:47:14 -03001772 saa7146_vv_release(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001773 return err;
1774 }
1775
1776 /* beware: this modifies dev->vv ... */
1777 saa7146_set_hps_source_and_sync(dev, SAA7146_HPS_SOURCE_PORT_A,
1778 SAA7146_HPS_SYNC_PORT_A);
1779
1780 saa7113_setinput(budget_av, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001781 }
1782
1783 /* fixme: find some sane values here... */
1784 saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
1785
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001786 mac = budget_av->budget.dvb_adapter.proposed_mac;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001787 if (i2c_readregs(&budget_av->budget.i2c_adap, 0xa0, 0x30, mac, 6)) {
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001788 printk(KERN_ERR "KNC1-%d: Could not read MAC from KNC1 card\n",
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001789 budget_av->budget.dvb_adapter.num);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001790 memset(mac, 0, 6);
1791 } else {
Johannes Stezenbachb82a96a2005-05-16 21:54:49 -07001792 printk(KERN_INFO "KNC1-%d: MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001793 budget_av->budget.dvb_adapter.num,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001794 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
1795 }
1796
Johannes Stezenbachfdc53a62005-05-16 21:54:39 -07001797 budget_av->budget.dvb_adapter.priv = budget_av;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001798 frontend_init(budget_av);
Andrew de Quinceyc5e768a2006-06-29 13:16:11 -03001799 ciintf_init(budget_av);
Oliver Endriss32e4c3a2006-07-18 22:55:23 -03001800
1801 ttpci_budget_init_hooks(&budget_av->budget);
1802
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803 return 0;
1804}
1805
1806#define KNC1_INPUTS 2
1807static struct v4l2_input knc1_inputs[KNC1_INPUTS] = {
1808 {0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
1809 {1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
1810};
1811
1812static struct saa7146_extension_ioctls ioctls[] = {
1813 {VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE},
1814 {VIDIOC_G_INPUT, SAA7146_EXCLUSIVE},
1815 {VIDIOC_S_INPUT, SAA7146_EXCLUSIVE},
1816 {0, 0}
1817};
1818
1819static int av_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
1820{
1821 struct saa7146_dev *dev = fh->dev;
1822 struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
1823
1824 switch (cmd) {
1825 case VIDIOC_ENUMINPUT:{
1826 struct v4l2_input *i = arg;
1827
1828 dprintk(1, "VIDIOC_ENUMINPUT %d.\n", i->index);
1829 if (i->index < 0 || i->index >= KNC1_INPUTS) {
1830 return -EINVAL;
1831 }
1832 memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input));
1833 return 0;
1834 }
1835 case VIDIOC_G_INPUT:{
1836 int *input = (int *) arg;
1837
1838 *input = budget_av->cur_input;
1839
1840 dprintk(1, "VIDIOC_G_INPUT %d.\n", *input);
1841 return 0;
1842 }
1843 case VIDIOC_S_INPUT:{
1844 int input = *(int *) arg;
1845 dprintk(1, "VIDIOC_S_INPUT %d.\n", input);
1846 return saa7113_setinput(budget_av, input);
1847 }
1848 default:
1849 return -ENOIOCTLCMD;
1850 }
1851 return 0;
1852}
1853
1854static struct saa7146_standard standard[] = {
1855 {.name = "PAL",.id = V4L2_STD_PAL,
1856 .v_offset = 0x17,.v_field = 288,
1857 .h_offset = 0x14,.h_pixels = 680,
1858 .v_max_out = 576,.h_max_out = 768 },
1859
1860 {.name = "NTSC",.id = V4L2_STD_NTSC,
1861 .v_offset = 0x16,.v_field = 240,
1862 .h_offset = 0x06,.h_pixels = 708,
1863 .v_max_out = 480,.h_max_out = 640, },
1864};
1865
1866static struct saa7146_ext_vv vv_data = {
1867 .inputs = 2,
1868 .capabilities = 0, // perhaps later: V4L2_CAP_VBI_CAPTURE, but that need tweaking with the saa7113
1869 .flags = 0,
1870 .stds = &standard[0],
Andi Drebesaf520a32007-07-30 11:48:10 -03001871 .num_stds = ARRAY_SIZE(standard),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001872 .ioctls = &ioctls[0],
1873 .ioctl = av_ioctl,
1874};
1875
1876static struct saa7146_extension budget_extension;
1877
1878MAKE_BUDGET_INFO(knc1s, "KNC1 DVB-S", BUDGET_KNC1S);
Manu Abraham41e11512007-09-22 21:28:11 -03001879MAKE_BUDGET_INFO(knc1s2,"KNC1 DVB-S2", BUDGET_KNC1S2);
Arvo Jarve5dc16112007-10-25 13:25:23 -03001880MAKE_BUDGET_INFO(sates2,"Satelco EasyWatch DVB-S2", BUDGET_KNC1S2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001881MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C);
1882MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T);
Regis Prevotf8bf1342006-01-11 23:31:53 -02001883MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR);
Thilo Berger36f4f332006-02-27 00:09:08 -03001884MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR);
Lothar Englisch60110ce2006-06-06 16:13:46 -03001885MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S);
Oliver Endrissf72ce642007-05-13 23:25:57 -03001886MAKE_BUDGET_INFO(satewps, "Satelco EasyWatch DVB-S", BUDGET_KNC1S);
Thomas Hammc01d1e42006-11-17 07:12:58 -03001887MAKE_BUDGET_INFO(satewplc, "Satelco EasyWatch DVB-C", BUDGET_KNC1CP);
Hartmut Birraa323ac2007-04-21 19:37:17 -03001888MAKE_BUDGET_INFO(satewcmk3, "Satelco EasyWatch DVB-C MK3", BUDGET_KNC1C_MK3);
Kim Sandberg251130b2008-01-30 00:42:01 -03001889MAKE_BUDGET_INFO(satewt, "Satelco EasyWatch DVB-T", BUDGET_KNC1T);
Johannes Stezenbach2d4f2c22005-05-16 21:54:23 -07001890MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP);
Oliver Endriss03aa73c2008-01-29 23:56:51 -03001891MAKE_BUDGET_INFO(knc1spx4, "KNC1 DVB-S Plus X4", BUDGET_KNC1SP);
Johannes Stezenbach2d4f2c22005-05-16 21:54:23 -07001892MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP);
Hartmut Birraa323ac2007-04-21 19:37:17 -03001893MAKE_BUDGET_INFO(knc1cmk3, "KNC1 DVB-C MK3", BUDGET_KNC1C_MK3);
1894MAKE_BUDGET_INFO(knc1cpmk3, "KNC1 DVB-C Plus MK3", BUDGET_KNC1CP_MK3);
Johannes Stezenbach2d4f2c22005-05-16 21:54:23 -07001895MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001896MAKE_BUDGET_INFO(cin1200s, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
Regis Prevotf8bf1342006-01-11 23:31:53 -02001897MAKE_BUDGET_INFO(cin1200sn, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001898MAKE_BUDGET_INFO(cin1200c, "Terratec Cinergy 1200 DVB-C", BUDGET_CIN1200C);
Hartmut Birraa323ac2007-04-21 19:37:17 -03001899MAKE_BUDGET_INFO(cin1200cmk3, "Terratec Cinergy 1200 DVB-C MK3", BUDGET_CIN1200C_MK3);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001900MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T);
1901
1902static struct pci_device_id pci_tbl[] = {
1903 MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x4f56),
Johannes Stezenbach2d4f2c22005-05-16 21:54:23 -07001904 MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x0010),
Andrew de Quinceyeffa7912006-01-09 15:25:09 -02001905 MAKE_EXTENSION_PCI(knc1s, 0x1894, 0x0010),
Johannes Stezenbach2d4f2c22005-05-16 21:54:23 -07001906 MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011),
Christoph Pfister4e318be2006-08-12 09:13:35 -03001907 MAKE_EXTENSION_PCI(knc1sp, 0x1894, 0x0011),
Regis Prevotf8bf1342006-01-11 23:31:53 -02001908 MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014),
Oliver Endriss03aa73c2008-01-29 23:56:51 -03001909 MAKE_EXTENSION_PCI(knc1spx4, 0x1894, 0x0015),
Regis Prevotf8bf1342006-01-11 23:31:53 -02001910 MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016),
Manu Abraham41e11512007-09-22 21:28:11 -03001911 MAKE_EXTENSION_PCI(knc1s2, 0x1894, 0x0018),
1912 MAKE_EXTENSION_PCI(knc1s2, 0x1894, 0x0019),
Arvo Jarve5dc16112007-10-25 13:25:23 -03001913 MAKE_EXTENSION_PCI(sates2, 0x1894, 0x001d),
Thilo Berger36f4f332006-02-27 00:09:08 -03001914 MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e),
Lothar Englisch60110ce2006-06-06 16:13:46 -03001915 MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a),
Oliver Endrissf72ce642007-05-13 23:25:57 -03001916 MAKE_EXTENSION_PCI(satewps, 0x1894, 0x001b),
Thomas Hammc01d1e42006-11-17 07:12:58 -03001917 MAKE_EXTENSION_PCI(satewplc, 0x1894, 0x002a),
Hartmut Birraa323ac2007-04-21 19:37:17 -03001918 MAKE_EXTENSION_PCI(satewcmk3, 0x1894, 0x002c),
Kim Sandberg251130b2008-01-30 00:42:01 -03001919 MAKE_EXTENSION_PCI(satewt, 0x1894, 0x003a),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001920 MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020),
Johannes Stezenbach2d4f2c22005-05-16 21:54:23 -07001921 MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021),
Hartmut Birraa323ac2007-04-21 19:37:17 -03001922 MAKE_EXTENSION_PCI(knc1cmk3, 0x1894, 0x0022),
1923 MAKE_EXTENSION_PCI(knc1cpmk3, 0x1894, 0x0023),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001924 MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030),
Johannes Stezenbach2d4f2c22005-05-16 21:54:23 -07001925 MAKE_EXTENSION_PCI(knc1tp, 0x1894, 0x0031),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001926 MAKE_EXTENSION_PCI(cin1200s, 0x153b, 0x1154),
Regis Prevotf8bf1342006-01-11 23:31:53 -02001927 MAKE_EXTENSION_PCI(cin1200sn, 0x153b, 0x1155),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001928 MAKE_EXTENSION_PCI(cin1200c, 0x153b, 0x1156),
Hartmut Birraa323ac2007-04-21 19:37:17 -03001929 MAKE_EXTENSION_PCI(cin1200cmk3, 0x153b, 0x1176),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001930 MAKE_EXTENSION_PCI(cin1200t, 0x153b, 0x1157),
1931 {
1932 .vendor = 0,
1933 }
1934};
1935
1936MODULE_DEVICE_TABLE(pci, pci_tbl);
1937
1938static struct saa7146_extension budget_extension = {
Julian Scheel27b05fd2005-07-12 13:58:39 -07001939 .name = "budget_av",
Oliver Endriss00c4cc62006-11-01 13:09:51 -03001940 .flags = SAA7146_USE_I2C_IRQ,
Oliver Endriss69459f3d2005-12-01 00:51:48 -08001941
Linus Torvalds1da177e2005-04-16 15:20:36 -07001942 .pci_tbl = pci_tbl,
1943
1944 .module = THIS_MODULE,
1945 .attach = budget_av_attach,
1946 .detach = budget_av_detach,
1947
1948 .irq_mask = MASK_10,
1949 .irq_func = budget_av_irq,
1950};
1951
1952static int __init budget_av_init(void)
1953{
1954 return saa7146_register_extension(&budget_extension);
1955}
1956
1957static void __exit budget_av_exit(void)
1958{
1959 saa7146_unregister_extension(&budget_extension);
1960}
1961
1962module_init(budget_av_init);
1963module_exit(budget_av_exit);
1964
1965MODULE_LICENSE("GPL");
1966MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others");
1967MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
1968 "budget PCI DVB w/ analog input and CI-module (e.g. the KNC cards)");