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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6

* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6:
[media] msp3400: fill in v4l2_tuner based on vt->type field
[media] tuner-core.c: don't change type field in g_tuner or g_frequency
[media] cx18/ivtv: fix g_tuner support
[media] tuner-core: power up tuner when called with s_power(1)
[media] v4l2-ioctl.c: check for valid tuner type in S_HW_FREQ_SEEK
[media] tuner-core: simplify the standard fixup
[media] tuner-core/v4l2-subdev: document that the type field has to be filled in
[media] v4l2-subdev.h: remove unused s_mode tuner op
[media] feature-removal-schedule: change in how radio device nodes are handled
[media] bttv: fix s_tuner for radio
[media] pvrusb2: fix g/s_tuner support
[media] v4l2-ioctl.c: prefill tuner type for g_frequency and g/s_tuner
[media] tuner-core: fix tuner_resume: use t->mode instead of t->type
[media] tuner-core: fix s_std and s_tuner

+175 -140
+22
Documentation/feature-removal-schedule.txt
··· 583 583 Who: Laurent Pinchart <laurent.pinchart@ideasonboard.com> 584 584 585 585 ---------------------------- 586 + 587 + What: For VIDIOC_S_FREQUENCY the type field must match the device node's type. 588 + If not, return -EINVAL. 589 + When: 3.2 590 + Why: It makes no sense to switch the tuner to radio mode by calling 591 + VIDIOC_S_FREQUENCY on a video node, or to switch the tuner to tv mode by 592 + calling VIDIOC_S_FREQUENCY on a radio node. This is the first step of a 593 + move to more consistent handling of tv and radio tuners. 594 + Who: Hans Verkuil <hans.verkuil@cisco.com> 595 + 596 + ---------------------------- 597 + 598 + What: Opening a radio device node will no longer automatically switch the 599 + tuner mode from tv to radio. 600 + When: 3.3 601 + Why: Just opening a V4L device should not change the state of the hardware 602 + like that. It's very unexpected and against the V4L spec. Instead, you 603 + switch to radio mode by calling VIDIOC_S_FREQUENCY. This is the second 604 + and last step of the move to consistent handling of tv and radio tuners. 605 + Who: Hans Verkuil <hans.verkuil@cisco.com> 606 + 607 + ----------------------------
+1 -1
drivers/media/video/bt8xx/bttv-driver.c
··· 3474 3474 if (0 != t->index) 3475 3475 return -EINVAL; 3476 3476 3477 - bttv_call_all(btv, tuner, g_tuner, t); 3477 + bttv_call_all(btv, tuner, s_tuner, t); 3478 3478 return 0; 3479 3479 } 3480 3480
+2 -6
drivers/media/video/cx18/cx18-ioctl.c
··· 695 695 696 696 cx18_call_all(cx, tuner, g_tuner, vt); 697 697 698 - if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) { 698 + if (vt->type == V4L2_TUNER_RADIO) 699 699 strlcpy(vt->name, "cx18 Radio Tuner", sizeof(vt->name)); 700 - vt->type = V4L2_TUNER_RADIO; 701 - } else { 700 + else 702 701 strlcpy(vt->name, "cx18 TV Tuner", sizeof(vt->name)); 703 - vt->type = V4L2_TUNER_ANALOG_TV; 704 - } 705 - 706 702 return 0; 707 703 } 708 704
+2 -6
drivers/media/video/ivtv/ivtv-ioctl.c
··· 1184 1184 1185 1185 ivtv_call_all(itv, tuner, g_tuner, vt); 1186 1186 1187 - if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) { 1187 + if (vt->type == V4L2_TUNER_RADIO) 1188 1188 strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name)); 1189 - vt->type = V4L2_TUNER_RADIO; 1190 - } else { 1189 + else 1191 1190 strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name)); 1192 - vt->type = V4L2_TUNER_ANALOG_TV; 1193 - } 1194 - 1195 1191 return 0; 1196 1192 } 1197 1193
+7 -5
drivers/media/video/msp3400-driver.c
··· 480 480 struct msp_state *state = to_state(sd); 481 481 struct i2c_client *client = v4l2_get_subdevdata(sd); 482 482 483 - if (state->radio) 483 + if (vt->type != V4L2_TUNER_ANALOG_TV) 484 484 return 0; 485 - if (state->opmode == OPMODE_AUTOSELECT) 486 - msp_detect_stereo(client); 487 - vt->audmode = state->audmode; 488 - vt->rxsubchans = state->rxsubchans; 485 + if (!state->radio) { 486 + if (state->opmode == OPMODE_AUTOSELECT) 487 + msp_detect_stereo(client); 488 + vt->rxsubchans = state->rxsubchans; 489 + } 490 + vt->audmode = state->audmode; 489 491 vt->capability |= V4L2_TUNER_CAP_STEREO | 490 492 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; 491 493 return 0;
+4
drivers/media/video/pvrusb2/pvrusb2-hdw.c
··· 3046 3046 if (hdw->input_dirty || hdw->audiomode_dirty || hdw->force_dirty) { 3047 3047 struct v4l2_tuner vt; 3048 3048 memset(&vt, 0, sizeof(vt)); 3049 + vt.type = (hdw->input_val == PVR2_CVAL_INPUT_RADIO) ? 3050 + V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 3049 3051 vt.audmode = hdw->audiomode_val; 3050 3052 v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, s_tuner, &vt); 3051 3053 } ··· 5173 5171 { 5174 5172 struct v4l2_tuner *vtp = &hdw->tuner_signal_info; 5175 5173 memset(vtp, 0, sizeof(*vtp)); 5174 + vtp->type = (hdw->input_val == PVR2_CVAL_INPUT_RADIO) ? 5175 + V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 5176 5176 hdw->tuner_signal_stale = 0; 5177 5177 /* Note: There apparently is no replacement for VIDIOC_CROPCAP 5178 5178 using v4l2-subdev - therefore we can't support that AT ALL right
+115 -116
drivers/media/video/tuner-core.c
··· 724 724 } 725 725 726 726 /** 727 - * set_mode_freq - Switch tuner to other mode. 728 - * @client: struct i2c_client pointer 727 + * set_mode - Switch tuner to other mode. 729 728 * @t: a pointer to the module's internal struct_tuner 730 729 * @mode: enum v4l2_type (radio or TV) 731 - * @freq: frequency to set (0 means to use the previous one) 732 730 * 733 731 * If tuner doesn't support the needed mode (radio or TV), prints a 734 732 * debug message and returns -EINVAL, changing its state to standby. 735 - * Otherwise, changes the state and sets frequency to the last value, if 736 - * the tuner can sleep or if it supports both Radio and TV. 733 + * Otherwise, changes the mode and returns 0. 737 734 */ 738 - static int set_mode_freq(struct i2c_client *client, struct tuner *t, 739 - enum v4l2_tuner_type mode, unsigned int freq) 735 + static int set_mode(struct tuner *t, enum v4l2_tuner_type mode) 740 736 { 741 737 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; 742 738 ··· 748 752 t->mode = mode; 749 753 tuner_dbg("Changing to mode %d\n", mode); 750 754 } 751 - if (t->mode == V4L2_TUNER_RADIO) { 752 - if (freq) 753 - t->radio_freq = freq; 754 - set_radio_freq(client, t->radio_freq); 755 - } else { 756 - if (freq) 757 - t->tv_freq = freq; 758 - set_tv_freq(client, t->tv_freq); 759 - } 760 - 761 755 return 0; 756 + } 757 + 758 + /** 759 + * set_freq - Set the tuner to the desired frequency. 760 + * @t: a pointer to the module's internal struct_tuner 761 + * @freq: frequency to set (0 means to use the current frequency) 762 + */ 763 + static void set_freq(struct tuner *t, unsigned int freq) 764 + { 765 + struct i2c_client *client = v4l2_get_subdevdata(&t->sd); 766 + 767 + if (t->mode == V4L2_TUNER_RADIO) { 768 + if (!freq) 769 + freq = t->radio_freq; 770 + set_radio_freq(client, freq); 771 + } else { 772 + if (!freq) 773 + freq = t->tv_freq; 774 + set_tv_freq(client, freq); 775 + } 762 776 } 763 777 764 778 /* ··· 823 817 /** 824 818 * tuner_fixup_std - force a given video standard variant 825 819 * 826 - * @t: tuner internal struct 820 + * @t: tuner internal struct 821 + * @std: TV standard 827 822 * 828 823 * A few devices or drivers have problem to detect some standard variations. 829 824 * On other operational systems, the drivers generally have a per-country ··· 834 827 * to distinguish all video standard variations, a modprobe parameter can 835 828 * be used to force a video standard match. 836 829 */ 837 - static int tuner_fixup_std(struct tuner *t) 830 + static v4l2_std_id tuner_fixup_std(struct tuner *t, v4l2_std_id std) 838 831 { 839 - if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) { 832 + if (pal[0] != '-' && (std & V4L2_STD_PAL) == V4L2_STD_PAL) { 840 833 switch (pal[0]) { 841 834 case '6': 842 - tuner_dbg("insmod fixup: PAL => PAL-60\n"); 843 - t->std = V4L2_STD_PAL_60; 844 - break; 835 + return V4L2_STD_PAL_60; 845 836 case 'b': 846 837 case 'B': 847 838 case 'g': 848 839 case 'G': 849 - tuner_dbg("insmod fixup: PAL => PAL-BG\n"); 850 - t->std = V4L2_STD_PAL_BG; 851 - break; 840 + return V4L2_STD_PAL_BG; 852 841 case 'i': 853 842 case 'I': 854 - tuner_dbg("insmod fixup: PAL => PAL-I\n"); 855 - t->std = V4L2_STD_PAL_I; 856 - break; 843 + return V4L2_STD_PAL_I; 857 844 case 'd': 858 845 case 'D': 859 846 case 'k': 860 847 case 'K': 861 - tuner_dbg("insmod fixup: PAL => PAL-DK\n"); 862 - t->std = V4L2_STD_PAL_DK; 863 - break; 848 + return V4L2_STD_PAL_DK; 864 849 case 'M': 865 850 case 'm': 866 - tuner_dbg("insmod fixup: PAL => PAL-M\n"); 867 - t->std = V4L2_STD_PAL_M; 868 - break; 851 + return V4L2_STD_PAL_M; 869 852 case 'N': 870 853 case 'n': 871 - if (pal[1] == 'c' || pal[1] == 'C') { 872 - tuner_dbg("insmod fixup: PAL => PAL-Nc\n"); 873 - t->std = V4L2_STD_PAL_Nc; 874 - } else { 875 - tuner_dbg("insmod fixup: PAL => PAL-N\n"); 876 - t->std = V4L2_STD_PAL_N; 877 - } 878 - break; 879 - case '-': 880 - /* default parameter, do nothing */ 881 - break; 854 + if (pal[1] == 'c' || pal[1] == 'C') 855 + return V4L2_STD_PAL_Nc; 856 + return V4L2_STD_PAL_N; 882 857 default: 883 858 tuner_warn("pal= argument not recognised\n"); 884 859 break; 885 860 } 886 861 } 887 - if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) { 862 + if (secam[0] != '-' && (std & V4L2_STD_SECAM) == V4L2_STD_SECAM) { 888 863 switch (secam[0]) { 889 864 case 'b': 890 865 case 'B': ··· 874 885 case 'G': 875 886 case 'h': 876 887 case 'H': 877 - tuner_dbg("insmod fixup: SECAM => SECAM-BGH\n"); 878 - t->std = V4L2_STD_SECAM_B | 879 - V4L2_STD_SECAM_G | 880 - V4L2_STD_SECAM_H; 881 - break; 888 + return V4L2_STD_SECAM_B | 889 + V4L2_STD_SECAM_G | 890 + V4L2_STD_SECAM_H; 882 891 case 'd': 883 892 case 'D': 884 893 case 'k': 885 894 case 'K': 886 - tuner_dbg("insmod fixup: SECAM => SECAM-DK\n"); 887 - t->std = V4L2_STD_SECAM_DK; 888 - break; 895 + return V4L2_STD_SECAM_DK; 889 896 case 'l': 890 897 case 'L': 891 - if ((secam[1] == 'C') || (secam[1] == 'c')) { 892 - tuner_dbg("insmod fixup: SECAM => SECAM-L'\n"); 893 - t->std = V4L2_STD_SECAM_LC; 894 - } else { 895 - tuner_dbg("insmod fixup: SECAM => SECAM-L\n"); 896 - t->std = V4L2_STD_SECAM_L; 897 - } 898 - break; 899 - case '-': 900 - /* default parameter, do nothing */ 901 - break; 898 + if ((secam[1] == 'C') || (secam[1] == 'c')) 899 + return V4L2_STD_SECAM_LC; 900 + return V4L2_STD_SECAM_L; 902 901 default: 903 902 tuner_warn("secam= argument not recognised\n"); 904 903 break; 905 904 } 906 905 } 907 906 908 - if ((t->std & V4L2_STD_NTSC) == V4L2_STD_NTSC) { 907 + if (ntsc[0] != '-' && (std & V4L2_STD_NTSC) == V4L2_STD_NTSC) { 909 908 switch (ntsc[0]) { 910 909 case 'm': 911 910 case 'M': 912 - tuner_dbg("insmod fixup: NTSC => NTSC-M\n"); 913 - t->std = V4L2_STD_NTSC_M; 914 - break; 911 + return V4L2_STD_NTSC_M; 915 912 case 'j': 916 913 case 'J': 917 - tuner_dbg("insmod fixup: NTSC => NTSC_M_JP\n"); 918 - t->std = V4L2_STD_NTSC_M_JP; 919 - break; 914 + return V4L2_STD_NTSC_M_JP; 920 915 case 'k': 921 916 case 'K': 922 - tuner_dbg("insmod fixup: NTSC => NTSC_M_KR\n"); 923 - t->std = V4L2_STD_NTSC_M_KR; 924 - break; 925 - case '-': 926 - /* default parameter, do nothing */ 927 - break; 917 + return V4L2_STD_NTSC_M_KR; 928 918 default: 929 919 tuner_info("ntsc= argument not recognised\n"); 930 920 break; 931 921 } 932 922 } 933 - return 0; 923 + return std; 934 924 } 935 925 936 926 /* ··· 1026 1058 static int tuner_s_radio(struct v4l2_subdev *sd) 1027 1059 { 1028 1060 struct tuner *t = to_tuner(sd); 1029 - struct i2c_client *client = v4l2_get_subdevdata(sd); 1030 1061 1031 - if (set_mode_freq(client, t, V4L2_TUNER_RADIO, 0) == -EINVAL) 1032 - return 0; 1062 + if (set_mode(t, V4L2_TUNER_RADIO) == 0) 1063 + set_freq(t, 0); 1033 1064 return 0; 1034 1065 } 1035 1066 ··· 1039 1072 /** 1040 1073 * tuner_s_power - controls the power state of the tuner 1041 1074 * @sd: pointer to struct v4l2_subdev 1042 - * @on: a zero value puts the tuner to sleep 1075 + * @on: a zero value puts the tuner to sleep, non-zero wakes it up 1043 1076 */ 1044 1077 static int tuner_s_power(struct v4l2_subdev *sd, int on) 1045 1078 { 1046 1079 struct tuner *t = to_tuner(sd); 1047 1080 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; 1048 1081 1049 - /* FIXME: Why this function don't wake the tuner if on != 0 ? */ 1050 - if (on) 1082 + if (on) { 1083 + if (t->standby && set_mode(t, t->mode) == 0) { 1084 + tuner_dbg("Waking up tuner\n"); 1085 + set_freq(t, 0); 1086 + } 1051 1087 return 0; 1088 + } 1052 1089 1053 1090 tuner_dbg("Putting tuner to sleep\n"); 1054 1091 t->standby = true; ··· 1064 1093 static int tuner_s_std(struct v4l2_subdev *sd, v4l2_std_id std) 1065 1094 { 1066 1095 struct tuner *t = to_tuner(sd); 1067 - struct i2c_client *client = v4l2_get_subdevdata(sd); 1068 1096 1069 - if (set_mode_freq(client, t, V4L2_TUNER_ANALOG_TV, 0) == -EINVAL) 1097 + if (set_mode(t, V4L2_TUNER_ANALOG_TV)) 1070 1098 return 0; 1071 1099 1072 - t->std = std; 1073 - tuner_fixup_std(t); 1074 - 1100 + t->std = tuner_fixup_std(t, std); 1101 + if (t->std != std) 1102 + tuner_dbg("Fixup standard %llx to %llx\n", std, t->std); 1103 + set_freq(t, 0); 1075 1104 return 0; 1076 1105 } 1077 1106 1078 1107 static int tuner_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f) 1079 1108 { 1080 1109 struct tuner *t = to_tuner(sd); 1081 - struct i2c_client *client = v4l2_get_subdevdata(sd); 1082 1110 1083 - if (set_mode_freq(client, t, f->type, f->frequency) == -EINVAL) 1084 - return 0; 1085 - 1111 + if (set_mode(t, f->type) == 0) 1112 + set_freq(t, f->frequency); 1086 1113 return 0; 1087 1114 } 1088 1115 1116 + /** 1117 + * tuner_g_frequency - Get the tuned frequency for the tuner 1118 + * @sd: pointer to struct v4l2_subdev 1119 + * @f: pointer to struct v4l2_frequency 1120 + * 1121 + * At return, the structure f will be filled with tuner frequency 1122 + * if the tuner matches the f->type. 1123 + * Note: f->type should be initialized before calling it. 1124 + * This is done by either video_ioctl2 or by the bridge driver. 1125 + */ 1089 1126 static int tuner_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f) 1090 1127 { 1091 1128 struct tuner *t = to_tuner(sd); ··· 1101 1122 1102 1123 if (check_mode(t, f->type) == -EINVAL) 1103 1124 return 0; 1104 - f->type = t->mode; 1105 - if (fe_tuner_ops->get_frequency && !t->standby) { 1125 + if (f->type == t->mode && fe_tuner_ops->get_frequency && !t->standby) { 1106 1126 u32 abs_freq; 1107 1127 1108 1128 fe_tuner_ops->get_frequency(&t->fe, &abs_freq); ··· 1109 1131 DIV_ROUND_CLOSEST(abs_freq * 2, 125) : 1110 1132 DIV_ROUND_CLOSEST(abs_freq, 62500); 1111 1133 } else { 1112 - f->frequency = (V4L2_TUNER_RADIO == t->mode) ? 1134 + f->frequency = (V4L2_TUNER_RADIO == f->type) ? 1113 1135 t->radio_freq : t->tv_freq; 1114 1136 } 1115 1137 return 0; 1116 1138 } 1117 1139 1140 + /** 1141 + * tuner_g_tuner - Fill in tuner information 1142 + * @sd: pointer to struct v4l2_subdev 1143 + * @vt: pointer to struct v4l2_tuner 1144 + * 1145 + * At return, the structure vt will be filled with tuner information 1146 + * if the tuner matches vt->type. 1147 + * Note: vt->type should be initialized before calling it. 1148 + * This is done by either video_ioctl2 or by the bridge driver. 1149 + */ 1118 1150 static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) 1119 1151 { 1120 1152 struct tuner *t = to_tuner(sd); ··· 1133 1145 1134 1146 if (check_mode(t, vt->type) == -EINVAL) 1135 1147 return 0; 1136 - vt->type = t->mode; 1137 - if (analog_ops->get_afc) 1148 + if (vt->type == t->mode && analog_ops->get_afc) 1138 1149 vt->afc = analog_ops->get_afc(&t->fe); 1139 - if (t->mode == V4L2_TUNER_ANALOG_TV) 1150 + if (vt->type == V4L2_TUNER_ANALOG_TV) 1140 1151 vt->capability |= V4L2_TUNER_CAP_NORM; 1141 - if (t->mode != V4L2_TUNER_RADIO) { 1152 + if (vt->type != V4L2_TUNER_RADIO) { 1142 1153 vt->rangelow = tv_range[0] * 16; 1143 1154 vt->rangehigh = tv_range[1] * 16; 1144 1155 return 0; 1145 1156 } 1146 1157 1147 1158 /* radio mode */ 1148 - vt->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; 1149 - if (fe_tuner_ops->get_status) { 1150 - u32 tuner_status; 1159 + if (vt->type == t->mode) { 1160 + vt->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; 1161 + if (fe_tuner_ops->get_status) { 1162 + u32 tuner_status; 1151 1163 1152 - fe_tuner_ops->get_status(&t->fe, &tuner_status); 1153 - vt->rxsubchans = 1154 - (tuner_status & TUNER_STATUS_STEREO) ? 1155 - V4L2_TUNER_SUB_STEREO : 1156 - V4L2_TUNER_SUB_MONO; 1164 + fe_tuner_ops->get_status(&t->fe, &tuner_status); 1165 + vt->rxsubchans = 1166 + (tuner_status & TUNER_STATUS_STEREO) ? 1167 + V4L2_TUNER_SUB_STEREO : 1168 + V4L2_TUNER_SUB_MONO; 1169 + } 1170 + if (analog_ops->has_signal) 1171 + vt->signal = analog_ops->has_signal(&t->fe); 1172 + vt->audmode = t->audmode; 1157 1173 } 1158 - if (analog_ops->has_signal) 1159 - vt->signal = analog_ops->has_signal(&t->fe); 1160 1174 vt->capability |= V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; 1161 - vt->audmode = t->audmode; 1162 1175 vt->rangelow = radio_range[0] * 16000; 1163 1176 vt->rangehigh = radio_range[1] * 16000; 1164 1177 1165 1178 return 0; 1166 1179 } 1167 1180 1181 + /** 1182 + * tuner_s_tuner - Set the tuner's audio mode 1183 + * @sd: pointer to struct v4l2_subdev 1184 + * @vt: pointer to struct v4l2_tuner 1185 + * 1186 + * Sets the audio mode if the tuner matches vt->type. 1187 + * Note: vt->type should be initialized before calling it. 1188 + * This is done by either video_ioctl2 or by the bridge driver. 1189 + */ 1168 1190 static int tuner_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) 1169 1191 { 1170 1192 struct tuner *t = to_tuner(sd); 1171 - struct i2c_client *client = v4l2_get_subdevdata(sd); 1172 1193 1173 - if (set_mode_freq(client, t, vt->type, 0) == -EINVAL) 1194 + if (set_mode(t, vt->type)) 1174 1195 return 0; 1175 1196 1176 1197 if (t->mode == V4L2_TUNER_RADIO) 1177 1198 t->audmode = vt->audmode; 1199 + set_freq(t, 0); 1178 1200 1179 1201 return 0; 1180 1202 } ··· 1219 1221 tuner_dbg("resume\n"); 1220 1222 1221 1223 if (!t->standby) 1222 - set_mode_freq(c, t, t->type, 0); 1224 + if (set_mode(t, t->mode) == 0) 1225 + set_freq(t, 0); 1223 1226 1224 1227 return 0; 1225 1228 }
+15 -3
drivers/media/video/v4l2-ioctl.c
··· 1822 1822 if (!ops->vidioc_g_tuner) 1823 1823 break; 1824 1824 1825 + p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? 1826 + V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 1825 1827 ret = ops->vidioc_g_tuner(file, fh, p); 1826 1828 if (!ret) 1827 1829 dbgarg(cmd, "index=%d, name=%s, type=%d, " ··· 1842 1840 1843 1841 if (!ops->vidioc_s_tuner) 1844 1842 break; 1843 + p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? 1844 + V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 1845 1845 dbgarg(cmd, "index=%d, name=%s, type=%d, " 1846 1846 "capability=0x%x, rangelow=%d, " 1847 1847 "rangehigh=%d, signal=%d, afc=%d, " ··· 1862 1858 if (!ops->vidioc_g_frequency) 1863 1859 break; 1864 1860 1861 + p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? 1862 + V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 1865 1863 ret = ops->vidioc_g_frequency(file, fh, p); 1866 1864 if (!ret) 1867 1865 dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n", ··· 1946 1940 case VIDIOC_S_HW_FREQ_SEEK: 1947 1941 { 1948 1942 struct v4l2_hw_freq_seek *p = arg; 1943 + enum v4l2_tuner_type type; 1949 1944 1950 1945 if (!ops->vidioc_s_hw_freq_seek) 1951 1946 break; 1947 + type = (vfd->vfl_type == VFL_TYPE_RADIO) ? 1948 + V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 1952 1949 dbgarg(cmd, 1953 - "tuner=%d, type=%d, seek_upward=%d, wrap_around=%d\n", 1954 - p->tuner, p->type, p->seek_upward, p->wrap_around); 1955 - ret = ops->vidioc_s_hw_freq_seek(file, fh, p); 1950 + "tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u\n", 1951 + p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing); 1952 + if (p->type != type) 1953 + ret = -EINVAL; 1954 + else 1955 + ret = ops->vidioc_s_hw_freq_seek(file, fh, p); 1956 1956 break; 1957 1957 } 1958 1958 case VIDIOC_ENUM_FRAMESIZES:
+7 -3
include/media/v4l2-subdev.h
··· 173 173 struct v4l2_event_subscription *sub); 174 174 }; 175 175 176 - /* s_mode: switch the tuner to a specific tuner mode. Replacement of s_radio. 176 + /* s_radio: v4l device was opened in radio mode. 177 177 178 - s_radio: v4l device was opened in Radio mode, to be replaced by s_mode. 178 + g_frequency: freq->type must be filled in. Normally done by video_ioctl2 179 + or the bridge driver. 180 + 181 + g_tuner: 182 + s_tuner: vt->type must be filled in. Normally done by video_ioctl2 or the 183 + bridge driver. 179 184 180 185 s_type_addr: sets tuner type and its I2C addr. 181 186 182 187 s_config: sets tda9887 specific stuff, like port1, port2 and qss 183 188 */ 184 189 struct v4l2_subdev_tuner_ops { 185 - int (*s_mode)(struct v4l2_subdev *sd, enum v4l2_tuner_type); 186 190 int (*s_radio)(struct v4l2_subdev *sd); 187 191 int (*s_frequency)(struct v4l2_subdev *sd, struct v4l2_frequency *freq); 188 192 int (*g_frequency)(struct v4l2_subdev *sd, struct v4l2_frequency *freq);