15
15
#include " Driver/tas5805m/tas5805m.h"
16
16
#include " Driver/wm8960/mtb_wm8960.h"
17
17
#include " Driver/wm8994/wm8994.h"
18
+ #include " Driver/wm8978/WM8978.h"
18
19
#include " DriverPins.h"
19
20
20
21
namespace audio_driver {
@@ -41,7 +42,7 @@ class CodecConfig : public codec_config_t {
41
42
i2s.bits = BIT_LENGTH_16BITS;
42
43
i2s.rate = RATE_44K;
43
44
i2s.channels = CHANNELS2;
44
- i2s.fmt = I2S_NORMAL;
45
+ i2s.fmt = I2S_NORMAL;
45
46
// codec is slave - microcontroller is master
46
47
i2s.mode = MODE_SLAVE;
47
48
}
@@ -107,20 +108,20 @@ class CodecConfig : public codec_config_t {
107
108
108
109
// / Defines the number of channels
109
110
bool setChannelsNumeric (int channels) {
110
- switch (2 ){
111
+ switch (2 ) {
111
112
case CHANNELS2:
112
- i2s.channels = (channels_t )channels;
113
+ i2s.channels = (channels_t )channels;
113
114
return true ;
114
115
case CHANNELS8:
115
- i2s.channels = (channels_t )channels;
116
+ i2s.channels = (channels_t )channels;
116
117
return true ;
117
118
case CHANNELS16:
118
- i2s.channels = (channels_t )channels;
119
+ i2s.channels = (channels_t )channels;
119
120
return true ;
120
121
default :
121
- i2s.channels = CHANNELS2;
122
+ i2s.channels = CHANNELS2;
122
123
return false ;
123
- }
124
+ }
124
125
}
125
126
126
127
// / Sets the sample rate as number: returns the effectively set rate
@@ -196,6 +197,8 @@ class AudioDriver {
196
197
AD_LOGD (" AudioDriver::begin:setPAPower" );
197
198
setPAPower (true );
198
199
AD_LOGD (" AudioDriver::begin:completed" );
200
+ // setup default volume
201
+ setVolume (DRIVER_DEFAULT_VOLUME);
199
202
return result;
200
203
}
201
204
virtual bool setConfig (CodecConfig codecCfg) {
@@ -1071,6 +1074,129 @@ class AudioDriverWM8960Class : public AudioDriver {
1071
1074
}
1072
1075
};
1073
1076
1077
+ /* *
1078
+ * @brief Driver API for the wm8978 codec chip
1079
+ * @author Phil Schatzmann
1080
+ * @copyright GPLv3
1081
+ */
1082
+ class AudioDriverWM8978Class : public AudioDriver {
1083
+ public:
1084
+ AudioDriverWM8978Class () {}
1085
+
1086
+ bool begin (CodecConfig codecCfg, DriverPins &pins) override {
1087
+ bool rc = true ;
1088
+ codec_cfg = codecCfg;
1089
+ auto i2c = pins.getI2CPins (PinFunction::CODEC);
1090
+ if (!i2c) {
1091
+ rc = wm8078.begin ();
1092
+ } else {
1093
+ auto i2c_pins = i2c.value ();
1094
+ rc = wm8078.begin (i2c_pins.sda , i2c_pins.scl , i2c_pins.frequency );
1095
+ }
1096
+ bool is_dac = codec_cfg.output_device != DAC_OUTPUT_NONE;
1097
+ bool is_adc = codec_cfg.input_device != ADC_INPUT_NONE;
1098
+ wm8078.cfgADDA (is_dac, is_adc);
1099
+
1100
+ bool is_mic = codec_cfg.input_device == ADC_INPUT_LINE1 ||
1101
+ codec_cfg.input_device == ADC_INPUT_ALL;
1102
+ bool is_linein = codec_cfg.input_device == ADC_INPUT_LINE2 ||
1103
+ codec_cfg.input_device == ADC_INPUT_ALL;
1104
+ bool is_auxin = codec_cfg.input_device == ADC_INPUT_LINE3 ||
1105
+ codec_cfg.input_device == ADC_INPUT_ALL;
1106
+ wm8078.cfgInput (is_mic, is_linein, is_auxin);
1107
+ wm8078.cfgOutput (is_dac, false );
1108
+
1109
+ int bits = toBits (codecCfg.i2s .bits );
1110
+ if (bits < 0 ) return false ;
1111
+ int i2s = toI2S (codecCfg.i2s .fmt );
1112
+ if (i2s < 0 ) return false ;
1113
+ wm8078.cfgI2S (i2s, bits);
1114
+
1115
+ // setup initial default volume
1116
+ setVolume (DRIVER_DEFAULT_VOLUME);
1117
+
1118
+ return rc;
1119
+ }
1120
+
1121
+ bool end () override {
1122
+ setVolume (0 );
1123
+ wm8078.cfgADDA (false , false );
1124
+ return true ;
1125
+ }
1126
+
1127
+ bool setMute (bool mute) override {
1128
+ if (mute) {
1129
+ int tmp = volume;
1130
+ setVolume (0 );
1131
+ volume = tmp;
1132
+ } else {
1133
+ setVolume (volume);
1134
+ }
1135
+ return true ;
1136
+ }
1137
+
1138
+ bool setVolume (int volume) override {
1139
+ this ->volume = volume;
1140
+ int scaled = map (volume, 0 , 100 , 0 , 63 );
1141
+ wm8078.setSPKvol (scaled);
1142
+ wm8078.setHPvol (scaled, scaled);
1143
+ return true ;
1144
+ }
1145
+
1146
+ int getVolume () override { return volume; }
1147
+
1148
+ bool setInputVolume (int volume) override {
1149
+ int scaled = map (volume, 0 , 100 , 0 , 63 );
1150
+ wm8078.setMICgain (scaled);
1151
+ wm8078.setAUXgain (scaled);
1152
+ wm8078.setLINEINgain (scaled);
1153
+ return true ;
1154
+ }
1155
+
1156
+ bool isVolumeSupported () override { return true ; }
1157
+
1158
+ bool isInputVolumeSupported () override { return true ; }
1159
+
1160
+ WM8978& driver () {
1161
+ return wm8078;
1162
+ }
1163
+
1164
+ protected:
1165
+ WM8978 wm8078;
1166
+ int volume = 0 ;
1167
+
1168
+ // / fmt:0,LSB(right-aligned);1,MSB(left-aligned);2,Philips standard,
1169
+ // / I2S;3,PCM/DSP;
1170
+ int toI2S (i2s_format_t fmt) {
1171
+ switch (fmt) {
1172
+ case I2S_NORMAL:
1173
+ return 2 ;
1174
+ case I2S_LEFT:
1175
+ return 1 ;
1176
+ case I2S_RIGHT:
1177
+ return 0 ;
1178
+ case I2S_DSP:
1179
+ return 3 ;
1180
+ }
1181
+ return -1 ;
1182
+ }
1183
+
1184
+ // len: 0, 16 digits; 1, 20 digits; 2, 24 digits; 3, 32 digits;
1185
+ int toBits (sample_bits_t bits) {
1186
+ switch (bits) {
1187
+ case BIT_LENGTH_16BITS:
1188
+ return 0 ;
1189
+ case BIT_LENGTH_20BITS:
1190
+ return 1 ;
1191
+ case BIT_LENGTH_24BITS:
1192
+ return 2 ;
1193
+ case BIT_LENGTH_32BITS:
1194
+ return 3 ;
1195
+ }
1196
+ return -1 ;
1197
+ }
1198
+ };
1199
+
1074
1200
/* *
1075
1201
* @brief Driver API for the wm8994 codec chip
1076
1202
* @author Phil Schatzmann
0 commit comments