diff options
Diffstat (limited to 'drivers/media/radio/radio-aimslab.c')
-rw-r--r-- | drivers/media/radio/radio-aimslab.c | 151 |
1 files changed, 107 insertions, 44 deletions
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c index df22a582e7a2..3368a89bfadb 100644 --- a/drivers/media/radio/radio-aimslab.c +++ b/drivers/media/radio/radio-aimslab.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* radiotrack (radioreveal) driver for Linux radio support | 1 | /* radiotrack (radioreveal) driver for Linux radio support |
2 | * (c) 1997 M. Kirkwood | 2 | * (c) 1997 M. Kirkwood |
3 | * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> | ||
3 | * Converted to new API by Alan Cox <Alan.Cox@linux.org> | 4 | * Converted to new API by Alan Cox <Alan.Cox@linux.org> |
4 | * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org> | 5 | * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org> |
5 | * | 6 | * |
@@ -33,11 +34,13 @@ | |||
33 | #include <linux/delay.h> /* udelay */ | 34 | #include <linux/delay.h> /* udelay */ |
34 | #include <asm/io.h> /* outb, outb_p */ | 35 | #include <asm/io.h> /* outb, outb_p */ |
35 | #include <asm/uaccess.h> /* copy to/from user */ | 36 | #include <asm/uaccess.h> /* copy to/from user */ |
36 | #include <linux/videodev.h> /* kernel radio structs */ | 37 | #include <linux/videodev2.h> /* kernel radio structs */ |
37 | #include <media/v4l2-common.h> | 38 | #include <media/v4l2-common.h> |
38 | #include <linux/config.h> /* CONFIG_RADIO_RTRACK_PORT */ | ||
39 | #include <asm/semaphore.h> /* Lock for the I/O */ | 39 | #include <asm/semaphore.h> /* Lock for the I/O */ |
40 | 40 | ||
41 | #include <linux/version.h> /* for KERNEL_VERSION MACRO */ | ||
42 | #define RADIO_VERSION KERNEL_VERSION(0,0,2) | ||
43 | |||
41 | #ifndef CONFIG_RADIO_RTRACK_PORT | 44 | #ifndef CONFIG_RADIO_RTRACK_PORT |
42 | #define CONFIG_RADIO_RTRACK_PORT -1 | 45 | #define CONFIG_RADIO_RTRACK_PORT -1 |
43 | #endif | 46 | #endif |
@@ -209,6 +212,25 @@ static int rt_getsigstr(struct rt_device *dev) | |||
209 | return 1; /* signal present */ | 212 | return 1; /* signal present */ |
210 | } | 213 | } |
211 | 214 | ||
215 | static struct v4l2_queryctrl radio_qctrl[] = { | ||
216 | { | ||
217 | .id = V4L2_CID_AUDIO_MUTE, | ||
218 | .name = "Mute", | ||
219 | .minimum = 0, | ||
220 | .maximum = 1, | ||
221 | .default_value = 1, | ||
222 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
223 | },{ | ||
224 | .id = V4L2_CID_AUDIO_VOLUME, | ||
225 | .name = "Volume", | ||
226 | .minimum = 0, | ||
227 | .maximum = 0xff, | ||
228 | .step = 1, | ||
229 | .default_value = 0xff, | ||
230 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
231 | } | ||
232 | }; | ||
233 | |||
212 | static int rt_do_ioctl(struct inode *inode, struct file *file, | 234 | static int rt_do_ioctl(struct inode *inode, struct file *file, |
213 | unsigned int cmd, void *arg) | 235 | unsigned int cmd, void *arg) |
214 | { | 236 | { |
@@ -217,73 +239,114 @@ static int rt_do_ioctl(struct inode *inode, struct file *file, | |||
217 | 239 | ||
218 | switch(cmd) | 240 | switch(cmd) |
219 | { | 241 | { |
220 | case VIDIOCGCAP: | 242 | case VIDIOC_QUERYCAP: |
221 | { | 243 | { |
222 | struct video_capability *v = arg; | 244 | struct v4l2_capability *v = arg; |
223 | memset(v,0,sizeof(*v)); | 245 | memset(v,0,sizeof(*v)); |
224 | v->type=VID_TYPE_TUNER; | 246 | strlcpy(v->driver, "radio-aimslab", sizeof (v->driver)); |
225 | v->channels=1; | 247 | strlcpy(v->card, "RadioTrack", sizeof (v->card)); |
226 | v->audios=1; | 248 | sprintf(v->bus_info,"ISA"); |
227 | strcpy(v->name, "RadioTrack"); | 249 | v->version = RADIO_VERSION; |
250 | v->capabilities = V4L2_CAP_TUNER; | ||
251 | |||
228 | return 0; | 252 | return 0; |
229 | } | 253 | } |
230 | case VIDIOCGTUNER: | 254 | case VIDIOC_G_TUNER: |
231 | { | 255 | { |
232 | struct video_tuner *v = arg; | 256 | struct v4l2_tuner *v = arg; |
233 | if(v->tuner) /* Only 1 tuner */ | 257 | |
258 | if (v->index > 0) | ||
234 | return -EINVAL; | 259 | return -EINVAL; |
260 | |||
261 | memset(v,0,sizeof(*v)); | ||
262 | strcpy(v->name, "FM"); | ||
263 | v->type = V4L2_TUNER_RADIO; | ||
264 | |||
235 | v->rangelow=(87*16000); | 265 | v->rangelow=(87*16000); |
236 | v->rangehigh=(108*16000); | 266 | v->rangehigh=(108*16000); |
237 | v->flags=VIDEO_TUNER_LOW; | 267 | v->rxsubchans =V4L2_TUNER_SUB_MONO; |
238 | v->mode=VIDEO_MODE_AUTO; | 268 | v->capability=V4L2_TUNER_CAP_LOW; |
239 | strcpy(v->name, "FM"); | 269 | v->audmode = V4L2_TUNER_MODE_MONO; |
240 | v->signal=0xFFFF*rt_getsigstr(rt); | 270 | v->signal=0xFFFF*rt_getsigstr(rt); |
271 | |||
241 | return 0; | 272 | return 0; |
242 | } | 273 | } |
243 | case VIDIOCSTUNER: | 274 | case VIDIOC_S_TUNER: |
244 | { | 275 | { |
245 | struct video_tuner *v = arg; | 276 | struct v4l2_tuner *v = arg; |
246 | if(v->tuner!=0) | 277 | |
278 | if (v->index > 0) | ||
247 | return -EINVAL; | 279 | return -EINVAL; |
248 | /* Only 1 tuner so no setting needed ! */ | 280 | |
249 | return 0; | 281 | return 0; |
250 | } | 282 | } |
251 | case VIDIOCGFREQ: | 283 | case VIDIOC_S_FREQUENCY: |
252 | { | 284 | { |
253 | unsigned long *freq = arg; | 285 | struct v4l2_frequency *f = arg; |
254 | *freq = rt->curfreq; | 286 | |
287 | rt->curfreq = f->frequency; | ||
288 | rt_setfreq(rt, rt->curfreq); | ||
255 | return 0; | 289 | return 0; |
256 | } | 290 | } |
257 | case VIDIOCSFREQ: | 291 | case VIDIOC_G_FREQUENCY: |
258 | { | 292 | { |
259 | unsigned long *freq = arg; | 293 | struct v4l2_frequency *f = arg; |
260 | rt->curfreq = *freq; | 294 | |
261 | rt_setfreq(rt, rt->curfreq); | 295 | f->type = V4L2_TUNER_RADIO; |
296 | f->frequency = rt->curfreq; | ||
297 | |||
262 | return 0; | 298 | return 0; |
263 | } | 299 | } |
264 | case VIDIOCGAUDIO: | 300 | case VIDIOC_QUERYCTRL: |
265 | { | 301 | { |
266 | struct video_audio *v = arg; | 302 | struct v4l2_queryctrl *qc = arg; |
267 | memset(v,0, sizeof(*v)); | 303 | int i; |
268 | v->flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME; | 304 | |
269 | v->volume=rt->curvol * 6554; | 305 | for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { |
270 | v->step=6554; | 306 | if (qc->id && qc->id == radio_qctrl[i].id) { |
271 | strcpy(v->name, "Radio"); | 307 | memcpy(qc, &(radio_qctrl[i]), |
272 | return 0; | 308 | sizeof(*qc)); |
309 | return (0); | ||
310 | } | ||
311 | } | ||
312 | return -EINVAL; | ||
273 | } | 313 | } |
274 | case VIDIOCSAUDIO: | 314 | case VIDIOC_G_CTRL: |
275 | { | 315 | { |
276 | struct video_audio *v = arg; | 316 | struct v4l2_control *ctrl= arg; |
277 | if(v->audio) | 317 | |
278 | return -EINVAL; | 318 | switch (ctrl->id) { |
279 | if(v->flags&VIDEO_AUDIO_MUTE) | 319 | case V4L2_CID_AUDIO_MUTE: |
280 | rt_mute(rt); | 320 | ctrl->value=rt->muted; |
281 | else | 321 | return (0); |
282 | rt_setvol(rt,v->volume/6554); | 322 | case V4L2_CID_AUDIO_VOLUME: |
283 | return 0; | 323 | ctrl->value=rt->curvol * 6554; |
324 | return (0); | ||
325 | } | ||
326 | return -EINVAL; | ||
284 | } | 327 | } |
328 | case VIDIOC_S_CTRL: | ||
329 | { | ||
330 | struct v4l2_control *ctrl= arg; | ||
331 | |||
332 | switch (ctrl->id) { | ||
333 | case V4L2_CID_AUDIO_MUTE: | ||
334 | if (ctrl->value) { | ||
335 | rt_mute(rt); | ||
336 | } else { | ||
337 | rt_setvol(rt,rt->curvol); | ||
338 | } | ||
339 | return (0); | ||
340 | case V4L2_CID_AUDIO_VOLUME: | ||
341 | rt_setvol(rt,ctrl->value); | ||
342 | return (0); | ||
343 | } | ||
344 | return -EINVAL; | ||
345 | } | ||
346 | |||
285 | default: | 347 | default: |
286 | return -ENOIOCTLCMD; | 348 | return v4l_compat_translate_ioctl(inode,file,cmd,arg, |
349 | rt_do_ioctl); | ||
287 | } | 350 | } |
288 | } | 351 | } |
289 | 352 | ||
@@ -309,7 +372,7 @@ static struct video_device rtrack_radio= | |||
309 | .owner = THIS_MODULE, | 372 | .owner = THIS_MODULE, |
310 | .name = "RadioTrack radio", | 373 | .name = "RadioTrack radio", |
311 | .type = VID_TYPE_TUNER, | 374 | .type = VID_TYPE_TUNER, |
312 | .hardware = VID_HARDWARE_RTRACK, | 375 | .hardware = 0, |
313 | .fops = &rtrack_fops, | 376 | .fops = &rtrack_fops, |
314 | }; | 377 | }; |
315 | 378 | ||