sound/soc/tegra/tegra20_ac97.c

Source file repositories/reference/linux-study-clean/sound/soc/tegra/tegra20_ac97.c

File Facts

System
Linux kernel
Corpus path
sound/soc/tegra/tegra20_ac97.c
Extension
.c
Size
11694 bytes
Lines
460
Domain
Driver Families
Bucket
sound/soc
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

// SPDX-License-Identifier: GPL-2.0-only
/*
 * tegra20_ac97.c - Tegra20 AC97 platform driver
 *
 * Copyright (c) 2012 Lucas Stach <dev@lynxeye.de>
 *
 * Partly based on code copyright/by:
 *
 * Copyright (c) 2011,2012 Toradex Inc.
 */

#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/gpio/consumer.h>
#include <linux/io.h>
#include <linux/jiffies.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/dmaengine_pcm.h>

#include "tegra20_ac97.h"

#define DRV_NAME "tegra20-ac97"

static struct tegra20_ac97 *workdata;

static void tegra20_ac97_codec_reset(struct snd_ac97 *ac97)
{
	u32 readback;
	unsigned long timeout;

	/*
	 * The reset line is not driven by DAC pad group, have to toggle GPIO.
	 * The RESET line is active low but this is abstracted by the GPIO
	 * library.
	 */
	gpiod_set_value(workdata->reset_gpio, 1);
	udelay(2);

	gpiod_set_value(workdata->reset_gpio, 0);
	udelay(2);

	timeout = jiffies + msecs_to_jiffies(100);

	do {
		regmap_read(workdata->regmap, TEGRA20_AC97_STATUS1, &readback);
		if (readback & TEGRA20_AC97_STATUS1_CODEC1_RDY)
			break;
		usleep_range(1000, 2000);
	} while (!time_after(jiffies, timeout));
}

static void tegra20_ac97_codec_warm_reset(struct snd_ac97 *ac97)
{
	u32 readback;
	unsigned long timeout;

	/*
	 * although sync line is driven by the DAC pad group warm reset using
	 * the controller cmd is not working, have to toggle sync line
	 * manually.
	 */
	gpiod_direction_output(workdata->sync_gpio, 1);
	udelay(2);
	gpiod_set_value(workdata->sync_gpio, 0);
	udelay(2);

	timeout = jiffies + msecs_to_jiffies(100);

	do {
		regmap_read(workdata->regmap, TEGRA20_AC97_STATUS1, &readback);
		if (readback & TEGRA20_AC97_STATUS1_CODEC1_RDY)
			break;
		usleep_range(1000, 2000);
	} while (!time_after(jiffies, timeout));
}

static unsigned short tegra20_ac97_codec_read(struct snd_ac97 *ac97_snd,
					      unsigned short reg)
{
	u32 readback;

Annotation

Implementation Notes