Path: blob/master/sound/soc/atmel/snd-soc-afeb9260.c
10817 views
/*1* afeb9260.c -- SoC audio for AFEB92602*3* Copyright (C) 2009 Sergey Lapin <[email protected]>4*5* This program is free software; you can redistribute it and/or6* modify it under the terms of the GNU General Public License7* version 2 as published by the Free Software Foundation.8*9* This program is distributed in the hope that it will be useful, but10* WITHOUT ANY WARRANTY; without even the implied warranty of11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU12* General Public License for more details.13*14* You should have received a copy of the GNU General Public License15* along with this program; if not, write to the Free Software16* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA17* 02110-1301 USA18*19*/2021#include <linux/module.h>22#include <linux/moduleparam.h>23#include <linux/kernel.h>24#include <linux/clk.h>25#include <linux/platform_device.h>2627#include <linux/atmel-ssc.h>28#include <sound/core.h>29#include <sound/pcm.h>30#include <sound/pcm_params.h>31#include <sound/soc.h>3233#include <asm/mach-types.h>34#include <mach/hardware.h>35#include <linux/gpio.h>3637#include "../codecs/tlv320aic23.h"38#include "atmel-pcm.h"39#include "atmel_ssc_dai.h"4041#define CODEC_CLOCK 120000004243static int afeb9260_hw_params(struct snd_pcm_substream *substream,44struct snd_pcm_hw_params *params)45{46struct snd_soc_pcm_runtime *rtd = substream->private_data;47struct snd_soc_dai *codec_dai = rtd->codec_dai;48struct snd_soc_dai *cpu_dai = rtd->cpu_dai;49int err;5051/* Set codec DAI configuration */52err = snd_soc_dai_set_fmt(codec_dai,53SND_SOC_DAIFMT_I2S|54SND_SOC_DAIFMT_NB_IF |55SND_SOC_DAIFMT_CBM_CFM);56if (err < 0) {57printk(KERN_ERR "can't set codec DAI configuration\n");58return err;59}6061/* Set cpu DAI configuration */62err = snd_soc_dai_set_fmt(cpu_dai,63SND_SOC_DAIFMT_I2S |64SND_SOC_DAIFMT_NB_IF |65SND_SOC_DAIFMT_CBM_CFM);66if (err < 0) {67printk(KERN_ERR "can't set cpu DAI configuration\n");68return err;69}7071/* Set the codec system clock for DAC and ADC */72err =73snd_soc_dai_set_sysclk(codec_dai, 0, CODEC_CLOCK, SND_SOC_CLOCK_IN);7475if (err < 0) {76printk(KERN_ERR "can't set codec system clock\n");77return err;78}7980return err;81}8283static struct snd_soc_ops afeb9260_ops = {84.hw_params = afeb9260_hw_params,85};8687static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = {88SND_SOC_DAPM_HP("Headphone Jack", NULL),89SND_SOC_DAPM_LINE("Line In", NULL),90SND_SOC_DAPM_MIC("Mic Jack", NULL),91};9293static const struct snd_soc_dapm_route audio_map[] = {94{"Headphone Jack", NULL, "LHPOUT"},95{"Headphone Jack", NULL, "RHPOUT"},9697{"LLINEIN", NULL, "Line In"},98{"RLINEIN", NULL, "Line In"},99100{"MICIN", NULL, "Mic Jack"},101};102103static int afeb9260_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)104{105struct snd_soc_codec *codec = rtd->codec;106struct snd_soc_dapm_context *dapm = &codec->dapm;107108/* Add afeb9260 specific widgets */109snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets,110ARRAY_SIZE(tlv320aic23_dapm_widgets));111112/* Set up afeb9260 specific audio path audio_map */113snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));114115snd_soc_dapm_enable_pin(dapm, "Headphone Jack");116snd_soc_dapm_enable_pin(dapm, "Line In");117snd_soc_dapm_enable_pin(dapm, "Mic Jack");118119snd_soc_dapm_sync(dapm);120121return 0;122}123124/* Digital audio interface glue - connects codec <--> CPU */125static struct snd_soc_dai_link afeb9260_dai = {126.name = "TLV320AIC23",127.stream_name = "AIC23",128.cpu_dai_name = "atmel-ssc-dai.0",129.codec_dai_name = "tlv320aic23-hifi",130.platform_name = "atmel_pcm-audio",131.codec_name = "tlv320aic23-codec.0-001a",132.init = afeb9260_tlv320aic23_init,133.ops = &afeb9260_ops,134};135136/* Audio machine driver */137static struct snd_soc_card snd_soc_machine_afeb9260 = {138.name = "AFEB9260",139.dai_link = &afeb9260_dai,140.num_links = 1,141};142143static struct platform_device *afeb9260_snd_device;144145static int __init afeb9260_soc_init(void)146{147int err;148struct device *dev;149150if (!(machine_is_afeb9260()))151return -ENODEV;152153154afeb9260_snd_device = platform_device_alloc("soc-audio", -1);155if (!afeb9260_snd_device) {156printk(KERN_ERR "ASoC: Platform device allocation failed\n");157return -ENOMEM;158}159160platform_set_drvdata(afeb9260_snd_device, &snd_soc_machine_afeb9260);161err = platform_device_add(afeb9260_snd_device);162if (err)163goto err1;164165dev = &afeb9260_snd_device->dev;166167return 0;168err1:169platform_device_put(afeb9260_snd_device);170return err;171}172173static void __exit afeb9260_soc_exit(void)174{175platform_device_unregister(afeb9260_snd_device);176}177178module_init(afeb9260_soc_init);179module_exit(afeb9260_soc_exit);180181MODULE_AUTHOR("Sergey Lapin <[email protected]>");182MODULE_DESCRIPTION("ALSA SoC for AFEB9260");183MODULE_LICENSE("GPL");184185186187