summaryrefslogtreecommitdiffstats
path: root/firmware/drivers/audio/es9018.c
blob: 89e8c1d46f6b6182ad5174904cdc4f365a15b7f7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/***************************************************************************
 *             __________               __   ___.
 *   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:  The register names are not known, as the register numbering
   listed in the ES9018 datasheet does not match what is described below.. */

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);
}