Skip to contentSkip to conversation

Xlinx ML403 AC97 Controller Reference device driver

PATCH In review Joachim Förster 4 participants 14 messages Aug 9, 2007 – Aug 15, 2007 Sound

lore
Share & tools
lore
#0 lore raw

PATCH 1/2 Xlinx ML403 AC97 Controller Reference device driver

From: Joachim Foerster <[email protected]>

Add ALSA support for the opb_ac97_controller_ref_v1_00_a ip core found in Xilinx' ML403 reference design.

Known issue: Currently this driver hits a WARN_ON_ONCE(1) statement in kernel/irq/resend.c (line 70). According to Linus
(http://lkml.org/lkml/2007/8/5/5) this may be ignored, right? I haven't had a look into this "problem" yet.

(Patch for Linus' master branch, date 2007/08/08)

This patchset _will_ be published on
http://www.esic-solutions.com/support.html soon (like the first version of the driver (tar file), but this may take some days ...).

---
 sound/ppc/Kconfig         |   13 +
 sound/ppc/Makefile        |    2 +
 sound/ppc/ml403_ac97cr.c  | 1274 +++++++++++++++++++++++++++++++++++++++++++++
 sound/ppc/pcm-indirect2.h |  658 +++++++++++++++++++++++
 4 files changed, 1947 insertions(+), 0 deletions(-)
 create mode 100644 sound/ppc/ml403_ac97cr.c
 create mode 100644 sound/ppc/pcm-indirect2.h
sound/ppc/Kconfig +13 -0
index cacb0b1..cd492bf 100644
@@ -52,4 +52,17 @@ config SND_PS3_DEFAULT_START_DELAY
 	int "Startup delay time in ms"
 	depends on SND_PS3
 	default "2000"
+
+config SND_ML403_AC97CR
+       tristate "Xilinx ML403 AC97 Controller Reference"
+       depends on SND && XILINX_VIRTEX
+       select SND_AC97_CODEC
+       help
+         Say Y here to include support for the
+         opb_ac97_controller_ref_v1_00_a ip core found in Xilinx' ML403
+         reference design.
+
+         To compile this driver as a module, choose M here: the module
+         will be called snd-ml403_ac97cr.
+
 endmenu
sound/ppc/Makefile +2 -0
index eacee2d..827f2f5 100644
@@ -4,7 +4,9 @@
 #
 
 snd-powermac-objs := powermac.o pmac.o awacs.o burgundy.o daca.o tumbler.o keywest.o beep.o
+snd-ml403_ac97cr-objs := ml403_ac97cr.o
 
 # Toplevel Module Dependency
 obj-$(CONFIG_SND_POWERMAC)	+= snd-powermac.o
 obj-$(CONFIG_SND_PS3)		+= snd_ps3.o
+obj-$(CONFIG_SND_ML403_AC97CR)	+= snd-ml403_ac97cr.o
sound/ppc/ml403_ac97cr.c new file +1274 -0

1,274 lines not on this page · raw message

sound/ppc/pcm-indirect2.h new file +658 -0

658 lines not on this page · raw message

Signature · 1 line
1.5.2.4
#1 lore raw

Hi,

thanks for the patch. Here the quick review at a first glance...

At Thu, 09 Aug 2007 12:36:50 +0200,

sound/ppc/Makefile line 12

Quoted 13 lines · Joachim Förster
sound/ppc/Makefile +2 -0
@@ -4,7 +4,9 @@
 #
 
 snd-powermac-objs := powermac.o pmac.o awacs.o burgundy.o daca.o tumbler.o keywest.o beep.o
+snd-ml403_ac97cr-objs := ml403_ac97cr.o
 
 # Toplevel Module Dependency
 obj-$(CONFIG_SND_POWERMAC)	+= snd-powermac.o
 obj-$(CONFIG_SND_PS3)		+= snd_ps3.o
+obj-$(CONFIG_SND_ML403_AC97CR)	+= snd-ml403_ac97cr.o

Using both _ and - look weird. Let's choose '-' as well as others.

Quoted 2 lines
sound/ppc/ml403_ac97cr.c new file +0 -0

(snip)

sound/ppc/ml403_ac97cr.c line 61

Quoted 3 lines
sound/ppc/ml403_ac97cr.c new file +3 -0
+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
+static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
+static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;

Can the driver really support multiple instances?
If not, better to avoid these arrays.

sound/ppc/ml403_ac97cr.c line 105

Quoted 2 lines
sound/ppc/ml403_ac97cr.c new file +2 -0
+#define PDEBUG(fac, fmt, args...) if (fac & PDEBUG_FACILITIES) \
+		snd_printd(KERN_DEBUG SND_ML403_AC97CR_DRIVER ": " fmt, ##args)

This should be wrapped with do { } while (0)

sound/ppc/ml403_ac97cr.c line 160

Quoted 4 lines
sound/ppc/ml403_ac97cr.c new file +4 -0
+struct lm4550_reg lm4550_regfile[64] = {
+	{.reg = 0x00,
+	 .flag = LM4550_REG_NOSAVE | LM4550_REG_FAKEREAD,
+	 .def = 0x0D50},

Better to use C99 style initialization here, e.g.

	[0x00] = { .... },
	[0x02] = { .... },
	[0x7e] = { .... },

so you can avoid writing empty items.
The index value could be also AC97_XXX, such as [AC97_MASTER] = {...}.

What is the purpose of reg field at all, BTW? I guess it's superfluous.

sound/ppc/ml403_ac97cr.c line 265

Quoted 13 lines
sound/ppc/ml403_ac97cr.c new file +13 -0
+#define LM4550_RF_OK(reg)    ((lm4550_regfile[reg / 2].reg != 0) \
+			      || (lm4550_regfile[reg / 2].flag != 0))
+#define LM4550_RF_FLAG(reg)  lm4550_regfile[reg / 2].flag
+#define LM4550_RF_VAL(reg)   lm4550_regfile[reg / 2].value
+#define LM4550_RF_DEF(reg)   lm4550_regfile[reg / 2].def
+#define LM4550_RF_WMASK(reg) lm4550_regfile[reg / 2].wmask
+
+static void lm4550_regfile_init(void)
+{
+	int i;
+	for (i = 0; i < 128; i = i + 2)
+		if (LM4550_RF_FLAG(i) & LM4550_REG_FAKEPROBE)
+			LM4550_RF_VAL(i) = LM4550_RF_DEF(i);

"MACRO(x) = XXX" looks a bit strange to me.

sound/ppc/ml403_ac97cr.c line 363

Quoted 8 lines
sound/ppc/ml403_ac97cr.c new file +8 -0
+static struct snd_pcm_hardware snd_ml403_ac97cr_playback = {
+	.info =	            (SNDRV_PCM_INFO_MMAP |
+		             SNDRV_PCM_INFO_INTERLEAVED |
+		             SNDRV_PCM_INFO_MMAP_VALID),
+	.formats =          SNDRV_PCM_FMTBIT_S16_BE,
+	.rates =	    (SNDRV_PCM_RATE_CONTINUOUS |
+			     SNDRV_PCM_RATE_8000_48000 |
+			     SNDRV_PCM_RATE_KNOT),

RATE_CONTINUOUS and RATE_KNOW are usually exclusive.

Quoted 11 lines
sound/ppc/ml403_ac97cr.c new file +11 -0
+static int
+snd_ml403_ac97cr_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+	struct snd_ml403_ac97cr *ml403_ac97cr;
+	int err = 0;
+
+	ml403_ac97cr = snd_pcm_substream_chip(substream);
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		if (substream == ml403_ac97cr->playback_substream) {

sound/ppc/ml403_ac97cr.c line 540

Quoted 10 lines
sound/ppc/ml403_ac97cr.c new file +10 -0
+			PDEBUG(WORK_INFO, "trigger(playback): START\n");
+			ml403_ac97cr->ind_rec.hw_ready = 1;
+
+			/* clear play FIFO */
+			out_be32(CR_REG(ml403_ac97cr, RESETFIFO), CR_PLAYRESET);
+
+			/* enable play irq */
+			ml403_ac97cr->enable_irq = 1;
+			enable_irq(ml403_ac97cr->irq);
+		}

Maybe better to create two functions, one for playback and one for capture, instead of many if's in a function?

sound/ppc/ml403_ac97cr.c line 593

Quoted 9 lines
sound/ppc/ml403_ac97cr.c new file +9 -0
+static int snd_ml403_ac97cr_pcm_prepare(struct snd_pcm_substream *substream)
+{
+	struct snd_ml403_ac97cr *ml403_ac97cr;
+	struct snd_pcm_runtime *runtime;
+
+	ml403_ac97cr = snd_pcm_substream_chip(substream);
+	runtime = substream->runtime;
+
+	if (substream == ml403_ac97cr->playback_substream) {

Ditto.

sound/ppc/ml403_ac97cr.c line 658

Quoted 10 lines
sound/ppc/ml403_ac97cr.c new file +10 -0
+static int
+snd_ml403_ac97cr_hw_params(struct snd_pcm_substream *substream,
+			   struct snd_pcm_hw_params *hw_params)
+{
+	PDEBUG(WORK_INFO, "hw_params(): desired buffer bytes=%d, desired "
+	       "period bytes=%d\n",
+	       params_buffer_bytes(hw_params), params_period_bytes(hw_params));
+	/* check period bytes, has to be multiple of CR_FIFO_SIZE / 2, don't
+	 * know if ALSA takes multiples of period_bytes_min _only_ ...?!
+	 */

This should be done via an additional hw_constraint at open,

	snd_pcm_hw_constraint_step(runtime, 0,
		SNDRV_PCM_HW_PARAM_PERIOD_BYTES, CR_FIFO_SIZE / 2);
Quoted 1 line

+struct snd_pcm_ops snd_ml403_ac97cr_playback_ops = {

Missing static.

Quoted 1 line

+irqreturn_t snd_ml403_ac97cr_irq(int irq, void *dev_id, struct pt_regs *regs)

Hm, this looks like an old style irq handler.
Did you test the driver with the recent kernel?

Also, missing static there.

Quoted 2 lines
sound/ppc/ml403_ac97cr.c new file +2 -0
+static unsigned short
+snd_ml403_ac97cr_codec_read(struct snd_ac97 *ac97, unsigned short reg)

....

Quoted 2 lines
sound/ppc/ml403_ac97cr.c new file +2 -0
+	/* if we are here, we _have_ to access the codec really, no faking */
+	spin_lock(&ml403_ac97cr->reg_lock);

....

Quoted 1 line
sound/ppc/ml403_ac97cr.c new file +1 -0
+	do {

....

sound/ppc/ml403_ac97cr.c

Quoted 2 lines
sound/ppc/ml403_ac97cr.c new file +2 -0
+		schedule_timeout_uninterruptible(1);
+	} while (time_after(end_time, jiffies));

Sleep in spinlock is bad.

sound/ppc/ml403_ac97cr.c line 1044

Quoted 3 lines
sound/ppc/ml403_ac97cr.c new file +3 -0
+static int __init
+snd_ml403_ac97cr_create(struct snd_card *card, struct platform_device *pfdev,
+			struct snd_ml403_ac97cr **rml403_ac97cr)

It's no longer __init as long as you use platform_device. It should be __devinit instead.

Quoted 2 lines
sound/ppc/pcm-indirect2.h new file +0 -0

(snip)

sound/ppc/pcm-indirect2.h line 117

Quoted 3 lines
sound/ppc/pcm-indirect2.h new file +3 -0
+#ifdef SND_PCM_INDIRECT2_STAT
+static inline void snd_pcm_indirect2_stat(struct snd_pcm_substream *substream,
+					  struct snd_pcm_indirect2 *rec)

Remove inline from the functions in this file. They are too lengthy.

sound/pcm-indirect.h contain inline functions becuase they are relatively small, and I didn't want to add them in the core module unconditionally.

Last but not least, the whole patch appears not following strictly the standard kernel coding style. For example, the style

	if ((err = foo()) < 0)
		....

should be

	err = foo();
	if (err < 0)
		...

Also, many lines are over 80 chars. Fold them appropriately. At least the new patches should be like that.

In doubt, you can try $KERNEL/scripts/checkpatch.pl script, which was added recently to linux kernel tree.

Takashi

#2 lore raw

Hi Takashi,

before posting a corrected version, I would like to ask some unclear things (I think I understood the rest):

Quoted 7 lines · Takashi Iwai

(snip)

sound/ppc/ml403_ac97cr.c line 61

Quoted 3 lines
sound/ppc/ml403_ac97cr.c new file +3 -0
+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
+static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
+static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;

Can the driver really support multiple instances?
If not, better to avoid these arrays.

Well, while I wrote the driver I considered that there might be more than one instance - though I didn't test it and I won't be able to test it (no such hardware available - with more than one LM4550 chip). So, shall I remove it?

Quoted 11 lines

sound/ppc/ml403_ac97cr.c line 160

Quoted 4 lines
sound/ppc/ml403_ac97cr.c new file +4 -0
+struct lm4550_reg lm4550_regfile[64] = {
+	{.reg = 0x00,
+	 .flag = LM4550_REG_NOSAVE | LM4550_REG_FAKEREAD,
+	 .def = 0x0D50},

Better to use C99 style initialization here, e.g.

	[0x00] = { .... },
	[0x02] = { .... },
	[0x7e] = { .... },
Quoted 6 lines

so you can avoid writing empty items.
The index value could be also AC97_XXX, such as [AC97_MASTER] = {...}.

What is the purpose of reg field at all, BTW? I guess it's superfluous.

No, it's there to provide a shadow copy of the codec's (LM4550) registers. It contains default values and (while driver is running) current values, which were written to the hardware. I had to introduce this, because Xilinx's AC97 Controller Reference has a very ugly bug: It provides a "register access finish" bit, so the driver is able to tell when a register read or write access is finished. Unfortunately this particular bit only works in the range of 0 to 100 times since board reset. After that many register access it just remains saying: I'm _not_ ready. But in fact, in most cases (98%) the correct value already is the read register (assume we have just said to the control that we want to read a register).
I thought, ok we have such RegAccessFinished bit, so use it, if we have to, until it doesn't work anymore.
So, through a shadow copy of most registers (some cannot be shadow or it makes no sence) I can provide the values without having to actually read from the controller/codec. The regfile also contains info which register might be shadowed, if values get saved at all (if written) ... Furthermore ALSA's AC97 layer does heavy initialization access series on the codec, which I tried to "mask out" completely (LM4550_REG_FAKEPROBE).

Quoted 1 line
Quoted 1 line

+#define LM4550_RF_FLAG(reg) lm4550_regfile[reg / 2].flag

<snip>

Quoted 8 lines

sound/ppc/ml403_ac97cr.c line 265

Quoted 6 lines
sound/ppc/ml403_ac97cr.c new file +6 -0
+static void lm4550_regfile_init(void)
+{
+	int i;
+	for (i = 0; i < 128; i = i + 2)
+		if (LM4550_RF_FLAG(i) & LM4550_REG_FAKEPROBE)
+			LM4550_RF_VAL(i) = LM4550_RF_DEF(i);

"MACRO(x) = XXX" looks a bit strange to me.

Hmmm, ok. I thought about that, too. I think, I'll spell them out?

Quoted 1 line

RATE_CONTINUOUS and RATE_KNOW are usually exclusive.

Ok, so what I want is RATE_CONTINUOUS, right? (because the LM4550 supports 4000 to 48000kHz in 1Hz steps)
BTW: What is RATE_KNOT good for?

Joachim

#3 lore raw

At Thu, 09 Aug 2007 21:44:46 +0200,

Quoted 15 lines · Joachim Förster

Hi Takashi,

before posting a corrected version, I would like to ask some unclear things (I think I understood the rest):

Quoted 7 lines · Takashi Iwai

(snip)

sound/ppc/ml403_ac97cr.c line 61

Quoted 3 lines
sound/ppc/ml403_ac97cr.c new file +3 -0
+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
+static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
+static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;

Can the driver really support multiple instances?
If not, better to avoid these arrays.

Quoted 4 lines

Well, while I wrote the driver I considered that there might be more than one instance - though I didn't test it and I won't be able to test it (no such hardware available - with more than one LM4550 chip). So, shall I remove it?

It's up to you. If it makes the code easier and more maintenable, it's worth to try.

Quoted 15 lines
Quoted 15 lines

sound/ppc/ml403_ac97cr.c line 160

Quoted 4 lines
sound/ppc/ml403_ac97cr.c new file +4 -0
+struct lm4550_reg lm4550_regfile[64] = {
+	{.reg = 0x00,
+	 .flag = LM4550_REG_NOSAVE | LM4550_REG_FAKEREAD,
+	 .def = 0x0D50},

Better to use C99 style initialization here, e.g.

	[0x00] = { .... },
	[0x02] = { .... },
	[0x7e] = { .... },

so you can avoid writing empty items.
The index value could be also AC97_XXX, such as [AC97_MASTER] = {...}.

Quoted 5 lines
Quoted 2 lines

What is the purpose of reg field at all, BTW? I guess it's superfluous.

No, it's there to provide a shadow copy of the codec's (LM4550) registers.

That I understood too. My question was the reg _field_. It looks like an index but it can be even easily calculated from the pointer address...

Quoted 31 lines

It contains default values and (while driver is running) current values, which were written to the hardware. I had to introduce this, because Xilinx's AC97 Controller Reference has a very ugly bug: It provides a "register access finish" bit, so the driver is able to tell when a register read or write access is finished. Unfortunately this particular bit only works in the range of 0 to 100 times since board reset. After that many register access it just remains saying: I'm _not_ ready. But in fact, in most cases (98%) the correct value already is the read register (assume we have just said to the control that we want to read a register).
I thought, ok we have such RegAccessFinished bit, so use it, if we have to, until it doesn't work anymore.
So, through a shadow copy of most registers (some cannot be shadow or it makes no sence) I can provide the values without having to actually read from the controller/codec. The regfile also contains info which register might be shadowed, if values get saved at all (if written) ... Furthermore ALSA's AC97 layer does heavy initialization access series on the codec, which I tried to "mask out" completely (LM4550_REG_FAKEPROBE).

Quoted 1 line
Quoted 1 line

+#define LM4550_RF_FLAG(reg) lm4550_regfile[reg / 2].flag

<snip>

Quoted 8 lines

sound/ppc/ml403_ac97cr.c line 265

Quoted 6 lines
sound/ppc/ml403_ac97cr.c new file +6 -0
+static void lm4550_regfile_init(void)
+{
+	int i;
+	for (i = 0; i < 128; i = i + 2)
+		if (LM4550_RF_FLAG(i) & LM4550_REG_FAKEPROBE)
+			LM4550_RF_VAL(i) = LM4550_RF_DEF(i);

"MACRO(x) = XXX" looks a bit strange to me.

Quoted 7 lines

Hmmm, ok. I thought about that, too. I think, I'll spell them out?

Quoted 1 line

RATE_CONTINUOUS and RATE_KNOW are usually exclusive.

Ok, so what I want is RATE_CONTINUOUS, right? (because the LM4550 supports 4000 to 48000kHz in 1Hz steps)
BTW: What is RATE_KNOT good for?

It indicates unusual non-continuous sample rates that don't match with SNDRV_PCM_RATE_XXX bits are supported. The rates in 1Hz step is continuous enough :)

Takashi

#4 lore raw
In reply to Takashi Iwai

Hi Takashi,

again some question came up (while correcting all the other issues):

Quoted 6 lines · Takashi Iwai

sound/ppc/ml403_ac97cr.c line 1044

Quoted 3 lines
sound/ppc/ml403_ac97cr.c new file +3 -0
+static int __init
+snd_ml403_ac97cr_create(struct snd_card *card, struct platform_device *pfdev,
+			struct snd_ml403_ac97cr **rml403_ac97cr)

It's no longer __init as long as you use platform_device. It should be __devinit instead.

Ok, I changed that (for create(), pcm(), mixer(), etc.). Do I have to change it for the module_init and module_exit functions, too? I guess, they are not in the "scope" of platform device, right? So, they will keep __init / __exit ?

Quoted 9 lines
Quoted 2 lines
sound/ppc/pcm-indirect2.h new file +0 -0

(snip)

sound/ppc/pcm-indirect2.h line 117

Quoted 3 lines
sound/ppc/pcm-indirect2.h new file +3 -0
+#ifdef SND_PCM_INDIRECT2_STAT
+static inline void snd_pcm_indirect2_stat(struct snd_pcm_substream *substream,
+					  struct snd_pcm_indirect2 *rec)

Remove inline from the functions in this file. They are too lengthy.

Quoted 3 lines

sound/pcm-indirect.h contain inline functions becuase they are relatively small, and I didn't want to add them in the core module unconditionally.

I looked at my functions again. And I think we could still go with inline for the *_interrupt() and *_pointer() functions since they have just a few lines.
With both *_transfer() functions - I don't know. In fact they shouldn't be much longer than yours in pcm-indirect.h . They seem long, because there are lot of comments and the #ifdef SND_PCM_INDIRECT2_STAT stuff, which is/was a debugging feature, which _won't_ be compiled in without CONFIG_SND_DEBUG.

[I removed inline from the _stat() and _min_periods() function - that's true, they are too long.]

The other thing I thought about, is: Is it ok to have non-inline functions in a header file? Don't we need a .c file + .h ? (Are there any CodingStyle rules about that?)

Joachim

#5 lore raw

At Fri, 10 Aug 2007 13:50:40 +0200,

Quoted 13 lines · Joachim Förster

Hi Takashi,

again some question came up (while correcting all the other issues):

Quoted 6 lines · Takashi Iwai

sound/ppc/ml403_ac97cr.c line 1044

Quoted 3 lines
sound/ppc/ml403_ac97cr.c new file +3 -0
+static int __init
+snd_ml403_ac97cr_create(struct snd_card *card, struct platform_device *pfdev,
+			struct snd_ml403_ac97cr **rml403_ac97cr)

It's no longer __init as long as you use platform_device. It should be __devinit instead.

Quoted 4 lines

Ok, I changed that (for create(), pcm(), mixer(), etc.). Do I have to change it for the module_init and module_exit functions, too? I guess, they are not in the "scope" of platform device, right? So, they will keep __init / __exit ?

Yes, they can be __init & __exit.

Quoted 13 lines
Quoted 9 lines
Quoted 2 lines
sound/ppc/pcm-indirect2.h new file +0 -0

(snip)

sound/ppc/pcm-indirect2.h line 117

Quoted 3 lines
sound/ppc/pcm-indirect2.h new file +3 -0
+#ifdef SND_PCM_INDIRECT2_STAT
+static inline void snd_pcm_indirect2_stat(struct snd_pcm_substream *substream,
+					  struct snd_pcm_indirect2 *rec)

Remove inline from the functions in this file. They are too lengthy.

Quoted 3 lines

sound/pcm-indirect.h contain inline functions becuase they are relatively small, and I didn't want to add them in the core module unconditionally.

Quoted 8 lines

I looked at my functions again. And I think we could still go with inline for the *_interrupt() and *_pointer() functions since they have just a few lines.
With both *_transfer() functions - I don't know. In fact they shouldn't be much longer than yours in pcm-indirect.h . They seem long, because there are lot of comments and the #ifdef SND_PCM_INDIRECT2_STAT stuff, which is/was a debugging feature, which _won't_ be compiled in without CONFIG_SND_DEBUG.

IMO, the inline isn't usually necessary unless it hits really the performance. Let the compiler optimize the codes. The size reduction often wins in the end than inlining.

Quoted 6 lines

[I removed inline from the _stat() and _min_periods() function - that's true, they are too long.]

The other thing I thought about, is: Is it ok to have non-inline functions in a header file? Don't we need a .c file + .h ? (Are there any CodingStyle rules about that?)

Yeah, *.c sounds more appropriate.

Takashi

#6 lore raw

Re: [PATCHv2 1/2] Xilinx ML403 AC97 Controller Reference device driver

In reply to Takashi Iwai

Hi Takashi, Grant, Stephen,

I tried to correct the issues you pointed out and below you'll find a new version of my patch. Maybe important changes:
- I moved to sound/drivers, so there will be less problems as soon as somebody confirms that it works on MicroBlaze, too.
- I removed the inline stuff from pcm-indirect2.h and split it into a .c file and a .h file.
@Stephen: Wolfgang Reissnegger's changes don't exist in any "(un)official" branches, so I thought I stay with XILINX_VIRTEX - anyway, it's a very small change to make - so we might do this later. Or did I overlook something?

From: Joachim Foerster <[email protected]>

Add ALSA support for the opb_ac97_controller_ref_v1_00_a ip core found in Xilinx' ML403 reference design.

Known issue: Currently this driver hits a WARN_ON_ONCE(1) statement in kernel/irq/resend.c (line 70). According to Linus
(http://lkml.org/lkml/2007/8/5/5) this may be ignored, right? I haven't had a look into this "problem" yet.

(Patch for Linus' master branch, date 2007/08/08)

This patchset _will_ be published on
http://www.esic-solutions.com/support.html soon (like the first version of the driver (tar file), but this may take some time ...).

---
 sound/drivers/Kconfig         |   12 +
 sound/drivers/Makefile        |    2 +
 sound/drivers/ml403-ac97cr.c  | 1353 +++++++++++++++++++++++++++++++++++++++++
 sound/drivers/pcm-indirect2.c |  591 ++++++++++++++++++
 sound/drivers/pcm-indirect2.h |  140 +++++
 5 files changed, 2098 insertions(+), 0 deletions(-)
 create mode 100644 sound/drivers/ml403-ac97cr.c
 create mode 100644 sound/drivers/pcm-indirect2.c
 create mode 100644 sound/drivers/pcm-indirect2.h
sound/drivers/Kconfig +12 -0
index 83529b0..6716adf 100644
@@ -120,4 +120,16 @@ config SND_PORTMAN2X4
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-portman2x4.
 
+config SND_ML403_AC97CR
+       tristate "Xilinx ML403 AC97 Controller Reference"
+       depends on SND && XILINX_VIRTEX
+       select SND_AC97_CODEC
+       help
+         Say Y here to include support for the
+         opb_ac97_controller_ref_v1_00_a ip core found in Xilinx' ML403
+         reference design.
+
+         To compile this driver as a module, choose M here: the module
+         will be called snd-ml403_ac97cr.
+
 endmenu
sound/drivers/Makefile +2 -0
index 0411264..c5a9471 100644
@@ -9,6 +9,7 @@ snd-mts64-objs := mts64.o
 snd-portman2x4-objs := portman2x4.o
 snd-serial-u16550-objs := serial-u16550.o
 snd-virmidi-objs := virmidi.o
+snd-ml403-ac97cr-objs := ml403-ac97cr.o pcm-indirect2.o
 
 # Toplevel Module Dependency
 obj-$(CONFIG_SND_DUMMY) += snd-dummy.o
@@ -17,5 +18,6 @@ obj-$(CONFIG_SND_SERIAL_U16550) += snd-serial-u16550.o
 obj-$(CONFIG_SND_MTPAV) += snd-mtpav.o
 obj-$(CONFIG_SND_MTS64) += snd-mts64.o
 obj-$(CONFIG_SND_PORTMAN2X4) += snd-portman2x4.o
+obj-$(CONFIG_SND_ML403_AC97CR) += snd-ml403-ac97cr.o
 
 obj-$(CONFIG_SND) += opl3/ opl4/ mpu401/ vx/
sound/drivers/ml403-ac97cr.c new file +1353 -0

1,353 lines not on this page · raw message

sound/drivers/pcm-indirect2.c new file +591 -0

591 lines not on this page · raw message

sound/drivers/pcm-indirect2.h new file +140 -0

140 lines not on this page · raw message

Signature · 1 line
1.5.2.4
#7 lore raw

Re: [PATCH] [ML403-AC97CR] Fix (device/driver) name registered with platform bus

Hi all,

below, you'll find a very small patch: In the current state, platform bus _never_ activates (= calls probe() callback on) the driver, because the driver's name has a dash and the device's name has an underscore. I made this horrible change _after_ I tested the final patch, which I posted on Saturday. Sorry.

From: Joachim Foerster <[email protected]>

Names inside struct platform_device and struct platform_driver seem to need underscores instead of dashes.

(Patch for Linus' master branch, date 2007/08/08 _including_ my patches sent on Saturday)

---
 arch/ppc/syslib/virtex_devices.c |    2 +-
 sound/drivers/ml403-ac97cr.c     |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
arch/ppc/syslib/virtex_devices.c +1 -1
index d0b04d6..9fa10b1 100644
@@ -122,7 +122,7 @@
 }
 
 #define XPAR_AC97_CONTROLLER_REFERENCE(num) { \
-	.name = "ml403-ac97cr", \
+	.name = "ml403_ac97cr", \
 	.id = num, \
 	.num_resources = 3, \
 	.resource = (struct resource[]) { \
sound/drivers/ml403-ac97cr.c +1 -1
index 2222315..2636249 100644
@@ -66,7 +66,7 @@
 #include "pcm-indirect2.h"
 
 
-#define SND_ML403_AC97CR_DRIVER "ml403-ac97cr"
+#define SND_ML403_AC97CR_DRIVER "ml403_ac97cr"
 
 MODULE_AUTHOR("Joachim Foerster <[email protected]>");
 MODULE_DESCRIPTION("Xilinx ML403 AC97 Controller Reference");
Signature · 1 line
1.5.2.4
#8 lore raw

Re: [PATCHv2 2/2] [VIRTEX] Register AC97 Controller Reference with the platform bus

In reply to Takashi Iwai

Hi Grant, Takashi, Stephen,

I tried to correct the issues here, too. But unfortunately Xilinx EDK uses such long #define macro names. I guess we have to leave it the way it is?

From: Joachim Foerster <[email protected]>

(Patch for Linus' master branch, date 2007/08/08)

---
 arch/ppc/syslib/virtex_devices.c |   28 ++++++++++++++++++++++++++++
 1 files changed, 28 insertions(+), 0 deletions(-)
arch/ppc/syslib/virtex_devices.c +28 -0
index 62a9495..d0b04d6 100644
@@ -121,6 +121,29 @@
 	}, \
 }
 
+#define XPAR_AC97_CONTROLLER_REFERENCE(num) { \
+	.name = "ml403-ac97cr", \
+	.id = num, \
+	.num_resources = 3, \
+	.resource = (struct resource[]) { \
+		{ \
+			.start = XPAR_OPB_AC97_CONTROLLER_REF_##num##_BASEADDR, \
+			.end = XPAR_OPB_AC97_CONTROLLER_REF_##num##_HIGHADDR, \
+			.flags = IORESOURCE_MEM, \
+		}, \
+		{ \
+			.start = XPAR_OPB_INTC_0_OPB_AC97_CONTROLLER_REF_##num##_PLAYBACK_INTERRUPT_INTR, \
+			.end = XPAR_OPB_INTC_0_OPB_AC97_CONTROLLER_REF_##num##_PLAYBACK_INTERRUPT_INTR, \
+			.flags = IORESOURCE_IRQ, \
+		}, \
+		{ \
+			.start = XPAR_OPB_INTC_0_OPB_AC97_CONTROLLER_REF_##num##_RECORD_INTERRUPT_INTR, \
+			.end = XPAR_OPB_INTC_0_OPB_AC97_CONTROLLER_REF_##num##_RECORD_INTERRUPT_INTR, \
+			.flags = IORESOURCE_IRQ, \
+		}, \
+	}, \
+}
+
 /* UART 8250 driver platform data table */
 struct plat_serial8250_port virtex_serial_platform_data[] = {
 #if defined(XPAR_UARTNS550_0_BASEADDR)
@@ -221,6 +244,11 @@ struct platform_device virtex_platform_devices[] = {
 #if defined(XPAR_TFT_3_BASEADDR)
 	XPAR_TFT(3),
 #endif
+
+	/* AC97 Controller Reference instances */
+#if defined(XPAR_OPB_AC97_CONTROLLER_REF_0_BASEADDR)
+	XPAR_AC97_CONTROLLER_REFERENCE(0),
+#endif
 };
 
 /* Early serial support functions */
Signature · 1 line
1.5.2.4
#9 lore raw
In reply to Joachim Förster
Quoted 10 lines · Joachim Förster

From: Joachim Foerster <[email protected]>

Add ALSA support for the opb_ac97_controller_ref_v1_00_a ip core found in Xilinx' ML403 reference design.

Known issue: Currently this driver hits a WARN_ON_ONCE(1) statement in kernel/irq/resend.c (line 70). According to Linus
(http://lkml.org/lkml/2007/8/5/5) this may be ignored, right? I haven't had a look into this "problem" yet.

Quoted 5 lines

(Patch for Linus' master branch, date 2007/08/08)

This patchset _will_ be published on
http://www.esic-solutions.com/support.html soon (like the first version of the driver (tar file), but this may take some days ...).

Comments below

sound/ppc/Makefile

Quoted 4 lines
sound/ppc/Makefile +0 -0
index eacee2d..827f2f5 100644

Couldn't this end up on MicroBlaze too? If so, sound/ppc is the wrong place.

sound/ppc/Makefile line 7

Quoted 5 lines
sound/ppc/Makefile +1 -0
@@ -4,7 +4,9 @@
 #
 
 snd-powermac-objs := powermac.o pmac.o awacs.o burgundy.o daca.o tumbler.o keywest.o beep.o
+snd-ml403_ac97cr-objs := ml403_ac97cr.o

This line is only needed if you're compiling multiple .c files into one .ko

Quoted 58 lines
sound/ppc/Makefile +1 -0
 # Toplevel Module Dependency
 obj-$(CONFIG_SND_POWERMAC)     += snd-powermac.o
 obj-$(CONFIG_SND_PS3)          += snd_ps3.o
+obj-$(CONFIG_SND_ML403_AC97CR) += snd-ml403_ac97cr.o
sound/ppc/ml403_ac97cr.c new file +47 -0
new file mode 100644
index 0000000..99791d7
@@ -0,0 +1,1274 @@
+
+/*  ALSA driver for Xilinx ML403 AC97 Controller Reference
+ *    IP: opb_ac97_controller_ref_v1_00_a (EDK 8.1i)
+ *    IP: opb_ac97_controller_ref_v1_00_a (EDK 9.1i)
+ *
+ *  Copyright (c) by 2007  Joachim Foerster <[email protected]>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#include <sound/driver.h>
+#include <linux/init.h>
+#include <linux/moduleparam.h>
+
+#include <linux/platform_device.h>
+
+#include <linux/ioport.h>
+#include <asm/io.h>
+#include <linux/interrupt.h>
+
+/* HZ */
+#include <linux/param.h>
+/* jiffies, time_*() */
+#include <linux/jiffies.h>
+/* schedule_timeout*() */
+#include <linux/sched.h>
+/* spin_lock*() */
+#include <linux/spinlock.h>
+
+/* snd_printk(), snd_printd() */
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/initval.h>

sound/ppc/ml403_ac97cr.c line 57

Quoted 10 lines
sound/ppc/ml403_ac97cr.c new file +10 -0
+#include <sound/ac97_codec.h>
+
+
+#define SND_ML403_AC97CR_DRIVER "ml403_ac97cr"
+
+MODULE_AUTHOR("Joachim Foerster <[email protected]>");
+MODULE_DESCRIPTION("Xilinx ML403 AC97 Controller Reference");
+MODULE_LICENSE("GPL");
+MODULE_SUPPORTED_DEVICE("{{Xilinx,ML403 AC97 Controller Reference}}");
+MODULE_VERSION("0.0.1-pre2");

This patch is targeted for mainline inclusion (which gives you the kernel version number). Do you really want to maintain a separate version number that needs to be update manually? I'd drop the MODULE_VERSION line.

<snip>

I'm not an ALSA expert, so I didn't review the rest of the code in detail (but I didn't see anything to comment on with a quick review). I'll try adding your patches to my tree this afternoon.

g.

Signature · 4 lines
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
[email protected]
(403) 399-0195
#10 lore raw

Hi Grant,

Quoted 6 lines · Grant Likely

sound/ppc/Makefile

Quoted 4 lines
sound/ppc/Makefile +0 -0
index eacee2d..827f2f5 100644

Couldn't this end up on MicroBlaze too? If so, sound/ppc is the wrong place.

Well, I don't know. The only arch depended calls I use (am aware of) are in/out_be32(), so this _might_ work for mb, too. (I won't be able to test that in the next few months ...)

Quoted 10 lines · Stephen Neuendorffer

I second grant here... this should eventually work on microblaze, too,
so putting it drivers/ and using XILINX_DRIVERS instead of XILINX_VIRTEX (based on the patch Wolfgang recently posted) would probably be preferable.

sound/ppc/Makefile

Quoted 4 lines
sound/ppc/Makefile +4 -0
+
+config SND_ML403_AC97CR
+       tristate "Xilinx ML403 AC97 Controller Reference"
+       depends on SND && XILINX_VIRTEX

Steve

So, like Stephen Neuendorffer said, I should move it to sound/drivers, right? Takashi?

Quoted 3 lines · Grant Likely
Quoted 1 line

+snd-ml403_ac97cr-objs := ml403_ac97cr.o

This line is only needed if you're compiling multiple .c files into one .ko

Ah, well, then I have to rename the main .c file. But all the other ALSA drivers seem to _not_ include the "snd-" in front of it (ok, except the new PS3 driver and maybe other new ones?)

Quoted 1 line

I'll try adding your patches to my tree this afternoon.

I made patch against your tree, too (like a said before). Tell me, then I post it ...

Joachim

#11 lore raw
Quoted 35 lines · Joachim Förster

Hi Grant,

Quoted 6 lines · Grant Likely

sound/ppc/Makefile

Quoted 4 lines
sound/ppc/Makefile +0 -0
index eacee2d..827f2f5 100644

Couldn't this end up on MicroBlaze too? If so, sound/ppc is the wrong place.

Well, I don't know. The only arch depended calls I use (am aware of) are in/out_be32(), so this _might_ work for mb, too. (I won't be able to test that in the next few months ...)

Quoted 10 lines · Stephen Neuendorffer

I second grant here... this should eventually work on microblaze, too,
so putting it drivers/ and using XILINX_DRIVERS instead of XILINX_VIRTEX (based on the patch Wolfgang recently posted) would probably be preferable.

sound/ppc/Makefile

Quoted 4 lines
sound/ppc/Makefile +4 -0
+
+config SND_ML403_AC97CR
+       tristate "Xilinx ML403 AC97 Controller Reference"
+       depends on SND && XILINX_VIRTEX

Steve

So, like Stephen Neuendorffer said, I should move it to sound/drivers, right? Takashi?

Quoted 3 lines · Grant Likely
Quoted 1 line

+snd-ml403_ac97cr-objs := ml403_ac97cr.o

This line is only needed if you're compiling multiple .c files into one .ko

Quoted 8 lines

Ah, well, then I have to rename the main .c file. But all the other ALSA drivers seem to _not_ include the "snd-" in front of it (ok, except the new PS3 driver and maybe other new ones?)

Quoted 1 line

I'll try adding your patches to my tree this afternoon.

I made patch against your tree, too (like a said before). Tell me, then I post it ...

No, don't base against my tree. You worry about mainline; I'll worry about my tree. :-)

My tree gets rebased periodically anyway, so it's a much harder target.

Quoted 5 lines

Joachim

Signature · 4 lines
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
[email protected]
(403) 399-0195
#12 lore raw
In reply to Joachim Förster

At Thu, 09 Aug 2007 22:01:40 +0200,

Quoted 27 lines · Joachim Förster

Hi Grant,

Quoted 6 lines · Grant Likely

sound/ppc/Makefile

Quoted 4 lines
sound/ppc/Makefile +0 -0
index eacee2d..827f2f5 100644

Couldn't this end up on MicroBlaze too? If so, sound/ppc is the wrong place.

Well, I don't know. The only arch depended calls I use (am aware of) are in/out_be32(), so this _might_ work for mb, too. (I won't be able to test that in the next few months ...)

Quoted 10 lines · Stephen Neuendorffer

I second grant here... this should eventually work on microblaze, too,
so putting it drivers/ and using XILINX_DRIVERS instead of XILINX_VIRTEX (based on the patch Wolfgang recently posted) would probably be preferable.

sound/ppc/Makefile

Quoted 4 lines
sound/ppc/Makefile +4 -0
+
+config SND_ML403_AC97CR
+       tristate "Xilinx ML403 AC97 Controller Reference"
+       depends on SND && XILINX_VIRTEX

Steve

Quoted 2 lines

So, like Stephen Neuendorffer said, I should move it to sound/drivers, right? Takashi?

Well, yes, drivers appears like a more reasonable place.

Quoted 8 lines · Grant Likely
Quoted 3 lines
Quoted 1 line

+snd-ml403_ac97cr-objs := ml403_ac97cr.o

This line is only needed if you're compiling multiple .c files into one .ko

Ah, well, then I have to rename the main .c file. But all the other ALSA drivers seem to _not_ include the "snd-" in front of it (ok, except the new PS3 driver and maybe other new ones?)

Right. I prefer the file name should be without prefix, too. The snd- prefix came from a historical reason, to avoid the name crash with OSS drivers.

Takashi

#13 lore raw
In reply to Joachim Förster

I second grant here... this should eventually work on microblaze, too, so putting it drivers/ and using XILINX_DRIVERS instead of XILINX_VIRTEX (based on the patch Wolfgang recently posted) would probably be preferable.

sound/ppc/Kconfig config SND_PS3_DEFAULT_START_DELAY · line 58

Quoted 4 lines
sound/ppc/Kconfig +4 -0
+
+config SND_ML403_AC97CR
+       tristate "Xilinx ML403 AC97 Controller Reference"
+       depends on SND && XILINX_VIRTEX

Steve