aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/saa7134/saa6752hs.c
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2009-01-14 04:54:38 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 11:42:22 -0400
commit5b73e98c83fc5087f591c9b12ee546b97e9283d4 (patch)
tree555244e0ac94e8428f7fa58154df59dcc3f0aad4 /drivers/media/video/saa7134/saa6752hs.c
parentb634a93f783dbd4be31f3cc9b2292eddfb496d10 (diff)
V4L/DVB (10246): saa6752hs: convert to v4l2_subdev.
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/saa7134/saa6752hs.c')
-rw-r--r--drivers/media/video/saa7134/saa6752hs.c566
1 files changed, 333 insertions, 233 deletions
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c
index 1fee6e84a512..25e6ab28a0a3 100644
--- a/drivers/media/video/saa7134/saa6752hs.c
+++ b/drivers/media/video/saa7134/saa6752hs.c
@@ -33,6 +33,7 @@
33#include <linux/i2c.h> 33#include <linux/i2c.h>
34#include <linux/types.h> 34#include <linux/types.h>
35#include <linux/videodev2.h> 35#include <linux/videodev2.h>
36#include <media/v4l2-device.h>
36#include <media/v4l2-common.h> 37#include <media/v4l2-common.h>
37#include <media/v4l2-chip-ident.h> 38#include <media/v4l2-chip-ident.h>
38#include <media/v4l2-i2c-drv-legacy.h> 39#include <media/v4l2-i2c-drv-legacy.h>
@@ -95,6 +96,7 @@ static const struct v4l2_format v4l2_format_table[] =
95}; 96};
96 97
97struct saa6752hs_state { 98struct saa6752hs_state {
99 struct v4l2_subdev sd;
98 int chip; 100 int chip;
99 u32 revision; 101 u32 revision;
100 int has_ac3; 102 int has_ac3;
@@ -115,6 +117,11 @@ enum saa6752hs_command {
115 SAA6752HS_COMMAND_MAX 117 SAA6752HS_COMMAND_MAX
116}; 118};
117 119
120static inline struct saa6752hs_state *to_state(struct v4l2_subdev *sd)
121{
122 return container_of(sd, struct saa6752hs_state, sd);
123}
124
118/* ---------------------------------------------------------------------- */ 125/* ---------------------------------------------------------------------- */
119 126
120static u8 PAT[] = { 127static u8 PAT[] = {
@@ -360,185 +367,191 @@ static int saa6752hs_set_bitrate(struct i2c_client *client,
360 return 0; 367 return 0;
361} 368}
362 369
363static void saa6752hs_set_subsampling(struct i2c_client *client,
364 struct v4l2_format *f)
365{
366 struct saa6752hs_state *h = i2c_get_clientdata(client);
367 int dist_352, dist_480, dist_720;
368
369 /*
370 FIXME: translate and round width/height into EMPRESS
371 subsample type:
372 370
373 type | PAL | NTSC 371static int get_ctrl(int has_ac3, struct saa6752hs_mpeg_params *params,
374 --------------------------- 372 struct v4l2_ext_control *ctrl)
375 SIF | 352x288 | 352x240 373{
376 1/2 D1 | 352x576 | 352x480 374 switch (ctrl->id) {
377 2/3 D1 | 480x576 | 480x480 375 case V4L2_CID_MPEG_STREAM_TYPE:
378 D1 | 720x576 | 720x480 376 ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
379 */ 377 break;
380 378 case V4L2_CID_MPEG_STREAM_PID_PMT:
381 dist_352 = abs(f->fmt.pix.width - 352); 379 ctrl->value = params->ts_pid_pmt;
382 dist_480 = abs(f->fmt.pix.width - 480); 380 break;
383 dist_720 = abs(f->fmt.pix.width - 720); 381 case V4L2_CID_MPEG_STREAM_PID_AUDIO:
384 if (dist_720 < dist_480) { 382 ctrl->value = params->ts_pid_audio;
385 f->fmt.pix.width = 720; 383 break;
386 f->fmt.pix.height = 576; 384 case V4L2_CID_MPEG_STREAM_PID_VIDEO:
387 h->video_format = SAA6752HS_VF_D1; 385 ctrl->value = params->ts_pid_video;
388 } 386 break;
389 else if (dist_480 < dist_352) { 387 case V4L2_CID_MPEG_STREAM_PID_PCR:
390 f->fmt.pix.width = 480; 388 ctrl->value = params->ts_pid_pcr;
391 f->fmt.pix.height = 576; 389 break;
392 h->video_format = SAA6752HS_VF_2_3_D1; 390 case V4L2_CID_MPEG_AUDIO_ENCODING:
393 } 391 ctrl->value = params->au_encoding;
394 else { 392 break;
395 f->fmt.pix.width = 352; 393 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
396 if (abs(f->fmt.pix.height - 576) < 394 ctrl->value = params->au_l2_bitrate;
397 abs(f->fmt.pix.height - 288)) { 395 break;
398 f->fmt.pix.height = 576; 396 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
399 h->video_format = SAA6752HS_VF_1_2_D1; 397 if (!has_ac3)
400 } 398 return -EINVAL;
401 else { 399 ctrl->value = params->au_ac3_bitrate;
402 f->fmt.pix.height = 288; 400 break;
403 h->video_format = SAA6752HS_VF_SIF; 401 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
404 } 402 ctrl->value = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
403 break;
404 case V4L2_CID_MPEG_VIDEO_ENCODING:
405 ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
406 break;
407 case V4L2_CID_MPEG_VIDEO_ASPECT:
408 ctrl->value = params->vi_aspect;
409 break;
410 case V4L2_CID_MPEG_VIDEO_BITRATE:
411 ctrl->value = params->vi_bitrate * 1000;
412 break;
413 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
414 ctrl->value = params->vi_bitrate_peak * 1000;
415 break;
416 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
417 ctrl->value = params->vi_bitrate_mode;
418 break;
419 default:
420 return -EINVAL;
405 } 421 }
422 return 0;
406} 423}
407 424
408
409static int handle_ctrl(int has_ac3, struct saa6752hs_mpeg_params *params, 425static int handle_ctrl(int has_ac3, struct saa6752hs_mpeg_params *params,
410 struct v4l2_ext_control *ctrl, unsigned int cmd) 426 struct v4l2_ext_control *ctrl, int set)
411{ 427{
412 int old = 0, new; 428 int old = 0, new;
413 int set = (cmd == VIDIOC_S_EXT_CTRLS);
414 429
415 new = ctrl->value; 430 new = ctrl->value;
416 switch (ctrl->id) { 431 switch (ctrl->id) {
417 case V4L2_CID_MPEG_STREAM_TYPE: 432 case V4L2_CID_MPEG_STREAM_TYPE:
418 old = V4L2_MPEG_STREAM_TYPE_MPEG2_TS; 433 old = V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
419 if (set && new != old) 434 if (set && new != old)
420 return -ERANGE; 435 return -ERANGE;
421 new = old; 436 new = old;
422 break; 437 break;
423 case V4L2_CID_MPEG_STREAM_PID_PMT: 438 case V4L2_CID_MPEG_STREAM_PID_PMT:
424 old = params->ts_pid_pmt; 439 old = params->ts_pid_pmt;
425 if (set && new > MPEG_PID_MAX) 440 if (set && new > MPEG_PID_MAX)
426 return -ERANGE; 441 return -ERANGE;
427 if (new > MPEG_PID_MAX) 442 if (new > MPEG_PID_MAX)
428 new = MPEG_PID_MAX; 443 new = MPEG_PID_MAX;
429 params->ts_pid_pmt = new; 444 params->ts_pid_pmt = new;
430 break; 445 break;
431 case V4L2_CID_MPEG_STREAM_PID_AUDIO: 446 case V4L2_CID_MPEG_STREAM_PID_AUDIO:
432 old = params->ts_pid_audio; 447 old = params->ts_pid_audio;
433 if (set && new > MPEG_PID_MAX) 448 if (set && new > MPEG_PID_MAX)
434 return -ERANGE; 449 return -ERANGE;
435 if (new > MPEG_PID_MAX) 450 if (new > MPEG_PID_MAX)
436 new = MPEG_PID_MAX; 451 new = MPEG_PID_MAX;
437 params->ts_pid_audio = new; 452 params->ts_pid_audio = new;
438 break; 453 break;
439 case V4L2_CID_MPEG_STREAM_PID_VIDEO: 454 case V4L2_CID_MPEG_STREAM_PID_VIDEO:
440 old = params->ts_pid_video; 455 old = params->ts_pid_video;
441 if (set && new > MPEG_PID_MAX) 456 if (set && new > MPEG_PID_MAX)
442 return -ERANGE; 457 return -ERANGE;
443 if (new > MPEG_PID_MAX) 458 if (new > MPEG_PID_MAX)
444 new = MPEG_PID_MAX; 459 new = MPEG_PID_MAX;
445 params->ts_pid_video = new; 460 params->ts_pid_video = new;
446 break; 461 break;
447 case V4L2_CID_MPEG_STREAM_PID_PCR: 462 case V4L2_CID_MPEG_STREAM_PID_PCR:
448 old = params->ts_pid_pcr; 463 old = params->ts_pid_pcr;
449 if (set && new > MPEG_PID_MAX) 464 if (set && new > MPEG_PID_MAX)
450 return -ERANGE; 465 return -ERANGE;
451 if (new > MPEG_PID_MAX) 466 if (new > MPEG_PID_MAX)
452 new = MPEG_PID_MAX; 467 new = MPEG_PID_MAX;
453 params->ts_pid_pcr = new; 468 params->ts_pid_pcr = new;
454 break; 469 break;
455 case V4L2_CID_MPEG_AUDIO_ENCODING: 470 case V4L2_CID_MPEG_AUDIO_ENCODING:
456 old = params->au_encoding; 471 old = params->au_encoding;
457 if (set && new != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 && 472 if (set && new != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 &&
458 (!has_ac3 || new != V4L2_MPEG_AUDIO_ENCODING_AC3)) 473 (!has_ac3 || new != V4L2_MPEG_AUDIO_ENCODING_AC3))
459 return -ERANGE; 474 return -ERANGE;
460 new = old; 475 new = old;
461 break; 476 break;
462 case V4L2_CID_MPEG_AUDIO_L2_BITRATE: 477 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
463 old = params->au_l2_bitrate; 478 old = params->au_l2_bitrate;
464 if (set && new != V4L2_MPEG_AUDIO_L2_BITRATE_256K && 479 if (set && new != V4L2_MPEG_AUDIO_L2_BITRATE_256K &&
465 new != V4L2_MPEG_AUDIO_L2_BITRATE_384K) 480 new != V4L2_MPEG_AUDIO_L2_BITRATE_384K)
466 return -ERANGE; 481 return -ERANGE;
467 if (new <= V4L2_MPEG_AUDIO_L2_BITRATE_256K) 482 if (new <= V4L2_MPEG_AUDIO_L2_BITRATE_256K)
468 new = V4L2_MPEG_AUDIO_L2_BITRATE_256K; 483 new = V4L2_MPEG_AUDIO_L2_BITRATE_256K;
469 else 484 else
470 new = V4L2_MPEG_AUDIO_L2_BITRATE_384K; 485 new = V4L2_MPEG_AUDIO_L2_BITRATE_384K;
471 params->au_l2_bitrate = new; 486 params->au_l2_bitrate = new;
472 break; 487 break;
473 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: 488 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
474 if (!has_ac3) 489 if (!has_ac3)
475 return -EINVAL;
476 old = params->au_ac3_bitrate;
477 if (set && new != V4L2_MPEG_AUDIO_AC3_BITRATE_256K &&
478 new != V4L2_MPEG_AUDIO_AC3_BITRATE_384K)
479 return -ERANGE;
480 if (new <= V4L2_MPEG_AUDIO_AC3_BITRATE_256K)
481 new = V4L2_MPEG_AUDIO_AC3_BITRATE_256K;
482 else
483 new = V4L2_MPEG_AUDIO_AC3_BITRATE_384K;
484 params->au_ac3_bitrate = new;
485 break;
486 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
487 old = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
488 if (set && new != old)
489 return -ERANGE;
490 new = old;
491 break;
492 case V4L2_CID_MPEG_VIDEO_ENCODING:
493 old = V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
494 if (set && new != old)
495 return -ERANGE;
496 new = old;
497 break;
498 case V4L2_CID_MPEG_VIDEO_ASPECT:
499 old = params->vi_aspect;
500 if (set && new != V4L2_MPEG_VIDEO_ASPECT_16x9 &&
501 new != V4L2_MPEG_VIDEO_ASPECT_4x3)
502 return -ERANGE;
503 if (new != V4L2_MPEG_VIDEO_ASPECT_16x9)
504 new = V4L2_MPEG_VIDEO_ASPECT_4x3;
505 params->vi_aspect = new;
506 break;
507 case V4L2_CID_MPEG_VIDEO_BITRATE:
508 old = params->vi_bitrate * 1000;
509 new = 1000 * (new / 1000);
510 if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
511 return -ERANGE;
512 if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
513 new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000;
514 params->vi_bitrate = new / 1000;
515 break;
516 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
517 old = params->vi_bitrate_peak * 1000;
518 new = 1000 * (new / 1000);
519 if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
520 return -ERANGE;
521 if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
522 new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000;
523 params->vi_bitrate_peak = new / 1000;
524 break;
525 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
526 old = params->vi_bitrate_mode;
527 params->vi_bitrate_mode = new;
528 break;
529 default:
530 return -EINVAL; 490 return -EINVAL;
491 old = params->au_ac3_bitrate;
492 if (set && new != V4L2_MPEG_AUDIO_AC3_BITRATE_256K &&
493 new != V4L2_MPEG_AUDIO_AC3_BITRATE_384K)
494 return -ERANGE;
495 if (new <= V4L2_MPEG_AUDIO_AC3_BITRATE_256K)
496 new = V4L2_MPEG_AUDIO_AC3_BITRATE_256K;
497 else
498 new = V4L2_MPEG_AUDIO_AC3_BITRATE_384K;
499 params->au_ac3_bitrate = new;
500 break;
501 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
502 old = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
503 if (set && new != old)
504 return -ERANGE;
505 new = old;
506 break;
507 case V4L2_CID_MPEG_VIDEO_ENCODING:
508 old = V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
509 if (set && new != old)
510 return -ERANGE;
511 new = old;
512 break;
513 case V4L2_CID_MPEG_VIDEO_ASPECT:
514 old = params->vi_aspect;
515 if (set && new != V4L2_MPEG_VIDEO_ASPECT_16x9 &&
516 new != V4L2_MPEG_VIDEO_ASPECT_4x3)
517 return -ERANGE;
518 if (new != V4L2_MPEG_VIDEO_ASPECT_16x9)
519 new = V4L2_MPEG_VIDEO_ASPECT_4x3;
520 params->vi_aspect = new;
521 break;
522 case V4L2_CID_MPEG_VIDEO_BITRATE:
523 old = params->vi_bitrate * 1000;
524 new = 1000 * (new / 1000);
525 if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
526 return -ERANGE;
527 if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
528 new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000;
529 params->vi_bitrate = new / 1000;
530 break;
531 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
532 old = params->vi_bitrate_peak * 1000;
533 new = 1000 * (new / 1000);
534 if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
535 return -ERANGE;
536 if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
537 new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000;
538 params->vi_bitrate_peak = new / 1000;
539 break;
540 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
541 old = params->vi_bitrate_mode;
542 params->vi_bitrate_mode = new;
543 break;
544 default:
545 return -EINVAL;
531 } 546 }
532 if (cmd == VIDIOC_G_EXT_CTRLS) 547 ctrl->value = new;
533 ctrl->value = old;
534 else
535 ctrl->value = new;
536 return 0; 548 return 0;
537} 549}
538 550
539static int saa6752hs_qctrl(struct saa6752hs_state *h, 551
540 struct v4l2_queryctrl *qctrl) 552static int saa6752hs_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl)
541{ 553{
554 struct saa6752hs_state *h = to_state(sd);
542 struct saa6752hs_mpeg_params *params = &h->params; 555 struct saa6752hs_mpeg_params *params = &h->params;
543 int err; 556 int err;
544 557
@@ -610,8 +623,7 @@ static int saa6752hs_qctrl(struct saa6752hs_state *h,
610 return -EINVAL; 623 return -EINVAL;
611} 624}
612 625
613static int saa6752hs_qmenu(struct saa6752hs_state *h, 626static int saa6752hs_querymenu(struct v4l2_subdev *sd, struct v4l2_querymenu *qmenu)
614 struct v4l2_querymenu *qmenu)
615{ 627{
616 static const u32 mpeg_audio_encoding[] = { 628 static const u32 mpeg_audio_encoding[] = {
617 V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 629 V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
@@ -632,11 +644,12 @@ static int saa6752hs_qmenu(struct saa6752hs_state *h,
632 V4L2_MPEG_AUDIO_AC3_BITRATE_384K, 644 V4L2_MPEG_AUDIO_AC3_BITRATE_384K,
633 V4L2_CTRL_MENU_IDS_END 645 V4L2_CTRL_MENU_IDS_END
634 }; 646 };
647 struct saa6752hs_state *h = to_state(sd);
635 struct v4l2_queryctrl qctrl; 648 struct v4l2_queryctrl qctrl;
636 int err; 649 int err;
637 650
638 qctrl.id = qmenu->id; 651 qctrl.id = qmenu->id;
639 err = saa6752hs_qctrl(h, &qctrl); 652 err = saa6752hs_queryctrl(sd, &qctrl);
640 if (err) 653 if (err)
641 return err; 654 return err;
642 switch (qmenu->id) { 655 switch (qmenu->id) {
@@ -656,17 +669,16 @@ static int saa6752hs_qmenu(struct saa6752hs_state *h,
656 return v4l2_ctrl_query_menu(qmenu, &qctrl, NULL); 669 return v4l2_ctrl_query_menu(qmenu, &qctrl, NULL);
657} 670}
658 671
659static int saa6752hs_init(struct i2c_client *client, u32 leading_null_bytes) 672static int saa6752hs_init(struct v4l2_subdev *sd, u32 leading_null_bytes)
660{ 673{
661 unsigned char buf[9], buf2[4]; 674 unsigned char buf[9], buf2[4];
662 struct saa6752hs_state *h; 675 struct saa6752hs_state *h = to_state(sd);
676 struct i2c_client *client = v4l2_get_subdevdata(sd);
663 unsigned size; 677 unsigned size;
664 u32 crc; 678 u32 crc;
665 unsigned char localPAT[256]; 679 unsigned char localPAT[256];
666 unsigned char localPMT[256]; 680 unsigned char localPMT[256];
667 681
668 h = i2c_get_clientdata(client);
669
670 /* Set video format - must be done first as it resets other settings */ 682 /* Set video format - must be done first as it resets other settings */
671 set_reg8(client, 0x41, h->video_format); 683 set_reg8(client, 0x41, h->video_format);
672 684
@@ -762,7 +774,7 @@ static int saa6752hs_init(struct i2c_client *client, u32 leading_null_bytes)
762 buf[3] = 0x82; 774 buf[3] = 0x82;
763 buf[4] = 0xB0; 775 buf[4] = 0xB0;
764 buf[5] = buf2[0]; 776 buf[5] = buf2[0];
765 switch(h->params.vi_aspect) { 777 switch (h->params.vi_aspect) {
766 case V4L2_MPEG_VIDEO_ASPECT_16x9: 778 case V4L2_MPEG_VIDEO_ASPECT_16x9:
767 buf[6] = buf2[1] | 0x40; 779 buf[6] = buf2[1] | 0x40;
768 break; 780 break;
@@ -770,7 +782,6 @@ static int saa6752hs_init(struct i2c_client *client, u32 leading_null_bytes)
770 default: 782 default:
771 buf[6] = buf2[1] & 0xBF; 783 buf[6] = buf2[1] & 0xBF;
772 break; 784 break;
773 break;
774 } 785 }
775 buf[7] = buf2[2]; 786 buf[7] = buf2[2];
776 buf[8] = buf2[3]; 787 buf[8] = buf2[3];
@@ -779,81 +790,167 @@ static int saa6752hs_init(struct i2c_client *client, u32 leading_null_bytes)
779 return 0; 790 return 0;
780} 791}
781 792
782static int 793static int saa6752hs_do_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls, int set)
783saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
784{ 794{
785 struct saa6752hs_state *h = i2c_get_clientdata(client); 795 struct saa6752hs_state *h = to_state(sd);
786 struct v4l2_ext_controls *ctrls = arg;
787 struct saa6752hs_mpeg_params params; 796 struct saa6752hs_mpeg_params params;
788 int err = 0;
789 int i; 797 int i;
790 798
791 switch (cmd) { 799 if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
792 case VIDIOC_INT_INIT: 800 return -EINVAL;
793 /* apply settings and start encoder */ 801
794 saa6752hs_init(client, *(u32 *)arg); 802 params = h->params;
795 break; 803 for (i = 0; i < ctrls->count; i++) {
796 case VIDIOC_S_EXT_CTRLS: 804 int err = handle_ctrl(h->has_ac3, &params, ctrls->controls + i, set);
797 if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG) 805
798 return -EINVAL; 806 if (err) {
799 /* fall through */ 807 ctrls->error_idx = i;
800 case VIDIOC_TRY_EXT_CTRLS: 808 return err;
801 case VIDIOC_G_EXT_CTRLS:
802 if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
803 return -EINVAL;
804 params = h->params;
805 for (i = 0; i < ctrls->count; i++) {
806 err = handle_ctrl(h->has_ac3, &params, ctrls->controls + i, cmd);
807 if (err) {
808 ctrls->error_idx = i;
809 return err;
810 }
811 } 809 }
812 h->params = params;
813 break;
814 case VIDIOC_QUERYCTRL:
815 return saa6752hs_qctrl(h, arg);
816 case VIDIOC_QUERYMENU:
817 return saa6752hs_qmenu(h, arg);
818 case VIDIOC_G_FMT:
819 {
820 struct v4l2_format *f = arg;
821
822 if (h->video_format == SAA6752HS_VF_UNKNOWN)
823 h->video_format = SAA6752HS_VF_D1;
824 f->fmt.pix.width =
825 v4l2_format_table[h->video_format].fmt.pix.width;
826 f->fmt.pix.height =
827 v4l2_format_table[h->video_format].fmt.pix.height;
828 break ;
829 } 810 }
830 case VIDIOC_S_FMT: 811 if (set)
831 { 812 h->params = params;
832 struct v4l2_format *f = arg; 813 return 0;
814}
833 815
834 saa6752hs_set_subsampling(client, f); 816static int saa6752hs_s_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
835 break; 817{
818 return saa6752hs_do_ext_ctrls(sd, ctrls, 1);
819}
820
821static int saa6752hs_try_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
822{
823 return saa6752hs_do_ext_ctrls(sd, ctrls, 0);
824}
825
826static int saa6752hs_g_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
827{
828 struct saa6752hs_state *h = to_state(sd);
829 int i;
830
831 if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
832 return -EINVAL;
833
834 for (i = 0; i < ctrls->count; i++) {
835 int err = get_ctrl(h->has_ac3, &h->params, ctrls->controls + i);
836
837 if (err) {
838 ctrls->error_idx = i;
839 return err;
840 }
836 } 841 }
837 case VIDIOC_S_STD: 842 return 0;
838 h->standard = *((v4l2_std_id *) arg); 843}
839 break;
840 844
841 case VIDIOC_DBG_G_CHIP_IDENT: 845static int saa6752hs_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
842 return v4l2_chip_ident_i2c_client(client, 846{
843 arg, h->chip, h->revision); 847 struct saa6752hs_state *h = to_state(sd);
844 848
845 default: 849 if (h->video_format == SAA6752HS_VF_UNKNOWN)
846 /* nothing */ 850 h->video_format = SAA6752HS_VF_D1;
847 break; 851 f->fmt.pix.width =
852 v4l2_format_table[h->video_format].fmt.pix.width;
853 f->fmt.pix.height =
854 v4l2_format_table[h->video_format].fmt.pix.height;
855 return 0;
856}
857
858static int saa6752hs_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
859{
860 struct saa6752hs_state *h = to_state(sd);
861 int dist_352, dist_480, dist_720;
862
863 /*
864 FIXME: translate and round width/height into EMPRESS
865 subsample type:
866
867 type | PAL | NTSC
868 ---------------------------
869 SIF | 352x288 | 352x240
870 1/2 D1 | 352x576 | 352x480
871 2/3 D1 | 480x576 | 480x480
872 D1 | 720x576 | 720x480
873 */
874
875 dist_352 = abs(f->fmt.pix.width - 352);
876 dist_480 = abs(f->fmt.pix.width - 480);
877 dist_720 = abs(f->fmt.pix.width - 720);
878 if (dist_720 < dist_480) {
879 f->fmt.pix.width = 720;
880 f->fmt.pix.height = 576;
881 h->video_format = SAA6752HS_VF_D1;
882 } else if (dist_480 < dist_352) {
883 f->fmt.pix.width = 480;
884 f->fmt.pix.height = 576;
885 h->video_format = SAA6752HS_VF_2_3_D1;
886 } else {
887 f->fmt.pix.width = 352;
888 if (abs(f->fmt.pix.height - 576) <
889 abs(f->fmt.pix.height - 288)) {
890 f->fmt.pix.height = 576;
891 h->video_format = SAA6752HS_VF_1_2_D1;
892 } else {
893 f->fmt.pix.height = 288;
894 h->video_format = SAA6752HS_VF_SIF;
895 }
848 } 896 }
897 return 0;
898}
899
900static int saa6752hs_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
901{
902 struct saa6752hs_state *h = to_state(sd);
903
904 h->standard = std;
905 return 0;
906}
907
908static int saa6752hs_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
909{
910 struct i2c_client *client = v4l2_get_subdevdata(sd);
911 struct saa6752hs_state *h = to_state(sd);
912
913 return v4l2_chip_ident_i2c_client(client,
914 chip, h->chip, h->revision);
915}
849 916
850 return err; 917static int saa6752hs_command(struct i2c_client *client, unsigned cmd, void *arg)
918{
919 return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
851} 920}
852 921
922/* ----------------------------------------------------------------------- */
923
924static const struct v4l2_subdev_core_ops saa6752hs_core_ops = {
925 .g_chip_ident = saa6752hs_g_chip_ident,
926 .init = saa6752hs_init,
927 .queryctrl = saa6752hs_queryctrl,
928 .querymenu = saa6752hs_querymenu,
929 .g_ext_ctrls = saa6752hs_g_ext_ctrls,
930 .s_ext_ctrls = saa6752hs_s_ext_ctrls,
931 .try_ext_ctrls = saa6752hs_try_ext_ctrls,
932};
933
934static const struct v4l2_subdev_tuner_ops saa6752hs_tuner_ops = {
935 .s_std = saa6752hs_s_std,
936};
937
938static const struct v4l2_subdev_video_ops saa6752hs_video_ops = {
939 .s_fmt = saa6752hs_s_fmt,
940 .g_fmt = saa6752hs_g_fmt,
941};
942
943static const struct v4l2_subdev_ops saa6752hs_ops = {
944 .core = &saa6752hs_core_ops,
945 .tuner = &saa6752hs_tuner_ops,
946 .video = &saa6752hs_video_ops,
947};
948
853static int saa6752hs_probe(struct i2c_client *client, 949static int saa6752hs_probe(struct i2c_client *client,
854 const struct i2c_device_id *id) 950 const struct i2c_device_id *id)
855{ 951{
856 struct saa6752hs_state *h = kzalloc(sizeof(*h), GFP_KERNEL); 952 struct saa6752hs_state *h = kzalloc(sizeof(*h), GFP_KERNEL);
953 struct v4l2_subdev *sd;
857 u8 addr = 0x13; 954 u8 addr = 0x13;
858 u8 data[12]; 955 u8 data[12];
859 956
@@ -861,6 +958,8 @@ static int saa6752hs_probe(struct i2c_client *client,
861 client->addr << 1, client->adapter->name); 958 client->addr << 1, client->adapter->name);
862 if (h == NULL) 959 if (h == NULL)
863 return -ENOMEM; 960 return -ENOMEM;
961 sd = &h->sd;
962 v4l2_i2c_subdev_init(sd, client, &saa6752hs_ops);
864 963
865 i2c_master_send(client, &addr, 1); 964 i2c_master_send(client, &addr, 1);
866 i2c_master_recv(client, data, sizeof(data)); 965 i2c_master_recv(client, data, sizeof(data));
@@ -874,14 +973,15 @@ static int saa6752hs_probe(struct i2c_client *client,
874 } 973 }
875 h->params = param_defaults; 974 h->params = param_defaults;
876 h->standard = 0; /* Assume 625 input lines */ 975 h->standard = 0; /* Assume 625 input lines */
877
878 i2c_set_clientdata(client, h);
879 return 0; 976 return 0;
880} 977}
881 978
882static int saa6752hs_remove(struct i2c_client *client) 979static int saa6752hs_remove(struct i2c_client *client)
883{ 980{
884 kfree(i2c_get_clientdata(client)); 981 struct v4l2_subdev *sd = i2c_get_clientdata(client);
982
983 v4l2_device_unregister_subdev(sd);
984 kfree(to_state(sd));
885 return 0; 985 return 0;
886} 986}
887 987