Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] msp3400: Add standards detection to the driver

As msp3400 allows standards detection, add support for it. That
efectivelly means that devices with msp3400 can now implement
VIDIOC_QUERYSTD, and it will provide very good detection for
the standard, specially if combined with a video decoder detection.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

+85 -23
+20
drivers/media/video/msp3400-driver.c
··· 426 426 return 0; 427 427 } 428 428 429 + static int msp_querystd(struct v4l2_subdev *sd, v4l2_std_id *id) 430 + { 431 + struct msp_state *state = to_state(sd); 432 + struct i2c_client *client = v4l2_get_subdevdata(sd); 433 + 434 + *id &= state->detected_std; 435 + 436 + v4l_dbg(2, msp_debug, client, 437 + "detected standard: %s(0x%08Lx)\n", 438 + msp_standard_std_name(state->std), state->detected_std); 439 + 440 + return 0; 441 + } 442 + 429 443 static int msp_s_std(struct v4l2_subdev *sd, v4l2_std_id id) 430 444 { 431 445 struct msp_state *state = to_state(sd); ··· 630 616 .s_std = msp_s_std, 631 617 }; 632 618 619 + static const struct v4l2_subdev_video_ops msp_video_ops = { 620 + .querystd = msp_querystd, 621 + }; 622 + 633 623 static const struct v4l2_subdev_tuner_ops msp_tuner_ops = { 634 624 .s_frequency = msp_s_frequency, 635 625 .g_tuner = msp_g_tuner, ··· 648 630 649 631 static const struct v4l2_subdev_ops msp_ops = { 650 632 .core = &msp_core_ops, 633 + .video = &msp_video_ops, 651 634 .tuner = &msp_tuner_ops, 652 635 .audio = &msp_audio_ops, 653 636 }; ··· 683 664 v4l2_i2c_subdev_init(sd, client, &msp_ops); 684 665 685 666 state->v4l2_std = V4L2_STD_NTSC; 667 + state->detected_std = V4L2_STD_ALL; 686 668 state->audmode = V4L2_TUNER_MODE_STEREO; 687 669 state->input = -1; 688 670 state->i2s_mode = 0;
+1 -1
drivers/media/video/msp3400-driver.h
··· 75 75 int opmode; 76 76 int std; 77 77 int mode; 78 - v4l2_std_id v4l2_std; 78 + v4l2_std_id v4l2_std, detected_std; 79 79 int nicam_on; 80 80 int acb; 81 81 int in_scart;
+64 -22
drivers/media/video/msp3400-kthreads.c
··· 37 37 int retval; 38 38 int main, second; 39 39 char *name; 40 + v4l2_std_id std; 40 41 } msp_stdlist[] = { 41 - { 0x0000, 0, 0, "could not detect sound standard" }, 42 - { 0x0001, 0, 0, "autodetect start" }, 43 - { 0x0002, MSP_CARRIER(4.5), MSP_CARRIER(4.72), "4.5/4.72 M Dual FM-Stereo" }, 44 - { 0x0003, MSP_CARRIER(5.5), MSP_CARRIER(5.7421875), "5.5/5.74 B/G Dual FM-Stereo" }, 45 - { 0x0004, MSP_CARRIER(6.5), MSP_CARRIER(6.2578125), "6.5/6.25 D/K1 Dual FM-Stereo" }, 46 - { 0x0005, MSP_CARRIER(6.5), MSP_CARRIER(6.7421875), "6.5/6.74 D/K2 Dual FM-Stereo" }, 47 - { 0x0006, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5 D/K FM-Mono (HDEV3)" }, 48 - { 0x0007, MSP_CARRIER(6.5), MSP_CARRIER(5.7421875), "6.5/5.74 D/K3 Dual FM-Stereo" }, 49 - { 0x0008, MSP_CARRIER(5.5), MSP_CARRIER(5.85), "5.5/5.85 B/G NICAM FM" }, 50 - { 0x0009, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 L NICAM AM" }, 51 - { 0x000a, MSP_CARRIER(6.0), MSP_CARRIER(6.55), "6.0/6.55 I NICAM FM" }, 52 - { 0x000b, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM" }, 53 - { 0x000c, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM (HDEV2)" }, 54 - { 0x000d, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM (HDEV3)" }, 55 - { 0x0020, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M BTSC-Stereo" }, 56 - { 0x0021, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M BTSC-Mono + SAP" }, 57 - { 0x0030, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M EIA-J Japan Stereo" }, 58 - { 0x0040, MSP_CARRIER(10.7), MSP_CARRIER(10.7), "10.7 FM-Stereo Radio" }, 59 - { 0x0050, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5 SAT-Mono" }, 60 - { 0x0051, MSP_CARRIER(7.02), MSP_CARRIER(7.20), "7.02/7.20 SAT-Stereo" }, 61 - { 0x0060, MSP_CARRIER(7.2), MSP_CARRIER(7.2), "7.2 SAT ADR" }, 62 - { -1, 0, 0, NULL }, /* EOF */ 42 + { 0x0000, 0, 0, "could not detect sound standard", V4L2_STD_ALL }, 43 + { 0x0001, 0, 0, "autodetect start", V4L2_STD_ALL }, 44 + { 0x0002, MSP_CARRIER(4.5), MSP_CARRIER(4.72), 45 + "4.5/4.72 M Dual FM-Stereo", V4L2_STD_MN }, 46 + { 0x0003, MSP_CARRIER(5.5), MSP_CARRIER(5.7421875), 47 + "5.5/5.74 B/G Dual FM-Stereo", V4L2_STD_BG }, 48 + { 0x0004, MSP_CARRIER(6.5), MSP_CARRIER(6.2578125), 49 + "6.5/6.25 D/K1 Dual FM-Stereo", V4L2_STD_DK }, 50 + { 0x0005, MSP_CARRIER(6.5), MSP_CARRIER(6.7421875), 51 + "6.5/6.74 D/K2 Dual FM-Stereo", V4L2_STD_DK }, 52 + { 0x0006, MSP_CARRIER(6.5), MSP_CARRIER(6.5), 53 + "6.5 D/K FM-Mono (HDEV3)", V4L2_STD_DK }, 54 + { 0x0007, MSP_CARRIER(6.5), MSP_CARRIER(5.7421875), 55 + "6.5/5.74 D/K3 Dual FM-Stereo", V4L2_STD_DK }, 56 + { 0x0008, MSP_CARRIER(5.5), MSP_CARRIER(5.85), 57 + "5.5/5.85 B/G NICAM FM", V4L2_STD_BG }, 58 + { 0x0009, MSP_CARRIER(6.5), MSP_CARRIER(5.85), 59 + "6.5/5.85 L NICAM AM", V4L2_STD_L }, 60 + { 0x000a, MSP_CARRIER(6.0), MSP_CARRIER(6.55), 61 + "6.0/6.55 I NICAM FM", V4L2_STD_PAL_I }, 62 + { 0x000b, MSP_CARRIER(6.5), MSP_CARRIER(5.85), 63 + "6.5/5.85 D/K NICAM FM", V4L2_STD_DK }, 64 + { 0x000c, MSP_CARRIER(6.5), MSP_CARRIER(5.85), 65 + "6.5/5.85 D/K NICAM FM (HDEV2)", V4L2_STD_DK }, 66 + { 0x000d, MSP_CARRIER(6.5), MSP_CARRIER(5.85), 67 + "6.5/5.85 D/K NICAM FM (HDEV3)", V4L2_STD_DK }, 68 + { 0x0020, MSP_CARRIER(4.5), MSP_CARRIER(4.5), 69 + "4.5 M BTSC-Stereo", V4L2_STD_MTS }, 70 + { 0x0021, MSP_CARRIER(4.5), MSP_CARRIER(4.5), 71 + "4.5 M BTSC-Mono + SAP", V4L2_STD_MTS }, 72 + { 0x0030, MSP_CARRIER(4.5), MSP_CARRIER(4.5), 73 + "4.5 M EIA-J Japan Stereo", V4L2_STD_NTSC_M_JP }, 74 + { 0x0040, MSP_CARRIER(10.7), MSP_CARRIER(10.7), 75 + "10.7 FM-Stereo Radio", V4L2_STD_ALL }, 76 + { 0x0050, MSP_CARRIER(6.5), MSP_CARRIER(6.5), 77 + "6.5 SAT-Mono", V4L2_STD_ALL }, 78 + { 0x0051, MSP_CARRIER(7.02), MSP_CARRIER(7.20), 79 + "7.02/7.20 SAT-Stereo", V4L2_STD_ALL }, 80 + { 0x0060, MSP_CARRIER(7.2), MSP_CARRIER(7.2), 81 + "7.2 SAT ADR", V4L2_STD_ALL }, 82 + { -1, 0, 0, NULL, 0 }, /* EOF */ 63 83 }; 64 84 65 85 static struct msp3400c_init_data_dem { ··· 174 154 if (msp_stdlist[i].retval == std) 175 155 return msp_stdlist[i].name; 176 156 return "unknown"; 157 + } 158 + 159 + static v4l2_std_id msp_standard_std(int std) 160 + { 161 + int i; 162 + 163 + for (i = 0; msp_stdlist[i].name != NULL; i++) 164 + if (msp_stdlist[i].retval == std) 165 + return msp_stdlist[i].std; 166 + return V4L2_STD_ALL; 177 167 } 178 168 179 169 static void msp_set_source(struct i2c_client *client, u16 src) ··· 509 479 int count, max1, max2, val1, val2, val, i; 510 480 511 481 v4l_dbg(1, msp_debug, client, "msp3400 daemon started\n"); 482 + state->detected_std = V4L2_STD_ALL; 512 483 set_freezable(); 513 484 for (;;) { 514 485 v4l_dbg(2, msp_debug, client, "msp3400 thread: sleep\n"); ··· 610 579 state->main = msp3400c_carrier_detect_main[max1].cdo; 611 580 switch (max1) { 612 581 case 1: /* 5.5 */ 582 + state->detected_std = V4L2_STD_BG | V4L2_STD_PAL_H; 613 583 if (max2 == 0) { 614 584 /* B/G FM-stereo */ 615 585 state->second = msp3400c_carrier_detect_55[max2].cdo; ··· 628 596 break; 629 597 case 2: /* 6.0 */ 630 598 /* PAL I NICAM */ 599 + state->detected_std = V4L2_STD_PAL_I; 631 600 state->second = MSP_CARRIER(6.552); 632 601 msp3400c_set_mode(client, MSP_MODE_FM_NICAM2); 633 602 state->nicam_on = 1; ··· 640 607 state->second = msp3400c_carrier_detect_65[max2].cdo; 641 608 msp3400c_set_mode(client, MSP_MODE_FM_TERRA); 642 609 state->watch_stereo = 1; 610 + state->detected_std = V4L2_STD_DK; 643 611 } else if (max2 == 0 && (state->v4l2_std & V4L2_STD_SECAM)) { 644 612 /* L NICAM or AM-mono */ 645 613 state->second = msp3400c_carrier_detect_65[max2].cdo; 646 614 msp3400c_set_mode(client, MSP_MODE_AM_NICAM); 647 615 state->watch_stereo = 1; 616 + state->detected_std = V4L2_STD_L; 648 617 } else if (max2 == 0 && state->has_nicam) { 649 618 /* D/K NICAM */ 650 619 state->second = msp3400c_carrier_detect_65[max2].cdo; 651 620 msp3400c_set_mode(client, MSP_MODE_FM_NICAM1); 652 621 state->nicam_on = 1; 653 622 state->watch_stereo = 1; 623 + state->detected_std = V4L2_STD_DK; 654 624 } else { 655 625 goto no_second; 656 626 } 657 627 break; 658 628 case 0: /* 4.5 */ 629 + state->detected_std = V4L2_STD_MN; 659 630 default: 660 631 no_second: 661 632 state->second = msp3400c_carrier_detect_main[max1].cdo; ··· 699 662 int val, i, std, count; 700 663 701 664 v4l_dbg(1, msp_debug, client, "msp3410 daemon started\n"); 665 + state->detected_std = V4L2_STD_ALL; 702 666 set_freezable(); 703 667 for (;;) { 704 668 v4l_dbg(2, msp_debug, client, "msp3410 thread: sleep\n"); ··· 781 743 msp_stdlist[8].name : "unknown", val); 782 744 state->std = val = 0x0009; 783 745 msp_write_dem(client, 0x20, val); 746 + } else { 747 + state->detected_std = msp_standard_std(state->std); 784 748 } 785 749 786 750 /* set stereo */ ··· 997 957 int val, i; 998 958 999 959 v4l_dbg(1, msp_debug, client, "msp34xxg daemon started\n"); 960 + state->detected_std = V4L2_STD_ALL; 1000 961 set_freezable(); 1001 962 for (;;) { 1002 963 v4l_dbg(2, msp_debug, client, "msp34xxg thread: sleep\n"); ··· 1054 1013 v4l_dbg(1, msp_debug, client, 1055 1014 "detected standard: %s (0x%04x)\n", 1056 1015 msp_standard_std_name(state->std), state->std); 1016 + state->detected_std = msp_standard_std(state->std); 1057 1017 1058 1018 if (state->std == 9) { 1059 1019 /* AM NICAM mode */