Xlinx ML403 AC97 Controller Reference device driver
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
@@ -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
@@ -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
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_opssnd_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
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 alsoAC97_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_CONTINUOUSandRATE_KNOWare 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
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 alsoAC97_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_CONTINUOUSandRATE_KNOWare usually exclusive.Ok, so what I want is
RATE_CONTINUOUS, right? (because the LM4550 supports 4000 to 48000kHz in 1Hz steps)
BTW: What isRATE_KNOTgood 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
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
__initas long as you useplatform_device. It should be__devinitinstead.
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.hcontain 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
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
__initas long as you useplatform_device. It should be__devinitinstead.
Quoted 4 lines
Ok, I changed that (for
create(),pcm(),mixer(), etc.). Do I have to change it for themodule_initandmodule_exitfunctions, 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.hcontain 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 inpcm-indirect.h. They seem long, because there are lot of comments and the #ifdefSND_PCM_INDIRECT2_STATstuff, which is/was a debugging feature, which _won't_ be compiled in withoutCONFIG_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
Re: [PATCHv2 1/2] Xilinx ML403 AC97 Controller Reference device driver
In reply to Takashi IwaiHi 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
@@ -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
@@ -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
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
@@ -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
@@ -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
Re: [PATCHv2 2/2] [VIRTEX] Register AC97 Controller Reference with the platform bus
In reply to Takashi IwaiHi 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
@@ -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
Quoted 10 lines · Joachim Förster
From: Joachim Foerster <[email protected]>
Add ALSA support for the
opb_ac97_controller_ref_v1_00_aip core found in Xilinx' ML403 reference design.Known issue: Currently this driver hits a
WARN_ON_ONCE(1)statement inkernel/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
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.osound/ppc/ml403_ac97cr.c new file +47
-0@@ -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
Hi Grant,
Quoted 6 lines · Grant Likely
sound/ppc/Makefile
Quoted 4 lines
sound/ppc/Makefile +0
-0Couldn't this end up on MicroBlaze too? If so,
sound/ppcis 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 itdrivers/and usingXILINX_DRIVERSinstead ofXILINX_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_VIRTEXSteve
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
Quoted 35 lines · Joachim Förster
Hi Grant,
Quoted 6 lines · Grant Likely
sound/ppc/Makefile
Quoted 4 lines
sound/ppc/Makefile +0
-0Couldn't this end up on MicroBlaze too? If so,
sound/ppcis 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 itdrivers/and usingXILINX_DRIVERSinstead ofXILINX_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_VIRTEXSteve
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
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
-0Couldn't this end up on MicroBlaze too? If so,
sound/ppcis 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 itdrivers/and usingXILINX_DRIVERSinstead ofXILINX_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_VIRTEXSteve
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
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