blob: d728eb5c5c5909b50bb314c49ecac325f9e516e0 [file] [log] [blame]
Googler9398cc32022-12-02 17:21:52 +08001// SPDX-License-Identifier: GPL-2.0
Googler4f18c0c2022-09-20 17:23:36 +08002/*
Googler9398cc32022-12-02 17:21:52 +08003 * Copyright (C) 2019 Amlogic, Inc. All rights reserved.
Googler4f18c0c2022-09-20 17:23:36 +08004 *
5 */
6
Googler9726be62022-12-14 05:53:31 +00007/*#define DEBUG*/
8
Googler4f18c0c2022-09-20 17:23:36 +08009#include <linux/of.h>
10#include <linux/io.h>
11#include <linux/of_address.h>
12#include <linux/platform_device.h>
Googler9398cc32022-12-02 17:21:52 +080013#include <linux/module.h>
Googler4f18c0c2022-09-20 17:23:36 +080014
Googler38bda472022-08-19 10:07:08 -070015#include "regs.h"
Googler4f18c0c2022-09-20 17:23:36 +080016#include "iomap.h"
Googler38bda472022-08-19 10:07:08 -070017#include "audio_aed_reg_list.h"
18#include "audio_top_reg_list.h"
Googler4f18c0c2022-09-20 17:23:36 +080019
20#define DEV_NAME "auge_snd_iomap"
21
22static void __iomem *aml_snd_reg_map[IO_MAX];
Googler9726be62022-12-14 05:53:31 +000023
24#ifdef DEBUG
Googler38bda472022-08-19 10:07:08 -070025static void register_debug(u32 base_type, unsigned int reg, unsigned int val)
26{
27 if (base_type == IO_AUDIO_BUS) {
Googler9726be62022-12-14 05:53:31 +000028 pr_debug("audio top reg:[%s] addr: [%#x] val: [%#x]\n",
Googler9398cc32022-12-02 17:21:52 +080029 top_register_table[reg].name,
30 top_register_table[reg].addr, val);
Googler38bda472022-08-19 10:07:08 -070031 } else if (base_type == IO_EQDRC_BUS) {
Googler9726be62022-12-14 05:53:31 +000032 pr_debug("audio aed reg:[%s] addr: [%#x] val: [%#x]\n",
Googler9398cc32022-12-02 17:21:52 +080033 aed_register_table[reg].name,
34 aed_register_table[reg].addr, val);
Googler38bda472022-08-19 10:07:08 -070035 }
36}
37#endif
Googler4f18c0c2022-09-20 17:23:36 +080038
39static int aml_snd_read(u32 base_type, unsigned int reg, unsigned int *val)
40{
41 if (base_type < IO_MAX) {
42 *val = readl((aml_snd_reg_map[base_type] + (reg << 2)));
43
44 return 0;
45 }
46
47 return -1;
48}
49
50static void aml_snd_write(u32 base_type, unsigned int reg, unsigned int val)
51{
Googler4f18c0c2022-09-20 17:23:36 +080052 if (base_type < IO_MAX) {
53 writel(val, (aml_snd_reg_map[base_type] + (reg << 2)));
Googler9726be62022-12-14 05:53:31 +000054#ifdef DEBUG
Googler38bda472022-08-19 10:07:08 -070055 register_debug(base_type, reg, val);
56#endif
Googler4f18c0c2022-09-20 17:23:36 +080057 return;
58 }
59
60 pr_err("write snd reg %x error\n", reg);
61}
62
Googler38bda472022-08-19 10:07:08 -070063static void aml_snd_update_bits(u32 base_type, unsigned int reg,
64 unsigned int mask, unsigned int val)
Googler4f18c0c2022-09-20 17:23:36 +080065{
66 if (base_type < IO_MAX) {
67 unsigned int tmp, orig;
68
69 if (aml_snd_read(base_type, reg, &orig) == 0) {
70 tmp = orig & ~mask;
71 tmp |= val & mask;
72 aml_snd_write(base_type, reg, tmp);
73
74 return;
75 }
76 }
77 pr_err("write snd reg %x error\n", reg);
Googler4f18c0c2022-09-20 17:23:36 +080078}
79
Googler9398cc32022-12-02 17:21:52 +080080int aml_pdm_read(int id, unsigned int reg)
Googler4f18c0c2022-09-20 17:23:36 +080081{
82 int ret, val = 0;
Googler9398cc32022-12-02 17:21:52 +080083 if (id == 0) {
84 ret = aml_snd_read(IO_PDM_BUS, reg, &val);
85 if (ret) {
86 pr_err("read pdm reg %x error %d\n", reg, ret);
87 return -1;
88 }
89 } else if (id == 1) {
90 ret = aml_snd_read(IO_PDM_BUS_B, reg, &val);
91 if (ret) {
92 pr_err("read pdm reg %x error %d\n", reg, ret);
93 return -1;
94 }
Googler4f18c0c2022-09-20 17:23:36 +080095 }
96 return val;
97}
98EXPORT_SYMBOL(aml_pdm_read);
99
Googler9398cc32022-12-02 17:21:52 +0800100void aml_pdm_write(int id, unsigned int reg, unsigned int val)
Googler4f18c0c2022-09-20 17:23:36 +0800101{
Googler9398cc32022-12-02 17:21:52 +0800102 if (id == 0)
103 aml_snd_write(IO_PDM_BUS, reg, val);
104 else if (id == 1)
105 aml_snd_write(IO_PDM_BUS_B, reg, val);
Googler4f18c0c2022-09-20 17:23:36 +0800106}
107EXPORT_SYMBOL(aml_pdm_write);
108
Googler9398cc32022-12-02 17:21:52 +0800109void aml_pdm_update_bits(int id, unsigned int reg, unsigned int mask,
Googler38bda472022-08-19 10:07:08 -0700110 unsigned int val)
Googler4f18c0c2022-09-20 17:23:36 +0800111{
Googler9398cc32022-12-02 17:21:52 +0800112 if (id == 0)
113 aml_snd_update_bits(IO_PDM_BUS, reg, mask, val);
114 else if (id == 1)
115 aml_snd_update_bits(IO_PDM_BUS_B, reg, mask, val);
Googler4f18c0c2022-09-20 17:23:36 +0800116}
117EXPORT_SYMBOL(aml_pdm_update_bits);
118
119int audiobus_read(unsigned int reg)
120{
121 int ret, val = 0;
122
123 ret = aml_snd_read(IO_AUDIO_BUS, reg, &val);
124
125 if (ret) {
126 pr_err("read audio reg %x error %d\n", reg, ret);
127 return -1;
128 }
129 return val;
130}
131EXPORT_SYMBOL(audiobus_read);
132
133void audiobus_write(unsigned int reg, unsigned int val)
134{
135 aml_snd_write(IO_AUDIO_BUS, reg, val);
136}
137EXPORT_SYMBOL(audiobus_write);
138
Googler38bda472022-08-19 10:07:08 -0700139void audiobus_update_bits(unsigned int reg, unsigned int mask,
140 unsigned int val)
Googler4f18c0c2022-09-20 17:23:36 +0800141{
142 aml_snd_update_bits(IO_AUDIO_BUS, reg, mask, val);
143}
144EXPORT_SYMBOL(audiobus_update_bits);
145
146int audiolocker_read(unsigned int reg)
147{
148 int ret, val = 0;
149
150 ret = aml_snd_read(IO_AUDIO_LOCKER, reg, &val);
151
152 if (ret) {
153 pr_err("read reg %x error %d\n", reg, ret);
154 return -1;
155 }
156 return val;
157}
158EXPORT_SYMBOL(audiolocker_read);
159
160void audiolocker_write(unsigned int reg, unsigned int val)
161{
162 aml_snd_write(IO_AUDIO_LOCKER, reg, val);
163}
164EXPORT_SYMBOL(audiolocker_write);
165
Googler38bda472022-08-19 10:07:08 -0700166void audiolocker_update_bits(unsigned int reg, unsigned int mask,
167 unsigned int val)
Googler4f18c0c2022-09-20 17:23:36 +0800168{
169 aml_snd_update_bits(IO_AUDIO_LOCKER, reg, mask, val);
170}
171EXPORT_SYMBOL(audiolocker_update_bits);
172
173int eqdrc_read(unsigned int reg)
174{
175 int ret, val = 0;
176
177 ret = aml_snd_read(IO_EQDRC_BUS, reg, &val);
178
179 if (ret) {
180 pr_err("read audio reg %x error %d\n", reg, ret);
181 return -1;
182 }
183 return val;
184}
185EXPORT_SYMBOL(eqdrc_read);
186
187void eqdrc_write(unsigned int reg, unsigned int val)
188{
189 aml_snd_write(IO_EQDRC_BUS, reg, val);
190}
191EXPORT_SYMBOL(eqdrc_write);
192
Googler38bda472022-08-19 10:07:08 -0700193void eqdrc_update_bits(unsigned int reg, unsigned int mask,
194 unsigned int val)
Googler4f18c0c2022-09-20 17:23:36 +0800195{
196 aml_snd_update_bits(IO_EQDRC_BUS, reg, mask, val);
197}
198EXPORT_SYMBOL(eqdrc_update_bits);
199
Googler4f18c0c2022-09-20 17:23:36 +0800200int vad_read(unsigned int reg)
201{
202 int ret, val = 0;
203
204 ret = aml_snd_read(IO_VAD, reg, &val);
205
206 if (ret) {
207 pr_err("read audio reg %x error %d\n", reg, ret);
208 return -1;
209 }
210 return val;
211}
212EXPORT_SYMBOL(vad_read);
213
214void vad_write(unsigned int reg, unsigned int val)
215{
216 aml_snd_write(IO_VAD, reg, val);
217}
218EXPORT_SYMBOL(vad_write);
219
Googler38bda472022-08-19 10:07:08 -0700220void vad_update_bits(unsigned int reg, unsigned int mask,
221 unsigned int val)
Googler4f18c0c2022-09-20 17:23:36 +0800222{
223 aml_snd_update_bits(IO_VAD, reg, mask, val);
224}
225EXPORT_SYMBOL(vad_update_bits);
226
Googler38bda472022-08-19 10:07:08 -0700227unsigned int new_resample_read(enum resample_idx id, unsigned int reg)
Googler4f18c0c2022-09-20 17:23:36 +0800228{
Googler38bda472022-08-19 10:07:08 -0700229 unsigned int val = 0;
Googler4f18c0c2022-09-20 17:23:36 +0800230
Googler38bda472022-08-19 10:07:08 -0700231 if (id == RESAMPLE_A)
232 val = readl((aml_snd_reg_map[IO_RESAMPLEA] +
233 (reg << 2)));
234 else if (id == RESAMPLE_B)
235 val = readl((aml_snd_reg_map[IO_RESAMPLEB] +
236 (reg << 2)));
Googler4f18c0c2022-09-20 17:23:36 +0800237
Googler4f18c0c2022-09-20 17:23:36 +0800238 return val;
239}
Googler4f18c0c2022-09-20 17:23:36 +0800240
Googler38bda472022-08-19 10:07:08 -0700241void new_resample_write(enum resample_idx id, unsigned int reg,
242 unsigned int val)
Googler4f18c0c2022-09-20 17:23:36 +0800243{
Googler38bda472022-08-19 10:07:08 -0700244 if (id == RESAMPLE_A)
245 writel(val, (aml_snd_reg_map[IO_RESAMPLEA] + (reg << 2)));
246 else if (id == RESAMPLE_B)
247 writel(val, (aml_snd_reg_map[IO_RESAMPLEB] + (reg << 2)));
Googler4f18c0c2022-09-20 17:23:36 +0800248}
Googler4f18c0c2022-09-20 17:23:36 +0800249
Googler38bda472022-08-19 10:07:08 -0700250void new_resample_update_bits(enum resample_idx id, unsigned int reg,
251 unsigned int mask, unsigned int val)
Googler4f18c0c2022-09-20 17:23:36 +0800252{
Googler38bda472022-08-19 10:07:08 -0700253 unsigned int tmp, orig;
254
255 orig = new_resample_read(id, reg);
256 tmp = orig & ~mask;
257 tmp |= val & mask;
258
259 new_resample_write(id, reg, tmp);
Googler4f18c0c2022-09-20 17:23:36 +0800260}
Googler4f18c0c2022-09-20 17:23:36 +0800261
262static int snd_iomap_probe(struct platform_device *pdev)
263{
264 struct resource res;
265 struct device_node *np, *child;
266 int i = 0;
267 int ret = 0;
268
269 np = pdev->dev.of_node;
270 for_each_child_of_node(np, child) {
271 if (of_address_to_resource(child, 0, &res)) {
272 ret = -1;
Googler9398cc32022-12-02 17:21:52 +0800273 pr_err("%s could not get resource", __func__);
Googler4f18c0c2022-09-20 17:23:36 +0800274 break;
275 }
276 aml_snd_reg_map[i] =
277 ioremap_nocache(res.start, resource_size(&res));
278 pr_info("aml_snd_reg_map[%d], reg:%x, size:%x\n",
279 i, (u32)res.start, (u32)resource_size(&res));
280
281 i++;
282 }
283 pr_info("amlogic %s probe done\n", DEV_NAME);
284
285 return ret;
286}
287
288static const struct of_device_id snd_iomap_dt_match[] = {
289 { .compatible = "amlogic, snd-iomap" },
290 {},
291};
292
293static struct platform_driver snd_iomap_platform_driver = {
294 .probe = snd_iomap_probe,
295 .driver = {
296 .owner = THIS_MODULE,
297 .name = DEV_NAME,
298 .of_match_table = snd_iomap_dt_match,
299 },
300};
301
302int __init auge_snd_iomap_init(void)
303{
Googler9398cc32022-12-02 17:21:52 +0800304 return platform_driver_register(&snd_iomap_platform_driver);
Googler012a81c2022-09-15 14:55:24 +0800305}
Googler9398cc32022-12-02 17:21:52 +0800306
307void __exit auge_snd_iomap_exit(void)
308{
309 platform_driver_unregister(&snd_iomap_platform_driver);
310}
311
312#ifndef MODULE
Googler4f18c0c2022-09-20 17:23:36 +0800313core_initcall(auge_snd_iomap_init);
Googler9398cc32022-12-02 17:21:52 +0800314module_exit(auge_snd_iomap_exit);
315#endif