get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/27572/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 27572,
    "url": "http://patchwork.ozlabs.org/api/patches/27572/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/linuxppc-dev/patch/20090523231307.17919.5277.stgit@terra/",
    "project": {
        "id": 2,
        "url": "http://patchwork.ozlabs.org/api/projects/2/?format=api",
        "name": "Linux PPC development",
        "link_name": "linuxppc-dev",
        "list_id": "linuxppc-dev.lists.ozlabs.org",
        "list_email": "linuxppc-dev@lists.ozlabs.org",
        "web_url": "https://github.com/linuxppc/wiki/wiki",
        "scm_url": "https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git",
        "webscm_url": "https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git/",
        "list_archive_url": "https://lore.kernel.org/linuxppc-dev/",
        "list_archive_url_format": "https://lore.kernel.org/linuxppc-dev/{}/",
        "commit_url_format": "https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git/commit/?id={}"
    },
    "msgid": "<20090523231307.17919.5277.stgit@terra>",
    "list_archive_url": "https://lore.kernel.org/linuxppc-dev/20090523231307.17919.5277.stgit@terra/",
    "date": "2009-05-23T23:13:07",
    "name": "[V2,6/9] Codec for STAC9766 used on the Efika",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "25a2473fa78757cf6976a2e6aa59fc4827660aaa",
    "submitter": {
        "id": 375,
        "url": "http://patchwork.ozlabs.org/api/people/375/?format=api",
        "name": "jonsmirl@gmail.com",
        "email": "jonsmirl@gmail.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/linuxppc-dev/patch/20090523231307.17919.5277.stgit@terra/mbox/",
    "series": [],
    "comments": "http://patchwork.ozlabs.org/api/patches/27572/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/27572/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@ozlabs.org>",
        "X-Original-To": [
            "patchwork-incoming@bilbo.ozlabs.org",
            "linuxppc-dev@ozlabs.org"
        ],
        "Delivered-To": [
            "patchwork-incoming@bilbo.ozlabs.org",
            "patchwork-incoming@ozlabs.org",
            "linuxppc-dev@ozlabs.org"
        ],
        "Received": [
            "from ozlabs.org (ozlabs.org [203.10.76.45])\n\t(using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))\n\t(Client CN \"mx.ozlabs.org\",\n\tIssuer \"CA Cert Signing Authority\" (verified OK))\n\tby bilbo.ozlabs.org (Postfix) with ESMTPS id 76417B6F35\n\tfor <patchwork-incoming@bilbo.ozlabs.org>;\n\tSun, 24 May 2009 09:23:00 +1000 (EST)",
            "by ozlabs.org (Postfix)\n\tid 39963DF3DD; Sun, 24 May 2009 09:16:28 +1000 (EST)",
            "from ozlabs.org (localhost [127.0.0.1])\n\tby ozlabs.org (Postfix) with ESMTP id 354EDDF3DC\n\tfor <patchwork-incoming@ozlabs.org>;\n\tSun, 24 May 2009 09:16:28 +1000 (EST)",
            "from yx-out-2324.google.com (yx-out-2324.google.com [74.125.44.30])\n\tby ozlabs.org (Postfix) with ESMTP id 23146DE13C\n\tfor <linuxppc-dev@ozlabs.org>; Sun, 24 May 2009 09:13:08 +1000 (EST)",
            "by yx-out-2324.google.com with SMTP id 8so1216733yxb.39\n\tfor <linuxppc-dev@ozlabs.org>; Sat, 23 May 2009 16:13:08 -0700 (PDT)",
            "by 10.100.46.17 with SMTP id t17mr9860651ant.50.1243120388335;\n\tSat, 23 May 2009 16:13:08 -0700 (PDT)",
            "from terra (c-76-109-159-38.hsd1.fl.comcast.net [76.109.159.38])\n\tby mx.google.com with ESMTPS id 8sm11060952agd.37.2009.05.23.16.13.07\n\t(version=TLSv1/SSLv3 cipher=RC4-MD5);\n\tSat, 23 May 2009 16:13:08 -0700 (PDT)",
            "from localhost ([127.0.0.1] helo=[127.0.1.1])\n\tby terra with esmtp (Exim 4.69) (envelope-from <jonsmirl@gmail.com>)\n\tid 1M80Op-0004hi-Pm; Sat, 23 May 2009 19:13:07 -0400"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; \n\th=domainkey-signature:received:received:received:subject:to:from:date\n\t:message-id:in-reply-to:references:user-agent:mime-version\n\t:content-type:content-transfer-encoding;\n\tbh=hp7t6YG/lRP4eiXMtaA+6zh/Yln8yacQSw745D+gEUY=;\n\tb=fdARZ8FV4XGli5TEPzYfkCugQvMN62314h/M2llpc3rHyERwDBRNfMGr4CteKAjJwQ\n\t116AIPuPPPwqX5642cBbOa/iQ8Ounkpdgikw1Lpfw2nehUWJfu2cY0EOgCrrbyxQG7zp\n\tCP2olu8o3hYf3z2XuK2bsHFrl3Fumhh4N/ncg=",
        "DomainKey-Signature": "a=rsa-sha1; c=nofws; d=gmail.com; s=gamma;\n\th=subject:to:from:date:message-id:in-reply-to:references:user-agent\n\t:mime-version:content-type:content-transfer-encoding;\n\tb=kxWoYgrjtLRTWLkCo7M+G1NSM6fCAX6wZLIaJbPp//XAa8faHij8k1kersWysdo8tf\n\t4HfbKnh+kGQwObCLbiFHgNzC28VIq+0QVYVDzq34O5WVI0fhYgH0+YJcR3MeyQggfeMZ\n\tkFAtVm87TkZ/YV2ntNeSZ1HA8WwF2j4h3E4/k=",
        "Subject": "[PATCH V2 6/9] Codec for STAC9766 used on the Efika",
        "To": "grant.likely@secretlab.ca, linuxppc-dev@ozlabs.org,\n\talsa-devel@alsa-project.org, broonie@sirena.org.uk",
        "From": "Jon Smirl <jonsmirl@gmail.com>",
        "Date": "Sat, 23 May 2009 19:13:07 -0400",
        "Message-ID": "<20090523231307.17919.5277.stgit@terra>",
        "In-Reply-To": "<20090523231148.17919.46103.stgit@terra>",
        "References": "<20090523231148.17919.46103.stgit@terra>",
        "User-Agent": "StGit/0.14.3.366.gf979",
        "MIME-Version": "1.0",
        "X-BeenThere": "linuxppc-dev@ozlabs.org",
        "X-Mailman-Version": "2.1.11",
        "Precedence": "list",
        "List-Id": "Linux on PowerPC Developers Mail List <linuxppc-dev.ozlabs.org>",
        "List-Unsubscribe": "<https://ozlabs.org/mailman/options/linuxppc-dev>,\n\t<mailto:linuxppc-dev-request@ozlabs.org?subject=unsubscribe>",
        "List-Archive": "<http://ozlabs.org/pipermail/linuxppc-dev>",
        "List-Post": "<mailto:linuxppc-dev@ozlabs.org>",
        "List-Help": "<mailto:linuxppc-dev-request@ozlabs.org?subject=help>",
        "List-Subscribe": "<https://ozlabs.org/mailman/listinfo/linuxppc-dev>,\n\t<mailto:linuxppc-dev-request@ozlabs.org?subject=subscribe>",
        "Content-Type": "text/plain; charset=\"us-ascii\"",
        "Content-Transfer-Encoding": "7bit",
        "Sender": "linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@ozlabs.org",
        "Errors-To": "linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@ozlabs.org"
    },
    "content": "AC97 codec for STAC9766 used on the Efika.\nDatasheet: http://www.idt.com/products/getDoc.cfm?docID=13134007\n\nSigned-off-by: Jon Smirl <jonsmirl@gmail.com>\n---\n 0 files changed, 0 insertions(+), 0 deletions(-)",
    "diff": "diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig\nindex 7f78b65..cb07d9b 100644\n--- a/sound/soc/codecs/Kconfig\n+++ b/sound/soc/codecs/Kconfig\n@@ -19,6 +19,7 @@ config SND_SOC_ALL_CODECS\n \tselect SND_SOC_CS4270 if I2C\n \tselect SND_SOC_PCM3008\n \tselect SND_SOC_SSM2602 if I2C\n+\tselect SND_SOC_STAC9766 if SND_SOC_AC97_BUS\n \tselect SND_SOC_TLV320AIC23 if I2C\n \tselect SND_SOC_TLV320AIC26 if SPI_MASTER\n \tselect SND_SOC_TLV320AIC3X if I2C\n@@ -93,6 +94,9 @@ config SND_SOC_PCM3008\n config SND_SOC_SSM2602\n \ttristate\n \n+config SND_SOC_STAC9766\n+\ttristate\n+\n config SND_SOC_TLV320AIC23\n \ttristate\n \ndiff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile\nindex 70c55fa..46c007c 100644\n--- a/sound/soc/codecs/Makefile\n+++ b/sound/soc/codecs/Makefile\n@@ -7,6 +7,7 @@ snd-soc-cs4270-objs := cs4270.o\n snd-soc-l3-objs := l3.o\n snd-soc-pcm3008-objs := pcm3008.o\n snd-soc-ssm2602-objs := ssm2602.o\n+snd-soc-stac9766-objs := stac9766.o\n snd-soc-tlv320aic23-objs := tlv320aic23.o\n snd-soc-tlv320aic26-objs := tlv320aic26.o\n snd-soc-tlv320aic3x-objs := tlv320aic3x.o\n@@ -42,6 +43,7 @@ obj-$(CONFIG_SND_SOC_CS4270)\t+= snd-soc-cs4270.o\n obj-$(CONFIG_SND_SOC_L3)\t+= snd-soc-l3.o\n obj-$(CONFIG_SND_SOC_PCM3008)\t+= snd-soc-pcm3008.o\n obj-$(CONFIG_SND_SOC_SSM2602)\t+= snd-soc-ssm2602.o\n+obj-$(CONFIG_SND_SOC_STAC9766)\t+= snd-soc-stac9766.o\n obj-$(CONFIG_SND_SOC_TLV320AIC23)\t+= snd-soc-tlv320aic23.o\n obj-$(CONFIG_SND_SOC_TLV320AIC26)\t+= snd-soc-tlv320aic26.o\n obj-$(CONFIG_SND_SOC_TLV320AIC3X)\t+= snd-soc-tlv320aic3x.o\ndiff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c\nnew file mode 100644\nindex 0000000..7740cd5\n--- /dev/null\n+++ b/sound/soc/codecs/stac9766.c\n@@ -0,0 +1,470 @@\n+/*\n+ * stac9766.c  --  ALSA SoC STAC9766 codec support\n+ *\n+ * Copyright 2009 Jon Smirl, Digispeaker\n+ * Author: Jon Smirl <jonsmirl@gmail.com>\n+ *\n+ *  This program is free software; you can redistribute  it and/or modify it\n+ *  under  the terms of  the GNU General  Public License as published by the\n+ *  Free Software Foundation;  either version 2 of the  License, or (at your\n+ *  option) any later version.\n+ *\n+ *  Features:-\n+ *\n+ *   o Support for AC97 Codec, S/PDIF\n+ */\n+\n+#include <linux/init.h>\n+#include <linux/module.h>\n+#include <linux/device.h>\n+#include <sound/core.h>\n+#include <sound/pcm.h>\n+#include <sound/ac97_codec.h>\n+#include <sound/initval.h>\n+#include <sound/pcm_params.h>\n+#include <sound/soc.h>\n+#include <sound/tlv.h>\n+#include <sound/soc-of-simple.h>\n+\n+#include \"stac9766.h\"\n+\n+#define STAC9766_VERSION \"0.10\"\n+\n+/*\n+ * STAC9766 register cache\n+ */\n+static const u16 stac9766_reg[] = {\n+\t0x6A90, 0x8000, 0x8000, 0x8000, /* 6 */\n+\t0x0000, 0x0000, 0x8008, 0x8008, /* e */\n+\t0x8808, 0x8808, 0x8808, 0x8808, /* 16 */\n+\t0x8808, 0x0000, 0x8000, 0x0000, /* 1e */\n+\t0x0000, 0x0000, 0x0000, 0x000f, /* 26 */\n+\t0x0a05, 0x0400, 0xbb80, 0x0000, /* 2e */\n+\t0x0000, 0xbb80, 0x0000, 0x0000, /* 36 */\n+\t0x0000, 0x2000, 0x0000, 0x0100, /* 3e */\n+\t0x0000, 0x0000, 0x0080, 0x0000, /* 46 */\n+\t0x0000, 0x0000, 0x0003, 0xffff, /* 4e */\n+\t0x0000, 0x0000, 0x0000, 0x0000, /* 56 */\n+\t0x4000, 0x0000, 0x0000, 0x0000, /* 5e */\n+\t0x1201, 0xFFFF, 0xFFFF, 0x0000, /* 66 */\n+\t0x0000, 0x0000, 0x0000, 0x0000, /* 6e */\n+\t0x0000, 0x0000, 0x0000, 0x0006, /* 76 */\n+\t0x0000, 0x0000, 0x0000, 0x0000, /* 7e */\n+};\n+\n+static const char *stac9766_record_mux[] = {\"Mic\", \"CD\", \"Video\", \"AUX\", \"Line\", \"Stereo Mix\", \"Mono Mix\", \"Phone\"};\n+static const char *stac9766_mono_mux[] = {\"Mix\", \"Mic\"};\n+static const char *stac9766_mic_mux[] = {\"Mic1\", \"Mic2\"};\n+static const char *stac9766_SPDIF_mux[] = {\"PCM\", \"ADC Record\"};\n+static const char *stac9766_popbypass_mux[] = {\"Normal\", \"Bypass Mixer\"};\n+static const char *stac9766_record_all_mux[] = {\"All analog\", \"Analog plus DAC\"};\n+static const char *stac9766_boost1[] = {\"0dB\", \"10dB\"};\n+static const char *stac9766_boost2[] = {\"0dB\", \"20dB\"};\n+static const char *stac9766_stereo_mic[] = {\"Off\", \"On\"};\n+\n+static const struct soc_enum stac9766_record_enum =\n+\tSOC_ENUM_DOUBLE(AC97_REC_SEL, 8, 0, 8, stac9766_record_mux);\n+static const struct soc_enum stac9766_mono_enum =\n+\tSOC_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 9, 2, stac9766_mono_mux);\n+static const struct soc_enum stac9766_mic_enum =\n+\tSOC_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 8, 2, stac9766_mic_mux);\n+static const struct soc_enum stac9766_SPDIF_enum =\n+\tSOC_ENUM_SINGLE(AC97_STAC_DA_CONTROL, 1, 2, stac9766_SPDIF_mux);\n+static const struct soc_enum stac9766_popbypass_enum =\n+\tSOC_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 15, 2, stac9766_popbypass_mux);\n+static const struct soc_enum stac9766_record_all_enum =\n+\tSOC_ENUM_SINGLE(AC97_STAC_ANALOG_SPECIAL, 12, 2, stac9766_record_all_mux);\n+static const struct soc_enum stac9766_boost1_enum =\n+\tSOC_ENUM_SINGLE(AC97_MIC, 6, 2, stac9766_boost1); /* 0/10dB */\n+static const struct soc_enum stac9766_boost2_enum =\n+\tSOC_ENUM_SINGLE(AC97_STAC_ANALOG_SPECIAL, 2, 2, stac9766_boost2); /* 0/20dB */\n+static const struct soc_enum stac9766_stereo_mic_enum =\n+\tSOC_ENUM_SINGLE(AC97_STAC_STEREO_MIC, 2, 1, stac9766_stereo_mic);\n+\n+static const DECLARE_TLV_DB_LINEAR(master_tlv, -4600, 0);\n+static const DECLARE_TLV_DB_LINEAR(record_tlv, 0, 2250);\n+static const DECLARE_TLV_DB_LINEAR(beep_tlv, -4500, 0);\n+static const DECLARE_TLV_DB_LINEAR(mix_tlv, -3450, 1200);\n+\n+static const struct snd_kcontrol_new stac9766_snd_ac97_controls[] = {\n+\tSOC_DOUBLE_TLV(\"Speaker Volume\", AC97_MASTER, 8, 0, 31, 1, master_tlv),\n+\tSOC_SINGLE(\"Speaker Switch\", AC97_MASTER, 15, 1, 1),\n+\tSOC_DOUBLE_TLV(\"Headphone Volume\", AC97_HEADPHONE, 8, 0, 31, 1, master_tlv),\n+\tSOC_SINGLE(\"Headphone Switch\", AC97_HEADPHONE, 15, 1, 1),\n+\tSOC_SINGLE_TLV(\"Mono Out Volume\", AC97_MASTER_MONO, 0, 31, 1, master_tlv),\n+\tSOC_SINGLE(\"Mono Out Switch\", AC97_MASTER_MONO, 15, 1, 1),\n+\n+\tSOC_DOUBLE_TLV(\"Record Volume\", AC97_REC_GAIN, 8, 0, 15, 0, record_tlv),\n+\tSOC_SINGLE(\"Record Switch\", AC97_REC_GAIN, 15, 1, 1),\n+\n+\n+\tSOC_SINGLE_TLV(\"Beep Volume\", AC97_PC_BEEP, 1, 15, 1, beep_tlv),\n+\tSOC_SINGLE(\"Beep Switch\", AC97_PC_BEEP, 15, 1, 1),\n+\tSOC_SINGLE(\"Beep Frequency\", AC97_PC_BEEP, 5, 127, 1),\n+\tSOC_SINGLE_TLV(\"Phone Volume\", AC97_PHONE, 0, 31, 1, mix_tlv),\n+\tSOC_SINGLE(\"Phone Switch\", AC97_PHONE, 15, 1, 1),\n+\n+\tSOC_ENUM(\"Mic Boost1\", stac9766_boost1_enum),\n+\tSOC_ENUM(\"Mic Boost2\", stac9766_boost2_enum),\n+\tSOC_SINGLE_TLV(\"Mic Volume\", AC97_MIC, 0, 31, 1, mix_tlv),\n+\tSOC_SINGLE(\"Mic Switch\", AC97_MIC, 15, 1, 1),\n+\tSOC_ENUM(\"Stereo Mic\", stac9766_stereo_mic_enum),\n+\n+\tSOC_DOUBLE_TLV(\"Line Volume\", AC97_LINE, 8, 0, 31, 1, mix_tlv),\n+\tSOC_SINGLE(\"Line Switch\", AC97_LINE, 15, 1, 1),\n+\tSOC_DOUBLE_TLV(\"CD Volume\", AC97_CD, 8, 0, 31, 1, mix_tlv),\n+\tSOC_SINGLE(\"CD Switch\", AC97_CD, 15, 1, 1),\n+\tSOC_DOUBLE_TLV(\"AUX Volume\", AC97_AUX, 8, 0, 31, 1, mix_tlv),\n+\tSOC_SINGLE(\"AUX Switch\", AC97_AUX, 15, 1, 1),\n+\tSOC_DOUBLE_TLV(\"Video Volume\", AC97_VIDEO, 8, 0, 31, 1, mix_tlv),\n+\tSOC_SINGLE(\"Video Switch\", AC97_VIDEO, 15, 1, 1),\n+\n+\tSOC_DOUBLE_TLV(\"DAC Volume\", AC97_PCM, 8, 0, 31, 1, mix_tlv),\n+\tSOC_SINGLE(\"DAC Switch\", AC97_PCM, 15, 1, 1),\n+\tSOC_SINGLE(\"Loopback Test Switch\", AC97_GENERAL_PURPOSE, 7, 1, 0),\n+\tSOC_SINGLE(\"3D Volume\", AC97_3D_CONTROL, 3, 2, 1),\n+\tSOC_SINGLE(\"3D Switch\", AC97_GENERAL_PURPOSE, 13, 1, 0),\n+\n+\tSOC_ENUM(\"SPDIF Mux\", stac9766_SPDIF_enum),\n+\tSOC_ENUM(\"Mic1/2 Mux\", stac9766_mic_enum),\n+\tSOC_ENUM(\"Record All Mux\", stac9766_record_all_enum),\n+\tSOC_ENUM(\"Record Mux\", stac9766_record_enum),\n+\tSOC_ENUM(\"Mono Mux\", stac9766_mono_enum),\n+\tSOC_ENUM(\"Pop Bypass Mux\", stac9766_popbypass_enum),\n+};\n+\n+int stac9766_ac97_write(struct snd_soc_codec *codec, unsigned int reg,\n+                                unsigned int val)\n+{\n+\tu16 *cache = codec->reg_cache;\n+\n+\tif (reg > AC97_STAC_PAGE0) {\n+\t\tstac9766_ac97_write(codec, AC97_INT_PAGING, 0);\n+\t\tsoc_ac97_ops.write(codec->ac97, reg, val);\n+\t\tstac9766_ac97_write(codec, AC97_INT_PAGING, 1);\n+\t\treturn 0;\n+\t}\n+\tif (reg / 2 > ARRAY_SIZE(stac9766_reg))\n+\t\treturn -EIO;\n+\n+\tsoc_ac97_ops.write(codec->ac97, reg, val);\n+\tcache[reg / 2] = val;\n+\treturn 0;\n+}\n+\n+unsigned int stac9766_ac97_read(struct snd_soc_codec *codec, unsigned int reg)\n+{\n+\tu16 val = 0, *cache = codec->reg_cache;\n+\n+\tif (reg > AC97_STAC_PAGE0) {\n+\t\tstac9766_ac97_write(codec, AC97_INT_PAGING, 0);\n+\t\tval = soc_ac97_ops.read(codec->ac97, reg - AC97_STAC_PAGE0);\n+\t\tstac9766_ac97_write(codec, AC97_INT_PAGING, 1);\n+\t\treturn val;\n+\t}\n+\tif (reg / 2 > ARRAY_SIZE(stac9766_reg))\n+\t\treturn -EIO;\n+\n+\tif (reg == AC97_RESET || reg == AC97_GPIO_STATUS ||\n+\t\treg == AC97_INT_PAGING || reg == AC97_VENDOR_ID1 ||\n+\t\treg == AC97_VENDOR_ID2) {\n+\n+\t\tval = soc_ac97_ops.read(codec->ac97, reg);\n+\t\treturn val;\n+\t}\n+\treturn cache[reg / 2];\n+}\n+\n+static int ac97_analog_prepare(struct snd_pcm_substream *substream,\n+                                struct snd_soc_dai *dai)\n+{\n+\tstruct snd_soc_codec *codec = dai->codec;\n+\tstruct snd_pcm_runtime *runtime = substream->runtime;\n+\tunsigned short reg, vra;\n+\n+\tvra = stac9766_ac97_read(codec, AC97_EXTENDED_STATUS);\n+\n+\tvra |= 0x1; /* enable variable rate audio */\n+\n+\tstac9766_ac97_write(codec, AC97_EXTENDED_STATUS, vra);\n+\n+\tif (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)\n+\t\treg = AC97_PCM_FRONT_DAC_RATE;\n+\telse\n+\t\treg = AC97_PCM_LR_ADC_RATE;\n+\n+\treturn stac9766_ac97_write(codec, reg, runtime->rate);\n+}\n+\n+static int ac97_digital_prepare(struct snd_pcm_substream *substream,\n+                                struct snd_soc_dai *dai)\n+{\n+\tstruct snd_soc_codec *codec = dai->codec;\n+\tstruct snd_pcm_runtime *runtime = substream->runtime;\n+\tunsigned short reg, vra;\n+\n+\tstac9766_ac97_write(codec, AC97_SPDIF, 0x2002);\n+\n+\tvra = stac9766_ac97_read(codec, AC97_EXTENDED_STATUS);\n+\tvra |= 0x5; /* Enable VRA and SPDIF out */\n+\n+\tstac9766_ac97_write(codec, AC97_EXTENDED_STATUS, vra);\n+\n+\treg = AC97_PCM_FRONT_DAC_RATE;\n+\n+\treturn stac9766_ac97_write(codec, reg, runtime->rate);\n+}\n+\n+static int ac97_digital_trigger(struct snd_pcm_substream *substream,\n+\t\t\t\t\t\t\t\tint cmd, struct snd_soc_dai *dai)\n+{\n+\tstruct snd_soc_codec *codec = dai->codec;\n+\tunsigned short vra;\n+\n+\tswitch (cmd) {\n+\tcase SNDRV_PCM_TRIGGER_STOP:\n+\t\tvra = stac9766_ac97_read(codec, AC97_EXTENDED_STATUS);\n+\t\tvra &= !0x04;\n+\t\tstac9766_ac97_write(codec, AC97_EXTENDED_STATUS, vra);\n+\t\tbreak;\n+\t}\n+\treturn 0;\n+}\n+\n+static int stac9766_set_bias_level(struct snd_soc_codec *codec,\n+                                enum snd_soc_bias_level level)\n+{\n+\tswitch (level) {\n+\tcase SND_SOC_BIAS_ON: /* full On */\n+\tcase SND_SOC_BIAS_PREPARE: /* partial On */\n+\tcase SND_SOC_BIAS_STANDBY: /* Off, with power */\n+\t\tstac9766_ac97_write(codec, AC97_POWERDOWN, 0x0000);\n+\t\tbreak;\n+\tcase SND_SOC_BIAS_OFF: /* Off, without power */\n+\t\t/* disable everything including AC link */\n+\t\tstac9766_ac97_write(codec, AC97_POWERDOWN, 0xffff);\n+\t\tbreak;\n+\t}\n+\tcodec->bias_level = level;\n+\treturn 0;\n+}\n+\n+int stac9766_reset(struct snd_soc_codec *codec, int try_warm)\n+{\n+\tif (try_warm && soc_ac97_ops.warm_reset) {\n+\t\tsoc_ac97_ops.warm_reset(codec->ac97);\n+\t\tif (stac9766_ac97_read(codec, 0) == stac9766_reg[0])\n+\t\t\treturn 1;\n+\t}\n+\n+\tsoc_ac97_ops.reset(codec->ac97);\n+\tif (soc_ac97_ops.warm_reset)\n+\t\tsoc_ac97_ops.warm_reset(codec->ac97);\n+\tif (stac9766_ac97_read(codec, 0) != stac9766_reg[0])\n+\t\treturn -EIO;\n+\treturn 0;\n+}\n+\n+static int stac9766_codec_suspend(struct platform_device *pdev,\n+                                pm_message_t state)\n+{\n+\tstruct snd_soc_device *socdev = platform_get_drvdata(pdev);\n+\tstruct snd_soc_codec *codec = socdev->card->codec;\n+\n+\tstac9766_set_bias_level(codec, SND_SOC_BIAS_OFF);\n+\treturn 0;\n+}\n+\n+static int stac9766_codec_resume(struct platform_device *pdev)\n+{\n+\tstruct snd_soc_device *socdev = platform_get_drvdata(pdev);\n+\tstruct snd_soc_codec *codec = socdev->card->codec;\n+\tu16 id, reset;\n+\n+\treset = 0;\n+\t/* give the codec an AC97 warm reset to start the link */\n+reset:\n+\tif (reset > 5) {\n+\t\tprintk(KERN_ERR \"stac9766 failed to resume\");\n+\t\treturn -EIO;\n+\t}\n+\tcodec->ac97->bus->ops->warm_reset(codec->ac97);\n+\tid = soc_ac97_ops.read(codec->ac97, AC97_VENDOR_ID2);\n+\tif (id != 0x4c13) {\n+\t\tstac9766_reset(codec, 0);\n+\t\treset++;\n+\t\tgoto reset;\n+\t}\n+\tstac9766_set_bias_level(codec, SND_SOC_BIAS_STANDBY);\n+\n+\tif (codec->suspend_bias_level == SND_SOC_BIAS_ON)\n+\t\tstac9766_set_bias_level(codec, SND_SOC_BIAS_ON);\n+\n+\treturn 0;\n+}\n+\n+static struct snd_soc_dai_ops stac9766_dai_ops_analog =\n+{\n+\t.prepare = ac97_analog_prepare,\n+};\n+\n+static struct snd_soc_dai_ops stac9766_dai_ops_digital =\n+{\n+\t.prepare = ac97_digital_prepare,\n+\t.trigger = ac97_digital_trigger,\n+};\n+\n+struct snd_soc_dai stac9766_dai[] = {\n+{\n+\t.name = \"stac9766 analog\",\n+\t.id = 0,\n+\t.ac97_control = 1,\n+\n+\t/* stream cababilities */\n+\t.playback = {\n+\t\t.stream_name = \"stac9766 analog\",\n+\t\t.channels_min = 1,\n+\t\t.channels_max = 2,\n+\t\t.rates = SNDRV_PCM_RATE_8000_48000,\n+\t\t.formats = SND_SOC_STD_AC97_FMTS,\n+\t},\n+\t.capture = {\n+\t\t.stream_name = \"stac9766 analog\",\n+\t\t.channels_min = 1,\n+\t\t.channels_max = 2,\n+\t\t.rates = SNDRV_PCM_RATE_8000_48000,\n+\t\t.formats = SND_SOC_STD_AC97_FMTS,\n+\t},\n+\t/* alsa ops */\n+\t.ops = &stac9766_dai_ops_analog,\n+},\n+{\n+\t.name = \"stac9766 IEC958\",\n+\t.id = 1,\n+\t.ac97_control = 1,\n+\n+\t/* stream cababilities */\n+\t.playback = {\n+\t\t.stream_name = \"stac9766 IEC958\",\n+\t\t.channels_min = 1,\n+\t\t.channels_max = 2,\n+\t\t.rates = SNDRV_PCM_RATE_32000 | \\\n+\t\t\tSNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,\n+\t\t.formats = SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE,\n+\t},\n+\t/* alsa ops */\n+\t.ops = &stac9766_dai_ops_digital,\n+}};\n+EXPORT_SYMBOL_GPL(stac9766_dai);\n+\n+static int stac9766_codec_probe(struct platform_device *pdev)\n+{\n+\tstruct snd_soc_device *socdev = platform_get_drvdata(pdev);\n+\tstruct snd_soc_codec *codec;\n+\tint ret = 0;\n+\n+\tprintk(KERN_INFO \"STAC9766 SoC Audio Codec %s\\n\", STAC9766_VERSION);\n+\n+\tsocdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);\n+\tif (socdev->card->codec == NULL)\n+\t\treturn -ENOMEM;\n+\tcodec = socdev->card->codec;\n+\tmutex_init(&codec->mutex);\n+\n+\tcodec->reg_cache = kmemdup(stac9766_reg, sizeof(stac9766_reg), GFP_KERNEL);\n+\tif (codec->reg_cache == NULL) {\n+\t\tret = -ENOMEM;\n+\t\tgoto cache_err;\n+\t}\n+\tcodec->reg_cache_size = sizeof(stac9766_reg);\n+\tcodec->reg_cache_step = 2;\n+\n+\tcodec->name = \"STAC9766\";\n+\tcodec->owner = THIS_MODULE;\n+\tcodec->dai = stac9766_dai;\n+\tcodec->num_dai = ARRAY_SIZE(stac9766_dai);\n+\tcodec->write = stac9766_ac97_write;\n+\tcodec->read = stac9766_ac97_read;\n+\tcodec->set_bias_level = stac9766_set_bias_level;\n+\tINIT_LIST_HEAD(&codec->dapm_widgets);\n+\tINIT_LIST_HEAD(&codec->dapm_paths);\n+\n+\tret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);\n+\tif (ret < 0)\n+\t\tgoto codec_err;\n+\n+\t/* register pcms */\n+\tret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);\n+\tif (ret < 0)\n+\t\tgoto pcm_err;\n+\n+\t/* do a cold reset for the controller and then try\n+\t * a warm reset followed by an optional cold reset for codec */\n+\tstac9766_reset(codec, 0);\n+\tret = stac9766_reset(codec, 1);\n+\tif (ret < 0) {\n+\t\tprintk(KERN_ERR \"Failed to reset STAC9766: AC97 link error\\n\");\n+\t\tgoto reset_err;\n+\t}\n+\n+\tstac9766_set_bias_level(codec, SND_SOC_BIAS_STANDBY);\n+\n+\tsnd_soc_add_controls(codec, stac9766_snd_ac97_controls, ARRAY_SIZE(\n+\t                                stac9766_snd_ac97_controls));\n+\n+\tret = snd_soc_init_card(socdev);\n+\tif (ret < 0)\n+\t\tgoto reset_err;\n+\treturn 0;\n+\n+reset_err:\n+\tsnd_soc_free_pcms(socdev);\n+pcm_err:\n+\tsnd_soc_free_ac97_codec(codec);\n+codec_err:\n+\tkfree(codec->private_data);\n+cache_err:\n+\tkfree(socdev->card->codec);\n+\tsocdev->card->codec = NULL;\n+\treturn ret;\n+}\n+\n+static int stac9766_codec_remove(struct platform_device *pdev)\n+{\n+\tstruct snd_soc_device *socdev = platform_get_drvdata(pdev);\n+\tstruct snd_soc_codec *codec = socdev->card->codec;\n+\n+\tif (codec == NULL)\n+\t\treturn 0;\n+\n+\tsnd_soc_free_pcms(socdev);\n+\tsnd_soc_free_ac97_codec(codec);\n+\tkfree(codec->reg_cache);\n+\tkfree(codec);\n+\treturn 0;\n+}\n+\n+struct snd_soc_codec_device soc_codec_dev_stac9766 =\n+{\n+\t.probe = stac9766_codec_probe,\n+\t.remove = stac9766_codec_remove,\n+\t.suspend = stac9766_codec_suspend,\n+\t.resume = stac9766_codec_resume,\n+};\n+EXPORT_SYMBOL_GPL(soc_codec_dev_stac9766);\n+\n+static int __init stac9766_modinit(void)\n+{\n+\treturn snd_soc_register_dais(stac9766_dai, ARRAY_SIZE(stac9766_dai));\n+}\n+module_init(stac9766_modinit);\n+\n+static void __exit stac9766_exit(void)\n+{\n+\tsnd_soc_unregister_dais(stac9766_dai, ARRAY_SIZE(stac9766_dai));\n+}\n+module_exit(stac9766_exit);\n+\n+MODULE_DESCRIPTION(\"ASoC stac9766 driver\");\n+MODULE_AUTHOR(\"Jon Smirl <jonsmirl@gmail.com>\");\n+MODULE_LICENSE(\"GPL\");\ndiff --git a/sound/soc/codecs/stac9766.h b/sound/soc/codecs/stac9766.h\nnew file mode 100644\nindex 0000000..65642eb\n--- /dev/null\n+++ b/sound/soc/codecs/stac9766.h\n@@ -0,0 +1,21 @@\n+/*\n+ * stac9766.h  --  STAC9766 Soc Audio driver\n+ */\n+\n+#ifndef _STAC9766_H\n+#define _STAC9766_H\n+\n+#define AC97_STAC_PAGE0 0x1000\n+#define AC97_STAC_DA_CONTROL (AC97_STAC_PAGE0 | 0x6A)\n+#define AC97_STAC_ANALOG_SPECIAL (AC97_STAC_PAGE0 | 0x6E)\n+#define AC97_STAC_STEREO_MIC 0x78\n+\n+/* STAC9766 DAI ID's */\n+#define STAC9766_DAI_AC97_ANALOG\t\t0\n+#define STAC9766_DAI_AC97_DIGITAL\t\t1\n+\n+extern struct snd_soc_dai stac9766_dai[];\n+extern struct snd_soc_codec_device soc_codec_dev_stac9766;\n+\n+\n+#endif\n",
    "prefixes": [
        "V2",
        "6/9"
    ]
}