1
0
Fork 0
forked from len0rd/rockbox
foxbox/firmware/drivers/audio/es9018.c
Dana Conrad a3fe07ff12 ErosQ New Revision HW volume
Add HW volume control via ES9018K2M, and reorganize
eros_qn_codec.c/.h, audiohw-erosqnative.c.

This automatically detects the presence of the new DAC and
uses its hardware volume scaling. If not present, use same
SWVOL we have been using so far.

Add debug menu readout of SWVOL/I2C result.

Break out es9018k2m stuff into its own file so that
maybe it can be useful to other ports.

Note that we may need to get smarter about detecting the DAC
type if/when another model emerges.

Change-Id: I586a1cf7f150dd6b4e221157859825952840af56
2024-01-02 06:51:07 -05:00

134 lines
4.1 KiB
C

/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2016 by Roman Stolyarov
*
* 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 "es9018.h"
#include "config.h"
#include "audio.h"
#include "audiohw.h"
/* NOTE: This implementation is specifically for the ES9018K2M, which has a different register
* structure from the ES9018. */
static uint8_t reg0 = 0x00; /* System settings. Default value of register 0 */
static uint8_t reg1 = 0x80; /* Input settings. Manual input, I2S, 32-bit (?) */
static uint8_t reg4 = 0x00; /* Automute time. Default = disabled */
static uint8_t reg5 = 0x68; /* Automute level. Default is some level */
static uint8_t reg6 = 0x4A; /* Deemphasis. Default = disabled */
static uint8_t reg7 = 0x83; /* General settings. Default sharp fir, pcm iir and muted */
static uint8_t reg8 = 0x10; /* GPIO configuration */
static uint8_t reg10 = 0x05; /* Master Mode Control. Default value: master mode off */
static uint8_t reg11 = 0x02; /* Channel Mapping. Default stereo is Ch1=left, Ch2=right */
static uint8_t reg12 = 0x50; /* DPLL Settings. Default = 005 for I2S, OFF for DSD */
static uint8_t reg13 = 0x40; /* THD Compensation */
static uint8_t reg14 = 0x8A; /* Soft Start Settings */
static uint8_t reg21 = 0x00; /* Oversampling filter. Default: oversampling ON */
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
static int vol_tenthdb2hw(const int tdb)
{
if (tdb < ES9018_VOLUME_MIN) {
return 0xff;
} else if (tdb > ES9018_VOLUME_MAX) {
return 0x00;
} else {
return (-tdb/5);
}
}
void audiohw_set_volume(int vol_l, int vol_r)
{
es9018_write_reg(15, vol_tenthdb2hw(vol_l));
es9018_write_reg(16, vol_tenthdb2hw(vol_r));
}
void audiohw_mute(void)
{
bitSet(reg7, 0); /* Mute Channel 1 */
bitSet(reg7, 1); /* Mute Channel 2 */
es9018_write_reg(0x07, reg7);
}
void audiohw_unmute(void)
{
bitClear(reg7, 0); /* Unmute Channel 1 */
bitClear(reg7, 1); /* Unmute Channel 2 */
es9018_write_reg(0x07, reg7);
}
void audiohw_init(void)
{
es9018_write_reg(0x00, reg0);
es9018_write_reg(0x01, reg1);
es9018_write_reg(0x04, reg4);
es9018_write_reg(0x05, reg5);
es9018_write_reg(0x06, reg6);
es9018_write_reg(0x07, reg7);
es9018_write_reg(0x08, reg8);
es9018_write_reg(0x0A, reg10);
es9018_write_reg(0x0B, reg11);
es9018_write_reg(0x0C, reg12);
es9018_write_reg(0x0D, reg13);
es9018_write_reg(0x0E, reg14);
es9018_write_reg(0x15, reg21);
}
void audiohw_preinit(void)
{
}
void audiohw_set_frequency(int fsel)
{
(void)fsel;
}
void audiohw_set_filter_roll_off(int value)
{
/* 0 = Sharp (Default)
1 = Slow
2 = Short
3 = Bypass */
switch(value)
{
case 0:
bitClear(reg7, 5);
bitClear(reg7, 6);
bitClear(reg21, 0);
break;
case 1:
bitSet(reg7, 5);
bitClear(reg7, 6);
bitClear(reg21, 0);
break;
case 2:
bitClear(reg7, 5);
bitSet(reg7, 6);
bitClear(reg21, 0);
break;
case 3:
bitSet(reg21, 0);
break;
}
es9018_write_reg(0x07, reg7);
es9018_write_reg(0x15, reg21);
}