At Sat, 5 Jul 2008 01:45:59 +0200 (CEST), Thomas Bogendoerfer wrote:
This patch adds a new ALSA driver for the audio device found inside most of the SGI O2 workstation. The hardware uses a SGI custom chip, which feeds a AD codec chip.
Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de
Please apply for 2.6.27.
Thanks for the patch. Below is a quick review.
diff --git a/sound/mips/Kconfig b/sound/mips/Kconfig index 531f8ba..a3e202e 100644 --- a/sound/mips/Kconfig +++ b/sound/mips/Kconfig @@ -11,5 +11,11 @@ config SND_AU1X00 help ALSA Sound driver for the Au1x00's AC97 port.
+config SND_SGI_O2
- tristate "SGI O2 Audio"
- depends on SND && SGI_IP32
helpSound support for the SGI O2 Workstation.endmenu
The recent version doesn't require "depends on SND" here because of changes to menuconfig. Check the latest ALSA tree or linux-next tree.
--- /dev/null +++ b/sound/mips/ad1843.c +const struct ad1843_gain ad1843_gain_RECLEV = {
- 0, &ad1843_LIG, &ad1843_RIG
+}; +const struct ad1843_gain ad1843_gain_LINE = {
- 1, &ad1843_LX1M, &ad1843_RX1M, &ad1843_LX1MM, &ad1843_RX1MM
+}; +const struct ad1843_gain ad1843_gain_LINE_2 = {
- 1, &ad1843_LDA2G, &ad1843_RDA2G, &ad1843_LDA2GM, &ad1843_RDA2GM
+}; +const struct ad1843_gain ad1843_gain_MIC = {
- 1, &ad1843_LMCM, &ad1843_RMCM, &ad1843_LMCMM, &ad1843_RMCMM
+}; +const struct ad1843_gain ad1843_gain_PCM_0 = {
- 1, &ad1843_LDA1G, &ad1843_RDA1G, &ad1843_LDA1GM, &ad1843_RDA1GM
+}; +const struct ad1843_gain ad1843_gain_PCM_1 = {
- 1, &ad1843_LD2M, &ad1843_RD2M, &ad1843_LD2MM, &ad1843_RD2MM
+};
Missing static?
+const struct ad1843_gain *ad1843_gain[AD1843_GAIN_SIZE] = +{
- &ad1843_gain_RECLEV,
- &ad1843_gain_LINE,
- &ad1843_gain_LINE_2,
- &ad1843_gain_MIC,
- &ad1843_gain_PCM_0,
- &ad1843_gain_PCM_1,
+};
Ditto. Also, better to use C99 style initialization.
+int ad1843_init(struct snd_ad1843 *ad1843) +{
- unsigned long later;
- if (ad1843_read_bits(ad1843, &ad1843_INIT) != 0) {
printk(KERN_ERR "ad1843: AD1843 won't initialize\n");return -EIO;- }
- ad1843_write_bits(ad1843, &ad1843_SCF, 1);
- /* 4. Put the conversion resources into standby. */
- ad1843_write_bits(ad1843, &ad1843_PDNI, 0);
- later = jiffies + HZ / 2; /* roughly half a second */
Use msecs_to_jiffies().
- while (ad1843_read_bits(ad1843, &ad1843_PDNO)) {
if (time_after(jiffies, later)) {printk(KERN_ERR"ad1843: AD1843 won't power up\n");return -EIO;}schedule();
No set_current_state() ?
--- /dev/null +++ b/sound/mips/sgio2audio.c +static int read_ad1843_reg(void *priv, int reg) +{
- struct snd_sgio2audio *chip = priv;
- int val;
- unsigned long flags;
- spin_lock_irqsave(&chip->ad1843_lock, flags);
- writeq((reg << CODEC_CONTROL_ADDRESS_SHIFT) |
CODEC_CONTROL_READ, &mace->perif.audio.codec_control);- wmb();
- val = readq(&mace->perif.audio.codec_control); /* flush bus */
- udelay(200);
It'd be nicer if this long delay can be avoided. Or, could it be mutex?
This isn't a fatal problem, so it's OK as is, though.
+static int __devinit snd_sgio2audio_create(struct snd_card *card,
struct snd_sgio2audio **rchip)+{
- struct snd_sgio2audio *chip;
- int i, err;
- *rchip = NULL;
- /* check if a codec is attached to the interface */
- /* (Audio or Audio/Video board present) */
- if (!(readq(&mace->perif.audio.control) & AUDIO_CONTROL_CODEC_PRESENT))
return -ENOENT;- chip = kzalloc(sizeof(struct snd_sgio2audio), GFP_KERNEL);
- if (chip == NULL)
return -ENOMEM;- chip->card = card;
- chip->ring_base = dma_alloc_coherent(NULL, MACEISA_RINGBUFFERS_SIZE,
&chip->ring_base_dma, GFP_USER);- if (chip->ring_base == NULL) {
printk(KERN_ERR"sgio2audio: could not allocate ring buffers\n");kfree(chip);return -ENOMEM;- }
- spin_lock_init(&chip->ad1843_lock);
- chip->volume = SGIO2AUDIO_MAX_VOLUME;
- /* initialize channels */
- for (i = 0; i < 3; i++) {
spin_lock_init(&chip->channel[i].lock);chip->channel[i].idx = i;- }
- /* allocate IRQs */
- for (i = 0; i < ARRAY_SIZE(snd_sgio2_isr_table); i++) {
if (request_irq(snd_sgio2_isr_table[i].irq,snd_sgio2_isr_table[i].isr,IRQF_SHARED,snd_sgio2_isr_table[i].desc,&chip->channel[snd_sgio2_isr_table[i].idx])) {snd_sgio2audio_free(chip);printk(KERN_ERR "sgio2audio: cannot allocate irq %d\n",snd_sgio2_isr_table[i].irq);return -EBUSY;}- }
If there are shared interrupts, they could be called before the initialization below. So, safer to move after the init.
thanks,
Takashi