]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - sound/arm/omap-aic23.c
Merge with ../linux-2.6
[linux-2.6-omap-h63xx.git] / sound / arm / omap-aic23.c
1 /*
2  * sound/arm/omap-aic23.c
3  * 
4  * Alsa Driver for AIC23 codec on OSK5912 platform board
5  *
6  * Copyright (C) 2005 Instituto Nokia de Tecnologia - INdT - Manaus Brazil
7  * Written by Daniel Petrini, David Cohen, Anderson Briglia
8  *            {daniel.petrini, david.cohen, anderson.briglia}@indt.org.br
9  *
10  * Based on sa11xx-uda1341.c, 
11  * Copyright (C) 2002 Tomas Kasparek <tomas.kasparek@seznam.cz>
12  *
13  * This program is free software; you can redistribute it and/or modify it
14  * under the terms of the GNU General Public License as published by the
15  * Free Software Foundation; either version 2 of the License, or (at your
16  * option) any later version.
17  *
18  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
19  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
21  * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  *
29  * You should have received a copy of the  GNU General Public License along
30  * with this program; if not, write  to the Free Software Foundation, Inc.,
31  * 675 Mass Ave, Cambridge, MA 02139, USA.
32  *
33  * History:
34  *
35  * 2005-07-29   INdT Kernel Team - Alsa driver for omap osk. Creation of new 
36  *                                 file omap-aic23.c
37  */
38
39 #include <linux/config.h>
40 #include <sound/driver.h>
41 #include <linux/module.h>
42 #include <linux/device.h>
43 #include <linux/moduleparam.h>
44 #include <linux/init.h>
45 #include <linux/errno.h>
46 #include <linux/ioctl.h>
47 #include <linux/delay.h>
48 #include <linux/slab.h>
49
50 #ifdef CONFIG_PM
51 #include <linux/pm.h>
52 #endif
53
54 #include <asm/hardware.h>
55 #include <asm/mach-types.h>
56 #include <asm/arch/dma.h>
57 #include <asm/arch/aic23.h>
58 #include <asm/hardware/clock.h>
59 #include <asm/arch/mcbsp.h>
60
61 #include <sound/core.h>
62 #include <sound/pcm.h>
63 #include <sound/initval.h>
64 #include <sound/memalloc.h>
65
66 #include "omap-alsa-dma.h"
67 #include "omap-aic23.h"
68
69 #undef DEBUG
70
71 #ifdef DEBUG
72 #define ADEBUG() printk("XXX Alsa debug f:%s, l:%d\n", __FUNCTION__, __LINE__)
73 #else
74 #define ADEBUG()                /* nop */
75 #endif
76
77 /* Define to set the AIC23 as the master w.r.t McBSP */
78 #define AIC23_MASTER
79
80 /*
81  * AUDIO related MACROS
82  */
83 #define DEFAULT_BITPERSAMPLE          16
84 #define AUDIO_RATE_DEFAULT            44100
85 #define AUDIO_MCBSP                   OMAP_MCBSP1
86 #define NUMBER_SAMPLE_RATES_SUPPORTED 10
87
88
89 MODULE_AUTHOR("Daniel Petrini, David Cohen, Anderson Briglia - INdT");
90 MODULE_LICENSE("GPL");
91 MODULE_DESCRIPTION("OMAP AIC23 driver for ALSA");
92 MODULE_SUPPORTED_DEVICE("{{AIC23,OMAP AIC23}}");
93 MODULE_ALIAS("omap_mcbsp.1");
94
95 static char *id = NULL; 
96 MODULE_PARM_DESC(id, "OMAP OSK ALSA Driver for AIC23 chip.");
97
98 static struct snd_card_omap_aic23 *omap_aic23 = NULL;
99
100 static struct clk *aic23_mclk = 0;
101
102 struct sample_rate_rate_reg_info {
103         u8 control;             /* SR3, SR2, SR1, SR0 and BOSR */
104         u8 divider;             /* if 0 CLKIN = MCLK, if 1 CLKIN = MCLK/2 */
105 };
106
107 /*
108  * DAC USB-mode sampling rates (MCLK = 12 MHz)
109  * The rates and rate_reg_into MUST be in the same order
110  */
111 static unsigned int rates[] = {
112         4000, 8000, 16000, 22050,
113         24000, 32000, 44100,
114         48000, 88200, 96000,
115 };
116 static const struct sample_rate_rate_reg_info
117  rate_reg_info[NUMBER_SAMPLE_RATES_SUPPORTED] = {
118         {0x06, 1},              /*  4000 */
119         {0x06, 0},              /*  8000 */
120         {0x0C, 1},              /* 16000 */
121         {0x11, 1},              /* 22050 */
122         {0x00, 1},              /* 24000 */
123         {0x0C, 0},              /* 32000 */
124         {0x11, 0},              /* 44100 */
125         {0x00, 0},              /* 48000 */
126         {0x1F, 0},              /* 88200 */
127         {0x0E, 0},              /* 96000 */
128 };
129
130 /*
131  *  mcbsp configuration structure
132  */
133 static struct omap_mcbsp_reg_cfg initial_config_mcbsp = {
134         .spcr2 = FREE | FRST | GRST | XRST | XINTM(3),
135         .spcr1 = RINTM(3) | RRST,
136         .rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) |
137             RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(0),
138         .rcr1 = RFRLEN1(OMAP_MCBSP_WORD_8) | RWDLEN1(OMAP_MCBSP_WORD_16),
139         .xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) |
140             XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(0) | XFIG,
141         .xcr1 = XFRLEN1(OMAP_MCBSP_WORD_8) | XWDLEN1(OMAP_MCBSP_WORD_16),
142         .srgr1 = FWID(DEFAULT_BITPERSAMPLE - 1),
143         .srgr2 = GSYNC | CLKSP | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1),
144 #ifndef AIC23_MASTER
145         /* configure McBSP to be the I2S master */
146         .pcr0 = FSXM | FSRM | CLKXM | CLKRM | CLKXP | CLKRP,
147 #else
148         /* configure McBSP to be the I2S slave */
149         .pcr0 = CLKXP | CLKRP,
150 #endif                          /* AIC23_MASTER */
151 };
152
153 static snd_pcm_hw_constraint_list_t hw_constraints_rates = {
154         .count = ARRAY_SIZE(rates),
155         .list = rates,
156         .mask = 0,
157 };
158
159
160 /*
161  * Codec/mcbsp init and configuration section
162  * codec dependent code.
163  */
164
165 extern int tlv320aic23_write_value(u8 reg, u16 value);
166
167 /* TLV320AIC23 is a write only device */
168 __inline__ void audio_aic23_write(u8 address, u16 data)
169 {
170         tlv320aic23_write_value(address, data);
171 }
172
173 /*
174  * Sample rate changing
175  */
176 static void omap_aic23_set_samplerate(struct snd_card_omap_aic23
177                                       *omap_aic23, long rate)
178 {
179         u8 count = 0;
180         u16 data = 0;
181
182         /* Fix the rate if it has a wrong value */
183         if (rate >= 96000)
184                 rate = 96000;
185         else if (rate >= 88200)
186                 rate = 88200;
187         else if (rate >= 48000)
188                 rate = 48000;
189         else if (rate >= 44100)
190                 rate = 44100;
191         else if (rate >= 32000)
192                 rate = 32000;
193         else if (rate >= 24000)
194                 rate = 24000;
195         else if (rate >= 22050)
196                 rate = 22050;
197         else if (rate >= 16000)
198                 rate = 16000;
199         else if (rate >= 8000)
200                 rate = 8000;
201         else
202                 rate = 4000;
203
204         /* Search for the right sample rate */
205         /* Verify what happens if the rate is not supported
206          * now it goes to 96Khz */
207         while ((rates[count] != rate) &&
208                (count < (NUMBER_SAMPLE_RATES_SUPPORTED - 1))) {
209                 count++;
210         }
211
212         data = (rate_reg_info[count].divider << CLKIN_SHIFT) |
213             (rate_reg_info[count].control << BOSR_SHIFT) | USB_CLK_ON;
214
215         audio_aic23_write(SAMPLE_RATE_CONTROL_ADDR, data);
216
217         omap_aic23->samplerate = rate;
218 }
219
220 static inline void aic23_configure(void)
221 {
222         /* Reset codec */
223         audio_aic23_write(RESET_CONTROL_ADDR, 0);
224
225         /* Initialize the AIC23 internal state */
226
227         /* Analog audio path control, DAC selected, delete INSEL_MIC for line in */
228         audio_aic23_write(ANALOG_AUDIO_CONTROL_ADDR, DEFAULT_ANALOG_AUDIO_CONTROL);
229
230         /* Digital audio path control, de-emphasis control 44.1kHz */
231         audio_aic23_write(DIGITAL_AUDIO_CONTROL_ADDR, DEEMP_44K);
232
233         /* Digital audio interface, master/slave mode, I2S, 16 bit */
234 #ifdef AIC23_MASTER
235         audio_aic23_write(DIGITAL_AUDIO_FORMAT_ADDR,
236                           MS_MASTER | IWL_16 | FOR_DSP);
237 #else
238         audio_aic23_write(DIGITAL_AUDIO_FORMAT_ADDR, IWL_16 | FOR_DSP);
239 #endif
240
241         /* Enable digital interface */
242         audio_aic23_write(DIGITAL_INTERFACE_ACT_ADDR, ACT_ON);
243
244 }
245
246 static void omap_aic23_audio_init(struct snd_card_omap_aic23 *omap_aic23)
247 {
248         /* Setup DMA stuff */
249         omap_aic23->s[SNDRV_PCM_STREAM_PLAYBACK].id = "Alsa AIC23 out";
250         omap_aic23->s[SNDRV_PCM_STREAM_PLAYBACK].stream_id =
251             SNDRV_PCM_STREAM_PLAYBACK;
252         omap_aic23->s[SNDRV_PCM_STREAM_PLAYBACK].dma_dev =
253             OMAP_DMA_MCBSP1_TX;
254
255         omap_aic23->s[SNDRV_PCM_STREAM_CAPTURE].id = "Alsa AIC23 in";
256         omap_aic23->s[SNDRV_PCM_STREAM_CAPTURE].stream_id =
257             SNDRV_PCM_STREAM_CAPTURE;
258         omap_aic23->s[SNDRV_PCM_STREAM_CAPTURE].dma_dev =
259             OMAP_DMA_MCBSP1_RX;
260
261         /* configuring the McBSP */
262         omap_mcbsp_request(AUDIO_MCBSP);
263
264         /* if configured, then stop mcbsp */
265         omap_mcbsp_stop(AUDIO_MCBSP);
266
267         omap_mcbsp_config(AUDIO_MCBSP, &initial_config_mcbsp);
268         omap_mcbsp_start(AUDIO_MCBSP);
269         aic23_configure();
270 }
271
272 /* 
273  * DMA functions 
274  * Depends on omap-aic23-dma.c functions and (omap) dma.c
275  * 
276  */
277 #define DMA_BUF_SIZE    1024 * 8
278
279 static int audio_dma_request(struct audio_stream *s,
280                              void (*callback) (void *))
281 {
282         int err;
283
284         err = omap_request_sound_dma(s->dma_dev, s->id, s, &s->lch);
285         if (err < 0)
286                 printk(KERN_ERR "unable to grab audio dma 0x%x\n",
287                        s->dma_dev);
288         return err;
289 }
290
291 static int audio_dma_free(struct audio_stream *s)
292 {
293         int err = 0;
294
295         err = omap_free_sound_dma(s, &s->lch);
296         if (err < 0)
297                 printk(KERN_ERR "Unable to free audio dma channels!\n");
298         return err;
299 }
300
301 /*
302  *  This function should calculate the current position of the dma in the
303  *  buffer. It will help alsa middle layer to continue update the buffer.
304  *  Its correctness is crucial for good functioning.
305  */
306 static u_int audio_get_dma_pos(struct audio_stream *s)
307 {
308         snd_pcm_substream_t *substream = s->stream;
309         snd_pcm_runtime_t *runtime = substream->runtime;
310         unsigned int offset;
311         unsigned long flags;
312         dma_addr_t count;
313         ADEBUG();
314
315         /* this must be called w/ interrupts locked as requested in dma.c */
316         spin_lock_irqsave(&s->dma_lock, flags);
317
318         /* For the current period let's see where we are */
319         count = omap_get_dma_src_addr_counter(s->lch[s->dma_q_head]);
320
321         spin_unlock_irqrestore(&s->dma_lock, flags);
322
323         /* Now, the position related to the end of that period */
324         offset = bytes_to_frames(runtime, s->offset) - bytes_to_frames(runtime, count);
325
326         if (offset >= runtime->buffer_size || offset < 0)
327                 offset = 0;
328
329         return offset;
330 }
331
332 /*
333  * this stops the dma and clears the dma ptrs
334  */
335 static void audio_stop_dma(struct audio_stream *s)
336 {
337         unsigned long flags;
338         ADEBUG();
339
340         spin_lock_irqsave(&s->dma_lock, flags);
341         s->active = 0;
342         s->period = 0;
343         s->periods = 0;
344
345         /* this stops the dma channel and clears the buffer ptrs */
346         omap_audio_stop_dma(s);
347
348         omap_clear_sound_dma(s);
349
350         spin_unlock_irqrestore(&s->dma_lock, flags);
351 }
352
353 /*
354  *  Main dma routine, requests dma according where you are in main alsa buffer
355  */
356 static void audio_process_dma(struct audio_stream *s)
357 {
358         snd_pcm_substream_t *substream = s->stream;
359         snd_pcm_runtime_t *runtime;
360         unsigned int dma_size;
361         unsigned int offset;
362         int ret;
363
364         runtime = substream->runtime;
365         if (s->active) {
366                 dma_size = frames_to_bytes(runtime, runtime->period_size);
367                 offset = dma_size * s->period;
368                 snd_assert(dma_size <= DMA_BUF_SIZE,);
369                 ret =
370                     omap_start_sound_dma(s,
371                                          (dma_addr_t) runtime->dma_area +
372                                          offset, dma_size);
373                 if (ret) {
374                         printk(KERN_ERR
375                                "audio_process_dma: cannot queue DMA buffer (%i)\n",
376                                ret);
377                         return;
378                 }
379
380                 s->period++;
381                 s->period %= runtime->periods;
382                 s->periods++;
383                 s->offset = offset;
384         }
385 }
386
387 /* 
388  *  This is called when dma IRQ occurs at the end of each transmited block
389  */
390 void audio_dma_callback(void *data)
391 {
392         struct audio_stream *s = data;
393
394         /* 
395          * If we are getting a callback for an active stream then we inform
396          * the PCM middle layer we've finished a period
397          */
398         if (s->active)
399                 snd_pcm_period_elapsed(s->stream);
400
401         spin_lock(&s->dma_lock);
402         if (s->periods > 0) {
403                 s->periods--;
404         }
405         audio_process_dma(s);
406         spin_unlock(&s->dma_lock);
407 }
408
409
410 /* 
411  * Alsa section
412  * PCM settings and callbacks
413  */
414
415 static int snd_omap_aic23_trigger(snd_pcm_substream_t * substream, int cmd)
416 {
417         struct snd_card_omap_aic23 *chip =
418             snd_pcm_substream_chip(substream);
419         int stream_id = substream->pstr->stream;
420         struct audio_stream *s = &chip->s[stream_id];
421         int err = 0;
422         ADEBUG();
423
424         /* note local interrupts are already disabled in the midlevel code */
425         spin_lock(&s->dma_lock);
426         switch (cmd) {
427         case SNDRV_PCM_TRIGGER_START:
428                 /* requested stream startup */
429                 s->active = 1;
430                 audio_process_dma(s);
431                 break;
432         case SNDRV_PCM_TRIGGER_STOP:
433                 /* requested stream shutdown */
434                 audio_stop_dma(s);
435                 break;
436         default:
437                 err = -EINVAL;
438                 break;
439         }
440         spin_unlock(&s->dma_lock);
441         
442         return err;
443 }
444
445 static int snd_omap_aic23_prepare(snd_pcm_substream_t * substream)
446 {
447         struct snd_card_omap_aic23 *chip =
448             snd_pcm_substream_chip(substream);
449         snd_pcm_runtime_t *runtime = substream->runtime;
450         struct audio_stream *s = &chip->s[substream->pstr->stream];
451
452         /* set requested samplerate */
453         omap_aic23_set_samplerate(chip, runtime->rate);
454
455         s->period = 0;
456         s->periods = 0;
457
458         return 0;
459 }
460
461 static snd_pcm_uframes_t snd_omap_aic23_pointer(snd_pcm_substream_t *
462                                                 substream)
463 {
464         struct snd_card_omap_aic23 *chip =
465             snd_pcm_substream_chip(substream);
466         
467         return audio_get_dma_pos(&chip->s[substream->pstr->stream]);
468 }
469
470 /* Hardware capabilities */
471
472 static snd_pcm_hardware_t snd_omap_aic23_capture = {
473         .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
474                  SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),
475         .formats = (SNDRV_PCM_FMTBIT_S16_LE),
476         .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
477                   SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |
478                   SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
479                   SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
480                   SNDRV_PCM_RATE_KNOT),
481         .rate_min = 8000,
482         .rate_max = 96000,
483         .channels_min = 2,
484         .channels_max = 2,
485         .buffer_bytes_max = 128 * 1024,
486         .period_bytes_min = 32,
487         .period_bytes_max = 8 * 1024,
488         .periods_min = 16,
489         .periods_max = 255,
490         .fifo_size = 0,
491 };
492
493 static snd_pcm_hardware_t snd_omap_aic23_playback = {
494         .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
495                  SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),      
496         .formats = (SNDRV_PCM_FMTBIT_S16_LE),
497         .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
498                   SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |
499                   SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
500                   SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
501                   SNDRV_PCM_RATE_KNOT),
502         .rate_min = 8000,
503         .rate_max = 96000,
504         .channels_min = 2,
505         .channels_max = 2,
506         .buffer_bytes_max = 128 * 1024,
507         .period_bytes_min = 32,
508         .period_bytes_max = 8 * 1024,
509         .periods_min = 16,
510         .periods_max = 255,
511         .fifo_size = 0,
512 };
513
514 static int snd_card_omap_aic23_open(snd_pcm_substream_t * substream)
515 {
516         struct snd_card_omap_aic23 *chip =
517             snd_pcm_substream_chip(substream);
518         snd_pcm_runtime_t *runtime = substream->runtime;
519         int stream_id = substream->pstr->stream;
520         int err;
521         ADEBUG();
522
523         chip->s[stream_id].stream = substream;
524         
525         omap_aic23_clock_on();
526         
527         if (stream_id == SNDRV_PCM_STREAM_PLAYBACK)
528                 runtime->hw = snd_omap_aic23_playback;
529         else
530                 runtime->hw = snd_omap_aic23_capture;
531         if ((err =
532              snd_pcm_hw_constraint_integer(runtime,
533                                            SNDRV_PCM_HW_PARAM_PERIODS)) <
534             0)
535                 return err;
536         if ((err =
537              snd_pcm_hw_constraint_list(runtime, 0,
538                                         SNDRV_PCM_HW_PARAM_RATE,
539                                         &hw_constraints_rates)) < 0)
540                 return err;
541
542         return 0;
543 }
544
545 static int snd_card_omap_aic23_close(snd_pcm_substream_t * substream)
546 {
547         struct snd_card_omap_aic23 *chip =
548             snd_pcm_substream_chip(substream);
549         ADEBUG();
550         
551         omap_aic23_clock_off();
552         chip->s[substream->pstr->stream].stream = NULL;
553         
554         return 0;
555 }
556
557 /* HW params & free */
558
559 static int snd_omap_aic23_hw_params(snd_pcm_substream_t * substream,
560                                     snd_pcm_hw_params_t * hw_params)
561 {
562         return snd_pcm_lib_malloc_pages(substream,
563                                         params_buffer_bytes(hw_params));
564 }
565
566 static int snd_omap_aic23_hw_free(snd_pcm_substream_t * substream)
567 {
568         return snd_pcm_lib_free_pages(substream);
569 }
570
571 /* pcm operations */
572
573 static snd_pcm_ops_t snd_card_omap_aic23_playback_ops = {
574         .open =         snd_card_omap_aic23_open,
575         .close =        snd_card_omap_aic23_close,
576         .ioctl =        snd_pcm_lib_ioctl,
577         .hw_params =    snd_omap_aic23_hw_params,
578         .hw_free =      snd_omap_aic23_hw_free,
579         .prepare =      snd_omap_aic23_prepare,
580         .trigger =      snd_omap_aic23_trigger,
581         .pointer =      snd_omap_aic23_pointer,
582 };
583
584 static snd_pcm_ops_t snd_card_omap_aic23_capture_ops = {
585         .open =         snd_card_omap_aic23_open,
586         .close =        snd_card_omap_aic23_close,
587         .ioctl =        snd_pcm_lib_ioctl,
588         .hw_params =    snd_omap_aic23_hw_params,
589         .hw_free =      snd_omap_aic23_hw_free,
590         .prepare =      snd_omap_aic23_prepare,
591         .trigger =      snd_omap_aic23_trigger,
592         .pointer =      snd_omap_aic23_pointer,
593 };
594
595 /*
596  *  Alsa init and exit section
597  *  
598  *  Inits pcm alsa structures, allocate the alsa buffer, suspend, resume
599  */
600 static int __init snd_card_omap_aic23_pcm(struct snd_card_omap_aic23
601                                           *omap_aic23, int device)
602 {
603         snd_pcm_t *pcm;
604         int err;
605         ADEBUG();
606
607         if ((err =
608              snd_pcm_new(omap_aic23->card, "AIC23 PCM", device, 1, 1,
609                          &pcm)) < 0)
610                 return err;
611
612         /* sets up initial buffer with continuous allocation */
613         snd_pcm_lib_preallocate_pages_for_all(pcm,
614                                               SNDRV_DMA_TYPE_CONTINUOUS,
615                                               snd_dma_continuous_data
616                                               (GFP_KERNEL),
617                                               128 * 1024, 128 * 1024);
618
619         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
620                         &snd_card_omap_aic23_playback_ops);
621         snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
622                         &snd_card_omap_aic23_capture_ops);
623         pcm->private_data = omap_aic23;
624         pcm->info_flags = 0;
625         strcpy(pcm->name, "omap aic23 pcm");
626
627         omap_aic23_audio_init(omap_aic23);
628
629         /* setup DMA controller */
630         audio_dma_request(&omap_aic23->s[SNDRV_PCM_STREAM_PLAYBACK],
631                           audio_dma_callback);
632         audio_dma_request(&omap_aic23->s[SNDRV_PCM_STREAM_CAPTURE],
633                           audio_dma_callback);
634
635         omap_aic23->pcm = pcm;
636
637         return 0;
638 }
639
640
641 #ifdef CONFIG_PM
642
643 static int snd_omap_aic23_suspend(snd_card_t * card, pm_message_t state)
644 {
645         struct snd_card_omap_aic23 *chip = card->pm_private_data;
646         ADEBUG();
647
648         if (chip->card->power_state != SNDRV_CTL_POWER_D3hot) {
649                 snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot);
650                 snd_pcm_suspend_all(chip->pcm);
651                 /* Mutes and turn clock off */
652                 omap_aic23_clock_off();
653                 snd_omap_suspend_mixer();
654         }
655
656         return 0;
657 }
658
659 /*
660  *  Prepare hardware for resume
661  */
662 static int snd_omap_aic23_resume(snd_card_t * card)
663 {
664         struct snd_card_omap_aic23 *chip = card->pm_private_data;
665         ADEBUG();
666         
667         if (chip->card->power_state != SNDRV_CTL_POWER_D0) {
668                 snd_power_change_state(chip->card, SNDRV_CTL_POWER_D0);
669                 omap_aic23_clock_on();
670                 snd_omap_resume_mixer();
671         }
672
673         return 0;
674 }
675
676 /*
677  * Driver suspend/resume - calls alsa functions. Some hints from aaci.c
678  */
679 static int omap_aic23_suspend(struct device *dev, pm_message_t state, u32 level)
680 {
681         snd_card_t *card = dev_get_drvdata(dev);
682         
683         if (card->power_state != SNDRV_CTL_POWER_D3hot) {
684                 snd_omap_aic23_suspend(card, 0);
685         }
686         return 0;
687 }
688
689 static int omap_aic23_resume(struct device *dev, u32 level)
690 {
691         snd_card_t *card = dev_get_drvdata(dev);
692
693         if (card->power_state != SNDRV_CTL_POWER_D0) {
694                 snd_omap_aic23_resume(card);
695         }
696         return 0;
697 }
698
699 #else
700 #define snd_omap_aic23_suspend  NULL
701 #define snd_omap_aic23_resume   NULL
702 #define omap_aic23_suspend      NULL
703 #define omap_aic23_resume       NULL
704
705 #endif  /* CONFIG_PM */
706
707 /* 
708  */
709 void snd_omap_aic23_free(snd_card_t * card)
710 {
711         struct snd_card_omap_aic23 *chip = card->private_data;
712         ADEBUG();
713         
714         /*
715          * Turn off codec after it is done.
716          * Can't do it immediately, since it may still have
717          * buffered data.
718          */
719         set_current_state(TASK_INTERRUPTIBLE);
720         schedule_timeout(2);
721
722         omap_mcbsp_stop(AUDIO_MCBSP);
723         omap_mcbsp_free(AUDIO_MCBSP);
724
725         audio_aic23_write(RESET_CONTROL_ADDR, 0);
726         audio_aic23_write(POWER_DOWN_CONTROL_ADDR, 0xff);
727
728         audio_dma_free(&chip->s[SNDRV_PCM_STREAM_PLAYBACK]);
729         audio_dma_free(&chip->s[SNDRV_PCM_STREAM_CAPTURE]);
730 }
731
732 /*
733  *  Omap MCBSP clock configuration
734  *  
735  *  Here we have some functions that allows clock to be enabled and
736  *   disabled only when needed. Besides doing clock configuration 
737  *   it allows turn on/turn off audio when necessary. 
738  */
739 #define CODEC_CLOCK                   12000000
740 #define AUDIO_RATE_DEFAULT            44100
741
742 /*
743  * Do clock framework mclk search
744  */
745 static __init void omap_aic23_clock_setup(void)
746 {
747         aic23_mclk = clk_get(0, "mclk");
748 }
749
750 /*
751  * Do some sanity check, set clock rate, starts it and
752  *  turn codec audio on 
753  */
754 int omap_aic23_clock_on(void)
755 {
756         if (clk_get_usecount(aic23_mclk) > 0) {
757                 /* MCLK is already in use */
758                 printk(KERN_WARNING
759                        "MCLK in use at %d Hz. We change it to %d Hz\n",
760                        (uint) clk_get_rate(aic23_mclk),
761                        CODEC_CLOCK);
762         }
763         
764         if (clk_set_rate(aic23_mclk, CODEC_CLOCK)) {
765                 printk(KERN_ERR
766                        "Cannot set MCLK for AIC23 CODEC\n");
767                 return -ECANCELED;
768         }
769
770         clk_use(aic23_mclk);
771
772         printk(KERN_DEBUG
773                 "MCLK = %d [%d], usecount = %d\n",
774                (uint) clk_get_rate(aic23_mclk), CODEC_CLOCK,
775                clk_get_usecount(aic23_mclk));
776
777         /* Now turn the audio on */
778         audio_aic23_write(POWER_DOWN_CONTROL_ADDR, 
779                           ~DEVICE_POWER_OFF & ~OUT_OFF & ~DAC_OFF &
780                           ~ADC_OFF & ~MIC_OFF & ~LINE_OFF);
781         
782         return 0;
783 }
784 /*
785  * Do some sanity check, turn clock off and then turn
786  *  codec audio off
787  */
788 int omap_aic23_clock_off(void)
789 {
790         if  (clk_get_usecount(aic23_mclk) > 0) { 
791                 if (clk_get_rate(aic23_mclk) != CODEC_CLOCK) {
792                         printk(KERN_WARNING
793                                "MCLK for audio should be %d Hz. But is %d Hz\n",
794                                (uint) clk_get_rate(aic23_mclk),
795                                CODEC_CLOCK);
796                 }
797
798                 clk_unuse(aic23_mclk);
799         }
800         
801         audio_aic23_write(POWER_DOWN_CONTROL_ADDR,
802                           DEVICE_POWER_OFF | OUT_OFF | DAC_OFF |
803                           ADC_OFF | MIC_OFF | LINE_OFF);        
804         return 0;
805 }
806
807 /* module init & exit */
808
809 /* 
810  *  Inits alsa soudcard structure
811  */
812 static int __init snd_omap_aic23_probe(struct device *dev)
813 {
814         int err = 0;
815         snd_card_t *card;
816         ADEBUG();
817         
818         /* gets clock from clock framework */
819         omap_aic23_clock_setup();
820
821         /* register the soundcard */
822         card = snd_card_new(-1, id, THIS_MODULE, sizeof(omap_aic23));
823         if (card == NULL)
824                 return -ENOMEM;
825
826         omap_aic23 = kcalloc(1, sizeof(*omap_aic23), GFP_KERNEL);
827         if (omap_aic23 == NULL)
828                 return -ENOMEM;
829
830         card->private_data = (void *) omap_aic23;
831         card->private_free = snd_omap_aic23_free;
832
833         omap_aic23->card = card;
834         omap_aic23->samplerate = AUDIO_RATE_DEFAULT;
835
836         spin_lock_init(&omap_aic23->s[0].dma_lock);
837         spin_lock_init(&omap_aic23->s[1].dma_lock);
838
839         /* mixer */
840         if ((err = snd_omap_mixer(omap_aic23)) < 0) 
841                 goto nodev;
842
843         /* PCM */
844         if ((err = snd_card_omap_aic23_pcm(omap_aic23, 0)) < 0)
845                 goto nodev;
846
847         snd_card_set_pm_callback(card, snd_omap_aic23_suspend,
848                                  snd_omap_aic23_resume, omap_aic23);
849
850         strcpy(card->driver, "AIC23");
851         strcpy(card->shortname, "OSK AIC23");
852         sprintf(card->longname, "OMAP OSK with AIC23");
853
854         snd_omap_init_mixer();
855         
856         if ((err = snd_card_register(card)) == 0) {
857                 printk(KERN_INFO "OSK audio support initialized\n");
858                 dev_set_drvdata(dev, card); 
859                 return 0;
860         }
861         
862 nodev:
863         snd_omap_aic23_free(card);
864         
865         return err;
866 }
867
868 static int snd_omap_aic23_remove(struct device *dev)
869 {
870         snd_card_t *card = dev_get_drvdata(dev);
871         struct snd_card_omap_aic23 *chip = card->private_data;
872         
873         snd_card_free(card);
874
875         omap_aic23 = NULL;
876         card->private_data = NULL;
877         kfree(chip);
878         
879         dev_set_drvdata(dev, NULL); 
880         
881         return 0;
882         
883 }
884
885 static struct device_driver omap_alsa_driver = {
886         .name =         "omap_mcbsp",
887         .bus =          &platform_bus_type,
888         .probe =        snd_omap_aic23_probe,
889         .remove =       snd_omap_aic23_remove,
890         .suspend =      omap_aic23_suspend, 
891         .resume =       omap_aic23_resume, 
892 };
893
894 static int __init omap_aic23_init(void)
895 {
896         int err;
897         ADEBUG();
898
899         err = driver_register(&omap_alsa_driver);
900
901         return err;
902 }
903
904 static void __exit omap_aic23_exit(void)
905 {
906         ADEBUG();
907         
908         driver_unregister(&omap_alsa_driver);
909 }
910
911 module_init(omap_aic23_init);
912 module_exit(omap_aic23_exit);