sound/atmel/ac97c.c

Source file repositories/reference/linux-study-clean/sound/atmel/ac97c.c

File Facts

System
Linux kernel
Corpus path
sound/atmel/ac97c.c
Extension
.c
Size
22173 bytes
Lines
866
Domain
Driver Families
Bucket
sound/atmel
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 atmel_ac97c {
	struct clk			*pclk;
	struct platform_device		*pdev;

	struct snd_pcm_substream	*playback_substream;
	struct snd_pcm_substream	*capture_substream;
	struct snd_card			*card;
	struct snd_pcm			*pcm;
	struct snd_ac97			*ac97;
	struct snd_ac97_bus		*ac97_bus;

	u64				cur_format;
	unsigned int			cur_rate;
	int				playback_period, capture_period;
	/* Serialize access to opened variable */
	spinlock_t			lock;
	void __iomem			*regs;
	int				irq;
	int				opened;
	struct gpio_desc		*reset_pin;
};

#define get_chip(card) ((struct atmel_ac97c *)(card)->private_data)

#define ac97c_writel(chip, reg, val)			\
	__raw_writel((val), (chip)->regs + AC97C_##reg)
#define ac97c_readl(chip, reg)				\
	__raw_readl((chip)->regs + AC97C_##reg)

static const struct snd_pcm_hardware atmel_ac97c_hw = {
	.info			= (SNDRV_PCM_INFO_MMAP
				  | SNDRV_PCM_INFO_MMAP_VALID
				  | SNDRV_PCM_INFO_INTERLEAVED
				  | SNDRV_PCM_INFO_BLOCK_TRANSFER
				  | SNDRV_PCM_INFO_JOINT_DUPLEX
				  | SNDRV_PCM_INFO_RESUME
				  | SNDRV_PCM_INFO_PAUSE),
	.formats		= (SNDRV_PCM_FMTBIT_S16_BE
				  | SNDRV_PCM_FMTBIT_S16_LE),
	.rates			= (SNDRV_PCM_RATE_CONTINUOUS),
	.rate_min		= 4000,
	.rate_max		= 48000,
	.channels_min		= 1,
	.channels_max		= 2,
	.buffer_bytes_max	= 2 * 2 * 64 * 2048,
	.period_bytes_min	= 4096,
	.period_bytes_max	= 4096,
	.periods_min		= 6,
	.periods_max		= 64,
};

static int atmel_ac97c_playback_open(struct snd_pcm_substream *substream)
{
	struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
	struct snd_pcm_runtime *runtime = substream->runtime;

	guard(mutex)(&opened_mutex);
	chip->opened++;
	runtime->hw = atmel_ac97c_hw;
	if (chip->cur_rate) {
		runtime->hw.rate_min = chip->cur_rate;
		runtime->hw.rate_max = chip->cur_rate;
	}
	if (chip->cur_format)
		runtime->hw.formats = pcm_format_to_bits(chip->cur_format);
	chip->playback_substream = substream;
	return 0;
}

static int atmel_ac97c_capture_open(struct snd_pcm_substream *substream)
{
	struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
	struct snd_pcm_runtime *runtime = substream->runtime;

	guard(mutex)(&opened_mutex);
	chip->opened++;
	runtime->hw = atmel_ac97c_hw;
	if (chip->cur_rate) {
		runtime->hw.rate_min = chip->cur_rate;
		runtime->hw.rate_max = chip->cur_rate;
	}
	if (chip->cur_format)
		runtime->hw.formats = pcm_format_to_bits(chip->cur_format);
	chip->capture_substream = substream;
	return 0;
}

static int atmel_ac97c_playback_close(struct snd_pcm_substream *substream)
{
	struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);

Annotation

Implementation Notes