Skip to content

Commit b68d40b

Browse files
committed
AudioDriverWM8978Class
1 parent 7256f10 commit b68d40b

File tree

1 file changed

+133
-7
lines changed

1 file changed

+133
-7
lines changed

src/Driver.h

Lines changed: 133 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "Driver/tas5805m/tas5805m.h"
1616
#include "Driver/wm8960/mtb_wm8960.h"
1717
#include "Driver/wm8994/wm8994.h"
18+
#include "Driver/wm8978/WM8978.h"
1819
#include "DriverPins.h"
1920

2021
namespace audio_driver {
@@ -41,7 +42,7 @@ class CodecConfig : public codec_config_t {
4142
i2s.bits = BIT_LENGTH_16BITS;
4243
i2s.rate = RATE_44K;
4344
i2s.channels = CHANNELS2;
44-
i2s.fmt = I2S_NORMAL;
45+
i2s.fmt = I2S_NORMAL;
4546
// codec is slave - microcontroller is master
4647
i2s.mode = MODE_SLAVE;
4748
}
@@ -107,20 +108,20 @@ class CodecConfig : public codec_config_t {
107108

108109
/// Defines the number of channels
109110
bool setChannelsNumeric(int channels) {
110-
switch(2){
111+
switch (2) {
111112
case CHANNELS2:
112-
i2s.channels = (channels_t)channels;
113+
i2s.channels = (channels_t)channels;
113114
return true;
114115
case CHANNELS8:
115-
i2s.channels = (channels_t)channels;
116+
i2s.channels = (channels_t)channels;
116117
return true;
117118
case CHANNELS16:
118-
i2s.channels = (channels_t)channels;
119+
i2s.channels = (channels_t)channels;
119120
return true;
120121
default:
121-
i2s.channels = CHANNELS2;
122+
i2s.channels = CHANNELS2;
122123
return false;
123-
}
124+
}
124125
}
125126

126127
/// Sets the sample rate as number: returns the effectively set rate
@@ -196,6 +197,8 @@ class AudioDriver {
196197
AD_LOGD("AudioDriver::begin:setPAPower");
197198
setPAPower(true);
198199
AD_LOGD("AudioDriver::begin:completed");
200+
// setup default volume
201+
setVolume(DRIVER_DEFAULT_VOLUME);
199202
return result;
200203
}
201204
virtual bool setConfig(CodecConfig codecCfg) {
@@ -1071,6 +1074,129 @@ class AudioDriverWM8960Class : public AudioDriver {
10711074
}
10721075
};
10731076

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+
10741200
/**
10751201
* @brief Driver API for the wm8994 codec chip
10761202
* @author Phil Schatzmann

0 commit comments

Comments
 (0)