[alsa-devel] [RFC 3/4] ASoC SST: add mid machine driver

Koul, Vinod vinod.koul at intel.com
Tue Dec 28 13:11:27 CET 2010


From: Vinod Koul <vinod.koul at intel.com>

This patch adds the mic machine driver
The mid machine driver glues the msic and mid_platfrom driver to form the asoc sound driver

Signed-off-by: Vinod Koul <vinod.koul at intel.com>
Signed-off-by: Harsha Priya <priya.harsha at intel.com>
---
 sound/soc/mid-x86/mid_machine.c       |  168 +++++++++++++++++++++++++++++++++
 sound/soc/mid-x86/mid_machine.h       |   63 ++++++++++++
 sound/soc/mid-x86/mid_machine_pvt.c   |   81 ++++++++++++++++
 sound/soc/mid-x86/mid_machine_table.h |  154 ++++++++++++++++++++++++++++++
 4 files changed, 466 insertions(+), 0 deletions(-)
 create mode 100644 sound/soc/mid-x86/mid_machine.c
 create mode 100644 sound/soc/mid-x86/mid_machine.h
 create mode 100644 sound/soc/mid-x86/mid_machine_pvt.c
 create mode 100644 sound/soc/mid-x86/mid_machine_table.h

diff --git a/sound/soc/mid-x86/mid_machine.c b/sound/soc/mid-x86/mid_machine.c
new file mode 100644
index 0000000..4f4bc0c
--- /dev/null
+++ b/sound/soc/mid-x86/mid_machine.c
@@ -0,0 +1,168 @@
+/*
+ *  mid_machine.c - Intel MID Machine driver
+ *
+ *  Copyright (C) 2010 Intel Corp
+ *  Author: Harsha Priya <priya.harsha at intel.com>
+ *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; 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 <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/initval.h>
+#include <sound/soc.h>
+#include <sound/intel_sst.h>
+#include "../codecs/msic.h"
+#include "mid_platform.h"
+#include "mid_machine.h"
+#include "mid_machine_table.h"
+
+
+static struct platform_device *mid_platform_device,
+			*mid_codec_device,
+			*mid_soc_device;
+
+struct mid_dev_data	platform_drv_data;
+struct snd_soc_card	soc_dev_data;
+
+
+int __devinit snd_intelmid_mc_probe(struct platform_device *pdev)
+{
+	int ret_val = 0, i;
+	struct codec_id_info *codec;
+	const struct platform_device_id *id = platform_get_device_id(pdev);
+	unsigned int cpu_id, codec_id;
+
+	pr_debug("snd_intelmid_mc_probe called\n");
+
+	codec = (void *)id->driver_data;
+	if (codec == NULL) {
+		pr_err("driver data received as null\n");
+		return 0;
+	}
+
+	codec_id = get_codec_id(codec);
+	cpu_id = codec->cpu_id;
+	pr_debug("**codec id = %d \t ***cpu id = %d\n", codec_id, cpu_id);
+
+	for (i = 0; i < ARRAY_SIZE(machine_table); i++) {
+		struct platform_codec_map mc = machine_table[i];
+		if (mc.cpu_id == cpu_id && mc.codec_id == codec_id) {
+			platform_drv_data.dai = mc.cpu_dai;
+			platform_drv_data.num_dais = mc.cpu_num_dais;
+			ret_val = create_device(&mid_platform_device,
+				mc.platform_name, &platform_drv_data);
+			if (ret_val)
+				return ret_val;
+
+			ret_val = create_device(&mid_codec_device,
+				mc.codec_name, NULL);
+			if (ret_val)
+				goto unreg_platform;
+
+			soc_dev_data.name = mc.soc_name;
+			soc_dev_data.dai_link = mc.dai_link;
+			soc_dev_data.num_links = mc.num_dai_links;
+			/*soc_dev_data.codec_dev = mc.codec_dev;*/
+			ret_val = create_device(&mid_soc_device,
+				"soc-audio", &soc_dev_data);
+			if (ret_val)
+				goto unreg_codec;
+		}
+
+	}
+	if (i > ARRAY_SIZE(machine_table)) {
+		pr_err("no platform and codec found to be registered\n");
+		return -1;
+	}
+	pr_debug("successfully exited probe\n");
+	return ret_val;
+unreg_codec:
+	platform_device_unregister(mid_codec_device);
+unreg_platform:
+	platform_device_unregister(mid_platform_device);
+	return ret_val;
+}
+
+static int snd_intelmid_remove(struct platform_device *pdev)
+{
+	const struct platform_device_id *id = platform_get_device_id(pdev);
+	struct codec_id_info *codec;
+	int i;
+	unsigned int cpu_id, codec_id;
+
+	pr_debug("snd_intelmid_remove called\n");
+
+	codec = (void *)id->driver_data;
+	if (codec == NULL) {
+		pr_err("driver data received as null\n");
+		return 0;
+	}
+	codec_id = get_codec_id(codec);
+	cpu_id = codec->cpu_id;
+	pr_debug("**codec id = %d \t ***cpu id = %d\n", codec_id, cpu_id);
+
+	for (i = 0; i < ARRAY_SIZE(machine_table); i++) {
+		struct platform_codec_map mc = machine_table[i];
+		if (mc.cpu_id == cpu_id && mc.codec_id == codec_id) {
+			platform_device_unregister(mid_soc_device);
+			platform_device_unregister(mid_platform_device);
+			platform_device_unregister(mid_codec_device);
+			platform_set_drvdata(pdev, NULL);
+		}
+	}
+	return 0;
+}
+
+
+static struct platform_driver snd_intelmid_mc_driver = {
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = "mid_sound_card",
+	},
+	.id_table = snd_intelmid_ids,
+	.probe = snd_intelmid_mc_probe,
+	.remove = __devexit_p(snd_intelmid_remove),
+};
+
+static int __init intelmidmc_soc_init(void)
+{
+	pr_debug("intelmidmc_soc_init called\n");
+
+	return platform_driver_register(&snd_intelmid_mc_driver);
+}
+module_init(intelmidmc_soc_init);
+
+static void __exit intelmidmc_soc_exit(void)
+{
+	pr_debug("intelmidmc_soc_exit called\n");
+	platform_driver_unregister(&snd_intelmid_mc_driver);
+}
+module_exit(intelmidmc_soc_exit);
+
+MODULE_DESCRIPTION("ASoC Intel(R) MACHINE driver");
+MODULE_AUTHOR("Harsha Priya");
+MODULE_LICENSE("GPL v2");
+
+
diff --git a/sound/soc/mid-x86/mid_machine.h b/sound/soc/mid-x86/mid_machine.h
new file mode 100644
index 0000000..efe693e
--- /dev/null
+++ b/sound/soc/mid-x86/mid_machine.h
@@ -0,0 +1,63 @@
+/*
+ *  mid_machine.h - Intel MID Machine driver header file
+ *
+ *  Copyright (C) 2010 Intel Corp
+ *  Author: Harsha Priya <priya.harsha at intel.com>
+ *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; 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 __MID_MACHINEDRV_H__
+#define __MID_MACHINEDRV_H__
+
+#define MONO 1
+#define STEREO 2
+#define MAX_CAP 5
+#define DRIVER_NAME_MFLD "msic_audio"
+#define DRIVER_NAME_MRST "pmic_audio"
+#define CPU_CHIP_LINCROFT       1 /* System running lincroft */
+#define CPU_CHIP_PENWELL        2 /* System running penwell */
+#define MSIC_CODEC		3
+
+struct codec_id_info {
+	unsigned int	cpu_id;
+	unsigned int	reg_addr;
+	unsigned int	shift;
+	unsigned int	mask;
+};
+
+struct platform_codec_map {
+	int			cpu_id;
+	int			codec_id;
+	char			*platform_name;
+	char			*codec_name;
+	char			*soc_name;
+	struct snd_soc_dai_driver *cpu_dai;
+	int			cpu_num_dais;
+	struct snd_soc_dai_link *dai_link;
+	int			num_dai_links;
+};
+
+int create_device(struct platform_device **device, char *name,
+				void *drv_data);
+
+int get_codec_id(struct codec_id_info *codec);
+
+#endif
+
diff --git a/sound/soc/mid-x86/mid_machine_pvt.c b/sound/soc/mid-x86/mid_machine_pvt.c
new file mode 100644
index 0000000..71ab0e8
--- /dev/null
+++ b/sound/soc/mid-x86/mid_machine_pvt.c
@@ -0,0 +1,81 @@
+/*
+ *  mid_machine_pvt.c - Intel Machine driver private functions
+ *
+ *  Copyright (C) 2010 Intel Corp
+ *  Author: Harsha Priya <priya.harsha at intel.com>
+ *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; 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 <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/initval.h>
+#include <sound/soc.h>
+#include "mid_machine.h"
+#include <asm/intel_scu_ipc.h>
+
+int get_codec_id(struct codec_id_info *codec)
+{
+	u8 value;
+	int ret;
+
+	pr_debug("reg id = %d, reg shift = %d, reg mask = %x\n",
+			codec->reg_addr, codec->shift, codec->mask);
+	ret = intel_scu_ipc_ioread8(codec->reg_addr, &value);
+	if (ret)
+		pr_err("scu ipc read failed to read codec vendor reg\n");
+
+	return (value >> codec->shift) & codec->mask;
+}
+
+int create_device(struct platform_device **device, char *name,
+				void *drv_data)
+{
+	int ret_val = 0;
+
+	pr_debug("%s device creation...", name);
+
+	*device = platform_device_alloc(name, -1);
+	if (!*device) {
+		pr_err("ERR:%s device allocation failed\n", name);
+		return -ENOMEM;
+	}
+
+	if (drv_data)
+		platform_set_drvdata(*device, drv_data);
+
+	ret_val = platform_device_add(*device);
+	if (ret_val) {
+		pr_err("ERR:Unable to add platform device\n");
+		platform_device_put(*device);
+	}
+	pr_debug("%s...created\n", name);
+	return ret_val;
+}
+
+MODULE_DESCRIPTION("ASoC Intel(R) MACHINE pvt module");
+MODULE_AUTHOR("Harsha Priya");
+MODULE_LICENSE("GPL v2");
+
+
diff --git a/sound/soc/mid-x86/mid_machine_table.h b/sound/soc/mid-x86/mid_machine_table.h
new file mode 100644
index 0000000..7038c1d
--- /dev/null
+++ b/sound/soc/mid-x86/mid_machine_table.h
@@ -0,0 +1,154 @@
+/*
+ *  mid_machine_table.h - Intel Machine driver tables for different platform
+ *  codec combination
+ *
+ *  Copyright (C) 2010 Intel Corp
+ *  Author: Harsha Priya <priya.harsha at intel.com>
+ *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; 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 __MID_MACHINE_TABLE_H__
+#define __MID_MACHINE_TABLE_H__
+#include "mid_machine.h"
+
+#define INFO(_cpu_id, _reg_addr, _shift, _mask) \
+	((kernel_ulong_t)&(struct codec_id_info) {	\
+		.cpu_id = (_cpu_id),			\
+		.reg_addr = (_reg_addr),		\
+		.shift = (_shift),			\
+		.mask = (_mask),			\
+	})
+/*MFLD - MSIC*/
+struct snd_soc_dai_driver mfld_dai[] = {
+{
+	.name = "Headset-cpu-dai",
+	.id = 0,
+	.playback = {
+		.channels_min = STEREO,
+		.channels_max = STEREO,
+		.rates = SNDRV_PCM_RATE_48000,
+		.formats = SNDRV_PCM_FMTBIT_S24_LE,
+	},
+},
+{
+	.name = "Speaker-cpu-dai",
+	.id = 1,
+	.playback = {
+		.channels_min = MONO,
+		.channels_max = STEREO,
+		.rates = SNDRV_PCM_RATE_48000,
+		.formats = SNDRV_PCM_FMTBIT_S24_LE,
+	},
+},
+{
+	.name = "Vibra 1-cpu-dai",
+	.id = 2,
+	.playback = {
+		.channels_min = MONO,
+		.channels_max = MONO,
+		.rates = SNDRV_PCM_RATE_48000,
+		.formats = SNDRV_PCM_FMTBIT_S24_LE,
+	},
+},
+{
+	.name = "Vibra 2-cpu-dai",
+	.id = 3,
+	.playback = {
+		.channels_min = MONO,
+		.channels_max = STEREO,
+		.rates = SNDRV_PCM_RATE_48000,
+		.formats = SNDRV_PCM_FMTBIT_S24_LE,
+	},
+},
+};
+
+struct snd_soc_dai_link mfld_msic_dailink[] = {
+	{
+		.name = "Intel MSIC Headset",
+		.stream_name = "Codec",
+		.cpu_dai_name = "Headset-cpu-dai",
+		.codec_dai_name = "Intel MSIC Headset",
+		.codec_name = "mid-msic-codec",
+		.platform_name = "mid-audio-platform",
+		.init = NULL,
+	},
+	{
+		.name = "Intel MSIC Speaker",
+		.stream_name = "Speaker",
+		.cpu_dai_name = "Speaker-cpu-dai",
+		.codec_dai_name = "Intel MSIC Speaker",
+		.codec_name = "mid-msic-codec",
+		.platform_name = "mid-audio-platform",
+		.init = NULL,
+	},
+	{
+		.name = "Intel MSIC Vibra1",
+		.stream_name = "Vibra1",
+		.cpu_dai_name = "Vibra 1-cpu-dai",
+		.codec_dai_name = "Intel MSIC Vibra1",
+		.codec_name = "mid-msic-codec",
+		.platform_name = "mid-audio-platform",
+		.init = NULL,
+	},
+	{
+		.name = "Intel MSIC Vibra2",
+		.stream_name = "Vibra2",
+		.cpu_dai_name = "Vibra 2-cpu-dai",
+		.codec_dai_name = "Intel MSIC Vibra2",
+		.codec_name =  "mid-msic-codec",
+		.platform_name = "mid-audio-platform",
+		.init = NULL,
+	},
+};
+/* MFLD - MSIC END*/
+
+/*add table entry for every platform-codec combination*/
+struct platform_codec_map machine_table[] = {
+	{
+		.cpu_id		= CPU_CHIP_PENWELL,
+		.codec_id	= MSIC_CODEC,
+		.platform_name	= "mid-audio-platform",
+		.codec_name	= "mid-msic-codec",
+		.soc_name	= "mid",
+		.cpu_dai	= mfld_dai,
+		.cpu_num_dais	= ARRAY_SIZE(mfld_dai),
+		.dai_link	= mfld_msic_dailink,
+		.num_dai_links  = ARRAY_SIZE(mfld_msic_dailink),
+		/*the following is exported from your codec file*/
+		/*.codec_dev	= &intel_msic_codec,*/
+		/*.i2c_drv_name	= "mid_virt_i2c_scu", */
+	},
+};
+
+/*driver data
+ ____________
+ * cpu_id,
+ * register addres of codec vendor id,
+ * shift bits to extract vendor id,
+ * mask bits to extract vendor id
+ * */
+static const struct platform_device_id snd_intelmid_ids[] = {
+	{DRIVER_NAME_MRST, INFO(CPU_CHIP_LINCROFT, 0, 0, 0x07)},
+	{DRIVER_NAME_MFLD, INFO(CPU_CHIP_PENWELL, 0, 6, 0x03)},
+	{"", 0},
+};
+
+#endif
+
-- 
1.7.2.3



More information about the Alsa-devel mailing list