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 }