162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (c) 2017 MediaTek Inc. 462306a36Sopenharmony_ci * Author: Chen Zhong <chen.zhong@mediatek.com> 562306a36Sopenharmony_ci * Sean Wang <sean.wang@mediatek.com> 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/clk-provider.h> 962306a36Sopenharmony_ci#include <linux/of.h> 1062306a36Sopenharmony_ci#include <linux/of_address.h> 1162306a36Sopenharmony_ci#include <linux/of_platform.h> 1262306a36Sopenharmony_ci#include <linux/platform_device.h> 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#include "clk-mtk.h" 1562306a36Sopenharmony_ci#include "clk-gate.h" 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#include <dt-bindings/clock/mt7622-clk.h> 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#define GATE_AUDIO0(_id, _name, _parent, _shift) \ 2062306a36Sopenharmony_ci GATE_MTK(_id, _name, _parent, &audio0_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr) 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#define GATE_AUDIO1(_id, _name, _parent, _shift) \ 2362306a36Sopenharmony_ci GATE_MTK(_id, _name, _parent, &audio1_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr) 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci#define GATE_AUDIO2(_id, _name, _parent, _shift) \ 2662306a36Sopenharmony_ci GATE_MTK(_id, _name, _parent, &audio2_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr) 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci#define GATE_AUDIO3(_id, _name, _parent, _shift) \ 2962306a36Sopenharmony_ci GATE_MTK(_id, _name, _parent, &audio3_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr) 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_cistatic const struct mtk_gate_regs audio0_cg_regs = { 3262306a36Sopenharmony_ci .set_ofs = 0x0, 3362306a36Sopenharmony_ci .clr_ofs = 0x0, 3462306a36Sopenharmony_ci .sta_ofs = 0x0, 3562306a36Sopenharmony_ci}; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_cistatic const struct mtk_gate_regs audio1_cg_regs = { 3862306a36Sopenharmony_ci .set_ofs = 0x10, 3962306a36Sopenharmony_ci .clr_ofs = 0x10, 4062306a36Sopenharmony_ci .sta_ofs = 0x10, 4162306a36Sopenharmony_ci}; 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_cistatic const struct mtk_gate_regs audio2_cg_regs = { 4462306a36Sopenharmony_ci .set_ofs = 0x14, 4562306a36Sopenharmony_ci .clr_ofs = 0x14, 4662306a36Sopenharmony_ci .sta_ofs = 0x14, 4762306a36Sopenharmony_ci}; 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_cistatic const struct mtk_gate_regs audio3_cg_regs = { 5062306a36Sopenharmony_ci .set_ofs = 0x634, 5162306a36Sopenharmony_ci .clr_ofs = 0x634, 5262306a36Sopenharmony_ci .sta_ofs = 0x634, 5362306a36Sopenharmony_ci}; 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_cistatic const struct mtk_gate audio_clks[] = { 5662306a36Sopenharmony_ci /* AUDIO0 */ 5762306a36Sopenharmony_ci GATE_AUDIO0(CLK_AUDIO_AFE, "audio_afe", "rtc", 2), 5862306a36Sopenharmony_ci GATE_AUDIO0(CLK_AUDIO_HDMI, "audio_hdmi", "apll1_ck_sel", 20), 5962306a36Sopenharmony_ci GATE_AUDIO0(CLK_AUDIO_SPDF, "audio_spdf", "apll1_ck_sel", 21), 6062306a36Sopenharmony_ci GATE_AUDIO0(CLK_AUDIO_APLL, "audio_apll", "apll1_ck_sel", 23), 6162306a36Sopenharmony_ci /* AUDIO1 */ 6262306a36Sopenharmony_ci GATE_AUDIO1(CLK_AUDIO_I2SIN1, "audio_i2sin1", "a1sys_hp_sel", 0), 6362306a36Sopenharmony_ci GATE_AUDIO1(CLK_AUDIO_I2SIN2, "audio_i2sin2", "a1sys_hp_sel", 1), 6462306a36Sopenharmony_ci GATE_AUDIO1(CLK_AUDIO_I2SIN3, "audio_i2sin3", "a1sys_hp_sel", 2), 6562306a36Sopenharmony_ci GATE_AUDIO1(CLK_AUDIO_I2SIN4, "audio_i2sin4", "a1sys_hp_sel", 3), 6662306a36Sopenharmony_ci GATE_AUDIO1(CLK_AUDIO_I2SO1, "audio_i2so1", "a1sys_hp_sel", 6), 6762306a36Sopenharmony_ci GATE_AUDIO1(CLK_AUDIO_I2SO2, "audio_i2so2", "a1sys_hp_sel", 7), 6862306a36Sopenharmony_ci GATE_AUDIO1(CLK_AUDIO_I2SO3, "audio_i2so3", "a1sys_hp_sel", 8), 6962306a36Sopenharmony_ci GATE_AUDIO1(CLK_AUDIO_I2SO4, "audio_i2so4", "a1sys_hp_sel", 9), 7062306a36Sopenharmony_ci GATE_AUDIO1(CLK_AUDIO_ASRCI1, "audio_asrci1", "asm_h_sel", 12), 7162306a36Sopenharmony_ci GATE_AUDIO1(CLK_AUDIO_ASRCI2, "audio_asrci2", "asm_h_sel", 13), 7262306a36Sopenharmony_ci GATE_AUDIO1(CLK_AUDIO_ASRCO1, "audio_asrco1", "asm_h_sel", 14), 7362306a36Sopenharmony_ci GATE_AUDIO1(CLK_AUDIO_ASRCO2, "audio_asrco2", "asm_h_sel", 15), 7462306a36Sopenharmony_ci GATE_AUDIO1(CLK_AUDIO_INTDIR, "audio_intdir", "intdir_sel", 20), 7562306a36Sopenharmony_ci GATE_AUDIO1(CLK_AUDIO_A1SYS, "audio_a1sys", "a1sys_hp_sel", 21), 7662306a36Sopenharmony_ci GATE_AUDIO1(CLK_AUDIO_A2SYS, "audio_a2sys", "a2sys_hp_sel", 22), 7762306a36Sopenharmony_ci GATE_AUDIO1(CLK_AUDIO_AFE_CONN, "audio_afe_conn", "a1sys_hp_sel", 23), 7862306a36Sopenharmony_ci /* AUDIO2 */ 7962306a36Sopenharmony_ci GATE_AUDIO2(CLK_AUDIO_UL1, "audio_ul1", "a1sys_hp_sel", 0), 8062306a36Sopenharmony_ci GATE_AUDIO2(CLK_AUDIO_UL2, "audio_ul2", "a1sys_hp_sel", 1), 8162306a36Sopenharmony_ci GATE_AUDIO2(CLK_AUDIO_UL3, "audio_ul3", "a1sys_hp_sel", 2), 8262306a36Sopenharmony_ci GATE_AUDIO2(CLK_AUDIO_UL4, "audio_ul4", "a1sys_hp_sel", 3), 8362306a36Sopenharmony_ci GATE_AUDIO2(CLK_AUDIO_UL5, "audio_ul5", "a1sys_hp_sel", 4), 8462306a36Sopenharmony_ci GATE_AUDIO2(CLK_AUDIO_UL6, "audio_ul6", "a1sys_hp_sel", 5), 8562306a36Sopenharmony_ci GATE_AUDIO2(CLK_AUDIO_DL1, "audio_dl1", "a1sys_hp_sel", 6), 8662306a36Sopenharmony_ci GATE_AUDIO2(CLK_AUDIO_DL2, "audio_dl2", "a1sys_hp_sel", 7), 8762306a36Sopenharmony_ci GATE_AUDIO2(CLK_AUDIO_DL3, "audio_dl3", "a1sys_hp_sel", 8), 8862306a36Sopenharmony_ci GATE_AUDIO2(CLK_AUDIO_DL4, "audio_dl4", "a1sys_hp_sel", 9), 8962306a36Sopenharmony_ci GATE_AUDIO2(CLK_AUDIO_DL5, "audio_dl5", "a1sys_hp_sel", 10), 9062306a36Sopenharmony_ci GATE_AUDIO2(CLK_AUDIO_DL6, "audio_dl6", "a1sys_hp_sel", 11), 9162306a36Sopenharmony_ci GATE_AUDIO2(CLK_AUDIO_DLMCH, "audio_dlmch", "a1sys_hp_sel", 12), 9262306a36Sopenharmony_ci GATE_AUDIO2(CLK_AUDIO_ARB1, "audio_arb1", "a1sys_hp_sel", 13), 9362306a36Sopenharmony_ci GATE_AUDIO2(CLK_AUDIO_AWB, "audio_awb", "a1sys_hp_sel", 14), 9462306a36Sopenharmony_ci GATE_AUDIO2(CLK_AUDIO_AWB2, "audio_awb2", "a1sys_hp_sel", 15), 9562306a36Sopenharmony_ci GATE_AUDIO2(CLK_AUDIO_DAI, "audio_dai", "a1sys_hp_sel", 16), 9662306a36Sopenharmony_ci GATE_AUDIO2(CLK_AUDIO_MOD, "audio_mod", "a1sys_hp_sel", 17), 9762306a36Sopenharmony_ci /* AUDIO3 */ 9862306a36Sopenharmony_ci GATE_AUDIO3(CLK_AUDIO_ASRCI3, "audio_asrci3", "asm_h_sel", 2), 9962306a36Sopenharmony_ci GATE_AUDIO3(CLK_AUDIO_ASRCI4, "audio_asrci4", "asm_h_sel", 3), 10062306a36Sopenharmony_ci GATE_AUDIO3(CLK_AUDIO_ASRCO3, "audio_asrco3", "asm_h_sel", 6), 10162306a36Sopenharmony_ci GATE_AUDIO3(CLK_AUDIO_ASRCO4, "audio_asrco4", "asm_h_sel", 7), 10262306a36Sopenharmony_ci GATE_AUDIO3(CLK_AUDIO_MEM_ASRC1, "audio_mem_asrc1", "asm_h_sel", 10), 10362306a36Sopenharmony_ci GATE_AUDIO3(CLK_AUDIO_MEM_ASRC2, "audio_mem_asrc2", "asm_h_sel", 11), 10462306a36Sopenharmony_ci GATE_AUDIO3(CLK_AUDIO_MEM_ASRC3, "audio_mem_asrc3", "asm_h_sel", 12), 10562306a36Sopenharmony_ci GATE_AUDIO3(CLK_AUDIO_MEM_ASRC4, "audio_mem_asrc4", "asm_h_sel", 13), 10662306a36Sopenharmony_ci GATE_AUDIO3(CLK_AUDIO_MEM_ASRC5, "audio_mem_asrc5", "asm_h_sel", 14), 10762306a36Sopenharmony_ci}; 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_cistatic const struct mtk_clk_desc audio_desc = { 11062306a36Sopenharmony_ci .clks = audio_clks, 11162306a36Sopenharmony_ci .num_clks = ARRAY_SIZE(audio_clks), 11262306a36Sopenharmony_ci}; 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_cistatic int clk_mt7622_aud_probe(struct platform_device *pdev) 11562306a36Sopenharmony_ci{ 11662306a36Sopenharmony_ci int r; 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci r = mtk_clk_simple_probe(pdev); 11962306a36Sopenharmony_ci if (r) { 12062306a36Sopenharmony_ci dev_err(&pdev->dev, 12162306a36Sopenharmony_ci "could not register clock provider: %s: %d\n", 12262306a36Sopenharmony_ci pdev->name, r); 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci return r; 12562306a36Sopenharmony_ci } 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci r = devm_of_platform_populate(&pdev->dev); 12862306a36Sopenharmony_ci if (r) 12962306a36Sopenharmony_ci goto err_plat_populate; 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci return 0; 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_cierr_plat_populate: 13462306a36Sopenharmony_ci mtk_clk_simple_remove(pdev); 13562306a36Sopenharmony_ci return r; 13662306a36Sopenharmony_ci} 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_cistatic void clk_mt7622_aud_remove(struct platform_device *pdev) 13962306a36Sopenharmony_ci{ 14062306a36Sopenharmony_ci of_platform_depopulate(&pdev->dev); 14162306a36Sopenharmony_ci mtk_clk_simple_remove(pdev); 14262306a36Sopenharmony_ci} 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_cistatic const struct of_device_id of_match_clk_mt7622_aud[] = { 14562306a36Sopenharmony_ci { .compatible = "mediatek,mt7622-audsys", .data = &audio_desc }, 14662306a36Sopenharmony_ci { /* sentinel */ } 14762306a36Sopenharmony_ci}; 14862306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, of_match_clk_mt7622_aud); 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_cistatic struct platform_driver clk_mt7622_aud_drv = { 15162306a36Sopenharmony_ci .probe = clk_mt7622_aud_probe, 15262306a36Sopenharmony_ci .remove_new = clk_mt7622_aud_remove, 15362306a36Sopenharmony_ci .driver = { 15462306a36Sopenharmony_ci .name = "clk-mt7622-aud", 15562306a36Sopenharmony_ci .of_match_table = of_match_clk_mt7622_aud, 15662306a36Sopenharmony_ci }, 15762306a36Sopenharmony_ci}; 15862306a36Sopenharmony_cimodule_platform_driver(clk_mt7622_aud_drv); 15962306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 160