Linux-2.6.12-rc2
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / media / dvb / ttpci / budget-av.c
blob14e963206b8901b7baa15d6668a090d36590605e
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 0x4f56: // Typhoon/KNC1 DVB-S budget (stv0299/Philips SU1278(tsa5059))
705 budget_av->budget.dvb_frontend =
706 stv0299_attach(&typhoon_config, &budget_av->budget.i2c_adap);
707 if (budget_av->budget.dvb_frontend != NULL) {
708 break;
710 break;
712 case 0x0020: // KNC1 DVB-C budget (tda10021/Philips CU1216(tua6034))
713 budget_av->budget.dvb_frontend =
714 tda10021_attach(&philips_cu1216_config,
715 &budget_av->budget.i2c_adap, read_pwm(budget_av));
716 if (budget_av->budget.dvb_frontend != NULL) {
717 break;
719 break;
721 case 0x0030: // KNC1 DVB-T budget (tda10046/Philips TU1216(tda6651tt))
722 budget_av->budget.dvb_frontend =
723 tda10046_attach(&philips_tu1216_config, &budget_av->budget.i2c_adap);
724 if (budget_av->budget.dvb_frontend != NULL) {
725 break;
727 break;
729 case 0x1154: // TerraTec Cinergy 1200 DVB-S (stv0299/Philips SU1278(tsa5059))
730 budget_av->budget.dvb_frontend =
731 stv0299_attach(&cinergy_1200s_config, &budget_av->budget.i2c_adap);
732 if (budget_av->budget.dvb_frontend != NULL) {
733 break;
735 break;
737 case 0x1156: // Terratec Cinergy 1200 DVB-C (tda10021/Philips CU1216(tua6034))
738 budget_av->budget.dvb_frontend =
739 tda10021_attach(&philips_cu1216_config,
740 &budget_av->budget.i2c_adap, read_pwm(budget_av));
741 if (budget_av->budget.dvb_frontend) {
742 break;
744 break;
746 case 0x1157: // Terratec Cinergy 1200 DVB-T (tda10046/Philips TU1216(tda6651tt))
747 budget_av->budget.dvb_frontend =
748 tda10046_attach(&philips_tu1216_config, &budget_av->budget.i2c_adap);
749 if (budget_av->budget.dvb_frontend) {
750 break;
752 break;
755 if (budget_av->budget.dvb_frontend == NULL) {
756 printk("budget_av: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
757 budget_av->budget.dev->pci->vendor,
758 budget_av->budget.dev->pci->device,
759 budget_av->budget.dev->pci->subsystem_vendor,
760 budget_av->budget.dev->pci->subsystem_device);
761 } else {
762 if (dvb_register_frontend
763 (budget_av->budget.dvb_adapter, budget_av->budget.dvb_frontend)) {
764 printk("budget-av: Frontend registration failed!\n");
765 if (budget_av->budget.dvb_frontend->ops->release)
766 budget_av->budget.dvb_frontend->ops->release(budget_av->budget.dvb_frontend);
767 budget_av->budget.dvb_frontend = NULL;
773 static void budget_av_irq(struct saa7146_dev *dev, u32 * isr)
775 struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
777 dprintk(8, "dev: %p, budget_av: %p\n", dev, budget_av);
779 if (*isr & MASK_10)
780 ttpci_budget_irq10_handler(dev, isr);
783 static int budget_av_detach(struct saa7146_dev *dev)
785 struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
786 int err;
788 dprintk(2, "dev: %p\n", dev);
790 if (1 == budget_av->has_saa7113) {
791 saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO);
793 msleep(200);
795 saa7146_unregister_device(&budget_av->vd, dev);
798 if (budget_av->budget.ci_present)
799 ciintf_deinit(budget_av);
801 if (budget_av->budget.dvb_frontend != NULL)
802 dvb_unregister_frontend(budget_av->budget.dvb_frontend);
803 err = ttpci_budget_deinit(&budget_av->budget);
805 kfree(budget_av);
807 return err;
810 static struct saa7146_ext_vv vv_data;
812 static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
814 struct budget_av *budget_av;
815 u8 *mac;
816 int err;
818 dprintk(2, "dev: %p\n", dev);
820 if (!(budget_av = kmalloc(sizeof(struct budget_av), GFP_KERNEL)))
821 return -ENOMEM;
823 memset(budget_av, 0, sizeof(struct budget_av));
825 budget_av->budget.ci_present = 0;
827 dev->ext_priv = budget_av;
829 if ((err = ttpci_budget_init(&budget_av->budget, dev, info, THIS_MODULE))) {
830 kfree(budget_av);
831 return err;
834 /* knc1 initialization */
835 saa7146_write(dev, DD1_STREAM_B, 0x04000000);
836 saa7146_write(dev, DD1_INIT, 0x07000600);
837 saa7146_write(dev, MC2, MASK_09 | MASK_25 | MASK_10 | MASK_26);
839 saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTHI);
840 msleep(500);
842 if (0 == saa7113_init(budget_av)) {
843 budget_av->has_saa7113 = 1;
845 if (0 != saa7146_vv_init(dev, &vv_data)) {
846 /* fixme: proper cleanup here */
847 ERR(("cannot init vv subsystem.\n"));
848 return err;
851 if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) {
852 /* fixme: proper cleanup here */
853 ERR(("cannot register capture v4l2 device.\n"));
854 return err;
857 /* beware: this modifies dev->vv ... */
858 saa7146_set_hps_source_and_sync(dev, SAA7146_HPS_SOURCE_PORT_A,
859 SAA7146_HPS_SYNC_PORT_A);
861 saa7113_setinput(budget_av, 0);
862 } else {
863 budget_av->has_saa7113 = 0;
865 saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO);
868 /* fixme: find some sane values here... */
869 saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
871 mac = budget_av->budget.dvb_adapter->proposed_mac;
872 if (i2c_readregs(&budget_av->budget.i2c_adap, 0xa0, 0x30, mac, 6)) {
873 printk("KNC1-%d: Could not read MAC from KNC1 card\n",
874 budget_av->budget.dvb_adapter->num);
875 memset(mac, 0, 6);
876 } else {
877 printk("KNC1-%d: MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
878 budget_av->budget.dvb_adapter->num,
879 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
882 budget_av->budget.dvb_adapter->priv = budget_av;
883 frontend_init(budget_av);
885 if (enable_ci)
886 ciintf_init(budget_av);
888 return 0;
891 #define KNC1_INPUTS 2
892 static struct v4l2_input knc1_inputs[KNC1_INPUTS] = {
893 {0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
894 {1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
897 static struct saa7146_extension_ioctls ioctls[] = {
898 {VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE},
899 {VIDIOC_G_INPUT, SAA7146_EXCLUSIVE},
900 {VIDIOC_S_INPUT, SAA7146_EXCLUSIVE},
901 {0, 0}
904 static int av_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
906 struct saa7146_dev *dev = fh->dev;
907 struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
909 switch (cmd) {
910 case VIDIOC_ENUMINPUT:{
911 struct v4l2_input *i = arg;
913 dprintk(1, "VIDIOC_ENUMINPUT %d.\n", i->index);
914 if (i->index < 0 || i->index >= KNC1_INPUTS) {
915 return -EINVAL;
917 memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input));
918 return 0;
920 case VIDIOC_G_INPUT:{
921 int *input = (int *) arg;
923 *input = budget_av->cur_input;
925 dprintk(1, "VIDIOC_G_INPUT %d.\n", *input);
926 return 0;
928 case VIDIOC_S_INPUT:{
929 int input = *(int *) arg;
930 dprintk(1, "VIDIOC_S_INPUT %d.\n", input);
931 return saa7113_setinput(budget_av, input);
933 default:
934 return -ENOIOCTLCMD;
936 return 0;
939 static struct saa7146_standard standard[] = {
940 {.name = "PAL",.id = V4L2_STD_PAL,
941 .v_offset = 0x17,.v_field = 288,
942 .h_offset = 0x14,.h_pixels = 680,
943 .v_max_out = 576,.h_max_out = 768 },
945 {.name = "NTSC",.id = V4L2_STD_NTSC,
946 .v_offset = 0x16,.v_field = 240,
947 .h_offset = 0x06,.h_pixels = 708,
948 .v_max_out = 480,.h_max_out = 640, },
951 static struct saa7146_ext_vv vv_data = {
952 .inputs = 2,
953 .capabilities = 0, // perhaps later: V4L2_CAP_VBI_CAPTURE, but that need tweaking with the saa7113
954 .flags = 0,
955 .stds = &standard[0],
956 .num_stds = sizeof(standard) / sizeof(struct saa7146_standard),
957 .ioctls = &ioctls[0],
958 .ioctl = av_ioctl,
961 static struct saa7146_extension budget_extension;
963 MAKE_BUDGET_INFO(knc1s, "KNC1 DVB-S", BUDGET_KNC1S);
964 MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C);
965 MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T);
966 MAKE_BUDGET_INFO(cin1200s, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
967 MAKE_BUDGET_INFO(cin1200c, "Terratec Cinergy 1200 DVB-C", BUDGET_CIN1200C);
968 MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T);
970 static struct pci_device_id pci_tbl[] = {
971 MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x4f56),
972 MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020),
973 MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030),
974 MAKE_EXTENSION_PCI(cin1200s, 0x153b, 0x1154),
975 MAKE_EXTENSION_PCI(cin1200c, 0x153b, 0x1156),
976 MAKE_EXTENSION_PCI(cin1200t, 0x153b, 0x1157),
978 .vendor = 0,
982 MODULE_DEVICE_TABLE(pci, pci_tbl);
984 static struct saa7146_extension budget_extension = {
985 .name = "budget dvb /w video in\0",
986 .pci_tbl = pci_tbl,
988 .module = THIS_MODULE,
989 .attach = budget_av_attach,
990 .detach = budget_av_detach,
992 .irq_mask = MASK_10,
993 .irq_func = budget_av_irq,
996 static int __init budget_av_init(void)
998 return saa7146_register_extension(&budget_extension);
1001 static void __exit budget_av_exit(void)
1003 saa7146_unregister_extension(&budget_extension);
1006 module_init(budget_av_init);
1007 module_exit(budget_av_exit);
1009 MODULE_LICENSE("GPL");
1010 MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others");
1011 MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
1012 "budget PCI DVB w/ analog input and CI-module (e.g. the KNC cards)");
1013 module_param_named(enable_ci, enable_ci, int, 0644);
1014 MODULE_PARM_DESC(enable_ci, "Turn on/off CI module (default:off).");