~ubuntu-branches/ubuntu/karmic/linux-mvl-dove/karmic-proposed

« back to all changes in this revision

Viewing changes to arch/arm/plat-orion/mv_hal_drivers/mv_drivers_lsp/mv_audio/cs42l51-hal.c

  • Committer: Bazaar Package Importer
  • Author(s): Stefan Bader
  • Date: 2010-03-10 22:24:12 UTC
  • mto: (15.1.2 karmic-security)
  • mto: This revision was merged to the branch mainline in revision 18.
  • Revision ID: james.westby@ubuntu.com-20100310222412-k86m3r53jw0je7x1
Tags: upstream-2.6.31
ImportĀ upstreamĀ versionĀ 2.6.31

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *
3
 
 *      Marvell Orion Alsa Sound driver
4
 
 *
5
 
 *      Author: Maen Suleiman
6
 
 *      Copyright (C) 2008 Marvell Ltd.
7
 
 *
8
 
 *
9
 
 * This program is free software; you can redistribute it and/or modify
10
 
 * it under the terms of the GNU General Public License version 2 as
11
 
 * published by the Free Software Foundation.
12
 
 *
13
 
 */
14
 
#include <linux/ioport.h>
15
 
#include <linux/interrupt.h>
16
 
#include <linux/platform_device.h>
17
 
#include <linux/init.h>
18
 
#include <linux/slab.h>
19
 
#include <linux/version.h>
20
 
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)
21
 
#include <sound/driver.h>
22
 
#endif
23
 
#include <sound/core.h>
24
 
#include <sound/initval.h>
25
 
#include <sound/control.h>
26
 
#include <sound/pcm.h>
27
 
#include <sound/asoundef.h>
28
 
#include <sound/asound.h>
29
 
 
30
 
#include "twsi/mvTwsi.h"
31
 
#include "audio/dac/mvCLAudioCodec.h"
32
 
#include "boardEnv/mvBoardEnvLib.h"
33
 
 
34
 
 
35
 
 
36
 
/*
37
 
 * Initialize the audio decoder.
38
 
 */
39
 
int
40
 
cs42l51_init(MV_U8 port)
41
 
{
42
 
    MV_AUDIO_CODEC_DEV codec_params;
43
 
    unsigned char reg_data;
44
 
    
45
 
    codec_params.chanNum = mvBoardA2DTwsiChanNumGet(port);
46
 
    codec_params.ADCMode = MV_I2S_MODE;
47
 
    codec_params.DACDigitalIFFormat = MV_I2S_UP_TO_24_BIT;
48
 
    codec_params.twsiSlave.moreThen256 = MV_FALSE;
49
 
    codec_params.twsiSlave.validOffset = MV_TRUE;
50
 
    codec_params.twsiSlave.slaveAddr.address = mvBoardA2DTwsiAddrGet(port);
51
 
    codec_params.twsiSlave.slaveAddr.type = mvBoardA2DTwsiAddrTypeGet(port);
52
 
    if(mvCLAudioCodecInit(&codec_params) == MV_FALSE)
53
 
    {
54
 
        printk("Error - Cannot initialize audio decoder.at address =0x%x",
55
 
                                codec_params.twsiSlave.slaveAddr.address);
56
 
        return -1;
57
 
    }
58
 
 
59
 
#ifdef CONFIG_MACH_DOVE_RD_AVNG
60
 
    /* Default Gain */
61
 
    mvCLAudioCodecRegSet(&codec_params,0x8,
62
 
                         mvCLAudioCodecRegGet(&codec_params,0x8)|0xE0);
63
 
#endif
64
 
 
65
 
    /* Use the signal processor.               */
66
 
    mvCLAudioCodecRegSet(&codec_params,0x9,0x40);
67
 
    
68
 
    /* Unmute PCM-A & PCM-B and set default      */
69
 
    mvCLAudioCodecRegSet(&codec_params,0x10,0x10);
70
 
    mvCLAudioCodecRegSet(&codec_params,0x11,0x10);
71
 
 
72
 
    /* default for AOUTx*/
73
 
    mvCLAudioCodecRegSet(&codec_params,0x16,0x05);
74
 
    mvCLAudioCodecRegSet(&codec_params,0x17,0x05);
75
 
 
76
 
    /* swap channels */
77
 
    mvCLAudioCodecRegSet(&codec_params,0x18,0xff);
78
 
    if (0) {
79
 
            int i;
80
 
            for (i=1; i<= 0x21 ; i++) {
81
 
                    reg_data = mvCLAudioCodecRegGet(&codec_params,i);
82
 
                    printk("CLS reg=0x%02x val=0x%02x\n",i,reg_data);
83
 
            }
84
 
            
85
 
    }
86
 
    
87
 
    return 0;
88
 
}
89
 
 
90
 
#define MVAUD_NUM_VOLUME_STEPS  (40)
91
 
static MV_U8 auddec_volume_mapping[MVAUD_NUM_VOLUME_STEPS] =
92
 
{
93
 
        0x19,   0xB2,   0xB7,   0xBD,   0xC3,   0xC9,   0xCF,   0xD5,
94
 
        0xD8,   0xE1,   0xE7,   0xED,   0xF3,   0xF9,   0xFF,   0x00,   
95
 
        0x01,   0x02,   0x03,   0x04,   0x05,   0x06,   0x07,   0x08,   
96
 
        0x09,   0x0A,   0x0B,   0x0C,   0x0D,   0x0E,   0x0F,   0x10,   
97
 
        0x11,   0x12,   0x13,   0x14,   0x15,   0x16,   0x17,   0x18
98
 
};
99
 
 
100
 
 
101
 
/*
102
 
 * Get the audio decoder volume for both channels.
103
 
 * 0 is lowest volume, MVAUD_NUM_VOLUME_STEPS-1 is the highest volume.
104
 
 */
105
 
 
106
 
void
107
 
cs42l51_vol_get(MV_U8 port, MV_U8 *vol_list)
108
 
{
109
 
    MV_AUDIO_CODEC_DEV  codec_params;
110
 
    MV_U8   reg_data;
111
 
    MV_U32  i;
112
 
    MV_U32  vol_idx;
113
 
 
114
 
    codec_params.chanNum = mvBoardA2DTwsiChanNumGet(port);
115
 
    codec_params.ADCMode = MV_I2S_MODE;
116
 
    codec_params.DACDigitalIFFormat = MV_I2S_UP_TO_24_BIT;
117
 
    codec_params.twsiSlave.moreThen256 = MV_FALSE;
118
 
    codec_params.twsiSlave.validOffset = MV_TRUE;
119
 
        codec_params.twsiSlave.slaveAddr.address = mvBoardA2DTwsiAddrGet(port);
120
 
        codec_params.twsiSlave.slaveAddr.type = mvBoardA2DTwsiAddrTypeGet(port);
121
 
 
122
 
 
123
 
    for(vol_idx = 0; vol_idx < 2; vol_idx++)
124
 
    {
125
 
        reg_data = mvCLAudioCodecRegGet(&codec_params,0x16 + vol_idx);
126
 
 
127
 
       /*printk("\tVolume was get: 0x%x.\n",
128
 
                                reg_data);*/
129
 
 
130
 
        /* Look for the index that mapps to this dB value.  */
131
 
        for(i = 0; i < MVAUD_NUM_VOLUME_STEPS; i++)
132
 
        {
133
 
                if (reg_data == auddec_volume_mapping[i])
134
 
                        break;
135
 
                if (( auddec_volume_mapping[i] > auddec_volume_mapping[MVAUD_NUM_VOLUME_STEPS-1]) 
136
 
                                        && (reg_data > auddec_volume_mapping[i]) 
137
 
                                        && (reg_data < auddec_volume_mapping[i+1]))
138
 
                        break;
139
 
                 
140
 
        }
141
 
 
142
 
        vol_list[vol_idx] = i;
143
 
       /*printk("\tvol_list[%d] = %d.\n",vol_idx,
144
 
                                vol_list[vol_idx]);*/
145
 
 
146
 
    }
147
 
 
148
 
    return;
149
 
}
150
 
 
151
 
 
152
 
/*
153
 
 * Set the audio decoder volume for both channels.
154
 
 * 0 is lowest volume, MVAUD_NUM_VOLUME_STEPS-1 is the highest volume.
155
 
 */
156
 
void
157
 
cs42l51_vol_set(MV_U8 port, MV_U8 *vol_list)
158
 
{
159
 
    MV_AUDIO_CODEC_DEV  codec_params;
160
 
    MV_U32  vol_idx;
161
 
 
162
 
    codec_params.chanNum = mvBoardA2DTwsiChanNumGet(port);
163
 
    codec_params.ADCMode = MV_I2S_MODE;
164
 
    codec_params.DACDigitalIFFormat = MV_I2S_UP_TO_24_BIT;
165
 
    codec_params.twsiSlave.moreThen256 = MV_FALSE;
166
 
    codec_params.twsiSlave.validOffset = MV_TRUE;
167
 
    codec_params.twsiSlave.slaveAddr.address = mvBoardA2DTwsiAddrGet(port);
168
 
    codec_params.twsiSlave.slaveAddr.type = mvBoardA2DTwsiAddrTypeGet(port);
169
 
 
170
 
   
171
 
    for(vol_idx = 0; vol_idx < 2; vol_idx++)
172
 
    {
173
 
        /*printk("\tvol_list[%d] = %d.\n",vol_idx,
174
 
                                vol_list[vol_idx]);*/
175
 
 
176
 
        if(vol_list[vol_idx] >= MVAUD_NUM_VOLUME_STEPS)
177
 
                vol_list[vol_idx] = MVAUD_NUM_VOLUME_STEPS -1;
178
 
 
179
 
        mvCLAudioCodecRegSet(&codec_params,0x16 + vol_idx,
180
 
                             auddec_volume_mapping[vol_list[vol_idx]]);
181
 
 
182
 
        /*printk("\tVolume was set to 0x%x.\n",
183
 
                                auddec_volume_mapping[vol_list[vol_idx]]);*/
184
 
    }
185
 
 
186
 
    return;
187
 
}
188
 
 
189
 
#ifdef CONFIG_MACH_DOVE_RD_AVNG
190
 
 
191
 
#define lineIn          0
192
 
#define internalMic     1
193
 
#define phoneIn         2
194
 
 
195
 
/*
196
 
 * Set the audio codec's ADC path.
197
 
 */
198
 
void
199
 
cs42l51_input_select(MV_U8 port, int type)
200
 
{
201
 
    MV_AUDIO_CODEC_DEV codec_params;
202
 
 
203
 
    codec_params.chanNum = mvBoardA2DTwsiChanNumGet(port);
204
 
    codec_params.ADCMode = MV_I2S_MODE;
205
 
    codec_params.DACDigitalIFFormat = MV_I2S_UP_TO_24_BIT;
206
 
    codec_params.twsiSlave.moreThen256 = MV_FALSE;
207
 
    codec_params.twsiSlave.validOffset = MV_TRUE;
208
 
    codec_params.twsiSlave.slaveAddr.address = mvBoardA2DTwsiAddrGet(port);
209
 
    codec_params.twsiSlave.slaveAddr.type = mvBoardA2DTwsiAddrTypeGet(port);
210
 
 
211
 
    if (type == internalMic) {
212
 
        /* Set PDN bit first */
213
 
        mvCLAudioCodecRegSet(&codec_params,0x02,0x01);
214
 
        /* Wait until codec is in standby mode */
215
 
        mdelay(10);
216
 
        /* Enable PDN_PGAB and PDN_ADCB also */
217
 
        mvCLAudioCodecRegSet(&codec_params,0x02,0x15);
218
 
        /* Enable PDN_MICB and disable PDN_MICA and PDN_MICBIAS */
219
 
        mvCLAudioCodecRegSet(&codec_params,0x03,0xA8);
220
 
        /* MICBIAS_SEL set to AIN2B, disable MICB_BOOST and enable MICA_BOOST */
221
 
        mvCLAudioCodecRegSet(&codec_params,0x05,0x11);
222
 
        /* Set AIN3A->Pre Amp->PGAA and AIN1B->PGAB */
223
 
        mvCLAudioCodecRegSet(&codec_params,0x07,0x30);
224
 
        /* Disable PDN bit last */
225
 
        mvCLAudioCodecRegSet(&codec_params,0x02,0x14);
226
 
    } else if (type == phoneIn) {
227
 
        /* Set PDN bit first */
228
 
        mvCLAudioCodecRegSet(&codec_params,0x02,0x01);
229
 
        /* Wait until codec is in standby mode */
230
 
        mdelay(10);
231
 
        /* Enable PDN_PGAA and PDN_ADCA also */
232
 
        mvCLAudioCodecRegSet(&codec_params,0x02,0x0B);
233
 
        /* Enable PDN_MICA and disable PDN_MICB and PDN_MICBIAS */
234
 
        mvCLAudioCodecRegSet(&codec_params,0x03,0xA4);
235
 
        /* MICBIAS_SEL set to AIN2B, disable MICA_BOOST and enable MICB_BOOST */
236
 
        mvCLAudioCodecRegSet(&codec_params,0x05,0x12);
237
 
        /* Set AIN3B->Pre Amp->PGAB and AIN1A->PGAA */
238
 
        mvCLAudioCodecRegSet(&codec_params,0x07,0xC0);
239
 
        /* Disable PDN bit last */
240
 
        mvCLAudioCodecRegSet(&codec_params,0x02,0x0A);
241
 
    } else {
242
 
        /* default to LineIn */
243
 
        /* Set PDN bit first */
244
 
        mvCLAudioCodecRegSet(&codec_params,0x02,0x01);
245
 
        /* Wait until codec is in standby mode */
246
 
        mdelay(10);
247
 
        /* Enable PDN_MICB, PDN_MICA, and PDN_MICBIAS */
248
 
        mvCLAudioCodecRegSet(&codec_params,0x03,0xAE);
249
 
        /* MICBIAS_SEL set to AIN3B, disable both MICB_BOOST and MICA_BOOST */
250
 
        mvCLAudioCodecRegSet(&codec_params,0x05,0x0);
251
 
        /* Set AIN1A->PGAA and AIN1B->PGAB */
252
 
        mvCLAudioCodecRegSet(&codec_params,0x07,0x0);
253
 
        /* Disable PDN bit last */
254
 
        mvCLAudioCodecRegSet(&codec_params,0x02,0x0);
255
 
    }
256
 
 
257
 
    if (0) {
258
 
            int i;
259
 
            MV_U8 reg_data;
260
 
 
261
 
            for (i=1; i<= 0x21 ; i++) {
262
 
                    reg_data = mvCLAudioCodecRegGet(&codec_params,i);
263
 
                    printk("CLS reg=0x%02x val=0x%02x\n",i,reg_data);
264
 
            }
265
 
    }
266
 
}
267
 
#endif