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>
41 #include <asm/uaccess.h>
42 #include <asm/hardware.h>
44 #include <asm/mach-types.h>
46 #include <asm/arch/mcbsp.h>
47 #include <asm/arch/fpga.h>
48 #include <asm/arch/aic23.h>
50 #include <asm/hardware/clock.h>
52 #include "omap-audio.h"
53 #include "omap-audio-dma-intfc.h"
56 #include <linux/proc_fs.h>
57 #define PROC_START_FILE "driver/aic23-audio-start"
58 #define PROC_STOP_FILE "driver/aic23-audio-stop"
64 #define DPRINTK(ARGS...) printk("<%s>: ",__FUNCTION__);printk(ARGS)
66 #define DPRINTK( x... )
69 #define CODEC_NAME "AIC23"
71 #if CONFIG_MACH_OMAP_OSK
72 #define PLATFORM_NAME "OMAP OSK"
73 #elif CONFIG_MACH_OMAP_INNOVATOR
74 #define PLATFORM_NAME "OMAP INNOVATOR"
76 #error "Unsupported plattform"
79 /* Define to set the AIC23 as the master w.r.t McBSP */
82 #define CODEC_CLOCK 12000000
85 * AUDIO related MACROS
87 #define DEFAULT_BITPERSAMPLE 16
88 #define AUDIO_RATE_DEFAULT 44100
90 /* Select the McBSP For Audio */
91 #define AUDIO_MCBSP OMAP_MCBSP1
93 #define REC_MASK (SOUND_MASK_LINE | SOUND_MASK_MIC)
94 #define DEV_MASK (REC_MASK | SOUND_MASK_VOLUME)
99 #define DEFAULT_OUTPUT_VOLUME 93
100 #define DEFAULT_INPUT_VOLUME 0 /* 0 ==> mute line in */
102 #define OUTPUT_VOLUME_MIN LHV_MIN
103 #define OUTPUT_VOLUME_MAX LHV_MAX
104 #define OUTPUT_VOLUME_RANGE (OUTPUT_VOLUME_MAX - OUTPUT_VOLUME_MIN)
105 #define OUTPUT_VOLUME_MASK OUTPUT_VOLUME_MAX
107 #define INPUT_VOLUME_MIN LIV_MIN
108 #define INPUT_VOLUME_MAX LIV_MAX
109 #define INPUT_VOLUME_RANGE (INPUT_VOLUME_MAX - INPUT_VOLUME_MIN)
110 #define INPUT_VOLUME_MASK INPUT_VOLUME_MAX
112 #define NUMBER_SAMPLE_RATES_SUPPORTED 9
114 static audio_stream_t output_stream = {
116 .dma_dev = OMAP_DMA_MCBSP1_TX,
117 .input_or_output = FMODE_WRITE
120 static audio_stream_t input_stream = {
122 .dma_dev = OMAP_DMA_MCBSP1_RX,
123 .input_or_output = FMODE_READ
126 static struct clk *aic23_mclk = 0;
128 static int audio_dev_id, mixer_dev_id;
130 static struct aic23_local_info {
135 u16 input_volume_reg;
139 struct sample_rate_reg_info {
141 u8 control; /* SR3, SR2, SR1, SR0 and BOSR */
142 u8 divider; /* if 0 CLKIN = MCLK, if 1 CLKIN = MCLK/2 */
145 /* To Store the default sample rate */
146 static long audio_samplerate = AUDIO_RATE_DEFAULT;
148 /* DAC USB-mode sampling rates (MCLK = 12 MHz) */
149 static const struct sample_rate_reg_info
150 reg_info[NUMBER_SAMPLE_RATES_SUPPORTED] = {
162 static struct omap_mcbsp_reg_cfg initial_config = {
163 .spcr2 = FREE | FRST | GRST | XRST | XINTM(3),
164 .spcr1 = RINTM(3) | RRST,
165 .rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) |
166 RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(0),
167 .rcr1 = RFRLEN1(OMAP_MCBSP_WORD_8) | RWDLEN1(OMAP_MCBSP_WORD_16),
168 .xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) |
169 XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(0) | XFIG,
170 .xcr1 = XFRLEN1(OMAP_MCBSP_WORD_8) | XWDLEN1(OMAP_MCBSP_WORD_16),
171 .srgr1 = FWID(DEFAULT_BITPERSAMPLE - 1),
172 .srgr2 = GSYNC | CLKSP | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1),
174 /* configure McBSP to be the I2S master */
175 .pcr0 = FSXM | FSRM | CLKXM | CLKRM | CLKXP | CLKRP,
177 /* configure McBSP to be the I2S slave */
178 .pcr0 = CLKXP | CLKRP,
179 #endif /* AIC23_MASTER */
182 static void omap_aic23_initialize(void *dummy);
183 static void omap_aic23_shutdown(void *dummy);
184 static int omap_aic23_ioctl(struct inode *inode, struct file *file,
185 uint cmd, ulong arg);
186 static int omap_aic23_probe(void);
188 static void omap_aic23_remove(void);
190 static int omap_aic23_suspend(void);
191 static int omap_aic23_resume(void);
192 static inline void aic23_configure(void);
193 static int mixer_open(struct inode *inode, struct file *file);
194 static int mixer_release(struct inode *inode, struct file *file);
195 static int mixer_ioctl(struct inode *inode, struct file *file, uint cmd,
198 #ifdef CONFIG_PROC_FS
199 static int codec_start(char *buf, char **start, off_t offset, int count,
200 int *eof, void *data);
201 static int codec_stop(char *buf, char **start, off_t offset, int count,
202 int *eof, void *data);
206 /* File Op structure for mixer */
207 static struct file_operations omap_mixer_fops = {
209 .release = mixer_release,
210 .ioctl = mixer_ioctl,
214 /* To store characteristic info regarding the codec for the audio driver */
215 static audio_state_t aic23_state = {
216 .output_stream = &output_stream,
217 .input_stream = &input_stream,
218 /* .need_tx_for_rx = 1, //Once the Full Duplex works */
220 .hw_init = omap_aic23_initialize,
221 .hw_shutdown = omap_aic23_shutdown,
222 .client_ioctl = omap_aic23_ioctl,
223 .hw_probe = omap_aic23_probe,
224 .hw_remove = __exit_p(omap_aic23_remove),
225 .hw_suspend = omap_aic23_suspend,
226 .hw_resume = omap_aic23_resume,
227 .sem = __SEMAPHORE_INIT(aic23_state.sem, 1),
230 /* This will be defined in the audio.h */
231 static struct file_operations *omap_audio_fops;
233 extern int tlv320aic23_write_value(u8 reg, u16 value);
235 /* TLV320AIC23 is a write only device */
236 static __inline__ void audio_aic23_write(u8 address, u16 data)
238 tlv320aic23_write_value(address, data);
241 static int aic23_update(int flag, int val)
245 /* Ignore separate left/right channel for now,
246 even the codec does support it. */
249 if (val < 0 || val > 100) {
250 printk(KERN_ERR "Trying a bad volume value(%d)!\n",val);
256 // Convert 0 -> 100 volume to 0x00 (LHV_MIN) -> 0x7f (LHV_MAX)
258 volume = ((val * OUTPUT_VOLUME_RANGE) / 100) + OUTPUT_VOLUME_MIN;
260 // R/LHV[6:0] 1111111 (+6dB) to 0000000 (-73dB) in 1db steps,
261 // default 1111001 (0dB)
262 aic23_local.volume_reg &= ~OUTPUT_VOLUME_MASK;
263 aic23_local.volume_reg |= volume;
264 audio_aic23_write(LEFT_CHANNEL_VOLUME_ADDR, aic23_local.volume_reg);
265 audio_aic23_write(RIGHT_CHANNEL_VOLUME_ADDR, aic23_local.volume_reg);
269 // Convert 0 -> 100 volume to 0x0 (LIV_MIN) -> 0x1f (LIV_MAX)
271 volume = ((val * INPUT_VOLUME_RANGE) / 100) + INPUT_VOLUME_MIN;
273 // R/LIV[4:0] 11111 (+12dB) to 00000 (-34.5dB) in 1.5dB steps,
274 // default 10111 (0dB)
275 aic23_local.input_volume_reg &= ~INPUT_VOLUME_MASK;
276 aic23_local.input_volume_reg |= volume;
277 audio_aic23_write(LEFT_LINE_VOLUME_ADDR, aic23_local.input_volume_reg);
278 audio_aic23_write(RIGHT_LINE_VOLUME_ADDR, aic23_local.input_volume_reg);
284 static int mixer_open(struct inode *inode, struct file *file)
286 /* Any mixer specific initialization */
291 static int mixer_release(struct inode *inode, struct file *file)
293 /* Any mixer specific Un-initialization */
299 mixer_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
303 int nr = _IOC_NR(cmd);
306 * We only accept mixer (type 'M') ioctls.
308 if (_IOC_TYPE(cmd) != 'M')
311 DPRINTK(" 0x%08x\n", cmd);
313 if (cmd == SOUND_MIXER_INFO) {
314 struct mixer_info mi;
316 strncpy(mi.id, "AIC23", sizeof(mi.id));
317 strncpy(mi.name, "TI AIC23", sizeof(mi.name));
318 mi.modify_counter = aic23_local.mod_cnt;
319 return copy_to_user((void *)arg, &mi, sizeof(mi));
322 if (_IOC_DIR(cmd) & _IOC_WRITE) {
323 ret = get_user(val, (int *)arg);
329 case SOUND_MIXER_VOLUME:
330 aic23_local.volume = val;
331 aic23_local.mod_cnt++;
332 ret = aic23_update(SET_VOLUME, val);
335 case SOUND_MIXER_LINE:
336 aic23_local.line = val;
337 aic23_local.mod_cnt++;
338 ret = aic23_update(SET_LINE, val);
341 case SOUND_MIXER_MIC:
342 aic23_local.mic = val;
343 aic23_local.mod_cnt++;
344 ret = aic23_update(SET_LINE, val);
347 case SOUND_MIXER_RECSRC:
355 if (ret == 0 && _IOC_DIR(cmd) & _IOC_READ) {
359 case SOUND_MIXER_VOLUME:
360 val = aic23_local.volume;
362 case SOUND_MIXER_LINE:
363 val = aic23_local.line;
365 case SOUND_MIXER_MIC:
366 val = aic23_local.mic;
368 case SOUND_MIXER_RECSRC:
371 case SOUND_MIXER_RECMASK:
374 case SOUND_MIXER_DEVMASK:
377 case SOUND_MIXER_CAPS:
380 case SOUND_MIXER_STEREODEVS:
390 ret = put_user(val, (int *)arg);
397 int omap_set_samplerate(long sample_rate)
401 /* wait for any frame to complete */
404 /* Search for the right sample rate */
405 while ((reg_info[count].sample_rate != sample_rate) &&
406 (count < NUMBER_SAMPLE_RATES_SUPPORTED)) {
409 if (count == NUMBER_SAMPLE_RATES_SUPPORTED) {
410 printk(KERN_ERR "Invalid Sample Rate %d requested\n",
415 if (machine_is_omap_innovator()) {
416 /* set the CODEC clock input source to 12.000MHz */
417 fpga_write(fpga_read(OMAP1510_FPGA_POWER) & ~0x01,
418 OMAP1510_FPGA_POWER);
421 data = (reg_info[count].divider << CLKIN_SHIFT) |
422 (reg_info[count].control << BOSR_SHIFT) | USB_CLK_ON;
424 audio_aic23_write(SAMPLE_RATE_CONTROL_ADDR, data);
426 audio_samplerate = sample_rate;
432 Set Sample Rate at McBSP
435 Codec System Clock = CODEC_CLOCK, or half if clock_divider = 1;
436 clkgdv = ((Codec System Clock / (SampleRate * BitsPerSample * 2)) - 1);
438 FWID = BitsPerSample - 1;
439 FPER = (BitsPerSample * 2) - 1;
441 if (reg_info[count].divider)
442 clkgdv = CODEC_CLOCK / 2;
444 clkgdv = CODEC_CLOCK;
446 clkgdv = (clkgdv / (sample_rate * DEFAULT_BITPERSAMPLE * 2)) - 1;
448 initial_config.srgr1 = (FWID(DEFAULT_BITPERSAMPLE - 1) | CLKGDV(clkgdv));
450 initial_config.srgr2 =
451 (CLKSM | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1));
453 omap_mcbsp_config(AUDIO_MCBSP, &initial_config);
455 #endif /* AIC23_MASTER */
460 static void omap_aic23_initialize(void *dummy)
464 /* initialize with default sample rate */
465 audio_samplerate = AUDIO_RATE_DEFAULT;
467 omap_mcbsp_request(AUDIO_MCBSP);
469 /* if configured, then stop mcbsp */
470 omap_mcbsp_stop(AUDIO_MCBSP);
472 omap_mcbsp_config(AUDIO_MCBSP, &initial_config);
473 omap_mcbsp_start(AUDIO_MCBSP);
479 static void omap_aic23_shutdown(void *dummy)
482 Turn off codec after it is done.
483 Can't do it immediately, since it may still have
486 Wait 20ms (arbitrary value) and then turn it off.
489 set_current_state(TASK_INTERRUPTIBLE);
492 omap_mcbsp_stop(AUDIO_MCBSP);
493 omap_mcbsp_free(AUDIO_MCBSP);
495 audio_aic23_write(RESET_CONTROL_ADDR, 0);
496 audio_aic23_write(POWER_DOWN_CONTROL_ADDR, 0xff);
499 static inline void aic23_configure()
502 audio_aic23_write(RESET_CONTROL_ADDR, 0);
504 /* Initialize the AIC23 internal state */
506 /* Left/Right line input volume control */
507 aic23_local.line = DEFAULT_INPUT_VOLUME;
508 aic23_local.mic = DEFAULT_INPUT_VOLUME;
509 aic23_update(SET_LINE, DEFAULT_INPUT_VOLUME);
511 /* Left/Right headphone channel volume control */
512 /* Zero-cross detect on */
513 aic23_local.volume_reg = LZC_ON;
514 aic23_update(SET_VOLUME, aic23_local.volume);
516 /* Analog audio path control, DAC selected, delete INSEL_MIC for line in */
517 audio_aic23_write(ANALOG_AUDIO_CONTROL_ADDR, DAC_SELECTED | INSEL_MIC);
519 /* Digital audio path control, de-emphasis control 44.1kHz */
520 audio_aic23_write(DIGITAL_AUDIO_CONTROL_ADDR, DEEMP_44K);
522 /* Power control, everything is on */
523 audio_aic23_write(POWER_DOWN_CONTROL_ADDR, 0);
525 /* Digital audio interface, master/slave mode, I2S, 16 bit */
527 audio_aic23_write(DIGITAL_AUDIO_FORMAT_ADDR, MS_MASTER | IWL_16 | FOR_DSP);
529 audio_aic23_write(DIGITAL_AUDIO_FORMAT_ADDR, IWL_16 | FOR_DSP);
530 #endif /* AIC23_MASTER */
532 /* Enable digital interface */
533 audio_aic23_write(DIGITAL_INTERFACE_ACT_ADDR, ACT_ON);
535 /* clock configuration */
536 omap_set_samplerate(audio_samplerate);
540 omap_aic23_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
545 DPRINTK(" 0x%08x\n", cmd);
548 * These are platform dependent ioctls which are not handled by the
549 * generic omap-audio module.
552 case SNDCTL_DSP_STEREO:
553 ret = get_user(val, (int *)arg);
556 /* the AIC23 is stereo only */
557 ret = (val == 0) ? -EINVAL : 1;
558 return put_user(ret, (int *)arg);
560 case SNDCTL_DSP_CHANNELS:
561 case SOUND_PCM_READ_CHANNELS:
562 /* the AIC23 is stereo only */
563 return put_user(2, (long *)arg);
565 case SNDCTL_DSP_SPEED:
566 ret = get_user(val, (long *)arg);
569 ret = omap_set_samplerate(val);
574 case SOUND_PCM_READ_RATE:
575 return put_user(audio_samplerate, (long *)arg);
577 case SOUND_PCM_READ_BITS:
578 case SNDCTL_DSP_SETFMT:
579 case SNDCTL_DSP_GETFMTS:
580 /* we can do 16-bit only */
581 return put_user(AFMT_S16_LE, (long *)arg);
584 /* Maybe this is meant for the mixer (As per OSS Docs) */
585 return mixer_ioctl(inode, file, cmd, arg);
591 static int omap_aic23_probe(void)
593 /* Get the fops from audio oss driver */
594 if (!(omap_audio_fops = audio_get_fops())) {
595 printk(KERN_ERR "Unable to get the file operations for AIC23 OSS driver\n");
596 audio_unregister_codec(&aic23_state);
600 aic23_local.volume = DEFAULT_OUTPUT_VOLUME;
602 /* register devices */
603 audio_dev_id = register_sound_dsp(omap_audio_fops, -1);
604 mixer_dev_id = register_sound_mixer(&omap_mixer_fops, -1);
606 #ifdef CONFIG_PROC_FS
607 create_proc_read_entry(PROC_START_FILE, 0 /* default mode */ ,
608 NULL /* parent dir */ ,
609 codec_start, NULL /* client data */ );
611 create_proc_read_entry(PROC_STOP_FILE, 0 /* default mode */ ,
612 NULL /* parent dir */ ,
613 codec_stop, NULL /* client data */ );
616 /* Announcement Time */
617 printk(KERN_INFO PLATFORM_NAME " " CODEC_NAME
618 " audio support initialized\n");
623 static void __exit omap_aic23_remove(void)
625 /* Un-Register the codec with the audio driver */
626 unregister_sound_dsp(audio_dev_id);
627 unregister_sound_mixer(mixer_dev_id);
629 #ifdef CONFIG_PROC_FS
630 remove_proc_entry(PROC_START_FILE, NULL);
631 remove_proc_entry(PROC_STOP_FILE, NULL);
636 static int omap_aic23_suspend(void)
638 /* Empty for the moment */
642 static int omap_aic23_resume(void)
644 /* Empty for the moment */
648 static int __init audio_aic23_init(void)
653 if (machine_is_omap_h2() || machine_is_omap_h3())
656 if (machine_is_omap_osk()) {
657 /* Set MCLK to be clock input for AIC23 */
658 aic23_mclk = clk_get(0, "mclk");
660 if(clk_get_rate( aic23_mclk) != CODEC_CLOCK){
661 /* MCLK ist not at CODEC_CLOCK */
662 if( clk_get_usecount(aic23_mclk) > 0 ){
663 /* MCLK is already in use */
664 printk(KERN_WARNING "MCLK in use at %d Hz. We change it to %d Hz\n",
665 (uint)clk_get_rate( aic23_mclk), CODEC_CLOCK);
667 if( clk_set_rate( aic23_mclk, CODEC_CLOCK ) ){
668 printk(KERN_ERR "Cannot set MCLK for AIC23 CODEC\n");
673 clk_use( aic23_mclk );
675 DPRINTK("MCLK = %d [%d], usecount = %d\n",(uint)clk_get_rate( aic23_mclk ),
676 CODEC_CLOCK, clk_get_usecount( aic23_mclk));
679 if (machine_is_omap_innovator()) {
682 Turn on chip select for CODEC (shared with touchscreen).
683 Don't turn it back off, in case touch screen needs it.
685 fpga = fpga_read(OMAP1510_FPGA_TOUCHSCREEN);
687 fpga_write(fpga, OMAP1510_FPGA_TOUCHSCREEN);
690 /* register the codec with the audio driver */
691 if ((err = audio_register_codec(&aic23_state))) {
693 "Failed to register AIC23 driver with Audio OSS Driver\n");
699 static void __exit audio_aic23_exit(void)
701 (void)audio_unregister_codec(&aic23_state);
705 #ifdef CONFIG_PROC_FS
706 static int codec_start(char *buf, char **start, off_t offset, int count,
707 int *eof, void *data)
711 omap_aic23_initialize(foo);
713 printk("AIC23 codec initialization done.\n");
716 static int codec_stop(char *buf, char **start, off_t offset, int count,
717 int *eof, void *data)
721 omap_aic23_shutdown(foo);
723 printk("AIC23 codec shutdown.\n");
726 #endif /* CONFIG_PROC_FS */
728 module_init(audio_aic23_init);
729 module_exit(audio_aic23_exit);
731 MODULE_AUTHOR("Dirk Behme <dirk.behme@de.bosch.com>");
732 MODULE_DESCRIPTION("Glue audio driver for the TI AIC23 codec.");
733 MODULE_LICENSE("GPL");