aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/radio
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-09-30 12:39:15 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-09-30 12:39:15 -0400
commit5ffd1a6aaacc25be8cd0770a51ec6d46add3a276 (patch)
tree5b076c44f8b7ff88dba9a554d7748c6f083c9071 /drivers/media/radio
parent0cd43f83d381c4246a08cd775834833d6fd64805 (diff)
parent8dd86eebc5315910ebfd9f30f1674254308be4b3 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb
* master.kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (180 commits) V4L/DVB (4641): Trivial: use lowercase letters in hex subsystem ids V4L/DVB (4639): Cx88: add autodetection for alternate revision of Leadtek PVR V4L/DVB (4638): Basic DVB-T and analog TV support for the HVR1300. V4L/DVB (4637): Add a default method for VIDIOC_G_PARM V4L/DVB (4635): Extend bttv and saa7134 to check for both AGP and PCI PCI failure case V4L/DVB (4634): Zr36120: implement pcipci checks V4L/DVB (4632): Zoran: Implement pcipci failure check V4L/DVB (4631): Av7110: remove V4L2_CAP_VBI_CAPTURE flag V4L/DVB (4630): Av7110: FW_LOADER depemdency fixed V4L/DVB (4629): Saa7134: add card support for Proteus Pro 2309 V4L/DVB (4628): Fix VIDIOC_ENUMSTD ioctl in videodev.c V4L/DVB (4627): Vivi crashes with mplayer V4L/DVB (4626): On saa7111/7113, LUMA_CTRL need a different value V4L/DVB (4624): Tvaudio: Replaced kernel_thread() with kthread_run() V4L/DVB (4622): Copy-paste bug in videodev.c V4L/DVB (4620): Fix AGC configuration for MOD3000P-based boards V4L/DVB (4619): Fixes some I2C dependencies on V4L devices V4L/DVB (4617): Problem with dibusb-mb.c USB IDs V4L/DVB (4616): [PATCH] Nebula DigiTV USB RC support V4L/DVB (4614): Export symbol saa7134_tvaudio_setmute from saa7134 for saa7134-alsa ...
Diffstat (limited to 'drivers/media/radio')
-rw-r--r--drivers/media/radio/Kconfig30
-rw-r--r--drivers/media/radio/dsbr100.c198
-rw-r--r--drivers/media/radio/radio-aimslab.c151
-rw-r--r--drivers/media/radio/radio-aztech.c166
-rw-r--r--drivers/media/radio/radio-cadet.c250
-rw-r--r--drivers/media/radio/radio-gemtek-pci.c170
-rw-r--r--drivers/media/radio/radio-gemtek.c165
-rw-r--r--drivers/media/radio/radio-maestro.c197
-rw-r--r--drivers/media/radio/radio-maxiradio.c166
-rw-r--r--drivers/media/radio/radio-rtrack2.c163
-rw-r--r--drivers/media/radio/radio-sf16fmi.c158
-rw-r--r--drivers/media/radio/radio-sf16fmr2.c223
-rw-r--r--drivers/media/radio/radio-terratec.c154
-rw-r--r--drivers/media/radio/radio-trust.c188
-rw-r--r--drivers/media/radio/radio-typhoon.c171
-rw-r--r--drivers/media/radio/radio-zoltrix.c183
16 files changed, 1795 insertions, 938 deletions
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index 220076b1b956..7015517e2c1b 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -7,7 +7,7 @@ menu "Radio Adapters"
7 7
8config RADIO_CADET 8config RADIO_CADET
9 tristate "ADS Cadet AM/FM Tuner" 9 tristate "ADS Cadet AM/FM Tuner"
10 depends on ISA && VIDEO_V4L1 10 depends on ISA && VIDEO_V4L2
11 ---help--- 11 ---help---
12 Choose Y here if you have one of these AM/FM radio cards, and then 12 Choose Y here if you have one of these AM/FM radio cards, and then
13 fill in the port address below. 13 fill in the port address below.
@@ -25,7 +25,7 @@ config RADIO_CADET
25 25
26config RADIO_RTRACK 26config RADIO_RTRACK
27 tristate "AIMSlab RadioTrack (aka RadioReveal) support" 27 tristate "AIMSlab RadioTrack (aka RadioReveal) support"
28 depends on ISA && VIDEO_V4L1 28 depends on ISA && VIDEO_V4L2
29 ---help--- 29 ---help---
30 Choose Y here if you have one of these FM radio cards, and then fill 30 Choose Y here if you have one of these FM radio cards, and then fill
31 in the port address below. 31 in the port address below.
@@ -59,7 +59,7 @@ config RADIO_RTRACK_PORT
59 59
60config RADIO_RTRACK2 60config RADIO_RTRACK2
61 tristate "AIMSlab RadioTrack II support" 61 tristate "AIMSlab RadioTrack II support"
62 depends on ISA && VIDEO_V4L1 62 depends on ISA && VIDEO_V4L2
63 ---help--- 63 ---help---
64 Choose Y here if you have this FM radio card, and then fill in the 64 Choose Y here if you have this FM radio card, and then fill in the
65 port address below. 65 port address below.
@@ -82,7 +82,7 @@ config RADIO_RTRACK2_PORT
82 82
83config RADIO_AZTECH 83config RADIO_AZTECH
84 tristate "Aztech/Packard Bell Radio" 84 tristate "Aztech/Packard Bell Radio"
85 depends on ISA && VIDEO_V4L1 85 depends on ISA && VIDEO_V4L2
86 ---help--- 86 ---help---
87 Choose Y here if you have one of these FM radio cards, and then fill 87 Choose Y here if you have one of these FM radio cards, and then fill
88 in the port address below. 88 in the port address below.
@@ -106,7 +106,7 @@ config RADIO_AZTECH_PORT
106 106
107config RADIO_GEMTEK 107config RADIO_GEMTEK
108 tristate "GemTek Radio Card support" 108 tristate "GemTek Radio Card support"
109 depends on ISA && VIDEO_V4L1 109 depends on ISA && VIDEO_V4L2
110 ---help--- 110 ---help---
111 Choose Y here if you have this FM radio card, and then fill in the 111 Choose Y here if you have this FM radio card, and then fill in the
112 port address below. 112 port address below.
@@ -131,7 +131,7 @@ config RADIO_GEMTEK_PORT
131 131
132config RADIO_GEMTEK_PCI 132config RADIO_GEMTEK_PCI
133 tristate "GemTek PCI Radio Card support" 133 tristate "GemTek PCI Radio Card support"
134 depends on VIDEO_V4L1 && PCI 134 depends on VIDEO_V4L2 && PCI
135 ---help--- 135 ---help---
136 Choose Y here if you have this PCI FM radio card. 136 Choose Y here if you have this PCI FM radio card.
137 137
@@ -145,7 +145,7 @@ config RADIO_GEMTEK_PCI
145 145
146config RADIO_MAXIRADIO 146config RADIO_MAXIRADIO
147 tristate "Guillemot MAXI Radio FM 2000 radio" 147 tristate "Guillemot MAXI Radio FM 2000 radio"
148 depends on VIDEO_V4L1 && PCI 148 depends on VIDEO_V4L2 && PCI
149 ---help--- 149 ---help---
150 Choose Y here if you have this radio card. This card may also be 150 Choose Y here if you have this radio card. This card may also be
151 found as Gemtek PCI FM. 151 found as Gemtek PCI FM.
@@ -160,7 +160,7 @@ config RADIO_MAXIRADIO
160 160
161config RADIO_MAESTRO 161config RADIO_MAESTRO
162 tristate "Maestro on board radio" 162 tristate "Maestro on board radio"
163 depends on VIDEO_V4L1 163 depends on VIDEO_V4L2 && PCI
164 ---help--- 164 ---help---
165 Say Y here to directly support the on-board radio tuner on the 165 Say Y here to directly support the on-board radio tuner on the
166 Maestro 2 or 2E sound card. 166 Maestro 2 or 2E sound card.
@@ -208,7 +208,7 @@ config RADIO_MIROPCM20_RDS
208 208
209config RADIO_SF16FMI 209config RADIO_SF16FMI
210 tristate "SF16FMI Radio" 210 tristate "SF16FMI Radio"
211 depends on ISA && VIDEO_V4L1 211 depends on ISA && VIDEO_V4L2
212 ---help--- 212 ---help---
213 Choose Y here if you have one of these FM radio cards. If you 213 Choose Y here if you have one of these FM radio cards. If you
214 compile the driver into the kernel and your card is not PnP one, you 214 compile the driver into the kernel and your card is not PnP one, you
@@ -225,7 +225,7 @@ config RADIO_SF16FMI
225 225
226config RADIO_SF16FMR2 226config RADIO_SF16FMR2
227 tristate "SF16FMR2 Radio" 227 tristate "SF16FMR2 Radio"
228 depends on ISA && VIDEO_V4L1 228 depends on ISA && VIDEO_V4L2
229 ---help--- 229 ---help---
230 Choose Y here if you have one of these FM radio cards. 230 Choose Y here if you have one of these FM radio cards.
231 231
@@ -239,7 +239,7 @@ config RADIO_SF16FMR2
239 239
240config RADIO_TERRATEC 240config RADIO_TERRATEC
241 tristate "TerraTec ActiveRadio ISA Standalone" 241 tristate "TerraTec ActiveRadio ISA Standalone"
242 depends on ISA && VIDEO_V4L1 242 depends on ISA && VIDEO_V4L2
243 ---help--- 243 ---help---
244 Choose Y here if you have this FM radio card, and then fill in the 244 Choose Y here if you have this FM radio card, and then fill in the
245 port address below. (TODO) 245 port address below. (TODO)
@@ -268,7 +268,7 @@ config RADIO_TERRATEC_PORT
268 268
269config RADIO_TRUST 269config RADIO_TRUST
270 tristate "Trust FM radio card" 270 tristate "Trust FM radio card"
271 depends on ISA && VIDEO_V4L1 271 depends on ISA && VIDEO_V4L2
272 help 272 help
273 This is a driver for the Trust FM radio cards. Say Y if you have 273 This is a driver for the Trust FM radio cards. Say Y if you have
274 such a card and want to use it under Linux. 274 such a card and want to use it under Linux.
@@ -286,7 +286,7 @@ config RADIO_TRUST_PORT
286 286
287config RADIO_TYPHOON 287config RADIO_TYPHOON
288 tristate "Typhoon Radio (a.k.a. EcoRadio)" 288 tristate "Typhoon Radio (a.k.a. EcoRadio)"
289 depends on ISA && VIDEO_V4L1 289 depends on ISA && VIDEO_V4L2
290 ---help--- 290 ---help---
291 Choose Y here if you have one of these FM radio cards, and then fill 291 Choose Y here if you have one of these FM radio cards, and then fill
292 in the port address and the frequency used for muting below. 292 in the port address and the frequency used for muting below.
@@ -330,7 +330,7 @@ config RADIO_TYPHOON_MUTEFREQ
330 330
331config RADIO_ZOLTRIX 331config RADIO_ZOLTRIX
332 tristate "Zoltrix Radio" 332 tristate "Zoltrix Radio"
333 depends on ISA && VIDEO_V4L1 333 depends on ISA && VIDEO_V4L2
334 ---help--- 334 ---help---
335 Choose Y here if you have one of these FM radio cards, and then fill 335 Choose Y here if you have one of these FM radio cards, and then fill
336 in the port address below. 336 in the port address below.
@@ -352,7 +352,7 @@ config RADIO_ZOLTRIX_PORT
352 352
353config USB_DSBR 353config USB_DSBR
354 tristate "D-Link USB FM radio support (EXPERIMENTAL)" 354 tristate "D-Link USB FM radio support (EXPERIMENTAL)"
355 depends on USB && VIDEO_V4L1 && EXPERIMENTAL 355 depends on USB && VIDEO_V4L2 && EXPERIMENTAL
356 ---help--- 356 ---help---
357 Say Y here if you want to connect this type of radio to your 357 Say Y here if you want to connect this type of radio to your
358 computer's USB port. Note that the audio is not digital, and 358 computer's USB port. Note that the audio is not digital, and
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c
index f7e33f9ee8e9..db865a0667e5 100644
--- a/drivers/media/radio/dsbr100.c
+++ b/drivers/media/radio/dsbr100.c
@@ -33,8 +33,14 @@
33 33
34 History: 34 History:
35 35
36 Version 0.41-ac1:
37 Alan Cox: Some cleanups and fixes
38
39 Version 0.41:
40 Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
41
36 Version 0.40: 42 Version 0.40:
37 Markus: Updates for 2.6.x kernels, code layout changes, name sanitizing 43 Markus: Updates for 2.6.x kernels, code layout changes, name sanitizing
38 44
39 Version 0.30: 45 Version 0.30:
40 Markus: Updates for 2.5.x kernel and more ISO compliant source 46 Markus: Updates for 2.5.x kernel and more ISO compliant source
@@ -65,13 +71,12 @@
65 71
66*/ 72*/
67 73
68
69#include <linux/kernel.h> 74#include <linux/kernel.h>
70#include <linux/module.h> 75#include <linux/module.h>
71#include <linux/init.h> 76#include <linux/init.h>
72#include <linux/slab.h> 77#include <linux/slab.h>
73#include <linux/input.h> 78#include <linux/input.h>
74#include <linux/videodev.h> 79#include <linux/videodev2.h>
75#include <media/v4l2-common.h> 80#include <media/v4l2-common.h>
76#include <linux/usb.h> 81#include <linux/usb.h>
77#include <linux/smp_lock.h> 82#include <linux/smp_lock.h>
@@ -79,7 +84,22 @@
79/* 84/*
80 * Version Information 85 * Version Information
81 */ 86 */
82#define DRIVER_VERSION "v0.40" 87#include <linux/version.h> /* for KERNEL_VERSION MACRO */
88
89#define DRIVER_VERSION "v0.41"
90#define RADIO_VERSION KERNEL_VERSION(0,4,1)
91
92static struct v4l2_queryctrl radio_qctrl[] = {
93 {
94 .id = V4L2_CID_AUDIO_MUTE,
95 .name = "Mute",
96 .minimum = 0,
97 .maximum = 1,
98 .default_value = 1,
99 .type = V4L2_CTRL_TYPE_BOOLEAN,
100 }
101};
102
83#define DRIVER_AUTHOR "Markus Demleitner <msdemlei@tucana.harvard.edu>" 103#define DRIVER_AUTHOR "Markus Demleitner <msdemlei@tucana.harvard.edu>"
84#define DRIVER_DESC "D-Link DSB-R100 USB FM radio driver" 104#define DRIVER_DESC "D-Link DSB-R100 USB FM radio driver"
85 105
@@ -111,7 +131,7 @@ static int radio_nr = -1;
111module_param(radio_nr, int, 0); 131module_param(radio_nr, int, 0);
112 132
113/* Data for one (physical) device */ 133/* Data for one (physical) device */
114typedef struct { 134struct dsbr100_device {
115 struct usb_device *usbdev; 135 struct usb_device *usbdev;
116 struct video_device *videodev; 136 struct video_device *videodev;
117 unsigned char transfer_buffer[TB_LEN]; 137 unsigned char transfer_buffer[TB_LEN];
@@ -119,7 +139,8 @@ typedef struct {
119 int stereo; 139 int stereo;
120 int users; 140 int users;
121 int removed; 141 int removed;
122} dsbr100_device; 142 int muted;
143};
123 144
124 145
125/* File system interface */ 146/* File system interface */
@@ -138,7 +159,6 @@ static struct video_device dsbr100_videodev_template=
138 .owner = THIS_MODULE, 159 .owner = THIS_MODULE,
139 .name = "D-Link DSB-R 100", 160 .name = "D-Link DSB-R 100",
140 .type = VID_TYPE_TUNER, 161 .type = VID_TYPE_TUNER,
141 .hardware = VID_HARDWARE_AZTECH,
142 .fops = &usb_dsbr100_fops, 162 .fops = &usb_dsbr100_fops,
143 .release = video_device_release, 163 .release = video_device_release,
144}; 164};
@@ -161,7 +181,7 @@ static struct usb_driver usb_dsbr100_driver = {
161/* Low-level device interface begins here */ 181/* Low-level device interface begins here */
162 182
163/* switch on radio */ 183/* switch on radio */
164static int dsbr100_start(dsbr100_device *radio) 184static int dsbr100_start(struct dsbr100_device *radio)
165{ 185{
166 if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), 186 if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
167 USB_REQ_GET_STATUS, 187 USB_REQ_GET_STATUS,
@@ -172,12 +192,13 @@ static int dsbr100_start(dsbr100_device *radio)
172 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 192 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
173 0x01, 0x00, radio->transfer_buffer, 8, 300)<0) 193 0x01, 0x00, radio->transfer_buffer, 8, 300)<0)
174 return -1; 194 return -1;
195 radio->muted=0;
175 return (radio->transfer_buffer)[0]; 196 return (radio->transfer_buffer)[0];
176} 197}
177 198
178 199
179/* switch off radio */ 200/* switch off radio */
180static int dsbr100_stop(dsbr100_device *radio) 201static int dsbr100_stop(struct dsbr100_device *radio)
181{ 202{
182 if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), 203 if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
183 USB_REQ_GET_STATUS, 204 USB_REQ_GET_STATUS,
@@ -188,11 +209,12 @@ static int dsbr100_stop(dsbr100_device *radio)
188 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 209 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
189 0x00, 0x00, radio->transfer_buffer, 8, 300)<0) 210 0x00, 0x00, radio->transfer_buffer, 8, 300)<0)
190 return -1; 211 return -1;
212 radio->muted=1;
191 return (radio->transfer_buffer)[0]; 213 return (radio->transfer_buffer)[0];
192} 214}
193 215
194/* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */ 216/* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */
195static int dsbr100_setfreq(dsbr100_device *radio, int freq) 217static int dsbr100_setfreq(struct dsbr100_device *radio, int freq)
196{ 218{
197 freq = (freq/16*80)/1000+856; 219 freq = (freq/16*80)/1000+856;
198 if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), 220 if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
@@ -217,7 +239,7 @@ static int dsbr100_setfreq(dsbr100_device *radio, int freq)
217 239
218/* return the device status. This is, in effect, just whether it 240/* return the device status. This is, in effect, just whether it
219sees a stereo signal or not. Pity. */ 241sees a stereo signal or not. Pity. */
220static void dsbr100_getstat(dsbr100_device *radio) 242static void dsbr100_getstat(struct dsbr100_device *radio)
221{ 243{
222 if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), 244 if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0),
223 USB_REQ_GET_STATUS, 245 USB_REQ_GET_STATUS,
@@ -236,9 +258,9 @@ usb if it is */
236static int usb_dsbr100_probe(struct usb_interface *intf, 258static int usb_dsbr100_probe(struct usb_interface *intf,
237 const struct usb_device_id *id) 259 const struct usb_device_id *id)
238{ 260{
239 dsbr100_device *radio; 261 struct dsbr100_device *radio;
240 262
241 if (!(radio = kmalloc(sizeof(dsbr100_device), GFP_KERNEL))) 263 if (!(radio = kmalloc(sizeof(struct dsbr100_device), GFP_KERNEL)))
242 return -ENOMEM; 264 return -ENOMEM;
243 if (!(radio->videodev = video_device_alloc())) { 265 if (!(radio->videodev = video_device_alloc())) {
244 kfree(radio); 266 kfree(radio);
@@ -271,7 +293,7 @@ code I'd expect I better did that, but if there's a memory
271leak here it's tiny (~50 bytes per disconnect) */ 293leak here it's tiny (~50 bytes per disconnect) */
272static void usb_dsbr100_disconnect(struct usb_interface *intf) 294static void usb_dsbr100_disconnect(struct usb_interface *intf)
273{ 295{
274 dsbr100_device *radio = usb_get_intfdata(intf); 296 struct dsbr100_device *radio = usb_get_intfdata(intf);
275 297
276 usb_set_intfdata (intf, NULL); 298 usb_set_intfdata (intf, NULL);
277 if (radio) { 299 if (radio) {
@@ -291,89 +313,121 @@ static void usb_dsbr100_disconnect(struct usb_interface *intf)
291static int usb_dsbr100_do_ioctl(struct inode *inode, struct file *file, 313static int usb_dsbr100_do_ioctl(struct inode *inode, struct file *file,
292 unsigned int cmd, void *arg) 314 unsigned int cmd, void *arg)
293{ 315{
294 dsbr100_device *radio=video_get_drvdata(video_devdata(file)); 316 struct dsbr100_device *radio=video_get_drvdata(video_devdata(file));
295 317
296 if (!radio) 318 if (!radio)
297 return -EIO; 319 return -EIO;
298 320
299 switch(cmd) { 321 switch(cmd) {
300 case VIDIOCGCAP: { 322 case VIDIOC_QUERYCAP:
301 struct video_capability *v = arg; 323 {
302 324 struct v4l2_capability *v = arg;
303 memset(v, 0, sizeof(*v)); 325 memset(v,0,sizeof(*v));
304 v->type = VID_TYPE_TUNER; 326 strlcpy(v->driver, "dsbr100", sizeof (v->driver));
305 v->channels = 1; 327 strlcpy(v->card, "D-Link R-100 USB FM Radio", sizeof (v->card));
306 v->audios = 1; 328 sprintf(v->bus_info,"ISA");
307 strcpy(v->name, "D-Link R-100 USB FM Radio"); 329 v->version = RADIO_VERSION;
330 v->capabilities = V4L2_CAP_TUNER;
331
308 return 0; 332 return 0;
309 } 333 }
310 case VIDIOCGTUNER: { 334 case VIDIOC_G_TUNER:
311 struct video_tuner *v = arg; 335 {
336 struct v4l2_tuner *v = arg;
312 337
313 dsbr100_getstat(radio); 338 if (v->index > 0)
314 if(v->tuner) /* Only 1 tuner */
315 return -EINVAL; 339 return -EINVAL;
340
341 dsbr100_getstat(radio);
342
343 memset(v,0,sizeof(*v));
344 strcpy(v->name, "FM");
345 v->type = V4L2_TUNER_RADIO;
346
316 v->rangelow = FREQ_MIN*FREQ_MUL; 347 v->rangelow = FREQ_MIN*FREQ_MUL;
317 v->rangehigh = FREQ_MAX*FREQ_MUL; 348 v->rangehigh = FREQ_MAX*FREQ_MUL;
318 v->flags = VIDEO_TUNER_LOW; 349 v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
319 v->mode = VIDEO_MODE_AUTO; 350 v->capability=V4L2_TUNER_CAP_LOW;
320 v->signal = radio->stereo*0x7000; 351 if(radio->stereo)
321 /* Don't know how to get signal strength */ 352 v->audmode = V4L2_TUNER_MODE_STEREO;
322 v->flags |= VIDEO_TUNER_STEREO_ON*radio->stereo; 353 else
323 strcpy(v->name, "DSB R-100"); 354 v->audmode = V4L2_TUNER_MODE_MONO;
324 return 0; 355 v->signal = 0xFFFF; /* We can't get the signal strength */
325 }
326 case VIDIOCSTUNER: {
327 struct video_tuner *v = arg;
328 356
329 if(v->tuner!=0)
330 return -EINVAL;
331 /* Only 1 tuner so no setting needed ! */
332 return 0; 357 return 0;
333 } 358 }
334 case VIDIOCGFREQ: { 359 case VIDIOC_S_TUNER:
335 int *freq = arg; 360 {
361 struct v4l2_tuner *v = arg;
336 362
337 if (radio->curfreq==-1) 363 if (v->index > 0)
338 return -EINVAL; 364 return -EINVAL;
339 *freq = radio->curfreq; 365
340 return 0; 366 return 0;
341 } 367 }
342 case VIDIOCSFREQ: { 368 case VIDIOC_S_FREQUENCY:
343 int *freq = arg; 369 {
370 struct v4l2_frequency *f = arg;
344 371
345 radio->curfreq = *freq; 372 radio->curfreq = f->frequency;
346 if (dsbr100_setfreq(radio, radio->curfreq)==-1) 373 if (dsbr100_setfreq(radio, radio->curfreq)==-1)
347 warn("Set frequency failed"); 374 warn("Set frequency failed");
348 return 0; 375 return 0;
349 } 376 }
350 case VIDIOCGAUDIO: { 377 case VIDIOC_G_FREQUENCY:
351 struct video_audio *v = arg; 378 {
352 379 struct v4l2_frequency *f = arg;
353 memset(v, 0, sizeof(*v)); 380
354 v->flags |= VIDEO_AUDIO_MUTABLE; 381 f->type = V4L2_TUNER_RADIO;
355 v->mode = VIDEO_SOUND_STEREO; 382 f->frequency = radio->curfreq;
356 v->volume = 1; 383
357 v->step = 1;
358 strcpy(v->name, "Radio");
359 return 0; 384 return 0;
360 } 385 }
361 case VIDIOCSAUDIO: { 386 case VIDIOC_QUERYCTRL:
362 struct video_audio *v = arg; 387 {
363 388 struct v4l2_queryctrl *qc = arg;
364 if (v->audio) 389 int i;
365 return -EINVAL; 390
366 if (v->flags&VIDEO_AUDIO_MUTE) { 391 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
367 if (dsbr100_stop(radio)==-1) 392 if (qc->id && qc->id == radio_qctrl[i].id) {
368 warn("Radio did not respond properly"); 393 memcpy(qc, &(radio_qctrl[i]),
394 sizeof(*qc));
395 return 0;
396 }
369 } 397 }
370 else 398 return -EINVAL;
371 if (dsbr100_start(radio)==-1) 399 }
372 warn("Radio did not respond properly"); 400 case VIDIOC_G_CTRL:
373 return 0; 401 {
402 struct v4l2_control *ctrl= arg;
403
404 switch (ctrl->id) {
405 case V4L2_CID_AUDIO_MUTE:
406 ctrl->value=radio->muted;
407 return 0;
408 }
409 return -EINVAL;
410 }
411 case VIDIOC_S_CTRL:
412 {
413 struct v4l2_control *ctrl= arg;
414
415 switch (ctrl->id) {
416 case V4L2_CID_AUDIO_MUTE:
417 if (ctrl->value) {
418 if (dsbr100_stop(radio)==-1)
419 warn("Radio did not respond properly");
420 } else {
421 if (dsbr100_start(radio)==-1)
422 warn("Radio did not respond properly");
423 }
424 return 0;
425 }
426 return -EINVAL;
374 } 427 }
375 default: 428 default:
376 return -ENOIOCTLCMD; 429 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
430 usb_dsbr100_do_ioctl);
377 } 431 }
378} 432}
379 433
@@ -385,9 +439,11 @@ static int usb_dsbr100_ioctl(struct inode *inode, struct file *file,
385 439
386static int usb_dsbr100_open(struct inode *inode, struct file *file) 440static int usb_dsbr100_open(struct inode *inode, struct file *file)
387{ 441{
388 dsbr100_device *radio=video_get_drvdata(video_devdata(file)); 442 struct dsbr100_device *radio=video_get_drvdata(video_devdata(file));
389 443
390 radio->users = 1; 444 radio->users = 1;
445 radio->muted = 1;
446
391 if (dsbr100_start(radio)<0) { 447 if (dsbr100_start(radio)<0) {
392 warn("Radio did not start up properly"); 448 warn("Radio did not start up properly");
393 radio->users = 0; 449 radio->users = 0;
@@ -399,7 +455,7 @@ static int usb_dsbr100_open(struct inode *inode, struct file *file)
399 455
400static int usb_dsbr100_close(struct inode *inode, struct file *file) 456static int usb_dsbr100_close(struct inode *inode, struct file *file)
401{ 457{
402 dsbr100_device *radio=video_get_drvdata(video_devdata(file)); 458 struct dsbr100_device *radio=video_get_drvdata(video_devdata(file));
403 459
404 if (!radio) 460 if (!radio)
405 return -ENODEV; 461 return -ENODEV;
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
215static 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
212static int rt_do_ioctl(struct inode *inode, struct file *file, 234static 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
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c
index 95e6322133ee..3ba5fa8cf7e6 100644
--- a/drivers/media/radio/radio-aztech.c
+++ b/drivers/media/radio/radio-aztech.c
@@ -1,5 +1,6 @@
1/* radio-aztech.c - Aztech radio card driver for Linux 2.2 1/* radio-aztech.c - Aztech radio card driver for Linux 2.2
2 * 2 *
3 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
3 * Adapted to support the Video for Linux API by 4 * Adapted to support the Video for Linux API by
4 * Russell Kroll <rkroll@exploits.org>. Based on original tuner code by: 5 * Russell Kroll <rkroll@exploits.org>. Based on original tuner code by:
5 * 6 *
@@ -30,9 +31,30 @@
30#include <linux/delay.h> /* udelay */ 31#include <linux/delay.h> /* udelay */
31#include <asm/io.h> /* outb, outb_p */ 32#include <asm/io.h> /* outb, outb_p */
32#include <asm/uaccess.h> /* copy to/from user */ 33#include <asm/uaccess.h> /* copy to/from user */
33#include <linux/videodev.h> /* kernel radio structs */ 34#include <linux/videodev2.h> /* kernel radio structs */
34#include <media/v4l2-common.h> 35#include <media/v4l2-common.h>
35#include <linux/config.h> /* CONFIG_RADIO_AZTECH_PORT */ 36
37#include <linux/version.h> /* for KERNEL_VERSION MACRO */
38#define RADIO_VERSION KERNEL_VERSION(0,0,2)
39
40static struct v4l2_queryctrl radio_qctrl[] = {
41 {
42 .id = V4L2_CID_AUDIO_MUTE,
43 .name = "Mute",
44 .minimum = 0,
45 .maximum = 1,
46 .default_value = 1,
47 .type = V4L2_CTRL_TYPE_BOOLEAN,
48 },{
49 .id = V4L2_CID_AUDIO_VOLUME,
50 .name = "Volume",
51 .minimum = 0,
52 .maximum = 0xff,
53 .step = 1,
54 .default_value = 0xff,
55 .type = V4L2_CTRL_TYPE_INTEGER,
56 }
57};
36 58
37/* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */ 59/* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */
38 60
@@ -166,81 +188,121 @@ static int az_do_ioctl(struct inode *inode, struct file *file,
166 188
167 switch(cmd) 189 switch(cmd)
168 { 190 {
169 case VIDIOCGCAP: 191 case VIDIOC_QUERYCAP:
170 { 192 {
171 struct video_capability *v = arg; 193 struct v4l2_capability *v = arg;
172 memset(v,0,sizeof(*v)); 194 memset(v,0,sizeof(*v));
173 v->type=VID_TYPE_TUNER; 195 strlcpy(v->driver, "radio-aztech", sizeof (v->driver));
174 v->channels=1; 196 strlcpy(v->card, "Aztech Radio", sizeof (v->card));
175 v->audios=1; 197 sprintf(v->bus_info,"ISA");
176 strcpy(v->name, "Aztech Radio"); 198 v->version = RADIO_VERSION;
199 v->capabilities = V4L2_CAP_TUNER;
200
177 return 0; 201 return 0;
178 } 202 }
179 case VIDIOCGTUNER: 203 case VIDIOC_G_TUNER:
180 { 204 {
181 struct video_tuner *v = arg; 205 struct v4l2_tuner *v = arg;
182 if(v->tuner) /* Only 1 tuner */ 206
207 if (v->index > 0)
183 return -EINVAL; 208 return -EINVAL;
209
210 memset(v,0,sizeof(*v));
211 strcpy(v->name, "FM");
212 v->type = V4L2_TUNER_RADIO;
213
184 v->rangelow=(87*16000); 214 v->rangelow=(87*16000);
185 v->rangehigh=(108*16000); 215 v->rangehigh=(108*16000);
186 v->flags=VIDEO_TUNER_LOW; 216 v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
187 v->mode=VIDEO_MODE_AUTO; 217 v->capability=V4L2_TUNER_CAP_LOW;
188 v->signal=0xFFFF*az_getsigstr(az);
189 if(az_getstereo(az)) 218 if(az_getstereo(az))
190 v->flags|=VIDEO_TUNER_STEREO_ON; 219 v->audmode = V4L2_TUNER_MODE_STEREO;
191 strcpy(v->name, "FM"); 220 else
221 v->audmode = V4L2_TUNER_MODE_MONO;
222 v->signal=0xFFFF*az_getsigstr(az);
223
192 return 0; 224 return 0;
193 } 225 }
194 case VIDIOCSTUNER: 226 case VIDIOC_S_TUNER:
195 { 227 {
196 struct video_tuner *v = arg; 228 struct v4l2_tuner *v = arg;
197 if(v->tuner!=0) 229
230 if (v->index > 0)
198 return -EINVAL; 231 return -EINVAL;
232
199 return 0; 233 return 0;
200 } 234 }
201 case VIDIOCGFREQ: 235 case VIDIOC_S_FREQUENCY:
202 { 236 {
203 unsigned long *freq = arg; 237 struct v4l2_frequency *f = arg;
204 *freq = az->curfreq; 238
239 az->curfreq = f->frequency;
240 az_setfreq(az, az->curfreq);
205 return 0; 241 return 0;
206 } 242 }
207 case VIDIOCSFREQ: 243 case VIDIOC_G_FREQUENCY:
208 { 244 {
209 unsigned long *freq = arg; 245 struct v4l2_frequency *f = arg;
210 az->curfreq = *freq; 246
211 az_setfreq(az, az->curfreq); 247 f->type = V4L2_TUNER_RADIO;
248 f->frequency = az->curfreq;
249
212 return 0; 250 return 0;
213 } 251 }
214 case VIDIOCGAUDIO: 252
253 case VIDIOC_QUERYCTRL:
215 { 254 {
216 struct video_audio *v = arg; 255 struct v4l2_queryctrl *qc = arg;
217 memset(v,0, sizeof(*v)); 256 int i;
218 v->flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME; 257
219 if(az->stereo) 258 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
220 v->mode=VIDEO_SOUND_STEREO; 259 if (qc->id && qc->id == radio_qctrl[i].id) {
221 else 260 memcpy(qc, &(radio_qctrl[i]),
222 v->mode=VIDEO_SOUND_MONO; 261 sizeof(*qc));
223 v->volume=az->curvol; 262 return (0);
224 v->step=16384; 263 }
225 strcpy(v->name, "Radio"); 264 }
226 return 0; 265 return -EINVAL;
227 } 266 }
228 case VIDIOCSAUDIO: 267 case VIDIOC_G_CTRL:
229 { 268 {
230 struct video_audio *v = arg; 269 struct v4l2_control *ctrl= arg;
231 if(v->audio) 270
232 return -EINVAL; 271 switch (ctrl->id) {
233 az->curvol=v->volume; 272 case V4L2_CID_AUDIO_MUTE:
234 273 if (az->curvol==0)
235 az->stereo=(v->mode&VIDEO_SOUND_STEREO)?1:0; 274 ctrl->value=1;
236 if(v->flags&VIDEO_AUDIO_MUTE) 275 else
237 az_setvol(az,0); 276 ctrl->value=0;
238 else 277 return (0);
239 az_setvol(az,az->curvol); 278 case V4L2_CID_AUDIO_VOLUME:
240 return 0; 279 ctrl->value=az->curvol * 6554;
280 return (0);
281 }
282 return -EINVAL;
283 }
284 case VIDIOC_S_CTRL:
285 {
286 struct v4l2_control *ctrl= arg;
287
288 switch (ctrl->id) {
289 case V4L2_CID_AUDIO_MUTE:
290 if (ctrl->value) {
291 az_setvol(az,0);
292 } else {
293 az_setvol(az,az->curvol);
294 }
295 return (0);
296 case V4L2_CID_AUDIO_VOLUME:
297 az_setvol(az,ctrl->value);
298 return (0);
299 }
300 return -EINVAL;
241 } 301 }
302
242 default: 303 default:
243 return -ENOIOCTLCMD; 304 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
305 az_do_ioctl);
244 } 306 }
245} 307}
246 308
@@ -266,7 +328,7 @@ static struct video_device aztech_radio=
266 .owner = THIS_MODULE, 328 .owner = THIS_MODULE,
267 .name = "Aztech radio", 329 .name = "Aztech radio",
268 .type = VID_TYPE_TUNER, 330 .type = VID_TYPE_TUNER,
269 .hardware = VID_HARDWARE_AZTECH, 331 .hardware = 0,
270 .fops = &aztech_fops, 332 .fops = &aztech_fops,
271}; 333};
272 334
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
index 8641aec7baf8..69d4b7919c5a 100644
--- a/drivers/media/radio/radio-cadet.c
+++ b/drivers/media/radio/radio-cadet.c
@@ -25,20 +25,28 @@
25 * 25 *
26 * 2003-01-31 Alan Cox <alan@redhat.com> 26 * 2003-01-31 Alan Cox <alan@redhat.com>
27 * Cleaned up locking, delay code, general odds and ends 27 * Cleaned up locking, delay code, general odds and ends
28 *
29 * 2006-07-30 Hans J. Koch <koch@hjk-az.de>
30 * Changed API to V4L2
28 */ 31 */
29 32
33#include <linux/version.h>
30#include <linux/module.h> /* Modules */ 34#include <linux/module.h> /* Modules */
31#include <linux/init.h> /* Initdata */ 35#include <linux/init.h> /* Initdata */
32#include <linux/ioport.h> /* request_region */ 36#include <linux/ioport.h> /* request_region */
33#include <linux/delay.h> /* udelay */ 37#include <linux/delay.h> /* udelay */
34#include <asm/io.h> /* outb, outb_p */ 38#include <asm/io.h> /* outb, outb_p */
35#include <asm/uaccess.h> /* copy to/from user */ 39#include <asm/uaccess.h> /* copy to/from user */
36#include <linux/videodev.h> /* kernel radio structs */ 40#include <linux/videodev2.h> /* V4L2 API defs */
37#include <media/v4l2-common.h> 41#include <media/v4l2-common.h>
38#include <linux/param.h> 42#include <linux/param.h>
39#include <linux/pnp.h> 43#include <linux/pnp.h>
40 44
41#define RDS_BUFFER 256 45#define RDS_BUFFER 256
46#define RDS_RX_FLAG 1
47#define MBS_RX_FLAG 2
48
49#define CADET_VERSION KERNEL_VERSION(0,3,3)
42 50
43static int io=-1; /* default to isapnp activation */ 51static int io=-1; /* default to isapnp activation */
44static int radio_nr = -1; 52static int radio_nr = -1;
@@ -61,44 +69,24 @@ static int cadet_probe(void);
61 */ 69 */
62static __u16 sigtable[2][4]={{5,10,30,150},{28,40,63,1000}}; 70static __u16 sigtable[2][4]={{5,10,30,150},{28,40,63,1000}};
63 71
64static int cadet_getrds(void)
65{
66 int rdsstat=0;
67
68 spin_lock(&cadet_io_lock);
69 outb(3,io); /* Select Decoder Control/Status */
70 outb(inb(io+1)&0x7f,io+1); /* Reset RDS detection */
71 spin_unlock(&cadet_io_lock);
72
73 msleep(100);
74
75 spin_lock(&cadet_io_lock);
76 outb(3,io); /* Select Decoder Control/Status */
77 if((inb(io+1)&0x80)!=0) {
78 rdsstat|=VIDEO_TUNER_RDS_ON;
79 }
80 if((inb(io+1)&0x10)!=0) {
81 rdsstat|=VIDEO_TUNER_MBS_ON;
82 }
83 spin_unlock(&cadet_io_lock);
84 return rdsstat;
85}
86 72
87static int cadet_getstereo(void) 73static int
74cadet_getstereo(void)
88{ 75{
89 int ret = 0; 76 int ret = V4L2_TUNER_SUB_MONO;
90 if(curtuner != 0) /* Only FM has stereo capability! */ 77 if(curtuner != 0) /* Only FM has stereo capability! */
91 return 0; 78 return V4L2_TUNER_SUB_MONO;
92 79
93 spin_lock(&cadet_io_lock); 80 spin_lock(&cadet_io_lock);
94 outb(7,io); /* Select tuner control */ 81 outb(7,io); /* Select tuner control */
95 if( (inb(io+1) & 0x40) == 0) 82 if( (inb(io+1) & 0x40) == 0)
96 ret = 1; 83 ret = V4L2_TUNER_SUB_STEREO;
97 spin_unlock(&cadet_io_lock); 84 spin_unlock(&cadet_io_lock);
98 return ret; 85 return ret;
99} 86}
100 87
101static unsigned cadet_gettune(void) 88static unsigned
89cadet_gettune(void)
102{ 90{
103 int curvol,i; 91 int curvol,i;
104 unsigned fifo=0; 92 unsigned fifo=0;
@@ -135,7 +123,8 @@ static unsigned cadet_gettune(void)
135 return fifo; 123 return fifo;
136} 124}
137 125
138static unsigned cadet_getfreq(void) 126static unsigned
127cadet_getfreq(void)
139{ 128{
140 int i; 129 int i;
141 unsigned freq=0,test,fifo=0; 130 unsigned freq=0,test,fifo=0;
@@ -167,7 +156,8 @@ static unsigned cadet_getfreq(void)
167 return freq; 156 return freq;
168} 157}
169 158
170static void cadet_settune(unsigned fifo) 159static void
160cadet_settune(unsigned fifo)
171{ 161{
172 int i; 162 int i;
173 unsigned test; 163 unsigned test;
@@ -195,7 +185,8 @@ static void cadet_settune(unsigned fifo)
195 spin_unlock(&cadet_io_lock); 185 spin_unlock(&cadet_io_lock);
196} 186}
197 187
198static void cadet_setfreq(unsigned freq) 188static void
189cadet_setfreq(unsigned freq)
199{ 190{
200 unsigned fifo; 191 unsigned fifo;
201 int i,j,test; 192 int i,j,test;
@@ -255,7 +246,8 @@ static void cadet_setfreq(unsigned freq)
255} 246}
256 247
257 248
258static int cadet_getvol(void) 249static int
250cadet_getvol(void)
259{ 251{
260 int ret = 0; 252 int ret = 0;
261 253
@@ -270,7 +262,8 @@ static int cadet_getvol(void)
270} 262}
271 263
272 264
273static void cadet_setvol(int vol) 265static void
266cadet_setvol(int vol)
274{ 267{
275 spin_lock(&cadet_io_lock); 268 spin_lock(&cadet_io_lock);
276 outb(7,io); /* Select tuner control */ 269 outb(7,io); /* Select tuner control */
@@ -281,7 +274,8 @@ static void cadet_setvol(int vol)
281 spin_unlock(&cadet_io_lock); 274 spin_unlock(&cadet_io_lock);
282} 275}
283 276
284static void cadet_handler(unsigned long data) 277static void
278cadet_handler(unsigned long data)
285{ 279{
286 /* 280 /*
287 * Service the RDS fifo 281 * Service the RDS fifo
@@ -322,8 +316,8 @@ static void cadet_handler(unsigned long data)
322 316
323 317
324 318
325static ssize_t cadet_read(struct file *file, char __user *data, 319static ssize_t
326 size_t count, loff_t *ppos) 320cadet_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
327{ 321{
328 int i=0; 322 int i=0;
329 unsigned char readbuf[RDS_BUFFER]; 323 unsigned char readbuf[RDS_BUFFER];
@@ -359,128 +353,156 @@ static int cadet_do_ioctl(struct inode *inode, struct file *file,
359{ 353{
360 switch(cmd) 354 switch(cmd)
361 { 355 {
362 case VIDIOCGCAP: 356 case VIDIOC_QUERYCAP:
363 { 357 {
364 struct video_capability *v = arg; 358 struct v4l2_capability *cap = arg;
365 memset(v,0,sizeof(*v)); 359 memset(cap,0,sizeof(*cap));
366 v->type=VID_TYPE_TUNER; 360 cap->capabilities =
367 v->channels=2; 361 V4L2_CAP_TUNER |
368 v->audios=1; 362 V4L2_CAP_READWRITE;
369 strcpy(v->name, "ADS Cadet"); 363 cap->version = CADET_VERSION;
364 strcpy(cap->driver, "ADS Cadet");
365 strcpy(cap->card, "ADS Cadet");
370 return 0; 366 return 0;
371 } 367 }
372 case VIDIOCGTUNER: 368 case VIDIOC_G_TUNER:
373 { 369 {
374 struct video_tuner *v = arg; 370 struct v4l2_tuner *t = arg;
375 if((v->tuner<0)||(v->tuner>1)) { 371 memset(t,0,sizeof(*t));
376 return -EINVAL; 372 t->type = V4L2_TUNER_RADIO;
377 } 373 switch (t->index)
378 switch(v->tuner) { 374 {
379 case 0: 375 case 0: strcpy(t->name, "FM");
380 strcpy(v->name,"FM"); 376 t->capability = V4L2_TUNER_CAP_STEREO;
381 v->rangelow=1400; /* 87.5 MHz */ 377 t->rangelow = 1400; /* 87.5 MHz */
382 v->rangehigh=1728; /* 108.0 MHz */ 378 t->rangehigh = 1728; /* 108.0 MHz */
383 v->flags=0; 379 t->rxsubchans=cadet_getstereo();
384 v->mode=0; 380 switch (t->rxsubchans){
385 v->mode|=VIDEO_MODE_AUTO; 381 case V4L2_TUNER_SUB_MONO:
386 v->signal=sigstrength; 382 t->audmode = V4L2_TUNER_MODE_MONO;
387 if(cadet_getstereo()==1) { 383 break;
388 v->flags|=VIDEO_TUNER_STEREO_ON; 384 case V4L2_TUNER_SUB_STEREO:
389 } 385 t->audmode = V4L2_TUNER_MODE_STEREO;
390 v->flags|=cadet_getrds(); 386 break;
391 break; 387 default: ;
392 case 1: 388 }
393 strcpy(v->name,"AM"); 389 break;
394 v->rangelow=8320; /* 520 kHz */ 390 case 1: strcpy(t->name, "AM");
395 v->rangehigh=26400; /* 1650 kHz */ 391 t->capability = V4L2_TUNER_CAP_LOW;
396 v->flags=0; 392 t->rangelow = 8320; /* 520 kHz */
397 v->flags|=VIDEO_TUNER_LOW; 393 t->rangehigh = 26400; /* 1650 kHz */
398 v->mode=0; 394 t->rxsubchans = V4L2_TUNER_SUB_MONO;
399 v->mode|=VIDEO_MODE_AUTO; 395 t->audmode = V4L2_TUNER_MODE_MONO;
400 v->signal=sigstrength; 396 break;
401 break; 397 default:
398 return -EINVAL;
402 } 399 }
400
401 t->signal = sigstrength; /* We might need to modify scaling of this */
403 return 0; 402 return 0;
404 } 403 }
405 case VIDIOCSTUNER: 404 case VIDIOC_S_TUNER:
406 { 405 {
407 struct video_tuner *v = arg; 406 struct v4l2_tuner *t = arg;
408 if((v->tuner<0)||(v->tuner>1)) { 407 if((t->index != 0)&&(t->index != 1))
409 return -EINVAL; 408 return -EINVAL;
410 } 409
411 curtuner=v->tuner; 410 curtuner = t->index;
412 return 0; 411 return 0;
413 } 412 }
414 case VIDIOCGFREQ: 413 case VIDIOC_G_FREQUENCY:
415 { 414 {
416 unsigned long *freq = arg; 415 struct v4l2_frequency *f = arg;
417 *freq = cadet_getfreq(); 416 memset(f,0,sizeof(*f));
417 f->tuner = curtuner;
418 f->type = V4L2_TUNER_RADIO;
419 f->frequency = cadet_getfreq();
418 return 0; 420 return 0;
419 } 421 }
420 case VIDIOCSFREQ: 422 case VIDIOC_S_FREQUENCY:
421 { 423 {
422 unsigned long *freq = arg; 424 struct v4l2_frequency *f = arg;
423 if((curtuner==0)&&((*freq<1400)||(*freq>1728))) { 425 if (f->type != V4L2_TUNER_RADIO){
426 return -EINVAL;
427 }
428 if((curtuner==0)&&((f->frequency<1400)||(f->frequency>1728))) {
424 return -EINVAL; 429 return -EINVAL;
425 } 430 }
426 if((curtuner==1)&&((*freq<8320)||(*freq>26400))) { 431 if((curtuner==1)&&((f->frequency<8320)||(f->frequency>26400))) {
427 return -EINVAL; 432 return -EINVAL;
428 } 433 }
429 cadet_setfreq(*freq); 434 cadet_setfreq(f->frequency);
430 return 0; 435 return 0;
431 } 436 }
432 case VIDIOCGAUDIO: 437 case VIDIOC_G_CTRL:
433 { 438 {
434 struct video_audio *v = arg; 439 struct v4l2_control *c = arg;
435 memset(v,0, sizeof(*v)); 440 switch (c->id){
436 v->flags=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME; 441 case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */
437 if(cadet_getstereo()==0) { 442 c->value = (cadet_getvol() == 0);
438 v->mode=VIDEO_SOUND_MONO; 443 break;
439 } else { 444 case V4L2_CID_AUDIO_VOLUME:
440 v->mode=VIDEO_SOUND_STEREO; 445 c->value = cadet_getvol();
446 break;
447 default:
448 return -EINVAL;
441 } 449 }
442 v->volume=cadet_getvol();
443 v->step=0xffff;
444 strcpy(v->name, "Radio");
445 return 0; 450 return 0;
446 } 451 }
447 case VIDIOCSAUDIO: 452 case VIDIOC_S_CTRL:
448 { 453 {
449 struct video_audio *v = arg; 454 struct v4l2_control *c = arg;
450 if(v->audio) 455 switch (c->id){
451 return -EINVAL; 456 case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */
452 cadet_setvol(v->volume); 457 if (c->value) cadet_setvol(0);
453 if(v->flags&VIDEO_AUDIO_MUTE) 458 else cadet_setvol(0xffff);
454 cadet_setvol(0); 459 break;
455 else 460 case V4L2_CID_AUDIO_VOLUME:
456 cadet_setvol(0xffff); 461 cadet_setvol(c->value);
462 break;
463 default:
464 return -EINVAL;
465 }
457 return 0; 466 return 0;
458 } 467 }
468
459 default: 469 default:
460 return -ENOIOCTLCMD; 470 return -ENOIOCTLCMD;
461 } 471 }
462} 472}
463 473
464static int cadet_ioctl(struct inode *inode, struct file *file, 474static int
475cadet_ioctl(struct inode *inode, struct file *file,
465 unsigned int cmd, unsigned long arg) 476 unsigned int cmd, unsigned long arg)
466{ 477{
467 return video_usercopy(inode, file, cmd, arg, cadet_do_ioctl); 478 return video_usercopy(inode, file, cmd, arg, cadet_do_ioctl);
468} 479}
469 480
470static int cadet_open(struct inode *inode, struct file *file) 481static int
482cadet_open(struct inode *inode, struct file *file)
471{ 483{
472 if(users)
473 return -EBUSY;
474 users++; 484 users++;
475 init_waitqueue_head(&read_queue); 485 if (1 == users) init_waitqueue_head(&read_queue);
476 return 0; 486 return 0;
477} 487}
478 488
479static int cadet_release(struct inode *inode, struct file *file) 489static int
490cadet_release(struct inode *inode, struct file *file)
480{ 491{
481 del_timer_sync(&readtimer);
482 rdsstat=0;
483 users--; 492 users--;
493 if (0 == users){
494 del_timer_sync(&readtimer);
495 rdsstat=0;
496 }
497 return 0;
498}
499
500static unsigned int
501cadet_poll(struct file *file, struct poll_table_struct *wait)
502{
503 poll_wait(file,&read_queue,wait);
504 if(rdsin != rdsout)
505 return POLLIN | POLLRDNORM;
484 return 0; 506 return 0;
485} 507}
486 508
@@ -491,6 +513,7 @@ static struct file_operations cadet_fops = {
491 .release = cadet_release, 513 .release = cadet_release,
492 .read = cadet_read, 514 .read = cadet_read,
493 .ioctl = cadet_ioctl, 515 .ioctl = cadet_ioctl,
516 .poll = cadet_poll,
494 .compat_ioctl = v4l_compat_ioctl32, 517 .compat_ioctl = v4l_compat_ioctl32,
495 .llseek = no_llseek, 518 .llseek = no_llseek,
496}; 519};
@@ -500,7 +523,6 @@ static struct video_device cadet_radio=
500 .owner = THIS_MODULE, 523 .owner = THIS_MODULE,
501 .name = "Cadet radio", 524 .name = "Cadet radio",
502 .type = VID_TYPE_TUNER, 525 .type = VID_TYPE_TUNER,
503 .hardware = VID_HARDWARE_CADET,
504 .fops = &cadet_fops, 526 .fops = &cadet_fops,
505}; 527};
506 528
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c
index 4c82956390c1..cfab57d6bc4a 100644
--- a/drivers/media/radio/radio-gemtek-pci.c
+++ b/drivers/media/radio/radio-gemtek-pci.c
@@ -34,6 +34,8 @@
34 * 34 *
35 * TODO: multiple device support and portability were not tested 35 * TODO: multiple device support and portability were not tested
36 * 36 *
37 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
38 *
37 *************************************************************************** 39 ***************************************************************************
38 */ 40 */
39 41
@@ -42,10 +44,32 @@
42#include <linux/module.h> 44#include <linux/module.h>
43#include <linux/init.h> 45#include <linux/init.h>
44#include <linux/pci.h> 46#include <linux/pci.h>
45#include <linux/videodev.h> 47#include <linux/videodev2.h>
46#include <media/v4l2-common.h> 48#include <media/v4l2-common.h>
47#include <linux/errno.h> 49#include <linux/errno.h>
48 50
51#include <linux/version.h> /* for KERNEL_VERSION MACRO */
52#define RADIO_VERSION KERNEL_VERSION(0,0,2)
53
54static struct v4l2_queryctrl radio_qctrl[] = {
55 {
56 .id = V4L2_CID_AUDIO_MUTE,
57 .name = "Mute",
58 .minimum = 0,
59 .maximum = 1,
60 .default_value = 1,
61 .type = V4L2_CTRL_TYPE_BOOLEAN,
62 },{
63 .id = V4L2_CID_AUDIO_VOLUME,
64 .name = "Volume",
65 .minimum = 0,
66 .maximum = 65535,
67 .step = 65535,
68 .default_value = 0xff,
69 .type = V4L2_CTRL_TYPE_INTEGER,
70 }
71};
72
49#include <asm/io.h> 73#include <asm/io.h>
50#include <asm/uaccess.h> 74#include <asm/uaccess.h>
51 75
@@ -183,91 +207,117 @@ static int gemtek_pci_do_ioctl(struct inode *inode, struct file *file,
183 struct gemtek_pci_card *card = dev->priv; 207 struct gemtek_pci_card *card = dev->priv;
184 208
185 switch ( cmd ) { 209 switch ( cmd ) {
186 case VIDIOCGCAP: 210 case VIDIOC_QUERYCAP:
187 { 211 {
188 struct video_capability *c = arg; 212 struct v4l2_capability *v = arg;
213 memset(v,0,sizeof(*v));
214 strlcpy(v->driver, "radio-gemtek-pci", sizeof (v->driver));
215 strlcpy(v->card, "GemTek PCI Radio", sizeof (v->card));
216 sprintf(v->bus_info,"ISA");
217 v->version = RADIO_VERSION;
218 v->capabilities = V4L2_CAP_TUNER;
189 219
190 memset(c,0,sizeof(*c));
191 c->type = VID_TYPE_TUNER;
192 c->channels = 1;
193 c->audios = 1;
194 strcpy( c->name, "Gemtek PCI Radio" );
195 return 0; 220 return 0;
196 } 221 }
197 222 case VIDIOC_G_TUNER:
198 case VIDIOCGTUNER:
199 { 223 {
200 struct video_tuner *t = arg; 224 struct v4l2_tuner *v = arg;
201 225
202 if ( t->tuner ) 226 if (v->index > 0)
203 return -EINVAL; 227 return -EINVAL;
204 228
205 t->rangelow = GEMTEK_PCI_RANGE_LOW; 229 memset(v,0,sizeof(*v));
206 t->rangehigh = GEMTEK_PCI_RANGE_HIGH; 230 strcpy(v->name, "FM");
207 t->flags = VIDEO_TUNER_LOW; 231 v->type = V4L2_TUNER_RADIO;
208 t->mode = VIDEO_MODE_AUTO; 232
209 t->signal = 0xFFFF * gemtek_pci_getsignal( card ); 233 v->rangelow = GEMTEK_PCI_RANGE_LOW;
210 strcpy( t->name, "FM" ); 234 v->rangehigh = GEMTEK_PCI_RANGE_HIGH;
235 v->rxsubchans =V4L2_TUNER_SUB_MONO;
236 v->capability=V4L2_TUNER_CAP_LOW;
237 v->audmode = V4L2_TUNER_MODE_MONO;
238 v->signal=0xFFFF*gemtek_pci_getsignal( card );
239
211 return 0; 240 return 0;
212 } 241 }
213 242 case VIDIOC_S_TUNER:
214 case VIDIOCSTUNER:
215 { 243 {
216 struct video_tuner *t = arg; 244 struct v4l2_tuner *v = arg;
217 if ( t->tuner ) 245
246 if (v->index > 0)
218 return -EINVAL; 247 return -EINVAL;
219 return 0;
220 }
221 248
222 case VIDIOCGFREQ:
223 {
224 unsigned long *freq = arg;
225 *freq = card->current_frequency;
226 return 0; 249 return 0;
227 } 250 }
228 case VIDIOCSFREQ: 251 case VIDIOC_S_FREQUENCY:
229 { 252 {
230 unsigned long *freq = arg; 253 struct v4l2_frequency *f = arg;
231 254
232 if ( (*freq < GEMTEK_PCI_RANGE_LOW) || 255 if ( (f->frequency < GEMTEK_PCI_RANGE_LOW) ||
233 (*freq > GEMTEK_PCI_RANGE_HIGH) ) 256 (f->frequency > GEMTEK_PCI_RANGE_HIGH) )
234 return -EINVAL; 257 return -EINVAL;
235 258
236 gemtek_pci_setfrequency( card, *freq );
237 card->current_frequency = *freq;
238 card->mute = FALSE;
239 259
260 gemtek_pci_setfrequency( card, f->frequency );
261 card->current_frequency = f->frequency;
262 card->mute = FALSE;
240 return 0; 263 return 0;
241 } 264 }
242 265 case VIDIOC_QUERYCTRL:
243 case VIDIOCGAUDIO:
244 { 266 {
245 struct video_audio *a = arg; 267 struct v4l2_queryctrl *qc = arg;
246 268 int i;
247 memset( a, 0, sizeof( *a ) ); 269
248 a->flags |= VIDEO_AUDIO_MUTABLE; 270 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
249 a->volume = 1; 271 if (qc->id && qc->id == radio_qctrl[i].id) {
250 a->step = 65535; 272 memcpy(qc, &(radio_qctrl[i]),
251 strcpy( a->name, "Radio" ); 273 sizeof(*qc));
252 return 0; 274 return (0);
275 }
276 }
277 return -EINVAL;
253 } 278 }
254 279 case VIDIOC_G_CTRL:
255 case VIDIOCSAUDIO:
256 { 280 {
257 struct video_audio *a = arg; 281 struct v4l2_control *ctrl= arg;
258 282
259 if ( a->audio ) 283 switch (ctrl->id) {
260 return -EINVAL; 284 case V4L2_CID_AUDIO_MUTE:
261 285 ctrl->value=card->mute;
262 if ( a->flags & VIDEO_AUDIO_MUTE ) 286 return (0);
263 gemtek_pci_mute( card ); 287 case V4L2_CID_AUDIO_VOLUME:
264 else 288 if (card->mute)
265 gemtek_pci_unmute( card ); 289 ctrl->value=0;
266 return 0; 290 else
291 ctrl->value=65535;
292 return (0);
293 }
294 return -EINVAL;
295 }
296 case VIDIOC_S_CTRL:
297 {
298 struct v4l2_control *ctrl= arg;
299
300 switch (ctrl->id) {
301 case V4L2_CID_AUDIO_MUTE:
302 if (ctrl->value) {
303 gemtek_pci_mute(card);
304 } else {
305 gemtek_pci_unmute(card);
306 }
307 return (0);
308 case V4L2_CID_AUDIO_VOLUME:
309 if (ctrl->value) {
310 gemtek_pci_unmute(card);
311 } else {
312 gemtek_pci_mute(card);
313 }
314 return (0);
315 }
316 return -EINVAL;
267 } 317 }
268
269 default: 318 default:
270 return -ENOIOCTLCMD; 319 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
320 gemtek_pci_do_ioctl);
271 } 321 }
272} 322}
273 323
@@ -309,7 +359,7 @@ static struct video_device vdev_template = {
309 .owner = THIS_MODULE, 359 .owner = THIS_MODULE,
310 .name = "Gemtek PCI Radio", 360 .name = "Gemtek PCI Radio",
311 .type = VID_TYPE_TUNER, 361 .type = VID_TYPE_TUNER,
312 .hardware = VID_HARDWARE_GEMTEK, 362 .hardware = 0,
313 .fops = &gemtek_pci_fops, 363 .fops = &gemtek_pci_fops,
314}; 364};
315 365
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
index 162f37d8bf96..730fe16126cb 100644
--- a/drivers/media/radio/radio-gemtek.c
+++ b/drivers/media/radio/radio-gemtek.c
@@ -13,6 +13,7 @@
13 * 13 *
14 * TODO: Allow for more than one of these foolish entities :-) 14 * TODO: Allow for more than one of these foolish entities :-)
15 * 15 *
16 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
16 */ 17 */
17 18
18#include <linux/module.h> /* Modules */ 19#include <linux/module.h> /* Modules */
@@ -21,11 +22,32 @@
21#include <linux/delay.h> /* udelay */ 22#include <linux/delay.h> /* udelay */
22#include <asm/io.h> /* outb, outb_p */ 23#include <asm/io.h> /* outb, outb_p */
23#include <asm/uaccess.h> /* copy to/from user */ 24#include <asm/uaccess.h> /* copy to/from user */
24#include <linux/videodev.h> /* kernel radio structs */ 25#include <linux/videodev2.h> /* kernel radio structs */
25#include <media/v4l2-common.h> 26#include <media/v4l2-common.h>
26#include <linux/config.h> /* CONFIG_RADIO_GEMTEK_PORT */
27#include <linux/spinlock.h> 27#include <linux/spinlock.h>
28 28
29#include <linux/version.h> /* for KERNEL_VERSION MACRO */
30#define RADIO_VERSION KERNEL_VERSION(0,0,2)
31
32static struct v4l2_queryctrl radio_qctrl[] = {
33 {
34 .id = V4L2_CID_AUDIO_MUTE,
35 .name = "Mute",
36 .minimum = 0,
37 .maximum = 1,
38 .default_value = 1,
39 .type = V4L2_CTRL_TYPE_BOOLEAN,
40 },{
41 .id = V4L2_CID_AUDIO_VOLUME,
42 .name = "Volume",
43 .minimum = 0,
44 .maximum = 65535,
45 .step = 65535,
46 .default_value = 0xff,
47 .type = V4L2_CTRL_TYPE_INTEGER,
48 }
49};
50
29#ifndef CONFIG_RADIO_GEMTEK_PORT 51#ifndef CONFIG_RADIO_GEMTEK_PORT
30#define CONFIG_RADIO_GEMTEK_PORT -1 52#define CONFIG_RADIO_GEMTEK_PORT -1
31#endif 53#endif
@@ -147,77 +169,122 @@ static int gemtek_do_ioctl(struct inode *inode, struct file *file,
147 169
148 switch(cmd) 170 switch(cmd)
149 { 171 {
150 case VIDIOCGCAP: 172 case VIDIOC_QUERYCAP:
151 { 173 {
152 struct video_capability *v = arg; 174 struct v4l2_capability *v = arg;
153 memset(v,0,sizeof(*v)); 175 memset(v,0,sizeof(*v));
154 v->type=VID_TYPE_TUNER; 176 strlcpy(v->driver, "radio-gemtek", sizeof (v->driver));
155 v->channels=1; 177 strlcpy(v->card, "GemTek", sizeof (v->card));
156 v->audios=1; 178 sprintf(v->bus_info,"ISA");
157 strcpy(v->name, "GemTek"); 179 v->version = RADIO_VERSION;
180 v->capabilities = V4L2_CAP_TUNER;
181
158 return 0; 182 return 0;
159 } 183 }
160 case VIDIOCGTUNER: 184 case VIDIOC_G_TUNER:
161 { 185 {
162 struct video_tuner *v = arg; 186 struct v4l2_tuner *v = arg;
163 if(v->tuner) /* Only 1 tuner */ 187
188 if (v->index > 0)
164 return -EINVAL; 189 return -EINVAL;
165 v->rangelow=87*16000; 190
166 v->rangehigh=108*16000; 191 memset(v,0,sizeof(*v));
167 v->flags=VIDEO_TUNER_LOW;
168 v->mode=VIDEO_MODE_AUTO;
169 v->signal=0xFFFF*gemtek_getsigstr(rt);
170 strcpy(v->name, "FM"); 192 strcpy(v->name, "FM");
193 v->type = V4L2_TUNER_RADIO;
194
195 v->rangelow=(87*16000);
196 v->rangehigh=(108*16000);
197 v->rxsubchans =V4L2_TUNER_SUB_MONO;
198 v->capability=V4L2_TUNER_CAP_LOW;
199 v->audmode = V4L2_TUNER_MODE_MONO;
200 v->signal=0xFFFF*gemtek_getsigstr(rt);
201
171 return 0; 202 return 0;
172 } 203 }
173 case VIDIOCSTUNER: 204 case VIDIOC_S_TUNER:
174 { 205 {
175 struct video_tuner *v = arg; 206 struct v4l2_tuner *v = arg;
176 if(v->tuner!=0) 207
208 if (v->index > 0)
177 return -EINVAL; 209 return -EINVAL;
178 /* Only 1 tuner so no setting needed ! */ 210
179 return 0;
180 }
181 case VIDIOCGFREQ:
182 {
183 unsigned long *freq = arg;
184 *freq = rt->curfreq;
185 return 0; 211 return 0;
186 } 212 }
187 case VIDIOCSFREQ: 213 case VIDIOC_S_FREQUENCY:
188 { 214 {
189 unsigned long *freq = arg; 215 struct v4l2_frequency *f = arg;
190 rt->curfreq = *freq; 216
217 rt->curfreq = f->frequency;
191 /* needs to be called twice in order for getsigstr to work */ 218 /* needs to be called twice in order for getsigstr to work */
192 gemtek_setfreq(rt, rt->curfreq); 219 gemtek_setfreq(rt, rt->curfreq);
193 gemtek_setfreq(rt, rt->curfreq); 220 gemtek_setfreq(rt, rt->curfreq);
194 return 0; 221 return 0;
195 } 222 }
196 case VIDIOCGAUDIO: 223 case VIDIOC_G_FREQUENCY:
197 {
198 struct video_audio *v = arg;
199 memset(v,0, sizeof(*v));
200 v->flags|=VIDEO_AUDIO_MUTABLE;
201 v->volume=1;
202 v->step=65535;
203 strcpy(v->name, "Radio");
204 return 0;
205 }
206 case VIDIOCSAUDIO:
207 { 224 {
208 struct video_audio *v = arg; 225 struct v4l2_frequency *f = arg;
209 if(v->audio)
210 return -EINVAL;
211 226
212 if(v->flags&VIDEO_AUDIO_MUTE) 227 f->type = V4L2_TUNER_RADIO;
213 gemtek_mute(rt); 228 f->frequency = rt->curfreq;
214 else
215 gemtek_unmute(rt);
216 229
217 return 0; 230 return 0;
218 } 231 }
232 case VIDIOC_QUERYCTRL:
233 {
234 struct v4l2_queryctrl *qc = arg;
235 int i;
236
237 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
238 if (qc->id && qc->id == radio_qctrl[i].id) {
239 memcpy(qc, &(radio_qctrl[i]),
240 sizeof(*qc));
241 return (0);
242 }
243 }
244 return -EINVAL;
245 }
246 case VIDIOC_G_CTRL:
247 {
248 struct v4l2_control *ctrl= arg;
249
250 switch (ctrl->id) {
251 case V4L2_CID_AUDIO_MUTE:
252 ctrl->value=rt->muted;
253 return (0);
254 case V4L2_CID_AUDIO_VOLUME:
255 if (rt->muted)
256 ctrl->value=0;
257 else
258 ctrl->value=65535;
259 return (0);
260 }
261 return -EINVAL;
262 }
263 case VIDIOC_S_CTRL:
264 {
265 struct v4l2_control *ctrl= arg;
266
267 switch (ctrl->id) {
268 case V4L2_CID_AUDIO_MUTE:
269 if (ctrl->value) {
270 gemtek_mute(rt);
271 } else {
272 gemtek_unmute(rt);
273 }
274 return (0);
275 case V4L2_CID_AUDIO_VOLUME:
276 if (ctrl->value) {
277 gemtek_unmute(rt);
278 } else {
279 gemtek_mute(rt);
280 }
281 return (0);
282 }
283 return -EINVAL;
284 }
219 default: 285 default:
220 return -ENOIOCTLCMD; 286 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
287 gemtek_do_ioctl);
221 } 288 }
222} 289}
223 290
@@ -243,7 +310,7 @@ static struct video_device gemtek_radio=
243 .owner = THIS_MODULE, 310 .owner = THIS_MODULE,
244 .name = "GemTek radio", 311 .name = "GemTek radio",
245 .type = VID_TYPE_TUNER, 312 .type = VID_TYPE_TUNER,
246 .hardware = VID_HARDWARE_GEMTEK, 313 .hardware = 0,
247 .fops = &gemtek_fops, 314 .fops = &gemtek_fops,
248}; 315};
249 316
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c
index fcfa6c9fe225..e8ce5f75cf12 100644
--- a/drivers/media/radio/radio-maestro.c
+++ b/drivers/media/radio/radio-maestro.c
@@ -14,6 +14,8 @@
14 * version 0.04 14 * version 0.04
15 * + code improvements 15 * + code improvements
16 * + VIDEO_TUNER_LOW is permanent 16 * + VIDEO_TUNER_LOW is permanent
17 *
18 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
17 */ 19 */
18 20
19#include <linux/module.h> 21#include <linux/module.h>
@@ -25,10 +27,23 @@
25#include <asm/uaccess.h> 27#include <asm/uaccess.h>
26#include <linux/mutex.h> 28#include <linux/mutex.h>
27#include <linux/pci.h> 29#include <linux/pci.h>
28#include <linux/videodev.h> 30#include <linux/videodev2.h>
29#include <media/v4l2-common.h> 31#include <media/v4l2-common.h>
30 32
31#define DRIVER_VERSION "0.05" 33#include <linux/version.h> /* for KERNEL_VERSION MACRO */
34#define RADIO_VERSION KERNEL_VERSION(0,0,6)
35#define DRIVER_VERSION "0.06"
36
37static struct v4l2_queryctrl radio_qctrl[] = {
38 {
39 .id = V4L2_CID_AUDIO_MUTE,
40 .name = "Mute",
41 .minimum = 0,
42 .maximum = 1,
43 .default_value = 1,
44 .type = V4L2_CTRL_TYPE_BOOLEAN,
45 }
46};
32 47
33#define GPIO_DATA 0x60 /* port offset from ESS_IO_BASE */ 48#define GPIO_DATA 0x60 /* port offset from ESS_IO_BASE */
34 49
@@ -96,7 +111,7 @@ static struct file_operations maestro_fops = {
96static struct video_device maestro_radio = { 111static struct video_device maestro_radio = {
97 .name = "Maestro radio", 112 .name = "Maestro radio",
98 .type = VID_TYPE_TUNER, 113 .type = VID_TYPE_TUNER,
99 .hardware = VID_HARDWARE_SF16MI, 114 .hardware = 0,
100 .fops = &maestro_fops, 115 .fops = &maestro_fops,
101}; 116};
102 117
@@ -130,7 +145,7 @@ static u32 radio_bits_get(struct radio_device *dev)
130 rdata = inw(io); 145 rdata = inw(io);
131 if(!l) 146 if(!l)
132 dev->stereo = rdata & STR_MOST ? 147 dev->stereo = rdata & STR_MOST ?
133 0 : VIDEO_TUNER_STEREO_ON; 148 0 : 1;
134 else 149 else
135 if(rdata & STR_DATA) 150 if(rdata & STR_DATA)
136 data++; 151 data++;
@@ -183,72 +198,120 @@ static inline int radio_function(struct inode *inode, struct file *file,
183 struct radio_device *card = video_get_drvdata(dev); 198 struct radio_device *card = video_get_drvdata(dev);
184 199
185 switch (cmd) { 200 switch (cmd) {
186 case VIDIOCGCAP: { 201 case VIDIOC_QUERYCAP:
187 struct video_capability *v = arg; 202 {
188 memset(v, 0, sizeof(*v)); 203 struct v4l2_capability *v = arg;
189 strcpy(v->name, "Maestro radio"); 204 memset(v,0,sizeof(*v));
190 v->type = VID_TYPE_TUNER; 205 strlcpy(v->driver, "radio-maestro", sizeof (v->driver));
191 v->channels = v->audios = 1; 206 strlcpy(v->card, "Maestro Radio", sizeof (v->card));
192 return 0; 207 sprintf(v->bus_info,"PCI");
193 } case VIDIOCGTUNER: { 208 v->version = RADIO_VERSION;
194 struct video_tuner *v = arg; 209 v->capabilities = V4L2_CAP_TUNER;
195 if (v->tuner) 210
196 return -EINVAL; 211 return 0;
197 (void)radio_bits_get(card); 212 }
198 v->flags = VIDEO_TUNER_LOW | card->stereo; 213 case VIDIOC_G_TUNER:
199 v->signal = card->tuned; 214 {
200 strcpy(v->name, "FM"); 215 struct v4l2_tuner *v = arg;
201 v->rangelow = FREQ_LO; 216
202 v->rangehigh = FREQ_HI; 217 if (v->index > 0)
203 v->mode = VIDEO_MODE_AUTO; 218 return -EINVAL;
204 return 0; 219
205 } case VIDIOCSTUNER: { 220 (void)radio_bits_get(card);
206 struct video_tuner *v = arg; 221
207 if (v->tuner != 0) 222 memset(v,0,sizeof(*v));
208 return -EINVAL; 223 strcpy(v->name, "FM");
209 return 0; 224 v->type = V4L2_TUNER_RADIO;
210 } case VIDIOCGFREQ: { 225
211 unsigned long *freq = arg; 226 v->rangelow = FREQ_LO;
212 *freq = BITS2FREQ(radio_bits_get(card)); 227 v->rangehigh = FREQ_HI;
213 return 0; 228 v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
214 } case VIDIOCSFREQ: { 229 v->capability=V4L2_TUNER_CAP_LOW;
215 unsigned long *freq = arg; 230 if(card->stereo)
216 if (*freq < FREQ_LO || *freq > FREQ_HI) 231 v->audmode = V4L2_TUNER_MODE_STEREO;
232 else
233 v->audmode = V4L2_TUNER_MODE_MONO;
234 v->signal=card->tuned;
235
236 return 0;
237 }
238 case VIDIOC_S_TUNER:
239 {
240 struct v4l2_tuner *v = arg;
241
242 if (v->index > 0)
243 return -EINVAL;
244
245 return 0;
246 }
247 case VIDIOC_S_FREQUENCY:
248 {
249 struct v4l2_frequency *f = arg;
250
251 if (f->frequency < FREQ_LO || f->frequency > FREQ_HI)
252 return -EINVAL;
253 radio_bits_set(card, FREQ2BITS(f->frequency));
254
255 return 0;
256 }
257 case VIDIOC_G_FREQUENCY:
258 {
259 struct v4l2_frequency *f = arg;
260
261 f->type = V4L2_TUNER_RADIO;
262 f->frequency = BITS2FREQ(radio_bits_get(card));
263
264 return 0;
265 }
266 case VIDIOC_QUERYCTRL:
267 {
268 struct v4l2_queryctrl *qc = arg;
269 int i;
270
271 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
272 if (qc->id && qc->id == radio_qctrl[i].id) {
273 memcpy(qc, &(radio_qctrl[i]),
274 sizeof(*qc));
275 return (0);
276 }
277 }
217 return -EINVAL; 278 return -EINVAL;
218 radio_bits_set(card, FREQ2BITS(*freq)); 279 }
219 return 0; 280 case VIDIOC_G_CTRL:
220 } case VIDIOCGAUDIO: { 281 {
221 struct video_audio *v = arg; 282 struct v4l2_control *ctrl= arg;
222 memset(v, 0, sizeof(*v)); 283
223 strcpy(v->name, "Radio"); 284 switch (ctrl->id) {
224 v->flags = VIDEO_AUDIO_MUTABLE | card->muted; 285 case V4L2_CID_AUDIO_MUTE:
225 v->mode = VIDEO_SOUND_STEREO; 286 ctrl->value=card->muted;
226 return 0; 287 return (0);
227 } case VIDIOCSAUDIO: { 288 }
228 struct video_audio *v = arg;
229 if (v->audio)
230 return -EINVAL; 289 return -EINVAL;
290 }
291 case VIDIOC_S_CTRL:
231 { 292 {
232 register u16 io = card->io; 293 struct v4l2_control *ctrl= arg;
233 register u16 omask = inw(io + IO_MASK); 294
234 outw(~STR_WREN, io + IO_MASK); 295 switch (ctrl->id) {
235 outw((card->muted = v->flags & VIDEO_AUDIO_MUTE) ? 296 case V4L2_CID_AUDIO_MUTE:
236 STR_WREN : 0, io); 297 {
237 udelay(4); 298 register u16 io = card->io;
238 outw(omask, io + IO_MASK); 299 register u16 omask = inw(io + IO_MASK);
239 msleep(125); 300 outw(~STR_WREN, io + IO_MASK);
240 return 0; 301 outw((card->muted = ctrl->value ) ?
302 STR_WREN : 0, io);
303 udelay(4);
304 outw(omask, io + IO_MASK);
305 msleep(125);
306
307 return (0);
308 }
309 }
310 return -EINVAL;
241 } 311 }
242 } case VIDIOCGUNIT: { 312 default:
243 struct video_unit *v = arg; 313 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
244 v->video = VIDEO_NO_UNIT; 314 radio_function);
245 v->vbi = VIDEO_NO_UNIT;
246 v->radio = dev->minor;
247 v->audio = 0;
248 v->teletext = VIDEO_NO_UNIT;
249 return 0;
250 } default:
251 return -ENOIOCTLCMD;
252 } 315 }
253} 316}
254 317
@@ -275,7 +338,7 @@ static u16 __devinit radio_power_on(struct radio_device *dev)
275 omask = inw(io + IO_MASK); 338 omask = inw(io + IO_MASK);
276 odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN); 339 odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN);
277 outw(odir & ~STR_WREN, io + IO_DIR); 340 outw(odir & ~STR_WREN, io + IO_DIR);
278 dev->muted = inw(io) & STR_WREN ? 0 : VIDEO_AUDIO_MUTE; 341 dev->muted = inw(io) & STR_WREN ? 0 : 1;
279 outw(odir, io + IO_DIR); 342 outw(odir, io + IO_DIR);
280 outw(~(STR_WREN | STR_CLK), io + IO_MASK); 343 outw(~(STR_WREN | STR_CLK), io + IO_MASK);
281 outw(dev->muted ? 0 : STR_WREN, io); 344 outw(dev->muted ? 0 : STR_WREN, io);
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c
index f93d7afe7304..c2eeae7a10d0 100644
--- a/drivers/media/radio/radio-maxiradio.c
+++ b/drivers/media/radio/radio-maxiradio.c
@@ -20,13 +20,14 @@
20 * 0.75b 20 * 0.75b
21 * - better pci interface thanks to Francois Romieu <romieu@cogenit.fr> 21 * - better pci interface thanks to Francois Romieu <romieu@cogenit.fr>
22 * 22 *
23 * 0.75 23 * 0.75 Sun Feb 4 22:51:27 EET 2001
24 * - tiding up 24 * - tiding up
25 * - removed support for multiple devices as it didn't work anyway 25 * - removed support for multiple devices as it didn't work anyway
26 * 26 *
27 * BUGS: 27 * BUGS:
28 * - card unmutes if you change frequency 28 * - card unmutes if you change frequency
29 * 29 *
30 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
30 */ 31 */
31 32
32 33
@@ -40,11 +41,24 @@
40#include <linux/mutex.h> 41#include <linux/mutex.h>
41 42
42#include <linux/pci.h> 43#include <linux/pci.h>
43#include <linux/videodev.h> 44#include <linux/videodev2.h>
44#include <media/v4l2-common.h> 45#include <media/v4l2-common.h>
45 46
46/* version 0.75 Sun Feb 4 22:51:27 EET 2001 */ 47#define DRIVER_VERSION "0.76"
47#define DRIVER_VERSION "0.75" 48
49#include <linux/version.h> /* for KERNEL_VERSION MACRO */
50#define RADIO_VERSION KERNEL_VERSION(0,7,6)
51
52static struct v4l2_queryctrl radio_qctrl[] = {
53 {
54 .id = V4L2_CID_AUDIO_MUTE,
55 .name = "Mute",
56 .minimum = 0,
57 .maximum = 1,
58 .default_value = 1,
59 .type = V4L2_CTRL_TYPE_BOOLEAN,
60 }
61};
48 62
49#ifndef PCI_VENDOR_ID_GUILLEMOT 63#ifndef PCI_VENDOR_ID_GUILLEMOT
50#define PCI_VENDOR_ID_GUILLEMOT 0x5046 64#define PCI_VENDOR_ID_GUILLEMOT 0x5046
@@ -90,7 +104,6 @@ static struct video_device maxiradio_radio =
90 .owner = THIS_MODULE, 104 .owner = THIS_MODULE,
91 .name = "Maxi Radio FM2000 radio", 105 .name = "Maxi Radio FM2000 radio",
92 .type = VID_TYPE_TUNER, 106 .type = VID_TYPE_TUNER,
93 .hardware = VID_HARDWARE_SF16MI,
94 .fops = &maxiradio_fops, 107 .fops = &maxiradio_fops,
95}; 108};
96 109
@@ -176,89 +189,116 @@ static inline int radio_function(struct inode *inode, struct file *file,
176 struct radio_device *card=dev->priv; 189 struct radio_device *card=dev->priv;
177 190
178 switch(cmd) { 191 switch(cmd) {
179 case VIDIOCGCAP: { 192 case VIDIOC_QUERYCAP:
180 struct video_capability *v = arg; 193 {
181 194 struct v4l2_capability *v = arg;
182 memset(v,0,sizeof(*v)); 195 memset(v,0,sizeof(*v));
183 strcpy(v->name, "Maxi Radio FM2000 radio"); 196 strlcpy(v->driver, "radio-maxiradio", sizeof (v->driver));
184 v->type=VID_TYPE_TUNER; 197 strlcpy(v->card, "Maxi Radio FM2000 radio", sizeof (v->card));
185 v->channels=v->audios=1; 198 sprintf(v->bus_info,"ISA");
199 v->version = RADIO_VERSION;
200 v->capabilities = V4L2_CAP_TUNER;
201
186 return 0; 202 return 0;
187 } 203 }
188 case VIDIOCGTUNER: { 204 case VIDIOC_G_TUNER:
189 struct video_tuner *v = arg; 205 {
206 struct v4l2_tuner *v = arg;
190 207
191 if(v->tuner) 208 if (v->index > 0)
192 return -EINVAL; 209 return -EINVAL;
193 210
194 card->stereo = 0xffff * get_stereo(card->io); 211 memset(v,0,sizeof(*v));
195 card->tuned = 0xffff * get_tune(card->io);
196
197 v->flags = VIDEO_TUNER_LOW | card->stereo;
198 v->signal = card->tuned;
199
200 strcpy(v->name, "FM"); 212 strcpy(v->name, "FM");
201 213 v->type = V4L2_TUNER_RADIO;
202 v->rangelow = FREQ_LO; 214
203 v->rangehigh = FREQ_HI; 215 v->rangelow=FREQ_LO;
204 v->mode = VIDEO_MODE_AUTO; 216 v->rangehigh=FREQ_HI;
217 v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
218 v->capability=V4L2_TUNER_CAP_LOW;
219 if(get_stereo(card->io))
220 v->audmode = V4L2_TUNER_MODE_STEREO;
221 else
222 v->audmode = V4L2_TUNER_MODE_MONO;
223 v->signal=0xffff*get_tune(card->io);
205 224
206 return 0; 225 return 0;
207 } 226 }
208 case VIDIOCSTUNER: { 227 case VIDIOC_S_TUNER:
209 struct video_tuner *v = arg; 228 {
210 if(v->tuner!=0) 229 struct v4l2_tuner *v = arg;
230
231 if (v->index > 0)
211 return -EINVAL; 232 return -EINVAL;
212 return 0;
213 }
214 case VIDIOCGFREQ: {
215 unsigned long *freq = arg;
216 233
217 *freq = card->freq;
218 return 0; 234 return 0;
219 } 235 }
220 case VIDIOCSFREQ: { 236 case VIDIOC_S_FREQUENCY:
221 unsigned long *freq = arg; 237 {
238 struct v4l2_frequency *f = arg;
222 239
223 if (*freq < FREQ_LO || *freq > FREQ_HI) 240 if (f->frequency < FREQ_LO || f->frequency > FREQ_HI)
224 return -EINVAL; 241 return -EINVAL;
225 card->freq = *freq; 242
243 card->freq = f->frequency;
226 set_freq(card->io, FREQ2BITS(card->freq)); 244 set_freq(card->io, FREQ2BITS(card->freq));
227 msleep(125); 245 msleep(125);
228 return 0; 246 return 0;
229 } 247 }
230 case VIDIOCGAUDIO: { 248 case VIDIOC_G_FREQUENCY:
231 struct video_audio *v = arg; 249 {
232 memset(v,0,sizeof(*v)); 250 struct v4l2_frequency *f = arg;
233 strcpy(v->name, "Radio");
234 v->flags=VIDEO_AUDIO_MUTABLE | card->muted;
235 v->mode=VIDEO_SOUND_STEREO;
236 return 0;
237 }
238 251
239 case VIDIOCSAUDIO: { 252 f->type = V4L2_TUNER_RADIO;
240 struct video_audio *v = arg; 253 f->frequency = card->freq;
241 254
242 if(v->audio)
243 return -EINVAL;
244 card->muted = v->flags & VIDEO_AUDIO_MUTE;
245 if(card->muted)
246 turn_power(card->io, 0);
247 else
248 set_freq(card->io, FREQ2BITS(card->freq));
249 return 0; 255 return 0;
250 } 256 }
251 case VIDIOCGUNIT: { 257 case VIDIOC_QUERYCTRL:
252 struct video_unit *v = arg; 258 {
253 259 struct v4l2_queryctrl *qc = arg;
254 v->video=VIDEO_NO_UNIT; 260 int i;
255 v->vbi=VIDEO_NO_UNIT; 261
256 v->radio=dev->minor; 262 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
257 v->audio=0; 263 if (qc->id && qc->id == radio_qctrl[i].id) {
258 v->teletext=VIDEO_NO_UNIT; 264 memcpy(qc, &(radio_qctrl[i]),
259 return 0; 265 sizeof(*qc));
266 return (0);
267 }
268 }
269 return -EINVAL;
270 }
271 case VIDIOC_G_CTRL:
272 {
273 struct v4l2_control *ctrl= arg;
274
275 switch (ctrl->id) {
276 case V4L2_CID_AUDIO_MUTE:
277 ctrl->value=card->muted;
278 return (0);
279 }
280 return -EINVAL;
260 } 281 }
261 default: return -ENOIOCTLCMD; 282 case VIDIOC_S_CTRL:
283 {
284 struct v4l2_control *ctrl= arg;
285
286 switch (ctrl->id) {
287 case V4L2_CID_AUDIO_MUTE:
288 card->muted = ctrl->value;
289 if(card->muted)
290 turn_power(card->io, 0);
291 else
292 set_freq(card->io, FREQ2BITS(card->freq));
293 return 0;
294 }
295 return -EINVAL;
296 }
297
298 default:
299 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
300 radio_function);
301
262 } 302 }
263} 303}
264 304
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c
index 5b68ac4c7322..b9e98483e58d 100644
--- a/drivers/media/radio/radio-rtrack2.c
+++ b/drivers/media/radio/radio-rtrack2.c
@@ -6,6 +6,7 @@
6 * 6 *
7 * TODO: Allow for more than one of these foolish entities :-) 7 * TODO: Allow for more than one of these foolish entities :-)
8 * 8 *
9 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
9 */ 10 */
10 11
11#include <linux/module.h> /* Modules */ 12#include <linux/module.h> /* Modules */
@@ -14,11 +15,32 @@
14#include <linux/delay.h> /* udelay */ 15#include <linux/delay.h> /* udelay */
15#include <asm/io.h> /* outb, outb_p */ 16#include <asm/io.h> /* outb, outb_p */
16#include <asm/uaccess.h> /* copy to/from user */ 17#include <asm/uaccess.h> /* copy to/from user */
17#include <linux/videodev.h> /* kernel radio structs */ 18#include <linux/videodev2.h> /* kernel radio structs */
18#include <media/v4l2-common.h> 19#include <media/v4l2-common.h>
19#include <linux/config.h> /* CONFIG_RADIO_RTRACK2_PORT */
20#include <linux/spinlock.h> 20#include <linux/spinlock.h>
21 21
22#include <linux/version.h> /* for KERNEL_VERSION MACRO */
23#define RADIO_VERSION KERNEL_VERSION(0,0,2)
24
25static struct v4l2_queryctrl radio_qctrl[] = {
26 {
27 .id = V4L2_CID_AUDIO_MUTE,
28 .name = "Mute",
29 .minimum = 0,
30 .maximum = 1,
31 .default_value = 1,
32 .type = V4L2_CTRL_TYPE_BOOLEAN,
33 },{
34 .id = V4L2_CID_AUDIO_VOLUME,
35 .name = "Volume",
36 .minimum = 0,
37 .maximum = 65535,
38 .step = 65535,
39 .default_value = 0xff,
40 .type = V4L2_CTRL_TYPE_INTEGER,
41 }
42};
43
22#ifndef CONFIG_RADIO_RTRACK2_PORT 44#ifndef CONFIG_RADIO_RTRACK2_PORT
23#define CONFIG_RADIO_RTRACK2_PORT -1 45#define CONFIG_RADIO_RTRACK2_PORT -1
24#endif 46#endif
@@ -115,75 +137,120 @@ static int rt_do_ioctl(struct inode *inode, struct file *file,
115 137
116 switch(cmd) 138 switch(cmd)
117 { 139 {
118 case VIDIOCGCAP: 140 case VIDIOC_QUERYCAP:
119 { 141 {
120 struct video_capability *v = arg; 142 struct v4l2_capability *v = arg;
121 memset(v,0,sizeof(*v)); 143 memset(v,0,sizeof(*v));
122 v->type=VID_TYPE_TUNER; 144 strlcpy(v->driver, "radio-rtrack2", sizeof (v->driver));
123 v->channels=1; 145 strlcpy(v->card, "RadioTrack II", sizeof (v->card));
124 v->audios=1; 146 sprintf(v->bus_info,"ISA");
125 strcpy(v->name, "RadioTrack II"); 147 v->version = RADIO_VERSION;
148 v->capabilities = V4L2_CAP_TUNER;
149
126 return 0; 150 return 0;
127 } 151 }
128 case VIDIOCGTUNER: 152 case VIDIOC_G_TUNER:
129 { 153 {
130 struct video_tuner *v = arg; 154 struct v4l2_tuner *v = arg;
131 if(v->tuner) /* Only 1 tuner */ 155
156 if (v->index > 0)
132 return -EINVAL; 157 return -EINVAL;
133 v->rangelow=88*16000; 158
134 v->rangehigh=108*16000; 159 memset(v,0,sizeof(*v));
135 v->flags=VIDEO_TUNER_LOW;
136 v->mode=VIDEO_MODE_AUTO;
137 v->signal=0xFFFF*rt_getsigstr(rt);
138 strcpy(v->name, "FM"); 160 strcpy(v->name, "FM");
161 v->type = V4L2_TUNER_RADIO;
162
163 v->rangelow=(88*16000);
164 v->rangehigh=(108*16000);
165 v->rxsubchans =V4L2_TUNER_SUB_MONO;
166 v->capability=V4L2_TUNER_CAP_LOW;
167 v->audmode = V4L2_TUNER_MODE_MONO;
168 v->signal=0xFFFF*rt_getsigstr(rt);
169
139 return 0; 170 return 0;
140 } 171 }
141 case VIDIOCSTUNER: 172 case VIDIOC_S_TUNER:
142 { 173 {
143 struct video_tuner *v = arg; 174 struct v4l2_tuner *v = arg;
144 if(v->tuner!=0) 175
176 if (v->index > 0)
145 return -EINVAL; 177 return -EINVAL;
146 /* Only 1 tuner so no setting needed ! */ 178
147 return 0; 179 return 0;
148 } 180 }
149 case VIDIOCGFREQ: 181 case VIDIOC_S_FREQUENCY:
150 { 182 {
151 unsigned long *freq = arg; 183 struct v4l2_frequency *f = arg;
152 *freq = rt->curfreq; 184
185 rt->curfreq = f->frequency;
186 rt_setfreq(rt, rt->curfreq);
153 return 0; 187 return 0;
154 } 188 }
155 case VIDIOCSFREQ: 189 case VIDIOC_G_FREQUENCY:
156 { 190 {
157 unsigned long *freq = arg; 191 struct v4l2_frequency *f = arg;
158 rt->curfreq = *freq; 192
159 rt_setfreq(rt, rt->curfreq); 193 f->type = V4L2_TUNER_RADIO;
194 f->frequency = rt->curfreq;
195
160 return 0; 196 return 0;
161 } 197 }
162 case VIDIOCGAUDIO: 198 case VIDIOC_QUERYCTRL:
163 { 199 {
164 struct video_audio *v = arg; 200 struct v4l2_queryctrl *qc = arg;
165 memset(v,0, sizeof(*v)); 201 int i;
166 v->flags|=VIDEO_AUDIO_MUTABLE; 202
167 v->volume=1; 203 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
168 v->step=65535; 204 if (qc->id && qc->id == radio_qctrl[i].id) {
169 strcpy(v->name, "Radio"); 205 memcpy(qc, &(radio_qctrl[i]),
170 return 0; 206 sizeof(*qc));
207 return (0);
208 }
209 }
210 return -EINVAL;
171 } 211 }
172 case VIDIOCSAUDIO: 212 case VIDIOC_G_CTRL:
173 { 213 {
174 struct video_audio *v = arg; 214 struct v4l2_control *ctrl= arg;
175 if(v->audio) 215
176 return -EINVAL; 216 switch (ctrl->id) {
177 217 case V4L2_CID_AUDIO_MUTE:
178 if(v->flags&VIDEO_AUDIO_MUTE) 218 ctrl->value=rt->muted;
179 rt_mute(rt); 219 return (0);
180 else 220 case V4L2_CID_AUDIO_VOLUME:
181 rt_unmute(rt); 221 if (rt->muted)
182 222 ctrl->value=0;
183 return 0; 223 else
224 ctrl->value=65535;
225 return (0);
226 }
227 return -EINVAL;
228 }
229 case VIDIOC_S_CTRL:
230 {
231 struct v4l2_control *ctrl= arg;
232
233 switch (ctrl->id) {
234 case V4L2_CID_AUDIO_MUTE:
235 if (ctrl->value) {
236 rt_mute(rt);
237 } else {
238 rt_unmute(rt);
239 }
240 return (0);
241 case V4L2_CID_AUDIO_VOLUME:
242 if (ctrl->value) {
243 rt_unmute(rt);
244 } else {
245 rt_mute(rt);
246 }
247 return (0);
248 }
249 return -EINVAL;
184 } 250 }
185 default: 251 default:
186 return -ENOIOCTLCMD; 252 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
253 rt_do_ioctl);
187 } 254 }
188} 255}
189 256
@@ -209,7 +276,7 @@ static struct video_device rtrack2_radio=
209 .owner = THIS_MODULE, 276 .owner = THIS_MODULE,
210 .name = "RadioTrack II radio", 277 .name = "RadioTrack II radio",
211 .type = VID_TYPE_TUNER, 278 .type = VID_TYPE_TUNER,
212 .hardware = VID_HARDWARE_RTRACK2, 279 .hardware = 0,
213 .fops = &rtrack2_fops, 280 .fops = &rtrack2_fops,
214}; 281};
215 282
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
index efee6e339d15..ecc854b4ba38 100644
--- a/drivers/media/radio/radio-sf16fmi.c
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -13,20 +13,35 @@
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
19#include <linux/version.h>
18#include <linux/kernel.h> /* __setup */ 20#include <linux/kernel.h> /* __setup */
19#include <linux/module.h> /* Modules */ 21#include <linux/module.h> /* Modules */
20#include <linux/init.h> /* Initdata */ 22#include <linux/init.h> /* Initdata */
21#include <linux/ioport.h> /* request_region */ 23#include <linux/ioport.h> /* request_region */
22#include <linux/delay.h> /* udelay */ 24#include <linux/delay.h> /* udelay */
23#include <linux/videodev.h> /* kernel radio structs */ 25#include <linux/videodev2.h> /* kernel radio structs */
24#include <media/v4l2-common.h> 26#include <media/v4l2-common.h>
25#include <linux/isapnp.h> 27#include <linux/isapnp.h>
26#include <asm/io.h> /* outb, outb_p */ 28#include <asm/io.h> /* outb, outb_p */
27#include <asm/uaccess.h> /* copy to/from user */ 29#include <asm/uaccess.h> /* copy to/from user */
28#include <linux/mutex.h> 30#include <linux/mutex.h>
29 31
32#define RADIO_VERSION KERNEL_VERSION(0,0,2)
33
34static struct v4l2_queryctrl radio_qctrl[] = {
35 {
36 .id = V4L2_CID_AUDIO_MUTE,
37 .name = "Mute",
38 .minimum = 0,
39 .maximum = 1,
40 .default_value = 1,
41 .type = V4L2_CTRL_TYPE_BOOLEAN,
42 }
43};
44
30struct fmi_device 45struct fmi_device
31{ 46{
32 int port; 47 int port;
@@ -123,93 +138,122 @@ static int fmi_do_ioctl(struct inode *inode, struct file *file,
123 138
124 switch(cmd) 139 switch(cmd)
125 { 140 {
126 case VIDIOCGCAP: 141 case VIDIOC_QUERYCAP:
127 { 142 {
128 struct video_capability *v = arg; 143 struct v4l2_capability *v = arg;
129 memset(v,0,sizeof(*v)); 144 memset(v,0,sizeof(*v));
130 strcpy(v->name, "SF16-FMx radio"); 145 strlcpy(v->driver, "radio-sf16fmi", sizeof (v->driver));
131 v->type=VID_TYPE_TUNER; 146 strlcpy(v->card, "SF16-FMx radio", sizeof (v->card));
132 v->channels=1; 147 sprintf(v->bus_info,"ISA");
133 v->audios=1; 148 v->version = RADIO_VERSION;
149 v->capabilities = V4L2_CAP_TUNER;
150
134 return 0; 151 return 0;
135 } 152 }
136 case VIDIOCGTUNER: 153 case VIDIOC_G_TUNER:
137 { 154 {
138 struct video_tuner *v = arg; 155 struct v4l2_tuner *v = arg;
139 int mult; 156 int mult;
140 157
141 if(v->tuner) /* Only 1 tuner */ 158 if (v->index > 0)
142 return -EINVAL; 159 return -EINVAL;
160
161 memset(v,0,sizeof(*v));
143 strcpy(v->name, "FM"); 162 strcpy(v->name, "FM");
144 mult = (fmi->flags & VIDEO_TUNER_LOW) ? 1 : 1000; 163 v->type = V4L2_TUNER_RADIO;
164
165 mult = (fmi->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000;
145 v->rangelow = RSF16_MINFREQ/mult; 166 v->rangelow = RSF16_MINFREQ/mult;
146 v->rangehigh = RSF16_MAXFREQ/mult; 167 v->rangehigh = RSF16_MAXFREQ/mult;
147 v->flags=fmi->flags; 168 v->rxsubchans =V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO;
148 v->mode=VIDEO_MODE_AUTO; 169 v->capability=fmi->flags&V4L2_TUNER_CAP_LOW;
170 v->audmode = V4L2_TUNER_MODE_STEREO;
149 v->signal = fmi_getsigstr(fmi); 171 v->signal = fmi_getsigstr(fmi);
172
150 return 0; 173 return 0;
151 } 174 }
152 case VIDIOCSTUNER: 175 case VIDIOC_S_TUNER:
153 { 176 {
154 struct video_tuner *v = arg; 177 struct v4l2_tuner *v = arg;
155 if(v->tuner!=0) 178
179 if (v->index > 0)
156 return -EINVAL; 180 return -EINVAL;
157 fmi->flags = v->flags & VIDEO_TUNER_LOW; 181
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; 182 return 0;
168 } 183 }
169 case VIDIOCSFREQ: 184 case VIDIOC_S_FREQUENCY:
170 { 185 {
171 unsigned long *freq = arg; 186 struct v4l2_frequency *f = arg;
172 if (!(fmi->flags & VIDEO_TUNER_LOW)) 187
173 *freq *= 1000; 188 if (!(fmi->flags & V4L2_TUNER_CAP_LOW))
174 if (*freq < RSF16_MINFREQ || *freq > RSF16_MAXFREQ ) 189 f->frequency *= 1000;
190 if (f->frequency < RSF16_MINFREQ ||
191 f->frequency > RSF16_MAXFREQ )
175 return -EINVAL; 192 return -EINVAL;
176 /*rounding in steps of 800 to match th freq 193 /*rounding in steps of 800 to match th freq
177 that will be used */ 194 that will be used */
178 fmi->curfreq = (*freq/800)*800; 195 fmi->curfreq = (f->frequency/800)*800;
179 fmi_setfreq(fmi); 196 fmi_setfreq(fmi);
197
180 return 0; 198 return 0;
181 } 199 }
182 case VIDIOCGAUDIO: 200 case VIDIOC_G_FREQUENCY:
183 { 201 {
184 struct video_audio *v = arg; 202 struct v4l2_frequency *f = arg;
185 memset(v,0,sizeof(*v)); 203
186 v->flags=( (!fmi->curvol)*VIDEO_AUDIO_MUTE | VIDEO_AUDIO_MUTABLE); 204 f->type = V4L2_TUNER_RADIO;
187 strcpy(v->name, "Radio"); 205 f->frequency = fmi->curfreq;
188 v->mode=VIDEO_SOUND_STEREO; 206 if (!(fmi->flags & V4L2_TUNER_CAP_LOW))
207 f->frequency /= 1000;
208
189 return 0; 209 return 0;
190 } 210 }
191 case VIDIOCSAUDIO: 211 case VIDIOC_QUERYCTRL:
192 { 212 {
193 struct video_audio *v = arg; 213 struct v4l2_queryctrl *qc = arg;
194 if(v->audio) 214 int i;
195 return -EINVAL; 215
196 fmi->curvol= v->flags&VIDEO_AUDIO_MUTE ? 0 : 1; 216 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
197 fmi->curvol ? 217 if (qc->id && qc->id == radio_qctrl[i].id) {
198 fmi_unmute(fmi->port) : fmi_mute(fmi->port); 218 memcpy(qc, &(radio_qctrl[i]),
199 return 0; 219 sizeof(*qc));
220 return (0);
221 }
222 }
223 return -EINVAL;
200 } 224 }
201 case VIDIOCGUNIT: 225 case VIDIOC_G_CTRL:
202 { 226 {
203 struct video_unit *v = arg; 227 struct v4l2_control *ctrl= arg;
204 v->video=VIDEO_NO_UNIT; 228
205 v->vbi=VIDEO_NO_UNIT; 229 switch (ctrl->id) {
206 v->radio=dev->minor; 230 case V4L2_CID_AUDIO_MUTE:
207 v->audio=0; /* How do we find out this??? */ 231 ctrl->value=fmi->curvol;
208 v->teletext=VIDEO_NO_UNIT; 232 return (0);
209 return 0; 233 }
234 return -EINVAL;
235 }
236 case VIDIOC_S_CTRL:
237 {
238 struct v4l2_control *ctrl= arg;
239
240 switch (ctrl->id) {
241 case V4L2_CID_AUDIO_MUTE:
242 {
243 if (ctrl->value)
244 fmi_mute(fmi->port);
245 else
246 fmi_unmute(fmi->port);
247
248 fmi->curvol=ctrl->value;
249 return (0);
250 }
251 }
252 return -EINVAL;
210 } 253 }
211 default: 254 default:
212 return -ENOIOCTLCMD; 255 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
256 fmi_do_ioctl);
213 } 257 }
214} 258}
215 259
@@ -235,7 +279,7 @@ static struct video_device fmi_radio=
235 .owner = THIS_MODULE, 279 .owner = THIS_MODULE,
236 .name = "SF16FMx radio", 280 .name = "SF16FMx radio",
237 .type = VID_TYPE_TUNER, 281 .type = VID_TYPE_TUNER,
238 .hardware = VID_HARDWARE_SF16MI, 282 .hardware = 0,
239 .fops = &fmi_fops, 283 .fops = &fmi_fops,
240}; 284};
241 285
@@ -294,7 +338,7 @@ static int __init fmi_init(void)
294 fmi_unit.port = io; 338 fmi_unit.port = io;
295 fmi_unit.curvol = 0; 339 fmi_unit.curvol = 0;
296 fmi_unit.curfreq = 0; 340 fmi_unit.curfreq = 0;
297 fmi_unit.flags = VIDEO_TUNER_LOW; 341 fmi_unit.flags = V4L2_TUNER_CAP_LOW;
298 fmi_radio.priv = &fmi_unit; 342 fmi_radio.priv = &fmi_unit;
299 343
300 mutex_init(&lock); 344 mutex_init(&lock);
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c
index 3483b2c7bc9d..4444dce864a9 100644
--- a/drivers/media/radio/radio-sf16fmr2.c
+++ b/drivers/media/radio/radio-sf16fmr2.c
@@ -10,6 +10,8 @@
10 * For read stereo/mono you must wait 0.1 sec after set frequency and 10 * For read stereo/mono you must wait 0.1 sec after set frequency and
11 * card unmuted so I set frequency on unmute 11 * card unmuted so I set frequency on unmute
12 * Signal handling seem to work only on autoscanning (not implemented) 12 * Signal handling seem to work only on autoscanning (not implemented)
13 *
14 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
13 */ 15 */
14 16
15#include <linux/module.h> /* Modules */ 17#include <linux/module.h> /* Modules */
@@ -18,12 +20,34 @@
18#include <linux/delay.h> /* udelay */ 20#include <linux/delay.h> /* udelay */
19#include <asm/io.h> /* outb, outb_p */ 21#include <asm/io.h> /* outb, outb_p */
20#include <asm/uaccess.h> /* copy to/from user */ 22#include <asm/uaccess.h> /* copy to/from user */
21#include <linux/videodev.h> /* kernel radio structs */ 23#include <linux/videodev2.h> /* kernel radio structs */
22#include <media/v4l2-common.h> 24#include <media/v4l2-common.h>
23#include <linux/mutex.h> 25#include <linux/mutex.h>
24 26
25static struct mutex lock; 27static struct mutex lock;
26 28
29#include <linux/version.h> /* for KERNEL_VERSION MACRO */
30#define RADIO_VERSION KERNEL_VERSION(0,0,2)
31
32static struct v4l2_queryctrl radio_qctrl[] = {
33 {
34 .id = V4L2_CID_AUDIO_MUTE,
35 .name = "Mute",
36 .minimum = 0,
37 .maximum = 1,
38 .default_value = 1,
39 .type = V4L2_CTRL_TYPE_BOOLEAN,
40 },{
41 .id = V4L2_CID_AUDIO_VOLUME,
42 .name = "Volume",
43 .minimum = 0,
44 .maximum = 65535,
45 .step = 1<<12,
46 .default_value = 0xff,
47 .type = V4L2_CTRL_TYPE_INTEGER,
48 }
49};
50
27#undef DEBUG 51#undef DEBUG
28//#define DEBUG 1 52//#define DEBUG 1
29 53
@@ -214,63 +238,65 @@ static int fmr2_do_ioctl(struct inode *inode, struct file *file,
214 238
215 switch(cmd) 239 switch(cmd)
216 { 240 {
217 case VIDIOCGCAP: 241 case VIDIOC_QUERYCAP:
218 { 242 {
219 struct video_capability *v = arg; 243 struct v4l2_capability *v = arg;
220 memset(v,0,sizeof(*v)); 244 memset(v,0,sizeof(*v));
221 strcpy(v->name, "SF16-FMR2 radio"); 245 strlcpy(v->driver, "radio-sf16fmr2", sizeof (v->driver));
222 v->type=VID_TYPE_TUNER; 246 strlcpy(v->card, "SF16-FMR2 radio", sizeof (v->card));
223 v->channels=1; 247 sprintf(v->bus_info,"ISA");
224 v->audios=1; 248 v->version = RADIO_VERSION;
249 v->capabilities = V4L2_CAP_TUNER;
250
225 return 0; 251 return 0;
226 } 252 }
227 case VIDIOCGTUNER: 253 case VIDIOC_G_TUNER:
228 { 254 {
229 struct video_tuner *v = arg; 255 struct v4l2_tuner *v = arg;
230 int mult; 256 int mult;
231 257
232 if(v->tuner) /* Only 1 tuner */ 258 if (v->index > 0)
233 return -EINVAL; 259 return -EINVAL;
260
261 memset(v,0,sizeof(*v));
234 strcpy(v->name, "FM"); 262 strcpy(v->name, "FM");
235 mult = (fmr2->flags & VIDEO_TUNER_LOW) ? 1 : 1000; 263 v->type = V4L2_TUNER_RADIO;
264
265 mult = (fmr2->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000;
236 v->rangelow = RSF16_MINFREQ/mult; 266 v->rangelow = RSF16_MINFREQ/mult;
237 v->rangehigh = RSF16_MAXFREQ/mult; 267 v->rangehigh = RSF16_MAXFREQ/mult;
238 v->flags = fmr2->flags | VIDEO_AUDIO_MUTABLE; 268 v->rxsubchans =V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO;
239 if (fmr2->mute) 269 v->capability=fmr2->flags&V4L2_TUNER_CAP_LOW;
240 v->flags |= VIDEO_AUDIO_MUTE; 270
241 v->mode=VIDEO_MODE_AUTO; 271 v->audmode = fmr2->stereo ? V4L2_TUNER_MODE_STEREO:
272 V4L2_TUNER_MODE_MONO;
242 mutex_lock(&lock); 273 mutex_lock(&lock);
243 v->signal = fmr2_getsigstr(fmr2); 274 v->signal = fmr2_getsigstr(fmr2);
244 mutex_unlock(&lock); 275 mutex_unlock(&lock);
276
245 return 0; 277 return 0;
246 } 278 }
247 case VIDIOCSTUNER: 279 case VIDIOC_S_TUNER:
248 { 280 {
249 struct video_tuner *v = arg; 281 struct v4l2_tuner *v = arg;
250 if (v->tuner!=0) 282
283 if (v->index > 0)
251 return -EINVAL; 284 return -EINVAL;
252 fmr2->flags = v->flags & VIDEO_TUNER_LOW; 285
253 return 0;
254 }
255 case VIDIOCGFREQ:
256 {
257 unsigned long *freq = arg;
258 *freq = fmr2->curfreq;
259 if (!(fmr2->flags & VIDEO_TUNER_LOW))
260 *freq /= 1000;
261 return 0; 286 return 0;
262 } 287 }
263 case VIDIOCSFREQ: 288 case VIDIOC_S_FREQUENCY:
264 { 289 {
265 unsigned long *freq = arg; 290 struct v4l2_frequency *f = arg;
266 if (!(fmr2->flags & VIDEO_TUNER_LOW)) 291
267 *freq *= 1000; 292 if (!(fmr2->flags & V4L2_TUNER_CAP_LOW))
268 if ( *freq < RSF16_MINFREQ || *freq > RSF16_MAXFREQ ) 293 f->frequency *= 1000;
294 if (f->frequency < RSF16_MINFREQ ||
295 f->frequency > RSF16_MAXFREQ )
269 return -EINVAL; 296 return -EINVAL;
270 /* rounding in steps of 200 to match th freq 297 /*rounding in steps of 200 to match th freq
271 * that will be used 298 that will be used */
272 */ 299 fmr2->curfreq = (f->frequency/200)*200;
273 fmr2->curfreq = (*freq/200)*200;
274 300
275 /* set card freq (if not muted) */ 301 /* set card freq (if not muted) */
276 if (fmr2->curvol && !fmr2->mute) 302 if (fmr2->curvol && !fmr2->mute)
@@ -279,40 +305,81 @@ static int fmr2_do_ioctl(struct inode *inode, struct file *file,
279 fmr2_setfreq(fmr2); 305 fmr2_setfreq(fmr2);
280 mutex_unlock(&lock); 306 mutex_unlock(&lock);
281 } 307 }
308
282 return 0; 309 return 0;
283 } 310 }
284 case VIDIOCGAUDIO: 311 case VIDIOC_G_FREQUENCY:
285 { 312 {
286 struct video_audio *v = arg; 313 struct v4l2_frequency *f = arg;
287 memset(v,0,sizeof(*v)); 314
288 /* !!! do not return VIDEO_AUDIO_MUTE */ 315 f->type = V4L2_TUNER_RADIO;
289 v->flags = VIDEO_AUDIO_MUTABLE; 316 f->frequency = fmr2->curfreq;
290 strcpy(v->name, "Radio"); 317 if (!(fmr2->flags & V4L2_TUNER_CAP_LOW))
291 /* get current stereo mode */ 318 f->frequency /= 1000;
292 v->mode = fmr2->stereo ? VIDEO_SOUND_STEREO: VIDEO_SOUND_MONO; 319
293 /* volume supported ? */
294 if (fmr2->card_type == 11)
295 {
296 v->flags |= VIDEO_AUDIO_VOLUME;
297 v->step = 1 << 12;
298 v->volume = fmr2->curvol;
299 }
300 debug_print((KERN_DEBUG "Get flags %d vol %d\n", v->flags, v->volume));
301 return 0; 320 return 0;
302 } 321 }
303 case VIDIOCSAUDIO: 322 case VIDIOC_QUERYCTRL:
304 { 323 {
305 struct video_audio *v = arg; 324 struct v4l2_queryctrl *qc = arg;
306 if(v->audio) 325 int i;
307 return -EINVAL; 326
308 debug_print((KERN_DEBUG "Set flags %d vol %d\n", v->flags, v->volume)); 327 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
309 /* set volume */ 328 if ((fmr2->card_type != 11)
310 if (v->flags & VIDEO_AUDIO_VOLUME) 329 && V4L2_CID_AUDIO_VOLUME)
311 fmr2->curvol = v->volume; /* !!! set with precision */ 330 radio_qctrl[i].step=65535;
312 if (fmr2->card_type != 11) fmr2->curvol = 65535; 331 if (qc->id && qc->id == radio_qctrl[i].id) {
313 fmr2->mute = 0; 332 memcpy(qc, &(radio_qctrl[i]),
314 if (v->flags & VIDEO_AUDIO_MUTE) 333 sizeof(*qc));
315 fmr2->mute = 1; 334 return (0);
335 }
336 }
337 return -EINVAL;
338 }
339 case VIDIOC_G_CTRL:
340 {
341 struct v4l2_control *ctrl= arg;
342
343 switch (ctrl->id) {
344 case V4L2_CID_AUDIO_MUTE:
345 ctrl->value=fmr2->mute;
346 return (0);
347 case V4L2_CID_AUDIO_VOLUME:
348 ctrl->value=fmr2->curvol;
349 return (0);
350 }
351 return -EINVAL;
352 }
353 case VIDIOC_S_CTRL:
354 {
355 struct v4l2_control *ctrl= arg;
356
357 switch (ctrl->id) {
358 case V4L2_CID_AUDIO_MUTE:
359 fmr2->mute=ctrl->value;
360 if (fmr2->card_type != 11) {
361 if (!fmr2->mute) {
362 fmr2->curvol = 65535;
363 } else {
364 fmr2->curvol = 0;
365 }
366 }
367 break;
368 case V4L2_CID_AUDIO_VOLUME:
369 fmr2->curvol = ctrl->value;
370 if (fmr2->card_type != 11) {
371 if (fmr2->curvol) {
372 fmr2->curvol = 65535;
373 fmr2->mute = 0;
374 } else {
375 fmr2->curvol = 0;
376 fmr2->mute = 1;
377 }
378 }
379 break;
380 default:
381 return -EINVAL;
382 }
316#ifdef DEBUG 383#ifdef DEBUG
317 if (fmr2->curvol && !fmr2->mute) 384 if (fmr2->curvol && !fmr2->mute)
318 printk(KERN_DEBUG "unmute\n"); 385 printk(KERN_DEBUG "unmute\n");
@@ -320,27 +387,18 @@ static int fmr2_do_ioctl(struct inode *inode, struct file *file,
320 printk(KERN_DEBUG "mute\n"); 387 printk(KERN_DEBUG "mute\n");
321#endif 388#endif
322 mutex_lock(&lock); 389 mutex_lock(&lock);
323 if (fmr2->curvol && !fmr2->mute) 390 if (fmr2->curvol && !fmr2->mute) {
324 {
325 fmr2_setvolume(fmr2); 391 fmr2_setvolume(fmr2);
326 fmr2_setfreq(fmr2); 392 fmr2_setfreq(fmr2);
327 } 393 } else
328 else fmr2_mute(fmr2->port); 394 fmr2_mute(fmr2->port);
329 mutex_unlock(&lock); 395 mutex_unlock(&lock);
330 return 0; 396 return (0);
331 }
332 case VIDIOCGUNIT:
333 {
334 struct video_unit *v = arg;
335 v->video=VIDEO_NO_UNIT;
336 v->vbi=VIDEO_NO_UNIT;
337 v->radio=dev->minor;
338 v->audio=0; /* How do we find out this??? */
339 v->teletext=VIDEO_NO_UNIT;
340 return 0;
341 } 397 }
342 default: 398 default:
343 return -ENOIOCTLCMD; 399 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
400 fmr2_do_ioctl);
401
344 } 402 }
345} 403}
346 404
@@ -366,7 +424,7 @@ static struct video_device fmr2_radio=
366 .owner = THIS_MODULE, 424 .owner = THIS_MODULE,
367 .name = "SF16FMR2 radio", 425 .name = "SF16FMR2 radio",
368 . type = VID_TYPE_TUNER, 426 . type = VID_TYPE_TUNER,
369 .hardware = VID_HARDWARE_SF16FMR2, 427 .hardware = 0,
370 .fops = &fmr2_fops, 428 .fops = &fmr2_fops,
371}; 429};
372 430
@@ -377,7 +435,7 @@ static int __init fmr2_init(void)
377 fmr2_unit.mute = 0; 435 fmr2_unit.mute = 0;
378 fmr2_unit.curfreq = 0; 436 fmr2_unit.curfreq = 0;
379 fmr2_unit.stereo = 1; 437 fmr2_unit.stereo = 1;
380 fmr2_unit.flags = VIDEO_TUNER_LOW; 438 fmr2_unit.flags = V4L2_TUNER_CAP_LOW;
381 fmr2_unit.card_type = 0; 439 fmr2_unit.card_type = 0;
382 fmr2_radio.priv = &fmr2_unit; 440 fmr2_radio.priv = &fmr2_unit;
383 441
@@ -396,7 +454,6 @@ static int __init fmr2_init(void)
396 } 454 }
397 455
398 printk(KERN_INFO "SF16FMR2 radio card driver at 0x%x.\n", io); 456 printk(KERN_INFO "SF16FMR2 radio card driver at 0x%x.\n", io);
399 debug_print((KERN_DEBUG "Mute %d Low %d\n",VIDEO_AUDIO_MUTE,VIDEO_TUNER_LOW));
400 /* mute card - prevents noisy bootups */ 457 /* mute card - prevents noisy bootups */
401 mutex_lock(&lock); 458 mutex_lock(&lock);
402 fmr2_mute(io); 459 fmr2_mute(io);
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c
index dfba4ae596cd..f539491a0d76 100644
--- a/drivers/media/radio/radio-terratec.c
+++ b/drivers/media/radio/radio-terratec.c
@@ -21,6 +21,7 @@
21 * If you can help me out with that, please contact me!! 21 * If you can help me out with that, please contact me!!
22 * 22 *
23 * 23 *
24 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
24 */ 25 */
25 26
26#include <linux/module.h> /* Modules */ 27#include <linux/module.h> /* Modules */
@@ -29,11 +30,32 @@
29#include <linux/delay.h> /* udelay */ 30#include <linux/delay.h> /* udelay */
30#include <asm/io.h> /* outb, outb_p */ 31#include <asm/io.h> /* outb, outb_p */
31#include <asm/uaccess.h> /* copy to/from user */ 32#include <asm/uaccess.h> /* copy to/from user */
32#include <linux/videodev.h> /* kernel radio structs */ 33#include <linux/videodev2.h> /* kernel radio structs */
33#include <media/v4l2-common.h> 34#include <media/v4l2-common.h>
34#include <linux/config.h> /* CONFIG_RADIO_TERRATEC_PORT */
35#include <linux/spinlock.h> 35#include <linux/spinlock.h>
36 36
37#include <linux/version.h> /* for KERNEL_VERSION MACRO */
38#define RADIO_VERSION KERNEL_VERSION(0,0,2)
39
40static struct v4l2_queryctrl radio_qctrl[] = {
41 {
42 .id = V4L2_CID_AUDIO_MUTE,
43 .name = "Mute",
44 .minimum = 0,
45 .maximum = 1,
46 .default_value = 1,
47 .type = V4L2_CTRL_TYPE_BOOLEAN,
48 },{
49 .id = V4L2_CID_AUDIO_VOLUME,
50 .name = "Volume",
51 .minimum = 0,
52 .maximum = 0xff,
53 .step = 1,
54 .default_value = 0xff,
55 .type = V4L2_CTRL_TYPE_INTEGER,
56 }
57};
58
37#ifndef CONFIG_RADIO_TERRATEC_PORT 59#ifndef CONFIG_RADIO_TERRATEC_PORT
38#define CONFIG_RADIO_TERRATEC_PORT 0x590 60#define CONFIG_RADIO_TERRATEC_PORT 0x590
39#endif 61#endif
@@ -194,73 +216,117 @@ static int tt_do_ioctl(struct inode *inode, struct file *file,
194 216
195 switch(cmd) 217 switch(cmd)
196 { 218 {
197 case VIDIOCGCAP: 219 case VIDIOC_QUERYCAP:
198 { 220 {
199 struct video_capability *v = arg; 221 struct v4l2_capability *v = arg;
200 memset(v,0,sizeof(*v)); 222 memset(v,0,sizeof(*v));
201 v->type=VID_TYPE_TUNER; 223 strlcpy(v->driver, "radio-terratec", sizeof (v->driver));
202 v->channels=1; 224 strlcpy(v->card, "ActiveRadio", sizeof (v->card));
203 v->audios=1; 225 sprintf(v->bus_info,"ISA");
204 strcpy(v->name, "ActiveRadio"); 226 v->version = RADIO_VERSION;
227 v->capabilities = V4L2_CAP_TUNER;
228
205 return 0; 229 return 0;
206 } 230 }
207 case VIDIOCGTUNER: 231 case VIDIOC_G_TUNER:
208 { 232 {
209 struct video_tuner *v = arg; 233 struct v4l2_tuner *v = arg;
210 if(v->tuner) /* Only 1 tuner */ 234
235 if (v->index > 0)
211 return -EINVAL; 236 return -EINVAL;
237
238 memset(v,0,sizeof(*v));
239 strcpy(v->name, "FM");
240 v->type = V4L2_TUNER_RADIO;
241
212 v->rangelow=(87*16000); 242 v->rangelow=(87*16000);
213 v->rangehigh=(108*16000); 243 v->rangehigh=(108*16000);
214 v->flags=VIDEO_TUNER_LOW; 244 v->rxsubchans =V4L2_TUNER_SUB_MONO;
215 v->mode=VIDEO_MODE_AUTO; 245 v->capability=V4L2_TUNER_CAP_LOW;
216 strcpy(v->name, "FM"); 246 v->audmode = V4L2_TUNER_MODE_MONO;
217 v->signal=0xFFFF*tt_getsigstr(tt); 247 v->signal=0xFFFF*tt_getsigstr(tt);
248
218 return 0; 249 return 0;
219 } 250 }
220 case VIDIOCSTUNER: 251 case VIDIOC_S_TUNER:
221 { 252 {
222 struct video_tuner *v = arg; 253 struct v4l2_tuner *v = arg;
223 if(v->tuner!=0) 254
255 if (v->index > 0)
224 return -EINVAL; 256 return -EINVAL;
225 /* Only 1 tuner so no setting needed ! */ 257
226 return 0; 258 return 0;
227 } 259 }
228 case VIDIOCGFREQ: 260 case VIDIOC_S_FREQUENCY:
229 { 261 {
230 unsigned long *freq = arg; 262 struct v4l2_frequency *f = arg;
231 *freq = tt->curfreq; 263
264 tt->curfreq = f->frequency;
265 tt_setfreq(tt, tt->curfreq);
232 return 0; 266 return 0;
233 } 267 }
234 case VIDIOCSFREQ: 268 case VIDIOC_G_FREQUENCY:
235 { 269 {
236 unsigned long *freq = arg; 270 struct v4l2_frequency *f = arg;
237 tt->curfreq = *freq; 271
238 tt_setfreq(tt, tt->curfreq); 272 f->type = V4L2_TUNER_RADIO;
273 f->frequency = tt->curfreq;
274
239 return 0; 275 return 0;
240 } 276 }
241 case VIDIOCGAUDIO: 277 case VIDIOC_QUERYCTRL:
242 { 278 {
243 struct video_audio *v = arg; 279 struct v4l2_queryctrl *qc = arg;
244 memset(v,0, sizeof(*v)); 280 int i;
245 v->flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME; 281
246 v->volume=tt->curvol * 6554; 282 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
247 v->step=6554; 283 if (qc->id && qc->id == radio_qctrl[i].id) {
248 strcpy(v->name, "Radio"); 284 memcpy(qc, &(radio_qctrl[i]),
249 return 0; 285 sizeof(*qc));
286 return (0);
287 }
288 }
289 return -EINVAL;
250 } 290 }
251 case VIDIOCSAUDIO: 291 case VIDIOC_G_CTRL:
252 { 292 {
253 struct video_audio *v = arg; 293 struct v4l2_control *ctrl= arg;
254 if(v->audio) 294
255 return -EINVAL; 295 switch (ctrl->id) {
256 if(v->flags&VIDEO_AUDIO_MUTE) 296 case V4L2_CID_AUDIO_MUTE:
257 tt_mute(tt); 297 if (tt->muted)
258 else 298 ctrl->value=1;
259 tt_setvol(tt,v->volume/6554); 299 else
260 return 0; 300 ctrl->value=0;
301 return (0);
302 case V4L2_CID_AUDIO_VOLUME:
303 ctrl->value=tt->curvol * 6554;
304 return (0);
305 }
306 return -EINVAL;
261 } 307 }
308 case VIDIOC_S_CTRL:
309 {
310 struct v4l2_control *ctrl= arg;
311
312 switch (ctrl->id) {
313 case V4L2_CID_AUDIO_MUTE:
314 if (ctrl->value) {
315 tt_mute(tt);
316 } else {
317 tt_setvol(tt,tt->curvol);
318 }
319 return (0);
320 case V4L2_CID_AUDIO_VOLUME:
321 tt_setvol(tt,ctrl->value);
322 return (0);
323 }
324 return -EINVAL;
325 }
326
262 default: 327 default:
263 return -ENOIOCTLCMD; 328 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
329 tt_do_ioctl);
264 } 330 }
265} 331}
266 332
@@ -286,7 +352,7 @@ static struct video_device terratec_radio=
286 .owner = THIS_MODULE, 352 .owner = THIS_MODULE,
287 .name = "TerraTec ActiveRadio", 353 .name = "TerraTec ActiveRadio",
288 .type = VID_TYPE_TUNER, 354 .type = VID_TYPE_TUNER,
289 .hardware = VID_HARDWARE_TERRATEC, 355 .hardware = 0,
290 .fops = &terratec_fops, 356 .fops = &terratec_fops,
291}; 357};
292 358
diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c
index 8da4badc22b4..bb03ad5a2033 100644
--- a/drivers/media/radio/radio-trust.c
+++ b/drivers/media/radio/radio-trust.c
@@ -12,7 +12,7 @@
12 * Scott McGrath (smcgrath@twilight.vtc.vsc.edu) 12 * Scott McGrath (smcgrath@twilight.vtc.vsc.edu)
13 * William McGrath (wmcgrath@twilight.vtc.vsc.edu) 13 * William McGrath (wmcgrath@twilight.vtc.vsc.edu)
14 * 14 *
15 * The basis for this code may be found at http://bigbang.vtc.vsc.edu/fmradio/ 15 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
16 */ 16 */
17 17
18#include <stdarg.h> 18#include <stdarg.h>
@@ -21,9 +21,46 @@
21#include <linux/ioport.h> 21#include <linux/ioport.h>
22#include <asm/io.h> 22#include <asm/io.h>
23#include <asm/uaccess.h> 23#include <asm/uaccess.h>
24#include <linux/videodev.h> 24#include <linux/videodev2.h>
25#include <media/v4l2-common.h> 25#include <media/v4l2-common.h>
26#include <linux/config.h> /* CONFIG_RADIO_TRUST_PORT */ 26
27#include <linux/version.h> /* for KERNEL_VERSION MACRO */
28#define RADIO_VERSION KERNEL_VERSION(0,0,2)
29
30static struct v4l2_queryctrl radio_qctrl[] = {
31 {
32 .id = V4L2_CID_AUDIO_MUTE,
33 .name = "Mute",
34 .minimum = 0,
35 .maximum = 1,
36 .default_value = 1,
37 .type = V4L2_CTRL_TYPE_BOOLEAN,
38 },{
39 .id = V4L2_CID_AUDIO_VOLUME,
40 .name = "Volume",
41 .minimum = 0,
42 .maximum = 65535,
43 .step = 2048,
44 .default_value = 65535,
45 .type = V4L2_CTRL_TYPE_INTEGER,
46 },{
47 .id = V4L2_CID_AUDIO_BASS,
48 .name = "Bass",
49 .minimum = 0,
50 .maximum = 65535,
51 .step = 4370,
52 .default_value = 32768,
53 .type = V4L2_CTRL_TYPE_INTEGER,
54 },{
55 .id = V4L2_CID_AUDIO_TREBLE,
56 .name = "Treble",
57 .minimum = 0,
58 .maximum = 65535,
59 .step = 4370,
60 .default_value = 32768,
61 .type = V4L2_CTRL_TYPE_INTEGER,
62 },
63};
27 64
28/* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */ 65/* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */
29 66
@@ -160,88 +197,125 @@ static int tr_do_ioctl(struct inode *inode, struct file *file,
160{ 197{
161 switch(cmd) 198 switch(cmd)
162 { 199 {
163 case VIDIOCGCAP: 200 case VIDIOC_QUERYCAP:
164 { 201 {
165 struct video_capability *v = arg; 202 struct v4l2_capability *v = arg;
166
167 memset(v,0,sizeof(*v)); 203 memset(v,0,sizeof(*v));
168 v->type=VID_TYPE_TUNER; 204 strlcpy(v->driver, "radio-trust", sizeof (v->driver));
169 v->channels=1; 205 strlcpy(v->card, "Trust FM Radio", sizeof (v->card));
170 v->audios=1; 206 sprintf(v->bus_info,"ISA");
171 strcpy(v->name, "Trust FM Radio"); 207 v->version = RADIO_VERSION;
208 v->capabilities = V4L2_CAP_TUNER;
172 209
173 return 0; 210 return 0;
174 } 211 }
175 case VIDIOCGTUNER: 212 case VIDIOC_G_TUNER:
176 { 213 {
177 struct video_tuner *v = arg; 214 struct v4l2_tuner *v = arg;
178 215
179 if(v->tuner) /* Only 1 tuner */ 216 if (v->index > 0)
180 return -EINVAL; 217 return -EINVAL;
181 218
182 v->rangelow = 87500 * 16; 219 memset(v,0,sizeof(*v));
183 v->rangehigh = 108000 * 16; 220 strcpy(v->name, "FM");
184 v->flags = VIDEO_TUNER_LOW; 221 v->type = V4L2_TUNER_RADIO;
185 v->mode = VIDEO_MODE_AUTO;
186 222
187 v->signal = tr_getsigstr(); 223 v->rangelow=(87.5*16000);
224 v->rangehigh=(108*16000);
225 v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
226 v->capability=V4L2_TUNER_CAP_LOW;
188 if(tr_getstereo()) 227 if(tr_getstereo())
189 v->flags |= VIDEO_TUNER_STEREO_ON; 228 v->audmode = V4L2_TUNER_MODE_STEREO;
190 229 else
191 strcpy(v->name, "FM"); 230 v->audmode = V4L2_TUNER_MODE_MONO;
231 v->signal=tr_getsigstr();
192 232
193 return 0; 233 return 0;
194 } 234 }
195 case VIDIOCSTUNER: 235 case VIDIOC_S_TUNER:
196 { 236 {
197 struct video_tuner *v = arg; 237 struct v4l2_tuner *v = arg;
198 if(v->tuner != 0) 238
239 if (v->index > 0)
199 return -EINVAL; 240 return -EINVAL;
241
200 return 0; 242 return 0;
201 } 243 }
202 case VIDIOCGFREQ: 244 case VIDIOC_S_FREQUENCY:
203 { 245 {
204 unsigned long *freq = arg; 246 struct v4l2_frequency *f = arg;
205 *freq = curfreq; 247
248 curfreq = f->frequency;
249 tr_setfreq(curfreq);
206 return 0; 250 return 0;
207 } 251 }
208 case VIDIOCSFREQ: 252 case VIDIOC_G_FREQUENCY:
209 { 253 {
210 unsigned long *freq = arg; 254 struct v4l2_frequency *f = arg;
211 tr_setfreq(*freq); 255
256 f->type = V4L2_TUNER_RADIO;
257 f->frequency = curfreq;
258
212 return 0; 259 return 0;
213 } 260 }
214 case VIDIOCGAUDIO: 261 case VIDIOC_QUERYCTRL:
215 { 262 {
216 struct video_audio *v = arg; 263 struct v4l2_queryctrl *qc = arg;
217 264 int i;
218 memset(v,0, sizeof(*v)); 265
219 v->flags = VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME | 266 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
220 VIDEO_AUDIO_BASS | VIDEO_AUDIO_TREBLE; 267 if (qc->id && qc->id == radio_qctrl[i].id) {
221 v->mode = curstereo? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO; 268 memcpy(qc, &(radio_qctrl[i]),
222 v->volume = curvol * 2048; 269 sizeof(*qc));
223 v->step = 2048; 270 return (0);
224 v->bass = curbass * 4370; 271 }
225 v->treble = curtreble * 4370; 272 }
226 273 return -EINVAL;
227 strcpy(v->name, "Trust FM Radio");
228 return 0;
229 } 274 }
230 case VIDIOCSAUDIO: 275 case VIDIOC_G_CTRL:
231 { 276 {
232 struct video_audio *v = arg; 277 struct v4l2_control *ctrl= arg;
233 278
234 if(v->audio) 279 switch (ctrl->id) {
235 return -EINVAL; 280 case V4L2_CID_AUDIO_MUTE:
236 tr_setvol(v->volume); 281 ctrl->value=curmute;
237 tr_setbass(v->bass); 282 return (0);
238 tr_settreble(v->treble); 283 case V4L2_CID_AUDIO_VOLUME:
239 tr_setstereo(v->mode & VIDEO_SOUND_STEREO); 284 ctrl->value= curvol * 2048;
240 tr_setmute(v->flags & VIDEO_AUDIO_MUTE); 285 return (0);
241 return 0; 286 case V4L2_CID_AUDIO_BASS:
287 ctrl->value= curbass * 4370;
288 return (0);
289 case V4L2_CID_AUDIO_TREBLE:
290 ctrl->value= curtreble * 4370;
291 return (0);
292 }
293 return -EINVAL;
242 } 294 }
295 case VIDIOC_S_CTRL:
296 {
297 struct v4l2_control *ctrl= arg;
298
299 switch (ctrl->id) {
300 case V4L2_CID_AUDIO_MUTE:
301 tr_setmute(ctrl->value);
302 return 0;
303 case V4L2_CID_AUDIO_VOLUME:
304 tr_setvol(ctrl->value);
305 return 0;
306 case V4L2_CID_AUDIO_BASS:
307 tr_setbass(ctrl->value);
308 return 0;
309 case V4L2_CID_AUDIO_TREBLE:
310 tr_settreble(ctrl->value);
311 return (0);
312 }
313 return -EINVAL;
314 }
315
243 default: 316 default:
244 return -ENOIOCTLCMD; 317 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
318 tr_do_ioctl);
245 } 319 }
246} 320}
247 321
@@ -265,7 +339,7 @@ static struct video_device trust_radio=
265 .owner = THIS_MODULE, 339 .owner = THIS_MODULE,
266 .name = "Trust FM Radio", 340 .name = "Trust FM Radio",
267 .type = VID_TYPE_TUNER, 341 .type = VID_TYPE_TUNER,
268 .hardware = VID_HARDWARE_TRUST, 342 .hardware = 0,
269 .fops = &trust_fops, 343 .fops = &trust_fops,
270}; 344};
271 345
diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c
index edd012288669..4a72b4d4e62a 100644
--- a/drivers/media/radio/radio-typhoon.c
+++ b/drivers/media/radio/radio-typhoon.c
@@ -27,6 +27,8 @@
27 * value where I do expect just noise and turn the speaker volume down. 27 * value where I do expect just noise and turn the speaker volume down.
28 * The frequency change is necessary since the card never seems to be 28 * The frequency change is necessary since the card never seems to be
29 * completely silent. 29 * completely silent.
30 *
31 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
30 */ 32 */
31 33
32#include <linux/module.h> /* Modules */ 34#include <linux/module.h> /* Modules */
@@ -35,11 +37,32 @@
35#include <linux/proc_fs.h> /* radio card status report */ 37#include <linux/proc_fs.h> /* radio card status report */
36#include <asm/io.h> /* outb, outb_p */ 38#include <asm/io.h> /* outb, outb_p */
37#include <asm/uaccess.h> /* copy to/from user */ 39#include <asm/uaccess.h> /* copy to/from user */
38#include <linux/videodev.h> /* kernel radio structs */ 40#include <linux/videodev2.h> /* kernel radio structs */
39#include <media/v4l2-common.h> 41#include <media/v4l2-common.h>
40#include <linux/config.h> /* CONFIG_RADIO_TYPHOON_* */
41 42
42#define BANNER "Typhoon Radio Card driver v0.1\n" 43#include <linux/version.h> /* for KERNEL_VERSION MACRO */
44#define RADIO_VERSION KERNEL_VERSION(0,1,1)
45#define BANNER "Typhoon Radio Card driver v0.1.1\n"
46
47static struct v4l2_queryctrl radio_qctrl[] = {
48 {
49 .id = V4L2_CID_AUDIO_MUTE,
50 .name = "Mute",
51 .minimum = 0,
52 .maximum = 1,
53 .default_value = 1,
54 .type = V4L2_CTRL_TYPE_BOOLEAN,
55 },{
56 .id = V4L2_CID_AUDIO_VOLUME,
57 .name = "Volume",
58 .minimum = 0,
59 .maximum = 65535,
60 .step = 1<<14,
61 .default_value = 0xff,
62 .type = V4L2_CTRL_TYPE_INTEGER,
63 }
64};
65
43 66
44#ifndef CONFIG_RADIO_TYPHOON_PORT 67#ifndef CONFIG_RADIO_TYPHOON_PORT
45#define CONFIG_RADIO_TYPHOON_PORT -1 68#define CONFIG_RADIO_TYPHOON_PORT -1
@@ -171,76 +194,114 @@ static int typhoon_do_ioctl(struct inode *inode, struct file *file,
171 struct typhoon_device *typhoon = dev->priv; 194 struct typhoon_device *typhoon = dev->priv;
172 195
173 switch (cmd) { 196 switch (cmd) {
174 case VIDIOCGCAP: 197 case VIDIOC_QUERYCAP:
175 { 198 {
176 struct video_capability *v = arg; 199 struct v4l2_capability *v = arg;
177 memset(v,0,sizeof(*v)); 200 memset(v,0,sizeof(*v));
178 v->type = VID_TYPE_TUNER; 201 strlcpy(v->driver, "radio-typhoon", sizeof (v->driver));
179 v->channels = 1; 202 strlcpy(v->card, "Typhoon Radio", sizeof (v->card));
180 v->audios = 1; 203 sprintf(v->bus_info,"ISA");
181 strcpy(v->name, "Typhoon Radio"); 204 v->version = RADIO_VERSION;
205 v->capabilities = V4L2_CAP_TUNER;
206
182 return 0; 207 return 0;
183 } 208 }
184 case VIDIOCGTUNER: 209 case VIDIOC_G_TUNER:
185 { 210 {
186 struct video_tuner *v = arg; 211 struct v4l2_tuner *v = arg;
187 if (v->tuner) /* Only 1 tuner */ 212
213 if (v->index > 0)
188 return -EINVAL; 214 return -EINVAL;
189 v->rangelow = 875 * 1600; 215
190 v->rangehigh = 1080 * 1600; 216 memset(v,0,sizeof(*v));
191 v->flags = VIDEO_TUNER_LOW;
192 v->mode = VIDEO_MODE_AUTO;
193 v->signal = 0xFFFF; /* We can't get the signal strength */
194 strcpy(v->name, "FM"); 217 strcpy(v->name, "FM");
218 v->type = V4L2_TUNER_RADIO;
219
220 v->rangelow=(87.5*16000);
221 v->rangehigh=(108*16000);
222 v->rxsubchans =V4L2_TUNER_SUB_MONO;
223 v->capability=V4L2_TUNER_CAP_LOW;
224 v->audmode = V4L2_TUNER_MODE_MONO;
225 v->signal = 0xFFFF; /* We can't get the signal strength */
226
195 return 0; 227 return 0;
196 } 228 }
197 case VIDIOCSTUNER: 229 case VIDIOC_S_TUNER:
198 { 230 {
199 struct video_tuner *v = arg; 231 struct v4l2_tuner *v = arg;
200 if (v->tuner != 0) 232
233 if (v->index > 0)
201 return -EINVAL; 234 return -EINVAL;
202 /* Only 1 tuner so no setting needed ! */ 235
203 return 0; 236 return 0;
204 } 237 }
205 case VIDIOCGFREQ: 238 case VIDIOC_S_FREQUENCY:
206 {
207 unsigned long *freq = arg;
208 *freq = typhoon->curfreq;
209 return 0;
210 }
211 case VIDIOCSFREQ:
212 {
213 unsigned long *freq = arg;
214 typhoon->curfreq = *freq;
215 typhoon_setfreq(typhoon, typhoon->curfreq);
216 return 0;
217 }
218 case VIDIOCGAUDIO:
219 { 239 {
220 struct video_audio *v = arg; 240 struct v4l2_frequency *f = arg;
221 memset(v, 0, sizeof(*v)); 241
222 v->flags |= VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME; 242 typhoon->curfreq = f->frequency;
223 v->mode |= VIDEO_SOUND_MONO; 243 typhoon_setfreq(typhoon, typhoon->curfreq);
224 v->volume = typhoon->curvol;
225 v->step = 1 << 14;
226 strcpy(v->name, "Typhoon Radio");
227 return 0; 244 return 0;
228 } 245 }
229 case VIDIOCSAUDIO: 246 case VIDIOC_G_FREQUENCY:
230 { 247 {
231 struct video_audio *v = arg; 248 struct v4l2_frequency *f = arg;
232 if (v->audio) 249
233 return -EINVAL; 250 f->type = V4L2_TUNER_RADIO;
234 if (v->flags & VIDEO_AUDIO_MUTE) 251 f->frequency = typhoon->curfreq;
235 typhoon_mute(typhoon); 252
236 else
237 typhoon_unmute(typhoon);
238 if (v->flags & VIDEO_AUDIO_VOLUME)
239 typhoon_setvol(typhoon, v->volume);
240 return 0; 253 return 0;
241 } 254 }
242 default: 255 case VIDIOC_QUERYCTRL:
243 return -ENOIOCTLCMD; 256 {
257 struct v4l2_queryctrl *qc = arg;
258 int i;
259
260 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
261 if (qc->id && qc->id == radio_qctrl[i].id) {
262 memcpy(qc, &(radio_qctrl[i]),
263 sizeof(*qc));
264 return (0);
265 }
266 }
267 return -EINVAL;
268 }
269 case VIDIOC_G_CTRL:
270 {
271 struct v4l2_control *ctrl= arg;
272
273 switch (ctrl->id) {
274 case V4L2_CID_AUDIO_MUTE:
275 ctrl->value=typhoon->muted;
276 return (0);
277 case V4L2_CID_AUDIO_VOLUME:
278 ctrl->value=typhoon->curvol;
279 return (0);
280 }
281 return -EINVAL;
282 }
283 case VIDIOC_S_CTRL:
284 {
285 struct v4l2_control *ctrl= arg;
286
287 switch (ctrl->id) {
288 case V4L2_CID_AUDIO_MUTE:
289 if (ctrl->value) {
290 typhoon_mute(typhoon);
291 } else {
292 typhoon_unmute(typhoon);
293 }
294 return (0);
295 case V4L2_CID_AUDIO_VOLUME:
296 typhoon_setvol(typhoon, ctrl->value);
297 return (0);
298 }
299 return -EINVAL;
300 }
301
302 default:
303 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
304 typhoon_do_ioctl);
244 } 305 }
245} 306}
246 307
@@ -271,7 +332,7 @@ static struct video_device typhoon_radio =
271 .owner = THIS_MODULE, 332 .owner = THIS_MODULE,
272 .name = "Typhoon Radio", 333 .name = "Typhoon Radio",
273 .type = VID_TYPE_TUNER, 334 .type = VID_TYPE_TUNER,
274 .hardware = VID_HARDWARE_TYPHOON, 335 .hardware = 0,
275 .fops = &typhoon_fops, 336 .fops = &typhoon_fops,
276}; 337};
277 338
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c
index 59b86a6b4b0e..671fe1b1e5bc 100644
--- a/drivers/media/radio/radio-zoltrix.c
+++ b/drivers/media/radio/radio-zoltrix.c
@@ -24,6 +24,9 @@
24 * - Added unmute function 24 * - Added unmute function
25 * - Reworked ioctl functions 25 * - Reworked ioctl functions
26 * 2002-07-15 - Fix Stereo typo 26 * 2002-07-15 - Fix Stereo typo
27 *
28 * 2006-07-24 - Converted to V4L2 API
29 * by Mauro Carvalho Chehab <mchehab@infradead.org>
27 */ 30 */
28 31
29#include <linux/module.h> /* Modules */ 32#include <linux/module.h> /* Modules */
@@ -32,9 +35,30 @@
32#include <linux/delay.h> /* udelay, msleep */ 35#include <linux/delay.h> /* udelay, msleep */
33#include <asm/io.h> /* outb, outb_p */ 36#include <asm/io.h> /* outb, outb_p */
34#include <asm/uaccess.h> /* copy to/from user */ 37#include <asm/uaccess.h> /* copy to/from user */
35#include <linux/videodev.h> /* kernel radio structs */ 38#include <linux/videodev2.h> /* kernel radio structs */
36#include <media/v4l2-common.h> 39#include <media/v4l2-common.h>
37#include <linux/config.h> /* CONFIG_RADIO_ZOLTRIX_PORT */ 40
41#include <linux/version.h> /* for KERNEL_VERSION MACRO */
42#define RADIO_VERSION KERNEL_VERSION(0,0,2)
43
44static struct v4l2_queryctrl radio_qctrl[] = {
45 {
46 .id = V4L2_CID_AUDIO_MUTE,
47 .name = "Mute",
48 .minimum = 0,
49 .maximum = 1,
50 .default_value = 1,
51 .type = V4L2_CTRL_TYPE_BOOLEAN,
52 },{
53 .id = V4L2_CID_AUDIO_VOLUME,
54 .name = "Volume",
55 .minimum = 0,
56 .maximum = 65535,
57 .step = 4096,
58 .default_value = 0xff,
59 .type = V4L2_CTRL_TYPE_INTEGER,
60 }
61};
38 62
39#ifndef CONFIG_RADIO_ZOLTRIX_PORT 63#ifndef CONFIG_RADIO_ZOLTRIX_PORT
40#define CONFIG_RADIO_ZOLTRIX_PORT -1 64#define CONFIG_RADIO_ZOLTRIX_PORT -1
@@ -213,78 +237,116 @@ static int zol_do_ioctl(struct inode *inode, struct file *file,
213 struct zol_device *zol = dev->priv; 237 struct zol_device *zol = dev->priv;
214 238
215 switch (cmd) { 239 switch (cmd) {
216 case VIDIOCGCAP: 240 case VIDIOC_QUERYCAP:
217 { 241 {
218 struct video_capability *v = arg; 242 struct v4l2_capability *v = arg;
219
220 memset(v,0,sizeof(*v)); 243 memset(v,0,sizeof(*v));
221 v->type = VID_TYPE_TUNER; 244 strlcpy(v->driver, "radio-zoltrix", sizeof (v->driver));
222 v->channels = 1 + zol->stereo; 245 strlcpy(v->card, "Zoltrix Radio", sizeof (v->card));
223 v->audios = 1; 246 sprintf(v->bus_info,"ISA");
224 strcpy(v->name, "Zoltrix Radio"); 247 v->version = RADIO_VERSION;
248 v->capabilities = V4L2_CAP_TUNER;
249
225 return 0; 250 return 0;
226 } 251 }
227 case VIDIOCGTUNER: 252 case VIDIOC_G_TUNER:
228 { 253 {
229 struct video_tuner *v = arg; 254 struct v4l2_tuner *v = arg;
230 if (v->tuner) 255
256 if (v->index > 0)
231 return -EINVAL; 257 return -EINVAL;
258
259 memset(v,0,sizeof(*v));
232 strcpy(v->name, "FM"); 260 strcpy(v->name, "FM");
233 v->rangelow = (int) (88.0 * 16000); 261 v->type = V4L2_TUNER_RADIO;
234 v->rangehigh = (int) (108.0 * 16000); 262
235 v->flags = zol_is_stereo(zol) 263 v->rangelow=(88*16000);
236 ? VIDEO_TUNER_STEREO_ON : 0; 264 v->rangehigh=(108*16000);
237 v->flags |= VIDEO_TUNER_LOW; 265 v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
238 v->mode = VIDEO_MODE_AUTO; 266 v->capability=V4L2_TUNER_CAP_LOW;
239 v->signal = 0xFFFF * zol_getsigstr(zol); 267 if(zol_is_stereo(zol))
268 v->audmode = V4L2_TUNER_MODE_STEREO;
269 else
270 v->audmode = V4L2_TUNER_MODE_MONO;
271 v->signal=0xFFFF*zol_getsigstr(zol);
272
240 return 0; 273 return 0;
241 } 274 }
242 case VIDIOCSTUNER: 275 case VIDIOC_S_TUNER:
243 { 276 {
244 struct video_tuner *v = arg; 277 struct v4l2_tuner *v = arg;
245 if (v->tuner != 0) 278
279 if (v->index > 0)
246 return -EINVAL; 280 return -EINVAL;
247 /* Only 1 tuner so no setting needed ! */ 281
248 return 0; 282 return 0;
249 } 283 }
250 case VIDIOCGFREQ: 284 case VIDIOC_S_FREQUENCY:
251 {
252 unsigned long *freq = arg;
253 *freq = zol->curfreq;
254 return 0;
255 }
256 case VIDIOCSFREQ:
257 {
258 unsigned long *freq = arg;
259 zol->curfreq = *freq;
260 zol_setfreq(zol, zol->curfreq);
261 return 0;
262 }
263 case VIDIOCGAUDIO:
264 { 285 {
265 struct video_audio *v = arg; 286 struct v4l2_frequency *f = arg;
266 memset(v, 0, sizeof(*v)); 287
267 v->flags |= VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME; 288 zol->curfreq = f->frequency;
268 v->mode |= zol_is_stereo(zol) 289 zol_setfreq(zol, zol->curfreq);
269 ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO;
270 v->volume = zol->curvol * 4096;
271 v->step = 4096;
272 strcpy(v->name, "Zoltrix Radio");
273 return 0; 290 return 0;
274 } 291 }
275 case VIDIOCSAUDIO: 292 case VIDIOC_G_FREQUENCY:
276 { 293 {
277 struct video_audio *v = arg; 294 struct v4l2_frequency *f = arg;
278 if (v->audio)
279 return -EINVAL;
280 295
281 if (v->flags & VIDEO_AUDIO_MUTE) 296 f->type = V4L2_TUNER_RADIO;
282 zol_mute(zol); 297 f->frequency = zol->curfreq;
283 else {
284 zol_unmute(zol);
285 zol_setvol(zol, v->volume / 4096);
286 }
287 298
299 return 0;
300 }
301 case VIDIOC_QUERYCTRL:
302 {
303 struct v4l2_queryctrl *qc = arg;
304 int i;
305
306 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
307 if (qc->id && qc->id == radio_qctrl[i].id) {
308 memcpy(qc, &(radio_qctrl[i]),
309 sizeof(*qc));
310 return (0);
311 }
312 }
313 return -EINVAL;
314 }
315 case VIDIOC_G_CTRL:
316 {
317 struct v4l2_control *ctrl= arg;
318
319 switch (ctrl->id) {
320 case V4L2_CID_AUDIO_MUTE:
321 ctrl->value=zol->muted;
322 return (0);
323 case V4L2_CID_AUDIO_VOLUME:
324 ctrl->value=zol->curvol * 4096;
325 return (0);
326 }
327 return -EINVAL;
328 }
329 case VIDIOC_S_CTRL:
330 {
331 struct v4l2_control *ctrl= arg;
332
333 switch (ctrl->id) {
334 case V4L2_CID_AUDIO_MUTE:
335 if (ctrl->value) {
336 zol_mute(zol);
337 } else {
338 zol_unmute(zol);
339 zol_setvol(zol,zol->curvol);
340 }
341 return (0);
342 case V4L2_CID_AUDIO_VOLUME:
343 zol_setvol(zol,ctrl->value/4096);
344 return (0);
345 }
346 zol->stereo = 1;
347 zol_setfreq(zol, zol->curfreq);
348#if 0
349/* FIXME: Implement stereo/mono switch on V4L2 */
288 if (v->mode & VIDEO_SOUND_STEREO) { 350 if (v->mode & VIDEO_SOUND_STEREO) {
289 zol->stereo = 1; 351 zol->stereo = 1;
290 zol_setfreq(zol, zol->curfreq); 352 zol_setfreq(zol, zol->curfreq);
@@ -293,10 +355,13 @@ static int zol_do_ioctl(struct inode *inode, struct file *file,
293 zol->stereo = 0; 355 zol->stereo = 0;
294 zol_setfreq(zol, zol->curfreq); 356 zol_setfreq(zol, zol->curfreq);
295 } 357 }
296 return 0; 358#endif
359 return -EINVAL;
297 } 360 }
298 default: 361
299 return -ENOIOCTLCMD; 362 default:
363 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
364 zol_do_ioctl);
300 } 365 }
301} 366}
302 367
@@ -323,7 +388,7 @@ static struct video_device zoltrix_radio =
323 .owner = THIS_MODULE, 388 .owner = THIS_MODULE,
324 .name = "Zoltrix Radio Plus", 389 .name = "Zoltrix Radio Plus",
325 .type = VID_TYPE_TUNER, 390 .type = VID_TYPE_TUNER,
326 .hardware = VID_HARDWARE_ZOLTRIX, 391 .hardware = 0,
327 .fops = &zoltrix_fops, 392 .fops = &zoltrix_fops,
328}; 393};
329 394