^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * i2sbus driver -- pcm routines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <asm/macio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "../soundbus.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "i2sbus.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) static inline void get_pcm_info(struct i2sbus_dev *i2sdev, int in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) struct pcm_info **pi, struct pcm_info **other)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) if (in) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) if (pi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) *pi = &i2sdev->in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) if (other)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) *other = &i2sdev->out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) if (pi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) *pi = &i2sdev->out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) if (other)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) *other = &i2sdev->in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) static int clock_and_divisors(int mclk, int sclk, int rate, int *out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /* sclk must be derived from mclk! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) if (mclk % sclk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /* derive sclk register value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) if (i2s_sf_sclkdiv(mclk / sclk, out))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if (I2S_CLOCK_SPEED_18MHz % (rate * mclk) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) if (!i2s_sf_mclkdiv(I2S_CLOCK_SPEED_18MHz / (rate * mclk), out)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) *out |= I2S_SF_CLOCK_SOURCE_18MHz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (I2S_CLOCK_SPEED_45MHz % (rate * mclk) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) if (!i2s_sf_mclkdiv(I2S_CLOCK_SPEED_45MHz / (rate * mclk), out)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) *out |= I2S_SF_CLOCK_SOURCE_45MHz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (I2S_CLOCK_SPEED_49MHz % (rate * mclk) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) if (!i2s_sf_mclkdiv(I2S_CLOCK_SPEED_49MHz / (rate * mclk), out)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) *out |= I2S_SF_CLOCK_SOURCE_49MHz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define CHECK_RATE(rate) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) do { if (rates & SNDRV_PCM_RATE_ ##rate) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) int dummy; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if (clock_and_divisors(sysclock_factor, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) bus_factor, rate, &dummy)) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) rates &= ~SNDRV_PCM_RATE_ ##rate; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) } } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static int i2sbus_pcm_open(struct i2sbus_dev *i2sdev, int in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) struct pcm_info *pi, *other;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct soundbus_dev *sdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) int masks_inited = 0, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct codec_info_item *cii, *rev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct snd_pcm_hardware *hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) u64 formats = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) unsigned int rates = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct transfer_info v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) int result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) int bus_factor = 0, sysclock_factor = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) int found_this;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) mutex_lock(&i2sdev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) get_pcm_info(i2sdev, in, &pi, &other);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) hw = &pi->substream->runtime->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) sdev = &i2sdev->sound;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (pi->active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /* alsa messed up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) result = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) /* we now need to assign the hw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) list_for_each_entry(cii, &sdev->codec_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct transfer_info *ti = cii->codec->transfers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) bus_factor = cii->codec->bus_factor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) sysclock_factor = cii->codec->sysclock_factor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) while (ti->formats && ti->rates) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) v = *ti;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (ti->transfer_in == in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) && cii->codec->usable(cii, ti, &v)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (masks_inited) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) formats &= v.formats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) rates &= v.rates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) formats = v.formats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) rates = v.rates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) masks_inited = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) ti++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (!masks_inited || !bus_factor || !sysclock_factor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) result = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /* bus dependent stuff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) hw->info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_RESUME |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) SNDRV_PCM_INFO_JOINT_DUPLEX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) CHECK_RATE(5512);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) CHECK_RATE(8000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) CHECK_RATE(11025);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) CHECK_RATE(16000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) CHECK_RATE(22050);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) CHECK_RATE(32000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) CHECK_RATE(44100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) CHECK_RATE(48000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) CHECK_RATE(64000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) CHECK_RATE(88200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) CHECK_RATE(96000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) CHECK_RATE(176400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) CHECK_RATE(192000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) hw->rates = rates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /* well. the codec might want 24 bits only, and we'll
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * ever only transfer 24 bits, but they are top-aligned!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * So for alsa, we claim that we're doing full 32 bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * while in reality we'll ignore the lower 8 bits of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * that when doing playback (they're transferred as 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * as far as I know, no codecs we have are 32-bit capable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * so I can't really test) and when doing recording we'll
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * always have those lower 8 bits recorded as 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if (formats & SNDRV_PCM_FMTBIT_S24_BE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) formats |= SNDRV_PCM_FMTBIT_S32_BE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (formats & SNDRV_PCM_FMTBIT_U24_BE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) formats |= SNDRV_PCM_FMTBIT_U32_BE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) /* now mask off what we can support. I suppose we could
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * also support S24_3LE and some similar formats, but I
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * doubt there's a codec that would be able to use that,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * so we don't support it here. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) hw->formats = formats & (SNDRV_PCM_FMTBIT_S16_BE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) SNDRV_PCM_FMTBIT_U16_BE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) SNDRV_PCM_FMTBIT_S32_BE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) SNDRV_PCM_FMTBIT_U32_BE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /* we need to set the highest and lowest rate possible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * These are the highest and lowest rates alsa can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * support properly in its bitfield.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * Below, we'll use that to restrict to the rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * currently in use (if any). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) hw->rate_min = 5512;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) hw->rate_max = 192000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) /* if the other stream is active, then we can only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * support what it is currently using.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * FIXME: I lied. This comment is wrong. We can support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * anything that works with the same serial format, ie.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * when recording 24 bit sound we can well play 16 bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * sound at the same time iff using the same transfer mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (other->active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /* FIXME: is this guaranteed by the alsa api? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) hw->formats &= pcm_format_to_bits(i2sdev->format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /* see above, restrict rates to the one we already have */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) hw->rate_min = i2sdev->rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) hw->rate_max = i2sdev->rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) hw->channels_min = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) hw->channels_max = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /* these are somewhat arbitrary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) hw->buffer_bytes_max = 131072;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) hw->period_bytes_min = 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) hw->period_bytes_max = 16384;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) hw->periods_min = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) hw->periods_max = MAX_DBDMA_COMMANDS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) err = snd_pcm_hw_constraint_integer(pi->substream->runtime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) SNDRV_PCM_HW_PARAM_PERIODS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) result = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) list_for_each_entry(cii, &sdev->codec_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (cii->codec->open) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) err = cii->codec->open(cii, pi->substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) result = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /* unwind */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) found_this = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) list_for_each_entry_reverse(rev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) &sdev->codec_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (found_this && rev->codec->close) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) rev->codec->close(rev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) pi->substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (rev == cii)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) found_this = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) mutex_unlock(&i2sdev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) #undef CHECK_RATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) static int i2sbus_pcm_close(struct i2sbus_dev *i2sdev, int in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) struct codec_info_item *cii;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) struct pcm_info *pi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) int err = 0, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) mutex_lock(&i2sdev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) get_pcm_info(i2sdev, in, &pi, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (cii->codec->close) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) tmp = cii->codec->close(cii, pi->substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) err = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) pi->substream = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) pi->active = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) mutex_unlock(&i2sdev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) static void i2sbus_wait_for_stop(struct i2sbus_dev *i2sdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) struct pcm_info *pi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) DECLARE_COMPLETION_ONSTACK(done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) spin_lock_irqsave(&i2sdev->low_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (pi->dbdma_ring.stopping) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) pi->stop_completion = &done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) spin_unlock_irqrestore(&i2sdev->low_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) timeout = wait_for_completion_timeout(&done, HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) spin_lock_irqsave(&i2sdev->low_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) pi->stop_completion = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (timeout == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /* timeout expired, stop dbdma forcefully */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) printk(KERN_ERR "i2sbus_wait_for_stop: timed out\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) /* make sure RUN, PAUSE and S0 bits are cleared */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) out_le32(&pi->dbdma->control, (RUN | PAUSE | 1) << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) pi->dbdma_ring.stopping = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) timeout = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) while (in_le32(&pi->dbdma->status) & ACTIVE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) if (--timeout <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) spin_unlock_irqrestore(&i2sdev->low_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) void i2sbus_wait_for_stop_both(struct i2sbus_dev *i2sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) struct pcm_info *pi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) get_pcm_info(i2sdev, 0, &pi, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) i2sbus_wait_for_stop(i2sdev, pi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) get_pcm_info(i2sdev, 1, &pi, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) i2sbus_wait_for_stop(i2sdev, pi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) static inline int i2sbus_hw_free(struct snd_pcm_substream *substream, int in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) struct pcm_info *pi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) get_pcm_info(i2sdev, in, &pi, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (pi->dbdma_ring.stopping)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) i2sbus_wait_for_stop(i2sdev, pi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) static int i2sbus_playback_hw_free(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return i2sbus_hw_free(substream, 0);
^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) static int i2sbus_record_hw_free(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return i2sbus_hw_free(substream, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static int i2sbus_pcm_prepare(struct i2sbus_dev *i2sdev, int in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) /* whee. Hard work now. The user has selected a bitrate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * and bit format, so now we have to program our
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * I2S controller appropriately. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) struct snd_pcm_runtime *runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) struct dbdma_cmd *command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) int i, periodsize, nperiods;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) dma_addr_t offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) struct bus_info bi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) struct codec_info_item *cii;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) int sfr = 0; /* serial format register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) int dws = 0; /* data word sizes reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) int input_16bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) struct pcm_info *pi, *other;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) int cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) int result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) unsigned int cmd, stopaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) mutex_lock(&i2sdev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) get_pcm_info(i2sdev, in, &pi, &other);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) if (pi->dbdma_ring.running) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) result = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (pi->dbdma_ring.stopping)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) i2sbus_wait_for_stop(i2sdev, pi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (!pi->substream || !pi->substream->runtime) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) result = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) goto out_unlock;
^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) runtime = pi->substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) pi->active = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (other->active &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) ((i2sdev->format != runtime->format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) || (i2sdev->rate != runtime->rate))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) result = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) i2sdev->format = runtime->format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) i2sdev->rate = runtime->rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) periodsize = snd_pcm_lib_period_bytes(pi->substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) nperiods = pi->substream->runtime->periods;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) pi->current_period = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) /* generate dbdma command ring first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) command = pi->dbdma_ring.cmds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) memset(command, 0, (nperiods + 2) * sizeof(struct dbdma_cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) /* commands to DMA to/from the ring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) * For input, we need to do a graceful stop; if we abort
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) * the DMA, we end up with leftover bytes that corrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) * the next recording. To do this we set the S0 status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) * bit and wait for the DMA controller to stop. Each
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * command has a branch condition to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) * make it branch to a stop command if S0 is set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) * On input we also need to wait for the S7 bit to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) * set before turning off the DMA controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) * In fact we do the graceful stop for output as well.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) offset = runtime->dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) cmd = (in? INPUT_MORE: OUTPUT_MORE) | BR_IFSET | INTR_ALWAYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) stopaddr = pi->dbdma_ring.bus_cmd_start +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) (nperiods + 1) * sizeof(struct dbdma_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) for (i = 0; i < nperiods; i++, command++, offset += periodsize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) command->command = cpu_to_le16(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) command->cmd_dep = cpu_to_le32(stopaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) command->phy_addr = cpu_to_le32(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) command->req_count = cpu_to_le16(periodsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) /* branch back to beginning of ring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) command->command = cpu_to_le16(DBDMA_NOP | BR_ALWAYS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) command->cmd_dep = cpu_to_le32(pi->dbdma_ring.bus_cmd_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) command++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) /* set stop command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) command->command = cpu_to_le16(DBDMA_STOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) /* ok, let's set the serial format and stuff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) switch (runtime->format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) /* 16 bit formats */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) case SNDRV_PCM_FORMAT_S16_BE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) case SNDRV_PCM_FORMAT_U16_BE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) /* FIXME: if we add different bus factors we need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) * do more here!! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) bi.bus_factor = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) bi.bus_factor = cii->codec->bus_factor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (!bi.bus_factor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) result = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) input_16bit = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) case SNDRV_PCM_FORMAT_S32_BE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) case SNDRV_PCM_FORMAT_U32_BE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) /* force 64x bus speed, otherwise the data cannot be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) * transferred quickly enough! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) bi.bus_factor = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) input_16bit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) result = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) /* we assume all sysclocks are the same! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) bi.sysclock_factor = cii->codec->sysclock_factor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (clock_and_divisors(bi.sysclock_factor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) bi.bus_factor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) runtime->rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) &sfr) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) result = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) switch (bi.bus_factor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) case 32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) sfr |= I2S_SF_SERIAL_FORMAT_I2S_32X;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) case 64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) sfr |= I2S_SF_SERIAL_FORMAT_I2S_64X;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) /* FIXME: THIS ASSUMES MASTER ALL THE TIME */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) sfr |= I2S_SF_SCLK_MASTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (cii->codec->prepare)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) err = cii->codec->prepare(cii, &bi, pi->substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) result = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) /* codecs are fine with it, so set our clocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (input_16bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) dws = (2 << I2S_DWS_NUM_CHANNELS_IN_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) (2 << I2S_DWS_NUM_CHANNELS_OUT_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) I2S_DWS_DATA_IN_16BIT | I2S_DWS_DATA_OUT_16BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) dws = (2 << I2S_DWS_NUM_CHANNELS_IN_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) (2 << I2S_DWS_NUM_CHANNELS_OUT_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) I2S_DWS_DATA_IN_24BIT | I2S_DWS_DATA_OUT_24BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) /* early exit if already programmed correctly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) /* not locking these is fine since we touch them only in this function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if (in_le32(&i2sdev->intfregs->serial_format) == sfr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) && in_le32(&i2sdev->intfregs->data_word_sizes) == dws)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) /* let's notify the codecs about clocks going away.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * For now we only do mastering on the i2s cell... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) list_for_each_entry(cii, &i2sdev->sound.codec_list, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) if (cii->codec->switch_clock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) cii->codec->switch_clock(cii, CLOCK_SWITCH_PREPARE_SLAVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) i2sbus_control_enable(i2sdev->control, i2sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) i2sbus_control_cell(i2sdev->control, i2sdev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) out_le32(&i2sdev->intfregs->intr_ctl, I2S_PENDING_CLOCKS_STOPPED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) i2sbus_control_clock(i2sdev->control, i2sdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) /* wait for clock stopped. This can apparently take a while... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) cnt = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) while (cnt-- &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) !(in_le32(&i2sdev->intfregs->intr_ctl) & I2S_PENDING_CLOCKS_STOPPED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) msleep(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) out_le32(&i2sdev->intfregs->intr_ctl, I2S_PENDING_CLOCKS_STOPPED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) /* not locking these is fine since we touch them only in this function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) out_le32(&i2sdev->intfregs->serial_format, sfr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) out_le32(&i2sdev->intfregs->data_word_sizes, dws);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) i2sbus_control_enable(i2sdev->control, i2sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) i2sbus_control_cell(i2sdev->control, i2sdev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) i2sbus_control_clock(i2sdev->control, i2sdev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) list_for_each_entry(cii, &i2sdev->sound.codec_list, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (cii->codec->switch_clock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) cii->codec->switch_clock(cii, CLOCK_SWITCH_SLAVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) mutex_unlock(&i2sdev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) void i2sbus_pcm_prepare_both(struct i2sbus_dev *i2sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) i2sbus_pcm_prepare(i2sdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) i2sbus_pcm_prepare(i2sdev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) static int i2sbus_pcm_trigger(struct i2sbus_dev *i2sdev, int in, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) struct codec_info_item *cii;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) struct pcm_info *pi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) int result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) spin_lock_irqsave(&i2sdev->low_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) get_pcm_info(i2sdev, in, &pi, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) case SNDRV_PCM_TRIGGER_RESUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (pi->dbdma_ring.running) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) result = -EALREADY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) list_for_each_entry(cii, &i2sdev->sound.codec_list, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) if (cii->codec->start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) cii->codec->start(cii, pi->substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) pi->dbdma_ring.running = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (pi->dbdma_ring.stopping) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) /* Clear the S0 bit, then see if we stopped yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) out_le32(&pi->dbdma->control, 1 << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if (in_le32(&pi->dbdma->status) & ACTIVE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) /* possible race here? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) if (in_le32(&pi->dbdma->status) & ACTIVE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) pi->dbdma_ring.stopping = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) goto out_unlock; /* keep running */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) /* make sure RUN, PAUSE and S0 bits are cleared */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) out_le32(&pi->dbdma->control, (RUN | PAUSE | 1) << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) /* set branch condition select register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) out_le32(&pi->dbdma->br_sel, (1 << 16) | 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) /* write dma command buffer address to the dbdma chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) out_le32(&pi->dbdma->cmdptr, pi->dbdma_ring.bus_cmd_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) /* initialize the frame count and current period */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) pi->current_period = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) pi->frame_count = in_le32(&i2sdev->intfregs->frame_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) /* set the DMA controller running */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) out_le32(&pi->dbdma->control, (RUN << 16) | RUN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) /* off you go! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) case SNDRV_PCM_TRIGGER_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) if (!pi->dbdma_ring.running) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) result = -EALREADY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) pi->dbdma_ring.running = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) /* Set the S0 bit to make the DMA branch to the stop cmd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) out_le32(&pi->dbdma->control, (1 << 16) | 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) pi->dbdma_ring.stopping = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) list_for_each_entry(cii, &i2sdev->sound.codec_list, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) if (cii->codec->stop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) cii->codec->stop(cii, pi->substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) result = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) spin_unlock_irqrestore(&i2sdev->low_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) static snd_pcm_uframes_t i2sbus_pcm_pointer(struct i2sbus_dev *i2sdev, int in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) struct pcm_info *pi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) u32 fc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) get_pcm_info(i2sdev, in, &pi, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) fc = in_le32(&i2sdev->intfregs->frame_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) fc = fc - pi->frame_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) if (fc >= pi->substream->runtime->buffer_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) fc %= pi->substream->runtime->buffer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) return fc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) static inline void handle_interrupt(struct i2sbus_dev *i2sdev, int in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) struct pcm_info *pi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) u32 fc, nframes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) int timeout, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) int dma_stopped = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) struct snd_pcm_runtime *runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) spin_lock(&i2sdev->low_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) get_pcm_info(i2sdev, in, &pi, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) if (!pi->dbdma_ring.running && !pi->dbdma_ring.stopping)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) i = pi->current_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) runtime = pi->substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) while (pi->dbdma_ring.cmds[i].xfer_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) if (le16_to_cpu(pi->dbdma_ring.cmds[i].xfer_status) & BT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) * BT is the branch taken bit. If it took a branch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) * it is because we set the S0 bit to make it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) * branch to the stop command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) dma_stopped = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) pi->dbdma_ring.cmds[i].xfer_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (++i >= runtime->periods) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) pi->frame_count += runtime->buffer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) pi->current_period = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) * Check the frame count. The DMA tends to get a bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) * ahead of the frame counter, which confuses the core.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) fc = in_le32(&i2sdev->intfregs->frame_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) nframes = i * runtime->period_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) if (fc < pi->frame_count + nframes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) pi->frame_count = fc - nframes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) if (dma_stopped) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) timeout = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) status = in_le32(&pi->dbdma->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) if (!(status & ACTIVE) && (!in || (status & 0x80)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) if (--timeout <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) printk(KERN_ERR "i2sbus: timed out "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) "waiting for DMA to stop!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) /* Turn off DMA controller, clear S0 bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) out_le32(&pi->dbdma->control, (RUN | PAUSE | 1) << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) pi->dbdma_ring.stopping = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (pi->stop_completion)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) complete(pi->stop_completion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) if (!pi->dbdma_ring.running)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) spin_unlock(&i2sdev->low_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) /* may call _trigger again, hence needs to be unlocked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) snd_pcm_period_elapsed(pi->substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) spin_unlock(&i2sdev->low_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) irqreturn_t i2sbus_tx_intr(int irq, void *devid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) handle_interrupt((struct i2sbus_dev *)devid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) return IRQ_HANDLED;
^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) irqreturn_t i2sbus_rx_intr(int irq, void *devid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) handle_interrupt((struct i2sbus_dev *)devid, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) static int i2sbus_playback_open(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) if (!i2sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) i2sdev->out.substream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) return i2sbus_pcm_open(i2sdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) static int i2sbus_playback_close(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) if (!i2sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) if (i2sdev->out.substream != substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) err = i2sbus_pcm_close(i2sdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) i2sdev->out.substream = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) return err;
^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) static int i2sbus_playback_prepare(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) if (!i2sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) if (i2sdev->out.substream != substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) return i2sbus_pcm_prepare(i2sdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) static int i2sbus_playback_trigger(struct snd_pcm_substream *substream, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) if (!i2sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) if (i2sdev->out.substream != substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) return i2sbus_pcm_trigger(i2sdev, 0, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) static snd_pcm_uframes_t i2sbus_playback_pointer(struct snd_pcm_substream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (!i2sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if (i2sdev->out.substream != substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) return i2sbus_pcm_pointer(i2sdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) static const struct snd_pcm_ops i2sbus_playback_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) .open = i2sbus_playback_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) .close = i2sbus_playback_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) .hw_free = i2sbus_playback_hw_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) .prepare = i2sbus_playback_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) .trigger = i2sbus_playback_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) .pointer = i2sbus_playback_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) static int i2sbus_record_open(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (!i2sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) i2sdev->in.substream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) return i2sbus_pcm_open(i2sdev, 1);
^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) static int i2sbus_record_close(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) if (!i2sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (i2sdev->in.substream != substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) err = i2sbus_pcm_close(i2sdev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) i2sdev->in.substream = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) static int i2sbus_record_prepare(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) if (!i2sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) if (i2sdev->in.substream != substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) return i2sbus_pcm_prepare(i2sdev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) static int i2sbus_record_trigger(struct snd_pcm_substream *substream, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) if (!i2sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) if (i2sdev->in.substream != substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) return i2sbus_pcm_trigger(i2sdev, 1, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) static snd_pcm_uframes_t i2sbus_record_pointer(struct snd_pcm_substream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (!i2sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) if (i2sdev->in.substream != substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) return i2sbus_pcm_pointer(i2sdev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) static const struct snd_pcm_ops i2sbus_record_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) .open = i2sbus_record_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) .close = i2sbus_record_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) .hw_free = i2sbus_record_hw_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) .prepare = i2sbus_record_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) .trigger = i2sbus_record_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) .pointer = i2sbus_record_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) static void i2sbus_private_free(struct snd_pcm *pcm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) struct i2sbus_dev *i2sdev = snd_pcm_chip(pcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) struct codec_info_item *p, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) i2sdev->sound.pcm = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) i2sdev->out.created = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) i2sdev->in.created = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) list_for_each_entry_safe(p, tmp, &i2sdev->sound.codec_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) printk(KERN_ERR "i2sbus: a codec didn't unregister!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) list_del(&p->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) module_put(p->codec->owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) kfree(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) soundbus_dev_put(&i2sdev->sound);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) module_put(THIS_MODULE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) struct codec_info *ci, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) int err, in = 0, out = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) struct transfer_info *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) struct i2sbus_dev *i2sdev = soundbus_dev_to_i2sbus_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) struct codec_info_item *cii;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) if (!dev->pcmname || dev->pcmid == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) printk(KERN_ERR "i2sbus: pcm name and id must be set!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) return -EINVAL;
^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) list_for_each_entry(cii, &dev->codec_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) if (cii->codec_data == data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) return -EALREADY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) if (!ci->transfers || !ci->transfers->formats
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) || !ci->transfers->rates || !ci->usable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) /* we currently code the i2s transfer on the clock, and support only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) * 32 and 64 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) if (ci->bus_factor != 32 && ci->bus_factor != 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) /* If you want to fix this, you need to keep track of what transport infos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) * are to be used, which codecs they belong to, and then fix all the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) * sysclock/busclock stuff above to depend on which is usable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) list_for_each_entry(cii, &dev->codec_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) if (cii->codec->sysclock_factor != ci->sysclock_factor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) "cannot yet handle multiple different sysclocks!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) if (cii->codec->bus_factor != ci->bus_factor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) "cannot yet handle multiple different bus clocks!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) tmp = ci->transfers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) while (tmp->formats && tmp->rates) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) if (tmp->transfer_in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) in = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) out = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) tmp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) cii = kzalloc(sizeof(struct codec_info_item), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) if (!cii) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) printk(KERN_DEBUG "i2sbus: failed to allocate cii\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) /* use the private data to point to the codec info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) cii->sdev = soundbus_dev_get(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) cii->codec = ci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) cii->codec_data = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) if (!cii->sdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) "i2sbus: failed to get soundbus dev reference\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) goto out_free_cii;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) if (!try_module_get(THIS_MODULE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) printk(KERN_DEBUG "i2sbus: failed to get module reference!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) err = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) goto out_put_sdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) if (!try_module_get(ci->owner)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) "i2sbus: failed to get module reference to codec owner!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) err = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) goto out_put_this_module;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) if (!dev->pcm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) err = snd_pcm_new(card, dev->pcmname, dev->pcmid, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) &dev->pcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) printk(KERN_DEBUG "i2sbus: failed to create pcm\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) goto out_put_ci_module;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) /* ALSA yet again sucks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) * If it is ever fixed, remove this line. See below. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) out = in = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) if (!i2sdev->out.created && out) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) if (dev->pcm->card != card) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) /* eh? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) "Can't attach same bus to different cards!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) goto out_put_ci_module;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) err = snd_pcm_new_stream(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) goto out_put_ci_module;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) &i2sbus_playback_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) dev->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].dev.parent =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) &dev->ofdev.dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) i2sdev->out.created = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) if (!i2sdev->in.created && in) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) if (dev->pcm->card != card) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) "Can't attach same bus to different cards!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) goto out_put_ci_module;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) err = snd_pcm_new_stream(dev->pcm, SNDRV_PCM_STREAM_CAPTURE, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) goto out_put_ci_module;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_CAPTURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) &i2sbus_record_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) dev->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].dev.parent =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) &dev->ofdev.dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) i2sdev->in.created = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) /* so we have to register the pcm after adding any substream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) * to it because alsa doesn't create the devices for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) * substreams when we add them later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) * Therefore, force in and out on both busses (above) and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) * register the pcm now instead of just after creating it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) err = snd_device_register(card, dev->pcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) printk(KERN_ERR "i2sbus: error registering new pcm\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) goto out_put_ci_module;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) /* no errors any more, so let's add this to our list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) list_add(&cii->list, &dev->codec_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) dev->pcm->private_data = i2sdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) dev->pcm->private_free = i2sbus_private_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) /* well, we really should support scatter/gather DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) snd_pcm_set_managed_buffer_all(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) dev->pcm, SNDRV_DMA_TYPE_DEV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) &macio_get_pci_dev(i2sdev->macio)->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 64 * 1024, 64 * 1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) out_put_ci_module:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) module_put(ci->owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) out_put_this_module:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) module_put(THIS_MODULE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) out_put_sdev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) soundbus_dev_put(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) out_free_cii:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) kfree(cii);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) void i2sbus_detach_codec(struct soundbus_dev *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) struct codec_info_item *cii = NULL, *i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) list_for_each_entry(i, &dev->codec_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) if (i->codec_data == data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) cii = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) if (cii) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) list_del(&cii->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) module_put(cii->codec->owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) kfree(cii);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) /* no more codecs, but still a pcm? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) if (list_empty(&dev->codec_list) && dev->pcm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) /* the actual cleanup is done by the callback above! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) snd_device_free(dev->pcm->card, dev->pcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) }