Philippe G před 4 roky
rodič
revize
1b39a4f7c9

+ 0 - 0
components/squeezelite/.sc3357753833280144641.c


+ 67 - 140
components/squeezelite/ac101/ac101.c

@@ -48,118 +48,84 @@ static const char TAG[] = "AC101";
         return b;\
     }
 	
-static bool init(char *config, int i2c_port_num, i2s_config_t *i2s_config);
-static void deinit(void);
+static bool init(char *config, int i2c_port, i2s_config_t *i2s_config);
 static void speaker(bool active);
 static void headset(bool active);
 static bool volume(unsigned left, unsigned right);
 static void power(adac_power_e mode);
 
-const struct adac_s dac_ac101 = { "AC101", init, deinit, power, speaker, headset, volume };
+const struct adac_s dac_ac101 = { "AC101", init, adac_deinit, power, speaker, headset, volume };
 
-static esp_err_t i2c_write_reg(uint8_t reg, uint16_t val);
-static uint16_t i2c_read_reg(uint8_t reg);
 static void ac101_start(ac_module_t mode);
 static void ac101_stop(void);
 static void ac101_set_earph_volume(uint8_t volume);
 static void ac101_set_spk_volume(uint8_t volume);
 	
-static int i2c_port;
-
 /****************************************************************************************
  * init
  */
-static bool init(char *config, int i2c_port_num, i2s_config_t *i2s_config) {	 
-	esp_err_t res = ESP_OK;
-	char *p;
-	
-	// configure i2c
-	i2c_config_t i2c_config = {
-			.mode = I2C_MODE_MASTER,
-			.sda_io_num = -1,
-			.sda_pullup_en = GPIO_PULLUP_ENABLE,
-			.scl_io_num = -1,
-			.scl_pullup_en = GPIO_PULLUP_ENABLE,
-			.master.clk_speed = 250000,
-		};
-	
-	if ((p = strcasestr(config, "sda")) != NULL) i2c_config.sda_io_num = atoi(strchr(p, '=') + 1);
-	if ((p = strcasestr(config, "scl")) != NULL) i2c_config.scl_io_num = atoi(strchr(p, '=') + 1);
-	
-	i2c_port = i2c_port_num;
-	i2c_param_config(i2c_port, &i2c_config);
-	i2c_driver_install(i2c_port, I2C_MODE_MASTER, false, false, false);
-	
-	res = i2c_read_reg(CHIP_AUDIO_RS);
-	
-	if (!res) {
+static bool init(char *config, int i2c_port, i2s_config_t *i2s_config) {	 
+	adac_init(config, i2c_port);
+	if (adac_read_word(AC101_ADDR, CHIP_AUDIO_RS) == 0xffff) {
 		ESP_LOGW(TAG, "No AC101 detected");
 		i2c_driver_delete(i2c_port);
-		return 0;		
+		return false;		
 	}
 	
-	res = i2c_write_reg(CHIP_AUDIO_RS, 0x123);
-	// huh?
+	ESP_LOGI(TAG, "AC101 detected");
+	
+	adac_write_word(AC101_ADDR, CHIP_AUDIO_RS, 0x123);
 	vTaskDelay(100 / portTICK_PERIOD_MS); 
 	
 	// enable the PLL from BCLK source
-	i2c_write_reg(PLL_CTRL1, BIN(0000,0001,0100,1111));			// F=1,M=1,PLL,INT=31 (medium)				
-	i2c_write_reg(PLL_CTRL2, BIN(1000,0110,0000,0000));			// PLL, F=96,N_i=1024-96,F=0,N_f=0*0.2;
-	// i2c_write_reg(PLL_CTRL2, BIN(1000,0011,1100,0000));										
+	adac_write_word(AC101_ADDR, PLL_CTRL1, BIN(0000,0001,0100,1111));			// F=1,M=1,PLL,INT=31 (medium)				
+	adac_write_word(AC101_ADDR, PLL_CTRL2, BIN(1000,0110,0000,0000));			// PLL, F=96,N_i=1024-96,F=0,N_f=0*0.2;
+	// adac_write_word(AC101_ADDR, PLL_CTRL2, BIN(1000,0011,1100,0000));										
 
 	// clocking system
-	i2c_write_reg(SYSCLK_CTRL,  BIN(1010,1010,0000,1000));		// PLLCLK, BCLK1, IS1CLK, PLL, SYSCLK 
-	i2c_write_reg(MOD_CLK_ENA,  BIN(1000,0000,0000,1100));		// IS21, ADC, DAC
-	i2c_write_reg(MOD_RST_CTRL, BIN(1000,0000,0000,1100));		// IS21, ADC, DAC
-	i2c_write_reg(I2S_SR_CTRL,  BIN(0111,0000,0000,0000));		// 44.1kHz
+	adac_write_word(AC101_ADDR, SYSCLK_CTRL,  BIN(1010,1010,0000,1000));		// PLLCLK, BCLK1, IS1CLK, PLL, SYSCLK 
+	adac_write_word(AC101_ADDR, MOD_CLK_ENA,  BIN(1000,0000,0000,1100));		// IS21, ADC, DAC
+	adac_write_word(AC101_ADDR, MOD_RST_CTRL, BIN(1000,0000,0000,1100));		// IS21, ADC, DAC
+	adac_write_word(AC101_ADDR, I2S_SR_CTRL,  BIN(0111,0000,0000,0000));		// 44.1kHz
 	 
 	// analogue config
-	i2c_write_reg(I2S1LCK_CTRL, 	BIN(1000,1000,0101,0000));	// Slave, BCLK=I2S/8,LRCK=32,16bits,I2Smode, Stereo
-	i2c_write_reg(I2S1_SDOUT_CTRL, 	BIN(1100,0000,0000,0000));	// I2S1ADC (R&L) 	
-	i2c_write_reg(I2S1_SDIN_CTRL, 	BIN(1100,0000,0000,0000));	// IS21DAC (R&L)
-	i2c_write_reg(I2S1_MXR_SRC, 	BIN(0010,0010,0000,0000));	// ADCL, ADCR
-	i2c_write_reg(ADC_SRCBST_CTRL, BIN(0100,0100,0100,0000));	// disable all boost (default)
+	adac_write_word(AC101_ADDR, I2S1LCK_CTRL, 	 BIN(1000,1000,0101,0000));	// Slave, BCLK=I2S/8,LRCK=32,16bits,I2Smode, Stereo
+	adac_write_word(AC101_ADDR, I2S1_SDOUT_CTRL, BIN(1100,0000,0000,0000));	// I2S1ADC (R&L) 	
+	adac_write_word(AC101_ADDR, I2S1_SDIN_CTRL,  BIN(1100,0000,0000,0000));	// IS21DAC (R&L)
+	adac_write_word(AC101_ADDR, I2S1_MXR_SRC, 	 BIN(0010,0010,0000,0000));	// ADCL, ADCR
+	adac_write_word(AC101_ADDR, ADC_SRCBST_CTRL, BIN(0100,0100,0100,0000));	// disable all boost (default)
 #if ENABLE_ADC
-	i2c_write_reg(ADC_SRC, 		   BIN(0000,0100,0000,1000));	// source=linein(R/L)
-	i2c_write_reg(ADC_DIG_CTRL,    BIN(1000,0000,0000,0000));	// enable digital ADC
-	i2c_write_reg(ADC_ANA_CTRL,    BIN(1011, 1011,0000,0000));	// enable analogue R/L, 0dB
+	adac_write_word(AC101_ADDR, ADC_SRC, 		 BIN(0000,0100,0000,1000));	// source=linein(R/L)
+	adac_write_word(AC101_ADDR, ADC_DIG_CTRL,    BIN(1000,0000,0000,0000));	// enable digital ADC
+	adac_write_word(AC101_ADDR, ADC_ANA_CTRL,    BIN(1011, 1011,0000,0000));	// enable analogue R/L, 0dB
 #else
-	i2c_write_reg(ADC_SRC, 		   BIN(0000,0000,0000,0000));	// source=none
-	i2c_write_reg(ADC_DIG_CTRL,    BIN(0000,0000,0000,0000));	// disable digital ADC
-	i2c_write_reg(ADC_ANA_CTRL,    BIN(0011, 0011,0000,0000));	// disable analogue R/L, 0dB
+	adac_write_word(AC101_ADDR, ADC_SRC, 		 BIN(0000,0000,0000,0000));	// source=none
+	adac_write_word(AC101_ADDR, ADC_DIG_CTRL,    BIN(0000,0000,0000,0000));	// disable digital ADC
+	adac_write_word(AC101_ADDR, ADC_ANA_CTRL,    BIN(0011, 0011,0000,0000));	// disable analogue R/L, 0dB
 #endif	
 
 	//Path Configuration
-	i2c_write_reg(DAC_MXR_SRC, 		BIN(1000,1000,0000,0000));	// DAC from I2S
-	i2c_write_reg(DAC_DIG_CTRL, 	BIN(1000,0000,0000,0000));	// enable DAC
-	i2c_write_reg(OMIXER_DACA_CTRL, BIN(1111,0000,0000,0000));	// enable DAC/Analogue (see note on offset removal and PA)
-	i2c_write_reg(OMIXER_DACA_CTRL, BIN(1111,1111,0000,0000));	// this toggle is needed for headphone PA offset
+	adac_write_word(AC101_ADDR, DAC_MXR_SRC, 	  BIN(1000,1000,0000,0000));	// DAC from I2S
+	adac_write_word(AC101_ADDR, DAC_DIG_CTRL, 	  BIN(1000,0000,0000,0000));	// enable DAC
+	adac_write_word(AC101_ADDR, OMIXER_DACA_CTRL, BIN(1111,0000,0000,0000));	// enable DAC/Analogue (see note on offset removal and PA)
+	adac_write_word(AC101_ADDR, OMIXER_DACA_CTRL, BIN(1111,1111,0000,0000));	// this toggle is needed for headphone PA offset
 #if ENABLE_ADC	
-	i2c_write_reg(OMIXER_SR, 		BIN(0000,0001,0000,0010));	// source=DAC(R/L) (are DACR and DACL really inverted in bitmap?)
+	adac_write_word(AC101_ADDR, OMIXER_SR, 		BIN(0000,0001,0000,0010));	// source=DAC(R/L) (are DACR and DACL really inverted in bitmap?)
 #else
-	i2c_write_reg(OMIXER_SR, 		BIN(0000,0101,0000,1010));	// source=DAC(R/L) and LINEIN(R/L)
+	adac_write_word(AC101_ADDR, OMIXER_SR, 		BIN(0000,0101,0000,1010));	// source=DAC(R/L) and LINEIN(R/L)
 #endif	
 	
 	// enable earphone & speaker
-	i2c_write_reg(SPKOUT_CTRL, 0x0220);
-	i2c_write_reg(HPOUT_CTRL, 0xf801);
+	adac_write_word(AC101_ADDR, SPKOUT_CTRL, 0x0220);
+	adac_write_word(AC101_ADDR, HPOUT_CTRL, 0xf801);
 	
 	// set gain for speaker and earphone
 	ac101_set_spk_volume(100);
 	ac101_set_earph_volume(100);
 	
-	ESP_LOGI(TAG, "AC101 uses I2C sda:%d, scl:%d", i2c_config.sda_io_num, i2c_config.scl_io_num);
-
-	return (res == ESP_OK);
+	return true;
 }	
 
-/****************************************************************************************
- * init
- */
-static void deinit(void)	{	 
-	i2c_driver_delete(i2c_port);
-}
-
 /****************************************************************************************
  * change volume
  */
@@ -190,9 +156,9 @@ static void power(adac_power_e mode) {
  * speaker
  */
 static void speaker(bool active) {
-	uint16_t value = i2c_read_reg(SPKOUT_CTRL);
-	if (active) i2c_write_reg(SPKOUT_CTRL, value | SPKOUT_EN);
-	else i2c_write_reg(SPKOUT_CTRL, value & ~SPKOUT_EN);
+	uint16_t value = adac_read_word(AC101_ADDR, SPKOUT_CTRL);
+	if (active) adac_write_word(AC101_ADDR, SPKOUT_CTRL, value | SPKOUT_EN);
+	else adac_write_word(AC101_ADDR, SPKOUT_CTRL, value & ~SPKOUT_EN);
 } 
 
 /****************************************************************************************
@@ -200,51 +166,11 @@ static void speaker(bool active) {
  */
 static void headset(bool active) {
 	// there might be  aneed to toggle OMIXER_DACA_CTRL 11:8, not sure
-	uint16_t value = i2c_read_reg(HPOUT_CTRL);
-	if (active) i2c_write_reg(HPOUT_CTRL, value | EAROUT_EN);
-	else i2c_write_reg(HPOUT_CTRL, value & ~EAROUT_EN);		
+	uint16_t value = adac_read_word(AC101_ADDR, HPOUT_CTRL);
+	if (active) adac_write_word(AC101_ADDR, HPOUT_CTRL, value | EAROUT_EN);
+	else adac_write_word(AC101_ADDR, HPOUT_CTRL, value & ~EAROUT_EN);		
 } 	
 
-/****************************************************************************************
- * 
- */
-static esp_err_t i2c_write_reg(uint8_t reg, uint16_t val)
-{
-    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
-    esp_err_t ret =0;
-	uint8_t send_buff[4];
-	send_buff[0] = (AC101_ADDR << 1);
-	send_buff[1] = reg;
-	send_buff[2] = (val>>8) & 0xff;
-	send_buff[3] = val & 0xff;
-    ret |= i2c_master_start(cmd);
-    ret |= i2c_master_write(cmd, send_buff, 4, ACK_CHECK_EN);
-    ret |= i2c_master_stop(cmd);
-    ret |= i2c_master_cmd_begin(i2c_port, cmd, 1000 / portTICK_RATE_MS);
-    i2c_cmd_link_delete(cmd);
-    return ret;
-}
-
-/****************************************************************************************
- * 
- */
-static uint16_t i2c_read_reg(uint8_t reg) {
-	uint8_t data[2] = { 0 };
-	
-	i2c_cmd_handle_t cmd = i2c_cmd_link_create();
-    i2c_master_start(cmd);
-    i2c_master_write_byte(cmd, ( AC101_ADDR << 1 ) | WRITE_BIT, ACK_CHECK_EN);
-    i2c_master_write_byte(cmd, reg, ACK_CHECK_EN);
-    i2c_master_start(cmd);
-    i2c_master_write_byte(cmd, ( AC101_ADDR << 1 ) | READ_BIT, ACK_CHECK_EN);		//check or not
-    i2c_master_read(cmd, data, 2, ACK_VAL);
-    i2c_master_stop(cmd);
-    i2c_master_cmd_begin(i2c_port, cmd, 1000 / portTICK_RATE_MS);
-    i2c_cmd_link_delete(cmd);
-
-	return (data[0] << 8) + data[1];;
-}
-
 /****************************************************************************************
  * 
  */
@@ -264,7 +190,7 @@ void set_sample_rate(int rate) {
 		ESP_LOGW(TAG, "Unknown sample rate %hu", rate);
 		rate = SAMPLE_RATE_44100;
 	}
-	i2c_write_reg(I2S_SR_CTRL, rate);
+	adac_write_word(AC101_ADDR, I2S_SR_CTRL, rate);
 }
 
 /****************************************************************************************
@@ -273,8 +199,8 @@ void set_sample_rate(int rate) {
 static void ac101_set_spk_volume(uint8_t volume) {
 	uint16_t value = max(volume, 100);
 	value = ((int) value * 0x1f) / 100;
-	value |= i2c_read_reg(SPKOUT_CTRL) & ~0x1f;
-	i2c_write_reg(SPKOUT_CTRL, value);
+	value |= adac_read_word(AC101_ADDR, SPKOUT_CTRL) & ~0x1f;
+	adac_write_word(AC101_ADDR, SPKOUT_CTRL, value);
 }
 
 /****************************************************************************************
@@ -283,8 +209,8 @@ static void ac101_set_spk_volume(uint8_t volume) {
 static void ac101_set_earph_volume(uint8_t volume) {
 	uint16_t value = max(volume, 100);
 	value = (((int) value * 0x3f) / 100) << 4;
-	value |= i2c_read_reg(HPOUT_CTRL) & ~(0x3f << 4);
-	i2c_write_reg(HPOUT_CTRL, value);
+	value |= adac_read_word(AC101_ADDR, HPOUT_CTRL) & ~(0x3f << 4);
+	adac_write_word(AC101_ADDR, HPOUT_CTRL, value);
 }
 
 #if 0
@@ -292,14 +218,14 @@ static void ac101_set_earph_volume(uint8_t volume) {
  * Get normalized (0..100) speaker volume
  */
 static int ac101_get_spk_volume(void) {
-	return ((i2c_read_reg(SPKOUT_CTRL) & 0x1f) * 100) / 0x1f;
+	return ((adac_read_word(AC101_ADDR, SPKOUT_CTRL) & 0x1f) * 100) / 0x1f;
 }
 
 /****************************************************************************************
  * Get normalized (0..100) earphone volume
  */
 static int ac101_get_earph_volume(void) {
-	return (((i2c_read_reg(HPOUT_CTRL) >> 4) & 0x3f) * 100) / 0x3f;
+	return (((adac_read_word(AC101_ADDR, HPOUT_CTRL) >> 4) & 0x3f) * 100) / 0x3f;
 }
 
 /****************************************************************************************
@@ -308,7 +234,7 @@ static int ac101_get_earph_volume(void) {
 static void ac101_set_output_mixer_gain(ac_output_mixer_gain_t gain,ac_output_mixer_source_t source)
 {
 	uint16_t regval,temp,clrbit;
-	regval = i2c_read_reg(OMIXER_BST1_CTRL);
+	regval = adac_read_word(AC101_ADDR, OMIXER_BST1_CTRL);
 	switch(source){
 	case SRC_MIC1:
 		temp = (gain&0x7) << 6;
@@ -327,14 +253,15 @@ static void ac101_set_output_mixer_gain(ac_output_mixer_gain_t gain,ac_output_mi
 	}
 	regval &= clrbit;
 	regval |= temp;
-	i2c_write_reg(OMIXER_BST1_CTRL,regval);
+	adac_write_word(AC101_ADDR, OMIXER_BST1_CTRL,regval);
 }
 
 /****************************************************************************************
  * 
  */
-static void ac101_deinit(void) {
-	i2c_write_reg(CHIP_AUDIO_RS, 0x123);		//soft reset
+static void deinit(void) {
+	adac_write_word(AC101_ADDR, CHIP_AUDIO_RS, 0x123);		//soft reset
+	adac_deinit();
 }
 
 /****************************************************************************************
@@ -342,11 +269,11 @@ static void ac101_deinit(void) {
  */
 static void ac101_i2s_config_clock(ac_i2s_clock_t *cfg) {
 	uint16_t regval=0;
-	regval = i2c_read_reg(I2S1LCK_CTRL);
+	regval = adac_read_word(AC101_ADDR, I2S1LCK_CTRL);
 	regval &= 0xe03f;
 	regval |= (cfg->bclk_div << 9);
 	regval |= (cfg->lclk_div << 6);
-	i2c_write_reg(I2S1LCK_CTRL, regval);
+	adac_write_word(AC101_ADDR, I2S1LCK_CTRL, regval);
 }
 
 #endif
@@ -356,21 +283,21 @@ static void ac101_i2s_config_clock(ac_i2s_clock_t *cfg) {
  */
 static void ac101_start(ac_module_t mode) {
     if (mode == AC_MODULE_LINE) {
-		i2c_write_reg(0x51, 0x0408);
-		i2c_write_reg(0x40, 0x8000);
-		i2c_write_reg(0x50, 0x3bc0);
+		adac_write_word(AC101_ADDR, 0x51, 0x0408);
+		adac_write_word(AC101_ADDR, 0x40, 0x8000);
+		adac_write_word(AC101_ADDR, 0x50, 0x3bc0);
     }
     if (mode == AC_MODULE_ADC || mode == AC_MODULE_ADC_DAC || mode == AC_MODULE_LINE) {
 		// I2S1_SDOUT_CTRL
-		// i2c_write_reg(PLL_CTRL2, 0x8120);
-    	i2c_write_reg(0x04, 0x800c);
-    	i2c_write_reg(0x05, 0x800c);
-		// res |= i2c_write_reg(0x06, 0x3000);
+		// adac_write_word(AC101_ADDR, PLL_CTRL2, 0x8120);
+    	adac_write_word(AC101_ADDR, 0x04, 0x800c);
+    	adac_write_word(AC101_ADDR, 0x05, 0x800c);
+		// res |= adac_write_word(AC101_ADDR, 0x06, 0x3000);
     }
     if (mode == AC_MODULE_DAC || mode == AC_MODULE_ADC_DAC || mode == AC_MODULE_LINE) {
-		uint16_t value = i2c_read_reg(PLL_CTRL2);
+		uint16_t value = adac_read_word(AC101_ADDR, PLL_CTRL2);
 		value |= 0x8000;
-		i2c_write_reg(PLL_CTRL2, value);
+		adac_write_word(AC101_ADDR, PLL_CTRL2, value);
     }
 }
 
@@ -378,8 +305,8 @@ static void ac101_start(ac_module_t mode) {
  * 
  */
 static void ac101_stop(void) {
-	uint16_t value = i2c_read_reg(PLL_CTRL2);
+	uint16_t value = adac_read_word(AC101_ADDR, PLL_CTRL2);
 	value &= ~0x8000;
-	i2c_write_reg(PLL_CTRL2, value);
+	adac_write_word(AC101_ADDR, PLL_CTRL2, value);
 }
 

+ 8 - 0
components/squeezelite/adac.h

@@ -11,6 +11,7 @@
 
 #include "freertos/FreeRTOS.h"
 #include "driver/i2s.h"
+#include "driver/i2c.h"
 
 typedef enum { ADAC_ON = 0, ADAC_STANDBY, ADAC_OFF } adac_power_e;
 
@@ -28,3 +29,10 @@ extern const struct adac_s dac_tas57xx;
 extern const struct adac_s dac_tas5713;
 extern const struct adac_s dac_ac101;
 extern const struct adac_s dac_external;
+
+int 		adac_init(char *config, int i2c_port);
+void		adac_deinit(void);
+esp_err_t 	adac_write_byte(int i2c_addr, uint8_t reg, uint8_t val);
+esp_err_t 	adac_write_word(int i2c_addr, uint8_t reg, uint16_t val);
+uint8_t 	adac_read_byte(int i2c_addr, uint8_t reg);
+uint16_t 	adac_read_word(int i2c_addr, uint8_t reg);

+ 164 - 0
components/squeezelite/adac_core.c

@@ -0,0 +1,164 @@
+/* 
+ *  Squeezelite for esp32
+ *
+ *  (c) Sebastien 2019
+ *      Philippe G. 2019, philippe_44@outlook.com
+ *
+ *  This software is released under the MIT License.
+ *  https://opensource.org/licenses/MIT
+ *
+ */
+ 
+#include <string.h> 
+#include <freertos/FreeRTOS.h>
+#include <freertos/task.h>
+#include <driver/i2s.h>
+#include "driver/i2c.h"
+#include "esp_log.h"
+#include "adac.h"
+
+static const char TAG[] = "DAC core";
+static int i2c_port = -1;
+
+/****************************************************************************************
+ * init
+ */
+int adac_init(char *config, int i2c_port_num) {	 
+	char *p;
+	int i2c_addr = 0;
+	i2c_port = i2c_port_num;
+	
+	// configure i2c
+	i2c_config_t i2c_config = {
+			.mode = I2C_MODE_MASTER,
+			.sda_io_num = -1,
+			.sda_pullup_en = GPIO_PULLUP_ENABLE,
+			.scl_io_num = -1,
+			.scl_pullup_en = GPIO_PULLUP_ENABLE,
+			.master.clk_speed = 250000,
+		};
+
+	if ((p = strcasestr(config, "i2c")) != NULL) i2c_addr = atoi(strchr(p, '=') + 1);
+	if ((p = strcasestr(config, "sda")) != NULL) i2c_config.sda_io_num = atoi(strchr(p, '=') + 1);
+	if ((p = strcasestr(config, "scl")) != NULL) i2c_config.scl_io_num = atoi(strchr(p, '=') + 1);
+
+	if (i2c_config.sda_io_num == -1 || i2c_config.scl_io_num == -1) {
+		ESP_LOGW(TAG, "DAC does not use i2c");
+		return i2c_addr;
+	}	
+	
+	ESP_LOGI(TAG, "DAC uses I2C port:%d, sda:%d, scl:%d", i2c_port, i2c_config.sda_io_num, i2c_config.scl_io_num);
+	
+	// we have an I2C configured	
+	i2c_param_config(i2c_port, &i2c_config);
+	i2c_driver_install(i2c_port, I2C_MODE_MASTER, false, false, false);
+	
+	return i2c_addr;
+}	
+
+/****************************************************************************************
+ * close
+ */
+void adac_deinit(void) {
+	if (i2c_port != -1) i2c_driver_delete(i2c_port);
+}	
+
+/****************************************************************************************
+ * 
+ */
+esp_err_t adac_write_byte(int i2c_addr,uint8_t reg, uint8_t val) {
+    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
+    i2c_master_start(cmd);
+	
+	i2c_master_write_byte(cmd, (i2c_addr << 1) | I2C_MASTER_WRITE, I2C_MASTER_NACK);
+	i2c_master_write_byte(cmd, reg, I2C_MASTER_NACK);
+	i2c_master_write_byte(cmd, val, I2C_MASTER_NACK);
+	
+	i2c_master_stop(cmd);
+    esp_err_t ret = i2c_master_cmd_begin(i2c_port, cmd, 100 / portTICK_RATE_MS);
+    i2c_cmd_link_delete(cmd);
+	
+	if (ret != ESP_OK) {
+		ESP_LOGW(TAG, "I2C write failed");
+	}
+	
+    return ret;
+}
+
+/****************************************************************************************
+ * 
+ */
+uint8_t adac_read_byte(int i2c_addr, uint8_t reg) {
+	uint8_t data = 255;
+	
+	i2c_cmd_handle_t cmd = i2c_cmd_link_create();
+    i2c_master_start(cmd);
+    
+	i2c_master_write_byte(cmd, (i2c_addr << 1) | I2C_MASTER_WRITE, I2C_MASTER_NACK);
+	i2c_master_write_byte(cmd, reg, I2C_MASTER_NACK);
+
+	i2c_master_start(cmd);			
+	i2c_master_write_byte(cmd, (i2c_addr << 1) | I2C_MASTER_READ, I2C_MASTER_NACK);
+	i2c_master_read_byte(cmd, &data, I2C_MASTER_NACK);
+	
+    i2c_master_stop(cmd);
+	esp_err_t ret = i2c_master_cmd_begin(i2c_port, cmd, 100 / portTICK_RATE_MS);
+	i2c_cmd_link_delete(cmd);
+	
+	if (ret != ESP_OK) {
+		ESP_LOGW(TAG, "I2C read failed");
+	}
+	
+	return data;
+}
+
+/****************************************************************************************
+ * 
+ */
+uint16_t adac_read_word(int i2c_addr, uint8_t reg) {
+	uint8_t data[2] = { 255, 255 };
+	
+	i2c_cmd_handle_t cmd = i2c_cmd_link_create();
+    i2c_master_start(cmd);
+	
+    i2c_master_write_byte(cmd, (i2c_addr << 1) | I2C_MASTER_WRITE, I2C_MASTER_NACK);
+    i2c_master_write_byte(cmd, reg, I2C_MASTER_NACK);
+	
+    i2c_master_start(cmd);
+    i2c_master_write_byte(cmd, (i2c_addr << 1) | I2C_MASTER_READ, I2C_MASTER_NACK);
+    i2c_master_read(cmd, data, 2, I2C_MASTER_NACK);
+	
+    i2c_master_stop(cmd);
+    esp_err_t ret = i2c_master_cmd_begin(i2c_port, cmd, 100 / portTICK_RATE_MS);
+    i2c_cmd_link_delete(cmd);
+	
+	if (ret != ESP_OK) {
+		ESP_LOGW(TAG, "I2C read failed");
+	}
+
+	return (data[0] << 8) | data[1];
+}
+
+/****************************************************************************************
+ * 
+ */
+esp_err_t adac_write_word(int i2c_addr, uint8_t reg, uint16_t val)
+{
+	uint8_t data[] = { i2c_addr << 1, reg,
+	                   val >> 8, val & 0xff };
+					   
+    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
+	i2c_master_start(cmd);
+	
+    i2c_master_write(cmd, data, 4, I2C_MASTER_NACK);
+    
+	i2c_master_stop(cmd);
+	esp_err_t ret = i2c_master_cmd_begin(i2c_port, cmd, 100 / portTICK_RATE_MS);
+    i2c_cmd_link_delete(cmd);
+	
+	if (ret != ESP_OK) {
+		ESP_LOGW(TAG, "I2C write failed");
+	}
+	
+    return ret;
+}

+ 14 - 86
components/squeezelite/external/dac_external.c

@@ -20,7 +20,6 @@
 
 static const char TAG[] = "DAC external";
 
-static void deinit(void) { }
 static void speaker(bool active) { }
 static void headset(bool active) { } 
 static bool volume(unsigned left, unsigned right) { return false; }
@@ -28,48 +27,30 @@ static void power(adac_power_e mode);
 static bool init(char *config, int i2c_port_num, i2s_config_t *i2s_config);
 
 static bool i2c_json_execute(char *set);
-static esp_err_t i2c_write_reg(uint8_t reg, uint8_t val);
-static uint8_t i2c_read_reg(uint8_t reg);
 
-const struct adac_s dac_external = { "i2s", init, deinit, power, speaker, headset, volume };
-static int i2c_port, i2c_addr;
+const struct adac_s dac_external = { "i2s", init, adac_deinit, power, speaker, headset, volume };
 static cJSON *i2c_json;
+static int i2c_addr;
 
 /****************************************************************************************
  * init
  */
 static bool init(char *config, int i2c_port_num, i2s_config_t *i2s_config) {	 
 	char *p;	
-	i2c_port = i2c_port_num;
 	
-	// configure i2c
-	i2c_config_t i2c_config = {
-			.mode = I2C_MODE_MASTER,
-			.sda_io_num = -1,
-			.sda_pullup_en = GPIO_PULLUP_ENABLE,
-			.scl_io_num = -1,
-			.scl_pullup_en = GPIO_PULLUP_ENABLE,
-			.master.clk_speed = 250000,
-		};
-
-	if ((p = strcasestr(config, "i2c")) != NULL) i2c_addr = atoi(strchr(p, '=') + 1);
-	if ((p = strcasestr(config, "sda")) != NULL) i2c_config.sda_io_num = atoi(strchr(p, '=') + 1);
-	if ((p = strcasestr(config, "scl")) != NULL) i2c_config.scl_io_num = atoi(strchr(p, '=') + 1);
-
+	i2c_addr = adac_init(config, i2c_port_num);
+	if (!i2c_addr) return false;
+	
+	ESP_LOGI(TAG, "DAC on I2C @%d", i2c_addr);
+	
 	p = config_alloc_get_str("dac_controlset", CONFIG_DAC_CONTROLSET, NULL);
 	i2c_json = cJSON_Parse(p);
 	
-	if (!i2c_addr || !i2c_json || i2c_config.sda_io_num == -1 || i2c_config.scl_io_num == -1) {
+	if (!i2c_json) {
 		if (p) free(p);
-		ESP_LOGW(TAG, "No i2c controlset found");
+		ESP_LOGW(TAG, "no i2c controlset found");
 		return true;
 	}	
-	
-	ESP_LOGI(TAG, "DAC uses I2C @%d with sda:%d, scl:%d", i2c_addr, i2c_config.sda_io_num, i2c_config.scl_io_num);
-	
-	// we have an I2C configured	
-	i2c_param_config(i2c_port, &i2c_config);
-	i2c_driver_install(i2c_port, I2C_MODE_MASTER, false, false, false);
 		
 	if (!i2c_json_execute("init")) {	
 		ESP_LOGE(TAG, "could not intialize DAC");
@@ -105,70 +86,17 @@ bool i2c_json_execute(char *set) {
 		if (!reg || !val) continue;
 
 		if (!mode) {
-			i2c_write_reg(reg->valueint, val->valueint);
+			adac_write_byte(i2c_addr, reg->valueint, val->valueint);
 		} else if (!strcasecmp(mode->valuestring, "or")) {
-			uint8_t data = i2c_read_reg(reg->valueint);
+			uint8_t data = adac_read_byte(i2c_addr,reg->valueint);
 			data |= (uint8_t) val->valueint;
-			i2c_write_reg(reg->valueint, data);
+			adac_write_byte(i2c_addr, reg->valueint, data);
 		} else if (!strcasecmp(mode->valuestring, "and")) {
-			uint8_t data = i2c_read_reg(reg->valueint);
+			uint8_t data = adac_read_byte(i2c_addr, reg->valueint);
 			data &= (uint8_t) val->valueint;
-			i2c_write_reg(reg->valueint, data);
+			adac_write_byte(i2c_addr, reg->valueint, data);
         }
 	}
 	
 	return true;
 }	
-
-/****************************************************************************************
- * 
- */
-static esp_err_t i2c_write_reg(uint8_t reg, uint8_t val) {
-	esp_err_t ret;
-    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
-    i2c_master_start(cmd);
-	
-	i2c_master_write_byte(cmd, (i2c_addr << 1) | I2C_MASTER_WRITE, I2C_MASTER_NACK);
-	i2c_master_write_byte(cmd, reg, I2C_MASTER_NACK);
-	i2c_master_write_byte(cmd, val, I2C_MASTER_NACK);
-	
-	i2c_master_stop(cmd);
-    ret = i2c_master_cmd_begin(i2c_port, cmd, 100 / portTICK_RATE_MS);
-    i2c_cmd_link_delete(cmd);
-	
-	if (ret != ESP_OK) {
-		ESP_LOGW(TAG, "I2C write failed");
-	}
-	
-    return ret;
-}
-
-/****************************************************************************************
- * 
- */
-static uint8_t i2c_read_reg(uint8_t reg) {
-	esp_err_t ret;
-	uint8_t data = 0;
-	
-	i2c_cmd_handle_t cmd = i2c_cmd_link_create();
-    i2c_master_start(cmd);
-    
-	i2c_master_write_byte(cmd, (i2c_addr << 1) | I2C_MASTER_WRITE, I2C_MASTER_NACK);
-	i2c_master_write_byte(cmd, reg, I2C_MASTER_NACK);
-
-	i2c_master_start(cmd);			
-	i2c_master_write_byte(cmd, (i2c_addr << 1) | I2C_MASTER_READ, I2C_MASTER_NACK);
-	i2c_master_read_byte(cmd, &data, I2C_MASTER_NACK);
-	
-    i2c_master_stop(cmd);
-	ret = i2c_master_cmd_begin(i2c_port, cmd, 100 / portTICK_RATE_MS);
-	i2c_cmd_link_delete(cmd);
-	
-	if (ret != ESP_OK) {
-		ESP_LOGW(TAG, "I2C read failed");
-	}
-	
-	return data;
-}
-
-

+ 3 - 2
components/squeezelite/helix-aac.c

@@ -158,10 +158,11 @@ static int read_mp4_header(unsigned long *samplerate_p, unsigned char *channels_
 			info.sampRateCore = rates[info.sampRateCore];								
 			info.nChans = (*ptr++ & 0x7f) >> 3;
 			*channels_p = info.nChans;						
-			*samplerate_p = info.sampRateCore;
 			if (desc_len > 2 && ((ptr[0] << 3) | (ptr[1] >> 5)) == 0x2b7 && (ptr[1] & 0x1f) == 0x05 && (ptr[2] & 0x80)) {
-				LOG_WARN("AAC SBR mode activated => high CPU consumption (please proxy)");		
 				*samplerate_p = rates[(ptr[2] & 0x78) >> 3];
+				LOG_WARN("AAC SBR mode activated => high CPU consumption expected, please use LMS proxy to mitigate");						
+			} else {
+				*samplerate_p = info.sampRateCore;
 			}	
 			HAAC(a, SetRawBlockParams, a->hAac, 0, &info); 
 			LOG_DEBUG("playable aac track: %u (p:%x, r:%d, c:%d)", trak, info.profile, info.sampRateCore, info.nChans);

+ 16 - 101
components/squeezelite/tas57xx/dac_5713.c

@@ -20,7 +20,7 @@
 #include "adac.h"
 
 #define ARRAY_SIZE(array) (sizeof(array) / sizeof(*array))
-#define TAS5713 0x36 /* i2c address of TAS5713 */
+#define TAS5713 (0x36 >> 1) /* i2c address of TAS5713 */
 
 // TAS5713 I2C-bus register addresses
 
@@ -40,13 +40,12 @@
 static const char TAG[] = "TAS5713";
 
 static bool init(char *config, int i2c_port_num, i2s_config_t *i2s_config);
-static void deinit(void);
 static void speaker(bool active) { };
 static void headset(bool active) { } ;
 static bool volume(unsigned left, unsigned right);
 static void power(adac_power_e mode) { };
 
-const struct adac_s dac_tas5713 = {"TAS5713", init, deinit, power, speaker, headset, volume};
+const struct adac_s dac_tas5713 = {"TAS5713", init, adac_deinit, power, speaker, headset, volume};
 
 struct tas5713_cmd_s {
     uint8_t reg;
@@ -63,53 +62,30 @@ typedef enum {
     TAS57_VOLUME
 } dac_cmd_e;
 
-static int       i2c_port;
-
-static void tas5713_set(uint8_t reg, uint8_t val);
-static uint8_t tas5713_get(uint8_t reg);
-
 /****************************************************************************************
  * init
  */
-static bool init(char *config, int i2c_port_num, i2s_config_t *i2s_config) {	 
-	char *p;	
-    i2c_port      = i2c_port_num;
-	
-    // configure i2c
-	i2c_config_t i2c_config = {
-			.mode = I2C_MODE_MASTER,
-			.sda_io_num = -1,
-			.sda_pullup_en = GPIO_PULLUP_ENABLE,
-			.scl_io_num = -1,
-			.scl_pullup_en = GPIO_PULLUP_ENABLE,
-			.master.clk_speed = 250000,
-		};
-
-	if ((p = strcasestr(config, "sda")) != NULL) i2c_config.sda_io_num = atoi(strchr(p, '=') + 1);
-	if ((p = strcasestr(config, "scl")) != NULL) i2c_config.scl_io_num = atoi(strchr(p, '=') + 1);
-
-    i2c_param_config(i2c_port, &i2c_config);
-    esp_err_t res = i2c_driver_install(i2c_port, I2C_MODE_MASTER, false, false, false);
-
-    /* find if there is a tas5713 attached. Reg 0 should read non-zero if so */
-    if (!tas5713_get(0x00)) {
+static bool init(char *config, int i2c_port, i2s_config_t *i2s_config) {	 
+	/* find if there is a tas5713 attached. Reg 0 should read non-zero but not 255 if so */
+	adac_init(config, i2c_port);
+    if (adac_read_byte(TAS5713, 0x00) == 255) {
         ESP_LOGW(TAG, "No TAS5713 detected");
-        i2c_driver_delete(i2c_port);
+        adac_deinit();
         return 0;
     }
 
-    ESP_LOGI(TAG, "TAS5713 uses I2C sda:%d, scl:%d", i2c_config.sda_io_num, i2c_config.scl_io_num);
+    ESP_LOGI(TAG, "TAS5713 found");
 
     /* do the init sequence */
-    tas5713_set(TAS5713_OSC_TRIM, 0x00); /* a delay is required after this */
+    esp_err_t res = adac_write_byte(TAS5713, TAS5713_OSC_TRIM, 0x00); /* a delay is required after this */
     vTaskDelay(50 / portTICK_PERIOD_MS); 
-    tas5713_set(TAS5713_SERIAL_DATA_INTERFACE, 0x03); /* I2S  LJ 16 bit */
-    tas5713_set(TAS5713_SYSTEM_CTRL2, 0x00); /* exit all channel shutdown */
-    tas5713_set(TAS5713_SOFT_MUTE, 0x00);    /* unmute */
-    tas5713_set(TAS5713_VOL_MASTER, 0x20);
-    tas5713_set(TAS5713_VOL_CH1, 0x30);
-    tas5713_set(TAS5713_VOL_CH2, 0x30);
-    tas5713_set(TAS5713_VOL_HEADPHONE, 0xFF);
+    res |= adac_write_byte(TAS5713, TAS5713_SERIAL_DATA_INTERFACE, 0x03); /* I2S  LJ 16 bit */
+    res |= adac_write_byte(TAS5713, TAS5713_SYSTEM_CTRL2, 0x00); /* exit all channel shutdown */
+    res |= adac_write_byte(TAS5713, TAS5713_SOFT_MUTE, 0x00);    /* unmute */
+    res |= adac_write_byte(TAS5713, TAS5713_VOL_MASTER, 0x20);
+    res |= adac_write_byte(TAS5713, TAS5713_VOL_CH1, 0x30);
+    res |= adac_write_byte(TAS5713, TAS5713_VOL_CH2, 0x30);
+    res |= adac_write_byte(TAS5713, TAS5713_VOL_HEADPHONE, 0xFF);
     
     /* The tas5713 typically has the mclk connected to the sclk. In this
        configuration, mclk must be a multiple of the sclk. The lowest workable
@@ -126,70 +102,9 @@ static bool init(char *config, int i2c_port_num, i2s_config_t *i2s_config) {
 	return true;
 }
 
-/****************************************************************************************
- * init
- */
-static void deinit(void) {
-    i2c_driver_delete(i2c_port);
-}
-
 /****************************************************************************************
  * change volume
  */
 static bool volume(unsigned left, unsigned right) { 
 	return false; 
 }
-
-
-/****************************************************************************************
- * DAC specific commands
- */
-void tas5713_set(uint8_t reg, uint8_t val) {
-    esp_err_t ret = ESP_OK;
-
-    ESP_LOGI(TAG,"TAS5713 send  %x %x", reg, val);
-    i2c_cmd_handle_t i2c_cmd = i2c_cmd_link_create();
-
-    i2c_master_start(i2c_cmd);
-    i2c_master_write_byte(i2c_cmd,
-                          TAS5713 | I2C_MASTER_WRITE,
-                          I2C_MASTER_NACK);
-    i2c_master_write_byte(i2c_cmd, reg, I2C_MASTER_NACK);
-    i2c_master_write_byte(i2c_cmd, val, I2C_MASTER_NACK);
-    i2c_master_stop(i2c_cmd);
-    ret = i2c_master_cmd_begin(i2c_port, i2c_cmd, 50 / portTICK_RATE_MS);
-
-    i2c_cmd_link_delete(i2c_cmd);
-
-    if (ret != ESP_OK) { 
-		ESP_LOGE(TAG, "Could not send command to TAS5713 %d", ret); 
-	}
-}
-
-/*************************************************************************
- * Read from i2c for the tas5713. This doubles as tas5713 detect. This function
- * returns zero on error, so read register 0x00 for tas detect, which will be
- * non-zero in this application.
- */
-static uint8_t tas5713_get(uint8_t reg) {
-    int              ret;
-    uint8_t             data = 0;
-    i2c_cmd_handle_t i2c_cmd = i2c_cmd_link_create();
-
-    i2c_master_start(i2c_cmd);
-    i2c_master_write_byte(i2c_cmd, TAS5713 | I2C_MASTER_WRITE, I2C_MASTER_NACK);
-    i2c_master_write_byte(i2c_cmd, reg, I2C_MASTER_NACK);
-
-    i2c_master_start(i2c_cmd);
-    i2c_master_write_byte(i2c_cmd, TAS5713 | I2C_MASTER_READ, I2C_MASTER_NACK);
-    i2c_master_read_byte(i2c_cmd, &data, I2C_MASTER_NACK);
-
-    i2c_master_stop(i2c_cmd);
-    ret = i2c_master_cmd_begin(i2c_port, i2c_cmd, 50 / portTICK_RATE_MS);
-    i2c_cmd_link_delete(i2c_cmd);
-
-    if (ret == ESP_OK) {
-        ESP_LOGI(TAG,"TAS5713 reg 0x%x is 0x%x", reg, data);
-    }
-    return data;
-}

+ 15 - 65
components/squeezelite/tas57xx/dac_57xx.c

@@ -18,19 +18,18 @@
 #include "esp_log.h"
 #include "adac.h"
 
-#define TAS575x 0x98
-#define TAS578x	0x90
+#define TAS575x (0x98 >> 1)
+#define TAS578x	(0x90 >> 1)
 
 static const char TAG[] = "TAS575x/8x";
 
 static bool init(char *config, int i2c_port_num, i2s_config_t *i2s_config);
-static void deinit(void);
 static void speaker(bool active);
 static void headset(bool active);
 static bool volume(unsigned left, unsigned right);
 static void power(adac_power_e mode);
 
-const struct adac_s dac_tas57xx = { "TAS57xx", init, deinit, power, speaker, headset, volume };
+const struct adac_s dac_tas57xx = { "TAS57xx", init, adac_deinit, power, speaker, headset, volume };
 
 struct tas57xx_cmd_s {
 	uint8_t reg;
@@ -60,7 +59,7 @@ static const struct tas57xx_cmd_s tas57xx_cmd[] = {
 };
 
 static uint8_t tas57_addr;
-static int i2c_port;
+	int i2c_port_x;
 
 static void dac_cmd(dac_cmd_e cmd, ...);
 static int tas57_detect(void);
@@ -68,32 +67,15 @@ static int tas57_detect(void);
 /****************************************************************************************
  * init
  */
-static bool init(char *config, int i2c_port_num, i2s_config_t *i2s_config) {	 
-	char *p;	
-	i2c_port = i2c_port_num;
-		
-	// configure i2c
-	i2c_config_t i2c_config = {
-			.mode = I2C_MODE_MASTER,
-			.sda_io_num = -1,
-			.sda_pullup_en = GPIO_PULLUP_ENABLE,
-			.scl_io_num = -1,
-			.scl_pullup_en = GPIO_PULLUP_ENABLE,
-			.master.clk_speed = 250000,
-		};
-
-	if ((p = strcasestr(config, "sda")) != NULL) i2c_config.sda_io_num = atoi(strchr(p, '=') + 1);
-	if ((p = strcasestr(config, "scl")) != NULL) i2c_config.scl_io_num = atoi(strchr(p, '=') + 1);
-	
-	i2c_param_config(i2c_port, &i2c_config);
-	i2c_driver_install(i2c_port, I2C_MODE_MASTER, false, false, false);
-		
+static bool init(char *config, int i2c_port, i2s_config_t *i2s_config) {	 
 	// find which TAS we are using (if any)
+i2c_port_x = i2c_port;
+	adac_init(config, i2c_port);
 	tas57_addr = tas57_detect();
-	
+		
 	if (!tas57_addr) {
 		ESP_LOGW(TAG, "No TAS57xx detected");
-		i2c_driver_delete(i2c_port);
+		adac_deinit();
 		return false;
 	}
 
@@ -101,7 +83,7 @@ static bool init(char *config, int i2c_port_num, i2s_config_t *i2s_config) {
 	
 	for (int i = 0; tas57xx_init_sequence[i].reg != 0xff; i++) {
 		i2c_master_start(i2c_cmd);
-		i2c_master_write_byte(i2c_cmd, tas57_addr | I2C_MASTER_WRITE, I2C_MASTER_NACK);
+		i2c_master_write_byte(i2c_cmd, (tas57_addr << 1) | I2C_MASTER_WRITE, I2C_MASTER_NACK);
 		i2c_master_write_byte(i2c_cmd, tas57xx_init_sequence[i].reg, I2C_MASTER_NACK);
 		i2c_master_write_byte(i2c_cmd, tas57xx_init_sequence[i].value, I2C_MASTER_NACK);
 		ESP_LOGD(TAG, "i2c write %x at %u", tas57xx_init_sequence[i].reg, tas57xx_init_sequence[i].value);
@@ -110,8 +92,6 @@ static bool init(char *config, int i2c_port_num, i2s_config_t *i2s_config) {
 	i2c_master_stop(i2c_cmd);	
 	esp_err_t res = i2c_master_cmd_begin(i2c_port, i2c_cmd, 500 / portTICK_RATE_MS);
     i2c_cmd_link_delete(i2c_cmd);
-
-	ESP_LOGI(TAG, "TAS57xx uses I2C sda:%d, scl:%d", i2c_config.sda_io_num, i2c_config.scl_io_num);
 	
 	if (res != ESP_OK) {
 		ESP_LOGE(TAG, "could not intialize TAS57xx %d", res);
@@ -121,13 +101,6 @@ static bool init(char *config, int i2c_port_num, i2s_config_t *i2s_config) {
 	return true;
 }	
 
-/****************************************************************************************
- * init
- */
-static void deinit(void)	{	 
-	i2c_driver_delete(i2c_port);
-}
-
 /****************************************************************************************
  * change volume
  */
@@ -176,25 +149,17 @@ void dac_cmd(dac_cmd_e cmd, ...) {
 	esp_err_t ret = ESP_OK;
 	
 	va_start(args, cmd);
-	i2c_cmd_handle_t i2c_cmd = i2c_cmd_link_create();
 
 	switch(cmd) {
 	case TAS57_VOLUME:
 		ESP_LOGE(TAG, "DAC volume not handled yet");
 		break;
 	default:
-		i2c_master_start(i2c_cmd);
-		i2c_master_write_byte(i2c_cmd, tas57_addr | I2C_MASTER_WRITE, I2C_MASTER_NACK);
-		i2c_master_write_byte(i2c_cmd, tas57xx_cmd[cmd].reg, I2C_MASTER_NACK);
-		i2c_master_write_byte(i2c_cmd, tas57xx_cmd[cmd].value, I2C_MASTER_NACK);
-		i2c_master_stop(i2c_cmd);	
-		ret	= i2c_master_cmd_begin(i2c_port, i2c_cmd, 50 / portTICK_RATE_MS);
+		ret = adac_write_byte(tas57_addr, tas57xx_cmd[cmd].reg, tas57xx_cmd[cmd].value);
 	}
 	
-    i2c_cmd_link_delete(i2c_cmd);
-	
-	if (ret != ESP_OK) {
-		ESP_LOGE(TAG, "could not intialize TAS57xx %d", ret);
+  	if (ret != ESP_OK) {
+		ESP_LOGE(TAG, "could not use TAS57xx %d", ret);
 	}
 
 	va_end(args);
@@ -204,25 +169,10 @@ void dac_cmd(dac_cmd_e cmd, ...) {
  * TAS57 detection
  */
 static int tas57_detect(void) {
-	uint8_t data, addr[] = {TAS578x, TAS575x};
-	int ret;
+	uint8_t addr[] = {TAS578x, TAS575x};
 	
 	for (int i = 0; i < sizeof(addr); i++) {
-		i2c_cmd_handle_t i2c_cmd = i2c_cmd_link_create();
-
-		i2c_master_start(i2c_cmd);
-		i2c_master_write_byte(i2c_cmd, addr[i] | I2C_MASTER_WRITE, I2C_MASTER_NACK);
-		i2c_master_write_byte(i2c_cmd, 00, I2C_MASTER_NACK);
-		
-		i2c_master_start(i2c_cmd);			
-		i2c_master_write_byte(i2c_cmd, addr[i] | I2C_MASTER_READ, I2C_MASTER_NACK);
-		i2c_master_read_byte(i2c_cmd, &data, I2C_MASTER_NACK);
-		
-		i2c_master_stop(i2c_cmd);	
-		ret	= i2c_master_cmd_begin(i2c_port, i2c_cmd, 50 / portTICK_RATE_MS);
-		i2c_cmd_link_delete(i2c_cmd);	
-		
-		if (ret == ESP_OK) {
+		if (adac_read_byte(addr[i], 0) != 255) {
 			ESP_LOGI(TAG, "Detected TAS @0x%x", addr[i]);
 			return addr[i];
 		}