1 /* 2 * Copyright (c) 2015, Freescale Semiconductor, Inc. 3 * Copyright 2016-2021 NXP 4 * Copyright (c) 2022 HPMicro 5 * 6 * SPDX-License-Identifier: BSD-3-Clause 7 * 8 */ 9 10 #ifndef _HPM_WM8960_H_ 11 #define _HPM_WM8960_H_ 12 13 //#include "hpm_i2c_drv.h" 14 //#include "hpm_common.h" 15 #include <rtthread.h> 16 #include <rtdevice.h> 17 #include "rtt_board.h" 18 #include "drivers/i2c.h" 19 #include "hpm_wm8960_regs.h" 20 21 #define WM8960_I2C_ADDR 0x1A 22 23 typedef enum wm8960_module { 24 wm8960_module_adc = 0, /* ADC module in WM8960 */ 25 wm8960_module_dac = 1, /* DAC module in WM8960 */ 26 wm8960_module_vref = 2, /* VREF module */ 27 wm8960_module_headphone = 3, /* Headphone */ 28 wm8960_module_micbais = 4, /* Mic bias */ 29 wm8960_module_ana_in = 6, /* Analog in PGA */ 30 wm8960_module_lineout = 7, /* Line out module */ 31 wm8960_module_speaker = 8, /* Speaker module */ 32 wm8960_module_output_mixer = 9, /* Output mixer */ 33 } wm8960_module_t; 34 35 /* wm8960 play source for output mixer */ 36 typedef enum wm8960_play_source { 37 wm8960_play_source_input_mixer = 1, /* Input Boost Mixer to Output Mixer */ 38 wm8960_play_source_input3 = 2, /* L/RINPUT3 to Output Mixer */ 39 wm8960_play_source_dac = 4, /* DAC to Output Mixer */ 40 } wm8960_play_source_t; 41 42 /* WM8960 data route */ 43 typedef enum wm8960_route { 44 wm8960_route_bypass = 0, /* ANA_IN->Headphone. */ 45 wm8960_route_playback = 1, /* I2SIN->DAC->Headphone. */ 46 wm8960_route_playback_and_record = 2, /* I2SIN->DAC->Headphone, ANA_IN->ADC->I2SOUT. */ 47 wm8960_route_record = 5 /* ANA_IN->ADC->I2SOUT. */ 48 } wm8960_route_t; 49 50 /* The audio data transfer protocol choice */ 51 typedef enum wm8960_protocol { 52 wm8960_bus_i2s = 2, /* I2S type */ 53 wm8960_bus_left_justified = 1, /* Left justified mode */ 54 wm8960_bus_right_justified = 0, /* Right justified mode */ 55 wm8960_bus_pcma = 3, /* PCM A mode */ 56 wm8960_bus_pcmb = 3 | (1 << 4) /* PCM B mode */ 57 } wm8960_protocol_t; 58 59 /* wm8960 input source */ 60 typedef enum wm8960_input { 61 wm8960_input_closed = 0, /* Input device is closed */ 62 wm8960_input_single_ended_mic = 1, /* Input as single ended mic, only use L/RINPUT1 */ 63 wm8960_input_differential_mic_input2 = 2, /* Input as differential mic, use L/RINPUT1 and L/RINPUT2 */ 64 wm8960_input_differential_mic_input3 = 3, /* Input as differential mic, use L/RINPUT1 and L/RINPUT3*/ 65 wm8960_input_line_input2 = 4, /* Input as line input, only use L/RINPUT2 */ 66 wm8960_input_line_input3 = 5 /* Input as line input, only use L/RINPUT3 */ 67 } wm8960_input_t; 68 69 /* wm8960 audio format */ 70 typedef struct wm8960_audio_format { 71 uint32_t mclk_hz; /* master clock frequency */ 72 uint32_t sample_rate; /* sample rate */ 73 uint32_t bit_width; /* bit width */ 74 } wm8960_audio_format_t; 75 76 /* configure structure of WM8960 */ 77 typedef struct wm8960_config { 78 wm8960_route_t route; /* Audio data route.*/ 79 wm8960_protocol_t bus; /* Audio transfer protocol */ 80 bool enable_speaker; /* True means enable class D speaker as output, false means no */ 81 wm8960_input_t left_input; /* Left input source for WM8960 */ 82 wm8960_input_t right_input; /* Right input source for wm8960 */ 83 wm8960_play_source_t play_source; /* play source */ 84 wm8960_audio_format_t format; /* Audio format */ 85 } wm8960_config_t; 86 87 typedef struct { 88 struct rt_i2c_bus_device *i2c_bus; /* I2C bus device */ 89 uint8_t slave_address; /* code device address */ 90 } wm8960_control_t; 91 92 93 #if defined(__cplusplus) 94 extern "C" { 95 #endif 96 97 /** 98 * @brief WM8960 initialize function. 99 * 100 * @param control WM8960 control structure. 101 * @param config WM8960 configuration structure. 102 */ 103 hpm_stat_t wm8960_init(wm8960_control_t *control, wm8960_config_t *config); 104 105 /** 106 * @brief Deinit the WM8960 codec. 107 * 108 * This function close all modules in WM8960 to save power. 109 * 110 * @param control WM8960 control structure pointer. 111 */ 112 hpm_stat_t wm8960_deinit(wm8960_control_t *control); 113 114 /** 115 * @brief Set audio data route in WM8960. 116 * 117 * This function would set the data route according to route. 118 * 119 * @param control WM8960 control structure. 120 * @param config Audio configure structure in WM8960. 121 */ 122 hpm_stat_t wm8960_set_data_route(wm8960_control_t *control, wm8960_config_t *config); 123 124 /** 125 * @brief Set left audio input source in WM8960. 126 * 127 * @param control WM8960 control structure. 128 * @param input Audio input source. 129 */ 130 hpm_stat_t wm8960_set_left_input(wm8960_control_t *control, wm8960_input_t input); 131 132 /** 133 * @brief Set right audio input source in WM8960. 134 * 135 * @param control WM8960 control structure. 136 * @param input Audio input source. 137 */ 138 hpm_stat_t wm8960_set_right_input(wm8960_control_t *control, wm8960_input_t input); 139 140 /** 141 * @brief Set the audio transfer protocol. 142 * 143 * @param control WM8960 control structure. 144 * @param protocol Audio data transfer protocol. 145 */ 146 hpm_stat_t wm8960_set_protocol(wm8960_control_t *control, wm8960_protocol_t protocol); 147 148 /** 149 * @brief Set the volume of different modules in WM8960. 150 * 151 * This function would set the volume of WM8960 modules. Uses need to appoint the module. 152 * The function assume that left channel and right channel has the same volume. 153 * 154 * Module:wm8960_module_adc, volume range value: 0 is mute, 1-255 is -97db to 30db 155 * Module:wm8960_module_dac, volume range value: 0 is mute, 1-255 is -127db to 0db 156 * Module:wm8960_module_headphone, volume range value: 0 - 2F is mute, 0x30 - 0x7F is -73db to 6db 157 * Module:wm8960_module_ana_in, volume range value: 0 - 0x3F is -17.25db to 30db 158 * Module:wm8960_module_speaker, volume range value: 0 - 2F is mute, 0x30 - 0x7F is -73db to 6db 159 * 160 * 161 * @param control WM8960 control structure. 162 * @param module Module to set volume, it can be ADC, DAC, Headphone and so on. 163 * @param volume Volume value need to be set. 164 */ 165 hpm_stat_t wm8960_set_volume(wm8960_control_t *control, wm8960_module_t module, uint32_t volume); 166 167 /** 168 * @brief Enable/disable expected module. 169 * 170 * @param control WM8960 control structure. 171 * @param module Module expected to enable. 172 * @param enable Enable or disable moudles. 173 */ 174 hpm_stat_t wm8960_set_module(wm8960_control_t *control, wm8960_module_t module, bool enable); 175 176 /** 177 * @brief SET the WM8960 play source. 178 * 179 * @param control WM8960 control structure. 180 * @param play_source play source 181 * 182 * @return kStatus_WM8904_Success if successful, different code otherwise.. 183 */ 184 hpm_stat_t wm8960_config_input_to_output_mixer(wm8960_control_t *control, uint32_t play_source); 185 186 /** 187 * @brief Configure the data format of audio data. 188 * 189 * This function would configure the registers about the sample rate, bit depths. 190 * 191 * @param control WM8960 control structure pointer. 192 * @param sysclk system clock of the codec which can be generated by MCLK or PLL output. 193 * @param sample_rate Sample rate of audio file running in WM8960. WM8960 now 194 * supports 8k, 11.025k, 12k, 16k, 22.05k, 24k, 32k, 44.1k, 48k and 96k sample rate. 195 * @param bits Bit depth of audio file (WM8960 only supports 16bit, 20bit, 24bit 196 * and 32 bit in HW). 197 */ 198 hpm_stat_t wm8960_set_data_format(wm8960_control_t *control, uint32_t sysclk, uint32_t sample_rate, uint32_t bits); 199 200 201 /** 202 * @brief Write register to WM8960 using I2C. 203 * 204 * @param control WM8960 control structure. 205 * @param reg The register address in WM8960. 206 * @param val Value needs to write into the register. 207 */ 208 hpm_stat_t wm8960_write_reg(wm8960_control_t *control, uint8_t reg, uint16_t val); 209 210 /** 211 * @brief Read register from WM8960 using I2C. 212 * @param reg The register address in WM8960. 213 * @param val Value written to. 214 */ 215 hpm_stat_t wm8960_read_reg(uint8_t reg, uint16_t *val); 216 217 /** 218 * @brief Modify some bits in the register using I2C. 219 * @param control WM8960 control structure. 220 * @param reg The register address in WM8960. 221 * @param mask The mask code for the bits want to write. The bit you want to write should be 0. 222 * @param val Value needs to write into the register. 223 */ 224 hpm_stat_t wm8960_modify_reg(wm8960_control_t *control, uint8_t reg, uint16_t mask, uint16_t val); 225 226 227 #endif /* _HPM_WM8960_H_ */ 228