From 4dc69be22163bab880384858f30cb8cc76ad47f9 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Tue, 4 Jan 2011 20:16:07 +0530 Subject: ASoC: sst v2: Add sn95031 codec driver This patch adds the sn95031 asoc codec driver. This driver currently supports only playback. Capture and jack detection to be added later Signed-off-by: Vinod Koul Signed-off-by: Harsha Priya Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 4 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/sn95031.c | 495 +++++++++++++++++++++++++++++++++++++++++++++ sound/soc/codecs/sn95031.h | 99 +++++++++ 4 files changed, 600 insertions(+) create mode 100644 sound/soc/codecs/sn95031.c create mode 100644 sound/soc/codecs/sn95031.h diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 054191ed08ef..fa42be529a73 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -32,6 +32,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_MAX98088 if I2C select SND_SOC_MAX9877 if I2C select SND_SOC_PCM3008 + select SND_SOC_SN95031 if INTEL_SCU_IPC select SND_SOC_SPDIF select SND_SOC_SSM2602 if I2C select SND_SOC_STAC9766 if SND_SOC_AC97_BUS @@ -173,6 +174,9 @@ config SND_SOC_MAX98088 config SND_SOC_PCM3008 tristate +config SND_SOC_SN95031 + tristate + config SND_SOC_SPDIF tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 6a1e17bbbf83..76304d478912 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -18,6 +18,7 @@ snd-soc-l3-objs := l3.o snd-soc-max98088-objs := max98088.o snd-soc-pcm3008-objs := pcm3008.o snd-soc-alc5623-objs := alc5623.o +snd-soc-sn95031-objs := sn95031.o snd-soc-spdif-objs := spdif_transciever.o snd-soc-ssm2602-objs := ssm2602.o snd-soc-stac9766-objs := stac9766.o @@ -97,6 +98,7 @@ obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o +obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c new file mode 100644 index 000000000000..146b74467ae7 --- /dev/null +++ b/sound/soc/codecs/sn95031.c @@ -0,0 +1,495 @@ +/* + * sn95031.c - TI sn95031 Codec driver + * + * Copyright (C) 2010 Intel Corp + * Author: Vinod Koul + * Author: Harsha Priya + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * 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; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * + */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include "sn95031.h" + +#define SN95031_RATES (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100) +#define SN95031_FORMATS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) + +/* + * todo: + * capture paths + * jack detection + * PM functions + */ + +static inline unsigned int sn95031_read(struct snd_soc_codec *codec, + unsigned int reg) +{ + u8 value = 0; + int ret; + + ret = intel_scu_ipc_ioread8(reg, &value); + if (ret) + pr_err("read of %x failed, err %d\n", reg, ret); + return value; + +} + +static inline int sn95031_write(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value) +{ + int ret; + + ret = intel_scu_ipc_iowrite8(reg, value); + if (ret) + pr_err("write of %x failed, err %d\n", reg, ret); + return ret; +} + +static int sn95031_set_vaud_bias(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + switch (level) { + case SND_SOC_BIAS_ON: + break; + + case SND_SOC_BIAS_PREPARE: + if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) { + pr_debug("vaud_bias powering up pll\n"); + /* power up the pll */ + snd_soc_write(codec, SN95031_AUDPLLCTRL, BIT(5)); + /* enable pcm 2 */ + snd_soc_update_bits(codec, SN95031_PCM2C2, + BIT(0), BIT(0)); + } + break; + + case SND_SOC_BIAS_STANDBY: + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { + pr_debug("vaud_bias power up rail\n"); + /* power up the rail */ + snd_soc_write(codec, SN95031_VAUD, + BIT(2)|BIT(1)|BIT(0)); + msleep(1); + } else if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE) { + /* turn off pcm */ + pr_debug("vaud_bias power dn pcm\n"); + snd_soc_update_bits(codec, SN95031_PCM2C2, BIT(0), 0); + snd_soc_write(codec, SN95031_AUDPLLCTRL, 0); + } + break; + + + case SND_SOC_BIAS_OFF: + pr_debug("vaud_bias _OFF doing rail shutdown\n"); + snd_soc_write(codec, SN95031_VAUD, BIT(3)); + break; + } + + codec->dapm.bias_level = level; + return 0; +} + +static int sn95031_vhs_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + if (SND_SOC_DAPM_EVENT_ON(event)) { + pr_debug("VHS SND_SOC_DAPM_EVENT_ON doing rail startup now\n"); + /* power up the rail */ + snd_soc_write(w->codec, SN95031_VHSP, 0x3D); + snd_soc_write(w->codec, SN95031_VHSN, 0x3F); + msleep(1); + } else if (SND_SOC_DAPM_EVENT_OFF(event)) { + pr_debug("VHS SND_SOC_DAPM_EVENT_OFF doing rail shutdown\n"); + snd_soc_write(w->codec, SN95031_VHSP, 0xC4); + snd_soc_write(w->codec, SN95031_VHSN, 0x04); + } + return 0; +} + +static int sn95031_vihf_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + if (SND_SOC_DAPM_EVENT_ON(event)) { + pr_debug("VIHF SND_SOC_DAPM_EVENT_ON doing rail startup now\n"); + /* power up the rail */ + snd_soc_write(w->codec, SN95031_VIHF, 0x27); + msleep(1); + } else if (SND_SOC_DAPM_EVENT_OFF(event)) { + pr_debug("VIHF SND_SOC_DAPM_EVENT_OFF doing rail shutdown\n"); + snd_soc_write(w->codec, SN95031_VIHF, 0x24); + } + return 0; +} + +/* DAPM widgets */ +static const struct snd_soc_dapm_widget sn95031_dapm_widgets[] = { + + /* all end points mic, hs etc */ + SND_SOC_DAPM_OUTPUT("HPOUTL"), + SND_SOC_DAPM_OUTPUT("HPOUTR"), + SND_SOC_DAPM_OUTPUT("EPOUT"), + SND_SOC_DAPM_OUTPUT("IHFOUTL"), + SND_SOC_DAPM_OUTPUT("IHFOUTR"), + SND_SOC_DAPM_OUTPUT("LINEOUTL"), + SND_SOC_DAPM_OUTPUT("LINEOUTR"), + SND_SOC_DAPM_OUTPUT("VIB1OUT"), + SND_SOC_DAPM_OUTPUT("VIB2OUT"), + + SND_SOC_DAPM_SUPPLY("Headset Rail", SND_SOC_NOPM, 0, 0, + sn95031_vhs_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY("Speaker Rail", SND_SOC_NOPM, 0, 0, + sn95031_vihf_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + /* playback path driver enables */ + SND_SOC_DAPM_PGA("Headset Left Playback", + SN95031_DRIVEREN, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("Headset Right Playback", + SN95031_DRIVEREN, 1, 0, NULL, 0), + SND_SOC_DAPM_PGA("Speaker Left Playback", + SN95031_DRIVEREN, 2, 0, NULL, 0), + SND_SOC_DAPM_PGA("Speaker Right Playback", + SN95031_DRIVEREN, 3, 0, NULL, 0), + SND_SOC_DAPM_PGA("Vibra1 Playback", + SN95031_DRIVEREN, 4, 0, NULL, 0), + SND_SOC_DAPM_PGA("Vibra2 Playback", + SN95031_DRIVEREN, 5, 0, NULL, 0), + SND_SOC_DAPM_PGA("Earpiece Playback", + SN95031_DRIVEREN, 6, 0, NULL, 0), + SND_SOC_DAPM_PGA("Lineout Left Playback", + SN95031_LOCTL, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("Lineout Right Playback", + SN95031_LOCTL, 4, 0, NULL, 0), + + /* playback path filter enable */ + SND_SOC_DAPM_PGA("Headset Left Filter", + SN95031_HSEPRXCTRL, 4, 0, NULL, 0), + SND_SOC_DAPM_PGA("Headset Right Filter", + SN95031_HSEPRXCTRL, 5, 0, NULL, 0), + SND_SOC_DAPM_PGA("Speaker Left Filter", + SN95031_IHFRXCTRL, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("Speaker Right Filter", + SN95031_IHFRXCTRL, 1, 0, NULL, 0), + + /* DACs */ + SND_SOC_DAPM_DAC("HSDAC Left", "Headset", + SN95031_DACCONFIG, 0, 0), + SND_SOC_DAPM_DAC("HSDAC Right", "Headset", + SN95031_DACCONFIG, 1, 0), + SND_SOC_DAPM_DAC("IHFDAC Left", "Speaker", + SN95031_DACCONFIG, 2, 0), + SND_SOC_DAPM_DAC("IHFDAC Right", "Speaker", + SN95031_DACCONFIG, 3, 0), + SND_SOC_DAPM_DAC("Vibra1 DAC", "Vibra1", + SN95031_VIB1C5, 1, 0), + SND_SOC_DAPM_DAC("Vibra2 DAC", "Vibra2", + SN95031_VIB2C5, 1, 0), +}; + +static const struct snd_soc_dapm_route sn95031_audio_map[] = { + /* headset and earpiece map */ + { "HPOUTL", NULL, "Headset Left Playback" }, + { "HPOUTR", NULL, "Headset Right Playback" }, + { "EPOUT", NULL, "Earpiece Playback" }, + { "Headset Left Playback", NULL, "Headset Left Filter"}, + { "Headset Right Playback", NULL, "Headset Right Filter"}, + { "Earpiece Playback", NULL, "Headset Left Filter"}, + { "Headset Left Filter", NULL, "HSDAC Left"}, + { "Headset Right Filter", NULL, "HSDAC Right"}, + { "HSDAC Left", NULL, "Headset Rail"}, + { "HSDAC Right", NULL, "Headset Rail"}, + + /* speaker map */ + { "IHFOUTL", "NULL", "Speaker Left Playback"}, + { "IHFOUTR", "NULL", "Speaker Right Playback"}, + { "Speaker Left Playback", NULL, "Speaker Left Filter"}, + { "Speaker Right Playback", NULL, "Speaker Right Filter"}, + { "Speaker Left Filter", NULL, "IHFDAC Left"}, + { "Speaker Right Filter", NULL, "IHFDAC Right"}, + { "IHFDAC Left", NULL, "Speaker Rail"}, + { "IHFDAC Right", NULL, "Speaker Rail"}, + + /* vibra map */ + {"VIB1OUT", NULL, "Vibra1 Playback"}, + {"Vibra1 Playback", NULL, "Vibra1 DAC"}, + + {"VIB2OUT", NULL, "Vibra2 Playback"}, + {"Vibra2 Playback", NULL, "Vibra2 DAC"}, + + /* lineout */ + {"LINEOUTL", NULL, "Lineout Left Playback"}, + {"LINEOUTR", NULL, "Lineout Right Playback"}, + {"Lineout Left Playback", NULL, "Headset Left Filter"}, + {"Lineout Left Playback", NULL, "Speaker Left Filter"}, + {"Lineout Left Playback", NULL, "Vibra1 DAC"}, + {"Lineout Right Playback", NULL, "Headset Right Filter"}, + {"Lineout Right Playback", NULL, "Speaker Right Filter"}, + {"Lineout Right Playback", NULL, "Vibra2 DAC"}, +}; + +/* speaker and headset mutes, for audio pops and clicks */ +static int sn95031_pcm_hs_mute(struct snd_soc_dai *dai, int mute) +{ + snd_soc_update_bits(dai->codec, + SN95031_HSLVOLCTRL, BIT(7), (!mute << 7)); + snd_soc_update_bits(dai->codec, + SN95031_HSRVOLCTRL, BIT(7), (!mute << 7)); + return 0; +} + +static int sn95031_pcm_spkr_mute(struct snd_soc_dai *dai, int mute) +{ + snd_soc_update_bits(dai->codec, + SN95031_IHFLVOLCTRL, BIT(7), (!mute << 7)); + snd_soc_update_bits(dai->codec, + SN95031_IHFRVOLCTRL, BIT(7), (!mute << 7)); + return 0; +} + +int sn95031_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) +{ + unsigned int format, rate; + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + format = BIT(4)|BIT(5); + break; + + case SNDRV_PCM_FORMAT_S24_LE: + format = 0; + break; + default: + return -EINVAL; + } + snd_soc_update_bits(dai->codec, SN95031_PCM2C2, + BIT(4)|BIT(5), format); + + switch (params_rate(params)) { + case 48000: + pr_debug("RATE_48000\n"); + rate = 0; + break; + + case 44100: + pr_debug("RATE_44100\n"); + rate = BIT(7); + break; + + default: + pr_err("ERR rate %d\n", params_rate(params)); + return -EINVAL; + } + snd_soc_update_bits(dai->codec, SN95031_PCM1C1, BIT(7), rate); + + return 0; +} + +/* Codec DAI section */ +static struct snd_soc_dai_ops sn95031_headset_dai_ops = { + .digital_mute = sn95031_pcm_hs_mute, + .hw_params = sn95031_pcm_hw_params, +}; + +static struct snd_soc_dai_ops sn95031_speaker_dai_ops = { + .digital_mute = sn95031_pcm_spkr_mute, + .hw_params = sn95031_pcm_hw_params, +}; + +static struct snd_soc_dai_ops sn95031_vib1_dai_ops = { + .hw_params = sn95031_pcm_hw_params, +}; + +static struct snd_soc_dai_ops sn95031_vib2_dai_ops = { + .hw_params = sn95031_pcm_hw_params, +}; + +struct snd_soc_dai_driver sn95031_dais[] = { +{ + .name = "SN95031 Headset", + .playback = { + .stream_name = "Headset", + .channels_min = 2, + .channels_max = 2, + .rates = SN95031_RATES, + .formats = SN95031_FORMATS, + }, + .ops = &sn95031_headset_dai_ops, +}, +{ .name = "SN95031 Speaker", + .playback = { + .stream_name = "Speaker", + .channels_min = 2, + .channels_max = 2, + .rates = SN95031_RATES, + .formats = SN95031_FORMATS, + }, + .ops = &sn95031_speaker_dai_ops, +}, +{ .name = "SN95031 Vibra1", + .playback = { + .stream_name = "Vibra1", + .channels_min = 1, + .channels_max = 1, + .rates = SN95031_RATES, + .formats = SN95031_FORMATS, + }, + .ops = &sn95031_vib1_dai_ops, +}, +{ .name = "SN95031 Vibra2", + .playback = { + .stream_name = "Vibra2", + .channels_min = 1, + .channels_max = 1, + .rates = SN95031_RATES, + .formats = SN95031_FORMATS, + }, + .ops = &sn95031_vib2_dai_ops, +}, +}; + +/* codec registration */ +static int sn95031_codec_probe(struct snd_soc_codec *codec) +{ + int ret; + + pr_debug("codec_probe called\n"); + + codec->dapm.bias_level = SND_SOC_BIAS_OFF; + codec->dapm.idle_bias_off = 1; + + /* PCM interface config + * This sets the pcm rx slot conguration to max 6 slots + * for max 4 dais (2 stereo and 2 mono) + */ + snd_soc_write(codec, SN95031_PCM2RXSLOT01, 0x10); + snd_soc_write(codec, SN95031_PCM2RXSLOT23, 0x32); + snd_soc_write(codec, SN95031_PCM2RXSLOT45, 0x54); + /* pcm port setting + * This sets the pcm port to slave and clock at 19.2Mhz which + * can support 6slots, sampling rate set per stream in hw-params + */ + snd_soc_write(codec, SN95031_PCM1C1, 0x00); + snd_soc_write(codec, SN95031_PCM2C1, 0x01); + snd_soc_write(codec, SN95031_PCM2C2, 0x0A); + snd_soc_write(codec, SN95031_HSMIXER, BIT(0)|BIT(4)); + /* vendor vibra workround, the vibras are muted by + * custom register so unmute them + */ + snd_soc_write(codec, SN95031_SSR5, 0x80); + snd_soc_write(codec, SN95031_SSR6, 0x80); + snd_soc_write(codec, SN95031_VIB1C5, 0x00); + snd_soc_write(codec, SN95031_VIB2C5, 0x00); + /* configure vibras for pcm port */ + snd_soc_write(codec, SN95031_VIB1C3, 0x00); + snd_soc_write(codec, SN95031_VIB2C3, 0x00); + + /* soft mute ramp time */ + snd_soc_write(codec, SN95031_SOFTMUTE, 0x3); + /* fix the initial volume at 1dB, + * default in +9dB, + * 1dB give optimal swing on DAC, amps + */ + snd_soc_write(codec, SN95031_HSLVOLCTRL, 0x08); + snd_soc_write(codec, SN95031_HSRVOLCTRL, 0x08); + snd_soc_write(codec, SN95031_IHFLVOLCTRL, 0x08); + snd_soc_write(codec, SN95031_IHFRVOLCTRL, 0x08); + /* dac mode and lineout workaround */ + snd_soc_write(codec, SN95031_SSR2, 0x10); + snd_soc_write(codec, SN95031_SSR3, 0x40); + + ret = snd_soc_dapm_new_controls(&codec->dapm, sn95031_dapm_widgets, + ARRAY_SIZE(sn95031_dapm_widgets)); + if (ret) + pr_err("soc_dapm_new_control failed %d", ret); + ret = snd_soc_dapm_add_routes(&codec->dapm, sn95031_audio_map, + ARRAY_SIZE(sn95031_audio_map)); + if (ret) + pr_err("soc_dapm_add_routes failed %d", ret); + + return ret; +} + +static int sn95031_codec_remove(struct snd_soc_codec *codec) +{ + pr_debug("codec_remove called\n"); + sn95031_set_vaud_bias(codec, SND_SOC_BIAS_OFF); + + return 0; +} + +struct snd_soc_codec_driver sn95031_codec = { + .probe = sn95031_codec_probe, + .remove = sn95031_codec_remove, + .read = sn95031_read, + .write = sn95031_write, + .set_bias_level = sn95031_set_vaud_bias, +}; + +static int __devinit sn95031_device_probe(struct platform_device *pdev) +{ + pr_debug("codec device probe called for %s\n", dev_name(&pdev->dev)); + return snd_soc_register_codec(&pdev->dev, &sn95031_codec, + sn95031_dais, ARRAY_SIZE(sn95031_dais)); +} + +static int __devexit sn95031_device_remove(struct platform_device *pdev) +{ + pr_debug("codec device remove called\n"); + snd_soc_unregister_codec(&pdev->dev); + return 0; +} + +static struct platform_driver sn95031_codec_driver = { + .driver = { + .name = "sn95031", + .owner = THIS_MODULE, + }, + .probe = sn95031_device_probe, + .remove = sn95031_device_remove, +}; + +static int __init sn95031_init(void) +{ + pr_debug("driver init called\n"); + return platform_driver_register(&sn95031_codec_driver); +} +module_init(sn95031_init); + +static void __exit sn95031_exit(void) +{ + pr_debug("driver exit called\n"); + platform_driver_unregister(&sn95031_codec_driver); +} +module_exit(sn95031_exit); + +MODULE_DESCRIPTION("ASoC Intel(R) SN95031 codec driver"); +MODULE_AUTHOR("Vinod Koul "); +MODULE_AUTHOR("Harsha Priya "); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:sn95031"); diff --git a/sound/soc/codecs/sn95031.h b/sound/soc/codecs/sn95031.h new file mode 100644 index 000000000000..b17a39b2aef5 --- /dev/null +++ b/sound/soc/codecs/sn95031.h @@ -0,0 +1,99 @@ +/* + * sn95031.h - TI sn95031 Codec driver + * + * Copyright (C) 2010 Intel Corp + * Author: Vinod Koul + * Author: Harsha Priya + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * 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; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * + */ +#ifndef _SN95031_H +#define _SN95031_H + +/*register map*/ +#define SN95031_VAUD 0xDB +#define SN95031_VHSP 0xDC +#define SN95031_VHSN 0xDD +#define SN95031_VIHF 0xC9 + +#define SN95031_AUDPLLCTRL 0x240 +#define SN95031_DMICBUF0123 0x241 +#define SN95031_DMICBUF45 0x242 +#define SN95031_DMICGPO 0x244 +#define SN95031_DMICMUX 0x245 +#define SN95031_DMICLK 0x246 +#define SN95031_MICBIAS 0x247 +#define SN95031_ADCCONFIG 0x248 +#define SN95031_MICAMP1 0x249 +#define SN95031_MICAMP2 0x24A +#define SN95031_NOISEMUX 0x24B +#define SN95031_AUDIOMUX12 0x24C +#define SN95031_AUDIOMUX34 0x24D +#define SN95031_AUDIOSINC 0x24E +#define SN95031_AUDIOTXEN 0x24F +#define SN95031_HSEPRXCTRL 0x250 +#define SN95031_IHFRXCTRL 0x251 +#define SN95031_HSMIXER 0x256 +#define SN95031_DACCONFIG 0x257 +#define SN95031_SOFTMUTE 0x258 +#define SN95031_HSLVOLCTRL 0x259 +#define SN95031_HSRVOLCTRL 0x25A +#define SN95031_IHFLVOLCTRL 0x25B +#define SN95031_IHFRVOLCTRL 0x25C +#define SN95031_DRIVEREN 0x25D +#define SN95031_LOCTL 0x25E +#define SN95031_VIB1C1 0x25F +#define SN95031_VIB1C2 0x260 +#define SN95031_VIB1C3 0x261 +#define SN95031_VIB1SPIPCM1 0x262 +#define SN95031_VIB1SPIPCM2 0x263 +#define SN95031_VIB1C5 0x264 +#define SN95031_VIB2C1 0x265 +#define SN95031_VIB2C2 0x266 +#define SN95031_VIB2C3 0x267 +#define SN95031_VIB2SPIPCM1 0x268 +#define SN95031_VIB2SPIPCM2 0x269 +#define SN95031_VIB2C5 0x26A +#define SN95031_BTNCTRL1 0x26B +#define SN95031_BTNCTRL2 0x26C +#define SN95031_PCM1TXSLOT01 0x26D +#define SN95031_PCM1TXSLOT23 0x26E +#define SN95031_PCM1TXSLOT45 0x26F +#define SN95031_PCM1RXSLOT0_3 0x270 +#define SN95031_PCM1RXSLOT45 0x271 +#define SN95031_PCM2TXSLOT01 0x272 +#define SN95031_PCM2TXSLOT23 0x273 +#define SN95031_PCM2TXSLOT45 0x274 +#define SN95031_PCM2RXSLOT01 0x275 +#define SN95031_PCM2RXSLOT23 0x276 +#define SN95031_PCM2RXSLOT45 0x277 +#define SN95031_PCM1C1 0x278 +#define SN95031_PCM1C2 0x279 +#define SN95031_PCM1C3 0x27A +#define SN95031_PCM2C1 0x27B +#define SN95031_PCM2C2 0x27C +/*end codec register defn*/ + +/*vendor defn these are not part of avp*/ +#define SN95031_SSR2 0x381 +#define SN95031_SSR3 0x382 +#define SN95031_SSR5 0x384 +#define SN95031_SSR6 0x385 + +#endif -- cgit v1.2.3 From d927fdae5cb2ca36f0c5b61e528078e8c1261607 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Tue, 4 Jan 2011 20:16:32 +0530 Subject: ASoC: sst v2: Add mid platform driver This patch adds the platform driver for mid asoc drivers. This platfrom driver sends commands to sst dsp engine driver for the dai operations. For this purpose it depends on intel_sst driver which is currently in staging tree Signed-off-by: Vinod Koul Signed-off-by: Harsha Priya Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/mid-x86/sst_platform.c | 484 +++++++++++++++++++++++++++++++++++++++ sound/soc/mid-x86/sst_platform.h | 63 +++++ 2 files changed, 547 insertions(+) create mode 100644 sound/soc/mid-x86/sst_platform.c create mode 100644 sound/soc/mid-x86/sst_platform.h diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c new file mode 100644 index 000000000000..189d546fbf94 --- /dev/null +++ b/sound/soc/mid-x86/sst_platform.c @@ -0,0 +1,484 @@ +/* + * sst_platform.c - Intel MID Platform driver + * + * Copyright (C) 2010 Intel Corp + * Author: Vinod Koul + * Author: Harsha Priya + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * 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; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * + */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include "../../../drivers/staging/intel_sst/intel_sst_ioctl.h" +#include "../../../drivers/staging/intel_sst/intel_sst.h" +#include "sst_platform.h" + +static struct snd_pcm_hardware sst_platform_pcm_hw = { + .info = (SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_DOUBLE | + SNDRV_PCM_INFO_PAUSE | + SNDRV_PCM_INFO_RESUME | + SNDRV_PCM_INFO_MMAP| + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_SYNC_START), + .formats = (SNDRV_PCM_FMTBIT_S16 | SNDRV_PCM_FMTBIT_U16 | + SNDRV_PCM_FMTBIT_S24 | SNDRV_PCM_FMTBIT_U24 | + SNDRV_PCM_FMTBIT_S32 | SNDRV_PCM_FMTBIT_U32), + .rates = (SNDRV_PCM_RATE_8000| + SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000), + .rate_min = SST_MIN_RATE, + .rate_max = SST_MAX_RATE, + .channels_min = SST_MIN_CHANNEL, + .channels_max = SST_MAX_CHANNEL, + .buffer_bytes_max = SST_MAX_BUFFER, + .period_bytes_min = SST_MIN_PERIOD_BYTES, + .period_bytes_max = SST_MAX_PERIOD_BYTES, + .periods_min = SST_MIN_PERIODS, + .periods_max = SST_MAX_PERIODS, + .fifo_size = SST_FIFO_SIZE, +}; + +/* MFLD - MSIC */ +struct snd_soc_dai_driver sst_platform_dai[] = { +{ + .name = "Headset-cpu-dai", + .id = 0, + .playback = { + .channels_min = SST_STEREO, + .channels_max = SST_STEREO, + .rates = SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S24_LE, + }, +}, +{ + .name = "Speaker-cpu-dai", + .id = 1, + .playback = { + .channels_min = SST_MONO, + .channels_max = SST_STEREO, + .rates = SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S24_LE, + }, +}, +{ + .name = "Vibra1-cpu-dai", + .id = 2, + .playback = { + .channels_min = SST_MONO, + .channels_max = SST_MONO, + .rates = SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S24_LE, + }, +}, +{ + .name = "Vibra2-cpu-dai", + .id = 3, + .playback = { + .channels_min = SST_MONO, + .channels_max = SST_STEREO, + .rates = SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S24_LE, + }, +}, +}; +/* helper functions */ +static int sst_platform_alloc_stream(struct snd_pcm_substream *substream) +{ + struct sst_runtime_stream *stream = + substream->runtime->private_data; + struct snd_sst_stream_params param = {{{0,},},}; + struct snd_sst_params str_params = {0}; + int ret_val; + + /* set codec params and inform SST driver the same */ + + param.uc.pcm_params.codec = SST_CODEC_TYPE_PCM; + param.uc.pcm_params.num_chan = (u8) substream->runtime->channels; + param.uc.pcm_params.pcm_wd_sz = substream->runtime->sample_bits; + param.uc.pcm_params.reserved = 0; + param.uc.pcm_params.sfreq = substream->runtime->rate; + param.uc.pcm_params.ring_buffer_size = + snd_pcm_lib_buffer_bytes(substream); + param.uc.pcm_params.period_count = substream->runtime->period_size; + param.uc.pcm_params.ring_buffer_addr = + virt_to_phys(substream->dma_buffer.area); + substream->runtime->dma_area = substream->dma_buffer.area; + + pr_debug("period_cnt = %d\n", param.uc.pcm_params.period_count); + pr_debug("sfreq= %d, wd_sz = %d\n", + param.uc.pcm_params.sfreq, param.uc.pcm_params.pcm_wd_sz); + + str_params.sparams = param; + str_params.codec = SST_CODEC_TYPE_PCM; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + str_params.ops = STREAM_OPS_PLAYBACK; + str_params.device_type = substream->pcm->device + 1; + pr_debug("Playbck stream,Device %d\n", + substream->pcm->device); + } else { + str_params.ops = STREAM_OPS_CAPTURE; + str_params.device_type = SND_SST_DEVICE_CAPTURE; + pr_debug("Capture stream,Device %d\n", + substream->pcm->device); + } + ret_val = stream->sstdrv_ops->control_set(SST_SND_ALLOC, &str_params); + pr_debug("SST_SND_PLAY/CAPTURE ret_val = %x\n", ret_val); + if (ret_val < 0) + return ret_val; + + stream->stream_info.str_id = ret_val; + pr_debug("str id : %d\n", stream->stream_info.str_id); + + return ret_val; +} + + +static void sst_period_elapsed(void *mad_substream) +{ + struct snd_pcm_substream *substream = mad_substream; + struct sst_runtime_stream *stream; + + if (!substream || !substream->runtime) + return; + stream = substream->runtime->private_data; + if (!stream) + return; + + spin_lock(&stream->status_lock); + if (stream->stream_status != SST_PLATFORM_RUNNING) { + spin_unlock(&stream->status_lock); + return; + } + spin_unlock(&stream->status_lock); + snd_pcm_period_elapsed(substream); + return; +} + +static int sst_platform_init_stream(struct snd_pcm_substream *substream) +{ + struct sst_runtime_stream *stream = + substream->runtime->private_data; + int ret_val; + + pr_debug("setting buffer ptr param\n"); + spin_lock(&stream->status_lock); + stream->stream_status = SST_PLATFORM_INIT; + spin_unlock(&stream->status_lock); + stream->stream_info.period_elapsed = sst_period_elapsed; + stream->stream_info.mad_substream = substream; + stream->stream_info.buffer_ptr = 0; + stream->stream_info.sfreq = substream->runtime->rate; + ret_val = stream->sstdrv_ops->control_set(SST_SND_STREAM_INIT, + &stream->stream_info); + if (ret_val) + pr_err("control_set ret error %d\n", ret_val); + return ret_val; + +} +/* end -- helper functions */ + +static int sst_platform_open(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime; + struct sst_runtime_stream *stream; + int ret_val = 0; + + pr_debug("sst_platform_open called\n"); + + runtime = substream->runtime; + runtime->hw = sst_platform_pcm_hw; + + stream = kzalloc(sizeof(*stream), GFP_KERNEL); + if (!stream) + return -ENOMEM; + + spin_lock_init(&stream->status_lock); + stream->stream_info.str_id = 0; + + spin_lock(&stream->status_lock); + stream->stream_status = SST_PLATFORM_INIT; + spin_unlock(&stream->status_lock); + + stream->stream_info.mad_substream = substream; + /* allocate memory for SST API set */ + stream->sstdrv_ops = kzalloc(sizeof(*stream->sstdrv_ops), + GFP_KERNEL); + if (!stream->sstdrv_ops) { + pr_err("sst: mem allocation for ops fail\n"); + kfree(stream); + return -ENOMEM; + } + stream->sstdrv_ops->vendor_id = MSIC_VENDOR_ID; + + /* registering with SST driver to get access to SST APIs to use */ + ret_val = register_sst_card(stream->sstdrv_ops); + if (ret_val) { + pr_err("sst: sst card registration failed\n"); + return ret_val; + } + runtime->private_data = stream; + return snd_pcm_hw_constraint_integer(runtime, + SNDRV_PCM_HW_PARAM_PERIODS); +} + +static int sst_platform_close(struct snd_pcm_substream *substream) +{ + struct sst_runtime_stream *stream; + int ret_val = 0, str_id; + + pr_debug("sst_platform_close called\n"); + + stream = substream->runtime->private_data; + str_id = stream->stream_info.str_id; + + if (str_id) + ret_val = stream->sstdrv_ops->control_set( + SST_SND_FREE, &str_id); + + kfree(stream->sstdrv_ops); + kfree(stream); + return ret_val; +} + +static int sst_platform_pcm_prepare(struct snd_pcm_substream *substream) +{ + struct sst_runtime_stream *stream; + int ret_val = 0, str_id; + + pr_debug("sst_platform_pcm_prepare called\n"); + + stream = substream->runtime->private_data; + str_id = stream->stream_info.str_id; + if (stream->stream_info.str_id) { + ret_val = stream->sstdrv_ops->control_set( + SST_SND_DROP, &str_id); + return ret_val; + } + + ret_val = sst_platform_alloc_stream(substream); + if (ret_val < 0) + return ret_val; + snprintf(substream->pcm->id, sizeof(substream->pcm->id), + "%d", stream->stream_info.str_id); + + ret_val = sst_platform_init_stream(substream); + if (ret_val) + return ret_val; + substream->runtime->hw.info = SNDRV_PCM_INFO_BLOCK_TRANSFER; + return ret_val; +} + +static int sst_platform_pcm_trigger(struct snd_pcm_substream *substream, + int cmd) +{ + int ret_val = 0, str_id; + struct sst_runtime_stream *stream; + + pr_debug("sst_platform_pcm_trigger called\n"); + + stream = substream->runtime->private_data; + + str_id = stream->stream_info.str_id; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + pr_debug("sst: Trigger Start\n"); + ret_val = stream->sstdrv_ops->control_set( + SST_SND_START, &str_id); + if (ret_val) + break; + spin_lock(&stream->status_lock); + stream->stream_status = SST_PLATFORM_RUNNING; + spin_unlock(&stream->status_lock); + stream->stream_info.mad_substream = substream; + break; + case SNDRV_PCM_TRIGGER_STOP: + pr_debug("sst: in stop\n"); + ret_val = stream->sstdrv_ops->control_set( + SST_SND_DROP, &str_id); + if (ret_val) + break; + spin_lock(&stream->status_lock); + stream->stream_status = SST_PLATFORM_DROPPED; + spin_unlock(&stream->status_lock); + break; + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + pr_debug("sst: in pause\n"); + ret_val = stream->sstdrv_ops->control_set( + SST_SND_PAUSE, &str_id); + if (ret_val) + break; + spin_lock(&stream->status_lock); + stream->stream_status = SST_PLATFORM_PAUSED; + spin_unlock(&stream->status_lock); + break; + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + pr_debug("sst: in pause release\n"); + ret_val = stream->sstdrv_ops->control_set( + SST_SND_RESUME, &str_id); + if (ret_val) + break; + spin_lock(&stream->status_lock); + stream->stream_status = SST_PLATFORM_RUNNING; + spin_unlock(&stream->status_lock); + break; + default: + ret_val = -EINVAL; + } + return ret_val; +} + + +static snd_pcm_uframes_t sst_platform_pcm_pointer + (struct snd_pcm_substream *substream) +{ + struct sst_runtime_stream *stream; + int ret_val; + struct pcm_stream_info *str_info; + + + stream = substream->runtime->private_data; + spin_lock(&stream->status_lock); + if (stream->stream_status == SST_PLATFORM_INIT) { + spin_unlock(&stream->status_lock); + return 0; + } + spin_unlock(&stream->status_lock); + + str_info = &stream->stream_info; + ret_val = stream->sstdrv_ops->control_set( + SST_SND_BUFFER_POINTER, str_info); + if (ret_val) { + pr_err("sst: error code = %d\n", ret_val); + return ret_val; + } + + return stream->stream_info.buffer_ptr; +} + + +static struct snd_pcm_ops sst_platform_ops = { + .open = sst_platform_open, + .close = sst_platform_close, + .ioctl = snd_pcm_lib_ioctl, + .prepare = sst_platform_pcm_prepare, + .trigger = sst_platform_pcm_trigger, + .pointer = sst_platform_pcm_pointer, +}; + +static void sst_pcm_free(struct snd_pcm *pcm) +{ + pr_debug("sst_pcm_free called\n"); + snd_pcm_lib_preallocate_free_for_all(pcm); +} + +int sst_pcm_new(struct snd_card *card, struct snd_soc_dai *dai, + struct snd_pcm *pcm) +{ + int retval = 0; + + pr_debug("sst_pcm_new called\n"); + + if (dai->driver->playback.channels_min || + dai->driver->capture.channels_min) { + retval = snd_pcm_lib_preallocate_pages_for_all(pcm, + SNDRV_DMA_TYPE_CONTINUOUS, + snd_dma_continuous_data(GFP_KERNEL), + SST_MIN_BUFFER, SST_MAX_BUFFER); + if (retval) { + pr_err("dma buffer allocationf fail\n"); + return retval; + } + } + + return retval; +} +struct snd_soc_platform_driver sst_soc_platform_drv = { + .ops = &sst_platform_ops, + .pcm_new = sst_pcm_new, + .pcm_free = sst_pcm_free, +}; + +static int sst_platform_probe(struct platform_device *pdev) +{ + int ret; + + pr_debug("sst_platform_probe called\n"); + ret = snd_soc_register_platform(&pdev->dev, &sst_soc_platform_drv); + if (ret) { + pr_err("registering soc platform failed\n"); + return ret; + } + ret = snd_soc_register_dais(&pdev->dev, + sst_platform_dai, ARRAY_SIZE(sst_platform_dai)); + if (ret) { + pr_err("registering cpu dais failed\n"); + snd_soc_unregister_platform(&pdev->dev); + } + return ret; +} + +static int sst_platform_remove(struct platform_device *pdev) +{ + + snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(sst_platform_dai)); + + snd_soc_unregister_platform(&pdev->dev); + pr_debug("sst_platform_remove sucess\n"); + + return 0; +} + +static struct platform_driver sst_platform_driver = { + .driver = { + .name = "sst-platform", + .owner = THIS_MODULE, + }, + .probe = sst_platform_probe, + .remove = sst_platform_remove, +}; + +static int __init sst_soc_platform_init(void) +{ + pr_debug("sst_soc_platform_init called\n"); + return platform_driver_register(&sst_platform_driver); +} +module_init(sst_soc_platform_init); + +static void __exit sst_soc_platform_exit(void) +{ + platform_driver_unregister(&sst_platform_driver); + pr_debug("sst_soc_platform_exit sucess\n"); +} +module_exit(sst_soc_platform_exit); + +MODULE_DESCRIPTION("ASoC Intel(R) MID Platform driver"); +MODULE_AUTHOR("Vinod Koul "); +MODULE_AUTHOR("Harsha Priya "); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platfrom: sst-platform"); diff --git a/sound/soc/mid-x86/sst_platform.h b/sound/soc/mid-x86/sst_platform.h new file mode 100644 index 000000000000..df370286694f --- /dev/null +++ b/sound/soc/mid-x86/sst_platform.h @@ -0,0 +1,63 @@ +/* + * sst_platform.h - Intel MID Platform driver header file + * + * Copyright (C) 2010 Intel Corp + * Author: Vinod Koul + * Author: Harsha Priya + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * 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; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * + */ + +#ifndef __SST_PLATFORMDRV_H__ +#define __SST_PLATFORMDRV_H__ + +#define SST_MONO 1 +#define SST_STEREO 2 +#define SST_MAX_CAP 5 + +#define SST_MIN_RATE 8000 +#define SST_MAX_RATE 48000 +#define SST_MIN_CHANNEL 1 +#define SST_MAX_CHANNEL 5 +#define SST_MAX_BUFFER (800*1024) +#define SST_MIN_BUFFER (800*1024) +#define SST_MIN_PERIOD_BYTES 32 +#define SST_MAX_PERIOD_BYTES SST_MAX_BUFFER +#define SST_MIN_PERIODS 2 +#define SST_MAX_PERIODS (1024*2) +#define SST_FIFO_SIZE 0 +#define SST_CARD_NAMES "intel_mid_card" +#define MSIC_VENDOR_ID 3 + +struct sst_runtime_stream { + int stream_status; + struct pcm_stream_info stream_info; + struct intel_sst_card_ops *sstdrv_ops; + spinlock_t status_lock; +}; + +enum sst_drv_status { + SST_PLATFORM_INIT = 1, + SST_PLATFORM_STARTED, + SST_PLATFORM_RUNNING, + SST_PLATFORM_PAUSED, + SST_PLATFORM_DROPPED, +}; + +#endif -- cgit v1.2.3 From 55c720369dbe1dd558b87478e3448df837fbe7a3 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Tue, 4 Jan 2011 20:16:50 +0530 Subject: ASoC sst v2: Add medfield machine driver This patch adds the medfield machine driver Machine driver glues the sn95031 codec driver and sst_platform driver to form the asoc sound driver Signed-off-by: Vinod Koul Signed-off-by: Harsha Priya Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/mid-x86/mfld_machine.c | 296 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 296 insertions(+) create mode 100644 sound/soc/mid-x86/mfld_machine.c diff --git a/sound/soc/mid-x86/mfld_machine.c b/sound/soc/mid-x86/mfld_machine.c new file mode 100644 index 000000000000..1a330be1a01e --- /dev/null +++ b/sound/soc/mid-x86/mfld_machine.c @@ -0,0 +1,296 @@ +/* + * mfld_machine.c - ASoc Machine driver for Intel Medfield MID platform + * + * Copyright (C) 2010 Intel Corp + * Author: Vinod Koul + * Author: Harsha Priya + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * 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; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include "../codecs/sn95031.h" + +#define MID_MONO 1 +#define MID_STEREO 2 +#define MID_MAX_CAP 5 + +static unsigned int hs_switch; +static unsigned int lo_dac; + +/* sound card controls */ +static const char *headset_switch_text[] = {"Earpiece", "Headset"}; + +static const char *lo_text[] = {"Vibra", "Headset", "IHF", "None"}; + +static const struct soc_enum headset_enum = + SOC_ENUM_SINGLE_EXT(2, headset_switch_text); + +static const struct soc_enum lo_enum = + SOC_ENUM_SINGLE_EXT(4, lo_text); + +static int headset_get_switch(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = hs_switch; + return 0; +} + +static int headset_set_switch(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + + if (ucontrol->value.integer.value[0] == hs_switch) + return 0; + + if (ucontrol->value.integer.value[0]) { + pr_debug("hs_set HS path\n"); + snd_soc_dapm_enable_pin(&codec->dapm, "HPOUTL"); + snd_soc_dapm_enable_pin(&codec->dapm, "HPOUTR"); + snd_soc_dapm_disable_pin(&codec->dapm, "EPOUT"); + } else { + pr_debug("hs_set EP path\n"); + snd_soc_dapm_disable_pin(&codec->dapm, "HPOUTL"); + snd_soc_dapm_disable_pin(&codec->dapm, "HPOUTR"); + snd_soc_dapm_enable_pin(&codec->dapm, "EPOUT"); + } + snd_soc_dapm_sync(&codec->dapm); + hs_switch = ucontrol->value.integer.value[0]; + + return 0; +} + +static void lo_enable_out_pins(struct snd_soc_codec *codec) +{ + snd_soc_dapm_enable_pin(&codec->dapm, "IHFOUTL"); + snd_soc_dapm_enable_pin(&codec->dapm, "IHFOUTR"); + snd_soc_dapm_enable_pin(&codec->dapm, "LINEOUTL"); + snd_soc_dapm_enable_pin(&codec->dapm, "LINEOUTR"); + snd_soc_dapm_enable_pin(&codec->dapm, "VIB1OUT"); + snd_soc_dapm_enable_pin(&codec->dapm, "VIB2OUT"); + if (hs_switch) { + snd_soc_dapm_enable_pin(&codec->dapm, "HPOUTL"); + snd_soc_dapm_enable_pin(&codec->dapm, "HPOUTR"); + snd_soc_dapm_disable_pin(&codec->dapm, "EPOUT"); + } else { + snd_soc_dapm_disable_pin(&codec->dapm, "HPOUTL"); + snd_soc_dapm_disable_pin(&codec->dapm, "HPOUTR"); + snd_soc_dapm_enable_pin(&codec->dapm, "EPOUT"); + } +} + +static int lo_get_switch(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = lo_dac; + return 0; +} + +static int lo_set_switch(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + + if (ucontrol->value.integer.value[0] == lo_dac) + return 0; + + /* we dont want to work with last state of lineout so just enable all + * pins and then disable pins not required + */ + lo_enable_out_pins(codec); + switch (ucontrol->value.integer.value[0]) { + case 0: + pr_debug("set vibra path\n"); + snd_soc_dapm_disable_pin(&codec->dapm, "VIB1OUT"); + snd_soc_dapm_disable_pin(&codec->dapm, "VIB2OUT"); + snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0); + break; + + case 1: + pr_debug("set hs path\n"); + snd_soc_dapm_disable_pin(&codec->dapm, "HPOUTL"); + snd_soc_dapm_disable_pin(&codec->dapm, "HPOUTR"); + snd_soc_dapm_disable_pin(&codec->dapm, "EPOUT"); + snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x22); + break; + + case 2: + pr_debug("set spkr path\n"); + snd_soc_dapm_disable_pin(&codec->dapm, "IHFOUTL"); + snd_soc_dapm_disable_pin(&codec->dapm, "IHFOUTR"); + snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x44); + break; + + case 3: + pr_debug("set null path\n"); + snd_soc_dapm_disable_pin(&codec->dapm, "LINEOUTL"); + snd_soc_dapm_disable_pin(&codec->dapm, "LINEOUTR"); + snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x66); + break; + } + snd_soc_dapm_sync(&codec->dapm); + lo_dac = ucontrol->value.integer.value[0]; + return 0; +} + +static const struct snd_kcontrol_new mfld_snd_controls[] = { + SOC_ENUM_EXT("Playback Switch", headset_enum, + headset_get_switch, headset_set_switch), + SOC_ENUM_EXT("Lineout Mux", lo_enum, + lo_get_switch, lo_set_switch), +}; + +static int mfld_init(struct snd_soc_pcm_runtime *runtime) +{ + struct snd_soc_codec *codec = runtime->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; + int ret_val; + + ret_val = snd_soc_add_controls(codec, mfld_snd_controls, + ARRAY_SIZE(mfld_snd_controls)); + if (ret_val) { + pr_err("soc_add_controls failed %d", ret_val); + return ret_val; + } + /* default is earpiece pin, userspace sets it explcitly */ + snd_soc_dapm_disable_pin(dapm, "HPOUTL"); + snd_soc_dapm_disable_pin(dapm, "HPOUTR"); + /* default is lineout NC, userspace sets it explcitly */ + snd_soc_dapm_disable_pin(dapm, "LINEOUTL"); + snd_soc_dapm_disable_pin(dapm, "LINEOUTR"); + lo_dac = 3; + hs_switch = 0; + return snd_soc_dapm_sync(dapm); +} + +struct snd_soc_dai_link mfld_msic_dailink[] = { + { + .name = "Medfield Headset", + .stream_name = "Headset", + .cpu_dai_name = "Headset-cpu-dai", + .codec_dai_name = "SN95031 Headset", + .codec_name = "sn95031", + .platform_name = "sst-platform", + .init = mfld_init, + }, + { + .name = "Medfield Speaker", + .stream_name = "Speaker", + .cpu_dai_name = "Speaker-cpu-dai", + .codec_dai_name = "SN95031 Speaker", + .codec_name = "sn95031", + .platform_name = "sst-platform", + .init = NULL, + }, + { + .name = "Medfield Vibra", + .stream_name = "Vibra1", + .cpu_dai_name = "Vibra1-cpu-dai", + .codec_dai_name = "SN95031 Vibra1", + .codec_name = "sn95031", + .platform_name = "sst-platform", + .init = NULL, + }, + { + .name = "Medfield Haptics", + .stream_name = "Vibra2", + .cpu_dai_name = "Vibra2-cpu-dai", + .codec_dai_name = "SN95031 Vibra2", + .codec_name = "sn95031", + .platform_name = "sst-platform", + .init = NULL, + }, +}; + +/* SoC card */ +static struct snd_soc_card snd_soc_card_mfld = { + .name = "medfield_audio", + .dai_link = mfld_msic_dailink, + .num_links = ARRAY_SIZE(mfld_msic_dailink), +}; + +static int __devinit snd_mfld_mc_probe(struct platform_device *pdev) +{ + struct platform_device *socdev; + int ret_val = 0; + + pr_debug("snd_mfld_mc_probe called\n"); + + socdev = platform_device_alloc("soc-audio", -1); + if (!socdev) { + pr_err("soc-audio device allocation failed\n"); + return -ENOMEM; + } + platform_set_drvdata(socdev, &snd_soc_card_mfld); + ret_val = platform_device_add(socdev); + if (ret_val) { + pr_err("Unable to add soc-audio device, err %d\n", ret_val); + platform_device_put(socdev); + } + + platform_set_drvdata(pdev, socdev); + + pr_debug("successfully exited probe\n"); + return ret_val; +} + +static int __devexit snd_mfld_mc_remove(struct platform_device *pdev) +{ + struct platform_device *socdev = platform_get_drvdata(pdev); + pr_debug("snd_mfld_mc_remove called\n"); + + platform_device_unregister(socdev); + platform_set_drvdata(pdev, NULL); + return 0; +} + +static struct platform_driver snd_mfld_mc_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "msic_audio", + }, + .probe = snd_mfld_mc_probe, + .remove = __devexit_p(snd_mfld_mc_remove), +}; + +static int __init snd_mfld_driver_init(void) +{ + pr_debug("snd_mfld_driver_init called\n"); + return platform_driver_register(&snd_mfld_mc_driver); +} +module_init(snd_mfld_driver_init); + +static void __exit snd_mfld_driver_exit(void) +{ + pr_debug("snd_mfld_driver_exit called\n"); + platform_driver_unregister(&snd_mfld_mc_driver); +} +module_exit(snd_mfld_driver_exit); + +MODULE_DESCRIPTION("ASoC Intel(R) MID Machine driver"); +MODULE_AUTHOR("Vinod Koul "); +MODULE_AUTHOR("Harsha Priya "); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:msic-audio"); -- cgit v1.2.3 From e62255f2adf2e6407d9ac72f5d5ec17712a4fc1d Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Tue, 4 Jan 2011 20:17:04 +0530 Subject: ASoC: sst v2: Add makefiles and kconfigs changes This patch adds the makefile and kconfig changes for mid asoc drivers: platform and machine driver which are introduced in 2 preceeding patches Signed-off-by: Vinod Koul Signed-off-by: Harsha Priya Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/Kconfig | 1 + sound/soc/Makefile | 1 + sound/soc/mid-x86/Kconfig | 13 +++++++++++++ sound/soc/mid-x86/Makefile | 7 +++++++ 4 files changed, 22 insertions(+) create mode 100644 sound/soc/mid-x86/Kconfig create mode 100644 sound/soc/mid-x86/Makefile diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index a3efc52a34da..821ab0b759bb 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig @@ -50,6 +50,7 @@ source "sound/soc/jz4740/Kconfig" source "sound/soc/nuc900/Kconfig" source "sound/soc/omap/Kconfig" source "sound/soc/kirkwood/Kconfig" +source "sound/soc/mid-x86/Kconfig" source "sound/soc/pxa/Kconfig" source "sound/soc/samsung/Kconfig" source "sound/soc/s6000/Kconfig" diff --git a/sound/soc/Makefile b/sound/soc/Makefile index ce913bf5213c..df83d2143afb 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_SND_SOC) += ep93xx/ obj-$(CONFIG_SND_SOC) += fsl/ obj-$(CONFIG_SND_SOC) += imx/ obj-$(CONFIG_SND_SOC) += jz4740/ +obj-$(CONFIG_SND_SOC) += mid-x86/ obj-$(CONFIG_SND_SOC) += nuc900/ obj-$(CONFIG_SND_SOC) += omap/ obj-$(CONFIG_SND_SOC) += kirkwood/ diff --git a/sound/soc/mid-x86/Kconfig b/sound/soc/mid-x86/Kconfig new file mode 100644 index 000000000000..e0123a408227 --- /dev/null +++ b/sound/soc/mid-x86/Kconfig @@ -0,0 +1,13 @@ +config SND_MFLD_MACHINE + tristate "SOC Machine Audio driver for Intel Medfield MID platform" + select SND_SOC_SN95031 + select SND_SST_PLATFORM + help + This adds support for ASoC machine driver for Intel(R) MID Medfield platform + used as alsa device in audio substem in Intel(R) MID devices + Say Y if you have such a device + If unsure select "N". + +config SND_SST_PLATFORM + tristate + depends on SND_INTEL_SST diff --git a/sound/soc/mid-x86/Makefile b/sound/soc/mid-x86/Makefile new file mode 100644 index 000000000000..a1a93314b842 --- /dev/null +++ b/sound/soc/mid-x86/Makefile @@ -0,0 +1,7 @@ +EXTRA_CFLAGS += -DDEBUG + +snd-soc-sst-platform-objs := sst_platform.o +snd-soc-mfld-machine-objs := mfld_machine.o + +obj-$(CONFIG_SND_SST_PLATFORM) += snd-soc-sst-platform.o +obj-$(CONFIG_SND_MFLD_MACHINE) += snd-soc-mfld-machine.o -- cgit v1.2.3 From b22dab8883250d5fd91c8c4a7bd00c5985ac82ad Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Fri, 7 Jan 2011 16:20:28 +0530 Subject: ASoC: sn95031 fix the code style and format inconsistencies this patch fixes inconsistencies commented by Mark. This also fixes few other style things in audio_map & header file Signed-off-by: Vinod Koul Signed-off-by: Harsha Priya Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/sn95031.c | 30 +++++++++++++++--------------- sound/soc/codecs/sn95031.h | 12 ++++++------ 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c index 146b74467ae7..593632cf791d 100644 --- a/sound/soc/codecs/sn95031.c +++ b/sound/soc/codecs/sn95031.c @@ -235,21 +235,21 @@ static const struct snd_soc_dapm_route sn95031_audio_map[] = { { "IHFDAC Right", NULL, "Speaker Rail"}, /* vibra map */ - {"VIB1OUT", NULL, "Vibra1 Playback"}, - {"Vibra1 Playback", NULL, "Vibra1 DAC"}, + { "VIB1OUT", NULL, "Vibra1 Playback"}, + { "Vibra1 Playback", NULL, "Vibra1 DAC"}, - {"VIB2OUT", NULL, "Vibra2 Playback"}, - {"Vibra2 Playback", NULL, "Vibra2 DAC"}, + { "VIB2OUT", NULL, "Vibra2 Playback"}, + { "Vibra2 Playback", NULL, "Vibra2 DAC"}, /* lineout */ - {"LINEOUTL", NULL, "Lineout Left Playback"}, - {"LINEOUTR", NULL, "Lineout Right Playback"}, - {"Lineout Left Playback", NULL, "Headset Left Filter"}, - {"Lineout Left Playback", NULL, "Speaker Left Filter"}, - {"Lineout Left Playback", NULL, "Vibra1 DAC"}, - {"Lineout Right Playback", NULL, "Headset Right Filter"}, - {"Lineout Right Playback", NULL, "Speaker Right Filter"}, - {"Lineout Right Playback", NULL, "Vibra2 DAC"}, + { "LINEOUTL", NULL, "Lineout Left Playback"}, + { "LINEOUTR", NULL, "Lineout Right Playback"}, + { "Lineout Left Playback", NULL, "Headset Left Filter"}, + { "Lineout Left Playback", NULL, "Speaker Left Filter"}, + { "Lineout Left Playback", NULL, "Vibra1 DAC"}, + { "Lineout Right Playback", NULL, "Headset Right Filter"}, + { "Lineout Right Playback", NULL, "Speaker Right Filter"}, + { "Lineout Right Playback", NULL, "Vibra2 DAC"}, }; /* speaker and headset mutes, for audio pops and clicks */ @@ -444,8 +444,8 @@ static int sn95031_codec_remove(struct snd_soc_codec *codec) } struct snd_soc_codec_driver sn95031_codec = { - .probe = sn95031_codec_probe, - .remove = sn95031_codec_remove, + .probe = sn95031_codec_probe, + .remove = sn95031_codec_remove, .read = sn95031_read, .write = sn95031_write, .set_bias_level = sn95031_set_vaud_bias, @@ -488,7 +488,7 @@ static void __exit sn95031_exit(void) } module_exit(sn95031_exit); -MODULE_DESCRIPTION("ASoC Intel(R) SN95031 codec driver"); +MODULE_DESCRIPTION("ASoC TI SN95031 codec driver"); MODULE_AUTHOR("Vinod Koul "); MODULE_AUTHOR("Harsha Priya "); MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/sn95031.h b/sound/soc/codecs/sn95031.h index b17a39b2aef5..e2b17d908aeb 100644 --- a/sound/soc/codecs/sn95031.h +++ b/sound/soc/codecs/sn95031.h @@ -35,13 +35,13 @@ #define SN95031_AUDPLLCTRL 0x240 #define SN95031_DMICBUF0123 0x241 #define SN95031_DMICBUF45 0x242 -#define SN95031_DMICGPO 0x244 -#define SN95031_DMICMUX 0x245 +#define SN95031_DMICGPO 0x244 +#define SN95031_DMICMUX 0x245 #define SN95031_DMICLK 0x246 -#define SN95031_MICBIAS 0x247 +#define SN95031_MICBIAS 0x247 #define SN95031_ADCCONFIG 0x248 -#define SN95031_MICAMP1 0x249 -#define SN95031_MICAMP2 0x24A +#define SN95031_MICAMP1 0x249 +#define SN95031_MICAMP2 0x24A #define SN95031_NOISEMUX 0x24B #define SN95031_AUDIOMUX12 0x24C #define SN95031_AUDIOMUX34 0x24D @@ -49,7 +49,7 @@ #define SN95031_AUDIOTXEN 0x24F #define SN95031_HSEPRXCTRL 0x250 #define SN95031_IHFRXCTRL 0x251 -#define SN95031_HSMIXER 0x256 +#define SN95031_HSMIXER 0x256 #define SN95031_DACCONFIG 0x257 #define SN95031_SOFTMUTE 0x258 #define SN95031_HSLVOLCTRL 0x259 -- cgit v1.2.3 From f5c6b2aa33cdacb4902c7b946395f7e73b00d4ce Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Fri, 7 Jan 2011 16:20:56 +0530 Subject: ASoC: sst platform - fix the style inconsistency this patch fixes the style inconsistency by removing empty space in MODULE_ALIAS also removes a redundant return statement Signed-off-by: Vinod Koul Signed-off-by: Harsha Priya Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/mid-x86/sst_platform.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c index 189d546fbf94..0e994c16e7ab 100644 --- a/sound/soc/mid-x86/sst_platform.c +++ b/sound/soc/mid-x86/sst_platform.c @@ -176,7 +176,6 @@ static void sst_period_elapsed(void *mad_substream) } spin_unlock(&stream->status_lock); snd_pcm_period_elapsed(substream); - return; } static int sst_platform_init_stream(struct snd_pcm_substream *substream) @@ -481,4 +480,4 @@ MODULE_DESCRIPTION("ASoC Intel(R) MID Platform driver"); MODULE_AUTHOR("Vinod Koul "); MODULE_AUTHOR("Harsha Priya "); MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platfrom: sst-platform"); +MODULE_ALIAS("platform:sst-platform"); -- cgit v1.2.3 From fd0d08d9edc8ffc900896e1d1f7f287e6fde1ab3 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Fri, 7 Jan 2011 16:21:12 +0530 Subject: ASoC: mid-x86 - remove the flag in makefile previous commit e62255f2adf2 introduced DDEBUG flag in Makefile This causes all debug statemenets to be ON. This patch removes this flag Signed-off-by: Vinod Koul Signed-off-by: Harsha Priya Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/mid-x86/Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/soc/mid-x86/Makefile b/sound/soc/mid-x86/Makefile index a1a93314b842..639883339465 100644 --- a/sound/soc/mid-x86/Makefile +++ b/sound/soc/mid-x86/Makefile @@ -1,5 +1,3 @@ -EXTRA_CFLAGS += -DDEBUG - snd-soc-sst-platform-objs := sst_platform.o snd-soc-mfld-machine-objs := mfld_machine.o -- cgit v1.2.3 From 4f644ea70d54bf851fc0ebc77fa0f66fce7cb7d2 Mon Sep 17 00:00:00 2001 From: Seungwhan Youn Date: Fri, 7 Jan 2011 13:46:52 +0900 Subject: ASoC: SAMSUNG: Remove AC97 header file This patch moves AC97 specific definitions, they doesn't need to be shared, into 'ac97.c' from 'ac97.h'. This patch also remove header file, 'ac97.h', and remove includes on machine drivers. Signed-off-by: Seungwhan Youn Acked-by: Jassi Brar Signed-off-by: Mark Brown --- sound/soc/samsung/ac97.c | 4 +++- sound/soc/samsung/ac97.h | 21 --------------------- sound/soc/samsung/ln2440sbc_alc650.c | 1 - sound/soc/samsung/smdk2443_wm9710.c | 1 - sound/soc/samsung/smdk_wm9713.c | 1 - 5 files changed, 3 insertions(+), 25 deletions(-) delete mode 100644 sound/soc/samsung/ac97.h diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c index 4770a9550341..1e84ee01eaca 100644 --- a/sound/soc/samsung/ac97.c +++ b/sound/soc/samsung/ac97.c @@ -25,11 +25,13 @@ #include #include "dma.h" -#include "ac97.h" #define AC_CMD_ADDR(x) (x << 16) #define AC_CMD_DATA(x) (x & 0xffff) +#define S3C_AC97_DAI_PCM 0 +#define S3C_AC97_DAI_MIC 1 + struct s3c_ac97_info { struct clk *ac97_clk; void __iomem *regs; diff --git a/sound/soc/samsung/ac97.h b/sound/soc/samsung/ac97.h deleted file mode 100644 index 0d0e1b511457..000000000000 --- a/sound/soc/samsung/ac97.h +++ /dev/null @@ -1,21 +0,0 @@ -/* sound/soc/samsung/ac97.h - * - * ALSA SoC Audio Layer - S3C AC97 Controller driver - * Evolved from s3c2443-ac97.h - * - * Copyright (c) 2010 Samsung Electronics Co. Ltd - * Author: Jaswinder Singh - * Credits: Graeme Gregory, Sean Choi - * - * 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. - */ - -#ifndef __S3C_AC97_H_ -#define __S3C_AC97_H_ - -#define S3C_AC97_DAI_PCM 0 -#define S3C_AC97_DAI_MIC 1 - -#endif /* __S3C_AC97_H_ */ diff --git a/sound/soc/samsung/ln2440sbc_alc650.c b/sound/soc/samsung/ln2440sbc_alc650.c index a2bb34def740..02414290169b 100644 --- a/sound/soc/samsung/ln2440sbc_alc650.c +++ b/sound/soc/samsung/ln2440sbc_alc650.c @@ -23,7 +23,6 @@ #include #include "dma.h" -#include "ac97.h" static struct snd_soc_card ln2440sbc; diff --git a/sound/soc/samsung/smdk2443_wm9710.c b/sound/soc/samsung/smdk2443_wm9710.c index 3be7e7e92d6e..4bd8c0b63966 100644 --- a/sound/soc/samsung/smdk2443_wm9710.c +++ b/sound/soc/samsung/smdk2443_wm9710.c @@ -19,7 +19,6 @@ #include #include "dma.h" -#include "ac97.h" static struct snd_soc_card smdk2443; diff --git a/sound/soc/samsung/smdk_wm9713.c b/sound/soc/samsung/smdk_wm9713.c index ae5fed6f772f..d58d86e7e19d 100644 --- a/sound/soc/samsung/smdk_wm9713.c +++ b/sound/soc/samsung/smdk_wm9713.c @@ -16,7 +16,6 @@ #include #include "dma.h" -#include "ac97.h" static struct snd_soc_card smdk; -- cgit v1.2.3 From f7f741810f14f971337b15892007622c3af1f109 Mon Sep 17 00:00:00 2001 From: Seungwhan Youn Date: Fri, 7 Jan 2011 13:51:26 +0900 Subject: ASoC: SAMSUNG: Clean-up DMA header file This patch moves DMA specific definitions, they doesn't need to be shared, into 'dma.c' from 'dma.h'. And remove unnecessery definitions on 'dma.h'. Signed-off-by: Seungwhan Youn Acked-by: Jassi Brar Signed-off-by: Mark Brown --- sound/soc/samsung/dma.c | 3 +++ sound/soc/samsung/dma.h | 8 -------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c index 21240198c5d6..c2cdb4597e56 100644 --- a/sound/soc/samsung/dma.c +++ b/sound/soc/samsung/dma.c @@ -32,6 +32,9 @@ #include "dma.h" +#define ST_RUNNING (1<<0) +#define ST_OPENED (1<<1) + static const struct snd_pcm_hardware dma_hardware = { .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | diff --git a/sound/soc/samsung/dma.h b/sound/soc/samsung/dma.h index f8cd2b4223af..c50659269a40 100644 --- a/sound/soc/samsung/dma.h +++ b/sound/soc/samsung/dma.h @@ -12,9 +12,6 @@ #ifndef _S3C_AUDIO_H #define _S3C_AUDIO_H -#define ST_RUNNING (1<<0) -#define ST_OPENED (1<<1) - struct s3c_dma_params { struct s3c2410_dma_client *client; /* stream identifier */ int channel; /* Channel ID */ @@ -22,9 +19,4 @@ struct s3c_dma_params { int dma_size; /* Size of the DMA transfer */ }; -#define S3C24XX_DAI_I2S 0 - -/* platform data */ -extern struct snd_ac97_bus_ops s3c24xx_ac97_ops; - #endif -- cgit v1.2.3 From 9c6df19e55799d23863eb414b0ee850c4fd3a174 Mon Sep 17 00:00:00 2001 From: Seungwhan Youn Date: Fri, 7 Jan 2011 13:57:23 +0900 Subject: ASoC: SAMSUNG: Move PCM specific definitions into pcm.c This patch moves PCM specific definitions, they doesn't need to be shared, into 'pcm.c' from 'pcm.h'. Signed-off-by: Seungwhan Youn Acked-by: Jassi Brar Signed-off-by: Mark Brown --- sound/soc/samsung/pcm.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++ sound/soc/samsung/pcm.h | 107 ------------------------------------------------ 2 files changed, 107 insertions(+), 107 deletions(-) diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c index 48d0b750406b..091db5dce07e 100644 --- a/sound/soc/samsung/pcm.c +++ b/sound/soc/samsung/pcm.c @@ -32,6 +32,113 @@ #include "dma.h" #include "pcm.h" +/*Register Offsets */ +#define S3C_PCM_CTL 0x00 +#define S3C_PCM_CLKCTL 0x04 +#define S3C_PCM_TXFIFO 0x08 +#define S3C_PCM_RXFIFO 0x0C +#define S3C_PCM_IRQCTL 0x10 +#define S3C_PCM_IRQSTAT 0x14 +#define S3C_PCM_FIFOSTAT 0x18 +#define S3C_PCM_CLRINT 0x20 + +/* PCM_CTL Bit-Fields */ +#define S3C_PCM_CTL_TXDIPSTICK_MASK 0x3f +#define S3C_PCM_CTL_TXDIPSTICK_SHIFT 13 +#define S3C_PCM_CTL_RXDIPSTICK_MASK 0x3f +#define S3C_PCM_CTL_RXDIPSTICK_SHIFT 7 +#define S3C_PCM_CTL_TXDMA_EN (0x1 << 6) +#define S3C_PCM_CTL_RXDMA_EN (0x1 << 5) +#define S3C_PCM_CTL_TXMSB_AFTER_FSYNC (0x1 << 4) +#define S3C_PCM_CTL_RXMSB_AFTER_FSYNC (0x1 << 3) +#define S3C_PCM_CTL_TXFIFO_EN (0x1 << 2) +#define S3C_PCM_CTL_RXFIFO_EN (0x1 << 1) +#define S3C_PCM_CTL_ENABLE (0x1 << 0) + +/* PCM_CLKCTL Bit-Fields */ +#define S3C_PCM_CLKCTL_SERCLK_EN (0x1 << 19) +#define S3C_PCM_CLKCTL_SERCLKSEL_PCLK (0x1 << 18) +#define S3C_PCM_CLKCTL_SCLKDIV_MASK 0x1ff +#define S3C_PCM_CLKCTL_SYNCDIV_MASK 0x1ff +#define S3C_PCM_CLKCTL_SCLKDIV_SHIFT 9 +#define S3C_PCM_CLKCTL_SYNCDIV_SHIFT 0 + +/* PCM_TXFIFO Bit-Fields */ +#define S3C_PCM_TXFIFO_DVALID (0x1 << 16) +#define S3C_PCM_TXFIFO_DATA_MSK (0xffff << 0) + +/* PCM_RXFIFO Bit-Fields */ +#define S3C_PCM_RXFIFO_DVALID (0x1 << 16) +#define S3C_PCM_RXFIFO_DATA_MSK (0xffff << 0) + +/* PCM_IRQCTL Bit-Fields */ +#define S3C_PCM_IRQCTL_IRQEN (0x1 << 14) +#define S3C_PCM_IRQCTL_WRDEN (0x1 << 12) +#define S3C_PCM_IRQCTL_TXEMPTYEN (0x1 << 11) +#define S3C_PCM_IRQCTL_TXALMSTEMPTYEN (0x1 << 10) +#define S3C_PCM_IRQCTL_TXFULLEN (0x1 << 9) +#define S3C_PCM_IRQCTL_TXALMSTFULLEN (0x1 << 8) +#define S3C_PCM_IRQCTL_TXSTARVEN (0x1 << 7) +#define S3C_PCM_IRQCTL_TXERROVRFLEN (0x1 << 6) +#define S3C_PCM_IRQCTL_RXEMPTEN (0x1 << 5) +#define S3C_PCM_IRQCTL_RXALMSTEMPTEN (0x1 << 4) +#define S3C_PCM_IRQCTL_RXFULLEN (0x1 << 3) +#define S3C_PCM_IRQCTL_RXALMSTFULLEN (0x1 << 2) +#define S3C_PCM_IRQCTL_RXSTARVEN (0x1 << 1) +#define S3C_PCM_IRQCTL_RXERROVRFLEN (0x1 << 0) + +/* PCM_IRQSTAT Bit-Fields */ +#define S3C_PCM_IRQSTAT_IRQPND (0x1 << 13) +#define S3C_PCM_IRQSTAT_WRD_XFER (0x1 << 12) +#define S3C_PCM_IRQSTAT_TXEMPTY (0x1 << 11) +#define S3C_PCM_IRQSTAT_TXALMSTEMPTY (0x1 << 10) +#define S3C_PCM_IRQSTAT_TXFULL (0x1 << 9) +#define S3C_PCM_IRQSTAT_TXALMSTFULL (0x1 << 8) +#define S3C_PCM_IRQSTAT_TXSTARV (0x1 << 7) +#define S3C_PCM_IRQSTAT_TXERROVRFL (0x1 << 6) +#define S3C_PCM_IRQSTAT_RXEMPT (0x1 << 5) +#define S3C_PCM_IRQSTAT_RXALMSTEMPT (0x1 << 4) +#define S3C_PCM_IRQSTAT_RXF