1 // SPDX-License-Identifier: GPL-2.0 1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (c) 2020, Linaro Limited 2 // Copyright (c) 2020, Linaro Limited 3 3 4 #include <dt-bindings/sound/qcom,q6afe.h> << 5 #include <linux/err.h> 4 #include <linux/err.h> 6 #include <linux/init.h> 5 #include <linux/init.h> 7 #include <linux/clk-provider.h> 6 #include <linux/clk-provider.h> 8 #include <linux/module.h> 7 #include <linux/module.h> 9 #include <linux/device.h> 8 #include <linux/device.h> 10 #include <linux/platform_device.h> 9 #include <linux/platform_device.h> 11 #include "q6dsp-lpass-clocks.h" !! 10 #include <linux/of.h> >> 11 #include <linux/slab.h> 12 #include "q6afe.h" 12 #include "q6afe.h" 13 13 14 #define Q6AFE_CLK(id) { !! 14 #define Q6AFE_CLK(id) &(struct q6afe_clk) { \ 15 .clk_id = id, 15 .clk_id = id, \ 16 .q6dsp_clk_id = Q6AFE_##id, !! 16 .afe_clk_id = Q6AFE_##id, \ 17 .name = #id, 17 .name = #id, \ >> 18 .attributes = LPASS_CLK_ATTRIBUTE_COUPLE_NO, \ 18 .rate = 19200000, 19 .rate = 19200000, \ >> 20 .hw.init = &(struct clk_init_data) { \ >> 21 .ops = &clk_q6afe_ops, \ >> 22 .name = #id, \ >> 23 }, \ 19 } 24 } 20 25 >> 26 #define Q6AFE_VOTE_CLK(id, blkid, n) &(struct q6afe_clk) { \ >> 27 .clk_id = id, \ >> 28 .afe_clk_id = blkid, \ >> 29 .name = #n, \ >> 30 .hw.init = &(struct clk_init_data) { \ >> 31 .ops = &clk_vote_q6afe_ops, \ >> 32 .name = #id, \ >> 33 }, \ >> 34 } >> 35 >> 36 struct q6afe_clk { >> 37 struct device *dev; >> 38 int clk_id; >> 39 int afe_clk_id; >> 40 char *name; >> 41 int attributes; >> 42 int rate; >> 43 uint32_t handle; >> 44 struct clk_hw hw; >> 45 }; >> 46 >> 47 #define to_q6afe_clk(_hw) container_of(_hw, struct q6afe_clk, hw) >> 48 >> 49 struct q6afe_cc { >> 50 struct device *dev; >> 51 struct q6afe_clk **clks; >> 52 int num_clks; >> 53 }; >> 54 >> 55 static int clk_q6afe_prepare(struct clk_hw *hw) >> 56 { >> 57 struct q6afe_clk *clk = to_q6afe_clk(hw); >> 58 >> 59 return q6afe_set_lpass_clock(clk->dev, clk->afe_clk_id, clk->attributes, >> 60 Q6AFE_LPASS_CLK_ROOT_DEFAULT, clk->rate); >> 61 } >> 62 >> 63 static void clk_q6afe_unprepare(struct clk_hw *hw) >> 64 { >> 65 struct q6afe_clk *clk = to_q6afe_clk(hw); >> 66 >> 67 q6afe_set_lpass_clock(clk->dev, clk->afe_clk_id, clk->attributes, >> 68 Q6AFE_LPASS_CLK_ROOT_DEFAULT, 0); >> 69 } >> 70 >> 71 static int clk_q6afe_set_rate(struct clk_hw *hw, unsigned long rate, >> 72 unsigned long parent_rate) >> 73 { >> 74 struct q6afe_clk *clk = to_q6afe_clk(hw); >> 75 >> 76 clk->rate = rate; >> 77 >> 78 return 0; >> 79 } >> 80 >> 81 static unsigned long clk_q6afe_recalc_rate(struct clk_hw *hw, >> 82 unsigned long parent_rate) >> 83 { >> 84 struct q6afe_clk *clk = to_q6afe_clk(hw); >> 85 >> 86 return clk->rate; >> 87 } >> 88 >> 89 static long clk_q6afe_round_rate(struct clk_hw *hw, unsigned long rate, >> 90 unsigned long *parent_rate) >> 91 { >> 92 return rate; >> 93 } >> 94 >> 95 static const struct clk_ops clk_q6afe_ops = { >> 96 .prepare = clk_q6afe_prepare, >> 97 .unprepare = clk_q6afe_unprepare, >> 98 .set_rate = clk_q6afe_set_rate, >> 99 .round_rate = clk_q6afe_round_rate, >> 100 .recalc_rate = clk_q6afe_recalc_rate, >> 101 }; >> 102 >> 103 static int clk_vote_q6afe_block(struct clk_hw *hw) >> 104 { >> 105 struct q6afe_clk *clk = to_q6afe_clk(hw); 21 106 22 static const struct q6dsp_clk_init q6afe_clks[ !! 107 return q6afe_vote_lpass_core_hw(clk->dev, clk->afe_clk_id, 23 Q6AFE_CLK(LPASS_CLK_ID_PRI_MI2S_IBIT), !! 108 clk->name, &clk->handle); 24 Q6AFE_CLK(LPASS_CLK_ID_PRI_MI2S_EBIT), !! 109 } 25 Q6AFE_CLK(LPASS_CLK_ID_SEC_MI2S_IBIT), !! 110 26 Q6AFE_CLK(LPASS_CLK_ID_SEC_MI2S_EBIT), !! 111 static void clk_unvote_q6afe_block(struct clk_hw *hw) 27 Q6AFE_CLK(LPASS_CLK_ID_TER_MI2S_IBIT), !! 112 { 28 Q6AFE_CLK(LPASS_CLK_ID_TER_MI2S_EBIT), !! 113 struct q6afe_clk *clk = to_q6afe_clk(hw); 29 Q6AFE_CLK(LPASS_CLK_ID_QUAD_MI2S_IBIT) !! 114 30 Q6AFE_CLK(LPASS_CLK_ID_QUAD_MI2S_EBIT) !! 115 q6afe_unvote_lpass_core_hw(clk->dev, clk->afe_clk_id, clk->handle); 31 Q6AFE_CLK(LPASS_CLK_ID_SPEAKER_I2S_IBI !! 116 } 32 Q6AFE_CLK(LPASS_CLK_ID_SPEAKER_I2S_EBI !! 117 33 Q6AFE_CLK(LPASS_CLK_ID_SPEAKER_I2S_OSR !! 118 static const struct clk_ops clk_vote_q6afe_ops = { 34 Q6AFE_CLK(LPASS_CLK_ID_QUI_MI2S_IBIT), !! 119 .prepare = clk_vote_q6afe_block, 35 Q6AFE_CLK(LPASS_CLK_ID_QUI_MI2S_EBIT), !! 120 .unprepare = clk_unvote_q6afe_block, 36 Q6AFE_CLK(LPASS_CLK_ID_SEN_MI2S_IBIT), !! 121 }; 37 Q6AFE_CLK(LPASS_CLK_ID_SEN_MI2S_EBIT), !! 122 38 Q6AFE_CLK(LPASS_CLK_ID_INT0_MI2S_IBIT) !! 123 struct q6afe_clk *q6afe_clks[Q6AFE_MAX_CLK_ID] = { 39 Q6AFE_CLK(LPASS_CLK_ID_INT1_MI2S_IBIT) !! 124 [LPASS_CLK_ID_PRI_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_PRI_MI2S_IBIT), 40 Q6AFE_CLK(LPASS_CLK_ID_INT2_MI2S_IBIT) !! 125 [LPASS_CLK_ID_PRI_MI2S_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_PRI_MI2S_EBIT), 41 Q6AFE_CLK(LPASS_CLK_ID_INT3_MI2S_IBIT) !! 126 [LPASS_CLK_ID_SEC_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_SEC_MI2S_IBIT), 42 Q6AFE_CLK(LPASS_CLK_ID_INT4_MI2S_IBIT) !! 127 [LPASS_CLK_ID_SEC_MI2S_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_SEC_MI2S_EBIT), 43 Q6AFE_CLK(LPASS_CLK_ID_INT5_MI2S_IBIT) !! 128 [LPASS_CLK_ID_TER_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_TER_MI2S_IBIT), 44 Q6AFE_CLK(LPASS_CLK_ID_INT6_MI2S_IBIT) !! 129 [LPASS_CLK_ID_TER_MI2S_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_TER_MI2S_EBIT), 45 Q6AFE_CLK(LPASS_CLK_ID_QUI_MI2S_OSR), !! 130 [LPASS_CLK_ID_QUAD_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUAD_MI2S_IBIT), 46 Q6AFE_CLK(LPASS_CLK_ID_PRI_PCM_IBIT), !! 131 [LPASS_CLK_ID_QUAD_MI2S_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUAD_MI2S_EBIT), 47 Q6AFE_CLK(LPASS_CLK_ID_PRI_PCM_EBIT), !! 132 [LPASS_CLK_ID_SPEAKER_I2S_IBIT] = 48 Q6AFE_CLK(LPASS_CLK_ID_SEC_PCM_IBIT), !! 133 Q6AFE_CLK(LPASS_CLK_ID_SPEAKER_I2S_IBIT), 49 Q6AFE_CLK(LPASS_CLK_ID_SEC_PCM_EBIT), !! 134 [LPASS_CLK_ID_SPEAKER_I2S_EBIT] = 50 Q6AFE_CLK(LPASS_CLK_ID_TER_PCM_IBIT), !! 135 Q6AFE_CLK(LPASS_CLK_ID_SPEAKER_I2S_EBIT), 51 Q6AFE_CLK(LPASS_CLK_ID_TER_PCM_EBIT), !! 136 [LPASS_CLK_ID_SPEAKER_I2S_OSR] = 52 Q6AFE_CLK(LPASS_CLK_ID_QUAD_PCM_IBIT), !! 137 Q6AFE_CLK(LPASS_CLK_ID_SPEAKER_I2S_OSR), 53 Q6AFE_CLK(LPASS_CLK_ID_QUAD_PCM_EBIT), !! 138 [LPASS_CLK_ID_QUI_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUI_MI2S_IBIT), 54 Q6AFE_CLK(LPASS_CLK_ID_QUIN_PCM_IBIT), !! 139 [LPASS_CLK_ID_QUI_MI2S_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUI_MI2S_EBIT), 55 Q6AFE_CLK(LPASS_CLK_ID_QUIN_PCM_EBIT), !! 140 [LPASS_CLK_ID_SEN_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_SEN_MI2S_IBIT), 56 Q6AFE_CLK(LPASS_CLK_ID_QUI_PCM_OSR), !! 141 [LPASS_CLK_ID_SEN_MI2S_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_SEN_MI2S_EBIT), 57 Q6AFE_CLK(LPASS_CLK_ID_PRI_TDM_IBIT), !! 142 [LPASS_CLK_ID_INT0_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_INT0_MI2S_IBIT), 58 Q6AFE_CLK(LPASS_CLK_ID_PRI_TDM_EBIT), !! 143 [LPASS_CLK_ID_INT1_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_INT1_MI2S_IBIT), 59 Q6AFE_CLK(LPASS_CLK_ID_SEC_TDM_IBIT), !! 144 [LPASS_CLK_ID_INT2_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_INT2_MI2S_IBIT), 60 Q6AFE_CLK(LPASS_CLK_ID_SEC_TDM_EBIT), !! 145 [LPASS_CLK_ID_INT3_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_INT3_MI2S_IBIT), 61 Q6AFE_CLK(LPASS_CLK_ID_TER_TDM_IBIT), !! 146 [LPASS_CLK_ID_INT4_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_INT4_MI2S_IBIT), 62 Q6AFE_CLK(LPASS_CLK_ID_TER_TDM_EBIT), !! 147 [LPASS_CLK_ID_INT5_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_INT5_MI2S_IBIT), 63 Q6AFE_CLK(LPASS_CLK_ID_QUAD_TDM_IBIT), !! 148 [LPASS_CLK_ID_INT6_MI2S_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_INT6_MI2S_IBIT), 64 Q6AFE_CLK(LPASS_CLK_ID_QUAD_TDM_EBIT), !! 149 [LPASS_CLK_ID_QUI_MI2S_OSR] = Q6AFE_CLK(LPASS_CLK_ID_QUI_MI2S_OSR), 65 Q6AFE_CLK(LPASS_CLK_ID_QUIN_TDM_IBIT), !! 150 [LPASS_CLK_ID_PRI_PCM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_PRI_PCM_IBIT), 66 Q6AFE_CLK(LPASS_CLK_ID_QUIN_TDM_EBIT), !! 151 [LPASS_CLK_ID_PRI_PCM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_PRI_PCM_EBIT), 67 Q6AFE_CLK(LPASS_CLK_ID_QUIN_TDM_OSR), !! 152 [LPASS_CLK_ID_SEC_PCM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_SEC_PCM_IBIT), 68 Q6AFE_CLK(LPASS_CLK_ID_MCLK_1), !! 153 [LPASS_CLK_ID_SEC_PCM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_SEC_PCM_EBIT), 69 Q6AFE_CLK(LPASS_CLK_ID_MCLK_2), !! 154 [LPASS_CLK_ID_TER_PCM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_TER_PCM_IBIT), 70 Q6AFE_CLK(LPASS_CLK_ID_MCLK_3), !! 155 [LPASS_CLK_ID_TER_PCM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_TER_PCM_EBIT), 71 Q6AFE_CLK(LPASS_CLK_ID_MCLK_4), !! 156 [LPASS_CLK_ID_QUAD_PCM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUAD_PCM_IBIT), 72 Q6AFE_CLK(LPASS_CLK_ID_INTERNAL_DIGITA !! 157 [LPASS_CLK_ID_QUAD_PCM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUAD_PCM_EBIT), 73 Q6AFE_CLK(LPASS_CLK_ID_INT_MCLK_0), !! 158 [LPASS_CLK_ID_QUIN_PCM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUIN_PCM_IBIT), 74 Q6AFE_CLK(LPASS_CLK_ID_INT_MCLK_1), !! 159 [LPASS_CLK_ID_QUIN_PCM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUIN_PCM_EBIT), 75 Q6AFE_CLK(LPASS_CLK_ID_WSA_CORE_MCLK), !! 160 [LPASS_CLK_ID_QUI_PCM_OSR] = Q6AFE_CLK(LPASS_CLK_ID_QUI_PCM_OSR), 76 Q6AFE_CLK(LPASS_CLK_ID_WSA_CORE_NPL_MC !! 161 [LPASS_CLK_ID_PRI_TDM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_PRI_TDM_IBIT), 77 Q6AFE_CLK(LPASS_CLK_ID_VA_CORE_MCLK), !! 162 [LPASS_CLK_ID_PRI_TDM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_PRI_TDM_EBIT), 78 Q6AFE_CLK(LPASS_CLK_ID_TX_CORE_MCLK), !! 163 [LPASS_CLK_ID_SEC_TDM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_SEC_TDM_IBIT), 79 Q6AFE_CLK(LPASS_CLK_ID_TX_CORE_NPL_MCL !! 164 [LPASS_CLK_ID_SEC_TDM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_SEC_TDM_EBIT), 80 Q6AFE_CLK(LPASS_CLK_ID_RX_CORE_MCLK), !! 165 [LPASS_CLK_ID_TER_TDM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_TER_TDM_IBIT), 81 Q6AFE_CLK(LPASS_CLK_ID_RX_CORE_NPL_MCL !! 166 [LPASS_CLK_ID_TER_TDM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_TER_TDM_EBIT), 82 Q6AFE_CLK(LPASS_CLK_ID_VA_CORE_2X_MCLK !! 167 [LPASS_CLK_ID_QUAD_TDM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUAD_TDM_IBIT), 83 Q6DSP_VOTE_CLK(LPASS_HW_AVTIMER_VOTE, !! 168 [LPASS_CLK_ID_QUAD_TDM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUAD_TDM_EBIT), 84 Q6AFE_LPASS_CORE_AVTIME !! 169 [LPASS_CLK_ID_QUIN_TDM_IBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUIN_TDM_IBIT), 85 "LPASS_AVTIMER_MACRO"), !! 170 [LPASS_CLK_ID_QUIN_TDM_EBIT] = Q6AFE_CLK(LPASS_CLK_ID_QUIN_TDM_EBIT), 86 Q6DSP_VOTE_CLK(LPASS_HW_MACRO_VOTE, !! 171 [LPASS_CLK_ID_QUIN_TDM_OSR] = Q6AFE_CLK(LPASS_CLK_ID_QUIN_TDM_OSR), 87 Q6AFE_LPASS_CORE_HW_MAC !! 172 [LPASS_CLK_ID_MCLK_1] = Q6AFE_CLK(LPASS_CLK_ID_MCLK_1), 88 "LPASS_HW_MACRO"), !! 173 [LPASS_CLK_ID_MCLK_2] = Q6AFE_CLK(LPASS_CLK_ID_MCLK_2), 89 Q6DSP_VOTE_CLK(LPASS_HW_DCODEC_VOTE, !! 174 [LPASS_CLK_ID_MCLK_3] = Q6AFE_CLK(LPASS_CLK_ID_MCLK_3), 90 Q6AFE_LPASS_CORE_HW_DCO !! 175 [LPASS_CLK_ID_MCLK_4] = Q6AFE_CLK(LPASS_CLK_ID_MCLK_4), 91 "LPASS_HW_DCODEC"), !! 176 [LPASS_CLK_ID_INTERNAL_DIGITAL_CODEC_CORE] = 92 }; !! 177 Q6AFE_CLK(LPASS_CLK_ID_INTERNAL_DIGITAL_CODEC_CORE), 93 !! 178 [LPASS_CLK_ID_INT_MCLK_0] = Q6AFE_CLK(LPASS_CLK_ID_INT_MCLK_0), 94 static const struct q6dsp_clk_desc q6dsp_clk_q !! 179 [LPASS_CLK_ID_INT_MCLK_1] = Q6AFE_CLK(LPASS_CLK_ID_INT_MCLK_1), 95 .clks = q6afe_clks, !! 180 [LPASS_CLK_ID_WSA_CORE_MCLK] = Q6AFE_CLK(LPASS_CLK_ID_WSA_CORE_MCLK), 96 .num_clks = ARRAY_SIZE(q6afe_clks), !! 181 [LPASS_CLK_ID_WSA_CORE_NPL_MCLK] = 97 .lpass_set_clk = q6afe_set_lpass_clock !! 182 Q6AFE_CLK(LPASS_CLK_ID_WSA_CORE_NPL_MCLK), 98 .lpass_vote_clk = q6afe_vote_lpass_cor !! 183 [LPASS_CLK_ID_VA_CORE_MCLK] = Q6AFE_CLK(LPASS_CLK_ID_VA_CORE_MCLK), 99 .lpass_unvote_clk = q6afe_unvote_lpass !! 184 [LPASS_CLK_ID_TX_CORE_MCLK] = Q6AFE_CLK(LPASS_CLK_ID_TX_CORE_MCLK), >> 185 [LPASS_CLK_ID_TX_CORE_NPL_MCLK] = >> 186 Q6AFE_CLK(LPASS_CLK_ID_TX_CORE_NPL_MCLK), >> 187 [LPASS_CLK_ID_RX_CORE_MCLK] = Q6AFE_CLK(LPASS_CLK_ID_RX_CORE_MCLK), >> 188 [LPASS_CLK_ID_RX_CORE_NPL_MCLK] = >> 189 Q6AFE_CLK(LPASS_CLK_ID_RX_CORE_NPL_MCLK), >> 190 [LPASS_CLK_ID_VA_CORE_2X_MCLK] = >> 191 Q6AFE_CLK(LPASS_CLK_ID_VA_CORE_2X_MCLK), >> 192 [LPASS_HW_AVTIMER_VOTE] = Q6AFE_VOTE_CLK(LPASS_HW_AVTIMER_VOTE, >> 193 Q6AFE_LPASS_CORE_AVTIMER_BLOCK, >> 194 "LPASS_AVTIMER_MACRO"), >> 195 [LPASS_HW_MACRO_VOTE] = Q6AFE_VOTE_CLK(LPASS_HW_MACRO_VOTE, >> 196 Q6AFE_LPASS_CORE_HW_MACRO_BLOCK, >> 197 "LPASS_HW_MACRO"), >> 198 [LPASS_HW_DCODEC_VOTE] = Q6AFE_VOTE_CLK(LPASS_HW_DCODEC_VOTE, >> 199 Q6AFE_LPASS_CORE_HW_DCODEC_BLOCK, >> 200 "LPASS_HW_DCODEC"), 100 }; 201 }; 101 202 >> 203 static struct clk_hw *q6afe_of_clk_hw_get(struct of_phandle_args *clkspec, >> 204 void *data) >> 205 { >> 206 struct q6afe_cc *cc = data; >> 207 unsigned int idx = clkspec->args[0]; >> 208 unsigned int attr = clkspec->args[1]; >> 209 >> 210 if (idx >= cc->num_clks || attr > LPASS_CLK_ATTRIBUTE_COUPLE_DIVISOR) { >> 211 dev_err(cc->dev, "Invalid clk specifier (%d, %d)\n", idx, attr); >> 212 return ERR_PTR(-EINVAL); >> 213 } >> 214 >> 215 if (cc->clks[idx]) { >> 216 cc->clks[idx]->attributes = attr; >> 217 return &cc->clks[idx]->hw; >> 218 } >> 219 >> 220 return ERR_PTR(-ENOENT); >> 221 } >> 222 >> 223 static int q6afe_clock_dev_probe(struct platform_device *pdev) >> 224 { >> 225 struct q6afe_cc *cc; >> 226 struct device *dev = &pdev->dev; >> 227 int i, ret; >> 228 >> 229 cc = devm_kzalloc(dev, sizeof(*cc), GFP_KERNEL); >> 230 if (!cc) >> 231 return -ENOMEM; >> 232 >> 233 cc->clks = &q6afe_clks[0]; >> 234 cc->num_clks = ARRAY_SIZE(q6afe_clks); >> 235 for (i = 0; i < ARRAY_SIZE(q6afe_clks); i++) { >> 236 if (!q6afe_clks[i]) >> 237 continue; >> 238 >> 239 q6afe_clks[i]->dev = dev; >> 240 >> 241 ret = devm_clk_hw_register(dev, &q6afe_clks[i]->hw); >> 242 if (ret) >> 243 return ret; >> 244 } >> 245 >> 246 ret = of_clk_add_hw_provider(dev->of_node, q6afe_of_clk_hw_get, cc); >> 247 if (ret) >> 248 return ret; >> 249 >> 250 dev_set_drvdata(dev, cc); >> 251 >> 252 return 0; >> 253 } >> 254 102 #ifdef CONFIG_OF 255 #ifdef CONFIG_OF 103 static const struct of_device_id q6afe_clock_d 256 static const struct of_device_id q6afe_clock_device_id[] = { 104 { .compatible = "qcom,q6afe-clocks", . !! 257 { .compatible = "qcom,q6afe-clocks" }, 105 {}, 258 {}, 106 }; 259 }; 107 MODULE_DEVICE_TABLE(of, q6afe_clock_device_id) 260 MODULE_DEVICE_TABLE(of, q6afe_clock_device_id); 108 #endif 261 #endif 109 262 110 static struct platform_driver q6afe_clock_plat 263 static struct platform_driver q6afe_clock_platform_driver = { 111 .driver = { 264 .driver = { 112 .name = "q6afe-clock", 265 .name = "q6afe-clock", 113 .of_match_table = of_match_ptr 266 .of_match_table = of_match_ptr(q6afe_clock_device_id), 114 }, 267 }, 115 .probe = q6dsp_clock_dev_probe, !! 268 .probe = q6afe_clock_dev_probe, 116 }; 269 }; 117 module_platform_driver(q6afe_clock_platform_dr 270 module_platform_driver(q6afe_clock_platform_driver); 118 271 119 MODULE_DESCRIPTION("Q6 Audio Frontend clock dr 272 MODULE_DESCRIPTION("Q6 Audio Frontend clock driver"); 120 MODULE_LICENSE("GPL v2"); 273 MODULE_LICENSE("GPL v2"); 121 274
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.