diff options
Diffstat (limited to 'drivers/media/radio/radio-sf16fmi.c')
-rw-r--r-- | drivers/media/radio/radio-sf16fmi.c | 41 |
1 files changed, 21 insertions, 20 deletions
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c index 53073b424107..efee6e339d15 100644 --- a/drivers/media/radio/radio-sf16fmi.c +++ b/drivers/media/radio/radio-sf16fmi.c | |||
@@ -12,7 +12,7 @@ | |||
12 | * Frequency control is done digitally -- ie out(port,encodefreq(95.8)); | 12 | * Frequency control is done digitally -- ie out(port,encodefreq(95.8)); |
13 | * No volume control - only mute/unmute - you have to use line volume | 13 | * No volume control - only mute/unmute - you have to use line volume |
14 | * control on SB-part of SF16FMI | 14 | * control on SB-part of SF16FMI |
15 | * | 15 | * |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/kernel.h> /* __setup */ | 18 | #include <linux/kernel.h> /* __setup */ |
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/ioport.h> /* request_region */ | 21 | #include <linux/ioport.h> /* request_region */ |
22 | #include <linux/delay.h> /* udelay */ | 22 | #include <linux/delay.h> /* udelay */ |
23 | #include <linux/videodev.h> /* kernel radio structs */ | 23 | #include <linux/videodev.h> /* kernel radio structs */ |
24 | #include <media/v4l2-common.h> | ||
24 | #include <linux/isapnp.h> | 25 | #include <linux/isapnp.h> |
25 | #include <asm/io.h> /* outb, outb_p */ | 26 | #include <asm/io.h> /* outb, outb_p */ |
26 | #include <asm/uaccess.h> /* copy to/from user */ | 27 | #include <asm/uaccess.h> /* copy to/from user */ |
@@ -29,19 +30,19 @@ | |||
29 | struct fmi_device | 30 | struct fmi_device |
30 | { | 31 | { |
31 | int port; | 32 | int port; |
32 | int curvol; /* 1 or 0 */ | 33 | int curvol; /* 1 or 0 */ |
33 | unsigned long curfreq; /* freq in kHz */ | 34 | unsigned long curfreq; /* freq in kHz */ |
34 | __u32 flags; | 35 | __u32 flags; |
35 | }; | 36 | }; |
36 | 37 | ||
37 | static int io = -1; | 38 | static int io = -1; |
38 | static int radio_nr = -1; | 39 | static int radio_nr = -1; |
39 | static struct pnp_dev *dev = NULL; | 40 | static struct pnp_dev *dev = NULL; |
40 | static struct mutex lock; | 41 | static struct mutex lock; |
41 | 42 | ||
42 | /* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */ | 43 | /* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */ |
43 | /* It is only useful to give freq in intervall of 800 (=0.05Mhz), | 44 | /* It is only useful to give freq in intervall of 800 (=0.05Mhz), |
44 | * other bits will be truncated, e.g 92.7400016 -> 92.7, but | 45 | * other bits will be truncated, e.g 92.7400016 -> 92.7, but |
45 | * 92.7400017 -> 92.75 | 46 | * 92.7400017 -> 92.75 |
46 | */ | 47 | */ |
47 | #define RSF16_ENCODE(x) ((x)/800+214) | 48 | #define RSF16_ENCODE(x) ((x)/800+214) |
@@ -51,7 +52,7 @@ static struct mutex lock; | |||
51 | static void outbits(int bits, unsigned int data, int port) | 52 | static void outbits(int bits, unsigned int data, int port) |
52 | { | 53 | { |
53 | while(bits--) { | 54 | while(bits--) { |
54 | if(data & 1) { | 55 | if(data & 1) { |
55 | outb(5, port); | 56 | outb(5, port); |
56 | udelay(6); | 57 | udelay(6); |
57 | outb(7, port); | 58 | outb(7, port); |
@@ -101,7 +102,7 @@ static inline int fmi_getsigstr(struct fmi_device *dev) | |||
101 | int res; | 102 | int res; |
102 | int myport = dev->port; | 103 | int myport = dev->port; |
103 | 104 | ||
104 | 105 | ||
105 | mutex_lock(&lock); | 106 | mutex_lock(&lock); |
106 | val = dev->curvol ? 0x08 : 0x00; /* unmute/mute */ | 107 | val = dev->curvol ? 0x08 : 0x00; /* unmute/mute */ |
107 | outb(val, myport); | 108 | outb(val, myport); |
@@ -109,7 +110,7 @@ static inline int fmi_getsigstr(struct fmi_device *dev) | |||
109 | msleep(143); /* was schedule_timeout(HZ/7) */ | 110 | msleep(143); /* was schedule_timeout(HZ/7) */ |
110 | res = (int)inb(myport+1); | 111 | res = (int)inb(myport+1); |
111 | outb(val, myport); | 112 | outb(val, myport); |
112 | 113 | ||
113 | mutex_unlock(&lock); | 114 | mutex_unlock(&lock); |
114 | return (res & 2) ? 0 : 0xFFFF; | 115 | return (res & 2) ? 0 : 0xFFFF; |
115 | } | 116 | } |
@@ -119,7 +120,7 @@ static int fmi_do_ioctl(struct inode *inode, struct file *file, | |||
119 | { | 120 | { |
120 | struct video_device *dev = video_devdata(file); | 121 | struct video_device *dev = video_devdata(file); |
121 | struct fmi_device *fmi=dev->priv; | 122 | struct fmi_device *fmi=dev->priv; |
122 | 123 | ||
123 | switch(cmd) | 124 | switch(cmd) |
124 | { | 125 | { |
125 | case VIDIOCGCAP: | 126 | case VIDIOCGCAP: |
@@ -174,18 +175,18 @@ static int fmi_do_ioctl(struct inode *inode, struct file *file, | |||
174 | return -EINVAL; | 175 | return -EINVAL; |
175 | /*rounding in steps of 800 to match th freq | 176 | /*rounding in steps of 800 to match th freq |
176 | that will be used */ | 177 | that will be used */ |
177 | fmi->curfreq = (*freq/800)*800; | 178 | fmi->curfreq = (*freq/800)*800; |
178 | fmi_setfreq(fmi); | 179 | fmi_setfreq(fmi); |
179 | return 0; | 180 | return 0; |
180 | } | 181 | } |
181 | case VIDIOCGAUDIO: | 182 | case VIDIOCGAUDIO: |
182 | { | 183 | { |
183 | struct video_audio *v = arg; | 184 | struct video_audio *v = arg; |
184 | memset(v,0,sizeof(*v)); | 185 | memset(v,0,sizeof(*v)); |
185 | v->flags=( (!fmi->curvol)*VIDEO_AUDIO_MUTE | VIDEO_AUDIO_MUTABLE); | 186 | v->flags=( (!fmi->curvol)*VIDEO_AUDIO_MUTE | VIDEO_AUDIO_MUTABLE); |
186 | strcpy(v->name, "Radio"); | 187 | strcpy(v->name, "Radio"); |
187 | v->mode=VIDEO_SOUND_STEREO; | 188 | v->mode=VIDEO_SOUND_STEREO; |
188 | return 0; | 189 | return 0; |
189 | } | 190 | } |
190 | case VIDIOCSAUDIO: | 191 | case VIDIOCSAUDIO: |
191 | { | 192 | { |
@@ -193,19 +194,19 @@ static int fmi_do_ioctl(struct inode *inode, struct file *file, | |||
193 | if(v->audio) | 194 | if(v->audio) |
194 | return -EINVAL; | 195 | return -EINVAL; |
195 | fmi->curvol= v->flags&VIDEO_AUDIO_MUTE ? 0 : 1; | 196 | fmi->curvol= v->flags&VIDEO_AUDIO_MUTE ? 0 : 1; |
196 | fmi->curvol ? | 197 | fmi->curvol ? |
197 | fmi_unmute(fmi->port) : fmi_mute(fmi->port); | 198 | fmi_unmute(fmi->port) : fmi_mute(fmi->port); |
198 | return 0; | 199 | return 0; |
199 | } | 200 | } |
200 | case VIDIOCGUNIT: | 201 | case VIDIOCGUNIT: |
201 | { | 202 | { |
202 | struct video_unit *v = arg; | 203 | struct video_unit *v = arg; |
203 | v->video=VIDEO_NO_UNIT; | 204 | v->video=VIDEO_NO_UNIT; |
204 | v->vbi=VIDEO_NO_UNIT; | 205 | v->vbi=VIDEO_NO_UNIT; |
205 | v->radio=dev->minor; | 206 | v->radio=dev->minor; |
206 | v->audio=0; /* How do we find out this??? */ | 207 | v->audio=0; /* How do we find out this??? */ |
207 | v->teletext=VIDEO_NO_UNIT; | 208 | v->teletext=VIDEO_NO_UNIT; |
208 | return 0; | 209 | return 0; |
209 | } | 210 | } |
210 | default: | 211 | default: |
211 | return -ENOIOCTLCMD; | 212 | return -ENOIOCTLCMD; |
@@ -295,14 +296,14 @@ static int __init fmi_init(void) | |||
295 | fmi_unit.curfreq = 0; | 296 | fmi_unit.curfreq = 0; |
296 | fmi_unit.flags = VIDEO_TUNER_LOW; | 297 | fmi_unit.flags = VIDEO_TUNER_LOW; |
297 | fmi_radio.priv = &fmi_unit; | 298 | fmi_radio.priv = &fmi_unit; |
298 | 299 | ||
299 | mutex_init(&lock); | 300 | mutex_init(&lock); |
300 | 301 | ||
301 | if (video_register_device(&fmi_radio, VFL_TYPE_RADIO, radio_nr) == -1) { | 302 | if (video_register_device(&fmi_radio, VFL_TYPE_RADIO, radio_nr) == -1) { |
302 | release_region(io, 2); | 303 | release_region(io, 2); |
303 | return -EINVAL; | 304 | return -EINVAL; |
304 | } | 305 | } |
305 | 306 | ||
306 | printk(KERN_INFO "SF16FMx radio card driver at 0x%x\n", io); | 307 | printk(KERN_INFO "SF16FMx radio card driver at 0x%x\n", io); |
307 | /* mute card - prevents noisy bootups */ | 308 | /* mute card - prevents noisy bootups */ |
308 | fmi_mute(io); | 309 | fmi_mute(io); |