OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [tags/] [linux-2.6/] [linux-2.6.24_or32_unified_v2.3/] [sound/] [arm/] [sa11xx-uda1341.c] - Blame information for rev 8

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
2
 *  Driver for Philips UDA1341TS on Compaq iPAQ H3600 soundcard
3
 *  Copyright (C) 2002 Tomas Kasparek <tomas.kasparek@seznam.cz>
4
 *
5
 *   This program is free software; you can redistribute it and/or modify
6
 *   it under the terms of the GNU General Public License.
7
 *
8
 * History:
9
 *
10
 * 2002-03-13   Tomas Kasparek  initial release - based on h3600-uda1341.c from OSS
11
 * 2002-03-20   Tomas Kasparek  playback over ALSA is working
12
 * 2002-03-28   Tomas Kasparek  playback over OSS emulation is working
13
 * 2002-03-29   Tomas Kasparek  basic capture is working (native ALSA)
14
 * 2002-03-29   Tomas Kasparek  capture is working (OSS emulation)
15
 * 2002-04-04   Tomas Kasparek  better rates handling (allow non-standard rates)
16
 * 2003-02-14   Brian Avery     fixed full duplex mode, other updates
17
 * 2003-02-20   Tomas Kasparek  merged updates by Brian (except HAL)
18
 * 2003-04-19   Jaroslav Kysela recoded DMA stuff to follow 2.4.18rmk3-hh24 kernel
19
 *                              working suspend and resume
20
 * 2003-04-28   Tomas Kasparek  updated work by Jaroslav to compile it under 2.5.x again
21
 *                              merged HAL layer (patches from Brian)
22
 */
23
 
24
/* $Id: sa11xx-uda1341.c,v 1.27 2005/12/07 09:13:42 cladisch Exp $ */
25
 
26
/***************************************************************************************************
27
*
28
* To understand what Alsa Drivers should be doing look at "Writing an Alsa Driver" by Takashi Iwai
29
* available in the Alsa doc section on the website
30
*
31
* A few notes to make things clearer. The UDA1341 is hooked up to Serial port 4 on the SA1100.
32
* We are using  SSP mode to talk to the UDA1341. The UDA1341 bit & wordselect clocks are generated
33
* by this UART. Unfortunately, the clock only runs if the transmit buffer has something in it.
34
* So, if we are just recording, we feed the transmit DMA stream a bunch of 0x0000 so that the
35
* transmit buffer is full and the clock keeps going. The zeroes come from FLUSH_BASE_PHYS which
36
* is a mem loc that always decodes to 0's w/ no off chip access.
37
*
38
* Some alsa terminology:
39
*       frame => num_channels * sample_size  e.g stereo 16 bit is 2 * 16 = 32 bytes
40
*       period => the least number of bytes that will generate an interrupt e.g. we have a 1024 byte
41
*             buffer and 4 periods in the runtime structure this means we'll get an int every 256
42
*             bytes or 4 times per buffer.
43
*             A number of the sizes are in frames rather than bytes, use frames_to_bytes and
44
*             bytes_to_frames to convert.  The easiest way to tell the units is to look at the
45
*             type i.e. runtime-> buffer_size is in frames and its type is snd_pcm_uframes_t
46
*
47
*       Notes about the pointer fxn:
48
*       The pointer fxn needs to return the offset into the dma buffer in frames.
49
*       Interrupts must be blocked before calling the dma_get_pos fxn to avoid race with interrupts.
50
*
51
*       Notes about pause/resume
52
*       Implementing this would be complicated so it's skipped.  The problem case is:
53
*       A full duplex connection is going, then play is paused. At this point you need to start xmitting
54
*       0's to keep the record active which means you cant just freeze the dma and resume it later you'd
55
*       need to save off the dma info, and restore it properly on a resume.  Yeach!
56
*
57
*       Notes about transfer methods:
58
*       The async write calls fail.  I probably need to implement something else to support them?
59
*
60
***************************************************************************************************/
61
 
62
#include <sound/driver.h>
63
#include <linux/module.h>
64
#include <linux/moduleparam.h>
65
#include <linux/init.h>
66
#include <linux/err.h>
67
#include <linux/platform_device.h>
68
#include <linux/errno.h>
69
#include <linux/ioctl.h>
70
#include <linux/delay.h>
71
#include <linux/slab.h>
72
 
73
#ifdef CONFIG_PM
74
#include <linux/pm.h>
75
#endif
76
 
77
#include <asm/hardware.h>
78
#include <asm/arch/h3600.h>
79
#include <asm/mach-types.h>
80
#include <asm/dma.h>
81
 
82
#include <sound/core.h>
83
#include <sound/pcm.h>
84
#include <sound/initval.h>
85
 
86
#include <linux/l3/l3.h>
87
 
88
#undef DEBUG_MODE
89
#undef DEBUG_FUNCTION_NAMES
90
#include <sound/uda1341.h>
91
 
92
/*
93
 * FIXME: Is this enough as autodetection of 2.4.X-rmkY-hhZ kernels?
94
 * We use DMA stuff from 2.4.18-rmk3-hh24 here to be able to compile this
95
 * module for Familiar 0.6.1
96
 */
97
 
98
/* {{{ Type definitions */
99
 
100
MODULE_AUTHOR("Tomas Kasparek <tomas.kasparek@seznam.cz>");
101
MODULE_LICENSE("GPL");
102
MODULE_DESCRIPTION("SA1100/SA1111 + UDA1341TS driver for ALSA");
103
MODULE_SUPPORTED_DEVICE("{{UDA1341,iPAQ H3600 UDA1341TS}}");
104
 
105
static char *id;        /* ID for this card */
106
 
107
module_param(id, charp, 0444);
108
MODULE_PARM_DESC(id, "ID string for SA1100/SA1111 + UDA1341TS soundcard.");
109
 
110
struct audio_stream {
111
        char *id;               /* identification string */
112
        int stream_id;          /* numeric identification */
113
        dma_device_t dma_dev;   /* device identifier for DMA */
114
#ifdef HH_VERSION
115
        dmach_t dmach;          /* dma channel identification */
116
#else
117
        dma_regs_t *dma_regs;   /* points to our DMA registers */
118
#endif
119
        unsigned int active:1;  /* we are using this stream for transfer now */
120
        int period;             /* current transfer period */
121
        int periods;            /* current count of periods registerd in the DMA engine */
122
        int tx_spin;            /* are we recoding - flag used to do DMA trans. for sync */
123
        unsigned int old_offset;
124
        spinlock_t dma_lock;    /* for locking in DMA operations (see dma-sa1100.c in the kernel) */
125
        struct snd_pcm_substream *stream;
126
};
127
 
128
struct sa11xx_uda1341 {
129
        struct snd_card *card;
130
        struct l3_client *uda1341;
131
        struct snd_pcm *pcm;
132
        long samplerate;
133
        struct audio_stream s[2];       /* playback & capture */
134
};
135
 
136
static unsigned int rates[] = {
137
        8000,  10666, 10985, 14647,
138
        16000, 21970, 22050, 24000,
139
        29400, 32000, 44100, 48000,
140
};
141
 
142
static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
143
        .count  = ARRAY_SIZE(rates),
144
        .list   = rates,
145
        .mask   = 0,
146
};
147
 
148
static struct platform_device *device;
149
 
150
/* }}} */
151
 
152
/* {{{ Clock and sample rate stuff */
153
 
154
/*
155
 * Stop-gap solution until rest of hh.org HAL stuff is merged.
156
 */
157
#define GPIO_H3600_CLK_SET0             GPIO_GPIO (12)
158
#define GPIO_H3600_CLK_SET1             GPIO_GPIO (13)
159
 
160
#ifdef CONFIG_SA1100_H3XXX
161
#define clr_sa11xx_uda1341_egpio(x)     clr_h3600_egpio(x)
162
#define set_sa11xx_uda1341_egpio(x)     set_h3600_egpio(x)
163
#else
164
#error This driver could serve H3x00 handhelds only!
165
#endif
166
 
167
static void sa11xx_uda1341_set_audio_clock(long val)
168
{
169
        switch (val) {
170
        case 24000: case 32000: case 48000:     /* 00: 12.288 MHz */
171
                GPCR = GPIO_H3600_CLK_SET0 | GPIO_H3600_CLK_SET1;
172
                break;
173
 
174
        case 22050: case 29400: case 44100:     /* 01: 11.2896 MHz */
175
                GPSR = GPIO_H3600_CLK_SET0;
176
                GPCR = GPIO_H3600_CLK_SET1;
177
                break;
178
 
179
        case 8000: case 10666: case 16000:      /* 10: 4.096 MHz */
180
                GPCR = GPIO_H3600_CLK_SET0;
181
                GPSR = GPIO_H3600_CLK_SET1;
182
                break;
183
 
184
        case 10985: case 14647: case 21970:     /* 11: 5.6245 MHz */
185
                GPSR = GPIO_H3600_CLK_SET0 | GPIO_H3600_CLK_SET1;
186
                break;
187
        }
188
}
189
 
190
static void sa11xx_uda1341_set_samplerate(struct sa11xx_uda1341 *sa11xx_uda1341, long rate)
191
{
192
        int clk_div = 0;
193
        int clk=0;
194
 
195
        /* We don't want to mess with clocks when frames are in flight */
196
        Ser4SSCR0 &= ~SSCR0_SSE;
197
        /* wait for any frame to complete */
198
        udelay(125);
199
 
200
        /*
201
         * We have the following clock sources:
202
         * 4.096 MHz, 5.6245 MHz, 11.2896 MHz, 12.288 MHz
203
         * Those can be divided either by 256, 384 or 512.
204
         * This makes up 12 combinations for the following samplerates...
205
         */
206
        if (rate >= 48000)
207
                rate = 48000;
208
        else if (rate >= 44100)
209
                rate = 44100;
210
        else if (rate >= 32000)
211
                rate = 32000;
212
        else if (rate >= 29400)
213
                rate = 29400;
214
        else if (rate >= 24000)
215
                rate = 24000;
216
        else if (rate >= 22050)
217
                rate = 22050;
218
        else if (rate >= 21970)
219
                rate = 21970;
220
        else if (rate >= 16000)
221
                rate = 16000;
222
        else if (rate >= 14647)
223
                rate = 14647;
224
        else if (rate >= 10985)
225
                rate = 10985;
226
        else if (rate >= 10666)
227
                rate = 10666;
228
        else
229
                rate = 8000;
230
 
231
        /* Set the external clock generator */
232
 
233
        sa11xx_uda1341_set_audio_clock(rate);
234
 
235
        /* Select the clock divisor */
236
        switch (rate) {
237
        case 8000:
238
        case 10985:
239
        case 22050:
240
        case 24000:
241
                clk = F512;
242
                clk_div = SSCR0_SerClkDiv(16);
243
                break;
244
        case 16000:
245
        case 21970:
246
        case 44100:
247
        case 48000:
248
                clk = F256;
249
                clk_div = SSCR0_SerClkDiv(8);
250
                break;
251
        case 10666:
252
        case 14647:
253
        case 29400:
254
        case 32000:
255
                clk = F384;
256
                clk_div = SSCR0_SerClkDiv(12);
257
                break;
258
        }
259
 
260
        /* FMT setting should be moved away when other FMTs are added (FIXME) */
261
        l3_command(sa11xx_uda1341->uda1341, CMD_FORMAT, (void *)LSB16);
262
 
263
        l3_command(sa11xx_uda1341->uda1341, CMD_FS, (void *)clk);
264
        Ser4SSCR0 = (Ser4SSCR0 & ~0xff00) + clk_div + SSCR0_SSE;
265
        sa11xx_uda1341->samplerate = rate;
266
}
267
 
268
/* }}} */
269
 
270
/* {{{ HW init and shutdown */
271
 
272
static void sa11xx_uda1341_audio_init(struct sa11xx_uda1341 *sa11xx_uda1341)
273
{
274
        unsigned long flags;
275
 
276
        /* Setup DMA stuff */
277
        sa11xx_uda1341->s[SNDRV_PCM_STREAM_PLAYBACK].id = "UDA1341 out";
278
        sa11xx_uda1341->s[SNDRV_PCM_STREAM_PLAYBACK].stream_id = SNDRV_PCM_STREAM_PLAYBACK;
279
        sa11xx_uda1341->s[SNDRV_PCM_STREAM_PLAYBACK].dma_dev = DMA_Ser4SSPWr;
280
 
281
        sa11xx_uda1341->s[SNDRV_PCM_STREAM_CAPTURE].id = "UDA1341 in";
282
        sa11xx_uda1341->s[SNDRV_PCM_STREAM_CAPTURE].stream_id = SNDRV_PCM_STREAM_CAPTURE;
283
        sa11xx_uda1341->s[SNDRV_PCM_STREAM_CAPTURE].dma_dev = DMA_Ser4SSPRd;
284
 
285
        /* Initialize the UDA1341 internal state */
286
 
287
        /* Setup the uarts */
288
        local_irq_save(flags);
289
        GAFR |= (GPIO_SSP_CLK);
290
        GPDR &= ~(GPIO_SSP_CLK);
291
        Ser4SSCR0 = 0;
292
        Ser4SSCR0 = SSCR0_DataSize(16) + SSCR0_TI + SSCR0_SerClkDiv(8);
293
        Ser4SSCR1 = SSCR1_SClkIactL + SSCR1_SClk1P + SSCR1_ExtClk;
294
        Ser4SSCR0 |= SSCR0_SSE;
295
        local_irq_restore(flags);
296
 
297
        /* Enable the audio power */
298
 
299
        clr_sa11xx_uda1341_egpio(IPAQ_EGPIO_CODEC_NRESET);
300
        set_sa11xx_uda1341_egpio(IPAQ_EGPIO_AUDIO_ON);
301
        set_sa11xx_uda1341_egpio(IPAQ_EGPIO_QMUTE);
302
 
303
        /* Wait for the UDA1341 to wake up */
304
        mdelay(1); //FIXME - was removed by Perex - Why?
305
 
306
        /* Initialize the UDA1341 internal state */
307
        l3_open(sa11xx_uda1341->uda1341);
308
 
309
        /* external clock configuration (after l3_open - regs must be initialized */
310
        sa11xx_uda1341_set_samplerate(sa11xx_uda1341, sa11xx_uda1341->samplerate);
311
 
312
        /* Wait for the UDA1341 to wake up */
313
        set_sa11xx_uda1341_egpio(IPAQ_EGPIO_CODEC_NRESET);
314
        mdelay(1);
315
 
316
        /* make the left and right channels unswapped (flip the WS latch) */
317
        Ser4SSDR = 0;
318
 
319
        clr_sa11xx_uda1341_egpio(IPAQ_EGPIO_QMUTE);
320
}
321
 
322
static void sa11xx_uda1341_audio_shutdown(struct sa11xx_uda1341 *sa11xx_uda1341)
323
{
324
        /* mute on */
325
        set_sa11xx_uda1341_egpio(IPAQ_EGPIO_QMUTE);
326
 
327
        /* disable the audio power and all signals leading to the audio chip */
328
        l3_close(sa11xx_uda1341->uda1341);
329
        Ser4SSCR0 = 0;
330
        clr_sa11xx_uda1341_egpio(IPAQ_EGPIO_CODEC_NRESET);
331
 
332
        /* power off and mute off */
333
        /* FIXME - is muting off necesary??? */
334
 
335
        clr_sa11xx_uda1341_egpio(IPAQ_EGPIO_AUDIO_ON);
336
        clr_sa11xx_uda1341_egpio(IPAQ_EGPIO_QMUTE);
337
}
338
 
339
/* }}} */
340
 
341
/* {{{ DMA staff */
342
 
343
/*
344
 * these are the address and sizes used to fill the xmit buffer
345
 * so we can get a clock in record only mode
346
 */
347
#define FORCE_CLOCK_ADDR                (dma_addr_t)FLUSH_BASE_PHYS
348
#define FORCE_CLOCK_SIZE                4096 // was 2048
349
 
350
// FIXME Why this value exactly - wrote comment
351
#define DMA_BUF_SIZE    8176    /* <= MAX_DMA_SIZE from asm/arch-sa1100/dma.h */
352
 
353
#ifdef HH_VERSION
354
 
355
static int audio_dma_request(struct audio_stream *s, void (*callback)(void *, int))
356
{
357
        int ret;
358
 
359
        ret = sa1100_request_dma(&s->dmach, s->id, s->dma_dev);
360
        if (ret < 0) {
361
                printk(KERN_ERR "unable to grab audio dma 0x%x\n", s->dma_dev);
362
                return ret;
363
        }
364
        sa1100_dma_set_callback(s->dmach, callback);
365
        return 0;
366
}
367
 
368
static inline void audio_dma_free(struct audio_stream *s)
369
{
370
        sa1100_free_dma(s->dmach);
371
        s->dmach = -1;
372
}
373
 
374
#else
375
 
376
static int audio_dma_request(struct audio_stream *s, void (*callback)(void *))
377
{
378
        int ret;
379
 
380
        ret = sa1100_request_dma(s->dma_dev, s->id, callback, s, &s->dma_regs);
381
        if (ret < 0)
382
                printk(KERN_ERR "unable to grab audio dma 0x%x\n", s->dma_dev);
383
        return ret;
384
}
385
 
386
static void audio_dma_free(struct audio_stream *s)
387
{
388
        sa1100_free_dma(s->dma_regs);
389
        s->dma_regs = 0;
390
}
391
 
392
#endif
393
 
394
static u_int audio_get_dma_pos(struct audio_stream *s)
395
{
396
        struct snd_pcm_substream *substream = s->stream;
397
        struct snd_pcm_runtime *runtime = substream->runtime;
398
        unsigned int offset;
399
        unsigned long flags;
400
        dma_addr_t addr;
401
 
402
        // this must be called w/ interrupts locked out see dma-sa1100.c in the kernel
403
        spin_lock_irqsave(&s->dma_lock, flags);
404
#ifdef HH_VERSION       
405
        sa1100_dma_get_current(s->dmach, NULL, &addr);
406
#else
407
        addr = sa1100_get_dma_pos((s)->dma_regs);
408
#endif
409
        offset = addr - runtime->dma_addr;
410
        spin_unlock_irqrestore(&s->dma_lock, flags);
411
 
412
        offset = bytes_to_frames(runtime,offset);
413
        if (offset >= runtime->buffer_size)
414
                offset = 0;
415
 
416
        return offset;
417
}
418
 
419
/*
420
 * this stops the dma and clears the dma ptrs
421
 */
422
static void audio_stop_dma(struct audio_stream *s)
423
{
424
        unsigned long flags;
425
 
426
        spin_lock_irqsave(&s->dma_lock, flags);
427
        s->active = 0;
428
        s->period = 0;
429
        /* this stops the dma channel and clears the buffer ptrs */
430
#ifdef HH_VERSION
431
        sa1100_dma_flush_all(s->dmach);
432
#else
433
        sa1100_clear_dma(s->dma_regs);
434
#endif
435
        spin_unlock_irqrestore(&s->dma_lock, flags);
436
}
437
 
438
static void audio_process_dma(struct audio_stream *s)
439
{
440
        struct snd_pcm_substream *substream = s->stream;
441
        struct snd_pcm_runtime *runtime;
442
        unsigned int dma_size;
443
        unsigned int offset;
444
        int ret;
445
 
446
        /* we are requested to process synchronization DMA transfer */
447
        if (s->tx_spin) {
448
                snd_assert(s->stream_id == SNDRV_PCM_STREAM_PLAYBACK, return);
449
                /* fill the xmit dma buffers and return */
450
#ifdef HH_VERSION
451
                sa1100_dma_set_spin(s->dmach, FORCE_CLOCK_ADDR, FORCE_CLOCK_SIZE);
452
#else
453
                while (1) {
454
                        ret = sa1100_start_dma(s->dma_regs, FORCE_CLOCK_ADDR, FORCE_CLOCK_SIZE);
455
                        if (ret)
456
                                return;
457
                }
458
#endif
459
                return;
460
        }
461
 
462
        /* must be set here - only valid for running streams, not for forced_clock dma fills  */
463
        runtime = substream->runtime;
464
        while (s->active && s->periods < runtime->periods) {
465
                dma_size = frames_to_bytes(runtime, runtime->period_size);
466
                if (s->old_offset) {
467
                        /* a little trick, we need resume from old position */
468
                        offset = frames_to_bytes(runtime, s->old_offset - 1);
469
                        s->old_offset = 0;
470
                        s->periods = 0;
471
                        s->period = offset / dma_size;
472
                        offset %= dma_size;
473
                        dma_size = dma_size - offset;
474
                        if (!dma_size)
475
                                continue;               /* special case */
476
                } else {
477
                        offset = dma_size * s->period;
478
                        snd_assert(dma_size <= DMA_BUF_SIZE, );
479
                }
480
#ifdef HH_VERSION
481
                ret = sa1100_dma_queue_buffer(s->dmach, s, runtime->dma_addr + offset, dma_size);
482
                if (ret)
483
                        return; //FIXME
484
#else
485
                ret = sa1100_start_dma((s)->dma_regs, runtime->dma_addr + offset, dma_size);
486
                if (ret) {
487
                        printk(KERN_ERR "audio_process_dma: cannot queue DMA buffer (%i)\n", ret);
488
                        return;
489
                }
490
#endif
491
 
492
                s->period++;
493
                s->period %= runtime->periods;
494
                s->periods++;
495
        }
496
}
497
 
498
#ifdef HH_VERSION
499
static void audio_dma_callback(void *data, int size)
500
#else
501
static void audio_dma_callback(void *data)
502
#endif
503
{
504
        struct audio_stream *s = data;
505
 
506
        /*
507
         * If we are getting a callback for an active stream then we inform
508
         * the PCM middle layer we've finished a period
509
         */
510
        if (s->active)
511
                snd_pcm_period_elapsed(s->stream);
512
 
513
        spin_lock(&s->dma_lock);
514
        if (!s->tx_spin && s->periods > 0)
515
                s->periods--;
516
        audio_process_dma(s);
517
        spin_unlock(&s->dma_lock);
518
}
519
 
520
/* }}} */
521
 
522
/* {{{ PCM setting */
523
 
524
/* {{{ trigger & timer */
525
 
526
static int snd_sa11xx_uda1341_trigger(struct snd_pcm_substream *substream, int cmd)
527
{
528
        struct sa11xx_uda1341 *chip = snd_pcm_substream_chip(substream);
529
        int stream_id = substream->pstr->stream;
530
        struct audio_stream *s = &chip->s[stream_id];
531
        struct audio_stream *s1 = &chip->s[stream_id ^ 1];
532
        int err = 0;
533
 
534
        /* note local interrupts are already disabled in the midlevel code */
535
        spin_lock(&s->dma_lock);
536
        switch (cmd) {
537
        case SNDRV_PCM_TRIGGER_START:
538
                /* now we need to make sure a record only stream has a clock */
539
                if (stream_id == SNDRV_PCM_STREAM_CAPTURE && !s1->active) {
540
                        /* we need to force fill the xmit DMA with zeros */
541
                        s1->tx_spin = 1;
542
                        audio_process_dma(s1);
543
                }
544
                /* this case is when you were recording then you turn on a
545
                 * playback stream so we stop (also clears it) the dma first,
546
                 * clear the sync flag and then we let it turned on
547
                 */
548
                else {
549
                        s->tx_spin = 0;
550
                }
551
 
552
                /* requested stream startup */
553
                s->active = 1;
554
                audio_process_dma(s);
555
                break;
556
        case SNDRV_PCM_TRIGGER_STOP:
557
                /* requested stream shutdown */
558
                audio_stop_dma(s);
559
 
560
                /*
561
                 * now we need to make sure a record only stream has a clock
562
                 * so if we're stopping a playback with an active capture
563
                 * we need to turn the 0 fill dma on for the xmit side
564
                 */
565
                if (stream_id == SNDRV_PCM_STREAM_PLAYBACK && s1->active) {
566
                        /* we need to force fill the xmit DMA with zeros */
567
                        s->tx_spin = 1;
568
                        audio_process_dma(s);
569
                }
570
                /*
571
                 * we killed a capture only stream, so we should also kill
572
                 * the zero fill transmit
573
                 */
574
                else {
575
                        if (s1->tx_spin) {
576
                                s1->tx_spin = 0;
577
                                audio_stop_dma(s1);
578
                        }
579
                }
580
 
581
                break;
582
        case SNDRV_PCM_TRIGGER_SUSPEND:
583
                s->active = 0;
584
#ifdef HH_VERSION               
585
                sa1100_dma_stop(s->dmach);
586
#else
587
                //FIXME - DMA API
588
#endif          
589
                s->old_offset = audio_get_dma_pos(s) + 1;
590
#ifdef HH_VERSION               
591
                sa1100_dma_flush_all(s->dmach);
592
#else
593
                //FIXME - DMA API
594
#endif          
595
                s->periods = 0;
596
                break;
597
        case SNDRV_PCM_TRIGGER_RESUME:
598
                s->active = 1;
599
                s->tx_spin = 0;
600
                audio_process_dma(s);
601
                if (stream_id == SNDRV_PCM_STREAM_CAPTURE && !s1->active) {
602
                        s1->tx_spin = 1;
603
                        audio_process_dma(s1);
604
                }
605
                break;
606
        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
607
#ifdef HH_VERSION               
608
                sa1100_dma_stop(s->dmach);
609
#else
610
                //FIXME - DMA API
611
#endif
612
                s->active = 0;
613
                if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) {
614
                        if (s1->active) {
615
                                s->tx_spin = 1;
616
                                s->old_offset = audio_get_dma_pos(s) + 1;
617
#ifdef HH_VERSION                               
618
                                sa1100_dma_flush_all(s->dmach);
619
#else
620
                                //FIXME - DMA API
621
#endif                          
622
                                audio_process_dma(s);
623
                        }
624
                } else {
625
                        if (s1->tx_spin) {
626
                                s1->tx_spin = 0;
627
#ifdef HH_VERSION                               
628
                                sa1100_dma_flush_all(s1->dmach);
629
#else
630
                                //FIXME - DMA API
631
#endif                          
632
                        }
633
                }
634
                break;
635
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
636
                s->active = 1;
637
                if (s->old_offset) {
638
                        s->tx_spin = 0;
639
                        audio_process_dma(s);
640
                        break;
641
                }
642
                if (stream_id == SNDRV_PCM_STREAM_CAPTURE && !s1->active) {
643
                        s1->tx_spin = 1;
644
                        audio_process_dma(s1);
645
                }
646
#ifdef HH_VERSION               
647
                sa1100_dma_resume(s->dmach);
648
#else
649
                //FIXME - DMA API
650
#endif
651
                break;
652
        default:
653
                err = -EINVAL;
654
                break;
655
        }
656
        spin_unlock(&s->dma_lock);
657
        return err;
658
}
659
 
660
static int snd_sa11xx_uda1341_prepare(struct snd_pcm_substream *substream)
661
{
662
        struct sa11xx_uda1341 *chip = snd_pcm_substream_chip(substream);
663
        struct snd_pcm_runtime *runtime = substream->runtime;
664
        struct audio_stream *s = &chip->s[substream->pstr->stream];
665
 
666
        /* set requested samplerate */
667
        sa11xx_uda1341_set_samplerate(chip, runtime->rate);
668
 
669
        /* set requestd format when available */
670
        /* set FMT here !!! FIXME */
671
 
672
        s->period = 0;
673
        s->periods = 0;
674
 
675
        return 0;
676
}
677
 
678
static snd_pcm_uframes_t snd_sa11xx_uda1341_pointer(struct snd_pcm_substream *substream)
679
{
680
        struct sa11xx_uda1341 *chip = snd_pcm_substream_chip(substream);
681
        return audio_get_dma_pos(&chip->s[substream->pstr->stream]);
682
}
683
 
684
/* }}} */
685
 
686
static struct snd_pcm_hardware snd_sa11xx_uda1341_capture =
687
{
688
        .info                   = (SNDRV_PCM_INFO_INTERLEAVED |
689
                                   SNDRV_PCM_INFO_BLOCK_TRANSFER |
690
                                   SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
691
                                   SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
692
        .formats                = SNDRV_PCM_FMTBIT_S16_LE,
693
        .rates                  = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
694
                                   SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |\
695
                                   SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
696
                                   SNDRV_PCM_RATE_KNOT),
697
        .rate_min               = 8000,
698
        .rate_max               = 48000,
699
        .channels_min           = 2,
700
        .channels_max           = 2,
701
        .buffer_bytes_max       = 64*1024,
702
        .period_bytes_min       = 64,
703
        .period_bytes_max       = DMA_BUF_SIZE,
704
        .periods_min            = 2,
705
        .periods_max            = 255,
706
        .fifo_size              = 0,
707
};
708
 
709
static struct snd_pcm_hardware snd_sa11xx_uda1341_playback =
710
{
711
        .info                   = (SNDRV_PCM_INFO_INTERLEAVED |
712
                                   SNDRV_PCM_INFO_BLOCK_TRANSFER |
713
                                   SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
714
                                   SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
715
        .formats                = SNDRV_PCM_FMTBIT_S16_LE,
716
        .rates                  = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
717
                                   SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |\
718
                                   SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
719
                                   SNDRV_PCM_RATE_KNOT),
720
        .rate_min               = 8000,
721
        .rate_max               = 48000,
722
        .channels_min           = 2,
723
        .channels_max           = 2,
724
        .buffer_bytes_max       = 64*1024,
725
        .period_bytes_min       = 64,
726
        .period_bytes_max       = DMA_BUF_SIZE,
727
        .periods_min            = 2,
728
        .periods_max            = 255,
729
        .fifo_size              = 0,
730
};
731
 
732
static int snd_card_sa11xx_uda1341_open(struct snd_pcm_substream *substream)
733
{
734
        struct sa11xx_uda1341 *chip = snd_pcm_substream_chip(substream);
735
        struct snd_pcm_runtime *runtime = substream->runtime;
736
        int stream_id = substream->pstr->stream;
737
        int err;
738
 
739
        chip->s[stream_id].stream = substream;
740
 
741
        if (stream_id == SNDRV_PCM_STREAM_PLAYBACK)
742
                runtime->hw = snd_sa11xx_uda1341_playback;
743
        else
744
                runtime->hw = snd_sa11xx_uda1341_capture;
745
        if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
746
                return err;
747
        if ((err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates)) < 0)
748
                return err;
749
 
750
        return 0;
751
}
752
 
753
static int snd_card_sa11xx_uda1341_close(struct snd_pcm_substream *substream)
754
{
755
        struct sa11xx_uda1341 *chip = snd_pcm_substream_chip(substream);
756
 
757
        chip->s[substream->pstr->stream].stream = NULL;
758
        return 0;
759
}
760
 
761
/* {{{ HW params & free */
762
 
763
static int snd_sa11xx_uda1341_hw_params(struct snd_pcm_substream *substream,
764
                                        struct snd_pcm_hw_params *hw_params)
765
{
766
 
767
        return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
768
}
769
 
770
static int snd_sa11xx_uda1341_hw_free(struct snd_pcm_substream *substream)
771
{
772
        return snd_pcm_lib_free_pages(substream);
773
}
774
 
775
/* }}} */
776
 
777
static struct snd_pcm_ops snd_card_sa11xx_uda1341_playback_ops = {
778
        .open                   = snd_card_sa11xx_uda1341_open,
779
        .close                  = snd_card_sa11xx_uda1341_close,
780
        .ioctl                  = snd_pcm_lib_ioctl,
781
        .hw_params              = snd_sa11xx_uda1341_hw_params,
782
        .hw_free                = snd_sa11xx_uda1341_hw_free,
783
        .prepare                = snd_sa11xx_uda1341_prepare,
784
        .trigger                = snd_sa11xx_uda1341_trigger,
785
        .pointer                = snd_sa11xx_uda1341_pointer,
786
};
787
 
788
static struct snd_pcm_ops snd_card_sa11xx_uda1341_capture_ops = {
789
        .open                   = snd_card_sa11xx_uda1341_open,
790
        .close                  = snd_card_sa11xx_uda1341_close,
791
        .ioctl                  = snd_pcm_lib_ioctl,
792
        .hw_params              = snd_sa11xx_uda1341_hw_params,
793
        .hw_free                = snd_sa11xx_uda1341_hw_free,
794
        .prepare                = snd_sa11xx_uda1341_prepare,
795
        .trigger                = snd_sa11xx_uda1341_trigger,
796
        .pointer                = snd_sa11xx_uda1341_pointer,
797
};
798
 
799
static int __init snd_card_sa11xx_uda1341_pcm(struct sa11xx_uda1341 *sa11xx_uda1341, int device)
800
{
801
        struct snd_pcm *pcm;
802
        int err;
803
 
804
        if ((err = snd_pcm_new(sa11xx_uda1341->card, "UDA1341 PCM", device, 1, 1, &pcm)) < 0)
805
                return err;
806
 
807
        /*
808
         * this sets up our initial buffers and sets the dma_type to isa.
809
         * isa works but I'm not sure why (or if) it's the right choice
810
         * this may be too large, trying it for now
811
         */
812
        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
813
                                              snd_dma_isa_data(),
814
                                              64*1024, 64*1024);
815
 
816
        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_card_sa11xx_uda1341_playback_ops);
817
        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_card_sa11xx_uda1341_capture_ops);
818
        pcm->private_data = sa11xx_uda1341;
819
        pcm->info_flags = 0;
820
        strcpy(pcm->name, "UDA1341 PCM");
821
 
822
        sa11xx_uda1341_audio_init(sa11xx_uda1341);
823
 
824
        /* setup DMA controller */
825
        audio_dma_request(&sa11xx_uda1341->s[SNDRV_PCM_STREAM_PLAYBACK], audio_dma_callback);
826
        audio_dma_request(&sa11xx_uda1341->s[SNDRV_PCM_STREAM_CAPTURE], audio_dma_callback);
827
 
828
        sa11xx_uda1341->pcm = pcm;
829
 
830
        return 0;
831
}
832
 
833
/* }}} */
834
 
835
/* {{{ module init & exit */
836
 
837
#ifdef CONFIG_PM
838
 
839
static int snd_sa11xx_uda1341_suspend(struct platform_device *devptr,
840
                                      pm_message_t state)
841
{
842
        struct snd_card *card = platform_get_drvdata(devptr);
843
        struct sa11xx_uda1341 *chip = card->private_data;
844
 
845
        snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
846
        snd_pcm_suspend_all(chip->pcm);
847
#ifdef HH_VERSION
848
        sa1100_dma_sleep(chip->s[SNDRV_PCM_STREAM_PLAYBACK].dmach);
849
        sa1100_dma_sleep(chip->s[SNDRV_PCM_STREAM_CAPTURE].dmach);
850
#else
851
        //FIXME
852
#endif
853
        l3_command(chip->uda1341, CMD_SUSPEND, NULL);
854
        sa11xx_uda1341_audio_shutdown(chip);
855
 
856
        return 0;
857
}
858
 
859
static int snd_sa11xx_uda1341_resume(struct platform_device *devptr)
860
{
861
        struct snd_card *card = platform_get_drvdata(devptr);
862
        struct sa11xx_uda1341 *chip = card->private_data;
863
 
864
        sa11xx_uda1341_audio_init(chip);
865
        l3_command(chip->uda1341, CMD_RESUME, NULL);
866
#ifdef HH_VERSION       
867
        sa1100_dma_wakeup(chip->s[SNDRV_PCM_STREAM_PLAYBACK].dmach);
868
        sa1100_dma_wakeup(chip->s[SNDRV_PCM_STREAM_CAPTURE].dmach);
869
#else
870
        //FIXME
871
#endif
872
        snd_power_change_state(card, SNDRV_CTL_POWER_D0);
873
        return 0;
874
}
875
#endif /* COMFIG_PM */
876
 
877
void snd_sa11xx_uda1341_free(struct snd_card *card)
878
{
879
        struct sa11xx_uda1341 *chip = card->private_data;
880
 
881
        audio_dma_free(&chip->s[SNDRV_PCM_STREAM_PLAYBACK]);
882
        audio_dma_free(&chip->s[SNDRV_PCM_STREAM_CAPTURE]);
883
}
884
 
885
static int __init sa11xx_uda1341_probe(struct platform_device *devptr)
886
{
887
        int err;
888
        struct snd_card *card;
889
        struct sa11xx_uda1341 *chip;
890
 
891
        /* register the soundcard */
892
        card = snd_card_new(-1, id, THIS_MODULE, sizeof(struct sa11xx_uda1341));
893
        if (card == NULL)
894
                return -ENOMEM;
895
 
896
        chip = card->private_data;
897
        spin_lock_init(&chip->s[0].dma_lock);
898
        spin_lock_init(&chip->s[1].dma_lock);
899
 
900
        card->private_free = snd_sa11xx_uda1341_free;
901
        chip->card = card;
902
        chip->samplerate = AUDIO_RATE_DEFAULT;
903
 
904
        // mixer
905
        if ((err = snd_chip_uda1341_mixer_new(card, &chip->uda1341)))
906
                goto nodev;
907
 
908
        // PCM
909
        if ((err = snd_card_sa11xx_uda1341_pcm(chip, 0)) < 0)
910
                goto nodev;
911
 
912
        strcpy(card->driver, "UDA1341");
913
        strcpy(card->shortname, "H3600 UDA1341TS");
914
        sprintf(card->longname, "Compaq iPAQ H3600 with Philips UDA1341TS");
915
 
916
        snd_card_set_dev(card, &devptr->dev);
917
 
918
        if ((err = snd_card_register(card)) == 0) {
919
                printk( KERN_INFO "iPAQ audio support initialized\n" );
920
                platform_set_drvdata(devptr, card);
921
                return 0;
922
        }
923
 
924
 nodev:
925
        snd_card_free(card);
926
        return err;
927
}
928
 
929
static int __devexit sa11xx_uda1341_remove(struct platform_device *devptr)
930
{
931
        snd_card_free(platform_get_drvdata(devptr));
932
        platform_set_drvdata(devptr, NULL);
933
        return 0;
934
}
935
 
936
#define SA11XX_UDA1341_DRIVER   "sa11xx_uda1341"
937
 
938
static struct platform_driver sa11xx_uda1341_driver = {
939
        .probe          = sa11xx_uda1341_probe,
940
        .remove         = __devexit_p(sa11xx_uda1341_remove),
941
#ifdef CONFIG_PM
942
        .suspend        = snd_sa11xx_uda1341_suspend,
943
        .resume         = snd_sa11xx_uda1341_resume,
944
#endif
945
        .driver         = {
946
                .name   = SA11XX_UDA1341_DRIVER,
947
        },
948
};
949
 
950
static int __init sa11xx_uda1341_init(void)
951
{
952
        int err;
953
 
954
        if (!machine_is_h3xxx())
955
                return -ENODEV;
956
        if ((err = platform_driver_register(&sa11xx_uda1341_driver)) < 0)
957
                return err;
958
        device = platform_device_register_simple(SA11XX_UDA1341_DRIVER, -1, NULL, 0);
959
        if (!IS_ERR(device)) {
960
                if (platform_get_drvdata(device))
961
                        return 0;
962
                platform_device_unregister(device);
963
                err = -ENODEV;
964
        } else
965
                err = PTR_ERR(device);
966
        platform_driver_unregister(&sa11xx_uda1341_driver);
967
        return err;
968
}
969
 
970
static void __exit sa11xx_uda1341_exit(void)
971
{
972
        platform_device_unregister(device);
973
        platform_driver_unregister(&sa11xx_uda1341_driver);
974
}
975
 
976
module_init(sa11xx_uda1341_init);
977
module_exit(sa11xx_uda1341_exit);
978
 
979
/* }}} */
980
 
981
/*
982
 * Local variables:
983
 * indent-tabs-mode: t
984
 * End:
985
 */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.