diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2009-02-18 15:26:06 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-03-30 11:42:57 -0400 |
commit | 107063c6156a0cbf055e771baafc28a3e3c0fb9b (patch) | |
tree | 813a2dc2c1426521167f2f289d7a106aaf2f24ec /drivers/media/video/vpx3220.c | |
parent | 84c1b09495ea366276726b0df2dcd7898cda9d0f (diff) |
V4L/DVB (10714): zoran et al: convert zoran i2c modules to V4L2.
The zoran i2c modules were still using V4L1 internally. Replace this
with V4L2. Also deleted saa7111.c and saa7114.c, we use saa7115.c instead.
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
[mchehab@redhat.com: fix v4l2_ctrl_query_fill_std merge conflict]
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/vpx3220.c')
-rw-r--r-- | drivers/media/video/vpx3220.c | 232 |
1 files changed, 115 insertions, 117 deletions
diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c index 67aa0db4b81a..cd2064e7733b 100644 --- a/drivers/media/video/vpx3220.c +++ b/drivers/media/video/vpx3220.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <media/v4l2-common.h> | 27 | #include <media/v4l2-common.h> |
28 | #include <media/v4l2-i2c-drv-legacy.h> | 28 | #include <media/v4l2-i2c-drv-legacy.h> |
29 | #include <linux/videodev.h> | 29 | #include <linux/videodev.h> |
30 | #include <linux/videodev2.h> | ||
30 | #include <linux/video_decoder.h> | 31 | #include <linux/video_decoder.h> |
31 | 32 | ||
32 | MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video decoder driver"); | 33 | MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video decoder driver"); |
@@ -44,7 +45,7 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); | |||
44 | struct vpx3220 { | 45 | struct vpx3220 { |
45 | unsigned char reg[255]; | 46 | unsigned char reg[255]; |
46 | 47 | ||
47 | int norm; | 48 | v4l2_std_id norm; |
48 | int input; | 49 | int input; |
49 | int enable; | 50 | int enable; |
50 | int bright; | 51 | int bright; |
@@ -259,79 +260,41 @@ static const unsigned short init_fp[] = { | |||
259 | 0x4b, 0x298, /* PLL gain */ | 260 | 0x4b, 0x298, /* PLL gain */ |
260 | }; | 261 | }; |
261 | 262 | ||
262 | static void vpx3220_dump_i2c(struct i2c_client *client) | ||
263 | { | ||
264 | int len = sizeof(init_common); | ||
265 | const unsigned char *data = init_common; | ||
266 | |||
267 | while (len > 1) { | ||
268 | v4l_dbg(1, debug, client, "i2c reg 0x%02x data 0x%02x\n", | ||
269 | *data, vpx3220_read(client, *data)); | ||
270 | data += 2; | ||
271 | len -= 2; | ||
272 | } | ||
273 | } | ||
274 | 263 | ||
275 | static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg) | 264 | static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg) |
276 | { | 265 | { |
277 | struct vpx3220 *decoder = i2c_get_clientdata(client); | 266 | struct vpx3220 *decoder = i2c_get_clientdata(client); |
278 | 267 | ||
279 | switch (cmd) { | 268 | switch (cmd) { |
280 | case 0: | 269 | case VIDIOC_INT_INIT: |
281 | { | 270 | { |
282 | vpx3220_write_block(client, init_common, | 271 | vpx3220_write_block(client, init_common, |
283 | sizeof(init_common)); | 272 | sizeof(init_common)); |
284 | vpx3220_write_fp_block(client, init_fp, | 273 | vpx3220_write_fp_block(client, init_fp, |
285 | sizeof(init_fp) >> 1); | 274 | sizeof(init_fp) >> 1); |
286 | switch (decoder->norm) { | 275 | if (decoder->norm & V4L2_STD_NTSC) { |
287 | case VIDEO_MODE_NTSC: | ||
288 | vpx3220_write_fp_block(client, init_ntsc, | 276 | vpx3220_write_fp_block(client, init_ntsc, |
289 | sizeof(init_ntsc) >> 1); | 277 | sizeof(init_ntsc) >> 1); |
290 | break; | 278 | } else if (decoder->norm & V4L2_STD_PAL) { |
291 | |||
292 | case VIDEO_MODE_PAL: | ||
293 | vpx3220_write_fp_block(client, init_pal, | 279 | vpx3220_write_fp_block(client, init_pal, |
294 | sizeof(init_pal) >> 1); | 280 | sizeof(init_pal) >> 1); |
295 | break; | 281 | } else if (decoder->norm & V4L2_STD_SECAM) { |
296 | case VIDEO_MODE_SECAM: | ||
297 | vpx3220_write_fp_block(client, init_secam, | 282 | vpx3220_write_fp_block(client, init_secam, |
298 | sizeof(init_secam) >> 1); | 283 | sizeof(init_secam) >> 1); |
299 | break; | 284 | } else { |
300 | default: | ||
301 | vpx3220_write_fp_block(client, init_pal, | 285 | vpx3220_write_fp_block(client, init_pal, |
302 | sizeof(init_pal) >> 1); | 286 | sizeof(init_pal) >> 1); |
303 | break; | ||
304 | } | 287 | } |
305 | break; | 288 | break; |
306 | } | 289 | } |
307 | 290 | ||
308 | case DECODER_DUMP: | 291 | case VIDIOC_QUERYSTD: |
309 | { | 292 | case VIDIOC_INT_G_INPUT_STATUS: |
310 | vpx3220_dump_i2c(client); | ||
311 | break; | ||
312 | } | ||
313 | |||
314 | case DECODER_GET_CAPABILITIES: | ||
315 | { | ||
316 | struct video_decoder_capability *cap = arg; | ||
317 | |||
318 | v4l_dbg(1, debug, client, "DECODER_GET_CAPABILITIES\n"); | ||
319 | |||
320 | cap->flags = VIDEO_DECODER_PAL | | ||
321 | VIDEO_DECODER_NTSC | | ||
322 | VIDEO_DECODER_SECAM | | ||
323 | VIDEO_DECODER_AUTO | | ||
324 | VIDEO_DECODER_CCIR; | ||
325 | cap->inputs = 3; | ||
326 | cap->outputs = 1; | ||
327 | break; | ||
328 | } | ||
329 | |||
330 | case DECODER_GET_STATUS: | ||
331 | { | 293 | { |
332 | int res = 0, status; | 294 | int res = V4L2_IN_ST_NO_SIGNAL, status; |
295 | v4l2_std_id std = 0; | ||
333 | 296 | ||
334 | v4l_dbg(1, debug, client, "DECODER_GET_STATUS\n"); | 297 | v4l_dbg(1, debug, client, "VIDIOC_QUERYSTD/VIDIOC_INT_G_INPUT_STATUS\n"); |
335 | 298 | ||
336 | status = vpx3220_fp_read(client, 0x0f3); | 299 | status = vpx3220_fp_read(client, 0x0f3); |
337 | 300 | ||
@@ -341,35 +304,38 @@ static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg) | |||
341 | return status; | 304 | return status; |
342 | 305 | ||
343 | if ((status & 0x20) == 0) { | 306 | if ((status & 0x20) == 0) { |
344 | res |= DECODER_STATUS_GOOD | DECODER_STATUS_COLOR; | 307 | res = 0; |
345 | 308 | ||
346 | switch (status & 0x18) { | 309 | switch (status & 0x18) { |
347 | case 0x00: | 310 | case 0x00: |
348 | case 0x10: | 311 | case 0x10: |
349 | case 0x14: | 312 | case 0x14: |
350 | case 0x18: | 313 | case 0x18: |
351 | res |= DECODER_STATUS_PAL; | 314 | std = V4L2_STD_PAL; |
352 | break; | 315 | break; |
353 | 316 | ||
354 | case 0x08: | 317 | case 0x08: |
355 | res |= DECODER_STATUS_SECAM; | 318 | std = V4L2_STD_SECAM; |
356 | break; | 319 | break; |
357 | 320 | ||
358 | case 0x04: | 321 | case 0x04: |
359 | case 0x0c: | 322 | case 0x0c: |
360 | case 0x1c: | 323 | case 0x1c: |
361 | res |= DECODER_STATUS_NTSC; | 324 | std = V4L2_STD_NTSC; |
362 | break; | 325 | break; |
363 | } | 326 | } |
364 | } | 327 | } |
365 | 328 | ||
366 | *(int *) arg = res; | 329 | if (cmd == VIDIOC_QUERYSTD) |
330 | *(v4l2_std_id *)arg = std; | ||
331 | else | ||
332 | *(int *)arg = res; | ||
367 | break; | 333 | break; |
368 | } | 334 | } |
369 | 335 | ||
370 | case DECODER_SET_NORM: | 336 | case VIDIOC_S_STD: |
371 | { | 337 | { |
372 | int *iarg = arg, data; | 338 | v4l2_std_id *iarg = arg; |
373 | int temp_input; | 339 | int temp_input; |
374 | 340 | ||
375 | /* Here we back up the input selection because it gets | 341 | /* Here we back up the input selection because it gets |
@@ -377,36 +343,23 @@ static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg) | |||
377 | choosen video norm */ | 343 | choosen video norm */ |
378 | temp_input = vpx3220_fp_read(client, 0xf2); | 344 | temp_input = vpx3220_fp_read(client, 0xf2); |
379 | 345 | ||
380 | v4l_dbg(1, debug, client, "DECODER_SET_NORM %d\n", *iarg); | 346 | v4l_dbg(1, debug, client, "VIDIOC_S_STD %llx\n", *iarg); |
381 | switch (*iarg) { | 347 | if (*iarg & V4L2_STD_NTSC) { |
382 | case VIDEO_MODE_NTSC: | ||
383 | vpx3220_write_fp_block(client, init_ntsc, | 348 | vpx3220_write_fp_block(client, init_ntsc, |
384 | sizeof(init_ntsc) >> 1); | 349 | sizeof(init_ntsc) >> 1); |
385 | v4l_dbg(1, debug, client, "norm switched to NTSC\n"); | 350 | v4l_dbg(1, debug, client, "norm switched to NTSC\n"); |
386 | break; | 351 | } else if (*iarg & V4L2_STD_PAL) { |
387 | |||
388 | case VIDEO_MODE_PAL: | ||
389 | vpx3220_write_fp_block(client, init_pal, | 352 | vpx3220_write_fp_block(client, init_pal, |
390 | sizeof(init_pal) >> 1); | 353 | sizeof(init_pal) >> 1); |
391 | v4l_dbg(1, debug, client, "norm switched to PAL\n"); | 354 | v4l_dbg(1, debug, client, "norm switched to PAL\n"); |
392 | break; | 355 | } else if (*iarg & V4L2_STD_SECAM) { |
393 | |||
394 | case VIDEO_MODE_SECAM: | ||
395 | vpx3220_write_fp_block(client, init_secam, | 356 | vpx3220_write_fp_block(client, init_secam, |
396 | sizeof(init_secam) >> 1); | 357 | sizeof(init_secam) >> 1); |
397 | v4l_dbg(1, debug, client, "norm switched to SECAM\n"); | 358 | v4l_dbg(1, debug, client, "norm switched to SECAM\n"); |
398 | break; | 359 | } else { |
399 | |||
400 | case VIDEO_MODE_AUTO: | ||
401 | /* FIXME This is only preliminary support */ | ||
402 | data = vpx3220_fp_read(client, 0xf2) & 0x20; | ||
403 | vpx3220_fp_write(client, 0xf2, 0x00c0 | data); | ||
404 | v4l_dbg(1, debug, client, "norm switched to AUTO\n"); | ||
405 | break; | ||
406 | |||
407 | default: | ||
408 | return -EINVAL; | 360 | return -EINVAL; |
409 | } | 361 | } |
362 | |||
410 | decoder->norm = *iarg; | 363 | decoder->norm = *iarg; |
411 | 364 | ||
412 | /* And here we set the backed up video input again */ | 365 | /* And here we set the backed up video input again */ |
@@ -415,9 +368,10 @@ static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg) | |||
415 | break; | 368 | break; |
416 | } | 369 | } |
417 | 370 | ||
418 | case DECODER_SET_INPUT: | 371 | case VIDIOC_INT_S_VIDEO_ROUTING: |
419 | { | 372 | { |
420 | int *iarg = arg, data; | 373 | struct v4l2_routing *route = arg; |
374 | int data; | ||
421 | 375 | ||
422 | /* RJ: *iarg = 0: ST8 (PCTV) input | 376 | /* RJ: *iarg = 0: ST8 (PCTV) input |
423 | *iarg = 1: COMPOSITE input | 377 | *iarg = 1: COMPOSITE input |
@@ -429,73 +383,117 @@ static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg) | |||
429 | {0x0e, 1} | 383 | {0x0e, 1} |
430 | }; | 384 | }; |
431 | 385 | ||
432 | if (*iarg < 0 || *iarg > 2) | 386 | if (route->input < 0 || route->input > 2) |
433 | return -EINVAL; | 387 | return -EINVAL; |
434 | 388 | ||
435 | v4l_dbg(1, debug, client, "input switched to %s\n", inputs[*iarg]); | 389 | v4l_dbg(1, debug, client, "input switched to %s\n", inputs[route->input]); |
436 | 390 | ||
437 | vpx3220_write(client, 0x33, input[*iarg][0]); | 391 | vpx3220_write(client, 0x33, input[route->input][0]); |
438 | 392 | ||
439 | data = vpx3220_fp_read(client, 0xf2) & ~(0x0020); | 393 | data = vpx3220_fp_read(client, 0xf2) & ~(0x0020); |
440 | if (data < 0) | 394 | if (data < 0) |
441 | return data; | 395 | return data; |
442 | /* 0x0010 is required to latch the setting */ | 396 | /* 0x0010 is required to latch the setting */ |
443 | vpx3220_fp_write(client, 0xf2, | 397 | vpx3220_fp_write(client, 0xf2, |
444 | data | (input[*iarg][1] << 5) | 0x0010); | 398 | data | (input[route->input][1] << 5) | 0x0010); |
445 | 399 | ||
446 | udelay(10); | 400 | udelay(10); |
447 | break; | 401 | break; |
448 | } | 402 | } |
449 | 403 | ||
450 | case DECODER_SET_OUTPUT: | 404 | case VIDIOC_STREAMON: |
405 | case VIDIOC_STREAMOFF: | ||
451 | { | 406 | { |
452 | int *iarg = arg; | 407 | int on = cmd == VIDIOC_STREAMON; |
408 | v4l_dbg(1, debug, client, "VIDIOC_STREAM%s\n", on ? "ON" : "OFF"); | ||
453 | 409 | ||
454 | /* not much choice of outputs */ | 410 | vpx3220_write(client, 0xf2, (on ? 0x1b : 0x00)); |
455 | if (*iarg != 0) { | ||
456 | return -EINVAL; | ||
457 | } | ||
458 | break; | 411 | break; |
459 | } | 412 | } |
460 | 413 | ||
461 | case DECODER_ENABLE_OUTPUT: | 414 | case VIDIOC_QUERYCTRL: |
462 | { | 415 | { |
463 | int *iarg = arg; | 416 | struct v4l2_queryctrl *qc = arg; |
464 | 417 | ||
465 | v4l_dbg(1, debug, client, "DECODER_ENABLE_OUTPUT %d\n", *iarg); | 418 | switch (qc->id) { |
419 | case V4L2_CID_BRIGHTNESS: | ||
420 | v4l2_ctrl_query_fill(qc, -128, 127, 1, 0); | ||
421 | break; | ||
422 | |||
423 | case V4L2_CID_CONTRAST: | ||
424 | v4l2_ctrl_query_fill(qc, 0, 63, 1, 32); | ||
425 | break; | ||
426 | |||
427 | case V4L2_CID_SATURATION: | ||
428 | v4l2_ctrl_query_fill(qc, 0, 4095, 1, 2048); | ||
429 | break; | ||
466 | 430 | ||
467 | vpx3220_write(client, 0xf2, (*iarg ? 0x1b : 0x00)); | 431 | case V4L2_CID_HUE: |
432 | v4l2_ctrl_query_fill(qc, -512, 511, 1, 0); | ||
433 | break; | ||
434 | |||
435 | default: | ||
436 | return -EINVAL; | ||
437 | } | ||
468 | break; | 438 | break; |
469 | } | 439 | } |
470 | 440 | ||
471 | case DECODER_SET_PICTURE: | 441 | case VIDIOC_G_CTRL: |
472 | { | 442 | { |
473 | struct video_picture *pic = arg; | 443 | struct v4l2_control *ctrl = arg; |
474 | 444 | ||
475 | if (decoder->bright != pic->brightness) { | 445 | switch (ctrl->id) { |
476 | /* We want -128 to 128 we get 0-65535 */ | 446 | case V4L2_CID_BRIGHTNESS: |
477 | decoder->bright = pic->brightness; | 447 | ctrl->value = decoder->bright; |
478 | vpx3220_write(client, 0xe6, | 448 | break; |
479 | (decoder->bright - 32768) >> 8); | 449 | case V4L2_CID_CONTRAST: |
480 | } | 450 | ctrl->value = decoder->contrast; |
481 | if (decoder->contrast != pic->contrast) { | 451 | break; |
482 | /* We want 0 to 64 we get 0-65535 */ | 452 | case V4L2_CID_SATURATION: |
483 | /* Bit 7 and 8 is for noise shaping */ | 453 | ctrl->value = decoder->sat; |
484 | decoder->contrast = pic->contrast; | 454 | break; |
485 | vpx3220_write(client, 0xe7, | 455 | case V4L2_CID_HUE: |
486 | (decoder->contrast >> 10) + 192); | 456 | ctrl->value = decoder->hue; |
487 | } | 457 | break; |
488 | if (decoder->sat != pic->colour) { | 458 | default: |
489 | /* We want 0 to 4096 we get 0-65535 */ | 459 | return -EINVAL; |
490 | decoder->sat = pic->colour; | ||
491 | vpx3220_fp_write(client, 0xa0, | ||
492 | decoder->sat >> 4); | ||
493 | } | 460 | } |
494 | if (decoder->hue != pic->hue) { | 461 | break; |
495 | /* We want -512 to 512 we get 0-65535 */ | 462 | } |
496 | decoder->hue = pic->hue; | 463 | |
497 | vpx3220_fp_write(client, 0x1c, | 464 | case VIDIOC_S_CTRL: |
498 | ((decoder->hue - 32768) >> 6) & 0xFFF); | 465 | { |
466 | struct v4l2_control *ctrl = arg; | ||
467 | |||
468 | switch (ctrl->id) { | ||
469 | case V4L2_CID_BRIGHTNESS: | ||
470 | if (decoder->bright != ctrl->value) { | ||
471 | decoder->bright = ctrl->value; | ||
472 | vpx3220_write(client, 0xe6, decoder->bright); | ||
473 | } | ||
474 | break; | ||
475 | case V4L2_CID_CONTRAST: | ||
476 | if (decoder->contrast != ctrl->value) { | ||
477 | /* Bit 7 and 8 is for noise shaping */ | ||
478 | decoder->contrast = ctrl->value; | ||
479 | vpx3220_write(client, 0xe7, | ||
480 | decoder->contrast + 192); | ||
481 | } | ||
482 | break; | ||
483 | case V4L2_CID_SATURATION: | ||
484 | if (decoder->sat != ctrl->value) { | ||
485 | decoder->sat = ctrl->value; | ||
486 | vpx3220_fp_write(client, 0xa0, decoder->sat); | ||
487 | } | ||
488 | break; | ||
489 | case V4L2_CID_HUE: | ||
490 | if (decoder->hue != ctrl->value) { | ||
491 | decoder->hue = ctrl->value; | ||
492 | vpx3220_fp_write(client, 0x1c, decoder->hue); | ||
493 | } | ||
494 | break; | ||
495 | default: | ||
496 | return -EINVAL; | ||
499 | } | 497 | } |
500 | break; | 498 | break; |
501 | } | 499 | } |
@@ -541,7 +539,7 @@ static int vpx3220_probe(struct i2c_client *client, | |||
541 | decoder = kzalloc(sizeof(struct vpx3220), GFP_KERNEL); | 539 | decoder = kzalloc(sizeof(struct vpx3220), GFP_KERNEL); |
542 | if (decoder == NULL) | 540 | if (decoder == NULL) |
543 | return -ENOMEM; | 541 | return -ENOMEM; |
544 | decoder->norm = VIDEO_MODE_PAL; | 542 | decoder->norm = V4L2_STD_PAL; |
545 | decoder->input = 0; | 543 | decoder->input = 0; |
546 | decoder->enable = 1; | 544 | decoder->enable = 1; |
547 | decoder->bright = 32768; | 545 | decoder->bright = 32768; |