aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/radio/radio-sf16fmi.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2006-08-08 08:10:02 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2006-09-26 10:53:13 -0400
commita2ef73af4cd6cb46be13b11f9ce64d6b44f0350b (patch)
treed1bec6b312ff5861f32fb84dfa3b946f35f8bc65 /drivers/media/radio/radio-sf16fmi.c
parentf8c559f8c066a045fb3f70bbb35f9e7c2064b8ae (diff)
V4L/DVB (4353): V4L2 conversion: radio-sf16fmi
Driver conversion to V4L2 API. Require some testing, since this obsolete hardware is not common those days. Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/radio/radio-sf16fmi.c')
-rw-r--r--drivers/media/radio/radio-sf16fmi.c157
1 files changed, 100 insertions, 57 deletions
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
index efee6e339d15..43524119ac1c 100644
--- a/drivers/media/radio/radio-sf16fmi.c
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -13,6 +13,7 @@
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 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
16 */ 17 */
17 18
18#include <linux/kernel.h> /* __setup */ 19#include <linux/kernel.h> /* __setup */
@@ -20,13 +21,26 @@
20#include <linux/init.h> /* Initdata */ 21#include <linux/init.h> /* Initdata */
21#include <linux/ioport.h> /* request_region */ 22#include <linux/ioport.h> /* request_region */
22#include <linux/delay.h> /* udelay */ 23#include <linux/delay.h> /* udelay */
23#include <linux/videodev.h> /* kernel radio structs */ 24#include <linux/videodev2.h> /* kernel radio structs */
24#include <media/v4l2-common.h> 25#include <media/v4l2-common.h>
25#include <linux/isapnp.h> 26#include <linux/isapnp.h>
26#include <asm/io.h> /* outb, outb_p */ 27#include <asm/io.h> /* outb, outb_p */
27#include <asm/uaccess.h> /* copy to/from user */ 28#include <asm/uaccess.h> /* copy to/from user */
28#include <linux/mutex.h> 29#include <linux/mutex.h>
29 30
31#define RADIO_VERSION KERNEL_VERSION(0,0,2)
32
33static struct v4l2_queryctrl radio_qctrl[] = {
34 {
35 .id = V4L2_CID_AUDIO_MUTE,
36 .name = "Mute",
37 .minimum = 0,
38 .maximum = 1,
39 .default_value = 1,
40 .type = V4L2_CTRL_TYPE_BOOLEAN,
41 }
42};
43
30struct fmi_device 44struct fmi_device
31{ 45{
32 int port; 46 int port;
@@ -123,93 +137,122 @@ static int fmi_do_ioctl(struct inode *inode, struct file *file,
123 137
124 switch(cmd) 138 switch(cmd)
125 { 139 {
126 case VIDIOCGCAP: 140 case VIDIOC_QUERYCAP:
127 { 141 {
128 struct video_capability *v = arg; 142 struct v4l2_capability *v = arg;
129 memset(v,0,sizeof(*v)); 143 memset(v,0,sizeof(*v));
130 strcpy(v->name, "SF16-FMx radio"); 144 strlcpy(v->driver, "radio-sf16fmi", sizeof (v->driver));
131 v->type=VID_TYPE_TUNER; 145 strlcpy(v->card, "SF16-FMx radio", sizeof (v->card));
132 v->channels=1; 146 sprintf(v->bus_info,"ISA");
133 v->audios=1; 147 v->version = RADIO_VERSION;
148 v->capabilities = V4L2_CAP_TUNER;
149
134 return 0; 150 return 0;
135 } 151 }
136 case VIDIOCGTUNER: 152 case VIDIOC_G_TUNER:
137 { 153 {
138 struct video_tuner *v = arg; 154 struct v4l2_tuner *v = arg;
139 int mult; 155 int mult;
140 156
141 if(v->tuner) /* Only 1 tuner */ 157 if (v->index > 0)
142 return -EINVAL; 158 return -EINVAL;
159
160 memset(v,0,sizeof(*v));
143 strcpy(v->name, "FM"); 161 strcpy(v->name, "FM");
144 mult = (fmi->flags & VIDEO_TUNER_LOW) ? 1 : 1000; 162 v->type = V4L2_TUNER_RADIO;
163
164 mult = (fmi->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000;
145 v->rangelow = RSF16_MINFREQ/mult; 165 v->rangelow = RSF16_MINFREQ/mult;
146 v->rangehigh = RSF16_MAXFREQ/mult; 166 v->rangehigh = RSF16_MAXFREQ/mult;
147 v->flags=fmi->flags; 167 v->rxsubchans =V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO;
148 v->mode=VIDEO_MODE_AUTO; 168 v->capability=fmi->flags;
169 v->audmode = V4L2_TUNER_MODE_STEREO;
149 v->signal = fmi_getsigstr(fmi); 170 v->signal = fmi_getsigstr(fmi);
171
150 return 0; 172 return 0;
151 } 173 }
152 case VIDIOCSTUNER: 174 case VIDIOC_S_TUNER:
153 { 175 {
154 struct video_tuner *v = arg; 176 struct v4l2_tuner *v = arg;
155 if(v->tuner!=0) 177
178 if (v->index > 0)
156 return -EINVAL; 179 return -EINVAL;
157 fmi->flags = v->flags & VIDEO_TUNER_LOW; 180
158 /* Only 1 tuner so no setting needed ! */
159 return 0;
160 }
161 case VIDIOCGFREQ:
162 {
163 unsigned long *freq = arg;
164 *freq = fmi->curfreq;
165 if (!(fmi->flags & VIDEO_TUNER_LOW))
166 *freq /= 1000;
167 return 0; 181 return 0;
168 } 182 }
169 case VIDIOCSFREQ: 183 case VIDIOC_S_FREQUENCY:
170 { 184 {
171 unsigned long *freq = arg; 185 struct v4l2_frequency *f = arg;
172 if (!(fmi->flags & VIDEO_TUNER_LOW)) 186
173 *freq *= 1000; 187 if (!(fmi->flags & V4L2_TUNER_CAP_LOW))
174 if (*freq < RSF16_MINFREQ || *freq > RSF16_MAXFREQ ) 188 f->frequency *= 1000;
189 if (f->frequency < RSF16_MINFREQ ||
190 f->frequency > RSF16_MAXFREQ )
175 return -EINVAL; 191 return -EINVAL;
176 /*rounding in steps of 800 to match th freq 192 /*rounding in steps of 800 to match th freq
177 that will be used */ 193 that will be used */
178 fmi->curfreq = (*freq/800)*800; 194 fmi->curfreq = (f->frequency/800)*800;
179 fmi_setfreq(fmi); 195 fmi_setfreq(fmi);
196
180 return 0; 197 return 0;
181 } 198 }
182 case VIDIOCGAUDIO: 199 case VIDIOC_G_FREQUENCY:
183 { 200 {
184 struct video_audio *v = arg; 201 struct v4l2_frequency *f = arg;
185 memset(v,0,sizeof(*v)); 202
186 v->flags=( (!fmi->curvol)*VIDEO_AUDIO_MUTE | VIDEO_AUDIO_MUTABLE); 203 f->type = V4L2_TUNER_RADIO;
187 strcpy(v->name, "Radio"); 204 f->frequency = fmi->curfreq;
188 v->mode=VIDEO_SOUND_STEREO; 205 if (!(fmi->flags & V4L2_TUNER_CAP_LOW))
206 f->frequency /= 1000;
207
189 return 0; 208 return 0;
190 } 209 }
191 case VIDIOCSAUDIO: 210 case VIDIOC_QUERYCTRL:
192 { 211 {
193 struct video_audio *v = arg; 212 struct v4l2_queryctrl *qc = arg;
194 if(v->audio) 213 int i;
195 return -EINVAL; 214
196 fmi->curvol= v->flags&VIDEO_AUDIO_MUTE ? 0 : 1; 215 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
197 fmi->curvol ? 216 if (qc->id && qc->id == radio_qctrl[i].id) {
198 fmi_unmute(fmi->port) : fmi_mute(fmi->port); 217 memcpy(qc, &(radio_qctrl[i]),
199 return 0; 218 sizeof(*qc));
219 return (0);
220 }
221 }
222 return -EINVAL;
200 } 223 }
201 case VIDIOCGUNIT: 224 case VIDIOC_G_CTRL:
202 { 225 {
203 struct video_unit *v = arg; 226 struct v4l2_control *ctrl= arg;
204 v->video=VIDEO_NO_UNIT; 227
205 v->vbi=VIDEO_NO_UNIT; 228 switch (ctrl->id) {
206 v->radio=dev->minor; 229 case V4L2_CID_AUDIO_MUTE:
207 v->audio=0; /* How do we find out this??? */ 230 ctrl->value=fmi->curvol;
208 v->teletext=VIDEO_NO_UNIT; 231 return (0);
209 return 0; 232 }
233 return -EINVAL;
234 }
235 case VIDIOC_S_CTRL:
236 {
237 struct v4l2_control *ctrl= arg;
238
239 switch (ctrl->id) {
240 case V4L2_CID_AUDIO_MUTE:
241 {
242 if (ctrl->value)
243 fmi_mute(fmi->port);
244 else
245 fmi_unmute(fmi->port);
246
247 fmi->curvol=ctrl->value;
248 return (0);
249 }
250 }
251 return -EINVAL;
210 } 252 }
211 default: 253 default:
212 return -ENOIOCTLCMD; 254 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
255 fmi_do_ioctl);
213 } 256 }
214} 257}
215 258
@@ -235,7 +278,7 @@ static struct video_device fmi_radio=
235 .owner = THIS_MODULE, 278 .owner = THIS_MODULE,
236 .name = "SF16FMx radio", 279 .name = "SF16FMx radio",
237 .type = VID_TYPE_TUNER, 280 .type = VID_TYPE_TUNER,
238 .hardware = VID_HARDWARE_SF16MI, 281 .hardware = 0,
239 .fops = &fmi_fops, 282 .fops = &fmi_fops,
240}; 283};
241 284
@@ -294,7 +337,7 @@ static int __init fmi_init(void)
294 fmi_unit.port = io; 337 fmi_unit.port = io;
295 fmi_unit.curvol = 0; 338 fmi_unit.curvol = 0;
296 fmi_unit.curfreq = 0; 339 fmi_unit.curfreq = 0;
297 fmi_unit.flags = VIDEO_TUNER_LOW; 340 fmi_unit.flags = V4L2_TUNER_CAP_LOW;
298 fmi_radio.priv = &fmi_unit; 341 fmi_radio.priv = &fmi_unit;
299 342
300 mutex_init(&lock); 343 mutex_init(&lock);