Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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)