Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Ondrej Zary and committed by
Mauro Carvalho Chehab
4522e825 2ef40370

+42 -76
+4 -2
include/sound/tea575x-tuner.h
··· 23 23 */ 24 24 25 25 #include <linux/videodev2.h> 26 + #include <media/v4l2-ctrls.h> 26 27 #include <media/v4l2-dev.h> 27 - #include <media/v4l2-ioctl.h> 28 28 29 29 #define TEA575X_FMIF 10700 30 30 ··· 42 42 }; 43 43 44 44 struct snd_tea575x { 45 - struct video_device *vd; /* video device */ 45 + struct video_device vd; /* video device */ 46 46 bool tea5759; /* 5759 chip is present */ 47 47 bool mute; /* Device is muted? */ 48 48 bool stereo; /* receiving stereo */ ··· 54 54 void *private_data; 55 55 u8 card[32]; 56 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 61 int snd_tea575x_init(struct snd_tea575x *tea);
+38 -74
sound/i2c/other/tea575x-tuner.c
··· 22 22 23 23 #include <asm/io.h> 24 24 #include <linux/delay.h> 25 - #include <linux/interrupt.h> 26 25 #include <linux/init.h> 27 26 #include <linux/slab.h> 28 27 #include <linux/version.h> 29 - #include <sound/core.h> 28 + #include <media/v4l2-dev.h> 29 + #include <media/v4l2-ioctl.h> 30 30 #include <sound/tea575x-tuner.h> 31 31 32 32 MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); ··· 61 61 #define TEA575X_BIT_SEARCH_150_1000 (3<<16) /* FM > 150uV, AM > 1000uV */ 62 62 #define TEA575X_BIT_DUMMY (1<<15) /* buffer */ 63 63 #define TEA575X_BIT_FREQ_MASK 0x7fff 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 64 76 65 /* 77 66 * lowlevel part ··· 255 266 return 0; 256 267 } 257 268 258 - static int vidioc_queryctrl(struct file *file, void *priv, 259 - struct v4l2_queryctrl *qc) 269 + static int tea575x_s_ctrl(struct v4l2_ctrl *ctrl) 260 270 { 261 - int i; 262 - 263 - for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { 264 - if (qc->id && qc->id == radio_qctrl[i].id) { 265 - memcpy(qc, &(radio_qctrl[i]), 266 - sizeof(*qc)); 267 - return 0; 268 - } 269 - } 270 - return -EINVAL; 271 - } 272 - 273 - static int vidioc_g_ctrl(struct file *file, void *priv, 274 - struct v4l2_control *ctrl) 275 - { 276 - struct snd_tea575x *tea = video_drvdata(file); 271 + struct snd_tea575x *tea = container_of(ctrl->handler, struct snd_tea575x, ctrl_handler); 277 272 278 273 switch (ctrl->id) { 279 274 case V4L2_CID_AUDIO_MUTE: 280 - ctrl->value = tea->mute; 275 + tea->mute = ctrl->val; 276 + snd_tea575x_set_freq(tea); 281 277 return 0; 282 278 } 283 - return -EINVAL; 284 - } 285 279 286 - static int vidioc_s_ctrl(struct file *file, void *priv, 287 - struct v4l2_control *ctrl) 288 - { 289 - struct snd_tea575x *tea = video_drvdata(file); 290 - 291 - switch (ctrl->id) { 292 - case V4L2_CID_AUDIO_MUTE: 293 - if (tea->mute != ctrl->value) { 294 - tea->mute = ctrl->value; 295 - snd_tea575x_set_freq(tea); 296 - } 297 - return 0; 298 - } 299 280 return -EINVAL; 300 281 } 301 282 ··· 314 355 .vidioc_s_input = vidioc_s_input, 315 356 .vidioc_g_frequency = vidioc_g_frequency, 316 357 .vidioc_s_frequency = vidioc_s_frequency, 317 - .vidioc_queryctrl = vidioc_queryctrl, 318 - .vidioc_g_ctrl = vidioc_g_ctrl, 319 - .vidioc_s_ctrl = vidioc_s_ctrl, 320 358 }; 321 359 322 360 static struct video_device tea575x_radio = { 323 361 .name = "tea575x-tuner", 324 362 .fops = &tea575x_fops, 325 363 .ioctl_ops = &tea575x_ioctl_ops, 326 - .release = video_device_release, 364 + .release = video_device_release_empty, 365 + }; 366 + 367 + static const struct v4l2_ctrl_ops tea575x_ctrl_ops = { 368 + .s_ctrl = tea575x_s_ctrl, 327 369 }; 328 370 329 371 /* ··· 333 373 int snd_tea575x_init(struct snd_tea575x *tea) 334 374 { 335 375 int retval; 336 - struct video_device *tea575x_radio_inst; 337 376 338 377 tea->mute = 1; 339 378 ··· 343 384 tea->in_use = 0; 344 385 tea->val = TEA575X_BIT_BAND_FM | TEA575X_BIT_SEARCH_10_40; 345 386 tea->freq = 90500 * 16; /* 90.5Mhz default */ 387 + snd_tea575x_set_freq(tea); 346 388 347 - tea575x_radio_inst = video_device_alloc(); 348 - if (tea575x_radio_inst == NULL) { 349 - printk(KERN_ERR "tea575x-tuner: not enough memory\n"); 350 - return -ENOMEM; 351 - } 389 + tea->vd = tea575x_radio; 390 + video_set_drvdata(&tea->vd, tea); 352 391 353 - memcpy(tea575x_radio_inst, &tea575x_radio, sizeof(tea575x_radio)); 354 - 355 - strcpy(tea575x_radio.name, tea->tea5759 ? 356 - "TEA5759 radio" : "TEA5757 radio"); 357 - 358 - video_set_drvdata(tea575x_radio_inst, tea); 359 - 360 - retval = video_register_device(tea575x_radio_inst, 361 - VFL_TYPE_RADIO, radio_nr); 392 + v4l2_ctrl_handler_init(&tea->ctrl_handler, 1); 393 + tea->vd.ctrl_handler = &tea->ctrl_handler; 394 + v4l2_ctrl_new_std(&tea->ctrl_handler, &tea575x_ctrl_ops, V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1); 395 + retval = tea->ctrl_handler.error; 362 396 if (retval) { 363 - printk(KERN_ERR "tea575x-tuner: can't register video device!\n"); 364 - kfree(tea575x_radio_inst); 397 + printk(KERN_ERR "tea575x-tuner: can't initialize controls\n"); 398 + v4l2_ctrl_handler_free(&tea->ctrl_handler); 365 399 return retval; 366 400 } 367 401 368 - snd_tea575x_set_freq(tea); 369 - tea->vd = tea575x_radio_inst; 402 + if (tea->ext_init) { 403 + retval = tea->ext_init(tea); 404 + if (retval) { 405 + v4l2_ctrl_handler_free(&tea->ctrl_handler); 406 + return retval; 407 + } 408 + } 409 + 410 + v4l2_ctrl_handler_setup(&tea->ctrl_handler); 411 + 412 + retval = video_register_device(&tea->vd, VFL_TYPE_RADIO, radio_nr); 413 + if (retval) { 414 + printk(KERN_ERR "tea575x-tuner: can't register video device!\n"); 415 + v4l2_ctrl_handler_free(&tea->ctrl_handler); 416 + return retval; 417 + } 370 418 371 419 return 0; 372 420 } 373 421 374 422 void snd_tea575x_exit(struct snd_tea575x *tea) 375 423 { 376 - if (tea->vd) { 377 - video_unregister_device(tea->vd); 378 - tea->vd = NULL; 379 - } 424 + video_unregister_device(&tea->vd); 425 + v4l2_ctrl_handler_free(&tea->ctrl_handler); 380 426 } 381 427 382 428 static int __init alsa_tea575x_module_init(void)