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 (limited to 'sound/soc/mid-x86') diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c new file mode 100644 index 00000000000..189d546fbf9 --- /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 00000000000..df370286694 --- /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-18-g5258 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 (limited to 'sound/soc/mid-x86') diff --git a/sound/soc/mid-x86/mfld_machine.c b/sound/soc/mid-x86/mfld_machine.c new file mode 100644 index 00000000000..1a330be1a01 --- /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-18-g5258 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/mid-x86/Kconfig | 13 +++++++++++++ sound/soc/mid-x86/Makefile | 7 +++++++ 2 files changed, 20 insertions(+) create mode 100644 sound/soc/mid-x86/Kconfig create mode 100644 sound/soc/mid-x86/Makefile (limited to 'sound/soc/mid-x86') diff --git a/sound/soc/mid-x86/Kconfig b/sound/soc/mid-x86/Kconfig new file mode 100644 index 00000000000..e0123a40822 --- /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 00000000000..a1a93314b84 --- /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-18-g5258 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(-) (limited to 'sound/soc/mid-x86') diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c index 189d546fbf9..0e994c16e7a 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-18-g5258 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(-) (limited to 'sound/soc/mid-x86') diff --git a/sound/soc/mid-x86/Makefile b/sound/soc/mid-x86/Makefile index a1a93314b84..63988333946 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-18-g5258 From 5c68536f32a46c8ccc98df3d9b154e1f33f72447 Mon Sep 17 00:00:00 2001 From: Harsha Priya Date: Tue, 11 Jan 2011 14:50:35 +0530 Subject: ASoC: sst_platform created helper functions Few funtions can be modularized in this driver to make them look cleaner like managing the stream status with locks and filling pcm parameters. This patch adds helper functions to do the same. 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 | 123 +++++++++++++++++---------------------- 1 file changed, 53 insertions(+), 70 deletions(-) (limited to 'sound/soc/mid-x86') diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c index 0e994c16e7a..a4e3fa3761f 100644 --- a/sound/soc/mid-x86/sst_platform.c +++ b/sound/soc/mid-x86/sst_platform.c @@ -105,7 +105,45 @@ struct snd_soc_dai_driver sst_platform_dai[] = { }, }, }; + /* helper functions */ +static inline void sst_set_stream_status(struct sst_runtime_stream *stream, + int state) +{ + spin_lock(&stream->status_lock); + stream->stream_status = state; + spin_unlock(&stream->status_lock); +} + +static inline int sst_get_stream_status(struct sst_runtime_stream *stream) +{ + int state; + + spin_lock(&stream->status_lock); + state = stream->stream_status; + spin_unlock(&stream->status_lock); + return state; +} + +static void sst_fill_pcm_params(struct snd_pcm_substream *substream, + struct snd_sst_stream_params *param) +{ + + 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); + 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); +} + static int sst_platform_alloc_stream(struct snd_pcm_substream *substream) { struct sst_runtime_stream *stream = @@ -115,26 +153,10 @@ static int sst_platform_alloc_stream(struct snd_pcm_substream *substream) 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); + sst_fill_pcm_params(substream, ¶m); 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; - + str_params.codec = param.uc.pcm_params.codec; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { str_params.ops = STREAM_OPS_PLAYBACK; str_params.device_type = substream->pcm->device + 1; @@ -153,28 +175,23 @@ static int sst_platform_alloc_stream(struct snd_pcm_substream *substream) 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; + int status; 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); + status = sst_get_stream_status(stream); + if (status != SST_PLATFORM_RUNNING) return; - } - spin_unlock(&stream->status_lock); snd_pcm_period_elapsed(substream); } @@ -185,9 +202,7 @@ static int sst_platform_init_stream(struct snd_pcm_substream *substream) 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); + sst_set_stream_status(stream, SST_PLATFORM_INIT); stream->stream_info.period_elapsed = sst_period_elapsed; stream->stream_info.mad_substream = substream; stream->stream_info.buffer_ptr = 0; @@ -208,21 +223,14 @@ static int sst_platform_open(struct snd_pcm_substream *substream) 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); - + sst_set_stream_status(stream, SST_PLATFORM_INIT); stream->stream_info.mad_substream = substream; /* allocate memory for SST API set */ stream->sstdrv_ops = kzalloc(sizeof(*stream->sstdrv_ops), @@ -233,7 +241,6 @@ static int sst_platform_open(struct snd_pcm_substream *substream) 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) { @@ -251,14 +258,11 @@ static int sst_platform_close(struct snd_pcm_substream *substream) 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; @@ -270,7 +274,6 @@ static int sst_platform_pcm_prepare(struct snd_pcm_substream *substream) 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) { @@ -299,11 +302,8 @@ static int sst_platform_pcm_trigger(struct snd_pcm_substream *substream, 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"); @@ -311,9 +311,7 @@ static int sst_platform_pcm_trigger(struct snd_pcm_substream *substream, 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); + sst_set_stream_status(stream, SST_PLATFORM_RUNNING); stream->stream_info.mad_substream = substream; break; case SNDRV_PCM_TRIGGER_STOP: @@ -322,9 +320,7 @@ static int sst_platform_pcm_trigger(struct snd_pcm_substream *substream, 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); + sst_set_stream_status(stream, SST_PLATFORM_DROPPED); break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: pr_debug("sst: in pause\n"); @@ -332,9 +328,7 @@ static int sst_platform_pcm_trigger(struct snd_pcm_substream *substream, 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); + sst_set_stream_status(stream, SST_PLATFORM_PAUSED); break; case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: pr_debug("sst: in pause release\n"); @@ -342,9 +336,7 @@ static int sst_platform_pcm_trigger(struct snd_pcm_substream *substream, 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); + sst_set_stream_status(stream, SST_PLATFORM_RUNNING); break; default: ret_val = -EINVAL; @@ -357,18 +349,13 @@ static snd_pcm_uframes_t sst_platform_pcm_pointer (struct snd_pcm_substream *substream) { struct sst_runtime_stream *stream; - int ret_val; + int ret_val, status; 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); + status = sst_get_stream_status(stream); + if (status == SST_PLATFORM_INIT) 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); @@ -376,7 +363,6 @@ static snd_pcm_uframes_t sst_platform_pcm_pointer pr_err("sst: error code = %d\n", ret_val); return ret_val; } - return stream->stream_info.buffer_ptr; } @@ -402,7 +388,6 @@ int sst_pcm_new(struct snd_card *card, struct snd_soc_dai *dai, 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, @@ -414,7 +399,6 @@ int sst_pcm_new(struct snd_card *card, struct snd_soc_dai *dai, return retval; } } - return retval; } struct snd_soc_platform_driver sst_soc_platform_drv = { @@ -433,6 +417,7 @@ static int sst_platform_probe(struct platform_device *pdev) 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) { @@ -446,10 +431,8 @@ 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; } -- cgit v1.2.3-18-g5258 From 065ae6784f03016ed1c0613863461a162388cf5a Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Tue, 18 Jan 2011 19:11:48 +0530 Subject: ASoC: Add dependency on INTEL_SCU_IPC for Intel MID drivers Signed-off-by: Vinod Koul Signed-off-by: Harsha Priya Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/mid-x86/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/soc/mid-x86') diff --git a/sound/soc/mid-x86/Kconfig b/sound/soc/mid-x86/Kconfig index e0123a40822..1ad75383635 100644 --- a/sound/soc/mid-x86/Kconfig +++ b/sound/soc/mid-x86/Kconfig @@ -1,5 +1,6 @@ config SND_MFLD_MACHINE tristate "SOC Machine Audio driver for Intel Medfield MID platform" + depends on INTEL_SCU_IPC select SND_SOC_SN95031 select SND_SST_PLATFORM help -- cgit v1.2.3-18-g5258 From a211701eb1e4a41bbee22d61f35dba8e55925db4 Mon Sep 17 00:00:00 2001 From: Harsha Priya Date: Tue, 11 Jan 2011 14:50:59 +0530 Subject: ASoC: sst_platform porting sst dsp driver interface as per latest in Greg's staging tree The interface between sst platform driver and intel sst dsp driver have been changed in Greg's staging tree - next branch This patch adds the interface changes compatible with the new interface in Greg's staging tree Signed-off-by: Harsha Priya Signed-off-by: Vinod Koul Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/mid-x86/sst_platform.c | 49 +++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 28 deletions(-) (limited to 'sound/soc/mid-x86') diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c index a4e3fa3761f..1d1f5447b33 100644 --- a/sound/soc/mid-x86/sst_platform.c +++ b/sound/soc/mid-x86/sst_platform.c @@ -168,7 +168,7 @@ static int sst_platform_alloc_stream(struct snd_pcm_substream *substream) pr_debug("Capture stream,Device %d\n", substream->pcm->device); } - ret_val = stream->sstdrv_ops->control_set(SST_SND_ALLOC, &str_params); + ret_val = stream->sstdrv_ops->pcm_control->open(&str_params); pr_debug("SST_SND_PLAY/CAPTURE ret_val = %x\n", ret_val); if (ret_val < 0) return ret_val; @@ -207,8 +207,8 @@ static int sst_platform_init_stream(struct snd_pcm_substream *substream) 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); + ret_val = stream->sstdrv_ops->pcm_control->device_control( + SST_SND_STREAM_INIT, &stream->stream_info); if (ret_val) pr_err("control_set ret error %d\n", ret_val); return ret_val; @@ -261,8 +261,7 @@ static int sst_platform_close(struct snd_pcm_substream *substream) 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); + ret_val = stream->sstdrv_ops->pcm_control->close(str_id); kfree(stream->sstdrv_ops); kfree(stream); return ret_val; @@ -277,7 +276,7 @@ static int sst_platform_pcm_prepare(struct snd_pcm_substream *substream) 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( + ret_val = stream->sstdrv_ops->pcm_control->device_control( SST_SND_DROP, &str_id); return ret_val; } @@ -300,6 +299,7 @@ static int sst_platform_pcm_trigger(struct snd_pcm_substream *substream, { int ret_val = 0, str_id; struct sst_runtime_stream *stream; + int str_cmd, status; pr_debug("sst_platform_pcm_trigger called\n"); stream = substream->runtime->private_data; @@ -307,40 +307,33 @@ static int sst_platform_pcm_trigger(struct snd_pcm_substream *substream, 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; - sst_set_stream_status(stream, SST_PLATFORM_RUNNING); + str_cmd = SST_SND_START; + status = SST_PLATFORM_RUNNING; 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; - sst_set_stream_status(stream, SST_PLATFORM_DROPPED); + str_cmd = SST_SND_DROP; + status = SST_PLATFORM_DROPPED; 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; - sst_set_stream_status(stream, SST_PLATFORM_PAUSED); + str_cmd = SST_SND_PAUSE; + status = SST_PLATFORM_PAUSED; 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; - sst_set_stream_status(stream, SST_PLATFORM_RUNNING); + str_cmd = SST_SND_RESUME; + status = SST_PLATFORM_RUNNING; break; default: - ret_val = -EINVAL; + return -EINVAL; } + ret_val = stream->sstdrv_ops->pcm_control->device_control(str_cmd, + &str_id); + if (!ret_val) + sst_set_stream_status(stream, status); + return ret_val; } @@ -357,7 +350,7 @@ static snd_pcm_uframes_t sst_platform_pcm_pointer if (status == SST_PLATFORM_INIT) return 0; str_info = &stream->stream_info; - ret_val = stream->sstdrv_ops->control_set( + ret_val = stream->sstdrv_ops->pcm_control->device_control( SST_SND_BUFFER_POINTER, str_info); if (ret_val) { pr_err("sst: error code = %d\n", ret_val); -- cgit v1.2.3-18-g5258 From a7bffdf7d885197857bb04919344dc17ffaf79b9 Mon Sep 17 00:00:00 2001 From: Harsha Priya Date: Fri, 28 Jan 2011 22:27:26 +0530 Subject: ASoC: sst_platform: add support for capture stream on headset dai 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 | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'sound/soc/mid-x86') diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c index 1d1f5447b33..96e6e9c9c5f 100644 --- a/sound/soc/mid-x86/sst_platform.c +++ b/sound/soc/mid-x86/sst_platform.c @@ -73,6 +73,12 @@ struct snd_soc_dai_driver sst_platform_dai[] = { .rates = SNDRV_PCM_RATE_48000, .formats = SNDRV_PCM_FMTBIT_S24_LE, }, + .capture = { + .channels_min = 1, + .channels_max = 5, + .rates = SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S24_LE, + }, }, { .name = "Speaker-cpu-dai", -- cgit v1.2.3-18-g5258 From d316553a0cb4569a9b6260e870cab8b9c102eace Mon Sep 17 00:00:00 2001 From: Harsha Priya Date: Fri, 28 Jan 2011 22:28:32 +0530 Subject: ASoC: mid-x86: Add support for capture in machine driver This configures the capture unused pins 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 | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sound/soc/mid-x86') diff --git a/sound/soc/mid-x86/mfld_machine.c b/sound/soc/mid-x86/mfld_machine.c index 1a330be1a01..7925851a5de 100644 --- a/sound/soc/mid-x86/mfld_machine.c +++ b/sound/soc/mid-x86/mfld_machine.c @@ -182,6 +182,9 @@ static int mfld_init(struct snd_soc_pcm_runtime *runtime) snd_soc_dapm_disable_pin(dapm, "LINEOUTR"); lo_dac = 3; hs_switch = 0; + /* we dont use linein in this so set to NC */ + snd_soc_dapm_disable_pin(dapm, "LINEINL"); + snd_soc_dapm_disable_pin(dapm, "LINEINR"); return snd_soc_dapm_sync(dapm); } -- cgit v1.2.3-18-g5258 From 480b08d0bb1aab29de2545625767dac55c7dcb59 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Sun, 6 Feb 2011 15:35:48 +0530 Subject: ASoC: mid-x86: Fix dependency on intel_sst driver Enabling medfield asoc driver causes compliation error when intel_sst is not selected ERROR: "register_sst_card" [sound/soc/mid-x86/snd-soc-sst-platform.ko] undefined! This patch puts proper dependency to elimate build error Signed-off-by: Vinod Koul Signed-off-by: Harsha Priya Reported-by: Andrew Morton Signed-off-by: Mark Brown --- sound/soc/mid-x86/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/soc/mid-x86') diff --git a/sound/soc/mid-x86/Kconfig b/sound/soc/mid-x86/Kconfig index 1ad75383635..29350428f1c 100644 --- a/sound/soc/mid-x86/Kconfig +++ b/sound/soc/mid-x86/Kconfig @@ -1,6 +1,7 @@ config SND_MFLD_MACHINE tristate "SOC Machine Audio driver for Intel Medfield MID platform" depends on INTEL_SCU_IPC + depends on SND_INTEL_SST select SND_SOC_SN95031 select SND_SST_PLATFORM help @@ -11,4 +12,3 @@ config SND_MFLD_MACHINE config SND_SST_PLATFORM tristate - depends on SND_INTEL_SST -- cgit v1.2.3-18-g5258 From 42aee9b43e76645cda59bce30a101e7574ce913e Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Wed, 9 Feb 2011 21:44:33 +0530 Subject: ASoC: mfld_machine: Add support for jack detection This patch adds support for registering jack interupt and registering jack with core 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 | 203 +++++++++++++++++++++++++++++++++------ 1 file changed, 176 insertions(+), 27 deletions(-) (limited to 'sound/soc/mid-x86') diff --git a/sound/soc/mid-x86/mfld_machine.c b/sound/soc/mid-x86/mfld_machine.c index 7925851a5de..45a00670802 100644 --- a/sound/soc/mid-x86/mfld_machine.c +++ b/sound/soc/mid-x86/mfld_machine.c @@ -27,18 +27,53 @@ #include #include #include +#include #include #include #include +#include #include "../codecs/sn95031.h" #define MID_MONO 1 #define MID_STEREO 2 #define MID_MAX_CAP 5 +#define MFLD_JACK_INSERT 0x04 + +enum soc_mic_bias_zones { + MFLD_MV_START = 0, + /* mic bias volutage range for Headphones*/ + MFLD_MV_HP = 400, + /* mic bias volutage range for American Headset*/ + MFLD_MV_AM_HS = 650, + /* mic bias volutage range for Headset*/ + MFLD_MV_HS = 2000, + MFLD_MV_UNDEFINED, +}; static unsigned int hs_switch; static unsigned int lo_dac; +struct mfld_mc_private { + struct platform_device *socdev; + void __iomem *int_base; + struct snd_soc_codec *codec; + u8 interrupt_status; +}; + +struct snd_soc_jack mfld_jack; + +/*Headset jack detection DAPM pins */ +static struct snd_soc_jack_pin mfld_jack_pins[] = { + { + .pin = "Headphones", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "AMIC1", + .mask = SND_JACK_MICROPHONE, + }, +}; + /* sound card controls */ static const char *headset_switch_text[] = {"Earpiece", "Headset"}; @@ -67,13 +102,11 @@ static int headset_set_switch(struct snd_kcontrol *kcontrol, 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_enable_pin(&codec->dapm, "Headphones"); 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_disable_pin(&codec->dapm, "Headphones"); snd_soc_dapm_enable_pin(&codec->dapm, "EPOUT"); } snd_soc_dapm_sync(&codec->dapm); @@ -91,12 +124,10 @@ static void lo_enable_out_pins(struct snd_soc_codec *codec) 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_enable_pin(&codec->dapm, "Headphones"); 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_disable_pin(&codec->dapm, "Headphones"); snd_soc_dapm_enable_pin(&codec->dapm, "EPOUT"); } } @@ -130,8 +161,7 @@ static int lo_set_switch(struct snd_kcontrol *kcontrol, 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, "Headphones"); snd_soc_dapm_disable_pin(&codec->dapm, "EPOUT"); snd_soc_update_bits(codec, SN95031_LOCTL, 0x66, 0x22); break; @@ -162,12 +192,45 @@ static const struct snd_kcontrol_new mfld_snd_controls[] = { lo_get_switch, lo_set_switch), }; +static const struct snd_soc_dapm_widget mfld_widgets[] = { + SND_SOC_DAPM_HP("Headphones", NULL), + SND_SOC_DAPM_MIC("Mic", NULL), +}; + +static const struct snd_soc_dapm_route mfld_map[] = { + {"Headphones", NULL, "HPOUTR"}, + {"Headphones", NULL, "HPOUTL"}, + {"Mic", NULL, "AMIC1"}, +}; + +static void mfld_jack_check(unsigned int intr_status) +{ + struct mfld_jack_data jack_data; + + jack_data.mfld_jack = &mfld_jack; + jack_data.intr_id = intr_status; + + sn95031_jack_detection(&jack_data); + /* TODO: add american headset detection post gpiolib support */ +} + 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; + /* Add jack sense widgets */ + snd_soc_dapm_new_controls(dapm, mfld_widgets, ARRAY_SIZE(mfld_widgets)); + + /* Set up the map */ + snd_soc_dapm_add_routes(dapm, mfld_map, ARRAY_SIZE(mfld_map)); + + /* always connected */ + snd_soc_dapm_enable_pin(dapm, "Headphones"); + snd_soc_dapm_enable_pin(dapm, "Mic"); + snd_soc_dapm_sync(dapm); + ret_val = snd_soc_add_controls(codec, mfld_snd_controls, ARRAY_SIZE(mfld_snd_controls)); if (ret_val) { @@ -175,8 +238,7 @@ static int mfld_init(struct snd_soc_pcm_runtime *runtime) 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"); + snd_soc_dapm_disable_pin(dapm, "Headphones"); /* default is lineout NC, userspace sets it explcitly */ snd_soc_dapm_disable_pin(dapm, "LINEOUTL"); snd_soc_dapm_disable_pin(dapm, "LINEOUTR"); @@ -185,7 +247,29 @@ static int mfld_init(struct snd_soc_pcm_runtime *runtime) /* we dont use linein in this so set to NC */ snd_soc_dapm_disable_pin(dapm, "LINEINL"); snd_soc_dapm_disable_pin(dapm, "LINEINR"); - return snd_soc_dapm_sync(dapm); + snd_soc_dapm_sync(dapm); + + /* Headset and button jack detection */ + ret_val = snd_soc_jack_new(codec, "Intel(R) MID Audio Jack", + SND_JACK_HEADSET | SND_JACK_BTN_0 | + SND_JACK_BTN_1, &mfld_jack); + if (ret_val) { + pr_err("jack creation failed\n"); + return ret_val; + } + + ret_val = snd_soc_jack_add_pins(&mfld_jack, + ARRAY_SIZE(mfld_jack_pins), mfld_jack_pins); + if (ret_val) { + pr_err("adding jack pins failed\n"); + return ret_val; + } + + /* we want to check if anything is inserted at boot, + * so send a fake event to codec and it will read adc + * to find if anything is there or not */ + mfld_jack_check(MFLD_JACK_INSERT); + return ret_val; } struct snd_soc_dai_link mfld_msic_dailink[] = { @@ -234,37 +318,102 @@ static struct snd_soc_card snd_soc_card_mfld = { .num_links = ARRAY_SIZE(mfld_msic_dailink), }; +static irqreturn_t snd_mfld_jack_intr_handler(int irq, void *dev) +{ + struct mfld_mc_private *mc_private = (struct mfld_mc_private *) dev; + + memcpy_fromio(&mc_private->interrupt_status, + ((void *)(mc_private->int_base)), + sizeof(u8)); + return IRQ_WAKE_THREAD; +} + +static irqreturn_t snd_mfld_jack_detection(int irq, void *data) +{ + struct mfld_mc_private *mc_drv_ctx = (struct mfld_mc_private *) data; + + if (mfld_jack.codec == NULL) + return IRQ_HANDLED; + mfld_jack_check(mc_drv_ctx->interrupt_status); + + return IRQ_HANDLED; +} + static int __devinit snd_mfld_mc_probe(struct platform_device *pdev) { - struct platform_device *socdev; - int ret_val = 0; + int ret_val = 0, irq; + struct mfld_mc_private *mc_drv_ctx; + struct resource *irq_mem; 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"); + /* retrive the irq number */ + irq = platform_get_irq(pdev, 0); + + /* audio interrupt base of SRAM location where + * interrupts are stored by System FW */ + mc_drv_ctx = kzalloc(sizeof(*mc_drv_ctx), GFP_ATOMIC); + if (!mc_drv_ctx) { + pr_err("allocation failed\n"); return -ENOMEM; } - platform_set_drvdata(socdev, &snd_soc_card_mfld); - ret_val = platform_device_add(socdev); + + irq_mem = platform_get_resource_byname( + pdev, IORESOURCE_MEM, "IRQ_BASE"); + if (!irq_mem) { + pr_err("no mem resource given\n"); + ret_val = -ENODEV; + goto unalloc; + } + mc_drv_ctx->int_base = ioremap_nocache(irq_mem->start, + resource_size(irq_mem)); + if (!mc_drv_ctx->int_base) { + pr_err("Mapping of cache failed\n"); + ret_val = -ENOMEM; + goto unalloc; + } + /* register for interrupt */ + ret_val = request_threaded_irq(irq, snd_mfld_jack_intr_handler, + snd_mfld_jack_detection, + IRQF_SHARED, pdev->dev.driver->name, mc_drv_ctx); + if (ret_val) { + pr_err("cannot register IRQ\n"); + goto unalloc; + } + /* create soc device */ + mc_drv_ctx->socdev = platform_device_alloc("soc-audio", -1); + if (!mc_drv_ctx->socdev) { + pr_err("soc-audio device allocation failed\n"); + ret_val = -ENOMEM; + goto freeirq; + } + platform_set_drvdata(mc_drv_ctx->socdev, &snd_soc_card_mfld); + ret_val = platform_device_add(mc_drv_ctx->socdev); if (ret_val) { pr_err("Unable to add soc-audio device, err %d\n", ret_val); - platform_device_put(socdev); + goto unregister; } - - platform_set_drvdata(pdev, socdev); - + platform_set_drvdata(pdev, mc_drv_ctx); pr_debug("successfully exited probe\n"); return ret_val; + +unregister: + platform_device_put(mc_drv_ctx->socdev); +freeirq: + free_irq(irq, mc_drv_ctx); +unalloc: + kfree(mc_drv_ctx); + 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"); + struct mfld_mc_private *mc_drv_ctx = platform_get_drvdata(pdev); - platform_device_unregister(socdev); + pr_debug("snd_mfld_mc_remove called\n"); + free_irq(platform_get_irq(pdev, 0), mc_drv_ctx); + platform_device_unregister(mc_drv_ctx->socdev); + kfree(mc_drv_ctx); platform_set_drvdata(pdev, NULL); return 0; } -- cgit v1.2.3-18-g5258 From 7ae7434086f5b106021276e88b8ef49debf30aa8 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Thu, 10 Feb 2011 12:58:01 +0530 Subject: ASoC: mid-x86: Use the soc-jack apis for jack type detection This patch modifies the mfld_machine to use the new jack apis for adding the voltage zones for jack type detection. It also modifed TI sn95031 codec driver to use these new apis 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 | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'sound/soc/mid-x86') diff --git a/sound/soc/mid-x86/mfld_machine.c b/sound/soc/mid-x86/mfld_machine.c index 45a00670802..96487fb8d26 100644 --- a/sound/soc/mid-x86/mfld_machine.c +++ b/sound/soc/mid-x86/mfld_machine.c @@ -74,6 +74,12 @@ static struct snd_soc_jack_pin mfld_jack_pins[] = { }, }; +/* jack detection voltage zones */ +static struct snd_soc_jack_zone mfld_zones[] = { + {MFLD_MV_START, MFLD_MV_AM_HS, SND_JACK_HEADPHONE}, + {MFLD_MV_AM_HS, MFLD_MV_HS, SND_JACK_HEADSET}, +}; + /* sound card controls */ static const char *headset_switch_text[] = {"Earpiece", "Headset"}; @@ -264,6 +270,12 @@ static int mfld_init(struct snd_soc_pcm_runtime *runtime) pr_err("adding jack pins failed\n"); return ret_val; } + ret_val = snd_soc_jack_add_zones(&mfld_jack, + ARRAY_SIZE(mfld_zones), mfld_zones); + if (ret_val) { + pr_err("adding jack zones failed\n"); + return ret_val; + } /* we want to check if anything is inserted at boot, * so send a fake event to codec and it will read adc -- cgit v1.2.3-18-g5258 From d58198b943c7af6975dec869d75b15dd66d1495c Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Tue, 15 Feb 2011 18:28:55 +0530 Subject: ASoC: mfld_machine: make use of soc_register_card API This patch removes the old method of soc-audio device creation in mfld machine and makes use of new soc_register_card API to register the card 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 | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) (limited to 'sound/soc/mid-x86') diff --git a/sound/soc/mid-x86/mfld_machine.c b/sound/soc/mid-x86/mfld_machine.c index 96487fb8d26..429aa1be2cf 100644 --- a/sound/soc/mid-x86/mfld_machine.c +++ b/sound/soc/mid-x86/mfld_machine.c @@ -392,25 +392,17 @@ static int __devinit snd_mfld_mc_probe(struct platform_device *pdev) pr_err("cannot register IRQ\n"); goto unalloc; } - /* create soc device */ - mc_drv_ctx->socdev = platform_device_alloc("soc-audio", -1); - if (!mc_drv_ctx->socdev) { - pr_err("soc-audio device allocation failed\n"); - ret_val = -ENOMEM; - goto freeirq; - } - platform_set_drvdata(mc_drv_ctx->socdev, &snd_soc_card_mfld); - ret_val = platform_device_add(mc_drv_ctx->socdev); + /* register the soc card */ + snd_soc_card_mfld.dev = &pdev->dev; + ret_val = snd_soc_register_card(&snd_soc_card_mfld); if (ret_val) { - pr_err("Unable to add soc-audio device, err %d\n", ret_val); - goto unregister; + pr_debug("snd_soc_register_card failed %d\n", ret_val); + goto freeirq; } platform_set_drvdata(pdev, mc_drv_ctx); pr_debug("successfully exited probe\n"); return ret_val; -unregister: - platform_device_put(mc_drv_ctx->socdev); freeirq: free_irq(irq, mc_drv_ctx); unalloc: @@ -424,7 +416,7 @@ static int __devexit snd_mfld_mc_remove(struct platform_device *pdev) pr_debug("snd_mfld_mc_remove called\n"); free_irq(platform_get_irq(pdev, 0), mc_drv_ctx); - platform_device_unregister(mc_drv_ctx->socdev); + snd_soc_unregister_card(&snd_soc_card_mfld); kfree(mc_drv_ctx); platform_set_drvdata(pdev, NULL); return 0; -- cgit v1.2.3-18-g5258 From 5b499f8bf376ecd1575c0cc2095555cf382063ae Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Tue, 15 Feb 2011 18:28:54 +0530 Subject: ASoC: sst_platform: fix the pulseaudio error Pulseaudio doesnt work with current driver and it was root caused to absense of hw_params function and malloc_pages in it. This patch adds this and allows pa to work fine with these drivers 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 | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'sound/soc/mid-x86') diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c index 96e6e9c9c5f..ee2c22475a7 100644 --- a/sound/soc/mid-x86/sst_platform.c +++ b/sound/soc/mid-x86/sst_platform.c @@ -365,6 +365,14 @@ static snd_pcm_uframes_t sst_platform_pcm_pointer return stream->stream_info.buffer_ptr; } +static int sst_platform_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); + memset(substream->runtime->dma_area, 0, params_buffer_bytes(params)); + + return 0; +} static struct snd_pcm_ops sst_platform_ops = { .open = sst_platform_open, @@ -373,6 +381,7 @@ static struct snd_pcm_ops sst_platform_ops = { .prepare = sst_platform_pcm_prepare, .trigger = sst_platform_pcm_trigger, .pointer = sst_platform_pcm_pointer, + .hw_params = sst_platform_pcm_hw_params, }; static void sst_pcm_free(struct snd_pcm *pcm) -- cgit v1.2.3-18-g5258