aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/radio/radio-sf16fmr2.c102
1 files changed, 39 insertions, 63 deletions
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c
index ebc5fbbc38bb..7bf7d534c042 100644
--- a/drivers/media/radio/radio-sf16fmr2.c
+++ b/drivers/media/radio/radio-sf16fmr2.c
@@ -29,6 +29,8 @@ static struct mutex lock;
29#include <linux/version.h> /* for KERNEL_VERSION MACRO */ 29#include <linux/version.h> /* for KERNEL_VERSION MACRO */
30#define RADIO_VERSION KERNEL_VERSION(0,0,2) 30#define RADIO_VERSION KERNEL_VERSION(0,0,2)
31 31
32#define AUD_VOL_INDEX 1
33
32static struct v4l2_queryctrl radio_qctrl[] = { 34static struct v4l2_queryctrl radio_qctrl[] = {
33 { 35 {
34 .id = V4L2_CID_AUDIO_MUTE, 36 .id = V4L2_CID_AUDIO_MUTE,
@@ -37,13 +39,14 @@ static struct v4l2_queryctrl radio_qctrl[] = {
37 .maximum = 1, 39 .maximum = 1,
38 .default_value = 1, 40 .default_value = 1,
39 .type = V4L2_CTRL_TYPE_BOOLEAN, 41 .type = V4L2_CTRL_TYPE_BOOLEAN,
40 },{ 42 },
43 [AUD_VOL_INDEX] = {
41 .id = V4L2_CID_AUDIO_VOLUME, 44 .id = V4L2_CID_AUDIO_VOLUME,
42 .name = "Volume", 45 .name = "Volume",
43 .minimum = 0, 46 .minimum = 0,
44 .maximum = 65535, 47 .maximum = 15,
45 .step = 1<<12, 48 .step = 1,
46 .default_value = 0xff, 49 .default_value = 0,
47 .type = V4L2_CTRL_TYPE_INTEGER, 50 .type = V4L2_CTRL_TYPE_INTEGER,
48 } 51 }
49}; 52};
@@ -61,7 +64,7 @@ static struct v4l2_queryctrl radio_qctrl[] = {
61struct fmr2_device 64struct fmr2_device
62{ 65{
63 int port; 66 int port;
64 int curvol; /* 0-65535, if not volume 0 or 65535 */ 67 int curvol; /* 0-15 */
65 int mute; 68 int mute;
66 int stereo; /* card is producing stereo audio */ 69 int stereo; /* card is producing stereo audio */
67 unsigned long curfreq; /* freq in kHz */ 70 unsigned long curfreq; /* freq in kHz */
@@ -176,51 +179,35 @@ static int fmr2_setfreq(struct fmr2_device *dev)
176/* !!! not tested, in my card this does't work !!! */ 179/* !!! not tested, in my card this does't work !!! */
177static int fmr2_setvolume(struct fmr2_device *dev) 180static int fmr2_setvolume(struct fmr2_device *dev)
178{ 181{
179 int i,a,n, port = dev->port; 182 int vol[16] = { 0x021, 0x084, 0x090, 0x104,
183 0x110, 0x204, 0x210, 0x402,
184 0x404, 0x408, 0x410, 0x801,
185 0x802, 0x804, 0x808, 0x810 };
186 int i, a, port = dev->port;
187 int n = vol[dev->curvol & 0x0f];
180 188
181 if (dev->card_type != 11) return 1; 189 if (dev->card_type != 11)
190 return 1;
182 191
183 switch( (dev->curvol+(1<<11)) >> 12 ) 192 for (i = 12; --i >= 0; ) {
184 {
185 case 0: case 1: n = 0x21; break;
186 case 2: n = 0x84; break;
187 case 3: n = 0x90; break;
188 case 4: n = 0x104; break;
189 case 5: n = 0x110; break;
190 case 6: n = 0x204; break;
191 case 7: n = 0x210; break;
192 case 8: n = 0x402; break;
193 case 9: n = 0x404; break;
194 default:
195 case 10: n = 0x408; break;
196 case 11: n = 0x410; break;
197 case 12: n = 0x801; break;
198 case 13: n = 0x802; break;
199 case 14: n = 0x804; break;
200 case 15: n = 0x808; break;
201 case 16: n = 0x810; break;
202 }
203 for(i=12;--i>=0;)
204 {
205 a = ((n >> i) & 1) << 6; /* if (a=0) a= 0; else a= 0x40; */ 193 a = ((n >> i) & 1) << 6; /* if (a=0) a= 0; else a= 0x40; */
206 outb(a|4, port); 194 outb(a | 4, port);
207 wait(4,port); 195 wait(4, port);
208 outb(a|0x24, port); 196 outb(a | 0x24, port);
209 wait(4,port); 197 wait(4, port);
210 outb(a|4, port); 198 outb(a | 4, port);
211 wait(4,port); 199 wait(4, port);
212 } 200 }
213 for(i=6;--i>=0;) 201 for (i = 6; --i >= 0; ) {
214 {
215 a = ((0x18 >> i) & 1) << 6; 202 a = ((0x18 >> i) & 1) << 6;
216 outb(a|4, port); 203 outb(a | 4, port);
217 wait(4,port); 204 wait(4,port);
218 outb(a|0x24, port); 205 outb(a | 0x24, port);
219 wait(4,port); 206 wait(4,port);
220 outb(a|4, port); 207 outb(a|4, port);
221 wait(4,port); 208 wait(4,port);
222 } 209 }
223 wait(4,port); 210 wait(4, port);
224 outb(0x14, port); 211 outb(0x14, port);
225 212
226 return 0; 213 return 0;
@@ -312,16 +299,10 @@ static int vidioc_queryctrl(struct file *file, void *priv,
312 struct v4l2_queryctrl *qc) 299 struct v4l2_queryctrl *qc)
313{ 300{
314 int i; 301 int i;
315 struct video_device *dev = video_devdata(file);
316 struct fmr2_device *fmr2 = dev->priv;
317 302
318 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { 303 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
319 if ((fmr2->card_type != 11)
320 && V4L2_CID_AUDIO_VOLUME)
321 radio_qctrl[i].step = 65535;
322 if (qc->id && qc->id == radio_qctrl[i].id) { 304 if (qc->id && qc->id == radio_qctrl[i].id) {
323 memcpy(qc, &(radio_qctrl[i]), 305 memcpy(qc, &radio_qctrl[i], sizeof(*qc));
324 sizeof(*qc));
325 return 0; 306 return 0;
326 } 307 }
327 } 308 }
@@ -354,24 +335,13 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
354 switch (ctrl->id) { 335 switch (ctrl->id) {
355 case V4L2_CID_AUDIO_MUTE: 336 case V4L2_CID_AUDIO_MUTE:
356 fmr2->mute = ctrl->value; 337 fmr2->mute = ctrl->value;
357 if (fmr2->card_type != 11) {
358 if (!fmr2->mute)
359 fmr2->curvol = 65535;
360 else
361 fmr2->curvol = 0;
362 }
363 break; 338 break;
364 case V4L2_CID_AUDIO_VOLUME: 339 case V4L2_CID_AUDIO_VOLUME:
365 fmr2->curvol = ctrl->value; 340 if (ctrl->value > radio_qctrl[AUD_VOL_INDEX].maximum)
366 if (fmr2->card_type != 11) { 341 fmr2->curvol = radio_qctrl[AUD_VOL_INDEX].maximum;
367 if (fmr2->curvol) { 342 else
368 fmr2->curvol = 65535; 343 fmr2->curvol = ctrl->value;
369 fmr2->mute = 0; 344
370 } else {
371 fmr2->curvol = 0;
372 fmr2->mute = 1;
373 }
374 }
375 break; 345 break;
376 default: 346 default:
377 return -EINVAL; 347 return -EINVAL;
@@ -387,6 +357,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
387 mutex_lock(&lock); 357 mutex_lock(&lock);
388 if (fmr2->curvol && !fmr2->mute) { 358 if (fmr2->curvol && !fmr2->mute) {
389 fmr2_setvolume(fmr2); 359 fmr2_setvolume(fmr2);
360 /* Set frequency and unmute card */
390 fmr2_setfreq(fmr2); 361 fmr2_setfreq(fmr2);
391 } else 362 } else
392 fmr2_mute(fmr2->port); 363 fmr2_mute(fmr2->port);
@@ -487,6 +458,11 @@ static int __init fmr2_init(void)
487 fmr2_product_info(&fmr2_unit); 458 fmr2_product_info(&fmr2_unit);
488 mutex_unlock(&lock); 459 mutex_unlock(&lock);
489 debug_print((KERN_DEBUG "card_type %d\n", fmr2_unit.card_type)); 460 debug_print((KERN_DEBUG "card_type %d\n", fmr2_unit.card_type));
461
462 /* Only card_type == 11 implements volume */
463 if (fmr2_unit.card_type != 11)
464 radio_qctrl[AUD_VOL_INDEX].maximum = 1;
465
490 return 0; 466 return 0;
491} 467}
492 468