Package: kernel-source-2.6.8

Thanks Julien. I now forward this to the kernel-source-2.6.8 package in order
to not lose it in my mail archive.

Friendly,

Sven Luther

On Wed, Sep 08, 2004 at 11:44:56AM +0200, Julien BLACHE wrote:
> Sven Luther <[EMAIL PROTECTED]> wrote:
> 
> Hi Sven,
> 
> >> Use filterdiff (patchutils) to filter the changes made to sound/ppc/*,
> >> and here's your diff.
> >
> > I am over busy with other stuff right now, but would you care to do this and
> > send me the patch (or fill a bug report) ?
> 
> Here it is. beep.patch contains everything related to the beep
> support. chips.patch contains the other changes to the files in
> sound/ppc, which are bugfixes and new features for the awacs, daca,
> tumbler and burgundy chips.
> 
> The changes in chips.patch are minimal, you could apply them too
> without any problem.
> 
> I didn't try to build with the patches applied (lacking time), but
> reading the diff there's nothing that should break.
> 
> JB.
> 
> -- 
>  Julien BLACHE - Debian & GNU/Linux Developer - <[EMAIL PROTECTED]> 
>  
>  Public key available on <http://www.jblache.org> - KeyID: F5D6 5169 
>  GPG Fingerprint : 935A 79F1 C8B3 3521 FD62 7CC7 CD61 4FD7 F5D6 5169 
> 

Content-Description: Beep support for PowerMac
> --- linux-2.5-plain/sound/ppc/beep.c  1970-01-01 01:00:00.000000000 +0100
> +++ linux-sound-plain/sound/ppc/beep.c        2004-08-26 21:17:10.000000000 
> +0200
> @@ -0,0 +1,262 @@
> +/*
> + * Beep using pcm
> + *
> + * Copyright (c) by Takashi Iwai <[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 <asm/io.h>
> +#include <asm/irq.h>
> +#include <linux/init.h>
> +#include <linux/slab.h>
> +#include <linux/input.h>
> +#include <sound/core.h>
> +#include <sound/control.h>
> +#include "pmac.h"
> +
> +struct snd_pmac_beep {
> +     int running;    /* boolean */
> +     int volume;     /* mixer volume: 0-100 */
> +     int volume_play;        /* currently playing volume */
> +     int hz;
> +     int nsamples;
> +     short *buf;             /* allocated wave buffer */
> +     unsigned long addr;     /* physical address of buffer */
> +     struct input_dev dev;
> +};
> +
> +/*
> + * stop beep if running
> + */
> +void snd_pmac_beep_stop(pmac_t *chip)
> +{
> +     pmac_beep_t *beep = chip->beep;
> +     if (beep && beep->running) {
> +             beep->running = 0;
> +             snd_pmac_beep_dma_stop(chip);
> +     }
> +}
> +
> +/*
> + * Stuff for outputting a beep.  The values range from -327 to +327
> + * so we can multiply by an amplitude in the range 0..100 to get a
> + * signed short value to put in the output buffer.
> + */
> +static short beep_wform[256] = {
> +     0,      40,     79,     117,    153,    187,    218,    245,
> +     269,    288,    304,    316,    323,    327,    327,    324,
> +     318,    310,    299,    288,    275,    262,    249,    236,
> +     224,    213,    204,    196,    190,    186,    183,    182,
> +     182,    183,    186,    189,    192,    196,    200,    203,
> +     206,    208,    209,    209,    209,    207,    204,    201,
> +     197,    193,    188,    183,    179,    174,    170,    166,
> +     163,    161,    160,    159,    159,    160,    161,    162,
> +     164,    166,    168,    169,    171,    171,    171,    170,
> +     169,    167,    163,    159,    155,    150,    144,    139,
> +     133,    128,    122,    117,    113,    110,    107,    105,
> +     103,    103,    103,    103,    104,    104,    105,    105,
> +     105,    103,    101,    97,     92,     86,     78,     68,
> +     58,     45,     32,     18,     3,      -11,    -26,    -41,
> +     -55,    -68,    -79,    -88,    -95,    -100,   -102,   -102,
> +     -99,    -93,    -85,    -75,    -62,    -48,    -33,    -16,
> +     0,      16,     33,     48,     62,     75,     85,     93,
> +     99,     102,    102,    100,    95,     88,     79,     68,
> +     55,     41,     26,     11,     -3,     -18,    -32,    -45,
> +     -58,    -68,    -78,    -86,    -92,    -97,    -101,   -103,
> +     -105,   -105,   -105,   -104,   -104,   -103,   -103,   -103,
> +     -103,   -105,   -107,   -110,   -113,   -117,   -122,   -128,
> +     -133,   -139,   -144,   -150,   -155,   -159,   -163,   -167,
> +     -169,   -170,   -171,   -171,   -171,   -169,   -168,   -166,
> +     -164,   -162,   -161,   -160,   -159,   -159,   -160,   -161,
> +     -163,   -166,   -170,   -174,   -179,   -183,   -188,   -193,
> +     -197,   -201,   -204,   -207,   -209,   -209,   -209,   -208,
> +     -206,   -203,   -200,   -196,   -192,   -189,   -186,   -183,
> +     -182,   -182,   -183,   -186,   -190,   -196,   -204,   -213,
> +     -224,   -236,   -249,   -262,   -275,   -288,   -299,   -310,
> +     -318,   -324,   -327,   -327,   -323,   -316,   -304,   -288,
> +     -269,   -245,   -218,   -187,   -153,   -117,   -79,    -40,
> +};
> +
> +#define BEEP_SRATE   22050   /* 22050 Hz sample rate */
> +#define BEEP_BUFLEN  512
> +#define BEEP_VOLUME  15      /* 0 - 100 */
> +
> +static int snd_pmac_beep_event(struct input_dev *dev, unsigned int type, 
> unsigned int code, int hz)
> +{
> +     pmac_t *chip;
> +     pmac_beep_t *beep;
> +     unsigned long flags;
> +     int beep_speed = 0;
> +     int srate;
> +     int period, ncycles, nsamples;
> +     int i, j, f;
> +     short *p;
> +
> +     if (type != EV_SND)
> +             return -1;
> +
> +     switch (code) {
> +     case SND_BELL: if (hz) hz = 1000;
> +     case SND_TONE: break;
> +     default: return -1;
> +     }
> +
> +     chip = dev->private;
> +     if (! chip || (beep = chip->beep) == NULL)
> +             return -1;
> +
> +     if (! hz) {
> +             spin_lock_irqsave(&chip->reg_lock, flags);
> +             if (beep->running)
> +                     snd_pmac_beep_stop(chip);
> +             spin_unlock_irqrestore(&chip->reg_lock, flags);
> +             return 0;
> +     }
> +
> +     beep_speed = snd_pmac_rate_index(chip, &chip->playback, BEEP_SRATE);
> +     srate = chip->freq_table[beep_speed];
> +
> +     if (hz <= srate / BEEP_BUFLEN || hz > srate / 2)
> +             hz = 1000;
> +
> +     spin_lock_irqsave(&chip->reg_lock, flags);
> +     if (chip->playback.running || chip->capture.running || beep->running) {
> +             spin_unlock_irqrestore(&chip->reg_lock, flags);
> +             return 0;
> +     }
> +     beep->running = 1;
> +     spin_unlock_irqrestore(&chip->reg_lock, flags);
> +
> +     if (hz == beep->hz && beep->volume == beep->volume_play) {
> +             nsamples = beep->nsamples;
> +     } else {
> +             period = srate * 256 / hz;      /* fixed point */
> +             ncycles = BEEP_BUFLEN * 256 / period;
> +             nsamples = (period * ncycles) >> 8;
> +             f = ncycles * 65536 / nsamples;
> +             j = 0;
> +             p = beep->buf;
> +             for (i = 0; i < nsamples; ++i, p += 2) {
> +                     p[0] = p[1] = beep_wform[j >> 8] * beep->volume;
> +                     j = (j + f) & 0xffff;
> +             }
> +             beep->hz = hz;
> +             beep->volume_play = beep->volume;
> +             beep->nsamples = nsamples;
> +     }
> +
> +     spin_lock_irqsave(&chip->reg_lock, flags);
> +     snd_pmac_beep_dma_start(chip, beep->nsamples * 4, beep->addr, 
> beep_speed);
> +     spin_unlock_irqrestore(&chip->reg_lock, flags);
> +     return 0;
> +}
> +
> +/*
> + * beep volume mixer
> + */
> +
> +#define chip_t pmac_t
> +
> +static int snd_pmac_info_beep(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t 
> *uinfo)
> +{
> +     uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
> +     uinfo->count = 1;
> +     uinfo->value.integer.min = 0;
> +     uinfo->value.integer.max = 100;
> +     return 0;
> +}
> +
> +static int snd_pmac_get_beep(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t 
> *ucontrol)
> +{
> +     pmac_t *chip = snd_kcontrol_chip(kcontrol);
> +     snd_assert(chip->beep, return -ENXIO);
> +     ucontrol->value.integer.value[0] = chip->beep->volume;
> +     return 0;
> +}
> +
> +static int snd_pmac_put_beep(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t 
> *ucontrol)
> +{
> +     pmac_t *chip = snd_kcontrol_chip(kcontrol);
> +     int oval;
> +     snd_assert(chip->beep, return -ENXIO);
> +     oval = chip->beep->volume;
> +     chip->beep->volume = ucontrol->value.integer.value[0];
> +     return oval != chip->beep->volume;
> +}
> +
> +static snd_kcontrol_new_t snd_pmac_beep_mixer = {
> +     .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
> +     .name = "Beep Playback Volume",
> +     .info = snd_pmac_info_beep,
> +     .get = snd_pmac_get_beep,
> +     .put = snd_pmac_put_beep,
> +};
> +
> +/* Initialize beep stuff */
> +int __init snd_pmac_attach_beep(pmac_t *chip)
> +{
> +     pmac_beep_t *beep;
> +     int err;
> +
> +     beep = kmalloc(sizeof(*beep), GFP_KERNEL);
> +     if (! beep)
> +             return -ENOMEM;
> +
> +     memset(beep, 0, sizeof(*beep));
> +     beep->buf = (short *) kmalloc(BEEP_BUFLEN * 4, GFP_KERNEL);
> +     if (! beep->buf) {
> +             kfree(beep);
> +             return -ENOMEM;
> +     }
> +     beep->addr = virt_to_bus(beep->buf);
> +
> +     beep->dev.evbit[0] = BIT(EV_SND);
> +     beep->dev.sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
> +     beep->dev.event = snd_pmac_beep_event;
> +     beep->dev.private = chip;
> +
> +     /* FIXME: set more better values */
> +     beep->dev.name = "PowerMac Beep";
> +     beep->dev.phys = "powermac/beep";
> +     beep->dev.id.bustype = BUS_ADB;
> +     beep->dev.id.vendor = 0x001f;
> +     beep->dev.id.product = 0x0001;
> +     beep->dev.id.version = 0x0100;
> +
> +     beep->volume = BEEP_VOLUME;
> +     beep->running = 0;
> +     if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_pmac_beep_mixer, 
> chip))) < 0) {
> +             kfree(beep->buf);
> +             kfree(beep);
> +             return err;
> +     }
> +
> +     chip->beep = beep;
> +     input_register_device(&beep->dev);
> +
> +     return 0;
> +}
> +
> +void snd_pmac_detach_beep(pmac_t *chip)
> +{
> +     if (chip->beep) {
> +             input_unregister_device(&chip->beep->dev);
> +             kfree(chip->beep->buf);
> +             kfree(chip->beep);
> +             chip->beep = NULL;
> +     }
> +}
> --- linux-2.5-plain/sound/ppc/Kconfig 2004-08-26 21:01:50.000000000 +0200
> +++ linux-sound-plain/sound/ppc/Kconfig       2004-08-26 21:16:11.000000000 
> +0200
> @@ -6,9 +6,12 @@
>  comment "ALSA PowerMac requires I2C"
>       depends on SND && I2C=n
>  
> +comment "ALSA PowerMac requires INPUT"
> +     depends on SND && INPUT=n
> +
>  config SND_POWERMAC
>       tristate "PowerMac (AWACS, DACA, Burgundy, Tumbler, Keywest)"
> -     depends on SND && I2C
> +     depends on SND && I2C && INPUT
>       select SND_PCM
>  
>  endmenu
> --- linux-2.5-plain/sound/ppc/Makefile        2004-08-26 21:01:48.000000000 
> +0200
> +++ linux-sound-plain/sound/ppc/Makefile      2004-08-26 21:16:09.000000000 
> +0200
> @@ -3,7 +3,7 @@
>  # Copyright (c) 2001 by Jaroslav Kysela <[EMAIL PROTECTED]>
>  #
>  
> -snd-powermac-objs := powermac.o pmac.o awacs.o burgundy.o daca.o tumbler.o 
> keywest.o
> +snd-powermac-objs := powermac.o pmac.o awacs.o burgundy.o daca.o tumbler.o 
> keywest.o beep.o
>  
>  # Toplevel Module Dependency
>  obj-$(CONFIG_SND_POWERMAC) += snd-powermac.o
> --- linux-2.5-plain/sound/ppc/pmac.c  2004-08-26 21:05:32.000000000 +0200
> +++ linux-sound-plain/sound/ppc/pmac.c        2004-08-26 21:20:59.000000000 
> +0200
> @@ -36,8 +36,6 @@
>  #include <asm/feature.h>
>  #endif
>  
> -#define chip_t pmac_t
> -
>  
>  #if defined(CONFIG_PM) && defined(CONFIG_PMAC_PBOOK)
>  static int snd_pmac_register_sleep_notifier(pmac_t *chip);
> @@ -52,8 +50,8 @@
>       44100, 29400, 22050, 17640, 14700, 11025, 8820, 7350
>  };
>  /* fixed frequency table for tumbler */
> -static int tumbler_freqs[2] = {
> -     48000, 44100
> +static int tumbler_freqs[1] = {
> +     44100
>  };
>  
>  /*
> @@ -86,7 +84,7 @@
>   * look up frequency table
>   */
>  
> -static unsigned int snd_pmac_rate_index(pmac_t *chip, pmac_stream_t *rec, 
> unsigned int rate)
> +unsigned int snd_pmac_rate_index(pmac_t *chip, pmac_stream_t *rec, unsigned 
> int rate)
>  {
>       int i, ok, found;
>  
> @@ -203,7 +201,6 @@
>  {
>       int i;
>       volatile struct dbdma_cmd *cp;
> -     unsigned long flags;
>       snd_pcm_runtime_t *runtime = subs->runtime;
>       int rate_index;
>       long offset;
> @@ -226,15 +223,17 @@
>       /* We really want to execute a DMA stop command, after the AWACS
>        * is initialized.
>        * For reasons I don't understand, it stops the hissing noise
> -      * common to many PowerBook G3 systems (like mine :-).
> +      * common to many PowerBook G3 systems and random noise otherwise
> +      * captured on iBook2's about every third time. -ReneR
>        */
> -     spin_lock_irqsave(&chip->reg_lock, flags);
> +     spin_lock_irq(&chip->reg_lock);
>       snd_pmac_dma_stop(rec);
> -     if (rec->stream == SNDRV_PCM_STREAM_PLAYBACK) {
> -             st_le16(&chip->extra_dma.cmds->command, DBDMA_STOP);
> -             snd_pmac_dma_set_command(rec, &chip->extra_dma);
> -             snd_pmac_dma_run(rec, RUN);
> -     }
> +     st_le16(&chip->extra_dma.cmds->command, DBDMA_STOP);
> +     snd_pmac_dma_set_command(rec, &chip->extra_dma);
> +     snd_pmac_dma_run(rec, RUN);
> +     spin_unlock_irq(&chip->reg_lock);
> +     mdelay(5);
> +     spin_lock_irq(&chip->reg_lock);
>       /* continuous DMA memory type doesn't provide the physical address,
>        * so we need to resolve the address here...
>        */
> @@ -252,7 +251,7 @@
>  
>       snd_pmac_dma_stop(rec);
>       snd_pmac_dma_set_command(rec, &rec->cmd);
> -     spin_unlock_irqrestore(&chip->reg_lock, flags);
> +     spin_unlock_irq(&chip->reg_lock);
>  
>       return 0;
>  }
> @@ -264,7 +263,6 @@
>  static int snd_pmac_pcm_trigger(pmac_t *chip, pmac_stream_t *rec,
>                               snd_pcm_substream_t *subs, int cmd)
>  {
> -     unsigned long flags;
>       volatile struct dbdma_cmd *cp;
>       int i, command;
>  
> @@ -275,7 +273,7 @@
>                       return -EBUSY;
>               command = (subs->stream == SNDRV_PCM_STREAM_PLAYBACK ?
>                          OUTPUT_MORE : INPUT_MORE) + INTR_ALWAYS;
> -             spin_lock_irqsave(&chip->reg_lock, flags);
> +             spin_lock(&chip->reg_lock);
>               snd_pmac_beep_stop(chip);
>               snd_pmac_pcm_set_format(chip);
>               for (i = 0, cp = rec->cmd.cmds; i < rec->nperiods; i++, cp++)
> @@ -284,18 +282,18 @@
>               (void)in_le32(&rec->dma->status);
>               snd_pmac_dma_run(rec, RUN|WAKE);
>               rec->running = 1;
> -             spin_unlock_irqrestore(&chip->reg_lock, flags);
> +             spin_unlock(&chip->reg_lock);
>               break;
>  
>       case SNDRV_PCM_TRIGGER_STOP:
>       case SNDRV_PCM_TRIGGER_SUSPEND:
> -             spin_lock_irqsave(&chip->reg_lock, flags);
> +             spin_lock(&chip->reg_lock);
>               rec->running = 0;
>               /*printk("stopped!!\n");*/
>               snd_pmac_dma_stop(rec);
>               for (i = 0, cp = rec->cmd.cmds; i < rec->nperiods; i++, cp++)
>                       out_le16(&cp->command, DBDMA_STOP);
> -             spin_unlock_irqrestore(&chip->reg_lock, flags);
> +             spin_unlock(&chip->reg_lock);
>               break;
>  
>       default:
> @@ -490,14 +488,12 @@
>       snd_pcm_runtime_t *runtime = subs->runtime;
>       int i, j, fflags;
>       static int typical_freqs[] = {
> -             48000,
>               44100,
>               22050,
>               11025,
>               0,
>       };
>       static int typical_freq_flags[] = {
> -             SNDRV_PCM_RATE_48000,
>               SNDRV_PCM_RATE_44100,
>               SNDRV_PCM_RATE_22050,
>               SNDRV_PCM_RATE_11025,
> @@ -651,7 +647,7 @@
>  
>       pcm->private_data = chip;
>       pcm->private_free = pmac_pcm_free;
> -     pcm->info_flags = 0;
> +     pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
>       strcpy(pcm->name, chip->card->shortname);
>       chip->pcm = pcm;
>  
> @@ -683,12 +679,41 @@
>  
>  
>  /*
> + * handling beep
> + */
> +void snd_pmac_beep_dma_start(pmac_t *chip, int bytes, unsigned long addr, 
> int speed)
> +{
> +     pmac_stream_t *rec = &chip->playback;
> +
> +     snd_pmac_dma_stop(rec);
> +     st_le16(&chip->extra_dma.cmds->req_count, bytes);
> +     st_le16(&chip->extra_dma.cmds->xfer_status, 0);
> +     st_le32(&chip->extra_dma.cmds->cmd_dep, chip->extra_dma.addr);
> +     st_le32(&chip->extra_dma.cmds->phy_addr, addr);
> +     st_le16(&chip->extra_dma.cmds->command, OUTPUT_MORE + BR_ALWAYS);
> +     out_le32(&chip->awacs->control,
> +              (in_le32(&chip->awacs->control) & ~0x1f00)
> +              | (speed << 8));
> +     out_le32(&chip->awacs->byteswap, 0);
> +     snd_pmac_dma_set_command(rec, &chip->extra_dma);
> +     snd_pmac_dma_run(rec, RUN);
> +}
> +
> +void snd_pmac_beep_dma_stop(pmac_t *chip)
> +{
> +     snd_pmac_dma_stop(&chip->playback);
> +     st_le16(&chip->extra_dma.cmds->command, DBDMA_STOP);
> +     snd_pmac_pcm_set_format(chip); /* reset format */
> +}
> +
> +
> +/*
>   * interrupt handlers
>   */
>  static irqreturn_t
>  snd_pmac_tx_intr(int irq, void *devid, struct pt_regs *regs)
>  {
> -     pmac_t *chip = snd_magic_cast(pmac_t, devid, return IRQ_NONE);
> +     pmac_t *chip = devid;
>       snd_pmac_pcm_update(chip, &chip->playback);
>       return IRQ_HANDLED;
>  }
> @@ -697,7 +722,7 @@
>  static irqreturn_t
>  snd_pmac_rx_intr(int irq, void *devid, struct pt_regs *regs)
>  {
> -     pmac_t *chip = snd_magic_cast(pmac_t, devid, return IRQ_NONE);
> +     pmac_t *chip = devid;
>       snd_pmac_pcm_update(chip, &chip->capture);
>       return IRQ_HANDLED;
>  }
> @@ -706,7 +731,7 @@
>  static irqreturn_t
>  snd_pmac_ctrl_intr(int irq, void *devid, struct pt_regs *regs)
>  {
> -     pmac_t *chip = snd_magic_cast(pmac_t, devid, return IRQ_NONE);
> +     pmac_t *chip = devid;
>       int ctrl = in_le32(&chip->awacs->control);
>  
>       /*printk("pmac: control interrupt.. 0x%x\n", ctrl);*/
> @@ -776,6 +801,8 @@
>       if (chip->mixer_free)
>               chip->mixer_free(chip);
>  
> +     snd_pmac_detach_beep(chip);
> +
>       /* release resources */
>       if (chip->irq >= 0)
>               free_irq(chip->irq, (void*)chip);
> @@ -802,7 +829,7 @@
>                               release_OF_resource(chip->node, i);
>               }
>       }
> -     snd_magic_kfree(chip);
> +     kfree(chip);
>       return 0;
>  }
>  
> @@ -812,7 +839,7 @@
>   */
>  static int snd_pmac_dev_free(snd_device_t *device)
>  {
> -     pmac_t *chip = snd_magic_cast(pmac_t, device->device_data, return 
> -ENXIO);
> +     pmac_t *chip = device->device_data;
>       return snd_pmac_free(chip);
>  }
>  
> @@ -862,7 +889,7 @@
>       chip->can_byte_swap = 1;
>       chip->can_duplex = 1;
>       chip->can_capture = 1;
> -     chip->num_freqs = 8;
> +     chip->num_freqs = ARRAY_SIZE(awacs_freqs);
>       chip->freq_table = awacs_freqs;
>  
>       chip->control_mask = MASK_IEPC | MASK_IEE | 0x11; /* default */
> @@ -920,14 +947,14 @@
>               chip->can_capture = 0;  /* no capture */
>               chip->can_duplex = 0;
>               // chip->can_byte_swap = 0; /* FIXME: check this */
> -             chip->num_freqs = 2;
> +             chip->num_freqs = ARRAY_SIZE(tumbler_freqs);
>               chip->freq_table = tumbler_freqs;
>               chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */
>       }
>       if (device_is_compatible(sound, "snapper")) {
>               chip->model = PMAC_SNAPPER;
>               // chip->can_byte_swap = 0; /* FIXME: check this */
> -             chip->num_freqs = 2;
> +             chip->num_freqs = ARRAY_SIZE(tumbler_freqs);
>               chip->freq_table = tumbler_freqs;
>               chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */
>       }
> @@ -1069,7 +1096,7 @@
>       snd_runtime_check(chip_return, return -EINVAL);
>       *chip_return = NULL;
>  
> -     chip = snd_magic_kcalloc(pmac_t, 0, GFP_KERNEL);
> +     chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
>       if (chip == NULL)
>               return -ENOMEM;
>       chip->card = card;
> @@ -1206,7 +1233,7 @@
>  
>  static int snd_pmac_suspend(snd_card_t *card, unsigned int state)
>  {
> -     pmac_t *chip = snd_magic_cast(pmac_t, card->pm_private_data, return 
> -EINVAL);
> +     pmac_t *chip = card->pm_private_data;
>       unsigned long flags;
>  
>       if (chip->suspend)
> @@ -1228,7 +1255,7 @@
>  
>  static int snd_pmac_resume(snd_card_t *card, unsigned int state)
>  {
> -     pmac_t *chip = snd_magic_cast(pmac_t, card->pm_private_data, return 
> -EINVAL);
> +     pmac_t *chip = card->pm_private_data;
>  
>       snd_pmac_sound_feature(chip, 1);
>       if (chip->resume)
> --- linux-2.5-plain/sound/ppc/pmac.h  2004-08-26 21:03:12.000000000 +0200
> +++ linux-sound-plain/sound/ppc/pmac.h        2004-08-26 21:18:00.000000000 
> +0200
> @@ -84,7 +84,7 @@
>  
>       snd_pcm_substream_t *substream;
>  
> -     unsigned int cur_freqs;         /* currently available frequences */
> +     unsigned int cur_freqs;         /* currently available frequencies */
>       unsigned int cur_formats;       /* currently available formats */
>  };
>  
> @@ -155,6 +155,7 @@
>       void (*mixer_free)(pmac_t *);
>       snd_kcontrol_t *master_sw_ctl;
>       snd_kcontrol_t *speaker_sw_ctl;
> +     snd_kcontrol_t *drc_sw_ctl;     /* only used for tumbler -ReneR */
>       snd_kcontrol_t *hp_detect_ctl;
>  
>       /* lowlevel callbacks */
> @@ -173,6 +174,12 @@
>  int snd_pmac_new(snd_card_t *card, pmac_t **chip_return);
>  int snd_pmac_pcm_new(pmac_t *chip);
>  int snd_pmac_attach_beep(pmac_t *chip);
> +void snd_pmac_detach_beep(pmac_t *chip);
> +void snd_pmac_beep_stop(pmac_t *chip);
> +unsigned int snd_pmac_rate_index(pmac_t *chip, pmac_stream_t *rec, unsigned 
> int rate);
> +
> +void snd_pmac_beep_dma_start(pmac_t *chip, int bytes, unsigned long addr, 
> int speed);
> +void snd_pmac_beep_dma_stop(pmac_t *chip);
>  
>  /* initialize mixer */
>  int snd_pmac_awacs_init(pmac_t *chip);
> @@ -206,9 +213,4 @@
>       schedule_timeout(((msec) * HZ + 999) / 1000);\
>  } while (0)
>  
> -#ifndef PMAC_SUPPORT_PCM_BEEP
> -#define snd_pmac_attach_beep(chip) 0
> -#define snd_pmac_beep_stop(chip)  /**/
> -#endif
> -
>  #endif /* __PMAC_H */
> --- linux-2.5-plain/sound/ppc/powermac.c      2004-08-26 21:05:28.000000000 
> +0200
> +++ linux-sound-plain/sound/ppc/powermac.c    2004-08-26 21:20:52.000000000 
> +0200
> @@ -30,31 +30,19 @@
>  #define CHIP_NAME "PMac"
>  
>  MODULE_DESCRIPTION("PowerMac");
> -MODULE_CLASSES("{sound}");
> -MODULE_DEVICES("{{Apple,PowerMac}}");
> +MODULE_SUPPORTED_DEVICE("{{Apple,PowerMac}}");
>  MODULE_LICENSE("GPL");
>  
>  static int index = SNDRV_DEFAULT_IDX1;               /* Index 0-MAX */
>  static char *id = SNDRV_DEFAULT_STR1;                /* ID for this card */
> -/* static int enable = 1; */
> -#ifdef PMAC_SUPPORT_PCM_BEEP
>  static int enable_beep = 1;
> -#endif
>  
>  module_param(index, int, 0444);
>  MODULE_PARM_DESC(index, "Index value for " CHIP_NAME " soundchip.");
> -MODULE_PARM_SYNTAX(index, SNDRV_INDEX_DESC);
>  module_param(id, charp, 0444);
>  MODULE_PARM_DESC(id, "ID string for " CHIP_NAME " soundchip.");
> -MODULE_PARM_SYNTAX(id, SNDRV_ID_DESC);
> -/* module_param(enable, bool, 0444);
> -   MODULE_PARM_DESC(enable, "Enable this soundchip.");
> -   MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC); */
> -#ifdef PMAC_SUPPORT_PCM_BEEP
>  module_param(enable_beep, bool, 0444);
>  MODULE_PARM_DESC(enable_beep, "Enable beep using PCM.");
> -MODULE_PARM_SYNTAX(enable_beep, SNDRV_ENABLED "," SNDRV_BOOLEAN_TRUE_DESC);
> -#endif
>  
>  
>  /*
> @@ -133,10 +121,8 @@
>               goto __error;
>  
>       chip->initialized = 1;
> -#ifdef PMAC_SUPPORT_PCM_BEEP
>       if (enable_beep)
>               snd_pmac_attach_beep(chip);
> -#endif
>  
>       if ((err = snd_card_register(card)) < 0)
>               goto __error;
> @@ -151,18 +137,14 @@
>  
>  
>  /*
> - * MODULE sutff
> + * MODULE stuff
>   */
>  
>  static int __init alsa_card_pmac_init(void)
>  {
>       int err;
> -     if ((err = snd_pmac_probe()) < 0) {
> -#ifdef MODULE
> -             printk(KERN_ERR "no PMac soundchip found\n");
> -#endif
> +     if ((err = snd_pmac_probe()) < 0)
>               return err;
> -     }
>       return 0;
>  
>  }

Content-Description: hardware support updates for awacs, daca, tumbler, burgundy
> --- linux-2.5-plain/sound/ppc/awacs.c 2004-08-26 21:02:24.000000000 +0200
> +++ linux-sound-plain/sound/ppc/awacs.c       2004-08-26 21:16:57.000000000 
> +0200
> @@ -29,8 +29,6 @@
>  #include <sound/core.h>
>  #include "pmac.h"
>  
> -#define chip_t pmac_t
> -
>  
>  #ifdef CONFIG_ADB_CUDA
>  #define PMAC_AMP_AVAIL
> @@ -574,11 +572,22 @@
>       AWACS_VOLUME("Master Playback Volume", 2, 6, 1),
>       AWACS_SWITCH("Master Capture Switch", 1, SHIFT_LOOPTHRU, 0),
>       AWACS_VOLUME("Capture Volume", 0, 4, 0),
> -     AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_LINE, 0),
>       AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
> +};
> +
> +/* FIXME: is this correct order?
> + * screamer (powerbook G3 pismo) seems to have different bits...
> + */
> +static snd_kcontrol_new_t snd_pmac_awacs_mixers2[] __initdata = {
> +     AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_LINE, 0),
>       AWACS_SWITCH("Mic Capture Switch", 0, SHIFT_MUX_MIC, 0),
>  };
>  
> +static snd_kcontrol_new_t snd_pmac_screamer_mixers2[] __initdata = {
> +     AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_MIC, 0),
> +     AWACS_SWITCH("Mic Capture Switch", 0, SHIFT_MUX_LINE, 0),
> +};
> +
>  static snd_kcontrol_new_t snd_pmac_awacs_master_sw __initdata =
>  AWACS_SWITCH("Master Playback Switch", 1, SHIFT_HDMUTE, 1);
>  
> @@ -602,8 +611,6 @@
>  AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_SPKMUTE, 1);
>  
>  
> -#define num_controls(ary) (sizeof(ary) / sizeof(snd_kcontrol_new_t))
> -
>  /*
>   * add new mixer elements to the card
>   */
> @@ -818,9 +825,17 @@
>        */
>       strcpy(chip->card->mixername, "PowerMac AWACS");
>  
> -     if ((err = build_mixers(chip, num_controls(snd_pmac_awacs_mixers),
> +     if ((err = build_mixers(chip, ARRAY_SIZE(snd_pmac_awacs_mixers),
>                               snd_pmac_awacs_mixers)) < 0)
>               return err;
> +     if (chip->model == PMAC_SCREAMER)
> +             err = build_mixers(chip, ARRAY_SIZE(snd_pmac_screamer_mixers2),
> +                                snd_pmac_screamer_mixers2);
> +     else
> +             err = build_mixers(chip, ARRAY_SIZE(snd_pmac_awacs_mixers2),
> +                                snd_pmac_awacs_mixers2);
> +     if (err < 0)
> +             return err;
>       chip->master_sw_ctl = snd_ctl_new1(&snd_pmac_awacs_master_sw, chip);
>       if ((err = snd_ctl_add(chip->card, chip->master_sw_ctl)) < 0)
>               return err;
> @@ -832,7 +847,7 @@
>                * screamer registers.
>                * in this case, it seems the route C is not used.
>                */
> -             if ((err = build_mixers(chip, 
> num_controls(snd_pmac_awacs_amp_vol),
> +             if ((err = build_mixers(chip, 
> ARRAY_SIZE(snd_pmac_awacs_amp_vol),
>                                       snd_pmac_awacs_amp_vol)) < 0)
>                       return err;
>               /* overwrite */
> @@ -846,7 +861,7 @@
>  #endif /* PMAC_AMP_AVAIL */
>       {
>               /* route A = headphone, route C = speaker */
> -             if ((err = build_mixers(chip, 
> num_controls(snd_pmac_awacs_speaker_vol),
> +             if ((err = build_mixers(chip, 
> ARRAY_SIZE(snd_pmac_awacs_speaker_vol),
>                                       snd_pmac_awacs_speaker_vol)) < 0)
>                       return err;
>               chip->speaker_sw_ctl = snd_ctl_new1(&snd_pmac_awacs_speaker_sw, 
> chip);
> @@ -855,11 +870,11 @@
>       }
>  
>       if (chip->model == PMAC_SCREAMER) {
> -             if ((err = build_mixers(chip, 
> num_controls(snd_pmac_screamer_mic_boost),
> +             if ((err = build_mixers(chip, 
> ARRAY_SIZE(snd_pmac_screamer_mic_boost),
>                                       snd_pmac_screamer_mic_boost)) < 0)
>                       return err;
>       } else {
> -             if ((err = build_mixers(chip, 
> num_controls(snd_pmac_awacs_mic_boost),
> +             if ((err = build_mixers(chip, 
> ARRAY_SIZE(snd_pmac_awacs_mic_boost),
>                                       snd_pmac_awacs_mic_boost)) < 0)
>                       return err;
>       }
> --- linux-2.5-plain/sound/ppc/burgundy.c      2004-08-26 21:01:31.000000000 
> +0200
> +++ linux-sound-plain/sound/ppc/burgundy.c    2004-08-26 21:15:31.000000000 
> +0200
> @@ -28,8 +28,6 @@
>  #include "pmac.h"
>  #include "burgundy.h"
>  
> -#define chip_t pmac_t
> -
>  
>  /* Waits for busy flag to clear */
>  inline static void
> @@ -324,8 +322,6 @@
>  static snd_kcontrol_new_t snd_pmac_burgundy_speaker_sw __initdata = 
>  BURGUNDY_OUTPUT_SWITCH("PC Speaker Playback Switch", 0, 
> BURGUNDY_OUTPUT_INTERN, 0, 0);
>  
> -#define num_controls(ary) (sizeof(ary) / sizeof(snd_kcontrol_new_t))
> -
>  
>  #ifdef PMAC_SUPPORT_AUTOMUTE
>  /*
> @@ -420,7 +416,7 @@
>        */
>       strcpy(chip->card->mixername, "PowerMac Burgundy");
>  
> -     for (i = 0; i < num_controls(snd_pmac_burgundy_mixers); i++) {
> +     for (i = 0; i < ARRAY_SIZE(snd_pmac_burgundy_mixers); i++) {
>               if ((err = snd_ctl_add(chip->card, 
> snd_ctl_new1(&snd_pmac_burgundy_mixers[i], chip))) < 0)
>                       return err;
>       }
> --- linux-2.5-plain/sound/ppc/daca.c  2004-08-26 21:01:02.000000000 +0200
> +++ linux-sound-plain/sound/ppc/daca.c        2004-08-26 21:14:44.000000000 
> +0200
> @@ -28,8 +28,6 @@
>  #include <sound/core.h>
>  #include "pmac.h"
>  
> -#define chip_t pmac_t
> -
>  /* i2c address */
>  #define DACA_I2C_ADDR        0x4d
>  
> @@ -217,8 +215,6 @@
>       },
>  };
>  
> -#define num_controls(ary) (sizeof(ary) / sizeof(snd_kcontrol_new_t))
> -
>  
>  #ifdef CONFIG_PMAC_PBOOK
>  static void daca_resume(pmac_t *chip)
> @@ -272,7 +268,7 @@
>        */
>       strcpy(chip->card->mixername, "PowerMac DACA");
>  
> -     for (i = 0; i < num_controls(daca_mixers); i++) {
> +     for (i = 0; i < ARRAY_SIZE(daca_mixers); i++) {
>               if ((err = snd_ctl_add(chip->card, 
> snd_ctl_new1(&daca_mixers[i], chip))) < 0)
>                       return err;
>       }
> --- linux-2.5-plain/sound/ppc/tumbler.c       2004-08-26 21:00:41.000000000 
> +0200
> +++ linux-sound-plain/sound/ppc/tumbler.c     2004-08-26 21:14:00.000000000 
> +0200
> @@ -16,6 +16,11 @@
>   *   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
> + *
> + *   Rene Rebe <[EMAIL PROTECTED]>:
> + *     * update from shadow registers on wakeup and headphone plug
> + *     * automatically toggle DRC on headphone plug
> + *   
>   */
>  
>  
> @@ -36,8 +41,6 @@
>  #include "pmac.h"
>  #include "tumbler_volume.h"
>  
> -#define chip_t pmac_t
> -
>  /* i2c address for tumbler */
>  #define TAS_I2C_ADDR 0x34
>  
> @@ -759,12 +762,6 @@
>       DEFINE_MONO("Tone Control - Treble", treble),
>       DEFINE_MONO("PCM Playback Volume", pcm),
>       { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
> -       .name = "DRC Switch",
> -       .info = snd_pmac_boolean_mono_info,
> -       .get = tumbler_get_drc_switch,
> -       .put = tumbler_put_drc_switch
> -     },
> -     { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
>         .name = "DRC Range",
>         .info = tumbler_info_drc_value,
>         .get = tumbler_get_drc_value,
> @@ -791,12 +788,6 @@
>       DEFINE_SNAPPER_MONO("Tone Control - Bass", bass),
>       DEFINE_SNAPPER_MONO("Tone Control - Treble", treble),
>       { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
> -       .name = "DRC Switch",
> -       .info = snd_pmac_boolean_mono_info,
> -       .get = tumbler_get_drc_switch,
> -       .put = tumbler_put_drc_switch
> -     },
> -     { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
>         .name = "DRC Range",
>         .info = tumbler_info_drc_value,
>         .get = tumbler_get_drc_value,
> @@ -826,6 +817,14 @@
>       .put = tumbler_put_mute_switch,
>       .private_value = TUMBLER_MUTE_AMP,
>  };
> +static snd_kcontrol_new_t tumbler_drc_sw __initdata = {
> +     .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
> +     .name = "DRC Switch",
> +     .info = snd_pmac_boolean_mono_info,
> +     .get = tumbler_get_drc_switch,
> +     .put = tumbler_put_drc_switch
> +};
> +
>  
>  #ifdef PMAC_SUPPORT_AUTOMUTE
>  /*
> @@ -847,6 +846,29 @@
>       }
>  }
>  
> +static struct work_struct device_change;
> +
> +static void
> +device_change_handler(void *self)
> +{
> +     pmac_t *chip = (pmac_t*) self;
> +     pmac_tumbler_t *mix;
> +
> +     if (!chip)
> +             return;
> +
> +     mix = chip->mixer_data;
> +
> +     /* first set the DRC so the speaker do not explode -ReneR */
> +     if (chip->model == PMAC_TUMBLER)
> +             tumbler_set_drc(mix);
> +     else
> +             snapper_set_drc(mix);
> +
> +     /* reset the master volume so the correct amplification is applied */
> +     tumbler_set_master_volume(mix);
> +}
> +
>  static void tumbler_update_automute(pmac_t *chip, int do_notify)
>  {
>       if (chip->auto_mute) {
> @@ -856,14 +878,25 @@
>                       /* mute speaker */
>                       check_mute(chip, &mix->amp_mute, 1, do_notify, 
> chip->speaker_sw_ctl);
>                       check_mute(chip, &mix->hp_mute, 0, do_notify, 
> chip->master_sw_ctl);
> +                     mix->drc_enable = 0;
> +
>               } else {
>                       /* unmute speaker */
>                       check_mute(chip, &mix->amp_mute, 0, do_notify, 
> chip->speaker_sw_ctl);
>                       check_mute(chip, &mix->hp_mute, 1, do_notify, 
> chip->master_sw_ctl);
> +                     mix->drc_enable = 1;
>               }
> -             if (do_notify)
> +             if (do_notify) {
>                       snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
>                                      &chip->hp_detect_ctl->id);
> +                     snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
> +                                    &chip->drc_sw_ctl->id);
> +             }
> +
> +             /* finally we need to schedule an update of the mixer values
> +                (master and DRC are enough for now) -ReneR */
> +             schedule_work(&device_change);
> +
>       }
>  }
>  #endif /* PMAC_SUPPORT_AUTOMUTE */
> @@ -872,7 +905,7 @@
>  /* interrupt - headphone plug changed */
>  static irqreturn_t headphone_intr(int irq, void *devid, struct pt_regs *regs)
>  {
> -     pmac_t *chip = snd_magic_cast(pmac_t, devid, return IRQ_NONE);
> +     pmac_t *chip = devid;
>       if (chip->update_automute && chip->initialized) {
>               chip->update_automute(chip, 1);
>               return IRQ_HANDLED;
> @@ -1114,11 +1147,17 @@
>       chip->speaker_sw_ctl = snd_ctl_new1(&tumbler_speaker_sw, chip);
>       if ((err = snd_ctl_add(chip->card, chip->speaker_sw_ctl)) < 0)
>               return err;
> +     chip->drc_sw_ctl = snd_ctl_new1(&tumbler_drc_sw, chip);
> +     if ((err = snd_ctl_add(chip->card, chip->drc_sw_ctl)) < 0)
> +             return err;
> +
>  
>  #ifdef CONFIG_PMAC_PBOOK
>       chip->resume = tumbler_resume;
>  #endif
>  
> +     INIT_WORK(&device_change, device_change_handler, (void *)chip);
> +
>  #ifdef PMAC_SUPPORT_AUTOMUTE
>       if (mix->headphone_irq >=0 && (err = snd_pmac_add_automute(chip)) < 0)
>               return err;

Reply via email to