[alsa-devel] 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?
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.
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 Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
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 Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
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 Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
-- Hans Verkuil - video4linux developer - sponsored by Cisco
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).
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
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 majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
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 linux@rainbow-software.org
--- 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 */
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 linux@rainbow-software.org
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)
f->type = V4L2_TUNER_RADIO;return -EINVAL;
- 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
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 linux@rainbow-software.org
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 mchehab@redhat.com
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)
f->type = V4L2_TUNER_RADIO;return -EINVAL;
- 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 majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
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 linux@rainbow-software.org
Acked-by: Hans Verkuil hverkuil@xs4all.nl
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)
f->type = V4L2_TUNER_RADIO;return -EINVAL;
- 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 */
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
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:
- multiple-open does not work
- something bad with s_frequency
- input functions are present
- 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
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:
- multiple-open does not work
- something bad with s_frequency
- input functions are present
- 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)".
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:
- multiple-open does not work
- something bad with s_frequency
- input functions are present
- 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
Remove unused dev_nr from struct tea575x_tuner.
Signed-off-by: Ondrej Zary linux@rainbow-software.org
--- 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;
Add TEA5757 radio tuner support to es1968 driver. This is found at least on MediaForte SF64-PCE2 sound cards.
Signed-off-by: Ondrej Zary linux@rainbow-software.org
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
Remove broken radio-maestro driver as the radio functionality is now integrated in the es1968 driver.
Signed-off-by: Ondrej Zary linux@rainbow-software.org
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, atlka@pg.gda.pl - * 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 mchehab@infradead.org - */ - -#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, atlka@pg.gda.pl"); -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);
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 mchehab@redhat.com
Signed-off-by: Ondrej Zary linux@rainbow-software.org
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, atlka@pg.gda.pl
- 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 mchehab@infradead.org
- */
-#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, atlka@pg.gda.pl"); -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);
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 mchehab@redhat.com
OK, I removed it in my tree now.
Thanks!
Takashi
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 linux@rainbow-software.org
Acked-by: Hans Verkuil hverkuil@xs4all.nl
Also for patches 2 & 3 :-)
Regards,
Hans
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
participants (4)
-
Hans Verkuil
-
Mauro Carvalho Chehab
-
Ondrej Zary
-
Takashi Iwai