1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Copyright (c) 2018 MediaTek Inc. |
4 | * Author: Ryder Lee <ryder.lee@mediatek.com> |
5 | */ |
6 | |
7 | #include <linux/clk-provider.h> |
8 | #include <linux/of.h> |
9 | #include <linux/of_address.h> |
10 | #include <linux/of_platform.h> |
11 | #include <linux/platform_device.h> |
12 | |
13 | #include "clk-mtk.h" |
14 | #include "clk-gate.h" |
15 | |
16 | #include <dt-bindings/clock/mt2701-clk.h> |
17 | |
18 | #define GATE_AUDIO0(_id, _name, _parent, _shift) \ |
19 | GATE_MTK(_id, _name, _parent, &audio0_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr) |
20 | |
21 | #define GATE_AUDIO1(_id, _name, _parent, _shift) \ |
22 | GATE_MTK(_id, _name, _parent, &audio1_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr) |
23 | |
24 | #define GATE_AUDIO2(_id, _name, _parent, _shift) \ |
25 | GATE_MTK(_id, _name, _parent, &audio2_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr) |
26 | |
27 | #define GATE_AUDIO3(_id, _name, _parent, _shift) \ |
28 | GATE_MTK(_id, _name, _parent, &audio3_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr) |
29 | |
30 | static const struct mtk_gate_regs audio0_cg_regs = { |
31 | .set_ofs = 0x0, |
32 | .clr_ofs = 0x0, |
33 | .sta_ofs = 0x0, |
34 | }; |
35 | |
36 | static const struct mtk_gate_regs audio1_cg_regs = { |
37 | .set_ofs = 0x10, |
38 | .clr_ofs = 0x10, |
39 | .sta_ofs = 0x10, |
40 | }; |
41 | |
42 | static const struct mtk_gate_regs audio2_cg_regs = { |
43 | .set_ofs = 0x14, |
44 | .clr_ofs = 0x14, |
45 | .sta_ofs = 0x14, |
46 | }; |
47 | |
48 | static const struct mtk_gate_regs audio3_cg_regs = { |
49 | .set_ofs = 0x634, |
50 | .clr_ofs = 0x634, |
51 | .sta_ofs = 0x634, |
52 | }; |
53 | |
54 | static const struct mtk_gate audio_clks[] = { |
55 | GATE_DUMMY(CLK_DUMMY, "aud_dummy" ), |
56 | /* AUDIO0 */ |
57 | GATE_AUDIO0(CLK_AUD_AFE, "audio_afe" , "aud_intbus_sel" , 2), |
58 | GATE_AUDIO0(CLK_AUD_HDMI, "audio_hdmi" , "audpll_sel" , 20), |
59 | GATE_AUDIO0(CLK_AUD_SPDF, "audio_spdf" , "audpll_sel" , 21), |
60 | GATE_AUDIO0(CLK_AUD_SPDF2, "audio_spdf2" , "audpll_sel" , 22), |
61 | GATE_AUDIO0(CLK_AUD_APLL, "audio_apll" , "audpll_sel" , 23), |
62 | /* AUDIO1 */ |
63 | GATE_AUDIO1(CLK_AUD_I2SIN1, "audio_i2sin1" , "aud_mux1_sel" , 0), |
64 | GATE_AUDIO1(CLK_AUD_I2SIN2, "audio_i2sin2" , "aud_mux1_sel" , 1), |
65 | GATE_AUDIO1(CLK_AUD_I2SIN3, "audio_i2sin3" , "aud_mux1_sel" , 2), |
66 | GATE_AUDIO1(CLK_AUD_I2SIN4, "audio_i2sin4" , "aud_mux1_sel" , 3), |
67 | GATE_AUDIO1(CLK_AUD_I2SIN5, "audio_i2sin5" , "aud_mux1_sel" , 4), |
68 | GATE_AUDIO1(CLK_AUD_I2SIN6, "audio_i2sin6" , "aud_mux1_sel" , 5), |
69 | GATE_AUDIO1(CLK_AUD_I2SO1, "audio_i2so1" , "aud_mux1_sel" , 6), |
70 | GATE_AUDIO1(CLK_AUD_I2SO2, "audio_i2so2" , "aud_mux1_sel" , 7), |
71 | GATE_AUDIO1(CLK_AUD_I2SO3, "audio_i2so3" , "aud_mux1_sel" , 8), |
72 | GATE_AUDIO1(CLK_AUD_I2SO4, "audio_i2so4" , "aud_mux1_sel" , 9), |
73 | GATE_AUDIO1(CLK_AUD_I2SO5, "audio_i2so5" , "aud_mux1_sel" , 10), |
74 | GATE_AUDIO1(CLK_AUD_I2SO6, "audio_i2so6" , "aud_mux1_sel" , 11), |
75 | GATE_AUDIO1(CLK_AUD_ASRCI1, "audio_asrci1" , "asm_h_sel" , 12), |
76 | GATE_AUDIO1(CLK_AUD_ASRCI2, "audio_asrci2" , "asm_h_sel" , 13), |
77 | GATE_AUDIO1(CLK_AUD_ASRCO1, "audio_asrco1" , "asm_h_sel" , 14), |
78 | GATE_AUDIO1(CLK_AUD_ASRCO2, "audio_asrco2" , "asm_h_sel" , 15), |
79 | GATE_AUDIO1(CLK_AUD_INTDIR, "audio_intdir" , "intdir_sel" , 20), |
80 | GATE_AUDIO1(CLK_AUD_A1SYS, "audio_a1sys" , "aud_mux1_sel" , 21), |
81 | GATE_AUDIO1(CLK_AUD_A2SYS, "audio_a2sys" , "aud_mux2_sel" , 22), |
82 | GATE_AUDIO1(CLK_AUD_AFE_CONN, "audio_afe_conn" , "aud_mux1_sel" , 23), |
83 | GATE_AUDIO1(CLK_AUD_AFE_MRGIF, "audio_afe_mrgif" , "aud_mux1_sel" , 25), |
84 | /* AUDIO2 */ |
85 | GATE_AUDIO2(CLK_AUD_MMIF_UL1, "audio_ul1" , "aud_mux1_sel" , 0), |
86 | GATE_AUDIO2(CLK_AUD_MMIF_UL2, "audio_ul2" , "aud_mux1_sel" , 1), |
87 | GATE_AUDIO2(CLK_AUD_MMIF_UL3, "audio_ul3" , "aud_mux1_sel" , 2), |
88 | GATE_AUDIO2(CLK_AUD_MMIF_UL4, "audio_ul4" , "aud_mux1_sel" , 3), |
89 | GATE_AUDIO2(CLK_AUD_MMIF_UL5, "audio_ul5" , "aud_mux1_sel" , 4), |
90 | GATE_AUDIO2(CLK_AUD_MMIF_UL6, "audio_ul6" , "aud_mux1_sel" , 5), |
91 | GATE_AUDIO2(CLK_AUD_MMIF_DL1, "audio_dl1" , "aud_mux1_sel" , 6), |
92 | GATE_AUDIO2(CLK_AUD_MMIF_DL2, "audio_dl2" , "aud_mux1_sel" , 7), |
93 | GATE_AUDIO2(CLK_AUD_MMIF_DL3, "audio_dl3" , "aud_mux1_sel" , 8), |
94 | GATE_AUDIO2(CLK_AUD_MMIF_DL4, "audio_dl4" , "aud_mux1_sel" , 9), |
95 | GATE_AUDIO2(CLK_AUD_MMIF_DL5, "audio_dl5" , "aud_mux1_sel" , 10), |
96 | GATE_AUDIO2(CLK_AUD_MMIF_DL6, "audio_dl6" , "aud_mux1_sel" , 11), |
97 | GATE_AUDIO2(CLK_AUD_MMIF_DLMCH, "audio_dlmch" , "aud_mux1_sel" , 12), |
98 | GATE_AUDIO2(CLK_AUD_MMIF_ARB1, "audio_arb1" , "aud_mux1_sel" , 13), |
99 | GATE_AUDIO2(CLK_AUD_MMIF_AWB1, "audio_awb" , "aud_mux1_sel" , 14), |
100 | GATE_AUDIO2(CLK_AUD_MMIF_AWB2, "audio_awb2" , "aud_mux1_sel" , 15), |
101 | GATE_AUDIO2(CLK_AUD_MMIF_DAI, "audio_dai" , "aud_mux1_sel" , 16), |
102 | /* AUDIO3 */ |
103 | GATE_AUDIO3(CLK_AUD_ASRCI3, "audio_asrci3" , "asm_h_sel" , 2), |
104 | GATE_AUDIO3(CLK_AUD_ASRCI4, "audio_asrci4" , "asm_h_sel" , 3), |
105 | GATE_AUDIO3(CLK_AUD_ASRCI5, "audio_asrci5" , "asm_h_sel" , 4), |
106 | GATE_AUDIO3(CLK_AUD_ASRCI6, "audio_asrci6" , "asm_h_sel" , 5), |
107 | GATE_AUDIO3(CLK_AUD_ASRCO3, "audio_asrco3" , "asm_h_sel" , 6), |
108 | GATE_AUDIO3(CLK_AUD_ASRCO4, "audio_asrco4" , "asm_h_sel" , 7), |
109 | GATE_AUDIO3(CLK_AUD_ASRCO5, "audio_asrco5" , "asm_h_sel" , 8), |
110 | GATE_AUDIO3(CLK_AUD_ASRCO6, "audio_asrco6" , "asm_h_sel" , 9), |
111 | GATE_AUDIO3(CLK_AUD_MEM_ASRC1, "audio_mem_asrc1" , "asm_h_sel" , 10), |
112 | GATE_AUDIO3(CLK_AUD_MEM_ASRC2, "audio_mem_asrc2" , "asm_h_sel" , 11), |
113 | GATE_AUDIO3(CLK_AUD_MEM_ASRC3, "audio_mem_asrc3" , "asm_h_sel" , 12), |
114 | GATE_AUDIO3(CLK_AUD_MEM_ASRC4, "audio_mem_asrc4" , "asm_h_sel" , 13), |
115 | GATE_AUDIO3(CLK_AUD_MEM_ASRC5, "audio_mem_asrc5" , "asm_h_sel" , 14), |
116 | }; |
117 | |
118 | static const struct mtk_clk_desc audio_desc = { |
119 | .clks = audio_clks, |
120 | .num_clks = ARRAY_SIZE(audio_clks), |
121 | }; |
122 | |
123 | static const struct of_device_id of_match_clk_mt2701_aud[] = { |
124 | { .compatible = "mediatek,mt2701-audsys" , .data = &audio_desc }, |
125 | { /* sentinel */ } |
126 | }; |
127 | MODULE_DEVICE_TABLE(of, of_match_clk_mt2701_aud); |
128 | |
129 | static int clk_mt2701_aud_probe(struct platform_device *pdev) |
130 | { |
131 | int r; |
132 | |
133 | r = mtk_clk_simple_probe(pdev); |
134 | if (r) { |
135 | dev_err(&pdev->dev, |
136 | "could not register clock provider: %s: %d\n" , |
137 | pdev->name, r); |
138 | |
139 | return r; |
140 | } |
141 | |
142 | r = devm_of_platform_populate(dev: &pdev->dev); |
143 | if (r) |
144 | goto err_plat_populate; |
145 | |
146 | return 0; |
147 | |
148 | err_plat_populate: |
149 | mtk_clk_simple_remove(pdev); |
150 | return r; |
151 | } |
152 | |
153 | static void clk_mt2701_aud_remove(struct platform_device *pdev) |
154 | { |
155 | of_platform_depopulate(parent: &pdev->dev); |
156 | mtk_clk_simple_remove(pdev); |
157 | } |
158 | |
159 | static struct platform_driver clk_mt2701_aud_drv = { |
160 | .probe = clk_mt2701_aud_probe, |
161 | .remove_new = clk_mt2701_aud_remove, |
162 | .driver = { |
163 | .name = "clk-mt2701-aud" , |
164 | .of_match_table = of_match_clk_mt2701_aud, |
165 | }, |
166 | }; |
167 | module_platform_driver(clk_mt2701_aud_drv); |
168 | MODULE_LICENSE("GPL" ); |
169 | |