diff options
author | Matthew Wilcox <willy@debian.org> | 2004-08-21 22:30:17 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-08-21 22:30:17 -0700 |
commit | 5ce15909cd8872b6e9e9d2f59710ef7646b196f0 (patch) | |
tree | af77626eae6fc49e270a2c8ef66d7e541c56e354 /sound | |
parent | b5ac4f2c850f82a1d271201a5a428be451630d8f (diff) | |
download | history-5ce15909cd8872b6e9e9d2f59710ef7646b196f0.tar.gz |
[PATCH] PA-RISC sound updates
PA-RISC sound updates:
- Do a DAC/ADC reset for sampling rate changes in ad1889 (Randolph Chung)
- Set the ad1889 interrupt configuration properly (Randolph Chung)
- Fix dependency for the OSS Harmony driver (Thibaut Varene)
- Forward port Stuart Brady's 2.4 Harmony driver patches (Thibaut Varene)
- Fix sample skipping (Stuart Brady)
- Prevent harmony_silence being called wrongly (Stuart Brady)
- Fix crash caused by buf_to_fill becoming -1 (Stuart Brady)
- Improve naming of mixer channels (Stuart Brady)
- Implement SNDCTL_DSP_CHANNELS ioctl (Stuart Brady)
- Improve toggling the recording source (Stuart Brady)
- Sanity check MIXER_WRITE volume levels (Stuart Brady)
- Fix MIXER_READ right_level return (Stuart Brady)
- Reject AFMT_S16_LE format (Stuart Brady)
- Fail OSS Harmony initialisation if no irq (Helge Deller)
- Fix typos in ALSA Harmony (Andy Walker, Grant Grundler, Stuart Brady)
Diffstat (limited to 'sound')
-rw-r--r-- | sound/oss/Kconfig | 5 | ||||
-rw-r--r-- | sound/oss/ad1889.c | 79 | ||||
-rw-r--r-- | sound/oss/ad1889.h | 6 | ||||
-rw-r--r-- | sound/oss/harmony.c | 134 | ||||
-rw-r--r-- | sound/parisc/harmony.c | 8 |
5 files changed, 143 insertions, 89 deletions
diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig index 05f6bc8ecee8dd..5859ca26ee4cda 100644 --- a/sound/oss/Kconfig +++ b/sound/oss/Kconfig @@ -162,7 +162,10 @@ config SOUND_ICH config SOUND_HARMONY tristate "PA Harmony audio driver" - depends on GSC_LASI && SOUND + depends on GSC_LASI && SOUND_PRIME!=n + help + Say 'Y' or 'M' to include support for Harmony soundchip + on HP 712, 715/new and many other GSC based machines. config SOUND_SONICVIBES tristate "S3 SonicVibes" diff --git a/sound/oss/ad1889.c b/sound/oss/ad1889.c index 2423b1f2d59044..25477365397d6f 100644 --- a/sound/oss/ad1889.c +++ b/sound/oss/ad1889.c @@ -1,5 +1,5 @@ /* - * Copyright 2001 Randolph Chung <tausq@debian.org> + * Copyright 2001-2004 Randolph Chung <tausq@debian.org> * * Analog Devices 1889 PCI audio driver (AD1819 AC97-compatible codec) * @@ -61,6 +61,7 @@ #define AD1889_WRITEL(dev,reg,val) writel((val), dev->regbase + reg) //now 100ms +/* #define WAIT_10MS() schedule_timeout(HZ/10) */ #define WAIT_10MS() do { int __i; for (__i = 0; __i < 100; __i++) udelay(1000); } while(0) /* currently only support a single device */ @@ -69,25 +70,43 @@ static ad1889_dev_t *ad1889_dev = NULL; /************************* helper routines ***************************** */ static inline void ad1889_set_wav_rate(ad1889_dev_t *dev, int rate) { + struct ac97_codec *ac97_codec = dev->ac97_codec; + + DBG("Setting WAV rate to %d\n", rate); dev->state[AD_WAV_STATE].dmabuf.rate = rate; AD1889_WRITEW(dev, AD_DSWAS, rate); + + /* Cycle the DAC to enable the new rate */ + ac97_codec->codec_write(dev->ac97_codec, AC97_POWER_CONTROL, 0x0200); + WAIT_10MS(); + ac97_codec->codec_write(dev->ac97_codec, AC97_POWER_CONTROL, 0); } static inline void ad1889_set_adc_rate(ad1889_dev_t *dev, int rate) { + struct ac97_codec *ac97_codec = dev->ac97_codec; + + DBG("Setting ADC rate to %d\n", rate); dev->state[AD_ADC_STATE].dmabuf.rate = rate; AD1889_WRITEW(dev, AD_DSRES, rate); + + /* Cycle the ADC to enable the new rate */ + ac97_codec->codec_write(dev->ac97_codec, AC97_POWER_CONTROL, 0x0100); + WAIT_10MS(); + ac97_codec->codec_write(dev->ac97_codec, AC97_POWER_CONTROL, 0); } static inline void ad1889_set_wav_fmt(ad1889_dev_t *dev, int fmt) { u16 tmp; + DBG("Setting WAV format to 0x%x\n", fmt); + tmp = AD1889_READW(ad1889_dev, AD_DSWSMC); - if (fmt == AFMT_S16_LE) { + if (fmt & AFMT_S16_LE) { //tmp |= 0x0100; /* set WA16 */ tmp |= 0x0300; /* set WA16 stereo */ - } else if (fmt == AFMT_U8) { + } else if (fmt & AFMT_U8) { tmp &= ~0x0100; /* clear WA16 */ } AD1889_WRITEW(ad1889_dev, AD_DSWSMC, tmp); @@ -97,10 +116,12 @@ static inline void ad1889_set_adc_fmt(ad1889_dev_t *dev, int fmt) { u16 tmp; + DBG("Setting ADC format to 0x%x\n", fmt); + tmp = AD1889_READW(ad1889_dev, AD_DSRAMC); - if (fmt == AFMT_S16_LE) { + if (fmt & AFMT_S16_LE) { tmp |= 0x0100; /* set WA16 */ - } else if (fmt == AFMT_U8) { + } else if (fmt & AFMT_U8) { tmp &= ~0x0100; /* clear WA16 */ } AD1889_WRITEW(ad1889_dev, AD_DSRAMC, tmp); @@ -133,6 +154,9 @@ static void ad1889_start_wav(ad1889_state_t *state) dmabuf->dma_len = cnt; dmabuf->ready = 1; + DBG("Starting playback at 0x%p for %ld bytes\n", dmabuf->rawbuf + + dmabuf->rd_ptr, dmabuf->dma_len); + /* load up the current register set */ AD1889_WRITEL(ad1889_dev, AD_DMAWAVCC, cnt); AD1889_WRITEL(ad1889_dev, AD_DMAWAVICC, cnt); @@ -243,7 +267,7 @@ static ad1889_dev_t *ad1889_alloc_dev(struct pci_dev *pci) dmabuf->dma_handle = 0; dmabuf->rd_ptr = dmabuf->wr_ptr = dmabuf->dma_len = 0UL; dmabuf->ready = 0; - dmabuf->rate = 44100; + dmabuf->rate = 48000; } return dev; @@ -472,7 +496,6 @@ static ssize_t ad1889_write(struct file *file, const char __user *buffer, size_t long cnt = count; unsigned long flags; - for (;;) { long used_bytes; long timeout; /* max time for DMA in jiffies */ @@ -498,17 +521,11 @@ static ssize_t ad1889_write(struct file *file, const char __user *buffer, size_t } set_current_state(TASK_INTERRUPTIBLE); - if (!schedule_timeout(timeout + 1)) - printk(KERN_WARNING "AD1889 timeout(%ld) r/w %lx/%lx len %lx\n", - timeout+1, - dmabuf->rd_ptr, dmabuf->wr_ptr, - dmabuf->dma_len); - + schedule_timeout(timeout + 1); if (signal_pending(current)) { ret = -ERESTARTSYS; goto err2; } - } /* watch out for wrapping around static buffer */ @@ -616,6 +633,8 @@ static int ad1889_ioctl(struct inode *inode, struct file *file, unsigned int cmd audio_buf_info abinfo; int __user *p = (int __user *)arg; + DBG("ad1889_ioctl cmd 0x%x arg %lu\n", cmd, arg); + switch (cmd) { case OSS_GETVERSION: @@ -674,11 +693,15 @@ static int ad1889_ioctl(struct inode *inode, struct file *file, unsigned int cmd if (get_user(val, p)) return -EFAULT; - if (file->f_mode & FMODE_READ) - ad1889_set_adc_fmt(dev, val); + if (val == 0) { + if (file->f_mode & FMODE_READ) + ad1889_set_adc_fmt(dev, val); - if (file->f_mode & FMODE_WRITE) - ad1889_set_wav_fmt(dev, val); + if (file->f_mode & FMODE_WRITE) + ad1889_set_wav_fmt(dev, val); + } else { + val = AFMT_S16_LE | AFMT_U8; + } return put_user(val, p); @@ -758,7 +781,7 @@ static int ad1889_open(struct inode *inode, struct file *file) file->private_data = ad1889_dev; - ad1889_set_wav_rate(ad1889_dev, 44100); + ad1889_set_wav_rate(ad1889_dev, 48000); ad1889_set_wav_fmt(ad1889_dev, AFMT_S16_LE); AD1889_WRITEW(ad1889_dev, AD_DSWADA, 0x0404); /* attenuation */ return nonseekable_open(inode, file); @@ -938,7 +961,6 @@ static irqreturn_t ad1889_interrupt(int irq, void *dev_id, struct pt_regs *regs) ad1889_stop_wav(&dev->state[AD_WAV_STATE]); /* clean up */ ad1889_start_wav(&dev->state[AD_WAV_STATE]); /* start new */ } - } if ((stat & 0x2) && dev->state[AD_ADC_STATE].dmabuf.ready) { /* ADCI */ @@ -952,18 +974,19 @@ static irqreturn_t ad1889_interrupt(int irq, void *dev_id, struct pt_regs *regs) static void ad1889_initcfg(ad1889_dev_t *dev) { - u16 tmp; + u16 tmp16; + u32 tmp32; /* make sure the interrupt bits are setup the way we want */ - tmp = AD1889_READW(dev, AD_DMAWAVCTRL); - tmp &= ~0x00ff; /* flat dma, no sg, mask out the intr bits */ - tmp |= 0x0004; /* intr on count, loop */ - AD1889_WRITEW(dev, AD_DMAWAVCTRL, tmp); + tmp32 = AD1889_READL(dev, AD_DMAWAVCTRL); + tmp32 &= ~0xff; /* flat dma, no sg, mask out the intr bits */ + tmp32 |= 0x6; /* intr on count, loop */ + AD1889_WRITEL(dev, AD_DMAWAVCTRL, tmp32); /* unmute... */ - tmp = AD1889_READW(dev, AD_DSWADA); - tmp &= ~0x8080; - AD1889_WRITEW(dev, AD_DSWADA, tmp); + tmp16 = AD1889_READW(dev, AD_DSWADA); + tmp16 &= ~0x8080; + AD1889_WRITEW(dev, AD_DSWADA, tmp16); } static int __devinit ad1889_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) diff --git a/sound/oss/ad1889.h b/sound/oss/ad1889.h index 5d13ef11d331e9..964a6b4d5716aa 100644 --- a/sound/oss/ad1889.h +++ b/sound/oss/ad1889.h @@ -34,9 +34,9 @@ #define AD_DMAWAVICC 0x98 /* WAV interrupt current count */ #define AD_DMAWAVIBC 0x9c /* WAV interrupt base count */ #define AD_DMARESCTRL 0xa0 /* RES PCI control/status */ -#define AD_DMAADCCTRL 0xa8 /* RES PCI control/status */ -#define AD_DMASYNCTRL 0xb0 /* RES PCI control/status */ -#define AD_DMAWAVCTRL 0xb8 /* RES PCI control/status */ +#define AD_DMAADCCTRL 0xa8 /* ADC PCI control/status */ +#define AD_DMASYNCTRL 0xb0 /* SYN PCI control/status */ +#define AD_DMAWAVCTRL 0xb8 /* WAV PCI control/status */ #define AD_DMADISR 0xc0 /* PCI DMA intr status */ #define AD_DMACHSS 0xc4 /* PCI DMA channel stop status */ diff --git a/sound/oss/harmony.c b/sound/oss/harmony.c index 22f0eff1380915..d253dfea014fc3 100644 --- a/sound/oss/harmony.c +++ b/sound/oss/harmony.c @@ -12,6 +12,7 @@ Copyright 2000-2003 (c) Helge Deller <deller@gmx.de> Copyright 2001 (c) Matthieu Delahaye <delahaym@esiee.fr> Copyright 2001 (c) Jean-Christophe Vaugeois <vaugeoij@esiee.fr> + Copyright 2004 (c) Stuart Brady <sdbrady@ntlworld.com> TODO: @@ -124,9 +125,17 @@ TODO: #define GAIN_RO_MASK ( 0x3f << GAIN_RO_SHIFT) -#define MAX_OUTPUT_LEVEL (GAIN_RO_MASK >> GAIN_RO_SHIFT) -#define MAX_INPUT_LEVEL (GAIN_RI_MASK >> GAIN_RI_SHIFT) -#define MAX_VOLUME_LEVEL (GAIN_MA_MASK >> GAIN_MA_SHIFT) +#define MAX_OUTPUT_LEVEL (GAIN_RO_MASK >> GAIN_RO_SHIFT) +#define MAX_INPUT_LEVEL (GAIN_RI_MASK >> GAIN_RI_SHIFT) +#define MAX_MONITOR_LEVEL (GAIN_MA_MASK >> GAIN_MA_SHIFT) + +#define MIXER_INTERNAL SOUND_MIXER_LINE1 +#define MIXER_LINEOUT SOUND_MIXER_LINE2 +#define MIXER_HEADPHONES SOUND_MIXER_LINE3 + +#define MASK_INTERNAL SOUND_MASK_LINE1 +#define MASK_LINEOUT SOUND_MASK_LINE2 +#define MASK_HEADPHONES SOUND_MASK_LINE3 /* * Channels Mask in mixer register @@ -543,6 +552,7 @@ static ssize_t harmony_audio_write(struct file *file, int count = 0; int frame_size; int buf_to_fill; + int fresh_buffer; if (!harmony.format_initialized) { if (harmony_format_auto_detect(buffer, total_count)) @@ -564,12 +574,16 @@ static ssize_t harmony_audio_write(struct file *file, buf_to_fill = (harmony.first_filled_play+harmony.nb_filled_play); - if (harmony.play_offset) + if (harmony.play_offset) { buf_to_fill--; + buf_to_fill += MAX_BUFS; + } buf_to_fill %= MAX_BUFS; - + + fresh_buffer = (harmony.play_offset == 0); + /* Figure out the size of the frame */ - if ((total_count-count) > HARMONY_BUF_SIZE - harmony.play_offset) { + if ((total_count-count) >= HARMONY_BUF_SIZE - harmony.play_offset) { frame_size = HARMONY_BUF_SIZE - harmony.play_offset; } else { frame_size = total_count - count; @@ -587,7 +601,7 @@ static ssize_t harmony_audio_write(struct file *file, CHECK_WBACK_INV_OFFSET(played_buf, (HARMONY_BUF_SIZE*buf_to_fill + harmony.play_offset), frame_size); - if (!harmony.play_offset) + if (fresh_buffer) harmony.nb_filled_play++; count += frame_size; @@ -650,18 +664,17 @@ static int harmony_audio_ioctl(struct inode *inode, switch (ival) { case AFMT_MU_LAW: new_format = HARMONY_DF_8BIT_ULAW; break; case AFMT_A_LAW: new_format = HARMONY_DF_8BIT_ALAW; break; - case AFMT_S16_LE: /* fall through, but not really supported */ - case AFMT_S16_BE: new_format = HARMONY_DF_16BIT_LINEAR; - ival = AFMT_S16_BE; - break; + case AFMT_S16_BE: new_format = HARMONY_DF_16BIT_LINEAR; break; default: { DPRINTK(KERN_WARNING PFX "unsupported sound format 0x%04x requested.\n", ival); - return -EINVAL; + ival = AFMT_S16_BE; + return put_user(ival, (int *) arg); } } harmony_set_format(new_format); + return 0; } else { switch (harmony.data_format) { case HARMONY_DF_8BIT_ULAW: ival = AFMT_MU_LAW; break; @@ -669,8 +682,8 @@ static int harmony_audio_ioctl(struct inode *inode, case HARMONY_DF_16BIT_LINEAR: ival = AFMT_U16_BE; break; default: ival = 0; } + return put_user(ival, (int *) arg); } - return put_user(ival, (int *) arg); case SOUND_PCM_READ_RATE: ival = harmony.dac_rate; @@ -689,7 +702,17 @@ static int harmony_audio_ioctl(struct inode *inode, if (ival != 0 && ival != 1) return -EINVAL; harmony_set_stereo(ival); - return put_user(ival, (int *) arg); + return 0; + + case SNDCTL_DSP_CHANNELS: + if (get_user(ival, (int *) arg)) + return -EFAULT; + if (ival != 1 && ival != 2) { + ival = harmony.stereo_select == HARMONY_SS_MONO ? 1 : 2; + return put_user(ival, (int *) arg); + } + harmony_set_stereo(ival-1); + return 0; case SNDCTL_DSP_GETBLKSIZE: ival = HARMONY_BUF_SIZE; @@ -887,7 +910,7 @@ static int harmony_mixer_get_level(int channel) int right_level; switch (channel) { - case SOUND_MIXER_OGAIN: + case SOUND_MIXER_VOLUME: left_level = (harmony.current_gain & GAIN_LO_MASK) >> GAIN_LO_SHIFT; right_level = (harmony.current_gain & GAIN_RO_MASK) >> GAIN_RO_SHIFT; left_level = to_oss_level(MAX_OUTPUT_LEVEL - left_level, MAX_OUTPUT_LEVEL); @@ -901,10 +924,10 @@ static int harmony_mixer_get_level(int channel) right_level= to_oss_level(right_level, MAX_INPUT_LEVEL); return (right_level << 8)+left_level; - case SOUND_MIXER_VOLUME: + case SOUND_MIXER_MONITOR: left_level = (harmony.current_gain & GAIN_MA_MASK) >> GAIN_MA_SHIFT; - left_level = to_oss_level(MAX_VOLUME_LEVEL-left_level, MAX_VOLUME_LEVEL); - return left_level; + left_level = to_oss_level(MAX_MONITOR_LEVEL-left_level, MAX_MONITOR_LEVEL); + return (left_level << 8)+left_level; } return -EINVAL; } @@ -926,9 +949,11 @@ static int harmony_mixer_set_level(int channel, int value) right_level = (value & 0x0000ff00) >> 8; left_level = value & 0x000000ff; + if (right_level > 100) right_level = 100; + if (left_level > 100) left_level = 100; switch (channel) { - case SOUND_MIXER_OGAIN: + case SOUND_MIXER_VOLUME: right_level = to_harmony_level(100-right_level, MAX_OUTPUT_LEVEL); left_level = to_harmony_level(100-left_level, MAX_OUTPUT_LEVEL); new_right_level = to_oss_level(MAX_OUTPUT_LEVEL - right_level, MAX_OUTPUT_LEVEL); @@ -948,12 +973,12 @@ static int harmony_mixer_set_level(int channel, int value) harmony_mixer_set_gain(); return (new_right_level << 8) + new_left_level; - case SOUND_MIXER_VOLUME: - left_level = to_harmony_level(100-left_level, MAX_VOLUME_LEVEL); - new_left_level = to_oss_level(MAX_VOLUME_LEVEL-left_level, MAX_VOLUME_LEVEL); - harmony.current_gain = (harmony.current_gain & ~GAIN_MA_MASK)| (left_level << GAIN_MA_SHIFT); + case SOUND_MIXER_MONITOR: + left_level = to_harmony_level(100-left_level, MAX_MONITOR_LEVEL); + new_left_level = to_oss_level(MAX_MONITOR_LEVEL-left_level, MAX_MONITOR_LEVEL); + harmony.current_gain = (harmony.current_gain & ~GAIN_MA_MASK) | (left_level << GAIN_MA_SHIFT); harmony_mixer_set_gain(); - return new_left_level; + return (new_left_level << 8) + new_left_level; } return -EINVAL; @@ -986,11 +1011,15 @@ static int harmony_mixer_set_recmask(int recmask) { int new_input_line; int new_input_mask; - - if ((recmask & SOUND_MASK_LINE)) { + int current_input_line; + + current_input_line = (harmony.current_gain & GAIN_IS_MASK) + >> GAIN_IS_SHIFT; + if ((current_input_line && ((recmask & SOUND_MASK_LINE) || !(recmask & SOUND_MASK_MIC))) || + (!current_input_line && ((recmask & SOUND_MASK_LINE) && !(recmask & SOUND_MASK_MIC)))) { new_input_line = 0; new_input_mask = SOUND_MASK_LINE; - } else { + } else { new_input_line = 1; new_input_mask = SOUND_MASK_MIC; } @@ -1009,9 +1038,9 @@ static int harmony_mixer_get_outmask(void) { int outmask = 0; - if (harmony.current_gain & GAIN_HE_MASK) outmask |=SOUND_MASK_PHONEOUT; - if (harmony.current_gain & GAIN_LE_MASK) outmask |=SOUND_MASK_LINE; - if (harmony.current_gain & GAIN_SE_MASK) outmask |=SOUND_MASK_SPEAKER; + if (harmony.current_gain & GAIN_SE_MASK) outmask |= MASK_INTERNAL; + if (harmony.current_gain & GAIN_LE_MASK) outmask |= MASK_LINEOUT; + if (harmony.current_gain & GAIN_HE_MASK) outmask |= MASK_HEADPHONES; return outmask; } @@ -1019,24 +1048,24 @@ static int harmony_mixer_get_outmask(void) static int harmony_mixer_set_outmask(int outmask) { - if (outmask & SOUND_MASK_PHONEOUT) - harmony.current_gain |= GAIN_HE_MASK; + if (outmask & MASK_INTERNAL) + harmony.current_gain |= GAIN_SE_MASK; else - harmony.current_gain &= ~GAIN_HE_MASK; + harmony.current_gain &= ~GAIN_SE_MASK; - if (outmask & SOUND_MASK_LINE) + if (outmask & MASK_LINEOUT) harmony.current_gain |= GAIN_LE_MASK; else harmony.current_gain &= ~GAIN_LE_MASK; - if (outmask & SOUND_MASK_SPEAKER) - harmony.current_gain |= GAIN_SE_MASK; + if (outmask & MASK_HEADPHONES) + harmony.current_gain |= GAIN_HE_MASK; else - harmony.current_gain &= ~GAIN_SE_MASK; + harmony.current_gain &= ~GAIN_HE_MASK; harmony_mixer_set_gain(); - return (outmask & (SOUND_MASK_PHONEOUT | SOUND_MASK_LINE | SOUND_MASK_SPEAKER)); + return (outmask & (MASK_INTERNAL | MASK_LINEOUT | MASK_HEADPHONES)); } /* @@ -1074,19 +1103,19 @@ static int harmony_mixer_ioctl(struct inode * inode, struct file * file, ret = SOUND_CAP_EXCL_INPUT; break; case MIXER_READ(SOUND_MIXER_STEREODEVS): - ret = SOUND_MASK_IGAIN | SOUND_MASK_OGAIN; + ret = SOUND_MASK_VOLUME | SOUND_MASK_IGAIN; break; case MIXER_READ(SOUND_MIXER_RECMASK): ret = SOUND_MASK_MIC | SOUND_MASK_LINE; break; case MIXER_READ(SOUND_MIXER_DEVMASK): - ret = SOUND_MASK_OGAIN | SOUND_MASK_IGAIN | - SOUND_MASK_VOLUME; + ret = SOUND_MASK_VOLUME | SOUND_MASK_IGAIN | + SOUND_MASK_MONITOR; break; case MIXER_READ(SOUND_MIXER_OUTMASK): - ret = SOUND_MASK_SPEAKER | SOUND_MASK_LINE | - SOUND_MASK_PHONEOUT; + ret = MASK_INTERNAL | MASK_LINEOUT | + MASK_HEADPHONES; break; case MIXER_WRITE(SOUND_MIXER_RECSRC): @@ -1103,15 +1132,15 @@ static int harmony_mixer_ioctl(struct inode * inode, struct file * file, ret = harmony_mixer_get_outmask(); break; - case MIXER_WRITE(SOUND_MIXER_OGAIN): - case MIXER_WRITE(SOUND_MIXER_IGAIN): case MIXER_WRITE(SOUND_MIXER_VOLUME): + case MIXER_WRITE(SOUND_MIXER_IGAIN): + case MIXER_WRITE(SOUND_MIXER_MONITOR): ret = harmony_mixer_set_level(cmd & 0xff, val); break; - case MIXER_READ(SOUND_MIXER_OGAIN): - case MIXER_READ(SOUND_MIXER_IGAIN): case MIXER_READ(SOUND_MIXER_VOLUME): + case MIXER_READ(SOUND_MIXER_IGAIN): + case MIXER_READ(SOUND_MIXER_MONITOR): ret = harmony_mixer_get_level(cmd & 0xff); break; @@ -1201,16 +1230,15 @@ harmony_driver_probe(struct parisc_device *dev) return -EBUSY; } - harmony.dev = dev; - - /* Set the HPA of harmony */ - harmony.hpa = (struct harmony_hpa *)dev->hpa; - - if (!harmony.dev->irq) { + if (!dev->irq) { printk(KERN_ERR PFX "no irq found\n"); return -ENODEV; } + /* Set the HPA of harmony */ + harmony.hpa = (struct harmony_hpa *)dev->hpa; + harmony.dev = dev; + /* Grab the ID and revision from the device */ id = gsc_readb(&harmony.hpa->id); if ((id | 1) != 0x15) { diff --git a/sound/parisc/harmony.c b/sound/parisc/harmony.c index 423ab05c0480f0..53ecf3efeb8c02 100644 --- a/sound/parisc/harmony.c +++ b/sound/parisc/harmony.c @@ -6,7 +6,7 @@ * * Harmony is found in HP 712s, 715/new and many other GSC based machines. * On older 715 machines you'll find the technically identical chip - * called 'Vivace'. Both Harmony and Vicace are supported by this driver. + * called 'Vivace'. Both Harmony and Vivace are supported by this driver. * * this ALSA driver is based on OSS driver by: * Copyright 2000 (c) Linuxcare Canada, Alex deVries <alex@linuxcare.com> @@ -43,7 +43,7 @@ * to be recorded is put in RNXTADD. There is 2 read-only registers, PCURADD and * RCURADD that provides adress of current page. * - * Harmony has no way to controll full duplex or half duplex mode. It means + * Harmony has no way to control full duplex or half duplex mode. It means * that we always need to provide adresses of playback and capture data, even * when this is not needed. That's why we statically alloc one graveyard * buffer (to put recorded data in play-only mode) and a silence buffer. @@ -556,7 +556,7 @@ static int snd_card_harmony_playback_prepare(snd_pcm_substream_t * substream) harmony->sample_rate = snd_card_harmony_rate_bits(runtime->rate); /* data format */ - harmony->data_format = snd_harmony_set_data_format(haromny, runtime->format); + harmony->data_format = snd_harmony_set_data_format(harmony, runtime->format); /* number of channels */ if (runtime->channels == 2) @@ -587,7 +587,7 @@ static int snd_card_harmony_capture_prepare(snd_pcm_substream_t * substream) harmony->sample_rate = snd_card_harmony_rate_bits(runtime->rate); /* data format */ - harmony->data_format = snd_harmony_set_data_format(haromny, runtime->format); + harmony->data_format = snd_harmony_set_data_format(harmony, runtime->format); /* number of channels */ if (runtime->channels == 1) |