V4L/DVB (4501): Add support for knc one dvb-s plus with 1894:0011
[linux-2.6.git] / drivers / media / dvb / ttpci / budget-av.c
blob16ff8ae80d8051b52ffa1c333b1009d95200f347
1 /*
2 * budget-av.c: driver for the SAA7146 based Budget DVB cards
3 * with analog video in
5 * Compiled from various sources by Michael Hunold <michael@mihu.de>
7 * CI interface support (c) 2004 Olivier Gournet <ogournet@anevia.com> &
8 * Andrew de Quincey <adq_dvb@lidskialf.net>
10 * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
12 * Copyright (C) 1999-2002 Ralph Metzler
13 * & Marcus Metzler for convergence integrated media GmbH
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.
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.
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
33 * the project's page is at http://www.linuxtv.org/dvb/
36 #include "budget.h"
37 #include "stv0299.h"
38 #include "tda10021.h"
39 #include "tda1004x.h"
40 #include "dvb-pll.h"
41 #include <media/saa7146_vv.h>
42 #include <linux/module.h>
43 #include <linux/errno.h>
44 #include <linux/slab.h>
45 #include <linux/interrupt.h>
46 #include <linux/input.h>
47 #include <linux/spinlock.h>
49 #include "dvb_ca_en50221.h"
51 #define DEBICICAM 0x02420000
53 #define SLOTSTATUS_NONE 1
54 #define SLOTSTATUS_PRESENT 2
55 #define SLOTSTATUS_RESET 4
56 #define SLOTSTATUS_READY 8
57 #define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)
59 struct budget_av {
60 struct budget budget;
61 struct video_device *vd;
62 int cur_input;
63 int has_saa7113;
64 struct tasklet_struct ciintf_irq_tasklet;
65 int slot_status;
66 struct dvb_ca_en50221 ca;
67 u8 reinitialise_demod:1;
68 u8 tda10021_poclkp:1;
69 u8 tda10021_ts_enabled;
70 int (*tda10021_set_frontend)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p);
73 static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot);
76 /* GPIO Connections:
77 * 0 - Vcc/Reset (Reset is controlled by capacitor). Resets the frontend *AS WELL*!
78 * 1 - CI memory select 0=>IO memory, 1=>Attribute Memory
79 * 2 - CI Card Enable (Active Low)
80 * 3 - CI Card Detect
83 /****************************************************************************
84 * INITIALIZATION
85 ****************************************************************************/
87 static u8 i2c_readreg(struct i2c_adapter *i2c, u8 id, u8 reg)
89 u8 mm1[] = { 0x00 };
90 u8 mm2[] = { 0x00 };
91 struct i2c_msg msgs[2];
93 msgs[0].flags = 0;
94 msgs[1].flags = I2C_M_RD;
95 msgs[0].addr = msgs[1].addr = id / 2;
96 mm1[0] = reg;
97 msgs[0].len = 1;
98 msgs[1].len = 1;
99 msgs[0].buf = mm1;
100 msgs[1].buf = mm2;
102 i2c_transfer(i2c, msgs, 2);
104 return mm2[0];
107 static int i2c_readregs(struct i2c_adapter *i2c, u8 id, u8 reg, u8 * buf, u8 len)
109 u8 mm1[] = { reg };
110 struct i2c_msg msgs[2] = {
111 {.addr = id / 2,.flags = 0,.buf = mm1,.len = 1},
112 {.addr = id / 2,.flags = I2C_M_RD,.buf = buf,.len = len}
115 if (i2c_transfer(i2c, msgs, 2) != 2)
116 return -EIO;
118 return 0;
121 static int i2c_writereg(struct i2c_adapter *i2c, u8 id, u8 reg, u8 val)
123 u8 msg[2] = { reg, val };
124 struct i2c_msg msgs;
126 msgs.flags = 0;
127 msgs.addr = id / 2;
128 msgs.len = 2;
129 msgs.buf = msg;
130 return i2c_transfer(i2c, &msgs, 1);
133 static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
135 struct budget_av *budget_av = (struct budget_av *) ca->data;
136 int result;
138 if (slot != 0)
139 return -EINVAL;
141 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
142 udelay(1);
144 result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 1);
145 if (result == -ETIMEDOUT) {
146 ciintf_slot_shutdown(ca, slot);
147 printk(KERN_INFO "budget-av: cam ejected 1\n");
149 return result;
152 static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
154 struct budget_av *budget_av = (struct budget_av *) ca->data;
155 int result;
157 if (slot != 0)
158 return -EINVAL;
160 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
161 udelay(1);
163 result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 1);
164 if (result == -ETIMEDOUT) {
165 ciintf_slot_shutdown(ca, slot);
166 printk(KERN_INFO "budget-av: cam ejected 2\n");
168 return result;
171 static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
173 struct budget_av *budget_av = (struct budget_av *) ca->data;
174 int result;
176 if (slot != 0)
177 return -EINVAL;
179 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
180 udelay(1);
182 result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 3, 1, 0, 0);
183 if ((result == -ETIMEDOUT) || ((result == 0xff) && ((address & 3) < 2))) {
184 ciintf_slot_shutdown(ca, slot);
185 printk(KERN_INFO "budget-av: cam ejected 3\n");
186 return -ETIMEDOUT;
188 return result;
191 static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
193 struct budget_av *budget_av = (struct budget_av *) ca->data;
194 int result;
196 if (slot != 0)
197 return -EINVAL;
199 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
200 udelay(1);
202 result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 3, 1, value, 0, 0);
203 if (result == -ETIMEDOUT) {
204 ciintf_slot_shutdown(ca, slot);
205 printk(KERN_INFO "budget-av: cam ejected 5\n");
207 return result;
210 static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
212 struct budget_av *budget_av = (struct budget_av *) ca->data;
213 struct saa7146_dev *saa = budget_av->budget.dev;
215 if (slot != 0)
216 return -EINVAL;
218 dprintk(1, "ciintf_slot_reset\n");
219 budget_av->slot_status = SLOTSTATUS_RESET;
221 saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */
223 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); /* Vcc off */
224 msleep(2);
225 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); /* Vcc on */
226 msleep(20); /* 20 ms Vcc settling time */
228 saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO); /* enable card */
229 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
230 msleep(20);
232 /* reinitialise the frontend if necessary */
233 if (budget_av->reinitialise_demod)
234 dvb_frontend_reinitialise(budget_av->budget.dvb_frontend);
236 /* set tda10021 back to original clock configuration on reset */
237 if (budget_av->tda10021_poclkp) {
238 tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa0);
239 budget_av->tda10021_ts_enabled = 0;
242 return 0;
245 static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
247 struct budget_av *budget_av = (struct budget_av *) ca->data;
248 struct saa7146_dev *saa = budget_av->budget.dev;
250 if (slot != 0)
251 return -EINVAL;
253 dprintk(1, "ciintf_slot_shutdown\n");
255 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
256 budget_av->slot_status = SLOTSTATUS_NONE;
258 /* set tda10021 back to original clock configuration when cam removed */
259 if (budget_av->tda10021_poclkp) {
260 tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa0);
261 budget_av->tda10021_ts_enabled = 0;
263 return 0;
266 static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
268 struct budget_av *budget_av = (struct budget_av *) ca->data;
269 struct saa7146_dev *saa = budget_av->budget.dev;
271 if (slot != 0)
272 return -EINVAL;
274 dprintk(1, "ciintf_slot_ts_enable: %d\n", budget_av->slot_status);
276 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
278 /* tda10021 seems to need a different TS clock config when data is routed to the CAM */
279 if (budget_av->tda10021_poclkp) {
280 tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa1);
281 budget_av->tda10021_ts_enabled = 1;
284 return 0;
287 static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
289 struct budget_av *budget_av = (struct budget_av *) ca->data;
290 struct saa7146_dev *saa = budget_av->budget.dev;
291 int result;
293 if (slot != 0)
294 return -EINVAL;
296 /* test the card detect line - needs to be done carefully
297 * since it never goes high for some CAMs on this interface (e.g. topuptv) */
298 if (budget_av->slot_status == SLOTSTATUS_NONE) {
299 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
300 udelay(1);
301 if (saa7146_read(saa, PSR) & MASK_06) {
302 if (budget_av->slot_status == SLOTSTATUS_NONE) {
303 budget_av->slot_status = SLOTSTATUS_PRESENT;
304 printk(KERN_INFO "budget-av: cam inserted A\n");
307 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
310 /* We also try and read from IO memory to work round the above detection bug. If
311 * there is no CAM, we will get a timeout. Only done if there is no cam
312 * present, since this test actually breaks some cams :(
314 * if the CI interface is not open, we also do the above test since we
315 * don't care if the cam has problems - we'll be resetting it on open() anyway */
316 if ((budget_av->slot_status == SLOTSTATUS_NONE) || (!open)) {
317 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
318 result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1);
319 if ((result >= 0) && (budget_av->slot_status == SLOTSTATUS_NONE)) {
320 budget_av->slot_status = SLOTSTATUS_PRESENT;
321 printk(KERN_INFO "budget-av: cam inserted B\n");
322 } else if (result < 0) {
323 if (budget_av->slot_status != SLOTSTATUS_NONE) {
324 ciintf_slot_shutdown(ca, slot);
325 printk(KERN_INFO "budget-av: cam ejected 5\n");
326 return 0;
331 /* read from attribute memory in reset/ready state to know when the CAM is ready */
332 if (budget_av->slot_status == SLOTSTATUS_RESET) {
333 result = ciintf_read_attribute_mem(ca, slot, 0);
334 if (result == 0x1d) {
335 budget_av->slot_status = SLOTSTATUS_READY;
339 /* work out correct return code */
340 if (budget_av->slot_status != SLOTSTATUS_NONE) {
341 if (budget_av->slot_status & SLOTSTATUS_READY) {
342 return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
344 return DVB_CA_EN50221_POLL_CAM_PRESENT;
346 return 0;
349 static int ciintf_init(struct budget_av *budget_av)
351 struct saa7146_dev *saa = budget_av->budget.dev;
352 int result;
354 memset(&budget_av->ca, 0, sizeof(struct dvb_ca_en50221));
356 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
357 saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO);
358 saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO);
359 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
361 /* Enable DEBI pins */
362 saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16) | 0x800);
364 /* register CI interface */
365 budget_av->ca.owner = THIS_MODULE;
366 budget_av->ca.read_attribute_mem = ciintf_read_attribute_mem;
367 budget_av->ca.write_attribute_mem = ciintf_write_attribute_mem;
368 budget_av->ca.read_cam_control = ciintf_read_cam_control;
369 budget_av->ca.write_cam_control = ciintf_write_cam_control;
370 budget_av->ca.slot_reset = ciintf_slot_reset;
371 budget_av->ca.slot_shutdown = ciintf_slot_shutdown;
372 budget_av->ca.slot_ts_enable = ciintf_slot_ts_enable;
373 budget_av->ca.poll_slot_status = ciintf_poll_slot_status;
374 budget_av->ca.data = budget_av;
375 budget_av->budget.ci_present = 1;
376 budget_av->slot_status = SLOTSTATUS_NONE;
378 if ((result = dvb_ca_en50221_init(&budget_av->budget.dvb_adapter,
379 &budget_av->ca, 0, 1)) != 0) {
380 printk(KERN_ERR "budget-av: ci initialisation failed.\n");
381 goto error;
384 printk(KERN_INFO "budget-av: ci interface initialised.\n");
385 return 0;
387 error:
388 saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16));
389 return result;
392 static void ciintf_deinit(struct budget_av *budget_av)
394 struct saa7146_dev *saa = budget_av->budget.dev;
396 saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
397 saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT);
398 saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
399 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
401 /* release the CA device */
402 dvb_ca_en50221_release(&budget_av->ca);
404 /* disable DEBI pins */
405 saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16));
409 static const u8 saa7113_tab[] = {
410 0x01, 0x08,
411 0x02, 0xc0,
412 0x03, 0x33,
413 0x04, 0x00,
414 0x05, 0x00,
415 0x06, 0xeb,
416 0x07, 0xe0,
417 0x08, 0x28,
418 0x09, 0x00,
419 0x0a, 0x80,
420 0x0b, 0x47,
421 0x0c, 0x40,
422 0x0d, 0x00,
423 0x0e, 0x01,
424 0x0f, 0x44,
426 0x10, 0x08,
427 0x11, 0x0c,
428 0x12, 0x7b,
429 0x13, 0x00,
430 0x15, 0x00, 0x16, 0x00, 0x17, 0x00,
432 0x57, 0xff,
433 0x40, 0x82, 0x58, 0x00, 0x59, 0x54, 0x5a, 0x07,
434 0x5b, 0x83, 0x5e, 0x00,
435 0xff
438 static int saa7113_init(struct budget_av *budget_av)
440 struct budget *budget = &budget_av->budget;
441 struct saa7146_dev *saa = budget->dev;
442 const u8 *data = saa7113_tab;
444 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI);
445 msleep(200);
447 if (i2c_writereg(&budget->i2c_adap, 0x4a, 0x01, 0x08) != 1) {
448 dprintk(1, "saa7113 not found on KNC card\n");
449 return -ENODEV;
452 dprintk(1, "saa7113 detected and initializing\n");
454 while (*data != 0xff) {
455 i2c_writereg(&budget->i2c_adap, 0x4a, *data, *(data + 1));
456 data += 2;
459 dprintk(1, "saa7113 status=%02x\n", i2c_readreg(&budget->i2c_adap, 0x4a, 0x1f));
461 return 0;
464 static int saa7113_setinput(struct budget_av *budget_av, int input)
466 struct budget *budget = &budget_av->budget;
468 if (1 != budget_av->has_saa7113)
469 return -ENODEV;
471 if (input == 1) {
472 i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc7);
473 i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x80);
474 } else if (input == 0) {
475 i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc0);
476 i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x00);
477 } else
478 return -EINVAL;
480 budget_av->cur_input = input;
481 return 0;
485 static int philips_su1278_ty_ci_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
487 u8 aclk = 0;
488 u8 bclk = 0;
489 u8 m1;
491 aclk = 0xb5;
492 if (srate < 2000000)
493 bclk = 0x86;
494 else if (srate < 5000000)
495 bclk = 0x89;
496 else if (srate < 15000000)
497 bclk = 0x8f;
498 else if (srate < 45000000)
499 bclk = 0x95;
501 m1 = 0x14;
502 if (srate < 4000000)
503 m1 = 0x10;
505 stv0299_writereg(fe, 0x13, aclk);
506 stv0299_writereg(fe, 0x14, bclk);
507 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
508 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
509 stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
510 stv0299_writereg(fe, 0x0f, 0x80 | m1);
512 return 0;
515 static int philips_su1278_ty_ci_tuner_set_params(struct dvb_frontend *fe,
516 struct dvb_frontend_parameters *params)
518 u32 div;
519 u8 buf[4];
520 struct budget *budget = (struct budget *) fe->dvb->priv;
521 struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
523 if ((params->frequency < 950000) || (params->frequency > 2150000))
524 return -EINVAL;
526 div = (params->frequency + (125 - 1)) / 125; // round correctly
527 buf[0] = (div >> 8) & 0x7f;
528 buf[1] = div & 0xff;
529 buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
530 buf[3] = 0x20;
532 if (params->u.qpsk.symbol_rate < 4000000)
533 buf[3] |= 1;
535 if (params->frequency < 1250000)
536 buf[3] |= 0;
537 else if (params->frequency < 1550000)
538 buf[3] |= 0x40;
539 else if (params->frequency < 2050000)
540 buf[3] |= 0x80;
541 else if (params->frequency < 2150000)
542 buf[3] |= 0xC0;
544 if (fe->ops.i2c_gate_ctrl)
545 fe->ops.i2c_gate_ctrl(fe, 1);
546 if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
547 return -EIO;
548 return 0;
551 #define MIN2(a,b) ((a) < (b) ? (a) : (b))
552 #define MIN3(a,b,c) MIN2(MIN2(a,b),c)
554 static int philips_su1278sh2_tua6100_tuner_set_params(struct dvb_frontend *fe,
555 struct dvb_frontend_parameters *params)
557 u8 reg0 [2] = { 0x00, 0x00 };
558 u8 reg1 [4] = { 0x01, 0x00, 0x00, 0x00 };
559 u8 reg2 [3] = { 0x02, 0x00, 0x00 };
560 int _fband;
561 int first_ZF;
562 int R, A, N, P, M;
563 struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = NULL,.len = 0 };
564 int freq = params->frequency;
565 struct budget *budget = (struct budget *) fe->dvb->priv;
567 first_ZF = (freq) / 1000;
569 if (abs(MIN2(abs(first_ZF-1190),abs(first_ZF-1790))) <
570 abs(MIN3(abs(first_ZF-1202),abs(first_ZF-1542),abs(first_ZF-1890))))
571 _fband = 2;
572 else
573 _fband = 3;
575 if (_fband == 2) {
576 if (((first_ZF >= 950) && (first_ZF < 1350)) ||
577 ((first_ZF >= 1430) && (first_ZF < 1950)))
578 reg0[1] = 0x07;
579 else if (((first_ZF >= 1350) && (first_ZF < 1430)) ||
580 ((first_ZF >= 1950) && (first_ZF < 2150)))
581 reg0[1] = 0x0B;
584 if(_fband == 3) {
585 if (((first_ZF >= 950) && (first_ZF < 1350)) ||
586 ((first_ZF >= 1455) && (first_ZF < 1950)))
587 reg0[1] = 0x07;
588 else if (((first_ZF >= 1350) && (first_ZF < 1420)) ||
589 ((first_ZF >= 1950) && (first_ZF < 2150)))
590 reg0[1] = 0x0B;
591 else if ((first_ZF >= 1420) && (first_ZF < 1455))
592 reg0[1] = 0x0F;
595 if (first_ZF > 1525)
596 reg1[1] |= 0x80;
597 else
598 reg1[1] &= 0x7F;
600 if (_fband == 2) {
601 if (first_ZF > 1430) { /* 1430MHZ */
602 reg1[1] &= 0xCF; /* N2 */
603 reg2[1] &= 0xCF; /* R2 */
604 reg2[1] |= 0x10;
605 } else {
606 reg1[1] &= 0xCF; /* N2 */
607 reg1[1] |= 0x20;
608 reg2[1] &= 0xCF; /* R2 */
609 reg2[1] |= 0x10;
613 if (_fband == 3) {
614 if ((first_ZF >= 1455) &&
615 (first_ZF < 1630)) {
616 reg1[1] &= 0xCF; /* N2 */
617 reg1[1] |= 0x20;
618 reg2[1] &= 0xCF; /* R2 */
619 } else {
620 if (first_ZF < 1455) {
621 reg1[1] &= 0xCF; /* N2 */
622 reg1[1] |= 0x20;
623 reg2[1] &= 0xCF; /* R2 */
624 reg2[1] |= 0x10;
625 } else {
626 if (first_ZF >= 1630) {
627 reg1[1] &= 0xCF; /* N2 */
628 reg2[1] &= 0xCF; /* R2 */
629 reg2[1] |= 0x10;
635 /* set ports, enable P0 for symbol rates > 4Ms/s */
636 if (params->u.qpsk.symbol_rate >= 4000000)
637 reg1[1] |= 0x0c;
638 else
639 reg1[1] |= 0x04;
641 reg2[1] |= 0x0c;
643 R = 64;
644 A = 64;
645 P = 64; //32
647 M = (freq * R) / 4; /* in Mhz */
648 N = (M - A * 1000) / (P * 1000);
650 reg1[1] |= (N >> 9) & 0x03;
651 reg1[2] = (N >> 1) & 0xff;
652 reg1[3] = (N << 7) & 0x80;
654 reg2[1] |= (R >> 8) & 0x03;
655 reg2[2] = R & 0xFF; /* R */
657 reg1[3] |= A & 0x7f; /* A */
659 if (P == 64)
660 reg1[1] |= 0x40; /* Prescaler 64/65 */
662 reg0[1] |= 0x03;
664 /* already enabled - do not reenable i2c repeater or TX fails */
665 if (fe->ops.i2c_gate_ctrl)
666 fe->ops.i2c_gate_ctrl(fe, 1);
667 msg.buf = reg0;
668 msg.len = sizeof(reg0);
669 if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
670 return -EIO;
672 if (fe->ops.i2c_gate_ctrl)
673 fe->ops.i2c_gate_ctrl(fe, 1);
674 msg.buf = reg1;
675 msg.len = sizeof(reg1);
676 if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
677 return -EIO;
679 if (fe->ops.i2c_gate_ctrl)
680 fe->ops.i2c_gate_ctrl(fe, 1);
681 msg.buf = reg2;
682 msg.len = sizeof(reg2);
683 if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
684 return -EIO;
686 return 0;
689 static u8 typhoon_cinergy1200s_inittab[] = {
690 0x01, 0x15,
691 0x02, 0x30,
692 0x03, 0x00,
693 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
694 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
695 0x06, 0x40, /* DAC not used, set to high impendance mode */
696 0x07, 0x00, /* DAC LSB */
697 0x08, 0x40, /* DiSEqC off */
698 0x09, 0x00, /* FIFO */
699 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
700 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
701 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
702 0x10, 0x3f, // AGC2 0x3d
703 0x11, 0x84,
704 0x12, 0xb9,
705 0x15, 0xc9, // lock detector threshold
706 0x16, 0x00,
707 0x17, 0x00,
708 0x18, 0x00,
709 0x19, 0x00,
710 0x1a, 0x00,
711 0x1f, 0x50,
712 0x20, 0x00,
713 0x21, 0x00,
714 0x22, 0x00,
715 0x23, 0x00,
716 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
717 0x29, 0x1e, // 1/2 threshold
718 0x2a, 0x14, // 2/3 threshold
719 0x2b, 0x0f, // 3/4 threshold
720 0x2c, 0x09, // 5/6 threshold
721 0x2d, 0x05, // 7/8 threshold
722 0x2e, 0x01,
723 0x31, 0x1f, // test all FECs
724 0x32, 0x19, // viterbi and synchro search
725 0x33, 0xfc, // rs control
726 0x34, 0x93, // error control
727 0x0f, 0x92,
728 0xff, 0xff
731 static struct stv0299_config typhoon_config = {
732 .demod_address = 0x68,
733 .inittab = typhoon_cinergy1200s_inittab,
734 .mclk = 88000000UL,
735 .invert = 0,
736 .skip_reinit = 0,
737 .lock_output = STV0229_LOCKOUTPUT_1,
738 .volt13_op0_op1 = STV0299_VOLT13_OP0,
739 .min_delay_ms = 100,
740 .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
744 static struct stv0299_config cinergy_1200s_config = {
745 .demod_address = 0x68,
746 .inittab = typhoon_cinergy1200s_inittab,
747 .mclk = 88000000UL,
748 .invert = 0,
749 .skip_reinit = 0,
750 .lock_output = STV0229_LOCKOUTPUT_0,
751 .volt13_op0_op1 = STV0299_VOLT13_OP0,
752 .min_delay_ms = 100,
753 .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
756 static struct stv0299_config cinergy_1200s_1894_0010_config = {
757 .demod_address = 0x68,
758 .inittab = typhoon_cinergy1200s_inittab,
759 .mclk = 88000000UL,
760 .invert = 1,
761 .skip_reinit = 0,
762 .lock_output = STV0229_LOCKOUTPUT_1,
763 .volt13_op0_op1 = STV0299_VOLT13_OP0,
764 .min_delay_ms = 100,
765 .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
768 static int philips_cu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
770 struct budget *budget = (struct budget *) fe->dvb->priv;
771 u8 buf[4];
772 struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
774 #define TUNER_MUL 62500
776 u32 div = (params->frequency + 36125000 + TUNER_MUL / 2) / TUNER_MUL;
778 buf[0] = (div >> 8) & 0x7f;
779 buf[1] = div & 0xff;
780 buf[2] = 0x86;
781 buf[3] = (params->frequency < 150000000 ? 0x01 :
782 params->frequency < 445000000 ? 0x02 : 0x04);
784 if (fe->ops.i2c_gate_ctrl)
785 fe->ops.i2c_gate_ctrl(fe, 1);
786 if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
787 return -EIO;
788 return 0;
791 static struct tda10021_config philips_cu1216_config = {
792 .demod_address = 0x0c,
798 static int philips_tu1216_tuner_init(struct dvb_frontend *fe)
800 struct budget *budget = (struct budget *) fe->dvb->priv;
801 static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab };
802 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) };
804 // setup PLL configuration
805 if (fe->ops.i2c_gate_ctrl)
806 fe->ops.i2c_gate_ctrl(fe, 1);
807 if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
808 return -EIO;
809 msleep(1);
811 return 0;
814 static int philips_tu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
816 struct budget *budget = (struct budget *) fe->dvb->priv;
817 u8 tuner_buf[4];
818 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,.len =
819 sizeof(tuner_buf) };
820 int tuner_frequency = 0;
821 u8 band, cp, filter;
823 // determine charge pump
824 tuner_frequency = params->frequency + 36166000;
825 if (tuner_frequency < 87000000)
826 return -EINVAL;
827 else if (tuner_frequency < 130000000)
828 cp = 3;
829 else if (tuner_frequency < 160000000)
830 cp = 5;
831 else if (tuner_frequency < 200000000)
832 cp = 6;
833 else if (tuner_frequency < 290000000)
834 cp = 3;
835 else if (tuner_frequency < 420000000)
836 cp = 5;
837 else if (tuner_frequency < 480000000)
838 cp = 6;
839 else if (tuner_frequency < 620000000)
840 cp = 3;
841 else if (tuner_frequency < 830000000)
842 cp = 5;
843 else if (tuner_frequency < 895000000)
844 cp = 7;
845 else
846 return -EINVAL;
848 // determine band
849 if (params->frequency < 49000000)
850 return -EINVAL;
851 else if (params->frequency < 161000000)
852 band = 1;
853 else if (params->frequency < 444000000)
854 band = 2;
855 else if (params->frequency < 861000000)
856 band = 4;
857 else
858 return -EINVAL;
860 // setup PLL filter
861 switch (params->u.ofdm.bandwidth) {
862 case BANDWIDTH_6_MHZ:
863 filter = 0;
864 break;
866 case BANDWIDTH_7_MHZ:
867 filter = 0;
868 break;
870 case BANDWIDTH_8_MHZ:
871 filter = 1;
872 break;
874 default:
875 return -EINVAL;
878 // calculate divisor
879 // ((36166000+((1000000/6)/2)) + Finput)/(1000000/6)
880 tuner_frequency = (((params->frequency / 1000) * 6) + 217496) / 1000;
882 // setup tuner buffer
883 tuner_buf[0] = (tuner_frequency >> 8) & 0x7f;
884 tuner_buf[1] = tuner_frequency & 0xff;
885 tuner_buf[2] = 0xca;
886 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
888 if (fe->ops.i2c_gate_ctrl)
889 fe->ops.i2c_gate_ctrl(fe, 1);
890 if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
891 return -EIO;
893 msleep(1);
894 return 0;
897 static int philips_tu1216_request_firmware(struct dvb_frontend *fe,
898 const struct firmware **fw, char *name)
900 struct budget *budget = (struct budget *) fe->dvb->priv;
902 return request_firmware(fw, name, &budget->dev->pci->dev);
905 static struct tda1004x_config philips_tu1216_config = {
907 .demod_address = 0x8,
908 .invert = 1,
909 .invert_oclk = 1,
910 .xtal_freq = TDA10046_XTAL_4M,
911 .agc_config = TDA10046_AGC_DEFAULT,
912 .if_freq = TDA10046_FREQ_3617,
913 .request_firmware = philips_tu1216_request_firmware,
916 static u8 philips_sd1878_inittab[] = {
917 0x01, 0x15,
918 0x02, 0x30,
919 0x03, 0x00,
920 0x04, 0x7d,
921 0x05, 0x35,
922 0x06, 0x40,
923 0x07, 0x00,
924 0x08, 0x43,
925 0x09, 0x02,
926 0x0C, 0x51,
927 0x0D, 0x82,
928 0x0E, 0x23,
929 0x10, 0x3f,
930 0x11, 0x84,
931 0x12, 0xb9,
932 0x15, 0xc9,
933 0x16, 0x19,
934 0x17, 0x8c,
935 0x18, 0x59,
936 0x19, 0xf8,
937 0x1a, 0xfe,
938 0x1c, 0x7f,
939 0x1d, 0x00,
940 0x1e, 0x00,
941 0x1f, 0x50,
942 0x20, 0x00,
943 0x21, 0x00,
944 0x22, 0x00,
945 0x23, 0x00,
946 0x28, 0x00,
947 0x29, 0x28,
948 0x2a, 0x14,
949 0x2b, 0x0f,
950 0x2c, 0x09,
951 0x2d, 0x09,
952 0x31, 0x1f,
953 0x32, 0x19,
954 0x33, 0xfc,
955 0x34, 0x93,
956 0xff, 0xff
959 static int philips_sd1878_tda8261_tuner_set_params(struct dvb_frontend *fe,
960 struct dvb_frontend_parameters *params)
962 u8 buf[4];
963 int rc;
964 struct i2c_msg tuner_msg = {.addr=0x60,.flags=0,.buf=buf,.len=sizeof(buf)};
965 struct budget *budget = (struct budget *) fe->dvb->priv;
967 if((params->frequency < 950000) || (params->frequency > 2150000))
968 return -EINVAL;
970 rc=dvb_pll_configure(&dvb_pll_philips_sd1878_tda8261, buf,
971 params->frequency, 0);
972 if(rc < 0) return rc;
974 if (fe->ops.i2c_gate_ctrl)
975 fe->ops.i2c_gate_ctrl(fe, 1);
976 if(i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
977 return -EIO;
979 return 0;
982 static int philips_sd1878_ci_set_symbol_rate(struct dvb_frontend *fe,
983 u32 srate, u32 ratio)
985 u8 aclk = 0;
986 u8 bclk = 0;
987 u8 m1;
989 aclk = 0xb5;
990 if (srate < 2000000)
991 bclk = 0x86;
992 else if (srate < 5000000)
993 bclk = 0x89;
994 else if (srate < 15000000)
995 bclk = 0x8f;
996 else if (srate < 45000000)
997 bclk = 0x95;
999 m1 = 0x14;
1000 if (srate < 4000000)
1001 m1 = 0x10;
1003 stv0299_writereg(fe, 0x0e, 0x23);
1004 stv0299_writereg(fe, 0x0f, 0x94);
1005 stv0299_writereg(fe, 0x10, 0x39);
1006 stv0299_writereg(fe, 0x13, aclk);
1007 stv0299_writereg(fe, 0x14, bclk);
1008 stv0299_writereg(fe, 0x15, 0xc9);
1009 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
1010 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
1011 stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
1012 stv0299_writereg(fe, 0x0f, 0x80 | m1);
1014 return 0;
1017 static struct stv0299_config philips_sd1878_config = {
1018 .demod_address = 0x68,
1019 .inittab = philips_sd1878_inittab,
1020 .mclk = 88000000UL,
1021 .invert = 0,
1022 .skip_reinit = 0,
1023 .lock_output = STV0229_LOCKOUTPUT_1,
1024 .volt13_op0_op1 = STV0299_VOLT13_OP0,
1025 .min_delay_ms = 100,
1026 .set_symbol_rate = philips_sd1878_ci_set_symbol_rate,
1029 static u8 read_pwm(struct budget_av *budget_av)
1031 u8 b = 0xff;
1032 u8 pwm;
1033 struct i2c_msg msg[] = { {.addr = 0x50,.flags = 0,.buf = &b,.len = 1},
1034 {.addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1}
1037 if ((i2c_transfer(&budget_av->budget.i2c_adap, msg, 2) != 2)
1038 || (pwm == 0xff))
1039 pwm = 0x48;
1041 return pwm;
1044 #define SUBID_DVBS_KNC1 0x0010
1045 #define SUBID_DVBS_KNC1_PLUS 0x0011
1046 #define SUBID_DVBS_TYPHOON 0x4f56
1047 #define SUBID_DVBS_CINERGY1200 0x1154
1048 #define SUBID_DVBS_CYNERGY1200N 0x1155
1050 #define SUBID_DVBS_TV_STAR 0x0014
1051 #define SUBID_DVBS_TV_STAR_CI 0x0016
1052 #define SUBID_DVBS_EASYWATCH_1 0x001a
1053 #define SUBID_DVBS_EASYWATCH 0x001e
1054 #define SUBID_DVBC_KNC1 0x0020
1055 #define SUBID_DVBC_KNC1_PLUS 0x0021
1056 #define SUBID_DVBC_CINERGY1200 0x1156
1058 #define SUBID_DVBT_KNC1_PLUS 0x0031
1059 #define SUBID_DVBT_KNC1 0x0030
1060 #define SUBID_DVBT_CINERGY1200 0x1157
1063 static int tda10021_set_frontend(struct dvb_frontend *fe,
1064 struct dvb_frontend_parameters *p)
1066 struct budget_av* budget_av = fe->dvb->priv;
1067 int result;
1069 result = budget_av->tda10021_set_frontend(fe, p);
1070 if (budget_av->tda10021_ts_enabled) {
1071 tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa1);
1072 } else {
1073 tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa0);
1076 return result;
1079 static void frontend_init(struct budget_av *budget_av)
1081 struct saa7146_dev * saa = budget_av->budget.dev;
1082 struct dvb_frontend * fe = NULL;
1084 /* Enable / PowerON Frontend */
1085 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
1087 /* additional setup necessary for the PLUS cards */
1088 switch (saa->pci->subsystem_device) {
1089 case SUBID_DVBS_KNC1_PLUS:
1090 case SUBID_DVBC_KNC1_PLUS:
1091 case SUBID_DVBT_KNC1_PLUS:
1092 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI);
1093 break;
1096 switch (saa->pci->subsystem_device) {
1098 case SUBID_DVBS_KNC1:
1099 case SUBID_DVBS_KNC1_PLUS:
1100 case SUBID_DVBS_EASYWATCH_1:
1101 if (saa->pci->subsystem_vendor == 0x1894) {
1102 fe = dvb_attach(stv0299_attach, &cinergy_1200s_1894_0010_config,
1103 &budget_av->budget.i2c_adap);
1104 if (fe) {
1105 fe->ops.tuner_ops.set_params = philips_su1278sh2_tua6100_tuner_set_params;
1107 } else {
1108 fe = dvb_attach(stv0299_attach, &typhoon_config,
1109 &budget_av->budget.i2c_adap);
1110 if (fe) {
1111 fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
1114 break;
1116 case SUBID_DVBS_TV_STAR:
1117 case SUBID_DVBS_TV_STAR_CI:
1118 case SUBID_DVBS_CYNERGY1200N:
1119 case SUBID_DVBS_EASYWATCH:
1120 fe = dvb_attach(stv0299_attach, &philips_sd1878_config,
1121 &budget_av->budget.i2c_adap);
1122 if (fe) {
1123 fe->ops.tuner_ops.set_params = philips_sd1878_tda8261_tuner_set_params;
1125 break;
1127 case SUBID_DVBS_TYPHOON:
1128 fe = dvb_attach(stv0299_attach, &typhoon_config,
1129 &budget_av->budget.i2c_adap);
1130 if (fe) {
1131 fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
1133 break;
1135 case SUBID_DVBS_CINERGY1200:
1136 fe = dvb_attach(stv0299_attach, &cinergy_1200s_config,
1137 &budget_av->budget.i2c_adap);
1138 if (fe) {
1139 fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
1141 break;
1143 case SUBID_DVBC_KNC1:
1144 case SUBID_DVBC_KNC1_PLUS:
1145 case SUBID_DVBC_CINERGY1200:
1146 budget_av->reinitialise_demod = 1;
1147 fe = dvb_attach(tda10021_attach, &philips_cu1216_config,
1148 &budget_av->budget.i2c_adap,
1149 read_pwm(budget_av));
1150 if (fe) {
1151 budget_av->tda10021_poclkp = 1;
1152 budget_av->tda10021_set_frontend = fe->ops.set_frontend;
1153 fe->ops.set_frontend = tda10021_set_frontend;
1154 fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params;
1156 break;
1158 case SUBID_DVBT_KNC1:
1159 case SUBID_DVBT_KNC1_PLUS:
1160 case SUBID_DVBT_CINERGY1200:
1161 budget_av->reinitialise_demod = 1;
1162 fe = dvb_attach(tda10046_attach, &philips_tu1216_config,
1163 &budget_av->budget.i2c_adap);
1164 if (fe) {
1165 fe->ops.tuner_ops.init = philips_tu1216_tuner_init;
1166 fe->ops.tuner_ops.set_params = philips_tu1216_tuner_set_params;
1168 break;
1171 if (fe == NULL) {
1172 printk(KERN_ERR "budget-av: A frontend driver was not found "
1173 "for device %04x/%04x subsystem %04x/%04x\n",
1174 saa->pci->vendor,
1175 saa->pci->device,
1176 saa->pci->subsystem_vendor,
1177 saa->pci->subsystem_device);
1178 return;
1181 budget_av->budget.dvb_frontend = fe;
1183 if (dvb_register_frontend(&budget_av->budget.dvb_adapter,
1184 budget_av->budget.dvb_frontend)) {
1185 printk(KERN_ERR "budget-av: Frontend registration failed!\n");
1186 dvb_frontend_detach(budget_av->budget.dvb_frontend);
1187 budget_av->budget.dvb_frontend = NULL;
1192 static void budget_av_irq(struct saa7146_dev *dev, u32 * isr)
1194 struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
1196 dprintk(8, "dev: %p, budget_av: %p\n", dev, budget_av);
1198 if (*isr & MASK_10)
1199 ttpci_budget_irq10_handler(dev, isr);
1202 static int budget_av_detach(struct saa7146_dev *dev)
1204 struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
1205 int err;
1207 dprintk(2, "dev: %p\n", dev);
1209 if (1 == budget_av->has_saa7113) {
1210 saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO);
1212 msleep(200);
1214 saa7146_unregister_device(&budget_av->vd, dev);
1217 if (budget_av->budget.ci_present)
1218 ciintf_deinit(budget_av);
1220 if (budget_av->budget.dvb_frontend != NULL) {
1221 dvb_unregister_frontend(budget_av->budget.dvb_frontend);
1222 dvb_frontend_detach(budget_av->budget.dvb_frontend);
1224 err = ttpci_budget_deinit(&budget_av->budget);
1226 kfree(budget_av);
1228 return err;
1231 static struct saa7146_ext_vv vv_data;
1233 static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
1235 struct budget_av *budget_av;
1236 u8 *mac;
1237 int err;
1239 dprintk(2, "dev: %p\n", dev);
1241 if (!(budget_av = kzalloc(sizeof(struct budget_av), GFP_KERNEL)))
1242 return -ENOMEM;
1244 budget_av->has_saa7113 = 0;
1245 budget_av->budget.ci_present = 0;
1247 dev->ext_priv = budget_av;
1249 if ((err = ttpci_budget_init(&budget_av->budget, dev, info, THIS_MODULE))) {
1250 kfree(budget_av);
1251 return err;
1254 /* knc1 initialization */
1255 saa7146_write(dev, DD1_STREAM_B, 0x04000000);
1256 saa7146_write(dev, DD1_INIT, 0x07000600);
1257 saa7146_write(dev, MC2, MASK_09 | MASK_25 | MASK_10 | MASK_26);
1259 if (saa7113_init(budget_av) == 0) {
1260 budget_av->has_saa7113 = 1;
1262 if (0 != saa7146_vv_init(dev, &vv_data)) {
1263 /* fixme: proper cleanup here */
1264 ERR(("cannot init vv subsystem.\n"));
1265 return err;
1268 if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) {
1269 /* fixme: proper cleanup here */
1270 ERR(("cannot register capture v4l2 device.\n"));
1271 return err;
1274 /* beware: this modifies dev->vv ... */
1275 saa7146_set_hps_source_and_sync(dev, SAA7146_HPS_SOURCE_PORT_A,
1276 SAA7146_HPS_SYNC_PORT_A);
1278 saa7113_setinput(budget_av, 0);
1281 /* fixme: find some sane values here... */
1282 saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
1284 mac = budget_av->budget.dvb_adapter.proposed_mac;
1285 if (i2c_readregs(&budget_av->budget.i2c_adap, 0xa0, 0x30, mac, 6)) {
1286 printk(KERN_ERR "KNC1-%d: Could not read MAC from KNC1 card\n",
1287 budget_av->budget.dvb_adapter.num);
1288 memset(mac, 0, 6);
1289 } else {
1290 printk(KERN_INFO "KNC1-%d: MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
1291 budget_av->budget.dvb_adapter.num,
1292 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
1295 budget_av->budget.dvb_adapter.priv = budget_av;
1296 frontend_init(budget_av);
1297 ciintf_init(budget_av);
1299 ttpci_budget_init_hooks(&budget_av->budget);
1301 return 0;
1304 #define KNC1_INPUTS 2
1305 static struct v4l2_input knc1_inputs[KNC1_INPUTS] = {
1306 {0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
1307 {1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
1310 static struct saa7146_extension_ioctls ioctls[] = {
1311 {VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE},
1312 {VIDIOC_G_INPUT, SAA7146_EXCLUSIVE},
1313 {VIDIOC_S_INPUT, SAA7146_EXCLUSIVE},
1314 {0, 0}
1317 static int av_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
1319 struct saa7146_dev *dev = fh->dev;
1320 struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
1322 switch (cmd) {
1323 case VIDIOC_ENUMINPUT:{
1324 struct v4l2_input *i = arg;
1326 dprintk(1, "VIDIOC_ENUMINPUT %d.\n", i->index);
1327 if (i->index < 0 || i->index >= KNC1_INPUTS) {
1328 return -EINVAL;
1330 memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input));
1331 return 0;
1333 case VIDIOC_G_INPUT:{
1334 int *input = (int *) arg;
1336 *input = budget_av->cur_input;
1338 dprintk(1, "VIDIOC_G_INPUT %d.\n", *input);
1339 return 0;
1341 case VIDIOC_S_INPUT:{
1342 int input = *(int *) arg;
1343 dprintk(1, "VIDIOC_S_INPUT %d.\n", input);
1344 return saa7113_setinput(budget_av, input);
1346 default:
1347 return -ENOIOCTLCMD;
1349 return 0;
1352 static struct saa7146_standard standard[] = {
1353 {.name = "PAL",.id = V4L2_STD_PAL,
1354 .v_offset = 0x17,.v_field = 288,
1355 .h_offset = 0x14,.h_pixels = 680,
1356 .v_max_out = 576,.h_max_out = 768 },
1358 {.name = "NTSC",.id = V4L2_STD_NTSC,
1359 .v_offset = 0x16,.v_field = 240,
1360 .h_offset = 0x06,.h_pixels = 708,
1361 .v_max_out = 480,.h_max_out = 640, },
1364 static struct saa7146_ext_vv vv_data = {
1365 .inputs = 2,
1366 .capabilities = 0, // perhaps later: V4L2_CAP_VBI_CAPTURE, but that need tweaking with the saa7113
1367 .flags = 0,
1368 .stds = &standard[0],
1369 .num_stds = sizeof(standard) / sizeof(struct saa7146_standard),
1370 .ioctls = &ioctls[0],
1371 .ioctl = av_ioctl,
1374 static struct saa7146_extension budget_extension;
1376 MAKE_BUDGET_INFO(knc1s, "KNC1 DVB-S", BUDGET_KNC1S);
1377 MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C);
1378 MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T);
1379 MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR);
1380 MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR);
1381 MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S);
1382 MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP);
1383 MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP);
1384 MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP);
1385 MAKE_BUDGET_INFO(cin1200s, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
1386 MAKE_BUDGET_INFO(cin1200sn, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
1387 MAKE_BUDGET_INFO(cin1200c, "Terratec Cinergy 1200 DVB-C", BUDGET_CIN1200C);
1388 MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T);
1390 static struct pci_device_id pci_tbl[] = {
1391 MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x4f56),
1392 MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x0010),
1393 MAKE_EXTENSION_PCI(knc1s, 0x1894, 0x0010),
1394 MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011),
1395 MAKE_EXTENSION_PCI(knc1sp, 0x1894, 0x0011),
1396 MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014),
1397 MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016),
1398 MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e),
1399 MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a),
1400 MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020),
1401 MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021),
1402 MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030),
1403 MAKE_EXTENSION_PCI(knc1tp, 0x1894, 0x0031),
1404 MAKE_EXTENSION_PCI(cin1200s, 0x153b, 0x1154),
1405 MAKE_EXTENSION_PCI(cin1200sn, 0x153b, 0x1155),
1406 MAKE_EXTENSION_PCI(cin1200c, 0x153b, 0x1156),
1407 MAKE_EXTENSION_PCI(cin1200t, 0x153b, 0x1157),
1409 .vendor = 0,
1413 MODULE_DEVICE_TABLE(pci, pci_tbl);
1415 static struct saa7146_extension budget_extension = {
1416 .name = "budget_av",
1417 .flags = SAA7146_I2C_SHORT_DELAY,
1419 .pci_tbl = pci_tbl,
1421 .module = THIS_MODULE,
1422 .attach = budget_av_attach,
1423 .detach = budget_av_detach,
1425 .irq_mask = MASK_10,
1426 .irq_func = budget_av_irq,
1429 static int __init budget_av_init(void)
1431 return saa7146_register_extension(&budget_extension);
1434 static void __exit budget_av_exit(void)
1436 saa7146_unregister_extension(&budget_extension);
1439 module_init(budget_av_init);
1440 module_exit(budget_av_exit);
1442 MODULE_LICENSE("GPL");
1443 MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others");
1444 MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
1445 "budget PCI DVB w/ analog input and CI-module (e.g. the KNC cards)");