aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2012-04-29 15:47:47 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-05-14 13:54:58 -0400
commit6e65ca942b9664a987866ac0c62e7e450777056b (patch)
treefcd78f02819a1d3d0559ab51a8bb87412d911783 /drivers/media/video
parent5becbc58a01f1adaf34703c18287d9f7b46a17f6 (diff)
[media] mxb/saa7146: first round of cleanups
Convert to the control framework, fix the easy v4l2-compliance failures. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video')
-rw-r--r--drivers/media/video/mxb.c173
-rw-r--r--drivers/media/video/mxb.h29
2 files changed, 85 insertions, 117 deletions
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c
index ca3f70f0bad5..2bed92ff9476 100644
--- a/drivers/media/video/mxb.c
+++ b/drivers/media/video/mxb.c
@@ -64,8 +64,8 @@ enum { TUNER, AUX1, AUX3, AUX3_YC };
64static struct v4l2_input mxb_inputs[MXB_INPUTS] = { 64static struct v4l2_input mxb_inputs[MXB_INPUTS] = {
65 { TUNER, "Tuner", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, 65 { TUNER, "Tuner", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
66 { AUX1, "AUX1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, 66 { AUX1, "AUX1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
67 { AUX3, "AUX3 Composite", V4L2_INPUT_TYPE_CAMERA, 4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, 67 { AUX3, "AUX3 Composite", V4L2_INPUT_TYPE_CAMERA, 8, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
68 { AUX3_YC, "AUX3 S-Video", V4L2_INPUT_TYPE_CAMERA, 4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, 68 { AUX3_YC, "AUX3 S-Video", V4L2_INPUT_TYPE_CAMERA, 8, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
69}; 69};
70 70
71/* this array holds the information, which port of the saa7146 each 71/* this array holds the information, which port of the saa7146 each
@@ -90,6 +90,36 @@ struct mxb_routing {
90 u32 output; 90 u32 output;
91}; 91};
92 92
93/* these are the available audio sources, which can switched
94 to the line- and cd-output individually */
95static struct v4l2_audio mxb_audios[MXB_AUDIOS] = {
96 {
97 .index = 0,
98 .name = "Tuner",
99 .capability = V4L2_AUDCAP_STEREO,
100 } , {
101 .index = 1,
102 .name = "AUX1",
103 .capability = V4L2_AUDCAP_STEREO,
104 } , {
105 .index = 2,
106 .name = "AUX2",
107 .capability = V4L2_AUDCAP_STEREO,
108 } , {
109 .index = 3,
110 .name = "AUX3",
111 .capability = V4L2_AUDCAP_STEREO,
112 } , {
113 .index = 4,
114 .name = "Radio (X9)",
115 .capability = V4L2_AUDCAP_STEREO,
116 } , {
117 .index = 5,
118 .name = "CD-ROM (X10)",
119 .capability = V4L2_AUDCAP_STEREO,
120 }
121};
122
93/* These are the necessary input-output-pins for bringing one audio source 123/* These are the necessary input-output-pins for bringing one audio source
94 (see above) to the CD-output. Note that gain is set to 0 in this table. */ 124 (see above) to the CD-output. Note that gain is set to 0 in this table. */
95static struct mxb_routing TEA6420_cd[MXB_AUDIOS + 1][2] = { 125static struct mxb_routing TEA6420_cd[MXB_AUDIOS + 1][2] = {
@@ -114,11 +144,6 @@ static struct mxb_routing TEA6420_line[MXB_AUDIOS + 1][2] = {
114 { { 6, 3 }, { 6, 2 } } /* Mute */ 144 { { 6, 3 }, { 6, 2 } } /* Mute */
115}; 145};
116 146
117#define MAXCONTROLS 1
118static struct v4l2_queryctrl mxb_controls[] = {
119 { V4L2_CID_AUDIO_MUTE, V4L2_CTRL_TYPE_BOOLEAN, "Mute", 0, 1, 1, 0, 0 },
120};
121
122struct mxb 147struct mxb
123{ 148{
124 struct video_device *video_dev; 149 struct video_device *video_dev;
@@ -168,16 +193,45 @@ static inline void tea6420_route_line(struct mxb *mxb, int idx)
168 193
169static struct saa7146_extension extension; 194static struct saa7146_extension extension;
170 195
196static int mxb_s_ctrl(struct v4l2_ctrl *ctrl)
197{
198 struct saa7146_dev *dev = container_of(ctrl->handler,
199 struct saa7146_dev, ctrl_handler);
200 struct mxb *mxb = dev->ext_priv;
201
202 switch (ctrl->id) {
203 case V4L2_CID_AUDIO_MUTE:
204 mxb->cur_mute = ctrl->val;
205 /* switch the audio-source */
206 tea6420_route_line(mxb, ctrl->val ? 6 :
207 video_audio_connect[mxb->cur_input]);
208 break;
209 default:
210 return -EINVAL;
211 }
212 return 0;
213}
214
215static const struct v4l2_ctrl_ops mxb_ctrl_ops = {
216 .s_ctrl = mxb_s_ctrl,
217};
218
171static int mxb_probe(struct saa7146_dev *dev) 219static int mxb_probe(struct saa7146_dev *dev)
172{ 220{
221 struct v4l2_ctrl_handler *hdl = &dev->ctrl_handler;
173 struct mxb *mxb = NULL; 222 struct mxb *mxb = NULL;
174 223
224 v4l2_ctrl_new_std(hdl, &mxb_ctrl_ops,
225 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
226 if (hdl->error)
227 return hdl->error;
175 mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL); 228 mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL);
176 if (mxb == NULL) { 229 if (mxb == NULL) {
177 DEB_D("not enough kernel memory\n"); 230 DEB_D("not enough kernel memory\n");
178 return -ENOMEM; 231 return -ENOMEM;
179 } 232 }
180 233
234
181 snprintf(mxb->i2c_adapter.name, sizeof(mxb->i2c_adapter.name), "mxb%d", mxb_num); 235 snprintf(mxb->i2c_adapter.name, sizeof(mxb->i2c_adapter.name), "mxb%d", mxb_num);
182 236
183 saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480); 237 saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
@@ -385,69 +439,6 @@ void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask)
385} 439}
386*/ 440*/
387 441
388static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qc)
389{
390 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
391 int i;
392
393 for (i = MAXCONTROLS - 1; i >= 0; i--) {
394 if (mxb_controls[i].id == qc->id) {
395 *qc = mxb_controls[i];
396 DEB_D("VIDIOC_QUERYCTRL %d\n", qc->id);
397 return 0;
398 }
399 }
400 return dev->ext_vv_data->core_ops->vidioc_queryctrl(file, fh, qc);
401}
402
403static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
404{
405 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
406 struct mxb *mxb = (struct mxb *)dev->ext_priv;
407 int i;
408
409 for (i = MAXCONTROLS - 1; i >= 0; i--) {
410 if (mxb_controls[i].id == vc->id)
411 break;
412 }
413
414 if (i < 0)
415 return dev->ext_vv_data->core_ops->vidioc_g_ctrl(file, fh, vc);
416
417 if (vc->id == V4L2_CID_AUDIO_MUTE) {
418 vc->value = mxb->cur_mute;
419 DEB_D("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d\n", vc->value);
420 return 0;
421 }
422
423 DEB_EE("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d\n", vc->value);
424 return 0;
425}
426
427static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
428{
429 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
430 struct mxb *mxb = (struct mxb *)dev->ext_priv;
431 int i = 0;
432
433 for (i = MAXCONTROLS - 1; i >= 0; i--) {
434 if (mxb_controls[i].id == vc->id)
435 break;
436 }
437
438 if (i < 0)
439 return dev->ext_vv_data->core_ops->vidioc_s_ctrl(file, fh, vc);
440
441 if (vc->id == V4L2_CID_AUDIO_MUTE) {
442 mxb->cur_mute = vc->value;
443 /* switch the audio-source */
444 tea6420_route_line(mxb, vc->value ? 6 :
445 video_audio_connect[mxb->cur_input]);
446 DEB_EE("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d\n", vc->value);
447 }
448 return 0;
449}
450
451static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) 442static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
452{ 443{
453 DEB_EE("VIDIOC_ENUMINPUT %d\n", i->index); 444 DEB_EE("VIDIOC_ENUMINPUT %d\n", i->index);
@@ -568,12 +559,8 @@ static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency
568 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 559 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
569 struct mxb *mxb = (struct mxb *)dev->ext_priv; 560 struct mxb *mxb = (struct mxb *)dev->ext_priv;
570 561
571 if (mxb->cur_input) { 562 if (f->tuner)
572 DEB_D("VIDIOC_G_FREQ: channel %d does not have a tuner!\n",
573 mxb->cur_input);
574 return -EINVAL; 563 return -EINVAL;
575 }
576
577 *f = mxb->cur_freq; 564 *f = mxb->cur_freq;
578 565
579 DEB_EE("VIDIOC_G_FREQ: freq:0x%08x\n", mxb->cur_freq.frequency); 566 DEB_EE("VIDIOC_G_FREQ: freq:0x%08x\n", mxb->cur_freq.frequency);
@@ -592,17 +579,16 @@ static int vidioc_s_frequency(struct file *file, void *fh, struct v4l2_frequency
592 if (V4L2_TUNER_ANALOG_TV != f->type) 579 if (V4L2_TUNER_ANALOG_TV != f->type)
593 return -EINVAL; 580 return -EINVAL;
594 581
595 if (mxb->cur_input) {
596 DEB_D("VIDIOC_S_FREQ: channel %d does not have a tuner!\n",
597 mxb->cur_input);
598 return -EINVAL;
599 }
600
601 mxb->cur_freq = *f;
602 DEB_EE("VIDIOC_S_FREQUENCY: freq:0x%08x\n", mxb->cur_freq.frequency); 582 DEB_EE("VIDIOC_S_FREQUENCY: freq:0x%08x\n", mxb->cur_freq.frequency);
603 583
604 /* tune in desired frequency */ 584 /* tune in desired frequency */
605 tuner_call(mxb, tuner, s_frequency, &mxb->cur_freq); 585 tuner_call(mxb, tuner, s_frequency, f);
586 /* let the tuner subdev clamp the frequency to the tuner range */
587 tuner_call(mxb, tuner, g_frequency, f);
588 mxb->cur_freq = *f;
589
590 if (mxb->cur_input)
591 return 0;
606 592
607 /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */ 593 /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
608 spin_lock(&dev->slock); 594 spin_lock(&dev->slock);
@@ -612,6 +598,14 @@ static int vidioc_s_frequency(struct file *file, void *fh, struct v4l2_frequency
612 return 0; 598 return 0;
613} 599}
614 600
601static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a)
602{
603 if (a->index >= MXB_AUDIOS)
604 return -EINVAL;
605 *a = mxb_audios[a->index];
606 return 0;
607}
608
615static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a) 609static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
616{ 610{
617 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 611 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
@@ -629,8 +623,13 @@ static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
629 623
630static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a) 624static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
631{ 625{
626 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
627 struct mxb *mxb = (struct mxb *)dev->ext_priv;
628
632 DEB_D("VIDIOC_S_AUDIO %d\n", a->index); 629 DEB_D("VIDIOC_S_AUDIO %d\n", a->index);
633 return 0; 630 if (mxb_inputs[mxb->cur_input].audioset & (1 << a->index))
631 return 0;
632 return -EINVAL;
634} 633}
635 634
636#ifdef CONFIG_VIDEO_ADV_DEBUG 635#ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -709,9 +708,6 @@ static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data
709 } 708 }
710 mxb = (struct mxb *)dev->ext_priv; 709 mxb = (struct mxb *)dev->ext_priv;
711 710
712 vv_data.ops.vidioc_queryctrl = vidioc_queryctrl;
713 vv_data.ops.vidioc_g_ctrl = vidioc_g_ctrl;
714 vv_data.ops.vidioc_s_ctrl = vidioc_s_ctrl;
715 vv_data.ops.vidioc_enum_input = vidioc_enum_input; 711 vv_data.ops.vidioc_enum_input = vidioc_enum_input;
716 vv_data.ops.vidioc_g_input = vidioc_g_input; 712 vv_data.ops.vidioc_g_input = vidioc_g_input;
717 vv_data.ops.vidioc_s_input = vidioc_s_input; 713 vv_data.ops.vidioc_s_input = vidioc_s_input;
@@ -719,6 +715,7 @@ static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data
719 vv_data.ops.vidioc_s_tuner = vidioc_s_tuner; 715 vv_data.ops.vidioc_s_tuner = vidioc_s_tuner;
720 vv_data.ops.vidioc_g_frequency = vidioc_g_frequency; 716 vv_data.ops.vidioc_g_frequency = vidioc_g_frequency;
721 vv_data.ops.vidioc_s_frequency = vidioc_s_frequency; 717 vv_data.ops.vidioc_s_frequency = vidioc_s_frequency;
718 vv_data.ops.vidioc_enumaudio = vidioc_enumaudio;
722 vv_data.ops.vidioc_g_audio = vidioc_g_audio; 719 vv_data.ops.vidioc_g_audio = vidioc_g_audio;
723 vv_data.ops.vidioc_s_audio = vidioc_s_audio; 720 vv_data.ops.vidioc_s_audio = vidioc_s_audio;
724#ifdef CONFIG_VIDEO_ADV_DEBUG 721#ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -836,7 +833,7 @@ MODULE_DEVICE_TABLE(pci, pci_tbl);
836 833
837static struct saa7146_ext_vv vv_data = { 834static struct saa7146_ext_vv vv_data = {
838 .inputs = MXB_INPUTS, 835 .inputs = MXB_INPUTS,
839 .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE, 836 .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_AUDIO,
840 .stds = &standard[0], 837 .stds = &standard[0],
841 .num_stds = sizeof(standard)/sizeof(struct saa7146_standard), 838 .num_stds = sizeof(standard)/sizeof(struct saa7146_standard),
842 .std_callback = &std_callback, 839 .std_callback = &std_callback,
diff --git a/drivers/media/video/mxb.h b/drivers/media/video/mxb.h
index 400a57ba62ec..dfa4b1cca23a 100644
--- a/drivers/media/video/mxb.h
+++ b/drivers/media/video/mxb.h
@@ -10,33 +10,4 @@
10 10
11#define MXB_AUDIOS 6 11#define MXB_AUDIOS 6
12 12
13/* these are the available audio sources, which can switched
14 to the line- and cd-output individually */
15static struct v4l2_audio mxb_audios[MXB_AUDIOS] = {
16 {
17 .index = 0,
18 .name = "Tuner",
19 .capability = V4L2_AUDCAP_STEREO,
20 } , {
21 .index = 1,
22 .name = "AUX1",
23 .capability = V4L2_AUDCAP_STEREO,
24 } , {
25 .index = 2,
26 .name = "AUX2",
27 .capability = V4L2_AUDCAP_STEREO,
28 } , {
29 .index = 3,
30 .name = "AUX3",
31 .capability = V4L2_AUDCAP_STEREO,
32 } , {
33 .index = 4,
34 .name = "Radio (X9)",
35 .capability = V4L2_AUDCAP_STEREO,
36 } , {
37 .index = 5,
38 .name = "CD-ROM (X10)",
39 .capability = V4L2_AUDCAP_STEREO,
40 }
41};
42#endif 13#endif