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);
173 static struct saa7146_ext_vv vv_data;
175 static int budget_av_attach (struct saa7146_dev* dev,
176 struct saa7146_pci_extension_data *info)
178 struct budget_av *budget_av;
179 struct budget_info *bi = info->ext_priv;
182 DEB_EE(("dev: %p\n",dev));
184 if (bi->type != BUDGET_KNC1) {
188 if (!(budget_av = kmalloc(sizeof(struct budget_av), GFP_KERNEL)))
191 memset(budget_av, 0, sizeof(struct budget_av));
193 if ((err = ttpci_budget_init(&budget_av->budget, dev, info))) {
198 dev->ext_priv = budget_av;
200 /* knc1 initialization */
201 saa7146_write(dev, DD1_STREAM_B, 0x04000000);
202 saa7146_write(dev, DD1_INIT, 0x07000600);
203 saa7146_write(dev, MC2, MASK_09 | MASK_25 | MASK_10 | MASK_26);
205 //test_knc_ci(av7110);
207 saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTHI);
210 if ((err = saa7113_init (budget_av))) {
211 /* fixme: proper cleanup here */
212 ERR(("cannot init saa7113.\n"));
216 if ( 0 != saa7146_vv_init(dev,&vv_data)) {
217 /* fixme: proper cleanup here */
218 ERR(("cannot init vv subsystem.\n"));
222 if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1",
225 /* fixme: proper cleanup here */
226 ERR(("cannot register capture v4l2 device.\n"));
230 /* beware: this modifies dev->vv ... */
231 saa7146_set_hps_source_and_sync(dev, SAA7146_HPS_SOURCE_PORT_A,
232 SAA7146_HPS_SYNC_PORT_A);
234 saa7113_setinput (budget_av, 0);
236 /* what is this? since we don't support open()/close()
237 notifications, we simply put this into the release handler... */
239 saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO);
240 set_current_state(TASK_INTERRUPTIBLE);
241 schedule_timeout (20);
243 /* fixme: find some sane values here... */
244 saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
251 #define KNC1_INPUTS 2
252 static struct v4l2_input knc1_inputs[KNC1_INPUTS] = {
253 { 0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
254 { 1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
258 static struct saa7146_extension_ioctls ioctls[] = {
259 { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
260 { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
261 { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
266 static int av_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
268 struct saa7146_dev *dev = fh->dev;
269 struct budget_av *budget_av = (struct budget_av*) dev->ext_priv;
271 struct saa7146_vv *vv = dev->vv_data;
274 case VIDIOC_ENUMINPUT:
276 struct v4l2_input *i = arg;
278 DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index));
279 if( i->index < 0 || i->index >= KNC1_INPUTS) {
282 memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input));
287 int *input = (int *)arg;
289 *input = budget_av->cur_input;
291 DEB_EE(("VIDIOC_G_INPUT %d.\n",*input));
296 int input = *(int *)arg;
297 DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
298 return saa7113_setinput (budget_av, input);
302 DEB2(printk("does not handle this ioctl.\n"));
309 static struct saa7146_standard standard[] = {
311 .name = "PAL", .id = V4L2_STD_PAL,
312 .v_offset = 0x17, .v_field = 288, .v_calc = 576,
313 .h_offset = 0x14, .h_pixels = 680, .h_calc = 680+1,
314 .v_max_out = 576, .h_max_out = 768,
316 .name = "NTSC", .id = V4L2_STD_NTSC,
317 .v_offset = 0x16, .v_field = 240, .v_calc = 480,
318 .h_offset = 0x06, .h_pixels = 708, .h_calc = 708+1,
319 .v_max_out = 480, .h_max_out = 640,
323 static struct saa7146_ext_vv vv_data = {
325 .capabilities = 0, // perhaps later: V4L2_CAP_VBI_CAPTURE, but that need tweaking with the saa7113
327 .stds = &standard[0],
328 .num_stds = sizeof(standard)/sizeof(struct saa7146_standard),
329 .ioctls = &ioctls[0],
335 static struct saa7146_extension budget_extension;
338 MAKE_BUDGET_INFO(knc1, "KNC1 DVB-S", BUDGET_KNC1);
340 static struct pci_device_id pci_tbl [] = {
341 MAKE_EXTENSION_PCI(knc1, 0x1131, 0x4f56),
347 MODULE_DEVICE_TABLE(pci, pci_tbl);
349 static struct saa7146_extension budget_extension = {
350 .name = "budget dvb /w video in\0",
353 .module = THIS_MODULE,
354 .attach = budget_av_attach,
355 .detach = budget_av_detach,
358 .irq_func = ttpci_budget_irq10_handler,
362 static int __init budget_av_init(void)
366 if (saa7146_register_extension(&budget_extension))
373 static void __exit budget_av_exit(void)
376 saa7146_unregister_extension(&budget_extension);
379 module_init(budget_av_init);
380 module_exit(budget_av_exit);
382 MODULE_LICENSE("GPL");
383 MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others");
384 MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
385 "budget PCI DVB w/ analog input (e.g. the KNC cards)");