1 /*
2 * Copyright (c) 2019-2025 Allwinner Technology Co., Ltd. ALL rights reserved.
3 *
4 * Allwinner is a trademark of Allwinner Technology Co.,Ltd., registered in
5 * the the people's Republic of China and other countries.
6 * All Allwinner Technology Co.,Ltd. trademarks are used with permission.
7 *
8 * DISCLAIMER
9 * THIRD PARTY LICENCES MAY BE REQUIRED TO IMPLEMENT THE SOLUTION/PRODUCT.
10 * IF YOU NEED TO INTEGRATE THIRD PARTY’S TECHNOLOGY (SONY, DTS, DOLBY, AVS OR MPEGLA, ETC.)
11 * IN ALLWINNERS’SDK OR PRODUCTS, YOU SHALL BE SOLELY RESPONSIBLE TO OBTAIN
12 * ALL APPROPRIATELY REQUIRED THIRD PARTY LICENCES.
13 * ALLWINNER SHALL HAVE NO WARRANTY, INDEMNITY OR OTHER OBLIGATIONS WITH RESPECT TO MATTERS
14 * COVERED UNDER ANY REQUIRED THIRD PARTY LICENSE.
15 * YOU ARE SOLELY RESPONSIBLE FOR YOUR USAGE OF THIRD PARTY’S TECHNOLOGY.
16 *
17 *
18 * THIS SOFTWARE IS PROVIDED BY ALLWINNER"AS IS" AND TO THE MAXIMUM EXTENT
19 * PERMITTED BY LAW, ALLWINNER EXPRESSLY DISCLAIMS ALL WARRANTIES OF ANY KIND,
20 * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION REGARDING
21 * THE TITLE, NON-INFRINGEMENT, ACCURACY, CONDITION, COMPLETENESS, PERFORMANCE
22 * OR MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23 * IN NO EVENT SHALL ALLWINNER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS, OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
30 * OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32 #include <hal_cmd.h>
33 #include <sound/snd_core.h>
34 #include "sunxi-codec.h"
35
36
37 /*#define TEST_MODE*/
38
39 #ifndef u32
40 #define u32 unsigned int
41 #endif
42
43 #define ADDR_WIDTH 0x3f
44
45 u32 read_prcm_wvalue(u32 addr, void *ADDA_PR_CFG_REG);
46 void write_prcm_wvalue(u32 addr, u32 val, void *ADDA_PR_CFG_REG);
47
sunxi_codec_read(struct snd_codec * codec,unsigned int reg)48 unsigned int sunxi_codec_read(struct snd_codec *codec, unsigned int reg)
49 {
50 /* struct sunxi_codec_info *sunxi_codec = codec->private_data; */
51 unsigned int reg_val;
52
53 if (reg >= SUNXI_PR_CFG) {
54 reg = reg - SUNXI_PR_CFG;
55 return read_prcm_wvalue(reg, codec->codec_base_addr + SUNXI_PR_CFG);
56 } else {
57 #ifdef TEST_MODE
58 reg_val = 0x1;
59 #else
60 reg_val = snd_readl(codec->codec_base_addr + reg);
61 #endif
62 }
63 return reg_val;
64 }
65
sunxi_codec_write(struct snd_codec * codec,unsigned int reg,unsigned int val)66 unsigned int sunxi_codec_write(struct snd_codec *codec, unsigned int reg, unsigned int val)
67 {
68 /* struct sunxi_codec_info *sunxi_codec = codec->private_data; */
69
70 if (reg >= SUNXI_PR_CFG) {
71 reg = reg - SUNXI_PR_CFG;
72 write_prcm_wvalue(reg, val, codec->codec_base_addr + SUNXI_PR_CFG);
73 } else {
74 #ifndef TEST_MODE
75 snd_writel(val, codec->codec_base_addr + reg);
76 #endif
77 }
78 return 0;
79 }
80
read_prcm_wvalue(u32 addr,void * ADDA_PR_CFG_REG)81 u32 read_prcm_wvalue(u32 addr, void *ADDA_PR_CFG_REG)
82 {
83 u32 reg = 0;
84
85 #ifndef TEST_MODE
86 reg = snd_readl(ADDA_PR_CFG_REG);
87 reg |= (0x1 << 28);
88 snd_writel(reg, ADDA_PR_CFG_REG);
89
90 reg = snd_readl(ADDA_PR_CFG_REG);
91 reg &= ~(0x1 << 24);
92 snd_writel(reg, ADDA_PR_CFG_REG);
93
94 reg = snd_readl(ADDA_PR_CFG_REG);
95 reg &= ~(ADDR_WIDTH << 16);
96 reg |= (addr << 16);
97 snd_writel(reg, ADDA_PR_CFG_REG);
98
99 reg = snd_readl(ADDA_PR_CFG_REG);
100 reg &= (0xff << 0);
101 #endif
102
103 return reg;
104 }
105
write_prcm_wvalue(u32 addr,u32 val,void * ADDA_PR_CFG_REG)106 void write_prcm_wvalue(u32 addr, u32 val, void *ADDA_PR_CFG_REG)
107 {
108 u32 reg;
109
110 #ifndef TEST_MODE
111 reg = snd_readl(ADDA_PR_CFG_REG);
112 reg |= (0x1 << 28);
113 snd_writel(reg, ADDA_PR_CFG_REG);
114
115 reg = snd_readl(ADDA_PR_CFG_REG);
116 reg &= ~(ADDR_WIDTH << 16);
117 reg |= (addr << 16);
118 snd_writel(reg, ADDA_PR_CFG_REG);
119
120 reg = snd_readl(ADDA_PR_CFG_REG);
121 reg &= ~(0xff << 8);
122 reg |= (val << 8);
123 snd_writel(reg, ADDA_PR_CFG_REG);
124
125 reg = snd_readl(ADDA_PR_CFG_REG);
126 reg |= (0x1 << 24);
127 snd_writel(reg, ADDA_PR_CFG_REG);
128
129 reg = snd_readl(ADDA_PR_CFG_REG);
130 reg &= ~(0x1 << 24);
131 snd_writel(reg, ADDA_PR_CFG_REG);
132 #endif
133 }
134
135 #include <console.h>
sunxi_audiocodec_reg_dump(void)136 __attribute__((weak)) void sunxi_audiocodec_reg_dump(void)
137 {
138
139 }
140
cmd_audiocodec_dump(int argc,char * argv[])141 int cmd_audiocodec_dump(int argc, char *argv[])
142 {
143 /*TODO, add read,write function */
144 sunxi_audiocodec_reg_dump();
145 }
146 FINSH_FUNCTION_EXPORT_CMD(cmd_audiocodec_dump, audiocodec, audiocodec dump reg);
147