2 * linux/sound/oss/omap-audio-aic23.c
4 * Glue audio driver for TI TLV320AIC23 codec
6 * Copyright (c) 2000 Nicolas Pitre <nico@cam.org>
7 * Copyright (C) 2001, Steve Johnson <stevej@ridgerun.com>
8 * Copyright (C) 2004 Texas Instruments, Inc.
9 * Copyright (C) 2005 Dirk Behme <dirk.behme@de.bosch.com>
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
19 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
22 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 * You should have received a copy of the GNU General Public License along
28 * with this program; if not, write to the Free Software Foundation, Inc.,
29 * 675 Mass Ave, Cambridge, MA 02139, USA.
32 #include <linux/module.h>
33 #include <linux/init.h>
34 #include <linux/types.h>
35 #include <linux/delay.h>
37 #include <linux/errno.h>
38 #include <linux/sound.h>
39 #include <linux/soundcard.h>
40 #include <linux/clk.h>
41 #include <linux/mutex.h>
43 #include <asm/uaccess.h>
44 #include <asm/hardware.h>
46 #include <asm/mach-types.h>
48 #include <asm/arch/mcbsp.h>
49 #include <asm/arch/fpga.h>
50 #include <asm/arch/aic23.h>
51 #include <asm/arch/clock.h>
53 #include "omap-audio.h"
54 #include "omap-audio-dma-intfc.h"
57 #include <linux/proc_fs.h>
58 #define PROC_START_FILE "driver/aic23-audio-start"
59 #define PROC_STOP_FILE "driver/aic23-audio-stop"
65 #define DPRINTK(ARGS...) printk("<%s>: ",__FUNCTION__);printk(ARGS)
67 #define DPRINTK( x... )
70 #define CODEC_NAME "AIC23"
72 #if CONFIG_MACH_OMAP_OSK
73 #define PLATFORM_NAME "OMAP OSK"
74 #elif CONFIG_MACH_OMAP_INNOVATOR
75 #define PLATFORM_NAME "OMAP INNOVATOR"
77 #error "Unsupported plattform"
80 /* Define to set the AIC23 as the master w.r.t McBSP */
83 #define CODEC_CLOCK 12000000
86 * AUDIO related MACROS
88 #define DEFAULT_BITPERSAMPLE 16
89 #define AUDIO_RATE_DEFAULT 44100
91 /* Select the McBSP For Audio */
92 #define AUDIO_MCBSP OMAP_MCBSP1
94 #define REC_MASK (SOUND_MASK_LINE | SOUND_MASK_MIC)
95 #define DEV_MASK (REC_MASK | SOUND_MASK_VOLUME)
100 #define DEFAULT_OUTPUT_VOLUME 93
101 #define DEFAULT_INPUT_VOLUME 0 /* 0 ==> mute line in */
103 #define OUTPUT_VOLUME_MIN LHV_MIN
104 #define OUTPUT_VOLUME_MAX LHV_MAX
105 #define OUTPUT_VOLUME_RANGE (OUTPUT_VOLUME_MAX - OUTPUT_VOLUME_MIN)
106 #define OUTPUT_VOLUME_MASK OUTPUT_VOLUME_MAX
108 #define INPUT_VOLUME_MIN LIV_MIN
109 #define INPUT_VOLUME_MAX LIV_MAX
110 #define INPUT_VOLUME_RANGE (INPUT_VOLUME_MAX - INPUT_VOLUME_MIN)
111 #define INPUT_VOLUME_MASK INPUT_VOLUME_MAX
113 #define NUMBER_SAMPLE_RATES_SUPPORTED 9
116 * HW interface start and stop helper functions
118 static int audio_ifc_start(void)
120 omap_mcbsp_start(AUDIO_MCBSP);
124 static int audio_ifc_stop(void)
126 omap_mcbsp_stop(AUDIO_MCBSP);
130 static audio_stream_t output_stream = {
132 .dma_dev = OMAP_DMA_MCBSP1_TX,
133 .input_or_output = FMODE_WRITE,
134 .hw_start = audio_ifc_start,
135 .hw_stop = audio_ifc_stop
138 static audio_stream_t input_stream = {
140 .dma_dev = OMAP_DMA_MCBSP1_RX,
141 .input_or_output = FMODE_READ,
142 .hw_start = audio_ifc_start,
143 .hw_stop = audio_ifc_stop
146 static struct clk *aic23_mclk = 0;
148 static int audio_dev_id, mixer_dev_id;
150 static struct aic23_local_info {
155 u16 input_volume_reg;
159 struct sample_rate_reg_info {
161 u8 control; /* SR3, SR2, SR1, SR0 and BOSR */
162 u8 divider; /* if 0 CLKIN = MCLK, if 1 CLKIN = MCLK/2 */
165 /* To Store the default sample rate */
166 static long audio_samplerate = AUDIO_RATE_DEFAULT;
168 /* DAC USB-mode sampling rates (MCLK = 12 MHz) */
169 static const struct sample_rate_reg_info
170 reg_info[NUMBER_SAMPLE_RATES_SUPPORTED] = {
182 static struct omap_mcbsp_reg_cfg initial_config = {
183 .spcr2 = FREE | FRST | GRST | XRST | XINTM(3),
184 .spcr1 = RINTM(3) | RRST,
185 .rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) |
186 RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(0),
187 .rcr1 = RFRLEN1(OMAP_MCBSP_WORD_8) | RWDLEN1(OMAP_MCBSP_WORD_16),
188 .xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) |
189 XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(0) | XFIG,
190 .xcr1 = XFRLEN1(OMAP_MCBSP_WORD_8) | XWDLEN1(OMAP_MCBSP_WORD_16),
191 .srgr1 = FWID(DEFAULT_BITPERSAMPLE - 1),
192 .srgr2 = GSYNC | CLKSP | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1),
194 /* configure McBSP to be the I2S master */
195 .pcr0 = FSXM | FSRM | CLKXM | CLKRM | CLKXP | CLKRP,
197 /* configure McBSP to be the I2S slave */
198 .pcr0 = CLKXP | CLKRP,
199 #endif /* AIC23_MASTER */
202 static void omap_aic23_initialize(void *dummy);
203 static void omap_aic23_shutdown(void *dummy);
204 static int omap_aic23_ioctl(struct inode *inode, struct file *file,
205 uint cmd, ulong arg);
206 static int omap_aic23_probe(void);
208 static void omap_aic23_remove(void);
210 static int omap_aic23_suspend(void);
211 static int omap_aic23_resume(void);
212 static inline void aic23_configure(void);
213 static int mixer_open(struct inode *inode, struct file *file);
214 static int mixer_release(struct inode *inode, struct file *file);
215 static int mixer_ioctl(struct inode *inode, struct file *file, uint cmd,
218 #ifdef CONFIG_PROC_FS
219 static int codec_start(char *buf, char **start, off_t offset, int count,
220 int *eof, void *data);
221 static int codec_stop(char *buf, char **start, off_t offset, int count,
222 int *eof, void *data);
226 /* File Op structure for mixer */
227 static struct file_operations omap_mixer_fops = {
229 .release = mixer_release,
230 .ioctl = mixer_ioctl,
234 /* To store characteristic info regarding the codec for the audio driver */
235 static audio_state_t aic23_state = {
236 .output_stream = &output_stream,
237 .input_stream = &input_stream,
238 /* .need_tx_for_rx = 1, //Once the Full Duplex works */
240 .hw_init = omap_aic23_initialize,
241 .hw_shutdown = omap_aic23_shutdown,
242 .client_ioctl = omap_aic23_ioctl,
243 .hw_probe = omap_aic23_probe,
244 .hw_remove = __exit_p(omap_aic23_remove),
245 .hw_suspend = omap_aic23_suspend,
246 .hw_resume = omap_aic23_resume,
249 /* This will be defined in the audio.h */
250 static struct file_operations *omap_audio_fops;
252 extern int aic23_write_value(u8 reg, u16 value);
254 /* TLV320AIC23 is a write only device */
255 static __inline__ void audio_aic23_write(u8 address, u16 data)
257 aic23_write_value(address, data);
260 static int aic23_update(int flag, int val)
264 /* Ignore separate left/right channel for now,
265 even the codec does support it. */
268 if (val < 0 || val > 100) {
269 printk(KERN_ERR "Trying a bad volume value(%d)!\n",val);
275 // Convert 0 -> 100 volume to 0x00 (LHV_MIN) -> 0x7f (LHV_MAX)
277 volume = ((val * OUTPUT_VOLUME_RANGE) / 100) + OUTPUT_VOLUME_MIN;
279 // R/LHV[6:0] 1111111 (+6dB) to 0000000 (-73dB) in 1db steps,
280 // default 1111001 (0dB)
281 aic23_local.volume_reg &= ~OUTPUT_VOLUME_MASK;
282 aic23_local.volume_reg |= volume;
283 audio_aic23_write(LEFT_CHANNEL_VOLUME_ADDR, aic23_local.volume_reg);
284 audio_aic23_write(RIGHT_CHANNEL_VOLUME_ADDR, aic23_local.volume_reg);
288 // Convert 0 -> 100 volume to 0x0 (LIV_MIN) -> 0x1f (LIV_MAX)
290 volume = ((val * INPUT_VOLUME_RANGE) / 100) + INPUT_VOLUME_MIN;
292 // R/LIV[4:0] 11111 (+12dB) to 00000 (-34.5dB) in 1.5dB steps,
293 // default 10111 (0dB)
294 aic23_local.input_volume_reg &= ~INPUT_VOLUME_MASK;
295 aic23_local.input_volume_reg |= volume;
296 audio_aic23_write(LEFT_LINE_VOLUME_ADDR, aic23_local.input_volume_reg);
297 audio_aic23_write(RIGHT_LINE_VOLUME_ADDR, aic23_local.input_volume_reg);
303 static int mixer_open(struct inode *inode, struct file *file)
305 /* Any mixer specific initialization */
310 static int mixer_release(struct inode *inode, struct file *file)
312 /* Any mixer specific Un-initialization */
318 mixer_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
322 int nr = _IOC_NR(cmd);
325 * We only accept mixer (type 'M') ioctls.
327 if (_IOC_TYPE(cmd) != 'M')
330 DPRINTK(" 0x%08x\n", cmd);
332 if (cmd == SOUND_MIXER_INFO) {
333 struct mixer_info mi;
335 strncpy(mi.id, "AIC23", sizeof(mi.id));
336 strncpy(mi.name, "TI AIC23", sizeof(mi.name));
337 mi.modify_counter = aic23_local.mod_cnt;
338 return copy_to_user((void *)arg, &mi, sizeof(mi));
341 if (_IOC_DIR(cmd) & _IOC_WRITE) {
342 ret = get_user(val, (int *)arg);
348 case SOUND_MIXER_VOLUME:
349 aic23_local.volume = val;
350 aic23_local.mod_cnt++;
351 ret = aic23_update(SET_VOLUME, val);
354 case SOUND_MIXER_LINE:
355 aic23_local.line = val;
356 aic23_local.mod_cnt++;
357 ret = aic23_update(SET_LINE, val);
360 case SOUND_MIXER_MIC:
361 aic23_local.mic = val;
362 aic23_local.mod_cnt++;
363 ret = aic23_update(SET_LINE, val);
366 case SOUND_MIXER_RECSRC:
374 if (ret == 0 && _IOC_DIR(cmd) & _IOC_READ) {
378 case SOUND_MIXER_VOLUME:
379 val = aic23_local.volume;
381 case SOUND_MIXER_LINE:
382 val = aic23_local.line;
384 case SOUND_MIXER_MIC:
385 val = aic23_local.mic;
387 case SOUND_MIXER_RECSRC:
390 case SOUND_MIXER_RECMASK:
393 case SOUND_MIXER_DEVMASK:
396 case SOUND_MIXER_CAPS:
399 case SOUND_MIXER_STEREODEVS:
409 ret = put_user(val, (int *)arg);
416 int omap_set_samplerate(long sample_rate)
420 /* wait for any frame to complete */
423 /* Search for the right sample rate */
424 while ((reg_info[count].sample_rate != sample_rate) &&
425 (count < NUMBER_SAMPLE_RATES_SUPPORTED)) {
428 if (count == NUMBER_SAMPLE_RATES_SUPPORTED) {
429 printk(KERN_ERR "Invalid Sample Rate %d requested\n",
434 if (machine_is_omap_innovator()) {
435 /* set the CODEC clock input source to 12.000MHz */
436 fpga_write(fpga_read(OMAP1510_FPGA_POWER) & ~0x01,
437 OMAP1510_FPGA_POWER);
440 data = (reg_info[count].divider << CLKIN_SHIFT) |
441 (reg_info[count].control << BOSR_SHIFT) | USB_CLK_ON;
443 audio_aic23_write(SAMPLE_RATE_CONTROL_ADDR, data);
445 audio_samplerate = sample_rate;
451 Set Sample Rate at McBSP
454 Codec System Clock = CODEC_CLOCK, or half if clock_divider = 1;
455 clkgdv = ((Codec System Clock / (SampleRate * BitsPerSample * 2)) - 1);
457 FWID = BitsPerSample - 1;
458 FPER = (BitsPerSample * 2) - 1;
460 if (reg_info[count].divider)
461 clkgdv = CODEC_CLOCK / 2;
463 clkgdv = CODEC_CLOCK;
465 clkgdv = (clkgdv / (sample_rate * DEFAULT_BITPERSAMPLE * 2)) - 1;
467 initial_config.srgr1 = (FWID(DEFAULT_BITPERSAMPLE - 1) | CLKGDV(clkgdv));
469 initial_config.srgr2 =
470 (CLKSM | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1));
472 omap_mcbsp_config(AUDIO_MCBSP, &initial_config);
474 #endif /* AIC23_MASTER */
479 static void omap_aic23_initialize(void *dummy)
483 /* initialize with default sample rate */
484 audio_samplerate = AUDIO_RATE_DEFAULT;
486 omap_mcbsp_request(AUDIO_MCBSP);
488 /* if configured, then stop mcbsp */
489 omap_mcbsp_stop(AUDIO_MCBSP);
491 omap_mcbsp_config(AUDIO_MCBSP, &initial_config);
492 omap_mcbsp_start(AUDIO_MCBSP);
498 static void omap_aic23_shutdown(void *dummy)
501 Turn off codec after it is done.
502 Can't do it immediately, since it may still have
505 Wait 20ms (arbitrary value) and then turn it off.
508 set_current_state(TASK_INTERRUPTIBLE);
511 omap_mcbsp_stop(AUDIO_MCBSP);
512 omap_mcbsp_free(AUDIO_MCBSP);
514 audio_aic23_write(RESET_CONTROL_ADDR, 0);
515 audio_aic23_write(POWER_DOWN_CONTROL_ADDR, 0xff);
518 static inline void aic23_configure()
521 audio_aic23_write(RESET_CONTROL_ADDR, 0);
523 /* Initialize the AIC23 internal state */
525 /* Left/Right line input volume control */
526 aic23_local.line = DEFAULT_INPUT_VOLUME;
527 aic23_local.mic = DEFAULT_INPUT_VOLUME;
528 aic23_update(SET_LINE, DEFAULT_INPUT_VOLUME);
530 /* Left/Right headphone channel volume control */
531 /* Zero-cross detect on */
532 aic23_local.volume_reg = LZC_ON;
533 aic23_update(SET_VOLUME, aic23_local.volume);
535 /* Analog audio path control, DAC selected, delete INSEL_MIC for line in */
536 audio_aic23_write(ANALOG_AUDIO_CONTROL_ADDR, DAC_SELECTED | INSEL_MIC);
538 /* Digital audio path control, de-emphasis control 44.1kHz */
539 audio_aic23_write(DIGITAL_AUDIO_CONTROL_ADDR, DEEMP_44K);
541 /* Power control, everything is on */
542 audio_aic23_write(POWER_DOWN_CONTROL_ADDR, 0);
544 /* Digital audio interface, master/slave mode, I2S, 16 bit */
546 audio_aic23_write(DIGITAL_AUDIO_FORMAT_ADDR, MS_MASTER | IWL_16 | FOR_DSP);
548 audio_aic23_write(DIGITAL_AUDIO_FORMAT_ADDR, IWL_16 | FOR_DSP);
549 #endif /* AIC23_MASTER */
551 /* Enable digital interface */
552 audio_aic23_write(DIGITAL_INTERFACE_ACT_ADDR, ACT_ON);
554 /* clock configuration */
555 omap_set_samplerate(audio_samplerate);
559 omap_aic23_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
564 DPRINTK(" 0x%08x\n", cmd);
567 * These are platform dependent ioctls which are not handled by the
568 * generic omap-audio module.
571 case SNDCTL_DSP_STEREO:
572 ret = get_user(val, (int *)arg);
575 /* the AIC23 is stereo only */
576 ret = (val == 0) ? -EINVAL : 1;
577 return put_user(ret, (int *)arg);
579 case SNDCTL_DSP_CHANNELS:
580 case SOUND_PCM_READ_CHANNELS:
581 /* the AIC23 is stereo only */
582 return put_user(2, (long *)arg);
584 case SNDCTL_DSP_SPEED:
585 ret = get_user(val, (long *)arg);
588 ret = omap_set_samplerate(val);
593 case SOUND_PCM_READ_RATE:
594 return put_user(audio_samplerate, (long *)arg);
596 case SOUND_PCM_READ_BITS:
597 case SNDCTL_DSP_SETFMT:
598 case SNDCTL_DSP_GETFMTS:
599 /* we can do 16-bit only */
600 return put_user(AFMT_S16_LE, (long *)arg);
603 /* Maybe this is meant for the mixer (As per OSS Docs) */
604 return mixer_ioctl(inode, file, cmd, arg);
610 static int omap_aic23_probe(void)
612 /* Get the fops from audio oss driver */
613 if (!(omap_audio_fops = audio_get_fops())) {
614 printk(KERN_ERR "Unable to get the file operations for AIC23 OSS driver\n");
615 audio_unregister_codec(&aic23_state);
619 aic23_local.volume = DEFAULT_OUTPUT_VOLUME;
621 /* register devices */
622 audio_dev_id = register_sound_dsp(omap_audio_fops, -1);
623 mixer_dev_id = register_sound_mixer(&omap_mixer_fops, -1);
625 #ifdef CONFIG_PROC_FS
626 create_proc_read_entry(PROC_START_FILE, 0 /* default mode */ ,
627 NULL /* parent dir */ ,
628 codec_start, NULL /* client data */ );
630 create_proc_read_entry(PROC_STOP_FILE, 0 /* default mode */ ,
631 NULL /* parent dir */ ,
632 codec_stop, NULL /* client data */ );
635 /* Announcement Time */
636 printk(KERN_INFO PLATFORM_NAME " " CODEC_NAME
637 " audio support initialized\n");
642 static void __exit omap_aic23_remove(void)
644 /* Un-Register the codec with the audio driver */
645 unregister_sound_dsp(audio_dev_id);
646 unregister_sound_mixer(mixer_dev_id);
648 #ifdef CONFIG_PROC_FS
649 remove_proc_entry(PROC_START_FILE, NULL);
650 remove_proc_entry(PROC_STOP_FILE, NULL);
655 static int omap_aic23_suspend(void)
657 /* Empty for the moment */
661 static int omap_aic23_resume(void)
663 /* Empty for the moment */
667 static int __init audio_aic23_init(void)
672 if (machine_is_omap_h2() || machine_is_omap_h3())
675 mutex_init(&aic23_state.mutex);
677 if (machine_is_omap_osk()) {
678 /* Set MCLK to be clock input for AIC23 */
679 aic23_mclk = clk_get(0, "mclk");
681 if(clk_get_rate( aic23_mclk) != CODEC_CLOCK){
682 /* MCLK ist not at CODEC_CLOCK */
683 if( clk_get_usecount(aic23_mclk) > 0 ){
684 /* MCLK is already in use */
685 printk(KERN_WARNING "MCLK in use at %d Hz. We change it to %d Hz\n",
686 (uint)clk_get_rate( aic23_mclk), CODEC_CLOCK);
688 if( clk_set_rate( aic23_mclk, CODEC_CLOCK ) ){
689 printk(KERN_ERR "Cannot set MCLK for AIC23 CODEC\n");
694 clk_enable( aic23_mclk );
696 DPRINTK("MCLK = %d [%d], usecount = %d\n",(uint)clk_get_rate( aic23_mclk ),
697 CODEC_CLOCK, clk_get_usecount( aic23_mclk));
700 if (machine_is_omap_innovator()) {
703 Turn on chip select for CODEC (shared with touchscreen).
704 Don't turn it back off, in case touch screen needs it.
706 fpga = fpga_read(OMAP1510_FPGA_TOUCHSCREEN);
708 fpga_write(fpga, OMAP1510_FPGA_TOUCHSCREEN);
711 /* register the codec with the audio driver */
712 if ((err = audio_register_codec(&aic23_state))) {
714 "Failed to register AIC23 driver with Audio OSS Driver\n");
720 static void __exit audio_aic23_exit(void)
722 (void)audio_unregister_codec(&aic23_state);
726 #ifdef CONFIG_PROC_FS
727 static int codec_start(char *buf, char **start, off_t offset, int count,
728 int *eof, void *data)
732 omap_aic23_initialize(foo);
734 printk("AIC23 codec initialization done.\n");
737 static int codec_stop(char *buf, char **start, off_t offset, int count,
738 int *eof, void *data)
742 omap_aic23_shutdown(foo);
744 printk("AIC23 codec shutdown.\n");
747 #endif /* CONFIG_PROC_FS */
749 module_init(audio_aic23_init);
750 module_exit(audio_aic23_exit);
752 MODULE_AUTHOR("Dirk Behme <dirk.behme@de.bosch.com>");
753 MODULE_DESCRIPTION("Glue audio driver for the TI AIC23 codec.");
754 MODULE_LICENSE("GPL");