1 #include "bflb_dac.h"
2 #include "hardware/dac_reg.h"
3
4 #if defined(BL702) || defined(BL602) || defined(BL702L)
5 #define DAC_GPIP_BASE ((uint32_t)0x40002000)
6 #elif defined(BL616) || defined(BL606P) || defined(BL808) || defined(BL628)
7 #define DAC_GPIP_BASE ((uint32_t)0x20002000)
8 #endif
9
bflb_dac_init(struct bflb_device_s * dev,uint8_t clk_div)10 void bflb_dac_init(struct bflb_device_s *dev, uint8_t clk_div)
11 {
12 uint32_t regval;
13 uint32_t reg_base;
14
15 reg_base = dev->reg_base;
16
17 /* dac reset */
18 regval = getreg32(reg_base + GLB_GPDAC_CTRL_OFFSET);
19 regval &= ~GLB_GPDACA_RSTN_ANA;
20 putreg32(regval, reg_base + GLB_GPDAC_CTRL_OFFSET);
21
22 __asm volatile("nop");
23 __asm volatile("nop");
24 __asm volatile("nop");
25 __asm volatile("nop");
26
27 regval = getreg32(reg_base + GLB_GPDAC_CTRL_OFFSET);
28 regval &= ~GLB_GPDACB_RSTN_ANA;
29 putreg32(regval, reg_base + GLB_GPDAC_CTRL_OFFSET);
30
31 __asm volatile("nop");
32 __asm volatile("nop");
33 __asm volatile("nop");
34 __asm volatile("nop");
35
36 regval = getreg32(reg_base + GLB_GPDAC_CTRL_OFFSET);
37 regval |= (GLB_GPDACA_RSTN_ANA | GLB_GPDACB_RSTN_ANA);
38 putreg32(regval, reg_base + GLB_GPDAC_CTRL_OFFSET);
39
40 regval = getreg32(reg_base + GLB_GPDAC_CTRL_OFFSET);
41 regval &= ~GLB_GPDAC_REF_SEL;
42 putreg32(regval, reg_base + GLB_GPDAC_CTRL_OFFSET);
43
44 regval = 0;
45 regval |= GPIP_GPDAC_EN;
46 #ifdef GPIP_GPDAC_EN2
47 regval |= GPIP_GPDAC_EN2;
48 #endif
49 regval |= (clk_div << GPIP_GPDAC_MODE_SHIFT);
50 putreg32(regval, DAC_GPIP_BASE + GPIP_GPDAC_CONFIG_OFFSET);
51
52 regval = getreg32(DAC_GPIP_BASE + GPIP_GPDAC_DMA_CONFIG_OFFSET);
53 regval &= ~GPIP_GPDAC_DMA_TX_EN;
54 putreg32(regval, DAC_GPIP_BASE + GPIP_GPDAC_DMA_CONFIG_OFFSET);
55 }
56
bflb_dac_channel_enable(struct bflb_device_s * dev,uint8_t ch)57 void bflb_dac_channel_enable(struct bflb_device_s *dev, uint8_t ch)
58 {
59 uint32_t regval;
60 uint32_t reg_base;
61
62 reg_base = dev->reg_base;
63
64 if (ch & DAC_CHANNEL_A) {
65 regval = getreg32(reg_base + GLB_GPDAC_ACTRL_OFFSET);
66 regval |= (GLB_GPDAC_A_EN | GLB_GPDAC_IOA_EN);
67 putreg32(regval, reg_base + GLB_GPDAC_ACTRL_OFFSET);
68 }
69
70 if (ch & DAC_CHANNEL_B) {
71 regval = getreg32(reg_base + GLB_GPDAC_BCTRL_OFFSET);
72 regval |= (GLB_GPDAC_B_EN | GLB_GPDAC_IOB_EN);
73 putreg32(regval, reg_base + GLB_GPDAC_BCTRL_OFFSET);
74 #ifdef GPIP_GPDAC_EN2
75 regval = getreg32(reg_base + GLB_GPDAC_ACTRL_OFFSET);
76 regval |= (GLB_GPDAC_A_EN | GLB_GPDAC_IOA_EN);
77 putreg32(regval, reg_base + GLB_GPDAC_ACTRL_OFFSET);
78 #endif
79 }
80 }
81
bflb_dac_channel_disable(struct bflb_device_s * dev,uint8_t ch)82 void bflb_dac_channel_disable(struct bflb_device_s *dev, uint8_t ch)
83 {
84 uint32_t regval;
85 uint32_t reg_base;
86
87 reg_base = dev->reg_base;
88
89 if (ch & DAC_CHANNEL_A) {
90 regval = getreg32(reg_base + GLB_GPDAC_ACTRL_OFFSET);
91 regval &= ~(GLB_GPDAC_A_EN | GLB_GPDAC_IOA_EN);
92 putreg32(regval, reg_base + GLB_GPDAC_ACTRL_OFFSET);
93 }
94
95 if (ch & DAC_CHANNEL_B) {
96 regval = getreg32(reg_base + GLB_GPDAC_BCTRL_OFFSET);
97 regval &= ~(GLB_GPDAC_B_EN | GLB_GPDAC_IOB_EN);
98 putreg32(regval, reg_base + GLB_GPDAC_BCTRL_OFFSET);
99 }
100 }
101
bflb_dac_link_txdma(struct bflb_device_s * dev,bool enable)102 void bflb_dac_link_txdma(struct bflb_device_s *dev, bool enable)
103 {
104 uint32_t regval1;
105 uint32_t regval2;
106 uint32_t reg_base;
107 uint8_t flag = 0;
108
109 reg_base = dev->reg_base;
110
111 regval1 = getreg32(DAC_GPIP_BASE + GPIP_GPDAC_CONFIG_OFFSET);
112 regval1 &= ~GPIP_GPDAC_CH_A_SEL_MASK;
113 regval1 &= ~GPIP_GPDAC_CH_B_SEL_MASK;
114
115 regval2 = getreg32(DAC_GPIP_BASE + GPIP_GPDAC_DMA_CONFIG_OFFSET);
116 if (enable) {
117 if (getreg32(reg_base + GLB_GPDAC_ACTRL_OFFSET) & (GLB_GPDAC_A_EN | GLB_GPDAC_IOA_EN)) {
118 regval1 |= (1 << GPIP_GPDAC_CH_A_SEL_SHIFT);
119 flag++;
120 }
121
122 if (getreg32(reg_base + GLB_GPDAC_BCTRL_OFFSET) & (GLB_GPDAC_B_EN | GLB_GPDAC_IOB_EN)) {
123 regval1 |= (1 << GPIP_GPDAC_CH_B_SEL_SHIFT);
124 flag++;
125 }
126
127 if (flag == 1) {
128 regval2 |= (0 << GPIP_GPDAC_DMA_FORMAT_SHIFT);
129 } else {
130 regval2 |= (1 << GPIP_GPDAC_DMA_FORMAT_SHIFT);
131 }
132 regval2 |= GPIP_GPDAC_DMA_TX_EN;
133 } else {
134 regval2 &= ~GPIP_GPDAC_DMA_TX_EN;
135 }
136 putreg32(regval2, DAC_GPIP_BASE + GPIP_GPDAC_DMA_CONFIG_OFFSET);
137 putreg32(regval1, DAC_GPIP_BASE + GPIP_GPDAC_CONFIG_OFFSET);
138 }
139
bflb_dac_set_value(struct bflb_device_s * dev,uint8_t ch,uint16_t value)140 void bflb_dac_set_value(struct bflb_device_s *dev, uint8_t ch, uint16_t value)
141 {
142 uint32_t regval;
143 uint32_t reg_base;
144
145 reg_base = dev->reg_base;
146
147 regval = getreg32(reg_base + GLB_GPDAC_DATA_OFFSET);
148
149 if (ch & DAC_CHANNEL_A) {
150 regval &= ~GLB_GPDAC_A_DATA_MASK;
151 regval |= (value << GLB_GPDAC_A_DATA_SHIFT);
152 }
153
154 if (ch & DAC_CHANNEL_B) {
155 regval &= ~GLB_GPDAC_B_DATA_MASK;
156 regval |= (value << GLB_GPDAC_B_DATA_SHIFT);
157 }
158
159 putreg32(regval, reg_base + GLB_GPDAC_DATA_OFFSET);
160 }