sound/mips/sgio2audio.c

Source file repositories/reference/linux-study-clean/sound/mips/sgio2audio.c

File Facts

System
Linux kernel
Corpus path
sound/mips/sgio2audio.c
Extension
.c
Size
25056 bytes
Lines
918
Domain
Driver Families
Bucket
sound/mips
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct snd_sgio2audio_chan {
	int idx;
	struct snd_pcm_substream *substream;
	int pos;
	snd_pcm_uframes_t size;
	spinlock_t lock;
};

/* definition of the chip-specific record */
struct snd_sgio2audio {
	struct snd_card *card;

	/* codec */
	struct snd_ad1843 ad1843;
	spinlock_t ad1843_lock;

	/* channels */
	struct snd_sgio2audio_chan channel[3];

	/* resources */
	void *ring_base;
	dma_addr_t ring_base_dma;
};

/* AD1843 access */

/*
 * read_ad1843_reg returns the current contents of a 16 bit AD1843 register.
 *
 * Returns unsigned register value on success, -errno on failure.
 */
static int read_ad1843_reg(void *priv, int reg)
{
	struct snd_sgio2audio *chip = priv;
	int val;

	guard(spinlock_irqsave)(&chip->ad1843_lock);

	writeq((reg << CODEC_CONTROL_ADDRESS_SHIFT) |
	       CODEC_CONTROL_READ, &mace->perif.audio.codec_control);
	wmb();
	val = readq(&mace->perif.audio.codec_control); /* flush bus */
	udelay(200);

	val = readq(&mace->perif.audio.codec_read);

	return val;
}

/*
 * write_ad1843_reg writes the specified value to a 16 bit AD1843 register.
 */
static int write_ad1843_reg(void *priv, int reg, int word)
{
	struct snd_sgio2audio *chip = priv;
	int val;

	guard(spinlock_irqsave)(&chip->ad1843_lock);

	writeq((reg << CODEC_CONTROL_ADDRESS_SHIFT) |
	       (word << CODEC_CONTROL_WORD_SHIFT),
	       &mace->perif.audio.codec_control);
	wmb();
	val = readq(&mace->perif.audio.codec_control); /* flush bus */
	udelay(200);

	return 0;
}

static int sgio2audio_gain_info(struct snd_kcontrol *kcontrol,
			       struct snd_ctl_elem_info *uinfo)
{
	struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol);

	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
	uinfo->count = 2;
	uinfo->value.integer.min = 0;
	uinfo->value.integer.max = ad1843_get_gain_max(&chip->ad1843,
					     (int)kcontrol->private_value);
	return 0;
}

static int sgio2audio_gain_get(struct snd_kcontrol *kcontrol,
			       struct snd_ctl_elem_value *ucontrol)
{
	struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol);
	int vol;

	vol = ad1843_get_gain(&chip->ad1843, (int)kcontrol->private_value);

Annotation

Implementation Notes