All of lore.kernel.org
 help / color / mirror / Atom feed
* Linux driver for cs4281 with TWO cs4299 codecs?
@ 2002-05-22 15:59 tomasz motylewski
  2002-05-22 18:11 ` Takashi Iwai
  0 siblings, 1 reply; 13+ messages in thread
From: tomasz motylewski @ 2002-05-22 15:59 UTC (permalink / raw)
  To: twoller; +Cc: pcaudio, alsa-devel, peter wachtendorf


I hope you do not mind that I have contacted you directly.

I would like to ask whether anyone has developed a driver for cs4281 working in
a dual codec sound card.

We have developed such a card, and it works fine with a single cs4299 codec,
but current alsa-driver-0.9.0rc1 fails with:

ALSA ../alsa-kernel/pci/cs4281.c:1455: DLLRDY not seen
CS4281 soundcard not found or device busy

when we connect another codec configured as slave (no quartz signal on
secondary, but SYNC, BIT_CLK, SDATA_OUT, SDATA_IN, RESET connected).

I have tried to increase the timeout to 1 s, but without any result.

Any advice?

Is the programming manual cs4281tm.pdf available at
http://www.alsa-project.org/alsa/ftp/manuals/cirrus/cs4281tm.pdf the most
recent one?

Best regards,
--
Tomasz Motylewski

BFAD GmbH & Co. KG


_______________________________________________________________

Don't miss the 2002 Sprint PCS Application Developer's Conference
August 25-28 in Las Vegas -- http://devcon.sprintpcs.com/adp/index.cfm

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Linux driver for cs4281 with TWO cs4299 codecs?
  2002-05-22 15:59 Linux driver for cs4281 with TWO cs4299 codecs? tomasz motylewski
@ 2002-05-22 18:11 ` Takashi Iwai
  2002-05-22 18:33   ` tomasz motylewski
  2002-05-22 21:15   ` tomasz motylewski
  0 siblings, 2 replies; 13+ messages in thread
From: Takashi Iwai @ 2002-05-22 18:11 UTC (permalink / raw)
  To: tomasz motylewski; +Cc: twoller, pcaudio, alsa-devel, peter wachtendorf

[-- Attachment #1: Type: text/plain, Size: 1173 bytes --]

Hi,

At Wed, 22 May 2002 17:59:55 +0200 (CEST),
tomasz motylewski wrote:
> 
> 
> I hope you do not mind that I have contacted you directly.
> 
> I would like to ask whether anyone has developed a driver for cs4281 working in
> a dual codec sound card.
> 
> We have developed such a card, and it works fine with a single cs4299 codec,
> but current alsa-driver-0.9.0rc1 fails with:
> 
> ALSA ../alsa-kernel/pci/cs4281.c:1455: DLLRDY not seen
> CS4281 soundcard not found or device busy
> 
> when we connect another codec configured as slave (no quartz signal on
> secondary, but SYNC, BIT_CLK, SDATA_OUT, SDATA_IN, RESET connected).
> 
> I have tried to increase the timeout to 1 s, but without any result.
> 
> Any advice?
 
ALSA driver still doesn't support secondary codec, so most likely it's
a driver problem.

according to the cirrus' doc, ASDI2E and TCID must be set for the
secondary codec before the loop checking DLLRDY.

ok, now i did a very very quick hack.  could you try the attached
patch?  (you'll need to pass the module option snd_dual_codec=1)
it doesn't change the TCID value (it was set to 1).  it might be
different value.  tune as you like.


Takashi

[-- Attachment #2: cs4281-dual-codec.dif --]
[-- Type: application/octet-stream, Size: 5049 bytes --]

Index: alsa-kernel/pci/cs4281.c
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/pci/cs4281.c,v
retrieving revision 1.15
diff -u -r1.15 cs4281.c
--- alsa-kernel/pci/cs4281.c	21 May 2002 09:33:23 -0000	1.15
+++ alsa-kernel/pci/cs4281.c	22 May 2002 17:57:22 -0000
@@ -50,6 +50,7 @@
 static int snd_index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 static char *snd_id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
 static int snd_enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable switches */
+static int snd_dual_codec[SNDRV_CARDS];	/* dual codec */
 
 MODULE_PARM(snd_index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
 MODULE_PARM_DESC(snd_index, "Index value for CS4281 soundcard.");
@@ -60,6 +61,9 @@
 MODULE_PARM(snd_enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
 MODULE_PARM_DESC(snd_enable, "Enable CS4281 soundcard.");
 MODULE_PARM_SYNTAX(snd_enable, SNDRV_ENABLE_DESC);
+MODULE_PARM(snd_dual_codec, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+MODULE_PARM_DESC(snd_dual_codec, "Enable Dual Codec.");
+MODULE_PARM_SYNTAX(snd_dual_codec, SNDRV_BOOLEAN_FALSE_DESC);
 
 /*
  *
@@ -473,7 +477,10 @@
 	struct resource *ba0_res;
 	struct resource *ba1_res;
 
+	int dual_codec;
+
 	ac97_t *ac97;
+	ac97_t *ac97_secondary;
 
 	struct pci_dev *pci;
 	snd_card_t *card;
@@ -577,7 +584,7 @@
 	snd_cs4281_pokeBA0(chip, BA0_ACCAD, reg);
 	snd_cs4281_pokeBA0(chip, BA0_ACCDA, val);
 	snd_cs4281_pokeBA0(chip, BA0_ACCTL, BA0_ACCTL_DCV | BA0_ACCTL_VFRM |
-				            BA0_ACCTL_ESYN);
+				            BA0_ACCTL_ESYN | (ac97->num ? BA0_ACCTL_TC : 0));
 	for (count = 0; count < 2000; count++) {
 		/*
 		 *  First, we want to wait for a short time.
@@ -610,7 +617,7 @@
 	 *  6. Read ACSTS = Status Register = 464h, check VSTS bit
 	 */
 
-	snd_cs4281_peekBA0(chip, BA0_ACSDA);
+	snd_cs4281_peekBA0(chip, ac97->num ? BA0_ACSDA2 : BA0_ACSDA);
 
 	/*
 	 *  Setup the AC97 control registers on the CS461x to send the
@@ -628,7 +635,8 @@
 	snd_cs4281_pokeBA0(chip, BA0_ACCAD, reg);
 	snd_cs4281_pokeBA0(chip, BA0_ACCDA, 0);
 	snd_cs4281_pokeBA0(chip, BA0_ACCTL, BA0_ACCTL_DCV | BA0_ACCTL_CRW |
-					    BA0_ACCTL_VFRM | BA0_ACCTL_ESYN);
+					    BA0_ACCTL_VFRM | BA0_ACCTL_ESYN |
+			   (ac97->num ? BA0_ACCTL_TC : 0));
 
 
 	/*
@@ -661,7 +669,7 @@
 		 *  ACSTS = Status Register = 464h
 		 *  VSTS - Valid Status
 		 */
-		if (snd_cs4281_peekBA0(chip, BA0_ACSTS) & BA0_ACSTS_VSTS)
+		if (snd_cs4281_peekBA0(chip, ac97->num ? BA0_ACSTS2 : BA0_ACSTS) & BA0_ACSTS_VSTS)
 			goto __ok2;
 		udelay(10);
 	}
@@ -675,7 +683,7 @@
 	 *  Read the data returned from the AC97 register.
 	 *  ACSDA = Status Data Register = 474h
 	 */
-	result = snd_cs4281_peekBA0(chip, BA0_ACSDA);
+	result = snd_cs4281_peekBA0(chip, ac97->num ? BA0_ACSDA2 : BA0_ACSDA);
 
       __end:
 	return result;
@@ -1021,7 +1029,10 @@
 static void snd_cs4281_mixer_free_ac97(ac97_t *ac97)
 {
 	cs4281_t *chip = snd_magic_cast(cs4281_t, ac97->private_data, return);
-	chip->ac97 = NULL;
+	if (ac97->num)
+		chip->ac97_secondary = NULL;
+	else
+		chip->ac97 = NULL;
 }
 
 static int __devinit snd_cs4281_mixer(cs4281_t * chip)
@@ -1037,6 +1048,11 @@
 	ac97.private_free = snd_cs4281_mixer_free_ac97;
 	if ((err = snd_ac97_mixer(card, &ac97, &chip->ac97)) < 0)
 		return err;
+	if (chip->dual_codec) {
+		ac97.num = 1;
+		if ((err = snd_ac97_mixer(card, &ac97, &chip->ac97_secondary)) < 0)
+			return err;
+	}
 	return 0;
 }
 
@@ -1324,7 +1340,8 @@
 
 static int __devinit snd_cs4281_create(snd_card_t * card,
 				    struct pci_dev *pci,
-				    cs4281_t ** rchip)
+				    cs4281_t ** rchip,
+				       int dual_codec)
 {
 	cs4281_t *chip;
 	unsigned int tmp;
@@ -1347,6 +1364,7 @@
 	chip->ba0_addr = pci_resource_start(pci, 0);
 	chip->ba1_addr = pci_resource_start(pci, 1);
 	pci_set_master(pci);
+	chip->dual_codec = dual_codec;
 
 	if ((chip->ba0_res = request_mem_region(chip->ba0_addr, CS4281_BA0_SIZE, "CS4281 BA0")) == NULL) {
 		snd_cs4281_free(chip);
@@ -1426,6 +1444,9 @@
 	snd_cs4281_pokeBA0(chip, BA0_SPMC, BA0_SPMC_RSTN);
 	snd_cs4281_delay(50000);
 
+	if (chip->dual_codec)
+		snd_cs4281_pokeBA0(chip, BA0_SPMC, BA0_SPMC_RSTN | BA0_SPMC_ASDI2E);
+
 	/*
 	 *  Set the serial port timing configuration.
 	 */
@@ -1486,6 +1507,18 @@
 	return -EIO;
 
       __ok1:
+	if (chip->dual_codec) {
+		end_time = (jiffies + (3 * HZ) / 4) + 1;
+		do {
+			if (snd_cs4281_peekBA0(chip, BA0_ACSTS2) & BA0_ACSTS_CRDY)
+				goto __codec2_ok;
+			set_current_state(TASK_UNINTERRUPTIBLE);
+			schedule_timeout(1);
+		} while (end_time - (signed long)jiffies >= 0);
+		snd_printk(KERN_INFO "secondary codec doesn't respond. disable it...\n");
+		chip->dual_codec = 0;
+	__codec2_ok: ;
+	}
 
 	/*
 	 *  Assert the valid frame signal so that we can start sending commands
@@ -1836,7 +1869,7 @@
 	if (card == NULL)
 		return -ENOMEM;
 
-	if ((err = snd_cs4281_create(card, pci, &chip)) < 0) {
+	if ((err = snd_cs4281_create(card, pci, &chip, snd_dual_codec[dev])) < 0) {
 		snd_card_free(card);
 		return err;
 	}

^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: Linux driver for cs4281 with TWO cs4299 codecs?
@ 2002-05-22 18:27 Woller, Thomas
  0 siblings, 0 replies; 13+ messages in thread
From: Woller, Thomas @ 2002-05-22 18:27 UTC (permalink / raw)
  To: 'Takashi Iwai', tomasz motylewski
  Cc: Woller, Thomas, Austin PC Audio Support, alsa-devel,
	peter wachtendorf

I do not have a dual codec cs4281 driver. i do not believe that
any of our customers ever created such a design either, so not
100% sure that the h/w will all work as spec'ed, but I have no
idea... might though. officially cirrus did not support >1 codec
with the cs4281.  i do know that the linux driver will support
multiple cs4281/single codec systems, up to 4 i believe was
tested external to cirrus. 
tom woller

-----Original Message-----
From: Takashi Iwai [mailto:tiwai@suse.de]
Sent: Wednesday, May 22, 2002 1:12 PM
To: tomasz motylewski
Cc: twoller@crystal.cirrus.com; pcaudio@crystal.cirrus.com;
alsa-devel@lists.sourceforge.net; peter wachtendorf
Subject: Re: [Alsa-devel] Linux driver for cs4281 with TWO cs4299
codecs?


Hi,

At Wed, 22 May 2002 17:59:55 +0200 (CEST),
tomasz motylewski wrote:
> 
> 
> I hope you do not mind that I have contacted you directly.
> 
> I would like to ask whether anyone has developed a driver for
cs4281 working in
> a dual codec sound card.
> 
> We have developed such a card, and it works fine with a single
cs4299 codec,
> but current alsa-driver-0.9.0rc1 fails with:
> 
> ALSA ../alsa-kernel/pci/cs4281.c:1455: DLLRDY not seen
> CS4281 soundcard not found or device busy
> 
> when we connect another codec configured as slave (no quartz
signal on
> secondary, but SYNC, BIT_CLK, SDATA_OUT, SDATA_IN, RESET
connected).
> 
> I have tried to increase the timeout to 1 s, but without any
result.
> 
> Any advice?
 
ALSA driver still doesn't support secondary codec, so most likely
it's
a driver problem.

according to the cirrus' doc, ASDI2E and TCID must be set for the
secondary codec before the loop checking DLLRDY.

ok, now i did a very very quick hack.  could you try the attached
patch?  (you'll need to pass the module option snd_dual_codec=1)
it doesn't change the TCID value (it was set to 1).  it might be
different value.  tune as you like.


Takashi

_______________________________________________________________

Don't miss the 2002 Sprint PCS Application Developer's Conference
August 25-28 in Las Vegas -- http://devcon.sprintpcs.com/adp/index.cfm

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Linux driver for cs4281 with TWO cs4299 codecs?
  2002-05-22 18:11 ` Takashi Iwai
@ 2002-05-22 18:33   ` tomasz motylewski
  2002-05-22 21:15   ` tomasz motylewski
  1 sibling, 0 replies; 13+ messages in thread
From: tomasz motylewski @ 2002-05-22 18:33 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: twoller, pcaudio, alsa-devel, peter wachtendorf

> ok, now i did a very very quick hack.  could you try the attached
> patch?  (you'll need to pass the module option snd_dual_codec=1)
> it doesn't change the TCID value (it was set to 1).  it might be
> different value.  tune as you like.

You did quite a lot of code in such a short time. Thanks a lot!

Unfortunately does not work:

ALSA ../alsa-kernel/pci/cs4281.c:1476: DLLRDY not seen
CS4281 soundcard not found or device busy

(I have done  modprobe snd-cs4281 snd_dual_codec=1).

Please let me know if you have any other ideas, otherwhise I will go on
to debug it myself. Your patch seems to be a very good start.

BTW I am using 2.4.17 kernel recompiled with HZ=1000 and low-latency patch and
alsa-driver-0.9.0rc1.

In fact I would prefer alsa-driver-0.5.12a to work with this dual codec
(application porting!) but I am aware nobody is going to help me with ALSA5.

Best regards,
--
Tomasz Motylewski
BFAD GmbH & Co. KG


_______________________________________________________________

Don't miss the 2002 Sprint PCS Application Developer's Conference
August 25-28 in Las Vegas -- http://devcon.sprintpcs.com/adp/index.cfm

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Linux driver for cs4281 with TWO cs4299 codecs?
  2002-05-22 18:11 ` Takashi Iwai
  2002-05-22 18:33   ` tomasz motylewski
@ 2002-05-22 21:15   ` tomasz motylewski
  2002-05-23  8:40     ` Takashi Iwai
  1 sibling, 1 reply; 13+ messages in thread
From: tomasz motylewski @ 2002-05-22 21:15 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: twoller, pcaudio, alsa-devel, peter wachtendorf, arip


single codec, snd_dual_codec=0
ALSA ../alsa-kernel/pci/cs4281.c:1557: never read ISV3 and ISV4 from AC'97
CS4281 soundcard not found or device busy

modprobe AGAIN:

loads OK. 

The same behaviour with not patched alsa-driver-0.9.0rc1 driver! Probably
timeout too short. When I have increased the timeout 0.5 s the driver loaded OK
on the first try (well, not always. I have to investigate it in more detail).


Another test with Takashi patch:

single codec installed, snd_dual_codec=1
ALSA ../../alsa-kernel/pci/ac97/ac97_codec.c:1458: AC'97 1:0 does not respond -
RESET [REC_GAIN = 0xffff]
CS4281 soundcard not found or device busy

- this suggests autodetection should be possible.


I have looked more on the hardware and found out that the clock signal on
XTL_IN was too weak when the plate with additional codec was added. This signal
is not connected to the secondary codec, but the length of the wire was enough
to make it too weak.

After I fixed the problem the driver patched by Takashi actually loaded with
snd_dual_codec=1 !

I have seen:
cat /proc/asound/card0/ac97#0
0-1/0: Cirrus Logic CS4299 rev 4

Capabilities     : -headphone out-
DAC resolution   : 20-bit
ADC resolution   : 18-bit
3D enhancement   : Crystal Semi 3D Stereo Enhancement

Current setup
Mic gain         : +0dB [+0dB]
POP path         : pre 3D
Sim. stereo      : off
3D enhancement   : off
Loudness         : off
Mono output      : MIX
Mic select       : Mic1
ADC/DAC loopback : off
Extended ID      : codec=3 rev=0 AMAP DSA=0 VRA
Extended status  : VRA
PCM front DAC    : 48000Hz
PCM ADC          : 48000Hz

When I loaded the same driver with snd_dual_codec=0 I have got:

cat /proc/asound/card0/ac97#0
0-0/0: Cirrus Logic CS4299 rev 4

Capabilities     : -headphone out-
DAC resolution   : 20-bit
ADC resolution   : 18-bit
3D enhancement   : Crystal Semi 3D Stereo Enhancement

Current setup
Mic gain         : +0dB [+0dB]
POP path         : pre 3D
Sim. stereo      : off
3D enhancement   : off
Loudness         : off
Mono output      : MIX
Mic select       : Mic1
ADC/DAC loopback : off
Extended ID      : codec=0 rev=0 AMAP DSA=0 VRA
Extended status  : VRA
PCM front DAC    : 48000Hz
PCM ADC          : 48000Hz

But why there was always only a single codec listed in /proc/asound/card0/ ?

Best regards,
--
Tomasz Motylewski


_______________________________________________________________

Don't miss the 2002 Sprint PCS Application Developer's Conference
August 25-28 in Las Vegas -- http://devcon.sprintpcs.com/adp/index.cfm

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Linux driver for cs4281 with TWO cs4299 codecs?
  2002-05-22 21:15   ` tomasz motylewski
@ 2002-05-23  8:40     ` Takashi Iwai
  2002-05-23 10:27       ` tomasz motylewski
  0 siblings, 1 reply; 13+ messages in thread
From: Takashi Iwai @ 2002-05-23  8:40 UTC (permalink / raw)
  To: tomasz motylewski; +Cc: twoller, pcaudio, alsa-devel, peter wachtendorf, arip

[-- Attachment #1: Type: text/plain, Size: 2560 bytes --]

At Wed, 22 May 2002 23:15:36 +0200 (CEST),
tomasz motylewski wrote:
> 
> Another test with Takashi patch:
> 
> single codec installed, snd_dual_codec=1
> ALSA ../../alsa-kernel/pci/ac97/ac97_codec.c:1458: AC'97 1:0 does not respond -
> RESET [REC_GAIN = 0xffff]
> CS4281 soundcard not found or device busy
> 
> - this suggests autodetection should be possible.

yes.  but i think we can keep it as a module option, because, as
Thomas mentioned, there is almost no cards with dual codecs.


> 
> I have looked more on the hardware and found out that the clock signal on
> XTL_IN was too weak when the plate with additional codec was added. This signal
> is not connected to the secondary codec, but the length of the wire was enough
> to make it too weak.
> 
> After I fixed the problem the driver patched by Takashi actually loaded with
> snd_dual_codec=1 !

good to hear that :)

> I have seen:
> cat /proc/asound/card0/ac97#0
> 0-1/0: Cirrus Logic CS4299 rev 4
> 
> Capabilities     : -headphone out-
> DAC resolution   : 20-bit
> ADC resolution   : 18-bit
> 3D enhancement   : Crystal Semi 3D Stereo Enhancement
> 
> Current setup
> Mic gain         : +0dB [+0dB]
> POP path         : pre 3D
> Sim. stereo      : off
> 3D enhancement   : off
> Loudness         : off
> Mono output      : MIX
> Mic select       : Mic1
> ADC/DAC loopback : off
> Extended ID      : codec=3 rev=0 AMAP DSA=0 VRA
> Extended status  : VRA
> PCM front DAC    : 48000Hz
> PCM ADC          : 48000Hz
> 
> When I loaded the same driver with snd_dual_codec=0 I have got:
> 
> cat /proc/asound/card0/ac97#0
> 0-0/0: Cirrus Logic CS4299 rev 4
> 
> Capabilities     : -headphone out-
> DAC resolution   : 20-bit
> ADC resolution   : 18-bit
> 3D enhancement   : Crystal Semi 3D Stereo Enhancement
> 
> Current setup
> Mic gain         : +0dB [+0dB]
> POP path         : pre 3D
> Sim. stereo      : off
> 3D enhancement   : off
> Loudness         : off
> Mono output      : MIX
> Mic select       : Mic1
> ADC/DAC loopback : off
> Extended ID      : codec=0 rev=0 AMAP DSA=0 VRA
> Extended status  : VRA
> PCM front DAC    : 48000Hz
> PCM ADC          : 48000Hz
> 
> But why there was always only a single codec listed in /proc/asound/card0/ ?

oh, you hit a bug.
the second codec is not shown, because the primary and secondary codec
try to create the same file.
the attached patch will fix this problem.
the second codec will be shown in the file
/proc/asound/card0/ac97#0-1.

does alsamixer show entries for the second codec?
they must be there even without the patch below.


Takashi

[-- Attachment #2: ac97-fix.dif --]
[-- Type: application/octet-stream, Size: 1229 bytes --]

Index: alsa-kernel/pci/ac97/ac97_codec.c
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/pci/ac97/ac97_codec.c,v
retrieving revision 1.17
diff -u -r1.17 ac97_codec.c
--- alsa-kernel/pci/ac97/ac97_codec.c	22 May 2002 09:55:01 -0000	1.17
+++ alsa-kernel/pci/ac97/ac97_codec.c	23 May 2002 08:23:30 -0000
@@ -1775,9 +1775,12 @@
 static void snd_ac97_proc_init(snd_card_t * card, ac97_t * ac97)
 {
 	snd_info_entry_t *entry;
-	char name[12];
+	char name[32];
 
-	sprintf(name, "ac97#%d", ac97->addr);
+	if (ac97->num)
+		sprintf(name, "ac97#%d-%d", ac97->addr, ac97->num);
+	else
+		sprintf(name, "ac97#%d", ac97->addr);
 	if ((entry = snd_info_create_card_entry(card, name, card->proc_root)) != NULL) {
 		entry->content = SNDRV_INFO_CONTENT_TEXT;
 		entry->private_data = ac97;
@@ -1790,7 +1793,10 @@
 		}
 	}
 	ac97->proc_entry = entry;
-	sprintf(name, "ac97#%dregs", ac97->addr);
+	if (ac97->num)
+		sprintf(name, "ac97#%d-%dregs", ac97->addr, ac97->num);
+	else
+		sprintf(name, "ac97#%dregs", ac97->addr);
 	if ((entry = snd_info_create_card_entry(card, name, card->proc_root)) != NULL) {
 		entry->content = SNDRV_INFO_CONTENT_TEXT;
 		entry->private_data = ac97;

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Linux driver for cs4281 with TWO cs4299 codecs?
  2002-05-23  8:40     ` Takashi Iwai
@ 2002-05-23 10:27       ` tomasz motylewski
  2002-05-27 16:37         ` tomasz motylewski
  0 siblings, 1 reply; 13+ messages in thread
From: tomasz motylewski @ 2002-05-23 10:27 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: twoller, pcaudio, alsa-devel, peter wachtendorf, arip

On Thu, 23 May 2002, Takashi Iwai wrote:

> > - this suggests autodetection should be possible.
> 
> yes.  but i think we can keep it as a module option, because, as
> Thomas mentioned, there is almost no cards with dual codecs.

Sure. Agree.

> oh, you hit a bug.
> the second codec is not shown, because the primary and secondary codec
> try to create the same file.


> the attached patch will fix this problem.
> the second codec will be shown in the file
> /proc/asound/card0/ac97#0-1.

Funny, what I can see now is 

pc145:/proc/asound/card0# ls -l
total 69
-rw-r--r--    1 root     root            0 May 23 11:27 ac97#0
-rw-r--r--    1 root     root            0 May 23 11:27 ac97#0
-rw-r--r--    1 root     root            0 May 23 11:27 ac97#0regs
-rw-r--r--    1 root     root            0 May 23 11:27 ac97#0regs

But the source code looks good.

> does alsamixer show entries for the second codec?
> they must be there even without the patch below.

Well, I have first to compile all libraries and utils and put it on my embedeed
system.

My choice is the moment is either:

1. backport your changes to ALSA5.

2. Port my application to ALSA9.

This is VoIP application running in memory mapped mode, very close to the
hardware. I am using things like mmap_control->status.frag_io on the play side
(fragments are 80 samples long) to determine where to write the next soound
data (1-2 fragments before the currently processed one). Also access to
mmap_control->status.status is important.

On the capture side I first prepare the buffer overwriting it with a
"magick" values, and then read new samples as they are transferred by DMA to
the buffer. In this way I can achieve 1-2 ms latency.

I would prefer to port all to ALSA9, especially if the support for the driver
will continue to be so good.

I would prefer to use alsa-lib only to configure the driver and then operate
directly on memory mapped buffers, having a really efficient way to determine
which position the hardware processes at the very moment. ALSA5 interface was
very good for it (OK, I had to patch alsa-lib to allow write access to the
capture buffer).

A question:

will I get now 2 sound interfaces with 2 voices each, or rather a single
interface with 4 voices?

Please let me know if this discussion is getting off-topic on alsa-devel list.

Best regards,
--
Tomasz Motylewski


_______________________________________________________________

Don't miss the 2002 Sprint PCS Application Developer's Conference
August 25-28 in Las Vegas -- http://devcon.sprintpcs.com/adp/index.cfm

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Linux driver for cs4281 with TWO cs4299 codecs?
  2002-05-23 10:27       ` tomasz motylewski
@ 2002-05-27 16:37         ` tomasz motylewski
  2002-05-27 16:49           ` Takashi Iwai
                             ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: tomasz motylewski @ 2002-05-27 16:37 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: twoller, pcaudio, alsa-devel, peter wachtendorf, arip

Now I have got all alsa9 utilites on the system and the driver does something.

I can see for example PCM (2 channels) and PCM 1 (2 channels) in alsamixer.

I can also record like: arecord -c 4 -t raw -f S16_LE aaa.raw
and I get:
od -i aaa.raw | more
0000000    -10     -6      0      0      1      3      0      0
0000020     -8     -8      0      0     -7     -7      0      0
0000040     -7     -6      0      0     -6     -2      0      0
0000060    -10     -9      0      0     -9     -8      0      0

But here is a problem - I would expect to see some noise in both codecs - I
have configured and unmuted them BOTH to max volume.

In fact I have tried also -c 3 and -c 5  and always only the first 2 channels
are non-zero.

arecord -l    
card 0: card0 [Cirrus Logic CS4281], device 0: CS4281 [CS4281]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

How can I record data from the secondary codec?


BTW. I have done:

--- cs4281.c-takashi-2	Sat May 25 23:02:01 2002
+++ cs4281.c	Sat May 25 23:04:35 2002
@@ -61,7 +61,7 @@
 MODULE_PARM_DESC(snd_enable, "Enable CS4281 soundcard.");
 MODULE_PARM_SYNTAX(snd_enable, SNDRV_ENABLE_DESC);
 MODULE_PARM(snd_dual_codec, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
-MODULE_PARM_DESC(snd_dual_codec, "Enable Dual Codec.");
+MODULE_PARM_DESC(snd_dual_codec, "Enable Dual Codec. (put ID(1-3) here)");
 MODULE_PARM_SYNTAX(snd_dual_codec, SNDRV_BOOLEAN_FALSE_DESC);
 
 /*
@@ -1449,7 +1449,7 @@
 	/*
 	 *  Set the serial port timing configuration.
 	 */
-	snd_cs4281_pokeBA0(chip, BA0_SERMC, BA0_SERMC_TCID(1) | BA0_SERMC_PTC_AC97 | BA0_SERMC_MSPE);
+	snd_cs4281_pokeBA0(chip, BA0_SERMC, BA0_SERMC_TCID(chip->dual_codec) | BA0_SERMC_PTC_AC97 | BA0_SERMC_MSPE);
 
 	/*
 	 *  Start the DLL Clock logic.


I believe this is a nice way to give the actual codec ID (0 is always the
primary codec).

Best regards,
--
Tomasz Motylewski
BFAD GmbH & Co. KG


_______________________________________________________________

Don't miss the 2002 Sprint PCS Application Developer's Conference
August 25-28 in Las Vegas -- http://devcon.sprintpcs.com/adp/index.cfm

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Linux driver for cs4281 with TWO cs4299 codecs?
  2002-05-27 16:37         ` tomasz motylewski
@ 2002-05-27 16:49           ` Takashi Iwai
  2002-05-28 20:10           ` does CS4281 have enough SRC for 4 input + 4 output channels? tomasz motylewski
  2002-05-29 16:53           ` cs4281 with TWO cs4299 codecs - something works tomasz motylewski
  2 siblings, 0 replies; 13+ messages in thread
From: Takashi Iwai @ 2002-05-27 16:49 UTC (permalink / raw)
  To: tomasz motylewski; +Cc: twoller, pcaudio, alsa-devel, peter wachtendorf, arip

At Mon, 27 May 2002 18:37:09 +0200 (CEST),
tomasz motylewski wrote:
> 
> Now I have got all alsa9 utilites on the system and the driver does something.
> 
> I can see for example PCM (2 channels) and PCM 1 (2 channels) in alsamixer.
> 
> I can also record like: arecord -c 4 -t raw -f S16_LE aaa.raw
> and I get:
> od -i aaa.raw | more
> 0000000    -10     -6      0      0      1      3      0      0
> 0000020     -8     -8      0      0     -7     -7      0      0
> 0000040     -7     -6      0      0     -6     -2      0      0
> 0000060    -10     -9      0      0     -9     -8      0      0
> 
> But here is a problem - I would expect to see some noise in both codecs - I
> have configured and unmuted them BOTH to max volume.
> 
> In fact I have tried also -c 3 and -c 5  and always only the first 2 channels
> are non-zero.
> 
> arecord -l    
> card 0: card0 [Cirrus Logic CS4281], device 0: CS4281 [CS4281]
>   Subdevices: 1/1
>   Subdevice #0: subdevice #0
> 
> How can I record data from the secondary codec?
 
the patch i made was only for enabling the 2nd codec.
it does nothing actually about playback/capture using the 2nd codec
yet, so it's normal that you receive the result above.
the multi-channel was _emulated_ in alsa-lib.

i've not read the spec of cs4281 precisely, but there must be setting
to specify which codec is used for playback/capture.
sorry, i have no time atm for digging more about this.
do you have clue about this?

anyway, what we need to do on the driver are:

- increase the number of channels for pcm playback/capture, or create
  the second pcm stream for 2nd codec.
- set up the codec in prepare(), hw_params() or open() callback.
  disable in close() if necessary.

please check other hardwares with double codecs.


> 
> BTW. I have done:
...
> 
> I believe this is a nice way to give the actual codec ID (0 is always the
> primary codec).

yes.  but the exactly same hack was already on cvs at last week ;)


Takashi

_______________________________________________________________

Don't miss the 2002 Sprint PCS Application Developer's Conference
August 25-28 in Las Vegas -- http://devcon.sprintpcs.com/adp/index.cfm

^ permalink raw reply	[flat|nested] 13+ messages in thread

* does CS4281 have enough SRC for 4 input + 4 output channels?
  2002-05-27 16:37         ` tomasz motylewski
  2002-05-27 16:49           ` Takashi Iwai
@ 2002-05-28 20:10           ` tomasz motylewski
  2002-05-29 16:53           ` cs4281 with TWO cs4299 codecs - something works tomasz motylewski
  2 siblings, 0 replies; 13+ messages in thread
From: tomasz motylewski @ 2002-05-28 20:10 UTC (permalink / raw)
  To: twoller; +Cc: Takashi Iwai, pcaudio, alsa-devel, peter wachtendorf, arip, a.geh

Dear Mr. Woller,

I have taken some advice from Takashi Iwai and I am implementing dual codec
support for CS4281 chip.

I wanted to have 4 channels input (FIFO0(primary codec) and
FIFO1(secondary codec)) and 4 channels output (FIFO2 and FIFO3 in the same
way).

But what do I write to SRC Slot Assignment (SRCSA) register? I only have 4
slots while I need 8! 

Should I first write the playback and capture slots of the primary codec, then
set up FIFO0 and FIFO2, and then write slots of the secondary codec to SRCSA
and set up FIFO1 and FIFO3 ?


If this is indeed hardware limitation then I have the following 3 questions:

1. I am going to use CS4299 codecs at 8000 Hz only. They have internal sample
rate converters (SRC) working at 8000 Hz. Do I really need to use SRC in
CS4281? What will happen if I just set up the FIFOs and do not configure SRCSA
at all?

2. I really need in fact only input from left channels of both codecs and
output to the right channels of both codecs. May I for example program SRCSA
left capture slot CLSS to 10 (Left PCM record) and the right capture slot
CRSS to 20 (Secondary Left PCM record) or 22, 24 etc?
I would then do the same trick with the playback slots.
I would get the capture stereo stream from left PCM channels of the primary and
secondary codecs and play 2 channel stereo to the right channels of both
codecs.

3. Is it possible to have all the 4 channels interleaved? I mean can two DMA
engines write to the same memory buffer, just with 2 sample offset and skipping
each 2 samples?


Best regards,
--
Tomasz Motylewski

P.S. To ALSA developers: if my guess is right, then we may support all 4
channels full duplex only at a few predefines speeds. But we may use 4 SRC
units and for example make one codec any-speed, or all playback any-speed, or
all left channels (packed in a single stereo stream) any-speed. Does ALSA
support such wild configurations?


_______________________________________________________________

Don't miss the 2002 Sprint PCS Application Developer's Conference
August 25-28 in Las Vegas -- http://devcon.sprintpcs.com/adp/index.cfm

^ permalink raw reply	[flat|nested] 13+ messages in thread

* cs4281 with TWO cs4299 codecs - something works
  2002-05-27 16:37         ` tomasz motylewski
  2002-05-27 16:49           ` Takashi Iwai
  2002-05-28 20:10           ` does CS4281 have enough SRC for 4 input + 4 output channels? tomasz motylewski
@ 2002-05-29 16:53           ` tomasz motylewski
  2002-06-08 16:46             ` cs4281 - only 2 periods supported? tomasz motylewski
  2 siblings, 1 reply; 13+ messages in thread
From: tomasz motylewski @ 2002-05-29 16:53 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: twoller, alsa-devel, peter wachtendorf, arip

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1300 bytes --]


I have managed to get capture stereo sound from  right channels of both codecs.
I have just redefined AC slots and made sure second codec is configured.

The attached patch is very experimental, proof of concept. But some parts of it
could be commited (especially replacing numeric constants like 0,1, 10, 11 with
things like chip->src_left_play_slot). Also there are constants like
SRCSLOT_LEFT_PCM_PLAYBACK. The translation table ss2slot and change of
definition for BA0_AC*SV_SLV is probably also to be merged in.

The real development should go the following way IMHO:

1. add second PCM subdevice for use with second codec (interleaved 4 channel
mode will be rather not possible). It will be 2 subdevices with 1-2
channels each.

2. Reserve 4 available SRC to be used with the primary codec (same as in
the current code).

3. Use the second codec without CS4281 rate convertes and set the closest rates
in AC97_PCM_FRONT_DAC_RATE and AC97_PCM_LR_ADC_RATE (rates supported by CS4299:
8000, 11025, 16000, 22050, 32000, 44100, 48000). B0 in AC97_EXTENDED_STATUS has
to be set before.


My plans at the moment are to backport the changes to ALSA5 (card-cs4281.c
hacked by Pekka Pessi), and then if time allows (or porting problems
arise) implement above points.

Best regards,
--
Tomasz Motylewski

[-- Attachment #2: Type: TEXT/PLAIN, Size: 11189 bytes --]

diff -ur alsa-driver-0.9.0rc1-orig-takashi2/alsa-kernel/include/ac97_codec.h alsa-driver-0.9.0rc1/alsa-kernel/include/ac97_codec.h
--- alsa-driver-0.9.0rc1-orig-takashi2/alsa-kernel/include/ac97_codec.h	Thu Apr  4 09:37:53 2002
+++ alsa-driver-0.9.0rc1/alsa-kernel/include/ac97_codec.h	Wed May 29 17:21:13 2002
@@ -118,6 +118,16 @@
 #define AC97_AD_SERIAL_CFG	0x74	/* Serial Configuration */
 #define AC97_AD_MISC		0x76	/* Misc Control Bits */
 
+/* specific - Cirrus Logic (at least CS4299) */
+#define AC97_CS_MODE            0x5e	/* mainly AC slot mapping */
+#define AC97_CS_MISC            0x60	/* Misc. Crystal Control */
+#define AC97_CS_SPDIF_REG       0x68	/* S/PDIF Control */
+/* CS flags */
+#define AC97_CS_MODE_AMAP (1<<7) /* 1 - slot mapping by codec ID, 0 - by SM */
+#define AC97_CS_MODE_DDM (1<<8)
+#define AC97_CS_MODE_SM(x) (((x)&3)<<4) /* Slot Map No. */
+#define AC97_CS_MISC_LOSM (1<<0) /* Loss of SYNC Mute Enable. Defaults to 1 */
+
 /* ac97->scaps */
 #define AC97_SCAP_SURROUND_DAC	(1<<0)	/* surround L&R DACs are present */
 #define AC97_SCAP_CENTER_LFE_DAC (1<<1)	/* center and LFE DACs are present */
diff -ur alsa-driver-0.9.0rc1-orig-takashi2/alsa-kernel/pci/cs4281.c alsa-driver-0.9.0rc1/alsa-kernel/pci/cs4281.c
--- alsa-driver-0.9.0rc1-orig-takashi2/alsa-kernel/pci/cs4281.c	Sat May 25 23:04:35 2002
+++ alsa-driver-0.9.0rc1/alsa-kernel/pci/cs4281.c	Wed May 29 17:23:57 2002
@@ -51,6 +51,8 @@
 static int snd_enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable switches */
 static int snd_dual_codec[SNDRV_CARDS];	/* dual codec */
 
+static mangle_channels =1;
+
 MODULE_PARM(snd_index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
 MODULE_PARM_DESC(snd_index, "Index value for CS4281 soundcard.");
 MODULE_PARM_SYNTAX(snd_index, SNDRV_INDEX_DESC);
@@ -63,6 +65,8 @@
 MODULE_PARM(snd_dual_codec, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
 MODULE_PARM_DESC(snd_dual_codec, "Enable Dual Codec. (put ID(1-3) here)");
 MODULE_PARM_SYNTAX(snd_dual_codec, SNDRV_BOOLEAN_FALSE_DESC);
+MODULE_PARM(mangle_channels, "i");
+MODULE_PARM_DESC(mangle_channels, "set to 0 to get default L/R");
 
 /*
  *
@@ -283,13 +287,13 @@
 #define BA0_ACSTS_CRDY		(1<<0)	/* Codec Ready */
 
 #define BA0_ACOSV		0x0468	/* AC'97 Output Slot Valid */
-#define BA0_ACOSV_SLV(x)	(1<<((x)-3))
+#define BA0_ACOSV_SLV(x)	(1<<((ss2slot[x])-3))
 
 #define BA0_ACCAD		0x046c	/* AC'97 Command Address */
 #define BA0_ACCDA		0x0470	/* AC'97 Command Data */
 
 #define BA0_ACISV		0x0474	/* AC'97 Input Slot Valid */
-#define BA0_ACISV_SLV(x)	(1<<((x)-3))
+#define BA0_ACISV_SLV(x)	(1<<((ss2slot[x])-3))
 
 #define BA0_ACSAD		0x0478	/* AC'97 Status Address */
 #define BA0_ACSDA		0x047c	/* AC'97 Status Data */
@@ -488,12 +492,16 @@
 	snd_rawmidi_substream_t *midi_input;
 	snd_rawmidi_substream_t *midi_output;
 
+/// DMA(FIFOs) 0 and 1 play, 2 and 3 record
+#define DMA_PLAY_INDX 0
+/// was 1, but we need 2 dma for dual codec
+#define DMA_REC_INDX 2
 	cs4281_dma_t dma[4];
 
-	unsigned char src_left_play_slot;
-	unsigned char src_right_play_slot;
-	unsigned char src_left_rec_slot;
-	unsigned char src_right_rec_slot;
+	unsigned char src_left_play_slot[2];
+	unsigned char src_right_play_slot[2];
+	unsigned char src_left_rec_slot[2];
+	unsigned char src_right_rec_slot[2];
 
 	unsigned int spurious_dhtc_irq;
 	unsigned int spurious_dtc_irq;
@@ -516,6 +524,14 @@
 	{ 0, }
 };
 
+#define SS_SIZE 32
+/// Table 29 and Table 30 CS4281 Programming Manual
+unsigned char ss2slot[SS_SIZE] = {
+//	0   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f
+	3,  4,  5,  6,  7,  8,  9, 10, 11,  0,  3,  4,  5,  6,  7,  8,
+	9, 10, 11,  0,  3,  4,  5,  6,  7,  8,  9, 10, 11,  0,  0,  0
+};
+
 MODULE_DEVICE_TABLE(pci, snd_cs4281_ids);
 
 /*
@@ -757,11 +773,21 @@
 static void snd_cs4281_mode(cs4281_t *chip, cs4281_dma_t *dma, snd_pcm_runtime_t *runtime, int capture, int src)
 {
 	int rec_mono;
+	int codec=0;
 
 	dma->valDMR = BA0_DMR_TYPE_SINGLE | BA0_DMR_AUTO |
 		      (capture ? BA0_DMR_TR_WRITE : BA0_DMR_TR_READ);
-	if (runtime->channels == 1)
+	switch(runtime->channels == 1) {
+	case 1:
 		dma->valDMR |= BA0_DMR_MONO;
+	case 2:
+		break;
+	case 4:
+		// FXDUAL activate second codec
+		break;
+	case 3:
+	default:
+	}
 	if (snd_pcm_format_unsigned(runtime->format) > 0)
 		dma->valDMR |= BA0_DMR_USIGN;
 	if (snd_pcm_format_big_endian(runtime->format) > 0)
@@ -780,23 +806,23 @@
 	/* Initialize DMA */
 	snd_cs4281_pokeBA0(chip, dma->regDBA, runtime->dma_addr);
 	snd_cs4281_pokeBA0(chip, dma->regDBC, runtime->buffer_size - 1);
-	rec_mono = (chip->dma[1].valDMR & BA0_DMR_MONO) == BA0_DMR_MONO;
-	snd_cs4281_pokeBA0(chip, BA0_SRCSA, (chip->src_left_play_slot << 0) |
-					    (chip->src_right_play_slot << 8) |
-					    (chip->src_left_rec_slot << 16) |
-					    ((rec_mono ? 31 : chip->src_right_rec_slot) << 24));
+	rec_mono = (chip->dma[DMA_REC_INDX].valDMR & BA0_DMR_MONO) == BA0_DMR_MONO;
+	snd_cs4281_pokeBA0(chip, BA0_SRCSA, (chip->src_left_play_slot[codec] << 0) |
+					    (chip->src_right_play_slot[codec] << 8) |
+					    (chip->src_left_rec_slot[codec] << 16) |
+					    ((rec_mono ? 31 : chip->src_right_rec_slot[codec]) << 24));
 	if (!src)
 		goto __skip_src;
 	if (!capture) {
-		if (dma->left_slot == chip->src_left_play_slot) {
+		if (dma->left_slot == chip->src_left_play_slot[codec]) {
 			unsigned int val = snd_cs4281_rate(runtime->rate, NULL);
-			snd_assert(dma->right_slot == chip->src_right_play_slot, );
+			snd_assert(dma->right_slot == chip->src_right_play_slot[codec], );
 			snd_cs4281_pokeBA0(chip, BA0_DACSR, val);
 		}
 	} else {
-		if (dma->left_slot == chip->src_left_rec_slot) {
+		if (dma->left_slot == chip->src_left_rec_slot[codec]) {
 			unsigned int val = snd_cs4281_rate(runtime->rate, NULL);
-			snd_assert(dma->right_slot == chip->src_right_rec_slot, );
+			snd_assert(dma->right_slot == chip->src_right_rec_slot[codec], );
 			snd_cs4281_pokeBA0(chip, BA0_ADCSR, val);
 		}
 	}
@@ -915,10 +941,10 @@
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	cs4281_dma_t *dma;
 
-	dma = &chip->dma[0];
+	dma = &chip->dma[DMA_PLAY_INDX];
 	dma->substream = substream;
-	dma->left_slot = 0;
-	dma->right_slot = 1;
+	dma->left_slot = chip->src_left_play_slot[0];
+	dma->right_slot = chip->src_right_play_slot[0];
 	runtime->private_data = dma;
 	runtime->hw = snd_cs4281_playback;
 	snd_pcm_set_sync(substream);
@@ -935,10 +961,10 @@
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	cs4281_dma_t *dma;
 
-	dma = &chip->dma[1];
+	dma = &chip->dma[DMA_REC_INDX];
 	dma->substream = substream;
-	dma->left_slot = 10;
-	dma->right_slot = 11;
+	dma->left_slot = chip->src_left_rec_slot[0];
+	dma->right_slot = chip->src_right_rec_slot[0];
 	runtime->private_data = dma;
 	runtime->hw = snd_cs4281_capture;
 	snd_pcm_set_sync(substream);
@@ -1532,12 +1558,37 @@
 	 */
 
 	end_time = (jiffies + (5 * HZ) / 4) + 1;
+	chip->src_left_play_slot[0] = SRCSLOT_LEFT_PCM_PLAYBACK;
+	chip->src_right_play_slot[0] = SRCSLOT_RIGHT_PCM_PLAYBACK;
+	chip->src_left_rec_slot[0] = SRCSLOT_LEFT_PCM_RECORD;
+	chip->src_right_rec_slot[0] = SRCSLOT_RIGHT_PCM_RECORD;
+
+// FXDUAL - this will depend on setting AC Mode Control Register (0x5e) in secondary codec
+	// AC97 channels are 6,9 by default for the codec TCID=3
+	// may be changed by writing to AC97_CS_MODE
+	// and by default it maps to these values:
+	chip->src_left_play_slot[1] = SRCSLOT_CENTER_PCM_PLAYBACK;
+	chip->src_right_play_slot[1] = SRCSLOT_LFE_PCM_PLAYBACK;
+	chip->src_left_rec_slot[1] = SRCSLOT_SECONDARY_MIC_ADC;
+	chip->src_right_rec_slot[1] = 26;
+
+	if(mangle_channels) {
+	chip->src_right_play_slot[0] = chip->src_left_play_slot[1];
+	chip->src_left_rec_slot[0] = chip->src_right_rec_slot[1];
+	}
+
 	do {
 		/*
 		 *  Read the input slot valid register and see if input slots 3
 		 *  4 are valid yet.
 		 */
-                if ((snd_cs4281_peekBA0(chip, BA0_ACISV) & (BA0_ACISV_SLV(3) | BA0_ACISV_SLV(4))) == (BA0_ACISV_SLV(3) | BA0_ACISV_SLV(4)))
+		if ( mangle_channels &&
+			((snd_cs4281_peekBA0(chip, BA0_ACISV) & BA0_ACISV_SLV(chip->src_right_rec_slot[0])) == BA0_ACISV_SLV(chip->src_right_rec_slot[0]))
+			&&
+			((snd_cs4281_peekBA0(chip, BA0_ACISV2) & BA0_ACISV_SLV(chip->src_left_rec_slot[0])) == BA0_ACISV_SLV(chip->src_left_rec_slot[0]))
+			) {
+			goto __ok2;
+		} else if ((snd_cs4281_peekBA0(chip, BA0_ACISV) & (BA0_ACISV_SLV(chip->src_left_rec_slot[0]) | BA0_ACISV_SLV(chip->src_right_rec_slot[0]))) == (BA0_ACISV_SLV(chip->src_left_rec_slot[0]) | BA0_ACISV_SLV(chip->src_right_rec_slot[0])))
                         goto __ok2;
                 set_current_state(TASK_UNINTERRUPTIBLE);
                 schedule_timeout(1);
@@ -1553,7 +1604,7 @@
 	 *  Now, assert valid frame and the slot 3 and 4 valid bits.  This will
 	 *  commense the transfer of digital audio data to the AC97 codec.
 	 */
-	snd_cs4281_pokeBA0(chip, BA0_ACOSV, BA0_ACOSV_SLV(3) | BA0_ACOSV_SLV(4));
+	snd_cs4281_pokeBA0(chip, BA0_ACOSV, BA0_ACOSV_SLV(chip->src_left_play_slot[0]) | BA0_ACOSV_SLV(chip->src_right_play_slot[0]));
 
 	/*
 	 *  Initialize DMA structures
@@ -1577,10 +1628,6 @@
 				   BA0_FCR_OF(dma->fifo_offset));
 	}
 
-	chip->src_left_play_slot = 0;	/* AC'97 left PCM playback (3) */
-	chip->src_right_play_slot = 1;	/* AC'97 right PCM playback (4) */
-	chip->src_left_rec_slot = 10;	/* AC'97 left PCM record (3) */
-	chip->src_right_rec_slot = 11;	/* AC'97 right PCM record (4) */
 
 	/* Initialize digital volume */
 	snd_cs4281_pokeBA0(chip, BA0_PPLVC, 0);
diff -ur alsa-driver-0.9.0rc1-orig-takashi2/include/sound/ac97_codec.h alsa-driver-0.9.0rc1/include/sound/ac97_codec.h
--- alsa-driver-0.9.0rc1-orig-takashi2/include/sound/ac97_codec.h	Thu Apr  4 09:37:53 2002
+++ alsa-driver-0.9.0rc1/include/sound/ac97_codec.h	Wed May 29 17:21:13 2002
@@ -118,6 +118,16 @@
 #define AC97_AD_SERIAL_CFG	0x74	/* Serial Configuration */
 #define AC97_AD_MISC		0x76	/* Misc Control Bits */
 
+/* specific - Cirrus Logic (at least CS4299) */
+#define AC97_CS_MODE            0x5e	/* mainly AC slot mapping */
+#define AC97_CS_MISC            0x60	/* Misc. Crystal Control */
+#define AC97_CS_SPDIF_REG       0x68	/* S/PDIF Control */
+/* CS flags */
+#define AC97_CS_MODE_AMAP (1<<7) /* 1 - slot mapping by codec ID, 0 - by SM */
+#define AC97_CS_MODE_DDM (1<<8)
+#define AC97_CS_MODE_SM(x) (((x)&3)<<4) /* Slot Map No. */
+#define AC97_CS_MISC_LOSM (1<<0) /* Loss of SYNC Mute Enable. Defaults to 1 */
+
 /* ac97->scaps */
 #define AC97_SCAP_SURROUND_DAC	(1<<0)	/* surround L&R DACs are present */
 #define AC97_SCAP_CENTER_LFE_DAC (1<<1)	/* center and LFE DACs are present */
Binary files alsa-driver-0.9.0rc1-orig-takashi2/modules/snd-cs4281.o and alsa-driver-0.9.0rc1/modules/snd-cs4281.o differ
Binary files alsa-driver-0.9.0rc1-orig-takashi2/pci/cs4281.o and alsa-driver-0.9.0rc1/pci/cs4281.o differ
Binary files alsa-driver-0.9.0rc1-orig-takashi2/pci/snd-cs4281.o and alsa-driver-0.9.0rc1/pci/snd-cs4281.o differ

^ permalink raw reply	[flat|nested] 13+ messages in thread

* cs4281 - only 2 periods supported?
  2002-05-29 16:53           ` cs4281 with TWO cs4299 codecs - something works tomasz motylewski
@ 2002-06-08 16:46             ` tomasz motylewski
  2002-06-10 13:54               ` Takashi Iwai
  0 siblings, 1 reply; 13+ messages in thread
From: tomasz motylewski @ 2002-06-08 16:46 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: twoller, alsa-devel, peter wachtendorf, arip, Pekka.Pessi


I have seen that alsa-driver-0.9.0rc1 cs4281.c driver supports only 2 periods.

There exists an unofficial patch for alsa-driver-0.5.12a done by
Pekka.Pessi@nokia.com. I have seen that some parts of it are included in
0.9.0rc1, some are obsolete, but the limit of only 2 periods is not fixed in
0.9.0rc1 (playback). 

Especially snd_cs4281_start_new_dma(cs4281_t *chip, cs4281_dma_t *dma) and
changes to the interrupt handler are not in 0.9.0rc1 (and I believe also not in
CVS).

I am trying to backport it now, but it seems some interfaces have changed.

For exaple what the "pointer" function should return?

I do not understand the following code in alsa-kernel/core/pcm_lib.c:

    new_hw_ptr = runtime->hw_ptr_base + pos;
        
    hw_ptr_interrupt = runtime->hw_ptr_interrupt + runtime->period_size;
        
    delta = hw_ptr_interrupt - new_hw_ptr;
    if (delta > 0) {
        if (delta < runtime->buffer_size / 2) {
            snd_printd("Unexpected hw_pointer value (stream = %i, delta: -%ld,
max jitter = %ld): wrong interrupt acknowledge?\n", substream->stream,
(long) delta, runtime->buffer_size /
2);                                                                                   return
0;
        }               
        runtime->hw_ptr_base += runtime->buffer_size;
        if (runtime->hw_ptr_base == runtime->boundary)
            runtime->hw_ptr_base = 0;
        new_hw_ptr = runtime->hw_ptr_base + pos;
    }           
    runtime->status->hw_ptr = new_hw_ptr;
    runtime->hw_ptr_interrupt = new_hw_ptr - (runtime->hw_ptr_base + pos) %
runtime->period_size;                                     

Why is runtime->buffer_size the whole buffer or the period size? What is in
bytes, what in frames? Is there any function/field giving size of a single
frame in bytes?

Best regards,
--
Tomasz Motylewski




_______________________________________________________________

Don't miss the 2002 Sprint PCS Application Developer's Conference
August 25-28 in Las Vegas - http://devcon.sprintpcs.com/adp/index.cfm?source=osdntextlink

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: cs4281 - only 2 periods supported?
  2002-06-08 16:46             ` cs4281 - only 2 periods supported? tomasz motylewski
@ 2002-06-10 13:54               ` Takashi Iwai
  0 siblings, 0 replies; 13+ messages in thread
From: Takashi Iwai @ 2002-06-10 13:54 UTC (permalink / raw)
  To: tomasz motylewski; +Cc: alsa-devel

At Sat, 8 Jun 2002 18:46:10 +0200 (CEST),
tomasz motylewski wrote:
> 
> 
> I have seen that alsa-driver-0.9.0rc1 cs4281.c driver supports only 2 periods.
> 
> There exists an unofficial patch for alsa-driver-0.5.12a done by
> Pekka.Pessi@nokia.com. I have seen that some parts of it are included in
> 0.9.0rc1, some are obsolete, but the limit of only 2 periods is not fixed in
> 0.9.0rc1 (playback). 
> 
> Especially snd_cs4281_start_new_dma(cs4281_t *chip, cs4281_dma_t *dma) and
> changes to the interrupt handler are not in 0.9.0rc1 (and I believe also not in
> CVS).
> 
> I am trying to backport it now, but it seems some interfaces have changed.
> 
> For exaple what the "pointer" function should return?
 
the current offset pointer of dma in frames on the buffer.
if the current pointer is at the top of the buffer, then returns zero.
if it's at the X-th frame, then returns X.

> I do not understand the following code in alsa-kernel/core/pcm_lib.c:
> 
>     new_hw_ptr = runtime->hw_ptr_base + pos;
>         
>     hw_ptr_interrupt = runtime->hw_ptr_interrupt + runtime->period_size;
>         
>     delta = hw_ptr_interrupt - new_hw_ptr;
>     if (delta > 0) {
>         if (delta < runtime->buffer_size / 2) {
>             snd_printd("Unexpected hw_pointer value (stream = %i, delta: -%ld,
> max jitter = %ld): wrong interrupt acknowledge?\n", substream->stream,
> (long) delta, runtime->buffer_size /
> 2);                                                                                   return
> 0;
>         }               
>         runtime->hw_ptr_base += runtime->buffer_size;
>         if (runtime->hw_ptr_base == runtime->boundary)
>             runtime->hw_ptr_base = 0;
>         new_hw_ptr = runtime->hw_ptr_base + pos;
>     }           
>     runtime->status->hw_ptr = new_hw_ptr;
>     runtime->hw_ptr_interrupt = new_hw_ptr - (runtime->hw_ptr_base + pos) %
> runtime->period_size;                                     
> 
> Why is runtime->buffer_size the whole buffer or the period size? What is in
> bytes, what in frames? Is there any function/field giving size of a single
> frame in bytes?

1 frame = channels * sample-width bytes

1 sample = sapmle-width bytes


the bit-size of frame is given in runtime->frame_bits.

runtime->buffer_size and period_size are in frames.
you can guess easily from their type names.

there are convenient functions to convert between frames and bytes
defined in pcm.h, such as bytes_to_frames() and frames_to_bytes().


Takashi

_______________________________________________________________

Don't miss the 2002 Sprint PCS Application Developer's Conference
August 25-28 in Las Vegas - http://devcon.sprintpcs.com/adp/index.cfm?source=osdntextlink

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2002-06-10 13:54 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-05-22 15:59 Linux driver for cs4281 with TWO cs4299 codecs? tomasz motylewski
2002-05-22 18:11 ` Takashi Iwai
2002-05-22 18:33   ` tomasz motylewski
2002-05-22 21:15   ` tomasz motylewski
2002-05-23  8:40     ` Takashi Iwai
2002-05-23 10:27       ` tomasz motylewski
2002-05-27 16:37         ` tomasz motylewski
2002-05-27 16:49           ` Takashi Iwai
2002-05-28 20:10           ` does CS4281 have enough SRC for 4 input + 4 output channels? tomasz motylewski
2002-05-29 16:53           ` cs4281 with TWO cs4299 codecs - something works tomasz motylewski
2002-06-08 16:46             ` cs4281 - only 2 periods supported? tomasz motylewski
2002-06-10 13:54               ` Takashi Iwai
  -- strict thread matches above, loose matches on Subject: below --
2002-05-22 18:27 Linux driver for cs4281 with TWO cs4299 codecs? Woller, Thomas

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.