1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2005 by Christian Gmeiner
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.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
27 #if CONFIG_I2C == I2C_COLDFIRE
28 #include "i2c-coldfire.h"
29 #elif CONFIG_I2C == I2C_DM320
30 #include "i2c-dm320.h"
34 const struct sound_settings_info audiohw_settings
[] = {
35 [SOUND_VOLUME
] = {"dB", 0, 1, -73, 6, -20},
36 /* HAVE_SW_TONE_CONTROLS */
37 [SOUND_BASS
] = {"dB", 0, 1, -24, 24, 0},
38 [SOUND_TREBLE
] = {"dB", 0, 1, -24, 24, 0},
39 [SOUND_BALANCE
] = {"%", 0, 1,-100, 100, 0},
40 [SOUND_CHANNELS
] = {"", 0, 1, 0, 5, 0},
41 [SOUND_STEREO_WIDTH
] = {"%", 0, 5, 0, 250, 100},
43 [SOUND_LEFT_GAIN
] = {"dB", 1, 1, 0, 31, 23},
44 [SOUND_RIGHT_GAIN
] = {"dB", 1, 1, 0, 31, 23},
45 [SOUND_MIC_GAIN
] = {"dB", 1, 1, 0, 1, 1},
49 /* convert tenth of dB volume (-840..0) to master volume register value */
50 int tenthdb2master(int db
)
52 /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */
53 /* 1111111 == +6dB (0x7f) */
54 /* 1111001 == 0dB (0x79) */
55 /* 0110000 == -73dB (0x30) */
56 /* 0101111 == mute (0x2f) */
58 if (db
< VOLUME_MIN
) {
61 return((db
/10)+73+0x30);
65 /* local functions and definations */
67 #define TLV320_ADDR 0x34
69 #define TLV320_ADDR 0x1A
78 /* Shadow registers */
79 unsigned tlv320_regs
[0xf];
81 static void tlv320_write_reg(unsigned reg
, unsigned value
)
83 unsigned char data
[2];
85 /* The register address is the high 7 bits and the data the low 9 bits */
86 data
[0] = (reg
<< 1) | ((value
>> 8) & 1);
89 #if CONFIG_I2C == I2C_COLDFIRE
90 if (i2c_write(I2C_IFACE_0
, TLV320_ADDR
, data
, 2) != 2)
91 #elif CONFIG_I2C == I2C_DM320
92 if (i2c_write(TLV320_ADDR
, data
, 2) != 0)
94 #warning Implement tlv320_write_reg()
97 logf("tlv320 error reg=0x%x", reg
);
101 tlv320_regs
[reg
] = value
;
104 static void audiohw_mute(bool mute
)
106 unsigned value_dap
= tlv320_regs
[REG_DAP
];
107 unsigned value_l
, value_r
;
111 value_l
= LHV_LHV(HEADPHONE_MUTE
);
112 value_r
= RHV_RHV(HEADPHONE_MUTE
);
113 value_dap
|= DAP_DACM
;
117 value_l
= LHV_LHV(tlv320
.vol_l
);
118 value_r
= RHV_RHV(tlv320
.vol_r
);
119 if (value_l
> HEADPHONE_MUTE
|| value_r
> HEADPHONE_MUTE
)
120 value_dap
&= ~DAP_DACM
;
123 tlv320_write_reg(REG_LHV
, LHV_LZC
| value_l
);
124 tlv320_write_reg(REG_RHV
, RHV_RZC
| value_r
);
125 tlv320_write_reg(REG_DAP
, value_dap
);
128 /* public functions */
131 * Init our tlv with default values
133 void audiohw_init(void)
136 memset(tlv320_regs
, 0, sizeof(tlv320_regs
));
138 /* Initialize all registers */
140 /* All ON except OUT, ADC, MIC and LINE */
141 tlv320_write_reg(REG_PC
, PC_OUT
| PC_ADC
| PC_MIC
| PC_LINE
);
142 #ifdef HAVE_RECORDING
143 audiohw_set_recvol(0, 0, AUDIO_GAIN_MIC
);
144 audiohw_set_recvol(0, 0, AUDIO_GAIN_LINEIN
);
147 tlv320_write_reg(REG_AAP
, AAP_DAC
| AAP_MICM
);
148 tlv320_write_reg(REG_DAP
, 0x00); /* No deemphasis */
150 tlv320_write_reg(REG_DAIF
, DAIF_IWL_16
| DAIF_FOR_I2S
);
152 tlv320_write_reg(REG_DAIF
, DAIF_IWL_32
| DAIF_FOR_DSP
);
154 tlv320_write_reg(REG_DIA
, DIA_ACT
);
155 audiohw_set_frequency(-1); /* default */
161 void audiohw_postinit(void)
163 /* All ON except ADC, MIC and LINE */
165 tlv320_write_reg(REG_PC
, PC_ADC
| PC_MIC
| PC_LINE
);
171 * Sets internal sample rate for DAC and ADC relative to MCLK
172 * Selection for frequency:
174 * 11025: 0 = MCLK/2 MCLK/2 SCLK, LRCK: Audio Clk / 16
175 * 22050: 0 = MCLK/2 MCLK SCLK, LRCK: Audio Clk / 8
176 * 44100: 1 = MCLK MCLK SCLK, LRCK: Audio Clk / 4 (default)
177 * 88200: 2 = MCLK*2 MCLK SCLK, LRCK: Audio Clk / 2
179 void audiohw_set_frequency(int fsel
)
181 /* All rates available for 11.2896MHz besides 8.021 */
182 static const unsigned char values_src
[HW_NUM_FREQ
] =
184 HW_HAVE_11_([HW_FREQ_11
] = (0x8 << 2) | SRC_CLKIN
,)
185 HW_HAVE_22_([HW_FREQ_22
] = (0x8 << 2) | SRC_CLKIN
,)
186 HW_HAVE_44_([HW_FREQ_44
] = (0x8 << 2),)
187 HW_HAVE_88_([HW_FREQ_88
] = (0xf << 2),)
190 unsigned value_dap
, value_pc
;
192 if ((unsigned)fsel
>= HW_NUM_FREQ
)
193 fsel
= HW_FREQ_DEFAULT
;
195 /* Temporarily turn off the DAC and ADC before switching sample
196 rates or they don't choose their filters correctly */
197 value_dap
= tlv320_regs
[REG_DAP
];
198 value_pc
= tlv320_regs
[REG_PC
];
200 tlv320_write_reg(REG_DAP
, value_dap
| DAP_DACM
);
201 tlv320_write_reg(REG_PC
, value_pc
| PC_DAC
| PC_ADC
);
202 tlv320_write_reg(REG_SRC
, values_src
[fsel
]);
203 tlv320_write_reg(REG_PC
, value_pc
| PC_DAC
);
204 tlv320_write_reg(REG_PC
, value_pc
);
205 tlv320_write_reg(REG_DAP
, value_dap
);
209 * Sets left and right headphone volume
211 * Left & Right: 48 .. 121 .. 127 => Volume -73dB (mute) .. +0 dB .. +6 dB
213 void audiohw_set_headphone_vol(int vol_l
, int vol_r
)
215 unsigned value_dap
= tlv320_regs
[REG_DAP
];
216 unsigned value_dap_last
= value_dap
;
217 unsigned value_l
= LHV_LHV(vol_l
);
218 unsigned value_r
= RHV_RHV(vol_r
);
220 /* keep track of current setting */
221 tlv320
.vol_l
= vol_l
;
222 tlv320
.vol_r
= vol_r
;
224 if (value_l
> HEADPHONE_MUTE
|| value_r
> HEADPHONE_MUTE
)
225 value_dap
&= ~DAP_DACM
;
227 value_dap
|= DAP_DACM
;
230 tlv320_write_reg(REG_LHV
, LHV_LZC
| value_l
);
231 tlv320_write_reg(REG_RHV
, RHV_RZC
| value_r
);
232 if (value_dap
!= value_dap_last
)
233 tlv320_write_reg(REG_DAP
, value_dap
);
237 * Set recording volume
239 * Line in : 0 .. 31 => Volume -34.5 .. +12 dB
240 * Mic (left): 0 .. 1 => Volume +0, +20 dB
243 #ifdef HAVE_RECORDING
244 void audiohw_set_recvol(int left
, int right
, int type
)
246 if (type
== AUDIO_GAIN_MIC
)
248 unsigned value_aap
= tlv320_regs
[REG_AAP
];
251 value_aap
|= AAP_MICB
; /* Enable mic boost (20dB) */
253 value_aap
&= ~AAP_MICB
;
255 tlv320_write_reg(REG_AAP
, value_aap
);
257 else if (type
== AUDIO_GAIN_LINEIN
)
259 tlv320_write_reg(REG_LLIV
, LLIV_LIV(left
));
260 tlv320_write_reg(REG_RLIV
, RLIV_RIV(right
));
265 /* Nice shutdown of TLV320 codec */
266 void audiohw_close(void)
271 tlv320_write_reg(REG_PC
, PC_OFF
| PC_CLK
| PC_OSC
| PC_OUT
|
272 PC_DAC
| PC_ADC
| PC_MIC
| PC_LINE
); /* All OFF */
275 #ifdef HAVE_RECORDING
276 void audiohw_enable_recording(bool source_mic
)
278 unsigned value_aap
, value_pc
;
282 /* select MIC and enable mic boost (20 dB) */
283 value_aap
= AAP_DAC
| AAP_INSEL
| AAP_MICB
;
284 value_pc
= PC_LINE
; /* power down LINE */
288 value_aap
= AAP_DAC
| AAP_MICM
;
289 value_pc
= PC_MIC
; /* power down MIC */
292 tlv320_write_reg(REG_PC
, value_pc
);
293 tlv320_write_reg(REG_AAP
, value_aap
);
296 void audiohw_disable_recording(void)
298 unsigned value_pc
= tlv320_regs
[REG_PC
];
299 unsigned value_aap
= tlv320_regs
[REG_AAP
];
301 value_aap
|= AAP_MICM
; /* mute MIC */
302 tlv320_write_reg(REG_PC
, value_aap
);
304 value_pc
|= PC_ADC
| PC_MIC
| PC_LINE
; /* ADC, MIC and LINE off */
305 tlv320_write_reg(REG_PC
, value_pc
);
309 void audiohw_set_monitor(bool enable
)
311 unsigned value_aap
, value_pc
;
315 /* Keep DAC on to allow mixing of voice with analog audio */
316 value_aap
= AAP_DAC
| AAP_BYPASS
| AAP_MICM
;
317 value_pc
= PC_ADC
| PC_MIC
; /* ADC and MIC off */
321 value_aap
= AAP_DAC
| AAP_MICM
;
322 value_pc
= PC_ADC
| PC_MIC
| PC_LINE
; /* ADC, MIC and LINE off */
325 tlv320_write_reg(REG_AAP
, value_aap
);
326 tlv320_write_reg(REG_PC
, value_pc
);