[PATCH] dvb: modified dvb_register_adapter() to avoid kmalloc/kfree
[linux-2.6/verdex.git] / drivers / media / dvb / ttpci / budget-av.c
blob7891f3f06f04724e41e27b703796dec933bfda37
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 <media/saa7146_vv.h>
41 #include <linux/module.h>
42 #include <linux/errno.h>
43 #include <linux/slab.h>
44 #include <linux/interrupt.h>
45 #include <linux/input.h>
46 #include <linux/spinlock.h>
48 #include "dvb_ca_en50221.h"
50 #define DEBICICAM 0x02420000
52 struct budget_av {
53 struct budget budget;
54 struct video_device *vd;
55 int cur_input;
56 int has_saa7113;
57 struct tasklet_struct ciintf_irq_tasklet;
58 int slot_status;
59 struct dvb_ca_en50221 ca;
62 static int enable_ci = 0;
65 /****************************************************************************
66 * INITIALIZATION
67 ****************************************************************************/
69 static u8 i2c_readreg(struct i2c_adapter *i2c, u8 id, u8 reg)
71 u8 mm1[] = { 0x00 };
72 u8 mm2[] = { 0x00 };
73 struct i2c_msg msgs[2];
75 msgs[0].flags = 0;
76 msgs[1].flags = I2C_M_RD;
77 msgs[0].addr = msgs[1].addr = id / 2;
78 mm1[0] = reg;
79 msgs[0].len = 1;
80 msgs[1].len = 1;
81 msgs[0].buf = mm1;
82 msgs[1].buf = mm2;
84 i2c_transfer(i2c, msgs, 2);
86 return mm2[0];
89 static int i2c_readregs(struct i2c_adapter *i2c, u8 id, u8 reg, u8 * buf, u8 len)
91 u8 mm1[] = { reg };
92 struct i2c_msg msgs[2] = {
93 {.addr = id / 2,.flags = 0,.buf = mm1,.len = 1},
94 {.addr = id / 2,.flags = I2C_M_RD,.buf = buf,.len = len}
97 if (i2c_transfer(i2c, msgs, 2) != 2)
98 return -EIO;
100 return 0;
103 static int i2c_writereg(struct i2c_adapter *i2c, u8 id, u8 reg, u8 val)
105 u8 msg[2] = { reg, val };
106 struct i2c_msg msgs;
108 msgs.flags = 0;
109 msgs.addr = id / 2;
110 msgs.len = 2;
111 msgs.buf = msg;
112 return i2c_transfer(i2c, &msgs, 1);
115 static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
117 struct budget_av *budget_av = (struct budget_av *) ca->data;
118 int result;
120 if (slot != 0)
121 return -EINVAL;
123 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
124 udelay(1);
126 result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 0);
128 if (result == -ETIMEDOUT)
129 budget_av->slot_status = 0;
130 return result;
133 static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
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_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 0);
146 if (result == -ETIMEDOUT)
147 budget_av->slot_status = 0;
148 return result;
151 static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
153 struct budget_av *budget_av = (struct budget_av *) ca->data;
154 int result;
156 if (slot != 0)
157 return -EINVAL;
159 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
160 udelay(1);
162 result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 3, 1, 0, 0);
164 if (result == -ETIMEDOUT)
165 budget_av->slot_status = 0;
166 return result;
169 static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
171 struct budget_av *budget_av = (struct budget_av *) ca->data;
172 int result;
174 if (slot != 0)
175 return -EINVAL;
177 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
178 udelay(1);
180 result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 3, 1, value, 0, 0);
182 if (result == -ETIMEDOUT)
183 budget_av->slot_status = 0;
184 return result;
187 static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
189 struct budget_av *budget_av = (struct budget_av *) ca->data;
190 struct saa7146_dev *saa = budget_av->budget.dev;
191 int max = 20;
193 if (slot != 0)
194 return -EINVAL;
196 dprintk(1, "ciintf_slot_reset\n");
198 /* reset the card */
199 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI);
200 msleep(100);
201 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
203 while (--max > 0 && ciintf_read_attribute_mem(ca, slot, 0) != 0x1d)
204 msleep(100);
206 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
207 return 0;
210 static int ciintf_slot_shutdown(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_shutdown\n");
220 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
221 budget_av->slot_status = 0;
222 return 0;
225 static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
227 struct budget_av *budget_av = (struct budget_av *) ca->data;
228 struct saa7146_dev *saa = budget_av->budget.dev;
230 if (slot != 0)
231 return -EINVAL;
233 dprintk(1, "ciintf_slot_ts_enable: %d\n", budget_av->slot_status);
235 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
236 return 0;
239 static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
241 struct budget_av *budget_av = (struct budget_av *) ca->data;
242 struct saa7146_dev *saa = budget_av->budget.dev;
243 int cam = 0;
245 if (slot != 0)
246 return -EINVAL;
248 if (!budget_av->slot_status) {
249 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
250 udelay(1);
251 cam = saa7146_read(saa, PSR) & MASK_06;
252 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
254 if (cam)
255 budget_av->slot_status = 1;
256 } else if (!open) {
257 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
258 if (ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1) == -ETIMEDOUT)
259 budget_av->slot_status = 0;
262 if (budget_av->slot_status == 1)
263 return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
265 return 0;
268 static int ciintf_init(struct budget_av *budget_av)
270 struct saa7146_dev *saa = budget_av->budget.dev;
271 int result;
273 memset(&budget_av->ca, 0, sizeof(struct dvb_ca_en50221));
275 /* setup GPIOs */
276 saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
277 saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO);
278 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
280 /* Reset the card */
281 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI);
282 msleep(50);
283 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
284 msleep(100);
286 /* Enable DEBI pins */
287 saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16) | 0x800);
289 /* register CI interface */
290 budget_av->ca.owner = THIS_MODULE;
291 budget_av->ca.read_attribute_mem = ciintf_read_attribute_mem;
292 budget_av->ca.write_attribute_mem = ciintf_write_attribute_mem;
293 budget_av->ca.read_cam_control = ciintf_read_cam_control;
294 budget_av->ca.write_cam_control = ciintf_write_cam_control;
295 budget_av->ca.slot_reset = ciintf_slot_reset;
296 budget_av->ca.slot_shutdown = ciintf_slot_shutdown;
297 budget_av->ca.slot_ts_enable = ciintf_slot_ts_enable;
298 budget_av->ca.poll_slot_status = ciintf_poll_slot_status;
299 budget_av->ca.data = budget_av;
300 if ((result = dvb_ca_en50221_init(&budget_av->budget.dvb_adapter,
301 &budget_av->ca, 0, 1)) != 0) {
302 printk("budget_av: CI interface detected, but initialisation failed.\n");
303 goto error;
305 // success!
306 printk("ciintf_init: CI interface initialised\n");
307 budget_av->budget.ci_present = 1;
308 return 0;
310 error:
311 saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16));
312 return result;
315 static void ciintf_deinit(struct budget_av *budget_av)
317 struct saa7146_dev *saa = budget_av->budget.dev;
319 saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
320 saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT);
321 saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
322 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
324 /* release the CA device */
325 dvb_ca_en50221_release(&budget_av->ca);
327 /* disable DEBI pins */
328 saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16));
332 static const u8 saa7113_tab[] = {
333 0x01, 0x08,
334 0x02, 0xc0,
335 0x03, 0x33,
336 0x04, 0x00,
337 0x05, 0x00,
338 0x06, 0xeb,
339 0x07, 0xe0,
340 0x08, 0x28,
341 0x09, 0x00,
342 0x0a, 0x80,
343 0x0b, 0x47,
344 0x0c, 0x40,
345 0x0d, 0x00,
346 0x0e, 0x01,
347 0x0f, 0x44,
349 0x10, 0x08,
350 0x11, 0x0c,
351 0x12, 0x7b,
352 0x13, 0x00,
353 0x15, 0x00, 0x16, 0x00, 0x17, 0x00,
355 0x57, 0xff,
356 0x40, 0x82, 0x58, 0x00, 0x59, 0x54, 0x5a, 0x07,
357 0x5b, 0x83, 0x5e, 0x00,
358 0xff
361 static int saa7113_init(struct budget_av *budget_av)
363 struct budget *budget = &budget_av->budget;
364 const u8 *data = saa7113_tab;
366 if (i2c_writereg(&budget->i2c_adap, 0x4a, 0x01, 0x08) != 1) {
367 dprintk(1, "saa7113 not found on KNC card\n");
368 return -ENODEV;
371 dprintk(1, "saa7113 detected and initializing\n");
373 while (*data != 0xff) {
374 i2c_writereg(&budget->i2c_adap, 0x4a, *data, *(data + 1));
375 data += 2;
378 dprintk(1, "saa7113 status=%02x\n", i2c_readreg(&budget->i2c_adap, 0x4a, 0x1f));
380 return 0;
383 static int saa7113_setinput(struct budget_av *budget_av, int input)
385 struct budget *budget = &budget_av->budget;
387 if (1 != budget_av->has_saa7113)
388 return -ENODEV;
390 if (input == 1) {
391 i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc7);
392 i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x80);
393 } else if (input == 0) {
394 i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc0);
395 i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x00);
396 } else
397 return -EINVAL;
399 budget_av->cur_input = input;
400 return 0;
404 static int philips_su1278_ty_ci_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
406 u8 aclk = 0;
407 u8 bclk = 0;
408 u8 m1;
410 aclk = 0xb5;
411 if (srate < 2000000)
412 bclk = 0x86;
413 else if (srate < 5000000)
414 bclk = 0x89;
415 else if (srate < 15000000)
416 bclk = 0x8f;
417 else if (srate < 45000000)
418 bclk = 0x95;
420 m1 = 0x14;
421 if (srate < 4000000)
422 m1 = 0x10;
424 stv0299_writereg(fe, 0x13, aclk);
425 stv0299_writereg(fe, 0x14, bclk);
426 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
427 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
428 stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
429 stv0299_writereg(fe, 0x0f, 0x80 | m1);
431 return 0;
434 static int philips_su1278_ty_ci_pll_set(struct dvb_frontend *fe,
435 struct dvb_frontend_parameters *params)
437 struct budget_av *budget_av = (struct budget_av *) fe->dvb->priv;
438 u32 div;
439 u8 buf[4];
440 struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
442 if ((params->frequency < 950000) || (params->frequency > 2150000))
443 return -EINVAL;
445 div = (params->frequency + (125 - 1)) / 125; // round correctly
446 buf[0] = (div >> 8) & 0x7f;
447 buf[1] = div & 0xff;
448 buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
449 buf[3] = 0x20;
451 if (params->u.qpsk.symbol_rate < 4000000)
452 buf[3] |= 1;
454 if (params->frequency < 1250000)
455 buf[3] |= 0;
456 else if (params->frequency < 1550000)
457 buf[3] |= 0x40;
458 else if (params->frequency < 2050000)
459 buf[3] |= 0x80;
460 else if (params->frequency < 2150000)
461 buf[3] |= 0xC0;
463 if (i2c_transfer(&budget_av->budget.i2c_adap, &msg, 1) != 1)
464 return -EIO;
465 return 0;
468 static u8 typhoon_cinergy1200s_inittab[] = {
469 0x01, 0x15,
470 0x02, 0x30,
471 0x03, 0x00,
472 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
473 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
474 0x06, 0x40, /* DAC not used, set to high impendance mode */
475 0x07, 0x00, /* DAC LSB */
476 0x08, 0x40, /* DiSEqC off */
477 0x09, 0x00, /* FIFO */
478 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
479 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
480 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
481 0x10, 0x3f, // AGC2 0x3d
482 0x11, 0x84,
483 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on
484 0x15, 0xc9, // lock detector threshold
485 0x16, 0x00,
486 0x17, 0x00,
487 0x18, 0x00,
488 0x19, 0x00,
489 0x1a, 0x00,
490 0x1f, 0x50,
491 0x20, 0x00,
492 0x21, 0x00,
493 0x22, 0x00,
494 0x23, 0x00,
495 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
496 0x29, 0x1e, // 1/2 threshold
497 0x2a, 0x14, // 2/3 threshold
498 0x2b, 0x0f, // 3/4 threshold
499 0x2c, 0x09, // 5/6 threshold
500 0x2d, 0x05, // 7/8 threshold
501 0x2e, 0x01,
502 0x31, 0x1f, // test all FECs
503 0x32, 0x19, // viterbi and synchro search
504 0x33, 0xfc, // rs control
505 0x34, 0x93, // error control
506 0x0f, 0x92,
507 0xff, 0xff
510 static struct stv0299_config typhoon_config = {
511 .demod_address = 0x68,
512 .inittab = typhoon_cinergy1200s_inittab,
513 .mclk = 88000000UL,
514 .invert = 0,
515 .enhanced_tuning = 0,
516 .skip_reinit = 0,
517 .lock_output = STV0229_LOCKOUTPUT_1,
518 .volt13_op0_op1 = STV0299_VOLT13_OP0,
519 .min_delay_ms = 100,
520 .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
521 .pll_set = philips_su1278_ty_ci_pll_set,
525 static struct stv0299_config cinergy_1200s_config = {
526 .demod_address = 0x68,
527 .inittab = typhoon_cinergy1200s_inittab,
528 .mclk = 88000000UL,
529 .invert = 0,
530 .enhanced_tuning = 0,
531 .skip_reinit = 0,
532 .lock_output = STV0229_LOCKOUTPUT_0,
533 .volt13_op0_op1 = STV0299_VOLT13_OP0,
534 .min_delay_ms = 100,
535 .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
536 .pll_set = philips_su1278_ty_ci_pll_set,
540 static int philips_cu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
542 struct budget *budget = (struct budget *) fe->dvb->priv;
543 u8 buf[4];
544 struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
546 #define TUNER_MUL 62500
548 u32 div = (params->frequency + 36125000 + TUNER_MUL / 2) / TUNER_MUL;
550 buf[0] = (div >> 8) & 0x7f;
551 buf[1] = div & 0xff;
552 buf[2] = 0x8e;
553 buf[3] = (params->frequency < 174500000 ? 0xa1 :
554 params->frequency < 454000000 ? 0x92 : 0x34);
556 if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
557 return -EIO;
558 return 0;
561 static struct tda10021_config philips_cu1216_config = {
562 .demod_address = 0x0c,
563 .pll_set = philips_cu1216_pll_set,
569 static int philips_tu1216_pll_init(struct dvb_frontend *fe)
571 struct budget *budget = (struct budget *) fe->dvb->priv;
572 static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab };
573 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) };
575 // setup PLL configuration
576 if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
577 return -EIO;
578 msleep(1);
580 return 0;
583 static int philips_tu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
585 struct budget *budget = (struct budget *) fe->dvb->priv;
586 u8 tuner_buf[4];
587 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,.len =
588 sizeof(tuner_buf) };
589 int tuner_frequency = 0;
590 u8 band, cp, filter;
592 // determine charge pump
593 tuner_frequency = params->frequency + 36166000;
594 if (tuner_frequency < 87000000)
595 return -EINVAL;
596 else if (tuner_frequency < 130000000)
597 cp = 3;
598 else if (tuner_frequency < 160000000)
599 cp = 5;
600 else if (tuner_frequency < 200000000)
601 cp = 6;
602 else if (tuner_frequency < 290000000)
603 cp = 3;
604 else if (tuner_frequency < 420000000)
605 cp = 5;
606 else if (tuner_frequency < 480000000)
607 cp = 6;
608 else if (tuner_frequency < 620000000)
609 cp = 3;
610 else if (tuner_frequency < 830000000)
611 cp = 5;
612 else if (tuner_frequency < 895000000)
613 cp = 7;
614 else
615 return -EINVAL;
617 // determine band
618 if (params->frequency < 49000000)
619 return -EINVAL;
620 else if (params->frequency < 161000000)
621 band = 1;
622 else if (params->frequency < 444000000)
623 band = 2;
624 else if (params->frequency < 861000000)
625 band = 4;
626 else
627 return -EINVAL;
629 // setup PLL filter
630 switch (params->u.ofdm.bandwidth) {
631 case BANDWIDTH_6_MHZ:
632 filter = 0;
633 break;
635 case BANDWIDTH_7_MHZ:
636 filter = 0;
637 break;
639 case BANDWIDTH_8_MHZ:
640 filter = 1;
641 break;
643 default:
644 return -EINVAL;
647 // calculate divisor
648 // ((36166000+((1000000/6)/2)) + Finput)/(1000000/6)
649 tuner_frequency = (((params->frequency / 1000) * 6) + 217496) / 1000;
651 // setup tuner buffer
652 tuner_buf[0] = (tuner_frequency >> 8) & 0x7f;
653 tuner_buf[1] = tuner_frequency & 0xff;
654 tuner_buf[2] = 0xca;
655 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
657 if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
658 return -EIO;
660 msleep(1);
661 return 0;
664 static int philips_tu1216_request_firmware(struct dvb_frontend *fe,
665 const struct firmware **fw, char *name)
667 struct budget *budget = (struct budget *) fe->dvb->priv;
669 return request_firmware(fw, name, &budget->dev->pci->dev);
672 static struct tda1004x_config philips_tu1216_config = {
674 .demod_address = 0x8,
675 .invert = 1,
676 .invert_oclk = 1,
677 .pll_init = philips_tu1216_pll_init,
678 .pll_set = philips_tu1216_pll_set,
679 .request_firmware = philips_tu1216_request_firmware,
685 static u8 read_pwm(struct budget_av *budget_av)
687 u8 b = 0xff;
688 u8 pwm;
689 struct i2c_msg msg[] = { {.addr = 0x50,.flags = 0,.buf = &b,.len = 1},
690 {.addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1}
693 if ((i2c_transfer(&budget_av->budget.i2c_adap, msg, 2) != 2)
694 || (pwm == 0xff))
695 pwm = 0x48;
697 return pwm;
701 static void frontend_init(struct budget_av *budget_av)
703 switch (budget_av->budget.dev->pci->subsystem_device) {
704 case 0x0011: // KNC1 DVB-S Plus budget with AV IN (stv0299/Philips SU1278(tsa5059))
705 saa7146_write(budget_av->budget.dev, GPIO_CTRL, 0x50000000); // Enable / PowerON Frontend
706 case 0x4f56: // Typhoon/KNC1 DVB-S budget (stv0299/Philips SU1278(tsa5059))
707 case 0x0010: // KNC1 DVB-S budget (stv0299/Philips SU1278(tsa5059))
708 budget_av->budget.dvb_frontend =
709 stv0299_attach(&typhoon_config, &budget_av->budget.i2c_adap);
710 if (budget_av->budget.dvb_frontend != NULL) {
711 break;
713 break;
715 case 0x0021: // KNC1 DVB-C Plus budget with AV IN (tda10021/Philips CU1216(tua6034))
716 saa7146_write(budget_av->budget.dev, GPIO_CTRL, 0x50000000); // Enable / PowerON Frontend
717 case 0x0020: // KNC1 DVB-C budget (tda10021/Philips CU1216(tua6034))
718 budget_av->budget.dvb_frontend =
719 tda10021_attach(&philips_cu1216_config,
720 &budget_av->budget.i2c_adap, read_pwm(budget_av));
721 if (budget_av->budget.dvb_frontend != NULL) {
722 break;
724 break;
726 case 0x0031: // KNC1 DVB-T Plus budget with AV IN (tda10046/Philips TU1216(tda6651tt))
727 saa7146_write(budget_av->budget.dev, GPIO_CTRL, 0x50000000); // Enable / PowerON Frontend
728 case 0x0030: // KNC1 DVB-T budget (tda10046/Philips TU1216(tda6651tt))
729 budget_av->budget.dvb_frontend =
730 tda10046_attach(&philips_tu1216_config, &budget_av->budget.i2c_adap);
731 if (budget_av->budget.dvb_frontend != NULL) {
732 break;
734 break;
736 case 0x1154: // TerraTec Cinergy 1200 DVB-S (stv0299/Philips SU1278(tsa5059))
737 budget_av->budget.dvb_frontend =
738 stv0299_attach(&cinergy_1200s_config, &budget_av->budget.i2c_adap);
739 if (budget_av->budget.dvb_frontend != NULL) {
740 break;
742 break;
744 case 0x1156: // Terratec Cinergy 1200 DVB-C (tda10021/Philips CU1216(tua6034))
745 budget_av->budget.dvb_frontend =
746 tda10021_attach(&philips_cu1216_config,
747 &budget_av->budget.i2c_adap, read_pwm(budget_av));
748 if (budget_av->budget.dvb_frontend) {
749 break;
751 break;
753 case 0x1157: // Terratec Cinergy 1200 DVB-T (tda10046/Philips TU1216(tda6651tt))
754 budget_av->budget.dvb_frontend =
755 tda10046_attach(&philips_tu1216_config, &budget_av->budget.i2c_adap);
756 if (budget_av->budget.dvb_frontend) {
757 break;
759 break;
762 if (budget_av->budget.dvb_frontend == NULL) {
763 printk("budget_av: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
764 budget_av->budget.dev->pci->vendor,
765 budget_av->budget.dev->pci->device,
766 budget_av->budget.dev->pci->subsystem_vendor,
767 budget_av->budget.dev->pci->subsystem_device);
768 } else {
769 if (dvb_register_frontend
770 (&budget_av->budget.dvb_adapter, budget_av->budget.dvb_frontend)) {
771 printk("budget-av: Frontend registration failed!\n");
772 if (budget_av->budget.dvb_frontend->ops->release)
773 budget_av->budget.dvb_frontend->ops->release(budget_av->budget.dvb_frontend);
774 budget_av->budget.dvb_frontend = NULL;
780 static void budget_av_irq(struct saa7146_dev *dev, u32 * isr)
782 struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
784 dprintk(8, "dev: %p, budget_av: %p\n", dev, budget_av);
786 if (*isr & MASK_10)
787 ttpci_budget_irq10_handler(dev, isr);
790 static int budget_av_detach(struct saa7146_dev *dev)
792 struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
793 int err;
795 dprintk(2, "dev: %p\n", dev);
797 if (1 == budget_av->has_saa7113) {
798 saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO);
800 msleep(200);
802 saa7146_unregister_device(&budget_av->vd, dev);
805 if (budget_av->budget.ci_present)
806 ciintf_deinit(budget_av);
808 if (budget_av->budget.dvb_frontend != NULL)
809 dvb_unregister_frontend(budget_av->budget.dvb_frontend);
810 err = ttpci_budget_deinit(&budget_av->budget);
812 kfree(budget_av);
814 return err;
817 static struct saa7146_ext_vv vv_data;
819 static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
821 struct budget_av *budget_av;
822 u8 *mac;
823 int err;
825 dprintk(2, "dev: %p\n", dev);
827 if (!(budget_av = kmalloc(sizeof(struct budget_av), GFP_KERNEL)))
828 return -ENOMEM;
830 memset(budget_av, 0, sizeof(struct budget_av));
832 budget_av->budget.ci_present = 0;
834 dev->ext_priv = budget_av;
836 if ((err = ttpci_budget_init(&budget_av->budget, dev, info, THIS_MODULE))) {
837 kfree(budget_av);
838 return err;
841 /* knc1 initialization */
842 saa7146_write(dev, DD1_STREAM_B, 0x04000000);
843 saa7146_write(dev, DD1_INIT, 0x07000600);
844 saa7146_write(dev, MC2, MASK_09 | MASK_25 | MASK_10 | MASK_26);
846 saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTHI);
847 msleep(500);
849 if (0 == saa7113_init(budget_av)) {
850 budget_av->has_saa7113 = 1;
852 if (0 != saa7146_vv_init(dev, &vv_data)) {
853 /* fixme: proper cleanup here */
854 ERR(("cannot init vv subsystem.\n"));
855 return err;
858 if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) {
859 /* fixme: proper cleanup here */
860 ERR(("cannot register capture v4l2 device.\n"));
861 return err;
864 /* beware: this modifies dev->vv ... */
865 saa7146_set_hps_source_and_sync(dev, SAA7146_HPS_SOURCE_PORT_A,
866 SAA7146_HPS_SYNC_PORT_A);
868 saa7113_setinput(budget_av, 0);
869 } else {
870 budget_av->has_saa7113 = 0;
872 saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO);
875 /* fixme: find some sane values here... */
876 saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
878 mac = budget_av->budget.dvb_adapter.proposed_mac;
879 if (i2c_readregs(&budget_av->budget.i2c_adap, 0xa0, 0x30, mac, 6)) {
880 printk("KNC1-%d: Could not read MAC from KNC1 card\n",
881 budget_av->budget.dvb_adapter.num);
882 memset(mac, 0, 6);
883 } else {
884 printk("KNC1-%d: MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
885 budget_av->budget.dvb_adapter.num,
886 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
889 budget_av->budget.dvb_adapter.priv = budget_av;
890 frontend_init(budget_av);
892 if (enable_ci)
893 ciintf_init(budget_av);
895 return 0;
898 #define KNC1_INPUTS 2
899 static struct v4l2_input knc1_inputs[KNC1_INPUTS] = {
900 {0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
901 {1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
904 static struct saa7146_extension_ioctls ioctls[] = {
905 {VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE},
906 {VIDIOC_G_INPUT, SAA7146_EXCLUSIVE},
907 {VIDIOC_S_INPUT, SAA7146_EXCLUSIVE},
908 {0, 0}
911 static int av_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
913 struct saa7146_dev *dev = fh->dev;
914 struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
916 switch (cmd) {
917 case VIDIOC_ENUMINPUT:{
918 struct v4l2_input *i = arg;
920 dprintk(1, "VIDIOC_ENUMINPUT %d.\n", i->index);
921 if (i->index < 0 || i->index >= KNC1_INPUTS) {
922 return -EINVAL;
924 memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input));
925 return 0;
927 case VIDIOC_G_INPUT:{
928 int *input = (int *) arg;
930 *input = budget_av->cur_input;
932 dprintk(1, "VIDIOC_G_INPUT %d.\n", *input);
933 return 0;
935 case VIDIOC_S_INPUT:{
936 int input = *(int *) arg;
937 dprintk(1, "VIDIOC_S_INPUT %d.\n", input);
938 return saa7113_setinput(budget_av, input);
940 default:
941 return -ENOIOCTLCMD;
943 return 0;
946 static struct saa7146_standard standard[] = {
947 {.name = "PAL",.id = V4L2_STD_PAL,
948 .v_offset = 0x17,.v_field = 288,
949 .h_offset = 0x14,.h_pixels = 680,
950 .v_max_out = 576,.h_max_out = 768 },
952 {.name = "NTSC",.id = V4L2_STD_NTSC,
953 .v_offset = 0x16,.v_field = 240,
954 .h_offset = 0x06,.h_pixels = 708,
955 .v_max_out = 480,.h_max_out = 640, },
958 static struct saa7146_ext_vv vv_data = {
959 .inputs = 2,
960 .capabilities = 0, // perhaps later: V4L2_CAP_VBI_CAPTURE, but that need tweaking with the saa7113
961 .flags = 0,
962 .stds = &standard[0],
963 .num_stds = sizeof(standard) / sizeof(struct saa7146_standard),
964 .ioctls = &ioctls[0],
965 .ioctl = av_ioctl,
968 static struct saa7146_extension budget_extension;
970 MAKE_BUDGET_INFO(knc1s, "KNC1 DVB-S", BUDGET_KNC1S);
971 MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C);
972 MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T);
973 MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP);
974 MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP);
975 MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP);
976 MAKE_BUDGET_INFO(cin1200s, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
977 MAKE_BUDGET_INFO(cin1200c, "Terratec Cinergy 1200 DVB-C", BUDGET_CIN1200C);
978 MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T);
980 static struct pci_device_id pci_tbl[] = {
981 MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x4f56),
982 MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x0010),
983 MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011),
984 MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020),
985 MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021),
986 MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030),
987 MAKE_EXTENSION_PCI(knc1tp, 0x1894, 0x0031),
988 MAKE_EXTENSION_PCI(cin1200s, 0x153b, 0x1154),
989 MAKE_EXTENSION_PCI(cin1200c, 0x153b, 0x1156),
990 MAKE_EXTENSION_PCI(cin1200t, 0x153b, 0x1157),
992 .vendor = 0,
996 MODULE_DEVICE_TABLE(pci, pci_tbl);
998 static struct saa7146_extension budget_extension = {
999 .name = "budget dvb /w video in\0",
1000 .pci_tbl = pci_tbl,
1002 .module = THIS_MODULE,
1003 .attach = budget_av_attach,
1004 .detach = budget_av_detach,
1006 .irq_mask = MASK_10,
1007 .irq_func = budget_av_irq,
1010 static int __init budget_av_init(void)
1012 return saa7146_register_extension(&budget_extension);
1015 static void __exit budget_av_exit(void)
1017 saa7146_unregister_extension(&budget_extension);
1020 module_init(budget_av_init);
1021 module_exit(budget_av_exit);
1023 MODULE_LICENSE("GPL");
1024 MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others");
1025 MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
1026 "budget PCI DVB w/ analog input and CI-module (e.g. the KNC cards)");
1027 module_param_named(enable_ci, enable_ci, int, 0644);
1028 MODULE_PARM_DESC(enable_ci, "Turn on/off CI module (default:off).");