diff options
Diffstat (limited to 'sound/soc/u8500/u8500_msp_dai.c')
-rwxr-xr-x | sound/soc/u8500/u8500_msp_dai.c | 513 |
1 files changed, 0 insertions, 513 deletions
diff --git a/sound/soc/u8500/u8500_msp_dai.c b/sound/soc/u8500/u8500_msp_dai.c deleted file mode 100755 index c5600669091..00000000000 --- a/sound/soc/u8500/u8500_msp_dai.c +++ /dev/null @@ -1,513 +0,0 @@ -/* - * Copyright (C) ST-Ericsson SA 2010 - * - * Author: Ola Lilja ola.o.lilja@stericsson.com, - * Roger Nilsson roger.xr.nilsson@stericsson.com - * for ST-Ericsson. - * - * License terms: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - */ -#include <sound/soc.h> -#include <sound/soc-dai.h> -#include <asm/dma.h> -#include "u8500_msp_dai.h" -#include "u8500_pcm.h" - -#include <mach/msp.h> -#include <linux/i2s/i2s.h> - -struct u8500_dai_private_t{ - spinlock_t lock; - struct i2s_device *i2s; - u8 rx_active; - u8 tx_active; -}; - -struct u8500_dai_private_t msp_dai_private[U8500_NBR_OF_DAI] = -{ - /* DAI 0 */ - { - .lock = SPIN_LOCK_UNLOCKED, - .i2s = NULL, - .tx_active = 0, - .rx_active = 0, - }, - /* DAI 1 */ - { - .lock = SPIN_LOCK_UNLOCKED, - .i2s = NULL, - .tx_active = 0, - .rx_active = 0, - }, -}; - -static void compile_msp_config(struct msp_generic_config *msp_config,struct snd_pcm_substream *substream) -{ - int channels; - - msp_config->tx_clock_sel = 0; - msp_config->rx_clock_sel = 0; - msp_config->tx_frame_sync_sel = 0; - msp_config->rx_frame_sync_sel = 0; - msp_config->input_clock_freq = MSP_INPUT_FREQ_48MHZ; - msp_config->srg_clock_sel = 0; - msp_config->rx_frame_sync_pol = RX_FIFO_SYNC_HI; - msp_config->tx_frame_sync_pol = TX_FIFO_SYNC_HI; - msp_config->rx_fifo_config = RX_FIFO_ENABLE; - msp_config->tx_fifo_config = TX_FIFO_ENABLE; - msp_config->spi_clk_mode = SPI_CLK_MODE_NORMAL; - msp_config->spi_burst_mode = 0; - msp_config->handler = u8500_pcm_dma_eot_handler; - msp_config->tx_callback_data = substream; - msp_config->tx_data_enable = 0; - msp_config->rx_callback_data = substream; - msp_config->loopback_enable = 0; - msp_config->multichannel_configured = 0; - msp_config->def_elem_len = 0; - msp_config->default_protocol_desc = 0; - msp_config->protocol_desc.rx_phase_mode = MSP_SINGLE_PHASE; - msp_config->protocol_desc.tx_phase_mode = MSP_SINGLE_PHASE; - msp_config->protocol_desc.rx_phase2_start_mode = MSP_PHASE2_START_MODE_IMEDIATE; - msp_config->protocol_desc.tx_phase2_start_mode = MSP_PHASE2_START_MODE_IMEDIATE; - msp_config->protocol_desc.rx_bit_transfer_format = MSP_BTF_MS_BIT_FIRST; - msp_config->protocol_desc.tx_bit_transfer_format = MSP_BTF_MS_BIT_FIRST; - msp_config->protocol_desc. rx_frame_length_1 = MSP_FRAME_LENGTH_2; - msp_config->protocol_desc. rx_frame_length_2 = MSP_FRAME_LENGTH_2; - msp_config->protocol_desc.tx_frame_length_1 = MSP_FRAME_LENGTH_2; - msp_config->protocol_desc.tx_frame_length_2 = MSP_FRAME_LENGTH_2; - msp_config->protocol_desc. rx_element_length_1 = MSP_ELEM_LENGTH_32; - msp_config->protocol_desc.rx_element_length_2 = MSP_ELEM_LENGTH_32; - msp_config->protocol_desc.tx_element_length_1 = MSP_ELEM_LENGTH_32; - msp_config->protocol_desc.tx_element_length_2 = MSP_ELEM_LENGTH_32; - msp_config->protocol_desc.rx_data_delay = MSP_DELAY_0; - msp_config->protocol_desc.tx_data_delay = MSP_DELAY_0; - msp_config->protocol_desc.rx_clock_pol = MSP_FALLING_EDGE; - msp_config->protocol_desc.tx_clock_pol = MSP_RISING_EDGE; - msp_config->protocol_desc. rx_frame_sync_pol = MSP_FRAME_SYNC_POL_ACTIVE_HIGH; - msp_config->protocol_desc.tx_frame_sync_pol = MSP_FRAME_SYNC_POL_ACTIVE_HIGH; - msp_config->protocol_desc.rx_half_word_swap = MSP_HWS_NO_SWAP; - msp_config->protocol_desc.tx_half_word_swap = MSP_HWS_NO_SWAP; - msp_config->protocol_desc.compression_mode = MSP_COMPRESS_MODE_LINEAR; - msp_config->protocol_desc.expansion_mode = MSP_EXPAND_MODE_LINEAR; - msp_config->protocol_desc.spi_clk_mode = MSP_SPI_CLOCK_MODE_NON_SPI; - msp_config->protocol_desc.spi_burst_mode = MSP_SPI_BURST_MODE_DISABLE; - msp_config->protocol_desc.frame_sync_ignore = MSP_FRAME_SYNC_IGNORE; - msp_config->protocol_desc.frame_period = 63; - msp_config->protocol_desc.frame_width = 31; - msp_config->protocol_desc.total_clocks_for_one_frame = 64; - msp_config->protocol = MSP_I2S_PROTOCOL; //MSP_PCM_PROTOCOL - msp_config->direction = MSP_BOTH_T_R_MODE; - msp_config->frame_size = 0; - msp_config->frame_freq = 48000; - channels = 2; - msp_config->data_size = (channels == 1) ? MSP_DATA_SIZE_16BIT : MSP_DATA_SIZE_32BIT; - msp_config->work_mode = MSP_DMA_MODE; - msp_config->multichannel_configured = 1; - msp_config->multichannel_config.tx_multichannel_enable = 1; - msp_config->multichannel_config.tx_channel_0_enable = 0x0000003; //Channel 1 and channel 2 - msp_config->multichannel_config.tx_channel_1_enable = 0x0000000; //Channel 1 and channel 2 - msp_config->multichannel_config.tx_channel_2_enable = 0x0000000; //Channel 1 and channel 2 - msp_config->multichannel_config.tx_channel_3_enable = 0x0000000; //Channel 1 and channel 2 - msp_config->multichannel_config.rx_multichannel_enable = 1; - msp_config->multichannel_config.rx_channel_0_enable = 0x0000003; //Channel 1 and channel 2 - msp_config->multichannel_config.rx_channel_1_enable = 0x0000000; //Channel 1 and channel 2 - msp_config->multichannel_config.rx_channel_2_enable = 0x0000000; //Channel 1 and channel 2 - msp_config->multichannel_config.rx_channel_3_enable = 0x0000000; //Channel 1 and channel 2 -} - -static void u8500_dai_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *msp_dai) -{ - int ret = 0; - unsigned long flags; - struct u8500_dai_private_t *dai_private; - - printk(KERN_ALERT "STW4500: u8500_dai_shutdown\n"); - - if (!(dai_private = msp_dai->private_data)) - return; - - spin_lock_irqsave(&dai_private->lock, flags); - - /* Mark the stopped direction as inactive */ - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - dai_private->tx_active = 0; - } else { - dai_private->rx_active = 0; - } - - if (0 == dai_private->tx_active && 0 == dai_private->rx_active) { - msp_dai->private_data = NULL; - - - ret = i2s_cleanup(dai_private->i2s->controller, DISABLE_ALL); - - if (ret) - printk(KERN_WARNING "Error closing i2s\n"); - - } else { - - if(dai_private->tx_active) - ret = i2s_cleanup(dai_private->i2s->controller, DISABLE_RECEIVE); - else - ret = i2s_cleanup(dai_private->i2s->controller, DISABLE_TRANSMIT); - - if (ret) - printk(KERN_WARNING "Error closing i2s\n"); - } - - spin_unlock_irqrestore(&dai_private->lock, flags); - - return; -} - -static int u8500_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *msp_dai) -{ - struct u8500_dai_private_t *dai_private; - - printk(KERN_ALERT "STW4500: u8500_dai_startup\n"); - - dai_private=&msp_dai_private[msp_dai->id]; - /* Store pointer to private data */ - msp_dai->private_data = dai_private; - - if (dai_private->i2s == NULL) - { - printk(KERN_ALERT "u8500_pcm_open: Error: i2sdrv.i2s == NULL.\n"); - return -1; - } - if (dai_private->i2s->controller == NULL) - { - printk(KERN_ALERT "u8500_pcm_open: Error: i2sdrv.i2s->controller == NULL.\n"); - return -1; - } - - - return 0; -} - -static int u8500_dai_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *msp_dai) -{ - int ret = 0; - unsigned long flags_private; - struct u8500_dai_private_t *dai_private; - struct msp_generic_config msp_config; - - printk(KERN_ALERT "STW4500: u8500_dai_prepare\n"); - - dai_private = msp_dai->private_data; - - spin_lock_irqsave(&dai_private->lock, flags_private); - - /* Is the other direction already active? */ - if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK && - dai_private->rx_active) || - (substream->stream == SNDRV_PCM_STREAM_CAPTURE && - dai_private->tx_active)) { - /* TODO: Check if sample rate match ! */ - /* - if ( != runtime->rate) { - printk(KERN_ERR "CPU_DAI configuration mismatch with already opened stream!\n"); - ret = -EBUSY; - goto cleanup; - } - */ - } else if (!dai_private->rx_active && !dai_private->tx_active) { - ret = 0; - - compile_msp_config(&msp_config,substream); - - ret = i2s_setup(dai_private->i2s->controller, &msp_config); - if (ret < 0) { - printk(KERN_ALERT "u8500_dai_prepare: i2s_setup failed! ret = %d\n", ret); - goto cleanup; - } - } - - /* Mark the newly started stream as active */ - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - dai_private->tx_active = 1; - } else { - dai_private->rx_active = 1; - } - -cleanup: - spin_unlock_irqrestore(&dai_private->lock, flags_private); - return ret; -} - -static int u8500_dai_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, struct snd_soc_dai *msp_dai) -{ - printk(KERN_ALERT "STW4500: u8500_dai_hw_params\n"); - - return 0; -} - -static int u8500_dai_set_dai_fmt(struct snd_soc_dai *msp_dai, unsigned int fmt) -{ - printk(KERN_ALERT "STW4500: u8500_dai_set_dai_fmt\n"); - return 0; -} - -static int u8500_dai_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *msp_dai) -{ - unsigned long flags; - int ret = 0; - struct u8500_dai_private_t *u8500_dai_private = msp_dai->private_data; - - printk(KERN_ALERT "STW4500: u8500_dai_trigger\n"); - - spin_lock_irqsave(&u8500_dai_private->lock, flags); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - ret = 0; - break; - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - ret = 0; - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - ret = 0; - break; - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - ret = 0; - break; - default: - ret = -EINVAL; - break; - } - - spin_unlock_irqrestore(&u8500_dai_private->lock, flags); - return ret; -} - -int u8500_i2s_send_data(void *data, size_t bytes, int dai_idx) -{ - unsigned long flags; - struct u8500_dai_private_t *dai_private; - struct i2s_message message; - struct i2s_device *i2s_dev; - int ret = 0; - dai_private=&msp_dai_private[dai_idx]; - - spin_lock_irqsave(&dai_private->lock, flags); - - i2s_dev=dai_private->i2s; - - - if(!dai_private->tx_active) - { - printk(KERN_ERR "u8500_i2s_send_data: I2S controller not available\n"); - goto cleanup; - } - - message.txbytes = bytes; - message.txdata = data; - message.rxbytes = 0; - message.rxdata = NULL; - message.dma_flag = 1; - - ret = i2s_transfer(i2s_dev->controller, &message); - if(ret < 0) - { - printk(KERN_ERR "u8500_i2s_send_data: Error: i2s_transfer failed!\n"); - goto cleanup; - } - -cleanup: - spin_unlock_irqrestore(&dai_private->lock, flags); - return ret; -} - -int u8500_i2s_receive_data(void *data, size_t bytes, int dai_idx) -{ - unsigned long flags; - struct u8500_dai_private_t *dai_private; - struct i2s_message message; - struct i2s_device *i2s_dev; - int ret = 0; - dai_private=&msp_dai_private[dai_idx]; - - spin_lock_irqsave(&dai_private->lock, flags); - - i2s_dev=dai_private->i2s; - - - if(!dai_private->rx_active) - { - printk(KERN_ERR "u8500_i2s_receive_data: I2S controller not available\n"); - goto cleanup; - } - - message.rxbytes = bytes; - message.rxdata = data; - message.txbytes = 0; - message.txdata = NULL; - message.dma_flag = 1; - - ret = i2s_transfer(i2s_dev->controller, &message); - if(ret < 0) - { - printk(KERN_ERR "u8500_i2s_receive_data: Error: i2s_transfer failed!\n"); - goto cleanup; - } - -cleanup: - spin_unlock_irqrestore(&dai_private->lock, flags); - return ret; -} - -#define u8500_I2S_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | \ - SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) -#define u8500_I2S_FORMATS ( SNDRV_PCM_FMTBIT_S16_LE ) - -#define dai_suspend NULL -#define dai_resume NULL -#define u8500_dai_set_dai_sysclk NULL - -struct snd_soc_dai_ops u8500_msp_dai_ops_0 = -{ - .set_sysclk=u8500_dai_set_dai_sysclk, - .set_fmt=u8500_dai_set_dai_fmt, - .startup = u8500_dai_startup, - .shutdown = u8500_dai_shutdown, - .prepare = u8500_dai_prepare, - .trigger = u8500_dai_trigger, - .hw_params = u8500_dai_hw_params, -}; - -struct snd_soc_dai_ops u8500_msp_dai_ops_1 = -{ - .set_sysclk=u8500_dai_set_dai_sysclk, - .set_fmt=u8500_dai_set_dai_fmt, - .startup = u8500_dai_startup, - .shutdown = u8500_dai_shutdown, - .prepare = u8500_dai_prepare, - .trigger = u8500_dai_trigger, - .hw_params = u8500_dai_hw_params, -}; - -struct snd_soc_dai u8500_msp_dai[U8500_NBR_OF_DAI] = -{ - { - .name = "u8500_i2s-0", - .id = 0, - //.type = SND_SOC_DAI_I2S, - .suspend = dai_suspend, - .resume = dai_resume, - .playback = { - .channels_min = 2, - .channels_max = 2, - .rates = u8500_I2S_RATES, - .formats = u8500_I2S_FORMATS,}, - .capture = { - .channels_min = 2, - .channels_max = 2, - .rates = u8500_I2S_RATES, - .formats = u8500_I2S_FORMATS,}, - .ops = &u8500_msp_dai_ops_0, - .private_data = &msp_dai_private[0], - }, - { - .name = "u8500_i2s-1", - .id = 1, - //.type = SND_SOC_DAI_I2S, - .suspend = dai_suspend, - .resume = dai_resume, - .playback = { - .channels_min = 2, - .channels_max = 2, - .rates = u8500_I2S_RATES, - .formats = u8500_I2S_FORMATS,}, - .capture = { - .channels_min = 2, - .channels_max = 2, - .rates = u8500_I2S_RATES, - .formats = u8500_I2S_FORMATS,}, - .ops = &u8500_msp_dai_ops_1, - .private_data = &msp_dai_private[1], - }, -}; - -EXPORT_SYMBOL(u8500_msp_dai); - - - -static int i2sdrv_probe(struct i2s_device *i2s) -{ - unsigned long flags; - struct u8500_dai_private_t *u8500_dai_private; - - u8500_dai_private=&msp_dai_private[0]; - printk(KERN_DEBUG "i2sdrv_probe: Enter.\n"); - - spin_lock_irqsave(&u8500_dai_private->lock, flags); - u8500_dai_private->i2s = i2s; - spin_unlock_irqrestore(&u8500_dai_private->lock, flags); - - try_module_get(i2s->controller->dev.parent->driver->owner); - i2s_set_drvdata(i2s, (void*)u8500_dai_private); - - return 0; -} - - - -static int i2sdrv_remove(struct i2s_device *i2s) -{ - unsigned long flags; - struct u8500_dai_private_t *u8500_dai_private = i2s_get_drvdata(i2s); - - printk(KERN_DEBUG "U8500_PCM: i2sdrv_remove\n"); - - spin_lock_irqsave(&u8500_dai_private->lock, flags); - - u8500_dai_private->i2s = NULL; - i2s_set_drvdata(i2s, NULL); - spin_unlock_irqrestore(&u8500_dai_private->lock, flags); - - - printk(KERN_ALERT "i2sdrv_remove: module_put\n"); - module_put(i2s->controller->dev.parent->driver->owner); - - return 0; -} - - - -static const struct i2s_device_id dev_id_table[] = { - { "i2s_device.0", 0, 0 }, - { }, -}; -MODULE_DEVICE_TABLE(i2s, acodec_id_table); - - - -static struct i2s_driver i2sdrv_i2s = { - .driver = { - .name = "nomadik_acodec", - .owner = THIS_MODULE, - }, - .probe = i2sdrv_probe, - .remove = __devexit_p(i2sdrv_remove), - .id_table = dev_id_table, -}; - -int u8500_platform_registerI2S(void) -{ - int ret; - - printk(KERN_ALERT "u8500_platform_registerI2S: Register I2S-driver.\n"); - ret = i2s_register_driver(&i2sdrv_i2s); - if (ret < 0) { - printk(KERN_ALERT "u8500_platform_registerI2S: Unable to register I2S-driver\n"); - } - - return ret; -} |