diff options
Diffstat (limited to 'drivers/media/radio/radio-gemtek-pci.c')
-rw-r--r-- | drivers/media/radio/radio-gemtek-pci.c | 170 |
1 files changed, 110 insertions, 60 deletions
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c index 4c82956390c1..ee19979e540c 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 | |||
54 | static 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_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 | ||