add support for the Simplemachines Sim.One board
[librecmc/librecmc.git] / target / linux / ep93xx / patches-2.6.30 / 010-ep93xx-snd-ac97.patch
1 --- a/arch/arm/mach-ep93xx/include/mach/hardware.h
2 +++ b/arch/arm/mach-ep93xx/include/mach/hardware.h
3 @@ -5,6 +5,7 @@
4  #define __ASM_ARCH_HARDWARE_H
5  
6  #include "ep93xx-regs.h"
7 +#include "regs_ac97.h"
8  
9  #define pcibios_assign_all_busses()    0
10  #include "regs_raster.h"
11 --- /dev/null
12 +++ b/arch/arm/mach-ep93xx/include/mach/regs_ac97.h
13 @@ -0,0 +1,180 @@
14 +/*=============================================================================
15 + *  FILE:           regs_ac97.h
16 + *
17 + *  DESCRIPTION:    Ac'97 Register Definition
18 + *
19 + *  Copyright Cirrus Logic, 2001-2003
20 + *
21 + * This program is free software; you can redistribute it and/or modify
22 + * it under the terms of the GNU General Public License as published by
23 + * the Free Software Foundation; either version 2 of the License, or
24 + * (at your option) any later version.
25 + *
26 + * This program is distributed in the hope that it will be useful,
27 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29 + * GNU General Public License for more details.
30 + *
31 + * You should have received a copy of the GNU General Public License
32 + * along with this program; if not, write to the Free Software
33 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
34 + *=============================================================================
35 + */
36 +#ifndef _REGS_AC97_H_
37 +#define _REGS_AC97_H_
38 +
39 +//-----------------------------------------------------------------------------
40 +// Bit definitionses
41 +//-----------------------------------------------------------------------------
42 +#define AC97ISR_RIS                     8
43 +#define AC97ISR_TIS                     4
44 +#define AC97ISR_RTIS                    2
45 +#define AC97ISR_TCIS                    1
46 +
47 +#define AC97RGIS_SLOT1TXCOMPLETE     0x01
48 +#define AC97RGIS_SLOT2RXVALID        0x02
49 +#define AC97RGIS_GPIOTXCOMPLETE      0x04
50 +#define AC97RGIS_GPIOINTRX           0x08
51 +#define AC97RGIS_RWIS                0x10
52 +#define AC97RGIS_CODECREADY          0x20
53 +#define AC97RGIS_SLOT2TXCOMPLETE     0x40
54 +
55 +#define AC97SR_RXFE                 0x0001
56 +#define AC97SR_TXFE                 0x0002
57 +#define AC97SR_RXFF                 0x0004
58 +#define AC97SR_TXFF                 0x0008
59 +#define AC97SR_TXBUSY               0x0010
60 +#define AC97SR_RXOE                 0x0020
61 +#define AC97SR_TXUE                 0x0040
62 +
63 +#define AC97GSR_IFE                     0x1
64 +#define AC97GSR_LOOP                    0x2
65 +#define AC97GSR_OVERRIDECODECREADY      0x4
66 +
67 +#define AC97RESET_TIMEDRESET            0x1
68 +#define AC97RESET_FORCEDRESET           0x2
69 +#define AC97RESET_EFORCER               0x4
70 +
71 +#define AC97RXCR_REN                    0x1
72 +
73 +#define AC97TXCR_TEN                    0x1
74 +
75 +
76 +//****************************************************************************
77 +//
78 +// The Ac97 Codec registers, accessable through the Ac-link.
79 +// These are not controller registers and are not memory mapped.
80 +// Includes registers specific to CS4202 (Beavis).
81 +//
82 +//****************************************************************************
83 +#define AC97_REG_OFFSET_MASK                0x0000007E
84 +
85 +#define AC97_00_RESET                          0x00000000
86 +#define AC97_02_MASTER_VOL                     0x00000002
87 +#define AC97_04_HEADPHONE_VOL                  0x00000004
88 +#define AC97_06_MONO_VOL                       0x00000006
89 +#define AC97_08_TONE                           0x00000008
90 +#define AC97_0A_PC_BEEP_VOL                    0x0000000A
91 +#define AC97_0C_PHONE_VOL                      0x0000000C
92 +#define AC97_0E_MIC_VOL                        0x0000000E
93 +#define AC97_10_LINE_IN_VOL                    0x00000010
94 +#define AC97_12_CD_VOL                         0x00000012
95 +#define AC97_14_VIDEO_VOL                      0x00000014
96 +#define AC97_16_AUX_VOL                        0x00000016
97 +#define AC97_18_PCM_OUT_VOL                    0x00000018
98 +#define AC97_1A_RECORD_SELECT                  0x0000001A
99 +#define AC97_1C_RECORD_GAIN                    0x0000001C
100 +#define AC97_1E_RESERVED_1E                    0x0000001E
101 +#define AC97_20_GENERAL_PURPOSE                0x00000020
102 +#define AC97_22_3D_CONTROL                     0x00000022
103 +#define AC97_24_MODEM_RATE                     0x00000024
104 +#define AC97_26_POWERDOWN                      0x00000026
105 +#define AC97_28_EXT_AUDIO_ID                   0x00000028
106 +#define AC97_2A_EXT_AUDIO_POWER                0x0000002A
107 +#define AC97_2C_PCM_FRONT_DAC_RATE             0x0000002C
108 +#define AC97_2E_PCM_SURR_DAC_RATE              0x0000002E
109 +#define AC97_30_PCM_LFE_DAC_RATE               0x00000030
110 +#define AC97_32_PCM_LR_ADC_RATE                0x00000032
111 +#define AC97_34_MIC_ADC_RATE                   0x00000034
112 +#define AC97_36_6CH_VOL_C_LFE                  0x00000036
113 +#define AC97_38_6CH_VOL_SURROUND               0x00000038
114 +#define AC97_3A_SPDIF_CONTROL                  0x0000003A
115 +#define AC97_3C_EXT_MODEM_ID                   0x0000003C
116 +#define AC97_3E_EXT_MODEM_POWER                0x0000003E
117 +#define AC97_40_LINE1_CODEC_RATE               0x00000040
118 +#define AC97_42_LINE2_CODEC_RATE               0x00000042
119 +#define AC97_44_HANDSET_CODEC_RATE             0x00000044
120 +#define AC97_46_LINE1_CODEC_LEVEL              0x00000046
121 +#define AC97_48_LINE2_CODEC_LEVEL              0x00000048
122 +#define AC97_4A_HANDSET_CODEC_LEVEL            0x0000004A
123 +#define AC97_4C_GPIO_PIN_CONFIG                0x0000004C
124 +#define AC97_4E_GPIO_PIN_TYPE                  0x0000004E
125 +#define AC97_50_GPIO_PIN_STICKY                0x00000050
126 +#define AC97_52_GPIO_PIN_WAKEUP                0x00000052
127 +#define AC97_54_GPIO_PIN_STATUS                0x00000054
128 +#define AC97_56_RESERVED                       0x00000056
129 +#define AC97_58_RESERVED                       0x00000058
130 +#define AC97_5A_CRYSTAL_REV_N_FAB_ID           0x0000005A
131 +#define AC97_5C_TEST_AND_MISC_CTRL             0x0000005C
132 +#define AC97_5E_AC_MODE                        0x0000005E
133 +#define AC97_60_MISC_CRYSTAL_CONTROL           0x00000060
134 +#define AC97_62_VENDOR_RESERVED                0x00000062
135 +#define AC97_64_DAC_SRC_PHASE_INCR             0x00000064
136 +#define AC97_66_ADC_SRC_PHASE_INCR             0x00000066
137 +#define AC97_68_RESERVED_68                    0x00000068
138 +#define AC97_6A_SERIAL_PORT_CONTROL            0x0000006A
139 +#define AC97_6C_VENDOR_RESERVED                0x0000006C
140 +#define AC97_6E_VENDOR_RESERVED                0x0000006E
141 +#define AC97_70_BDI_CONFIG                     0x00000070
142 +#define AC97_72_BDI_WAKEUP                     0x00000072
143 +#define AC97_74_VENDOR_RESERVED                0x00000074
144 +#define AC97_76_CAL_ADDRESS                    0x00000076
145 +#define AC97_78_CAL_DATA                       0x00000078
146 +#define AC97_7A_VENDOR_RESERVED                0x0000007A
147 +#define AC97_7C_VENDOR_ID1                     0x0000007C
148 +#define AC97_7E_VENDOR_ID2                     0x0000007E
149 +
150 +
151 +#ifndef __ASSEMBLY__
152 +
153 +//
154 +// enum type for use with reg AC97_RECORD_SELECT
155 +//
156 +typedef enum{
157 +    RECORD_MIC          = 0x0000,
158 +    RECORD_CD           = 0x0101,
159 +    RECORD_VIDEO_IN     = 0x0202,
160 +    RECORD_AUX_IN       = 0x0303,
161 +    RECORD_LINE_IN      = 0x0404,
162 +    RECORD_STEREO_MIX   = 0x0505,
163 +    RECORD_MONO_MIX     = 0x0606,
164 +    RECORD_PHONE_IN     = 0x0707
165 +} Ac97RecordSources;
166 +
167 +#endif /* __ASSEMBLY__ */
168 +
169 +//
170 +// Sample rates supported directly in AC97_PCM_FRONT_DAC_RATE and
171 +// AC97_PCM_LR_ADC_RATE.
172 +//
173 +#define Ac97_Fs_8000        0x1f40
174 +#define Ac97_Fs_11025       0x2b11
175 +#define Ac97_Fs_16000       0x3e80
176 +#define Ac97_Fs_22050       0x5622
177 +#define Ac97_Fs_32000       0x7d00
178 +#define Ac97_Fs_44100       0xac44
179 +#define Ac97_Fs_48000       0xbb80
180 +
181 +//
182 +// RSIZE and TSIZE in AC97RXCR and AC97TXCR
183 +//
184 +#define Ac97_SIZE_20            2
185 +#define Ac97_SIZE_18            1
186 +#define Ac97_SIZE_16            0
187 +#define Ac97_SIZE_12            3
188 +
189 +//=============================================================================
190 +//=============================================================================
191 +
192 +
193 +#endif /* _REGS_AC97_H_ */
194 --- a/sound/arm/Kconfig
195 +++ b/sound/arm/Kconfig
196 @@ -11,6 +11,23 @@ menuconfig SND_ARM
197  
198  if SND_ARM
199  
200 +config SND_EP93XX_AC97
201 +       tristate "AC97 driver for the Cirrus EP93xx chip"
202 +       depends on ARCH_EP93XX && SND
203 +       select SND_EP93XX_PCM
204 +       select SND_AC97_CODEC
205 +       help
206 +         Say Y here to use AC'97 audio with a Cirrus Logic EP93xx chip.
207 +
208 +         To compile this driver as a module, choose M here: the module
209 +         will be called snd-ep93xx-ac97.
210 +
211 +config SND_EP93XX_PCM
212 +       tristate
213 +       select SND_PCM
214 +       help
215 +        Generic PCM module for EP93xx
216 +
217  config SND_ARMAACI
218         tristate "ARM PrimeCell PL041 AC Link support"
219         depends on ARM_AMBA
220 --- a/sound/arm/Makefile
221 +++ b/sound/arm/Makefile
222 @@ -5,6 +5,9 @@
223  obj-$(CONFIG_SND_ARMAACI)      += snd-aaci.o
224  snd-aaci-objs                  := aaci.o devdma.o
225  
226 +obj-$(CONFIG_SND_EP93XX_AC97)  += snd-ep93xx-ac97.o
227 +snd-ep93xx-ac97-objs           := ep93xx-ac97.o
228 +
229  obj-$(CONFIG_SND_PXA2XX_PCM)   += snd-pxa2xx-pcm.o
230  snd-pxa2xx-pcm-objs            := pxa2xx-pcm.o
231  
232 --- /dev/null
233 +++ b/sound/arm/ep93xx-ac97.c
234 @@ -0,0 +1,3482 @@
235 +/*
236 + * linux/sound/arm/ep93xx-ac97.c -- ALSA PCM interface for the edb93xx ac97 audio
237 + */
238 +
239 +#include <linux/autoconf.h>
240 +#include <linux/module.h>
241 +#include <linux/init.h>
242 +#include <linux/platform_device.h>
243 +#include <linux/delay.h>
244 +#include <linux/soundcard.h>
245 +
246 +#include <sound/driver.h>
247 +#include <sound/core.h>
248 +#include <sound/pcm.h>
249 +#include <sound/pcm_params.h>
250 +#include <sound/control.h>
251 +#include <sound/initval.h>
252 +#include <sound/ac97_codec.h>
253 +
254 +#include <asm/irq.h>
255 +#include <asm/semaphore.h>
256 +#include <asm/hardware.h>
257 +#include <asm/io.h>
258 +#include <asm/arch/dma.h>
259 +#include "ep93xx-ac97.h"
260 +
261 +#define        DRIVER_VERSION  "01/05/2009"
262 +#define        DRIVER_DESC     "EP93xx AC97 Audio driver"
263 +static int ac_link_enabled = 0;
264 +static int codec_supported_mixers;
265 +
266 +//#define DEBUG 1
267 +#ifdef DEBUG
268 +#define DPRINTK( fmt, arg... )  printk( fmt, ##arg )
269 +#else
270 +#define DPRINTK( fmt, arg... )
271 +#endif
272 +
273 +#define WL16   0
274 +#define WL24   1
275 +
276 +#define AUDIO_NAME                     "ep93xx-ac97"
277 +#define AUDIO_SAMPLE_RATE_DEFAULT       44100
278 +#define AUDIO_DEFAULT_VOLUME            0
279 +#define AUDIO_MAX_VOLUME               181
280 +#define AUDIO_DEFAULT_DMACHANNELS       3
281 +#define PLAYBACK_DEFAULT_DMACHANNELS    3
282 +#define CAPTURE_DEFAULT_DMACHANNELS     3
283 +
284 +#define CHANNEL_FRONT                  (1<<0)
285 +#define CHANNEL_REAR                           (1<<1)
286 +#define CHANNEL_CENTER_LFE              (1<<2)
287 +
288 +static void snd_ep93xx_dma_tx_callback( ep93xx_dma_int_t DMAInt,
289 +                                       ep93xx_dma_dev_t device,
290 +                                       unsigned int user_data);
291 +static void snd_ep93xx_dma_rx_callback( ep93xx_dma_int_t DMAInt,
292 +                                       ep93xx_dma_dev_t device,
293 +                                       unsigned int user_data);
294 +
295 +static const struct snd_pcm_hardware ep93xx_ac97_pcm_hardware = {
296 +
297 +
298 +    .info              = ( SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE  ),
299 +    .formats           = ( SNDRV_PCM_FMTBIT_U8     | SNDRV_PCM_FMTBIT_S8     |
300 +                           SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_S16_LE |
301 +                           SNDRV_PCM_FMTBIT_U16_BE | SNDRV_PCM_FMTBIT_S16_BE |
302 +                           SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_S32_LE |
303 +                           SNDRV_PCM_FMTBIT_U32_BE | SNDRV_PCM_FMTBIT_S32_BE ),
304 +    .rates             = ( SNDRV_PCM_RATE_8000  | SNDRV_PCM_RATE_11025 |
305 +                           SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
306 +                           SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
307 +                           SNDRV_PCM_RATE_48000 ),
308 +    .rate_min          = 8000,
309 +    .rate_max          = 48000,
310 +    .channels_min      = 1,/*2,*/
311 +    .channels_max      = 2,
312 +
313 +    .period_bytes_min  = 1 * 1024,
314 +    .period_bytes_max  = 32 * 1024,
315 +    .periods_min       = 1,
316 +    .periods_max       = 32,
317 +    .buffer_bytes_max  = 32 * 1024,
318 +    .fifo_size         = 0,
319 +};
320 +
321 +static audio_stream_t output_stream;
322 +static audio_stream_t input_stream;
323 +
324 +static audio_state_t audio_state =
325 +{
326 +    .output_stream             =&output_stream,
327 +    .output_dma[0]             =DMATx_AAC1,
328 +    .output_id[0]              ="Ac97 out",
329 +
330 +    .input_stream              =&input_stream,
331 +    .input_dma[0]              =DMARx_AAC1,
332 +    .input_id[0]               ="Ac97 in",
333 +
334 +    .sem                    = __SEMAPHORE_INIT(audio_state.sem,1),
335 +    .codec_set_by_playback  = 0,
336 +    .codec_set_by_capture   = 0,
337 +    .DAC_bit_width              =16,
338 +    .bCompactMode               =0,
339 +};
340 +
341 +
342 +
343 +/*
344 + * peek
345 + *
346 + * Reads an AC97 codec register.  Returns -1 if there was an error.
347 + */
348 +static int peek(unsigned int uiAddress)
349 +{
350 +       unsigned int uiAC97RGIS;
351 +
352 +       if( !ac_link_enabled )
353 +       {
354 +               printk("ep93xx ac97 peek: attempt to peek before enabling ac-link.\n");
355 +               return -1;
356 +       }
357 +
358 +       /*
359 +        * Check to make sure that the address is aligned on a word boundary
360 +        * and is 7E or less.
361 +        */
362 +       if( ((uiAddress & 0x1)!=0) || (uiAddress > 0x007e))
363 +       {
364 +               return -1;
365 +       }
366 +
367 +       /*
368 +        * How it is supposed to work is:
369 +        *  - The ac97 controller sends out a read addr in slot 1.
370 +        *  - In the next frame, the codec will echo that address back in slot 1
371 +        *    and send the data in slot 2.  SLOT2RXVALID will be set to 1.
372 +        *
373 +        * Read until SLOT2RXVALID goes to 1.  Reading the data in AC97S2DATA
374 +        * clears SLOT2RXVALID.
375 +        */
376 +
377 +       /*
378 +        * First, delay one frame in case of back to back peeks/pokes.
379 +        */
380 +       mdelay( 1 );
381 +
382 +       /*
383 +        * Write the address to AC97S1DATA, delay 1 frame, read the flags.
384 +        */
385 +       outl( uiAddress, AC97S1DATA);
386 +       udelay( 21 * 4 );
387 +       uiAC97RGIS = inl( AC97RGIS );
388 +
389 +       /*
390 +        * Return error if we timed out.
391 +        */
392 +       if( ((uiAC97RGIS & AC97RGIS_SLOT1TXCOMPLETE) == 0 ) &&
393 +               ((uiAC97RGIS & AC97RGIS_SLOT2RXVALID) == 0 ) )
394 +       {
395 +               printk( "ep93xx-ac97 - peek failed reading reg 0x%02x.\n", uiAddress );
396 +               return -1;
397 +       }
398 +
399 +       return ( inl(AC97S2DATA) & 0x000fffff);
400 +}
401 +
402 +/*
403 + * poke
404 + *
405 + * Writes an AC97 codec Register.  Return -1 if error.
406 + */
407 +static int poke(unsigned int uiAddress, unsigned int uiValue)
408 +{
409 +       unsigned int uiAC97RGIS;
410 +
411 +       if( !ac_link_enabled )
412 +       {
413 +               printk("ep93xx ac97 poke: attempt to poke before enabling ac-link.\n");
414 +               return -1;
415 +       }
416 +
417 +       /*
418 +        * Check to make sure that the address is align on a word boundary and
419 +        * is 7E or less.  And that the value is a 16 bit value.
420 +        */
421 +       if( ((uiAddress & 0x1)!=0) || (uiAddress > 0x007e))
422 +       {
423 +               printk("ep93xx ac97 poke: address error.\n");
424 +               return -1;
425 +       }
426 +
427 +       /*stop the audio loop from the input to the output directly*/
428 +
429 +       if((uiAddress==AC97_0E_MIC_VOL)||(uiAddress==AC97_10_LINE_IN_VOL))
430 +       {
431 +               uiValue = (uiValue | 0x8000);
432 +
433 +       }
434 +
435 +       /*
436 +        * First, delay one frame in case of back to back peeks/pokes.
437 +        */
438 +       mdelay( 1 );
439 +
440 +       /*
441 +        * Write the data to AC97S2DATA, then the address to AC97S1DATA.
442 +        */
443 +       outl( uiValue, AC97S2DATA );
444 +       outl( uiAddress, AC97S1DATA );
445 +
446 +       /*
447 +        * Wait for the tx to complete, get status.
448 +        */
449 +       udelay( 30 );/*21*/
450 +       uiAC97RGIS = inl(AC97RGIS);
451 +
452 +       /*
453 +        * Return error if we timed out.
454 +        */
455 +       if( !(inl(AC97RGIS) & AC97RGIS_SLOT1TXCOMPLETE) )
456 +       {
457 +               printk( "ep93xx-ac97: poke failed writing reg 0x%02x  value 0x%02x.\n", uiAddress, uiValue );
458 +               return -1;
459 +       }
460 +
461 +       return 0;
462 +}
463 +
464 +
465 +/*
466 + * When we get to the multichannel case the pre-fill and enable code
467 + * will go to the dma driver's start routine.
468 + */
469 +static void ep93xx_audio_enable( int input_or_output_stream )
470 +{
471 +       unsigned int uiTemp;
472 +
473 +       DPRINTK("ep93xx_audio_enable :%x\n",input_or_output_stream);
474 +
475 +       /*
476 +        * Enable the rx or tx channel depending on the value of
477 +        * input_or_output_stream
478 +        */
479 +       if( input_or_output_stream )
480 +       {
481 +               uiTemp = inl(AC97TXCR1);
482 +               outl( (uiTemp | AC97TXCR_TEN), AC97TXCR1 );
483 +       }
484 +       else
485 +       {
486 +               uiTemp = inl(AC97RXCR1);
487 +               outl( (uiTemp | AC97RXCR_REN), AC97RXCR1 );
488 +       }
489 +
490 +
491 +       //DDEBUG("ep93xx_audio_enable - EXIT\n");
492 +}
493 +
494 +static void ep93xx_audio_disable( int input_or_output_stream )
495 +{
496 +       unsigned int uiTemp;
497 +
498 +       DPRINTK("ep93xx_audio_disable\n");
499 +
500 +       /*
501 +        * Disable the rx or tx channel depending on the value of
502 +        * input_or_output_stream
503 +        */
504 +       if( input_or_output_stream )
505 +       {
506 +               uiTemp = inl(AC97TXCR1);
507 +               outl( (uiTemp & ~AC97TXCR_TEN), AC97TXCR1 );
508 +       }
509 +       else
510 +       {
511 +               uiTemp = inl(AC97RXCR1);
512 +               outl( (uiTemp & ~AC97RXCR_REN), AC97RXCR1 );
513 +       }
514 +
515 +       //DDEBUG("ep93xx_audio_disable - EXIT\n");
516 +}
517 +
518 +
519 +
520 +/*=======================================================================================*/
521 +/*
522 + * ep93xx_setup_src
523 + *
524 + * Once the ac-link is up and all is good, we want to set the codec to a
525 + * usable mode.
526 + */
527 +static void ep93xx_setup_src(void)
528 +{
529 +       int iTemp;
530 +
531 +       /*
532 +        * Set the VRA bit to enable the SRC.
533 +        */
534 +       iTemp = peek( AC97_2A_EXT_AUDIO_POWER );
535 +       poke( AC97_2A_EXT_AUDIO_POWER,  (iTemp | 0x1) );
536 +
537 +       /*
538 +        * Set the DSRC/ASRC bits to enable the variable rate SRC.
539 +        */
540 +       iTemp = peek( AC97_60_MISC_CRYSTAL_CONTROL  );
541 +       poke( AC97_60_MISC_CRYSTAL_CONTROL, (iTemp  | 0x0300) );
542 +}
543 +
544 +/*
545 + * ep93xx_set_samplerate
546 + *
547 + *   lFrequency       - Sample Rate in Hz
548 + *   bCapture       - 0 to set Tx sample rate; 1 to set Rx sample rate
549 + */
550 +static void ep93xx_set_samplerate( long lSampleRate, int bCapture )
551 +{
552 +       unsigned short usDivider, usPhase;
553 +
554 +       DPRINTK( "ep93xx_set_samplerate - Fs = %d\n", (int)lSampleRate );
555 +
556 +       if( (lSampleRate <  7200) || (lSampleRate > 48000)  )
557 +       {
558 +               printk( "ep93xx_set_samplerate - invalid Fs = %d\n",
559 +                                (int)lSampleRate );
560 +               return;
561 +       }
562 +
563 +       /*
564 +        * Calculate divider and phase increment.
565 +        *
566 +        * divider = round( 0x1770000 / lSampleRate )
567 +        *  Note that usually rounding is done by adding 0.5 to a floating
568 +        *  value and then truncating.  To do this without using floating
569 +        *  point, I multiply the fraction by two, do the division, then add one,
570 +        *  then divide the whole by 2 and then truncate.
571 +        *  Same effect, no floating point math.
572 +        *
573 +        * Ph incr = trunc( (0x1000000 / usDivider) + 1 )
574 +        */
575 +
576 +       usDivider = (unsigned short)( ((2 * 0x1770000 / lSampleRate) +  1) / 2 );
577 +
578 +       usPhase = (0x1000000 / usDivider) + 1;
579 +
580 +       /*
581 +        * Write them in the registers.  Spec says divider must be
582 +        * written after phase incr.
583 +        */
584 +       if(!bCapture)
585 +       {
586 +               poke( AC97_2C_PCM_FRONT_DAC_RATE, usDivider);
587 +               poke( AC97_64_DAC_SRC_PHASE_INCR, usPhase);
588 +       }
589 +       else
590 +       {
591 +
592 +               poke( AC97_32_PCM_LR_ADC_RATE,  usDivider);
593 +               poke( AC97_66_ADC_SRC_PHASE_INCR, usPhase);
594 +       }
595 +
596 +       DPRINTK( "ep93xx_set_samplerate - phase = %d,  divider = %d\n",
597 +                               (unsigned int)usPhase, (unsigned int)usDivider );
598 +
599 +       /*
600 +        * We sorta should report the actual samplerate back to the calling
601 +        * application.  But some applications freak out if they don't get
602 +        * exactly what they asked for.  So we fudge and tell them what
603 +        * they want to hear.
604 +        */
605 +       //audio_samplerate = lSampleRate;
606 +
607 +       DPRINTK( "ep93xx_set_samplerate - EXIT\n" );
608 +}
609 +
610 +/*
611 + * ep93xx_set_hw_format
612 + *
613 + * Sets up whether the controller is expecting 20 bit data in 32 bit words
614 + * or 16 bit data compacted to have a stereo sample in each 32 bit word.
615 + */
616 +static void ep93xx_set_hw_format( long format,long channel )
617 +{
618 +       int bCompactMode;
619 +
620 +       switch( format )
621 +       {
622 +               /*
623 +                * Here's all the <=16 bit formats.  We can squeeze both L and R
624 +                * into one 32 bit sample so use compact mode.
625 +                */
626 +               case SNDRV_PCM_FORMAT_U8:
627 +               case SNDRV_PCM_FORMAT_S8:
628 +               case SNDRV_PCM_FORMAT_S16_LE:
629 +               case SNDRV_PCM_FORMAT_U16_LE:
630 +                       bCompactMode = 1;
631 +                       break;
632 +
633 +               /*
634 +                * Add any other >16 bit formats here...
635 +                */
636 +               case SNDRV_PCM_FORMAT_S32_LE:
637 +               default:
638 +                       bCompactMode = 0;
639 +                       break;
640 +       }
641 +
642 +       if( bCompactMode )
643 +       {
644 +               DPRINTK("ep93xx_set_hw_format - Setting serial mode to 16 bit compact.\n");
645 +
646 +               /*
647 +                * Turn on Compact Mode so we can fit each stereo sample into
648 +                * a 32 bit word.  Twice as efficent for DMA and FIFOs.
649 +                */
650 +               if(channel==2){
651 +                       outl( 0x00008018, AC97RXCR1 );
652 +                       outl( 0x00008018, AC97TXCR1 );
653 +               }
654 +               else {
655 +                       outl( 0x00008018, AC97RXCR1 );
656 +                        outl( 0x00008018, AC97TXCR1 );
657 +                }
658 +
659 +
660 +               audio_state.DAC_bit_width = 16;
661 +               audio_state.bCompactMode = 1;
662 +       }
663 +       else
664 +       {
665 +               DPRINTK("ep93xx_set_hw_format - Setting serial mode to 20 bit non-CM.\n");
666 +
667 +               /*
668 +                * Turn off Compact Mode so we can do > 16 bits per channel
669 +                */
670 +               if(channel==2){
671 +                       outl( 0x00004018, AC97RXCR1 );
672 +                       outl( 0x00004018, AC97TXCR1 );
673 +               }
674 +               else{
675 +                        outl( 0x00004018, AC97RXCR1 );
676 +                        outl( 0x00004018, AC97TXCR1 );
677 +               }
678 +
679 +               audio_state.DAC_bit_width = 20;
680 +               audio_state.bCompactMode = 0;
681 +       }
682 +
683 +}
684 +
685 +/*
686 + * ep93xx_stop_loop
687 + *
688 + * Once the ac-link is up and all is good, we want to set the codec to a
689 + * usable mode.
690 + */
691 +static void ep93xx_stop_loop(void)
692 +{
693 +        int iTemp;
694 +
695 +        /*
696 +         * Set the AC97_0E_MIC_VOL MUTE bit to enable the LOOP.
697 +         */
698 +        iTemp = peek( AC97_0E_MIC_VOL );
699 +        poke( AC97_0E_MIC_VOL,  (iTemp | 0x8000) );
700 +
701 +        /*
702 +         * Set the AC97_10_LINE_IN_VOL MUTE bit to enable the LOOP.
703 +         */
704 +        iTemp = peek( AC97_10_LINE_IN_VOL  );
705 +        poke( AC97_10_LINE_IN_VOL, (iTemp  | 0x8000) );
706 +}
707 +
708 +/*
709 + * ep93xx_init_ac97_controller
710 + *
711 + * This routine sets up the Ac'97 Controller.
712 + */
713 +static void ep93xx_init_ac97_controller(void)
714 +{
715 +       unsigned int uiDEVCFG, uiTemp;
716 +
717 +       DPRINTK("ep93xx_init_ac97_controller - enter\n");
718 +
719 +       /*
720 +        * Configure the multiplexed Ac'97 pins to be Ac97 not I2s.
721 +        * Configure the EGPIO4 and EGPIO6 to be GPIOS, not to be
722 +        * SDOUT's for the second and third I2S controller channels.
723 +        */
724 +       uiDEVCFG = inl(EP93XX_SYSCON_DEVICE_CONFIG);
725 +
726 +       uiDEVCFG &= ~(EP93XX_SYSCON_DEVCFG_CONFIG_I2SONAC97 |
727 +                                 EP93XX_SYSCON_DEVCFG_A1onG |
728 +                                 EP93XX_SYSCON_DEVCFG_A2onG);
729 +
730 +       SysconSetLocked(EP93XX_SYSCON_DEVICE_CONFIG, uiDEVCFG);
731 +
732 +       /*
733 +        * Disable the AC97 controller internal loopback.
734 +        * Disable Override codec ready.
735 +        */
736 +       outl( 0, AC97GCR );
737 +
738 +       /*
739 +        * Enable the AC97 Link.
740 +        */
741 +       uiTemp = inl(AC97GCR);
742 +       outl( (uiTemp | AC97GSR_IFE), AC97GCR );
743 +
744 +       /*
745 +        * Set the TIMEDRESET bit.  Will cause a > 1uSec reset of the ac-link.
746 +        * This bit is self resetting.
747 +        */
748 +       outl( AC97RESET_TIMEDRESET, AC97RESET );
749 +
750 +       /*
751 +        *  Delay briefly, but let's not hog the processor.
752 +        */
753 +       set_current_state(TASK_INTERRUPTIBLE);
754 +       schedule_timeout( 5 ); /* 50 mSec */
755 +
756 +       /*
757 +        * Read the AC97 status register to see if we've seen a CODECREADY
758 +        * signal from the AC97 codec.
759 +        */
760 +       if( !(inl(AC97RGIS) & AC97RGIS_CODECREADY))
761 +       {
762 +               printk( "ep93xx-ac97 - FAIL: CODECREADY still low!\n");
763 +               return;
764 +       }
765 +
766 +       /*
767 +        *  Delay for a second, not hogging the processor
768 +        */
769 +       set_current_state(TASK_INTERRUPTIBLE);
770 +       schedule_timeout( HZ ); /* 1 Sec */
771 +
772 +       /*
773 +        * Now the Ac-link is up.  We can read and write codec registers.
774 +        */
775 +       ac_link_enabled = 1;
776 +
777 +       /*
778 +        * Set up the rx and tx channels
779 +        * Set the CM bit, data size=16 bits, enable tx slots 3 & 4.
780 +        */
781 +       ep93xx_set_hw_format( EP93XX_DEFAULT_FORMAT,EP93XX_DEFAULT_NUM_CHANNELS );
782 +
783 +       DPRINTK( "ep93xx-ac97 -- AC97RXCR1:  %08x\n", inl(AC97RXCR1) );
784 +       DPRINTK( "ep93xx-ac97 -- AC97TXCR1:  %08x\n", inl(AC97TXCR1) );
785 +
786 +       DPRINTK("ep93xx_init_ac97_controller - EXIT - success\n");
787 +
788 +}
789 +
790 +#ifdef alsa_ac97_debug
791 +static void ep93xx_dump_ac97_regs(void)
792 +{
793 +       int i;
794 +       unsigned int reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7;
795 +
796 +       DPRINTK( "---------------------------------------------\n");
797 +       DPRINTK( "   :   0    2    4    6    8    A    C    E\n" );
798 +
799 +       for( i=0 ; i < 0x80 ; i+=0x10 )
800 +       {
801 +               reg0 = 0xffff & (unsigned int)peek( i );
802 +               reg1 = 0xffff & (unsigned int)peek( i + 0x2 );
803 +               reg2 = 0xffff & (unsigned int)peek( i + 0x4 );
804 +               reg3 = 0xffff & (unsigned int)peek( i + 0x6 );
805 +               reg4 = 0xffff & (unsigned int)peek( i + 0x8 );
806 +               reg5 = 0xffff & (unsigned int)peek( i + 0xa );
807 +               reg6 = 0xffff & (unsigned int)peek( i + 0xc );
808 +               reg7 = 0xffff & (unsigned int)peek( i + 0xe );
809 +
810 +               DPRINTK( " %02x : %04x %04x %04x %04x %04x %04x %04x %04x\n",
811 +                                i, reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7);
812 +       }
813 +
814 +       DPRINTK( "---------------------------------------------\n");
815 +}
816 +#endif
817 +
818 +
819 +#define supported_mixer(FOO) \
820 +        ( (FOO >= 0) && \
821 +        (FOO < SOUND_MIXER_NRDEVICES) && \
822 +        codec_supported_mixers & (1<<FOO) )
823 +
824 +/*
825 + * Available record sources.
826 + * LINE1 refers to AUX in.
827 + * IGAIN refers to input gain which means stereo mix.
828 + */
829 +#define AC97_RECORD_MASK \
830 +        (SOUND_MASK_MIC | SOUND_MASK_CD | SOUND_MASK_IGAIN | SOUND_MASK_VIDEO |\
831 +        SOUND_MASK_LINE1 | SOUND_MASK_LINE | SOUND_MASK_PHONEIN)
832 +
833 +#define AC97_STEREO_MASK \
834 +        (SOUND_MASK_VOLUME | SOUND_MASK_PCM | SOUND_MASK_LINE | SOUND_MASK_CD | \
835 +        SOUND_MASK_ALTPCM | SOUND_MASK_IGAIN | SOUND_MASK_LINE1 | SOUND_MASK_VIDEO)
836 +
837 +#define AC97_SUPPORTED_MASK \
838 +        (AC97_STEREO_MASK | SOUND_MASK_BASS | SOUND_MASK_TREBLE | \
839 +        SOUND_MASK_SPEAKER | SOUND_MASK_MIC | \
840 +        SOUND_MASK_PHONEIN | SOUND_MASK_PHONEOUT)
841 +
842 +
843 +
844 +
845 +/* this table has default mixer values for all OSS mixers. */
846 +typedef struct  {
847 +       int mixer;
848 +       unsigned int value;
849 +} mixer_defaults_t;
850 +
851 +/*
852 + * Default mixer settings that are set up during boot.
853 + *
854 + * These values are 16 bit numbers in which the upper byte is right volume
855 + * and the lower byte is left volume or mono volume for mono controls.
856 + *
857 + * OSS Range for each of left and right volumes is 0 to 100 (0x00 to 0x64).
858 + *
859 + */
860 +static mixer_defaults_t mixer_defaults[SOUND_MIXER_NRDEVICES] =
861 +{
862 +       /* Outputs */
863 +       {SOUND_MIXER_VOLUME,    0x6464},   /* 0 dB */  /* -46.5dB to  0 dB */
864 +       {SOUND_MIXER_ALTPCM,    0x6464},   /* 0 dB */  /* -46.5dB to  0 dB */
865 +       {SOUND_MIXER_PHONEOUT,  0x6464},   /* 0 dB */  /* -46.5dB to  0 dB */
866 +
867 +       /* PCM playback gain */
868 +       {SOUND_MIXER_PCM,               0x4b4b},   /* 0 dB */  /* -34.5dB to +12dB */
869 +
870 +       /* Record gain */
871 +       {SOUND_MIXER_IGAIN,             0x0000},   /* 0 dB */  /* -34.5dB to +12dB */
872 +
873 +       /* Inputs */
874 +       {SOUND_MIXER_MIC,               0x0000},   /* mute */  /* -34.5dB to +12dB */
875 +       {SOUND_MIXER_LINE,              0x4b4b},   /* 0 dB */  /* -34.5dB to +12dB */
876 +
877 +       /* Inputs that are not connected. */
878 +       {SOUND_MIXER_SPEAKER,   0x0000},   /* mute */  /* -45dB   to   0dB */
879 +       {SOUND_MIXER_PHONEIN,   0x0000},   /* mute */  /* -34.5dB to +12dB */
880 +       {SOUND_MIXER_CD,                0x0000},   /* mute */  /* -34.5dB to +12dB */
881 +       {SOUND_MIXER_VIDEO,             0x0000},   /* mute */  /* -34.5dB to +12dB */
882 +       {SOUND_MIXER_LINE1,             0x0000},   /* mute */  /* -34.5dB to +12dB */
883 +
884 +       {-1,0} /* last entry */
885 +};
886 +
887 +/* table to scale scale from OSS mixer value to AC97 mixer register value */
888 +typedef struct {
889 +       unsigned int offset;
890 +       int scale;
891 +} ac97_mixer_hw_t;
892 +
893 +static ac97_mixer_hw_t ac97_hw[SOUND_MIXER_NRDEVICES] =
894 +{
895 +       [SOUND_MIXER_VOLUME]            =       {AC97_02_MASTER_VOL,    64},
896 +       [SOUND_MIXER_BASS]                      =       {0, 0},
897 +       [SOUND_MIXER_TREBLE]            =       {0, 0},
898 +       [SOUND_MIXER_SYNTH]                     =       {0,     0},
899 +       [SOUND_MIXER_PCM]                       =       {AC97_18_PCM_OUT_VOL,   32},
900 +       [SOUND_MIXER_SPEAKER]           =       {AC97_0A_PC_BEEP_VOL,   32},
901 +       [SOUND_MIXER_LINE]                      =       {AC97_10_LINE_IN_VOL,   32},
902 +       [SOUND_MIXER_MIC]                       =       {AC97_0E_MIC_VOL,               32},
903 +       [SOUND_MIXER_CD]                        =       {AC97_12_CD_VOL,                32},
904 +       [SOUND_MIXER_IMIX]                      =       {0,     0},
905 +       [SOUND_MIXER_ALTPCM]            =       {AC97_04_HEADPHONE_VOL, 64},
906 +       [SOUND_MIXER_RECLEV]            =       {0,     0},
907 +       [SOUND_MIXER_IGAIN]                     =       {AC97_1C_RECORD_GAIN,   16},
908 +       [SOUND_MIXER_OGAIN]                     =       {0,     0},
909 +       [SOUND_MIXER_LINE1]                     =       {AC97_16_AUX_VOL,               32},
910 +       [SOUND_MIXER_LINE2]                     =       {0,     0},
911 +       [SOUND_MIXER_LINE3]                     =       {0,     0},
912 +       [SOUND_MIXER_DIGITAL1]          =       {0,     0},
913 +       [SOUND_MIXER_DIGITAL2]          =       {0,     0},
914 +       [SOUND_MIXER_DIGITAL3]          =       {0,     0},
915 +       [SOUND_MIXER_PHONEIN]           =       {AC97_0C_PHONE_VOL,             32},
916 +       [SOUND_MIXER_PHONEOUT]          =       {AC97_06_MONO_VOL,              64},
917 +       [SOUND_MIXER_VIDEO]                     =       {AC97_14_VIDEO_VOL,             32},
918 +       [SOUND_MIXER_RADIO]                     =       {0,     0},
919 +       [SOUND_MIXER_MONITOR]           =       {0,     0},
920 +};
921 +
922 +
923 +/* the following tables allow us to go from OSS <-> ac97 quickly. */
924 +enum ac97_recsettings
925 +{
926 +       AC97_REC_MIC=0,
927 +       AC97_REC_CD,
928 +       AC97_REC_VIDEO,
929 +       AC97_REC_AUX,
930 +       AC97_REC_LINE,
931 +       AC97_REC_STEREO, /* combination of all enabled outputs..  */
932 +       AC97_REC_MONO,        /*.. or the mono equivalent */
933 +       AC97_REC_PHONE
934 +};
935 +
936 +static const unsigned int ac97_rm2oss[] =
937 +{
938 +       [AC97_REC_MIC]   = SOUND_MIXER_MIC,
939 +       [AC97_REC_CD]    = SOUND_MIXER_CD,
940 +       [AC97_REC_VIDEO] = SOUND_MIXER_VIDEO,
941 +       [AC97_REC_AUX]   = SOUND_MIXER_LINE1,
942 +       [AC97_REC_LINE]  = SOUND_MIXER_LINE,
943 +       [AC97_REC_STEREO]= SOUND_MIXER_IGAIN,
944 +       [AC97_REC_PHONE] = SOUND_MIXER_PHONEIN
945 +};
946 +
947 +/* indexed by bit position */
948 +static const unsigned int ac97_oss_rm[] =
949 +{
950 +       [SOUND_MIXER_MIC]       = AC97_REC_MIC,
951 +       [SOUND_MIXER_CD]        = AC97_REC_CD,
952 +       [SOUND_MIXER_VIDEO] = AC97_REC_VIDEO,
953 +       [SOUND_MIXER_LINE1] = AC97_REC_AUX,
954 +       [SOUND_MIXER_LINE]      = AC97_REC_LINE,
955 +       [SOUND_MIXER_IGAIN]     = AC97_REC_STEREO,
956 +       [SOUND_MIXER_PHONEIN]   = AC97_REC_PHONE
957 +};
958 +
959 +
960 +/*
961 + * ep93xx_write_mixer
962 + *
963 + */
964 +static void ep93xx_write_mixer
965 +(
966 +       int oss_channel,
967 +       unsigned int left,
968 +       unsigned int right
969 +)
970 +{
971 +       u16 val = 0;
972 +       ac97_mixer_hw_t * mh = &ac97_hw[oss_channel];
973 +
974 +       DPRINTK("ac97_codec: wrote OSS %2d (ac97 0x%02x), "
975 +              "l:%2d, r:%2d:",
976 +              oss_channel, mh->offset, left, right);
977 +
978 +       if( !mh->scale )
979 +       {
980 +               printk( "ep93xx-ac97.c: ep93xx_write_mixer - not a valid OSS channel\n");
981 +               return;
982 +       }
983 +
984 +       if( AC97_STEREO_MASK & (1 << oss_channel) )
985 +       {
986 +               /* stereo mixers */
987 +               if (left == 0 && right == 0)
988 +               {
989 +                       val = 0x8000;
990 +               }
991 +               else
992 +               {
993 +                       if (oss_channel == SOUND_MIXER_IGAIN)
994 +                       {
995 +                               right = (right * mh->scale) / 100;
996 +                               left = (left * mh->scale) / 100;
997 +                               if (right >= mh->scale)
998 +                                       right = mh->scale-1;
999 +                               if (left >= mh->scale)
1000 +                                       left = mh->scale-1;
1001 +                       }
1002 +                       else
1003 +                       {
1004 +                               right = ((100 - right) * mh->scale) / 100;
1005 +                               left = ((100 - left) * mh->scale) / 100;
1006 +                               if (right >= mh->scale)
1007 +                                       right = mh->scale-1;
1008 +                               if (left >= mh->scale)
1009 +                                       left = mh->scale-1;
1010 +                       }
1011 +                       val = (left << 8) | right;
1012 +               }
1013 +       }
1014 +       else if(left == 0)
1015 +       {
1016 +               val = 0x8000;
1017 +       }
1018 +       else if( (oss_channel == SOUND_MIXER_SPEAKER) ||
1019 +                       (oss_channel == SOUND_MIXER_PHONEIN) ||
1020 +                       (oss_channel == SOUND_MIXER_PHONEOUT) )
1021 +       {
1022 +               left = ((100 - left) * mh->scale) / 100;
1023 +               if (left >= mh->scale)
1024 +                       left = mh->scale-1;
1025 +               val = left;
1026 +       }
1027 +       else if (oss_channel == SOUND_MIXER_MIC)
1028 +       {
1029 +               val = peek( mh->offset) & ~0x801f;
1030 +               left = ((100 - left) * mh->scale) / 100;
1031 +               if (left >= mh->scale)
1032 +                       left = mh->scale-1;
1033 +               val |= left;
1034 +       }
1035 +       /*
1036 +        * For bass and treble, the low bit is optional.  Masking it
1037 +        * lets us avoid the 0xf 'bypass'.
1038 +        * Do a read, modify, write as we have two contols in one reg.
1039 +        */
1040 +       else if (oss_channel == SOUND_MIXER_BASS)
1041 +       {
1042 +               val = peek( mh->offset) & ~0x0f00;
1043 +               left = ((100 - left) * mh->scale) / 100;
1044 +               if (left >= mh->scale)
1045 +                       left = mh->scale-1;
1046 +               val |= (left << 8) & 0x0e00;
1047 +       }
1048 +       else if (oss_channel == SOUND_MIXER_TREBLE)
1049 +       {
1050 +               val = peek( mh->offset) & ~0x000f;
1051 +               left = ((100 - left) * mh->scale) / 100;
1052 +               if (left >= mh->scale)
1053 +                       left = mh->scale-1;
1054 +               val |= left & 0x000e;
1055 +       }
1056 +
1057 +       DPRINTK(" 0x%04x", val);
1058 +
1059 +       poke( mh->offset, val );
1060 +
1061 +#ifdef alsa_ac97_debug
1062 +       val = peek( mh->offset );
1063 +       DEBUG(" -> 0x%04x\n", val);
1064 +#endif
1065 +
1066 +}
1067 +
1068 +/* a thin wrapper for write_mixer */
1069 +static void ep93xx_set_mixer
1070 +(
1071 +       unsigned int oss_mixer,
1072 +       unsigned int val
1073 +)
1074 +{
1075 +       unsigned int left,right;
1076 +
1077 +       /* cleanse input a little */
1078 +       right = ((val >> 8)  & 0xff) ;
1079 +       left = (val  & 0xff) ;
1080 +
1081 +       if (right > 100) right = 100;
1082 +       if (left > 100) left = 100;
1083 +
1084 +       /*mixer_state[oss_mixer] = (right << 8) | left;*/
1085 +       ep93xx_write_mixer( oss_mixer, left, right);
1086 +}
1087 +
1088 +static void ep93xx_init_mixer(void)
1089 +{
1090 +       u16 cap;
1091 +       int i;
1092 +
1093 +       /* mixer masks */
1094 +       codec_supported_mixers  = AC97_SUPPORTED_MASK;
1095 +
1096 +       cap = peek( AC97_00_RESET );
1097 +       if( !(cap & 0x04) )
1098 +       {
1099 +               codec_supported_mixers &= ~(SOUND_MASK_BASS|SOUND_MASK_TREBLE);
1100 +       }
1101 +       if( !(cap & 0x10) )
1102 +       {
1103 +               codec_supported_mixers &= ~SOUND_MASK_ALTPCM;
1104 +       }
1105 +
1106 +       /*
1107 +        * Detect bit resolution of output volume controls by writing to the
1108 +        * 6th bit (not unmuting yet)
1109 +        */
1110 +       poke( AC97_02_MASTER_VOL, 0xa020 );
1111 +       if( peek( AC97_02_MASTER_VOL) != 0xa020 )
1112 +       {
1113 +               ac97_hw[SOUND_MIXER_VOLUME].scale = 32;
1114 +       }
1115 +
1116 +       poke( AC97_04_HEADPHONE_VOL, 0xa020 );
1117 +       if( peek( AC97_04_HEADPHONE_VOL) != 0xa020 )
1118 +       {
1119 +               ac97_hw[AC97_04_HEADPHONE_VOL].scale = 32;
1120 +       }
1121 +
1122 +       poke( AC97_06_MONO_VOL, 0x8020 );
1123 +       if( peek( AC97_06_MONO_VOL) != 0x8020 )
1124 +       {
1125 +               ac97_hw[AC97_06_MONO_VOL].scale = 32;
1126 +       }
1127 +
1128 +       /* initialize mixer channel volumes */
1129 +       for( i = 0;
1130 +               (i < SOUND_MIXER_NRDEVICES) && (mixer_defaults[i].mixer != -1) ;
1131 +               i++ )
1132 +       {
1133 +               if( !supported_mixer( mixer_defaults[i].mixer) )
1134 +               {
1135 +                       continue;
1136 +               }
1137 +
1138 +               ep93xx_set_mixer( mixer_defaults[i].mixer, mixer_defaults[i].value);
1139 +       }
1140 +
1141 +}
1142 +
1143 +static int ep93xx_set_recsource( int mask )
1144 +{
1145 +       unsigned int val;
1146 +
1147 +       /* Arg contains a bit for each recording source */
1148 +       if( mask == 0 )
1149 +       {
1150 +               return 0;
1151 +       }
1152 +
1153 +       mask &= AC97_RECORD_MASK;
1154 +
1155 +       if( mask == 0 )
1156 +       {
1157 +               return -EINVAL;
1158 +       }
1159 +
1160 +       /*
1161 +        * May have more than one bit set.  So clear out currently selected
1162 +        * record source value first (AC97 supports only 1 input)
1163 +        */
1164 +       val = (1 << ac97_rm2oss[peek( AC97_1A_RECORD_SELECT ) & 0x07]);
1165 +       if (mask != val)
1166 +           mask &= ~val;
1167 +
1168 +       val = ffs(mask);
1169 +       val = ac97_oss_rm[val-1];
1170 +       val |= val << 8;  /* set both channels */
1171 +
1172 +       /*
1173 +        *
1174 +        */
1175 +        val = peek( AC97_1A_RECORD_SELECT ) & 0x0707;
1176 +        if ((val&0x0404)!=0)
1177 +          val=0x0404;
1178 +        else if((val&0x0000)!=0)
1179 +          val=0x0101;
1180 +
1181 +
1182 +       DPRINTK("ac97_codec: setting ac97 recmask to 0x%04x\n", val);
1183 +
1184 +       poke( AC97_1A_RECORD_SELECT, val);
1185 +
1186 +       return 0;
1187 +}
1188 +
1189 +/*
1190 + * ep93xx_init_ac97_codec
1191 + *
1192 + * Program up the external Ac97 codec.
1193 + *
1194 + */
1195 +static void ep93xx_init_ac97_codec( void )
1196 +{
1197 +       DPRINTK("ep93xx_init_ac97_codec - enter\n");
1198 +
1199 +       ep93xx_setup_src();
1200 +       ep93xx_set_samplerate( AUDIO_SAMPLE_RATE_DEFAULT, 0 );
1201 +       ep93xx_set_samplerate( AUDIO_SAMPLE_RATE_DEFAULT, 1 );
1202 +       ep93xx_init_mixer();
1203 +
1204 +       DPRINTK("ep93xx_init_ac97_codec - EXIT\n");
1205 +
1206 +}
1207 +
1208 +
1209 +/*
1210 + * ep93xx_audio_init
1211 + * Audio interface
1212 + */
1213 +static void ep93xx_audio_init(void)
1214 +{
1215 +       DPRINTK("ep93xx_audio_init - enter\n");
1216 +       /*
1217 +        * Init the controller, enable the ac-link.
1218 +        * Initialize the codec.
1219 +        */
1220 +       ep93xx_init_ac97_controller();
1221 +       ep93xx_init_ac97_codec();
1222 +       /*stop the audio loop from the input to the output directly*/
1223 +       ep93xx_stop_loop();
1224 +
1225 +#ifdef alsa_ac97_debug
1226 +       ep93xx_dump_ac97_regs();
1227 +#endif
1228 +       DPRINTK("ep93xx_audio_init - EXIT\n");
1229 +}
1230 +
1231 +/*====================================================================================*/
1232 +
1233 +
1234 +static void print_audio_format( long format )
1235 +{
1236 +    switch( format ){
1237 +       case SNDRV_PCM_FORMAT_S8:
1238 +               DPRINTK( "AFMT_S8\n" );
1239 +               break;
1240 +
1241 +       case SNDRV_PCM_FORMAT_U8:
1242 +               DPRINTK( "AFMT_U8\n" );
1243 +               break;
1244 +
1245 +       case SNDRV_PCM_FORMAT_S16_LE:
1246 +               DPRINTK( "AFMT_S16_LE\n" );
1247 +               break;
1248 +
1249 +       case SNDRV_PCM_FORMAT_S16_BE:
1250 +               DPRINTK( "AFMT_S16_BE\n" );
1251 +               break;
1252 +
1253 +       case SNDRV_PCM_FORMAT_U16_LE:
1254 +               DPRINTK( "AFMT_U16_LE\n" );
1255 +               break;
1256 +       case SNDRV_PCM_FORMAT_U16_BE:
1257 +               DPRINTK( "AFMT_U16_BE\n" );
1258 +               break;
1259 +
1260 +       case SNDRV_PCM_FORMAT_S24_LE:
1261 +               DPRINTK( "AFMT_S24_LE\n" );
1262 +               break;
1263 +
1264 +       case SNDRV_PCM_FORMAT_S24_BE:
1265 +               DPRINTK( "AFMT_S24_BE\n" );
1266 +               break;
1267 +
1268 +       case SNDRV_PCM_FORMAT_U24_LE:
1269 +               DPRINTK( "AFMT_U24_LE\n" );
1270 +               break;
1271 +
1272 +       case SNDRV_PCM_FORMAT_U24_BE:
1273 +               DPRINTK( "AFMT_U24_BE\n" );
1274 +               break;
1275 +       case SNDRV_PCM_FORMAT_S32_LE:
1276 +               DPRINTK( "AFMT_S24_LE\n" );
1277 +               break;
1278 +
1279 +       case SNDRV_PCM_FORMAT_S32_BE:
1280 +               DPRINTK( "AFMT_S24_BE\n" );
1281 +               break;
1282 +
1283 +       case SNDRV_PCM_FORMAT_U32_LE:
1284 +               DPRINTK( "AFMT_U24_LE\n" );
1285 +               break;
1286 +
1287 +       case SNDRV_PCM_FORMAT_U32_BE:
1288 +               DPRINTK( "AFMT_U24_BE\n" );
1289 +               break;
1290 +       default:
1291 +               DPRINTK( "ep93xx_i2s_Unsupported Audio Format\n" );
1292 +               break;
1293 +    }
1294 +}
1295 +
1296 +static void audio_set_format( audio_stream_t * s, long val )
1297 +{
1298 +    DPRINTK( "ep93xx_i2s_audio_set_format enter.  Format requested (%d) %d ",
1299 +                               (int)val,SNDRV_PCM_FORMAT_S16_LE);
1300 +    print_audio_format( val );
1301 +
1302 +    switch( val ){
1303 +       case SNDRV_PCM_FORMAT_S8:
1304 +               s->audio_format = SNDRV_PCM_FORMAT_S8;
1305 +               s->audio_stream_bitwidth = 8;
1306 +               break;
1307 +
1308 +       case SNDRV_PCM_FORMAT_U8:
1309 +               s->audio_format = SNDRV_PCM_FORMAT_U8;
1310 +               s->audio_stream_bitwidth = 8;
1311 +               break;
1312 +
1313 +       case SNDRV_PCM_FORMAT_S16_LE:
1314 +       case SNDRV_PCM_FORMAT_S16_BE:
1315 +               s->audio_format = SNDRV_PCM_FORMAT_S16_LE;
1316 +               s->audio_stream_bitwidth = 16;
1317 +               break;
1318 +
1319 +       case SNDRV_PCM_FORMAT_U16_LE:
1320 +       case SNDRV_PCM_FORMAT_U16_BE:
1321 +               s->audio_format = SNDRV_PCM_FORMAT_U16_LE;
1322 +               s->audio_stream_bitwidth = 16;
1323 +               break;
1324 +
1325 +       case SNDRV_PCM_FORMAT_S24_LE:
1326 +       case SNDRV_PCM_FORMAT_S24_BE:
1327 +               s->audio_format = SNDRV_PCM_FORMAT_S24_LE;
1328 +               s->audio_stream_bitwidth = 24;
1329 +               break;
1330 +
1331 +       case SNDRV_PCM_FORMAT_U24_LE:
1332 +       case SNDRV_PCM_FORMAT_U24_BE:
1333 +               s->audio_format = SNDRV_PCM_FORMAT_U24_LE;
1334 +               s->audio_stream_bitwidth = 24;
1335 +               break;
1336 +
1337 +       case SNDRV_PCM_FORMAT_U32_LE:
1338 +       case SNDRV_PCM_FORMAT_U32_BE:
1339 +       case SNDRV_PCM_FORMAT_S32_LE:
1340 +       case SNDRV_PCM_FORMAT_S32_BE:
1341 +               s->audio_format = SNDRV_PCM_FORMAT_S32_LE;
1342 +               s->audio_stream_bitwidth = 32;
1343 +               break;
1344 +       default:
1345 +               DPRINTK( "ep93xx_i2s_Unsupported Audio Format\n" );
1346 +               break;
1347 +    }
1348 +
1349 +    DPRINTK( "ep93xx_i2s_audio_set_format EXIT format set to be (%d) ", (int)s->audio_format );
1350 +    print_audio_format( (long)s->audio_format );
1351 +}
1352 +
1353 +static __inline__ unsigned long copy_to_user_S24_LE
1354 +(
1355 +    audio_stream_t *stream,
1356 +    const char *to,
1357 +    unsigned long to_count
1358 +)
1359 +{
1360 +    int *dma_buffer_0 = (int *)stream->hwbuf[0];
1361 +    int *dma_buffer_1 = (int *)stream->hwbuf[1];
1362 +    int *dma_buffer_2 = (int *)stream->hwbuf[2];
1363 +
1364 +    int total_to_count = to_count;
1365 +    int *user_ptr = (int *)to; /* 32 bit user buffer */
1366 +    int count;
1367 +
1368 +    count = 8 * stream->dma_num_channels;
1369 +
1370 +    while (to_count > 0){
1371 +
1372 +       __put_user( (int)( *dma_buffer_0++ ), user_ptr++ );
1373 +       __put_user( (int)( *dma_buffer_0++ ), user_ptr++ );
1374 +
1375 +        if(stream->audio_channels_flag & CHANNEL_REAR ){
1376 +           __put_user( (int)( *dma_buffer_1++ ), user_ptr++ );
1377 +           __put_user( (int)( *dma_buffer_1++ ), user_ptr++ );
1378 +       }
1379 +
1380 +        if(stream->audio_channels_flag & CHANNEL_CENTER_LFE ){
1381 +           __put_user( (int)( *dma_buffer_2++ ), user_ptr++ );
1382 +           __put_user( (int)( *dma_buffer_2++ ), user_ptr++ );
1383 +       }
1384 +       to_count -= count;
1385 +    }
1386 +    return total_to_count;
1387 +}
1388 +
1389 +static __inline__ unsigned long copy_to_user_U24_LE
1390 +(
1391 +    audio_stream_t *stream,
1392 +    const char *to,
1393 +    unsigned long to_count
1394 +)
1395 +{
1396 +    int *dma_buffer_0 = (int *)stream->hwbuf[0];
1397 +    int *dma_buffer_1 = (int *)stream->hwbuf[1];
1398 +    int *dma_buffer_2 = (int *)stream->hwbuf[2];
1399 +
1400 +    int total_to_count = to_count;
1401 +    unsigned int * user_ptr = (unsigned int *)to;      /* 32 bit user buffer */
1402 +    int count;
1403 +
1404 +    count = 8 * stream->dma_num_channels;
1405 +
1406 +    while (to_count > 0){
1407 +       __put_user( ((unsigned int)( *dma_buffer_0++ )) ^ 0x8000, user_ptr++ );
1408 +       __put_user( ((unsigned int)( *dma_buffer_0++ )) ^ 0x8000, user_ptr++ );
1409 +
1410 +        if(stream->audio_channels_flag & CHANNEL_REAR ){
1411 +           __put_user( ((unsigned int)( *dma_buffer_1++ )) ^ 0x8000, user_ptr++ );
1412 +           __put_user( ((unsigned int)( *dma_buffer_1++ )) ^ 0x8000, user_ptr++ );
1413 +       }
1414 +
1415 +        if(stream->audio_channels_flag & CHANNEL_CENTER_LFE ){
1416 +           __put_user( ((unsigned int)( *dma_buffer_2++ )) ^ 0x8000, user_ptr++ );
1417 +           __put_user( ((unsigned int)( *dma_buffer_2++ )) ^ 0x8000, user_ptr++ );
1418 +       }
1419 +       to_count -= count;
1420 +    }
1421 +    return total_to_count;
1422 +}
1423 +
1424 +static __inline__ unsigned long copy_to_user_S16_LE
1425 +(
1426 +    audio_stream_t *stream,
1427 +    const char *to,
1428 +    unsigned long to_count
1429 +)
1430 +{
1431 +    int *dma_buffer_0 = (int *)stream->hwbuf[0];
1432 +    int *dma_buffer_1 = (int *)stream->hwbuf[1];
1433 +    int *dma_buffer_2 = (int *)stream->hwbuf[2];
1434 +    int total_to_count = to_count;
1435 +    short * user_ptr = (short *)to;    /* 16 bit user buffer */
1436 +    int count;
1437 +
1438 +    count = 4 * stream->dma_num_channels;
1439 +
1440 +    while (to_count > 0){
1441 +
1442 +       __put_user( (short)( *dma_buffer_0++ ), user_ptr++ );
1443 +       __put_user( (short)( *dma_buffer_0++ ), user_ptr++ );
1444 +
1445 +        if( stream->audio_channels_flag & CHANNEL_REAR ){
1446 +           __put_user( (short)( *dma_buffer_1++ ), user_ptr++ );
1447 +           __put_user( (short)( *dma_buffer_1++ ), user_ptr++ );
1448 +       }
1449 +
1450 +        if( stream->audio_channels_flag  & CHANNEL_CENTER_LFE ){
1451 +           __put_user( (short)( *dma_buffer_2++ ), user_ptr++ );
1452 +           __put_user( (short)( *dma_buffer_2++ ), user_ptr++ );
1453 +       }
1454 +       to_count -= count;
1455 +    }
1456 +    return total_to_count;
1457 +}
1458 +
1459 +static __inline__ unsigned long copy_to_user_U16_LE
1460 +(
1461 +    audio_stream_t *stream,
1462 +    const char *to,
1463 +    unsigned long to_count
1464 +)
1465 +{
1466 +    int *dma_buffer_0 = (int *)stream->hwbuf[0];
1467 +    int *dma_buffer_1 = (int *)stream->hwbuf[1];
1468 +    int *dma_buffer_2 = (int *)stream->hwbuf[2];
1469 +    int count;
1470 +    int total_to_count = to_count;
1471 +    short * user_ptr = (short *)to;    /* 16 bit user buffer */
1472 +
1473 +    count = 4 * stream->dma_num_channels;
1474 +
1475 +    while (to_count > 0){
1476 +
1477 +       __put_user( ((unsigned short)( *dma_buffer_0++ )) ^ 0x8000, user_ptr++ );
1478 +       __put_user( ((unsigned short)( *dma_buffer_0++ )) ^ 0x8000, user_ptr++ );
1479 +
1480 +        if(stream->audio_channels_flag & CHANNEL_REAR ){
1481 +           __put_user( ((unsigned short)( *dma_buffer_1++ )) ^ 0x8000, user_ptr++ );
1482 +           __put_user( ((unsigned short)( *dma_buffer_1++ )) ^ 0x8000, user_ptr++ );
1483 +       }
1484 +
1485 +        if(stream->audio_channels_flag & CHANNEL_CENTER_LFE ){
1486 +           __put_user( ((unsigned short)( *dma_buffer_2++ )) ^ 0x8000, user_ptr++ );
1487 +           __put_user( ((unsigned short)( *dma_buffer_2++ )) ^ 0x8000, user_ptr++ );
1488 +       }
1489 +       to_count -= count;
1490 +    }
1491 +    return total_to_count;
1492 +}
1493 +
1494 +static __inline__ unsigned long copy_to_user_S8
1495 +(
1496 +    audio_stream_t *stream,
1497 +    const char *to,
1498 +    unsigned long to_count
1499 +)
1500 +{
1501 +    char *dma_buffer_0 = (char *)stream->hwbuf[0];
1502 +    char *dma_buffer_1 = (char *)stream->hwbuf[1];
1503 +    char *dma_buffer_2 = (char *)stream->hwbuf[2];
1504 +    int count;
1505 +    int total_to_count = to_count;
1506 +    char * user_ptr = (char *)to;  /*  8 bit user buffer */
1507 +
1508 +    count = 2 * stream->dma_num_channels;
1509 +
1510 +    dma_buffer_0++;
1511 +    dma_buffer_1++;
1512 +    dma_buffer_2++;
1513 +
1514 +    while (to_count > 0){
1515 +
1516 +       __put_user( (char)( *dma_buffer_0 ), user_ptr++ );
1517 +       dma_buffer_0 += 4;
1518 +       __put_user( (char)( *dma_buffer_0 ), user_ptr++ );
1519 +       dma_buffer_0 += 4;
1520 +
1521 +        if(stream->audio_channels_flag & CHANNEL_REAR ){
1522 +           __put_user( (char)( *dma_buffer_1 ), user_ptr++ );
1523 +            dma_buffer_1 += 4;
1524 +           __put_user( (char)( *dma_buffer_1 ), user_ptr++ );
1525 +           dma_buffer_1 += 4;
1526 +       }
1527 +
1528 +        if(stream->audio_channels_flag & CHANNEL_CENTER_LFE ){
1529 +           __put_user( (char)( *dma_buffer_2 ), user_ptr++ );
1530 +           dma_buffer_2 += 4;
1531 +           __put_user( (char)( *dma_buffer_2 ), user_ptr++ );
1532 +           dma_buffer_2 += 4;
1533 +       }
1534 +       to_count -= count;
1535 +    }
1536 +    return total_to_count;
1537 +}
1538 +
1539 +static __inline__ unsigned long copy_to_user_U8
1540 +(
1541 +    audio_stream_t *stream,
1542 +    const char *to,
1543 +    unsigned long to_count
1544 +)
1545 +{
1546 +    char *dma_buffer_0 = (char *)stream->hwbuf[0];
1547 +    char *dma_buffer_1 = (char *)stream->hwbuf[1];
1548 +    char *dma_buffer_2 = (char *)stream->hwbuf[2];
1549 +    int count;
1550 +    int total_to_count = to_count;
1551 +    char * user_ptr = (char *)to;  /*  8 bit user buffer */
1552 +
1553 +    count = 2 * stream->dma_num_channels;
1554 +
1555 +    dma_buffer_0++;
1556 +    dma_buffer_1++;
1557 +    dma_buffer_2++;
1558 +
1559 +    while (to_count > 0){
1560 +
1561 +       __put_user( (char)( *dma_buffer_0 ) ^ 0x80, user_ptr++ );
1562 +       dma_buffer_0 += 4;
1563 +       __put_user( (char)( *dma_buffer_0 ) ^ 0x80, user_ptr++ );
1564 +       dma_buffer_0 += 4;
1565 +
1566 +        if(stream->audio_channels_flag & CHANNEL_REAR ){
1567 +           __put_user( (char)( *dma_buffer_1 ) ^ 0x80, user_ptr++ );
1568 +           dma_buffer_1 += 4;
1569 +           __put_user( (char)( *dma_buffer_1 ) ^ 0x80, user_ptr++ );
1570 +           dma_buffer_1 += 4;
1571 +       }
1572 +
1573 +        if(stream->audio_channels_flag & CHANNEL_CENTER_LFE ){
1574 +           __put_user( (char)( *dma_buffer_2 ) ^ 0x80, user_ptr++ );
1575 +           dma_buffer_2 += 4;
1576 +           __put_user( (char)( *dma_buffer_2 ) ^ 0x80, user_ptr++ );
1577 +           dma_buffer_2 += 4;
1578 +       }
1579 +       to_count -= count;
1580 +    }
1581 +    return total_to_count;
1582 +}
1583 +
1584 +
1585 +
1586 +
1587 +static __inline__ unsigned long copy_to_user_S16_LE_CM
1588 +(
1589 +    audio_stream_t *stream,
1590 +    const char *to,
1591 +    unsigned long to_count
1592 +)
1593 +{
1594 +    short *dma_buffer_0 = (short *)stream->hwbuf[0];
1595 +    int *dma_buffer_1 = (int *)stream->hwbuf[1];
1596 +    int *dma_buffer_2 = (int *)stream->hwbuf[2];
1597 +    int total_to_count = to_count;
1598 +    short * user_ptr = (short *)to;    /* 16 bit user buffer */
1599 +    int count;
1600 +
1601 +
1602 +    count = 4 * stream->dma_num_channels;
1603 +
1604 +    while (to_count > 0){
1605 +       if(stream->audio_num_channels == 2){
1606 +               __put_user( (short)( *dma_buffer_0++ ), user_ptr++ );
1607 +               __put_user( (short)( *dma_buffer_0++ ), user_ptr++ );
1608 +               to_count -= count;
1609 +       }
1610 +       else{
1611 +               dma_buffer_0++;
1612 +               __put_user( (short)( *dma_buffer_0++ ), user_ptr++ );
1613 +               to_count -= 2;
1614 +       }
1615 +
1616 +        if( stream->audio_channels_flag & CHANNEL_REAR ){
1617 +           __put_user( (short)( *dma_buffer_1++ ), user_ptr++ );
1618 +           __put_user( (short)( *dma_buffer_1++ ), user_ptr++ );
1619 +       }
1620 +
1621 +        if( stream->audio_channels_flag  & CHANNEL_CENTER_LFE ){
1622 +           __put_user( (short)( *dma_buffer_2++ ), user_ptr++ );
1623 +           __put_user( (short)( *dma_buffer_2++ ), user_ptr++ );
1624 +       }
1625 +       //to_count -= count;
1626 +    }
1627 +    return total_to_count;
1628 +}
1629 +
1630 +static __inline__ unsigned long copy_to_user_U16_LE_CM
1631 +(
1632 +    audio_stream_t *stream,
1633 +    const char *to,
1634 +    unsigned long to_count
1635 +)
1636 +{
1637 +    unsigned short *dma_buffer_0 = (unsigned short *)stream->hwbuf[0];
1638 +    int *dma_buffer_1 = (int *)stream->hwbuf[1];
1639 +    int *dma_buffer_2 = (int *)stream->hwbuf[2];
1640 +    int count;
1641 +    int total_to_count = to_count;
1642 +    unsigned short * user_ptr = (unsigned short *)to;  /* 16 bit user buffer */
1643 +
1644 +    count = 4 * stream->dma_num_channels;
1645 +
1646 +    while (to_count > 0){
1647 +
1648 +       if(stream->audio_num_channels == 2){
1649 +               __put_user( ((unsigned short)( *dma_buffer_0++ )) ^ 0x8000, user_ptr++ );
1650 +               __put_user( ((unsigned short)( *dma_buffer_0++ )) ^ 0x8000, user_ptr++ );
1651 +               to_count -= count;
1652 +       }
1653 +       else{
1654 +               dma_buffer_0++;
1655 +               __put_user( ((unsigned short)( *dma_buffer_0++ )) ^ 0x8000, user_ptr++ );
1656 +               to_count -= 2;
1657 +       }
1658 +
1659 +        if(stream->audio_channels_flag & CHANNEL_REAR ){
1660 +           __put_user( ((unsigned short)( *dma_buffer_1++ )) ^ 0x8000, user_ptr++ );
1661 +           __put_user( ((unsigned short)( *dma_buffer_1++ )) ^ 0x8000, user_ptr++ );
1662 +       }
1663 +
1664 +        if(stream->audio_channels_flag & CHANNEL_CENTER_LFE ){
1665 +           __put_user( ((unsigned short)( *dma_buffer_2++ )) ^ 0x8000, user_ptr++ );
1666 +           __put_user( ((unsigned short)( *dma_buffer_2++ )) ^ 0x8000, user_ptr++ );
1667 +       }
1668 +       //to_count -= count;
1669 +    }
1670 +    return total_to_count;
1671 +}
1672 +
1673 +static __inline__ unsigned long copy_to_user_S8_CM
1674 +(
1675 +    audio_stream_t *stream,
1676 +    const char *to,
1677 +    unsigned long to_count
1678 +)
1679 +{
1680 +    unsigned short *dma_buffer_0 = (unsigned short *)stream->hwbuf[0];
1681 +    char *dma_buffer_1 = (char *)stream->hwbuf[1];
1682 +    char *dma_buffer_2 = (char *)stream->hwbuf[2];
1683 +    int count;
1684 +    int total_to_count = to_count;
1685 +    char * user_ptr = (char *)to;  /*  8 bit user buffer */
1686 +
1687 +    count = 2 * stream->dma_num_channels;
1688 +
1689 +    dma_buffer_0++;
1690 +    dma_buffer_1++;
1691 +    dma_buffer_2++;
1692 +
1693 +    while (to_count > 0){
1694 +       if(stream->audio_num_channels == 2){
1695 +               __put_user( (char)( *dma_buffer_0++ >> 8), user_ptr++ );
1696 +               //dma_buffer_0 += 4;
1697 +               __put_user( (char)( *dma_buffer_0++ >> 8), user_ptr++ );
1698 +               //dma_buffer_0 += 4;
1699 +               to_count -= count;
1700 +       }
1701 +       else{
1702 +               dma_buffer_0++ ;
1703 +               __put_user( (char)( *dma_buffer_0++ >> 8), user_ptr++ );
1704 +
1705 +               to_count -= 1;
1706 +       }
1707 +        if(stream->audio_channels_flag & CHANNEL_REAR ){
1708 +           __put_user( (char)( *dma_buffer_1 ), user_ptr++ );
1709 +            dma_buffer_1 += 4;
1710 +           __put_user( (char)( *dma_buffer_1 ), user_ptr++ );
1711 +           dma_buffer_1 += 4;
1712 +       }
1713 +
1714 +        if(stream->audio_channels_flag & CHANNEL_CENTER_LFE ){
1715 +           __put_user( (char)( *dma_buffer_2 ), user_ptr++ );
1716 +           dma_buffer_2 += 4;
1717 +           __put_user( (char)( *dma_buffer_2 ), user_ptr++ );
1718 +           dma_buffer_2 += 4;
1719 +       }
1720 +       //to_count -= count;
1721 +    }
1722 +    return total_to_count;
1723 +}
1724 +
1725 +static __inline__ unsigned long copy_to_user_U8_CM
1726 +(
1727 +    audio_stream_t *stream,
1728 +    const char *to,
1729 +    unsigned long to_count
1730 +)
1731 +{
1732 +    unsigned short *dma_buffer_0 = (unsigned short *)stream->hwbuf[0];
1733 +    char *dma_buffer_1 = (char *)stream->hwbuf[1];
1734 +    char *dma_buffer_2 = (char *)stream->hwbuf[2];
1735 +    int count;
1736 +    int total_to_count = to_count;
1737 +    char * user_ptr = (char *)to;  /*  8 bit user buffer */
1738 +
1739 +    count = 2 * stream->dma_num_channels;
1740 +
1741 +    dma_buffer_0++;
1742 +    dma_buffer_1++;
1743 +    dma_buffer_2++;
1744 +
1745 +    while (to_count > 0){
1746 +       if(stream->audio_num_channels == 2){
1747 +               __put_user( (char)( *dma_buffer_0++  >>8) ^ 0x80, user_ptr++ );
1748 +               //dma_buffer_0 += 4;
1749 +               __put_user( (char)( *dma_buffer_0++  >>8) ^ 0x80, user_ptr++ );
1750 +               //dma_buffer_0 += 4;
1751 +               to_count -= count;
1752 +       }
1753 +       else{
1754 +               dma_buffer_0++;
1755 +               __put_user( (char)( *dma_buffer_0++  >>8) ^ 0x80, user_ptr++ );
1756 +               //dma_buffer_0 += 4;
1757 +               to_count--;
1758 +       }
1759 +
1760 +        if(stream->audio_channels_flag & CHANNEL_REAR ){
1761 +           __put_user( (char)( *dma_buffer_1 ) ^ 0x80, user_ptr++ );
1762 +           dma_buffer_1 += 4;
1763 +           __put_user( (char)( *dma_buffer_1 ) ^ 0x80, user_ptr++ );
1764 +           dma_buffer_1 += 4;
1765 +       }
1766 +
1767 +        if(stream->audio_channels_flag & CHANNEL_CENTER_LFE ){
1768 +           __put_user( (char)( *dma_buffer_2 ) ^ 0x80, user_ptr++ );
1769 +           dma_buffer_2 += 4;
1770 +           __put_user( (char)( *dma_buffer_2 ) ^ 0x80, user_ptr++ );
1771 +           dma_buffer_2 += 4;
1772 +       }
1773 +       //to_count -= count;
1774 +    }
1775 +    return total_to_count;
1776 +}
1777 +
1778 +static __inline__ unsigned long copy_to_user_U32
1779 +(
1780 +    audio_stream_t *stream,
1781 +    const char *to,
1782 +    unsigned long to_count
1783 +)
1784 +{
1785 +    char *dma_buffer_0 = (char *)stream->hwbuf[0];
1786 +
1787 +    if(__copy_to_user( (char *)to, dma_buffer_0, to_count))
1788 +    {
1789 +       return -EFAULT;
1790 +    }
1791 +    return to_count;
1792 +}
1793 +
1794 +static __inline__ int copy_to_user_with_conversion
1795 +(
1796 +    audio_stream_t *stream,
1797 +    const char *to,
1798 +    int toCount,
1799 +    int bCompactMode
1800 +)
1801 +{
1802 +    int ret = 0;
1803 +
1804 +    if( toCount == 0 ){
1805 +       DPRINTK("ep93xx_i2s_copy_to_user_with_conversion - nothing to copy!\n");
1806 +    }
1807 +
1808 +    if( bCompactMode == 1 ){
1809 +
1810 +        switch( stream->audio_format ){
1811 +
1812 +       case SNDRV_PCM_FORMAT_S8:
1813 +               ret = copy_to_user_S8_CM( stream, to, toCount );
1814 +               break;
1815 +
1816 +       case SNDRV_PCM_FORMAT_U8:
1817 +               ret = copy_to_user_U8_CM( stream, to, toCount );
1818 +               break;
1819 +
1820 +       case SNDRV_PCM_FORMAT_S16_LE:
1821 +               ret = copy_to_user_S16_LE_CM( stream, to, toCount );
1822 +               break;
1823 +
1824 +       case SNDRV_PCM_FORMAT_U16_LE:
1825 +               ret = copy_to_user_U16_LE_CM( stream, to, toCount );
1826 +               break;
1827 +
1828 +       case SNDRV_PCM_FORMAT_S24_LE:
1829 +               //ret = copy_to_user_S24_LE( stream, to, toCount );
1830 +               //break;
1831 +
1832 +       case SNDRV_PCM_FORMAT_U24_LE:
1833 +               //ret = copy_to_user_U24_LE( stream, to, toCount );
1834 +               //break;
1835 +
1836 +       case SNDRV_PCM_FORMAT_S32_LE:
1837 +        default:
1838 +                DPRINTK( "ep93xx_i2s copy to user unsupported audio format %x\n",stream->audio_format );
1839 +               break;
1840 +        }
1841 +
1842 +    }
1843 +    else{
1844 +
1845 +        switch( stream->audio_format ){
1846 +
1847 +       case SNDRV_PCM_FORMAT_S8:
1848 +               ret = copy_to_user_S8( stream, to, toCount );
1849 +               break;
1850 +
1851 +       case SNDRV_PCM_FORMAT_U8:
1852 +               ret = copy_to_user_U8( stream, to, toCount );
1853 +               break;
1854 +
1855 +       case SNDRV_PCM_FORMAT_S16_LE:
1856 +               ret = copy_to_user_S16_LE( stream, to, toCount );
1857 +               break;
1858 +
1859 +       case SNDRV_PCM_FORMAT_U16_LE:
1860 +               ret = copy_to_user_U16_LE( stream, to, toCount );
1861 +               break;
1862 +
1863 +       case SNDRV_PCM_FORMAT_S24_LE:
1864 +               //ret = copy_to_user_S24_LE( stream, to, toCount );
1865 +               //break;
1866 +
1867 +       case SNDRV_PCM_FORMAT_U24_LE:
1868 +               //ret = copy_to_user_U24_LE( stream, to, toCount );
1869 +               //break;
1870 +               DPRINTK( "ep93xx_i2s copy to user unsupported audio format %x\n",stream->audio_format );
1871 +               break;
1872 +
1873 +       case SNDRV_PCM_FORMAT_S32_LE:
1874 +
1875 +               //__copy_to_user( (char *)to, from, toCount);
1876 +               ret = copy_to_user_U32( stream, to, toCount );
1877 +               break;
1878 +        default:
1879 +                DPRINTK( "ep93xx_i2s copy to user unsupported audio format\n" );
1880 +               break;
1881 +        }
1882 +
1883 +    }
1884 +    return ret;
1885 +}
1886 +
1887 +static __inline__ int copy_from_user_S24_LE
1888 +(
1889 +    audio_stream_t *stream,
1890 +    const char *from,
1891 +    int toCount
1892 +)
1893 +{
1894 +    int *dma_buffer_0 = (int *)stream->hwbuf[0];
1895 +    int *dma_buffer_1 = (int *)stream->hwbuf[1];
1896 +    int *dma_buffer_2 = (int *)stream->hwbuf[2];
1897 +    int count;
1898 +
1899 +    unsigned int * user_buffer = (unsigned int *)from;
1900 +    unsigned int data;
1901 +
1902 +    int toCount0 = toCount;
1903 +    count = 8 * stream->dma_num_channels;
1904 +
1905 +    while (toCount > 0){
1906 +
1907 +       __get_user(data, user_buffer++);
1908 +       *dma_buffer_0++ = (unsigned int)data;
1909 +       __get_user(data, user_buffer++);
1910 +       *dma_buffer_0++ = (unsigned int)data;
1911 +
1912 +        if(stream->audio_channels_flag & CHANNEL_REAR ){
1913 +           __get_user(data, user_buffer++);
1914 +           *dma_buffer_1++ = (unsigned int)data;
1915 +           __get_user(data, user_buffer++);
1916 +           *dma_buffer_1++ = (unsigned int)data;
1917 +       }
1918 +
1919 +        if(stream->audio_channels_flag & CHANNEL_CENTER_LFE ){
1920 +           __get_user(data, user_buffer++);
1921 +           *dma_buffer_2++ = (unsigned int)data;
1922 +           __get_user(data, user_buffer++);
1923 +           *dma_buffer_2++ = (unsigned int)data;
1924 +        }
1925 +       toCount -= count;
1926 +    }
1927 +    return toCount0 / 2;
1928 +}
1929 +
1930 +static __inline__ int copy_from_user_U24_LE
1931 +(
1932 +    audio_stream_t *stream,
1933 +    const char *from,
1934 +    int toCount
1935 +)
1936 +{
1937 +    int *dma_buffer_0 = (int *)stream->hwbuf[0];
1938 +    int *dma_buffer_1 = (int *)stream->hwbuf[1];
1939 +    int *dma_buffer_2 = (int *)stream->hwbuf[2];
1940 +    int count;
1941 +    unsigned int * user_buffer = (unsigned int *)from;
1942 +    unsigned int data;
1943 +
1944 +    int toCount0 = toCount;
1945 +    count = 8 * stream->dma_num_channels;
1946 +
1947 +    while (toCount > 0){
1948 +
1949 +       __get_user(data, user_buffer++);
1950 +       *dma_buffer_0++ = ((unsigned int)data ^ 0x8000);
1951 +       __get_user(data, user_buffer++);
1952 +       *dma_buffer_0++ = ((unsigned int)data ^ 0x8000);
1953 +
1954 +        if(stream->audio_channels_flag & CHANNEL_REAR ){
1955 +           __get_user(data, user_buffer++);
1956 +           *dma_buffer_1++ = ((unsigned int)data ^ 0x8000);
1957 +           __get_user(data, user_buffer++);
1958 +           *dma_buffer_1++ = ((unsigned int)data ^ 0x8000);
1959 +       }
1960 +
1961 +        if(stream->audio_channels_flag & CHANNEL_CENTER_LFE ){
1962 +           __get_user(data, user_buffer++);
1963 +           *dma_buffer_2++ = ((unsigned int)data ^ 0x8000);
1964 +           __get_user(data, user_buffer++);
1965 +           *dma_buffer_2++ = ((unsigned int)data ^ 0x8000);
1966 +       }
1967 +       toCount -= count;
1968 +    }
1969 +    return toCount0 / 2;
1970 +}
1971 +
1972 +static __inline__ int copy_from_user_S16_LE
1973 +(
1974 +       audio_stream_t *stream,
1975 +       const char *from,
1976 +       int toCount
1977 +)
1978 +{
1979 +    int *dma_buffer_0 = (int *)stream->hwbuf[0];
1980 +    int *dma_buffer_1 = (int *)stream->hwbuf[1];
1981 +    int *dma_buffer_2 = (int *)stream->hwbuf[2];
1982 +    unsigned short *user_buffer = (unsigned short *)from;
1983 +    unsigned short data;
1984 +
1985 +    int toCount0 = toCount;
1986 +    int count;
1987 +    count = 8 * stream->dma_num_channels;
1988 +
1989 +    while (toCount > 0){
1990 +
1991 +       __get_user(data, user_buffer++);
1992 +       *dma_buffer_0++ = data;
1993 +       if(stream->audio_num_channels == 2){
1994 +           __get_user(data, user_buffer++);
1995 +       }
1996 +       *dma_buffer_0++ = data;
1997 +
1998 +        if(stream->audio_channels_flag & CHANNEL_REAR ){
1999 +           __get_user(data, user_buffer++);
2000 +           *dma_buffer_1++ = data;
2001 +           __get_user(data, user_buffer++);
2002 +           *dma_buffer_1++ = data;
2003 +       }
2004 +
2005 +        if(stream->audio_channels_flag & CHANNEL_CENTER_LFE ){
2006 +           __get_user(data, user_buffer++);
2007 +           *dma_buffer_2++ = data;
2008 +           __get_user(data, user_buffer++);
2009 +           *dma_buffer_2++ = data;
2010 +       }
2011 +       toCount -= count;
2012 +    }
2013 +
2014 +    if(stream->audio_num_channels == 1){
2015 +       return toCount0 / 4;
2016 +    }
2017 +    return toCount0 / 2;
2018 +}
2019 +
2020 +static __inline__ int copy_from_user_U16_LE
2021 +(
2022 +    audio_stream_t *stream,
2023 +    const char *from,
2024 +    int toCount
2025 +)
2026 +{
2027 +    int *dma_buffer_0 = (int *)stream->hwbuf[0];
2028 +    int *dma_buffer_1 = (int *)stream->hwbuf[1];
2029 +    int *dma_buffer_2 = (int *)stream->hwbuf[2];
2030 +    int count;
2031 +    unsigned short * user_buffer = (unsigned short *)from;
2032 +    unsigned short data;
2033 +
2034 +    int toCount0 = toCount;
2035 +    count = 8 * stream->dma_num_channels;
2036 +
2037 +    while (toCount > 0){
2038 +
2039 +       __get_user(data, user_buffer++);
2040 +       *dma_buffer_0++ = ((unsigned int)data ^ 0x8000);
2041 +       if(stream->audio_num_channels == 2){
2042 +           __get_user(data, user_buffer++);
2043 +       }
2044 +       *dma_buffer_0++ = ((unsigned int)data ^ 0x8000);
2045 +
2046 +        if(stream->audio_channels_flag & CHANNEL_REAR ){
2047 +           __get_user(data, user_buffer++);
2048 +           *dma_buffer_1++ = ((unsigned int)data ^ 0x8000);
2049 +           __get_user(data, user_buffer++);
2050 +            *dma_buffer_1++ = ((unsigned int)data ^ 0x8000);
2051 +       }
2052 +
2053 +        if(stream->audio_channels_flag & CHANNEL_CENTER_LFE ){
2054 +           __get_user(data, user_buffer++);
2055 +           *dma_buffer_2++ = ((unsigned int)data ^ 0x8000);
2056 +           __get_user(data, user_buffer++);
2057 +           *dma_buffer_2++ = ((unsigned int)data ^ 0x8000);
2058 +       }
2059 +       toCount -= count;
2060 +    }
2061 +
2062 +    if(stream->audio_num_channels == 1){
2063 +        return toCount0 / 4;
2064 +    }
2065 +    return toCount0 / 2;
2066 +}
2067 +
2068 +static __inline__ int copy_from_user_S8
2069 +(
2070 +    audio_stream_t *stream,
2071 +    const char *from,
2072 +    int toCount
2073 +)
2074 +{
2075 +    char *dma_buffer_0 = (char *)stream->hwbuf[0];
2076 +    char *dma_buffer_1 = (char *)stream->hwbuf[1];
2077 +    char *dma_buffer_2 = (char *)stream->hwbuf[2];
2078 +    int count;
2079 +    unsigned char * user_buffer = (unsigned char *)from;
2080 +    unsigned char data;
2081 +
2082 +    int toCount0 = toCount;
2083 +    count = 8 * stream->dma_num_channels;
2084 +
2085 +    dma_buffer_0++;
2086 +    dma_buffer_1++;
2087 +    dma_buffer_2++;
2088 +
2089 +    while (toCount > 0){
2090 +       __get_user(data, user_buffer++);
2091 +       *dma_buffer_0 = data;
2092 +       dma_buffer_0 += 4;
2093 +       if(stream->audio_num_channels == 2){
2094 +           __get_user(data, user_buffer++);
2095 +       }
2096 +       *dma_buffer_0 = data;
2097 +       dma_buffer_0 += 4;
2098 +
2099 +        if(stream->audio_channels_flag & CHANNEL_REAR ){
2100 +           __get_user(data, user_buffer++);
2101 +           *dma_buffer_1 = data;
2102 +            dma_buffer_1 += 4;
2103 +           __get_user(data, user_buffer++);
2104 +            *dma_buffer_1 = data;
2105 +           dma_buffer_1 += 4;
2106 +       }
2107 +
2108 +        if(stream->audio_channels_flag & CHANNEL_CENTER_LFE ){
2109 +           __get_user(data, user_buffer++);
2110 +           *dma_buffer_2 = data;
2111 +           dma_buffer_2 += 4;
2112 +           __get_user(data, user_buffer++);
2113 +           *dma_buffer_2 = data;
2114 +            dma_buffer_2 += 4;
2115 +       }
2116 +       toCount -= count;
2117 +    }
2118 +
2119 +    if(stream->audio_num_channels == 1){
2120 +       return toCount0 / 8;
2121 +    }
2122 +    return toCount0 / 4;
2123 +}
2124 +
2125 +static __inline__ int copy_from_user_U8
2126 +(
2127 +    audio_stream_t *stream,
2128 +    const char *from,
2129 +    int toCount
2130 +)
2131 +{
2132 +    char *dma_buffer_0 = (char *)stream->hwbuf[0];
2133 +    char *dma_buffer_1 = (char *)stream->hwbuf[1];
2134 +    char *dma_buffer_2 = (char *)stream->hwbuf[2];
2135 +    int count;
2136 +    unsigned char *user_buffer = (unsigned char *)from;
2137 +    unsigned char data;
2138 +
2139 +    int toCount0 = toCount;
2140 +    count = 8 * stream->dma_num_channels;
2141 +
2142 +    dma_buffer_0 ++;
2143 +    dma_buffer_1 ++;
2144 +    dma_buffer_2 ++;
2145 +
2146 +    while (toCount > 0){
2147 +
2148 +       __get_user(data, user_buffer++);
2149 +       *dma_buffer_0 = ((unsigned char)data ^ 0x80);
2150 +       dma_buffer_0 += 4;
2151 +       if(stream->audio_num_channels == 2){
2152 +           __get_user(data, user_buffer++);
2153 +       }
2154 +       *dma_buffer_0 = ((unsigned char)data ^ 0x80);
2155 +       dma_buffer_0 += 4;
2156 +
2157 +        if(stream->audio_channels_flag & CHANNEL_REAR ){
2158 +           __get_user(data, user_buffer++);
2159 +           *dma_buffer_1 = ((unsigned char)data ^ 0x80);
2160 +            dma_buffer_1 += 4;
2161 +           __get_user(data, user_buffer++);
2162 +            *dma_buffer_1 = ((unsigned char)data ^ 0x80);
2163 +            dma_buffer_1 += 4;
2164 +       }
2165 +
2166 +        if(stream->audio_channels_flag & CHANNEL_CENTER_LFE ){
2167 +           __get_user(data, user_buffer++);
2168 +           *dma_buffer_2 = ((unsigned char)data ^ 0x80);
2169 +           dma_buffer_2 += 4;
2170 +           __get_user(data, user_buffer++);
2171 +           *dma_buffer_2 = ((unsigned char)data ^ 0x80);
2172 +            dma_buffer_2 += 4;
2173 +       }
2174 +       toCount -= count;
2175 +    }
2176 +
2177 +    if(stream->audio_num_channels == 1){
2178 +       return toCount0 / 8;
2179 +    }
2180 +    return toCount0 / 4;
2181 +}
2182 +
2183 +static __inline__ int copy_from_user_S16_LE_CM
2184 +(
2185 +       audio_stream_t *stream,
2186 +       const char *from,
2187 +       int toCount
2188 +)
2189 +{
2190 +    unsigned int *dma_buffer_0 = (int *)stream->hwbuf[0];
2191 +    unsigned int *dma_buffer_1 = (int *)stream->hwbuf[1];
2192 +    unsigned int *dma_buffer_2 = (int *)stream->hwbuf[2];
2193 +    unsigned short *user_buffer = (unsigned short *)from;
2194 +    short data;
2195 +    unsigned int val;
2196 +    int toCount0 = toCount;
2197 +    int count;
2198 +    count = 4 * stream->dma_num_channels;
2199 +
2200 +       //printk("count=%x tocount\n",count,toCount);
2201 +    while (toCount > 0){
2202 +
2203 +       __get_user(data, user_buffer++);
2204 +       //*dma_buffer_0++ = data;
2205 +       val = (unsigned int)data & 0x0000ffff;
2206 +       if(stream->audio_num_channels == 2){
2207 +           __get_user(data, user_buffer++);
2208 +        }
2209 +       *dma_buffer_0++ = ((unsigned int)data << 16) | val;
2210 +
2211 +        if(stream->audio_channels_flag & CHANNEL_REAR ){
2212 +           __get_user(data, user_buffer++);
2213 +           //*dma_buffer_1++ = data;
2214 +           val = (unsigned int)data & 0x0000ffff;
2215 +           __get_user(data, user_buffer++);
2216 +           *dma_buffer_1++ = ((unsigned int)data << 16) | val;
2217 +       }
2218 +
2219 +        if(stream->audio_channels_flag & CHANNEL_CENTER_LFE ){
2220 +           __get_user(data, user_buffer++);
2221 +           //*dma_buffer_2++ = data;
2222 +           val = (unsigned int)data & 0x0000ffff;
2223 +           __get_user(data, user_buffer++);
2224 +           *dma_buffer_2++ = ((unsigned int)data << 16) | val;
2225 +       }
2226 +       toCount -= count;
2227 +    }
2228 +
2229 +    if(stream->audio_num_channels == 1){
2230 +        return toCount0 /2 ;
2231 +    }
2232 +
2233 +    return toCount0 ;
2234 +}
2235 +
2236 +static __inline__ int copy_from_user_U16_LE_CM
2237 +(
2238 +    audio_stream_t *stream,
2239 +    const char *from,
2240 +    int toCount
2241 +)
2242 +{
2243 +    int *dma_buffer_0 = (int *)stream->hwbuf[0];
2244 +    int *dma_buffer_1 = (int *)stream->hwbuf[1];
2245 +    int *dma_buffer_2 = (int *)stream->hwbuf[2];
2246 +    int count;
2247 +    unsigned short * user_buffer = (unsigned short *)from;
2248 +    unsigned short data;
2249 +    unsigned int val;
2250 +    int toCount0 = toCount;
2251 +    count = 4 * stream->dma_num_channels;
2252 +
2253 +    while (toCount > 0){
2254 +
2255 +       __get_user(data, user_buffer++);
2256 +       //*dma_buffer_0++ = ((unsigned int)data ^ 0x8000);
2257 +       val = (unsigned int)data & 0x0000ffff;
2258 +       if(stream->audio_num_channels == 2){
2259 +           __get_user(data, user_buffer++);
2260 +        }
2261 +       //*dma_buffer_0++ = ((unsigned int)data ^ 0x8000);
2262 +        *dma_buffer_0++ = (((unsigned int)data << 16) | val) ^ 0x80008000;
2263 +
2264 +        if(stream->audio_channels_flag & CHANNEL_REAR ){
2265 +           __get_user(data, user_buffer++);
2266 +           //*dma_buffer_1++ = ((unsigned int)data ^ 0x8000);
2267 +           val = (unsigned int)data & 0x0000ffff;
2268 +           __get_user(data, user_buffer++);
2269 +            //*dma_buffer_1++ = ((unsigned int)data ^ 0x8000);
2270 +            *dma_buffer_1++ = (((unsigned int)data << 16) | val) ^ 0x80008000;
2271 +       }
2272 +
2273 +        if(stream->audio_channels_flag & CHANNEL_CENTER_LFE ){
2274 +           __get_user(data, user_buffer++);
2275 +           //*dma_buffer_2++ = ((unsigned int)data ^ 0x8000);
2276 +           val = (unsigned int)data & 0x0000ffff;
2277 +           __get_user(data, user_buffer++);
2278 +           //*dma_buffer_2++ = ((unsigned int)data ^ 0x8000);
2279 +           *dma_buffer_2++ = (((unsigned int)data << 16) | val) ^ 0x80008000;
2280 +       }
2281 +       toCount -= count;
2282 +    }
2283 +
2284 +    if(stream->audio_num_channels == 1){
2285 +        return toCount0/2;
2286 +    }
2287 +    return toCount0 ;
2288 +}
2289 +
2290 +static __inline__ int copy_from_user_S8_CM
2291 +(
2292 +    audio_stream_t *stream,
2293 +    const char *from,
2294 +    int toCount
2295 +)
2296 +{
2297 +    char *dma_buffer_0 = (char *)stream->hwbuf[0];
2298 +    char *dma_buffer_1 = (char *)stream->hwbuf[1];
2299 +    char *dma_buffer_2 = (char *)stream->hwbuf[2];
2300 +    int count;
2301 +    unsigned char * user_buffer = (unsigned char *)from;
2302 +    unsigned char data;
2303 +    int toCount0 = toCount;
2304 +    count = 4 * stream->dma_num_channels;
2305 +
2306 +    dma_buffer_0++;
2307 +    dma_buffer_1++;
2308 +    dma_buffer_2++;
2309 +
2310 +    while (toCount > 0){
2311 +       __get_user(data, user_buffer++);
2312 +       *dma_buffer_0 = data;
2313 +       *(dma_buffer_0 +1 ) = 0;
2314 +       dma_buffer_0 += 2;
2315 +
2316 +       if(stream->audio_num_channels == 2){
2317 +           __get_user(data, user_buffer++);
2318 +       }
2319 +       *dma_buffer_0 = data;
2320 +       *(dma_buffer_0 +1 ) = 0;
2321 +       dma_buffer_0 += 2;
2322 +
2323 +        if(stream->audio_channels_flag & CHANNEL_REAR ){
2324 +           __get_user(data, user_buffer++);
2325 +           *dma_buffer_1 = data;
2326 +           dma_buffer_1 += 2;
2327 +           __get_user(data, user_buffer++);
2328 +            *dma_buffer_1 = data;
2329 +            dma_buffer_1 += 2;
2330 +       }
2331 +
2332 +        if(stream->audio_channels_flag & CHANNEL_CENTER_LFE ){
2333 +           __get_user(data, user_buffer++);
2334 +           *dma_buffer_2 = data;
2335 +           dma_buffer_2 += 2;
2336 +           __get_user(data, user_buffer++);
2337 +           *dma_buffer_2 = data;
2338 +           dma_buffer_2 += 2;
2339 +       }
2340 +       toCount -= count;
2341 +    }
2342 +
2343 +    if(stream->audio_num_channels == 1){
2344 +        return toCount0 / 4;
2345 +    }
2346 +
2347 +    return toCount0 / 2;
2348 +}
2349 +
2350 +static __inline__ int copy_from_user_U8_CM
2351 +(
2352 +    audio_stream_t *stream,
2353 +    const char *from,
2354 +    int toCount
2355 +)
2356 +{
2357 +    unsigned char *dma_buffer_0 = (unsigned char *)stream->hwbuf[0];
2358 +    unsigned char *dma_buffer_1 = (unsigned char *)stream->hwbuf[1];
2359 +    unsigned char *dma_buffer_2 = (unsigned char *)stream->hwbuf[2];
2360 +    int count;
2361 +    unsigned char *user_buffer = (unsigned char *)from;
2362 +    unsigned char data;
2363 +
2364 +    int toCount0 = toCount;
2365 +    count = 4 * stream->dma_num_channels;
2366 +
2367 +    dma_buffer_0 ++;
2368 +    dma_buffer_1 ++;
2369 +    dma_buffer_2 ++;
2370 +
2371 +    while (toCount > 0){
2372 +
2373 +       __get_user(data, user_buffer++);
2374 +       *dma_buffer_0 = ((unsigned char)data ^ 0x80);
2375 +       *(dma_buffer_0 +1 ) = 0;
2376 +       dma_buffer_0 += 2;
2377 +
2378 +       if(stream->audio_num_channels == 2){
2379 +           __get_user(data, user_buffer++);
2380 +       }
2381 +       *dma_buffer_0 = ((unsigned char)data ^ 0x80);
2382 +       *(dma_buffer_0 +1 ) = 0;
2383 +       dma_buffer_0 += 2;
2384 +
2385 +
2386 +        if(stream->audio_channels_flag & CHANNEL_REAR ){
2387 +           __get_user(data, user_buffer++);
2388 +           *dma_buffer_1 = ((unsigned char)data ^ 0x80);
2389 +           dma_buffer_1 += 2;
2390 +           __get_user(data, user_buffer++);
2391 +            *dma_buffer_1 = ((unsigned char)data ^ 0x80);
2392 +            dma_buffer_1 += 2;
2393 +       }
2394 +
2395 +        if(stream->audio_channels_flag & CHANNEL_CENTER_LFE ){
2396 +           __get_user(data, user_buffer++);
2397 +           *dma_buffer_2 = ((unsigned char)data ^ 0x80);
2398 +           dma_buffer_2 += 2;
2399 +           __get_user(data, user_buffer++);
2400 +           *dma_buffer_2 = ((unsigned char)data ^ 0x80);
2401 +            dma_buffer_2 += 2;
2402 +       }
2403 +       toCount -= count;
2404 +    }
2405 +
2406 +    if(stream->audio_num_channels == 1){
2407 +        return toCount0 / 4;
2408 +    }
2409 +
2410 +    return toCount0 / 2;
2411 +}
2412 +
2413 +static int copy_from_user_U32
2414 +(
2415 +       audio_stream_t *stream,
2416 +       const char *from,
2417 +       int toCount
2418 +)
2419 +{
2420 +    char *dma_buffer_0 = (char *)stream->hwbuf[0];
2421 +
2422 +    if (copy_from_user( (char *)dma_buffer_0, from, toCount))
2423 +    {
2424 +       return -EFAULT;
2425 +    }
2426 +
2427 +    return toCount;
2428 +
2429 +}
2430 +
2431 +/*
2432 + * Returns negative for error
2433 + * Returns # of bytes transferred out of the from buffer
2434 + * for success.
2435 + */
2436 +static __inline__ int copy_from_user_with_conversion
2437 +(
2438 +    audio_stream_t *stream,
2439 +    const char *from,
2440 +    int toCount,
2441 +    int bCompactMode
2442 +)
2443 +{
2444 +    int ret = 0;
2445 +//    DPRINTK("copy_from_user_with_conversion\n");
2446 +    if( toCount == 0 ){
2447 +       DPRINTK("ep93xx_i2s_copy_from_user_with_conversion - nothing to copy!\n");
2448 +    }
2449 +
2450 +    if( bCompactMode == 1){
2451 +
2452 +       switch( stream->audio_format ){
2453 +
2454 +               case SNDRV_PCM_FORMAT_S8:
2455 +                       DPRINTK("SNDRV_PCM_FORMAT_S8 CM\n");
2456 +                       ret = copy_from_user_S8_CM( stream, from, toCount );
2457 +                       break;
2458 +
2459 +               case SNDRV_PCM_FORMAT_U8:
2460 +                       DPRINTK("SNDRV_PCM_FORMAT_U8 CM\n");
2461 +                       ret = copy_from_user_U8_CM( stream, from, toCount );
2462 +                       break;
2463 +
2464 +               case SNDRV_PCM_FORMAT_S16_LE:
2465 +                       DPRINTK("SNDRV_PCM_FORMAT_S16_LE CM\n");
2466 +                       ret = copy_from_user_S16_LE_CM( stream, from, toCount );
2467 +                       break;
2468 +
2469 +               case SNDRV_PCM_FORMAT_U16_LE:
2470 +                       DPRINTK("SNDRV_PCM_FORMAT_U16_LE CM\n");
2471 +                       ret = copy_from_user_U16_LE_CM( stream, from, toCount );
2472 +                       break;
2473 +
2474 +               case SNDRV_PCM_FORMAT_S24_LE:
2475 +                       DPRINTK("SNDRV_PCM_FORMAT_S24_LE CM\n");
2476 +                       //ret = copy_from_user_S24_LE( stream, from, toCount );
2477 +                       //break;
2478 +
2479 +               case SNDRV_PCM_FORMAT_U24_LE:
2480 +                       DPRINTK("SNDRV_PCM_FORMAT_U24_LE CM\n");
2481 +                       //ret = copy_from_user_U24_LE( stream, from, toCount );
2482 +                       //break;
2483 +               case SNDRV_PCM_FORMAT_S32_LE:
2484 +                       DPRINTK("SNDRV_PCM_FORMAT_S32_LE CM\n");
2485 +                       //break;
2486 +               default:
2487 +                       DPRINTK( "ep93xx_i2s copy from user unsupported audio format\n" );
2488 +                       break;
2489 +       }
2490 +    }
2491 +    else{
2492 +        switch( stream->audio_format ){
2493 +
2494 +       case SNDRV_PCM_FORMAT_S8:
2495 +               DPRINTK("SNDRV_PCM_FORMAT_S8\n");
2496 +               ret = copy_from_user_S8( stream, from, toCount );
2497 +               break;
2498 +
2499 +       case SNDRV_PCM_FORMAT_U8:
2500 +               DPRINTK("SNDRV_PCM_FORMAT_U8\n");
2501 +               ret = copy_from_user_U8( stream, from, toCount );
2502 +               break;
2503 +
2504 +       case SNDRV_PCM_FORMAT_S16_LE:
2505 +               DPRINTK("SNDRV_PCM_FORMAT_S16_LE\n");
2506 +               ret = copy_from_user_S16_LE( stream, from, toCount );
2507 +               break;
2508 +
2509 +       case SNDRV_PCM_FORMAT_U16_LE:
2510 +               DPRINTK("SNDRV_PCM_FORMAT_U16_LE\n");
2511 +               ret = copy_from_user_U16_LE( stream, from, toCount );
2512 +               break;
2513 +
2514 +       case SNDRV_PCM_FORMAT_S24_LE:
2515 +               DPRINTK("SNDRV_PCM_FORMAT_S24_LE\n");
2516 +               //ret = copy_from_user_S24_LE( stream, from, toCount );
2517 +               //break;
2518 +
2519 +       case SNDRV_PCM_FORMAT_U24_LE:
2520 +               DPRINTK("SNDRV_PCM_FORMAT_U24_LE\n");
2521 +               //ret = copy_from_user_U24_LE( stream, from, toCount );
2522 +               //break;
2523 +               DPRINTK( "ep93xx_i2s copy from user unsupported audio format\n" );
2524 +               break;
2525 +       case SNDRV_PCM_FORMAT_S32_LE:
2526 +               DPRINTK("SNDRV_PCM_FORMAT_S32_LE\n");
2527 +               ret = copy_from_user_U32( stream, from, toCount );
2528 +               break;
2529 +        default:
2530 +                DPRINTK( "ep93xx_i2s copy from user unsupported audio format\n" );
2531 +               break;
2532 +       }
2533 +    }
2534 +
2535 +    return ret;
2536 +}
2537 +
2538 +
2539 +
2540 +/*
2541 + *  For audio playback, we convert samples of arbitrary format to be 32 bit
2542 + *  for our hardware. We're scaling a user buffer to a dma buffer.  So when
2543 + *  report byte counts, we scale them acording to the ratio of DMA sample
2544 + *  size to user buffer sample size.  When we report # of DMA fragments,
2545 + *  we don't scale that.  So:
2546 + *
2547 + *  Also adjust the size and number of dma fragments if sample size changed.
2548 + *
2549 + *  Input format       Input sample     Output sample size    ratio (out:in)
2550 + *  bits   channels    size (bytes)       CM   non-CM          CM   non-CM
2551 + *   8      stereo         2              4      8            2:1   4:1
2552 + *   16     stereo         4              4      8            1:1   2:1
2553 + *   24     stereo         6              4      8             X    8:6 not a real case
2554 + *
2555 + */
2556 +static void snd_ep93xx_dma2usr_ratio( audio_stream_t * stream,int bCompactMode )
2557 +{
2558 +    unsigned int dma_sample_size, user_sample_size;
2559 +
2560 +    if(bCompactMode == 1){
2561 +       dma_sample_size = 4;    /* each stereo sample is 2 * 32 bits */
2562 +    }
2563 +    else{
2564 +       dma_sample_size = 8;
2565 +    }
2566 +
2567 +    // If stereo 16 bit, user sample is 4 bytes.
2568 +    // If stereo  8 bit, user sample is 2 bytes.
2569 +    if(stream->audio_num_channels == 1){
2570 +       user_sample_size = stream->audio_stream_bitwidth / 8;
2571 +    }
2572 +    else{
2573 +       user_sample_size = stream->audio_stream_bitwidth / 4;
2574 +    }
2575 +
2576 +    stream->dma2usr_ratio = dma_sample_size / user_sample_size;
2577 +}
2578 +
2579 +/*---------------------------------------------------------------------------------------------*/
2580 +
2581 +static int snd_ep93xx_dma_free(struct snd_pcm_substream *substream ){
2582 +
2583 +
2584 +    audio_state_t *state = substream->private_data;
2585 +    audio_stream_t *stream = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
2586 +                              state->output_stream:state->input_stream;
2587 +    int i;
2588 +
2589 +
2590 +    DPRINTK("snd_ep93xx_dma_free - enter\n");
2591 +    for( i = 0 ; i < stream->dma_num_channels ;i++ ){
2592 +       ep93xx_dma_free( stream->dmahandles[i] );
2593 +    }
2594 +    DPRINTK("snd_ep93xx_dma_free - exit\n");
2595 +    return 0;
2596 +}
2597 +
2598 +static int snd_ep93xx_dma_config(struct snd_pcm_substream *substream ){
2599 +
2600 +    audio_state_t *state = substream->private_data;
2601 +    audio_stream_t *stream = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
2602 +                               state->output_stream:state->input_stream;
2603 +    int i,err = 0;
2604 +
2605 +    DPRINTK("snd_ep93xx_dma_config - enter\n");
2606 +
2607 +    for( i = 0 ; i < stream->dma_num_channels ;i++ ){
2608 +
2609 +        err = ep93xx_dma_request(&stream->dmahandles[i],
2610 +                               stream->devicename,
2611 +                               (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
2612 +                               state->output_dma[i]:state->input_dma[i] );
2613 +        if (err){
2614 +           printk("snd_ep93xx_dma_config - exit ERROR dma request failed\n");
2615 +           return err;
2616 +        }
2617 +       err = ep93xx_dma_config( stream->dmahandles[i],
2618 +                               IGNORE_CHANNEL_ERROR,
2619 +                               0,
2620 +                               (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
2621 +                               snd_ep93xx_dma_tx_callback:snd_ep93xx_dma_rx_callback,
2622 +                               (unsigned int)substream );
2623 +        if (err){
2624 +           printk("snd_ep93xx_dma_config - exit ERROR dma request failed\n");
2625 +           return err;
2626 +       }
2627 +    }
2628 +
2629 +    DPRINTK("snd_ep93xx_dma_config - enter\n");
2630 +    return err;
2631 +}
2632 +
2633 +static void snd_ep93xx_dma_start( audio_state_t * state, audio_stream_t * stream )
2634 +{
2635 +    int err,i;
2636 +
2637 +    DPRINTK("snd_ep93xx_dma_start - enter\n");
2638 +
2639 +    for(i = 0 ;i < stream->dma_num_channels;i++)
2640 +       err = ep93xx_dma_start( stream->dmahandles[i], 1,(unsigned int *) stream->dmahandles );
2641 +
2642 +    stream->active = 1;
2643 +
2644 +    DPRINTK("snd_ep93xx_dma_start - exit\n");
2645 +}
2646 +
2647 +static void snd_ep93xx_dma_pause( audio_state_t * state, audio_stream_t * stream )
2648 +{
2649 +    int i;
2650 +
2651 +    DPRINTK("snd_ep93xx_dma_pause - enter\n");
2652 +
2653 +    for(i = 0 ;i < stream->dma_num_channels;i++)
2654 +       ep93xx_dma_pause( stream->dmahandles[i], 1,(unsigned int *)stream->dmahandles );
2655 +
2656 +    stream->active = 0;
2657 +    DPRINTK("snd_ep93xx_dma_pause - exit\n");
2658 +
2659 +}
2660 +
2661 +static void snd_ep93xx_dma_flush( audio_state_t * state, audio_stream_t * stream ){
2662 +
2663 +    int i;
2664 +
2665 +    DPRINTK("snd_ep93xx_dma_flush - enter\n");
2666 +
2667 +    for( i = 0 ; i < stream->dma_num_channels ; i++ )
2668 +       ep93xx_dma_flush( stream->dmahandles[i] );
2669 +
2670 +    DPRINTK("snd_ep93xx_dma_flush - exit\n");
2671 +}
2672 +
2673 +static void snd_ep93xx_deallocate_buffers( struct snd_pcm_substream *substream, audio_stream_t *stream )
2674 +{
2675 +    int i;
2676 +    audio_channel_t *dma_chan;
2677 +
2678 +    DPRINTK("snd_ep93xx_deallocate_buffers - enter\n");
2679 +
2680 +    if( stream->dma_channels ){
2681 +
2682 +        for(i = 0;i < stream->dma_num_channels;i++){
2683 +
2684 +           dma_chan = &stream->dma_channels[i];
2685 +
2686 +           if( dma_chan->area ){
2687 +
2688 +               if( dma_chan->audio_buffers ){
2689 +
2690 +                   kfree(dma_chan->audio_buffers);
2691 +                   dma_chan->audio_buffers = NULL;
2692 +
2693 +               }
2694 +
2695 +               kfree(dma_chan->area);
2696 +               dma_chan->area = NULL;
2697 +           }
2698 +       }
2699 +       kfree(stream->dma_channels);
2700 +       stream->dma_channels = NULL;
2701 +    }
2702 +    DPRINTK("snd_ep93xx_deallocate_buffers - exit\n");
2703 +}
2704 +
2705 +static int snd_ep93xx_allocate_buffers(struct snd_pcm_substream *substream, audio_stream_t *stream)
2706 +{
2707 +    audio_channel_t *channel;
2708 +    unsigned int size,tmpsize,bufsize,bufextsize;
2709 +    int i,j;
2710 +
2711 +
2712 +    DPRINTK("snd_ep93xx_allocate_buffers - enter\n" );
2713 +
2714 +    if (stream->dma_channels){
2715 +       printk("ep93xx_i2s  %s BUSY\n",__FUNCTION__);
2716 +        return -EBUSY;
2717 +    }
2718 +
2719 +    stream->dma_channels = (audio_channel_t *)kmalloc(sizeof(audio_channel_t) * stream->dma_num_channels , GFP_KERNEL);
2720 +
2721 +    if (!stream->dma_channels){
2722 +       printk(AUDIO_NAME ": unable to allocate dma_channels memory\n");
2723 +       return - ENOMEM;
2724 +    }
2725 +
2726 +    size = ( stream->dmasize / stream->dma_num_channels ) * stream->dma2usr_ratio;
2727 +
2728 +    for( i = 0; i < stream->dma_num_channels;i++){
2729 +       channel = &stream->dma_channels[i];
2730 +
2731 +       channel->area = kmalloc( size, GFP_DMA );
2732 +
2733 +       if(!channel->area){
2734 +           printk(AUDIO_NAME ": unable to allocate audio memory\n");
2735 +           return -ENOMEM;
2736 +       }
2737 +       channel->bytes = size;
2738 +       channel->addr = __virt_to_phys((int) channel->area);
2739 +        memset( channel->area, 0, channel->bytes );
2740 +
2741 +       bufsize = ( stream->fragsize / stream->dma_num_channels ) * stream->dma2usr_ratio;
2742 +       channel->audio_buff_count = size / bufsize;
2743 +       bufextsize = size % bufsize;
2744 +
2745 +       if( bufextsize > 0 ){
2746 +           channel->audio_buff_count++;
2747 +       }
2748 +
2749 +       channel->audio_buffers = (audio_buf_t *)kmalloc(sizeof(audio_buf_t) * channel->audio_buff_count , GFP_KERNEL);
2750 +
2751 +       if (!channel->audio_buffers){
2752 +           printk(AUDIO_NAME ": unable to allocate audio memory\n ");
2753 +           return -ENOMEM;
2754 +       }
2755 +
2756 +       tmpsize = size;
2757 +
2758 +       for( j = 0; j < channel->audio_buff_count; j++){
2759 +
2760 +           channel->audio_buffers[j].dma_addr = channel->addr + j * bufsize;
2761 +
2762 +           if( tmpsize >= bufsize ){
2763 +               tmpsize -= bufsize;
2764 +               channel->audio_buffers[j].bytes = bufsize;
2765 +               channel->audio_buffers[j].reportedbytes = bufsize / stream->dma2usr_ratio;
2766 +           }
2767 +           else{
2768 +                channel->audio_buffers[j].bytes = bufextsize;
2769 +                channel->audio_buffers[j].reportedbytes = bufextsize / stream->dma2usr_ratio;
2770 +           }
2771 +       }
2772 +    }
2773 +
2774 +    DPRINTK("snd_ep93xx_allocate_buffers -- exit SUCCESS\n" );
2775 +    return 0;
2776 +}
2777 +
2778 +/*
2779 + * DMA callback functions
2780 + */
2781 +
2782 +static void snd_ep93xx_dma_tx_callback
2783 +(
2784 +       ep93xx_dma_int_t DMAInt,
2785 +       ep93xx_dma_dev_t device,
2786 +       unsigned int user_data
2787 +)
2788 +{
2789 +    int handle;
2790 +    int i,chan;
2791 +    unsigned int buf_id;
2792 +
2793 +    struct snd_pcm_substream *substream = (struct snd_pcm_substream *)user_data;
2794 +    audio_state_t *state = (audio_state_t *)(substream->private_data);
2795 +    audio_stream_t *stream = state->output_stream;
2796 +    audio_buf_t *buf;
2797 +
2798 +    switch( device )
2799 +    {
2800 +       case DMATx_I2S3:
2801 +           DPRINTK( "snd_ep93xx_dma_tx_callback - DMATx_I2S3\n");
2802 +           i = 2;
2803 +           break;
2804 +       case DMATx_I2S2:
2805 +           DPRINTK( "snd_ep93xx_dma_tx_callback - DMATx_I2S2\n");
2806 +                   i = 1;
2807 +           break;
2808 +       case DMATx_I2S1:
2809 +           default:
2810 +           DPRINTK( "snd_ep93xx_dma_tx_callback - DMATx_I2S1\n");
2811 +                   i = 0;
2812 +           break;
2813 +    }
2814 +
2815 +    if(stream->audio_num_channels == 1){
2816 +       chan = 0;
2817 +    }
2818 +    else{
2819 +        chan = stream->audio_num_channels / 2 - 1;
2820 +    }
2821 +    handle = stream->dmahandles[i];
2822 +
2823 +    if(stream->stopped == 0){
2824 +
2825 +       if( ep93xx_dma_remove_buffer( handle, &buf_id ) >= 0 ){
2826 +
2827 +           buf = (audio_buf_t *)buf_id;
2828 +            stream->bytecount += buf->reportedbytes;
2829 +           ep93xx_dma_add_buffer( stream->dmahandles[i],
2830 +                                   (unsigned int)buf->dma_addr,
2831 +                                   0,
2832 +                                   buf->bytes,
2833 +                                   0,
2834 +                                   (unsigned int) buf );
2835 +            if(chan == i)
2836 +               snd_pcm_period_elapsed(substream);
2837 +       }
2838 +    }
2839 +}
2840 +
2841 +static void snd_ep93xx_dma_rx_callback
2842 +(
2843 +       ep93xx_dma_int_t DMAInt,
2844 +       ep93xx_dma_dev_t device,
2845 +       unsigned int user_data
2846 +)
2847 +{
2848 +    int handle,i,chan;
2849 +    unsigned int buf_id;
2850 +    audio_buf_t *buf;
2851 +
2852 +    struct snd_pcm_substream *substream = (struct snd_pcm_substream *)user_data;
2853 +    audio_state_t *state = (audio_state_t *)(substream->private_data);
2854 +    audio_stream_t *stream = state->input_stream;
2855 +
2856 +    switch( device ){
2857 +
2858 +       case DMARx_I2S3:
2859 +           DPRINTK( "snd_ep93xx_dma_rx_callback - DMARx_I2S3\n");
2860 +           i = 2;
2861 +           break;
2862 +       case DMARx_I2S2:
2863 +          DPRINTK( "snd_ep93xx_dma_rx_callback - DMARx_I2S2\n");
2864 +           i = 1;
2865 +           break;
2866 +       case DMARx_I2S1:
2867 +           default:
2868 +           DPRINTK( "snd_ep93xx_dma_rx_callback - DMARx_I2S1\n");
2869 +           i = 0;
2870 +           break;
2871 +    }
2872 +
2873 +    if(stream->audio_num_channels == 1){
2874 +       chan = 0;
2875 +    }
2876 +    else{
2877 +        chan = stream->audio_num_channels / 2 - 1;
2878 +    }
2879 +    handle = stream->dmahandles[i];
2880 +
2881 +    if( stream->stopped == 0 ){
2882 +
2883 +        if( ep93xx_dma_remove_buffer( handle, &buf_id ) >= 0 ){
2884 +
2885 +           buf = (audio_buf_t *)buf_id;
2886 +           stream->bytecount += buf->reportedbytes;
2887 +           ep93xx_dma_add_buffer( stream->dmahandles[i],
2888 +                                   (unsigned int)buf->dma_addr,
2889 +                                   0,
2890 +                                   buf->bytes,
2891 +                                   0,
2892 +                                   (unsigned int) buf );
2893 +            if( i == chan )
2894 +                snd_pcm_period_elapsed(substream);
2895 +       }
2896 +    }
2897 +}
2898 +
2899 +static int snd_ep93xx_release(struct snd_pcm_substream *substream)
2900 +{
2901 +    audio_state_t *state = (audio_state_t *)substream->private_data;
2902 +    audio_stream_t *stream = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
2903 +                             state->output_stream : state->input_stream;
2904 +
2905 +    DPRINTK("snd_ep93xx_release - enter\n");
2906 +
2907 +    down(&state->sem);
2908 +    stream->active = 0;
2909 +    stream->stopped = 0;
2910 +    snd_ep93xx_deallocate_buffers(substream, stream);
2911 +    up(&state->sem);
2912 +
2913 +    DPRINTK("snd_ep93xx_release - exit\n");
2914 +
2915 +    return 0;
2916 +}
2917 +
2918 +static int ep93xx_ac97_pcm_startup(struct snd_pcm_substream *substream)
2919 +{
2920 +       struct snd_pcm_runtime *runtime = substream->runtime;
2921 +       int r;
2922 +       int iTempMasterVol,iTempHeadphoneVol,iTempMonoVol,iTempRecordSelect;
2923 +        /*save the old mixer*/
2924 +       iTempRecordSelect       = peek(AC97_1A_RECORD_SELECT);
2925 +        iTempMasterVol         = peek( AC97_02_MASTER_VOL);
2926 +        iTempHeadphoneVol      = peek( AC97_04_HEADPHONE_VOL);
2927 +        iTempMonoVol           = peek( AC97_06_MONO_VOL);
2928 +
2929 +       runtime->hw.channels_min = 1;
2930 +       runtime->hw.channels_max = 2;
2931 +
2932 +       ep93xx_audio_init();
2933 +       /*ep93xx_init_ac97_controller();*/
2934 +
2935 +        /*reset the old output mixer*/
2936 +        poke( AC97_02_MASTER_VOL, iTempMasterVol);
2937 +        poke( AC97_04_HEADPHONE_VOL,iTempHeadphoneVol );
2938 +        poke( AC97_06_MONO_VOL, iTempMonoVol);
2939 +       poke( AC97_1A_RECORD_SELECT,iTempRecordSelect);
2940 +
2941 +       r = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
2942 +           AC97_RATES_FRONT_DAC : AC97_RATES_ADC;
2943 +
2944 +       DPRINTK(" ep93xx_ac97_pcm_startup=%x\n",r);
2945 +
2946 +               return 0;
2947 +}
2948 +
2949 +
2950 +static int snd_ep93xx_pcm_hw_params(struct snd_pcm_substream *substream,
2951 +                               struct snd_pcm_hw_params *params)
2952 +{
2953 +        DPRINTK("snd_ep93xx_pcm_hw_params - enter\n");
2954 +       return snd_pcm_lib_malloc_pages(substream,params_buffer_bytes(params));
2955 +}
2956 +
2957 +static int snd_ep93xx_pcm_hw_free(struct snd_pcm_substream *substream)
2958 +{
2959 +
2960 +       DPRINTK("snd_ep93xx_pcm_hw_free - enter\n");
2961 +       return snd_pcm_lib_free_pages(substream);
2962 +}
2963 +
2964 +/*
2965 + *snd_ep93xx_pcm_prepare: need to finish these functions as lower
2966 + *chip_set_sample_format
2967 + *chip_set_sample_rate
2968 + *chip_set_channels
2969 + *chip_set_dma_setup
2970 + */
2971 +
2972 +static int snd_ep93xx_pcm_prepare_playback( struct snd_pcm_substream *substream)
2973 +{
2974 +    audio_state_t *state = (audio_state_t *) substream->private_data;
2975 +    struct snd_pcm_runtime *runtime = substream->runtime;
2976 +    audio_stream_t *stream = state->output_stream;
2977 +
2978 +    DPRINTK("snd_ep93xx_pcm_prepare_playback - enter\n");
2979 +
2980 +    ep93xx_audio_disable(1);
2981 +    ep93xx_ac97_pcm_startup(substream);
2982 +
2983 +    snd_ep93xx_deallocate_buffers(substream,stream);
2984 +
2985 +    //if(runtime->channels % 2 != 0)
2986 +    // return -1;
2987 +
2988 +    DPRINTK("The runtime item : \n");
2989 +    DPRINTK("runtime->dma_addr    = 0x%x\n", runtime->dma_addr);
2990 +    DPRINTK("runtime->dma_area    = 0x%x\n", runtime->dma_area);
2991 +    DPRINTK("runtime->dma_bytes   = %d\n",   runtime->dma_bytes);
2992 +    DPRINTK("runtime->frame_bits  = %d\n",   runtime->frame_bits);
2993 +    DPRINTK("runtime->buffer_size = %d\n",   runtime->buffer_size);
2994 +    DPRINTK("runtime->period_size = %d\n",   runtime->period_size);
2995 +    DPRINTK("runtime->periods     = %d\n",   runtime->periods);
2996 +    DPRINTK("runtime->rate        = %d\n",   runtime->rate);
2997 +    DPRINTK("runtime->format      = %d\n",   runtime->format);
2998 +    DPRINTK("runtime->channels    = %d\n",   runtime->channels);
2999 +
3000 +    /* set requestd format when available */
3001 +    stream->audio_num_channels = runtime->channels;
3002 +    if(stream->audio_num_channels == 1){
3003 +       stream->dma_num_channels = 1;
3004 +    }
3005 +    else{
3006 +       stream->dma_num_channels = runtime->channels / 2;
3007 +    }
3008 +
3009 +    stream->audio_channels_flag = CHANNEL_FRONT;
3010 +    if(stream->dma_num_channels == 2)
3011 +        stream->audio_channels_flag |= CHANNEL_REAR;
3012 +    if(stream->dma_num_channels == 3)
3013 +        stream->audio_channels_flag |= CHANNEL_REAR | CHANNEL_CENTER_LFE;
3014 +
3015 +    stream->dmasize = runtime->dma_bytes;
3016 +    stream->nbfrags = runtime->periods;
3017 +    stream->fragsize = frames_to_bytes (runtime, runtime->period_size);
3018 +    stream->bytecount = 0;
3019 +
3020 +    if( !state->codec_set_by_capture ){
3021 +       state->codec_set_by_playback = 1;
3022 +
3023 +       if( stream->audio_rate != runtime->rate ){
3024 +           ep93xx_set_samplerate( runtime->rate,0 );
3025 +       }
3026 +       //if( stream->audio_format != runtime->format ){
3027 +       //    snd_ep93xx_i2s_init((stream->audio_stream_bitwidth == 24));
3028 +       //}
3029 +    }
3030 +    else{
3031 +        audio_stream_t *s = state->input_stream;
3032 +        if( runtime->format != s->audio_format)
3033 +           return -1;
3034 +       if( runtime->rate != s->audio_rate )
3035 +           return -1;
3036 +    }
3037 +
3038 +    stream->audio_format = runtime->format ;
3039 +    ep93xx_set_hw_format(stream->audio_format,stream->audio_num_channels);
3040 +
3041 +
3042 +    stream->audio_rate = runtime->rate;
3043 +    audio_set_format( stream, runtime->format );
3044 +    snd_ep93xx_dma2usr_ratio( stream,state->bCompactMode );
3045 +
3046 +    if( snd_ep93xx_allocate_buffers( substream, stream ) != 0 ){
3047 +        snd_ep93xx_deallocate_buffers( substream, stream );
3048 +        return -1;
3049 +    }
3050 +
3051 +    ep93xx_audio_enable(1);
3052 +
3053 +    DPRINTK("snd_ep93xx_pcm_prepare_playback - exit\n");
3054 +    return 0;
3055 +}
3056 +
3057 +static int snd_ep93xx_pcm_prepare_capture( struct snd_pcm_substream *substream)
3058 +{
3059 +    audio_state_t *state = (audio_state_t *) substream->private_data;
3060 +    struct snd_pcm_runtime *runtime = substream->runtime;
3061 +    audio_stream_t *stream = state->input_stream;
3062 +
3063 +    ep93xx_audio_disable(0);
3064 +    ep93xx_ac97_pcm_startup(substream);
3065 +
3066 +    snd_ep93xx_deallocate_buffers(substream,stream);
3067 +
3068 +    //if(runtime->channels % 2 != 0)
3069 +       //return -1;
3070 +
3071 +    DPRINTK("snd_ep93xx_pcm_prepare_capture - enter\n");
3072 +
3073 +//    printk("The runtime item : \n");
3074 +//    printk("runtime->dma_addr    = 0x%x\n", runtime->dma_addr);
3075 +//    printk("runtime->dma_area    = 0x%x\n", runtime->dma_area);
3076 +//    printk("runtime->dma_bytes   = %d\n",   runtime->dma_bytes);
3077 +//    printk("runtime->frame_bits  = %d\n",   runtime->frame_bits);
3078 +//    printk("runtime->buffer_size = %d\n",   runtime->buffer_size);
3079 +//    printk("runtime->period_size = %d\n",   runtime->period_size);
3080 +//    printk("runtime->periods     = %d\n",   runtime->periods);
3081 +//    printk("runtime->rate        = %d\n",   runtime->rate);
3082 +//    printk("runtime->format      = %d\n",   runtime->format);
3083 +//    printk("runtime->channels    = %d\n",   runtime->channels);
3084 +
3085 +    /* set requestd format when available */
3086 +    stream->audio_num_channels = runtime->channels;
3087 +    if(stream->audio_num_channels == 1){
3088 +       stream->dma_num_channels = 1;
3089 +    }
3090 +    else{
3091 +       stream->dma_num_channels = runtime->channels / 2;
3092 +    }
3093 +
3094 +    stream->audio_channels_flag = CHANNEL_FRONT;
3095 +    if(stream->dma_num_channels == 2)
3096 +       stream->audio_channels_flag |= CHANNEL_REAR;
3097 +    if(stream->dma_num_channels == 3)
3098 +       stream->audio_channels_flag |= CHANNEL_REAR | CHANNEL_CENTER_LFE;
3099 +
3100 +    stream->dmasize = runtime->dma_bytes;
3101 +    stream->nbfrags = runtime->periods;
3102 +    stream->fragsize = frames_to_bytes (runtime, runtime->period_size);
3103 +    stream->bytecount = 0;
3104 +
3105 +    if( !state->codec_set_by_playback ){
3106 +       state->codec_set_by_capture = 1;
3107 +
3108 +       /*rate*/
3109 +       if( stream->audio_rate != runtime->rate ){
3110 +           ep93xx_set_samplerate( runtime->rate,1 );
3111 +       }
3112 +
3113 +       /*mixer*/
3114 +       ep93xx_set_recsource(SOUND_MASK_MIC|SOUND_MASK_LINE1 | SOUND_MASK_LINE);
3115 +       poke( AC97_1C_RECORD_GAIN, 0);
3116 +
3117 +       /*format*/
3118 +        //if( stream->audio_format != runtime->format ){
3119 +       //    snd_ep93xx_i2s_init((stream->audio_stream_bitwidth == 24));
3120 +       //}
3121 +    }
3122 +    else{
3123 +        audio_stream_t *s = state->output_stream;
3124 +        if( runtime->format != s->audio_format)
3125 +           return -1;
3126 +       if( runtime->rate != s->audio_rate )
3127 +           return -1;
3128 +    }
3129 +
3130 +    stream->audio_format = runtime->format ;
3131 +    ep93xx_set_hw_format(stream->audio_format,stream->audio_num_channels);
3132 +
3133 +
3134 +    stream->audio_rate = runtime->rate;
3135 +    audio_set_format( stream, runtime->format );
3136 +    snd_ep93xx_dma2usr_ratio( stream,state->bCompactMode );
3137 +
3138 +    if( snd_ep93xx_allocate_buffers( substream, stream ) != 0 ){
3139 +        snd_ep93xx_deallocate_buffers( substream, stream );
3140 +       return -1;
3141 +    }
3142 +
3143 +    ep93xx_audio_enable(0);
3144 +
3145 +    DPRINTK("snd_ep93xx_pcm_prepare_capture - exit\n");
3146 +    return 0;
3147 +}
3148 +/*
3149 + *start/stop/pause dma translate
3150 + */
3151 +static int snd_ep93xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
3152 +{
3153 +    audio_state_t  *state = (audio_state_t *)substream->private_data;
3154 +    audio_stream_t *stream = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
3155 +                               state->output_stream:state->input_stream;
3156 +    audio_buf_t *buf;
3157 +    audio_channel_t *dma_channel;
3158 +    int i,count,ret = 0;
3159 +    unsigned long flags;
3160 +
3161 +    DPRINTK("snd_ep93xx_pcm_triger %d - enter \n",cmd);
3162 +
3163 +    switch (cmd){
3164 +
3165 +       case SNDRV_PCM_TRIGGER_START:
3166 +
3167 +           snd_ep93xx_dma_config( substream );
3168 +
3169 +            stream->stopped = 0;
3170 +
3171 +            if( !stream->active && !stream->stopped ){
3172 +               stream->active = 1;
3173 +               snd_ep93xx_dma_start( state, stream );
3174 +            }
3175 +
3176 +            local_irq_save(flags);
3177 +
3178 +           for (i = 0; i < stream->dma_num_channels; i++){
3179 +               dma_channel = &stream->dma_channels[i];
3180 +
3181 +               for(count = 0 ;count < dma_channel->audio_buff_count; count++){
3182 +
3183 +                   buf = &dma_channel->audio_buffers[count];
3184 +                   ep93xx_dma_add_buffer( stream->dmahandles[i],
3185 +                                           (unsigned int)buf->dma_addr,
3186 +                                           0,
3187 +                                           buf->bytes,
3188 +                                           0,
3189 +                                           (unsigned int) buf );
3190 +               }
3191 +           }
3192 +
3193 +           local_irq_restore(flags);
3194 +           break;
3195 +
3196 +       case SNDRV_PCM_TRIGGER_STOP:
3197 +           stream->stopped = 1;
3198 +           snd_ep93xx_dma_pause( state, stream );
3199 +           snd_ep93xx_dma_flush( state, stream );
3200 +           snd_ep93xx_dma_free( substream );
3201 +           break;
3202 +
3203 +       case SNDRV_PCM_TRIGGER_SUSPEND:
3204 +           break;
3205 +       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
3206 +           break;
3207 +       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
3208 +           break;
3209 +
3210 +           default:
3211 +           ret = -EINVAL;
3212 +    }
3213 +    DPRINTK("snd_ep93xx_pcm_triger %d - exit \n",cmd);
3214 +    return ret;
3215 +}
3216 +
3217 +static snd_pcm_uframes_t snd_ep93xx_pcm_pointer_playback(struct snd_pcm_substream *substream)
3218 +{
3219 +    audio_state_t *state = (audio_state_t *)(substream->private_data);
3220 +    struct snd_pcm_runtime *runtime = substream->runtime;
3221 +    audio_stream_t *stream = state->output_stream;
3222 +    snd_pcm_uframes_t pointer = 0;
3223 +
3224 +    pointer = bytes_to_frames( runtime,stream->bytecount );
3225 +
3226 +    if (pointer >= runtime->buffer_size){
3227 +       pointer = 0;
3228 +       stream->bytecount = 0;
3229 +    }
3230 +
3231 +    DPRINTK("snd_ep93xx_pcm_pointer_playback - exit\n");
3232 +    return pointer;
3233 +}
3234 +
3235 +static snd_pcm_uframes_t snd_ep93xx_pcm_pointer_capture(struct snd_pcm_substream *substream)
3236 +{
3237 +    audio_state_t *state = (audio_state_t *)(substream->private_data);
3238 +    struct snd_pcm_runtime *runtime = substream->runtime;
3239 +    audio_stream_t *stream = state->input_stream;
3240 +    snd_pcm_uframes_t pointer = 0;
3241 +
3242 +    pointer = bytes_to_frames( runtime,stream->bytecount );
3243 +
3244 +    if (pointer >= runtime->buffer_size){
3245 +       pointer = 0;
3246 +       stream->bytecount = 0;
3247 +    }
3248 +
3249 +    DPRINTK("snd_ep93xx_pcm_pointer_capture - exit\n");
3250 +    return pointer;
3251 +}
3252 +
3253 +static int snd_ep93xx_pcm_open(struct snd_pcm_substream *substream)
3254 +{
3255 +    audio_state_t *state = substream->private_data;
3256 +    struct snd_pcm_runtime *runtime = substream->runtime;
3257 +    audio_stream_t *stream = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
3258 +                                state->output_stream:state->input_stream;
3259 +
3260 +    DPRINTK("snd_ep93xx_pcm_open - enter\n");
3261 +
3262 +    down(&state->sem);
3263 +
3264 +    runtime->hw = ep93xx_ac97_pcm_hardware;
3265 +
3266 +    stream->dma_num_channels = AUDIO_DEFAULT_DMACHANNELS;
3267 +    stream->dma_channels = NULL;
3268 +    stream->audio_rate = 0;
3269 +    stream->audio_stream_bitwidth = 0;
3270 +
3271 +    up(&state->sem);
3272 +
3273 +    DPRINTK("snd_ep93xx_pcm_open - exit\n");
3274 +    return 0;
3275 +}
3276 +
3277 +/*
3278 + *free the HW dma channel
3279 + *free the HW dma buffer
3280 + *free the Hw dma decrotion using function :kfree
3281 + */
3282 +static int snd_ep93xx_pcm_close(struct snd_pcm_substream *substream)
3283 +{
3284 +    audio_state_t *state = (audio_state_t *)(substream->private_data);
3285 +
3286 +    DPRINTK("snd_ep93xx_pcm_close - enter\n");
3287 +
3288 +    snd_ep93xx_release(substream);
3289 +
3290 +    if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
3291 +       state->codec_set_by_playback = 0;
3292 +    else
3293 +       state->codec_set_by_capture = 0;
3294 +
3295 +    DPRINTK("snd_ep93xx_pcm_close - exit\n");
3296 +    return 0;
3297 +}
3298 +
3299 +static int snd_ep93xx_pcm_copy_playback(struct snd_pcm_substream * substream,int channel,
3300 +                               snd_pcm_uframes_t pos,void __user *src, snd_pcm_uframes_t count)
3301 +{
3302 +
3303 +    audio_state_t *state = (audio_state_t *)substream->private_data;
3304 +    struct snd_pcm_runtime *runtime = substream->runtime;
3305 +    audio_stream_t *stream = state->output_stream ;
3306 +    audio_channel_t *dma_channel;
3307 +    int i;
3308 +    int tocount = frames_to_bytes(runtime,count);
3309 +
3310 +    for( i = 0; i < stream->dma_num_channels; i++ ){
3311 +
3312 +       dma_channel = &stream->dma_channels[i];
3313 +       stream->hwbuf[i] = dma_channel->area + ( frames_to_bytes(runtime,pos) * stream->dma2usr_ratio / stream->dma_num_channels );
3314 +
3315 +    }
3316 +
3317 +    if(copy_from_user_with_conversion(stream ,(const char*)src,(tocount * stream->dma2usr_ratio),state->bCompactMode) <=0 ){
3318 +       DPRINTK(KERN_ERR "copy_from_user_with_conversion() failed\n");
3319 +       return -EFAULT;
3320 +    }
3321 +
3322 +    DPRINTK("snd_ep93xx_pcm_copy_playback - exit\n");
3323 +    return 0;
3324 +}
3325 +
3326 +
3327 +static int snd_ep93xx_pcm_copy_capture(struct snd_pcm_substream * substream,int channel,
3328 +                               snd_pcm_uframes_t pos,void __user *src, snd_pcm_uframes_t count)
3329 +{
3330 +    audio_state_t *state = (audio_state_t *)substream->private_data;
3331 +    struct snd_pcm_runtime *runtime = substream->runtime;
3332 +    audio_stream_t *stream = state->input_stream ;
3333 +    audio_channel_t *dma_channel;
3334 +    int i;
3335 +
3336 +    int tocount = frames_to_bytes(runtime,count);
3337 +
3338 +    for( i = 0; i < stream->dma_num_channels; i++ ){
3339 +
3340 +       dma_channel = &stream->dma_channels[i];
3341 +       stream->hwbuf[i] = dma_channel->area + ( frames_to_bytes(runtime,pos) * stream->dma2usr_ratio / stream->dma_num_channels );
3342 +
3343 +    }
3344 +
3345 +    if(copy_to_user_with_conversion(stream,(const char*)src,tocount,state->bCompactMode) <=0 ){
3346 +
3347 +       DPRINTK(KERN_ERR "copy_to_user_with_conversion() failed\n");
3348 +       return -EFAULT;
3349 +    }
3350 +
3351 +    DPRINTK("snd_ep93xx_pcm_copy_capture - exit\n");
3352 +    return 0;
3353 +}
3354 +
3355 +/*----------------------------------------------------------------------------------*/
3356 +static unsigned short ep93xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
3357 +{
3358 +       int val = -1;
3359 +       /*volatile u32 *reg_addr;*/
3360 +
3361 +       DPRINTK(" number of codec:%x reg=%x\n",ac97->num,reg);
3362 +       val=peek(reg);
3363 +       if(val==-1){
3364 +               printk(KERN_ERR "%s: read error (ac97_reg=%d )val=%x\n",
3365 +                               __FUNCTION__, reg, val);
3366 +               return 0;
3367 +       }
3368 +
3369 +       return val;
3370 +}
3371 +
3372 +static void ep93xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
3373 +{
3374 +       /*volatile u32 *reg_addr;*/
3375 +       int ret;
3376 +
3377 +       DPRINTK(" number of codec:%x rge=%x val=%x\n",ac97->num,reg,val);
3378 +       ret=poke(reg, val);
3379 +       if(ret!=0){
3380 +               printk(KERN_ERR "%s: write error (ac97_reg=%d val=%x)\n",
3381 +                               __FUNCTION__, reg, val);
3382 +       }
3383 +
3384 +}
3385 +
3386 +static void ep93xx_ac97_reset(struct snd_ac97 *ac97)
3387 +{
3388 +
3389 +       DPRINTK(" ep93xx_ac97_reset\n");
3390 +       ep93xx_audio_init();
3391 +
3392 +}
3393 +
3394 +static struct snd_ac97_bus_ops ep93xx_ac97_ops = {
3395 +       .read   = ep93xx_ac97_read,
3396 +       .write  = ep93xx_ac97_write,
3397 +       .reset  = ep93xx_ac97_reset,
3398 +};
3399 +
3400 +static struct snd_pcm *ep93xx_ac97_pcm;
3401 +static struct snd_ac97 *ep93xx_ac97_ac97;
3402 +
3403 +static struct snd_pcm_ops snd_ep93xx_pcm_playback_ops = {
3404 +       .open           = snd_ep93xx_pcm_open,
3405 +       .close          = snd_ep93xx_pcm_close,
3406 +       .ioctl          = snd_pcm_lib_ioctl,
3407 +       .hw_params      = snd_ep93xx_pcm_hw_params,
3408 +       .hw_free        = snd_ep93xx_pcm_hw_free,
3409 +       .prepare        = snd_ep93xx_pcm_prepare_playback,
3410 +       .trigger        = snd_ep93xx_pcm_trigger,
3411 +       .pointer        = snd_ep93xx_pcm_pointer_playback,
3412 +       .copy           = snd_ep93xx_pcm_copy_playback,
3413 +
3414 +};
3415 +
3416 +static struct snd_pcm_ops snd_ep93xx_pcm_capture_ops = {
3417 +       .open           = snd_ep93xx_pcm_open,
3418 +       .close          = snd_ep93xx_pcm_close,
3419 +       .ioctl          = snd_pcm_lib_ioctl,
3420 +       .hw_params      = snd_ep93xx_pcm_hw_params,
3421 +       .hw_free        = snd_ep93xx_pcm_hw_free,
3422 +       .prepare        = snd_ep93xx_pcm_prepare_capture,
3423 +       .trigger        = snd_ep93xx_pcm_trigger,
3424 +       .pointer        = snd_ep93xx_pcm_pointer_capture,
3425 +       .copy           = snd_ep93xx_pcm_copy_capture,
3426 +};
3427 +
3428 +/*--------------------------------------------------------------------------*/
3429 +
3430 +
3431 +static int snd_ep93xx_pcm_new(struct snd_card *card, audio_state_t *state, struct snd_pcm **rpcm)
3432 +{
3433 +    struct snd_pcm *pcm;
3434 +    int play = state->output_stream? 1 : 0;/*SNDRV_PCM_STREAM_PLAYBACK*/
3435 +    int capt = state->input_stream ? 1 : 0;/*SNDRV_PCM_STREAM_CAPTURE*/
3436 +    int ret = 0;
3437 +
3438 +    DPRINTK("snd_ep93xx_pcm_new - enter\n");
3439 +
3440 +    /* Register the new pcm device interface */
3441 +    ret = snd_pcm_new(card, "EP93xx-AC97-PCM", 0, play, capt, &pcm);
3442 +
3443 +    if (ret){
3444 +       DPRINTK("%s--%x:card=%x,play=%x,capt=%x,&pcm=%x\n",__FUNCTION__,ret,(int)card,play,capt,(int)pcm);
3445 +       goto out;
3446 +    }
3447 +
3448 +    /* allocate the pcm(DMA) memory */
3449 +    ret = snd_pcm_lib_preallocate_pages_for_all(pcm, /*SNDRV_DMA_TYPE_DEV,0,*/SNDRV_DMA_TYPE_CONTINUOUS,snd_dma_continuous_data(GFP_KERNEL),128*1024,128*1024);
3450 +
3451 +    DPRINTK("The substream item : \n");
3452 +    DPRINTK("pcm->streams[0].substream->dma_buffer.addr  = 0x%x\n", pcm->streams[0].substream->dma_buffer.addr);
3453 +    DPRINTK("pcm->streams[0].substream->dma_buffer.area  = 0x%x\n", pcm->streams[0].substream->dma_buffer.area);
3454 +    DPRINTK("pcm->streams[0].substream->dma_buffer.bytes = 0x%x\n", pcm->streams[0].substream->dma_buffer.bytes);
3455 +    DPRINTK("pcm->streams[1].substream->dma_buffer.addr  = 0x%x\n", pcm->streams[1].substream->dma_buffer.addr);
3456 +    DPRINTK("pcm->streams[1].substream->dma_buffer.area  = 0x%x\n", pcm->streams[1].substream->dma_buffer.area);
3457 +    DPRINTK("pcm->streams[1].substream->dma_buffer.bytes = 0x%x\n", pcm->streams[1].substream->dma_buffer.bytes);
3458 +
3459 +    pcm->private_data = state;
3460 +
3461 +    /* seem to free the pcm data struct-->self dma buffer */
3462 +    pcm->private_free = (void*) snd_pcm_lib_preallocate_free_for_all;
3463 +
3464 +    /* alsa pcm ops setting for SNDRV_PCM_STREAM_PLAYBACK */
3465 +    if (play) {
3466 +       int stream = SNDRV_PCM_STREAM_PLAYBACK;
3467 +       snd_pcm_set_ops(pcm, stream, &snd_ep93xx_pcm_playback_ops);
3468 +    }
3469 +
3470 +    /* alsa pcm ops setting for SNDRV_PCM_STREAM_CAPTURE */
3471 +    if (capt) {
3472 +       int stream = SNDRV_PCM_STREAM_CAPTURE;
3473 +       snd_pcm_set_ops(pcm, stream, &snd_ep93xx_pcm_capture_ops);
3474 +    }
3475 +
3476 +    if (rpcm)
3477 +       *rpcm = pcm;
3478 +    DPRINTK("snd_ep93xx_pcm_new - exit\n");
3479 +out:
3480 +    return ret;
3481 +}
3482 +
3483 +#ifdef CONFIG_PM
3484 +
3485 +int ep93xx_ac97_do_suspend(struct snd_card *card, unsigned int state)
3486 +{
3487 +       if (card->power_state != SNDRV_CTL_POWER_D3cold) {
3488 +               snd_pcm_suspend_all(ep93xx_ac97_pcm);
3489 +               snd_ac97_suspend(ep93xx_ac97_ac97);
3490 +               snd_power_change_state(card, SNDRV_CTL_POWER_D3cold);
3491 +       }
3492 +
3493 +       return 0;
3494 +}
3495 +
3496 +int ep93xx_ac97_do_resume(struct snd_card *card, unsigned int state)
3497 +{
3498 +       if (card->power_state != SNDRV_CTL_POWER_D0) {
3499 +
3500 +               snd_ac97_resume(ep93xx_ac97_ac97);
3501 +               snd_power_change_state(card, SNDRV_CTL_POWER_D0);
3502 +       }
3503 +
3504 +       return 0;
3505 +}
3506 +
3507 +int ep93xx_ac97_suspend(struct platform_device *_dev, u32 state, u32 level)
3508 +{
3509 +       struct snd_card *card = platform_get_drvdata(_dev);
3510 +       int ret = 0;
3511 +
3512 +       if (card && level == SUSPEND_DISABLE)
3513 +               ret = ep93xx_ac97_do_suspend(card, SNDRV_CTL_POWER_D3cold);
3514 +
3515 +       return ret;
3516 +}
3517 +
3518 +int ep93xx_ac97_resume(struct platform_device *_dev, u32 level)
3519 +{
3520 +       struct snd_card *card = platform_get_drvdata(_dev);
3521 +       int ret = 0;
3522 +
3523 +       if (card && level == RESUME_ENABLE)
3524 +               ret = ep93xx_ac97_do_resume(card, SNDRV_CTL_POWER_D0);
3525 +
3526 +       return ret;
3527 +}
3528 +
3529 +#else
3530 +/*
3531 +#define ep93xx_ac97_do_suspend         NULL
3532 +#define ep93xx_ac97_do_resume          NULL
3533 +#define ep93xx_ac97_suspend            NULL
3534 +#define ep93xx_ac97_resume             NULL
3535 +*/
3536 +
3537 +int ep93xx_ac97_do_suspend(struct snd_card *card, unsigned int state)
3538 +{
3539 +        return 0;
3540 +}
3541 +
3542 +int ep93xx_ac97_do_resume(struct snd_card *card, unsigned int state)
3543 +{
3544 +        return 0;
3545 +}
3546 +
3547 +int ep93xx_ac97_resume(struct platform_device *_dev, u32 level)
3548 +{
3549 +        struct snd_card *card = platform_get_drvdata(_dev);
3550 +        int ret = 0;
3551 +
3552 +        //if (card && level == RESUME_ENABLE)
3553 +                ret = ep93xx_ac97_do_resume(card, SNDRV_CTL_POWER_D0);
3554 +
3555 +        return ret;
3556 +}
3557 +
3558 +int ep93xx_ac97_suspend(struct platform_device *_dev, u32 state, u32 level)
3559 +{
3560 +        struct snd_card *card = platform_get_drvdata(_dev);
3561 +        int ret = 0;
3562 +
3563 +        //if (card && level == SUSPEND_DISABLE)
3564 +                ret = ep93xx_ac97_do_suspend(card, SNDRV_CTL_POWER_D3cold);
3565 +
3566 +        return ret;
3567 +}
3568 +
3569 +#endif
3570 +
3571 +
3572 +
3573 +/* module init & exit */
3574 +static int __devinit ep93xx_ac97_probe(struct platform_device *dev)
3575 +{
3576 +    struct snd_card *card;
3577 +    struct snd_ac97_bus *ac97_bus;
3578 +    struct snd_ac97_template ac97_template;
3579 +    int err = -ENOMEM;
3580 +    struct resource *res = NULL;
3581 +
3582 +    DPRINTK("snd_ep93xx_probe - enter\n");
3583 +
3584 +    /* Enable audio early on, give the DAC time to come up. */
3585 +    res = platform_get_resource( dev, IORESOURCE_MEM, 0);
3586 +
3587 +    if(!res) {
3588 +       printk("error : platform_get_resource \n");
3589 +        return -ENODEV;
3590 +    }
3591 +
3592 +    if (!request_mem_region(res->start,res->end - res->start + 1, "snd-ac97-cs4202" )){
3593 +       printk("error : request_mem_region\n");
3594 +        return -EBUSY;
3595 +    }
3596 +
3597 +    /*enable ac97 codec*/
3598 +    ep93xx_audio_init();
3599 +
3600 +    /* register the soundcard */
3601 +    card = snd_card_new(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
3602 +                           THIS_MODULE, 0);
3603 +    if (!card){
3604 +       printk("AC97: snd_card_new error\n");
3605 +       goto error;
3606 +    }
3607 +
3608 +    card->dev = &dev->dev;
3609 +    /*regist the new pcm device*/
3610 +    err = snd_ep93xx_pcm_new(card, &audio_state, &ep93xx_ac97_pcm);
3611 +    if (err){
3612 +       printk("AC97: ep93xx_ac97_pcm_new error\n");
3613 +       goto error;
3614 +    }
3615 +    if (card == NULL) {
3616 +       DPRINTK(KERN_ERR "snd_card_new() failed\n");
3617 +       goto error;
3618 +    }
3619 +
3620 +    /*driver name*/
3621 +    strcpy(card->driver, "CS4202A");
3622 +    strcpy(card->shortname, "Cirrus Logic AC97 Audio ");
3623 +    strcpy(card->longname, "Cirrus Logic AC97 Audio with CS4202A");
3624 +
3625 +    /*regist the new ac97 device*/
3626 +    err = snd_ac97_bus(card, 0, &ep93xx_ac97_ops, NULL, &ac97_bus);
3627 +    if (err){
3628 +       printk("AC97: snd_ac97_bus error\n");
3629 +       goto error;
3630 +    }
3631 +
3632 +    memset(&ac97_template, 0, sizeof(ac97_template));
3633 +    err = snd_ac97_mixer(ac97_bus, &ac97_template, &ep93xx_ac97_ac97);
3634 +    if (err){
3635 +       printk("AC97: snd_ac97_mixer error\n");
3636 +       goto error;
3637 +    }
3638 +
3639 +    /**/
3640 +    ep93xx_audio_init();
3641 +    /*setting the card device callback*/
3642 +    //err = snd_card_set_pm_callback(card, ep93xx_ac97_do_suspend,ep93xx_ac97_do_resume, (void*)NULL);
3643 +    //if(err != 0){
3644 +    // printk("snd_card_set_pm_callback error\n");
3645 +    //}
3646 +
3647 +    /*regist the new CARD device*/
3648 +    err = snd_card_register(card);
3649 +    if (err == 0) {
3650 +       printk( KERN_INFO "Cirrus Logic ep93xx ac97 audio initialized\n" );
3651 +       platform_set_drvdata(dev,card);
3652 +       DPRINTK("snd_ep93xx_probe - exit\n");
3653 +       return 0;
3654 +    }
3655 +
3656 +error:
3657 +    snd_card_free(card);
3658 +    printk("snd_ep93xx_probe - error\n");
3659 +    return err;
3660 +
3661 +return 0;
3662 +}
3663 +
3664 +static int __devexit ep93xx_ac97_remove(struct platform_device *dev)
3665 +{
3666 +    struct resource *res;
3667 +    struct snd_card *card = platform_get_drvdata(dev);
3668 +
3669 +    res = platform_get_resource( dev, IORESOURCE_MEM, 0);
3670 +    release_mem_region(res->start, res->end - res->start + 1);
3671 +
3672 +    DPRINTK("snd_ep93xx_ac97_remove - enter\n");
3673 +
3674 +    if (card) {
3675 +       snd_card_free(card);
3676 +       platform_set_drvdata(dev, NULL);
3677 +    }
3678 +    DPRINTK("snd_ep93xx_remove - exit\n");
3679 +
3680 +return 0;
3681 +}
3682 +
3683 +
3684 +static struct platform_driver ep93xx_ac97_driver = {
3685 +       .probe          = ep93xx_ac97_probe,
3686 +       .remove         = __devexit_p (ep93xx_ac97_remove),
3687 +       .suspend        = ep93xx_ac97_suspend,
3688 +       .resume         = ep93xx_ac97_resume,
3689 +       .driver         = {
3690 +               .name   = "ep93xx-ac97",
3691 +       },
3692 +};
3693 +
3694 +
3695 +static int __init ep93xx_ac97_init(void)
3696 +{
3697 +    int ret;
3698 +
3699 +    DPRINTK(KERN_INFO "%s: version %s\n", DRIVER_DESC, DRIVER_VERSION);
3700 +    DPRINTK("snd_ep93xx_AC97_init - enter\n");
3701 +    ret = platform_driver_register(&ep93xx_ac97_driver);
3702 +    DPRINTK("snd_ep93xx_AC97_init - exit\n");
3703 +    return ret;
3704 +}
3705 +
3706 +static void __exit ep93xx_ac97_exit(void)
3707 +{
3708 +    DPRINTK("ep93xx_ac97_exit  - enter\n");
3709 +    return platform_driver_unregister(&ep93xx_ac97_driver);
3710 +}
3711 +
3712 +module_init(ep93xx_ac97_init);
3713 +module_exit(ep93xx_ac97_exit);
3714 +
3715 +MODULE_DESCRIPTION("Cirrus Logic audio module");
3716 +MODULE_LICENSE("GPL");
3717 --- /dev/null
3718 +++ b/sound/arm/ep93xx-ac97.h
3719 @@ -0,0 +1,89 @@
3720 +/*
3721 + * linux/sound/arm/ep93xx-ac97.h -- ALSA PCM interface for the edb93xx ac97 audio
3722 + *
3723 + * Author:      Fred Wei
3724 + * Created:     July 19, 2005
3725 + * Copyright:   Cirrus Logic, Inc.
3726 + *
3727 + * This program is free software; you can redistribute it and/or modify
3728 + * it under the terms of the GNU General Public License version 2 as
3729 + * published by the Free Software Foundation.
3730 + */
3731 +
3732 +#define EP93XX_DEFAULT_NUM_CHANNELS     2
3733 +#define EP93XX_DEFAULT_FORMAT           SNDRV_PCM_FORMAT_S16_LE
3734 +#define EP93XX_DEFAULT_BIT_WIDTH        16
3735 +#define MAX_DEVICE_NAME                20
3736 +
3737 +/*
3738 + * Buffer Management
3739 + */
3740 +
3741 +typedef struct {
3742 +
3743 +    unsigned char      *area;          /* virtual pointer */
3744 +    dma_addr_t                 dma_addr;       /* physical address */
3745 +    size_t             bytes;
3746 +    size_t             reportedbytes;  /* buffer size */
3747 +    int                sent;           /* indicates that dma has the buf */
3748 +    char               *start;         /* points to actual buffer */
3749 +
3750 +} audio_buf_t;
3751 +
3752 +
3753 +typedef struct {
3754 +
3755 +    unsigned char      *area;                  /* virtual pointer */
3756 +    dma_addr_t                 addr;                   /* physical address */
3757 +    size_t             bytes;                  /* buffer size in bytes */
3758 +    unsigned char              *buff_pos;              /* virtual pointer */
3759 +    audio_buf_t                *audio_buffers;         /* array of audio buffer structures */
3760 +    int                audio_buff_count;
3761 +
3762 +
3763 +} audio_channel_t;
3764 +
3765 +typedef struct audio_stream_s {
3766 +
3767 +    /* dma stuff */
3768 +    int                        dmahandles[3];          /* handles for dma driver instances */
3769 +    char               devicename[MAX_DEVICE_NAME]; /* string - name of device */
3770 +    int                        dma_num_channels;               /* 1, 2, or 3 DMA channels */
3771 +    audio_channel_t    *dma_channels;
3772 +    u_int              nbfrags;                /* nbr of fragments i.e. buffers */
3773 +    u_int              fragsize;               /* fragment i.e. buffer size */
3774 +    u_int              dmasize;
3775 +    int                bytecount;              /* nbr of processed bytes */
3776 +    int                externedbytecount;      /* nbr of processed bytes */
3777 +    volatile int        active;                 /* actually in progress                 */
3778 +    volatile int        stopped;                /* might be active but stopped          */
3779 +    char               *hwbuf[3];
3780 +    long               audio_rate;
3781 +    long               audio_num_channels;             /* Range: 1 to 6 */
3782 +    int                        audio_channels_flag;
3783 +    long               audio_format;
3784 +    long               audio_stream_bitwidth;          /* Range: 8, 16, 24 */
3785 +    int                        dma2usr_ratio;
3786 +
3787 +} audio_stream_t;
3788 +
3789 +
3790 +/*
3791 + * State structure for one instance
3792 + */
3793 +typedef struct {
3794 +
3795 +    audio_stream_t     *output_stream;
3796 +    audio_stream_t     *input_stream;
3797 +    ep93xx_dma_dev_t   output_dma[3];
3798 +    ep93xx_dma_dev_t   input_dma[3];
3799 +    char               *output_id[3];
3800 +    char               *input_id[3];
3801 +    struct              semaphore sem;          /* to protect against races in attach() */
3802 +    int                        codec_set_by_playback;
3803 +    int                 codec_set_by_capture;
3804 +    int                 DAC_bit_width;          /* 16, 20, 24 bits */
3805 +    int                 bCompactMode;           /* set if 32bits = a stereo sample */
3806 +
3807 +} audio_state_t;
3808 +