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