2 * mtk-afe-platform-driver.c -- Mediatek afe platform driver
4 * Copyright (c) 2016 MediaTek Inc.
5 * Author: Garlic Tseng <garlic.tseng@mediatek.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 and
9 * only version 2 as published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
17 #include <linux/module.h>
18 #include <linux/dma-mapping.h>
19 #include <sound/soc.h>
21 #include "mtk-afe-platform-driver.h"
22 #include "mtk-base-afe.h"
24 static snd_pcm_uframes_t mtk_afe_pcm_pointer
25 (struct snd_pcm_substream
*substream
)
27 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
28 struct mtk_base_afe
*afe
= snd_soc_platform_get_drvdata(rtd
->platform
);
29 struct mtk_base_afe_memif
*memif
= &afe
->memif
[rtd
->cpu_dai
->id
];
30 const struct mtk_base_memif_data
*memif_data
= memif
->data
;
31 struct regmap
*regmap
= afe
->regmap
;
32 struct device
*dev
= afe
->dev
;
33 int reg_ofs_base
= memif_data
->reg_ofs_base
;
34 int reg_ofs_cur
= memif_data
->reg_ofs_cur
;
35 unsigned int hw_ptr
= 0, hw_base
= 0;
36 int ret
, pcm_ptr_bytes
;
38 ret
= regmap_read(regmap
, reg_ofs_cur
, &hw_ptr
);
39 if (ret
|| hw_ptr
== 0) {
40 dev_err(dev
, "%s hw_ptr err\n", __func__
);
42 goto POINTER_RETURN_FRAMES
;
45 ret
= regmap_read(regmap
, reg_ofs_base
, &hw_base
);
46 if (ret
|| hw_base
== 0) {
47 dev_err(dev
, "%s hw_ptr err\n", __func__
);
49 goto POINTER_RETURN_FRAMES
;
52 pcm_ptr_bytes
= hw_ptr
- hw_base
;
54 POINTER_RETURN_FRAMES
:
55 return bytes_to_frames(substream
->runtime
, pcm_ptr_bytes
);
58 static const struct snd_pcm_ops mtk_afe_pcm_ops
= {
59 .ioctl
= snd_pcm_lib_ioctl
,
60 .pointer
= mtk_afe_pcm_pointer
,
63 static int mtk_afe_pcm_new(struct snd_soc_pcm_runtime
*rtd
)
66 struct snd_card
*card
= rtd
->card
->snd_card
;
67 struct snd_pcm
*pcm
= rtd
->pcm
;
68 struct mtk_base_afe
*afe
= snd_soc_platform_get_drvdata(rtd
->platform
);
70 size
= afe
->mtk_afe_hardware
->buffer_bytes_max
;
71 return snd_pcm_lib_preallocate_pages_for_all(pcm
, SNDRV_DMA_TYPE_DEV
,
72 card
->dev
, size
, size
);
75 static void mtk_afe_pcm_free(struct snd_pcm
*pcm
)
77 snd_pcm_lib_preallocate_free_for_all(pcm
);
80 const struct snd_soc_platform_driver mtk_afe_pcm_platform
= {
81 .ops
= &mtk_afe_pcm_ops
,
82 .pcm_new
= mtk_afe_pcm_new
,
83 .pcm_free
= mtk_afe_pcm_free
,
85 EXPORT_SYMBOL_GPL(mtk_afe_pcm_platform
);
87 MODULE_DESCRIPTION("Mediatek simple platform driver");
88 MODULE_AUTHOR("Garlic Tseng <garlic.tseng@mediatek.com>");
89 MODULE_LICENSE("GPL v2");