2 * Copyright (c) 2010-2011,2013-2015 The Linux Foundation. All rights reserved.
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.
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.
13 * lpass-cpu.c -- ALSA SoC CPU DAI driver for QTi LPASS
16 #include <linux/clk.h>
17 #include <linux/kernel.h>
18 #include <linux/module.h>
20 #include <linux/of_device.h>
21 #include <linux/platform_device.h>
22 #include <sound/pcm.h>
23 #include <sound/pcm_params.h>
24 #include <linux/regmap.h>
25 #include <sound/soc.h>
26 #include <sound/soc-dai.h>
27 #include "lpass-lpaif-reg.h"
30 static int lpass_cpu_daiops_set_sysclk(struct snd_soc_dai
*dai
, int clk_id
,
31 unsigned int freq
, int dir
)
33 struct lpass_data
*drvdata
= snd_soc_dai_get_drvdata(dai
);
36 if (IS_ERR(drvdata
->mi2s_osr_clk
[dai
->driver
->id
]))
39 ret
= clk_set_rate(drvdata
->mi2s_osr_clk
[dai
->driver
->id
], freq
);
41 dev_err(dai
->dev
, "%s() error setting mi2s osrclk to %u: %d\n",
47 static int lpass_cpu_daiops_startup(struct snd_pcm_substream
*substream
,
48 struct snd_soc_dai
*dai
)
50 struct lpass_data
*drvdata
= snd_soc_dai_get_drvdata(dai
);
53 if (!IS_ERR(drvdata
->mi2s_osr_clk
[dai
->driver
->id
])) {
54 ret
= clk_prepare_enable(
55 drvdata
->mi2s_osr_clk
[dai
->driver
->id
]);
57 dev_err(dai
->dev
, "%s() error in enabling mi2s osr clk: %d\n",
63 ret
= clk_prepare_enable(drvdata
->mi2s_bit_clk
[dai
->driver
->id
]);
65 dev_err(dai
->dev
, "%s() error in enabling mi2s bit clk: %d\n",
67 if (!IS_ERR(drvdata
->mi2s_osr_clk
[dai
->driver
->id
]))
68 clk_disable_unprepare(
69 drvdata
->mi2s_osr_clk
[dai
->driver
->id
]);
76 static void lpass_cpu_daiops_shutdown(struct snd_pcm_substream
*substream
,
77 struct snd_soc_dai
*dai
)
79 struct lpass_data
*drvdata
= snd_soc_dai_get_drvdata(dai
);
81 clk_disable_unprepare(drvdata
->mi2s_bit_clk
[dai
->driver
->id
]);
83 if (!IS_ERR(drvdata
->mi2s_osr_clk
[dai
->driver
->id
]))
84 clk_disable_unprepare(drvdata
->mi2s_osr_clk
[dai
->driver
->id
]);
87 static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream
*substream
,
88 struct snd_pcm_hw_params
*params
, struct snd_soc_dai
*dai
)
90 struct lpass_data
*drvdata
= snd_soc_dai_get_drvdata(dai
);
91 snd_pcm_format_t format
= params_format(params
);
92 unsigned int channels
= params_channels(params
);
93 unsigned int rate
= params_rate(params
);
97 bitwidth
= snd_pcm_format_width(format
);
99 dev_err(dai
->dev
, "%s() invalid bit width given: %d\n",
104 regval
= LPAIF_I2SCTL_LOOPBACK_DISABLE
|
105 LPAIF_I2SCTL_WSSRC_INTERNAL
;
109 regval
|= LPAIF_I2SCTL_BITWIDTH_16
;
112 regval
|= LPAIF_I2SCTL_BITWIDTH_24
;
115 regval
|= LPAIF_I2SCTL_BITWIDTH_32
;
118 dev_err(dai
->dev
, "%s() invalid bitwidth given: %d\n",
123 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
126 regval
|= LPAIF_I2SCTL_SPKMODE_SD0
;
127 regval
|= LPAIF_I2SCTL_SPKMONO_MONO
;
130 regval
|= LPAIF_I2SCTL_SPKMODE_SD0
;
131 regval
|= LPAIF_I2SCTL_SPKMONO_STEREO
;
134 regval
|= LPAIF_I2SCTL_SPKMODE_QUAD01
;
135 regval
|= LPAIF_I2SCTL_SPKMONO_STEREO
;
138 regval
|= LPAIF_I2SCTL_SPKMODE_6CH
;
139 regval
|= LPAIF_I2SCTL_SPKMONO_STEREO
;
142 regval
|= LPAIF_I2SCTL_SPKMODE_8CH
;
143 regval
|= LPAIF_I2SCTL_SPKMONO_STEREO
;
146 dev_err(dai
->dev
, "%s() invalid channels given: %u\n",
153 regval
|= LPAIF_I2SCTL_MICMODE_SD0
;
154 regval
|= LPAIF_I2SCTL_MICMONO_MONO
;
157 regval
|= LPAIF_I2SCTL_MICMODE_SD0
;
158 regval
|= LPAIF_I2SCTL_MICMONO_STEREO
;
161 regval
|= LPAIF_I2SCTL_MICMODE_QUAD01
;
162 regval
|= LPAIF_I2SCTL_MICMONO_STEREO
;
165 regval
|= LPAIF_I2SCTL_MICMODE_6CH
;
166 regval
|= LPAIF_I2SCTL_MICMONO_STEREO
;
169 regval
|= LPAIF_I2SCTL_MICMODE_8CH
;
170 regval
|= LPAIF_I2SCTL_MICMONO_STEREO
;
173 dev_err(dai
->dev
, "%s() invalid channels given: %u\n",
179 ret
= regmap_write(drvdata
->lpaif_map
,
180 LPAIF_I2SCTL_REG(drvdata
->variant
, dai
->driver
->id
),
183 dev_err(dai
->dev
, "%s() error writing to i2sctl reg: %d\n",
188 ret
= clk_set_rate(drvdata
->mi2s_bit_clk
[dai
->driver
->id
],
189 rate
* bitwidth
* 2);
191 dev_err(dai
->dev
, "%s() error setting mi2s bitclk to %u: %d\n",
192 __func__
, rate
* bitwidth
* 2, ret
);
199 static int lpass_cpu_daiops_hw_free(struct snd_pcm_substream
*substream
,
200 struct snd_soc_dai
*dai
)
202 struct lpass_data
*drvdata
= snd_soc_dai_get_drvdata(dai
);
205 ret
= regmap_write(drvdata
->lpaif_map
,
206 LPAIF_I2SCTL_REG(drvdata
->variant
, dai
->driver
->id
),
209 dev_err(dai
->dev
, "%s() error writing to i2sctl reg: %d\n",
215 static int lpass_cpu_daiops_prepare(struct snd_pcm_substream
*substream
,
216 struct snd_soc_dai
*dai
)
218 struct lpass_data
*drvdata
= snd_soc_dai_get_drvdata(dai
);
220 unsigned int val
, mask
;
222 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
223 val
= LPAIF_I2SCTL_SPKEN_ENABLE
;
224 mask
= LPAIF_I2SCTL_SPKEN_MASK
;
226 val
= LPAIF_I2SCTL_MICEN_ENABLE
;
227 mask
= LPAIF_I2SCTL_MICEN_MASK
;
230 ret
= regmap_update_bits(drvdata
->lpaif_map
,
231 LPAIF_I2SCTL_REG(drvdata
->variant
, dai
->driver
->id
),
234 dev_err(dai
->dev
, "%s() error writing to i2sctl reg: %d\n",
240 static int lpass_cpu_daiops_trigger(struct snd_pcm_substream
*substream
,
241 int cmd
, struct snd_soc_dai
*dai
)
243 struct lpass_data
*drvdata
= snd_soc_dai_get_drvdata(dai
);
245 unsigned int val
, mask
;
248 case SNDRV_PCM_TRIGGER_START
:
249 case SNDRV_PCM_TRIGGER_RESUME
:
250 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
251 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
252 val
= LPAIF_I2SCTL_SPKEN_ENABLE
;
253 mask
= LPAIF_I2SCTL_SPKEN_MASK
;
255 val
= LPAIF_I2SCTL_MICEN_ENABLE
;
256 mask
= LPAIF_I2SCTL_MICEN_MASK
;
259 ret
= regmap_update_bits(drvdata
->lpaif_map
,
260 LPAIF_I2SCTL_REG(drvdata
->variant
,
264 dev_err(dai
->dev
, "%s() error writing to i2sctl reg: %d\n",
267 case SNDRV_PCM_TRIGGER_STOP
:
268 case SNDRV_PCM_TRIGGER_SUSPEND
:
269 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
270 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
271 val
= LPAIF_I2SCTL_SPKEN_DISABLE
;
272 mask
= LPAIF_I2SCTL_SPKEN_MASK
;
274 val
= LPAIF_I2SCTL_MICEN_DISABLE
;
275 mask
= LPAIF_I2SCTL_MICEN_MASK
;
278 ret
= regmap_update_bits(drvdata
->lpaif_map
,
279 LPAIF_I2SCTL_REG(drvdata
->variant
,
283 dev_err(dai
->dev
, "%s() error writing to i2sctl reg: %d\n",
291 const struct snd_soc_dai_ops asoc_qcom_lpass_cpu_dai_ops
= {
292 .set_sysclk
= lpass_cpu_daiops_set_sysclk
,
293 .startup
= lpass_cpu_daiops_startup
,
294 .shutdown
= lpass_cpu_daiops_shutdown
,
295 .hw_params
= lpass_cpu_daiops_hw_params
,
296 .hw_free
= lpass_cpu_daiops_hw_free
,
297 .prepare
= lpass_cpu_daiops_prepare
,
298 .trigger
= lpass_cpu_daiops_trigger
,
300 EXPORT_SYMBOL_GPL(asoc_qcom_lpass_cpu_dai_ops
);
302 int asoc_qcom_lpass_cpu_dai_probe(struct snd_soc_dai
*dai
)
304 struct lpass_data
*drvdata
= snd_soc_dai_get_drvdata(dai
);
307 /* ensure audio hardware is disabled */
308 ret
= regmap_write(drvdata
->lpaif_map
,
309 LPAIF_I2SCTL_REG(drvdata
->variant
, dai
->driver
->id
), 0);
311 dev_err(dai
->dev
, "%s() error writing to i2sctl reg: %d\n",
316 EXPORT_SYMBOL_GPL(asoc_qcom_lpass_cpu_dai_probe
);
318 static const struct snd_soc_component_driver lpass_cpu_comp_driver
= {
322 static bool lpass_cpu_regmap_writeable(struct device
*dev
, unsigned int reg
)
324 struct lpass_data
*drvdata
= dev_get_drvdata(dev
);
325 struct lpass_variant
*v
= drvdata
->variant
;
328 for (i
= 0; i
< v
->i2s_ports
; ++i
)
329 if (reg
== LPAIF_I2SCTL_REG(v
, i
))
332 for (i
= 0; i
< v
->irq_ports
; ++i
) {
333 if (reg
== LPAIF_IRQEN_REG(v
, i
))
335 if (reg
== LPAIF_IRQCLEAR_REG(v
, i
))
339 for (i
= 0; i
< v
->rdma_channels
; ++i
) {
340 if (reg
== LPAIF_RDMACTL_REG(v
, i
))
342 if (reg
== LPAIF_RDMABASE_REG(v
, i
))
344 if (reg
== LPAIF_RDMABUFF_REG(v
, i
))
346 if (reg
== LPAIF_RDMAPER_REG(v
, i
))
350 for (i
= 0; i
< v
->wrdma_channels
; ++i
) {
351 if (reg
== LPAIF_WRDMACTL_REG(v
, i
+ v
->wrdma_channel_start
))
353 if (reg
== LPAIF_WRDMABASE_REG(v
, i
+ v
->wrdma_channel_start
))
355 if (reg
== LPAIF_WRDMABUFF_REG(v
, i
+ v
->wrdma_channel_start
))
357 if (reg
== LPAIF_WRDMAPER_REG(v
, i
+ v
->wrdma_channel_start
))
364 static bool lpass_cpu_regmap_readable(struct device
*dev
, unsigned int reg
)
366 struct lpass_data
*drvdata
= dev_get_drvdata(dev
);
367 struct lpass_variant
*v
= drvdata
->variant
;
370 for (i
= 0; i
< v
->i2s_ports
; ++i
)
371 if (reg
== LPAIF_I2SCTL_REG(v
, i
))
374 for (i
= 0; i
< v
->irq_ports
; ++i
) {
375 if (reg
== LPAIF_IRQEN_REG(v
, i
))
377 if (reg
== LPAIF_IRQSTAT_REG(v
, i
))
381 for (i
= 0; i
< v
->rdma_channels
; ++i
) {
382 if (reg
== LPAIF_RDMACTL_REG(v
, i
))
384 if (reg
== LPAIF_RDMABASE_REG(v
, i
))
386 if (reg
== LPAIF_RDMABUFF_REG(v
, i
))
388 if (reg
== LPAIF_RDMACURR_REG(v
, i
))
390 if (reg
== LPAIF_RDMAPER_REG(v
, i
))
394 for (i
= 0; i
< v
->wrdma_channels
; ++i
) {
395 if (reg
== LPAIF_WRDMACTL_REG(v
, i
+ v
->wrdma_channel_start
))
397 if (reg
== LPAIF_WRDMABASE_REG(v
, i
+ v
->wrdma_channel_start
))
399 if (reg
== LPAIF_WRDMABUFF_REG(v
, i
+ v
->wrdma_channel_start
))
401 if (reg
== LPAIF_WRDMACURR_REG(v
, i
+ v
->wrdma_channel_start
))
403 if (reg
== LPAIF_WRDMAPER_REG(v
, i
+ v
->wrdma_channel_start
))
410 static bool lpass_cpu_regmap_volatile(struct device
*dev
, unsigned int reg
)
412 struct lpass_data
*drvdata
= dev_get_drvdata(dev
);
413 struct lpass_variant
*v
= drvdata
->variant
;
416 for (i
= 0; i
< v
->irq_ports
; ++i
)
417 if (reg
== LPAIF_IRQSTAT_REG(v
, i
))
420 for (i
= 0; i
< v
->rdma_channels
; ++i
)
421 if (reg
== LPAIF_RDMACURR_REG(v
, i
))
424 for (i
= 0; i
< v
->wrdma_channels
; ++i
)
425 if (reg
== LPAIF_WRDMACURR_REG(v
, i
+ v
->wrdma_channel_start
))
431 static struct regmap_config lpass_cpu_regmap_config
= {
435 .writeable_reg
= lpass_cpu_regmap_writeable
,
436 .readable_reg
= lpass_cpu_regmap_readable
,
437 .volatile_reg
= lpass_cpu_regmap_volatile
,
438 .cache_type
= REGCACHE_FLAT
,
441 int asoc_qcom_lpass_cpu_platform_probe(struct platform_device
*pdev
)
443 struct lpass_data
*drvdata
;
444 struct device_node
*dsp_of_node
;
445 struct resource
*res
;
446 struct lpass_variant
*variant
;
447 struct device
*dev
= &pdev
->dev
;
448 const struct of_device_id
*match
;
452 dsp_of_node
= of_parse_phandle(pdev
->dev
.of_node
, "qcom,adsp", 0);
454 dev_err(&pdev
->dev
, "%s() DSP exists and holds audio resources\n",
459 drvdata
= devm_kzalloc(&pdev
->dev
, sizeof(struct lpass_data
),
463 platform_set_drvdata(pdev
, drvdata
);
465 match
= of_match_device(dev
->driver
->of_match_table
, dev
);
466 if (!match
|| !match
->data
)
469 drvdata
->variant
= (struct lpass_variant
*)match
->data
;
470 variant
= drvdata
->variant
;
472 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "lpass-lpaif");
474 drvdata
->lpaif
= devm_ioremap_resource(&pdev
->dev
, res
);
475 if (IS_ERR((void const __force
*)drvdata
->lpaif
)) {
476 dev_err(&pdev
->dev
, "%s() error mapping reg resource: %ld\n",
478 PTR_ERR((void const __force
*)drvdata
->lpaif
));
479 return PTR_ERR((void const __force
*)drvdata
->lpaif
);
482 lpass_cpu_regmap_config
.max_register
= LPAIF_WRDMAPER_REG(variant
,
483 variant
->wrdma_channels
+
484 variant
->wrdma_channel_start
);
486 drvdata
->lpaif_map
= devm_regmap_init_mmio(&pdev
->dev
, drvdata
->lpaif
,
487 &lpass_cpu_regmap_config
);
488 if (IS_ERR(drvdata
->lpaif_map
)) {
489 dev_err(&pdev
->dev
, "%s() error initializing regmap: %ld\n",
490 __func__
, PTR_ERR(drvdata
->lpaif_map
));
491 return PTR_ERR(drvdata
->lpaif_map
);
497 for (i
= 0; i
< variant
->num_dai
; i
++) {
498 dai_id
= variant
->dai_driver
[i
].id
;
499 if (variant
->num_dai
> 1)
500 sprintf(clk_name
, "mi2s-osr-clk%d", i
);
502 sprintf(clk_name
, "mi2s-osr-clk");
504 drvdata
->mi2s_osr_clk
[dai_id
] = devm_clk_get(&pdev
->dev
,
506 if (IS_ERR(drvdata
->mi2s_osr_clk
[dai_id
])) {
508 "%s() error getting mi2s-osr-clk: %ld\n",
510 PTR_ERR(drvdata
->mi2s_osr_clk
[dai_id
]));
513 if (variant
->num_dai
> 1)
514 sprintf(clk_name
, "mi2s-bit-clk%d", i
);
516 sprintf(clk_name
, "mi2s-bit-clk");
518 drvdata
->mi2s_bit_clk
[dai_id
] = devm_clk_get(&pdev
->dev
,
520 if (IS_ERR(drvdata
->mi2s_bit_clk
[dai_id
])) {
522 "%s() error getting mi2s-bit-clk: %ld\n",
524 PTR_ERR(drvdata
->mi2s_bit_clk
[dai_id
]));
525 return PTR_ERR(drvdata
->mi2s_bit_clk
[dai_id
]);
529 drvdata
->ahbix_clk
= devm_clk_get(&pdev
->dev
, "ahbix-clk");
530 if (IS_ERR(drvdata
->ahbix_clk
)) {
531 dev_err(&pdev
->dev
, "%s() error getting ahbix-clk: %ld\n",
532 __func__
, PTR_ERR(drvdata
->ahbix_clk
));
533 return PTR_ERR(drvdata
->ahbix_clk
);
536 ret
= clk_set_rate(drvdata
->ahbix_clk
, LPASS_AHBIX_CLOCK_FREQUENCY
);
538 dev_err(&pdev
->dev
, "%s() error setting rate on ahbix_clk: %d\n",
542 dev_dbg(&pdev
->dev
, "%s() set ahbix_clk rate to %lu\n", __func__
,
543 clk_get_rate(drvdata
->ahbix_clk
));
545 ret
= clk_prepare_enable(drvdata
->ahbix_clk
);
547 dev_err(&pdev
->dev
, "%s() error enabling ahbix_clk: %d\n",
552 ret
= devm_snd_soc_register_component(&pdev
->dev
,
553 &lpass_cpu_comp_driver
,
557 dev_err(&pdev
->dev
, "%s() error registering cpu driver: %d\n",
562 ret
= asoc_qcom_lpass_platform_register(pdev
);
564 dev_err(&pdev
->dev
, "%s() error registering platform driver: %d\n",
572 clk_disable_unprepare(drvdata
->ahbix_clk
);
575 EXPORT_SYMBOL_GPL(asoc_qcom_lpass_cpu_platform_probe
);
577 int asoc_qcom_lpass_cpu_platform_remove(struct platform_device
*pdev
)
579 struct lpass_data
*drvdata
= platform_get_drvdata(pdev
);
581 if (drvdata
->variant
->exit
)
582 drvdata
->variant
->exit(pdev
);
584 clk_disable_unprepare(drvdata
->ahbix_clk
);
588 EXPORT_SYMBOL_GPL(asoc_qcom_lpass_cpu_platform_remove
);
590 MODULE_DESCRIPTION("QTi LPASS CPU Driver");
591 MODULE_LICENSE("GPL v2");