sound/soc/tegra/tegra30_ahub.c

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

File Facts

System
Linux kernel
Corpus path
sound/soc/tegra/tegra30_ahub.c
Extension
.c
Size
18340 bytes
Lines
688
Domain
Driver Families
Bucket
sound/soc
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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
/*
 * tegra30_ahub.c - Tegra30 AHUB driver
 *
 * Copyright (c) 2011,2012, NVIDIA CORPORATION.  All rights reserved.
 */

#include <linux/clk.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/slab.h>
#include <sound/soc.h>
#include "tegra30_ahub.h"

#define DRV_NAME "tegra30-ahub"

static struct tegra30_ahub *ahub;

static inline void tegra30_apbif_write(u32 reg, u32 val)
{
	regmap_write(ahub->regmap_apbif, reg, val);
}

static inline u32 tegra30_apbif_read(u32 reg)
{
	u32 val;

	regmap_read(ahub->regmap_apbif, reg, &val);
	return val;
}

static inline void tegra30_audio_write(u32 reg, u32 val)
{
	regmap_write(ahub->regmap_ahub, reg, val);
}

static int tegra30_ahub_runtime_suspend(struct device *dev)
{
	regcache_cache_only(ahub->regmap_apbif, true);
	regcache_cache_only(ahub->regmap_ahub, true);

	clk_bulk_disable_unprepare(ahub->nclocks, ahub->clocks);

	return 0;
}

/*
 * clk_apbif isn't required for an I2S<->I2S configuration where no PCM data
 * is read from or sent to memory. However, that's not something the rest of
 * the driver supports right now, so we'll just treat the two clocks as one
 * for now.
 *
 * These functions should not be a plain ref-count. Instead, each active stream
 * contributes some requirement to the minimum clock rate, so starting or
 * stopping streams should dynamically adjust the clock as required.  However,
 * this is not yet implemented.
 */
static int tegra30_ahub_runtime_resume(struct device *dev)
{
	int ret;

	ret = reset_control_bulk_assert(ahub->nresets, ahub->resets);
	if (ret)
		return ret;

	ret = clk_bulk_prepare_enable(ahub->nclocks, ahub->clocks);
	if (ret)
		return ret;

	usleep_range(10, 100);

	ret = reset_control_bulk_deassert(ahub->nresets, ahub->resets);
	if (ret)
		goto disable_clocks;

	regcache_cache_only(ahub->regmap_apbif, false);
	regcache_cache_only(ahub->regmap_ahub, false);
	regcache_mark_dirty(ahub->regmap_apbif);
	regcache_mark_dirty(ahub->regmap_ahub);

	ret = regcache_sync(ahub->regmap_apbif);
	if (ret)
		goto disable_clocks;

Annotation

Implementation Notes