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 /sound/i2c | |
| 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>
Diffstat (limited to 'sound/i2c')
| -rw-r--r-- | sound/i2c/other/tea575x-tuner.c | 106 |
1 files changed, 35 insertions, 71 deletions
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) |
