* [PATCH] New driver for the radio FM module on Miro PCM20 sound card
@ 2009-11-24 21:12 Krzysztof Helt
2009-11-25 9:13 ` Takashi Iwai
2009-11-26 7:58 ` Hans Verkuil
0 siblings, 2 replies; 10+ messages in thread
From: Krzysztof Helt @ 2009-11-24 21:12 UTC (permalink / raw)
To: linux-media; +Cc: Takashi Iwai
From: Krzysztof Helt <krzysztof.h1@wp.pl>
This is recreated driver for the FM module found on Miro
PCM20 sound cards. This driver was removed around the 2.6.2x
kernels because it relied on the removed OSS module. Now, it
uses a current ALSA module (snd-miro) and is adapted to v4l2
layer.
It provides only basic functionality: frequency changing and
FM module muting.
Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl>
---
This driver depends on changes to the snd-miro driver. These changes
are already accepted to the ALSA tree, but these changes
won't be pushed into the 2.6.33 kernel.
drivers/media/radio/Kconfig | 17 ++
drivers/media/radio/Makefile | 1 +
drivers/media/radio/radio-miropcm20.c | 271 +++++++++++++++++++++++++++++++++
3 files changed, 289 insertions(+), 0 deletions(-)
create mode 100644 drivers/media/radio/radio-miropcm20.c
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index a87a477..1c12f99 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -195,6 +195,23 @@ config RADIO_MAESTRO
To compile this driver as a module, choose M here: the
module will be called radio-maestro.
+config RADIO_MIROPCM20
+ tristate "miroSOUND PCM20 radio"
+ depends on ISA && VIDEO_V4L2
+ select SND_MIRO
+ ---help---
+ Choose Y here if you have this FM radio card. You also need to select
+ the "Miro miroSOUND PCM1pro/PCM12/PCM20radio driver" ALSA sound card
+ driver for this to work.
+
+ In order to control your radio card, you will need to use programs
+ that are compatible with the Video For Linux API. Information on
+ this API and pointers to "v4l" programs may be found at
+ <file:Documentation/video4linux/API.html>.
+
+ To compile this driver as a module, choose M here: the
+ module will be called radio-miropcm20.
+
config RADIO_SF16FMI
tristate "SF16FMI Radio"
depends on ISA && VIDEO_V4L2
diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
index 2a1be3b..8a63d54 100644
--- a/drivers/media/radio/Makefile
+++ b/drivers/media/radio/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_RADIO_TRUST) += radio-trust.o
obj-$(CONFIG_I2C_SI4713) += si4713-i2c.o
obj-$(CONFIG_RADIO_SI4713) += radio-si4713.o
obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o
+obj-$(CONFIG_RADIO_MIROPCM20) += radio-miropcm20.o
obj-$(CONFIG_USB_DSBR) += dsbr100.o
obj-$(CONFIG_RADIO_SI470X) += si470x/
obj-$(CONFIG_USB_MR800) += radio-mr800.o
diff --git a/drivers/media/radio/radio-miropcm20.c b/drivers/media/radio/radio-miropcm20.c
new file mode 100644
index 0000000..0b6940c
--- /dev/null
+++ b/drivers/media/radio/radio-miropcm20.c
@@ -0,0 +1,271 @@
+/* Miro PCM20 radio driver for Linux radio support
+ * (c) 1998 Ruurd Reitsma <R.A.Reitsma@wbmt.tudelft.nl>
+ * Thanks to Norberto Pellici for the ACI device interface specification
+ * The API part is based on the radiotrack driver by M. Kirkwood
+ * This driver relies on the aci mixer provided by the snd-miro
+ * ALSA driver.
+ * Look there for further info...
+ */
+
+/* Revision history:
+ *
+ * 1998 Ruurd Reitsma <R.A.Reitsma@wbmt.tudelft.nl>
+ * 2000-09-05 Robert Siemer <Robert.Siemer@gmx.de>
+ * removed unfinished volume control (maybe adding it later again)
+ * use OSS-mixer; added stereo control
+ */
+
+/* What ever you think about the ACI, version 0x07 is not very well!
+ * I can't get frequency, 'tuner status', 'tuner flags' or mute/mono
+ * conditions... Robert
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <sound/aci.h>
+
+static int radio_nr = -1;
+module_param(radio_nr, int, 0);
+
+static int mono;
+module_param(mono, bool, 0);
+MODULE_PARM_DESC(mono, "Force tuner into mono mode.");
+
+struct pcm20 {
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
+ unsigned long freq;
+ int muted;
+ struct snd_miro_aci *aci;
+};
+
+static struct pcm20 pcm20_card = {
+ .freq = 87*16000,
+ .muted = 1,
+};
+
+static int pcm20_mute(struct pcm20 *dev, unsigned char mute)
+{
+ dev->muted = mute;
+ return snd_aci_cmd(dev->aci, ACI_SET_TUNERMUTE, mute, -1);
+}
+
+static int pcm20_stereo(struct pcm20 *dev, unsigned char stereo)
+{
+ return snd_aci_cmd(dev->aci, ACI_SET_TUNERMONO, !stereo, -1);
+}
+
+static int pcm20_setfreq(struct pcm20 *dev, unsigned long freq)
+{
+ unsigned char freql;
+ unsigned char freqh;
+ struct snd_miro_aci *aci = dev->aci;
+
+ dev->freq = freq;
+
+ freq /= 160;
+ if (!(aci->aci_version == 0x07 || aci->aci_version >= 0xb0))
+ freq /= 10; /* I don't know exactly which version
+ * needs this hack */
+ freql = freq & 0xff;
+ freqh = freq >> 8;
+
+ pcm20_stereo(dev, !mono);
+ return snd_aci_cmd(aci, ACI_WRITE_TUNE, freql, freqh);
+}
+
+static const struct v4l2_file_operations pcm20_fops = {
+ .owner = THIS_MODULE,
+ .ioctl = video_ioctl2,
+};
+
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *v)
+{
+ strlcpy(v->driver, "Miro PCM20", sizeof(v->driver));
+ strlcpy(v->card, "Miro PCM20", sizeof(v->card));
+ strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
+ v->version = 0x1;
+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+ return 0;
+}
+
+static int vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ if (v->index) /* Only 1 tuner */
+ return -EINVAL;
+ strlcpy(v->name, "FM", sizeof(v->name));
+ v->type = V4L2_TUNER_RADIO;
+ v->rangelow = 87*16000;
+ v->rangehigh = 108*16000;
+ v->signal = 0xffff;
+ v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
+ v->capability = V4L2_TUNER_CAP_LOW;
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ return 0;
+}
+
+static int vidioc_s_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ return v->index ? -EINVAL : 0;
+}
+
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct pcm20 *dev = video_drvdata(file);
+
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = dev->freq;
+ return 0;
+}
+
+
+static int vidioc_s_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct pcm20 *dev = video_drvdata(file);
+
+ dev->freq = f->frequency;
+ pcm20_setfreq(dev, f->frequency);
+ return 0;
+}
+
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ switch (qc->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+ }
+ return -EINVAL;
+}
+
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct pcm20 *dev = video_drvdata(file);
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = dev->muted;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct pcm20 *dev = video_drvdata(file);
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ pcm20_mute(dev, ctrl->value);
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
+}
+
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
+{
+ return i ? -EINVAL : 0;
+}
+
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ a->index = 0;
+ strlcpy(a->name, "Radio", sizeof(a->name));
+ a->capability = V4L2_AUDCAP_STEREO;
+ return 0;
+}
+
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ return a->index ? -EINVAL : 0;
+}
+
+static const struct v4l2_ioctl_ops pcm20_ioctl_ops = {
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
+};
+
+static int __init pcm20_init(void)
+{
+ struct pcm20 *dev = &pcm20_card;
+ struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
+ int res;
+
+ dev->aci = snd_aci_get_aci();
+ if (dev->aci == NULL) {
+ v4l2_err(v4l2_dev,
+ "you must load the snd-miro driver first!\n");
+ return -ENODEV;
+ }
+ strlcpy(v4l2_dev->name, "miropcm20", sizeof(v4l2_dev->name));
+
+
+ res = v4l2_device_register(NULL, v4l2_dev);
+ if (res < 0) {
+ v4l2_err(v4l2_dev, "could not register v4l2_device\n");
+ return -EINVAL;
+ }
+
+ strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
+ dev->vdev.v4l2_dev = v4l2_dev;
+ dev->vdev.fops = &pcm20_fops;
+ dev->vdev.ioctl_ops = &pcm20_ioctl_ops;
+ dev->vdev.release = video_device_release_empty;
+ video_set_drvdata(&dev->vdev, dev);
+
+ if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0)
+ goto fail;
+
+ v4l2_info(v4l2_dev, "Mirosound PCM20 Radio tuner\n");
+ return 0;
+fail:
+ v4l2_device_unregister(v4l2_dev);
+ return -EINVAL;
+}
+
+MODULE_AUTHOR("Ruurd Reitsma, Krzysztof Helt");
+MODULE_DESCRIPTION("A driver for the Miro PCM20 radio card.");
+MODULE_LICENSE("GPL");
+
+static void __exit pcm20_cleanup(void)
+{
+ struct pcm20 *dev = &pcm20_card;
+
+ video_unregister_device(&dev->vdev);
+ v4l2_device_unregister(&dev->v4l2_dev);
+}
+
+module_init(pcm20_init);
+module_exit(pcm20_cleanup);
--
1.6.4
----------------------------------------------------------------------
Kawalerka za 79 000 zl!
Sprawdz >>> http://link.interia.pl/f2425
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH] New driver for the radio FM module on Miro PCM20 sound card
2009-11-24 21:12 Krzysztof Helt
@ 2009-11-25 9:13 ` Takashi Iwai
2009-11-25 9:57 ` Takashi Iwai
2009-11-26 7:58 ` Hans Verkuil
1 sibling, 1 reply; 10+ messages in thread
From: Takashi Iwai @ 2009-11-25 9:13 UTC (permalink / raw)
To: Krzysztof Helt; +Cc: linux-media
At Tue, 24 Nov 2009 22:12:36 +0100,
Krzysztof Helt wrote:
>
> From: Krzysztof Helt <krzysztof.h1@wp.pl>
>
> This is recreated driver for the FM module found on Miro
> PCM20 sound cards. This driver was removed around the 2.6.2x
> kernels because it relied on the removed OSS module. Now, it
> uses a current ALSA module (snd-miro) and is adapted to v4l2
> layer.
>
> It provides only basic functionality: frequency changing and
> FM module muting.
>
> Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl>
> ---
> This driver depends on changes to the snd-miro driver. These changes
> are already accepted to the ALSA tree, but these changes
> won't be pushed into the 2.6.33 kernel.
Well, if we get ACK from V4L guys for this patch, I can merge it
together with snd-miro changes for 2.6.33. But, it should be done
ASAP (preferably in this week).
> drivers/media/radio/Kconfig | 17 ++
> drivers/media/radio/Makefile | 1 +
> drivers/media/radio/radio-miropcm20.c | 271 +++++++++++++++++++++++++++++++++
> 3 files changed, 289 insertions(+), 0 deletions(-)
> create mode 100644 drivers/media/radio/radio-miropcm20.c
>
> diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
> index a87a477..1c12f99 100644
> --- a/drivers/media/radio/Kconfig
> +++ b/drivers/media/radio/Kconfig
> @@ -195,6 +195,23 @@ config RADIO_MAESTRO
> To compile this driver as a module, choose M here: the
> module will be called radio-maestro.
>
> +config RADIO_MIROPCM20
> + tristate "miroSOUND PCM20 radio"
> + depends on ISA && VIDEO_V4L2
> + select SND_MIRO
> + ---help---
> + Choose Y here if you have this FM radio card. You also need to select
> + the "Miro miroSOUND PCM1pro/PCM12/PCM20radio driver" ALSA sound card
> + driver for this to work.
Better to rephrase "This driver will select ...."? You cannot select it
in practice but it's forcibly set.
> --- /dev/null
> +++ b/drivers/media/radio/radio-miropcm20.c
(snip)
> +
> +static int radio_nr = -1;
> +module_param(radio_nr, int, 0);
Missing MODULE_PARM_DESC().
thanks,
Takashi
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] New driver for the radio FM module on Miro PCM20 sound card
2009-11-25 9:13 ` Takashi Iwai
@ 2009-11-25 9:57 ` Takashi Iwai
0 siblings, 0 replies; 10+ messages in thread
From: Takashi Iwai @ 2009-11-25 9:57 UTC (permalink / raw)
To: Krzysztof Helt; +Cc: linux-media
At Wed, 25 Nov 2009 10:13:53 +0100,
I wrote:
>
> At Tue, 24 Nov 2009 22:12:36 +0100,
> Krzysztof Helt wrote:
> >
> > From: Krzysztof Helt <krzysztof.h1@wp.pl>
> >
> > This is recreated driver for the FM module found on Miro
> > PCM20 sound cards. This driver was removed around the 2.6.2x
> > kernels because it relied on the removed OSS module. Now, it
> > uses a current ALSA module (snd-miro) and is adapted to v4l2
> > layer.
> >
> > It provides only basic functionality: frequency changing and
> > FM module muting.
> >
> > Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl>
> > ---
> > This driver depends on changes to the snd-miro driver. These changes
> > are already accepted to the ALSA tree, but these changes
> > won't be pushed into the 2.6.33 kernel.
>
> Well, if we get ACK from V4L guys for this patch, I can merge it
> together with snd-miro changes for 2.6.33. But, it should be done
> ASAP (preferably in this week).
BTW, the patches for snd-miro driver can be found in sound GIT tree
next/isa or master branches
git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6.git next/isa
Takashi
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] New driver for the radio FM module on Miro PCM20 sound card
2009-11-24 21:12 Krzysztof Helt
2009-11-25 9:13 ` Takashi Iwai
@ 2009-11-26 7:58 ` Hans Verkuil
1 sibling, 0 replies; 10+ messages in thread
From: Hans Verkuil @ 2009-11-26 7:58 UTC (permalink / raw)
To: Krzysztof Helt; +Cc: linux-media, Takashi Iwai
Hi Krzysztof,
I did a quick review and found just two small things. If you fix those,
then you can add a
Reviewed-by: Hans Verkuil <hverkuil@xs4all.nl>
line to your patch.
Thanks,
Hans
On Tuesday 24 November 2009 22:12:36 Krzysztof Helt wrote:
> From: Krzysztof Helt <krzysztof.h1@wp.pl>
>
> This is recreated driver for the FM module found on Miro
> PCM20 sound cards. This driver was removed around the 2.6.2x
> kernels because it relied on the removed OSS module. Now, it
> uses a current ALSA module (snd-miro) and is adapted to v4l2
> layer.
>
> It provides only basic functionality: frequency changing and
> FM module muting.
>
> Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl>
> ---
> This driver depends on changes to the snd-miro driver. These changes
> are already accepted to the ALSA tree, but these changes
> won't be pushed into the 2.6.33 kernel.
>
> drivers/media/radio/Kconfig | 17 ++
> drivers/media/radio/Makefile | 1 +
> drivers/media/radio/radio-miropcm20.c | 271 +++++++++++++++++++++++++++++++++
> 3 files changed, 289 insertions(+), 0 deletions(-)
> create mode 100644 drivers/media/radio/radio-miropcm20.c
>
> diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
> index a87a477..1c12f99 100644
> --- a/drivers/media/radio/Kconfig
> +++ b/drivers/media/radio/Kconfig
> @@ -195,6 +195,23 @@ config RADIO_MAESTRO
> To compile this driver as a module, choose M here: the
> module will be called radio-maestro.
>
> +config RADIO_MIROPCM20
> + tristate "miroSOUND PCM20 radio"
> + depends on ISA && VIDEO_V4L2
> + select SND_MIRO
> + ---help---
> + Choose Y here if you have this FM radio card. You also need to select
> + the "Miro miroSOUND PCM1pro/PCM12/PCM20radio driver" ALSA sound card
> + driver for this to work.
> +
> + In order to control your radio card, you will need to use programs
> + that are compatible with the Video For Linux API. Information on
> + this API and pointers to "v4l" programs may be found at
> + <file:Documentation/video4linux/API.html>.
> +
> + To compile this driver as a module, choose M here: the
> + module will be called radio-miropcm20.
> +
> config RADIO_SF16FMI
> tristate "SF16FMI Radio"
> depends on ISA && VIDEO_V4L2
> diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
> index 2a1be3b..8a63d54 100644
> --- a/drivers/media/radio/Makefile
> +++ b/drivers/media/radio/Makefile
> @@ -18,6 +18,7 @@ obj-$(CONFIG_RADIO_TRUST) += radio-trust.o
> obj-$(CONFIG_I2C_SI4713) += si4713-i2c.o
> obj-$(CONFIG_RADIO_SI4713) += radio-si4713.o
> obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o
> +obj-$(CONFIG_RADIO_MIROPCM20) += radio-miropcm20.o
> obj-$(CONFIG_USB_DSBR) += dsbr100.o
> obj-$(CONFIG_RADIO_SI470X) += si470x/
> obj-$(CONFIG_USB_MR800) += radio-mr800.o
> diff --git a/drivers/media/radio/radio-miropcm20.c b/drivers/media/radio/radio-miropcm20.c
> new file mode 100644
> index 0000000..0b6940c
> --- /dev/null
> +++ b/drivers/media/radio/radio-miropcm20.c
> @@ -0,0 +1,271 @@
> +/* Miro PCM20 radio driver for Linux radio support
> + * (c) 1998 Ruurd Reitsma <R.A.Reitsma@wbmt.tudelft.nl>
> + * Thanks to Norberto Pellici for the ACI device interface specification
> + * The API part is based on the radiotrack driver by M. Kirkwood
> + * This driver relies on the aci mixer provided by the snd-miro
> + * ALSA driver.
> + * Look there for further info...
> + */
> +
> +/* Revision history:
> + *
> + * 1998 Ruurd Reitsma <R.A.Reitsma@wbmt.tudelft.nl>
> + * 2000-09-05 Robert Siemer <Robert.Siemer@gmx.de>
> + * removed unfinished volume control (maybe adding it later again)
> + * use OSS-mixer; added stereo control
> + */
> +
> +/* What ever you think about the ACI, version 0x07 is not very well!
> + * I can't get frequency, 'tuner status', 'tuner flags' or mute/mono
> + * conditions... Robert
> + */
> +
> +#include <linux/module.h>
> +#include <linux/init.h>
> +#include <linux/videodev2.h>
> +#include <media/v4l2-device.h>
> +#include <media/v4l2-ioctl.h>
> +#include <sound/aci.h>
> +
> +static int radio_nr = -1;
> +module_param(radio_nr, int, 0);
> +
> +static int mono;
> +module_param(mono, bool, 0);
> +MODULE_PARM_DESC(mono, "Force tuner into mono mode.");
> +
> +struct pcm20 {
> + struct v4l2_device v4l2_dev;
> + struct video_device vdev;
> + unsigned long freq;
> + int muted;
> + struct snd_miro_aci *aci;
> +};
> +
> +static struct pcm20 pcm20_card = {
> + .freq = 87*16000,
> + .muted = 1,
> +};
> +
> +static int pcm20_mute(struct pcm20 *dev, unsigned char mute)
> +{
> + dev->muted = mute;
> + return snd_aci_cmd(dev->aci, ACI_SET_TUNERMUTE, mute, -1);
> +}
> +
> +static int pcm20_stereo(struct pcm20 *dev, unsigned char stereo)
> +{
> + return snd_aci_cmd(dev->aci, ACI_SET_TUNERMONO, !stereo, -1);
> +}
> +
> +static int pcm20_setfreq(struct pcm20 *dev, unsigned long freq)
> +{
> + unsigned char freql;
> + unsigned char freqh;
> + struct snd_miro_aci *aci = dev->aci;
> +
> + dev->freq = freq;
> +
> + freq /= 160;
> + if (!(aci->aci_version == 0x07 || aci->aci_version >= 0xb0))
> + freq /= 10; /* I don't know exactly which version
> + * needs this hack */
> + freql = freq & 0xff;
> + freqh = freq >> 8;
> +
> + pcm20_stereo(dev, !mono);
> + return snd_aci_cmd(aci, ACI_WRITE_TUNE, freql, freqh);
> +}
> +
> +static const struct v4l2_file_operations pcm20_fops = {
> + .owner = THIS_MODULE,
> + .ioctl = video_ioctl2,
> +};
> +
> +static int vidioc_querycap(struct file *file, void *priv,
> + struct v4l2_capability *v)
> +{
> + strlcpy(v->driver, "Miro PCM20", sizeof(v->driver));
> + strlcpy(v->card, "Miro PCM20", sizeof(v->card));
> + strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
> + v->version = 0x1;
> + v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
> + return 0;
> +}
> +
> +static int vidioc_g_tuner(struct file *file, void *priv,
> + struct v4l2_tuner *v)
> +{
> + if (v->index) /* Only 1 tuner */
> + return -EINVAL;
> + strlcpy(v->name, "FM", sizeof(v->name));
> + v->type = V4L2_TUNER_RADIO;
> + v->rangelow = 87*16000;
> + v->rangehigh = 108*16000;
> + v->signal = 0xffff;
> + v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
> + v->capability = V4L2_TUNER_CAP_LOW;
> + v->audmode = V4L2_TUNER_MODE_MONO;
> + return 0;
> +}
> +
> +static int vidioc_s_tuner(struct file *file, void *priv,
> + struct v4l2_tuner *v)
> +{
> + return v->index ? -EINVAL : 0;
> +}
> +
> +static int vidioc_g_frequency(struct file *file, void *priv,
> + struct v4l2_frequency *f)
> +{
> + struct pcm20 *dev = video_drvdata(file);
> +
This needs a check like this:
if (f->tuner != 0)
return -EINVAL;
> + f->type = V4L2_TUNER_RADIO;
> + f->frequency = dev->freq;
> + return 0;
> +}
> +
> +
> +static int vidioc_s_frequency(struct file *file, void *priv,
> + struct v4l2_frequency *f)
> +{
> + struct pcm20 *dev = video_drvdata(file);
This needs a check like this:
if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
return -EINVAL;
> +
> + dev->freq = f->frequency;
> + pcm20_setfreq(dev, f->frequency);
> + return 0;
> +}
> +
> +static int vidioc_queryctrl(struct file *file, void *priv,
> + struct v4l2_queryctrl *qc)
> +{
> + switch (qc->id) {
> + case V4L2_CID_AUDIO_MUTE:
> + return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
> + }
> + return -EINVAL;
> +}
> +
> +static int vidioc_g_ctrl(struct file *file, void *priv,
> + struct v4l2_control *ctrl)
> +{
> + struct pcm20 *dev = video_drvdata(file);
> +
> + switch (ctrl->id) {
> + case V4L2_CID_AUDIO_MUTE:
> + ctrl->value = dev->muted;
> + break;
> + default:
> + return -EINVAL;
> + }
> + return 0;
> +}
> +
> +static int vidioc_s_ctrl(struct file *file, void *priv,
> + struct v4l2_control *ctrl)
> +{
> + struct pcm20 *dev = video_drvdata(file);
> +
> + switch (ctrl->id) {
> + case V4L2_CID_AUDIO_MUTE:
> + pcm20_mute(dev, ctrl->value);
> + break;
> + default:
> + return -EINVAL;
> + }
> + return 0;
> +}
> +
> +static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
> +{
> + *i = 0;
> + return 0;
> +}
> +
> +static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
> +{
> + return i ? -EINVAL : 0;
> +}
> +
> +static int vidioc_g_audio(struct file *file, void *priv,
> + struct v4l2_audio *a)
> +{
> + a->index = 0;
> + strlcpy(a->name, "Radio", sizeof(a->name));
> + a->capability = V4L2_AUDCAP_STEREO;
> + return 0;
> +}
> +
> +static int vidioc_s_audio(struct file *file, void *priv,
> + struct v4l2_audio *a)
> +{
> + return a->index ? -EINVAL : 0;
> +}
> +
> +static const struct v4l2_ioctl_ops pcm20_ioctl_ops = {
> + .vidioc_querycap = vidioc_querycap,
> + .vidioc_g_tuner = vidioc_g_tuner,
> + .vidioc_s_tuner = vidioc_s_tuner,
> + .vidioc_g_frequency = vidioc_g_frequency,
> + .vidioc_s_frequency = vidioc_s_frequency,
> + .vidioc_queryctrl = vidioc_queryctrl,
> + .vidioc_g_ctrl = vidioc_g_ctrl,
> + .vidioc_s_ctrl = vidioc_s_ctrl,
> + .vidioc_g_audio = vidioc_g_audio,
> + .vidioc_s_audio = vidioc_s_audio,
> + .vidioc_g_input = vidioc_g_input,
> + .vidioc_s_input = vidioc_s_input,
> +};
> +
> +static int __init pcm20_init(void)
> +{
> + struct pcm20 *dev = &pcm20_card;
> + struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
> + int res;
> +
> + dev->aci = snd_aci_get_aci();
> + if (dev->aci == NULL) {
> + v4l2_err(v4l2_dev,
> + "you must load the snd-miro driver first!\n");
> + return -ENODEV;
> + }
> + strlcpy(v4l2_dev->name, "miropcm20", sizeof(v4l2_dev->name));
> +
> +
> + res = v4l2_device_register(NULL, v4l2_dev);
> + if (res < 0) {
> + v4l2_err(v4l2_dev, "could not register v4l2_device\n");
> + return -EINVAL;
> + }
> +
> + strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
> + dev->vdev.v4l2_dev = v4l2_dev;
> + dev->vdev.fops = &pcm20_fops;
> + dev->vdev.ioctl_ops = &pcm20_ioctl_ops;
> + dev->vdev.release = video_device_release_empty;
> + video_set_drvdata(&dev->vdev, dev);
> +
> + if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0)
> + goto fail;
> +
> + v4l2_info(v4l2_dev, "Mirosound PCM20 Radio tuner\n");
> + return 0;
> +fail:
> + v4l2_device_unregister(v4l2_dev);
> + return -EINVAL;
> +}
> +
> +MODULE_AUTHOR("Ruurd Reitsma, Krzysztof Helt");
> +MODULE_DESCRIPTION("A driver for the Miro PCM20 radio card.");
> +MODULE_LICENSE("GPL");
> +
> +static void __exit pcm20_cleanup(void)
> +{
> + struct pcm20 *dev = &pcm20_card;
> +
> + video_unregister_device(&dev->vdev);
> + v4l2_device_unregister(&dev->v4l2_dev);
> +}
> +
> +module_init(pcm20_init);
> +module_exit(pcm20_cleanup);
>
--
Hans Verkuil - video4linux developer - sponsored by TANDBERG
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH] New driver for the radio FM module on Miro PCM20 sound card
@ 2009-11-26 12:50 Krzysztof Helt
2009-11-26 15:43 ` Takashi Iwai
0 siblings, 1 reply; 10+ messages in thread
From: Krzysztof Helt @ 2009-11-26 12:50 UTC (permalink / raw)
To: linux-media; +Cc: Takashi Iwai, Hans Verkuil
From: Krzysztof Helt <krzysztof.h1@wp.pl>
This is recreated driver for the FM module found on Miro
PCM20 sound cards. This driver was removed around the 2.6.2x
kernels because it relied on the removed OSS module. Now, it
uses a current ALSA module (snd-miro) and is adapted to v4l2
layer.
It provides only basic functionality: frequency changing and
FM module muting.
Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl>
Reviewed-by: Hans Verkuil <hverkuil@xs4all.nl>
---
This is the second version of the patch with changes suggested by Hans Verkuil.
drivers/media/radio/Kconfig | 17 ++
drivers/media/radio/Makefile | 1 +
drivers/media/radio/radio-miropcm20.c | 269 +++++++++++++++++++++++++++++++++
3 files changed, 287 insertions(+), 0 deletions(-)
create mode 100644 drivers/media/radio/radio-miropcm20.c
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index a87a477..b1df9f2 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -195,6 +195,23 @@ config RADIO_MAESTRO
To compile this driver as a module, choose M here: the
module will be called radio-maestro.
+config RADIO_MIROPCM20
+ tristate "miroSOUND PCM20 radio"
+ depends on ISA && VIDEO_V4L2
+ select SND_MIRO
+ ---help---
+ Choose Y here if you have this FM radio card. You also need to select
+ the "Miro miroSOUND PCM1pro/PCM12/PCM20radio driver" ALSA sound card
+ driver for this to work.
+
+ In order to control your radio card, you will need to use programs
+ that are compatible with the Video For Linux API. Information on
+ this API and pointers to "v4l" programs may be found at
+ <file:Documentation/video4linux/API.html>.
+
+ To compile this driver as a module, choose M here: the
+ module will be called radio-miropcm20.
+
config RADIO_SF16FMI
tristate "SF16FMI Radio"
depends on ISA && VIDEO_V4L2
diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
index 2a1be3b..8a63d54 100644
--- a/drivers/media/radio/Makefile
+++ b/drivers/media/radio/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_RADIO_TRUST) += radio-trust.o
obj-$(CONFIG_I2C_SI4713) += si4713-i2c.o
obj-$(CONFIG_RADIO_SI4713) += radio-si4713.o
obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o
+obj-$(CONFIG_RADIO_MIROPCM20) += radio-miropcm20.o
obj-$(CONFIG_USB_DSBR) += dsbr100.o
obj-$(CONFIG_RADIO_SI470X) += si470x/
obj-$(CONFIG_USB_MR800) += radio-mr800.o
diff --git a/drivers/media/radio/radio-miropcm20.c b/drivers/media/radio/radio-miropcm20.c
new file mode 100644
index 0000000..6fd71f3
--- /dev/null
+++ b/drivers/media/radio/radio-miropcm20.c
@@ -0,0 +1,269 @@
+/* Miro PCM20 radio driver for Linux radio support
+ * (c) 1998 Ruurd Reitsma <R.A.Reitsma@wbmt.tudelft.nl>
+ * Thanks to Norberto Pellici for the ACI device interface specification
+ * The API part is based on the radiotrack driver by M. Kirkwood
+ * This driver relies on the aci mixer provided by the snd-miro
+ * ALSA driver.
+ * Look there for further info...
+ */
+
+/* What ever you think about the ACI, version 0x07 is not very well!
+ * I can't get frequency, 'tuner status', 'tuner flags' or mute/mono
+ * conditions... Robert
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <sound/aci.h>
+
+static int radio_nr = -1;
+module_param(radio_nr, int, 0);
+
+static int mono;
+module_param(mono, bool, 0);
+MODULE_PARM_DESC(mono, "Force tuner into mono mode.");
+
+struct pcm20 {
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
+ unsigned long freq;
+ int muted;
+ struct snd_miro_aci *aci;
+};
+
+static struct pcm20 pcm20_card = {
+ .freq = 87*16000,
+ .muted = 1,
+};
+
+static int pcm20_mute(struct pcm20 *dev, unsigned char mute)
+{
+ dev->muted = mute;
+ return snd_aci_cmd(dev->aci, ACI_SET_TUNERMUTE, mute, -1);
+}
+
+static int pcm20_stereo(struct pcm20 *dev, unsigned char stereo)
+{
+ return snd_aci_cmd(dev->aci, ACI_SET_TUNERMONO, !stereo, -1);
+}
+
+static int pcm20_setfreq(struct pcm20 *dev, unsigned long freq)
+{
+ unsigned char freql;
+ unsigned char freqh;
+ struct snd_miro_aci *aci = dev->aci;
+
+ dev->freq = freq;
+
+ freq /= 160;
+ if (!(aci->aci_version == 0x07 || aci->aci_version >= 0xb0))
+ freq /= 10; /* I don't know exactly which version
+ * needs this hack */
+ freql = freq & 0xff;
+ freqh = freq >> 8;
+
+ pcm20_stereo(dev, !mono);
+ return snd_aci_cmd(aci, ACI_WRITE_TUNE, freql, freqh);
+}
+
+static const struct v4l2_file_operations pcm20_fops = {
+ .owner = THIS_MODULE,
+ .ioctl = video_ioctl2,
+};
+
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *v)
+{
+ strlcpy(v->driver, "Miro PCM20", sizeof(v->driver));
+ strlcpy(v->card, "Miro PCM20", sizeof(v->card));
+ strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
+ v->version = 0x1;
+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+ return 0;
+}
+
+static int vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ if (v->index) /* Only 1 tuner */
+ return -EINVAL;
+ strlcpy(v->name, "FM", sizeof(v->name));
+ v->type = V4L2_TUNER_RADIO;
+ v->rangelow = 87*16000;
+ v->rangehigh = 108*16000;
+ v->signal = 0xffff;
+ v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
+ v->capability = V4L2_TUNER_CAP_LOW;
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ return 0;
+}
+
+static int vidioc_s_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ return v->index ? -EINVAL : 0;
+}
+
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct pcm20 *dev = video_drvdata(file);
+
+ if (f->tuner != 0)
+ return -EINVAL;
+
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = dev->freq;
+ return 0;
+}
+
+
+static int vidioc_s_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct pcm20 *dev = video_drvdata(file);
+
+ if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
+ return -EINVAL;
+
+ dev->freq = f->frequency;
+ pcm20_setfreq(dev, f->frequency);
+ return 0;
+}
+
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ switch (qc->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+ }
+ return -EINVAL;
+}
+
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct pcm20 *dev = video_drvdata(file);
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = dev->muted;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct pcm20 *dev = video_drvdata(file);
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ pcm20_mute(dev, ctrl->value);
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
+}
+
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
+{
+ return i ? -EINVAL : 0;
+}
+
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ a->index = 0;
+ strlcpy(a->name, "Radio", sizeof(a->name));
+ a->capability = V4L2_AUDCAP_STEREO;
+ return 0;
+}
+
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ return a->index ? -EINVAL : 0;
+}
+
+static const struct v4l2_ioctl_ops pcm20_ioctl_ops = {
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
+};
+
+static int __init pcm20_init(void)
+{
+ struct pcm20 *dev = &pcm20_card;
+ struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
+ int res;
+
+ dev->aci = snd_aci_get_aci();
+ if (dev->aci == NULL) {
+ v4l2_err(v4l2_dev,
+ "you must load the snd-miro driver first!\n");
+ return -ENODEV;
+ }
+ strlcpy(v4l2_dev->name, "miropcm20", sizeof(v4l2_dev->name));
+
+
+ res = v4l2_device_register(NULL, v4l2_dev);
+ if (res < 0) {
+ v4l2_err(v4l2_dev, "could not register v4l2_device\n");
+ return -EINVAL;
+ }
+
+ strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
+ dev->vdev.v4l2_dev = v4l2_dev;
+ dev->vdev.fops = &pcm20_fops;
+ dev->vdev.ioctl_ops = &pcm20_ioctl_ops;
+ dev->vdev.release = video_device_release_empty;
+ video_set_drvdata(&dev->vdev, dev);
+
+ if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0)
+ goto fail;
+
+ v4l2_info(v4l2_dev, "Mirosound PCM20 Radio tuner\n");
+ return 0;
+fail:
+ v4l2_device_unregister(v4l2_dev);
+ return -EINVAL;
+}
+
+MODULE_AUTHOR("Ruurd Reitsma, Krzysztof Helt");
+MODULE_DESCRIPTION("A driver for the Miro PCM20 radio card.");
+MODULE_LICENSE("GPL");
+
+static void __exit pcm20_cleanup(void)
+{
+ struct pcm20 *dev = &pcm20_card;
+
+ video_unregister_device(&dev->vdev);
+ v4l2_device_unregister(&dev->v4l2_dev);
+}
+
+module_init(pcm20_init);
+module_exit(pcm20_cleanup);
--
1.6.4
----------------------------------------------------------------------
Audi kilka tysiecy zlotych taniej? Przebieraj wsrod tysiecy ogloszen!
Kliknij >>> http://link.interia.pl/f2424
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH] New driver for the radio FM module on Miro PCM20 sound card
2009-11-26 12:50 Krzysztof Helt
@ 2009-11-26 15:43 ` Takashi Iwai
[not found] ` <20091126183827.f9b0770e.krzysztof.h1@poczta.fm>
0 siblings, 1 reply; 10+ messages in thread
From: Takashi Iwai @ 2009-11-26 15:43 UTC (permalink / raw)
To: Krzysztof Helt; +Cc: linux-media, Hans Verkuil
At Thu, 26 Nov 2009 13:50:17 +0100,
Krzysztof Helt wrote:
>
> From: Krzysztof Helt <krzysztof.h1@wp.pl>
>
> This is recreated driver for the FM module found on Miro
> PCM20 sound cards. This driver was removed around the 2.6.2x
> kernels because it relied on the removed OSS module. Now, it
> uses a current ALSA module (snd-miro) and is adapted to v4l2
> layer.
>
> It provides only basic functionality: frequency changing and
> FM module muting.
>
> Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl>
> Reviewed-by: Hans Verkuil <hverkuil@xs4all.nl>
> ---
> This is the second version of the patch with changes suggested by Hans Verkuil.
Thanks. But you didn't check my review comment in my previous mail...?
Takashi
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] New driver for the radio FM module on Miro PCM20 sound card
[not found] ` <20091126183827.f9b0770e.krzysztof.h1@poczta.fm>
@ 2009-11-26 17:42 ` Takashi Iwai
0 siblings, 0 replies; 10+ messages in thread
From: Takashi Iwai @ 2009-11-26 17:42 UTC (permalink / raw)
To: Krzysztof Helt; +Cc: linux-media, Hans Verkuil
At Thu, 26 Nov 2009 18:38:27 +0100,
Krzysztof Helt wrote:
>
> On Thu, 26 Nov 2009 16:43:15 +0100
> Takashi Iwai <tiwai@suse.de> wrote:
>
> > At Thu, 26 Nov 2009 13:50:17 +0100,
> > Krzysztof Helt wrote:
> > >
> > > From: Krzysztof Helt <krzysztof.h1@wp.pl>
> > >
> > > This is recreated driver for the FM module found on Miro
> > > PCM20 sound cards. This driver was removed around the 2.6.2x
> > > kernels because it relied on the removed OSS module. Now, it
> > > uses a current ALSA module (snd-miro) and is adapted to v4l2
> > > layer.
> > >
> > > It provides only basic functionality: frequency changing and
> > > FM module muting.
> > >
> > > Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl>
> > > Reviewed-by: Hans Verkuil <hverkuil@xs4all.nl>
> > > ---
> > > This is the second version of the patch with changes suggested by Hans Verkuil.
> >
> > Thanks. But you didn't check my review comment in my previous mail...?
> >
>
> I have missed it. I will redo the patch.
OK, thanks ;)
Takashi
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH] New driver for the radio FM module on Miro PCM20 sound card
@ 2009-11-27 10:24 Krzysztof Helt
2009-11-27 10:53 ` Takashi Iwai
2009-11-27 12:20 ` Mauro Carvalho Chehab
0 siblings, 2 replies; 10+ messages in thread
From: Krzysztof Helt @ 2009-11-27 10:24 UTC (permalink / raw)
To: linux-media; +Cc: Takashi Iwai, Hans Verkuil
From: Krzysztof Helt <krzysztof.h1@wp.pl>
This is recreated driver for the FM module found on Miro
PCM20 sound cards. This driver was removed around the 2.6.2x
kernels because it relied on the removed OSS module. Now, it
uses a current ALSA module (snd-miro) and is adapted to v4l2
layer.
It provides only basic functionality: frequency changing and
FM module muting.
Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl>
Reviewed-by: Hans Verkuil <hverkuil@xs4all.nl>
---
This is the third version of the patch with fixed issues pointed
by Takashi Iwai.
drivers/media/radio/Kconfig | 18 +++
drivers/media/radio/Makefile | 1 +
drivers/media/radio/radio-miropcm20.c | 270 +++++++++++++++++++++++++++++++++
3 files changed, 289 insertions(+), 0 deletions(-)
create mode 100644 drivers/media/radio/radio-miropcm20.c
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index a87a477..b134553 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -195,6 +195,24 @@ config RADIO_MAESTRO
To compile this driver as a module, choose M here: the
module will be called radio-maestro.
+config RADIO_MIROPCM20
+ tristate "miroSOUND PCM20 radio"
+ depends on ISA && VIDEO_V4L2
+ select SND_MIRO
+ ---help---
+ Choose Y here if you have this FM radio card. You also need to enable
+ the ALSA sound system. This choice automatically selects the ALSA
+ sound card driver "Miro miroSOUND PCM1pro/PCM12/PCM20radio" as this
+ is required for the radio-miropcm20.
+
+ In order to control your radio card, you will need to use programs
+ that are compatible with the Video For Linux API. Information on
+ this API and pointers to "v4l" programs may be found at
+ <file:Documentation/video4linux/API.html>.
+
+ To compile this driver as a module, choose M here: the
+ module will be called radio-miropcm20.
+
config RADIO_SF16FMI
tristate "SF16FMI Radio"
depends on ISA && VIDEO_V4L2
diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
index 2a1be3b..8a63d54 100644
--- a/drivers/media/radio/Makefile
+++ b/drivers/media/radio/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_RADIO_TRUST) += radio-trust.o
obj-$(CONFIG_I2C_SI4713) += si4713-i2c.o
obj-$(CONFIG_RADIO_SI4713) += radio-si4713.o
obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o
+obj-$(CONFIG_RADIO_MIROPCM20) += radio-miropcm20.o
obj-$(CONFIG_USB_DSBR) += dsbr100.o
obj-$(CONFIG_RADIO_SI470X) += si470x/
obj-$(CONFIG_USB_MR800) += radio-mr800.o
diff --git a/drivers/media/radio/radio-miropcm20.c b/drivers/media/radio/radio-miropcm20.c
new file mode 100644
index 0000000..4ff8854
--- /dev/null
+++ b/drivers/media/radio/radio-miropcm20.c
@@ -0,0 +1,270 @@
+/* Miro PCM20 radio driver for Linux radio support
+ * (c) 1998 Ruurd Reitsma <R.A.Reitsma@wbmt.tudelft.nl>
+ * Thanks to Norberto Pellici for the ACI device interface specification
+ * The API part is based on the radiotrack driver by M. Kirkwood
+ * This driver relies on the aci mixer provided by the snd-miro
+ * ALSA driver.
+ * Look there for further info...
+ */
+
+/* What ever you think about the ACI, version 0x07 is not very well!
+ * I can't get frequency, 'tuner status', 'tuner flags' or mute/mono
+ * conditions... Robert
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <sound/aci.h>
+
+static int radio_nr = -1;
+module_param(radio_nr, int, 0);
+MODULE_PARM_DESC(radio_nr, "Set radio device number (/dev/radioX). Default: -1 (autodetect)");
+
+static int mono;
+module_param(mono, bool, 0);
+MODULE_PARM_DESC(mono, "Force tuner into mono mode.");
+
+struct pcm20 {
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
+ unsigned long freq;
+ int muted;
+ struct snd_miro_aci *aci;
+};
+
+static struct pcm20 pcm20_card = {
+ .freq = 87*16000,
+ .muted = 1,
+};
+
+static int pcm20_mute(struct pcm20 *dev, unsigned char mute)
+{
+ dev->muted = mute;
+ return snd_aci_cmd(dev->aci, ACI_SET_TUNERMUTE, mute, -1);
+}
+
+static int pcm20_stereo(struct pcm20 *dev, unsigned char stereo)
+{
+ return snd_aci_cmd(dev->aci, ACI_SET_TUNERMONO, !stereo, -1);
+}
+
+static int pcm20_setfreq(struct pcm20 *dev, unsigned long freq)
+{
+ unsigned char freql;
+ unsigned char freqh;
+ struct snd_miro_aci *aci = dev->aci;
+
+ dev->freq = freq;
+
+ freq /= 160;
+ if (!(aci->aci_version == 0x07 || aci->aci_version >= 0xb0))
+ freq /= 10; /* I don't know exactly which version
+ * needs this hack */
+ freql = freq & 0xff;
+ freqh = freq >> 8;
+
+ pcm20_stereo(dev, !mono);
+ return snd_aci_cmd(aci, ACI_WRITE_TUNE, freql, freqh);
+}
+
+static const struct v4l2_file_operations pcm20_fops = {
+ .owner = THIS_MODULE,
+ .ioctl = video_ioctl2,
+};
+
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *v)
+{
+ strlcpy(v->driver, "Miro PCM20", sizeof(v->driver));
+ strlcpy(v->card, "Miro PCM20", sizeof(v->card));
+ strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
+ v->version = 0x1;
+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+ return 0;
+}
+
+static int vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ if (v->index) /* Only 1 tuner */
+ return -EINVAL;
+ strlcpy(v->name, "FM", sizeof(v->name));
+ v->type = V4L2_TUNER_RADIO;
+ v->rangelow = 87*16000;
+ v->rangehigh = 108*16000;
+ v->signal = 0xffff;
+ v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
+ v->capability = V4L2_TUNER_CAP_LOW;
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ return 0;
+}
+
+static int vidioc_s_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ return v->index ? -EINVAL : 0;
+}
+
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct pcm20 *dev = video_drvdata(file);
+
+ if (f->tuner != 0)
+ return -EINVAL;
+
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = dev->freq;
+ return 0;
+}
+
+
+static int vidioc_s_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct pcm20 *dev = video_drvdata(file);
+
+ if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
+ return -EINVAL;
+
+ dev->freq = f->frequency;
+ pcm20_setfreq(dev, f->frequency);
+ return 0;
+}
+
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ switch (qc->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+ }
+ return -EINVAL;
+}
+
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct pcm20 *dev = video_drvdata(file);
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = dev->muted;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct pcm20 *dev = video_drvdata(file);
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ pcm20_mute(dev, ctrl->value);
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
+}
+
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
+{
+ return i ? -EINVAL : 0;
+}
+
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ a->index = 0;
+ strlcpy(a->name, "Radio", sizeof(a->name));
+ a->capability = V4L2_AUDCAP_STEREO;
+ return 0;
+}
+
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ return a->index ? -EINVAL : 0;
+}
+
+static const struct v4l2_ioctl_ops pcm20_ioctl_ops = {
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
+};
+
+static int __init pcm20_init(void)
+{
+ struct pcm20 *dev = &pcm20_card;
+ struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
+ int res;
+
+ dev->aci = snd_aci_get_aci();
+ if (dev->aci == NULL) {
+ v4l2_err(v4l2_dev,
+ "you must load the snd-miro driver first!\n");
+ return -ENODEV;
+ }
+ strlcpy(v4l2_dev->name, "miropcm20", sizeof(v4l2_dev->name));
+
+
+ res = v4l2_device_register(NULL, v4l2_dev);
+ if (res < 0) {
+ v4l2_err(v4l2_dev, "could not register v4l2_device\n");
+ return -EINVAL;
+ }
+
+ strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
+ dev->vdev.v4l2_dev = v4l2_dev;
+ dev->vdev.fops = &pcm20_fops;
+ dev->vdev.ioctl_ops = &pcm20_ioctl_ops;
+ dev->vdev.release = video_device_release_empty;
+ video_set_drvdata(&dev->vdev, dev);
+
+ if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0)
+ goto fail;
+
+ v4l2_info(v4l2_dev, "Mirosound PCM20 Radio tuner\n");
+ return 0;
+fail:
+ v4l2_device_unregister(v4l2_dev);
+ return -EINVAL;
+}
+
+MODULE_AUTHOR("Ruurd Reitsma, Krzysztof Helt");
+MODULE_DESCRIPTION("A driver for the Miro PCM20 radio card.");
+MODULE_LICENSE("GPL");
+
+static void __exit pcm20_cleanup(void)
+{
+ struct pcm20 *dev = &pcm20_card;
+
+ video_unregister_device(&dev->vdev);
+ v4l2_device_unregister(&dev->v4l2_dev);
+}
+
+module_init(pcm20_init);
+module_exit(pcm20_cleanup);
--
1.6.4
----------------------------------------------------------------------
Internetowi nie placa! Otworz Konto Direct.
Kliknij >> http://link.interia.pl/f2448
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH] New driver for the radio FM module on Miro PCM20 sound card
2009-11-27 10:24 [PATCH] New driver for the radio FM module on Miro PCM20 sound card Krzysztof Helt
@ 2009-11-27 10:53 ` Takashi Iwai
2009-11-27 12:20 ` Mauro Carvalho Chehab
1 sibling, 0 replies; 10+ messages in thread
From: Takashi Iwai @ 2009-11-27 10:53 UTC (permalink / raw)
To: Krzysztof Helt; +Cc: linux-media, Hans Verkuil
At Fri, 27 Nov 2009 11:24:13 +0100,
Krzysztof Helt wrote:
>
> From: Krzysztof Helt <krzysztof.h1@wp.pl>
>
> This is recreated driver for the FM module found on Miro
> PCM20 sound cards. This driver was removed around the 2.6.2x
> kernels because it relied on the removed OSS module. Now, it
> uses a current ALSA module (snd-miro) and is adapted to v4l2
> layer.
>
> It provides only basic functionality: frequency changing and
> FM module muting.
>
> Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl>
> Reviewed-by: Hans Verkuil <hverkuil@xs4all.nl>
> ---
> This is the third version of the patch with fixed issues pointed
> by Takashi Iwai.
Thanks, I merged now this to sound tree exceptionally since it's purely
depends on snd-miro driver. Will appear in the next linux-next.
Takashi
>
> drivers/media/radio/Kconfig | 18 +++
> drivers/media/radio/Makefile | 1 +
> drivers/media/radio/radio-miropcm20.c | 270 +++++++++++++++++++++++++++++++++
> 3 files changed, 289 insertions(+), 0 deletions(-)
> create mode 100644 drivers/media/radio/radio-miropcm20.c
>
> diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
> index a87a477..b134553 100644
> --- a/drivers/media/radio/Kconfig
> +++ b/drivers/media/radio/Kconfig
> @@ -195,6 +195,24 @@ config RADIO_MAESTRO
> To compile this driver as a module, choose M here: the
> module will be called radio-maestro.
>
> +config RADIO_MIROPCM20
> + tristate "miroSOUND PCM20 radio"
> + depends on ISA && VIDEO_V4L2
> + select SND_MIRO
> + ---help---
> + Choose Y here if you have this FM radio card. You also need to enable
> + the ALSA sound system. This choice automatically selects the ALSA
> + sound card driver "Miro miroSOUND PCM1pro/PCM12/PCM20radio" as this
> + is required for the radio-miropcm20.
> +
> + In order to control your radio card, you will need to use programs
> + that are compatible with the Video For Linux API. Information on
> + this API and pointers to "v4l" programs may be found at
> + <file:Documentation/video4linux/API.html>.
> +
> + To compile this driver as a module, choose M here: the
> + module will be called radio-miropcm20.
> +
> config RADIO_SF16FMI
> tristate "SF16FMI Radio"
> depends on ISA && VIDEO_V4L2
> diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
> index 2a1be3b..8a63d54 100644
> --- a/drivers/media/radio/Makefile
> +++ b/drivers/media/radio/Makefile
> @@ -18,6 +18,7 @@ obj-$(CONFIG_RADIO_TRUST) += radio-trust.o
> obj-$(CONFIG_I2C_SI4713) += si4713-i2c.o
> obj-$(CONFIG_RADIO_SI4713) += radio-si4713.o
> obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o
> +obj-$(CONFIG_RADIO_MIROPCM20) += radio-miropcm20.o
> obj-$(CONFIG_USB_DSBR) += dsbr100.o
> obj-$(CONFIG_RADIO_SI470X) += si470x/
> obj-$(CONFIG_USB_MR800) += radio-mr800.o
> diff --git a/drivers/media/radio/radio-miropcm20.c b/drivers/media/radio/radio-miropcm20.c
> new file mode 100644
> index 0000000..4ff8854
> --- /dev/null
> +++ b/drivers/media/radio/radio-miropcm20.c
> @@ -0,0 +1,270 @@
> +/* Miro PCM20 radio driver for Linux radio support
> + * (c) 1998 Ruurd Reitsma <R.A.Reitsma@wbmt.tudelft.nl>
> + * Thanks to Norberto Pellici for the ACI device interface specification
> + * The API part is based on the radiotrack driver by M. Kirkwood
> + * This driver relies on the aci mixer provided by the snd-miro
> + * ALSA driver.
> + * Look there for further info...
> + */
> +
> +/* What ever you think about the ACI, version 0x07 is not very well!
> + * I can't get frequency, 'tuner status', 'tuner flags' or mute/mono
> + * conditions... Robert
> + */
> +
> +#include <linux/module.h>
> +#include <linux/init.h>
> +#include <linux/videodev2.h>
> +#include <media/v4l2-device.h>
> +#include <media/v4l2-ioctl.h>
> +#include <sound/aci.h>
> +
> +static int radio_nr = -1;
> +module_param(radio_nr, int, 0);
> +MODULE_PARM_DESC(radio_nr, "Set radio device number (/dev/radioX). Default: -1 (autodetect)");
> +
> +static int mono;
> +module_param(mono, bool, 0);
> +MODULE_PARM_DESC(mono, "Force tuner into mono mode.");
> +
> +struct pcm20 {
> + struct v4l2_device v4l2_dev;
> + struct video_device vdev;
> + unsigned long freq;
> + int muted;
> + struct snd_miro_aci *aci;
> +};
> +
> +static struct pcm20 pcm20_card = {
> + .freq = 87*16000,
> + .muted = 1,
> +};
> +
> +static int pcm20_mute(struct pcm20 *dev, unsigned char mute)
> +{
> + dev->muted = mute;
> + return snd_aci_cmd(dev->aci, ACI_SET_TUNERMUTE, mute, -1);
> +}
> +
> +static int pcm20_stereo(struct pcm20 *dev, unsigned char stereo)
> +{
> + return snd_aci_cmd(dev->aci, ACI_SET_TUNERMONO, !stereo, -1);
> +}
> +
> +static int pcm20_setfreq(struct pcm20 *dev, unsigned long freq)
> +{
> + unsigned char freql;
> + unsigned char freqh;
> + struct snd_miro_aci *aci = dev->aci;
> +
> + dev->freq = freq;
> +
> + freq /= 160;
> + if (!(aci->aci_version == 0x07 || aci->aci_version >= 0xb0))
> + freq /= 10; /* I don't know exactly which version
> + * needs this hack */
> + freql = freq & 0xff;
> + freqh = freq >> 8;
> +
> + pcm20_stereo(dev, !mono);
> + return snd_aci_cmd(aci, ACI_WRITE_TUNE, freql, freqh);
> +}
> +
> +static const struct v4l2_file_operations pcm20_fops = {
> + .owner = THIS_MODULE,
> + .ioctl = video_ioctl2,
> +};
> +
> +static int vidioc_querycap(struct file *file, void *priv,
> + struct v4l2_capability *v)
> +{
> + strlcpy(v->driver, "Miro PCM20", sizeof(v->driver));
> + strlcpy(v->card, "Miro PCM20", sizeof(v->card));
> + strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
> + v->version = 0x1;
> + v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
> + return 0;
> +}
> +
> +static int vidioc_g_tuner(struct file *file, void *priv,
> + struct v4l2_tuner *v)
> +{
> + if (v->index) /* Only 1 tuner */
> + return -EINVAL;
> + strlcpy(v->name, "FM", sizeof(v->name));
> + v->type = V4L2_TUNER_RADIO;
> + v->rangelow = 87*16000;
> + v->rangehigh = 108*16000;
> + v->signal = 0xffff;
> + v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
> + v->capability = V4L2_TUNER_CAP_LOW;
> + v->audmode = V4L2_TUNER_MODE_MONO;
> + return 0;
> +}
> +
> +static int vidioc_s_tuner(struct file *file, void *priv,
> + struct v4l2_tuner *v)
> +{
> + return v->index ? -EINVAL : 0;
> +}
> +
> +static int vidioc_g_frequency(struct file *file, void *priv,
> + struct v4l2_frequency *f)
> +{
> + struct pcm20 *dev = video_drvdata(file);
> +
> + if (f->tuner != 0)
> + return -EINVAL;
> +
> + f->type = V4L2_TUNER_RADIO;
> + f->frequency = dev->freq;
> + return 0;
> +}
> +
> +
> +static int vidioc_s_frequency(struct file *file, void *priv,
> + struct v4l2_frequency *f)
> +{
> + struct pcm20 *dev = video_drvdata(file);
> +
> + if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
> + return -EINVAL;
> +
> + dev->freq = f->frequency;
> + pcm20_setfreq(dev, f->frequency);
> + return 0;
> +}
> +
> +static int vidioc_queryctrl(struct file *file, void *priv,
> + struct v4l2_queryctrl *qc)
> +{
> + switch (qc->id) {
> + case V4L2_CID_AUDIO_MUTE:
> + return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
> + }
> + return -EINVAL;
> +}
> +
> +static int vidioc_g_ctrl(struct file *file, void *priv,
> + struct v4l2_control *ctrl)
> +{
> + struct pcm20 *dev = video_drvdata(file);
> +
> + switch (ctrl->id) {
> + case V4L2_CID_AUDIO_MUTE:
> + ctrl->value = dev->muted;
> + break;
> + default:
> + return -EINVAL;
> + }
> + return 0;
> +}
> +
> +static int vidioc_s_ctrl(struct file *file, void *priv,
> + struct v4l2_control *ctrl)
> +{
> + struct pcm20 *dev = video_drvdata(file);
> +
> + switch (ctrl->id) {
> + case V4L2_CID_AUDIO_MUTE:
> + pcm20_mute(dev, ctrl->value);
> + break;
> + default:
> + return -EINVAL;
> + }
> + return 0;
> +}
> +
> +static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
> +{
> + *i = 0;
> + return 0;
> +}
> +
> +static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
> +{
> + return i ? -EINVAL : 0;
> +}
> +
> +static int vidioc_g_audio(struct file *file, void *priv,
> + struct v4l2_audio *a)
> +{
> + a->index = 0;
> + strlcpy(a->name, "Radio", sizeof(a->name));
> + a->capability = V4L2_AUDCAP_STEREO;
> + return 0;
> +}
> +
> +static int vidioc_s_audio(struct file *file, void *priv,
> + struct v4l2_audio *a)
> +{
> + return a->index ? -EINVAL : 0;
> +}
> +
> +static const struct v4l2_ioctl_ops pcm20_ioctl_ops = {
> + .vidioc_querycap = vidioc_querycap,
> + .vidioc_g_tuner = vidioc_g_tuner,
> + .vidioc_s_tuner = vidioc_s_tuner,
> + .vidioc_g_frequency = vidioc_g_frequency,
> + .vidioc_s_frequency = vidioc_s_frequency,
> + .vidioc_queryctrl = vidioc_queryctrl,
> + .vidioc_g_ctrl = vidioc_g_ctrl,
> + .vidioc_s_ctrl = vidioc_s_ctrl,
> + .vidioc_g_audio = vidioc_g_audio,
> + .vidioc_s_audio = vidioc_s_audio,
> + .vidioc_g_input = vidioc_g_input,
> + .vidioc_s_input = vidioc_s_input,
> +};
> +
> +static int __init pcm20_init(void)
> +{
> + struct pcm20 *dev = &pcm20_card;
> + struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
> + int res;
> +
> + dev->aci = snd_aci_get_aci();
> + if (dev->aci == NULL) {
> + v4l2_err(v4l2_dev,
> + "you must load the snd-miro driver first!\n");
> + return -ENODEV;
> + }
> + strlcpy(v4l2_dev->name, "miropcm20", sizeof(v4l2_dev->name));
> +
> +
> + res = v4l2_device_register(NULL, v4l2_dev);
> + if (res < 0) {
> + v4l2_err(v4l2_dev, "could not register v4l2_device\n");
> + return -EINVAL;
> + }
> +
> + strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
> + dev->vdev.v4l2_dev = v4l2_dev;
> + dev->vdev.fops = &pcm20_fops;
> + dev->vdev.ioctl_ops = &pcm20_ioctl_ops;
> + dev->vdev.release = video_device_release_empty;
> + video_set_drvdata(&dev->vdev, dev);
> +
> + if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0)
> + goto fail;
> +
> + v4l2_info(v4l2_dev, "Mirosound PCM20 Radio tuner\n");
> + return 0;
> +fail:
> + v4l2_device_unregister(v4l2_dev);
> + return -EINVAL;
> +}
> +
> +MODULE_AUTHOR("Ruurd Reitsma, Krzysztof Helt");
> +MODULE_DESCRIPTION("A driver for the Miro PCM20 radio card.");
> +MODULE_LICENSE("GPL");
> +
> +static void __exit pcm20_cleanup(void)
> +{
> + struct pcm20 *dev = &pcm20_card;
> +
> + video_unregister_device(&dev->vdev);
> + v4l2_device_unregister(&dev->v4l2_dev);
> +}
> +
> +module_init(pcm20_init);
> +module_exit(pcm20_cleanup);
> --
> 1.6.4
>
>
> ----------------------------------------------------------------------
> Internetowi nie placa! Otworz Konto Direct.
> Kliknij >> http://link.interia.pl/f2448
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] New driver for the radio FM module on Miro PCM20 sound card
2009-11-27 10:24 [PATCH] New driver for the radio FM module on Miro PCM20 sound card Krzysztof Helt
2009-11-27 10:53 ` Takashi Iwai
@ 2009-11-27 12:20 ` Mauro Carvalho Chehab
1 sibling, 0 replies; 10+ messages in thread
From: Mauro Carvalho Chehab @ 2009-11-27 12:20 UTC (permalink / raw)
To: Krzysztof Helt; +Cc: linux-media, Takashi Iwai, Hans Verkuil
Krzysztof Helt wrote:
> From: Krzysztof Helt <krzysztof.h1@wp.pl>
>
> This is recreated driver for the FM module found on Miro
> PCM20 sound cards. This driver was removed around the 2.6.2x
> kernels because it relied on the removed OSS module. Now, it
> uses a current ALSA module (snd-miro) and is adapted to v4l2
> layer.
>
> It provides only basic functionality: frequency changing and
> FM module muting.
>
> Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl>
> Reviewed-by: Hans Verkuil <hverkuil@xs4all.nl>
Acked-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Cheers,
Mauro.
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2009-11-27 12:20 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-11-27 10:24 [PATCH] New driver for the radio FM module on Miro PCM20 sound card Krzysztof Helt
2009-11-27 10:53 ` Takashi Iwai
2009-11-27 12:20 ` Mauro Carvalho Chehab
-- strict thread matches above, loose matches on Subject: below --
2009-11-26 12:50 Krzysztof Helt
2009-11-26 15:43 ` Takashi Iwai
[not found] ` <20091126183827.f9b0770e.krzysztof.h1@poczta.fm>
2009-11-26 17:42 ` Takashi Iwai
2009-11-24 21:12 Krzysztof Helt
2009-11-25 9:13 ` Takashi Iwai
2009-11-25 9:57 ` Takashi Iwai
2009-11-26 7:58 ` Hans Verkuil
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox