summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/drivers/uda1380.c127
-rw-r--r--firmware/export/uda1380.h132
-rw-r--r--firmware/sound.c4
3 files changed, 192 insertions, 71 deletions
diff --git a/firmware/drivers/uda1380.c b/firmware/drivers/uda1380.c
index 4b63ccd744..4eb04d1ba3 100644
--- a/firmware/drivers/uda1380.c
+++ b/firmware/drivers/uda1380.c
@@ -39,27 +39,28 @@
39int uda1380_write_reg(unsigned char reg, unsigned short value); 39int uda1380_write_reg(unsigned char reg, unsigned short value);
40unsigned short uda1380_regs[0x30]; 40unsigned short uda1380_regs[0x30];
41 41
42/* Definition of a good (?) configuration to start with */ 42/* Definition of a playback configuration to start with */
43/* Not enabling ADC for now.. */
44 43
45#define NUM_DEFAULT_REGS 13 44#define NUM_DEFAULT_REGS 13
46unsigned short uda1380_defaults[2*NUM_DEFAULT_REGS] = 45unsigned short uda1380_defaults[2*NUM_DEFAULT_REGS] =
47{ 46{
48 REG_0, EN_DAC | EN_INT | EN_DEC | SYSCLK_256FS | WSPLL_25_50, 47 REG_0, EN_DAC | EN_INT | EN_DEC | SYSCLK_256FS | WSPLL_25_50,
49 REG_I2S, I2S_IFMT_IIS, 48 REG_I2S, I2S_IFMT_IIS,
50 REG_PWR, PON_PLL | PON_DAC | PON_BIAS, /* PON_HP is enabled later */ 49 REG_PWR, PON_PLL | PON_DAC | PON_BIAS, /* PON_HP is enabled later */
51 REG_AMIX, AMIX_RIGHT(0x10) | AMIX_LEFT(0x10), /* 00=max, 3f=mute */ 50 REG_AMIX, AMIX_RIGHT(0x3f) | AMIX_LEFT(0x3f), /* 00=max, 3f=mute */
52 REG_MASTER_VOL, MASTER_VOL_LEFT(0x20) | MASTER_VOL_RIGHT(0x20), /* 00=max, ff=mute */ 51 REG_MASTER_VOL, MASTER_VOL_LEFT(0x20) | MASTER_VOL_RIGHT(0x20), /* 00=max, ff=mute */
53 REG_MIX_VOL, MIX_VOL_CHANNEL_1(0) | MIX_VOL_CHANNEL_2(0xff), /* 00=max, ff=mute */ 52 REG_MIX_VOL, MIX_VOL_CH_1(0) | MIX_VOL_CH_2(0xff), /* 00=max, ff=mute */
54 REG_EQ, 0, 53 REG_EQ, EQ_MODE_MAX, /* Bass and tremble = 0 dB */
55 REG_MUTE, MUTE_MASTER, /* Mute everything to start with */ 54 REG_MUTE, MUTE_MASTER, /* Mute everything to start with */
56 REG_MIX_CTL, 0, 55 REG_MIX_CTL, 0,
57 REG_DEC_VOL, 0, 56 REG_DEC_VOL, 0,
58 REG_PGA, MUTE_ADC, 57 REG_PGA, MUTE_ADC,
59 REG_ADC, SKIP_DCFIL, 58 REG_ADC, SKIP_DCFIL,
60 REG_AGC, 0 59 REG_AGC, 0
61}; 60};
62 61
62
63
63/* Returns 0 if register was written or -1 if write failed */ 64/* Returns 0 if register was written or -1 if write failed */
64int uda1380_write_reg(unsigned char reg, unsigned short value) 65int uda1380_write_reg(unsigned char reg, unsigned short value)
65{ 66{
@@ -93,6 +94,22 @@ int uda1380_setvol(int vol)
93 MASTER_VOL_LEFT(vol) | MASTER_VOL_RIGHT(vol)); 94 MASTER_VOL_LEFT(vol) | MASTER_VOL_RIGHT(vol));
94} 95}
95 96
97/**
98 * Sets the bass value (0-15)
99 */
100void uda1380_set_bass(int value)
101{
102 uda1380_write_reg(REG_EQ, (uda1380_regs[REG_EQ] & ~BASS_MASK) | BASSL(value) | BASSR(value));
103}
104
105/**
106 * Sets the treble value (0-3)
107 */
108void uda1380_set_treble(int value)
109{
110 uda1380_write_reg(REG_EQ, (uda1380_regs[REG_EQ] & ~TREBLE_MASK) | TREBLEL(value) | TREBLER(value));
111}
112
96/** 113/**
97 * Mute (mute=1) or enable sound (mute=0) 114 * Mute (mute=1) or enable sound (mute=0)
98 * 115 *
@@ -163,3 +180,81 @@ void uda1380_close(void)
163 uda1380_write_reg(REG_PWR, 0); 180 uda1380_write_reg(REG_PWR, 0);
164 uda1380_write_reg(REG_0, 0); /* Disable codec */ 181 uda1380_write_reg(REG_0, 0); /* Disable codec */
165} 182}
183
184/**
185 * Calling this function enables the UDA1380 to send
186 * sound samples over the I2S bus, which is connected
187 * to the processor's IIS1 interface.
188 *
189 * source_mic: true=record from microphone, false=record from line-in
190 */
191void uda1380_enable_recording(bool source_mic)
192{
193 uda1380_write_reg(REG_0, uda1380_regs[REG_0] | EN_ADC);
194
195 if (source_mic)
196 {
197 uda1380_write_reg(REG_PWR, uda1380_regs[REG_PWR] | PON_LNA | PON_ADCL);
198 uda1380_write_reg(REG_ADC, (uda1380_regs[REG_ADC] & VGA_GAIN_MASK) | SEL_LNA | SEL_MIC | EN_DCFIL); /* VGA_GAIN: 0=0 dB, F=30dB */
199 uda1380_write_reg(REG_PGA, 0);
200 } else
201 {
202 uda1380_write_reg(REG_PWR, uda1380_regs[REG_PWR] | PON_PGAL | PON_ADCL | PON_PGAR | PON_ADCR);
203 uda1380_write_reg(REG_ADC, EN_DCFIL);
204 uda1380_write_reg(REG_PGA, (uda1380_regs[REG_PGA] & PGA_GAIN_MASK) | PGA_GAINL(0) | PGA_GAINR(0)); /* PGA_GAIN: 0=0 dB, F=24dB */
205 }
206
207 uda1380_write_reg(REG_I2S, uda1380_regs[REG_I2S] | I2S_MODE_MASTER);
208 uda1380_write_reg(REG_MIX_CTL, MIX_MODE(3)); /* Not sure which mode is the best one.. */
209
210}
211
212/**
213 * Stop sending samples on the I2S bus
214 */
215void uda1380_disable_recording(void)
216{
217 uda1380_write_reg(REG_PGA, MUTE_ADC);
218 sleep(HZ/8);
219
220 uda1380_write_reg(REG_I2S, I2S_IFMT_IIS);
221 uda1380_write_reg(REG_PWR, uda1380_regs[REG_PWR] & ~(PON_LNA | PON_ADCL | PON_ADCR | PON_PGAL | PON_PGAR));
222 uda1380_write_reg(REG_0, uda1380_regs[REG_0] & ~EN_ADC);
223 uda1380_write_reg(REG_ADC, SKIP_DCFIL);
224}
225
226/**
227 * Set recording gain and volume
228 *
229 * mic_gain : range 0 .. 15 -> 0 .. 30 dB gain
230 * linein_gain : range 0 .. 15 -> 0 .. 24 dB gain
231 *
232 * adc_volume : range -127 .. 48 -> -63 .. 24 dB gain
233 * note that 0 -> 0 dB gain..
234 */
235void uda1380_set_recvol(int mic_gain, int linein_gain, int adc_volume)
236{
237 uda1380_write_reg(REG_DEC_VOL, DEC_VOLL(adc_volume) | DEC_VOLR(adc_volume));
238 uda1380_write_reg(REG_PGA, (uda1380_regs[REG_PGA] & ~PGA_GAIN_MASK) | PGA_GAINL(linein_gain) | PGA_GAINR(linein_gain));
239 uda1380_write_reg(REG_ADC, (uda1380_regs[REG_ADC] & ~VGA_GAIN_MASK) | VGA_GAIN(mic_gain));
240}
241
242
243/**
244 * Enable or disable recording monitor (so one can listen to the recording)
245 *
246 */
247void uda1380_set_monitor(int enable)
248{
249 if (enable)
250 {
251 /* enable channel 2 */
252 uda1380_write_reg(REG_MIX_VOL, (uda1380_regs[REG_MIX_VOL] & 0x00FF) | MIX_VOL_CH_2(0));
253 uda1380_write_reg(REG_MUTE, 0);
254 } else
255 {
256 /* mute channel 2 */
257 uda1380_write_reg(REG_MUTE, MUTE_CH2);
258 uda1380_write_reg(REG_MIX_VOL, (uda1380_regs[REG_MIX_VOL] & 0x00FF) | MIX_VOL_CH_2(0xff));
259 }
260}
diff --git a/firmware/export/uda1380.h b/firmware/export/uda1380.h
index c6993ef84c..f7e97e13c7 100644
--- a/firmware/export/uda1380.h
+++ b/firmware/export/uda1380.h
@@ -17,32 +17,33 @@
17 * 17 *
18 ****************************************************************************/ 18 ****************************************************************************/
19 19
20/*
21 * Driver for UDA1380 Audio-Codec
22 * 2005-02-17 hubble@mochine.com
23 *
24 */
25
26#ifndef _UDA1380_H 20#ifndef _UDA1380_H
27#define _UDA1380_H 21#define _UDA1380_H
28 22
29extern int uda1380_init(void); 23extern int uda1380_init(void);
30extern void uda1380_enable_output(bool enable); 24extern void uda1380_enable_output(bool enable);
31extern int uda1380_setvol(int vol); 25extern int uda1380_setvol(int vol);
26extern void uda1380_set_bass(int value);
27extern void uda1380_set_treble(int value);
32extern int uda1380_mute(int mute); 28extern int uda1380_mute(int mute);
33extern void uda1380_close(void); 29extern void uda1380_close(void);
34 30
35#define UDA1380_ADDR 0x30 31extern void uda1380_enable_recording(bool source_mic);
32extern void uda1380_disable_recording(void);
33extern void uda1380_set_recvol(int mic_gain, int linein_gain, int adc_volume);
34extern void uda1380_set_monitor(int enable);
35
36#define UDA1380_ADDR 0x30
36 37
37/* REG_0: Misc settings */ 38/* REG_0: Misc settings */
38#define REG_0 0x00 39#define REG_0 0x00
39 40
40#define EN_ADC (1 << 11) /* Enable ADC */ 41#define EN_ADC (1 << 11) /* Enable ADC */
41#define EN_DEC (1 << 10) /* Enable Decimator */ 42#define EN_DEC (1 << 10) /* Enable Decimator */
42#define EN_DAC (1 << 9) /* Enable DAC */ 43#define EN_DAC (1 << 9) /* Enable DAC */
43#define EN_INT (1 << 8) /* Enable Interpolator */ 44#define EN_INT (1 << 8) /* Enable Interpolator */
44#define ADC_CLK (1 << 5) /* ADC_CLK: WSPLL (1) SYSCLK (0) */ 45#define ADC_CLK (1 << 5) /* ADC_CLK: WSPLL (1) SYSCLK (0) */
45#define DAC_CLK (1 << 4) /* DAC_CLK: WSPLL (1) SYSCLK (0) */ 46#define DAC_CLK (1 << 4) /* DAC_CLK: WSPLL (1) SYSCLK (0) */
46 47
47/* SYSCLK freqency select */ 48/* SYSCLK freqency select */
48#define SYSCLK_256FS (0 << 2) 49#define SYSCLK_256FS (0 << 2)
@@ -51,14 +52,14 @@ extern void uda1380_close(void);
51#define SYSCLK_768FS (3 << 2) 52#define SYSCLK_768FS (3 << 2)
52 53
53/* WSPLL Input frequency range (kHz) */ 54/* WSPLL Input frequency range (kHz) */
54#define WSPLL_625_125 (0 << 0) /* 6.25 - 12.5 */ 55#define WSPLL_625_125 (0 << 0) /* 6.25 - 12.5 */
55#define WSPLL_125_25 (1 << 0) /* 12.5 - 25 */ 56#define WSPLL_125_25 (1 << 0) /* 12.5 - 25 */
56#define WSPLL_25_50 (2 << 0) /* 25 - 50 */ 57#define WSPLL_25_50 (2 << 0) /* 25 - 50 */
57#define WSPLL_50_100 (3 << 0) /* 50 - 100 */ 58#define WSPLL_50_100 (3 << 0) /* 50 - 100 */
58 59
59 60
60/* REG_I2S: I2S settings */ 61/* REG_I2S: I2S settings */
61#define REG_I2S 0x01 62#define REG_I2S 0x01
62#define I2S_IFMT_IIS (0 << 8) 63#define I2S_IFMT_IIS (0 << 8)
63#define I2S_IFMT_LSB16 (1 << 8) 64#define I2S_IFMT_LSB16 (1 << 8)
64#define I2S_IFMT_LSB18 (2 << 8) 65#define I2S_IFMT_LSB18 (2 << 8)
@@ -70,71 +71,92 @@ extern void uda1380_close(void);
70#define I2S_OFMT_LSB20 (3 << 0) 71#define I2S_OFMT_LSB20 (3 << 0)
71#define I2S_OFMT_LSB24 (4 << 0) 72#define I2S_OFMT_LSB24 (4 << 0)
72#define I2S_OFMT_MSB (5 << 0) 73#define I2S_OFMT_MSB (5 << 0)
73 74#define I2S_MODE_MASTER (1 << 4)
74 75
75/* REG_PWR: Power control */ 76/* REG_PWR: Power control */
76#define REG_PWR 0x02 77#define REG_PWR 0x02
77#define PON_PLL (1 << 15) /* Power-on WSPLL */ 78#define PON_PLL (1 << 15) /* Power-on WSPLL */
78#define PON_HP (1 << 13) /* Power-on Headphone driver */ 79#define PON_HP (1 << 13) /* Power-on Headphone driver */
79#define PON_DAC (1 << 10) /* Power-on DAC */ 80#define PON_DAC (1 << 10) /* Power-on DAC */
80#define PON_BIAS (1 << 8) /* Power-on BIAS for ADC, AVC, FSDAC */ 81#define PON_BIAS (1 << 8) /* Power-on BIAS for ADC, AVC, FSDAC */
81#define EN_AVC (1 << 7) /* Enable analog mixer */ 82#define EN_AVC (1 << 7) /* Enable analog mixer */
82#define PON_AVC (1 << 6) /* Power-on analog mixer */ 83#define PON_AVC (1 << 6) /* Power-on analog mixer */
83#define PON_LNA (1 << 4) /* Power-on LNA & SDC */ 84#define PON_LNA (1 << 4) /* Power-on LNA & SDC */
84#define PON_PGAL (1 << 3) /* Power-on PGA left */ 85#define PON_PGAL (1 << 3) /* Power-on PGA left */
85#define PON_ADCL (1 << 2) /* Power-on ADC left */ 86#define PON_ADCL (1 << 2) /* Power-on ADC left */
86#define PON_PGAR (1 << 1) /* Power-on PGA right */ 87#define PON_PGAR (1 << 1) /* Power-on PGA right */
87#define PON_ADCR (1 << 0) /* Power-on ADC right */ 88#define PON_ADCR (1 << 0) /* Power-on ADC right */
88 89
89 90
90/* REG_AMIX: Analog mixer */ 91/* REG_AMIX: Analog mixer */
91#define REG_AMIX 0x03 92#define REG_AMIX 0x03
92#define AMIX_LEFT(x) (((x) & 0x3f) << 8) 93#define AMIX_LEFT(x) (((x) & 0x3f) << 8)
93#define AMIX_RIGHT(x) (((x) & 0x3f) << 0) 94#define AMIX_RIGHT(x) (((x) & 0x3f) << 0)
94 95
95/* REG_HP: Headphone amp */ 96/* REG_HP: Headphone amp */
96#define REG_HP 0x04 97#define REG_HP 0x04
97 98
98/* REG_MV: Master Volume control */ 99/* REG_MV: Master Volume control */
99#define REG_MASTER_VOL 0x10 100#define REG_MASTER_VOL 0x10
100 101
101#define MASTER_VOL_RIGHT(x) (((x) & 0xff) << 8) 102#define MASTER_VOL_RIGHT(x) (((x) & 0xff) << 8)
102#define MASTER_VOL_LEFT(x) (((x) & 0xff) << 0) 103#define MASTER_VOL_LEFT(x) (((x) & 0xff) << 0)
103 104
104/* REG_MIX: Mixer volume control */ 105/* REG_MIX: Mixer volume control */
105/* Channel 1 is from digital data from I2S */ 106/* Channel 1 is from digital data from I2S */
106/* Channel 2 is from decimation filter */ 107/* Channel 2 is from decimation filter */
107 108
108#define REG_MIX_VOL 0x11 109#define REG_MIX_VOL 0x11
109#define MIX_VOL_CHANNEL_1(x) (((x) & 0xff) << 0) 110#define MIX_VOL_CH_1(x) (((x) & 0xff) << 0)
110#define MIX_VOL_CHANNEL_2(x) (((x) & 0xff) << 8) 111#define MIX_VOL_CH_2(x) (((x) & 0xff) << 8)
111 112
112/* REG_EQ: Bass boost and tremble */ 113/* REG_EQ: Bass boost and tremble */
113#define REG_EQ 0x12 114#define REG_EQ 0x12
115#define EQ_MODE_FLAG (0 << 14)
116#define EQ_MODE_MIN (1 << 14)
117#define EQ_MODE_MAX (3 << 14)
118#define BASSL(x) (((x) & 0xF) << 8)
119#define BASSR(x) (((x) & 0xF) << 0)
120#define TREBLEL(x) (((x) & 0x3) << 12)
121#define TREBLER(x) (((x) & 0x3) << 4)
122#define BASS_MASK 0x0F0F
123#define TREBLE_MASK 0x3030
124
125/* REG_MUTE: Master Mute, silence detector and oversampling */
126#define REG_MUTE 0x13
127#define MUTE_MASTER (1 << 14) /* Master Mute (soft) */
128#define MIX_MODE(x) ((x) << 12) /* Mixer mode: See table 48 */
129#define MUTE_CH2 (1 << 11) /* Channel 2 mute */
130#define MUTE_CH1 (1 << 3) /* Channel 1 mute */
114 131
115/* REG_MUTE: Master Mute */
116#define REG_MUTE 0x13
117#define MUTE_MASTER (1 << 14) /* Master Mute (soft) */
118#define MUTE_CH2 (1 << 11) /* Channel 2 mute */
119#define MUTE_CH1 (1 << 3) /* Channel 1 mute */
120 132
121/* REG_MIX_CTL: Mixer, silence detector and oversampling settings */ 133/* REG_MIX_CTL: Mixer, silence detector and oversampling settings */
122#define REG_MIX_CTL 0x14 134#define REG_MIX_CTL 0x14
123#define MIX_CTL_MIX_POS (1 << 13) 135#define MIX_CTL_MIX_POS (1 << 13)
124#define MIX_CTL_MIX (1 << 12) 136#define MIX_CTL_MIX (1 << 12)
125 137
126/* REG_DEC_VOL: Decimator Volume control */ 138/* REG_DEC_VOL: Decimator (ADC) volume control */
127#define REG_DEC_VOL 0x20 139#define REG_DEC_VOL 0x20
140#define DEC_VOLL(x) (((x) & 0xff) << 8)
141#define DEC_VOLR(x) (((x) & 0xff) << 0)
128 142
129/* REG_PGA: PGA settings and mute */ 143/* REG_PGA: PGA settings and mute */
130#define REG_PGA 0x21 144#define REG_PGA 0x21
131#define MUTE_ADC (1 << 15) /* Mute ADC */ 145#define MUTE_ADC (1 << 15) /* Mute ADC */
146#define PGA_GAINR(x) (((x) & 0xF) << 8)
147#define PGA_GAINL(x) (((x) & 0xF) << 0)
148#define PGA_GAIN_MASK 0x0F0F
132 149
133/* REG_ADC: */ 150/* REG_ADC: */
134#define REG_ADC 0x22 151#define REG_ADC 0x22
152#define SEL_LNA (1 << 3)
153#define SEL_MIC (1 << 2)
154#define SKIP_DCFIL (1 << 1)
155#define EN_DCFIL (1 << 0)
156#define VGA_GAIN(x) (((x) & 0xF) << 8)
157#define VGA_GAIN_MASK 0x0F00
135 158
136/* REG_AGC: Attack / Gain */ 159/* REG_AGC: Attack / Gain */
137#define REG_AGC 0x23 160#define REG_AGC 0x23
138#define SKIP_DCFIL ( 1 << 1)
139 161
140#endif /* _UDA_1380_H */ 162#endif /* _UDA_1380_H */
diff --git a/firmware/sound.c b/firmware/sound.c
index c8347f297b..7558a3349b 100644
--- a/firmware/sound.c
+++ b/firmware/sound.c
@@ -498,6 +498,8 @@ void sound_set(int setting, int value)
498#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) 498#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
499 tmp = ((value * 8) & 0xff) << 8; 499 tmp = ((value * 8) & 0xff) << 8;
500 mas_codec_writereg(0x14, tmp & 0xff00); 500 mas_codec_writereg(0x14, tmp & 0xff00);
501#elif defined(HAVE_UDA1380)
502 uda1380_set_bass(value >> 1);
501#elif CONFIG_HWCODEC == MAS3507D 503#elif CONFIG_HWCODEC == MAS3507D
502 mas_writereg(MAS_REG_KBASS, bass_table[value+15]); 504 mas_writereg(MAS_REG_KBASS, bass_table[value+15]);
503 current_bass = value * 10; 505 current_bass = value * 10;
@@ -509,6 +511,8 @@ void sound_set(int setting, int value)
509#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) 511#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
510 tmp = ((value * 8) & 0xff) << 8; 512 tmp = ((value * 8) & 0xff) << 8;
511 mas_codec_writereg(0x15, tmp & 0xff00); 513 mas_codec_writereg(0x15, tmp & 0xff00);
514#elif defined(HAVE_UDA1380)
515 uda1380_set_treble(value >> 1);
512#elif CONFIG_HWCODEC == MAS3507D 516#elif CONFIG_HWCODEC == MAS3507D
513 mas_writereg(MAS_REG_KTREBLE, treble_table[value+15]); 517 mas_writereg(MAS_REG_KTREBLE, treble_table[value+15]);
514 current_treble = value * 10; 518 current_treble = value * 10;