diff --git a/apps/debug_menu.c b/apps/debug_menu.c index d8b92b7d09..d816a760f6 100644 --- a/apps/debug_menu.c +++ b/apps/debug_menu.c @@ -2624,8 +2624,9 @@ static bool dbg_device_data(void) simplelist_setline("Device data"); #if defined(EROS_QN) - simplelist_addline("Lcd Version: %d", (int)device_data.lcd_version); + simplelist_addline("Hardware Revision: %d", (int)device_data.hw_rev); #endif + simplelist_addline("Struct Ver: %d", (int)device_data.version); simplelist_setline("Device data RAW:"); for (size_t i = 0; i < device_data.length; i += 4) diff --git a/firmware/SOURCES b/firmware/SOURCES index 8ad9093e20..9ee81de392 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -525,9 +525,6 @@ drivers/audio/cs4398.c drivers/audio/es9018.c #elif defined (HAVE_ES9218) drivers/audio/es9218.c -#elif defined (HAVE_EROS_QN_CODEC) -drivers/audio/eros_qn_codec.c -drivers/audio/es9018k2m.c #endif /* defined(HAVE_*) */ #else /* PLATFORM_HOSTED */ #if defined(SAMSUNG_YPR0) && defined(HAVE_AS3514) @@ -562,6 +559,12 @@ target/hosted/sdl/pcm-sdl.c #endif /* !defined(BOOTLOADER) */ +/* build erosqn codec in bootloader for detection */ +#if defined(HAVE_EROS_QN_CODEC) +drivers/audio/eros_qn_codec.c +drivers/audio/es9018k2m.c +#endif /* defined(HAVE_EROSQN_CODEC) */ + /* WiFi */ #if !defined(BOOTLOADER) #if (CONFIG_PLATFORM & PLATFORM_NATIVE) diff --git a/firmware/drivers/audio/eros_qn_codec.c b/firmware/drivers/audio/eros_qn_codec.c index 1d6753eb3a..c9d01c5ed4 100644 --- a/firmware/drivers/audio/eros_qn_codec.c +++ b/firmware/drivers/audio/eros_qn_codec.c @@ -24,15 +24,22 @@ #include "config.h" #include "audio.h" #include "audiohw.h" +#ifndef BOOTLOADER #include "settings.h" +#endif #include "pcm_sw_volume.h" -#include "gpio-x1000.h" +// #define LOGF_ENABLE +#include "logf.h" + +#include "gpio-x1000.h" +#include "i2c-x1000.h" -static long int vol_l_hw = PCM5102A_VOLUME_MIN; -static long int vol_r_hw = PCM5102A_VOLUME_MIN; int es9018k2m_present_flag = 0; +#ifndef BOOTLOADER +static long int vol_l_hw = PCM5102A_VOLUME_MIN; +static long int vol_r_hw = PCM5102A_VOLUME_MIN; void eros_qn_set_outputs(void) { audiohw_set_volume(vol_l_hw, vol_r_hw); @@ -63,4 +70,33 @@ void eros_qn_switch_output(int select) { gpio_set_level(GPIO_STEREOSW_SEL, 1); } -} \ No newline at end of file +} +#endif /* !defined(BOOTLOADER) */ + +bool eros_qn_discover_dac(bool pwr_after_discovery) +{ + i2c_x1000_set_freq(ES9018K2M_BUS, I2C_FREQ_400K); + gpio_set_level(GPIO_DAC_PWR, 1); + gpio_set_level(GPIO_DAC_ANALOG_PWR, 1); + mdelay(10); + int ret = es9018k2m_read_reg(ES9018K2M_REG0_SYSTEM_SETTINGS); + if (ret == 0) + { + es9018k2m_present_flag = 1; + logf("ES9018K2M found! ret=%d", ret); + } + /* other options will go here if need be */ + else + { + es9018k2m_present_flag = 0; + logf("Default to SWVOL: ret=%d", ret); + } + + if (!pwr_after_discovery) + { + gpio_set_level(GPIO_DAC_PWR, 0); + gpio_set_level(GPIO_DAC_ANALOG_PWR, 0); + } + + return es9018k2m_present_flag; +} diff --git a/firmware/drivers/audio/es9018k2m.c b/firmware/drivers/audio/es9018k2m.c index 3f14aaea39..00eeebd7b3 100644 --- a/firmware/drivers/audio/es9018k2m.c +++ b/firmware/drivers/audio/es9018k2m.c @@ -23,7 +23,9 @@ #include "system.h" #include "es9018k2m.h" #include "i2c-async.h" -#include "action.h" +#ifndef BOOTLOADER +# include "action.h" +#endif //====================================================================================== // ES9018K2M support stuff @@ -36,6 +38,7 @@ # error "No definition for ES9018K2M I2C address!" #endif +#ifndef BOOTLOADER static int vol_tenthdb2hw(const int tdb) { if (tdb < ES9018K2M_VOLUME_MIN) { @@ -147,6 +150,7 @@ void es9018k2m_set_filter_roll_off(int value) es9018k2m_write_reg(ES9018K2M_REG7_GENERAL_SETTINGS, reg7_general_settings); es9018k2m_write_reg(ES9018K2M_REG21_GPIO_INPUT_SELECT, reg21_gpio_input_selection); } +#endif /* !defined(BOOTLOADER) */ /* returns I2C_STATUS_OK upon success, I2C_STATUS_* errors upon error */ int es9018k2m_write_reg(uint8_t reg, uint8_t val) diff --git a/firmware/drivers/axp-pmu.c b/firmware/drivers/axp-pmu.c index 0aa1610623..66949e338c 100644 --- a/firmware/drivers/axp-pmu.c +++ b/firmware/drivers/axp-pmu.c @@ -531,7 +531,7 @@ bool axp_debug_menu(void) # if defined(BOOTLOADER) devicever = EROSQN_VER; # else - devicever = device_data.lcd_version; + devicever = device_data.hw_rev; # endif if (devicever >= 4) { return axp2101_debug_menu(); @@ -556,7 +556,7 @@ unsigned int power_input_status(void) # if defined(BOOTLOADER) devicever = EROSQN_VER; # else - devicever = device_data.lcd_version; + devicever = device_data.hw_rev; # endif if (devicever >= 4) { return axp2101_power_input_status(); diff --git a/firmware/export/devicedata.h b/firmware/export/devicedata.h index c19b0ca25d..167d8e802f 100644 --- a/firmware/export/devicedata.h +++ b/firmware/export/devicedata.h @@ -37,6 +37,7 @@ #define DEVICE_DATA_MAGIC0 ('r' | 'b' << 8 | 'd' << 16 | 'e' << 24) #define DEVICE_DATA_MAGIC1 ('v' | 'i' << 8 | 'c' << 16 | 'e' << 24) +#define DEIVCE_DATA_VERSION 0 /* maximum size of payload */ #define DEVICE_DATA_PAYLOAD_SIZE 4 @@ -59,8 +60,9 @@ struct device_data_t struct { #if defined(EROS_QN) - uint8_t lcd_version; + uint8_t hw_rev; #endif + uint8_t version; }; uint8_t payload[DEVICE_DATA_PAYLOAD_SIZE]; }; diff --git a/firmware/export/eros_qn_codec.h b/firmware/export/eros_qn_codec.h index 223ef06779..c06cee30b6 100644 --- a/firmware/export/eros_qn_codec.h +++ b/firmware/export/eros_qn_codec.h @@ -53,4 +53,10 @@ void eros_qn_set_outputs(void); /* returns (global_settings.volume_limit * 10) */ int eros_qn_get_volume_limit(void); +/* powers on the dac and tries to speak over i2c. + * will return 1 if es9018k2m, 0 if non-i2c dac. + * if pwr_after_discovery = 1, leave dac powered up. + * if 0, power down dac. */ +bool eros_qn_discover_dac(bool pwr_after_discovery); + #endif diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c b/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c index 6968a19a1c..742899df68 100644 --- a/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c +++ b/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c @@ -32,6 +32,7 @@ #include "aic-x1000.h" #include "i2c-x1000.h" #include "gpio-x1000.h" +#include "devicedata.h" /* * Earlier devices audio path appears to be: @@ -42,7 +43,7 @@ * DAC --> HP Amp --> Stereo Switch \--> HP OUT * \-> LO OUT */ - +#if !defined(BOOTLOADER) void audiohw_init(void) { /* explicitly mute everything */ @@ -93,11 +94,18 @@ void audiohw_postinit(void) i2c_x1000_set_freq(ES9018K2M_BUS, I2C_FREQ_400K); - int ret = es9018k2m_read_reg(ES9018K2M_REG0_SYSTEM_SETTINGS); - if (ret >= 0) /* Detected ES9018K2M DAC */ + // devices hw2 and newer use es9018k2m i2c dac + // hw1 devices use swvol + // special case hw2 devices with bootloaders identifying as hw1 (pre-version field) + if (device_data.hw_rev >= 2 || \ + (device_data.version == 0xff && eros_qn_discover_dac(true))) { - logf("ES9018K2M found: ret=%d", ret); - es9018k2m_present_flag = 1; +#if defined(LOGF_ENABLE) + if (device_data.version == 0xff) { + logf("OLD BOOTLOADER FOUND, UPDATE IT!"); + } +#endif + es9018k2m_present_flag = true; /* Default is 32-bit data, and it works ok. Enabling the following * causes issue. Which is weird, I definitely thought AIC was configured @@ -128,8 +136,6 @@ void audiohw_postinit(void) * ! will hear random dropouts. (Fixed my SurfansF20 v3.2 dropouts) */ es9018k2m_write_reg(ES9018K2M_REG12_DPLL_SETTINGS, 0xda); - } else { /* Default to SWVOL for PCM5102A DAC */ - logf("Default to SWVOL: ret=%d", ret); } } @@ -205,4 +211,5 @@ void audiohw_set_filter_roll_off(int value) { es9018k2m_set_filter_roll_off(value); } -} \ No newline at end of file +} +#endif /* !defined(BOOTLOADER) */ \ No newline at end of file diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c b/firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c index 67da3ce645..3fa825fcdc 100644 --- a/firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c +++ b/firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c @@ -205,7 +205,7 @@ void button_init_device(void) /* Set up headphone and line out detect polling */ #ifndef BOOTLOADER - hp_detect_init(device_data.lcd_version); + hp_detect_init(device_data.hw_rev); #endif } @@ -266,7 +266,7 @@ int button_read_device(void) if((d & (1 << 5)) == 0) r |= BUTTON_BACK; # endif #else - if (device_data.lcd_version >= 4){ + if (device_data.hw_rev >= 4){ if((b & (1 << 31)) == 0) r |= BUTTON_POWER; if((a & (1 << 18)) == 0) r |= BUTTON_BACK; } else { @@ -280,7 +280,7 @@ int button_read_device(void) if((c & (1 << 24)) == 0) r |= BUTTON_NEXT; #ifndef BOOTLOADER - if (device_data.lcd_version >= 4){ + if (device_data.hw_rev >= 4){ // get new HP/LO detect states // HP_detect PB14 --> hp_detect bit 4 // LO_detect PB22 --> hp_detect bit 5 diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/lcd-erosqnative.c b/firmware/target/mips/ingenic_x1000/erosqnative/lcd-erosqnative.c index fb39051c7a..cad1a13cd7 100644 --- a/firmware/target/mips/ingenic_x1000/erosqnative/lcd-erosqnative.c +++ b/firmware/target/mips/ingenic_x1000/erosqnative/lcd-erosqnative.c @@ -297,7 +297,7 @@ void lcd_tgt_enable(bool enable) gpio_set_level(GPIO_LCD_PWR_HW1, 1); # endif #else - if (device_data.lcd_version <= 3) + if (device_data.hw_rev <= 3) { gpio_set_level(GPIO_LCD_PWR_HW1, 1); } @@ -322,7 +322,7 @@ void lcd_tgt_enable(bool enable) lcd_exec_commands(&erosqnative_lcd_cmd_enable_v1[0]); # endif #else - if (device_data.lcd_version >= 3) + if (device_data.hw_rev >= 3) { lcd_exec_commands(&erosqnative_lcd_cmd_enable_v3[0]); } diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/power-erosqnative.c b/firmware/target/mips/ingenic_x1000/erosqnative/power-erosqnative.c index 85fddc6044..5dad78392e 100644 --- a/firmware/target/mips/ingenic_x1000/erosqnative/power-erosqnative.c +++ b/firmware/target/mips/ingenic_x1000/erosqnative/power-erosqnative.c @@ -65,7 +65,7 @@ void power_init(void) #if defined(BOOTLOADER) devicever = EROSQN_VER; #else - devicever = device_data.lcd_version; + devicever = device_data.hw_rev; #endif if (devicever >= 4){ uint8_t regread; @@ -165,7 +165,7 @@ void usb_charging_maxcurrent_change(int maxcurrent) #if defined(BOOTLOADER) devicever = EROSQN_VER; #else - devicever = device_data.lcd_version; + devicever = device_data.hw_rev; #endif if (devicever >= 4){ axp2101_set_charge_current(maxcurrent); @@ -186,7 +186,7 @@ void power_off(void) #if defined(BOOTLOADER) devicever = EROSQN_VER; #else - devicever = device_data.lcd_version; + devicever = device_data.hw_rev; #endif if (devicever >= 4){ axp2101_power_off(); @@ -202,7 +202,7 @@ bool charging_state(void) #if defined(BOOTLOADER) devicever = EROSQN_VER; #else - devicever = device_data.lcd_version; + devicever = device_data.hw_rev; #endif if (devicever >= 4){ return axp2101_battery_status() == AXP2101_BATT_CHARGING; @@ -217,7 +217,7 @@ int _battery_voltage(void) #if defined(BOOTLOADER) devicever = EROSQN_VER; #else - devicever = device_data.lcd_version; + devicever = device_data.hw_rev; #endif if (devicever >= 4){ return axp2101_adc_read(AXP2101_ADC_VBAT_VOLTAGE); @@ -233,7 +233,7 @@ int _battery_current(void) #if defined(BOOTLOADER) devicever = EROSQN_VER; #else - devicever = device_data.lcd_version; + devicever = device_data.hw_rev; #endif if (devicever <= 3){ if(charging_state()) diff --git a/firmware/target/mips/ingenic_x1000/gpio-x1000.c b/firmware/target/mips/ingenic_x1000/gpio-x1000.c index f826971869..128687a358 100644 --- a/firmware/target/mips/ingenic_x1000/gpio-x1000.c +++ b/firmware/target/mips/ingenic_x1000/gpio-x1000.c @@ -67,7 +67,7 @@ void gpio_init(void) # if defined(BOOTLOADER) devicever = EROSQN_VER; # else - devicever = device_data.lcd_version; + devicever = device_data.hw_rev; # endif #endif /* Apply all initial GPIO settings */ diff --git a/firmware/target/mips/ingenic_x1000/system-x1000.c b/firmware/target/mips/ingenic_x1000/system-x1000.c index 1c850736b6..365b0031ec 100644 --- a/firmware/target/mips/ingenic_x1000/system-x1000.c +++ b/firmware/target/mips/ingenic_x1000/system-x1000.c @@ -41,6 +41,10 @@ #include "devicedata.h" #endif +#if defined(EROS_QN) +#include "eros_qn_codec.h" +#endif + #ifdef X1000_CPUIDLE_STATS int __cpu_idle_avg = 0; int __cpu_idle_cur = 0; @@ -89,14 +93,23 @@ void system_early_init(void) #if defined (HAVE_DEVICEDATA) && defined(EROS_QN) void fill_devicedata(struct device_data_t *data) { -#ifdef BOOTLOADER +# ifdef BOOTLOADER memset(data->payload, 0xff, data->length); - data->lcd_version = EROSQN_VER; -#else - uint8_t lcd_version = device_data.lcd_version; +# if EROSQN_VER == 1 + // version 2 has newer dac, 1 has old dac. + data->hw_rev = eros_qn_discover_dac(false) ? 2 : 1; +# else + // versions 3 and 4 both have new dac + data->hw_rev = EROSQN_VER; +# endif + data->version = DEIVCE_DATA_VERSION; +# else + uint8_t hw_rev = device_data.hw_rev; + uint8_t version = device_data.version; memset(data->payload, 0xff, data->length); - data->lcd_version = lcd_version; -#endif + data->hw_rev = hw_rev; + data->version = version; +# endif } #endif