1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright (c) 2017 MediaTek Inc. |
4 | * Author: Chen Zhong <chen.zhong@mediatek.com> |
5 | * Sean Wang <sean.wang@mediatek.com> |
6 | */ |
7 | |
8 | #include <linux/clk-provider.h> |
9 | #include <linux/of.h> |
10 | #include <linux/of_address.h> |
11 | #include <linux/of_platform.h> |
12 | #include <linux/platform_device.h> |
13 | |
14 | #include "clk-mtk.h" |
15 | #include "clk-gate.h" |
16 | |
17 | #include <dt-bindings/clock/mt7622-clk.h> |
18 | |
19 | #define GATE_AUDIO0(_id, _name, _parent, _shift) \ |
20 | GATE_MTK(_id, _name, _parent, &audio0_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr) |
21 | |
22 | #define GATE_AUDIO1(_id, _name, _parent, _shift) \ |
23 | GATE_MTK(_id, _name, _parent, &audio1_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr) |
24 | |
25 | #define GATE_AUDIO2(_id, _name, _parent, _shift) \ |
26 | GATE_MTK(_id, _name, _parent, &audio2_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr) |
27 | |
28 | #define GATE_AUDIO3(_id, _name, _parent, _shift) \ |
29 | GATE_MTK(_id, _name, _parent, &audio3_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr) |
30 | |
31 | static const struct mtk_gate_regs audio0_cg_regs = { |
32 | .set_ofs = 0x0, |
33 | .clr_ofs = 0x0, |
34 | .sta_ofs = 0x0, |
35 | }; |
36 | |
37 | static const struct mtk_gate_regs audio1_cg_regs = { |
38 | .set_ofs = 0x10, |
39 | .clr_ofs = 0x10, |
40 | .sta_ofs = 0x10, |
41 | }; |
42 | |
43 | static const struct mtk_gate_regs audio2_cg_regs = { |
44 | .set_ofs = 0x14, |
45 | .clr_ofs = 0x14, |
46 | .sta_ofs = 0x14, |
47 | }; |
48 | |
49 | static const struct mtk_gate_regs audio3_cg_regs = { |
50 | .set_ofs = 0x634, |
51 | .clr_ofs = 0x634, |
52 | .sta_ofs = 0x634, |
53 | }; |
54 | |
55 | static const struct mtk_gate audio_clks[] = { |
56 | /* AUDIO0 */ |
57 | GATE_AUDIO0(CLK_AUDIO_AFE, "audio_afe" , "rtc" , 2), |
58 | GATE_AUDIO0(CLK_AUDIO_HDMI, "audio_hdmi" , "apll1_ck_sel" , 20), |
59 | GATE_AUDIO0(CLK_AUDIO_SPDF, "audio_spdf" , "apll1_ck_sel" , 21), |
60 | GATE_AUDIO0(CLK_AUDIO_APLL, "audio_apll" , "apll1_ck_sel" , 23), |
61 | /* AUDIO1 */ |
62 | GATE_AUDIO1(CLK_AUDIO_I2SIN1, "audio_i2sin1" , "a1sys_hp_sel" , 0), |
63 | GATE_AUDIO1(CLK_AUDIO_I2SIN2, "audio_i2sin2" , "a1sys_hp_sel" , 1), |
64 | GATE_AUDIO1(CLK_AUDIO_I2SIN3, "audio_i2sin3" , "a1sys_hp_sel" , 2), |
65 | GATE_AUDIO1(CLK_AUDIO_I2SIN4, "audio_i2sin4" , "a1sys_hp_sel" , 3), |
66 | GATE_AUDIO1(CLK_AUDIO_I2SO1, "audio_i2so1" , "a1sys_hp_sel" , 6), |
67 | GATE_AUDIO1(CLK_AUDIO_I2SO2, "audio_i2so2" , "a1sys_hp_sel" , 7), |
68 | GATE_AUDIO1(CLK_AUDIO_I2SO3, "audio_i2so3" , "a1sys_hp_sel" , 8), |
69 | GATE_AUDIO1(CLK_AUDIO_I2SO4, "audio_i2so4" , "a1sys_hp_sel" , 9), |
70 | GATE_AUDIO1(CLK_AUDIO_ASRCI1, "audio_asrci1" , "asm_h_sel" , 12), |
71 | GATE_AUDIO1(CLK_AUDIO_ASRCI2, "audio_asrci2" , "asm_h_sel" , 13), |
72 | GATE_AUDIO1(CLK_AUDIO_ASRCO1, "audio_asrco1" , "asm_h_sel" , 14), |
73 | GATE_AUDIO1(CLK_AUDIO_ASRCO2, "audio_asrco2" , "asm_h_sel" , 15), |
74 | GATE_AUDIO1(CLK_AUDIO_INTDIR, "audio_intdir" , "intdir_sel" , 20), |
75 | GATE_AUDIO1(CLK_AUDIO_A1SYS, "audio_a1sys" , "a1sys_hp_sel" , 21), |
76 | GATE_AUDIO1(CLK_AUDIO_A2SYS, "audio_a2sys" , "a2sys_hp_sel" , 22), |
77 | GATE_AUDIO1(CLK_AUDIO_AFE_CONN, "audio_afe_conn" , "a1sys_hp_sel" , 23), |
78 | /* AUDIO2 */ |
79 | GATE_AUDIO2(CLK_AUDIO_UL1, "audio_ul1" , "a1sys_hp_sel" , 0), |
80 | GATE_AUDIO2(CLK_AUDIO_UL2, "audio_ul2" , "a1sys_hp_sel" , 1), |
81 | GATE_AUDIO2(CLK_AUDIO_UL3, "audio_ul3" , "a1sys_hp_sel" , 2), |
82 | GATE_AUDIO2(CLK_AUDIO_UL4, "audio_ul4" , "a1sys_hp_sel" , 3), |
83 | GATE_AUDIO2(CLK_AUDIO_UL5, "audio_ul5" , "a1sys_hp_sel" , 4), |
84 | GATE_AUDIO2(CLK_AUDIO_UL6, "audio_ul6" , "a1sys_hp_sel" , 5), |
85 | GATE_AUDIO2(CLK_AUDIO_DL1, "audio_dl1" , "a1sys_hp_sel" , 6), |
86 | GATE_AUDIO2(CLK_AUDIO_DL2, "audio_dl2" , "a1sys_hp_sel" , 7), |
87 | GATE_AUDIO2(CLK_AUDIO_DL3, "audio_dl3" , "a1sys_hp_sel" , 8), |
88 | GATE_AUDIO2(CLK_AUDIO_DL4, "audio_dl4" , "a1sys_hp_sel" , 9), |
89 | GATE_AUDIO2(CLK_AUDIO_DL5, "audio_dl5" , "a1sys_hp_sel" , 10), |
90 | GATE_AUDIO2(CLK_AUDIO_DL6, "audio_dl6" , "a1sys_hp_sel" , 11), |
91 | GATE_AUDIO2(CLK_AUDIO_DLMCH, "audio_dlmch" , "a1sys_hp_sel" , 12), |
92 | GATE_AUDIO2(CLK_AUDIO_ARB1, "audio_arb1" , "a1sys_hp_sel" , 13), |
93 | GATE_AUDIO2(CLK_AUDIO_AWB, "audio_awb" , "a1sys_hp_sel" , 14), |
94 | GATE_AUDIO2(CLK_AUDIO_AWB2, "audio_awb2" , "a1sys_hp_sel" , 15), |
95 | GATE_AUDIO2(CLK_AUDIO_DAI, "audio_dai" , "a1sys_hp_sel" , 16), |
96 | GATE_AUDIO2(CLK_AUDIO_MOD, "audio_mod" , "a1sys_hp_sel" , 17), |
97 | /* AUDIO3 */ |
98 | GATE_AUDIO3(CLK_AUDIO_ASRCI3, "audio_asrci3" , "asm_h_sel" , 2), |
99 | GATE_AUDIO3(CLK_AUDIO_ASRCI4, "audio_asrci4" , "asm_h_sel" , 3), |
100 | GATE_AUDIO3(CLK_AUDIO_ASRCO3, "audio_asrco3" , "asm_h_sel" , 6), |
101 | GATE_AUDIO3(CLK_AUDIO_ASRCO4, "audio_asrco4" , "asm_h_sel" , 7), |
102 | GATE_AUDIO3(CLK_AUDIO_MEM_ASRC1, "audio_mem_asrc1" , "asm_h_sel" , 10), |
103 | GATE_AUDIO3(CLK_AUDIO_MEM_ASRC2, "audio_mem_asrc2" , "asm_h_sel" , 11), |
104 | GATE_AUDIO3(CLK_AUDIO_MEM_ASRC3, "audio_mem_asrc3" , "asm_h_sel" , 12), |
105 | GATE_AUDIO3(CLK_AUDIO_MEM_ASRC4, "audio_mem_asrc4" , "asm_h_sel" , 13), |
106 | GATE_AUDIO3(CLK_AUDIO_MEM_ASRC5, "audio_mem_asrc5" , "asm_h_sel" , 14), |
107 | }; |
108 | |
109 | static const struct mtk_clk_desc audio_desc = { |
110 | .clks = audio_clks, |
111 | .num_clks = ARRAY_SIZE(audio_clks), |
112 | }; |
113 | |
114 | static int clk_mt7622_aud_probe(struct platform_device *pdev) |
115 | { |
116 | int r; |
117 | |
118 | r = mtk_clk_simple_probe(pdev); |
119 | if (r) { |
120 | dev_err(&pdev->dev, |
121 | "could not register clock provider: %s: %d\n" , |
122 | pdev->name, r); |
123 | |
124 | return r; |
125 | } |
126 | |
127 | r = devm_of_platform_populate(dev: &pdev->dev); |
128 | if (r) |
129 | goto err_plat_populate; |
130 | |
131 | return 0; |
132 | |
133 | err_plat_populate: |
134 | mtk_clk_simple_remove(pdev); |
135 | return r; |
136 | } |
137 | |
138 | static void clk_mt7622_aud_remove(struct platform_device *pdev) |
139 | { |
140 | of_platform_depopulate(parent: &pdev->dev); |
141 | mtk_clk_simple_remove(pdev); |
142 | } |
143 | |
144 | static const struct of_device_id of_match_clk_mt7622_aud[] = { |
145 | { .compatible = "mediatek,mt7622-audsys" , .data = &audio_desc }, |
146 | { /* sentinel */ } |
147 | }; |
148 | MODULE_DEVICE_TABLE(of, of_match_clk_mt7622_aud); |
149 | |
150 | static struct platform_driver clk_mt7622_aud_drv = { |
151 | .probe = clk_mt7622_aud_probe, |
152 | .remove_new = clk_mt7622_aud_remove, |
153 | .driver = { |
154 | .name = "clk-mt7622-aud" , |
155 | .of_match_table = of_match_clk_mt7622_aud, |
156 | }, |
157 | }; |
158 | module_platform_driver(clk_mt7622_aud_drv); |
159 | MODULE_LICENSE("GPL" ); |
160 | |