Fix playlist catalog directory manual spelling
[maemo-rb.git] / firmware / drivers / audio / uda1341.c
blob6b38353afe59b184a34ab5a87227cd94d8c458d6
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: uda1380.c 21975 2009-07-19 22:45:32Z bertrik $
10 * Copyright (C) 2009 by Bob Cousins
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 ****************************************************************************/
21 #include <string.h>
23 #include "config.h"
24 #include "logf.h"
25 #include "system.h"
26 #include "audio.h"
27 #include "debug.h"
29 #include "audiohw.h"
32 const struct sound_settings_info audiohw_settings[] = {
33 [SOUND_VOLUME] = {"dB", 0, 1, -84, 0, -25},
34 [SOUND_BASS] = {"dB", 0, 2, 0, 24, 0},
35 [SOUND_TREBLE] = {"dB", 0, 2, 0, 6, 0},
36 [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, /* not used */
37 [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, /* not used */
38 [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, /* not used */
39 #ifdef HAVE_RECORDING
40 [SOUND_LEFT_GAIN] = {"dB", 1, 1,-128, 96, 0},
41 [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-128, 96, 0},
42 [SOUND_MIC_GAIN] = {"dB", 1, 1,-128, 108, 16},
43 #endif
46 /* convert tenth of dB volume (-600..0) to master volume register value */
47 int tenthdb2master(int db)
49 if (db < -600)
50 return 63;
51 else /* 1 dB steps */
52 return -(db / 10) + 1;
55 static unsigned short uda_regs[NUM_REG_ID];
57 /****************************************************************************/
59 /* ------------------------------------------------- */
60 /* Local functions and variables */
61 /* ------------------------------------------------- */
63 /* Generic L3 functions */
65 #define L3PORT GPBDAT
66 #define L3MODE (1 << 2)
67 #define L3DATA (1 << 3)
68 #define L3CLOCK (1 << 4)
70 static void l3_init (void)
72 L3PORT |= L3MODE | L3CLOCK;
73 L3PORT &= ~L3DATA;
75 S3C2440_GPIO_CONFIG (GPBCON, 2, GPIO_OUTPUT); /* L3 MODE */
76 S3C2440_GPIO_CONFIG (GPBCON, 3, GPIO_OUTPUT); /* L3 DATA */
77 S3C2440_GPIO_CONFIG (GPBCON, 4, GPIO_OUTPUT); /* L3 CLOCK */
79 S3C2440_GPIO_PULLUP (GPBUP, 2, GPIO_PULLUP_DISABLE);
80 S3C2440_GPIO_PULLUP (GPBUP, 3, GPIO_PULLUP_DISABLE);
81 S3C2440_GPIO_PULLUP (GPBUP, 4, GPIO_PULLUP_DISABLE);
84 static void bit_delay (void)
86 volatile int j;
87 for (j=0; j<5; j++)
91 static void l3_write_byte (unsigned char data, bool address_mode)
93 int bit;
95 L3PORT |= L3CLOCK;
96 if (address_mode)
97 L3PORT &= ~L3MODE;
98 else
99 L3PORT |= L3MODE;
100 bit_delay();
102 for (bit=0; bit < 8; bit++)
104 if (data & 1)
106 L3PORT |= L3DATA;
108 else
110 L3PORT &= ~L3DATA;
112 L3PORT &= ~L3CLOCK;
113 bit_delay();
114 L3PORT |= L3CLOCK;
115 bit_delay();
117 data >>= 1;
120 if (address_mode)
121 L3PORT |= L3MODE;
122 else
123 L3PORT &= ~L3MODE;
124 bit_delay();
127 static void l3_write_addr (unsigned char addr)
129 /* write address byte */
130 l3_write_byte (addr, true);
133 static void l3_write_data (unsigned char data)
135 /* write data byte */
136 l3_write_byte (data, false);
139 /****************************************************************************/
141 /* UDA1341 access functions */
143 static int udacodec_write(unsigned char reg, unsigned short value)
145 l3_write_addr (UDA1341_ADDR | reg);
146 l3_write_data (value & 0xff);
147 return 0;
150 static void udacodec_reset(void)
152 /* uda reset */
153 l3_init();
155 udacodec_write (UDA_REG_STATUS, UDA_STATUS_0 | UDA_RESET | UDA_SYSCLK_256FS |
156 I2S_IFMT_IIS);
157 udacodec_write (UDA_REG_STATUS, UDA_STATUS_0 | UDA_SYSCLK_256FS | I2S_IFMT_IIS);
158 udacodec_write (UDA_REG_STATUS, UDA_STATUS_1 | UDA_POWER_DAC_ON);
160 uda_regs[UDA_REG_ID_CTRL2] = UDA_PEAK_DETECT_POS_AFTER |
161 UDA_DE_EMPHASIS_NONE | UDA_MUTE_OFF | UDA_MODE_SWITCH_FLAT;
165 /****************************************************************************/
167 /* Audio API functions */
169 /* This table must match the table in pcm-xxxx.c if using Master mode */
170 /* [reserved, master clock rate] */
171 static const unsigned char uda_freq_parms[HW_NUM_FREQ][2] =
173 [HW_FREQ_44] = { 0, UDA_SYSCLK_384FS },
174 [HW_FREQ_22] = { 0, UDA_SYSCLK_256FS },
175 [HW_FREQ_11] = { 0, UDA_SYSCLK_256FS },
178 void audiohw_init(void)
180 udacodec_reset();
182 audiohw_set_bass (0);
183 audiohw_set_treble (0);
184 audiohw_set_master_vol (26, 26); /* -25 dB */
187 void audiohw_postinit(void)
191 void audiohw_close(void)
193 /* DAC, ADC off */
194 udacodec_write (UDA_REG_STATUS, UDA_STATUS_1 | 0);
197 void audiohw_set_bass(int value)
199 uda_regs [UDA_REG_ID_CTRL1] &= UDA_BASS_BOOST (UDA_BASS_BOOST_MASK);
200 uda_regs [UDA_REG_ID_CTRL1] |= UDA_BASS_BOOST (value & UDA_BASS_BOOST_MASK);
202 udacodec_write (UDA_REG_DATA0, UDA_DATA_CTRL1 | uda_regs [UDA_REG_ID_CTRL1] );
205 void audiohw_set_treble(int value)
207 uda_regs [UDA_REG_ID_CTRL1] &= UDA_TREBLE (UDA_TREBLE_MASK);
208 uda_regs [UDA_REG_ID_CTRL1] |= UDA_TREBLE (value & UDA_TREBLE_MASK);
210 udacodec_write (UDA_REG_DATA0, UDA_DATA_CTRL1 | uda_regs [UDA_REG_ID_CTRL1] );
213 /*static void audiohw_mute(bool mute)
215 if (mute)
216 uda_regs [UDA_REG_ID_CTRL2] |= UDA_MUTE_ON;
217 else
218 uda_regs [UDA_REG_ID_CTRL2] &= ~UDA_MUTE_ON;
220 udacodec_write (UDA_REG_DATA0, UDA_DATA_CTRL2 | uda_regs [UDA_REG_ID_CTRL2] );
224 #ifdef AUDIOHW_HAVE_PRESCALER
225 void audiohw_set_prescaler(int val)
227 (void)val;
229 #endif /* AUDIOHW_HAVE_PRESCALER */
232 * Sets left and right master volume (1(max) to 62(muted))
234 void audiohw_set_master_vol(int vol_l, int vol_r)
236 uda_regs[UDA_REG_ID_CTRL0] = (vol_l + vol_r) / 2;
237 udacodec_write (UDA_REG_DATA0, UDA_DATA_CTRL0 | uda_regs[UDA_REG_ID_CTRL0]);
240 void audiohw_set_frequency(int fsel)
242 if ((unsigned)fsel >= HW_NUM_FREQ)
243 fsel = HW_FREQ_DEFAULT;
245 uda_regs[UDA_REG_ID_STATUS_0] = I2S_IFMT_IIS | uda_freq_parms[fsel][1];
247 udacodec_write (UDA_REG_STATUS, UDA_STATUS_0 | uda_regs[UDA_REG_ID_STATUS_0]);