summaryrefslogtreecommitdiff
path: root/firmware/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers')
-rw-r--r--firmware/drivers/audio/es9018.c134
-rw-r--r--firmware/drivers/audio/wm8740.c106
2 files changed, 240 insertions, 0 deletions
diff --git a/firmware/drivers/audio/es9018.c b/firmware/drivers/audio/es9018.c
new file mode 100644
index 0000000000..89e8c1d46f
--- /dev/null
+++ b/firmware/drivers/audio/es9018.c
@@ -0,0 +1,134 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2016 by Roman Stolyarov
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "system.h"
23#include "es9018.h"
24#include "config.h"
25#include "audio.h"
26#include "audiohw.h"
27
28/* NOTE: The register names are not known, as the register numbering
29 listed in the ES9018 datasheet does not match what is described below.. */
30
31static uint8_t reg0 = 0x00; /* System settings. Default value of register 0 */
32static uint8_t reg1 = 0x80; /* Input settings. Manual input, I2S, 32-bit (?) */
33static uint8_t reg4 = 0x00; /* Automute time. Default = disabled */
34static uint8_t reg5 = 0x68; /* Automute level. Default is some level */
35static uint8_t reg6 = 0x4A; /* Deemphasis. Default = disabled */
36static uint8_t reg7 = 0x83; /* General settings. Default sharp fir, pcm iir and muted */
37static uint8_t reg8 = 0x10; /* GPIO configuration */
38static uint8_t reg10 = 0x05; /* Master Mode Control. Default value: master mode off */
39static uint8_t reg11 = 0x02; /* Channel Mapping. Default stereo is Ch1=left, Ch2=right */
40static uint8_t reg12 = 0x50; /* DPLL Settings. Default = 005 for I2S, OFF for DSD */
41static uint8_t reg13 = 0x40; /* THD Compensation */
42static uint8_t reg14 = 0x8A; /* Soft Start Settings */
43static uint8_t reg21 = 0x00; /* Oversampling filter. Default: oversampling ON */
44
45#define bitSet(value, bit) ((value) |= (1UL << (bit)))
46#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
47
48static int vol_tenthdb2hw(const int tdb)
49{
50 if (tdb < ES9018_VOLUME_MIN) {
51 return 0xff;
52 } else if (tdb > ES9018_VOLUME_MAX) {
53 return 0x00;
54 } else {
55 return (-tdb/5);
56 }
57}
58
59void audiohw_set_volume(int vol_l, int vol_r)
60{
61 es9018_write_reg(15, vol_tenthdb2hw(vol_l));
62 es9018_write_reg(16, vol_tenthdb2hw(vol_r));
63}
64
65void audiohw_mute(void)
66{
67 bitSet(reg7, 0); /* Mute Channel 1 */
68 bitSet(reg7, 1); /* Mute Channel 2 */
69 es9018_write_reg(0x07, reg7);
70}
71
72void audiohw_unmute(void)
73{
74 bitClear(reg7, 0); /* Unmute Channel 1 */
75 bitClear(reg7, 1); /* Unmute Channel 2 */
76 es9018_write_reg(0x07, reg7);
77}
78
79void audiohw_init(void)
80{
81 es9018_write_reg(0x00, reg0);
82 es9018_write_reg(0x01, reg1);
83 es9018_write_reg(0x04, reg4);
84 es9018_write_reg(0x05, reg5);
85 es9018_write_reg(0x06, reg6);
86 es9018_write_reg(0x07, reg7);
87 es9018_write_reg(0x08, reg8);
88 es9018_write_reg(0x0A, reg10);
89 es9018_write_reg(0x0B, reg11);
90 es9018_write_reg(0x0C, reg12);
91 es9018_write_reg(0x0D, reg13);
92 es9018_write_reg(0x0E, reg14);
93 es9018_write_reg(0x15, reg21);
94}
95
96void audiohw_preinit(void)
97{
98}
99
100void audiohw_set_frequency(int fsel)
101{
102 (void)fsel;
103}
104
105void audiohw_set_filter_roll_off(int value)
106{
107 /* 0 = Sharp (Default)
108 1 = Slow
109 2 = Short
110 3 = Bypass */
111 switch(value)
112 {
113 case 0:
114 bitClear(reg7, 5);
115 bitClear(reg7, 6);
116 bitClear(reg21, 0);
117 break;
118 case 1:
119 bitSet(reg7, 5);
120 bitClear(reg7, 6);
121 bitClear(reg21, 0);
122 break;
123 case 2:
124 bitClear(reg7, 5);
125 bitSet(reg7, 6);
126 bitClear(reg21, 0);
127 break;
128 case 3:
129 bitSet(reg21, 0);
130 break;
131 }
132 es9018_write_reg(0x07, reg7);
133 es9018_write_reg(0x15, reg21);
134}
diff --git a/firmware/drivers/audio/wm8740.c b/firmware/drivers/audio/wm8740.c
new file mode 100644
index 0000000000..d88f53bd75
--- /dev/null
+++ b/firmware/drivers/audio/wm8740.c
@@ -0,0 +1,106 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2016 by Roman Stolyarov
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "system.h"
23#include "wm8740.h"
24#include "config.h"
25#include "audio.h"
26#include "audiohw.h"
27
28static void wm8740_write_reg(const int reg, const unsigned int value)
29{
30 int i;
31
32 for (i = (1<<15); i; i >>= 1) {
33 udelay(1);
34 wm8740_set_mc(0);
35 if ((reg|value) & i) {
36 wm8740_set_md(1);
37 } else {
38 wm8740_set_md(0);
39 }
40 udelay(1);
41 wm8740_set_mc(1);
42 }
43 udelay(1);
44 wm8740_set_ml(0);
45 udelay(1);
46 wm8740_set_mc(0);
47 udelay(1);
48 wm8740_set_ml(1);
49 udelay(1);
50}
51
52static int vol_tenthdb2hw(const int tdb)
53{
54 if (tdb < WM8740_VOLUME_MIN) {
55 return 0x00;
56 } else if (tdb > WM8740_VOLUME_MAX) {
57 return 0xff;
58 } else {
59 return ((tdb / 5 + 0xff) & 0xff);
60 }
61}
62
63void audiohw_set_volume(int vol_l, int vol_r)
64{
65 wm8740_write_reg(WM8740_REG0, vol_tenthdb2hw(vol_l));
66 wm8740_write_reg(WM8740_REG1, vol_tenthdb2hw(vol_r) | WM8740_LDR);
67}
68
69void audiohw_mute(void)
70{
71 wm8740_write_reg(WM8740_REG2, WM8740_MUT);
72}
73
74void audiohw_unmute(void)
75{
76 wm8740_write_reg(WM8740_REG2, 0x00);
77}
78
79void audiohw_init(void)
80{
81 wm8740_write_reg(WM8740_REG0, 0x00);
82 wm8740_write_reg(WM8740_REG1, 0x00);
83 wm8740_write_reg(WM8740_REG2, WM8740_MUT);
84 wm8740_write_reg(WM8740_REG3, WM8740_I2S);
85 wm8740_write_reg(WM8740_REG4, 0x00);
86}
87
88void audiohw_preinit(void)
89{
90}
91
92void audiohw_set_frequency(int fsel)
93{
94 (void)fsel;
95}
96
97void audiohw_set_filter_roll_off(int value)
98{
99 /* 0 = fast (sharp);
100 1 = slow */
101 if (value == 0) {
102 wm8740_write_reg(WM8740_REG3, WM8740_I2S);
103 } else {
104 wm8740_write_reg(WM8740_REG3, WM8740_I2S | WM8740_SR0);
105 }
106}