^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) ad1816a.c - lowlevel code for Analog Devices AD1816A chip.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) Copyright (C) 1999-2000 by Massimo Piccioni <dafastidio@libero.it>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <sound/tlv.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <sound/ad1816a.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <asm/dma.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static inline int snd_ad1816a_busy_wait(struct snd_ad1816a *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) int timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) for (timeout = 1000; timeout-- > 0; udelay(10))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) if (inb(AD1816A_REG(AD1816A_CHIP_STATUS)) & AD1816A_READY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) snd_printk(KERN_WARNING "chip busy.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static inline unsigned char snd_ad1816a_in(struct snd_ad1816a *chip, unsigned char reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) snd_ad1816a_busy_wait(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) return inb(AD1816A_REG(reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static inline void snd_ad1816a_out(struct snd_ad1816a *chip, unsigned char reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) unsigned char value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) snd_ad1816a_busy_wait(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) outb(value, AD1816A_REG(reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static inline void snd_ad1816a_out_mask(struct snd_ad1816a *chip, unsigned char reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) unsigned char mask, unsigned char value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) snd_ad1816a_out(chip, reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) (value & mask) | (snd_ad1816a_in(chip, reg) & ~mask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static unsigned short snd_ad1816a_read(struct snd_ad1816a *chip, unsigned char reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) snd_ad1816a_out(chip, AD1816A_INDIR_ADDR, reg & 0x3f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) return snd_ad1816a_in(chip, AD1816A_INDIR_DATA_LOW) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) (snd_ad1816a_in(chip, AD1816A_INDIR_DATA_HIGH) << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) static void snd_ad1816a_write(struct snd_ad1816a *chip, unsigned char reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) unsigned short value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) snd_ad1816a_out(chip, AD1816A_INDIR_ADDR, reg & 0x3f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) snd_ad1816a_out(chip, AD1816A_INDIR_DATA_LOW, value & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) snd_ad1816a_out(chip, AD1816A_INDIR_DATA_HIGH, (value >> 8) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static void snd_ad1816a_write_mask(struct snd_ad1816a *chip, unsigned char reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) unsigned short mask, unsigned short value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) snd_ad1816a_write(chip, reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) (value & mask) | (snd_ad1816a_read(chip, reg) & ~mask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) static unsigned char snd_ad1816a_get_format(struct snd_ad1816a *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) snd_pcm_format_t format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) int channels)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) unsigned char retval = AD1816A_FMT_LINEAR_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) switch (format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) case SNDRV_PCM_FORMAT_MU_LAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) retval = AD1816A_FMT_ULAW_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) case SNDRV_PCM_FORMAT_A_LAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) retval = AD1816A_FMT_ALAW_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) case SNDRV_PCM_FORMAT_S16_LE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) retval = AD1816A_FMT_LINEAR_16_LIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) case SNDRV_PCM_FORMAT_S16_BE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) retval = AD1816A_FMT_LINEAR_16_BIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) return (channels > 1) ? (retval | AD1816A_FMT_STEREO) : retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static int snd_ad1816a_open(struct snd_ad1816a *chip, unsigned int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) spin_lock_irqsave(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (chip->mode & mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) spin_unlock_irqrestore(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) switch ((mode &= AD1816A_MODE_OPEN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) case AD1816A_MODE_PLAYBACK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) snd_ad1816a_out_mask(chip, AD1816A_INTERRUPT_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) AD1816A_PLAYBACK_IRQ_PENDING, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) snd_ad1816a_write_mask(chip, AD1816A_INTERRUPT_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) AD1816A_PLAYBACK_IRQ_ENABLE, 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) case AD1816A_MODE_CAPTURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) snd_ad1816a_out_mask(chip, AD1816A_INTERRUPT_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) AD1816A_CAPTURE_IRQ_PENDING, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) snd_ad1816a_write_mask(chip, AD1816A_INTERRUPT_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) AD1816A_CAPTURE_IRQ_ENABLE, 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) case AD1816A_MODE_TIMER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) snd_ad1816a_out_mask(chip, AD1816A_INTERRUPT_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) AD1816A_TIMER_IRQ_PENDING, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) snd_ad1816a_write_mask(chip, AD1816A_INTERRUPT_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) AD1816A_TIMER_IRQ_ENABLE, 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) chip->mode |= mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) spin_unlock_irqrestore(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static void snd_ad1816a_close(struct snd_ad1816a *chip, unsigned int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) spin_lock_irqsave(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) switch ((mode &= AD1816A_MODE_OPEN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) case AD1816A_MODE_PLAYBACK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) snd_ad1816a_out_mask(chip, AD1816A_INTERRUPT_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) AD1816A_PLAYBACK_IRQ_PENDING, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) snd_ad1816a_write_mask(chip, AD1816A_INTERRUPT_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) AD1816A_PLAYBACK_IRQ_ENABLE, 0x0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) case AD1816A_MODE_CAPTURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) snd_ad1816a_out_mask(chip, AD1816A_INTERRUPT_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) AD1816A_CAPTURE_IRQ_PENDING, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) snd_ad1816a_write_mask(chip, AD1816A_INTERRUPT_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) AD1816A_CAPTURE_IRQ_ENABLE, 0x0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) case AD1816A_MODE_TIMER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) snd_ad1816a_out_mask(chip, AD1816A_INTERRUPT_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) AD1816A_TIMER_IRQ_PENDING, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) snd_ad1816a_write_mask(chip, AD1816A_INTERRUPT_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) AD1816A_TIMER_IRQ_ENABLE, 0x0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (!((chip->mode &= ~mode) & AD1816A_MODE_OPEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) chip->mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) spin_unlock_irqrestore(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static int snd_ad1816a_trigger(struct snd_ad1816a *chip, unsigned char what,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) int channel, int cmd, int iscapture)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) spin_lock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) cmd = (cmd == SNDRV_PCM_TRIGGER_START) ? 0xff: 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /* if (what & AD1816A_PLAYBACK_ENABLE) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) /* That is not valid, because playback and capture enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * are the same bit pattern, just to different addresses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (! iscapture)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) snd_ad1816a_out_mask(chip, AD1816A_PLAYBACK_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) AD1816A_PLAYBACK_ENABLE, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) snd_ad1816a_out_mask(chip, AD1816A_CAPTURE_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) AD1816A_CAPTURE_ENABLE, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) spin_unlock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) snd_printk(KERN_WARNING "invalid trigger mode 0x%x.\n", what);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static int snd_ad1816a_playback_trigger(struct snd_pcm_substream *substream, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) return snd_ad1816a_trigger(chip, AD1816A_PLAYBACK_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) SNDRV_PCM_STREAM_PLAYBACK, cmd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) static int snd_ad1816a_capture_trigger(struct snd_pcm_substream *substream, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return snd_ad1816a_trigger(chip, AD1816A_CAPTURE_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) SNDRV_PCM_STREAM_CAPTURE, cmd, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) static int snd_ad1816a_playback_prepare(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) unsigned int size, rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) spin_lock_irqsave(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) chip->p_dma_size = size = snd_pcm_lib_buffer_bytes(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) snd_ad1816a_out_mask(chip, AD1816A_PLAYBACK_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) AD1816A_PLAYBACK_ENABLE | AD1816A_PLAYBACK_PIO, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) snd_dma_program(chip->dma1, runtime->dma_addr, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) DMA_MODE_WRITE | DMA_AUTOINIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) rate = runtime->rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (chip->clock_freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) rate = (rate * 33000) / chip->clock_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) snd_ad1816a_write(chip, AD1816A_PLAYBACK_SAMPLE_RATE, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) snd_ad1816a_out_mask(chip, AD1816A_PLAYBACK_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) AD1816A_FMT_ALL | AD1816A_FMT_STEREO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) snd_ad1816a_get_format(chip, runtime->format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) runtime->channels));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) snd_ad1816a_write(chip, AD1816A_PLAYBACK_BASE_COUNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) snd_pcm_lib_period_bytes(substream) / 4 - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) spin_unlock_irqrestore(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static int snd_ad1816a_capture_prepare(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) unsigned int size, rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) spin_lock_irqsave(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) chip->c_dma_size = size = snd_pcm_lib_buffer_bytes(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) snd_ad1816a_out_mask(chip, AD1816A_CAPTURE_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) AD1816A_CAPTURE_ENABLE | AD1816A_CAPTURE_PIO, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) snd_dma_program(chip->dma2, runtime->dma_addr, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) DMA_MODE_READ | DMA_AUTOINIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) rate = runtime->rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (chip->clock_freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) rate = (rate * 33000) / chip->clock_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) snd_ad1816a_write(chip, AD1816A_CAPTURE_SAMPLE_RATE, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) snd_ad1816a_out_mask(chip, AD1816A_CAPTURE_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) AD1816A_FMT_ALL | AD1816A_FMT_STEREO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) snd_ad1816a_get_format(chip, runtime->format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) runtime->channels));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) snd_ad1816a_write(chip, AD1816A_CAPTURE_BASE_COUNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) snd_pcm_lib_period_bytes(substream) / 4 - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) spin_unlock_irqrestore(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) static snd_pcm_uframes_t snd_ad1816a_playback_pointer(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) size_t ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (!(chip->mode & AD1816A_MODE_PLAYBACK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) ptr = snd_dma_pointer(chip->dma1, chip->p_dma_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return bytes_to_frames(substream->runtime, ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) static snd_pcm_uframes_t snd_ad1816a_capture_pointer(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) size_t ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (!(chip->mode & AD1816A_MODE_CAPTURE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) ptr = snd_dma_pointer(chip->dma2, chip->c_dma_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) return bytes_to_frames(substream->runtime, ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) static irqreturn_t snd_ad1816a_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) struct snd_ad1816a *chip = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) unsigned char status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) spin_lock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) status = snd_ad1816a_in(chip, AD1816A_INTERRUPT_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) spin_unlock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if ((status & AD1816A_PLAYBACK_IRQ_PENDING) && chip->playback_substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) snd_pcm_period_elapsed(chip->playback_substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if ((status & AD1816A_CAPTURE_IRQ_PENDING) && chip->capture_substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) snd_pcm_period_elapsed(chip->capture_substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if ((status & AD1816A_TIMER_IRQ_PENDING) && chip->timer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) snd_timer_interrupt(chip->timer, chip->timer->sticks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) spin_lock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) snd_ad1816a_out(chip, AD1816A_INTERRUPT_STATUS, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) spin_unlock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) static const struct snd_pcm_hardware snd_ad1816a_playback = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) SNDRV_PCM_INFO_MMAP_VALID),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) SNDRV_PCM_FMTBIT_S16_BE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) .rate_min = 4000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) .rate_max = 55200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) .buffer_bytes_max = (128*1024),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) .period_bytes_min = 64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) .period_bytes_max = (128*1024),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) .periods_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) .periods_max = 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) .fifo_size = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static const struct snd_pcm_hardware snd_ad1816a_capture = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) SNDRV_PCM_INFO_MMAP_VALID),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) SNDRV_PCM_FMTBIT_S16_BE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) .rate_min = 4000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) .rate_max = 55200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) .buffer_bytes_max = (128*1024),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) .period_bytes_min = 64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) .period_bytes_max = (128*1024),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) .periods_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) .periods_max = 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) .fifo_size = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) static int snd_ad1816a_timer_close(struct snd_timer *timer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) struct snd_ad1816a *chip = snd_timer_chip(timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) snd_ad1816a_close(chip, AD1816A_MODE_TIMER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) static int snd_ad1816a_timer_open(struct snd_timer *timer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) struct snd_ad1816a *chip = snd_timer_chip(timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) snd_ad1816a_open(chip, AD1816A_MODE_TIMER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) static unsigned long snd_ad1816a_timer_resolution(struct snd_timer *timer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (snd_BUG_ON(!timer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) return 10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) static int snd_ad1816a_timer_start(struct snd_timer *timer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) unsigned short bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) struct snd_ad1816a *chip = snd_timer_chip(timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) spin_lock_irqsave(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) bits = snd_ad1816a_read(chip, AD1816A_INTERRUPT_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (!(bits & AD1816A_TIMER_ENABLE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) snd_ad1816a_write(chip, AD1816A_TIMER_BASE_COUNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) timer->sticks & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) snd_ad1816a_write_mask(chip, AD1816A_INTERRUPT_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) AD1816A_TIMER_ENABLE, 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) spin_unlock_irqrestore(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) static int snd_ad1816a_timer_stop(struct snd_timer *timer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) struct snd_ad1816a *chip = snd_timer_chip(timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) spin_lock_irqsave(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) snd_ad1816a_write_mask(chip, AD1816A_INTERRUPT_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) AD1816A_TIMER_ENABLE, 0x0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) spin_unlock_irqrestore(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) static const struct snd_timer_hardware snd_ad1816a_timer_table = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) .flags = SNDRV_TIMER_HW_AUTO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) .resolution = 10000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) .ticks = 65535,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) .open = snd_ad1816a_timer_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) .close = snd_ad1816a_timer_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) .c_resolution = snd_ad1816a_timer_resolution,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) .start = snd_ad1816a_timer_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) .stop = snd_ad1816a_timer_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) static int snd_ad1816a_playback_open(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if ((error = snd_ad1816a_open(chip, AD1816A_MODE_PLAYBACK)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) runtime->hw = snd_ad1816a_playback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.buffer_bytes_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.period_bytes_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) chip->playback_substream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) static int snd_ad1816a_capture_open(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if ((error = snd_ad1816a_open(chip, AD1816A_MODE_CAPTURE)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) runtime->hw = snd_ad1816a_capture;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.buffer_bytes_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.period_bytes_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) chip->capture_substream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) static int snd_ad1816a_playback_close(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) chip->playback_substream = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) snd_ad1816a_close(chip, AD1816A_MODE_PLAYBACK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) static int snd_ad1816a_capture_close(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) chip->capture_substream = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) snd_ad1816a_close(chip, AD1816A_MODE_CAPTURE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) static void snd_ad1816a_init(struct snd_ad1816a *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) spin_lock_irqsave(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) snd_ad1816a_out(chip, AD1816A_INTERRUPT_STATUS, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) snd_ad1816a_out_mask(chip, AD1816A_PLAYBACK_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) AD1816A_PLAYBACK_ENABLE | AD1816A_PLAYBACK_PIO, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) snd_ad1816a_out_mask(chip, AD1816A_CAPTURE_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) AD1816A_CAPTURE_ENABLE | AD1816A_CAPTURE_PIO, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) snd_ad1816a_write(chip, AD1816A_INTERRUPT_ENABLE, 0x0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) snd_ad1816a_write_mask(chip, AD1816A_CHIP_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) AD1816A_CAPTURE_NOT_EQUAL | AD1816A_WSS_ENABLE, 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) snd_ad1816a_write(chip, AD1816A_DSP_CONFIG, 0x0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) snd_ad1816a_write(chip, AD1816A_POWERDOWN_CTRL, 0x0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) spin_unlock_irqrestore(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) void snd_ad1816a_suspend(struct snd_ad1816a *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) spin_lock_irqsave(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) for (reg = 0; reg < 48; reg++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) chip->image[reg] = snd_ad1816a_read(chip, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) spin_unlock_irqrestore(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) void snd_ad1816a_resume(struct snd_ad1816a *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) snd_ad1816a_init(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) spin_lock_irqsave(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) for (reg = 0; reg < 48; reg++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) snd_ad1816a_write(chip, reg, chip->image[reg]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) spin_unlock_irqrestore(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) static int snd_ad1816a_probe(struct snd_ad1816a *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) spin_lock_irqsave(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) switch (chip->version = snd_ad1816a_read(chip, AD1816A_VERSION_ID)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) chip->hardware = AD1816A_HW_AD1815;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) chip->hardware = AD1816A_HW_AD18MAX10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) chip->hardware = AD1816A_HW_AD1816A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) chip->hardware = AD1816A_HW_AUTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) spin_unlock_irqrestore(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) static int snd_ad1816a_free(struct snd_ad1816a *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) release_and_free_resource(chip->res_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (chip->irq >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) free_irq(chip->irq, (void *) chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) if (chip->dma1 >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) snd_dma_disable(chip->dma1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) free_dma(chip->dma1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (chip->dma2 >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) snd_dma_disable(chip->dma2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) free_dma(chip->dma2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) static int snd_ad1816a_dev_free(struct snd_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) struct snd_ad1816a *chip = device->device_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) return snd_ad1816a_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) static const char *snd_ad1816a_chip_id(struct snd_ad1816a *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) switch (chip->hardware) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) case AD1816A_HW_AD1816A: return "AD1816A";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) case AD1816A_HW_AD1815: return "AD1815";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) case AD1816A_HW_AD18MAX10: return "AD18max10";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) snd_printk(KERN_WARNING "Unknown chip version %d:%d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) chip->version, chip->hardware);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return "AD1816A - unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) int snd_ad1816a_create(struct snd_card *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) unsigned long port, int irq, int dma1, int dma2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) struct snd_ad1816a *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) static const struct snd_device_ops ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) .dev_free = snd_ad1816a_dev_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) chip->irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) chip->dma1 = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) chip->dma2 = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if ((chip->res_port = request_region(port, 16, "AD1816A")) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) snd_printk(KERN_ERR "ad1816a: can't grab port 0x%lx\n", port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) snd_ad1816a_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if (request_irq(irq, snd_ad1816a_interrupt, 0, "AD1816A", (void *) chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) snd_printk(KERN_ERR "ad1816a: can't grab IRQ %d\n", irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) snd_ad1816a_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) chip->irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) card->sync_irq = chip->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) if (request_dma(dma1, "AD1816A - 1")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) snd_printk(KERN_ERR "ad1816a: can't grab DMA1 %d\n", dma1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) snd_ad1816a_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) chip->dma1 = dma1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if (request_dma(dma2, "AD1816A - 2")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) snd_printk(KERN_ERR "ad1816a: can't grab DMA2 %d\n", dma2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) snd_ad1816a_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) chip->dma2 = dma2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) chip->card = card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) chip->port = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) spin_lock_init(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) if ((error = snd_ad1816a_probe(chip))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) snd_ad1816a_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) snd_ad1816a_init(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) /* Register device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) if ((error = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) snd_ad1816a_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) static const struct snd_pcm_ops snd_ad1816a_playback_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) .open = snd_ad1816a_playback_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) .close = snd_ad1816a_playback_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) .prepare = snd_ad1816a_playback_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) .trigger = snd_ad1816a_playback_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) .pointer = snd_ad1816a_playback_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) static const struct snd_pcm_ops snd_ad1816a_capture_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) .open = snd_ad1816a_capture_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) .close = snd_ad1816a_capture_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) .prepare = snd_ad1816a_capture_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) .trigger = snd_ad1816a_capture_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) .pointer = snd_ad1816a_capture_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) int snd_ad1816a_pcm(struct snd_ad1816a *chip, int device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) struct snd_pcm *pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) if ((error = snd_pcm_new(chip->card, "AD1816A", device, 1, 1, &pcm)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ad1816a_playback_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ad1816a_capture_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) pcm->private_data = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) pcm->info_flags = (chip->dma1 == chip->dma2 ) ? SNDRV_PCM_INFO_JOINT_DUPLEX : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) strcpy(pcm->name, snd_ad1816a_chip_id(chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) snd_ad1816a_init(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 64*1024, chip->dma1 > 3 || chip->dma2 > 3 ? 128*1024 : 64*1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) chip->pcm = pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) int snd_ad1816a_timer(struct snd_ad1816a *chip, int device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) struct snd_timer *timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) struct snd_timer_id tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) tid.dev_class = SNDRV_TIMER_CLASS_CARD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) tid.card = chip->card->number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) tid.device = device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) tid.subdevice = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if ((error = snd_timer_new(chip->card, "AD1816A", &tid, &timer)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) strcpy(timer->name, snd_ad1816a_chip_id(chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) timer->private_data = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) chip->timer = timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) timer->hw = snd_ad1816a_timer_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) static int snd_ad1816a_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) static const char * const texts[8] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) "Line", "Mix", "CD", "Synth", "Video",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) "Mic", "Phone",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) return snd_ctl_enum_info(uinfo, 2, 7, texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) static int snd_ad1816a_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) struct snd_ad1816a *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) unsigned short val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) spin_lock_irqsave(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) val = snd_ad1816a_read(chip, AD1816A_ADC_SOURCE_SEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) spin_unlock_irqrestore(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) ucontrol->value.enumerated.item[0] = (val >> 12) & 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) ucontrol->value.enumerated.item[1] = (val >> 4) & 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) static int snd_ad1816a_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) struct snd_ad1816a *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) unsigned short val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) if (ucontrol->value.enumerated.item[0] > 6 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) ucontrol->value.enumerated.item[1] > 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) val = (ucontrol->value.enumerated.item[0] << 12) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) (ucontrol->value.enumerated.item[1] << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) spin_lock_irqsave(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) change = snd_ad1816a_read(chip, AD1816A_ADC_SOURCE_SEL) != val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) snd_ad1816a_write(chip, AD1816A_ADC_SOURCE_SEL, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) spin_unlock_irqrestore(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) #define AD1816A_SINGLE_TLV(xname, reg, shift, mask, invert, xtlv) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) .name = xname, .info = snd_ad1816a_info_single, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) .get = snd_ad1816a_get_single, .put = snd_ad1816a_put_single, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) .tlv = { .p = (xtlv) } }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) #define AD1816A_SINGLE(xname, reg, shift, mask, invert) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ad1816a_info_single, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) .get = snd_ad1816a_get_single, .put = snd_ad1816a_put_single, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) static int snd_ad1816a_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) int mask = (kcontrol->private_value >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) uinfo->value.integer.max = mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) static int snd_ad1816a_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) struct snd_ad1816a *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) int reg = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) int shift = (kcontrol->private_value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) int mask = (kcontrol->private_value >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) int invert = (kcontrol->private_value >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) spin_lock_irqsave(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) ucontrol->value.integer.value[0] = (snd_ad1816a_read(chip, reg) >> shift) & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) spin_unlock_irqrestore(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) if (invert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) static int snd_ad1816a_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) struct snd_ad1816a *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) int reg = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) int shift = (kcontrol->private_value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) int mask = (kcontrol->private_value >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) int invert = (kcontrol->private_value >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) unsigned short old_val, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) val = (ucontrol->value.integer.value[0] & mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) if (invert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) val = mask - val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) val <<= shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) spin_lock_irqsave(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) old_val = snd_ad1816a_read(chip, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) val = (old_val & ~(mask << shift)) | val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) change = val != old_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) snd_ad1816a_write(chip, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) spin_unlock_irqrestore(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) #define AD1816A_DOUBLE_TLV(xname, reg, shift_left, shift_right, mask, invert, xtlv) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) .name = xname, .info = snd_ad1816a_info_double, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) .get = snd_ad1816a_get_double, .put = snd_ad1816a_put_double, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) .private_value = reg | (shift_left << 8) | (shift_right << 12) | (mask << 16) | (invert << 24), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) .tlv = { .p = (xtlv) } }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) #define AD1816A_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ad1816a_info_double, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) .get = snd_ad1816a_get_double, .put = snd_ad1816a_put_double, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) .private_value = reg | (shift_left << 8) | (shift_right << 12) | (mask << 16) | (invert << 24) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) static int snd_ad1816a_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) int mask = (kcontrol->private_value >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) uinfo->count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) uinfo->value.integer.max = mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) static int snd_ad1816a_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) struct snd_ad1816a *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) int reg = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) int shift_left = (kcontrol->private_value >> 8) & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) int shift_right = (kcontrol->private_value >> 12) & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) int mask = (kcontrol->private_value >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) int invert = (kcontrol->private_value >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) unsigned short val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) spin_lock_irqsave(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) val = snd_ad1816a_read(chip, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) ucontrol->value.integer.value[0] = (val >> shift_left) & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) ucontrol->value.integer.value[1] = (val >> shift_right) & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) spin_unlock_irqrestore(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) if (invert) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) static int snd_ad1816a_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) struct snd_ad1816a *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) int reg = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) int shift_left = (kcontrol->private_value >> 8) & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) int shift_right = (kcontrol->private_value >> 12) & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) int mask = (kcontrol->private_value >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) int invert = (kcontrol->private_value >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) unsigned short old_val, val1, val2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) val1 = ucontrol->value.integer.value[0] & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) val2 = ucontrol->value.integer.value[1] & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (invert) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) val1 = mask - val1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) val2 = mask - val2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) val1 <<= shift_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) val2 <<= shift_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) spin_lock_irqsave(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) old_val = snd_ad1816a_read(chip, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) val1 = (old_val & ~((mask << shift_left) | (mask << shift_right))) | val1 | val2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) change = val1 != old_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) snd_ad1816a_write(chip, reg, val1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) spin_unlock_irqrestore(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) static const DECLARE_TLV_DB_SCALE(db_scale_4bit, -4500, 300, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) static const DECLARE_TLV_DB_SCALE(db_scale_5bit, -4650, 150, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) static const struct snd_kcontrol_new snd_ad1816a_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) AD1816A_DOUBLE("Master Playback Switch", AD1816A_MASTER_ATT, 15, 7, 1, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) AD1816A_DOUBLE_TLV("Master Playback Volume", AD1816A_MASTER_ATT, 8, 0, 31, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) db_scale_5bit),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) AD1816A_DOUBLE("PCM Playback Switch", AD1816A_VOICE_ATT, 15, 7, 1, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) AD1816A_DOUBLE_TLV("PCM Playback Volume", AD1816A_VOICE_ATT, 8, 0, 63, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) db_scale_6bit),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) AD1816A_DOUBLE("Line Playback Switch", AD1816A_LINE_GAIN_ATT, 15, 7, 1, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) AD1816A_DOUBLE_TLV("Line Playback Volume", AD1816A_LINE_GAIN_ATT, 8, 0, 31, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) db_scale_5bit_12db_max),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) AD1816A_DOUBLE("CD Playback Switch", AD1816A_CD_GAIN_ATT, 15, 7, 1, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) AD1816A_DOUBLE_TLV("CD Playback Volume", AD1816A_CD_GAIN_ATT, 8, 0, 31, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) db_scale_5bit_12db_max),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) AD1816A_DOUBLE("Synth Playback Switch", AD1816A_SYNTH_GAIN_ATT, 15, 7, 1, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) AD1816A_DOUBLE_TLV("Synth Playback Volume", AD1816A_SYNTH_GAIN_ATT, 8, 0, 31, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) db_scale_5bit_12db_max),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) AD1816A_DOUBLE("FM Playback Switch", AD1816A_FM_ATT, 15, 7, 1, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) AD1816A_DOUBLE_TLV("FM Playback Volume", AD1816A_FM_ATT, 8, 0, 63, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) db_scale_6bit),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) AD1816A_SINGLE("Mic Playback Switch", AD1816A_MIC_GAIN_ATT, 15, 1, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) AD1816A_SINGLE_TLV("Mic Playback Volume", AD1816A_MIC_GAIN_ATT, 8, 31, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) db_scale_5bit_12db_max),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) AD1816A_SINGLE("Mic Boost", AD1816A_MIC_GAIN_ATT, 14, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) AD1816A_DOUBLE("Video Playback Switch", AD1816A_VID_GAIN_ATT, 15, 7, 1, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) AD1816A_DOUBLE_TLV("Video Playback Volume", AD1816A_VID_GAIN_ATT, 8, 0, 31, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) db_scale_5bit_12db_max),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) AD1816A_SINGLE("Phone Capture Switch", AD1816A_PHONE_IN_GAIN_ATT, 15, 1, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) AD1816A_SINGLE_TLV("Phone Capture Volume", AD1816A_PHONE_IN_GAIN_ATT, 0, 15, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) db_scale_4bit),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) AD1816A_SINGLE("Phone Playback Switch", AD1816A_PHONE_OUT_ATT, 7, 1, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) AD1816A_SINGLE_TLV("Phone Playback Volume", AD1816A_PHONE_OUT_ATT, 0, 31, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) db_scale_5bit),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) .name = "Capture Source",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) .info = snd_ad1816a_info_mux,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) .get = snd_ad1816a_get_mux,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) .put = snd_ad1816a_put_mux,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) AD1816A_DOUBLE("Capture Switch", AD1816A_ADC_PGA, 15, 7, 1, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) AD1816A_DOUBLE_TLV("Capture Volume", AD1816A_ADC_PGA, 8, 0, 15, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) db_scale_rec_gain),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) AD1816A_SINGLE("3D Control - Switch", AD1816A_3D_PHAT_CTRL, 15, 1, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) AD1816A_SINGLE("3D Control - Level", AD1816A_3D_PHAT_CTRL, 0, 15, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) int snd_ad1816a_mixer(struct snd_ad1816a *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) unsigned int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) if (snd_BUG_ON(!chip || !chip->card))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) card = chip->card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) strcpy(card->mixername, snd_ad1816a_chip_id(chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) for (idx = 0; idx < ARRAY_SIZE(snd_ad1816a_controls); idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_ad1816a_controls[idx], chip))) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) }