aboutsummaryrefslogtreecommitdiffstats
path: root/sound/i2c
diff options
context:
space:
mode:
authorOndrej Zary <linux@rainbow-software.org>2011-05-23 08:17:19 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-07-27 16:52:20 -0400
commit4522e825dbfc19537a08f65719dc3d69c46fe661 (patch)
tree174e008ad224d01104f92e4e247431c749c91d6a /sound/i2c
parent2ef403708880c6e00854fb81bbffb9a4036327e6 (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.c106
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
32MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); 32MODULE_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
65static 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
269static int vidioc_queryctrl(struct file *file, void *priv, 258static 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
284static 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
297static 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
363static struct video_device tea575x_radio = { 319static 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
326static 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 = {
373int snd_tea575x_init(struct snd_tea575x *tea) 333int 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
415void snd_tea575x_exit(struct snd_tea575x *tea) 381void 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
423static int __init alsa_tea575x_module_init(void) 387static int __init alsa_tea575x_module_init(void)