drivers/clk/clk-cdce925.c
Source file repositories/reference/linux-study-clean/drivers/clk/clk-cdce925.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/clk/clk-cdce925.c- Extension
.c- Size
- 21782 bytes
- Lines
- 859
- Domain
- Driver Families
- Bucket
- drivers/clk
- 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.
- 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.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/clk.hlinux/clk-provider.hlinux/delay.hlinux/module.hlinux/i2c.hlinux/regmap.hlinux/regulator/consumer.hlinux/slab.hlinux/gcd.h
Detected Declarations
struct clk_cdce925_chip_infostruct clk_cdce925_chipstruct clk_cdce925_outputstruct clk_cdce925_pllstruct clk_cdce925_chipfunction cdce925_pll_calculate_ratefunction cdce925_pll_recalc_ratefunction cdce925_pll_find_ratefunction cdce925_pll_determine_ratefunction cdce925_pll_set_ratefunction cdce925_pll_calc_pfunction cdce925_pll_calc_range_bitsfunction cdce925_pll_preparefunction cdce925_pll_unpreparefunction cdce925_clk_set_pdivfunction cdce925_clk_activatefunction cdce925_clk_preparefunction cdce925_clk_unpreparefunction cdce925_clk_recalc_ratefunction cdce925_calc_dividerfunction cdce925_clk_best_parent_ratefunction cdce925_clk_determine_ratefunction cdce925_clk_set_ratefunction cdce925_y1_calc_dividerfunction cdce925_clk_y1_determine_ratefunction cdce925_clk_y1_set_ratefunction cdce925_regmap_i2c_writefunction cdce925_regmap_i2c_readfunction of_clk_cdce925_getfunction cdce925_regulator_enablefunction cdce925_probe
Annotated Snippet
struct clk_cdce925_chip_info {
int num_plls;
int num_outputs;
};
#define MAX_NUMBER_OF_PLLS 4
#define MAX_NUMBER_OF_OUTPUTS 9
#define CDCE925_REG_GLOBAL1 0x01
#define CDCE925_REG_Y1SPIPDIVH 0x02
#define CDCE925_REG_PDIVL 0x03
#define CDCE925_REG_XCSEL 0x05
/* PLL parameters start at 0x10, steps of 0x10 */
#define CDCE925_OFFSET_PLL 0x10
/* Add CDCE925_OFFSET_PLL * (pll) to these registers before sending */
#define CDCE925_PLL_MUX_OUTPUTS 0x14
#define CDCE925_PLL_MULDIV 0x18
#define CDCE925_PLL_FREQUENCY_MIN 80000000ul
#define CDCE925_PLL_FREQUENCY_MAX 230000000ul
struct clk_cdce925_chip;
struct clk_cdce925_output {
struct clk_hw hw;
struct clk_cdce925_chip *chip;
u8 index;
u16 pdiv; /* 1..127 for Y2-Y9; 1..1023 for Y1 */
};
#define to_clk_cdce925_output(_hw) \
container_of(_hw, struct clk_cdce925_output, hw)
struct clk_cdce925_pll {
struct clk_hw hw;
struct clk_cdce925_chip *chip;
u8 index;
u16 m; /* 1..511 */
u16 n; /* 1..4095 */
};
#define to_clk_cdce925_pll(_hw) container_of(_hw, struct clk_cdce925_pll, hw)
struct clk_cdce925_chip {
struct regmap *regmap;
struct i2c_client *i2c_client;
const struct clk_cdce925_chip_info *chip_info;
struct clk_cdce925_pll pll[MAX_NUMBER_OF_PLLS];
struct clk_cdce925_output clk[MAX_NUMBER_OF_OUTPUTS];
};
/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
static unsigned long cdce925_pll_calculate_rate(unsigned long parent_rate,
u16 n, u16 m)
{
if ((!m || !n) || (m == n))
return parent_rate; /* In bypass mode runs at same frequency */
return mult_frac(parent_rate, (unsigned long)n, (unsigned long)m);
}
static unsigned long cdce925_pll_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
/* Output frequency of PLL is Fout = (Fin/Pdiv)*(N/M) */
struct clk_cdce925_pll *data = to_clk_cdce925_pll(hw);
return cdce925_pll_calculate_rate(parent_rate, data->n, data->m);
}
static void cdce925_pll_find_rate(unsigned long rate,
unsigned long parent_rate, u16 *n, u16 *m)
{
unsigned long un;
unsigned long um;
unsigned long g;
if (rate <= parent_rate) {
/* Can always deliver parent_rate in bypass mode */
*n = 0;
*m = 0;
} else {
/* In PLL mode, need to apply min/max range */
if (rate < CDCE925_PLL_FREQUENCY_MIN)
rate = CDCE925_PLL_FREQUENCY_MIN;
else if (rate > CDCE925_PLL_FREQUENCY_MAX)
rate = CDCE925_PLL_FREQUENCY_MAX;
g = gcd(rate, parent_rate);
um = parent_rate / g;
un = rate / g;
/* When outside hw range, reduce to fit (rounding errors) */
while ((un > 4095) || (um > 511)) {
Annotation
- Immediate include surface: `linux/clk.h`, `linux/clk-provider.h`, `linux/delay.h`, `linux/module.h`, `linux/i2c.h`, `linux/regmap.h`, `linux/regulator/consumer.h`, `linux/slab.h`.
- Detected declarations: `struct clk_cdce925_chip_info`, `struct clk_cdce925_chip`, `struct clk_cdce925_output`, `struct clk_cdce925_pll`, `struct clk_cdce925_chip`, `function cdce925_pll_calculate_rate`, `function cdce925_pll_recalc_rate`, `function cdce925_pll_find_rate`, `function cdce925_pll_determine_rate`, `function cdce925_pll_set_rate`.
- Atlas domain: Driver Families / drivers/clk.
- Implementation status: source 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.