aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2005-09-06 18:19:37 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-07 19:58:01 -0400
commitd203a7eca85101f0a8ce1dc139ee91196142da36 (patch)
tree83c7d467ef3b6e3e9a2b9ad56ee4f5b2f8d76aa5
parent0bb6fcc13ae4fad98e0d610458975e47be0d2203 (diff)
[PATCH] Indycam / VINO drivers
Rewrite of the Indycam / VINO video v4l2 drivers for the SGI Indy. Signed-off-by: Ralf Baechle <ralf@linux-mips.org> Signed-off-by: Mikael Nousiainen <tmnousia@cc.hut.fi> Cc: <video4linux-list@redhat.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/media/video/Makefile2
-rw-r--r--drivers/media/video/indycam.c412
-rw-r--r--drivers/media/video/indycam.h112
-rw-r--r--drivers/media/video/saa7191.c512
-rw-r--r--drivers/media/video/saa7191.h139
-rw-r--r--drivers/media/video/vino.c4273
-rw-r--r--drivers/media/video/vino.h61
7 files changed, 5319 insertions, 192 deletions
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 810e7aac0a53..3e6f5347da21 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -29,7 +29,7 @@ obj-$(CONFIG_VIDEO_ZORAN_LML33R10) += saa7114.o adv7170.o zr36060.o
29obj-$(CONFIG_VIDEO_ZORAN) += zr36067.o videocodec.o 29obj-$(CONFIG_VIDEO_ZORAN) += zr36067.o videocodec.o
30obj-$(CONFIG_VIDEO_PMS) += pms.o 30obj-$(CONFIG_VIDEO_PMS) += pms.o
31obj-$(CONFIG_VIDEO_PLANB) += planb.o 31obj-$(CONFIG_VIDEO_PLANB) += planb.o
32obj-$(CONFIG_VIDEO_VINO) += vino.o 32obj-$(CONFIG_VIDEO_VINO) += vino.o saa7191.o indycam.o
33obj-$(CONFIG_VIDEO_STRADIS) += stradis.o 33obj-$(CONFIG_VIDEO_STRADIS) += stradis.o
34obj-$(CONFIG_VIDEO_CPIA) += cpia.o 34obj-$(CONFIG_VIDEO_CPIA) += cpia.o
35obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o 35obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o
diff --git a/drivers/media/video/indycam.c b/drivers/media/video/indycam.c
new file mode 100644
index 000000000000..b2b0384cd4b9
--- /dev/null
+++ b/drivers/media/video/indycam.c
@@ -0,0 +1,412 @@
1/*
2 * indycam.c - Silicon Graphics IndyCam digital camera driver
3 *
4 * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
5 * Copyright (C) 2004,2005 Mikael Nousiainen <tmnousia@cc.hut.fi>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/delay.h>
15#include <linux/errno.h>
16#include <linux/fs.h>
17#include <linux/kernel.h>
18#include <linux/major.h>
19#include <linux/slab.h>
20#include <linux/mm.h>
21#include <linux/sched.h>
22
23#include <linux/videodev.h>
24/* IndyCam decodes stream of photons into digital image representation ;-) */
25#include <linux/video_decoder.h>
26#include <linux/i2c.h>
27
28#include "indycam.h"
29
30//#define INDYCAM_DEBUG
31
32#define INDYCAM_MODULE_VERSION "0.0.3"
33
34MODULE_DESCRIPTION("SGI IndyCam driver");
35MODULE_VERSION(INDYCAM_MODULE_VERSION);
36MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
37MODULE_LICENSE("GPL");
38
39#ifdef INDYCAM_DEBUG
40#define dprintk(x...) printk("IndyCam: " x);
41#define indycam_regdump(client) indycam_regdump_debug(client)
42#else
43#define dprintk(x...)
44#define indycam_regdump(client)
45#endif
46
47#define VINO_ADAPTER (I2C_ALGO_SGI | I2C_HW_SGI_VINO)
48
49struct indycam {
50 struct i2c_client *client;
51 int version;
52};
53
54static struct i2c_driver i2c_driver_indycam;
55
56static const unsigned char initseq[] = {
57 INDYCAM_CONTROL_AGCENA, /* INDYCAM_CONTROL */
58 INDYCAM_SHUTTER_DEFAULT, /* INDYCAM_SHUTTER */
59 INDYCAM_GAIN_DEFAULT, /* INDYCAM_GAIN */
60 0x00, /* INDYCAM_BRIGHTNESS (read-only) */
61 INDYCAM_RED_BALANCE_DEFAULT, /* INDYCAM_RED_BALANCE */
62 INDYCAM_BLUE_BALANCE_DEFAULT, /* INDYCAM_BLUE_BALANCE */
63 INDYCAM_RED_SATURATION_DEFAULT, /* INDYCAM_RED_SATURATION */
64 INDYCAM_BLUE_SATURATION_DEFAULT,/* INDYCAM_BLUE_SATURATION */
65};
66
67/* IndyCam register handling */
68
69static int indycam_read_reg(struct i2c_client *client, unsigned char reg,
70 unsigned char *value)
71{
72 int ret;
73
74 if (reg == INDYCAM_RESET) {
75 dprintk("indycam_read_reg(): "
76 "skipping write-only register %d\n", reg);
77 *value = 0;
78 return 0;
79 }
80
81 ret = i2c_smbus_read_byte_data(client, reg);
82 if (ret < 0) {
83 printk(KERN_ERR "IndyCam: indycam_read_reg(): read failed, "
84 "register = 0x%02x\n", reg);
85 return ret;
86 }
87
88 *value = (unsigned char)ret;
89
90 return 0;
91}
92
93static int indycam_write_reg(struct i2c_client *client, unsigned char reg,
94 unsigned char value)
95{
96 int err;
97
98 if ((reg == INDYCAM_BRIGHTNESS)
99 || (reg == INDYCAM_VERSION)) {
100 dprintk("indycam_write_reg(): "
101 "skipping read-only register %d\n", reg);
102 return 0;
103 }
104
105 dprintk("Writing Reg %d = 0x%02x\n", reg, value);
106 err = i2c_smbus_write_byte_data(client, reg, value);
107 if (err) {
108 printk(KERN_ERR "IndyCam: indycam_write_reg(): write failed, "
109 "register = 0x%02x, value = 0x%02x\n", reg, value);
110 }
111 return err;
112}
113
114static int indycam_write_block(struct i2c_client *client, unsigned char reg,
115 unsigned char length, unsigned char *data)
116{
117 unsigned char i;
118 int err;
119
120 for (i = reg; i < length; i++) {
121 err = indycam_write_reg(client, reg + i, data[i]);
122 if (err)
123 return err;
124 }
125
126 return 0;
127}
128
129/* Helper functions */
130
131#ifdef INDYCAM_DEBUG
132static void indycam_regdump_debug(struct i2c_client *client)
133{
134 int i;
135 unsigned char val;
136
137 for (i = 0; i < 9; i++) {
138 indycam_read_reg(client, i, &val);
139 dprintk("Reg %d = 0x%02x\n", i, val);
140 }
141}
142#endif
143
144static int indycam_get_controls(struct i2c_client *client,
145 struct indycam_control *ctrl)
146{
147 unsigned char ctrl_reg;
148
149 indycam_read_reg(client, INDYCAM_CONTROL, &ctrl_reg);
150 ctrl->agc = (ctrl_reg & INDYCAM_CONTROL_AGCENA)
151 ? INDYCAM_VALUE_ENABLED
152 : INDYCAM_VALUE_DISABLED;
153 ctrl->awb = (ctrl_reg & INDYCAM_CONTROL_AWBCTL)
154 ? INDYCAM_VALUE_ENABLED
155 : INDYCAM_VALUE_DISABLED;
156 indycam_read_reg(client, INDYCAM_SHUTTER,
157 (unsigned char *)&ctrl->shutter);
158 indycam_read_reg(client, INDYCAM_GAIN,
159 (unsigned char *)&ctrl->gain);
160 indycam_read_reg(client, INDYCAM_RED_BALANCE,
161 (unsigned char *)&ctrl->red_balance);
162 indycam_read_reg(client, INDYCAM_BLUE_BALANCE,
163 (unsigned char *)&ctrl->blue_balance);
164 indycam_read_reg(client, INDYCAM_RED_SATURATION,
165 (unsigned char *)&ctrl->red_saturation);
166 indycam_read_reg(client, INDYCAM_BLUE_SATURATION,
167 (unsigned char *)&ctrl->blue_saturation);
168 indycam_read_reg(client, INDYCAM_GAMMA,
169 (unsigned char *)&ctrl->gamma);
170
171 return 0;
172}
173
174static int indycam_set_controls(struct i2c_client *client,
175 struct indycam_control *ctrl)
176{
177 unsigned char ctrl_reg;
178
179 indycam_read_reg(client, INDYCAM_CONTROL, &ctrl_reg);
180 if (ctrl->agc != INDYCAM_VALUE_UNCHANGED) {
181 if (ctrl->agc)
182 ctrl_reg |= INDYCAM_CONTROL_AGCENA;
183 else
184 ctrl_reg &= ~INDYCAM_CONTROL_AGCENA;
185 }
186 if (ctrl->awb != INDYCAM_VALUE_UNCHANGED) {
187 if (ctrl->awb)
188 ctrl_reg |= INDYCAM_CONTROL_AWBCTL;
189 else
190 ctrl_reg &= ~INDYCAM_CONTROL_AWBCTL;
191 }
192 indycam_write_reg(client, INDYCAM_CONTROL, ctrl_reg);
193
194 if (ctrl->shutter >= 0)
195 indycam_write_reg(client, INDYCAM_SHUTTER, ctrl->shutter);
196 if (ctrl->gain >= 0)
197 indycam_write_reg(client, INDYCAM_GAIN, ctrl->gain);
198 if (ctrl->red_balance >= 0)
199 indycam_write_reg(client, INDYCAM_RED_BALANCE,
200 ctrl->red_balance);
201 if (ctrl->blue_balance >= 0)
202 indycam_write_reg(client, INDYCAM_BLUE_BALANCE,
203 ctrl->blue_balance);
204 if (ctrl->red_saturation >= 0)
205 indycam_write_reg(client, INDYCAM_RED_SATURATION,
206 ctrl->red_saturation);
207 if (ctrl->blue_saturation >= 0)
208 indycam_write_reg(client, INDYCAM_BLUE_SATURATION,
209 ctrl->blue_saturation);
210 if (ctrl->gamma >= 0)
211 indycam_write_reg(client, INDYCAM_GAMMA, ctrl->gamma);
212
213 return 0;
214}
215
216/* I2C-interface */
217
218static int indycam_attach(struct i2c_adapter *adap, int addr, int kind)
219{
220 int err = 0;
221 struct indycam *camera;
222 struct i2c_client *client;
223
224 printk(KERN_INFO "SGI IndyCam driver version %s\n",
225 INDYCAM_MODULE_VERSION);
226
227 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
228 if (!client)
229 return -ENOMEM;
230 camera = kmalloc(sizeof(struct indycam), GFP_KERNEL);
231 if (!camera) {
232 err = -ENOMEM;
233 goto out_free_client;
234 }
235
236 memset(client, 0, sizeof(struct i2c_client));
237 memset(camera, 0, sizeof(struct indycam));
238
239 client->addr = addr;
240 client->adapter = adap;
241 client->driver = &i2c_driver_indycam;
242 client->flags = 0;
243 strcpy(client->name, "IndyCam client");
244 i2c_set_clientdata(client, camera);
245
246 camera->client = client;
247
248 err = i2c_attach_client(client);
249 if (err)
250 goto out_free_camera;
251
252 camera->version = i2c_smbus_read_byte_data(client, INDYCAM_VERSION);
253 if (camera->version != CAMERA_VERSION_INDY &&
254 camera->version != CAMERA_VERSION_MOOSE) {
255 err = -ENODEV;
256 goto out_detach_client;
257 }
258 printk(KERN_INFO "IndyCam v%d.%d detected\n",
259 INDYCAM_VERSION_MAJOR(camera->version),
260 INDYCAM_VERSION_MINOR(camera->version));
261
262 indycam_regdump(client);
263
264 // initialize
265 err = indycam_write_block(client, 0, sizeof(initseq),
266 (unsigned char *)&initseq);
267 if (err) {
268 printk(KERN_ERR "IndyCam initalization failed\n");
269 err = -EIO;
270 goto out_detach_client;
271 }
272
273 indycam_regdump(client);
274
275 // white balance
276 err = indycam_write_reg(client, INDYCAM_CONTROL,
277 INDYCAM_CONTROL_AGCENA | INDYCAM_CONTROL_AWBCTL);
278 if (err) {
279 printk(KERN_ERR "IndyCam white balance "
280 "initialization failed\n");
281 err = -EIO;
282 goto out_detach_client;
283 }
284
285 indycam_regdump(client);
286
287 printk(KERN_INFO "IndyCam initialized\n");
288
289 return 0;
290
291out_detach_client:
292 i2c_detach_client(client);
293out_free_camera:
294 kfree(camera);
295out_free_client:
296 kfree(client);
297 return err;
298}
299
300static int indycam_probe(struct i2c_adapter *adap)
301{
302 /* Indy specific crap */
303 if (adap->id == VINO_ADAPTER)
304 return indycam_attach(adap, INDYCAM_ADDR, 0);
305 /* Feel free to add probe here :-) */
306 return -ENODEV;
307}
308
309static int indycam_detach(struct i2c_client *client)
310{
311 struct indycam *camera = i2c_get_clientdata(client);
312
313 i2c_detach_client(client);
314 kfree(camera);
315 kfree(client);
316 return 0;
317}
318
319static int indycam_command(struct i2c_client *client, unsigned int cmd,
320 void *arg)
321{
322 // struct indycam *camera = i2c_get_clientdata(client);
323
324 /* The old video_decoder interface just isn't enough,
325 * so we'll use some custom commands. */
326 switch (cmd) {
327 case DECODER_GET_CAPABILITIES: {
328 struct video_decoder_capability *cap = arg;
329
330 cap->flags = VIDEO_DECODER_NTSC;
331 cap->inputs = 1;
332 cap->outputs = 1;
333 break;
334 }
335 case DECODER_GET_STATUS: {
336 int *iarg = arg;
337
338 *iarg = DECODER_STATUS_GOOD | DECODER_STATUS_NTSC |
339 DECODER_STATUS_COLOR;
340 break;
341 }
342 case DECODER_SET_NORM: {
343 int *iarg = arg;
344
345 switch (*iarg) {
346 case VIDEO_MODE_NTSC:
347 break;
348 default:
349 return -EINVAL;
350 }
351 break;
352 }
353 case DECODER_SET_INPUT: {
354 int *iarg = arg;
355
356 if (*iarg != 0)
357 return -EINVAL;
358 break;
359 }
360 case DECODER_SET_OUTPUT: {
361 int *iarg = arg;
362
363 if (*iarg != 0)
364 return -EINVAL;
365 break;
366 }
367 case DECODER_ENABLE_OUTPUT: {
368 /* Always enabled */
369 break;
370 }
371 case DECODER_SET_PICTURE: {
372 // struct video_picture *pic = arg;
373 /* TODO: convert values for indycam_set_controls() */
374 break;
375 }
376 case DECODER_INDYCAM_GET_CONTROLS: {
377 struct indycam_control *ctrl = arg;
378 indycam_get_controls(client, ctrl);
379 }
380 case DECODER_INDYCAM_SET_CONTROLS: {
381 struct indycam_control *ctrl = arg;
382 indycam_set_controls(client, ctrl);
383 }
384 default:
385 return -EINVAL;
386 }
387
388 return 0;
389}
390
391static struct i2c_driver i2c_driver_indycam = {
392 .owner = THIS_MODULE,
393 .name = "indycam",
394 .id = I2C_DRIVERID_INDYCAM,
395 .flags = I2C_DF_NOTIFY,
396 .attach_adapter = indycam_probe,
397 .detach_client = indycam_detach,
398 .command = indycam_command,
399};
400
401static int __init indycam_init(void)
402{
403 return i2c_add_driver(&i2c_driver_indycam);
404}
405
406static void __exit indycam_exit(void)
407{
408 i2c_del_driver(&i2c_driver_indycam);
409}
410
411module_init(indycam_init);
412module_exit(indycam_exit);
diff --git a/drivers/media/video/indycam.h b/drivers/media/video/indycam.h
new file mode 100644
index 000000000000..d9ddb6b79a03
--- /dev/null
+++ b/drivers/media/video/indycam.h
@@ -0,0 +1,112 @@
1/*
2 * indycam.h - Silicon Graphics IndyCam digital camera driver
3 *
4 * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
5 * Copyright (C) 2004,2005 Mikael Nousiainen <tmnousia@cc.hut.fi>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef _INDYCAM_H_
13#define _INDYCAM_H_
14
15/* I2C address for the Guinness Camera */
16#define INDYCAM_ADDR 0x56
17
18/* Camera version */
19#define CAMERA_VERSION_INDY 0x10 /* v1.0 */
20#define CAMERA_VERSION_MOOSE 0x12 /* v1.2 */
21#define INDYCAM_VERSION_MAJOR(x) (((x) & 0xf0) >> 4)
22#define INDYCAM_VERSION_MINOR(x) ((x) & 0x0f)
23
24/* Register bus addresses */
25#define INDYCAM_CONTROL 0x00
26#define INDYCAM_SHUTTER 0x01
27#define INDYCAM_GAIN 0x02
28#define INDYCAM_BRIGHTNESS 0x03 /* read-only */
29#define INDYCAM_RED_BALANCE 0x04
30#define INDYCAM_BLUE_BALANCE 0x05
31#define INDYCAM_RED_SATURATION 0x06
32#define INDYCAM_BLUE_SATURATION 0x07
33#define INDYCAM_GAMMA 0x08
34#define INDYCAM_VERSION 0x0e /* read-only */
35#define INDYCAM_RESET 0x0f /* write-only */
36
37#define INDYCAM_LED 0x46
38#define INDYCAM_ORIENTATION 0x47
39#define INDYCAM_BUTTON 0x48
40
41/* Field definitions of registers */
42#define INDYCAM_CONTROL_AGCENA (1<<0) /* automatic gain control */
43#define INDYCAM_CONTROL_AWBCTL (1<<1) /* automatic white balance */
44 /* 2-3 are reserved */
45#define INDYCAM_CONTROL_EVNFLD (1<<4) /* read-only */
46
47#define INDYCAM_SHUTTER_10000 0x02 /* 1/10000 second */
48#define INDYCAM_SHUTTER_4000 0x04 /* 1/4000 second */
49#define INDYCAM_SHUTTER_2000 0x08 /* 1/2000 second */
50#define INDYCAM_SHUTTER_1000 0x10 /* 1/1000 second */
51#define INDYCAM_SHUTTER_500 0x20 /* 1/500 second */
52#define INDYCAM_SHUTTER_250 0x3f /* 1/250 second */
53#define INDYCAM_SHUTTER_125 0x7e /* 1/125 second */
54#define INDYCAM_SHUTTER_100 0x9e /* 1/100 second */
55#define INDYCAM_SHUTTER_60 0x00 /* 1/60 second */
56
57#define INDYCAM_LED_ACTIVE 0x10
58#define INDYCAM_LED_INACTIVE 0x30
59#define INDYCAM_ORIENTATION_BOTTOM_TO_TOP 0x40
60#define INDYCAM_BUTTON_RELEASED 0x10
61
62#define INDYCAM_SHUTTER_MIN 0x00
63#define INDYCAM_SHUTTER_MAX 0xff
64#define INDYCAM_GAIN_MIN 0x00
65#define INDYCAM_GAIN_MAX 0xff
66#define INDYCAM_RED_BALANCE_MIN 0x00 /* the effect is the opposite? */
67#define INDYCAM_RED_BALANCE_MAX 0xff
68#define INDYCAM_BLUE_BALANCE_MIN 0x00 /* the effect is the opposite? */
69#define INDYCAM_BLUE_BALANCE_MAX 0xff
70#define INDYCAM_RED_SATURATION_MIN 0x00
71#define INDYCAM_RED_SATURATION_MAX 0xff
72#define INDYCAM_BLUE_SATURATION_MIN 0x00
73#define INDYCAM_BLUE_SATURATION_MAX 0xff
74#define INDYCAM_GAMMA_MIN 0x00
75#define INDYCAM_GAMMA_MAX 0xff
76
77/* Driver interface definitions */
78
79#define INDYCAM_VALUE_ENABLED 1
80#define INDYCAM_VALUE_DISABLED 0
81#define INDYCAM_VALUE_UNCHANGED -1
82
83/* When setting controls, a value of -1 leaves the control unchanged. */
84struct indycam_control {
85 int agc; /* boolean */
86 int awb; /* boolean */
87 int shutter;
88 int gain;
89 int red_balance;
90 int blue_balance;
91 int red_saturation;
92 int blue_saturation;
93 int gamma;
94};
95
96#define DECODER_INDYCAM_GET_CONTROLS _IOR('d', 193, struct indycam_control)
97#define DECODER_INDYCAM_SET_CONTROLS _IOW('d', 194, struct indycam_control)
98
99/* Default values for controls */
100
101#define INDYCAM_AGC_DEFAULT INDYCAM_VALUE_ENABLED
102#define INDYCAM_AWB_DEFAULT INDYCAM_VALUE_ENABLED
103
104#define INDYCAM_SHUTTER_DEFAULT INDYCAM_SHUTTER_60
105#define INDYCAM_GAIN_DEFAULT 0x80
106#define INDYCAM_RED_BALANCE_DEFAULT 0x18
107#define INDYCAM_BLUE_BALANCE_DEFAULT 0xa4
108#define INDYCAM_RED_SATURATION_DEFAULT 0x80
109#define INDYCAM_BLUE_SATURATION_DEFAULT 0xc0
110#define INDYCAM_GAMMA_DEFAULT 0x80
111
112#endif
diff --git a/drivers/media/video/saa7191.c b/drivers/media/video/saa7191.c
new file mode 100644
index 000000000000..454f5c1199b4
--- /dev/null
+++ b/drivers/media/video/saa7191.c
@@ -0,0 +1,512 @@
1/*
2 * saa7191.c - Philips SAA7191 video decoder driver
3 *
4 * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
5 * Copyright (C) 2004,2005 Mikael Nousiainen <tmnousia@cc.hut.fi>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/delay.h>
15#include <linux/errno.h>
16#include <linux/fs.h>
17#include <linux/kernel.h>
18#include <linux/major.h>
19#include <linux/slab.h>
20#include <linux/mm.h>
21#include <linux/sched.h>
22
23#include <linux/videodev.h>
24#include <linux/video_decoder.h>
25#include <linux/i2c.h>
26
27#include "saa7191.h"
28
29#define SAA7191_MODULE_VERSION "0.0.3"
30
31MODULE_DESCRIPTION("Philips SAA7191 video decoder driver");
32MODULE_VERSION(SAA7191_MODULE_VERSION);
33MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
34MODULE_LICENSE("GPL");
35
36#define VINO_ADAPTER (I2C_ALGO_SGI | I2C_HW_SGI_VINO)
37
38struct saa7191 {
39 struct i2c_client *client;
40
41 /* the register values are stored here as the actual
42 * I2C-registers are write-only */
43 unsigned char reg[25];
44
45 unsigned char norm;
46 unsigned char input;
47};
48
49static struct i2c_driver i2c_driver_saa7191;
50
51static const unsigned char initseq[] = {
52 0, /* Subaddress */
53 0x50, /* SAA7191_REG_IDEL */
54 0x30, /* SAA7191_REG_HSYB */
55 0x00, /* SAA7191_REG_HSYS */
56 0xe8, /* SAA7191_REG_HCLB */
57 0xb6, /* SAA7191_REG_HCLS */
58 0xf4, /* SAA7191_REG_HPHI */
59 0x01, /* SAA7191_REG_LUMA - chrominance trap active (CVBS) */
60 0x00, /* SAA7191_REG_HUEC */
61 0xf8, /* SAA7191_REG_CKTQ */
62 0xf8, /* SAA7191_REG_CKTS */
63 0x90, /* SAA7191_REG_PLSE */
64 0x90, /* SAA7191_REG_SESE */
65 0x00, /* SAA7191_REG_GAIN */
66 0x0c, /* SAA7191_REG_STDC - not SECAM, slow time constant */
67 0x78, /* SAA7191_REG_IOCK - chrominance from CVBS, GPSW1 & 2 off */
68 0x99, /* SAA7191_REG_CTL3 - automatic field detection */
69 0x00, /* SAA7191_REG_CTL4 */
70 0x2c, /* SAA7191_REG_CHCV */
71 0x00, /* unused */
72 0x00, /* unused */
73 0x34, /* SAA7191_REG_HS6B */
74 0x0a, /* SAA7191_REG_HS6S */
75 0xf4, /* SAA7191_REG_HC6B */
76 0xce, /* SAA7191_REG_HC6S */
77 0xf4, /* SAA7191_REG_HP6I */
78};
79
80/* SAA7191 register handling */
81
82static unsigned char saa7191_read_reg(struct i2c_client *client,
83 unsigned char reg)
84{
85 return ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg];
86}
87
88static int saa7191_read_status(struct i2c_client *client,
89 unsigned char *value)
90{
91 int ret;
92
93 ret = i2c_master_recv(client, value, 1);
94 if (ret < 0) {
95 printk(KERN_ERR "SAA7191: saa7191_read_status(): read failed");
96 return ret;
97 }
98
99 return 0;
100}
101
102
103static int saa7191_write_reg(struct i2c_client *client, unsigned char reg,
104 unsigned char value)
105{
106
107 ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg] = value;
108 return i2c_smbus_write_byte_data(client, reg, value);
109}
110
111/* the first byte of data must be the first subaddress number (register) */
112static int saa7191_write_block(struct i2c_client *client,
113 unsigned char length, unsigned char *data)
114{
115 int i;
116 int ret;
117
118 struct saa7191 *decoder = (struct saa7191 *)i2c_get_clientdata(client);
119 for (i = 0; i < (length - 1); i++) {
120 decoder->reg[data[0] + i] = data[i + 1];
121 }
122
123 ret = i2c_master_send(client, data, length);
124 if (ret < 0) {
125 printk(KERN_ERR "SAA7191: saa7191_write_block(): "
126 "write failed");
127 return ret;
128 }
129
130 return 0;
131}
132
133/* Helper functions */
134
135static int saa7191_set_input(struct i2c_client *client, int input)
136{
137 unsigned char luma = saa7191_read_reg(client, SAA7191_REG_LUMA);
138 unsigned char iock = saa7191_read_reg(client, SAA7191_REG_IOCK);
139 int err;
140
141 switch (input) {
142 case SAA7191_INPUT_COMPOSITE: /* Set Composite input */
143 iock &= ~(SAA7191_IOCK_CHRS | SAA7191_IOCK_GPSW1
144 | SAA7191_IOCK_GPSW2);
145 /* Chrominance trap active */
146 luma &= ~SAA7191_LUMA_BYPS;
147 break;
148 case SAA7191_INPUT_SVIDEO: /* Set S-Video input */
149 iock |= SAA7191_IOCK_CHRS | SAA7191_IOCK_GPSW2;
150 /* Chrominance trap bypassed */
151 luma |= SAA7191_LUMA_BYPS;
152 break;
153 default:
154 return -EINVAL;
155 }
156
157 err = saa7191_write_reg(client, SAA7191_REG_LUMA, luma);
158 if (err)
159 return -EIO;
160 err = saa7191_write_reg(client, SAA7191_REG_IOCK, iock);
161 if (err)
162 return -EIO;
163
164 return 0;
165}
166
167static int saa7191_set_norm(struct i2c_client *client, int norm)
168{
169 struct saa7191 *decoder = i2c_get_clientdata(client);
170 unsigned char stdc = saa7191_read_reg(client, SAA7191_REG_STDC);
171 unsigned char ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
172 unsigned char chcv = saa7191_read_reg(client, SAA7191_REG_CHCV);
173 int err;
174
175 switch(norm) {
176 case SAA7191_NORM_AUTO: {
177 unsigned char status;
178
179 // does status depend on current norm ?
180 if (saa7191_read_status(client, &status))
181 return -EIO;
182
183 stdc &= ~SAA7191_STDC_SECS;
184 ctl3 &= ~SAA7191_CTL3_FSEL;
185 ctl3 |= SAA7191_CTL3_AUFD;
186 chcv = (status & SAA7191_STATUS_FIDT)
187 ? SAA7191_CHCV_NTSC : SAA7191_CHCV_PAL;
188 break;
189 }
190 case SAA7191_NORM_PAL:
191 stdc &= ~SAA7191_STDC_SECS;
192 ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL);
193 chcv = SAA7191_CHCV_PAL;
194 break;
195 case SAA7191_NORM_NTSC:
196 stdc &= ~SAA7191_STDC_SECS;
197 ctl3 &= ~SAA7191_CTL3_AUFD;
198 ctl3 |= SAA7191_CTL3_FSEL;
199 chcv = SAA7191_CHCV_NTSC;
200 break;
201 case SAA7191_NORM_SECAM:
202 stdc |= SAA7191_STDC_SECS;
203 ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL);
204 chcv = SAA7191_CHCV_PAL;
205 break;
206 default:
207 return -EINVAL;
208 }
209
210 err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
211 if (err)
212 return -EIO;
213 err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc);
214 if (err)
215 return -EIO;
216 err = saa7191_write_reg(client, SAA7191_REG_CHCV, chcv);
217 if (err)
218 return -EIO;
219
220 decoder->norm = norm;
221
222 return 0;
223}
224
225static int saa7191_get_controls(struct i2c_client *client,
226 struct saa7191_control *ctrl)
227{
228 unsigned char hue = saa7191_read_reg(client, SAA7191_REG_HUEC);
229 unsigned char stdc = saa7191_read_reg(client, SAA7191_REG_STDC);
230
231 if (hue < 0x80) {
232 hue += 0x80;
233 } else {
234 hue -= 0x80;
235 }
236 ctrl->hue = hue;
237
238 ctrl->vtrc = (stdc & SAA7191_STDC_VTRC)
239 ? SAA7191_VALUE_ENABLED : SAA7191_VALUE_DISABLED;
240
241 return 0;
242}
243
244static int saa7191_set_controls(struct i2c_client *client,
245 struct saa7191_control *ctrl)
246{
247 int err;
248
249 if (ctrl->hue >= 0) {
250 unsigned char hue = ctrl->hue & 0xff;
251 if (hue < 0x80) {
252 hue += 0x80;
253 } else {
254 hue -= 0x80;
255 }
256 err = saa7191_write_reg(client, SAA7191_REG_HUEC, hue);
257 if (err)
258 return -EIO;
259 }
260 if (ctrl->vtrc >= 0) {
261 unsigned char stdc =
262 saa7191_read_reg(client, SAA7191_REG_STDC);
263
264 if (ctrl->vtrc) {
265 stdc |= SAA7191_STDC_VTRC;
266 } else {
267 stdc &= ~SAA7191_STDC_VTRC;
268 }
269
270 err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc);
271 if (err)
272 return -EIO;
273 }
274
275 return 0;
276}
277
278/* I2C-interface */
279
280static int saa7191_attach(struct i2c_adapter *adap, int addr, int kind)
281{
282 int err = 0;
283 struct saa7191 *decoder;
284 struct i2c_client *client;
285
286 printk(KERN_INFO "Philips SAA7191 driver version %s\n",
287 SAA7191_MODULE_VERSION);
288
289 client = kmalloc(sizeof(*client), GFP_KERNEL);
290 if (!client)
291 return -ENOMEM;
292 decoder = kmalloc(sizeof(*decoder), GFP_KERNEL);
293 if (!decoder) {
294 err = -ENOMEM;
295 goto out_free_client;
296 }
297
298 memset(client, 0, sizeof(struct i2c_client));
299 memset(decoder, 0, sizeof(struct saa7191));
300
301 client->addr = addr;
302 client->adapter = adap;
303 client->driver = &i2c_driver_saa7191;
304 client->flags = 0;
305 strcpy(client->name, "saa7191 client");
306 i2c_set_clientdata(client, decoder);
307
308 decoder->client = client;
309
310 err = i2c_attach_client(client);
311 if (err)
312 goto out_free_decoder;
313
314 decoder->input = SAA7191_INPUT_COMPOSITE;
315 decoder->norm = SAA7191_NORM_AUTO;
316
317 err = saa7191_write_block(client, sizeof(initseq),
318 (unsigned char *)initseq);
319 if (err) {
320 printk(KERN_ERR "SAA7191 initialization failed\n");
321 goto out_detach_client;
322 }
323
324 printk(KERN_INFO "SAA7191 initialized\n");
325
326 return 0;
327
328out_detach_client:
329 i2c_detach_client(client);
330out_free_decoder:
331 kfree(decoder);
332out_free_client:
333 kfree(client);
334 return err;
335}
336
337static int saa7191_probe(struct i2c_adapter *adap)
338{
339 /* Always connected to VINO */
340 if (adap->id == VINO_ADAPTER)
341 return saa7191_attach(adap, SAA7191_ADDR, 0);
342 /* Feel free to add probe here :-) */
343 return -ENODEV;
344}
345
346static int saa7191_detach(struct i2c_client *client)
347{
348 struct saa7191 *decoder = i2c_get_clientdata(client);
349
350 i2c_detach_client(client);
351 kfree(decoder);
352 kfree(client);
353 return 0;
354}
355
356static int saa7191_command(struct i2c_client *client, unsigned int cmd,
357 void *arg)
358{
359 struct saa7191 *decoder = i2c_get_clientdata(client);
360
361 switch (cmd) {
362 case DECODER_GET_CAPABILITIES: {
363 struct video_decoder_capability *cap = arg;
364
365 cap->flags = VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC |
366 VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO;
367 cap->inputs = (client->adapter->id == VINO_ADAPTER) ? 2 : 1;
368 cap->outputs = 1;
369 break;
370 }
371 case DECODER_GET_STATUS: {
372 int *iarg = arg;
373 unsigned char status;
374 int res = 0;
375
376 if (saa7191_read_status(client, &status)) {
377 return -EIO;
378 }
379 if ((status & SAA7191_STATUS_HLCK) == 0)
380 res |= DECODER_STATUS_GOOD;
381 if (status & SAA7191_STATUS_CODE)
382 res |= DECODER_STATUS_COLOR;
383 switch (decoder->norm) {
384 case SAA7191_NORM_NTSC:
385 res |= DECODER_STATUS_NTSC;
386 break;
387 case SAA7191_NORM_PAL:
388 res |= DECODER_STATUS_PAL;
389 break;
390 case SAA7191_NORM_SECAM:
391 res |= DECODER_STATUS_SECAM;
392 break;
393 case SAA7191_NORM_AUTO:
394 default:
395 if (status & SAA7191_STATUS_FIDT)
396 res |= DECODER_STATUS_NTSC;
397 else
398 res |= DECODER_STATUS_PAL;
399 break;
400 }
401 *iarg = res;
402 break;
403 }
404 case DECODER_SET_NORM: {
405 int *iarg = arg;
406
407 switch (*iarg) {
408 case VIDEO_MODE_AUTO:
409 return saa7191_set_norm(client, SAA7191_NORM_AUTO);
410 case VIDEO_MODE_PAL:
411 return saa7191_set_norm(client, SAA7191_NORM_PAL);
412 case VIDEO_MODE_NTSC:
413 return saa7191_set_norm(client, SAA7191_NORM_NTSC);
414 case VIDEO_MODE_SECAM:
415 return saa7191_set_norm(client, SAA7191_NORM_SECAM);
416 default:
417 return -EINVAL;
418 }
419 break;
420 }
421 case DECODER_SET_INPUT: {
422 int *iarg = arg;
423
424 switch (client->adapter->id) {
425 case VINO_ADAPTER:
426 return saa7191_set_input(client, *iarg);
427 default:
428 if (*iarg != 0)
429 return -EINVAL;
430 }
431 break;
432 }
433 case DECODER_SET_OUTPUT: {
434 int *iarg = arg;
435
436 /* not much choice of outputs */
437 if (*iarg != 0)
438 return -EINVAL;
439 break;
440 }
441 case DECODER_ENABLE_OUTPUT: {
442 /* Always enabled */
443 break;
444 }
445 case DECODER_SET_PICTURE: {
446 struct video_picture *pic = arg;
447 unsigned val;
448 int err;
449
450 val = (pic->hue >> 8) - 0x80;
451 err = saa7191_write_reg(client, SAA7191_REG_HUEC, val);
452 if (err)
453 return -EIO;
454 break;
455 }
456 case DECODER_SAA7191_GET_STATUS: {
457 struct saa7191_status *status = arg;
458 unsigned char status_reg;
459
460 if (saa7191_read_status(client, &status_reg))
461 return -EIO;
462 status->signal = ((status_reg & SAA7191_STATUS_HLCK) == 0)
463 ? SAA7191_VALUE_ENABLED : SAA7191_VALUE_DISABLED;
464 status->ntsc = (status_reg & SAA7191_STATUS_FIDT)
465 ? SAA7191_VALUE_ENABLED : SAA7191_VALUE_DISABLED;
466 status->color = (status_reg & SAA7191_STATUS_CODE)
467 ? SAA7191_VALUE_ENABLED : SAA7191_VALUE_DISABLED;
468
469 status->input = decoder->input;
470 status->norm = decoder->norm;
471 }
472 case DECODER_SAA7191_SET_NORM: {
473 int *norm = arg;
474 return saa7191_set_norm(client, *norm);
475 }
476 case DECODER_SAA7191_GET_CONTROLS: {
477 struct saa7191_control *ctrl = arg;
478 return saa7191_get_controls(client, ctrl);
479 }
480 case DECODER_SAA7191_SET_CONTROLS: {
481 struct saa7191_control *ctrl = arg;
482 return saa7191_set_controls(client, ctrl);
483 }
484 default:
485 return -EINVAL;
486 }
487
488 return 0;
489}
490
491static struct i2c_driver i2c_driver_saa7191 = {
492 .owner = THIS_MODULE,
493 .name = "saa7191",
494 .id = I2C_DRIVERID_SAA7191,
495 .flags = I2C_DF_NOTIFY,
496 .attach_adapter = saa7191_probe,
497 .detach_client = saa7191_detach,
498 .command = saa7191_command
499};
500
501static int saa7191_init(void)
502{
503 return i2c_add_driver(&i2c_driver_saa7191);
504}
505
506static void saa7191_exit(void)
507{
508 i2c_del_driver(&i2c_driver_saa7191);
509}
510
511module_init(saa7191_init);
512module_exit(saa7191_exit);
diff --git a/drivers/media/video/saa7191.h b/drivers/media/video/saa7191.h
new file mode 100644
index 000000000000..272045031435
--- /dev/null
+++ b/drivers/media/video/saa7191.h
@@ -0,0 +1,139 @@
1/*
2 * saa7191.h - Philips SAA7191 video decoder driver
3 *
4 * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
5 * Copyright (C) 2004,2005 Mikael Nousiainen <tmnousia@cc.hut.fi>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef _SAA7191_H_
13#define _SAA7191_H_
14
15/* Philips SAA7191 DMSD I2C bus address */
16#define SAA7191_ADDR 0x8a
17
18/* Register subaddresses. */
19#define SAA7191_REG_IDEL 0x00
20#define SAA7191_REG_HSYB 0x01
21#define SAA7191_REG_HSYS 0x02
22#define SAA7191_REG_HCLB 0x03
23#define SAA7191_REG_HCLS 0x04
24#define SAA7191_REG_HPHI 0x05
25#define SAA7191_REG_LUMA 0x06
26#define SAA7191_REG_HUEC 0x07
27#define SAA7191_REG_CKTQ 0x08
28#define SAA7191_REG_CKTS 0x09
29#define SAA7191_REG_PLSE 0x0a
30#define SAA7191_REG_SESE 0x0b
31#define SAA7191_REG_GAIN 0x0c
32#define SAA7191_REG_STDC 0x0d
33#define SAA7191_REG_IOCK 0x0e
34#define SAA7191_REG_CTL3 0x0f
35#define SAA7191_REG_CTL4 0x10
36#define SAA7191_REG_CHCV 0x11
37#define SAA7191_REG_HS6B 0x14
38#define SAA7191_REG_HS6S 0x15
39#define SAA7191_REG_HC6B 0x16
40#define SAA7191_REG_HC6S 0x17
41#define SAA7191_REG_HP6I 0x18
42#define SAA7191_REG_STATUS 0xff /* not really a subaddress */
43
44/* Status Register definitions */
45#define SAA7191_STATUS_CODE 0x01 /* color detected flag */
46#define SAA7191_STATUS_FIDT 0x20 /* format type NTSC/PAL */
47#define SAA7191_STATUS_HLCK 0x40 /* PLL unlocked/locked */
48#define SAA7191_STATUS_STTC 0x80 /* tv/vtr time constant */
49
50/* Luminance Control Register definitions */
51#define SAA7191_LUMA_BYPS 0x80
52
53/* Chroma Gain Control Settings Register definitions */
54/* 0=automatic colour-killer enabled, 1=forced colour on */
55#define SAA7191_GAIN_COLO 0x80
56
57/* Standard/Mode Control Register definitions */
58/* tv/vtr mode bit: 0=TV mode (slow time constant),
59 * 1=VTR mode (fast time constant) */
60#define SAA7191_STDC_VTRC 0x80
61/* SECAM mode bit: 0=other standards, 1=SECAM */
62#define SAA7191_STDC_SECS 0x01
63/* the bit fields above must be or'd with this value */
64#define SAA7191_STDC_VALUE 0x0c
65
66/* I/O and Clock Control Register definitions */
67/* horizontal clock PLL: 0=PLL closed,
68 * 1=PLL circuit open and horizontal freq fixed */
69#define SAA7191_IOCK_HPLL 0x80
70/* S-VHS bit (chrominance from CVBS or from chrominance input):
71 * 0=controlled by BYPS-bit, 1=from chrominance input */
72#define SAA7191_IOCK_CHRS 0x04
73/* general purpose switch 2
74 * VINO-specific: 0=used with CVBS, 1=used with S-Video */
75#define SAA7191_IOCK_GPSW2 0x02
76/* general purpose switch 1 */
77/* VINO-specific: 0=always, 1=not used!*/
78#define SAA7191_IOCK_GPSW1 0x01
79
80/* Miscellaneous Control #1 Register definitions */
81/* automatic field detection (50/60Hz standard) */
82#define SAA7191_CTL3_AUFD 0x80
83/* field select: (if AUFD=0)
84 * 0=50Hz (625 lines), 1=60Hz (525 lines) */
85#define SAA7191_CTL3_FSEL 0x40
86/* the bit fields above must be or'd with this value */
87#define SAA7191_CTL3_VALUE 0x19
88
89/* Chrominance Gain Control Register definitions
90 * (nominal value for UV CCIR level) */
91#define SAA7191_CHCV_NTSC 0x2c
92#define SAA7191_CHCV_PAL 0x59
93
94/* Driver interface definitions */
95#define SAA7191_INPUT_COMPOSITE 0
96#define SAA7191_INPUT_SVIDEO 1
97
98#define SAA7191_NORM_AUTO 0
99#define SAA7191_NORM_PAL 1
100#define SAA7191_NORM_NTSC 2
101#define SAA7191_NORM_SECAM 3
102
103#define SAA7191_VALUE_ENABLED 1
104#define SAA7191_VALUE_DISABLED 0
105#define SAA7191_VALUE_UNCHANGED -1
106
107struct saa7191_status {
108 /* 0=no signal, 1=signal active*/
109 int signal;
110 /* 0=50hz (pal) signal, 1=60hz (ntsc) signal */
111 int ntsc;
112 /* 0=no color detected, 1=color detected */
113 int color;
114
115 /* current SAA7191_INPUT_ */
116 int input;
117 /* current SAA7191_NORM_ */
118 int norm;
119};
120
121#define SAA7191_HUE_MIN 0x00
122#define SAA7191_HUE_MAX 0xff
123#define SAA7191_HUE_DEFAULT 0x80
124
125#define SAA7191_VTRC_MIN 0x00
126#define SAA7191_VTRC_MAX 0x01
127#define SAA7191_VTRC_DEFAULT 0x00
128
129struct saa7191_control {
130 int hue;
131 int vtrc;
132};
133
134#define DECODER_SAA7191_GET_STATUS _IOR('d', 195, struct saa7191_status)
135#define DECODER_SAA7191_SET_NORM _IOW('d', 196, int)
136#define DECODER_SAA7191_GET_CONTROLS _IOR('d', 197, struct saa7191_control)
137#define DECODER_SAA7191_SET_CONTROLS _IOW('d', 198, struct saa7191_control)
138
139#endif
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
index 76e8681d65c6..d8a0f763ca10 100644
--- a/drivers/media/video/vino.c
+++ b/drivers/media/video/vino.c
@@ -1,80 +1,606 @@
1/* 1/*
2 * (incomplete) Driver for the VINO (Video In No Out) system found in SGI Indys. 2 * Driver for the VINO (Video In No Out) system found in SGI Indys.
3 * 3 *
4 * This file is subject to the terms and conditions of the GNU General Public 4 * This file is subject to the terms and conditions of the GNU General Public
5 * License version 2 as published by the Free Software Foundation. 5 * License version 2 as published by the Free Software Foundation.
6 * 6 *
7 * Copyright (C) 2004,2005 Mikael Nousiainen <tmnousia@cc.hut.fi>
8 *
9 * Based on the previous version of the driver for 2.4 kernels by:
7 * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org> 10 * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
8 */ 11 */
9 12
10#include <linux/module.h> 13/*
14 * TODO:
15 * - remove "hacks" from memory allocation code and implement nopage()
16 * - check decimation, calculating and reporting image size when
17 * using decimation
18 * - check vino_acquire_input(), vino_set_input() and channel
19 * ownership handling
20 * - report VINO error-interrupts via ioctls ?
21 * - implement picture controls (all implemented?)
22 * - use macros for boolean values (?)
23 * - implement user mode buffers and overlay (?)
24 */
25
11#include <linux/init.h> 26#include <linux/init.h>
12#include <linux/types.h> 27#include <linux/module.h>
13#include <linux/mm.h>
14#include <linux/slab.h>
15#include <linux/wrapper.h>
16#include <linux/errno.h>
17#include <linux/irq.h>
18#include <linux/delay.h> 28#include <linux/delay.h>
19#include <linux/videodev.h> 29#include <linux/errno.h>
30#include <linux/fs.h>
31#include <linux/kernel.h>
32#include <linux/mm.h>
33#include <linux/interrupt.h>
34#include <linux/dma-mapping.h>
35#include <linux/time.h>
36#include <linux/moduleparam.h>
37
38#ifdef CONFIG_KMOD
39#include <linux/kmod.h>
40#endif
41
20#include <linux/i2c.h> 42#include <linux/i2c.h>
21#include <linux/i2c-algo-sgi.h> 43#include <linux/i2c-algo-sgi.h>
22 44
23#include <asm/addrspace.h> 45#include <linux/videodev.h>
24#include <asm/system.h> 46#include <linux/videodev2.h>
25#include <asm/bootinfo.h> 47#include <linux/video_decoder.h>
26#include <asm/pgtable.h> 48
27#include <asm/paccess.h> 49#include <asm/paccess.h>
28#include <asm/io.h> 50#include <asm/io.h>
29#include <asm/sgi/ip22.h> 51#include <asm/sgi/ip22.h>
30#include <asm/sgi/hpc3.h>
31#include <asm/sgi/mc.h> 52#include <asm/sgi/mc.h>
32 53
33#include "vino.h" 54#include "vino.h"
55#include "saa7191.h"
56#include "indycam.h"
57
58/* Uncomment the following line to get lots and lots of (mostly useless)
59 * debug info.
60 * Note that the debug output also slows down the driver significantly */
61// #define VINO_DEBUG
62
63#define VINO_MODULE_VERSION "0.0.3"
64#define VINO_VERSION_CODE KERNEL_VERSION(0, 0, 3)
65
66MODULE_DESCRIPTION("SGI VINO Video4Linux2 driver");
67MODULE_VERSION(VINO_MODULE_VERSION);
68MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
69MODULE_LICENSE("GPL");
34 70
35/* debugging? */ 71#define mem_map_reserve(p) set_bit(PG_reserved, &((p)->flags))
36#if 1 72#define mem_map_unreserve(p) clear_bit(PG_reserved, &((p)->flags))
37#define DEBUG(x...) printk(x); 73
74#ifdef VINO_DEBUG
75#define dprintk(x...) printk("VINO: " x);
38#else 76#else
39#define DEBUG(x...) 77#define dprintk(x...)
40#endif 78#endif
41 79
80#define VINO_NO_CHANNEL 0
81#define VINO_CHANNEL_A 1
82#define VINO_CHANNEL_B 2
83
84#define VINO_PAL_WIDTH 768
85#define VINO_PAL_HEIGHT 576
86#define VINO_NTSC_WIDTH 640
87#define VINO_NTSC_HEIGHT 480
88
89#define VINO_MIN_WIDTH 32
90#define VINO_MIN_HEIGHT 32
91
92#define VINO_CLIPPING_START_ODD_D1 1
93#define VINO_CLIPPING_START_ODD_PAL 1
94#define VINO_CLIPPING_START_ODD_NTSC 1
95
96#define VINO_CLIPPING_START_EVEN_D1 2
97#define VINO_CLIPPING_START_EVEN_PAL 2
98#define VINO_CLIPPING_START_EVEN_NTSC 2
99
100#define VINO_INPUT_CHANNEL_COUNT 3
101
102#define VINO_INPUT_NONE -1
103#define VINO_INPUT_COMPOSITE 0
104#define VINO_INPUT_SVIDEO 1
105#define VINO_INPUT_D1 2
106
107#define VINO_PAGE_RATIO (PAGE_SIZE / VINO_PAGE_SIZE)
108
109#define VINO_FIFO_THRESHOLD_DEFAULT 512
110
111/*#define VINO_FRAMEBUFFER_SIZE (VINO_PAL_WIDTH * VINO_PAL_HEIGHT * 4 \
112 + 2 * PAGE_SIZE)*/
113#define VINO_FRAMEBUFFER_SIZE ((VINO_PAL_WIDTH \
114 * VINO_PAL_HEIGHT * 4 \
115 + 3 * PAGE_SIZE) & ~(PAGE_SIZE - 1))
116
117#define VINO_FRAMEBUFFER_MAX_COUNT 8
118
119#define VINO_FRAMEBUFFER_UNUSED 0
120#define VINO_FRAMEBUFFER_IN_USE 1
121#define VINO_FRAMEBUFFER_READY 2
122
123#define VINO_QUEUE_ERROR -1
124#define VINO_QUEUE_MAGIC 0x20050125
125
126#define VINO_MEMORY_NONE 0
127#define VINO_MEMORY_MMAP 1
128#define VINO_MEMORY_USERPTR 2
129
130#define VINO_DUMMY_DESC_COUNT 4
131#define VINO_DESC_FETCH_DELAY 5 /* microseconds */
132
133/* the number is the index for vino_data_formats */
134#define VINO_DATA_FMT_NONE -1
135#define VINO_DATA_FMT_GREY 0
136#define VINO_DATA_FMT_RGB332 1
137#define VINO_DATA_FMT_RGB32 2
138#define VINO_DATA_FMT_YUV 3
139//#define VINO_DATA_FMT_RGB24 4
140
141#define VINO_DATA_FMT_COUNT 4
142
143#define VINO_DATA_NORM_NONE -1
144#define VINO_DATA_NORM_NTSC 0
145#define VINO_DATA_NORM_PAL 1
146#define VINO_DATA_NORM_SECAM 2
147#define VINO_DATA_NORM_D1 3
148/* The following is a special entry that can be used to
149 * autodetect the norm. */
150#define VINO_DATA_NORM_AUTO 0xff
151
152#define VINO_DATA_NORM_COUNT 4
42 153
43/* VINO ASIC registers */ 154/* Internal data structure definitions */
44struct sgi_vino *vino;
45 155
46static const char *vinostr = "VINO IndyCam/TV"; 156struct vino_input {
47static int threshold_a = 512; 157 char *name;
48static int threshold_b = 512; 158 v4l2_std_id std;
159};
160
161struct vino_clipping {
162 unsigned int left, right, top, bottom;
163};
164
165struct vino_data_format {
166 /* the description */
167 char *description;
168 /* bytes per pixel */
169 unsigned int bpp;
170 /* V4L2 fourcc code */
171 __u32 pixelformat;
172 /* V4L2 colorspace (duh!) */
173 enum v4l2_colorspace colorspace;
174};
175
176struct vino_data_norm {
177 char *description;
178 unsigned int width, height;
179 struct vino_clipping odd;
180 struct vino_clipping even;
181
182 v4l2_std_id std;
183 unsigned int fps_min, fps_max;
184 __u32 framelines;
185};
186
187struct vino_descriptor_table {
188 /* the number of PAGE_SIZE sized pages in the buffer */
189 unsigned int page_count;
190 /* virtual (kmalloc'd) pointers to the actual data
191 * (in PAGE_SIZE chunks, used with mmap streaming) */
192 unsigned long *virtual;
193
194 /* cpu address for the VINO descriptor table
195 * (contains DMA addresses, VINO_PAGE_SIZE chunks) */
196 unsigned long *dma_cpu;
197 /* dma address for the VINO descriptor table
198 * (contains DMA addresses, VINO_PAGE_SIZE chunks) */
199 dma_addr_t dma;
200};
201
202struct vino_framebuffer {
203 /* identifier nubmer */
204 unsigned int id;
205 /* the length of the whole buffer */
206 unsigned int size;
207 /* the length of actual data in buffer */
208 unsigned int data_size;
209 /* the data format */
210 unsigned int data_format;
211 /* the state of buffer data */
212 unsigned int state;
213 /* is the buffer mapped in user space? */
214 unsigned int map_count;
215 /* memory offset for mmap() */
216 unsigned int offset;
217 /* frame counter */
218 unsigned int frame_counter;
219 /* timestamp (written when image capture finishes) */
220 struct timeval timestamp;
221
222 struct vino_descriptor_table desc_table;
223
224 spinlock_t state_lock;
225};
49 226
50struct vino_device { 227struct vino_framebuffer_fifo {
51 struct video_device vdev; 228 unsigned int length;
52#define VINO_CHAN_A 1 229
53#define VINO_CHAN_B 2 230 unsigned int used;
54 int chan; 231 unsigned int head;
232 unsigned int tail;
233
234 unsigned int data[VINO_FRAMEBUFFER_MAX_COUNT];
235};
236
237struct vino_framebuffer_queue {
238 unsigned int magic;
239
240 /* VINO_MEMORY_NONE, VINO_MEMORY_MMAP or VINO_MEMORY_USERPTR */
241 unsigned int type;
242 unsigned int length;
243
244 /* data field of in and out contain index numbers for buffer */
245 struct vino_framebuffer_fifo in;
246 struct vino_framebuffer_fifo out;
247
248 struct vino_framebuffer *buffer[VINO_FRAMEBUFFER_MAX_COUNT];
249
250 spinlock_t queue_lock;
251 struct semaphore queue_sem;
252 wait_queue_head_t frame_wait_queue;
253};
254
255struct vino_channel_settings {
256 unsigned int channel;
257
258 int input;
259 unsigned int data_format;
260 unsigned int data_norm;
261 struct vino_clipping clipping;
262 unsigned int decimation;
263 unsigned int line_size;
264 unsigned int alpha;
265 unsigned int fps;
266 unsigned int framert_reg;
267
268 unsigned int fifo_threshold;
269
270 struct vino_framebuffer_queue fb_queue;
271
272 /* number of the current field */
273 unsigned int field;
274
275 /* read in progress */
276 int reading;
277 /* streaming is active */
278 int streaming;
279 /* the driver is currently processing the queue */
280 int capturing;
281
282 struct semaphore sem;
283 spinlock_t capture_lock;
284
285 unsigned int users;
286
287 /* V4L support */
288 struct video_device *v4l_device;
55}; 289};
56 290
57struct vino_client { 291struct vino_client {
292 /* the channel which owns this client:
293 * VINO_NO_CHANNEL, VINO_CHANNEL_A or VINO_CHANNEL_B */
294 unsigned int owner;
58 struct i2c_client *driver; 295 struct i2c_client *driver;
59 int owner;
60}; 296};
61 297
62struct vino_video { 298struct vino_settings {
63 struct vino_device chA; 299 struct vino_channel_settings a;
64 struct vino_device chB; 300 struct vino_channel_settings b;
65 301
66 struct vino_client decoder; 302 struct vino_client decoder;
67 struct vino_client camera; 303 struct vino_client camera;
68 304
69 struct semaphore input_lock; 305 /* a lock for vino register access */
306 spinlock_t vino_lock;
307 /* a lock for channel input changes */
308 spinlock_t input_lock;
70 309
71 /* Loaded into VINO descriptors to clear End Of Descriptors table
72 * interupt condition */
73 unsigned long dummy_page; 310 unsigned long dummy_page;
74 unsigned int dummy_buf[4] __attribute__((aligned(8))); 311 struct vino_descriptor_table dummy_desc_table;
75}; 312};
76 313
77static struct vino_video *Vino; 314/* Module parameters */
315
316/*
317 * Using vino_pixel_conversion the ARGB32-format pixels supplied
318 * by the VINO chip can be converted to more common formats
319 * like RGBA32 (or probably RGB24 in the future). This way we
320 * can give out data that can be specified correctly with
321 * the V4L2-definitions.
322 *
323 * The pixel format is specified as RGBA32 when no conversion
324 * is used.
325 *
326 * Note that this only affects the 32-bit bit depth.
327 *
328 * Use non-zero value to enable conversion.
329 */
330static int vino_pixel_conversion = 0;
331module_param_named(pixelconv, vino_pixel_conversion, int, 0);
332MODULE_PARM_DESC(pixelconv,
333 "enable pixel conversion (non-zero value enables)");
334
335/* Internal data structures */
336
337static struct sgi_vino *vino;
338
339static struct vino_settings *vino_drvdata;
340
341static const char *vino_driver_name = "vino";
342static const char *vino_driver_description = "SGI VINO";
343static const char *vino_bus_name = "GIO64 bus";
344static const char *vino_v4l_device_name_a = "SGI VINO Channel A";
345static const char *vino_v4l_device_name_b = "SGI VINO Channel B";
346
347static const struct vino_input vino_inputs[] = {
348 {
349 .name = "Composite",
350 .std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
351 },{
352 .name = "S-Video",
353 .std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
354 },{
355 .name = "D1 (IndyCam)",
356 .std = V4L2_STD_NTSC,
357 }
358};
359
360static const struct vino_data_format vino_data_formats[] = {
361 {
362 .description = "8-bit greyscale",
363 .bpp = 1,
364 .pixelformat = V4L2_PIX_FMT_GREY,
365 .colorspace = V4L2_COLORSPACE_SMPTE170M,
366 },{
367 .description = "8-bit dithered RGB 3-3-2",
368 .bpp = 1,
369 .pixelformat = V4L2_PIX_FMT_RGB332,
370 .colorspace = V4L2_COLORSPACE_SRGB,
371 },{
372 .description = "32-bit RGB",
373 .bpp = 4,
374 .pixelformat = V4L2_PIX_FMT_RGB32,
375 .colorspace = V4L2_COLORSPACE_SRGB,
376 },{
377 .description = "YUV 4:2:2",
378 .bpp = 4,
379 .pixelformat = V4L2_PIX_FMT_YUYV, // XXX: swapped?
380 .colorspace = V4L2_COLORSPACE_SMPTE170M,
381 }/*,{
382 .description = "24-bit RGB",
383 .bpp = 3,
384 .pixelformat = V4L2_PIX_FMT_RGB24,
385 .colorspace = V4L2_COLORSPACE_SRGB,
386 }*/
387};
388
389static const struct vino_data_norm vino_data_norms[] = {
390 {
391 .description = "NTSC",
392 .std = V4L2_STD_NTSC,
393 .fps_min = 6,
394 .fps_max = 30,
395 .framelines = 525,
396 .width = VINO_NTSC_WIDTH,
397 .height = VINO_NTSC_HEIGHT,
398 .odd = {
399 .top = VINO_CLIPPING_START_ODD_NTSC,
400 .left = 0,
401 .bottom = VINO_CLIPPING_START_ODD_NTSC
402 + VINO_NTSC_HEIGHT / 2 - 1,
403 .right = VINO_NTSC_WIDTH,
404 },
405 .even = {
406 .top = VINO_CLIPPING_START_EVEN_NTSC,
407 .left = 0,
408 .bottom = VINO_CLIPPING_START_EVEN_NTSC
409 + VINO_NTSC_HEIGHT / 2 - 1,
410 .right = VINO_NTSC_WIDTH,
411 },
412 },{
413 .description = "PAL",
414 .std = V4L2_STD_PAL,
415 .fps_min = 5,
416 .fps_max = 25,
417 .framelines = 625,
418 .width = VINO_PAL_WIDTH,
419 .height = VINO_PAL_HEIGHT,
420 .odd = {
421 .top = VINO_CLIPPING_START_ODD_PAL,
422 .left = 0,
423 .bottom = VINO_CLIPPING_START_ODD_PAL
424 + VINO_PAL_HEIGHT / 2 - 1,
425 .right = VINO_PAL_WIDTH,
426 },
427 .even = {
428 .top = VINO_CLIPPING_START_EVEN_PAL,
429 .left = 0,
430 .bottom = VINO_CLIPPING_START_EVEN_PAL
431 + VINO_PAL_HEIGHT / 2 - 1,
432 .right = VINO_PAL_WIDTH,
433 },
434 },{
435 .description = "SECAM",
436 .std = V4L2_STD_SECAM,
437 .fps_min = 5,
438 .fps_max = 25,
439 .framelines = 625,
440 .width = VINO_PAL_WIDTH,
441 .height = VINO_PAL_HEIGHT,
442 .odd = {
443 .top = VINO_CLIPPING_START_ODD_PAL,
444 .left = 0,
445 .bottom = VINO_CLIPPING_START_ODD_PAL
446 + VINO_PAL_HEIGHT / 2 - 1,
447 .right = VINO_PAL_WIDTH,
448 },
449 .even = {
450 .top = VINO_CLIPPING_START_EVEN_PAL,
451 .left = 0,
452 .bottom = VINO_CLIPPING_START_EVEN_PAL
453 + VINO_PAL_HEIGHT / 2 - 1,
454 .right = VINO_PAL_WIDTH,
455 },
456 },{
457 .description = "NTSC (D1 input)",
458 .std = V4L2_STD_NTSC,
459 .fps_min = 6,
460 .fps_max = 30,
461 .framelines = 525,
462 .width = VINO_NTSC_WIDTH,
463 .height = VINO_NTSC_HEIGHT,
464 .odd = {
465 .top = VINO_CLIPPING_START_ODD_D1,
466 .left = 0,
467 .bottom = VINO_CLIPPING_START_ODD_D1
468 + VINO_NTSC_HEIGHT / 2 - 1,
469 .right = VINO_NTSC_WIDTH,
470 },
471 .even = {
472 .top = VINO_CLIPPING_START_EVEN_D1,
473 .left = 0,
474 .bottom = VINO_CLIPPING_START_EVEN_D1
475 + VINO_NTSC_HEIGHT / 2 - 1,
476 .right = VINO_NTSC_WIDTH,
477 },
478 }
479};
480
481#define VINO_INDYCAM_V4L2_CONTROL_COUNT 9
482
483struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
484 {
485 .id = V4L2_CID_AUTOGAIN,
486 .type = V4L2_CTRL_TYPE_BOOLEAN,
487 .name = "Automatic Gain Control",
488 .minimum = 0,
489 .maximum = 1,
490 .step = 1,
491 .default_value = INDYCAM_AGC_DEFAULT,
492 .flags = 0,
493 .reserved = { 0, 0 },
494 },{
495 .id = V4L2_CID_AUTO_WHITE_BALANCE,
496 .type = V4L2_CTRL_TYPE_BOOLEAN,
497 .name = "Automatic White Balance",
498 .minimum = 0,
499 .maximum = 1,
500 .step = 1,
501 .default_value = INDYCAM_AWB_DEFAULT,
502 .flags = 0,
503 .reserved = { 0, 0 },
504 },{
505 .id = V4L2_CID_GAIN,
506 .type = V4L2_CTRL_TYPE_INTEGER,
507 .name = "Gain",
508 .minimum = INDYCAM_GAIN_MIN,
509 .maximum = INDYCAM_GAIN_MAX,
510 .step = 1,
511 .default_value = INDYCAM_GAIN_DEFAULT,
512 .flags = 0,
513 .reserved = { 0, 0 },
514 },{
515 .id = V4L2_CID_PRIVATE_BASE,
516 .type = V4L2_CTRL_TYPE_INTEGER,
517 .name = "Red Saturation",
518 .minimum = INDYCAM_RED_SATURATION_MIN,
519 .maximum = INDYCAM_RED_SATURATION_MAX,
520 .step = 1,
521 .default_value = INDYCAM_RED_SATURATION_DEFAULT,
522 .flags = 0,
523 .reserved = { 0, 0 },
524 },{
525 .id = V4L2_CID_PRIVATE_BASE + 1,
526 .type = V4L2_CTRL_TYPE_INTEGER,
527 .name = "Blue Saturation",
528 .minimum = INDYCAM_BLUE_SATURATION_MIN,
529 .maximum = INDYCAM_BLUE_SATURATION_MAX,
530 .step = 1,
531 .default_value = INDYCAM_BLUE_SATURATION_DEFAULT,
532 .flags = 0,
533 .reserved = { 0, 0 },
534 },{
535 .id = V4L2_CID_RED_BALANCE,
536 .type = V4L2_CTRL_TYPE_INTEGER,
537 .name = "Red Balance",
538 .minimum = INDYCAM_RED_BALANCE_MIN,
539 .maximum = INDYCAM_RED_BALANCE_MAX,
540 .step = 1,
541 .default_value = INDYCAM_RED_BALANCE_DEFAULT,
542 .flags = 0,
543 .reserved = { 0, 0 },
544 },{
545 .id = V4L2_CID_BLUE_BALANCE,
546 .type = V4L2_CTRL_TYPE_INTEGER,
547 .name = "Blue Balance",
548 .minimum = INDYCAM_BLUE_BALANCE_MIN,
549 .maximum = INDYCAM_BLUE_BALANCE_MAX,
550 .step = 1,
551 .default_value = INDYCAM_BLUE_BALANCE_DEFAULT,
552 .flags = 0,
553 .reserved = { 0, 0 },
554 },{
555 .id = V4L2_CID_EXPOSURE,
556 .type = V4L2_CTRL_TYPE_INTEGER,
557 .name = "Shutter Control",
558 .minimum = INDYCAM_SHUTTER_MIN,
559 .maximum = INDYCAM_SHUTTER_MAX,
560 .step = 1,
561 .default_value = INDYCAM_SHUTTER_DEFAULT,
562 .flags = 0,
563 .reserved = { 0, 0 },
564 },{
565 .id = V4L2_CID_GAMMA,
566 .type = V4L2_CTRL_TYPE_INTEGER,
567 .name = "Gamma",
568 .minimum = INDYCAM_GAMMA_MIN,
569 .maximum = INDYCAM_GAMMA_MAX,
570 .step = 1,
571 .default_value = INDYCAM_GAMMA_DEFAULT,
572 .flags = 0,
573 .reserved = { 0, 0 },
574 }
575};
576
577#define VINO_SAA7191_V4L2_CONTROL_COUNT 2
578
579struct v4l2_queryctrl vino_saa7191_v4l2_controls[] = {
580 {
581 .id = V4L2_CID_HUE,
582 .type = V4L2_CTRL_TYPE_INTEGER,
583 .name = "Hue",
584 .minimum = SAA7191_HUE_MIN,
585 .maximum = SAA7191_HUE_MAX,
586 .step = 1,
587 .default_value = SAA7191_HUE_DEFAULT,
588 .flags = 0,
589 .reserved = { 0, 0 },
590 },{
591 .id = V4L2_CID_PRIVATE_BASE,
592 .type = V4L2_CTRL_TYPE_BOOLEAN,
593 .name = "VTR Time Constant",
594 .minimum = SAA7191_VTRC_MIN,
595 .maximum = SAA7191_VTRC_MAX,
596 .step = 1,
597 .default_value = SAA7191_VTRC_DEFAULT,
598 .flags = 0,
599 .reserved = { 0, 0 },
600 }
601};
602
603/* VINO I2C bus functions */
78 604
79unsigned i2c_vino_getctrl(void *data) 605unsigned i2c_vino_getctrl(void *data)
80{ 606{
@@ -112,49 +638,49 @@ static struct i2c_algo_sgi_data i2c_sgi_vino_data =
112 */ 638 */
113static int i2c_vino_client_reg(struct i2c_client *client) 639static int i2c_vino_client_reg(struct i2c_client *client)
114{ 640{
115 int res = 0; 641 int ret = 0;
116 642
117 down(&Vino->input_lock); 643 spin_lock(&vino_drvdata->input_lock);
118 switch (client->driver->id) { 644 switch (client->driver->id) {
119 case I2C_DRIVERID_SAA7191: 645 case I2C_DRIVERID_SAA7191:
120 if (Vino->decoder.driver) 646 if (vino_drvdata->decoder.driver)
121 res = -EBUSY; 647 ret = -EBUSY;
122 else 648 else
123 Vino->decoder.driver = client; 649 vino_drvdata->decoder.driver = client;
124 break; 650 break;
125 case I2C_DRIVERID_INDYCAM: 651 case I2C_DRIVERID_INDYCAM:
126 if (Vino->camera.driver) 652 if (vino_drvdata->camera.driver)
127 res = -EBUSY; 653 ret = -EBUSY;
128 else 654 else
129 Vino->camera.driver = client; 655 vino_drvdata->camera.driver = client;
130 break; 656 break;
131 default: 657 default:
132 res = -ENODEV; 658 ret = -ENODEV;
133 } 659 }
134 up(&Vino->input_lock); 660 spin_unlock(&vino_drvdata->input_lock);
135 661
136 return res; 662 return ret;
137} 663}
138 664
139static int i2c_vino_client_unreg(struct i2c_client *client) 665static int i2c_vino_client_unreg(struct i2c_client *client)
140{ 666{
141 int res = 0; 667 int ret = 0;
142 668
143 down(&Vino->input_lock); 669 spin_lock(&vino_drvdata->input_lock);
144 if (client == Vino->decoder.driver) { 670 if (client == vino_drvdata->decoder.driver) {
145 if (Vino->decoder.owner) 671 if (vino_drvdata->decoder.owner != VINO_NO_CHANNEL)
146 res = -EBUSY; 672 ret = -EBUSY;
147 else 673 else
148 Vino->decoder.driver = NULL; 674 vino_drvdata->decoder.driver = NULL;
149 } else if (client == Vino->camera.driver) { 675 } else if (client == vino_drvdata->camera.driver) {
150 if (Vino->camera.owner) 676 if (vino_drvdata->camera.owner != VINO_NO_CHANNEL)
151 res = -EBUSY; 677 ret = -EBUSY;
152 else 678 else
153 Vino->camera.driver = NULL; 679 vino_drvdata->camera.driver = NULL;
154 } 680 }
155 up(&Vino->input_lock); 681 spin_unlock(&vino_drvdata->input_lock);
156 682
157 return res; 683 return ret;
158} 684}
159 685
160static struct i2c_adapter vino_i2c_adapter = 686static struct i2c_adapter vino_i2c_adapter =
@@ -176,172 +702,3591 @@ static int vino_i2c_del_bus(void)
176 return i2c_sgi_del_bus(&vino_i2c_adapter); 702 return i2c_sgi_del_bus(&vino_i2c_adapter);
177} 703}
178 704
705static int i2c_camera_command(unsigned int cmd, void *arg)
706{
707 return vino_drvdata->camera.driver->
708 driver->command(vino_drvdata->camera.driver,
709 cmd, arg);
710}
711
712static int i2c_decoder_command(unsigned int cmd, void *arg)
713{
714 return vino_drvdata->decoder.driver->
715 driver->command(vino_drvdata->decoder.driver,
716 cmd, arg);
717}
718
719/* VINO framebuffer/DMA descriptor management */
720
721static void vino_free_buffer_with_count(struct vino_framebuffer *fb,
722 unsigned int count)
723{
724 unsigned int i;
725
726 dprintk("vino_free_buffer_with_count(): count = %d\n", count);
727
728 for (i = 0; i < count; i++) {
729 mem_map_unreserve(virt_to_page(fb->desc_table.virtual[i]));
730 dma_unmap_single(NULL,
731 fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i],
732 PAGE_SIZE, DMA_FROM_DEVICE);
733 free_page(fb->desc_table.virtual[i]);
734 }
735
736 dma_free_coherent(NULL,
737 VINO_PAGE_RATIO * (fb->desc_table.page_count + 4) *
738 sizeof(dma_addr_t), (void *)fb->desc_table.dma_cpu,
739 fb->desc_table.dma);
740 kfree(fb->desc_table.virtual);
741
742 memset(fb, 0, sizeof(struct vino_framebuffer));
743}
744
745static void vino_free_buffer(struct vino_framebuffer *fb)
746{
747 vino_free_buffer_with_count(fb, fb->desc_table.page_count);
748}
749
750static int vino_allocate_buffer(struct vino_framebuffer *fb,
751 unsigned int size)
752{
753 unsigned int count, i, j;
754 int ret = 0;
755
756 dprintk("vino_allocate_buffer():\n");
757
758 if (size < 1)
759 return -EINVAL;
760
761 memset(fb, 0, sizeof(struct vino_framebuffer));
762
763 count = ((size / PAGE_SIZE) + 4) & ~3;
764
765 dprintk("vino_allocate_buffer(): size = %d, count = %d\n",
766 size, count);
767
768 /* allocate memory for table with virtual (page) addresses */
769 fb->desc_table.virtual = (unsigned long *)
770 kmalloc(count * sizeof(unsigned long), GFP_KERNEL);
771 if (!fb->desc_table.virtual)
772 return -ENOMEM;
773
774 /* allocate memory for table with dma addresses
775 * (has space for four extra descriptors) */
776 fb->desc_table.dma_cpu =
777 dma_alloc_coherent(NULL, VINO_PAGE_RATIO * (count + 4) *
778 sizeof(dma_addr_t), &fb->desc_table.dma,
779 GFP_KERNEL | GFP_DMA);
780 if (!fb->desc_table.dma_cpu) {
781 ret = -ENOMEM;
782 goto out_free_virtual;
783 }
784
785 /* allocate pages for the buffer and acquire the according
786 * dma addresses */
787 for (i = 0; i < count; i++) {
788 dma_addr_t dma_data_addr;
789
790 fb->desc_table.virtual[i] =
791 get_zeroed_page(GFP_KERNEL | GFP_DMA);
792 if (!fb->desc_table.virtual[i]) {
793 ret = -ENOBUFS;
794 break;
795 }
796
797 dma_data_addr =
798 dma_map_single(NULL,
799 (void *)fb->desc_table.virtual[i],
800 PAGE_SIZE, DMA_FROM_DEVICE);
801
802 for (j = 0; j < VINO_PAGE_RATIO; j++) {
803 fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i + j] =
804 dma_data_addr + VINO_PAGE_SIZE * j;
805 }
806
807 mem_map_reserve(virt_to_page(fb->desc_table.virtual[i]));
808 }
809
810 /* page_count needs to be set anyway, because the descriptor table has
811 * been allocated according to this number */
812 fb->desc_table.page_count = count;
813
814 if (ret) {
815 /* the descriptor with index i doesn't contain
816 * a valid address yet */
817 vino_free_buffer_with_count(fb, i);
818 return ret;
819 }
820
821 //fb->size = size;
822 fb->size = count * PAGE_SIZE;
823 fb->data_format = VINO_DATA_FMT_NONE;
824
825 /* set the dma stop-bit for the last (count+1)th descriptor */
826 fb->desc_table.dma_cpu[VINO_PAGE_RATIO * count] = VINO_DESC_STOP;
827 return 0;
828
829 out_free_virtual:
830 kfree(fb->desc_table.virtual);
831 return ret;
832}
833
834#if 0
835/* user buffers not fully implemented yet */
836static int vino_prepare_user_buffer(struct vino_framebuffer *fb,
837 void *user,
838 unsigned int size)
839{
840 unsigned int count, i, j;
841 int ret = 0;
842
843 dprintk("vino_prepare_user_buffer():\n");
844
845 if (size < 1)
846 return -EINVAL;
847
848 memset(fb, 0, sizeof(struct vino_framebuffer));
849
850 count = ((size / PAGE_SIZE)) & ~3;
851
852 dprintk("vino_prepare_user_buffer(): size = %d, count = %d\n",
853 size, count);
854
855 /* allocate memory for table with virtual (page) addresses */
856 fb->desc_table.virtual = (unsigned long *)
857 kmalloc(count * sizeof(unsigned long), GFP_KERNEL);
858 if (!fb->desc_table.virtual)
859 return -ENOMEM;
860
861 /* allocate memory for table with dma addresses
862 * (has space for four extra descriptors) */
863 fb->desc_table.dma_cpu =
864 dma_alloc_coherent(NULL, VINO_PAGE_RATIO * (count + 4) *
865 sizeof(dma_addr_t), &fb->desc_table.dma,
866 GFP_KERNEL | GFP_DMA);
867 if (!fb->desc_table.dma_cpu) {
868 ret = -ENOMEM;
869 goto out_free_virtual;
870 }
871
872 /* allocate pages for the buffer and acquire the according
873 * dma addresses */
874 for (i = 0; i < count; i++) {
875 dma_addr_t dma_data_addr;
876
877 fb->desc_table.virtual[i] =
878 get_zeroed_page(GFP_KERNEL | GFP_DMA);
879 if (!fb->desc_table.virtual[i]) {
880 ret = -ENOBUFS;
881 break;
882 }
883
884 dma_data_addr =
885 dma_map_single(NULL,
886 (void *)fb->desc_table.virtual[i],
887 PAGE_SIZE, DMA_FROM_DEVICE);
888
889 for (j = 0; j < VINO_PAGE_RATIO; j++) {
890 fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i + j] =
891 dma_data_addr + VINO_PAGE_SIZE * j;
892 }
893
894 mem_map_reserve(virt_to_page(fb->desc_table.virtual[i]));
895 }
896
897 /* page_count needs to be set anyway, because the descriptor table has
898 * been allocated according to this number */
899 fb->desc_table.page_count = count;
900
901 if (ret) {
902 /* the descriptor with index i doesn't contain
903 * a valid address yet */
904 vino_free_buffer_with_count(fb, i);
905 return ret;
906 }
907
908 //fb->size = size;
909 fb->size = count * PAGE_SIZE;
910
911 /* set the dma stop-bit for the last (count+1)th descriptor */
912 fb->desc_table.dma_cpu[VINO_PAGE_RATIO * count] = VINO_DESC_STOP;
913 return 0;
914
915 out_free_virtual:
916 kfree(fb->desc_table.virtual);
917 return ret;
918}
919#endif
920
921static void vino_sync_buffer(struct vino_framebuffer *fb)
922{
923 int i;
924
925 dprintk("vino_sync_buffer():\n");
926
927 for (i = 0; i < fb->desc_table.page_count; i++)
928 dma_sync_single(NULL,
929 fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i],
930 PAGE_SIZE, DMA_FROM_DEVICE);
931}
932
933/* Framebuffer fifo functions (need to be locked externally) */
934
935static void vino_fifo_init(struct vino_framebuffer_fifo *f,
936 unsigned int length)
937{
938 f->length = 0;
939 f->used = 0;
940 f->head = 0;
941 f->tail = 0;
942
943 if (length > VINO_FRAMEBUFFER_MAX_COUNT)
944 length = VINO_FRAMEBUFFER_MAX_COUNT;
945
946 f->length = length;
947}
948
949/* returns true/false */
950static int vino_fifo_has_id(struct vino_framebuffer_fifo *f, unsigned int id)
951{
952 unsigned int i;
953 for (i = f->head; i == (f->tail - 1); i = (i + 1) % f->length) {
954 if (f->data[i] == id)
955 return 1;
956 }
957
958 return 0;
959}
960
961/* returns true/false */
962static int vino_fifo_full(struct vino_framebuffer_fifo *f)
963{
964 return (f->used == f->length);
965}
966
967static unsigned int vino_fifo_get_used(struct vino_framebuffer_fifo *f)
968{
969 return f->used;
970}
179 971
180static void vino_interrupt(int irq, void *dev_id, struct pt_regs *regs) 972static int vino_fifo_enqueue(struct vino_framebuffer_fifo *f, unsigned int id)
181{ 973{
974 if (id >= f->length) {
975 return VINO_QUEUE_ERROR;
976 }
977
978 if (vino_fifo_has_id(f, id)) {
979 return VINO_QUEUE_ERROR;
980 }
981
982 if (f->used < f->length) {
983 f->data[f->tail] = id;
984 f->tail = (f->tail + 1) % f->length;
985 f->used++;
986 } else {
987 return VINO_QUEUE_ERROR;
988 }
989
990 return 0;
182} 991}
183 992
184static int vino_open(struct video_device *dev, int flags) 993static int vino_fifo_peek(struct vino_framebuffer_fifo *f, unsigned int *id)
185{ 994{
186 struct vino_device *videv = (struct vino_device *)dev; 995 if (f->used > 0) {
996 *id = f->data[f->head];
997 } else {
998 return VINO_QUEUE_ERROR;
999 }
187 1000
188 return 0; 1001 return 0;
189} 1002}
190 1003
191static void vino_close(struct video_device *dev) 1004static int vino_fifo_dequeue(struct vino_framebuffer_fifo *f, unsigned int *id)
192{ 1005{
193 struct vino_device *videv = (struct vino_device *)dev; 1006 if (f->used > 0) {
1007 *id = f->data[f->head];
1008 f->head = (f->head + 1) % f->length;
1009 f->used--;
1010 } else {
1011 return VINO_QUEUE_ERROR;
1012 }
1013
1014 return 0;
194} 1015}
195 1016
196static int vino_mmap(struct video_device *dev, const char *adr, 1017/* Framebuffer queue functions */
197 unsigned long size) 1018
1019/* execute with queue_lock locked */
1020static void vino_queue_free_with_count(struct vino_framebuffer_queue *q,
1021 unsigned int length)
198{ 1022{
199 struct vino_device *videv = (struct vino_device *)dev; 1023 unsigned int i;
200 1024
201 return -EINVAL; 1025 q->length = 0;
1026 memset(&q->in, 0, sizeof(struct vino_framebuffer_fifo));
1027 memset(&q->out, 0, sizeof(struct vino_framebuffer_fifo));
1028 for (i = 0; i < length; i++) {
1029 dprintk("vino_queue_free_with_count(): freeing buffer %d\n",
1030 i);
1031 vino_free_buffer(q->buffer[i]);
1032 kfree(q->buffer[i]);
1033 }
1034
1035 q->type = VINO_MEMORY_NONE;
1036 q->magic = 0;
202} 1037}
203 1038
204static int vino_ioctl(struct video_device *dev, unsigned int cmd, void *arg) 1039static void vino_queue_free(struct vino_framebuffer_queue *q)
205{ 1040{
206 struct vino_device *videv = (struct vino_device *)dev; 1041 dprintk("vino_queue_free():\n");
1042
1043 if (q->magic != VINO_QUEUE_MAGIC)
1044 return;
1045 if (q->type != VINO_MEMORY_MMAP)
1046 return;
1047
1048 down(&q->queue_sem);
1049
1050 vino_queue_free_with_count(q, q->length);
1051
1052 up(&q->queue_sem);
1053}
1054
1055static int vino_queue_init(struct vino_framebuffer_queue *q,
1056 unsigned int *length)
1057{
1058 unsigned int i;
1059 int ret = 0;
1060
1061 dprintk("vino_queue_init(): length = %d\n", *length);
1062
1063 if (q->magic == VINO_QUEUE_MAGIC) {
1064 dprintk("vino_queue_init(): queue already initialized!\n");
1065 return -EINVAL;
1066 }
1067
1068 if (q->type != VINO_MEMORY_NONE) {
1069 dprintk("vino_queue_init(): queue already initialized!\n");
1070 return -EINVAL;
1071 }
1072
1073 if (*length < 1)
1074 return -EINVAL;
1075
1076 down(&q->queue_sem);
1077
1078 if (*length > VINO_FRAMEBUFFER_MAX_COUNT)
1079 *length = VINO_FRAMEBUFFER_MAX_COUNT;
1080
1081 q->length = 0;
1082
1083 for (i = 0; i < *length; i++) {
1084 dprintk("vino_queue_init(): allocating buffer %d\n", i);
1085 q->buffer[i] = kmalloc(sizeof(struct vino_framebuffer),
1086 GFP_KERNEL);
1087 if (!q->buffer[i]) {
1088 dprintk("vino_queue_init(): kmalloc() failed\n");
1089 ret = -ENOMEM;
1090 break;
1091 }
1092
1093 ret = vino_allocate_buffer(q->buffer[i],
1094 VINO_FRAMEBUFFER_SIZE);
1095 if (ret) {
1096 kfree(q->buffer[i]);
1097 dprintk("vino_queue_init(): "
1098 "vino_allocate_buffer() failed\n");
1099 break;
1100 }
1101
1102 q->buffer[i]->id = i;
1103 if (i > 0) {
1104 q->buffer[i]->offset = q->buffer[i - 1]->offset +
1105 q->buffer[i - 1]->size;
1106 } else {
1107 q->buffer[i]->offset = 0;
1108 }
1109
1110 spin_lock_init(&q->buffer[i]->state_lock);
1111
1112 dprintk("vino_queue_init(): buffer = %d, offset = %d, "
1113 "size = %d\n", i, q->buffer[i]->offset,
1114 q->buffer[i]->size);
1115 }
1116
1117 if (ret) {
1118 vino_queue_free_with_count(q, i);
1119 *length = 0;
1120 } else {
1121 q->length = *length;
1122 vino_fifo_init(&q->in, q->length);
1123 vino_fifo_init(&q->out, q->length);
1124 q->type = VINO_MEMORY_MMAP;
1125 q->magic = VINO_QUEUE_MAGIC;
1126 }
1127
1128 up(&q->queue_sem);
1129
1130 return ret;
1131}
1132
1133static struct vino_framebuffer *vino_queue_add(struct
1134 vino_framebuffer_queue *q,
1135 unsigned int id)
1136{
1137 struct vino_framebuffer *ret = NULL;
1138 unsigned int total;
1139 unsigned long flags;
1140
1141 dprintk("vino_queue_add(): id = %d\n", id);
1142
1143 if (q->magic != VINO_QUEUE_MAGIC) {
1144 return ret;
1145 }
1146
1147 spin_lock_irqsave(&q->queue_lock, flags);
1148
1149 if (q->length == 0)
1150 goto out;
1151
1152 if (id >= q->length)
1153 goto out;
1154
1155 /* not needed?: if (vino_fifo_full(&q->out)) {
1156 goto out;
1157 }*/
1158 /* check that outgoing queue isn't already full
1159 * (or that it won't become full) */
1160 total = vino_fifo_get_used(&q->in) +
1161 vino_fifo_get_used(&q->out);
1162 if (total >= q->length)
1163 goto out;
1164
1165 if (vino_fifo_enqueue(&q->in, id))
1166 goto out;
1167
1168 ret = q->buffer[id];
1169
1170out:
1171 spin_unlock_irqrestore(&q->queue_lock, flags);
1172
1173 return ret;
1174}
1175
1176static struct vino_framebuffer *vino_queue_transfer(struct
1177 vino_framebuffer_queue *q)
1178{
1179 struct vino_framebuffer *ret = NULL;
1180 struct vino_framebuffer *fb;
1181 int id;
1182 unsigned long flags;
1183
1184 dprintk("vino_queue_transfer():\n");
1185
1186 if (q->magic != VINO_QUEUE_MAGIC) {
1187 return ret;
1188 }
1189
1190 spin_lock_irqsave(&q->queue_lock, flags);
1191
1192 if (q->length == 0)
1193 goto out;
1194
1195 // now this actually removes an entry from the incoming queue
1196 if (vino_fifo_dequeue(&q->in, &id)) {
1197 goto out;
1198 }
1199
1200 dprintk("vino_queue_transfer(): id = %d\n", id);
1201 fb = q->buffer[id];
1202
1203 // we have already checked that the outgoing queue is not full, but...
1204 if (vino_fifo_enqueue(&q->out, id)) {
1205 printk(KERN_ERR "vino_queue_transfer(): "
1206 "outgoing queue is full, this shouldn't happen!\n");
1207 goto out;
1208 }
1209
1210 ret = fb;
1211out:
1212 spin_unlock_irqrestore(&q->queue_lock, flags);
1213
1214 return ret;
1215}
1216
1217/* returns true/false */
1218static int vino_queue_incoming_contains(struct vino_framebuffer_queue *q,
1219 unsigned int id)
1220{
1221 int ret = 0;
1222 unsigned long flags;
1223
1224 if (q->magic != VINO_QUEUE_MAGIC) {
1225 return ret;
1226 }
1227
1228 spin_lock_irqsave(&q->queue_lock, flags);
1229
1230 if (q->length == 0)
1231 goto out;
1232
1233 ret = vino_fifo_has_id(&q->in, id);
1234
1235out:
1236 spin_unlock_irqrestore(&q->queue_lock, flags);
1237
1238 return ret;
1239}
1240
1241/* returns true/false */
1242static int vino_queue_outgoing_contains(struct vino_framebuffer_queue *q,
1243 unsigned int id)
1244{
1245 int ret = 0;
1246 unsigned long flags;
1247
1248 if (q->magic != VINO_QUEUE_MAGIC) {
1249 return ret;
1250 }
1251
1252 spin_lock_irqsave(&q->queue_lock, flags);
1253
1254 if (q->length == 0)
1255 goto out;
1256
1257 ret = vino_fifo_has_id(&q->out, id);
1258
1259out:
1260 spin_unlock_irqrestore(&q->queue_lock, flags);
1261
1262 return ret;
1263}
1264
1265static int vino_queue_get_incoming(struct vino_framebuffer_queue *q,
1266 unsigned int *used)
1267{
1268 int ret = 0;
1269 unsigned long flags;
1270
1271 if (q->magic != VINO_QUEUE_MAGIC) {
1272 return VINO_QUEUE_ERROR;
1273 }
1274
1275 spin_lock_irqsave(&q->queue_lock, flags);
1276
1277 if (q->length == 0) {
1278 ret = VINO_QUEUE_ERROR;
1279 goto out;
1280 }
1281
1282 *used = vino_fifo_get_used(&q->in);
1283
1284out:
1285 spin_unlock_irqrestore(&q->queue_lock, flags);
1286
1287 return ret;
1288}
1289
1290static int vino_queue_get_outgoing(struct vino_framebuffer_queue *q,
1291 unsigned int *used)
1292{
1293 int ret = 0;
1294 unsigned long flags;
1295
1296 if (q->magic != VINO_QUEUE_MAGIC) {
1297 return VINO_QUEUE_ERROR;
1298 }
1299
1300 spin_lock_irqsave(&q->queue_lock, flags);
1301
1302 if (q->length == 0) {
1303 ret = VINO_QUEUE_ERROR;
1304 goto out;
1305 }
1306
1307 *used = vino_fifo_get_used(&q->out);
1308
1309out:
1310 spin_unlock_irqrestore(&q->queue_lock, flags);
1311
1312 return ret;
1313}
1314
1315static int vino_queue_get_total(struct vino_framebuffer_queue *q,
1316 unsigned int *total)
1317{
1318 int ret = 0;
1319 unsigned long flags;
1320
1321 if (q->magic != VINO_QUEUE_MAGIC) {
1322 return VINO_QUEUE_ERROR;
1323 }
1324
1325 spin_lock_irqsave(&q->queue_lock, flags);
1326
1327 if (q->length == 0) {
1328 ret = VINO_QUEUE_ERROR;
1329 goto out;
1330 }
1331
1332 *total = vino_fifo_get_used(&q->in) +
1333 vino_fifo_get_used(&q->out);
1334
1335out:
1336 spin_unlock_irqrestore(&q->queue_lock, flags);
1337
1338 return ret;
1339}
1340
1341static struct vino_framebuffer *vino_queue_peek(struct
1342 vino_framebuffer_queue *q,
1343 unsigned int *id)
1344{
1345 struct vino_framebuffer *ret = NULL;
1346 unsigned long flags;
1347
1348 if (q->magic != VINO_QUEUE_MAGIC) {
1349 return ret;
1350 }
1351
1352 spin_lock_irqsave(&q->queue_lock, flags);
1353
1354 if (q->length == 0)
1355 goto out;
1356
1357 if (vino_fifo_peek(&q->in, id)) {
1358 goto out;
1359 }
1360
1361 ret = q->buffer[*id];
1362out:
1363 spin_unlock_irqrestore(&q->queue_lock, flags);
1364
1365 return ret;
1366}
1367
1368static struct vino_framebuffer *vino_queue_remove(struct
1369 vino_framebuffer_queue *q,
1370 unsigned int *id)
1371{
1372 struct vino_framebuffer *ret = NULL;
1373 unsigned long flags;
1374 dprintk("vino_queue_remove():\n");
1375
1376 if (q->magic != VINO_QUEUE_MAGIC) {
1377 return ret;
1378 }
1379
1380 spin_lock_irqsave(&q->queue_lock, flags);
1381
1382 if (q->length == 0)
1383 goto out;
1384
1385 if (vino_fifo_dequeue(&q->out, id)) {
1386 goto out;
1387 }
1388
1389 dprintk("vino_queue_remove(): id = %d\n", *id);
1390 ret = q->buffer[*id];
1391out:
1392 spin_unlock_irqrestore(&q->queue_lock, flags);
1393
1394 return ret;
1395}
1396
1397static struct
1398vino_framebuffer *vino_queue_get_buffer(struct vino_framebuffer_queue *q,
1399 unsigned int id)
1400{
1401 struct vino_framebuffer *ret = NULL;
1402 unsigned long flags;
1403
1404 if (q->magic != VINO_QUEUE_MAGIC) {
1405 return ret;
1406 }
1407
1408 spin_lock_irqsave(&q->queue_lock, flags);
1409
1410 if (q->length == 0)
1411 goto out;
1412
1413 if (id >= q->length)
1414 goto out;
1415
1416 ret = q->buffer[id];
1417 out:
1418 spin_unlock_irqrestore(&q->queue_lock, flags);
1419
1420 return ret;
1421}
1422
1423static unsigned int vino_queue_get_length(struct vino_framebuffer_queue *q)
1424{
1425 unsigned int length = 0;
1426 unsigned long flags;
1427
1428 if (q->magic != VINO_QUEUE_MAGIC) {
1429 return length;
1430 }
1431
1432 spin_lock_irqsave(&q->queue_lock, flags);
1433 length = q->length;
1434 spin_unlock_irqrestore(&q->queue_lock, flags);
1435
1436 return length;
1437}
1438
1439static int vino_queue_has_mapped_buffers(struct vino_framebuffer_queue *q)
1440{
1441 unsigned int i;
1442 int ret = 0;
1443 unsigned long flags;
1444
1445 if (q->magic != VINO_QUEUE_MAGIC) {
1446 return ret;
1447 }
1448
1449 spin_lock_irqsave(&q->queue_lock, flags);
1450 for (i = 0; i < q->length; i++) {
1451 if (q->buffer[i]->map_count > 0) {
1452 ret = 1;
1453 break;
1454 }
1455 }
1456 spin_unlock_irqrestore(&q->queue_lock, flags);
1457
1458 return ret;
1459}
1460
1461/* VINO functions */
1462
1463/* execute with input_lock locked */
1464static void vino_update_line_size(struct vino_channel_settings *vcs)
1465{
1466 unsigned int w = vcs->clipping.right - vcs->clipping.left;
1467 unsigned int d = vcs->decimation;
1468 unsigned int bpp = vino_data_formats[vcs->data_format].bpp;
1469 unsigned int lsize;
1470
1471 dprintk("update_line_size(): before: w = %d, d = %d, "
1472 "line_size = %d\n", w, d, vcs->line_size);
1473 /* line size must be multiple of 8 bytes */
1474 lsize = (bpp * (w / d)) & ~7;
1475 w = (lsize / bpp) * d;
1476
1477 vcs->clipping.right = vcs->clipping.left + w;
1478 vcs->line_size = lsize;
1479 dprintk("update_line_size(): after: w = %d, d = %d, "
1480 "line_size = %d\n", w, d, vcs->line_size);
1481}
1482
1483/* execute with input_lock locked */
1484static void vino_set_clipping(struct vino_channel_settings *vcs,
1485 unsigned int x, unsigned int y,
1486 unsigned int w, unsigned int h)
1487{
1488 unsigned int maxwidth, maxheight;
1489 unsigned int d;
1490
1491 maxwidth = vino_data_norms[vcs->data_norm].width;
1492 maxheight = vino_data_norms[vcs->data_norm].height;
1493 d = vcs->decimation;
1494
1495 y &= ~1; /* odd/even fields */
1496
1497 if (x > maxwidth) {
1498 x = 0;
1499 }
1500 if (y > maxheight) {
1501 y = 0;
1502 }
1503
1504 if (((w / d) < VINO_MIN_WIDTH)
1505 || ((h / d) < VINO_MIN_HEIGHT)) {
1506 w = VINO_MIN_WIDTH * d;
1507 h = VINO_MIN_HEIGHT * d;
1508 }
1509
1510 if ((x + w) > maxwidth) {
1511 w = maxwidth - x;
1512 if ((w / d) < VINO_MIN_WIDTH)
1513 x = maxwidth - VINO_MIN_WIDTH * d;
1514 }
1515 if ((y + h) > maxheight) {
1516 h = maxheight - y;
1517 if ((h / d) < VINO_MIN_HEIGHT)
1518 y = maxheight - VINO_MIN_HEIGHT * d;
1519 }
1520
1521 vcs->clipping.left = x;
1522 vcs->clipping.top = y;
1523 vcs->clipping.right = x + w;
1524 vcs->clipping.bottom = y + h;
1525
1526 vino_update_line_size(vcs);
1527
1528 dprintk("clipping %d, %d, %d, %d / %d - %d\n",
1529 vcs->clipping.left, vcs->clipping.top, vcs->clipping.right,
1530 vcs->clipping.bottom, vcs->decimation, vcs->line_size);
1531}
1532
1533/* execute with input_lock locked */
1534static void vino_set_default_clipping(struct vino_channel_settings *vcs)
1535{
1536 vino_set_clipping(vcs, 0, 0, vino_data_norms[vcs->data_norm].width,
1537 vino_data_norms[vcs->data_norm].height);
1538}
1539
1540/* execute with input_lock locked */
1541static void vino_set_scaling(struct vino_channel_settings *vcs,
1542 unsigned int w, unsigned int h)
1543{
1544 unsigned int x, y, curw, curh, d;
1545
1546 x = vcs->clipping.left;
1547 y = vcs->clipping.top;
1548 curw = vcs->clipping.right - vcs->clipping.left;
1549 curh = vcs->clipping.bottom - vcs->clipping.top;
1550
1551 d = max(curw / w, curh / h);
1552
1553 dprintk("scaling w: %d, h: %d, curw: %d, curh: %d, d: %d\n",
1554 w, h, curw, curh, d);
1555
1556 if (d < 1) {
1557 d = 1;
1558 }
1559 if (d > 8) {
1560 d = 8;
1561 }
1562
1563 vcs->decimation = d;
1564 vino_set_clipping(vcs, x, y, w * d, h * d);
1565
1566 dprintk("scaling %d, %d, %d, %d / %d - %d\n", vcs->clipping.left,
1567 vcs->clipping.top, vcs->clipping.right, vcs->clipping.bottom,
1568 vcs->decimation, vcs->line_size);
1569}
1570
1571/* execute with input_lock locked */
1572static void vino_reset_scaling(struct vino_channel_settings *vcs)
1573{
1574 vino_set_scaling(vcs, vcs->clipping.right - vcs->clipping.left,
1575 vcs->clipping.bottom - vcs->clipping.top);
1576}
1577
1578/* execute with input_lock locked */
1579static void vino_set_framerate(struct vino_channel_settings *vcs,
1580 unsigned int fps)
1581{
1582 unsigned int mask;
1583
1584 switch (vcs->data_norm) {
1585 case VINO_DATA_NORM_NTSC:
1586 case VINO_DATA_NORM_D1:
1587 fps = (unsigned int)(fps / 6) * 6; // FIXME: round!
1588
1589 if (fps < vino_data_norms[vcs->data_norm].fps_min)
1590 fps = vino_data_norms[vcs->data_norm].fps_min;
1591 if (fps > vino_data_norms[vcs->data_norm].fps_max)
1592 fps = vino_data_norms[vcs->data_norm].fps_max;
1593
1594 switch (fps) {
1595 case 6:
1596 mask = 0x003;
1597 break;
1598 case 12:
1599 mask = 0x0c3;
1600 break;
1601 case 18:
1602 mask = 0x333;
1603 break;
1604 case 24:
1605 mask = 0x3ff;
1606 break;
1607 case 30:
1608 mask = 0xfff;
1609 break;
1610 default:
1611 mask = VINO_FRAMERT_FULL;
1612 }
1613 vcs->framert_reg = VINO_FRAMERT_RT(mask);
1614 break;
1615 case VINO_DATA_NORM_PAL:
1616 case VINO_DATA_NORM_SECAM:
1617 fps = (unsigned int)(fps / 5) * 5; // FIXME: round!
1618
1619 if (fps < vino_data_norms[vcs->data_norm].fps_min)
1620 fps = vino_data_norms[vcs->data_norm].fps_min;
1621 if (fps > vino_data_norms[vcs->data_norm].fps_max)
1622 fps = vino_data_norms[vcs->data_norm].fps_max;
1623
1624 switch (fps) {
1625 case 5:
1626 mask = 0x003;
1627 break;
1628 case 10:
1629 mask = 0x0c3;
1630 break;
1631 case 15:
1632 mask = 0x333;
1633 break;
1634 case 20:
1635 mask = 0x0ff;
1636 break;
1637 case 25:
1638 mask = 0x3ff;
1639 break;
1640 default:
1641 mask = VINO_FRAMERT_FULL;
1642 }
1643 vcs->framert_reg = VINO_FRAMERT_RT(mask) | VINO_FRAMERT_PAL;
1644 break;
1645 }
1646
1647 vcs->fps = fps;
1648}
1649
1650/* execute with input_lock locked */
1651static void vino_set_default_framerate(struct vino_channel_settings *vcs)
1652{
1653 vino_set_framerate(vcs, vino_data_norms[vcs->data_norm].fps_max);
1654}
1655
1656/*
1657 * Prepare VINO for DMA transfer...
1658 * (execute only with vino_lock and input_lock locked)
1659 */
1660static int vino_dma_setup(struct vino_channel_settings *vcs,
1661 struct vino_framebuffer *fb)
1662{
1663 u32 ctrl, intr;
1664 struct sgi_vino_channel *ch;
1665 const struct vino_data_norm *norm;
1666
1667 dprintk("vino_dma_setup():\n");
1668
1669 vcs->field = 0;
1670 fb->frame_counter = 0;
1671
1672 ch = (vcs->channel == VINO_CHANNEL_A) ? &vino->a : &vino->b;
1673 norm = &vino_data_norms[vcs->data_norm];
1674
1675 ch->page_index = 0;
1676 ch->line_count = 0;
1677
1678 /* VINO line size register is set 8 bytes less than actual */
1679 ch->line_size = vcs->line_size - 8;
1680
1681 /* let VINO know where to transfer data */
1682 ch->start_desc_tbl = fb->desc_table.dma;
1683 ch->next_4_desc = fb->desc_table.dma;
1684
1685 /* give vino time to fetch the first four descriptors, 5 usec
1686 * should be more than enough time */
1687 udelay(VINO_DESC_FETCH_DELAY);
1688
1689 /* set the alpha register */
1690 ch->alpha = vcs->alpha;
1691
1692 /* set clipping registers */
1693 ch->clip_start = VINO_CLIP_ODD(norm->odd.top + vcs->clipping.top / 2) |
1694 VINO_CLIP_EVEN(norm->even.top +
1695 vcs->clipping.top / 2) |
1696 VINO_CLIP_X(vcs->clipping.left);
1697 ch->clip_end = VINO_CLIP_ODD(norm->odd.top +
1698 vcs->clipping.bottom / 2 - 1) |
1699 VINO_CLIP_EVEN(norm->even.top +
1700 vcs->clipping.bottom / 2 - 1) |
1701 VINO_CLIP_X(vcs->clipping.right);
1702 /* FIXME: end-of-field bug workaround
1703 VINO_CLIP_X(VINO_PAL_WIDTH);
1704 */
1705
1706 /* set the size of actual content in the buffer (DECIMATION !) */
1707 fb->data_size = ((vcs->clipping.right - vcs->clipping.left) /
1708 vcs->decimation) *
1709 ((vcs->clipping.bottom - vcs->clipping.top) /
1710 vcs->decimation) *
1711 vino_data_formats[vcs->data_format].bpp;
1712
1713 ch->frame_rate = vcs->framert_reg;
1714
1715 ctrl = vino->control;
1716 intr = vino->intr_status;
1717
1718 if (vcs->channel == VINO_CHANNEL_A) {
1719 /* All interrupt conditions for this channel was cleared
1720 * so clear the interrupt status register and enable
1721 * interrupts */
1722 intr &= ~VINO_INTSTAT_A;
1723 ctrl |= VINO_CTRL_A_INT;
1724
1725 /* enable synchronization */
1726 ctrl |= VINO_CTRL_A_SYNC_ENBL;
1727
1728 /* enable frame assembly */
1729 ctrl |= VINO_CTRL_A_INTERLEAVE_ENBL;
1730
1731 /* set decimation used */
1732 if (vcs->decimation < 2)
1733 ctrl &= ~VINO_CTRL_A_DEC_ENBL;
1734 else {
1735 ctrl |= VINO_CTRL_A_DEC_ENBL;
1736 ctrl &= ~VINO_CTRL_A_DEC_SCALE_MASK;
1737 ctrl |= (vcs->decimation - 1) <<
1738 VINO_CTRL_A_DEC_SCALE_SHIFT;
1739 }
1740
1741 /* select input interface */
1742 if (vcs->input == VINO_INPUT_D1)
1743 ctrl |= VINO_CTRL_A_SELECT;
1744 else
1745 ctrl &= ~VINO_CTRL_A_SELECT;
1746
1747 /* palette */
1748 ctrl &= ~(VINO_CTRL_A_LUMA_ONLY | VINO_CTRL_A_RGB |
1749 VINO_CTRL_A_DITHER);
1750 } else {
1751 intr &= ~VINO_INTSTAT_B;
1752 ctrl |= VINO_CTRL_B_INT;
1753
1754 ctrl |= VINO_CTRL_B_SYNC_ENBL;
1755 ctrl |= VINO_CTRL_B_INTERLEAVE_ENBL;
1756
1757 if (vcs->decimation < 2)
1758 ctrl &= ~VINO_CTRL_B_DEC_ENBL;
1759 else {
1760 ctrl |= VINO_CTRL_B_DEC_ENBL;
1761 ctrl &= ~VINO_CTRL_B_DEC_SCALE_MASK;
1762 ctrl |= (vcs->decimation - 1) <<
1763 VINO_CTRL_B_DEC_SCALE_SHIFT;
1764
1765 }
1766 if (vcs->input == VINO_INPUT_D1)
1767 ctrl |= VINO_CTRL_B_SELECT;
1768 else
1769 ctrl &= ~VINO_CTRL_B_SELECT;
1770
1771 ctrl &= ~(VINO_CTRL_B_LUMA_ONLY | VINO_CTRL_B_RGB |
1772 VINO_CTRL_B_DITHER);
1773 }
1774
1775 /* set palette */
1776 fb->data_format = vcs->data_format;
1777
1778 switch (vcs->data_format) {
1779 case VINO_DATA_FMT_GREY:
1780 ctrl |= (vcs->channel == VINO_CHANNEL_A) ?
1781 VINO_CTRL_A_LUMA_ONLY : VINO_CTRL_B_LUMA_ONLY;
1782 break;
1783 case VINO_DATA_FMT_RGB32:
1784 ctrl |= (vcs->channel == VINO_CHANNEL_A) ?
1785 VINO_CTRL_A_RGB : VINO_CTRL_B_RGB;
1786 break;
1787 case VINO_DATA_FMT_YUV:
1788 /* nothing needs to be done */
1789 break;
1790 case VINO_DATA_FMT_RGB332:
1791 ctrl |= (vcs->channel == VINO_CHANNEL_A) ?
1792 VINO_CTRL_A_RGB | VINO_CTRL_A_DITHER :
1793 VINO_CTRL_B_RGB | VINO_CTRL_B_DITHER;
1794 break;
1795 }
1796
1797 vino->intr_status = intr;
1798 vino->control = ctrl;
1799
1800 return 0;
1801}
1802
1803/* (execute only with vino_lock locked) */
1804static void vino_dma_start(struct vino_channel_settings *vcs)
1805{
1806 u32 ctrl = vino->control;
1807
1808 dprintk("vino_dma_start():\n");
1809 ctrl |= (vcs->channel == VINO_CHANNEL_A) ?
1810 VINO_CTRL_A_DMA_ENBL : VINO_CTRL_B_DMA_ENBL;
1811 vino->control = ctrl;
1812}
1813
1814/* (execute only with vino_lock locked) */
1815static void vino_dma_stop(struct vino_channel_settings *vcs)
1816{
1817 u32 ctrl = vino->control;
1818
1819 ctrl &= (vcs->channel == VINO_CHANNEL_A) ?
1820 ~VINO_CTRL_A_DMA_ENBL : ~VINO_CTRL_B_DMA_ENBL;
1821 vino->control = ctrl;
1822 dprintk("vino_dma_stop():\n");
1823}
1824
1825/*
1826 * Load dummy page to descriptor registers. This prevents generating of
1827 * spurious interrupts. (execute only with vino_lock locked)
1828 */
1829static void vino_clear_interrupt(struct vino_channel_settings *vcs)
1830{
1831 struct sgi_vino_channel *ch;
1832
1833 ch = (vcs->channel == VINO_CHANNEL_A) ? &vino->a : &vino->b;
1834
1835 ch->page_index = 0;
1836 ch->line_count = 0;
1837
1838 ch->start_desc_tbl = vino_drvdata->dummy_desc_table.dma;
1839 ch->next_4_desc = vino_drvdata->dummy_desc_table.dma;
1840
1841 udelay(VINO_DESC_FETCH_DELAY);
1842 dprintk("channel %c clear interrupt condition\n",
1843 (vcs->channel == VINO_CHANNEL_A) ? 'A':'B');
1844}
1845
1846static int vino_capture(struct vino_channel_settings *vcs,
1847 struct vino_framebuffer *fb)
1848{
1849 int err = 0;
1850 unsigned long flags, flags2;
1851
1852 spin_lock_irqsave(&fb->state_lock, flags);
1853
1854 if (fb->state == VINO_FRAMEBUFFER_IN_USE)
1855 err = -EBUSY;
1856 fb->state = VINO_FRAMEBUFFER_IN_USE;
1857
1858 spin_unlock_irqrestore(&fb->state_lock, flags);
1859
1860 if (err)
1861 return err;
1862
1863 spin_lock_irqsave(&vino_drvdata->vino_lock, flags);
1864 spin_lock_irqsave(&vino_drvdata->input_lock, flags2);
1865
1866 vino_dma_setup(vcs, fb);
1867 vino_dma_start(vcs);
1868
1869 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags2);
1870 spin_unlock_irqrestore(&vino_drvdata->vino_lock, flags);
1871
1872 return err;
1873}
1874
1875static
1876struct vino_framebuffer *vino_capture_enqueue(struct
1877 vino_channel_settings *vcs,
1878 unsigned int index)
1879{
1880 struct vino_framebuffer *fb;
1881 unsigned long flags;
1882
1883 dprintk("vino_capture_enqueue():\n");
1884
1885 spin_lock_irqsave(&vcs->capture_lock, flags);
1886
1887 fb = vino_queue_add(&vcs->fb_queue, index);
1888 if (fb == NULL) {
1889 dprintk("vino_capture_enqueue(): vino_queue_add() failed, "
1890 "queue full?\n");
1891 goto out;
1892 }
1893out:
1894 spin_unlock_irqrestore(&vcs->capture_lock, flags);
1895
1896 return fb;
1897}
1898
1899static int vino_capture_next(struct vino_channel_settings *vcs, int start)
1900{
1901 struct vino_framebuffer *fb;
1902 unsigned int incoming, id;
1903 int err = 0;
1904 unsigned long flags, flags2;
1905
1906 dprintk("vino_capture_next():\n");
1907
1908 spin_lock_irqsave(&vcs->capture_lock, flags);
1909
1910 if (start) {
1911 /* start capture only if capture isn't in progress already */
1912 if (vcs->capturing) {
1913 spin_unlock_irqrestore(&vcs->capture_lock, flags);
1914 return 0;
1915 }
1916
1917 } else {
1918 /* capture next frame:
1919 * stop capture if capturing is not set */
1920 if (!vcs->capturing) {
1921 spin_unlock_irqrestore(&vcs->capture_lock, flags);
1922 return 0;
1923 }
1924 }
1925
1926 err = vino_queue_get_incoming(&vcs->fb_queue, &incoming);
1927 if (err) {
1928 dprintk("vino_capture_next(): vino_queue_get_incoming() "
1929 "failed\n");
1930 err = -EINVAL;
1931 goto out;
1932 }
1933 if (incoming == 0) {
1934 dprintk("vino_capture_next(): no buffers available\n");
1935 goto out;
1936 }
1937
1938 fb = vino_queue_peek(&vcs->fb_queue, &id);
1939 if (fb == NULL) {
1940 dprintk("vino_capture_next(): vino_queue_peek() failed\n");
1941 err = -EINVAL;
1942 goto out;
1943 }
1944
1945 spin_lock_irqsave(&fb->state_lock, flags2);
1946 fb->state = VINO_FRAMEBUFFER_UNUSED;
1947 spin_unlock_irqrestore(&fb->state_lock, flags2);
1948
1949 if (start) {
1950 vcs->capturing = 1;
1951 }
1952
1953 spin_unlock_irqrestore(&vcs->capture_lock, flags);
1954
1955 err = vino_capture(vcs, fb);
1956
1957 return err;
1958
1959out:
1960 vcs->capturing = 0;
1961 spin_unlock_irqrestore(&vcs->capture_lock, flags);
1962
1963 return err;
1964}
1965
1966static int vino_is_capturing(struct vino_channel_settings *vcs)
1967{
1968 int ret;
1969 unsigned long flags;
1970
1971 spin_lock_irqsave(&vcs->capture_lock, flags);
1972
1973 ret = vcs->capturing;
1974
1975 spin_unlock_irqrestore(&vcs->capture_lock, flags);
1976
1977 return ret;
1978}
1979
1980/* waits until a frame is captured */
1981static int vino_wait_for_frame(struct vino_channel_settings *vcs)
1982{
1983 wait_queue_t wait;
1984 int err = 0;
1985
1986 dprintk("vino_wait_for_frame():\n");
1987
1988 init_waitqueue_entry(&wait, current);
1989 /* add ourselves into wait queue */
1990 add_wait_queue(&vcs->fb_queue.frame_wait_queue, &wait);
1991 /* and set current state */
1992 set_current_state(TASK_INTERRUPTIBLE);
1993
1994 /* to ensure that schedule_timeout will return immediately
1995 * if VINO interrupt was triggred meanwhile */
1996 schedule_timeout(HZ / 10);
1997
1998 if (signal_pending(current))
1999 err = -EINTR;
2000
2001 remove_wait_queue(&vcs->fb_queue.frame_wait_queue, &wait);
2002
2003 dprintk("vino_wait_for_frame(): waiting for frame %s\n",
2004 err ? "failed" : "ok");
2005
2006 return err;
2007}
2008
2009/* the function assumes that PAGE_SIZE % 4 == 0 */
2010static void vino_convert_to_rgba(struct vino_framebuffer *fb) {
2011 unsigned char *pageptr;
2012 unsigned int page, i;
2013 unsigned char a;
2014
2015 for (page = 0; page < fb->desc_table.page_count; page++) {
2016 pageptr = (unsigned char *)fb->desc_table.virtual[page];
2017
2018 for (i = 0; i < PAGE_SIZE; i += 4) {
2019 a = pageptr[0];
2020 pageptr[0] = pageptr[3];
2021 pageptr[1] = pageptr[2];
2022 pageptr[2] = pageptr[1];
2023 pageptr[3] = a;
2024 pageptr += 4;
2025 }
2026 }
2027}
2028
2029/* checks if the buffer is in correct state and syncs data */
2030static int vino_check_buffer(struct vino_channel_settings *vcs,
2031 struct vino_framebuffer *fb)
2032{
2033 int err = 0;
2034 unsigned long flags;
2035
2036 dprintk("vino_check_buffer():\n");
2037
2038 spin_lock_irqsave(&fb->state_lock, flags);
2039 switch (fb->state) {
2040 case VINO_FRAMEBUFFER_IN_USE:
2041 err = -EIO;
2042 break;
2043 case VINO_FRAMEBUFFER_READY:
2044 vino_sync_buffer(fb);
2045 fb->state = VINO_FRAMEBUFFER_UNUSED;
2046 break;
2047 default:
2048 err = -EINVAL;
2049 }
2050 spin_unlock_irqrestore(&fb->state_lock, flags);
2051
2052 if (!err) {
2053 if (vino_pixel_conversion
2054 && (fb->data_format == VINO_DATA_FMT_RGB32)) {
2055 vino_convert_to_rgba(fb);
2056 }
2057 } else if (err && (err != -EINVAL)) {
2058 dprintk("vino_check_buffer(): buffer not ready\n");
2059
2060 spin_lock_irqsave(&vino_drvdata->vino_lock, flags);
2061 vino_dma_stop(vcs);
2062 vino_clear_interrupt(vcs);
2063 spin_unlock_irqrestore(&vino_drvdata->vino_lock, flags);
2064 }
2065
2066 return err;
2067}
2068
2069/* forcefully terminates capture */
2070static void vino_capture_stop(struct vino_channel_settings *vcs)
2071{
2072 unsigned int incoming = 0, outgoing = 0, id;
2073 unsigned long flags, flags2;
2074
2075 dprintk("vino_capture_stop():\n");
2076
2077 spin_lock_irqsave(&vcs->capture_lock, flags);
2078 /* unset capturing to stop queue processing */
2079 vcs->capturing = 0;
2080
2081 spin_lock_irqsave(&vino_drvdata->vino_lock, flags2);
2082
2083 vino_dma_stop(vcs);
2084 vino_clear_interrupt(vcs);
2085
2086 spin_unlock_irqrestore(&vino_drvdata->vino_lock, flags2);
2087
2088 /* remove all items from the queue */
2089 if (vino_queue_get_incoming(&vcs->fb_queue, &incoming)) {
2090 dprintk("vino_capture_stop(): "
2091 "vino_queue_get_incoming() failed\n");
2092 goto out;
2093 }
2094 while (incoming > 0) {
2095 vino_queue_transfer(&vcs->fb_queue);
2096
2097 if (vino_queue_get_incoming(&vcs->fb_queue, &incoming)) {
2098 dprintk("vino_capture_stop(): "
2099 "vino_queue_get_incoming() failed\n");
2100 goto out;
2101 }
2102 }
2103
2104 if (vino_queue_get_outgoing(&vcs->fb_queue, &outgoing)) {
2105 dprintk("vino_capture_stop(): "
2106 "vino_queue_get_outgoing() failed\n");
2107 goto out;
2108 }
2109 while (outgoing > 0) {
2110 vino_queue_remove(&vcs->fb_queue, &id);
2111
2112 if (vino_queue_get_outgoing(&vcs->fb_queue, &outgoing)) {
2113 dprintk("vino_capture_stop(): "
2114 "vino_queue_get_outgoing() failed\n");
2115 goto out;
2116 }
2117 }
2118
2119out:
2120 spin_unlock_irqrestore(&vcs->capture_lock, flags);
2121}
2122
2123static int vino_capture_failed(struct vino_channel_settings *vcs)
2124{
2125 struct vino_framebuffer *fb;
2126 unsigned long flags;
2127 unsigned int i;
2128 int ret;
2129
2130 dprintk("vino_capture_failed():\n");
2131
2132 spin_lock_irqsave(&vino_drvdata->vino_lock, flags);
2133
2134 vino_dma_stop(vcs);
2135 vino_clear_interrupt(vcs);
2136
2137 spin_unlock_irqrestore(&vino_drvdata->vino_lock, flags);
2138
2139 ret = vino_queue_get_incoming(&vcs->fb_queue, &i);
2140 if (ret == VINO_QUEUE_ERROR) {
2141 dprintk("vino_queue_get_incoming() failed\n");
2142 return -EINVAL;
2143 }
2144 if (i == 0) {
2145 /* no buffers to process */
2146 return 0;
2147 }
2148
2149 fb = vino_queue_peek(&vcs->fb_queue, &i);
2150 if (fb == NULL) {
2151 dprintk("vino_queue_peek() failed\n");
2152 return -EINVAL;
2153 }
2154
2155 spin_lock_irqsave(&fb->state_lock, flags);
2156 if (fb->state == VINO_FRAMEBUFFER_IN_USE) {
2157 fb->state = VINO_FRAMEBUFFER_UNUSED;
2158 vino_queue_transfer(&vcs->fb_queue);
2159 vino_queue_remove(&vcs->fb_queue, &i);
2160 /* we should actually discard the newest frame,
2161 * but who cares ... */
2162 }
2163 spin_unlock_irqrestore(&fb->state_lock, flags);
2164
2165 return 0;
2166}
2167
2168static void vino_frame_done(struct vino_channel_settings *vcs,
2169 unsigned int fc)
2170{
2171 struct vino_framebuffer *fb;
2172 unsigned long flags;
2173
2174 spin_lock_irqsave(&vcs->capture_lock, flags);
2175 fb = vino_queue_transfer(&vcs->fb_queue);
2176 if (!fb) {
2177 spin_unlock_irqrestore(&vcs->capture_lock, flags);
2178 dprintk("vino_frame_done(): vino_queue_transfer() failed!\n");
2179 return;
2180 }
2181 spin_unlock_irqrestore(&vcs->capture_lock, flags);
2182
2183 fb->frame_counter = fc;
2184 do_gettimeofday(&fb->timestamp);
2185
2186 spin_lock_irqsave(&fb->state_lock, flags);
2187 if (fb->state == VINO_FRAMEBUFFER_IN_USE)
2188 fb->state = VINO_FRAMEBUFFER_READY;
2189 spin_unlock_irqrestore(&fb->state_lock, flags);
2190
2191 wake_up(&vcs->fb_queue.frame_wait_queue);
2192
2193 vino_capture_next(vcs, 0);
2194}
2195
2196static irqreturn_t vino_interrupt(int irq, void *dev_id, struct pt_regs *regs)
2197{
2198 u32 intr;
2199 unsigned int fc_a, fc_b;
2200 int done_a = 0;
2201 int done_b = 0;
2202
2203 spin_lock(&vino_drvdata->vino_lock);
2204
2205 intr = vino->intr_status;
2206 fc_a = vino->a.field_counter / 2;
2207 fc_b = vino->b.field_counter / 2;
2208
2209 // TODO: handle error-interrupts in some special way ?
2210
2211 if (intr & VINO_INTSTAT_A) {
2212 if (intr & VINO_INTSTAT_A_EOF) {
2213 vino_drvdata->a.field++;
2214 if (vino_drvdata->a.field > 1) {
2215 vino_dma_stop(&vino_drvdata->a);
2216 vino_clear_interrupt(&vino_drvdata->a);
2217 vino_drvdata->a.field = 0;
2218 done_a = 1;
2219 }
2220 dprintk("intr: channel A end-of-field interrupt: "
2221 "%04x\n", intr);
2222 } else {
2223 vino_dma_stop(&vino_drvdata->a);
2224 vino_clear_interrupt(&vino_drvdata->a);
2225 done_a = 1;
2226 dprintk("channel A error interrupt: %04x\n", intr);
2227 }
2228 }
2229 if (intr & VINO_INTSTAT_B) {
2230 if (intr & VINO_INTSTAT_B_EOF) {
2231 vino_drvdata->b.field++;
2232 if (vino_drvdata->b.field > 1) {
2233 vino_dma_stop(&vino_drvdata->b);
2234 vino_clear_interrupt(&vino_drvdata->b);
2235 vino_drvdata->b.field = 0;
2236 done_b = 1;
2237 }
2238 dprintk("intr: channel B end-of-field interrupt: "
2239 "%04x\n", intr);
2240 } else {
2241 vino_dma_stop(&vino_drvdata->b);
2242 vino_clear_interrupt(&vino_drvdata->b);
2243 done_b = 1;
2244 dprintk("channel B error interrupt: %04x\n", intr);
2245 }
2246 }
2247
2248 /* always remember to clear interrupt status */
2249 vino->intr_status = ~intr;
2250
2251 spin_unlock(&vino_drvdata->vino_lock);
2252
2253 if (done_a) {
2254 vino_frame_done(&vino_drvdata->a, fc_a);
2255 dprintk("channel A frame done, interrupt: %d\n", intr);
2256 }
2257 if (done_b) {
2258 vino_frame_done(&vino_drvdata->b, fc_b);
2259 dprintk("channel B frame done, interrupt: %d\n", intr);
2260 }
207 2261
208 return -EINVAL; 2262 return IRQ_HANDLED;
209} 2263}
210 2264
211static const struct video_device vino_device = { 2265/* VINO video input management */
2266
2267static int vino_get_saa7191_input(int input)
2268{
2269 switch (input) {
2270 case VINO_INPUT_COMPOSITE:
2271 return SAA7191_INPUT_COMPOSITE;
2272 case VINO_INPUT_SVIDEO:
2273 return SAA7191_INPUT_SVIDEO;
2274 default:
2275 printk(KERN_ERR "VINO: vino_get_saa7191_input(): "
2276 "invalid input!\n");
2277 return -1;
2278 }
2279}
2280
2281static int vino_get_saa7191_norm(int norm)
2282{
2283 switch (norm) {
2284 case VINO_DATA_NORM_AUTO:
2285 return SAA7191_NORM_AUTO;
2286 case VINO_DATA_NORM_PAL:
2287 return SAA7191_NORM_PAL;
2288 case VINO_DATA_NORM_NTSC:
2289 return SAA7191_NORM_NTSC;
2290 case VINO_DATA_NORM_SECAM:
2291 return SAA7191_NORM_SECAM;
2292 default:
2293 printk(KERN_ERR "VINO: vino_get_saa7191_norm(): "
2294 "invalid norm!\n");
2295 return -1;
2296 }
2297}
2298
2299/* execute with input_lock locked */
2300static int vino_is_input_owner(struct vino_channel_settings *vcs)
2301{
2302 switch(vcs->input) {
2303 case VINO_INPUT_COMPOSITE:
2304 case VINO_INPUT_SVIDEO:
2305 return (vino_drvdata->decoder.owner == vcs->channel);
2306 case VINO_INPUT_D1:
2307 return (vino_drvdata->camera.owner == vcs->channel);
2308 default:
2309 return 0;
2310 }
2311}
2312
2313static int vino_acquire_input(struct vino_channel_settings *vcs)
2314{
2315 int ret = 0;
2316
2317 dprintk("vino_acquire_input():\n");
2318
2319 spin_lock(&vino_drvdata->input_lock);
2320
2321 /* First try D1 and then SAA7191 */
2322 if (vino_drvdata->camera.driver
2323 && (vino_drvdata->camera.owner == VINO_NO_CHANNEL)) {
2324 if (i2c_use_client(vino_drvdata->camera.driver)) {
2325 ret = -ENODEV;
2326 goto out;
2327 }
2328
2329 vino_drvdata->camera.owner = vcs->channel;
2330 vcs->input = VINO_INPUT_D1;
2331 vcs->data_norm = VINO_DATA_NORM_D1;
2332 } else if (vino_drvdata->decoder.driver
2333 && (vino_drvdata->decoder.owner == VINO_NO_CHANNEL)) {
2334 int saa7191_input;
2335 int saa7191_norm;
2336
2337 if (i2c_use_client(vino_drvdata->decoder.driver)) {
2338 ret = -ENODEV;
2339 goto out;
2340 }
2341
2342 vino_drvdata->decoder.owner = vcs->channel;
2343 vcs->input = VINO_INPUT_COMPOSITE;
2344 vcs->data_norm = VINO_DATA_NORM_PAL;
2345
2346 saa7191_input = vino_get_saa7191_input(vcs->input);
2347 i2c_decoder_command(DECODER_SET_INPUT, &saa7191_input);
2348
2349 saa7191_norm = vino_get_saa7191_norm(vcs->data_norm);
2350 i2c_decoder_command(DECODER_SAA7191_SET_NORM, &saa7191_norm);
2351 } else {
2352 vcs->input = (vcs->channel == VINO_CHANNEL_A) ?
2353 vino_drvdata->b.input : vino_drvdata->a.input;
2354 vcs->data_norm = (vcs->channel == VINO_CHANNEL_A) ?
2355 vino_drvdata->b.data_norm : vino_drvdata->a.data_norm;
2356 }
2357
2358 if (vcs->input == VINO_INPUT_NONE) {
2359 ret = -ENODEV;
2360 goto out;
2361 }
2362
2363 if (vino_is_input_owner(vcs)) {
2364 vino_set_default_clipping(vcs);
2365 vino_set_default_framerate(vcs);
2366 }
2367
2368 dprintk("vino_acquire_input(): %s\n", vino_inputs[vcs->input].name);
2369
2370out:
2371 spin_unlock(&vino_drvdata->input_lock);
2372
2373 return ret;
2374}
2375
2376static int vino_set_input(struct vino_channel_settings *vcs, int input)
2377{
2378 struct vino_channel_settings *vcs2 = (vcs->channel == VINO_CHANNEL_A) ?
2379 &vino_drvdata->b : &vino_drvdata->a;
2380 int ret = 0;
2381
2382 dprintk("vino_set_input():\n");
2383
2384 spin_lock(&vino_drvdata->input_lock);
2385
2386 if (vcs->input == input)
2387 goto out;
2388
2389 switch(input) {
2390 case VINO_INPUT_COMPOSITE:
2391 case VINO_INPUT_SVIDEO:
2392 if (!vino_drvdata->decoder.driver) {
2393 ret = -EINVAL;
2394 goto out;
2395 }
2396
2397 if (vino_drvdata->decoder.owner == VINO_NO_CHANNEL) {
2398 if (i2c_use_client(vino_drvdata->decoder.driver)) {
2399 ret = -ENODEV;
2400 goto out;
2401 }
2402 vino_drvdata->decoder.owner = vcs->channel;
2403 }
2404
2405 if (vino_drvdata->decoder.owner == vcs->channel) {
2406 int saa7191_input;
2407 int saa7191_norm;
2408
2409 vcs->input = input;
2410 vcs->data_norm = VINO_DATA_NORM_PAL;
2411
2412 saa7191_input = vino_get_saa7191_input(vcs->input);
2413 i2c_decoder_command(DECODER_SET_INPUT, &saa7191_input);
2414 saa7191_norm = vino_get_saa7191_norm(vcs->data_norm);
2415 i2c_decoder_command(DECODER_SAA7191_SET_NORM,
2416 &saa7191_norm);
2417 } else {
2418 if (vcs2->input != input) {
2419 ret = -EBUSY;
2420 goto out;
2421 }
2422
2423 vcs->input = input;
2424 vcs->data_norm = vcs2->data_norm;
2425 }
2426
2427 if (vino_drvdata->camera.owner == vcs->channel) {
2428 /* Transfer the ownership or release the input */
2429 if (vcs2->input == VINO_INPUT_D1) {
2430 vino_drvdata->camera.owner = vcs2->channel;
2431 } else {
2432 i2c_release_client(vino_drvdata->
2433 camera.driver);
2434 vino_drvdata->camera.owner = VINO_NO_CHANNEL;
2435 }
2436 }
2437 break;
2438 case VINO_INPUT_D1:
2439 if (!vino_drvdata->camera.driver) {
2440 ret = -EINVAL;
2441 goto out;
2442 }
2443
2444 if (vino_drvdata->camera.owner == VINO_NO_CHANNEL) {
2445 if (i2c_use_client(vino_drvdata->camera.driver)) {
2446 ret = -ENODEV;
2447 goto out;
2448 }
2449 vino_drvdata->camera.owner = vcs->channel;
2450 }
2451
2452 if (vino_drvdata->decoder.owner == vcs->channel) {
2453 /* Transfer the ownership or release the input */
2454 if ((vcs2->input == VINO_INPUT_COMPOSITE) ||
2455 (vcs2->input == VINO_INPUT_SVIDEO)) {
2456 vino_drvdata->decoder.owner = vcs2->channel;
2457 } else {
2458 i2c_release_client(vino_drvdata->
2459 decoder.driver);
2460 vino_drvdata->decoder.owner = VINO_NO_CHANNEL;
2461 }
2462 }
2463
2464 vcs->input = input;
2465 vcs->data_norm = VINO_DATA_NORM_D1;
2466 break;
2467 default:
2468 ret = -EINVAL;
2469 goto out;
2470 }
2471
2472 vino_set_default_clipping(vcs);
2473 vino_set_default_framerate(vcs);
2474
2475 dprintk("vino_set_input(): %s\n", vino_inputs[vcs->input].name);
2476
2477out:
2478 spin_unlock(&vino_drvdata->input_lock);
2479
2480 return ret;
2481}
2482
2483static void vino_release_input(struct vino_channel_settings *vcs)
2484{
2485 struct vino_channel_settings *vcs2 = (vcs->channel == VINO_CHANNEL_A) ?
2486 &vino_drvdata->b : &vino_drvdata->a;
2487
2488 dprintk("vino_release_input():\n");
2489
2490 spin_lock(&vino_drvdata->input_lock);
2491
2492 /* Release ownership of the channel
2493 * and if the other channel takes input from
2494 * the same source, transfer the ownership */
2495 if (vino_drvdata->camera.owner == vcs->channel) {
2496 if (vcs2->input == VINO_INPUT_D1) {
2497 vino_drvdata->camera.owner = vcs2->channel;
2498 } else {
2499 i2c_release_client(vino_drvdata->camera.driver);
2500 vino_drvdata->camera.owner = VINO_NO_CHANNEL;
2501 }
2502 } else if (vino_drvdata->decoder.owner == vcs->channel) {
2503 if ((vcs2->input == VINO_INPUT_COMPOSITE) ||
2504 (vcs2->input == VINO_INPUT_SVIDEO)) {
2505 vino_drvdata->decoder.owner = vcs2->channel;
2506 } else {
2507 i2c_release_client(vino_drvdata->decoder.driver);
2508 vino_drvdata->decoder.owner = VINO_NO_CHANNEL;
2509 }
2510 }
2511 vcs->input = VINO_INPUT_NONE;
2512
2513 spin_unlock(&vino_drvdata->input_lock);
2514}
2515
2516/* execute with input_lock locked */
2517static int vino_set_data_norm(struct vino_channel_settings *vcs,
2518 unsigned int data_norm)
2519{
2520 int saa7191_norm;
2521
2522 switch (vcs->input) {
2523 case VINO_INPUT_D1:
2524 /* only one "norm" supported */
2525 if (data_norm != VINO_DATA_NORM_D1)
2526 return -EINVAL;
2527 break;
2528 case VINO_INPUT_COMPOSITE:
2529 case VINO_INPUT_SVIDEO:
2530
2531 saa7191_norm = vino_get_saa7191_norm(data_norm);
2532
2533 i2c_decoder_command(DECODER_SAA7191_SET_NORM, &saa7191_norm);
2534 vcs->data_norm = data_norm;
2535 break;
2536 default:
2537 return -EINVAL;
2538 }
2539
2540 return 0;
2541}
2542
2543/* V4L2 helper functions */
2544
2545static int vino_find_data_format(__u32 pixelformat)
2546{
2547 int i;
2548
2549 for (i = 0; i < VINO_DATA_FMT_COUNT; i++) {
2550 if (vino_data_formats[i].pixelformat == pixelformat)
2551 return i;
2552 }
2553
2554 return VINO_DATA_FMT_NONE;
2555}
2556
2557static int vino_enum_data_norm(struct vino_channel_settings *vcs, __u32 index)
2558{
2559 int data_norm = VINO_DATA_NORM_NONE;
2560
2561 spin_lock(&vino_drvdata->input_lock);
2562 switch(vcs->input) {
2563 case VINO_INPUT_COMPOSITE:
2564 case VINO_INPUT_SVIDEO:
2565 if (index == 0) {
2566 data_norm = VINO_DATA_NORM_PAL;
2567 } else if (index == 1) {
2568 data_norm = VINO_DATA_NORM_NTSC;
2569 } else if (index == 2) {
2570 data_norm = VINO_DATA_NORM_SECAM;
2571 }
2572 break;
2573 case VINO_INPUT_D1:
2574 if (index == 0) {
2575 data_norm = VINO_DATA_NORM_D1;
2576 }
2577 break;
2578 }
2579 spin_unlock(&vino_drvdata->input_lock);
2580
2581 return data_norm;
2582}
2583
2584static int vino_enum_input(struct vino_channel_settings *vcs, __u32 index)
2585{
2586 int input = VINO_INPUT_NONE;
2587
2588 spin_lock(&vino_drvdata->input_lock);
2589 if (vino_drvdata->decoder.driver && vino_drvdata->camera.driver) {
2590 switch (index) {
2591 case 0:
2592 input = VINO_INPUT_COMPOSITE;
2593 break;
2594 case 1:
2595 input = VINO_INPUT_SVIDEO;
2596 break;
2597 case 2:
2598 input = VINO_INPUT_D1;
2599 break;
2600 }
2601 } else if (vino_drvdata->decoder.driver) {
2602 switch (index) {
2603 case 0:
2604 input = VINO_INPUT_COMPOSITE;
2605 break;
2606 case 1:
2607 input = VINO_INPUT_SVIDEO;
2608 break;
2609 }
2610 } else if (vino_drvdata->camera.driver) {
2611 switch (index) {
2612 case 0:
2613 input = VINO_INPUT_D1;
2614 break;
2615 }
2616 }
2617 spin_unlock(&vino_drvdata->input_lock);
2618
2619 return input;
2620}
2621
2622/* execute with input_lock locked */
2623static __u32 vino_find_input_index(struct vino_channel_settings *vcs)
2624{
2625 __u32 index = 0;
2626 // FIXME: detect when no inputs available
2627
2628 if (vino_drvdata->decoder.driver && vino_drvdata->camera.driver) {
2629 switch (vcs->input) {
2630 case VINO_INPUT_COMPOSITE:
2631 index = 0;
2632 break;
2633 case VINO_INPUT_SVIDEO:
2634 index = 1;
2635 break;
2636 case VINO_INPUT_D1:
2637 index = 2;
2638 break;
2639 }
2640 } else if (vino_drvdata->decoder.driver) {
2641 switch (vcs->input) {
2642 case VINO_INPUT_COMPOSITE:
2643 index = 0;
2644 break;
2645 case VINO_INPUT_SVIDEO:
2646 index = 1;
2647 break;
2648 }
2649 } else if (vino_drvdata->camera.driver) {
2650 switch (vcs->input) {
2651 case VINO_INPUT_D1:
2652 index = 0;
2653 break;
2654 }
2655 }
2656
2657 return index;
2658}
2659
2660/* V4L2 ioctls */
2661
2662static void vino_v4l2_querycap(struct v4l2_capability *cap)
2663{
2664 memset(cap, 0, sizeof(struct v4l2_capability));
2665
2666 strcpy(cap->driver, vino_driver_name);
2667 strcpy(cap->card, vino_driver_description);
2668 strcpy(cap->bus_info, vino_bus_name);
2669 cap->version = VINO_VERSION_CODE;
2670 cap->capabilities =
2671 V4L2_CAP_VIDEO_CAPTURE |
2672 V4L2_CAP_STREAMING;
2673 // V4L2_CAP_OVERLAY, V4L2_CAP_READWRITE
2674}
2675
2676static int vino_v4l2_enuminput(struct vino_channel_settings *vcs,
2677 struct v4l2_input *i)
2678{
2679 __u32 index = i->index;
2680 int input;
2681 dprintk("requested index = %d\n", index);
2682
2683 input = vino_enum_input(vcs, index);
2684 if (input == VINO_INPUT_NONE)
2685 return -EINVAL;
2686
2687 memset(i, 0, sizeof(struct v4l2_input));
2688
2689 i->index = index;
2690 i->type = V4L2_INPUT_TYPE_CAMERA;
2691 i->std = vino_inputs[input].std;
2692 strcpy(i->name, vino_inputs[input].name);
2693
2694 if ((input == VINO_INPUT_COMPOSITE)
2695 || (input == VINO_INPUT_SVIDEO)) {
2696 struct saa7191_status status;
2697 i2c_decoder_command(DECODER_SAA7191_GET_STATUS, &status);
2698 i->status |= status.signal ? 0 : V4L2_IN_ST_NO_SIGNAL;
2699 i->status |= status.color ? 0 : V4L2_IN_ST_NO_COLOR;
2700 }
2701
2702 return 0;
2703}
2704
2705static int vino_v4l2_g_input(struct vino_channel_settings *vcs,
2706 struct v4l2_input *i)
2707{
2708 __u32 index;
2709 int input;
2710
2711 spin_lock(&vino_drvdata->input_lock);
2712 input = vcs->input;
2713 index = vino_find_input_index(vcs);
2714 spin_unlock(&vino_drvdata->input_lock);
2715
2716 dprintk("input = %d\n", input);
2717
2718 if (input == VINO_INPUT_NONE) {
2719 return -EINVAL;
2720 }
2721
2722 memset(i, 0, sizeof(struct v4l2_input));
2723
2724 i->index = index;
2725 i->type = V4L2_INPUT_TYPE_CAMERA;
2726 i->std = vino_inputs[input].std;
2727 strcpy(i->name, vino_inputs[input].name);
2728
2729 return 0;
2730}
2731
2732static int vino_v4l2_s_input(struct vino_channel_settings *vcs,
2733 struct v4l2_input *i)
2734{
2735 int input;
2736 dprintk("requested input = %d\n", i->index);
2737
2738 input = vino_enum_input(vcs, i->index);
2739 if (input == VINO_INPUT_NONE)
2740 return -EINVAL;
2741
2742 return vino_set_input(vcs, input);
2743}
2744
2745static int vino_v4l2_enumstd(struct vino_channel_settings *vcs,
2746 struct v4l2_standard *s)
2747{
2748 int index = s->index;
2749 int data_norm = vino_enum_data_norm(vcs, index);
2750 dprintk("standard index = %d\n", index);
2751
2752 if (data_norm == VINO_DATA_NORM_NONE)
2753 return -EINVAL;
2754
2755 dprintk("standard name = %s\n",
2756 vino_data_norms[data_norm].description);
2757
2758 memset(s, 0, sizeof(struct v4l2_standard));
2759 s->index = index;
2760
2761 s->id = vino_data_norms[data_norm].std;
2762 s->frameperiod.numerator = 1;
2763 s->frameperiod.denominator =
2764 vino_data_norms[data_norm].fps_max;
2765 s->framelines =
2766 vino_data_norms[data_norm].framelines;
2767 strcpy(s->name,
2768 vino_data_norms[data_norm].description);
2769
2770 return 0;
2771}
2772
2773static int vino_v4l2_g_std(struct vino_channel_settings *vcs,
2774 v4l2_std_id *std)
2775{
2776 spin_lock(&vino_drvdata->input_lock);
2777 dprintk("current standard = %d\n", vcs->data_norm);
2778 *std = vino_data_norms[vcs->data_norm].std;
2779 spin_unlock(&vino_drvdata->input_lock);
2780
2781 return 0;
2782}
2783
2784static int vino_v4l2_s_std(struct vino_channel_settings *vcs,
2785 v4l2_std_id *std)
2786{
2787 int ret = 0;
2788
2789 spin_lock(&vino_drvdata->input_lock);
2790
2791 /* check if the standard is valid for the current input */
2792 if (vino_is_input_owner(vcs)
2793 && (vino_inputs[vcs->input].std & (*std))) {
2794 dprintk("standard accepted\n");
2795
2796 /* change the video norm for SAA7191
2797 * and accept NTSC for D1 (do nothing) */
2798
2799 if (vcs->input == VINO_INPUT_D1)
2800 goto out;
2801
2802 if ((*std) & V4L2_STD_PAL) {
2803 vino_set_data_norm(vcs, VINO_DATA_NORM_PAL);
2804 vcs->data_norm = VINO_DATA_NORM_PAL;
2805 } else if ((*std) & V4L2_STD_NTSC) {
2806 vino_set_data_norm(vcs, VINO_DATA_NORM_NTSC);
2807 vcs->data_norm = VINO_DATA_NORM_NTSC;
2808 } else if ((*std) & V4L2_STD_SECAM) {
2809 vino_set_data_norm(vcs, VINO_DATA_NORM_SECAM);
2810 vcs->data_norm = VINO_DATA_NORM_SECAM;
2811 } else {
2812 ret = -EINVAL;
2813 }
2814 } else {
2815 ret = -EINVAL;
2816 }
2817
2818out:
2819 spin_unlock(&vino_drvdata->input_lock);
2820
2821 return ret;
2822}
2823
2824static int vino_v4l2_enum_fmt(struct vino_channel_settings *vcs,
2825 struct v4l2_fmtdesc *fd)
2826{
2827 enum v4l2_buf_type type = fd->type;
2828 int index = fd->index;
2829 dprintk("format index = %d\n", index);
2830
2831 switch (fd->type) {
2832 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2833 if ((fd->index < 0) ||
2834 (fd->index >= VINO_DATA_FMT_COUNT))
2835 return -EINVAL;
2836 dprintk("format name = %s\n",
2837 vino_data_formats[index].description);
2838
2839 memset(fd, 0, sizeof(struct v4l2_fmtdesc));
2840 fd->index = index;
2841 fd->type = type;
2842 fd->pixelformat = vino_data_formats[index].pixelformat;
2843 strcpy(fd->description, vino_data_formats[index].description);
2844 break;
2845 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2846 default:
2847 return -EINVAL;
2848 }
2849
2850 return 0;
2851}
2852
2853static int vino_v4l2_try_fmt(struct vino_channel_settings *vcs,
2854 struct v4l2_format *f)
2855{
2856 struct vino_channel_settings tempvcs;
2857
2858 switch (f->type) {
2859 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
2860 struct v4l2_pix_format *pf = &f->fmt.pix;
2861
2862 dprintk("requested: w = %d, h = %d\n",
2863 pf->width, pf->height);
2864
2865 spin_lock(&vino_drvdata->input_lock);
2866 memcpy(&tempvcs, vcs, sizeof(struct vino_channel_settings));
2867 spin_unlock(&vino_drvdata->input_lock);
2868
2869 tempvcs.data_format = vino_find_data_format(pf->pixelformat);
2870 if (tempvcs.data_format == VINO_DATA_FMT_NONE) {
2871 tempvcs.data_format = VINO_DATA_FMT_RGB32;
2872 pf->pixelformat =
2873 vino_data_formats[tempvcs.data_format].
2874 pixelformat;
2875 }
2876
2877 /* data format must be set before clipping/scaling */
2878 vino_set_scaling(&tempvcs, pf->width, pf->height);
2879
2880 dprintk("data format = %s\n",
2881 vino_data_formats[tempvcs.data_format].description);
2882
2883 pf->width = (tempvcs.clipping.right - tempvcs.clipping.left) /
2884 tempvcs.decimation;
2885 pf->height = (tempvcs.clipping.bottom - tempvcs.clipping.top) /
2886 tempvcs.decimation;
2887
2888 pf->field = V4L2_FIELD_INTERLACED;
2889 pf->bytesperline = tempvcs.line_size;
2890 pf->sizeimage = tempvcs.line_size *
2891 (tempvcs.clipping.bottom - tempvcs.clipping.top) /
2892 tempvcs.decimation;
2893 pf->colorspace =
2894 vino_data_formats[tempvcs.data_format].colorspace;
2895
2896 pf->priv = 0;
2897 break;
2898 }
2899 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2900 default:
2901 return -EINVAL;
2902 }
2903
2904 return 0;
2905}
2906
2907static int vino_v4l2_g_fmt(struct vino_channel_settings *vcs,
2908 struct v4l2_format *f)
2909{
2910 switch (f->type) {
2911 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
2912 struct v4l2_pix_format *pf = &f->fmt.pix;
2913 spin_lock(&vino_drvdata->input_lock);
2914
2915 pf->width = (vcs->clipping.right - vcs->clipping.left) /
2916 vcs->decimation;
2917 pf->height = (vcs->clipping.bottom - vcs->clipping.top) /
2918 vcs->decimation;
2919 pf->pixelformat =
2920 vino_data_formats[vcs->data_format].pixelformat;
2921
2922 pf->field = V4L2_FIELD_INTERLACED;
2923 pf->bytesperline = vcs->line_size;
2924 pf->sizeimage = vcs->line_size *
2925 (vcs->clipping.bottom - vcs->clipping.top) /
2926 vcs->decimation;
2927 pf->colorspace =
2928 vino_data_formats[vcs->data_format].colorspace;
2929
2930 pf->priv = 0;
2931
2932 spin_unlock(&vino_drvdata->input_lock);
2933 break;
2934 }
2935 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2936 default:
2937 return -EINVAL;
2938 }
2939
2940 return 0;
2941}
2942
2943static int vino_v4l2_s_fmt(struct vino_channel_settings *vcs,
2944 struct v4l2_format *f)
2945{
2946 int data_format;
2947
2948 switch (f->type) {
2949 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
2950 struct v4l2_pix_format *pf = &f->fmt.pix;
2951 spin_lock(&vino_drvdata->input_lock);
2952
2953 if (!vino_is_input_owner(vcs)) {
2954 spin_unlock(&vino_drvdata->input_lock);
2955 return -EINVAL;
2956 }
2957
2958 data_format = vino_find_data_format(pf->pixelformat);
2959 if (data_format == VINO_DATA_FMT_NONE) {
2960 vcs->data_format = VINO_DATA_FMT_RGB32;
2961 pf->pixelformat =
2962 vino_data_formats[vcs->data_format].
2963 pixelformat;
2964 } else {
2965 vcs->data_format = data_format;
2966 }
2967
2968 /* data format must be set before clipping/scaling */
2969 vino_set_scaling(vcs, pf->width, pf->height);
2970
2971 dprintk("data format = %s\n",
2972 vino_data_formats[vcs->data_format].description);
2973
2974 pf->width = vcs->clipping.right - vcs->clipping.left;
2975 pf->height = vcs->clipping.bottom - vcs->clipping.top;
2976
2977 pf->field = V4L2_FIELD_INTERLACED;
2978 pf->bytesperline = vcs->line_size;
2979 pf->sizeimage = vcs->line_size *
2980 (vcs->clipping.bottom - vcs->clipping.top) /
2981 vcs->decimation;
2982 pf->colorspace =
2983 vino_data_formats[vcs->data_format].colorspace;
2984
2985 pf->priv = 0;
2986
2987 spin_unlock(&vino_drvdata->input_lock);
2988 break;
2989 }
2990 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2991 default:
2992 return -EINVAL;
2993 }
2994
2995 return 0;
2996}
2997
2998static int vino_v4l2_cropcap(struct vino_channel_settings *vcs,
2999 struct v4l2_cropcap *ccap)
3000{
3001 const struct vino_data_norm *norm;
3002
3003 switch (ccap->type) {
3004 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
3005 spin_lock(&vino_drvdata->input_lock);
3006 norm = &vino_data_norms[vcs->data_norm];
3007 spin_unlock(&vino_drvdata->input_lock);
3008
3009 ccap->bounds.left = 0;
3010 ccap->bounds.top = 0;
3011 ccap->bounds.width = norm->width;
3012 ccap->bounds.height = norm->height;
3013 memcpy(&ccap->defrect, &ccap->bounds,
3014 sizeof(struct v4l2_rect));
3015
3016 ccap->pixelaspect.numerator = 1;
3017 ccap->pixelaspect.denominator = 1;
3018 break;
3019 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3020 default:
3021 return -EINVAL;
3022 }
3023
3024 return 0;
3025}
3026
3027static int vino_v4l2_g_crop(struct vino_channel_settings *vcs,
3028 struct v4l2_crop *c)
3029{
3030 switch (c->type) {
3031 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
3032 spin_lock(&vino_drvdata->input_lock);
3033
3034 c->c.left = vcs->clipping.left;
3035 c->c.top = vcs->clipping.top;
3036 c->c.width = vcs->clipping.right - vcs->clipping.left;
3037 c->c.height = vcs->clipping.bottom - vcs->clipping.top;
3038
3039 spin_unlock(&vino_drvdata->input_lock);
3040 break;
3041 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3042 default:
3043 return -EINVAL;
3044 }
3045
3046 return 0;
3047}
3048
3049static int vino_v4l2_s_crop(struct vino_channel_settings *vcs,
3050 struct v4l2_crop *c)
3051{
3052 switch (c->type) {
3053 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
3054 spin_lock(&vino_drvdata->input_lock);
3055
3056 if (!vino_is_input_owner(vcs)) {
3057 spin_unlock(&vino_drvdata->input_lock);
3058 return -EINVAL;
3059 }
3060 vino_set_clipping(vcs, c->c.left, c->c.top,
3061 c->c.width, c->c.height);
3062
3063 spin_unlock(&vino_drvdata->input_lock);
3064 break;
3065 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3066 default:
3067 return -EINVAL;
3068 }
3069
3070 return 0;
3071}
3072
3073static int vino_v4l2_g_parm(struct vino_channel_settings *vcs,
3074 struct v4l2_streamparm *sp)
3075{
3076 switch (sp->type) {
3077 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
3078 struct v4l2_captureparm *cp = &sp->parm.capture;
3079 memset(cp, 0, sizeof(struct v4l2_captureparm));
3080
3081 cp->capability = V4L2_CAP_TIMEPERFRAME;
3082 cp->timeperframe.numerator = 1;
3083
3084 spin_lock(&vino_drvdata->input_lock);
3085 cp->timeperframe.denominator = vcs->fps;
3086 spin_unlock(&vino_drvdata->input_lock);
3087
3088 // TODO: cp->readbuffers = xxx;
3089 break;
3090 }
3091 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3092 default:
3093 return -EINVAL;
3094 }
3095
3096 return 0;
3097}
3098
3099static int vino_v4l2_s_parm(struct vino_channel_settings *vcs,
3100 struct v4l2_streamparm *sp)
3101{
3102 switch (sp->type) {
3103 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
3104 struct v4l2_captureparm *cp = &sp->parm.capture;
3105
3106 spin_lock(&vino_drvdata->input_lock);
3107 if (!vino_is_input_owner(vcs)) {
3108 spin_unlock(&vino_drvdata->input_lock);
3109 return -EINVAL;
3110 }
3111
3112 if ((cp->timeperframe.numerator == 0) ||
3113 (cp->timeperframe.denominator == 0)) {
3114 /* reset framerate */
3115 vino_set_default_framerate(vcs);
3116 } else {
3117 vino_set_framerate(vcs, cp->timeperframe.denominator /
3118 cp->timeperframe.numerator);
3119 }
3120 spin_unlock(&vino_drvdata->input_lock);
3121
3122 // TODO: set buffers according to cp->readbuffers
3123 break;
3124 }
3125 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3126 default:
3127 return -EINVAL;
3128 }
3129
3130 return 0;
3131}
3132
3133static int vino_v4l2_reqbufs(struct vino_channel_settings *vcs,
3134 struct v4l2_requestbuffers *rb)
3135{
3136 if (vcs->reading)
3137 return -EBUSY;
3138
3139 switch (rb->type) {
3140 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
3141 // TODO: check queue type
3142 if (rb->memory != V4L2_MEMORY_MMAP) {
3143 dprintk("type not mmap\n");
3144 return -EINVAL;
3145 }
3146
3147 if (vino_is_capturing(vcs)) {
3148 dprintk("busy, capturing\n");
3149 return -EBUSY;
3150 }
3151
3152 dprintk("count = %d\n", rb->count);
3153 if (rb->count > 0) {
3154 if (vino_queue_has_mapped_buffers(&vcs->fb_queue)) {
3155 dprintk("busy, buffers still mapped\n");
3156 return -EBUSY;
3157 } else {
3158 vino_queue_free(&vcs->fb_queue);
3159 vino_queue_init(&vcs->fb_queue, &rb->count);
3160 }
3161 } else {
3162 vino_capture_stop(vcs);
3163 vino_queue_free(&vcs->fb_queue);
3164 }
3165 break;
3166 }
3167 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3168 default:
3169 return -EINVAL;
3170 }
3171
3172 return 0;
3173}
3174
3175static void vino_v4l2_get_buffer_status(struct vino_channel_settings *vcs,
3176 struct vino_framebuffer *fb,
3177 struct v4l2_buffer *b)
3178{
3179 if (vino_queue_outgoing_contains(&vcs->fb_queue,
3180 fb->id)) {
3181 b->flags &= ~V4L2_BUF_FLAG_QUEUED;
3182 b->flags |= V4L2_BUF_FLAG_DONE;
3183 } else if (vino_queue_incoming_contains(&vcs->fb_queue,
3184 fb->id)) {
3185 b->flags &= ~V4L2_BUF_FLAG_DONE;
3186 b->flags |= V4L2_BUF_FLAG_QUEUED;
3187 } else {
3188 b->flags &= ~(V4L2_BUF_FLAG_DONE |
3189 V4L2_BUF_FLAG_QUEUED);
3190 }
3191
3192 b->flags &= ~(V4L2_BUF_FLAG_TIMECODE);
3193
3194 if (fb->map_count > 0)
3195 b->flags |= V4L2_BUF_FLAG_MAPPED;
3196
3197 b->index = fb->id;
3198 b->memory = (vcs->fb_queue.type == VINO_MEMORY_MMAP) ?
3199 V4L2_MEMORY_MMAP : V4L2_MEMORY_USERPTR;
3200 b->m.offset = fb->offset;
3201 b->bytesused = fb->data_size;
3202 b->length = fb->size;
3203 b->field = V4L2_FIELD_INTERLACED;
3204 b->sequence = fb->frame_counter;
3205 memcpy(&b->timestamp, &fb->timestamp,
3206 sizeof(struct timeval));
3207 // b->input ?
3208
3209 dprintk("buffer %d: length = %d, bytesused = %d, offset = %d\n",
3210 fb->id, fb->size, fb->data_size, fb->offset);
3211}
3212
3213static int vino_v4l2_querybuf(struct vino_channel_settings *vcs,
3214 struct v4l2_buffer *b)
3215{
3216 if (vcs->reading)
3217 return -EBUSY;
3218
3219 switch (b->type) {
3220 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
3221 struct vino_framebuffer *fb;
3222
3223 // TODO: check queue type
3224 if (b->index >= vino_queue_get_length(&vcs->fb_queue)) {
3225 dprintk("invalid index = %d\n",
3226 b->index);
3227 return -EINVAL;
3228 }
3229
3230 fb = vino_queue_get_buffer(&vcs->fb_queue,
3231 b->index);
3232 if (fb == NULL) {
3233 dprintk("vino_queue_get_buffer() failed");
3234 return -EINVAL;
3235 }
3236
3237 vino_v4l2_get_buffer_status(vcs, fb, b);
3238 break;
3239 }
3240 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3241 default:
3242 return -EINVAL;
3243 }
3244
3245 return 0;
3246}
3247
3248static int vino_v4l2_qbuf(struct vino_channel_settings *vcs,
3249 struct v4l2_buffer *b)
3250{
3251 if (vcs->reading)
3252 return -EBUSY;
3253
3254 switch (b->type) {
3255 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
3256 struct vino_framebuffer *fb;
3257 int ret;
3258
3259 // TODO: check queue type
3260 if (b->memory != V4L2_MEMORY_MMAP) {
3261 dprintk("type not mmap\n");
3262 return -EINVAL;
3263 }
3264
3265 fb = vino_capture_enqueue(vcs, b->index);
3266 if (fb == NULL)
3267 return -EINVAL;
3268
3269 vino_v4l2_get_buffer_status(vcs, fb, b);
3270
3271 if (vcs->streaming) {
3272 ret = vino_capture_next(vcs, 1);
3273 if (ret)
3274 return ret;
3275 }
3276 break;
3277 }
3278 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3279 default:
3280 return -EINVAL;
3281 }
3282
3283 return 0;
3284}
3285
3286static int vino_v4l2_dqbuf(struct vino_channel_settings *vcs,
3287 struct v4l2_buffer *b,
3288 unsigned int nonblocking)
3289{
3290 if (vcs->reading)
3291 return -EBUSY;
3292
3293 switch (b->type) {
3294 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
3295 struct vino_framebuffer *fb;
3296 unsigned int incoming, outgoing;
3297 int err;
3298
3299 // TODO: check queue type
3300
3301 err = vino_queue_get_incoming(&vcs->fb_queue, &incoming);
3302 if (err) {
3303 dprintk("vino_queue_get_incoming() failed\n");
3304 return -EIO;
3305 }
3306 err = vino_queue_get_outgoing(&vcs->fb_queue, &outgoing);
3307 if (err) {
3308 dprintk("vino_queue_get_outgoing() failed\n");
3309 return -EIO;
3310 }
3311
3312 dprintk("incoming = %d, outgoing = %d\n", incoming, outgoing);
3313
3314 if (outgoing == 0) {
3315 if (incoming == 0) {
3316 dprintk("no incoming or outgoing buffers\n");
3317 return -EINVAL;
3318 }
3319 if (nonblocking) {
3320 dprintk("non-blocking I/O was selected and "
3321 "there are no buffers to dequeue\n");
3322 return -EAGAIN;
3323 }
3324
3325 err = vino_wait_for_frame(vcs);
3326 if (err) {
3327 err = vino_wait_for_frame(vcs);
3328 if (err) {
3329 /* interrupted */
3330 vino_capture_failed(vcs);
3331 return -EIO;
3332 }
3333 }
3334 }
3335
3336 fb = vino_queue_remove(&vcs->fb_queue, &b->index);
3337 if (fb == NULL) {
3338 dprintk("vino_queue_remove() failed\n");
3339 return -EINVAL;
3340 }
3341
3342 err = vino_check_buffer(vcs, fb);
3343 if (err)
3344 return -EIO;
3345
3346 vino_v4l2_get_buffer_status(vcs, fb, b);
3347 break;
3348 }
3349 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3350 default:
3351 return -EINVAL;
3352 }
3353
3354 return 0;
3355}
3356
3357static int vino_v4l2_streamon(struct vino_channel_settings *vcs)
3358{
3359 unsigned int incoming;
3360 int ret;
3361 if (vcs->reading)
3362 return -EBUSY;
3363
3364 if (vcs->streaming)
3365 return 0;
3366
3367 // TODO: check queue type
3368
3369 if (vino_queue_get_length(&vcs->fb_queue) < 1) {
3370 dprintk("no buffers allocated\n");
3371 return -EINVAL;
3372 }
3373
3374 ret = vino_queue_get_incoming(&vcs->fb_queue, &incoming);
3375 if (ret) {
3376 dprintk("vino_queue_get_incoming() failed\n");
3377 return -EINVAL;
3378 }
3379
3380 vcs->streaming = 1;
3381
3382 if (incoming > 0) {
3383 ret = vino_capture_next(vcs, 1);
3384 if (ret) {
3385 vcs->streaming = 0;
3386
3387 dprintk("couldn't start capture\n");
3388 return -EINVAL;
3389 }
3390 }
3391
3392 return 0;
3393}
3394
3395static int vino_v4l2_streamoff(struct vino_channel_settings *vcs)
3396{
3397 if (vcs->reading)
3398 return -EBUSY;
3399
3400 if (!vcs->streaming)
3401 return 0;
3402
3403 vino_capture_stop(vcs);
3404 vcs->streaming = 0;
3405
3406 return 0;
3407}
3408
3409static int vino_v4l2_queryctrl(struct vino_channel_settings *vcs,
3410 struct v4l2_queryctrl *queryctrl)
3411{
3412 int i;
3413 int err = 0;
3414
3415 spin_lock(&vino_drvdata->input_lock);
3416
3417 switch (vcs->input) {
3418 case VINO_INPUT_D1:
3419 for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) {
3420 if (vino_indycam_v4l2_controls[i].id ==
3421 queryctrl->id) {
3422 memcpy(queryctrl,
3423 &vino_indycam_v4l2_controls[i],
3424 sizeof(struct v4l2_queryctrl));
3425 goto found;
3426 }
3427 }
3428
3429 err = -EINVAL;
3430 break;
3431 case VINO_INPUT_COMPOSITE:
3432 case VINO_INPUT_SVIDEO:
3433 for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) {
3434 if (vino_saa7191_v4l2_controls[i].id ==
3435 queryctrl->id) {
3436 memcpy(queryctrl,
3437 &vino_saa7191_v4l2_controls[i],
3438 sizeof(struct v4l2_queryctrl));
3439 goto found;
3440 }
3441 }
3442
3443 err = -EINVAL;
3444 break;
3445 default:
3446 err = -EINVAL;
3447 }
3448
3449 found:
3450 spin_unlock(&vino_drvdata->input_lock);
3451
3452 return err;
3453}
3454
3455static int vino_v4l2_g_ctrl(struct vino_channel_settings *vcs,
3456 struct v4l2_control *control)
3457{
3458 struct indycam_control indycam_ctrl;
3459 struct saa7191_control saa7191_ctrl;
3460 int err = 0;
3461
3462 spin_lock(&vino_drvdata->input_lock);
3463
3464 switch (vcs->input) {
3465 case VINO_INPUT_D1:
3466 i2c_camera_command(DECODER_INDYCAM_GET_CONTROLS,
3467 &indycam_ctrl);
3468
3469 switch(control->id) {
3470 case V4L2_CID_AUTOGAIN:
3471 control->value = indycam_ctrl.agc;
3472 break;
3473 case V4L2_CID_AUTO_WHITE_BALANCE:
3474 control->value = indycam_ctrl.awb;
3475 break;
3476 case V4L2_CID_GAIN:
3477 control->value = indycam_ctrl.gain;
3478 break;
3479 case V4L2_CID_PRIVATE_BASE:
3480 control->value = indycam_ctrl.red_saturation;
3481 break;
3482 case V4L2_CID_PRIVATE_BASE + 1:
3483 control->value = indycam_ctrl.blue_saturation;
3484 break;
3485 case V4L2_CID_RED_BALANCE:
3486 control->value = indycam_ctrl.red_balance;
3487 break;
3488 case V4L2_CID_BLUE_BALANCE:
3489 control->value = indycam_ctrl.blue_balance;
3490 break;
3491 case V4L2_CID_EXPOSURE:
3492 control->value = indycam_ctrl.shutter;
3493 break;
3494 case V4L2_CID_GAMMA:
3495 control->value = indycam_ctrl.gamma;
3496 break;
3497 default:
3498 err = -EINVAL;
3499 }
3500 break;
3501 case VINO_INPUT_COMPOSITE:
3502 case VINO_INPUT_SVIDEO:
3503 i2c_decoder_command(DECODER_SAA7191_GET_CONTROLS,
3504 &saa7191_ctrl);
3505
3506 switch(control->id) {
3507 case V4L2_CID_HUE:
3508 control->value = saa7191_ctrl.hue;
3509 break;
3510 case V4L2_CID_PRIVATE_BASE:
3511 control->value = saa7191_ctrl.vtrc;
3512 break;
3513 default:
3514 err = -EINVAL;
3515 }
3516 break;
3517 default:
3518 err = -EINVAL;
3519 }
3520
3521 spin_unlock(&vino_drvdata->input_lock);
3522
3523 return err;
3524}
3525
3526static int vino_v4l2_s_ctrl(struct vino_channel_settings *vcs,
3527 struct v4l2_control *control)
3528{
3529 struct indycam_control indycam_ctrl;
3530 struct saa7191_control saa7191_ctrl;
3531 int i;
3532 int err = 0;
3533
3534 spin_lock(&vino_drvdata->input_lock);
3535
3536 switch (vcs->input) {
3537 case VINO_INPUT_D1:
3538 for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) {
3539 if (vino_indycam_v4l2_controls[i].id ==
3540 control->id) {
3541 if ((control->value >=
3542 vino_indycam_v4l2_controls[i].minimum)
3543 && (control->value <=
3544 vino_indycam_v4l2_controls[i].
3545 maximum)) {
3546 goto ok1;
3547 } else {
3548 err = -ERANGE;
3549 goto error;
3550 }
3551 }
3552 }
3553 err = -EINVAL;
3554 goto error;
3555
3556ok1:
3557 indycam_ctrl.agc = INDYCAM_VALUE_UNCHANGED;
3558 indycam_ctrl.awb = INDYCAM_VALUE_UNCHANGED;
3559 indycam_ctrl.shutter = INDYCAM_VALUE_UNCHANGED;
3560 indycam_ctrl.gain = INDYCAM_VALUE_UNCHANGED;
3561 indycam_ctrl.red_balance = INDYCAM_VALUE_UNCHANGED;
3562 indycam_ctrl.blue_balance = INDYCAM_VALUE_UNCHANGED;
3563 indycam_ctrl.red_saturation = INDYCAM_VALUE_UNCHANGED;
3564 indycam_ctrl.blue_saturation = INDYCAM_VALUE_UNCHANGED;
3565 indycam_ctrl.gamma = INDYCAM_VALUE_UNCHANGED;
3566
3567 switch(control->id) {
3568 case V4L2_CID_AUTOGAIN:
3569 indycam_ctrl.agc = control->value;
3570 break;
3571 case V4L2_CID_AUTO_WHITE_BALANCE:
3572 indycam_ctrl.awb = control->value;
3573 break;
3574 case V4L2_CID_GAIN:
3575 indycam_ctrl.gain = control->value;
3576 break;
3577 case V4L2_CID_PRIVATE_BASE:
3578 indycam_ctrl.red_saturation = control->value;
3579 break;
3580 case V4L2_CID_PRIVATE_BASE + 1:
3581 indycam_ctrl.blue_saturation = control->value;
3582 break;
3583 case V4L2_CID_RED_BALANCE:
3584 indycam_ctrl.red_balance = control->value;
3585 break;
3586 case V4L2_CID_BLUE_BALANCE:
3587 indycam_ctrl.blue_balance = control->value;
3588 break;
3589 case V4L2_CID_EXPOSURE:
3590 indycam_ctrl.shutter = control->value;
3591 break;
3592 case V4L2_CID_GAMMA:
3593 indycam_ctrl.gamma = control->value;
3594 break;
3595 default:
3596 err = -EINVAL;
3597 }
3598
3599 if (!err)
3600 i2c_camera_command(DECODER_INDYCAM_SET_CONTROLS,
3601 &indycam_ctrl);
3602 break;
3603 case VINO_INPUT_COMPOSITE:
3604 case VINO_INPUT_SVIDEO:
3605 for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) {
3606 if (vino_saa7191_v4l2_controls[i].id ==
3607 control->id) {
3608 if ((control->value >=
3609 vino_saa7191_v4l2_controls[i].minimum)
3610 && (control->value <=
3611 vino_saa7191_v4l2_controls[i].
3612 maximum)) {
3613 goto ok2;
3614 } else {
3615 err = -ERANGE;
3616 goto error;
3617 }
3618 }
3619 }
3620 err = -EINVAL;
3621 goto error;
3622
3623ok2:
3624 saa7191_ctrl.hue = SAA7191_VALUE_UNCHANGED;
3625 saa7191_ctrl.vtrc = SAA7191_VALUE_UNCHANGED;
3626
3627 switch(control->id) {
3628 case V4L2_CID_HUE:
3629 saa7191_ctrl.hue = control->value;
3630 break;
3631 case V4L2_CID_PRIVATE_BASE:
3632 saa7191_ctrl.vtrc = control->value;
3633 break;
3634 default:
3635 err = -EINVAL;
3636 }
3637
3638 if (!err)
3639 i2c_decoder_command(DECODER_SAA7191_SET_CONTROLS,
3640 &saa7191_ctrl);
3641 break;
3642 default:
3643 err = -EINVAL;
3644 }
3645
3646error:
3647 spin_unlock(&vino_drvdata->input_lock);
3648
3649 return err;
3650}
3651
3652/* File operations */
3653
3654static int vino_open(struct inode *inode, struct file *file)
3655{
3656 struct video_device *dev = video_devdata(file);
3657 struct vino_channel_settings *vcs = video_get_drvdata(dev);
3658 int ret = 0;
3659 dprintk("open(): channel = %c\n",
3660 (vcs->channel == VINO_CHANNEL_A) ? 'A' : 'B');
3661
3662 down(&vcs->sem);
3663
3664 if (vcs->users) {
3665 dprintk("open(): driver busy\n");
3666 ret = -EBUSY;
3667 goto out;
3668 }
3669
3670 ret = vino_acquire_input(vcs);
3671 if (ret) {
3672 dprintk("open(): vino_acquire_input() failed\n");
3673 goto out;
3674 }
3675
3676 vcs->users++;
3677
3678 out:
3679 up(&vcs->sem);
3680
3681 dprintk("open(): %s!\n", ret ? "failed" : "complete");
3682
3683 return ret;
3684}
3685
3686static int vino_close(struct inode *inode, struct file *file)
3687{
3688 struct video_device *dev = video_devdata(file);
3689 struct vino_channel_settings *vcs = video_get_drvdata(dev);
3690 dprintk("close():\n");
3691
3692 down(&vcs->sem);
3693
3694 vcs->users--;
3695
3696 if (!vcs->users) {
3697 vino_release_input(vcs);
3698
3699 /* stop DMA and free buffers */
3700 vino_capture_stop(vcs);
3701 vino_queue_free(&vcs->fb_queue);
3702 }
3703
3704 up(&vcs->sem);
3705
3706 return 0;
3707}
3708
3709static void vino_vm_open(struct vm_area_struct *vma)
3710{
3711 struct vino_framebuffer *fb = vma->vm_private_data;
3712
3713 fb->map_count++;
3714 dprintk("vino_vm_open(): count = %d\n", fb->map_count);
3715}
3716
3717static void vino_vm_close(struct vm_area_struct *vma)
3718{
3719 struct vino_framebuffer *fb = vma->vm_private_data;
3720
3721 fb->map_count--;
3722 dprintk("vino_vm_close(): count = %d\n", fb->map_count);
3723}
3724
3725static struct vm_operations_struct vino_vm_ops = {
3726 .open = vino_vm_open,
3727 .close = vino_vm_close,
3728};
3729
3730static int vino_mmap(struct file *file, struct vm_area_struct *vma)
3731{
3732 struct video_device *dev = video_devdata(file);
3733 struct vino_channel_settings *vcs = video_get_drvdata(dev);
3734
3735 unsigned long start = vma->vm_start;
3736 unsigned long size = vma->vm_end - vma->vm_start;
3737 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
3738
3739 struct vino_framebuffer *fb = NULL;
3740 unsigned int i, length;
3741 int ret = 0;
3742
3743 dprintk("mmap():\n");
3744
3745 // TODO: reject mmap if already mapped
3746
3747 if (down_interruptible(&vcs->sem))
3748 return -EINTR;
3749
3750 if (vcs->reading) {
3751 ret = -EBUSY;
3752 goto out;
3753 }
3754
3755 // TODO: check queue type
3756
3757 if (!(vma->vm_flags & VM_WRITE)) {
3758 dprintk("mmap(): app bug: PROT_WRITE please\n");
3759 ret = -EINVAL;
3760 goto out;
3761 }
3762 if (!(vma->vm_flags & VM_SHARED)) {
3763 dprintk("mmap(): app bug: MAP_SHARED please\n");
3764 ret = -EINVAL;
3765 goto out;
3766 }
3767
3768 /* find the correct buffer using offset */
3769 length = vino_queue_get_length(&vcs->fb_queue);
3770 if (length == 0) {
3771 dprintk("mmap(): queue not initialized\n");
3772 ret = -EINVAL;
3773 goto out;
3774 }
3775
3776 for (i = 0; i < length; i++) {
3777 fb = vino_queue_get_buffer(&vcs->fb_queue, i);
3778 if (fb == NULL) {
3779 dprintk("mmap(): vino_queue_get_buffer() failed\n");
3780 ret = -EINVAL;
3781 goto out;
3782 }
3783
3784 if (fb->offset == offset)
3785 goto found;
3786 }
3787
3788 dprintk("mmap(): invalid offset = %lu\n", offset);
3789 ret = -EINVAL;
3790 goto out;
3791
3792found:
3793 dprintk("mmap(): buffer = %d\n", i);
3794
3795 if (size > (fb->desc_table.page_count * PAGE_SIZE)) {
3796 dprintk("mmap(): failed: size = %lu > %lu\n",
3797 size, fb->desc_table.page_count * PAGE_SIZE);
3798 ret = -EINVAL;
3799 goto out;
3800 }
3801
3802 for (i = 0; i < fb->desc_table.page_count; i++) {
3803 unsigned long pfn =
3804 virt_to_phys((void *)fb->desc_table.virtual[i]) >>
3805 PAGE_SHIFT;
3806
3807 if (size < PAGE_SIZE)
3808 break;
3809
3810 // protection was: PAGE_READONLY
3811 if (remap_pfn_range(vma, start, pfn, PAGE_SIZE,
3812 vma->vm_page_prot)) {
3813 dprintk("mmap(): remap_pfn_range() failed\n");
3814 ret = -EAGAIN;
3815 goto out;
3816 }
3817
3818 start += PAGE_SIZE;
3819 size -= PAGE_SIZE;
3820 }
3821
3822 fb->map_count = 1;
3823
3824 vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED;
3825 vma->vm_flags &= ~VM_IO;
3826 vma->vm_private_data = fb;
3827 vma->vm_file = file;
3828 vma->vm_ops = &vino_vm_ops;
3829
3830out:
3831 up(&vcs->sem);
3832
3833 return ret;
3834}
3835
3836static unsigned int vino_poll(struct file *file, poll_table *pt)
3837{
3838 struct video_device *dev = video_devdata(file);
3839 struct vino_channel_settings *vcs = video_get_drvdata(dev);
3840 unsigned int outgoing;
3841 unsigned int ret = 0;
3842
3843 // lock mutex (?)
3844 // TODO: this has to be corrected for different read modes
3845
3846 dprintk("poll():\n");
3847
3848 if (vino_queue_get_outgoing(&vcs->fb_queue, &outgoing)) {
3849 dprintk("poll(): vino_queue_get_outgoing() failed\n");
3850 ret = POLLERR;
3851 goto error;
3852 }
3853 if (outgoing > 0)
3854 goto over;
3855
3856 poll_wait(file, &vcs->fb_queue.frame_wait_queue, pt);
3857
3858 if (vino_queue_get_outgoing(&vcs->fb_queue, &outgoing)) {
3859 dprintk("poll(): vino_queue_get_outgoing() failed\n");
3860 ret = POLLERR;
3861 goto error;
3862 }
3863
3864over:
3865 dprintk("poll(): data %savailable\n",
3866 (outgoing > 0) ? "" : "not ");
3867 if (outgoing > 0) {
3868 ret = POLLIN | POLLRDNORM;
3869 }
3870
3871error:
3872
3873 return ret;
3874}
3875
3876static int vino_do_ioctl(struct inode *inode, struct file *file,
3877 unsigned int cmd, void *arg)
3878{
3879 struct video_device *dev = video_devdata(file);
3880 struct vino_channel_settings *vcs = video_get_drvdata(dev);
3881
3882 switch (_IOC_TYPE(cmd)) {
3883 case 'v':
3884 dprintk("ioctl(): V4L1 unsupported (0x%08x)\n", cmd);
3885 break;
3886 case 'V':
3887 dprintk("ioctl(): V4L2 %s (0x%08x)\n",
3888 v4l2_ioctl_names[_IOC_NR(cmd)], cmd);
3889 break;
3890 default:
3891 dprintk("ioctl(): unsupported command 0x%08x\n", cmd);
3892 }
3893
3894 switch (cmd) {
3895 /* TODO: V4L1 interface (use compatibility layer?) */
3896 /* V4L2 interface */
3897 case VIDIOC_QUERYCAP: {
3898 vino_v4l2_querycap(arg);
3899 break;
3900 }
3901 case VIDIOC_ENUMINPUT: {
3902 return vino_v4l2_enuminput(vcs, arg);
3903 }
3904 case VIDIOC_G_INPUT: {
3905 return vino_v4l2_g_input(vcs, arg);
3906 }
3907 case VIDIOC_S_INPUT: {
3908 return vino_v4l2_s_input(vcs, arg);
3909 }
3910 case VIDIOC_ENUMSTD: {
3911 return vino_v4l2_enumstd(vcs, arg);
3912 }
3913 case VIDIOC_G_STD: {
3914 return vino_v4l2_g_std(vcs, arg);
3915 }
3916 case VIDIOC_S_STD: {
3917 return vino_v4l2_s_std(vcs, arg);
3918 }
3919 case VIDIOC_ENUM_FMT: {
3920 return vino_v4l2_enum_fmt(vcs, arg);
3921 }
3922 case VIDIOC_TRY_FMT: {
3923 return vino_v4l2_try_fmt(vcs, arg);
3924 }
3925 case VIDIOC_G_FMT: {
3926 return vino_v4l2_g_fmt(vcs, arg);
3927 }
3928 case VIDIOC_S_FMT: {
3929 return vino_v4l2_s_fmt(vcs, arg);
3930 }
3931 case VIDIOC_CROPCAP: {
3932 return vino_v4l2_cropcap(vcs, arg);
3933 }
3934 case VIDIOC_G_CROP: {
3935 return vino_v4l2_g_crop(vcs, arg);
3936 }
3937 case VIDIOC_S_CROP: {
3938 return vino_v4l2_s_crop(vcs, arg);
3939 }
3940 case VIDIOC_G_PARM: {
3941 return vino_v4l2_g_parm(vcs, arg);
3942 }
3943 case VIDIOC_S_PARM: {
3944 return vino_v4l2_s_parm(vcs, arg);
3945 }
3946 case VIDIOC_REQBUFS: {
3947 return vino_v4l2_reqbufs(vcs, arg);
3948 }
3949 case VIDIOC_QUERYBUF: {
3950 return vino_v4l2_querybuf(vcs, arg);
3951 }
3952 case VIDIOC_QBUF: {
3953 return vino_v4l2_qbuf(vcs, arg);
3954 }
3955 case VIDIOC_DQBUF: {
3956 return vino_v4l2_dqbuf(vcs, arg, file->f_flags & O_NONBLOCK);
3957 }
3958 case VIDIOC_STREAMON: {
3959 return vino_v4l2_streamon(vcs);
3960 }
3961 case VIDIOC_STREAMOFF: {
3962 return vino_v4l2_streamoff(vcs);
3963 }
3964 case VIDIOC_QUERYCTRL: {
3965 return vino_v4l2_queryctrl(vcs, arg);
3966 }
3967 case VIDIOC_G_CTRL: {
3968 return vino_v4l2_g_ctrl(vcs, arg);
3969 }
3970 case VIDIOC_S_CTRL: {
3971 return vino_v4l2_s_ctrl(vcs, arg);
3972 }
3973 default:
3974 return -ENOIOCTLCMD;
3975 }
3976
3977 return 0;
3978}
3979
3980static int vino_ioctl(struct inode *inode, struct file *file,
3981 unsigned int cmd, unsigned long arg)
3982{
3983 struct video_device *dev = video_devdata(file);
3984 struct vino_channel_settings *vcs = video_get_drvdata(dev);
3985 int ret;
3986
3987 if (down_interruptible(&vcs->sem))
3988 return -EINTR;
3989
3990 ret = video_usercopy(inode, file, cmd, arg, vino_do_ioctl);
3991
3992 up(&vcs->sem);
3993
3994 return ret;
3995}
3996
3997/* Initialization and cleanup */
3998
3999// __initdata
4000static int vino_init_stage = 0;
4001
4002static struct file_operations vino_fops = {
212 .owner = THIS_MODULE, 4003 .owner = THIS_MODULE,
213 .type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE,
214 .hardware = VID_HARDWARE_VINO,
215 .name = "VINO",
216 .open = vino_open, 4004 .open = vino_open,
217 .close = vino_close, 4005 .release = vino_close,
218 .ioctl = vino_ioctl, 4006 .ioctl = vino_ioctl,
219 .mmap = vino_mmap, 4007 .mmap = vino_mmap,
4008 .poll = vino_poll,
4009 .llseek = no_llseek,
220}; 4010};
221 4011
222static int __init vino_init(void) 4012static struct video_device v4l_device_template = {
4013 .name = "NOT SET",
4014 //.type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE |
4015 // VID_TYPE_CLIPPING | VID_TYPE_SCALES, VID_TYPE_OVERLAY
4016 .hardware = VID_HARDWARE_VINO,
4017 .fops = &vino_fops,
4018 .minor = -1,
4019};
4020
4021static void vino_module_cleanup(int stage)
4022{
4023 switch(stage) {
4024 case 10:
4025 video_unregister_device(vino_drvdata->b.v4l_device);
4026 vino_drvdata->b.v4l_device = NULL;
4027 case 9:
4028 video_unregister_device(vino_drvdata->a.v4l_device);
4029 vino_drvdata->a.v4l_device = NULL;
4030 case 8:
4031 vino_i2c_del_bus();
4032 case 7:
4033 free_irq(SGI_VINO_IRQ, NULL);
4034 case 6:
4035 if (vino_drvdata->b.v4l_device) {
4036 video_device_release(vino_drvdata->b.v4l_device);
4037 vino_drvdata->b.v4l_device = NULL;
4038 }
4039 case 5:
4040 if (vino_drvdata->a.v4l_device) {
4041 video_device_release(vino_drvdata->a.v4l_device);
4042 vino_drvdata->a.v4l_device = NULL;
4043 }
4044 case 4:
4045 /* all entries in dma_cpu dummy table have the same address */
4046 dma_unmap_single(NULL,
4047 vino_drvdata->dummy_desc_table.dma_cpu[0],
4048 PAGE_SIZE, DMA_FROM_DEVICE);
4049 dma_free_coherent(NULL, VINO_DUMMY_DESC_COUNT
4050 * sizeof(dma_addr_t),
4051 (void *)vino_drvdata->
4052 dummy_desc_table.dma_cpu,
4053 vino_drvdata->dummy_desc_table.dma);
4054 case 3:
4055 free_page(vino_drvdata->dummy_page);
4056 case 2:
4057 kfree(vino_drvdata);
4058 case 1:
4059 iounmap(vino);
4060 case 0:
4061 break;
4062 default:
4063 dprintk("vino_module_cleanup(): invalid cleanup stage = %d\n",
4064 stage);
4065 }
4066}
4067
4068static int vino_probe(void)
223{ 4069{
224 unsigned long rev; 4070 unsigned long rev_id;
225 int i, ret = 0;
226 4071
227 /* VINO is Indy specific beast */ 4072 if (ip22_is_fullhouse()) {
228 if (ip22_is_fullhouse()) 4073 printk(KERN_ERR "VINO doesn't exist in IP22 Fullhouse\n");
229 return -ENODEV; 4074 return -ENODEV;
4075 }
230 4076
231 /*
232 * VINO is in the EISA address space, so the sysid register will tell
233 * us if the EISA_PRESENT pin on MC has been pulled low.
234 *
235 * If EISA_PRESENT is not set we definitely don't have a VINO equiped
236 * system.
237 */
238 if (!(sgimc->systemid & SGIMC_SYSID_EPRESENT)) { 4077 if (!(sgimc->systemid & SGIMC_SYSID_EPRESENT)) {
239 printk(KERN_ERR "VINO not found\n"); 4078 printk(KERN_ERR "VINO is not found (EISA BUS not present)\n");
240 return -ENODEV; 4079 return -ENODEV;
241 } 4080 }
242 4081
243 vino = (struct sgi_vino *)ioremap(VINO_BASE, sizeof(struct sgi_vino)); 4082 vino = (struct sgi_vino *)ioremap(VINO_BASE, sizeof(struct sgi_vino));
244 if (!vino) 4083 if (!vino) {
4084 printk(KERN_ERR "VINO: ioremap() failed\n");
245 return -EIO; 4085 return -EIO;
4086 }
4087 vino_init_stage++;
246 4088
247 /* Okay, once we know that VINO is present we'll read its revision 4089 if (get_dbe(rev_id, &(vino->rev_id))) {
248 * safe way. One never knows... */ 4090 printk(KERN_ERR "Failed to read VINO revision register\n");
249 if (get_dbe(rev, &(vino->rev_id))) { 4091 vino_module_cleanup(vino_init_stage);
250 printk(KERN_ERR "VINO: failed to read revision register\n"); 4092 return -ENODEV;
251 ret = -ENODEV;
252 goto out_unmap;
253 } 4093 }
254 if (VINO_ID_VALUE(rev) != VINO_CHIP_ID) { 4094
255 printk(KERN_ERR "VINO is not VINO (Rev/ID: 0x%04lx)\n", rev); 4095 if (VINO_ID_VALUE(rev_id) != VINO_CHIP_ID) {
256 ret = -ENODEV; 4096 printk(KERN_ERR "Unknown VINO chip ID (Rev/ID: 0x%02lx)\n",
257 goto out_unmap; 4097 rev_id);
4098 vino_module_cleanup(vino_init_stage);
4099 return -ENODEV;
258 } 4100 }
259 printk(KERN_INFO "VINO Rev: 0x%02lx\n", VINO_REV_NUM(rev));
260 4101
261 Vino = (struct vino_video *) 4102 printk(KERN_INFO "VINO with chip ID %ld, revision %ld found\n",
262 kmalloc(sizeof(struct vino_video), GFP_KERNEL); 4103 VINO_ID_VALUE(rev_id), VINO_REV_NUM(rev_id));
263 if (!Vino) { 4104
264 ret = -ENOMEM; 4105 return 0;
265 goto out_unmap; 4106}
4107
4108static int vino_init(void)
4109{
4110 dma_addr_t dma_dummy_address;
4111 int i;
4112
4113 vino_drvdata = (struct vino_settings *)
4114 kmalloc(sizeof(struct vino_settings), GFP_KERNEL);
4115 if (!vino_drvdata) {
4116 vino_module_cleanup(vino_init_stage);
4117 return -ENOMEM;
266 } 4118 }
4119 memset(vino_drvdata, 0, sizeof(struct vino_settings));
4120 vino_init_stage++;
267 4121
268 Vino->dummy_page = get_zeroed_page(GFP_KERNEL | GFP_DMA); 4122 /* create a dummy dma descriptor */
269 if (!Vino->dummy_page) { 4123 vino_drvdata->dummy_page = get_zeroed_page(GFP_KERNEL | GFP_DMA);
270 ret = -ENOMEM; 4124 if (!vino_drvdata->dummy_page) {
271 goto out_free_vino; 4125 vino_module_cleanup(vino_init_stage);
4126 return -ENOMEM;
272 } 4127 }
273 for (i = 0; i < 4; i++) 4128 vino_init_stage++;
274 Vino->dummy_buf[i] = PHYSADDR(Vino->dummy_page); 4129
4130 // TODO: use page_count in dummy_desc_table
4131
4132 vino_drvdata->dummy_desc_table.dma_cpu =
4133 dma_alloc_coherent(NULL,
4134 VINO_DUMMY_DESC_COUNT * sizeof(dma_addr_t),
4135 &vino_drvdata->dummy_desc_table.dma,
4136 GFP_KERNEL | GFP_DMA);
4137 if (!vino_drvdata->dummy_desc_table.dma_cpu) {
4138 vino_module_cleanup(vino_init_stage);
4139 return -ENOMEM;
4140 }
4141 vino_init_stage++;
4142
4143 dma_dummy_address = dma_map_single(NULL,
4144 (void *)vino_drvdata->dummy_page,
4145 PAGE_SIZE, DMA_FROM_DEVICE);
4146 for (i = 0; i < VINO_DUMMY_DESC_COUNT; i++) {
4147 vino_drvdata->dummy_desc_table.dma_cpu[i] = dma_dummy_address;
4148 }
4149
4150 /* initialize VINO */
275 4151
276 vino->control = 0; 4152 vino->control = 0;
277 /* prevent VINO from throwing spurious interrupts */ 4153 vino->a.next_4_desc = vino_drvdata->dummy_desc_table.dma;
278 vino->a.next_4_desc = PHYSADDR(Vino->dummy_buf); 4154 vino->b.next_4_desc = vino_drvdata->dummy_desc_table.dma;
279 vino->b.next_4_desc = PHYSADDR(Vino->dummy_buf); 4155 udelay(VINO_DESC_FETCH_DELAY);
280 udelay(5); 4156
281 vino->intr_status = 0; 4157 vino->intr_status = 0;
282 /* set threshold level */
283 vino->a.fifo_thres = threshold_a;
284 vino->b.fifo_thres = threshold_b;
285 4158
286 init_MUTEX(&Vino->input_lock); 4159 vino->a.fifo_thres = VINO_FIFO_THRESHOLD_DEFAULT;
4160 vino->b.fifo_thres = VINO_FIFO_THRESHOLD_DEFAULT;
4161
4162 return 0;
4163}
4164
4165static int vino_init_channel_settings(struct vino_channel_settings *vcs,
4166 unsigned int channel, const char *name)
4167{
4168 vcs->channel = channel;
4169 vcs->input = VINO_INPUT_NONE;
4170 vcs->alpha = 0;
4171 vcs->users = 0;
4172 vcs->data_format = VINO_DATA_FMT_GREY;
4173 vcs->data_norm = VINO_DATA_NORM_NTSC;
4174 vcs->decimation = 1;
4175 vino_set_default_clipping(vcs);
4176 vino_set_default_framerate(vcs);
4177
4178 vcs->capturing = 0;
4179
4180 init_MUTEX(&vcs->sem);
4181 spin_lock_init(&vcs->capture_lock);
4182
4183 init_MUTEX(&vcs->fb_queue.queue_sem);
4184 spin_lock_init(&vcs->fb_queue.queue_lock);
4185 init_waitqueue_head(&vcs->fb_queue.frame_wait_queue);
4186
4187 vcs->v4l_device = video_device_alloc();
4188 if (!vcs->v4l_device) {
4189 vino_module_cleanup(vino_init_stage);
4190 return -ENOMEM;
4191 }
4192 vino_init_stage++;
4193
4194 memcpy(vcs->v4l_device, &v4l_device_template,
4195 sizeof(struct video_device));
4196 strcpy(vcs->v4l_device->name, name);
4197 vcs->v4l_device->release = video_device_release;
4198
4199 video_set_drvdata(vcs->v4l_device, vcs);
4200
4201 return 0;
4202}
4203
4204static int __init vino_module_init(void)
4205{
4206 int ret;
4207
4208 printk(KERN_INFO "SGI VINO driver version %s\n",
4209 VINO_MODULE_VERSION);
4210
4211 ret = vino_probe();
4212 if (ret)
4213 return ret;
4214
4215 ret = vino_init();
4216 if (ret)
4217 return ret;
4218
4219 /* initialize data structures */
287 4220
288 if (request_irq(SGI_VINO_IRQ, vino_interrupt, 0, vinostr, NULL)) { 4221 spin_lock_init(&vino_drvdata->vino_lock);
289 printk(KERN_ERR "VINO: irq%02d registration failed\n", 4222 spin_lock_init(&vino_drvdata->input_lock);
4223
4224 ret = vino_init_channel_settings(&vino_drvdata->a, VINO_CHANNEL_A,
4225 vino_v4l_device_name_a);
4226 if (ret)
4227 return ret;
4228
4229 ret = vino_init_channel_settings(&vino_drvdata->b, VINO_CHANNEL_B,
4230 vino_v4l_device_name_b);
4231 if (ret)
4232 return ret;
4233
4234 /* initialize hardware and register V4L devices */
4235
4236 ret = request_irq(SGI_VINO_IRQ, vino_interrupt, 0,
4237 vino_driver_description, NULL);
4238 if (ret) {
4239 printk(KERN_ERR "VINO: requesting IRQ %02d failed\n",
290 SGI_VINO_IRQ); 4240 SGI_VINO_IRQ);
291 ret = -EAGAIN; 4241 vino_module_cleanup(vino_init_stage);
292 goto out_free_page; 4242 return -EAGAIN;
293 } 4243 }
4244 vino_init_stage++;
294 4245
295 ret = vino_i2c_add_bus(); 4246 ret = vino_i2c_add_bus();
296 if (ret) { 4247 if (ret) {
297 printk(KERN_ERR "VINO: I2C bus registration failed\n"); 4248 printk(KERN_ERR "VINO I2C bus registration failed\n");
298 goto out_free_irq; 4249 vino_module_cleanup(vino_init_stage);
4250 return ret;
299 } 4251 }
4252 vino_init_stage++;
300 4253
301 if (video_register_device(&Vino->chA.vdev, VFL_TYPE_GRABBER, -1) < 0) { 4254 ret = video_register_device(vino_drvdata->a.v4l_device,
302 printk("%s, chnl %d: device registration failed.\n", 4255 VFL_TYPE_GRABBER, -1);
303 Vino->chA.vdev.name, Vino->chA.chan); 4256 if (ret < 0) {
304 ret = -EINVAL; 4257 printk(KERN_ERR "VINO channel A Video4Linux-device "
305 goto out_i2c_del_bus; 4258 "registration failed\n");
4259 vino_module_cleanup(vino_init_stage);
4260 return -EINVAL;
306 } 4261 }
307 if (video_register_device(&Vino->chB.vdev, VFL_TYPE_GRABBER, -1) < 0) { 4262 vino_init_stage++;
308 printk("%s, chnl %d: device registration failed.\n", 4263
309 Vino->chB.vdev.name, Vino->chB.chan); 4264 ret = video_register_device(vino_drvdata->b.v4l_device,
310 ret = -EINVAL; 4265 VFL_TYPE_GRABBER, -1);
311 goto out_unregister_vdev; 4266 if (ret < 0) {
4267 printk(KERN_ERR "VINO channel B Video4Linux-device "
4268 "registration failed\n");
4269 vino_module_cleanup(vino_init_stage);
4270 return -EINVAL;
312 } 4271 }
4272 vino_init_stage++;
313 4273
314 return 0; 4274#if defined(CONFIG_KMOD) && defined(MODULE)
4275 request_module("saa7191");
4276 request_module("indycam");
4277#endif
315 4278
316out_unregister_vdev: 4279 dprintk("init complete!\n");
317 video_unregister_device(&Vino->chA.vdev);
318out_i2c_del_bus:
319 vino_i2c_del_bus();
320out_free_irq:
321 free_irq(SGI_VINO_IRQ, NULL);
322out_free_page:
323 free_page(Vino->dummy_page);
324out_free_vino:
325 kfree(Vino);
326out_unmap:
327 iounmap(vino);
328 4280
329 return ret; 4281 return 0;
330} 4282}
331 4283
332static void __exit vino_exit(void) 4284static void __exit vino_module_exit(void)
333{ 4285{
334 video_unregister_device(&Vino->chA.vdev); 4286 dprintk("exiting, stage = %d ...\n", vino_init_stage);
335 video_unregister_device(&Vino->chB.vdev); 4287 vino_module_cleanup(vino_init_stage);
336 vino_i2c_del_bus(); 4288 dprintk("cleanup complete, exit!\n");
337 free_irq(SGI_VINO_IRQ, NULL);
338 free_page(Vino->dummy_page);
339 kfree(Vino);
340 iounmap(vino);
341} 4289}
342 4290
343module_init(vino_init); 4291module_init(vino_module_init);
344module_exit(vino_exit); 4292module_exit(vino_module_exit);
345
346MODULE_DESCRIPTION("Video4Linux driver for SGI Indy VINO (IndyCam)");
347MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/vino.h b/drivers/media/video/vino.h
index d2fce472f35a..de2d615ae7c9 100644
--- a/drivers/media/video/vino.h
+++ b/drivers/media/video/vino.h
@@ -1,13 +1,19 @@
1/* 1/*
2 * Driver for the VINO (Video In No Out) system found in SGI Indys.
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License version 2 as published by the Free Software Foundation.
6 *
2 * Copyright (C) 1999 Ulf Karlsson <ulfc@bun.falkenberg.se> 7 * Copyright (C) 1999 Ulf Karlsson <ulfc@bun.falkenberg.se>
3 * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org> 8 * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
4 */ 9 */
5 10
6#ifndef VINO_H 11#ifndef _VINO_H_
7#define VINO_H 12#define _VINO_H_
8 13
9#define VINO_BASE 0x00080000 /* Vino is in the EISA address space, 14#define VINO_BASE 0x00080000 /* Vino is in the EISA address space,
10 * but it is not an EISA bus card */ 15 * but it is not an EISA bus card */
16#define VINO_PAGE_SIZE 4096
11 17
12struct sgi_vino_channel { 18struct sgi_vino_channel {
13 u32 _pad_alpha; 19 u32 _pad_alpha;
@@ -21,8 +27,9 @@ struct sgi_vino_channel {
21 u32 _pad_clip_end; 27 u32 _pad_clip_end;
22 volatile u32 clip_end; 28 volatile u32 clip_end;
23 29
30#define VINO_FRAMERT_FULL 0xfff
24#define VINO_FRAMERT_PAL (1<<0) /* 0=NTSC 1=PAL */ 31#define VINO_FRAMERT_PAL (1<<0) /* 0=NTSC 1=PAL */
25#define VINO_FRAMERT_RT(x) (((x) & 0x1fff) << 1) /* bits 1:12 */ 32#define VINO_FRAMERT_RT(x) (((x) & 0xfff) << 1) /* bits 1:12 */
26 u32 _pad_frame_rate; 33 u32 _pad_frame_rate;
27 volatile u32 frame_rate; 34 volatile u32 frame_rate;
28 35
@@ -67,18 +74,18 @@ struct sgi_vino {
67 volatile u32 rev_id; 74 volatile u32 rev_id;
68 75
69#define VINO_CTRL_LITTLE_ENDIAN (1<<0) 76#define VINO_CTRL_LITTLE_ENDIAN (1<<0)
70#define VINO_CTRL_A_FIELD_TRANS_INT (1<<1) /* Field transferred int */ 77#define VINO_CTRL_A_EOF_INT (1<<1) /* Field transferred int */
71#define VINO_CTRL_A_FIFO_OF_INT (1<<2) /* FIFO overflow int */ 78#define VINO_CTRL_A_FIFO_INT (1<<2) /* FIFO overflow int */
72#define VINO_CTRL_A_END_DESC_TBL_INT (1<<3) /* End of desc table int */ 79#define VINO_CTRL_A_EOD_INT (1<<3) /* End of desc table int */
73#define VINO_CTRL_A_INT (VINO_CTRL_A_FIELD_TRANS_INT | \ 80#define VINO_CTRL_A_INT (VINO_CTRL_A_EOF_INT | \
74 VINO_CTRL_A_FIFO_OF_INT | \ 81 VINO_CTRL_A_FIFO_INT | \
75 VINO_CTRL_A_END_DESC_TBL_INT) 82 VINO_CTRL_A_EOD_INT)
76#define VINO_CTRL_B_FIELD_TRANS_INT (1<<4) /* Field transferred int */ 83#define VINO_CTRL_B_EOF_INT (1<<4) /* Field transferred int */
77#define VINO_CTRL_B_FIFO_OF_INT (1<<5) /* FIFO overflow int */ 84#define VINO_CTRL_B_FIFO_INT (1<<5) /* FIFO overflow int */
78#define VINO_CTRL_B_END_DESC_TBL_INT (1<<6) /* End of desc table int */ 85#define VINO_CTRL_B_EOD_INT (1<<6) /* End of desc table int */
79#define VINO_CTRL_B_INT (VINO_CTRL_B_FIELD_TRANS_INT | \ 86#define VINO_CTRL_B_INT (VINO_CTRL_B_EOF_INT | \
80 VINO_CTRL_B_FIFO_OF_INT | \ 87 VINO_CTRL_B_FIFO_INT | \
81 VINO_CTRL_B_END_DESC_TBL_INT) 88 VINO_CTRL_B_EOD_INT)
82#define VINO_CTRL_A_DMA_ENBL (1<<7) 89#define VINO_CTRL_A_DMA_ENBL (1<<7)
83#define VINO_CTRL_A_INTERLEAVE_ENBL (1<<8) 90#define VINO_CTRL_A_INTERLEAVE_ENBL (1<<8)
84#define VINO_CTRL_A_SYNC_ENBL (1<<9) 91#define VINO_CTRL_A_SYNC_ENBL (1<<9)
@@ -104,18 +111,18 @@ struct sgi_vino {
104 u32 _pad_control; 111 u32 _pad_control;
105 volatile u32 control; 112 volatile u32 control;
106 113
107#define VINO_INTSTAT_A_FIELD_TRANS (1<<0) /* Field transferred int */ 114#define VINO_INTSTAT_A_EOF (1<<0) /* Field transferred int */
108#define VINO_INTSTAT_A_FIFO_OF (1<<1) /* FIFO overflow int */ 115#define VINO_INTSTAT_A_FIFO (1<<1) /* FIFO overflow int */
109#define VINO_INTSTAT_A_END_DESC_TBL (1<<2) /* End of desc table int */ 116#define VINO_INTSTAT_A_EOD (1<<2) /* End of desc table int */
110#define VINO_INTSTAT_A (VINO_INTSTAT_A_FIELD_TRANS | \ 117#define VINO_INTSTAT_A (VINO_INTSTAT_A_EOF | \
111 VINO_INTSTAT_A_FIFO_OF | \ 118 VINO_INTSTAT_A_FIFO | \
112 VINO_INTSTAT_A_END_DESC_TBL) 119 VINO_INTSTAT_A_EOD)
113#define VINO_INTSTAT_B_FIELD_TRANS (1<<3) /* Field transferred int */ 120#define VINO_INTSTAT_B_EOF (1<<3) /* Field transferred int */
114#define VINO_INTSTAT_B_FIFO_OF (1<<4) /* FIFO overflow int */ 121#define VINO_INTSTAT_B_FIFO (1<<4) /* FIFO overflow int */
115#define VINO_INTSTAT_B_END_DESC_TBL (1<<5) /* End of desc table int */ 122#define VINO_INTSTAT_B_EOD (1<<5) /* End of desc table int */
116#define VINO_INTSTAT_B (VINO_INTSTAT_B_FIELD_TRANS | \ 123#define VINO_INTSTAT_B (VINO_INTSTAT_B_EOF | \
117 VINO_INTSTAT_B_FIFO_OF | \ 124 VINO_INTSTAT_B_FIFO | \
118 VINO_INTSTAT_B_END_DESC_TBL) 125 VINO_INTSTAT_B_EOD)
119 u32 _pad_intr_status; 126 u32 _pad_intr_status;
120 volatile u32 intr_status; 127 volatile u32 intr_status;
121 128