^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) * PMac DBDMA lowlevel functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) by Takashi Iwai <tiwai@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * code based on dmasound.c.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "pmac.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <sound/pcm_params.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <asm/pmac_feature.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /* fixed frequency table for awacs, screamer, burgundy, DACA (44100 max) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static const int awacs_freqs[8] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) 44100, 29400, 22050, 17640, 14700, 11025, 8820, 7350
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /* fixed frequency table for tumbler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static const int tumbler_freqs[1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) 44100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * we will allocate a single 'emergency' dbdma cmd block to use if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * tx status comes up "DEAD". This happens on some PowerComputing Pmac
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * clones, either owing to a bug in dbdma or some interaction between
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * IDE and sound. However, this measure would deal with DEAD status if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * it appeared elsewhere.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static struct pmac_dbdma emergency_dbdma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static int emergency_in_use;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * allocate DBDMA command arrays
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static int snd_pmac_dbdma_alloc(struct snd_pmac *chip, struct pmac_dbdma *rec, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) unsigned int rsize = sizeof(struct dbdma_cmd) * (size + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) rec->space = dma_alloc_coherent(&chip->pdev->dev, rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) &rec->dma_base, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) if (rec->space == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) rec->size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) memset(rec->space, 0, rsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) rec->cmds = (void __iomem *)DBDMA_ALIGN(rec->space);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) rec->addr = rec->dma_base + (unsigned long)((char *)rec->cmds - (char *)rec->space);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static void snd_pmac_dbdma_free(struct snd_pmac *chip, struct pmac_dbdma *rec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if (rec->space) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) unsigned int rsize = sizeof(struct dbdma_cmd) * (rec->size + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) dma_free_coherent(&chip->pdev->dev, rsize, rec->space, rec->dma_base);
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * pcm stuff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * look up frequency table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) unsigned int snd_pmac_rate_index(struct snd_pmac *chip, struct pmac_stream *rec, unsigned int rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) int i, ok, found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) ok = rec->cur_freqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (rate > chip->freq_table[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) for (i = 0; i < chip->num_freqs; i++, ok >>= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (! (ok & 1)) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) found = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (rate >= chip->freq_table[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^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) * check whether another stream is active
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static inline int another_stream(int stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return (stream == SNDRV_PCM_STREAM_PLAYBACK) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * get a stream of the opposite direction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static struct pmac_stream *snd_pmac_get_stream(struct snd_pmac *chip, int stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) switch (stream) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) case SNDRV_PCM_STREAM_PLAYBACK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return &chip->playback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) case SNDRV_PCM_STREAM_CAPTURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) return &chip->capture;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) snd_BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * wait while run status is on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) snd_pmac_wait_ack(struct pmac_stream *rec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) int timeout = 50000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) while ((in_le32(&rec->dma->status) & RUN) && timeout-- > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * set the format and rate to the chip.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * call the lowlevel function if defined (e.g. for AWACS).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static void snd_pmac_pcm_set_format(struct snd_pmac *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /* set up frequency and format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) out_le32(&chip->awacs->control, chip->control_mask | (chip->rate_index << 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) out_le32(&chip->awacs->byteswap, chip->format == SNDRV_PCM_FORMAT_S16_LE ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (chip->set_format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) chip->set_format(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * stop the DMA transfer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) static inline void snd_pmac_dma_stop(struct pmac_stream *rec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) out_le32(&rec->dma->control, (RUN|WAKE|FLUSH|PAUSE) << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) snd_pmac_wait_ack(rec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * set the command pointer address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static inline void snd_pmac_dma_set_command(struct pmac_stream *rec, struct pmac_dbdma *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) out_le32(&rec->dma->cmdptr, cmd->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * start the DMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static inline void snd_pmac_dma_run(struct pmac_stream *rec, int status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) out_le32(&rec->dma->control, status | (status << 16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * prepare playback/capture stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static int snd_pmac_pcm_prepare(struct snd_pmac *chip, struct pmac_stream *rec, struct snd_pcm_substream *subs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) volatile struct dbdma_cmd __iomem *cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct snd_pcm_runtime *runtime = subs->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) int rate_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) long offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) struct pmac_stream *astr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) rec->dma_size = snd_pcm_lib_buffer_bytes(subs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) rec->period_size = snd_pcm_lib_period_bytes(subs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) rec->nperiods = rec->dma_size / rec->period_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) rec->cur_period = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) rate_index = snd_pmac_rate_index(chip, rec, runtime->rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /* set up constraints */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) astr = snd_pmac_get_stream(chip, another_stream(rec->stream));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (! astr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) astr->cur_freqs = 1 << rate_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) astr->cur_formats = 1 << runtime->format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) chip->rate_index = rate_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) chip->format = runtime->format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) /* We really want to execute a DMA stop command, after the AWACS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * is initialized.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * For reasons I don't understand, it stops the hissing noise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * common to many PowerBook G3 systems and random noise otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * captured on iBook2's about every third time. -ReneR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) spin_lock_irq(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) snd_pmac_dma_stop(rec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) chip->extra_dma.cmds->command = cpu_to_le16(DBDMA_STOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) snd_pmac_dma_set_command(rec, &chip->extra_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) snd_pmac_dma_run(rec, RUN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) spin_unlock_irq(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) mdelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) spin_lock_irq(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /* continuous DMA memory type doesn't provide the physical address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * so we need to resolve the address here...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) offset = runtime->dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) for (i = 0, cp = rec->cmd.cmds; i < rec->nperiods; i++, cp++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) cp->phy_addr = cpu_to_le32(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) cp->req_count = cpu_to_le16(rec->period_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /*cp->res_count = cpu_to_le16(0);*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) cp->xfer_status = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) offset += rec->period_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) /* make loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) cp->command = cpu_to_le16(DBDMA_NOP | BR_ALWAYS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) cp->cmd_dep = cpu_to_le32(rec->cmd.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) snd_pmac_dma_stop(rec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) snd_pmac_dma_set_command(rec, &rec->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) spin_unlock_irq(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^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) * PCM trigger/stop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static int snd_pmac_pcm_trigger(struct snd_pmac *chip, struct pmac_stream *rec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) struct snd_pcm_substream *subs, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) volatile struct dbdma_cmd __iomem *cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) int i, command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) case SNDRV_PCM_TRIGGER_RESUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (rec->running)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) command = (subs->stream == SNDRV_PCM_STREAM_PLAYBACK ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) OUTPUT_MORE : INPUT_MORE) + INTR_ALWAYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) spin_lock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) snd_pmac_beep_stop(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) snd_pmac_pcm_set_format(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) for (i = 0, cp = rec->cmd.cmds; i < rec->nperiods; i++, cp++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) out_le16(&cp->command, command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) snd_pmac_dma_set_command(rec, &rec->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) (void)in_le32(&rec->dma->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) snd_pmac_dma_run(rec, RUN|WAKE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) rec->running = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) spin_unlock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) case SNDRV_PCM_TRIGGER_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) spin_lock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) rec->running = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) /*printk(KERN_DEBUG "stopped!!\n");*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) snd_pmac_dma_stop(rec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) for (i = 0, cp = rec->cmd.cmds; i < rec->nperiods; i++, cp++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) out_le16(&cp->command, DBDMA_STOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) spin_unlock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) * return the current pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) static snd_pcm_uframes_t snd_pmac_pcm_pointer(struct snd_pmac *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) struct pmac_stream *rec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) struct snd_pcm_substream *subs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) #if 1 /* hmm.. how can we get the current dma pointer?? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) int stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) volatile struct dbdma_cmd __iomem *cp = &rec->cmd.cmds[rec->cur_period];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) stat = le16_to_cpu(cp->xfer_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (stat & (ACTIVE|DEAD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) count = in_le16(&cp->res_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) count = rec->period_size - count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) count += rec->cur_period * rec->period_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /*printk(KERN_DEBUG "pointer=%d\n", count);*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return bytes_to_frames(subs->runtime, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * playback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) static int snd_pmac_playback_prepare(struct snd_pcm_substream *subs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) struct snd_pmac *chip = snd_pcm_substream_chip(subs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return snd_pmac_pcm_prepare(chip, &chip->playback, subs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) static int snd_pmac_playback_trigger(struct snd_pcm_substream *subs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) struct snd_pmac *chip = snd_pcm_substream_chip(subs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) return snd_pmac_pcm_trigger(chip, &chip->playback, subs, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) static snd_pcm_uframes_t snd_pmac_playback_pointer(struct snd_pcm_substream *subs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) struct snd_pmac *chip = snd_pcm_substream_chip(subs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) return snd_pmac_pcm_pointer(chip, &chip->playback, subs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) * capture
^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 int snd_pmac_capture_prepare(struct snd_pcm_substream *subs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) struct snd_pmac *chip = snd_pcm_substream_chip(subs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) return snd_pmac_pcm_prepare(chip, &chip->capture, subs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) static int snd_pmac_capture_trigger(struct snd_pcm_substream *subs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) struct snd_pmac *chip = snd_pcm_substream_chip(subs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) return snd_pmac_pcm_trigger(chip, &chip->capture, subs, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) static snd_pcm_uframes_t snd_pmac_capture_pointer(struct snd_pcm_substream *subs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) struct snd_pmac *chip = snd_pcm_substream_chip(subs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) return snd_pmac_pcm_pointer(chip, &chip->capture, subs);
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) * Handle DEAD DMA transfers:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * if the TX status comes up "DEAD" - reported on some Power Computing machines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) * we need to re-start the dbdma - but from a different physical start address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) * and with a different transfer length. It would get very messy to do this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) * with the normal dbdma_cmd blocks - we would have to re-write the buffer start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * addresses each time. So, we will keep a single dbdma_cmd block which can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * fiddled with.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) * When DEAD status is first reported the content of the faulted dbdma block is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * copied into the emergency buffer and we note that the buffer is in use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) * we then bump the start physical address by the amount that was successfully
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) * output before it died.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) * On any subsequent DEAD result we just do the bump-ups (we know that we are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) * already using the emergency dbdma_cmd).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) * CHECK: this just tries to "do it". It is possible that we should abandon
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) * xfers when the number of residual bytes gets below a certain value - I can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) * see that this might cause a loop-forever if a too small transfer causes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) * DEAD status. However this is a TODO for now - we'll see what gets reported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) * When we get a successful transfer result with the emergency buffer we just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * pretend that it completed using the original dmdma_cmd and carry on. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) * 'next_cmd' field will already point back to the original loop of blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) static inline void snd_pmac_pcm_dead_xfer(struct pmac_stream *rec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) volatile struct dbdma_cmd __iomem *cp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) unsigned short req, res ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) unsigned int phy ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) /* printk(KERN_WARNING "snd-powermac: DMA died - patching it up!\n"); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) /* to clear DEAD status we must first clear RUN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) set it to quiescent to be on the safe side */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) (void)in_le32(&rec->dma->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) out_le32(&rec->dma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) if (!emergency_in_use) { /* new problem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) memcpy((void *)emergency_dbdma.cmds, (void *)cp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) sizeof(struct dbdma_cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) emergency_in_use = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) cp->xfer_status = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) cp->req_count = cpu_to_le16(rec->period_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) cp = emergency_dbdma.cmds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) /* now bump the values to reflect the amount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) we haven't yet shifted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) req = le16_to_cpu(cp->req_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) res = le16_to_cpu(cp->res_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) phy = le32_to_cpu(cp->phy_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) phy += (req - res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) cp->req_count = cpu_to_le16(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) cp->res_count = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) cp->xfer_status = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) cp->phy_addr = cpu_to_le32(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) cp->cmd_dep = cpu_to_le32(rec->cmd.addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) + sizeof(struct dbdma_cmd)*((rec->cur_period+1)%rec->nperiods));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) cp->command = cpu_to_le16(OUTPUT_MORE | BR_ALWAYS | INTR_ALWAYS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) /* point at our patched up command block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) out_le32(&rec->dma->cmdptr, emergency_dbdma.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) /* we must re-start the controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) (void)in_le32(&rec->dma->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) /* should complete clearing the DEAD status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) out_le32(&rec->dma->control, ((RUN|WAKE) << 16) + (RUN|WAKE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) * update playback/capture pointer from interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) static void snd_pmac_pcm_update(struct snd_pmac *chip, struct pmac_stream *rec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) volatile struct dbdma_cmd __iomem *cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) int c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) int stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) spin_lock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (rec->running) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) for (c = 0; c < rec->nperiods; c++) { /* at most all fragments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) if (emergency_in_use) /* already using DEAD xfer? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) cp = emergency_dbdma.cmds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) cp = &rec->cmd.cmds[rec->cur_period];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) stat = le16_to_cpu(cp->xfer_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (stat & DEAD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) snd_pmac_pcm_dead_xfer(rec, cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) break; /* this block is still going */
^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) if (emergency_in_use)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) emergency_in_use = 0 ; /* done that */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) if (! (stat & ACTIVE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) /*printk(KERN_DEBUG "update frag %d\n", rec->cur_period);*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) cp->xfer_status = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) cp->req_count = cpu_to_le16(rec->period_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) /*cp->res_count = cpu_to_le16(0);*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) rec->cur_period++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) if (rec->cur_period >= rec->nperiods) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) rec->cur_period = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) spin_unlock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) snd_pcm_period_elapsed(rec->substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) spin_lock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) spin_unlock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) * hw info
^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 const struct snd_pcm_hardware snd_pmac_playback =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) .info = (SNDRV_PCM_INFO_INTERLEAVED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) SNDRV_PCM_INFO_MMAP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) SNDRV_PCM_INFO_MMAP_VALID |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) SNDRV_PCM_INFO_RESUME),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) .formats = SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_S16_LE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) .rates = SNDRV_PCM_RATE_8000_44100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) .rate_min = 7350,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) .rate_max = 44100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) .channels_min = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) .buffer_bytes_max = 131072,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) .period_bytes_min = 256,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) .period_bytes_max = 16384,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) .periods_min = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) .periods_max = PMAC_MAX_FRAGS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) static const struct snd_pcm_hardware snd_pmac_capture =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) .info = (SNDRV_PCM_INFO_INTERLEAVED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) SNDRV_PCM_INFO_MMAP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) SNDRV_PCM_INFO_MMAP_VALID |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) SNDRV_PCM_INFO_RESUME),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) .formats = SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_S16_LE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) .rates = SNDRV_PCM_RATE_8000_44100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) .rate_min = 7350,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) .rate_max = 44100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) .channels_min = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) .buffer_bytes_max = 131072,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) .period_bytes_min = 256,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) .period_bytes_max = 16384,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) .periods_min = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) .periods_max = PMAC_MAX_FRAGS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) };
^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) #if 0 // NYI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) static int snd_pmac_hw_rule_rate(struct snd_pcm_hw_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) struct snd_pcm_hw_rule *rule)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) struct snd_pmac *chip = rule->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) struct pmac_stream *rec = snd_pmac_get_stream(chip, rule->deps[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) int i, freq_table[8], num_freqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if (! rec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) num_freqs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) for (i = chip->num_freqs - 1; i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) if (rec->cur_freqs & (1 << i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) freq_table[num_freqs++] = chip->freq_table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) return snd_interval_list(hw_param_interval(params, rule->var),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) num_freqs, freq_table, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) static int snd_pmac_hw_rule_format(struct snd_pcm_hw_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) struct snd_pcm_hw_rule *rule)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) struct snd_pmac *chip = rule->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) struct pmac_stream *rec = snd_pmac_get_stream(chip, rule->deps[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) if (! rec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) return snd_mask_refine_set(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) rec->cur_formats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) #endif // NYI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) static int snd_pmac_pcm_open(struct snd_pmac *chip, struct pmac_stream *rec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) struct snd_pcm_substream *subs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) struct snd_pcm_runtime *runtime = subs->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) /* look up frequency table and fill bit mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) runtime->hw.rates = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) for (i = 0; i < chip->num_freqs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) if (chip->freqs_ok & (1 << i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) runtime->hw.rates |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) snd_pcm_rate_to_rate_bit(chip->freq_table[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) /* check for minimum and maximum rates */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) for (i = 0; i < chip->num_freqs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (chip->freqs_ok & (1 << i)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) runtime->hw.rate_max = chip->freq_table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) break;
^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) for (i = chip->num_freqs - 1; i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) if (chip->freqs_ok & (1 << i)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) runtime->hw.rate_min = chip->freq_table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) runtime->hw.formats = chip->formats_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if (chip->can_capture) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if (! chip->can_duplex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) runtime->hw.info |= SNDRV_PCM_INFO_HALF_DUPLEX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) runtime->hw.info |= SNDRV_PCM_INFO_JOINT_DUPLEX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) runtime->private_data = rec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) rec->substream = subs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) #if 0 /* FIXME: still under development.. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) snd_pmac_hw_rule_rate, chip, rec->stream, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) snd_pmac_hw_rule_format, chip, rec->stream, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) runtime->hw.periods_max = rec->cmd.size - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) /* constraints to fix choppy sound */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) static int snd_pmac_pcm_close(struct snd_pmac *chip, struct pmac_stream *rec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) struct snd_pcm_substream *subs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) struct pmac_stream *astr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) snd_pmac_dma_stop(rec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) astr = snd_pmac_get_stream(chip, another_stream(rec->stream));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) if (! astr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) /* reset constraints */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) astr->cur_freqs = chip->freqs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) astr->cur_formats = chip->formats_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) static int snd_pmac_playback_open(struct snd_pcm_substream *subs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) struct snd_pmac *chip = snd_pcm_substream_chip(subs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) subs->runtime->hw = snd_pmac_playback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) return snd_pmac_pcm_open(chip, &chip->playback, subs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) static int snd_pmac_capture_open(struct snd_pcm_substream *subs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) struct snd_pmac *chip = snd_pcm_substream_chip(subs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) subs->runtime->hw = snd_pmac_capture;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) return snd_pmac_pcm_open(chip, &chip->capture, subs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) static int snd_pmac_playback_close(struct snd_pcm_substream *subs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) struct snd_pmac *chip = snd_pcm_substream_chip(subs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) return snd_pmac_pcm_close(chip, &chip->playback, subs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) static int snd_pmac_capture_close(struct snd_pcm_substream *subs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) struct snd_pmac *chip = snd_pcm_substream_chip(subs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) return snd_pmac_pcm_close(chip, &chip->capture, subs);
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) static const struct snd_pcm_ops snd_pmac_playback_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) .open = snd_pmac_playback_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) .close = snd_pmac_playback_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) .prepare = snd_pmac_playback_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) .trigger = snd_pmac_playback_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) .pointer = snd_pmac_playback_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) static const struct snd_pcm_ops snd_pmac_capture_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) .open = snd_pmac_capture_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) .close = snd_pmac_capture_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) .prepare = snd_pmac_capture_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) .trigger = snd_pmac_capture_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) .pointer = snd_pmac_capture_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) int snd_pmac_pcm_new(struct snd_pmac *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) struct snd_pcm *pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) int num_captures = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) if (! chip->can_capture)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) num_captures = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) err = snd_pcm_new(chip->card, chip->card->driver, 0, 1, num_captures, &pcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_pmac_playback_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) if (chip->can_capture)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_pmac_capture_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) pcm->private_data = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) strcpy(pcm->name, chip->card->shortname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) chip->pcm = pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) chip->formats_ok = SNDRV_PCM_FMTBIT_S16_BE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) if (chip->can_byte_swap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) chip->formats_ok |= SNDRV_PCM_FMTBIT_S16_LE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) chip->playback.cur_formats = chip->formats_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) chip->capture.cur_formats = chip->formats_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) chip->playback.cur_freqs = chip->freqs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) chip->capture.cur_freqs = chip->freqs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) /* preallocate 64k buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) &chip->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 64 * 1024, 64 * 1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) }
^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 void snd_pmac_dbdma_reset(struct snd_pmac *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) out_le32(&chip->playback.dma->control, (RUN|PAUSE|FLUSH|WAKE|DEAD) << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) snd_pmac_wait_ack(&chip->playback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) out_le32(&chip->capture.dma->control, (RUN|PAUSE|FLUSH|WAKE|DEAD) << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) snd_pmac_wait_ack(&chip->capture);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) * handling beep
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) void snd_pmac_beep_dma_start(struct snd_pmac *chip, int bytes, unsigned long addr, int speed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) struct pmac_stream *rec = &chip->playback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) snd_pmac_dma_stop(rec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) chip->extra_dma.cmds->req_count = cpu_to_le16(bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) chip->extra_dma.cmds->xfer_status = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) chip->extra_dma.cmds->cmd_dep = cpu_to_le32(chip->extra_dma.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) chip->extra_dma.cmds->phy_addr = cpu_to_le32(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) chip->extra_dma.cmds->command = cpu_to_le16(OUTPUT_MORE | BR_ALWAYS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) out_le32(&chip->awacs->control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) (in_le32(&chip->awacs->control) & ~0x1f00)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) | (speed << 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) out_le32(&chip->awacs->byteswap, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) snd_pmac_dma_set_command(rec, &chip->extra_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) snd_pmac_dma_run(rec, RUN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) void snd_pmac_beep_dma_stop(struct snd_pmac *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) snd_pmac_dma_stop(&chip->playback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) chip->extra_dma.cmds->command = cpu_to_le16(DBDMA_STOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) snd_pmac_pcm_set_format(chip); /* reset format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) * interrupt handlers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) static irqreturn_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) snd_pmac_tx_intr(int irq, void *devid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) struct snd_pmac *chip = devid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) snd_pmac_pcm_update(chip, &chip->playback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) static irqreturn_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) snd_pmac_rx_intr(int irq, void *devid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) struct snd_pmac *chip = devid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) snd_pmac_pcm_update(chip, &chip->capture);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) static irqreturn_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) snd_pmac_ctrl_intr(int irq, void *devid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) struct snd_pmac *chip = devid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) int ctrl = in_le32(&chip->awacs->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) /*printk(KERN_DEBUG "pmac: control interrupt.. 0x%x\n", ctrl);*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if (ctrl & MASK_PORTCHG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) /* do something when headphone is plugged/unplugged? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) if (chip->update_automute)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) chip->update_automute(chip, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) if (ctrl & MASK_CNTLERR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) int err = (in_le32(&chip->awacs->codec_stat) & MASK_ERRCODE) >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) if (err && chip->model <= PMAC_SCREAMER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) snd_printk(KERN_DEBUG "error %x\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) /* Writing 1s to the CNTLERR and PORTCHG bits clears them... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) out_le32(&chip->awacs->control, ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) return IRQ_HANDLED;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) * a wrapper to feature call for compatibility
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) static void snd_pmac_sound_feature(struct snd_pmac *chip, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) if (ppc_md.feature_call)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) ppc_md.feature_call(PMAC_FTR_SOUND_CHIP_ENABLE, chip->node, 0, enable);
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) * release resources
^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) static int snd_pmac_free(struct snd_pmac *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) /* stop sounds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if (chip->initialized) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) snd_pmac_dbdma_reset(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) /* disable interrupts from awacs interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) out_le32(&chip->awacs->control, in_le32(&chip->awacs->control) & 0xfff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) if (chip->node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) snd_pmac_sound_feature(chip, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) /* clean up mixer if any */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) if (chip->mixer_free)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) chip->mixer_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) snd_pmac_detach_beep(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) /* release resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if (chip->irq >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) free_irq(chip->irq, (void*)chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) if (chip->tx_irq >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) free_irq(chip->tx_irq, (void*)chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) if (chip->rx_irq >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) free_irq(chip->rx_irq, (void*)chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) snd_pmac_dbdma_free(chip, &chip->playback.cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) snd_pmac_dbdma_free(chip, &chip->capture.cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) snd_pmac_dbdma_free(chip, &chip->extra_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) snd_pmac_dbdma_free(chip, &emergency_dbdma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) iounmap(chip->macio_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) iounmap(chip->latch_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) iounmap(chip->awacs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) iounmap(chip->playback.dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) iounmap(chip->capture.dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) if (chip->node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) for (i = 0; i < 3; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) if (chip->requested & (1 << i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) release_mem_region(chip->rsrc[i].start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) resource_size(&chip->rsrc[i]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) pci_dev_put(chip->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) of_node_put(chip->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) kfree(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) }
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) * free the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) static int snd_pmac_dev_free(struct snd_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) struct snd_pmac *chip = device->device_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) return snd_pmac_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^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) * check the machine support byteswap (little-endian)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) static void detect_byte_swap(struct snd_pmac *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) struct device_node *mio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) /* if seems that Keylargo can't byte-swap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) for (mio = chip->node->parent; mio; mio = mio->parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) if (of_node_name_eq(mio, "mac-io")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) if (of_device_is_compatible(mio, "Keylargo"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) chip->can_byte_swap = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) break;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) /* it seems the Pismo & iBook can't byte-swap in hardware. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) if (of_machine_is_compatible("PowerBook3,1") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) of_machine_is_compatible("PowerBook2,1"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) chip->can_byte_swap = 0 ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) if (of_machine_is_compatible("PowerBook2,1"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) chip->can_duplex = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) * detect a sound chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) static int snd_pmac_detect(struct snd_pmac *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) struct device_node *sound;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) struct device_node *dn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) const unsigned int *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) unsigned int l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) struct macio_chip* macio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) if (!machine_is(powermac))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) chip->subframe = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) chip->revision = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) chip->freqs_ok = 0xff; /* all ok */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) chip->model = PMAC_AWACS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) chip->can_byte_swap = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) chip->can_duplex = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) chip->can_capture = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) chip->num_freqs = ARRAY_SIZE(awacs_freqs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) chip->freq_table = awacs_freqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) chip->pdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) chip->control_mask = MASK_IEPC | MASK_IEE | 0x11; /* default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) /* check machine type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) if (of_machine_is_compatible("AAPL,3400/2400")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) || of_machine_is_compatible("AAPL,3500"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) chip->is_pbook_3400 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) else if (of_machine_is_compatible("PowerBook1,1")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) || of_machine_is_compatible("AAPL,PowerBook1998"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) chip->is_pbook_G3 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) chip->node = of_find_node_by_name(NULL, "awacs");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) sound = of_node_get(chip->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) * powermac G3 models have a node called "davbus"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) * with a child called "sound".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) if (!chip->node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) chip->node = of_find_node_by_name(NULL, "davbus");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) * if we didn't find a davbus device, try 'i2s-a' since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) * this seems to be what iBooks have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) if (! chip->node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) chip->node = of_find_node_by_name(NULL, "i2s-a");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) if (chip->node && chip->node->parent &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) chip->node->parent->parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) if (of_device_is_compatible(chip->node->parent->parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) "K2-Keylargo"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) chip->is_k2 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) if (! chip->node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) if (!sound) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) for_each_node_by_name(sound, "sound")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) if (sound->parent == chip->node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) if (! sound) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) of_node_put(chip->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) chip->node = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) prop = of_get_property(sound, "sub-frame", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) if (prop && *prop < 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) chip->subframe = *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) prop = of_get_property(sound, "layout-id", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) if (prop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) /* partly deprecate snd-powermac, for those machines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) * that have a layout-id property for now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) printk(KERN_INFO "snd-powermac no longer handles any "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) "machines with a layout-id property "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) "in the device-tree, use snd-aoa.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) of_node_put(sound);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) of_node_put(chip->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) chip->node = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) /* This should be verified on older screamers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) if (of_device_is_compatible(sound, "screamer")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) chip->model = PMAC_SCREAMER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) // chip->can_byte_swap = 0; /* FIXME: check this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) if (of_device_is_compatible(sound, "burgundy")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) chip->model = PMAC_BURGUNDY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) if (of_device_is_compatible(sound, "daca")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) chip->model = PMAC_DACA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) chip->can_capture = 0; /* no capture */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) chip->can_duplex = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) // chip->can_byte_swap = 0; /* FIXME: check this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) if (of_device_is_compatible(sound, "tumbler")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) chip->model = PMAC_TUMBLER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) chip->can_capture = of_machine_is_compatible("PowerMac4,2")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) || of_machine_is_compatible("PowerBook3,2")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) || of_machine_is_compatible("PowerBook3,3")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) || of_machine_is_compatible("PowerBook4,1")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) || of_machine_is_compatible("PowerBook4,2")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) || of_machine_is_compatible("PowerBook4,3");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) chip->can_duplex = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) // chip->can_byte_swap = 0; /* FIXME: check this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) chip->num_freqs = ARRAY_SIZE(tumbler_freqs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) chip->freq_table = tumbler_freqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) if (of_device_is_compatible(sound, "snapper")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) chip->model = PMAC_SNAPPER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) // chip->can_byte_swap = 0; /* FIXME: check this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) chip->num_freqs = ARRAY_SIZE(tumbler_freqs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) chip->freq_table = tumbler_freqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) prop = of_get_property(sound, "device-id", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) if (prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) chip->device_id = *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) dn = of_find_node_by_name(NULL, "perch");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) chip->has_iic = (dn != NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) of_node_put(dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) /* We need the PCI device for DMA allocations, let's use a crude method
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) * for now ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) macio = macio_find(chip->node, macio_unknown);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) if (macio == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) printk(KERN_WARNING "snd-powermac: can't locate macio !\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) struct pci_dev *pdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) for_each_pci_dev(pdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) struct device_node *np = pci_device_to_OF_node(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) if (np && np == macio->of_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) chip->pdev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) if (chip->pdev == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) printk(KERN_WARNING "snd-powermac: can't locate macio PCI"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) " device !\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) detect_byte_swap(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) /* look for a property saying what sample rates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) are available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) prop = of_get_property(sound, "sample-rates", &l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) if (! prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) prop = of_get_property(sound, "output-frame-rates", &l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) if (prop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) chip->freqs_ok = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) for (l /= sizeof(int); l > 0; --l) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) unsigned int r = *prop++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) /* Apple 'Fixed' format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) if (r >= 0x10000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) r >>= 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) for (i = 0; i < chip->num_freqs; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) if (r == chip->freq_table[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) chip->freqs_ok |= (1 << i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) /* assume only 44.1khz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) chip->freqs_ok = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) of_node_put(sound);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) #ifdef PMAC_SUPPORT_AUTOMUTE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) * auto-mute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) static int pmac_auto_mute_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) ucontrol->value.integer.value[0] = chip->auto_mute;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) static int pmac_auto_mute_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) if (ucontrol->value.integer.value[0] != chip->auto_mute) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) chip->auto_mute = !!ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) if (chip->update_automute)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) chip->update_automute(chip, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) static int pmac_hp_detect_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) if (chip->detect_headphone)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) ucontrol->value.integer.value[0] = chip->detect_headphone(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) ucontrol->value.integer.value[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) static const struct snd_kcontrol_new auto_mute_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) .name = "Auto Mute Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) .info = snd_pmac_boolean_mono_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) .get = pmac_auto_mute_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) .put = pmac_auto_mute_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) .name = "Headphone Detection",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) .access = SNDRV_CTL_ELEM_ACCESS_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) .info = snd_pmac_boolean_mono_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) .get = pmac_hp_detect_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) int snd_pmac_add_automute(struct snd_pmac *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) chip->auto_mute = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) err = snd_ctl_add(chip->card, snd_ctl_new1(&auto_mute_controls[0], chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) printk(KERN_ERR "snd-powermac: Failed to add automute control\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) chip->hp_detect_ctl = snd_ctl_new1(&auto_mute_controls[1], chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) return snd_ctl_add(chip->card, chip->hp_detect_ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) #endif /* PMAC_SUPPORT_AUTOMUTE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) * create and detect a pmac chip record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) int snd_pmac_new(struct snd_card *card, struct snd_pmac **chip_return)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) struct snd_pmac *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) unsigned int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) unsigned long ctrl_addr, txdma_addr, rxdma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) static const struct snd_device_ops ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) .dev_free = snd_pmac_dev_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) *chip_return = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) chip = kzalloc(sizeof(*chip), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) if (chip == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) chip->card = card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) spin_lock_init(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) chip->irq = chip->tx_irq = chip->rx_irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) chip->playback.stream = SNDRV_PCM_STREAM_PLAYBACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) chip->capture.stream = SNDRV_PCM_STREAM_CAPTURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) if ((err = snd_pmac_detect(chip)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) goto __error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) if (snd_pmac_dbdma_alloc(chip, &chip->playback.cmd, PMAC_MAX_FRAGS + 1) < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) snd_pmac_dbdma_alloc(chip, &chip->capture.cmd, PMAC_MAX_FRAGS + 1) < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) snd_pmac_dbdma_alloc(chip, &chip->extra_dma, 2) < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) snd_pmac_dbdma_alloc(chip, &emergency_dbdma, 2) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) goto __error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) np = chip->node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) chip->requested = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) if (chip->is_k2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) static const char * const rnames[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) "Sound Control", "Sound DMA" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) for (i = 0; i < 2; i ++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) if (of_address_to_resource(np->parent, i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) &chip->rsrc[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) printk(KERN_ERR "snd: can't translate rsrc "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) " %d (%s)\n", i, rnames[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) goto __error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) if (request_mem_region(chip->rsrc[i].start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) resource_size(&chip->rsrc[i]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) rnames[i]) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) printk(KERN_ERR "snd: can't request rsrc "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) " %d (%s: %pR)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) i, rnames[i], &chip->rsrc[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) goto __error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) chip->requested |= (1 << i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) ctrl_addr = chip->rsrc[0].start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) txdma_addr = chip->rsrc[1].start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) rxdma_addr = txdma_addr + 0x100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) static const char * const rnames[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) "Sound Control", "Sound Tx DMA", "Sound Rx DMA" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) for (i = 0; i < 3; i ++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) if (of_address_to_resource(np, i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) &chip->rsrc[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) printk(KERN_ERR "snd: can't translate rsrc "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) " %d (%s)\n", i, rnames[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) goto __error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) if (request_mem_region(chip->rsrc[i].start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) resource_size(&chip->rsrc[i]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) rnames[i]) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) printk(KERN_ERR "snd: can't request rsrc "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) " %d (%s: %pR)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) i, rnames[i], &chip->rsrc[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) goto __error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) chip->requested |= (1 << i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) ctrl_addr = chip->rsrc[0].start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) txdma_addr = chip->rsrc[1].start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) rxdma_addr = chip->rsrc[2].start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) chip->awacs = ioremap(ctrl_addr, 0x1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) chip->playback.dma = ioremap(txdma_addr, 0x100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) chip->capture.dma = ioremap(rxdma_addr, 0x100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) if (chip->model <= PMAC_BURGUNDY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) irq = irq_of_parse_and_map(np, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) if (request_irq(irq, snd_pmac_ctrl_intr, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) "PMac", (void*)chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) snd_printk(KERN_ERR "pmac: unable to grab IRQ %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) err = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) goto __error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) chip->irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) irq = irq_of_parse_and_map(np, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) if (request_irq(irq, snd_pmac_tx_intr, 0, "PMac Output", (void*)chip)){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) snd_printk(KERN_ERR "pmac: unable to grab IRQ %d\n", irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) err = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) goto __error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) chip->tx_irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) irq = irq_of_parse_and_map(np, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) if (request_irq(irq, snd_pmac_rx_intr, 0, "PMac Input", (void*)chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) snd_printk(KERN_ERR "pmac: unable to grab IRQ %d\n", irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) err = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) goto __error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) chip->rx_irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) snd_pmac_sound_feature(chip, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) /* reset & enable interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) if (chip->model <= PMAC_BURGUNDY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) out_le32(&chip->awacs->control, chip->control_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) /* Powerbooks have odd ways of enabling inputs such as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) an expansion-bay CD or sound from an internal modem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) or a PC-card modem. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) if (chip->is_pbook_3400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) /* Enable CD and PC-card sound inputs. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) /* This is done by reading from address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) * f301a000, + 0x10 to enable the expansion-bay
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) * CD sound input, + 0x80 to enable the PC-card
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) * sound input. The 0x100 enables the SCSI bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) * terminator power.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) chip->latch_base = ioremap (0xf301a000, 0x1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) in_8(chip->latch_base + 0x190);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) } else if (chip->is_pbook_G3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) struct device_node* mio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) for (mio = chip->node->parent; mio; mio = mio->parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) if (of_node_name_eq(mio, "mac-io")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) struct resource r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) if (of_address_to_resource(mio, 0, &r) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) chip->macio_base =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) ioremap(r.start, 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) /* Enable CD sound input. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) /* The relevant bits for writing to this byte are 0x8f.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) * I haven't found out what the 0x80 bit does.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) * For the 0xf bits, writing 3 or 7 enables the CD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) * input, any other value disables it. Values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) * 1, 3, 5, 7 enable the microphone. Values 0, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) * 4, 6, 8 - f enable the input from the modem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) if (chip->macio_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) out_8(chip->macio_base + 0x37, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) /* Reset dbdma channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) snd_pmac_dbdma_reset(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) goto __error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) *chip_return = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) __error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) snd_pmac_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) * sleep notify for powerbook
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) * Save state when going to sleep, restore it afterwards.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) void snd_pmac_suspend(struct snd_pmac *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) if (chip->suspend)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) chip->suspend(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) spin_lock_irqsave(&chip->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) snd_pmac_beep_stop(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) spin_unlock_irqrestore(&chip->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) if (chip->irq >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) disable_irq(chip->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) if (chip->tx_irq >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) disable_irq(chip->tx_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) if (chip->rx_irq >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) disable_irq(chip->rx_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) snd_pmac_sound_feature(chip, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) void snd_pmac_resume(struct snd_pmac *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) snd_pmac_sound_feature(chip, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) if (chip->resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) chip->resume(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) /* enable CD sound input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) if (chip->macio_base && chip->is_pbook_G3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) out_8(chip->macio_base + 0x37, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) else if (chip->is_pbook_3400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) in_8(chip->latch_base + 0x190);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) snd_pmac_pcm_set_format(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) if (chip->irq >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) enable_irq(chip->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) if (chip->tx_irq >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) enable_irq(chip->tx_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) if (chip->rx_irq >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) enable_irq(chip->rx_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) snd_power_change_state(chip->card, SNDRV_CTL_POWER_D0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) #endif /* CONFIG_PM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367)