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