Alsa-devel
Threads by month
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
December 2010
- 86 participants
- 327 discussions
29 Dec '10
On Wed, 2010-12-29 at 12:44 +0200, Felipe Balbi wrote:
> Hi,
>
> On Wed, Dec 29, 2010 at 10:35:31AM +0000, Liam Girdwood wrote:
> >> Even though the driver will never work with those other archs, compile
> >> testing with several of them isn't bad at all.
> >
> >This seems unnecessary since this driver is for the OMAP platform only
> >and also means maintainers will have to waste time fixing any build
> >issues for this driver on irrelevant architectures. The costs here
> >outweigh any benefits....
>
> If that's the case, what's the use for linux-next, then ? Drivers should
> be arch independent as much as possible, no ? Isn't that why we don't
> want drivers using branches to things such as machine_is_omap4_panda()
> or similar ?
>
I agree that drivers should be arch independent when possible, but in
this case the OMAP DMIC DAI driver is coupled to the OMAP platform only.
i.e. it performs IO directly on the OMAP DMIC IP. This IP is only found
on OMAP silicon.
I also agree it would be nice if it builds for PXA, MIPS, SuperH etc but
what happens when the driver builds fine for OMAP but breaks the PXA,
MIPS, SuperH build ? Who will spend time to fix and test it ?
My main problem here is cost benefit. No one benefits directly by having
this driver available for the above platforms but it costs me time
fixing it when it breaks.
> But the whole audio part on OMAP is still in a bad shape anyway, e.g.
> mcbsp exports omap-only functions for drivers to use, so this will only
> be yet another driver to the pile :-p
>
In this case though the other McBSP user afaik is DaVinci, so in this
case it does make sense to make this driver support both.
> >It also seems inconsistent with the other OMAP system headers in
> >plat-omap too.
>
> Other than a few drivers which still need converting (and are on their
> way) I can only see really arch-specific bits and pieces under plat/.
>
> Not sure what's your point here.
>
The point is that David had split the DMIC headers into two files, one
for plat specific registers and bit definitions and the other for audio
definitions (for the machine drivers) and is/was consistent with the
current OMAP platform headers.
Liam
--
Freelance Developer, SlimLogic Ltd
ASoC and Voltage Regulator Maintainer.
http://www.slimlogic.co.uk
2
1
29 Dec '10
On Wed, 2010-12-29 at 11:47 +0200, Felipe Balbi wrote:
> Hi,
>
> On Tue, Dec 28, 2010 at 07:13:58PM -0600, Lambert, David wrote:
> >> one blank line only. BTW, are these used anywwhere outside the dmic.c
> >> driver ? If not, it's better to move the definitions there.
> >>
> >
> >They were originally in the omap-dmic.h header, but it was suggested
> >that we move
> >them to a platform header so that the driver could be more
> >architecture independent
> >and we could put the platform specific details here. I'm OK putting
> >them just about
> >anywhere, as long as we have consensus.
>
> The thing I don't like about putting register definitions under
> <plat/*.h> is that it creates the need for making the driver "depends on
> ARCH_OMAP" because it's the only architecture which has that file. If
> you put under <linux/*> or directly on the .c source file, you can have
> a much needed compile test with several architectures.
>
> Even though the driver will never work with those other archs, compile
> testing with several of them isn't bad at all.
This seems unnecessary since this driver is for the OMAP platform only
and also means maintainers will have to waste time fixing any build
issues for this driver on irrelevant architectures. The costs here
outweigh any benefits....
It also seems inconsistent with the other OMAP system headers in
plat-omap too.
Liam
--
Freelance Developer, SlimLogic Ltd
ASoC and Voltage Regulator Maintainer.
http://www.slimlogic.co.uk
1
0
29 Dec '10
On Tue, Dec 28, 2010 at 5:14 AM, Felipe Balbi <balbi(a)ti.com> wrote:
> Hi,
>
> On Mon, Dec 27, 2010 at 10:17:02PM -0600, David Lambert wrote:
>>
>> This patch adds support for the OMAP4 digital microphone DAI.
>>
>> This DAI can support support recording in 2, 4, or 6 channels
>>
>> When provided with a 19.2Mhz functional clock, can encode at 96Khz or
>> 192Khz (all
>> channels must have the same sample rate).
>>
>> Details of the hardware interface can be found in the OMAP4 TRM in Section
>> 23.7
>>
>> Signed-off-by: David Lambert <dlambert(a)ti.com>
>> ---
>> arch/arm/plat-omap/include/plat/dmic.h | 83 +++++
>> sound/soc/omap/omap-dmic.c | 596
>> ++++++++++++++++++++++++++++++++
>> sound/soc/omap/omap-dmic.h | 38 ++
>> 3 files changed, 717 insertions(+), 0 deletions(-)
>> create mode 100644 arch/arm/plat-omap/include/plat/dmic.h
>> create mode 100644 sound/soc/omap/omap-dmic.c
>> create mode 100644 sound/soc/omap/omap-dmic.h
>>
>> diff --git a/arch/arm/plat-omap/include/plat/dmic.h
>> b/arch/arm/plat-omap/include/plat/dmic.h
>> new file mode 100644
>> index 0000000..8a988bf
>> --- /dev/null
>> +++ b/arch/arm/plat-omap/include/plat/dmic.h
>> @@ -0,0 +1,83 @@
>> +/*
>> + * omap-dmic.h -- OMAP Digital Microphone Controller
>> + *
>> + * Author: Liam Girdwood <lrg(a)slimlogic.co.uk>
>> + * David Lambert <dlambert(a)ti.com>
>> + * Misael Lopez Cruz <misael.lopez(a)ti.com>
>> + *
>> + * 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 __ASM_ARCH_OMAP_DMIC_H
>> +#define __ASM_ARCH_OMAP_DMIC_H
>> +
>> +#define OMAP44XX_DMIC_L3_BASE 0x4902e000
>> +
>> +#define OMAP_DMIC_REVISION 0x00
>> +#define OMAP_DMIC_SYSCONFIG 0x10
>> +#define OMAP_DMIC_IRQSTATUS_RAW 0x24
>> +#define OMAP_DMIC_IRQSTATUS 0x28
>> +#define OMAP_DMIC_IRQENABLE_SET 0x2C
>> +#define OMAP_DMIC_IRQENABLE_CLR 0x30
>> +#define OMAP_DMIC_IRQWAKE_EN 0x34
>> +#define OMAP_DMIC_DMAENABLE_SET 0x38
>> +#define OMAP_DMIC_DMAENABLE_CLR 0x3C
>> +#define OMAP_DMIC_DMAWAKEEN 0x40
>> +#define OMAP_DMIC_CTRL 0x44
>> +#define OMAP_DMIC_DATA 0x48
>> +#define OMAP_DMIC_FIFO_CTRL 0x4C
>> +#define OMAP_DMIC_FIFO_DMIC1R_DATA 0x50
>> +#define OMAP_DMIC_FIFO_DMIC1L_DATA 0x54
>> +#define OMAP_DMIC_FIFO_DMIC2R_DATA 0x58
>> +#define OMAP_DMIC_FIFO_DMIC2L_DATA 0x5C
>> +#define OMAP_DMIC_FIFO_DMIC3R_DATA 0x60
>> +#define OMAP_DMIC_FIFO_DMIC3L_DATA 0x64
>> +
>> +/*
>> + * DMIC_IRQ bit fields
>> + * IRQSTATUS_RAW, IRQSTATUS, IRQENABLE_SET, IRQENABLE_CLR
>> + */
>> +
>> +#define OMAP_DMIC_IRQ (1 << 0)
>> +#define OMAP_DMIC_IRQ_FULL (1 << 1)
>> +#define OMAP_DMIC_IRQ_ALMST_EMPTY (1 << 2)
>> +#define OMAP_DMIC_IRQ_EMPTY (1 << 3)
>> +#define OMAP_DMIC_IRQ_MASK 0x07
>> +
>> +/*
>> + * DMIC_DMAENABLE bit fields
>> + */
>> +
>> +#define OMAP_DMIC_DMA_ENABLE 0x1
>> +
>> +/*
>> + * DMIC_CTRL bit fields
>> + */
>> +
>> +#define OMAP_DMIC_UP1_ENABLE 0x0001
>> +#define OMAP_DMIC_UP2_ENABLE 0x0002
>> +#define OMAP_DMIC_UP3_ENABLE 0x0004
>> +#define OMAP_DMIC_FORMAT 0x0008
>> +#define OMAP_DMIC_POLAR1 0x0010
>> +#define OMAP_DMIC_POLAR2 0x0020
>> +#define OMAP_DMIC_POLAR3 0x0040
>> +#define OMAP_DMIC_POLAR_MASK 0x0070
>> +#define OMAP_DMIC_CLK_DIV_SHIFT 7
>> +#define OMAP_DMIC_CLK_DIV_MASK 0x0380
>> +#define OMAP_DMIC_RESET 0x0400
>> +
>> +#define OMAP_DMIC_ENABLE_MASK 0x007
>> +
>> +#define OMAP_DMICOUTFORMAT_LJUST (0 << 3)
>> +#define OMAP_DMICOUTFORMAT_RJUST (1 << 3)
>> +
>> +/*
>> + * DMIC_FIFO_CTRL bit fields
>> + */
>> +
>> +#define OMAP_DMIC_THRES_MAX 0xF
>> +
>> +
>
> one blank line only. BTW, are these used anywwhere outside the dmic.c
> driver ? If not, it's better to move the definitions there.
>
They were originally in the omap-dmic.h header, but it was suggested
that we move
them to a platform header so that the driver could be more
architecture independent
and we could put the platform specific details here. I'm OK putting
them just about
anywhere, as long as we have consensus.
>> +#endif
>> diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c
>> new file mode 100644
>> index 0000000..6ba05bd
>> --- /dev/null
>> +++ b/sound/soc/omap/omap-dmic.c
>> @@ -0,0 +1,596 @@
>> +/*
>> + * omap-dmic.c -- OMAP ASoC DMIC DAI driver
>> + *
>> + * Copyright (C) 2010 Texas Instruments
>> + *
>> + * Author: Liam Girdwood <lrg(a)slimlogic.co.uk>
>> + * David Lambert <dlambert(a)ti.com>
>> + * Misael Lopez Cruz <misael.lopez(a)ti.com>
>> + *
>> + * 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.
>> + *
>> + * 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., 51 Franklin St, Fifth Floor, Boston, MA
>> + * 02110-1301 USA
>> + *
>> + */
>> +
>> +#undef DEBUG
>> +
>> +#include <linux/init.h>
>> +#include <linux/module.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/wait.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/err.h>
>> +#include <linux/clk.h>
>> +#include <linux/delay.h>
>> +#include <linux/io.h>
>> +#include <linux/irq.h>
>> +#include <linux/slab.h>
>> +#include <linux/pm_runtime.h>
>> +
>> +#include <plat/control.h>
>> +#include <plat/dma.h>
>> +#include <plat/dmic.h>
>> +#include <plat/omap_hwmod.h>
>
> I'm not sure drivers should be including these (besides dmic.h which you
> added). plat/control.h doesn't even exist anymore and hwmod is supposed
> to live under mach-omap*/ only.
>
>> +#include <sound/core.h>
>> +#include <sound/pcm.h>
>> +#include <sound/pcm_params.h>
>> +#include <sound/initval.h>
>> +#include <sound/soc.h>
>> +
>> +#include "omap-dmic.h"
>> +#include "omap-pcm.h"
>
> These little guys here look rather small to deserve being split to
> separate files. Also, it looks like they're only used by this driver
> (??) so it's better to move the definitions to this C source file
> instead.
Agreed, see comment above about the location of the macros for the
registers. If we agree it belongs in the platform header, we can collapse
the content of omap-dmic.h in to the C source file. If we don't think they
belong in a platform header, they can come back here and then it won't
be quite so little.
>
>> +static struct omap_dmic_link omap_dmic_link = {
>
> const ?
>
>> + .irq_mask = OMAP_DMIC_IRQ_EMPTY | OMAP_DMIC_IRQ_FULL,
>> + .threshold = 2,
>> + .format = OMAP_DMICOUTFORMAT_LJUST,
>> + .polar = OMAP_DMIC_POLAR1 | OMAP_DMIC_POLAR2
>> + | OMAP_DMIC_POLAR3,
>> +};
>> +
>> +/*
>> + * Stream DMA parameters
>> + */
>> +static struct omap_pcm_dma_data omap_dmic_dai_dma_params = {
>
> const ?
>
>> + .name = "DMIC capture",
>> + .data_type = OMAP_DMA_DATA_TYPE_S32,
>> + .sync_mode = OMAP_DMA_SYNC_PACKET,
>> + .packet_size = 2,
>> + .port_addr = OMAP44XX_DMIC_L3_BASE + OMAP_DMIC_DATA,
>> +};
>> +
>> +
>
> one blank line only.
>
>> +#ifdef DEBUG
>> +static void omap_dmic_reg_dump(struct omap_dmic *dmic)
>> +{
>> + dev_dbg(dmic->dev, "***********************\n");
>> + dev_dbg(dmic->dev, "OMAP_DMIC_IRQSTATUS_RAW: 0x%04x\n",
>> + omap_dmic_read(dmic, OMAP_DMIC_IRQSTATUS_RAW));
>> + dev_dbg(dmic->dev, "OMAP_DMIC_IRQSTATUS: 0x%04x\n",
>> + omap_dmic_read(dmic, OMAP_DMIC_IRQSTATUS));
>> + dev_dbg(dmic->dev, "OMAP_DMIC_IRQENABLE_SET: 0x%04x\n",
>> + omap_dmic_read(dmic, OMAP_DMIC_IRQENABLE_SET));
>> + dev_dbg(dmic->dev, "OMAP_DMIC_IRQENABLE_CLR: 0x%04x\n",
>> + omap_dmic_read(dmic, OMAP_DMIC_IRQENABLE_CLR));
>> + dev_dbg(dmic->dev, "OMAP_DMIC_IRQWAKE_EN: 0x%04x\n",
>> + omap_dmic_read(dmic, OMAP_DMIC_IRQWAKE_EN));
>> + dev_dbg(dmic->dev, "OMAP_DMIC_DMAENABLE_SET: 0x%04x\n",
>> + omap_dmic_read(dmic, OMAP_DMIC_DMAENABLE_SET));
>> + dev_dbg(dmic->dev, "OMAP_DMIC_DMAENABLE_CLR: 0x%04x\n",
>> + omap_dmic_read(dmic, OMAP_DMIC_DMAENABLE_CLR));
>> + dev_dbg(dmic->dev, "OMAP_DMIC_DMAWAKEEN: 0x%04x\n",
>> + omap_dmic_read(dmic, OMAP_DMIC_DMAWAKEEN));
>> + dev_dbg(dmic->dev, "OMAP_DMIC_CTRL: 0x%04x\n",
>> + omap_dmic_read(dmic, OMAP_DMIC_CTRL));
>> + dev_dbg(dmic->dev, "OMAP_DMIC_DATA: 0x%04x\n",
>> + omap_dmic_read(dmic, OMAP_DMIC_DATA));
>> + dev_dbg(dmic->dev, "OMAP_DMIC_FIFO_CTRL: 0x%04x\n",
>> + omap_dmic_read(dmic, OMAP_DMIC_FIFO_CTRL));
>> + dev_dbg(dmic->dev, "OMAP_DMIC_FIFO_DMIC1R_DATA: 0x%08x\n",
>> + omap_dmic_read(dmic, OMAP_DMIC_FIFO_DMIC1R_DATA));
>> + dev_dbg(dmic->dev, "OMAP_DMIC_FIFO_DMIC1L_DATA: 0x%08x\n",
>> + omap_dmic_read(dmic, OMAP_DMIC_FIFO_DMIC1L_DATA));
>> + dev_dbg(dmic->dev, "OMAP_DMIC_FIFO_DMIC2R_DATA: 0x%08x\n",
>> + omap_dmic_read(dmic, OMAP_DMIC_FIFO_DMIC2R_DATA));
>> + dev_dbg(dmic->dev, "OMAP_DMIC_FIFO_DMIC2L_DATA: 0x%08x\n",
>> + omap_dmic_read(dmic, OMAP_DMIC_FIFO_DMIC2L_DATA));
>> + dev_dbg(dmic->dev, "OMAP_DMIC_FIFO_DMIC3R_DATA: 0x%08x\n",
>> + omap_dmic_read(dmic, OMAP_DMIC_FIFO_DMIC3R_DATA));
>> + dev_dbg(dmic->dev, "OMAP_DMIC_FIFO_DMIC3L_DATA: 0x%08x\n",
>> + omap_dmic_read(dmic, OMAP_DMIC_FIFO_DMIC3L_DATA));
>> + dev_dbg(dmic->dev, "***********************\n");
>> +}
>> +#else
>> +static void omap_dmic_reg_dump(struct omap_dmic *dmic) {}
>> +#endif
>
> Would be better to make a debugfs layer ??
I'll look in to what it would take to do this. Could this be a
feature to add later?
>
>> +static irqreturn_t omap_dmic_irq_handler(int irq, void *dev_id)
>> +{
>> + struct omap_dmic *dmic = dev_id;
>> + u32 irq_status;
>> +
>> + irq_status = omap_dmic_read(dmic, OMAP_DMIC_IRQSTATUS);
>> +
>> + /* Acknowledge irq event */
>> + omap_dmic_write(dmic, OMAP_DMIC_IRQSTATUS, irq_status);
>> + if (irq_status & OMAP_DMIC_IRQ_FULL)
>> + dev_dbg(dmic->dev, "DMIC FIFO error %x\n", irq_status);
>> +
>> + if (irq_status & OMAP_DMIC_IRQ_EMPTY)
>> + dev_dbg(dmic->dev, "DMIC FIFO error %x\n", irq_status);
>> +
>> + if (irq_status & OMAP_DMIC_IRQ)
>> + dev_dbg(dmic->dev, "DMIC write request\n");
>
> no locking needed ??
>
>> +static int omap_dmic_dai_startup(struct snd_pcm_substream *substream,
>> + struct snd_soc_dai *dai)
>> +{
>> + struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
>> +
>> + if (!dmic->active++)
>> + pm_runtime_get_sync(dmic->dev);
>> +
>> + return 0;
>> +}
>> +
>> +static void omap_dmic_dai_shutdown(struct snd_pcm_substream *substream,
>> + struct snd_soc_dai *dai)
>> +{
>> + struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
>> +
>> + if (!--dmic->active)
>> + pm_runtime_put_sync(dmic->dev);
>
> I could be wrong but I believe pm_runtime implementation on OMAP has
> its own refcounting, so you could drop the need for dmic->active.
This was a included for a future use case where the driver would be
accessed by the
Audio Back End. In this case, there are multiple DAI's associated to
this driver and
we need to keep track of the number of active DAI's and only cal
pm_runtime_put_sync()
when there are no others running.
>
>> +static struct snd_soc_dai_ops omap_dmic_dai_ops = {
>
> should this be const ?
>
>> +static struct snd_soc_dai_driver omap_dmic_dai = {
>
> this too ??
>
>> +static __devinit int asoc_dmic_probe(struct platform_device *pdev)
>> +{
>> + struct omap_dmic *dmic;
>> + struct resource *res;
>> + int ret;
>> +
>> + dmic = kzalloc(sizeof(struct omap_dmic), GFP_KERNEL);
>> + if (!dmic)
>> + return -ENOMEM;
>> +
>> + platform_set_drvdata(pdev, dmic);
>> + dmic->dev = &pdev->dev;
>> + dmic->link = &omap_dmic_link;
>> + dmic->sysclk = OMAP_DMIC_SYSCLK_SYNC_MUX_CLKS;
>> +
>> + spin_lock_init(&dmic->lock);
>> +
>> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> + if (!res) {
>> + dev_err(dmic->dev, "invalid memory resource\n");
>> + ret = -ENODEV;
>> + goto err_res;
>> + }
>> +
>> + dmic->io_base = ioremap(res->start, resource_size(res));
>> + if (!dmic->io_base) {
>> + ret = -ENOMEM;
>> + goto err_res;
>> + }
>> +
>> + dmic->irq = platform_get_irq(pdev, 0);
>> + if (dmic->irq < 0) {
>> + ret = dmic->irq;
>> + goto err_irq;
>> + }
>> +
>> + res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
>> + if (!res) {
>> + dev_err(dmic->dev, "invalid dma resource\n");
>> + ret = -ENODEV;
>> + goto err_irq;
>> + }
>> + omap_dmic_dai_dma_params.dma_req = res->start;
>> +
>> + pm_runtime_enable(dmic->dev);
>> +
>> + /* Disable lines while request is ongoing */
>> + omap_dmic_write(dmic, OMAP_DMIC_CTRL, 0x00);
>> +
>> + ret = request_threaded_irq(dmic->irq, NULL, omap_dmic_irq_handler,
>> + IRQF_ONESHOT, "DMIC", (void *)dmic);
>
> Does this need to be threaded ? Doesn't look like. Also, you don't need
> the (void *) cast.
This was originally not a threaded IRQ handler. But in an internal
review, it was
suggested that this was the current trend in drivers and I should
follow that course.
I'm open to having it non-threaded.
>
>> +static int __devexit asoc_dmic_remove(struct platform_device *pdev)
>> +{
>> + struct omap_dmic *dmic = platform_get_drvdata(pdev);
>> +
>> + snd_soc_unregister_dai(&pdev->dev);
>> + free_irq(dmic->irq, dmic);
>> + iounmap(dmic->io_base);
>> + kfree(dmic);
>
> pm_runtime_disable() ??
>
> --
> balbi
>
--
David Lambert
OMAP™ Multimedia
214-567-5692
1
0
[alsa-devel] [PATCH 0/9 v2] ASoC: codecs: Fix register cache incoherencies
by Lars-Peter Clausen 29 Dec '10
by Lars-Peter Clausen 29 Dec '10
29 Dec '10
The multi-component patch(commit f0fba2ad1) moved the allocation of the
register cache from the driver to the ASoC core. Most drivers where adjusted to
this, but there are also some drivers now which use a mixture of their own
register cache and the generic register cache.
Thus these end up with two from each other incoherent register caches, which can
lead to undefined behaviour.
This patch series tries to fix these drivers by converting them to always use
the generic register cache framework instead of their own.
There are also quite a few drivers left, which do not use their own register
cache anymore, but still have a field for it in their private device structure.
The first patch of this series addresses those drivers and removes the unused
register cache arrays from their private device structs.
Please note, these patches, with the exception of wm8753, were only compile
tested.
Changes since v1:
* rebased against 2.6.37-rc7
* correct commit message
* more straight forward conversion in the wm8753 patch (there will be a
followup patch for cleanps)
- Lars
Lars-Peter Clausen (9):
ASoC: codecs: Remove unused reg_cache fields from device structs
ASoC: codecs: max98088: Fix register cache incoherency
ASoC: codecs: wm8523: Fix register cache incoherency
ASoC: codecs: wm8741: Fix register cache incoherency
ASoC: codecs: wm8904: Fix register cache incoherency
ASoC: codecs: wm8955: Fix register cache incoherency
ASoC: codecs: wm8962: Fix register cache incoherency
ASoC: codecs: wm9090: Fix register cache incoherency
ASoC: codecs: wm8753: Fix register cache incoherency
sound/soc/codecs/88pm860x-codec.c | 1 -
sound/soc/codecs/ad193x.c | 1 -
sound/soc/codecs/ak4671.c | 1 -
sound/soc/codecs/cs4270.c | 1 -
sound/soc/codecs/cs42l51.c | 1 -
sound/soc/codecs/cx20442.c | 1 -
sound/soc/codecs/max98088.c | 13 +-
sound/soc/codecs/tlv320aic26.c | 4 +-
sound/soc/codecs/uda1380.c | 1 -
sound/soc/codecs/wm8523.c | 9 +-
sound/soc/codecs/wm8580.c | 1 -
sound/soc/codecs/wm8711.c | 1 -
sound/soc/codecs/wm8731.c | 1 -
sound/soc/codecs/wm8741.c | 10 +-
sound/soc/codecs/wm8750.c | 1 -
sound/soc/codecs/wm8753.c | 267 ++++++++++++++-----------------------
sound/soc/codecs/wm8900.c | 1 -
sound/soc/codecs/wm8903.c | 2 -
sound/soc/codecs/wm8904.c | 37 +++---
sound/soc/codecs/wm8940.c | 1 -
sound/soc/codecs/wm8955.c | 30 ++--
sound/soc/codecs/wm8960.c | 1 -
sound/soc/codecs/wm8961.c | 1 -
sound/soc/codecs/wm8962.c | 45 +++----
sound/soc/codecs/wm8974.c | 1 -
sound/soc/codecs/wm8978.c | 1 -
sound/soc/codecs/wm8988.c | 1 -
sound/soc/codecs/wm8993.c | 1 -
sound/soc/codecs/wm9081.c | 1 -
sound/soc/codecs/wm9090.c | 18 ++--
30 files changed, 179 insertions(+), 276 deletions(-)
--
1.7.2.3
2
13
[alsa-devel] [PATCH] ASoC: codecs: Add missing control_type initialization
by Lars-Peter Clausen 29 Dec '10
by Lars-Peter Clausen 29 Dec '10
29 Dec '10
Some codec drivers do not initialize the control_type field in their private
device struct, but still use it when calling snd_soc_codec_set_cache_io.
This patch fixes the issue by properly initializing it in the drivers probe
functions.
Signed-off-by: Lars-Peter Clausen <lars(a)metafoo.de>
---
Compile tested only
---
sound/soc/codecs/wm8940.c | 1 +
sound/soc/codecs/wm8955.c | 1 +
sound/soc/codecs/wm8960.c | 1 +
sound/soc/codecs/wm8971.c | 1 +
sound/soc/codecs/wm9081.c | 1 +
5 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index f8c33b6..a2c788f 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -767,6 +767,7 @@ static __devinit int wm8940_i2c_probe(struct i2c_client *i2c,
i2c_set_clientdata(i2c, wm8940);
wm8940->control_data = i2c;
+ wm8940->control_type = SND_SOC_I2C;
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm8940, &wm8940_dai, 1);
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
index fdc7c8a..2ac35b0 100644
--- a/sound/soc/codecs/wm8955.c
+++ b/sound/soc/codecs/wm8955.c
@@ -1003,6 +1003,7 @@ static __devinit int wm8955_i2c_probe(struct i2c_client *i2c,
return -ENOMEM;
i2c_set_clientdata(i2c, wm8955);
+ wm8955->control_type = SND_SOC_I2C;
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm8955, &wm8955_dai, 1);
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index 6983502..4a99b766 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -1012,6 +1012,7 @@ static __devinit int wm8960_i2c_probe(struct i2c_client *i2c,
return -ENOMEM;
i2c_set_clientdata(i2c, wm8960);
+ wm8960->control_type = SND_SOC_I2C;
wm8960->control_data = i2c;
ret = snd_soc_register_codec(&i2c->dev,
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index 63f6dbf..9f18db6 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -718,6 +718,7 @@ static __devinit int wm8971_i2c_probe(struct i2c_client *i2c,
if (wm8971 == NULL)
return -ENOMEM;
+ wm8971->control_type = SND_SOC_I2C;
i2c_set_clientdata(i2c, wm8971);
ret = snd_soc_register_codec(&i2c->dev,
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index 11018e2..badc8ee 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -1334,6 +1334,7 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c,
return -ENOMEM;
i2c_set_clientdata(i2c, wm9081);
+ wm9081->control_type = SND_SOC_I2C;
wm9081->control_data = i2c;
ret = snd_soc_register_codec(&i2c->dev,
--
1.7.2.3
2
1
Hi,
In my driver I have specified that the hardware supports only two channels.
However, if I try playing mono input files on this system I get:
Playing WAVE 'test.wav' : Unsigned 8 bit, Rate 22050 Hz, Mono
aplay: set_params:1041: Unable to install hw params:
ACCESS: RW_INTERLEAVED
FORMAT: U8
SUBFORMAT: STD
SAMPLE_BITS: 8
FRAME_BITS: 8
CHANNELS: 1
RATE: 22050
PERIOD_TIME: (371519 371520)
PERIOD_SIZE: 8192
PERIOD_BYTES: 8192
PERIODS: 4
BUFFER_TIME: (1486077 1486078)
BUFFER_SIZE: 32768
BUFFER_BYTES: 32768
TICK_TIME: 0
If I try playing the same file through the virtual device that I specified
in asoundrc file like this:
pcm.mydev {
type plug
slave {
pcm default
channels 2
}
}
and I do aplay -Dmydev test.wav
File plays no problem.
I guess the question is shouldn't ALSA convert this data automatically or
the only way to get this to work is through plugin as I did?
Cheers
Ogi
1
0
[alsa-devel] Why is SND_PCM_FORMAT_S32_LE not able to be set and passed to Linux Kernel Asoc?
by Philip Chu 28 Dec '10
by Philip Chu 28 Dec '10
28 Dec '10
Hi all ALSA experts,
I am seeing a weird behavior of ALSA API lib 1.0.23, i.e., when I use SND_PCM_FORMAT_S32_LE, I am seeing that the data format is still configured as SND_PCM_FORMAT_S16_LE and passed to kernel driver layer.
The code I am using is shown below:
====================================================================================
snd_pcm_t *capture_handle;
rc = snd_pcm_open(&capture_handle, devName, SND_PCM_STREAM_CAPTURE, 0 /*SND_PCM_NONBLOCK*/); /* */
if (rc < 0) {
fprintf(stderr, "unable to open pcm device: %s\n", snd_strerror(rc));
exit(1);
}
/* Allocate a hardware parameters object. */
snd_pcm_hw_params_malloc(&hw_params);
/* Fill it in with default values. */
snd_pcm_hw_params_any(capture_handle, hw_params);
/* Set the desired hardware parameters. */
/* Interleaved mode 2-channel*/
snd_pcm_hw_params_set_access(capture_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); /* each frame left->right->left->right */
/* Signed 32-bit little-endian format */
snd_pcm_hw_params_set_format(capture_handle, hw_params, SND_PCM_FORMAT_S32_LE);
//snd_pcm_hw_params_set_format(HANDLE(direction), hw_params, SND_PCM_FORMAT_S16_LE);
/* Two channels (stereo) */
if( (rc=snd_pcm_hw_params_set_channels(capture_handle, hw_params, 2))<0) {
fprintf(stderr, "cannot set channel count 2\n");
exit(1);
}
int sample_rate = rate; /* The sample rate is 50000 */
snd_pcm_hw_params_set_rate_near(capture_handle, hw_params, &sample_rate, &dir);
if (sample_rate != rate) {
fprintf(stderr, "The rate %d Hz is not supported by your hardware.\n ==> Using %d Hz instead.\n", rate, sample_rate);
}
frames = 32;
/* Set period size to 32 frames. */
snd_pcm_hw_params_set_period_size_near(capture_handle, hw_params, &frames, &dir);
int periods = 2; /* Number of periods */
snd_pcm_uframes_t buffersize = periods*frames; /* Periodsize (bytes) */
/* Set buffer size (in frames). The resulting latency is given by */
/* latency = periodsize * periods / (rate * bytes_per_frame) */
if (snd_pcm_hw_params_set_buffer_size(capture_handle, hw_params, buffersize) < 0) { /* 2 period as buffer size*/
fprintf(stderr, "Error setting buffersize.\n");
return(-1);
}
/* Write the parameters to the driver */
rc = snd_pcm_hw_params(capture_handle, hw_params); /* call into kernel snd_pcm_common_ioctl1 */
if (rc < 0) {
fprintf(stderr, "unable to set hw parameters: %s\n", snd_strerror(rc));
exit(1);
}
Unsigned long buffer[1024];
memset(buffer, 0x0, sizeof(buffer)); /* Pre-set the data */
/* Start data transmission now */
/* Returns the number of frames actually written. */
snd_pcm_prepare(capture_handle); /* Need this if there are too many printf lines to interrupt the process */
/* Start receiving data from FPGA now */
/* Returns the number of frames actually read. */
rc = snd_pcm_readi(handle, buffer, frames);
The data read back looks like 0x????0000, which only has half content of 32-bit format.
Is there anything wrong with my code?
Any help will be appreciated.
3
5
From: Vinod Koul <vinod.koul(a)intel.com>
This patch adds the msic asoc codec driver. This driver currently supports only playback.
Capture and jack detection to be added later
Signed-off-by: Vinod Koul <vinod.koul(a)intel.com>
Signed-off-by: Harsha Priya <priya.harsha(a)intel.com>
---
sound/soc/codecs/msic.c | 721 +++++++++++++++++++++++++++++++++++++++++++++++
sound/soc/codecs/msic.h | 102 +++++++
2 files changed, 823 insertions(+), 0 deletions(-)
create mode 100644 sound/soc/codecs/msic.c
create mode 100644 sound/soc/codecs/msic.h
diff --git a/sound/soc/codecs/msic.c b/sound/soc/codecs/msic.c
new file mode 100644
index 0000000..f90f698
--- /dev/null
+++ b/sound/soc/codecs/msic.c
@@ -0,0 +1,721 @@
+/*
+ * msic.c - Intel MSIC Codec driver
+ *
+ * Copyright (C) 2010 Intel Corp
+ * Author: Vinod Koul <vinod.koul(a)intel.com>
+ * Author: Harsha Priya <priya.harsha(a)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) "sst: msic " fmt
+
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <asm/intel_scu_ipc.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+#include "msic.h"
+
+#define MSIC_RATES (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100)
+#define MSIC_FORMATS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
+
+/*
+ * todo:
+ * capture paths
+ * jack detection
+ * PM functions
+ */
+
+struct intel_msic_pvt {
+ struct snd_soc_codec *codec;
+ unsigned int hs_switch;
+ unsigned int lo_dac;
+};
+
+static inline unsigned int msic_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);
+ pr_debug("read for %x ret %x\n", reg, value);
+ return value;
+
+}
+
+static inline int msic_write(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int value)
+{
+ int ret;
+
+ pr_debug("write for %x with %x\n", reg, value);
+ ret = intel_scu_ipc_iowrite8(reg, value);
+ if (ret)
+ pr_err("write of %x failed, err %d\n", reg, ret);
+ return ret;
+}
+
+static inline int msic_modify(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int value, unsigned int mask)
+{
+ int ret;
+
+ pr_debug("Modify for %x with %x of mask %x\n", reg, value, mask);
+ ret = intel_scu_ipc_update_register(reg, value, mask);
+ if (ret)
+ pr_err("modify of %x failed, err %d\n", reg, ret);
+ return ret;
+}
+
+/*sound controls*/
+static const char *headset_switch_text[] = {"Earpiece", "HeadSet"};
+
+static const char *mic_switch_text[] = {"DMIC", "AMIC"};
+
+static const char *msic_lo_text[] = {"Vibra", "Headset", "IHF", "None"};
+
+static const unsigned int mic_switch_values[] = {0x76, 0x10};
+
+static const struct soc_enum msic_headset_enum =
+ SOC_ENUM_SINGLE_EXT(2, headset_switch_text);
+
+static const struct soc_enum msic_lo_enum =
+ SOC_ENUM_SINGLE_EXT(4, msic_lo_text);
+
+static int headset_get_switch(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct intel_msic_pvt *msic = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.integer.value[0] = msic->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);
+ struct intel_msic_pvt *msic = snd_soc_codec_get_drvdata(codec);
+
+ if (ucontrol->value.integer.value[0] == msic->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);
+ msic->hs_switch = ucontrol->value.integer.value[0];
+
+ return 0;
+}
+
+static void msic_lo_enable_out_pins(struct snd_soc_codec *codec)
+{
+ struct intel_msic_pvt *msic = snd_soc_codec_get_drvdata(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 (msic->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");
+ }
+ return;
+}
+
+static int lo_get_switch(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct intel_msic_pvt *msic = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.integer.value[0] = msic->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);
+ struct intel_msic_pvt *msic = snd_soc_codec_get_drvdata(codec);
+
+ if (ucontrol->value.integer.value[0] == msic->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
+ */
+ msic_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");
+ msic_modify(codec, MSIC_LOCTL, 0, 0x66);
+ 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");
+ msic_modify(codec, MSIC_LOCTL, 0x22, 0x66);
+ 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");
+ msic_modify(codec, MSIC_LOCTL, 0x44, 0x66);
+ 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");
+ msic_modify(codec, MSIC_LOCTL, 0x66, 0x66);
+ break;
+ }
+ snd_soc_dapm_sync(&codec->dapm);
+ msic->lo_dac = ucontrol->value.integer.value[0];
+ return 0;
+}
+
+static const struct soc_enum msic_mic_enum =
+ SOC_VALUE_ENUM_SINGLE(MSIC_AUDIOMUX12, 0, 0x76,
+ ARRAY_SIZE(mic_switch_text),
+ mic_switch_text,
+ mic_switch_values);
+
+
+static const struct snd_kcontrol_new intel_msic_snd_controls[] = {
+ SOC_ENUM_EXT("Playback Switch", msic_headset_enum,
+ headset_get_switch, headset_set_switch),
+ SOC_VALUE_ENUM("Capture Switch", msic_mic_enum),
+ SOC_ENUM_EXT("Lineout Mux", msic_lo_enum,
+ lo_get_switch, lo_set_switch),
+};
+
+static const struct snd_kcontrol_new msic_driver_controls[] = {
+ SOC_DAPM_SINGLE("Headset_L", MSIC_DRIVEREN, 0, 1, 0),
+ SOC_DAPM_SINGLE("Headset_R", MSIC_DRIVEREN, 1, 1, 0),
+ SOC_DAPM_SINGLE("Speaker_L", MSIC_DRIVEREN, 2, 1, 0),
+ SOC_DAPM_SINGLE("Speaker_R", MSIC_DRIVEREN, 3, 1, 0),
+ SOC_DAPM_SINGLE("Vibra1", MSIC_DRIVEREN, 4, 1, 0),
+ SOC_DAPM_SINGLE("Vibra2", MSIC_DRIVEREN, 5, 1, 0),
+ SOC_DAPM_SINGLE("Earpiece", MSIC_DRIVEREN, 6, 1, 0),
+ SOC_DAPM_SINGLE("Lineout_L", MSIC_LOCTL, 0, 1, 0),
+ SOC_DAPM_SINGLE("Lineout_R", MSIC_LOCTL, 4, 1, 0),
+};
+
+static int msic_set_vaud_bias(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ pr_debug("msic_set_vaud_bias %d\n", level);
+ switch (level) {
+ case SND_SOC_BIAS_PREPARE:
+ case SND_SOC_BIAS_STANDBY:
+ break;
+
+ case SND_SOC_BIAS_ON:
+ pr_debug("vaud_bias doing rail statup now\n");
+ /*power up the rail*/
+ msic_write(codec, MSIC_VAUD, BIT(2)|BIT(1)|BIT(0));
+ msleep(1);
+ /*power up the pll*/
+ msic_write(codec, MSIC_AUDPLLCTRL, BIT(5));
+ /*adding pcm 2 here for a while*/
+ msic_modify(codec, MSIC_PCM2C2, BIT(0), BIT(0));
+ break;
+
+ case SND_SOC_BIAS_OFF:
+ pr_debug("vaud_bias doing rail shutdown\n");
+ msic_modify(codec, MSIC_PCM2C2, 0, BIT(0));
+ msic_write(codec, MSIC_AUDPLLCTRL, 0);
+ msleep(1);
+ msic_write(codec, MSIC_VAUD, BIT(3));
+ }
+
+ codec->dapm.bias_level = level;
+ return 0;
+}
+
+static int msic_vhs_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ pr_debug("msic_vhs_event %d\n", event);
+ if (event == SND_SOC_DAPM_PRE_PMU) {
+ pr_debug("VHS SND_SOC_DAPM_PRE_PMU doing rail statup now\n");
+ /*power up the rail*/
+ msic_write(w->codec, MSIC_VHSP, 0x3D);
+ msic_write(w->codec, MSIC_VHSN, 0x3F);
+ msleep(1);
+ /*power up the pll*/
+ } else if (event == SND_SOC_DAPM_POST_PMD) {
+ pr_debug("VHS SND_SOC_DAPM_POST_PMD doing rail shutdown\n");
+ msic_write(w->codec, MSIC_VHSP, 0xC4);
+ msic_write(w->codec, MSIC_VHSN, 0x04);
+ }
+
+ return 0;
+}
+
+static int msic_vihf_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ pr_debug("msic_vihf_event %d\n", event);
+ if (event == SND_SOC_DAPM_PRE_PMU) {
+ pr_debug("VIHF SND_SOC_DAPM_PRE_PMU doing rail statup now\n");
+ /*power up the rail*/
+ msic_write(w->codec, MSIC_VIHF, 0x27);
+ msleep(1);
+ /*power up the pll*/
+ } else if (event == SND_SOC_DAPM_POST_PMD) {
+ pr_debug("VIHF SND_SOC_DAPM_POST_PMD doing rail shutdown\n");
+ msic_write(w->codec, MSIC_VIHF, 0x24);
+ }
+
+ return 0;
+}
+
+/*DAPM widgets*/
+static const struct snd_soc_dapm_widget intel_msic_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_INPUT("DMIC"),
+ SND_SOC_DAPM_INPUT("AMIC2"),
+ SND_SOC_DAPM_INPUT("HSMIC"), /*AMIC1 is this case*/
+
+ SND_SOC_DAPM_SUPPLY("Headset Rail", SND_SOC_NOPM, 0, 0,
+ msic_vhs_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_SUPPLY("Speaker Rail", SND_SOC_NOPM, 0, 0,
+ msic_vihf_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ /*playback paths speaker, dac, filter, rx selector*/
+ SND_SOC_DAPM_SWITCH("Headset Left Playback",
+ MSIC_DRIVEREN, 0, 0, &msic_driver_controls[0]),
+ SND_SOC_DAPM_SWITCH("Headset Right Playback",
+ MSIC_DRIVEREN, 1, 0, &msic_driver_controls[1]),
+ SND_SOC_DAPM_SWITCH("Speaker Left Playback",
+ MSIC_DRIVEREN, 2, 0, &msic_driver_controls[2]),
+ SND_SOC_DAPM_SWITCH("Speaker Right Playback",
+ MSIC_DRIVEREN, 3, 0, &msic_driver_controls[3]),
+ SND_SOC_DAPM_SWITCH("Vibra1 Playback",
+ MSIC_DRIVEREN, 4, 0, &msic_driver_controls[4]),
+ SND_SOC_DAPM_SWITCH("Vibra2 Playback",
+ MSIC_DRIVEREN, 5, 0, &msic_driver_controls[5]),
+ SND_SOC_DAPM_SWITCH("Earpiece Playback",
+ MSIC_DRIVEREN, 6, 0, &msic_driver_controls[6]),
+ SND_SOC_DAPM_SWITCH("Lineout Left Playback",
+ MSIC_LOCTL, 0, 0, &msic_driver_controls[7]),
+ SND_SOC_DAPM_SWITCH("Lineout Right Playback",
+ MSIC_LOCTL, 4, 0, &msic_driver_controls[8]),
+
+ /* DACs */
+ SND_SOC_DAPM_DAC("HSDAC Left", "HeadSet",
+ MSIC_DACCONFIG, 0, 0),
+ SND_SOC_DAPM_DAC("HSDAC Right", "HeadSet",
+ MSIC_DACCONFIG, 1, 0),
+ SND_SOC_DAPM_DAC("IHFDAC Left", "Speaker",
+ MSIC_DACCONFIG, 2, 0),
+ SND_SOC_DAPM_DAC("IHFDAC Right", "Speaker",
+ MSIC_DACCONFIG, 3, 0),
+ SND_SOC_DAPM_DAC("Vibra1 DAC", "Vibra1",
+ MSIC_VIB1C5, 1, 0),
+ SND_SOC_DAPM_DAC("Vibra2 DAC", "Vibra2",
+ MSIC_VIB2C5, 1, 0),
+
+ /*SND_SOC_DAPM_MICBIAS("Mic Bias", MICBIAS, 0, 0),*/
+};
+
+static const struct snd_soc_dapm_route msic_audio_map[] = {
+ /*headset and earpiece map*/
+ { "HPOUTL", NULL, "Headset Left Playback" },
+ { "HPOUTR", NULL, "Headset Right Playback" },
+ { "EPOUT", NULL, "Earpiece Playback" },
+ { "Headset Left Playback", NULL, "HSDAC Left"},
+ { "Headset Right Playback", NULL, "HSDAC Right"},
+ { "Earpiece Playback", NULL, "HSDAC Left"},
+ { "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, "IHFDAC Left"},
+ { "Speaker Right Playback", 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, "IHFDAC Left"},
+ {"Lineout Left Playback", NULL, "HSDAC Left"},
+ {"Lineout Left Playback", NULL, "Vibra1 DAC"},
+ {"Lineout Right Playback", NULL, "IHFDAC Right"},
+ {"Lineout Right Playback", NULL, "HSDAC Right"},
+ {"Lineout Right Playback", NULL, "Vibra2 DAC"},
+};
+
+static int msic_pcm_hs_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ pr_debug("pcm hs startup for %d\n", substream->pcm->device);
+
+ /*configure digital reciever here, add to DAPM later on*/
+ msic_write(dai->codec, MSIC_HSMIXER, BIT(0)|BIT(4));
+ msic_write(dai->codec, MSIC_HSEPRXCTRL, BIT(5)|BIT(4));
+
+ return 0;
+}
+
+static void msic_pcm_hs_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ pr_debug("pcm hs shutdown\n");
+ msic_write(dai->codec, MSIC_HSEPRXCTRL, 0);
+ return ;
+}
+
+static int msic_pcm_hs_mute(struct snd_soc_dai *dai, int mute)
+{
+ msic_modify(dai->codec, MSIC_HSLVOLCTRL, (!mute << 7), BIT(7));
+ msic_modify(dai->codec, MSIC_HSRVOLCTRL, (!mute << 7), BIT(7));
+ return 0;
+}
+
+static int msic_pcm_spkr_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ pr_debug("pcm spkr startup for %d\n", substream->pcm->device);
+ msic_modify(dai->codec, MSIC_IHFRXCTRL, BIT(0)|BIT(1), BIT(0)|BIT(1));
+ return 0;
+
+}
+
+static void msic_pcm_spkr_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ pr_debug("pcm spkr shutdown\n");
+ msic_modify(dai->codec, MSIC_IHFRXCTRL, 0, BIT(0)|BIT(1));
+ return;
+}
+
+static int msic_pcm_spkr_mute(struct snd_soc_dai *dai, int mute)
+{
+ msic_modify(dai->codec, MSIC_IHFLVOLCTRL, (!mute << 7), BIT(7));
+ msic_modify(dai->codec, MSIC_IHFRVOLCTRL, (!mute << 7), BIT(7));
+ return 0;
+}
+
+int msic_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
+{
+ unsigned int format, rate;
+
+ pr_debug("pcm hw params\n");
+
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ format = 3;
+ break;
+
+ case SNDRV_PCM_FORMAT_S24_LE:
+ format = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+ msic_modify(dai->codec, MSIC_PCM2C2, format, BIT(4)|BIT(5));
+
+ switch (params_rate(params)) {
+ case 48000:
+ pr_debug("RATE_48000\n");
+ rate = 0;
+ break;
+
+ case 44100:
+ pr_debug("RATE_44100\n");
+ rate = 1;
+ break;
+
+ default:
+ pr_err("ERR rate %d\n", params_rate(params));
+ return -EINVAL;
+ }
+ msic_modify(dai->codec, MSIC_PCM1C1, rate, BIT(7));
+
+ return 0;
+}
+
+/** Codec DAI section **/
+static struct snd_soc_dai_ops intel_msic_headset_dai_ops = {
+ .startup = msic_pcm_hs_startup,
+ .shutdown = msic_pcm_hs_shutdown,
+ .digital_mute = msic_pcm_hs_mute,
+ .hw_params = msic_pcm_hw_params,
+};
+
+static struct snd_soc_dai_ops intel_msic_speaker_dai_ops = {
+ .startup = msic_pcm_spkr_startup,
+ .shutdown = msic_pcm_spkr_shutdown,
+ .digital_mute = msic_pcm_spkr_mute,
+ .hw_params = msic_pcm_hw_params,
+};
+
+static struct snd_soc_dai_ops intel_msic_vib1_dai_ops = {
+ .hw_params = msic_pcm_hw_params,
+};
+
+static struct snd_soc_dai_ops intel_msic_vib2_dai_ops = {
+ .hw_params = msic_pcm_hw_params,
+};
+
+struct snd_soc_dai_driver intel_msic_dais[] = {
+{
+ .name = "Intel MSIC Headset",
+ .playback = {
+ .stream_name = "HeadSet",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = MSIC_RATES,
+ .formats = MSIC_FORMATS,
+ },
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 5,
+ .rates = MSIC_RATES,
+ .formats = MSIC_FORMATS,
+ },
+ .ops = &intel_msic_headset_dai_ops,
+ .symmetric_rates = 1,
+},
+{ .name = "Intel MSIC Speaker",
+ .playback = {
+ .stream_name = "Speaker",
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = MSIC_RATES,
+ .formats = MSIC_FORMATS,
+ },
+ .ops = &intel_msic_speaker_dai_ops,
+},
+{ .name = "Intel MSIC Vibra1",
+ .playback = {
+ .stream_name = "Vibra1",
+ .channels_min = 1,
+ .channels_max = 1,
+ .rates = MSIC_RATES,
+ .formats = MSIC_FORMATS,
+ },
+ .ops = &intel_msic_vib1_dai_ops,
+},
+{ .name = "Intel MSIC Vibra2",
+ .playback = {
+ .stream_name = "Vibra2",
+ .channels_min = 1,
+ .channels_max = 1,
+ .rates = MSIC_RATES,
+ .formats = MSIC_FORMATS,
+ },
+ .ops = &intel_msic_vib2_dai_ops,
+},
+};
+EXPORT_SYMBOL_GPL(intel_msic_dais);
+
+/** codec registration **/
+static int msic_codec_probe(struct snd_soc_codec *codec)
+{
+ struct intel_msic_pvt *msic;
+ int ret;
+
+ pr_debug("codec_probe called\n");
+
+ msic = kzalloc(sizeof(*msic), GFP_KERNEL);
+ if (msic == NULL)
+ return -ENOMEM;
+
+ msic->lo_dac = 3;
+ snd_soc_codec_set_drvdata(codec, msic);
+ msic->codec = codec;
+
+ codec->name = "msic";
+ codec->dapm.bias_level = SND_SOC_BIAS_OFF;
+ codec->dapm.idle_bias_off = 1;
+
+ /*FIXME PCM2 interface this is only fixed interface*/
+ msic_write(codec, MSIC_PCM2RXSLOT01, 0x10);
+ msic_write(codec, MSIC_PCM2RXSLOT23, 0x32);
+ msic_write(codec, MSIC_PCM2RXSLOT45, 0x54);
+
+ /* pcm port setting */
+ msic_write(codec, MSIC_PCM1C1, 0x00);
+ msic_write(codec, MSIC_PCM2C1, 0x01);
+ msic_write(codec, MSIC_PCM2C2, 0x0A);
+
+ /*vendor vibra w/a*/
+ msic_write(codec, MSIC_SSR5, 0x80);
+ msic_write(codec, MSIC_SSR6, 0x80);
+ msic_write(codec, MSIC_VIB1C5, 0x00);
+ msic_write(codec, MSIC_VIB2C5, 0x00);
+ /*configure vibras for pcm port*/
+ msic_write(codec, MSIC_VIB1C3, 0x00);
+ msic_write(codec, MSIC_VIB2C3, 0x00);
+
+ /*soft mute ramp time*/
+ msic_write(codec, MSIC_SOFTMUTE, 0x3);
+ /*fix the initial volume at 0dB*/
+ msic_write(codec, MSIC_HSLVOLCTRL, 0x08);
+ msic_write(codec, MSIC_HSRVOLCTRL, 0x08);
+ msic_write(codec, MSIC_IHFLVOLCTRL, 0x08);
+ msic_write(codec, MSIC_IHFRVOLCTRL, 0x08);
+ /*dac mode and lo w/a*/
+ msic_write(codec, MSIC_SSR2, 0x10);
+ msic_write(codec, MSIC_SSR3, 0x40);
+
+ ret = snd_soc_add_controls(codec, intel_msic_snd_controls,
+ ARRAY_SIZE(intel_msic_snd_controls));
+ if (ret)
+ pr_err("soc_add_controls failed %d", ret);
+ ret = snd_soc_dapm_new_controls(&codec->dapm, intel_msic_dapm_widgets,
+ ARRAY_SIZE(intel_msic_dapm_widgets));
+ if (ret)
+ pr_err("soc_dapm_new_control failed %d", ret);
+ ret = snd_soc_dapm_add_routes(&codec->dapm, msic_audio_map,
+ ARRAY_SIZE(msic_audio_map));
+ if (ret)
+ pr_err("soc_dapm_add_routes failed %d", ret);
+
+ /*default is earpiece pin, userspace sets it explcitly*/
+ snd_soc_dapm_disable_pin(&codec->dapm, "HPOUTL");
+ snd_soc_dapm_disable_pin(&codec->dapm, "HPOUTR");
+ /*default is lineout NC, userspace sets it explcitly*/
+ snd_soc_dapm_disable_pin(&codec->dapm, "LINEOUTL");
+ snd_soc_dapm_disable_pin(&codec->dapm, "LINEOUTR");
+ return 0;
+}
+
+static int msic_codec_remove(struct snd_soc_codec *codec)
+{
+ struct intel_msic_pvt *msic = snd_soc_codec_get_drvdata(codec);
+ pr_debug("codec_remove called\n");
+ snd_soc_codec_set_drvdata(codec, NULL);
+ msic_set_vaud_bias(codec, SND_SOC_BIAS_OFF);
+ kfree(msic);
+
+ return 0;
+}
+
+struct snd_soc_codec_driver intel_msic_codec = {
+ .probe = msic_codec_probe,
+ .remove = msic_codec_remove,
+ .read = msic_read,
+ .write = msic_write,
+ .set_bias_level = msic_set_vaud_bias,
+/* .suspend = msic_codec_suspend,
+ .resume = msic_codec_resume,
+*/
+};
+EXPORT_SYMBOL_GPL(intel_msic_codec);
+
+static int intelmid_codec_probe(struct platform_device *pdev)
+{
+ pr_debug("codec device probe called\n");
+ return snd_soc_register_codec(&pdev->dev, &intel_msic_codec,
+ intel_msic_dais, ARRAY_SIZE(intel_msic_dais));
+}
+
+static int intelmid_codec_remove(struct platform_device *pdev)
+{
+ pr_debug("codec device remove called\n");
+ snd_soc_unregister_codec(&pdev->dev);
+ return 0;
+}
+
+static struct platform_driver intelmid_codec_driver = {
+ .driver = {
+ .name = "mid-msic-codec",
+ .owner = THIS_MODULE,
+ },
+ .probe = intelmid_codec_probe,
+ .remove = intelmid_codec_remove,
+ /*.suspend = intelmid_codec_suspend,
+ .resume = intelmid_codec_resume,*/
+};
+
+static int __init intel_mid_msic_init(void)
+{
+ pr_debug("driver init called\n");
+ return platform_driver_register(&intelmid_codec_driver);
+}
+module_init(intel_mid_msic_init);
+
+static void __exit intel_mid_msic_exit(void)
+{
+ pr_debug("driver exit called\n");
+ platform_driver_unregister(&intelmid_codec_driver);
+}
+module_exit(intel_mid_msic_exit);
+
+MODULE_DESCRIPTION("ASoC Intel(R) MSIC codec driver");
+MODULE_AUTHOR("Vinod Koul <vinod.koul(a)intel.com>");
+MODULE_AUTHOR("Harsha Priya <priya.harsha(a)intel.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/msic.h b/sound/soc/codecs/msic.h
new file mode 100644
index 0000000..c17b318
--- /dev/null
+++ b/sound/soc/codecs/msic.h
@@ -0,0 +1,102 @@
+/*
+ * msic.h - Intel MSIC Codec driver
+ *
+ * Copyright (C) 2010 Intel Corp
+ * Author: Vinod Koul <vinod.koul(a)intel.com>
+ * Author: Harsha Priya <priya.harsha(a)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 _INTEL_MSIC_CODEC_H
+#define _INTEL_MSIC_CODEC_H
+
+/*register map*/
+#define MSIC_VAUD 0xDB
+#define MSIC_VHSP 0xDC
+#define MSIC_VHSN 0xDD
+#define MSIC_VIHF 0xC9
+
+#define MSIC_AUDPLLCTRL 0x240
+#define MSIC_MSIC_DMICBUF0123 0x241
+#define MSIC_MSIC_DMICBUF45 0x242
+#define MSIC_MSIC_DMICGPO 0x244
+#define MSIC_DMICMUX 0x245
+#define MSIC_DMICLK 0x246
+#define MSIC_MICBIAS 0x247
+#define MSIC_ADCCONFIG 0x248
+#define MSIC_MICAMP1 0x249
+#define MSIC_MICAMP2 0x24A
+#define MSIC_NOISEMUX 0x24B
+#define MSIC_AUDIOMUX12 0x24C
+#define MSIC_AUDIOMUX34 0x24D
+#define MSIC_AUDIOSINC 0x24E
+#define MSIC_AUDIOTXEN 0x24F
+#define MSIC_HSEPRXCTRL 0x250
+#define MSIC_IHFRXCTRL 0x251
+#define MSIC_HSMIXER 0x256
+#define MSIC_DACCONFIG 0x257
+#define MSIC_SOFTMUTE 0x258
+#define MSIC_HSLVOLCTRL 0x259
+#define MSIC_HSRVOLCTRL 0x25A
+#define MSIC_IHFLVOLCTRL 0x25B
+#define MSIC_IHFRVOLCTRL 0x25C
+#define MSIC_DRIVEREN 0x25D
+#define MSIC_LOCTL 0x25E
+#define MSIC_VIB1C1 0x25F
+#define MSIC_VIB1C2 0x260
+#define MSIC_VIB1C3 0x261
+#define MSIC_VIB1SPIPCM1 0x262
+#define MSIC_VIB1SPIPCM2 0x263
+#define MSIC_VIB1C5 0x264
+#define MSIC_VIB2C1 0x265
+#define MSIC_VIB2C2 0x266
+#define MSIC_VIB2C3 0x267
+#define MSIC_VIB2SPIPCM1 0x268
+#define MSIC_VIB2SPIPCM2 0x269
+#define MSIC_VIB2C5 0x26A
+#define MSIC_BTNCTRL1 0x26B
+#define MSIC_BTNCTRL2 0x26C
+#define MSIC_PCM1TXSLOT01 0x26D
+#define MSIC_PCM1TXSLOT23 0x26E
+#define MSIC_PCM1TXSLOT45 0x26F
+#define MSIC_PCM1RXSLOT0_3 0x270
+#define MSIC_PCM1RXSLOT45 0x271
+#define MSIC_PCM2TXSLOT01 0x272
+#define MSIC_PCM2TXSLOT23 0x273
+#define MSIC_PCM2TXSLOT45 0x274
+#define MSIC_PCM2RXSLOT01 0x275
+#define MSIC_PCM2RXSLOT23 0x276
+#define MSIC_PCM2RXSLOT45 0x277
+#define MSIC_PCM1C1 0x278
+#define MSIC_PCM1C2 0x279
+#define MSIC_PCM1C3 0x27A
+#define MSIC_PCM2C1 0x27B
+#define MSIC_PCM2C2 0x27C
+/*end codec register defn*/
+
+/*vendor defn these are not part of avp*/
+#define MSIC_SSR2 0x381
+#define MSIC_SSR3 0x382
+#define MSIC_SSR5 0x384
+#define MSIC_SSR6 0x385
+
+extern struct snd_soc_dai_driver intel_msic_dais[4];
+extern struct snd_soc_codec_driver intel_msic_codec;
+
+#endif
--
1.7.2.3
2
4
28 Dec '10
I tried to patch, but it´s no solution !
It´s working for me.
Maybe someone have a look.
If the N63Jn´s ID is true there must be another difference to detect the
right codec...
---
root@arthur:/usr/src/linux-2.6.37-rc7/sound/pci/hda# uname -r && diff -u
/usr/src/l2.6.37-rc7/sound/pci/hda/patch_realtek.c ./patch_realtek.c
2.6.37-rc7-git3
--- /usr/src/l2.6.37-rc7/sound/pci/hda/patch_realtek.c 2010-12-28
15:37:10.900000008 +0100
+++ ./patch_realtek.c 2010-12-28 15:23:09.390000004 +0100
@@ -14854,6 +14854,7 @@
SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z",
ALC269_FIXUP_DELL_M101Z),
SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14",
ALC269_FIXUP_SKU_IGNORE),
SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510",
ALC269_FIXUP_SKU_IGNORE),
+ SND_PCI_QUIRK(0x1043, 0x1113, "Asus N53Jf",
ALC269_FIXUP_ASUS_G73JW), // Connect Subwoofer "Asus Sonic Master"
SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw",
ALC269_FIXUP_ASUS_G73JW),
{}
};
@@ -14878,7 +14879,11 @@
SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
ALC269_AMIC),
SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
- SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
+
+// SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
// PCI ID Collide with Asus N53Jf
+
// and spoil Codec
+ SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N53Jf", ALC269_AUTO),
+
SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
root@arthur:/usr/src/linux-2.6.37-rc7/sound/pci/hda#
--
Alsa Info
!!################################
!!ALSA Information Script v 0.4.59
!!################################
!!Script ran on: Tue Dec 28 14:47:51 UTC 2010
!!Linux Distribution
!!------------------
Debian GNU/Linux 6.0 \n \l
!!DMI Information
!!---------------
Manufacturer: ASUSTeK Computer Inc.
Product Name: N53Jf
!!Kernel Information
!!------------------
Kernel release: 2.6.37-rc7-git3
Operating System: GNU/Linux
Architecture: i686
Processor: unknown
SMP Enabled: Yes
!!ALSA Version
!!------------
Driver version: 1.0.23
Library version: 1.0.23
Utilities version: 1.0.23
!!Loaded ALSA modules
!!-------------------
snd_hda_intel
!!Sound Servers on this system
!!----------------------------
aRts:
Installed - Yes (/usr/bin/artsd)
Running - No
Jack:
Installed - Yes (/usr/bin/jackd)
Running - No
!!Soundcards recognised by ALSA
!!-----------------------------
0 [Intel ]: HDA-Intel - HDA Intel
HDA Intel at 0xd9c00000 irq 49
!!PCI Soundcards installed in the system
!!--------------------------------------
00:1b.0 Audio device: Intel Corporation 5 Series/3400 Series Chipset High Definition Audio (rev 06)
!!Advanced information - PCI Vendor/Device/Susbsystem ID's
!!--------------------------------------------------------
00:1b.0 0403: 8086:3b56 (rev 06)
Subsystem: 1043:1113
!!Modprobe options (Sound related)
!!--------------------------------
snd-atiixp-modem: index=-2
snd-intel8x0m: index=-2
snd-via82xx-modem: index=-2
snd-pcsp: index=-2
snd-usb-audio: index=-2
snd-intel-hda: model=auto
snd_intel_hda: model=auto
!!Loaded sound module options
!!--------------------------
!!Module: snd_hda_intel
bdl_pos_adj : 1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
beep_mode : 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
enable : Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y
enable_msi : -1
id : (null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null)
index : -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
model : (null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null)
patch : (null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null),(null)
position_fix : 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
power_save : 0
power_save_controller : Y
probe_mask : -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
probe_only : 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
single_cmd : N
!!HDA-Intel Codec information
!!---------------------------
--startcollapse--
Codec: Realtek ALC269VB
Address: 0
AFG Function Id: 0x1 (unsol 1)
Vendor Id: 0x10ec0269
Subsystem Id: 0x10431113
Revision Id: 0x100100
No Modem Function Group found
Default PCM:
rates [0x560]: 44100 48000 96000 192000
bits [0xe]: 16 20 24
formats [0x1]: PCM
Default Amp-In caps: N/A
Default Amp-Out caps: N/A
GPIO: io=2, o=0, i=0, unsolicited=1, wake=0
IO[0]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0
IO[1]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0
Node 0x02 [Audio Output] wcaps 0x1d: Stereo Amp-Out
Amp-Out caps: ofs=0x57, nsteps=0x57, stepsize=0x02, mute=0
Amp-Out vals: [0x00 0x00]
Converter: stream=0, channel=0
PCM:
rates [0x560]: 44100 48000 96000 192000
bits [0xe]: 16 20 24
formats [0x1]: PCM
Node 0x03 [Audio Output] wcaps 0x1d: Stereo Amp-Out
Control: name="Speaker Playback Volume", index=0, device=0
ControlAmp: chs=3, dir=Out, idx=0, ofs=0
Device: name="ALC269VB Analog", type="Audio", device=0
Amp-Out caps: ofs=0x57, nsteps=0x57, stepsize=0x02, mute=0
Amp-Out vals: [0x3b 0x3b]
Converter: stream=5, channel=0
PCM:
rates [0x560]: 44100 48000 96000 192000
bits [0xe]: 16 20 24
formats [0x1]: PCM
Node 0x04 [Vendor Defined Widget] wcaps 0xf00000: Mono
Node 0x05 [Vendor Defined Widget] wcaps 0xf00000: Mono
Node 0x06 [Audio Output] wcaps 0x211: Stereo Digital
Control: name="IEC958 Playback Con Mask", index=0, device=0
Control: name="IEC958 Playback Pro Mask", index=0, device=0
Control: name="IEC958 Playback Default", index=0, device=0
Control: name="IEC958 Playback Switch", index=0, device=0
Control: name="IEC958 Default PCM Playback Switch", index=0, device=0
Device: name="ALC269VB Digital", type="SPDIF", device=1
Converter: stream=5, channel=0
Digital: Enabled
Digital category: 0x0
PCM:
rates [0x5e0]: 44100 48000 88200 96000 192000
bits [0xe]: 16 20 24
formats [0x1]: PCM
Node 0x07 [Vendor Defined Widget] wcaps 0xf00000: Mono
Node 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In
Control: name="Capture Switch", index=0, device=0
Control: name="Capture Volume", index=0, device=0
Device: name="ALC269VB Analog", type="Audio", device=0
Amp-In caps: ofs=0x0b, nsteps=0x1f, stepsize=0x05, mute=1
Amp-In vals: [0x9e 0x9e]
Converter: stream=0, channel=0
SDI-Select: 0
PCM:
rates [0x560]: 44100 48000 96000 192000
bits [0xe]: 16 20 24
formats [0x1]: PCM
Connection: 1
0x23
Node 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In
Control: name="Capture Switch", index=1, device=0
Control: name="Capture Volume", index=1, device=0
Amp-In caps: ofs=0x0b, nsteps=0x1f, stepsize=0x05, mute=1
Amp-In vals: [0x17 0x17]
Converter: stream=0, channel=0
SDI-Select: 0
PCM:
rates [0x560]: 44100 48000 96000 192000
bits [0xe]: 16 20 24
formats [0x1]: PCM
Connection: 1
0x22
Node 0x0a [Vendor Defined Widget] wcaps 0xf00000: Mono
Node 0x0b [Audio Mixer] wcaps 0x20010b: Stereo Amp-In
Amp-In caps: ofs=0x17, nsteps=0x1f, stepsize=0x05, mute=1
Amp-In vals: [0x97 0x97] [0x97 0x97] [0x97 0x97] [0x97 0x97] [0x97 0x97]
Connection: 5
0x18 0x19 0x1a 0x1b 0x1d
Node 0x0c [Audio Mixer] wcaps 0x20010b: Stereo Amp-In
Amp-In caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
Amp-In vals: [0x00 0x00] [0x00 0x00]
Connection: 2
0x02 0x0b
Node 0x0d [Audio Mixer] wcaps 0x20010b: Stereo Amp-In
Amp-In caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
Amp-In vals: [0x00 0x00] [0x00 0x00]
Connection: 2
0x03 0x0b
Node 0x0e [Vendor Defined Widget] wcaps 0xf00000: Mono
Node 0x0f [Audio Mixer] wcaps 0x20010a: Mono Amp-In
Amp-In caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
Amp-In vals: [0x00] [0x00]
Connection: 2
0x02 0x0b
Node 0x10 [Vendor Defined Widget] wcaps 0xf00000: Mono
Node 0x11 [Vendor Defined Widget] wcaps 0xf00000: Mono
Node 0x12 [Pin Complex] wcaps 0x40000b: Stereo Amp-In
Amp-In caps: ofs=0x00, nsteps=0x03, stepsize=0x2f, mute=0
Amp-In vals: [0x00 0x00]
Pincap 0x00000020: IN
Pin Default 0x411111f0: [N/A] Speaker at Ext Rear
Conn = 1/8, Color = Black
DefAssociation = 0xf, Sequence = 0x0
Misc = NO_PRESENCE
Pin-ctls: 0x00:
Node 0x13 [Vendor Defined Widget] wcaps 0xf00000: Mono
Node 0x14 [Pin Complex] wcaps 0x40018d: Stereo Amp-Out
Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
Amp-Out vals: [0x00 0x00]
Pincap 0x00010014: OUT EAPD Detect
EAPD 0x2: EAPD
Pin Default 0x411111f0: [N/A] Speaker at Ext Rear
Conn = 1/8, Color = Black
DefAssociation = 0xf, Sequence = 0x0
Misc = NO_PRESENCE
Pin-ctls: 0x40: OUT
Unsolicited: tag=00, enabled=0
Connection: 2
0x0c* 0x0d
Node 0x15 [Vendor Defined Widget] wcaps 0xf00000: Mono
Node 0x16 [Vendor Defined Widget] wcaps 0xf00000: Mono
Node 0x17 [Pin Complex] wcaps 0x40010c: Mono Amp-Out
Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
Amp-Out vals: [0x00]
Pincap 0x00000010: OUT
Pin Default 0x99130111: [Fixed] Speaker at Int ATAPI
Conn = ATAPI, Color = Unknown
DefAssociation = 0x1, Sequence = 0x1
Misc = NO_PRESENCE
Pin-ctls: 0x40: OUT
Connection: 1
0x0f
Node 0x18 [Pin Complex] wcaps 0x40018f: Stereo Amp-In Amp-Out
Control: name="Mic Boost", index=0, device=0
ControlAmp: chs=3, dir=In, idx=0, ofs=0
Amp-In caps: ofs=0x00, nsteps=0x03, stepsize=0x2f, mute=0
Amp-In vals: [0x03 0x03]
Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
Amp-Out vals: [0x80 0x80]
Pincap 0x00001734: IN OUT Detect
Vref caps: HIZ 50 GRD 80
Pin Default 0x01a19830: [Jack] Mic at Ext Rear
Conn = 1/8, Color = Pink
DefAssociation = 0x3, Sequence = 0x0
Pin-ctls: 0x24: IN VREF_80
Unsolicited: tag=08, enabled=1
Connection: 1
0x0d
Node 0x19 [Pin Complex] wcaps 0x40008b: Stereo Amp-In
Control: name="Internal Mic Boost", index=1, device=0
ControlAmp: chs=3, dir=In, idx=0, ofs=0
Amp-In caps: ofs=0x00, nsteps=0x03, stepsize=0x2f, mute=0
Amp-In vals: [0x03 0x03]
Pincap 0x00001724: IN Detect
Vref caps: HIZ 50 GRD 80
Pin Default 0x99a3093f: [Fixed] Mic at Int ATAPI
Conn = ATAPI, Color = Unknown
DefAssociation = 0x3, Sequence = 0xf
Misc = NO_PRESENCE
Pin-ctls: 0x24: IN VREF_80
Unsolicited: tag=00, enabled=0
Node 0x1a [Pin Complex] wcaps 0x40018f: Stereo Amp-In Amp-Out
Amp-In caps: ofs=0x00, nsteps=0x03, stepsize=0x2f, mute=0
Amp-In vals: [0x00 0x00]
Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
Amp-Out vals: [0x80 0x80]
Pincap 0x0000003c: IN OUT HP Detect
Pin Default 0x411111f0: [N/A] Speaker at Ext Rear
Conn = 1/8, Color = Black
DefAssociation = 0xf, Sequence = 0x0
Misc = NO_PRESENCE
Pin-ctls: 0x20: IN
Unsolicited: tag=00, enabled=0
Connection: 2
0x0c* 0x0d
Node 0x1b [Pin Complex] wcaps 0x40018f: Stereo Amp-In Amp-Out
Control: name="Speaker Playback Switch", index=0, device=0
ControlAmp: chs=3, dir=Out, idx=0, ofs=0
Amp-In caps: ofs=0x00, nsteps=0x03, stepsize=0x2f, mute=0
Amp-In vals: [0x00 0x00]
Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
Amp-Out vals: [0x00 0x00]
Pincap 0x00000034: IN OUT Detect
Pin Default 0x99130110: [Fixed] Speaker at Int ATAPI
Conn = ATAPI, Color = Unknown
DefAssociation = 0x1, Sequence = 0x0
Misc = NO_PRESENCE
Pin-ctls: 0x40: OUT
Unsolicited: tag=00, enabled=0
Connection: 2
0x0c 0x0d*
Node 0x1c [Vendor Defined Widget] wcaps 0xf00000: Mono
Node 0x1d [Pin Complex] wcaps 0x400000: Mono
Pincap 0x00000020: IN
Pin Default 0x40079a2d: [N/A] Line Out at Ext N/A
Conn = Analog, Color = Pink
DefAssociation = 0x2, Sequence = 0xd
Pin-ctls: 0x20: IN
Node 0x1e [Pin Complex] wcaps 0x400381: Stereo Digital
Pincap 0x00000014: OUT Detect
Pin Default 0x99430120: [Fixed] SPDIF Out at Int ATAPI
Conn = ATAPI, Color = Unknown
DefAssociation = 0x2, Sequence = 0x0
Misc = NO_PRESENCE
Pin-ctls: 0x40: OUT
Unsolicited: tag=00, enabled=0
Connection: 1
0x06
Node 0x1f [Vendor Defined Widget] wcaps 0xf00000: Mono
Node 0x20 [Vendor Defined Widget] wcaps 0xf00040: Mono
Processing caps: benign=0, ncoeff=25
Node 0x21 [Pin Complex] wcaps 0x40018d: Stereo Amp-Out
Control: name="Headphone Playback Switch", index=0, device=0
ControlAmp: chs=3, dir=Out, idx=0, ofs=0
Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
Amp-Out vals: [0x00 0x00]
Pincap 0x0000001c: OUT HP Detect
Pin Default 0x0121401f: [Jack] HP Out at Ext Rear
Conn = 1/8, Color = Green
DefAssociation = 0x1, Sequence = 0xf
Pin-ctls: 0xc0: OUT HP
Unsolicited: tag=04, enabled=1
Connection: 2
0x0c 0x0d*
Node 0x22 [Audio Selector] wcaps 0x30010b: Stereo Amp-In
Amp-In caps: N/A
Amp-In vals: [0x00 0x00] [0x00 0x00] [0x00 0x00] [0x00 0x00] [0x00 0x00] [0x00 0x00] [0x00 0x00]
Connection: 7
0x18* 0x19 0x1a 0x1b 0x1d 0x0b 0x12
Node 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In
Amp-In caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
Amp-In vals: [0x80 0x80] [0x00 0x00] [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80 0x80]
Connection: 6
0x18 0x19 0x1a 0x1b 0x1d 0x0b
--endcollapse--
!!ALSA Device nodes
!!-----------------
crw-rw---- 1 root audio 116, 8 Dec 28 15:28 /dev/snd/controlC0
crw-rw---- 1 root audio 116, 7 Dec 28 15:28 /dev/snd/hwC0D0
crw-rw---- 1 root audio 116, 6 Dec 28 15:28 /dev/snd/pcmC0D0c
crw-rw---- 1 root audio 116, 5 Dec 28 15:33 /dev/snd/pcmC0D0p
crw-rw---- 1 root audio 116, 4 Dec 28 15:28 /dev/snd/pcmC0D1p
crw-rw---- 1 root audio 116, 3 Dec 28 15:28 /dev/snd/seq
crw-rw---- 1 root audio 116, 2 Dec 28 15:28 /dev/snd/timer
/dev/snd/by-path:
total 0
drwxr-xr-x 2 root root 60 Dec 28 15:28 .
drwxr-xr-x 3 root root 200 Dec 28 15:28 ..
lrwxrwxrwx 1 root root 12 Dec 28 15:28 pci-0000:00:1b.0 -> ../controlC0
!!Aplay/Arecord output
!!------------
APLAY
**** List of PLAYBACK Hardware Devices ****
card 0: Intel [HDA Intel], device 0: ALC269VB Analog [ALC269VB Analog]
Subdevices: 0/1
Subdevice #0: subdevice #0
card 0: Intel [HDA Intel], device 1: ALC269VB Digital [ALC269VB Digital]
Subdevices: 1/1
Subdevice #0: subdevice #0
ARECORD
**** List of CAPTURE Hardware Devices ****
card 0: Intel [HDA Intel], device 0: ALC269VB Analog [ALC269VB Analog]
Subdevices: 1/1
Subdevice #0: subdevice #0
!!Amixer output
!!-------------
!!-------Mixer controls for card 0 [Intel]
Card hw:0 'Intel'/'HDA Intel at 0xd9c00000 irq 49'
Mixer name : 'Realtek ALC269VB'
Components : 'HDA:10ec0269,10431113,00100100'
Controls : 18
Simple ctrls : 11
Simple mixer control 'Master',0
Capabilities: pvolume pvolume-joined pswitch pswitch-joined penum
Playback channels: Mono
Limits: Playback 0 - 87
Mono: Playback 60 [69%] [-20.25dB] [on]
Simple mixer control 'Headphone',0
Capabilities: pswitch penum
Playback channels: Front Left - Front Right
Mono:
Front Left: Playback [on]
Front Right: Playback [on]
Simple mixer control 'Speaker',0
Capabilities: pvolume pswitch penum
Playback channels: Front Left - Front Right
Limits: Playback 0 - 87
Mono:
Front Left: Playback 86 [99%] [0.75dB] [on]
Front Right: Playback 86 [99%] [0.75dB] [on]
Simple mixer control 'PCM',0
Capabilities: pvolume penum
Playback channels: Front Left - Front Right
Limits: Playback 0 - 255
Mono:
Front Left: Playback 255 [100%] [0.00dB]
Front Right: Playback 255 [100%] [0.00dB]
Simple mixer control 'Mic Boost',0
Capabilities: volume penum
Playback channels: Front Left - Front Right
Capture channels: Front Left - Front Right
Limits: 0 - 3
Front Left: 3 [100%]
Front Right: 3 [100%]
Simple mixer control 'IEC958',0
Capabilities: pswitch pswitch-joined penum
Playback channels: Mono
Mono: Playback [on]
Simple mixer control 'IEC958 Default PCM',0
Capabilities: pswitch pswitch-joined penum
Playback channels: Mono
Mono: Playback [on]
Simple mixer control 'Capture',0
Capabilities: cvolume cswitch penum
Capture channels: Front Left - Front Right
Limits: Capture 0 - 31
Front Left: Capture 30 [97%] [28.50dB] [off]
Front Right: Capture 30 [97%] [28.50dB] [off]
Simple mixer control 'Capture',1
Capabilities: cvolume cswitch penum
Capture channels: Front Left - Front Right
Limits: Capture 0 - 31
Front Left: Capture 23 [74%] [18.00dB] [on]
Front Right: Capture 23 [74%] [18.00dB] [on]
Simple mixer control 'Digital',0
Capabilities: cvolume penum
Capture channels: Front Left - Front Right
Limits: Capture 0 - 120
Front Left: Capture 120 [100%] [30.00dB]
Front Right: Capture 120 [100%] [30.00dB]
Simple mixer control 'Internal Mic Boost',1
Capabilities: volume penum
Playback channels: Front Left - Front Right
Capture channels: Front Left - Front Right
Limits: 0 - 3
Front Left: 3 [100%]
Front Right: 3 [100%]
!!Alsactl output
!!-------------
--startcollapse--
state.Intel {
control.1 {
comment.access 'read write'
comment.type INTEGER
comment.count 2
comment.range '0 - 87'
comment.dbmin -6525
comment.dbmax 0
iface MIXER
name 'Speaker Playback Volume'
value.0 86
value.1 86
}
control.2 {
comment.access 'read write'
comment.type BOOLEAN
comment.count 2
iface MIXER
name 'Speaker Playback Switch'
value.0 true
value.1 true
}
control.3 {
comment.access 'read write'
comment.type BOOLEAN
comment.count 2
iface MIXER
name 'Headphone Playback Switch'
value.0 true
value.1 true
}
control.4 {
comment.access 'read write'
comment.type INTEGER
comment.count 2
comment.range '0 - 3'
comment.dbmin 0
comment.dbmax 3600
iface MIXER
name 'Mic Boost'
value.0 3
value.1 3
}
control.5 {
comment.access 'read write'
comment.type INTEGER
comment.count 2
comment.range '0 - 3'
comment.dbmin 0
comment.dbmax 3600
iface MIXER
name 'Internal Mic Boost'
index 1
value.0 3
value.1 3
}
control.6 {
comment.access 'read write'
comment.type BOOLEAN
comment.count 2
iface MIXER
name 'Capture Switch'
value.0 false
value.1 false
}
control.7 {
comment.access 'read write'
comment.type BOOLEAN
comment.count 2
iface MIXER
name 'Capture Switch'
index 1
value.0 true
value.1 true
}
control.8 {
comment.access 'read write'
comment.type INTEGER
comment.count 2
comment.range '0 - 31'
comment.dbmin -1650
comment.dbmax 3000
iface MIXER
name 'Capture Volume'
value.0 30
value.1 30
}
control.9 {
comment.access 'read write'
comment.type INTEGER
comment.count 2
comment.range '0 - 31'
comment.dbmin -1650
comment.dbmax 3000
iface MIXER
name 'Capture Volume'
index 1
value.0 23
value.1 23
}
control.10 {
comment.access read
comment.type IEC958
comment.count 1
iface MIXER
name 'IEC958 Playback Con Mask'
value '0fff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
}
control.11 {
comment.access read
comment.type IEC958
comment.count 1
iface MIXER
name 'IEC958 Playback Pro Mask'
value '0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
}
control.12 {
comment.access 'read write'
comment.type IEC958
comment.count 1
iface MIXER
name 'IEC958 Playback Default'
value '0400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
}
control.13 {
comment.access 'read write'
comment.type BOOLEAN
comment.count 1
iface MIXER
name 'IEC958 Playback Switch'
value true
}
control.14 {
comment.access 'read write'
comment.type BOOLEAN
comment.count 1
iface MIXER
name 'IEC958 Default PCM Playback Switch'
value true
}
control.15 {
comment.access 'read write'
comment.type INTEGER
comment.count 1
comment.range '0 - 87'
comment.dbmin -6525
comment.dbmax 0
iface MIXER
name 'Master Playback Volume'
value 60
}
control.16 {
comment.access 'read write'
comment.type BOOLEAN
comment.count 1
iface MIXER
name 'Master Playback Switch'
value true
}
control.17 {
comment.access 'read write user'
comment.type INTEGER
comment.count 2
comment.range '0 - 255'
comment.tlv '0000000100000008ffffec1400000014'
comment.dbmin -5100
comment.dbmax 0
iface MIXER
name 'PCM Playback Volume'
value.0 255
value.1 255
}
control.18 {
comment.access 'read write user'
comment.type INTEGER
comment.count 2
comment.range '0 - 120'
comment.tlv '0000000100000008fffff44800000032'
comment.dbmin -3000
comment.dbmax 3000
iface MIXER
name 'Digital Capture Volume'
value.0 120
value.1 120
}
}
--endcollapse--
!!All Loaded Modules
!!------------------
Module
binfmt_misc
loop
i915
drm_kms_helper
drm
i2c_algo_bit
snd_hda_codec_realtek
snd_hda_intel
snd_hda_codec
snd_hwdep
snd_pcm_oss
snd_mixer_oss
snd_pcm
snd_seq
snd_timer
snd_seq_device
snd
iwlagn
video
asus_laptop
btusb
output
sparse_keymap
evdev
uvcvideo
psmouse
iwlcore
snd_page_alloc
wmi
usbhid
atl1c
!!Sysfs Files
!!-----------
/sys/class/sound/hwC0D0/init_pin_configs:
0x12 0x411111f0
0x14 0x411111f0
0x17 0x411111f0
0x18 0x01a19830
0x19 0x99a3093f
0x1a 0x411111f0
0x1b 0x99130110
0x1d 0x40079a2d
0x1e 0x99430120
0x21 0x0121401f
/sys/class/sound/hwC0D0/driver_pin_configs:
0x17 0x99130111
/sys/class/sound/hwC0D0/user_pin_configs:
/sys/class/sound/hwC0D0/init_verbs:
!!ALSA/HDA dmesg
!!------------------
[ 7.140452] ieee80211 phy0: Selected rate control algorithm 'iwl-agn-rs'
[ 7.760717] HDA Intel 0000:00:1b.0: PCI INT A -> GSI 22 (level, low) -> IRQ 22
[ 7.760839] HDA Intel 0000:00:1b.0: irq 49 for MSI/MSI-X
[ 7.760902] HDA Intel 0000:00:1b.0: setting latency timer to 64
[ 7.760912] ALSA sound/pci/hda/hda_intel.c:2530: chipset global capabilities = 0x4401
[ 7.839383] ALSA sound/pci/hda/hda_intel.c:913: codec_mask = 0x1
[ 7.839687] ALSA sound/pci/hda/hda_intel.c:1351: codec #0 probed OK
[ 8.018570] ALSA sound/pci/hda/patch_realtek.c:1524: SKU: Nid=0x1d sku_cfg=0x40079a2d
[ 8.018581] ALSA sound/pci/hda/patch_realtek.c:1526: SKU: port_connectivity=0x1
[ 8.018587] ALSA sound/pci/hda/patch_realtek.c:1527: SKU: enable_pcbeep=0x0
[ 8.018594] ALSA sound/pci/hda/patch_realtek.c:1528: SKU: check_sum=0x00000007
[ 8.018601] ALSA sound/pci/hda/patch_realtek.c:1529: SKU: customization=0x0000009a
[ 8.018608] ALSA sound/pci/hda/patch_realtek.c:1530: SKU: external_amp=0x5
[ 8.018615] ALSA sound/pci/hda/patch_realtek.c:1531: SKU: platform_type=0x1
[ 8.018621] ALSA sound/pci/hda/patch_realtek.c:1532: SKU: swap=0x0
[ 8.018627] ALSA sound/pci/hda/patch_realtek.c:1533: SKU: override=0x1
[ 8.019090] ALSA sound/pci/hda/hda_codec.c:3726: hda_codec: model 'auto' is selected for config 1043:1113 (ASUS N53Jf)
[ 8.019096] ALSA sound/pci/hda/patch_realtek.c:1712: hda_codec: ALC269VB: Apply pincfg for Asus N53Jf
[ 8.019111] ALSA sound/pci/hda/hda_codec.c:4630: autoconfig: line_outs=2 (0x1b/0x17/0x0/0x0/0x0)
[ 8.019116] ALSA sound/pci/hda/hda_codec.c:4634: speaker_outs=0 (0x0/0x0/0x0/0x0/0x0)
[ 8.019120] ALSA sound/pci/hda/hda_codec.c:4638: hp_outs=1 (0x21/0x0/0x0/0x0/0x0)
[ 8.019124] ALSA sound/pci/hda/hda_codec.c:4639: mono: mono_out=0x0
[ 8.019128] ALSA sound/pci/hda/hda_codec.c:4642: dig-out=0x1e/0x0
[ 8.019131] ALSA sound/pci/hda/hda_codec.c:4643: inputs:
[ 8.019134] ALSA sound/pci/hda/hda_codec.c:4647: Mic=0x18
[ 8.019138] ALSA sound/pci/hda/hda_codec.c:4647: Internal Mic=0x19
[ 8.019142] ALSA sound/pci/hda/hda_codec.c:4649:
[ 8.020072] ALSA sound/pci/hda/patch_realtek.c:1581: realtek: No valid SSID, checking pincfg 0x40079a2d for NID 0x1d
[ 8.020077] ALSA sound/pci/hda/patch_realtek.c:1597: realtek: Enabling init ASM_ID=0x9a2d CODEC_ID=10ec0269
[ 8.020082] ALSA sound/pci/hda/patch_realtek.c:1411: realtek: Enable HP auto-muting on NID 0x21
[ 8.020088] ALSA sound/pci/hda/patch_realtek.c:1456: realtek: Enable auto-mic switch on NID 0x18/0x19
[ 8.023742] ALSA sound/pci/hda/hda_codec.c:2164: Cannot find slave Front Playback Volume, skipped
[ 8.023747] ALSA sound/pci/hda/hda_codec.c:2164: Cannot find slave Surround Playback Volume, skipped
[ 8.023751] ALSA sound/pci/hda/hda_codec.c:2164: Cannot find slave Center Playback Volume, skipped
[ 8.023756] ALSA sound/pci/hda/hda_codec.c:2164: Cannot find slave LFE Playback Volume, skipped
[ 8.023760] ALSA sound/pci/hda/hda_codec.c:2164: Cannot find slave Side Playback Volume, skipped
[ 8.023764] ALSA sound/pci/hda/hda_codec.c:2164: Cannot find slave Headphone Playback Volume, skipped
[ 8.023770] ALSA sound/pci/hda/hda_codec.c:2164: Cannot find slave Mono Playback Volume, skipped
[ 8.023774] ALSA sound/pci/hda/hda_codec.c:2164: Cannot find slave Line-Out Playback Volume, skipped
[ 8.023778] ALSA sound/pci/hda/hda_codec.c:2164: Cannot find slave PCM Playback Volume, skipped
[ 8.023787] ALSA sound/pci/hda/hda_codec.c:2164: Cannot find slave Front Playback Switch, skipped
[ 8.023792] ALSA sound/pci/hda/hda_codec.c:2164: Cannot find slave Surround Playback Switch, skipped
[ 8.023796] ALSA sound/pci/hda/hda_codec.c:2164: Cannot find slave Center Playback Switch, skipped
[ 8.023800] ALSA sound/pci/hda/hda_codec.c:2164: Cannot find slave LFE Playback Switch, skipped
[ 8.023804] ALSA sound/pci/hda/hda_codec.c:2164: Cannot find slave Side Playback Switch, skipped
[ 8.023812] ALSA sound/pci/hda/hda_codec.c:2164: Cannot find slave Mono Playback Switch, skipped
[ 8.023819] ALSA sound/pci/hda/hda_codec.c:2164: Cannot find slave Line-Out Playback Switch, skipped
[ 8.023823] ALSA sound/pci/hda/hda_codec.c:2164: Cannot find slave PCM Playback Switch, skipped
[ 8.024352] input: HDA Intel Mic as /devices/pci0000:00/0000:00:1b.0/sound/card0/input9
[ 8.024487] input: HDA Intel Headphone as /devices/pci0000:00/0000:00:1b.0/sound/card0/input10
[ 10.004618] Adding 3905532k swap on /dev/sda5. Priority:-1 extents:1 across:3905532k
--
[ 19.543476] NFSD: starting 90-second grace period
[ 24.032281] ALSA sound/pci/hda/hda_intel.c:1675: azx_pcm_prepare: bufsize=0x10000, format=0x31
[ 24.032301] ALSA sound/pci/hda/hda_codec.c:1227: hda_codec_setup_stream: NID=0x6, stream=0x5, channel=0, format=0x31
[ 24.032511] ALSA sound/pci/hda/hda_codec.c:1227: hda_codec_setup_stream: NID=0x3, stream=0x5, channel=0, format=0x31
[ 24.062896] ALSA sound/pci/hda/hda_codec.c:1290: hda_codec_cleanup_stream: NID=0x3
[ 24.062904] ALSA sound/pci/hda/hda_codec.c:1290: hda_codec_cleanup_stream: NID=0x6
[ 25.845885] apm: BIOS not found.
--
[ 59.055664] CPUFREQ: Per core ondemand sysfs interface is deprecated - up_threshold
[ 81.168959] ALSA sound/pci/hda/hda_codec.c:1290: hda_codec_cleanup_stream: NID=0x6
[ 81.230804] ALSA sound/pci/hda/hda_intel.c:1675: azx_pcm_prepare: bufsize=0x10000, format=0x31
[ 81.230824] ALSA sound/pci/hda/hda_codec.c:1227: hda_codec_setup_stream: NID=0x6, stream=0x5, channel=0, format=0x31
[ 81.230831] ALSA sound/pci/hda/hda_codec.c:1227: hda_codec_setup_stream: NID=0x3, stream=0x5, channel=0, format=0x31
[ 81.233247] ALSA sound/pci/hda/hda_codec.c:1290: hda_codec_cleanup_stream: NID=0x3
[ 81.233251] ALSA sound/pci/hda/hda_codec.c:1290: hda_codec_cleanup_stream: NID=0x6
[ 81.570625] ALSA sound/pci/hda/hda_intel.c:1675: azx_pcm_prepare: bufsize=0x10000, format=0x31
[ 81.570649] ALSA sound/pci/hda/hda_codec.c:1227: hda_codec_setup_stream: NID=0x6, stream=0x5, channel=0, format=0x31
[ 81.570659] ALSA sound/pci/hda/hda_codec.c:1227: hda_codec_setup_stream: NID=0x3, stream=0x5, channel=0, format=0x31
[ 81.572936] ALSA sound/pci/hda/hda_codec.c:1290: hda_codec_cleanup_stream: NID=0x3
[ 81.572943] ALSA sound/pci/hda/hda_codec.c:1290: hda_codec_cleanup_stream: NID=0x6
[ 81.575200] ALSA sound/pci/hda/hda_intel.c:1675: azx_pcm_prepare: bufsize=0x10000, format=0x31
[ 81.575219] ALSA sound/pci/hda/hda_codec.c:1227: hda_codec_setup_stream: NID=0x6, stream=0x5, channel=0, format=0x31
[ 81.575229] ALSA sound/pci/hda/hda_codec.c:1227: hda_codec_setup_stream: NID=0x3, stream=0x5, channel=0, format=0x31
[ 81.575642] ALSA sound/pci/hda/hda_codec.c:1290: hda_codec_cleanup_stream: NID=0x3
[ 81.575648] ALSA sound/pci/hda/hda_codec.c:1290: hda_codec_cleanup_stream: NID=0x6
[ 82.096033] ALSA sound/pci/hda/hda_intel.c:1675: azx_pcm_prepare: bufsize=0x10000, format=0x31
[ 82.096057] ALSA sound/pci/hda/hda_codec.c:1227: hda_codec_setup_stream: NID=0x6, stream=0x5, channel=0, format=0x31
[ 82.096067] ALSA sound/pci/hda/hda_codec.c:1227: hda_codec_setup_stream: NID=0x3, stream=0x5, channel=0, format=0x31
[ 90.411144] ALSA sound/pci/hda/hda_codec.c:1290: hda_codec_cleanup_stream: NID=0x3
[ 90.411152] ALSA sound/pci/hda/hda_codec.c:1290: hda_codec_cleanup_stream: NID=0x6
[ 326.983324] ALSA sound/pci/hda/hda_intel.c:1675: azx_pcm_prepare: bufsize=0x10000, format=0x31
[ 326.983343] ALSA sound/pci/hda/hda_codec.c:1227: hda_codec_setup_stream: NID=0x6, stream=0x5, channel=0, format=0x31
[ 326.983348] ALSA sound/pci/hda/hda_codec.c:1227: hda_codec_setup_stream: NID=0x3, stream=0x5, channel=0, format=0x31
[ 329.306843] hda-intel: IRQ timing workaround is activated for card #0. Suggest a bigger bdl_pos_adj.
[ 1180.124078] atl1c 0000:06:00.0: vpd r/w failed. This is likely a firmware bug on this device. Contact the card vendor for a firmware update.
1
0
From: Vinod Koul <vinod.koul(a)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(a)intel.com>
Signed-off-by: Harsha Priya <priya.harsha(a)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(a)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(a)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(a)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(a)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
2
2