diff options
author | Ondrej Zary <linux@rainbow-software.org> | 2011-05-23 08:17:19 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-07-27 16:52:20 -0400 |
commit | 4522e825dbfc19537a08f65719dc3d69c46fe661 (patch) | |
tree | 174e008ad224d01104f92e4e247431c749c91d6a | |
parent | 2ef403708880c6e00854fb81bbffb9a4036327e6 (diff) |
[media] tea575x: convert to control framework
Convert tea575x-tuner to use the new V4L2 control framework. Also add
ext_init() callback that can be used by a card driver for additional
initialization right before registering the video device (for SF16-FMR2).
Also embed struct video_device to struct snd_tea575x to simplify the code.
Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
Acked-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | include/sound/tea575x-tuner.h | 6 | ||||
-rw-r--r-- | sound/i2c/other/tea575x-tuner.c | 106 |
2 files changed, 39 insertions, 73 deletions
diff --git a/include/sound/tea575x-tuner.h b/include/sound/tea575x-tuner.h index d2ea112fc20f..5aa8186e7820 100644 --- a/include/sound/tea575x-tuner.h +++ b/include/sound/tea575x-tuner.h | |||
@@ -23,8 +23,8 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include <linux/videodev2.h> | 25 | #include <linux/videodev2.h> |
26 | #include <media/v4l2-ctrls.h> | ||
26 | #include <media/v4l2-dev.h> | 27 | #include <media/v4l2-dev.h> |
27 | #include <media/v4l2-ioctl.h> | ||
28 | 28 | ||
29 | #define TEA575X_FMIF 10700 | 29 | #define TEA575X_FMIF 10700 |
30 | 30 | ||
@@ -42,7 +42,7 @@ struct snd_tea575x_ops { | |||
42 | }; | 42 | }; |
43 | 43 | ||
44 | struct snd_tea575x { | 44 | struct snd_tea575x { |
45 | struct video_device *vd; /* video device */ | 45 | struct video_device vd; /* video device */ |
46 | bool tea5759; /* 5759 chip is present */ | 46 | bool tea5759; /* 5759 chip is present */ |
47 | bool mute; /* Device is muted? */ | 47 | bool mute; /* Device is muted? */ |
48 | bool stereo; /* receiving stereo */ | 48 | bool stereo; /* receiving stereo */ |
@@ -54,6 +54,8 @@ struct snd_tea575x { | |||
54 | void *private_data; | 54 | void *private_data; |
55 | u8 card[32]; | 55 | u8 card[32]; |
56 | u8 bus_info[32]; | 56 | u8 bus_info[32]; |
57 | struct v4l2_ctrl_handler ctrl_handler; | ||
58 | int (*ext_init)(struct snd_tea575x *tea); | ||
57 | }; | 59 | }; |
58 | 60 | ||
59 | int snd_tea575x_init(struct snd_tea575x *tea); | 61 | int snd_tea575x_init(struct snd_tea575x *tea); |
diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c index 4831800239d3..0d7a659c494c 100644 --- a/sound/i2c/other/tea575x-tuner.c +++ b/sound/i2c/other/tea575x-tuner.c | |||
@@ -22,11 +22,11 @@ | |||
22 | 22 | ||
23 | #include <asm/io.h> | 23 | #include <asm/io.h> |
24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
25 | #include <linux/interrupt.h> | ||
26 | #include <linux/init.h> | 25 | #include <linux/init.h> |
27 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
28 | #include <linux/version.h> | 27 | #include <linux/version.h> |
29 | #include <sound/core.h> | 28 | #include <media/v4l2-dev.h> |
29 | #include <media/v4l2-ioctl.h> | ||
30 | #include <sound/tea575x-tuner.h> | 30 | #include <sound/tea575x-tuner.h> |
31 | 31 | ||
32 | MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); | 32 | MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); |
@@ -62,17 +62,6 @@ module_param(radio_nr, int, 0); | |||
62 | #define TEA575X_BIT_DUMMY (1<<15) /* buffer */ | 62 | #define TEA575X_BIT_DUMMY (1<<15) /* buffer */ |
63 | #define TEA575X_BIT_FREQ_MASK 0x7fff | 63 | #define TEA575X_BIT_FREQ_MASK 0x7fff |
64 | 64 | ||
65 | static struct v4l2_queryctrl radio_qctrl[] = { | ||
66 | { | ||
67 | .id = V4L2_CID_AUDIO_MUTE, | ||
68 | .name = "Mute", | ||
69 | .minimum = 0, | ||
70 | .maximum = 1, | ||
71 | .default_value = 1, | ||
72 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
73 | } | ||
74 | }; | ||
75 | |||
76 | /* | 65 | /* |
77 | * lowlevel part | 66 | * lowlevel part |
78 | */ | 67 | */ |
@@ -266,47 +255,17 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
266 | return 0; | 255 | return 0; |
267 | } | 256 | } |
268 | 257 | ||
269 | static int vidioc_queryctrl(struct file *file, void *priv, | 258 | static int tea575x_s_ctrl(struct v4l2_ctrl *ctrl) |
270 | struct v4l2_queryctrl *qc) | ||
271 | { | 259 | { |
272 | int i; | 260 | struct snd_tea575x *tea = container_of(ctrl->handler, struct snd_tea575x, ctrl_handler); |
273 | |||
274 | for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { | ||
275 | if (qc->id && qc->id == radio_qctrl[i].id) { | ||
276 | memcpy(qc, &(radio_qctrl[i]), | ||
277 | sizeof(*qc)); | ||
278 | return 0; | ||
279 | } | ||
280 | } | ||
281 | return -EINVAL; | ||
282 | } | ||
283 | |||
284 | static int vidioc_g_ctrl(struct file *file, void *priv, | ||
285 | struct v4l2_control *ctrl) | ||
286 | { | ||
287 | struct snd_tea575x *tea = video_drvdata(file); | ||
288 | 261 | ||
289 | switch (ctrl->id) { | 262 | switch (ctrl->id) { |
290 | case V4L2_CID_AUDIO_MUTE: | 263 | case V4L2_CID_AUDIO_MUTE: |
291 | ctrl->value = tea->mute; | 264 | tea->mute = ctrl->val; |
265 | snd_tea575x_set_freq(tea); | ||
292 | return 0; | 266 | return 0; |
293 | } | 267 | } |
294 | return -EINVAL; | ||
295 | } | ||
296 | 268 | ||
297 | static int vidioc_s_ctrl(struct file *file, void *priv, | ||
298 | struct v4l2_control *ctrl) | ||
299 | { | ||
300 | struct snd_tea575x *tea = video_drvdata(file); | ||
301 | |||
302 | switch (ctrl->id) { | ||
303 | case V4L2_CID_AUDIO_MUTE: | ||
304 | if (tea->mute != ctrl->value) { | ||
305 | tea->mute = ctrl->value; | ||
306 | snd_tea575x_set_freq(tea); | ||
307 | } | ||
308 | return 0; | ||
309 | } | ||
310 | return -EINVAL; | 269 | return -EINVAL; |
311 | } | 270 | } |
312 | 271 | ||
@@ -355,16 +314,17 @@ static const struct v4l2_ioctl_ops tea575x_ioctl_ops = { | |||
355 | .vidioc_s_input = vidioc_s_input, | 314 | .vidioc_s_input = vidioc_s_input, |
356 | .vidioc_g_frequency = vidioc_g_frequency, | 315 | .vidioc_g_frequency = vidioc_g_frequency, |
357 | .vidioc_s_frequency = vidioc_s_frequency, | 316 | .vidioc_s_frequency = vidioc_s_frequency, |
358 | .vidioc_queryctrl = vidioc_queryctrl, | ||
359 | .vidioc_g_ctrl = vidioc_g_ctrl, | ||
360 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
361 | }; | 317 | }; |
362 | 318 | ||
363 | static struct video_device tea575x_radio = { | 319 | static struct video_device tea575x_radio = { |
364 | .name = "tea575x-tuner", | 320 | .name = "tea575x-tuner", |
365 | .fops = &tea575x_fops, | 321 | .fops = &tea575x_fops, |
366 | .ioctl_ops = &tea575x_ioctl_ops, | 322 | .ioctl_ops = &tea575x_ioctl_ops, |
367 | .release = video_device_release, | 323 | .release = video_device_release_empty, |
324 | }; | ||
325 | |||
326 | static const struct v4l2_ctrl_ops tea575x_ctrl_ops = { | ||
327 | .s_ctrl = tea575x_s_ctrl, | ||
368 | }; | 328 | }; |
369 | 329 | ||
370 | /* | 330 | /* |
@@ -373,7 +333,6 @@ static struct video_device tea575x_radio = { | |||
373 | int snd_tea575x_init(struct snd_tea575x *tea) | 333 | int snd_tea575x_init(struct snd_tea575x *tea) |
374 | { | 334 | { |
375 | int retval; | 335 | int retval; |
376 | struct video_device *tea575x_radio_inst; | ||
377 | 336 | ||
378 | tea->mute = 1; | 337 | tea->mute = 1; |
379 | 338 | ||
@@ -384,40 +343,45 @@ int snd_tea575x_init(struct snd_tea575x *tea) | |||
384 | tea->in_use = 0; | 343 | tea->in_use = 0; |
385 | tea->val = TEA575X_BIT_BAND_FM | TEA575X_BIT_SEARCH_10_40; | 344 | tea->val = TEA575X_BIT_BAND_FM | TEA575X_BIT_SEARCH_10_40; |
386 | tea->freq = 90500 * 16; /* 90.5Mhz default */ | 345 | tea->freq = 90500 * 16; /* 90.5Mhz default */ |
346 | snd_tea575x_set_freq(tea); | ||
387 | 347 | ||
388 | tea575x_radio_inst = video_device_alloc(); | 348 | tea->vd = tea575x_radio; |
389 | if (tea575x_radio_inst == NULL) { | 349 | video_set_drvdata(&tea->vd, tea); |
390 | printk(KERN_ERR "tea575x-tuner: not enough memory\n"); | ||
391 | return -ENOMEM; | ||
392 | } | ||
393 | 350 | ||
394 | memcpy(tea575x_radio_inst, &tea575x_radio, sizeof(tea575x_radio)); | 351 | v4l2_ctrl_handler_init(&tea->ctrl_handler, 1); |
352 | tea->vd.ctrl_handler = &tea->ctrl_handler; | ||
353 | v4l2_ctrl_new_std(&tea->ctrl_handler, &tea575x_ctrl_ops, V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1); | ||
354 | retval = tea->ctrl_handler.error; | ||
355 | if (retval) { | ||
356 | printk(KERN_ERR "tea575x-tuner: can't initialize controls\n"); | ||
357 | v4l2_ctrl_handler_free(&tea->ctrl_handler); | ||
358 | return retval; | ||
359 | } | ||
395 | 360 | ||
396 | strcpy(tea575x_radio.name, tea->tea5759 ? | 361 | if (tea->ext_init) { |
397 | "TEA5759 radio" : "TEA5757 radio"); | 362 | retval = tea->ext_init(tea); |
363 | if (retval) { | ||
364 | v4l2_ctrl_handler_free(&tea->ctrl_handler); | ||
365 | return retval; | ||
366 | } | ||
367 | } | ||
398 | 368 | ||
399 | video_set_drvdata(tea575x_radio_inst, tea); | 369 | v4l2_ctrl_handler_setup(&tea->ctrl_handler); |
400 | 370 | ||
401 | retval = video_register_device(tea575x_radio_inst, | 371 | retval = video_register_device(&tea->vd, VFL_TYPE_RADIO, radio_nr); |
402 | VFL_TYPE_RADIO, radio_nr); | ||
403 | if (retval) { | 372 | if (retval) { |
404 | printk(KERN_ERR "tea575x-tuner: can't register video device!\n"); | 373 | printk(KERN_ERR "tea575x-tuner: can't register video device!\n"); |
405 | kfree(tea575x_radio_inst); | 374 | v4l2_ctrl_handler_free(&tea->ctrl_handler); |
406 | return retval; | 375 | return retval; |
407 | } | 376 | } |
408 | 377 | ||
409 | snd_tea575x_set_freq(tea); | ||
410 | tea->vd = tea575x_radio_inst; | ||
411 | |||
412 | return 0; | 378 | return 0; |
413 | } | 379 | } |
414 | 380 | ||
415 | void snd_tea575x_exit(struct snd_tea575x *tea) | 381 | void snd_tea575x_exit(struct snd_tea575x *tea) |
416 | { | 382 | { |
417 | if (tea->vd) { | 383 | video_unregister_device(&tea->vd); |
418 | video_unregister_device(tea->vd); | 384 | v4l2_ctrl_handler_free(&tea->ctrl_handler); |
419 | tea->vd = NULL; | ||
420 | } | ||
421 | } | 385 | } |
422 | 386 | ||
423 | static int __init alsa_tea575x_module_init(void) | 387 | static int __init alsa_tea575x_module_init(void) |