1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2018 Microchip Technology Inc,
4 * Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
9 #include <linux/clk-provider.h>
11 #include <linux/mfd/syscon.h>
12 #include <linux/regmap.h>
13 #include <linux/slab.h>
15 #include <soc/at91/atmel-sfr.h>
21 struct regmap
*regmap
;
25 #define to_clk_i2s_mux(hw) container_of(hw, struct clk_i2s_mux, hw)
27 static u8
clk_i2s_mux_get_parent(struct clk_hw
*hw
)
29 struct clk_i2s_mux
*mux
= to_clk_i2s_mux(hw
);
32 regmap_read(mux
->regmap
, AT91_SFR_I2SCLKSEL
, &val
);
34 return (val
& BIT(mux
->bus_id
)) >> mux
->bus_id
;
37 static int clk_i2s_mux_set_parent(struct clk_hw
*hw
, u8 index
)
39 struct clk_i2s_mux
*mux
= to_clk_i2s_mux(hw
);
41 return regmap_update_bits(mux
->regmap
, AT91_SFR_I2SCLKSEL
,
42 BIT(mux
->bus_id
), index
<< mux
->bus_id
);
45 static const struct clk_ops clk_i2s_mux_ops
= {
46 .get_parent
= clk_i2s_mux_get_parent
,
47 .set_parent
= clk_i2s_mux_set_parent
,
48 .determine_rate
= __clk_mux_determine_rate
,
51 struct clk_hw
* __init
52 at91_clk_i2s_mux_register(struct regmap
*regmap
, const char *name
,
53 const char * const *parent_names
,
54 unsigned int num_parents
, u8 bus_id
)
56 struct clk_init_data init
= {};
57 struct clk_i2s_mux
*i2s_ck
;
60 i2s_ck
= kzalloc(sizeof(*i2s_ck
), GFP_KERNEL
);
62 return ERR_PTR(-ENOMEM
);
65 init
.ops
= &clk_i2s_mux_ops
;
66 init
.parent_names
= parent_names
;
67 init
.num_parents
= num_parents
;
69 i2s_ck
->hw
.init
= &init
;
70 i2s_ck
->bus_id
= bus_id
;
71 i2s_ck
->regmap
= regmap
;
73 ret
= clk_hw_register(NULL
, &i2s_ck
->hw
);