* snd-fm801: autodetect SF64-PCR (tuner-only) card
@ 2009-11-26 20:59 Ondrej Zary
2009-11-27 6:59 ` Jaroslav Kysela
0 siblings, 1 reply; 4+ messages in thread
From: Ondrej Zary @ 2009-11-26 20:59 UTC (permalink / raw)
To: alsa-devel
When primary AC97 is not found, don't fail with tons of AC97 errors.
Assume that the card is SF64-PCR (tuner-only).
This makes the SF64-PCR radio card work "out of the box".
Also fixes a bug that can cause an oops here:
if (tea575x_tuner > 0 && (tea575x_tuner & 0x000f) < 4) {
when tea575x_tuner == 16, it passes this check and causes problems
a couple lines below:
chip->tea.ops = &snd_fm801_tea_ops[(tea575x_tuner & 0x000f) - 1];
Tested with SF64-PCR, but I don't have any of those sound or sound+radio cards
to test if I didn't break anything.
Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
--- linux-source-2.6.31-orig/sound/pci/fm801.c 2009-09-10 00:13:59.000000000 +0200
+++ linux-source-2.6.31/sound/pci/fm801.c 2009-11-26 21:19:59.000000000 +0100
@@ -55,7 +55,6 @@ static int enable[SNDRV_CARDS] = SNDRV_D
* 1 = MediaForte 256-PCS
* 2 = MediaForte 256-PCPR
* 3 = MediaForte 64-PCR
- * 16 = setup tuner only (this is additional bit), i.e. SF-64-PCR FM card
* High 16-bits are video (radio) device number + 1
*/
static int tea575x_tuner[SNDRV_CARDS];
@@ -67,7 +66,7 @@ MODULE_PARM_DESC(id, "ID string for the
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable FM801 soundcard.");
module_param_array(tea575x_tuner, int, NULL, 0444);
-MODULE_PARM_DESC(tea575x_tuner, "Enable TEA575x tuner.");
+MODULE_PARM_DESC(tea575x_tuner, "TEA575x tuner type (1 = SF256-PCS, 2=SF256-PCPR, 3=SF64-PCR).");
/*
* Direct registers
@@ -160,7 +159,8 @@ struct fm801 {
unsigned int multichannel: 1, /* multichannel support */
secondary: 1; /* secondary codec */
unsigned char secondary_addr; /* address of the secondary codec */
- unsigned int tea575x_tuner; /* tuner flags */
+ unsigned int tea575x_tuner; /* tuner type */
+ bool tuner_only;
unsigned short ply_ctrl; /* playback control */
unsigned short cap_ctrl; /* capture control */
@@ -1287,20 +1287,20 @@ static int snd_fm801_chip_init(struct fm
{
unsigned short cmdw;
- if (chip->tea575x_tuner & 0x0010)
- goto __ac97_ok;
-
/* codec cold reset + AC'97 warm reset */
outw((1<<5) | (1<<6), FM801_REG(chip, CODEC_CTRL));
inw(FM801_REG(chip, CODEC_CTRL)); /* flush posting data */
udelay(100);
outw(0, FM801_REG(chip, CODEC_CTRL));
- if (wait_for_codec(chip, 0, AC97_RESET, msecs_to_jiffies(750)) < 0) {
- snd_printk(KERN_ERR "Primary AC'97 codec not found\n");
- if (! resume)
- return -EIO;
- }
+ if (wait_for_codec(chip, 0, AC97_RESET, msecs_to_jiffies(750)) < 0)
+ if (!resume) {
+ snd_printk(KERN_ERR "Primary AC'97 codec not found, "
+ "assume SF64-PCR (tuner-only)\n");
+ chip->tuner_only = 1;
+ chip->tea575x_tuner = 3;
+ goto __ac97_ok;
+ }
if (chip->multichannel) {
if (chip->secondary_addr) {
@@ -1414,21 +1414,27 @@ static int __devinit snd_fm801_create(st
return err;
}
chip->port = pci_resource_start(pci, 0);
- if ((tea575x_tuner & 0x0010) == 0) {
- if (request_irq(pci->irq, snd_fm801_interrupt, IRQF_SHARED,
- "FM801", chip)) {
- snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->irq);
- snd_fm801_free(chip);
- return -EBUSY;
- }
- chip->irq = pci->irq;
- pci_set_master(pci);
+ if (request_irq(pci->irq, snd_fm801_interrupt, IRQF_SHARED,
+ "FM801", chip)) {
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->irq);
+ snd_fm801_free(chip);
+ return -EBUSY;
}
+ chip->irq = pci->irq;
+ pci_set_master(pci);
if (pci->revision >= 0xb1) /* FM801-AU */
chip->multichannel = 1;
snd_fm801_chip_init(chip, 0);
+ /* init might set tuner type */
+ tea575x_tuner = chip->tea575x_tuner;
+
+ if (chip->tuner_only) {
+ pci_clear_master(pci);
+ free_irq(chip->irq, chip);
+ chip->irq = -1;
+ }
if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
snd_fm801_free(chip);
@@ -1438,7 +1444,7 @@ static int __devinit snd_fm801_create(st
snd_card_set_dev(card, &pci->dev);
#ifdef TEA575X_RADIO
- if (tea575x_tuner > 0 && (tea575x_tuner & 0x000f) < 4) {
+ if ((tea575x_tuner & 0x000f) > 0 && (tea575x_tuner & 0x000f) < 4) {
chip->tea.dev_nr = tea575x_tuner >> 16;
chip->tea.card = card;
chip->tea.freq_fixup = 10700;
@@ -1483,7 +1489,7 @@ static int __devinit snd_card_fm801_prob
sprintf(card->longname, "%s at 0x%lx, irq %i",
card->shortname, chip->port, chip->irq);
- if (tea575x_tuner[dev] & 0x0010)
+ if (chip->tuner_only)
goto __fm801_tuner_only;
if ((err = snd_fm801_pcm(chip, 0, NULL)) < 0) {
--
Ondrej Zary
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: snd-fm801: autodetect SF64-PCR (tuner-only) card
2009-11-26 20:59 snd-fm801: autodetect SF64-PCR (tuner-only) card Ondrej Zary
@ 2009-11-27 6:59 ` Jaroslav Kysela
2009-11-27 17:18 ` Ondrej Zary
0 siblings, 1 reply; 4+ messages in thread
From: Jaroslav Kysela @ 2009-11-27 6:59 UTC (permalink / raw)
To: Ondrej Zary; +Cc: ALSA development
On Thu, 26 Nov 2009, Ondrej Zary wrote:
> When primary AC97 is not found, don't fail with tons of AC97 errors.
> Assume that the card is SF64-PCR (tuner-only).
> This makes the SF64-PCR radio card work "out of the box".
I would leave the possibility to force FM tuner only detection without
touching AC97 bus. The auto detection is a good idea. Could you recode
your patch?
> Also fixes a bug that can cause an oops here:
> if (tea575x_tuner > 0 && (tea575x_tuner & 0x000f) < 4) {
> when tea575x_tuner == 16, it passes this check and causes problems
> a couple lines below:
> chip->tea.ops = &snd_fm801_tea_ops[(tea575x_tuner & 0x000f) - 1];
Thanks for catching this bug.
Jaroslav
-----
Jaroslav Kysela <perex@perex.cz>
Linux Kernel Sound Maintainer
ALSA Project, Red Hat, Inc.
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: snd-fm801: autodetect SF64-PCR (tuner-only) card
2009-11-27 6:59 ` Jaroslav Kysela
@ 2009-11-27 17:18 ` Ondrej Zary
2009-12-03 17:33 ` Takashi Iwai
0 siblings, 1 reply; 4+ messages in thread
From: Ondrej Zary @ 2009-11-27 17:18 UTC (permalink / raw)
To: alsa-devel
On Friday 27 November 2009 07:59:26 Jaroslav Kysela wrote:
> On Thu, 26 Nov 2009, Ondrej Zary wrote:
> > When primary AC97 is not found, don't fail with tons of AC97 errors.
> > Assume that the card is SF64-PCR (tuner-only).
> > This makes the SF64-PCR radio card work "out of the box".
>
> I would leave the possibility to force FM tuner only detection without
> touching AC97 bus. The auto detection is a good idea. Could you recode
> your patch?
Here it is.
BTW. Looks like the tuner could be detected automatically provided that
someone has the different cards to test.
When primary AC97 is not found, don't fail with tons of AC97 errors.
Assume that the card is SF64-PCR (tuner-only).
This makes the SF64-PCR radio card work "out of the box".
Also fixes a bug that can cause an oops here:
if (tea575x_tuner > 0 && (tea575x_tuner & 0x000f) < 4) {
when tea575x_tuner == 16, it passes this check and causes problems
a couple lines below:
chip->tea.ops = &snd_fm801_tea_ops[(tea575x_tuner & 0x000f) - 1];
Tested with SF64-PCR, but I don't have any of those sound or sound+radio cards
to test if I didn't break anything.
Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
--- linux-source-2.6.31-orig/sound/pci/fm801.c 2009-09-10 00:13:59.000000000 +0200
+++ linux-source-2.6.31/sound/pci/fm801.c 2009-11-27 18:05:32.000000000 +0100
@@ -55,7 +55,7 @@ static int enable[SNDRV_CARDS] = SNDRV_D
* 1 = MediaForte 256-PCS
* 2 = MediaForte 256-PCPR
* 3 = MediaForte 64-PCR
- * 16 = setup tuner only (this is additional bit), i.e. SF-64-PCR FM card
+ * 16 = setup tuner only (this is additional bit), i.e. SF64-PCR FM card
* High 16-bits are video (radio) device number + 1
*/
static int tea575x_tuner[SNDRV_CARDS];
@@ -67,7 +67,10 @@ MODULE_PARM_DESC(id, "ID string for the
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable FM801 soundcard.");
module_param_array(tea575x_tuner, int, NULL, 0444);
-MODULE_PARM_DESC(tea575x_tuner, "Enable TEA575x tuner.");
+MODULE_PARM_DESC(tea575x_tuner, "TEA575x tuner access method (1 = SF256-PCS, 2=SF256-PCPR, 3=SF64-PCR, +16=tuner-only).");
+
+#define TUNER_ONLY (1<<4)
+#define TUNER_TYPE_MASK (~TUNER_ONLY & 0xFFFF)
/*
* Direct registers
@@ -160,7 +163,7 @@ struct fm801 {
unsigned int multichannel: 1, /* multichannel support */
secondary: 1; /* secondary codec */
unsigned char secondary_addr; /* address of the secondary codec */
- unsigned int tea575x_tuner; /* tuner flags */
+ unsigned int tea575x_tuner; /* tuner access method & flags */
unsigned short ply_ctrl; /* playback control */
unsigned short cap_ctrl; /* capture control */
@@ -1287,7 +1290,7 @@ static int snd_fm801_chip_init(struct fm
{
unsigned short cmdw;
- if (chip->tea575x_tuner & 0x0010)
+ if (chip->tea575x_tuner & TUNER_ONLY)
goto __ac97_ok;
/* codec cold reset + AC'97 warm reset */
@@ -1296,11 +1299,13 @@ static int snd_fm801_chip_init(struct fm
udelay(100);
outw(0, FM801_REG(chip, CODEC_CTRL));
- if (wait_for_codec(chip, 0, AC97_RESET, msecs_to_jiffies(750)) < 0) {
- snd_printk(KERN_ERR "Primary AC'97 codec not found\n");
- if (! resume)
- return -EIO;
- }
+ if (wait_for_codec(chip, 0, AC97_RESET, msecs_to_jiffies(750)) < 0)
+ if (!resume) {
+ snd_printk(KERN_INFO "Primary AC'97 codec not found, "
+ "assume SF64-PCR (tuner-only)\n");
+ chip->tea575x_tuner = 3 | TUNER_ONLY;
+ goto __ac97_ok;
+ }
if (chip->multichannel) {
if (chip->secondary_addr) {
@@ -1414,7 +1419,7 @@ static int __devinit snd_fm801_create(st
return err;
}
chip->port = pci_resource_start(pci, 0);
- if ((tea575x_tuner & 0x0010) == 0) {
+ if ((tea575x_tuner & TUNER_ONLY) == 0) {
if (request_irq(pci->irq, snd_fm801_interrupt, IRQF_SHARED,
"FM801", chip)) {
snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->irq);
@@ -1429,6 +1434,14 @@ static int __devinit snd_fm801_create(st
chip->multichannel = 1;
snd_fm801_chip_init(chip, 0);
+ /* init might set tuner access method */
+ tea575x_tuner = chip->tea575x_tuner;
+
+ if (chip->irq >= 0 && (tea575x_tuner & TUNER_ONLY)) {
+ pci_clear_master(pci);
+ free_irq(chip->irq, chip);
+ chip->irq = -1;
+ }
if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
snd_fm801_free(chip);
@@ -1438,12 +1451,13 @@ static int __devinit snd_fm801_create(st
snd_card_set_dev(card, &pci->dev);
#ifdef TEA575X_RADIO
- if (tea575x_tuner > 0 && (tea575x_tuner & 0x000f) < 4) {
+ 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;
- chip->tea.ops = &snd_fm801_tea_ops[(tea575x_tuner & 0x000f) - 1];
+ chip->tea.ops = &snd_fm801_tea_ops[(tea575x_tuner & TUNER_TYPE_MASK) - 1];
snd_tea575x_init(&chip->tea);
}
#endif
@@ -1483,7 +1497,7 @@ static int __devinit snd_card_fm801_prob
sprintf(card->longname, "%s at 0x%lx, irq %i",
card->shortname, chip->port, chip->irq);
- if (tea575x_tuner[dev] & 0x0010)
+ if (chip->tea575x_tuner & TUNER_ONLY)
goto __fm801_tuner_only;
if ((err = snd_fm801_pcm(chip, 0, NULL)) < 0) {
--
Ondrej Zary
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: snd-fm801: autodetect SF64-PCR (tuner-only) card
2009-11-27 17:18 ` Ondrej Zary
@ 2009-12-03 17:33 ` Takashi Iwai
0 siblings, 0 replies; 4+ messages in thread
From: Takashi Iwai @ 2009-12-03 17:33 UTC (permalink / raw)
To: Ondrej Zary; +Cc: alsa-devel
At Fri, 27 Nov 2009 18:18:33 +0100,
Ondrej Zary wrote:
>
> On Friday 27 November 2009 07:59:26 Jaroslav Kysela wrote:
> > On Thu, 26 Nov 2009, Ondrej Zary wrote:
> > > When primary AC97 is not found, don't fail with tons of AC97 errors.
> > > Assume that the card is SF64-PCR (tuner-only).
> > > This makes the SF64-PCR radio card work "out of the box".
> >
> > I would leave the possibility to force FM tuner only detection without
> > touching AC97 bus. The auto detection is a good idea. Could you recode
> > your patch?
>
> Here it is.
> BTW. Looks like the tuner could be detected automatically provided that
> someone has the different cards to test.
>
>
>
> When primary AC97 is not found, don't fail with tons of AC97 errors.
> Assume that the card is SF64-PCR (tuner-only).
> This makes the SF64-PCR radio card work "out of the box".
>
> Also fixes a bug that can cause an oops here:
> if (tea575x_tuner > 0 && (tea575x_tuner & 0x000f) < 4) {
> when tea575x_tuner == 16, it passes this check and causes problems
> a couple lines below:
> chip->tea.ops = &snd_fm801_tea_ops[(tea575x_tuner & 0x000f) - 1];
>
>
> Tested with SF64-PCR, but I don't have any of those sound or sound+radio cards
> to test if I didn't break anything.
>
>
> Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
Looks good to me. Now applied. Thanks.
Takashi
_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2009-12-03 17:33 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-11-26 20:59 snd-fm801: autodetect SF64-PCR (tuner-only) card Ondrej Zary
2009-11-27 6:59 ` Jaroslav Kysela
2009-11-27 17:18 ` Ondrej Zary
2009-12-03 17:33 ` Takashi Iwai
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.