diff options
author | Huang Shijie <shijie8@gmail.com> | 2010-02-11 01:53:51 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-02-26 13:10:58 -0500 |
commit | 007ad830364e795316d2825f1ab68b3a53a3d56c (patch) | |
tree | cdb6ac4326a4dedda0ef95bcc4c8e4ad8fcd6047 | |
parent | 5b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89f (diff) |
V4L/DVB: tlg2300: remove the country code for analog tv and radio
video :
use the V4L2_STD macros to select the proper audio setting.
radio :
add preemphasis ctr.
test it by the command:
v4l2-ctl -d /dev/radio0 --set-ctrl=pre_emphasis_settings=1
[mchehab@redhat.com: folded documentation patch]
Signed-off-by: Huang Shijie <shijie8@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | Documentation/video4linux/README.tlg2300 | 198 | ||||
-rw-r--r-- | drivers/media/video/tlg2300/pd-common.h | 4 | ||||
-rw-r--r-- | drivers/media/video/tlg2300/pd-main.c | 36 | ||||
-rw-r--r-- | drivers/media/video/tlg2300/pd-radio.c | 107 | ||||
-rw-r--r-- | drivers/media/video/tlg2300/pd-video.c | 59 |
5 files changed, 135 insertions, 269 deletions
diff --git a/Documentation/video4linux/README.tlg2300 b/Documentation/video4linux/README.tlg2300 index 82417db3256f..416ccb93d8c9 100644 --- a/Documentation/video4linux/README.tlg2300 +++ b/Documentation/video4linux/README.tlg2300 | |||
@@ -37,195 +37,11 @@ TESTED APPLICATIONS: | |||
37 | 37 | ||
38 | --------------------------------------------------------------------------- | 38 | --------------------------------------------------------------------------- |
39 | KNOWN PROBLEMS: | 39 | KNOWN PROBLEMS: |
40 | about preemphasis: | ||
41 | You can set the preemphasis for radio by the following command: | ||
42 | #v4l2-ctl -d /dev/radio0 --set-ctrl=pre_emphasis_settings=1 | ||
43 | |||
44 | "pre_emphasis_settings=1" means that you select the 50us. If you want | ||
45 | to select the 75us, please use "pre_emphasis_settings=2" | ||
46 | |||
40 | 47 | ||
41 | country code | ||
42 | - The firmware of the chip needs the country code to determine | ||
43 | the stardards of video and audio when it runs for analog TV or radio. | ||
44 | The DVB-T does not need the country code. | ||
45 | |||
46 | So you must set the country-code correctly. The V4L2 does not have | ||
47 | the interface,the driver has to provide a parameter `country_code'. | ||
48 | |||
49 | You could set the coutry code in two ways, take USA as example | ||
50 | (The USA's country code is 1): | ||
51 | |||
52 | [1] add the following line in /etc/modprobe.conf before you insert the | ||
53 | card into USB hub's port : | ||
54 | poseidon country_code=1 | ||
55 | |||
56 | [2] You can also modify the parameter at runtime (before you run the | ||
57 | application such as VLC) | ||
58 | #echo 1 > /sys/module/poseidon/parameter/country_code | ||
59 | |||
60 | The known country codes show below: | ||
61 | country code : country | ||
62 | 93 "Afghanistan" | ||
63 | 355 "Albania" | ||
64 | 213 "Algeria" | ||
65 | 684 "American Samoa" | ||
66 | 376 "Andorra" | ||
67 | 244 "Angola" | ||
68 | 54 "Argentina" | ||
69 | 374 "Armenia" | ||
70 | 61 "Australia" | ||
71 | 43 "Austria" | ||
72 | 994 "Azerbaijan" | ||
73 | 973 "Bahrain" | ||
74 | 880 "Bangladesh" | ||
75 | 375 "Belarus" | ||
76 | 32 "Belgium" | ||
77 | 501 "Belize" | ||
78 | 229 "Benin" | ||
79 | 591 "Bolivia" | ||
80 | 387 "Bosnia and Herzegovina" | ||
81 | 267 "Botswana" | ||
82 | 55 "Brazil" | ||
83 | 673 "Brunei Darussalam" | ||
84 | 359 "Bulgalia" | ||
85 | 226 "Burkina Faso" | ||
86 | 257 "Burundi" | ||
87 | 237 "Cameroon" | ||
88 | 1 "Canada" | ||
89 | 236 "Central African Republic" | ||
90 | 235 "Chad" | ||
91 | 56 "Chile" | ||
92 | 86 "China" | ||
93 | 57 "Colombia" | ||
94 | 242 "Congo" | ||
95 | 243 "Congo, Dem. Rep. of " | ||
96 | 506 "Costa Rica" | ||
97 | 385 "Croatia" | ||
98 | 53 "Cuba or Guantanamo Bay" | ||
99 | 357 "Cyprus" | ||
100 | 420 "Czech Republic" | ||
101 | 45 "Denmark" | ||
102 | 246 "Diego Garcia" | ||
103 | 253 "Djibouti" | ||
104 | 593 "Ecuador" | ||
105 | 20 "Egypt" | ||
106 | 503 "El Salvador" | ||
107 | 240 "Equatorial Guinea" | ||
108 | 372 "Estonia" | ||
109 | 251 "Ethiopia" | ||
110 | 358 "Finland" | ||
111 | 33 "France" | ||
112 | 594 "French Guiana" | ||
113 | 689 "French Polynesia" | ||
114 | 241 "Gabonese Republic" | ||
115 | 220 "Gambia" | ||
116 | 995 "Georgia" | ||
117 | 49 "Germany" | ||
118 | 233 "Ghana" | ||
119 | 350 "Gibraltar" | ||
120 | 30 "Greece" | ||
121 | 299 "Greenland" | ||
122 | 671 "Guam" | ||
123 | 502 "Guatemala" | ||
124 | 592 "Guyana" | ||
125 | 509 "Haiti" | ||
126 | 504 "Honduras" | ||
127 | 852 "Hong Kong SAR, China" | ||
128 | 36 "Hungary" | ||
129 | 354 "Iceland" | ||
130 | 91 "India" | ||
131 | 98 "Iran" | ||
132 | 964 "Iraq" | ||
133 | 353 "Ireland" | ||
134 | 972 "Israel" | ||
135 | 39 "Italy or Vatican City" | ||
136 | 225 "Ivory Coast" | ||
137 | 81 "Japan" | ||
138 | 962 "Jordan" | ||
139 | 7 "Kazakhstan or Kyrgyzstan" | ||
140 | 254 "Kenya" | ||
141 | 686 "Kiribati" | ||
142 | 965 "Kuwait" | ||
143 | 856 "Laos" | ||
144 | 371 "Latvia" | ||
145 | 961 "Lebanon" | ||
146 | 266 "Lesotho" | ||
147 | 231 "Liberia" | ||
148 | 218 "Libya" | ||
149 | 41 "Liechtenstein or Switzerland" | ||
150 | 370 "Lithuania" | ||
151 | 352 "Luxembourg" | ||
152 | 853 "Macau SAR, China" | ||
153 | 261 "Madagascar" | ||
154 | 60 "Malaysia" | ||
155 | 960 "Maldives" | ||
156 | 223 "Mali Republic" | ||
157 | 356 "Malta" | ||
158 | 692 "Marshall Islands" | ||
159 | 596 "Martinique" | ||
160 | 222 "Mauritania" | ||
161 | 230 "Mauritus" | ||
162 | 52 "Mexico" | ||
163 | 691 "Micronesia" | ||
164 | 373 "Moldova" | ||
165 | 377 "Monaco" | ||
166 | 976 "Mongolia" | ||
167 | 212 "Morocco" | ||
168 | 258 "Mozambique" | ||
169 | 95 "Myanmar" | ||
170 | 264 "Namibia" | ||
171 | 674 "Nauru" | ||
172 | 31 "Netherlands" | ||
173 | 687 "New Caledonia" | ||
174 | 64 "New Zealand" | ||
175 | 505 "Nicaragua" | ||
176 | 227 "Niger" | ||
177 | 234 "Nigeria" | ||
178 | 850 "North Korea" | ||
179 | 47 "Norway" | ||
180 | 968 "Oman" | ||
181 | 92 "Pakistan" | ||
182 | 680 "Palau" | ||
183 | 507 "Panama" | ||
184 | 675 "Papua New Guinea" | ||
185 | 595 "Paraguay" | ||
186 | 51 "Peru" | ||
187 | 63 "Philippines" | ||
188 | 48 "Poland" | ||
189 | 351 "Portugal" | ||
190 | 974 "Qatar" | ||
191 | 262 "Reunion Island" | ||
192 | 40 "Romania" | ||
193 | 7 "Russia" | ||
194 | 378 "San Marino" | ||
195 | 239 "Sao Tome and Principe" | ||
196 | 966 "Saudi Arabia" | ||
197 | 221 "Senegal" | ||
198 | 248 "Seychelles Republic" | ||
199 | 232 "Sierra Leone" | ||
200 | 65 "Singapore" | ||
201 | 421 "Slovak Republic" | ||
202 | 386 "Slovenia" | ||
203 | 27 "South Africa" | ||
204 | 82 "South Korea " | ||
205 | 34 "Spain" | ||
206 | 94 "Sri Lanka" | ||
207 | 508 "St. Pierre and Miquelon" | ||
208 | 249 "Sudan" | ||
209 | 597 "Suriname" | ||
210 | 268 "Swaziland" | ||
211 | 46 "Sweden" | ||
212 | 963 "Syria" | ||
213 | 886 "Taiwan Region" | ||
214 | 255 "Tanzania" | ||
215 | 66 "Thailand" | ||
216 | 228 "Togolese Republic" | ||
217 | 216 "Tunisia" | ||
218 | 90 "Turkey" | ||
219 | 993 "Turkmenistan" | ||
220 | 256 "Uganda" | ||
221 | 380 "Ukraine" | ||
222 | 971 "United Arab Emirates" | ||
223 | 44 "United Kingdom" | ||
224 | 1 "United States of America" | ||
225 | 598 "Uruguay" | ||
226 | 58 "Venezuela" | ||
227 | 84 "Vietnam" | ||
228 | 967 "Yemen" | ||
229 | 260 "Zambia" | ||
230 | 255 "Zanzibar" | ||
231 | 263 "Zimbabwe" | ||
diff --git a/drivers/media/video/tlg2300/pd-common.h b/drivers/media/video/tlg2300/pd-common.h index 619fd009e965..ae9cb6c581ac 100644 --- a/drivers/media/video/tlg2300/pd-common.h +++ b/drivers/media/video/tlg2300/pd-common.h | |||
@@ -118,6 +118,7 @@ struct radio_data { | |||
118 | __u32 fm_freq; | 118 | __u32 fm_freq; |
119 | int users; | 119 | int users; |
120 | unsigned int is_radio_streaming; | 120 | unsigned int is_radio_streaming; |
121 | int pre_emphasis; | ||
121 | struct video_device *fm_dev; | 122 | struct video_device *fm_dev; |
122 | }; | 123 | }; |
123 | 124 | ||
@@ -185,7 +186,6 @@ struct poseidon { | |||
185 | struct pd_dvb_adapter dvb_data; /* DVB */ | 186 | struct pd_dvb_adapter dvb_data; /* DVB */ |
186 | 187 | ||
187 | u32 state; | 188 | u32 state; |
188 | int country_code; | ||
189 | struct file *file_for_stream; /* the active stream*/ | 189 | struct file *file_for_stream; /* the active stream*/ |
190 | 190 | ||
191 | #ifdef CONFIG_PM | 191 | #ifdef CONFIG_PM |
@@ -240,7 +240,6 @@ struct video_device *vdev_init(struct poseidon *, struct video_device *); | |||
240 | int send_set_req(struct poseidon*, u8, s32, s32*); | 240 | int send_set_req(struct poseidon*, u8, s32, s32*); |
241 | int send_get_req(struct poseidon*, u8, s32, void*, s32*, s32); | 241 | int send_get_req(struct poseidon*, u8, s32, void*, s32*, s32); |
242 | s32 set_tuner_mode(struct poseidon*, unsigned char); | 242 | s32 set_tuner_mode(struct poseidon*, unsigned char); |
243 | enum tlg__analog_audio_standard get_audio_std(s32, s32); | ||
244 | 243 | ||
245 | /* bulk urb alloc/free */ | 244 | /* bulk urb alloc/free */ |
246 | int alloc_bulk_urbs_generic(struct urb **urb_array, int num, | 245 | int alloc_bulk_urbs_generic(struct urb **urb_array, int num, |
@@ -252,7 +251,6 @@ void free_all_urb_generic(struct urb **urb_array, int num); | |||
252 | /* misc */ | 251 | /* misc */ |
253 | void poseidon_delete(struct kref *kref); | 252 | void poseidon_delete(struct kref *kref); |
254 | void destroy_video_device(struct video_device **v_dev); | 253 | void destroy_video_device(struct video_device **v_dev); |
255 | extern int country_code; | ||
256 | extern int debug_mode; | 254 | extern int debug_mode; |
257 | void set_debug_mode(struct video_device *vfd, int debug_mode); | 255 | void set_debug_mode(struct video_device *vfd, int debug_mode); |
258 | 256 | ||
diff --git a/drivers/media/video/tlg2300/pd-main.c b/drivers/media/video/tlg2300/pd-main.c index 6df93803e3a8..fdcc5007a701 100644 --- a/drivers/media/video/tlg2300/pd-main.c +++ b/drivers/media/video/tlg2300/pd-main.c | |||
@@ -189,41 +189,6 @@ int set_tuner_mode(struct poseidon *pd, unsigned char mode) | |||
189 | return 0; | 189 | return 0; |
190 | } | 190 | } |
191 | 191 | ||
192 | enum tlg__analog_audio_standard get_audio_std(s32 mode, s32 country_code) | ||
193 | { | ||
194 | s32 nicam[] = {27, 32, 33, 34, 36, 44, 45, 46, 47, 48, 64, | ||
195 | 65, 86, 351, 352, 353, 354, 358, 372, 852, 972}; | ||
196 | s32 btsc[] = {1, 52, 54, 55, 886}; | ||
197 | s32 eiaj[] = {81}; | ||
198 | s32 i; | ||
199 | |||
200 | if (mode == TLG_MODE_FM_RADIO) { | ||
201 | if (country_code == 1) | ||
202 | return TLG_TUNE_ASTD_FM_US; | ||
203 | else | ||
204 | return TLG_TUNE_ASTD_FM_EUR; | ||
205 | } else if (mode == TLG_MODE_ANALOG_TV_UNCOMP) { | ||
206 | for (i = 0; i < sizeof(nicam) / sizeof(s32); i++) { | ||
207 | if (country_code == nicam[i]) | ||
208 | return TLG_TUNE_ASTD_NICAM; | ||
209 | } | ||
210 | |||
211 | for (i = 0; i < sizeof(btsc) / sizeof(s32); i++) { | ||
212 | if (country_code == btsc[i]) | ||
213 | return TLG_TUNE_ASTD_BTSC; | ||
214 | } | ||
215 | |||
216 | for (i = 0; i < sizeof(eiaj) / sizeof(s32); i++) { | ||
217 | if (country_code == eiaj[i]) | ||
218 | return TLG_TUNE_ASTD_EIAJ; | ||
219 | } | ||
220 | |||
221 | return TLG_TUNE_ASTD_A2; | ||
222 | } else { | ||
223 | return TLG_TUNE_ASTD_NONE; | ||
224 | } | ||
225 | } | ||
226 | |||
227 | void poseidon_delete(struct kref *kref) | 192 | void poseidon_delete(struct kref *kref) |
228 | { | 193 | { |
229 | struct poseidon *pd = container_of(kref, struct poseidon, kref); | 194 | struct poseidon *pd = container_of(kref, struct poseidon, kref); |
@@ -462,7 +427,6 @@ static int poseidon_probe(struct usb_interface *interface, | |||
462 | struct device *dev = &interface->dev; | 427 | struct device *dev = &interface->dev; |
463 | 428 | ||
464 | logpm(pd); | 429 | logpm(pd); |
465 | pd->country_code = 86; | ||
466 | mutex_init(&pd->lock); | 430 | mutex_init(&pd->lock); |
467 | 431 | ||
468 | /* register v4l2 device */ | 432 | /* register v4l2 device */ |
diff --git a/drivers/media/video/tlg2300/pd-radio.c b/drivers/media/video/tlg2300/pd-radio.c index bdbb0c11b3a9..755766b15157 100644 --- a/drivers/media/video/tlg2300/pd-radio.c +++ b/drivers/media/video/tlg2300/pd-radio.c | |||
@@ -22,9 +22,16 @@ static int poseidon_fm_open(struct file *filp); | |||
22 | #define TUNER_FREQ_MIN_FM 76000000 | 22 | #define TUNER_FREQ_MIN_FM 76000000 |
23 | #define TUNER_FREQ_MAX_FM 108000000 | 23 | #define TUNER_FREQ_MAX_FM 108000000 |
24 | 24 | ||
25 | #define MAX_PREEMPHASIS (V4L2_PREEMPHASIS_75_uS + 1) | ||
26 | static int preemphasis[MAX_PREEMPHASIS] = { | ||
27 | TLG_TUNE_ASTD_NONE, /* V4L2_PREEMPHASIS_DISABLED */ | ||
28 | TLG_TUNE_ASTD_FM_EUR, /* V4L2_PREEMPHASIS_50_uS */ | ||
29 | TLG_TUNE_ASTD_FM_US, /* V4L2_PREEMPHASIS_75_uS */ | ||
30 | }; | ||
31 | |||
25 | static int poseidon_check_mode_radio(struct poseidon *p) | 32 | static int poseidon_check_mode_radio(struct poseidon *p) |
26 | { | 33 | { |
27 | int ret, radiomode; | 34 | int ret; |
28 | u32 status; | 35 | u32 status; |
29 | 36 | ||
30 | set_current_state(TASK_INTERRUPTIBLE); | 37 | set_current_state(TASK_INTERRUPTIBLE); |
@@ -38,8 +45,8 @@ static int poseidon_check_mode_radio(struct poseidon *p) | |||
38 | goto out; | 45 | goto out; |
39 | 46 | ||
40 | ret = send_set_req(p, SGNL_SRC_SEL, TLG_SIG_SRC_ANTENNA, &status); | 47 | ret = send_set_req(p, SGNL_SRC_SEL, TLG_SIG_SRC_ANTENNA, &status); |
41 | radiomode = get_audio_std(TLG_MODE_FM_RADIO, p->country_code); | 48 | ret = send_set_req(p, TUNER_AUD_ANA_STD, |
42 | ret = send_set_req(p, TUNER_AUD_ANA_STD, radiomode, &status); | 49 | p->radio_data.pre_emphasis, &status); |
43 | ret |= send_set_req(p, TUNER_AUD_MODE, | 50 | ret |= send_set_req(p, TUNER_AUD_MODE, |
44 | TLG_TUNE_TVAUDIO_MODE_STEREO, &status); | 51 | TLG_TUNE_TVAUDIO_MODE_STEREO, &status); |
45 | ret |= send_set_req(p, AUDIO_SAMPLE_RATE_SEL, | 52 | ret |= send_set_req(p, AUDIO_SAMPLE_RATE_SEL, |
@@ -91,7 +98,9 @@ static int poseidon_fm_open(struct file *filp) | |||
91 | 98 | ||
92 | usb_autopm_get_interface(p->interface); | 99 | usb_autopm_get_interface(p->interface); |
93 | if (0 == p->state) { | 100 | if (0 == p->state) { |
94 | p->country_code = country_code; | 101 | /* default pre-emphasis */ |
102 | if (p->radio_data.pre_emphasis == 0) | ||
103 | p->radio_data.pre_emphasis = TLG_TUNE_ASTD_FM_EUR; | ||
95 | set_debug_mode(vfd, debug_mode); | 104 | set_debug_mode(vfd, debug_mode); |
96 | 105 | ||
97 | ret = poseidon_check_mode_radio(p); | 106 | ret = poseidon_check_mode_radio(p); |
@@ -205,13 +214,12 @@ int fm_get_freq(struct file *file, void *priv, struct v4l2_frequency *argp) | |||
205 | static int set_frequency(struct poseidon *p, __u32 frequency) | 214 | static int set_frequency(struct poseidon *p, __u32 frequency) |
206 | { | 215 | { |
207 | __u32 freq ; | 216 | __u32 freq ; |
208 | int ret, status, radiomode; | 217 | int ret, status; |
209 | 218 | ||
210 | mutex_lock(&p->lock); | 219 | mutex_lock(&p->lock); |
211 | 220 | ||
212 | radiomode = get_audio_std(TLG_MODE_FM_RADIO, p->country_code); | 221 | ret = send_set_req(p, TUNER_AUD_ANA_STD, |
213 | /*NTSC 8,PAL 2 */ | 222 | p->radio_data.pre_emphasis, &status); |
214 | ret = send_set_req(p, TUNER_AUD_ANA_STD, radiomode, &status); | ||
215 | 223 | ||
216 | freq = (frequency * 125) * 500 / 1000;/* kHZ */ | 224 | freq = (frequency * 125) * 500 / 1000;/* kHZ */ |
217 | if (freq < TUNER_FREQ_MIN_FM/1000 || freq > TUNER_FREQ_MAX_FM/1000) { | 225 | if (freq < TUNER_FREQ_MIN_FM/1000 || freq > TUNER_FREQ_MAX_FM/1000) { |
@@ -253,27 +261,86 @@ int fm_set_freq(struct file *file, void *priv, struct v4l2_frequency *argp) | |||
253 | int tlg_fm_vidioc_g_ctrl(struct file *file, void *priv, | 261 | int tlg_fm_vidioc_g_ctrl(struct file *file, void *priv, |
254 | struct v4l2_control *arg) | 262 | struct v4l2_control *arg) |
255 | { | 263 | { |
256 | return 0; | 264 | return 0; |
265 | } | ||
266 | |||
267 | int tlg_fm_vidioc_g_exts_ctrl(struct file *file, void *fh, | ||
268 | struct v4l2_ext_controls *ctrls) | ||
269 | { | ||
270 | struct poseidon *p = file->private_data; | ||
271 | int i; | ||
272 | |||
273 | if (ctrls->ctrl_class != V4L2_CTRL_CLASS_FM_TX) | ||
274 | return -EINVAL; | ||
275 | |||
276 | for (i = 0; i < ctrls->count; i++) { | ||
277 | struct v4l2_ext_control *ctrl = ctrls->controls + i; | ||
278 | |||
279 | if (ctrl->id != V4L2_CID_TUNE_PREEMPHASIS) | ||
280 | continue; | ||
281 | |||
282 | if (i < MAX_PREEMPHASIS) | ||
283 | ctrl->value = p->radio_data.pre_emphasis; | ||
284 | } | ||
285 | return 0; | ||
257 | } | 286 | } |
258 | 287 | ||
259 | int tlg_fm_vidioc_exts_ctrl(struct file *file, void *fh, | 288 | int tlg_fm_vidioc_s_exts_ctrl(struct file *file, void *fh, |
260 | struct v4l2_ext_controls *a) | 289 | struct v4l2_ext_controls *ctrls) |
261 | { | 290 | { |
262 | return 0; | 291 | int i; |
292 | |||
293 | if (ctrls->ctrl_class != V4L2_CTRL_CLASS_FM_TX) | ||
294 | return -EINVAL; | ||
295 | |||
296 | for (i = 0; i < ctrls->count; i++) { | ||
297 | struct v4l2_ext_control *ctrl = ctrls->controls + i; | ||
298 | |||
299 | if (ctrl->id != V4L2_CID_TUNE_PREEMPHASIS) | ||
300 | continue; | ||
301 | |||
302 | if (ctrl->value >= 0 && ctrl->value < MAX_PREEMPHASIS) { | ||
303 | struct poseidon *p = file->private_data; | ||
304 | int pre_emphasis = preemphasis[ctrl->value]; | ||
305 | u32 status; | ||
306 | |||
307 | send_set_req(p, TUNER_AUD_ANA_STD, | ||
308 | pre_emphasis, &status); | ||
309 | p->radio_data.pre_emphasis = pre_emphasis; | ||
310 | } | ||
311 | } | ||
312 | return 0; | ||
263 | } | 313 | } |
264 | 314 | ||
265 | int tlg_fm_vidioc_s_ctrl(struct file *file, void *priv, | 315 | int tlg_fm_vidioc_s_ctrl(struct file *file, void *priv, |
266 | struct v4l2_control *arg) | 316 | struct v4l2_control *ctrl) |
267 | { | 317 | { |
268 | return 0; | 318 | return 0; |
269 | } | 319 | } |
270 | 320 | ||
271 | int tlg_fm_vidioc_queryctrl(struct file *file, void *priv, | 321 | int tlg_fm_vidioc_queryctrl(struct file *file, void *priv, |
272 | struct v4l2_queryctrl *arg) | 322 | struct v4l2_queryctrl *ctrl) |
273 | { | 323 | { |
274 | arg->minimum = 0; | 324 | if (!(ctrl->id & V4L2_CTRL_FLAG_NEXT_CTRL)) |
275 | arg->maximum = 65535; | 325 | return -EINVAL; |
276 | return 0; | 326 | |
327 | ctrl->id &= ~V4L2_CTRL_FLAG_NEXT_CTRL; | ||
328 | if (ctrl->id != V4L2_CID_TUNE_PREEMPHASIS) { | ||
329 | /* return the next supported control */ | ||
330 | ctrl->id = V4L2_CID_TUNE_PREEMPHASIS; | ||
331 | v4l2_ctrl_query_fill(ctrl, V4L2_PREEMPHASIS_DISABLED, | ||
332 | V4L2_PREEMPHASIS_75_uS, 1, | ||
333 | V4L2_PREEMPHASIS_50_uS); | ||
334 | ctrl->flags = V4L2_CTRL_FLAG_UPDATE; | ||
335 | return 0; | ||
336 | } | ||
337 | return -EINVAL; | ||
338 | } | ||
339 | |||
340 | int tlg_fm_vidioc_querymenu(struct file *file, void *fh, | ||
341 | struct v4l2_querymenu *qmenu) | ||
342 | { | ||
343 | return v4l2_ctrl_query_menu(qmenu, NULL, NULL); | ||
277 | } | 344 | } |
278 | 345 | ||
279 | static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *vt) | 346 | static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *vt) |
@@ -311,9 +378,11 @@ static const struct v4l2_ioctl_ops poseidon_fm_ioctl_ops = { | |||
311 | .vidioc_g_input = vidioc_g_input, | 378 | .vidioc_g_input = vidioc_g_input, |
312 | .vidioc_s_input = vidioc_s_input, | 379 | .vidioc_s_input = vidioc_s_input, |
313 | .vidioc_queryctrl = tlg_fm_vidioc_queryctrl, | 380 | .vidioc_queryctrl = tlg_fm_vidioc_queryctrl, |
381 | .vidioc_querymenu = tlg_fm_vidioc_querymenu, | ||
314 | .vidioc_g_ctrl = tlg_fm_vidioc_g_ctrl, | 382 | .vidioc_g_ctrl = tlg_fm_vidioc_g_ctrl, |
315 | .vidioc_s_ctrl = tlg_fm_vidioc_s_ctrl, | 383 | .vidioc_s_ctrl = tlg_fm_vidioc_s_ctrl, |
316 | .vidioc_s_ext_ctrls = tlg_fm_vidioc_exts_ctrl, | 384 | .vidioc_s_ext_ctrls = tlg_fm_vidioc_s_exts_ctrl, |
385 | .vidioc_g_ext_ctrls = tlg_fm_vidioc_g_exts_ctrl, | ||
317 | .vidioc_s_tuner = vidioc_s_tuner, | 386 | .vidioc_s_tuner = vidioc_s_tuner, |
318 | .vidioc_g_tuner = tlg_fm_vidioc_g_tuner, | 387 | .vidioc_g_tuner = tlg_fm_vidioc_g_tuner, |
319 | .vidioc_g_frequency = fm_get_freq, | 388 | .vidioc_g_frequency = fm_get_freq, |
diff --git a/drivers/media/video/tlg2300/pd-video.c b/drivers/media/video/tlg2300/pd-video.c index 5f0300ac465c..becfba6a3041 100644 --- a/drivers/media/video/tlg2300/pd-video.c +++ b/drivers/media/video/tlg2300/pd-video.c | |||
@@ -15,10 +15,6 @@ static int pm_video_suspend(struct poseidon *pd); | |||
15 | static int pm_video_resume(struct poseidon *pd); | 15 | static int pm_video_resume(struct poseidon *pd); |
16 | static void iso_bubble_handler(struct work_struct *w); | 16 | static void iso_bubble_handler(struct work_struct *w); |
17 | 17 | ||
18 | int country_code = 86; | ||
19 | module_param(country_code, int, 0644); | ||
20 | MODULE_PARM_DESC(country_code, "country code (e.g China is 86)"); | ||
21 | |||
22 | int usb_transfer_mode; | 18 | int usb_transfer_mode; |
23 | module_param(usb_transfer_mode, int, 0644); | 19 | module_param(usb_transfer_mode, int, 0644); |
24 | MODULE_PARM_DESC(usb_transfer_mode, "0 = Bulk, 1 = Isochronous"); | 20 | MODULE_PARM_DESC(usb_transfer_mode, "0 = Bulk, 1 = Isochronous"); |
@@ -93,27 +89,53 @@ static struct poseidon_control controls[] = { | |||
93 | { V4L2_CID_BRIGHTNESS, V4L2_CTRL_TYPE_INTEGER, | 89 | { V4L2_CID_BRIGHTNESS, V4L2_CTRL_TYPE_INTEGER, |
94 | "brightness", 0, 10000, 1, 100, 0, }, | 90 | "brightness", 0, 10000, 1, 100, 0, }, |
95 | CUST_PARM_ID_BRIGHTNESS_CTRL | 91 | CUST_PARM_ID_BRIGHTNESS_CTRL |
96 | }, | 92 | }, { |
97 | |||
98 | { | ||
99 | { V4L2_CID_CONTRAST, V4L2_CTRL_TYPE_INTEGER, | 93 | { V4L2_CID_CONTRAST, V4L2_CTRL_TYPE_INTEGER, |
100 | "contrast", 0, 10000, 1, 100, 0, }, | 94 | "contrast", 0, 10000, 1, 100, 0, }, |
101 | CUST_PARM_ID_CONTRAST_CTRL, | 95 | CUST_PARM_ID_CONTRAST_CTRL, |
102 | }, | 96 | }, { |
103 | |||
104 | { | ||
105 | { V4L2_CID_HUE, V4L2_CTRL_TYPE_INTEGER, | 97 | { V4L2_CID_HUE, V4L2_CTRL_TYPE_INTEGER, |
106 | "hue", 0, 10000, 1, 100, 0, }, | 98 | "hue", 0, 10000, 1, 100, 0, }, |
107 | CUST_PARM_ID_HUE_CTRL, | 99 | CUST_PARM_ID_HUE_CTRL, |
108 | }, | 100 | }, { |
109 | |||
110 | { | ||
111 | { V4L2_CID_SATURATION, V4L2_CTRL_TYPE_INTEGER, | 101 | { V4L2_CID_SATURATION, V4L2_CTRL_TYPE_INTEGER, |
112 | "saturation", 0, 10000, 1, 100, 0, }, | 102 | "saturation", 0, 10000, 1, 100, 0, }, |
113 | CUST_PARM_ID_SATURATION_CTRL, | 103 | CUST_PARM_ID_SATURATION_CTRL, |
114 | }, | 104 | }, |
115 | }; | 105 | }; |
116 | 106 | ||
107 | struct video_std_to_audio_std { | ||
108 | v4l2_std_id video_std; | ||
109 | int audio_std; | ||
110 | }; | ||
111 | |||
112 | static const struct video_std_to_audio_std video_to_audio_map[] = { | ||
113 | /* country : { 27, 32, 33, 34, 36, 44, 45, 46, 47, 48, 64, | ||
114 | 65, 86, 351, 352, 353, 354, 358, 372, 852, 972 } */ | ||
115 | { (V4L2_STD_PAL_I | V4L2_STD_PAL_B | V4L2_STD_PAL_D | | ||
116 | V4L2_STD_SECAM_L | V4L2_STD_SECAM_D), TLG_TUNE_ASTD_NICAM }, | ||
117 | |||
118 | /* country : { 1, 52, 54, 55, 886 } */ | ||
119 | {V4L2_STD_NTSC_M | V4L2_STD_PAL_N | V4L2_STD_PAL_M, TLG_TUNE_ASTD_BTSC}, | ||
120 | |||
121 | /* country : { 81 } */ | ||
122 | { V4L2_STD_NTSC_M_JP, TLG_TUNE_ASTD_EIAJ }, | ||
123 | |||
124 | /* other country : TLG_TUNE_ASTD_A2 */ | ||
125 | }; | ||
126 | static const unsigned int map_size = ARRAY_SIZE(video_to_audio_map); | ||
127 | |||
128 | static int get_audio_std(v4l2_std_id v4l2_std) | ||
129 | { | ||
130 | int i = 0; | ||
131 | |||
132 | for (; i < map_size; i++) { | ||
133 | if (v4l2_std & video_to_audio_map[i].video_std) | ||
134 | return video_to_audio_map[i].audio_std; | ||
135 | } | ||
136 | return TLG_TUNE_ASTD_A2; | ||
137 | } | ||
138 | |||
117 | static int vidioc_querycap(struct file *file, void *fh, | 139 | static int vidioc_querycap(struct file *file, void *fh, |
118 | struct v4l2_capability *cap) | 140 | struct v4l2_capability *cap) |
119 | { | 141 | { |
@@ -1067,7 +1089,7 @@ static int pd_vidioc_s_tuner(struct poseidon *pd, int index) | |||
1067 | mutex_lock(&pd->lock); | 1089 | mutex_lock(&pd->lock); |
1068 | param = pd_audio_modes[index].tlg_audio_mode; | 1090 | param = pd_audio_modes[index].tlg_audio_mode; |
1069 | ret = send_set_req(pd, TUNER_AUD_MODE, param, &cmd_status); | 1091 | ret = send_set_req(pd, TUNER_AUD_MODE, param, &cmd_status); |
1070 | audiomode = get_audio_std(TLG_MODE_ANALOG_TV, pd->country_code); | 1092 | audiomode = get_audio_std(pd->video_data.context.tvnormid); |
1071 | ret |= send_set_req(pd, TUNER_AUD_ANA_STD, audiomode, | 1093 | ret |= send_set_req(pd, TUNER_AUD_ANA_STD, audiomode, |
1072 | &cmd_status); | 1094 | &cmd_status); |
1073 | if (!ret) | 1095 | if (!ret) |
@@ -1255,9 +1277,7 @@ static int vidioc_streamoff(struct file *file, void *fh, | |||
1255 | return videobuf_streamoff(&front->q); | 1277 | return videobuf_streamoff(&front->q); |
1256 | } | 1278 | } |
1257 | 1279 | ||
1258 | /* | 1280 | /* Set the firmware's default values : need altersetting */ |
1259 | * Set the firmware' default values : need altersetting and country code | ||
1260 | */ | ||
1261 | static int pd_video_checkmode(struct poseidon *pd) | 1281 | static int pd_video_checkmode(struct poseidon *pd) |
1262 | { | 1282 | { |
1263 | s32 ret = 0, cmd_status, audiomode; | 1283 | s32 ret = 0, cmd_status, audiomode; |
@@ -1286,8 +1306,8 @@ static int pd_video_checkmode(struct poseidon *pd) | |||
1286 | ret |= send_set_req(pd, TUNE_FREQ_SELECT, TUNER_FREQ_MIN, &cmd_status); | 1306 | ret |= send_set_req(pd, TUNE_FREQ_SELECT, TUNER_FREQ_MIN, &cmd_status); |
1287 | ret |= send_set_req(pd, VBI_DATA_SEL, 1, &cmd_status);/* enable vbi */ | 1307 | ret |= send_set_req(pd, VBI_DATA_SEL, 1, &cmd_status);/* enable vbi */ |
1288 | 1308 | ||
1289 | /* need country code to set the audio */ | 1309 | /* set the audio */ |
1290 | audiomode = get_audio_std(TLG_MODE_ANALOG_TV, pd->country_code); | 1310 | audiomode = get_audio_std(pd->video_data.context.tvnormid); |
1291 | ret |= send_set_req(pd, TUNER_AUD_ANA_STD, audiomode, &cmd_status); | 1311 | ret |= send_set_req(pd, TUNER_AUD_ANA_STD, audiomode, &cmd_status); |
1292 | ret |= send_set_req(pd, TUNER_AUD_MODE, | 1312 | ret |= send_set_req(pd, TUNER_AUD_MODE, |
1293 | TLG_TUNE_TVAUDIO_MODE_STEREO, &cmd_status); | 1313 | TLG_TUNE_TVAUDIO_MODE_STEREO, &cmd_status); |
@@ -1392,7 +1412,6 @@ static int pd_video_open(struct file *file) | |||
1392 | goto out; | 1412 | goto out; |
1393 | 1413 | ||
1394 | pd->cur_transfer_mode = usb_transfer_mode;/* bulk or iso */ | 1414 | pd->cur_transfer_mode = usb_transfer_mode;/* bulk or iso */ |
1395 | pd->country_code = country_code; | ||
1396 | init_video_context(&pd->video_data.context); | 1415 | init_video_context(&pd->video_data.context); |
1397 | 1416 | ||
1398 | ret = pd_video_checkmode(pd); | 1417 | ret = pd_video_checkmode(pd); |