2 * budget-av.c: driver for the SAA7146 based Budget DVB cards
5 * Compiled from various sources by Michael Hunold <michael@mihu.de>
7 * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
9 * Copyright (C) 1999-2002 Ralph Metzler
10 * & Marcus Metzler for convergence integrated media GmbH
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
30 * the project's page is at http://www.linuxtv.org/dvb/
33 #include <media/saa7146_vv.h>
36 #include "dvb_functions.h"
40 struct video_device vd
;
44 /****************************************************************************
46 ****************************************************************************/
49 static u8
i2c_readreg (struct dvb_i2c_bus
*i2c
, u8 id
, u8 reg
)
53 struct i2c_msg msgs
[2];
56 msgs
[1].flags
= I2C_M_RD
;
57 msgs
[0].addr
= msgs
[1].addr
=id
/2;
59 msgs
[0].len
= 1; msgs
[1].len
= 1;
60 msgs
[0].buf
= mm1
; msgs
[1].buf
= mm2
;
62 i2c
->xfer(i2c
, msgs
, 2);
68 static int i2c_writereg (struct dvb_i2c_bus
*i2c
, u8 id
, u8 reg
, u8 val
)
70 u8 msg
[2]={ reg
, val
};
77 return i2c
->xfer (i2c
, &msgs
, 1);
81 static const u8 saa7113_tab
[] = {
102 0x15, 0x00, 0x16, 0x00, 0x17, 0x00,
105 0x40, 0x82, 0x58, 0x00, 0x59, 0x54, 0x5a, 0x07,
106 0x5b, 0x83, 0x5e, 0x00,
111 static int saa7113_init (struct budget_av
*budget_av
)
113 struct budget
*budget
= &budget_av
->budget
;
114 const u8
*data
= saa7113_tab
;
116 if (i2c_writereg (budget
->i2c_bus
, 0x4a, 0x01, 0x08) != 1) {
117 DEB_D(("saa7113: not found on KNC card\n"));
121 INFO(("saa7113: detected and initializing\n"));
123 while (*data
!= 0xff) {
124 i2c_writereg(budget
->i2c_bus
, 0x4a, *data
, *(data
+1));
128 DEB_D(("saa7113: status=%02x\n",
129 i2c_readreg(budget
->i2c_bus
, 0x4a, 0x1f)));
135 static int saa7113_setinput (struct budget_av
*budget_av
, int input
)
137 struct budget
*budget
= &budget_av
->budget
;
140 i2c_writereg(budget
->i2c_bus
, 0x4a, 0x02, 0xc7);
141 i2c_writereg(budget
->i2c_bus
, 0x4a, 0x09, 0x80);
142 } else if (input
== 0) {
143 i2c_writereg(budget
->i2c_bus
, 0x4a, 0x02, 0xc0);
144 i2c_writereg(budget
->i2c_bus
, 0x4a, 0x09, 0x00);
148 budget_av
->cur_input
= input
;
153 static int budget_av_detach (struct saa7146_dev
*dev
)
155 struct budget_av
*budget_av
= (struct budget_av
*) dev
->ext_priv
;
158 DEB_EE(("dev: %p\n",dev
));
160 saa7146_setgpio(dev
, 0, SAA7146_GPIO_OUTLO
);
164 saa7146_unregister_device (&budget_av
->vd
, dev
);
166 err
= ttpci_budget_deinit (&budget_av
->budget
);
174 static int budget_av_attach (struct saa7146_dev
* dev
,
175 struct saa7146_pci_extension_data
*info
)
177 struct budget_av
*budget_av
;
178 struct budget_info
*bi
= info
->ext_priv
;
181 DEB_EE(("dev: %p\n",dev
));
183 if (bi
->type
!= BUDGET_KNC1
) {
187 if (!(budget_av
= kmalloc(sizeof(struct budget_av
), GFP_KERNEL
)))
190 memset(budget_av
, 0, sizeof(struct budget_av
));
192 if ((err
= ttpci_budget_init(&budget_av
->budget
, dev
, info
))) {
197 dev
->ext_priv
= budget_av
;
199 /* knc1 initialization */
200 saa7146_write(dev
, DD1_STREAM_B
, 0x04000000);
201 saa7146_write(dev
, DD1_INIT
, 0x07000600);
202 saa7146_write(dev
, MC2
, MASK_09
| MASK_25
| MASK_10
| MASK_26
);
204 //test_knc_ci(av7110);
206 saa7146_setgpio(dev
, 0, SAA7146_GPIO_OUTHI
);
209 if ((err
= saa7113_init (budget_av
))) {
210 budget_av_detach(dev
);
214 saa7146_vv_init(dev
);
215 if ((err
= saa7146_register_device(&budget_av
->vd
, dev
, "knc1",
218 ERR(("cannot register capture v4l2 device.\n"));
219 budget_av_detach(dev
);
223 /* beware: this modifies dev->vv ... */
224 saa7146_set_hps_source_and_sync(dev
, SAA7146_HPS_SOURCE_PORT_A
,
225 SAA7146_HPS_SYNC_PORT_A
);
227 saa7113_setinput (budget_av
, 0);
229 /* what is this? since we don't support open()/close()
230 notifications, we simply put this into the release handler... */
232 saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO);
233 set_current_state(TASK_INTERRUPTIBLE);
234 schedule_timeout (20);
236 /* fixme: find some sane values here... */
237 saa7146_write(dev
, PCI_BT_V1
, 0x1c00101f);
244 #define KNC1_INPUTS 2
245 static struct v4l2_input knc1_inputs
[KNC1_INPUTS
] = {
246 { 0, "Composite", V4L2_INPUT_TYPE_TUNER
, 1, 0, V4L2_STD_PAL_BG
|V4L2_STD_NTSC_M
, 0 },
247 { 1, "S-Video", V4L2_INPUT_TYPE_CAMERA
, 2, 0, V4L2_STD_PAL_BG
|V4L2_STD_NTSC_M
, 0 },
251 static struct saa7146_extension_ioctls ioctls
[] = {
252 { VIDIOC_ENUMINPUT
, SAA7146_EXCLUSIVE
},
253 { VIDIOC_G_INPUT
, SAA7146_EXCLUSIVE
},
254 { VIDIOC_S_INPUT
, SAA7146_EXCLUSIVE
},
259 static int av_ioctl(struct saa7146_dev
*dev
, unsigned int cmd
, void *arg
)
261 struct budget_av
*budget_av
= (struct budget_av
*) dev
->ext_priv
;
263 struct saa7146_vv *vv = dev->vv_data;
266 case VIDIOC_ENUMINPUT
:
268 struct v4l2_input
*i
= arg
;
270 DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i
->index
));
271 if( i
->index
< 0 || i
->index
>= KNC1_INPUTS
) {
274 memcpy(i
, &knc1_inputs
[i
->index
], sizeof(struct v4l2_input
));
279 int *input
= (int *)arg
;
281 *input
= budget_av
->cur_input
;
283 DEB_EE(("VIDIOC_G_INPUT %d.\n",*input
));
288 int input
= *(int *)arg
;
289 DEB_EE(("VIDIOC_S_INPUT %d.\n", input
));
290 return saa7113_setinput (budget_av
, input
);
294 DEB2(printk("does not handle this ioctl.\n"));
301 static struct saa7146_standard standard
[] = {
302 { "PAL", V4L2_STD_PAL
, SAA7146_PAL_VALUES
},
303 { "NTSC", V4L2_STD_NTSC
, SAA7146_NTSC_VALUES
},
307 static struct saa7146_ext_vv vv_data
= {
309 .capabilities
= 0, // perhaps later: V4L2_CAP_VBI_CAPTURE, but that need tweaking with the saa7113
311 .stds
= &standard
[0],
312 .num_stds
= sizeof(standard
)/sizeof(struct saa7146_standard
),
313 .ioctls
= &ioctls
[0],
319 static struct saa7146_extension budget_extension
;
322 MAKE_BUDGET_INFO(knc1
, "KNC1 DVB-S", BUDGET_KNC1
);
324 static struct pci_device_id pci_tbl
[] = {
325 MAKE_EXTENSION_PCI(knc1
, 0x1131, 0x4f56),
331 MODULE_DEVICE_TABLE(pci
, pci_tbl
);
333 static struct saa7146_extension budget_extension
= {
334 .name
= "budget dvb /w video in\0",
337 .module
= THIS_MODULE
,
338 .attach
= budget_av_attach
,
339 .detach
= budget_av_detach
,
341 .ext_vv_data
= &vv_data
,
344 .irq_func
= ttpci_budget_irq10_handler
,
348 static int __init
budget_av_init(void)
352 if (saa7146_register_extension(&budget_extension
))
359 static void __exit
budget_av_exit(void)
362 saa7146_unregister_extension(&budget_extension
);
365 module_init(budget_av_init
);
366 module_exit(budget_av_exit
);
368 MODULE_LICENSE("GPL");
369 MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others");
370 MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
371 "budget PCI DVB w/ analog input (e.g. the KNC cards)");