2 * budget-av.c: driver for the SAA7146 based Budget DVB cards
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/
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
54 struct video_device
*vd
;
57 struct tasklet_struct ciintf_irq_tasklet
;
59 struct dvb_ca_en50221 ca
;
62 static int enable_ci
= 0;
65 /****************************************************************************
67 ****************************************************************************/
69 static u8
i2c_readreg(struct i2c_adapter
*i2c
, u8 id
, u8 reg
)
73 struct i2c_msg msgs
[2];
76 msgs
[1].flags
= I2C_M_RD
;
77 msgs
[0].addr
= msgs
[1].addr
= id
/ 2;
84 i2c_transfer(i2c
, msgs
, 2);
89 static int i2c_readregs(struct i2c_adapter
*i2c
, u8 id
, u8 reg
, u8
* buf
, u8 len
)
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)
103 static int i2c_writereg(struct i2c_adapter
*i2c
, u8 id
, u8 reg
, u8 val
)
105 u8 msg
[2] = { reg
, val
};
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
;
123 saa7146_setgpio(budget_av
->budget
.dev
, 1, SAA7146_GPIO_OUTHI
);
126 result
= ttpci_budget_debiread(&budget_av
->budget
, DEBICICAM
, address
& 0xfff, 1, 0, 0);
128 if (result
== -ETIMEDOUT
)
129 budget_av
->slot_status
= 0;
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
;
141 saa7146_setgpio(budget_av
->budget
.dev
, 1, SAA7146_GPIO_OUTHI
);
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;
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
;
159 saa7146_setgpio(budget_av
->budget
.dev
, 1, SAA7146_GPIO_OUTLO
);
162 result
= ttpci_budget_debiread(&budget_av
->budget
, DEBICICAM
, address
& 3, 1, 0, 0);
164 if (result
== -ETIMEDOUT
)
165 budget_av
->slot_status
= 0;
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
;
177 saa7146_setgpio(budget_av
->budget
.dev
, 1, SAA7146_GPIO_OUTLO
);
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;
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
;
196 dprintk(1, "ciintf_slot_reset\n");
199 saa7146_setgpio(saa
, 0, SAA7146_GPIO_OUTHI
);
201 saa7146_setgpio(saa
, 0, SAA7146_GPIO_OUTLO
);
203 while (--max
> 0 && ciintf_read_attribute_mem(ca
, slot
, 0) != 0x1d)
206 ttpci_budget_set_video_port(saa
, BUDGET_VIDEO_PORTB
);
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
;
218 dprintk(1, "ciintf_slot_shutdown\n");
220 ttpci_budget_set_video_port(saa
, BUDGET_VIDEO_PORTB
);
221 budget_av
->slot_status
= 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
;
233 dprintk(1, "ciintf_slot_ts_enable: %d\n", budget_av
->slot_status
);
235 ttpci_budget_set_video_port(saa
, BUDGET_VIDEO_PORTA
);
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
;
248 if (!budget_av
->slot_status
) {
249 saa7146_setgpio(saa
, 3, SAA7146_GPIO_INPUT
);
251 cam
= saa7146_read(saa
, PSR
) & MASK_06
;
252 saa7146_setgpio(saa
, 3, SAA7146_GPIO_OUTLO
);
255 budget_av
->slot_status
= 1;
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
;
268 static int ciintf_init(struct budget_av
*budget_av
)
270 struct saa7146_dev
*saa
= budget_av
->budget
.dev
;
273 memset(&budget_av
->ca
, 0, sizeof(struct dvb_ca_en50221
));
276 saa7146_setgpio(saa
, 1, SAA7146_GPIO_OUTHI
);
277 saa7146_setgpio(saa
, 2, SAA7146_GPIO_OUTLO
);
278 saa7146_setgpio(saa
, 3, SAA7146_GPIO_OUTLO
);
281 saa7146_setgpio(saa
, 0, SAA7146_GPIO_OUTHI
);
283 saa7146_setgpio(saa
, 0, SAA7146_GPIO_OUTLO
);
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");
306 printk("ciintf_init: CI interface initialised\n");
307 budget_av
->budget
.ci_present
= 1;
311 saa7146_write(saa
, MC1
, saa7146_read(saa
, MC1
) | (0x800 << 16));
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
[] = {
353 0x15, 0x00, 0x16, 0x00, 0x17, 0x00,
356 0x40, 0x82, 0x58, 0x00, 0x59, 0x54, 0x5a, 0x07,
357 0x5b, 0x83, 0x5e, 0x00,
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");
371 dprintk(1, "saa7113 detected and initializing\n");
373 while (*data
!= 0xff) {
374 i2c_writereg(&budget
->i2c_adap
, 0x4a, *data
, *(data
+ 1));
378 dprintk(1, "saa7113 status=%02x\n", i2c_readreg(&budget
->i2c_adap
, 0x4a, 0x1f));
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
)
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);
399 budget_av
->cur_input
= input
;
404 static int philips_su1278_ty_ci_set_symbol_rate(struct dvb_frontend
*fe
, u32 srate
, u32 ratio
)
413 else if (srate
< 5000000)
415 else if (srate
< 15000000)
417 else if (srate
< 45000000)
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
);
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
;
440 struct i2c_msg msg
= {.addr
= 0x61,.flags
= 0,.buf
= buf
,.len
= sizeof(buf
) };
442 if ((params
->frequency
< 950000) || (params
->frequency
> 2150000))
445 div
= (params
->frequency
+ (125 - 1)) / 125; // round correctly
446 buf
[0] = (div
>> 8) & 0x7f;
448 buf
[2] = 0x80 | ((div
& 0x18000) >> 10) | 4;
451 if (params
->u
.qpsk
.symbol_rate
< 4000000)
454 if (params
->frequency
< 1250000)
456 else if (params
->frequency
< 1550000)
458 else if (params
->frequency
< 2050000)
460 else if (params
->frequency
< 2150000)
463 if (i2c_transfer(&budget_av
->budget
.i2c_adap
, &msg
, 1) != 1)
468 static u8 typhoon_cinergy1200s_inittab
[] = {
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
483 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on
484 0x15, 0xc9, // lock detector threshold
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
502 0x31, 0x1f, // test all FECs
503 0x32, 0x19, // viterbi and synchro search
504 0x33, 0xfc, // rs control
505 0x34, 0x93, // error control
510 static struct stv0299_config typhoon_config
= {
511 .demod_address
= 0x68,
512 .inittab
= typhoon_cinergy1200s_inittab
,
515 .enhanced_tuning
= 0,
517 .lock_output
= STV0229_LOCKOUTPUT_1
,
518 .volt13_op0_op1
= STV0299_VOLT13_OP0
,
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
,
530 .enhanced_tuning
= 0,
532 .lock_output
= STV0229_LOCKOUTPUT_0
,
533 .volt13_op0_op1
= STV0299_VOLT13_OP0
,
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
;
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;
553 buf
[3] = (params
->frequency
< 174500000 ? 0xa1 :
554 params
->frequency
< 454000000 ? 0x92 : 0x34);
556 if (i2c_transfer(&budget
->i2c_adap
, &msg
, 1) != 1)
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)
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
;
587 struct i2c_msg tuner_msg
= {.addr
= 0x60,.flags
= 0,.buf
= tuner_buf
,.len
=
589 int tuner_frequency
= 0;
592 // determine charge pump
593 tuner_frequency
= params
->frequency
+ 36166000;
594 if (tuner_frequency
< 87000000)
596 else if (tuner_frequency
< 130000000)
598 else if (tuner_frequency
< 160000000)
600 else if (tuner_frequency
< 200000000)
602 else if (tuner_frequency
< 290000000)
604 else if (tuner_frequency
< 420000000)
606 else if (tuner_frequency
< 480000000)
608 else if (tuner_frequency
< 620000000)
610 else if (tuner_frequency
< 830000000)
612 else if (tuner_frequency
< 895000000)
618 if (params
->frequency
< 49000000)
620 else if (params
->frequency
< 161000000)
622 else if (params
->frequency
< 444000000)
624 else if (params
->frequency
< 861000000)
630 switch (params
->u
.ofdm
.bandwidth
) {
631 case BANDWIDTH_6_MHZ
:
635 case BANDWIDTH_7_MHZ
:
639 case BANDWIDTH_8_MHZ
:
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;
655 tuner_buf
[3] = (cp
<< 5) | (filter
<< 3) | band
;
657 if (i2c_transfer(&budget
->i2c_adap
, &tuner_msg
, 1) != 1)
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,
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
)
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)
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
) {
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
) {
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
) {
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
) {
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
) {
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
) {
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
);
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
);
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
;
795 dprintk(2, "dev: %p\n", dev
);
797 if (1 == budget_av
->has_saa7113
) {
798 saa7146_setgpio(dev
, 0, SAA7146_GPIO_OUTLO
);
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
);
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
;
825 dprintk(2, "dev: %p\n", dev
);
827 if (!(budget_av
= kmalloc(sizeof(struct budget_av
), GFP_KERNEL
)))
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
))) {
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
);
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"));
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"));
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);
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
);
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
);
893 ciintf_init(budget_av
);
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
},
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
;
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
) {
924 memcpy(i
, &knc1_inputs
[i
->index
], sizeof(struct v4l2_input
));
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
);
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
);
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
= {
960 .capabilities
= 0, // perhaps later: V4L2_CAP_VBI_CAPTURE, but that need tweaking with the saa7113
962 .stds
= &standard
[0],
963 .num_stds
= sizeof(standard
) / sizeof(struct saa7146_standard
),
964 .ioctls
= &ioctls
[0],
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),
996 MODULE_DEVICE_TABLE(pci
, pci_tbl
);
998 static struct saa7146_extension budget_extension
= {
999 .name
= "budget dvb /w video in\0",
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).");