hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/sound/soc/qcom/lpass-apq8016.c
....@@ -1,17 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (c) 2010-2011,2013-2015 The Linux Foundation. All rights reserved.
34 *
4
- * This program is free software; you can redistribute it and/or modify
5
- * it under the terms of the GNU General Public License version 2 and
6
- * only version 2 as published by the Free Software Foundation.
7
- *
8
- * This program is distributed in the hope that it will be useful,
9
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
- * GNU General Public License for more details.
12
- *
135 * lpass-apq8016.c -- ALSA SoC CPU DAI driver for APQ8016 LPASS
14
- *
156 */
167
178
....@@ -134,7 +125,7 @@
134125 };
135126
136127 static int apq8016_lpass_alloc_dma_channel(struct lpass_data *drvdata,
137
- int direction)
128
+ int direction, unsigned int dai_id)
138129 {
139130 struct lpass_variant *v = drvdata->variant;
140131 int chan = 0;
....@@ -160,7 +151,7 @@
160151 return chan;
161152 }
162153
163
-static int apq8016_lpass_free_dma_channel(struct lpass_data *drvdata, int chan)
154
+static int apq8016_lpass_free_dma_channel(struct lpass_data *drvdata, int chan, unsigned int dai_id)
164155 {
165156 clear_bit(chan, &drvdata->dma_ch_bit_map);
166157
....@@ -170,45 +161,67 @@
170161 static int apq8016_lpass_init(struct platform_device *pdev)
171162 {
172163 struct lpass_data *drvdata = platform_get_drvdata(pdev);
164
+ struct lpass_variant *variant = drvdata->variant;
173165 struct device *dev = &pdev->dev;
174
- int ret;
166
+ int ret, i;
175167
176
- drvdata->pcnoc_mport_clk = devm_clk_get(dev, "pcnoc-mport-clk");
177
- if (IS_ERR(drvdata->pcnoc_mport_clk)) {
178
- dev_err(&pdev->dev, "error getting pcnoc-mport-clk: %ld\n",
179
- PTR_ERR(drvdata->pcnoc_mport_clk));
180
- return PTR_ERR(drvdata->pcnoc_mport_clk);
181
- }
182168
183
- ret = clk_prepare_enable(drvdata->pcnoc_mport_clk);
169
+ drvdata->clks = devm_kcalloc(dev, variant->num_clks,
170
+ sizeof(*drvdata->clks), GFP_KERNEL);
171
+ if (!drvdata->clks)
172
+ return -ENOMEM;
173
+ drvdata->num_clks = variant->num_clks;
174
+
175
+ for (i = 0; i < drvdata->num_clks; i++)
176
+ drvdata->clks[i].id = variant->clk_name[i];
177
+
178
+ ret = devm_clk_bulk_get(dev, drvdata->num_clks, drvdata->clks);
184179 if (ret) {
185
- dev_err(&pdev->dev, "Error enabling pcnoc-mport-clk: %d\n",
186
- ret);
180
+ dev_err(dev, "Failed to get clocks %d\n", ret);
187181 return ret;
188182 }
189183
190
- drvdata->pcnoc_sway_clk = devm_clk_get(dev, "pcnoc-sway-clk");
191
- if (IS_ERR(drvdata->pcnoc_sway_clk)) {
192
- dev_err(&pdev->dev, "error getting pcnoc-sway-clk: %ld\n",
193
- PTR_ERR(drvdata->pcnoc_sway_clk));
194
- return PTR_ERR(drvdata->pcnoc_sway_clk);
184
+ ret = clk_bulk_prepare_enable(drvdata->num_clks, drvdata->clks);
185
+ if (ret) {
186
+ dev_err(dev, "apq8016 clk_enable failed\n");
187
+ return ret;
195188 }
196189
197
- ret = clk_prepare_enable(drvdata->pcnoc_sway_clk);
190
+ drvdata->ahbix_clk = devm_clk_get(dev, "ahbix-clk");
191
+ if (IS_ERR(drvdata->ahbix_clk)) {
192
+ dev_err(dev, "error getting ahbix-clk: %ld\n",
193
+ PTR_ERR(drvdata->ahbix_clk));
194
+ ret = PTR_ERR(drvdata->ahbix_clk);
195
+ goto err_ahbix_clk;
196
+ }
197
+
198
+ ret = clk_set_rate(drvdata->ahbix_clk, LPASS_AHBIX_CLOCK_FREQUENCY);
198199 if (ret) {
199
- dev_err(&pdev->dev, "Error enabling pcnoc_sway_clk: %d\n", ret);
200
- return ret;
200
+ dev_err(dev, "error setting rate on ahbix_clk: %d\n", ret);
201
+ goto err_ahbix_clk;
202
+ }
203
+ dev_dbg(dev, "set ahbix_clk rate to %lu\n",
204
+ clk_get_rate(drvdata->ahbix_clk));
205
+
206
+ ret = clk_prepare_enable(drvdata->ahbix_clk);
207
+ if (ret) {
208
+ dev_err(dev, "error enabling ahbix_clk: %d\n", ret);
209
+ goto err_ahbix_clk;
201210 }
202211
203212 return 0;
213
+
214
+err_ahbix_clk:
215
+ clk_bulk_disable_unprepare(drvdata->num_clks, drvdata->clks);
216
+ return ret;
204217 }
205218
206219 static int apq8016_lpass_exit(struct platform_device *pdev)
207220 {
208221 struct lpass_data *drvdata = platform_get_drvdata(pdev);
209222
210
- clk_disable_unprepare(drvdata->pcnoc_mport_clk);
211
- clk_disable_unprepare(drvdata->pcnoc_sway_clk);
223
+ clk_bulk_disable_unprepare(drvdata->num_clks, drvdata->clks);
224
+ clk_disable_unprepare(drvdata->ahbix_clk);
212225
213226 return 0;
214227 }
....@@ -229,6 +242,35 @@
229242 .wrdma_reg_stride = 0x1000,
230243 .wrdma_channel_start = 5,
231244 .wrdma_channels = 2,
245
+ .loopback = REG_FIELD_ID(0x1000, 15, 15, 4, 0x1000),
246
+ .spken = REG_FIELD_ID(0x1000, 14, 14, 4, 0x1000),
247
+ .spkmode = REG_FIELD_ID(0x1000, 10, 13, 4, 0x1000),
248
+ .spkmono = REG_FIELD_ID(0x1000, 9, 9, 4, 0x1000),
249
+ .micen = REG_FIELD_ID(0x1000, 8, 8, 4, 0x1000),
250
+ .micmode = REG_FIELD_ID(0x1000, 4, 7, 4, 0x1000),
251
+ .micmono = REG_FIELD_ID(0x1000, 3, 3, 4, 0x1000),
252
+ .wssrc = REG_FIELD_ID(0x1000, 2, 2, 4, 0x1000),
253
+ .bitwidth = REG_FIELD_ID(0x1000, 0, 1, 4, 0x1000),
254
+
255
+ .rdma_dyncclk = REG_FIELD_ID(0x8400, 12, 12, 2, 0x1000),
256
+ .rdma_bursten = REG_FIELD_ID(0x8400, 11, 11, 2, 0x1000),
257
+ .rdma_wpscnt = REG_FIELD_ID(0x8400, 8, 10, 2, 0x1000),
258
+ .rdma_intf = REG_FIELD_ID(0x8400, 4, 7, 2, 0x1000),
259
+ .rdma_fifowm = REG_FIELD_ID(0x8400, 1, 3, 2, 0x1000),
260
+ .rdma_enable = REG_FIELD_ID(0x8400, 0, 0, 2, 0x1000),
261
+
262
+ .wrdma_dyncclk = REG_FIELD_ID(0xB000, 12, 12, 2, 0x1000),
263
+ .wrdma_bursten = REG_FIELD_ID(0xB000, 11, 11, 2, 0x1000),
264
+ .wrdma_wpscnt = REG_FIELD_ID(0xB000, 8, 10, 2, 0x1000),
265
+ .wrdma_intf = REG_FIELD_ID(0xB000, 4, 7, 2, 0x1000),
266
+ .wrdma_fifowm = REG_FIELD_ID(0xB000, 1, 3, 2, 0x1000),
267
+ .wrdma_enable = REG_FIELD_ID(0xB000, 0, 0, 2, 0x1000),
268
+
269
+ .clk_name = (const char*[]) {
270
+ "pcnoc-mport-clk",
271
+ "pcnoc-sway-clk",
272
+ },
273
+ .num_clks = 2,
232274 .dai_driver = apq8016_lpass_cpu_dai_driver,
233275 .num_dai = ARRAY_SIZE(apq8016_lpass_cpu_dai_driver),
234276 .dai_osr_clk_names = (const char *[]) {