mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-11-10 13:42:29 -05:00
Setting not yet hidden for older hardware revision. Change-Id: Iaaa5727e63c38de578a6bbc73498ae1073180e65
161 lines
No EOL
5.8 KiB
C
161 lines
No EOL
5.8 KiB
C
/***************************************************************************
|
|
* __________ __ ___.
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
* \/ \/ \/ \/ \/
|
|
* $Id$
|
|
*
|
|
*
|
|
* Copyright (c) 2023 Dana Conrad
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
* KIND, either express or implied.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#include "system.h"
|
|
#include "es9018k2m.h"
|
|
#include "i2c-async.h"
|
|
#include "action.h"
|
|
|
|
//======================================================================================
|
|
// ES9018K2M support stuff
|
|
|
|
#ifndef ES9018K2M_BUS
|
|
# error "No definition for ES9018K2M I2C bus!"
|
|
#endif
|
|
|
|
#ifndef ES9018K2M_ADDR
|
|
# error "No definition for ES9018K2M I2C address!"
|
|
#endif
|
|
|
|
static int vol_tenthdb2hw(const int tdb)
|
|
{
|
|
if (tdb < ES9018K2M_VOLUME_MIN) {
|
|
return 0xff;
|
|
} else if (tdb > ES9018K2M_VOLUME_MAX) {
|
|
return 0x00;
|
|
} else {
|
|
return (-tdb/5);
|
|
}
|
|
}
|
|
|
|
/* NOTE: This implementation is for the ES9018K2M specifically. */
|
|
/* Register defaults from the datasheet. */
|
|
/* These are basically just for reference. All defaults work out for us.
|
|
* static uint8_t reg0_system_settings = 0x00; // System settings. Default value of register 0
|
|
* static uint8_t reg1_input_configuration = 0x8C; // Input settings. I2S input, 32-bit
|
|
* static uint8_t reg4_automute_time = 0x00; // Automute time. Default = disabled
|
|
* static uint8_t reg5_automute_level = 0x68; // Automute level. Default is some level
|
|
* static uint8_t reg6_deemphasis = 0x4A; // Deemphasis. Default = disabled
|
|
*/
|
|
static uint8_t reg7_general_settings = 0x80; // General settings. Default sharp fir, pcm iir and unmuted
|
|
/*
|
|
* static uint8_t reg8_gpio_configuration = 0x10; // GPIO configuration
|
|
* static uint8_t reg10_master_mode_control = 0x05; // Master Mode Control. Default value: master mode off
|
|
* static uint8_t reg11_channel_mapping = 0x02; // Channel Mapping. Default stereo is Ch1=left, Ch2=right
|
|
* static uint8_t reg12_dpll_settings = 0x5A; // DPLL Settings. Default = 5 for I2S, A for DSD
|
|
* static uint8_t reg13_thd_comp = 0x40; // THD Compensation
|
|
* static uint8_t reg14_softstart_settings = 0x8A; // Soft Start Settings
|
|
*/
|
|
static uint8_t reg21_gpio_input_selection = 0x00; // Oversampling filter. Default: oversampling ON
|
|
|
|
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
|
|
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
|
|
|
|
static uint8_t vol_reg_l = ES9018K2M_REG15_VOLUME_L;
|
|
static uint8_t reg15_vol_l = 0;
|
|
i2c_descriptor vol_desc_l = {
|
|
.slave_addr = ES9018K2M_ADDR,
|
|
.bus_cond = I2C_START | I2C_STOP,
|
|
.tran_mode = I2C_WRITE,
|
|
.buffer[0] = &vol_reg_l,
|
|
.count[0] = 1,
|
|
.buffer[1] = ®15_vol_l,
|
|
.count[1] = 1,
|
|
.callback = NULL,
|
|
.arg = 0,
|
|
.next = NULL,
|
|
};
|
|
|
|
static uint8_t vol_reg_r = ES9018K2M_REG16_VOLUME_R;
|
|
static uint8_t reg16_vol_r = 0;
|
|
i2c_descriptor vol_desc_r = {
|
|
.slave_addr = ES9018K2M_ADDR,
|
|
.bus_cond = I2C_START | I2C_STOP,
|
|
.tran_mode = I2C_WRITE,
|
|
.buffer[0] = &vol_reg_r,
|
|
.count[0] = 1,
|
|
.buffer[1] = ®16_vol_r,
|
|
.count[1] = 1,
|
|
.callback = NULL,
|
|
.arg = 0,
|
|
.next = NULL,
|
|
};
|
|
|
|
void es9018k2m_set_volume_async(int vol_l, int vol_r)
|
|
{
|
|
/* Queue writes to the DAC's volume.
|
|
* Note that this needs to be done asynchronously. From testing, calling
|
|
* synchronous writes from HP/LO detect causes hangs. */
|
|
reg15_vol_l = vol_tenthdb2hw(vol_l);
|
|
reg16_vol_r = vol_tenthdb2hw(vol_r);
|
|
i2c_async_queue(ES9018K2M_BUS, TIMEOUT_NOBLOCK, I2C_Q_ADD, 0, &vol_desc_l);
|
|
i2c_async_queue(ES9018K2M_BUS, TIMEOUT_NOBLOCK, I2C_Q_ADD, 0, &vol_desc_r);
|
|
}
|
|
|
|
void es9018k2m_set_filter_roll_off(int value)
|
|
{
|
|
/* Note: the ihifi800 implementation manipulates
|
|
* bit 0 of reg21, but I think that is incorrect?
|
|
* Bit 2 is the bypass for the IIR digital filters,
|
|
* Whereas Bit 0 is the oversampling filter, which
|
|
* the datasheet seems to say should be left on. */
|
|
|
|
/* 0 = "Sharp" / Fast Rolloff (Default)
|
|
1 = Slow Rolloff
|
|
2 = "Short" / Minimum Phase
|
|
3 = Bypass */
|
|
switch(value)
|
|
{
|
|
case 0:
|
|
bitClear(reg7_general_settings, 5);
|
|
bitClear(reg7_general_settings, 6);
|
|
bitClear(reg21_gpio_input_selection, 2);
|
|
break;
|
|
case 1:
|
|
bitSet(reg7_general_settings, 5);
|
|
bitClear(reg7_general_settings, 6);
|
|
bitClear(reg21_gpio_input_selection, 2);
|
|
break;
|
|
case 2:
|
|
bitClear(reg7_general_settings, 5);
|
|
bitSet(reg7_general_settings, 6);
|
|
bitClear(reg21_gpio_input_selection, 2);
|
|
break;
|
|
case 3:
|
|
bitSet(reg21_gpio_input_selection, 2);
|
|
break;
|
|
}
|
|
es9018k2m_write_reg(ES9018K2M_REG7_GENERAL_SETTINGS, reg7_general_settings);
|
|
es9018k2m_write_reg(ES9018K2M_REG21_GPIO_INPUT_SELECT, reg21_gpio_input_selection);
|
|
}
|
|
|
|
/* returns I2C_STATUS_OK upon success, I2C_STATUS_* errors upon error */
|
|
int es9018k2m_write_reg(uint8_t reg, uint8_t val)
|
|
{
|
|
return i2c_reg_write1(ES9018K2M_BUS, ES9018K2M_ADDR, reg, val);
|
|
}
|
|
|
|
/* returns register value, or -1 upon error */
|
|
int es9018k2m_read_reg(uint8_t reg)
|
|
{
|
|
return i2c_reg_read1(ES9018K2M_BUS, ES9018K2M_ADDR, reg);
|
|
} |