| /* |
| * pxa-ssp.c -- ALSA Soc Audio Layer |
| * |
| * Copyright 2005,2008 Wolfson Microelectronics PLC. |
| * Author: Liam Girdwood |
| * Mark Brown <broonie@opensource.wolfsonmicro.com> |
| * |
| * This program is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License as published by the |
| * Free Software Foundation; either version 2 of the License, or (at your |
| * option) any later version. |
| * |
| * TODO: |
| * o Test network mode for > 16bit sample size |
| */ |
| |
| #include <linux/init.h> |
| #include <linux/module.h> |
| #include <linux/slab.h> |
| #include <linux/platform_device.h> |
| #include <linux/clk.h> |
| #include <linux/io.h> |
| #include <linux/pxa2xx_ssp.h> |
| #include <linux/of.h> |
| #include <linux/dmaengine.h> |
| #include <linux/delay.h> |
| #include <linux/platform_data/mmp_audio.h> |
| #include <linux/pinctrl/consumer.h> |
| #include <linux/of_gpio.h> |
| #include <linux/features.h> |
| |
| #include <asm/irq.h> |
| |
| #include <sound/core.h> |
| #include <sound/pcm.h> |
| #include <sound/initval.h> |
| #include <sound/pcm_params.h> |
| #include <sound/soc.h> |
| #include <sound/pxa2xx-lib.h> |
| #include <sound/dmaengine_pcm.h> |
| |
| //#include <mach/hardware.h> |
| |
| //#include "../../arm/pxa2xx-pcm.h" |
| #include "pxa-ssp.h" |
| #ifndef CONFIG_CPU_ASR18XX |
| extern u32 sscr0_hifi; |
| extern u32 sscr1_hifi; |
| #else |
| extern u32 top_ctrl_hifi; |
| extern u32 fifo_ctrl_hifi; |
| extern u32 rwot_ctrl_hifi; |
| extern u32 network_ctrl_hifi; |
| extern u32 int_en_hifi; |
| #endif |
| |
| //extern int mmp_pcm_probe(struct platform_device *pdev); |
| //extern int pxa_pcm_platform_register(struct device *dev); |
| |
| static int pxa_ssp_startup(struct snd_pcm_substream *substream, |
| struct snd_soc_dai *cpu_dai) |
| { |
| return 0; |
| } |
| |
| static void pxa_ssp_shutdown(struct snd_pcm_substream *substream, |
| struct snd_soc_dai *cpu_dai) |
| { |
| return; |
| } |
| |
| #ifdef CONFIG_PM |
| |
| static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai) |
| { |
| return 0; |
| } |
| |
| static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai) |
| { |
| return 0; |
| } |
| |
| #else |
| #define pxa_ssp_suspend NULL |
| #define pxa_ssp_resume NULL |
| #endif |
| |
| |
| /* |
| * Set the SSP ports SYSCLK. |
| */ |
| static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai, |
| int clk_id, unsigned int freq, int dir) |
| { |
| return 0; |
| } |
| |
| /* |
| * Set the SSP clock dividers. |
| */ |
| static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai, |
| int div_id, int div) |
| { |
| return 0; |
| } |
| |
| /* |
| * Configure the PLL frequency pxa27x and (afaik - pxa320 only) |
| */ |
| static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id, |
| int source, unsigned int freq_in, unsigned int freq_out) |
| { |
| return 0; |
| } |
| |
| /* |
| * Set the active slots in TDM/Network mode |
| */ |
| static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, |
| unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) |
| { |
| return 0; |
| } |
| |
| /* |
| * Tristate the SSP DAI lines |
| */ |
| static int pxa_ssp_set_dai_tristate(struct snd_soc_dai *cpu_dai, |
| int tristate) |
| { |
| return 0; |
| } |
| |
| /* |
| * Set up the SSP DAI format. |
| * The SSP Port must be inactive before calling this function as the |
| * physical interface format is changed. |
| */ |
| static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai, |
| unsigned int fmt) |
| { |
| return 0; |
| } |
| |
| /* |
| * Set the SSP audio DMA parameters and sample size. |
| * Can be called multiple times by oss emulation. |
| */ |
| |
| static int pxa_ssp_hw_params(struct snd_pcm_substream *substream, |
| struct snd_pcm_hw_params *params, |
| struct snd_soc_dai *cpu_dai) |
| { |
| return 0; |
| } |
| |
| static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd, |
| struct snd_soc_dai *cpu_dai) |
| { |
| return 0; |
| } |
| |
| static int pxa_ssp_probe(struct snd_soc_dai *dai) |
| { |
| return 0; |
| } |
| |
| static int pxa_ssp_remove(struct snd_soc_dai *dai) |
| { |
| return 0; |
| } |
| |
| #define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ |
| SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \ |
| SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ |
| SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | \ |
| SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) |
| |
| #define PXA_SSP_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ |
| SNDRV_PCM_FMTBIT_S24_LE | \ |
| SNDRV_PCM_FMTBIT_S32_LE) |
| |
| static const struct snd_soc_dai_ops pxa_ssp_dai_ops = { |
| .startup = pxa_ssp_startup, |
| .shutdown = pxa_ssp_shutdown, |
| .trigger = pxa_ssp_trigger, |
| .hw_params = pxa_ssp_hw_params, |
| .set_sysclk = pxa_ssp_set_dai_sysclk, |
| .set_clkdiv = pxa_ssp_set_dai_clkdiv, |
| .set_pll = pxa_ssp_set_dai_pll, |
| .set_fmt = pxa_ssp_set_dai_fmt, |
| .set_tdm_slot = pxa_ssp_set_dai_tdm_slot, |
| .set_tristate = pxa_ssp_set_dai_tristate, |
| }; |
| |
| static struct snd_soc_dai_driver pxa_ssp_dai = { |
| .probe = pxa_ssp_probe, |
| .remove = pxa_ssp_remove, |
| .suspend = pxa_ssp_suspend, |
| .resume = pxa_ssp_resume, |
| .playback = { |
| .channels_min = 1, |
| .channels_max = 8, |
| .rates = PXA_SSP_RATES, |
| .formats = PXA_SSP_FORMATS, |
| }, |
| .capture = { |
| .channels_min = 1, |
| .channels_max = 8, |
| .rates = PXA_SSP_RATES, |
| .formats = PXA_SSP_FORMATS, |
| }, |
| .ops = &pxa_ssp_dai_ops, |
| }; |
| |
| static const struct snd_soc_component_driver pxa_ssp_component = { |
| .name = "pxa-ssp", |
| }; |
| |
| #ifdef CONFIG_OF |
| static const struct of_device_id pxa_ssp_of_ids[] = { |
| { .compatible = "asr,pxa-ssp-dai" }, |
| }; |
| #endif |
| |
| static int asoc_ssp_probe(struct platform_device *pdev) |
| { |
| struct device_node *np = pdev->dev.of_node; |
| char const *platform_driver_name; |
| int ret; |
| |
| printk(KERN_INFO"[5616 platform probe: begin] %s/L%d.\n", __FUNCTION__, __LINE__); |
| |
| if (of_property_read_string(np, |
| "platform_driver_name", |
| &platform_driver_name)) { |
| dev_err(&pdev->dev, |
| "Missing platform_driver_name property in the DT\n"); |
| return -EINVAL; |
| } |
| |
| ret = devm_snd_soc_register_component(&pdev->dev, &pxa_ssp_component, |
| &pxa_ssp_dai, 1); |
| if (ret != 0) { |
| dev_err(&pdev->dev, "Failed to register DAI\n"); |
| return ret; |
| } |
| |
| #if 0 //yjg |
| if (strcmp(platform_driver_name, "tdma_platform") == 0) { |
| printk(KERN_INFO"[5616 platform probe] %s/L%d.\n", __FUNCTION__, __LINE__); |
| ret = mmp_pcm_probe(pdev); |
| } else if (strcmp(platform_driver_name, "pdma_platform") == 0) { |
| printk(KERN_INFO"[5616 platform probe] %s/L%d.\n", __FUNCTION__, __LINE__); |
| ret = pxa_pcm_platform_register(&pdev->dev); |
| } |
| #endif |
| |
| printk(KERN_INFO"[5616 platform probe: end] %s/L%d.\n", __FUNCTION__, __LINE__); |
| |
| return ret; |
| } |
| |
| static struct platform_driver asoc_ssp_driver = { |
| .driver = { |
| .name = "pxa-ssp-dai", |
| .of_match_table = of_match_ptr(pxa_ssp_of_ids), |
| }, |
| |
| .probe = asoc_ssp_probe, |
| //.remove = asoc_ssp_remove, |
| }; |
| |
| module_platform_driver(asoc_ssp_driver); |
| |
| /* Module information */ |
| MODULE_AUTHOR("wenchen@asrmicro.com"); |
| MODULE_DESCRIPTION("ASR SSP/PCM SoC Interface"); |
| MODULE_LICENSE("GPL"); |