2011-03-12 18:19:29

by Ondrej Zary

[permalink] [raw]
Subject: radio-maestro broken (conflicts with snd-es1968)

Hello,
the radio-maestro driver is badly broken. It's intended to drive the radio on
MediaForte ESS Maestro-based sound cards with integrated radio (like
SF64-PCE2-04). But it conflicts with snd_es1968, ALSA driver for the sound
chip itself.

If one driver is loaded, the other one does not work - because a driver is
already registered for the PCI device (there is only one). This was probably
broken by conversion of PCI probing in 2006:
ttp://lkml.org/lkml/2005/12/31/93

How to fix it properly? Include radio functionality in snd-es1968 and delete
radio-maestro?

--
Ondrej Zary


2011-03-12 18:53:23

by Hans Verkuil

[permalink] [raw]
Subject: Re: radio-maestro broken (conflicts with snd-es1968)

On Saturday, March 12, 2011 19:19:00 Ondrej Zary wrote:
> Hello,
> the radio-maestro driver is badly broken. It's intended to drive the radio on
> MediaForte ESS Maestro-based sound cards with integrated radio (like
> SF64-PCE2-04). But it conflicts with snd_es1968, ALSA driver for the sound
> chip itself.
>
> If one driver is loaded, the other one does not work - because a driver is
> already registered for the PCI device (there is only one). This was probably
> broken by conversion of PCI probing in 2006:
> ttp://lkml.org/lkml/2005/12/31/93
>
> How to fix it properly? Include radio functionality in snd-es1968 and delete
> radio-maestro?

Interesting. I don't know anyone among the video4linux developers who has
this hardware, so the radio-maestro driver hasn't been tested in at least
6 or 7 years.

The proper fix would be to do it like the fm801.c alsa driver does: have
the radio functionality as an i2c driver. In fact, it would not surprise
me at all if you could use the tea575x-tuner.c driver (in sound/i2c/other)
for the es1968 and delete the radio-maestro altogether.

Both are for the tea575x tuner, although radio-maestro seems to have better
support for the g_tuner operation. It doesn't seem difficult to add that to
tea575x-tuner.c.

The fm801 code for driving the tea575x is pretty horrible and it should be
possible to improve that. I suspect that those read/write/mute functions
really belong in tea575x-tuner.c and that only the low-level gpio actions
need to be in the fm801/es1968 drivers.

Hope this helps.

Regards,

Hans

BTW: if anyone has spare hardware for testing the radio-maestro/tea575x-tuner,
then I'm interested.

--
Hans Verkuil - video4linux developer - sponsored by Cisco

2011-03-14 09:46:22

by Takashi Iwai

[permalink] [raw]
Subject: Re: [alsa-devel] radio-maestro broken (conflicts with snd-es1968)

At Sat, 12 Mar 2011 19:19:00 +0100,
Ondrej Zary wrote:
>
> Hello,
> the radio-maestro driver is badly broken. It's intended to drive the radio on
> MediaForte ESS Maestro-based sound cards with integrated radio (like
> SF64-PCE2-04). But it conflicts with snd_es1968, ALSA driver for the sound
> chip itself.
>
> If one driver is loaded, the other one does not work - because a driver is
> already registered for the PCI device (there is only one). This was probably
> broken by conversion of PCI probing in 2006:
> ttp://lkml.org/lkml/2005/12/31/93
>
> How to fix it properly? Include radio functionality in snd-es1968 and delete
> radio-maestro?

Yes.


Takashi

2011-03-14 09:53:37

by Takashi Iwai

[permalink] [raw]
Subject: Re: [alsa-devel] radio-maestro broken (conflicts with snd-es1968)

At Sat, 12 Mar 2011 19:52:39 +0100,
Hans Verkuil wrote:
>
> On Saturday, March 12, 2011 19:19:00 Ondrej Zary wrote:
> > Hello,
> > the radio-maestro driver is badly broken. It's intended to drive the radio on
> > MediaForte ESS Maestro-based sound cards with integrated radio (like
> > SF64-PCE2-04). But it conflicts with snd_es1968, ALSA driver for the sound
> > chip itself.
> >
> > If one driver is loaded, the other one does not work - because a driver is
> > already registered for the PCI device (there is only one). This was probably
> > broken by conversion of PCI probing in 2006:
> > ttp://lkml.org/lkml/2005/12/31/93
> >
> > How to fix it properly? Include radio functionality in snd-es1968 and delete
> > radio-maestro?
>
> Interesting. I don't know anyone among the video4linux developers who has
> this hardware, so the radio-maestro driver hasn't been tested in at least
> 6 or 7 years.
>
> The proper fix would be to do it like the fm801.c alsa driver does: have
> the radio functionality as an i2c driver. In fact, it would not surprise
> me at all if you could use the tea575x-tuner.c driver (in sound/i2c/other)
> for the es1968 and delete the radio-maestro altogether.

I guess simply porting radio-maestro codes into snd-es1968 would work
without much hustles, and it's a bit safe way to go for now; smaller
changes have less chance for breakage, and as little people seem using
this driver, it'd be better to take a safer option, IMO.

If we have active testers for both devices, it's nicer to go forward
to clean-up works indeed, though.


thanks,

Takashi

> Both are for the tea575x tuner, although radio-maestro seems to have better
> support for the g_tuner operation. It doesn't seem difficult to add that to
> tea575x-tuner.c.
>
> The fm801 code for driving the tea575x is pretty horrible and it should be
> possible to improve that. I suspect that those read/write/mute functions
> really belong in tea575x-tuner.c and that only the low-level gpio actions
> need to be in the fm801/es1968 drivers.
>
> Hope this helps.
>
> Regards,
>
> Hans
>
> BTW: if anyone has spare hardware for testing the radio-maestro/tea575x-tuner,
> then I'm interested.
>
> --
> Hans Verkuil - video4linux developer - sponsored by Cisco
> _______________________________________________
> Alsa-devel mailing list
> [email protected]
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
>

2011-03-14 09:59:54

by Hans Verkuil

[permalink] [raw]
Subject: Re: [alsa-devel] radio-maestro broken (conflicts with snd-es1968)

> At Sat, 12 Mar 2011 19:52:39 +0100,
> Hans Verkuil wrote:
>>
>> On Saturday, March 12, 2011 19:19:00 Ondrej Zary wrote:
>> > Hello,
>> > the radio-maestro driver is badly broken. It's intended to drive the
>> radio on
>> > MediaForte ESS Maestro-based sound cards with integrated radio (like
>> > SF64-PCE2-04). But it conflicts with snd_es1968, ALSA driver for the
>> sound
>> > chip itself.
>> >
>> > If one driver is loaded, the other one does not work - because a
>> driver is
>> > already registered for the PCI device (there is only one). This was
>> probably
>> > broken by conversion of PCI probing in 2006:
>> > ttp://lkml.org/lkml/2005/12/31/93
>> >
>> > How to fix it properly? Include radio functionality in snd-es1968 and
>> delete
>> > radio-maestro?
>>
>> Interesting. I don't know anyone among the video4linux developers who
>> has
>> this hardware, so the radio-maestro driver hasn't been tested in at
>> least
>> 6 or 7 years.
>>
>> The proper fix would be to do it like the fm801.c alsa driver does: have
>> the radio functionality as an i2c driver. In fact, it would not surprise
>> me at all if you could use the tea575x-tuner.c driver (in
>> sound/i2c/other)
>> for the es1968 and delete the radio-maestro altogether.
>
> I guess simply porting radio-maestro codes into snd-es1968 would work
> without much hustles, and it's a bit safe way to go for now; smaller
> changes have less chance for breakage, and as little people seem using
> this driver, it'd be better to take a safer option, IMO.

I assume someone has hardware since someone reported this breakage. So try
to use tuner-tea575x for the es1968. It shouldn't be too difficult.
Additional cleanup should probably wait until we find a tester for the
fm801 as well.

I don't like the idea to duplicate code.

Regards,

Hans

> If we have active testers for both devices, it's nicer to go forward
> to clean-up works indeed, though.
>
>
> thanks,
>
> Takashi
>
>> Both are for the tea575x tuner, although radio-maestro seems to have
>> better
>> support for the g_tuner operation. It doesn't seem difficult to add that
>> to
>> tea575x-tuner.c.
>>
>> The fm801 code for driving the tea575x is pretty horrible and it should
>> be
>> possible to improve that. I suspect that those read/write/mute functions
>> really belong in tea575x-tuner.c and that only the low-level gpio
>> actions
>> need to be in the fm801/es1968 drivers.
>>
>> Hope this helps.
>>
>> Regards,
>>
>> Hans
>>
>> BTW: if anyone has spare hardware for testing the
>> radio-maestro/tea575x-tuner,
>> then I'm interested.
>>
>> --
>> Hans Verkuil - video4linux developer - sponsored by Cisco
>> _______________________________________________
>> Alsa-devel mailing list
>> [email protected]
>> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
>>
>


--
Hans Verkuil - video4linux developer - sponsored by Cisco

2011-03-14 10:08:37

by Takashi Iwai

[permalink] [raw]
Subject: Re: [alsa-devel] radio-maestro broken (conflicts with snd-es1968)

At Mon, 14 Mar 2011 10:59:47 +0100,
Hans Verkuil wrote:
>
> > At Sat, 12 Mar 2011 19:52:39 +0100,
> > Hans Verkuil wrote:
> >>
> >> On Saturday, March 12, 2011 19:19:00 Ondrej Zary wrote:
> >> > Hello,
> >> > the radio-maestro driver is badly broken. It's intended to drive the
> >> radio on
> >> > MediaForte ESS Maestro-based sound cards with integrated radio (like
> >> > SF64-PCE2-04). But it conflicts with snd_es1968, ALSA driver for the
> >> sound
> >> > chip itself.
> >> >
> >> > If one driver is loaded, the other one does not work - because a
> >> driver is
> >> > already registered for the PCI device (there is only one). This was
> >> probably
> >> > broken by conversion of PCI probing in 2006:
> >> > ttp://lkml.org/lkml/2005/12/31/93
> >> >
> >> > How to fix it properly? Include radio functionality in snd-es1968 and
> >> delete
> >> > radio-maestro?
> >>
> >> Interesting. I don't know anyone among the video4linux developers who
> >> has
> >> this hardware, so the radio-maestro driver hasn't been tested in at
> >> least
> >> 6 or 7 years.
> >>
> >> The proper fix would be to do it like the fm801.c alsa driver does: have
> >> the radio functionality as an i2c driver. In fact, it would not surprise
> >> me at all if you could use the tea575x-tuner.c driver (in
> >> sound/i2c/other)
> >> for the es1968 and delete the radio-maestro altogether.
> >
> > I guess simply porting radio-maestro codes into snd-es1968 would work
> > without much hustles, and it's a bit safe way to go for now; smaller
> > changes have less chance for breakage, and as little people seem using
> > this driver, it'd be better to take a safer option, IMO.
>
> I assume someone has hardware since someone reported this breakage. So try
> to use tuner-tea575x for the es1968. It shouldn't be too difficult.

We can try at least, yes...

> Additional cleanup should probably wait until we find a tester for the
> fm801 as well.

My concern is that having both testers might be not easy, if we need
to change something in tea575-tuner side.
(We have already the same code, so porting it doesn't increase the code
size :) Anyway I agree to unify in a long term. Let's see whether
tea-575x works as is.


thanks,

Takashi

> I don't like the idea to duplicate code.
>
> Regards,
>
> Hans
>
> > If we have active testers for both devices, it's nicer to go forward
> > to clean-up works indeed, though.
> >
> >
> > thanks,
> >
> > Takashi
> >
> >> Both are for the tea575x tuner, although radio-maestro seems to have
> >> better
> >> support for the g_tuner operation. It doesn't seem difficult to add that
> >> to
> >> tea575x-tuner.c.
> >>
> >> The fm801 code for driving the tea575x is pretty horrible and it should
> >> be
> >> possible to improve that. I suspect that those read/write/mute functions
> >> really belong in tea575x-tuner.c and that only the low-level gpio
> >> actions
> >> need to be in the fm801/es1968 drivers.
> >>
> >> Hope this helps.
> >>
> >> Regards,
> >>
> >> Hans
> >>
> >> BTW: if anyone has spare hardware for testing the
> >> radio-maestro/tea575x-tuner,
> >> then I'm interested.
> >>
> >> --
> >> Hans Verkuil - video4linux developer - sponsored by Cisco
> >> _______________________________________________
> >> Alsa-devel mailing list
> >> [email protected]
> >> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
> >>
> >
>
>
> --
> Hans Verkuil - video4linux developer - sponsored by Cisco
>

2011-03-14 10:28:16

by Ondrej Zary

[permalink] [raw]
Subject: Re: [alsa-devel] radio-maestro broken (conflicts with snd-es1968)

On Monday 14 March 2011, Hans Verkuil wrote:
> > At Sat, 12 Mar 2011 19:52:39 +0100,
> >
> > Hans Verkuil wrote:
> >> On Saturday, March 12, 2011 19:19:00 Ondrej Zary wrote:
> >> > Hello,
> >> > the radio-maestro driver is badly broken. It's intended to drive the
> >>
> >> radio on
> >>
> >> > MediaForte ESS Maestro-based sound cards with integrated radio (like
> >> > SF64-PCE2-04). But it conflicts with snd_es1968, ALSA driver for the
> >>
> >> sound
> >>
> >> > chip itself.
> >> >
> >> > If one driver is loaded, the other one does not work - because a
> >>
> >> driver is
> >>
> >> > already registered for the PCI device (there is only one). This was
> >>
> >> probably
> >>
> >> > broken by conversion of PCI probing in 2006:
> >> > ttp://lkml.org/lkml/2005/12/31/93
> >> >
> >> > How to fix it properly? Include radio functionality in snd-es1968 and
> >>
> >> delete
> >>
> >> > radio-maestro?
> >>
> >> Interesting. I don't know anyone among the video4linux developers who
> >> has
> >> this hardware, so the radio-maestro driver hasn't been tested in at
> >> least
> >> 6 or 7 years.
> >>
> >> The proper fix would be to do it like the fm801.c alsa driver does: have
> >> the radio functionality as an i2c driver. In fact, it would not surprise
> >> me at all if you could use the tea575x-tuner.c driver (in
> >> sound/i2c/other)
> >> for the es1968 and delete the radio-maestro altogether.
> >
> > I guess simply porting radio-maestro codes into snd-es1968 would work
> > without much hustles, and it's a bit safe way to go for now; smaller
> > changes have less chance for breakage, and as little people seem using
> > this driver, it'd be better to take a safer option, IMO.
>
> I assume someone has hardware since someone reported this breakage. So try
> to use tuner-tea575x for the es1968. It shouldn't be too difficult.
> Additional cleanup should probably wait until we find a tester for the
> fm801 as well.

I have the hardware - both ES1968 (SF64-PCE2-04) and FM801 cards (SF64-PCR)
with these tuners. I remember fixing mute in tea5757x-tuner back in 2009
(testing it on SF64-PCR).

> I don't like the idea to duplicate code.

I don't like that either. I've done a quick hack - copied radio support from
fm801 and radio_bits_get() and radio_bits_set() from radio-maestro to es1968
and it seems to basically work.
Now I just need some more time to finish it, then move everything good from
radio-maestro to tea575x-tuner and delete radio-maestro.

IIRC, the TEA5757 tuner is also present on at least one ISA radio card -
SF16-FMR2 (which I also have).

--
Ondrej Zary

2011-03-14 10:29:28

by Takashi Iwai

[permalink] [raw]
Subject: Re: [alsa-devel] radio-maestro broken (conflicts with snd-es1968)

At Mon, 14 Mar 2011 11:28:01 +0100,
Ondrej Zary wrote:
>
> On Monday 14 March 2011, Hans Verkuil wrote:
> > > At Sat, 12 Mar 2011 19:52:39 +0100,
> > >
> > > Hans Verkuil wrote:
> > >> On Saturday, March 12, 2011 19:19:00 Ondrej Zary wrote:
> > >> > Hello,
> > >> > the radio-maestro driver is badly broken. It's intended to drive the
> > >>
> > >> radio on
> > >>
> > >> > MediaForte ESS Maestro-based sound cards with integrated radio (like
> > >> > SF64-PCE2-04). But it conflicts with snd_es1968, ALSA driver for the
> > >>
> > >> sound
> > >>
> > >> > chip itself.
> > >> >
> > >> > If one driver is loaded, the other one does not work - because a
> > >>
> > >> driver is
> > >>
> > >> > already registered for the PCI device (there is only one). This was
> > >>
> > >> probably
> > >>
> > >> > broken by conversion of PCI probing in 2006:
> > >> > ttp://lkml.org/lkml/2005/12/31/93
> > >> >
> > >> > How to fix it properly? Include radio functionality in snd-es1968 and
> > >>
> > >> delete
> > >>
> > >> > radio-maestro?
> > >>
> > >> Interesting. I don't know anyone among the video4linux developers who
> > >> has
> > >> this hardware, so the radio-maestro driver hasn't been tested in at
> > >> least
> > >> 6 or 7 years.
> > >>
> > >> The proper fix would be to do it like the fm801.c alsa driver does: have
> > >> the radio functionality as an i2c driver. In fact, it would not surprise
> > >> me at all if you could use the tea575x-tuner.c driver (in
> > >> sound/i2c/other)
> > >> for the es1968 and delete the radio-maestro altogether.
> > >
> > > I guess simply porting radio-maestro codes into snd-es1968 would work
> > > without much hustles, and it's a bit safe way to go for now; smaller
> > > changes have less chance for breakage, and as little people seem using
> > > this driver, it'd be better to take a safer option, IMO.
> >
> > I assume someone has hardware since someone reported this breakage. So try
> > to use tuner-tea575x for the es1968. It shouldn't be too difficult.
> > Additional cleanup should probably wait until we find a tester for the
> > fm801 as well.
>
> I have the hardware - both ES1968 (SF64-PCE2-04) and FM801 cards (SF64-PCR)
> with these tuners. I remember fixing mute in tea5757x-tuner back in 2009
> (testing it on SF64-PCR).
>
> > I don't like the idea to duplicate code.
>
> I don't like that either. I've done a quick hack - copied radio support from
> fm801 and radio_bits_get() and radio_bits_set() from radio-maestro to es1968
> and it seems to basically work.
> Now I just need some more time to finish it, then move everything good from
> radio-maestro to tea575x-tuner and delete radio-maestro.

Great!


Takashi

2011-03-14 11:57:34

by Hans Verkuil

[permalink] [raw]
Subject: Re: [alsa-devel] radio-maestro broken (conflicts with snd-es1968)

> On Monday 14 March 2011, Hans Verkuil wrote:
>> > At Sat, 12 Mar 2011 19:52:39 +0100,
>> >
>> > Hans Verkuil wrote:
>> >> On Saturday, March 12, 2011 19:19:00 Ondrej Zary wrote:
>> >> > Hello,
>> >> > the radio-maestro driver is badly broken. It's intended to drive
>> the
>> >>
>> >> radio on
>> >>
>> >> > MediaForte ESS Maestro-based sound cards with integrated radio
>> (like
>> >> > SF64-PCE2-04). But it conflicts with snd_es1968, ALSA driver for
>> the
>> >>
>> >> sound
>> >>
>> >> > chip itself.
>> >> >
>> >> > If one driver is loaded, the other one does not work - because a
>> >>
>> >> driver is
>> >>
>> >> > already registered for the PCI device (there is only one). This was
>> >>
>> >> probably
>> >>
>> >> > broken by conversion of PCI probing in 2006:
>> >> > ttp://lkml.org/lkml/2005/12/31/93
>> >> >
>> >> > How to fix it properly? Include radio functionality in snd-es1968
>> and
>> >>
>> >> delete
>> >>
>> >> > radio-maestro?
>> >>
>> >> Interesting. I don't know anyone among the video4linux developers who
>> >> has
>> >> this hardware, so the radio-maestro driver hasn't been tested in at
>> >> least
>> >> 6 or 7 years.
>> >>
>> >> The proper fix would be to do it like the fm801.c alsa driver does:
>> have
>> >> the radio functionality as an i2c driver. In fact, it would not
>> surprise
>> >> me at all if you could use the tea575x-tuner.c driver (in
>> >> sound/i2c/other)
>> >> for the es1968 and delete the radio-maestro altogether.
>> >
>> > I guess simply porting radio-maestro codes into snd-es1968 would work
>> > without much hustles, and it's a bit safe way to go for now; smaller
>> > changes have less chance for breakage, and as little people seem using
>> > this driver, it'd be better to take a safer option, IMO.
>>
>> I assume someone has hardware since someone reported this breakage. So
>> try
>> to use tuner-tea575x for the es1968. It shouldn't be too difficult.
>> Additional cleanup should probably wait until we find a tester for the
>> fm801 as well.
>
> I have the hardware - both ES1968 (SF64-PCE2-04) and FM801 cards
> (SF64-PCR)
> with these tuners. I remember fixing mute in tea5757x-tuner back in 2009
> (testing it on SF64-PCR).
>
>> I don't like the idea to duplicate code.
>
> I don't like that either. I've done a quick hack - copied radio support
> from
> fm801 and radio_bits_get() and radio_bits_set() from radio-maestro to
> es1968
> and it seems to basically work.
> Now I just need some more time to finish it, then move everything good
> from
> radio-maestro to tea575x-tuner and delete radio-maestro.

Great! Let me know if you have any v4l-related questions!

>
> IIRC, the TEA5757 tuner is also present on at least one ISA radio card -
> SF16-FMR2 (which I also have).

Interesting. I have a bunch of isa radio cards myself and I am planning a
major cleanup of those isa drivers. I might get back to you for testing.

Regards,

Hans

>
> --
> Ondrej Zary
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>


--
Hans Verkuil - video4linux developer - sponsored by Cisco

2011-03-19 15:33:18

by Ondrej Zary

[permalink] [raw]
Subject: [RFC PATCH 2/3] tea575x-tuner: remove dev_nr

Remove unused dev_nr from struct tea575x_tuner.

Signed-off-by: Ondrej Zary <[email protected]>

--- linux-2.6.38-rc4-/include/sound/tea575x-tuner.h 2011-03-19 16:00:53.000000000 +0100
+++ linux-2.6.38-rc4/include/sound/tea575x-tuner.h 2011-03-19 16:01:12.000000000 +0100
@@ -37,7 +37,6 @@ struct snd_tea575x_ops {
struct snd_tea575x {
struct snd_card *card;
struct video_device *vd; /* video device */
- int dev_nr; /* requested device number + 1 */
bool tea5759; /* 5759 chip is present */
bool mute; /* Device is muted? */
bool stereo; /* receiving stereo */
--- linux-2.6.38-rc4-/sound/pci/fm801.c 2011-02-08 01:03:55.000000000 +0100
+++ linux-2.6.38-rc4/sound/pci/fm801.c 2011-03-19 16:02:33.000000000 +0100
@@ -1453,7 +1453,6 @@ static int __devinit snd_fm801_create(st
#ifdef TEA575X_RADIO
if ((tea575x_tuner & TUNER_TYPE_MASK) > 0 &&
(tea575x_tuner & TUNER_TYPE_MASK) < 4) {
- chip->tea.dev_nr = tea575x_tuner >> 16;
chip->tea.card = card;
chip->tea.freq_fixup = 10700;
chip->tea.private_data = chip;


--
Ondrej Zary

2011-03-19 15:33:17

by Ondrej Zary

[permalink] [raw]
Subject: [RFC PATCH 1/3] tea575x-tuner: various improvements

Improve tea575x-tuner with various good things from radio-maestro:
- extend frequency range to 50-150MHz
- fix querycap(): card name, CAP_RADIO
- improve g_tuner(): CAP_STEREO, stereo and tuned indication
- improve g_frequency(): tuner index checking and reading frequency from HW
- improve s_frequency(): tuner index and type checking

Signed-off-by: Ondrej Zary <[email protected]>

--- linux-2.6.38-rc4-orig/sound/i2c/other/tea575x-tuner.c 2011-02-08 01:03:55.000000000 +0100
+++ linux-2.6.38-rc4/sound/i2c/other/tea575x-tuner.c 2011-03-19 15:40:14.000000000 +0100
@@ -37,8 +37,8 @@ static int radio_nr = -1;
module_param(radio_nr, int, 0);

#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
-#define FREQ_LO (87 * 16000)
-#define FREQ_HI (108 * 16000)
+#define FREQ_LO (50UL * 16000)
+#define FREQ_HI (150UL * 16000)

/*
* definitions
@@ -77,15 +77,29 @@ static struct v4l2_queryctrl radio_qctrl
* lowlevel part
*/

+static void snd_tea575x_get_freq(struct snd_tea575x *tea)
+{
+ unsigned long freq;
+
+ freq = tea->ops->read(tea) & TEA575X_BIT_FREQ_MASK;
+ /* freq *= 12.5 */
+ freq *= 125;
+ freq /= 10;
+ /* crystal fixup */
+ if (tea->tea5759)
+ freq += tea->freq_fixup;
+ else
+ freq -= tea->freq_fixup;
+
+ tea->freq = freq * 16; /* from kHz */
+}
+
static void snd_tea575x_set_freq(struct snd_tea575x *tea)
{
unsigned long freq;

- freq = tea->freq / 16; /* to kHz */
- if (freq > 108000)
- freq = 108000;
- if (freq < 87000)
- freq = 87000;
+ freq = clamp(tea->freq, FREQ_LO, FREQ_HI);
+ freq /= 16; /* to kHz */
/* crystal fixup */
if (tea->tea5759)
freq -= tea->freq_fixup;
@@ -109,29 +123,33 @@ static int vidioc_querycap(struct file *
{
struct snd_tea575x *tea = video_drvdata(file);

- strcpy(v->card, tea->tea5759 ? "TEA5759" : "TEA5757");
strlcpy(v->driver, "tea575x-tuner", sizeof(v->driver));
- strlcpy(v->card, "Maestro Radio", sizeof(v->card));
+ strlcpy(v->card, tea->tea5759 ? "TEA5759" : "TEA5757", sizeof(v->card));
sprintf(v->bus_info, "PCI");
v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
}

static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
+ struct snd_tea575x *tea = video_drvdata(file);
+
if (v->index > 0)
return -EINVAL;

+ tea->ops->read(tea);
+
strcpy(v->name, "FM");
v->type = V4L2_TUNER_RADIO;
+ v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
v->rangelow = FREQ_LO;
v->rangehigh = FREQ_HI;
- v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
- v->capability = V4L2_TUNER_CAP_LOW;
- v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal = 0xffff;
+ v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
+ v->audmode = tea->stereo ? V4L2_TUNER_MODE_STEREO : V4L2_TUNER_MODE_MONO;
+ v->signal = tea->tuned ? 0xffff : 0;
+
return 0;
}

@@ -148,7 +166,10 @@ static int vidioc_g_frequency(struct fil
{
struct snd_tea575x *tea = video_drvdata(file);

+ if (f->tuner != 0)
+ return -EINVAL;
f->type = V4L2_TUNER_RADIO;
+ snd_tea575x_get_freq(tea);
f->frequency = tea->freq;
return 0;
}
@@ -158,6 +179,9 @@ static int vidioc_s_frequency(struct fil
{
struct snd_tea575x *tea = video_drvdata(file);

+ if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
+ return -EINVAL;
+
if (f->frequency < FREQ_LO || f->frequency > FREQ_HI)
return -EINVAL;

--- linux-2.6.38-rc4-orig/include/sound/tea575x-tuner.h 2011-02-08 01:03:55.000000000 +0100
+++ linux-2.6.38-rc4/include/sound/tea575x-tuner.h 2011-03-19 14:18:06.000000000 +0100
@@ -38,8 +38,10 @@ struct snd_tea575x {
struct snd_card *card;
struct video_device *vd; /* video device */
int dev_nr; /* requested device number + 1 */
- int tea5759; /* 5759 chip is present */
- int mute; /* Device is muted? */
+ bool tea5759; /* 5759 chip is present */
+ bool mute; /* Device is muted? */
+ bool stereo; /* receiving stereo */
+ bool tuned; /* tuned to a station */
unsigned int freq_fixup; /* crystal onboard */
unsigned int val; /* hw value */
unsigned long freq; /* frequency */


--
Ondrej Zary

2011-03-19 15:33:27

by Ondrej Zary

[permalink] [raw]
Subject: [RFC PATCH 3/3] es1968: add radio (tea575x tuner) support

Add TEA5757 radio tuner support to es1968 driver. This is found at least on
MediaForte SF64-PCE2 sound cards.

Signed-off-by: Ondrej Zary <[email protected]>

diff -urp linux-2.6.38-rc4-orig/sound/pci/es1968.c linux-2.6.38-rc4/sound/pci/es1968.c
--- linux-2.6.38-rc4-orig/sound/pci/es1968.c 2011-02-08 01:03:55.000000000 +0100
+++ linux-2.6.38-rc4/sound/pci/es1968.c 2011-03-18 22:51:48.000000000 +0100
@@ -112,6 +112,10 @@
#include <sound/ac97_codec.h>
#include <sound/initval.h>

+#ifdef CONFIG_SND_ES1968_RADIO
+#include <sound/tea575x-tuner.h>
+#endif
+
#define CARD_NAME "ESS Maestro1/2"
#define DRIVER_NAME "ES1968"

@@ -553,6 +557,10 @@ struct es1968 {
spinlock_t ac97_lock;
struct tasklet_struct hwvol_tq;
#endif
+
+#ifdef CONFIG_SND_ES1968_RADIO
+ struct snd_tea575x tea;
+#endif
};

static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id);
@@ -2571,6 +2579,111 @@ static int __devinit snd_es1968_input_re
}
#endif /* CONFIG_SND_ES1968_INPUT */

+#ifdef CONFIG_SND_ES1968_RADIO
+#define GPIO_DATA 0x60
+#define IO_MASK 4 /* mask register offset from GPIO_DATA
+ bits 1=unmask write to given bit */
+#define IO_DIR 8 /* direction register offset from GPIO_DATA
+ bits 0/1=read/write direction */
+/* mask bits for GPIO lines */
+#define STR_DATA 0x0040 /* GPIO6 */
+#define STR_CLK 0x0080 /* GPIO7 */
+#define STR_WREN 0x0100 /* GPIO8 */
+#define STR_MOST 0x0200 /* GPIO9 */
+
+static void snd_es1968_tea575x_write(struct snd_tea575x *tea, unsigned int val)
+{
+ struct es1968 *chip = tea->private_data;
+ unsigned long io = chip->io_port + GPIO_DATA;
+ u16 l, bits;
+ u16 omask, odir;
+
+ omask = inw(io + IO_MASK);
+ odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN);
+ outw(odir | STR_DATA, io + IO_DIR);
+ outw(~(STR_DATA | STR_CLK | STR_WREN), io + IO_MASK);
+ udelay(16);
+
+ for (l = 25; l; l--) {
+ bits = ((val >> 18) & STR_DATA) | STR_WREN;
+ val <<= 1; /* shift data */
+ outw(bits, io); /* start strobe */
+ udelay(2);
+ outw(bits | STR_CLK, io); /* HI level */
+ udelay(2);
+ outw(bits, io); /* LO level */
+ udelay(4);
+ }
+
+ if (!tea->mute)
+ outw(0, io);
+
+ udelay(4);
+ outw(omask, io + IO_MASK);
+ outw(odir, io + IO_DIR);
+ msleep(125);
+}
+
+static unsigned int snd_es1968_tea575x_read(struct snd_tea575x *tea)
+{
+ struct es1968 *chip = tea->private_data;
+ unsigned long io = chip->io_port + GPIO_DATA;
+ u16 l, rdata;
+ u32 data = 0;
+ u16 omask;
+
+ omask = inw(io + IO_MASK);
+ outw(~(STR_CLK | STR_WREN), io + IO_MASK);
+ outw(0, io);
+ udelay(16);
+
+ for (l = 24; l--;) {
+ outw(STR_CLK, io); /* HI state */
+ udelay(2);
+ if (!l)
+ tea->tuned = inw(io) & STR_MOST ? 0 : 1;
+ outw(0, io); /* LO state */
+ udelay(2);
+ data <<= 1; /* shift data */
+ rdata = inw(io);
+ if (!l)
+ tea->stereo = (rdata & STR_MOST) ? 0 : 1;
+ else if (l && rdata & STR_DATA)
+ data++;
+ udelay(2);
+ }
+
+ if (tea->mute)
+ outw(STR_WREN, io);
+
+ udelay(4);
+ outw(omask, io + IO_MASK);
+
+ return data & 0x3ffe;
+}
+
+static void snd_es1968_tea575x_mute(struct snd_tea575x *tea, unsigned int mute)
+{
+ struct es1968 *chip = tea->private_data;
+ unsigned long io = chip->io_port + GPIO_DATA;
+ u16 omask;
+
+ omask = inw(io + IO_MASK);
+ outw(~STR_WREN, io + IO_MASK);
+ tea->mute = mute;
+ outw(tea->mute ? STR_WREN : 0, io);
+ udelay(4);
+ outw(omask, io + IO_MASK);
+ msleep(125);
+}
+
+static struct snd_tea575x_ops snd_es1968_tea_ops = {
+ .write = snd_es1968_tea575x_write,
+ .read = snd_es1968_tea575x_read,
+ .mute = snd_es1968_tea575x_mute,
+};
+#endif
+
static int snd_es1968_free(struct es1968 *chip)
{
#ifdef CONFIG_SND_ES1968_INPUT
@@ -2585,6 +2698,10 @@ static int snd_es1968_free(struct es1968
outw(0, chip->io_port + ESM_PORT_HOST_IRQ); /* disable IRQ */
}

+#ifdef CONFIG_SND_ES1968_RADIO
+ snd_tea575x_exit(&chip->tea);
+#endif
+
if (chip->irq >= 0)
free_irq(chip->irq, chip);
snd_es1968_free_gameport(chip);
@@ -2723,6 +2840,14 @@ static int __devinit snd_es1968_create(s

snd_card_set_dev(card, &pci->dev);

+#ifdef CONFIG_SND_ES1968_RADIO
+ chip->tea.card = card;
+ chip->tea.freq_fixup = 10700;
+ chip->tea.private_data = chip;
+ chip->tea.ops = &snd_es1968_tea_ops;
+ snd_tea575x_init(&chip->tea);
+#endif
+
*chip_ret = chip;

return 0;
diff -urp linux-2.6.38-rc4-orig/sound/pci/Kconfig linux-2.6.38-rc4/sound/pci/Kconfig
--- linux-2.6.38-rc4-orig/sound/pci/Kconfig 2011-02-08 01:03:55.000000000 +0100
+++ linux-2.6.38-rc4/sound/pci/Kconfig 2011-03-13 00:01:26.000000000 +0100
@@ -528,6 +528,14 @@ config SND_ES1968_INPUT
If you say N the buttons will directly control the master volume.
It is recommended to say Y.

+config SND_ES1968_RADIO
+ bool "Enable TEA5757 radio tuner support for es1968"
+ depends on SND_ES1968
+ depends on VIDEO_V4L2=y || VIDEO_V4L2=SND_ES1968
+ help
+ Say Y here to include support for TEA5757 radio tuner integrated on
+ some MediaForte cards (e.g. SF64-PCE2).
+
config SND_FM801
tristate "ForteMedia FM801"
select SND_OPL3_LIB
@@ -549,10 +557,10 @@ config SND_FM801_TEA575X_BOOL
FM801 chip with a TEA5757 tuner connected to GPIO1-3 pins (Media
Forte SF256-PCS-02) into the snd-fm801 driver.

-config SND_FM801_TEA575X
+config SND_TEA575X
tristate
- depends on SND_FM801_TEA575X_BOOL
- default SND_FM801
+ depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO
+ default SND_FM801 || SND_ES1968

source "sound/pci/hda/Kconfig"

diff -urp linux-2.6.38-rc4-orig/sound/i2c/other/Makefile linux-2.6.38-rc4/sound/i2c/other/Makefile
--- linux-2.6.38-rc4-orig/sound/i2c/other/Makefile 2011-02-08 01:03:55.000000000 +0100
+++ linux-2.6.38-rc4/sound/i2c/other/Makefile 2011-03-12 23:59:37.000000000 +0100
@@ -14,4 +14,4 @@ snd-tea575x-tuner-objs := tea575x-tuner.
obj-$(CONFIG_SND_PDAUDIOCF) += snd-ak4117.o
obj-$(CONFIG_SND_ICE1712) += snd-ak4xxx-adda.o
obj-$(CONFIG_SND_ICE1724) += snd-ak4114.o snd-ak4113.o snd-ak4xxx-adda.o snd-pt2258.o
-obj-$(CONFIG_SND_FM801_TEA575X) += snd-tea575x-tuner.o
+obj-$(CONFIG_SND_TEA575X) += snd-tea575x-tuner.o


--
Ondrej Zary

2011-03-19 16:24:03

by Ondrej Zary

[permalink] [raw]
Subject: [RFC PATCH 4/3] remove radio-maestro

Remove broken radio-maestro driver as the radio functionality is now
integrated in the es1968 driver.

Signed-off-by: Ondrej Zary <[email protected]>

diff -urNp linux-2.6.38-rc4-orig/drivers/media/radio/Kconfig linux-2.6.38-rc4/drivers/media/radio/Kconfig
--- linux-2.6.38-rc4-orig/drivers/media/radio/Kconfig 2011-02-08 01:03:55.000000000 +0100
+++ linux-2.6.38-rc4/drivers/media/radio/Kconfig 2011-03-19 17:12:32.000000000 +0100
@@ -166,21 +166,6 @@ config RADIO_MAXIRADIO
To compile this driver as a module, choose M here: the
module will be called radio-maxiradio.

-config RADIO_MAESTRO
- tristate "Maestro on board radio"
- depends on VIDEO_V4L2 && PCI
- ---help---
- Say Y here to directly support the on-board radio tuner on the
- Maestro 2 or 2E sound card.
-
- 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-maestro.
-
config RADIO_MIROPCM20
tristate "miroSOUND PCM20 radio"
depends on ISA && VIDEO_V4L2 && SND
diff -urNp linux-2.6.38-rc4-orig/drivers/media/radio/Makefile linux-2.6.38-rc4/drivers/media/radio/Makefile
--- linux-2.6.38-rc4-orig/drivers/media/radio/Makefile 2011-02-08 01:03:55.000000000 +0100
+++ linux-2.6.38-rc4/drivers/media/radio/Makefile 2011-03-19 17:12:39.000000000 +0100
@@ -16,7 +16,6 @@ obj-$(CONFIG_RADIO_GEMTEK) += radio-gemt
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/
diff -urNp linux-2.6.38-rc4-orig/drivers/media/radio/radio-maestro.c linux-2.6.38-rc4/drivers/media/radio/radio-maestro.c
--- linux-2.6.38-rc4-orig/drivers/media/radio/radio-maestro.c 2011-02-08 01:03:55.000000000 +0100
+++ linux-2.6.38-rc4/drivers/media/radio/radio-maestro.c 1970-01-01 01:00:00.000000000 +0100
@@ -1,452 +0,0 @@
-/* Maestro PCI sound card radio driver for Linux support
- * (c) 2000 A. Tlalka, [email protected]
- * Notes on the hardware
- *
- * + Frequency control is done digitally
- * + No volume control - only mute/unmute - you have to use Aux line volume
- * control on Maestro card to set the volume
- * + Radio status (tuned/not_tuned and stereo/mono) is valid some time after
- * frequency setting (>100ms) and only when the radio is unmuted.
- * version 0.02
- * + io port is automatically detected - only the first radio is used
- * version 0.03
- * + thread access locking additions
- * version 0.04
- * + code improvements
- * + VIDEO_TUNER_LOW is permanent
- *
- * Converted to V4L2 API by Mauro Carvalho Chehab <[email protected]>
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/version.h> /* for KERNEL_VERSION MACRO */
-#include <linux/pci.h>
-#include <linux/videodev2.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-
-MODULE_AUTHOR("Adam Tlalka, [email protected]");
-MODULE_DESCRIPTION("Radio driver for the Maestro PCI sound card radio.");
-MODULE_LICENSE("GPL");
-
-static int radio_nr = -1;
-module_param(radio_nr, int, 0);
-
-#define RADIO_VERSION KERNEL_VERSION(0, 0, 6)
-#define DRIVER_VERSION "0.06"
-
-#define GPIO_DATA 0x60 /* port offset from ESS_IO_BASE */
-
-#define IO_MASK 4 /* mask register offset from GPIO_DATA
- bits 1=unmask write to given bit */
-#define IO_DIR 8 /* direction register offset from GPIO_DATA
- bits 0/1=read/write direction */
-
-#define GPIO6 0x0040 /* mask bits for GPIO lines */
-#define GPIO7 0x0080
-#define GPIO8 0x0100
-#define GPIO9 0x0200
-
-#define STR_DATA GPIO6 /* radio TEA5757 pins and GPIO bits */
-#define STR_CLK GPIO7
-#define STR_WREN GPIO8
-#define STR_MOST GPIO9
-
-#define FREQ_LO 50*16000
-#define FREQ_HI 150*16000
-
-#define FREQ_IF 171200 /* 10.7*16000 */
-#define FREQ_STEP 200 /* 12.5*16 */
-
-#define FREQ2BITS(x) ((((unsigned int)(x)+FREQ_IF+(FREQ_STEP<<1))\
- /(FREQ_STEP<<2))<<2) /* (x==fmhz*16*1000) -> bits */
-
-#define BITS2FREQ(x) ((x) * FREQ_STEP - FREQ_IF)
-
-struct maestro {
- struct v4l2_device v4l2_dev;
- struct video_device vdev;
- struct pci_dev *pdev;
- struct mutex lock;
-
- u16 io; /* base of Maestro card radio io (GPIO_DATA)*/
- u16 muted; /* VIDEO_AUDIO_MUTE */
- u16 stereo; /* VIDEO_TUNER_STEREO_ON */
- u16 tuned; /* signal strength (0 or 0xffff) */
-};
-
-static inline struct maestro *to_maestro(struct v4l2_device *v4l2_dev)
-{
- return container_of(v4l2_dev, struct maestro, v4l2_dev);
-}
-
-static u32 radio_bits_get(struct maestro *dev)
-{
- u16 io = dev->io, l, rdata;
- u32 data = 0;
- u16 omask;
-
- omask = inw(io + IO_MASK);
- outw(~(STR_CLK | STR_WREN), io + IO_MASK);
- outw(0, io);
- udelay(16);
-
- for (l = 24; l--;) {
- outw(STR_CLK, io); /* HI state */
- udelay(2);
- if (!l)
- dev->tuned = inw(io) & STR_MOST ? 0 : 0xffff;
- outw(0, io); /* LO state */
- udelay(2);
- data <<= 1; /* shift data */
- rdata = inw(io);
- if (!l)
- dev->stereo = (rdata & STR_MOST) ? 0 : 1;
- else if (rdata & STR_DATA)
- data++;
- udelay(2);
- }
-
- if (dev->muted)
- outw(STR_WREN, io);
-
- udelay(4);
- outw(omask, io + IO_MASK);
-
- return data & 0x3ffe;
-}
-
-static void radio_bits_set(struct maestro *dev, u32 data)
-{
- u16 io = dev->io, l, bits;
- u16 omask, odir;
-
- omask = inw(io + IO_MASK);
- odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN);
- outw(odir | STR_DATA, io + IO_DIR);
- outw(~(STR_DATA | STR_CLK | STR_WREN), io + IO_MASK);
- udelay(16);
- for (l = 25; l; l--) {
- bits = ((data >> 18) & STR_DATA) | STR_WREN;
- data <<= 1; /* shift data */
- outw(bits, io); /* start strobe */
- udelay(2);
- outw(bits | STR_CLK, io); /* HI level */
- udelay(2);
- outw(bits, io); /* LO level */
- udelay(4);
- }
-
- if (!dev->muted)
- outw(0, io);
-
- udelay(4);
- outw(omask, io + IO_MASK);
- outw(odir, io + IO_DIR);
- msleep(125);
-}
-
-static int vidioc_querycap(struct file *file, void *priv,
- struct v4l2_capability *v)
-{
- struct maestro *dev = video_drvdata(file);
-
- strlcpy(v->driver, "radio-maestro", sizeof(v->driver));
- strlcpy(v->card, "Maestro Radio", sizeof(v->card));
- snprintf(v->bus_info, sizeof(v->bus_info), "PCI:%s", pci_name(dev->pdev));
- v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
- return 0;
-}
-
-static int vidioc_g_tuner(struct file *file, void *priv,
- struct v4l2_tuner *v)
-{
- struct maestro *dev = video_drvdata(file);
-
- if (v->index > 0)
- return -EINVAL;
-
- mutex_lock(&dev->lock);
- radio_bits_get(dev);
-
- strlcpy(v->name, "FM", sizeof(v->name));
- v->type = V4L2_TUNER_RADIO;
- v->rangelow = FREQ_LO;
- v->rangehigh = FREQ_HI;
- v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
- v->capability = V4L2_TUNER_CAP_LOW;
- if (dev->stereo)
- v->audmode = V4L2_TUNER_MODE_STEREO;
- else
- v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal = dev->tuned;
- mutex_unlock(&dev->lock);
- return 0;
-}
-
-static int vidioc_s_tuner(struct file *file, void *priv,
- struct v4l2_tuner *v)
-{
- return v->index ? -EINVAL : 0;
-}
-
-static int vidioc_s_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- struct maestro *dev = video_drvdata(file);
-
- if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
- return -EINVAL;
- if (f->frequency < FREQ_LO || f->frequency > FREQ_HI)
- return -EINVAL;
- mutex_lock(&dev->lock);
- radio_bits_set(dev, FREQ2BITS(f->frequency));
- mutex_unlock(&dev->lock);
- return 0;
-}
-
-static int vidioc_g_frequency(struct file *file, void *priv,
- struct v4l2_frequency *f)
-{
- struct maestro *dev = video_drvdata(file);
-
- if (f->tuner != 0)
- return -EINVAL;
- f->type = V4L2_TUNER_RADIO;
- mutex_lock(&dev->lock);
- f->frequency = BITS2FREQ(radio_bits_get(dev));
- mutex_unlock(&dev->lock);
- 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 maestro *dev = video_drvdata(file);
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- ctrl->value = dev->muted;
- return 0;
- }
- return -EINVAL;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- struct maestro *dev = video_drvdata(file);
- u16 io = dev->io;
- u16 omask;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- mutex_lock(&dev->lock);
- omask = inw(io + IO_MASK);
- outw(~STR_WREN, io + IO_MASK);
- dev->muted = ctrl->value;
- outw(dev->muted ? STR_WREN : 0, io);
- udelay(4);
- outw(omask, io + IO_MASK);
- msleep(125);
- mutex_unlock(&dev->lock);
- return 0;
- }
- return -EINVAL;
-}
-
-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_file_operations maestro_fops = {
- .owner = THIS_MODULE,
- .unlocked_ioctl = video_ioctl2,
-};
-
-static const struct v4l2_ioctl_ops maestro_ioctl_ops = {
- .vidioc_querycap = vidioc_querycap,
- .vidioc_g_tuner = vidioc_g_tuner,
- .vidioc_s_tuner = vidioc_s_tuner,
- .vidioc_g_audio = vidioc_g_audio,
- .vidioc_s_audio = vidioc_s_audio,
- .vidioc_g_input = vidioc_g_input,
- .vidioc_s_input = vidioc_s_input,
- .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,
-};
-
-static u16 __devinit radio_power_on(struct maestro *dev)
-{
- register u16 io = dev->io;
- register u32 ofreq;
- u16 omask, odir;
-
- omask = inw(io + IO_MASK);
- odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN);
- outw(odir & ~STR_WREN, io + IO_DIR);
- dev->muted = inw(io) & STR_WREN ? 0 : 1;
- outw(odir, io + IO_DIR);
- outw(~(STR_WREN | STR_CLK), io + IO_MASK);
- outw(dev->muted ? 0 : STR_WREN, io);
- udelay(16);
- outw(omask, io + IO_MASK);
- ofreq = radio_bits_get(dev);
-
- if ((ofreq < FREQ2BITS(FREQ_LO)) || (ofreq > FREQ2BITS(FREQ_HI)))
- ofreq = FREQ2BITS(FREQ_LO);
- radio_bits_set(dev, ofreq);
-
- return (ofreq == radio_bits_get(dev));
-}
-
-static int __devinit maestro_probe(struct pci_dev *pdev,
- const struct pci_device_id *ent)
-{
- struct maestro *dev;
- struct v4l2_device *v4l2_dev;
- int retval;
-
- retval = pci_enable_device(pdev);
- if (retval) {
- dev_err(&pdev->dev, "enabling pci device failed!\n");
- goto err;
- }
-
- retval = -ENOMEM;
-
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (dev == NULL) {
- dev_err(&pdev->dev, "not enough memory\n");
- goto err;
- }
-
- v4l2_dev = &dev->v4l2_dev;
- mutex_init(&dev->lock);
- dev->pdev = pdev;
-
- strlcpy(v4l2_dev->name, "maestro", sizeof(v4l2_dev->name));
-
- retval = v4l2_device_register(&pdev->dev, v4l2_dev);
- if (retval < 0) {
- v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
- goto errfr;
- }
-
- dev->io = pci_resource_start(pdev, 0) + GPIO_DATA;
-
- strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
- dev->vdev.v4l2_dev = v4l2_dev;
- dev->vdev.fops = &maestro_fops;
- dev->vdev.ioctl_ops = &maestro_ioctl_ops;
- dev->vdev.release = video_device_release_empty;
- video_set_drvdata(&dev->vdev, dev);
-
- if (!radio_power_on(dev)) {
- retval = -EIO;
- goto errfr1;
- }
-
- retval = video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr);
- if (retval) {
- v4l2_err(v4l2_dev, "can't register video device!\n");
- goto errfr1;
- }
-
- v4l2_info(v4l2_dev, "version " DRIVER_VERSION "\n");
-
- return 0;
-errfr1:
- v4l2_device_unregister(v4l2_dev);
-errfr:
- kfree(dev);
-err:
- return retval;
-
-}
-
-static void __devexit maestro_remove(struct pci_dev *pdev)
-{
- struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
- struct maestro *dev = to_maestro(v4l2_dev);
-
- video_unregister_device(&dev->vdev);
- v4l2_device_unregister(&dev->v4l2_dev);
-}
-
-static struct pci_device_id maestro_r_pci_tbl[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1968),
- .class = PCI_CLASS_MULTIMEDIA_AUDIO << 8,
- .class_mask = 0xffff00 },
- { PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1978),
- .class = PCI_CLASS_MULTIMEDIA_AUDIO << 8,
- .class_mask = 0xffff00 },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, maestro_r_pci_tbl);
-
-static struct pci_driver maestro_r_driver = {
- .name = "maestro_radio",
- .id_table = maestro_r_pci_tbl,
- .probe = maestro_probe,
- .remove = __devexit_p(maestro_remove),
-};
-
-static int __init maestro_radio_init(void)
-{
- int retval = pci_register_driver(&maestro_r_driver);
-
- if (retval)
- printk(KERN_ERR "error during registration pci driver\n");
-
- return retval;
-}
-
-static void __exit maestro_radio_exit(void)
-{
- pci_unregister_driver(&maestro_r_driver);
-}
-
-module_init(maestro_radio_init);
-module_exit(maestro_radio_exit);


--
Ondrej Zary

2011-03-21 11:48:33

by Takashi Iwai

[permalink] [raw]
Subject: Re: [RFC PATCH 1/3] tea575x-tuner: various improvements

At Sat, 19 Mar 2011 16:32:53 +0100,
Ondrej Zary wrote:
>
> Improve tea575x-tuner with various good things from radio-maestro:
> - extend frequency range to 50-150MHz
> - fix querycap(): card name, CAP_RADIO
> - improve g_tuner(): CAP_STEREO, stereo and tuned indication
> - improve g_frequency(): tuner index checking and reading frequency from HW
> - improve s_frequency(): tuner index and type checking
>
> Signed-off-by: Ondrej Zary <[email protected]>

Applied these 3 patches now to topic/misc branch of sound git tree
(i.e. for 2.6.40 kernel).

I leave the removal of radio-maestro to v4l guys, as this is fairly
independent.


thanks,

Takashi


> --- linux-2.6.38-rc4-orig/sound/i2c/other/tea575x-tuner.c 2011-02-08 01:03:55.000000000 +0100
> +++ linux-2.6.38-rc4/sound/i2c/other/tea575x-tuner.c 2011-03-19 15:40:14.000000000 +0100
> @@ -37,8 +37,8 @@ static int radio_nr = -1;
> module_param(radio_nr, int, 0);
>
> #define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
> -#define FREQ_LO (87 * 16000)
> -#define FREQ_HI (108 * 16000)
> +#define FREQ_LO (50UL * 16000)
> +#define FREQ_HI (150UL * 16000)
>
> /*
> * definitions
> @@ -77,15 +77,29 @@ static struct v4l2_queryctrl radio_qctrl
> * lowlevel part
> */
>
> +static void snd_tea575x_get_freq(struct snd_tea575x *tea)
> +{
> + unsigned long freq;
> +
> + freq = tea->ops->read(tea) & TEA575X_BIT_FREQ_MASK;
> + /* freq *= 12.5 */
> + freq *= 125;
> + freq /= 10;
> + /* crystal fixup */
> + if (tea->tea5759)
> + freq += tea->freq_fixup;
> + else
> + freq -= tea->freq_fixup;
> +
> + tea->freq = freq * 16; /* from kHz */
> +}
> +
> static void snd_tea575x_set_freq(struct snd_tea575x *tea)
> {
> unsigned long freq;
>
> - freq = tea->freq / 16; /* to kHz */
> - if (freq > 108000)
> - freq = 108000;
> - if (freq < 87000)
> - freq = 87000;
> + freq = clamp(tea->freq, FREQ_LO, FREQ_HI);
> + freq /= 16; /* to kHz */
> /* crystal fixup */
> if (tea->tea5759)
> freq -= tea->freq_fixup;
> @@ -109,29 +123,33 @@ static int vidioc_querycap(struct file *
> {
> struct snd_tea575x *tea = video_drvdata(file);
>
> - strcpy(v->card, tea->tea5759 ? "TEA5759" : "TEA5757");
> strlcpy(v->driver, "tea575x-tuner", sizeof(v->driver));
> - strlcpy(v->card, "Maestro Radio", sizeof(v->card));
> + strlcpy(v->card, tea->tea5759 ? "TEA5759" : "TEA5757", sizeof(v->card));
> sprintf(v->bus_info, "PCI");
> v->version = RADIO_VERSION;
> - v->capabilities = V4L2_CAP_TUNER;
> + v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
> return 0;
> }
>
> static int vidioc_g_tuner(struct file *file, void *priv,
> struct v4l2_tuner *v)
> {
> + struct snd_tea575x *tea = video_drvdata(file);
> +
> if (v->index > 0)
> return -EINVAL;
>
> + tea->ops->read(tea);
> +
> strcpy(v->name, "FM");
> v->type = V4L2_TUNER_RADIO;
> + v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
> v->rangelow = FREQ_LO;
> v->rangehigh = FREQ_HI;
> - v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
> - v->capability = V4L2_TUNER_CAP_LOW;
> - v->audmode = V4L2_TUNER_MODE_MONO;
> - v->signal = 0xffff;
> + v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
> + v->audmode = tea->stereo ? V4L2_TUNER_MODE_STEREO : V4L2_TUNER_MODE_MONO;
> + v->signal = tea->tuned ? 0xffff : 0;
> +
> return 0;
> }
>
> @@ -148,7 +166,10 @@ static int vidioc_g_frequency(struct fil
> {
> struct snd_tea575x *tea = video_drvdata(file);
>
> + if (f->tuner != 0)
> + return -EINVAL;
> f->type = V4L2_TUNER_RADIO;
> + snd_tea575x_get_freq(tea);
> f->frequency = tea->freq;
> return 0;
> }
> @@ -158,6 +179,9 @@ static int vidioc_s_frequency(struct fil
> {
> struct snd_tea575x *tea = video_drvdata(file);
>
> + if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
> + return -EINVAL;
> +
> if (f->frequency < FREQ_LO || f->frequency > FREQ_HI)
> return -EINVAL;
>
> --- linux-2.6.38-rc4-orig/include/sound/tea575x-tuner.h 2011-02-08 01:03:55.000000000 +0100
> +++ linux-2.6.38-rc4/include/sound/tea575x-tuner.h 2011-03-19 14:18:06.000000000 +0100
> @@ -38,8 +38,10 @@ struct snd_tea575x {
> struct snd_card *card;
> struct video_device *vd; /* video device */
> int dev_nr; /* requested device number + 1 */
> - int tea5759; /* 5759 chip is present */
> - int mute; /* Device is muted? */
> + bool tea5759; /* 5759 chip is present */
> + bool mute; /* Device is muted? */
> + bool stereo; /* receiving stereo */
> + bool tuned; /* tuned to a station */
> unsigned int freq_fixup; /* crystal onboard */
> unsigned int val; /* hw value */
> unsigned long freq; /* frequency */
>
>
> --
> Ondrej Zary
>

2011-03-22 18:40:07

by Mauro Carvalho Chehab

[permalink] [raw]
Subject: Re: [RFC PATCH 1/3] tea575x-tuner: various improvements

Em 21-03-2011 08:48, Takashi Iwai escreveu:
> At Sat, 19 Mar 2011 16:32:53 +0100,
> Ondrej Zary wrote:
>>
>> Improve tea575x-tuner with various good things from radio-maestro:
>> - extend frequency range to 50-150MHz
>> - fix querycap(): card name, CAP_RADIO
>> - improve g_tuner(): CAP_STEREO, stereo and tuned indication
>> - improve g_frequency(): tuner index checking and reading frequency from HW
>> - improve s_frequency(): tuner index and type checking
>>
>> Signed-off-by: Ondrej Zary <[email protected]>
>
> Applied these 3 patches now to topic/misc branch of sound git tree
> (i.e. for 2.6.40 kernel).

Patches look sane to me, you may add my ACK if you want.

Acked-by: Mauro Carvalho Chehab <[email protected]>

>
> I leave the removal of radio-maestro to v4l guys, as this is fairly
> independent.
>
>
> thanks,
>
> Takashi
>
>
>> --- linux-2.6.38-rc4-orig/sound/i2c/other/tea575x-tuner.c 2011-02-08 01:03:55.000000000 +0100
>> +++ linux-2.6.38-rc4/sound/i2c/other/tea575x-tuner.c 2011-03-19 15:40:14.000000000 +0100
>> @@ -37,8 +37,8 @@ static int radio_nr = -1;
>> module_param(radio_nr, int, 0);
>>
>> #define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
>> -#define FREQ_LO (87 * 16000)
>> -#define FREQ_HI (108 * 16000)
>> +#define FREQ_LO (50UL * 16000)
>> +#define FREQ_HI (150UL * 16000)
>>
>> /*
>> * definitions
>> @@ -77,15 +77,29 @@ static struct v4l2_queryctrl radio_qctrl
>> * lowlevel part
>> */
>>
>> +static void snd_tea575x_get_freq(struct snd_tea575x *tea)
>> +{
>> + unsigned long freq;
>> +
>> + freq = tea->ops->read(tea) & TEA575X_BIT_FREQ_MASK;
>> + /* freq *= 12.5 */
>> + freq *= 125;
>> + freq /= 10;
>> + /* crystal fixup */
>> + if (tea->tea5759)
>> + freq += tea->freq_fixup;
>> + else
>> + freq -= tea->freq_fixup;
>> +
>> + tea->freq = freq * 16; /* from kHz */
>> +}
>> +
>> static void snd_tea575x_set_freq(struct snd_tea575x *tea)
>> {
>> unsigned long freq;
>>
>> - freq = tea->freq / 16; /* to kHz */
>> - if (freq > 108000)
>> - freq = 108000;
>> - if (freq < 87000)
>> - freq = 87000;
>> + freq = clamp(tea->freq, FREQ_LO, FREQ_HI);
>> + freq /= 16; /* to kHz */
>> /* crystal fixup */
>> if (tea->tea5759)
>> freq -= tea->freq_fixup;
>> @@ -109,29 +123,33 @@ static int vidioc_querycap(struct file *
>> {
>> struct snd_tea575x *tea = video_drvdata(file);
>>
>> - strcpy(v->card, tea->tea5759 ? "TEA5759" : "TEA5757");
>> strlcpy(v->driver, "tea575x-tuner", sizeof(v->driver));
>> - strlcpy(v->card, "Maestro Radio", sizeof(v->card));
>> + strlcpy(v->card, tea->tea5759 ? "TEA5759" : "TEA5757", sizeof(v->card));
>> sprintf(v->bus_info, "PCI");
>> v->version = RADIO_VERSION;
>> - v->capabilities = V4L2_CAP_TUNER;
>> + v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
>> return 0;
>> }
>>
>> static int vidioc_g_tuner(struct file *file, void *priv,
>> struct v4l2_tuner *v)
>> {
>> + struct snd_tea575x *tea = video_drvdata(file);
>> +
>> if (v->index > 0)
>> return -EINVAL;
>>
>> + tea->ops->read(tea);
>> +
>> strcpy(v->name, "FM");
>> v->type = V4L2_TUNER_RADIO;
>> + v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
>> v->rangelow = FREQ_LO;
>> v->rangehigh = FREQ_HI;
>> - v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
>> - v->capability = V4L2_TUNER_CAP_LOW;
>> - v->audmode = V4L2_TUNER_MODE_MONO;
>> - v->signal = 0xffff;
>> + v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
>> + v->audmode = tea->stereo ? V4L2_TUNER_MODE_STEREO : V4L2_TUNER_MODE_MONO;
>> + v->signal = tea->tuned ? 0xffff : 0;
>> +
>> return 0;
>> }
>>
>> @@ -148,7 +166,10 @@ static int vidioc_g_frequency(struct fil
>> {
>> struct snd_tea575x *tea = video_drvdata(file);
>>
>> + if (f->tuner != 0)
>> + return -EINVAL;
>> f->type = V4L2_TUNER_RADIO;
>> + snd_tea575x_get_freq(tea);
>> f->frequency = tea->freq;
>> return 0;
>> }
>> @@ -158,6 +179,9 @@ static int vidioc_s_frequency(struct fil
>> {
>> struct snd_tea575x *tea = video_drvdata(file);
>>
>> + if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
>> + return -EINVAL;
>> +
>> if (f->frequency < FREQ_LO || f->frequency > FREQ_HI)
>> return -EINVAL;
>>
>> --- linux-2.6.38-rc4-orig/include/sound/tea575x-tuner.h 2011-02-08 01:03:55.000000000 +0100
>> +++ linux-2.6.38-rc4/include/sound/tea575x-tuner.h 2011-03-19 14:18:06.000000000 +0100
>> @@ -38,8 +38,10 @@ struct snd_tea575x {
>> struct snd_card *card;
>> struct video_device *vd; /* video device */
>> int dev_nr; /* requested device number + 1 */
>> - int tea5759; /* 5759 chip is present */
>> - int mute; /* Device is muted? */
>> + bool tea5759; /* 5759 chip is present */
>> + bool mute; /* Device is muted? */
>> + bool stereo; /* receiving stereo */
>> + bool tuned; /* tuned to a station */
>> unsigned int freq_fixup; /* crystal onboard */
>> unsigned int val; /* hw value */
>> unsigned long freq; /* frequency */
>>
>>
>> --
>> Ondrej Zary
>>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html

2011-03-22 18:45:03

by Mauro Carvalho Chehab

[permalink] [raw]
Subject: Re: [RFC PATCH 4/3] remove radio-maestro

Hi Takashi,

Em 19-03-2011 13:23, Ondrej Zary escreveu:
> Remove broken radio-maestro driver as the radio functionality is now
> integrated in the es1968 driver.

I prefer if you could also add it on your tree, as we want to make sure that
this patch will be applied together with the patches that moved Maestro
support into the es1968 driver.

I have no means to test if the es1968 changes work with a Maestro radio (as I
don't have this hardware), but I'm OK with this change. So:

Acked-by: Mauro Carvalho Chehab <[email protected]>

>
> Signed-off-by: Ondrej Zary <[email protected]>
>
> diff -urNp linux-2.6.38-rc4-orig/drivers/media/radio/Kconfig linux-2.6.38-rc4/drivers/media/radio/Kconfig
> --- linux-2.6.38-rc4-orig/drivers/media/radio/Kconfig 2011-02-08 01:03:55.000000000 +0100
> +++ linux-2.6.38-rc4/drivers/media/radio/Kconfig 2011-03-19 17:12:32.000000000 +0100
> @@ -166,21 +166,6 @@ config RADIO_MAXIRADIO
> To compile this driver as a module, choose M here: the
> module will be called radio-maxiradio.
>
> -config RADIO_MAESTRO
> - tristate "Maestro on board radio"
> - depends on VIDEO_V4L2 && PCI
> - ---help---
> - Say Y here to directly support the on-board radio tuner on the
> - Maestro 2 or 2E sound card.
> -
> - 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-maestro.
> -
> config RADIO_MIROPCM20
> tristate "miroSOUND PCM20 radio"
> depends on ISA && VIDEO_V4L2 && SND
> diff -urNp linux-2.6.38-rc4-orig/drivers/media/radio/Makefile linux-2.6.38-rc4/drivers/media/radio/Makefile
> --- linux-2.6.38-rc4-orig/drivers/media/radio/Makefile 2011-02-08 01:03:55.000000000 +0100
> +++ linux-2.6.38-rc4/drivers/media/radio/Makefile 2011-03-19 17:12:39.000000000 +0100
> @@ -16,7 +16,6 @@ obj-$(CONFIG_RADIO_GEMTEK) += radio-gemt
> 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/
> diff -urNp linux-2.6.38-rc4-orig/drivers/media/radio/radio-maestro.c linux-2.6.38-rc4/drivers/media/radio/radio-maestro.c
> --- linux-2.6.38-rc4-orig/drivers/media/radio/radio-maestro.c 2011-02-08 01:03:55.000000000 +0100
> +++ linux-2.6.38-rc4/drivers/media/radio/radio-maestro.c 1970-01-01 01:00:00.000000000 +0100
> @@ -1,452 +0,0 @@
> -/* Maestro PCI sound card radio driver for Linux support
> - * (c) 2000 A. Tlalka, [email protected]
> - * Notes on the hardware
> - *
> - * + Frequency control is done digitally
> - * + No volume control - only mute/unmute - you have to use Aux line volume
> - * control on Maestro card to set the volume
> - * + Radio status (tuned/not_tuned and stereo/mono) is valid some time after
> - * frequency setting (>100ms) and only when the radio is unmuted.
> - * version 0.02
> - * + io port is automatically detected - only the first radio is used
> - * version 0.03
> - * + thread access locking additions
> - * version 0.04
> - * + code improvements
> - * + VIDEO_TUNER_LOW is permanent
> - *
> - * Converted to V4L2 API by Mauro Carvalho Chehab <[email protected]>
> - */
> -
> -#include <linux/module.h>
> -#include <linux/init.h>
> -#include <linux/ioport.h>
> -#include <linux/delay.h>
> -#include <linux/version.h> /* for KERNEL_VERSION MACRO */
> -#include <linux/pci.h>
> -#include <linux/videodev2.h>
> -#include <linux/io.h>
> -#include <linux/slab.h>
> -#include <media/v4l2-device.h>
> -#include <media/v4l2-ioctl.h>
> -
> -MODULE_AUTHOR("Adam Tlalka, [email protected]");
> -MODULE_DESCRIPTION("Radio driver for the Maestro PCI sound card radio.");
> -MODULE_LICENSE("GPL");
> -
> -static int radio_nr = -1;
> -module_param(radio_nr, int, 0);
> -
> -#define RADIO_VERSION KERNEL_VERSION(0, 0, 6)
> -#define DRIVER_VERSION "0.06"
> -
> -#define GPIO_DATA 0x60 /* port offset from ESS_IO_BASE */
> -
> -#define IO_MASK 4 /* mask register offset from GPIO_DATA
> - bits 1=unmask write to given bit */
> -#define IO_DIR 8 /* direction register offset from GPIO_DATA
> - bits 0/1=read/write direction */
> -
> -#define GPIO6 0x0040 /* mask bits for GPIO lines */
> -#define GPIO7 0x0080
> -#define GPIO8 0x0100
> -#define GPIO9 0x0200
> -
> -#define STR_DATA GPIO6 /* radio TEA5757 pins and GPIO bits */
> -#define STR_CLK GPIO7
> -#define STR_WREN GPIO8
> -#define STR_MOST GPIO9
> -
> -#define FREQ_LO 50*16000
> -#define FREQ_HI 150*16000
> -
> -#define FREQ_IF 171200 /* 10.7*16000 */
> -#define FREQ_STEP 200 /* 12.5*16 */
> -
> -#define FREQ2BITS(x) ((((unsigned int)(x)+FREQ_IF+(FREQ_STEP<<1))\
> - /(FREQ_STEP<<2))<<2) /* (x==fmhz*16*1000) -> bits */
> -
> -#define BITS2FREQ(x) ((x) * FREQ_STEP - FREQ_IF)
> -
> -struct maestro {
> - struct v4l2_device v4l2_dev;
> - struct video_device vdev;
> - struct pci_dev *pdev;
> - struct mutex lock;
> -
> - u16 io; /* base of Maestro card radio io (GPIO_DATA)*/
> - u16 muted; /* VIDEO_AUDIO_MUTE */
> - u16 stereo; /* VIDEO_TUNER_STEREO_ON */
> - u16 tuned; /* signal strength (0 or 0xffff) */
> -};
> -
> -static inline struct maestro *to_maestro(struct v4l2_device *v4l2_dev)
> -{
> - return container_of(v4l2_dev, struct maestro, v4l2_dev);
> -}
> -
> -static u32 radio_bits_get(struct maestro *dev)
> -{
> - u16 io = dev->io, l, rdata;
> - u32 data = 0;
> - u16 omask;
> -
> - omask = inw(io + IO_MASK);
> - outw(~(STR_CLK | STR_WREN), io + IO_MASK);
> - outw(0, io);
> - udelay(16);
> -
> - for (l = 24; l--;) {
> - outw(STR_CLK, io); /* HI state */
> - udelay(2);
> - if (!l)
> - dev->tuned = inw(io) & STR_MOST ? 0 : 0xffff;
> - outw(0, io); /* LO state */
> - udelay(2);
> - data <<= 1; /* shift data */
> - rdata = inw(io);
> - if (!l)
> - dev->stereo = (rdata & STR_MOST) ? 0 : 1;
> - else if (rdata & STR_DATA)
> - data++;
> - udelay(2);
> - }
> -
> - if (dev->muted)
> - outw(STR_WREN, io);
> -
> - udelay(4);
> - outw(omask, io + IO_MASK);
> -
> - return data & 0x3ffe;
> -}
> -
> -static void radio_bits_set(struct maestro *dev, u32 data)
> -{
> - u16 io = dev->io, l, bits;
> - u16 omask, odir;
> -
> - omask = inw(io + IO_MASK);
> - odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN);
> - outw(odir | STR_DATA, io + IO_DIR);
> - outw(~(STR_DATA | STR_CLK | STR_WREN), io + IO_MASK);
> - udelay(16);
> - for (l = 25; l; l--) {
> - bits = ((data >> 18) & STR_DATA) | STR_WREN;
> - data <<= 1; /* shift data */
> - outw(bits, io); /* start strobe */
> - udelay(2);
> - outw(bits | STR_CLK, io); /* HI level */
> - udelay(2);
> - outw(bits, io); /* LO level */
> - udelay(4);
> - }
> -
> - if (!dev->muted)
> - outw(0, io);
> -
> - udelay(4);
> - outw(omask, io + IO_MASK);
> - outw(odir, io + IO_DIR);
> - msleep(125);
> -}
> -
> -static int vidioc_querycap(struct file *file, void *priv,
> - struct v4l2_capability *v)
> -{
> - struct maestro *dev = video_drvdata(file);
> -
> - strlcpy(v->driver, "radio-maestro", sizeof(v->driver));
> - strlcpy(v->card, "Maestro Radio", sizeof(v->card));
> - snprintf(v->bus_info, sizeof(v->bus_info), "PCI:%s", pci_name(dev->pdev));
> - v->version = RADIO_VERSION;
> - v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
> - return 0;
> -}
> -
> -static int vidioc_g_tuner(struct file *file, void *priv,
> - struct v4l2_tuner *v)
> -{
> - struct maestro *dev = video_drvdata(file);
> -
> - if (v->index > 0)
> - return -EINVAL;
> -
> - mutex_lock(&dev->lock);
> - radio_bits_get(dev);
> -
> - strlcpy(v->name, "FM", sizeof(v->name));
> - v->type = V4L2_TUNER_RADIO;
> - v->rangelow = FREQ_LO;
> - v->rangehigh = FREQ_HI;
> - v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
> - v->capability = V4L2_TUNER_CAP_LOW;
> - if (dev->stereo)
> - v->audmode = V4L2_TUNER_MODE_STEREO;
> - else
> - v->audmode = V4L2_TUNER_MODE_MONO;
> - v->signal = dev->tuned;
> - mutex_unlock(&dev->lock);
> - return 0;
> -}
> -
> -static int vidioc_s_tuner(struct file *file, void *priv,
> - struct v4l2_tuner *v)
> -{
> - return v->index ? -EINVAL : 0;
> -}
> -
> -static int vidioc_s_frequency(struct file *file, void *priv,
> - struct v4l2_frequency *f)
> -{
> - struct maestro *dev = video_drvdata(file);
> -
> - if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
> - return -EINVAL;
> - if (f->frequency < FREQ_LO || f->frequency > FREQ_HI)
> - return -EINVAL;
> - mutex_lock(&dev->lock);
> - radio_bits_set(dev, FREQ2BITS(f->frequency));
> - mutex_unlock(&dev->lock);
> - return 0;
> -}
> -
> -static int vidioc_g_frequency(struct file *file, void *priv,
> - struct v4l2_frequency *f)
> -{
> - struct maestro *dev = video_drvdata(file);
> -
> - if (f->tuner != 0)
> - return -EINVAL;
> - f->type = V4L2_TUNER_RADIO;
> - mutex_lock(&dev->lock);
> - f->frequency = BITS2FREQ(radio_bits_get(dev));
> - mutex_unlock(&dev->lock);
> - 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 maestro *dev = video_drvdata(file);
> -
> - switch (ctrl->id) {
> - case V4L2_CID_AUDIO_MUTE:
> - ctrl->value = dev->muted;
> - return 0;
> - }
> - return -EINVAL;
> -}
> -
> -static int vidioc_s_ctrl(struct file *file, void *priv,
> - struct v4l2_control *ctrl)
> -{
> - struct maestro *dev = video_drvdata(file);
> - u16 io = dev->io;
> - u16 omask;
> -
> - switch (ctrl->id) {
> - case V4L2_CID_AUDIO_MUTE:
> - mutex_lock(&dev->lock);
> - omask = inw(io + IO_MASK);
> - outw(~STR_WREN, io + IO_MASK);
> - dev->muted = ctrl->value;
> - outw(dev->muted ? STR_WREN : 0, io);
> - udelay(4);
> - outw(omask, io + IO_MASK);
> - msleep(125);
> - mutex_unlock(&dev->lock);
> - return 0;
> - }
> - return -EINVAL;
> -}
> -
> -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_file_operations maestro_fops = {
> - .owner = THIS_MODULE,
> - .unlocked_ioctl = video_ioctl2,
> -};
> -
> -static const struct v4l2_ioctl_ops maestro_ioctl_ops = {
> - .vidioc_querycap = vidioc_querycap,
> - .vidioc_g_tuner = vidioc_g_tuner,
> - .vidioc_s_tuner = vidioc_s_tuner,
> - .vidioc_g_audio = vidioc_g_audio,
> - .vidioc_s_audio = vidioc_s_audio,
> - .vidioc_g_input = vidioc_g_input,
> - .vidioc_s_input = vidioc_s_input,
> - .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,
> -};
> -
> -static u16 __devinit radio_power_on(struct maestro *dev)
> -{
> - register u16 io = dev->io;
> - register u32 ofreq;
> - u16 omask, odir;
> -
> - omask = inw(io + IO_MASK);
> - odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN);
> - outw(odir & ~STR_WREN, io + IO_DIR);
> - dev->muted = inw(io) & STR_WREN ? 0 : 1;
> - outw(odir, io + IO_DIR);
> - outw(~(STR_WREN | STR_CLK), io + IO_MASK);
> - outw(dev->muted ? 0 : STR_WREN, io);
> - udelay(16);
> - outw(omask, io + IO_MASK);
> - ofreq = radio_bits_get(dev);
> -
> - if ((ofreq < FREQ2BITS(FREQ_LO)) || (ofreq > FREQ2BITS(FREQ_HI)))
> - ofreq = FREQ2BITS(FREQ_LO);
> - radio_bits_set(dev, ofreq);
> -
> - return (ofreq == radio_bits_get(dev));
> -}
> -
> -static int __devinit maestro_probe(struct pci_dev *pdev,
> - const struct pci_device_id *ent)
> -{
> - struct maestro *dev;
> - struct v4l2_device *v4l2_dev;
> - int retval;
> -
> - retval = pci_enable_device(pdev);
> - if (retval) {
> - dev_err(&pdev->dev, "enabling pci device failed!\n");
> - goto err;
> - }
> -
> - retval = -ENOMEM;
> -
> - dev = kzalloc(sizeof(*dev), GFP_KERNEL);
> - if (dev == NULL) {
> - dev_err(&pdev->dev, "not enough memory\n");
> - goto err;
> - }
> -
> - v4l2_dev = &dev->v4l2_dev;
> - mutex_init(&dev->lock);
> - dev->pdev = pdev;
> -
> - strlcpy(v4l2_dev->name, "maestro", sizeof(v4l2_dev->name));
> -
> - retval = v4l2_device_register(&pdev->dev, v4l2_dev);
> - if (retval < 0) {
> - v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
> - goto errfr;
> - }
> -
> - dev->io = pci_resource_start(pdev, 0) + GPIO_DATA;
> -
> - strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
> - dev->vdev.v4l2_dev = v4l2_dev;
> - dev->vdev.fops = &maestro_fops;
> - dev->vdev.ioctl_ops = &maestro_ioctl_ops;
> - dev->vdev.release = video_device_release_empty;
> - video_set_drvdata(&dev->vdev, dev);
> -
> - if (!radio_power_on(dev)) {
> - retval = -EIO;
> - goto errfr1;
> - }
> -
> - retval = video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr);
> - if (retval) {
> - v4l2_err(v4l2_dev, "can't register video device!\n");
> - goto errfr1;
> - }
> -
> - v4l2_info(v4l2_dev, "version " DRIVER_VERSION "\n");
> -
> - return 0;
> -errfr1:
> - v4l2_device_unregister(v4l2_dev);
> -errfr:
> - kfree(dev);
> -err:
> - return retval;
> -
> -}
> -
> -static void __devexit maestro_remove(struct pci_dev *pdev)
> -{
> - struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
> - struct maestro *dev = to_maestro(v4l2_dev);
> -
> - video_unregister_device(&dev->vdev);
> - v4l2_device_unregister(&dev->v4l2_dev);
> -}
> -
> -static struct pci_device_id maestro_r_pci_tbl[] = {
> - { PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1968),
> - .class = PCI_CLASS_MULTIMEDIA_AUDIO << 8,
> - .class_mask = 0xffff00 },
> - { PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1978),
> - .class = PCI_CLASS_MULTIMEDIA_AUDIO << 8,
> - .class_mask = 0xffff00 },
> - { 0 }
> -};
> -MODULE_DEVICE_TABLE(pci, maestro_r_pci_tbl);
> -
> -static struct pci_driver maestro_r_driver = {
> - .name = "maestro_radio",
> - .id_table = maestro_r_pci_tbl,
> - .probe = maestro_probe,
> - .remove = __devexit_p(maestro_remove),
> -};
> -
> -static int __init maestro_radio_init(void)
> -{
> - int retval = pci_register_driver(&maestro_r_driver);
> -
> - if (retval)
> - printk(KERN_ERR "error during registration pci driver\n");
> -
> - return retval;
> -}
> -
> -static void __exit maestro_radio_exit(void)
> -{
> - pci_unregister_driver(&maestro_r_driver);
> -}
> -
> -module_init(maestro_radio_init);
> -module_exit(maestro_radio_exit);
>
>

2011-03-22 19:03:13

by Hans Verkuil

[permalink] [raw]
Subject: Re: [RFC PATCH 1/3] tea575x-tuner: various improvements

On Saturday, March 19, 2011 16:32:53 Ondrej Zary wrote:
> Improve tea575x-tuner with various good things from radio-maestro:
> - extend frequency range to 50-150MHz
> - fix querycap(): card name, CAP_RADIO
> - improve g_tuner(): CAP_STEREO, stereo and tuned indication
> - improve g_frequency(): tuner index checking and reading frequency from HW
> - improve s_frequency(): tuner index and type checking
>
> Signed-off-by: Ondrej Zary <[email protected]>

Acked-by: Hans Verkuil <[email protected]>

BTW, can you run the v4l2-compliance utility for the two boards that use
this radio tuner?

This utility is part of the v4l-utils repository (http://git.linuxtv.org/v4l-utils.git).

Run as 'v4l2-compliance -r /dev/radioX -v2'.

I'm sure there will be some errors/warnings (warnings regarding G/S_PRIORITY
are to be expected). But I can use it to make a patch for 2.6.40 that fixes
any issues.

Regards,

Hans

>
> --- linux-2.6.38-rc4-orig/sound/i2c/other/tea575x-tuner.c 2011-02-08 01:03:55.000000000 +0100
> +++ linux-2.6.38-rc4/sound/i2c/other/tea575x-tuner.c 2011-03-19 15:40:14.000000000 +0100
> @@ -37,8 +37,8 @@ static int radio_nr = -1;
> module_param(radio_nr, int, 0);
>
> #define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
> -#define FREQ_LO (87 * 16000)
> -#define FREQ_HI (108 * 16000)
> +#define FREQ_LO (50UL * 16000)
> +#define FREQ_HI (150UL * 16000)
>
> /*
> * definitions
> @@ -77,15 +77,29 @@ static struct v4l2_queryctrl radio_qctrl
> * lowlevel part
> */
>
> +static void snd_tea575x_get_freq(struct snd_tea575x *tea)
> +{
> + unsigned long freq;
> +
> + freq = tea->ops->read(tea) & TEA575X_BIT_FREQ_MASK;
> + /* freq *= 12.5 */
> + freq *= 125;
> + freq /= 10;
> + /* crystal fixup */
> + if (tea->tea5759)
> + freq += tea->freq_fixup;
> + else
> + freq -= tea->freq_fixup;
> +
> + tea->freq = freq * 16; /* from kHz */
> +}
> +
> static void snd_tea575x_set_freq(struct snd_tea575x *tea)
> {
> unsigned long freq;
>
> - freq = tea->freq / 16; /* to kHz */
> - if (freq > 108000)
> - freq = 108000;
> - if (freq < 87000)
> - freq = 87000;
> + freq = clamp(tea->freq, FREQ_LO, FREQ_HI);
> + freq /= 16; /* to kHz */
> /* crystal fixup */
> if (tea->tea5759)
> freq -= tea->freq_fixup;
> @@ -109,29 +123,33 @@ static int vidioc_querycap(struct file *
> {
> struct snd_tea575x *tea = video_drvdata(file);
>
> - strcpy(v->card, tea->tea5759 ? "TEA5759" : "TEA5757");
> strlcpy(v->driver, "tea575x-tuner", sizeof(v->driver));
> - strlcpy(v->card, "Maestro Radio", sizeof(v->card));
> + strlcpy(v->card, tea->tea5759 ? "TEA5759" : "TEA5757", sizeof(v->card));
> sprintf(v->bus_info, "PCI");
> v->version = RADIO_VERSION;
> - v->capabilities = V4L2_CAP_TUNER;
> + v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
> return 0;
> }
>
> static int vidioc_g_tuner(struct file *file, void *priv,
> struct v4l2_tuner *v)
> {
> + struct snd_tea575x *tea = video_drvdata(file);
> +
> if (v->index > 0)
> return -EINVAL;
>
> + tea->ops->read(tea);
> +
> strcpy(v->name, "FM");
> v->type = V4L2_TUNER_RADIO;
> + v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
> v->rangelow = FREQ_LO;
> v->rangehigh = FREQ_HI;
> - v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
> - v->capability = V4L2_TUNER_CAP_LOW;
> - v->audmode = V4L2_TUNER_MODE_MONO;
> - v->signal = 0xffff;
> + v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
> + v->audmode = tea->stereo ? V4L2_TUNER_MODE_STEREO : V4L2_TUNER_MODE_MONO;
> + v->signal = tea->tuned ? 0xffff : 0;
> +
> return 0;
> }
>
> @@ -148,7 +166,10 @@ static int vidioc_g_frequency(struct fil
> {
> struct snd_tea575x *tea = video_drvdata(file);
>
> + if (f->tuner != 0)
> + return -EINVAL;
> f->type = V4L2_TUNER_RADIO;
> + snd_tea575x_get_freq(tea);
> f->frequency = tea->freq;
> return 0;
> }
> @@ -158,6 +179,9 @@ static int vidioc_s_frequency(struct fil
> {
> struct snd_tea575x *tea = video_drvdata(file);
>
> + if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
> + return -EINVAL;
> +
> if (f->frequency < FREQ_LO || f->frequency > FREQ_HI)
> return -EINVAL;
>
> --- linux-2.6.38-rc4-orig/include/sound/tea575x-tuner.h 2011-02-08 01:03:55.000000000 +0100
> +++ linux-2.6.38-rc4/include/sound/tea575x-tuner.h 2011-03-19 14:18:06.000000000 +0100
> @@ -38,8 +38,10 @@ struct snd_tea575x {
> struct snd_card *card;
> struct video_device *vd; /* video device */
> int dev_nr; /* requested device number + 1 */
> - int tea5759; /* 5759 chip is present */
> - int mute; /* Device is muted? */
> + bool tea5759; /* 5759 chip is present */
> + bool mute; /* Device is muted? */
> + bool stereo; /* receiving stereo */
> + bool tuned; /* tuned to a station */
> unsigned int freq_fixup; /* crystal onboard */
> unsigned int val; /* hw value */
> unsigned long freq; /* frequency */
>
>
>

2011-03-22 19:03:56

by Hans Verkuil

[permalink] [raw]
Subject: Re: [RFC PATCH 4/3] remove radio-maestro

On Saturday, March 19, 2011 17:23:47 Ondrej Zary wrote:
> Remove broken radio-maestro driver as the radio functionality is now
> integrated in the es1968 driver.
>
> Signed-off-by: Ondrej Zary <[email protected]>

Acked-by: Hans Verkuil <[email protected]>

Also for patches 2 & 3 :-)

Regards,

Hans

2011-03-23 07:13:57

by Takashi Iwai

[permalink] [raw]
Subject: Re: [RFC PATCH 4/3] remove radio-maestro

At Tue, 22 Mar 2011 15:44:05 -0300,
Mauro Carvalho Chehab wrote:
>
> Hi Takashi,
>
> Em 19-03-2011 13:23, Ondrej Zary escreveu:
> > Remove broken radio-maestro driver as the radio functionality is now
> > integrated in the es1968 driver.
>
> I prefer if you could also add it on your tree, as we want to make sure that
> this patch will be applied together with the patches that moved Maestro
> support into the es1968 driver.
>
> I have no means to test if the es1968 changes work with a Maestro radio (as I
> don't have this hardware), but I'm OK with this change. So:
>
> Acked-by: Mauro Carvalho Chehab <[email protected]>

OK, I removed it in my tree now.

Thanks!


Takashi

2011-03-25 21:40:30

by Ondrej Zary

[permalink] [raw]
Subject: Re: [RFC PATCH 1/3] tea575x-tuner: various improvements

On Tuesday 22 March 2011 20:02:30 Hans Verkuil wrote:
> BTW, can you run the v4l2-compliance utility for the two boards that use
> this radio tuner?
>
> This utility is part of the v4l-utils repository
> (http://git.linuxtv.org/v4l-utils.git).
>
> Run as 'v4l2-compliance -r /dev/radioX -v2'.
>
> I'm sure there will be some errors/warnings (warnings regarding
> G/S_PRIORITY are to be expected). But I can use it to make a patch for
> 2.6.40 that fixes any issues.

The output is the same for both fm801 and es1968 (see below). Seems that
there are 4 errors:
1. multiple-open does not work
2. something bad with s_frequency
3. input functions are present
4. no extended controls



Running on 2.6.38

Driver Info:
Driver name : tea575x-tuner
Card type : TEA5757
Bus info : PCI
Driver version: 0.0.2
Capabilities : 0x00050000
Tuner
Radio

Compliance test for device /dev/radio0 (not using libv4l2):

Required ioctls:
test VIDIOC_QUERYCAP: OK

Allow for multiple opens:
test second radio open: FAIL

Debug ioctls:
test VIDIOC_DBG_G_CHIP_IDENT: Not Supported
test VIDIOC_DBG_G/S_REGISTER: Not Supported
test VIDIOC_LOG_STATUS: Not Supported

Input ioctls:
test VIDIOC_G/S_TUNER: OK
fail: set rangehigh+1 frequency did not return EINVAL
test VIDIOC_G/S_FREQUENCY: FAIL
test VIDIOC_ENUMAUDIO: Not Supported
fail: radio can't have input support
test VIDIOC_G/S/ENUMINPUT: FAIL
test VIDIOC_G/S_AUDIO: Not Supported
Inputs: 0 Audio Inputs: 0 Tuners: 1

Output ioctls:
test VIDIOC_G/S_MODULATOR: Not Supported
test VIDIOC_G/S_FREQUENCY: OK
test VIDIOC_ENUMAUDOUT: Not Supported
test VIDIOC_G/S/ENUMOUTPUT: Not Supported
test VIDIOC_G/S_AUDOUT: Not Supported
Outputs: 0 Audio Outputs: 0 Modulators: 0

Control ioctls:
fail: does not support V4L2_CTRL_FLAG_NEXT_CTRL
test VIDIOC_QUERYCTRL/MENU: FAIL
test VIDIOC_G/S_CTRL: OK
test VIDIOC_G/S/TRY_EXT_CTRLS: Not Supported
Standard Controls: 0 Private Controls: 0

Input/Output configuration ioctls:
test VIDIOC_ENUM/G/S/QUERY_STD: Not Supported
test VIDIOC_ENUM/G/S/QUERY_DV_PRESETS: Not Supported
test VIDIOC_G/S_DV_TIMINGS: Not Supported

Total: 21 Succeeded: 17 Failed: 4 Warnings: 0

--
Ondrej Zary

2011-03-26 10:19:46

by Hans Verkuil

[permalink] [raw]
Subject: Re: [RFC PATCH 1/3] tea575x-tuner: various improvements

On Friday, March 25, 2011 22:40:12 Ondrej Zary wrote:
> On Tuesday 22 March 2011 20:02:30 Hans Verkuil wrote:
> > BTW, can you run the v4l2-compliance utility for the two boards that use
> > this radio tuner?
> >
> > This utility is part of the v4l-utils repository
> > (http://git.linuxtv.org/v4l-utils.git).
> >
> > Run as 'v4l2-compliance -r /dev/radioX -v2'.
> >
> > I'm sure there will be some errors/warnings (warnings regarding
> > G/S_PRIORITY are to be expected). But I can use it to make a patch for
> > 2.6.40 that fixes any issues.
>
> The output is the same for both fm801 and es1968 (see below). Seems that
> there are 4 errors:
> 1. multiple-open does not work
> 2. something bad with s_frequency
> 3. input functions are present
> 4. no extended controls

Thanks for testing! Some comments are below...

>
>
>
> Running on 2.6.38
>
> Driver Info:
> Driver name : tea575x-tuner
> Card type : TEA5757
> Bus info : PCI
> Driver version: 0.0.2
> Capabilities : 0x00050000
> Tuner
> Radio
>
> Compliance test for device /dev/radio0 (not using libv4l2):
>
> Required ioctls:
> test VIDIOC_QUERYCAP: OK
>
> Allow for multiple opens:
> test second radio open: FAIL

I will fix this. Once 2.6.39-rc1 is released I can make a patch fixing this.

>
> Debug ioctls:
> test VIDIOC_DBG_G_CHIP_IDENT: Not Supported
> test VIDIOC_DBG_G/S_REGISTER: Not Supported
> test VIDIOC_LOG_STATUS: Not Supported
>
> Input ioctls:
> test VIDIOC_G/S_TUNER: OK
> fail: set rangehigh+1 frequency did not return EINVAL
> test VIDIOC_G/S_FREQUENCY: FAIL

Hmm, S_FREQUENCY apparently fails to check for valid frequency values.
Can you take a quick look at the code?

> test VIDIOC_ENUMAUDIO: Not Supported
> fail: radio can't have input support
> test VIDIOC_G/S/ENUMINPUT: FAIL

ENUMINPUT/G/S_INPUT are not allowed for radio devices. These ioctls are specific
for video. 90% of all radio driver use it, though :-)

I'll fix this when I go through all radio drivers.

> test VIDIOC_G/S_AUDIO: Not Supported
> Inputs: 0 Audio Inputs: 0 Tuners: 1
>
> Output ioctls:
> test VIDIOC_G/S_MODULATOR: Not Supported
> test VIDIOC_G/S_FREQUENCY: OK
> test VIDIOC_ENUMAUDOUT: Not Supported
> test VIDIOC_G/S/ENUMOUTPUT: Not Supported
> test VIDIOC_G/S_AUDOUT: Not Supported
> Outputs: 0 Audio Outputs: 0 Modulators: 0
>
> Control ioctls:
> fail: does not support V4L2_CTRL_FLAG_NEXT_CTRL
> test VIDIOC_QUERYCTRL/MENU: FAIL

I'll fix this as well. The drivers needs to be converted to the control
framework.

Regards,

Hans


> test VIDIOC_G/S_CTRL: OK
> test VIDIOC_G/S/TRY_EXT_CTRLS: Not Supported
> Standard Controls: 0 Private Controls: 0
>
> Input/Output configuration ioctls:
> test VIDIOC_ENUM/G/S/QUERY_STD: Not Supported
> test VIDIOC_ENUM/G/S/QUERY_DV_PRESETS: Not Supported
> test VIDIOC_G/S_DV_TIMINGS: Not Supported
>
> Total: 21 Succeeded: 17 Failed: 4 Warnings: 0
>
>

--
Hans Verkuil - video4linux developer - sponsored by Cisco

2011-03-29 19:26:07

by Ondrej Zary

[permalink] [raw]
Subject: Re: [RFC PATCH 1/3] tea575x-tuner: various improvements

On Saturday 26 March 2011 11:19:31 Hans Verkuil wrote:
> On Friday, March 25, 2011 22:40:12 Ondrej Zary wrote:
> > On Tuesday 22 March 2011 20:02:30 Hans Verkuil wrote:
> > > BTW, can you run the v4l2-compliance utility for the two boards that
> > > use this radio tuner?
> > >
> > > This utility is part of the v4l-utils repository
> > > (http://git.linuxtv.org/v4l-utils.git).
> > >
> > > Run as 'v4l2-compliance -r /dev/radioX -v2'.
> > >
> > > I'm sure there will be some errors/warnings (warnings regarding
> > > G/S_PRIORITY are to be expected). But I can use it to make a patch for
> > > 2.6.40 that fixes any issues.
> >
> > The output is the same for both fm801 and es1968 (see below). Seems that
> > there are 4 errors:
> > 1. multiple-open does not work
> > 2. something bad with s_frequency
> > 3. input functions are present
> > 4. no extended controls
>
> Thanks for testing! Some comments are below...
>
> > Running on 2.6.38
> >
> > Driver Info:
> > Driver name : tea575x-tuner
> > Card type : TEA5757
> > Bus info : PCI
> > Driver version: 0.0.2
> > Capabilities : 0x00050000
> > Tuner
> > Radio
> >
> > Compliance test for device /dev/radio0 (not using libv4l2):
> >
> > Required ioctls:
> > test VIDIOC_QUERYCAP: OK
> >
> > Allow for multiple opens:
> > test second radio open: FAIL
>
> I will fix this. Once 2.6.39-rc1 is released I can make a patch fixing
> this.
>
> > Debug ioctls:
> > test VIDIOC_DBG_G_CHIP_IDENT: Not Supported
> > test VIDIOC_DBG_G/S_REGISTER: Not Supported
> > test VIDIOC_LOG_STATUS: Not Supported
> >
> > Input ioctls:
> > test VIDIOC_G/S_TUNER: OK
> > fail: set rangehigh+1 frequency did not return EINVAL
> > test VIDIOC_G/S_FREQUENCY: FAIL
>
> Hmm, S_FREQUENCY apparently fails to check for valid frequency values.
> Can you take a quick look at the code?

The driver code is OK. But there is a bug in v4l2-test-input-output.cpp at
line 214:
if (ret)
return fail("set rangehigh+1 frequency did not return EINVAL\n");

There should be "if (ret != EINVAL)" instead of "if (ret)".

--
Ondrej Zary

2011-03-29 19:39:33

by Hans Verkuil

[permalink] [raw]
Subject: Re: [RFC PATCH 1/3] tea575x-tuner: various improvements

On Tuesday, March 29, 2011 21:25:55 Ondrej Zary wrote:
> On Saturday 26 March 2011 11:19:31 Hans Verkuil wrote:
> > On Friday, March 25, 2011 22:40:12 Ondrej Zary wrote:
> > > On Tuesday 22 March 2011 20:02:30 Hans Verkuil wrote:
> > > > BTW, can you run the v4l2-compliance utility for the two boards that
> > > > use this radio tuner?
> > > >
> > > > This utility is part of the v4l-utils repository
> > > > (http://git.linuxtv.org/v4l-utils.git).
> > > >
> > > > Run as 'v4l2-compliance -r /dev/radioX -v2'.
> > > >
> > > > I'm sure there will be some errors/warnings (warnings regarding
> > > > G/S_PRIORITY are to be expected). But I can use it to make a patch for
> > > > 2.6.40 that fixes any issues.
> > >
> > > The output is the same for both fm801 and es1968 (see below). Seems that
> > > there are 4 errors:
> > > 1. multiple-open does not work
> > > 2. something bad with s_frequency
> > > 3. input functions are present
> > > 4. no extended controls
> >
> > Thanks for testing! Some comments are below...
> >
> > > Running on 2.6.38
> > >
> > > Driver Info:
> > > Driver name : tea575x-tuner
> > > Card type : TEA5757
> > > Bus info : PCI
> > > Driver version: 0.0.2
> > > Capabilities : 0x00050000
> > > Tuner
> > > Radio
> > >
> > > Compliance test for device /dev/radio0 (not using libv4l2):
> > >
> > > Required ioctls:
> > > test VIDIOC_QUERYCAP: OK
> > >
> > > Allow for multiple opens:
> > > test second radio open: FAIL
> >
> > I will fix this. Once 2.6.39-rc1 is released I can make a patch fixing
> > this.
> >
> > > Debug ioctls:
> > > test VIDIOC_DBG_G_CHIP_IDENT: Not Supported
> > > test VIDIOC_DBG_G/S_REGISTER: Not Supported
> > > test VIDIOC_LOG_STATUS: Not Supported
> > >
> > > Input ioctls:
> > > test VIDIOC_G/S_TUNER: OK
> > > fail: set rangehigh+1 frequency did not return EINVAL
> > > test VIDIOC_G/S_FREQUENCY: FAIL
> >
> > Hmm, S_FREQUENCY apparently fails to check for valid frequency values.
> > Can you take a quick look at the code?
>
> The driver code is OK. But there is a bug in v4l2-test-input-output.cpp at
> line 214:
> if (ret)
> return fail("set rangehigh+1 frequency did not return EINVAL\n");
>
> There should be "if (ret != EINVAL)" instead of "if (ret)".

Grrr. I hate it when test code has bugs :-)

Thanks for finding this. I've fixed it in the code and pushed it to the v4l-utils
repository.

Regards,

Hans