diff options
Diffstat (limited to 'drivers/media/pci/saa7146/mxb.c')
| -rw-r--r-- | drivers/media/pci/saa7146/mxb.c | 103 |
1 files changed, 51 insertions, 52 deletions
diff --git a/drivers/media/pci/saa7146/mxb.c b/drivers/media/pci/saa7146/mxb.c index 44440c6208df..a14b839098b8 100644 --- a/drivers/media/pci/saa7146/mxb.c +++ b/drivers/media/pci/saa7146/mxb.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* mxb - v4l2 driver for the Multimedia eXtension Board @@ -6,19 +7,6 @@ Visit http://www.themm.net/~mihu/linux/saa7146/mxb.html for further details about this card. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -60,6 +48,7 @@ static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); +#define MXB_STD (V4L2_STD_PAL_BG | V4L2_STD_PAL_I | V4L2_STD_SECAM | V4L2_STD_NTSC) #define MXB_INPUTS 4 enum { TUNER, AUX1, AUX3, AUX3_YC }; @@ -67,11 +56,11 @@ static struct v4l2_input mxb_inputs[MXB_INPUTS] = { { TUNER, "Tuner", V4L2_INPUT_TYPE_TUNER, 0x3f, 0, V4L2_STD_PAL_BG | V4L2_STD_PAL_I, 0, V4L2_IN_CAP_STD }, { AUX1, "AUX1", V4L2_INPUT_TYPE_CAMERA, 0x3f, 0, - V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, + MXB_STD, 0, V4L2_IN_CAP_STD }, { AUX3, "AUX3 Composite", V4L2_INPUT_TYPE_CAMERA, 0x3f, 0, - V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, + MXB_STD, 0, V4L2_IN_CAP_STD }, { AUX3_YC, "AUX3 S-Video", V4L2_INPUT_TYPE_CAMERA, 0x3f, 0, - V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, + MXB_STD, 0, V4L2_IN_CAP_STD }, }; /* this array holds the information, which port of the saa7146 each @@ -352,7 +341,7 @@ static int mxb_init_done(struct saa7146_dev* dev) struct tuner_setup tun_setup; v4l2_std_id std = V4L2_STD_PAL_BG; - int i = 0, err = 0; + int i, err = 0; /* mute audio on tea6420s */ tea6420_route(mxb, 6); @@ -361,7 +350,6 @@ static int mxb_init_done(struct saa7146_dev* dev) saa7111a_call(mxb, video, s_std, std); /* select tuner-output on saa7111a */ - i = 0; saa7111a_call(mxb, video, s_routing, SAA7115_COMPOSITE0, SAA7111_FMT_CCIR, 0); @@ -399,7 +387,7 @@ static int mxb_init_done(struct saa7146_dev* dev) /* check if the saa7740 (aka 'sound arena module') is present on the mxb. if so, we must initialize it. due to lack of - informations about the saa7740, the values were reverse + information about the saa7740, the values were reverse engineered. */ msg.addr = 0x1b; msg.flags = 0; @@ -469,7 +457,7 @@ static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) static int vidioc_g_input(struct file *file, void *fh, unsigned int *i) { - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; + struct saa7146_dev *dev = video_drvdata(file); struct mxb *mxb = (struct mxb *)dev->ext_priv; *i = mxb->cur_input; @@ -479,7 +467,7 @@ static int vidioc_g_input(struct file *file, void *fh, unsigned int *i) static int vidioc_s_input(struct file *file, void *fh, unsigned int input) { - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; + struct saa7146_dev *dev = video_drvdata(file); struct mxb *mxb = (struct mxb *)dev->ext_priv; int err = 0; int i = 0; @@ -495,7 +483,7 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input) input_port_selection[input].hps_sync); /* prepare switching of tea6415c and saa7111a; - have a look at the 'background'-file for further informations */ + have a look at the 'background'-file for further information */ switch (input) { case TUNER: i = SAA7115_COMPOSITE0; @@ -525,6 +513,9 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input) if (err) return err; + mxb->video_dev.tvnorms = mxb_inputs[input].std; + mxb->vbi_dev.tvnorms = mxb_inputs[input].std; + /* switch video in saa7111a */ if (saa7111a_call(mxb, video, s_routing, i, SAA7111_FMT_CCIR, 0)) pr_err("VIDIOC_S_INPUT: could not address saa7111a\n"); @@ -541,7 +532,7 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input) static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t) { - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; + struct saa7146_dev *dev = video_drvdata(file); struct mxb *mxb = (struct mxb *)dev->ext_priv; if (t->index) { @@ -563,7 +554,7 @@ static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t) static int vidioc_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *t) { - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; + struct saa7146_dev *dev = video_drvdata(file); struct mxb *mxb = (struct mxb *)dev->ext_priv; if (t->index) { @@ -578,14 +569,14 @@ static int vidioc_s_tuner(struct file *file, void *fh, const struct v4l2_tuner * static int vidioc_querystd(struct file *file, void *fh, v4l2_std_id *norm) { - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; + struct saa7146_dev *dev = video_drvdata(file); return call_all(dev, video, querystd, norm); } static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *f) { - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; + struct saa7146_dev *dev = video_drvdata(file); struct mxb *mxb = (struct mxb *)dev->ext_priv; if (f->tuner) @@ -598,9 +589,8 @@ static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency static int vidioc_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *f) { - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; + struct saa7146_dev *dev = video_drvdata(file); struct mxb *mxb = (struct mxb *)dev->ext_priv; - struct saa7146_vv *vv = dev->vv_data; if (f->tuner) return -EINVAL; @@ -617,15 +607,6 @@ static int vidioc_s_frequency(struct file *file, void *fh, const struct v4l2_fre tuner_call(mxb, tuner, g_frequency, &mxb->cur_freq); if (mxb->cur_audinput == 0) mxb_update_audmode(mxb); - - if (mxb->cur_input) - return 0; - - /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */ - spin_lock(&dev->slock); - vv->vbi_fieldcount = 0; - spin_unlock(&dev->slock); - return 0; } @@ -639,7 +620,7 @@ static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a) static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a) { - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; + struct saa7146_dev *dev = video_drvdata(file); struct mxb *mxb = (struct mxb *)dev->ext_priv; DEB_EE("VIDIOC_G_AUDIO\n"); @@ -649,26 +630,27 @@ static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a) static int vidioc_s_audio(struct file *file, void *fh, const struct v4l2_audio *a) { - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; + struct saa7146_dev *dev = video_drvdata(file); struct mxb *mxb = (struct mxb *)dev->ext_priv; DEB_D("VIDIOC_S_AUDIO %d\n", a->index); - if (mxb_inputs[mxb->cur_input].audioset & (1 << a->index)) { - if (mxb->cur_audinput != a->index) { - mxb->cur_audinput = a->index; - tea6420_route(mxb, a->index); - if (mxb->cur_audinput == 0) - mxb_update_audmode(mxb); - } - return 0; + if (a->index >= 32 || + !(mxb_inputs[mxb->cur_input].audioset & (1 << a->index))) + return -EINVAL; + + if (mxb->cur_audinput != a->index) { + mxb->cur_audinput = a->index; + tea6420_route(mxb, a->index); + if (mxb->cur_audinput == 0) + mxb_update_audmode(mxb); } - return -EINVAL; + return 0; } #ifdef CONFIG_VIDEO_ADV_DEBUG static int vidioc_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg) { - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; + struct saa7146_dev *dev = video_drvdata(file); if (reg->reg > pci_resource_len(dev->pci, 0) - 4) return -EINVAL; @@ -679,7 +661,7 @@ static int vidioc_g_register(struct file *file, void *fh, struct v4l2_dbg_regist static int vidioc_s_register(struct file *file, void *fh, const struct v4l2_dbg_register *reg) { - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; + struct saa7146_dev *dev = video_drvdata(file); if (reg->reg > pci_resource_len(dev->pci, 0) - 4) return -EINVAL; @@ -694,10 +676,16 @@ static struct saa7146_ext_vv vv_data; static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info) { struct mxb *mxb; + int ret; DEB_EE("dev:%p\n", dev); - saa7146_vv_init(dev, &vv_data); + ret = saa7146_vv_init(dev, &vv_data); + if (ret) { + ERR("Error in saa7146_vv_init()"); + return ret; + } + if (mxb_probe(dev)) { saa7146_vv_release(dev); return -1; @@ -719,7 +707,18 @@ static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data vv_data.vid_ops.vidioc_g_register = vidioc_g_register; vv_data.vid_ops.vidioc_s_register = vidioc_s_register; #endif - if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) { + vv_data.vbi_ops.vidioc_enum_input = vidioc_enum_input; + vv_data.vbi_ops.vidioc_g_input = vidioc_g_input; + vv_data.vbi_ops.vidioc_s_input = vidioc_s_input; + vv_data.vbi_ops.vidioc_querystd = vidioc_querystd; + vv_data.vbi_ops.vidioc_g_tuner = vidioc_g_tuner; + vv_data.vbi_ops.vidioc_s_tuner = vidioc_s_tuner; + vv_data.vbi_ops.vidioc_g_frequency = vidioc_g_frequency; + vv_data.vbi_ops.vidioc_s_frequency = vidioc_s_frequency; + vv_data.vbi_ops.vidioc_enumaudio = vidioc_enumaudio; + vv_data.vbi_ops.vidioc_g_audio = vidioc_g_audio; + vv_data.vbi_ops.vidioc_s_audio = vidioc_s_audio; + if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_VIDEO)) { ERR("cannot register capture v4l2 device. skipping.\n"); saa7146_vv_release(dev); return -1; |
