1 /*
2  * Copyright (c) 2024 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #ifndef _HPM_W8978_H_
9 #define _HPM_W8978_H_
10 
11 #include "hpm_i2c_drv.h"
12 #include "hpm_wm8978_regs.h"
13 
14 typedef enum wm8978_audio_interface {
15     wm8978_right_justified = 0,  /* Right Justified */
16     wm8978_left_justified,       /* Left Justified */
17     wm8978_philips_i2s,          /* I2S format */
18     wm8978_pcm_mode,             /* DSP/PCM mode */
19 } wm8978_audio_interface_t;
20 
21 typedef enum wm8978_word_length {
22     wm8978_16bits_length        = 0,  /* 16bits */
23     wm8978_20bits_length,           /* 20bits */
24     wm8978_24bits_length,           /* 24bits */
25     wm8978_32bits_length,           /* 32bits */
26 } wm8978_word_length_t;
27 
28 typedef enum wm8978_out_channel {
29     wm8978_out1_channel         = 0,  /* R/LOUT1 channel. */
30     wm8978_out2_channel         = 1, /*  R/LOUT2 channel. */
31 } wm8978_out_channel_t;
32 
33 typedef enum input_channel_flag {
34     input_off                  = 0x00,    /* no input */
35     mic_left_on                = 0x01,    /* LIN,LIP pin,MIC left input */
36     mic_right_on               = 0x02,    /* RIN,RIP pin,MIC right input */
37     line_on                    = 0x04,    /* L2,R2 pin input */
38     aux_on                     = 0x08,    /* AUXL,AUXR pins input */
39     dac_on                     = 0x10,    /* dac for i2s */
40     adc_on                     = 0x20     /* input fed into the WM8978 internal ADC */
41 } input_channel_flags_t;
42 
43 /* WM8978 音频输出通道控制选项, 可以选择多路 */
44 typedef enum output_channel_flag {
45     output_off                 = 0x00,    /* no output */
46     earphone_left_on           = 0x01,    /* LOUT1 earphone */
47     earphone_right_on          = 0x02,    /* ROUT1 earphone */
48     spk_on                     = 0x04,    /* LOUT2 and ROUT2 Inverting output mono*/
49     out_3_4_on                 = 0x08,    /* OUT3 and OUT4 output mono audio*/
50 } output_channel_flag_t;
51 
52 typedef struct {
53     I2C_Type *ptr;                      /* I2C bus */
54     uint8_t device_address;             /* code device address */
55 } wm8978_context_t;
56 
57 #if defined(__cplusplus)
58 extern "C" {
59 #endif
60 
61 /**
62  * @brief WM8979 initialize function.
63  *
64  * @param [in] control WM8979 control structure.
65  * @retval hpm_stat_t status_success if init without any error
66  */
67 hpm_stat_t wm8979_init(wm8978_context_t *control);
68 
69 /**
70  * @brief WM8979 set out volume function.
71  *
72  * @param [in] control WM8979 control structure.
73  * @param [in] channel out channel
74  * @param [in] volume volume value
75  * @retval hpm_stat_t status_success if set without any error
76  */
77 hpm_stat_t wm8978_set_out_volume(wm8978_context_t *control, wm8978_out_channel_t channel, uint8_t volume);
78 
79 /**
80  * @brief WM8979 read out volume function.
81  *
82  * @param [in] control WM8979 control structure.
83  * @param [in] channel out channel
84  * @param [out] volume volume points value
85  * @retval hpm_stat_t status_success if set without any error
86  */
87 hpm_stat_t wm8978_get_out_volume(wm8978_context_t *control, wm8978_out_channel_t channel, uint8_t *volume);
88 
89 /**
90  * @brief WM8979 set out mute.
91  *
92  * @param [in] control WM8979 control structure.
93  * @param [in] channel out channel
94  * @param [in] mute if mute is set to true
95  * @retval hpm_stat_t status_success if set without any error
96  */
97 hpm_stat_t wm8978_set_out_mute(wm8978_context_t *control, wm8978_out_channel_t channel, bool mute);
98 
99 /**
100  * @brief WM8979 set gain of mic.
101  *
102  * @param [in] control WM8979 control structure.
103  * @param [in] gain gain value, range: 0 ~ 63
104  * @retval hpm_stat_t status_success if set without any error
105  */
106 hpm_stat_t wm8978_set_mic_gain(wm8978_context_t *control, uint8_t gain);
107 
108 /**
109  * @brief WM8979 set the gain of the Line input channel
110  *
111  * @param [in] control WM8979 control structure.
112  * @param [in] gain volume value, range: 0 ~ 7
113  * @retval hpm_stat_t status_success if set without any error
114  */
115 hpm_stat_t wm8978_set_line_gain(wm8978_context_t *control, uint8_t gain);
116 
117 /**
118  * @brief WM8979 enter power down mode
119  *
120  * @param [in] control WM8979 control structure.
121  * @retval hpm_stat_t status_success if set without any error
122  */
123 hpm_stat_t wm8978_power_down(wm8978_context_t *control);
124 
125 /**
126  * @brief Control the GPIO1 pin of WM8978 to output high or low
127  *
128  * @param [in] control WM8979 control structure.
129  * @param [in] value output high or low. if true, it's high
130  * @retval hpm_stat_t status_success if set without any error
131  */
132 hpm_stat_t wm8978_ctrl_gpio1(wm8978_context_t *control, bool value);
133 
134 /**
135  * @brief Configuring the audio interface of WM8978
136  *
137  * @param [in] control WM8979 control structure.
138  * @param [in] standard wm8978_audio_interface_t structure
139  * @param [in] word_len wm8978_word_length_t structure
140  * @retval hpm_stat_t status_success if set without any error
141  */
142 hpm_stat_t wm8978_cfg_audio_interface(wm8978_context_t *control,
143                                         wm8978_audio_interface_t standard,
144                                         wm8978_word_length_t word_len);
145 
146 /**
147  * @brief Configure wm8978 audio channel
148  *
149  * @param [in] control WM8979 control structure.
150  * @param [in] in_flags input_channel_flags_t structure
151  * @param [in] out_flags output_channel_flag_t structure
152  * @retval hpm_stat_t status_success if set without any error
153  */
154 hpm_stat_t wm8978_cfg_audio_channel(wm8978_context_t *control,
155                                     input_channel_flags_t in_flags,
156                                     output_channel_flag_t out_flags);
157 
158 /**
159  * @brief setting the Notch Filter for WM8978
160  *
161  * @note used to suppress positive feedback of microphone sound waves to avoid howling
162  * @param [in] control WM8979 control structure.
163  * @param [in] nfa0 Notch Filter0 value
164  * @param [in] nfa1 Notch Filter1 value
165  * @retval hpm_stat_t status_success if set without any error
166  */
167 hpm_stat_t wm8978_notch_filter(wm8978_context_t *control, uint16_t nfa0, uint16_t nfa1);
168 
169 /**
170  * @brief Write register to WM8978 using I2C.
171  *
172  * @param [in] control WM8978 control structure.
173  * @retval hpm_stat_t status_success if reset without any error
174  */
175 hpm_stat_t wm8978_reset(wm8978_context_t *control);
176 
177 /**
178  * @brief Write register to WM8978 using I2C.
179  *
180  * @param [in] control WM8978 control structure.
181  * @param [in] reg The register address in WM8978.
182  * @param [in] val Value needs to write into the register.
183  * @retval hpm_stat_t status_success if write reg without any error
184  */
185 hpm_stat_t wm8978_write_reg(wm8978_context_t *control, uint8_t reg, uint16_t val);
186 
187 /**
188  * @brief Read register from WM8978 using I2C.
189  * @param [in] reg The register address in WM8978.
190  * @param [in] reg The register address in WM8978.
191  * @param [out] val Value point read to.
192  * @retval hpm_stat_t status_success if read reg without any error
193  */
194 hpm_stat_t wm8978_read_reg(wm8978_context_t *control, uint8_t reg, uint16_t *val);
195 
196 /**
197  * @brief Modify some bits in the register using I2C.
198  * @param [in] control WM8978 control structure.
199  * @param [in] reg The register address in WM8978.
200  * @param [in] mask The mask code for the bits want to write. The bit you want to write should be 0.
201  * @param [in] val Value needs to write into the register.
202  * @retval hpm_stat_t status_success if modify reg without any error
203  */
204 hpm_stat_t wm8978_modify_reg(wm8978_context_t *control, uint8_t reg, uint16_t mask, uint16_t val);
205 
206 #ifdef __cplusplus
207 }
208 #endif
209 
210 /**
211  * @}
212  *
213  */
214 
215 #endif /* HPM_WM8978_H */