drivers/clk/meson/clk-phase.c
Source file repositories/reference/linux-study-clean/drivers/clk/meson/clk-phase.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/clk/meson/clk-phase.c- Extension
.c- Size
- 5543 bytes
- Lines
- 198
- Domain
- Driver Families
- Bucket
- drivers/clk
- 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.
- 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/clk-provider.hlinux/module.hclk-regmap.hclk-phase.h
Detected Declarations
function Copyrightfunction meson_clk_degrees_from_valfunction meson_clk_degrees_to_valfunction meson_clk_phase_get_phasefunction meson_clk_phase_set_phasefunction worldfunction meson_clk_triphase_syncfunction meson_clk_triphase_get_phasefunction meson_clk_triphase_set_phasefunction meson_sclk_ws_inv_datafunction meson_sclk_ws_inv_syncfunction meson_sclk_ws_inv_get_phasefunction meson_sclk_ws_inv_set_phase
Annotated Snippet
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/*
* Copyright (c) 2018 BayLibre, SAS.
* Author: Jerome Brunet <jbrunet@baylibre.com>
*/
#include <linux/clk-provider.h>
#include <linux/module.h>
#include "clk-regmap.h"
#include "clk-phase.h"
#define phase_step(_width) (360 / (1 << (_width)))
static inline struct meson_clk_phase_data *
meson_clk_phase_data(struct clk_regmap *clk)
{
return (struct meson_clk_phase_data *)clk->data;
}
static int meson_clk_degrees_from_val(unsigned int val, unsigned int width)
{
return phase_step(width) * val;
}
static unsigned int meson_clk_degrees_to_val(int degrees, unsigned int width)
{
unsigned int val = DIV_ROUND_CLOSEST(degrees, phase_step(width));
/*
* This last calculation is here for cases when degrees is rounded
* to 360, in which case val == (1 << width).
*/
return val % (1 << width);
}
static int meson_clk_phase_get_phase(struct clk_hw *hw)
{
struct clk_regmap *clk = to_clk_regmap(hw);
struct meson_clk_phase_data *phase = meson_clk_phase_data(clk);
unsigned int val;
val = meson_parm_read(clk->map, &phase->ph);
return meson_clk_degrees_from_val(val, phase->ph.width);
}
static int meson_clk_phase_set_phase(struct clk_hw *hw, int degrees)
{
struct clk_regmap *clk = to_clk_regmap(hw);
struct meson_clk_phase_data *phase = meson_clk_phase_data(clk);
unsigned int val;
val = meson_clk_degrees_to_val(degrees, phase->ph.width);
meson_parm_write(clk->map, &phase->ph, val);
return 0;
}
const struct clk_ops meson_clk_phase_ops = {
.init = clk_regmap_init,
.get_phase = meson_clk_phase_get_phase,
.set_phase = meson_clk_phase_set_phase,
};
EXPORT_SYMBOL_NS_GPL(meson_clk_phase_ops, "CLK_MESON");
/*
* This is a special clock for the audio controller.
* The phase of mst_sclk clock output can be controlled independently
* for the outside world (ph0), the tdmout (ph1) and tdmin (ph2).
* Controlling these 3 phases as just one makes things simpler and
* give the same clock view to all the element on the i2s bus.
* If necessary, we can still control the phase in the tdm block
* which makes these independent control redundant.
*/
static inline struct meson_clk_triphase_data *
meson_clk_triphase_data(struct clk_regmap *clk)
{
return (struct meson_clk_triphase_data *)clk->data;
}
static int meson_clk_triphase_sync(struct clk_hw *hw)
{
struct clk_regmap *clk = to_clk_regmap(hw);
struct meson_clk_triphase_data *tph = meson_clk_triphase_data(clk);
unsigned int val;
int ret;
ret = clk_regmap_init(hw);
if (ret)
Annotation
- Immediate include surface: `linux/clk-provider.h`, `linux/module.h`, `clk-regmap.h`, `clk-phase.h`.
- Detected declarations: `function Copyright`, `function meson_clk_degrees_from_val`, `function meson_clk_degrees_to_val`, `function meson_clk_phase_get_phase`, `function meson_clk_phase_set_phase`, `function world`, `function meson_clk_triphase_sync`, `function meson_clk_triphase_get_phase`, `function meson_clk_triphase_set_phase`, `function meson_sclk_ws_inv_data`.
- Atlas domain: Driver Families / drivers/clk.
- Implementation status: integration implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.