^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Driver for A2 audio system used in SGI machines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2008 Thomas Bogendoerfer <tsbogend@alpha.fanken.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Based on OSS code from Ladislav Michl <ladis@linux-mips.org>, which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * was based on code from Ulf Carlsson
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <asm/sgi/hpc3.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <asm/sgi/ip22.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <sound/control.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <sound/pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <sound/pcm-indirect.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <sound/initval.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include "hal2.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) module_param(index, int, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) MODULE_PARM_DESC(index, "Index value for SGI HAL2 soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) module_param(id, charp, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) MODULE_PARM_DESC(id, "ID string for SGI HAL2 soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) MODULE_DESCRIPTION("ALSA driver for SGI HAL2 audio");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) MODULE_AUTHOR("Thomas Bogendoerfer");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define H2_BLOCK_SIZE 1024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define H2_BUF_SIZE 16384
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct hal2_pbus {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct hpc3_pbus_dmacregs *pbus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) int pbusnr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) unsigned int ctrl; /* Current state of pbus->pbdma_ctrl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct hal2_desc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct hpc_dma_desc desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) u32 pad; /* padding */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct hal2_codec {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct snd_pcm_indirect pcm_indirect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) struct snd_pcm_substream *substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) unsigned char *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) dma_addr_t buffer_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct hal2_desc *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) dma_addr_t desc_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) int desc_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct hal2_pbus pbus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) int voices; /* mono/stereo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) unsigned int sample_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) unsigned int master; /* Master frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) unsigned short mod; /* MOD value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) unsigned short inc; /* INC value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define H2_MIX_OUTPUT_ATT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define H2_MIX_INPUT_GAIN 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct snd_hal2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct hal2_ctl_regs *ctl_regs; /* HAL2 ctl registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct hal2_aes_regs *aes_regs; /* HAL2 aes registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct hal2_vol_regs *vol_regs; /* HAL2 vol registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct hal2_syn_regs *syn_regs; /* HAL2 syn registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct hal2_codec dac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct hal2_codec adc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define H2_INDIRECT_WAIT(regs) while (hal2_read(®s->isr) & H2_ISR_TSTATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define H2_READ_ADDR(addr) (addr | (1<<7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define H2_WRITE_ADDR(addr) (addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static inline u32 hal2_read(u32 *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) return __raw_readl(reg);
^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 inline void hal2_write(u32 val, u32 *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) __raw_writel(val, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static u32 hal2_i_read32(struct snd_hal2 *hal2, u16 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) u32 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct hal2_ctl_regs *regs = hal2->ctl_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) hal2_write(H2_READ_ADDR(addr), ®s->iar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) H2_INDIRECT_WAIT(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) ret = hal2_read(®s->idr0) & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) hal2_write(H2_READ_ADDR(addr) | 0x1, ®s->iar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) H2_INDIRECT_WAIT(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) ret |= (hal2_read(®s->idr0) & 0xffff) << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static void hal2_i_write16(struct snd_hal2 *hal2, u16 addr, u16 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct hal2_ctl_regs *regs = hal2->ctl_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) hal2_write(val, ®s->idr0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) hal2_write(0, ®s->idr1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) hal2_write(0, ®s->idr2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) hal2_write(0, ®s->idr3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) hal2_write(H2_WRITE_ADDR(addr), ®s->iar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) H2_INDIRECT_WAIT(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static void hal2_i_write32(struct snd_hal2 *hal2, u16 addr, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct hal2_ctl_regs *regs = hal2->ctl_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) hal2_write(val & 0xffff, ®s->idr0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) hal2_write(val >> 16, ®s->idr1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) hal2_write(0, ®s->idr2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) hal2_write(0, ®s->idr3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) hal2_write(H2_WRITE_ADDR(addr), ®s->iar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) H2_INDIRECT_WAIT(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static void hal2_i_setbit16(struct snd_hal2 *hal2, u16 addr, u16 bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) struct hal2_ctl_regs *regs = hal2->ctl_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) hal2_write(H2_READ_ADDR(addr), ®s->iar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) H2_INDIRECT_WAIT(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) hal2_write((hal2_read(®s->idr0) & 0xffff) | bit, ®s->idr0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) hal2_write(0, ®s->idr1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) hal2_write(0, ®s->idr2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) hal2_write(0, ®s->idr3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) hal2_write(H2_WRITE_ADDR(addr), ®s->iar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) H2_INDIRECT_WAIT(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static void hal2_i_clearbit16(struct snd_hal2 *hal2, u16 addr, u16 bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) struct hal2_ctl_regs *regs = hal2->ctl_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) hal2_write(H2_READ_ADDR(addr), ®s->iar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) H2_INDIRECT_WAIT(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) hal2_write((hal2_read(®s->idr0) & 0xffff) & ~bit, ®s->idr0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) hal2_write(0, ®s->idr1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) hal2_write(0, ®s->idr2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) hal2_write(0, ®s->idr3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) hal2_write(H2_WRITE_ADDR(addr), ®s->iar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) H2_INDIRECT_WAIT(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static int hal2_gain_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) uinfo->count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) switch ((int)kcontrol->private_value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) case H2_MIX_OUTPUT_ATT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) uinfo->value.integer.max = 31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) case H2_MIX_INPUT_GAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) uinfo->value.integer.max = 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) static int hal2_gain_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct snd_hal2 *hal2 = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) int l, r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) switch ((int)kcontrol->private_value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) case H2_MIX_OUTPUT_ATT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) tmp = hal2_i_read32(hal2, H2I_DAC_C2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (tmp & H2I_C2_MUTE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) l = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) r = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) l = 31 - ((tmp >> H2I_C2_L_ATT_SHIFT) & 31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) r = 31 - ((tmp >> H2I_C2_R_ATT_SHIFT) & 31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) case H2_MIX_INPUT_GAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) tmp = hal2_i_read32(hal2, H2I_ADC_C2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) l = (tmp >> H2I_C2_L_GAIN_SHIFT) & 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) r = (tmp >> H2I_C2_R_GAIN_SHIFT) & 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) ucontrol->value.integer.value[0] = l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) ucontrol->value.integer.value[1] = r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) static int hal2_gain_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) struct snd_hal2 *hal2 = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) u32 old, new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) int l, r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) l = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) r = ucontrol->value.integer.value[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) switch ((int)kcontrol->private_value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) case H2_MIX_OUTPUT_ATT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) old = hal2_i_read32(hal2, H2I_DAC_C2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) new = old & ~(H2I_C2_L_ATT_M | H2I_C2_R_ATT_M | H2I_C2_MUTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (l | r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) l = 31 - l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) r = 31 - r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) new |= (l << H2I_C2_L_ATT_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) new |= (r << H2I_C2_R_ATT_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) new |= H2I_C2_L_ATT_M | H2I_C2_R_ATT_M | H2I_C2_MUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) hal2_i_write32(hal2, H2I_DAC_C2, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) case H2_MIX_INPUT_GAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) old = hal2_i_read32(hal2, H2I_ADC_C2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) new = old & ~(H2I_C2_L_GAIN_M | H2I_C2_R_GAIN_M);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) new |= (l << H2I_C2_L_GAIN_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) new |= (r << H2I_C2_R_GAIN_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) hal2_i_write32(hal2, H2I_ADC_C2, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) return old != new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) static const struct snd_kcontrol_new hal2_ctrl_headphone = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) .name = "Headphone Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) .private_value = H2_MIX_OUTPUT_ATT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) .info = hal2_gain_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) .get = hal2_gain_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) .put = hal2_gain_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) static const struct snd_kcontrol_new hal2_ctrl_mic = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) .name = "Mic Capture Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) .private_value = H2_MIX_INPUT_GAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) .info = hal2_gain_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) .get = hal2_gain_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) .put = hal2_gain_put,
^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 int hal2_mixer_create(struct snd_hal2 *hal2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) /* mute DAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) hal2_i_write32(hal2, H2I_DAC_C2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) H2I_C2_L_ATT_M | H2I_C2_R_ATT_M | H2I_C2_MUTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /* mute ADC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) hal2_i_write32(hal2, H2I_ADC_C2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) err = snd_ctl_add(hal2->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) snd_ctl_new1(&hal2_ctrl_headphone, hal2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) err = snd_ctl_add(hal2->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) snd_ctl_new1(&hal2_ctrl_mic, hal2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) static irqreturn_t hal2_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) struct snd_hal2 *hal2 = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) irqreturn_t ret = IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) /* decide what caused this interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (hal2->dac.pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_INT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) snd_pcm_period_elapsed(hal2->dac.substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) ret = IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (hal2->adc.pbus.pbus->pbdma_ctrl & HPC3_PDMACTRL_INT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) snd_pcm_period_elapsed(hal2->adc.substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) ret = IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) static int hal2_compute_rate(struct hal2_codec *codec, unsigned int rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) unsigned short mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if (44100 % rate < 48000 % rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) mod = 4 * 44100 / rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) codec->master = 44100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) mod = 4 * 48000 / rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) codec->master = 48000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) codec->inc = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) codec->mod = mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) rate = 4 * codec->master / mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) return rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) static void hal2_set_dac_rate(struct snd_hal2 *hal2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) unsigned int master = hal2->dac.master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) int inc = hal2->dac.inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) int mod = hal2->dac.mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) hal2_i_write16(hal2, H2I_BRES1_C1, (master == 44100) ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) hal2_i_write32(hal2, H2I_BRES1_C2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) ((0xffff & (inc - mod - 1)) << 16) | inc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) static void hal2_set_adc_rate(struct snd_hal2 *hal2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) unsigned int master = hal2->adc.master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) int inc = hal2->adc.inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) int mod = hal2->adc.mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) hal2_i_write16(hal2, H2I_BRES2_C1, (master == 44100) ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) hal2_i_write32(hal2, H2I_BRES2_C2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) ((0xffff & (inc - mod - 1)) << 16) | inc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) static void hal2_setup_dac(struct snd_hal2 *hal2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) unsigned int fifobeg, fifoend, highwater, sample_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) struct hal2_pbus *pbus = &hal2->dac.pbus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) /* Now we set up some PBUS information. The PBUS needs information about
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * what portion of the fifo it will use. If it's receiving or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) * transmitting, and finally whether the stream is little endian or big
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) * endian. The information is written later, on the start call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) sample_size = 2 * hal2->dac.voices;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) /* Fifo should be set to hold exactly four samples. Highwater mark
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) * should be set to two samples. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) highwater = (sample_size * 2) >> 1; /* halfwords */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) fifobeg = 0; /* playback is first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) fifoend = (sample_size * 4) >> 3; /* doublewords */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) pbus->ctrl = HPC3_PDMACTRL_RT | HPC3_PDMACTRL_LD |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) (highwater << 8) | (fifobeg << 16) | (fifoend << 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) /* We disable everything before we do anything at all */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) pbus->pbus->pbdma_ctrl = HPC3_PDMACTRL_LD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) hal2_i_clearbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECTX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) /* Setup the HAL2 for playback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) hal2_set_dac_rate(hal2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) /* Set endianess */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) hal2_i_clearbit16(hal2, H2I_DMA_END, H2I_DMA_END_CODECTX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) /* Set DMA bus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) hal2_i_setbit16(hal2, H2I_DMA_DRV, (1 << pbus->pbusnr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) /* We are using 1st Bresenham clock generator for playback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) hal2_i_write16(hal2, H2I_DAC_C1, (pbus->pbusnr << H2I_C1_DMA_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) | (1 << H2I_C1_CLKID_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) | (hal2->dac.voices << H2I_C1_DATAT_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) static void hal2_setup_adc(struct snd_hal2 *hal2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) unsigned int fifobeg, fifoend, highwater, sample_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) struct hal2_pbus *pbus = &hal2->adc.pbus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) sample_size = 2 * hal2->adc.voices;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) highwater = (sample_size * 2) >> 1; /* halfwords */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) fifobeg = (4 * 4) >> 3; /* record is second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) fifoend = (4 * 4 + sample_size * 4) >> 3; /* doublewords */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) pbus->ctrl = HPC3_PDMACTRL_RT | HPC3_PDMACTRL_RCV | HPC3_PDMACTRL_LD |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) (highwater << 8) | (fifobeg << 16) | (fifoend << 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) pbus->pbus->pbdma_ctrl = HPC3_PDMACTRL_LD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) hal2_i_clearbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) /* Setup the HAL2 for record */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) hal2_set_adc_rate(hal2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) /* Set endianess */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) hal2_i_clearbit16(hal2, H2I_DMA_END, H2I_DMA_END_CODECR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) /* Set DMA bus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) hal2_i_setbit16(hal2, H2I_DMA_DRV, (1 << pbus->pbusnr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) /* We are using 2nd Bresenham clock generator for record */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) hal2_i_write16(hal2, H2I_ADC_C1, (pbus->pbusnr << H2I_C1_DMA_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) | (2 << H2I_C1_CLKID_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) | (hal2->adc.voices << H2I_C1_DATAT_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) static void hal2_start_dac(struct snd_hal2 *hal2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) struct hal2_pbus *pbus = &hal2->dac.pbus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) pbus->pbus->pbdma_dptr = hal2->dac.desc_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) pbus->pbus->pbdma_ctrl = pbus->ctrl | HPC3_PDMACTRL_ACT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) /* enable DAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) hal2_i_setbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECTX);
^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 void hal2_start_adc(struct snd_hal2 *hal2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) struct hal2_pbus *pbus = &hal2->adc.pbus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) pbus->pbus->pbdma_dptr = hal2->adc.desc_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) pbus->pbus->pbdma_ctrl = pbus->ctrl | HPC3_PDMACTRL_ACT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) /* enable ADC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) hal2_i_setbit16(hal2, H2I_DMA_PORT_EN, H2I_DMA_PORT_EN_CODECR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) static inline void hal2_stop_dac(struct snd_hal2 *hal2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) hal2->dac.pbus.pbus->pbdma_ctrl = HPC3_PDMACTRL_LD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) /* The HAL2 itself may remain enabled safely */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) static inline void hal2_stop_adc(struct snd_hal2 *hal2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) hal2->adc.pbus.pbus->pbdma_ctrl = HPC3_PDMACTRL_LD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) static int hal2_alloc_dmabuf(struct snd_hal2 *hal2, struct hal2_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) enum dma_data_direction buffer_dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) struct device *dev = hal2->card->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) struct hal2_desc *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) dma_addr_t desc_dma, buffer_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) int count = H2_BUF_SIZE / H2_BLOCK_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) codec->buffer = dma_alloc_noncoherent(dev, H2_BUF_SIZE, &buffer_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) buffer_dir, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (!codec->buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) desc = dma_alloc_noncoherent(dev, count * sizeof(struct hal2_desc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) &desc_dma, DMA_BIDIRECTIONAL, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (!desc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) dma_free_noncoherent(dev, H2_BUF_SIZE, codec->buffer, buffer_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) buffer_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) codec->buffer_dma = buffer_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) codec->desc_dma = desc_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) codec->desc = desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) for (i = 0; i < count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) desc->desc.pbuf = buffer_dma + i * H2_BLOCK_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) desc->desc.cntinfo = HPCDMA_XIE | H2_BLOCK_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) desc->desc.pnext = (i == count - 1) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) desc_dma : desc_dma + (i + 1) * sizeof(struct hal2_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) desc++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) dma_sync_single_for_device(dev, codec->desc_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) count * sizeof(struct hal2_desc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) DMA_BIDIRECTIONAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) codec->desc_count = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) static void hal2_free_dmabuf(struct snd_hal2 *hal2, struct hal2_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) enum dma_data_direction buffer_dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) struct device *dev = hal2->card->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) dma_free_noncoherent(dev, codec->desc_count * sizeof(struct hal2_desc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) codec->desc, codec->desc_dma, DMA_BIDIRECTIONAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) dma_free_noncoherent(dev, H2_BUF_SIZE, codec->buffer, codec->buffer_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) buffer_dir);
^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) static const struct snd_pcm_hardware hal2_pcm_hw = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) .info = (SNDRV_PCM_INFO_MMAP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) SNDRV_PCM_INFO_MMAP_VALID |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) SNDRV_PCM_INFO_INTERLEAVED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) SNDRV_PCM_INFO_BLOCK_TRANSFER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) SNDRV_PCM_INFO_SYNC_APPLPTR),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) .formats = SNDRV_PCM_FMTBIT_S16_BE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) .rates = SNDRV_PCM_RATE_8000_48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) .rate_min = 8000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) .rate_max = 48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) .channels_min = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) .buffer_bytes_max = 65536,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) .period_bytes_min = 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) .period_bytes_max = 65536,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) .periods_min = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) .periods_max = 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) static int hal2_playback_open(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) runtime->hw = hal2_pcm_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) return hal2_alloc_dmabuf(hal2, &hal2->dac, DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) static int hal2_playback_close(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) hal2_free_dmabuf(hal2, &hal2->dac, DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) static int hal2_playback_prepare(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) struct hal2_codec *dac = &hal2->dac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) dac->voices = runtime->channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) dac->sample_rate = hal2_compute_rate(dac, runtime->rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) memset(&dac->pcm_indirect, 0, sizeof(dac->pcm_indirect));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) dac->pcm_indirect.hw_buffer_size = H2_BUF_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) dac->pcm_indirect.hw_queue_size = H2_BUF_SIZE / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) dac->pcm_indirect.hw_io = dac->buffer_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) dac->pcm_indirect.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) dac->substream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) hal2_setup_dac(hal2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) static int hal2_playback_trigger(struct snd_pcm_substream *substream, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) hal2_start_dac(hal2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) hal2_stop_dac(hal2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) return 0;
^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 snd_pcm_uframes_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) hal2_playback_pointer(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) struct hal2_codec *dac = &hal2->dac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) return snd_pcm_indirect_playback_pointer(substream, &dac->pcm_indirect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) dac->pbus.pbus->pbdma_bptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) static void hal2_playback_transfer(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) struct snd_pcm_indirect *rec, size_t bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) unsigned char *buf = hal2->dac.buffer + rec->hw_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) memcpy(buf, substream->runtime->dma_area + rec->sw_data, bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) dma_sync_single_for_device(hal2->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) hal2->dac.buffer_dma + rec->hw_data, bytes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) static int hal2_playback_ack(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) struct hal2_codec *dac = &hal2->dac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) return snd_pcm_indirect_playback_transfer(substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) &dac->pcm_indirect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) hal2_playback_transfer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) static int hal2_capture_open(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) runtime->hw = hal2_pcm_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) return hal2_alloc_dmabuf(hal2, &hal2->adc, DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) static int hal2_capture_close(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) hal2_free_dmabuf(hal2, &hal2->adc, DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) static int hal2_capture_prepare(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) struct hal2_codec *adc = &hal2->adc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) adc->voices = runtime->channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) adc->sample_rate = hal2_compute_rate(adc, runtime->rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) memset(&adc->pcm_indirect, 0, sizeof(adc->pcm_indirect));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) adc->pcm_indirect.hw_buffer_size = H2_BUF_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) adc->pcm_indirect.hw_queue_size = H2_BUF_SIZE / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) adc->pcm_indirect.hw_io = adc->buffer_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) adc->pcm_indirect.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) adc->substream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) hal2_setup_adc(hal2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) return 0;
^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) static int hal2_capture_trigger(struct snd_pcm_substream *substream, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) hal2_start_adc(hal2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) hal2_stop_adc(hal2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) static snd_pcm_uframes_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) hal2_capture_pointer(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) struct hal2_codec *adc = &hal2->adc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) return snd_pcm_indirect_capture_pointer(substream, &adc->pcm_indirect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) adc->pbus.pbus->pbdma_bptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) static void hal2_capture_transfer(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) struct snd_pcm_indirect *rec, size_t bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) unsigned char *buf = hal2->adc.buffer + rec->hw_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) dma_sync_single_for_cpu(hal2->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) hal2->adc.buffer_dma + rec->hw_data, bytes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) memcpy(substream->runtime->dma_area + rec->sw_data, buf, bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) static int hal2_capture_ack(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) struct snd_hal2 *hal2 = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) struct hal2_codec *adc = &hal2->adc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) return snd_pcm_indirect_capture_transfer(substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) &adc->pcm_indirect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) hal2_capture_transfer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) static const struct snd_pcm_ops hal2_playback_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) .open = hal2_playback_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) .close = hal2_playback_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) .prepare = hal2_playback_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) .trigger = hal2_playback_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) .pointer = hal2_playback_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) .ack = hal2_playback_ack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) static const struct snd_pcm_ops hal2_capture_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) .open = hal2_capture_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) .close = hal2_capture_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) .prepare = hal2_capture_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) .trigger = hal2_capture_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) .pointer = hal2_capture_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) .ack = hal2_capture_ack,
^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 hal2_pcm_create(struct snd_hal2 *hal2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) struct snd_pcm *pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) /* create first pcm device with one outputs and one input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) err = snd_pcm_new(hal2->card, "SGI HAL2 Audio", 0, 1, 1, &pcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) pcm->private_data = hal2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) strcpy(pcm->name, "SGI HAL2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) /* set operators */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) &hal2_playback_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) &hal2_capture_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) NULL, 0, 1024 * 1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^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 hal2_dev_free(struct snd_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) struct snd_hal2 *hal2 = device->device_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) free_irq(SGI_HPCDMA_IRQ, hal2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) kfree(hal2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) static const struct snd_device_ops hal2_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) .dev_free = hal2_dev_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) static void hal2_init_codec(struct hal2_codec *codec, struct hpc3_regs *hpc3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) codec->pbus.pbusnr = index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) codec->pbus.pbus = &hpc3->pbdma[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) static int hal2_detect(struct snd_hal2 *hal2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) unsigned short board, major, minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) unsigned short rev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) /* reset HAL2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) hal2_write(0, &hal2->ctl_regs->isr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) /* release reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) hal2_write(H2_ISR_GLOBAL_RESET_N | H2_ISR_CODEC_RESET_N,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) &hal2->ctl_regs->isr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) hal2_i_write16(hal2, H2I_RELAY_C, H2I_RELAY_C_STATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) rev = hal2_read(&hal2->ctl_regs->rev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) if (rev & H2_REV_AUDIO_PRESENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) board = (rev & H2_REV_BOARD_M) >> 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) major = (rev & H2_REV_MAJOR_CHIP_M) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) minor = (rev & H2_REV_MINOR_CHIP_M);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) printk(KERN_INFO "SGI HAL2 revision %i.%i.%i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) board, major, minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) static int hal2_create(struct snd_card *card, struct snd_hal2 **rchip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) struct snd_hal2 *hal2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) struct hpc3_regs *hpc3 = hpc3c0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) hal2 = kzalloc(sizeof(*hal2), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) if (!hal2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) hal2->card = card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) if (request_irq(SGI_HPCDMA_IRQ, hal2_interrupt, IRQF_SHARED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) "SGI HAL2", hal2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) printk(KERN_ERR "HAL2: Can't get irq %d\n", SGI_HPCDMA_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) kfree(hal2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) hal2->ctl_regs = (struct hal2_ctl_regs *)hpc3->pbus_extregs[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) hal2->aes_regs = (struct hal2_aes_regs *)hpc3->pbus_extregs[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) hal2->vol_regs = (struct hal2_vol_regs *)hpc3->pbus_extregs[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) hal2->syn_regs = (struct hal2_syn_regs *)hpc3->pbus_extregs[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) if (hal2_detect(hal2) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) kfree(hal2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) hal2_init_codec(&hal2->dac, hpc3, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) hal2_init_codec(&hal2->adc, hpc3, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) * All DMA channel interfaces in HAL2 are designed to operate with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) * PBUS programmed for 2 cycles in D3, 2 cycles in D4 and 2 cycles
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) * in D5. HAL2 is a 16-bit device which can accept both big and little
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) * endian format. It assumes that even address bytes are on high
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) * portion of PBUS (15:8) and assumes that HPC3 is programmed to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) * accept a live (unsynchronized) version of P_DREQ_N from HAL2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) #define HAL2_PBUS_DMACFG ((0 << HPC3_DMACFG_D3R_SHIFT) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) (2 << HPC3_DMACFG_D4R_SHIFT) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) (2 << HPC3_DMACFG_D5R_SHIFT) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) (0 << HPC3_DMACFG_D3W_SHIFT) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) (2 << HPC3_DMACFG_D4W_SHIFT) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) (2 << HPC3_DMACFG_D5W_SHIFT) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) HPC3_DMACFG_DS16 | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) HPC3_DMACFG_EVENHI | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) HPC3_DMACFG_RTIME | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) (8 << HPC3_DMACFG_BURST_SHIFT) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) HPC3_DMACFG_DRQLIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) * Ignore what's mentioned in the specification and write value which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) * works in The Real World (TM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) hpc3->pbus_dmacfg[hal2->dac.pbus.pbusnr][0] = 0x8208844;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) hpc3->pbus_dmacfg[hal2->adc.pbus.pbusnr][0] = 0x8208844;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, hal2, &hal2_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) free_irq(SGI_HPCDMA_IRQ, hal2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) kfree(hal2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) *rchip = hal2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) static int hal2_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) struct snd_hal2 *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) err = snd_card_new(&pdev->dev, index, id, THIS_MODULE, 0, &card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) err = hal2_create(card, &chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) err = hal2_pcm_create(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) err = hal2_mixer_create(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) strcpy(card->driver, "SGI HAL2 Audio");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) strcpy(card->shortname, "SGI HAL2 Audio");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) sprintf(card->longname, "%s irq %i",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) card->shortname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) SGI_HPCDMA_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) err = snd_card_register(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) platform_set_drvdata(pdev, card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) static int hal2_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) struct snd_card *card = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) static struct platform_driver hal2_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) .probe = hal2_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) .remove = hal2_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) .name = "sgihal2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) module_platform_driver(hal2_driver);