summaryrefslogtreecommitdiff
path: root/firmware/drivers/audio/as3514.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/audio/as3514.c')
-rw-r--r--firmware/drivers/audio/as3514.c211
1 files changed, 211 insertions, 0 deletions
diff --git a/firmware/drivers/audio/as3514.c b/firmware/drivers/audio/as3514.c
new file mode 100644
index 0000000000..89761fbbe0
--- /dev/null
+++ b/firmware/drivers/audio/as3514.c
@@ -0,0 +1,211 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Driver for AS3514 audio codec
11 *
12 * Copyright (c) 2007 Daniel Ankers
13 * Copyright (c) 2007 Christian Gmeiner
14 *
15 * All files in this archive are subject to the GNU General Public License.
16 * See the file COPYING in the source tree root for full license agreement.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22#include "cpu.h"
23#include "debug.h"
24#include "system.h"
25
26#include "as3514.h"
27#include "i2s.h"
28#include "i2c-pp.h"
29
30/* Shadow registers */
31int as3514_regs[0x1D];
32
33/*
34 * little helper method to set register values.
35 * With the help of as3514_regs, we minimize i2c
36 * traffic.
37 */
38static void as3514_write(int reg, int value)
39{
40 if (pp_i2c_send(AS3514_I2C_ADDR, reg, value) != 2)
41 {
42 DEBUGF("as3514 error reg=0x%x", reg);
43 }
44 as3514_regs[reg] = value;
45}
46
47/* convert tenth of dB volume to master volume register value */
48int tenthdb2master(int db)
49{
50 /* +6 to -40.43dB in 1.5dB steps == 32 levels = 5 bits */
51 /* 11111 == +6dB (0x1f) = 31) */
52 /* 11110 == -4.5dB (0x1e) = 30) */
53 /* 00001 == -39dB (0x01) */
54 /* 00000 == -40.5dB (0x00) */
55
56 if (db < VOLUME_MIN) {
57 return 0x0;
58 } else if (db >= VOLUME_MAX) {
59 return 0x1f;
60 } else {
61 return((db-VOLUME_MIN)/15); /* VOLUME_MIN is negative */
62 }
63}
64
65void audiohw_reset(void);
66
67/*
68 * Initialise the PP I2C and I2S.
69 */
70int audiohw_init(void)
71{
72 unsigned int i;
73
74 /* reset I2C */
75 i2c_init();
76
77 /* normal outputs for CDI and I2S pin groups */
78 DEV_INIT &= ~0x300;
79
80 /*mini2?*/
81 outl(inl(0x70000010) & ~0x3000000, 0x70000010);
82 /*mini2?*/
83
84 /* device reset */
85 DEV_RS |= 0x800;
86 DEV_RS &=~0x800;
87
88 /* device enable */
89 DEV_EN |= 0x807;
90
91 /* enable external dev clock clocks */
92 DEV_EN |= 0x2;
93
94 /* external dev clock to 24MHz */
95 outl(inl(0x70000018) & ~0xc, 0x70000018);
96
97 i2s_reset();
98
99 /* Set ADC off, mixer on, DAC on, line out off, line in off, mic off */
100 as3514_write(AUDIOSET1, 0x20); /* Turn on DAC */
101 as3514_write(AUDIOSET3, 0x5); /* Set HPCM off, ZCU off*/
102 as3514_write(HPH_OUT_R, 0xc0 | 0x16); /* set vol and set speaker over-current to 0 */
103 as3514_write(HPH_OUT_L, 0x16); /* set default vol for headphone */
104 as3514_write(PLLMODE, 0x04);
105
106 /* read all reg values */
107 for (i = 0; i < sizeof(as3514_regs); i++)
108 {
109 as3514_regs[i] = i2c_readbyte(AS3514_I2C_ADDR, i);
110 }
111
112 return 0;
113}
114
115void audiohw_postinit(void)
116{
117}
118
119/* Silently enable / disable audio output */
120void audiohw_enable_output(bool enable)
121{
122 int curr;
123 curr = as3514_regs[HPH_OUT_L];
124
125 if (enable)
126 {
127 /* reset the I2S controller into known state */
128 i2s_reset();
129
130 as3514_write(HPH_OUT_L, curr | 0x40); /* power on */
131 audiohw_mute(0);
132 } else {
133 audiohw_mute(1);
134 as3514_write(HPH_OUT_L, curr & ~(0x40)); /* power off */
135 }
136}
137
138int audiohw_set_master_vol(int vol_l, int vol_r)
139{
140 vol_l &= 0x1f;
141 vol_r &= 0x1f;
142
143 /* we are controling dac volume instead of headphone volume,
144 as the volume is bigger.
145 HDP: 1.07 dB gain
146 DAC: 6 dB gain
147 */
148 as3514_write(DAC_R, vol_r);
149 as3514_write(DAC_L, 0x40 | vol_l);
150
151 return 0;
152}
153
154int audiohw_set_lineout_vol(int vol_l, int vol_r)
155{
156 as3514_write(LINE_OUT_R, vol_r);
157 as3514_write(LINE_OUT_L, 0x40 | vol_l);
158
159 return 0;
160}
161
162int audiohw_mute(int mute)
163{
164 int curr;
165 curr = as3514_regs[HPH_OUT_L];
166
167 if (mute)
168 {
169 as3514_write(HPH_OUT_L, curr | 0x80);
170 } else {
171 as3514_write(HPH_OUT_L, curr & ~(0x80));
172 }
173
174 return 0;
175}
176
177/* Nice shutdown of WM8758 codec */
178void audiohw_close(void)
179{
180 /* mute headphones */
181 audiohw_mute(1);
182
183 /* turn off everything */
184 as3514_write(AUDIOSET1, 0x0);
185}
186
187void audiohw_set_sample_rate(int sampling_control)
188{
189 (void)sampling_control;
190}
191
192void audiohw_enable_recording(bool source_mic)
193{
194 (void)source_mic;
195}
196
197void audiohw_disable_recording(void)
198{
199}
200
201void audiohw_set_recvol(int left, int right, int type)
202{
203 (void)left;
204 (void)right;
205 (void)type;
206}
207
208void audiohw_set_monitor(int enable)
209{
210 (void)enable;
211}