aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2009-02-27 07:05:10 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 11:43:10 -0400
commitcf4e9484f402c799fa25c9ffb7e9a3b620a3702d (patch)
tree5f7839009c8a66f4c1b5eaaf2c3c7365b515564d /drivers/media/video
parentbabb7dc7776dd6ded4e1e6cb7acc34c25c0eb521 (diff)
V4L/DVB (10861): vino/indycam/saa7191: convert to i2c modules to V4L2.
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video')
-rw-r--r--drivers/media/video/indycam.c234
-rw-r--r--drivers/media/video/indycam.h19
-rw-r--r--drivers/media/video/saa7191.c228
-rw-r--r--drivers/media/video/saa7191.h26
-rw-r--r--drivers/media/video/vino.c396
5 files changed, 256 insertions, 647 deletions
diff --git a/drivers/media/video/indycam.c b/drivers/media/video/indycam.c
index 84b9e4f2b3b3..54099e303c8d 100644
--- a/drivers/media/video/indycam.c
+++ b/drivers/media/video/indycam.c
@@ -19,10 +19,11 @@
19#include <linux/mm.h> 19#include <linux/mm.h>
20#include <linux/slab.h> 20#include <linux/slab.h>
21 21
22#include <linux/videodev.h>
23/* IndyCam decodes stream of photons into digital image representation ;-) */ 22/* IndyCam decodes stream of photons into digital image representation ;-) */
24#include <linux/video_decoder.h> 23#include <linux/videodev2.h>
25#include <linux/i2c.h> 24#include <linux/i2c.h>
25#include <media/v4l2-common.h>
26#include <media/v4l2-i2c-drv-legacy.h>
26 27
27#include "indycam.h" 28#include "indycam.h"
28 29
@@ -33,6 +34,10 @@ MODULE_VERSION(INDYCAM_MODULE_VERSION);
33MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>"); 34MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
34MODULE_LICENSE("GPL"); 35MODULE_LICENSE("GPL");
35 36
37static unsigned short normal_i2c[] = { 0x56 >> 1, I2C_CLIENT_END };
38
39I2C_CLIENT_INSMOD;
40
36// #define INDYCAM_DEBUG 41// #define INDYCAM_DEBUG
37 42
38#ifdef INDYCAM_DEBUG 43#ifdef INDYCAM_DEBUG
@@ -48,8 +53,6 @@ struct indycam {
48 u8 version; 53 u8 version;
49}; 54};
50 55
51static struct i2c_driver i2c_driver_indycam;
52
53static const u8 initseq[] = { 56static const u8 initseq[] = {
54 INDYCAM_CONTROL_AGCENA, /* INDYCAM_CONTROL */ 57 INDYCAM_CONTROL_AGCENA, /* INDYCAM_CONTROL */
55 INDYCAM_SHUTTER_60, /* INDYCAM_SHUTTER */ 58 INDYCAM_SHUTTER_60, /* INDYCAM_SHUTTER */
@@ -138,44 +141,44 @@ static void indycam_regdump_debug(struct i2c_client *client)
138#endif 141#endif
139 142
140static int indycam_get_control(struct i2c_client *client, 143static int indycam_get_control(struct i2c_client *client,
141 struct indycam_control *ctrl) 144 struct v4l2_control *ctrl)
142{ 145{
143 struct indycam *camera = i2c_get_clientdata(client); 146 struct indycam *camera = i2c_get_clientdata(client);
144 u8 reg; 147 u8 reg;
145 int ret = 0; 148 int ret = 0;
146 149
147 switch (ctrl->type) { 150 switch (ctrl->id) {
148 case INDYCAM_CONTROL_AGC: 151 case V4L2_CID_AUTOGAIN:
149 case INDYCAM_CONTROL_AWB: 152 case V4L2_CID_AUTO_WHITE_BALANCE:
150 ret = indycam_read_reg(client, INDYCAM_REG_CONTROL, &reg); 153 ret = indycam_read_reg(client, INDYCAM_REG_CONTROL, &reg);
151 if (ret) 154 if (ret)
152 return -EIO; 155 return -EIO;
153 if (ctrl->type == INDYCAM_CONTROL_AGC) 156 if (ctrl->id == V4L2_CID_AUTOGAIN)
154 ctrl->value = (reg & INDYCAM_CONTROL_AGCENA) 157 ctrl->value = (reg & INDYCAM_CONTROL_AGCENA)
155 ? 1 : 0; 158 ? 1 : 0;
156 else 159 else
157 ctrl->value = (reg & INDYCAM_CONTROL_AWBCTL) 160 ctrl->value = (reg & INDYCAM_CONTROL_AWBCTL)
158 ? 1 : 0; 161 ? 1 : 0;
159 break; 162 break;
160 case INDYCAM_CONTROL_SHUTTER: 163 case V4L2_CID_EXPOSURE:
161 ret = indycam_read_reg(client, INDYCAM_REG_SHUTTER, &reg); 164 ret = indycam_read_reg(client, INDYCAM_REG_SHUTTER, &reg);
162 if (ret) 165 if (ret)
163 return -EIO; 166 return -EIO;
164 ctrl->value = ((s32)reg == 0x00) ? 0xff : ((s32)reg - 1); 167 ctrl->value = ((s32)reg == 0x00) ? 0xff : ((s32)reg - 1);
165 break; 168 break;
166 case INDYCAM_CONTROL_GAIN: 169 case V4L2_CID_GAIN:
167 ret = indycam_read_reg(client, INDYCAM_REG_GAIN, &reg); 170 ret = indycam_read_reg(client, INDYCAM_REG_GAIN, &reg);
168 if (ret) 171 if (ret)
169 return -EIO; 172 return -EIO;
170 ctrl->value = (s32)reg; 173 ctrl->value = (s32)reg;
171 break; 174 break;
172 case INDYCAM_CONTROL_RED_BALANCE: 175 case V4L2_CID_RED_BALANCE:
173 ret = indycam_read_reg(client, INDYCAM_REG_RED_BALANCE, &reg); 176 ret = indycam_read_reg(client, INDYCAM_REG_RED_BALANCE, &reg);
174 if (ret) 177 if (ret)
175 return -EIO; 178 return -EIO;
176 ctrl->value = (s32)reg; 179 ctrl->value = (s32)reg;
177 break; 180 break;
178 case INDYCAM_CONTROL_BLUE_BALANCE: 181 case V4L2_CID_BLUE_BALANCE:
179 ret = indycam_read_reg(client, INDYCAM_REG_BLUE_BALANCE, &reg); 182 ret = indycam_read_reg(client, INDYCAM_REG_BLUE_BALANCE, &reg);
180 if (ret) 183 if (ret)
181 return -EIO; 184 return -EIO;
@@ -195,7 +198,7 @@ static int indycam_get_control(struct i2c_client *client,
195 return -EIO; 198 return -EIO;
196 ctrl->value = (s32)reg; 199 ctrl->value = (s32)reg;
197 break; 200 break;
198 case INDYCAM_CONTROL_GAMMA: 201 case V4L2_CID_GAMMA:
199 if (camera->version == CAMERA_VERSION_MOOSE) { 202 if (camera->version == CAMERA_VERSION_MOOSE) {
200 ret = indycam_read_reg(client, 203 ret = indycam_read_reg(client,
201 INDYCAM_REG_GAMMA, &reg); 204 INDYCAM_REG_GAMMA, &reg);
@@ -214,20 +217,20 @@ static int indycam_get_control(struct i2c_client *client,
214} 217}
215 218
216static int indycam_set_control(struct i2c_client *client, 219static int indycam_set_control(struct i2c_client *client,
217 struct indycam_control *ctrl) 220 struct v4l2_control *ctrl)
218{ 221{
219 struct indycam *camera = i2c_get_clientdata(client); 222 struct indycam *camera = i2c_get_clientdata(client);
220 u8 reg; 223 u8 reg;
221 int ret = 0; 224 int ret = 0;
222 225
223 switch (ctrl->type) { 226 switch (ctrl->id) {
224 case INDYCAM_CONTROL_AGC: 227 case V4L2_CID_AUTOGAIN:
225 case INDYCAM_CONTROL_AWB: 228 case V4L2_CID_AUTO_WHITE_BALANCE:
226 ret = indycam_read_reg(client, INDYCAM_REG_CONTROL, &reg); 229 ret = indycam_read_reg(client, INDYCAM_REG_CONTROL, &reg);
227 if (ret) 230 if (ret)
228 break; 231 break;
229 232
230 if (ctrl->type == INDYCAM_CONTROL_AGC) { 233 if (ctrl->id == V4L2_CID_AUTOGAIN) {
231 if (ctrl->value) 234 if (ctrl->value)
232 reg |= INDYCAM_CONTROL_AGCENA; 235 reg |= INDYCAM_CONTROL_AGCENA;
233 else 236 else
@@ -241,18 +244,18 @@ static int indycam_set_control(struct i2c_client *client,
241 244
242 ret = indycam_write_reg(client, INDYCAM_REG_CONTROL, reg); 245 ret = indycam_write_reg(client, INDYCAM_REG_CONTROL, reg);
243 break; 246 break;
244 case INDYCAM_CONTROL_SHUTTER: 247 case V4L2_CID_EXPOSURE:
245 reg = (ctrl->value == 0xff) ? 0x00 : (ctrl->value + 1); 248 reg = (ctrl->value == 0xff) ? 0x00 : (ctrl->value + 1);
246 ret = indycam_write_reg(client, INDYCAM_REG_SHUTTER, reg); 249 ret = indycam_write_reg(client, INDYCAM_REG_SHUTTER, reg);
247 break; 250 break;
248 case INDYCAM_CONTROL_GAIN: 251 case V4L2_CID_GAIN:
249 ret = indycam_write_reg(client, INDYCAM_REG_GAIN, ctrl->value); 252 ret = indycam_write_reg(client, INDYCAM_REG_GAIN, ctrl->value);
250 break; 253 break;
251 case INDYCAM_CONTROL_RED_BALANCE: 254 case V4L2_CID_RED_BALANCE:
252 ret = indycam_write_reg(client, INDYCAM_REG_RED_BALANCE, 255 ret = indycam_write_reg(client, INDYCAM_REG_RED_BALANCE,
253 ctrl->value); 256 ctrl->value);
254 break; 257 break;
255 case INDYCAM_CONTROL_BLUE_BALANCE: 258 case V4L2_CID_BLUE_BALANCE:
256 ret = indycam_write_reg(client, INDYCAM_REG_BLUE_BALANCE, 259 ret = indycam_write_reg(client, INDYCAM_REG_BLUE_BALANCE,
257 ctrl->value); 260 ctrl->value);
258 break; 261 break;
@@ -264,7 +267,7 @@ static int indycam_set_control(struct i2c_client *client,
264 ret = indycam_write_reg(client, INDYCAM_REG_BLUE_SATURATION, 267 ret = indycam_write_reg(client, INDYCAM_REG_BLUE_SATURATION,
265 ctrl->value); 268 ctrl->value);
266 break; 269 break;
267 case INDYCAM_CONTROL_GAMMA: 270 case V4L2_CID_GAMMA:
268 if (camera->version == CAMERA_VERSION_MOOSE) { 271 if (camera->version == CAMERA_VERSION_MOOSE) {
269 ret = indycam_write_reg(client, INDYCAM_REG_GAMMA, 272 ret = indycam_write_reg(client, INDYCAM_REG_GAMMA,
270 ctrl->value); 273 ctrl->value);
@@ -279,44 +282,50 @@ static int indycam_set_control(struct i2c_client *client,
279 282
280/* I2C-interface */ 283/* I2C-interface */
281 284
282static int indycam_attach(struct i2c_adapter *adap, int addr, int kind) 285static int indycam_command(struct i2c_client *client, unsigned int cmd,
286 void *arg)
287{
288 /* The old video_decoder interface just isn't enough,
289 * so we'll use some custom commands. */
290 switch (cmd) {
291 case VIDIOC_G_CTRL:
292 return indycam_get_control(client, arg);
293
294 case VIDIOC_S_CTRL:
295 return indycam_set_control(client, arg);
296
297 default:
298 return -EINVAL;
299 }
300
301 return 0;
302}
303
304static int indycam_probe(struct i2c_client *client,
305 const struct i2c_device_id *id)
283{ 306{
284 int err = 0; 307 int err = 0;
285 struct indycam *camera; 308 struct indycam *camera;
286 struct i2c_client *client;
287 309
288 printk(KERN_INFO "SGI IndyCam driver version %s\n", 310 v4l_info(client, "chip found @ 0x%x (%s)\n",
289 INDYCAM_MODULE_VERSION); 311 client->addr << 1, client->adapter->name);
290 312
291 client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
292 if (!client)
293 return -ENOMEM;
294 camera = kzalloc(sizeof(struct indycam), GFP_KERNEL); 313 camera = kzalloc(sizeof(struct indycam), GFP_KERNEL);
295 if (!camera) { 314 if (!camera)
296 err = -ENOMEM; 315 return -ENOMEM;
297 goto out_free_client;
298 }
299 316
300 client->addr = addr;
301 client->adapter = adap;
302 client->driver = &i2c_driver_indycam;
303 client->flags = 0;
304 strcpy(client->name, "IndyCam client");
305 i2c_set_clientdata(client, camera); 317 i2c_set_clientdata(client, camera);
306 318
307 camera->client = client; 319 camera->client = client;
308 320
309 err = i2c_attach_client(client);
310 if (err)
311 goto out_free_camera;
312
313 camera->version = i2c_smbus_read_byte_data(client, 321 camera->version = i2c_smbus_read_byte_data(client,
314 INDYCAM_REG_VERSION); 322 INDYCAM_REG_VERSION);
315 if (camera->version != CAMERA_VERSION_INDY && 323 if (camera->version != CAMERA_VERSION_INDY &&
316 camera->version != CAMERA_VERSION_MOOSE) { 324 camera->version != CAMERA_VERSION_MOOSE) {
317 err = -ENODEV; 325 kfree(camera);
318 goto out_detach_client; 326 return -ENODEV;
319 } 327 }
328
320 printk(KERN_INFO "IndyCam v%d.%d detected\n", 329 printk(KERN_INFO "IndyCam v%d.%d detected\n",
321 INDYCAM_VERSION_MAJOR(camera->version), 330 INDYCAM_VERSION_MAJOR(camera->version),
322 INDYCAM_VERSION_MINOR(camera->version)); 331 INDYCAM_VERSION_MINOR(camera->version));
@@ -327,8 +336,8 @@ static int indycam_attach(struct i2c_adapter *adap, int addr, int kind)
327 err = indycam_write_block(client, 0, sizeof(initseq), (u8 *)&initseq); 336 err = indycam_write_block(client, 0, sizeof(initseq), (u8 *)&initseq);
328 if (err) { 337 if (err) {
329 printk(KERN_ERR "IndyCam initialization failed\n"); 338 printk(KERN_ERR "IndyCam initialization failed\n");
330 err = -EIO; 339 kfree(camera);
331 goto out_detach_client; 340 return -EIO;
332 } 341 }
333 342
334 indycam_regdump(client); 343 indycam_regdump(client);
@@ -338,8 +347,8 @@ static int indycam_attach(struct i2c_adapter *adap, int addr, int kind)
338 INDYCAM_CONTROL_AGCENA | INDYCAM_CONTROL_AWBCTL); 347 INDYCAM_CONTROL_AGCENA | INDYCAM_CONTROL_AWBCTL);
339 if (err) { 348 if (err) {
340 printk(KERN_ERR "IndyCam: White balancing camera failed\n"); 349 printk(KERN_ERR "IndyCam: White balancing camera failed\n");
341 err = -EIO; 350 kfree(camera);
342 goto out_detach_client; 351 return -EIO;
343 } 352 }
344 353
345 indycam_regdump(client); 354 indycam_regdump(client);
@@ -347,124 +356,33 @@ static int indycam_attach(struct i2c_adapter *adap, int addr, int kind)
347 printk(KERN_INFO "IndyCam initialized\n"); 356 printk(KERN_INFO "IndyCam initialized\n");
348 357
349 return 0; 358 return 0;
350
351out_detach_client:
352 i2c_detach_client(client);
353out_free_camera:
354 kfree(camera);
355out_free_client:
356 kfree(client);
357 return err;
358} 359}
359 360
360static int indycam_probe(struct i2c_adapter *adap) 361static int indycam_remove(struct i2c_client *client)
361{
362 /* Indy specific crap */
363 if (adap->id == I2C_HW_SGI_VINO)
364 return indycam_attach(adap, INDYCAM_ADDR, 0);
365 /* Feel free to add probe here :-) */
366 return -ENODEV;
367}
368
369static int indycam_detach(struct i2c_client *client)
370{ 362{
371 struct indycam *camera = i2c_get_clientdata(client); 363 struct indycam *camera = i2c_get_clientdata(client);
372 364
373 i2c_detach_client(client);
374 kfree(camera); 365 kfree(camera);
375 kfree(client);
376 return 0; 366 return 0;
377} 367}
378 368
379static int indycam_command(struct i2c_client *client, unsigned int cmd, 369static int indycam_legacy_probe(struct i2c_adapter *adapter)
380 void *arg)
381{ 370{
382 // struct indycam *camera = i2c_get_clientdata(client); 371 return adapter->id == I2C_HW_SGI_VINO;
383
384 /* The old video_decoder interface just isn't enough,
385 * so we'll use some custom commands. */
386 switch (cmd) {
387 case DECODER_GET_CAPABILITIES: {
388 struct video_decoder_capability *cap = arg;
389
390 cap->flags = VIDEO_DECODER_NTSC;
391 cap->inputs = 1;
392 cap->outputs = 1;
393 break;
394 }
395 case DECODER_GET_STATUS: {
396 int *iarg = arg;
397
398 *iarg = DECODER_STATUS_GOOD | DECODER_STATUS_NTSC |
399 DECODER_STATUS_COLOR;
400 break;
401 }
402 case DECODER_SET_NORM: {
403 int *iarg = arg;
404
405 switch (*iarg) {
406 case VIDEO_MODE_NTSC:
407 break;
408 default:
409 return -EINVAL;
410 }
411 break;
412 }
413 case DECODER_SET_INPUT: {
414 int *iarg = arg;
415
416 if (*iarg != 0)
417 return -EINVAL;
418 break;
419 }
420 case DECODER_SET_OUTPUT: {
421 int *iarg = arg;
422
423 if (*iarg != 0)
424 return -EINVAL;
425 break;
426 }
427 case DECODER_ENABLE_OUTPUT: {
428 /* Always enabled */
429 break;
430 }
431 case DECODER_SET_PICTURE: {
432 // struct video_picture *pic = arg;
433 /* TODO: convert values for indycam_set_controls() */
434 break;
435 }
436 case DECODER_INDYCAM_GET_CONTROL: {
437 return indycam_get_control(client, arg);
438 }
439 case DECODER_INDYCAM_SET_CONTROL: {
440 return indycam_set_control(client, arg);
441 }
442 default:
443 return -EINVAL;
444 }
445
446 return 0;
447} 372}
448 373
449static struct i2c_driver i2c_driver_indycam = { 374static const struct i2c_device_id indycam_id[] = {
450 .driver = { 375 { "indycam", 0 },
451 .name = "indycam", 376 { }
452 }, 377};
453 .id = I2C_DRIVERID_INDYCAM, 378MODULE_DEVICE_TABLE(i2c, indycam_id);
454 .attach_adapter = indycam_probe, 379
455 .detach_client = indycam_detach, 380static struct v4l2_i2c_driver_data v4l2_i2c_data = {
456 .command = indycam_command, 381 .name = "indycam",
382 .driverid = I2C_DRIVERID_INDYCAM,
383 .command = indycam_command,
384 .probe = indycam_probe,
385 .remove = indycam_remove,
386 .legacy_probe = indycam_legacy_probe,
387 .id_table = indycam_id,
457}; 388};
458
459static int __init indycam_init(void)
460{
461 return i2c_add_driver(&i2c_driver_indycam);
462}
463
464static void __exit indycam_exit(void)
465{
466 i2c_del_driver(&i2c_driver_indycam);
467}
468
469module_init(indycam_init);
470module_exit(indycam_exit);
diff --git a/drivers/media/video/indycam.h b/drivers/media/video/indycam.h
index e6ee82063ed8..881f21c474c4 100644
--- a/drivers/media/video/indycam.h
+++ b/drivers/media/video/indycam.h
@@ -87,22 +87,7 @@
87 87
88/* Driver interface definitions */ 88/* Driver interface definitions */
89 89
90#define INDYCAM_CONTROL_AGC 0 /* boolean */ 90#define INDYCAM_CONTROL_RED_SATURATION (V4L2_CID_PRIVATE_BASE + 0)
91#define INDYCAM_CONTROL_AWB 1 /* boolean */ 91#define INDYCAM_CONTROL_BLUE_SATURATION (V4L2_CID_PRIVATE_BASE + 1)
92#define INDYCAM_CONTROL_SHUTTER 2
93#define INDYCAM_CONTROL_GAIN 3
94#define INDYCAM_CONTROL_RED_BALANCE 4
95#define INDYCAM_CONTROL_BLUE_BALANCE 5
96#define INDYCAM_CONTROL_RED_SATURATION 6
97#define INDYCAM_CONTROL_BLUE_SATURATION 7
98#define INDYCAM_CONTROL_GAMMA 8
99
100struct indycam_control {
101 u8 type;
102 s32 value;
103};
104
105#define DECODER_INDYCAM_GET_CONTROL _IOR('d', 193, struct indycam_control)
106#define DECODER_INDYCAM_SET_CONTROL _IOW('d', 194, struct indycam_control)
107 92
108#endif 93#endif
diff --git a/drivers/media/video/saa7191.c b/drivers/media/video/saa7191.c
index 9943e5c35e15..4c7bddf4b7ee 100644
--- a/drivers/media/video/saa7191.c
+++ b/drivers/media/video/saa7191.c
@@ -19,8 +19,7 @@
19#include <linux/mm.h> 19#include <linux/mm.h>
20#include <linux/slab.h> 20#include <linux/slab.h>
21 21
22#include <linux/videodev.h> 22#include <linux/videodev2.h>
23#include <linux/video_decoder.h>
24#include <linux/i2c.h> 23#include <linux/i2c.h>
25#include <media/v4l2-common.h> 24#include <media/v4l2-common.h>
26#include <media/v4l2-i2c-drv-legacy.h> 25#include <media/v4l2-i2c-drv-legacy.h>
@@ -57,7 +56,7 @@ struct saa7191 {
57 u8 reg[25]; 56 u8 reg[25];
58 57
59 int input; 58 int input;
60 int norm; 59 v4l2_std_id norm;
61}; 60};
62 61
63static const u8 initseq[] = { 62static const u8 initseq[] = {
@@ -191,7 +190,7 @@ static int saa7191_set_input(struct i2c_client *client, int input)
191 return 0; 190 return 0;
192} 191}
193 192
194static int saa7191_set_norm(struct i2c_client *client, int norm) 193static int saa7191_set_norm(struct i2c_client *client, v4l2_std_id norm)
195{ 194{
196 struct saa7191 *decoder = i2c_get_clientdata(client); 195 struct saa7191 *decoder = i2c_get_clientdata(client);
197 u8 stdc = saa7191_read_reg(client, SAA7191_REG_STDC); 196 u8 stdc = saa7191_read_reg(client, SAA7191_REG_STDC);
@@ -199,24 +198,20 @@ static int saa7191_set_norm(struct i2c_client *client, int norm)
199 u8 chcv = saa7191_read_reg(client, SAA7191_REG_CHCV); 198 u8 chcv = saa7191_read_reg(client, SAA7191_REG_CHCV);
200 int err; 199 int err;
201 200
202 switch(norm) { 201 if (norm & V4L2_STD_PAL) {
203 case SAA7191_NORM_PAL:
204 stdc &= ~SAA7191_STDC_SECS; 202 stdc &= ~SAA7191_STDC_SECS;
205 ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL); 203 ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL);
206 chcv = SAA7191_CHCV_PAL; 204 chcv = SAA7191_CHCV_PAL;
207 break; 205 } else if (norm & V4L2_STD_NTSC) {
208 case SAA7191_NORM_NTSC:
209 stdc &= ~SAA7191_STDC_SECS; 206 stdc &= ~SAA7191_STDC_SECS;
210 ctl3 &= ~SAA7191_CTL3_AUFD; 207 ctl3 &= ~SAA7191_CTL3_AUFD;
211 ctl3 |= SAA7191_CTL3_FSEL; 208 ctl3 |= SAA7191_CTL3_FSEL;
212 chcv = SAA7191_CHCV_NTSC; 209 chcv = SAA7191_CHCV_NTSC;
213 break; 210 } else if (norm & V4L2_STD_SECAM) {
214 case SAA7191_NORM_SECAM:
215 stdc |= SAA7191_STDC_SECS; 211 stdc |= SAA7191_STDC_SECS;
216 ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL); 212 ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL);
217 chcv = SAA7191_CHCV_PAL; 213 chcv = SAA7191_CHCV_PAL;
218 break; 214 } else {
219 default:
220 return -EINVAL; 215 return -EINVAL;
221 } 216 }
222 217
@@ -234,7 +229,7 @@ static int saa7191_set_norm(struct i2c_client *client, int norm)
234 229
235 dprintk("ctl3: %02x stdc: %02x chcv: %02x\n", ctl3, 230 dprintk("ctl3: %02x stdc: %02x chcv: %02x\n", ctl3,
236 stdc, chcv); 231 stdc, chcv);
237 dprintk("norm: %d\n", norm); 232 dprintk("norm: %llx\n", norm);
238 233
239 return 0; 234 return 0;
240} 235}
@@ -262,15 +257,19 @@ static int saa7191_wait_for_signal(struct i2c_client *client, u8 *status)
262 return -EBUSY; 257 return -EBUSY;
263} 258}
264 259
265static int saa7191_autodetect_norm_extended(struct i2c_client *client) 260static int saa7191_autodetect_norm_extended(struct i2c_client *client,
261 v4l2_std_id *norm)
266{ 262{
263 struct saa7191 *decoder = i2c_get_clientdata(client);
267 u8 stdc = saa7191_read_reg(client, SAA7191_REG_STDC); 264 u8 stdc = saa7191_read_reg(client, SAA7191_REG_STDC);
268 u8 ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3); 265 u8 ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
269 u8 status; 266 u8 status;
267 v4l2_std_id old_norm = decoder->norm;
270 int err = 0; 268 int err = 0;
271 269
272 dprintk("SAA7191 extended signal auto-detection...\n"); 270 dprintk("SAA7191 extended signal auto-detection...\n");
273 271
272 *norm = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
274 stdc &= ~SAA7191_STDC_SECS; 273 stdc &= ~SAA7191_STDC_SECS;
275 ctl3 &= ~(SAA7191_CTL3_FSEL); 274 ctl3 &= ~(SAA7191_CTL3_FSEL);
276 275
@@ -301,14 +300,15 @@ static int saa7191_autodetect_norm_extended(struct i2c_client *client)
301 if (status & SAA7191_STATUS_FIDT) { 300 if (status & SAA7191_STATUS_FIDT) {
302 /* 60Hz signal -> NTSC */ 301 /* 60Hz signal -> NTSC */
303 dprintk("60Hz signal: NTSC\n"); 302 dprintk("60Hz signal: NTSC\n");
304 return saa7191_set_norm(client, SAA7191_NORM_NTSC); 303 *norm = V4L2_STD_NTSC;
304 return 0;
305 } 305 }
306 306
307 /* 50Hz signal */ 307 /* 50Hz signal */
308 dprintk("50Hz signal: Trying PAL...\n"); 308 dprintk("50Hz signal: Trying PAL...\n");
309 309
310 /* try PAL first */ 310 /* try PAL first */
311 err = saa7191_set_norm(client, SAA7191_NORM_PAL); 311 err = saa7191_set_norm(client, V4L2_STD_PAL);
312 if (err) 312 if (err)
313 goto out; 313 goto out;
314 314
@@ -321,20 +321,20 @@ static int saa7191_autodetect_norm_extended(struct i2c_client *client)
321 /* not 50Hz ? */ 321 /* not 50Hz ? */
322 if (status & SAA7191_STATUS_FIDT) { 322 if (status & SAA7191_STATUS_FIDT) {
323 dprintk("No 50Hz signal\n"); 323 dprintk("No 50Hz signal\n");
324 err = -EAGAIN; 324 saa7191_set_norm(client, old_norm);
325 goto out; 325 return -EAGAIN;
326 } 326 }
327 327
328 if (status & SAA7191_STATUS_CODE) { 328 if (status & SAA7191_STATUS_CODE) {
329 dprintk("PAL\n"); 329 dprintk("PAL\n");
330 return 0; 330 *norm = V4L2_STD_PAL;
331 return saa7191_set_norm(client, old_norm);
331 } 332 }
332 333
333 dprintk("No color detected with PAL - Trying SECAM...\n"); 334 dprintk("No color detected with PAL - Trying SECAM...\n");
334 335
335 /* no color detected ? -> try SECAM */ 336 /* no color detected ? -> try SECAM */
336 err = saa7191_set_norm(client, 337 err = saa7191_set_norm(client, V4L2_STD_SECAM);
337 SAA7191_NORM_SECAM);
338 if (err) 338 if (err)
339 goto out; 339 goto out;
340 340
@@ -354,29 +354,14 @@ static int saa7191_autodetect_norm_extended(struct i2c_client *client)
354 if (status & SAA7191_STATUS_CODE) { 354 if (status & SAA7191_STATUS_CODE) {
355 /* Color detected -> SECAM */ 355 /* Color detected -> SECAM */
356 dprintk("SECAM\n"); 356 dprintk("SECAM\n");
357 return 0; 357 *norm = V4L2_STD_SECAM;
358 return saa7191_set_norm(client, old_norm);
358 } 359 }
359 360
360 dprintk("No color detected with SECAM - Going back to PAL.\n"); 361 dprintk("No color detected with SECAM - Going back to PAL.\n");
361 362
362 /* still no color detected ?
363 * -> set norm back to PAL */
364 err = saa7191_set_norm(client,
365 SAA7191_NORM_PAL);
366 if (err)
367 goto out;
368
369out: 363out:
370 ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3); 364 return saa7191_set_norm(client, old_norm);
371 if (ctl3 & SAA7191_CTL3_AUFD) {
372 ctl3 &= ~(SAA7191_CTL3_AUFD);
373 err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
374 if (err) {
375 err = -EIO;
376 }
377 }
378
379 return err;
380} 365}
381 366
382static int saa7191_autodetect_norm(struct i2c_client *client) 367static int saa7191_autodetect_norm(struct i2c_client *client)
@@ -403,26 +388,26 @@ static int saa7191_autodetect_norm(struct i2c_client *client)
403 if (status & SAA7191_STATUS_FIDT) { 388 if (status & SAA7191_STATUS_FIDT) {
404 /* 60hz signal -> NTSC */ 389 /* 60hz signal -> NTSC */
405 dprintk("NTSC\n"); 390 dprintk("NTSC\n");
406 return saa7191_set_norm(client, SAA7191_NORM_NTSC); 391 return saa7191_set_norm(client, V4L2_STD_NTSC);
407 } else { 392 } else {
408 /* 50hz signal -> PAL */ 393 /* 50hz signal -> PAL */
409 dprintk("PAL\n"); 394 dprintk("PAL\n");
410 return saa7191_set_norm(client, SAA7191_NORM_PAL); 395 return saa7191_set_norm(client, V4L2_STD_PAL);
411 } 396 }
412} 397}
413 398
414static int saa7191_get_control(struct i2c_client *client, 399static int saa7191_get_control(struct i2c_client *client,
415 struct saa7191_control *ctrl) 400 struct v4l2_control *ctrl)
416{ 401{
417 u8 reg; 402 u8 reg;
418 int ret = 0; 403 int ret = 0;
419 404
420 switch (ctrl->type) { 405 switch (ctrl->id) {
421 case SAA7191_CONTROL_BANDPASS: 406 case SAA7191_CONTROL_BANDPASS:
422 case SAA7191_CONTROL_BANDPASS_WEIGHT: 407 case SAA7191_CONTROL_BANDPASS_WEIGHT:
423 case SAA7191_CONTROL_CORING: 408 case SAA7191_CONTROL_CORING:
424 reg = saa7191_read_reg(client, SAA7191_REG_LUMA); 409 reg = saa7191_read_reg(client, SAA7191_REG_LUMA);
425 switch (ctrl->type) { 410 switch (ctrl->id) {
426 case SAA7191_CONTROL_BANDPASS: 411 case SAA7191_CONTROL_BANDPASS:
427 ctrl->value = ((s32)reg & SAA7191_LUMA_BPSS_MASK) 412 ctrl->value = ((s32)reg & SAA7191_LUMA_BPSS_MASK)
428 >> SAA7191_LUMA_BPSS_SHIFT; 413 >> SAA7191_LUMA_BPSS_SHIFT;
@@ -440,13 +425,13 @@ static int saa7191_get_control(struct i2c_client *client,
440 case SAA7191_CONTROL_FORCE_COLOUR: 425 case SAA7191_CONTROL_FORCE_COLOUR:
441 case SAA7191_CONTROL_CHROMA_GAIN: 426 case SAA7191_CONTROL_CHROMA_GAIN:
442 reg = saa7191_read_reg(client, SAA7191_REG_GAIN); 427 reg = saa7191_read_reg(client, SAA7191_REG_GAIN);
443 if (ctrl->type == SAA7191_CONTROL_FORCE_COLOUR) 428 if (ctrl->id == SAA7191_CONTROL_FORCE_COLOUR)
444 ctrl->value = ((s32)reg & SAA7191_GAIN_COLO) ? 1 : 0; 429 ctrl->value = ((s32)reg & SAA7191_GAIN_COLO) ? 1 : 0;
445 else 430 else
446 ctrl->value = ((s32)reg & SAA7191_GAIN_LFIS_MASK) 431 ctrl->value = ((s32)reg & SAA7191_GAIN_LFIS_MASK)
447 >> SAA7191_GAIN_LFIS_SHIFT; 432 >> SAA7191_GAIN_LFIS_SHIFT;
448 break; 433 break;
449 case SAA7191_CONTROL_HUE: 434 case V4L2_CID_HUE:
450 reg = saa7191_read_reg(client, SAA7191_REG_HUEC); 435 reg = saa7191_read_reg(client, SAA7191_REG_HUEC);
451 if (reg < 0x80) 436 if (reg < 0x80)
452 reg += 0x80; 437 reg += 0x80;
@@ -478,17 +463,17 @@ static int saa7191_get_control(struct i2c_client *client,
478} 463}
479 464
480static int saa7191_set_control(struct i2c_client *client, 465static int saa7191_set_control(struct i2c_client *client,
481 struct saa7191_control *ctrl) 466 struct v4l2_control *ctrl)
482{ 467{
483 u8 reg; 468 u8 reg;
484 int ret = 0; 469 int ret = 0;
485 470
486 switch (ctrl->type) { 471 switch (ctrl->id) {
487 case SAA7191_CONTROL_BANDPASS: 472 case SAA7191_CONTROL_BANDPASS:
488 case SAA7191_CONTROL_BANDPASS_WEIGHT: 473 case SAA7191_CONTROL_BANDPASS_WEIGHT:
489 case SAA7191_CONTROL_CORING: 474 case SAA7191_CONTROL_CORING:
490 reg = saa7191_read_reg(client, SAA7191_REG_LUMA); 475 reg = saa7191_read_reg(client, SAA7191_REG_LUMA);
491 switch (ctrl->type) { 476 switch (ctrl->id) {
492 case SAA7191_CONTROL_BANDPASS: 477 case SAA7191_CONTROL_BANDPASS:
493 reg &= ~SAA7191_LUMA_BPSS_MASK; 478 reg &= ~SAA7191_LUMA_BPSS_MASK;
494 reg |= (ctrl->value << SAA7191_LUMA_BPSS_SHIFT) 479 reg |= (ctrl->value << SAA7191_LUMA_BPSS_SHIFT)
@@ -510,7 +495,7 @@ static int saa7191_set_control(struct i2c_client *client,
510 case SAA7191_CONTROL_FORCE_COLOUR: 495 case SAA7191_CONTROL_FORCE_COLOUR:
511 case SAA7191_CONTROL_CHROMA_GAIN: 496 case SAA7191_CONTROL_CHROMA_GAIN:
512 reg = saa7191_read_reg(client, SAA7191_REG_GAIN); 497 reg = saa7191_read_reg(client, SAA7191_REG_GAIN);
513 if (ctrl->type == SAA7191_CONTROL_FORCE_COLOUR) { 498 if (ctrl->id == SAA7191_CONTROL_FORCE_COLOUR) {
514 if (ctrl->value) 499 if (ctrl->value)
515 reg |= SAA7191_GAIN_COLO; 500 reg |= SAA7191_GAIN_COLO;
516 else 501 else
@@ -522,7 +507,7 @@ static int saa7191_set_control(struct i2c_client *client,
522 } 507 }
523 ret = saa7191_write_reg(client, SAA7191_REG_GAIN, reg); 508 ret = saa7191_write_reg(client, SAA7191_REG_GAIN, reg);
524 break; 509 break;
525 case SAA7191_CONTROL_HUE: 510 case V4L2_CID_HUE:
526 reg = ctrl->value & 0xff; 511 reg = ctrl->value & 0xff;
527 if (reg < 0x80) 512 if (reg < 0x80)
528 reg += 0x80; 513 reg += 0x80;
@@ -568,141 +553,42 @@ static int saa7191_set_control(struct i2c_client *client,
568static int saa7191_command(struct i2c_client *client, unsigned int cmd, 553static int saa7191_command(struct i2c_client *client, unsigned int cmd,
569 void *arg) 554 void *arg)
570{ 555{
571 struct saa7191 *decoder = i2c_get_clientdata(client);
572
573 switch (cmd) { 556 switch (cmd) {
574 case DECODER_GET_CAPABILITIES: { 557 case VIDIOC_INT_G_INPUT_STATUS: {
575 struct video_decoder_capability *cap = arg; 558 u32 *iarg = arg;
576
577 cap->flags = VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC |
578 VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO;
579 cap->inputs = (client->adapter->id == I2C_HW_SGI_VINO) ? 2 : 1;
580 cap->outputs = 1;
581 break;
582 }
583 case DECODER_GET_STATUS: {
584 int *iarg = arg;
585 u8 status; 559 u8 status;
586 int res = 0; 560 int res = V4L2_IN_ST_NO_SIGNAL;
587 561
588 if (saa7191_read_status(client, &status)) { 562 if (saa7191_read_status(client, &status))
589 return -EIO; 563 return -EIO;
590 }
591 if ((status & SAA7191_STATUS_HLCK) == 0) 564 if ((status & SAA7191_STATUS_HLCK) == 0)
592 res |= DECODER_STATUS_GOOD; 565 res = 0;
593 if (status & SAA7191_STATUS_CODE) 566 if (!(status & SAA7191_STATUS_CODE))
594 res |= DECODER_STATUS_COLOR; 567 res |= V4L2_IN_ST_NO_COLOR;
595 switch (decoder->norm) {
596 case SAA7191_NORM_NTSC:
597 res |= DECODER_STATUS_NTSC;
598 break;
599 case SAA7191_NORM_PAL:
600 res |= DECODER_STATUS_PAL;
601 break;
602 case SAA7191_NORM_SECAM:
603 res |= DECODER_STATUS_SECAM;
604 break;
605 case SAA7191_NORM_AUTO:
606 default:
607 if (status & SAA7191_STATUS_FIDT)
608 res |= DECODER_STATUS_NTSC;
609 else
610 res |= DECODER_STATUS_PAL;
611 break;
612 }
613 *iarg = res; 568 *iarg = res;
614 break; 569 break;
615 } 570 }
616 case DECODER_SET_NORM: {
617 int *iarg = arg;
618
619 switch (*iarg) {
620 case VIDEO_MODE_AUTO:
621 return saa7191_autodetect_norm(client);
622 case VIDEO_MODE_PAL:
623 return saa7191_set_norm(client, SAA7191_NORM_PAL);
624 case VIDEO_MODE_NTSC:
625 return saa7191_set_norm(client, SAA7191_NORM_NTSC);
626 case VIDEO_MODE_SECAM:
627 return saa7191_set_norm(client, SAA7191_NORM_SECAM);
628 default:
629 return -EINVAL;
630 }
631 break;
632 }
633 case DECODER_SET_INPUT: {
634 int *iarg = arg;
635
636 switch (client->adapter->id) {
637 case I2C_HW_SGI_VINO:
638 return saa7191_set_input(client, *iarg);
639 default:
640 if (*iarg != 0)
641 return -EINVAL;
642 }
643 break;
644 }
645 case DECODER_SET_OUTPUT: {
646 int *iarg = arg;
647 571
648 /* not much choice of outputs */ 572 case VIDIOC_QUERYSTD:
649 if (*iarg != 0) 573 return saa7191_autodetect_norm_extended(client, arg);
650 return -EINVAL;
651 break;
652 }
653 case DECODER_ENABLE_OUTPUT: {
654 /* Always enabled */
655 break;
656 }
657 case DECODER_SET_PICTURE: {
658 struct video_picture *pic = arg;
659 unsigned val;
660 int err;
661
662 val = (pic->hue >> 8) - 0x80;
663 574
664 err = saa7191_write_reg(client, SAA7191_REG_HUEC, val); 575 case VIDIOC_S_STD: {
665 if (err) 576 v4l2_std_id *istd = arg;
666 return -EIO;
667 577
668 break; 578 return saa7191_set_norm(client, *istd);
669 } 579 }
670 case DECODER_SAA7191_GET_STATUS: { 580 case VIDIOC_INT_S_VIDEO_ROUTING: {
671 struct saa7191_status *status = arg; 581 struct v4l2_routing *route = arg;
672 u8 status_reg;
673
674 if (saa7191_read_status(client, &status_reg))
675 return -EIO;
676
677 status->signal = ((status_reg & SAA7191_STATUS_HLCK) == 0)
678 ? 1 : 0;
679 status->signal_60hz = (status_reg & SAA7191_STATUS_FIDT)
680 ? 1 : 0;
681 status->color = (status_reg & SAA7191_STATUS_CODE) ? 1 : 0;
682 582
683 status->input = decoder->input; 583 return saa7191_set_input(client, route->input);
684 status->norm = decoder->norm;
685
686 break;
687 } 584 }
688 case DECODER_SAA7191_SET_NORM: { 585
689 int *norm = arg; 586 case VIDIOC_G_CTRL:
690
691 switch (*norm) {
692 case SAA7191_NORM_AUTO:
693 return saa7191_autodetect_norm(client);
694 case SAA7191_NORM_AUTO_EXT:
695 return saa7191_autodetect_norm_extended(client);
696 default:
697 return saa7191_set_norm(client, *norm);
698 }
699 }
700 case DECODER_SAA7191_GET_CONTROL: {
701 return saa7191_get_control(client, arg); 587 return saa7191_get_control(client, arg);
702 } 588
703 case DECODER_SAA7191_SET_CONTROL: { 589 case VIDIOC_S_CTRL:
704 return saa7191_set_control(client, arg); 590 return saa7191_set_control(client, arg);
705 } 591
706 default: 592 default:
707 return -EINVAL; 593 return -EINVAL;
708 } 594 }
@@ -737,7 +623,7 @@ static int saa7191_probe(struct i2c_client *client,
737 printk(KERN_INFO "SAA7191 initialized\n"); 623 printk(KERN_INFO "SAA7191 initialized\n");
738 624
739 decoder->input = SAA7191_INPUT_COMPOSITE; 625 decoder->input = SAA7191_INPUT_COMPOSITE;
740 decoder->norm = SAA7191_NORM_PAL; 626 decoder->norm = V4L2_STD_PAL;
741 627
742 err = saa7191_autodetect_norm(client); 628 err = saa7191_autodetect_norm(client);
743 if (err && (err != -EBUSY)) 629 if (err && (err != -EBUSY))
diff --git a/drivers/media/video/saa7191.h b/drivers/media/video/saa7191.h
index a2310da1940d..803c74d6066f 100644
--- a/drivers/media/video/saa7191.h
+++ b/drivers/media/video/saa7191.h
@@ -176,11 +176,9 @@
176#define SAA7191_INPUT_COMPOSITE 0 176#define SAA7191_INPUT_COMPOSITE 0
177#define SAA7191_INPUT_SVIDEO 1 177#define SAA7191_INPUT_SVIDEO 1
178 178
179#define SAA7191_NORM_AUTO 0
180#define SAA7191_NORM_PAL 1 179#define SAA7191_NORM_PAL 1
181#define SAA7191_NORM_NTSC 2 180#define SAA7191_NORM_NTSC 2
182#define SAA7191_NORM_SECAM 3 181#define SAA7191_NORM_SECAM 3
183#define SAA7191_NORM_AUTO_EXT 4 /* extended auto-detection */
184 182
185struct saa7191_status { 183struct saa7191_status {
186 /* 0=no signal, 1=signal detected */ 184 /* 0=no signal, 1=signal detected */
@@ -232,24 +230,16 @@ struct saa7191_status {
232#define SAA7191_VNR_MAX 0x03 230#define SAA7191_VNR_MAX 0x03
233#define SAA7191_VNR_DEFAULT 0x00 231#define SAA7191_VNR_DEFAULT 0x00
234 232
235#define SAA7191_CONTROL_BANDPASS 0 233#define SAA7191_CONTROL_BANDPASS (V4L2_CID_PRIVATE_BASE + 0)
236#define SAA7191_CONTROL_BANDPASS_WEIGHT 1 234#define SAA7191_CONTROL_BANDPASS_WEIGHT (V4L2_CID_PRIVATE_BASE + 1)
237#define SAA7191_CONTROL_CORING 2 235#define SAA7191_CONTROL_CORING (V4L2_CID_PRIVATE_BASE + 2)
238#define SAA7191_CONTROL_FORCE_COLOUR 3 /* boolean */ 236#define SAA7191_CONTROL_FORCE_COLOUR (V4L2_CID_PRIVATE_BASE + 3)
239#define SAA7191_CONTROL_CHROMA_GAIN 4 237#define SAA7191_CONTROL_CHROMA_GAIN (V4L2_CID_PRIVATE_BASE + 4)
240#define SAA7191_CONTROL_HUE 5 238#define SAA7191_CONTROL_VTRC (V4L2_CID_PRIVATE_BASE + 5)
241#define SAA7191_CONTROL_VTRC 6 /* boolean */ 239#define SAA7191_CONTROL_LUMA_DELAY (V4L2_CID_PRIVATE_BASE + 6)
242#define SAA7191_CONTROL_LUMA_DELAY 7 240#define SAA7191_CONTROL_VNR (V4L2_CID_PRIVATE_BASE + 7)
243#define SAA7191_CONTROL_VNR 8
244
245struct saa7191_control {
246 u8 type;
247 s32 value;
248};
249 241
250#define DECODER_SAA7191_GET_STATUS _IOR('d', 195, struct saa7191_status) 242#define DECODER_SAA7191_GET_STATUS _IOR('d', 195, struct saa7191_status)
251#define DECODER_SAA7191_SET_NORM _IOW('d', 196, int) 243#define DECODER_SAA7191_SET_NORM _IOW('d', 196, int)
252#define DECODER_SAA7191_GET_CONTROL _IOR('d', 197, struct saa7191_control)
253#define DECODER_SAA7191_SET_CONTROL _IOW('d', 198, struct saa7191_control)
254 244
255#endif 245#endif
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
index f9ca27a9524e..0a5cd567bfb1 100644
--- a/drivers/media/video/vino.c
+++ b/drivers/media/video/vino.c
@@ -38,7 +38,6 @@
38#include <linux/videodev2.h> 38#include <linux/videodev2.h>
39#include <media/v4l2-common.h> 39#include <media/v4l2-common.h>
40#include <media/v4l2-ioctl.h> 40#include <media/v4l2-ioctl.h>
41#include <linux/video_decoder.h>
42#include <linux/mutex.h> 41#include <linux/mutex.h>
43 42
44#include <asm/paccess.h> 43#include <asm/paccess.h>
@@ -139,10 +138,6 @@ MODULE_LICENSE("GPL");
139#define VINO_DATA_NORM_PAL 1 138#define VINO_DATA_NORM_PAL 1
140#define VINO_DATA_NORM_SECAM 2 139#define VINO_DATA_NORM_SECAM 2
141#define VINO_DATA_NORM_D1 3 140#define VINO_DATA_NORM_D1 3
142/* The following are special entries that can be used to
143 * autodetect the norm. */
144#define VINO_DATA_NORM_AUTO 0xfe
145#define VINO_DATA_NORM_AUTO_EXT 0xff
146 141
147#define VINO_DATA_NORM_COUNT 4 142#define VINO_DATA_NORM_COUNT 4
148 143
@@ -360,11 +355,11 @@ static const struct vino_input vino_inputs[] = {
360 .name = "Composite", 355 .name = "Composite",
361 .std = V4L2_STD_NTSC | V4L2_STD_PAL 356 .std = V4L2_STD_NTSC | V4L2_STD_PAL
362 | V4L2_STD_SECAM, 357 | V4L2_STD_SECAM,
363 },{ 358 }, {
364 .name = "S-Video", 359 .name = "S-Video",
365 .std = V4L2_STD_NTSC | V4L2_STD_PAL 360 .std = V4L2_STD_NTSC | V4L2_STD_PAL
366 | V4L2_STD_SECAM, 361 | V4L2_STD_SECAM,
367 },{ 362 }, {
368 .name = "D1/IndyCam", 363 .name = "D1/IndyCam",
369 .std = V4L2_STD_NTSC, 364 .std = V4L2_STD_NTSC,
370 } 365 }
@@ -376,17 +371,17 @@ static const struct vino_data_format vino_data_formats[] = {
376 .bpp = 1, 371 .bpp = 1,
377 .pixelformat = V4L2_PIX_FMT_GREY, 372 .pixelformat = V4L2_PIX_FMT_GREY,
378 .colorspace = V4L2_COLORSPACE_SMPTE170M, 373 .colorspace = V4L2_COLORSPACE_SMPTE170M,
379 },{ 374 }, {
380 .description = "8-bit dithered RGB 3-3-2", 375 .description = "8-bit dithered RGB 3-3-2",
381 .bpp = 1, 376 .bpp = 1,
382 .pixelformat = V4L2_PIX_FMT_RGB332, 377 .pixelformat = V4L2_PIX_FMT_RGB332,
383 .colorspace = V4L2_COLORSPACE_SRGB, 378 .colorspace = V4L2_COLORSPACE_SRGB,
384 },{ 379 }, {
385 .description = "32-bit RGB", 380 .description = "32-bit RGB",
386 .bpp = 4, 381 .bpp = 4,
387 .pixelformat = V4L2_PIX_FMT_RGB32, 382 .pixelformat = V4L2_PIX_FMT_RGB32,
388 .colorspace = V4L2_COLORSPACE_SRGB, 383 .colorspace = V4L2_COLORSPACE_SRGB,
389 },{ 384 }, {
390 .description = "YUV 4:2:2", 385 .description = "YUV 4:2:2",
391 .bpp = 2, 386 .bpp = 2,
392 .pixelformat = V4L2_PIX_FMT_YUYV, // XXX: swapped? 387 .pixelformat = V4L2_PIX_FMT_YUYV, // XXX: swapped?
@@ -417,7 +412,7 @@ static const struct vino_data_norm vino_data_norms[] = {
417 + VINO_NTSC_HEIGHT / 2 - 1, 412 + VINO_NTSC_HEIGHT / 2 - 1,
418 .right = VINO_NTSC_WIDTH, 413 .right = VINO_NTSC_WIDTH,
419 }, 414 },
420 },{ 415 }, {
421 .description = "PAL", 416 .description = "PAL",
422 .std = V4L2_STD_PAL, 417 .std = V4L2_STD_PAL,
423 .fps_min = 5, 418 .fps_min = 5,
@@ -439,7 +434,7 @@ static const struct vino_data_norm vino_data_norms[] = {
439 + VINO_PAL_HEIGHT / 2 - 1, 434 + VINO_PAL_HEIGHT / 2 - 1,
440 .right = VINO_PAL_WIDTH, 435 .right = VINO_PAL_WIDTH,
441 }, 436 },
442 },{ 437 }, {
443 .description = "SECAM", 438 .description = "SECAM",
444 .std = V4L2_STD_SECAM, 439 .std = V4L2_STD_SECAM,
445 .fps_min = 5, 440 .fps_min = 5,
@@ -461,7 +456,7 @@ static const struct vino_data_norm vino_data_norms[] = {
461 + VINO_PAL_HEIGHT / 2 - 1, 456 + VINO_PAL_HEIGHT / 2 - 1,
462 .right = VINO_PAL_WIDTH, 457 .right = VINO_PAL_WIDTH,
463 }, 458 },
464 },{ 459 }, {
465 .description = "NTSC/D1", 460 .description = "NTSC/D1",
466 .std = V4L2_STD_NTSC, 461 .std = V4L2_STD_NTSC,
467 .fps_min = 6, 462 .fps_min = 6,
@@ -497,9 +492,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
497 .maximum = 1, 492 .maximum = 1,
498 .step = 1, 493 .step = 1,
499 .default_value = INDYCAM_AGC_DEFAULT, 494 .default_value = INDYCAM_AGC_DEFAULT,
500 .flags = 0, 495 }, {
501 .reserved = { INDYCAM_CONTROL_AGC, 0 },
502 },{
503 .id = V4L2_CID_AUTO_WHITE_BALANCE, 496 .id = V4L2_CID_AUTO_WHITE_BALANCE,
504 .type = V4L2_CTRL_TYPE_BOOLEAN, 497 .type = V4L2_CTRL_TYPE_BOOLEAN,
505 .name = "Automatic White Balance", 498 .name = "Automatic White Balance",
@@ -507,9 +500,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
507 .maximum = 1, 500 .maximum = 1,
508 .step = 1, 501 .step = 1,
509 .default_value = INDYCAM_AWB_DEFAULT, 502 .default_value = INDYCAM_AWB_DEFAULT,
510 .flags = 0, 503 }, {
511 .reserved = { INDYCAM_CONTROL_AWB, 0 },
512 },{
513 .id = V4L2_CID_GAIN, 504 .id = V4L2_CID_GAIN,
514 .type = V4L2_CTRL_TYPE_INTEGER, 505 .type = V4L2_CTRL_TYPE_INTEGER,
515 .name = "Gain", 506 .name = "Gain",
@@ -517,29 +508,23 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
517 .maximum = INDYCAM_GAIN_MAX, 508 .maximum = INDYCAM_GAIN_MAX,
518 .step = 1, 509 .step = 1,
519 .default_value = INDYCAM_GAIN_DEFAULT, 510 .default_value = INDYCAM_GAIN_DEFAULT,
520 .flags = 0, 511 }, {
521 .reserved = { INDYCAM_CONTROL_GAIN, 0 }, 512 .id = INDYCAM_CONTROL_RED_SATURATION,
522 },{
523 .id = V4L2_CID_PRIVATE_BASE,
524 .type = V4L2_CTRL_TYPE_INTEGER, 513 .type = V4L2_CTRL_TYPE_INTEGER,
525 .name = "Red Saturation", 514 .name = "Red Saturation",
526 .minimum = INDYCAM_RED_SATURATION_MIN, 515 .minimum = INDYCAM_RED_SATURATION_MIN,
527 .maximum = INDYCAM_RED_SATURATION_MAX, 516 .maximum = INDYCAM_RED_SATURATION_MAX,
528 .step = 1, 517 .step = 1,
529 .default_value = INDYCAM_RED_SATURATION_DEFAULT, 518 .default_value = INDYCAM_RED_SATURATION_DEFAULT,
530 .flags = 0, 519 }, {
531 .reserved = { INDYCAM_CONTROL_RED_SATURATION, 0 }, 520 .id = INDYCAM_CONTROL_BLUE_SATURATION,
532 },{
533 .id = V4L2_CID_PRIVATE_BASE + 1,
534 .type = V4L2_CTRL_TYPE_INTEGER, 521 .type = V4L2_CTRL_TYPE_INTEGER,
535 .name = "Blue Saturation", 522 .name = "Blue Saturation",
536 .minimum = INDYCAM_BLUE_SATURATION_MIN, 523 .minimum = INDYCAM_BLUE_SATURATION_MIN,
537 .maximum = INDYCAM_BLUE_SATURATION_MAX, 524 .maximum = INDYCAM_BLUE_SATURATION_MAX,
538 .step = 1, 525 .step = 1,
539 .default_value = INDYCAM_BLUE_SATURATION_DEFAULT, 526 .default_value = INDYCAM_BLUE_SATURATION_DEFAULT,
540 .flags = 0, 527 }, {
541 .reserved = { INDYCAM_CONTROL_BLUE_SATURATION, 0 },
542 },{
543 .id = V4L2_CID_RED_BALANCE, 528 .id = V4L2_CID_RED_BALANCE,
544 .type = V4L2_CTRL_TYPE_INTEGER, 529 .type = V4L2_CTRL_TYPE_INTEGER,
545 .name = "Red Balance", 530 .name = "Red Balance",
@@ -547,9 +532,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
547 .maximum = INDYCAM_RED_BALANCE_MAX, 532 .maximum = INDYCAM_RED_BALANCE_MAX,
548 .step = 1, 533 .step = 1,
549 .default_value = INDYCAM_RED_BALANCE_DEFAULT, 534 .default_value = INDYCAM_RED_BALANCE_DEFAULT,
550 .flags = 0, 535 }, {
551 .reserved = { INDYCAM_CONTROL_RED_BALANCE, 0 },
552 },{
553 .id = V4L2_CID_BLUE_BALANCE, 536 .id = V4L2_CID_BLUE_BALANCE,
554 .type = V4L2_CTRL_TYPE_INTEGER, 537 .type = V4L2_CTRL_TYPE_INTEGER,
555 .name = "Blue Balance", 538 .name = "Blue Balance",
@@ -557,9 +540,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
557 .maximum = INDYCAM_BLUE_BALANCE_MAX, 540 .maximum = INDYCAM_BLUE_BALANCE_MAX,
558 .step = 1, 541 .step = 1,
559 .default_value = INDYCAM_BLUE_BALANCE_DEFAULT, 542 .default_value = INDYCAM_BLUE_BALANCE_DEFAULT,
560 .flags = 0, 543 }, {
561 .reserved = { INDYCAM_CONTROL_BLUE_BALANCE, 0 },
562 },{
563 .id = V4L2_CID_EXPOSURE, 544 .id = V4L2_CID_EXPOSURE,
564 .type = V4L2_CTRL_TYPE_INTEGER, 545 .type = V4L2_CTRL_TYPE_INTEGER,
565 .name = "Shutter Control", 546 .name = "Shutter Control",
@@ -567,9 +548,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
567 .maximum = INDYCAM_SHUTTER_MAX, 548 .maximum = INDYCAM_SHUTTER_MAX,
568 .step = 1, 549 .step = 1,
569 .default_value = INDYCAM_SHUTTER_DEFAULT, 550 .default_value = INDYCAM_SHUTTER_DEFAULT,
570 .flags = 0, 551 }, {
571 .reserved = { INDYCAM_CONTROL_SHUTTER, 0 },
572 },{
573 .id = V4L2_CID_GAMMA, 552 .id = V4L2_CID_GAMMA,
574 .type = V4L2_CTRL_TYPE_INTEGER, 553 .type = V4L2_CTRL_TYPE_INTEGER,
575 .name = "Gamma", 554 .name = "Gamma",
@@ -577,8 +556,6 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
577 .maximum = INDYCAM_GAMMA_MAX, 556 .maximum = INDYCAM_GAMMA_MAX,
578 .step = 1, 557 .step = 1,
579 .default_value = INDYCAM_GAMMA_DEFAULT, 558 .default_value = INDYCAM_GAMMA_DEFAULT,
580 .flags = 0,
581 .reserved = { INDYCAM_CONTROL_GAMMA, 0 },
582 } 559 }
583}; 560};
584 561
@@ -593,88 +570,70 @@ struct v4l2_queryctrl vino_saa7191_v4l2_controls[] = {
593 .maximum = SAA7191_HUE_MAX, 570 .maximum = SAA7191_HUE_MAX,
594 .step = 1, 571 .step = 1,
595 .default_value = SAA7191_HUE_DEFAULT, 572 .default_value = SAA7191_HUE_DEFAULT,
596 .flags = 0, 573 }, {
597 .reserved = { SAA7191_CONTROL_HUE, 0 }, 574 .id = SAA7191_CONTROL_BANDPASS,
598 },{
599 .id = V4L2_CID_PRIVATE_BASE,
600 .type = V4L2_CTRL_TYPE_INTEGER, 575 .type = V4L2_CTRL_TYPE_INTEGER,
601 .name = "Luminance Bandpass", 576 .name = "Luminance Bandpass",
602 .minimum = SAA7191_BANDPASS_MIN, 577 .minimum = SAA7191_BANDPASS_MIN,
603 .maximum = SAA7191_BANDPASS_MAX, 578 .maximum = SAA7191_BANDPASS_MAX,
604 .step = 1, 579 .step = 1,
605 .default_value = SAA7191_BANDPASS_DEFAULT, 580 .default_value = SAA7191_BANDPASS_DEFAULT,
606 .flags = 0, 581 }, {
607 .reserved = { SAA7191_CONTROL_BANDPASS, 0 }, 582 .id = SAA7191_CONTROL_BANDPASS_WEIGHT,
608 },{
609 .id = V4L2_CID_PRIVATE_BASE + 1,
610 .type = V4L2_CTRL_TYPE_INTEGER, 583 .type = V4L2_CTRL_TYPE_INTEGER,
611 .name = "Luminance Bandpass Weight", 584 .name = "Luminance Bandpass Weight",
612 .minimum = SAA7191_BANDPASS_WEIGHT_MIN, 585 .minimum = SAA7191_BANDPASS_WEIGHT_MIN,
613 .maximum = SAA7191_BANDPASS_WEIGHT_MAX, 586 .maximum = SAA7191_BANDPASS_WEIGHT_MAX,
614 .step = 1, 587 .step = 1,
615 .default_value = SAA7191_BANDPASS_WEIGHT_DEFAULT, 588 .default_value = SAA7191_BANDPASS_WEIGHT_DEFAULT,
616 .flags = 0, 589 }, {
617 .reserved = { SAA7191_CONTROL_BANDPASS_WEIGHT, 0 }, 590 .id = SAA7191_CONTROL_CORING,
618 },{
619 .id = V4L2_CID_PRIVATE_BASE + 2,
620 .type = V4L2_CTRL_TYPE_INTEGER, 591 .type = V4L2_CTRL_TYPE_INTEGER,
621 .name = "HF Luminance Coring", 592 .name = "HF Luminance Coring",
622 .minimum = SAA7191_CORING_MIN, 593 .minimum = SAA7191_CORING_MIN,
623 .maximum = SAA7191_CORING_MAX, 594 .maximum = SAA7191_CORING_MAX,
624 .step = 1, 595 .step = 1,
625 .default_value = SAA7191_CORING_DEFAULT, 596 .default_value = SAA7191_CORING_DEFAULT,
626 .flags = 0, 597 }, {
627 .reserved = { SAA7191_CONTROL_CORING, 0 }, 598 .id = SAA7191_CONTROL_FORCE_COLOUR,
628 },{
629 .id = V4L2_CID_PRIVATE_BASE + 3,
630 .type = V4L2_CTRL_TYPE_BOOLEAN, 599 .type = V4L2_CTRL_TYPE_BOOLEAN,
631 .name = "Force Colour", 600 .name = "Force Colour",
632 .minimum = SAA7191_FORCE_COLOUR_MIN, 601 .minimum = SAA7191_FORCE_COLOUR_MIN,
633 .maximum = SAA7191_FORCE_COLOUR_MAX, 602 .maximum = SAA7191_FORCE_COLOUR_MAX,
634 .step = 1, 603 .step = 1,
635 .default_value = SAA7191_FORCE_COLOUR_DEFAULT, 604 .default_value = SAA7191_FORCE_COLOUR_DEFAULT,
636 .flags = 0, 605 }, {
637 .reserved = { SAA7191_CONTROL_FORCE_COLOUR, 0 }, 606 .id = SAA7191_CONTROL_CHROMA_GAIN,
638 },{
639 .id = V4L2_CID_PRIVATE_BASE + 4,
640 .type = V4L2_CTRL_TYPE_INTEGER, 607 .type = V4L2_CTRL_TYPE_INTEGER,
641 .name = "Chrominance Gain Control", 608 .name = "Chrominance Gain Control",
642 .minimum = SAA7191_CHROMA_GAIN_MIN, 609 .minimum = SAA7191_CHROMA_GAIN_MIN,
643 .maximum = SAA7191_CHROMA_GAIN_MAX, 610 .maximum = SAA7191_CHROMA_GAIN_MAX,
644 .step = 1, 611 .step = 1,
645 .default_value = SAA7191_CHROMA_GAIN_DEFAULT, 612 .default_value = SAA7191_CHROMA_GAIN_DEFAULT,
646 .flags = 0, 613 }, {
647 .reserved = { SAA7191_CONTROL_CHROMA_GAIN, 0 }, 614 .id = SAA7191_CONTROL_VTRC,
648 },{
649 .id = V4L2_CID_PRIVATE_BASE + 5,
650 .type = V4L2_CTRL_TYPE_BOOLEAN, 615 .type = V4L2_CTRL_TYPE_BOOLEAN,
651 .name = "VTR Time Constant", 616 .name = "VTR Time Constant",
652 .minimum = SAA7191_VTRC_MIN, 617 .minimum = SAA7191_VTRC_MIN,
653 .maximum = SAA7191_VTRC_MAX, 618 .maximum = SAA7191_VTRC_MAX,
654 .step = 1, 619 .step = 1,
655 .default_value = SAA7191_VTRC_DEFAULT, 620 .default_value = SAA7191_VTRC_DEFAULT,
656 .flags = 0, 621 }, {
657 .reserved = { SAA7191_CONTROL_VTRC, 0 }, 622 .id = SAA7191_CONTROL_LUMA_DELAY,
658 },{
659 .id = V4L2_CID_PRIVATE_BASE + 6,
660 .type = V4L2_CTRL_TYPE_INTEGER, 623 .type = V4L2_CTRL_TYPE_INTEGER,
661 .name = "Luminance Delay Compensation", 624 .name = "Luminance Delay Compensation",
662 .minimum = SAA7191_LUMA_DELAY_MIN, 625 .minimum = SAA7191_LUMA_DELAY_MIN,
663 .maximum = SAA7191_LUMA_DELAY_MAX, 626 .maximum = SAA7191_LUMA_DELAY_MAX,
664 .step = 1, 627 .step = 1,
665 .default_value = SAA7191_LUMA_DELAY_DEFAULT, 628 .default_value = SAA7191_LUMA_DELAY_DEFAULT,
666 .flags = 0, 629 }, {
667 .reserved = { SAA7191_CONTROL_LUMA_DELAY, 0 }, 630 .id = SAA7191_CONTROL_VNR,
668 },{
669 .id = V4L2_CID_PRIVATE_BASE + 7,
670 .type = V4L2_CTRL_TYPE_INTEGER, 631 .type = V4L2_CTRL_TYPE_INTEGER,
671 .name = "Vertical Noise Reduction", 632 .name = "Vertical Noise Reduction",
672 .minimum = SAA7191_VNR_MIN, 633 .minimum = SAA7191_VNR_MIN,
673 .maximum = SAA7191_VNR_MAX, 634 .maximum = SAA7191_VNR_MAX,
674 .step = 1, 635 .step = 1,
675 .default_value = SAA7191_VNR_DEFAULT, 636 .default_value = SAA7191_VNR_DEFAULT,
676 .flags = 0,
677 .reserved = { SAA7191_CONTROL_VNR, 0 },
678 } 637 }
679}; 638};
680 639
@@ -2490,77 +2449,6 @@ static int vino_get_saa7191_input(int input)
2490 } 2449 }
2491} 2450}
2492 2451
2493static int vino_get_saa7191_norm(unsigned int data_norm)
2494{
2495 switch (data_norm) {
2496 case VINO_DATA_NORM_AUTO:
2497 return SAA7191_NORM_AUTO;
2498 case VINO_DATA_NORM_AUTO_EXT:
2499 return SAA7191_NORM_AUTO_EXT;
2500 case VINO_DATA_NORM_PAL:
2501 return SAA7191_NORM_PAL;
2502 case VINO_DATA_NORM_NTSC:
2503 return SAA7191_NORM_NTSC;
2504 case VINO_DATA_NORM_SECAM:
2505 return SAA7191_NORM_SECAM;
2506 default:
2507 printk(KERN_ERR "VINO: vino_get_saa7191_norm(): "
2508 "invalid norm!\n");
2509 return -1;
2510 }
2511}
2512
2513static int vino_get_from_saa7191_norm(int saa7191_norm)
2514{
2515 switch (saa7191_norm) {
2516 case SAA7191_NORM_PAL:
2517 return VINO_DATA_NORM_PAL;
2518 case SAA7191_NORM_NTSC:
2519 return VINO_DATA_NORM_NTSC;
2520 case SAA7191_NORM_SECAM:
2521 return VINO_DATA_NORM_SECAM;
2522 default:
2523 printk(KERN_ERR "VINO: vino_get_from_saa7191_norm(): "
2524 "invalid norm!\n");
2525 return VINO_DATA_NORM_NONE;
2526 }
2527}
2528
2529static int vino_saa7191_set_norm(unsigned int *data_norm)
2530{
2531 int saa7191_norm, new_data_norm;
2532 int err = 0;
2533
2534 saa7191_norm = vino_get_saa7191_norm(*data_norm);
2535
2536 err = i2c_decoder_command(DECODER_SAA7191_SET_NORM,
2537 &saa7191_norm);
2538 if (err)
2539 goto out;
2540
2541 if ((*data_norm == VINO_DATA_NORM_AUTO)
2542 || (*data_norm == VINO_DATA_NORM_AUTO_EXT)) {
2543 struct saa7191_status status;
2544
2545 err = i2c_decoder_command(DECODER_SAA7191_GET_STATUS,
2546 &status);
2547 if (err)
2548 goto out;
2549
2550 new_data_norm =
2551 vino_get_from_saa7191_norm(status.norm);
2552 if (new_data_norm == VINO_DATA_NORM_NONE) {
2553 err = -EINVAL;
2554 goto out;
2555 }
2556
2557 *data_norm = (unsigned int)new_data_norm;
2558 }
2559
2560out:
2561 return err;
2562}
2563
2564/* execute with input_lock locked */ 2452/* execute with input_lock locked */
2565static int vino_is_input_owner(struct vino_channel_settings *vcs) 2453static int vino_is_input_owner(struct vino_channel_settings *vcs)
2566{ 2454{
@@ -2593,15 +2481,16 @@ static int vino_acquire_input(struct vino_channel_settings *vcs)
2593 vcs->data_norm = VINO_DATA_NORM_D1; 2481 vcs->data_norm = VINO_DATA_NORM_D1;
2594 } else if (vino_drvdata->decoder.driver 2482 } else if (vino_drvdata->decoder.driver
2595 && (vino_drvdata->decoder.owner == VINO_NO_CHANNEL)) { 2483 && (vino_drvdata->decoder.owner == VINO_NO_CHANNEL)) {
2596 int input, data_norm; 2484 int input;
2597 int saa7191_input; 2485 int data_norm;
2486 v4l2_std_id norm;
2487 struct v4l2_routing route = { 0, 0 };
2598 2488
2599 i2c_use_client(vino_drvdata->decoder.driver); 2489 i2c_use_client(vino_drvdata->decoder.driver);
2600 input = VINO_INPUT_COMPOSITE; 2490 input = VINO_INPUT_COMPOSITE;
2601 2491
2602 saa7191_input = vino_get_saa7191_input(input); 2492 route.input = vino_get_saa7191_input(input);
2603 ret = i2c_decoder_command(DECODER_SET_INPUT, 2493 ret = i2c_decoder_command(VIDIOC_INT_S_VIDEO_ROUTING, &route);
2604 &saa7191_input);
2605 if (ret) { 2494 if (ret) {
2606 ret = -EINVAL; 2495 ret = -EINVAL;
2607 goto out; 2496 goto out;
@@ -2612,12 +2501,15 @@ static int vino_acquire_input(struct vino_channel_settings *vcs)
2612 /* Don't hold spinlocks while auto-detecting norm 2501 /* Don't hold spinlocks while auto-detecting norm
2613 * as it may take a while... */ 2502 * as it may take a while... */
2614 2503
2615 data_norm = VINO_DATA_NORM_AUTO_EXT; 2504 ret = i2c_decoder_command(VIDIOC_QUERYSTD, &norm);
2616 2505 if (!ret) {
2617 ret = vino_saa7191_set_norm(&data_norm); 2506 for (data_norm = 0; data_norm < 3; data_norm++) {
2618 if ((ret == -EBUSY) || (ret == -EAGAIN)) { 2507 if (vino_data_norms[data_norm].std & norm)
2619 data_norm = VINO_DATA_NORM_PAL; 2508 break;
2620 ret = vino_saa7191_set_norm(&data_norm); 2509 }
2510 if (data_norm == 3)
2511 data_norm = VINO_DATA_NORM_PAL;
2512 ret = i2c_decoder_command(VIDIOC_S_STD, &norm);
2621 } 2513 }
2622 2514
2623 spin_lock_irqsave(&vino_drvdata->input_lock, flags); 2515 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
@@ -2684,11 +2576,11 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input)
2684 2576
2685 if (vino_drvdata->decoder.owner == vcs->channel) { 2577 if (vino_drvdata->decoder.owner == vcs->channel) {
2686 int data_norm; 2578 int data_norm;
2687 int saa7191_input; 2579 v4l2_std_id norm;
2580 struct v4l2_routing route = { 0, 0 };
2688 2581
2689 saa7191_input = vino_get_saa7191_input(input); 2582 route.input = vino_get_saa7191_input(input);
2690 ret = i2c_decoder_command(DECODER_SET_INPUT, 2583 ret = i2c_decoder_command(VIDIOC_INT_S_VIDEO_ROUTING, &route);
2691 &saa7191_input);
2692 if (ret) { 2584 if (ret) {
2693 vino_drvdata->decoder.owner = VINO_NO_CHANNEL; 2585 vino_drvdata->decoder.owner = VINO_NO_CHANNEL;
2694 ret = -EINVAL; 2586 ret = -EINVAL;
@@ -2700,12 +2592,15 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input)
2700 /* Don't hold spinlocks while auto-detecting norm 2592 /* Don't hold spinlocks while auto-detecting norm
2701 * as it may take a while... */ 2593 * as it may take a while... */
2702 2594
2703 data_norm = VINO_DATA_NORM_AUTO_EXT; 2595 ret = i2c_decoder_command(VIDIOC_QUERYSTD, &norm);
2704 2596 if (!ret) {
2705 ret = vino_saa7191_set_norm(&data_norm); 2597 for (data_norm = 0; data_norm < 3; data_norm++) {
2706 if ((ret == -EBUSY) || (ret == -EAGAIN)) { 2598 if (vino_data_norms[data_norm].std & norm)
2707 data_norm = VINO_DATA_NORM_PAL; 2599 break;
2708 ret = vino_saa7191_set_norm(&data_norm); 2600 }
2601 if (data_norm == 3)
2602 data_norm = VINO_DATA_NORM_PAL;
2603 ret = i2c_decoder_command(VIDIOC_S_STD, &norm);
2709 } 2604 }
2710 2605
2711 spin_lock_irqsave(&vino_drvdata->input_lock, flags); 2606 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
@@ -2733,8 +2628,7 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input)
2733 if (vcs2->input == VINO_INPUT_D1) { 2628 if (vcs2->input == VINO_INPUT_D1) {
2734 vino_drvdata->camera.owner = vcs2->channel; 2629 vino_drvdata->camera.owner = vcs2->channel;
2735 } else { 2630 } else {
2736 i2c_release_client(vino_drvdata-> 2631 i2c_release_client(vino_drvdata->camera.driver);
2737 camera.driver);
2738 vino_drvdata->camera.owner = VINO_NO_CHANNEL; 2632 vino_drvdata->camera.owner = VINO_NO_CHANNEL;
2739 } 2633 }
2740 } 2634 }
@@ -2829,18 +2723,16 @@ static int vino_set_data_norm(struct vino_channel_settings *vcs,
2829 switch (vcs->input) { 2723 switch (vcs->input) {
2830 case VINO_INPUT_D1: 2724 case VINO_INPUT_D1:
2831 /* only one "norm" supported */ 2725 /* only one "norm" supported */
2832 if ((data_norm != VINO_DATA_NORM_D1) 2726 if (data_norm != VINO_DATA_NORM_D1)
2833 && (data_norm != VINO_DATA_NORM_AUTO)
2834 && (data_norm != VINO_DATA_NORM_AUTO_EXT))
2835 return -EINVAL; 2727 return -EINVAL;
2836 break; 2728 break;
2837 case VINO_INPUT_COMPOSITE: 2729 case VINO_INPUT_COMPOSITE:
2838 case VINO_INPUT_SVIDEO: { 2730 case VINO_INPUT_SVIDEO: {
2731 v4l2_std_id norm;
2732
2839 if ((data_norm != VINO_DATA_NORM_PAL) 2733 if ((data_norm != VINO_DATA_NORM_PAL)
2840 && (data_norm != VINO_DATA_NORM_NTSC) 2734 && (data_norm != VINO_DATA_NORM_NTSC)
2841 && (data_norm != VINO_DATA_NORM_SECAM) 2735 && (data_norm != VINO_DATA_NORM_SECAM))
2842 && (data_norm != VINO_DATA_NORM_AUTO)
2843 && (data_norm != VINO_DATA_NORM_AUTO_EXT))
2844 return -EINVAL; 2736 return -EINVAL;
2845 2737
2846 spin_unlock_irqrestore(&vino_drvdata->input_lock, *flags); 2738 spin_unlock_irqrestore(&vino_drvdata->input_lock, *flags);
@@ -2848,7 +2740,8 @@ static int vino_set_data_norm(struct vino_channel_settings *vcs,
2848 /* Don't hold spinlocks while setting norm 2740 /* Don't hold spinlocks while setting norm
2849 * as it may take a while... */ 2741 * as it may take a while... */
2850 2742
2851 err = vino_saa7191_set_norm(&data_norm); 2743 norm = vino_data_norms[data_norm].std;
2744 err = i2c_decoder_command(VIDIOC_S_STD, &norm);
2852 2745
2853 spin_lock_irqsave(&vino_drvdata->input_lock, *flags); 2746 spin_lock_irqsave(&vino_drvdata->input_lock, *flags);
2854 2747
@@ -2998,14 +2891,8 @@ static int vino_enum_input(struct file *file, void *__fh,
2998 i->std = vino_inputs[input].std; 2891 i->std = vino_inputs[input].std;
2999 strcpy(i->name, vino_inputs[input].name); 2892 strcpy(i->name, vino_inputs[input].name);
3000 2893
3001 if ((input == VINO_INPUT_COMPOSITE) 2894 if (input == VINO_INPUT_COMPOSITE || input == VINO_INPUT_SVIDEO)
3002 || (input == VINO_INPUT_SVIDEO)) { 2895 i2c_decoder_command(VIDIOC_INT_G_INPUT_STATUS, &i->status);
3003 struct saa7191_status status;
3004 i2c_decoder_command(DECODER_SAA7191_GET_STATUS, &status);
3005 i->status |= status.signal ? 0 : V4L2_IN_ST_NO_SIGNAL;
3006 i->status |= status.color ? 0 : V4L2_IN_ST_NO_COLOR;
3007 }
3008
3009 return 0; 2896 return 0;
3010} 2897}
3011 2898
@@ -3062,19 +2949,7 @@ static int vino_querystd(struct file *file, void *__fh,
3062 break; 2949 break;
3063 case VINO_INPUT_COMPOSITE: 2950 case VINO_INPUT_COMPOSITE:
3064 case VINO_INPUT_SVIDEO: { 2951 case VINO_INPUT_SVIDEO: {
3065 struct saa7191_status status; 2952 i2c_decoder_command(VIDIOC_QUERYSTD, std);
3066
3067 i2c_decoder_command(DECODER_SAA7191_GET_STATUS, &status);
3068
3069 if (status.signal) {
3070 if (status.signal_60hz) {
3071 *std = V4L2_STD_NTSC;
3072 } else {
3073 *std = V4L2_STD_PAL | V4L2_STD_SECAM;
3074 }
3075 } else {
3076 *std = vino_inputs[vcs->input].std;
3077 }
3078 break; 2953 break;
3079 } 2954 }
3080 default: 2955 default:
@@ -3126,12 +3001,7 @@ static int vino_s_std(struct file *file, void *__fh,
3126 if (vcs->input == VINO_INPUT_D1) 3001 if (vcs->input == VINO_INPUT_D1)
3127 goto out; 3002 goto out;
3128 3003
3129 if (((*std) & V4L2_STD_PAL) 3004 if ((*std) & V4L2_STD_PAL) {
3130 && ((*std) & V4L2_STD_NTSC)
3131 && ((*std) & V4L2_STD_SECAM)) {
3132 ret = vino_set_data_norm(vcs, VINO_DATA_NORM_AUTO_EXT,
3133 &flags);
3134 } else if ((*std) & V4L2_STD_PAL) {
3135 ret = vino_set_data_norm(vcs, VINO_DATA_NORM_PAL, 3005 ret = vino_set_data_norm(vcs, VINO_DATA_NORM_PAL,
3136 &flags); 3006 &flags);
3137 } else if ((*std) & V4L2_STD_NTSC) { 3007 } else if ((*std) & V4L2_STD_NTSC) {
@@ -3797,56 +3667,38 @@ static int vino_g_ctrl(struct file *file, void *__fh,
3797 3667
3798 switch (vcs->input) { 3668 switch (vcs->input) {
3799 case VINO_INPUT_D1: { 3669 case VINO_INPUT_D1: {
3800 struct indycam_control indycam_ctrl; 3670 err = -EINVAL;
3801
3802 for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) { 3671 for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) {
3803 if (vino_indycam_v4l2_controls[i].id == 3672 if (vino_indycam_v4l2_controls[i].id == control->id) {
3804 control->id) { 3673 err = 0;
3805 goto found1; 3674 break;
3806 } 3675 }
3807 } 3676 }
3808 3677
3809 err = -EINVAL; 3678 if (err)
3810 goto out;
3811
3812found1:
3813 indycam_ctrl.type = vino_indycam_v4l2_controls[i].reserved[0];
3814
3815 err = i2c_camera_command(DECODER_INDYCAM_GET_CONTROL,
3816 &indycam_ctrl);
3817 if (err) {
3818 err = -EINVAL;
3819 goto out; 3679 goto out;
3820 }
3821 3680
3822 control->value = indycam_ctrl.value; 3681 err = i2c_camera_command(VIDIOC_G_CTRL, &control);
3682 if (err)
3683 err = -EINVAL;
3823 break; 3684 break;
3824 } 3685 }
3825 case VINO_INPUT_COMPOSITE: 3686 case VINO_INPUT_COMPOSITE:
3826 case VINO_INPUT_SVIDEO: { 3687 case VINO_INPUT_SVIDEO: {
3827 struct saa7191_control saa7191_ctrl; 3688 err = -EINVAL;
3828
3829 for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) { 3689 for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) {
3830 if (vino_saa7191_v4l2_controls[i].id == 3690 if (vino_saa7191_v4l2_controls[i].id == control->id) {
3831 control->id) { 3691 err = 0;
3832 goto found2; 3692 break;
3833 } 3693 }
3834 } 3694 }
3835 3695
3836 err = -EINVAL; 3696 if (err)
3837 goto out;
3838
3839found2:
3840 saa7191_ctrl.type = vino_saa7191_v4l2_controls[i].reserved[0];
3841
3842 err = i2c_decoder_command(DECODER_SAA7191_GET_CONTROL,
3843 &saa7191_ctrl);
3844 if (err) {
3845 err = -EINVAL;
3846 goto out; 3697 goto out;
3847 }
3848 3698
3849 control->value = saa7191_ctrl.value; 3699 err = i2c_decoder_command(VIDIOC_G_CTRL, &control);
3700 if (err)
3701 err = -EINVAL;
3850 break; 3702 break;
3851 } 3703 }
3852 default: 3704 default:
@@ -3876,65 +3728,43 @@ static int vino_s_ctrl(struct file *file, void *__fh,
3876 3728
3877 switch (vcs->input) { 3729 switch (vcs->input) {
3878 case VINO_INPUT_D1: { 3730 case VINO_INPUT_D1: {
3879 struct indycam_control indycam_ctrl; 3731 err = -EINVAL;
3880
3881 for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) { 3732 for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) {
3882 if (vino_indycam_v4l2_controls[i].id == 3733 if (vino_indycam_v4l2_controls[i].id == control->id) {
3883 control->id) { 3734 err = 0;
3884 if ((control->value >= 3735 break;
3885 vino_indycam_v4l2_controls[i].minimum)
3886 && (control->value <=
3887 vino_indycam_v4l2_controls[i].
3888 maximum)) {
3889 goto found1;
3890 } else {
3891 err = -ERANGE;
3892 goto out;
3893 }
3894 } 3736 }
3895 } 3737 }
3896 3738 if (err)
3897 err = -EINVAL; 3739 goto out;
3898 goto out; 3740 if (control->value < vino_indycam_v4l2_controls[i].minimum ||
3899 3741 control->value > vino_indycam_v4l2_controls[i].maximum) {
3900found1: 3742 err = -ERANGE;
3901 indycam_ctrl.type = vino_indycam_v4l2_controls[i].reserved[0]; 3743 goto out;
3902 indycam_ctrl.value = control->value; 3744 }
3903 3745 err = i2c_camera_command(VIDIOC_S_CTRL, &control);
3904 err = i2c_camera_command(DECODER_INDYCAM_SET_CONTROL,
3905 &indycam_ctrl);
3906 if (err) 3746 if (err)
3907 err = -EINVAL; 3747 err = -EINVAL;
3908 break; 3748 break;
3909 } 3749 }
3910 case VINO_INPUT_COMPOSITE: 3750 case VINO_INPUT_COMPOSITE:
3911 case VINO_INPUT_SVIDEO: { 3751 case VINO_INPUT_SVIDEO: {
3912 struct saa7191_control saa7191_ctrl; 3752 err = -EINVAL;
3913
3914 for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) { 3753 for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) {
3915 if (vino_saa7191_v4l2_controls[i].id == 3754 if (vino_saa7191_v4l2_controls[i].id == control->id) {
3916 control->id) { 3755 err = 0;
3917 if ((control->value >= 3756 break;
3918 vino_saa7191_v4l2_controls[i].minimum)
3919 && (control->value <=
3920 vino_saa7191_v4l2_controls[i].
3921 maximum)) {
3922 goto found2;
3923 } else {
3924 err = -ERANGE;
3925 goto out;
3926 }
3927 } 3757 }
3928 } 3758 }
3929 err = -EINVAL; 3759 if (err)
3930 goto out; 3760 goto out;
3931 3761 if (control->value < vino_saa7191_v4l2_controls[i].minimum ||
3932found2: 3762 control->value > vino_saa7191_v4l2_controls[i].maximum) {
3933 saa7191_ctrl.type = vino_saa7191_v4l2_controls[i].reserved[0]; 3763 err = -ERANGE;
3934 saa7191_ctrl.value = control->value; 3764 goto out;
3765 }
3935 3766
3936 err = i2c_decoder_command(DECODER_SAA7191_SET_CONTROL, 3767 err = i2c_decoder_command(VIDIOC_S_CTRL, &control);
3937 &saa7191_ctrl);
3938 if (err) 3768 if (err)
3939 err = -EINVAL; 3769 err = -EINVAL;
3940 break; 3770 break;