diff options
Diffstat (limited to 'drivers/media/radio/radio-terratec.c')
-rw-r--r-- | drivers/media/radio/radio-terratec.c | 247 |
1 files changed, 138 insertions, 109 deletions
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c index d59a27accb84..e43acfd7e533 100644 --- a/drivers/media/radio/radio-terratec.c +++ b/drivers/media/radio/radio-terratec.c | |||
@@ -205,135 +205,152 @@ static int tt_getsigstr(struct tt_device *dev) /* TODO */ | |||
205 | return 1; /* signal present */ | 205 | return 1; /* signal present */ |
206 | } | 206 | } |
207 | 207 | ||
208 | static int vidioc_querycap(struct file *file, void *priv, | ||
209 | struct v4l2_capability *v) | ||
210 | { | ||
211 | strlcpy(v->driver, "radio-terratec", sizeof(v->driver)); | ||
212 | strlcpy(v->card, "ActiveRadio", sizeof(v->card)); | ||
213 | sprintf(v->bus_info, "ISA"); | ||
214 | v->version = RADIO_VERSION; | ||
215 | v->capabilities = V4L2_CAP_TUNER; | ||
216 | return 0; | ||
217 | } | ||
208 | 218 | ||
209 | /* implement the video4linux api */ | 219 | static int vidioc_g_tuner(struct file *file, void *priv, |
210 | 220 | struct v4l2_tuner *v) | |
211 | static int tt_do_ioctl(struct inode *inode, struct file *file, | ||
212 | unsigned int cmd, void *arg) | ||
213 | { | 221 | { |
214 | struct video_device *dev = video_devdata(file); | 222 | struct video_device *dev = video_devdata(file); |
215 | struct tt_device *tt=dev->priv; | 223 | struct tt_device *tt = dev->priv; |
216 | 224 | ||
217 | switch(cmd) | 225 | if (v->index > 0) |
218 | { | 226 | return -EINVAL; |
219 | case VIDIOC_QUERYCAP: | ||
220 | { | ||
221 | struct v4l2_capability *v = arg; | ||
222 | memset(v,0,sizeof(*v)); | ||
223 | strlcpy(v->driver, "radio-terratec", sizeof (v->driver)); | ||
224 | strlcpy(v->card, "ActiveRadio", sizeof (v->card)); | ||
225 | sprintf(v->bus_info,"ISA"); | ||
226 | v->version = RADIO_VERSION; | ||
227 | v->capabilities = V4L2_CAP_TUNER; | ||
228 | 227 | ||
229 | return 0; | 228 | strcpy(v->name, "FM"); |
230 | } | 229 | v->type = V4L2_TUNER_RADIO; |
231 | case VIDIOC_G_TUNER: | 230 | v->rangelow = (87*16000); |
232 | { | 231 | v->rangehigh = (108*16000); |
233 | struct v4l2_tuner *v = arg; | 232 | v->rxsubchans = V4L2_TUNER_SUB_MONO; |
233 | v->capability = V4L2_TUNER_CAP_LOW; | ||
234 | v->audmode = V4L2_TUNER_MODE_MONO; | ||
235 | v->signal = 0xFFFF*tt_getsigstr(tt); | ||
236 | return 0; | ||
237 | } | ||
234 | 238 | ||
235 | if (v->index > 0) | 239 | static int vidioc_s_tuner(struct file *file, void *priv, |
236 | return -EINVAL; | 240 | struct v4l2_tuner *v) |
241 | { | ||
242 | if (v->index > 0) | ||
243 | return -EINVAL; | ||
244 | return 0; | ||
245 | } | ||
237 | 246 | ||
238 | memset(v,0,sizeof(*v)); | 247 | static int vidioc_s_frequency(struct file *file, void *priv, |
239 | strcpy(v->name, "FM"); | 248 | struct v4l2_frequency *f) |
240 | v->type = V4L2_TUNER_RADIO; | 249 | { |
250 | struct video_device *dev = video_devdata(file); | ||
251 | struct tt_device *tt = dev->priv; | ||
241 | 252 | ||
242 | v->rangelow=(87*16000); | 253 | tt->curfreq = f->frequency; |
243 | v->rangehigh=(108*16000); | 254 | tt_setfreq(tt, tt->curfreq); |
244 | v->rxsubchans =V4L2_TUNER_SUB_MONO; | 255 | return 0; |
245 | v->capability=V4L2_TUNER_CAP_LOW; | 256 | } |
246 | v->audmode = V4L2_TUNER_MODE_MONO; | ||
247 | v->signal=0xFFFF*tt_getsigstr(tt); | ||
248 | 257 | ||
249 | return 0; | 258 | static int vidioc_g_frequency(struct file *file, void *priv, |
250 | } | 259 | struct v4l2_frequency *f) |
251 | case VIDIOC_S_TUNER: | 260 | { |
252 | { | 261 | struct video_device *dev = video_devdata(file); |
253 | struct v4l2_tuner *v = arg; | 262 | struct tt_device *tt = dev->priv; |
254 | 263 | ||
255 | if (v->index > 0) | 264 | f->type = V4L2_TUNER_RADIO; |
256 | return -EINVAL; | 265 | f->frequency = tt->curfreq; |
266 | return 0; | ||
267 | } | ||
257 | 268 | ||
258 | return 0; | 269 | static int vidioc_queryctrl(struct file *file, void *priv, |
259 | } | 270 | struct v4l2_queryctrl *qc) |
260 | case VIDIOC_S_FREQUENCY: | 271 | { |
261 | { | 272 | int i; |
262 | struct v4l2_frequency *f = arg; | ||
263 | 273 | ||
264 | tt->curfreq = f->frequency; | 274 | for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { |
265 | tt_setfreq(tt, tt->curfreq); | 275 | if (qc->id && qc->id == radio_qctrl[i].id) { |
276 | memcpy(qc, &(radio_qctrl[i]), | ||
277 | sizeof(*qc)); | ||
266 | return 0; | 278 | return 0; |
267 | } | 279 | } |
268 | case VIDIOC_G_FREQUENCY: | 280 | } |
269 | { | 281 | return -EINVAL; |
270 | struct v4l2_frequency *f = arg; | 282 | } |
271 | 283 | ||
272 | f->type = V4L2_TUNER_RADIO; | 284 | static int vidioc_g_ctrl(struct file *file, void *priv, |
273 | f->frequency = tt->curfreq; | 285 | struct v4l2_control *ctrl) |
286 | { | ||
287 | struct video_device *dev = video_devdata(file); | ||
288 | struct tt_device *tt = dev->priv; | ||
274 | 289 | ||
275 | return 0; | 290 | switch (ctrl->id) { |
276 | } | 291 | case V4L2_CID_AUDIO_MUTE: |
277 | case VIDIOC_QUERYCTRL: | 292 | if (tt->muted) |
278 | { | 293 | ctrl->value = 1; |
279 | struct v4l2_queryctrl *qc = arg; | 294 | else |
280 | int i; | 295 | ctrl->value = 0; |
281 | 296 | return 0; | |
282 | for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { | 297 | case V4L2_CID_AUDIO_VOLUME: |
283 | if (qc->id && qc->id == radio_qctrl[i].id) { | 298 | ctrl->value = tt->curvol * 6554; |
284 | memcpy(qc, &(radio_qctrl[i]), | 299 | return 0; |
285 | sizeof(*qc)); | 300 | } |
286 | return (0); | 301 | return -EINVAL; |
287 | } | 302 | } |
288 | } | ||
289 | return -EINVAL; | ||
290 | } | ||
291 | case VIDIOC_G_CTRL: | ||
292 | { | ||
293 | struct v4l2_control *ctrl= arg; | ||
294 | |||
295 | switch (ctrl->id) { | ||
296 | case V4L2_CID_AUDIO_MUTE: | ||
297 | if (tt->muted) | ||
298 | ctrl->value=1; | ||
299 | else | ||
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; | ||
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 | 303 | ||
327 | default: | 304 | static int vidioc_s_ctrl(struct file *file, void *priv, |
328 | return v4l_compat_translate_ioctl(inode,file,cmd,arg, | 305 | struct v4l2_control *ctrl) |
329 | tt_do_ioctl); | 306 | { |
307 | struct video_device *dev = video_devdata(file); | ||
308 | struct tt_device *tt = dev->priv; | ||
309 | |||
310 | switch (ctrl->id) { | ||
311 | case V4L2_CID_AUDIO_MUTE: | ||
312 | if (ctrl->value) | ||
313 | tt_mute(tt); | ||
314 | else | ||
315 | tt_setvol(tt,tt->curvol); | ||
316 | return 0; | ||
317 | case V4L2_CID_AUDIO_VOLUME: | ||
318 | tt_setvol(tt,ctrl->value); | ||
319 | return 0; | ||
330 | } | 320 | } |
321 | return -EINVAL; | ||
322 | } | ||
323 | |||
324 | static int vidioc_g_audio(struct file *file, void *priv, | ||
325 | struct v4l2_audio *a) | ||
326 | { | ||
327 | if (a->index > 1) | ||
328 | return -EINVAL; | ||
329 | |||
330 | strcpy(a->name, "Radio"); | ||
331 | a->capability = V4L2_AUDCAP_STEREO; | ||
332 | return 0; | ||
333 | } | ||
334 | |||
335 | static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) | ||
336 | { | ||
337 | *i = 0; | ||
338 | return 0; | ||
331 | } | 339 | } |
332 | 340 | ||
333 | static int tt_ioctl(struct inode *inode, struct file *file, | 341 | static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) |
334 | unsigned int cmd, unsigned long arg) | ||
335 | { | 342 | { |
336 | return video_usercopy(inode, file, cmd, arg, tt_do_ioctl); | 343 | if (i != 0) |
344 | return -EINVAL; | ||
345 | return 0; | ||
346 | } | ||
347 | |||
348 | static int vidioc_s_audio(struct file *file, void *priv, | ||
349 | struct v4l2_audio *a) | ||
350 | { | ||
351 | if (a->index != 0) | ||
352 | return -EINVAL; | ||
353 | return 0; | ||
337 | } | 354 | } |
338 | 355 | ||
339 | static struct tt_device terratec_unit; | 356 | static struct tt_device terratec_unit; |
@@ -342,7 +359,7 @@ static const struct file_operations terratec_fops = { | |||
342 | .owner = THIS_MODULE, | 359 | .owner = THIS_MODULE, |
343 | .open = video_exclusive_open, | 360 | .open = video_exclusive_open, |
344 | .release = video_exclusive_release, | 361 | .release = video_exclusive_release, |
345 | .ioctl = tt_ioctl, | 362 | .ioctl = video_ioctl2, |
346 | .compat_ioctl = v4l_compat_ioctl32, | 363 | .compat_ioctl = v4l_compat_ioctl32, |
347 | .llseek = no_llseek, | 364 | .llseek = no_llseek, |
348 | }; | 365 | }; |
@@ -354,6 +371,18 @@ static struct video_device terratec_radio= | |||
354 | .type = VID_TYPE_TUNER, | 371 | .type = VID_TYPE_TUNER, |
355 | .hardware = 0, | 372 | .hardware = 0, |
356 | .fops = &terratec_fops, | 373 | .fops = &terratec_fops, |
374 | .vidioc_querycap = vidioc_querycap, | ||
375 | .vidioc_g_tuner = vidioc_g_tuner, | ||
376 | .vidioc_s_tuner = vidioc_s_tuner, | ||
377 | .vidioc_g_frequency = vidioc_g_frequency, | ||
378 | .vidioc_s_frequency = vidioc_s_frequency, | ||
379 | .vidioc_queryctrl = vidioc_queryctrl, | ||
380 | .vidioc_g_ctrl = vidioc_g_ctrl, | ||
381 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
382 | .vidioc_g_audio = vidioc_g_audio, | ||
383 | .vidioc_s_audio = vidioc_s_audio, | ||
384 | .vidioc_g_input = vidioc_g_input, | ||
385 | .vidioc_s_input = vidioc_s_input, | ||
357 | }; | 386 | }; |
358 | 387 | ||
359 | static int __init terratec_init(void) | 388 | static int __init terratec_init(void) |